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

其他书籍

开发平台:

HTML/CSS

  1. // Cylinder.cpp: implementation of the CCylinder class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "Cylinder.h"
  5. //////////////////////////////////////////////////////////////////////
  6. // Construction/Destruction
  7. //////////////////////////////////////////////////////////////////////
  8. CCylinder::CCylinder(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 + 1) * 4) + 2;
  19. m_dwNumOfSidePolygons = m_nSegments * 2;
  20. m_dwNumOfEndPolygons = m_nSegments;
  21. //Set material default values (R, G, B, A)
  22. D3DCOLORVALUE rgbaDiffuse  = {1.0, 1.0, 1.0, 0.0,};
  23. D3DCOLORVALUE rgbaAmbient  = {1.0, 1.0, 1.0, 0.0,};
  24. D3DCOLORVALUE rgbaSpecular = {0.0, 0.0, 0.0, 0.0,};
  25. D3DCOLORVALUE rgbaEmissive = {0.0, 0.0, 0.0, 0.0,};
  26. SetMaterial(rgbaDiffuse, rgbaAmbient, rgbaSpecular, rgbaEmissive, 0);
  27. //Initialize Vertex Buffer
  28.     if(CreateVertexBuffer())
  29. {
  30. if(UpdateVertices())
  31. {
  32. LogInfo("<li>Cylinder created OK");
  33. return;
  34. }
  35. }
  36. LogError("<li>Cylinder failed to create");
  37. }
  38. CCylinder::~CCylinder()
  39. {
  40. SafeRelease(m_pSideTexture);
  41. SafeRelease(m_pEndTexture);
  42. SafeRelease(m_pVertexBuffer);
  43. LogInfo("<li>Cylinder destroyed OK");
  44. }
  45. DWORD CCylinder::Render()
  46. {
  47. m_pD3DDevice->SetStreamSource(0, m_pVertexBuffer, sizeof(CYLINDER_CUSTOMVERTEX));
  48. m_pD3DDevice->SetVertexShader(CYLINDER_D3DFVF_CUSTOMVERTEX);
  49. if(m_pSideTexture != NULL)
  50. {
  51. //A texture has been set. We want our texture to be shaded based
  52. //on the current light levels, so used D3DTOP_MODULATE.
  53. m_pD3DDevice->SetTexture(0, m_pSideTexture);
  54. m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
  55. m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
  56. m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT);
  57. }
  58. else
  59. {
  60. //No texture has been set
  61. m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG2);
  62. m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
  63. m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT);
  64. }
  65. //Select the material to use
  66. m_pD3DDevice->SetMaterial(&m_matMaterial);
  67. //Render polygons from vertex buffer - Sides
  68. m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, m_dwNumOfSidePolygons);
  69. m_pD3DDevice->SetTexture(0, 0);
  70. if(m_pEndTexture != NULL)
  71. {
  72. //A texture has been set. We want our texture to be shaded based
  73. //on the current light levels, so used D3DTOP_MODULATE.
  74. m_pD3DDevice->SetTexture(0, m_pEndTexture);
  75. m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
  76. m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
  77. m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT);
  78. }
  79. else
  80. {
  81. //No texture has been set
  82. m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG2);
  83. m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
  84. m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT);
  85. }
  86. //Render polygons from vertex buffer - Top
  87. m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, ((m_nSegments + 1) * 2), m_dwNumOfEndPolygons);
  88. //Render polygons from vertex buffer - Bottom
  89. m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, ((m_nSegments + 1) * 3) + 1, m_dwNumOfEndPolygons);
  90. m_pD3DDevice->SetTexture(0, 0);
  91. m_pD3DDevice->SetStreamSource(0, 0, 0);
  92. //Return the number of polygons rendered
  93. return m_dwNumOfSidePolygons + (2 * m_dwNumOfEndPolygons);
  94. }
  95. bool CCylinder::CreateVertexBuffer()
  96. {
  97.     //Create the vertex buffer from our device.
  98.     if(FAILED(m_pD3DDevice->CreateVertexBuffer(m_dwNumOfVertices * sizeof(CYLINDER_CUSTOMVERTEX),
  99.                                                0, CYLINDER_D3DFVF_CUSTOMVERTEX,
  100.                                                D3DPOOL_DEFAULT, &m_pVertexBuffer)))
  101.     {
  102.         LogError("<li>CCylinder: Unable to create vertex buffer.");
  103. return false;
  104.     }
  105.     return true;
  106. }
  107. bool CCylinder::UpdateVertices()
  108. {
  109. CYLINDER_CUSTOMVERTEX* pVertex; 
  110. WORD wVertexIndex = 0;
  111. int nCurrentSegment;
  112. //Lock the vertex buffer
  113. if(FAILED(m_pVertexBuffer->Lock(0, 0, (BYTE**)&pVertex, 0)))
  114. {
  115. LogError("<li>CCylinder: Unable to lock vertex buffer.");
  116. return false;
  117. }
  118. float rDeltaSegAngle = (2.0f * D3DX_PI / m_nSegments);
  119. float rSegmentLength = 1.0f / (float)m_nSegments;
  120. //Create the sides triangle strip
  121. for(nCurrentSegment = 0; nCurrentSegment <= m_nSegments; nCurrentSegment++)
  122. {
  123. float x0 = m_rRadius * sinf(nCurrentSegment * rDeltaSegAngle);
  124. float z0 = m_rRadius * cosf(nCurrentSegment * rDeltaSegAngle);
  125. pVertex->x = x0;
  126. pVertex->y = 0.0f + (m_rHeight / 2.0f);
  127. pVertex->z = z0;
  128. pVertex->nx = x0;
  129. pVertex->ny = 0.0f;
  130. pVertex->nz = z0;
  131. pVertex->tu = 1.0f - (rSegmentLength * (float)nCurrentSegment);
  132. pVertex->tv = 0.0f;
  133. pVertex++;
  134. pVertex->x = x0;
  135. pVertex->y = 0.0f - (m_rHeight / 2.0f);
  136. pVertex->z = z0;
  137. pVertex->nx = x0;
  138. pVertex->ny = 0.0f;
  139. pVertex->nz = z0;
  140. pVertex->tu = 1.0f - (rSegmentLength * (float)nCurrentSegment);
  141. pVertex->tv = 1.0f;
  142. pVertex++;
  143. }
  144. //Create the top triangle fan: Center
  145. pVertex->x = 0.0f;
  146. pVertex->y = 0.0f + (m_rHeight / 2.0f);
  147. pVertex->z = 0.0f;
  148. pVertex->nx = 0.0f;
  149. pVertex->ny = 1.0f;
  150. pVertex->nz = 0.0f;
  151. pVertex->tu = 0.5f;
  152. pVertex->tv = 0.5f;
  153. pVertex++;
  154. //Create the top triangle fan: Edges
  155. for(nCurrentSegment = 0; nCurrentSegment <= m_nSegments; nCurrentSegment++)
  156. {
  157. float x0 = m_rRadius * sinf(nCurrentSegment * rDeltaSegAngle);
  158. float z0 = m_rRadius * cosf(nCurrentSegment * rDeltaSegAngle);
  159. pVertex->x = x0;
  160. pVertex->y = 0.0f + (m_rHeight / 2.0f);
  161. pVertex->z = z0;
  162. pVertex->nx = 0.0f;
  163. pVertex->ny = 1.0f;
  164. pVertex->nz = 0.0f;
  165. float tu0 = (0.5f * sinf(nCurrentSegment * rDeltaSegAngle)) + 0.5f;
  166. float tv0 = (0.5f * cosf(nCurrentSegment * rDeltaSegAngle)) + 0.5f;
  167. pVertex->tu = tu0;
  168. pVertex->tv = tv0;
  169. pVertex++;
  170. }
  171. //Create the bottom triangle fan: Center
  172. pVertex->x = 0.0f;
  173. pVertex->y = 0.0f - (m_rHeight / 2.0f);
  174. pVertex->z = 0.0f;
  175. pVertex->nx = 0.0f;
  176. pVertex->ny = -1.0f;
  177. pVertex->nz = 0.0f;
  178. pVertex->tu = 0.5f;
  179. pVertex->tv = 0.5f;
  180. pVertex++;
  181. //Create the bottom triangle fan: Edges
  182. for(nCurrentSegment = m_nSegments; nCurrentSegment >= 0; nCurrentSegment--)
  183. {
  184. float x0 = m_rRadius * sinf(nCurrentSegment * rDeltaSegAngle);
  185. float z0 = m_rRadius * cosf(nCurrentSegment * rDeltaSegAngle);
  186. pVertex->x = x0;
  187. pVertex->y = 0.0f - (m_rHeight / 2.0f);
  188. pVertex->z = z0;
  189. pVertex->nx = 0.0f;
  190. pVertex->ny = -1.0f;
  191. pVertex->nz = 0.0f;
  192. float tu0 = (0.5f * sinf(nCurrentSegment * rDeltaSegAngle)) + 0.5f;
  193. float tv0 = (0.5f * cosf(nCurrentSegment * rDeltaSegAngle)) + 0.5f;
  194. pVertex->tu = tu0;
  195. pVertex->tv = tv0;
  196. pVertex++;
  197. }
  198. if(FAILED(m_pVertexBuffer->Unlock()))
  199. {
  200. LogError("<li>CCylinder: Unable to unlock vertex buffer.");
  201. return false;
  202. }
  203. return true;  
  204. }
  205. bool CCylinder::SetSideTexture(const char *szTextureFilePath)
  206. {
  207. if(FAILED(D3DXCreateTextureFromFile(m_pD3DDevice, szTextureFilePath, &m_pSideTexture)))
  208. {
  209. return false;
  210. }
  211. return true;
  212. }
  213. bool CCylinder::SetEndTexture(const char *szTextureFilePath)
  214. {
  215. if(FAILED(D3DXCreateTextureFromFile(m_pD3DDevice, szTextureFilePath, &m_pEndTexture)))
  216. {
  217. return false;
  218. }
  219. return true;
  220. }
  221. bool CCylinder::SetMaterial(D3DCOLORVALUE rgbaDiffuse, D3DCOLORVALUE rgbaAmbient, D3DCOLORVALUE rgbaSpecular, D3DCOLORVALUE rgbaEmissive, float rPower)
  222. {
  223. //Set the RGBA for diffuse light reflected from this material. 
  224. m_matMaterial.Diffuse = rgbaDiffuse; 
  225. //Set the RGBA for ambient light reflected from this material. 
  226. m_matMaterial.Ambient = rgbaAmbient; 
  227. //Set the color and sharpness of specular highlights for the material. 
  228. m_matMaterial.Specular = rgbaSpecular; 
  229. m_matMaterial.Power = rPower;
  230. //Set the RGBA for light emitted from this material. 
  231. m_matMaterial.Emissive = rgbaEmissive;
  232. return true;
  233. }