OSGTextureChunk.cpp

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002  *                                OpenSG                                     *
00003  *                                                                           *
00004  *                                                                           *
00005  *             Copyright (C) 2000-2002 by the OpenSG Forum                   *
00006  *                                                                           *
00007  *                            www.opensg.org                                 *
00008  *                                                                           *
00009  *   contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de          *
00010  *                                                                           *
00011 \*---------------------------------------------------------------------------*/
00012 /*---------------------------------------------------------------------------*\
00013  *                                License                                    *
00014  *                                                                           *
00015  * This library is free software; you can redistribute it and/or modify it   *
00016  * under the terms of the GNU Library General Public License as published    *
00017  * by the Free Software Foundation, version 2.                               *
00018  *                                                                           *
00019  * This library is distributed in the hope that it will be useful, but       *
00020  * WITHOUT ANY WARRANTY; without even the implied warranty of                *
00021  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU         *
00022  * Library General Public License for more details.                          *
00023  *                                                                           *
00024  * You should have received a copy of the GNU Library General Public         *
00025  * License along with this library; if not, write to the Free Software       *
00026  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                 *
00027  *                                                                           *
00028 \*---------------------------------------------------------------------------*/
00029 /*---------------------------------------------------------------------------*\
00030  *                                Changes                                    *
00031  *                                                                           *
00032  *                                                                           *
00033  *                                                                           *
00034  *                                                                           *
00035  *                                                                           *
00036  *                                                                           *
00037 \*---------------------------------------------------------------------------*/
00038 
00039 //---------------------------------------------------------------------------
00040 //  Includes
00041 //---------------------------------------------------------------------------
00042 
00043 #include <cstdlib>
00044 #include <cstdio>
00045 
00046 #include <boost/bind.hpp>
00047 
00048 #include "OSGConfig.h"
00049 
00050 #include <OSGGL.h>
00051 #include <OSGGLU.h>
00052 #include <OSGGLEXT.h>
00053 #include <OSGImage.h>
00054 
00055 #include "OSGDrawActionBase.h"
00056 #include "OSGDrawEnv.h"
00057 
00058 #include "OSGTextureChunk.h"
00059 
00060 //#define OSG_DUMP_TEX
00061 
00062 OSG_USING_NAMESPACE
00063 
00064 // Documentation for this class is emited in the
00065 // OSGTextureChunkBase.cpp file.
00066 // To modify it, please change the .fcd file (OSGTextureChunk.fcd) and
00067 // regenerate the base file.
00068 
00069 /***************************************************************************\
00070  *                           Class variables                               *
00071 \***************************************************************************/
00072 
00073 UInt32 TextureChunk::_extTex3D                    = Window::invalidExtensionID;
00074 UInt32 TextureChunk::_arbMultiTex                 = Window::invalidExtensionID;
00075 UInt32 TextureChunk::_arbCubeTex                  = Window::invalidExtensionID;
00076 UInt32 TextureChunk::_nvPointSprite               = Window::invalidExtensionID;
00077 UInt32 TextureChunk::_nvTextureShader             = Window::invalidExtensionID;
00078 UInt32 TextureChunk::_nvTextureShader2            = Window::invalidExtensionID;
00079 UInt32 TextureChunk::_nvTextureShader3            = Window::invalidExtensionID;
00080 UInt32 TextureChunk::_sgisGenerateMipmap          = Window::invalidExtensionID;
00081 UInt32 TextureChunk::_extTextureLodBias           = Window::invalidExtensionID;
00082 UInt32 TextureChunk::_arbTextureCompression       = Window::invalidExtensionID;
00083 UInt32 TextureChunk::_arbTextureRectangle         = Window::invalidExtensionID;
00084 UInt32 TextureChunk::_arbTextureNonPowerOfTwo     = Window::invalidExtensionID;
00085 UInt32 TextureChunk::_extTextureFilterAnisotropic = Window::invalidExtensionID;
00086 UInt32 TextureChunk::_extShadow                   = Window::invalidExtensionID;
00087 UInt32 TextureChunk::_extDepthTexture             = Window::invalidExtensionID;
00088 
00089 UInt32 TextureChunk::_funcTexImage3D              = Window::invalidFunctionID;
00090 UInt32 TextureChunk::_funcTexSubImage3D           = Window::invalidFunctionID;
00091 UInt32 TextureChunk::_funcActiveTexture           = Window::invalidFunctionID;
00092 UInt32 TextureChunk::_funcCompressedTexImage1D    = Window::invalidFunctionID;
00093 UInt32 TextureChunk::_funcCompressedTexSubImage1D = Window::invalidFunctionID;
00094 UInt32 TextureChunk::_funcCompressedTexImage2D    = Window::invalidFunctionID;
00095 UInt32 TextureChunk::_funcCompressedTexSubImage2D = Window::invalidFunctionID;
00096 UInt32 TextureChunk::_funcCompressedTexImage3D    = Window::invalidFunctionID;
00097 UInt32 TextureChunk::_funcCompressedTexSubImage3D = Window::invalidFunctionID;
00098 
00099 // define GL_TEXTURE_3D, if not defined yet
00100 #ifndef GL_VERSION_1_2
00101 #  define GL_FUNC_TEXIMAGE3D    OSG_DLSYM_UNDERSCORE"glTexImage3DEXT"
00102 #  define GL_FUNC_TEXSUBIMAGE3D OSG_DLSYM_UNDERSCORE"glTexSubImage3DEXT"
00103 #else
00104 #  define GL_FUNC_TEXIMAGE3D    OSG_DLSYM_UNDERSCORE"glTexImage3D"
00105 #  define GL_FUNC_TEXSUBIMAGE3D OSG_DLSYM_UNDERSCORE"glTexSubImage3D"
00106 #endif
00107 
00108 
00109 /***************************************************************************\
00110  *                           Class methods                                 *
00111 \***************************************************************************/
00112 
00113 /*-------------------------------------------------------------------------*\
00114  -  private                                                                -
00115 \*-------------------------------------------------------------------------*/
00116 
00117 void TextureChunk::initMethod(InitPhase ePhase)
00118 {
00119     Inherited::initMethod(ePhase);
00120 
00121     if(ePhase == TypeObject::SystemPost)
00122     {
00123         _extTex3D          =
00124             Window::registerExtension("GL_EXT_texture3D"       );
00125         _arbMultiTex       =
00126             Window::registerExtension("GL_ARB_multitexture"    );
00127         _arbCubeTex        =
00128             Window::registerExtension("GL_ARB_texture_cube_map");
00129         _nvPointSprite     =
00130             Window::registerExtension("GL_NV_point_sprite"     );
00131         _nvTextureShader   =
00132             Window::registerExtension("GL_NV_texture_shader"   );
00133         _nvTextureShader2  =
00134             Window::registerExtension("GL_NV_texture_shader2"  );
00135         _nvTextureShader3  =
00136             Window::registerExtension("GL_NV_texture_shader3"  );
00137         _sgisGenerateMipmap  =
00138             Window::registerExtension("GL_SGIS_generate_mipmap"  );
00139         _extTextureLodBias  = 
00140             Window::registerExtension("GL_EXT_texture_lod_bias"  );
00141         _arbTextureCompression  = 
00142             Window::registerExtension("GL_ARB_texture_compression"  );
00143         _arbTextureRectangle  = 
00144             Window::registerExtension("GL_ARB_texture_rectangle"    );
00145         _arbTextureNonPowerOfTwo  = 
00146             Window::registerExtension("GL_ARB_texture_non_power_of_two" );
00147         _extTextureFilterAnisotropic = 
00148             Window::registerExtension("GL_EXT_texture_filter_anisotropic" );
00149 
00150         _extShadow =
00151             Window::registerExtension("GL_ARB_shadow"  );
00152         _extDepthTexture =
00153             Window::registerExtension("GL_ARB_dept_texture"  );
00154 
00155         _funcTexImage3D    =
00156             Window::registerFunction (GL_FUNC_TEXIMAGE3D, 
00157                                       _extTex3D);
00158         _funcTexSubImage3D =
00159             Window::registerFunction (GL_FUNC_TEXSUBIMAGE3D, 
00160                                       _extTex3D);
00161         _funcActiveTexture =
00162             Window::registerFunction (OSG_DLSYM_UNDERSCORE"glActiveTextureARB",
00163                                       _arbMultiTex);
00164         
00165         _funcCompressedTexImage1D    = Window::registerFunction(
00166             OSG_DLSYM_UNDERSCORE"glCompressedTexImage1DARB"             , 
00167             _arbTextureCompression);
00168 
00169         _funcCompressedTexSubImage1D = Window::registerFunction(
00170             OSG_DLSYM_UNDERSCORE"glCompressedTexSubImage1DARB"          , 
00171             _arbTextureCompression);
00172 
00173         _funcCompressedTexImage2D    = Window::registerFunction(
00174             OSG_DLSYM_UNDERSCORE"glCompressedTexImage2DARB"             , 
00175             _arbTextureCompression);
00176 
00177         _funcCompressedTexSubImage2D = Window::registerFunction(
00178             OSG_DLSYM_UNDERSCORE"glCompressedTexSubImage2DARB"          , 
00179             _arbTextureCompression);
00180 
00181         _funcCompressedTexImage3D    = Window::registerFunction(
00182             OSG_DLSYM_UNDERSCORE"glCompressedTexImage3DARB"             , 
00183             _arbTextureCompression);
00184 
00185         _funcCompressedTexSubImage3D = Window::registerFunction(
00186             OSG_DLSYM_UNDERSCORE"glCompressedTexSubImage3DARB"          , 
00187             _arbTextureCompression);
00188         
00189         Window::registerConstant(GL_MAX_TEXTURE_UNITS_ARB      );
00190         Window::registerConstant(GL_MAX_TEXTURE_IMAGE_UNITS_ARB);
00191         Window::registerConstant(GL_MAX_TEXTURE_COORDS_ARB     );    
00192     }
00193 }
00194 
00195 /***************************************************************************\
00196  *                           Instance methods                              *
00197 \***************************************************************************/
00198 
00199 /*-------------------------------------------------------------------------*\
00200  -  private                                                                 -
00201 \*-------------------------------------------------------------------------*/
00202 
00203 
00204 /*------------- constructors & destructors --------------------------------*/
00205 
00206 TextureChunk::TextureChunk(void) :
00207     Inherited()
00208 {
00209 }
00210 
00211 TextureChunk::TextureChunk(const TextureChunk &source) :
00212     Inherited(source)
00213 {
00214 }
00215 
00216 TextureChunk::~TextureChunk(void)
00217 {
00218     if(getGLId() > 0)
00219         Window::destroyGLObject(getGLId(), 1);
00220 }
00221 
00222 /*------------------------- Chunk Class Access ---------------------------*/
00223 
00224 bool TextureChunk::isCubeTexture(void)
00225 {
00226     return 
00227         this->getImage()                 != NullFC && 
00228         this->getImage()->getSideCount() == 6;
00229 }
00230 
00231 /*------------------------------- Sync -----------------------------------*/
00232 
00233 
00234 
00240 void TextureChunk::changed(ConstFieldMaskArg whichField, 
00241                            UInt32            origin,
00242                            BitVector         details)
00243 {
00244 #ifdef GV_CHECK
00245     if(Thread::getAspect() != _sfIgnoreGLForAspect.getValue())
00246     {
00247         if(getGLId() == 0)
00248         {
00249             TextureChunkPtr tmpPtr(*this);
00250 
00251             beginEditCP(tmpPtr, TextureChunk::GLIdFieldMask);
00252             
00253             setGLId(               
00254                 Window::registerGLObject(
00255                     boost::bind(&TextureChunk::handleGL, tmpPtr, 
00256                                     _1, _2, _3),
00257                     &TextureChunk::handleDestroyGL
00258                     ));
00259             
00260             endEditCP(tmpPtr, TextureChunk::GLIdFieldMask);
00261         }
00262     }
00263 #endif
00264 
00265     // Only filter changed? Mipmaps need reinit.
00266     if((whichField & ~(MinFilterFieldMask | MagFilterFieldMask)) == 0)
00267     {
00268         if((getMinFilter() != GL_NEAREST) &&
00269            (getMinFilter() != GL_LINEAR))
00270         {
00271 #ifdef GV_CHECK
00272             if(Thread::getAspect() != _sfIgnoreGLForAspect.getValue())
00273             {
00274 #endif
00275                 Window::reinitializeGLObject(getGLId());
00276 #ifdef GV_CHECK
00277             }
00278 #endif
00279         }
00280         else
00281         {
00282             imageContentChanged();
00283         }
00284     } // Only priority changed? Refresh is fine.
00285     else if((whichField & ~PriorityFieldMask || FrameFieldMask) == 0)
00286     {
00287         imageContentChanged();
00288     } // Only dirty rectangle changed? Refresh is fine.
00289     else if ((whichField & ~(DirtyMinXFieldMask | DirtyMaxXFieldMask |
00290                              DirtyMinYFieldMask | DirtyMaxYFieldMask |
00291                              DirtyMinZFieldMask | DirtyMaxZFieldMask)) == 0)
00292     {
00293 #ifdef GV_CHECK
00294         if(Thread::getAspect() != _sfIgnoreGLForAspect.getValue())
00295         {
00296 #endif
00297             Window::refreshGLObject(getGLId());
00298 #ifdef GV_CHECK
00299         }
00300 #endif
00301     }  
00302     else
00303     {
00304 #ifdef GV_CHECK
00305         if(Thread::getAspect() != _sfIgnoreGLForAspect.getValue())
00306         {
00307 #endif
00308             Window::reinitializeGLObject(getGLId());
00309 #ifdef GV_CHECK
00310         }
00311 #endif
00312     }
00313 
00314     Inherited::changed(whichField, origin, details);
00315 }
00316 
00317 bool TextureChunk::isTransparent(void) const
00318 {
00319     // Even if the texture has alpha, the Blending makes the sorting
00320     // important, thus textures per se are not transparent
00321     return false;
00322 }
00323 
00324 
00325 /*----------------------------- onCreate --------------------------------*/
00326 
00327 void TextureChunk::onCreate(const TextureChunk *source)
00328 {
00329     Inherited::onCreate(source);
00330 
00331     if(GlobalSystemState == Startup)
00332         return;
00333 
00334 #ifdef GV_CHECK
00335     if(Thread::getAspect() != _sfIgnoreGLForAspect.getValue())
00336     {
00337 #endif
00338        
00339         setGLId(               
00340             Window::registerGLObject(
00341                 boost::bind(&TextureChunk::handleGL, this, 
00342                                 _1, _2, _3),
00343                 &TextureChunk::handleDestroyGL
00344                 ));
00345 
00346 #ifdef GV_CHECK
00347     }
00348 #endif
00349 }
00350 
00351 void TextureChunk::onCreateAspect(const TextureChunk *createAspect,
00352                                   const TextureChunk *source      )
00353 {
00354     Inherited::onCreateAspect(createAspect, source);
00355 }
00356 
00357 /*------------------------------ Output ----------------------------------*/
00358 
00359 void TextureChunk::dump(      UInt32    OSG_CHECK_ARG(uiIndent),
00360                         const BitVector OSG_CHECK_ARG(bvFlags )) const
00361 {
00362     SLOG << "Dump TextureChunk NI" << std::endl;
00363 }
00364 
00365 
00366 /*------------------------------ State ------------------------------------*/
00367 
00372 void TextureChunk::handleTextureShader(Window *win, GLenum bindtarget)
00373 {
00374     if(!win->hasExtension(_nvTextureShader))
00375     {
00376         if(getShaderOperation() != GL_NONE)
00377             FINFO(("NV Texture Shaders not supported on Window %p!\n", win));
00378         return;
00379     }
00380 
00381     glErr("textureShader precheck");
00382 
00383     glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV,
00384                 getShaderOperation());
00385 
00386     glErr("textureShader setup: operation");
00387 
00388     if(getShaderOperation() == GL_NONE)
00389         return;
00390 
00391     if(bindtarget == GL_TEXTURE_3D && !win->hasExtension(_nvTextureShader2))
00392     {
00393         FINFO(("NV Texture Shaders 2 not supported on Window %p!\n", win));
00394         return;
00395     }
00396 
00397     if(getShaderInput() != GL_NONE)
00398         glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV,
00399                     getShaderInput());
00400 
00401     glErr("textureShader setup: input");
00402 
00403     if(getShaderRGBADotProduct() != GL_NONE)
00404         glTexEnvi(GL_TEXTURE_SHADER_NV, 
00405                   GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV,
00406                   getShaderRGBADotProduct());
00407 
00408     glErr("textureShader setup: rgba dotprod");
00409 
00410     if(getShaderOffsetMatrix().size() == 4)
00411     {
00412         glTexEnvfv(GL_TEXTURE_SHADER_NV, GL_OFFSET_TEXTURE_MATRIX_NV,
00413                     (GLfloat*)&(getShaderOffsetMatrix()[0]));
00414 
00415         glErr("textureShader setup: offset matrix");
00416     }
00417     else if(getShaderOffsetMatrix().size() != 0)
00418     {
00419         FWARNING(("TextureChunk::handleTextureShader: shaderOffsetMatrix has"
00420                     " to have 4 entries, not %d!\n",
00421                     getShaderOffsetMatrix().size() ));
00422     }
00423 
00424     glTexEnvf(GL_TEXTURE_SHADER_NV, GL_OFFSET_TEXTURE_SCALE_NV,
00425                 getShaderOffsetScale());
00426 
00427     glErr("textureShader setup: offset scale");
00428 
00429     glTexEnvf(GL_TEXTURE_SHADER_NV, GL_OFFSET_TEXTURE_BIAS_NV,
00430                 getShaderOffsetBias());
00431 
00432     glErr("textureShader setup: offset bias");
00433 
00434     GLint cullmodes[4];
00435     if(getShaderCullModes() & 0x1)
00436     {
00437         cullmodes[0] = GL_GEQUAL;
00438     }
00439     else
00440     {
00441         cullmodes[0] = GL_LESS;
00442     }
00443 
00444     if(getShaderCullModes() & 0x2)
00445     {
00446         cullmodes[1] = GL_GEQUAL;
00447     }
00448     else
00449     {
00450         cullmodes[1] = GL_LESS;
00451     }
00452 
00453     if(getShaderCullModes() & 0x4)
00454     {
00455         cullmodes[2] = GL_GEQUAL;
00456     }
00457     else
00458     {
00459         cullmodes[2] = GL_LESS;
00460     }
00461 
00462     if(getShaderCullModes() & 0x8)
00463     {
00464         cullmodes[3] = GL_GEQUAL;
00465     }
00466     else
00467     {
00468         cullmodes[3] = GL_LESS;
00469     }
00470 
00471     glTexEnviv(GL_TEXTURE_SHADER_NV, GL_CULL_MODES_NV,
00472                     cullmodes);
00473 
00474     glErr("textureShader setup: cull modes");
00475 
00476     glTexEnvfv(GL_TEXTURE_SHADER_NV, GL_CONST_EYE_NV,
00477                     getShaderConstEye().getValues());
00478 
00479     glErr("textureShader setup: const eye");
00480 
00481 
00482 
00483 #ifdef OSG_DEBUG
00484     GLint consistent;
00485     glGetTexEnviv(GL_TEXTURE_SHADER_NV, GL_SHADER_CONSISTENT_NV,
00486           &consistent);
00487     if(!consistent)
00488     {
00489         FWARNING(("Texture shaders not consistent!\n"));
00490     }
00491 #endif
00492 }
00493 
00494 void TextureChunk::handleTexture(Window *win, 
00495                                  UInt32 id,
00496                                  GLenum bindtarget,
00497                                  GLenum paramtarget,
00498                                  GLenum imgtarget,
00499                                  Window::GLObjectStatusE mode, 
00500                                  ImagePtr img,
00501                                  Int32    side)
00502 {
00503     if( img==NullFC || ! img->getDimension()) // no image ?
00504         return;
00505 
00506     if(mode == Window::initialize || mode == Window::reinitialize)
00507     {
00508         if( bindtarget                  == GL_TEXTURE_3D && 
00509            !win->hasExtension(_extTex3D)                 &&
00510             win->getGLVersion()         < 0x0102          )
00511         {
00512             FNOTICE(("3D textures not supported on Window %p!\n", win));
00513             return;
00514         }
00515 
00516         if(imgtarget == GL_TEXTURE_RECTANGLE_ARB && 
00517            !win->hasExtension(_arbTextureRectangle))
00518         {
00519             FNOTICE(("Rectangular textures not supported on Window %p!\n", 
00520                      win));
00521             return;
00522         }
00523 
00524         if(paramtarget == GL_TEXTURE_CUBE_MAP_ARB && 
00525            !win->hasExtension(_arbCubeTex))
00526         {
00527             FNOTICE(("Cube textures not supported on Window %p!\n", win));
00528             return;
00529         }
00530 
00531         if(img->hasCompressedData() && 
00532            !win->hasExtension(_arbTextureCompression))
00533         {
00534             FNOTICE(("Compressed textures not supported on Window %p!\n", 
00535                      win));
00536             return;
00537         }
00538 
00539         if(mode == Window::reinitialize)
00540         {
00541             GLuint tex = id;
00542             glDeleteTextures(1, &tex);
00543         }
00544 
00545         // 3D texture functions
00546         void (OSG_APIENTRY *TexImage3D)(GLenum target, 
00547                                         GLint level, 
00548                                         GLenum internalformat,
00549                                         GLsizei width, 
00550                                         GLsizei height, 
00551                                         GLsizei depth,
00552                                         GLint border, 
00553                                         GLenum format, 
00554                                         GLenum type,
00555                                         const GLvoid *pixels) =
00556             (void (OSG_APIENTRY*)(GLenum target, 
00557                                   GLint level, 
00558                                   GLenum internalformat,
00559                                   GLsizei width, 
00560                                   GLsizei height, 
00561                                   GLsizei depth,
00562                                   GLint border, 
00563                                   GLenum format, 
00564                                   GLenum type,
00565                                   const GLvoid *pixels))
00566             win->getFunction(_funcTexImage3D);
00567 
00568         void (OSG_APIENTRY*TexSubImage3D)
00569                           (GLenum target, GLint level, GLint xoffset,
00570                            GLint yoffset, GLint zoffset, GLsizei width,
00571                            GLsizei height, GLsizei depth, GLenum format,
00572                            GLenum type, const GLvoid *pixels) =
00573             (void (OSG_APIENTRY*)(GLenum target, GLint level, GLint xoffset,
00574                       GLint yoffset, GLint zoffset, GLsizei width,
00575                       GLsizei height, GLsizei depth, GLenum format,
00576                       GLenum type, const GLvoid *pixels))
00577             win->getFunction(_funcTexSubImage3D);
00578 
00579 
00580         // Compressed texture functions
00581         void (OSG_APIENTRY*CompressedTexImage1D)(GLenum target, 
00582                                                  GLint level, 
00583                                                  GLenum internalformat, 
00584                                                  GLsizei width, GLint border, 
00585                                                  GLsizei imageSize, 
00586                                                  const GLvoid *pixels) =
00587             (void (OSG_APIENTRY*)(GLenum target, 
00588                                   GLint level, 
00589                                   GLenum internalformat, 
00590                                   GLsizei width, 
00591                                   GLint border,  
00592                                   GLsizei imageSize, 
00593                                   const GLvoid *pixels))
00594             win->getFunction(_funcCompressedTexImage1D);
00595         
00596         void (OSG_APIENTRY*CompressedTexSubImage1D)(GLenum target, 
00597                                                     GLint level, 
00598                                                     GLint xoffset, 
00599                                                     GLsizei width,
00600                                                     GLenum format, 
00601                                                     GLsizei imageSize, 
00602                                                     const GLvoid *pixels) =
00603             (void (OSG_APIENTRY*)(GLenum target, 
00604                                   GLint level, 
00605                                   GLint xoffset, 
00606                                   GLsizei width,
00607                                   GLenum format, 
00608                                   GLsizei imageSize, 
00609                                   const GLvoid *pixels))
00610             win->getFunction(_funcCompressedTexSubImage1D);
00611         
00612         void (OSG_APIENTRY*CompressedTexImage2D)(GLenum target, 
00613                                                  GLint level, 
00614                                                  GLenum internalformat, 
00615                                                  GLsizei width, 
00616                                                  GLsizei height, 
00617                                                  GLint border, 
00618                                                  GLsizei imageSize, 
00619                                                  const GLvoid *pixels) =
00620             (void (OSG_APIENTRY*)(GLenum target, 
00621                                   GLint level, 
00622                                   GLenum internalformat, 
00623                                   GLsizei width, 
00624                                   GLsizei height, 
00625                                   GLint border, 
00626                                   GLsizei imageSize, 
00627                                   const GLvoid *pixels))
00628             win->getFunction(_funcCompressedTexImage2D);
00629         
00630         void (OSG_APIENTRY*CompressedTexSubImage2D)(GLenum target, 
00631                                                     GLint level, 
00632                                                     GLint xoffset, 
00633                                                     GLint yoffset, 
00634                                                     GLsizei width, 
00635                                                     GLsizei height, 
00636                                                     GLenum format,
00637                                                     GLsizei imageSize, 
00638                                                     const GLvoid *pixels) =
00639             (void (OSG_APIENTRY*)(GLenum target, 
00640                                   GLint level, 
00641                                   GLint xoffset, 
00642                                   GLint yoffset, 
00643                                   GLsizei width, 
00644                                   GLsizei height, 
00645                                   GLenum format,
00646                                   GLsizei imageSize, 
00647                                   const GLvoid *pixels))
00648             win->getFunction(_funcCompressedTexSubImage2D);
00649 
00650         void (OSG_APIENTRY*CompressedTexImage3D)(GLenum target, 
00651                                                  GLint level, 
00652                                                  GLenum internalformat,
00653                                                  GLsizei width, 
00654                                                  GLsizei height, 
00655                                                  GLsizei depth,
00656                                                  GLint border,
00657                                                  GLsizei imageSize, 
00658                                                  const GLvoid *pixels) =
00659             (void (OSG_APIENTRY*)(GLenum target, 
00660                                   GLint level, 
00661                                   GLenum internalformat,
00662                                   GLsizei width, 
00663                                   GLsizei height, 
00664                                   GLsizei depth,
00665                                   GLint border,
00666                                   GLsizei imageSize, 
00667                                   const GLvoid *pixels))
00668             win->getFunction(_funcCompressedTexImage3D);
00669         
00670         void (OSG_APIENTRY*CompressedTexSubImage3D)(GLenum target, 
00671                                                     GLint level, 
00672                                                     GLint xoffset, 
00673                                                     GLint yoffset, 
00674                                                     GLint zoffset, 
00675                                                     GLsizei width, 
00676                                                     GLsizei height, 
00677                                                     GLsizei depth, 
00678                                                     GLenum format, 
00679                                                     GLsizei imageSize, 
00680                                                     const GLvoid *pixels) =
00681             (void (OSG_APIENTRY*)(GLenum target, 
00682                                   GLint level, 
00683                                   GLint xoffset, 
00684                                   GLint yoffset, 
00685                                   GLint zoffset, 
00686                                   GLsizei width, 
00687                                   GLsizei height, 
00688                                   GLsizei depth, 
00689                                   GLenum format, 
00690                                   GLsizei imageSize, 
00691                                   const GLvoid *pixels))
00692             win->getFunction(_funcCompressedTexSubImage3D);
00693         
00694         // as we're not allocating anything here, the same code can be used
00695         // for reinitialization
00696         if(! img || ! img->getDimension()) // no image ?
00697             return;
00698 
00699         glErr("TextureChunk::initialize precheck");
00700 
00701         FDEBUG(("texture (re-)initialize\n"));
00702         
00703         glBindTexture(bindtarget, id);
00704 
00705         if(paramtarget != GL_NONE)
00706         {
00707             // set the parameters
00708             glTexParameterf(paramtarget, GL_TEXTURE_PRIORITY,   getPriority());
00709             glTexParameteri(paramtarget, GL_TEXTURE_MIN_FILTER, getMinFilter());
00710             glTexParameteri(paramtarget, GL_TEXTURE_MAG_FILTER, getMagFilter());
00711             glTexParameteri(paramtarget, GL_TEXTURE_WRAP_S, getWrapS());
00712 
00713             if(paramtarget == GL_TEXTURE_2D ||
00714                paramtarget == GL_TEXTURE_3D ||
00715                paramtarget == GL_TEXTURE_CUBE_MAP_ARB)
00716             {
00717                 glTexParameteri(paramtarget, GL_TEXTURE_WRAP_T, getWrapT());
00718             }
00719 
00720             if(paramtarget == GL_TEXTURE_3D ||
00721                paramtarget == GL_TEXTURE_CUBE_MAP_ARB)
00722             {
00723                 glTexParameteri(paramtarget, GL_TEXTURE_WRAP_R, getWrapR());
00724             }
00725 
00726              if(getAnisotropy() > 1.0f &&
00727                 win->hasExtension(_extTextureFilterAnisotropic))
00728              {
00729                 glTexParameterf(paramtarget, 
00730                                 GL_TEXTURE_MAX_ANISOTROPY_EXT, 
00731                                 getAnisotropy());
00732              }
00733 
00734              glTexParameterfv(paramtarget, 
00735                               GL_TEXTURE_BORDER_COLOR,
00736                               (GLfloat *) getBorderColor().getValuesRGBA());
00737 
00738              if(getCompareMode() != GL_NONE &&
00739                 win->hasExtension(_extShadow))
00740              {
00741                  glTexParameteri(paramtarget,
00742                                  GL_TEXTURE_COMPARE_MODE,
00743                                  getCompareMode());
00744                  glTexParameteri(paramtarget,
00745                                  GL_TEXTURE_COMPARE_FUNC,
00746                                  getCompareFunc());
00747              }
00748 
00749              if(getDepthMode() != GL_LUMINANCE &&
00750                 win->hasExtension(_extDepthTexture))
00751              {
00752                  glTexParameteri(paramtarget,
00753                                  GL_DEPTH_TEXTURE_MODE,
00754                                  getDepthMode());
00755              }
00756              
00757             glErr("TextureChunk::initialize params");
00758         }
00759 
00760         // set the image
00761         GLenum internalFormat = getInternalFormat();
00762         GLenum externalFormat = img->getPixelFormat();
00763         GLenum type           = img->getDataType();
00764         UInt32 width          = img->getWidth();
00765         UInt32 height         = img->getHeight();
00766         UInt32 depth          = img->getDepth();
00767         bool   compressedData = img->hasCompressedData();
00768 
00769         bool doScale = getScale(); // scale the texture to 2^?
00770         UInt32 frame = getFrame();
00771 
00772         bool defined = false;   // Texture defined ?
00773         bool needMipmaps =  getMinFilter() == GL_NEAREST_MIPMAP_NEAREST ||
00774                             getMinFilter() == GL_LINEAR_MIPMAP_NEAREST  ||
00775                             getMinFilter() == GL_NEAREST_MIPMAP_LINEAR  ||
00776                             getMinFilter() == GL_LINEAR_MIPMAP_LINEAR   ;
00777 
00778         if(internalFormat == GL_NONE)
00779         {
00780             switch(externalFormat)
00781             {
00782 #if defined(GL_BGR) && defined(GL_BGR_EXT)
00783                 case GL_BGR:
00784 #else
00785 #  if defined(GL_BGR)
00786                 case GL_BGR:
00787 #  endif
00788 #  if defined(GL_BGR_EXT)
00789                 case GL_BGR_EXT:
00790 #  endif
00791 #endif
00792 #if defined(GL_BGR) || defined(GL_BGR_EXT)
00793                     internalFormat = GL_RGB;
00794                     break;
00795 #endif
00796 #if defined(GL_BGRA) && defined(GL_BGRA_EXT)
00797                 case GL_BGRA:
00798 #else
00799 #  if defined(GL_BGRA)
00800                 case GL_BGRA:
00801 #  endif
00802 #  if defined(GL_BGRA_EXT)
00803                 case GL_BGRA_EXT:
00804 #  endif
00805 #endif
00806 #if defined(GL_BGRA) || defined(GL_BGRA_EXT)
00807                     internalFormat = GL_RGBA;
00808                     break;
00809 #endif
00810                 case GL_INTENSITY:
00811                     internalFormat = GL_INTENSITY;
00812                     externalFormat = GL_LUMINANCE;
00813                     break;
00814                     
00815                 default:    
00816                     internalFormat = externalFormat;
00817                     break;
00818             }
00819         }
00820 
00821         if(getExternalFormat() != GL_NONE)
00822             externalFormat = getExternalFormat();
00823         
00824         if(imgtarget == GL_TEXTURE_RECTANGLE_ARB && needMipmaps)
00825         {
00826             SWARNING << "TextureChunk::initialize1: Can't do mipmaps"
00827                      << "with GL_TEXTURE_RECTANGLE_ARB target! Ignored"
00828                      << std::endl;
00829             needMipmaps= false;
00830         }
00831         
00832         // do we need mipmaps?
00833         if(needMipmaps)
00834         {
00835             // do we have usable mipmaps ?
00836             if(img->getMipMapCount() == img->calcMipmapLevelCount() &&
00837                  osgIsPower2(width) && osgIsPower2(height) &&
00838                  osgIsPower2(depth)
00839               )
00840             {
00841                 for(UInt16 i = 0; i < img->getMipMapCount(); i++)
00842                 {
00843                     UInt32 w, h, d;
00844                     img->calcMipmapGeometry(i, w, h, d);
00845 
00846                     if(compressedData)
00847                     {
00848                         switch (imgtarget)
00849                         {
00850                         case GL_TEXTURE_1D:
00851                             CompressedTexImage1D(GL_TEXTURE_1D, i, internalFormat,
00852                                             w, getBorderWidth(),
00853                                             img->calcMipmapLevelSize(i),
00854                                             img->getData(i, frame, side));
00855                             break;
00856                         case GL_TEXTURE_2D:
00857                             CompressedTexImage2D(imgtarget, i, internalFormat,
00858                                             w, h, getBorderWidth(),
00859                                             img->calcMipmapLevelSize(i),
00860                                             img->getData(i, frame, side));
00861                             break;
00862                         case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
00863                         case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
00864                         case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
00865                         case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
00866                         case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
00867                         case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
00868                             CompressedTexImage2D(imgtarget, i, internalFormat,
00869                                             w, h, getBorderWidth(),
00870                                             img->calcMipmapLevelSize(i), 
00871                                             img->getData(i, frame, side));
00872                             break;
00873                         case GL_TEXTURE_3D:
00874                             CompressedTexImage3D(GL_TEXTURE_3D, i, internalFormat,
00875                                             w, h, d, getBorderWidth(),
00876                                             img->calcMipmapLevelSize(i),
00877                                             img->getData(i, frame, side));
00878                             break;
00879                        default:
00880                                 SFATAL << "TextureChunk::initialize1: unknown target "
00881                                        << imgtarget << "!!!" << std::endl;
00882                                 break;
00883                         }
00884                     }
00885                     else
00886                     {
00887                         switch (imgtarget)
00888                         {
00889                         case GL_TEXTURE_1D:
00890                             glTexImage1D(GL_TEXTURE_1D, i, internalFormat,
00891                                             w, getBorderWidth(),
00892                                             externalFormat, type,
00893                                             img->getData(i, frame, side));
00894                             break;
00895                         case GL_TEXTURE_2D:
00896                         case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
00897                         case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
00898                         case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
00899                         case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
00900                         case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
00901                         case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
00902                             glTexImage2D(imgtarget, i, internalFormat,
00903                                             w, h, getBorderWidth(),
00904                                             externalFormat, type,
00905                                             img->getData(i, frame, side));
00906                             break;
00907                         case GL_TEXTURE_3D:
00908                               TexImage3D(GL_TEXTURE_3D, i, internalFormat,
00909                                             w, h, d, getBorderWidth(),
00910                                             externalFormat, type,
00911                                             img->getData(i, frame, side));
00912                             break;
00913                        default:
00914                                 SFATAL << "TextureChunk::initialize1: unknown target "
00915                                        << imgtarget << "!!!" << std::endl;
00916                                 break;
00917                         }
00918                     }
00919                 }
00920                 defined = true;
00921             }
00922 
00923             if(! defined)
00924             {
00925                 // Nope, do we have SGIS_generate_mipmaps?
00926                 if(win->hasExtension(_sgisGenerateMipmap))
00927                 {
00928                     if(paramtarget != GL_NONE)
00929                         glTexParameteri(paramtarget, GL_GENERATE_MIPMAP_SGIS, GL_TRUE);
00930                     glErr("TextureChunk::activate generate_mipmaps");
00931                     needMipmaps = false; // automagic does it
00932                 }
00933                 else
00934                 {
00935                     // Nope, try to use gluBuild?DMipmaps
00936                     void *data = NULL;
00937 
00938                     // can we use it directly?
00939                     if(! osgIsPower2(width) ||
00940                          ! osgIsPower2(height) ||
00941                          ! osgIsPower2(depth)
00942                       )
00943                     {
00944                         // scale is only implemented for 2D
00945                         if(imgtarget != GL_TEXTURE_2D)
00946                         {
00947                             SWARNING << "TextureChunk::initialize: can't mipmap "
00948                                      << "non-2D textures that are not 2^x !!!"
00949                                      << std::endl;
00950                         }
00951                         else
00952                         {
00953                             UInt32 outw = osgNextPower2(width);
00954                             UInt32 outh = osgNextPower2(height);
00955 
00956                             data = malloc(outw * outh * img->getBpp());
00957 
00958                             // should we scale to next power of 2?
00959                             if(doScale)
00960                             {
00961                                 GLint res = gluScaleImage(externalFormat,
00962                                                 width, height, type, img->getData(0, frame, side),
00963                                                 outw, outh, type, data);
00964 
00965                                 if(res)
00966                                 {
00967                                     SWARNING << "TextureChunk::initialize: "
00968                                              << "gluScaleImage failed: "
00969                                              << gluErrorString(res) << "("
00970                                              << res << ")!"
00971                                              << std::endl;
00972                                     free(data);
00973                                     data = NULL;
00974                                 }
00975                                 else
00976                                 {
00977                                     width = outw;
00978                                     height = outh;
00979                                 }
00980                             }
00981                             else // nope, just copy the image to the lower left part
00982                             {
00983                                 memset(data, 0, outw * outh * img->getBpp());
00984 
00985                                 UInt16 bpl = width * img->getBpp();
00986                                 UInt8 * src = (UInt8 *) img->getData(0, frame, side);
00987                                 UInt8 * dest= (UInt8 *) data;
00988 
00989                                 for(UInt32 y = 0; y < height; y++)
00990                                 {
00991                                     memcpy(dest, src, bpl);
00992 
00993                                     src  += bpl;
00994                                     dest += outw * img->getBpp();
00995                                 }
00996                                 width = outw;
00997                                 height = outh;
00998                             }
00999                         }
01000                     }
01001                     else
01002                     {
01003                         data = const_cast<void *>(
01004                             static_cast<const void *>(img->getData(0, 
01005                                                                    frame,
01006                                                                    side)));
01007                     }
01008 
01009                     if(data)
01010                     {
01011                         switch (imgtarget)
01012                         {
01013                         case GL_TEXTURE_1D:
01014                                 gluBuild1DMipmaps(imgtarget, internalFormat, width,
01015                                                     externalFormat, type, data);
01016                                 break;
01017                         case GL_TEXTURE_2D:
01018                         case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
01019                         case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
01020                         case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
01021                         case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
01022                         case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
01023                         case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
01024                                 gluBuild2DMipmaps(imgtarget, internalFormat,
01025                                                     width, height,
01026                                                     externalFormat, type, data);
01027                                 break;
01028                         case GL_TEXTURE_3D:
01029 #  ifdef GLU_VERSION_1_3
01030                                 gluBuild3DMipmaps(imgtarget, internalFormat,
01031                                                     width, height, depth,