00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
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
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
00122
00123 activateTexEnvMode(stage, env);
00124 activateTexEnvColor(stage, env);
00125
00126
00127 _DriverGLStates.activeTextureARB(stage);
00128 if (mat.getTexCoordGen (stage))
00129 {
00130
00131 _DriverGLStates.enableTexGen (stage, true);
00132
00133
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
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)
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))
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
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
00234 _NbSetupMaterialCall++;
00235
00236
00237
00238
00239 if (!mat.pShader)
00240 {
00241
00242 ItShaderPtrList it= _Shaders.insert(_Shaders.end());
00243
00244 *it= mat.pShader= new CShaderGL(this, it);
00245
00246
00247 touched= IDRV_TOUCHED_ALL;
00248 }
00249 pShader=static_cast<CShaderGL*>((IShader*)(mat.pShader));
00250
00251
00252
00253
00254 if( touched )
00255 {
00256
00257
00258
00259
00260
00261 if( touched & (~_MaterialAllTextureTouchedFlag) )
00262 {
00263
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
00290 pShader->SupportedShader= getSupportedShader(mat.getShader());
00291 }
00292
00293
00294
00295
00296
00297
00298
00299 _CurrentMaterial= NULL;
00300 }
00301
00302
00303 mat.clearTouched(0xFFFFFFFF);
00304 }
00305
00306
00307
00308 CMaterial::TShader matShader = pShader->SupportedShader;
00309
00310
00311 _CurrentMaterialSupportedShader= matShader;
00312
00313
00314
00315
00316
00317
00318
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
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
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346 if(matShader != CMaterial::LightMap
00347 && matShader != CMaterial::PerPixelLighting
00348
00349 && matShader != CMaterial::Cloud
00350 )
00351 {
00352 for(stage=0 ; stage<inlGetNumTextStages() ; stage++)
00353 {
00354 ITexture *text= mat.getTexture(stage);
00355
00356
00357 activateTexture(stage,text);
00358
00359
00360
00361 setTextureEnvFunction(stage, mat);
00362 }
00363 }
00364
00365
00366
00367
00368 if (_CurrentMaterial!=&mat)
00369 {
00370
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
00377
00378
00379 uint32 twoSided= mat.getFlags()&IDRV_MAT_DOUBLE_SIDED;
00380 _DriverGLStates.enableCullFace( twoSided==0 );
00381
00382
00383
00384
00385 uint32 alphaTest= mat.getFlags()&IDRV_MAT_ALPHA_TEST;
00386 _DriverGLStates.enableAlphaTest(alphaTest);
00387 if(alphaTest)
00388 {
00389
00390 _DriverGLStates.alphaFunc(mat.getAlphaTestThreshold());
00391 }
00392
00393
00394
00395
00396 _DriverGLStates.enableZWrite(mat.getFlags()&IDRV_MAT_ZWRITE);
00397 _DriverGLStates.depthFunc(pShader->ZComp);
00398 _DriverGLStates.setDepthRange (mat.getZBias () * _OODeltaZ);
00399
00400
00401
00402
00403
00404
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
00418 CRGBA col= mat.getColor();
00419 glColor4ub(col.R, col.G, col.B, col.A);
00420 _DriverGLStates.setVertexColorLighted(false);
00421 }
00422
00423
00424
00425
00426
00427 if (_Extensions.NVTextureShader)
00428 {
00429 if (matShader == CMaterial::Normal)
00430 {
00431
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])
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
00467
00468
00469
00470 if( matShader != CMaterial::LightMap && _LastVertexSetupIsLightMap )
00471 resetLightMapVertexSetup();
00472
00473
00474 if (matShader == CMaterial::Normal)
00475 {
00476 setupUserTextureMatrix((uint) inlGetNumTextStages(), mat);
00477 }
00478 else
00479 {
00480 disableUserTextureMatrix();
00481 }
00482
00483 return true;
00484 }
00485
00486
00487
00488 sint CDriverGL::beginMultiPass()
00489 {
00490
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
00502
00503 case CMaterial::Cloud:
00504 return beginCloudMultiPass();
00505
00506
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
00528
00529
00530 case CMaterial::Cloud:
00531 setupCloudPass (pass);
00532 break;
00533
00534
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
00558
00559
00560 case CMaterial::Cloud:
00561 endCloudMultiPass();
00562 break;
00563
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
00575 nlassert(mat._LightMaps.size()<=NL3D_DRV_MAX_LIGHTMAP);
00576
00577
00578 _NLightMaps = 0;
00579
00580 for (uint i = 0; i < mat._LightMaps.size(); ++i)
00581 {
00582
00583 if (mat._LightMaps[i].Factor.getPacked() & RGBMaskPacked)
00584 {
00585 _LightMapLUT[_NLightMaps] = i;
00586 ++_NLightMaps;
00587 }
00588 }
00589
00590
00591 _NLightMapPerPass = inlGetNumTextStages()-1;
00592
00593 if (!_Extensions.NVTextureEnvCombine4 || !_Extensions.ATIXTextureEnvCombine3)
00594 _NLightMapPerPass = 1;
00595
00596
00597 _NLightMapPass = (_NLightMaps + _NLightMapPerPass-1)/(_NLightMapPerPass);
00598
00599
00600 }
00601
00602
00603
00604 sint CDriverGL::beginLightMapMultiPass ()
00605 {
00606 const CMaterial &mat= *_CurrentMaterial;
00607
00608
00609 computeLightMapInfos (mat);
00610
00611
00612 _DriverGLStates.enableLighting(false);
00613
00614 if (_LastVB.VertexFormat & CVertexBuffer::PrimaryColorFlag)
00615 _DriverGLStates.enableColorArray(false);
00616
00617
00618 return std::max (_NLightMapPass, (uint)1);
00619 }
00620
00621 void CDriverGL::setupLightMapPass(uint pass)
00622 {
00623 const CMaterial &mat= *_CurrentMaterial;
00624
00625
00626 if(_NLightMaps==0)
00627 {
00628 ITexture *text= mat.getTexture(0);
00629 activateTexture(0,text);
00630
00631
00632 CMaterial::CTexEnv env;
00633 activateTexEnvMode(0, env);
00634
00635
00636 glColor4ub(0, 0, 0, 255);
00637
00638
00639 _DriverGLStates.activeTextureARB(0);
00640 _DriverGLStates.enableTexGen (0, false);
00641
00642
00643 for(sint stage=1 ; stage<inlGetNumTextStages() ; stage++)
00644 {
00645
00646 activateTexture(stage, NULL);
00647 }
00648
00649 return;
00650 }
00651
00652 nlassert(pass<_NLightMapPass);
00653
00654
00655
00656
00657 uint lmapId;
00658 uint nstages;
00659 lmapId= pass * _NLightMapPerPass;
00660
00661 nstages= std::min(_NLightMapPerPass, _NLightMaps-lmapId) + 1;
00662
00663 for(uint stage= 0; stage<(uint)inlGetNumTextStages(); stage++)
00664 {
00665
00666 if(stage<nstages-1)
00667 {
00668
00669 uint whichLightMap= _LightMapLUT[lmapId];
00670
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
00678
00679 if(text)
00680 {
00681 static CMaterial::CTexEnv stdEnv;
00682
00683
00684 if (stage==0)
00685 {
00686
00687
00688 glColor4ub(lmapFactor.R, lmapFactor.G, lmapFactor.B, 255);
00689
00690
00691 activateTexEnvMode(stage, stdEnv);
00692
00693
00694 _DriverGLStates.activeTextureARB(stage);
00695 _DriverGLStates.enableTexGen (stage, false);
00696 }
00697 else
00698 {
00699
00700 nlassert(_Extensions.NVTextureEnvCombine4 || _Extensions.ATIXTextureEnvCombine3);
00701
00702
00703 stdEnv.ConstantColor=lmapFactor;
00704 activateTexEnvColor(stage, stdEnv);
00705
00706
00707
00708 _CurrentTexEnvSpecial[stage] = TexEnvSpecialLightMap;
00709
00710
00711 _DriverGLStates.activeTextureARB(stage);
00712
00713
00714 if(_CurrentTexEnvSpecial[stage] != TexEnvSpecialLightMap)
00715 {
00716 if (_Extensions.NVTextureEnvCombine4)
00717 {
00718
00719 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV);
00720
00721
00722 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_ADD );
00723 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_ADD );
00724
00725 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE );
00726 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, GL_SRC_COLOR);
00727
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
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
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
00740
00741 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
00742
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
00746 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE );
00747 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, GL_SRC_COLOR);
00748
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
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
00759 if( !_LastVertexSetupIsLightMap || _LightMapUVMap[stage]!=1 )
00760 {
00761 setupUVPtr(stage, _LastVB, 1);
00762 _LightMapUVMap[stage]= 1;
00763 }
00764 }
00765
00766
00767 lmapId++;
00768 }
00769 else if(stage<nstages)
00770 {
00771
00772
00773 if(pass==0 || (pass==_NLightMapPass-1 && stage!=_NLightMapPerPass))
00774 {
00775
00776 ITexture *text= mat.getTexture(0);
00777 activateTexture(stage,text);
00778
00779
00780 activateTexEnvMode(stage, _LightMapLastStageEnv);
00781
00782
00783 _DriverGLStates.activeTextureARB(stage);
00784 _DriverGLStates.enableTexGen (stage, false);
00785
00786
00787 if( !_LastVertexSetupIsLightMap || _LightMapUVMap[stage]!=0 )
00788 {
00789 setupUVPtr(stage, _LastVB, 0);
00790 _LightMapUVMap[stage]= 0;
00791 }
00792 }
00793 }
00794 else
00795 {
00796
00797 activateTexture(stage,NULL);
00798 }
00799 }
00800
00801
00802
00803
00804
00805
00806
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
00815 if( !mat.getBlend() )
00816 {
00817
00818 if(pass==0)
00819 {
00820
00821 _DriverGLStates.enableBlend(false);
00822 }
00823 else if(pass==1)
00824 {
00825
00826 _DriverGLStates.enableBlend(true);
00827 _DriverGLStates.blendFunc(GL_ONE, GL_ONE);
00828 }
00829 }
00830 else
00831 {
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846 if(pass==0)
00847 {
00848
00849 _DriverGLStates.enableBlend(true);
00850 _DriverGLStates.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00851 }
00852 else if(pass==1)
00853 {
00854
00855 _DriverGLStates.enableBlend(true);
00856 _DriverGLStates.blendFunc(GL_SRC_ALPHA, GL_ONE);
00857 }
00858 }
00859
00860 }
00861
00862 void CDriverGL::endLightMapMultiPass()
00863 {
00864
00865 _LastVertexSetupIsLightMap= true;
00866
00867
00868 if(_NLightMapPass>=2 && _FogEnabled)
00869 {
00870 glFogfv(GL_FOG_COLOR, _CurrentFogColor);
00871 }
00872
00873
00874
00875
00876 }
00877
00878
00879
00880 void CDriverGL::resetLightMapVertexSetup()
00881 {
00882
00883 for(sint i=0; i<inlGetNumTextStages(); i++)
00884 {
00885
00886 setupUVPtr(i, _LastVB, i);
00887
00888 _LightMapUVMap[i]= -1;
00889 }
00890
00891
00892 if (_LastVB.VertexFormat & CVertexBuffer::PrimaryColorFlag)
00893 _DriverGLStates.enableColorArray(true);
00894
00895
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
00911 if(mat.getTexture(1)==NULL)
00912 return 1;
00913
00914 if(!_Extensions.ARBTextureCubeMap)
00915 return 1;
00916
00917 if( _Extensions.NVTextureEnvCombine4 || _Extensions.ATIXTextureEnvCombine3)
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
00929 if(mat.getTexture(1)==NULL)
00930 {
00931
00932
00933 _DriverGLStates.enableBlend(false);
00934 return;
00935 }
00936
00938 if( _Extensions.NVTextureEnvCombine4 )
00939 {
00940 _DriverGLStates.enableBlend(false);
00941
00942
00943 if(_CurrentTexEnvSpecial[0] != TexEnvSpecialSpecularStage0)
00944 {
00945
00946 _CurrentTexEnvSpecial[0] = TexEnvSpecialSpecularStage0;
00947
00948 _DriverGLStates.activeTextureARB(0);
00949 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV);
00950
00951 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_ADD );
00952 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_ADD );
00953
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
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
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
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
00974 }
00975
00976
00977
00978 CTexEnvSpecial newEnvStage1;
00979 if( mat.getTexture(0) == NULL )
00980 newEnvStage1= TexEnvSpecialSpecularStage1NoText;
00981 else
00982 newEnvStage1= TexEnvSpecialSpecularStage1;
00983
00984 if(_CurrentTexEnvSpecial[1] != newEnvStage1)
00985 {
00986
00987 _CurrentTexEnvSpecial[1] = newEnvStage1;
00988
00989 _DriverGLStates.activeTextureARB(1);
00990 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV);
00991
00992 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_ADD );
00993 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_ADD );
00994
00995 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE );
00996 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, GL_SRC_COLOR );
00997
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
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
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
01015 }
01016
01017
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
01026 _DriverGLStates.enableBlend(false);
01027
01028
01029 if(_CurrentTexEnvSpecial[0] != TexEnvSpecialSpecularStage0)
01030 {
01031
01032 _CurrentTexEnvSpecial[0] = TexEnvSpecialSpecularStage0;
01033
01034 _DriverGLStates.activeTextureARB(0);
01035 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
01036
01037 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE );
01038 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE );
01039
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
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
01048 }
01049
01050
01051
01052 CTexEnvSpecial newEnvStage1;
01053 if( mat.getTexture(0) == NULL )
01054 newEnvStage1= TexEnvSpecialSpecularStage1NoText;
01055 else
01056 newEnvStage1= TexEnvSpecialSpecularStage1;
01057
01058 if(_CurrentTexEnvSpecial[1] != newEnvStage1)
01059 {
01060
01061 _CurrentTexEnvSpecial[1] = newEnvStage1;
01062
01063 _DriverGLStates.activeTextureARB(1);
01064 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
01065
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
01069 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE );
01070 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, GL_SRC_COLOR );
01071
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
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
01086 }
01087
01088
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 {
01096
01097 if( pass == 0 )
01098 {
01099 _DriverGLStates.enableBlend(false);
01100 _DriverGLStates.activeTextureARB(1);
01101 _DriverGLStates.setTextureMode(CDriverGLStates::TextureDisabled);
01102 }
01103 else
01104 {
01105 _DriverGLStates.enableBlend(true);
01106 _DriverGLStates.blendFunc(GL_ONE, GL_ONE);
01107
01108
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
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
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
01150 _DriverGLStates.activeTextureARB(1);
01151 _DriverGLStates.enableTexGen (1, false);
01152
01153
01154
01155 glMatrixMode(GL_TEXTURE);
01156 glLoadIdentity();
01157 glMatrixMode(GL_MODELVIEW);
01158 }
01159
01160
01161
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
01171 }
01172 float Exp;
01173 };
01174
01175
01176
01177
01178
01179
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
01190 static uint16 expToCubeMap[MaxExponent];
01191
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
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)
01234 {
01235 return _SpecularTextureCubes[cubeMapIndex];
01236 }
01237 else
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
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));
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
01291
01292
01293
01294
01295
01296
01297
01298
01299
01300
01301
01302
01303
01304
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
01313
01314
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
01326
01327
01328
01329 if(_CurrentTexEnvSpecial[0] != TexEnvSpecialPPLStage0)
01330 {
01331
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
01341 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE);
01342 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, GL_SRC_COLOR);
01343
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
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
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
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
01359 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE);
01360 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, GL_SRC_COLOR);
01361
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
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
01372 static CMaterial::CTexEnv env;
01373 env.Env.SrcArg1Alpha = CMaterial::Diffuse;
01374 activateTexEnvMode(1, env);
01375
01376
01377
01378
01379
01380
01381 if(_CurrentTexEnvSpecial[2] != TexEnvSpecialPPLStage2)
01382 {
01383
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
01391 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_ADD);
01392
01393 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE);
01394 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, GL_SRC_COLOR);
01395
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
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
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
01406 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_ADD);
01407
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
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
01414 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA_EXT, GL_ZERO);
01415 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA_EXT, GL_SRC_COLOR);
01416
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
01421 {
01422 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
01423
01424 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE_ADD_ATIX);
01425
01426 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE);
01427 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, GL_SRC_COLOR);
01428
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
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
01436 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_MODULATE_ADD_ATIX);
01437
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
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
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
01456 }
01457
01458
01459
01460 sint CDriverGL::beginPPLNoSpecMultiPass()
01461 {
01462 #ifdef NL_DEBUG
01463 nlassert(supportPerPixelLighting(false));
01464 #endif
01465 return 1;
01466 }
01467
01468
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
01481
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
01493
01494
01495
01496 if(_CurrentTexEnvSpecial[0] != TexEnvSpecialPPLStage0)
01497 {
01498
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
01508 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE);
01509 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, GL_SRC_COLOR);
01510
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
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
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
01526 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE);
01527 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, GL_SRC_COLOR);
01528
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
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
01539 static CMaterial::CTexEnv env;
01540 env.Env.SrcArg1Alpha = CMaterial::Diffuse;
01541 activateTexEnvMode(1, env);
01542
01543 }
01544
01545
01546 void CDriverGL::endPPLNoSpecMultiPass()
01547 {
01548
01549 }
01550
01551
01552
01553
01554
01555
01556
01557
01558
01559
01560
01561
01562
01563
01564
01565
01566
01567
01568
01570
01571
01573
01574
01576
01577
01578
01579
01580
01581
01582
01583
01584
01585
01586
01587
01588
01589
01590
01591
01592
01593
01594
01595
01596
01597
01598
01599
01600
01601
01602
01603
01604
01605
01606
01607
01608
01609
01610
01611
01612
01613
01615
01616
01617
01618
01619
01620
01621
01622
01623
01624
01625
01626
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
01658 _DriverGLStates.activeTextureARB(0);
01659 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV);
01660
01661 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_ADD);
01662
01663 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_ZERO);
01664 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, GL_SRC_COLOR);
01665
01666 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_ZERO);
01667 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, GL_SRC_COLOR);
01668
01669 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_EXT, GL_ZERO);
01670 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_EXT, GL_SRC_COLOR);
01671
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
01676 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_ADD);
01677
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
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
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
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
01691 _DriverGLStates.activeTextureARB(1);
01692 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV);
01693
01694 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_ADD);
01695
01696 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_ZERO);
01697 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, GL_SRC_COLOR);
01698
01699 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_ZERO);
01700 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, GL_SRC_COLOR);
01701
01702 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_EXT, GL_ZERO);
01703 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_EXT, GL_SRC_COLOR);
01704
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
01709 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_ADD);
01710
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
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
01717 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA_EXT, GL_ZERO);
01718 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA_EXT, GL_SRC_ALPHA);
01719
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
01725 {
01726
01727
01728
01729
01730
01731
01732
01733
01734
01735
01736
01737
01738
01739
01740
01741
01742
01743
01744
01745
01746
01747
01748
01749
01750 }
01751 }
01752 activateTexEnvColor (1, mat.getColor());
01753 }
01754
01755
01756 void CDriverGL::endCloudMultiPass()
01757 {
01758 nlassert(_CurrentMaterial->getShader() == CMaterial::Cloud);
01759 }
01760
01761 }