D3D Specific terrain
Does anyone know of a good way to render terrain in D3D(IM), given a Height map? My problem is figuring the algorythm to put the vertices in order to make them triangles (i.e. triangle with vertices = 0,0;1,1;2,0) in a simple loop to figure the vertices for the rendering. I know it probably isnt all that hard, but Im really at a loss for thought on this one and I need to figure it out by Friday.
Thanks for any Help
Etnu
Well, I did an isometric tilemap with a heightfield using
D3D IM. I suppose the way of doing it would be similar using
perspective D3D. The way I did it uses a variant D3DTLVERTEX
vertex. I read the heightmap from a BMP, and then connect
the vertices in the rectangle like (0,0)-(1,0)-(0,1)-(1,1)
using the heights from the heightmap (x,y)-(x+1,y)-(x,y+1)-
(x+1,y+1) and then rendering using drawprimitive TRIANGLESTRIP. I use a simple way of getting x and y (just multiply them with some factor to get a isometric layout) and then subtract the height from the y value.
I cant see as to why a specific algorith would be needed, the x and y values are just the respective positions of each vertex as they would be in the heightmap, and the height is z
(in my program, but really to be correct the positions of the vertices in the heightmap would be x and z, and the height would be y)
Doing this in perpective mode using "real 3D" would be easy, just treat the heights as the y value, and z as depth and x would be ,well x. Since I did this using a variant of
D3DTLVERTEX my values are just the screen coords, but if you want to render it letting D3D do the transformations just treat the min as the viewport min, and the same for max.
Shading the heightmap is just as easy as calculating the normals for each of the two triangles in every rectangle. (Or using D3Ds own lighting if youre not supplying your own)
D3D IM. I suppose the way of doing it would be similar using
perspective D3D. The way I did it uses a variant D3DTLVERTEX
vertex. I read the heightmap from a BMP, and then connect
the vertices in the rectangle like (0,0)-(1,0)-(0,1)-(1,1)
using the heights from the heightmap (x,y)-(x+1,y)-(x,y+1)-
(x+1,y+1) and then rendering using drawprimitive TRIANGLESTRIP. I use a simple way of getting x and y (just multiply them with some factor to get a isometric layout) and then subtract the height from the y value.
I cant see as to why a specific algorith would be needed, the x and y values are just the respective positions of each vertex as they would be in the heightmap, and the height is z
(in my program, but really to be correct the positions of the vertices in the heightmap would be x and z, and the height would be y)
Doing this in perpective mode using "real 3D" would be easy, just treat the heights as the y value, and z as depth and x would be ,well x. Since I did this using a variant of
D3DTLVERTEX my values are just the screen coords, but if you want to render it letting D3D do the transformations just treat the min as the viewport min, and the same for max.
Shading the heightmap is just as easy as calculating the normals for each of the two triangles in every rectangle. (Or using D3Ds own lighting if youre not supplying your own)
I am using the Height map just fine, but my problem is that It doesnt show up on screen. My game is basically a FPS. If I move, I determine the current Y value by interpolating between the nearest 4 points(X & Z) to calculate the appropriate height. The problem is that i cant figure out the order to place the vertices in order to draw with a single call to DrawPrimitive(). What I usually get is a garbled mass of triangles that dont look anything like they should, dont intersect, etc. Thanks
Etnu
Etnu
It sounds like you are creating triangles on the fly every time your character moves through the scene.
This is not the way to do it.
You should build a triangle mesh from the height map when the height map is read.
In your call to draw primitive you send in the indices of the triangles vertices that need to be rendered.
MCSE, MCSD, Sun Certified Java Programmer
Pimp Daddy ;)
This is not the way to do it.
You should build a triangle mesh from the height map when the height map is read.
In your call to draw primitive you send in the indices of the triangles vertices that need to be rendered.
MCSE, MCSD, Sun Certified Java Programmer
Pimp Daddy ;)
I am generating the triangles when the height map is loaded, but my problem is determining the order to send the vertices in order to create the terrain. If I do this
for(x= 0; x< MAX_X; x++)
{
for(z = 0; z < MAX_Z; z++)
{
m_TerrVerts[x][z].x = x;
m_TerrVerts[x][z].z = z;
m_TerrVerts[x][z].y = m_HeightMap[x][z];
}
}
my results are whacky. What I need is to know which element of the height map to grab for each vertex in order.
for(x= 0; x< MAX_X; x++)
{
for(z = 0; z < MAX_Z; z++)
{
m_TerrVerts[x][z].x = x;
m_TerrVerts[x][z].z = z;
m_TerrVerts[x][z].y = m_HeightMap[x][z];
}
}
my results are whacky. What I need is to know which element of the height map to grab for each vertex in order.
You''re not creating triangles, (just the vertices) that''s why. Here''s how to do triangles. In your mind, you need to split the heightfield into quads, and then split each quad into two triangles. So:
//triangles created clockwise
int verticeCount=0;
for (zV=0; zVfor (xV=0; xV{
x=xV*QUAD_SIZE;
z=zV*QUAD_SIZE;
//first triangle
vertices[verticeCount++]=D3DVERTEX(D3DVECTOR(x, y[zV][xV], z), etc.
vertices[verticeCount++]=D3DVERTEX(D3DVECTOR(x, y[zV+1][xV], z+QUAD_SIZE), etc.
vertices[verticeCount++]=D3DVERTEX(D3DVECTOR(x+QUAD_SIZE, y[zV][xV+1], z), etc.
//second triangle
vertices[verticeCount++]=D3DVERTEX(D3DVECTOR(x+QUAD_SIZE, y[zV][xV+1], z), etc.
vertices[verticeCount++]=D3DVERTEX(D3DVECTOR(x, y[zV+1][xV], z+QUAD_SIZE), etc.
vertices[verticeCount++]=D3DVERTEX(D3DVECTOR(x+QUAD_SIZE, y[zV+1][xV+1], z+QUAD_SIZE), etc.
}
}
The might be mistakes, but thats the idea.
//triangles created clockwise
int verticeCount=0;
for (zV=0; zVfor (xV=0; xV{
x=xV*QUAD_SIZE;
z=zV*QUAD_SIZE;
//first triangle
vertices[verticeCount++]=D3DVERTEX(D3DVECTOR(x, y[zV][xV], z), etc.
vertices[verticeCount++]=D3DVERTEX(D3DVECTOR(x, y[zV+1][xV], z+QUAD_SIZE), etc.
vertices[verticeCount++]=D3DVERTEX(D3DVECTOR(x+QUAD_SIZE, y[zV][xV+1], z), etc.
//second triangle
vertices[verticeCount++]=D3DVERTEX(D3DVECTOR(x+QUAD_SIZE, y[zV][xV+1], z), etc.
vertices[verticeCount++]=D3DVERTEX(D3DVECTOR(x, y[zV+1][xV], z+QUAD_SIZE), etc.
vertices[verticeCount++]=D3DVERTEX(D3DVECTOR(x+QUAD_SIZE, y[zV+1][xV+1], z+QUAD_SIZE), etc.
}
}
The might be mistakes, but thats the idea.
Palm, thanks again for your help on my texture thread, but I have to disagree with you here. Of the 6 vertices you create in your algorithm, 2 are duplicates, and these are getting projected every frame, right? I think this is a prime example of where one should use DrawIndexedPrimitive.
Etnu, your method of filling your terrVerts array looks good, except that the array needs to be 1-dimensional in order to send it to DrawIndexedPrimitive, i.e. terrVerts[ z * terrWidth + x ].whatever = whatever.
So now you need your index array which will specify which triangles to draw using your vertices.
numIndices = 0;
for(x=0; x < terrWidth - 1; x++ ){ // no tri's for last column
for(z=0; z < terrDepth - 1; z++ ){ // or last row
terrIndices[ numIndices ] = z * terrWidth + x;
terrIndices[ numIndices + 1 ] = ( z + 1 ) * terrWidth + x;
terrIndices[ numIndices + 2 ] = z * terrWidth + x + 1;
numIndice += 3;
terrIndices[ numIndices ] = z * terrWidth + x + 1;
terrIndices[ numIndices + 1 ] = ( z + 1 ) * terrWidth + x;
terrIndices[ numIndices + 2 ] = ( z + 1 ) * terrWidth + x + 1;
numIndice += 3;
}
}
Edited by - Eric on May 13, 2000 4:43:34 AM
Etnu, your method of filling your terrVerts array looks good, except that the array needs to be 1-dimensional in order to send it to DrawIndexedPrimitive, i.e. terrVerts[ z * terrWidth + x ].whatever = whatever.
So now you need your index array which will specify which triangles to draw using your vertices.
numIndices = 0;
for(x=0; x < terrWidth - 1; x++ ){ // no tri's for last column
for(z=0; z < terrDepth - 1; z++ ){ // or last row
terrIndices[ numIndices ] = z * terrWidth + x;
terrIndices[ numIndices + 1 ] = ( z + 1 ) * terrWidth + x;
terrIndices[ numIndices + 2 ] = z * terrWidth + x + 1;
numIndice += 3;
terrIndices[ numIndices ] = z * terrWidth + x + 1;
terrIndices[ numIndices + 1 ] = ( z + 1 ) * terrWidth + x;
terrIndices[ numIndices + 2 ] = ( z + 1 ) * terrWidth + x + 1;
numIndice += 3;
}
}
Edited by - Eric on May 13, 2000 4:43:34 AM
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement