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

其他书籍

开发平台:

HTML/CSS

  1. // Cone.cpp: implementation of the CCone class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "Cone.h"
  5. //////////////////////////////////////////////////////////////////////
  6. // Construction/Destruction
  7. //////////////////////////////////////////////////////////////////////
  8. CCone::CCone(LPDIRECT3DDEVICE8 pD3DDevice, float rHeight, float rRadius, int nSegments)
  9. {
  10. m_pD3DDevice = pD3DDevice;
  11. m_pVertexBuffer = NULL;
  12. m_pSideTexture = NULL;
  13. m_pEndTexture = NULL;
  14. m_rHeight = rHeight;
  15. m_rRadius = rRadius;
  16. m_nSegments = nSegments;
  17. //Setup counts for this object
  18. m_dwNumOfVertices = (m_nSegments * 3) + 2;
  19. m_dwNumOfIndices = m_nSegments * 3;
  20. m_dwNumOfSidePolygons = m_nSegments;
  21. m_dwNumOfEndPolygons = m_nSegments;
  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>Cone created OK");
  36. return;
  37. }
  38. }
  39. }
  40. LogError("<li>Cone failed to create");
  41. }
  42. CCone::~CCone()
  43. {
  44. SafeRelease(m_pSideTexture);
  45. SafeRelease(m_pEndTexture);
  46. SafeRelease(m_pIndexBuffer);
  47. SafeRelease(m_pVertexBuffer);
  48. LogInfo("<li>Cone destroyed OK");
  49. }
  50. DWORD CCone::Render()
  51. {
  52. m_pD3DDevice->SetStreamSource(0, m_pVertexBuffer, sizeof(CONE_CUSTOMVERTEX));
  53. m_pD3DDevice->SetVertexShader(CONE_D3DFVF_CUSTOMVERTEX);
  54. //Select the side texture
  55. if(m_pSideTexture != NULL)
  56. {
  57. //A texture has been set. We want our texture to be shaded based
  58. //on the current light levels, so used D3DTOP_MODULATE.
  59. m_pD3DDevice->SetTexture(0, m_pSideTexture);
  60. m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
  61. m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
  62. m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT);
  63. }
  64. else
  65. {
  66. //No texture has been set
  67. m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG2);
  68. m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
  69. m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT);
  70. }
  71. //Select the material to use
  72. m_pD3DDevice->SetMaterial(&m_matMaterial);
  73. //Select index buffer
  74. m_pD3DDevice->SetIndices(m_pIndexBuffer, 0);
  75. //Render polygons from vertex buffer - Sides
  76. m_pD3DDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, (m_nSegments * 3), 0, m_dwNumOfSidePolygons);
  77. m_pD3DDevice->SetTexture(0, 0); 
  78. m_pD3DDevice->SetIndices(0, 0);
  79. //Select the end texture
  80. if(m_pEndTexture != NULL)
  81. {
  82. //A texture has been set. We want our texture to be shaded based
  83. //on the current light levels, so used D3DTOP_MODULATE.
  84. m_pD3DDevice->SetTexture(0, m_pEndTexture);
  85. m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
  86. m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
  87. m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT);
  88. }
  89. else
  90. {
  91. //No texture has been set
  92. m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG2);
  93. m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
  94. m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT);
  95. }
  96. //Render polygons from vertex buffer - End
  97. m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, (m_nSegments * 2), m_dwNumOfEndPolygons);
  98. m_pD3DDevice->SetTexture(0, 0);
  99. m_pD3DDevice->SetStreamSource(0, 0, 0);
  100. //Return the number of polygons rendered
  101. return m_dwNumOfSidePolygons + m_dwNumOfEndPolygons;
  102. }
  103. bool CCone::CreateVertexBuffer()
  104. {
  105.     //Create the vertex buffer from our device.
  106.     if(FAILED(m_pD3DDevice->CreateVertexBuffer(m_dwNumOfVertices * sizeof(CONE_CUSTOMVERTEX),
  107.                                                0, CONE_D3DFVF_CUSTOMVERTEX,
  108.                                                D3DPOOL_DEFAULT, &m_pVertexBuffer)))
  109.     {
  110.         LogError("<li>CCone: Unable to create vertex buffer.");
  111. return false;
  112.     }
  113.     return true;
  114. }
  115. bool CCone::CreateIndexBuffer()
  116. {
  117. //Create the index buffer from our device
  118. if(FAILED(m_pD3DDevice->CreateIndexBuffer(m_dwNumOfIndices * sizeof(WORD), 
  119.   0, D3DFMT_INDEX16, D3DPOOL_MANAGED,
  120.   &m_pIndexBuffer)))
  121. {
  122. LogError("<li>CCone: Unable to create index buffer.");
  123.     return false;
  124. }
  125. return true;
  126. }
  127. bool CCone::UpdateVertices()
  128. {
  129. CONE_CUSTOMVERTEX* pVertex;
  130. WORD* pIndices;
  131. WORD wVertexIndex = 0;
  132. int nCurrentSegment;
  133. //Lock the vertex buffer
  134. if(FAILED(m_pVertexBuffer->Lock(0, 0, (BYTE**)&pVertex, 0)))
  135. {
  136. LogError("<li>CCone: Unable to lock vertex buffer.");
  137. return false;
  138. }
  139. //Lock the index buffer 
  140. if(FAILED(m_pIndexBuffer->Lock(0, m_dwNumOfIndices, (BYTE**)&pIndices, 0)))
  141. {
  142. LogError("<li>CCone: Unable to lock index buffer.");
  143. return false;
  144. }
  145. float rDeltaSegAngle = (2.0f * D3DX_PI / m_nSegments);
  146. float rSegmentLength = 1.0f / (float)m_nSegments;
  147. float ny0 = (90.0f - (float)D3DXToDegree(atan(m_rHeight / m_rRadius))) / 90.0f;
  148. //For each segment, add a triangle to the sides triangle list
  149. for(nCurrentSegment = 0; nCurrentSegment < m_nSegments; nCurrentSegment++)
  150. {
  151. float x0 = m_rRadius * sinf(nCurrentSegment * rDeltaSegAngle);
  152. float z0 = m_rRadius * cosf(nCurrentSegment * rDeltaSegAngle);
  153. pVertex->x = 0.0f;
  154. pVertex->y = 0.0f + (m_rHeight / 2.0f);
  155. pVertex->z = 0.0f;
  156. pVertex->nx = x0;
  157. pVertex->ny = ny0;
  158. pVertex->nz = z0;
  159. pVertex->tu = 1.0f - (rSegmentLength * (float)nCurrentSegment);
  160. pVertex->tv = 0.0f;
  161. pVertex++;
  162. pVertex->x = x0;
  163. pVertex->y = 0.0f - (m_rHeight / 2.0f);
  164. pVertex->z = z0;
  165. pVertex->nx = x0;
  166. pVertex->ny = ny0;
  167. pVertex->nz = z0;
  168. pVertex->tu = 1.0f - (rSegmentLength * (float)nCurrentSegment);
  169. pVertex->tv = 1.0f;
  170. pVertex++;
  171. //Set three indices (1 triangle) per segment
  172. *pIndices = wVertexIndex; 
  173. pIndices++;
  174. wVertexIndex++;
  175. *pIndices = wVertexIndex; 
  176. pIndices++;
  177. wVertexIndex += 2;
  178. if(nCurrentSegment == m_nSegments - 1)
  179. {
  180. *pIndices = 1; 
  181. pIndices++;
  182. wVertexIndex--;
  183. }
  184. else
  185. {
  186. *pIndices = wVertexIndex; 
  187. pIndices++;
  188. wVertexIndex--;
  189. }
  190. }
  191. //Create the bottom triangle fan: Center vertex
  192. pVertex->x = 0.0f;
  193. pVertex->y = 0.0f - (m_rHeight / 2.0f);
  194. pVertex->z = 0.0f;
  195. pVertex->nx = 0.0f;
  196. pVertex->ny = -1.0f;
  197. pVertex->nz = 0.0f;
  198. pVertex->tu = 0.5f;
  199. pVertex->tv = 0.5f;
  200. pVertex++;
  201. //Create the bottom triangle fan: Edge vertices
  202. for(nCurrentSegment = m_nSegments; nCurrentSegment >= 0; nCurrentSegment--)
  203. {
  204. float x0 = m_rRadius * sinf(nCurrentSegment * rDeltaSegAngle);
  205. float z0 = m_rRadius * cosf(nCurrentSegment * rDeltaSegAngle);
  206. pVertex->x = x0;
  207. pVertex->y = 0.0f - (m_rHeight / 2.0f);
  208. pVertex->z = z0;
  209. pVertex->nx = 0.0f;
  210. pVertex->ny = -1.0f;
  211. pVertex->nz = 0.0f;
  212. float tu0 = (0.5f * sinf(nCurrentSegment * rDeltaSegAngle)) + 0.5f;
  213. float tv0 = (0.5f * cosf(nCurrentSegment * rDeltaSegAngle)) + 0.5f;
  214. pVertex->tu = tu0;
  215. pVertex->tv = tv0;
  216. pVertex++;
  217. }
  218. if(FAILED(m_pVertexBuffer->Unlock()))
  219. {
  220. LogError("<li>CCone: Unable to unlock vertex buffer.");
  221. return false;
  222. }
  223. if(FAILED(m_pIndexBuffer->Unlock()))
  224. {
  225. LogError("<li>CCone: Unable to unlock index buffer.");
  226. return false;
  227. }
  228. return true; 
  229. }
  230. bool CCone::SetSideTexture(const char *szTextureFilePath)
  231. {
  232. if(FAILED(D3DXCreateTextureFromFile(m_pD3DDevice, szTextureFilePath, &m_pSideTexture)))
  233. {
  234. return false;
  235. }
  236. return true;
  237. }
  238. bool CCone::SetEndTexture(const char *szTextureFilePath)
  239. {
  240. if(FAILED(D3DXCreateTextureFromFile(m_pD3DDevice, szTextureFilePath, &m_pEndTexture)))
  241. {
  242. return false;
  243. }
  244. return true;
  245. }
  246. bool CCone::SetMaterial(D3DCOLORVALUE rgbaDiffuse, D3DCOLORVALUE rgbaAmbient, D3DCOLORVALUE rgbaSpecular, D3DCOLORVALUE rgbaEmissive, float rPower)
  247. {
  248. //Set the RGBA for diffuse light reflected from this material. 
  249. m_matMaterial.Diffuse = rgbaDiffuse; 
  250. //Set the RGBA for ambient light reflected from this material. 
  251. m_matMaterial.Ambient = rgbaAmbient; 
  252. //Set the color and sharpness of specular highlights for the material. 
  253. m_matMaterial.Specular = rgbaSpecular; 
  254. m_matMaterial.Power = rPower;
  255. //Set the RGBA for light emitted from this material. 
  256. m_matMaterial.Emissive = rgbaEmissive;
  257. return true;
  258. }