Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

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