Terrain.cpp
上传用户:cjwanglu
上传日期:2013-07-10
资源大小:4744k
文件大小:6k
源码类别:

游戏

开发平台:

Visual C++

  1. #include "stdafx.h"
  2. #include "Terrain.h"
  3. CTerrain::CTerrain(HINSTANCE hinst,LPDIRECT3DDEVICE9 d3dd)
  4. {
  5. m_pD3DDevice=d3dd;
  6.     m_dwRow=0;
  7. m_dwCol=0;
  8. m_fcell=30;
  9. m_fHeight=800;
  10. m_hInst=hinst;
  11. SetTexture();
  12. CreateVertex();
  13. }
  14. CTerrain::~CTerrain()
  15. {
  16. m_pVb->Release();
  17. m_pIb->Release();
  18. m_pTx->Release();
  19. delete []m_pHeightData;
  20. }
  21. D3DXVECTOR3 CTerrain::GetTriangeNormal(D3DXVECTOR3* vV1, D3DXVECTOR3* vV2, D3DXVECTOR3* vV3)
  22. {
  23. D3DXVECTOR3 vNormal;
  24. D3DXVECTOR3 v1;
  25. D3DXVECTOR3 v2;
  26. D3DXVec3Subtract(&v1, vV2, vV1);
  27. D3DXVec3Subtract(&v2, vV3, vV1);
  28. D3DXVec3Cross(&vNormal, &v1, &v2);
  29. D3DXVec3Normalize(&vNormal, &vNormal);
  30. return vNormal;
  31. }
  32. void CTerrain::CreateVertex()
  33. {   
  34. VERTEX * VertexBuffer;
  35.     DWORD * IndexBuffer;
  36. D3DXVECTOR3 vNormal;
  37. DWORD Vertex1;
  38. DWORD Vertex2;
  39. DWORD Vertex3;
  40. DWORD NumOfIndex;
  41. BITMAP bmp;
  42. HBITMAP hBmp;
  43. HBITMAP oldBmp;
  44. HDC hDC;
  45. hDC=CreateCompatibleDC(NULL);
  46. hBmp=(HBITMAP)LoadImage(m_hInst,"./res/map.bmp",IMAGE_BITMAP,m_dwRow,m_dwCol,LR_LOADFROMFILE);
  47. oldBmp=(HBITMAP)SelectObject(hDC,hBmp);
  48. GetObject(hBmp,sizeof(bmp),&bmp);
  49. m_dwRow=bmp.bmWidth;
  50. m_dwCol=bmp.bmHeight;
  51. m_pHeightData=new BYTE [m_dwRow*m_dwCol];
  52. DWORD color;
  53. for(DWORD i=0;i<m_dwRow;i++)
  54. {
  55. for(DWORD j=0;j<m_dwCol;j++)
  56. {
  57. color=GetPixel(hDC,j,i);
  58. m_pHeightData[i*m_dwCol+j]=*(BYTE*)&color;
  59. }
  60. }
  61.     WORD * NumOfShareFace=new WORD[m_dwRow*m_dwCol];
  62. D3DVECTOR *SumOfVertexNormal=new D3DVECTOR[m_dwRow*m_dwCol];
  63.  //oldBmp;
  64.  //hDC;
  65. //delete hBmp;
  66.    NumOfIndex=(m_dwRow-1)*(m_dwCol-1)*6;
  67.     m_pD3DDevice->CreateIndexBuffer(NumOfIndex*sizeof(DWORD),D3DUSAGE_WRITEONLY,D3DFMT_INDEX32,D3DPOOL_MANAGED,&m_pIb,NULL);
  68. m_pIb->Lock(0,0,(void **)&IndexBuffer,0);//(m_dwRow-1)*(m_dwCol-1)*6*sizeof(DWORD)
  69. DWORD k=0,a=0,b=0,c=0;
  70. for(DWORD i=0;i<m_dwRow-1;i++)
  71. {
  72. for(DWORD j=0;j<m_dwCol-1;j++)
  73. {   a=i*(m_dwCol)+j;
  74.     b=(i+1)*(m_dwCol)+j;
  75. c=i*(m_dwCol)+j+1;
  76. IndexBuffer[k+0]=a;
  77. IndexBuffer[k+1]=b;
  78. IndexBuffer[k+2]=c;
  79. IndexBuffer[k+3]=c;
  80. IndexBuffer[k+4]=b;
  81. IndexBuffer[k+5]=b+1;
  82. k+=6;
  83. }
  84. }
  85.   
  86. m_pIb->Unlock();
  87. float tu=0,tv=-0.5;
  88. m_pD3DDevice->CreateVertexBuffer(m_dwRow*m_dwCol*sizeof(VERTEX),D3DUSAGE_SOFTWAREPROCESSING,D3DFVF_VERTEX,D3DPOOL_DEFAULT,&m_pVb,NULL);
  89. m_pVb->Lock(0,m_dwRow*m_dwCol*sizeof(VERTEX),(void **)&VertexBuffer,D3DLOCK_DISCARD);
  90. for(DWORD i=0;i<m_dwRow*m_dwCol;i++)
  91. {
  92. NumOfShareFace[i]=0;
  93. SumOfVertexNormal[i]=D3DXVECTOR3(0,0,0);
  94. VertexBuffer[i].y=m_pHeightData[i]/255.0f*m_fHeight;
  95. VertexBuffer[i].x=m_fcell*(i%m_dwCol);
  96. VertexBuffer[i].z=m_fcell*(i/m_dwCol);
  97. tu=((tu+0.05f>1.0f)?(-1.0f):(tu+0.05f)); //tu=-1~1,-1~1,......
  98. if(i%m_dwCol==0) 
  99. {
  100. tv=((tv+0.05f>1.0f)?(-1.0f):(tv+0.05f));
  101. tu=0;
  102. }
  103. VertexBuffer[i].tu=tu>0?tu:-tu;
  104. VertexBuffer[i].tv=tv>0?tv:-tv;
  105. }
  106. for(DWORD i=0;i<NumOfIndex;i+=3)
  107. {
  108.      Vertex1=IndexBuffer[i];
  109.  Vertex2=IndexBuffer[i+1];
  110.  Vertex3=IndexBuffer[i+2];
  111.  vNormal=GetTriangeNormal(&D3DXVECTOR3(VertexBuffer[Vertex1].x,VertexBuffer[Vertex1].y,VertexBuffer[Vertex1].z),
  112.                       &D3DXVECTOR3(VertexBuffer[Vertex2].x,VertexBuffer[Vertex2].y,VertexBuffer[Vertex2].z),
  113.                               &D3DXVECTOR3(VertexBuffer[Vertex3].x,VertexBuffer[Vertex3].y,VertexBuffer[Vertex3].z));
  114.  NumOfShareFace[Vertex1]++;
  115.  NumOfShareFace[Vertex2]++;
  116.  NumOfShareFace[Vertex3]++;
  117.  SumOfVertexNormal[Vertex1].x+=vNormal.x;
  118.  SumOfVertexNormal[Vertex1].y+=vNormal.y;
  119.  SumOfVertexNormal[Vertex1].z+=vNormal.z;
  120.      SumOfVertexNormal[Vertex2].x+=vNormal.x;
  121.  SumOfVertexNormal[Vertex2].y+=vNormal.y;
  122.  SumOfVertexNormal[Vertex2].z+=vNormal.z;
  123.      SumOfVertexNormal[Vertex3].x+=vNormal.x;
  124.  SumOfVertexNormal[Vertex3].y+=vNormal.y;
  125.  SumOfVertexNormal[Vertex3].z+=vNormal.z;
  126. }
  127. for(DWORD i=0;i<(m_dwCol*m_dwRow);i++)
  128. {
  129. vNormal.x=SumOfVertexNormal[i].x/NumOfShareFace[i];
  130. vNormal.y=SumOfVertexNormal[i].y/NumOfShareFace[i];
  131. vNormal.z=SumOfVertexNormal[i].z/NumOfShareFace[i];
  132. D3DXVec3Normalize(&vNormal,&vNormal);
  133. VertexBuffer[i].nx=vNormal.x;
  134.         VertexBuffer[i].ny=vNormal.y;
  135. VertexBuffer[i].nz=vNormal.z;
  136. }
  137.    
  138. m_pVb->Unlock();
  139. }
  140. void CTerrain::SetTexture()
  141. {
  142. D3DXCreateTextureFromFile(m_pD3DDevice,"./res/floor.jpg",&m_pTx);
  143. }
  144. void CTerrain::RenerTerrain()
  145. {   static int kkk=0;
  146. VERTEX * VertexBuffer;
  147. SetMaterial();
  148.    // m_pD3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE,FALSE);
  149.    
  150.    // m_pD3DDevice->SetRenderState( D3DRS_ZWRITEENABLE,FALSE);
  151. m_pD3DDevice->SetTexture(0,m_pTx);
  152. m_pD3DDevice->SetStreamSource(0,m_pVb,0,sizeof(VERTEX));
  153. m_pD3DDevice->SetFVF(D3DFVF_VERTEX);
  154. m_pD3DDevice->SetIndices(m_pIb);
  155. m_pD3DDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,0,m_dwRow*m_dwCol,0,(m_dwRow-1)*(m_dwCol-1)*2);
  156. }
  157. void CTerrain::Translate()
  158. {
  159. D3DXMATRIX matWorld;
  160. D3DXMatrixTranslation(&matWorld,0.0f,0.0f,0.0f);
  161. m_pD3DDevice->SetTransform(D3DTS_WORLD,&matWorld);
  162. }
  163. float CTerrain::GetHeight(float x,float z)
  164. {
  165.         //x+=m_fcell*m_dwCol;
  166. //z+=m_fcell*m_dwRow;
  167. float rx,rz;
  168. rx=x/m_fcell;
  169. rz=z/m_fcell;
  170. long col1,row1,col2,row2;
  171. float h1,h2,h3,h4,ha,hb;
  172. col1=DWORD(rx);
  173. row1=DWORD(rz);
  174. if(col1>m_dwCol || col1<0 ||row1>m_dwRow || row1<0) return 0;
  175. else 
  176. { //双线性插值法计算
  177. col2=(col1==m_dwCol)?col1:col1+1;
  178. row2=(row1==m_dwRow)?row1:row1+1;
  179. h1=(m_pHeightData[row1*m_dwCol+col1]*m_fHeight/255.0f);
  180. h2=(m_pHeightData[row1*m_dwCol+col2]*m_fHeight/255.0f);
  181. h3=(m_pHeightData[row2*m_dwCol+col1]*m_fHeight/255.0f);
  182. h4=(m_pHeightData[row2*m_dwCol+col2]*m_fHeight/255.0f);
  183. ha=(h2*(rx-col1)+h1*(col2-rx));
  184. hb=(h4*(rx-col1)+h3*(col2-rx));
  185. return (hb*(rz-row1)+ha*(row2-rz));
  186. }
  187. }
  188. void CTerrain::SetMaterial()
  189. {
  190. ZeroMemory(&material,sizeof(material));
  191. material.Diffuse.r=material.Ambient.r=1.0f;
  192. material.Diffuse.g=material.Ambient.g=1.0f;
  193. material.Diffuse.b=material.Ambient.b=1.0f;
  194. material.Diffuse.a=material.Ambient.a=1.0f;
  195. material.Specular.r=0.0f;
  196. material.Specular.g=0.0f;
  197. material.Specular.b=0.0f;
  198. material.Specular.a=0.0f;
  199. material.Emissive.r=0.0f;
  200. material.Emissive.g=0.0f;
  201. material.Emissive.b=0.0f;
  202. material.Emissive.a=0.0f;
  203. m_pD3DDevice->SetMaterial(&material);
  204. }