加载地形的类

#ifndef   __TerrainH__
#define     __TerrainH__

#include <d3d9.h>
#include <d3dx9.h>
#include <vector>
using namespace std;

struct TERRAIN_CUSTOMVERTEX
{
    FLOAT x, y, z;
    FLOAT a, b, c;
    FLOAT u, v;
    FLOAT tu, tv;
};

#define TERRAIN_D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX2)

class CTerrain
{
public:
    LPDIRECT3DDEVICE9 m_pDevice;
    LPD3DXMESH m_pMesh;
    LPDIRECT3DTEXTURE9 m_pDTex;
    LPDIRECT3DTEXTURE9 m_pHeightMap;
    LPDIRECT3DTEXTURE9 m_pDetailTexture;
    D3DSURFACE_DESC m_HeightMapDesc;
    float m_fMaxHeight;
    float m_fTileLength;
    UINT m_uiNumXTile;
    UINT m_uiNumZTile;
    UINT m_uiNumTiles;
    UINT m_uiNumVertices;
    UINT m_uiNumFaces;
    UINT m_uiNumIndices;
    UINT m_uiDetail;
    vector<unsigned char> m_vucHeight;
public:
    CTerrain() : m_pDevice(NULL), m_pMesh(NULL), m_pDTex(NULL), m_pHeightMap(NULL), m_pDetailTexture(NULL), m_fMaxHeight(0.0f), m_fTileLength(0.0f),
        m_uiNumXTile(0), m_uiNumZTile(0), m_uiNumTiles(0), m_uiNumVertices(0), m_uiNumIndices(0)
    {
        ZeroMemory(&m_HeightMapDesc, sizeof(m_HeightMapDesc));
        m_vucHeight.clear();
    }
    ~CTerrain()
    {

    }
    void Init(IDirect3DDevice9* pDevice, char* sTexMapName, char* sHeightMapName, char* sDetailedMapName, float fMaxHeight, float fTileLength, UINT uiDetail)
    {
        m_pDevice = pDevice;
        D3DXCreateTextureFromFileA(m_pDevice, sTexMapName, &m_pDTex);
        D3DXCreateTextureFromFileA(m_pDevice, sHeightMapName, &m_pHeightMap);
        D3DXCreateTextureFromFileA(m_pDevice, sDetailedMapName, &m_pDetailTexture);
        m_fMaxHeight = fMaxHeight;
        m_fTileLength = fTileLength;
        m_uiDetail = uiDetail;
        m_pHeightMap->GetLevelDesc(2, &m_HeightMapDesc);
        m_uiNumXTile = m_HeightMapDesc.Width - 1;
        m_uiNumZTile = m_HeightMapDesc.Height - 1;
        m_uiNumTiles = m_uiNumXTile * m_uiNumZTile;
        m_uiNumVertices = m_HeightMapDesc.Width * m_HeightMapDesc.Height;
        m_uiNumFaces = m_uiNumTiles * 2;
        D3DXCreateMeshFVF(m_uiNumFaces, m_uiNumVertices, D3DXMESH_MANAGED, TERRAIN_D3DFVF_CUSTOMVERTEX, m_pDevice, &m_pMesh);
        m_vucHeight.resize(m_uiNumVertices);
        D3DLOCKED_RECT LockedRect;
        m_pHeightMap->LockRect(2, &LockedRect, NULL, 0);
        memcpy(&m_vucHeight[0], LockedRect.pBits, m_HeightMapDesc.Width * m_HeightMapDesc.Height);
        m_pHeightMap->UnlockRect(2);
        TERRAIN_CUSTOMVERTEX* pVertex;
        m_pMesh->LockVertexBuffer(0, (void**)&pVertex);
        UINT z, x, i, tz, tx;
        float fDetailPitch = 1.0f / m_uiDetail;
        float fTempBase = m_fMaxHeight / 256.0f;
        for(z = 0; z <= m_uiNumZTile; z ++)
        {
            for(x = 0; x <= m_uiNumXTile; x ++)
            {
                i = z * (m_uiNumZTile + 1) + x;
                pVertex[i].x = x * m_fTileLength;
                pVertex[i].z = (m_uiNumZTile - z) * m_fTileLength;
                pVertex[i].y = m_vucHeight[i] * fTempBase;
                pVertex[i].a = pVertex[i].c = 0.0f;
                pVertex[i].b = 1.0f;
                pVertex[i].u = (float)x / (float)m_uiNumXTile;
                pVertex[i].v = (float)z / (float)m_uiNumZTile;
                tx = x % m_uiDetail;
                tz = z % m_uiDetail;
                pVertex[i].tu = tx * fDetailPitch;
                pVertex[i].tv = tz * fDetailPitch;
            }
        }
        m_pMesh->UnlockVertexBuffer();
        short* pIndex;
        m_pMesh->LockIndexBuffer(0, (void**)&pIndex);
        for(z = 0; z < m_uiNumZTile; z ++)
        {
            for(x = 0; x < m_uiNumXTile; x ++)
            {
                i = (z * m_uiNumXTile + x) * 6;
                pIndex[i+0] = z * (m_uiNumXTile + 1) + x;
                pIndex[i+1] = pIndex[i+4] = z * (m_uiNumXTile + 1) + x + 1;
                pIndex[i+2] = pIndex[i+3] = (z + 1) * (m_uiNumXTile + 1) + x;
                pIndex[i+5] = (z + 1) * (m_uiNumXTile + 1) + x + 1;
            }
        }
        m_pMesh->UnlockIndexBuffer();
    }
    void Render(float fElapsedTime)
    {
        m_pDevice->SetRenderState(D3DRS_LIGHTING, TRUE);
        m_pDevice->SetRenderState(D3DRS_SPECULARENABLE, TRUE);
        m_pDevice->SetRenderState(D3DRS_NORMALIZENORMALS, TRUE);
        m_pDevice->SetTexture(0, m_pDTex);
        m_pDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
        m_pDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
        m_pDevice->SetTexture(1,  m_pDetailTexture);
        m_pDevice->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
        m_pDevice->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT);
        m_pDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE);
        m_pMesh->DrawSubset(0);
        m_pDevice->SetTexture(0,NULL);
        m_pDevice->SetTexture(1,NULL);
    }
};

#endif

 

posted on 2012-05-22 00:01  紫澜  阅读(251)  评论(0编辑  收藏  举报