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