Merge branch 'ryzom/ark-features' into main/gingo-test
[ryzomcore.git] / nel / src / 3d / landscapevb_allocator.cpp
blob762101cdb19038cb30b0a4cf3403084798c8ce4b
1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
3 //
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2013 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
6 //
7 // This program is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU Affero General Public License as
9 // published by the Free Software Foundation, either version 3 of the
10 // License, or (at your option) any later version.
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU Affero General Public License for more details.
17 // You should have received a copy of the GNU Affero General Public License
18 // along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include "std3d.h"
22 #include "nel/3d/landscapevb_allocator.h"
23 #include "nel/3d/driver.h"
24 #include "nel/misc/fast_mem.h"
27 using namespace std;
28 using namespace NLMISC;
30 #ifdef DEBUG_NEW
31 #define new DEBUG_NEW
32 #endif
34 namespace NL3D
38 Once a reallocation of a VBHard occurs, how many vertices we add to the re-allocation, to avoid
39 as possible reallocations.
41 #define NL3D_LANDSCAPE_VERTEX_ALLOCATE_SECURITY 1024
43 The start size of the array.
45 #define NL3D_LANDSCAPE_VERTEX_ALLOCATE_START 4048
48 #define NL3D_VERTEX_FREE_MEMORY_RESERVE 1024
49 /*// 65000 is a maximum because of GeForce limitations.
50 #define NL3D_VERTEX_MAX_VERTEX_VBHARD 40000*/
53 // ***************************************************************************
54 CLandscapeVBAllocator::CLandscapeVBAllocator(TType type, const std::string &vbName)
56 _Type= type;
57 _VBName= vbName;
58 _VertexFreeMemory.reserve(NL3D_VERTEX_FREE_MEMORY_RESERVE);
60 _ReallocationOccur= false;
61 _NumVerticesAllocated= 0;
62 _BufferLocked= false;
63 _LastFarVB = NULL;
64 _LastNearVB = NULL;
66 for(uint i=0;i<MaxVertexProgram;i++)
67 _VertexProgram[i]= NULL;
70 // ***************************************************************************
71 CLandscapeVBAllocator::~CLandscapeVBAllocator()
73 clear();
77 // ***************************************************************************
78 void CLandscapeVBAllocator::updateDriver(IDriver *driver)
80 // test change of driver.
81 nlassert(driver);
82 if( _Driver==NULL || driver!=_Driver )
84 deleteVertexBuffer();
85 _Driver= driver;
88 // If change of driver, delete the VertexProgram first, if any
89 deleteVertexProgram();
90 // Then rebuild VB format, and VertexProgram, if needed.
91 // Do it only if VP supported by GPU.
92 setupVBFormatAndVertexProgram(!_Driver->isVertexProgramEmulated() && (
93 _Driver->supportVertexProgram(CVertexProgram::nelvp)
94 // || _Driver->supportVertexProgram(CVertexProgram::glsl330v) // TODO_VP_GLSL
95 ));
97 // must reallocate the VertexBuffer.
98 if( _NumVerticesAllocated>0 )
99 allocateVertexBuffer(_NumVerticesAllocated);
104 // ***************************************************************************
105 void CLandscapeVBAllocator::clear()
107 // clear list.
108 _VertexFreeMemory.clear();
109 _NumVerticesAllocated= 0;
111 // delete the VB.
112 deleteVertexBuffer();
114 // delete vertex Program, if any
115 deleteVertexProgram();
117 // clear other states.
118 _ReallocationOccur= false;
119 _Driver= NULL;
124 // ***************************************************************************
125 void CLandscapeVBAllocator::resetReallocation()
127 _ReallocationOccur= false;
132 // ***************************************************************************
133 // ***************************************************************************
134 // allocation.
135 // ***************************************************************************
136 // ***************************************************************************
140 // ***************************************************************************
141 uint CLandscapeVBAllocator::allocateVertex()
143 // if no more free, allocate.
144 if( _VertexFreeMemory.empty() )
146 // enlarge capacity.
147 uint newResize;
148 if(_NumVerticesAllocated==0)
149 newResize= NL3D_LANDSCAPE_VERTEX_ALLOCATE_START;
150 else
151 newResize= NL3D_LANDSCAPE_VERTEX_ALLOCATE_SECURITY;
152 _NumVerticesAllocated+= newResize;
153 // re-allocate VB.
154 #ifdef NL_LANDSCAPE_INDEX16
155 nlassert(_NumVerticesAllocated <= 65535);
156 #endif
157 allocateVertexBuffer(_NumVerticesAllocated);
158 // resize infos on vertices.
159 _VertexInfos.resize(_NumVerticesAllocated);
161 // Fill list of free elements.
162 for(uint i=0;i<newResize;i++)
164 // create a new entry which points to this vertex.
165 // the list is made so allocation is in growing order.
166 _VertexFreeMemory.push_back( _NumVerticesAllocated - (i+1) );
168 // Mark as free the new vertices. (Debug).
169 _VertexInfos[_NumVerticesAllocated - (i+1)].Free= true;
173 // get a vertex (pop_back).
174 uint id= _VertexFreeMemory.back();
175 // delete this vertex free entry.
176 _VertexFreeMemory.pop_back();
178 // check and Mark as not free the vertex. (Debug).
179 nlassert(id<_NumVerticesAllocated);
180 nlassert(_VertexInfos[id].Free);
181 _VertexInfos[id].Free= false;
186 return id;
189 // ***************************************************************************
190 void CLandscapeVBAllocator::deleteVertex(uint vid)
192 // check and Mark as free the vertex. (Debug).
193 nlassert(vid<_NumVerticesAllocated);
194 nlassert(!_VertexInfos[vid].Free);
195 _VertexInfos[vid].Free= true;
197 // Add this vertex to the free list.
198 // create a new entry which points to this vertex.
199 _VertexFreeMemory.push_back( vid );
203 // ***************************************************************************
204 void CLandscapeVBAllocator::lockBuffer(CFarVertexBufferInfo &farVB)
206 nlassert( _Type==Far0 || _Type==Far1 );
208 // force unlock
209 unlockBuffer();
211 _LastFarVB = &farVB;
213 farVB.setupVertexBuffer(_VB, _VertexProgram[0]!=NULL );
215 _BufferLocked= true;
217 // ***************************************************************************
218 void CLandscapeVBAllocator::lockBuffer(CNearVertexBufferInfo &tileVB)
220 nlassert(_Type==Tile);
222 // force unlock
223 unlockBuffer();
225 _LastNearVB = &tileVB;
227 tileVB.setupVertexBuffer(_VB, _VertexProgram[0]!=NULL );
229 _BufferLocked= true;
231 // ***************************************************************************
232 void CLandscapeVBAllocator::unlockBuffer()
234 if(_BufferLocked)
236 if (_LastFarVB)
237 _LastFarVB->setupNullPointers();
238 _LastFarVB = NULL;
239 if (_LastNearVB)
240 _LastNearVB->setupNullPointers();
241 _LastNearVB = NULL;
242 _BufferLocked= false;
247 // ***************************************************************************
248 // ***************************************************************************
249 // VertexBuffer mgt.
250 // ***************************************************************************
251 // ***************************************************************************
254 // ***************************************************************************
255 void CLandscapeVBAllocator::activate(uint vpId)
257 nlassert(_Driver);
258 nlassert(!_BufferLocked);
260 activateVP(vpId);
262 _Driver->activeVertexBuffer(_VB);
266 // ***************************************************************************
267 void CLandscapeVBAllocator::activateVP(uint vpId)
269 nlassert(_Driver);
271 // If enabled, activate Vertex program first.
272 if (_VertexProgram[vpId])
274 //nlinfo("\nSTARTVP\n%s\nENDVP\n", _VertexProgram[vpId]->getProgram().c_str());
275 nlverify(_Driver->activeVertexProgram(_VertexProgram[vpId]));
280 // ***************************************************************************
281 void CLandscapeVBAllocator::deleteVertexBuffer()
283 // must unlock VBhard before.
284 unlockBuffer();
286 // delete the soft one.
287 _VB.deleteAllVertices();
291 // ***************************************************************************
292 void CLandscapeVBAllocator::allocateVertexBuffer(uint32 numVertices)
294 // no allocation must be done if the Driver is not setuped, or if the driver has been deleted by refPtr.
295 nlassert(_Driver);
297 // allocate() =>_ReallocationOccur= true;
298 _ReallocationOccur= true;
299 // must unlock VBhard before.
300 unlockBuffer();
302 // This always works.
303 _VB.setPreferredMemory(CVertexBuffer::AGPPreferred, false);
304 _VB.setNumVertices(numVertices);
305 _VB.setName (_VBName);
309 // ***************************************************************************
310 // ***************************************************************************
311 // Vertex Program.
312 // ***************************************************************************
313 // ***************************************************************************
316 // ***************************************************************************
318 Common Part. Inputs and constants.
320 Inputs
321 --------
322 Standard:
323 v[0] == StartPos. Hence, It is the SplitPoint of the father face.
324 v[8] == Tex0 (xy)
325 v[9] == Tex1 (xy) (different meanings for Far and Tile).
326 v[13] == Tex2 (xy) (just for Tile mode).
328 Geomorph:
329 v[10] == { GeomFactor, MaxNearLimit }
330 * where GeomFactor == max(SizeFaceA, SizeFaceB) * OORefineThreshold.
331 It's means vertices are re-computed when the RefineThreshold setup change.
333 * MaxNearLimit= max(nearLimitFaceA, nearLimitFaceB)
335 v[11].xyz == EndPos-StartPos
337 Alpha: NB: Since only useful for Far1, v[12] is not in the VB for Far0 and Tile VertexBuffer.
338 v[12] == { TransitionSqrMin, OOTransitionSqrDelta}
339 * TransitionSqrMin, OOTransitionSqrDelta : Alpha transition, see preRender().
340 There is only 3 values possibles. It depends on Far1 type. Changed in preRender()
343 Constant:
344 --------
345 Setuped at beginning of CLandscape::render()
346 c[0..3]= ModelViewProjection Matrix.
347 c[4]= {0, 1, 0.5, 0}
348 c[5]= RefineCenter
349 c[6]= {TileDistFarSqr, OOTileDistDeltaSqr, *, *}
350 c[7]= ???
351 c[8..11]= ModelView Matrix (for Fog).
352 c[12]= PZBModelPosition: landscape center / delta Position to apply before multipliying by mviewMatrix
355 Fog Note:
356 -----------
357 Fog is computed on geomorphed position R1.
358 R1.w==1, and suppose that ModelViewMatrix has no Projection Part.
359 Then Homogenous-coordinate == Non-Homogenous-coordinate.
360 Hence we need only (FogVector*R1).z to get the FogC value.
361 => computed in just on instruction.
365 // ***********************
367 Common start of the program for Far0, Far1 and Tile mode.
368 It compute the good Geomorphed position.
369 At the end of this program, nothing is written in the output register, and we have in the Temp Registers:
371 - R0= scratch
372 - R1= CurrentPos geomorphed
373 - R2.x= sqrDist= (startPos - RefineCenter).sqrnorm(). Useful for alpha computing.
375 Pgr Len= 18.
376 NB: 9 ope for normal errorMetric, and 9 ope for smoothing with TileNear.
378 The C code for this Program is: (v[] means data is a vertex input, c[] means it is a constant)
380 // Compute Basic ErrorMetric.
381 sqrDist= (v[StartPos] - c[RefineCenter]).sqrnorm()
382 ErrorMetric= v[GeomFactor] / sqrDist
384 // Compute ErrorMetric modified by TileNear transition.
385 f= (c[TileDistFarSqr] - sqrDist) * c[OOTileDistDeltaSqr]
386 clamp(f, 0, 1);
387 // ^4 gives better smooth result
388 f= sqr(f); f= sqr(f);
389 // interpolate the errorMetric
390 ErrorMetricModified= v[MaxNearLimit]*f + ErrorMetric*(1-f);
392 // Take the max errorMetric.
393 ErrorMetric= max(ErrorMetric, ErrorMetricModified);
395 // Interpolate StartPos to EndPos, between 1 and 2.
396 f= ErrorMetric - 1;
397 clamp(f, 0, 1);
398 R1= f * v[EndPos-StartPos] + StartPos;
402 const char* NL3D_LandscapeCommonStartProgram=
403 "!!VP1.0 \n\
404 # compute Basic geomorph into R0.x \n\
405 ADD R0, v[0], -c[5]; # R0 = startPos - RefineCenter \n\
406 DP3 R2.x, R0, R0; # R2.x= sqrDist= (startPos - RefineCenter).sqrnorm()\n\
407 RCP R0.x, R2.x; # R0.x= 1 / sqrDist \n\
408 MUL R0.x, v[10].x, R0.x; # R0.x= ErrorMetric= GeomFactor / sqrDist \n\
410 # compute Transition Factor To TileNear Geomorph, into R0.z \n\
411 ADD R0.z, c[6].x, -R2.x; # R0.z= TileDistFarSqr - sqrDist \n\
412 MUL R0.z, R0.z, c[6].y; # R0.z= f= (TileDistFarSqr - sqrDist ) * OOTileDistDeltaSqr \n\
413 MAX R0.z, R0.z, c[4].x; \n\
414 MIN R0.z, R0.z, c[4].y; # R0.z= f= clamp(f, 0, 1); \n\
415 MUL R0.z, R0.z, R0.z; \n\
416 MUL R0.z, R0.z, R0.z; # R0.z= finalFactor= f^4 \n\
418 # Apply the transition factor to the ErrorMetric => R0.w= ErrorMetricModified. \n\
419 ADD R0.w, v[10].y, -R0.x; # R0.w= maxNearLimit - ErrorMetric \n\
420 MAD R0.w, R0.z, R0.w, R0.x; # R0.w= finalFactor * (maxNearLimit - ErrorMetric) + ErrorMetric \n\
422 # R0.w may be < R0.x; (when the point is very near). Must take the bigger errorMetric. \n\
423 MAX R0.x, R0.x, R0.w; # R0.x= ErrorMetric Max \n\
425 # apply geomorph into R1 \n\
426 ADD R0.x, R0.x, -c[4].y; # R0.x= ErrorMetric Max - 1 \n\
427 MAX R0.x, R0.x, c[4].x; \n\
428 MIN R0.x, R0.x, c[4].y; # R0.x= geomBlend= clamp(R0.x, 0, 1); \n\
430 # NB: Can't use MAD R1.xyz, v[11], R0.x, v[0], because can't acces 2 inputs in one op. \n\
431 # Hence, can use a MAD to Sub the Landscape Center _PZBModelPosition \n\
432 # write to R1.w is useless (but needed to avoid a read error when multiplied by 0) \n\
433 # in the next instruction \n\
434 MAD R1.xyzw, v[11], R0.x, -c[12]; \n\
435 # set w to 1 by using c[4] = { 0, 1, 0.5, 0} \n\
436 MAD R1, R1, c[4].yyyx, v[0]; # R1= geomBlend * (EndPos-StartPos) + StartPos \n\
440 // ***********************
441 // Test Speed.
442 /*"!!VP1.0 \n\
443 # compute Basic geomorph into R0.x \n\
444 ADD R0, v[0], -c[5]; # R0 = startPos - RefineCenter \n\
445 DP3 R2.x, R0, R0; # R2.x= sqrDist= (startPos - RefineCenter).sqrnorm()\n\
446 MOV R1, v[0]; # R1= geomBlend * (EndPos-StartPos) + StartPos \n\
449 const string NL3D_LandscapeTestSpeedProgram=
450 " MOV R1, R1; \n MOV R1, R1; \n MOV R1, R1; \n MOV R1, R1; \n MOV R1, R1; \n\
451 MOV R1, R1; \n MOV R1, R1; \n MOV R1, R1; \n MOV R1, R1; \n MOV R1, R1; \n\
455 // ***********************
457 Far0:
458 just project, copy uv0 and uv1
459 NB: leave o[COL0] undefined because the material don't care diffuse RGBA here
461 // ***********************
462 const char* NL3D_LandscapeFar0EndProgram=
463 " # compute in Projection space \n\
464 DP4 o[HPOS].x, c[0], R1; \n\
465 DP4 o[HPOS].y, c[1], R1; \n\
466 DP4 o[HPOS].z, c[2], R1; \n\
467 DP4 o[HPOS].w, c[3], R1; \n\
468 MOV o[TEX0], v[8]; \n\
469 MOV o[TEX1], v[9]; \n\
470 DP4 o[FOGC].x, c[10], R1; \n\
471 END \n\
475 // ***********************
477 Far1:
478 Compute Alpha transition.
479 Project, copy uv0 and uv1,
480 NB: leave o[COL0] RGB undefined because the material don't care diffuse RGB
482 // ***********************
483 const char* NL3D_LandscapeFar1EndProgram=
484 " # compute Alpha Transition \n\
485 ADD R0.x, R2.x, -v[12].x; # R0.x= sqrDist-TransitionSqrMin \n\
486 MUL R0.x, R0.x, v[12].y; # R0.x= (sqrDist-TransitionSqrMin) * OOTransitionSqrDelta \n\
487 MAX R0.x, R0.x, c[4].x; \n\
488 MIN o[COL0].w, R0.x, c[4].y; # col.A= clamp(R0.x, 0, 1); \n\
490 # compute in Projection space \n\
491 DP4 o[HPOS].x, c[0], R1; \n\
492 DP4 o[HPOS].y, c[1], R1; \n\
493 DP4 o[HPOS].z, c[2], R1; \n\
494 DP4 o[HPOS].w, c[3], R1; \n\
495 MOV o[TEX0], v[8]; \n\
496 MOV o[TEX1], v[9]; \n\
497 DP4 o[FOGC].x, c[10], R1; \n\
498 END \n\
502 // ***********************
504 Tile:
505 just project, copy uv0, uv1.
506 NB: leave o[COL0] undefined because the material don't care diffuse RGBA here
508 // ***********************
509 const char* NL3D_LandscapeTileEndProgram=
510 " # compute in Projection space \n\
511 DP4 o[HPOS].x, c[0], R1; \n\
512 DP4 o[HPOS].y, c[1], R1; \n\
513 DP4 o[HPOS].z, c[2], R1; \n\
514 DP4 o[HPOS].w, c[3], R1; \n\
515 MOV o[TEX0], v[8]; \n\
516 MOV o[TEX1], v[9]; \n\
517 DP4 o[FOGC].x, c[10], R1; \n\
518 END \n\
521 /// Same version but write Tex0 to take uv2, ie v[13], for lightmap pass
522 const char* NL3D_LandscapeTileLightMapEndProgram=
523 " # compute in Projection space \n\
524 DP4 o[HPOS].x, c[0], R1; \n\
525 DP4 o[HPOS].y, c[1], R1; \n\
526 DP4 o[HPOS].z, c[2], R1; \n\
527 DP4 o[HPOS].w, c[3], R1; \n\
528 MOV o[TEX0], v[12]; \n\
529 MOV o[TEX1], v[9]; \n\
530 DP4 o[FOGC].x, c[10], R1; \n\
531 END \n\
535 // ***************************************************************************
536 void CLandscapeVBAllocator::deleteVertexProgram()
538 for (uint i = 0; i < MaxVertexProgram; ++i)
540 if (_VertexProgram[i])
542 _VertexProgram[i] = NULL; // smartptr
548 // ***************************************************************************
549 void CLandscapeVBAllocator::setupVBFormatAndVertexProgram(bool withVertexProgram)
551 // If not vertexProgram mode
552 if(!withVertexProgram)
554 // setup normal VB format.
555 if(_Type==Far0)
556 // v3f/t2f0/t2f1
557 _VB.setVertexFormat(CVertexBuffer::PositionFlag | CVertexBuffer::TexCoord0Flag | CVertexBuffer::TexCoord1Flag);
558 else if(_Type==Far1)
559 // v3f/t2f/t2f1/c4ub
560 _VB.setVertexFormat(CVertexBuffer::PositionFlag | CVertexBuffer::TexCoord0Flag | CVertexBuffer::TexCoord1Flag | CVertexBuffer::PrimaryColorFlag );
561 else
562 // v3f/t2f0/t2f1/t2f2
563 _VB.setVertexFormat(CVertexBuffer::PositionFlag | CVertexBuffer::TexCoord0Flag | CVertexBuffer::TexCoord1Flag | CVertexBuffer::TexCoord2Flag);
565 else
567 // Else Setup our Vertex Program, and good VBuffers, according to _Type.
569 if(_Type==Far0)
571 // Build the Vertex Format.
572 _VB.clearValueEx();
573 _VB.addValueEx(NL3D_LANDSCAPE_VPPOS_STARTPOS, CVertexBuffer::Float3); // v[0]= StartPos.
574 _VB.addValueEx(NL3D_LANDSCAPE_VPPOS_TEX0, CVertexBuffer::Float2); // v[8]= Tex0.
575 _VB.addValueEx(NL3D_LANDSCAPE_VPPOS_TEX1, CVertexBuffer::Float2); // v[9]= Tex1.
576 _VB.addValueEx(NL3D_LANDSCAPE_VPPOS_GEOMINFO, CVertexBuffer::Float2); // v[10]= GeomInfos.
577 _VB.addValueEx(NL3D_LANDSCAPE_VPPOS_DELTAPOS, CVertexBuffer::Float3); // v[11]= EndPos-StartPos.
578 _VB.initEx();
580 // Init the Vertex Program.
581 _VertexProgram[0] = new CVertexProgramLandscape(Far0);
582 nlverify(_Driver->compileVertexProgram(_VertexProgram[0]));
584 else if(_Type==Far1)
586 // Build the Vertex Format.
587 _VB.clearValueEx();
588 _VB.addValueEx(NL3D_LANDSCAPE_VPPOS_STARTPOS, CVertexBuffer::Float3); // v[0]= StartPos.
589 _VB.addValueEx(NL3D_LANDSCAPE_VPPOS_TEX0, CVertexBuffer::Float2); // v[8]= Tex0.
590 _VB.addValueEx(NL3D_LANDSCAPE_VPPOS_TEX1, CVertexBuffer::Float2); // v[9]= Tex1.
591 _VB.addValueEx(NL3D_LANDSCAPE_VPPOS_GEOMINFO, CVertexBuffer::Float2); // v[10]= GeomInfos.
592 _VB.addValueEx(NL3D_LANDSCAPE_VPPOS_DELTAPOS, CVertexBuffer::Float3); // v[11]= EndPos-StartPos.
593 _VB.addValueEx(NL3D_LANDSCAPE_VPPOS_ALPHAINFO, CVertexBuffer::Float2); // v[12]= AlphaInfos.
594 _VB.initEx();
596 // Init the Vertex Program.
597 _VertexProgram[0] = new CVertexProgramLandscape(Far1);
598 nlverify(_Driver->compileVertexProgram(_VertexProgram[0]));
600 else
602 // Build the Vertex Format.
603 _VB.clearValueEx();
604 _VB.addValueEx(NL3D_LANDSCAPE_VPPOS_STARTPOS, CVertexBuffer::Float3); // v[0]= StartPos.
605 _VB.addValueEx(NL3D_LANDSCAPE_VPPOS_TEX0, CVertexBuffer::Float2); // v[8]= Tex0.
606 _VB.addValueEx(NL3D_LANDSCAPE_VPPOS_TEX1, CVertexBuffer::Float2); // v[9]= Tex1.
607 _VB.addValueEx(NL3D_LANDSCAPE_VPPOS_TEX2, CVertexBuffer::Float2); // v[12]= Tex2.
608 _VB.addValueEx(NL3D_LANDSCAPE_VPPOS_GEOMINFO, CVertexBuffer::Float2); // v[10]= GeomInfos.
609 _VB.addValueEx(NL3D_LANDSCAPE_VPPOS_DELTAPOS, CVertexBuffer::Float3); // v[11]= EndPos-StartPos.
610 _VB.initEx();
612 // Init the Vertex Program.
613 _VertexProgram[0] = new CVertexProgramLandscape(Tile, false);
614 nlverify(_Driver->compileVertexProgram(_VertexProgram[0]));
616 // Init the Vertex Program for lightmap pass
617 _VertexProgram[1] = new CVertexProgramLandscape(Tile, true);
618 nlverify(_Driver->compileVertexProgram(_VertexProgram[1]));
624 CVertexProgramLandscape::CVertexProgramLandscape(CLandscapeVBAllocator::TType type, bool lightMap)
626 // nelvp
628 CSource *source = new CSource();
629 source->Profile = nelvp;
630 source->DisplayName = "Landscape/nelvp";
631 switch (type)
633 case CLandscapeVBAllocator::Far0:
634 source->DisplayName += "/far0";
635 source->setSource(std::string(NL3D_LandscapeCommonStartProgram)
636 + std::string(NL3D_LandscapeFar0EndProgram));
637 break;
638 case CLandscapeVBAllocator::Far1:
639 source->DisplayName += "/far1";
640 source->setSource(std::string(NL3D_LandscapeCommonStartProgram)
641 + std::string(NL3D_LandscapeFar1EndProgram));
642 break;
643 case CLandscapeVBAllocator::Tile:
644 source->DisplayName += "/tile";
645 if (lightMap)
647 source->DisplayName += "/lightmap";
648 source->setSource(std::string(NL3D_LandscapeCommonStartProgram)
649 + std::string(NL3D_LandscapeTileLightMapEndProgram));
651 else
653 source->setSource(std::string(NL3D_LandscapeCommonStartProgram)
654 + std::string(NL3D_LandscapeTileEndProgram));
656 break;
658 source->ParamIndices["modelViewProjection"] = 0;
659 source->ParamIndices["programConstants0"] = 4;
660 source->ParamIndices["refineCenter"] = 5;
661 source->ParamIndices["tileDist"] = 6;
662 source->ParamIndices["fog"] = 10;
663 source->ParamIndices["pzbModelPosition"] = 12;
664 addSource(source);
666 // TODO_VP_GLSL
668 // ....
672 void CVertexProgramLandscape::buildInfo()
674 m_Idx.ProgramConstants0 = getUniformIndex("programConstants0");
675 nlassert(m_Idx.ProgramConstants0 != std::numeric_limits<uint>::max());
676 m_Idx.RefineCenter = getUniformIndex("refineCenter");
677 nlassert(m_Idx.RefineCenter != std::numeric_limits<uint>::max());
678 m_Idx.TileDist = getUniformIndex("tileDist");
679 nlassert(m_Idx.TileDist != std::numeric_limits<uint>::max());
680 m_Idx.PZBModelPosition = getUniformIndex("pzbModelPosition");
681 nlassert(m_Idx.PZBModelPosition != std::numeric_limits<uint>::max());
684 } // NL3D