|

楼主 |
发表于 2005-11-16 11:48:00
|
显示全部楼层
Re:最近做的地表
由于采用了自己的PE游戏引擎,只能公布地图部分的算法代码,而且目前的算法代码只是初步实现了quadtree,没有优化,我打算采用ps重新写一次,稍后我会给大家一个可编译的文件包,到目前为止的地图代码:.h
///////////////////////////////////////////////////////////
// Polygon Engine Map
// Write by: Lingzhi
///////////////////////////////////////////////////////////
#ifndef __PE_Map_H__
#define __PE_Map_H__
#include "pe_def.h"
#include "pe_head.h"
#include "pe_math.h"
#include "pe_mixman.h"
#define PE_MAP_TEXMAXNUM 32 // 纹理的最多个数
#define PE_MAP_GENERATOR_QUADTREE // 是否使用四叉分割树来对地表处理
enum PE_Map_Script_T
{
PE_MAPSCRIPT_LOADMAP,
PE_MAPSCRIPT_TOTAL,
};
// 顶点
struct PE_MapVertexData_T
{
PE_FLOAT x,y,z; // 顶点数据
PE_FLOAT3 normal; // 顶点法线
PE_DWORD diffuse; // 颜色数据
PE_FLOAT u1,v1; // 第一层纹理
PE_FLOAT u2,v2; // 第二层纹理
};
// map Mesh
struct PE_MapMeshData_T
{
PE_UINT4 nIndex; // 位置索引
PE_BOOL bLoaded; // 是否装入完毕(用于多线程读取)
PE_FLOAT x,z; // 坐标偏移
PE_UINT4 nSide; // 边长
PE_FLOAT fTileSide; // 1个tile的边长
PE_TCHAR cHeightFile[PE_STR_LEN]; // 高度图文件(用于多线程读取)
PE_TCHAR cTexFile[PE_STR_LEN]; // 细节纹理设定文件(用于多线程读取)
PE_TCHAR cGroundFile[PE_STR_LEN]; // 地表纹理文件
PE_TCHAR cLightFile[PE_STR_LEN]; // 光照图设定文件
PE_UINT4 nGroundTexIndex; // 地表纹理
PE_UINT4 nLightTexSide; // 光照图的边长
PE_UINT4 *pLightTexBuffer; // 光照图的数据
PE_UINT4 nNumTex; // 细节纹理数量
PE_UINT4 nTexIndex[PE_MAP_TEXMAXNUM]; // 细节纹理的资源索引
PE_DWORD dwTexColor[PE_MAP_TEXMAXNUM]; // 细节纹理对应的颜色值(只在计算纹理映射表)
PE_FLOAT fHeightScale; // 高度系数
PE_UINT4 nHeightMapSide; // 高度图边长
PE_UINT1 *pHeightMapBuffer; // 高度图数据缓冲
PE_UINT4 nTexMapSide; // 纹理映射边长
PE_UINT1 *pTexMapBuffer; // 纹理映射数据
PE_FLOAT fDetailDistance; // 每隔多少距离,减少一个细节程度
PE_UINT1 nDetailHeight; // 每相差多少,增加一个细节程度
PE_UINT1 nReserved[3];
// 其他
#ifdef PE_MAP_GENERATOR_QUADTREE
//// 四叉分割树
PE_UINT1 *pDetailLevel; // 细节级别
PE_UINT1 *pDetailRender; // 需要显示的patch
PE_UINT1 *pDetailRenderFlag; // 第2级需要渲染的标志(标记哪个边的中点需要绘制)
#endif
void clear(IPERender* pRender)
{
PE_SAFEDELETE_ARRAY( pLightTexBuffer );
PE_SAFEDELETE_ARRAY( pHeightMapBuffer );
PE_SAFEDELETE_ARRAY( pTexMapBuffer );
#ifdef PE_MAP_GENERATOR_QUADTREE
PE_SAFEDELETE_ARRAY( pDetailLevel );
PE_SAFEDELETE_ARRAY( pDetailRender );
PE_SAFEDELETE_ARRAY( pDetailRenderFlag );
#endif
if( pRender )
{
}
}
};
// view param
struct PE_MapViewParam_T
{
PE_MapMeshData_T* pMapMesh;
PE_VECTOR3 *pEye, *pLookAt;
PE_FLOAT fDistance;
PE_FLOAT fViewRadianCos;
};
// 使用脚本命令
// loadmap 文件名 (返回值一直为1)
class CPEMap:public IPEMapMan
{
protected:
// 脚本声明
PE_SCRIPTCMD_DECLARE(PE_MAPSCRIPT_TOTAL);
// others
IPERender* m_pRender; // 渲染器
// 地图Mesh
CPEPoolArray< E_UINT4, PE_MapMeshData_T> m_MapMeshDataS;
PE_FLOAT m_fViewRadianCos; // 视角
PE_FLOAT m_fDistanceDetail; // 每距离多远增加一个细节
PE_FLOAT m_fHeightDetail; // 每相差多少高度增加一个细节
#ifdef PE_MAP_GENERATOR_QUADTREE
PE_MapVertexData_T m_MapMeshVertex[20];
PE_UINT4 m_nCountMapMeshVertex;
#endif
public:
virtual PE_BOOL OneTimeInit(PE_VOID);
virtual PE_BOOL FrameMove(PE_VOID);
virtual PE_BOOL Render(PE_VOID);
virtual PE_BOOL InvalidateDeviceObjects(PE_VOID);
virtual PE_BOOL RestoreDeviceObjects(PE_VOID);
virtual PE_BOOL FinalCleanup(PE_VOID);
virtual PE_UINT OnEngineMsg(PE_UINT4 unCom, PE_UINT4 unParam, PE_PVOID pValue, PE_PVOID pValue2);
// 渲染地图生成
// 设定地图显示参数
virtual PE_VOID SetParam(PE_FLOAT fViewRadianCos);
// 得到地表高度
virtual PE_FLOAT GetHeight(PE_FLOAT x, PE_FLOAT z);
// 其他需要调用的函数
virtual PE_BOOL LoadMap(PE_CTCHAR* pFilename);
virtual PE_BOOL LoadMap(PE_CCHAR* pFilename);
// 无限连续地图
virtual PE_UINT4 LoadMapMesh(PE_CTCHAR* pFilename, PE_BOOL bThread=PE_FALSE);
virtual PE_VOID DelMapMesh(PE_UINT4 nIndex);
virtual PE_VOID DelMapMesh(PE_VOID);
// 判断是否在水面附近(判断是否需要重新绘制水面的倒映)
virtual PE_BOOL IsNearWater(PE_FLOAT x, PE_FLOAT y, PE_FLOAT z);
// 得到水面绘制需要的世界矩阵
virtual PE_MATRIX* GetWaterWorldMatrix(PE_VOID);
// 开始水面绘制
virtual PE_VOID BeginRenderWater(PE_VOID);
// 结束水面绘制
virtual PE_VOID EndRenderWater(PE_VOID);
// 增加物体撞击(比如水花的模拟)
virtual PE_VOID AddBump(PE_FLOAT x, PE_FLOAT z, PE_FLOAT fSize);
CPEMap();
~CPEMap();
protected:
// 装入地图mesh(方便多线程读取)
PE_BOOL _LoadMapMesh(IPEFileMan* pFileMan, IPERender* pRender, PE_MapMeshData_T* pMapMesh);
// 读取高度图
PE_BOOL _LoadHeightMap(IPEFileMan* pFileMan, PE_CTCHAR* pFilename, PE_UINT4 nHeightMapSide, PE_UINT1** ppOutBuffer);
// 装入map的顶点光照纹理
PE_BOOL _LoadMapLightTex(IPEFileMan* pFileMan, PE_MapMeshData_T* pMapMesh);
// 创建map的顶点光照纹理
PE_BOOL _CreateMapLightTex(IPEFileMan* pFileMan, PE_MapMeshData_T* pMapMesh);
// 得到map mesh的指定点的高度
PE_FLOAT _GetMapMeshHeight(PE_MapMeshData_T* pMapMesh, PE_UINT4 x, PE_UINT4 z);
PE_BOOL _GetMapMeshHeight(PE_MapMeshData_T* pMapMesh, PE_FLOAT x, PE_FLOAT z, PE_FLOAT* pOutHeight);
PE_UINT1 _GetMapMeshTrueHeight(PE_MapMeshData_T* pMapMesh, PE_UINT4 x, PE_UINT4 z);
// 得到map mesh的指定点的细节纹理索引
PE_UINT4 _GetMapTexIndex(PE_MapMeshData_T* pMapMesh, PE_UINT4 x, PE_UINT4 z);
// 得到map mesh的指定点的光照值
PE_DWORD _GetMapLight(PE_MapMeshData_T* pMapMesh, PE_UINT4 x, PE_UINT4 z);
// 动态地图生成
#ifdef PE_MAP_GENERATOR_QUADTREE
PE_VOID _GenerateMapMesh_QuadTree(PE_MapViewParam_T* pViewParam, PE_UINT4 x, PE_UINT4 z, PE_UINT4 nEdgeLength);
PE_VOID _GenerateMapMeshFlag_QuadTree(PE_MapMeshData_T* pMapMesh);
PE_UINT4 _QuadTree_RenderPatch(PE_MapMeshData_T* pMapMesh, PE_UINT4 x, PE_UINT4 z, PE_UINT4 nEdgeLength);
PE_VOID _QuadTree_Render_AddVertex(PE_MapMeshData_T* pMapMesh, PE_UINT4 x, PE_UINT4 z, PE_UINT4 nEdgeLength, PE_UINT4 nWay);
#endif
};
#endif |
|