Visualization Library 2.0.0

A lightweight C++ OpenGL middleware for 2D/3D graphics

VL     Star     Watch     Fork     Issue

[Download] [Tutorials] [All Classes] [Grouped Classes]
Texture.cpp
Go to the documentation of this file.
1 /**************************************************************************************/
2 /* */
3 /* Visualization Library */
4 /* http://visualizationlibrary.org */
5 /* */
6 /* Copyright (c) 2005-2020, Michele Bosi */
7 /* All rights reserved. */
8 /* */
9 /* Redistribution and use in source and binary forms, with or without modification, */
10 /* are permitted provided that the following conditions are met: */
11 /* */
12 /* - Redistributions of source code must retain the above copyright notice, this */
13 /* list of conditions and the following disclaimer. */
14 /* */
15 /* - Redistributions in binary form must reproduce the above copyright notice, this */
16 /* list of conditions and the following disclaimer in the documentation and/or */
17 /* other materials provided with the distribution. */
18 /* */
19 /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND */
20 /* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED */
21 /* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE */
22 /* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR */
23 /* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES */
24 /* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */
25 /* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON */
26 /* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */
27 /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */
28 /* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
29 /* */
30 /**************************************************************************************/
31 
32 #include <vlGraphics/Texture.hpp>
33 #include <vlCore/checks.hpp>
34 #include <vlCore/Image.hpp>
35 #include <vlCore/math_utils.hpp>
36 #include <vlCore/Say.hpp>
37 #include <vlCore/Log.hpp>
38 
39 using namespace vl;
40 
41 namespace
42 {
43  // if you think your application has a bug that depends on this function you are wrong
44  int getDefaultFormat(ETextureFormat internal_format)
45  {
46  // OpenGL ES requires the internal format to be equal to the source image format when creating textures
47 #if defined(VL_OPENGL_ES1) || defined(VL_OPENGL_ES2)
48  return internal_format;
49 #else
50  switch(internal_format)
51  {
52  case TF_ALPHA:
53  case TF_ALPHA4:
54  case TF_ALPHA8:
55  case TF_ALPHA12:
56  case TF_ALPHA16:
57  return GL_ALPHA;
58 
59  case TF_LUMINANCE:
60  case TF_LUMINANCE4:
61  case TF_LUMINANCE8:
62  case TF_LUMINANCE12:
63  case TF_LUMINANCE16:
64  case TF_SLUMINANCE:
65  case TF_SLUMINANCE8:
66  return GL_LUMINANCE;
67 
68  case TF_LUMINANCE_ALPHA:
77  return GL_LUMINANCE_ALPHA;
78 
79  case TF_INTENSITY:
80  case TF_INTENSITY4:
81  case TF_INTENSITY8:
82  case TF_INTENSITY12:
83  case TF_INTENSITY16:
84  return GL_INTENSITY;
85 
86  case TF_RED:
87  case TF_R8:
88  case TF_R8_SNORM:
89  case TF_R16:
90  case TF_R16_SNORM:
91  case TF_R16F:
92  case TF_R32F:
93  return GL_RED;
94 
95  case TF_RG:
96  case TF_RG8:
97  case TF_RG8_SNORM:
98  case TF_RG16:
99  case TF_RG16_SNORM:
100  case TF_RG16F:
101  case TF_RG32F:
102  return GL_RG;
103 
104  case TF_RGB:
105  case TF_RGB4:
106  case TF_RGB5:
107  case TF_RGB8:
108  case TF_RGB8_SNORM:
109  case TF_RGB10:
110  case TF_RGB12:
111  case TF_RGB16:
112  // case TF_RGB16_SNORM:
113  case TF_RGB16F:
114  case TF_RGB32F:
115  case TF_R3_G3_B2:
116  case TF_R11F_G11F_B10F:
117  // case TF_RGB9_A5:
118  case TF_SRGB8:
119  return GL_RGB;
120 
121  case TF_RGBA:
122  case TF_RGBA2:
123  case TF_RGBA4:
124  case TF_RGBA8:
125  case TF_RGBA8_SNORM:
126  case TF_RGBA12:
127  case TF_RGBA16:
128  case TF_RGBA16_SNORM:
129  case TF_RGBA16F:
130  case TF_RGBA32F:
131  case TF_RGB5_A1:
132  case TF_RGB10_A2:
133  case TF_SRGB8_ALPHA8:
134  return GL_RGBA;
135 
136  case TF_R8I:
137  case TF_R8UI:
138  case TF_R16I:
139  case TF_R16UI:
140  case TF_R32I:
141  case TF_R32UI:
142  return GL_RED_INTEGER;
143 
144  case TF_RG8I:
145  case TF_RG8UI:
146  case TF_RG16I:
147  case TF_RG16UI:
148  case TF_RG32I:
149  case TF_RG32UI:
150  return GL_RG_INTEGER;
151 
152  case TF_RGB8I:
153  // case TF_RGB8I_EXT: // Has the same value has above
154  case TF_RGB8UI:
155  // case TF_RGB8UI_EXT: // Has the same value has above
156  case TF_RGB16I:
157  // case TF_RGB16I_EXT: // Has the same value has above
158  case TF_RGB16UI:
159  // case TF_RGB16UI_EXT: // Has the same value has above
160  case TF_RGB32I:
161  // case TF_RGB32I_EXT: // Has the same value has above
162  case TF_RGB32UI:
163  // case TF_RGB32UI_EXT: // Has the same value has above
164  return GL_RGB_INTEGER;
165 
166  case TF_RGBA8I:
167  // case TF_RGBAI_EXT: // Has the same value has above
168  case TF_RGBA8UI:
169  // case TF_RGBA8UI_EXT: // Has the same value has above
170  case TF_RGBA16I:
171  // case TF_RGBA16I_EXT: // Has the same value has above
172  case TF_RGBA16UI:
173  // case TF_RGBA16UI_EXT: // Has the same value has above
174  case TF_RGBA32I:
175  // case TF_RGBA32I_EXT: // Has the same value has above
176  case TF_RGBA32UI:
177  // case TF_RGBA32UI_EXT: // Has the same value has above
178  case TF_RGB10_A2UI:
179  return GL_RGBA_INTEGER;
180 
181  case TF_DEPTH_STENCIL:
182  case TF_DEPTH24_STENCIL8:
184  return GL_DEPTH_STENCIL;
185 
186  case TF_DEPTH_COMPONENT:
191  return GL_DEPTH_COMPONENT;
192 
193  // GL_EXT_texture_integer
194  case TF_ALPHA8I_EXT:
195  case TF_ALPHA8UI_EXT:
196  case TF_ALPHA16I_EXT:
197  case TF_ALPHA16UI_EXT:
198  case TF_ALPHA32I_EXT:
199  case TF_ALPHA32UI_EXT:
200  return GL_ALPHA_INTEGER;
201 
202  case TF_INTENSITY8I_EXT:
203  case TF_INTENSITY8UI_EXT:
204  case TF_INTENSITY16I_EXT:
206  case TF_INTENSITY32I_EXT:
208  return GL_RED_INTEGER; // Nothing associated with intensity in GL_EXT_texture_integer
209 
210  case TF_LUMINANCE8I_EXT:
211  case TF_LUMINANCE8UI_EXT:
213  case TF_LUMINANCE16I_EXT:
214  case TF_LUMINANCE32I_EXT:
216  return GL_LUMINANCE_INTEGER_EXT;
217 
224  return GL_LUMINANCE_ALPHA_INTEGER_EXT;
225 
226  default:
227  return GL_RED;
228  }
229 #endif
230  }
231 
232  // if you think your application has a bug that depends on this function you are wrong
233  int getDefaultType(ETextureFormat internal_format)
234  {
235  switch( internal_format )
236  {
237  case TF_ALPHA4:
238  case TF_ALPHA8:
239  case TF_ALPHA8UI_EXT:
240  case TF_INTENSITY4:
241  case TF_INTENSITY8:
242  case TF_INTENSITY8UI_EXT:
243  case TF_LUMINANCE4:
244  case TF_LUMINANCE8:
245  case TF_LUMINANCE8UI_EXT:
248  case TF_R8:
249  case TF_R8UI:
250  case TF_RG8:
251  case TF_RG8UI:
252  case TF_RGB8:
253  case TF_RGB8UI:
254  case TF_RGBA8:
255  case TF_RGBA8UI:
256  return GL_UNSIGNED_BYTE;
257 
258  case TF_ALPHA8I_EXT:
259  case TF_INTENSITY8I_EXT:
260  case TF_LUMINANCE8I_EXT:
262  case TF_R8I:
263  case TF_RG8I:
264  case TF_RGB8I:
265  case TF_RGBA8I:
266  return GL_BYTE;
267 
268  case TF_ALPHA12:
269  case TF_ALPHA16:
270  case TF_ALPHA16UI_EXT:
271  case TF_INTENSITY12:
272  case TF_INTENSITY16:
274  case TF_LUMINANCE12:
275  case TF_LUMINANCE16:
279  case TF_R16:
280  case TF_R16UI:
281  case TF_RG16:
282  case TF_RG16UI:
283  case TF_RGB10:
284  case TF_RGB12:
285  case TF_RGB16:
286  case TF_RGB16UI:
287  case TF_RGBA12:
288  case TF_RGBA16:
289  case TF_RGBA16UI:
291  return GL_UNSIGNED_SHORT;
292 
293  case TF_ALPHA16I_EXT:
294  case TF_INTENSITY16I_EXT:
295  case TF_LUMINANCE16I_EXT:
297  case TF_R16I:
298  case TF_RG16I:
299  case TF_RGB16I:
300  case TF_RGBA16I:
301  return GL_SHORT;
302 
303  case TF_ALPHA32UI_EXT:
307  case TF_R32UI:
308  case TF_RG32UI:
309  case TF_RGB32UI:
310  case TF_RGBA32UI:
313  return GL_UNSIGNED_INT;
314 
315  case TF_ALPHA32I_EXT:
316  case TF_INTENSITY32I_EXT:
317  case TF_LUMINANCE32I_EXT:
319  case TF_R32I:
320  case TF_RG32I:
321  case TF_RGB32I:
322  case TF_RGBA32I:
323  return GL_INT;
324 
325  case TF_DEPTH24_STENCIL8:
326  return GL_UNSIGNED_INT_24_8;
327 
328  case TF_R16F:
329  case TF_R32F:
330  case TF_RG16F:
331  case TF_RG32F:
332  case TF_RGB16F:
333  case TF_RGB32F:
334  case TF_RGBA16F:
335  case TF_RGBA32F:
336  case TF_R11F_G11F_B10F:
337  case TF_ALPHA16F:
338  case TF_ALPHA32F:
339  case TF_INTENSITY16F:
340  case TF_INTENSITY32F:
341  case TF_LUMINANCE16F:
342  case TF_LUMINANCE32F:
346  return GL_FLOAT;
347 
349  return GL_FLOAT_32_UNSIGNED_INT_24_8_REV;
350 
351  default:
352  return GL_UNSIGNED_BYTE;
353  }
354  }
355 }
356 //-----------------------------------------------------------------------------
357 // Texture
358 //-----------------------------------------------------------------------------
360 {
361  if ( mHandle && mManaged ) {
362  glDeleteTextures( 1, &mHandle ); VL_CHECK_OGL();
363  }
364 
365  reset();
366  // getTexParameter()->mDirty = true;
367 }
368 //-----------------------------------------------------------------------------
370 {
371  destroyTexture();
372 }
373 //-----------------------------------------------------------------------------
374 void Texture::reset()
375 {
378  setBorder(0);
379  setWidth(0);
380  setHeight(0);
381  setDepth(0);
382  mHandle = 0;
383  mManaged = true;
384  mSetupParams = NULL;
386  mSamples = 0;
387  mFixedSamplesLocation = true;
388  // TexParameter is not reset but is marked dirty
389  mTexParameter->setDirty(true);
390 }
391 //-----------------------------------------------------------------------------
393 {
394  VL_DEBUG_SET_OBJECT_NAME()
396  reset();
397  if (!createTexture(vl::TD_TEXTURE_1D, format, width, 0, 0, border, NULL, 0, 0))
398  {
399  Log::error("1D texture creation failed!\n");
400  }
401 }
402 //-----------------------------------------------------------------------------
404 {
405  VL_DEBUG_SET_OBJECT_NAME()
407  reset();
408  if (!createTexture(vl::TD_TEXTURE_2D, format, width, height, 0, border, NULL, 0, 0))
409  {
410  Log::error("2D texture constructor failed!\n");
411  }
412 }
413 //-----------------------------------------------------------------------------
415 {
416  VL_DEBUG_SET_OBJECT_NAME()
418  reset();
419  if (!createTexture(vl::TD_TEXTURE_3D, format, width, height, depth, border, NULL, 0, 0))
420  {
421  Log::error("3D texture constructor failed!\n");
422  }
423 }
424 //-----------------------------------------------------------------------------
425 Texture::Texture(const Image* image, ETextureFormat format, bool mipmaps , bool border)
426 {
427  VL_DEBUG_SET_OBJECT_NAME()
429  reset();
430 
431  if (image && image->isValid())
432  {
433  switch(image->dimension())
434  {
435 #if defined(VL_OPENGL)
436  case ID_1D: prepareTexture1D(image, format, mipmaps, border); break;
437 #else
438  case ID_1D: prepareTexture2D(image, format, mipmaps, border); break;
439 #endif
440  case ID_2D: prepareTexture2D(image, format, mipmaps, border); break;
441  case ID_3D: prepareTexture3D(image, format, mipmaps, border); break;
442  case ID_Cubemap: prepareTextureCubemap(image, format, mipmaps, border); break;
443  default:
444  break;
445  }
446  if( !createTexture() )
447  Log::error("Texture constructor failed!\n");
448  }
449  else
450  Log::bug("Texture constructor called with an invalid Image!\n");
451 }
452 //-----------------------------------------------------------------------------
453 Texture::Texture(const String& image_path, ETextureFormat format, bool mipmaps , bool border)
454 {
455  VL_DEBUG_SET_OBJECT_NAME()
457  reset();
458 
459  ref<Image> image = vl::loadImage(image_path);
460 
461  if (image && image->isValid())
462  {
463  switch(image->dimension())
464  {
465 #if defined(VL_OPENGL)
466  case ID_1D: prepareTexture1D(image.get(), format, mipmaps, border); break;
467 #else
468  case ID_1D: prepareTexture2D(image.get(), format, mipmaps, border); break;
469 #endif
470  case ID_2D: prepareTexture2D(image.get(), format, mipmaps, border); break;
471  case ID_3D: prepareTexture3D(image.get(), format, mipmaps, border); break;
472  case ID_Cubemap: prepareTextureCubemap(image.get(), format, mipmaps, border); break;
473  default:
474  break;
475  }
476  if( !createTexture() )
477  Log::error("Texture constructor failed!\n");
478  }
479  else
480  Log::bug("Texture constructor called with an invalid Image!\n");
481 }
482 //-----------------------------------------------------------------------------
484 {
485  VL_DEBUG_SET_OBJECT_NAME()
487  reset();
488 }
489 //-----------------------------------------------------------------------------
490 bool Texture::isValid() const
491 {
492  bool a = mWidth != 0 && mHeight == 0 && mDepth == 0;
493  bool b = mWidth != 0 && mHeight != 0 && mDepth == 0;
494  bool c = mWidth != 0 && mHeight != 0 && mDepth != 0;
495  return handle() != 0 && (a|b|c);
496 }
497 //-----------------------------------------------------------------------------
498 bool Texture::supports(ETextureDimension tex_dimension, ETextureFormat tex_format, int mip_level, EImageDimension img_dimension, int w, int h, int d, bool border, int samples, bool fixedsamplelocations, bool verbose)
499 {
500  VL_CHECK_OGL();
501 
502  // clear errors
503 
504  glGetError();
505 
506  // texture buffer
507 
508  if ( tex_dimension == TD_TEXTURE_2D_MULTISAMPLE || tex_dimension == TD_TEXTURE_2D_MULTISAMPLE_ARRAY )
509  {
511  {
512  if (verbose) Log::error("Texture::supports(): multisample textures not supported by the current hardware.\n");
513  return false;
514  }
515 
516  if (border)
517  {
518  if (verbose) Log::error("Texture::supports(): multisample textures cannot have borders.\n");
519  return false;
520  }
521 
522  if (mip_level)
523  {
524  if (verbose) Log::error("Texture::supports(): multisample textures cannot have mip levels other than 0.\n");
525  return false;
526  }
527 
528  // these should be non zero
529  VL_CHECK( w && h );
530  }
531 
532  if ( tex_dimension == TD_TEXTURE_BUFFER )
533  {
534  if (!Has_Texture_Buffer)
535  {
536  if (verbose) Log::error("Texture::supports(): texture buffer not supported by the current hardware.\n");
537  return false;
538  }
539 
540  if (border)
541  {
542  if (verbose) Log::error("Texture::supports(): a texture buffer cannot have borders.\n");
543  return false;
544  }
545 
546  if (mip_level)
547  {
548  if (verbose) Log::error("Texture::supports(): a texture buffer cannot have mip levels other than 0.\n");
549  return false;
550  }
551 
552  // these should be zero
553  VL_CHECK( !(w||h||d) );
554  }
555 
556  // cubemaps
557 
558  if ( tex_dimension == TD_TEXTURE_CUBE_MAP )
559  {
561  {
562  if (verbose) Log::error("Texture::supports(): texture cubemap not supported by the current hardware.\n");
563  return false;
564  }
565 
566  if ( w != h )
567  {
568  if (verbose) Log::error("Texture::supports(): cubemaps must have square faces.\n");
569  return false;
570  }
571  }
572 
573  // texture arrays
574 
575  if ( tex_dimension == TD_TEXTURE_1D_ARRAY || tex_dimension == TD_TEXTURE_2D_ARRAY )
576  {
577  if (border)
578  {
579  if (verbose) Log::error("Texture::supports(): you cannot create a texture array with borders.\n");
580  return false;
581  }
582 
583  if(!Has_Texture_Array)
584  {
585  if (verbose) Log::error("Texture::supports(): texture array not supported by the current hardware.\n");
586  return false;
587  }
588 
589  if ( img_dimension )
590  {
591  if ( (img_dimension != ID_2D && tex_dimension == TD_TEXTURE_1D_ARRAY) || ( img_dimension != ID_3D && tex_dimension == TD_TEXTURE_2D_ARRAY ) )
592  {
593  if (verbose) Log::error("Texture::supports(): the image dimensions are not suitable to create a texture array."
594  "To create a 1D texture array you need a 2D image and to create a 2D texture array you need a 3D image.\n");
595  return false;
596  }
597  }
598  }
599 
600  // texture rectangle
601 
602  if (tex_dimension == TD_TEXTURE_RECTANGLE)
603  {
605  {
606  if (verbose) Log::error("Texture::supports(): texture rectangle not supported by the current hardware.\n");
607  return false;
608  }
609 
610  if ( mip_level != 0 )
611  {
612  if (verbose) Log::error("Texture::supports(): TD_TEXTURE_RECTANGLE textures do not support mipmapping level other than zero.\n");
613  return false;
614  }
615 
616  if (border)
617  {
618  if (verbose) Log::error("Texture::supports(): TD_TEXTURE_RECTANGLE textures do not allow textures borders\n");
619  return false;
620  }
621  }
622 
623  // OpenGL ES does not support proxy textures and glGetTexLevelParameter*
624 #if defined(VL_OPENGL)
625  int width = 0;
626 
627  int default_format = getDefaultFormat(tex_format);
628  int default_type = getDefaultType(tex_format);
629 
630  if (tex_dimension == TD_TEXTURE_BUFFER)
631  {
632  width = 1; // pass the test
633  }
634  else
635  if (tex_dimension == TD_TEXTURE_2D_MULTISAMPLE)
636  {
637  glTexImage2DMultisample(GL_PROXY_TEXTURE_2D_MULTISAMPLE, samples, tex_format, w, h, fixedsamplelocations );
638  if ( glGetError() )
639  {
640  if (verbose) Log::error( Say("Texture::supports(): 2d multisample texture requested with too many samples for the current hardware! (%n)\n") << samples );
641  return false;
642  }
643  glGetTexLevelParameteriv(GL_PROXY_TEXTURE_2D_MULTISAMPLE, 0, GL_TEXTURE_WIDTH, &width); VL_CHECK_OGL();
644  }
645  else
646  if (tex_dimension == TD_TEXTURE_2D_MULTISAMPLE_ARRAY)
647  {
648  glTexImage3DMultisample(GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY, samples, tex_format, w, h, d, fixedsamplelocations ); VL_CHECK_OGL();
649  if ( glGetError() )
650  {
651  if (verbose) Log::error( Say("Texture::supports(): multisample texture array requested with too many samples for the current hardware! (%n)\n") << samples );
652  return false;
653  }
654  glGetTexLevelParameteriv(GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY, 0, GL_TEXTURE_WIDTH, &width); VL_CHECK_OGL();
655  }
656  else
657  if (tex_dimension == TD_TEXTURE_CUBE_MAP)
658  {
659  glTexImage2D(GL_PROXY_TEXTURE_CUBE_MAP, mip_level, tex_format, w + (border?2:0), h + (border?2:0), border?1:0, default_format, default_type, NULL);
660  glGetTexLevelParameteriv(GL_PROXY_TEXTURE_CUBE_MAP, mip_level, GL_TEXTURE_WIDTH, &width);
661  }
662  else
663  if (tex_dimension == TD_TEXTURE_2D_ARRAY)
664  {
665  glTexImage3D(GL_PROXY_TEXTURE_2D_ARRAY, mip_level, tex_format, w + (border?2:0), h + (border?2:0), d + (border?2:0), border?1:0, default_format, default_type, NULL);
666  glGetTexLevelParameteriv(GL_PROXY_TEXTURE_2D_ARRAY, mip_level, GL_TEXTURE_WIDTH, &width);
667  }
668  else
669  if (tex_dimension == TD_TEXTURE_3D)
670  {
671  glTexImage3D(GL_PROXY_TEXTURE_3D, mip_level, tex_format, w + (border?2:0), h + (border?2:0), d + (border?2:0), border?1:0, default_format, default_type, NULL);
672  glGetTexLevelParameteriv(GL_PROXY_TEXTURE_3D, mip_level, GL_TEXTURE_WIDTH, &width);
673  }
674  else
675  if (tex_dimension == TD_TEXTURE_RECTANGLE)
676  {
677  glTexImage2D(GL_PROXY_TEXTURE_RECTANGLE, mip_level, tex_format, w, h, 0, default_format, default_type, NULL);
678  glGetTexLevelParameteriv(GL_PROXY_TEXTURE_RECTANGLE, mip_level, GL_TEXTURE_WIDTH, &width);
679  }
680  else
681  if (tex_dimension == TD_TEXTURE_1D_ARRAY)
682  {
683  glTexImage2D(GL_PROXY_TEXTURE_1D_ARRAY, mip_level, tex_format, w, h, 0, default_format, default_type, NULL);
684  glGetTexLevelParameteriv(GL_PROXY_TEXTURE_1D_ARRAY, mip_level, GL_TEXTURE_WIDTH, &width);
685  }
686  else
687  if (tex_dimension == TD_TEXTURE_2D)
688  {
689  glTexImage2D(GL_PROXY_TEXTURE_2D, mip_level, tex_format, w + (border?2:0), h + (border?2:0), border?1:0, default_format, default_type, NULL);
690  glGetTexLevelParameteriv(GL_PROXY_TEXTURE_2D, mip_level, GL_TEXTURE_WIDTH, &width);
691  }
692  else
693  if (tex_dimension == TD_TEXTURE_1D)
694  {
695  glTexImage1D(GL_PROXY_TEXTURE_1D, mip_level, tex_format, w + (border?2:0), border?1:0, default_format, default_type, NULL);
696  glGetTexLevelParameteriv(GL_PROXY_TEXTURE_1D, mip_level, GL_TEXTURE_WIDTH, &width);
697  }
698 
699  GLenum err = glGetError();
700  return err == 0 && width != 0;
701 #else
702  return true;
703 #endif
704 }
705 //-----------------------------------------------------------------------------
706 bool Texture::createTexture(ETextureDimension tex_dimension, ETextureFormat tex_format, int w, int h, int d, bool border, BufferObject* buffer_object, int samples, bool fixedsamplelocations)
707 {
708  VL_CHECK_OGL()
709 
710  // Destroy previous texture but save and restore the setup params
711  ref<SetupParams> setup_params = mSetupParams;
712  destroyTexture();
713  mSetupParams = setup_params;
714 
715  if ( tex_dimension == TD_TEXTURE_BUFFER )
716  {
717  if( ! buffer_object || ! buffer_object->handle() || ! glIsBuffer( buffer_object->handle() ) )
718  {
719  Log::bug( "Texture::createTexture() requires a non NULL valid buffer object in order to create a texture buffer!\n" );
720  VL_CHECK(buffer_object);
721  VL_CHECK(buffer_object->handle());
722  VL_CHECK(glIsBuffer(buffer_object->handle()));
723  return false;
724  }
725 
726  // the buffer object must not be empty!
727  GLint buffer_size = 0;
728  glBindBuffer(GL_TEXTURE_BUFFER, buffer_object->handle());
729  glGetBufferParameteriv(GL_TEXTURE_BUFFER, GL_BUFFER_SIZE, &buffer_size);
730  glBindBuffer(GL_TEXTURE_BUFFER, 0);
731  if ( buffer_size == 0 )
732  {
733  Log::bug("Texture::createTexture(): cannot create a texture buffer with an empty buffer object!\n"); VL_TRAP();
734  return false;
735  }
736  }
737 
738  if ( !supports(tex_dimension , tex_format, 0, ID_None, w, h, d, border, samples, fixedsamplelocations, true) )
739  {
740  VL_CHECK_OGL()
741  Log::bug("Texture::createTexture(): the format/size combination requested is not supported!\n"); VL_TRAP();
742  return false;
743  }
744 
745  glGenTextures( 1, &mHandle ); VL_CHECK_OGL();
746 
747  if (!mHandle)
748  {
749  Log::bug("Texture::createTexture(): texture creation failed!\n");
750  VL_TRAP();
751  return false;
752  }
753 
754  setDimension(tex_dimension);
755  setInternalFormat(tex_format);
756  setWidth(w);
757  setHeight(h);
758  setDepth(d);
759  setBorder(border);
760  mBufferObject = buffer_object; // the user cannot change this
761  mSamples = samples;
762  mFixedSamplesLocation = fixedsamplelocations;
763  glBindTexture(tex_dimension, mHandle); VL_CHECK_OGL();
764 
765  int default_format = getDefaultFormat(tex_format);
766  int default_type = getDefaultType(tex_format);
767 
768  if (tex_dimension == TD_TEXTURE_2D_MULTISAMPLE)
769  {
770  glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, samples, tex_format, w, h, fixedsamplelocations ); VL_CHECK_OGL();
771  }
772  else
773  if (tex_dimension == TD_TEXTURE_2D_MULTISAMPLE_ARRAY)
774  {
775  glTexImage3DMultisample(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, samples, tex_format, w, h, d, fixedsamplelocations ); VL_CHECK_OGL();
776  }
777  else
778  if (tex_dimension == TD_TEXTURE_BUFFER)
779  {
780  VL_CHECK(buffer_object)
781  VL_CHECK(buffer_object->handle())
782  glTexBuffer(GL_TEXTURE_BUFFER, tex_format, buffer_object->handle());
783  unsigned int glerr = glGetError();
784  if (glerr != GL_NO_ERROR)
785  {
786  String msg( (const char*)getGLErrorString(glerr) );
787  Log::bug( "Texture::createTexture(): glTexBuffer() failed with error: '" + msg + "'.\n" );
788  Log::error("Probably you supplied a non supported texture format! Review the glTexBuffer() man page for a complete list of supported texture formats.\n");
789  VL_TRAP();
790  }
791  }
792  else
793  if (tex_dimension == TD_TEXTURE_CUBE_MAP)
794  {
795  glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, tex_format, w + (border?2:0), h + (border?2:0), border?1:0, default_format, default_type, NULL);
796  glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, tex_format, w + (border?2:0), h + (border?2:0), border?1:0, default_format, default_type, NULL);
797  glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, tex_format, w + (border?2:0), h + (border?2:0), border?1:0, default_format, default_type, NULL);
798  glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, tex_format, w + (border?2:0), h + (border?2:0), border?1:0, default_format, default_type, NULL);
799  glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, tex_format, w + (border?2:0), h + (border?2:0), border?1:0, default_format, default_type, NULL);
800  glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, tex_format, w + (border?2:0), h + (border?2:0), border?1:0, default_format, default_type, NULL);
801  VL_CHECK_OGL();
802  }
803  else
804  if (tex_dimension == TD_TEXTURE_2D_ARRAY)
805  {
806  VL_glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, tex_format, w + (border?2:0), h + (border?2:0), d + (border?2:0), border?1:0, default_format, default_type, NULL);
807  VL_CHECK_OGL();
808  }
809  else
810  if (tex_dimension == TD_TEXTURE_3D)
811  {
812  VL_glTexImage3D(GL_TEXTURE_3D, 0, tex_format, w + (border?2:0), h + (border?2:0), d + (border?2:0), border?1:0, default_format, default_type, NULL);
813  VL_CHECK_OGL();
814  }
815  else
816  if (tex_dimension == TD_TEXTURE_RECTANGLE)
817  {
818  glTexImage2D(GL_TEXTURE_RECTANGLE, 0, tex_format, w, h, 0, default_format, default_type, NULL);
819  VL_CHECK_OGL();
820  }
821  else
822  if (tex_dimension == TD_TEXTURE_1D_ARRAY)
823  {
824  glTexImage2D(GL_TEXTURE_1D_ARRAY, 0, tex_format, w, h, 0, default_format, default_type, NULL);
825  VL_CHECK_OGL();
826  }
827  else
828  if (tex_dimension == TD_TEXTURE_2D)
829  {
830  glTexImage2D(GL_TEXTURE_2D, 0, tex_format, w + (border?2:0), h + (border?2:0), border?1:0, default_format, default_type, NULL);
831  VL_CHECK_OGL();
832  }
833  else
834  if (tex_dimension == TD_TEXTURE_1D)
835  {
836  glTexImage1D(GL_TEXTURE_1D, 0, tex_format, w + (border?2:0), border?1:0, default_format, default_type, NULL);
837  VL_CHECK_OGL();
838  }
839 
840  glBindTexture(tex_dimension, 0); VL_CHECK_OGL();
841  return true;
842 }
843 //-----------------------------------------------------------------------------
844 bool Texture::setMipLevel(int mip_level, const Image* img, bool gen_mipmaps)
845 {
846  VL_CHECK_OGL()
847 
848 #if defined(VL_OPENGL_ES1) || defined(VL_OPENGL_ES2)
849  if (internalFormat() != img->format())
850  {
851  Log::bug("Texture::setMipLevel(): under OpenGL ES the texture internal format must match the source image format!\n");
852  return false;
853  }
854 #endif
855 
857  {
858  Log::bug("You cannot call Texture::setMipLevel() on a texture buffer or on a multisample texture!\n");
859  return false;
860  }
861 
862  if (!mHandle)
863  {
864  Log::error("Texture::setMipLevel(): texture hasn't been created yet, please call createTexture() first!\n");
865  VL_TRAP();
866  return false;
867  }
868 
869  if ( !supports(dimension(), internalFormat(), mip_level, img->dimension(), img->width(), img->height(), img->depth(), border(), 0, 0, true) )
870  {
871  VL_CHECK_OGL()
872  Log::error("Texture::setMipLevel(): the format/size combination requested is not supported.\n");
873  return false;
874  }
875 
876  glPixelStorei( GL_UNPACK_ALIGNMENT, img->byteAlignment() ); VL_CHECK_OGL()
877 
878  glBindTexture( dimension(), mHandle ); VL_CHECK_OGL()
879 
880  int w = width() + (border()?2:0);
881  int h = height() + (border()?2:0);
882  int d = depth() + (border()?2:0);
883  int is_compressed = (int)img->format() == (int)internalFormat() && isCompressedFormat( internalFormat() );
884 
885  bool use_glu = false;
886  GLint generate_mipmap_orig = GL_FALSE;
887  if ( gen_mipmaps )
888  {
889  if ( Has_glGenerateMipmaps )
890  {
891  // do nothing, we will use glGenerateMipmaps later
892  }
893  else
895  {
896  glGetTexParameteriv( dimension(), GL_GENERATE_MIPMAP, &generate_mipmap_orig ); VL_CHECK_OGL()
897  glTexParameteri(dimension(), GL_GENERATE_MIPMAP, GL_TRUE); VL_CHECK_OGL()
898  }
899  else
900  {
901  if (mip_level > 0) // because GLU regenerates the whole mip-mapping chain
902  Log::error("Texture::setMipLevel(): automatic mipmaps generation for levels below 0 requires OpenGL 1.4 minimum.\n");
903  else
904  use_glu = true;
905 
906  #define VL_IS_POW_2(x) ((x != 0) && ((x & (x - 1)) == 0))
907  if ( !VL_IS_POW_2(w) || !VL_IS_POW_2(h) )
908  Log::warning("Texture::setMipLevel(): the image will be rescaled to the nearest upper power of 2.\n");
909  }
910  }
911 
912  if ( use_glu && is_compressed )
913  {
914  Log::error("Texture::setMipLevel(): could not generate compressed mipmaps, OpenGL 1.4 required.\n");
915  use_glu = false;
916  }
917 
918  if ( use_glu && dimension() == TD_TEXTURE_3D )
919  {
920  Log::error("Texture::setMipLevel(): could not generate 3D mipmaps, OpenGL 1.4 required.\n");
921  use_glu = false;
922  }
923 
925  {
926  if (is_compressed)
927  {
928  VL_CHECK( img->requiredMemory() % 6 == 0 );
929  int bytes = img->requiredMemory() / 6;
930  glCompressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, mip_level, internalFormat(), w, h, border()?1:0, bytes, img->pixelsXP());
931  glCompressedTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, mip_level, internalFormat(), w, h, border()?1:0, bytes, img->pixelsXN());
932  glCompressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, mip_level, internalFormat(), w, h, border()?1:0, bytes, img->pixelsYP());
933  glCompressedTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, mip_level, internalFormat(), w, h, border()?1:0, bytes, img->pixelsYN());
934  glCompressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, mip_level, internalFormat(), w, h, border()?1:0, bytes, img->pixelsZP());
935  glCompressedTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, mip_level, internalFormat(), w, h, border()?1:0, bytes, img->pixelsZN());
936  VL_CHECK_OGL()
937  }
938  else
939  {
940  if (use_glu)
941  {
942  gluBuild2DMipmaps(GL_TEXTURE_CUBE_MAP_POSITIVE_X, internalFormat(), w, h, img->format(), img->type(), img->pixelsXP());
943  gluBuild2DMipmaps(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, internalFormat(), w, h, img->format(), img->type(), img->pixelsXN());
944  gluBuild2DMipmaps(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, internalFormat(), w, h, img->format(), img->type(), img->pixelsYP());
945  gluBuild2DMipmaps(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, internalFormat(), w, h, img->format(), img->type(), img->pixelsYN());
946  gluBuild2DMipmaps(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, internalFormat(), w, h, img->format(), img->type(), img->pixelsZP());
947  gluBuild2DMipmaps(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, internalFormat(), w, h, img->format(), img->type(), img->pixelsZN());
948  VL_CHECK_OGL()
949  }
950  else
951  {
952  glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, mip_level, internalFormat(), w, h, border()?1:0, img->format(), img->type(), img->pixelsXP());
953  glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, mip_level, internalFormat(), w, h, border()?1:0, img->format(), img->type(), img->pixelsXN());
954  glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, mip_level, internalFormat(), w, h, border()?1:0, img->format(), img->type(), img->pixelsYP());
955  glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, mip_level, internalFormat(), w, h, border()?1:0, img->format(), img->type(), img->pixelsYN());
956  glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, mip_level, internalFormat(), w, h, border()?1:0, img->format(), img->type(), img->pixelsZP());
957  glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, mip_level, internalFormat(), w, h, border()?1:0, img->format(), img->type(), img->pixelsZN());
958  VL_CHECK_OGL()
959  }
960  }
961  }
962  else
964  {
965  if (is_compressed)
966  {
967  VL_glCompressedTexImage3D(GL_TEXTURE_2D_ARRAY, mip_level, internalFormat(), w, h, d, border()?1:0, img->requiredMemory(), img->pixels());
968  VL_CHECK_OGL()
969  }
970  else
971  {
972  VL_glTexImage3D(GL_TEXTURE_2D_ARRAY, mip_level, internalFormat(), w, h, d, border()?1:0, img->format(), img->type(), img->pixels());
973  VL_CHECK_OGL()
974  }
975  }
976  else
977  if (dimension() == TD_TEXTURE_3D)
978  {
979  if (is_compressed)
980  {
981  VL_glCompressedTexImage3D(GL_TEXTURE_3D, mip_level, internalFormat(), w, h, d, border()?1:0, img->requiredMemory(), img->pixels());
982  VL_CHECK_OGL()
983  }
984  else
985  {
986  VL_glTexImage3D(GL_TEXTURE_3D, mip_level, internalFormat(), w, h, d, border()?1:0, img->format(), img->type(), img->pixels());
987  VL_CHECK_OGL()
988  }
989  }
990  else
992  {
993  if (is_compressed)
994  {
995  glCompressedTexImage2D(GL_TEXTURE_RECTANGLE, mip_level, internalFormat(), width(), height(), 0, img->requiredMemory(), img->pixels());
996  VL_CHECK_OGL()
997  }
998  else
999  {
1000  glTexImage2D(GL_TEXTURE_RECTANGLE, mip_level, internalFormat(), width(), height(), 0, img->format(), img->type(), img->pixels());
1001  VL_CHECK_OGL()
1002  }
1003  }
1004  else
1005  if (dimension() == TD_TEXTURE_1D_ARRAY)
1006  {
1007  if (is_compressed)
1008  {
1009  glCompressedTexImage2D(GL_TEXTURE_1D_ARRAY, mip_level, internalFormat(), width(), height(), 0, img->requiredMemory(), img->pixels());
1010  VL_CHECK_OGL()
1011  }
1012  else
1013  {
1014  glTexImage2D(GL_TEXTURE_1D_ARRAY, mip_level, internalFormat(), width(), height(), 0, img->format(), img->type(), img->pixels());
1015  VL_CHECK_OGL()
1016  }
1017  }
1018  else
1019  if (dimension() == TD_TEXTURE_2D)
1020  {
1021  if (is_compressed)
1022  {
1023  glCompressedTexImage2D(GL_TEXTURE_2D, mip_level, internalFormat(), w, h, border()?1:0, img->requiredMemory(), img->pixels());
1024  VL_CHECK_OGL()
1025  }
1026  else
1027  {
1028  if (use_glu)
1029  {
1030  gluBuild2DMipmaps(GL_TEXTURE_2D, internalFormat(), w, h, img->format(), img->type(), img->pixels());
1031  VL_CHECK_OGL()
1032  }
1033  else
1034  {
1035  glTexImage2D(GL_TEXTURE_2D, mip_level, internalFormat(), w, h, border()?1:0, img->format(), img->type(), img->pixels());
1036  VL_CHECK_OGL()
1037  }
1038  }
1039  }
1040  else
1041  if (dimension() == TD_TEXTURE_1D)
1042  {
1043  if (is_compressed)
1044  {
1045  glCompressedTexImage1D(GL_TEXTURE_1D, mip_level, internalFormat(), w, border()?1:0, img->requiredMemory(), img->pixels());
1046  VL_CHECK_OGL()
1047  }
1048  else
1049  {
1050  if (use_glu)
1051  {
1052  gluBuild1DMipmaps(GL_TEXTURE_1D, internalFormat(), w, img->format(), img->type(), img->pixels());
1053  VL_CHECK_OGL()
1054  }
1055  else
1056  {
1057  glTexImage1D(GL_TEXTURE_1D, mip_level, internalFormat(), w, border()?1:0, img->format(), img->type(), img->pixels());
1058  VL_CHECK_OGL()
1059  }
1060  }
1061  }
1062 
1063  if ( gen_mipmaps )
1064  {
1065  if ( Has_glGenerateMipmaps )
1066  {
1067  glGenerateMipmap( dimension() );
1068  }
1069  else
1070  if ( Has_GL_GENERATE_MIPMAP )
1071  {
1072  glTexParameteri(dimension(), GL_GENERATE_MIPMAP, generate_mipmap_orig); VL_CHECK_OGL()
1073  }
1074  }
1075 
1076  glBindTexture( dimension(), 0 ); VL_CHECK_OGL()
1077 
1078  glPixelStorei( GL_UNPACK_ALIGNMENT, 4 );
1079 
1080  return true;
1081 }
1082 //-----------------------------------------------------------------------------
1084 {
1085  VL_CHECK_OGL()
1086 
1087  if (!setupParams())
1088  return false;
1089 
1090  class InOutCondition
1091  {
1092  Texture* mTex;
1093  public:
1094  InOutCondition(Texture* tex): mTex(tex) {}
1095  ~InOutCondition()
1096  {
1097  // make sure no errors were generated
1098  VL_CHECK_OGL()
1099 
1100  // release Image and BufferObject from SetupParams
1101  if (mTex->mSetupParams)
1102  {
1103  if ( mTex->mSetupParams->image() ) {
1104  mTex->mSetupParams->setImagePath( mTex->mSetupParams->image()->filePath() );
1105  }
1106  mTex->mSetupParams->setImage(NULL);
1107  mTex->mSetupParams->setBufferObject(NULL);
1108  }
1109  }
1110  };
1111 
1112  InOutCondition in_out_condition(this);
1113 
1114  ETextureFormat tex_format = setupParams()->format();
1115  ETextureDimension tex_dimension = setupParams()->dimension();
1116  bool gen_mipmaps = setupParams()->genMipmaps();
1117  bool border = setupParams()->border();
1118  if ( !setupParams()->image() && !setupParams()->imagePath().empty() )
1119  {
1120  setupParams()->setImage( loadImage( setupParams()->imagePath() ).get() );
1121  if (!setupParams()->image())
1122  {
1123  vl::Log::error( Say("Texture::createTexture(): could not load image file '%s'\n") << setupParams()->imagePath() );
1124  return false;
1125  }
1126  }
1127 
1128  VL_CHECK( mSetupParams.get() );
1129  const Image* img = setupParams()->image();
1130 
1131  int w = setupParams()->width();
1132  int h = setupParams()->height();
1133  int d = setupParams()->depth();
1134  if (img)
1135  {
1136  setObjectName( img->objectName().c_str() );
1137  w = img->width();
1138  h = img->height();
1139  d = img->depth();
1140  // guess from image format
1141  if (tex_format == TF_UNKNOWN) {
1142  tex_format = (ETextureFormat)img->format();
1143  }
1144  }
1145 
1146  if ( ! createTexture( tex_dimension,
1147  tex_format,
1148  w, h, d,
1149  border,
1151  setupParams()->samples(),
1152  setupParams()->fixedSamplesLocations() ) ) {
1153  return false;
1154  }
1155 
1156  VL_CHECK_OGL()
1157 
1158  if (img)
1159  {
1160  // compile mipmapping levels
1161  std::vector<const vl::Image*> mipmaps;
1162  mipmaps.push_back(img);
1163  for(int i=0; i<(int)img->mipmaps().size(); ++i)
1164  mipmaps.push_back( img->mipmaps()[i].get() );
1165 
1166  bool ok = false;
1167 
1168  if (!gen_mipmaps) // no mipmaps
1169  {
1170  ok = setMipLevel(0, img, false);
1171  }
1172  else
1173  {
1174  if (mipmaps.size() > 1) // explicit mipmaps
1175  {
1176  for(int i=0; i<(int)mipmaps.size(); ++i)
1177  ok = setMipLevel(i, mipmaps[i], false);
1178  }
1179  else // automatic mipmaps generation
1180  if (mipmaps.size() == 1)
1181  {
1182  ok = setMipLevel(0, img, true);
1183  }
1184  }
1185  return ok;
1186  }
1187  else
1188  return true;
1189 }
1190 //-----------------------------------------------------------------------------
1191 void Texture::clone(const Texture& other)
1192 {
1193  // keep its own copyof SetupParams
1194  if (other.mSetupParams)
1195  mSetupParams = new SetupParams(*other.mSetupParams);
1196  else
1197  mSetupParams = NULL;
1198  mHandle = other.mHandle;
1199  mTexParameter = other.mTexParameter;
1200  mBufferObject = other.mBufferObject;
1201  mFormat = other.mFormat;
1202  mDimension = other.mDimension;
1203  mWidth = other.mWidth;
1204  mHeight = other.mHeight;
1205  mDepth = other.mDepth;
1206  mSamples = other.mSamples;
1207  mBorder = other.mBorder;
1209 }
1210 //-----------------------------------------------------------------------------
1212 {
1213  switch(internalFormat())
1214  {
1215  case TF_DEPTH_STENCIL:
1216  case TF_DEPTH24_STENCIL8:
1217 
1218  case TF_DEPTH_COMPONENT32F:
1219  case TF_DEPTH32F_STENCIL8:
1220 
1221  case TF_DEPTH_COMPONENT:
1222  case TF_DEPTH_COMPONENT16:
1223  case TF_DEPTH_COMPONENT24:
1224  case TF_DEPTH_COMPONENT32:
1225  return true;
1226 
1227  default:
1228  return false;
1229  }
1230 }
1231 //-----------------------------------------------------------------------------
1233 {
1234  int comp[] =
1235  {
1242 
1243  // 3DFX_texture_compression_FXT1
1246 
1247  // EXT_texture_compression_s3tc
1252 
1253  // GL_EXT_texture_compression_latc
1258 
1259  // EXT_texture_compression_rgtc
1264 
1265  0
1266  };
1267 
1268  for(int i=0; comp[i]; ++i)
1269  {
1270  if(comp[i] == format)
1271  return true;
1272  }
1273 
1274  return false;
1275 }
1276 //-----------------------------------------------------------------------------
int height() const
The vertical dimension of the texture in texels.
Definition: Texture.hpp:705
ETextureFormat format() const
Definition: Texture.hpp:182
void prepareTexture2D(int width, int height, ETextureFormat format, bool border=false)
Prepares for creation an empty 2D texture.
Definition: Texture.hpp:329
bool mFixedSamplesLocation
Definition: Texture.hpp:772
Texture()
Constructs an null texture that can be initialized later using one of the prepareTexture*() functions...
Definition: Texture.cpp:483
int depth() const
Definition: Image.hpp:211
bool Has_Cubemap_Textures
Definition: OpenGL.cpp:86
unsigned int handle() const
OpenGL texture handle as returned by glGenTextures().
Definition: Texture.hpp:678
bool Has_Texture_Multisample
Definition: OpenGL.cpp:90
Wraps the OpenGL function glTexParameter(), see also http://www.opengl.org/sdk/docs/man/xhtml/glTexPa...
Definition: Texture.hpp:62
bool Has_glGenerateMipmaps
Definition: OpenGL.cpp:96
const T * get() const
Definition: Object.hpp:128
static bool supports(ETextureDimension tex_dimension, ETextureFormat tex_format, int mip_level, EImageDimension img_dimension, int w, int h, int d, bool border, int samples, bool fixedsamplelocations, bool verbose)
Checks whether the specified texture type, format and dimension combination is supported by the curre...
Definition: Texture.cpp:498
A simple String formatting class.
Definition: Say.hpp:124
const unsigned char * pixels() const
Raw pointer to pixels.
Definition: Image.hpp:170
void setObjectName(const char *name)
The name of the object, by default set to the object&#39;s class name in debug builds.
Definition: Object.hpp:220
static void warning(const String &message)
Use this function to provide information about situations that might lead to errors or loss of data...
Definition: Log.cpp:155
The String class implements an advanced UTF16 (Unicode BMP) string manipulation engine.
Definition: String.hpp:62
void setImage(const Image *image)
Definition: Texture.hpp:171
ref< TexParameter > mTexParameter
Definition: Texture.hpp:761
const SetupParams * setupParams() const
See SetupParams.
Definition: Texture.hpp:731
void setBorder(bool border)
Whether the texture has a 1 pixel texture border or not.
Definition: Texture.hpp:713
static void error(const String &message)
Use this function to provide information about run-time errors: file not found, out of memory...
Definition: Log.cpp:165
static bool isCompressedFormat(int format)
Returns true if the specified format is compressed.
Definition: Texture.cpp:1232
bool Has_Texture_Rectangle
Definition: OpenGL.cpp:87
ETextureDimension mDimension
Definition: Texture.hpp:766
Wraps an OpenGL texture object representing and managing all the supported texture types...
Definition: Texture.hpp:143
bool createTexture()
Creates a texture using the parameters specified by the last prepareTexture*() called.
Definition: Texture.cpp:1083
int requiredMemory() const
Returns the number of bytes requested to store the image.
Definition: Image.cpp:532
bool isValid() const
Returns true if the image has valid width/height/depth, pitch and byte alignment, type/format combina...
Definition: Image.cpp:135
bool mBorder
Definition: Texture.hpp:771
VLCORE_EXPORT ref< Image > loadImage(VirtualFile *file)
Loads an image from the specified file.
Definition: Image.cpp:1214
void setDepth(int z)
The z dimension of the texture in texels.
Definition: Texture.hpp:708
bool genMipmaps() const
Definition: Texture.hpp:188
bool border() const
Whether the texture has a 1 pixel texture border or not.
Definition: Texture.hpp:715
int byteAlignment() const
Returns the byte-alignment of the row of the image.
Definition: Image.cpp:540
unsigned char * pixelsXN()
X-negative cubemap face.
Definition: Image.cpp:764
void setInternalFormat(ETextureFormat format)
The texture internal format as pecified by the internalFormat parameter of glTexImage*().
Definition: Texture.hpp:693
Visualization Library main namespace.
void prepareTexture1D(int width, ETextureFormat format, bool border=false)
Prepares for creation an empty 1D texture.
Definition: Texture.hpp:283
unsigned char * pixelsZN()
Z-negative cubemap face.
Definition: Image.cpp:836
BufferObject * bufferObject()
The buffer object bound to a buffer object texture.
Definition: Texture.hpp:255
ETextureFormat mFormat
Definition: Texture.hpp:765
bool Has_Texture_Array
Definition: OpenGL.cpp:88
static void bug(const String &message)
Use this function to provide information about programming errors: wrong parameter initialization...
Definition: Log.cpp:175
void setHeight(int y)
The vertical dimension of the texture in texels.
Definition: Texture.hpp:703
void prepareTexture3D(int width, int height, int depth, ETextureFormat format, bool border=false)
Prepares for creation an empty 3D texture.
Definition: Texture.hpp:376
bool isDepthTexture() const
Returns true if the texture is a depth or depth/stencil textre.
Definition: Texture.cpp:1211
int samples() const
The number of samples of a multisample texture.
Definition: Texture.hpp:720
int height() const
Definition: Image.hpp:209
#define VL_TRAP()
Definition: checks.hpp:70
~Texture()
Destructor.
Definition: Texture.cpp:369
void setDimension(ETextureDimension dimension)
The texture type (1d, 2d, cubemap etc.) as specified by the target parameter of glTexImage*().
Definition: Texture.hpp:688
unsigned char * pixelsZP()
Z-positive cubemap face.
Definition: Image.cpp:818
ref< BufferObject > mBufferObject
Definition: Texture.hpp:764
bool mManaged
Definition: Texture.hpp:760
EImageDimension dimension() const
Definition: Image.cpp:372
bool setMipLevel(int mip_level, const Image *img, bool gen_mipmaps)
Copies the texture image to the specified mip-maping level.
Definition: Texture.cpp:844
EImageDimension
bool Has_GL_GENERATE_MIPMAP
Definition: OpenGL.cpp:97
int width() const
Definition: Image.hpp:207
unsigned char * pixelsYP()
Y-positive cubemap face.
Definition: Image.cpp:782
ETextureDimension dimension() const
Definition: Texture.hpp:179
ETextureFormat internalFormat() const
The texture internal format as pecified by the internalFormat parameter of glTexImage*().
Definition: Texture.hpp:695
#define NULL
Definition: OpenGLDefs.hpp:81
bool isValid() const
Returns true if the current texture configuration seems valid.
Definition: Texture.cpp:490
unsigned char * pixelsYN()
Y-negative cubemap face.
Definition: Image.cpp:800
#define VL_IS_POW_2(x)
ETextureDimension dimension() const
The texture type (1d, 2d, cubemap etc.) as specified by the target parameter of glTexImage*().
Definition: Texture.hpp:690
int mSamples
Definition: Texture.hpp:770
ETextureDimension
bool Has_Texture_Buffer
Definition: OpenGL.cpp:89
VLGRAPHICS_EXPORT const char * getGLErrorString(int err)
Returns a readable string corresponding to the given OpenGL error code as returned by glGetError() ...
Definition: OpenGL.cpp:591
The BufferObject class is a Buffer that can upload its data on the GPU memory.
#define VL_CHECK_OGL()
Definition: OpenGL.hpp:156
unsigned int handle() const
SetupParams wraps all the parameters needed to crate a Texture.
Definition: Texture.hpp:154
void prepareTextureCubemap(int width, int height, ETextureFormat format, bool border=false)
Prepares for creation an empty cubemap texture.
Definition: Texture.hpp:424
EImageType type() const
Definition: Image.hpp:217
void clone(const Texture &other)
Copies all the texture parameters form the specified texture, including the OpenGL texture handle...
Definition: Texture.cpp:1191
unsigned int mHandle
Definition: Texture.hpp:759
Implements a generic 1d, 2d, 3d and cubemap image that can have mipmaps.
Definition: Image.hpp:54
The ref<> class is used to reference-count an Object.
Definition: Object.hpp:55
ETextureFormat
Definition: vlnamespace.hpp:45
int depth() const
The z dimension of the texture in texels.
Definition: Texture.hpp:710
unsigned char * pixelsXP()
X-positive cubemap face.
Definition: Image.cpp:746
ref< SetupParams > mSetupParams
Definition: Texture.hpp:763
void setWidth(int x)
The horizontal dimension of the texture in texels.
Definition: Texture.hpp:698
void destroyTexture()
Destroys the GL texture object if managed() is true (default).
Definition: Texture.cpp:359
#define VL_CHECK(expr)
Definition: checks.hpp:73
const Image * image() const
Definition: Texture.hpp:172
EImageFormat format() const
Definition: Image.hpp:215
int width() const
The horizontal dimension of the texture in texels.
Definition: Texture.hpp:700