# Home    # nevrax.com   
Nevrax
Nevrax.org
#News
#Mailing-list
#Documentation
#CVS
#Bugs
#License
Docs
 
Documentation  
Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages   Search  

driver_opengl_texture.cpp

Go to the documentation of this file.
00001 
00011 /* Copyright, 2000 Nevrax Ltd.
00012  *
00013  * This file is part of NEVRAX NEL.
00014  * NEVRAX NEL is free software; you can redistribute it and/or modify
00015  * it under the terms of the GNU General Public License as published by
00016  * the Free Software Foundation; either version 2, or (at your option)
00017  * any later version.
00018 
00019  * NEVRAX NEL 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  * General Public License for more details.
00023 
00024  * You should have received a copy of the GNU General Public License
00025  * along with NEVRAX NEL; see the file COPYING. If not, write to the
00026  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00027  * MA 02111-1307, USA.
00028  */
00029 
00030 #include "stdopengl.h"
00031 
00032 #include "3d/texture_cube.h"
00033 #include "nel/misc/rect.h"
00034 #include "nel/misc/file.h" // temp
00035 
00036 
00037 using   namespace NLMISC;
00038 using   namespace std;
00039 
00040 
00041 namespace NL3D
00042 {
00043 
00044 
00045 // ***************************************************************************
00046 CTextureDrvInfosGL::CTextureDrvInfosGL(IDriver *drv, ItTexDrvInfoPtrMap it, CDriverGL *drvGl) : ITextureDrvInfos(drv, it)
00047 {
00048         // The id is auto created here.
00049         glGenTextures(1,&ID);
00050         
00051         Compressed= false;
00052         TextureMemory= 0;
00053 
00054         // Nb: at Driver dtor, all tex infos are deleted, so _Driver is always valid.
00055         _Driver= drvGl;
00056 }
00057 // ***************************************************************************
00058 CTextureDrvInfosGL::~CTextureDrvInfosGL()
00059 {
00060         // The id is auto deleted here.
00061         glDeleteTextures(1,&ID);
00062 
00063         // release profiling texture mem.
00064         _Driver->_AllocatedTextureMemory-= TextureMemory;
00065 
00066         // release in TextureUsed.
00067         _Driver->_TextureUsed.erase (this);
00068 }
00069 
00070 
00071 
00072 // ***************************************************************************
00073 // Get the glText mirror of an existing setuped texture.
00074 static  inline CTextureDrvInfosGL*      getTextureGl(ITexture& tex)
00075 {
00076         CTextureDrvInfosGL*     gltex;
00077         gltex= (CTextureDrvInfosGL*)(ITextureDrvInfos*)(tex.TextureDrvShare->DrvTexture);
00078         return gltex;
00079 }
00080 
00081 
00082 // ***************************************************************************
00083 // Translation of TexFmt mode.
00084 GLint   CDriverGL::getGlTextureFormat(ITexture& tex, bool &compressed)
00085 {
00086         ITexture::TUploadFormat         texfmt= tex.getUploadFormat();
00087 
00088         // If auto, retrieve the pixel format of the bitmap.
00089         if(texfmt== ITexture::Auto)
00090         {
00091                 switch(tex.getPixelFormat())
00092                 {
00093                         case CBitmap::RGBA: 
00094                                 if(_ForceDXTCCompression && tex.allowDegradation() )
00095                                         texfmt= ITexture::DXTC5;
00096                                 else
00097                                         texfmt= ITexture::RGBA8888;
00098                                 break;
00099                         case CBitmap::DXTC1: texfmt= ITexture::DXTC1; break;
00100                         case CBitmap::DXTC1Alpha: texfmt= ITexture::DXTC1Alpha; break;
00101                         case CBitmap::DXTC3: texfmt= ITexture::DXTC3; break;
00102                         case CBitmap::DXTC5: texfmt= ITexture::DXTC5; break;
00103                         case CBitmap::Luminance: texfmt= ITexture::Luminance; break;
00104                         case CBitmap::Alpha: texfmt= ITexture::Alpha; break;
00105                         case CBitmap::AlphaLuminance: texfmt= ITexture::AlphaLuminance; break;
00106                         case CBitmap::DsDt: texfmt= ITexture::DsDt; break;
00107                         default: texfmt= ITexture::RGBA8888; break;
00108                 }
00109         }
00110 
00111 
00112         // Get gl tex format, try S3TC compressed ones.
00113         if(_Extensions.EXTTextureCompressionS3TC)
00114         {
00115                 compressed= true;
00116                 // Try Compressed ones.
00117                 switch(texfmt)
00118                 {
00119                         case ITexture::DXTC1:           return GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
00120                         case ITexture::DXTC1Alpha:      return GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
00121                         case ITexture::DXTC3:           return GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
00122                         case ITexture::DXTC5:           return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
00123                         default: break;
00124                 }
00125         }
00126 
00127 
00128         // Get standard gl tex format.
00129         compressed= false;
00130         switch(texfmt)
00131         {
00132                 case ITexture::RGBA8888: return GL_RGBA8;
00133                 case ITexture::RGBA4444: return GL_RGBA4;
00134                 case ITexture::RGBA5551: return GL_RGB5_A1;
00135                 case ITexture::RGB888: return GL_RGB8;
00136                 case ITexture::RGB565: return GL_RGB5;
00137                 case ITexture::Luminance: return GL_LUMINANCE8;
00138                 case ITexture::Alpha: return GL_ALPHA8;
00139                 case ITexture::AlphaLuminance: return GL_LUMINANCE8_ALPHA8;
00140                 case ITexture::DsDt: 
00141                         if (_Extensions.NVTextureShader) return GL_DSDT_NV;
00142                         else if (_Extensions.ATIEnvMapBumpMap) return GL_DU8DV8_ATI;
00143                         else
00144                         {                       
00145                                 nlassert(0);
00146                                 return 0;
00147                         }
00148                 break;
00149                 default: return GL_RGBA8;
00150         }
00151 }
00152 
00153 
00154 // ***************************************************************************
00155 static GLint    getGlSrcTextureFormat(ITexture &tex, GLint glfmt)
00156 {
00157         // Is destination format is alpha or lumiance ?
00158         if ((glfmt==GL_ALPHA8)||(glfmt==GL_LUMINANCE8_ALPHA8)||(glfmt==GL_LUMINANCE8))
00159         {
00160                 switch(tex.getPixelFormat())
00161                 {
00162                 case CBitmap::Alpha:    return GL_ALPHA;
00163                 case CBitmap::AlphaLuminance:   return GL_LUMINANCE_ALPHA;
00164                 case CBitmap::Luminance:        return GL_LUMINANCE;
00165                 default: break;
00166                 }
00167         }
00168 
00169         if (glfmt == GL_DSDT_NV)
00170         {
00171                 return GL_DSDT_NV;
00172         }
00173 
00174         if (glfmt == GL_DU8DV8_ATI)
00175         {
00176                 return GL_DUDV_ATI;
00177         }
00178 
00179         // Else, not a Src format for upload, or RGBA.
00180         return GL_RGBA;
00181 }
00182 
00183 // ***************************************************************************
00184 static GLenum getGlSrcTextureComponentType(GLint texSrcFormat)
00185 {
00186         switch (texSrcFormat)
00187         {
00188                 case GL_DSDT_NV:
00189                 case GL_DU8DV8_ATI:
00190                         return GL_BYTE; // these are signed format                      
00191                 break;          
00192                 default:
00193                         return GL_UNSIGNED_BYTE;
00194                 break;
00195 
00196         }
00197 }
00198 
00199 // ***************************************************************************
00200 uint                            CDriverGL::computeMipMapMemoryUsage(uint w, uint h, GLint glfmt) const
00201 {
00202         switch(glfmt)
00203         {
00204         case GL_RGBA8:          return w*h* 4;
00205         // Well this is ugly, but simple :). GeForce 888 is stored as 32 bits.
00206         case GL_RGB8:           return w*h* 4;
00207         case GL_RGBA4:          return w*h* 2;
00208         case GL_RGB5_A1:        return w*h* 2;
00209         case GL_RGB5:           return w*h* 2;
00210         case GL_LUMINANCE8:     return w*h* 1;
00211         case GL_ALPHA8:         return w*h* 1;
00212         case GL_LUMINANCE8_ALPHA8:      return w*h* 2;
00213         case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:   return w*h /2;
00214         case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:  return w*h /2;
00215         case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:  return w*h* 1;
00216         case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:  return w*h* 1;
00217         case GL_DU8DV8_ATI:
00218         case GL_DSDT_NV:                                                return w*h* 2;
00219         };
00220 
00221         // One format has not been coded.
00222         nlstop;
00223 
00225         return w*h* 4;
00226 }
00227 
00228 
00229 // ***************************************************************************
00230 // Translation of Wrap mode.
00231 static inline GLenum    translateWrapToGl(ITexture::TWrapMode mode, const CGlExtensions &extensions)
00232 {
00233         if(mode== ITexture::Repeat)
00234                 return GL_REPEAT;
00235         else
00236         {
00237                 if(extensions.Version1_2)
00238                         return GL_CLAMP_TO_EDGE;
00239                 else
00240                         return GL_CLAMP;
00241         }
00242 }
00243 
00244 
00245 // ***************************************************************************
00246 static inline GLenum    translateMagFilterToGl(ITexture::TMagFilter mode)
00247 {       
00248         switch(mode)
00249         {
00250                 case ITexture::Linear: return GL_LINEAR;
00251                 case ITexture::Nearest: return GL_NEAREST;
00252                 default: break;
00253         }
00254 
00255         nlstop;
00256         return GL_LINEAR;
00257 }
00258 
00259 
00260 // ***************************************************************************
00261 static inline GLenum    translateMinFilterToGl(ITexture::TMinFilter mode)
00262 {
00263         switch(mode)
00264         {
00265                 case ITexture::NearestMipMapOff: return GL_NEAREST;
00266                 case ITexture::NearestMipMapNearest: return GL_NEAREST_MIPMAP_NEAREST;
00267                 case ITexture::NearestMipMapLinear: return GL_NEAREST_MIPMAP_LINEAR;
00268                 case ITexture::LinearMipMapOff: return GL_LINEAR;
00269                 case ITexture::LinearMipMapNearest: return GL_LINEAR_MIPMAP_NEAREST;
00270                 case ITexture::LinearMipMapLinear: return GL_LINEAR_MIPMAP_LINEAR;
00271                 default: break;
00272         }
00273 
00274         nlstop;
00275         return GL_LINEAR;
00276 }
00277 
00278 
00279 // ***************************************************************************
00280 static inline bool              sameDXTCFormat(ITexture &tex, GLint glfmt)
00281 {
00282         if(glfmt==GL_COMPRESSED_RGB_S3TC_DXT1_EXT && tex.PixelFormat==CBitmap::DXTC1)
00283                 return true;
00284         if(glfmt==GL_COMPRESSED_RGBA_S3TC_DXT1_EXT && tex.PixelFormat==CBitmap::DXTC1Alpha)
00285                 return true;
00286         if(glfmt==GL_COMPRESSED_RGBA_S3TC_DXT3_EXT && tex.PixelFormat==CBitmap::DXTC3)
00287                 return true;
00288         if(glfmt==GL_COMPRESSED_RGBA_S3TC_DXT5_EXT && tex.PixelFormat==CBitmap::DXTC5)
00289                 return true;
00290 
00291         return false;
00292 }
00293 
00294 
00295 // ***************************************************************************
00296 static inline bool              isDXTCFormat(GLint glfmt)
00297 {
00298         if(glfmt==GL_COMPRESSED_RGB_S3TC_DXT1_EXT)
00299                 return true;
00300         if(glfmt==GL_COMPRESSED_RGBA_S3TC_DXT1_EXT)
00301                 return true;
00302         if(glfmt==GL_COMPRESSED_RGBA_S3TC_DXT3_EXT)
00303                 return true;
00304         if(glfmt==GL_COMPRESSED_RGBA_S3TC_DXT5_EXT)
00305                 return true;
00306 
00307         return false;
00308 }
00309 
00310 
00311 // ***************************************************************************
00312 bool CDriverGL::setupTexture (ITexture& tex)
00313 {
00314         bool nTmp;
00315         return setupTextureEx (tex, true, nTmp);
00316 }
00317 
00318 // ***************************************************************************
00319 bool CDriverGL::setupTextureEx (ITexture& tex, bool bUpload, bool &bAllUploaded, bool bMustRecreateSharedTexture)
00320 {
00321         bAllUploaded = false;
00322         
00323         if(tex.isTextureCube() && (!_Extensions.ARBTextureCubeMap))
00324                 return true;
00325 
00326         // 0. Create/Retrieve the driver texture.
00327         //=======================================
00328         bool mustCreate = false;
00329         if ( !tex.TextureDrvShare )
00330         {
00331                 // insert into driver list. (so it is deleted when driver is deleted).
00332                 ItTexDrvSharePtrList    it= _TexDrvShares.insert(_TexDrvShares.end());
00333                 // create and set iterator, for future deletion.
00334                 *it= tex.TextureDrvShare= new CTextureDrvShare(this, it);
00335 
00336                 // Must (re)-create the texture.
00337                 mustCreate = true;
00338         }
00339 
00340         if ( (!tex.touched()) && (!mustCreate) )
00341                 return true; // Do not do anything
00342 
00343 
00344         // 1. If modified, may (re)load texture part or all of the texture.
00345         //=================================================================
00346 
00347 
00348         bool    mustLoadAll= false;
00349         bool    mustLoadPart= false;
00350 
00351 
00352         // To avoid any delete/new ptr problem, disable all texturing.
00353         /* If an old texture is deleted, _CurrentTexture[*] and _CurrentTextureInfoGL[*] are invalid. 
00354                 But this is grave only if a new texture is created, with the same pointer (bad luck). 
00355                 Since an newly allocated texture always pass here before use, we are sure to avoid any problems.
00356         */
00357         for(sint stage=0 ; stage<inlGetNumTextStages() ; stage++)
00358         {
00359                 activateTexture(stage, NULL);
00360         }
00361 
00362 
00363         // A. Share mgt.
00364         //==============
00365         if(tex.supportSharing())
00366         {
00367                 // Try to get the shared texture.
00368 
00369                 // Create the shared Name.
00370                 std::string     name;
00371                 getTextureShareName (tex, name);
00372 
00373                 // insert or get the texture.
00374                 {
00375                         CSynchronized<TTexDrvInfoPtrMap>::CAccessor access(&_SyncTexDrvInfos);
00376                         TTexDrvInfoPtrMap &rTexDrvInfos = access.value();
00377 
00378                         ItTexDrvInfoPtrMap      itTex;
00379                         itTex= rTexDrvInfos.find(name);
00380 
00381                         // texture not found?
00382                         if( itTex==rTexDrvInfos.end() )
00383                         {
00384                                 // insert into driver map. (so it is deleted when driver is deleted).
00385                                 itTex= (rTexDrvInfos.insert(make_pair(name, (ITextureDrvInfos*)NULL))).first;
00386                                 // create and set iterator, for future deletion.
00387                                 itTex->second= tex.TextureDrvShare->DrvTexture= new CTextureDrvInfosGL(this, itTex, this);
00388 
00389                                 // need to load ALL this texture.
00390                                 mustLoadAll= true;
00391                         }
00392                         else
00393                         {
00394                                 tex.TextureDrvShare->DrvTexture= itTex->second;
00395 
00396                                 if(bMustRecreateSharedTexture)
00397                                         // reload this shared texture (user request)
00398                                         mustLoadAll= true;
00399                                 else
00400                                         // Do not need to reload this texture, even if the format/mipmap has changed, since we found this 
00401                                         // couple in the map.
00402                                         mustLoadAll= false;
00403                         }
00404                 }
00405                 // Do not test if part of texture may need to be computed, because Rect invalidation is incompatible 
00406                 // with texture sharing.
00407         }
00408         else
00409         {
00410                 // If texture not already created.
00411                 if(!tex.TextureDrvShare->DrvTexture)
00412                 {
00413                         // Must create it. Create auto a GL id (in constructor).
00414                         // Do not insert into the map. This un-shared texture will be deleted at deletion of the texture.
00415                         // Inform ITextureDrvInfos by passing NULL _Driver.
00416                         tex.TextureDrvShare->DrvTexture= new CTextureDrvInfosGL(NULL, ItTexDrvInfoPtrMap(), this);
00417 
00418                         // need to load ALL this texture.
00419                         mustLoadAll= true;
00420                 }
00421                 else if(tex.isAllInvalidated())
00422                         mustLoadAll= true;
00423                 else if(tex.touched())
00424                         mustLoadPart= true;
00425         }
00426 
00427         // B. Setup texture.
00428         //==================
00429         if(mustLoadAll || mustLoadPart)
00430         {
00431                 CTextureDrvInfosGL*     gltext;
00432                 gltext= getTextureGl(tex);
00433 
00434                 // system of "backup the previous binded texture" seems to not work with some drivers....
00435                 _DriverGLStates.activeTextureARB(0);
00436                 if(tex.isTextureCube())
00437                 {
00438                         _DriverGLStates.setTextureMode(CDriverGLStates::TextureCubeMap);
00439                         // Bind this texture, for reload...
00440                         glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, gltext->ID);                             
00441                 }
00442                 else
00443                 {
00444                         _DriverGLStates.setTextureMode(CDriverGLStates::Texture2D);
00445                         // Bind this texture, for reload...
00446                         glBindTexture(GL_TEXTURE_2D, gltext->ID);                               
00447                 }
00448 
00449 
00450                 glPixelStorei(GL_UNPACK_ALIGNMENT,1);
00451 
00452                 // a. Load All the texture case.
00453                 //==============================
00454                 if (mustLoadAll)
00455                 {
00456                         // profiling. sub old textre memory usage, and reset.
00457                         _AllocatedTextureMemory-= gltext->TextureMemory;
00458                         gltext->TextureMemory= 0;
00459 
00460 
00461                         if(tex.isTextureCube())
00462                         {
00463                                 static GLenum face_map[6] = {   GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB,
00464                                                                                                 GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB,
00465                                                                                                 GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB,
00466                                                                                                 GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB,
00467                                                                                                 GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB,
00468                                                                                                 GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB };
00469                                 CTextureCube *pTC = NLMISC::safe_cast<CTextureCube *>(&tex);
00470                                 // Regenerate all the texture.
00471                                 tex.generate();                                 
00472                                 for(uint nText = 0; nText < 6; ++nText)
00473                                 if(pTC->getTexture((CTextureCube::TFace)nText) != NULL)
00474                                 {
00475                                         ITexture *pTInTC = pTC->getTexture((CTextureCube::TFace)nText);
00476                                         // Get the correct texture format from texture...
00477                                         GLint   glfmt= getGlTextureFormat(*pTInTC, gltext->Compressed);
00478                                         GLint   glSrcFmt= getGlSrcTextureFormat(*pTInTC, glfmt);
00479                                         GLenum  glSrcType= getGlSrcTextureComponentType(glSrcFmt);
00480 
00481                                         sint    nMipMaps;
00482                                         if(glSrcFmt==GL_RGBA && pTInTC->getPixelFormat()!=CBitmap::RGBA )
00483                                                 pTInTC->convertToType(CBitmap::RGBA);
00484                                         if(tex.mipMapOn())
00485                                         {
00486                                                 pTInTC->buildMipMaps();
00487                                                 nMipMaps= pTInTC->getMipMapCount();
00488                                         }
00489                                         else
00490                                                 nMipMaps= 1;
00491 
00492                                         // Fill mipmaps.
00493                                         for(sint i=0;i<nMipMaps;i++)
00494                                         {
00495                                                 void    *ptr= &(*pTInTC->getPixels(i).begin());
00496                                                 uint    w= pTInTC->getWidth(i);
00497                                                 uint    h= pTInTC->getHeight(i);
00498                                                 if (bUpload)
00499                                                 {
00500                                                         glTexImage2D (face_map[nText], i, glfmt, w, h, 0, glSrcFmt, glSrcType, ptr);
00501                                                         bAllUploaded = true;
00502                                                 }
00503                                                 else
00504                                                 {
00505                                                         glTexImage2D (face_map[nText], i, glfmt, w, h, 0, glSrcFmt, glSrcType, NULL);
00506                                                 }
00507                                                 // profiling: count TextureMemory usage.
00508                                                 gltext->TextureMemory+= computeMipMapMemoryUsage(w, h, glfmt);
00509                                         }
00510                                 }
00511                         }
00512                         else
00513                         {
00514                                 // Regenerate all the texture.
00515                                 tex.generate();
00516 
00517                                 if(tex.getSize()>0)
00518                                 {
00519                                         // Get the correct texture format from texture...
00520                                         GLint   glfmt= getGlTextureFormat(tex, gltext->Compressed);
00521                                         GLint   glSrcFmt= getGlSrcTextureFormat(tex, glfmt);
00522                                         GLenum  glSrcType= getGlSrcTextureComponentType(glSrcFmt);
00523 
00524                                         // DXTC: if same format, and same mipmapOn/Off, use glTexCompressedImage*.
00525                                         // We cannot build the mipmaps if they are not here.
00526                                         if(_Extensions.EXTTextureCompressionS3TC && sameDXTCFormat(tex, glfmt) &&
00527                                                 (tex.mipMapOff() || tex.getMipMapCount()>1) )
00528                                         {
00529                                                 sint    nMipMaps;
00530                                                 if(tex.mipMapOn())
00531                                                         nMipMaps= tex.getMipMapCount();
00532                                                 else
00533                                                         nMipMaps= 1;
00534 
00535                                                 // Degradation in Size allowed only if DXTC texture are provided with mipmaps.
00536                                                 // Because use them to resize !!!
00537                                                 uint    decalMipMapResize= 0;
00538                                                 if(_ForceTextureResizePower>0 && tex.allowDegradation() && nMipMaps>1)
00539                                                 {
00540                                                         decalMipMapResize= min(_ForceTextureResizePower, (uint)(nMipMaps-1));
00541                                                 }
00542 
00543                                                 // Fill mipmaps.
00544                                                 for(sint i=decalMipMapResize;i<nMipMaps;i++)
00545                                                 {
00546                                                         void    *ptr= &(*tex.getPixels(i).begin());
00547                                                         sint    size= tex.getPixels(i).size();
00548                                                         if (bUpload)
00549                                                         {
00550                                                                 nglCompressedTexImage2DARB (GL_TEXTURE_2D, i-decalMipMapResize, glfmt, 
00551                                                                                                                         tex.getWidth(i),tex.getHeight(i), 0, size, ptr);
00552                                                                 bAllUploaded = true;
00553                                                         }
00554                                                         else
00555                                                         {
00556                                                                 //nglCompressedTexImage2DARB (GL_TEXTURE_2D, i-decalMipMapResize, glfmt, 
00557                                                                 //                                                      tex.getWidth(i),tex.getHeight(i), 0, size, NULL);
00558                                                                 glTexImage2D (GL_TEXTURE_2D, i-decalMipMapResize, glfmt, tex.getWidth(i), tex.getHeight(i), 
00559                                                                                                 0, glSrcFmt, glSrcType, NULL);
00560                                                         }
00561 
00562                                                         // profiling: count TextureMemory usage.
00563                                                         gltext->TextureMemory+= tex.getPixels(i).size();
00564                                                 }
00565                                         }
00566                                         else
00567                                         {
00568                                                 sint    nMipMaps;
00569                                                 if(glSrcFmt==GL_RGBA && tex.getPixelFormat()!=CBitmap::RGBA )
00570                                                 {
00571                                                         bUpload = true; // Force all upload
00572                                                         tex.convertToType(CBitmap::RGBA);
00573                                                 }
00574 
00575                                                 // Degradation in Size.
00576                                                 if(_ForceTextureResizePower>0 && tex.allowDegradation())
00577                                                 {
00578                                                         uint    w= tex.getWidth(0) >> _ForceTextureResizePower;
00579                                                         uint    h= tex.getHeight(0) >> _ForceTextureResizePower;
00580                                                         w= max(1U, w);
00581                                                         h= max(1U, h);
00582                                                         tex.resample(w, h);
00583                                                 }
00584 
00585                                                 if(tex.mipMapOn())
00586                                                 {
00587                                                         tex.buildMipMaps();
00588                                                         nMipMaps= tex.getMipMapCount();
00589                                                 }
00590                                                 else
00591                                                         nMipMaps= 1;
00592 
00593                                                 // Fill mipmaps.
00594                                                 for(sint i=0;i<nMipMaps;i++)
00595                                                 {
00596                                                         void    *ptr= &(*tex.getPixels(i).begin());
00597                                                         uint    w= tex.getWidth(i);
00598                                                         uint    h= tex.getHeight(i);
00599 
00600                                                         if (bUpload)
00601                                                         {                                                                                                                               
00602                                                                 glTexImage2D (GL_TEXTURE_2D, i, glfmt, w, h, 0,glSrcFmt, glSrcType, ptr);
00603                                                                 bAllUploaded = true;
00604                                                         }
00605                                                         else
00606                                                         {                                                               
00607                                                                 glTexImage2D (GL_TEXTURE_2D, i, glfmt, w, h, 0,glSrcFmt, glSrcType, NULL);                                                              
00608                                                         }
00609                                                         // profiling: count TextureMemory usage.
00610                                                         gltext->TextureMemory += computeMipMapMemoryUsage (w, h, glfmt);
00611                                                 }
00612                                         }
00613                                 }
00614                         }
00615                         //printf("%d,%d,%d\n", tex.getMipMapCount(), tex.getWidth(0), tex.getHeight(0));
00616 
00617 
00618                         // profiling. add new TextureMemory usage.
00619                         _AllocatedTextureMemory+= gltext->TextureMemory;
00620                 }
00621                 // b. Load part of the texture case.
00622                 //==================================
00623                 // \todo yoyo: TODO_DXTC
00624                 // Replace parts of a compressed image. Maybe don't work with the actual system of invalidateRect()...
00625                 else if (mustLoadPart && !gltext->Compressed)
00626                 {
00627                         // Regenerate wanted part of the texture.
00628                         tex.generate();
00629 
00630                         if(tex.getSize()>0)
00631                         {
00632                                 // Get the correct texture format from texture...
00633                                 //===============================================
00634                                 bool    dummy;
00635                                 GLint   glfmt= getGlTextureFormat(tex, dummy);
00636                                 GLint   glSrcFmt= getGlSrcTextureFormat(tex, glfmt);
00637                                 GLenum  glSrcType= getGlSrcTextureComponentType(glSrcFmt);
00638 
00639                                 sint    nMipMaps;
00640                                 if(glSrcFmt==GL_RGBA && tex.getPixelFormat()!=CBitmap::RGBA )
00641                                         tex.convertToType(CBitmap::RGBA);
00642                                 if(tex.mipMapOn())
00643                                 {
00644                                         bool    hadMipMap= tex.getMipMapCount()>1;
00645                                         tex.buildMipMaps();
00646                                         nMipMaps= tex.getMipMapCount();
00647                                         // If the texture had no mipmap before, release them.
00648                                         if(!hadMipMap)
00649                                         {
00650                                                 tex.releaseMipMaps();
00651                                         }
00652                                 }
00653                                 else
00654                                         nMipMaps= 1;
00655 
00656                                 // For all rect, update the texture/mipmap.
00657                                 //===============================================
00658                                 list<NLMISC::CRect>::iterator   itRect;
00659                                 for(itRect=tex._ListInvalidRect.begin(); itRect!=tex._ListInvalidRect.end(); itRect++)
00660                                 {
00661                                         CRect   &rect= *itRect;
00662                                         sint    x0= rect.X;
00663                                         sint    y0= rect.Y;
00664                                         sint    x1= rect.X+rect.Width;
00665                                         sint    y1= rect.Y+rect.Height;
00666 
00667                                         // Fill mipmaps.
00668                                         for(sint i=0;i<nMipMaps;i++)
00669                                         {
00670                                                 void    *ptr= &(*tex.getPixels(i).begin());
00671                                                 sint    w= tex.getWidth(i);
00672                                                 sint    h= tex.getHeight(i);
00673                                                 clamp(x0, 0, w);
00674                                                 clamp(y0, 0, h);
00675                                                 clamp(x1, x0, w);
00676                                                 clamp(y1, y0, h);
00677 
00678                                                 glPixelStorei(GL_UNPACK_ROW_LENGTH, w);
00679                                                 glPixelStorei(GL_UNPACK_SKIP_ROWS, y0);
00680                                                 glPixelStorei(GL_UNPACK_SKIP_PIXELS, x0);
00681                                                 if (bUpload)
00682                                                         glTexSubImage2D (GL_TEXTURE_2D, i, x0, y0, x1-x0, y1-y0, glSrcFmt,glSrcType, ptr);
00683                                                 else
00684                                                         glTexSubImage2D (GL_TEXTURE_2D, i, x0, y0, x1-x0, y1-y0, glSrcFmt,glSrcType, NULL);
00685 
00686                                                 // Next mipmap!!
00687                                                 // floor .
00688                                                 x0= x0/2;
00689                                                 y0= y0/2;
00690                                                 // ceil.
00691                                                 x1= (x1+1)/2;
00692                                                 y1= (y1+1)/2;
00693                                         }
00694                                 }
00695 
00696                                 // Reset the transfer mode...
00697                                 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
00698                                 glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
00699                                 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
00700                         }
00701                 }
00702 
00703 
00704                 // Release, if wanted.
00705                 if(tex.getReleasable())
00706                         tex.release();
00707 
00708                 // Basic parameters.
00709                 //==================
00710                 gltext->WrapS= tex.getWrapS();
00711                 gltext->WrapT= tex.getWrapT();
00712                 gltext->MagFilter= tex.getMagFilter();
00713                 gltext->MinFilter= tex.getMinFilter();
00714                 if(tex.isTextureCube())
00715                 {
00716                         glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB,GL_TEXTURE_WRAP_S, translateWrapToGl(ITexture::Clamp, _Extensions));
00717                         glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB,GL_TEXTURE_WRAP_T, translateWrapToGl(ITexture::Clamp, _Extensions));
00718                         glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB,GL_TEXTURE_WRAP_R, translateWrapToGl(ITexture::Clamp, _Extensions));
00719                         glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB,GL_TEXTURE_MAG_FILTER, translateMagFilterToGl(gltext->MagFilter));
00720                         glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB,GL_TEXTURE_MIN_FILTER, translateMinFilterToGl(gltext->MinFilter));
00721                 }
00722                 else
00723                 {
00724                         glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S, translateWrapToGl(gltext->WrapS, _Extensions));
00725                         glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T, translateWrapToGl(gltext->WrapT, _Extensions));
00726                         glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, translateMagFilterToGl(gltext->MagFilter));
00727                         glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, translateMinFilterToGl(gltext->MinFilter));
00728                 }
00729 
00730 
00731 
00732                 // Disable texture 0
00733                 _CurrentTexture[0]= NULL;
00734                 _CurrentTextureInfoGL[0]= NULL;
00735                 _DriverGLStates.setTextureMode(CDriverGLStates::TextureDisabled);
00736         }
00737 
00738 
00739         // The texture is correctly setuped.
00740         tex.clearTouched();
00741         return true;
00742 }
00743 
00744 
00745 // ***************************************************************************
00746 bool CDriverGL::uploadTexture (ITexture& tex, CRect& rect, uint8 nNumMipMap)
00747 {
00748         if (tex.TextureDrvShare == NULL)
00749                 return false; // Texture not created
00750         if (tex.TextureDrvShare->DrvTexture == NULL)
00751                 return false; // Texture not created
00752         if (tex.isTextureCube())
00753                 return false;
00754 
00755         nlassert(nNumMipMap<(uint8)tex.getMipMapCount());
00756 
00757         // validate rect.
00758         sint x0 = rect.X;
00759         sint y0 = rect.Y;
00760         sint x1 = rect.X+rect.Width;
00761         sint y1 = rect.Y+rect.Height;
00762         sint w = tex.getWidth (nNumMipMap);
00763         sint h = tex.getHeight (nNumMipMap);
00764         clamp (x0, 0, w);
00765         clamp (y0, 0, h);
00766         clamp (x1, x0, w);
00767         clamp (y1, y0, h);
00768 
00769         // bind the texture to upload 
00770         CTextureDrvInfosGL*     gltext;
00771         gltext = getTextureGl (tex);
00772 
00773         // system of "backup the previous binded texture" seems to not work with some drivers....
00774         _DriverGLStates.activeTextureARB (0);
00775         _DriverGLStates.setTextureMode (CDriverGLStates::Texture2D);
00776         // Bind this texture, for reload...
00777         glBindTexture (GL_TEXTURE_2D, gltext->ID);
00778 
00779         glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
00780 
00781         bool dummy;
00782         GLint glfmt = getGlTextureFormat (tex, dummy);
00783         GLint glSrcFmt = getGlSrcTextureFormat (tex, glfmt);
00784         GLenum  glSrcType= getGlSrcTextureComponentType(glSrcFmt);
00785         // If DXTC format
00786         //if (isDXTCFormat(glfmt))
00787         if (_Extensions.EXTTextureCompressionS3TC && sameDXTCFormat(tex, glfmt) &&
00788                         (tex.mipMapOff() || tex.getMipMapCount()>1) )
00789         {
00790                 nlassert (_Extensions.EXTTextureCompressionS3TC && sameDXTCFormat(tex, glfmt) &&
00791                                         (tex.mipMapOff() || tex.getMipMapCount()>1) );
00792 
00793                 sint nUploadMipMaps;
00794                 if (tex.mipMapOn())
00795                         nUploadMipMaps = tex.getMipMapCount();
00796                 else
00797                         nUploadMipMaps = 1;
00798 
00799                 uint decalMipMapResize = 0;
00800                 if (_ForceTextureResizePower>0 && tex.allowDegradation() && nUploadMipMaps>1)
00801                 {
00802                         decalMipMapResize = min(_ForceTextureResizePower, (uint)(nUploadMipMaps-1));
00803                 }
00804 
00805                 // Compute src compressed size and location
00806                 sint imageSize = (x1-x0)*(y1-y0);
00807                 void *ptr = &(*tex.getPixels(nNumMipMap).begin());
00808 
00809                 // If DXTC1 or DXTC1A, then 4 bits/texel else 8 bits/texel
00810                 if (glfmt == GL_COMPRESSED_RGB_S3TC_DXT1_EXT || glfmt == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT)
00811                 {
00812                         imageSize /= 2;
00813                         ptr = (uint8*)ptr + y0*w/2 + x0/2;
00814                 }
00815                 else
00816                 {
00817                         ptr = (uint8*)ptr + y0*w + x0;
00818                 }
00819 
00820                 // Upload
00821 
00822                 if (decalMipMapResize > nNumMipMap)
00823                 {
00824                         _CurrentTexture[0]= NULL;
00825                         _CurrentTextureInfoGL[0]= NULL;
00826                         _DriverGLStates.setTextureMode (CDriverGLStates::TextureDisabled);
00827                         return false;
00828                 }
00829                         
00830 
00831                 nlassert (((x0&3) == 0) && ((y0&3) == 0));
00832                 if ((w>=4) && (h>=4))
00833                 {
00834                         nglCompressedTexSubImage2DARB ( GL_TEXTURE_2D, nNumMipMap-decalMipMapResize, 
00835                                                                                         x0, y0, (x1-x0), (y1-y0), glfmt, imageSize, ptr );
00836                 }
00837                 else
00838                 {
00839                         // The CompressedTexSubImage2DARB function do not functionnate properly if width or height
00840                         // of the mipmap is less than 4 pixel so we use the other form. (its not really time critical
00841                         // to upload 16 bytes so we can do it twice if texture is cut)
00842                         imageSize = tex.getPixels(nNumMipMap).size();
00843                         nglCompressedTexImage2DARB (GL_TEXTURE_2D, nNumMipMap-decalMipMapResize, 
00844                                                                                 glfmt, w, h, 0, imageSize, ptr);
00845                 }
00846         }
00847         else
00848         {
00849                 // glSrcFmt and ITexture format must be identical
00850                 nlassert (glSrcFmt!=GL_RGBA || tex.getPixelFormat()==CBitmap::RGBA);
00851 
00852                 void    *ptr= &(*tex.getPixels(nNumMipMap).begin());
00853                 glPixelStorei (GL_UNPACK_ROW_LENGTH, w);
00854                 glPixelStorei (GL_UNPACK_SKIP_ROWS, y0);
00855                 glPixelStorei (GL_UNPACK_SKIP_PIXELS, x0);
00856                 glTexSubImage2D (GL_TEXTURE_2D, nNumMipMap, x0, y0, x1-x0, y1-y0, glSrcFmt,glSrcType, ptr);
00857 
00858                 // Reset the transfer mode...
00859                 glPixelStorei (GL_UNPACK_ROW_LENGTH, 0);
00860                 glPixelStorei (GL_UNPACK_SKIP_ROWS, 0);
00861                 glPixelStorei (GL_UNPACK_SKIP_PIXELS, 0);
00862         }
00863 
00864         // Disable texture 0
00865         _CurrentTexture[0]= NULL;
00866         _CurrentTextureInfoGL[0]= NULL;
00867         _DriverGLStates.setTextureMode (CDriverGLStates::TextureDisabled);
00868 
00869         return true;
00870 }
00871 
00872 // ***************************************************************************
00873 bool CDriverGL::uploadTextureCube (ITexture& tex, CRect& rect, uint8 nNumMipMap, uint8 nNumFace)
00874 {
00875         if (tex.TextureDrvShare == NULL)
00876                 return false; // Texture not created
00877         if (!tex.isTextureCube())
00878                 return false;
00879 
00880         return true;
00881 }
00882 
00883 // ***************************************************************************
00884 bool CDriverGL::activateTexture(uint stage, ITexture *tex)
00885 {       
00886         if (this->_CurrentTexture[stage]!=tex)
00887         {
00888                 _DriverGLStates.activeTextureARB(stage);
00889                 if(tex)
00890                 {
00891                         // get the drv info. should be not NULL.
00892                         CTextureDrvInfosGL*     gltext;
00893                         gltext= getTextureGl(*tex);
00894 
00895                         // Profile, log the use of this texture
00896                         //=========================================
00897                         if (_SumTextureMemoryUsed)
00898                         {
00899                                 // Insert the pointer of this texture
00900                                 _TextureUsed.insert (gltext);
00901                         }
00902 
00903 
00904                         if(tex->isTextureCube())
00905                         {
00906                                 // setup texture mode, after activeTextureARB()
00907                                 _DriverGLStates.setTextureMode(CDriverGLStates::TextureCubeMap);
00908 
00909                                 if(_Extensions.ARBTextureCubeMap)
00910                                 {
00911                                         // Activate texturing...
00912                                         //======================
00913 
00914                                         // If the shared texture is the same than before, no op.
00915                                         if(_CurrentTextureInfoGL[stage] != gltext)
00916                                         {
00917                                                 // Cache setup.
00918                                                 _CurrentTextureInfoGL[stage]= gltext;
00919 
00920                                                 // setup this texture
00921                                                 glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, gltext->ID);
00922                                                 
00923 
00924                                                 // Change parameters of texture, if necessary.
00925                                                 //============================================
00926                                                 if(gltext->MagFilter!= tex->getMagFilter())
00927                                                 {
00928                                                         gltext->MagFilter= tex->getMagFilter();
00929                                                         glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB,GL_TEXTURE_MAG_FILTER, translateMagFilterToGl(gltext->MagFilter));
00930                                                 }
00931                                                 if(gltext->MinFilter!= tex->getMinFilter())
00932                                                 {
00933                                                         gltext->MinFilter= tex->getMinFilter();
00934                                                         glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB,GL_TEXTURE_MIN_FILTER, translateMinFilterToGl(gltext->MinFilter));
00935                                                 }
00936                                         }
00937                                 }
00938                         }
00939                         else
00940                         {
00941                                 // setup texture mode, after activeTextureARB()
00942                                 _DriverGLStates.setTextureMode(CDriverGLStates::Texture2D);                                                             
00943 
00944                                 // Activate texture...
00945                                 //======================
00946 
00947                                 // If the shared texture is the same than before, no op.
00948                                 if(_CurrentTextureInfoGL[stage] != gltext)
00949                                 {
00950                                         // Cache setup.
00951                                         _CurrentTextureInfoGL[stage]= gltext;
00952 
00953                                         // setup this texture
00954                                         glBindTexture(GL_TEXTURE_2D, gltext->ID);                                                               
00955 
00956 
00957                                         // Change parameters of texture, if necessary.
00958                                         //============================================
00959                                         if(gltext->WrapS!= tex->getWrapS())
00960                                         {
00961                                                 gltext->WrapS= tex->getWrapS();
00962                                                 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S, translateWrapToGl(gltext->WrapS, _Extensions));
00963                                         }
00964                                         if(gltext->WrapT!= tex->getWrapT())
00965                                         {
00966                                                 gltext->WrapT= tex->getWrapT();
00967                                                 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T, translateWrapToGl(gltext->WrapT, _Extensions));
00968                                         }
00969                                         if(gltext->MagFilter!= tex->getMagFilter())
00970                                         {
00971                                                 gltext->MagFilter= tex->getMagFilter();
00972                                                 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, translateMagFilterToGl(gltext->MagFilter));
00973                                         }
00974                                         if(gltext->MinFilter!= tex->getMinFilter())
00975                                         {
00976                                                 gltext->MinFilter= tex->getMinFilter();                                 
00977                                                 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, translateMinFilterToGl(gltext->MinFilter));
00978                                         }
00979                                 }
00980                         }
00981                 }
00982                 else
00983                 {
00984                         // Force no texturing for this stage.
00985                         _CurrentTextureInfoGL[stage]= NULL;
00986                         // setup texture mode, after activeTextureARB()
00987                         _DriverGLStates.setTextureMode(CDriverGLStates::TextureDisabled);                                                                       
00988                 }
00989 
00990                 this->_CurrentTexture[stage]= tex;      
00991         }       
00992 
00993         return true;
00994 }
00995 
00996 // ***************************************************************************
00997 void            CDriverGL::forceActivateTexEnvMode(uint stage, const CMaterial::CTexEnv  &env)
00998 {
00999         // This maps the CMaterial::TTexOperator
01000         static  const   GLenum  operatorLUT[9]= { GL_REPLACE, GL_MODULATE, GL_ADD, GL_ADD_SIGNED_EXT, 
01001                 GL_INTERPOLATE_EXT, GL_INTERPOLATE_EXT, GL_INTERPOLATE_EXT, GL_INTERPOLATE_EXT, GL_BUMP_ENVMAP_ATI };
01002 
01003         // This maps the CMaterial::TTexSource
01004         static  const   GLenum  sourceLUT[4]= { GL_TEXTURE, GL_PREVIOUS_EXT, GL_PRIMARY_COLOR_EXT, GL_CONSTANT_EXT };
01005 
01006         // This maps the CMaterial::TTexOperand
01007         static  const   GLenum  operandLUT[4]= { GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA };
01008 
01009         // This maps the CMaterial::TTexOperator, used for openGL Arg2 setup.
01010         static  const   GLenum  interpolateSrcLUT[8]= { GL_TEXTURE, GL_TEXTURE, GL_TEXTURE, GL_TEXTURE, 
01011                 GL_TEXTURE, GL_PREVIOUS_EXT, GL_PRIMARY_COLOR_EXT, GL_CONSTANT_EXT };
01012 
01013 
01014 
01015         // cache mgt.
01016         _CurrentTexEnv[stage].EnvPacked= env.EnvPacked;
01017         // Disable Special tex env f().
01018         _CurrentTexEnvSpecial[stage]= TexEnvSpecialDisabled;
01019 
01020 
01021         // Setup the gl env mode.
01022         _DriverGLStates.activeTextureARB(stage);
01023         // "Normal drivers", setup EnvCombine.
01024         if(_Extensions.EXTTextureEnvCombine)
01025         {
01026                 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
01027 
01028 
01029                 // RGB.
01030                 //=====
01031                 // Operator.
01032                 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, operatorLUT[env.Env.OpRGB] );
01033                 // Arg0.
01034                 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, sourceLUT[env.Env.SrcArg0RGB] );
01035                 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, operandLUT[env.Env.OpArg0RGB]);
01036                 // Arg1.
01037                 if(env.Env.OpRGB > CMaterial::Replace)
01038                 {
01039                         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, sourceLUT[env.Env.SrcArg1RGB] );
01040                         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, operandLUT[env.Env.OpArg1RGB]);
01041                         // Arg2.
01042                         if(env.Env.OpRGB >= CMaterial::InterpolateTexture )
01043                         {
01044                                 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_EXT, interpolateSrcLUT[env.Env.OpRGB] );
01045                                 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_EXT, GL_SRC_ALPHA);
01046                         }
01047                 }
01048 
01049 
01050                 // Alpha.
01051                 //=====
01052                 // Operator.
01053                 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, operatorLUT[env.Env.OpAlpha] );
01054                 // Arg0.
01055                 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, sourceLUT[env.Env.SrcArg0Alpha] );
01056                 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_EXT, operandLUT[env.Env.OpArg0Alpha]);
01057                 // Arg1.
01058                 if(env.Env.OpAlpha > CMaterial::Replace)
01059                 {
01060                         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_EXT, sourceLUT[env.Env.SrcArg1Alpha] );
01061                         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_EXT, operandLUT[env.Env.OpArg1Alpha]);
01062                         // Arg2.
01063                         if(env.Env.OpAlpha >= CMaterial::InterpolateTexture )
01064                         {
01065                                 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA_EXT, interpolateSrcLUT[env.Env.OpAlpha] );
01066                                 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA_EXT, GL_SRC_ALPHA);
01067                         }
01068                 }
01069         }
01070         // Very Bad drivers.
01071         else
01072         {
01073                 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
01074         }
01075 
01076 }
01077 
01078 
01079 // ***************************************************************************
01080 void            CDriverGL::activateTexEnvColor(uint stage, NLMISC::CRGBA col)
01081 {       
01082         if (col != _CurrentTexEnv[stage].ConstantColor)
01083         {       
01084                 forceActivateTexEnvColor(stage, col);   
01085         }
01086 }
01087 
01088 
01089 // ***************************************************************************
01090 void            CDriverGL::activateTexEnvMode(uint stage, const CMaterial::CTexEnv  &env)
01091 {
01092         // If a special Texture environnement is setuped, or if not the same normal texture environnement,
01093         // must setup a new normal Texture environnement.
01094         if( _CurrentTexEnvSpecial[stage] != TexEnvSpecialDisabled || _CurrentTexEnv[stage].EnvPacked!= env.EnvPacked)
01095         { 
01096                 forceActivateTexEnvMode(stage, env);
01097         }
01098 }
01099 
01100 
01101 // ***************************************************************************
01102 void            CDriverGL::activateTexEnvColor(uint stage, const CMaterial::CTexEnv  &env)
01103 {
01104         if(_CurrentTexEnv[stage].ConstantColor!= env.ConstantColor)
01105         { 
01106                 forceActivateTexEnvColor(stage, env);
01107         }
01108 }
01109 
01110 
01111 // ***************************************************************************
01112 void            CDriverGL::forceDXTCCompression(bool dxtcComp)
01113 {
01114         _ForceDXTCCompression= dxtcComp;
01115 }
01116 
01117 // ***************************************************************************
01118 void            CDriverGL::forceTextureResize(uint divisor)
01119 {
01120         clamp(divisor, 1U, 256U);
01121 
01122         // 16 -> 4.
01123         _ForceTextureResizePower= getPowerOf2(divisor);
01124 }
01125 
01126 
01127 // ***************************************************************************
01128 void            CDriverGL::swapTextureHandle(ITexture &tex0, ITexture &tex1)
01129 {
01130         // ensure creation of both texture
01131         setupTexture(tex0);
01132         setupTexture(tex1);
01133 
01134         // avoid any problem, disable all textures
01135         for(sint stage=0; stage<inlGetNumTextStages() ; stage++)
01136         {
01137                 activateTexture(stage, NULL);
01138         }
01139 
01140         // get the handle.
01141         CTextureDrvInfosGL      *t0= getTextureGl(tex0);
01142         CTextureDrvInfosGL      *t1= getTextureGl(tex1);
01143 
01144         /* Swap contents. Can't swap directly the pointers cause would have to change all CTextureDrvShare which point on
01145                 Can't do swap(*t0, *t1), because must keep the correct _DriverIterator
01146         */
01147         swap(t0->ID, t1->ID);
01148         swap(t0->Compressed, t1->Compressed);
01149         swap(t0->TextureMemory, t1->TextureMemory);
01150         swap(t0->WrapS, t1->WrapS);
01151         swap(t0->WrapT, t1->WrapT);
01152         swap(t0->MagFilter, t1->MagFilter);
01153         swap(t0->MinFilter, t1->MinFilter);
01154 
01155 }
01156 
01157 
01158 } // NL3D