Cuboid.cpp
上传用户:whgydz
上传日期:2007-01-12
资源大小:2259k
文件大小:11k
源码类别:

其他书籍

开发平台:

HTML/CSS

  1. // Cuboid.cpp: implementation of the CCuboid class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "Cuboid.h"
  5. //////////////////////////////////////////////////////////////////////
  6. // Construction/Destruction
  7. //////////////////////////////////////////////////////////////////////
  8. CCuboid::CCuboid(LPDIRECT3DDEVICE8 pD3DDevice, float x, float y, float z)
  9. {
  10. m_pD3DDevice = pD3DDevice;
  11. m_pVertexBuffer = NULL;
  12. m_pIndexBuffer = NULL;
  13. m_pTexture = NULL;
  14. //Setup counts for this object
  15. m_dwNumOfVertices = 24;
  16. m_dwNumOfIndices  = 36;
  17. m_dwNumOfPolygons = 12;
  18. //Set a default size and position
  19. m_rWidth = 10.0;
  20. m_rHeight = 10.0;
  21. m_rDepth = 10.0;
  22. m_rX = x;
  23. m_rY = y;
  24. m_rZ = z;
  25. //Set material default values (R, G, B, A)
  26. D3DCOLORVALUE rgbaDiffuse  = {1.0, 1.0, 1.0, 0.0,};
  27. D3DCOLORVALUE rgbaAmbient  = {1.0, 1.0, 1.0, 0.0,};
  28. D3DCOLORVALUE rgbaSpecular = {0.0, 0.0, 0.0, 0.0,};
  29. D3DCOLORVALUE rgbaEmissive = {0.0, 0.0, 0.0, 0.0,};
  30. SetMaterial(rgbaDiffuse, rgbaAmbient, rgbaSpecular, rgbaEmissive, 0);
  31. //Initialize Vertex Buffer
  32.     if(SUCCEEDED(CreateVertexBuffer()))
  33. {
  34. if(CreateIndexBuffer())
  35. {
  36. UpdateVertices();
  37. }
  38. }
  39. }
  40. CCuboid::~CCuboid()
  41. {
  42. SafeRelease(m_pTexture);
  43. SafeRelease(m_pIndexBuffer);
  44. SafeRelease(m_pVertexBuffer);
  45. }
  46. DWORD CCuboid::Render()
  47. {
  48. m_pD3DDevice->SetStreamSource(0, m_pVertexBuffer, sizeof(CUBOID_CUSTOMVERTEX));
  49. m_pD3DDevice->SetVertexShader(CUBOID_D3DFVF_CUSTOMVERTEX);
  50. if(m_pTexture != NULL)
  51. {
  52. //A texture has been set. We want our texture to be shaded based
  53. //on the current light levels, so used D3DTOP_MODULATE.
  54. m_pD3DDevice->SetTexture(0, m_pTexture);
  55. m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
  56. m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
  57. m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT);
  58. }
  59. else
  60. {
  61. //No texture has been set
  62. m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG2);
  63. m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
  64. m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT);
  65. }
  66. //Select the material to use
  67. m_pD3DDevice->SetMaterial(&m_matMaterial);
  68. //Select index buffer
  69. m_pD3DDevice->SetIndices(m_pIndexBuffer, 0);
  70. //Render polygons from index buffer
  71. m_pD3DDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, m_dwNumOfVertices, 0, m_dwNumOfPolygons);
  72. //Return the number of polygons rendered
  73. return m_dwNumOfPolygons;
  74. }
  75. HRESULT CCuboid::CreateVertexBuffer()
  76. {
  77.     //Create the vertex buffer from our device.
  78.     if(FAILED(m_pD3DDevice->CreateVertexBuffer(m_dwNumOfVertices * sizeof(CUBOID_CUSTOMVERTEX),
  79.                                                0, CUBOID_D3DFVF_CUSTOMVERTEX,
  80.                                                D3DPOOL_DEFAULT, &m_pVertexBuffer)))
  81.     {
  82.         return E_FAIL;
  83.     }
  84.     return S_OK;
  85. }
  86. bool CCuboid::CreateIndexBuffer()
  87. {
  88. VOID* pBufferIndices;
  89. //Create the index buffer from our device
  90. if(FAILED(m_pD3DDevice->CreateIndexBuffer(m_dwNumOfIndices * sizeof(WORD), 
  91.   0, D3DFMT_INDEX16, D3DPOOL_MANAGED,
  92.   &m_pIndexBuffer)))
  93. {
  94.     return false;
  95. }
  96. //Set values for the index buffer
  97. WORD pIndices[] = { 0, 1, 2, 3, 2, 1, //Top
  98.     4, 5, 6, 7, 6, 5, //Face 1
  99.     8, 9,10,11,10, 9, //Face 2
  100.    12,13,14,15,14,13, //Face 3
  101.    16,17,18,19,18,17, //Face 4
  102.    20,21,22,23,22,21}; //Bottom
  103.    
  104. //Get a pointer to the index buffer indices and lock the index buffer    
  105. m_pIndexBuffer->Lock(0, m_dwNumOfIndices * sizeof(WORD), (BYTE**)&pBufferIndices, 0);
  106. //Copy our stored indices values into the index buffer
  107. memcpy(pBufferIndices, pIndices, m_dwNumOfIndices * sizeof(WORD));
  108. //Unlock the index buffer
  109. m_pIndexBuffer->Unlock();
  110. return true;
  111. }
  112. D3DXVECTOR3 CCuboid::GetTriangeNormal(D3DXVECTOR3* vVertex1, D3DXVECTOR3* vVertex2, D3DXVECTOR3* vVertex3)
  113. {
  114. D3DXVECTOR3 vNormal;
  115. D3DXVECTOR3 v1;
  116. D3DXVECTOR3 v2;
  117. D3DXVec3Subtract(&v1, vVertex2, vVertex1);
  118. D3DXVec3Subtract(&v2, vVertex3, vVertex1);
  119. D3DXVec3Cross(&vNormal, &v1, &v2);
  120. D3DXVec3Normalize(&vNormal, &vNormal);
  121. return vNormal;
  122. }
  123. bool CCuboid::UpdateVertices()
  124. {
  125. DWORD i;
  126. VOID* pVertices;
  127. WORD* pBufferIndices;
  128. D3DXVECTOR3 vNormal;
  129. DWORD dwVertex1;
  130. DWORD dwVertex2;
  131. DWORD dwVertex3;
  132. WORD* pNumOfSharedPolygons = new WORD[m_dwNumOfVertices]; //Array holds how many times this vertex is shared
  133. D3DVECTOR* pSumVertexNormal = new D3DVECTOR[m_dwNumOfVertices]; //Array holds sum of all face normals for shared vertex
  134. //Clear memory
  135. for(i = 0; i < m_dwNumOfVertices; i++)
  136. {
  137. pNumOfSharedPolygons[i] = 0;
  138. pSumVertexNormal[i] = D3DXVECTOR3(0,0,0);
  139. }
  140. CUBOID_CUSTOMVERTEX cvVertices[] =
  141. {
  142. //Top Face
  143. {m_rX - (m_rWidth / 2), m_rY + (m_rHeight / 2), m_rZ - (m_rDepth / 2), 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,}, //Vertex 0
  144. {m_rX - (m_rWidth / 2), m_rY + (m_rHeight / 2), m_rZ + (m_rDepth / 2), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,}, //Vertex 1
  145. {m_rX + (m_rWidth / 2), m_rY + (m_rHeight / 2), m_rZ - (m_rDepth / 2), 0.0f, 0.0f, 0.0f, 1.0f, 1.0f,}, //Vertex 2
  146. {m_rX + (m_rWidth / 2), m_rY + (m_rHeight / 2), m_rZ + (m_rDepth / 2), 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,}, //Vertex 3
  147. //Face 1
  148. {m_rX - (m_rWidth / 2), m_rY - (m_rHeight / 2), m_rZ - (m_rDepth / 2), 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,}, //Vertex 4
  149. {m_rX - (m_rWidth / 2), m_rY + (m_rHeight / 2), m_rZ - (m_rDepth / 2), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,}, //Vertex 5
  150. {m_rX + (m_rWidth / 2), m_rY - (m_rHeight / 2), m_rZ - (m_rDepth / 2), 0.0f, 0.0f, 0.0f, 1.0f, 1.0f,}, //Vertex 6
  151. {m_rX + (m_rWidth / 2), m_rY + (m_rHeight / 2), m_rZ - (m_rDepth / 2), 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,}, //Vertex 7
  152. //Face 2
  153. {m_rX + (m_rWidth / 2), m_rY - (m_rHeight / 2), m_rZ - (m_rDepth / 2), 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,}, //Vertex 8
  154. {m_rX + (m_rWidth / 2), m_rY + (m_rHeight / 2), m_rZ - (m_rDepth / 2), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,}, //Vertex 9
  155. {m_rX + (m_rWidth / 2), m_rY - (m_rHeight / 2), m_rZ + (m_rDepth / 2), 0.0f, 0.0f, 0.0f, 1.0f, 1.0f,}, //Vertex 10
  156. {m_rX + (m_rWidth / 2), m_rY + (m_rHeight / 2), m_rZ + (m_rDepth / 2), 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,}, //Vertex 11
  157. //Face 3
  158. {m_rX + (m_rWidth / 2), m_rY - (m_rHeight / 2), m_rZ + (m_rDepth / 2), 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,}, //Vertex 12
  159. {m_rX + (m_rWidth / 2), m_rY + (m_rHeight / 2), m_rZ + (m_rDepth / 2), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,}, //Vertex 13
  160. {m_rX - (m_rWidth / 2), m_rY - (m_rHeight / 2), m_rZ + (m_rDepth / 2), 0.0f, 0.0f, 0.0f, 1.0f, 1.0f,}, //Vertex 14
  161. {m_rX - (m_rWidth / 2), m_rY + (m_rHeight / 2), m_rZ + (m_rDepth / 2), 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,}, //Vertex 15
  162. //Face 4
  163. {m_rX - (m_rWidth / 2), m_rY - (m_rHeight / 2), m_rZ + (m_rDepth / 2), 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,}, //Vertex 16
  164. {m_rX - (m_rWidth / 2), m_rY + (m_rHeight / 2), m_rZ + (m_rDepth / 2), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,}, //Vertex 17
  165. {m_rX - (m_rWidth / 2), m_rY - (m_rHeight / 2), m_rZ - (m_rDepth / 2), 0.0f, 0.0f, 0.0f, 1.0f, 1.0f,}, //Vertex 18
  166. {m_rX - (m_rWidth / 2), m_rY + (m_rHeight / 2), m_rZ - (m_rDepth / 2), 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,}, //Vertex 19
  167. //Bottom Face
  168. {m_rX + (m_rWidth / 2), m_rY - (m_rHeight / 2), m_rZ - (m_rDepth / 2), 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,}, //Vertex 20
  169. {m_rX + (m_rWidth / 2), m_rY - (m_rHeight / 2), m_rZ + (m_rDepth / 2), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,}, //Vertex 21
  170. {m_rX - (m_rWidth / 2), m_rY - (m_rHeight / 2), m_rZ - (m_rDepth / 2), 0.0f, 0.0f, 0.0f, 1.0f, 1.0f,}, //Vertex 22
  171. {m_rX - (m_rWidth / 2), m_rY - (m_rHeight / 2), m_rZ + (m_rDepth / 2), 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,}, //Vertex 23
  172. };
  173. //Get a pointer to the index buffer indices and lock the index buffer    
  174. m_pIndexBuffer->Lock(0, m_dwNumOfIndices * sizeof(WORD), (BYTE**)&pBufferIndices, D3DLOCK_READONLY);
  175. //For each triangle, count the number of times each vertex is used and
  176. //add together the normals of faces that share a vertex
  177. for(i = 0; i < m_dwNumOfIndices; i += 3)
  178. {
  179. dwVertex1 = pBufferIndices[i];
  180. dwVertex2 = pBufferIndices[i + 1];
  181. dwVertex3 = pBufferIndices[i + 2];
  182. vNormal = GetTriangeNormal(&D3DXVECTOR3(cvVertices[dwVertex1].x, cvVertices[dwVertex1].y, cvVertices[dwVertex1].z), 
  183.    &D3DXVECTOR3(cvVertices[dwVertex2].x, cvVertices[dwVertex2].y, cvVertices[dwVertex2].z), 
  184.    &D3DXVECTOR3(cvVertices[dwVertex3].x, cvVertices[dwVertex3].y, cvVertices[dwVertex3].z));
  185. pNumOfSharedPolygons[dwVertex1]++;
  186. pNumOfSharedPolygons[dwVertex2]++;
  187. pNumOfSharedPolygons[dwVertex3]++;
  188. pSumVertexNormal[dwVertex1].x += vNormal.x;
  189. pSumVertexNormal[dwVertex1].y += vNormal.y;
  190. pSumVertexNormal[dwVertex1].z += vNormal.z;
  191. pSumVertexNormal[dwVertex2].x += vNormal.x;
  192. pSumVertexNormal[dwVertex2].y += vNormal.y;
  193. pSumVertexNormal[dwVertex2].z += vNormal.z;
  194. pSumVertexNormal[dwVertex3].x += vNormal.x;
  195. pSumVertexNormal[dwVertex3].y += vNormal.y;
  196. pSumVertexNormal[dwVertex3].z += vNormal.z;
  197. }
  198. //Unlock the index buffer
  199. m_pIndexBuffer->Unlock();
  200. //For each vertex, calculate and set the average normal
  201. for(i = 0; i < m_dwNumOfVertices; i++)
  202. {
  203. vNormal.x = pSumVertexNormal[i].x / pNumOfSharedPolygons[i];
  204. vNormal.y = pSumVertexNormal[i].y / pNumOfSharedPolygons[i];
  205. vNormal.z = pSumVertexNormal[i].z / pNumOfSharedPolygons[i];
  206. D3DXVec3Normalize(&vNormal, &vNormal);
  207. cvVertices[i].nx = vNormal.x;
  208. cvVertices[i].ny = vNormal.y;
  209. cvVertices[i].nz = vNormal.z;
  210. }
  211. //Get a pointer to the vertex buffer vertices and lock the vertex buffer
  212.     if(FAILED(m_pVertexBuffer->Lock(0, sizeof(cvVertices), (BYTE**)&pVertices, 0)))
  213.     {
  214.         return false;
  215.     }
  216.     //Copy our stored vertices values into the vertex buffer
  217.     memcpy(pVertices, cvVertices, sizeof(cvVertices));
  218.     //Unlock the vertex buffer
  219.     m_pVertexBuffer->Unlock();
  220. //Clean up
  221. delete pNumOfSharedPolygons;
  222. delete pSumVertexNormal;
  223. pNumOfSharedPolygons = NULL;
  224. pSumVertexNormal = NULL;
  225. return true;
  226. }
  227. bool CCuboid::SetSize(float rWidth, float rHeight, float rDepth)
  228. {
  229. m_rWidth = rWidth;
  230. m_rHeight = rHeight;
  231. m_rDepth = rDepth;
  232. UpdateVertices();
  233. return true;
  234. }
  235. bool CCuboid::SetPosition(float x, float y, float z)
  236. {
  237. m_rX = x;
  238. m_rY = y;
  239. m_rZ = z;
  240. UpdateVertices();
  241. return true;
  242. }
  243. bool CCuboid::SetTexture(const char *szTextureFilePath)
  244. {
  245. if(FAILED(D3DXCreateTextureFromFile(m_pD3DDevice, szTextureFilePath, &m_pTexture)))
  246. {
  247. return false;
  248. }
  249. return true;
  250. }
  251. bool CCuboid::SetMaterial(D3DCOLORVALUE rgbaDiffuse, D3DCOLORVALUE rgbaAmbient, D3DCOLORVALUE rgbaSpecular, D3DCOLORVALUE rgbaEmissive, float rPower)
  252. {
  253. //Set the RGBA for diffuse light reflected from this material. 
  254. m_matMaterial.Diffuse = rgbaDiffuse; 
  255. //Set the RGBA for ambient light reflected from this material. 
  256. m_matMaterial.Ambient = rgbaAmbient; 
  257. //Set the color and sharpness of specular highlights for the material. 
  258. m_matMaterial.Specular = rgbaSpecular; 
  259. m_matMaterial.Power = rPower;
  260. //Set the RGBA for light emitted from this material. 
  261. m_matMaterial.Emissive = rgbaEmissive;
  262. return true;
  263. }