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