I have recently begun to implement a terrain engine into my game but have stumbled on the first hurdle! I have set up a vertex buffer and an index buffer and filled these with the relevant data in what seems to be the right way to me! The problem is that when I go to render them (using the DrawIndexedPrimitive function) then nothing appears on my screen! If I just enter in three vertices into the VB then a triangle will appear but in screen coordinates.
Im assuming that I need to loop through the amount of polygons and render through each loop, setting the world matrix each time. I cant seem to get the implementation right however. Is this the right way to approach it or is there something im missing?
The code below is what I use to fill the Vertex and Index buffers;
HRESULT CTerrain::CreateTerrain( LPDIRECT3DDEVICE9 m_pd3dDevice )
{
HRESULT hResult;
///Dimension Variables
D3DXVECTOR3 minBounds;
D3DXVECTOR3 maxBounds;
//Define boundaries
minBounds.x = 100; minBounds.y = 0; minBounds.z = 100;
maxBounds.x = 400; maxBounds.y = 1; maxBounds.z = 400;
//Define Cell dimensions
int numCellsWide = 1;
int numCellsHigh = 1;
//Calculate number of verts on each axis
int numVertsX = numCellsWide + 1;
int numVertsZ = numCellsHigh + 1;
//Calculate total number of verts
NumVerts = numVertsX * numVertsZ;
//Calculate total number of polygons
NumPolygons = (numCellsWide * numCellsHigh) * 2;
//Calculate step between each vertex
float stepX = (maxBounds.x - minBounds.x) / numCellsWide;
float stepZ = (maxBounds.z - minBounds.z) / numCellsHigh;
// Set the start position
D3DXVECTOR3 pos(minBounds.x, 0, maxBounds.z);
//Initialise counter
int count = 0;
//Create custom data structure variable to hold info
TERRAINVERTEX* pVertices = new TERRAINVERTEX[NumVerts];
// Loop across and down
for (int z = 0; z < numVertsZ ;z++)
{
//Set X position
pos.x = minBounds.x;
for (int x = 0; x < numVertsX; x++)
{
// Create the verts
pVertices[count].vInfo = D3DXVECTOR4( pos.x, pos.z, 0.0f, 1.0f );
pVertices[count].color = 0xffff0f00;
// Increment x across
pos.x += stepX;
count++;
}
// Increment Z down
pos.z -= stepZ;
}
////Vertex Buffer
// Create a vextex buffer for the viewport
if( FAILED( m_pd3dDevice->CreateVertexBuffer( NumVerts * sizeof(TERRAINVERTEX),
D3DUSAGE_DYNAMIC, D3DFVF_TERRAINVERTEX,
D3DPOOL_MANAGED, &m_TerrainVB, NULL ) ) )
return DXTRACE_ERR( TEXT("m_pd3dDevice->CreateVertexBuffer"), S_OK);
//Custom vertex format
TERRAINVERTEX* Verts;
m_TerrainVB->Lock( 0, 0, (void**)&Verts, 0 );
//Copy Vertex data across
memcpy( Verts, pVertices, sizeof(pVertices) );
//Unlock buffer
m_TerrainVB->Unlock();
////Index Buffer
int NumIndices = (numCellsWide * 6) * numCellsHigh;
// Create an index buffer for the Terrain
if( FAILED( m_pd3dDevice->CreateIndexBuffer( NumIndices * sizeof(WORD),
0, D3DFMT_INDEX16,
D3DPOOL_MANAGED, &m_TerrainIB, NULL ) ) )
return false;
//Reinitialise Count
count = 0;
int vIndex = 0;
WORD* pIndices;
WORD* Indices = new WORD[NumIndices];
for (int z = 0; z < numCellsHigh; z++)
{
for (int x = 0;x < numCellsWide; x++)
{
// first triangle
Indices[count++] = (WORD)vIndex;
Indices[count++] = (WORD)(vIndex + 1);
Indices[count++] = (WORD)(vIndex + numVertsX);
// second triangle
Indices[count++] = (WORD)(vIndex + numVertsX);
Indices[count++] = (WORD)(vIndex + 1);
Indices[count++] = (WORD)(vIndex + numVertsX + 1);
vIndex++;
}
vIndex++;
}
//Get a pointer to the index buffer indices and lock the index buffer
m_TerrainIB->Lock(0, NumIndices * sizeof(WORD), (void**)&pIndices, 0);
//Copy indices data across
memcpy( pIndices, Indices, NumIndices * sizeof(WORD) );
//Unlock the index buffer
m_TerrainIB->Unlock();
return S_OK;
}
This code is the rendering code;
[source = lang"cpp"]
BOOL CTerrain::RenderTerrain( LPDIRECT3DDEVICE9 m_pd3dDevice )
{
D3DXMATRIX matTerrainWorld;
D3DXMatrixIdentity( &matTerrainWorld );
m_pd3dDevice->SetTransform( D3DTS_WORLD, &matTerrainWorld );
D3DMATERIAL9 m_matMaterial;
//Set material default values (R, G, B, A)
D3DCOLORVALUE rgbaDiffuse = {1.0f, 1.0f, 1.0f, 0.0f};
D3DCOLORVALUE rgbaAmbient = {1.0, 1.0, 1.0, 0.0};
D3DCOLORVALUE rgbaEmissive = {0.0, 0.0, 0.0, 0.0};
//Set the RGBA for diffuse light reflected from this material.
m_matMaterial.Diffuse = rgbaDiffuse;
//Set the RGBA for ambient light reflected from this material.
m_matMaterial.Ambient = rgbaAmbient;
//Set the RGBA for light emitted from this material.
m_matMaterial.Emissive = rgbaEmissive;
//Select the material to use
m_pd3dDevice->SetMaterial(&m_matMaterial);
// Tell DX from which index buffer you want to render. We have our indices
// stored in m_pIndexBuffer, so we tell dx to take indices from there.
m_pd3dDevice->SetIndices(m_TerrainIB);
//Set vertex format and terrain vertex buffer as stream source
m_pd3dDevice->SetFVF(D3DFVF_TERRAINVERTEX);
m_pd3dDevice->SetStreamSource(0, m_TerrainVB, 0, sizeof(TERRAINVERTEX));
//Draw the terrain
m_pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, NumVerts, 0, NumPolygons);
return TRUE;
}