이런걸로 만드는거... #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); }
근데 이 3D 지형 만드는 거
이런걸로 만드는거...
#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);
}