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.

1555 lines
37 KiB

  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <math.h>
  4. #include <string.h>
  5. #include <time.h>
  6. #include <float.h>
  7. #include <windows.h>
  8. #include <gl\gl.h>
  9. #include <gl\glu.h>
  10. #include <gl\glaux.h>
  11. // #define PROFILE 1
  12. #ifdef PROFILE
  13. #include <icapexp.h>
  14. #endif
  15. typedef struct
  16. {
  17. float x, y, z;
  18. float nx, ny, nz;
  19. float tu, tv;
  20. DWORD color;
  21. } D3DVERTEX;
  22. typedef D3DVERTEX *LPD3DVERTEX;
  23. typedef struct
  24. {
  25. int v1;
  26. int v2;
  27. int v3;
  28. } D3DTRIANGLE;
  29. typedef D3DTRIANGLE *LPD3DTRIANGLE;
  30. #define D3DVAL(f) ((float)(f))
  31. #define RGB_MAKE(r, g, b) \
  32. (((DWORD)((r) & 0xff) << 0) | \
  33. ((DWORD)((g) & 0xff) << 8) | \
  34. ((DWORD)((b) & 0xff) << 16) | \
  35. ((DWORD)(0xff) << 24))
  36. typedef float __GLfloat;
  37. typedef struct
  38. {
  39. __GLfloat matrix[4][4];
  40. } __GLmatrix;
  41. __GLmatrix identity =
  42. {
  43. 1.0f, 0.0f, 0.0f, 0.0f,
  44. 0.0f, 1.0f, 0.0f, 0.0f,
  45. 0.0f, 0.0f, 1.0f, 0.0f,
  46. 0.0f, 0.0f, 0.0f, 1.0f
  47. };
  48. void __glMultMatrix(__GLmatrix *r, const __GLmatrix *a, const __GLmatrix *b)
  49. {
  50. __GLfloat b00, b01, b02, b03;
  51. __GLfloat b10, b11, b12, b13;
  52. __GLfloat b20, b21, b22, b23;
  53. __GLfloat b30, b31, b32, b33;
  54. GLint i;
  55. b00 = b->matrix[0][0]; b01 = b->matrix[0][1];
  56. b02 = b->matrix[0][2]; b03 = b->matrix[0][3];
  57. b10 = b->matrix[1][0]; b11 = b->matrix[1][1];
  58. b12 = b->matrix[1][2]; b13 = b->matrix[1][3];
  59. b20 = b->matrix[2][0]; b21 = b->matrix[2][1];
  60. b22 = b->matrix[2][2]; b23 = b->matrix[2][3];
  61. b30 = b->matrix[3][0]; b31 = b->matrix[3][1];
  62. b32 = b->matrix[3][2]; b33 = b->matrix[3][3];
  63. for (i = 0; i < 4; i++) {
  64. r->matrix[i][0] = a->matrix[i][0]*b00 + a->matrix[i][1]*b10
  65. + a->matrix[i][2]*b20 + a->matrix[i][3]*b30;
  66. r->matrix[i][1] = a->matrix[i][0]*b01 + a->matrix[i][1]*b11
  67. + a->matrix[i][2]*b21 + a->matrix[i][3]*b31;
  68. r->matrix[i][2] = a->matrix[i][0]*b02 + a->matrix[i][1]*b12
  69. + a->matrix[i][2]*b22 + a->matrix[i][3]*b32;
  70. r->matrix[i][3] = a->matrix[i][0]*b03 + a->matrix[i][1]*b13
  71. + a->matrix[i][2]*b23 + a->matrix[i][3]*b33;
  72. }
  73. }
  74. void MakePosMatrix(__GLmatrix *lpM, float x, float y, float z)
  75. {
  76. memcpy(lpM, &identity, sizeof(__GLmatrix));
  77. lpM->matrix[3][0] = D3DVAL(x);
  78. lpM->matrix[3][1] = D3DVAL(y);
  79. lpM->matrix[3][2] = D3DVAL(z);
  80. }
  81. void MakeRotMatrix(__GLmatrix *lpM, float rx, float ry, float rz)
  82. {
  83. float ct, st;
  84. __GLmatrix My, Mx, Mz, T;
  85. memcpy(&My, &identity, sizeof(__GLmatrix));
  86. ct = D3DVAL(cos(ry));
  87. st = D3DVAL(sin(ry));
  88. My.matrix[0][0] = ct;
  89. My.matrix[0][2] = -st;
  90. My.matrix[2][0] = st;
  91. My.matrix[2][2] = ct;
  92. memcpy(&Mx, &identity, sizeof(__GLmatrix));
  93. ct = D3DVAL(cos(rx));
  94. st = D3DVAL(sin(rx));
  95. Mx.matrix[1][1] = ct;
  96. Mx.matrix[1][2] = st;
  97. Mx.matrix[2][1] = -st;
  98. Mx.matrix[2][2] = ct;
  99. memcpy(&Mz, &identity, sizeof(__GLmatrix));
  100. ct = D3DVAL(cos(rz));
  101. st = D3DVAL(sin(rz));
  102. Mz.matrix[0][0] = ct;
  103. Mz.matrix[0][1] = st;
  104. Mz.matrix[1][0] = -st;
  105. Mz.matrix[1][1] = ct;
  106. __glMultMatrix(&T, &My, &Mx);
  107. __glMultMatrix(lpM, &T, &Mz);
  108. }
  109. void *Malloc(size_t bytes)
  110. {
  111. void *pv;
  112. pv = malloc(bytes);
  113. if (pv == NULL)
  114. {
  115. printf("Unable to alloc %d bytes\n", bytes);
  116. exit(1);
  117. }
  118. return pv;
  119. }
  120. #define PI ((float)3.14159265358979323846)
  121. #define WIDTH 400
  122. #define HEIGHT 400
  123. #define SPWIDTH 140
  124. #define SPHEIGHT 140
  125. #define MAWIDTH 90
  126. #define MAHEIGHT 75
  127. #define LAWIDTH 230
  128. #define LAHEIGHT 190
  129. int iSwapWidth, iSwapHeight;
  130. #define SRADIUS 0.4f
  131. #define DMINUSR 0.6
  132. #define DV 0.05
  133. #define DR 0.3
  134. #define DEPTH 0.6f
  135. #define random(x) (((float)rand() / RAND_MAX) * (x))
  136. #define FILL_TRIANGLES 50
  137. #define MEDIUM_AREA 3000
  138. #define LARGE_AREA 20000
  139. #define FRONT_TO_BACK 0
  140. #define BACK_TO_FRONT 1
  141. #define ORDER_COUNT 2
  142. int iOrder = FRONT_TO_BACK;
  143. char *pszOrders[] =
  144. {
  145. "front-to-back",
  146. "back-to-front"
  147. };
  148. #define AREA_LARGE 0
  149. #define AREA_MEDIUM 1
  150. #define AREA_COUNT 2
  151. int iFillSize = AREA_MEDIUM;
  152. int iTriangleArea;
  153. typedef struct _Sphere
  154. {
  155. GLfloat xrv, yrv, zrv;
  156. __GLmatrix pos, dpos;
  157. __GLmatrix rot, drot;
  158. } Sphere;
  159. #define NSPHERES 8
  160. Sphere spheres[NSPHERES];
  161. BOOL fSingle = FALSE;
  162. BOOL fRotate = TRUE;
  163. BOOL fBounce = TRUE;
  164. BOOL fSwap = TRUE;
  165. BOOL fPaused = FALSE;
  166. BOOL fUseScissor = TRUE;
  167. BOOL fSpread = FALSE;
  168. BOOL fExit = FALSE;
  169. BOOL fSingleColor = TRUE;
  170. BOOL fVerbose = FALSE;
  171. BOOL fDisplayList = TRUE;
  172. int iMultiLoop = 1;
  173. int nRings = 30;
  174. int nSections = 30;
  175. GLint iDlist;
  176. #define TEXOBJ
  177. #ifdef TEXOBJ
  178. GLuint uiTexObj;
  179. #endif
  180. PFNGLADDSWAPHINTRECTWINPROC glAddSwapHintRectWIN;
  181. #define TEST_FILL 0
  182. #define TEST_POLYS 1
  183. #define TEST_COUNT 2
  184. int iTest = TEST_POLYS;
  185. AUX_RGBImageRec *pTexture;
  186. #define TEXMODE_REPLACE 0
  187. #define TEXMODE_DECAL 1
  188. #define TEXMODE_MODULATE 2
  189. #define TEXMODE_COUNT 3
  190. int iTexMode = TEXMODE_REPLACE;
  191. char *pszTexModes[] =
  192. {
  193. "replace", "decal", "modulate"
  194. };
  195. GLenum eTexModes[] =
  196. {
  197. GL_REPLACE, GL_DECAL, GL_MODULATE
  198. };
  199. BOOL fPerspective = TRUE;
  200. //--------------------------------------------------------------------------;
  201. //
  202. // FunctionName: GenerateSphere()
  203. //
  204. // Purpose:
  205. // Generate the geometry of a sphere.
  206. //
  207. // Returns BOOL
  208. //
  209. // History:
  210. // 11/17/95 RichGr
  211. //
  212. //--------------------------------------------------------------------------;
  213. /*
  214. * Generates a sphere around the y-axis centered at the origin including
  215. * normals and texture coordinates. Returns TRUE on success and FALSE on
  216. * failure.
  217. * sphere_r Radius of the sphere.
  218. * num_rings Number of full rings not including the top and bottom
  219. * caps.
  220. * num_sections Number of sections each ring is divided into. Each
  221. * section contains two triangles on full rings and one
  222. * on top and bottom caps.
  223. * sx, sy, sz Scaling along each axis. Set each to 1.0 for a
  224. * perfect sphere.
  225. * plpv On exit points to the vertices of the sphere. The
  226. * function allocates this space. Not allocated if
  227. * function fails.
  228. * plptri On exit points to the triangles of the sphere which
  229. * reference vertices in the vertex list. The function
  230. * allocates this space. Not allocated if function fails.
  231. * pnum_v On exit contains the number of vertices.
  232. * pnum_tri On exit contains the number of triangles.
  233. */
  234. BOOL GenerateSphere(float sphere_r, int num_rings, int num_sections,
  235. float sx, float sy, float sz, LPD3DVERTEX* plpv,
  236. LPD3DTRIANGLE* plptri, int* pnum_v, int* pnum_tri)
  237. {
  238. float theta, phi; /* Angles used to sweep around sphere */
  239. float dtheta, dphi; /* Angle between each section and ring */
  240. float x, y, z, v, rsintheta; /* Temporary variables */
  241. int i, j, n, m; /* counters */
  242. int num_v, num_tri; /* Internal vertex and triangle count */
  243. LPD3DVERTEX lpv; /* Internal pointer for vertices */
  244. LPD3DTRIANGLE lptri; /* Internal pointer for trianlges */
  245. /*
  246. * Check the parameters to make sure they are valid.
  247. */
  248. if ((sphere_r <= 0)
  249. || (num_rings < 1)
  250. || (num_sections < 3)
  251. || (sx <= 0) || (sy <= 0) || (sz <= 0))
  252. return FALSE;
  253. /*
  254. * Generate space for the required triangles and vertices.
  255. */
  256. num_tri = (num_rings + 1) * num_sections * 2;
  257. num_v = (num_rings + 1) * num_sections + 2;
  258. *plpv = (LPD3DVERTEX)Malloc(sizeof(D3DVERTEX) * num_v);
  259. *plptri = (LPD3DTRIANGLE)Malloc(sizeof(D3DTRIANGLE) * num_tri);
  260. lpv = *plpv;
  261. lptri = *plptri;
  262. *pnum_v = num_v;
  263. *pnum_tri = num_tri;
  264. /*
  265. * Generate vertices at the top and bottom points.
  266. */
  267. lpv[0].x = D3DVAL(0.0f);
  268. lpv[0].y = D3DVAL(sy * sphere_r);
  269. lpv[0].z = D3DVAL(0.0f);
  270. lpv[0].nx = D3DVAL(0.0f);
  271. lpv[0].ny = D3DVAL(1.0f);
  272. lpv[0].nz = D3DVAL(0.0f);
  273. lpv[0].color = RGB_MAKE(0, 0, 255);
  274. lpv[0].tu = D3DVAL(0.0f);
  275. lpv[0].tv = D3DVAL(0.0f);
  276. lpv[num_v - 1].x = D3DVAL(0.0f);
  277. lpv[num_v - 1].y = D3DVAL(sy * -sphere_r);
  278. lpv[num_v - 1].z = D3DVAL(0.0f);
  279. lpv[num_v - 1].nx = D3DVAL(0.0f);
  280. lpv[num_v - 1].ny = D3DVAL(-1.0f);
  281. lpv[num_v - 1].nz = D3DVAL(0.0f);
  282. lpv[num_v - 1].tu = D3DVAL(0.0f);
  283. lpv[num_v - 1].tv = D3DVAL(1.0f);
  284. lpv[num_v - 1].color = RGB_MAKE(0, 255, 0);
  285. /*
  286. * Generate vertex points for rings
  287. */
  288. dtheta = PI / (float) (num_rings + 2);
  289. dphi = 2.0f * PI / (float) num_sections;
  290. n = 1; /* vertex being generated, begins at 1 to skip top point */
  291. theta = dtheta;
  292. for (i = 0; i <= num_rings; i++)
  293. {
  294. y = (float)(sphere_r * cos(theta)); /* y is the same for each ring */
  295. v = theta / PI; /* v is the same for each ring */
  296. rsintheta = (float)(sphere_r * sin(theta));
  297. phi = 0.0f;
  298. for (j = 0; j < num_sections; j++)
  299. {
  300. x = (float)(rsintheta * sin(phi));
  301. z = (float)(rsintheta * cos(phi));
  302. lpv[n].x = D3DVAL(sx * x);
  303. lpv[n].z = D3DVAL(sz * z);
  304. lpv[n].y = D3DVAL(sy * y);
  305. lpv[n].nx = D3DVAL(x / sphere_r);
  306. lpv[n].ny = D3DVAL(y / sphere_r);
  307. lpv[n].nz = D3DVAL(z / sphere_r);
  308. lpv[n].tv = D3DVAL(v);
  309. lpv[n].tu = D3DVAL(1.0f - phi / (2.0f * PI));
  310. if (n & 1)
  311. {
  312. lpv[n].color = RGB_MAKE(0, 0, 255);
  313. }
  314. else
  315. {
  316. lpv[n].color = RGB_MAKE(0, 255, 0);
  317. }
  318. phi += dphi;
  319. ++n;
  320. }
  321. theta += dtheta;
  322. }
  323. /*
  324. * Generate triangles for top and bottom caps.
  325. */
  326. for (i = 0; i < num_sections; i++)
  327. {
  328. lptri[i].v1 = 0;
  329. lptri[i].v2 = i + 1;
  330. lptri[i].v3 = 1 + ((i + 1) % num_sections);
  331. // lptri[i].flags = D3D_EDGE_ENABLE_TRIANGLE;
  332. lptri[num_tri - num_sections + i].v1 = num_v - 1;
  333. lptri[num_tri - num_sections + i].v2 = num_v - 2 - i;
  334. lptri[num_tri - num_sections + i].v3 = num_v - 2 - ((1 + i) % num_sections);
  335. // lptri[num_tri - num_sections + i].flags= D3D_EDGE_ENABLE_TRIANGLE;
  336. }
  337. /*
  338. * Generate triangles for the rings
  339. */
  340. m = 1; /* first vertex in current ring,begins at 1 to skip top point*/
  341. n = num_sections; /* triangle being generated, skip the top cap */
  342. for (i = 0; i < num_rings; i++)
  343. {
  344. for (j = 0; j < num_sections; j++)
  345. {
  346. lptri[n].v1 = m + j;
  347. lptri[n].v2 = m + num_sections + j;
  348. lptri[n].v3 = m + num_sections + ((j + 1) % num_sections);
  349. // lptri[n].flags = D3D_EDGE_ENABLE_TRIANGLE;
  350. lptri[n + 1].v1 = lptri[n].v1;
  351. lptri[n + 1].v2 = lptri[n].v3;
  352. lptri[n + 1].v3 = m + ((j + 1) % num_sections);
  353. // lptri[n + 1].flags = D3D_EDGE_ENABLE_TRIANGLE;
  354. n += 2;
  355. }
  356. m += num_sections;
  357. }
  358. return TRUE;
  359. }
  360. // Creates triangle and quad strip index sets for vertex data generated
  361. // by GenerateSphere. The top and bottom triangle fans are omitted because
  362. // they're degenerate cases for strips
  363. int CreateStrip(int nSections, int **ppiStrip)
  364. {
  365. int nPts;
  366. int *piIdx, iIdxBase;
  367. int iRing, iSection;
  368. // Stick to a single strip for now
  369. nRings = 1;
  370. nPts = nRings*(nSections+1)*2;
  371. *ppiStrip = (int *)Malloc(sizeof(int)*nPts);
  372. piIdx = *ppiStrip;
  373. iIdxBase = 1;
  374. for (iRing = 0; iRing < nRings; iRing++)
  375. {
  376. for (iSection = 0; iSection <= nSections; iSection++)
  377. {
  378. *piIdx++ = iIdxBase+(iSection % nSections);
  379. *piIdx++ = iIdxBase+(iSection % nSections)+nSections;
  380. }
  381. iIdxBase += nSections;
  382. }
  383. return nPts;
  384. }
  385. float fltCenter[NSPHERES][2] =
  386. {
  387. -SRADIUS, 0.0f,
  388. 0.0f, SRADIUS,
  389. SRADIUS, 0.0f,
  390. 0.0f, -SRADIUS
  391. };
  392. void InitSpheres(void)
  393. {
  394. int i;
  395. Sphere *sp;
  396. float x, y, z;
  397. #if 0
  398. srand(time(NULL));
  399. #else
  400. srand( (unsigned)8269362521);
  401. #endif
  402. for (i = 0; i < NSPHERES; i++)
  403. {
  404. sp = &spheres[i];
  405. if (fBounce)
  406. {
  407. x = (float)DMINUSR - (float)random(2 * DMINUSR);
  408. y = (float)DMINUSR - (float)random(2 * DMINUSR);
  409. z = (float)-DEPTH + (float)random(2 * DEPTH);
  410. }
  411. else
  412. {
  413. x = fltCenter[i][0];
  414. y = fltCenter[i][1];
  415. z = 0.0f;
  416. }
  417. MakePosMatrix(&sp->pos, x, y, z);
  418. x = (float)DV - (float)random(2 * DV);
  419. y = (float)DV - (float)random(2 * DV);
  420. z = (float)DV - (float)random(2 * DV);
  421. MakePosMatrix(&sp->dpos, x, y, z);
  422. MakeRotMatrix(&sp->rot, 0.0f, 0.0f, 0.0f);
  423. sp->xrv = (float)DR - (float)random(2 * DR);
  424. sp->yrv = (float)DR - (float)random(2 * DR);
  425. sp->zrv = (float)DR - (float)random(2 * DR);
  426. MakeRotMatrix(&sp->drot, sp->xrv, sp->yrv, sp->zrv);
  427. }
  428. }
  429. void UpdateSphere(Sphere *sp)
  430. {
  431. GLboolean newRot;
  432. if (fBounce)
  433. {
  434. newRot = GL_FALSE;
  435. if (sp->pos.matrix[3][0] > DMINUSR || sp->pos.matrix[3][0] < -DMINUSR)
  436. {
  437. sp->dpos.matrix[3][0] = -sp->dpos.matrix[3][0];
  438. sp->zrv = -sp->zrv;
  439. sp->yrv = -sp->yrv;
  440. newRot = GL_TRUE;
  441. }
  442. if (sp->pos.matrix[3][1] > DMINUSR || sp->pos.matrix[3][1] < -DMINUSR)
  443. {
  444. sp->dpos.matrix[3][1] = -sp->dpos.matrix[3][1];
  445. sp->zrv = -sp->zrv;
  446. sp->xrv = -sp->xrv;
  447. newRot = GL_TRUE;
  448. }
  449. if (sp->pos.matrix[3][2] > DEPTH || sp->pos.matrix[3][2] < -DEPTH)
  450. {
  451. sp->dpos.matrix[3][2] = -sp->dpos.matrix[3][2];
  452. sp->xrv = -sp->xrv;
  453. sp->yrv = -sp->yrv;
  454. newRot = GL_TRUE;
  455. }
  456. if (newRot)
  457. {
  458. MakeRotMatrix(&sp->drot, sp->xrv, sp->yrv, sp->zrv);
  459. }
  460. __glMultMatrix(&sp->pos, &sp->dpos, &sp->pos);
  461. }
  462. if (fRotate)
  463. {
  464. __glMultMatrix(&sp->rot, &sp->drot, &sp->rot);
  465. }
  466. }
  467. #define TAN_60 1.732
  468. void SetTriangleVertices(LPD3DVERTEX v, float z, UINT ww, UINT wh, float a,
  469. int ox, int oy)
  470. {
  471. float dx, dy;
  472. float b = (float)sqrt((4 * a) / TAN_60);
  473. float h = (2 * a) / b;
  474. float x = (float)((b / 2) * (TAN_60 / 2));
  475. float cx, cy;
  476. dx = (float)ww;
  477. dy = (float)wh;
  478. cx = dx / 2 + ox;
  479. cy = dy / 2 + oy;
  480. /* V 0 */
  481. v[0].x = cx;
  482. v[0].y = cy + (h - x);
  483. v[0].z = z;
  484. v[0].color = RGB_MAKE(255, 0, 0);
  485. v[0].tu = D3DVAL(0.5);
  486. v[0].tv = D3DVAL(0.0);
  487. /* V 1 */
  488. v[1].x = cx + (b / 2);
  489. v[1].y = cy - x;
  490. v[1].z = z;
  491. v[1].color = RGB_MAKE(255, 255, 255);
  492. v[1].tu = D3DVAL(1.0);
  493. v[1].tv = D3DVAL(1.0);
  494. /* V 2 */
  495. v[2].x = cx - (b / 2);
  496. v[2].y = cy - x;
  497. v[2].z = z;
  498. v[2].color = RGB_MAKE(255, 255, 0);
  499. v[2].tu = D3DVAL(0.0);
  500. v[2].tv = D3DVAL(1.0);
  501. }
  502. void InitFill(LPD3DVERTEX *ppVertices, LPD3DTRIANGLE *ppTriangles)
  503. {
  504. *ppVertices = (LPD3DVERTEX)Malloc(3 * FILL_TRIANGLES * sizeof(D3DVERTEX));
  505. *ppTriangles = (LPD3DTRIANGLE)Malloc(FILL_TRIANGLES * sizeof(D3DTRIANGLE));
  506. }
  507. D3DVERTEX *pPolyVertices;
  508. D3DTRIANGLE *pPolyTriangles;
  509. int nNumVertices, nNumFaces;
  510. int *pPolyStrip;
  511. int nStripIndices;
  512. D3DVERTEX *pFillVertices;
  513. D3DTRIANGLE *pFillTriangles;
  514. int *pIndices;
  515. int nIndices;
  516. int nTriangles;
  517. #define POLYMODE_POINT 0
  518. #define POLYMODE_LINE 1
  519. #define POLYMODE_FILL 2
  520. #define POLYMODE_COUNT 3
  521. GLenum ePolygonModes[] =
  522. {
  523. GL_POINT, GL_LINE, GL_FILL
  524. };
  525. int iPolygonMode = POLYMODE_FILL;
  526. #define SMODEL_SMOOTH 0
  527. #define SMODEL_FLAT 1
  528. #define SMODEL_COUNT 2
  529. GLenum eShadeModels[] =
  530. {
  531. GL_SMOOTH, GL_FLAT
  532. };
  533. char *pszShadeModels[] =
  534. {
  535. "smooth", "flat"
  536. };
  537. int iShadeModel = SMODEL_SMOOTH;
  538. #define PRIM_TRIANGLES 0
  539. #define PRIM_TSTRIP 1
  540. #define PRIM_QSTRIP 2
  541. #define PRIM_COUNT 3
  542. GLenum ePrimTypes[] =
  543. {
  544. GL_TRIANGLES, GL_TRIANGLE_STRIP, GL_QUAD_STRIP
  545. };
  546. char *pszPrimTypes[] =
  547. {
  548. "Tris",
  549. "TStrip",
  550. "QStrip"
  551. };
  552. int iPrimType = PRIM_TRIANGLES;
  553. int total_ms = 0;
  554. int total_tris = 0 ;
  555. double peak_tri = 0, peak_fill = 0, avg_tri = 0, avg_fill = 0;
  556. int avg_cnt = 0;
  557. void ModeChange(void)
  558. {
  559. total_ms = 0;
  560. total_tris = 0;
  561. avg_tri = 0;
  562. avg_fill = 0;
  563. avg_cnt = 0;
  564. }
  565. void SetPrim(int iNew)
  566. {
  567. ModeChange();
  568. iPrimType = iNew;
  569. switch(iTest)
  570. {
  571. case TEST_POLYS:
  572. switch(iPrimType)
  573. {
  574. case PRIM_TRIANGLES:
  575. pIndices = (int *)pPolyTriangles;
  576. nIndices = nNumFaces*3;
  577. nTriangles = nNumFaces;
  578. break;
  579. case PRIM_TSTRIP:
  580. case PRIM_QSTRIP:
  581. pIndices = pPolyStrip;
  582. nIndices = nStripIndices;
  583. nTriangles = nSections*2;
  584. break;
  585. }
  586. nTriangles *= NSPHERES;
  587. break;
  588. case TEST_FILL:
  589. pIndices = (int *)pFillTriangles;
  590. nIndices = FILL_TRIANGLES*3;
  591. nTriangles = FILL_TRIANGLES;
  592. break;
  593. }
  594. }
  595. void SetVertexArrayVertices(LPD3DVERTEX pVertices)
  596. {
  597. glVertexPointer(3, GL_FLOAT, sizeof(D3DVERTEX), &pVertices[0].x);
  598. glNormalPointer(GL_FLOAT, sizeof(D3DVERTEX), &pVertices[0].nx);
  599. glTexCoordPointer(2, GL_FLOAT, sizeof(D3DVERTEX), &pVertices[0].tu);
  600. glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(D3DVERTEX),
  601. &pVertices[0].color);
  602. }
  603. void SetFill(int iNewSize, int iNewOrder)
  604. {
  605. int i;
  606. float z;
  607. int NumTri;
  608. LPD3DVERTEX pVert;
  609. LPD3DTRIANGLE pTri;
  610. UINT w, h;
  611. float area;
  612. int ox, oy, dox, doy;
  613. RECT rct;
  614. ModeChange();
  615. iFillSize = iNewSize;
  616. iOrder = iNewOrder;
  617. switch(iFillSize)
  618. {
  619. case AREA_LARGE:
  620. iTriangleArea = LARGE_AREA;
  621. iSwapWidth = LAWIDTH;
  622. iSwapHeight = LAHEIGHT;
  623. break;
  624. case AREA_MEDIUM:
  625. iTriangleArea = MEDIUM_AREA;
  626. iSwapWidth = MAWIDTH;
  627. iSwapHeight = MAHEIGHT;
  628. break;
  629. }
  630. glScissor((WIDTH-iSwapWidth)/2, (HEIGHT-iSwapHeight)/2,
  631. iSwapWidth, iSwapHeight);
  632. w = WIDTH;
  633. h = HEIGHT;
  634. NumTri = FILL_TRIANGLES;
  635. pVert = pFillVertices;
  636. if (fSpread)
  637. {
  638. ox = -NumTri*2;
  639. oy = -NumTri*2;
  640. dox = 4;
  641. doy = 4;
  642. }
  643. else
  644. {
  645. ox = 0;
  646. oy = 0;
  647. dox = 0;
  648. doy = 0;
  649. }
  650. if (iOrder == FRONT_TO_BACK)
  651. {
  652. for (i = 0, z = (float)0.0; i < NumTri; i++, z -= (float)0.9 / NumTri)
  653. {
  654. SetTriangleVertices(pVert, z, w, h, (float)iTriangleArea,
  655. ox, oy);
  656. pVert += 3;
  657. ox += dox;
  658. oy += doy;
  659. }
  660. }
  661. else
  662. {
  663. for (i = 0, z = (float)-0.9; i < NumTri; i++, z += (float)0.9 / NumTri)
  664. {
  665. SetTriangleVertices(pVert, z, w, h, (float)iTriangleArea,
  666. ox, oy);
  667. pVert += 3;
  668. ox += dox;
  669. oy += doy;
  670. }
  671. }
  672. pTri = pFillTriangles;
  673. for (i = 0; i < NumTri; i++)
  674. {
  675. pTri->v1 = i*3;
  676. pTri->v2 = i*3+1;
  677. pTri->v3 = i*3+2;
  678. pTri++;
  679. }
  680. GetClientRect(auxGetHWND(), &rct);
  681. FillRect(auxGetHDC(), &rct, GetStockObject(BLACK_BRUSH));
  682. }
  683. static __GLmatrix proj = {
  684. D3DVAL(2.0), D3DVAL(0.0), D3DVAL(0.0), D3DVAL(0.0),
  685. D3DVAL(0.0), D3DVAL(2.0), D3DVAL(0.0), D3DVAL(0.0),
  686. D3DVAL(0.0), D3DVAL(0.0), D3DVAL(1.0), D3DVAL(1.0),
  687. D3DVAL(0.0), D3DVAL(0.0), D3DVAL(-1.0), D3DVAL(0.0)
  688. };
  689. static __GLmatrix view = {
  690. D3DVAL(1.0), D3DVAL(0.0), D3DVAL(0.0), D3DVAL(0.0),
  691. D3DVAL(0.0), D3DVAL(1.0), D3DVAL(0.0), D3DVAL(0.0),
  692. D3DVAL(0.0), D3DVAL(0.0), D3DVAL(1.0), D3DVAL(0.0),
  693. D3DVAL(0.0), D3DVAL(0.0), D3DVAL(7.0), D3DVAL(1.0)
  694. };
  695. void SetTest(int iNew)
  696. {
  697. RECT rct;
  698. ModeChange();
  699. iTest = iNew;
  700. switch(iTest)
  701. {
  702. case TEST_POLYS:
  703. glDisableClientState(GL_COLOR_ARRAY);
  704. glEnable(GL_LIGHTING);
  705. glEnable(GL_CULL_FACE);
  706. iTexMode = TEXMODE_REPLACE;
  707. glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, eTexModes[iTexMode]);
  708. glMatrixMode(GL_PROJECTION);
  709. glLoadIdentity();
  710. #if 0
  711. gluPerspective(45, 1, .01, 15);
  712. gluLookAt(0, 0, 8, 0, 0, 0, 0, 1, 0);
  713. #else
  714. glLoadMatrixf((float *)&proj);
  715. glMultMatrixf((float *)&view);
  716. glDepthRange(1, 0);
  717. #endif
  718. glMatrixMode(GL_MODELVIEW);
  719. SetVertexArrayVertices(pPolyVertices);
  720. iSwapWidth = SPWIDTH;
  721. iSwapHeight = SPHEIGHT;
  722. glScissor((WIDTH-iSwapWidth)/2, (HEIGHT-iSwapHeight)/2,
  723. iSwapWidth, iSwapHeight);
  724. break;
  725. case TEST_FILL:
  726. glEnableClientState(GL_COLOR_ARRAY);
  727. glDisable(GL_LIGHTING);
  728. glDisable(GL_CULL_FACE);
  729. iTexMode = TEXMODE_MODULATE;
  730. glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, eTexModes[iTexMode]);
  731. glMatrixMode(GL_PROJECTION);
  732. glLoadIdentity();
  733. glOrtho(0, WIDTH, 0, HEIGHT, 0.0f, 1.0f);
  734. glMatrixMode(GL_MODELVIEW);
  735. glLoadIdentity();
  736. SetVertexArrayVertices(pFillVertices);
  737. SetFill(iFillSize, iOrder);
  738. break;
  739. }
  740. SetPrim(iPrimType);
  741. GetClientRect(auxGetHWND(), &rct);
  742. FillRect(auxGetHDC(), &rct, GetStockObject(BLACK_BRUSH));
  743. }
  744. void Init(void)
  745. {
  746. float fv4[4];
  747. int iPrim, iOldPrim;
  748. if (!GenerateSphere(SRADIUS, nRings, nSections, 1.0f, 1.0f, 1.0f,
  749. &pPolyVertices, &pPolyTriangles,
  750. &nNumVertices, &nNumFaces))
  751. {
  752. printf("Unable to generate sphere data\n");
  753. exit(1);
  754. }
  755. nStripIndices = CreateStrip(nSections, &pPolyStrip);
  756. InitSpheres();
  757. InitFill(&pFillVertices, &pFillTriangles);
  758. fv4[0] = 0.05f;
  759. fv4[1] = 0.05f;
  760. fv4[2] = 0.05f;
  761. fv4[3] = 1.0f;
  762. glLightModelfv(GL_LIGHT_MODEL_AMBIENT, fv4);
  763. fv4[0] = 0.0f;
  764. fv4[1] = 1.0f;
  765. fv4[2] = 1.0f;
  766. fv4[3] = 0.0f;
  767. glLightfv(GL_LIGHT0, GL_POSITION, fv4);
  768. fv4[0] = 0.9f;
  769. fv4[1] = 0.9f;
  770. fv4[2] = 0.9f;
  771. fv4[3] = 1.0f;
  772. glLightfv(GL_LIGHT0, GL_DIFFUSE, fv4);
  773. glEnable(GL_LIGHT0);
  774. glEnable(GL_LIGHTING);
  775. glEnableClientState(GL_VERTEX_ARRAY);
  776. glEnableClientState(GL_NORMAL_ARRAY);
  777. glEnableClientState(GL_TEXTURE_COORD_ARRAY);
  778. if (!fSingleColor)
  779. {
  780. glEnableClientState(GL_COLOR_ARRAY);
  781. glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
  782. glEnable(GL_COLOR_MATERIAL);
  783. }
  784. glEnable(GL_CULL_FACE);
  785. glEnable(GL_DEPTH_TEST);
  786. #ifdef TEXOBJ
  787. glGenTextures(1, &uiTexObj);
  788. glBindTexture(GL_TEXTURE_2D, uiTexObj);
  789. #endif
  790. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  791. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  792. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  793. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  794. glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
  795. glTexImage2D(GL_TEXTURE_2D, 0, 3, pTexture->sizeX, pTexture->sizeY, 0,
  796. GL_RGB, GL_UNSIGNED_BYTE, pTexture->data);
  797. glEnable(GL_TEXTURE_2D);
  798. glDisable(GL_DITHER);
  799. #ifdef GL_EXT_clip_volume
  800. glHint(GL_CLIP_VOLUME_CLIPPING_HINT_EXT, GL_FASTEST);
  801. #endif
  802. SetTest(iTest);
  803. glClear(GL_COLOR_BUFFER_BIT);
  804. if (fDisplayList)
  805. {
  806. iDlist = glGenLists(3);
  807. iOldPrim = iPrimType;
  808. for (iPrim = 0; iPrim < PRIM_COUNT; iPrim++)
  809. {
  810. SetPrim(iPrim);
  811. glNewList(iDlist+iPrim, GL_COMPILE);
  812. glDrawElements(ePrimTypes[iPrim], nIndices,
  813. GL_UNSIGNED_INT, pIndices);
  814. glEndList();
  815. }
  816. SetPrim(iOldPrim);
  817. }
  818. }
  819. void Redraw(void)
  820. {
  821. DWORD ms;
  822. int i;
  823. Sphere *sp;
  824. float fv4[4];
  825. int iv1[1];
  826. int loop;
  827. __GLmatrix xform;
  828. ms = GetTickCount();
  829. for (loop = 0; loop < iMultiLoop; loop++)
  830. {
  831. #if PROFILE
  832. if (loop > 0)
  833. {
  834. StartCAP();
  835. }
  836. #endif
  837. if (fUseScissor)
  838. {
  839. glEnable(GL_SCISSOR_TEST);
  840. if (glAddSwapHintRectWIN != NULL)
  841. {
  842. glAddSwapHintRectWIN((WIDTH-iSwapWidth)/2,
  843. (HEIGHT-iSwapHeight)/2,
  844. iSwapWidth, iSwapHeight);
  845. }
  846. }
  847. if (glIsEnabled(GL_DEPTH_TEST))
  848. {
  849. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  850. }
  851. else
  852. {
  853. glClear(GL_COLOR_BUFFER_BIT);
  854. }
  855. if (fUseScissor)
  856. {
  857. glDisable(GL_SCISSOR_TEST);
  858. }
  859. if (fSingleColor && iTest == TEST_POLYS)
  860. {
  861. fv4[0] = 1.0f;
  862. fv4[1] = 1.0f;
  863. fv4[2] = 1.0f;
  864. fv4[3] = 1.0f;
  865. glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, fv4);
  866. }
  867. fv4[0] = 0.6f;
  868. fv4[1] = 0.6f;
  869. fv4[2] = 0.6f;
  870. fv4[3] = 1.0f;
  871. glMaterialfv(GL_FRONT, GL_SPECULAR, fv4);
  872. iv1[0] = 40;
  873. glMaterialiv(GL_FRONT, GL_SHININESS, iv1);
  874. switch(iTest)
  875. {
  876. case TEST_POLYS:
  877. sp = &spheres[0];
  878. for (i = 0; i < NSPHERES; i++)
  879. {
  880. UpdateSphere(sp);
  881. // Always done to even out timings
  882. #if 1
  883. __glMultMatrix(&xform, &sp->rot, &sp->pos);
  884. #else
  885. __glMultMatrix(&xform, &sp->pos, &sp->rot);
  886. #endif
  887. if (fBounce && fRotate)
  888. {
  889. glLoadMatrixf(&xform.matrix[0][0]);
  890. }
  891. else if (fRotate)
  892. {
  893. glLoadMatrixf(&sp->rot.matrix[0][0]);
  894. }
  895. else
  896. {
  897. glLoadMatrixf(&sp->pos.matrix[0][0]);
  898. }
  899. #if 1
  900. glVertexPointer(3, GL_FLOAT, sizeof(D3DVERTEX), &pPolyVertices[0].x);
  901. glNormalPointer(GL_FLOAT, sizeof(D3DVERTEX), &pPolyVertices[0].nx);
  902. glTexCoordPointer(2, GL_FLOAT, sizeof(D3DVERTEX), &pPolyVertices[0].tu);
  903. fv4[0] = 1.0f;
  904. fv4[1] = 1.0f;
  905. fv4[2] = 1.0f;
  906. fv4[3] = 1.0f;
  907. glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, fv4);
  908. fv4[0] = 0.6f;
  909. fv4[1] = 0.6f;
  910. fv4[2] = 0.6f;
  911. fv4[3] = 1.0f;
  912. glMaterialfv(GL_FRONT, GL_SPECULAR, fv4);
  913. iv1[0] = 40;
  914. glMaterialiv(GL_FRONT, GL_SHININESS, iv1);
  915. glBindTexture(GL_TEXTURE_2D, uiTexObj);
  916. glTexParameteri(GL_TEXTURE_2D,
  917. GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  918. glTexParameteri(GL_TEXTURE_2D,
  919. GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  920. glEnable(GL_TEXTURE_2D);
  921. glDepthRange(1, 0);
  922. glEnableClientState(GL_NORMAL_ARRAY);
  923. glDisableClientState(GL_COLOR_ARRAY);
  924. glEnable(GL_LIGHTING);
  925. #endif
  926. if (fDisplayList)
  927. {
  928. glCallList(iDlist+iPrimType);
  929. }
  930. else
  931. {
  932. glDrawElements(ePrimTypes[iPrimType], nIndices,
  933. GL_UNSIGNED_INT, pIndices);
  934. }
  935. sp++;
  936. }
  937. break;
  938. case TEST_FILL:
  939. glDrawElements(GL_TRIANGLES, nIndices, GL_UNSIGNED_INT, pIndices);
  940. break;
  941. }
  942. if (fSwap && !fSingle)
  943. {
  944. auxSwapBuffers();
  945. }
  946. else
  947. {
  948. glFinish();
  949. }
  950. }
  951. #ifdef PROFILE
  952. if (iMultiLoop > 1)
  953. {
  954. StopCAP();
  955. }
  956. #endif
  957. ms = GetTickCount()-ms;
  958. total_ms += ms;
  959. total_tris += nTriangles*iMultiLoop;
  960. if (total_ms > 2000)
  961. {
  962. double val;
  963. switch(iTest)
  964. {
  965. case TEST_POLYS:
  966. val = (double)total_tris*1000.0/total_ms;
  967. if (val > peak_tri)
  968. {
  969. peak_tri = val;
  970. }
  971. avg_tri += val;
  972. break;
  973. case TEST_FILL:
  974. val = (double)iTriangleArea*total_tris*1000.0/total_ms;
  975. if (val > peak_fill)
  976. {
  977. peak_fill = val;
  978. }
  979. avg_fill += val;
  980. break;
  981. }
  982. avg_cnt++;
  983. if (fVerbose)
  984. {
  985. printf("%s, %s", pszPrimTypes[iPrimType],
  986. pszShadeModels[iShadeModel]);
  987. if (glIsEnabled(GL_CULL_FACE))
  988. {
  989. printf(", cull");
  990. }
  991. if (glIsEnabled(GL_LIGHTING))
  992. {
  993. printf(", lit");
  994. }
  995. if (glIsEnabled(GL_TEXTURE_2D))
  996. {
  997. printf(", %s", pszTexModes[iTexMode]);
  998. }
  999. if (glIsEnabled(GL_DITHER))
  1000. {
  1001. printf(", dither");
  1002. }
  1003. if (glIsEnabled(GL_DEPTH_TEST))
  1004. {
  1005. printf(", z");
  1006. }
  1007. #ifdef GL_EXT_clip_volume
  1008. glGetIntegerv(GL_CLIP_VOLUME_CLIPPING_HINT_EXT, &iv1[0]);
  1009. if (iv1[0] != GL_FASTEST)
  1010. #endif
  1011. {
  1012. printf(", clip");
  1013. }
  1014. if (fSwap)
  1015. {
  1016. printf(", swap");
  1017. }
  1018. if (fRotate)
  1019. {
  1020. printf(", rotate");
  1021. }
  1022. if (fBounce)
  1023. {
  1024. printf(", bounce");
  1025. }
  1026. if (fPerspective)
  1027. {
  1028. printf(", persp");
  1029. }
  1030. printf(", %d tri/frame\n", nTriangles);
  1031. switch(iTest)
  1032. {
  1033. case TEST_POLYS:
  1034. printf("%d ms, %d tri, %.3lf tri/sec, %.3lf peak, %.3lf avg\n",
  1035. total_ms, total_tris, val, peak_tri,
  1036. avg_tri/avg_cnt);
  1037. break;
  1038. case TEST_FILL:
  1039. printf("%d ms, %s, area %d, %.3lf pix/sec, "
  1040. "%.3lf peak, %.3lf avg\n",
  1041. total_ms, pszOrders[iOrder], iTriangleArea,
  1042. val, peak_fill, avg_fill/avg_cnt);
  1043. break;
  1044. }
  1045. }
  1046. else
  1047. {
  1048. char msg[80];
  1049. switch(iTest)
  1050. {
  1051. case TEST_POLYS:
  1052. sprintf(msg, "%.3lf tri/sec, %.3lf peak, %.3lf avg",
  1053. val, peak_tri, avg_tri/avg_cnt);
  1054. break;
  1055. case TEST_FILL:
  1056. sprintf(msg, "%.3lf pix/sec, %.3lf peak, %.3lf avg",
  1057. val, peak_fill, avg_fill/avg_cnt);
  1058. break;
  1059. }
  1060. SetWindowText(auxGetHWND(), msg);
  1061. }
  1062. total_ms = 0;
  1063. total_tris = 0;
  1064. }
  1065. }
  1066. void Reshape(GLsizei w, GLsizei h)
  1067. {
  1068. glViewport(0, 0, w, h);
  1069. }
  1070. void Step(void)
  1071. {
  1072. Redraw();
  1073. }
  1074. void KeyB(void)
  1075. {
  1076. ModeChange();
  1077. fBounce = !fBounce;
  1078. }
  1079. void Keyc(void)
  1080. {
  1081. ModeChange();
  1082. if (glIsEnabled(GL_CULL_FACE))
  1083. {
  1084. glDisable(GL_CULL_FACE);
  1085. }
  1086. else
  1087. {
  1088. glEnable(GL_CULL_FACE);
  1089. }
  1090. }
  1091. void KeyC(void)
  1092. {
  1093. ModeChange();
  1094. fUseScissor = !fUseScissor;
  1095. }
  1096. void Keyh(void)
  1097. {
  1098. ModeChange();
  1099. if (glIsEnabled(GL_DITHER))
  1100. {
  1101. glDisable(GL_DITHER);
  1102. }
  1103. else
  1104. {
  1105. glEnable(GL_DITHER);
  1106. }
  1107. }
  1108. void Keyi(void)
  1109. {
  1110. iFillSize = (iFillSize+1) % AREA_COUNT;
  1111. SetFill(iFillSize, iOrder);
  1112. }
  1113. void Keyl(void)
  1114. {
  1115. ModeChange();
  1116. if (glIsEnabled(GL_LIGHTING))
  1117. {
  1118. glDisable(GL_LIGHTING);
  1119. }
  1120. else
  1121. {
  1122. glEnable(GL_LIGHTING);
  1123. }
  1124. }
  1125. void Keym(void)
  1126. {
  1127. ModeChange();
  1128. iPolygonMode = (iPolygonMode+1) % POLYMODE_COUNT;
  1129. glPolygonMode(GL_FRONT_AND_BACK, ePolygonModes[iPolygonMode]);
  1130. }
  1131. void Keyo(void)
  1132. {
  1133. iOrder = (iOrder+1) % ORDER_COUNT;
  1134. SetFill(iFillSize, iOrder);
  1135. }
  1136. void Keyp(void)
  1137. {
  1138. ModeChange();
  1139. fPerspective = !fPerspective;
  1140. glHint(GL_PERSPECTIVE_CORRECTION_HINT,
  1141. fPerspective ? GL_NICEST : GL_FASTEST);
  1142. }
  1143. void KeyP(void)
  1144. {
  1145. #ifdef GL_EXT_clip_volume
  1146. int iv1[1];
  1147. ModeChange();
  1148. glGetIntegerv(GL_CLIP_VOLUME_CLIPPING_HINT_EXT, &iv1[0]);
  1149. if (iv1[0] == GL_FASTEST)
  1150. {
  1151. glHint(GL_CLIP_VOLUME_CLIPPING_HINT_EXT, GL_DONT_CARE);
  1152. }
  1153. else
  1154. {
  1155. glHint(GL_CLIP_VOLUME_CLIPPING_HINT_EXT, GL_FASTEST);
  1156. }
  1157. #endif
  1158. }
  1159. void KeyR(void)
  1160. {
  1161. ModeChange();
  1162. fRotate = !fRotate;
  1163. }
  1164. void Keys(void)
  1165. {
  1166. ModeChange();
  1167. iShadeModel = (iShadeModel+1) % SMODEL_COUNT;
  1168. glShadeModel(eShadeModels[iShadeModel]);
  1169. }
  1170. void KeyS(void)
  1171. {
  1172. fSpread = !fSpread;
  1173. SetFill(iFillSize, iOrder);
  1174. }
  1175. void Keyt(void)
  1176. {
  1177. SetPrim((iPrimType+1) % PRIM_COUNT);
  1178. }
  1179. void KeyT(void)
  1180. {
  1181. iTest = (iTest+1) % TEST_COUNT;
  1182. SetTest(iTest);
  1183. }
  1184. void Keyw(void)
  1185. {
  1186. ModeChange();
  1187. fSwap = !fSwap;
  1188. }
  1189. void Keyx(void)
  1190. {
  1191. ModeChange();
  1192. if (glIsEnabled(GL_TEXTURE_2D))
  1193. {
  1194. glDisable(GL_TEXTURE_2D);
  1195. }
  1196. else
  1197. {
  1198. glEnable(GL_TEXTURE_2D);
  1199. }
  1200. }
  1201. void KeyX(void)
  1202. {
  1203. ModeChange();
  1204. iTexMode = (iTexMode+1) % TEXMODE_COUNT;
  1205. glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, eTexModes[iTexMode]);
  1206. }
  1207. void Keyz(void)
  1208. {
  1209. ModeChange();
  1210. if (glIsEnabled(GL_DEPTH_TEST))
  1211. {
  1212. glDisable(GL_DEPTH_TEST);
  1213. }
  1214. else
  1215. {
  1216. glEnable(GL_DEPTH_TEST);
  1217. }
  1218. }
  1219. void KeySPACE(void)
  1220. {
  1221. fPaused = !fPaused;
  1222. if (fPaused)
  1223. {
  1224. auxIdleFunc(NULL);
  1225. }
  1226. else
  1227. {
  1228. auxIdleFunc(Step);
  1229. }
  1230. }
  1231. void __cdecl main(int argc, char **argv)
  1232. {
  1233. int mode;
  1234. int wd, ht;
  1235. char szWinDir[256];
  1236. int l;
  1237. wd = WIDTH;
  1238. ht = HEIGHT;
  1239. while (--argc > 0)
  1240. {
  1241. argv++;
  1242. if (!strcmp(*argv, "-sb"))
  1243. {
  1244. fSingle = TRUE;
  1245. }
  1246. else if (!strcmp(*argv, "-paused"))
  1247. {
  1248. fPaused = TRUE;
  1249. }
  1250. else if (!strcmp(*argv, "-exit"))
  1251. {
  1252. fExit = TRUE;
  1253. }
  1254. else if (!strcmp(*argv, "-cols"))
  1255. {
  1256. fSingleColor = FALSE;
  1257. }
  1258. else if (!strcmp(*argv, "-v"))
  1259. {
  1260. fVerbose = TRUE;
  1261. }
  1262. else if (!strcmp(*argv, "-nodlist"))
  1263. {
  1264. fDisplayList = FALSE;
  1265. }
  1266. else if (!strcmp(*argv, "-norotate"))
  1267. {
  1268. fRotate = FALSE;
  1269. }
  1270. else if (!strcmp(*argv, "-nobounce"))
  1271. {
  1272. fBounce = FALSE;
  1273. }
  1274. else if (!strcmp(*argv, "-noscissor"))
  1275. {
  1276. fUseScissor = FALSE;
  1277. }
  1278. else if (!strncmp(*argv, "-multi", 6))
  1279. {
  1280. sscanf(*argv+6, "%d", &iMultiLoop);
  1281. }
  1282. else if (!strncmp(*argv, "-wd", 3))
  1283. {
  1284. sscanf(*argv+3, "%d", &wd);
  1285. }
  1286. else if (!strncmp(*argv, "-ht", 3))
  1287. {
  1288. sscanf(*argv+3, "%d", &ht);
  1289. }
  1290. else if (!strncmp(*argv, "-rings", 6))
  1291. {
  1292. sscanf(*argv+6, "%d", &nRings);
  1293. }
  1294. else if (!strncmp(*argv, "-sections", 9))
  1295. {
  1296. sscanf(*argv+9, "%d", &nSections);
  1297. }
  1298. else if (!strncmp(*argv, "-tst", 4))
  1299. {
  1300. sscanf(*argv+4, "%d", &iTest);
  1301. }
  1302. else if (!strncmp(*argv, "-fsz", 4))
  1303. {
  1304. sscanf(*argv+4, "%d", &iFillSize);
  1305. }
  1306. }
  1307. auxInitPosition(10, 10, wd, ht);
  1308. mode = AUX_RGB | AUX_DEPTH16;
  1309. if (!fSingle)
  1310. {
  1311. mode |= AUX_DOUBLE;
  1312. }
  1313. auxInitDisplayMode(mode);
  1314. auxInitWindow("DrawElements Performance Test");
  1315. auxReshapeFunc(Reshape);
  1316. if (!fPaused)
  1317. {
  1318. auxIdleFunc(Step);
  1319. }
  1320. l = GetWindowsDirectory(szWinDir, sizeof(szWinDir));
  1321. if (l == 0)
  1322. {
  1323. printf("Unable to get windows directory\n");
  1324. exit(1);
  1325. }
  1326. strcpy(szWinDir+l, "\\cover8.bmp");
  1327. pTexture = auxDIBImageLoad(szWinDir);
  1328. if (pTexture == NULL)
  1329. {
  1330. printf("Unable to load texture\n");
  1331. exit(1);
  1332. }
  1333. auxKeyFunc(AUX_B, KeyB);
  1334. auxKeyFunc(AUX_c, Keyc);
  1335. auxKeyFunc(AUX_C, KeyC);
  1336. auxKeyFunc(AUX_h, Keyh);
  1337. auxKeyFunc(AUX_i, Keyi);
  1338. auxKeyFunc(AUX_l, Keyl);
  1339. auxKeyFunc(AUX_m, Keym);
  1340. auxKeyFunc(AUX_o, Keyo);
  1341. auxKeyFunc(AUX_p, Keyp);
  1342. auxKeyFunc(AUX_P, KeyP);
  1343. auxKeyFunc(AUX_R, KeyR);
  1344. auxKeyFunc(AUX_s, Keys);
  1345. auxKeyFunc(AUX_S, KeyS);
  1346. auxKeyFunc(AUX_t, Keyt);
  1347. auxKeyFunc(AUX_T, KeyT);
  1348. auxKeyFunc(AUX_w, Keyw);
  1349. auxKeyFunc(AUX_x, Keyx);
  1350. auxKeyFunc(AUX_X, KeyX);
  1351. auxKeyFunc(AUX_z, Keyz);
  1352. auxKeyFunc(AUX_SPACE, KeySPACE);
  1353. SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS);
  1354. glAddSwapHintRectWIN = (PFNGLADDSWAPHINTRECTWINPROC)
  1355. wglGetProcAddress("glAddSwapHintRectWIN");
  1356. #if 0
  1357. _controlfp((unsigned int)
  1358. (~(_EM_ZERODIVIDE | _EM_OVERFLOW | _EM_UNDERFLOW)), _MCW_EM);
  1359. #endif
  1360. Init();
  1361. if (fExit)
  1362. {
  1363. Redraw();
  1364. }
  1365. else
  1366. {
  1367. auxMainLoop(Redraw);
  1368. }
  1369. }