📄 game_terrain.cpp
字号:
#include "..\Include\Game_Terrain.h"
Game_Terrain::Game_Terrain(D3DXVECTOR3 pos,
LPCTSTR strTerrain,
float cellWidth,
float height,
float nTile){
m_v3=pos;
m_nCol=0;
m_nRow=0;
m_pTexture=NULL;
m_nTile=nTile;
m_CellWidth=cellWidth;
m_maxHeight=height;
m_cStrTerrain=strTerrain;
}
Game_Terrain::~Game_Terrain(){
SAFE_RELEASE(m_pTexture);
}
void Game_Terrain::InitObject(LPCTSTR strName){
D3DXCreateTextureFromFile(g_sGlobal.g_pDevice,strName,&m_pTexture);
//用GDI对象来读取位图,但是会转换成DIB位图
long i=0,j=0;
BITMAP bmp;
HBITMAP hBmp;
HDC hDC;
HBITMAP oldBmp;
hDC=CreateCompatibleDC(NULL);
hBmp=(HBITMAP)LoadImage(NULL,m_cStrTerrain,
IMAGE_BITMAP,m_nCol,m_nRow,LR_LOADFROMFILE);
oldBmp=(HBITMAP)SelectObject(hDC,hBmp);
GetObject(hBmp,sizeof(bmp),&bmp);
m_nCol=bmp.bmWidth;
m_nRow=bmp.bmHeight;
m_pHeightData=new BYTE[m_nCol*m_nRow];
DWORD color;
for(i=0;i<m_nRow;i++){
for(j=0;j<m_nCol;j++){
color=GetPixel(hDC,j,i);
m_pHeightData[i*m_nCol+j]=*(BYTE*)&color; //取红色通道 0xAABBGGRR
}
}
DeleteObject(oldBmp);
DeleteObject(hDC);
DeleteObject(hBmp);
m_dwNumOfVertices = m_nRow * m_nCol;
m_dwNumOfPolygons = (m_nCol-1)*(m_nRow-1)*2;
D3DXCreateMeshFVF(m_dwNumOfPolygons,m_dwNumOfVertices,D3DXMESH_MANAGED,D3DFVF_TERRAIN ,g_sGlobal.g_pDevice,&m_pMesh);
TVertexBuffer* pVertices;
m_pMesh->LockVertexBuffer(0,(void**)&pVertices);
for(i=0;i<m_nCol*m_nRow;i++){
pVertices[i].y=m_pHeightData[i];
pVertices[i].x=float(i%m_nCol);
pVertices[i].z=-float(i/m_nCol)+m_nRow;
pVertices[i].nx=0;
pVertices[i].ny=1;
pVertices[i].nz=0;
pVertices[i].tu=m_nTile*pVertices[i].x/m_nCol ;
pVertices[i].tv=m_nTile*pVertices[i].z/m_nRow ;
}
m_pMesh->UnlockVertexBuffer();
WORD* pIndex;
m_pMesh->LockIndexBuffer(0,(void**)&pIndex);
for(i=0,j=0;i<m_nCol*m_nRow;i++){
if((i+1)%m_nCol && i/m_nCol!=m_nRow-1){
pIndex[j+0]=(WORD)(i);
pIndex[j+1]=(WORD)(i+1);
pIndex[j+2]=(WORD)(i+m_nCol);
pIndex[j+3]=(WORD)(i+m_nCol);
pIndex[j+4]=(WORD)(i+1);
pIndex[j+5]=(WORD)(i+1+m_nCol);
j+=6;
}
}
m_pMesh->UnlockIndexBuffer();
//g_sGlobal.g_pDevice->SetRenderState(D3DRS_LIGHTING,TRUE);
g_sGlobal.g_pDevice->SetRenderState(D3DRS_ZENABLE,TRUE);
g_sGlobal.g_pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
g_sGlobal.g_pDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
g_sGlobal.g_pDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
g_sGlobal.g_pDevice->SetSamplerState(0,D3DSAMP_ADDRESSU,D3DTADDRESS_MIRROR);
g_sGlobal.g_pDevice->SetSamplerState(0,D3DSAMP_ADDRESSV,D3DTADDRESS_MIRROR);
g_sGlobal.g_pDevice->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_BLENDTEXTUREALPHA);
g_sGlobal.g_pDevice->SetSamplerState(0,D3DSAMP_MAGFILTER,D3DTEXF_LINEAR);
g_sGlobal.g_pDevice->SetSamplerState(0,D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
g_sGlobal.g_pDevice->SetSamplerState(0,D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
}
void Game_Terrain::FrameMove(){
ZeroMemory(&m_matWorld,sizeof(m_matWorld));
m_matWorld._11=m_CellWidth;
m_matWorld._22=m_maxHeight/255.0f;
m_matWorld._33=m_CellWidth;
m_matWorld._44=1;
m_matWorld._41=m_v3.x-m_nCol*m_CellWidth/2; //地形中心在m_vPos
m_matWorld._42=m_v3.y;
m_matWorld._43=m_v3.z-m_nRow*m_CellWidth/2; //地形中心在m_vPos
g_sGlobal.g_pDevice->SetTransform(D3DTS_WORLD,&m_matWorld);
}
void Game_Terrain::Render(){
/*if ( m_bHide )
return;*/
g_sGlobal.g_pDevice->SetTexture(0,m_pTexture);
FrameMove();
m_pMesh->DrawSubset(0);
}
FLOAT Game_Terrain::GetHeight(float x,float z){
D3DXVECTOR3 vPos(0,0,0);
x+=vPos.x+m_CellWidth*m_nCol/2.0f;
z+=vPos.z+m_CellWidth*m_nRow/2.0f;
float rx,rz;
rx=x/m_CellWidth;
rz=m_nRow-z/m_CellWidth;
long col1,row1,col2,row2;
float h1,h2,h3,h4,ha,hb;
col1=DWORD(rx);
row1=DWORD(rz);
if(col1>m_nCol || col1<0 ||row1>m_nRow || row1<0) return 0;
else { //双线性插值
col2=(col1==m_nCol)?col1:col1+1;
row2=(row1==m_nRow)?row1:row1+1;
h1=(m_pHeightData[row1*m_nCol+col1]*m_maxHeight/255.0f);
h2=(m_pHeightData[row1*m_nCol+col2]*m_maxHeight/255.0f);
h3=(m_pHeightData[row2*m_nCol+col1]*m_maxHeight/255.0f);
h4=(m_pHeightData[row2*m_nCol+col2]*m_maxHeight/255.0f);
ha=(h2*(rx-col1)+h1*(col2-rx));
hb=(h4*(rx-col1)+h3*(col2-rx));
return (hb*(rz-row1)+ha*(row2-rz));
}
}
HRESULT Game_Terrain::GetTerrainVertex(D3DXVECTOR3 *cross,DWORD index,float u,float v){
WORD* pIndices;
WORD index1,index2,index3;
D3DXVECTOR3 v1,v2,v3;
m_pMesh->LockIndexBuffer(0,(void**)&pIndices);
index1=pIndices[index*3];
index2=pIndices[index*3+1];
index3=pIndices[index*3+2];
m_pMesh->UnlockIndexBuffer();
TVertexBuffer* pcvVertices;
m_pMesh->LockVertexBuffer (0,(void**)&pcvVertices);
v1.x=pcvVertices[index1].x;
v1.y=pcvVertices[index1].y;
v1.z=pcvVertices[index1].z;
v2.x=pcvVertices[index2].x;
v2.y=pcvVertices[index2].y;
v2.z=pcvVertices[index2].z;
v3.x=pcvVertices[index3].x;
v3.y=pcvVertices[index3].y;
v3.z=pcvVertices[index3].z;
m_pMesh->UnlockVertexBuffer();
*cross = v1 + u * (v2 - v1) + v * (v3 - v1);
cross->x=cross->x*m_matWorld._11+cross->y*m_matWorld._21+cross->z*m_matWorld._31+m_matWorld._41;
cross->y=cross->x*m_matWorld._12+cross->y*m_matWorld._22+cross->z*m_matWorld._32+m_matWorld._42;
cross->z=cross->x*m_matWorld._13+cross->y*m_matWorld._23+cross->z*m_matWorld._33+m_matWorld._43;
return S_OK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -