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/patch__render_8cpp-source.html | 1865 +++++++++++++++++++++++ 1 file changed, 1865 insertions(+) create mode 100644 docs/doxygen/nel/patch__render_8cpp-source.html (limited to 'docs/doxygen/nel/patch__render_8cpp-source.html') diff --git a/docs/doxygen/nel/patch__render_8cpp-source.html b/docs/doxygen/nel/patch__render_8cpp-source.html new file mode 100644 index 00000000..83546866 --- /dev/null +++ b/docs/doxygen/nel/patch__render_8cpp-source.html @@ -0,0 +1,1865 @@ + + + + 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  
+

patch_render.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 
+00029 #include "3d/patch.h"
+00030 #include "3d/tessellation.h"
+00031 #include "3d/bezier_patch.h"
+00032 #include "3d/zone.h"
+00033 #include "3d/landscape.h"
+00034 #include "3d/landscape_profile.h"
+00035 #include "3d/patchdlm_context.h"
+00036 #include "nel/misc/vector.h"
+00037 #include "nel/misc/common.h"
+00038 using   namespace       std;
+00039 using   namespace       NLMISC;
+00040 
+00041 
+00042 namespace NL3D 
+00043 {
+00044 
+00045 
+00046 // ***************************************************************************
+00047 // ***************************************************************************
+00048 // Patch Texture computation.
+00049 // ***************************************************************************
+00050 // ***************************************************************************
+00051 
+00052 
+00053 // ***************************************************************************
+00054 void                    CPatch::computeNewFar(sint &newFar0, sint &newFar1)
+00055 {
+00056         // Classify the patch.
+00057         //========================
+00058         float   r= (CLandscapeGlobals::RefineCenter-BSphere.Center).norm() - BSphere.Radius;
+00059         float   rr=0.0;
+00060         if(r<CLandscapeGlobals::TileDistNear)
+00061                 rr= r-CLandscapeGlobals::TileDistNear, newFar0= 0;
+00062         else if(r<CLandscapeGlobals::Far0Dist)
+00063                 rr= r-CLandscapeGlobals::Far0Dist, newFar0= 1;
+00064         else if(r<CLandscapeGlobals::Far1Dist)
+00065                 rr= r-CLandscapeGlobals::Far1Dist, newFar0= 2;
+00066         else
+00067                 newFar0= 3;
+00068         // Transition with the next level.
+00069         newFar1=0;
+00070         if(newFar0<3 && rr>-(CLandscapeGlobals::FarTransition+2*BSphere.Radius))
+00071         {
+00072                 newFar1= newFar0+1;
+00073         }
+00074 
+00075 
+00076         // Update Texture Info.
+00077         //========================
+00078         if(newFar0!=Far0 || newFar1!=Far1)
+00079         {
+00080                 // Backup old pass0
+00081                 CPatchRdrPass   *oldPass0=Pass0.PatchRdrPass;
+00082                 CPatchRdrPass   *oldPass1=Pass1.PatchRdrPass;
+00083 
+00084                 // Checks
+00085                 if (oldPass0==NULL)
+00086                         nlassert (Far0<=0);
+00087                 if (oldPass1==NULL)
+00088                         nlassert (Far1<=0);
+00089 
+00090                 float oldFar0UScale=Far0UScale;
+00091                 float oldFar0VScale=Far0VScale;
+00092                 float oldFar0UBias=Far0UBias;
+00093                 float oldFar0VBias=Far0VBias;
+00094                 uint8 oldFlags=Flags;
+00095 
+00096 
+00097                 // Don't delete the pass0 if the new newFar1 will use it
+00098                 if ((newFar1==Far0)&&(Far0>0))
+00099                         Pass0.PatchRdrPass=NULL;
+00100 
+00101                 // Don't delete the pass1 if the new newFar0 will use it
+00102                 if ((newFar0==Far1)&&(Far1>0))
+00103                         Pass1.PatchRdrPass=NULL;
+00104 
+00105                 // Pass0 have changed ?
+00106                 if (newFar0!=Far0)
+00107                 {
+00108                         // Compute / get the texture Far.
+00109                         if(newFar0>0)
+00110                         {
+00111                                 // Free the old pass, don't used any more
+00112                                 if (Pass0.PatchRdrPass)
+00113                                         Zone->Landscape->freeFarRenderPass (this, Pass0.PatchRdrPass, Far0);
+00114 
+00115                                 // Can we use the old pass1 ?
+00116                                 if (newFar0==Far1)
+00117                                 {
+00118                                         // Yes, recycle it!
+00119                                         Pass0.PatchRdrPass=oldPass1;
+00120 
+00121                                         // Copy uv coordinates
+00122                                         Far0UScale=Far1UScale;
+00123                                         Far0VScale=Far1VScale;
+00124                                         Far0UBias=Far1UBias;
+00125                                         Far0VBias=Far1VBias;
+00126 
+00127                                         // Copy rotation flag
+00128                                         Flags&=~NL_PATCH_FAR0_ROTATED;                  // erase it
+00129                                         if (Flags&NL_PATCH_FAR1_ROTATED)
+00130                                                 Flags|=NL_PATCH_FAR0_ROTATED;                   // copy it
+00131                                 }
+00132                                 else    // get a new render pass
+00133                                 {
+00134                                         // Rotation boolean
+00135                                         bool bRot;
+00136                                         Pass0.PatchRdrPass=Zone->Landscape->getFarRenderPass(this, newFar0, Far0UScale, Far0VScale, Far0UBias, Far0VBias, bRot);
+00137 
+00138                                         // Flags is set if the far texture is rotated of 90° to the left
+00139                                         if (bRot)
+00140                                                 Flags|=NL_PATCH_FAR0_ROTATED;
+00141                                         else
+00142                                                 Flags&=~NL_PATCH_FAR0_ROTATED;
+00143                                 }
+00144                         }
+00145                         else    // no more far pass0
+00146                         {
+00147                                 if (Pass0.PatchRdrPass)
+00148                                 {
+00149                                         Zone->Landscape->freeFarRenderPass (this, Pass0.PatchRdrPass, Far0);
+00150                                         Pass0.PatchRdrPass=NULL;
+00151                                 }
+00152                         }
+00153                 }
+00154 
+00155                 // Pass1 have changed ?
+00156                 if (newFar1!=Far1)
+00157                 {
+00158                         // Now let's go with pass1
+00159                         if(newFar1>0)
+00160                         {
+00161                                 // Delete the pass1 if not used any more
+00162                                 if (Pass1.PatchRdrPass)
+00163                                         Zone->Landscape->freeFarRenderPass (this, Pass1.PatchRdrPass, Far1);
+00164 
+00165                                 // Can we use the old pass1 ?
+00166                                 if (newFar1==Far0)
+00167                                 {
+00168                                         // Yes, recycle it!
+00169                                         Pass1.PatchRdrPass= oldPass0;
+00170                                         nlassert (Pass1.PatchRdrPass);
+00171 
+00172                                         // Copy uv coordinates
+00173                                         Far1UScale=oldFar0UScale;
+00174                                         Far1VScale=oldFar0VScale;
+00175                                         Far1UBias=oldFar0UBias;
+00176                                         Far1VBias=oldFar0VBias;
+00177 
+00178                                         // Copy rotation flag
+00179                                         Flags&=~NL_PATCH_FAR1_ROTATED;                  // erase it
+00180                                         if (oldFlags&NL_PATCH_FAR0_ROTATED)
+00181                                                 Flags|=NL_PATCH_FAR1_ROTATED;                   // copy it
+00182                                 }
+00183                                 else    // get a new render pass
+00184                                 {
+00185                                         // Rotation boolean
+00186                                         bool bRot;
+00187                                         Pass1.PatchRdrPass=Zone->Landscape->getFarRenderPass(this, newFar1, Far1UScale, Far1VScale, Far1UBias, Far1VBias, bRot);
+00188                                         nlassert (Pass1.PatchRdrPass);
+00189 
+00190                                         // Flags is set if the far texture is rotated of 90° to the left
+00191                                         if (bRot)
+00192                                                 Flags|=NL_PATCH_FAR1_ROTATED;
+00193                                         else
+00194                                                 Flags&=~NL_PATCH_FAR1_ROTATED;
+00195                                 }
+00196 
+00197                                 // Compute info for transition.
+00198                                 float   farDist;
+00199                                 switch(newFar1)
+00200                                 {
+00201                                         case 1: farDist= CLandscapeGlobals::TileDistNear; break;
+00202                                         case 2: farDist= CLandscapeGlobals::Far0Dist; break;
+00203                                         case 3: farDist= CLandscapeGlobals::Far1Dist; break;
+00204                                         default: nlstop;
+00205                                 };
+00206                                 TransitionSqrMin= sqr(farDist-CLandscapeGlobals::FarTransition);
+00207                                 OOTransitionSqrDelta= 1.0f/(sqr(farDist)-TransitionSqrMin);
+00208                         }
+00209                         else    // no more far pass1
+00210                         {
+00211                                 if (Pass1.PatchRdrPass)
+00212                                 {
+00213                                         Zone->Landscape->freeFarRenderPass (this, Pass1.PatchRdrPass, Far1);
+00214                                         Pass1.PatchRdrPass=NULL;
+00215                                 }
+00216                         }
+00217                 }
+00218 
+00219         }
+00220 
+00221         // Don't copy Far0 and Far1.
+00222 }
+00223 
+00224 
+00225 // ***************************************************************************
+00226 void                    CPatch::updateTextureFarOnly()
+00227 {
+00228         // If visible, don't change Far, because VB must be changed too. preRender() should have been called isntead.
+00229         if(!RenderClipped)
+00230                 return;
+00231 
+00232         sint    newFar0,newFar1;
+00233         // compute new Far0 and new Far1.
+00234         computeNewFar(newFar0, newFar1);
+00235 
+00236         // Far change.
+00237         //------------------
+00238         // Set new far values
+00239         Far0= newFar0;
+00240         Far1= newFar1;
+00241 }
+00242 
+00243 
+00244 
+00245 // ***************************************************************************
+00246 // ***************************************************************************
+00247 // Patch / Face rendering.
+00248 // ***************************************************************************
+00249 // ***************************************************************************
+00250 
+00251 
+00252 // ***************************************************************************
+00253 void                    CPatch::preRender()
+00254 {
+00255         // If not visible, do nothing.
+00256         if(RenderClipped)
+00257                 return;
+00258 
+00259 
+00260         // 0. Classify the patch, and update TextureInfo.
+00261         //=======================
+00262         sint    newFar0,newFar1;
+00263         // compute new Far0 and new Far1.
+00264         computeNewFar(newFar0, newFar1);
+00265 
+00266 
+00267         // 2. Update vertices in VB
+00268         //========================
+00269         sint    oldFar0= Far0, oldFar1= Far1;
+00270 
+00271         // Test if go in or go out tileMode.
+00272         bool    changeTileMode;
+00273         // this is true if a change is made, and if old or current is in TileMode.
+00274         changeTileMode= (newFar0!=oldFar0) && (newFar0==0 || oldFar0==0);
+00275         // Or this is true if Far0 / Far1 was invalid before.
+00276         changeTileMode= changeTileMode || oldFar0==-1 || oldFar1==-1;
+00277 
+00278         // Pre VB change.
+00279         //------------------
+00280         // In this case, major change: delete all VB, then recreate after.
+00281         if(changeTileMode)
+00282         {
+00283                 // delete the old VB (NB: RenderClipped==false here). 
+00284                 // NB: Far0 and Far1 are still unmodified, so deleteVB() will do the good job.
+00285                 deleteVBAndFaceVector();
+00286         }
+00287         else
+00288         {
+00289                 // minor change: Far0 UV, or Far1.
+00290                 // Far0 UV: do nothing here.
+00291                 // If change in Far1, must delete Far1
+00292                 if(newFar1!=oldFar1)
+00293                 {
+00294                         // NB: Far1 is still unmodified, so deleteVB() will do the good job.
+00295                         deleteVBAndFaceVectorFar1Only();
+00296                 }
+00297         }
+00298 
+00299         // Far change.
+00300         //------------------
+00301         // Set new far values
+00302         Far0= newFar0;
+00303         Far1= newFar1;
+00304 
+00305 
+00306         // Post VB change.
+00307         //------------------
+00308         if(changeTileMode)
+00309         {
+00310                 // major change: recreate all the VB.
+00311                 allocateVBAndFaceVector();
+00312                 // Then try to refill if possible.
+00313                 fillVB();
+00314         }
+00315         else
+00316         {
+00317                 // minor change: Far0 UV, or Far1.
+00318                 // If change in Far0
+00319                 if(newFar0!=oldFar0)
+00320                 {
+00321                         // Then must recompute VB with good UVs.
+00322                         // An optimisation is to check if UVs had really change (see UScale ...)
+00323                         // but the case they don't change is very rare: 1/16.
+00324                         fillVBFar0Only();
+00325                 }
+00326 
+00327                 // If change in Far1, must allcoate and recompute UVs.
+00328                 if(newFar1!=oldFar1)
+00329                 {
+00330                         allocateVBAndFaceVectorFar1Only();
+00331                         // try to fill if no reallocation problem
+00332                         fillVBFar1Only();
+00333                 }
+00334         }
+00335 
+00336 
+00337         // 3. Append patch to renderList.
+00338         //=====================
+00339         // This patch is visible. So if good far, append.
+00340         if(Far0>0)
+00341         {
+00342                 Pass0.PatchRdrPass->appendRdrPatchFar0(&Pass0, NumRenderableFaces);
+00343         }
+00344         // Same for Far1.
+00345         if(Far1>0)
+00346         {
+00347                 Pass1.PatchRdrPass->appendRdrPatchFar1(&Pass1, NumRenderableFaces);
+00348         }
+00349 
+00350 
+00351         // 4. Clip tess blocks.
+00352         //=====================
+00353         // If we are in Tile/FarTransition
+00354         bool    doClipFar= Far0==0 && Far1==1;
+00355         // Parse all TessBlocks.
+00356         uint                    nTessBlock= TessBlocks.size();
+00357         CTessBlock              *pTessBlock= nTessBlock>0? &TessBlocks[0]: NULL ;
+00358         for(; nTessBlock>0; pTessBlock++, nTessBlock--)
+00359         {
+00360                 CTessBlock              &tblock= *pTessBlock;
+00361 
+00362                 // bkup the old result for clipping
+00363                 bool    oldVisibleFar0= tblock.visibleFar0();
+00364                 bool    oldVisibleTile= tblock.visibleTile();
+00365                 bool    oldVisibleFar1= tblock.visibleFar1();
+00366 
+00367                 // If this TessBlock is empty, do not need to clip
+00368                 if(tblock.FaceTileMaterialRefCount==0)
+00369                 {
+00370                         // Simply force the clip.
+00371                         tblock.forceClip();
+00372                 }
+00373                 else
+00374                 {
+00375                         // clip the tessBlock.
+00376                         tblock.resetClip();
+00377                         tblock.clip();
+00378                         // If we are in Tile/FarTransition
+00379                         if(doClipFar)
+00380                                 tblock.clipFar(CLandscapeGlobals::RefineCenter, CLandscapeGlobals::TileDistNear, CLandscapeGlobals::FarTransition);
+00381 
+00382                         // If TileMode, and if tile visible
+00383                         if(Far0==0 && tblock.visibleTile() )
+00384                         {
+00385                                 // Append all tiles (if any) to the renderPass list!
+00386                                 for(uint j=0;j<NL3D_TESSBLOCK_TILESIZE; j++)
+00387                                 {
+00388                                         // If tile exist
+00389                                         if(tblock.RdrTileRoot[j])
+00390                                                 // add it to the renderList
+00391                                                 tblock.RdrTileRoot[j]->appendTileToEachRenderPass(NumRenderableFaces);
+00392                                 }
+00393                         }       
+00394                 }
+00395 
+00396                 // If change of clip in tessBlock, must update the tessBlock
+00397                 if( Far0> 0 && oldVisibleFar0 != tblock.visibleFar0() )
+00398                 {
+00399                         if( tblock.visibleFar0() )
+00400                         {
+00401                                 // allocate
+00402                                 updateFar0VBAlloc(tblock.FarVertexList, true);
+00403                                 // fill only if possible.
+00404                                 if(!CLandscapeGlobals::CurrentFar0VBAllocator->reallocationOccurs())
+00405                                         fillFar0VertexListVB(tblock.FarVertexList);
+00406                                 // rebuild triangles index list.
+00407                                 tblock.refillFaceVectorFar0();
+00408                         }
+00409                         else
+00410                         {
+00411                                 // delete
+00412                                 updateFar0VBAlloc(tblock.FarVertexList, false);
+00413                         }
+00414                 }
+00415                 if( Far0==0 && oldVisibleTile != tblock.visibleTile() )
+00416                 {
+00417                         if( tblock.visibleTile() )
+00418                         {
+00419                                 // allocate
+00420                                 updateTileVBAlloc(tblock.NearVertexList, true);
+00421                                 // fill only if possible.
+00422                                 if(!CLandscapeGlobals::CurrentTileVBAllocator->reallocationOccurs())
+00423                                         fillTileVertexListVB(tblock.NearVertexList);
+00424                                 // rebuild triangles index list.
+00425                                 tblock.refillFaceVectorTile();
+00426                         }
+00427                         else
+00428                         {
+00429                                 // delete
+00430                                 updateTileVBAlloc(tblock.NearVertexList, false);
+00431                         }
+00432                 }
+00433                 if( Far1> 0 && oldVisibleFar1 != tblock.visibleFar1() )
+00434                 {
+00435                         if( tblock.visibleFar1() )
+00436                         {
+00437                                 // allocate
+00438                                 updateFar1VBAlloc(tblock.FarVertexList, true);
+00439                                 // fill only if possible.
+00440                                 if(!CLandscapeGlobals::CurrentFar1VBAllocator->reallocationOccurs())
+00441                                         fillFar1VertexListVB(tblock.FarVertexList);
+00442                                 // rebuild triangles index list.
+00443                                 tblock.refillFaceVectorFar1();
+00444                         }
+00445                         else
+00446                         {
+00447                                 // delete
+00448                                 updateFar1VBAlloc(tblock.FarVertexList, false);
+00449                         }
+00450                 }
+00451         }
+00452 
+00453 }
+00454 
+00455 
+00456 // Special profiling.
+00457 #ifdef  NL3D_PROFILE_LAND
+00458 #define NL3D_PROFILE_LAND_ADD_FACE_VECTOR(_x, _fv)              \
+00459         if(_fv)                                                                                 \
+00460         {                                                                                               \
+00461                 NL3D_PROFILE_LAND_ADD(_x, _fv->NumTri);         \
+00462         }
+00463 #else
+00464 #define NL3D_PROFILE_LAND_ADD_FACE_VECTOR(_x, _fv)
+00465 #endif
+00466 
+00467 
+00468 // ***************************************************************************
+00469 static  inline  void    renderFaceVector(CLandscapeFaceVector *fv)
+00470 {
+00471         // If not NULL (ie not empty).
+00472         if(fv)
+00473         {
+00474                 // TestYoyo: Bench.
+00475                 /*
+00476                 extern  uint    TEMP_NRFV;
+00477                 extern  uint    TEMP_NRFVTri;
+00478                 extern  float   TEMP_NRFVMeanTri;
+00479                 extern  float   TEMP_NRFVDeltaTri;
+00480                 TEMP_NRFV++;
+00481                 TEMP_NRFVTri+= fv->NumTri;
+00482                 TEMP_NRFVDeltaTri+= sqr(fv->NumTri-TEMP_NRFVMeanTri);
+00483                 */
+00484 
+00485                 // here we have NumTri>0, because fv!=NULL.
+00486 
+00487                 // making lot of render() is slower than copy a block, and render it.
+00488                 //CLandscapeGlobals::PatchCurrentDriver->renderSimpleTriangles(fv->TriPtr, fv->NumTri);
+00489 
+00490 #ifdef  NL_OS_WINDOWS
+00491                 __asm
+00492                 {
+00493                         mov             ebx, fv
+00494                         mov             edi, NL3D_LandscapeGlobals_PassTriCurPtr
+00495 
+00496                         mov             edx, NL3D_LandscapeGlobals_PassNTri
+00497                         xor             eax, eax                // Avoid AGI stall.
+00498 
+00499                         mov             ecx, [ebx]fv.NumTri
+00500                         mov             esi, [ebx]fv.TriPtr
+00501 
+00502                         mov             eax, ecx                                // eax= bkup NumTris
+00503                         lea             ecx, [ecx + ecx*2]              // ecx= nTriIndex= NumTris*3
+00504 
+00505                         // copy tri indices
+00506                         rep             movsd
+00507 
+00508                         add             edx, eax                                // edx= NL3D_LandscapeGlobals_PassNTri + fv->NumTri;
+00509 
+00510                         // NL3D_LandscapeGlobals_PassTriCurPtr= edi= new ptr after copy
+00511                         mov             NL3D_LandscapeGlobals_PassTriCurPtr, edi
+00512                         mov             NL3D_LandscapeGlobals_PassNTri, edx
+00513                 }
+00514 #else
+00515                 uint    nTriIndex= fv->NumTri*3;
+00516                 // Fill and increment the array.
+00517                 memcpy( NL3D_LandscapeGlobals_PassTriCurPtr, fv->TriPtr, nTriIndex * sizeof(uint32) );
+00518                 NL3D_LandscapeGlobals_PassTriCurPtr+= nTriIndex;
+00519                 NL3D_LandscapeGlobals_PassNTri+= fv->NumTri;
+00520 #endif
+00521         }
+00522 }
+00523 
+00524 
+00525 // ***************************************************************************
+00526 void                    CPatch::renderFar0()
+00527 {
+00528         // Must be visible, and must be called only if the RdrPass is enabled.
+00529         nlassert(!RenderClipped && Pass0.PatchRdrPass);
+00530 
+00531         // Render tris of MasterBlock.
+00532         renderFaceVector(MasterBlock.Far0FaceVector);
+00533         // profile
+00534         NL3D_PROFILE_LAND_ADD_FACE_VECTOR(ProfNRdrFar0, MasterBlock.Far0FaceVector);
+00535 
+00536         // Render tris of TessBlocks.
+00537         uint                    nTessBlock= TessBlocks.size();
+00538         CTessBlock              *pTessBlock= nTessBlock>0? &TessBlocks[0]: NULL ;
+00539         for(; nTessBlock>0; pTessBlock++, nTessBlock--)
+00540         {
+00541                 CTessBlock              &tblock= *pTessBlock;
+00542                 // if block visible, render
+00543                 if( tblock.visibleFar0() )
+00544                 {
+00545                         renderFaceVector(tblock.Far0FaceVector);
+00546                         // profile
+00547                         NL3D_PROFILE_LAND_ADD_FACE_VECTOR(ProfNRdrFar0, tblock.Far0FaceVector);
+00548                 }
+00549         }
+00550 
+00551         // Check the pass is in the set
+00552 #ifdef NL_DEBUG
+00553         if (Pass0.PatchRdrPass)
+00554         {
+00555                 nlassert (Zone->Landscape->_FarRdrPassSet.find (Pass0.PatchRdrPass)!=Zone->Landscape->_FarRdrPassSet.end());
+00556                 if (Zone->Landscape->_FarRdrPassSet.find (Pass0.PatchRdrPass)==Zone->Landscape->_FarRdrPassSet.end())
+00557                 {
+00558                         bool bFound=false;
+00559                         {
+00560                                 for (sint t=0; t<(sint)Zone->Landscape->_FarRdrPassSetVectorFree.size(); t++)
+00561                                 {
+00562                                         if (Zone->Landscape->_FarRdrPassSetVectorFree[t].find (Pass0.PatchRdrPass)!=Zone->Landscape->_FarRdrPassSetVectorFree[t].end())
+00563                                         {
+00564                                                 bFound=true;
+00565                                                 break;
+00566                                         }
+00567                                 }
+00568                         }
+00569                         nlassert (bFound);
+00570                 }
+00571         }
+00572 #endif // NL_DEBUG
+00573 }
+00574 
+00575 
+00576 // ***************************************************************************
+00577 void                    CPatch::renderFar1()
+00578 {
+00579         // Must be visible, and must be called only if the RdrPass is enabled.
+00580         nlassert(!RenderClipped && Pass1.PatchRdrPass);
+00581 
+00582         // Render tris of MasterBlock.
+00583         renderFaceVector(MasterBlock.Far1FaceVector);
+00584         // profile.
+00585         NL3D_PROFILE_LAND_ADD_FACE_VECTOR(ProfNRdrFar1, MasterBlock.Far1FaceVector);
+00586 
+00587         // Render tris of TessBlocks.
+00588         uint                    nTessBlock= TessBlocks.size();
+00589         CTessBlock              *pTessBlock= nTessBlock>0? &TessBlocks[0]: NULL ;
+00590         for(; nTessBlock>0; pTessBlock++, nTessBlock--)
+00591         {
+00592                 CTessBlock              &tblock= *pTessBlock;
+00593                 // if block visible, render
+00594                 if( tblock.visibleFar1() )
+00595                 {
+00596                         renderFaceVector(tblock.Far1FaceVector);
+00597                         // profile.
+00598                         NL3D_PROFILE_LAND_ADD_FACE_VECTOR(ProfNRdrFar1, tblock.Far1FaceVector);
+00599                 }
+00600         }
+00601 
+00602         // Check the pass is in the set
+00603 #ifdef NL_DEBUG
+00604         if (Pass1.PatchRdrPass)
+00605         {
+00606                 nlassert (Zone->Landscape->_FarRdrPassSet.find (Pass1.PatchRdrPass)!=Zone->Landscape->_FarRdrPassSet.end());
+00607                 if (Zone->Landscape->_FarRdrPassSet.find (Pass1.PatchRdrPass)==Zone->Landscape->_FarRdrPassSet.end())
+00608                 {
+00609                         bool bFound=false;
+00610                         {
+00611                                 for (sint t=0; t<(sint)Zone->Landscape->_FarRdrPassSetVectorFree.size(); t++)
+00612                                 {
+00613                                         if (Zone->Landscape->_FarRdrPassSetVectorFree[t].find (Pass1.PatchRdrPass)!=Zone->Landscape->_FarRdrPassSetVectorFree[t].end())
+00614                                         {
+00615                                                 bFound=true;
+00616                                                 break;
+00617                                         }
+00618                                 }
+00619                         }
+00620                         nlassert (bFound);
+00621                 }
+00622         }
+00623 #endif // NL_DEBUG
+00624 }
+00625 
+00626 
+00627 // ***************************************************************************
+00628 void                    CTileMaterial::renderTile(uint pass)
+00629 {
+00630         // because precisely inserted in preRender(), and correctly tested, this tile is to be rendered,
+00631         // If the pass is enabled.
+00632         if(Pass[pass].PatchRdrPass)
+00633         {
+00634                 // render tris of the good faceList.
+00635                 renderFaceVector(TileFaceVectors[pass]);
+00636 
+00637                 // profile.
+00638                 NL3D_PROFILE_LAND_ADD_FACE_VECTOR(ProfNRdrTile[pass], TileFaceVectors[pass]);
+00639         }
+00640 }
+00641 
+00642 // ***************************************************************************
+00643 void                    CTileMaterial::renderTilePassRGB0()
+00644 {
+00645         // because precisely inserted in preRender(), and correctly tested, this tile is to be rendered,
+00646         // this pass must be enabled!
+00647         nlassert(Pass[NL3D_TILE_PASS_RGB0].PatchRdrPass);
+00648         // render tris of the good faceList.
+00649         renderFaceVector(TileFaceVectors[NL3D_TILE_PASS_RGB0]);
+00650 
+00651         // profile.
+00652         NL3D_PROFILE_LAND_ADD_FACE_VECTOR(ProfNRdrTile[NL3D_TILE_PASS_RGB0], TileFaceVectors[NL3D_TILE_PASS_RGB0]);
+00653 }
+00654 
+00655 // ***************************************************************************
+00656 void                    CTileMaterial::renderTilePassLightmap()
+00657 {
+00658         // because precisely inserted in preRender(), and correctly tested, this tile is to be rendered,
+00659         // this pass must be enabled!
+00660         nlassert(Pass[NL3D_TILE_PASS_LIGHTMAP].PatchRdrPass);
+00661         // render tris of the good faceList, ie the one of PassRGB0, because vertices are reused.
+00662         renderFaceVector(TileFaceVectors[NL3D_TILE_PASS_RGB0]);
+00663 
+00664         // profile.
+00665         NL3D_PROFILE_LAND_ADD_FACE_VECTOR(ProfNRdrTile[NL3D_TILE_PASS_LIGHTMAP], TileFaceVectors[NL3D_TILE_PASS_RGB0]);
+00666 }
+00667 
+00668 
+00669 // ***************************************************************************
+00670 // ***************************************************************************
+00671 // FaceVector Allocation
+00672 // ***************************************************************************
+00673 // ***************************************************************************
+00674 
+00675 
+00676 // ***************************************************************************
+00677 void            CPatch::createFaceVectorFar1()
+00678 {
+00679         if(Far1>0)
+00680         {
+00681                 // Create the face for all TessBlocks.
+00682                 MasterBlock.createFaceVectorFar1(getLandscape()->_FaceVectorManager);
+00683                 for(uint i=0; i<TessBlocks.size(); i++)
+00684                         TessBlocks[i].createFaceVectorFar1(getLandscape()->_FaceVectorManager);
+00685         }
+00686 }
+00687 // ***************************************************************************
+00688 void            CPatch::deleteFaceVectorFar1()
+00689 {
+00690         if(Far1>0)
+00691         {
+00692                 // delete the face for all TessBlocks.
+00693                 MasterBlock.deleteFaceVectorFar1(getLandscape()->_FaceVectorManager);
+00694                 for(uint i=0; i<TessBlocks.size(); i++)
+00695                         TessBlocks[i].deleteFaceVectorFar1(getLandscape()->_FaceVectorManager);
+00696         }
+00697 }
+00698 // ***************************************************************************
+00699 void            CPatch::createFaceVectorFar0OrTile()
+00700 {
+00701         // If Far Mode.
+00702         if(Far0>0)
+00703         {
+00704                 // Create the face for all TessBlocks.
+00705                 MasterBlock.createFaceVectorFar0(getLandscape()->_FaceVectorManager);
+00706                 for(uint i=0; i<TessBlocks.size(); i++)
+00707                         TessBlocks[i].createFaceVectorFar0(getLandscape()->_FaceVectorManager);
+00708         }
+00709         // Or If Tile Mode.
+00710         else if(Far0==0)
+00711         {
+00712                 // Create the face for all TessBlocks.
+00713                 // No tiles in MasterBlock!
+00714                 for(uint i=0; i<TessBlocks.size(); i++)
+00715                         TessBlocks[i].createFaceVectorTile(getLandscape()->_FaceVectorManager);
+00716         }
+00717 }
+00718 // ***************************************************************************
+00719 void            CPatch::deleteFaceVectorFar0OrTile()
+00720 {
+00721         // If Far Mode.
+00722         if(Far0>0)
+00723         {
+00724                 // delete the face for all TessBlocks.
+00725                 MasterBlock.deleteFaceVectorFar0(getLandscape()->_FaceVectorManager);
+00726                 for(uint i=0; i<TessBlocks.size(); i++)
+00727                         TessBlocks[i].deleteFaceVectorFar0(getLandscape()->_FaceVectorManager);
+00728         }
+00729         // Or If Tile Mode.
+00730         else if(Far0==0)
+00731         {
+00732                 // delete the face for all TessBlocks.
+00733                 // No tiles in MasterBlock!
+00734                 for(uint i=0; i<TessBlocks.size(); i++)
+00735                         TessBlocks[i].deleteFaceVectorTile(getLandscape()->_FaceVectorManager);
+00736         }
+00737 }
+00738 
+00739 
+00740 // ***************************************************************************
+00741 void            CPatch::recreateTessBlockFaceVector(CTessBlock &block)
+00742 {
+00743         // Do it Only if patch is visible.
+00744         if(!RenderClipped)
+00745         {
+00746                 // Far0.
+00747                 // If Far Mode.
+00748                 if(Far0>0)
+00749                 {
+00750                         // Create the face for this TessBlock only.
+00751                         block.createFaceVectorFar0(getLandscape()->_FaceVectorManager);
+00752                 }
+00753                 // Or If Tile Mode.
+00754                 else if(Far0==0)
+00755                 {
+00756                         // No tiles in MasterBlock! So no need to call createFaceVectorTile(), if this block is the MasterBlock.
+00757                         if(&block != &MasterBlock)
+00758                                 block.createFaceVectorTile(getLandscape()->_FaceVectorManager);
+00759                 }
+00760 
+00761                 // Far1.
+00762                 if(Far1>0)
+00763                 {
+00764                         // Create the face for this TessBlock only.
+00765                         block.createFaceVectorFar1(getLandscape()->_FaceVectorManager);
+00766                 }
+00767         }
+00768 
+00769 }
+00770 
+00771 
+00772 // ***************************************************************************
+00773 // ***************************************************************************
+00774 // VB Allocation
+00775 // ***************************************************************************
+00776 // ***************************************************************************
+00777 
+00778 
+00779 // ***************************************************************************
+00780 void            CPatch::updateFar0VBAlloc(CTessList<CTessFarVertex>  &vertList, bool alloc)
+00781 {
+00782         // Traverse the vertList.
+00783         CTessFarVertex  *pVert;
+00784         for(pVert= vertList.begin(); pVert; pVert= (CTessFarVertex*)pVert->Next)
+00785         {
+00786                 if(alloc)
+00787                         pVert->Index0= CLandscapeGlobals::CurrentFar0VBAllocator->allocateVertex();
+00788                 else
+00789                         CLandscapeGlobals::CurrentFar0VBAllocator->deleteVertex(pVert->Index0);
+00790         }
+00791 }
+00792 
+00793 
+00794 // ***************************************************************************
+00795 void            CPatch::updateFar1VBAlloc(CTessList<CTessFarVertex>  &vertList, bool alloc)
+00796 {
+00797         // Traverse the vertList.
+00798         CTessFarVertex  *pVert;
+00799         for(pVert= vertList.begin(); pVert; pVert= (CTessFarVertex*)pVert->Next)
+00800         {
+00801                 if(alloc)
+00802                         pVert->Index1= CLandscapeGlobals::CurrentFar1VBAllocator->allocateVertex();
+00803                 else
+00804                         CLandscapeGlobals::CurrentFar1VBAllocator->deleteVertex(pVert->Index1);
+00805         }
+00806 }
+00807 
+00808 
+00809 // ***************************************************************************
+00810 void            CPatch::updateTileVBAlloc(CTessList<CTessNearVertex>  &vertList, bool alloc)
+00811 {
+00812         // Traverse the vertList.
+00813         CTessNearVertex *pVert;
+00814         for(pVert= vertList.begin(); pVert; pVert= (CTessNearVertex*)pVert->Next)
+00815         {
+00816                 if(alloc)
+00817                         pVert->Index= CLandscapeGlobals::CurrentTileVBAllocator->allocateVertex();
+00818                 else
+00819                         CLandscapeGlobals::CurrentTileVBAllocator->deleteVertex(pVert->Index);
+00820         }
+00821 }
+00822 
+00823 
+00824 // ***************************************************************************
+00825 void                    CPatch::updateVBAlloc(bool alloc)
+00826 {
+00827         // update Far0.
+00828         //=======
+00829         if(Far0>0)
+00830         {
+00831                 // alloc Far0 VB.
+00832                 updateFar0VBAlloc(MasterBlock.FarVertexList, alloc);
+00833                 for(sint i=0; i<(sint)TessBlocks.size(); i++)
+00834                 {
+00835                         CTessBlock      &tblock= TessBlocks[i];
+00836                         // need update VB only if tessBlock is visible.
+00837                         if( tblock.visibleFar0() )
+00838                                 updateFar0VBAlloc(tblock.FarVertexList, alloc);
+00839                 }
+00840         }
+00841         else if (Far0==0)
+00842         {
+00843                 // alloc Tile VB.
+00844                 // No Tiles in MasterBlock!!
+00845                 // Traverse the TessBlocks to add vertices.
+00846                 for(sint i=0; i<(sint)TessBlocks.size(); i++)
+00847                 {
+00848                         CTessBlock      &tblock= TessBlocks[i];
+00849                         // Add the vertices.
+00850                         // need update VB only if tessBlock is visible.
+00851                         if( tblock.visibleTile() )
+00852                                 updateTileVBAlloc(tblock.NearVertexList, alloc);
+00853                 }
+00854         }
+00855 
+00856         // update Far1.
+00857         //=======
+00858         if(Far1>0)
+00859         {
+00860                 // alloc VB.
+00861                 updateFar1VBAlloc(MasterBlock.FarVertexList, alloc);
+00862                 for(sint i=0; i<(sint)TessBlocks.size(); i++)
+00863                 {
+00864                         CTessBlock      &tblock= TessBlocks[i];
+00865                         // need update VB only if tessBlock is visible.
+00866                         if( tblock.visibleFar1() )
+00867                                 updateFar1VBAlloc(tblock.FarVertexList, alloc);
+00868                 }
+00869         }
+00870 }
+00871 
+00872 // ***************************************************************************
+00873 void                    CPatch::deleteVBAndFaceVector()
+00874 {
+00875         updateVBAlloc(false);
+00876         deleteFaceVectorFar1();
+00877         deleteFaceVectorFar0OrTile();
+00878 }
+00879 
+00880 // ***************************************************************************
+00881 void                    CPatch::allocateVBAndFaceVector()
+00882 {
+00883         updateVBAlloc(true);
+00884         createFaceVectorFar1();
+00885         createFaceVectorFar0OrTile();
+00886 }
+00887 
+00888 
+00889 // ***************************************************************************
+00890 void            CPatch::deleteVBAndFaceVectorFar1Only()
+00891 {
+00892         if(Far1>0)
+00893         {
+00894                 // alloc VB.
+00895                 updateFar1VBAlloc(MasterBlock.FarVertexList, false);
+00896                 for(sint i=0; i<(sint)TessBlocks.size(); i++)
+00897                 {
+00898                         CTessBlock      &tblock= TessBlocks[i];
+00899                         // need update VB only if tessBlock is visible.
+00900                         if( tblock.visibleFar1() )
+00901                                 updateFar1VBAlloc(tblock.FarVertexList, false);
+00902                 }
+00903         }
+00904 
+00905         deleteFaceVectorFar1();
+00906 }
+00907 
+00908 // ***************************************************************************
+00909 void            CPatch::allocateVBAndFaceVectorFar1Only()
+00910 {
+00911         if(Far1>0)
+00912         {
+00913                 // alloc VB.
+00914                 updateFar1VBAlloc(MasterBlock.FarVertexList, true);
+00915                 for(sint i=0; i<(sint)TessBlocks.size(); i++)
+00916                 {
+00917                         CTessBlock      &tblock= TessBlocks[i];
+00918                         // need update VB only if tessBlock is visible.
+00919                         if( tblock.visibleFar1() )
+00920                                 updateFar1VBAlloc(tblock.FarVertexList, true);
+00921                 }
+00922         }
+00923 
+00924         createFaceVectorFar1();
+00925 }
+00926 
+00927 
+00928 // ***************************************************************************
+00929 void            CPatch::debugAllocationMarkIndicesFarList(CTessList<CTessFarVertex>  &vertList, uint marker)
+00930 {
+00931         // Traverse the vertList.
+00932         CTessFarVertex  *pVert;
+00933         for(pVert= vertList.begin(); pVert; pVert= (CTessFarVertex*)pVert->Next)
+00934         {
+00935                 pVert->Index0= marker;
+00936                 pVert->Index1= marker;
+00937         }
+00938 }
+00939 
+00940 void            CPatch::debugAllocationMarkIndicesNearList(CTessList<CTessNearVertex>  &vertList, uint marker)
+00941 {
+00942         // Traverse the vertList.
+00943         CTessNearVertex *pVert;
+00944         for(pVert= vertList.begin(); pVert; pVert= (CTessNearVertex*)pVert->Next)
+00945         {
+00946                 pVert->Index= marker;
+00947         }
+00948 }
+00949 
+00950 void            CPatch::debugAllocationMarkIndices(uint marker)
+00951 {
+00952         sint i;
+00953 
+00954         // Do it For Far.
+00955         debugAllocationMarkIndicesFarList(MasterBlock.FarVertexList, marker);
+00956         for(i=0; i<(sint)TessBlocks.size(); i++)
+00957         {
+00958                 CTessBlock      &tblock= TessBlocks[i];
+00959                 debugAllocationMarkIndicesFarList(tblock.FarVertexList, marker);
+00960         }
+00961         // Do it For Near.
+00962         // No Tiles in MasterBlock!!
+00963         for(i=0; i<(sint)TessBlocks.size(); i++)
+00964         {
+00965                 CTessBlock      &tblock= TessBlocks[i];
+00966                 debugAllocationMarkIndicesNearList(tblock.NearVertexList, marker);
+00967         }
+00968 
+00969 }
+00970 
+00971 
+00972 
+00973 // ***************************************************************************
+00974 // ***************************************************************************
+00975 // VB Filling.
+00976 // ***************************************************************************
+00977 // ***************************************************************************
+00978 
+00979 
+00980 // ***************************************************************************
+00981 // NB: need to be inlined only for fillFar0VB() in this file.
+00982 inline void             CPatch::fillFar0VertexVB(CTessFarVertex *pVert)
+00983 {
+00984         // The Buffers must have been locked
+00985         nlassert(CLandscapeGlobals::CurrentFar0VBAllocator);
+00986         nlassert(CLandscapeGlobals::CurrentFar0VBAllocator->bufferLocked());
+00987         // VBInfo must be OK.
+00988         nlassert(!CLandscapeGlobals::CurrentFar0VBAllocator->reallocationOccurs());
+00989 
+00990         static  uint8   *CurVBPtr;
+00991         // Compute/build the new vertex.
+00992         CurVBPtr= (uint8*)CLandscapeGlobals::CurrentFar0VBInfo.VertexCoordPointer;
+00993         CurVBPtr+= pVert->Index0 * CLandscapeGlobals::CurrentFar0VBInfo.VertexSize;
+00994 
+00995         // NB: the filling order of data is important, for AGP write combiners.
+00996 
+00997         // compute Uvs.
+00998         static CUV      uv;
+00999         CParamCoord     pc= pVert->PCoord;
+01000         if (Flags&NL_PATCH_FAR0_ROTATED)
+01001         {
+01002                 uv.U= pc.getT()* Far0UScale + Far0UBias;
+01003                 uv.V= (1.f-pc.getS())* Far0VScale + Far0VBias;
+01004         }
+01005         else
+01006         {
+01007                 uv.U= pc.getS()* Far0UScale + Far0UBias;
+01008                 uv.V= pc.getT()* Far0VScale + Far0VBias;
+01009         }
+01010 
+01011         // compute Dynamic lightmap Uv.
+01012         static CUV      uvDLM;
+01013         if(_DLMContext)         //  (NB: Suppose BTB kill this test).
+01014         {
+01015                 // compute UV with DLM context info.
+01016                 uvDLM.U= pc.getS()* _DLMContext->DLMUScale + _DLMContext->DLMUBias;
+01017                 uvDLM.V= pc.getT()* _DLMContext->DLMVScale + _DLMContext->DLMVBias;
+01018         }
+01019         else
+01020         {
+01021                 // just set UV so the vertex point to a black pixel (see CTextureDLM).
+01022                 uvDLM.U= 1;
+01023                 uvDLM.V= 1;
+01024         }
+01025 
+01026         // If not VertexProgram (NB: Suppose BTB kill this test).
+01027         if( !CLandscapeGlobals::VertexProgramEnabled )
+01028         {
+01029                 // Set Pos. Set it local to the current center of landscape
+01030                 *(CVector*)CurVBPtr= pVert->Src->Pos - CLandscapeGlobals::PZBModelPosition;
+01031                 // Set Uvs.
+01032                 *(CUV*)(CurVBPtr + CLandscapeGlobals::CurrentFar0VBInfo.TexCoordOff0)= uv;
+01033                 *(CUV*)(CurVBPtr + CLandscapeGlobals::CurrentFar0VBInfo.TexCoordOff1)= uvDLM;
+01034         }
+01035         else
+01036         {
+01037                 // Else must setup Vertex program inputs
+01038                 // v[0]== StartPos.
+01039                 *(CVector*)CurVBPtr= pVert->Src->StartPos;
+01040                 // v[8]== Tex0
+01041                 *(CUV*)(CurVBPtr + CLandscapeGlobals::CurrentFar0VBInfo.TexCoordOff0)= uv;
+01042                 // v[9]== Tex1
+01043                 *(CUV*)(CurVBPtr + CLandscapeGlobals::CurrentFar0VBInfo.TexCoordOff1)= uvDLM;
+01044 
+01045                 // v[10]== GeomInfo.
+01046                 static CUV      geomInfo;
+01047                 geomInfo.U= pVert->Src->MaxFaceSize * CLandscapeGlobals::OORefineThreshold;
+01048                 geomInfo.V= pVert->Src->MaxNearLimit;
+01049                 *(CUV*)(CurVBPtr + CLandscapeGlobals::CurrentFar0VBInfo.GeomInfoOff)= geomInfo;
+01050 
+01051                 // v[11]== EndPos - StartPos
+01052                 *(CVector*)(CurVBPtr + CLandscapeGlobals::CurrentFar0VBInfo.DeltaPosOff)=
+01053                         pVert->Src->EndPos - pVert->Src->StartPos;
+01054         }
+01055 }
+01056 // ***************************************************************************
+01057 // NB: need to be inlined only for fillFar1VB() in this file.
+01058 inline void             CPatch::fillFar1VertexVB(CTessFarVertex *pVert)
+01059 {
+01060         // The Buffers must have been locked
+01061         nlassert(CLandscapeGlobals::CurrentFar1VBAllocator);
+01062         nlassert(CLandscapeGlobals::CurrentFar1VBAllocator->bufferLocked());
+01063         // VBInfo must be OK.
+01064         nlassert(!CLandscapeGlobals::CurrentFar1VBAllocator->reallocationOccurs());
+01065 
+01066         static  uint8   *CurVBPtr;
+01067         // Compute/build the new vertex.
+01068         CurVBPtr= (uint8*)CLandscapeGlobals::CurrentFar1VBInfo.VertexCoordPointer;
+01069         CurVBPtr+= pVert->Index1 * CLandscapeGlobals::CurrentFar1VBInfo.VertexSize;
+01070 
+01071         // NB: the filling order of data is important, for AGP write combiners.
+01072 
+01073         // compute Uvs.
+01074         static CUV      uv;
+01075         CParamCoord     pc= pVert->PCoord;
+01076         if (Flags&NL_PATCH_FAR1_ROTATED)
+01077         {
+01078                 uv.U= pc.getT()* Far1UScale + Far1UBias;
+01079                 uv.V= (1.f-pc.getS())* Far1VScale + Far1VBias;
+01080         }
+01081         else
+01082         {
+01083                 uv.U= pc.getS()* Far1UScale + Far1UBias;
+01084                 uv.V= pc.getT()* Far1VScale + Far1VBias;
+01085         }
+01086 
+01087         // compute Dynamic lightmap Uv.
+01088         static CUV      uvDLM;
+01089         if(_DLMContext)         //  (NB: Suppose BTB kill this test).
+01090         {
+01091                 // compute UV with DLM context info.
+01092                 uvDLM.U= pc.getS()* _DLMContext->DLMUScale + _DLMContext->DLMUBias;
+01093                 uvDLM.V= pc.getT()* _DLMContext->DLMVScale + _DLMContext->DLMVBias;
+01094         }
+01095         else
+01096         {
+01097                 // just set UV so the vertex point to a black pixel (see CTextureDLM).
+01098                 uvDLM.U= 1;
+01099                 uvDLM.V= 1;
+01100         }
+01101 
+01102         // If not VertexProgram (NB: Suppose BTB kill this test).
+01103         if( !CLandscapeGlobals::VertexProgramEnabled )
+01104         {
+01105                 // Set Pos. Set it local to the current center of landscape
+01106                 *(CVector*)CurVBPtr= pVert->Src->Pos - CLandscapeGlobals::PZBModelPosition;
+01107                 // Set Uvs.
+01108                 *(CUV*)(CurVBPtr + CLandscapeGlobals::CurrentFar1VBInfo.TexCoordOff0)= uv;
+01109                 *(CUV*)(CurVBPtr + CLandscapeGlobals::CurrentFar1VBInfo.TexCoordOff1)= uvDLM;
+01110                 // Set default color.
+01111                 static CRGBA    col(255,255,255,255);
+01112                 *(CRGBA*)(CurVBPtr + CLandscapeGlobals::CurrentFar1VBInfo.ColorOff)= col;
+01113         }
+01114         else
+01115         {
+01116                 // Else must setup Vertex program inputs
+01117                 // v[0]== StartPos.
+01118                 *(CVector*)CurVBPtr= pVert->Src->StartPos;
+01119                 // v[8]== Tex0
+01120                 *(CUV*)(CurVBPtr + CLandscapeGlobals::CurrentFar1VBInfo.TexCoordOff0)= uv;
+01121                 // v[9]== Tex1
+01122                 *(CUV*)(CurVBPtr + CLandscapeGlobals::CurrentFar1VBInfo.TexCoordOff1)= uvDLM;
+01123 
+01124                 // v[10]== GeomInfo.
+01125                 static CUV      geomInfo;
+01126                 geomInfo.U= pVert->Src->MaxFaceSize * CLandscapeGlobals::OORefineThreshold;
+01127                 geomInfo.V= pVert->Src->MaxNearLimit;
+01128                 *(CUV*)(CurVBPtr + CLandscapeGlobals::CurrentFar1VBInfo.GeomInfoOff)= geomInfo;
+01129 
+01130                 // v[11]== EndPos - StartPos
+01131                 *(CVector*)(CurVBPtr + CLandscapeGlobals::CurrentFar1VBInfo.DeltaPosOff)=
+01132                         pVert->Src->EndPos - pVert->Src->StartPos;
+01133 
+01134                 // v[12]== Alpha information
+01135                 // Hopefully, fillVBFar1Only() is called each Time the Far1 change, in preRender().
+01136                 // So TransitionSqrMin and OOTransitionSqrDelta in CPath are valid.
+01137                 geomInfo.U= TransitionSqrMin;
+01138                 geomInfo.V= OOTransitionSqrDelta;
+01139                 *(CUV*)(CurVBPtr + CLandscapeGlobals::CurrentFar1VBInfo.AlphaInfoOff)= geomInfo;
+01140 
+01141         }
+01142 }
+01143 // ***************************************************************************
+01144 // NB: need to be inlined only for fillTileVB() in this file.
+01145 inline void             CPatch::fillTileVertexVB(CTessNearVertex *pVert)
+01146 {
+01147         // The Buffers must have been locked
+01148         nlassert(CLandscapeGlobals::CurrentTileVBAllocator);
+01149         nlassert(CLandscapeGlobals::CurrentTileVBAllocator->bufferLocked());
+01150         // VBInfo must be OK.
+01151         nlassert(!CLandscapeGlobals::CurrentTileVBAllocator->reallocationOccurs());
+01152 
+01153         static  uint8   *CurVBPtr;
+01154         // Compute/build the new vertex.
+01155         CurVBPtr= (uint8*)CLandscapeGlobals::CurrentTileVBInfo.VertexCoordPointer;
+01156         CurVBPtr+= pVert->Index * CLandscapeGlobals::CurrentTileVBInfo.VertexSize;
+01157 
+01158 
+01159         // NB: the filling order of data is important, for AGP write combiners.
+01160 
+01161         // If not VertexProgram (NB: Suppose BTB kill this test).
+01162         if( !CLandscapeGlobals::VertexProgramEnabled )
+01163         {
+01164                 // Set Pos. Set it local to the current center of landscape
+01165                 *(CVector*)CurVBPtr= pVert->Src->Pos - CLandscapeGlobals::PZBModelPosition;
+01166                 // Set Uvs.
+01167                 *(CUV*)(CurVBPtr + CLandscapeGlobals::CurrentTileVBInfo.TexCoordOff0)= pVert->PUv0;
+01168                 *(CUV*)(CurVBPtr + CLandscapeGlobals::CurrentTileVBInfo.TexCoordOff1)= pVert->PUv1;
+01169                 *(CUV*)(CurVBPtr + CLandscapeGlobals::CurrentTileVBInfo.TexCoordOff2)= pVert->PUv2;
+01170         }
+01171         else
+01172         {
+01173                 // Else must setup Vertex program inputs
+01174                 // v[0]== StartPos.
+01175                 *(CVector*)CurVBPtr= pVert->Src->StartPos;
+01176                 // v[8]== Tex0
+01177                 *(CUV*)(CurVBPtr + CLandscapeGlobals::CurrentTileVBInfo.TexCoordOff0)= pVert->PUv0;
+01178                 // v[9]== Tex1
+01179                 *(CUV*)(CurVBPtr + CLandscapeGlobals::CurrentTileVBInfo.TexCoordOff1)= pVert->PUv1;
+01180                 // v[13]== Tex2
+01181                 *(CUV*)(CurVBPtr + CLandscapeGlobals::CurrentTileVBInfo.TexCoordOff2)= pVert->PUv2;
+01182 
+01183                 // v[10]== GeomInfo.
+01184                 static CUV      geomInfo;
+01185                 geomInfo.U= pVert->Src->MaxFaceSize * CLandscapeGlobals::OORefineThreshold;
+01186                 geomInfo.V= pVert->Src->MaxNearLimit;
+01187                 *(CUV*)(CurVBPtr + CLandscapeGlobals::CurrentTileVBInfo.GeomInfoOff)= geomInfo;
+01188 
+01189                 // v[11]== EndPos - StartPos
+01190                 *(CVector*)(CurVBPtr + CLandscapeGlobals::CurrentTileVBInfo.DeltaPosOff)=
+01191                         pVert->Src->EndPos - pVert->Src->StartPos;
+01192         }
+01193 }
+01194 
+01195 
+01196 // ***************************************************************************
+01197 void            CPatch::fillFar0VertexListVB(CTessList<CTessFarVertex>  &vertList)
+01198 {
+01199         // Traverse the vertList.
+01200         CTessFarVertex  *pVert;
+01201         for(pVert= vertList.begin(); pVert; pVert= (CTessFarVertex*)pVert->Next)
+01202         {
+01203                 fillFar0VertexVB(pVert);
+01204         }
+01205 }
+01206 
+01207 
+01208 // ***************************************************************************
+01209 void            CPatch::fillFar1VertexListVB(CTessList<CTessFarVertex>  &vertList)
+01210 {
+01211         // Traverse the vertList.
+01212         CTessFarVertex  *pVert;
+01213         for(pVert= vertList.begin(); pVert; pVert= (CTessFarVertex*)pVert->Next)
+01214         {
+01215                 fillFar1VertexVB(pVert);
+01216         }
+01217 }
+01218 
+01219 
+01220 // ***************************************************************************
+01221 void            CPatch::fillTileVertexListVB(CTessList<CTessNearVertex>  &vertList)
+01222 {
+01223         // Traverse the vertList.
+01224         CTessNearVertex *pVert;
+01225         for(pVert= vertList.begin(); pVert; pVert= (CTessNearVertex*)pVert->Next)
+01226         {
+01227                 fillTileVertexVB(pVert);
+01228         }
+01229 }
+01230 
+01231 
+01232 
+01233 // ***************************************************************************
+01234 void                    CPatch::fillVB()
+01235 {
+01236         // Fill Far0.
+01237         //=======
+01238         // fill only if no reallcoation occurs
+01239         if(Far0>0 && !CLandscapeGlobals::CurrentFar0VBAllocator->reallocationOccurs() )
+01240         {
+01241                 // Fill Far0 VB.
+01242                 fillFar0VertexListVB(MasterBlock.FarVertexList);
+01243                 for(sint i=0; i<(sint)TessBlocks.size(); i++)
+01244                 {
+01245                         CTessBlock      &tblock= TessBlocks[i];
+01246                         // fill only if tblock visible.
+01247                         if( tblock.visibleFar0() )
+01248                                 fillFar0VertexListVB(tblock.FarVertexList);
+01249                 }
+01250         }
+01251         else if(Far0==0 && !CLandscapeGlobals::CurrentTileVBAllocator->reallocationOccurs() )
+01252         {
+01253                 // Fill Tile VB.
+01254                 // No Tiles in MasterBlock!!
+01255                 // Traverse the TessBlocks to add vertices.
+01256                 for(sint i=0; i<(sint)TessBlocks.size(); i++)
+01257                 {
+01258                         CTessBlock      &tblock= TessBlocks[i];
+01259                         // fill only if tblock visible.
+01260                         if( tblock.visibleTile() )
+01261                                 fillTileVertexListVB(tblock.NearVertexList);
+01262                 }
+01263         }
+01264 
+01265         // Fill Far1.
+01266         //=======
+01267         if(Far1>0 && !CLandscapeGlobals::CurrentFar1VBAllocator->reallocationOccurs() )
+01268         {
+01269                 // Fill VB.
+01270                 fillFar1VertexListVB(MasterBlock.FarVertexList);
+01271                 for(sint i=0; i<(sint)TessBlocks.size(); i++)
+01272                 {
+01273                         CTessBlock      &tblock= TessBlocks[i];
+01274                         // fill only if tblock visible.
+01275                         if( tblock.visibleFar1() )
+01276                                 fillFar1VertexListVB(tblock.FarVertexList);
+01277                 }
+01278         }
+01279 
+01280 }
+01281 
+01282 
+01283 // ***************************************************************************
+01284 void            CPatch::fillVBIfVisible()
+01285 {
+01286         if(RenderClipped==false)
+01287                 fillVB();
+01288 }
+01289 
+01290 
+01291 // ***************************************************************************
+01292 void            CPatch::fillVBFar0Only()
+01293 {
+01294         if(Far0>0 && !CLandscapeGlobals::CurrentFar0VBAllocator->reallocationOccurs() )
+01295         {
+01296                 // Fill Far0 VB.
+01297                 fillFar0VertexListVB(MasterBlock.FarVertexList);
+01298                 for(sint i=0; i<(sint)TessBlocks.size(); i++)
+01299                 {
+01300                         CTessBlock      &tblock= TessBlocks[i];
+01301                         // fill only if tblock visible.
+01302                         if( tblock.visibleFar0() )
+01303                                 fillFar0VertexListVB(tblock.FarVertexList);
+01304                 }
+01305         }
+01306 }
+01307 
+01308 
+01309 // ***************************************************************************
+01310 void            CPatch::fillVBFar1Only()
+01311 {
+01312         if(Far1>0 && !CLandscapeGlobals::CurrentFar1VBAllocator->reallocationOccurs() )
+01313         {
+01314                 // Fill VB.
+01315                 fillFar1VertexListVB(MasterBlock.FarVertexList);
+01316                 for(sint i=0; i<(sint)TessBlocks.size(); i++)
+01317                 {
+01318                         CTessBlock      &tblock= TessBlocks[i];
+01319                         // fill only if tblock visible.
+01320                         if( tblock.visibleFar1() )
+01321                                 fillFar1VertexListVB(tblock.FarVertexList);
+01322                 }
+01323         }
+01324 }
+01325 
+01326 // ***************************************************************************
+01327 // ***************************************************************************
+01328 // VB Software Geomorph / Alpha.
+01329 // ***************************************************************************
+01330 // ***************************************************************************
+01331 
+01332 
+01333 // ***************************************************************************
+01334 void            CPatch::computeGeomorphVertexList(CTessList<CTessFarVertex>  &vertList)
+01335 {
+01336         // Traverse the vertList.
+01337         CTessFarVertex  *pVert;
+01338         for(pVert= vertList.begin(); pVert; pVert= (CTessFarVertex*)pVert->Next)
+01339         {
+01340                 // compute geomorph.
+01341                 pVert->Src->computeGeomPos();
+01342         }
+01343 }
+01344 
+01345 
+01346 // ***************************************************************************
+01347 void            CPatch::computeGeomorphFar0VertexListVB(CTessList<CTessFarVertex>  &vertList)
+01348 {
+01349         // Traverse the vertList.
+01350         CTessFarVertex  *pVert;
+01351         for(pVert= vertList.begin(); pVert; pVert= (CTessFarVertex*)pVert->Next)
+01352         {
+01353                 static  uint8   *CurVBPtr;
+01354                 // Compute/build the new vertex.
+01355                 CurVBPtr= (uint8*)CLandscapeGlobals::CurrentFar0VBInfo.VertexCoordPointer;
+01356                 CurVBPtr+= pVert->Index0 * CLandscapeGlobals::CurrentFar0VBInfo.VertexSize;
+01357 
+01358                 // Set Geomorphed Position. Set it local to the current center of landscape
+01359                 *(CVector*)CurVBPtr= pVert->Src->Pos - CLandscapeGlobals::PZBModelPosition;
+01360         }
+01361 }
+01362 
+01363 
+01364 // ***************************************************************************
+01365 void            CPatch::computeGeomorphAlphaFar1VertexListVB(CTessList<CTessFarVertex>  &vertList)
+01366 {
+01367         // Traverse the vertList.
+01368         CTessFarVertex  *pVert;
+01369         for(pVert= vertList.begin(); pVert; pVert= (CTessFarVertex*)pVert->Next)
+01370         {
+01371                 static  uint8   *CurVBPtr;
+01372                 // Compute/build the new vertex.
+01373                 CurVBPtr= (uint8*)CLandscapeGlobals::CurrentFar1VBInfo.VertexCoordPointer;
+01374                 CurVBPtr+= pVert->Index1 * CLandscapeGlobals::CurrentFar1VBInfo.VertexSize;
+01375 
+01376                 // NB: the filling order of data is important, for AGP write combiners.
+01377 
+01378                 // Set Geomorphed Position. Set it local to the current center of landscape
+01379                 *(CVector*)CurVBPtr= pVert->Src->Pos - CLandscapeGlobals::PZBModelPosition;
+01380 
+01381                 // Set Alpha color.
+01382                 static CRGBA    col(255,255,255,255);
+01383                 // For Far1, use alpha fro transition.
+01384                 // Prefer Use Pos, because of caching. So little difference between Soft and VertexProgram mode.
+01385                 float   f= (pVert->Src->Pos - CLandscapeGlobals::RefineCenter).sqrnorm();
+01386                 f= (f-TransitionSqrMin) * OOTransitionSqrDelta;
+01387                 clamp(f,0,1);
+01388                 col.A= (uint8)(f*255);
+01389                 *(CRGBA*)(CurVBPtr + CLandscapeGlobals::CurrentFar1VBInfo.ColorOff)= col;
+01390         }
+01391 }
+01392 
+01393 
+01394 // ***************************************************************************
+01395 void            CPatch::computeGeomorphTileVertexListVB(CTessList<CTessNearVertex>  &vertList)
+01396 {
+01397         // Traverse the vertList.
+01398         CTessNearVertex *pVert;
+01399         for(pVert= vertList.begin(); pVert; pVert= (CTessNearVertex*)pVert->Next)
+01400         {
+01401                 static  uint8   *CurVBPtr;
+01402                 // Compute/build the new vertex.
+01403                 CurVBPtr= (uint8*)CLandscapeGlobals::CurrentTileVBInfo.VertexCoordPointer;
+01404                 CurVBPtr+= pVert->Index * CLandscapeGlobals::CurrentTileVBInfo.VertexSize;
+01405 
+01406                 // Set Geomorphed Position. Set it local to the current center of landscape
+01407                 *(CVector*)CurVBPtr= pVert->Src->Pos - CLandscapeGlobals::PZBModelPosition;
+01408         }
+01409 }
+01410 
+01411 
+01412 
+01413 // ***************************************************************************
+01414 void            CPatch::computeSoftwareGeomorphAndAlpha()
+01415 {
+01416         if(RenderClipped)
+01417                 return;
+01418 
+01419         // Compute Geomorph.
+01420         //=======
+01421         // Need only to fill CTessVertex, so do it only for FarVertices
+01422         // Hence Geomorph is done twice on edges of patches!!.
+01423         // If not too near for precise, fast compute of geomorph.
+01424         if( TessBlocks.size()==0 )
+01425         {
+01426                 // Just update all vertices of master block.
+01427                 computeGeomorphVertexList(MasterBlock.FarVertexList);
+01428         }
+01429         else
+01430         {
+01431                 // update all vertices of master block.
+01432                 computeGeomorphVertexList(MasterBlock.FarVertexList);
+01433                 // update vertices of others block.
+01434                 for(sint i=0; i<(sint)TessBlocks.size(); i++)
+01435                 {
+01436                         CTessBlock      &tblock= TessBlocks[i];
+01437                         // Precise Clip.
+01438                         if(!tblock.getClipped())
+01439                         {
+01440                                 // compute the geomorph of the vertices in the tessblock.
+01441                                 computeGeomorphVertexList(tblock.FarVertexList);
+01442                         }
+01443                 }
+01444         }
+01445 
+01446 
+01447         // Fill Far0.
+01448         //=======
+01449         if(Far0>0)
+01450         {
+01451                 // Fill Far0 VB.
+01452                 computeGeomorphFar0VertexListVB(MasterBlock.FarVertexList);
+01453                 for(sint i=0; i<(sint)TessBlocks.size(); i++)
+01454                 {
+01455                         CTessBlock      &tblock= TessBlocks[i];
+01456                         // Precise Clip.
+01457                         if( tblock.visibleFar0() )
+01458                                 computeGeomorphFar0VertexListVB(tblock.FarVertexList);
+01459                 }
+01460         }
+01461         else if(Far0==0)
+01462         {
+01463                 // Fill Tile VB.
+01464                 // No Tiles in MasterBlock!!
+01465                 // Traverse the TessBlocks to compute vertices.
+01466                 for(sint i=0; i<(sint)TessBlocks.size(); i++)
+01467                 {
+01468                         CTessBlock      &tblock= TessBlocks[i];
+01469                         // Precise Clip.
+01470                         if( tblock.visibleTile() )
+01471                                 computeGeomorphTileVertexListVB(tblock.NearVertexList);
+01472                 }
+01473         }
+01474 
+01475         // Fill Far1.
+01476         //=======
+01477         if(Far1>0)
+01478         {
+01479                 // Fill VB.
+01480                 computeGeomorphAlphaFar1VertexListVB(MasterBlock.FarVertexList);
+01481                 for(sint i=0; i<(sint)TessBlocks.size(); i++)
+01482                 {
+01483                         CTessBlock      &tblock= TessBlocks[i];
+01484                         // Precise Clip.
+01485                         if( tblock.visibleFar1() )
+01486                                 computeGeomorphAlphaFar1VertexListVB(tblock.FarVertexList);
+01487                 }
+01488         }
+01489 }
+01490 
+01491 
+01492 // ***************************************************************************
+01493 // ***************************************************************************
+01494 // VB clip Allocate/Filling.
+01495 // ***************************************************************************
+01496 // ***************************************************************************
+01497                 
+01498 
+01499 // ***************************************************************************
+01500 void            CPatch::updateClipPatchVB()
+01501 {
+01502         // If there is a change in the clip state of this patch.
+01503         if( OldRenderClipped != RenderClipped )
+01504         {
+01505                 // bkup this state for next time.
+01506                 OldRenderClipped = RenderClipped;
+01507 
+01508                 // If now the patch is invisible
+01509                 if(RenderClipped)
+01510                 {
+01511                         // Then delete vertices.
+01512                         deleteVBAndFaceVector();
+01513 
+01514                         // Now, all vertices in VB are deleted.
+01515                         // Force clip state of all TessBlocks, so no allocation will be done on Vertices in VB.
+01516                         if(!TessBlocks.empty())
+01517                         {
+01518                                 for(uint i=0; i<TessBlocks.size();i++)
+01519                                 {
+01520                                         CTessBlock      &tblock= TessBlocks[i];
+01521                                         tblock.forceClip();
+01522                                 }
+01523                         }
+01524                 }
+01525                 else
+01526                 {
+01527                         // else allocate / fill them.
+01528                         allocateVBAndFaceVector();
+01529                         // NB: fillVB() test if any reallocation occurs.
+01530                         fillVB();
+01531                 }
+01532         }
+01533 }
+01534 
+01535 
+01536 // ***************************************************************************
+01537 // ***************************************************************************
+01538 // VB refine Allocate/Filling.
+01539 // ***************************************************************************
+01540 // ***************************************************************************
+01541 
+01542 
+01543 
+01544 // ***************************************************************************
+01545 void            CPatch::checkCreateVertexVBFar(CTessFarVertex *pVert)
+01546 {
+01547         nlassert(pVert);
+01548         // If visible, and Far0 in !Tile Mode, allocate.
+01549         // NB: must test Far0>0 because vertices are reallocated in preRender() if a change of Far occurs.
+01550         if(!RenderClipped && Far0>0 && pVert->OwnerBlock->visibleFar0() )
+01551         {
+01552                 pVert->Index0= CLandscapeGlobals::CurrentFar0VBAllocator->allocateVertex();
+01553         }
+01554 
+01555         // Idem for Far1
+01556         if(!RenderClipped && Far1>0 && pVert->OwnerBlock->visibleFar1())
+01557         {
+01558                 pVert->Index1= CLandscapeGlobals::CurrentFar1VBAllocator->allocateVertex();
+01559         }
+01560 
+01561 }
+01562 
+01563 
+01564 // ***************************************************************************
+01565 void            CPatch::checkFillVertexVBFar(CTessFarVertex *pVert)
+01566 {
+01567         nlassert(pVert);
+01568         // If visible, and Far0 in !Tile Mode, try to fill.
+01569         // NB: must test Far0>0 because vertices are reallocated in preRender() if a change of Far occurs.
+01570         if(!RenderClipped && Far0>0 && pVert->OwnerBlock->visibleFar0())
+01571         {
+01572                 if( !CLandscapeGlobals::CurrentFar0VBAllocator->reallocationOccurs() )
+01573                         fillFar0VertexVB(pVert);
+01574         }
+01575 
+01576         // Idem for Far1
+01577         if(!RenderClipped && Far1>0 && pVert->OwnerBlock->visibleFar1())
+01578         {
+01579                 if( !CLandscapeGlobals::CurrentFar1VBAllocator->reallocationOccurs() )
+01580                         fillFar1VertexVB(pVert);
+01581         }
+01582 }
+01583 
+01584 
+01585 // ***************************************************************************
+01586 void            CPatch::checkCreateVertexVBNear(CTessNearVertex *pVert)
+01587 {
+01588         nlassert(pVert);
+01589         // If visible, and Far0 in Tile Mode, allocate.
+01590         // NB: must test Far0==0 because vertices are reallocated in preRender() if a change of Far occurs.
+01591         if(!RenderClipped && Far0==0 && pVert->OwnerBlock->visibleTile())
+01592         {
+01593                 pVert->Index= CLandscapeGlobals::CurrentTileVBAllocator->allocateVertex();
+01594         }
+01595 }
+01596 
+01597 
+01598 // ***************************************************************************
+01599 void            CPatch::checkFillVertexVBNear(CTessNearVertex   *pVert)
+01600 {
+01601         nlassert(pVert);
+01602         // If visible, and Far0 in Tile Mode, try to fill.
+01603         // NB: must test Far0==0 because vertices are reallocated in preRender() if a change of Far occurs.
+01604         if(!RenderClipped&& Far0==0 && pVert->OwnerBlock->visibleTile() )
+01605         {
+01606                 // try to fill.
+01607                 if( !CLandscapeGlobals::CurrentTileVBAllocator->reallocationOccurs() )
+01608                         fillTileVertexVB(pVert);
+01609         }
+01610 }
+01611 
+01612 
+01613 // ***************************************************************************
+01614 void            CPatch::checkDeleteVertexVBFar(CTessFarVertex *pVert)
+01615 {
+01616         nlassert(pVert);
+01617         // If visible, and Far0 in !Tile Mode, ok, the vertex exist in VB, so delete.
+01618         // NB: must test Far0>0 because vertices are deleted in preRender() if a change of Far occurs.
+01619         if(!RenderClipped && Far0>0 && pVert->OwnerBlock->visibleFar0() )
+01620         {
+01621                 CLandscapeGlobals::CurrentFar0VBAllocator->deleteVertex(pVert->Index0);
+01622         }
+01623 
+01624         // Idem for Far1
+01625         if(!RenderClipped && Far1>0  && pVert->OwnerBlock->visibleFar1() )
+01626         {
+01627                 CLandscapeGlobals::CurrentFar1VBAllocator->deleteVertex(pVert->Index1);
+01628         }
+01629 }
+01630 
+01631 // ***************************************************************************
+01632 void            CPatch::checkDeleteVertexVBNear(CTessNearVertex *pVert)
+01633 {
+01634         nlassert(pVert);
+01635         // If visible, and Far0 in Tile Mode, ok, the vertex exist in VB, so delete.
+01636         // NB: must test Far0==0 because vertices are deleted in preRender() if a change of Far occurs.
+01637         if(!RenderClipped && Far0==0 && pVert->OwnerBlock->visibleTile() )
+01638         {
+01639                 CLandscapeGlobals::CurrentTileVBAllocator->deleteVertex(pVert->Index);
+01640         }
+01641 }
+01642 
+01643 
+01644 // ***************************************************************************
+01645 // ***************************************************************************
+01646 // VB DLM Filling
+01647 // ***************************************************************************
+01648 // ***************************************************************************
+01649 
+01650 
+01651 // ***************************************************************************
+01652 void            CPatch::fillFar0DLMUvOnlyVertexListVB(CTessList<CTessFarVertex>  &vertList)
+01653 {
+01654         // The Buffers must have been locked
+01655         nlassert(CLandscapeGlobals::CurrentFar0VBAllocator);
+01656         nlassert(CLandscapeGlobals::CurrentFar0VBAllocator->bufferLocked());
+01657         // VBInfo must be OK.
+01658         nlassert(!CLandscapeGlobals::CurrentFar0VBAllocator->reallocationOccurs());
+01659 
+01660         static  uint8   *CurVBPtr;
+01661         static CUV              uvDLM;
+01662 
+01663         // If the DLMContext exist
+01664         if(_DLMContext)
+01665         {
+01666                 // Traverse the vertList, to compute new uvDLM
+01667                 CTessFarVertex  *pVert;
+01668                 for(pVert= vertList.begin(); pVert; pVert= (CTessFarVertex*)pVert->Next)
+01669                 {
+01670                         // Compute/build the new vertex.
+01671                         CurVBPtr= (uint8*)CLandscapeGlobals::CurrentFar0VBInfo.VertexCoordPointer;
+01672                         CurVBPtr+= pVert->Index0 * CLandscapeGlobals::CurrentFar0VBInfo.VertexSize;
+01673 
+01674                         // compute Uvs.
+01675                         CParamCoord     pc= pVert->PCoord;
+01676 
+01677                         // compute Dynamic lightmap Uv with DLM context info.
+01678                         uvDLM.U= pc.getS()* _DLMContext->DLMUScale + _DLMContext->DLMUBias;
+01679                         uvDLM.V= pc.getT()* _DLMContext->DLMVScale + _DLMContext->DLMVBias;
+01680 
+01681                         // Set Uv DLM only (NB: same code for VertexProgram or not, only TexCoordOff1 may change).
+01682                         *(CUV*)(CurVBPtr + CLandscapeGlobals::CurrentFar0VBInfo.TexCoordOff1)= uvDLM;
+01683                 }
+01684         }
+01685         // else, reset all Uvs
+01686         else
+01687         {
+01688                 // just set UV so the vertex point to a black pixel (see CTextureDLM).
+01689                 uvDLM.U= 1;
+01690                 uvDLM.V= 1;
+01691 
+01692                 // Traverse the vertList, to reset uv
+01693                 CTessFarVertex  *pVert;
+01694                 for(pVert= vertList.begin(); pVert; pVert= (CTessFarVertex*)pVert->Next)
+01695                 {
+01696                         // Compute/build the new vertex.
+01697                         CurVBPtr= (uint8*)CLandscapeGlobals::CurrentFar0VBInfo.VertexCoordPointer;
+01698                         CurVBPtr+= pVert->Index0 * CLandscapeGlobals::CurrentFar0VBInfo.VertexSize;
+01699 
+01700                         // Set Uv DLM only (NB: same code for VertexProgram or not, only TexCoordOff1 may change).
+01701                         *(CUV*)(CurVBPtr + CLandscapeGlobals::CurrentFar0VBInfo.TexCoordOff1)= uvDLM;
+01702                 }
+01703         }
+01704 }
+01705 
+01706 // ***************************************************************************
+01707 void            CPatch::fillFar1DLMUvOnlyVertexListVB(CTessList<CTessFarVertex>  &vertList)
+01708 {
+01709         // The Buffers must have been locked
+01710         nlassert(CLandscapeGlobals::CurrentFar1VBAllocator);
+01711         nlassert(CLandscapeGlobals::CurrentFar1VBAllocator->bufferLocked());
+01712         // VBInfo must be OK.
+01713         nlassert(!CLandscapeGlobals::CurrentFar1VBAllocator->reallocationOccurs());
+01714 
+01715         static  uint8   *CurVBPtr;
+01716         static CUV              uvDLM;
+01717 
+01718         // If the DLMContext exist
+01719         if(_DLMContext)
+01720         {
+01721                 // Traverse the vertList, to compute new uvDLM
+01722                 CTessFarVertex  *pVert;
+01723                 for(pVert= vertList.begin(); pVert; pVert= (CTessFarVertex*)pVert->Next)
+01724                 {
+01725                         // Compute/build the new vertex.
+01726                         CurVBPtr= (uint8*)CLandscapeGlobals::CurrentFar1VBInfo.VertexCoordPointer;
+01727                         CurVBPtr+= pVert->Index1 * CLandscapeGlobals::CurrentFar1VBInfo.VertexSize;
+01728 
+01729                         // compute Uvs.
+01730                         CParamCoord     pc= pVert->PCoord;
+01731 
+01732                         // compute Dynamic lightmap Uv with DLM context info.
+01733                         uvDLM.U= pc.getS()* _DLMContext->DLMUScale + _DLMContext->DLMUBias;
+01734                         uvDLM.V= pc.getT()* _DLMContext->DLMVScale + _DLMContext->DLMVBias;
+01735 
+01736                         // Set Uv DLM only (NB: same code for VertexProgram or not, only TexCoordOff1 may change).
+01737                         *(CUV*)(CurVBPtr + CLandscapeGlobals::CurrentFar1VBInfo.TexCoordOff1)= uvDLM;
+01738                 }
+01739         }
+01740         // else, reset all Uvs
+01741         else
+01742         {
+01743                 // just set UV so the vertex point to a black pixel (see CTextureDLM).
+01744                 uvDLM.U= 1;
+01745                 uvDLM.V= 1;
+01746 
+01747                 // Traverse the vertList, to reset uv
+01748                 CTessFarVertex  *pVert;
+01749                 for(pVert= vertList.begin(); pVert; pVert= (CTessFarVertex*)pVert->Next)
+01750                 {
+01751                         // Compute/build the new vertex.
+01752                         CurVBPtr= (uint8*)CLandscapeGlobals::CurrentFar1VBInfo.VertexCoordPointer;
+01753                         CurVBPtr+= pVert->Index1 * CLandscapeGlobals::CurrentFar1VBInfo.VertexSize;
+01754 
+01755                         // Set Uv DLM only (NB: same code for VertexProgram or not, only TexCoordOff1 may change).
+01756                         *(CUV*)(CurVBPtr + CLandscapeGlobals::CurrentFar1VBInfo.TexCoordOff1)= uvDLM;
+01757                 }
+01758         }
+01759 }
+01760 
+01761 
+01762 // ***************************************************************************
+01763 void            CPatch::fillVBFarsDLMUvOnly()
+01764 {
+01765         // Do it for Far0.
+01766         if(Far0>0 && !CLandscapeGlobals::CurrentFar0VBAllocator->reallocationOccurs() )
+01767         {
+01768                 // Fill Far0 VB.
+01769                 fillFar0DLMUvOnlyVertexListVB(MasterBlock.FarVertexList);
+01770                 for(sint i=0; i<(sint)TessBlocks.size(); i++)
+01771                 {
+01772                         CTessBlock      &tblock= TessBlocks[i];
+01773                         // fill only if tblock visible.
+01774                         if( tblock.visibleFar0() )
+01775                                 fillFar0DLMUvOnlyVertexListVB(tblock.FarVertexList);
+01776                 }
+01777         }
+01778 
+01779         // Do it for Far1.
+01780         if(Far1>0 && !CLandscapeGlobals::CurrentFar1VBAllocator->reallocationOccurs() )
+01781         {
+01782                 // Fill VB.
+01783                 fillFar1DLMUvOnlyVertexListVB(MasterBlock.FarVertexList);
+01784                 for(sint i=0; i<(sint)TessBlocks.size(); i++)
+01785                 {
+01786                         CTessBlock      &tblock= TessBlocks[i];
+01787                         // fill only if tblock visible.
+01788                         if( tblock.visibleFar1() )
+01789                                 fillFar1DLMUvOnlyVertexListVB(tblock.FarVertexList);
+01790                 }
+01791         }
+01792 }
+01793 
+01794 
+01795 
+01796 } // NL3D
+
+ + +
                                                                                                                                                                    +
+ + -- cgit v1.2.1