# Visualization Library

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

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

- Main Page
- Related Pages
- 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.org                                               */
    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/math_utils.hpp>
    00036 #include <vlCore/Say.hpp>
    00037 #include <vlCore/Log.hpp>
    00038
    00039 using namespace vl;
    00040
    00041 namespace
    00042 {
    00043   // if you think your application has a bug that depends on this function you are wrong
    00044   int getDefaultFormat(ETextureFormat internal_format)
    00045   {
    00046     // OpenGL ES requires the internal format to be equal to the source image format when creating textures
    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       // case TF_RGB16_SNORM:
    00113       case TF_RGB16F:
    00114       case TF_RGB32F:
    00115       case TF_R3_G3_B2:
    00116       case TF_R11F_G11F_B10F:
    00117       // case TF_RGB9_A5:
    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       // case TF_RGB8I_EXT: // Has the same value has above
    00154       case TF_RGB8UI:
    00155       // case TF_RGB8UI_EXT: // Has the same value has above
    00156       case TF_RGB16I:
    00157       // case TF_RGB16I_EXT: // Has the same value has above
    00158       case TF_RGB16UI:
    00159       // case TF_RGB16UI_EXT: // Has the same value has above
    00160       case TF_RGB32I:
    00161       // case TF_RGB32I_EXT: // Has the same value has above
    00162       case TF_RGB32UI:
    00163       // case TF_RGB32UI_EXT: // Has the same value has above
    00164         return GL_RGB_INTEGER;
    00165
    00166       case TF_RGBA8I:
    00167       // case TF_RGBAI_EXT: // Has the same value has above
    00168       case TF_RGBA8UI:
    00169       // case TF_RGBA8UI_EXT: // Has the same value has above
    00170       case TF_RGBA16I:
    00171       // case TF_RGBA16I_EXT: // Has the same value has above
    00172       case TF_RGBA16UI:
    00173       // case TF_RGBA16UI_EXT: // Has the same value has above
    00174       case TF_RGBA32I:
    00175       // case TF_RGBA32I_EXT: // Has the same value has above
    00176       case TF_RGBA32UI:
    00177       // case TF_RGBA32UI_EXT: // Has the same value has above
    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       // GL_EXT_texture_integer
    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; // Nothing associated with intensity in GL_EXT_texture_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   // if you think your application has a bug that depends on this function you are wrong
    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 // Texture
    00358 //-----------------------------------------------------------------------------
    00359 void Texture::destroyTexture()
    00360 {
    00361   if (mHandle)
    00362     glDeleteTextures(1, &mHandle);
    00363   reset();
    00364   // getTexParameter()->mDirty = true;
    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   // clear errors
    00498
    00499   glGetError();
    00500
    00501   // texture buffer
    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     // these should be non zero
    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     // these should be zero
    00548     VL_CHECK( !(w||h||d) );
    00549   }
    00550
    00551   // cubemaps
    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   // texture arrays
    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   // texture rectangle
    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   // OpenGL ES does not support proxy textures and glGetTexLevelParameter*
    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; // pass the test
    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       // the buffer object must not be empty!
    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; // the user cannot change this
    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       // do nothing, we will use glGenerateMipmaps later
    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) // because GLU regenerates the whole mip-mapping chain
    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       // make sure no errors were generated
    01100       VL_CHECK_OGL()
    01101
    01102       // release Image and BufferObject from SetupParams
    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     // guess from image format
    01141     if (tex_format == TF_UNKNOWN)
    01142       tex_format = (ETextureFormat)img->format();
    01143   }
    01144   //w = w > 0 ? w : 1;
    01145   //h = h > 0 ? h : 1;
    01146   //d = d > 0 ? d : 1;
    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     // compile mipmapping levels
    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) // no mipmaps
    01164     {
    01165       ok = setMipLevel(0, img.get(), false);
    01166     }
    01167     else
    01168     {
    01169       if (mipmaps.size() > 1) // explicit mipmaps
    01170       {
    01171         for(int i=0; i<(int)mipmaps.size(); ++i)
    01172           ok = setMipLevel(i, mipmaps[i], false);
    01173       }
    01174       else // automatic mipmaps generation
    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   // keep its own copyof SetupParams
    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     // 3DFX_texture_compression_FXT1
    01239     TF_COMPRESSED_RGB_FXT1_3DFX,
    01240     TF_COMPRESSED_RGBA_FXT1_3DFX,
    01241
    01242     // EXT_texture_compression_s3tc
    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     // GL_EXT_texture_compression_latc
    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     // EXT_texture_compression_rgtc
    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 //-----------------------------------------------------------------------------

Visualization Library v2011.09.1162 Reference Documentation
Copyright 2005-2011 Michele Bosi. All rights reserved.
Updated on Thu Jan 26 2012 00:43:44.
Permission is granted to use this page to write and publish articles regarding Visualization Library.