Sign in to follow this  
Calin

Terrain engine with DirectX.

Recommended Posts

I am trying to make a terrain engine. I want to use the DrawIndexedPrimitive function. The problem is that I can`t figure out how do you pass the arguments in the above function. The terrain mesh is a 128x128 grid, each cell grid is made out of two triangles. Can anyone tell me the correct way to pass the arguments? I tryed this: pDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0,0, 98304, 0, 32768); and this: pDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0,0, ,16384, 32768); but in both situations I recive errors during runtime.

Share this post


Link to post
Share on other sites
What errors are you getting?

Check here first: DrawIndexedPrimitive

Here is the parameter list:
HRESULT DrawIndexedPrimitive( D3DPRIMITIVETYPE Type, INT BaseVertexIndex, UINT MinIndex, UINT NumVertices, UINT StartIndex, UINT PrimitiveCount );

You passed in the correct type and base vertex and index (I'm assuming). It should be pretty straightforward to determine the vertex count and primitive count.

The primitive count should be something like (width * height * 2).

The vertext count for a trianglelist should be (3 * primitive count) since each primitive consists of three verticies. However, you are using an index buffer so chances are that you are not duplicating verts (which would be bad). So the count probably is more like ((width + 1) * (height + 1)).

So a 3x3 grid would look like this:

+-+-+-+
|/|/|/|
+-+-+-+
|/|/|/|
+-+-+-+
|/|/|/|
+-+-+-+

Each '+' should be a vertex -- a total of (3 + 1) * (3 + 1) = 16. Count each triangle and you'll see 18 = (3 * 3 * 2). You just need to make sure your index buffer is set up correctly.

I would caution you against putting magic numbers in your code like you are doing here. Not only is it not readable at all, it doesn't allow you to easily change your grid size.

Share this post


Link to post
Share on other sites
I just changed the parameters value and I still recive a ingame error.
Here is the function:
pDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0,0, 129*129, 0, 128*128*2)
and here are the errors:

The following error occurred on line 245 of c:\documents and settings\calin\my documents\5sg_engine\alphabuild12b(firstpersonlook)\alphabuild\primitives1vb\terrainengine.cpp
D3DERR_INVALIDCALL
Extra information: Failed to draw primitives
Direct3D9: (ERROR) :Stream 0 does not have required number of vertices

First-chance exception at 0x7c81eb33 (kernel32.dll) in Primitives.exe: Microsoft C++ exception: long at memory location 0x0012f6d0..
Direct3D9: (ERROR) :DrawIndexedPrimitive failed.

Share this post


Link to post
Share on other sites
Hi there, can any one explain how to match up the bitmap pixels with the vertices? I mean the pixels would be covering more than one vertex, actually up to six, I think (if using triangle lists), for any vertices that aren't on the sides of the terrain?

thanks.

Share this post


Link to post
Share on other sites
Are these the same errors you were recieving before?

At any rate, it will completely depend on how you have set up your vertex and index buffers. Are you using a height map to build the verts? If so, you will want to modify my above post slightly. Instead of adding 1 to the width and height, the vert count will be (width * height). Each value in the heightmap will now be a separate vertex. The best way to set up your vertex buffer would be to fill it with a vertex for each '+' in the picture above. So basically just iterate through your heightmap (or wherever you are getting your terrain data from) like so:


for( int row = 0; row < height; row++ )
{
for( int col = 0; col < width; col++ )
{
// set vertex x,y,z, and u,v, and normals x,y,z
}
}


This way there is only one unique vertex for each part of the grid. Your new vertex count is 128 * 128 = 16384. Your primitive count will also slightly change to ((width - 1) * (width - 1) * 2 = 127 * 127 * 2 = 32258.

Setting up your index list is tricker though. Now you'll need to modify the code I gave above a little bit to add the appropriate indicies or do it after you set up the verts. You'll need to have three indices per triangle and they'll have to wind in the correct direction.

Share this post


Link to post
Share on other sites
Quote:
Original post by Stevieboy
Hi there, can any one explain how to match up the bitmap pixels with the vertices? I mean the pixels would be covering more than one vertex, actually up to six, I think (if using triangle lists), for any vertices that aren't on the sides of the terrain?

thanks.


Look at my post above. Create a vertex for each pixel in your heightmap bmp. You'll have to set up your index buffer to use the appropriate vertex.


Each vertex is now numbered

0-1-2
|/|/|
3-4-5
|/|/|
6-7-8

Given the picture above, your vertex buffer should look like so:
012345678
Depending on the winding order, your index buffer should look something like:
013 143 124 254 346 476 457 587 (I added a space between each primitive)

Now let's count them up. Num Verts: width * height = 3 x 3 = 9. Num Primitives: (width - 1) * (height - 1) * 2 = 2 * 2 * 2 = 8.


edit: BTW, Once you get this working, I would suggest using triangle strips instead of lists. I may be wrong, but I think those are more efficient. Of course, they are also trickier to set up.

Share this post


Link to post
Share on other sites
Thanks for the reply.

The way I was doing it there were a lot more vertices, three for each triangle, so in your 3*3 grid I would have 18 (triangles) * 3 (vertices) = 52 vertices. I know this is wasteful, but I wasn't sure how you could get the same vertex to represent a triangle in one row, and also a triangle in the row below it.

oh yeah, triangle strips would probably be better for a terrain.

Share this post


Link to post
Share on other sites
Quote:

This way there is only one unique vertex for each part of the grid. Your new vertex count is 128 * 128 = 16384. Your primitive count will also slightly change to ((width - 1) * (width - 1) * 2 = 127 * 127 * 2 = 32258.


This one is working.
Thank you for helping solve this problem. I have been trying to figure out a solution for two days.


Stevieboy: I found a nice terrain tutorial on the 32 bits site not long ago. It is a DX8 tutorial but it still might help your problem.

http://www.32bits.co.uk/

[Edited by - Calin on August 30, 2005 3:43:53 PM]

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this