📄 winmain.cpp
字号:
#pragma comment(lib, "d3d9.lib")
#pragma comment(lib, "d3dx9.lib")
#pragma comment(lib, "winmm.lib")
#pragma comment(lib, "dxguid.lib")
#pragma comment(lib, "dinput8.lib")
#define MAINBODY
#include <d3d9.h>
#include <d3dx9.h>
#include "Input.h"
#include "Camera.h"
#include "SkinMesh.h"
#define WINDOW_W 600
#define WINDOW_H 600
#define WINDOW_TITLE "HeightMap-TList"
#define BMP_HEIGHTMAP "map128.bmp"
#define EDGE_LENGTH 8.0f
#define KEYDOWN(VK) (GetAsyncKeyState(VK) & 0x8000 ? 1 : 0)
/**----------------------------------------------------------------------------
* 全局参数
*------------------------------------------------------------------------------
*/
HWND g_hwnd = NULL;
HINSTANCE g_hinst = NULL;
LPDIRECT3D9 g_pD3D = NULL; /// 创建D3D 设备的D3D对象参数
LPDIRECT3DDEVICE9 g_pd3dDevice = NULL; /// 渲染中使用的D3D设备
LPDIRECT3DVERTEXBUFFER9 g_pVB = NULL; /// 储存顶点的顶点缓冲
LPDIRECT3DINDEXBUFFER9 g_pIB = NULL; /// 储存索引的索引缓冲
LPDIRECT3DTEXTURE9 g_pTexHeight = NULL; /// 纹理高度图
LPDIRECT3DTEXTURE9 g_pTexDiffuse = NULL; /// 纹理颜色图
D3DXMATRIXA16 g_matAni;
DWORD g_cxHeight = 0;
DWORD g_czHeight = 0;
DXInput* g_pInput = NULL;
Camera* g_pCamera = NULL;
CSkinMesh* g_pSkinMesh = NULL;
CSkinMesh* g_pSkyBox = NULL;
float g_fTime = 0.0f;
/// 定义用户顶点的结构体
struct CUSTOMVERTEX
{
D3DXVECTOR3 p;
D3DXVECTOR3 n;
D3DXVECTOR2 t;
};
/// 表现用户顶点结构体相关信息的FVF值
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_TEX1)
struct MYINDEX
{
WORD _0, _1, _2; /// WORD,16位索引
};
CUSTOMVERTEX * g_pTerrainMap = NULL;
/**-----------------------------------------------------------------------------
* Direct3D初始化
*------------------------------------------------------------------------------
*/
void AnimatTime()
{
static float fTimeOld = (float)timeGetTime()/1000.0f;
static float fTimeNew = 0.0f;
fTimeNew = (float)timeGetTime()/1000.0f;
g_fTime = fTimeNew - fTimeOld;
fTimeOld = fTimeNew;
}
HRESULT InitD3D( HWND hWnd )
{
/// 创建一个用来创建设备的D3D对象
if( NULL == ( g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )
return E_FAIL;
/// 创建设备的结构体
/// 绘制复杂对象时需要Z-缓冲.
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory( &d3dpp, sizeof(d3dpp) );
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
d3dpp.EnableAutoDepthStencil = TRUE;
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
/// 创建设备
if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3dpp, &g_pd3dDevice ) ) )
{
return E_FAIL;
}
D3DXMATRIXA16 matProj;
D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/4, 1.0f, 1.0f, 2000.0f );
g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );
/// 基本卷起,CCW
g_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW );
/// 起到Z-缓冲功能.
g_pd3dDevice->SetRenderState( D3DRS_ZENABLE, TRUE );
return S_OK;
}
/**-----------------------------------------------------------------------------
* 纹理初始化
*------------------------------------------------------------------------------
*/
HRESULT InitTexture()
{
/// 高度图纹理
/// 调用该函数处理D3DFMT_X8R8G8B8和 D3DPOOL_MANAGED.
if( FAILED( D3DXCreateTextureFromFile( g_pd3dDevice, "Terrain_128_RGB.bmp", &g_pTexHeight) ) )
return E_FAIL;
/// 颜色图
if( FAILED( D3DXCreateTextureFromFile( g_pd3dDevice, "terr_dirt-grass.jpg", &g_pTexDiffuse) ) )
return E_FAIL;
return S_OK;
}
/**-----------------------------------------------------------------------------
* 创建顶点缓冲,设置顶点值.
*------------------------------------------------------------------------------
*/
HRESULT InitVB()
{
D3DSURFACE_DESC ddsd;
D3DLOCKED_RECT d3drc;
g_pTexHeight->GetLevelDesc( 0, &ddsd ); /// 纹理信息
g_cxHeight = ddsd.Width; /// 纹理的长度
g_czHeight = ddsd.Height; /// 纹理的宽度
if( FAILED( g_pd3dDevice->CreateVertexBuffer( ddsd.Width*ddsd.Height*sizeof(CUSTOMVERTEX),
0, D3DFVF_CUSTOMVERTEX,
D3DPOOL_DEFAULT, &g_pVB, NULL ) ) )
{
return E_FAIL;
}
/// 纹理存储器!
g_pTexHeight->LockRect( 0, &d3drc, NULL, D3DLOCK_READONLY );
VOID* pVertices;
/// 顶点缓冲!
if( FAILED( g_pVB->Lock( 0, g_cxHeight*g_czHeight*sizeof(CUSTOMVERTEX), (void**)&pVertices, 0 ) ) )
return E_FAIL;
g_pTerrainMap = new CUSTOMVERTEX[g_cxHeight*g_czHeight];
CUSTOMVERTEX v;
CUSTOMVERTEX* pV = g_pTerrainMap;
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)*EDGE_LENGTH; /// 顶点的x坐标(以原点为准对齐网格)
v.p.z = -((float)z-g_czHeight/2.0f)*EDGE_LENGTH; /// 顶点的z坐标(以顶点为准对齐网格),z轴指向显示器,乘以“-”.
v.p.y = ((float)(*((LPDWORD)d3drc.pBits+x+z*(d3drc.Pitch/4))&0x000000ff))/5.0f; /// 由于是DWORD,因此为pitch/4
v.n.x = 0;
v.n.y = 1.0f;
v.n.z = 0;
D3DXVec3Normalize( &v.n, &v.n );
v.t.x = (float)x*10 / (g_cxHeight-1);
v.t.y = (float)z*10 / (g_czHeight-1);
*pV++ = v;
}
}
memcpy(pVertices, g_pTerrainMap, g_cxHeight * g_czHeight * sizeof(CUSTOMVERTEX));
g_pVB->Unlock();
g_pTexHeight->UnlockRect( 0 );
return S_OK;
}
/**-----------------------------------------------------------------------------
* 索引缓冲初始化
*------------------------------------------------------------------------------
*/
HRESULT InitIB()
{
if( FAILED( g_pd3dDevice->CreateIndexBuffer( (g_cxHeight-1)*(g_czHeight-1)*2 * sizeof(MYINDEX), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &g_pIB, NULL ) ) )
{
return E_FAIL;
}
MYINDEX i;
MYINDEX* pI;
if( FAILED( g_pIB->Lock( 0, (g_cxHeight-1)*(g_czHeight-1)*2 * sizeof(MYINDEX), (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;
}
}
g_pIB->Unlock();
return S_OK;
}
/**-----------------------------------------------------------------------------
* 几何信息初始化
*------------------------------------------------------------------------------
*/
HRESULT InitGeometry()
{
if( FAILED( InitTexture() ) ) return E_FAIL;
if( FAILED( InitVB() ) ) return E_FAIL;
if( FAILED( InitIB() ) ) return E_FAIL;
g_pInput = new DXInput;
if( FAILED( g_pInput->InitInput(g_hwnd, g_hinst) ) ) return E_FAIL;
D3DXMATRIXA16 matScale,matRotation;
g_pSkyBox = new CSkinMesh(g_pd3dDevice); //创建天空盒网格
g_pSkyBox->LoadFromXFile("skybox.x");
D3DXMatrixScaling(&matScale, 200.0f, 200.0f, 200.0f);
g_pSkyBox->m_matWorld = matScale * g_pSkyBox->m_matWorld;
g_pSkinMesh = new CSkinMesh(g_pd3dDevice); //创建角色网格
g_pSkinMesh->LoadFromXFile("QD.X");
D3DXMatrixScaling(&matScale, 10.0f, 10.0f, 10.0f);
D3DXMatrixRotationY(&matRotation, D3DX_PI);
g_pSkinMesh->m_matWorld = matScale * matRotation * g_pSkinMesh->m_matWorld;
g_pSkinMesh->m_vPos = D3DXVECTOR3(g_pSkinMesh->m_matWorld._41, g_pSkinMesh->m_matWorld._42, g_pSkinMesh->m_matWorld._43);
D3DXVec3TransformCoord(&g_pSkinMesh->m_vDirection,&g_pSkinMesh->m_vDirection,&matRotation);
D3DXVECTOR3 vEyePt( 0.0f, 30.0f, -50.0f );//-(float)g_czHeight
D3DXVECTOR3 vUp( 0.0f, 1.0f, 0.0f );
D3DXVECTOR3 vLookat = g_pSkinMesh->m_vPos;
vLookat.y += 15.0f;
g_pCamera = new Camera(vEyePt,vLookat,vUp);
return S_OK;
}
//地形碰撞
bool TerrainCollision()
{
D3DXVECTOR3 dis = g_pSkinMesh->m_vPos - g_pTerrainMap[0].p;
int dx,dz;
dx = abs(dis.x) / EDGE_LENGTH;
dz = abs(dis.z) / EDGE_LENGTH;
D3DXVECTOR3 v0,v1,v2;
//计算网格落在哪个三角形上面
D3DXVECTOR3 temp = g_pSkinMesh->m_vPos - g_pTerrainMap[(dz+1)*g_cxHeight+dx].p;
if(temp.z >= temp.x)
{
v0 = g_pTerrainMap[dz*g_cxHeight + dx].p;
v1 = g_pTerrainMap[dz*g_cxHeight + dx + 1].p;
v2 = g_pTerrainMap[(dz+1)*g_cxHeight + dx].p;
}
else
{
v0 = g_pTerrainMap[(dz+1)*g_cxHeight+dx].p;
v1 = g_pTerrainMap[dz*g_cxHeight+dx+1].p;
v2 = g_pTerrainMap[(dz+1)*g_cxHeight+dx+1].p;
}
D3DXVECTOR3 vRayPos,vRayDir;
vRayPos = g_pSkinMesh->m_vPos;
vRayPos.y += 20.0f;
vRayDir = D3DXVECTOR3(0.0f,-1.0f,0.0f);
float fInterDis = 0.0f;
if(D3DXIntersectTri(&v0,&v1,&v2,&vRayPos,&vRayDir,NULL,NULL,&fInterDis))
{
g_pSkinMesh->m_matWorld._42 = g_pSkinMesh->m_vPos.y += (20.0f-fInterDis);
g_pCamera->m_vLookat.y += (20.0f-fInterDis);
g_pCamera->m_vEye.y += (20.0f-fInterDis);
return true;
}
return false;
}
//角色的前后移动
void MoveFrontBack(float fMove)
{
g_pSkinMesh->SetAnimationName("walk");
g_pSkinMesh->m_vPos.x = g_pSkinMesh->m_matWorld._41+=(g_pSkinMesh->m_vDirection.x*fMove);
g_pSkinMesh->m_vPos.y = g_pSkinMesh->m_matWorld._42+=(g_pSkinMesh->m_vDirection.y*fMove);
g_pSkinMesh->m_vPos.z = g_pSkinMesh->m_matWorld._43+=(g_pSkinMesh->m_vDirection.z*fMove);
g_pCamera->m_vLookat+=(g_pSkinMesh->m_vDirection*fMove);
g_pCamera->m_vEye+=(g_pSkinMesh->m_vDirection*fMove);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -