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