zfxLODTerrain.h
上传用户:junlon
上传日期:2022-01-05
资源大小:39075k
文件大小:6k
源码类别:

DirextX编程

开发平台:

Visual C++

  1. //--------------------------------------------------------------------------------------
  2. // 文件: zfxLODTerrain.h, 作者:曾凡喜
  3. //
  4. // 封装了 LOD地形节点类CZFXLODTrnNode 和LOD地形类CZFXLODTerrain ,
  5. //
  6. // 
  7. //
  8. // 版权归作者所有,不得用于商业用途
  9. //--------------------------------------------------------------------------------------
  10. #ifndef __ZFXLODTERRAIN__H__INCLUDED__
  11. #define __ZFXLODTERRAIN__H__INCLUDED__
  12. #include "zfxFrustum.h"
  13. #include "zfxCamera.h"
  14. typedef struct ZFXNODEPOSSIZE{
  15. public:
  16. ZFXNODEPOSSIZE() {};
  17. ZFXNODEPOSSIZE( UINT _x, UINT _y, UINT _size ) {x = _x; y = _y; size = _size;}
  18. UINT x;
  19. UINT y;
  20. UINT size;
  21. }ZFXNODEPOSSIZE;
  22. typedef struct tagZFXTRNVERTEX{
  23. D3DXVECTOR3 position; // The position of the vertex.
  24. D3DXVECTOR3 normal;   // The nomal Vector.
  25. D3DCOLOR    color;    // The color
  26. FLOAT       tu, tv;   // The texture coordinates
  27. }ZFXTRNVERTEX;
  28. #define D3DFVF_ZFXTRNVERTEX  D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_DIFFUSE|D3DFVF_TEX1
  29. typedef enum { HEADNODE = 0, TOPLEFT, BOTTOMLEFT, BOTTOMRIGHT, TOPRIGHT } LODNodeEnum;
  30. class CZFXLODTrnNode{
  31. public:
  32. CZFXLODTrnNode();
  33. CZFXLODTrnNode( ZFXNODEPOSSIZE nodePosSize );
  34. ~CZFXLODTrnNode();
  35. public:
  36. // 公有成员
  37. // 父节点
  38. CZFXLODTrnNode* m_pParentNode;
  39. // 子节点
  40. CZFXLODTrnNode* m_pTLChildNode;
  41. CZFXLODTrnNode* m_pBLChildNode;
  42. CZFXLODTrnNode* m_pTRChildNode;
  43. CZFXLODTrnNode* m_pBRChildNode;
  44. protected:
  45. ZFXNODEPOSSIZE m_nodePosSize;
  46. public:
  47. // 方法
  48. // 分裂节点
  49. void SplitNode();
  50. ZFXNODEPOSSIZE GetPosSize() { return m_nodePosSize; }
  51. // 属性
  52. public:
  53. BOOL IsSplit();
  54. LODNodeEnum m_EnumValue;
  55. UINT  m_level;  // m_level越低,LOD级别越高,节点细节越好,头节点的m_level最高
  56. bool m_bIsLeaf; // 表明该节点是否叶子节点,初始化为true
  57. bool m_bReachAcceptableLevel; // 表明该节点的level是否已足够低,初始化为false
  58. bool m_bTouched; // 遍历四叉树的时候是否访问过该节点,初始化为false
  59. bool m_bIsVisible; // 表明该节点是否可见,初始化为false
  60. };
  61. class CZFXLODTerrain{
  62. public:
  63. CZFXLODTerrain( LPCTSTR strFileName );  //height == width, 且都是2^n + 1
  64. CZFXLODTerrain();
  65. ~CZFXLODTerrain();
  66. public:
  67. // 公有方法
  68. HRESULT InitShader(LPDIRECT3DDEVICE9 pd3dDevice);
  69. void InitQuadTree();
  70. void SetDimesion( float width, float height/*地形的几何尺寸*/, D3DXVECTOR2 centerPt/*地形的中点位置*/ );
  71. void LoadTextureFromFile( LPDIRECT3DDEVICE9 pd3dDevice, LPCTSTR lowTexFile, LPCTSTR highTexFile );
  72. void CreateTerrain( LPDIRECT3DDEVICE9 pd3dDevice, CZFXCamera* pCamera );
  73. void RenderTerrain( LPDIRECT3DDEVICE9 pd3dDevice, BOOL bFog );
  74. // 给定X坐标和Y坐标,求出该点的地形高度
  75. float GetTerrainElev( float x, float z );
  76. UINT GetTriangles() { return m_numNodeRendered << 3; }
  77. protected:
  78. // 将头结点生长成一棵完全的二叉树
  79. void GrowQuadTree(CZFXLODTrnNode* pNode);
  80. // 将该节点及其所以子节点的属性(m_bReachAcceptableLevel,m_bTouched,m_bIsVisible)修改为false
  81. void ClearTreeFlag(CZFXLODTrnNode* pNode);
  82. // 遍历四叉树,判断节点的可见性和它的level是否达到要求,并对节点进行标记
  83. void ClimbQuadTree(CZFXLODTrnNode* pNode, LPDIRECT3DDEVICE9 pd3dDevice);
  84. // 判断某个节点是否可见
  85. BOOL IsVisible(CZFXLODTrnNode* pNode, LPDIRECT3DDEVICE9 pd3dDevice);
  86. // 判断某个节点的level是否已足够低
  87. BOOL IsReachAcceptableLevel(CZFXLODTrnNode* pNode);
  88. // 得到节点的四个相邻节点的父节点,将它们的指针存储在一个数组里
  89. void GetAdjNodeParent4(CZFXLODTrnNode** pAdjNodeArray, CZFXLODTrnNode* pNode);
  90. // 查找相对位置为(x, y)的那个节点的父节点
  91. CZFXLODTrnNode* FindParentNode(UINT x, UINT y);
  92. // 查找相对位置为(x, y)的那个节点
  93. CZFXLODTrnNode* FindNode(UINT x, UINT y);
  94. // 遍历四叉树,寻找树中m_bReachAcceptableLevel == true的节点,并将所有符合条件的节点写进顶点数组和索引数组中
  95. void RefineNode(CZFXLODTrnNode* pNode);
  96. protected:
  97. /*UINT m_height;*/
  98. UINT m_width;
  99. CZFXLODTrnNode* m_pHeadNode;
  100. // 地形的几何尺寸及中心位置
  101. float m_fWidth;
  102. float m_fHeight;
  103. // m_GridWidth = m_fWidth/(m_width - 1);
  104. // m_GridHeight = m_fHeight/(m_width - 1);  为避免重复计算次数过多,将计算结果保存到一个变量当中
  105. float m_GridHeight; // 网格宽度,加快计算速度
  106. float m_GridWidth;  // 网格高度,加快计算速度
  107. D3DXVECTOR2 m_centerPt;
  108. // 可视裁减体
  109. CZFXFrustum m_frustum;
  110. // 摄像机
  111. CZFXCamera* m_pCamera;
  112. // 二维高程数组
  113. float** m_elevArray;
  114. // 二维法线向量数组
  115. D3DXVECTOR3 ** m_normalArray;
  116. // 纹理坐标数组
  117. float* m_tuArray;
  118. float* m_tvArray;
  119. // 需要渲染得节点数
  120. UINT m_numNodeRendered;
  121. // 顶点数组
  122. ZFXTRNVERTEX *m_vertexArray;
  123. // 索引数组
  124. WORD *m_indexArray;
  125. // 顶点索引
  126. UINT m_vertexIndex;
  127. // 索引缓冲索引
  128. UINT m_indexIndex;
  129. // 顶点缓冲
  130. LPDIRECT3DVERTEXBUFFER9 m_pVB;
  131. // 索引缓冲
  132.     LPDIRECT3DINDEXBUFFER9 m_pIB;
  133. // 纹理
  134. LPDIRECT3DTEXTURE9 m_lowTexture;
  135. LPDIRECT3DTEXTURE9 m_highTexture;
  136. // Shader
  137. IDirect3DVertexShader9* m_pVShader;
  138. IDirect3DPixelShader9 * m_pPShader;
  139. ID3DXConstantTable* m_pVConstTable;
  140. ID3DXConstantTable* m_pPConstTable;
  141. // Constant table
  142. };
  143. // 将该节点及其所以子节点的属性(m_bReachAcceptableLevel,m_bTouched,m_bIsVisible)修改为false
  144. inline void CZFXLODTerrain::ClearTreeFlag(CZFXLODTrnNode* pNode)
  145. {
  146. //pNode->m_bReachAcceptableLevel = false;
  147. //pNode->m_bIsVisible = false;
  148. pNode->m_bTouched = false;
  149. if(!pNode->m_pBLChildNode->m_bIsLeaf)
  150. {
  151. ClearTreeFlag( pNode->m_pBLChildNode );
  152. ClearTreeFlag( pNode->m_pTLChildNode );
  153. ClearTreeFlag( pNode->m_pTRChildNode );
  154. ClearTreeFlag( pNode->m_pBRChildNode );
  155. }
  156. {
  157. pNode->m_pBLChildNode->m_bTouched = false;
  158. pNode->m_pTLChildNode->m_bTouched = false;
  159. pNode->m_pTRChildNode->m_bTouched = false;
  160. pNode->m_pBRChildNode->m_bTouched = false;
  161. }
  162. }
  163. #endif // __ZFXLODTERRAIN__H__INCLUDED__