# Problems of terrain generation with DirectX9

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

## Recommended Posts

Hey guys, I'm new here. I'm a rookie of DirectX and game programming, and I'm trying to write a virtual interactive environment program. However, I encountered problems about terrain generation. My goal is to produce a terrain with quad tree, but first I think I should build the terrain and leave the things about culling later. But the thing is not as easy as I estimated. Here I have built the CTerrain and CTerrainQuad(two adjacent triangles that compose a cell) classes under the guide of the book "Introduction to 3D Game Engine Design Using DirectX9 and C#"(it's the only book I can find on the topic in China~~). It seems to be right, but the terrain just cannot show up. I can't figure out what's wrong.Perhaps that my usage of the vertex buffer is wrong or I haven't set the instance of these classes and the matrices correctly in the DXUT framework program? I'll be really appreciated that you veterans can help me or introduce some available electronic tutorials of game programming using DirectX9. You know, I can't find materials of game programming and DirectX in China... Here is the project in VC 2005.

##### Share on other sites
I don't know how to upload my project or my source, could anyone tell me?
copy some here:
#pragma once

typedef struct CustomVertex
{
float x,y,z;
D3DXVECTOR3 n;
float u,v;
static const int FVF = D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_TEX1;
CustomVertex( float zx, float zy, float zz, D3DXVECTOR3 zn, float zu, float zv)
{
x = zx; y = zy; z = zz;
n = zn;
u = zu; v = zv;
}
CustomVertex()
{
x = y = z = 0;
n = D3DXVECTOR3(0,0,0);
u = v = 0;
}
void SetVertexWithoutNorm( float zx, float zy, float zz, float zu, float zv)
{
x = zx; y = zy; z = zz;
u = zu; v = zv;
};

void SetVertexNorm( D3DXVECTOR3 zn)
{
n = zn;
}
} CustomVertex;

{
public:
CTerrainQuad( const D3DXVECTOR3 p1, const D3DXVECTOR3 p2, const D3DXVECTOR3 p3, const D3DXVECTOR3 p4 );
void Setup( const D3DXVECTOR3 p1, const D3DXVECTOR3 p2, const D3DXVECTOR3 p3, const D3DXVECTOR3 p4 );
int RenderQuad( int Offset, CustomVertex* vertices);
inline bool isValid(){return m_bValid;}

inline D3DXVECTOR3 GetFaceNormals()
{
D3DXVECTOR3 sum = m_vFace1Norm + m_vFace2Norm;
D3DXVec3Normalize( &sum, &sum);
return sum;
}

inline void ComputeFaceNormal( const D3DXVECTOR3* p0,const D3DXVECTOR3* p1, const D3DXVECTOR3* p2, D3DXVECTOR3* out)
{
D3DXVECTOR3 u = *p1 - *p0;
D3DXVECTOR3 v = *p2 - *p0;

D3DXVec3Cross( out, &u, &v);
D3DXVec3Normalize( out, out);
}

void SetCornerNormal( int index, D3DXVECTOR3 zn);
D3DXVECTOR3 m_vFace1Norm;
D3DXVECTOR3 m_vFace2Norm;
private:
CustomVertex m_Corners[6];
bool m_bValid;
};

##### Share on other sites
#include "dxstdafx.h"

CTerrainQuad::CTerrainQuad(const D3DXVECTOR3 p1, const D3DXVECTOR3 p2, const D3DXVECTOR3 p3, const D3DXVECTOR3 p4 )
{
m_Corners[0].SetVertexWithoutNorm( p3.x, p3.y, p3.z, 0.0f, 1.0f); // northwest
m_Corners[1].SetVertexWithoutNorm( p1.x, p1.y, p1.z, 0.0f, 0.0f); // southwest
m_Corners[2].SetVertexWithoutNorm( p4.x, p4.y, p4.z, 1.0f, 1.0f); // northeast
m_Corners[3].SetVertexWithoutNorm( p2.x, p2.y, p2.z, 1.0f, 0.0f); // southeast

ComputeFaceNormal( &p3, &p1, &p4, &m_vFace1Norm);
ComputeFaceNormal( &p1, &p2, &p4, &m_vFace2Norm);

// Default the vertex normals to the face normal value
m_Corners[0].SetVertexNorm( m_vFace1Norm);
m_Corners[1].SetVertexNorm(GetFaceNormals());
m_Corners[2].SetVertexNorm(GetFaceNormals());
m_Corners[3].SetVertexNorm( m_vFace1Norm);
m_Corners[4].SetVertexNorm(GetFaceNormals());
m_Corners[5].SetVertexNorm(GetFaceNormals());

m_Corners[4].x = m_Corners[2].x; m_Corners[4].y = m_Corners[2].y; m_Corners[4].z = m_Corners[2].z;
m_Corners[4].u = m_Corners[2].u; m_Corners[4].v = m_Corners[2].v;

m_Corners[5].x = m_Corners[1].x; m_Corners[5].y = m_Corners[1].y; m_Corners[5].z = m_Corners[1].z;
m_Corners[5].u = m_Corners[1].u; m_Corners[5].v = m_Corners[1].v;

m_bValid = true;

}

{
}

{
int newOffset = Offset;

if (1) // modify later to include culling
{
for( int i = 0; i<6; i++)
vertices[ Offset + i] = m_Corners;
newOffset += 6;
}
return newOffset;
}

void CTerrainQuad::Setup(const D3DXVECTOR3 p1, const D3DXVECTOR3 p2, const D3DXVECTOR3 p3, const D3DXVECTOR3 p4 )
{
m_Corners[0].SetVertexWithoutNorm( p3.x, p3.y, p3.z, 0.0f, 1.0f); // northwest
m_Corners[1].SetVertexWithoutNorm( p1.x, p1.y, p1.z, 0.0f, 0.0f); // southwest
m_Corners[2].SetVertexWithoutNorm( p4.x, p4.y, p4.z, 1.0f, 1.0f); // northeast
m_Corners[3].SetVertexWithoutNorm( p2.x, p2.y, p2.z, 1.0f, 0.0f); // southeast

ComputeFaceNormal( &p3, &p1, &p4, &m_vFace1Norm);
ComputeFaceNormal( &p1, &p2, &p4, &m_vFace2Norm);

// Default the vertex normals to the face normal value
m_Corners[0].SetVertexNorm( m_vFace1Norm);
m_Corners[1].SetVertexNorm(GetFaceNormals());
m_Corners[2].SetVertexNorm(GetFaceNormals());
m_Corners[3].SetVertexNorm( m_vFace1Norm);
m_Corners[4].SetVertexNorm(GetFaceNormals());
m_Corners[5].SetVertexNorm(GetFaceNormals());

m_Corners[4].x = m_Corners[2].x; m_Corners[4].y = m_Corners[2].y; m_Corners[4].z = m_Corners[2].z;
m_Corners[4].u = m_Corners[2].u; m_Corners[4].v = m_Corners[2].v;

m_Corners[5].x = m_Corners[1].x; m_Corners[5].y = m_Corners[1].y; m_Corners[5].z = m_Corners[1].z;
m_Corners[5].u = m_Corners[1].u; m_Corners[5].v = m_Corners[1].v;

m_bValid = true;

}

void CTerrainQuad::SetCornerNormal(int index, D3DXVECTOR3 zn)
{
D3DXVec3Normalize( &zn, &zn);
m_Corners[index].SetVertexNorm( zn);
}

##### Share on other sites
The CTerrain.h:
#pragma once

class CTerrain
{
public:
CTerrain();
HRESULT Render(LPDIRECT3DDEVICE9 pd3dDevice);
HRESULT Setup(LPDIRECT3DDEVICE9 pd3dDevice, int xSize, int ySize, LPCWSTR sHeightMap, LPCWSTR sTexName, float fSpacing, float fElevFactor);
public:
void Destroy();
~CTerrain(void);
private:
D3DXVECTOR3* m_pElevations;
LPDIRECT3DVERTEXBUFFER9 m_pVB;
int m_xSize;
int m_ySize;
LPDIRECT3DTEXTURE9 m_pTex;
bool m_bValid;
CustomVertex* m_pVertices;
float m_fSpacing;
LPCWSTR m_sTexName;
};

##### Share on other sites
The CTerrain.cpp:
#include "dxstdafx.h"
#include "Terrain.h"
#include <fstream>
CTerrain::CTerrain(void):m_xSize(0),m_ySize(0),m_fSpacing(0),m_sTexName(NULL),m_bValid(true)
{
}

CTerrain::~CTerrain(void)
{
}

HRESULT CTerrain::Setup( LPDIRECT3DDEVICE9 pd3dDevice, int xSize, int ySize, LPCWSTR sHeightMap, LPCWSTR sTexName, float fSpacing, float fElevFactor)
{
m_pElevations = new D3DXVECTOR3 [xSize * ySize];
m_xSize = xSize - 1;
m_ySize = ySize - 1;
m_pTerrainQuads = new CTerrainQuad[ m_xSize * m_ySize ];
m_fSpacing = fSpacing;
m_pVertices = new CustomVertex[3000];
m_sTexName = sTexName;

std::ifstream inFile( sHeightMap, std::ios_base::binary);
if( inFile == 0)
return E_FAIL;

// Read the .raw File
for ( int i = 0; i < xSize; i++)
{
for ( int j = 0; j < ySize; j++)
{
char temp;
m_pElevations[i * xSize + j].x = i * fSpacing;
m_pElevations[i * xSize + j].z = j * fSpacing;
m_pElevations[i * xSize + j].y = temp * fElevFactor;
}
}

// Create Terrain Quads
for ( int i = 0; i < m_xSize; i++)
{
for ( int j = 0; j < m_ySize; j++)
{
tempQuad.Setup( m_pElevations[i * xSize + j],m_pElevations[(i+1) * xSize + j],
m_pElevations[i * xSize + j+1],m_pElevations[(i+1) * xSize + j+1]);
}
}

// Set up the vertices' normals
for (int i = 1; i < m_xSize-1; i++)
{
for ( int j = 1; j < m_ySize-1; j++)
{
D3DXVECTOR3 Normalsw = m_pTerrainQuads[i * m_xSize + j ].GetFaceNormals() +
m_pTerrainQuads[(i-1) * m_xSize + j - 1].GetFaceNormals()+
m_pTerrainQuads[(i-1) * m_xSize + j ].GetFaceNormals()+
m_pTerrainQuads[i * m_xSize + j - 1 ].GetFaceNormals();
m_pTerrainQuads[i * m_xSize + j ].SetCornerNormal( 0, Normalsw);

D3DXVECTOR3 Normalse = m_pTerrainQuads[i * m_xSize + j ].GetFaceNormals() +
m_pTerrainQuads[i * m_xSize + j - 1].GetFaceNormals()+
m_pTerrainQuads[(i+1) * m_xSize + j ].GetFaceNormals()+
m_pTerrainQuads[(i+1) * m_xSize + j - 1 ].GetFaceNormals();
m_pTerrainQuads[i * m_xSize + j ].SetCornerNormal( 1, Normalse);

D3DXVECTOR3 Normalnw = m_pTerrainQuads[i * m_xSize + j].GetFaceNormals() +
m_pTerrainQuads[(i-1) * m_xSize + j].GetFaceNormals()+
m_pTerrainQuads[(i-1) * m_xSize + j+1].GetFaceNormals()+
m_pTerrainQuads[ i * m_xSize + j+1].GetFaceNormals();
m_pTerrainQuads[i * m_xSize + j].SetCornerNormal( 2, Normalnw);

D3DXVECTOR3 Normalne = m_pTerrainQuads[i * m_xSize + j].GetFaceNormals() +
m_pTerrainQuads[i * m_xSize + j +1].GetFaceNormals()+
m_pTerrainQuads[(i+1) * m_xSize + j+1].GetFaceNormals()+
m_pTerrainQuads[(i+1) * m_xSize + j].GetFaceNormals();
m_pTerrainQuads[i * m_xSize + j].SetCornerNormal( 3, Normalnw);

}
}

HRESULT hr;
// V_RETURN(D3DXCreateTextureFromFile( pd3dDevice,sTexName, &m_pTex));
V_RETURN(pd3dDevice->CreateVertexBuffer( sizeof(CustomVertex) * 3000, D3DUSAGE_WRITEONLY,
CustomVertex::FVF, D3DPOOL_MANAGED,&m_pVB, NULL)
);

return S_OK;

}

HRESULT CTerrain::Render( LPDIRECT3DDEVICE9 pd3dDevice)
{
// Render Terrain Quads
if( m_bValid)
{
pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CW);
pd3dDevice->SetRenderState(D3DRS_FILLMODE, D3DFILLMODE::D3DFILL_WIREFRAME);
pd3dDevice->SetFVF( CustomVertex::FVF);

D3DMATERIAL9 mtrl;
mtrl.Ambient = D3DXCOLOR( 1.0f, 1.0f, 1.0f, 1.0f);
mtrl.Diffuse = D3DXCOLOR( 1.0f, 1.0f, 1.0f, 1.0f);
pd3dDevice->SetMaterial( &mtrl);

// pd3dDevice->SetTexture( 0, m_pTex);

int Offset = 0;
for ( int i = 0; i < m_xSize; i++)
{
for ( int j = 0; j < m_ySize; j++)
{
// Render 3000 vertices a time

// copy the vertices into space where m_pVertices points
if(FAILED(m_pVB->Lock( 0,sizeof(CustomVertex), (void**)&m_pVertices, 0)))
return E_FAIL;
Offset = m_pTerrainQuads[i * m_xSize + j].RenderQuad( Offset, m_pVertices);
m_pVB->Unlock();

if ( Offset >= 2990)
{
pd3dDevice->SetFVF( CustomVertex::FVF);
pd3dDevice->SetStreamSource( 0, m_pVB, 0, sizeof(CustomVertex));
pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, Offset/3);
Offset = 0;
}
}
}
if ( Offset > 0 )
{
pd3dDevice->SetFVF( CustomVertex::FVF);
pd3dDevice->SetStreamSource( 0, m_pVB, 0, sizeof(CustomVertex));
pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, Offset/3);
Offset = 0;
}
}
return S_OK;
}

void CTerrain::Destroy()
{
SAFE_DELETE_ARRAY( m_pElevations);
SAFE_DELETE_ARRAY( m_pVertices);
SAFE_RELEASE(m_pVB);
SAFE_RELEASE(m_pTex);
}

1. 1
2. 2
3. 3
Rutin
23
4. 4
5. 5
khawk
14

• 9
• 11
• 11
• 23
• 12
• ### Forum Statistics

• Total Topics
633653
• Total Posts
3013166
×