Jump to content
  • Advertisement
Sign in to follow this  
MikeyO

Drawing a Mesh as a triangle list

This topic is 4779 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I've run into a bit of trouble with my little terrain engine.. As I see it, I've got two options: A) To figure out a way to calculate the normals manually and not use Mesh at all, then just draw it like that or B) To create a new mesh with my Index and Vertex buffers, have it calculate the normals (if possible), and then draw with Mesh. But I ran into problems, for A, I dont know how to calculate the normals manually, and for B, it's drawing the terrain as a trianglestrip which the index buffer is not set up for, so it looks like a big ugly mess. I tried to just use the Mesh's index and vertex buffer to draw using DrawIndexedPrimitives(), but all I get is a blank screen when I do that. Does anybody have any ideas on how I could remedy this problem, or any links that might tell me how I can set up my terrain IB as a triangle strip instead of a list? Image Edited by Coder: Please don't inline large images (100 Kb+) [Edited by - Coder on April 26, 2005 3:08:08 PM]

Share this post


Link to post
Share on other sites
Advertisement
Here is the code for calculating the vertices and indices I have now:


CustomVertex.PositionNormalTextured[] vertices = new CustomVertex.PositionNormalTextured[width*height];
//Create vertices
for(int w = 0; w < width; w++)
{
for(int h = 0; h < height; h++)
{
Color pix = heightMap.GetPixel(w, h);
vertices[w+h*width].Position = new Vector3((w*vertDist)-(scale/2),
pix.ToArgb() * verticalScale,
(h*vertDist)-(scale/2));
vertices[w+h*width].Normal = new Vector3(0,1,0);
vertices[w+h*width].Tu = w/((float)width);
vertices[w+h*width].Tv = h/((float)height);
}
}

//Create indices
int[] indices = new int[(width-1)*(height-1)*6];
for (int x=0;x<width-1;x++) //List
{
for (int y=0; y<height-1;y++)
{
indices[(x+y*(width-1))*6] = (x+1)+(y+1)*width;
indices[(x+y*(width-1))*6+1] = (x+1)+y*width;
indices[(x+y*(width-1))*6+2] = x+y*width;

indices[(x+y*(width-1))*6+3] = (x+1)+(y+1)*width;
indices[(x+y*(width-1))*6+4] = x+y*width;
indices[(x+y*(width-1))*6+5] = x+(y+1)*width;
}
}

Share this post


Link to post
Share on other sites
Calculating the normal to a triangle is pretty easy. The normal to a triangle is just the cross product of two of its edges. So if a triangle has vertices v0, v1, and v2, then pseudocode to compute the triangle normal would look like this:

Vector3 e1 = v1-v0;
Vector3 e2 = v2-v0;
Vector3 normal = normalize(cross(e1,e2));

This is the normal you store at each vertex of the triangle.

If you want to compute smoother normals, then you need to take into account the normals of all triangles sharing a particular vertex. Pseudocode for that would look like this:

for( each vertex in terrain )
{
Vector3 avgNormal = (0,0,0);
for( each triangle sharing this vertex )
{
Vector3 e1 = v1-v0;
Vector3 e2 = v2-v0;
Vector3 normal = cross(e1,e2);
avgNormal += normal;
}
vertex.normal = normalize(avgNormal);
}

Hope this helps,
neneboricua

Share this post


Link to post
Share on other sites
Yes thank you very much;)

The algorithm works well, and it looks much better.. It's not very efficient, I couldn't figure out a good way to do the inner loop in your 2nd example.

Share this post


Link to post
Share on other sites
Quote:
Original post by MikeyO
The algorithm works well, and it looks much better.. It's not very efficient, I couldn't figure out a good way to do the inner loop in your 2nd example.

Do you mean that you were able to implement the second example and it looks good but that you couldn't figure out a more optimal way of doing it, or that you're not sure how to implement the second loop at all?

If you're not sure how to implement the second loop, the key is that you need to have some kind of adjacency information. This information can be either generated by you during mesh creation or you can use one of the methods of the D3DXMesh interface do it. I don't think you're using that interface so it might be a little easier for you to generate the adjacency yourself. On the other hand, you could just get by for now with using the face normal of the triangle for each of its vertices and not worry at all about using the "smoother normals" example from my previous post.

neneboricua

Share this post


Link to post
Share on other sites
Right now I just kind of.. go through each face for each vertice, if it is referenced by as one of the indices of the face then I add it to the average normal.

Obviously that is an extremely wasteful process that could be solved by simple math, but I can't be arsed right now, not when the loading time for the whole application is about 5 seconds anyway, and the terrain looks good with 4096 vertices.

Thank you very much for your help.

Here is a picture, runs at about 1000fps on my geforce 6800, with 7938 polygons, using repeating normal map & texture.
Image

I'm fairly pleased with the results, as I just started working on the terrain yesterday:D

Edited by Coder: Please don't inline large images

[Edited by - Coder on April 26, 2005 3:55:41 PM]

Share this post


Link to post
Share on other sites
Ok. That is something you can optimize later. I would say just continue adding the features you need to your application and then worry about optimizing them. If later on your profiling tells you that the application is spending too much time computing the normals for the terrain, then you can go back and try to make it more efficient. Until then, I would say continue on with other things :)

neneboricua

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!