# Home    # nevrax.com   
Nevrax
Nevrax.org
#News
#Mailing-list
#Documentation
#CVS
#Bugs
#License
Docs
 
Documentation  
Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages   Search  

landscapevb_allocator.cpp

Go to the documentation of this file.
00001 
00007 /* Copyright, 2001 Nevrax Ltd.
00008  *
00009  * This file is part of NEVRAX NEL.
00010  * NEVRAX NEL is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation; either version 2, or (at your option)
00013  * any later version.
00014 
00015  * NEVRAX NEL is distributed in the hope that it will be useful, but
00016  * WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00018  * General Public License for more details.
00019 
00020  * You should have received a copy of the GNU General Public License
00021  * along with NEVRAX NEL; see the file COPYING. If not, write to the
00022  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00023  * MA 02111-1307, USA.
00024  */
00025 
00026 #include "std3d.h"
00027 
00028 #include "3d/landscapevb_allocator.h"
00029 #include "3d/driver.h"
00030 
00031 
00032 using namespace std;
00033 
00034 namespace NL3D 
00035 {
00036 
00037 /*
00038         Once a reallocation of a VBHard occurs, how many vertices we add to the re-allocation, to avoid 
00039         as possible reallocations.
00040 */
00041 #define NL3D_LANDSCAPE_VERTEX_ALLOCATE_SECURITY         1024
00042 /*
00043         The start size of the array.
00044 */
00045 #define NL3D_LANDSCAPE_VERTEX_ALLOCATE_START            4048
00046 
00047 
00048 #define NL3D_VERTEX_FREE_MEMORY_RESERVE 1024
00049 // 65000 is a maximum because of GeForce limitations.
00050 #define NL3D_VERTEX_MAX_VERTEX_VBHARD   40000
00051 
00052 
00053 // ***************************************************************************
00054 CLandscapeVBAllocator::CLandscapeVBAllocator(TType type)
00055 {
00056         _Type= type;
00057         _VertexFreeMemory.reserve(NL3D_VERTEX_FREE_MEMORY_RESERVE);
00058 
00059         _ReallocationOccur= false;
00060         _NumVerticesAllocated= 0;
00061         _VBHardOk= false;
00062         _BufferLocked= false;
00063 
00064         for(uint i=0;i<MaxVertexProgram;i++)
00065                 _VertexProgram[i]= NULL;
00066 }
00067 
00068 // ***************************************************************************
00069 CLandscapeVBAllocator::~CLandscapeVBAllocator()
00070 {
00071         clear();
00072 }
00073 
00074 
00075 // ***************************************************************************
00076 void                    CLandscapeVBAllocator::updateDriver(IDriver *driver)
00077 {
00078         // test change of driver.
00079         nlassert(driver);
00080         if( _Driver==NULL || driver!=_Driver )
00081         {
00082                 deleteVertexBuffer();
00083                 _Driver= driver;
00084                 _VBHardOk= _Driver->supportVertexBufferHard();
00085 
00086                 // If change of driver, delete the VertexProgram first, if any
00087                 deleteVertexProgram();
00088                 // Then rebuild VB format, and VertexProgram, if needed.
00089                 // Do it only if VP supported by GPU.
00090                 setupVBFormatAndVertexProgram(_Driver->isVertexProgramSupported()  && !_Driver->isVertexProgramEmulated());
00091 
00092                 // must reallocate the VertexBuffer.
00093                 if( _NumVerticesAllocated>0 )
00094                         allocateVertexBuffer(_NumVerticesAllocated);
00095         }
00096         else
00097         {
00098                 // if VBHard possible, and if vbHardDeleted but space needed, reallocate.
00099                 if( _VBHardOk && _VBHard==NULL && _NumVerticesAllocated>0 )
00100                         allocateVertexBuffer(_NumVerticesAllocated);
00101         }
00102 
00103 }
00104 
00105 
00106 // ***************************************************************************
00107 void                    CLandscapeVBAllocator::clear()
00108 {
00109         // clear list.
00110         _VertexFreeMemory.clear();
00111         _NumVerticesAllocated= 0;
00112 
00113         // delete the VB.
00114         deleteVertexBuffer();
00115 
00116         // delete vertex Program, if any
00117         deleteVertexProgram();
00118 
00119         // clear other states.
00120         _ReallocationOccur= false;
00121         _Driver= NULL;
00122         _VBHardOk= false;
00123 }
00124 
00125 
00126 
00127 // ***************************************************************************
00128 void                    CLandscapeVBAllocator::resetReallocation()
00129 {
00130         _ReallocationOccur= false;
00131 }
00132 
00133 
00134 
00135 // ***************************************************************************
00136 // ***************************************************************************
00137 // allocation.
00138 // ***************************************************************************
00139 // ***************************************************************************
00140 
00141 
00142 
00143 // ***************************************************************************
00144 uint                    CLandscapeVBAllocator::allocateVertex()
00145 {
00146         // if no more free, allocate.
00147         if( _VertexFreeMemory.size()==0 )
00148         {
00149                 // enlarge capacity.
00150                 uint    newResize;
00151                 if(_NumVerticesAllocated==0)
00152                         newResize= NL3D_LANDSCAPE_VERTEX_ALLOCATE_START;
00153                 else
00154                         newResize= NL3D_LANDSCAPE_VERTEX_ALLOCATE_SECURITY;
00155                 _NumVerticesAllocated+= newResize;
00156                 // re-allocate VB.
00157                 allocateVertexBuffer(_NumVerticesAllocated);
00158                 // resize infos on vertices.
00159                 _VertexInfos.resize(_NumVerticesAllocated);
00160 
00161                 // Fill list of free elements.
00162                 for(uint i=0;i<newResize;i++)
00163                 {
00164                         // create a new entry which points to this vertex.
00165                         // the list is made so allocation is in growing order.
00166                         _VertexFreeMemory.push_back( _NumVerticesAllocated - (i+1) );
00167 
00168                         // Mark as free the new vertices. (Debug).
00169                         _VertexInfos[_NumVerticesAllocated - (i+1)].Free= true;
00170                 }
00171         }
00172 
00173         // get a vertex (pop_back).
00174         uint    id= _VertexFreeMemory.back();
00175         // delete this vertex free entry.
00176         _VertexFreeMemory.pop_back();
00177 
00178         // check and Mark as not free the vertex. (Debug).
00179         nlassert(id<_NumVerticesAllocated);
00180         nlassert(_VertexInfos[id].Free);
00181         _VertexInfos[id].Free= false;
00182 
00183         return id;
00184 }
00185 
00186 // ***************************************************************************
00187 void                    CLandscapeVBAllocator::deleteVertex(uint vid)
00188 {
00189         // check and Mark as free the vertex. (Debug).
00190         nlassert(vid<_NumVerticesAllocated);
00191         nlassert(!_VertexInfos[vid].Free);
00192         _VertexInfos[vid].Free= true;
00193 
00194         // Add this vertex to the free list.
00195         // create a new entry which points to this vertex.
00196         _VertexFreeMemory.push_back( vid );
00197 }
00198 
00199 
00200 // ***************************************************************************
00201 void                    CLandscapeVBAllocator::lockBuffer(CFarVertexBufferInfo &farVB)
00202 {
00203         nlassert( _Type==Far0 || _Type==Far1 );
00204         // force unlock
00205         unlockBuffer();
00206 
00207         if(_VBHard)
00208         {
00209                 void    *data= _VBHard->lock();
00210                 farVB.setupVertexBufferHard(*_VBHard, data, _VertexProgram[0]!=NULL );
00211         }
00212         else
00213         {
00214                 farVB.setupVertexBuffer(_VB, _VertexProgram[0]!=NULL );
00215         }
00216 
00217         _BufferLocked= true;
00218 }
00219 // ***************************************************************************
00220 void                    CLandscapeVBAllocator::lockBuffer(CNearVertexBufferInfo &tileVB)
00221 {
00222         nlassert(_Type==Tile);
00223         // force unlock
00224         unlockBuffer();
00225 
00226         if(_VBHard)
00227         {
00228                 void    *data= _VBHard->lock();
00229                 tileVB.setupVertexBufferHard(*_VBHard, data, _VertexProgram[0]!=NULL );
00230         }
00231         else
00232         {
00233                 tileVB.setupVertexBuffer(_VB, _VertexProgram[0]!=NULL );
00234         }
00235 
00236         _BufferLocked= true;
00237 }
00238 // ***************************************************************************
00239 void                    CLandscapeVBAllocator::unlockBuffer()
00240 {
00241         if(_BufferLocked)
00242         {
00243                 if(_VBHard)
00244                         _VBHard->unlock();
00245                 _BufferLocked= false;
00246         }
00247 }
00248 
00249 
00250 // ***************************************************************************
00251 // ***************************************************************************
00252 // VertexBuffer mgt.
00253 // ***************************************************************************
00254 // ***************************************************************************
00255 
00256 
00257 // ***************************************************************************
00258 void                    CLandscapeVBAllocator::activate(uint vpId)
00259 {
00260         nlassert(_Driver);
00261         nlassert(!_BufferLocked);
00262 
00263         // If enabled, activate Vertex program first.
00264         if(_VertexProgram[vpId])
00265         {
00266                 //nlinfo("\nSTARTVP\n%s\nENDVP\n", _VertexProgram[vpId]->getProgram().c_str());
00267                 nlverify(_Driver->activeVertexProgram(_VertexProgram[vpId]));
00268         }
00269 
00270         // Activate VB.
00271         if(_VBHard)
00272                 _Driver->activeVertexBufferHard(_VBHard);
00273         else
00274                 _Driver->activeVertexBuffer(_VB);
00275 }
00276 
00277 
00278 // ***************************************************************************
00279 void                            CLandscapeVBAllocator::deleteVertexBuffer()
00280 {
00281         // must unlock VBhard before.
00282         unlockBuffer();
00283 
00284         // test (refptr) if the object still exist in memory.
00285         if(_VBHard!=NULL)
00286         {
00287                 // A vbufferhard should still exist only if driver still exist.
00288                 nlassert(_Driver!=NULL);
00289 
00290                 // delete it from driver.
00291                 _Driver->deleteVertexBufferHard(_VBHard);
00292                 _VBHard= NULL;
00293         }
00294 
00295         // delete the soft one.
00296         _VB.deleteAllVertices();
00297 }
00298 
00299 
00300 // ***************************************************************************
00301 void                            CLandscapeVBAllocator::allocateVertexBuffer(uint32 numVertices)
00302 {
00303         // no allocation must be done if the Driver is not setuped, or if the driver has been deleted by refPtr.
00304         nlassert(_Driver);
00305 
00306         // allocate() =>_ReallocationOccur= true;
00307         _ReallocationOccur= true;
00308         // must unlock VBhard before.
00309         unlockBuffer();
00310 
00311         // trye to allocate a vbufferhard if possible.
00312         if( _VBHardOk )
00313         {
00314                 // delete possible old _VBHard.
00315                 if(_VBHard!=NULL)
00316                 {
00317                         // VertexBufferHard lifetime < Driver lifetime.
00318                         nlassert(_Driver!=NULL);
00319                         _Driver->deleteVertexBufferHard(_VBHard);
00320                 }
00321 
00322                 // try to create new one, in AGP Ram
00323                 // If too many vertices wanted, abort VBHard.
00324                 if(numVertices <= NL3D_VERTEX_MAX_VERTEX_VBHARD)
00325                         _VBHard= _Driver->createVertexBufferHard(_VB.getVertexFormat(), _VB.getValueTypePointer(), numVertices, IDriver::VBHardAGP);
00326                 else
00327                         _VBHard= NULL;
00328 
00329                 // If KO, never try again.
00330                 if(_VBHard==NULL)
00331                         _VBHardOk= false;
00332         }
00333 
00334         // else, or if last fails, allocate a standard VB.
00335         if(!_VBHardOk)
00336         {
00337                 // This always works.
00338                 _VB.setNumVertices(numVertices);
00339         }
00340 
00341 
00342         //nlinfo("Alloc a LandVB %s of %d vertices in %s", _Type==Far0?"Far0":(_Type==Far1?"Far1":"Tile"), numVertices, _VBHardOk?"VBHard":"VBSoft");
00343 }
00344 
00345 
00346 // ***************************************************************************
00347 // ***************************************************************************
00348 // Vertex Program.
00349 // ***************************************************************************
00350 // ***************************************************************************
00351 
00352 
00353 // ***************************************************************************
00354 /*
00355         Common Part. Inputs and constants.
00356 
00357         Inputs
00358         --------
00359         Standard:
00360         v[0] == StartPos.       Hence, It is the SplitPoint of the father face.
00361         v[8] == Tex0 (xy) 
00362         v[9] == Tex1 (xy) (different meanings for Far and Tile).
00363         v[13] == Tex2 (xy) (just for Tile mode).
00364 
00365         Geomorph:
00366         v[10] == { GeomFactor, MaxNearLimit }
00367                 * where GeomFactor == max(SizeFaceA, SizeFaceB) * OORefineThreshold.
00368                 It's means vertices are re-computed when the RefineThreshold setup change.
00369 
00370                 * MaxNearLimit= max(nearLimitFaceA, nearLimitFaceB)
00371 
00372         v[11].xyz == EndPos-StartPos
00373 
00374         Alpha: NB: Since only usefull for Far1, v[12] is not in the VB for Far0 and Tile VertexBuffer.
00375         v[12] == { TransitionSqrMin, OOTransitionSqrDelta}
00376                 * TransitionSqrMin, OOTransitionSqrDelta : Alpha transition, see preRender().
00377                         There is only 3 values possibles. It depends on Far1 type. Changed in preRender()
00378 
00379 
00380         Constant:
00381         --------
00382         Setuped at beginning of CLandscape::render()
00383         c[0..3]= ModelViewProjection Matrix.
00384         c[4]= {0, 1, 0.5, 0}
00385         c[5]= RefineCenter
00386         c[6]= {TileDistFarSqr, OOTileDistDeltaSqr, *, *}
00387         c[7]= ???
00388         c[8..11]= ModelView Matrix (for Fog).
00389         c[12]= PZBModelPosition: landscape center / delta Position to apply before multipliying by mviewMatrix
00390 
00391 
00392         Fog Note:
00393         -----------
00394         Fog is computed on geomorphed position R1.
00395         R1.w==1, and suppose that ModelViewMatrix has no Projection Part.
00396         Then Homogenous-coordinate == Non-Homogenous-coordinate.
00397         Hence we need only (ModelView*R1).z to get the FogC value.
00398         => computed in just on instruction.
00399 */
00400 
00401 
00402 // ***********************
00403 /*
00404         Common start of the program for Far0, Far1 and Tile mode.
00405         It compute the good Geomorphed position.
00406         At the end of this program, nothing is written in the output register, and we have in the Temp Registers:
00407 
00408         - R0= scratch
00409         - R1= CurrentPos geomorphed
00410         - R2.x= sqrDist= (startPos - RefineCenter).sqrnorm(). Usefull for alpha computing.
00411 
00412 Pgr Len= 18.
00413 NB: 9 ope for normal errorMetric, and 9 ope for smoothing with TileNear.
00414 
00415         The C code for this Program is:  (v[] means data is a vertex input, c[] means it is a constant)
00416         {
00417                 // Compute Basic ErrorMetric.
00418                 sqrDist= (v[StartPos] - c[RefineCenter]).sqrnorm()
00419                 ErrorMetric= v[GeomFactor] / sqrDist
00420 
00421                 // Compute ErrorMetric modified by TileNear transition.
00422                 f= (c[TileDistFarSqr] - sqrDist) * c[OOTileDistDeltaSqr]
00423                 clamp(f, 0, 1);
00424                 // ^4 gives better smooth result
00425                 f= sqr(f);      f= sqr(f);
00426                 // interpolate the errorMetric
00427                 ErrorMetricModified= v[MaxNearLimit]*f + ErrorMetric*(1-f);
00428 
00429                 // Take the max errorMetric.
00430                 ErrorMetric= max(ErrorMetric, ErrorMetricModified);
00431 
00432                 // Interpolate StartPos to EndPos, between 1 and 2.
00433                 f= ErrorMetric - 1;
00434                 clamp(f, 0, 1);
00435                 R1= f * v[EndPos-StartPos] + StartPos;
00436         }
00437 
00438 */
00439 const char* NL3D_LandscapeCommonStartProgram=
00440 "!!VP1.0                                                                                                                                                                \n\
00441         # compute Basic geomorph into R0.x                                                                                                      \n\
00442         ADD     R0, v[0], -c[5];                        # R0 = startPos - RefineCenter                                          \n\
00443         DP3     R2.x, R0, R0;                           # R2.x= sqrDist= (startPos - RefineCenter).sqrnorm()\n\
00444         RCP     R0.x, R2.x;                                     # R0.x= 1 / sqrDist                                                                     \n\
00445         MUL     R0.x, v[10].x, R0.x;            # R0.x= ErrorMetric= GeomFactor / sqrDist                       \n\
00446                                                                                                                                                                                 \n\
00447         # compute Transition Factor To TileNear Geomorph, into R0.z                                                     \n\
00448         ADD     R0.z, c[6].x, -R2.x;            # R0.z= TileDistFarSqr - sqrDist                                        \n\
00449         MUL     R0.z, R0.z, c[6].y;                     # R0.z= f= (TileDistFarSqr - sqrDist ) * OOTileDistDeltaSqr     \n\
00450         MAX R0.z, R0.z, c[4].x;                                                                                                                         \n\
00451         MIN R0.z, R0.z, c[4].y;                 # R0.z= f= clamp(f, 0, 1);                                                      \n\
00452         MUL R0.z, R0.z, R0.z;                                                                                                                           \n\
00453         MUL R0.z, R0.z, R0.z;                   # R0.z= finalFactor= f^4                                                        \n\
00454                                                                                                                                                                                 \n\
00455         # Apply the transition factor to the ErrorMetric => R0.w= ErrorMetricModified.          \n\
00456         ADD     R0.w, v[10].y, -R0.x;           # R0.w= maxNearLimit - ErrorMetric                                      \n\
00457         MAD     R0.w, R0.z, R0.w, R0.x; # R0.w= finalFactor * (maxNearLimit - ErrorMetric) + ErrorMetric \n\
00458                                                                                                                                                                                 \n\
00459         # R0.w may be < R0.x; (when the point is very near). Must take the bigger errorMetric.  \n\
00460         MAX     R0.x, R0.x, R0.w;                       # R0.x= ErrorMetric Max                                                         \n\
00461                                                                                                                                                                                 \n\
00462         # apply geomorph into R1                                                                                                                        \n\
00463         ADD R0.x, R0.x, -c[4].y;                # R0.x= ErrorMetric Max - 1                                                     \n\
00464         MAX R0.x, R0.x, c[4].x;                                                                                                                         \n\
00465         MIN R0.x, R0.x, c[4].y;                 # R0.x= geomBlend= clamp(R0.x, 0, 1);                           \n\
00466                                                                                                                                                                                 \n\
00467         # NB: Can't use MAD R1.xyz, v[11], R0.x, v[0], because can't acces 2 inputs in one op.  \n\
00468         # Hence, can use a MAD to Sub the Landscape Center _PZBModelPosition                            \n\
00469         MAD     R1.xyz, v[11], R0.x, -c[12];                                                                                                    \n\
00470         # trick here: since R1.w= 0, and v[0].w= 1, final R1.w==1.                                                      \n\
00471         ADD     R1, R1, v[0];                           # R1= geomBlend * (EndPos-StartPos) + StartPos          \n\
00472 ";
00473 
00474 
00475 // ***********************
00476 // Test Speed.
00477 /*"!!VP1.0                                                                                                                                                              \n\
00478         # compute Basic geomorph into R0.x                                                                                                      \n\
00479         ADD     R0, v[0], -c[5];                        # R0 = startPos - RefineCenter                                          \n\
00480         DP3     R2.x, R0, R0;                           # R2.x= sqrDist= (startPos - RefineCenter).sqrnorm()\n\
00481         MOV     R1, v[0];                                       # R1= geomBlend * (EndPos-StartPos) + StartPos          \n\
00482 ";
00483 */
00484 const string NL3D_LandscapeTestSpeedProgram=
00485 "       MOV R1, R1; \n  MOV R1, R1; \n  MOV R1, R1; \n  MOV R1, R1; \n  MOV R1, R1; \n\
00486         MOV R1, R1; \n  MOV R1, R1; \n  MOV R1, R1; \n  MOV R1, R1; \n  MOV R1, R1; \n\
00487 ";
00488 
00489 
00490 // ***********************
00491 /*
00492         Far0:
00493                 just project, copy uv0 and uv1
00494                 NB: leave o[COL0] undefined because the material don't care diffuse RGBA here
00495 */
00496 // ***********************
00497 const char* NL3D_LandscapeFar0EndProgram=
00498 "       # compute in Projection space                                                                                                           \n\
00499         DP4 o[HPOS].x, c[0], R1;                                                                                                                        \n\
00500         DP4 o[HPOS].y, c[1], R1;                                                                                                                        \n\
00501         DP4 o[HPOS].z, c[2], R1;                                                                                                                        \n\
00502         DP4 o[HPOS].w, c[3], R1;                                                                                                                        \n\
00503         MOV o[TEX0].xy, v[8];                                                                                                                           \n\
00504         MOV o[TEX1].xy, v[9];                                                                                                                           \n\
00505         DP4     o[FOGC].x, c[10], -R1;          # fogc>0 => fogc= - (ModelView*R1).z                            \n\
00506         END                                                                                                                                                                     \n\
00507 ";
00508 
00509 
00510 // ***********************
00511 /*
00512         Far1:
00513                 Compute Alpha transition.
00514                 Project, copy uv0 and uv1, 
00515                 NB: leave o[COL0] RGB undefined because the material don't care diffuse RGB
00516 */
00517 // ***********************
00518 const char* NL3D_LandscapeFar1EndProgram=
00519 "       # compute Alpha Transition                                                                                                                      \n\
00520         ADD R0.x, R2.x, -v[12].x;               # R0.x= sqrDist-TransitionSqrMin                                        \n\
00521         MUL     R0.x, R0.x, v[12].y;            # R0.x= (sqrDist-TransitionSqrMin) * OOTransitionSqrDelta       \n\
00522         MAX R0.x, R0.x, c[4].x;                                                                                                                         \n\
00523         MIN o[COL0].w, R0.x, c[4].y;    # col.A= clamp(R0.x, 0, 1);                                                     \n\
00524                                                                                                                                                                                 \n\
00525         # compute in Projection space                                                                                                           \n\
00526         DP4 o[HPOS].x, c[0], R1;                                                                                                                        \n\
00527         DP4 o[HPOS].y, c[1], R1;                                                                                                                        \n\
00528         DP4 o[HPOS].z, c[2], R1;                                                                                                                        \n\
00529         DP4 o[HPOS].w, c[3], R1;                                                                                                                        \n\
00530         MOV o[TEX0].xy, v[8];                                                                                                                           \n\
00531         MOV o[TEX1].xy, v[9];                                                                                                                           \n\
00532         DP4     o[FOGC].x, c[10], -R1;          # fogc>0 => fogc= - (ModelView*R1).z                            \n\
00533         END                                                                                                                                                                     \n\
00534 ";
00535 
00536 
00537 // ***********************
00538 /*
00539         Tile:
00540                 just project, copy uv0, uv1.
00541                 NB: leave o[COL0] undefined because the material don't care diffuse RGBA here
00542 */
00543 // ***********************
00544 const char* NL3D_LandscapeTileEndProgram=
00545 "       # compute in Projection space                                                                                                           \n\
00546         DP4 o[HPOS].x, c[0], R1;                                                                                                                        \n\
00547         DP4 o[HPOS].y, c[1], R1;                                                                                                                        \n\
00548         DP4 o[HPOS].z, c[2], R1;                                                                                                                        \n\
00549         DP4 o[HPOS].w, c[3], R1;                                                                                                                        \n\
00550         MOV o[TEX0].xy, v[8];                                                                                                                           \n\
00551         MOV o[TEX1].xy, v[9];                                                                                                                           \n\
00552         DP4     o[FOGC].x, c[10], -R1;          # fogc>0 => fogc= - (ModelView*R1).z                            \n\
00553         END                                                                                                                                                                     \n\
00554 ";
00555 
00557 const char* NL3D_LandscapeTileLightMapEndProgram=
00558 "       # compute in Projection space                                                                                                           \n\
00559         DP4 o[HPOS].x, c[0], R1;                                                                                                                        \n\
00560         DP4 o[HPOS].y, c[1], R1;                                                                                                                        \n\
00561         DP4 o[HPOS].z, c[2], R1;                                                                                                                        \n\
00562         DP4 o[HPOS].w, c[3], R1;                                                                                                                        \n\
00563         MOV o[TEX0].xy, v[13];                                                                                                                          \n\
00564         MOV o[TEX1].xy, v[9];                                                                                                                           \n\
00565         DP4     o[FOGC].x, c[10], -R1;          # fogc>0 => fogc= - (ModelView*R1).z                            \n\
00566         END                                                                                                                                                                     \n\
00567 ";
00568 
00569 
00570 // ***************************************************************************
00571 void                    CLandscapeVBAllocator::deleteVertexProgram()
00572 {
00573         for(uint i=0;i<MaxVertexProgram;i++)
00574         {
00575                 if(_VertexProgram[i])
00576                 {
00577                         delete _VertexProgram[i];
00578                         _VertexProgram[i]= NULL;
00579                 }
00580         }
00581 }
00582 
00583 
00584 // ***************************************************************************
00585 void                    CLandscapeVBAllocator::setupVBFormatAndVertexProgram(bool withVertexProgram)
00586 {
00587         // If not vertexProgram mode
00588         if(!withVertexProgram)
00589         {
00590                 // setup normal VB format.
00591                 if(_Type==Far0)
00592                         // v3f/t2f0/t2f1
00593                         _VB.setVertexFormat(CVertexBuffer::PositionFlag | CVertexBuffer::TexCoord0Flag | CVertexBuffer::TexCoord1Flag);
00594                 else if(_Type==Far1)
00595                         // v3f/t2f/t2f1/c4ub
00596                         _VB.setVertexFormat(CVertexBuffer::PositionFlag | CVertexBuffer::TexCoord0Flag | CVertexBuffer::TexCoord1Flag | CVertexBuffer::PrimaryColorFlag );
00597                 else
00598                         // v3f/t2f0/t2f1/t2f2
00599                         _VB.setVertexFormat(CVertexBuffer::PositionFlag | CVertexBuffer::TexCoord0Flag | CVertexBuffer::TexCoord1Flag | CVertexBuffer::TexCoord2Flag);
00600         }
00601         else
00602         {
00603                 // Else Setup our Vertex Program, and good VBuffers, according to _Type.
00604 
00605                 if(_Type==Far0)
00606                 {
00607                         // Build the Vertex Format.
00608                         _VB.clearValueEx();
00609                         _VB.addValueEx(NL3D_LANDSCAPE_VPPOS_STARTPOS,   CVertexBuffer::Float3); // v[0]= StartPos.
00610                         _VB.addValueEx(NL3D_LANDSCAPE_VPPOS_TEX0,               CVertexBuffer::Float2); // v[8]= Tex0.
00611                         _VB.addValueEx(NL3D_LANDSCAPE_VPPOS_TEX1,               CVertexBuffer::Float2); // v[9]= Tex1.
00612                         _VB.addValueEx(NL3D_LANDSCAPE_VPPOS_GEOMINFO,   CVertexBuffer::Float2); // v[10]= GeomInfos.
00613                         _VB.addValueEx(NL3D_LANDSCAPE_VPPOS_DELTAPOS,   CVertexBuffer::Float3); // v[11]= EndPos-StartPos.
00614                         _VB.initEx();
00615 
00616                         // Init the Vertex Program.
00617                         string  vpgram= string(NL3D_LandscapeCommonStartProgram) + 
00618                                 string(NL3D_LandscapeFar0EndProgram);
00619                         _VertexProgram[0]= new CVertexProgram(vpgram.c_str());
00620                 }
00621                 else if(_Type==Far1)
00622                 {
00623                         // Build the Vertex Format.
00624                         _VB.clearValueEx();
00625                         _VB.addValueEx(NL3D_LANDSCAPE_VPPOS_STARTPOS,   CVertexBuffer::Float3); // v[0]= StartPos.
00626                         _VB.addValueEx(NL3D_LANDSCAPE_VPPOS_TEX0,               CVertexBuffer::Float2); // v[8]= Tex0.
00627                         _VB.addValueEx(NL3D_LANDSCAPE_VPPOS_TEX1,               CVertexBuffer::Float2); // v[9]= Tex1.
00628                         _VB.addValueEx(NL3D_LANDSCAPE_VPPOS_GEOMINFO,   CVertexBuffer::Float2); // v[10]= GeomInfos.
00629                         _VB.addValueEx(NL3D_LANDSCAPE_VPPOS_DELTAPOS,   CVertexBuffer::Float3); // v[11]= EndPos-StartPos.
00630                         _VB.addValueEx(NL3D_LANDSCAPE_VPPOS_ALPHAINFO,  CVertexBuffer::Float2); // v[12]= AlphaInfos.
00631                         _VB.initEx();
00632 
00633                         // Init the Vertex Program.
00634                         string  vpgram= string(NL3D_LandscapeCommonStartProgram) + 
00635                                 string(NL3D_LandscapeFar1EndProgram);
00636                         _VertexProgram[0]= new CVertexProgram(vpgram.c_str());
00637                 }
00638                 else
00639                 {
00640                         // Build the Vertex Format.
00641                         _VB.clearValueEx();
00642                         _VB.addValueEx(NL3D_LANDSCAPE_VPPOS_STARTPOS,   CVertexBuffer::Float3); // v[0]= StartPos.
00643                         _VB.addValueEx(NL3D_LANDSCAPE_VPPOS_TEX0,               CVertexBuffer::Float2); // v[8]= Tex0.
00644                         _VB.addValueEx(NL3D_LANDSCAPE_VPPOS_TEX1,               CVertexBuffer::Float2); // v[9]= Tex1.
00645                         _VB.addValueEx(NL3D_LANDSCAPE_VPPOS_TEX2,               CVertexBuffer::Float2); // v[13]= Tex2.
00646                         _VB.addValueEx(NL3D_LANDSCAPE_VPPOS_GEOMINFO,   CVertexBuffer::Float2); // v[10]= GeomInfos.
00647                         _VB.addValueEx(NL3D_LANDSCAPE_VPPOS_DELTAPOS,   CVertexBuffer::Float3); // v[11]= EndPos-StartPos.
00648                         _VB.initEx();
00649 
00650                         // Init the Vertex Program.
00651                         string  vpgram= string(NL3D_LandscapeCommonStartProgram) + 
00652                                 string(NL3D_LandscapeTileEndProgram);
00653                         _VertexProgram[0]= new CVertexProgram(vpgram.c_str());
00654 
00655                         // Init the Vertex Program for lightmap pass
00656                         vpgram= string(NL3D_LandscapeCommonStartProgram) + 
00657                                 string(NL3D_LandscapeTileLightMapEndProgram);
00658                         _VertexProgram[1]= new CVertexProgram(vpgram.c_str());
00659                 }
00660         }
00661 
00662 }
00663 
00664 
00665 
00666 
00667 } // NL3D