Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

196 lines
5.0 KiB

  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <math.h>
  4. #include <string.h>
  5. #include <time.h>
  6. #include <assert.h>
  7. #include <windows.h>
  8. #include <gl\gl.h>
  9. #include <gl\glu.h>
  10. #include <gl\glaux.h>
  11. #include "mtk.hxx"
  12. #include "objects.hxx"
  13. #define RGB_COLOR(red, green, blue) \
  14. (((DWORD)(BYTE)(red) << 0) | \
  15. ((DWORD)(BYTE)(green) << 8) | \
  16. ((DWORD)(BYTE)(blue) << 16))
  17. #define RGBA_COLOR(red, green, blue, alpha) \
  18. (((DWORD)(BYTE)(red) << 0) | \
  19. ((DWORD)(BYTE)(green) << 8) | \
  20. ((DWORD)(BYTE)(blue) << 16) | \
  21. ((DWORD)(BYTE)(alpha) << 24))
  22. #define FRANDOM(x) (((float)rand() / RAND_MAX) * (x))
  23. /****** OBJECT *******************************************************/
  24. OBJECT::OBJECT( int rings, int sections )
  25. : nRings( rings ), nSections( sections )
  26. {
  27. pTriData = NULL;
  28. pVertData = NULL;
  29. alphaVal = 255;
  30. }
  31. OBJECT::~OBJECT()
  32. {
  33. // These ptrs alloc'd in inheriting classes...
  34. if( pVertData )
  35. free( pVertData );
  36. if( pTriData )
  37. free( pTriData );
  38. }
  39. /****** SPHERE *******************************************************/
  40. SPHERE::SPHERE(
  41. int rings, int sections, float fOpacity )
  42. : OBJECT( rings, sections )
  43. {
  44. iType = OBJECT_TYPE_SPHERE;
  45. alphaVal = (int) (fOpacity * 255.0f);
  46. SS_CLAMP_TO_RANGE2( alphaVal, 0, 255 );
  47. nVerts = CalcNVertices();
  48. nTris = CalcNTriangles();
  49. // Allocate memory for the sphere data (freed by the base OBJECT class)
  50. // Vertex data
  51. pVertData = (VERTEX *) malloc( nVerts * sizeof(VERTEX) );
  52. assert( pVertData != NULL );
  53. // Triangle indices
  54. pTriData = (TRIANGLE *) malloc( nTris * sizeof(TRIANGLE) );
  55. assert( pTriData != NULL );
  56. GenerateData(1.0f);
  57. }
  58. int
  59. SPHERE::CalcNVertices()
  60. {
  61. return (((nRings)+1)*(nSections)+2);
  62. }
  63. int
  64. SPHERE::CalcNTriangles()
  65. {
  66. return (((nRings)+1)*(nSections)*2);
  67. }
  68. void
  69. SPHERE::GenerateData( float fRadius )
  70. {
  71. float fTheta, fPhi; /* Angles used to sweep around sphere */
  72. float fDTheta, fDPhi; /* Angle between each section and ring */
  73. float fX, fY, fZ, fV, fRSinTheta; /* Temporary variables */
  74. int i, j, n, m; /* counters */
  75. VERTEX *pvtx = pVertData;
  76. TRIANGLE *ptri = pTriData;
  77. //mf: ! give these different alpha values !
  78. DWORD color0 = RGBA_COLOR( 255, 0, 0, alphaVal );
  79. DWORD color1 = RGBA_COLOR( 255, 255, 0, alphaVal ); // yellow
  80. /*
  81. * Generate vertices at the top and bottom points.
  82. */
  83. pvtx[0].fX = 0.0f;
  84. pvtx[0].fY = fRadius;
  85. pvtx[0].fZ = 0.0f;
  86. pvtx[0].fNx = 0.0f;
  87. pvtx[0].fNy = 1.0f;
  88. pvtx[0].fNz = 0.0f;
  89. pvtx[0].dwColor = color0;
  90. pvtx[nVerts - 1].fX = 0.0f;
  91. pvtx[nVerts - 1].fY = -fRadius;
  92. pvtx[nVerts - 1].fZ = 0.0f;
  93. pvtx[nVerts - 1].fNx = 0.0f;
  94. pvtx[nVerts - 1].fNy = -1.0f;
  95. pvtx[nVerts - 1].fNz = 0.0f;
  96. pvtx[nVerts - 1].dwColor = color1;
  97. /*
  98. * Generate vertex points for rings
  99. */
  100. fDTheta = PI / (float) (nRings + 2);
  101. fDPhi = 2.0f * PI / (float) nSections;
  102. n = 1; /* vertex being generated, begins at 1 to skip top point */
  103. fTheta = fDTheta;
  104. for (i = 0; i <= nRings; i++)
  105. {
  106. fY = (float)(fRadius * cos(fTheta)); /* y is the same for each ring */
  107. fV = fTheta / PI; /* v is the same for each ring */
  108. fRSinTheta = (float)(fRadius * sin(fTheta));
  109. fPhi = 0.0f;
  110. for (j = 0; j < nSections; j++)
  111. {
  112. fX = (float)(fRSinTheta * sin(fPhi));
  113. fZ = (float)(fRSinTheta * cos(fPhi));
  114. pvtx[n].fX = fX;
  115. pvtx[n].fZ = fZ;
  116. pvtx[n].fY = fY;
  117. pvtx[n].fNx = fX / fRadius;
  118. pvtx[n].fNy = fY / fRadius;
  119. pvtx[n].fNz = fZ / fRadius;
  120. if (n & 1)
  121. {
  122. pvtx[n].dwColor = color0;
  123. }
  124. else
  125. {
  126. pvtx[n].dwColor = color1;
  127. }
  128. fPhi += fDPhi;
  129. n++;
  130. }
  131. fTheta += fDTheta;
  132. }
  133. /*
  134. * Generate triangles for top and bottom caps.
  135. */
  136. for (i = 0; i < nSections; i++)
  137. {
  138. ptri[i].iV1 = 0;
  139. ptri[i].iV2 = i + 1;
  140. ptri[i].iV3 = 1 + ((i + 1) % nSections);
  141. ptri[nTris - nSections + i].iV1 = nVerts - 1;
  142. ptri[nTris - nSections + i].iV2 = nVerts - 2 - i;
  143. ptri[nTris - nSections + i].iV3 = nVerts - 2 - ((1 + i) % nSections);
  144. }
  145. /*
  146. * Generate triangles for the rings
  147. */
  148. m = 1; /* first vertex in current ring, begins at 1 to skip top point*/
  149. n = nSections; /* triangle being generated, skip the top cap */
  150. for (i = 0; i < nRings; i++)
  151. {
  152. for (j = 0; j < nSections; j++)
  153. {
  154. ptri[n].iV1 = m + j;
  155. ptri[n].iV2 = m + nSections + j;
  156. ptri[n].iV3 = m + nSections + ((j + 1) % nSections);
  157. ptri[n + 1].iV1 = ptri[n].iV1;
  158. ptri[n + 1].iV2 = ptri[n].iV3;
  159. ptri[n + 1].iV3 = m + ((j + 1) % nSections);
  160. n += 2;
  161. }
  162. m += nSections;
  163. }
  164. }