이런걸로 만드는거...
#include "Terrain.h"
CTerrain::CTerrain() { }
CTerrain::CTerrain(LPDIRECT3DDEVICE9 Device) {
m_Device = Device;
m_PVB = NULL;
m_PIB = NULL;
g_pTexHeight = NULL;
g_pTexDiffuse = NULL;
g_cxHeight = 0;
g_czHeight = 0;
InitTexture();
InitPVB();
InitPIB();
}
CTerrain::~CTerrain() {
SAFE_RELEASE(m_PVB);
SAFE_RELEASE(m_PIB);
}
HRESULT CTerrain::InitTexture() {
// 높이맵 텍스쳐
if( FAILED( D3DXCreateTextureFromFileEx(m_Device, "map128.bmp", D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, &g_pTexHeight) ) )
return E_FAIL;
// 색깔맵 텍스처
if( FAILED( D3DXCreateTextureFromFile( m_Device, "tile2.tga", &g_pTexDiffuse) ) )
return E_FAIL;
m_Device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
m_Device->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0);
m_Device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
m_Device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
m_Device->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
return S_OK;
}
HRESULT CTerrain::InitPVB() {
D3DSURFACE_DESC ddsd;
D3DLOCKED_RECT d3drc;
g_pTexHeight->GetLevelDesc( 0, &ddsd ); // 텍스처의 정보
g_cxHeight = ddsd.Width; // 텍스처의 가로크기
g_czHeight = ddsd.Height; // 텍스처의 세로크기
if( FAILED( m_Device ->CreateVertexBuffer( ddsd.Width * ddsd.Height * sizeof(CUSTOMVERTEX), 0, D3DFVF_VIRTUALPLANEVERTEX, D3DPOOL_DEFAULT, &m_PVB, NULL ) ) )
{
return E_FAIL;
}
// 텍스처 메모리 Lock
g_pTexHeight->LockRect( 0, &d3drc, NULL, D3DLOCK_READONLY );
VOID* pVertices;
// 정점버퍼 Lock
if( FAILED( m_PVB->Lock( 0, g_cxHeight * g_czHeight * sizeof(CUSTOMVERTEX), (void**)&pVertices, 0 ) ) )
return E_FAIL;
CUSTOMVERTEX v;
CUSTOMVERTEX* pV = (CUSTOMVERTEX*)pVertices;
//좌측 상단 삼각형 + 우측 하단 삼각형 순서로 인덱스 생성.
for( DWORD z = 0 ; z < g_czHeight ; z++ )
{
for( DWORD x = 0 ; x < g_cxHeight ; x++ )
{
v.p.x = (float)x - g_cxHeight / 2.0f;
v.p.z = -( (float)z - g_czHeight / 2.0f );
v.p.y = ( (float)(*( (LPDWORD)d3drc.pBits + x + z * (d3drc.Pitch / 4) )&0x000000ff ) ) / 10.0f;
// DWORD이므로 pitch/4
v.n.x = v.p.x;
v.n.y = v.p.y;
v.n.z = v.p.z;
D3DXVec3Normalize( &v.n, &v.n );
v.t.x = (float)x / (g_cxHeight - 1);
v.t.y = (float)z / (g_czHeight - 1);
*pV++ = v;
}
}
m_PVB->Unlock();
g_pTexHeight->UnlockRect( 0 );
return S_OK;
}
HRESULT CTerrain::InitPIB() {
if( FAILED( m_Device->CreateIndexBuffer((g_cxHeight - 1) * (g_czHeight - 1) * 2 * sizeof(CUSTOMINDEX), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &m_PIB, NULL ) ) )
{
return E_FAIL;
}
CUSTOMINDEX i;
CUSTOMINDEX* pI;
if( FAILED( m_PIB->Lock( 0, (g_cxHeight - 1) * (g_czHeight - 1) * 2 * sizeof(CUSTOMINDEX), (void**)&pI, 0 ) ) )
return E_FAIL;
for( DWORD z = 0 ; z < g_czHeight-1 ; z++ )
{
for( DWORD x = 0 ; x < g_cxHeight-1 ; x++ )
{
i._0 = (z * g_cxHeight + x);
i._1 = (z * g_cxHeight + x + 1);
i._2 = ((z + 1) * g_cxHeight + x);
*pI++ = i;
i._0 = ((z + 1) * g_cxHeight + x);
i._1 = (z * g_cxHeight + x + 1);
i._2 = ((z + 1) * g_cxHeight + x + 1);
*pI++ = i;
}
}
m_PIB->Unlock();
return S_OK;
}
VOID CTerrain::DrawTerrain() {
m_Device->SetTexture(0, g_pTexDiffuse);
m_Device->SetStreamSource(0, m_PVB, 0, sizeof(CUSTOMVERTEX));
m_Device->SetFVF(D3DFVF_VIRTUALPLANEVERTEX);
m_Device->SetIndices(m_PIB);
m_Device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, g_cxHeight * g_czHeight, 0, (g_cxHeight - 1) * (g_czHeight - 1) * 2);
}