#include "..\..\GameEngine\GameEngine_Common.h"
#include "LODTerrain.h"
#include "Frustum.h"
#include "Camera.h"
CLODTerrain::CLODTerrain(LPDIRECT3DDEVICE9 pd3dDevice,bool bUseHeightFile){
m_pd3dDevice=pd3dDevice;
m_pFrustum=new CFrustum();
m_iTerrainSize=1024;
m_pbQuadMat=new bool[(m_iTerrainSize+1)*(m_iTerrainSize+1)];
m_fHeightScale=1.0f;
m_pucHeightData=new unsigned char[(m_iTerrainSize+1)*(m_iTerrainSize+1)];
m_fResolution=5.0f;
m_fHeightDetail=8.0f;
m_iTexMapRepeatNum=10;
m_bUseHeightFile=bUseHeightFile;
}
CLODTerrain::~CLODTerrain(){
delete[] m_pbQuadMat;
delete[] m_pucHeightData;
if(m_pVertexBuffer!=NULL){
m_pVertexBuffer->Release();
m_pVertexBuffer=NULL;
}
if(m_pTexture!=NULL){
m_pTexture->Release();
m_pTexture=NULL;
}
}
bool CLODTerrain::InitTerrain(TCHAR* szHeightFile,TCHAR* szTextureFile){
if(m_bUseHeightFile){
if(!InitTerrainByFile(szHeightFile,szTextureFile)){
return false;
}
}
else{
if(!InitTerrainByFun(szTextureFile)){
return false;
}
}
return true;
}
bool CLODTerrain::InitTerrainByFun(char* szTextureFile){
if(!InitQuadMat())
return false;
if(!InitVertexBuf())
return false;
if(FAILED(D3DXCreateTextureFromFile(m_pd3dDevice,szTextureFile,&m_pTexture)))
return false;
return true;
}
bool CLODTerrain::InitTerrainByFile(TCHAR* szHeightFile,TCHAR* szTextureFile){
m_bUseHeightFile=true;
if(!InitQuadMat())
return false;
if(!InitVertexBuf())
return false;
if(!LoadHeightData(szHeightFile))
return false;
if(FAILED(D3DXCreateTextureFromFile(m_pd3dDevice,szTextureFile,&m_pTexture)))
return false;
return true;
}
bool CLODTerrain::InitQuadMat(){
if(!m_pbQuadMat){
MessageBox(NULL,"创建地形标志数组内存不足","提示",0);
return false;
}
for(int x=0;x<=m_iTerrainSize;x++){
for(int z=0;z<=m_iTerrainSize;z++){
SetQuadMatData(x,z,false);
}
}
return true;
}
bool CLODTerrain::InitVertexBuf(){
if(FAILED(m_pd3dDevice->CreateVertexBuffer(10*sizeof(CUSTOMVERTEX),0,CUSTOMVERTEX_FVF,
D3DPOOL_MANAGED,&m_pVertexBuffer,NULL))){
MessageBox(NULL,"创建顶点缓冲区失败","提示",0);
return false;
}
return true;
}
bool CLODTerrain::LoadHeightData(TCHAR* szFileName){
FILE* pFile;
pFile=fopen(szFileName,"rb");
if(!pFile){
return false;
}
if(!m_pucHeightData){
MessageBox(NULL,"创建地形数据内存不足","提示",0);
}
fread(m_pucHeightData,1,(m_iTerrainSize+1)*(m_iTerrainSize+1),pFile);
fclose(pFile);
return true;
}
float CLODTerrain::GenerateHeightData(float x,float z){
return 8*sinf(x)*cosf(z/10)+1.0f;
}
bool CLODTerrain::GetQuadMatData(int x,int z){
return m_pbQuadMat[m_iTerrainSize*z+x];
}
void CLODTerrain::SetQuadMatData(int x,int z,bool b){
if(x>=0 && x<=m_iTerrainSize && z>=0 && z<=m_iTerrainSize){
m_pbQuadMat[m_iTerrainSize*z+x]=b;
}
}
void CLODTerrain::TrimNodeSplit(int iX,int iZ,int iNodeLength){ //去除不合法的分割
int iChildNodeOffset=iNodeLength/4;
int iChildNodeLength=iNodeLength/2;
if(iNodeLength>=4 && GetQuadMatData(iX,iZ)==true){
if((iX+iNodeLength)<=m_iTerrainSize && GetQuadMatData(iX+iNodeLength,iZ)==false){
SetChildNodeFalse(iX+iChildNodeOffset,iZ+iChildNodeOffset,iChildNodeLength);
SetChildNodeFalse(iX+iChildNodeOffset,iZ-iChildNodeOffset,iChildNodeLength);
}
if((iZ-iNodeLength)>=0 && GetQuadMatData(iX,iZ-iNodeLength)==false){
SetChildNodeFalse(iX-iChildNodeOffset,iZ-iChildNodeOffset,iChildNodeLength);
SetChildNodeFalse(iX+iChildNodeOffset,iZ-iChildNodeOffset,iChildNodeLength);
}
if((iX-iNodeLength)>=0 && GetQuadMatData(iX-iNodeLength,iZ)==false){
SetChildNodeFalse(iX-iChildNodeOffset,iZ+iChildNodeOffset,iChildNodeLength);
SetChildNodeFalse(iX-iChildNodeOffset,iZ-iChildNodeOffset,iChildNodeLength);
}
if((iZ+iNodeLength)<=m_iTerrainSize && GetQuadMatData(iX,iZ+iNodeLength)==false){
SetChildNodeFalse(iX-iChildNodeOffset,iZ+iChildNodeOffset,iChildNodeLength);
SetChildNodeFalse(iX+iChildNodeOffset,iZ+iChildNodeOffset,iChildNodeLength);
}
TrimNodeSplit(iX+iChildNodeOffset,iZ+iChildNodeOffset,iChildNodeLength);
TrimNodeSplit(iX+iChildNodeOffset,iZ-iChildNodeOffset,iChildNodeLength);
TrimNodeSplit(iX-iChildNodeOffset,iZ+iChildNodeOffset,iChildNodeLength);
TrimNodeSplit(iX-iChildNodeOffset,iZ-iChildNodeOffset,iChildNodeLength);
}
else if(GetQuadMatData(iX,iZ)==false){
SetChildNodeFalse(iX,iZ,iNodeLength);
}
}
void CLODTerrain::SetChildNodeFalse(int iX,int iZ,int iNodeLength){
int iChildNodeOffset=iNodeLength/4;
int iChildNodeLength=iNodeLength/2;
SetQuadMatData(iX,iZ,false);
if(iNodeLength>=4){
SetChildNodeFalse(iX+iChildNodeOffset,iZ+iChildNodeOffset,iChildNodeLength);
SetChildNodeFalse(iX+iChildNodeOffset,iZ-iChildNodeOffset,iChildNodeLength);
SetChildNodeFalse(iX-iChildNodeOffset,iZ-iChildNodeOffset,iChildNodeLength);
SetChildNodeFalse(iX-iChildNodeOffset,iZ+iChildNodeOffset,iChildNodeLength);
}
}
void CLODTerrain::UpdateTerrain(CCamera* pCamera){
SplitNode(m_iTerrainSize/2.0f,m_iTerrainSize/2.0f,m_iTerrainSize,pCamera);
TrimNodeSplit(m_iTerrainSize/2,m_iTerrainSize/2,m_iTerrainSize);
}
void CLODTerrain::Render(){
m_pd3dDevice->Clear(0,NULL,D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,D3DCOLOR_XRGB(0,0,0),1.0f,0);
m_pd3dDevice->SetRenderState(D3DRS_LIGHTING,false);
// m_pd3dDevice->SetSamplerState(0,D3DSAMP_MINFILTER,D3DTEXF_LINEAR);
// m_pd3dDevice->SetSamplerState(0,D3DSAMP_MAGFILTER,D3DTEXF_LINEAR);
m_pd3dDevice->SetFVF(CUSTOMVERTEX_FVF);
// m_pd3dDevice->SetTexture(0,m_pTexture);
m_pd3dDevice->BeginScene();
RenderNode(m_iTerrainSize/2.0f,m_iTerrainSize/2.0f,m_iTerrainSize);
m_pd3dDevice->EndScene();
m_pd3dDevice->Present(NULL,NULL,NULL,NULL);
}
void CLODTerrain::SplitNode(float x,float z,int iNodeLength,CCamera* pCamera){
int iX=(int)x;
int iZ=(int)z;
float y;
if(!m_bUseHeightFile)
y=m_pucHeightData[iZ*m_iTerrainSize+iX]*m_fHeightScale; //该点的高度
else
y=GenerateHeightData(x,z)*m_fHeightScale;
float fCameraDistance;
float fRule;
bool bSplit;
int iChildNodeLength;
float fChildNodeOffset;
//节点不在视截体内,设置标志后返回
m_pFrustum->GetFrustum(m_pd3dDevice,0.0f);
if(m_pFrustum->CheckCube(x,y,z,(float)iNodeLength))
m_pbQuadMat[m_iTerrainSize*iZ+iX]=true;
else{
m_pbQuadMat[m_iTerrainSize*iZ+iX]=false;
return;
}
//距离检测
D3DXVECTOR3* pCameraPos=NULL;
pCameraPos=pCamera->GetCameraPos();
fCameraDistance=(float)(fabs(pCameraPos->x-x)+
fabs(pCameraPos->y-y)+
fabs(pCameraPos->z-z));
//变形幅度估值
if(m_bUseHeightFile==true){
int iVertexOffset=iNodeLength>>1;
int iChildNodeLength=iVertexOffset>>1;
float fArrayHeightEva[9];
fArrayHeightEva[0]=m_pucHeightData[m_iTerrainSize*iZ+iX]*m_fHeightScale;
fArrayHeightEva[1]=m_pucHeightData[m_iTerrainSize*iZ+(iX+iVertexOffset)]*m_fHeightScale;
fArrayHeightEva[2]=m_pucHeightData[m_iTerrainSize*(iZ-iVertexOffset)+iX]*m_fHeightScale;
fArrayHeightEva[3]=m_pucHeightData[m_iTerrainSize*iZ+(iX-iVertexOffset)]*m_fHeightScale;
fArrayHeightEva[4]=m_pucHeightData[m_iTerrainSize*(iZ+iVertexOffset)+iX]*m_fHeightScale;
fArrayHeightEva[5]=m_pucHeightData[m_iTerrainSize*(iZ+iChildNodeLength)+(iX+iChildNodeLength)]*m_fHeightScale;
fArrayHeightEva[6]=m_pucHeightData[m_iTerrainSize*(iZ-iChildNodeLength)+(iX+iChildNodeLength)]*m_fHeightScale;
fArrayHeightEva[7]=m_pucHeightData[m_iTerrainSize*(iZ-iChildNodeLength)+(iX-iChildNodeLength)]*m_fHeightScale;
fArrayHeightEva[8]=m_pucHeightData[m_iTerrainSize*(iZ+iChildNodeLength)+(iX-iChildNodeLength)]*m_fHeightScale;
float fMaxHeight=fArrayHeightEva[0];
float fMinHeight=fArrayHeightEva[0];
for(int i=1;i<9;i++){
if(fArrayHeightEva[i]>fMaxHeight)
fMaxHeight=fArrayHeightEva[i];
if(fArrayHeightEva[i]<fMinHeight)
fMinHeight=fArrayHeightEva[i];
}
float fHeightDiff=fMaxHeight-fMinH
vc++游戏编程源码.rar
需积分: 0 111 浏览量
更新于2008-10-09
收藏 15.89MB RAR 举报
《VC++游戏编程源码深度探索》
游戏编程是一门涉及多领域知识的综合性技术,而VC++作为Microsoft开发的一款强大的编程工具,被广泛应用于游戏开发。本资源库中的"vc++游戏编程源码.rar"提供了丰富的源代码实例,旨在帮助初学者和进阶者深入理解游戏编程的核心概念和技术。
我们要明确VC++在游戏编程中的角色。Visual C++不仅支持C++语言,还提供了方便的集成开发环境(IDE),以及对DirectX的无缝支持。DirectX是微软推出的一套API,包括Direct3D、DirectInput、DirectSound等多个组件,它们为游戏开发者提供了底层硬件访问的能力,使得游戏能够高效运行并呈现高质量的图形和音频效果。
在"vc++游戏编程源码.rar"中,你可以找到各种游戏编程的关键元素的实现:
1. **游戏循环**:游戏的基础框架,如主循环,负责处理输入、更新游戏状态、渲染画面等。
2. **图形渲染**:通过Direct3D或OpenGL,学习如何绘制2D和3D图形,理解坐标系统、变换、光照和纹理映射等概念。
3. **物理模拟**:观察如何实现简单的碰撞检测、物体运动和重力等物理效果。
4. **游戏对象管理**:了解如何创建、销毁、存储和管理游戏中的角色、道具等对象。
5. **用户输入处理**:研究如何接收和响应键盘、鼠标等输入设备的操作,实现玩家控制。
6. **音频处理**:通过DirectSound或OpenAL,学习如何播放背景音乐和音效。
7. **AI算法**:部分源码可能包含简单的AI实现,如寻路算法或敌人的行为模式。
8. **网络编程**:如果涉及到多人在线游戏,可以看到网络通信的实现,如TCP/IP连接和数据包处理。
9. **资源管理**:学习如何有效地加载、存储和释放游戏资源,如图像、音频和模型。
10. **游戏状态管理**:了解如何在不同游戏阶段(如菜单、游戏进行、暂停等)之间切换。
通过这些源码,你可以逐步解构一个游戏的内部运作机制,理解每部分代码的功能和作用。同时,直接运行的EXE文件让你有机会直观地看到代码的实际效果,从而加深理解。对于初学者,这是一份宝贵的实践资料,可以对照源码边学边练;对于有经验的开发者,这些示例代码则可能提供灵感或解决方案。
"vc++游戏编程源码.rar"是一个极好的学习资源,它将理论知识与实践相结合,帮助你提升游戏编程技能,无论你是初涉此道还是希望进一步提升,都能从中受益匪浅。记得动手实践,将理论付诸于代码,这是学习编程最有效的途径。祝你在游戏编程的世界里探索无尽的乐趣!
diannaoqingx
- 粉丝: 5
- 资源: 14
最新资源
- 仿真模拟电击穿路径的模型,可以自定义模型形状,利用有限元comsol相场法模拟,采用PDE模块自定义方程,通过求解偏微分方程来实现击穿路径的可视化
- MK3600双目活体超宽动态人脸识别一体机参数介绍及应用场景
- 10bit 高速SAR ADC基于0.18um工艺的电路,拿去直接可以仿真性能,有效位ENOB9.6bit,SFDR为63.7dB,逐次逼近型模数转器基于virtuoso
- 三级分销凹凸社区带短视频原生双端APP源码 抖音 段子 黄瓜分享推广+搭建视频教程
- 1233211234567
- 泵机群伺服质量管控大数据平台技术方案
- 数学公式编辑器安装包,好用便捷,推荐使用Axmath2.5版本公式编辑器
- 双馈风力发电机DFIG滑模控制SMC MATLAB Simulink仿真模型(成品) 1、采用非线性控制滑模控制策略 2、采用PI调节器为外环滑模控制器SMC作为内环控制,跟传统的双PI环相比,功率的
- 国产数据库:高斯数据库连接工具
- phoenix-winphlash-v1.7.16.0