1 /**
2  * Copyright:       Copyright (C) 2018 Gabriel Gheorghe, All Rights Reserved
3  * Authors:         $(Gabriel Gheorghe)
4  * License:         $(LINK2 https://www.gnu.org/licenses/gpl-3.0.txt, GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007)
5  * Source:          $(LINK2 https://github.com/GabyForceQ/LibertyEngine/blob/master/source/liberty/graphics/texture/impl.d)
6  * Documentation:
7  * Coverage:
8 **/
9 module liberty.graphics.texture.impl;
10 
11 import bindbc.opengl;
12 import liberty.logger.impl;
13 import liberty.graphics.texture.constants;
14 
15 /**
16  *
17 **/
18 final class Texture {
19   private {
20     uint id;
21     string path;
22     uint width;
23     uint height;
24     bool isBind = false;
25     float lodBias = float.nan;
26     TextureType type;
27   }
28 
29   /**
30    * Craete an empty texture.
31   **/
32   this() {}
33 
34   /**
35    * Create a texture with a given id.
36   **/
37   this(uint id) {
38     this.id = id;
39   }
40 
41   /**
42    * Generate texture internally.
43    * Returns reference to this so it can be used in a stream.
44   **/
45   typeof(this) generateTextures() {
46     glGenTextures(1, &id);
47     return this;
48   }
49 
50   /**
51    * Delete texture internally.
52    * Returns reference to this so it can be used in a stream.
53   **/
54   typeof(this) deleteTextures() {
55     glDeleteTextures(1, &id);
56     return this;
57   }
58 
59   /**
60    * Bind the texture.
61    * Returns reference to this so it can be used in a stream.
62   **/
63   typeof(this) bind(TextureType type) {
64     final switch (type) with (TextureType) {
65       case NONE:
66         Logger.error("Cannot bind NONE to texture.", typeof(this).stringof);
67         break;
68       case TEX_2D:
69         glBindTexture(GL_TEXTURE_2D, id);
70         break;
71       case CUBE_MAP:
72         glBindTexture(GL_TEXTURE_CUBE_MAP, id);
73         break;
74     }
75 
76     this.type = type;
77     isBind = true;
78 
79     return this;
80   }
81 
82   /**
83    * Unbind the texture.
84    * Returns reference to this so it can be used in a stream.
85   **/
86   typeof(this) unbind() {
87     final switch (type) with (TextureType) {
88       case NONE:
89         Logger.error("Cannot unbind NONE from texture.", typeof(this).stringof);
90         break;
91       case TEX_2D:
92         glBindTexture(GL_TEXTURE_2D, 0);
93         break;
94       case CUBE_MAP:
95         glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
96         break;
97     }
98 
99     isBind = false;
100     return this;
101   }
102 
103   /**
104    * Returns texture unique id.
105   **/
106   uint getId()   const {
107     return id;
108   }
109 
110   /**
111    * Returns the relative texure path.
112   **/
113   string getRelativePath()   const {
114     return path;
115   }
116 
117   /**
118    * Set both width and height of texture.
119    * Returns reference to this so it can be used in a stream.
120   **/
121   typeof(this) setExtent(uint width, uint height)   {
122     this.width = width;
123     this.height = height;
124     return this;
125   }
126 
127   /**
128    * Set the texture width.
129    * Returns reference to this so it can be used in a stream.
130   **/
131   typeof(this) setWidth(uint width)   {
132     this.width = width;
133     return this;
134   }
135 
136   /**
137    * Returns texture width.
138   **/
139   uint getWidth()   const {
140     return width;
141   }
142 
143   /**
144    * Set the texture height.
145    * Returns reference to this so it can be used in a stream.
146   **/
147   typeof(this) setHeight(uint height)   {
148     this.height = height;
149     return this;
150   }
151 
152   /**
153    * Returns texture height.
154   **/
155   uint getHeight()   const {
156     return height;
157   }
158 
159   /**
160    * Generate mipmap for texture 2D.
161    * Returns reference to this so it can be used in a stream.
162   **/
163   typeof(this) generateMipmap() {
164     glGenerateMipmap(GL_TEXTURE_2D);      
165     return this;
166   }
167 
168   /**
169    * Set texture level of detail bias.
170    * Returns reference to this so it can be used in a stream.
171   **/
172   typeof(this) setLODBias(string op = "=")(float value)
173   if (op == "=" || op == "+=" || op == "-=" || op == "*=" || op == "/=" || op == "%=") {
174     mixin("lodBias " ~ op ~ " value;");
175     const bindUnbind = !isBind; 
176     if (bindUnbind)
177       bind(type);
178     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_LOD_BIAS, lodBias);
179     if (bindUnbind)
180       unbind;
181     return this;
182   }
183 
184   /**
185    * Returns the texture level of detail bias.
186   **/
187   float getLODBias()   const {
188     return lodBias;
189   }
190 
191   /**
192    * Returns the type of the texture.
193    * For available options see $(D TextureType).
194   **/
195   TextureType getType()   const {
196     return type;
197   }
198 
199   package void setRealtivePath(string path)   {
200     this.path = path;
201   }
202 }