00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include <vlGraphics/Texture.hpp>
00033 #include <vlCore/checks.hpp>
00034 #include <vlCore/Image.hpp>
00035 #include <vlCore/math_utils.hpp>
00036 #include <vlCore/Say.hpp>
00037 #include <vlCore/Log.hpp>
00038
00039 using namespace vl;
00040
00041 namespace
00042 {
00043
00044 int getDefaultFormat(ETextureFormat internal_format)
00045 {
00046
00047 #if defined(VL_OPENGL_ES1) || defined(VL_OPENGL_ES2)
00048 return internal_format;
00049 #else
00050 switch(internal_format)
00051 {
00052 case TF_ALPHA:
00053 case TF_ALPHA4:
00054 case TF_ALPHA8:
00055 case TF_ALPHA12:
00056 case TF_ALPHA16:
00057 return GL_ALPHA;
00058
00059 case TF_LUMINANCE:
00060 case TF_LUMINANCE4:
00061 case TF_LUMINANCE8:
00062 case TF_LUMINANCE12:
00063 case TF_LUMINANCE16:
00064 case TF_SLUMINANCE:
00065 case TF_SLUMINANCE8:
00066 return GL_LUMINANCE;
00067
00068 case TF_LUMINANCE_ALPHA:
00069 case TF_LUMINANCE4_ALPHA4:
00070 case TF_LUMINANCE6_ALPHA2:
00071 case TF_LUMINANCE8_ALPHA8:
00072 case TF_LUMINANCE12_ALPHA4:
00073 case TF_LUMINANCE12_ALPHA12:
00074 case TF_LUMINANCE16_ALPHA16:
00075 case TF_SLUMINANCE_ALPHA:
00076 case TF_SLUMINANCE8_ALPHA8:
00077 return GL_LUMINANCE_ALPHA;
00078
00079 case TF_INTENSITY:
00080 case TF_INTENSITY4:
00081 case TF_INTENSITY8:
00082 case TF_INTENSITY12:
00083 case TF_INTENSITY16:
00084 return GL_INTENSITY;
00085
00086 case TF_RED:
00087 case TF_R8:
00088 case TF_R8_SNORM:
00089 case TF_R16:
00090 case TF_R16_SNORM:
00091 case TF_R16F:
00092 case TF_R32F:
00093 return GL_RED;
00094
00095 case TF_RG:
00096 case TF_RG8:
00097 case TF_RG8_SNORM:
00098 case TF_RG16:
00099 case TF_RG16_SNORM:
00100 case TF_RG16F:
00101 case TF_RG32F:
00102 return GL_RG;
00103
00104 case TF_RGB:
00105 case TF_RGB4:
00106 case TF_RGB5:
00107 case TF_RGB8:
00108 case TF_RGB8_SNORM:
00109 case TF_RGB10:
00110 case TF_RGB12:
00111 case TF_RGB16:
00112
00113 case TF_RGB16F:
00114 case TF_RGB32F:
00115 case TF_R3_G3_B2:
00116 case TF_R11F_G11F_B10F:
00117
00118 case TF_SRGB8:
00119 return GL_RGB;
00120
00121 case TF_RGBA:
00122 case TF_RGBA2:
00123 case TF_RGBA4:
00124 case TF_RGBA8:
00125 case TF_RGBA8_SNORM:
00126 case TF_RGBA12:
00127 case TF_RGBA16:
00128 case TF_RGBA16_SNORM:
00129 case TF_RGBA16F:
00130 case TF_RGBA32F:
00131 case TF_RGB5_A1:
00132 case TF_RGB10_A2:
00133 case TF_SRGB8_ALPHA8:
00134 return GL_RGBA;
00135
00136 case TF_R8I:
00137 case TF_R8UI:
00138 case TF_R16I:
00139 case TF_R16UI:
00140 case TF_R32I:
00141 case TF_R32UI:
00142 return GL_RED_INTEGER;
00143
00144 case TF_RG8I:
00145 case TF_RG8UI:
00146 case TF_RG16I:
00147 case TF_RG16UI:
00148 case TF_RG32I:
00149 case TF_RG32UI:
00150 return GL_RG_INTEGER;
00151
00152 case TF_RGB8I:
00153
00154 case TF_RGB8UI:
00155
00156 case TF_RGB16I:
00157
00158 case TF_RGB16UI:
00159
00160 case TF_RGB32I:
00161
00162 case TF_RGB32UI:
00163
00164 return GL_RGB_INTEGER;
00165
00166 case TF_RGBA8I:
00167
00168 case TF_RGBA8UI:
00169
00170 case TF_RGBA16I:
00171
00172 case TF_RGBA16UI:
00173
00174 case TF_RGBA32I:
00175
00176 case TF_RGBA32UI:
00177
00178 case TF_RGB10_A2UI:
00179 return GL_RGBA_INTEGER;
00180
00181 case TF_DEPTH_STENCIL:
00182 case TF_DEPTH24_STENCIL8:
00183 case TF_DEPTH32F_STENCIL8:
00184 return GL_DEPTH_STENCIL;
00185
00186 case TF_DEPTH_COMPONENT:
00187 case TF_DEPTH_COMPONENT16:
00188 case TF_DEPTH_COMPONENT24:
00189 case TF_DEPTH_COMPONENT32:
00190 case TF_DEPTH_COMPONENT32F:
00191 return GL_DEPTH_COMPONENT;
00192
00193
00194 case TF_ALPHA8I_EXT:
00195 case TF_ALPHA8UI_EXT:
00196 case TF_ALPHA16I_EXT:
00197 case TF_ALPHA16UI_EXT:
00198 case TF_ALPHA32I_EXT:
00199 case TF_ALPHA32UI_EXT:
00200 return GL_ALPHA_INTEGER;
00201
00202 case TF_INTENSITY8I_EXT:
00203 case TF_INTENSITY8UI_EXT:
00204 case TF_INTENSITY16I_EXT:
00205 case TF_INTENSITY16UI_EXT:
00206 case TF_INTENSITY32I_EXT:
00207 case TF_INTENSITY32UI_EXT:
00208 return GL_RED_INTEGER;
00209
00210 case TF_LUMINANCE8I_EXT:
00211 case TF_LUMINANCE8UI_EXT:
00212 case TF_LUMINANCE16UI_EXT:
00213 case TF_LUMINANCE16I_EXT:
00214 case TF_LUMINANCE32I_EXT:
00215 case TF_LUMINANCE32UI_EXT:
00216 return GL_LUMINANCE_INTEGER_EXT;
00217
00218 case TF_LUMINANCE_ALPHA8I_EXT:
00219 case TF_LUMINANCE_ALPHA8UI_EXT:
00220 case TF_LUMINANCE_ALPHA16I_EXT:
00221 case TF_LUMINANCE_ALPHA16UI_EXT:
00222 case TF_LUMINANCE_ALPHA32I_EXT:
00223 case TF_LUMINANCE_ALPHA32UI_EXT:
00224 return GL_LUMINANCE_ALPHA_INTEGER_EXT;
00225
00226 default:
00227 return GL_RED;
00228 }
00229 #endif
00230 }
00231
00232
00233 int getDefaultType(ETextureFormat internal_format)
00234 {
00235 switch( internal_format )
00236 {
00237 case TF_ALPHA4:
00238 case TF_ALPHA8:
00239 case TF_ALPHA8UI_EXT:
00240 case TF_INTENSITY4:
00241 case TF_INTENSITY8:
00242 case TF_INTENSITY8UI_EXT:
00243 case TF_LUMINANCE4:
00244 case TF_LUMINANCE8:
00245 case TF_LUMINANCE8UI_EXT:
00246 case TF_LUMINANCE8_ALPHA8:
00247 case TF_LUMINANCE_ALPHA8UI_EXT:
00248 case TF_R8:
00249 case TF_R8UI:
00250 case TF_RG8:
00251 case TF_RG8UI:
00252 case TF_RGB8:
00253 case TF_RGB8UI:
00254 case TF_RGBA8:
00255 case TF_RGBA8UI:
00256 return GL_UNSIGNED_BYTE;
00257
00258 case TF_ALPHA8I_EXT:
00259 case TF_INTENSITY8I_EXT:
00260 case TF_LUMINANCE8I_EXT:
00261 case TF_LUMINANCE_ALPHA8I_EXT:
00262 case TF_R8I:
00263 case TF_RG8I:
00264 case TF_RGB8I:
00265 case TF_RGBA8I:
00266 return GL_BYTE;
00267
00268 case TF_ALPHA12:
00269 case TF_ALPHA16:
00270 case TF_ALPHA16UI_EXT:
00271 case TF_INTENSITY12:
00272 case TF_INTENSITY16:
00273 case TF_INTENSITY16UI_EXT:
00274 case TF_LUMINANCE12:
00275 case TF_LUMINANCE16:
00276 case TF_LUMINANCE16UI_EXT:
00277 case TF_LUMINANCE16_ALPHA16:
00278 case TF_LUMINANCE_ALPHA16UI_EXT:
00279 case TF_R16:
00280 case TF_R16UI:
00281 case TF_RG16:
00282 case TF_RG16UI:
00283 case TF_RGB10:
00284 case TF_RGB12:
00285 case TF_RGB16:
00286 case TF_RGB16UI:
00287 case TF_RGBA12:
00288 case TF_RGBA16:
00289 case TF_RGBA16UI:
00290 case TF_DEPTH_COMPONENT16:
00291 return GL_UNSIGNED_SHORT;
00292
00293 case TF_ALPHA16I_EXT:
00294 case TF_INTENSITY16I_EXT:
00295 case TF_LUMINANCE16I_EXT:
00296 case TF_LUMINANCE_ALPHA16I_EXT:
00297 case TF_R16I:
00298 case TF_RG16I:
00299 case TF_RGB16I:
00300 case TF_RGBA16I:
00301 return GL_SHORT;
00302
00303 case TF_ALPHA32UI_EXT:
00304 case TF_INTENSITY32UI_EXT:
00305 case TF_LUMINANCE32UI_EXT:
00306 case TF_LUMINANCE_ALPHA32UI_EXT:
00307 case TF_R32UI:
00308 case TF_RG32UI:
00309 case TF_RGB32UI:
00310 case TF_RGBA32UI:
00311 case TF_DEPTH_COMPONENT24:
00312 case TF_DEPTH_COMPONENT32:
00313 return GL_UNSIGNED_INT;
00314
00315 case TF_ALPHA32I_EXT:
00316 case TF_INTENSITY32I_EXT:
00317 case TF_LUMINANCE32I_EXT:
00318 case TF_LUMINANCE_ALPHA32I_EXT:
00319 case TF_R32I:
00320 case TF_RG32I:
00321 case TF_RGB32I:
00322 case TF_RGBA32I:
00323 return GL_INT;
00324
00325 case TF_DEPTH24_STENCIL8:
00326 return GL_UNSIGNED_INT_24_8;
00327
00328 case TF_R16F:
00329 case TF_R32F:
00330 case TF_RG16F:
00331 case TF_RG32F:
00332 case TF_RGB16F:
00333 case TF_RGB32F:
00334 case TF_RGBA16F:
00335 case TF_RGBA32F:
00336 case TF_R11F_G11F_B10F:
00337 case TF_ALPHA16F:
00338 case TF_ALPHA32F:
00339 case TF_INTENSITY16F:
00340 case TF_INTENSITY32F:
00341 case TF_LUMINANCE16F:
00342 case TF_LUMINANCE32F:
00343 case TF_LUMINANCE_ALPHA16F:
00344 case TF_LUMINANCE_ALPHA32F:
00345 case TF_DEPTH_COMPONENT32F:
00346 return GL_FLOAT;
00347
00348 case TF_DEPTH32F_STENCIL8:
00349 return GL_FLOAT_32_UNSIGNED_INT_24_8_REV;
00350
00351 default:
00352 return GL_UNSIGNED_BYTE;
00353 }
00354 }
00355 }
00356
00357
00358
00359 void Texture::destroyTexture()
00360 {
00361 if (mHandle)
00362 glDeleteTextures(1, &mHandle);
00363 reset();
00364
00365 }
00366
00367 Texture::~Texture()
00368 {
00369 destroyTexture();
00370 }
00371
00372 void Texture::reset()
00373 {
00374 setDimension(TD_TEXTURE_UNKNOWN);
00375 setInternalFormat(TF_UNKNOWN);
00376 setBorder(0);
00377 setWidth(0);
00378 setHeight(0);
00379 setDepth(0);
00380 mHandle = 0;
00381 mSetupParams = NULL;
00382 mBufferObject = NULL;
00383 mSamples = 0;
00384 mFixedSamplesLocation = true;
00385 }
00386
00387 Texture::Texture(int width, ETextureFormat format, bool border)
00388 {
00389 VL_DEBUG_SET_OBJECT_NAME()
00390 mTexParameter = new TexParameter;
00391 reset();
00392 if (!createTexture(vl::TD_TEXTURE_1D, format, width, 0, 0, border, NULL, 0, 0))
00393 {
00394 Log::error("1D texture creation failed!\n");
00395 }
00396 }
00397
00398 Texture::Texture(int width, int height, ETextureFormat format, bool border)
00399 {
00400 VL_DEBUG_SET_OBJECT_NAME()
00401 mTexParameter = new TexParameter;
00402 reset();
00403 if (!createTexture(vl::TD_TEXTURE_2D, format, width, height, 0, border, NULL, 0, 0))
00404 {
00405 Log::error("2D texture constructor failed!\n");
00406 }
00407 }
00408
00409 Texture::Texture(int width, int height, int depth, ETextureFormat format, bool border)
00410 {
00411 VL_DEBUG_SET_OBJECT_NAME()
00412 mTexParameter = new TexParameter;
00413 reset();
00414 if (!createTexture(vl::TD_TEXTURE_3D, format, width, height, depth, border, NULL, 0, 0))
00415 {
00416 Log::error("3D texture constructor failed!\n");
00417 }
00418 }
00419
00420 Texture::Texture(const Image* image, ETextureFormat format, bool mipmaps , bool border)
00421 {
00422 VL_DEBUG_SET_OBJECT_NAME()
00423 mTexParameter = new TexParameter;
00424 reset();
00425
00426 if (image && image->isValid())
00427 {
00428 switch(image->dimension())
00429 {
00430 #if defined(VL_OPENGL)
00431 case ID_1D: prepareTexture1D(image, format, mipmaps, border); break;
00432 #else
00433 case ID_1D: prepareTexture2D(image, format, mipmaps, border); break;
00434 #endif
00435 case ID_2D: prepareTexture2D(image, format, mipmaps, border); break;
00436 case ID_3D: prepareTexture3D(image, format, mipmaps, border); break;
00437 case ID_Cubemap: prepareTextureCubemap(image, format, mipmaps, border); break;
00438 default:
00439 break;
00440 }
00441 if( !createTexture() )
00442 Log::error("Texture constructor failed!\n");
00443 }
00444 else
00445 Log::bug("Texture constructor called with an invalid Image!\n");
00446 }
00447
00448 Texture::Texture(const String& image_path, ETextureFormat format, bool mipmaps , bool border)
00449 {
00450 VL_DEBUG_SET_OBJECT_NAME()
00451 mTexParameter = new TexParameter;
00452 reset();
00453
00454 ref<Image> image = vl::loadImage(image_path);
00455
00456 if (image && image->isValid())
00457 {
00458 switch(image->dimension())
00459 {
00460 #if defined(VL_OPENGL)
00461 case ID_1D: prepareTexture1D(image.get(), format, mipmaps, border); break;
00462 #else
00463 case ID_1D: prepareTexture2D(image.get(), format, mipmaps, border); break;
00464 #endif
00465 case ID_2D: prepareTexture2D(image.get(), format, mipmaps, border); break;
00466 case ID_3D: prepareTexture3D(image.get(), format, mipmaps, border); break;
00467 case ID_Cubemap: prepareTextureCubemap(image.get(), format, mipmaps, border); break;
00468 default:
00469 break;
00470 }
00471 if( !createTexture() )
00472 Log::error("Texture constructor failed!\n");
00473 }
00474 else
00475 Log::bug("Texture constructor called with an invalid Image!\n");
00476 }
00477
00478 Texture::Texture()
00479 {
00480 VL_DEBUG_SET_OBJECT_NAME()
00481 mTexParameter = new TexParameter;
00482 reset();
00483 }
00484
00485 bool Texture::isValid() const
00486 {
00487 bool a = mWidth != 0 && mHeight == 0 && mDepth == 0;
00488 bool b = mWidth != 0 && mHeight != 0 && mDepth == 0;
00489 bool c = mWidth != 0 && mHeight != 0 && mDepth != 0;
00490 return handle() != 0 && (a|b|c);
00491 }
00492
00493 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)
00494 {
00495 VL_CHECK_OGL();
00496
00497
00498
00499 glGetError();
00500
00501
00502
00503 if ( tex_dimension == TD_TEXTURE_2D_MULTISAMPLE || tex_dimension == TD_TEXTURE_2D_MULTISAMPLE_ARRAY )
00504 {
00505 if (!Has_Texture_Multisample)
00506 {
00507 if (verbose) Log::error("Texture::supports(): multisample textures not supported by the current hardware.\n");
00508 return false;
00509 }
00510
00511 if (border)
00512 {
00513 if (verbose) Log::error("Texture::supports(): multisample textures cannot have borders.\n");
00514 return false;
00515 }
00516
00517 if (mip_level)
00518 {
00519 if (verbose) Log::error("Texture::supports(): multisample textures cannot have mip levels other than 0.\n");
00520 return false;
00521 }
00522
00523
00524 VL_CHECK( w && h );
00525 }
00526
00527 if ( tex_dimension == TD_TEXTURE_BUFFER )
00528 {
00529 if (!Has_Texture_Buffer)
00530 {
00531 if (verbose) Log::error("Texture::supports(): texture buffer not supported by the current hardware.\n");
00532 return false;
00533 }
00534
00535 if (border)
00536 {
00537 if (verbose) Log::error("Texture::supports(): a texture buffer cannot have borders.\n");
00538 return false;
00539 }
00540
00541 if (mip_level)
00542 {
00543 if (verbose) Log::error("Texture::supports(): a texture buffer cannot have mip levels other than 0.\n");
00544 return false;
00545 }
00546
00547
00548 VL_CHECK( !(w||h||d) );
00549 }
00550
00551
00552
00553 if ( tex_dimension == TD_TEXTURE_CUBE_MAP )
00554 {
00555 if (!Has_Cubemap_Textures)
00556 {
00557 if (verbose) Log::error("Texture::supports(): texture cubemap not supported by the current hardware.\n");
00558 return false;
00559 }
00560
00561 if ( w != h )
00562 {
00563 if (verbose) Log::error("Texture::supports(): cubemaps must have square faces.\n");
00564 return false;
00565 }
00566 }
00567
00568
00569
00570 if ( tex_dimension == TD_TEXTURE_1D_ARRAY || tex_dimension == TD_TEXTURE_2D_ARRAY )
00571 {
00572 if (border)
00573 {
00574 if (verbose) Log::error("Texture::supports(): you cannot create a texture array with borders.\n");
00575 return false;
00576 }
00577
00578 if(!Has_Texture_Array)
00579 {
00580 if (verbose) Log::error("Texture::supports(): texture array not supported by the current hardware.\n");
00581 return false;
00582 }
00583
00584 if ( img_dimension )
00585 {
00586 if ( (img_dimension != ID_2D && tex_dimension == TD_TEXTURE_1D_ARRAY) || ( img_dimension != ID_3D && tex_dimension == TD_TEXTURE_2D_ARRAY ) )
00587 {
00588 if (verbose) Log::error("Texture::supports(): the image dimensions are not suitable to create a texture array."
00589 "To create a 1D texture array you need a 2D image and to create a 2D texture array you need a 3D image.\n");
00590 return false;
00591 }
00592 }
00593 }
00594
00595
00596
00597 if (tex_dimension == TD_TEXTURE_RECTANGLE)
00598 {
00599 if (!Has_Texture_Rectangle)
00600 {
00601 if (verbose) Log::error("Texture::supports(): texture rectangle not supported by the current hardware.\n");
00602 return false;
00603 }
00604
00605 if ( mip_level != 0 )
00606 {
00607 if (verbose) Log::error("Texture::supports(): TD_TEXTURE_RECTANGLE textures do not support mipmapping level other than zero.\n");
00608 return false;
00609 }
00610
00611 if (border)
00612 {
00613 if (verbose) Log::error("Texture::supports(): TD_TEXTURE_RECTANGLE textures do not allow textures borders\n");
00614 return false;
00615 }
00616 }
00617
00618
00619 #if defined(VL_OPENGL)
00620 int width = 0;
00621
00622 int default_format = getDefaultFormat(tex_format);
00623 int default_type = getDefaultType(tex_format);
00624
00625 if (tex_dimension == TD_TEXTURE_BUFFER)
00626 {
00627 width = 1;
00628 }
00629 else
00630 if (tex_dimension == TD_TEXTURE_2D_MULTISAMPLE)
00631 {
00632 glTexImage2DMultisample(GL_PROXY_TEXTURE_2D_MULTISAMPLE, samples, tex_format, w, h, fixedsamplelocations );
00633 if ( glGetError() )
00634 {
00635 if (verbose) Log::error( Say("Texture::supports(): 2d multisample texture requested with too many samples for the current hardware! (%n)\n") << samples );
00636 return false;
00637 }
00638 glGetTexLevelParameteriv(GL_PROXY_TEXTURE_2D_MULTISAMPLE, 0, GL_TEXTURE_WIDTH, &width); VL_CHECK_OGL();
00639 }
00640 else
00641 if (tex_dimension == TD_TEXTURE_2D_MULTISAMPLE_ARRAY)
00642 {
00643 glTexImage3DMultisample(GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY, samples, tex_format, w, h, d, fixedsamplelocations ); VL_CHECK_OGL();
00644 if ( glGetError() )
00645 {
00646 if (verbose) Log::error( Say("Texture::supports(): multisample texture array requested with too many samples for the current hardware! (%n)\n") << samples );
00647 return false;
00648 }
00649 glGetTexLevelParameteriv(GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY, 0, GL_TEXTURE_WIDTH, &width); VL_CHECK_OGL();
00650 }
00651 else
00652 if (tex_dimension == TD_TEXTURE_CUBE_MAP)
00653 {
00654 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);
00655 glGetTexLevelParameteriv(GL_PROXY_TEXTURE_CUBE_MAP, mip_level, GL_TEXTURE_WIDTH, &width);
00656 }
00657 else
00658 if (tex_dimension == TD_TEXTURE_2D_ARRAY)
00659 {
00660 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);
00661 glGetTexLevelParameteriv(GL_PROXY_TEXTURE_2D_ARRAY, mip_level, GL_TEXTURE_WIDTH, &width);
00662 }
00663 else
00664 if (tex_dimension == TD_TEXTURE_3D)
00665 {
00666 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);
00667 glGetTexLevelParameteriv(GL_PROXY_TEXTURE_3D, mip_level, GL_TEXTURE_WIDTH, &width);
00668 }
00669 else
00670 if (tex_dimension == TD_TEXTURE_RECTANGLE)
00671 {
00672 glTexImage2D(GL_PROXY_TEXTURE_RECTANGLE, mip_level, tex_format, w, h, 0, default_format, default_type, NULL);
00673 glGetTexLevelParameteriv(GL_PROXY_TEXTURE_RECTANGLE, mip_level, GL_TEXTURE_WIDTH, &width);
00674 }
00675 else
00676 if (tex_dimension == TD_TEXTURE_1D_ARRAY)
00677 {
00678 glTexImage2D(GL_PROXY_TEXTURE_1D_ARRAY, mip_level, tex_format, w, h, 0, default_format, default_type, NULL);
00679 glGetTexLevelParameteriv(GL_PROXY_TEXTURE_1D_ARRAY, mip_level, GL_TEXTURE_WIDTH, &width);
00680 }
00681 else
00682 if (tex_dimension == TD_TEXTURE_2D)
00683 {
00684 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);
00685 glGetTexLevelParameteriv(GL_PROXY_TEXTURE_2D, mip_level, GL_TEXTURE_WIDTH, &width);
00686 }
00687 else
00688 if (tex_dimension == TD_TEXTURE_1D)
00689 {
00690 glTexImage1D(GL_PROXY_TEXTURE_1D, mip_level, tex_format, w + (border?2:0), border?1:0, default_format, default_type, NULL);
00691 glGetTexLevelParameteriv(GL_PROXY_TEXTURE_1D, mip_level, GL_TEXTURE_WIDTH, &width);
00692 }
00693
00694 GLenum err = glGetError();
00695 return err == 0 && width != 0;
00696 #else
00697 return true;
00698 #endif
00699 }
00700
00701 bool Texture::createTexture(ETextureDimension tex_dimension, ETextureFormat tex_format, int w, int h, int d, bool border, BufferObject* buffer_object, int samples, bool fixedsamplelocations)
00702 {
00703 VL_CHECK_OGL()
00704
00705 if ( tex_dimension == TD_TEXTURE_BUFFER )
00706 {
00707 if( !buffer_object || !buffer_object->handle() || !glIsBuffer(buffer_object->handle()) )
00708 {
00709 Log::bug( "Texture::createTexture() requires a non NULL valid buffer object in order to create a texture buffer!\n" );
00710 VL_CHECK(buffer_object);
00711 VL_CHECK(buffer_object->handle());
00712 VL_CHECK(glIsBuffer(buffer_object->handle()));
00713 return false;
00714 }
00715 else
00716 {
00717
00718 GLint buffer_size = 0;
00719 glBindBuffer(GL_TEXTURE_BUFFER, buffer_object->handle());
00720 glGetBufferParameteriv(GL_TEXTURE_BUFFER, GL_BUFFER_SIZE, &buffer_size);
00721 glBindBuffer(GL_TEXTURE_BUFFER, 0);
00722 if ( buffer_size == 0 )
00723 {
00724 Log::bug("Texture::createTexture(): cannot create a texture buffer with an empty buffer object!\n"); VL_TRAP();
00725 return false;
00726 }
00727 }
00728 }
00729
00730 if (mHandle)
00731 {
00732 Log::bug("Texture::createTexture(): a texture can be created only once!\n");
00733 return false;
00734 }
00735 else
00736 {
00737 if ( !supports(tex_dimension , tex_format, 0, ID_None, w, h, d, border, samples, fixedsamplelocations, true) )
00738 {
00739 VL_CHECK_OGL()
00740 Log::bug("Texture::createTexture(): the format/size combination requested is not supported!\n"); VL_TRAP();
00741 return false;
00742 }
00743
00744 reset();
00745
00746 glGenTextures( 1, &mHandle ); VL_CHECK_OGL();
00747
00748 if (!mHandle)
00749 {
00750 Log::bug("Texture::createTexture(): texture creation failed!\n");
00751 VL_TRAP();
00752 return false;
00753 }
00754
00755 setDimension(tex_dimension);
00756 setInternalFormat(tex_format);
00757 setWidth(w);
00758 setHeight(h);
00759 setDepth(d);
00760 setBorder(border);
00761 mBufferObject = buffer_object;
00762 mSamples = samples;
00763 mFixedSamplesLocation = fixedsamplelocations;
00764 glBindTexture(tex_dimension, mHandle); VL_CHECK_OGL();
00765
00766 int default_format = getDefaultFormat(tex_format);
00767 int default_type = getDefaultType(tex_format);
00768
00769 if (tex_dimension == TD_TEXTURE_2D_MULTISAMPLE)
00770 {
00771 glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, samples, tex_format, w, h, fixedsamplelocations ); VL_CHECK_OGL();
00772 }
00773 else
00774 if (tex_dimension == TD_TEXTURE_2D_MULTISAMPLE_ARRAY)
00775 {
00776 glTexImage3DMultisample(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, samples, tex_format, w, h, d, fixedsamplelocations ); VL_CHECK_OGL();
00777 }
00778 else
00779 if (tex_dimension == TD_TEXTURE_BUFFER)
00780 {
00781 VL_CHECK(buffer_object)
00782 VL_CHECK(buffer_object->handle())
00783 glTexBuffer(GL_TEXTURE_BUFFER, tex_format, buffer_object->handle());
00784 unsigned int glerr = glGetError();
00785 if (glerr != GL_NO_ERROR)
00786 {
00787 String msg( (const char*)getGLErrorString(glerr) );
00788 Log::bug( "Texture::createTexture(): glTexBuffer() failed with error: '" + msg + "'.\n" );
00789 Log::error("Probably you supplied a non supported texture format! Review the glTexBuffer() man page for a complete list of supported texture formats.\n");
00790 VL_TRAP();
00791 }
00792 }
00793 else
00794 if (tex_dimension == TD_TEXTURE_CUBE_MAP)
00795 {
00796 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);
00797 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);
00798 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);
00799 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);
00800 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);
00801 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);
00802 VL_CHECK_OGL();
00803 }
00804 else
00805 if (tex_dimension == TD_TEXTURE_2D_ARRAY)
00806 {
00807 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);
00808 VL_CHECK_OGL();
00809 }
00810 else
00811 if (tex_dimension == TD_TEXTURE_3D)
00812 {
00813 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);
00814 VL_CHECK_OGL();
00815 }
00816 else
00817 if (tex_dimension == TD_TEXTURE_RECTANGLE)
00818 {
00819 glTexImage2D(GL_TEXTURE_RECTANGLE, 0, tex_format, w, h, 0, default_format, default_type, NULL);
00820 VL_CHECK_OGL();
00821 }
00822 else
00823 if (tex_dimension == TD_TEXTURE_1D_ARRAY)
00824 {
00825 glTexImage2D(GL_TEXTURE_1D_ARRAY, 0, tex_format, w, h, 0, default_format, default_type, NULL);
00826 VL_CHECK_OGL();
00827 }
00828 else
00829 if (tex_dimension == TD_TEXTURE_2D)
00830 {
00831 glTexImage2D(GL_TEXTURE_2D, 0, tex_format, w + (border?2:0), h + (border?2:0), border?1:0, default_format, default_type, NULL);
00832 VL_CHECK_OGL();
00833 }
00834 else
00835 if (tex_dimension == TD_TEXTURE_1D)
00836 {
00837 glTexImage1D(GL_TEXTURE_1D, 0, tex_format, w + (border?2:0), border?1:0, default_format, default_type, NULL);
00838 VL_CHECK_OGL();
00839 }
00840
00841 glBindTexture(tex_dimension, 0); VL_CHECK_OGL();
00842 return true;
00843 }
00844 }
00845
00846 bool Texture::setMipLevel(int mip_level, const Image* img, bool gen_mipmaps)
00847 {
00848 VL_CHECK_OGL()
00849
00850 #if defined(VL_OPENGL_ES1) || defined(VL_OPENGL_ES2)
00851 if (internalFormat() != img->format())
00852 {
00853 Log::bug("Texture::setMipLevel(): under OpenGL ES the texture internal format must match the source image format!\n");
00854 return false;
00855 }
00856 #endif
00857
00858 if ( dimension() == TD_TEXTURE_BUFFER || dimension() == TD_TEXTURE_2D_MULTISAMPLE || dimension() == TD_TEXTURE_2D_MULTISAMPLE_ARRAY )
00859 {
00860 Log::bug("You cannot call Texture::setMipLevel() on a texture buffer or on a multisample texture!\n");
00861 return false;
00862 }
00863
00864 if (!mHandle)
00865 {
00866 Log::error("Texture::setMipLevel(): texture hasn't been created yet, please call createTexture() first!\n");
00867 VL_TRAP();
00868 return false;
00869 }
00870
00871 if ( !supports(dimension(), internalFormat(), mip_level, img->dimension(), img->width(), img->height(), img->depth(), border(), 0, 0, true) )
00872 {
00873 VL_CHECK_OGL()
00874 Log::error("Texture::setMipLevel(): the format/size combination requested is not supported.\n");
00875 return false;
00876 }
00877
00878 glPixelStorei( GL_UNPACK_ALIGNMENT, img->byteAlignment() ); VL_CHECK_OGL()
00879
00880 glBindTexture( dimension(), mHandle ); VL_CHECK_OGL()
00881
00882 int w = width() + (border()?2:0);
00883 int h = height() + (border()?2:0);
00884 int d = depth() + (border()?2:0);
00885 int is_compressed = (int)img->format() == (int)internalFormat() && isCompressedFormat( internalFormat() );
00886
00887 bool use_glu = false;
00888 GLint generate_mipmap_orig = GL_FALSE;
00889 if ( gen_mipmaps )
00890 {
00891 if ( Has_glGenerateMipmaps )
00892 {
00893
00894 }
00895 else
00896 if( Has_GL_GENERATE_MIPMAP )
00897 {
00898 glGetTexParameteriv( dimension(), GL_GENERATE_MIPMAP, &generate_mipmap_orig ); VL_CHECK_OGL()
00899 glTexParameteri(dimension(), GL_GENERATE_MIPMAP, GL_TRUE); VL_CHECK_OGL()
00900 }
00901 else
00902 {
00903 if (mip_level > 0)
00904 Log::error("Texture::setMipLevel(): automatic mipmaps generation for levels below 0 requires OpenGL 1.4 minimum.\n");
00905 else
00906 use_glu = true;
00907
00908 #define VL_IS_POW_2(x) ((x != 0) && ((x & (x - 1)) == 0))
00909 if ( !VL_IS_POW_2(w) || !VL_IS_POW_2(h) )
00910 Log::warning("Texture::setMipLevel(): the image will be rescaled to the nearest upper power of 2.\n");
00911 }
00912 }
00913
00914 if ( use_glu && is_compressed )
00915 {
00916 Log::error("Texture::setMipLevel(): could not generate compressed mipmaps, OpenGL 1.4 required.\n");
00917 use_glu = false;
00918 }
00919
00920 if ( use_glu && dimension() == TD_TEXTURE_3D )
00921 {
00922 Log::error("Texture::setMipLevel(): could not generate 3D mipmaps, OpenGL 1.4 required.\n");
00923 use_glu = false;
00924 }
00925
00926 if (dimension() == TD_TEXTURE_CUBE_MAP)
00927 {
00928 if (is_compressed)
00929 {
00930 VL_CHECK( img->requiredMemory() % 6 == 0 );
00931 int bytes = img->requiredMemory() / 6;
00932 glCompressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, mip_level, internalFormat(), w, h, border()?1:0, bytes, img->pixelsXP());
00933 glCompressedTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, mip_level, internalFormat(), w, h, border()?1:0, bytes, img->pixelsXN());
00934 glCompressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, mip_level, internalFormat(), w, h, border()?1:0, bytes, img->pixelsYP());
00935 glCompressedTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, mip_level, internalFormat(), w, h, border()?1:0, bytes, img->pixelsYN());
00936 glCompressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, mip_level, internalFormat(), w, h, border()?1:0, bytes, img->pixelsZP());
00937 glCompressedTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, mip_level, internalFormat(), w, h, border()?1:0, bytes, img->pixelsZN());
00938 VL_CHECK_OGL()
00939 }
00940 else
00941 {
00942 if (use_glu)
00943 {
00944 gluBuild2DMipmaps(GL_TEXTURE_CUBE_MAP_POSITIVE_X, internalFormat(), w, h, img->format(), img->type(), img->pixelsXP());
00945 gluBuild2DMipmaps(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, internalFormat(), w, h, img->format(), img->type(), img->pixelsXN());
00946 gluBuild2DMipmaps(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, internalFormat(), w, h, img->format(), img->type(), img->pixelsYP());
00947 gluBuild2DMipmaps(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, internalFormat(), w, h, img->format(), img->type(), img->pixelsYN());
00948 gluBuild2DMipmaps(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, internalFormat(), w, h, img->format(), img->type(), img->pixelsZP());
00949 gluBuild2DMipmaps(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, internalFormat(), w, h, img->format(), img->type(), img->pixelsZN());
00950 VL_CHECK_OGL()
00951 }
00952 else
00953 {
00954 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, mip_level, internalFormat(), w, h, border()?1:0, img->format(), img->type(), img->pixelsXP());
00955 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, mip_level, internalFormat(), w, h, border()?1:0, img->format(), img->type(), img->pixelsXN());
00956 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, mip_level, internalFormat(), w, h, border()?1:0, img->format(), img->type(), img->pixelsYP());
00957 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, mip_level, internalFormat(), w, h, border()?1:0, img->format(), img->type(), img->pixelsYN());
00958 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, mip_level, internalFormat(), w, h, border()?1:0, img->format(), img->type(), img->pixelsZP());
00959 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, mip_level, internalFormat(), w, h, border()?1:0, img->format(), img->type(), img->pixelsZN());
00960 VL_CHECK_OGL()
00961 }
00962 }
00963 }
00964 else
00965 if (dimension() == TD_TEXTURE_2D_ARRAY)
00966 {
00967 if (is_compressed)
00968 {
00969 VL_glCompressedTexImage3D(GL_TEXTURE_2D_ARRAY, mip_level, internalFormat(), w, h, d, border()?1:0, img->requiredMemory(), img->pixels());
00970 VL_CHECK_OGL()
00971 }
00972 else
00973 {
00974 VL_glTexImage3D(GL_TEXTURE_2D_ARRAY, mip_level, internalFormat(), w, h, d, border()?1:0, img->format(), img->type(), img->pixels());
00975 VL_CHECK_OGL()
00976 }
00977 }
00978 else
00979 if (dimension() == TD_TEXTURE_3D)
00980 {
00981 if (is_compressed)
00982 {
00983 VL_glCompressedTexImage3D(GL_TEXTURE_3D, mip_level, internalFormat(), w, h, d, border()?1:0, img->requiredMemory(), img->pixels());
00984 VL_CHECK_OGL()
00985 }
00986 else
00987 {
00988 VL_glTexImage3D(GL_TEXTURE_3D, mip_level, internalFormat(), w, h, d, border()?1:0, img->format(), img->type(), img->pixels());
00989 VL_CHECK_OGL()
00990 }
00991 }
00992 else
00993 if (dimension() == TD_TEXTURE_RECTANGLE)
00994 {
00995 if (is_compressed)
00996 {
00997 glCompressedTexImage2D(GL_TEXTURE_RECTANGLE, mip_level, internalFormat(), width(), height(), 0, img->requiredMemory(), img->pixels());
00998 VL_CHECK_OGL()
00999 }
01000 else
01001 {
01002 glTexImage2D(GL_TEXTURE_RECTANGLE, mip_level, internalFormat(), width(), height(), 0, img->format(), img->type(), img->pixels());
01003 VL_CHECK_OGL()
01004 }
01005 }
01006 else
01007 if (dimension() == TD_TEXTURE_1D_ARRAY)
01008 {
01009 if (is_compressed)
01010 {
01011 glCompressedTexImage2D(GL_TEXTURE_1D_ARRAY, mip_level, internalFormat(), width(), height(), 0, img->requiredMemory(), img->pixels());
01012 VL_CHECK_OGL()
01013 }
01014 else
01015 {
01016 glTexImage2D(GL_TEXTURE_1D_ARRAY, mip_level, internalFormat(), width(), height(), 0, img->format(), img->type(), img->pixels());
01017 VL_CHECK_OGL()
01018 }
01019 }
01020 else
01021 if (dimension() == TD_TEXTURE_2D)
01022 {
01023 if (is_compressed)
01024 {
01025 glCompressedTexImage2D(GL_TEXTURE_2D, mip_level, internalFormat(), w, h, border()?1:0, img->requiredMemory(), img->pixels());
01026 VL_CHECK_OGL()
01027 }
01028 else
01029 {
01030 if (use_glu)
01031 {
01032 gluBuild2DMipmaps(GL_TEXTURE_2D, internalFormat(), w, h, img->format(), img->type(), img->pixels());
01033 VL_CHECK_OGL()
01034 }
01035 else
01036 {
01037 glTexImage2D(GL_TEXTURE_2D, mip_level, internalFormat(), w, h, border()?1:0, img->format(), img->type(), img->pixels());
01038 VL_CHECK_OGL()
01039 }
01040 }
01041 }
01042 else
01043 if (dimension() == TD_TEXTURE_1D)
01044 {
01045 if (is_compressed)
01046 {
01047 glCompressedTexImage1D(GL_TEXTURE_1D, mip_level, internalFormat(), w, border()?1:0, img->requiredMemory(), img->pixels());
01048 VL_CHECK_OGL()
01049 }
01050 else
01051 {
01052 if (use_glu)
01053 {
01054 gluBuild1DMipmaps(GL_TEXTURE_1D, internalFormat(), w, img->format(), img->type(), img->pixels());
01055 VL_CHECK_OGL()
01056 }
01057 else
01058 {
01059 glTexImage1D(GL_TEXTURE_1D, mip_level, internalFormat(), w, border()?1:0, img->format(), img->type(), img->pixels());
01060 VL_CHECK_OGL()
01061 }
01062 }
01063 }
01064
01065 if ( gen_mipmaps )
01066 {
01067 if ( Has_glGenerateMipmaps )
01068 {
01069 glGenerateMipmap( dimension() );
01070 }
01071 else
01072 if ( Has_GL_GENERATE_MIPMAP )
01073 {
01074 glTexParameteri(dimension(), GL_GENERATE_MIPMAP, generate_mipmap_orig); VL_CHECK_OGL()
01075 }
01076 }
01077
01078 glBindTexture( dimension(), 0 ); VL_CHECK_OGL()
01079
01080 glPixelStorei( GL_UNPACK_ALIGNMENT, 4 );
01081
01082 return true;
01083 }
01084
01085 bool Texture::createTexture()
01086 {
01087 VL_CHECK_OGL()
01088
01089 if (!setupParams())
01090 return false;
01091
01092 class InOutCondition
01093 {
01094 Texture* mTex;
01095 public:
01096 InOutCondition(Texture* tex): mTex(tex) {}
01097 ~InOutCondition()
01098 {
01099
01100 VL_CHECK_OGL()
01101
01102
01103 if (mTex->mSetupParams)
01104 {
01105 if (mTex->mSetupParams->imagePath().empty() && mTex->mSetupParams->image())
01106 mTex->mSetupParams->setImagePath( mTex->mSetupParams->image()->filePath() );
01107 mTex->mSetupParams->setImage(NULL);
01108 mTex->mSetupParams->setBufferObject(NULL);
01109 }
01110 }
01111 };
01112
01113 InOutCondition in_out_condition(this);
01114
01115 ETextureFormat tex_format = setupParams()->format();
01116 ETextureDimension tex_dimension = setupParams()->dimension();
01117 bool gen_mipmaps = setupParams()->genMipmaps();
01118 bool border = setupParams()->border();
01119 if ( !setupParams()->image() && !setupParams()->imagePath().empty() )
01120 {
01121 setupParams()->setImage( loadImage( setupParams()->imagePath() ).get() );
01122 if (!setupParams()->image())
01123 {
01124 vl::Log::error( Say("Texture::createTexture(): could not load image file '%s'\n") << setupParams()->imagePath() );
01125 return false;
01126 }
01127 }
01128
01129 ref<Image> img = const_cast<Image*>(setupParams()->image());
01130
01131 int w = setupParams()->width();
01132 int h = setupParams()->height();
01133 int d = setupParams()->depth();
01134 if (img)
01135 {
01136 setObjectName( img->objectName().c_str() );
01137 w = img->width();
01138 h = img->height();
01139 d = img->depth();
01140
01141 if (tex_format == TF_UNKNOWN)
01142 tex_format = (ETextureFormat)img->format();
01143 }
01144
01145
01146
01147
01148 if ( !createTexture( tex_dimension, tex_format, w, h, d, border, setupParams()->bufferObject(), setupParams()->samples(), setupParams()->fixedSamplesLocations() ) )
01149 return false;
01150
01151 VL_CHECK_OGL()
01152
01153 if (img)
01154 {
01155
01156 std::vector<const vl::Image*> mipmaps;
01157 mipmaps.push_back(img.get());
01158 for(int i=0; i<(int)img->mipmaps().size(); ++i)
01159 mipmaps.push_back( img->mipmaps()[i].get() );
01160
01161 bool ok = false;
01162
01163 if (!gen_mipmaps)
01164 {
01165 ok = setMipLevel(0, img.get(), false);
01166 }
01167 else
01168 {
01169 if (mipmaps.size() > 1)
01170 {
01171 for(int i=0; i<(int)mipmaps.size(); ++i)
01172 ok = setMipLevel(i, mipmaps[i], false);
01173 }
01174 else
01175 if (mipmaps.size() == 1)
01176 {
01177 ok = setMipLevel(0, img.get(), true);
01178 }
01179 }
01180 return ok;
01181 }
01182 else
01183 return true;
01184 }
01185
01186 void Texture::clone(const Texture& other)
01187 {
01188
01189 if (other.mSetupParams)
01190 mSetupParams = new SetupParams(*other.mSetupParams);
01191 else
01192 mSetupParams = NULL;
01193 mHandle = other.mHandle;
01194 mTexParameter = other.mTexParameter;
01195 mBufferObject = other.mBufferObject;
01196 mFormat = other.mFormat;
01197 mDimension = other.mDimension;
01198 mWidth = other.mWidth;
01199 mHeight = other.mHeight;
01200 mDepth = other.mDepth;
01201 mSamples = other.mSamples;
01202 mBorder = other.mBorder;
01203 mFixedSamplesLocation = other.mFixedSamplesLocation;
01204 }
01205
01206 bool Texture::isDepthTexture() const
01207 {
01208 switch(internalFormat())
01209 {
01210 case TF_DEPTH_STENCIL:
01211 case TF_DEPTH24_STENCIL8:
01212
01213 case TF_DEPTH_COMPONENT32F:
01214 case TF_DEPTH32F_STENCIL8:
01215
01216 case TF_DEPTH_COMPONENT:
01217 case TF_DEPTH_COMPONENT16:
01218 case TF_DEPTH_COMPONENT24:
01219 case TF_DEPTH_COMPONENT32:
01220 return true;
01221
01222 default:
01223 return false;
01224 }
01225 }
01226
01227 bool Texture::isCompressedFormat(int format)
01228 {
01229 int comp[] =
01230 {
01231 TF_COMPRESSED_ALPHA,
01232 TF_COMPRESSED_INTENSITY,
01233 TF_COMPRESSED_LUMINANCE,
01234 TF_COMPRESSED_LUMINANCE_ALPHA,
01235 TF_COMPRESSED_RGB,
01236 TF_COMPRESSED_RGBA,
01237
01238
01239 TF_COMPRESSED_RGB_FXT1_3DFX,
01240 TF_COMPRESSED_RGBA_FXT1_3DFX,
01241
01242
01243 TF_COMPRESSED_RGB_S3TC_DXT1_EXT,
01244 TF_COMPRESSED_RGBA_S3TC_DXT1_EXT,
01245 TF_COMPRESSED_RGBA_S3TC_DXT3_EXT,
01246 TF_COMPRESSED_RGBA_S3TC_DXT5_EXT,
01247
01248
01249 TF_COMPRESSED_LUMINANCE_LATC1_EXT,
01250 TF_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT,
01251 TF_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT,
01252 TF_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT,
01253
01254
01255 TF_COMPRESSED_RED_RGTC1_EXT,
01256 TF_COMPRESSED_SIGNED_RED_RGTC1_EXT,
01257 TF_COMPRESSED_RED_GREEN_RGTC2_EXT,
01258 TF_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT,
01259
01260 0
01261 };
01262
01263 for(int i=0; comp[i]; ++i)
01264 {
01265 if(comp[i] == format)
01266 return true;
01267 }
01268
01269 return false;
01270 }
01271