NL3D::CMeshBlockManager Class Reference

#include <mesh_block_manager.h>


Detailed Description

A class used to render instances sorted by MeshGeom first, then per material, where possible. This allow optimisation because less renderState swapping are needed. WARNING: if you add MeshGeom to 2 different CMeshBlockManager at same times, it won't work, and will certainly crashes (not checked/assert).

NB VBHeap part works, even if no User interface use it. It don't give greate performance Add, but will may be used.

Author:
Lionel Berenguier

Nevrax France

Date:
2002

Definition at line 56 of file mesh_block_manager.h.

Public Member Functions

void addInstance (IMeshGeom *meshGeom, CMeshBaseInstance *inst, float polygonCount)
 CMeshBlockManager ()
 Constructor.

void flush (IDriver *drv, CScene *scene, CRenderTrav *renderTrav)
 ~CMeshBlockManager ()
VBHeap part.
bool addVBHeap (IDriver *drv, uint vertexFormat, uint maxVertices)
void freeMeshVBHeap (IMeshGeom *mesh)
 Called by ~IMeshGeom().

void releaseVBHeaps ()
 release all Heaps => clear memory of meshs registered.


Private Types

typedef std::map< uint, uintTVBHeapMap
 Heap Map from vertexFormat to VBHeap Id. NB: do not contains 0th.


Private Member Functions

void allocateMeshVBHeap (IMeshGeom *mesh)
 Try to allocate a MeshGeom into a specific Heap.

void render (CVBHeapBlock *hb, IMeshGeom *meshGeom, std::vector< CInstanceInfo > &rdrInstances)

Private Attributes

CMeshGeomRenderContext _RenderCtx
std::vector< CVBHeapBlock * > _VBHeapBlocks
TVBHeapMap _VBHeapMap


Member Typedef Documentation

typedef std::map<uint, uint> NL3D::CMeshBlockManager::TVBHeapMap [private]
 

Heap Map from vertexFormat to VBHeap Id. NB: do not contains 0th.

Definition at line 122 of file mesh_block_manager.h.


Constructor & Destructor Documentation

NL3D::CMeshBlockManager::CMeshBlockManager  ) 
 

Constructor.

Definition at line 44 of file mesh_block_manager.cpp.

References _RenderCtx, _VBHeapBlocks, NL3D::CMeshGeomRenderContext::Driver, NL3D::CMeshGeomRenderContext::RenderTrav, and NL3D::CMeshGeomRenderContext::Scene.

00045 {
00046         _RenderCtx.Driver= NULL;
00047         _RenderCtx.Scene= NULL;
00048         _RenderCtx.RenderTrav= NULL;
00049 
00050         // Allocate at least the 0th heap
00051         _VBHeapBlocks.resize(1);
00052         _VBHeapBlocks[0]= new CVBHeapBlock;
00053         // some reserve, avoiding first reallocation.
00054         _VBHeapBlocks[0]->RdrInstances.reserve(100);
00055         _VBHeapBlocks[0]->RdrMeshGeoms.reserve(100);
00056 }

NL3D::CMeshBlockManager::~CMeshBlockManager  ) 
 

Definition at line 59 of file mesh_block_manager.cpp.

References _VBHeapBlocks, and releaseVBHeaps().

00060 {
00061         // must release any user heap.
00062         releaseVBHeaps();
00063         // Release the 0th one.
00064         delete _VBHeapBlocks[0];
00065         _VBHeapBlocks.clear();
00066 }


Member Function Documentation

void NL3D::CMeshBlockManager::addInstance IMeshGeom meshGeom,
CMeshBaseInstance inst,
float  polygonCount
 

Add an instance of a MeshGeom to render. Only CMeshBaseInstance can be added. For now, only CMeshGeom and CMeshMRMGeom are known to work.

Definition at line 69 of file mesh_block_manager.cpp.

References NL3D::IMeshGeom::_MeshBlockManager, NL3D::IMeshGeom::_MeshVBHeapId, NL3D::IMeshGeom::_RootInstanceId, _VBHeapBlocks, allocateMeshVBHeap(), NL3D::CMeshBlockManager::CInstanceInfo::MBI, NL3D::CMeshBlockManager::CInstanceInfo::MeshGeom, NL3D::CMeshBlockManager::CInstanceInfo::NextInstance, NL3D_MBM_VBHEAP_HEAP_MASK, NL3D::CMeshBlockManager::CInstanceInfo::PolygonCount, NL3D::CMeshBlockManager::CVBHeapBlock::RdrInstances, and NL3D::CMeshBlockManager::CVBHeapBlock::RdrMeshGeoms.

Referenced by NL3D::CTransformShape::traverseRender().

00070 {
00071         // If the meshGeom has never been added to the manager, may do some precalc
00072         if(meshGeom->_MeshBlockManager==NULL)
00073         {
00074                 // Fill 
00075                 meshGeom->_MeshBlockManager= this;
00076                 // try to fit the meshGeom in one of our VBHeap.
00077                 allocateMeshVBHeap(meshGeom);
00078         }
00079 
00080         // TestYoyo
00081         /*extern uint   TEMP_Yoyo_NInstVBHeap;
00082         extern uint     TEMP_Yoyo_NInstNoVBHeap;
00083         if( meshGeom->_MeshVBHeapId & NL3D_MBM_VBHEAP_HEAP_MASK )
00084                 TEMP_Yoyo_NInstVBHeap++; 
00085         else
00086                 TEMP_Yoyo_NInstNoVBHeap++;*/
00087         // End TestYoyo
00088 
00089         // Choose the HeapBlock to fit in.
00090         CVBHeapBlock    *hb= _VBHeapBlocks[meshGeom->_MeshVBHeapId & NL3D_MBM_VBHEAP_HEAP_MASK];
00091 
00092         // If the mesh geom is not added to this manager, add it.
00093         if(meshGeom->_RootInstanceId==-1)
00094         {
00095                 hb->RdrMeshGeoms.push_back(meshGeom);
00096         }
00097 
00098         // setup the instance.
00099         CInstanceInfo           instInfo;
00100         instInfo.MeshGeom= meshGeom;
00101         instInfo.MBI= inst;
00102         instInfo.PolygonCount= polygonCount;
00103 
00104         // link to the head of the list.
00105         instInfo.NextInstance= meshGeom->_RootInstanceId;
00106         meshGeom->_RootInstanceId= hb->RdrInstances.size();
00107 
00108         // add this instance
00109         hb->RdrInstances.push_back(instInfo);
00110 
00111 }

bool NL3D::CMeshBlockManager::addVBHeap IDriver drv,
uint  vertexFormat,
uint  maxVertices
 

Add a Heap for a given vertexFormat. Any meshGeom added with addInstance() which has this vertex Format may fit in this heap. return false and fail if the heap can't be allocated or if the heap with same vertexFormat still exist.

Definition at line 393 of file mesh_block_manager.cpp.

References _VBHeapBlocks, _VBHeapMap, NL3D::CVertexBufferHeap::init(), uint, and NL3D::CMeshBlockManager::CVBHeapBlock::VBHeap.

00394 {
00395         // if find an existing vertexFormat, abort.
00396         TVBHeapMap::iterator    it= _VBHeapMap.find(vertexFormat);
00397         // if found, abort
00398         if( it!=_VBHeapMap.end() )
00399                 return false;
00400 
00401         // create the block
00402         CVBHeapBlock    *hb= new CVBHeapBlock;
00403 
00404         // allocate vertex space
00405         hb->VBHeap.init(drv, vertexFormat, maxVertices);
00406 
00407         // add an entry to the array, and the map.
00408         _VBHeapBlocks.push_back(hb);
00409         _VBHeapMap[vertexFormat]= _VBHeapBlocks.size()-1;
00410 
00411         return true;
00412 }

void NL3D::CMeshBlockManager::allocateMeshVBHeap IMeshGeom mesh  )  [private]
 

Try to allocate a MeshGeom into a specific Heap.

Definition at line 274 of file mesh_block_manager.cpp.

References NL3D::IMeshGeom::_MeshVBHeapId, NL3D::IMeshGeom::_MeshVBHeapIndexStart, NL3D::IMeshGeom::_MeshVBHeapNumVertices, _VBHeapBlocks, _VBHeapMap, NL3D::CVertexBufferHeap::allocate(), NL3D::CMeshBlockManager::CVBHeapBlock::AllocatedMeshGeoms, NL3D::IMeshGeom::computeMeshVBHeap(), NL3D::CMeshBlockManager::CVBHeapBlock::FreeIds, NL3D::IMeshGeom::getVBHeapInfo(), NL3D::CVertexBufferHeap::lock(), NL3D_MBM_VBHEAP_MESH_SHIFT, uint, uint8, NL3D::CVertexBufferHeap::unlock(), and NL3D::CMeshBlockManager::CVBHeapBlock::VBHeap.

Referenced by addInstance().

00275 {
00276         // Get info from mesh. 
00277         uint vertexFormat, numVertices;
00278         // if the mesh do not support VBHeap, quit.
00279         if( !mesh->getVBHeapInfo(vertexFormat, numVertices) )
00280                 return;
00281 
00282         // In case of ...
00283         if( numVertices==0 )
00284                 return;
00285 
00286         // try to find a VBHeap with this vertexFormat.
00287         TVBHeapMap::iterator    it= _VBHeapMap.find(vertexFormat);
00288         // if not found, abort
00289         if(it==_VBHeapMap.end())
00290                 return;
00291 
00292         // access to this VBHeap.
00293         uint    vbHeapId= it->second;
00294         CVBHeapBlock    *vbHeapBlock= _VBHeapBlocks[vbHeapId];
00295         // try to allocate sapce into the heap. Fail=> abort.
00296         uint    indexStart;
00297         if( !vbHeapBlock->VBHeap.allocate(numVertices, indexStart) )
00298                 return;
00299 
00300         // All is Ok here => setup infos.
00301         //==================
00302 
00303         // Keep track of the mesh => allocate.
00304         uint    meshId;
00305         // try to get a free id.
00306         if( !vbHeapBlock->FreeIds.empty() )
00307         {
00308                 meshId= vbHeapBlock->FreeIds.back();
00309                 vbHeapBlock->FreeIds.pop_back();
00310                 vbHeapBlock->AllocatedMeshGeoms[meshId]= mesh;
00311         }
00312         // else, must add to the array
00313         else
00314         {
00315                 meshId= vbHeapBlock->AllocatedMeshGeoms.size();
00316                 vbHeapBlock->AllocatedMeshGeoms.push_back(mesh);
00317         }
00318 
00319         // info for delete in mesh
00320         mesh->_MeshVBHeapIndexStart= indexStart;
00321         mesh->_MeshVBHeapId= vbHeapId + (meshId<<NL3D_MBM_VBHEAP_MESH_SHIFT);
00322         mesh->_MeshVBHeapNumVertices= numVertices;
00323 
00324 
00325         // Fill VB.
00326         //==================
00327         uint8   *dst= vbHeapBlock->VBHeap.lock(indexStart);
00328         mesh->computeMeshVBHeap(dst, indexStart);
00329         // unlock only what vertices have changed (ATI problem)
00330         vbHeapBlock->VBHeap.unlock(indexStart, indexStart+numVertices);
00331 }

void NL3D::CMeshBlockManager::flush IDriver drv,
CScene scene,
CRenderTrav renderTrav
 

Flush the manager and effectively render.

Definition at line 114 of file mesh_block_manager.cpp.

References _RenderCtx, _VBHeapBlocks, NL3D::CVertexBufferHeap::activate(), NL3D::CMeshGeomRenderContext::Driver, H_AUTO, nlassert, NL3D::CMeshBlockManager::CVBHeapBlock::RdrInstances, NL3D::CMeshBlockManager::CVBHeapBlock::RdrMeshGeoms, render(), NL3D::CMeshGeomRenderContext::RenderThroughVBHeap, NL3D::CMeshGeomRenderContext::RenderTrav, NL3D::CMeshGeomRenderContext::Scene, uint, and NL3D::CMeshBlockManager::CVBHeapBlock::VBHeap.

Referenced by NL3D::CRenderTrav::traverse().

00115 {
00116         uint    i,j;
00117 
00118         H_AUTO( NL3D_MeshBlockManager );
00119 
00120         // setup the manager
00121         nlassert(drv && scene && renderTrav);
00122         _RenderCtx.Driver= drv;
00123         _RenderCtx.Scene= scene;
00124         _RenderCtx.RenderTrav= renderTrav;
00125         
00126         // render
00127         //==========
00128 
00129         // sort by Heap first => small setup of VBs.
00130         for(j=0; j<_VBHeapBlocks.size();j++)
00131         {
00132                 CVBHeapBlock    *hb= _VBHeapBlocks[j];
00133                 // if not the special 0th heap, must activate VB.
00134                 if(j==0)
00135                 {
00136                         _RenderCtx.RenderThroughVBHeap= false;
00137                 }
00138                 else
00139                 {
00140                         // set to true => avoid mesh to setup their own VB.
00141                         _RenderCtx.RenderThroughVBHeap= true;
00142                         // activate current VB in driver
00143                         hb->VBHeap.activate();
00144                 }
00145 
00146 
00147                 // Always sort by MeshGeom, in this heap
00148                 for(i=0; i<hb->RdrMeshGeoms.size();i++)
00149                 {
00150                         // render the meshGeom and his instances
00151                         render(hb, hb->RdrMeshGeoms[i], hb->RdrInstances);
00152                 }
00153         }
00154 
00155         // reset.
00156         //==========
00157 
00158         // For all vb heaps
00159         for(j=0; j<_VBHeapBlocks.size();j++)
00160         {
00161                 CVBHeapBlock    *hb= _VBHeapBlocks[j];
00162 
00163                 // Parse all MehsGeoms, and flag them as Not Added to me
00164                 for(i=0; i<hb->RdrMeshGeoms.size();i++)
00165                 {
00166                         hb->RdrMeshGeoms[i]->_RootInstanceId= -1;
00167                 }
00168 
00169                 // clear rdr arrays
00170                 hb->RdrInstances.clear();
00171                 hb->RdrMeshGeoms.clear();
00172         }
00173 }

void NL3D::CMeshBlockManager::freeMeshVBHeap IMeshGeom mesh  ) 
 

Called by ~IMeshGeom().

Definition at line 334 of file mesh_block_manager.cpp.

References NL3D::IMeshGeom::_MeshVBHeapId, NL3D::IMeshGeom::_MeshVBHeapIndexStart, _VBHeapBlocks, NL3D::CMeshBlockManager::CVBHeapBlock::AllocatedMeshGeoms, NL3D::CVertexBufferHeap::free(), NL3D::CMeshBlockManager::CVBHeapBlock::FreeIds, NL3D_MBM_VBHEAP_HEAP_MASK, NL3D_MBM_VBHEAP_MESH_MASK, NL3D_MBM_VBHEAP_MESH_SHIFT, nlassert, uint, and NL3D::CMeshBlockManager::CVBHeapBlock::VBHeap.

Referenced by releaseVBHeaps(), and NL3D::IMeshGeom::~IMeshGeom().

00335 {
00336         nlassert(mesh->_MeshVBHeapId);
00337 
00338         // unpack heap and mesh id.
00339         uint    vbHeapId= mesh->_MeshVBHeapId & NL3D_MBM_VBHEAP_HEAP_MASK;
00340         uint    meshId= (mesh->_MeshVBHeapId & NL3D_MBM_VBHEAP_MESH_MASK) >> NL3D_MBM_VBHEAP_MESH_SHIFT;
00341 
00342         // access to this VBHeap.
00343         CVBHeapBlock    *vbHeapBlock= _VBHeapBlocks[vbHeapId];
00344 
00345         // free VB memory.
00346         vbHeapBlock->VBHeap.free(mesh->_MeshVBHeapIndexStart);
00347 
00348         // free this space
00349         nlassert(meshId<vbHeapBlock->AllocatedMeshGeoms.size());
00350         vbHeapBlock->AllocatedMeshGeoms[meshId]= NULL;
00351         vbHeapBlock->FreeIds.push_back(meshId);
00352 
00353         // reset mesh info.
00354         mesh->_MeshVBHeapId= 0;
00355         mesh->_MeshVBHeapIndexStart= 0;
00356 }

void NL3D::CMeshBlockManager::releaseVBHeaps  ) 
 

release all Heaps => clear memory of meshs registered.

Definition at line 359 of file mesh_block_manager.cpp.

References _VBHeapBlocks, _VBHeapMap, NL3D::CMeshBlockManager::CVBHeapBlock::AllocatedMeshGeoms, freeMeshVBHeap(), nlassert, and uint.

Referenced by ~CMeshBlockManager().

00360 {
00361         uint    i,j;
00362 
00363         // For all blocks but the 0th
00364         for(j=1; j<_VBHeapBlocks.size();j++)
00365         {
00366                 CVBHeapBlock    *hb= _VBHeapBlocks[j];
00367 
00368                 // For all allocated mesh of this heap.
00369                 for(i=0;i<hb->AllocatedMeshGeoms.size();i++)
00370                 {
00371                         IMeshGeom       *mesh= hb->AllocatedMeshGeoms[i];
00372                         // if the mesh exist.
00373                         if(mesh)
00374                         {
00375                                 // free his VBHeap Data.
00376                                 freeMeshVBHeap(mesh);
00377                                 nlassert( hb->AllocatedMeshGeoms[i] == NULL );
00378                         }
00379                 }
00380 
00381                 // delete the block. NB: VBHeap auto released
00382                 delete hb;
00383         }
00384 
00385         // erase all blocks but 0th
00386         _VBHeapBlocks.resize(1);
00387 
00388         // clear the map.
00389         contReset(_VBHeapMap);
00390 }

void NL3D::CMeshBlockManager::render CVBHeapBlock hb,
IMeshGeom meshGeom,
std::vector< CInstanceInfo > &  rdrInstances
[private]
 

Definition at line 177 of file mesh_block_manager.cpp.

References NL3D::IMeshGeom::_MeshVBHeapIndexStart, NL3D::IMeshGeom::_MeshVBHeapNumVertices, _RenderCtx, NL3D::IMeshGeom::_RootInstanceId, NL3D::IMeshGeom::activeInstance(), NL3D::IMeshGeom::beginMesh(), NL3D::IMeshGeom::endMesh(), NL3D::IMeshGeom::getNumRdrPassesForInstance(), NL3D::IMeshGeom::getNumRdrPassesForMesh(), NL3D::IMeshGeom::isActiveInstanceNeedVBFill(), NL3D::CVertexBufferHeap::lock(), NL3D::CMeshBlockManager::CInstanceInfo::MBI, NL3D::CMeshBlockManager::CInstanceInfo::NextInstance, NL3D::CMeshBlockManager::CInstanceInfo::PolygonCount, NL3D::IMeshGeom::renderPass(), NL3D::CMeshGeomRenderContext::RenderThroughVBHeap, sint32, NL3D::IMeshGeom::sortPerMaterial(), uint, NL3D::CVertexBufferHeap::unlock(), and NL3D::CMeshBlockManager::CVBHeapBlock::VBHeap.

Referenced by flush().

00178 {
00179         // TestYoyo
00180         /*extern uint TEMP_Yoyo_NMeshVBHeap;
00181         extern uint TEMP_Yoyo_NMeshNoVBHeap;
00182         if( _RenderCtx.RenderThroughVBHeap )
00183                 TEMP_Yoyo_NMeshVBHeap++;
00184         else
00185                 TEMP_Yoyo_NMeshNoVBHeap++;*/
00186         // End TestYoyo
00187 
00188         // Start for this mesh.
00189         meshGeom->beginMesh(_RenderCtx);
00190 
00191 
00192         // sort per material first?
00193         if( meshGeom->sortPerMaterial() )
00194         {
00195                 // number of renderPasses for this mesh.
00196                 uint    numRdrPass= meshGeom->getNumRdrPassesForMesh();
00197 
00198                 // for all material.
00199                 for(uint rdrPass=0;rdrPass<numRdrPass;rdrPass++)
00200                 {
00201                         // for all instance.
00202                         sint32  instId= meshGeom->_RootInstanceId;
00203                         while( instId!=-1 )
00204                         {
00205                                 CInstanceInfo           &instInfo= rdrInstances[instId];
00206 
00207                                 // activate this instance
00208                                 meshGeom->activeInstance(_RenderCtx, instInfo.MBI, instInfo.PolygonCount, NULL);
00209 
00210                                 // render the pass.
00211                                 meshGeom->renderPass(_RenderCtx, instInfo.MBI, instInfo.PolygonCount, rdrPass);
00212 
00213                                 // next instance
00214                                 instId= instInfo.NextInstance;
00215                         }
00216                 }
00217         }
00218         // else sort per instance first
00219         else
00220         {
00221                 // for all instance.
00222                 sint32  instId= meshGeom->_RootInstanceId;
00223                 while( instId!=-1 )
00224                 {
00225                         CInstanceInfo           &instInfo= rdrInstances[instId];
00226 
00227                         // If the meshGeom need to change Some VB (geomorphs...)
00228                         bool    needVBHeapLock= _RenderCtx.RenderThroughVBHeap && meshGeom->isActiveInstanceNeedVBFill();
00229                         void    *vbDst= NULL;
00230                         if(needVBHeapLock)
00231                         {
00232                                 // Lock the VBHeap
00233                                 vbDst= vbHeapBlock->VBHeap.lock(meshGeom->_MeshVBHeapIndexStart);
00234                         }
00235 
00236                         // activate this instance
00237                         meshGeom->activeInstance(_RenderCtx, instInfo.MBI, instInfo.PolygonCount, vbDst);
00238 
00239                         if(needVBHeapLock)
00240                         {
00241                                 // unlock only what vertices have changed (ATI problem)
00242                                 vbHeapBlock->VBHeap.unlock(meshGeom->_MeshVBHeapIndexStart, 
00243                                         meshGeom->_MeshVBHeapIndexStart + meshGeom->_MeshVBHeapNumVertices);
00244                         }
00245 
00246                         // number of renderPasses for this mesh.
00247                         uint    numRdrPass= meshGeom->getNumRdrPassesForInstance(instInfo.MBI);
00248 
00249                         // for all material.
00250                         for(uint rdrPass=0;rdrPass<numRdrPass;rdrPass++)
00251                         {
00252                                 // render the pass.
00253                                 meshGeom->renderPass(_RenderCtx, instInfo.MBI, instInfo.PolygonCount, rdrPass);
00254                         }
00255 
00256                         // next instance
00257                         instId= instInfo.NextInstance;
00258                 }
00259         }
00260 
00261         // End for this mesh.
00262         meshGeom->endMesh(_RenderCtx);
00263 }


Field Documentation

CMeshGeomRenderContext NL3D::CMeshBlockManager::_RenderCtx [private]
 

Definition at line 137 of file mesh_block_manager.h.

Referenced by CMeshBlockManager(), flush(), and render().

std::vector<CVBHeapBlock*> NL3D::CMeshBlockManager::_VBHeapBlocks [private]
 

List of Heaps. NB: 0th heap is special: contains all meshs which can't fit in any VBHeap.

Definition at line 128 of file mesh_block_manager.h.

Referenced by addInstance(), addVBHeap(), allocateMeshVBHeap(), CMeshBlockManager(), flush(), freeMeshVBHeap(), releaseVBHeaps(), and ~CMeshBlockManager().

TVBHeapMap NL3D::CMeshBlockManager::_VBHeapMap [private]
 

Definition at line 123 of file mesh_block_manager.h.

Referenced by addVBHeap(), allocateMeshVBHeap(), and releaseVBHeaps().


The documentation for this class was generated from the following files:
Generated on Tue Mar 16 06:51:48 2004 for NeL by doxygen 1.3.6