Archived

This topic is now archived and is closed to further replies.

SikCiv

Simple terrain implementation in DX8

Recommended Posts

I am using D3DXSprite to blit 2D textures and was wandering if its possible to create a simple textured terrain in the background. 1) Would I need to use an X File to draw the terrain? 2) I''d prefer to generate a terrain at run-time and draw it. Where can I get the code to do this? Ive checked the GameDev tutorials but there is nothing of significance (using D3D8). Thankx in advance

  Downloads:  ZeroOne Realm

Share this post


Link to post
Share on other sites
There is alot of info on creating & rendering terrain
out there on GameDev and on other sites.

The most simple way to do this (and an implementation
I''ve got running) is - DX8 aswell:

Load in an RGB or BW image.
Create a vertex buffer to accomadate all vertices
for the landscape - I use the formula:

numverts = ((width-1)*6) * (height-1)

for a 32x32 image this gives: 5766 vertices.

I do this since I render the landscape as a set of
triangles - 2 triangles per quad , this is done with
a simple call to DrawPrimitive with D3DPT_TRIANGLELIST.

You then scan the image from 0 to height - 1 and on each
iteration go across from 0 to width - 1. For each point
in the landscape you generate 6 vertices, 3 for each triangle
and use the four corner pixels of the quad to generate the
y heights. The x and z can be done from the x & y that you
are scanning across times a scale factor.

To get the height you have a few choices, you can average
across the RGB value, pick one of the 3 colours, or even
pick the maximum - or come up with your own wacky idea of
how to generate the height. You could also use this height
value to colour the terrain aswell.

Once you''ve generated all the tri''s you can then render them
using the method I said above, single call to DrawPrimitive
with D3DPT_TRIANGLELIST to render the whole landscape.

Okay, this is just a quick & simple brute force approach to
the problem - and I''m using as a starting point to generate
an OctTree based approach for the landscape, but that''s another
discussion and way beyond what you want.

If you want to chat more or need explantions - don''t hesitate
to email.


MrF.
--
Code..reboot..code..reboot..sigh!

Share this post


Link to post
Share on other sites
I will include my simple (if ugly) terrain loader for direct x below. It loads from a .RAW file made in photoshop, which is just an array containing one byte per pixel. The x,y values of the pixels become the x,z values of the vertices, and the grayscale alue of the pixel (0 to 255) becomes the y value of the vertex. An index buffer is then created (yeah, you can use triangle strips, but i chose a triangle list instead).


//Read Hieght Field
BYTE * pbHieghtField = new BYTE [ MAP_SIZE * MAP_SIZE ];
ifstream file;
file.open ("map.raw", ios::binary );
file.read ( (char *)pbHieghtField, MAP_SIZE * MAP_SIZE );
file.close();
int x,y;

for ( y = 0; y < MAP_SIZE; y++ )
for ( x = 0; x < MAP_SIZE; x++ )
{
//read in z values from hieghtmap
m_pvObjectVertices[ x + y * MAP_SIZE].p.x = (FLOAT) x - MAP_SIZE / 2;
m_pvObjectVertices[ x + y * MAP_SIZE].p.y = (FLOAT) pbHieghtField[x + y * MAP_SIZE]/8;
m_pvObjectVertices[ x + y * MAP_SIZE].p.z = (FLOAT) y - MAP_SIZE / 2;
m_pvObjectVertices[ x + y * MAP_SIZE].tu = (FLOAT) (x%32)/30.9;
m_pvObjectVertices[ x + y * MAP_SIZE].tv = (FLOAT) (y%32)/30.9;

m_pvWaterVertices[ x + y * MAP_SIZE].p.x = (FLOAT) (x - MAP_SIZE / 2)*4;
m_pvWaterVertices[ x + y * MAP_SIZE].p.y = 24;
m_pvWaterVertices[ x + y * MAP_SIZE].p.z = (FLOAT) (y - MAP_SIZE / 2)*4;
m_pvWaterVertices[ x + y * MAP_SIZE].tu = (FLOAT) (x%4)/3;
m_pvWaterVertices[ x + y * MAP_SIZE].tv = (FLOAT) (y%4)/3;


}

delete pbHieghtField;
pbHieghtField = NULL;

//Load index buffers
for ( y = 0; y < MAP_SIZE-1; y++ )
for ( x = 0; x < MAP_SIZE-1; x++ )
{

//Set left triangle indices in counter clockwise order, bottom left, top right, top left
m_pwObjectIndices[ ( (x * 2) + y * (MAP_SIZE - 1) * 2) * 3] = x + (y+1) * (MAP_SIZE);
m_pwObjectIndices[ ( (x * 2) + y * (MAP_SIZE - 1) * 2) * 3 + 1] = x + y * (MAP_SIZE) + 1;
m_pwObjectIndices[ ( (x * 2) + y * (MAP_SIZE - 1) * 2) * 3 + 2] = x + y * (MAP_SIZE);
//Set right triangle indices in counter clockwise order, bottom left, bottom right, top right
m_pwObjectIndices[ ( (x * 2) + y * (MAP_SIZE - 1) * 2) * 3 + 3] = x + (y+1) * (MAP_SIZE);
m_pwObjectIndices[ ( (x * 2) + y * (MAP_SIZE - 1) * 2) * 3 + 4] = x + (y+1) * (MAP_SIZE) + 1;
m_pwObjectIndices[ ( (x * 2) + y * (MAP_SIZE - 1) * 2) * 3 + 5] = x + y * (MAP_SIZE) + 1;

m_pwWaterIndices[ ( (x * 2) + y * (MAP_SIZE - 1) * 2) * 3] = x + (y+1) * (MAP_SIZE);
m_pwWaterIndices[ ( (x * 2) + y * (MAP_SIZE - 1) * 2) * 3 + 1] = x + y * (MAP_SIZE) + 1;
m_pwWaterIndices[ ( (x * 2) + y * (MAP_SIZE - 1) * 2) * 3 + 2] = x + y * (MAP_SIZE);
//Set right triangle indices in counter clockwise order, bottom left, bottom right, top right
m_pwWaterIndices[ ( (x * 2) + y * (MAP_SIZE - 1) * 2) * 3 + 3] = x + (y+1) * (MAP_SIZE);
m_pwWaterIndices[ ( (x * 2) + y * (MAP_SIZE - 1) * 2) * 3 + 4] = x + (y+1) * (MAP_SIZE) + 1;
m_pwWaterIndices[ ( (x * 2) + y * (MAP_SIZE - 1) * 2) * 3 + 5] = x + y * (MAP_SIZE) + 1;

}

[/CODE]

Share this post


Link to post
Share on other sites