HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
RE_OGLTexture.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: RE_OGLTexture.h ( RE Library, C++)
7  *
8  * COMMENTS:
9  * Base class for various OpenGL texture types: 1D, 2D, 3D, Cube,
10  * 2D rectangles, 1D arrays and 2D arrays.
11  *
12  */
13 #ifndef RE_OGLTexture_h
14 #define RE_OGLTexture_h
15 
16 class RE_Render;
17 class RE_TextureMap;
18 
19 #include <UT/UT_ValArray.h>
20 #include <UT/UT_Rect.h>
21 
22 #include "RE_CachedObject.h"
23 #include "RE_Types.h"
24 #include "RE_TextureTypes.h"
25 #include "RE_TextureFilter.h"
26 #include <IMG/IMG_FileTypes.h>
27 
28 #include <iosfwd>
29 
31 {
32 public:
33  virtual ~RE_OGLTexture();
34 
35  /// Returns the amount of main memory (NOT graphics memory!)
36  /// owned by this RE_OGLTexture.
37  virtual int64 getMemoryUsage(bool inclusive) const;
38 
39  virtual const char *className() const;
40 
41  // Texture type (dimensions)
42  RE_TextureDimension getTextureType() const;
43 
44  // Returns true if this texture type is supported.
45  virtual bool hasTextureSupport(RE_Render *r);
46 
47  // True if this texture type supports mipmapping (all but tex rectangles)
48  virtual bool hasMipMapSupport(RE_Render *);
49 
50  // Returns the maximum size of a texture edge of the given texture type
51  virtual int getMaxTextureSize(RE_Render *r) = 0;
52 
53  // Returns the maximum index that can be used for arrays and cube maps
54  virtual int getMaxTextureIndex(RE_Render *r);
55 
56  // True if GL can compress textures itself.
57  bool hasAutoCompression(RE_Render *r);
58 
59  // true if this has a valid texture created for it.
60  virtual bool isValid() const;
61 
62  // true if the texture res, format, mip levels can be changed on the fly
63  bool isMutable() const { return myMutableFlag; }
64 
65  // Texture identifier - opaque handle.
66  RE_TextureID getID() const;
67 
68  // Releases the texture on the GPU; this object becomes invalid.
69  virtual void free();
70 
71  // Returns a new texture with no attributes of the given type.
72  static RE_OGLTexture *newTexture(RE_TextureDimension t);
73 
74  // Returns a new, blank texture with the same attributes as this texture.
75  RE_OGLTexture *copyAttributes() const;
76 
77  // -----------------------------------------------------------------
78  // Basic Texture data (modifying will invalidate texture,
79  // requiring a setTexture() call)
80 
81  // The texture type can be color, stencil, or depth. Stencil and depth
82  // textures are more restrictive with the types that can be sent to them.
83  // They must be single channel textures; depth can be FLOAT16,24 or 32,
84  // while stencil must be UINT1,2,4,8 or 16. The default is Color.
85  // This must be set before calling setFormat().
86  void setDataType(RE_TextureDataType type);
87  RE_TextureDataType getDataType() const;
88 
89  // The data type is the CPU-side data format, vectorsize can be 1-4.
90  // To use leaner GPU-side data formats, set a texture compression.
91  void setFormat(RE_GPUType data, int vectorsize,
92  RE_TextureFormatExtra format_extra =
94  RE_GPUType getFormatType() const;
95  int getFormatSize() const;
96  RE_TextureFormatExtra getFormatExtra() const;
97 
98  // returns the GL internal format of the texture (ie, RGBA8).
99  int getInternalFormat() const { return myGLInternal; }
100 
101  // You can pass the data in a different format than the texture type.
102  // This must be called after setFormat().
103  void setClientFormat(RE_GPUType data, int vectorsize);
104 
105  // Compress the texture on the GPU, default is to use the same format as
106  // the CPU format (RE_COMPRESS_NONE). If auto_compress is false, it is
107  // assumed that the data passed to this texture object is already
108  // compressed.
109  void setCompression(RE_TextureCompress comp,
110  bool auto_compress);
111  RE_TextureCompress getCompression() const;
112  bool getAutoCompression() const;
113 
114  // Texture Resolution
115  // Height/depth may not be required, depending on texture dimension.
116  void setResolution(int w, int h = 1, int depth = 1,
117  bool force_pow2 = false);
118  int getWidth() const;
119  int getHeight() const;
120  int getDepth() const;
121 
122  // GL may differ from getWidth/Height/Depth if GPU requires pow2 textures
123  // These sizes will never be smaller than the above sizes.
124  int getGLWidth() const;
125  int getGLHeight() const;
126  int getGLDepth() const;
127 
128  // If the texture size differs from the GL size, this will return a value
129  // less than 1 to represent the coord where the image ends in the texture
130  float getTexS() const;
131  float getTexT() const;
132  float getTexR() const;
133 
134  // For multisample textures (2D)
135  virtual void setSamples(int samples);
136  int getSamples() const;
137 
138  // Enables mipmapping and auto-generation of mipmaps. Not all texture data
139  // formats can be mipmapped (specifically floating point). This also sets
140  // the minify filter to RE_FILT_LINEAR_MIPMAP_LINEAR if not set to a MIPMAP
141  // filter and it is enabled, or back to RE_FILT_LINEAR if disabled.
142  void setMipMap(bool m, bool autogen = true);
143  bool getMipMap() const;
144  bool getMipMapAutoGenerate() const;
145 
146  // Returns true if the texture actually is mipmapped, not just requested
147  // to be (some formats don't mipmap).
148  bool isMipMapped() const;
149 
150  // This can be called before the texture is created to determine if it's
151  // possible to use. Returns false if it's not possible to create. If the
152  // texture is already created, it returns the actual OpenGL texture values.
153  // 'format' is an internal OpenGL format specification (like GL_RGBA8).
154  bool queryTextureStats(RE_Render *r,
155  int *width, int *height, int *depth,
156  int *format);
157 
158  void setLabel(RE_Render *r, const char *label);
159 
160 
161  // ---------------------------------------------------------------------
162  // Texture transfer methods (CPU/GPU).
163 
164  // set/getTexture() writes or reads the entire texture.
165  // It is assumed that data points to a chunk of memory large enough for the
166  // texture. A set method must be called afterwards to reinitialize the
167  // texture if the above parameters are changed.
168  // If non-pow2 textures are not supported and you set the resolution to a
169  // non-pow2 size, you still pass in non-pow2 data and it will be written
170  // properly (do not pad to pow2). If you do not wish this to be the case,
171  // set a pow2 resolution insteead. When rendering a non-pow2 emulated
172  // texture, use the getTexS/T/R() methods to determine the edge of the data.
173 
174  // 'level' is the texture mipmap level.Must be -1 if mipmapping is disabled.
175  // 'index' varies by texture type; face for cube maps and index for arrays.
176  // 'proxy' does a texture proxy call, merely seeing if the texture can be
177  // created without generating any errors.
178  virtual void setTexture(RE_Render *r, const void *data,
179  int level=-1, int index=-1,
180  bool proxy=false) = 0;
181 
182  // How large a block is required to initialize or fetch this texture.
183  virtual int64 getSizeBytes() const;
184 
185  // The size of one scanline in the image. The second version using sublen
186  // instead of GLwidth
187  int64 getScanBytes() const;
188  int64 getScanBytes(int sublen) const;
189 
190  // Number of bits in a full pixel (ie, fp16 RGB has 48b).
191  int64 getBitsPerPixel() const;
192 
193  // Actual size of texture in GPU mem.
194  int64 getTextureSize() const;
195 
196  // Write to or read from a portion of the texture. Not all dimensions may
197  // be used. See derived classes for the meaning of 'z'. These can only be
198  // used after setTexture(), though it can be called with data=NULL to set
199  // up the texture for setSubTexture().
200  virtual void setSubTexture(RE_Render *r,
201  const void *data, int level,
202  int xoffset, int xsize,
203  int yoffset=0, int ysize=1,
204  int zoffset=0, int zsize=1) = 0;
205 
206  // Reads the entire texture at 'level' back into 'data'. 'data' must point
207  // to a block of at least 'getSizeBytes()' in size.
208  // Note that a non-pow2 emulated texture will return the entire GL pow2
209  // size, since there is no way to read a portion of a texture.
210  virtual void getTexture(RE_Render *r, void *data,
211  int level=0, int index=-1);
212 
213  // copies 'area' block of pixels from the read buffer to this texture,
214  // in screen coords (if NULL, the entire area) at offset (x,y,z) and
215  // miplevel 'level'. The pixels are converted to this texture's data format
216  virtual bool copyFromBuffer(RE_Render *r, int x, int y, int z = 0,
217  const UT_DimRect *bufferarea = NULL,
218  int level = 0) = 0;
219 
220  // Copy a subregion from a source texture to this texture. The x,y,z and
221  // width, height, depth parameters have different meanings depending on the
222  // source and destination texture types (eg, depth in cubemap is the face,
223  // height in a 1D array is the index). Requires RE_EXT_TEXTURE_COPY (GL4.3)
224  // Buffer textures cannot be copied to or from.
225  bool copyFromTexture(RE_Render *r,
226  const RE_OGLTexture *src_texture,
227  int src_x, int src_y, int src_z,
228  int dst_x, int dst_y, int dst_z,
229  int width = -1, // -1 = full src width
230  int height = -1,
231  int depth = -1,
232  int mip_level = 0);
233 
234 
235  // Build mip-maps from mip level 0 of the texture. Useful for
236  // filtering render-to-texture targets. Returns true if mipmaps were
237  // generated.
238  bool generateMipMaps(RE_Render *r);
239 
240  // ---------------------------------------------------------------------
241  // Texture Parameters (changing will modify, does not require setTexture)
242 
243  // Filter to use when displaying the texture at less than 100% zoom
244  void setMinFilter( RE_Render *r, RE_TexFiltType t );
245  RE_TexFiltType getMinFilter() const;
246 
247  // Filter to use when displaying the texture at greater than 100% zoom
248  void setMagFilter( RE_Render *r, RE_TexFiltType t );
249  RE_TexFiltType getMagFilter() const;
250 
251  void setMaxAnisotropy(RE_Render *r, int atf);
252  int getMaxAnisotropy() const;
253 
254  // Fixed bias value that is added to the level-of-detail parameter for
255  // the texture before texture sampling (when mipmapping).
256  void setLodBias(RE_Render *r, float bias);
257  float getLodBias() const;
258 
259  // Texture wrapping - clamp or repeat. Not all dimension may be used.
260  void setTextureWrap(RE_Render *r,
261  RE_TexClampType clamp_s,
262  RE_TexClampType clamp_t = RE_CLAMP_EDGE,
263  RE_TexClampType clamp_r = RE_CLAMP_EDGE);
264  bool getWrapS() const;
265  bool getWrapT() const;
266  bool getWrapR() const;
267 
268  void setBorder(RE_Render *r,
270  const UT_Vector4F *color_alpha = NULL);
271  UT_Vector4F getBorderColor() const;
272 
273  // Sets all of the above in one go.
274  void setTextureFilter(RE_Render *r,
275  const RE_TextureFilter &filter);
276 
277  // When on, depth comparison is used. When used in a shader, a shadow
278  // sampler must be used. If disabled, the raw depth value is returned and
279  // a normal texture sampler must be used. 'compare' can be set to a
280  // negative, positive or zero value, indicating less/equal, greater/equal or
281  // equal compare mode.
282  void setDepthCompareMode(RE_Render *r, bool enabled,
285 
286  // If RE_EXT_TEXTURE_SWIZZLE is supported, texture components can be
287  // shuffled about or set to a constant 0 or 1 value.
288  bool setTextureSwizzle(RE_Render *r,
293 
294  void setAlphaInfo(IMG_FileAlphaInfo a) { myAlphaInfo = a; }
295  IMG_FileAlphaInfo getAlphaInfo() const { return myAlphaInfo;}
296 
297  // --------------------------------------------------------------------
298  // Bindless Textures (requires RE_EXT_TEXTURE_BINDLESS)
299 
300  // Creates a bindless handle for the texture. Once this is done, the texture
301  // is immutable - its texel contents can change, but nothing else.
302  // Will return false if bindless texture is unsupported.
303  bool createTextureHandle(RE_Render *r);
304 
305  // returns the bindless texture handle. createTextureHandle() must be called
306  // first. If bindless is unsupported or create was not called, returns 0.
307  uint64 getTextureHandle() const { return myBindlessHandle; }
308 
309  // Before a bindless texture can be used, it must be made resident.
310  bool makeResidentTexture(RE_Render *r);
311 
312  // When a bindless texture is no longer needed, it should be removed from
313  // resident status to free up resources.
314  bool removeResidentTexture(RE_Render *r);
315 
316 
317 
318  // --------------------------------------------------------------------
319 
320  static int getGLTextureType(RE_TextureDimension t);
321  static RE_TextureDimension getRETextureType(int gl_type);
322  static RE_OGLTexture *findTextureWithID(RE_TextureID id);
323 
324  // Mostly for debug, this writes the texture out to a file (any supported
325  // image format, determined by the extension). 3D textures are best written
326  // as deep raster formats, like .pic.
327  bool writeToFile(RE_Render *r, const char *name,
328  int level = 0);
329 
330  // Expands a 2D multisample texture into a 2D texture with dimensions
331  // increased by the sampling factor: 2x (2,1), 4x (2,2), 6x (3,2), 8x (4,2)
332  RE_OGLTexture * expandMultisampleTexture(RE_Render *r);
333 
334  static void adjustPow2(int &w, int &h, int &d);
335 
336 
337  // References on this texture by other objects
338  void addReference(void (*cb)(void *, RE_OGLTexture *),
339  void *ref_obj);
340  void removeReference(void *ref_obj);
341 
342  void setFileModTime(int time) { myModTime = time; }
343  bool hasFileModTime() const { return myModTime != 0; }
344  int getFileModTime() const { return myModTime; }
345 
346 
347  void invalidateCache();
348 
349  // print a summary of this texture. If os is NULL, use std::cerr.
350  void print(std::ostream *os = NULL);
351 
352  // Dump all textures currently in use by Houdini. If min_tex_size is
353  // specified, only those textures >= the size will be printed. The summary
354  // line will always include stats from all textures.
355  static void dumpTextureTable(std::ostream &os,
356  int64 min_tex_size = -1);
357 protected:
358 
360 
361  void deleteObject();
362  void setupTextureParameters(RE_Render *r, bool force);
363  void validate();
364 
365  // These return various GL types (ie, GL_TEXTURE_2D, GL_PROXY_TEXTURE_2D,
366  // GL_TEXTURE_BINDING_2D)
367  virtual int getGLType() const = 0;
368  virtual int getGLProxy() const = 0;
369  virtual int getGLTypeBinding() const = 0;
370  virtual int getGLCreateType() const { return getGLType(); }
371 
372  // These methods must be called from within a locked context
373  virtual bool buildMipMaps(RE_Render *r, const void *data) = 0;
374 
375  bool createTextureID();
376 
377  RE_GPUType getClientType() const;
378 
379  // returns a malloc'ed image with the compressed data, which must be freed.
380  // If no compression is necessary, this will return NULL.
381  void * compressTexData(const void *src, int &w, int &h);
382  void determineCompressionInternal();
383  void determineTextureSize(RE_Render *r);
384 
385  // OpenGL data
387  int myGLType;
395 
396  void updateTextureWrap(RE_Render *r, bool force);
397  void updateFilters(RE_Render *r, bool force);
398 
399 private:
400  void buildFormatTable();
401 
402  // RE data
403  RE_TextureDataType myTextureDataType;
404  RE_GPUType myDataType;
405  RE_GPUType myClientType;
406  RE_TextureFormatExtra myFormatExtra;
407  RE_TextureDimension myTexDimension;
408  int myVectorSize;
409  int myWidth;
410  int myHeight;
411  int myDepth;
412  RE_TextureCompress myCompression;
413  bool myMipMapFlag;
414  bool myMipMapAutoGenFlag;
415  bool myAutoCompressFlag;
416  bool myCompressFlag;
417  bool myValidFlag;
418  bool myMutableFlag;
419  RE_TextureFilter myCurrentFilterState;
420  RE_TextureFilter myFilter;
421  int64 myTexSize;
422  IMG_FileAlphaInfo myAlphaInfo;
423  UT_ValArray<void *> myReferences;
425 
426  uint64 myBindlessHandle;
427  int myResidentCount;
428 
429 protected:
431  friend class RE_OGLRender;
432  friend class RE_OGLFramebuffer;
433  friend class RE_TextureMap;
434 };
435 
436 inline RE_TextureDimension
438 {
439  return myTexDimension;
440 }
441 
442 inline void
444 {
445  myTextureDataType = type;
446 
447  if(myVectorSize > 0)
448  setFormat(myDataType, myVectorSize, myFormatExtra);
449 }
450 
451 inline RE_TextureDataType
453 {
454  return myTextureDataType;
455 }
456 
457 inline bool
459 {
460  return myID != 0 && myValidFlag;
461 }
462 
463 inline RE_TextureID
465 {
466  return myID;
467 }
468 
469 inline RE_GPUType
471 {
472  return myDataType;
473 }
474 
475 inline RE_GPUType
477 {
478  return myClientType;
479 }
480 
481 inline int
483 {
484  return myVectorSize;
485 }
486 
489 {
490  return myFormatExtra;
491 }
492 
493 inline int
495 {
496  return myWidth;
497 }
498 
499 inline int
501 {
502  return myHeight;
503 }
504 
505 inline int
507 {
508  return myDepth;
509 }
510 
511 inline int
513 {
514  return myGLWidth;
515 }
516 
517 inline int
519 {
520  return myGLHeight;
521 }
522 
523 inline int
525 {
526  return myGLDepth;
527 }
528 
529 inline RE_TextureCompress
531 {
532  return myCompression;
533 }
534 
535 inline bool
537 {
538  return myAutoCompressFlag;
539 }
540 
541 inline bool
543 {
544  return true;
545 }
546 
547 inline bool
549 {
550  return myMipMapFlag;
551 }
552 
553 inline bool
555 {
556  return myMipMapFlag && myCanMipMap;
557 }
558 
559 inline bool
561 {
562  return myMipMapAutoGenFlag;
563 }
564 
565 inline RE_TexFiltType
567 {
568  return myCurrentFilterState.getMinFilter();
569 }
570 
571 inline RE_TexFiltType
573 {
574  return myCurrentFilterState.getMagFilter();
575 }
576 
577 inline float
579 {
580  return myCurrentFilterState.getLodBias();
581 }
582 
583 inline int
585 {
586  return myCurrentFilterState.getMaxAnisotropy();
587 }
588 
589 inline bool
591 {
592  return myCurrentFilterState.getWrapS();
593 }
594 
595 inline bool
597 {
598  return myCurrentFilterState.getWrapT();
599 }
600 
601 inline bool
603 {
604  return myCurrentFilterState.getWrapR();
605 }
606 
607 inline const char *
609 {
610  return "RE_OGLTexture";
611 }
612 
613 inline bool
615 {
616  return true;
617 }
618 
619 inline void
621 {
622  myValidFlag = true;
623 }
624 
625 inline int
627 {
628  return 1;
629 }
630 
631 inline float
633 {
634  return float(myWidth) / float(myGLWidth);
635 }
636 
637 inline float
639 {
640  return float(myHeight) / float(myGLHeight);
641 }
642 
643 inline float
645 {
646  return float(myDepth) / float(myGLDepth);
647 }
648 
649 inline int64
651 {
652  return myTexSize;
653 }
654 
655 inline int64
657 {
658  return getScanBytes(myGLWidth);
659 }
660 
661 
662 #endif
int getGLHeight() const
virtual int getMaxTextureIndex(RE_Render *r)
float getTexR() const
bool isMipMapped() const
bool getMipMapAutoGenerate() const
int getGLDepth() const
RE_GPUType getClientType() const
GLenum src
Definition: glew.h:2410
GLuint const GLchar * name
Definition: glew.h:1814
GLclampf GLclampf GLclampf alpha
Definition: glew.h:1520
bool getWrapS() const
virtual const char * className() const
#define RE_API
Definition: RE_API.h:10
GLint GLint xoffset
Definition: glew.h:1252
GLint GLint GLint GLint GLint GLint GLsizei width
Definition: glew.h:1252
int64 getTextureSize() const
GT_API const UT_StringHolder time
GLuint index
Definition: glew.h:1814
RE_TextureFormatExtra getFormatExtra() const
RE_TextureSwizzle
GLboolean GLboolean GLboolean GLboolean a
Definition: glew.h:9477
int getWidth() const
RE_TexFiltType getMagFilter() const
RE_TextureID myID
GLint GLint GLint GLint GLint GLint GLsizei GLsizei height
Definition: glew.h:1252
const GLdouble * m
Definition: glew.h:9124
RE_TextureDimension
bool getAutoCompression() const
int getDepth() const
int getMaxAnisotropy() const
float getLodBias() const
GLboolean red
Definition: glew.h:2171
virtual int getGLCreateType() const
virtual bool hasMipMapSupport(RE_Render *)
RE_TexFiltType getMagFilter() const
int getInternalFormat() const
Definition: RE_OGLTexture.h:99
GLdouble GLdouble z
Definition: glew.h:1559
RE_TextureDimension getTextureType() const
RE_TexFiltType
long long int64
Definition: SYS_Types.h:111
bool hasFileModTime() const
CompareResults OIIO_API compare(const ImageBuf &A, const ImageBuf &B, float failthresh, float warnthresh, ROI roi={}, int nthreads=0)
RE_GPUType
Definition: RE_Types.h:44
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
Definition: glew.h:2981
bool getWrapR() const
unsigned long long uint64
Definition: SYS_Types.h:112
GLint GLint GLint GLint GLint x
Definition: glew.h:1252
RE_TextureID getID() const
GLint GLint GLint GLint GLint GLint y
Definition: glew.h:1252
RE_TextureCompress myCompression
GLint GLenum GLsizei GLint GLsizei const void * data
Definition: glew.h:1379
unsigned int RE_TextureID
bool getWrapT() const
GLint GLint GLsizei GLsizei GLsizei GLint border
Definition: glew.h:1254
RE_TextureFormatExtra
GLubyte GLubyte GLubyte GLubyte w
Definition: glew.h:1890
RE_TexClampType
int getFormatSize() const
int getFileModTime() const
GLclampf green
Definition: glew.h:1520
virtual bool hasTextureSupport(RE_Render *r)
RE_TextureCompress getCompression() const
RE_TextureBorder
int64 getScanBytes() const
void setFileModTime(int time)
GLclampf GLclampf blue
Definition: glew.h:1520
GLfloat GLfloat GLfloat GLfloat h
Definition: glew.h:8011
GLfloat bias
Definition: glew.h:10274
int getMaxAnisotropy() const
virtual int64 getMemoryUsage(bool inclusive) const
int getHeight() const
GLuint GLuint GLsizei GLenum type
Definition: glew.h:1253
RE_TexFiltType getMinFilter() const
GLuint GLsizei GLsizei GLchar * label
Definition: glew.h:8986
uint64 getTextureHandle() const
IMG_FileAlphaInfo
RE_TextureDataType
GLint GLint GLint GLint zoffset
Definition: glew.h:1252
virtual bool isValid() const
Cached object implementation for RE_TextureCache.
float getTexS() const
float getLodBias() const
RE_TexClampType getWrapR() const
GLenum GLsizei const GLuint GLboolean enabled
Definition: glew.h:2579
RE_TexClampType getWrapS() const
RE_TextureDataType getDataType() const
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: glew.h:1254
GLdouble GLdouble GLdouble r
Definition: glew.h:1406
RE_GPUType getFormatType() const
RE_TexFiltType getMinFilter() const
GLint GLint GLint yoffset
Definition: glew.h:1252
void setAlphaInfo(IMG_FileAlphaInfo a)
IMG_FileAlphaInfo getAlphaInfo() const
int getGLWidth() const
void setDataType(RE_TextureDataType type)
float getTexT() const
GLsizei samples
Definition: glew.h:2998
RE_TextureCompress
RE_TexClampType getWrapT() const
bool getMipMap() const
RE_TextureCompare
bool isMutable() const
Definition: RE_OGLTexture.h:63
GLint level
Definition: glew.h:1252
GLdouble GLdouble t
Definition: glew.h:1398
void setFormat(RE_GPUType data, int vectorsize, RE_TextureFormatExtra format_extra=RE_TEXTURE_FORMAT_EXTRA_NONE)
GLint GLint GLsizei GLsizei GLsizei depth
Definition: glew.h:1254
type
Definition: core.h:528
std::enable_if< internal::is_string< S >::value >::type print(std::basic_ostream< FMT_CHAR(S)> &os, const S &format_str, const Args &...args)
Definition: ostream.h:146