⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 winmain.cpp

📁 Camera的源文件只是一部分Camera的源文件只是一部分
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#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 + -