00001
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
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"
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
00049 glGenTextures(1,&ID);
00050
00051 Compressed= false;
00052 TextureMemory= 0;
00053
00054
00055 _Driver= drvGl;
00056 }
00057
00058 CTextureDrvInfosGL::~CTextureDrvInfosGL()
00059 {
00060
00061 glDeleteTextures(1,&ID);
00062
00063
00064 _Driver->_AllocatedTextureMemory-= TextureMemory;
00065
00066
00067 _Driver->_TextureUsed.erase (this);
00068 }
00069
00070
00071
00072
00073
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
00084 GLint CDriverGL::getGlTextureFormat(ITexture& tex, bool &compressed)
00085 {
00086 ITexture::TUploadFormat texfmt= tex.getUploadFormat();
00087
00088
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
00113 if(_Extensions.EXTTextureCompressionS3TC)
00114 {
00115 compressed= true;
00116
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
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
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
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;
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
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
00222 nlstop;
00223
00225 return w*h* 4;
00226 }
00227
00228
00229
00230
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
00327
00328 bool mustCreate = false;
00329 if ( !tex.TextureDrvShare )
00330 {
00331
00332 ItTexDrvSharePtrList it= _TexDrvShares.insert(_TexDrvShares.end());
00333
00334 *it= tex.TextureDrvShare= new CTextureDrvShare(this, it);
00335
00336
00337 mustCreate = true;
00338 }
00339
00340 if ( (!tex.touched()) && (!mustCreate) )
00341 return true;
00342
00343
00344
00345
00346
00347
00348 bool mustLoadAll= false;
00349 bool mustLoadPart= false;
00350
00351
00352
00353
00354
00355
00356
00357 for(sint stage=0 ; stage<inlGetNumTextStages() ; stage++)
00358 {
00359 activateTexture(stage, NULL);
00360 }
00361
00362
00363
00364
00365 if(tex.supportSharing())
00366 {
00367
00368
00369
00370 std::string name;
00371 getTextureShareName (tex, name);
00372
00373
00374 {
00375 CSynchronized<TTexDrvInfoPtrMap>::CAccessor access(&_SyncTexDrvInfos);
00376 TTexDrvInfoPtrMap &rTexDrvInfos = access.value();
00377
00378 ItTexDrvInfoPtrMap itTex;
00379 itTex= rTexDrvInfos.find(name);
00380
00381
00382 if( itTex==rTexDrvInfos.end() )
00383 {
00384
00385 itTex= (rTexDrvInfos.insert(make_pair(name, (ITextureDrvInfos*)NULL))).first;
00386
00387 itTex->second= tex.TextureDrvShare->DrvTexture= new CTextureDrvInfosGL(this, itTex, this);
00388
00389
00390 mustLoadAll= true;
00391 }
00392 else
00393 {
00394 tex.TextureDrvShare->DrvTexture= itTex->second;
00395
00396 if(bMustRecreateSharedTexture)
00397
00398 mustLoadAll= true;
00399 else
00400
00401
00402 mustLoadAll= false;
00403 }
00404 }
00405
00406
00407 }
00408 else
00409 {
00410
00411 if(!tex.TextureDrvShare->DrvTexture)
00412 {
00413
00414
00415
00416 tex.TextureDrvShare->DrvTexture= new CTextureDrvInfosGL(NULL, ItTexDrvInfoPtrMap(), this);
00417
00418
00419 mustLoadAll= true;
00420 }
00421 else if(tex.isAllInvalidated())
00422 mustLoadAll= true;
00423 else if(tex.touched())
00424 mustLoadPart= true;
00425 }
00426
00427
00428
00429 if(mustLoadAll || mustLoadPart)
00430 {
00431 CTextureDrvInfosGL* gltext;
00432 gltext= getTextureGl(tex);
00433
00434
00435 _DriverGLStates.activeTextureARB(0);
00436 if(tex.isTextureCube())
00437 {
00438 _DriverGLStates.setTextureMode(CDriverGLStates::TextureCubeMap);
00439
00440 glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, gltext->ID);
00441 }
00442 else
00443 {
00444 _DriverGLStates.setTextureMode(CDriverGLStates::Texture2D);
00445
00446 glBindTexture(GL_TEXTURE_2D, gltext->ID);
00447 }
00448
00449
00450 glPixelStorei(GL_UNPACK_ALIGNMENT,1);
00451
00452
00453
00454 if (mustLoadAll)
00455 {
00456
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
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
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
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
00508 gltext->TextureMemory+= computeMipMapMemoryUsage(w, h, glfmt);
00509 }
00510 }
00511 }
00512 else
00513 {
00514
00515 tex.generate();
00516
00517 if(tex.getSize()>0)
00518 {
00519
00520 GLint glfmt= getGlTextureFormat(tex, gltext->Compressed);
00521 GLint glSrcFmt= getGlSrcTextureFormat(tex, glfmt);
00522 GLenum glSrcType= getGlSrcTextureComponentType(glSrcFmt);
00523
00524
00525
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
00536
00537 uint decalMipMapResize= 0;
00538 if(_ForceTextureResizePower>0 && tex.allowDegradation() && nMipMaps>1)
00539 {
00540 decalMipMapResize= min(_ForceTextureResizePower, (uint)(nMipMaps-1));
00541 }
00542
00543
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
00557
00558 glTexImage2D (GL_TEXTURE_2D, i-decalMipMapResize, glfmt, tex.getWidth(i), tex.getHeight(i),
00559 0, glSrcFmt, glSrcType, NULL);
00560 }
00561
00562
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;
00572 tex.convertToType(CBitmap::RGBA);
00573 }
00574
00575
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
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
00610 gltext->TextureMemory += computeMipMapMemoryUsage (w, h, glfmt);
00611 }
00612 }
00613 }
00614 }
00615
00616
00617
00618
00619 _AllocatedTextureMemory+= gltext->TextureMemory;
00620 }
00621
00622
00623
00624
00625 else if (mustLoadPart && !gltext->Compressed)
00626 {
00627
00628 tex.generate();
00629
00630 if(tex.getSize()>0)
00631 {
00632
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
00648 if(!hadMipMap)
00649 {
00650 tex.releaseMipMaps();
00651 }
00652 }
00653 else
00654 nMipMaps= 1;
00655
00656
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
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
00687
00688 x0= x0/2;
00689 y0= y0/2;
00690
00691 x1= (x1+1)/2;
00692 y1= (y1+1)/2;
00693 }
00694 }
00695
00696
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
00705 if(tex.getReleasable())
00706 tex.release();
00707
00708
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
00733 _CurrentTexture[0]= NULL;
00734 _CurrentTextureInfoGL[0]= NULL;
00735 _DriverGLStates.setTextureMode(CDriverGLStates::TextureDisabled);
00736 }
00737
00738
00739
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;
00750 if (tex.TextureDrvShare->DrvTexture == NULL)
00751 return false;
00752 if (tex.isTextureCube())
00753 return false;
00754
00755 nlassert(nNumMipMap<(uint8)tex.getMipMapCount());
00756
00757
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
00770 CTextureDrvInfosGL* gltext;
00771 gltext = getTextureGl (tex);
00772
00773
00774 _DriverGLStates.activeTextureARB (0);
00775 _DriverGLStates.setTextureMode (CDriverGLStates::Texture2D);
00776
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
00786
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
00806 sint imageSize = (x1-x0)*(y1-y0);
00807 void *ptr = &(*tex.getPixels(nNumMipMap).begin());
00808
00809
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
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
00840
00841
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
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
00859 glPixelStorei (GL_UNPACK_ROW_LENGTH, 0);
00860 glPixelStorei (GL_UNPACK_SKIP_ROWS, 0);
00861 glPixelStorei (GL_UNPACK_SKIP_PIXELS, 0);
00862 }
00863
00864
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;
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
00892 CTextureDrvInfosGL* gltext;
00893 gltext= getTextureGl(*tex);
00894
00895
00896
00897 if (_SumTextureMemoryUsed)
00898 {
00899
00900 _TextureUsed.insert (gltext);
00901 }
00902
00903
00904 if(tex->isTextureCube())
00905 {
00906
00907 _DriverGLStates.setTextureMode(CDriverGLStates::TextureCubeMap);
00908
00909 if(_Extensions.ARBTextureCubeMap)
00910 {
00911
00912
00913
00914
00915 if(_CurrentTextureInfoGL[stage] != gltext)
00916 {
00917
00918 _CurrentTextureInfoGL[stage]= gltext;
00919
00920
00921 glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, gltext->ID);
00922
00923
00924
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
00942 _DriverGLStates.setTextureMode(CDriverGLStates::Texture2D);
00943
00944
00945
00946
00947
00948 if(_CurrentTextureInfoGL[stage] != gltext)
00949 {
00950
00951 _CurrentTextureInfoGL[stage]= gltext;
00952
00953
00954 glBindTexture(GL_TEXTURE_2D, gltext->ID);
00955
00956
00957
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
00985 _CurrentTextureInfoGL[stage]= NULL;
00986
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
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
01004 static const GLenum sourceLUT[4]= { GL_TEXTURE, GL_PREVIOUS_EXT, GL_PRIMARY_COLOR_EXT, GL_CONSTANT_EXT };
01005
01006
01007 static const GLenum operandLUT[4]= { GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA };
01008
01009
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
01016 _CurrentTexEnv[stage].EnvPacked= env.EnvPacked;
01017
01018 _CurrentTexEnvSpecial[stage]= TexEnvSpecialDisabled;
01019
01020
01021
01022 _DriverGLStates.activeTextureARB(stage);
01023
01024 if(_Extensions.EXTTextureEnvCombine)
01025 {
01026 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
01027
01028
01029
01030
01031
01032 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, operatorLUT[env.Env.OpRGB] );
01033
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
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
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
01051
01052
01053 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, operatorLUT[env.Env.OpAlpha] );
01054
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
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
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
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
01093
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
01123 _ForceTextureResizePower= getPowerOf2(divisor);
01124 }
01125
01126
01127
01128 void CDriverGL::swapTextureHandle(ITexture &tex0, ITexture &tex1)
01129 {
01130
01131 setupTexture(tex0);
01132 setupTexture(tex1);
01133
01134
01135 for(sint stage=0; stage<inlGetNumTextStages() ; stage++)
01136 {
01137 activateTexture(stage, NULL);
01138 }
01139
01140
01141 CTextureDrvInfosGL *t0= getTextureGl(tex0);
01142 CTextureDrvInfosGL *t1= getTextureGl(tex1);
01143
01144
01145
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 }