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.

320 lines
9.3 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: genexpld.c
  3. *
  4. * The Explode style of the 3D Flying Objects screen saver.
  5. *
  6. * Simulation of a sphere that occasionally explodes.
  7. *
  8. * Copyright (c) 1994 Microsoft Corporation
  9. *
  10. \**************************************************************************/
  11. #include <windows.h>
  12. #include <GL\gl.h>
  13. #include <stdlib.h>
  14. #include <string.h>
  15. #include <math.h>
  16. #include "ss3dfo.h"
  17. #define RADIUS 0.3
  18. #define STEPS 30
  19. #define MAXPREC 20
  20. static MATRIX *faceMat;
  21. static float *xstep;
  22. static float *ystep;
  23. static float *zstep;
  24. static float *xrot;
  25. static float *yrot;
  26. static float *zrot;
  27. static MESH explodeMesh;
  28. static int iPrec = 10;
  29. static BOOL bOpenGL11;
  30. // Data type accepted by glInterleavedArrays
  31. typedef struct _POINT_N3F_V3F {
  32. POINT3D normal;
  33. POINT3D vertex;
  34. } POINT_N3F_V3F;
  35. static POINT_N3F_V3F *pN3V3;
  36. static GLfloat matl1Diffuse[] = {1.0f, 0.8f, 0.0f, 1.0f};
  37. static GLfloat matl2Diffuse[] = {0.8f, 0.8f, 0.8f, 1.0f};
  38. static GLfloat matlSpecular[] = {1.0f, 1.0f, 1.0f, 1.0f};
  39. static GLfloat light0Pos[] = {100.0f, 100.0f, 100.0f, 0.0f};
  40. void genExplode()
  41. {
  42. int i;
  43. POINT3D circle[MAXPREC+1];
  44. double angle;
  45. double step = -PI / (float)(iPrec - 1);
  46. double start = PI / 2.0;
  47. for (i = 0, angle = start; i < iPrec; i++, angle += step) {
  48. circle[i].x = (float) (RADIUS * cos(angle));
  49. circle[i].y = (float) (RADIUS * sin(angle));
  50. circle[i].z = 0.0f;
  51. }
  52. revolveSurface(&explodeMesh, circle, iPrec);
  53. for (i = 0; i < explodeMesh.numFaces; i++) {
  54. ss_matrixIdent(&faceMat[i]);
  55. xstep[i] = (float)(((float)(rand() & 0x3) * PI) / ((float)STEPS + 1.0));
  56. ystep[i] = (float)(((float)(rand() & 0x3) * PI) / ((float)STEPS + 1.0));
  57. zstep[i] = (float)(((float)(rand() & 0x3) * PI) / ((float)STEPS + 1.0));
  58. xrot[i] = 0.0f;
  59. yrot[i] = 0.0f;
  60. zrot[i] = 0.0f;
  61. }
  62. }
  63. void initExplodeScene()
  64. {
  65. iPrec = (int)(fTesselFact * 10.5);
  66. if (iPrec < 5)
  67. iPrec = 5;
  68. if (iPrec > MAXPREC)
  69. iPrec = MAXPREC;
  70. faceMat = (MATRIX *)SaverAlloc((iPrec * iPrec) *
  71. (4 * 4 * sizeof(float)));
  72. xstep = SaverAlloc(iPrec * iPrec * sizeof(float));
  73. ystep = SaverAlloc(iPrec * iPrec * sizeof(float));
  74. zstep = SaverAlloc(iPrec * iPrec * sizeof(float));
  75. xrot = SaverAlloc(iPrec * iPrec * sizeof(float));
  76. yrot = SaverAlloc(iPrec * iPrec * sizeof(float));
  77. zrot = SaverAlloc(iPrec * iPrec * sizeof(float));
  78. genExplode();
  79. // Find out the OpenGL version that we are running on.
  80. bOpenGL11 = ss_fOnGL11();
  81. // Setup the data arrays.
  82. pN3V3 = SaverAlloc(explodeMesh.numFaces * 4 * sizeof(POINT_N3F_V3F));
  83. // If we are running on OpenGL 1.1, use the new vertex array functions.
  84. if (bOpenGL11) {
  85. glInterleavedArrays(GL_N3F_V3F, 0, pN3V3);
  86. }
  87. glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, matl1Diffuse);
  88. glMaterialfv(GL_FRONT, GL_SPECULAR, matlSpecular);
  89. glMaterialf(GL_FRONT, GL_SHININESS, 100.0f);
  90. glMaterialfv(GL_BACK, GL_AMBIENT_AND_DIFFUSE, matl2Diffuse);
  91. glMaterialfv(GL_BACK, GL_SPECULAR, matlSpecular);
  92. glMaterialf(GL_BACK, GL_SHININESS, 60.0f);
  93. glMatrixMode(GL_PROJECTION);
  94. glLoadIdentity();
  95. glFrustum(-0.33, 0.33, -0.33, 0.33, 0.3, 3.0);
  96. glTranslatef(0.0f, 0.0f, -1.5f);
  97. }
  98. void delExplodeScene()
  99. {
  100. delMesh(&explodeMesh);
  101. SaverFree(faceMat);
  102. SaverFree(xstep);
  103. SaverFree(ystep);
  104. SaverFree(zstep);
  105. SaverFree(xrot);
  106. SaverFree(yrot);
  107. SaverFree(zrot);
  108. SaverFree(pN3V3);
  109. }
  110. void updateExplodeScene(int flags)
  111. {
  112. static double mxrot = 0.0;
  113. static double myrot = 0.0;
  114. static double mzrot = 0.0;
  115. static double mxrotInc = 0.0;
  116. static double myrotInc = 0.1;
  117. static double mzrotInc = 0.0;
  118. static float maxR;
  119. static float r = 0.0f;
  120. static float rotZ = 0.0f;
  121. static int count = 0;
  122. static int direction = 1;
  123. static int restCount = 0;
  124. static float lightSpin = 0.0f;
  125. static float spinDelta = 5.0f;
  126. static int h = 0;
  127. static RGBA color;
  128. int i;
  129. MFACE *faces;
  130. POINT_N3F_V3F *pn3v3;
  131. if( gbBounce ) {
  132. // floating window bounced off an edge
  133. if (mxrotInc) {
  134. mxrotInc = 0.0;
  135. myrotInc = 0.1;
  136. } else if (myrotInc) {
  137. myrotInc = 0.0;
  138. mzrotInc = 0.1;
  139. } else if (mzrotInc) {
  140. mzrotInc = 0.0;
  141. mxrotInc = 0.1;
  142. }
  143. gbBounce = FALSE;
  144. }
  145. mxrot += mxrotInc;
  146. myrot += myrotInc;
  147. mzrot += mzrotInc;
  148. if (bColorCycle || h == 0) {
  149. ss_HsvToRgb((float)h, 1.0f, 1.0f, &color);
  150. glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, (GLfloat *) &color);
  151. h++;
  152. h %= 360;
  153. }
  154. glMatrixMode(GL_MODELVIEW);
  155. glPushMatrix();
  156. glRotatef(-lightSpin, 0.0f, 1.0f, 0.0f);
  157. glLightfv(GL_LIGHT0, GL_POSITION, light0Pos);
  158. lightSpin += spinDelta;
  159. if ((lightSpin > 90.0) || (lightSpin < 0.0))
  160. spinDelta = -spinDelta;
  161. glPopMatrix();
  162. if (!bOpenGL11) {
  163. glBegin(GL_QUADS);
  164. }
  165. for(
  166. i = 0, faces = explodeMesh.faces, pn3v3 = pN3V3;
  167. i < explodeMesh.numFaces;
  168. i++, faces++, pn3v3 += 4
  169. ) {
  170. int a, b, c, d;
  171. int j;
  172. POINT3D vector;
  173. ss_matrixIdent(&faceMat[i]);
  174. ss_matrixRotate(&faceMat[i], xrot[i], yrot[i], zrot[i]);
  175. if (restCount)
  176. ;
  177. else {
  178. xrot[i] += (xstep[i]);
  179. yrot[i] += (ystep[i]);
  180. zrot[i] += (zstep[i]);
  181. }
  182. a = faces->p[0];
  183. b = faces->p[1];
  184. c = faces->p[3];
  185. d = faces->p[2];
  186. memcpy(&pn3v3[0].vertex, (explodeMesh.pts + a), sizeof(POINT3D));
  187. memcpy(&pn3v3[1].vertex, (explodeMesh.pts + b), sizeof(POINT3D));
  188. memcpy(&pn3v3[2].vertex, (explodeMesh.pts + c), sizeof(POINT3D));
  189. memcpy(&pn3v3[3].vertex, (explodeMesh.pts + d), sizeof(POINT3D));
  190. vector.x = pn3v3[0].vertex.x;
  191. vector.y = pn3v3[0].vertex.y;
  192. vector.z = pn3v3[0].vertex.z;
  193. for (j = 0; j < 4; j++) {
  194. pn3v3[j].vertex.x -= vector.x;
  195. pn3v3[j].vertex.y -= vector.y;
  196. pn3v3[j].vertex.z -= vector.z;
  197. ss_xformPoint((POINT3D *)&pn3v3[j].vertex, (POINT3D *)&pn3v3[j].vertex, &faceMat[i]);
  198. pn3v3[j].vertex.x += vector.x + (vector.x * r);
  199. pn3v3[j].vertex.y += vector.y + (vector.y * r);
  200. pn3v3[j].vertex.z += vector.z + (vector.z * r);
  201. }
  202. if (bSmoothShading) {
  203. memcpy(&pn3v3[0].normal, (explodeMesh.norms + a), sizeof(POINT3D));
  204. memcpy(&pn3v3[1].normal, (explodeMesh.norms + b), sizeof(POINT3D));
  205. memcpy(&pn3v3[2].normal, (explodeMesh.norms + c), sizeof(POINT3D));
  206. memcpy(&pn3v3[3].normal, (explodeMesh.norms + d), sizeof(POINT3D));
  207. for (j = 0; j < 4; j++)
  208. ss_xformNorm((POINT3D *)&pn3v3[j].normal, (POINT3D *)&pn3v3[j].normal, &faceMat[i]);
  209. } else {
  210. memcpy(&pn3v3[0].normal, &faces->norm, sizeof(POINT3D));
  211. ss_xformNorm((POINT3D *)&pn3v3[0].normal, (POINT3D *)&pn3v3[0].normal, &faceMat[i]);
  212. memcpy(&pn3v3[1].normal, &pn3v3[0].normal, sizeof(POINT3D));
  213. memcpy(&pn3v3[2].normal, &pn3v3[0].normal, sizeof(POINT3D));
  214. memcpy(&pn3v3[3].normal, &pn3v3[0].normal, sizeof(POINT3D));
  215. }
  216. if (!bOpenGL11) {
  217. if (bSmoothShading) {
  218. glNormal3fv((GLfloat *)&pn3v3[0].normal);
  219. glVertex3fv((GLfloat *)&pn3v3[0].vertex);
  220. glNormal3fv((GLfloat *)&pn3v3[1].normal);
  221. glVertex3fv((GLfloat *)&pn3v3[1].vertex);
  222. glNormal3fv((GLfloat *)&pn3v3[2].normal);
  223. glVertex3fv((GLfloat *)&pn3v3[2].vertex);
  224. glNormal3fv((GLfloat *)&pn3v3[3].normal);
  225. glVertex3fv((GLfloat *)&pn3v3[3].vertex);
  226. } else {
  227. glNormal3fv((GLfloat *)&pn3v3[0].normal);
  228. glVertex3fv((GLfloat *)&pn3v3[0].vertex);
  229. glVertex3fv((GLfloat *)&pn3v3[1].vertex);
  230. glVertex3fv((GLfloat *)&pn3v3[2].vertex);
  231. glVertex3fv((GLfloat *)&pn3v3[3].vertex);
  232. }
  233. }
  234. }
  235. if (bOpenGL11) {
  236. glDrawArrays(GL_QUADS, 0, explodeMesh.numFaces * 4);
  237. } else {
  238. glEnd();
  239. }
  240. if (restCount) {
  241. restCount--;
  242. goto resting;
  243. }
  244. if (direction) {
  245. maxR = r;
  246. r += (float) (0.3 * pow((double)(STEPS - count) / (double)STEPS, 4.0));
  247. } else {
  248. r -= (float) (maxR / (double)(STEPS));
  249. }
  250. count++;
  251. if (count > STEPS) {
  252. direction ^= 1;
  253. count = 0;
  254. if (direction == 1) {
  255. restCount = 10;
  256. r = 0.0f;
  257. for (i = 0; i < explodeMesh.numFaces; i++) {
  258. ss_matrixIdent(&faceMat[i]);
  259. xstep[i] = (float) (((float)(rand() & 0x3) * PI) / ((float)STEPS + 1.0));
  260. ystep[i] = (float) (((float)(rand() & 0x3) * PI) / ((float)STEPS + 1.0));
  261. zstep[i] = (float) (((float)(rand() & 0x3) * PI) / ((float)STEPS + 1.0));
  262. xrot[i] = 0.0f;
  263. yrot[i] = 0.0f;
  264. zrot[i] = 0.0f;
  265. }
  266. }
  267. }
  268. resting:
  269. ;
  270. }