Page 1 of 1

Using many entities

Posted: Mon Mar 21, 2005 6:21 pm
by Ephon
I'm trying to make a 3d tetris where there is a cubic volume that represents the area with the blocks. So the question is: How should I manage all the blocks, as it can potentially have 10*10*16=1600 blocks, which is alot I think. Tried this code where the outcome was that is runned very slow! The thought was to preallocate the block entities, position them in the cube and just enable/disable the visibility flag when needed.

Code: Select all

				Ogre::Entity *pBlock = mSceneMgr->createEntity(
					"block" + positionToString(col, row, layer), "block.mesh");
				Ogre::SceneNode *pBlockNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
				pBlockNode->attachObject(pBlock);
Any suggestions?

Posted: Mon Mar 21, 2005 8:15 pm
by DWORD
Batching is the keyword here. This is not as straightforward as using a lot of entities, but you get really effective rendering in return. I would suggest you subclass SimpleRenderable, and use one or more instances of the derived class.

For example you could let your derived class setup a vertex declaration with positions, normals, and vertex colours. The buffer should be large enough to hold the maximum number of vertices you will need (probably 10x10x16x8 = 12800). Then when the level changes you have to update the vertices in the buffer, and the index buffer pointing into the vertex buffer.

If you want to use materials and not just vertex colours. Instead you could use as many instances of your SimpleRenderable subclass as you have different materials, and then batch together just the faces that share material.

So to get the best performance, you'll have to do some work, but it's worth it. For starters you can check out the part of the manual dealing with hardware buffers. There are also a number of examples on the wiki for subclassing SimpleRenderable (Line3d, DynamicRenderable, both under CodeSnippets) and for creating manual meshes. Hope this will get you started.

BTW, if you get this working you could probably optimize it even more by excluding the faces between adjacent blocks rather easily. Say if you have two blocks sharing one side, you could skip the faces of that side in the index buffer. That would give even better performance.

Posted: Tue Mar 22, 2005 10:47 pm
by Ephon
I was thinking of using a rounded cube as the block, and creating a rounded cube manually seems to be not the best way, I think?

How about loading a roundedcube.mesh and manually creating a mesh with several submeshes, where the submeshes are the roundedcube. Then I can turn on/off the visible flag for each submesh as needed. Can that be done, and is it a good option?

Posted: Tue Mar 22, 2005 11:15 pm
by DWORD
It's of course a lot more polygons and more complicated using a rounded cube. I don't think you'll get much better performance from creating a mesh with more sub meshes, as that is more or less the same as having multiple entities (only one scene node, but just as many render operations). What you need to do to get best rendering performance is to somehow combine everything into as few render operations as possible. This is exactly what the StaticGeometry class does, but I'm not sure how well it performs when rebuilding everytime the level changes. Maybe you can find some middle course?

I think, though, that you can probably get some cheap performance boost by detaching the scene nodes of the unused blocks instead of hiding them. This performs better than using visibility, because there are done no transformations on the detached scene nodes IIRC.

Another rather complicated optimization would be to combine the above with some kind of occlusion culling. What performance are you currently getting; does it drop significantly with more blocks?