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

DirextX编程

开发平台:

Visual C++

  1. #include "zfxd3dUtility.h"
  2. #include "terrain.h"
  3. #include ".terrain.h"
  4. #define MINELEV 0.0f
  5. CZFXTerrain::CZFXTerrain(void)
  6. {
  7. m_iWidth=0;
  8. m_iHeight=0;
  9. m_pVB=NULL;
  10. m_pIB=NULL;
  11. m_pTexture = NULL;
  12. }
  13. CZFXTerrain::~CZFXTerrain(void)
  14. {
  15. SAFE_RELEASE(m_pVB);
  16. SAFE_RELEASE(m_pIB);
  17. SAFE_RELEASE(m_pTexture);
  18. }
  19. bool CZFXTerrain::RenderTerrain( LPDIRECT3DDEVICE9 pd3dDevice, D3DFILLMODE Flag)
  20. {
  21. if( NULL == m_pVB )
  22. {
  23. MessageBox( NULL, "地形未创建或未成功创建", "渲染地形失败", MB_OK );
  24. return false;
  25. }
  26.     // set material
  27. D3DMATERIAL9 material;
  28. ZeroMemory( &material, sizeof(D3DMATERIAL9) );
  29. material.Ambient.r = material.Ambient.g = material.Ambient.b = material.Ambient.a = 1.0f;
  30. material.Diffuse.r = material.Diffuse.g = material.Diffuse.b = material.Diffuse.a = 1.0f;
  31. material.Specular.r = material.Specular.g = material.Specular.b = material.Specular.a = 1.0f;
  32. pd3dDevice->SetMaterial( &material );
  33. // set lighting
  34. D3DLIGHT9 light;
  35. ZeroMemory( &light, sizeof(light) );
  36. light.Type = D3DLIGHT_DIRECTIONAL;
  37. light.Diffuse.r = 0.5f;
  38. light.Diffuse.g = 0.5f;
  39. light.Diffuse.b = 0.5f;
  40. light.Diffuse.a = 0.5f;
  41. light.Direction.x = -3.0f; light.Direction.y = -3.0f; light.Direction.z = 0.0f;
  42. pd3dDevice->SetLight( 0, &light );
  43. pd3dDevice->LightEnable( 0, TRUE );
  44. pd3dDevice->SetRenderState( D3DRS_AMBIENT, 0xff444444 );
  45. // set render state
  46. pd3dDevice->SetRenderState(D3DRS_FILLMODE, Flag);
  47. // set texture
  48. pd3dDevice->SetTexture(0, m_pTexture);
  49. // Rendering
  50. pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX );
  51. pd3dDevice->SetStreamSource( 0, m_pVB, 0, sizeof(CUSTOMVERTEX) );
  52. pd3dDevice->SetIndices(m_pIB);
  53. pd3dDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, // PrimitiveType
  54. 0,                  // BaseVertexIndex
  55. 0,                  // MinIndex
  56. m_iWidth*m_iHeight,                  // NumVertices
  57. 0,                  // StartIndex
  58. 2*(m_iWidth - 1) * (m_iHeight -1) ); // PrimitiveCount
  59. return true;
  60. }
  61. void CZFXTerrain::OnDestroyDevice()
  62. {
  63. SAFE_RELEASE(m_pVB);
  64. SAFE_RELEASE(m_pIB);
  65. SAFE_RELEASE(m_pTexture);
  66. }
  67. bool CZFXTerrain::CreateTerrain( LPDIRECT3DDEVICE9 pd3dDevice, int iWidth, int iHeight, float fWidth, float fHeight, 
  68. float height[][200], LPCTSTR strTexFileName )
  69. {
  70. m_iWidth  = iWidth;
  71. m_iHeight = iHeight;
  72. // 创建纹理
  73. if(strTexFileName != NULL)
  74. {
  75. if( FAILED( D3DXCreateTextureFromFile( pd3dDevice, strTexFileName, &m_pTexture )))
  76. {
  77. m_pTexture = NULL;
  78. }
  79. }
  80. else
  81. {
  82. m_pTexture = NULL;
  83. }
  84. CUSTOMVERTEX* vertices;
  85. vertices = new CUSTOMVERTEX[iWidth * iHeight];
  86. //// 调试用语句
  87. //float fMin = 100.0f;
  88. //float fMax = -100.0f;
  89. //// 调试用语句end
  90. for(int i=0;i<iHeight;i++)
  91. {
  92. for(int j=0;j<iWidth;j++)
  93. {
  94. //求出顶点的位置
  95. float x = (((float)(j-iWidth/2))*fWidth)/(float)iWidth;
  96. float y = (float)(height[i][j]-MINELEV)/2.0f;
  97. //// 调试用语句
  98. //if( y < -20.0f )
  99. // fMin = y;
  100. //if( y < fMin )
  101. // fMin = y;
  102. //if( y > fMax )
  103. // fMax = y;
  104. //// 调试用语句end
  105. float z = (((float)(i-iHeight/2))*fHeight)/(float)iHeight;
  106. vertices[i*(iWidth)+j].position = D3DXVECTOR3( x, y, z);
  107. //确定顶点的颜色
  108. vertices[i*(iWidth)+j].color = 0xffffffff;
  109. //求该点的法线向量,两向量叉乘
  110. //     / (i+1,j)
  111. //     ||
  112. //     ||<----(i,j+1)
  113. //    (i,j)
  114. float deltaHeight1, deltaHeight2;
  115. if(i<iHeight-1)
  116. deltaHeight1 = float(height[i][j]-height[i+1][j]);
  117. else
  118. deltaHeight1 = float(height[i-1][j]-height[i][j]);
  119. if(j<iWidth-1)
  120. deltaHeight2 = float(height[i][j+1]-height[i][j]);
  121. else
  122. deltaHeight2 = float(height[i][j]-height[i][j-1]);
  123. D3DXVECTOR3 vec1( -1.0f, 0.0f, deltaHeight1 );
  124. D3DXVECTOR3 vec2(  0.0f, 1.0f, deltaHeight2 );
  125. D3DXVec3Cross( &vertices[i*(iWidth)+j].normal, &vec1, &vec2 );
  126. // ASSERT(vertices[i*(iHeight+1)+j].normal
  127. //得到顶点的纹理坐标
  128. vertices[i*(iWidth)+j].tu = (float)i*20.0f/(float)iWidth;
  129. vertices[i*(iWidth)+j].tv = (float)j*20.0f/(float)iHeight;
  130. }
  131. }
  132. // WORD的大小仅限于256*256,所以当indices数组中某元素大于256*256时,将发生溢出
  133. // 相应的,创建索引缓冲的时候,D3DFMT_INDEX16需替换成D3DFMT_INDEX32
  134.     DWORD* indices;
  135. indices=new DWORD[6*(iWidth-1)*(iHeight-1)];
  136. int baseIndex = 0;
  137. for(DWORD i=0;i<(DWORD)iHeight-1;i++)
  138. {
  139. for(DWORD j=0;j<(DWORD)iWidth-1;j++)
  140. {
  141. indices[baseIndex]=i*(DWORD)iWidth+j;
  142. indices[baseIndex+1]=(i+1)*(DWORD)iWidth+j;
  143.             indices[baseIndex+2]=(i+1)*(DWORD)iWidth+j+1;
  144.             indices[baseIndex+3]=i*(DWORD)iWidth+j;
  145.             indices[baseIndex+4]=(i+1)*(DWORD)iWidth+j+1;
  146.             indices[baseIndex+5]=i*(DWORD)iWidth+j+1;
  147. baseIndex+=6;
  148. }
  149. }
  150.     if( FAILED( pd3dDevice->CreateIndexBuffer( 6*(iHeight-1)*(iWidth-1)*sizeof(DWORD),
  151.            D3DUSAGE_WRITEONLY, D3DFMT_INDEX32, D3DPOOL_MANAGED, 
  152.        &m_pIB, NULL ) ) )
  153.     return false;
  154. if( FAILED( pd3dDevice->CreateVertexBuffer( (iHeight)*(iWidth)*sizeof(CUSTOMVERTEX),
  155.          0 /*Usage*/, D3DFVF_CUSTOMVERTEX, D3DPOOL_MANAGED, &m_pVB, NULL )))
  156.     return  false;
  157. VOID* pVertices;
  158. if( FAILED( m_pVB->Lock( 0, (iHeight)*(iWidth)*sizeof( CUSTOMVERTEX ), (void**)&pVertices, 0 ) ) )
  159. return false;
  160.       memcpy( pVertices, vertices, (iHeight)*(iWidth)*sizeof( CUSTOMVERTEX ) );
  161.  m_pVB->Unlock();
  162. VOID* pIndices;
  163. if( FAILED( m_pIB->Lock( 
  164. 0,                 // Fill from start of the buffer
  165. 6*(iHeight-1)*(iWidth-1)*sizeof(DWORD),// Size of the data to load
  166. (void**)&pIndices,  // Returned index data
  167. 0 ) )   )         // Send default flags to the lock
  168. {
  169. //SAFE_RELEASE(m_pIB);
  170. return false;
  171. }
  172. memcpy( pIndices, indices, 6*(iHeight-1)*(iWidth-1)*sizeof(DWORD) );
  173. m_pIB->Unlock();
  174. delete [] vertices;
  175. delete [] indices;
  176. return false;
  177. }