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

render_trav.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 "std3d.h"
+00027 
+00028 #include "3d/render_trav.h"
+00029 #include "3d/hrc_trav.h"
+00030 #include "3d/clip_trav.h"
+00031 #include "3d/light_trav.h"
+00032 #include "3d/driver.h"
+00033 #include "3d/light.h"
+00034 #include "3d/skeleton_model.h"
+00035 #include "3d/scene.h"
+00036 #include "3d/coarse_mesh_manager.h"
+00037 #include "3d/lod_character_manager.h"
+00038 #include "nel/misc/hierarchical_timer.h"
+00039 
+00040 #include "3d/transform.h"
+00041 #include "3d/fast_floor.h"
+00042 #include "3d/mesh_skin_manager.h"
+00043 
+00044 using namespace std;
+00045 using namespace NLMISC;
+00046 
+00047 
+00048 namespace       NL3D
+00049 {
+00050 
+00051 
+00052 // ***************************************************************************
+00053 // ***************************************************************************
+00054 // CRenderTrav
+00055 // ***************************************************************************
+00056 // ***************************************************************************
+00057 
+00058 
+00059 // ***************************************************************************
+00060 CRenderTrav::CRenderTrav()
+00061 {
+00062         RenderList.reserve(1024);
+00063         OrderOpaqueList.init(1024);
+00064         OrderTransparentList.init(1024);
+00065         Driver = NULL;
+00066         _CurrentPassOpaque = true;
+00067 
+00068         _CacheLightContribution= NULL;
+00069 
+00070         // Default light Setup.
+00071         LightingSystemEnabled= false;
+00072         AmbientGlobal= CRGBA(50, 50, 50);
+00073         SunAmbient= CRGBA::Black;
+00074         SunDiffuse= SunSpecular= CRGBA::White;
+00075         _SunDirection.set(0, 0.5, -0.5);
+00076         _SunDirection.normalize();
+00077 
+00078         _StrongestLightTouched = true;
+00079 
+00080         _MeshSkinManager= NULL;
+00081 
+00082         _LayersRenderingOrder= true;
+00083 }
+00084 // ***************************************************************************
+00085 IObs            *CRenderTrav::createDefaultObs() const
+00086 {
+00087         return new CDefaultRenderObs;
+00088 }
+00089 // ***************************************************************************
+00090 void            CRenderTrav::traverse()
+00091 {
+00092         H_AUTO( NL3D_TravRender );
+00093 
+00094         ITravCameraScene::update();
+00095 
+00096         // Bind to Driver.
+00097         getDriver()->setFrustum(Left, Right, Bottom, Top, Near, Far, Perspective);
+00098         // Use setupViewMatrixEx() for ZBuffer precision.
+00099         getDriver()->setupViewMatrixEx(ViewMatrix, CamPos);
+00100         getDriver()->setupViewport(_Viewport);
+00101 
+00102         // reset the light setup, and set global ambient.
+00103         resetLightSetup();
+00104 
+00105 
+00106         // reset the Skin manager, if needed
+00107         if(_MeshSkinManager)
+00108         {
+00109                 if(Driver!=_MeshSkinManager->getDriver())
+00110                 {
+00111                         _MeshSkinManager->release();
+00112                         _MeshSkinManager->init(Driver, NL3D_MESH_SKIN_MANAGER_VERTEXFORMAT, NL3D_MESH_SKIN_MANAGER_MAXVERTICES);
+00113                 }
+00114         }
+00115 
+00116 
+00117         // Fill OT with observers, for both Opaque and transparent pass
+00118         // =============================
+00119 
+00120         // Sort the observers by distance from camera
+00121         // This is done here and not in the addRenderObs because of the LoadBalancing traversal which can modify
+00122         // the transparency flag (multi lod for instance)
+00123 
+00124         // clear the OTs, and prepare to allocate max element space
+00125         OrderOpaqueList.reset(RenderList.size());
+00126         OrderTransparentList.reset(RenderList.size());
+00127 
+00128         // fill the OTs.
+00129         IBaseRenderObs          **itRdrObs= NULL;
+00130         uint32                          nNbObs = RenderList.size();
+00131         if(nNbObs)      
+00132                 itRdrObs= &RenderList[0];
+00133         float   rPseudoZ, rPseudoZ2;
+00134 
+00135         // Some precalc
+00136         float   OOFar= 1.0f / this->Far;
+00137         uint32  opaqueOtSize= OrderOpaqueList.getSize();
+00138         uint32  opaqueOtMax= OrderOpaqueList.getSize()-1;
+00139         uint32  transparentOtSize= OrderTransparentList.getSize();
+00140         uint32  transparentOtMax= OrderTransparentList.getSize()-1;
+00141         uint32  otId;
+00142         // fast floor
+00143         OptFastFloorBegin();
+00144         // For all rdr observers
+00145         for( ; nNbObs>0; itRdrObs++, nNbObs-- )
+00146         {
+00147                 IBaseRenderObs          *pObs= *itRdrObs;
+00148                 // Only rdrObserver of transform models can be inserted!! It's a requirement
+00149                 CTransform                      *pTransform = safe_cast<CTransform*>(pObs->Model);
+00150                 CTransformHrcObs        *trHrcObs= safe_cast<CTransformHrcObs*>(pObs->HrcObs);
+00151 
+00152                 // Yoyo: skins are rendered through skeletons, so models WorldMatrix are all good here (even sticked objects)
+00153                 rPseudoZ = (trHrcObs->WorldMatrix.getPos() - CamPos).norm();
+00154 
+00155                 // rPseudoZ from 0.0 -> 1.0
+00156                 rPseudoZ =  sqrtf( rPseudoZ * OOFar );
+00157 
+00158                 if( pTransform->isOpaque() )
+00159                 {
+00160                         // since norm, we are sure that rPseudoZ>=0
+00161                         rPseudoZ2 = rPseudoZ * opaqueOtSize;
+00162                         otId= OptFastFloor(rPseudoZ2);
+00163                         otId= min(otId, opaqueOtMax);
+00164                         OrderOpaqueList.insert( otId, pObs );
+00165                 }
+00166                 if( pTransform->isTransparent() )
+00167                 {
+00168                         // since norm, we are sure that rPseudoZ>=0
+00169                         rPseudoZ2 = rPseudoZ * transparentOtSize;
+00170                         otId= OptFastFloor(rPseudoZ2);
+00171                         otId= min(otId, transparentOtMax);
+00172                         // must invert id, because transparent, sort from back to front
+00173                         OrderTransparentList.insert( pTransform->getOrderingLayer(), pObs, transparentOtMax-otId );
+00174                 }
+00175 
+00176         }
+00177         // fast floor
+00178         OptFastFloorEnd();
+00179 
+00180 
+00181         // Standard traverse (maybe not used)
+00182         // =============================
+00183 
+00184         // First traverse the root.
+00185         if(Root)
+00186                 Root->traverse(NULL);
+00187 
+00188 
+00189 
+00190         // Render Opaque stuff.
+00191         // =============================
+00192 
+00193         // TestYoyo
+00194         //OrderOpaqueList.reset(0);
+00195         //OrderTransparentList.reset(0);
+00196 
+00197         // Start LodCharacter Manager render.
+00198         CLodCharacterManager    *clodMngr= Scene->getLodCharacterManager();
+00199         if(clodMngr)
+00200                 clodMngr->beginRender(getDriver(), CamPos);
+00201 
+00202         // Render the opaque materials
+00203         _CurrentPassOpaque = true;
+00204         OrderOpaqueList.begin();
+00205         IBaseRenderObs *pBRO;
+00206         while( OrderOpaqueList.get() != NULL )
+00207         {
+00208                 pBRO = OrderOpaqueList.get();
+00209                 pBRO->traverse(NULL);
+00210                 OrderOpaqueList.next();
+00211         }
+00212 
+00213         /* Render MeshBlock Manager. 
+00214                 Some Meshs may be render per block. Interesting to remove VertexBuffer and Material setup overhead.
+00215                 Faster if rendered before lods, for ZBuffer optimisation: render first near objects then far. 
+00216                 Lods are usually far objects.
+00217         */
+00218         MeshBlockManager.flush(Driver, Scene, this);
+00219 
+00220 
+00221         // End LodCharacter Manager render.
+00222         if(clodMngr)
+00223                 clodMngr->endRender();
+00224 
+00225 
+00226         /* Render Scene CoarseMeshManager. 
+00227                 Important to render them at end of Opaque rendering, because coarses instances are created/removed during
+00228                 this model opaque rendering pass.
+00229         */
+00230         // Render dynamic one.
+00231         Scene->getDynamicCoarseMeshManager()->render(Driver);
+00232         // Render static one.
+00233         Scene->getStaticCoarseMeshManager()->render(Driver);
+00234 
+00235 
+00236         // Render Transparent stuff.
+00237         // =============================
+00238 
+00239          // Render transparent materials
+00240         _CurrentPassOpaque = false;
+00241         OrderTransparentList.begin(_LayersRenderingOrder);      
+00242         while( OrderTransparentList.get() != NULL )
+00243         {                               
+00244                 pBRO = OrderTransparentList.get();
+00245                 pBRO->traverse(NULL);
+00246                 OrderTransparentList.next();
+00247         }
+00248 
+00249 
+00250         // END!
+00251         // =============================
+00252 
+00253         // clean: reset the light setup
+00254         resetLightSetup();
+00255 
+00256 }
+00257 // ***************************************************************************
+00258 void            CRenderTrav::clearRenderList()
+00259 {
+00260         RenderList.clear();
+00261 }
+00262 // ***************************************************************************
+00263 void            CRenderTrav::addRenderObs(IBaseRenderObs *o)
+00264 {
+00265         RenderList.push_back(o);
+00266 }
+00267 
+00268 
+00269 // ***************************************************************************
+00270 void            CRenderTrav::setSunDirection(const CVector &dir)
+00271 {
+00272         _SunDirection= dir;
+00273         _SunDirection.normalize();
+00274 }
+00275 
+00276 
+00277 // ***************************************************************************
+00278 void            CRenderTrav::setMeshSkinManager(CMeshSkinManager *msm)
+00279 {
+00280         _MeshSkinManager= msm;
+00281 }
+00282 
+00283 
+00284 // ***************************************************************************
+00285 // ***************************************************************************
+00286 // LightSetup
+00287 // ***************************************************************************
+00288 // ***************************************************************************
+00289 
+00290 
+00291 // ***************************************************************************
+00292 void            CRenderTrav::resetLightSetup()
+00293 {
+00294         // If lighting System disabled, skip
+00295         if(!LightingSystemEnabled)
+00296         {
+00297                 // Dont modify Driver lights, but setup default lighting For VertexProgram Lighting.
+00298                 _NumLightEnabled= 1;
+00299                 // Setup A default directionnal.
+00300                 CVector         defDir(-0.5f, 0.0, -0.85f);
+00301                 defDir.normalize();
+00302                 CRGBA           aday= CRGBA(130,  105,  119);
+00303                 CRGBA           dday= CRGBA(238, 225, 204);
+00304                 _DriverLight[0].setupDirectional(aday, dday, dday, defDir);
+00305 
+00306                 return;
+00307         }
+00308         else
+00309         {
+00310                 uint i;
+00311 
+00312                 // Disable all lights.
+00313                 for(i=0; i<Driver->getMaxLight(); i++)
+00314                 {
+00315                         Driver->enableLight(i, false);
+00316                 }
+00317 
+00318 
+00319                 // setup the precise cache, and setup lights according to this cache?
+00320                 // setup blackSun (factor==0).
+00321                 _LastSunFactor= 0;
+00322                 _LastSunAmbient.set(0,0,0,255);
+00323                 _DriverLight[0].setupDirectional(CRGBA::Black, CRGBA::Black, CRGBA::Black, _SunDirection);
+00324                 Driver->setLight(0, _DriverLight[0]);
+00325                 // setup NULL point lights (=> cache will fail), so no need to setup other lights in Driver.
+00326                 for(i=0; i<NL3D_MAX_LIGHT_CONTRIBUTION; i++)
+00327                 {
+00328                         _LastPointLight[i]= NULL;
+00329                 }
+00330 
+00331 
+00332                 // setup the precise cache, and setup lights according to this cache?
+00333                 // setup blackSun (factor==0).
+00334                 _LastSunFactor= 0;
+00335                 _LastSunAmbient.set(0,0,0,255);
+00336                 CLight          light;
+00337                 light.setupDirectional(CRGBA::Black, CRGBA::Black, CRGBA::Black, _SunDirection);
+00338                 _DriverLight[0].setupDirectional(CRGBA::Black, CRGBA::Black, CRGBA::Black, _SunDirection);
+00339                 Driver->setLight(0, light);
+00340                 // setup NULL point lights (=> cache will fail), so no need to setup other lights in Driver.
+00341                 for(i=0; i<NL3D_MAX_LIGHT_CONTRIBUTION; i++)
+00342                 {
+00343                         _LastPointLight[i]= NULL;
+00344                 }
+00345 
+00346                 // Set the global ambientColor
+00347                 Driver->setAmbientColor(AmbientGlobal);
+00348 
+00349 
+00350                 // clear the cache.
+00351                 _CacheLightContribution= NULL;
+00352                 _NumLightEnabled= 0;
+00353 
+00354                 _StrongestLightTouched = true;
+00355         }
+00356 }
+00357 
+00358 
+00359 // ***************************************************************************
+00360 void            CRenderTrav::changeLightSetup(CLightContribution        *lightContribution, bool useLocalAttenuation)
+00361 {
+00362         // If lighting System disabled, skip
+00363         if(!LightingSystemEnabled)
+00364                 return;
+00365 
+00366         uint            i;
+00367 
+00368         // if same lightContribution, no-op.
+00369         if(_CacheLightContribution == lightContribution &&  _LastLocalAttenuation == useLocalAttenuation)
+00370                 return;
+00371         // else, must setup the lights into driver.
+00372         else
+00373         {
+00374                 _StrongestLightTouched = true;
+00375                 // if the setup is !NULL
+00376                 if(lightContribution)
+00377                 {
+00378                         // Compute SunAmbient / LocalAmbient
+00379                         //-----------
+00380                         CRGBA   finalAmbient;
+00381                         // Different case if the contribution is frozen or not.
+00382                         if(lightContribution->FrozenStaticLightSetup)
+00383                         {
+00384                                 // Any FrozenAmbientLight provided??
+00385                                 if(lightContribution->FrozenAmbientLight)
+00386                                         // Take his current (maybe animated) ambient
+00387                                         finalAmbient= lightContribution->FrozenAmbientLight->getAmbient();
+00388                                 else
+00389                                         // Take the sun ones.
+00390                                         finalAmbient= SunAmbient;
+00391                         }
+00392                         else
+00393                         {
+00394                                 // must interpolate between SunAmbient and localAmbient
+00395                                 uint    uAmbFactor= lightContribution->LocalAmbient.A;
+00396                                 // expand 0..255 to 0..256, to avoid loss of precision.
+00397                                 uAmbFactor+= uAmbFactor>>7;
+00398                                 // Blend, but LocalAmbient.r/g/b is already multiplied by a.
+00399                                 finalAmbient.modulateFromuiRGBOnly(SunAmbient, 256 - uAmbFactor);
+00400                                 finalAmbient.addRGBOnly(finalAmbient, lightContribution->LocalAmbient);
+00401                         }
+00402                         // Force Alpha to 255 for good cache test.
+00403                         finalAmbient.A= 255;
+00404 
+00405 
+00406                         // Setup the directionnal Sunlight.
+00407                         //-----------
+00408                         // expand 0..255 to 0..256, to avoid loss of precision.
+00409                         uint    ufactor= lightContribution->SunContribution;
+00410                         //      different SunLight as in cache ??
+00411                         //      NB: sunSetup can't change during renderPass, so need only to test factor.
+00412                         if(ufactor != _LastSunFactor || finalAmbient != _LastSunAmbient)
+00413                         {
+00414                                 // cache (before expanding!!)
+00415                                 _LastSunFactor= ufactor;
+00416                                 // Cache final ambient light
+00417                                 _LastSunAmbient= finalAmbient;
+00418 
+00419                                 // expand to 0..256.
+00420                                 ufactor+= ufactor>>7;   // add 0 or 1.
+00421                                 // modulate color with factor of the lightContribution.
+00422                                 CRGBA   sunDiffuse, sunSpecular;
+00423                                 sunDiffuse.modulateFromuiRGBOnly(SunDiffuse, ufactor);
+00424                                 sunSpecular.modulateFromuiRGBOnly(SunSpecular, ufactor);
+00425                                 // setup driver light
+00426                                 _DriverLight[0].setupDirectional(finalAmbient, sunDiffuse, sunSpecular, _SunDirection);
+00427                                 Driver->setLight(0, _DriverLight[0]);
+00428                         }
+00429 
+00430 
+00431                         // Setup other point lights
+00432                         //-----------
+00433                         uint    plId=0;
+00434                         // for the list of light.
+00435                         while(lightContribution->PointLight[plId]!=NULL)
+00436                         {
+00437                                 CPointLight             *pl= lightContribution->PointLight[plId];
+00438                                 uint                    inf;
+00439                                 if(useLocalAttenuation)
+00440                                         inf= lightContribution->Factor[plId];
+00441                                 else
+00442                                         inf= lightContribution->AttFactor[plId];
+00443 
+00444                                 // different PointLight setup than in cache??
+00445                                 // NB: pointLight setup can't change during renderPass, so need only to test pointer, 
+00446                                 // attenuation mode and factor.
+00447                                 if( pl!=_LastPointLight[plId] || 
+00448                                         inf!=_LastPointLightFactor[plId] ||
+00449                                         useLocalAttenuation!=_LastPointLightLocalAttenuation[plId] )
+00450                                 {
+00451                                         // need to resetup the light. Cache it.
+00452                                         _LastPointLight[plId]= pl;
+00453                                         _LastPointLightFactor[plId]= inf;
+00454                                         _LastPointLightLocalAttenuation[plId]= useLocalAttenuation;
+00455 
+00456                                         // compute the driver light
+00457                                         if(useLocalAttenuation)
+00458                                                 pl->setupDriverLight(_DriverLight[plId+1], inf);
+00459                                         else
+00460                                                 // Compute it with user Attenuation
+00461                                                 pl->setupDriverLightUserAttenuation(_DriverLight[plId+1], inf);
+00462 
+00463                                         // setup driver. decal+1 because of sun.
+00464                                         Driver->setLight(plId+1, _DriverLight[plId+1]);
+00465                                 }
+00466 
+00467                                 // next light?
+00468                                 plId++;
+00469                                 if(plId>=NL3D_MAX_LIGHT_CONTRIBUTION)
+00470                                         break;
+00471                         }
+00472 
+00473 
+00474                         // Disable olds, enable news, and cache.
+00475                         //-----------
+00476                         // count new number of light enabled.
+00477                         uint    newNumLightEnabled;
+00478                         // number of pointLight + the sun 
+00479                         newNumLightEnabled= plId + 1;
+00480 
+00481                         // enable lights which are used now and were not before.
+00482                         for(i=_NumLightEnabled; i<newNumLightEnabled; i++)
+00483                         {
+00484                                 Driver->enableLight(i, true);
+00485                         }
+00486 
+00487                         // disable lights which are no more used.
+00488                         for(i=newNumLightEnabled; i<_NumLightEnabled; i++)
+00489                         {
+00490                                 Driver->enableLight(i, false);
+00491                         }
+00492 
+00493                         // cache the setup.
+00494                         _CacheLightContribution = lightContribution;
+00495                         _NumLightEnabled= newNumLightEnabled;
+00496                         _LastLocalAttenuation= useLocalAttenuation;
+00497                 }
+00498                 else
+00499                 {
+00500                         // Disable old lights, and cache.
+00501                         //-----------
+00502                         // disable lights which are no more used.
+00503                         for(i=0; i<_NumLightEnabled; i++)
+00504                         {
+00505                                 Driver->enableLight(i, false);
+00506                         }
+00507 
+00508                         // cache the setup.
+00509                         _CacheLightContribution = NULL;
+00510                         _NumLightEnabled= 0;
+00511                 }
+00512 
+00513 
+00514         }
+00515 }
+00516 
+00517 // ***************************************************************************
+00518 // ***************************************************************************
+00519 // VertexProgram LightSetup
+00520 // ***************************************************************************
+00521 // ***************************************************************************
+00522 
+00523 
+00524 // ***************************************************************************
+00525 void            CRenderTrav::beginVPLightSetup(uint ctStart, bool supportSpecular, const CMatrix &invObjectWM)
+00526 {       
+00527         uint    i;               
+00528         nlassert(MaxVPLight==4);
+00529         _VPNumLights= min(_NumLightEnabled, (uint)MaxVPLight);
+00530         _VPCurrentCtStart= ctStart;
+00531         _VPSupportSpecular= supportSpecular;
+00532         
+00533         // Prepare Colors (to be multiplied by material)
+00534         //================
+00535         // Ambient. _VPCurrentCtStart+0
+00536         _VPFinalAmbient= AmbientGlobal;
+00537         for(i=0; i<_VPNumLights; i++)
+00538         {
+00539                 _VPFinalAmbient+= _DriverLight[i].getAmbiant();         
+00540         }
+00541         // Diffuse. _VPCurrentCtStart+1 to 4
+00542         for(i=0; i<_VPNumLights; i++)
+00543         {
+00544                 _VPLightDiffuse[i]= _DriverLight[i].getDiffuse();
+00545         }
+00546         // reset other to 0.
+00547         for(; i<MaxVPLight; i++)
+00548         {
+00549                 _VPLightDiffuse[i]= CRGBA::Black;
+00550                 Driver->setConstant(_VPCurrentCtStart+1+i, 0.f, 0.f, 0.f, 0.f);
+00551         }
+00552         // Specular. _VPCurrentCtStart+5 to 8 (only if supportSpecular)
+00553         if(supportSpecular)
+00554         {
+00555                 for(i=0; i<_VPNumLights; i++)
+00556                 {
+00557                         _VPLightSpecular[i]= _DriverLight[i].getSpecular();
+00558                 }
+00559                 // reset other to 0.
+00560                 for(; i<MaxVPLight; i++)
+00561                 {
+00562                         _VPLightSpecular[i]= CRGBA::Black;
+00563                         Driver->setConstant(_VPCurrentCtStart+5+i, 0.f, 0.f, 0.f, 0.f);
+00564                 }
+00565         }
+00566 
+00567 
+00568         // Compute Eye position in Object space.
+00569         CVector         eye= invObjectWM * CamPos;
+00570 
+00571 
+00572         // Setup Sun Directionnal light.
+00573         //================
+00574         CVector         lightDir;
+00575         // in objectSpace.
+00576         lightDir= invObjectWM.mulVector(_DriverLight[0].getDirection());
+00577         lightDir.normalize();
+00578         lightDir= -lightDir; 
+00579         if(supportSpecular)
+00580         {
+00581                 // Setup lightDir.
+00582                 Driver->setConstant(_VPCurrentCtStart+9, lightDir);
+00583         }
+00584         else
+00585         {
+00586                 // Setup lightDir. NB: no specular color!
+00587                 Driver->setConstant(_VPCurrentCtStart+5, lightDir);
+00588         }
+00589 
+00590 
+00591         // Setup PointLights
+00592         //================
+00593         uint            startPLPos;
+00594         if(supportSpecular)
+00595         {
+00596                 // Setup eye in objectSpace for localViewer
+00597                 Driver->setConstant(_VPCurrentCtStart+11, eye);
+00598                 // Start at 12.
+00599                 startPLPos= 12;
+00600         }
+00601         else
+00602         {
+00603                 // Start at 6.
+00604                 startPLPos= 6;
+00605         }
+00606         // For all pointLight enabled (other are black: don't matter)
+00607         for(i=1; i<_VPNumLights; i++)
+00608         {
+00609                 // Setup position of light.
+00610                 CVector         lightPos;
+00611                 lightPos= invObjectWM * _DriverLight[i].getPosition();
+00612                 Driver->setConstant(_VPCurrentCtStart+startPLPos+(i-1), lightPos);
+00613         }
+00614 
+00615 
+00616         // Must force real light setup at least the first time, in changeVPLightSetupMaterial()
+00617         _VPMaterialCacheDirty= true;
+00618 }
+00619 
+00620 // ***************************************************************************
+00621 void            CRenderTrav::changeVPLightSetupMaterial(const CMaterial &mat, bool excludeStrongest)
+00622 {
+00623         // Must test if at least done one time.
+00624         if(!_VPMaterialCacheDirty)
+00625         {
+00626                 // Must test if same as in cache
+00627                 if( _VPMaterialCacheEmissive == mat.getEmissive().getPacked() &&
+00628                         _VPMaterialCacheAmbient == mat.getAmbient().getPacked() &&
+00629                         _VPMaterialCacheDiffuse == mat.getDiffuse().getPacked() )
+00630                 {
+00631                         // Same Diffuse part, test if same specular if necessary
+00632                         if( !_VPSupportSpecular ||
+00633                                 ( _VPMaterialCacheSpecular == mat.getSpecular().getPacked() &&
+00634                                   _VPMaterialCacheShininess == mat.getShininess() )  )
+00635                         {
+00636                                 // Then ok, skip.
+00637                                 return;
+00638                         }
+00639                 }
+00640         }
+00641 
+00642         // If not skiped, cache now. cache all for simplification
+00643         _VPMaterialCacheDirty= false;
+00644         _VPMaterialCacheEmissive= mat.getEmissive().getPacked();
+00645         _VPMaterialCacheAmbient= mat.getDiffuse().getPacked();
+00646         _VPMaterialCacheDiffuse= mat.getDiffuse().getPacked();
+00647         _VPMaterialCacheSpecular= mat.getSpecular().getPacked();
+00648         _VPMaterialCacheShininess= mat.getShininess();
+00649 
+00650         // Setup constants
+00651         CRGBAF  color;
+00652         uint    i;
+00653         CRGBAF  matDiff= mat.getDiffuse();
+00654         CRGBAF  matSpec= mat.getSpecular();
+00655         float   specExp= mat.getShininess();
+00656         
+00657         uint strongestLightIndex = excludeStrongest ? getStrongestLightIndex() : _VPNumLights;
+00658 
+00659         // setup Ambient + Emissive
+00660         color= _VPFinalAmbient * mat.getAmbient();
+00661         color+= mat.getEmissive();
+00662         Driver->setConstant(_VPCurrentCtStart+0, 1, &color.R);
+00663         
+00664 
+00665         // is the strongest light is not excluded, its index should have been setup to _VPNumLights
+00666 
+00667         // setup Diffuse.
+00668         for(i = 0; i < strongestLightIndex; ++i)
+00669         {
+00670                 color= _VPLightDiffuse[i] * matDiff;
+00671                 Driver->setConstant(_VPCurrentCtStart+1+i, 1, &color.R);
+00672         }
+00673 
+00674         
+00675         if (i != _VPNumLights)
+00676         {
+00677                 color= _VPLightDiffuse[i] * matDiff;
+00678                 _StrongestLightDiffuse.set((uint8) (255.f * color.R), (uint8) (255.f * color.G), (uint8) (255.f * color.B), (uint8) (255.f * color.A));
+00679                 // setup strongest light to black for the gouraud part
+00680                 Driver->setConstant(_VPCurrentCtStart + 1 + i, 0.f, 0.f, 0.f, 0.f);
+00681                 ++i;
+00682                 // setup other lights
+00683                 for(; i < _VPNumLights; i++)
+00684                 {
+00685                         color= _VPLightDiffuse[i] * matDiff;
+00686                         Driver->setConstant(_VPCurrentCtStart + 1 + i, 1, &color.R);
+00687                 }
+00688         }
+00689 
+00690         // setup Specular
+00691         if(_VPSupportSpecular)
+00692         {
+00693                 for(i = 0; i < strongestLightIndex; ++i)
+00694                 {
+00695                         color= _VPLightSpecular[i] * matSpec;
+00696                         color.A= specExp;
+00697                         Driver->setConstant(_VPCurrentCtStart+5+i, 1, &color.R);
+00698                 }
+00699 
+00700                 if (i != _VPNumLights)
+00701                 {
+00702                         color= _VPLightSpecular[i] * matSpec;
+00703                         _StrongestLightSpecular.set((uint8) (255.f * color.R), (uint8) (255.f * color.G), (uint8) (255.f * color.B), (uint8) (255.f * color.A));
+00704 
+00705                         // setup strongest light to black (for gouraud part)
+00706                         Driver->setConstant(_VPCurrentCtStart + 5 + i, 0.f, 0.f, 0.f, 0.f);
+00707                         ++i;
+00708                         // setup other lights
+00709                         for(; i < _VPNumLights; i++)
+00710                         {
+00711                                 color= _VPLightSpecular[i] * matSpec;
+00712                                 color.A= specExp;
+00713                                 Driver->setConstant(_VPCurrentCtStart + 5 + i, 1, &color.R);
+00714                         }
+00715                 }
+00716         }
+00717 
+00718         // setup alpha.
+00719         static  float   alphaCte[4]= {0,0,1,0};
+00720         alphaCte[3]= matDiff.A;
+00721         // setup at good place
+00722         if(_VPSupportSpecular)
+00723                         Driver->setConstant(_VPCurrentCtStart+10, 1, alphaCte);
+00724         else
+00725                         Driver->setConstant(_VPCurrentCtStart+9, 1, alphaCte);
+00726 }
+00727 
+00728 // ***************************************************************************
+00729 sint CRenderTrav::getStrongestLightIndex() const
+00730 {
+00731         if (!_StrongestLightTouched) return -1;
+00732         uint vpNumLights = min(_NumLightEnabled, (uint)MaxVPLight);
+00733         // If there is only a directionnal light, use it
+00734         // If there is any point light, use the nearest, or the directionnal light if it is brighter
+00735         if (vpNumLights == 0) return -1;
+00736         if (vpNumLights == 1) return 0;
+00737         // First point light is brightest ?
+00738         float lumDir = _VPLightDiffuse[0].R + _VPLightDiffuse[0].G + _VPLightDiffuse[0].B + _VPLightDiffuse[0].A
+00739                                    + _VPLightSpecular[0].R + _VPLightSpecular[0].G + _VPLightSpecular[0].B + _VPLightSpecular[0].A;
+00740         float lumOmni = _VPLightDiffuse[1].R + _VPLightDiffuse[1].G + _VPLightDiffuse[1].B + _VPLightDiffuse[1].A
+00741                                    + _VPLightSpecular[1].R + _VPLightSpecular[1].G + _VPLightSpecular[1].B + _VPLightSpecular[1].A;
+00742         return lumDir > lumOmni ? 0 : 1;
+00743 }
+00744 
+00745 // ***************************************************************************
+00746 void    CRenderTrav::getStrongestLightColors(NLMISC::CRGBA &diffuse, NLMISC::CRGBA &specular)
+00747 {
+00748         sint strongestLightIndex = getStrongestLightIndex();
+00749         if (strongestLightIndex == -1)
+00750         {
+00751                 diffuse = specular = NLMISC::CRGBA::Black;              
+00752         }
+00753         else
+00754         {
+00755                 diffuse = _StrongestLightDiffuse;
+00756                 specular = _StrongestLightSpecular;             
+00757         }
+00758 }
+00759 
+00760 
+00761 // ***************************************************************************
+00762 static const char*      LightingVPFragmentNormalize=
+00763 "       # normalize normal                                                                                                                                      \n\
+00764         DP3     R6.w, R6, R6;                                                                                                                                   \n\
+00765         RSQ     R6.w, R6.w;                                                                                                                                             \n\
+00766         MUL     R6, R6, R6.w;                                                                                                                                   \n\
+00767 ";
+00768 
+00769 
+00770 // ***************************************************************************
+00771 // NB: all CTS+x are replaced with good cte index.
+00772 static const char*      LightingVPFragmentNoSpecular_Begin=
+00773 "                                                                                                                                                                               \n\
+00774         # Global Ambient.                                                                                                                                       \n\
+00775         MOV     R2, c[CTS+0];                                                                                                                                   \n\
+00776                                                                                                                                                                                 \n\
+00777         # Diffuse Sun                                                                                                                                           \n\
+00778         DP3     R0.x, R6, c[CTS+5];                     # R0.x= normal*-lightDir                                                        \n\
+00779         LIT     R0.y, R0.xxxx;                          # R0.y= R0.x clamped                                                            \n\
+00780         MAD     R2, R0.y, c[CTS+1], R2;         # R2= summed vertex color.                                                      \n\
+00781 ";
+00782 
+00783 // The 3 point Light code.
+00784 static const char*      LightingVPFragmentNoSpecular_PL[]=
+00785 {
+00786 "       # Diffuse PointLight 0.                                                                                                                         \n\
+00787         ADD     R0, c[CTS+6], -R5;                      # R0= lightPos-vertex                                                           \n\
+00788         DP3     R0.w, R0, R0;                           # normalize R0.                                                                         \n\
+00789         RSQ     R0.w, R0.w;                                                                                                                                             \n\
+00790         MUL     R0, R0, R0.w;                                                                                                                                   \n\
+00791         DP3     R0.x, R6, R0;                           # R0.x= normal*lightDir                                                         \n\
+00792         LIT     R0.y, R0.xxxx;                          # R0.y= R0.x clamped                                                            \n\
+00793         MAD     R2, R0.y, c[CTS+2], R2;         # R2= summed vertex color.                                                      \n\
+00794 ",
+00795 "       # Diffuse PointLight 1.                                                                                                                         \n\
+00796         ADD     R0, c[CTS+7], -R5;                      # R0= lightPos-vertex                                                           \n\
+00797         DP3     R0.w, R0, R0;                           # normalize R0.                                                                         \n\
+00798         RSQ     R0.w, R0.w;                                                                                                                                             \n\
+00799         MUL     R0, R0, R0.w;                                                                                                                                   \n\
+00800         DP3     R0.x, R6, R0;                           # R0.x= normal*lightDir                                                         \n\
+00801         LIT     R0.y, R0;                                       # R0.y= R0.x clamped                                                            \n\
+00802         MAD     R2, R0.y, c[CTS+3], R2;         # R2= summed vertex color.                                                      \n\
+00803 ",
+00804 "       # Diffuse PointLight 2.                                                                                                                         \n\
+00805         ADD     R0, c[CTS+8], -R5;                      # R0= lightPos-vertex                                                           \n\
+00806         DP3     R0.w, R0, R0;                           # normalize R0.                                                                         \n\
+00807         RSQ     R0.w, R0.w;                                                                                                                                             \n\
+00808         MUL     R0, R0, R0.w;                                                                                                                                   \n\
+00809         DP3     R0.x, R6, R0;                           # R0.x= normal*lightDir                                                         \n\
+00810         LIT     R0.y, R0;                                       # R0.y= R0.x clamped                                                            \n\
+00811         MAD     R2, R0.y, c[CTS+4], R2;         # R2= summed vertex color.                                                      \n\
+00812 "
+00813 };
+00814 
+00815 // The End code.
+00816 static const char*      LightingVPFragmentNoSpecular_End=
+00817 "       # output to o[COL0] only, replacing alpha with material alpha.                                          \n\
+00818         MAD     o[COL0], R2, c[CTS+9].zzzx, c[CTS+9].xxxw;                                                                              \n\
+00819 ";
+00820 
+00821 
+00822 // ***************************************************************************
+00823 // NB: all CTS+x are replaced with good cte index.
+00824 static const char*      LightingVPFragmentSpecular_Begin=
+00825 "                                                                                                                                                                               \n\
+00826         # Global Ambient.                                                                                                                                       \n\
+00827         MOV     R2, c[CTS+0];                                                                                                                                   \n\
+00828                                                                                                                                                                                 \n\
+00829         # Always keep Specular exponent in R0.w                                                                                         \n\
+00830         MOV     R0.w, c[CTS+5].w;                                                                                                                               \n\
+00831                                                                                                                                                                                 \n\
+00832         # Compute vertex-to-eye vector normed.                                                                                          \n\
+00833         ADD     R4, c[CTS+11], -R5;                                                                                                                             \n\
+00834         DP3     R4.w, R4, R4;                                                                                                                                   \n\
+00835         RSQ     R4.w, R4.w;                                                                                                                                             \n\
+00836         MUL R4, R4, R4.w;                                                                                                                                       \n\
+00837                                                                                                                                                                                 \n\
+00838         # Diffuse-Specular Sun                                                                                                                          \n\
+00839         # Compute R1= halfAngleVector= (lightDir+R4).normed().                                                          \n\
+00840         ADD     R1.xyz, c[CTS+9], R4;           # R1= halfAngleVector                                                           \n\
+00841         DP3     R1.w, R1, R1;                           # normalize R1.                                                                         \n\
+00842         RSQ     R1.w, R1.w;                                                                                                                                             \n\
+00843         MUL     R1.xyz, R1, R1.w;                                                                                                                               \n\
+00844         # Compute Factors and colors.                                                                                                           \n\
+00845         DP3     R0.x, R6, c[CTS+9];                     # R0.x= normal*-lightDir                                                        \n\
+00846         DP3     R0.yz, R6, R1;                          # R0.yz= normal*halfAngleVector                                         \n\
+00847         LIT     R0.yz, R0;                                      # R0.y= R0.x clamped, R0.z= pow(spec, R0.w) clamp       \n\
+00848         MAD     R2, R0.y, c[CTS+1], R2;         # R2= summed vertex color.                                                      \n\
+00849         MUL     R3, R0.z, c[CTS+5];                     # R3= specular color.                                                           \n\
+00850 ";
+00851 
+00852 // The 3 point Light code.
+00853 static const char*      LightingVPFragmentSpecular_PL[]=
+00854 {
+00855 "       # Diffuse-Specular PointLight 0.                                                                                                        \n\
+00856         # Compute R0= (lightPos-vertex).normed().                                                                                       \n\
+00857         ADD     R0.xyz, c[CTS+12], -R5;         # R0= lightPos-vertex                                                           \n\
+00858         DP3     R1.w, R0, R0;                           # normalize R0.                                                                         \n\
+00859         RSQ     R1.w, R1.w;                                                                                                                                             \n\
+00860         MUL     R0.xyz, R0, R1.w;                                                                                                                               \n\
+00861         # Compute R1= halfAngleVector= (R0+R4).normed().                                                                        \n\
+00862         ADD     R1.xyz, R0, R4;                         # R1= halfAngleVector                                                           \n\
+00863         DP3     R1.w, R1, R1;                           # normalize R1.                                                                         \n\
+00864         RSQ     R1.w, R1.w;                                                                                                                                             \n\
+00865         MUL     R1.xyz, R1, R1.w;                                                                                                                               \n\
+00866         # Compute Factors and colors.                                                                                                           \n\
+00867         DP3     R0.x, R6, R0;                           # R0.x= normal*lightDir                                                         \n\
+00868         DP3     R0.yz, R6, R1;                          # R0.yz= normal*halfAngleVector                                         \n\
+00869         LIT     R0.yz, R0;                                      # R0.y= R0.x clamped, R0.z= pow(spec, R0.w) clamp       \n\
+00870         MAD     R2, R0.y, c[CTS+2], R2;         # R2= summed vertex color.                                                      \n\
+00871         MAD     R3, R0.z, c[CTS+6], R3;         # R3= summed specular color.                                            \n\
+00872 ",
+00873 "       # Diffuse-Specular PointLight 1.                                                                                                        \n\
+00874         # Compute R0= (lightPos-vertex).normed().                                                                                       \n\
+00875         ADD     R0.xyz, c[CTS+13], -R5;         # R0= lightPos-vertex                                                           \n\
+00876         DP3     R1.w, R0, R0;                           # normalize R0.                                                                         \n\
+00877         RSQ     R1.w, R1.w;                                                                                                                                             \n\
+00878         MUL     R0.xyz, R0, R1.w;                                                                                                                               \n\
+00879         # Compute R1= halfAngleVector= (R0+R4).normed().                                                                        \n\
+00880         ADD     R1.xyz, R0, R4;                         # R1= halfAngleVector                                                           \n\
+00881         DP3     R1.w, R1, R1;                           # normalize R1.                                                                         \n\
+00882         RSQ     R1.w, R1.w;                                                                                                                                             \n\
+00883         MUL     R1.xyz, R1, R1.w;                                                                                                                               \n\
+00884         # Compute Factors and colors.                                                                                                           \n\
+00885         DP3     R0.x, R6, R0;                           # R0.x= normal*lightDir                                                         \n\
+00886         DP3     R0.yz, R6, R1;                          # R0.yz= normal*halfAngleVector                                         \n\
+00887         LIT     R0.yz, R0;                                      # R0.y= R0.x clamped, R0.z= pow(spec, R0.w) clamp       \n\
+00888         MAD     R2, R0.y, c[CTS+3], R2;         # R2= summed vertex color.                                                      \n\
+00889         MAD     R3, R0.z, c[CTS+7], R3;         # R3= summed specular color.                                            \n\
+00890 ",
+00891 "       # Diffuse-Specular PointLight 2.                                                                                                        \n\
+00892         # Compute R0= (lightPos-vertex).normed().                                                                                       \n\
+00893         ADD     R0.xyz, c[CTS+14], -R5;         # R0= lightPos-vertex                                                           \n\
+00894         DP3     R1.w, R0, R0;                           # normalize R0.                                                                         \n\
+00895         RSQ     R1.w, R1.w;                                                                                                                                             \n\
+00896         MUL     R0.xyz, R0, R1.w;                                                                                                                               \n\
+00897         # Compute R1= halfAngleVector= (R0+R4).normed().                                                                        \n\
+00898         ADD     R1.xyz, R0, R4;                         # R1= halfAngleVector                                                           \n\
+00899         DP3     R1.w, R1, R1;                           # normalize R1.                                                                         \n\
+00900         RSQ     R1.w, R1.w;                                                                                                                                             \n\
+00901         MUL     R1.xyz, R1, R1.w;                                                                                                                               \n\
+00902         # Compute Factors and colors.                                                                                                           \n\
+00903         DP3     R0.x, R6, R0;                           # R0.x= normal*lightDir                                                         \n\
+00904         DP3     R0.yz, R6, R1;                          # R0.yz= normal*halfAngleVector                                         \n\
+00905         LIT     R0.yz, R0;                                      # R0.y= R0.x clamped, R0.z= pow(spec, R0.w) clamp       \n\
+00906         MAD     R2, R0.y, c[CTS+4], R2;         # R2= summed vertex color.                                                      \n\
+00907 "
+00908 };
+00909 
+00910 
+00911 // The End code.
+00912 static const char*      LightingVPFragmentSpecular_End=
+00913 "       # output directly to secondary color.                                                                                           \n\
+00914         MAD     o[COL1], R0.z, c[CTS+8], R3;    # final summed specular color.                                  \n\
+00915                                                                                                                                                                                 \n\
+00916         # output diffuse to o[COL0], replacing alpha with material alpha.                                       \n\
+00917         MAD     o[COL0], R2, c[CTS+10].zzzx, c[CTS+10].xxxw;                                                                    \n\
+00918 ";
+00919 
+00920 // ***************************************************************************
+00921 static  void    strReplaceAll(string &strInOut, const string &tokenSrc, const string &tokenDst)
+00922 {
+00923         uint32  pos;
+00924         sint    srcLen= tokenSrc.size();
+00925         while( (pos=strInOut.find(tokenSrc)) != string::npos)
+00926         {
+00927                 strInOut.replace(pos, srcLen, tokenDst);
+00928         }
+00929 }
+00930 
+00931 // ***************************************************************************
+00932 std::string             CRenderTrav::getLightVPFragment(uint numActivePointLights, uint ctStart, bool supportSpecular, bool normalize)
+00933 {
+00934         string  ret;
+00935 
+00936         // Code frag written for 4 light max.
+00937         nlassert(MaxVPLight==4);
+00938         nlassert(numActivePointLights<=MaxVPLight-1);
+00939 
+00940         // Add LightingVPFragmentNormalize fragment?
+00941         if(normalize)
+00942                 ret+= LightingVPFragmentNormalize;
+00943 
+00944         // Which fragment to use...
+00945         if(supportSpecular)
+00946         {
+00947                 // Add start of VP.
+00948                 ret+= LightingVPFragmentSpecular_Begin;
+00949 
+00950                 // Add needed pointLights.
+00951                 for(uint i=0;i<numActivePointLights;i++)
+00952                 {
+00953                         ret+= LightingVPFragmentSpecular_PL[i];
+00954                 }
+00955 
+00956                 // Add end of VP.
+00957                 ret+= LightingVPFragmentSpecular_End;
+00958         }
+00959         else
+00960         {
+00961                 // Add start of VP.
+00962                 ret+= LightingVPFragmentNoSpecular_Begin;
+00963 
+00964                 // Add needed pointLights.
+00965                 for(uint i=0;i<numActivePointLights;i++)
+00966                 {
+00967                         ret+= LightingVPFragmentNoSpecular_PL[i];
+00968                 }
+00969 
+00970                 // Add end of VP.
+00971                 ret+= LightingVPFragmentNoSpecular_End;
+00972         }
+00973 
+00974         // Replace all CTS+x with good index. do it for 15 possible indices: 0 to 14 if specular.
+00975         // run from 14 to 0 so CTS+14 will not be taken for a CTS+1 !!
+00976         for(sint i=14; i>=0; i--)
+00977         {
+00978                 char    tokenSrc[256];
+00979                 sprintf(tokenSrc, "CTS+%d", i);
+00980                 char    tokenDst[256];
+00981                 sprintf(tokenDst, "%d", ctStart+i);
+00982                 // replace all in the string
+00983                 strReplaceAll(ret, tokenSrc, tokenDst);
+00984         }
+00985 
+00986         // verify no CTS+ leaved... (not all ctes parsed!!!)
+00987         nlassert( ret.find("CTS+")==string::npos );
+00988 
+00989         return ret;
+00990 }
+00991 
+00992 
+00993 }
+
+ + +
                                                                                                                                                                    +
+ + -- cgit v1.2.1