본문 바로가기
책갈피

근데 이 3D 지형 만드는 거

ㅇㅅㅇ |2011.12.26 10:47
조회 185 |추천 0

이런걸로 만드는거...

 

#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);

}

 

 

추천수0
반대수0

공감많은 뉴스 시사

더보기

뉴스 플러스