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.

813 lines
24 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: genwin.c
  3. *
  4. * The Windows Logo style of the 3D Flying Objects screen saver.
  5. *
  6. * Animated 3D model of the Microsoft (R) Windows NT (TM) flag logo.
  7. *
  8. * Copyright (c) 1994 Microsoft Corporation
  9. *
  10. \**************************************************************************/
  11. #include <stdlib.h>
  12. #include <windows.h>
  13. #include <GL\gl.h>
  14. #include <string.h>
  15. #include <math.h>
  16. #include "ss3dfo.h"
  17. #define WIN_TOP_BORDER (float)0.1
  18. #define WIN_RIGHT_BORDER WIN_TOP_BORDER
  19. #define WIN_CROSSBAR (0.6522f * WIN_TOP_BORDER)
  20. #define WIN_NUMPIECES 7
  21. #define WIN_NUMCOLUMNS 6
  22. #define WIN_GAP (WIN_TOP_BORDER / 8.0f)
  23. #define WIN_GAP_X (2.0f * WIN_GAP)
  24. #define WIN_HEIGHT ((WIN_GAP * 6.0f) + \
  25. (WIN_NUMPIECES * WIN_TOP_BORDER))
  26. #define WIN_WIDTH (0.7024f * WIN_HEIGHT)
  27. #define WIN_THICKNESS WIN_CROSSBAR
  28. #define WIN_TOTALWIDTH (WIN_TOP_BORDER * 1.1f * (float)WIN_NUMCOLUMNS + \
  29. WIN_WIDTH)
  30. #define BLOCK_TOP 0x0001
  31. #define BLOCK_BOTTOM 0x0002
  32. #define BLOCK_LEFT 0x0004
  33. #define BLOCK_RIGHT 0x0008
  34. #define BLOCK_FRONT 0x0010
  35. #define BLOCK_BACK 0x0020
  36. #define BLOCK_ALL 0x003f
  37. #define DELTA_BLEND 0x2000
  38. #define NO_BLEND 0x1000
  39. #define CUBE_FACES 6
  40. #define CUBE_POINTS 8
  41. #define MAX_FRAMES 20
  42. #define MAXPREC 15
  43. #define S_IPREC 3
  44. static int Frames = 10;
  45. static MESH winMesh[MAX_FRAMES];
  46. static MESH winStreamer[MAX_FRAMES];
  47. static float sinAngle = 0.0f;
  48. static float xTrans = 0.2f;
  49. static int curMatl = 0;
  50. static int iPrec = 10;
  51. static RGBA matlBrightSpecular = {1.0f, 1.0f, 1.0f, 1.0f};
  52. static RGBA matlDimSpecular = {0.5f, 0.5f, 0.5f, 1.0f};
  53. static RGBA matlNoSpecular = {0.0f, 0.0f, 0.0f, 0.0f};
  54. static GLfloat light0Pos[] = {20.0f, -10.0f, 20.0f, 0.0f};
  55. static RGBA light1Ambient = {0.0f, 0.0f, 0.0f, 0.0f};
  56. static RGBA light1Diffuse = {0.4f, 0.4f, 0.4f, 1.0f};
  57. static RGBA light1Specular = {0.0f, 0.0f, 0.0f, 0.0f};
  58. static GLfloat light1Pos[] = {-20.0f, 5.0f, 0.0f, 0.0f};
  59. static RGBA winColors[] = {{0.3f, 0.3f, 0.3f, 1.0f},
  60. {0.94f, 0.37f, 0.13f, 1.0f}, // red
  61. {0.22f, 0.42f, 0.78f, 1.0f}, // blue
  62. {0.35f, 0.71f, 0.35f, 1.0f}, // green
  63. {0.95f, 0.82f, 0.12f, 1.0f}}; // yellow
  64. static int iPtInList(MESH *mesh, int start,
  65. POINT3D *p, POINT3D *norm, BOOL blend)
  66. {
  67. int i;
  68. POINT3D *pts = mesh->pts + start;
  69. if (blend) {
  70. for (i = start; i < mesh->numPoints; i++, pts++) {
  71. if ((pts->x == p->x) && (pts->y == p->y) && (pts->z == p->z)) {
  72. mesh->norms[i].x += norm->x;
  73. mesh->norms[i].y += norm->y;
  74. mesh->norms[i].z += norm->z;
  75. return i;
  76. }
  77. }
  78. } else {
  79. i = mesh->numPoints;
  80. }
  81. mesh->pts[i] = *p;
  82. mesh->norms[i] = *norm;
  83. mesh->numPoints++;
  84. return i;
  85. }
  86. float getZPos(float x)
  87. {
  88. float xAbs = x - xTrans;
  89. float angle = (float) (sinAngle + ((2.0 * PI) * (xAbs / WIN_TOTALWIDTH)));
  90. xAbs += (WIN_TOTALWIDTH / 2.0f);
  91. xAbs = WIN_TOTALWIDTH - xAbs;
  92. return (float)((sin((double)angle) / 4.0) *
  93. sqrt((double)(xAbs / WIN_TOTALWIDTH )));
  94. }
  95. void AddFace(MESH *mesh, int startBlend, POINT3D *pos, float w, float h)
  96. {
  97. #define FACE_VERTEX(i) \
  98. iPtInList(mesh, startBlend, pts + i, &mesh->faces[faceCount].norm, TRUE)
  99. int faceCount = mesh->numFaces;
  100. int numPts = mesh->numPoints;
  101. POINT3D *pts = mesh->pts + numPts;
  102. float zLeft = getZPos(pos->x);
  103. float zRight = getZPos(pos->x + w);
  104. pts->x = (float)pos->x;
  105. pts->y = (float)pos->y;
  106. pts->z = zLeft;
  107. pts++;
  108. pts->x = (float)pos->x;
  109. pts->y = (float)(pos->y + h);
  110. pts->z = zLeft;
  111. pts++;
  112. pts->x = (float)(pos->x + w);
  113. pts->y = (float)(pos->y + h);
  114. pts->z = zRight;
  115. pts++;
  116. pts->x = (float)(pos->x + w);
  117. pts->y = (float)pos->y;
  118. pts->z = zRight;
  119. pts -= 3;
  120. mesh->faces[faceCount].material = curMatl;
  121. ss_calcNorm(&mesh->faces[faceCount].norm, pts + 2, pts + 1, pts);
  122. mesh->faces[faceCount].p[3] = FACE_VERTEX(0);
  123. mesh->faces[faceCount].p[2] = FACE_VERTEX(1);
  124. mesh->faces[faceCount].p[1] = FACE_VERTEX(2);
  125. mesh->faces[faceCount].p[0] = FACE_VERTEX(3);
  126. mesh->numFaces++;
  127. }
  128. #define BLOCK_VERTEX(face, i)\
  129. {\
  130. if (flags & DELTA_BLEND) {\
  131. mesh->faces[faceCount].p[face] = \
  132. iPtInList(mesh, blendStart, &pts[i], &norms[((i & 0x2) >> 1)],\
  133. bBlend);\
  134. } else\
  135. mesh->faces[faceCount].p[face] = \
  136. iPtInList(mesh, blendStart, &pts[i],\
  137. &mesh->faces[faceCount].norm, bBlend);\
  138. }
  139. #define DELTA_FACT (float)10.0
  140. void AddBlock(MESH *mesh, int blendStart, POINT3D *pos,
  141. float w, float h, float d, ULONG flags)
  142. {
  143. POINT3D pts[8];
  144. POINT3D ptsL[8];
  145. POINT3D ptsR[8];
  146. POINT3D norms[2];
  147. POINT3D posPrev;
  148. float zLeft = getZPos(pos->x);
  149. float zRight = getZPos(pos->x + w);
  150. int faceCount = mesh->numFaces;
  151. BOOL bBlend = ((flags & NO_BLEND) == 0);
  152. flags |= DELTA_BLEND;
  153. pts[0].x = (float)pos->x;
  154. pts[0].y = (float)(pos->y + h);
  155. pts[0].z = zLeft;
  156. pts[1].x = (float)pos->x;
  157. pts[1].y = (float)(pos->y + h);
  158. pts[1].z = zLeft + d;
  159. pts[2].x = (float)(pos->x + w);
  160. pts[2].y = (float)(pos->y + h);
  161. pts[2].z = zRight + d;
  162. pts[3].x = (float)(pos->x + w);
  163. pts[3].y = (float)(pos->y + h);
  164. pts[3].z = zRight;
  165. pts[4].x = (float)pos->x;
  166. pts[4].y = (float)pos->y;
  167. pts[4].z = zLeft;
  168. pts[5].x = (float)pos->x;
  169. pts[5].y = (float)pos->y;
  170. pts[5].z = zLeft + d;
  171. pts[6].x = (float)(pos->x + w);
  172. pts[6].y = (float)pos->y;
  173. pts[6].z = zRight + d;
  174. pts[7].x = (float)(pos->x + w);
  175. pts[7].y = (float)pos->y;
  176. pts[7].z = zRight;
  177. if (flags & DELTA_BLEND) {
  178. float prevW = w;
  179. posPrev = *pos;
  180. w /= DELTA_FACT;
  181. zRight = getZPos(pos->x + w);
  182. ptsL[0].x = (float)pos->x;
  183. ptsL[0].y = (float)(pos->y + h);
  184. ptsL[0].z = zLeft;
  185. ptsL[1].x = (float)pos->x;
  186. ptsL[1].y = (float)(pos->y + h);
  187. ptsL[1].z = zLeft + d;
  188. ptsL[2].x = (float)(pos->x + w);
  189. ptsL[2].y = (float)(pos->y + h);
  190. ptsL[2].z = zRight + d;
  191. ptsL[3].x = (float)(pos->x + w);
  192. ptsL[3].y = (float)(pos->y + h);
  193. ptsL[3].z = zRight;
  194. ptsL[4].x = (float)pos->x;
  195. ptsL[4].y = (float)pos->y;
  196. ptsL[4].z = zLeft;
  197. ptsL[5].x = (float)pos->x;
  198. ptsL[5].y = (float)pos->y;
  199. ptsL[5].z = zLeft + d;
  200. ptsL[6].x = (float)(pos->x + w);
  201. ptsL[6].y = (float)pos->y;
  202. ptsL[6].z = zRight + d;
  203. ptsL[7].x = (float)(pos->x + w);
  204. ptsL[7].y = (float)pos->y;
  205. ptsL[7].z = zRight;
  206. pos->x += (prevW - w);
  207. zLeft = getZPos(pos->x);
  208. zRight = getZPos(pos->x + w);
  209. ptsR[0].x = (float)pos->x;
  210. ptsR[0].y = (float)(pos->y + h);
  211. ptsR[0].z = zLeft;
  212. ptsR[1].x = (float)pos->x;
  213. ptsR[1].y = (float)(pos->y + h);
  214. ptsR[1].z = zLeft + d;
  215. ptsR[2].x = (float)(pos->x + w);
  216. ptsR[2].y = (float)(pos->y + h);
  217. ptsR[2].z = zRight + d;
  218. ptsR[3].x = (float)(pos->x + w);
  219. ptsR[3].y = (float)(pos->y + h);
  220. ptsR[3].z = zRight;
  221. ptsR[4].x = (float)pos->x;
  222. ptsR[4].y = (float)pos->y;
  223. ptsR[4].z = zLeft;
  224. ptsR[5].x = (float)pos->x;
  225. ptsR[5].y = (float)pos->y;
  226. ptsR[5].z = zLeft + d;
  227. ptsR[6].x = (float)(pos->x + w);
  228. ptsR[6].y = (float)pos->y;
  229. ptsR[6].z = zRight + d;
  230. ptsR[7].x = (float)(pos->x + w);
  231. ptsR[7].y = (float)pos->y;
  232. ptsR[7].z = zRight;
  233. *pos = posPrev;
  234. }
  235. if (flags & BLOCK_TOP) {
  236. mesh->faces[faceCount].material = curMatl;
  237. ss_calcNorm(&mesh->faces[faceCount].norm, &pts[0], &pts[1], &pts[2]);
  238. if (flags & DELTA_BLEND) {
  239. ss_calcNorm(&norms[0], &ptsL[0], &ptsL[1], &ptsL[2]);
  240. ss_calcNorm(&norms[1], &ptsR[0], &ptsR[1], &ptsR[2]);
  241. }
  242. BLOCK_VERTEX(0, 0);
  243. BLOCK_VERTEX(1, 1);
  244. BLOCK_VERTEX(2, 2);
  245. BLOCK_VERTEX(3, 3);
  246. faceCount++;
  247. mesh->numFaces++;
  248. }
  249. if (flags & BLOCK_BOTTOM) {
  250. mesh->faces[faceCount].material = curMatl;
  251. ss_calcNorm(&mesh->faces[faceCount].norm, &pts[4], &pts[7], &pts[6]);
  252. if (flags & DELTA_BLEND) {
  253. ss_calcNorm(&norms[0], &ptsL[4], &ptsL[7], &ptsL[6]);
  254. ss_calcNorm(&norms[1], &ptsR[4], &ptsR[7], &ptsR[6]);
  255. }
  256. BLOCK_VERTEX(0, 4);
  257. BLOCK_VERTEX(1, 7);
  258. BLOCK_VERTEX(2, 6);
  259. BLOCK_VERTEX(3, 5);
  260. faceCount++;
  261. mesh->numFaces++;
  262. }
  263. if (flags & BLOCK_LEFT) {
  264. mesh->faces[faceCount].material = curMatl;
  265. ss_calcNorm(&mesh->faces[faceCount].norm, &pts[1], &pts[0], &pts[4]);
  266. if (flags & DELTA_BLEND) {
  267. ss_calcNorm(&norms[0], &ptsL[1], &ptsL[0], &ptsL[4]);
  268. ss_calcNorm(&norms[1], &ptsR[1], &ptsR[0], &ptsR[4]);
  269. }
  270. BLOCK_VERTEX(0, 1);
  271. BLOCK_VERTEX(1, 0);
  272. BLOCK_VERTEX(2, 4);
  273. BLOCK_VERTEX(3, 5);
  274. faceCount++;
  275. mesh->numFaces++;
  276. }
  277. if (flags & BLOCK_RIGHT) {
  278. mesh->faces[faceCount].material = curMatl;
  279. ss_calcNorm(&mesh->faces[faceCount].norm, &pts[3], &pts[2], &pts[6]);
  280. if (flags & DELTA_BLEND) {
  281. ss_calcNorm(&norms[0], &ptsL[3], &ptsL[2], &ptsL[6]);
  282. ss_calcNorm(&norms[1], &ptsR[3], &ptsR[2], &ptsR[6]);
  283. }
  284. BLOCK_VERTEX(0, 3);
  285. BLOCK_VERTEX(1, 2);
  286. BLOCK_VERTEX(2, 6);
  287. BLOCK_VERTEX(3, 7);
  288. faceCount++;
  289. mesh->numFaces++;
  290. }
  291. if (flags & BLOCK_FRONT) {
  292. mesh->faces[faceCount].material = curMatl;
  293. ss_calcNorm(&mesh->faces[faceCount].norm, &pts[0], &pts[3], &pts[7]);
  294. if (flags & DELTA_BLEND) {
  295. ss_calcNorm(&norms[0], &ptsL[0], &ptsL[3], &ptsL[7]);
  296. ss_calcNorm(&norms[1], &ptsR[0], &ptsR[3], &ptsR[7]);
  297. }
  298. BLOCK_VERTEX(0, 0);
  299. BLOCK_VERTEX(1, 3);
  300. BLOCK_VERTEX(2, 7);
  301. BLOCK_VERTEX(3, 4);
  302. faceCount++;
  303. mesh->numFaces++;
  304. }
  305. if (flags & BLOCK_BACK) {
  306. mesh->faces[faceCount].material = curMatl;
  307. ss_calcNorm(&mesh->faces[faceCount].norm, &pts[1], &pts[5], &pts[6]);
  308. if (flags & DELTA_BLEND) {
  309. ss_calcNorm(&norms[0], &ptsL[1], &ptsL[5], &ptsL[6]);
  310. ss_calcNorm(&norms[1], &ptsR[1], &ptsR[5], &ptsR[6]);
  311. }
  312. BLOCK_VERTEX(0, 1);
  313. BLOCK_VERTEX(1, 5);
  314. BLOCK_VERTEX(2, 6);
  315. BLOCK_VERTEX(3, 2);
  316. mesh->numFaces++;
  317. }
  318. }
  319. void genWin(MESH *winMesh, MESH *winStreamer)
  320. {
  321. POINT3D pos, posCenter;
  322. float w, h, d;
  323. float wMax, hMax;
  324. float xpos;
  325. int i, j, prec;
  326. int startBlend;
  327. newMesh(winMesh, CUBE_FACES * iPrec * 20, CUBE_POINTS * iPrec * 20);
  328. //
  329. // create window frame
  330. //
  331. w = (WIN_WIDTH - WIN_TOP_BORDER) / (float)iPrec;
  332. h = (float)WIN_TOP_BORDER;
  333. d = (float)WIN_THICKNESS;
  334. // draw top and bottom portions
  335. pos.y = 0.0f;
  336. pos.z = 0.0f;
  337. for (i = 0, pos.x = xTrans, startBlend = winMesh->numPoints;
  338. i < iPrec; i++, pos.x += w)
  339. AddBlock(winMesh, startBlend, &pos, w, h, d, BLOCK_TOP);
  340. for (i = 0, pos.x = xTrans, startBlend = winMesh->numPoints;
  341. i < iPrec; i++, pos.x += w)
  342. AddBlock(winMesh, startBlend, &pos, w, h, d, BLOCK_BOTTOM);
  343. for (i = 0, pos.x = xTrans, startBlend = winMesh->numPoints;
  344. i < iPrec; i++, pos.x += w)
  345. AddBlock(winMesh, startBlend, &pos, w, h, d, BLOCK_FRONT);
  346. for (i = 0, pos.x = xTrans, startBlend = winMesh->numPoints;
  347. i < iPrec; i++, pos.x += w)
  348. AddBlock(winMesh, startBlend, &pos, w, h, d, BLOCK_BACK);
  349. pos.x = xTrans;
  350. AddBlock(winMesh, 0, &pos, w, h, d, BLOCK_LEFT | NO_BLEND);
  351. pos.y = WIN_HEIGHT - WIN_TOP_BORDER;
  352. pos.z = 0.0f;
  353. for (i = 0, pos.x = xTrans, startBlend = winMesh->numPoints;
  354. i < iPrec; i++, pos.x += w)
  355. AddBlock(winMesh, startBlend, &pos, w, h, d, BLOCK_TOP);
  356. for (i = 0, pos.x = xTrans, startBlend = winMesh->numPoints;
  357. i < iPrec; i++, pos.x += w)
  358. AddBlock(winMesh, startBlend, &pos, w, h, d, BLOCK_BOTTOM);
  359. for (i = 0, pos.x = xTrans, startBlend = winMesh->numPoints;
  360. i < iPrec; i++, pos.x += w)
  361. AddBlock(winMesh, startBlend, &pos, w, h, d, BLOCK_FRONT);
  362. for (i = 0, pos.x = xTrans, startBlend = winMesh->numPoints;
  363. i < iPrec; i++, pos.x += w)
  364. AddBlock(winMesh, startBlend, &pos, w, h, d, BLOCK_BACK);
  365. pos.x = xTrans;
  366. AddBlock(winMesh, 0, &pos, w, h, d, BLOCK_LEFT | NO_BLEND);
  367. // draw middle horizontal portions
  368. prec = (iPrec / 2);
  369. w = (WIN_WIDTH - WIN_TOP_BORDER - WIN_CROSSBAR) / 2.0f;
  370. w /= (float)prec;
  371. h = WIN_CROSSBAR;
  372. pos.y = (WIN_HEIGHT - WIN_CROSSBAR) / 2.0f;
  373. pos.z = 0.0f;
  374. for (i = 0, pos.x = xTrans, startBlend = winMesh->numPoints;
  375. i < prec; i++, pos.x += w)
  376. AddBlock(winMesh, startBlend, &pos, w, h, d, BLOCK_TOP);
  377. for (i = 0, pos.x = xTrans, startBlend = winMesh->numPoints;
  378. i < prec; i++, pos.x += w)
  379. AddBlock(winMesh, startBlend, &pos, w, h, d, BLOCK_BOTTOM);
  380. for (i = 0, pos.x = xTrans, startBlend = winMesh->numPoints;
  381. i < prec; i++, pos.x += w)
  382. AddBlock(winMesh, startBlend, &pos, w, h, d, BLOCK_FRONT);
  383. for (i = 0, pos.x = xTrans, startBlend = winMesh->numPoints;
  384. i < prec; i++, pos.x += w)
  385. AddBlock(winMesh, startBlend, &pos, w, h, d, BLOCK_BACK);
  386. xpos = pos.x + WIN_CROSSBAR;
  387. for (i = 0, pos.x = xpos, startBlend = winMesh->numPoints;
  388. i < prec; i++, pos.x += w)
  389. AddBlock(winMesh, startBlend, &pos, w, h, d, BLOCK_TOP);
  390. for (i = 0, pos.x = xpos, startBlend = winMesh->numPoints;
  391. i < prec; i++, pos.x += w)
  392. AddBlock(winMesh, startBlend, &pos, w, h, d, BLOCK_BOTTOM);
  393. for (i = 0, pos.x = xpos, startBlend = winMesh->numPoints;
  394. i < prec; i++, pos.x += w)
  395. AddBlock(winMesh, startBlend, &pos, w, h, d, BLOCK_FRONT);
  396. for (i = 0, pos.x = xpos, startBlend = winMesh->numPoints;
  397. i < prec; i++, pos.x += w)
  398. AddBlock(winMesh, startBlend, &pos, w, h, d, BLOCK_BACK);
  399. pos.x = xTrans;
  400. AddBlock(winMesh, 0, &pos, w, h, d, BLOCK_LEFT | NO_BLEND);
  401. // Draw thick right-hand edge of frame
  402. pos.x = xpos = xTrans + WIN_WIDTH - WIN_RIGHT_BORDER;
  403. pos.y = 0.0f;
  404. pos.z = 0.0f;
  405. w = WIN_RIGHT_BORDER / (float)S_IPREC;
  406. h = WIN_HEIGHT;
  407. AddBlock(winMesh, winMesh->numPoints, &pos, w, h, d, BLOCK_LEFT);
  408. for (i = 0, pos.x = xpos, startBlend = winMesh->numPoints;
  409. i < S_IPREC; i++, pos.x += w)
  410. AddBlock(winMesh, startBlend, &pos, w, h, d, BLOCK_FRONT);
  411. for (i = 0, pos.x = xpos, startBlend = winMesh->numPoints;
  412. i < S_IPREC; i++, pos.x += w)
  413. AddBlock(winMesh, startBlend, &pos, w, h, d, BLOCK_BACK);
  414. for (i = 0, pos.x = xpos, startBlend = winMesh->numPoints;
  415. i < S_IPREC; i++, pos.x += w)
  416. AddBlock(winMesh, startBlend, &pos, w, h, d, BLOCK_TOP);
  417. pos.y = WIN_HEIGHT;
  418. for (i = 0, pos.x = xpos, startBlend = winMesh->numPoints;
  419. i < S_IPREC; i++, pos.x += w)
  420. AddBlock(winMesh, startBlend, &pos, w, h, d, BLOCK_BOTTOM);
  421. pos.y = 0.0f;
  422. pos.x = xTrans + WIN_WIDTH - w;
  423. AddBlock(winMesh, winMesh->numPoints, &pos, w, h, d, BLOCK_RIGHT);
  424. // draw middle-vertical portion of frame
  425. pos.x = xTrans + (WIN_WIDTH - WIN_RIGHT_BORDER) / 2.0f - (WIN_CROSSBAR / 2.0f);
  426. pos.y = WIN_TOP_BORDER;
  427. pos.z = 0.0f;
  428. w = WIN_CROSSBAR;
  429. h = WIN_HEIGHT - 2.0f * WIN_TOP_BORDER;
  430. AddBlock(winMesh, 0, &pos, w, h, d, BLOCK_ALL | NO_BLEND);
  431. //
  432. // add the panels
  433. //
  434. w = (WIN_WIDTH - WIN_RIGHT_BORDER - WIN_CROSSBAR) / 2.0f;
  435. h = (WIN_HEIGHT - 2.0f * WIN_TOP_BORDER - WIN_CROSSBAR) / 2.0f;
  436. w /= (float)(iPrec / 2);
  437. curMatl = 2;
  438. pos.x = xTrans;
  439. pos.y = WIN_TOP_BORDER;
  440. for (i = 0, startBlend = winMesh->numPoints; i < iPrec / 2; i++) {
  441. AddFace(winMesh, startBlend, &pos, w, h);
  442. pos.x += w;
  443. }
  444. curMatl = 4;
  445. pos.x += WIN_CROSSBAR;
  446. for (i = 0, startBlend = winMesh->numPoints; i < iPrec / 2; i++) {
  447. AddFace(winMesh, startBlend, &pos, w, h);
  448. pos.x += w;
  449. }
  450. curMatl = 1;
  451. pos.x = xTrans;
  452. pos.y = WIN_TOP_BORDER + h + WIN_CROSSBAR;
  453. for (i = 0, startBlend = winMesh->numPoints; i < iPrec / 2; i++) {
  454. AddFace(winMesh, startBlend, &pos, w, h);
  455. pos.x += w;
  456. }
  457. curMatl = 3;
  458. pos.x += WIN_CROSSBAR;
  459. for (i = 0, startBlend = winMesh->numPoints; i < iPrec / 2; i++) {
  460. AddFace(winMesh, startBlend, &pos, w, h);
  461. pos.x += w;
  462. }
  463. ss_normalizeNorms(winMesh->norms, winMesh->numPoints);
  464. newMesh(winStreamer, CUBE_FACES * WIN_NUMPIECES * WIN_NUMCOLUMNS,
  465. CUBE_POINTS * WIN_NUMPIECES * WIN_NUMCOLUMNS);
  466. h = hMax = WIN_TOP_BORDER;
  467. w = wMax = WIN_TOP_BORDER * 1.1f;
  468. posCenter.x = pos.x = xTrans - wMax - WIN_GAP_X;
  469. posCenter.y = pos.y = 0.0f;
  470. for (i = 0; i < WIN_NUMCOLUMNS; i++) {
  471. for (j = 0; j < WIN_NUMPIECES; j++) {
  472. if (((j % 3) == 0) || (i == 0))
  473. curMatl = 0;
  474. else if (j < 3)
  475. curMatl = 2;
  476. else
  477. curMatl = 1;
  478. AddBlock(winStreamer, 0, &pos, w, h, d, BLOCK_ALL);
  479. pos.y += (hMax + WIN_GAP);
  480. }
  481. posCenter.x -= (wMax + WIN_GAP_X);
  482. posCenter.y = 0.0f;
  483. h = h * 0.8f;
  484. w = w * 0.8f;
  485. pos.x = posCenter.x;
  486. pos.y = posCenter.y;
  487. pos.x += (wMax - w) / 2.0f;
  488. pos.y += (hMax - h) / 2.0f;
  489. }
  490. ss_normalizeNorms(winStreamer->norms, winStreamer->numPoints);
  491. }
  492. void initWinScene()
  493. {
  494. int i;
  495. float angleDelta;
  496. iPrec = (int)(fTesselFact * 10.5);
  497. if (iPrec < 5)
  498. iPrec = 5;
  499. if (iPrec > MAXPREC)
  500. iPrec = MAXPREC;
  501. glMatrixMode(GL_PROJECTION);
  502. glLoadIdentity();
  503. glOrtho(-1.0, 1.0, -0.75, 1.25, 0.0, 3.0);
  504. glTranslatef(0.0f, 0.0f, -1.5f);
  505. glLightfv(GL_LIGHT0, GL_POSITION, light0Pos);
  506. glLightfv(GL_LIGHT1, GL_AMBIENT, (GLfloat *) &light1Ambient);
  507. glLightfv(GL_LIGHT1, GL_DIFFUSE, (GLfloat *) &light1Diffuse);
  508. glLightfv(GL_LIGHT1, GL_SPECULAR, (GLfloat *) &light1Specular);
  509. glLightfv(GL_LIGHT1, GL_POSITION, light1Pos);
  510. glEnable(GL_LIGHT1);
  511. glMatrixMode(GL_MODELVIEW);
  512. glFrontFace(GL_CCW);
  513. glEnable(GL_CULL_FACE);
  514. Frames = (int)((float)(MAX_FRAMES / 2) * fTesselFact);
  515. if (Frames < 5)
  516. Frames = 5;
  517. if (Frames > MAX_FRAMES)
  518. Frames = MAX_FRAMES;
  519. angleDelta = (float) ((2.0 * PI) / Frames);
  520. sinAngle = 0.0f;
  521. for (i = 0; i < Frames; i++) {
  522. genWin(&winMesh[i], &winStreamer[i]);
  523. sinAngle += angleDelta;
  524. }
  525. }
  526. void delWinScene()
  527. {
  528. int i;
  529. for (i = 0; i < Frames; i++) {
  530. delMesh(&winMesh[i]);
  531. delMesh(&winStreamer[i]);
  532. }
  533. }
  534. void updateWinScene(int flags)
  535. {
  536. MESH *mesh;
  537. MFACE *faces;
  538. int i;
  539. static double mxrot = 23.0;
  540. static double myrot = 23.0;
  541. static double mzrot = 5.7;
  542. static double mxrotInc = 0.0;
  543. static double myrotInc = 3.0;
  544. static double mzrotInc = 0.0;
  545. static int h = 0;
  546. static int frameNum = 0;
  547. POINT3D *pp;
  548. POINT3D *pn;
  549. int lastC, lastD;
  550. int aOffs, bOffs, cOffs, dOffs;
  551. int a, b;
  552. if (bColorCycle) {
  553. ss_HsvToRgb((float)h, 1.0f, 1.0f, &winColors[0] );
  554. h++;
  555. h %= 360;
  556. }
  557. glLoadIdentity();
  558. glRotatef((GLfloat) mxrot, 1.0f, 0.0f, 0.0f);
  559. glRotatef((GLfloat) myrot, 0.0f, 1.0f, 0.0f);
  560. glRotatef((GLfloat) mzrot, 0.0f, 0.0f, 1.0f);
  561. curMatl = 0;
  562. glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, (GLfloat *) &winColors[0]);
  563. glMaterialfv(GL_FRONT, GL_SPECULAR, (GLfloat *) &matlBrightSpecular);
  564. glMaterialf(GL_FRONT, GL_SHININESS, 60.0f);
  565. mesh = &winMesh[frameNum];
  566. glBegin(GL_QUAD_STRIP);
  567. pp = mesh->pts;
  568. pn = mesh->norms;
  569. for (i = 0, faces = mesh->faces, lastC = faces->p[0], lastD = faces->p[1];
  570. i < mesh->numFaces; i++, faces++) {
  571. a = faces->p[0];
  572. b = faces->p[1];
  573. if (!bSmoothShading) {
  574. if ((a != lastC) || (b != lastD)) {
  575. glNormal3fv((GLfloat *)&(faces - 1)->norm);
  576. glVertex3fv((GLfloat *)((char *)pp +
  577. (lastC << 3) + (lastC << 2)));
  578. glVertex3fv((GLfloat *)((char *)pp +
  579. (lastD << 3) + (lastD << 2)));
  580. glEnd();
  581. glBegin(GL_QUAD_STRIP);
  582. }
  583. if (faces->material != curMatl) {
  584. curMatl = faces->material;
  585. glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR,
  586. (GLfloat *) &matlNoSpecular);
  587. glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE,
  588. (GLfloat *) &winColors[curMatl]);
  589. }
  590. glNormal3fv((GLfloat *)&faces->norm);
  591. glVertex3fv((GLfloat *)((char *)pp + (a << 3) + (a << 2)));
  592. glVertex3fv((GLfloat *)((char *)pp + (b << 3) + (b << 2)));
  593. } else {
  594. if ((a != lastC) || (b != lastD)) {
  595. cOffs = (lastC << 3) + (lastC << 2);
  596. dOffs = (lastD << 3) + (lastD << 2);
  597. glNormal3fv((GLfloat *)((char *)pn + cOffs));
  598. glVertex3fv((GLfloat *)((char *)pp + cOffs));
  599. glNormal3fv((GLfloat *)((char *)pn + dOffs));
  600. glVertex3fv((GLfloat *)((char *)pp + dOffs));
  601. glEnd();
  602. glBegin(GL_QUAD_STRIP);
  603. }
  604. aOffs = (a << 3) + (a << 2);
  605. bOffs = (b << 3) + (b << 2);
  606. if (faces->material != curMatl) {
  607. curMatl = faces->material;
  608. glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR,
  609. (GLfloat *) &matlNoSpecular);
  610. glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE,
  611. (GLfloat *) &winColors[curMatl]);
  612. }
  613. glNormal3fv((GLfloat *)((char *)pn + aOffs));
  614. glVertex3fv((GLfloat *)((char *)pp + aOffs));
  615. glNormal3fv((GLfloat *)((char *)pn + bOffs));
  616. glVertex3fv((GLfloat *)((char *)pp + bOffs));
  617. }
  618. lastC = faces->p[3];
  619. lastD = faces->p[2];
  620. }
  621. if (!bSmoothShading) {
  622. glNormal3fv((GLfloat *)&(faces - 1)->norm);
  623. glVertex3fv((GLfloat *)((char *)pp + (lastC << 3) + (lastC << 2)));
  624. glVertex3fv((GLfloat *)((char *)pp + (lastD << 3) + (lastD << 2)));
  625. } else {
  626. cOffs = (lastC << 3) + (lastC << 2);
  627. dOffs = (lastD << 3) + (lastD << 2);
  628. glNormal3fv((GLfloat *)((char *)pn + cOffs));
  629. glVertex3fv((GLfloat *)((char *)pp + cOffs));
  630. glNormal3fv((GLfloat *)((char *)pn + dOffs));
  631. glVertex3fv((GLfloat *)((char *)pp + dOffs));
  632. }
  633. glEnd();
  634. glMaterialfv(GL_FRONT, GL_SPECULAR, (GLfloat *) &matlDimSpecular);
  635. glBegin(GL_QUADS);
  636. mesh = &winStreamer[frameNum];
  637. for (i = 0, faces = mesh->faces;
  638. i < mesh->numFaces; i++, faces++) {
  639. int a, b, c, d;
  640. a = faces->p[0];
  641. b = faces->p[1];
  642. c = faces->p[2];
  643. d = faces->p[3];
  644. if (faces->material != curMatl) {
  645. curMatl = faces->material;
  646. glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE,
  647. (GLfloat *)&winColors[curMatl]);
  648. }
  649. glNormal3fv((GLfloat *)&faces->norm);
  650. glVertex3fv((GLfloat *)(mesh->pts + a));
  651. glVertex3fv((GLfloat *)(mesh->pts + b));
  652. glVertex3fv((GLfloat *)(mesh->pts + c));
  653. glVertex3fv((GLfloat *)(mesh->pts + d));
  654. }
  655. glEnd();
  656. mxrot += mxrotInc;
  657. myrot += myrotInc;
  658. mzrot += mzrotInc;
  659. if ((myrot < -45.0) || (myrot > 45.0))
  660. myrotInc = -myrotInc;
  661. frameNum++;
  662. if (frameNum >= Frames)
  663. frameNum = 0;
  664. }