00001
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
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
00047
00048
00049
00050
00051
00052 void CPatch::computeNewFar(const NLMISC::CBSphere &patchSphere, sint &newFar0, sint &newFar1)
00053 {
00054
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
00067 newFar1=0;
00068 if(newFar0<3 && rr>-(CLandscapeGlobals::FarTransition+2*patchSphere.Radius))
00069 {
00070 newFar1= newFar0+1;
00071 }
00072
00073
00074
00075
00076 if(newFar0!=Far0 || newFar1!=Far1)
00077 {
00078
00079 CPatchRdrPass *oldPass0=_PatchRdrPassFar0;
00080 CPatchRdrPass *oldPass1=_PatchRdrPassFar1;
00081
00082
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
00096 if ((newFar1==Far0)&&(Far0>0))
00097 _PatchRdrPassFar0=NULL;
00098
00099
00100 if ((newFar0==Far1)&&(Far1>0))
00101 _PatchRdrPassFar1=NULL;
00102
00103
00104 if (newFar0!=Far0)
00105 {
00106
00107 if(newFar0>0)
00108 {
00109
00110 if (_PatchRdrPassFar0)
00111 Zone->Landscape->freeFarRenderPass (this, _PatchRdrPassFar0, Far0);
00112
00113
00114 if (newFar0==Far1)
00115 {
00116
00117 _PatchRdrPassFar0=oldPass1;
00118
00119
00120 Far0UScale=Far1UScale;
00121 Far0VScale=Far1VScale;
00122 Far0UBias=Far1UBias;
00123 Far0VBias=Far1VBias;
00124
00125
00126 Flags&=~NL_PATCH_FAR0_ROTATED;
00127 if (Flags&NL_PATCH_FAR1_ROTATED)
00128 Flags|=NL_PATCH_FAR0_ROTATED;
00129 }
00130 else
00131 {
00132
00133 bool bRot;
00134 _PatchRdrPassFar0=Zone->Landscape->getFarRenderPass(this, newFar0, Far0UScale, Far0VScale, Far0UBias, Far0VBias, bRot);
00135
00136
00137 if (bRot)
00138 Flags|=NL_PATCH_FAR0_ROTATED;
00139 else
00140 Flags&=~NL_PATCH_FAR0_ROTATED;
00141 }
00142 }
00143 else
00144 {
00145 if (_PatchRdrPassFar0)
00146 {
00147 Zone->Landscape->freeFarRenderPass (this, _PatchRdrPassFar0, Far0);
00148 _PatchRdrPassFar0=NULL;
00149 }
00150 }
00151 }
00152
00153
00154 if (newFar1!=Far1)
00155 {
00156
00157 if(newFar1>0)
00158 {
00159
00160 if (_PatchRdrPassFar1)
00161 Zone->Landscape->freeFarRenderPass (this, _PatchRdrPassFar1, Far1);
00162
00163
00164 if (newFar1==Far0)
00165 {
00166
00167 _PatchRdrPassFar1= oldPass0;
00168 nlassert (_PatchRdrPassFar1);
00169
00170
00171 Far1UScale=oldFar0UScale;
00172 Far1VScale=oldFar0VScale;
00173 Far1UBias=oldFar0UBias;
00174 Far1VBias=oldFar0VBias;
00175
00176
00177 Flags&=~NL_PATCH_FAR1_ROTATED;
00178 if (oldFlags&NL_PATCH_FAR0_ROTATED)
00179 Flags|=NL_PATCH_FAR1_ROTATED;
00180 }
00181 else
00182 {
00183
00184 bool bRot;
00185 _PatchRdrPassFar1=Zone->Landscape->getFarRenderPass(this, newFar1, Far1UScale, Far1VScale, Far1UBias, Far1VBias, bRot);
00186 nlassert (_PatchRdrPassFar1);
00187
00188
00189 if (bRot)
00190 Flags|=NL_PATCH_FAR1_ROTATED;
00191 else
00192 Flags&=~NL_PATCH_FAR1_ROTATED;
00193 }
00194
00195
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
00208 {
00209 if (_PatchRdrPassFar1)
00210 {
00211 Zone->Landscape->freeFarRenderPass (this, _PatchRdrPassFar1, Far1);
00212 _PatchRdrPassFar1=NULL;
00213 }
00214 }
00215 }
00216
00217 }
00218
00219
00220 }
00221
00222
00223
00224 void CPatch::updateTextureFarOnly(const NLMISC::CBSphere &patchSphere)
00225 {
00226 sint newFar0,newFar1;
00227
00228 computeNewFar(patchSphere, newFar0, newFar1);
00229
00230
00231
00232
00233 Far0= newFar0;
00234 Far1= newFar1;
00235 }
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247 void CPatch::preRender(const NLMISC::CBSphere &patchSphere)
00248 {
00249
00250
00251 sint newFar0,newFar1;
00252
00253 computeNewFar(patchSphere, newFar0, newFar1);
00254
00255
00256
00257
00258 sint oldFar0= Far0, oldFar1= Far1;
00259
00260
00261 bool changeTileMode;
00262
00263 changeTileMode= (newFar0!=oldFar0) && (newFar0==0 || oldFar0==0);
00264
00265 changeTileMode= changeTileMode || oldFar0==-1 || oldFar1==-1;
00266
00267
00268
00269
00270 if(changeTileMode)
00271 {
00272
00273
00274 deleteVBAndFaceVector();
00275 }
00276 else
00277 {
00278
00279
00280
00281 if(newFar1!=oldFar1)
00282 {
00283
00284 deleteVBAndFaceVectorFar1Only();
00285 }
00286 }
00287
00288
00289
00290
00291 Far0= newFar0;
00292 Far1= newFar1;
00293
00294
00295
00296
00297 if(changeTileMode)
00298 {
00299
00300 allocateVBAndFaceVector();
00301
00302 fillVB();
00303 }
00304 else
00305 {
00306
00307
00308 if(newFar0!=oldFar0)
00309 {
00310
00311
00312
00313 fillVBFar0Only();
00314 }
00315
00316
00317 if(newFar1!=oldFar1)
00318 {
00319 allocateVBAndFaceVectorFar1Only();
00320
00321 fillVBFar1Only();
00322 }
00323 }
00324
00325
00326
00327
00328
00329 if(Far0>0)
00330 {
00331 _PatchRdrPassFar0->appendRdrPatchFar0(this);
00332 }
00333
00334 if(Far1>0)
00335 {
00336 _PatchRdrPassFar1->appendRdrPatchFar1(this);
00337 }
00338
00339
00340
00341
00342
00343 bool doClipFar= Far0==0 && Far1==1;
00344
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
00352 bool oldVisibleFar0= tblock.visibleFar0();
00353 bool oldVisibleTile= tblock.visibleTile();
00354 bool oldVisibleFar1= tblock.visibleFar1();
00355
00356
00357 if(tblock.FaceTileMaterialRefCount==0)
00358 {
00359
00360 tblock.forceClip();
00361 }
00362 else
00363 {
00364
00365 tblock.resetClip();
00366 tblock.clip();
00367
00368 if(doClipFar)
00369 tblock.clipFar(CLandscapeGlobals::RefineCenter, CLandscapeGlobals::TileDistNear, CLandscapeGlobals::FarTransition);
00370
00371
00372 if(Far0==0 && tblock.visibleTile() )
00373 {
00374
00375 for(uint j=0;j<NL3D_TESSBLOCK_TILESIZE; j++)
00376 {
00377
00378 if(tblock.RdrTileRoot[j])
00379
00380 tblock.RdrTileRoot[j]->appendTileToEachRenderPass(NumRenderableFaces);
00381 }
00382 }
00383 }
00384
00385
00386 if( Far0> 0 && oldVisibleFar0 != tblock.visibleFar0() )
00387 {
00388 if( tblock.visibleFar0() )
00389 {
00390
00391 updateFar0VBAlloc(tblock.FarVertexList, true);
00392
00393 if(!CLandscapeGlobals::CurrentFar0VBAllocator->reallocationOccurs())
00394 fillFar0VertexListVB(tblock.FarVertexList);
00395
00396 tblock.refillFaceVectorFar0();
00397 }
00398 else
00399 {
00400
00401 updateFar0VBAlloc(tblock.FarVertexList, false);
00402 }
00403 }
00404 if( Far0==0 && oldVisibleTile != tblock.visibleTile() )
00405 {
00406 if( tblock.visibleTile() )
00407 {
00408
00409 updateTileVBAlloc(tblock.NearVertexList, true);
00410
00411 if(!CLandscapeGlobals::CurrentTileVBAllocator->reallocationOccurs())
00412 fillTileVertexListVB(tblock.NearVertexList);
00413
00414 tblock.refillFaceVectorTile();
00415 }
00416 else
00417 {
00418
00419 updateTileVBAlloc(tblock.NearVertexList, false);
00420 }
00421 }
00422 if( Far1> 0 && oldVisibleFar1 != tblock.visibleFar1() )
00423 {
00424 if( tblock.visibleFar1() )
00425 {
00426
00427 updateFar1VBAlloc(tblock.FarVertexList, true);
00428
00429 if(!CLandscapeGlobals::CurrentFar1VBAllocator->reallocationOccurs())
00430 fillFar1VertexListVB(tblock.FarVertexList);
00431
00432 tblock.refillFaceVectorFar1();
00433 }
00434 else
00435 {
00436
00437 updateFar1VBAlloc(tblock.FarVertexList, false);
00438 }
00439 }
00440 }
00441
00442 }
00443
00444
00445
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
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472 if(fv)
00473 {
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
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
00499
00500 mov ecx, [ebx]
00501 lea esi, [ebx+4]
00502
00503 mov eax, ecx
00504 lea ecx, [ecx + ecx*2]
00505
00506
00507 rep movsd
00508
00509 add edx, eax
00510
00511
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
00523
00524 movzx ecx, word ptr [ebx]
00525 lea esi, [ebx+2]
00526
00527 mov eax, ecx
00528 lea ecx, [ecx + ecx*2]
00529
00530 test ecx, 1
00531 jne odd_number
00532 shr ecx, 1
00533
00534 movsw
00535 dec ecx
00536 rep movsd
00537 movsw
00538 jmp even_number_done
00539 odd_number:
00540 shr ecx, 1
00541
00542 movsw
00543 rep movsd
00544 even_number_done:
00545
00546 add edx, eax
00547
00548
00549 mov NL3D_LandscapeGlobals_PassTriCurPtr, edi
00550 mov NL3D_LandscapeGlobals_PassNTri, edx
00551 }
00552 #endif
00553 #else
00554 uint nTriIndex= *fv*3;
00555
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
00576 nlassert(!isRenderClipped() && _PatchRdrPassFar0);
00577 #endif
00578
00579
00580 renderFaceVector(MasterBlock.Far0FaceVector);
00581
00582 NL3D_PROFILE_LAND_ADD_FACE_VECTOR(ProfNRdrFar0, MasterBlock.Far0FaceVector);
00583
00584
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
00591 if( tblock.visibleFar0() )
00592 {
00593 renderFaceVector(tblock.Far0FaceVector);
00594
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
00608 nlassert(!isRenderClipped() && _PatchRdrPassFar1);
00609 #endif
00610
00611
00612 renderFaceVector(MasterBlock.Far1FaceVector);
00613
00614 NL3D_PROFILE_LAND_ADD_FACE_VECTOR(ProfNRdrFar1, MasterBlock.Far1FaceVector);
00615
00616
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
00623 if( tblock.visibleFar1() )
00624 {
00625 renderFaceVector(tblock.Far1FaceVector);
00626
00627 NL3D_PROFILE_LAND_ADD_FACE_VECTOR(ProfNRdrFar1, tblock.Far1FaceVector);
00628 }
00629 }
00630 }
00631
00632
00633
00634 void CTileMaterial::renderTile(uint pass)
00635 {
00636
00637
00638 if(Pass[pass].PatchRdrPass)
00639 {
00640
00641 renderFaceVector(TileFaceVectors[pass]);
00642
00643
00644 NL3D_PROFILE_LAND_ADD_FACE_VECTOR(ProfNRdrTile[pass], TileFaceVectors[pass]);
00645 }
00646 }
00647
00648
00649 void CTileMaterial::renderTilePassRGB0()
00650 {
00651
00652
00653 nlassert(Pass[NL3D_TILE_PASS_RGB0].PatchRdrPass);
00654
00655 renderFaceVector(TileFaceVectors[NL3D_TILE_PASS_RGB0]);
00656
00657
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
00665
00666 nlassert(Pass[NL3D_TILE_PASS_LIGHTMAP].PatchRdrPass);
00667
00668 renderFaceVector(TileFaceVectors[NL3D_TILE_PASS_RGB0]);
00669
00670
00671 NL3D_PROFILE_LAND_ADD_FACE_VECTOR(ProfNRdrTile[NL3D_TILE_PASS_LIGHTMAP], TileFaceVectors[NL3D_TILE_PASS_RGB0]);
00672 }
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683 void CPatch::createFaceVectorFar1()
00684 {
00685 if(Far1>0)
00686 {
00687
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
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
00708 if(Far0>0)
00709 {
00710
00711 MasterBlock.createFaceVectorFar0(getLandscape()->_FaceVectorManager);
00712 for(uint i=0; i<TessBlocks.size(); i++)
00713 TessBlocks[i].createFaceVectorFar0(getLandscape()->_FaceVectorManager);
00714 }
00715
00716 else if(Far0==0)
00717 {
00718
00719
00720 for(uint i=0; i<TessBlocks.size(); i++)
00721 TessBlocks[i].createFaceVectorTile(getLandscape()->_FaceVectorManager);
00722 }
00723 }
00724
00725 void CPatch::deleteFaceVectorFar0OrTile()
00726 {
00727
00728 if(Far0>0)
00729 {
00730
00731 MasterBlock.deleteFaceVectorFar0(getLandscape()->_FaceVectorManager);
00732 for(uint i=0; i<TessBlocks.size(); i++)
00733 TessBlocks[i].deleteFaceVectorFar0(getLandscape()->_FaceVectorManager);
00734 }
00735
00736 else if(Far0==0)
00737 {
00738
00739
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
00750 if(!isRenderClipped())
00751 {
00752
00753
00754 if(Far0>0)
00755 {
00756
00757 block.createFaceVectorFar0(getLandscape()->_FaceVectorManager);
00758 }
00759
00760 else if(Far0==0)
00761 {
00762
00763 if(&block != &MasterBlock)
00764 block.createFaceVectorTile(getLandscape()->_FaceVectorManager);
00765 }
00766
00767
00768 if(Far1>0)
00769 {
00770
00771 block.createFaceVectorFar1(getLandscape()->_FaceVectorManager);
00772 }
00773 }
00774
00775 }
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786 void CPatch::updateFar0VBAlloc(CTessList<CTessFarVertex> &vertList, bool alloc)
00787 {
00788
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
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
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
00834
00835 if(Far0>0)
00836 {
00837
00838 updateFar0VBAlloc(MasterBlock.FarVertexList, alloc);
00839 for(sint i=0; i<(sint)TessBlocks.size(); i++)
00840 {
00841 CTessBlock &tblock= TessBlocks[i];
00842
00843 if( tblock.visibleFar0() )
00844 updateFar0VBAlloc(tblock.FarVertexList, alloc);
00845 }
00846 }
00847 else if (Far0==0)
00848 {
00849
00850
00851
00852 for(sint i=0; i<(sint)TessBlocks.size(); i++)
00853 {
00854 CTessBlock &tblock= TessBlocks[i];
00855
00856
00857 if( tblock.visibleTile() )
00858 updateTileVBAlloc(tblock.NearVertexList, alloc);
00859 }
00860 }
00861
00862
00863
00864 if(Far1>0)
00865 {
00866
00867 updateFar1VBAlloc(MasterBlock.FarVertexList, alloc);
00868 for(sint i=0; i<(sint)TessBlocks.size(); i++)
00869 {
00870 CTessBlock &tblock= TessBlocks[i];
00871
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
00901 updateFar1VBAlloc(MasterBlock.FarVertexList, false);
00902 for(sint i=0; i<(sint)TessBlocks.size(); i++)
00903 {
00904 CTessBlock &tblock= TessBlocks[i];
00905
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
00920 updateFar1VBAlloc(MasterBlock.FarVertexList, true);
00921 for(sint i=0; i<(sint)TessBlocks.size(); i++)
00922 {
00923 CTessBlock &tblock= TessBlocks[i];
00924
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
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
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
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
00968
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
00982
00983
00984
00985
00986
00987
00988 inline void CPatch::fillFar0VertexVB(CTessFarVertex *pVert)
00989 {
00990
00991 nlassert(CLandscapeGlobals::CurrentFar0VBAllocator);
00992 nlassert(CLandscapeGlobals::CurrentFar0VBAllocator->bufferLocked());
00993
00994 nlassert(!CLandscapeGlobals::CurrentFar0VBAllocator->reallocationOccurs());
00995
00996 static uint8 *CurVBPtr;
00997
00998 CurVBPtr= (uint8*)CLandscapeGlobals::CurrentFar0VBInfo.VertexCoordPointer;
00999 CurVBPtr+= pVert->Index0 * CLandscapeGlobals::CurrentFar0VBInfo.VertexSize;
01000
01001
01002
01003
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
01018 static CUV uvDLM;
01019 if(_DLMContext)
01020 {
01021
01022 uvDLM.U= pc.getS()* _DLMContext->DLMUScale + _DLMContext->DLMUBias;
01023 uvDLM.V= pc.getT()* _DLMContext->DLMVScale + _DLMContext->DLMVBias;
01024 }
01025 else
01026 {
01027
01028 uvDLM.U= 1;
01029 uvDLM.V= 1;
01030 }
01031
01032
01033 if( !CLandscapeGlobals::VertexProgramEnabled )
01034 {
01035
01036 CHECK_VBA_RANGE(CLandscapeGlobals::CurrentFar0VBInfo.Accessor, CurVBPtr, sizeof(CVector));
01037 *(CVector*)CurVBPtr= pVert->Src->Pos - CLandscapeGlobals::PZBModelPosition;
01038
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
01047
01048 CHECK_VBA_RANGE(CLandscapeGlobals::CurrentFar0VBInfo.Accessor, CurVBPtr, sizeof(CVector));
01049 *(CVector*)CurVBPtr= pVert->Src->StartPos;
01050
01051 CHECK_VBA_RANGE(CLandscapeGlobals::CurrentFar0VBInfo.Accessor, CurVBPtr + CLandscapeGlobals::CurrentFar0VBInfo.TexCoordOff0, sizeof(CUV));
01052 *(CUV*)(CurVBPtr + CLandscapeGlobals::CurrentFar0VBInfo.TexCoordOff0)= uv;
01053
01054 CHECK_VBA_RANGE(CLandscapeGlobals::CurrentFar0VBInfo.Accessor, CurVBPtr + CLandscapeGlobals::CurrentFar0VBInfo.TexCoordOff1, sizeof(CUV));
01055 *(CUV*)(CurVBPtr + CLandscapeGlobals::CurrentFar0VBInfo.TexCoordOff1)= uvDLM;
01056
01057
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
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
01072 inline void CPatch::fillFar1VertexVB(CTessFarVertex *pVert)
01073 {
01074
01075 nlassert(CLandscapeGlobals::CurrentFar1VBAllocator);
01076 nlassert(CLandscapeGlobals::CurrentFar1VBAllocator->bufferLocked());
01077
01078 nlassert(!CLandscapeGlobals::CurrentFar1VBAllocator->reallocationOccurs());
01079
01080 static uint8 *CurVBPtr;
01081
01082 CurVBPtr= (uint8*)CLandscapeGlobals::CurrentFar1VBInfo.VertexCoordPointer;
01083 CurVBPtr+= pVert->Index1 * CLandscapeGlobals::CurrentFar1VBInfo.VertexSize;
01084
01085
01086
01087
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
01102 static CUV uvDLM;
01103 if(_DLMContext)
01104 {
01105
01106 uvDLM.U= pc.getS()* _DLMContext->DLMUScale + _DLMContext->DLMUBias;
01107 uvDLM.V= pc.getT()* _DLMContext->DLMVScale + _DLMContext->DLMVBias;
01108 }
01109 else
01110 {
01111
01112 uvDLM.U= 1;
01113 uvDLM.V= 1;
01114 }
01115
01116
01117 if( !CLandscapeGlobals::VertexProgramEnabled )
01118 {
01119
01120 CHECK_VBA_RANGE(CLandscapeGlobals::CurrentFar1VBInfo.Accessor, CurVBPtr, sizeof(CVector));
01121 *(CVector*)CurVBPtr= pVert->Src->Pos - CLandscapeGlobals::PZBModelPosition;
01122
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
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
01135
01136 CHECK_VBA_RANGE(CLandscapeGlobals::CurrentFar1VBInfo.Accessor, CurVBPtr, sizeof(CVector));
01137 *(CVector*)CurVBPtr= pVert->Src->StartPos;
01138
01139 CHECK_VBA_RANGE(CLandscapeGlobals::CurrentFar1VBInfo.Accessor, CurVBPtr + CLandscapeGlobals::CurrentFar1VBInfo.TexCoordOff0, sizeof(CUV));
01140 *(CUV*)(CurVBPtr + CLandscapeGlobals::CurrentFar1VBInfo.TexCoordOff0)= uv;
01141
01142 CHECK_VBA_RANGE(CLandscapeGlobals::CurrentFar1VBInfo.Accessor, CurVBPtr + CLandscapeGlobals::CurrentFar1VBInfo.TexCoordOff1, sizeof(CUV));
01143 *(CUV*)(CurVBPtr + CLandscapeGlobals::CurrentFar1VBInfo.TexCoordOff1)= uvDLM;
01144
01145
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
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
01158
01159
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
01169 inline void CPatch::fillTileVertexVB(CTessNearVertex *pVert)
01170 {
01171
01172 nlassert(CLandscapeGlobals::CurrentTileVBAllocator);
01173 nlassert(CLandscapeGlobals::CurrentTileVBAllocator->bufferLocked());
01174
01175 nlassert(!CLandscapeGlobals::CurrentTileVBAllocator->reallocationOccurs());
01176
01177 static uint8 *CurVBPtr;
01178
01179 CurVBPtr= (uint8*)CLandscapeGlobals::CurrentTileVBInfo.VertexCoordPointer;
01180 CurVBPtr+= pVert->Index * CLandscapeGlobals::CurrentTileVBInfo.VertexSize;
01181
01182
01183
01184
01185
01186 if( !CLandscapeGlobals::VertexProgramEnabled )
01187 {
01188
01189 CHECK_VBA_RANGE(CLandscapeGlobals::CurrentTileVBInfo.Accessor, CurVBPtr, sizeof(CVector))
01190 *(CVector*)CurVBPtr= pVert->Src->Pos - CLandscapeGlobals::PZBModelPosition;
01191
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
01202
01203 CHECK_VBA_RANGE(CLandscapeGlobals::CurrentTileVBInfo.Accessor, CurVBPtr, sizeof(CVector))
01204 *(CVector*)CurVBPtr= pVert->Src->StartPos;
01205
01206 CHECK_VBA_RANGE(CLandscapeGlobals::CurrentTileVBInfo.Accessor, CurVBPtr + CLandscapeGlobals::CurrentTileVBInfo.TexCoordOff0, sizeof(CUV))
01207 *(CUV*)(CurVBPtr + CLandscapeGlobals::CurrentTileVBInfo.TexCoordOff0)= pVert->PUv0;
01208
01209 CHECK_VBA_RANGE(CLandscapeGlobals::CurrentTileVBInfo.Accessor, CurVBPtr + CLandscapeGlobals::CurrentTileVBInfo.TexCoordOff1, sizeof(CUV))
01210 *(CUV*)(CurVBPtr + CLandscapeGlobals::CurrentTileVBInfo.TexCoordOff1)= pVert->PUv1;
01211
01212 CHECK_VBA_RANGE(CLandscapeGlobals::CurrentTileVBInfo.Accessor, CurVBPtr + CLandscapeGlobals::CurrentTileVBInfo.TexCoordOff2, sizeof(CUV))
01213 *(CUV*)(CurVBPtr + CLandscapeGlobals::CurrentTileVBInfo.TexCoordOff2)= pVert->PUv2;
01214
01215
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
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
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
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
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
01271
01272
01273 if(Far0>0 && !CLandscapeGlobals::CurrentFar0VBAllocator->reallocationOccurs() )
01274 {
01275
01276 fillFar0VertexListVB(MasterBlock.FarVertexList);
01277 for(sint i=0; i<(sint)TessBlocks.size(); i++)
01278 {
01279 CTessBlock &tblock= TessBlocks[i];
01280
01281 if( tblock.visibleFar0() )
01282 fillFar0VertexListVB(tblock.FarVertexList);
01283 }
01284 }
01285 else if(Far0==0 && !CLandscapeGlobals::CurrentTileVBAllocator->reallocationOccurs() )
01286 {
01287
01288
01289
01290 for(sint i=0; i<(sint)TessBlocks.size(); i++)
01291 {
01292 CTessBlock &tblock= TessBlocks[i];
01293
01294 if( tblock.visibleTile() )
01295 fillTileVertexListVB(tblock.NearVertexList);
01296 }
01297 }
01298
01299
01300
01301 if(Far1>0 && !CLandscapeGlobals::CurrentFar1VBAllocator->reallocationOccurs() )
01302 {
01303
01304 fillFar1VertexListVB(MasterBlock.FarVertexList);
01305 for(sint i=0; i<(sint)TessBlocks.size(); i++)
01306 {
01307 CTessBlock &tblock= TessBlocks[i];
01308
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
01331 fillFar0VertexListVB(MasterBlock.FarVertexList);
01332 for(sint i=0; i<(sint)TessBlocks.size(); i++)
01333 {
01334 CTessBlock &tblock= TessBlocks[i];
01335
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
01349 fillFar1VertexListVB(MasterBlock.FarVertexList);
01350 for(sint i=0; i<(sint)TessBlocks.size(); i++)
01351 {
01352 CTessBlock &tblock= TessBlocks[i];
01353
01354 if( tblock.visibleFar1() )
01355 fillFar1VertexListVB(tblock.FarVertexList);
01356 }
01357 }
01358 }
01359
01360
01361
01362
01363
01364
01365
01366
01367
01368 void CPatch::computeGeomorphVertexList(CTessList<CTessFarVertex> &vertList)
01369 {
01370
01371 CTessFarVertex *pVert;
01372 for(pVert= vertList.begin(); pVert; pVert= (CTessFarVertex*)pVert->Next)
01373 {
01374
01375 pVert->Src->computeGeomPos();
01376 }
01377 }
01378
01379
01380
01381 void CPatch::computeGeomorphFar0VertexListVB(CTessList<CTessFarVertex> &vertList)
01382 {
01383
01384 CTessFarVertex *pVert;
01385 for(pVert= vertList.begin(); pVert; pVert= (CTessFarVertex*)pVert->Next)
01386 {
01387 static uint8 *CurVBPtr;
01388
01389 CurVBPtr= (uint8*)CLandscapeGlobals::CurrentFar0VBInfo.VertexCoordPointer;
01390 CurVBPtr+= pVert->Index0 * CLandscapeGlobals::CurrentFar0VBInfo.VertexSize;
01391
01392
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
01403 CTessFarVertex *pVert;
01404 for(pVert= vertList.begin(); pVert; pVert= (CTessFarVertex*)pVert->Next)
01405 {
01406 static uint8 *CurVBPtr;
01407
01408 CurVBPtr= (uint8*)CLandscapeGlobals::CurrentFar1VBInfo.VertexCoordPointer;
01409 CurVBPtr+= pVert->Index1 * CLandscapeGlobals::CurrentFar1VBInfo.VertexSize;
01410
01411
01412
01413
01414 CHECK_VBA_RANGE(CLandscapeGlobals::CurrentFar1VBInfo.Accessor, CurVBPtr, sizeof(CVector))
01415 *(CVector*)CurVBPtr= pVert->Src->Pos - CLandscapeGlobals::PZBModelPosition;
01416
01417
01418 static CRGBA col(255,255,255,255);
01419
01420
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
01435 CTessNearVertex *pVert;
01436 for(pVert= vertList.begin(); pVert; pVert= (CTessNearVertex*)pVert->Next)
01437 {
01438 static uint8 *CurVBPtr;
01439
01440 CurVBPtr= (uint8*)CLandscapeGlobals::CurrentTileVBInfo.VertexCoordPointer;
01441 CurVBPtr+= pVert->Index * CLandscapeGlobals::CurrentTileVBInfo.VertexSize;
01442
01443
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
01458
01459
01460
01461
01462 if( TessBlocks.size()==0 )
01463 {
01464
01465 computeGeomorphVertexList(MasterBlock.FarVertexList);
01466 }
01467 else
01468 {
01469
01470 computeGeomorphVertexList(MasterBlock.FarVertexList);
01471
01472 for(sint i=0; i<(sint)TessBlocks.size(); i++)
01473 {
01474 CTessBlock &tblock= TessBlocks[i];
01475
01476 if(!tblock.getClipped())
01477 {
01478
01479 computeGeomorphVertexList(tblock.FarVertexList);
01480 }
01481 }
01482 }
01483
01484
01485
01486
01487 if(Far0>0)
01488 {
01489
01490 computeGeomorphFar0VertexListVB(MasterBlock.FarVertexList);
01491 for(sint i=0; i<(sint)TessBlocks.size(); i++)
01492 {
01493 CTessBlock &tblock= TessBlocks[i];
01494
01495 if( tblock.visibleFar0() )
01496 computeGeomorphFar0VertexListVB(tblock.FarVertexList);
01497 }
01498 }
01499 else if(Far0==0)
01500 {
01501
01502
01503
01504 for(sint i=0; i<(sint)TessBlocks.size(); i++)
01505 {
01506 CTessBlock &tblock= TessBlocks[i];
01507
01508 if( tblock.visibleTile() )
01509 computeGeomorphTileVertexListVB(tblock.NearVertexList);
01510 }
01511 }
01512
01513
01514
01515 if(Far1>0)
01516 {
01517
01518 computeGeomorphAlphaFar1VertexListVB(MasterBlock.FarVertexList);
01519 for(sint i=0; i<(sint)TessBlocks.size(); i++)
01520 {
01521 CTessBlock &tblock= TessBlocks[i];
01522
01523 if( tblock.visibleFar1() )
01524 computeGeomorphAlphaFar1VertexListVB(tblock.FarVertexList);
01525 }
01526 }
01527 }
01528
01529
01530
01531
01532
01533
01534
01535
01536
01537
01538 void CPatch::updateClipPatchVB(bool renderClipped)
01539 {
01540
01541 if(renderClipped)
01542 {
01543
01544 deleteVBAndFaceVector();
01545
01546
01547
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
01560 allocateVBAndFaceVector();
01561
01562 fillVB();
01563 }
01564 }
01565
01566
01567
01568
01569
01570
01571
01572
01573
01574
01575
01576 void CPatch::checkCreateVertexVBFar(CTessFarVertex *pVert)
01577 {
01578 nlassert(pVert);
01579
01580
01581 if(!isRenderClipped() && Far0>0 && pVert->OwnerBlock->visibleFar0() )
01582 {
01583 pVert->Index0= CLandscapeGlobals::CurrentFar0VBAllocator->allocateVertex();
01584 }
01585
01586
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
01600
01601 if(!isRenderClipped() && Far0>0 && pVert->OwnerBlock->visibleFar0())
01602 {
01603 if( !CLandscapeGlobals::CurrentFar0VBAllocator->reallocationOccurs() )
01604 fillFar0VertexVB(pVert);
01605 }
01606
01607
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
01621
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
01634
01635 if(!isRenderClipped()&& Far0==0 && pVert->OwnerBlock->visibleTile() )
01636 {
01637
01638 if( !CLandscapeGlobals::CurrentTileVBAllocator->reallocationOccurs() )
01639 fillTileVertexVB(pVert);
01640 }
01641 }
01642
01643
01644
01645 void CPatch::checkDeleteVertexVBFar(CTessFarVertex *pVert)
01646 {
01647 nlassert(pVert);
01648
01649
01650 if(!isRenderClipped() && Far0>0 && pVert->OwnerBlock->visibleFar0() )
01651 {
01652 CLandscapeGlobals::CurrentFar0VBAllocator->deleteVertex(pVert->Index0);
01653 }
01654
01655
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
01667
01668 if(!isRenderClipped() && Far0==0 && pVert->OwnerBlock->visibleTile() )
01669 {
01670 CLandscapeGlobals::CurrentTileVBAllocator->deleteVertex(pVert->Index);
01671 }
01672 }
01673
01674
01675
01676
01677
01678
01679
01680
01681
01682
01683 void CPatch::fillFar0DLMUvOnlyVertexListVB(CTessList<CTessFarVertex> &vertList)
01684 {
01685
01686 nlassert(CLandscapeGlobals::CurrentFar0VBAllocator);
01687 nlassert(CLandscapeGlobals::CurrentFar0VBAllocator->bufferLocked());
01688
01689 nlassert(!CLandscapeGlobals::CurrentFar0VBAllocator->reallocationOccurs());
01690
01691 static uint8 *CurVBPtr;
01692 static CUV uvDLM;
01693
01694
01695 if(_DLMContext)
01696 {
01697
01698 CTessFarVertex *pVert;
01699 for(pVert= vertList.begin(); pVert; pVert= (CTessFarVertex*)pVert->Next)
01700 {
01701
01702 CurVBPtr= (uint8*)CLandscapeGlobals::CurrentFar0VBInfo.VertexCoordPointer;
01703 CurVBPtr+= pVert->Index0 * CLandscapeGlobals::CurrentFar0VBInfo.VertexSize;
01704
01705
01706 CParamCoord pc= pVert->PCoord;
01707
01708
01709 uvDLM.U= pc.getS()* _DLMContext->DLMUScale + _DLMContext->DLMUBias;
01710 uvDLM.V= pc.getT()* _DLMContext->DLMVScale + _DLMContext->DLMVBias;
01711
01712
01713 CHECK_VBA_RANGE(CLandscapeGlobals::CurrentFar0VBInfo.Accessor, CurVBPtr + CLandscapeGlobals::CurrentFar0VBInfo.TexCoordOff1, sizeof(CUV))
01714 *(CUV*)(CurVBPtr + CLandscapeGlobals::CurrentFar0VBInfo.TexCoordOff1)= uvDLM;
01715 }
01716 }
01717
01718 else
01719 {
01720
01721 uvDLM.U= 1;
01722 uvDLM.V= 1;
01723
01724
01725 CTessFarVertex *pVert;
01726 for(pVert= vertList.begin(); pVert; pVert= (CTessFarVertex*)pVert->Next)
01727 {
01728
01729 CurVBPtr= (uint8*)CLandscapeGlobals::CurrentFar0VBInfo.VertexCoordPointer;
01730 CurVBPtr+= pVert->Index0 * CLandscapeGlobals::CurrentFar0VBInfo.VertexSize;
01731
01732
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
01743 nlassert(CLandscapeGlobals::CurrentFar1VBAllocator);
01744 nlassert(CLandscapeGlobals::CurrentFar1VBAllocator->bufferLocked());
01745
01746 nlassert(!CLandscapeGlobals::CurrentFar1VBAllocator->reallocationOccurs());
01747
01748 static uint8 *CurVBPtr;
01749 static CUV uvDLM;
01750
01751
01752 if(_DLMContext)
01753 {
01754
01755 CTessFarVertex *pVert;
01756 for(pVert= vertList.begin(); pVert; pVert= (CTessFarVertex*)pVert->Next)
01757 {
01758
01759 CurVBPtr= (uint8*)CLandscapeGlobals::CurrentFar1VBInfo.VertexCoordPointer;
01760 CurVBPtr+= pVert->Index1 * CLandscapeGlobals::CurrentFar1VBInfo.VertexSize;
01761
01762
01763 CParamCoord pc= pVert->PCoord;
01764
01765
01766 uvDLM.U= pc.getS()* _DLMContext->DLMUScale + _DLMContext->DLMUBias;
01767 uvDLM.V= pc.getT()* _DLMContext->DLMVScale + _DLMContext->DLMVBias;
01768
01769
01770 CHECK_VBA_RANGE(CLandscapeGlobals::CurrentFar1VBInfo.Accessor, CurVBPtr + CLandscapeGlobals::CurrentFar1VBInfo.TexCoordOff1, sizeof(CUV))
01771 *(CUV*)(CurVBPtr + CLandscapeGlobals::CurrentFar1VBInfo.TexCoordOff1)= uvDLM;
01772 }
01773 }
01774
01775 else
01776 {
01777
01778 uvDLM.U= 1;
01779 uvDLM.V= 1;
01780
01781
01782 CTessFarVertex *pVert;
01783 for(pVert= vertList.begin(); pVert; pVert= (CTessFarVertex*)pVert->Next)
01784 {
01785
01786 CurVBPtr= (uint8*)CLandscapeGlobals::CurrentFar1VBInfo.VertexCoordPointer;
01787 CurVBPtr+= pVert->Index1 * CLandscapeGlobals::CurrentFar1VBInfo.VertexSize;
01788
01789
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
01801 if(Far0>0 && !CLandscapeGlobals::CurrentFar0VBAllocator->reallocationOccurs() )
01802 {
01803
01804 fillFar0DLMUvOnlyVertexListVB(MasterBlock.FarVertexList);
01805 for(sint i=0; i<(sint)TessBlocks.size(); i++)
01806 {
01807 CTessBlock &tblock= TessBlocks[i];
01808
01809 if( tblock.visibleFar0() )
01810 fillFar0DLMUvOnlyVertexListVB(tblock.FarVertexList);
01811 }
01812 }
01813
01814
01815 if(Far1>0 && !CLandscapeGlobals::CurrentFar1VBAllocator->reallocationOccurs() )
01816 {
01817
01818 fillFar1DLMUvOnlyVertexListVB(MasterBlock.FarVertexList);
01819 for(sint i=0; i<(sint)TessBlocks.size(); i++)
01820 {
01821 CTessBlock &tblock= TessBlocks[i];
01822
01823 if( tblock.visibleFar1() )
01824 fillFar1DLMUvOnlyVertexListVB(tblock.FarVertexList);
01825 }
01826 }
01827 }
01828
01829
01830
01831 }