From 0ea5fc66924303d1bf73ba283a383e2aadee02f2 Mon Sep 17 00:00:00 2001 From: neodarz Date: Sat, 11 Aug 2018 20:21:34 +0200 Subject: Initial commit --- .../nel/driver__opengl__material_8cpp-source.html | 1823 ++++++++++++++++++++ 1 file changed, 1823 insertions(+) create mode 100644 docs/doxygen/nel/driver__opengl__material_8cpp-source.html (limited to 'docs/doxygen/nel/driver__opengl__material_8cpp-source.html') diff --git a/docs/doxygen/nel/driver__opengl__material_8cpp-source.html b/docs/doxygen/nel/driver__opengl__material_8cpp-source.html new file mode 100644 index 00000000..666280d1 --- /dev/null +++ b/docs/doxygen/nel/driver__opengl__material_8cpp-source.html @@ -0,0 +1,1823 @@ + + + + nevrax.org : docs + + + + + + + + + + + + + + +
# 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_material.cpp

Go to the documentation of this file.
00001 
+00007 /* Copyright, 2000 Nevrax Ltd.
+00008  *
+00009  * This file is part of NEVRAX NEL.
+00010  * NEVRAX NEL is free software; you can redistribute it and/or modify
+00011  * it under the terms of the GNU General Public License as published by
+00012  * the Free Software Foundation; either version 2, or (at your option)
+00013  * any later version.
+00014 
+00015  * NEVRAX NEL is distributed in the hope that it will be useful, but
+00016  * WITHOUT ANY WARRANTY; without even the implied warranty of
+00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+00018  * General Public License for more details.
+00019 
+00020  * You should have received a copy of the GNU General Public License
+00021  * along with NEVRAX NEL; see the file COPYING. If not, write to the
+00022  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+00023  * MA 02111-1307, USA.
+00024  */
+00025 
+00026 #include "stdopengl.h"
+00027 #include "3d/cube_map_builder.h"
+00028 #include "3d/texture_mem.h"
+00029 
+00030 
+00031 namespace NL3D {
+00032 
+00033 static void convBlend(CMaterial::TBlend blend, GLenum& glenum)
+00034 {
+00035         switch(blend)
+00036         {
+00037                 case CMaterial::one:            glenum=GL_ONE; break;
+00038                 case CMaterial::zero:           glenum=GL_ZERO; break;
+00039                 case CMaterial::srcalpha:       glenum=GL_SRC_ALPHA; break;
+00040                 case CMaterial::invsrcalpha:glenum=GL_ONE_MINUS_SRC_ALPHA; break;
+00041                 case CMaterial::srccolor:       glenum=GL_SRC_COLOR; break;
+00042                 case CMaterial::invsrccolor:glenum=GL_ONE_MINUS_SRC_COLOR; break;
+00043                 // Extended Blend modes.
+00044                 case CMaterial::blendConstantColor:             glenum=GL_CONSTANT_COLOR_EXT; break;
+00045                 case CMaterial::blendConstantInvColor:  glenum=GL_ONE_MINUS_CONSTANT_COLOR_EXT; break;
+00046                 case CMaterial::blendConstantAlpha:             glenum=GL_CONSTANT_ALPHA_EXT; break;
+00047                 case CMaterial::blendConstantInvAlpha:  glenum=GL_ONE_MINUS_CONSTANT_ALPHA_EXT; break;
+00048                 default: nlstop;
+00049         }
+00050 }
+00051 
+00052 static void convZFunction(CMaterial::ZFunc zfunc, GLenum& glenum)
+00053 {
+00054         switch(zfunc)
+00055         {
+00056                 case CMaterial::lessequal:      glenum=GL_LEQUAL; break;
+00057                 case CMaterial::less:           glenum=GL_LESS; break;
+00058                 case CMaterial::always:         glenum=GL_ALWAYS; break;
+00059                 case CMaterial::never:          glenum=GL_NEVER; break;
+00060                 case CMaterial::equal:          glenum=GL_EQUAL; break;
+00061                 case CMaterial::notequal:       glenum=GL_NOTEQUAL; break;
+00062                 case CMaterial::greater:        glenum=GL_GREATER; break;
+00063                 case CMaterial::greaterequal:   glenum=GL_GEQUAL; break;
+00064                 default: nlstop;
+00065         }
+00066 }
+00067 
+00068 static void     convColor(CRGBA col, GLfloat glcol[4])
+00069 {
+00070         static  const float     OO255= 1.0f/255;
+00071         glcol[0]= col.R*OO255;
+00072         glcol[1]= col.G*OO255;
+00073         glcol[2]= col.B*OO255;
+00074         glcol[3]= col.A*OO255;
+00075 }
+00076 
+00077 static inline void convTexAddr(ITexture *tex, CMaterial::TTexAddressingMode mode, GLenum &glenum)
+00078 {       
+00079         nlassert(mode < CMaterial::TexAddrCount);
+00080         static const GLenum glTex2dAddrModesNV[] =
+00081         {
+00082                 GL_NONE, GL_TEXTURE_2D, GL_PASS_THROUGH_NV, GL_CULL_FRAGMENT_NV,
+00083                 GL_OFFSET_TEXTURE_2D_NV, GL_OFFSET_TEXTURE_2D_SCALE_NV,
+00084                 GL_DEPENDENT_AR_TEXTURE_2D_NV, GL_DEPENDENT_GB_TEXTURE_2D_NV,
+00085                 GL_DOT_PRODUCT_NV, GL_DOT_PRODUCT_TEXTURE_2D_NV, GL_DOT_PRODUCT_TEXTURE_CUBE_MAP_NV,
+00086                 GL_DOT_PRODUCT_REFLECT_CUBE_MAP_NV, GL_DOT_PRODUCT_CONST_EYE_REFLECT_CUBE_MAP_NV,
+00087                 GL_DOT_PRODUCT_DIFFUSE_CUBE_MAP_NV, GL_DOT_PRODUCT_DEPTH_REPLACE_NV
+00088         };
+00089 
+00090 
+00091         static const GLenum glTexCubedAddrModesNV[] =
+00092         {
+00093                 GL_NONE, GL_TEXTURE_CUBE_MAP_ARB, GL_PASS_THROUGH_NV, GL_CULL_FRAGMENT_NV,
+00094                 GL_OFFSET_TEXTURE_2D_NV, GL_OFFSET_TEXTURE_2D_SCALE_NV,
+00095                 GL_DEPENDENT_AR_TEXTURE_2D_NV, GL_DEPENDENT_GB_TEXTURE_2D_NV,
+00096                 GL_DOT_PRODUCT_NV, GL_DOT_PRODUCT_TEXTURE_2D_NV, GL_DOT_PRODUCT_TEXTURE_CUBE_MAP_NV,
+00097                 GL_DOT_PRODUCT_REFLECT_CUBE_MAP_NV, GL_DOT_PRODUCT_CONST_EYE_REFLECT_CUBE_MAP_NV,
+00098                 GL_DOT_PRODUCT_DIFFUSE_CUBE_MAP_NV, GL_DOT_PRODUCT_DEPTH_REPLACE_NV
+00099         };
+00100 
+00101         
+00102         if (!tex || !tex->isTextureCube())
+00103         {       
+00104                 glenum = glTex2dAddrModesNV[(uint) mode];
+00105         }
+00106         else
+00107         {
+00108                 glenum = glTexCubedAddrModesNV[(uint) mode];
+00109         }
+00110 }
+00111 
+00112 
+00113 // --------------------------------------------------
+00114 void CDriverGL::setTextureEnvFunction(uint stage, CMaterial& mat)
+00115 {
+00116         ITexture        *text= mat.getTexture(stage);
+00117         if(text)
+00118         {
+00119                 CMaterial::CTexEnv      &env= mat._TexEnvs[stage];
+00120 
+00121                 // Activate the env for this stage.
+00122                 // NB: Thoses calls use caching.
+00123                 activateTexEnvMode(stage, env);
+00124                 activateTexEnvColor(stage, env);
+00125 
+00126                 // Activate texture generation mapping
+00127                 _DriverGLStates.activeTextureARB(stage);
+00128                 if (mat.getTexCoordGen (stage))
+00129                 {
+00130                         // Enable it
+00131                         _DriverGLStates.enableTexGen (stage, true);
+00132 
+00133                         // Cubic or normal ?
+00134                         if (text->isTextureCube ())
+00135                                 _DriverGLStates.setTexGenMode (stage, GL_REFLECTION_MAP_ARB);
+00136                         else
+00137                                 _DriverGLStates.setTexGenMode (stage, GL_SPHERE_MAP);
+00138                 }
+00139                 else
+00140                 {
+00141                         _DriverGLStates.enableTexGen (stage, false);
+00142                 }
+00143         }
+00144 }
+00145 
+00146 
+00147 //--------------------------------
+00148 void CDriverGL::setupUserTextureMatrix(uint numStages, CMaterial& mat)
+00149 { 
+00150         if (
+00151                 (_UserTexMatEnabled != 0 && (mat.getFlags() & IDRV_MAT_USER_TEX_MAT_ALL) == 0)          
+00152                 || (mat.getFlags() & IDRV_MAT_USER_TEX_MAT_ALL) != 0
+00153            )
+00154         {
+00155                 glMatrixMode(GL_TEXTURE);
+00156                 // for each stage, setup the texture matrix if needed
+00157                 uint newMask = (mat.getFlags() & IDRV_MAT_USER_TEX_MAT_ALL) >> IDRV_MAT_USER_TEX_FIRST_BIT;
+00158                 uint shiftMask = 1;
+00159                 for (uint k = 0; k < numStages ; ++k)
+00160                 {
+00161                         if (newMask & shiftMask) // user matrix for this stage
+00162                         {               
+00163                                 _DriverGLStates.activeTextureARB(k);
+00164                                 glLoadMatrixf(mat.getUserTexMat(k).get());
+00165                                 _UserTexMatEnabled |= shiftMask;
+00166                         }
+00167                         else
+00168                         {
+00170                                 if (
+00171                                         (newMask & shiftMask) != (_UserTexMatEnabled & shiftMask)
+00172                                    )
+00173                                 {
+00174                                         _DriverGLStates.activeTextureARB(k);
+00175                                         glLoadIdentity();
+00176                                         _UserTexMatEnabled &= ~shiftMask;
+00177                                 }                               
+00178                         }
+00179                         shiftMask <<= 1;
+00180                 }
+00181                 glMatrixMode(GL_MODELVIEW);
+00182         }
+00183 }
+00184 
+00185 void CDriverGL::disableUserTextureMatrix()
+00186 { 
+00187         if (_UserTexMatEnabled != 0)            
+00188         {
+00189                 glMatrixMode(GL_TEXTURE);               
+00190                 uint k = 0;
+00191                 do
+00192                 {
+00193                         if (_UserTexMatEnabled & (1 << k)) // user matrix for this stage
+00194                         {                                               
+00195                                 _DriverGLStates.activeTextureARB(k);
+00196                                 glLoadIdentity();
+00197                                 _UserTexMatEnabled &= ~ (1 << k);
+00198                                                                 
+00199                         }                       
+00200                         ++k;
+00201                 }
+00202                 while (_UserTexMatEnabled != 0);
+00203                 glMatrixMode(GL_MODELVIEW);
+00204         }
+00205 }
+00206 
+00207 
+00208 // --------------------------------------------------
+00209 CMaterial::TShader      CDriverGL::getSupportedShader(CMaterial::TShader shader)
+00210 {
+00211         switch (shader)
+00212         {
+00213         case CMaterial::PerPixelLighting: return _SupportPerPixelShader ? CMaterial::PerPixelLighting : CMaterial::Normal;
+00214         case CMaterial::PerPixelLightingNoSpec: return _SupportPerPixelShaderNoSpec ? CMaterial::PerPixelLightingNoSpec : CMaterial::Normal;
+00215         // Lightmap and Specular work only if at least 2 text stages.
+00216         case CMaterial::LightMap: return (inlGetNumTextStages()>=2) ? CMaterial::LightMap : CMaterial::Normal;
+00217         case CMaterial::Specular: return (inlGetNumTextStages()>=2) ? CMaterial::Specular : CMaterial::Normal;
+00218                 default: return shader;         
+00219         }
+00220 }
+00221 
+00222 
+00223 // --------------------------------------------------
+00224 
+00225 bool CDriverGL::setupMaterial(CMaterial& mat)
+00226 {
+00227         CShaderGL*      pShader;
+00228         GLenum          glenum;
+00229         uint32          touched=mat.getTouched();
+00230         sint            stage;
+00231 
+00232 
+00233         // profile.
+00234         _NbSetupMaterialCall++;
+00235 
+00236 
+00237         // 0. Retrieve/Create driver shader.
+00238         //==================================
+00239         if (!mat.pShader)
+00240         {
+00241                 // insert into driver list. (so it is deleted when driver is deleted).
+00242                 ItShaderPtrList         it= _Shaders.insert(_Shaders.end());
+00243                 // create and set iterator, for future deletion.
+00244                 *it= mat.pShader= new CShaderGL(this, it);
+00245 
+00246                 // Must create all OpenGL shader states.
+00247                 touched= IDRV_TOUCHED_ALL;
+00248         }
+00249         pShader=static_cast<CShaderGL*>((IShader*)(mat.pShader));
+00250 
+00251 
+00252         // 1. Setup modified fields of material.
+00253         //=====================================
+00254         if( touched ) 
+00255         {
+00256                 /* Exception: if only Textures are modified in the material, no need to "Bind OpenGL States", or even to test
+00257                         for change, because textures are activated alone, see below.
+00258                         No problem with delete/new problem (see below), because in this case, IDRV_TOUCHED_ALL is set (see above).
+00259                 */
+00260                 // If any flag is set (but a flag of texture)
+00261                 if( touched & (~_MaterialAllTextureTouchedFlag) )
+00262                 {
+00263                         // Convert Material to driver shader.
+00264                         if (touched & IDRV_TOUCHED_BLENDFUNC)
+00265                         {
+00266                                 convBlend( mat.getSrcBlend(),glenum );
+00267                                 pShader->SrcBlend=glenum;
+00268                                 convBlend( mat.getDstBlend(),glenum );
+00269                                 pShader->DstBlend=glenum;
+00270                         }
+00271                         if (touched & IDRV_TOUCHED_ZFUNC)
+00272                         {
+00273                                 convZFunction( mat.getZFunc(),glenum);
+00274                                 pShader->ZComp= glenum;
+00275                         }
+00276                         if (touched & IDRV_TOUCHED_LIGHTING)
+00277                         {
+00278                                 convColor(mat.getEmissive(), pShader->Emissive);
+00279                                 convColor(mat.getAmbient(), pShader->Ambient);
+00280                                 convColor(mat.getDiffuse(), pShader->Diffuse);
+00281                                 convColor(mat.getSpecular(), pShader->Specular);
+00282                                 pShader->PackedEmissive= mat.getEmissive().getPacked();
+00283                                 pShader->PackedAmbient= mat.getAmbient().getPacked();
+00284                                 pShader->PackedDiffuse= mat.getDiffuse().getPacked();
+00285                                 pShader->PackedSpecular= mat.getSpecular().getPacked();
+00286                         }
+00287                         if (touched & IDRV_TOUCHED_SHADER)
+00288                         {
+00289                                 // Get shader. Fallback to other shader if not supported.
+00290                                 pShader->SupportedShader= getSupportedShader(mat.getShader());
+00291                         }
+00292 
+00293 
+00294                         // Since modified, must rebind all openGL states. And do this also for the delete/new problem.
+00295                         /* If an old material is deleted, _CurrentMaterial is invalid. But this is grave only if a new 
+00296                                 material is created, with the same pointer (bad luck). Since an newly allocated material always 
+00297                                 pass here before use, we are sure to avoid any problems.
+00298                         */
+00299                         _CurrentMaterial= NULL;
+00300                 }
+00301 
+00302                 // Optimize: reset all flags at the end.
+00303                 mat.clearTouched(0xFFFFFFFF);
+00304         }
+00305 
+00306 
+00307         // Now we can get the supported shader from the cache.
+00308         CMaterial::TShader matShader = pShader->SupportedShader;
+00309 
+00310         // setup the global
+00311         _CurrentMaterialSupportedShader= matShader;
+00312 
+00313 
+00314         // 2. Setup / Bind Textures.
+00315         //==========================
+00316         // Must setup textures each frame. (need to test if touched).
+00317         // Must separate texture setup and texture activation in 2 "for"...
+00318         // because setupTexture() may disable all stage.
+00319         for(stage=0 ; stage<inlGetNumTextStages() ; stage++)
+00320         {
+00321                 ITexture        *text= mat.getTexture(stage);
+00322                 if (text != NULL && !setupTexture(*text))
+00323                         return(false);
+00324         }
+00325         // Here, for Lightmap materials, setup the lightmaps.
+00326         if(matShader == CMaterial::LightMap)
+00327         {
+00328                 for(stage=0 ; stage<(sint)mat._LightMaps.size() ; stage++)
+00329                 {
+00330                         ITexture        *text= mat._LightMaps[stage].Texture;
+00331                         if (text != NULL && !setupTexture(*text))
+00332                                 return(false);
+00333                 }
+00334         }
+00335 
+00336         // Here, for caustic shader, setup the lightmaps
+00337         /*if (matShader == CMaterial::Caustics)
+00338         {
+00339                 if (mat.getTexture(stage))
+00340         }*/
+00341         
+00342 
+00343         // Activate the textures.
+00344         // Do not do it for Lightmap and per pixel lighting , because done in multipass in a very special fashion.
+00345         // This avoid the useless multiple change of texture states per lightmapped object.
+00346         if(matShader != CMaterial::LightMap
+00347                 && matShader != CMaterial::PerPixelLighting
+00348                 /* && matShader != CMaterial::Caustics  */
+00349                 && matShader != CMaterial::Cloud
+00350            )
+00351         {
+00352                 for(stage=0 ; stage<inlGetNumTextStages() ; stage++)
+00353                 {
+00354                         ITexture        *text= mat.getTexture(stage);
+00355 
+00356                         // activate the texture, or disable texturing if NULL.
+00357                         activateTexture(stage,text);
+00358 
+00359                         // If texture not NULL, Change texture env fonction.
+00360                         //==================================================
+00361                         setTextureEnvFunction(stage, mat);
+00362                 }                               
+00363         }
+00364 
+00365 
+00366         // 3. Bind OpenGL States.
+00367         //=======================
+00368         if (_CurrentMaterial!=&mat)
+00369         {
+00370                 // Bind Blend Part.
+00371                 //=================
+00372                 _DriverGLStates.enableBlend(mat.getFlags()&IDRV_MAT_BLEND);
+00373                 if(mat.getFlags()&IDRV_MAT_BLEND)
+00374                         _DriverGLStates.blendFunc(pShader->SrcBlend, pShader->DstBlend);
+00375 
+00376                 // Double Sided Part.
+00377                 //===================
+00378                 // NB: inverse state: DoubleSided <=> !CullFace.
+00379                 uint32  twoSided= mat.getFlags()&IDRV_MAT_DOUBLE_SIDED;
+00380                 _DriverGLStates.enableCullFace( twoSided==0 );
+00381 
+00382 
+00383                 // Alpha Test Part.
+00384                 //=================
+00385                 uint32  alphaTest= mat.getFlags()&IDRV_MAT_ALPHA_TEST;
+00386                 _DriverGLStates.enableAlphaTest(alphaTest);
+00387                 if(alphaTest)
+00388                 {
+00389                         // setup alphaTest threshold.
+00390                         _DriverGLStates.alphaFunc(mat.getAlphaTestThreshold());
+00391                 }
+00392 
+00393 
+00394                 // Bind ZBuffer Part.
+00395                 //===================
+00396                 _DriverGLStates.enableZWrite(mat.getFlags()&IDRV_MAT_ZWRITE);
+00397                 _DriverGLStates.depthFunc(pShader->ZComp);
+00398                 _DriverGLStates.setDepthRange (mat.getZBias () * _OODeltaZ);
+00399 
+00400 
+00401                 // Color-Lighting Part.
+00402                 //=====================
+00403 
+00404                 // Light Part.
+00405                 _DriverGLStates.enableLighting(mat.getFlags()&IDRV_MAT_LIGHTING);
+00406                 if(mat.getFlags()&IDRV_MAT_LIGHTING)
+00407                 {
+00408                         _DriverGLStates.setEmissive(pShader->PackedEmissive, pShader->Emissive);
+00409                         _DriverGLStates.setAmbient(pShader->PackedAmbient, pShader->Ambient);
+00410                         _DriverGLStates.setDiffuse(pShader->PackedDiffuse, pShader->Diffuse);
+00411                         _DriverGLStates.setSpecular(pShader->PackedSpecular, pShader->Specular);
+00412                         _DriverGLStates.setShininess(mat.getShininess());
+00413                         _DriverGLStates.setVertexColorLighted(mat.isLightedVertexColor ());
+00414                 }
+00415                 else
+00416                 {
+00417                         // Color unlit part.
+00418                         CRGBA   col= mat.getColor();
+00419                         glColor4ub(col.R, col.G, col.B, col.A);
+00420                         _DriverGLStates.setVertexColorLighted(false);
+00421                 }
+00422                 
+00423                 
+00424                 // Texture shader part.
+00425                 //=====================
+00426 
+00427                 if (_Extensions.NVTextureShader)
+00428                 {
+00429                         if (matShader == CMaterial::Normal)
+00430                         {
+00431                                 // Texture addressing modes (support only via NVTextureShader for now)
+00432                                 //===================================================================                                                           
+00433                                 if ( mat.getFlags() & IDRV_MAT_TEX_ADDR )
+00434                                 {               
+00435                                         enableNVTextureShader(true);
+00436 
+00437                                         GLenum glAddrMode;
+00438                                         for (stage = 0; stage < inlGetNumTextStages(); ++stage)
+00439                                         {                                                                               
+00440                                                 convTexAddr(mat.getTexture(stage), (CMaterial::TTexAddressingMode) (mat._TexAddrMode[stage]), glAddrMode);
+00441 
+00442                                                 if (glAddrMode != _CurrentTexAddrMode[stage]) // addressing mode different from the one in the device?
+00443                                         
+00444                                                 {
+00445                                                         _DriverGLStates.activeTextureARB(stage);
+00446                                                         glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, glAddrMode);                            
+00447                                                         _CurrentTexAddrMode[stage] = glAddrMode;                                        
+00448                                                 }
+00449                                         }                                                                                                               
+00450                                 }
+00451                                 else
+00452                                 {
+00453                                         enableNVTextureShader(false);
+00454                                 }                               
+00455                         }
+00456                         else 
+00457                         {
+00458                                 enableNVTextureShader(false);
+00459                         }
+00460                 }               
+00461 
+00462                 _CurrentMaterial=&mat;
+00463         }
+00464 
+00465 
+00466         // 4. Misc
+00467         //=====================================
+00468 
+00469         // If !lightMap and prec material was lihgtmap => vertex setup is dirty!
+00470         if( matShader != CMaterial::LightMap && _LastVertexSetupIsLightMap )
+00471                 resetLightMapVertexSetup();
+00472 
+00473         // Textures user matrix
+00474         if (matShader == CMaterial::Normal)
+00475         {
+00476                 setupUserTextureMatrix((uint) inlGetNumTextStages(), mat);              
+00477         }
+00478         else // deactivate texture matrix
+00479         {
+00480                 disableUserTextureMatrix();
+00481         }
+00482 
+00483         return true;
+00484 }
+00485 
+00486 
+00487 // ***************************************************************************
+00488 sint                    CDriverGL::beginMultiPass()
+00489 {
+00490         // Depending on material type and hardware, return number of pass required to draw this material.
+00491         switch(_CurrentMaterialSupportedShader)
+00492         {
+00493         case CMaterial::LightMap: 
+00494                 return  beginLightMapMultiPass();
+00495         case CMaterial::Specular: 
+00496                 return  beginSpecularMultiPass();
+00497         case CMaterial::PerPixelLighting:
+00498                 return  beginPPLMultiPass();
+00499         case CMaterial::PerPixelLightingNoSpec:
+00500                 return  beginPPLNoSpecMultiPass();      
+00501         /* case CMaterial::Caustics:
+00502                 return  beginCausticsMultiPass(); */
+00503         case CMaterial::Cloud:
+00504                 return  beginCloudMultiPass();
+00505 
+00506         // All others materials require just 1 pass.
+00507         default: return 1;
+00508         }
+00509 }
+00510 // ***************************************************************************
+00511 void                    CDriverGL::setupPass(uint pass)
+00512 {
+00513         switch(_CurrentMaterialSupportedShader)
+00514         {
+00515         case CMaterial::LightMap: 
+00516                 setupLightMapPass (pass);
+00517                 break;
+00518         case CMaterial::Specular: 
+00519                 setupSpecularPass (pass);
+00520                 break;
+00521         case CMaterial::PerPixelLighting:
+00522                 setupPPLPass (pass);
+00523                 break;
+00524         case CMaterial::PerPixelLightingNoSpec:
+00525                 setupPPLNoSpecPass (pass);
+00526                 break;  
+00527         /* case CMaterial::Caustics:
+00528                 case CMaterial::Caustics:
+00529                 break; */
+00530         case CMaterial::Cloud:
+00531                 setupCloudPass (pass);
+00532                 break;  
+00533 
+00534         // All others materials do not require multi pass.
+00535         default: return;
+00536         }
+00537 }
+00538 
+00539 
+00540 // ***************************************************************************
+00541 void                    CDriverGL::endMultiPass()
+00542 {
+00543         switch(_CurrentMaterialSupportedShader)
+00544         {
+00545         case CMaterial::LightMap: 
+00546                 endLightMapMultiPass();
+00547                 break;
+00548         case CMaterial::Specular: 
+00549                 endSpecularMultiPass();
+00550                 break;
+00551         case CMaterial::PerPixelLighting:
+00552                 endPPLMultiPass();
+00553                 break;
+00554         case CMaterial::PerPixelLightingNoSpec:
+00555                 endPPLNoSpecMultiPass();
+00556                 break;  
+00557         /* case CMaterial::Caustics:
+00558                 endCausticsMultiPass();
+00559                 break; */
+00560         case CMaterial::Cloud:
+00561                 endCloudMultiPass();
+00562                 break;  
+00563         // All others materials do not require multi pass.
+00564         default: return;
+00565         }
+00566 }
+00567 
+00568 
+00569 // ***************************************************************************
+00570 void CDriverGL::computeLightMapInfos (const CMaterial &mat)
+00571 {
+00572         static const uint32 RGBMaskPacked = CRGBA(255,255,255,0).getPacked();
+00573 
+00574         // For optimisation consideration, suppose there is not too much lightmap.
+00575         nlassert(mat._LightMaps.size()<=NL3D_DRV_MAX_LIGHTMAP);
+00576 
+00577         // Compute number of lightmaps really used (ie factor not NULL), and build the LUT.
+00578         _NLightMaps = 0;
+00579         // For all lightmaps of the material.
+00580         for (uint i = 0; i < mat._LightMaps.size(); ++i)
+00581         {
+00582                 // If the lightmap's factor is not null.
+00583                 if (mat._LightMaps[i].Factor.getPacked() & RGBMaskPacked)
+00584                 {
+00585                         _LightMapLUT[_NLightMaps] = i;
+00586                         ++_NLightMaps;
+00587                 }
+00588         }
+00589 
+00590         // Compute how many pass, according to driver caps.
+00591         _NLightMapPerPass = inlGetNumTextStages()-1;
+00592         // Can do more than 2 texture stages only if NVTextureEnvCombine4 or ATIXTextureEnvCombine3
+00593         if (!_Extensions.NVTextureEnvCombine4 || !_Extensions.ATIXTextureEnvCombine3)
+00594                 _NLightMapPerPass = 1;
+00595 
+00596         // Number of pass.
+00597         _NLightMapPass = (_NLightMaps + _NLightMapPerPass-1)/(_NLightMapPerPass);
+00598 
+00599         // NB: _NLightMaps==0 means there is no lightmaps at all.
+00600 }
+00601 
+00602 
+00603 // ***************************************************************************
+00604 sint CDriverGL::beginLightMapMultiPass ()
+00605 {
+00606         const CMaterial &mat= *_CurrentMaterial;
+00607 
+00608         // compute how many lightmap and pass we must process.
+00609         computeLightMapInfos (mat);
+00610 
+00611         // Too be sure, disable vertex coloring / lightmap.
+00612         _DriverGLStates.enableLighting(false);
+00613         // reset VertexColor array if necessary.
+00614         if (_LastVB.VertexFormat & CVertexBuffer::PrimaryColorFlag)
+00615                 _DriverGLStates.enableColorArray(false);
+00616 
+00617         // Manage too if no lightmaps.
+00618         return  std::max (_NLightMapPass, (uint)1);
+00619 }
+00620 // ***************************************************************************
+00621 void                    CDriverGL::setupLightMapPass(uint pass)
+00622 {
+00623         const CMaterial &mat= *_CurrentMaterial;
+00624 
+00625         // No lightmap or all blacks??, just setup "black texture" for stage 0.
+00626         if(_NLightMaps==0)
+00627         {
+00628                 ITexture        *text= mat.getTexture(0);
+00629                 activateTexture(0,text);
+00630 
+00631                 // setup std modulate env
+00632                 CMaterial::CTexEnv      env;
+00633                 activateTexEnvMode(0, env);
+00634                 // Since Lighting is disabled, as well as colorArray, must setup alpha.
+00635                 // setup color to 0 => blackness
+00636                 glColor4ub(0, 0, 0, 255);
+00637 
+00638                 // Setup gen tex off
+00639                 _DriverGLStates.activeTextureARB(0);
+00640                 _DriverGLStates.enableTexGen (0, false);
+00641 
+00642                 // And disable other stages.
+00643                 for(sint stage=1 ; stage<inlGetNumTextStages() ; stage++)
+00644                 {
+00645                         // disable texturing.
+00646                         activateTexture(stage, NULL);
+00647                 }
+00648 
+00649                 return;
+00650         }
+00651 
+00652         nlassert(pass<_NLightMapPass);
+00653 
+00654 
+00655         // setup Texture Pass.
+00656         //=========================
+00657         uint    lmapId;
+00658         uint    nstages;
+00659         lmapId= pass * _NLightMapPerPass; // Nb lightmaps already processed
+00660         // N lightmaps for this pass, plus the texture.
+00661         nstages= std::min(_NLightMapPerPass, _NLightMaps-lmapId) + 1;
+00662         // setup all stages.
+00663         for(uint stage= 0; stage<(uint)inlGetNumTextStages(); stage++)
+00664         {
+00665                 // if must setup a lightmap stage.
+00666                 if(stage<nstages-1)
+00667                 {
+00668                         // setup lightMap.
+00669                         uint    whichLightMap= _LightMapLUT[lmapId];
+00670                         // get text and factor.
+00671                         ITexture *text   = mat._LightMaps[whichLightMap].Texture;
+00672                         CRGBA lmapFactor = mat._LightMaps[whichLightMap].Factor;
+00673                         lmapFactor.A= 255;
+00674 
+00675                         activateTexture(stage,text);
+00676 
+00677                         // If texture not NULL, Change texture env fonction.
+00678                         //==================================================
+00679                         if(text)
+00680                         {
+00681                                 static CMaterial::CTexEnv       stdEnv;
+00682 
+00683                                 // NB, !_Extensions.NVTextureEnvCombine4, nstages==2, so here always stage==0.
+00684                                 if (stage==0)
+00685                                 {
+00686                                         // do not use consant color to blend lightmap, but incoming diffuse color, for stage0 only.
+00687                                         // (NB: lighting and vertexcolorArray are disabled here)
+00688                                         glColor4ub(lmapFactor.R, lmapFactor.G, lmapFactor.B, 255);
+00689 
+00690                                         // Leave stage as default env (Modulate with previous)
+00691                                         activateTexEnvMode(stage, stdEnv);
+00692 
+00693                                         // Setup gen tex off
+00694                                         _DriverGLStates.activeTextureARB(stage);
+00695                                         _DriverGLStates.enableTexGen (stage, false);
+00696                                 }
+00697                                 else
+00698                                 {
+00699                                         // Here, we are sure that texEnvCombine4 or texEnvCombine3 is OK.
+00700                                         nlassert(_Extensions.NVTextureEnvCombine4 || _Extensions.ATIXTextureEnvCombine3);
+00701 
+00702                                         // setup constant color with Lightmap factor.
+00703                                         stdEnv.ConstantColor=lmapFactor;
+00704                                         activateTexEnvColor(stage, stdEnv);
+00705 
+00706 
+00707                                         // TexEnv is special.
+00708                                         _CurrentTexEnvSpecial[stage] = TexEnvSpecialLightMap;
+00709 
+00710                                         // Setup env for texture stage.
+00711                                         _DriverGLStates.activeTextureARB(stage);
+00712 
+00713                                         // setup TexEnvCombine4 (ignore alpha part).
+00714                                         if(_CurrentTexEnvSpecial[stage] != TexEnvSpecialLightMap)
+00715                                         {
+00716                                                 if (_Extensions.NVTextureEnvCombine4)
+00717                                                 {                                                                                       
+00718                                                         // What we want to setup is  Texture*Constant + Previous*1.
+00719                                                         glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV);
+00720 
+00721                                                         // Operator.
+00722                                                         glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_ADD );
+00723                                                         glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_ADD );
+00724                                                         // Arg0.
+00725                                                         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE );
+00726                                                         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, GL_SRC_COLOR);
+00727                                                         // Arg1.
+00728                                                         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_CONSTANT_EXT );
+00729                                                         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, GL_SRC_COLOR);
+00730                                                         // Arg2.
+00731                                                         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_EXT, GL_PREVIOUS_EXT );
+00732                                                         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_EXT, GL_SRC_COLOR);
+00733                                                         // Arg3.
+00734                                                         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE3_RGB_NV, GL_ZERO);
+00735                                                         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND3_RGB_NV, GL_ONE_MINUS_SRC_COLOR);
+00736                                                 }                                                                                                                               
+00737                                                 else
+00738                                                 {
+00739                                                         // ATI EnvCombine3
+00740                                                         // What we want to setup is  Texture*Constant + Previous.
+00741                                                         glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
+00742                                                         // Operator.
+00743                                                         glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE_ADD_ATIX);
+00744                                                         glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_MODULATE_ADD_ATIX);                                          
+00745                                                         // Arg0.
+00746                                                         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE );
+00747                                                         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, GL_SRC_COLOR);
+00748                                                         // Arg1.
+00749                                                         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_CONSTANT_EXT );
+00750                                                         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, GL_SRC_COLOR);
+00751                                                         // Arg2.
+00752                                                         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_EXT, GL_PREVIOUS_EXT );
+00753                                                         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_EXT, GL_SRC_COLOR);
+00754                                                 }
+00755                                         }
+00756                                 }
+00757 
+00758                                 // setup UV, with UV1. Only if needed (cached)
+00759                                 if( !_LastVertexSetupIsLightMap || _LightMapUVMap[stage]!=1 )
+00760                                 {
+00761                                         setupUVPtr(stage, _LastVB, 1);
+00762                                         _LightMapUVMap[stage]= 1;
+00763                                 }
+00764                         }
+00765 
+00766                         // Next lightmap.
+00767                         lmapId++;
+00768                 }
+00769                 else if(stage<nstages)
+00770                 {
+00771                         // optim: do this only for first pass, and last pass only if stage!=nLMapPerPass 
+00772                         // (meaning not the same stage as preceding passes).
+00773                         if(pass==0 || (pass==_NLightMapPass-1 && stage!=_NLightMapPerPass))
+00774                         {
+00775                                 // activate the texture at last stage.
+00776                                 ITexture        *text= mat.getTexture(0);
+00777                                 activateTexture(stage,text);
+00778 
+00779                                 // setup ModulateRGB/ReplaceAlpha env. (this may disable possible COMBINE4_NV setup).
+00780                                 activateTexEnvMode(stage, _LightMapLastStageEnv);
+00781 
+00782                                 // Setup gen tex off
+00783                                 _DriverGLStates.activeTextureARB(stage);
+00784                                 _DriverGLStates.enableTexGen (stage, false);
+00785 
+00786                                 // setup UV, with UV0. Only if needed (cached)
+00787                                 if( !_LastVertexSetupIsLightMap || _LightMapUVMap[stage]!=0 )
+00788                                 {
+00789                                         setupUVPtr(stage, _LastVB, 0);
+00790                                         _LightMapUVMap[stage]= 0;
+00791                                 }
+00792                         }
+00793                 }
+00794                 else
+00795                 {
+00796                         // else all other stages are disabled.
+00797                         activateTexture(stage,NULL);
+00798                 }
+00799         }
+00800 
+00801 
+00802         // setup blend / lighting.
+00803         //=========================
+00804 
+00805         /* If multi-pass, then must setup a black Fog color for 1+ pass (just do it for the pass 1).
+00806                 This is because Transparency ONE/ONE is used.
+00807         */
+00808         if(pass==1 && _FogEnabled)
+00809         {
+00810                 static  GLfloat         blackFog[4]= {0,0,0,0};
+00811                 glFogfv(GL_FOG_COLOR, blackFog);
+00812         }
+00813 
+00814         // Blend is different if the material is blended or not
+00815         if( !mat.getBlend() )
+00816         {
+00817                 // Not blended, std case.
+00818                 if(pass==0)
+00819                 {
+00820                         // no transparency for first pass.
+00821                         _DriverGLStates.enableBlend(false);
+00822                 }
+00823                 else if(pass==1)
+00824                 {
+00825                         // setup an Additive transparency (only for pass 1, will be kept for successives pass).
+00826                         _DriverGLStates.enableBlend(true);
+00827                         _DriverGLStates.blendFunc(GL_ONE, GL_ONE);
+00828                 }
+00829         }
+00830         else
+00831         {
+00832                 /* 1st pass, std alphaBlend. 2nd pass, add to background. Demo:
+00833                         T: texture.
+00834                         l0: lightmap (or group of lightmap) of pass 0.
+00835                         l1: lightmap (or group of lightmap) of pass 1. (same thing with 2,3 etc....)
+00836                         B:      Background.
+00837                         A:      Alpha of texture.
+00838 
+00839                         finalResult= T*(l0+l1) * A + B * (1-A).
+00840 
+00841                         We get it in two pass:
+00842                                 fint=                   T*l0 * A + B * (1-A).
+00843                                 finalResult=    T*l1 * A + fint = T*l1 * A + T*l0 * A + B * (1-A)=
+00844                                         T* (l0+l1) * A + B * (1-A)
+00845                 */
+00846                 if(pass==0)
+00847                 {
+00848                         // no transparency for first pass.
+00849                         _DriverGLStates.enableBlend(true);
+00850                         _DriverGLStates.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+00851                 }
+00852                 else if(pass==1)
+00853                 {
+00854                         // setup an Additive transparency (only for pass 1, will be kept for successives pass).
+00855                         _DriverGLStates.enableBlend(true);
+00856                         _DriverGLStates.blendFunc(GL_SRC_ALPHA, GL_ONE);
+00857                 }
+00858         }
+00859 
+00860 }
+00861 // ***************************************************************************
+00862 void                    CDriverGL::endLightMapMultiPass()
+00863 {
+00864         // Cache it. reseted in setupGLArrays(), and setupMaterial()
+00865         _LastVertexSetupIsLightMap= true;
+00866 
+00867         // If multi-pass, then must reset the fog color
+00868         if(_NLightMapPass>=2 && _FogEnabled)
+00869         {
+00870                 glFogfv(GL_FOG_COLOR, _CurrentFogColor);
+00871         }
+00872 
+00873         // nothing to do with blending/lighting, since always setuped in activeMaterial().
+00874         // If material is the same, then it is still a lightmap material (if changed => touched => different!)
+00875         // So no need to reset lighting/blending here.
+00876 }
+00877 
+00878 
+00879 // ***************************************************************************
+00880 void                    CDriverGL::resetLightMapVertexSetup()
+00881 {
+00882         // special for all stage, std UV behavior.
+00883         for(sint i=0; i<inlGetNumTextStages(); i++)
+00884         {
+00885                 // normal behavior: each texture has its own UV.
+00886                 setupUVPtr(i, _LastVB, i);
+00887                 // reset cache
+00888                 _LightMapUVMap[i]= -1;
+00889         }
+00890 
+00891         // pop VertexColor array if necessary.
+00892         if (_LastVB.VertexFormat & CVertexBuffer::PrimaryColorFlag)
+00893                 _DriverGLStates.enableColorArray(true);
+00894 
+00895         // flag
+00896         _LastVertexSetupIsLightMap= false;
+00897 }
+00898 
+00899 
+00900 // ***************************************************************************
+00901 sint                    CDriverGL::beginSpecularMultiPass()
+00902 {
+00903         const CMaterial &mat= *_CurrentMaterial;
+00904 
+00905         _DriverGLStates.activeTextureARB(1);
+00906         glMatrixMode(GL_TEXTURE);
+00907         glLoadMatrixf( _TexMtx.get() );
+00908         glMatrixMode(GL_MODELVIEW);
+00909 
+00910         // Manage the rare case when the SpecularMap is not provided (fault of graphist).
+00911         if(mat.getTexture(1)==NULL)
+00912                 return 1;
+00913 
+00914         if(!_Extensions.ARBTextureCubeMap)
+00915                 return 1;
+00916 
+00917         if( _Extensions.NVTextureEnvCombine4 || _Extensions.ATIXTextureEnvCombine3) // NVidia or ATI optimization
+00918                 return 1;
+00919         else
+00920                 return 2;
+00921 
+00922 }
+00923 // ***************************************************************************
+00924 void                    CDriverGL::setupSpecularPass(uint pass)
+00925 {
+00926         const CMaterial &mat= *_CurrentMaterial;
+00927 
+00928         // Manage the rare case when the SpecularMap is not provided (error of a graphist).
+00929         if(mat.getTexture(1)==NULL)
+00930         {
+00931                 // Just display the texture forcing no blend (as in std case).
+00932                 // NB: setupMaterial() code has correclty setuped textures.
+00933                 _DriverGLStates.enableBlend(false);
+00934                 return;
+00935         }
+00936 
+00938         if( _Extensions.NVTextureEnvCombine4 )
+00939         {       // Ok we can do it in a single pass
+00940                 _DriverGLStates.enableBlend(false);
+00941 
+00942                 // Stage 0
+00943                 if(_CurrentTexEnvSpecial[0] != TexEnvSpecialSpecularStage0)
+00944                 {
+00945                         // TexEnv is special.
+00946                         _CurrentTexEnvSpecial[0] = TexEnvSpecialSpecularStage0;
+00947 
+00948                         _DriverGLStates.activeTextureARB(0);
+00949                         glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV);
+00950                         // Operator.
+00951                         glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_ADD );
+00952                         glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_ADD );
+00953                         // Arg0.
+00954                         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE );
+00955                         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, GL_SRC_COLOR );
+00956                         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE );
+00957                         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_EXT, GL_SRC_ALPHA );
+00958                         // Arg1.
+00959                         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT);
+00960                         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, GL_SRC_COLOR);
+00961                         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_EXT, GL_ZERO );
+00962                         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_EXT, GL_ONE_MINUS_SRC_ALPHA );
+00963                         // Arg2.
+00964                         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_EXT, GL_ZERO );
+00965                         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_EXT, GL_SRC_COLOR );
+00966                         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA_EXT, GL_ZERO );
+00967                         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA_EXT, GL_SRC_ALPHA );
+00968                         // Arg3.
+00969                         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE3_RGB_NV, GL_ZERO );
+00970                         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND3_RGB_NV, GL_SRC_COLOR);
+00971                         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE3_ALPHA_NV, GL_ZERO );
+00972                         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND3_ALPHA_NV, GL_SRC_ALPHA );
+00973                         // Result RGB : Texture*Diffuse, Alpha : Texture
+00974                 }
+00975 
+00976                 // Set Stage 1
+00977                 // Special: not the same sepcial env if there is or not texture in stage 0.
+00978                 CTexEnvSpecial          newEnvStage1;
+00979                 if( mat.getTexture(0) == NULL )
+00980                         newEnvStage1= TexEnvSpecialSpecularStage1NoText;
+00981                 else
+00982                         newEnvStage1= TexEnvSpecialSpecularStage1;
+00983                 // Test if same env as prec.
+00984                 if(_CurrentTexEnvSpecial[1] != newEnvStage1)
+00985                 {
+00986                         // TexEnv is special.
+00987                         _CurrentTexEnvSpecial[1] = newEnvStage1;
+00988 
+00989                         _DriverGLStates.activeTextureARB(1);
+00990                         glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV);
+00991                         // Operator Add (Arg0*Arg1+Arg2*Arg3)
+00992                         glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_ADD );
+00993                         glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_ADD );
+00994                         // Arg0.
+00995                         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE );
+00996                         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, GL_SRC_COLOR );
+00997                         // Arg1.
+00998                         if( newEnvStage1 == TexEnvSpecialSpecularStage1NoText )
+00999                         {
+01000                                 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_ZERO );
+01001                                 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, GL_ONE_MINUS_SRC_COLOR);
+01002                         }
+01003                         else
+01004                         {
+01005                                 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT );
+01006                                 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, GL_SRC_ALPHA );
+01007                         }
+01008                         // Arg2.
+01009                         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_EXT, GL_PREVIOUS_EXT );
+01010                         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_EXT, GL_SRC_COLOR );
+01011                         // Arg3.
+01012                         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE3_RGB_NV, GL_ZERO );
+01013                         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND3_RGB_NV, GL_ONE_MINUS_SRC_COLOR);
+01014                         // Result : Texture*Previous.Alpha+Previous
+01015                 }
+01016 
+01017                 // Setup TexCoord gen for stage1.
+01018                 _DriverGLStates.activeTextureARB(1);
+01019                 _DriverGLStates.setTextureMode(CDriverGLStates::TextureCubeMap);
+01020                 _DriverGLStates.setTexGenMode (1, GL_REFLECTION_MAP_ARB);
+01021                 _DriverGLStates.enableTexGen (1, true);
+01022         }
+01023         else if (_Extensions.ATIXTextureEnvCombine3)
+01024         {
+01025                 // Ok we can do it in a single pass
+01026                 _DriverGLStates.enableBlend(false);
+01027 
+01028                 // Stage 0
+01029                 if(_CurrentTexEnvSpecial[0] != TexEnvSpecialSpecularStage0)
+01030                 {
+01031                         // TexEnv is special.
+01032                         _CurrentTexEnvSpecial[0] = TexEnvSpecialSpecularStage0;
+01033 
+01034                         _DriverGLStates.activeTextureARB(0);            
+01035                         glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
+01036                         // Operator Mad (Arg0 * Arg2 + Arg1)                    
+01037                         glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE );
+01038                         glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE );
+01039                         // Arg0.
+01040                         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE );
+01041                         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, GL_SRC_COLOR );
+01042                         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE );
+01043                         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_EXT, GL_SRC_ALPHA );
+01044                         // Arg1.
+01045                         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT);
+01046                         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, GL_SRC_COLOR);                   
+01047                         // Result RGB : Texture*Diffuse, Alpha : Texture
+01048                 }
+01049 
+01050                 // Set Stage 1
+01051                 // Special: not the same sepcial env if there is or not texture in stage 0.
+01052                 CTexEnvSpecial          newEnvStage1;
+01053                 if( mat.getTexture(0) == NULL )
+01054                         newEnvStage1= TexEnvSpecialSpecularStage1NoText;
+01055                 else
+01056                         newEnvStage1= TexEnvSpecialSpecularStage1;
+01057                 // Test if same env as prec.
+01058                 if(_CurrentTexEnvSpecial[1] != newEnvStage1)
+01059                 {
+01060                         // TexEnv is special.
+01061                         _CurrentTexEnvSpecial[1] = newEnvStage1;
+01062 
+01063                         _DriverGLStates.activeTextureARB(1);
+01064                         glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
+01065                         // Operator Add (Arg0*Arg1+Arg2*Arg3)
+01066                         glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE_ADD_ATIX );
+01067                         glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_MODULATE_ADD_ATIX );
+01068                         // Arg0.
+01069                         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE );
+01070                         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, GL_SRC_COLOR );
+01071                         // Arg2.
+01072                         if( newEnvStage1 == TexEnvSpecialSpecularStage1NoText )
+01073                         {
+01074                                 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_EXT, GL_ZERO );
+01075                                 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_EXT, GL_ONE_MINUS_SRC_COLOR);
+01076                         }
+01077                         else
+01078                         {
+01079                                 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_EXT, GL_PREVIOUS_EXT );
+01080                                 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_EXT, GL_SRC_ALPHA );
+01081                         }
+01082                         // Arg1.
+01083                         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT );
+01084                         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, GL_SRC_COLOR );                  
+01085                         // Result : Texture*Previous.Alpha+Previous
+01086                 }
+01087 
+01088                 // Setup TexCoord gen for stage1.
+01089                 _DriverGLStates.activeTextureARB(1);
+01090                 _DriverGLStates.setTextureMode(CDriverGLStates::TextureCubeMap);
+01091                 _DriverGLStates.setTexGenMode (1, GL_REFLECTION_MAP_ARB);
+01092                 _DriverGLStates.enableTexGen (1, true);
+01093         }
+01094         else
+01095         { // We have to do it in 2 passes
+01096 
+01097                 if( pass == 0 )
+01098                 { // Just display the texture
+01099                         _DriverGLStates.enableBlend(false);
+01100                         _DriverGLStates.activeTextureARB(1);
+01101                         _DriverGLStates.setTextureMode(CDriverGLStates::TextureDisabled);
+01102                 }
+01103                 else
+01104                 { // Multiply texture1 by alpha_texture0 and display with add
+01105                         _DriverGLStates.enableBlend(true);
+01106                         _DriverGLStates.blendFunc(GL_ONE, GL_ONE);
+01107 
+01108                         // Set stage 0
+01109                         _DriverGLStates.activeTextureARB(0);
+01110                         CMaterial::CTexEnv      env;
+01111 
+01112                         env.Env.OpRGB = CMaterial::Replace;
+01113                         env.Env.SrcArg0RGB = CMaterial::Texture;
+01114                         env.Env.OpArg0RGB = CMaterial::SrcAlpha;
+01115 
+01116                         activateTexEnvMode(0, env);
+01117 
+01118 
+01119                         // Set stage 1
+01120                         if( mat.getTexture(0) == NULL )
+01121                         {
+01122                                 env.Env.OpRGB = CMaterial::Replace;
+01123                                 env.Env.SrcArg0RGB = CMaterial::Texture;
+01124                                 env.Env.OpArg0RGB = CMaterial::SrcColor;
+01125                         }
+01126                         else
+01127                         {
+01128                                 env.Env.OpRGB = CMaterial::Modulate;
+01129                                 env.Env.SrcArg0RGB = CMaterial::Texture;
+01130                                 env.Env.OpArg0RGB = CMaterial::SrcColor;
+01131                         
+01132                                 env.Env.SrcArg1RGB = CMaterial::Previous;
+01133                                 env.Env.OpArg1RGB = CMaterial::SrcColor;
+01134                         }
+01135 
+01136                         activateTexEnvMode(1, env);
+01137 
+01138                         // Set Stage 1
+01139                         _DriverGLStates.activeTextureARB(1);
+01140                         _DriverGLStates.setTextureMode(CDriverGLStates::TextureCubeMap);
+01141                         _DriverGLStates.setTexGenMode (1, GL_REFLECTION_MAP_ARB);
+01142                         _DriverGLStates.enableTexGen (1, true);
+01143                 }
+01144         }
+01145 }
+01146 // ***************************************************************************
+01147 void                    CDriverGL::endSpecularMultiPass()
+01148 {
+01149         // Disable Texture coord generation.
+01150         _DriverGLStates.activeTextureARB(1);
+01151         _DriverGLStates.enableTexGen (1, false);
+01152         //_DriverGLStates.setTextureMode(1, CDriverGLStates::TextureDisabled);
+01153 
+01154         // Happiness !!! we have already enabled the stage 1
+01155         glMatrixMode(GL_TEXTURE);
+01156         glLoadIdentity();
+01157         glMatrixMode(GL_MODELVIEW);
+01158 }
+01159 
+01160 
+01161 // a functor that can is used to generate a cube map used for specular / diffuse lighting
+01162 struct CSpecCubeMapFunctor : ICubeMapFunctor
+01163 {
+01164         CSpecCubeMapFunctor(float exp) : Exp(exp) {}
+01165         virtual NLMISC::CRGBA operator()(const NLMISC::CVector &v)
+01166         {
+01167                 
+01168                 uint8 intensity = (uint8) (255.f * ::powf(std::max(v.normed().z, 0.f), Exp));
+01169                 return NLMISC::CRGBA(intensity, intensity, intensity, intensity);               
+01170                 //return Exp == 1.f ? CRGBA((uint8)(v.x*127+127), (uint8)(v.y*127+127), (uint8)(v.z*127+127), 0): CRGBA::Black;
+01171         }
+01172         float Exp;
+01173 };
+01174 
+01175 
+01176 /* 
+01177 const uint MaxSpecularExp = 64;
+01178 const uint SpecularExpStep = 8;
+01179 const uint SpecularMapSize = 32; */
+01180 
+01181 
+01182 // ***************************************************************************
+01183 CTextureCube    *CDriverGL::getSpecularCubeMap(uint exp)
+01184 {
+01185         const uint SpecularMapSize = 32;
+01186         const uint SpecularMapSizeHighExponent = 64;
+01187         const float HighExponent = 128.f;
+01188         const uint MaxExponent = 512;
+01189         // this gives the cube map to use given an exponent (from 0 to 128)
+01190         static uint16 expToCubeMap[MaxExponent];        
+01191         // this gives the exponent used by a given cube map (not necessarily ordered)
+01192         static float cubeMapExp[] = 
+01193         {
+01194                 1.f, 4.f, 8.f, 24.f, 48.f, 128.f, 256.f, 511.f
+01195         };
+01196         const uint numCubeMap = sizeof(expToCubeMap) / sizeof(float);
+01197         static bool tableBuilt = false;
+01198 
+01199         if (!tableBuilt)
+01200         {
+01201                 for (uint k = 0; k < MaxExponent; ++k)
+01202                 {                       
+01203                         uint nearest = 0;
+01204                         float diff = (float) MaxExponent;
+01205                         // look for the nearest exponent
+01206                         for (uint l = 0; l < numCubeMap; ++l)
+01207                         {
+01208                                 float newDiff = ::fabsf(k - cubeMapExp[l]);
+01209                                 if (newDiff < diff)
+01210                                 {
+01211                                         diff = newDiff;
+01212                                         nearest = l;
+01213                                 }
+01214                         }
+01215                         expToCubeMap[k] = nearest;
+01216                 }
+01217                 tableBuilt = true;              
+01218         }
+01219 
+01220         if (_SpecularTextureCubes.empty())
+01221         {
+01222                 _SpecularTextureCubes.resize(MaxExponent);
+01223         }
+01224 
+01225                 
+01226         NLMISC::clamp(exp, 1u, (MaxExponent - 1));
+01227 
+01228 
+01229         uint cubeMapIndex = expToCubeMap[(uint) exp];
+01230         nlassert(cubeMapIndex < numCubeMap);    
+01231         
+01232         
+01233         if (_SpecularTextureCubes[cubeMapIndex] != NULL) // has the cube map already been cted ?
+01234         { 
+01235                 return _SpecularTextureCubes[cubeMapIndex]; 
+01236         }
+01237         else // build the cube map
+01238         {               
+01239                 float exponent    = cubeMapExp[cubeMapIndex];
+01240                 CSpecCubeMapFunctor scmf(exponent);
+01241                 const uint bufSize = 128;
+01242                 char name[bufSize];
+01243                 NLMISC::smprintf(name, bufSize, "#SM%d", cubeMapIndex);
+01244                 CTextureCube *tc = BuildCubeMap(exponent >= HighExponent ? SpecularMapSizeHighExponent
+01245                                                                                                                                 : SpecularMapSize,
+01246                                                                                 scmf,
+01247                                                                                 false,
+01248                                                                                 name);
+01249 
+01250                 static const CTextureCube::TFace numToFace[] =
+01251                 { CTextureCube::positive_x,
+01252                   CTextureCube::negative_x, 
+01253                   CTextureCube::positive_y, 
+01254                   CTextureCube::negative_y, 
+01255                   CTextureCube::positive_z, 
+01256                   CTextureCube::negative_z 
+01257                 };
+01258 
+01259                 if (exponent != 1.f)
+01260                 {
+01261                         // force 16 bit for specular part, 32 bit if exponent is 1 (diffuse part)
+01262                         for (uint k = 0; k < 6; ++k)
+01263                         {
+01264                                 nlassert(tc->getTexture(numToFace[k]));
+01265                                 tc->getTexture(numToFace[k])->setUploadFormat(ITexture::RGB565);
+01266                         }
+01267                 }
+01268 
+01269                 _SpecularTextureCubes[cubeMapIndex] = tc;
+01270                 return tc;
+01271         }
+01272 }
+01273 
+01274 // ***************************************************************************
+01275 sint                    CDriverGL::beginPPLMultiPass()
+01276 {
+01277         #ifdef NL_DEBUG
+01278                 nlassert(supportPerPixelLighting(true)); // make sure the hardware can do that
+01279         #endif
+01280         return 1;
+01281 }
+01282 
+01283 // ***************************************************************************
+01284 void                    CDriverGL::setupPPLPass(uint pass)
+01285 {
+01286         const CMaterial &mat= *_CurrentMaterial;
+01287 
+01288         nlassert(pass == 0);
+01289 
+01290 /*      ITexture *tex0 = getSpecularCubeMap(1);
+01291         if (tex0) setupTexture(*tex0);
+01292         activateTexture(0, tex0);
+01293         
+01294 
+01295         static CMaterial::CTexEnv       env;
+01296         env.Env.SrcArg0Alpha = CMaterial::Diffuse;              
+01297         env.Env.SrcArg1Alpha = CMaterial::Constant;             
+01298         env.Env.SrcArg0RGB = CMaterial::Diffuse;        
+01299         env.Env.SrcArg1RGB = CMaterial::Constant;
+01300         env.Env.OpRGB = CMaterial::Replace;
+01301         env.Env.OpAlpha = CMaterial::Replace;
+01302         activateTexEnvMode(0, env);
+01303 
+01304         return;*/
+01305 
+01306         ITexture *tex0 = getSpecularCubeMap(1); 
+01307         if (tex0) setupTexture(*tex0);
+01308         ITexture *tex2 = getSpecularCubeMap((uint) mat.getShininess());
+01309         if (tex2) setupTexture(*tex2);
+01310         if (mat.getTexture(0)) setupTexture(*mat.getTexture(0));
+01311 
+01312         // tex coord 0 = texture coordinates
+01313         // tex coord 1 = normal in tangent space
+01314         // tex coord 2 = half angle vector in tangent space
+01315 
+01316         activateTexture(0, tex0);
+01317         activateTexture(1, mat.getTexture(0));
+01318         activateTexture(2, tex2);
+01319 
+01320         for (uint k = 3; k < (uint) inlGetNumTextStages(); ++k)
+01321         {
+01322                 activateTexture(k, NULL);
+01323         }
+01324 
+01325         // setup the tex envs
+01326 
+01327 
+01328         // Stage 0 is rgb = DiffuseCubeMap * LightColor + DiffuseGouraud * 1 (TODO : EnvCombine3)
+01329         if(_CurrentTexEnvSpecial[0] != TexEnvSpecialPPLStage0)
+01330         {
+01331                 // TexEnv is special.
+01332                 _CurrentTexEnvSpecial[0] = TexEnvSpecialPPLStage0;
+01333                 _DriverGLStates.activeTextureARB(0);
+01334 
+01335                 if (_Extensions.NVTextureEnvCombine4)
+01336                 {               
+01337                         glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV);
+01338                         
+01339                         glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_ADD);                  
+01340                         // Arg0 = Diffuse read in cube map
+01341                         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE);
+01342                         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, GL_SRC_COLOR);
+01343                         // Arg1 = Light color
+01344                         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_CONSTANT_EXT);
+01345                         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, GL_SRC_COLOR);
+01346                         // Arg2 = Primary color (other light diffuse and 
+01347                         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_EXT, GL_PRIMARY_COLOR_EXT);
+01348                         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_EXT, GL_SRC_COLOR);
+01349                         // Arg3 = White (= ~ Black)
+01350                         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE3_RGB_NV, GL_ZERO);
+01351                         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND3_RGB_NV, GL_ONE_MINUS_SRC_COLOR);
+01352                 }
+01353                 else // use ATI extension
+01354                 {
+01355                         glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
+01356                         
+01357                         glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE_ADD_ATIX);                    
+01358                         // Arg0 = Diffuse read in cube map
+01359                         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE);
+01360                         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, GL_SRC_COLOR);
+01361                         // Arg1 = Light color
+01362                         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_EXT, GL_CONSTANT_EXT);
+01363                         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_EXT, GL_SRC_COLOR);
+01364                         // Arg2 = Primary color (other light diffuse and 
+01365                         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PRIMARY_COLOR_EXT);
+01366                         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, GL_SRC_COLOR);                   
+01367                 }
+01368         }
+01369         activateTexEnvColor(0, _PPLightDiffuseColor);
+01370 
+01371         // Stage 1      
+01372         static CMaterial::CTexEnv       env;
+01373         env.Env.SrcArg1Alpha = CMaterial::Diffuse;              
+01374         activateTexEnvMode(1, env);
+01375 
+01376 
+01377 
+01378         // Stage 2 is rgb = SpecularCubeMap * SpecularLightColor + Prec * 1
+01379         // alpha = prec alpha
+01380         
+01381         if(_CurrentTexEnvSpecial[2] != TexEnvSpecialPPLStage2)
+01382         {
+01383                 // TexEnv is special.
+01384                 _CurrentTexEnvSpecial[2] = TexEnvSpecialPPLStage2;
+01385                 _DriverGLStates.activeTextureARB(2);
+01386 
+01387                 if (_Extensions.NVTextureEnvCombine4)
+01388                 {
+01389                         glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV);         
+01390                         //== colors ==
+01391                         glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_ADD);
+01392                         // Arg0 = Specular read in cube map
+01393                         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE);
+01394                         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, GL_SRC_COLOR);
+01395                         // Arg1 = Light color
+01396                         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_CONSTANT_EXT);
+01397                         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, GL_SRC_COLOR);
+01398                         // Arg2 = Primary color ( + other light diffuse )
+01399                         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_EXT, GL_PREVIOUS_EXT);
+01400                         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_EXT, GL_SRC_COLOR);
+01401                         // Arg3 = White (= ~ Black)
+01402                         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE3_RGB_NV, GL_ZERO);
+01403                         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND3_RGB_NV, GL_ONE_MINUS_SRC_COLOR);
+01404 
+01405                         //== alpha ==
+01406                         glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_ADD);                        
+01407                         // Arg0 = PREVIOUS ALPHA
+01408                         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_PREVIOUS_EXT);
+01409                         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_EXT, GL_SRC_COLOR);
+01410                         // Arg1 = 1
+01411                         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_EXT, GL_ZERO);
+01412                         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_EXT, GL_ONE_MINUS_SRC_COLOR);
+01413                         // Arg2 = 0
+01414                         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA_EXT, GL_ZERO);
+01415                         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA_EXT, GL_SRC_COLOR);
+01416                         // Arg3 = 0
+01417                         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE3_ALPHA_NV, GL_ZERO);
+01418                         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND3_ALPHA_NV, GL_SRC_COLOR);
+01419                 }
+01420                 else // ATI EnvCombine3
+01421                 {
+01422                         glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);         
+01423                         //== colors ==
+01424                         glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE_ADD_ATIX);                    
+01425                         // Arg0 = Specular read in cube map
+01426                         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE);
+01427                         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, GL_SRC_COLOR);
+01428                         // Arg2 = Light color
+01429                         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_EXT, GL_CONSTANT_EXT);
+01430                         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_EXT, GL_SRC_COLOR);
+01431                         // Arg1 = Primary color ( + other light diffuse)
+01432                         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_EXT, GL_PREVIOUS_EXT);
+01433                         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_EXT, GL_SRC_COLOR);                   
+01434 
+01435                         //== alpha ==
+01436                         glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_MODULATE_ADD_ATIX);                  
+01437                         // Arg0 = PREVIOUS ALPHA
+01438                         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_PREVIOUS_EXT);
+01439                         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_EXT, GL_SRC_COLOR);
+01440                         // Arg2 = 1
+01441                         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA_EXT, GL_ZERO);
+01442                         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA_EXT, GL_ONE_MINUS_SRC_COLOR);
+01443                         // Arg1 = 0
+01444                         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_EXT, GL_ZERO);
+01445                         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_EXT, GL_SRC_COLOR);
+01446                 }
+01447         }
+01448         activateTexEnvColor(2, _PPLightSpecularColor);  
+01449 
+01450 }
+01451 
+01452 // ***************************************************************************
+01453 void                    CDriverGL::endPPLMultiPass()
+01454 {       
+01455         // nothing to do there ...
+01456 }
+01457 
+01458 
+01459 // ******PER PIXEL LIGHTING, NO SPECULAR**************************************
+01460 sint                    CDriverGL::beginPPLNoSpecMultiPass()
+01461 {
+01462         #ifdef NL_DEBUG
+01463                 nlassert(supportPerPixelLighting(false)); // make sure the hardware can do that
+01464         #endif
+01465         return 1;
+01466 }
+01467 
+01468 // ******PER PIXEL LIGHTING, NO SPECULAR**************************************
+01469 void                    CDriverGL::setupPPLNoSpecPass(uint pass)
+01470 {
+01471         const CMaterial &mat= *_CurrentMaterial;
+01472 
+01473         nlassert(pass == 0);
+01474 
+01475         ITexture *tex0 = getSpecularCubeMap(1);
+01476         if (tex0) setupTexture(*tex0);
+01477         
+01478         if (mat.getTexture(0)) setupTexture(*mat.getTexture(0));
+01479 
+01480         // tex coord 0 = texture coordinates
+01481         // tex coord 1 = normal in tangent space        
+01482 
+01483         activateTexture(0, tex0);
+01484         activateTexture(1, mat.getTexture(0));
+01485 
+01486 
+01487         for (uint k = 2; k < (uint) inlGetNumTextStages(); ++k)
+01488         {
+01489                 activateTexture(k, NULL);
+01490         }
+01491 
+01492         // setup the tex envs
+01493 
+01494 
+01495         // Stage 0 is rgb = DiffuseCubeMap * LightColor + DiffuseGouraud * 1 (TODO : EnvCombine3)
+01496         if(_CurrentTexEnvSpecial[0] != TexEnvSpecialPPLStage0)
+01497         {
+01498                 // TexEnv is special.
+01499                 _CurrentTexEnvSpecial[0] = TexEnvSpecialPPLStage0;
+01500                 _DriverGLStates.activeTextureARB(0);
+01501 
+01502                 if (_Extensions.NVTextureEnvCombine4)
+01503                 {
+01504                         glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV);
+01505                         
+01506                         glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_ADD);                  
+01507                         // Arg0 = Diffuse read in cube map alpha
+01508                         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE);
+01509                         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, GL_SRC_COLOR);
+01510                         // Arg1 = Light color
+01511                         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_CONSTANT_EXT);
+01512                         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, GL_SRC_COLOR);
+01513                         // Arg2 = Primary color (other light diffuse and 
+01514                         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_EXT, GL_PRIMARY_COLOR_EXT);
+01515                         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_EXT, GL_SRC_COLOR);
+01516                         // Arg3 = White (= ~ Black)
+01517                         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE3_RGB_NV, GL_ZERO);
+01518                         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND3_RGB_NV, GL_ONE_MINUS_SRC_COLOR);
+01519                 }
+01520                 else
+01521                 {
+01522                         glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
+01523                         
+01524                         glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE_ADD_ATIX);                    
+01525                         // Arg0 = Diffuse read in cube map alpha
+01526                         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE);
+01527                         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, GL_SRC_COLOR);
+01528                         // Arg2 = Light color
+01529                         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_EXT, GL_CONSTANT_EXT);
+01530                         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_EXT, GL_SRC_COLOR);
+01531                         // Arg1 = Primary color (other light diffuse and 
+01532                         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PRIMARY_COLOR_EXT);
+01533                         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, GL_SRC_COLOR);                   
+01534                 }
+01535         }
+01536         activateTexEnvColor(0, _PPLightDiffuseColor);
+01537 
+01538         // Stage 1      
+01539         static CMaterial::CTexEnv       env;
+01540         env.Env.SrcArg1Alpha = CMaterial::Diffuse;              
+01541         activateTexEnvMode(1, env);
+01542 
+01543 }
+01544 
+01545 // ******PER PIXEL LIGHTING, NO SPECULAR**************************************
+01546 void                    CDriverGL::endPPLNoSpecMultiPass()
+01547 {       
+01548         // nothing to do there ...
+01549 }
+01550 
+01551 // ***************************************************************************
+01552 /* sint         CDriverGL::beginCausticsMultiPass(const CMaterial &mat)
+01553 {
+01554         nlassert(mat.getShader() == CMaterial::Caustics);
+01555         if (!_Extensions.ARBTextureCubeMap) return 1;
+01556         switch (inlGetNumTextStages())
+01557         {
+01558                 case 1: return 3;
+01559                 case 2: return 2;
+01560                 default:
+01561                                 return 1;
+01562         }
+01563 }*/
+01564 
+01565 
+01566 // ***************************************************************************
+01567 /*inline void           CDriverGL::setupCausticsFirstTex(const CMaterial &mat)
+01568 {
+01570         activateTexture(0, mat.getTexture(0));
+01571 
+01573         setTextureEnvFunction(0, mat);
+01574 
+01576         setupUserTextureMatrix(0, mat);
+01577 }
+01578 
+01579 // ***************************************************************************
+01580 inline void             CDriverGL::setupCausticsSecondTex(uint stage)
+01581 {
+01582         activateTexture(stage, mat.getTexture(0));
+01583         _CausticCubeMap
+01584 }
+01585 
+01586 // ***************************************************************************
+01587 void            CDriverGL::setupCausticsPass(const CMaterial &mat, uint pass)
+01588 {
+01589         
+01590         nlassert(mat.getShader() == CMaterial::Caustics);
+01591 
+01592         if (inlGetNumTextStages() == 1 || !_Extensions.ARBTextureCubeMap)
+01593         {
+01594                 setupCausticsFirstTex(mat);
+01595         }
+01596         else
+01597         if (inlGetNumTextStages() >= 3) 
+01598         {
+01599                 nlassert(pass == 0);            
+01600 
+01601                 setupCausticsFirstTex(mat);
+01602                 
+01603 
+01604         }
+01605         else if (inlGetNumTextStages() == 2) 
+01606         {
+01607                 nlassert(pass < 2);
+01608                 if (pass == 0) 
+01609                 {
+01610                         setupCausticsFirstTex(mat);     
+01611                 }
+01612                 else 
+01613                 {
+01615                         _DriverGLStates.enableBlend();                  
+01616                         _DriverGLStates.blendFunc(pShader->SrcBlend, pShader->DstBlend);
+01617 
+01618 
+01619                 }
+01620         }
+01621 }
+01622 
+01623 // ***************************************************************************
+01624 void            CDriverGL::endCausticsMultiPass(const CMaterial &mat)
+01625 {
+01626         nlassert(mat.getShader() == CMaterial::Caustics);       
+01627 
+01628 }
+01629 */
+01630 
+01632 
+01633 // ***************************************************************************
+01634 sint            CDriverGL::beginCloudMultiPass ()
+01635 {
+01636         nlassert(_CurrentMaterial->getShader() == CMaterial::Cloud);
+01637         return 1;
+01638 }
+01639 
+01640 // ***************************************************************************
+01641 void            CDriverGL::setupCloudPass (uint pass)
+01642 {
+01643         nlassert(_CurrentMaterial->getShader() == CMaterial::Cloud);
+01644 
+01645         const CMaterial &mat= *_CurrentMaterial;
+01646         
+01647         activateTexture(0, mat.getTexture(0));
+01648         activateTexture(1, mat.getTexture(0));
+01649 
+01650         if (_CurrentTexEnvSpecial[0] != TexEnvSpecialCloudStage0)
+01651         {
+01652                 _CurrentTexEnvSpecial[0] = TexEnvSpecialCloudStage0;
+01653                 _CurrentTexEnvSpecial[1] = TexEnvSpecialCloudStage1;
+01654 
+01655                 if (_Extensions.NVTextureEnvCombine4)
+01656                 {
+01657                         // Setup 1st Stage
+01658                         _DriverGLStates.activeTextureARB(0);
+01659                         glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV);         
+01660                         //== colors ==
+01661                         glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_ADD);
+01662                         // Arg0 = 0
+01663                         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_ZERO);
+01664                         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, GL_SRC_COLOR);
+01665                         // Arg1 = 0
+01666                         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_ZERO);
+01667                         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, GL_SRC_COLOR);
+01668                         // Arg2 = 0
+01669                         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_EXT, GL_ZERO);
+01670                         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_EXT, GL_SRC_COLOR);
+01671                         // Arg3 = 0
+01672                         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE3_RGB_NV, GL_ZERO);
+01673                         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND3_RGB_NV, GL_SRC_COLOR);
+01674 
+01675                         //== alpha ==
+01676                         glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_ADD);
+01677                         // Arg0 = AT0
+01678                         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE0_ARB);
+01679                         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_EXT, GL_SRC_ALPHA);
+01680                         // Arg1 = AWPOS
+01681                         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_EXT, GL_PRIMARY_COLOR_EXT);
+01682                         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_EXT, GL_SRC_ALPHA);
+01683                         // Arg2 = AT1
+01684                         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA_EXT, GL_TEXTURE1_ARB);
+01685                         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA_EXT, GL_SRC_ALPHA);
+01686                         // Arg3 = 1-AWPOS
+01687                         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE3_ALPHA_NV, GL_PRIMARY_COLOR_EXT);
+01688                         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND3_ALPHA_NV, GL_ONE_MINUS_SRC_ALPHA);
+01689 
+01690                         // Setup 2nd Stage
+01691                         _DriverGLStates.activeTextureARB(1);
+01692                         glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV);         
+01693                         //== colors ==
+01694                         glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_ADD);
+01695                         // Arg0 = 0
+01696                         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_ZERO);
+01697                         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, GL_SRC_COLOR);
+01698                         // Arg1 = 0
+01699                         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_ZERO);
+01700                         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, GL_SRC_COLOR);
+01701                         // Arg2 = 0
+01702                         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_EXT, GL_ZERO);
+01703                         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_EXT, GL_SRC_COLOR);
+01704                         // Arg3 = 0
+01705                         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE3_RGB_NV, GL_ZERO);
+01706                         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND3_RGB_NV, GL_SRC_COLOR);
+01707 
+01708                         //== alpha ==
+01709                         glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_ADD);
+01710                         // Arg0 = AT0*AWPOS+AT1*(1-AWPOS)
+01711                         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_PREVIOUS_EXT);
+01712                         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_EXT, GL_SRC_ALPHA);
+01713                         // Arg1 = AINT
+01714                         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_EXT, GL_CONSTANT_EXT);
+01715                         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_EXT, GL_SRC_ALPHA);
+01716                         // Arg2 = 0
+01717                         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA_EXT, GL_ZERO);
+01718                         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA_EXT, GL_SRC_ALPHA);
+01719                         // Arg3 = 0
+01720                         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE3_ALPHA_NV, GL_ZERO);
+01721                         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND3_ALPHA_NV, GL_SRC_ALPHA);
+01722 
+01723                 }
+01724                 else // ATI EnvCombine3
+01725                 {
+01726                         /*glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);               
+01727                         //== colors ==
+01728                         glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE_ADD_ATIX);                    
+01729                         // Arg0 = Specular read in cube map
+01730                         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE);
+01731                         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, GL_SRC_COLOR);
+01732                         // Arg2 = Light color
+01733                         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_EXT, GL_CONSTANT_EXT);
+01734                         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_EXT, GL_SRC_COLOR);
+01735                         // Arg1 = Primary color ( + other light diffuse)
+01736                         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_EXT, GL_PREVIOUS_EXT);
+01737                         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_EXT, GL_SRC_COLOR);                   
+01738 
+01739                         //== alpha ==
+01740                         glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_MODULATE_ADD_ATIX);                  
+01741                         // Arg0 = PREVIOUS ALPHA
+01742                         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_PREVIOUS_EXT);
+01743                         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_EXT, GL_SRC_COLOR);
+01744                         // Arg2 = 1
+01745                         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA_EXT, GL_ZERO);
+01746                         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA_EXT, GL_ONE_MINUS_SRC_COLOR);
+01747                         // Arg1 = 0
+01748                         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_EXT, GL_ZERO);
+01749                         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_EXT, GL_SRC_COLOR);*/
+01750                 }
+01751         }
+01752         activateTexEnvColor (1, mat.getColor());
+01753 }
+01754 
+01755 // ***************************************************************************
+01756 void            CDriverGL::endCloudMultiPass()
+01757 {
+01758         nlassert(_CurrentMaterial->getShader() == CMaterial::Cloud);
+01759 }
+01760 
+01761 } // NL3D
+
+ + +
                                                                                                                                                                    +
+ + -- cgit v1.2.1