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