Allolib  1.0
C++ Components For Interactive Multimedia
al_Texture.hpp
1 #ifndef INCLUDE_AL_GRAPHICS_TEXTURE_HPP
2 #define INCLUDE_AL_GRAPHICS_TEXTURE_HPP
3 
4 /* Allocore --
5  Multimedia / virtual environment application class library
6 
7  Copyright (C) 2009. AlloSphere Research Group, Media Arts & Technology, UCSB.
8  Copyright (C) 2012. The Regents of the University of California.
9  All rights reserved.
10 
11  Redistribution and use in source and binary forms, with or without
12  modification, are permitted provided that the following conditions are met:
13 
14  Redistributions of source code must retain the above copyright notice,
15  this list of conditions and the following disclaimer.
16 
17  Redistributions in binary form must reproduce the above copyright
18  notice, this list of conditions and the following disclaimer in the
19  documentation and/or other materials provided with the distribution.
20 
21  Neither the name of the University of California nor the names of its
22  contributors may be used to endorse or promote products derived from
23  this software without specific prior written permission.
24 
25  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
29  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35  POSSIBILITY OF SUCH DAMAGE.
36 
37 
38  File description:
39  Helper object for Graphics Textures
40 
41  File author(s):
42  Lance Putnam, 2015, putnam.lance@gmail.com
43  Graham Wakefield, 2010, grrrwaaa@gmail.com
44  Wesley Smith, 2010, wesley.hoke@gmail.com
45  Keehong Youn, 2017, younkeehong@gmail.com
46 */
47 
48 #include "al/graphics/al_GPUObject.hpp"
49 #include "al/graphics/al_OpenGL.hpp"
50 // #include "al/types/al_Color.hpp"
51 
52 /*
53 https://www.khronos.org/opengl/wiki/Shader#Resource_limitations
54 GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS
55 The total number of texture units that can be used from all active programs.
56 This is the limit on glActiveTexture(GL_TEXTURE0 + i) and glBindSampler.
57 In GL 3.3, this was 48; in 4.3, it is 96.
58 */
59 
60 #define AL_TEX_MAX_BINDING_UNIT 48
61 // for temporary internal binding such as creating a texture
62 #define AL_TEX_TEMP_BINDING_UNIT 47
63 
64 /*
65 
66 usage:
67 Texture myTex;
68 myTex.filter(GL_LINEAR);
69 myTex.wrap(GL_CLAMP_TO_EDGE);
70 myTex.mipmap(false);
71 myTex.create2D(width, height, GL_RGB8, GL_RGBA, GL_FLOAT);
72 
73 myTex.submit(pointer_to_data); // you can skip this if using the texture for
74 render target
75 
76 to update params:
77 myTex.filter(GL_LINEAR);
78 myTex.wrap(GL_CLAMP_TO_EDGE);
79 myTex.update(); // remember to call update, this is not needed when calling
80 create2D (internally called)
81 
82  frequently used internal format:
83  GL_RGBA32F GL_RGBA8 GL_DEPTH_COMPONENT32F GL_DEPTH_COMPONENT16
84 */
85 
86 namespace al {
87 
90 class Texture : public GPUObject {
91  public:
92  enum DataType : unsigned int /* GLenum */ {
93  BYTE = GL_BYTE,
94  UBYTE = GL_UNSIGNED_BYTE,
95  SHORT = GL_SHORT,
96  USHORT = GL_UNSIGNED_SHORT,
97  INT = GL_INT,
98  UINT = GL_UNSIGNED_INT,
99  FLOAT = GL_FLOAT,
100  DOUBLE = GL_DOUBLE
101  };
102 
103  enum Target : unsigned int /* GLenum */ {
104  TEX_1D = GL_TEXTURE_1D,
105  TEX_2D = GL_TEXTURE_2D,
106  TEX_3D = GL_TEXTURE_3D,
107  TEX_1D_ARRAY = GL_TEXTURE_1D_ARRAY,
108  TEX_2D_ARRAY = GL_TEXTURE_2D_ARRAY,
109  TEX_RECTANGLE = GL_TEXTURE_RECTANGLE,
110  TEX_CUBE_MAP = GL_TEXTURE_CUBE_MAP,
111  TEX_BUFFER = GL_TEXTURE_BUFFER,
112  TEX_2D_MULTISAMPLE = GL_TEXTURE_2D_MULTISAMPLE,
113  TEX_2D_MULTISAMPLE_ARRAY = GL_TEXTURE_2D_MULTISAMPLE_ARRAY,
114  NO_TARGET = 0
115  };
116 
117  enum Wrap : int /* GLint */ {
118  CLAMP_TO_EDGE = GL_CLAMP_TO_EDGE,
119  CLAMP_TO_BORDER = GL_CLAMP_TO_BORDER,
120  MIRRORED_REPEAT = GL_MIRRORED_REPEAT,
121  REPEAT = GL_REPEAT
122  };
123 
124  enum Filter : int /* GLint */ {
125  NEAREST = GL_NEAREST,
126  LINEAR = GL_LINEAR,
127  // first term is within mipmap level, second term is between mipmap levels:
128  NEAREST_MIPMAP_NEAREST = GL_NEAREST_MIPMAP_NEAREST,
129  LINEAR_MIPMAP_NEAREST = GL_LINEAR_MIPMAP_NEAREST,
130  NEAREST_MIPMAP_LINEAR = GL_NEAREST_MIPMAP_LINEAR,
131  LINEAR_MIPMAP_LINEAR = GL_LINEAR_MIPMAP_LINEAR
132  };
133 
134  enum Format : unsigned int /* GLenum */ {
135  RED = GL_RED,
136  RG = GL_RG,
137  RGB = GL_RGB,
138  BGR = GL_BGR,
139  RGBA = GL_RGBA,
140  BGRA = GL_BGRA,
141  DEPTH_COMPONENT = GL_DEPTH_COMPONENT,
142  DEPTH_STENCIL = GL_DEPTH_STENCIL
143  };
144 
145  enum Internal : int /* GLint */ {
146  RGBA32F = GL_RGBA32F,
147  RGBA16 = GL_RGBA16,
148  RGBA16F = GL_RGBA16F,
149  RGBA8 = GL_RGBA8,
150  SRGB8_ALPHA8 = GL_SRGB8_ALPHA8,
151 
152  RG32F = GL_RG32F,
153  RG16 = GL_RG16,
154  RG16F = GL_RG16F,
155  RG8 = GL_RG8,
156 
157  R32F = GL_R32F,
158  R16F = GL_R16F,
159  R8 = GL_R8,
160 
161  RGB32F = GL_RGB32F,
162  RGB16F = GL_RGB16F,
163  RGB16 = GL_RGB16,
164  RGB8 = GL_RGB8,
165  SRGB8 = GL_SRGB8,
166 
167  DEPTH_COMPONENT32F = GL_DEPTH_COMPONENT32F,
168  DEPTH_COMPONENT24 = GL_DEPTH_COMPONENT24,
169  DEPTH_COMPONENT16 = GL_DEPTH_COMPONENT16,
170  DEPTH32F_STENCIL8 = GL_DEPTH32F_STENCIL8,
171  DEPTH24_STENCIL8 = GL_DEPTH24_STENCIL8
172 
173  // there's more... but above are common ones
174  };
175 
176  Texture();
177  virtual ~Texture();
178 
179  void create1D(GLsizei width, GLint internal = GL_RGBA8,
180  GLenum format = GL_RGBA, GLenum type = GL_UNSIGNED_BYTE);
181 
182  void create2D(unsigned int width, unsigned int height,
183  int internal = GL_RGBA8, unsigned int format = GL_RGBA,
184  unsigned int type = GL_UNSIGNED_BYTE // or GL_FLOAT is used
185  );
186 
187  void create2DArray(unsigned int width, unsigned int height, unsigned int depth,
188  int internal = GL_RGBA8, unsigned int format = GL_RGBA,
189  unsigned int type = GL_UNSIGNED_BYTE);
190  // TODO
191  // void create3D();
192 
193  void createCubemap(
194  unsigned int size, int internal = GL_RGBA8, unsigned int format = GL_RGBA,
195  unsigned int type = GL_UNSIGNED_BYTE // or GL_FLOAT is used
196  );
197 
200  void bind(int binding_point = 0);
203  void bind_temp();
204 
206  void unbind(int binding_point = 0);
207  void unbind_temp() { unbind(AL_TEX_TEMP_BINDING_UNIT, target()); }
208  static void unbind(int binding_point, unsigned int target);
209 
211  unsigned int target() const { return mTarget; }
212 
214  int internalFormat() const { return mInternalFormat; }
215 
217  unsigned int format() const { return mFormat; }
218 
220  unsigned int type() const { return mType; }
221 
223  unsigned int width() const { return mWidth; }
224 
226  unsigned int height() const { return mHeight; }
227 
229  unsigned int depth() const { return mDepth; }
230 
232  int filterMin() const { return mFilterMin; }
233 
235  int filterMag() const { return mFilterMag; }
236 
238  int wrapS() const { return mWrapS; }
239 
241  int wrapT() const { return mWrapT; }
242 
244  int wrapR() const { return mWrapR; }
245 
246  bool mipmap() const { return mUseMipmap; }
247 
249  // unsigned numComponents() const { return Graphics::numComponents(format());
250  // }
251 
253  // unsigned numElems() const {
254  // return numPixels() * numComponents();
255  // }
256 
258  // unsigned numPixels() const {
259  // return width() * (height()?height():1) * (depth()?depth():1);
260  // }
261 
263  void resize(unsigned w) {}
264 
266  // void resize (unsigned w, unsigned h) { }
267  bool resize(unsigned int w, unsigned int h, int internal, unsigned int format,
268  unsigned int type);
269  bool resize(unsigned int w, unsigned int h) {
270  return resize(w, h, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE);
271  }
272 
274  void resize(unsigned w, unsigned h, unsigned d) {}
275 
277  void filter(int v) {
278  filterMin(v);
279  filterMag(v);
280  }
281 
283  void filterMin(int v);
284 
286  void filterMag(int v);
287 
289  void wrap(int S, int T, int R);
290 
292  void wrap(int S, int T) { wrap(S, T, mWrapR); }
293 
295  void wrap(int v) { wrap(v, v, v); }
296 
297  void wrapS(int v) { wrap(v, mWrapT, mWrapR); }
298  void wrapT(int v) { wrap(mWrapS, v, mWrapR); }
299  void wrapR(int v) { wrap(mWrapS, mWrapT, v); }
300 
302  void mipmap(bool b) { mUseMipmap = b; }
303 
308  void submit(const void *pixels, unsigned int format, unsigned int type);
309  void submit(const void *pixels) { submit(pixels, format(), type()); }
310 
311  // void submit(std::vector<Colori> const& pixels) {
312  // submit(pixels.data(), Texture::RGBA, Texture::UBYTE);
313  // }
314  // void submit(std::vector<Color> const& pixels) {
315  // submit(pixels.data(), Texture::RGBA, Texture::FLOAT);
316  // }
317 
318  // update the changes in params or settings
319  // void update(bool force=false);
320 
321  void generateMipmap();
322  void disableMipmap();
323 
325 
333  void copyFrameBuffer(int w = -1, int h = -1, int fbx = 0, int fby = 0,
334  int texx = 0, int texy = 0, int texz = 0);
335 
337  static int numComponents(Texture::Format v);
338 
340  unsigned numComponents() const {
341  return numComponents(Texture::Format(format()));
342  }
343 
344  protected:
345  void onCreate() override;
346  void onDestroy() override;
347 
348  void update_filter();
349  void update_wrap();
350  void update_mipmap();
351 
352  // Pattern for setting a variable that when changed sets a notification flag
353  // if v != var, update var and set flag to true
354  template <class T>
355  void update_param(const T &v, T &var, bool &flag) {
356  if (v != var) {
357  var = v;
358  flag = true;
359  }
360  }
361 
362  unsigned int mTarget = GL_TEXTURE_2D;
363  int mInternalFormat = GL_RGBA8;
364  unsigned int mWidth = 0, mHeight = 0, mDepth = 0;
365  unsigned int mFormat = GL_RGBA;
366  unsigned int mType = GL_UNSIGNED_BYTE;
367 
368  int mWrapS = GL_CLAMP_TO_EDGE, mWrapT = GL_CLAMP_TO_EDGE,
369  mWrapR = GL_CLAMP_TO_EDGE;
370  int mFilterMin = GL_NEAREST, mFilterMag = GL_NEAREST;
371  bool mUseMipmap = false; // by default no mipmap
372 
373  bool mFilterUpdated = true; // Flags change in texture params (wrap, filter)
374  bool mWrapUpdated = true; // Flags change in texture params (wrap, filter)
375  bool mUsingMipmapUpdated = true;
376 };
377 
378 } // namespace al
379 
380 #endif
void filter(int v)
Set minification and magnification filter types all at once.
Definition: al_Texture.hpp:277
int filterMin() const
Get minification filter type.
Definition: al_Texture.hpp:232
unsigned int width() const
Get width, in pixels.
Definition: al_Texture.hpp:223
void wrap(int S, int T)
Set 2D wrapping modes.
Definition: al_Texture.hpp:292
void filterMag(int v)
Set magnification filter type.
void onCreate() override
Called when currently assigned context is created.
unsigned int type() const
Get pixel component data type.
Definition: al_Texture.hpp:220
void wrap(int v)
Set wrapping mode for all dimensions.
Definition: al_Texture.hpp:295
void unbind(int binding_point=0)
Unbind the texture (from a multitexture unit)
int filterMag() const
Get magnification filter type.
Definition: al_Texture.hpp:235
bool resize(unsigned int w, unsigned int h, int internal, unsigned int format, unsigned int type)
Resize 2D texture.
unsigned int height() const
Get height, in pixels.
Definition: al_Texture.hpp:226
void resize(unsigned w, unsigned h, unsigned d)
Resize 3D texture.
Definition: al_Texture.hpp:274
void wrap(int S, int T, int R)
Set 3D wrapping modes.
unsigned int target() const
Get target type (e.g., TEXTURE_2D)
Definition: al_Texture.hpp:211
unsigned int format() const
Get pixel (color) format.
Definition: al_Texture.hpp:217
int internalFormat() const
Get internal format.
Definition: al_Texture.hpp:214
void filterMin(int v)
Set minification filter type.
int wrapR() const
Get R wrapping type.
Definition: al_Texture.hpp:244
void bind(int binding_point=0)
void resize(unsigned w)
Get number of components per pixel.
Definition: al_Texture.hpp:263
void bind_temp()
unsigned numComponents() const
Get number of components per pixel.
Definition: al_Texture.hpp:340
static int numComponents(Texture::Format v)
Returns number of components for given color type.
void onDestroy() override
Called when currently assigned context is destroyed.
void submit(const void *pixels, unsigned int format, unsigned int type)
int wrapT() const
Get T wrapping type.
Definition: al_Texture.hpp:241
int wrapS() const
Get S wrapping type.
Definition: al_Texture.hpp:238
void mipmap(bool b)
Set whether to generate mipmaps.
Definition: al_Texture.hpp:302
void copyFrameBuffer(int w=-1, int h=-1, int fbx=0, int fby=0, int texx=0, int texy=0, int texz=0)
Copy pixels from current frame buffer to texture texels.
unsigned int depth() const
Get depth, in pixels.
Definition: al_Texture.hpp:229
Definition: al_App.hpp:23
Color represented by red, green, and blue components.
Definition: al_Color.hpp:503