Clone of mesa.
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.

isosurf.c 20KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821
  1. /* $Id: isosurf.c,v 1.1 1999/08/19 00:55:40 jtg Exp $ */
  2. /*
  3. * Display an isosurface of 3-D wind speed volume. Use arrow keys to
  4. * rotate, S toggles smooth shading, L toggles lighting
  5. * Brian Paul This file in public domain.
  6. */
  7. /*
  8. * $Log: isosurf.c,v $
  9. * Revision 1.1 1999/08/19 00:55:40 jtg
  10. * Initial revision
  11. *
  12. * Revision 3.4 1999/04/24 01:10:47 keithw
  13. * clip planes, materials
  14. *
  15. * Revision 3.3 1999/03/31 19:42:14 keithw
  16. * support for cva
  17. *
  18. * Revision 3.1 1998/11/01 20:30:20 brianp
  19. * added benchmark feature (b key)
  20. *
  21. * Revision 3.0 1998/02/14 18:42:29 brianp
  22. * initial rev
  23. *
  24. */
  25. #include <stdio.h>
  26. #include <string.h>
  27. #include <stdlib.h>
  28. #include <math.h>
  29. #include "GL/glut.h"
  30. #include "../util/readtex.c" /* I know, this is a hack. KW: me too. */
  31. #define TEXTURE_FILE "../images/reflect.rgb"
  32. #define LIT 0x1
  33. #define UNLIT 0x2
  34. #define TEXTURE 0x4
  35. #define NO_TEXTURE 0x8
  36. #define REFLECT 0x10
  37. #define NO_REFLECT 0x20
  38. #define POINT_FILTER 0x40
  39. #define LINEAR_FILTER 0x80
  40. #define IMMEDIATE 0x100
  41. #define DRAW_ARRAYS 0x200 /* or draw_elts, if compiled */
  42. #define ARRAY_ELT 0x400
  43. #define COMPILED 0x800
  44. #define NOT_COMPILED 0x1000
  45. #define SHADE_SMOOTH 0x2000
  46. #define SHADE_FLAT 0x4000
  47. #define TRIANGLES 0x8000
  48. #define STRIPS 0x10000
  49. #define USER_CLIP 0x20000
  50. #define NO_USER_CLIP 0x40000
  51. #define MATERIALS 0x80000
  52. #define NO_MATERIALS 0x100000
  53. #define QUIT 0x800000
  54. #define LIGHT_MASK (LIT|UNLIT)
  55. #define TEXTURE_MASK (TEXTURE|NO_TEXTURE)
  56. #define REFLECT_MASK (REFLECT|NO_REFLECT)
  57. #define FILTER_MASK (POINT_FILTER|LINEAR_FILTER)
  58. #define RENDER_STYLE_MASK (IMMEDIATE|DRAW_ARRAYS|ARRAY_ELT)
  59. #define COMPILED_MASK (COMPILED|NOT_COMPILED)
  60. #define MATERIAL_MASK (MATERIALS|NO_MATERIALS)
  61. #define PRIMITIVE_MASK (TRIANGLES|STRIPS)
  62. #define CLIP_MASK (USER_CLIP|NO_USER_CLIP)
  63. #define SHADE_MASK (SHADE_SMOOTH|SHADE_FLAT)
  64. #define MAXVERTS 10000
  65. static float data[MAXVERTS][6];
  66. static float compressed_data[MAXVERTS][6];
  67. static GLuint indices[MAXVERTS];
  68. static GLuint tri_indices[MAXVERTS*3];
  69. static GLfloat col[100][4];
  70. static GLint numverts, num_tri_verts, numuniq;
  71. static GLfloat xrot;
  72. static GLfloat yrot;
  73. static GLint state, allowed = ~0;
  74. static GLboolean doubleBuffer = GL_TRUE;
  75. static GLdouble plane[4] = {1.0, 0.0, -1.0, 0.0};
  76. static void read_surface( char *filename )
  77. {
  78. FILE *f;
  79. f = fopen(filename,"r");
  80. if (!f) {
  81. printf("couldn't read %s\n", filename);
  82. exit(1);
  83. }
  84. numverts = 0;
  85. while (!feof(f) && numverts<MAXVERTS) {
  86. fscanf( f, "%f %f %f %f %f %f",
  87. &data[numverts][0], &data[numverts][1], &data[numverts][2],
  88. &data[numverts][3], &data[numverts][4], &data[numverts][5] );
  89. numverts++;
  90. }
  91. numverts--;
  92. printf("%d vertices, %d triangles\n", numverts, numverts-2);
  93. fclose(f);
  94. }
  95. struct data_idx {
  96. float *data;
  97. int idx;
  98. int uniq_idx;
  99. };
  100. #define COMPARE_FUNC( AXIS ) \
  101. int compare_axis_##AXIS( const void *a, const void *b ) \
  102. { \
  103. float t = ( (*(struct data_idx *)a).data[AXIS] - \
  104. (*(struct data_idx *)b).data[AXIS] ); \
  105. \
  106. if (t < 0) return -1; \
  107. if (t > 0) return 1; \
  108. return 0; \
  109. }
  110. COMPARE_FUNC(0)
  111. COMPARE_FUNC(1)
  112. COMPARE_FUNC(2)
  113. COMPARE_FUNC(3)
  114. COMPARE_FUNC(4)
  115. COMPARE_FUNC(5)
  116. COMPARE_FUNC(6)
  117. int (*(compare[7]))( const void *a, const void *b ) =
  118. {
  119. compare_axis_0,
  120. compare_axis_1,
  121. compare_axis_2,
  122. compare_axis_3,
  123. compare_axis_4,
  124. compare_axis_5,
  125. compare_axis_6,
  126. };
  127. #define VEC_ELT(f, s, i) (float *)(((char *)f) + s * i)
  128. static int sort_axis( int axis,
  129. int vec_size,
  130. int vec_stride,
  131. struct data_idx *indices,
  132. int start,
  133. int finish,
  134. float *out,
  135. int uniq,
  136. const float fudge )
  137. {
  138. int i;
  139. if (finish-start > 2)
  140. {
  141. qsort( indices+start, finish-start, sizeof(*indices), compare[axis] );
  142. }
  143. else if (indices[start].data[axis] > indices[start+1].data[axis])
  144. {
  145. struct data_idx tmp = indices[start];
  146. indices[start] = indices[start+1];
  147. indices[start+1] = tmp;
  148. }
  149. if (axis == vec_size-1) {
  150. for (i = start ; i < finish ; ) {
  151. float max = indices[i].data[axis] + fudge;
  152. float *dest = VEC_ELT(out, vec_stride, uniq);
  153. int j;
  154. for (j = 0 ; j < vec_size ; j++)
  155. dest[j] = indices[i].data[j];
  156. for ( ; i < finish && max >= indices[i].data[axis]; i++)
  157. indices[i].uniq_idx = uniq;
  158. uniq++;
  159. }
  160. } else {
  161. for (i = start ; i < finish ; ) {
  162. int j = i + 1;
  163. float max = indices[i].data[axis] + fudge;
  164. while (j < finish && max >= indices[j].data[axis]) j++;
  165. if (j == i+1) {
  166. float *dest = VEC_ELT(out, vec_stride, uniq);
  167. int k;
  168. indices[i].uniq_idx = uniq;
  169. for (k = 0 ; k < vec_size ; k++)
  170. dest[k] = indices[i].data[k];
  171. uniq++;
  172. } else {
  173. uniq = sort_axis( axis+1, vec_size, vec_stride,
  174. indices, i, j, out, uniq, fudge );
  175. }
  176. i = j;
  177. }
  178. }
  179. return uniq;
  180. }
  181. static void extract_indices1( const struct data_idx *in, unsigned int *out,
  182. int n )
  183. {
  184. int i;
  185. for ( i = 0 ; i < n ; i++ ) {
  186. out[in[i].idx] = in[i].uniq_idx;
  187. }
  188. }
  189. static void compactify_arrays()
  190. {
  191. int i;
  192. struct data_idx *ind;
  193. ind = (struct data_idx *) malloc( sizeof(struct data_idx) * numverts );
  194. for (i = 0 ; i < numverts ; i++) {
  195. ind[i].idx = i;
  196. ind[i].data = data[i];
  197. }
  198. numuniq = sort_axis(0,
  199. sizeof(compressed_data[0])/sizeof(float),
  200. sizeof(compressed_data[0]),
  201. ind,
  202. 0,
  203. numverts,
  204. (float *)compressed_data,
  205. 0,
  206. 1e-6);
  207. printf("Nr unique vertex/normal pairs: %d\n", numuniq);
  208. extract_indices1( ind, indices, numverts );
  209. free( ind );
  210. }
  211. static float myrand( float max )
  212. {
  213. return max*rand()/(RAND_MAX+1.0);
  214. }
  215. static void make_tri_indices( void )
  216. {
  217. unsigned int *v = tri_indices;
  218. unsigned int parity = 0;
  219. unsigned int i, j;
  220. for (j=2;j<numverts;j++,parity^=1) {
  221. if (parity) {
  222. *v++ = indices[j-1];
  223. *v++ = indices[j-2];
  224. *v++ = indices[j];
  225. } else {
  226. *v++ = indices[j-2];
  227. *v++ = indices[j-1];
  228. *v++ = indices[j];
  229. }
  230. }
  231. num_tri_verts = v - tri_indices;
  232. printf("num_tri_verts: %d\n", num_tri_verts);
  233. for (i = j = 0 ; i < num_tri_verts ; i += 600, j++) {
  234. col[j][3] = 1;
  235. col[j][2] = myrand(1);
  236. col[j][1] = myrand(1);
  237. col[j][0] = myrand(1);
  238. }
  239. }
  240. #define MIN(x,y) (x < y) ? x : y
  241. static void draw_surface( void )
  242. {
  243. GLuint i, j;
  244. switch (state & (COMPILED_MASK|RENDER_STYLE_MASK|PRIMITIVE_MASK)) {
  245. #ifdef GL_EXT_vertex_array
  246. case (COMPILED|DRAW_ARRAYS|STRIPS):
  247. glDrawElements( GL_TRIANGLE_STRIP, numverts, GL_UNSIGNED_INT, indices );
  248. break;
  249. case (COMPILED|ARRAY_ELT|STRIPS):
  250. glBegin( GL_TRIANGLE_STRIP );
  251. for (i = 0 ; i < numverts ; i++)
  252. glArrayElement( indices[i] );
  253. glEnd();
  254. break;
  255. case (COMPILED|DRAW_ARRAYS|TRIANGLES):
  256. case (NOT_COMPILED|DRAW_ARRAYS|TRIANGLES):
  257. if (state & MATERIALS) {
  258. for (j = i = 0 ; i < num_tri_verts ; i += 600, j++) {
  259. GLuint nr = MIN(num_tri_verts-i, 600);
  260. glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, col[j]);
  261. glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, col[j]);
  262. glDrawElements( GL_TRIANGLES, nr, GL_UNSIGNED_INT, tri_indices+i );
  263. }
  264. } else {
  265. glDrawElements( GL_TRIANGLES, num_tri_verts, GL_UNSIGNED_INT,
  266. tri_indices );
  267. }
  268. break;
  269. /* Uses the original arrays (including duplicate elements):
  270. */
  271. case (NOT_COMPILED|DRAW_ARRAYS|STRIPS):
  272. glDrawArraysEXT( GL_TRIANGLE_STRIP, 0, numverts );
  273. break;
  274. /* Uses the original arrays (including duplicate elements):
  275. */
  276. case (NOT_COMPILED|ARRAY_ELT|STRIPS):
  277. glBegin( GL_TRIANGLE_STRIP );
  278. for (i = 0 ; i < numverts ; i++)
  279. glArrayElement( i );
  280. glEnd();
  281. break;
  282. case (NOT_COMPILED|ARRAY_ELT|TRIANGLES):
  283. case (COMPILED|ARRAY_ELT|TRIANGLES):
  284. if (state & MATERIALS) {
  285. for (j = i = 0 ; i < num_tri_verts ; i += 600, j++) {
  286. GLuint nr = MIN(num_tri_verts-i, 600);
  287. GLuint k;
  288. glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, col[j]);
  289. glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, col[j]);
  290. glBegin( GL_TRIANGLES );
  291. for (k = 0 ; k < nr ; k++)
  292. glArrayElement( tri_indices[i+k] );
  293. glEnd();
  294. }
  295. } else {
  296. glBegin( GL_TRIANGLES );
  297. for (i = 0 ; i < num_tri_verts ; i++)
  298. glArrayElement( tri_indices[i] );
  299. glEnd();
  300. }
  301. break;
  302. case (NOT_COMPILED|IMMEDIATE|TRIANGLES):
  303. if (state & MATERIALS) {
  304. for (j = i = 0 ; i < num_tri_verts ; i += 600, j++) {
  305. GLuint nr = MIN(num_tri_verts-i, 600);
  306. GLuint k;
  307. glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, col[j]);
  308. glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, col[j]);
  309. glBegin( GL_TRIANGLES );
  310. for (k = 0 ; k < nr ; k++) {
  311. glNormal3fv( &compressed_data[tri_indices[i+k]][3] );
  312. glVertex3fv( &compressed_data[tri_indices[i+k]][0] );
  313. }
  314. glEnd();
  315. }
  316. } else {
  317. glBegin( GL_TRIANGLES );
  318. for (i = 0 ; i < num_tri_verts ; i++) {
  319. glNormal3fv( &compressed_data[tri_indices[i]][3] );
  320. glVertex3fv( &compressed_data[tri_indices[i]][0] );
  321. }
  322. glEnd();
  323. }
  324. break;
  325. #endif
  326. /* Uses the original arrays (including duplicate elements):
  327. */
  328. default:
  329. glBegin( GL_TRIANGLE_STRIP );
  330. for (i=0;i<numverts;i++) {
  331. glNormal3fv( &data[i][3] );
  332. glVertex3fv( &data[i][0] );
  333. }
  334. glEnd();
  335. }
  336. }
  337. static void Display(void)
  338. {
  339. glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
  340. draw_surface();
  341. glFlush();
  342. if (doubleBuffer) glutSwapBuffers();
  343. }
  344. /* KW: only do this when necessary, so CVA can re-use results.
  345. */
  346. static void set_matrix( void )
  347. {
  348. glMatrixMode(GL_MODELVIEW);
  349. glLoadIdentity();
  350. glTranslatef( 0.0, 0.0, -6.0 );
  351. glRotatef( yrot, 0.0, 1.0, 0.0 );
  352. glRotatef( xrot, 1.0, 0.0, 0.0 );
  353. }
  354. static void Benchmark( float xdiff, float ydiff )
  355. {
  356. int startTime, endTime;
  357. int draws;
  358. double seconds, fps, triPerSecond;
  359. printf("Benchmarking...\n");
  360. draws = 0;
  361. startTime = glutGet(GLUT_ELAPSED_TIME);
  362. xrot = 0.0;
  363. do {
  364. xrot += xdiff;
  365. yrot += ydiff;
  366. set_matrix();
  367. Display();
  368. draws++;
  369. endTime = glutGet(GLUT_ELAPSED_TIME);
  370. } while (endTime - startTime < 5000); /* 5 seconds */
  371. /* Results */
  372. seconds = (double) (endTime - startTime) / 1000.0;
  373. triPerSecond = (numverts - 2) * draws / seconds;
  374. fps = draws / seconds;
  375. printf("Result: triangles/sec: %g fps: %g\n", triPerSecond, fps);
  376. }
  377. static void InitMaterials(void)
  378. {
  379. static float ambient[] = {0.1, 0.1, 0.1, 1.0};
  380. static float diffuse[] = {0.5, 1.0, 1.0, 1.0};
  381. static float position0[] = {0.0, 0.0, 20.0, 0.0};
  382. static float position1[] = {0.0, 0.0, -20.0, 0.0};
  383. static float front_mat_shininess[] = {60.0};
  384. static float front_mat_specular[] = {0.2, 0.2, 0.2, 1.0};
  385. static float front_mat_diffuse[] = {0.5, 0.28, 0.38, 1.0};
  386. /*
  387. static float back_mat_shininess[] = {60.0};
  388. static float back_mat_specular[] = {0.5, 0.5, 0.2, 1.0};
  389. static float back_mat_diffuse[] = {1.0, 1.0, 0.2, 1.0};
  390. */
  391. static float lmodel_ambient[] = {1.0, 1.0, 1.0, 1.0};
  392. static float lmodel_twoside[] = {GL_FALSE};
  393. glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
  394. glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
  395. glLightfv(GL_LIGHT0, GL_POSITION, position0);
  396. glEnable(GL_LIGHT0);
  397. glLightfv(GL_LIGHT1, GL_AMBIENT, ambient);
  398. glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse);
  399. glLightfv(GL_LIGHT1, GL_POSITION, position1);
  400. glEnable(GL_LIGHT1);
  401. glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
  402. glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE, lmodel_twoside);
  403. glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, front_mat_shininess);
  404. glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, front_mat_specular);
  405. glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, front_mat_diffuse);
  406. }
  407. #define UPDATE(o,n,mask) (o&=~mask, o|=n&mask)
  408. #define CHANGED(o,n,mask) ((n&mask) && \
  409. (n&mask) != (o&mask) ? UPDATE(o,n,mask) : 0)
  410. static void ModeMenu(int m)
  411. {
  412. m &= allowed;
  413. if (!m) return;
  414. if (m==QUIT)
  415. exit(0);
  416. if (CHANGED(state, m, FILTER_MASK)) {
  417. if (m & LINEAR_FILTER) {
  418. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  419. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  420. } else {
  421. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  422. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  423. }
  424. }
  425. if (CHANGED(state, m, LIGHT_MASK)) {
  426. if (m & LIT)
  427. glEnable(GL_LIGHTING);
  428. else
  429. glDisable(GL_LIGHTING);
  430. }
  431. if (CHANGED(state, m, SHADE_MASK)) {
  432. if (m & SHADE_SMOOTH)
  433. glShadeModel(GL_SMOOTH);
  434. else
  435. glShadeModel(GL_FLAT);
  436. }
  437. if (CHANGED(state, m, TEXTURE_MASK)) {
  438. if (m & TEXTURE)
  439. glEnable(GL_TEXTURE_2D);
  440. else
  441. glDisable(GL_TEXTURE_2D);
  442. }
  443. if (CHANGED(state, m, REFLECT_MASK)) {
  444. if (m & REFLECT) {
  445. glEnable(GL_TEXTURE_GEN_S);
  446. glEnable(GL_TEXTURE_GEN_T);
  447. } else {
  448. glDisable(GL_TEXTURE_GEN_S);
  449. glDisable(GL_TEXTURE_GEN_T);
  450. }
  451. }
  452. if (CHANGED(state, m, CLIP_MASK)) {
  453. if (m & USER_CLIP) {
  454. glEnable(GL_CLIP_PLANE0);
  455. } else {
  456. glDisable(GL_CLIP_PLANE0);
  457. }
  458. }
  459. #ifdef GL_EXT_vertex_array
  460. if (CHANGED(state, m, (COMPILED_MASK|RENDER_STYLE_MASK|PRIMITIVE_MASK)))
  461. {
  462. if ((m & (COMPILED_MASK|PRIMITIVE_MASK)) == (NOT_COMPILED|STRIPS))
  463. {
  464. glVertexPointerEXT( 3, GL_FLOAT, sizeof(data[0]), numverts, data );
  465. glNormalPointerEXT( GL_FLOAT, sizeof(data[0]), numverts, &data[0][3]);
  466. }
  467. else
  468. {
  469. glVertexPointerEXT( 3, GL_FLOAT, sizeof(data[0]), numuniq,
  470. compressed_data );
  471. glNormalPointerEXT( GL_FLOAT, sizeof(data[0]), numuniq,
  472. &compressed_data[0][3]);
  473. }
  474. #ifdef GL_EXT_compiled_vertex_array
  475. if (m & COMPILED) {
  476. glLockArraysEXT( 0, numuniq );
  477. } else {
  478. glUnlockArraysEXT();
  479. }
  480. #endif
  481. }
  482. #endif
  483. if (m & (RENDER_STYLE_MASK|PRIMITIVE_MASK)) {
  484. UPDATE(state, m, (RENDER_STYLE_MASK|PRIMITIVE_MASK));
  485. }
  486. if (m & MATERIAL_MASK) {
  487. UPDATE(state, m, MATERIAL_MASK);
  488. }
  489. glutPostRedisplay();
  490. }
  491. static void Init(void)
  492. {
  493. glClearColor(0.0, 0.0, 0.0, 0.0);
  494. glEnable( GL_DEPTH_TEST );
  495. glEnable( GL_VERTEX_ARRAY_EXT );
  496. glEnable( GL_NORMAL_ARRAY_EXT );
  497. InitMaterials();
  498. glMatrixMode(GL_PROJECTION);
  499. glLoadIdentity();
  500. glFrustum( -1.0, 1.0, -1.0, 1.0, 5, 25 );
  501. glMatrixMode(GL_MODELVIEW);
  502. glLoadIdentity();
  503. glClipPlane(GL_CLIP_PLANE0, plane);
  504. set_matrix();
  505. glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
  506. glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
  507. glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
  508. glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
  509. if (!LoadRGBMipmaps(TEXTURE_FILE, GL_RGB)) {
  510. printf("Error: couldn't load texture image\n");
  511. exit(1);
  512. }
  513. if (allowed & COMPILED) {
  514. compactify_arrays();
  515. make_tri_indices();
  516. }
  517. ModeMenu(SHADE_SMOOTH|
  518. LIT|
  519. NO_TEXTURE|
  520. NO_REFLECT|
  521. POINT_FILTER|
  522. NOT_COMPILED|
  523. NO_USER_CLIP|
  524. NO_MATERIALS|
  525. IMMEDIATE);
  526. }
  527. static void Reshape(int width, int height)
  528. {
  529. glViewport(0, 0, (GLint)width, (GLint)height);
  530. }
  531. static void Key( unsigned char key, int x, int y )
  532. {
  533. switch (key) {
  534. case 27:
  535. exit(0);
  536. case 's':
  537. ModeMenu((state ^ SHADE_MASK) & SHADE_MASK);
  538. break;
  539. case 'l':
  540. ModeMenu((state ^ LIGHT_MASK) & LIGHT_MASK);
  541. break;
  542. case 'm':
  543. ModeMenu((state ^ MATERIAL_MASK) & MATERIAL_MASK);
  544. break;
  545. case 'c':
  546. ModeMenu((state ^ CLIP_MASK) & CLIP_MASK);
  547. break;
  548. case 'b':
  549. Benchmark(5.0, 0);
  550. break;
  551. case 'B':
  552. Benchmark(0, 5.0);
  553. break;
  554. case '-':
  555. case '_':
  556. plane[3] += 2.0;
  557. glMatrixMode(GL_MODELVIEW);
  558. glLoadIdentity();
  559. glClipPlane(GL_CLIP_PLANE0, plane);
  560. set_matrix();
  561. glutPostRedisplay();
  562. break;
  563. case '+':
  564. case '=':
  565. plane[3] -= 2.0;
  566. glMatrixMode(GL_MODELVIEW);
  567. glLoadIdentity();
  568. glClipPlane(GL_CLIP_PLANE0, plane);
  569. set_matrix();
  570. glutPostRedisplay();
  571. break;
  572. }
  573. }
  574. static void SpecialKey( int key, int x, int y )
  575. {
  576. switch (key) {
  577. case GLUT_KEY_LEFT:
  578. yrot -= 15.0;
  579. break;
  580. case GLUT_KEY_RIGHT:
  581. yrot += 15.0;
  582. break;
  583. case GLUT_KEY_UP:
  584. xrot += 15.0;
  585. break;
  586. case GLUT_KEY_DOWN:
  587. xrot -= 15.0;
  588. break;
  589. default:
  590. return;
  591. }
  592. set_matrix();
  593. glutPostRedisplay();
  594. }
  595. static GLint Args(int argc, char **argv)
  596. {
  597. GLint i;
  598. GLint mode = 0;
  599. for (i = 1; i < argc; i++) {
  600. if (strcmp(argv[i], "-sb") == 0) {
  601. doubleBuffer = GL_FALSE;
  602. }
  603. else if (strcmp(argv[i], "-db") == 0) {
  604. doubleBuffer = GL_TRUE;
  605. }
  606. else {
  607. printf("%s (Bad option).\n", argv[i]);
  608. return QUIT;
  609. }
  610. }
  611. return mode;
  612. }
  613. int main(int argc, char **argv)
  614. {
  615. GLenum type;
  616. char *extensions;
  617. GLuint arg_mode = Args(argc, argv);
  618. if (arg_mode & QUIT)
  619. exit(0);
  620. read_surface( "isosurf.dat" );
  621. glutInitWindowPosition(0, 0);
  622. glutInitWindowSize(400, 400);
  623. type = GLUT_DEPTH;
  624. type |= GLUT_RGB;
  625. type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
  626. glutInitDisplayMode(type);
  627. if (glutCreateWindow("Isosurface") <= 0) {
  628. exit(0);
  629. }
  630. /* Make sure server supports the vertex array extension */
  631. extensions = (char *) glGetString( GL_EXTENSIONS );
  632. if (!strstr( extensions, "GL_EXT_vertex_array" ))
  633. {
  634. printf("Vertex arrays not supported by this renderer\n");
  635. allowed &= ~(COMPILED|DRAW_ARRAYS|ARRAY_ELT);
  636. }
  637. else if (!strstr( extensions, "GL_EXT_compiled_vertex_array" ))
  638. {
  639. printf("Compiled vertex arrays not supported by this renderer\n");
  640. allowed &= ~COMPILED;
  641. }
  642. Init();
  643. ModeMenu(arg_mode);
  644. glutCreateMenu(ModeMenu);
  645. glutAddMenuEntry("Lit", LIT|NO_TEXTURE|NO_REFLECT);
  646. glutAddMenuEntry("Unlit", UNLIT|NO_TEXTURE|NO_REFLECT);
  647. /* glutAddMenuEntry("Textured", TEXTURE); */
  648. glutAddMenuEntry("Reflect", TEXTURE|REFLECT);
  649. glutAddMenuEntry("", 0);
  650. glutAddMenuEntry("Smooth", SHADE_SMOOTH);
  651. glutAddMenuEntry("Flat", SHADE_FLAT);
  652. glutAddMenuEntry("", 0);
  653. glutAddMenuEntry("Point Filtered", POINT_FILTER);
  654. glutAddMenuEntry("Linear Filtered", LINEAR_FILTER);
  655. glutAddMenuEntry("", 0);
  656. glutAddMenuEntry("Immediate (STRIPS)", NOT_COMPILED|IMMEDIATE|STRIPS);
  657. glutAddMenuEntry("Immediate (TRIANGLES)", NOT_COMPILED|IMMEDIATE|TRIANGLES);
  658. glutAddMenuEntry("", 0);
  659. if (allowed & DRAW_ARRAYS) {
  660. glutAddMenuEntry("DrawArrays (STRIPS)",
  661. NOT_COMPILED|DRAW_ARRAYS|STRIPS);
  662. glutAddMenuEntry("ArrayElement (STRIPS)",
  663. NOT_COMPILED|ARRAY_ELT|STRIPS);
  664. glutAddMenuEntry("DrawElements (TRIANGLES)",
  665. NOT_COMPILED|DRAW_ARRAYS|TRIANGLES);
  666. glutAddMenuEntry("ArrayElement (TRIANGLES)",
  667. NOT_COMPILED|ARRAY_ELT|TRIANGLES);
  668. glutAddMenuEntry("", 0);
  669. }
  670. if (allowed & COMPILED) {
  671. glutAddMenuEntry("Compiled DrawElements (TRIANGLES)",
  672. COMPILED|DRAW_ARRAYS|TRIANGLES);
  673. glutAddMenuEntry("Compiled DrawElements (STRIPS)",
  674. COMPILED|DRAW_ARRAYS|STRIPS);
  675. glutAddMenuEntry("Compiled ArrayElement",
  676. COMPILED|ARRAY_ELT|STRIPS);
  677. glutAddMenuEntry("", 0);
  678. }
  679. glutAddMenuEntry("Quit", QUIT);
  680. glutAttachMenu(GLUT_RIGHT_BUTTON);
  681. glutReshapeFunc(Reshape);
  682. glutKeyboardFunc(Key);
  683. glutSpecialFunc(SpecialKey);
  684. glutDisplayFunc(Display);
  685. glutMainLoop();
  686. return 0;
  687. }