patch_render.cpp

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

Generated on Thu Jan 7 08:26:28 2010 for NeL by  doxygen 1.6.1