# Visualization Library

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

[Home] [Tutorials] [All Classes] [Grouped Classes]

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

# D:/VL/BuildSystem/VL_DISTRO/Visualization_Library_SDK/src/vlGraphics/Texture.cpp

Go to the documentation of this file.

    00001 /**************************************************************************************/
    00002 /*                                                                                    */
    00003 /*  Visualization Library                                                             */
    00004 /*  http://www.visualizationlibrary.com                                               */
    00005 /*                                                                                    */
    00006 /*  Copyright (c) 2005-2010, Michele Bosi                                             */
    00007 /*  All rights reserved.                                                              */
    00008 /*                                                                                    */
    00009 /*  Redistribution and use in source and binary forms, with or without modification,  */
    00010 /*  are permitted provided that the following conditions are met:                     */
    00011 /*                                                                                    */
    00012 /*  - Redistributions of source code must retain the above copyright notice, this     */
    00013 /*  list of conditions and the following disclaimer.                                  */
    00014 /*                                                                                    */
    00015 /*  - Redistributions in binary form must reproduce the above copyright notice, this  */
    00016 /*  list of conditions and the following disclaimer in the documentation and/or       */
    00017 /*  other materials provided with the distribution.                                   */
    00018 /*                                                                                    */
    00019 /*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND   */
    00020 /*  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED     */
    00021 /*  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE            */
    00022 /*  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR  */
    00023 /*  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    */
    00024 /*  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;      */
    00025 /*  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON    */
    00026 /*  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT           */
    00027 /*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS     */
    00028 /*  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                      */
    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       // case TF_RGB16_SNORM:
    00108       case TF_RGB16F:
    00109       case TF_RGB32F:
    00110       case TF_R3_G3_B2:
    00111       case TF_R11F_G11F_B10F:
    00112       // case TF_RGB9_A5:
    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       // case TF_RGB8I_EXT: // Has the same value has above
    00149       case TF_RGB8UI:
    00150       // case TF_RGB8UI_EXT: // Has the same value has above
    00151       case TF_RGB16I:
    00152       // case TF_RGB16I_EXT: // Has the same value has above
    00153       case TF_RGB16UI:
    00154       // case TF_RGB16UI_EXT: // Has the same value has above
    00155       case TF_RGB32I:
    00156       // case TF_RGB32I_EXT: // Has the same value has above
    00157       case TF_RGB32UI:
    00158       // case TF_RGB32UI_EXT: // Has the same value has above
    00159         return GL_RGB_INTEGER;
    00160
    00161       case TF_RGBA8I:
    00162       // case TF_RGBAI_EXT: // Has the same value has above
    00163       case TF_RGBA8UI:
    00164       // case TF_RGBA8UI_EXT: // Has the same value has above
    00165       case TF_RGBA16I:
    00166       // case TF_RGBA16I_EXT: // Has the same value has above
    00167       case TF_RGBA16UI:
    00168       // case TF_RGBA16UI_EXT: // Has the same value has above
    00169       case TF_RGBA32I:
    00170       // case TF_RGBA32I_EXT: // Has the same value has above
    00171       case TF_RGBA32UI:
    00172       // case TF_RGBA32UI_EXT: // Has the same value has above
    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       // GL_EXT_texture_integer
    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; // Nothing associated with intensity in GL_EXT_texture_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 // Texture
    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   // clear errors
    00465
    00466   glGetError();
    00467
    00468   // texture buffer
    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     // these should be non zero
    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     // these should be zero
    00515     VL_CHECK( !(w||h||d) );
    00516   }
    00517
    00518   // cubemaps
    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   // texture arrays
    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   // texture rectangle
    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; // pass the test
    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       // the buffer object must not be empty!
    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; // the user cannot change this
    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       // do nothing, we will use glGenerateMipmaps later
    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) // because GLU regenerates the whole mip-mapping chain
    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       // make sure no errors were generated
    01048       VL_CHECK_OGL()
    01049
    01050       // uninstall setup parameters
    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   //w = w > 0 ? w : 1;
    01083   //h = h > 0 ? h : 1;
    01084   //d = d > 0 ? d : 1;
    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     // compile mipmapping levels
    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) // no mipmaps
    01102       ok = setMipLevel(0, img.get(), false);
    01103     else
    01104     {
    01105       if (mipmaps.size() > 1) // explicit mipmaps
    01106       {
    01107         for(int i=0; i<(int)mipmaps.size(); ++i)
    01108           ok = setMipLevel(i, mipmaps[i], false);
    01109       }
    01110       else // automatic mipmaps generation
    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   // keep its own copyof SetupParams
    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     // 3DFX_texture_compression_FXT1
    01175     TF_COMPRESSED_RGB_FXT1_3DFX,
    01176     TF_COMPRESSED_RGBA_FXT1_3DFX,
    01177
    01178     // EXT_texture_compression_s3tc
    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     // GL_EXT_texture_compression_latc
    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     // EXT_texture_compression_rgtc
    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 //-----------------------------------------------------------------------------

Visualization Library v2011.05.1142 Reference Documentation
Copyright 2005-2011 Michele Bosi. All rights reserved.
Updated on Thu May 26 2011 22:51:25.
Permission is granted to use this page to write and publish articles regarding Visualization Library.