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

其他书籍

开发平台:

HTML/CSS

  1. // Sphere.cpp: implementation of the CSphere class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "Sphere.h"
  5. //////////////////////////////////////////////////////////////////////
  6. // Construction/Destruction
  7. //////////////////////////////////////////////////////////////////////
  8. CSphere::CSphere(LPDIRECT3DDEVICE8 pD3DDevice, int nRings, int nSegments)
  9. {
  10. m_pD3DDevice = pD3DDevice;
  11. m_pVertexBuffer = NULL;
  12. m_pIndexBuffer = NULL;
  13. m_pTexture = NULL;
  14. m_nRings = nRings;
  15. m_nSegments = nSegments;
  16. //Setup counts for this object
  17. m_dwNumOfVertices = (m_nRings + 1) * (m_nSegments + 1);
  18. m_dwNumOfIndices  = 2 * m_nRings * (m_nSegments + 1);
  19. m_dwNumOfPolygons = m_dwNumOfIndices - 2;
  20. //Set material default values (R, G, B, A)
  21. D3DCOLORVALUE rgbaDiffuse  = {1.0, 1.0, 1.0, 0.0,};
  22. D3DCOLORVALUE rgbaAmbient  = {1.0, 1.0, 1.0, 0.0,};
  23. D3DCOLORVALUE rgbaSpecular = {0.0, 0.0, 0.0, 0.0,};
  24. D3DCOLORVALUE rgbaEmissive = {0.0, 0.0, 0.0, 0.0,};
  25. SetMaterial(rgbaDiffuse, rgbaAmbient, rgbaSpecular, rgbaEmissive, 0);
  26. //Initialize Vertex Buffer
  27.     if(CreateVertexBuffer())
  28. {
  29. if(CreateIndexBuffer())
  30. {
  31. if(UpdateVertices())
  32. {
  33. LogInfo("<li>Sphere created OK");
  34. return;
  35. }
  36. }
  37. }
  38. LogError("<li>Sphere failed to create");
  39. }
  40. CSphere::~CSphere()
  41. {
  42. SafeRelease(m_pTexture);
  43. SafeRelease(m_pIndexBuffer);
  44. SafeRelease(m_pVertexBuffer);
  45. LogInfo("<li>Sphere destroyed OK");
  46. }
  47. DWORD CSphere::Render()
  48. {
  49. m_pD3DDevice->SetStreamSource(0, m_pVertexBuffer, sizeof(SPHERE_CUSTOMVERTEX));
  50. m_pD3DDevice->SetVertexShader(SPHERE_D3DFVF_CUSTOMVERTEX);
  51. if(m_pTexture != NULL)
  52. {
  53. //A texture has been set. We want our texture to be shaded based
  54. //on the current light levels, so used D3DTOP_MODULATE.
  55. m_pD3DDevice->SetTexture(0, m_pTexture);
  56. m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
  57. m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
  58. m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT);
  59. }
  60. else
  61. {
  62. //No texture has been set
  63. m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG2);
  64. m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
  65. m_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT);
  66. }
  67. //Select the material to use
  68. m_pD3DDevice->SetMaterial(&m_matMaterial);
  69. //Select index buffer
  70. m_pD3DDevice->SetIndices(m_pIndexBuffer, 0);
  71. //Render polygons from index buffer
  72. m_pD3DDevice->DrawIndexedPrimitive(D3DPT_TRIANGLESTRIP, 0, m_dwNumOfVertices, 0, m_dwNumOfPolygons);
  73. m_pD3DDevice->SetTexture(0, 0);
  74. m_pD3DDevice->SetStreamSource(0, 0, 0);
  75. m_pD3DDevice->SetIndices(0, 0);
  76. //Return the number of polygons rendered
  77. return m_dwNumOfPolygons;
  78. }
  79. bool CSphere::CreateVertexBuffer()
  80. {
  81.     //Create the vertex buffer from our device.
  82.     if(FAILED(m_pD3DDevice->CreateVertexBuffer(m_dwNumOfVertices * sizeof(SPHERE_CUSTOMVERTEX),
  83.                                                0, SPHERE_D3DFVF_CUSTOMVERTEX,
  84.                                                D3DPOOL_DEFAULT, &m_pVertexBuffer)))
  85.     {
  86. LogError("<li>CSphere: Unable to create vertex buffer.");
  87.         return false;
  88.     }
  89.     return true;
  90. }
  91. bool CSphere::CreateIndexBuffer()
  92. {
  93. //Create the index buffer from our device
  94. if(FAILED(m_pD3DDevice->CreateIndexBuffer(m_dwNumOfIndices * sizeof(WORD), 
  95.   0, D3DFMT_INDEX16, D3DPOOL_MANAGED,
  96.   &m_pIndexBuffer)))
  97. {
  98. LogError("<li>CSphere: Unable to create index buffer.");
  99.     return false;
  100. }
  101. return true;
  102. }
  103. bool CSphere::UpdateVertices()
  104. {
  105. //Code adapted from a sample by "Laurent" posted on the GameDev.net DirectX forum
  106. //http://www.gamedev.net/community/forums/topic.asp?topic_id=85779
  107. WORD* pIndices;
  108. SPHERE_CUSTOMVERTEX* pVertex; 
  109. WORD wVertexIndex = 0;
  110. int nCurrentRing;
  111. int nCurrentSegment;
  112. D3DXVECTOR3 vNormal;
  113. //Lock the vertex buffer
  114. if(FAILED(m_pVertexBuffer->Lock(0, 0, (BYTE**)&pVertex, 0)))
  115. {
  116. LogError("<li>CSphere: Unable to lock vertex buffer.");
  117. return false;
  118. }
  119. //Lock the index buffer 
  120. if(FAILED(m_pIndexBuffer->Lock(0, m_dwNumOfIndices, (BYTE**)&pIndices, 0)))
  121. {
  122. LogError("<li>CSphere: Unable to lock index buffer.");
  123. return false;
  124. }
  125. //Establish constants used in sphere generation
  126. FLOAT rDeltaRingAngle = (D3DX_PI / m_nRings);
  127. FLOAT rDeltaSegAngle = (2.0f * D3DX_PI / m_nSegments);
  128. //Generate the group of rings for the sphere
  129. for(nCurrentRing = 0; nCurrentRing < m_nRings + 1; nCurrentRing++)
  130. {
  131. FLOAT r0 = sinf(nCurrentRing * rDeltaRingAngle);
  132. FLOAT y0 = cosf(nCurrentRing * rDeltaRingAngle);
  133. //Generate the group of segments for the current ring
  134. for(nCurrentSegment = 0; nCurrentSegment < m_nSegments + 1; nCurrentSegment++)
  135. {
  136. FLOAT x0 = r0 * sinf(nCurrentSegment * rDeltaSegAngle);
  137. FLOAT z0 = r0 * cosf(nCurrentSegment * rDeltaSegAngle);
  138. vNormal.x = x0;
  139. vNormal.y = y0;
  140. vNormal.z = z0;
  141. D3DXVec3Normalize(&vNormal, &vNormal);
  142. //Add one vertex to the strip which makes up the sphere
  143. pVertex->x = x0;
  144. pVertex->y = y0;
  145. pVertex->z = z0;
  146. pVertex->nx = vNormal.x;
  147. pVertex->ny = vNormal.y;
  148. pVertex->nz = vNormal.z;
  149. pVertex->tu = 1.0f - ((FLOAT)nCurrentSegment / (FLOAT)m_nSegments);
  150. pVertex->tv = (FLOAT)nCurrentRing / (FLOAT)m_nRings;
  151. pVertex++;
  152. //Add two indices except for the last ring 
  153. if(nCurrentRing != m_nRings) 
  154. {
  155. *pIndices = wVertexIndex; 
  156. pIndices++;
  157. *pIndices = wVertexIndex + (WORD)(m_nSegments + 1); 
  158. pIndices++;
  159. wVertexIndex++; 
  160. }
  161. }
  162. }
  163. if(FAILED(m_pIndexBuffer->Unlock()))
  164. {
  165. LogError("<li>CSphere: Unable to unlock index buffer.");
  166. return false;
  167. }
  168. if(FAILED(m_pVertexBuffer->Unlock()))
  169. {
  170. LogError("<li>CSphere: Unable to unlock vertex buffer.");
  171. return false;
  172. }
  173. return true; 
  174. }
  175. bool CSphere::SetTexture(const char *szTextureFilePath)
  176. {
  177. if(FAILED(D3DXCreateTextureFromFile(m_pD3DDevice, szTextureFilePath, &m_pTexture)))
  178. {
  179. return false;
  180. }
  181. return true;
  182. }
  183. bool CSphere::SetMaterial(D3DCOLORVALUE rgbaDiffuse, D3DCOLORVALUE rgbaAmbient, D3DCOLORVALUE rgbaSpecular, D3DCOLORVALUE rgbaEmissive, float rPower)
  184. {
  185. //Set the RGBA for diffuse light reflected from this material. 
  186. m_matMaterial.Diffuse = rgbaDiffuse; 
  187. //Set the RGBA for ambient light reflected from this material. 
  188. m_matMaterial.Ambient = rgbaAmbient; 
  189. //Set the color and sharpness of specular highlights for the material. 
  190. m_matMaterial.Specular = rgbaSpecular; 
  191. m_matMaterial.Power = rPower;
  192. //Set the RGBA for light emitted from this material. 
  193. m_matMaterial.Emissive = rgbaEmissive;
  194. return true;
  195. }