Dynamic mesh creation

You are an experienced programmer and have a problem with the engine, shaders, or advanced effects? Here you'll get answers.
No questions about C++ programming or topics which are answered in the tutorials!
Post Reply
Slaine
Posts: 120
Joined: Fri May 04, 2007 12:28 pm

Dynamic mesh creation

Post by Slaine »

Hi there, I'm trying to draw a custom terrain mesh which get's it's data froma third party engine, I have got this working but it's running slow when the terrain becomes more detailed, I should study the TerrainSceneNode I know but that is hefty, mine is very much cut down, here is a snip of the code:

Code: Select all

for(u32 x = 0; x < nb_vertices; x++)
{	
	buffer->getVertexBuffer().push_back(video::S3DVertex(l_VertexData[x].m_Position[0],
														l_VertexData	[x].m_Position[1],
														l_VertexData[x].m_Position[2],
														(float)l_VertexData[x].m_Normal[0],
														(float)l_VertexData[x].m_Normal[1],
														(float)l_VertexData[x].m_Normal[2], 
														video::SColor(255,0,255,255), 0, 1));
}

buffer->getIndexBuffer().set_used(0);
for(u32 y = 0; y < nb_vertices; y+=3)
{

	buffer->getIndexBuffer().push_back(l_TriangleData[y].m_VertexIndices[0]);
	buffer->getIndexBuffer().push_back(l_TriangleData[y].m_VertexIndices[1]);
	buffer->getIndexBuffer().push_back(l_TriangleData[y].m_VertexIndices[2]);

}

buffer->getIndexBuffer().set_used(3*nb_vertices/2);

buffer->setDirty();

driver->drawMeshBuffer(buffer);
And after it has been drawn I'm using this to clear the array ready for the next pass.

Code: Select all

driver->endScene();

buffer->getVertexBuffer().set_used(0);
buffer->getIndexBuffer().set_used(0);
But like I said, it draws fine but when the terrain gets to about 15,000 vertexes it chugs to about 9 frames per second, wheras the SDL example that came with the engine runs at about 40fps.

I'm just curious to why? Is there a better way of creating and deleting vertexes every frame?

Many thanks.
slavik262
Posts: 753
Joined: Sun Nov 22, 2009 9:25 pm
Location: Wisconsin, USA

Post by slavik262 »

Unless I'm interpreting this wrong, you're re-creating the mesh every single frame. That would be a big slow-down. Once you've created your vertex and index buffers, you can reuse them each frame.
Slaine
Posts: 120
Joined: Fri May 04, 2007 12:28 pm

Post by Slaine »

slavik262 wrote:Unless I'm interpreting this wrong, you're re-creating the mesh every single frame. That would be a big slow-down. Once you've created your vertex and index buffers, you can reuse them each frame.
But the mesh I'm getting the data from is dynamically changing every frame, as in the vertex count, the triangle count and Index count? Have you any suggestions, I would very much appreciate it as I was hoping someone was going to say this :)
slavik262
Posts: 753
Joined: Sun Nov 22, 2009 9:25 pm
Location: Wisconsin, USA

Post by slavik262 »

Is it completely dynamic or does it have a few known configurations? What specifically are you using this for?
Slaine
Posts: 120
Joined: Fri May 04, 2007 12:28 pm

Post by Slaine »

slavik262 wrote:Is it completely dynamic or does it have a few known configurations? What specifically are you using this for?
It's a terrain engine geared around planetry scale environments, so at say 10000 miles into orbit the planet is only 200 polys, but as you move closer it adds detail to the terrain, so mountains begin to form etc. You can set a max vertex count and it'll keep it within that amount, so yeah I guess it's completely dynamic.

This is the main function which runs within the main loop.

Code: Select all

//	Create a new planet mesh (if enabled)
		if (g_Triangulate == true)
		{
			g_TriangleCount = l_Planet.Triangulate(cameraPosition
												,  &l_VertexData[0]
												,  &l_TriangleData[0]
													);
		}
slavik262
Posts: 753
Joined: Sun Nov 22, 2009 9:25 pm
Location: Wisconsin, USA

Post by slavik262 »

Ah. This is known as LOD (level of detail, where things grow more detailed as you approach them). I'm not an expert here. I'd recommend checking out the terrain scene node does LOD.
Slaine
Posts: 120
Joined: Fri May 04, 2007 12:28 pm

Post by Slaine »

Yes the terrain engine I am using has a LOD system, probably Chunked LOD.

The engine supplies you with the following data:
s_VertexData Which has
position[3]
normals[3]
Text_coords[2]

and

s_TriangleData Which has
vertex_Indices[3]

The example they supply you with passes this data to OpenGL like so:

Code: Select all

// Init buffer data pointers
			glTexCoordPointer(2, GL_DOUBLE, sizeof(tov::planet::s_VertexData), l_VertexData[0].m_TexCoords);
			glNormalPointer(	 GL_DOUBLE, sizeof(tov::planet::s_VertexData), l_VertexData[0].m_Normal);
			glVertexPointer(3,	 GL_DOUBLE, sizeof(tov::planet::s_VertexData), l_VertexData[0].m_Position);

			// Send triangles to OpenGL
			glColor4f(1, 1, 1, 1);
			glBindTexture(GL_TEXTURE_2D, m_TextureObject);
			glDrawElements(GL_TRIANGLES, (GLsizei)(3*m_TriangleRenderCount), GL_UNSIGNED_INT, (GLvoid*)l_TriangleData[0].m_VertexIndices);
This code is on Render() every frame.

Do you think this needs moving to Advanced?
slavik262
Posts: 753
Joined: Sun Nov 22, 2009 9:25 pm
Location: Wisconsin, USA

Post by slavik262 »

If it should be moved to Advanced, an admin will do it for you. Don't worry about that.

A way you could enhance performance is to just pick a set of LOD levels you want to use (generate the mesh at a few distances) and then store those. Then when you reach those distances (as you get closer or farther from the planet), you just switch visible meshes. The disadvantage obviously is you only get a certain number of set LOD levels, but the advantage is that you won't be doing terrain generation in real time, which will give you a massive performance boost.
Frank Dodd
Posts: 208
Joined: Sun Apr 02, 2006 9:20 pm

Post by Frank Dodd »

Do you mind me asking what library are you using for this?

As I'm sure you know most planetary rendering engines utilise some method of reducing the number of vertices they are using and changing each frame.

Often the surface is divided into a number of patches and as you move closer to or further away from a patch the resolution is changed most patches will not be updated on each frame greatly reducing the number of vertices that are updated.

The TerrainSceneNode is a manager for these types of patches although I am sceptical about its use to manage large numbers of them with a wide range of levels of detail.

My IrrlichtWrapper contains a very simple terrain sphere node which applies a spherical distortion to the terrain node and then allows 6 of them to be patched together to form a sphere. It might be useful in a game like Spore but its low resolution, slow and simply not the best way to do it I think. I have been considering replacing it myself with a more flexible (and straightforward) patch object that can subdivide to create, join to delete and generally manage child copies of itself.

Its a very interesting subject and when you see things like the following link its impossible not to be amazed by what is possible. I'm sure Irrlicht can eat this up it just needs the right node to come along :D

http://www.youtube.com/watch?v=0Dn76lJ082I
Acki
Posts: 3496
Joined: Tue Jun 29, 2004 12:04 am
Location: Nobody's Place (Venlo NL)
Contact:

Post by Acki »

maybe try to avoid the push_back calls !!! ;)
you can set the size, like you already did, with set_used() and then access each element like this: buffer[x] = vertex
while(!asleep) sheep++;
IrrExtensions:Image
http://abusoft.g0dsoft.com
try Stendhal a MORPG written in Java
Slaine
Posts: 120
Joined: Fri May 04, 2007 12:28 pm

Post by Slaine »

Not at all, it's called ovPlanet
http://www.organicvectory.com/index.php ... icle&id=50
I've given a link to a part of the webpage with an interested section on what it does, it is pretty impressive, not only does this library sub-divide the land as you move around, it focuses more vertex detail on areas of more interest, like mountainous areas, and simpler areas like flat lands it draws at a lower detail.

I will try a different method than push_back, I had a feeling it might of been this doing it, but I think that was wishful thinking on my behalf.

There must be a logical solution because the OpenGL example I posted above is used in the Irrlicht API?
Slaine
Posts: 120
Joined: Fri May 04, 2007 12:28 pm

Post by Slaine »

Oh and yes Infinity is very impressive, and from what I've read about ovPlanet it's a prime candidate to equal thier engine. It also allows you to easily integrate libnoise which can generate very impressive landscapes.

Plus it can handle chunk streaming, I haven't got around to that stage of testing yet but it sounds impressive.
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

Yeah, avoiding the set_used(0) and instead calling the correct number before accessing the values should speed up this thing a lot. Also make sure you create your meshbuffer with EHM_DYNAMIC for the hardware mapping hints.
Oh, and do you think that your index interpretation is correct? Sounds to me as if you should copy the indices directly into the Irrlicht index array. You are tripling those value and rendering wrong things and too many in turn.
Slaine
Posts: 120
Joined: Fri May 04, 2007 12:28 pm

Post by Slaine »

It doesn't seem to be the indexing which is slowing everything down, it's the adding of vertexes every frame which is doing it, but I don't know of another way of doing it, I've even tried this:

Code: Select all

		for(u32 x = 0; x < nb_vertices; x++)
		{			

			buffer->getVertexBuffer()[x].Pos.set(l_VertexData[x].m_Position[0],
												 l_VertexData[x].m_Position[1],
												 l_VertexData[x].m_Position[2]);

			buffer->getVertexBuffer()[x].Normal.set(l_VertexData[x].m_Normal[0],
													l_VertexData[x].m_Normal[1],
													l_VertexData[x].m_Normal[2]);
      }

The main problem at hand is the fact that the libraries vertex data is changing on every frame depending on camera position, so as far as I can tell I have to add and remove vertexes on every frame using Irrlicht?
Frank Dodd
Posts: 208
Joined: Sun Apr 02, 2006 9:20 pm

Post by Frank Dodd »

I'm very surprised that it would be returned like that surely there must be some segmentation. Even if the vertices had been entirely prepared for passing though the appropriate OpenGL calls, some segmentation would be required for the support of hardware buffering for example.

What frame rate does your Irrlicht example run at if you only update the vertices supplied from ovPlanet, just the once?
Post Reply