[2.1+] Removing largest LOD level on a large mesh

Discussion area about developing with Ogre2 branches (2.1, 2.2 and beyond)
Post Reply
Posts: 280
Joined: Mon May 09, 2016 8:21 am
x 33

[2.1+] Removing largest LOD level on a large mesh

Post by rujialiu »


We're got some large v2 meshes (60MB~120MB) and want to reduce their sizes with MeshLodGenerator. It crashes in 32-bit version because for a mesh with 2286390 vertices failed to allocate 134217728 bytes of memory.... We're working on a 64-bit version but the real question is... after MeshLodGenerator successfully generated all LOD levels, how to remove the LARGEST (original) LOD level and keep lower levels only?

I know that for "normal" use cases LODs are for reducing unneccesary vertex shader pressure when looking at objects are distant, but with such big meshes, we need to cut down the TOTAL MEMORY (CPU/GPU) first. I know there are mesh simplification softwares, but we already have working v2 meshes and we already have a good MeshLodGenerator, the only missing piece is: how to remove the largest LOD?

User avatar
OGRE Team Member
OGRE Team Member
Posts: 4350
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 883

Re: [2.1+] Removing largest LOD level on a large mesh

Post by dark_sylinc »

I can't remember if the MeshLodGenerator worked via reindexing (only creates new index buffers; all LODs share the original vertex buffer), or if it created new geometry (all LODs are independent).

If the former:
  1. For each LOD create a new vertex buffer that only contains the vertices used by LOD1's index buffer
  2. For each LOD create a new index buffer and reindex the old index buffer
  3. For each LOD create a new VertexArrayObject and replace the old ones in SubMesh::mVao
  4. Destroy the old Vaos and old vertex & index buffers
e.g. step 1 and 2 would be (pseudo code):

Code: Select all

//Find out which indices are in use in LOD1
indexBuffer = downloadTicketIndex->map();
std::set<uint32> usedVertices;
for( i< numIndices )
	usedVertices.insert( indexBuffer[i] );

//Copy vertexBuffer to newVertexBuffer
newVertexBuffer = new vertex[usedVertices.size()];
std::map<uint32, uint32> oldIndexToNewIndex;
uint32 nextVertex = 0;
vertexBuffer = downloadTicketVertex->map();
for( i < oldNumVertices )
	if( usedVertices.find( i ) != usedVertices.end() )
		newVertexBuffer[nextVertex] = vertexBuffer[i];
		oldIndexToNewIndex[i] = nextVertex;

//Copy and remap indexBuffer to newIndexBuffer
newIndexBuffer = new uint16[numIndices];

for( i< numIndices )
	newIndexBuffer[i] = oldIndexToNewIndex[indexBuffer[i]];
If the latter:
  1. Drop the first Vao in SubMesh::mVao[0]. Just delete it (via VaoManager->destroyVertexArrayObject)
  2. Remember to delete the vertex & index buffers that belonged to that Vao too
Basically just manipulate the array in SubMesh::mVao[0] so that SubMesh::mVao[0][0] is popped and leaks are removed (if it's an offline tool that saves to mesh file, you may even get away with leaking the buffers and let the OS cleanup for you).

Post Reply