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.

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036
  1. /* $Id: isosurf.c,v 1.9 2001/04/19 13:12:40 keithw Exp $ */
  2. /*
  3. * Display an isosurface of 3-D wind speed volume.
  4. *
  5. * Command line options:
  6. * -info print GL implementation information
  7. *
  8. * Brian Paul This file in public domain.
  9. */
  10. /* Keys:
  11. * =====
  12. *
  13. * - Arrow keys to rotate
  14. * - 's' toggles smooth shading
  15. * - 'l' toggles lighting
  16. * - 'f' toggles fog
  17. * - 'I' and 'i' zoom in and out
  18. * - 'c' toggles a user clip plane
  19. * - 'm' toggles colorful materials in GL_TRIANGLES modes.
  20. * - '+' and '-' move the user clip plane
  21. *
  22. * Other options are available via the popup menu.
  23. */
  24. #include <stdio.h>
  25. #include <string.h>
  26. #include <stdlib.h>
  27. #include <string.h>
  28. #include <math.h>
  29. #define GL_GLEXT_LEGACY
  30. #include "GL/glut.h"
  31. #include "readtex.c" /* I know, this is a hack. KW: me too. */
  32. #define TEXTURE_FILE "../images/reflect.rgb"
  33. #define LIT 0x1
  34. #define UNLIT 0x2
  35. #define TEXTURE 0x4
  36. #define NO_TEXTURE 0x8
  37. #define REFLECT 0x10
  38. #define NO_REFLECT 0x20
  39. #define POINT_FILTER 0x40
  40. #define LINEAR_FILTER 0x80
  41. #define GLVERTEX 0x100
  42. #define DRAW_ARRAYS 0x200 /* or draw_elts, if compiled */
  43. #define ARRAY_ELT 0x400
  44. #define COMPILED 0x800
  45. #define IMMEDIATE 0x1000
  46. #define SHADE_SMOOTH 0x2000
  47. #define SHADE_FLAT 0x4000
  48. #define TRIANGLES 0x8000
  49. #define STRIPS 0x10000
  50. #define POINTS 0x20000
  51. #define USER_CLIP 0x40000
  52. #define NO_USER_CLIP 0x80000
  53. #define MATERIALS 0x100000
  54. #define NO_MATERIALS 0x200000
  55. #define FOG 0x400000
  56. #define NO_FOG 0x800000
  57. #define QUIT 0x1000000
  58. #define DISPLAYLIST 0x2000000
  59. #define GLINFO 0x4000000
  60. #define STIPPLE 0x8000000
  61. #define NO_STIPPLE 0x10000000
  62. #define LIGHT_MASK (LIT|UNLIT)
  63. #define TEXTURE_MASK (TEXTURE|NO_TEXTURE)
  64. #define REFLECT_MASK (REFLECT|NO_REFLECT)
  65. #define FILTER_MASK (POINT_FILTER|LINEAR_FILTER)
  66. #define RENDER_STYLE_MASK (GLVERTEX|DRAW_ARRAYS|ARRAY_ELT)
  67. #define COMPILED_MASK (COMPILED|IMMEDIATE|DISPLAYLIST)
  68. #define MATERIAL_MASK (MATERIALS|NO_MATERIALS)
  69. #define PRIMITIVE_MASK (TRIANGLES|STRIPS|POINTS)
  70. #define CLIP_MASK (USER_CLIP|NO_USER_CLIP)
  71. #define SHADE_MASK (SHADE_SMOOTH|SHADE_FLAT)
  72. #define FOG_MASK (FOG|NO_FOG)
  73. #define STIPPLE_MASK (STIPPLE|NO_STIPPLE)
  74. #define MAXVERTS 10000
  75. static GLuint maxverts = MAXVERTS;
  76. static float data[MAXVERTS][6];
  77. static float compressed_data[MAXVERTS][6];
  78. static GLuint indices[MAXVERTS];
  79. static GLuint tri_indices[MAXVERTS*3];
  80. static GLfloat col[100][4];
  81. static GLint numverts, num_tri_verts, numuniq;
  82. static GLfloat xrot;
  83. static GLfloat yrot;
  84. static GLfloat dist = -6;
  85. static GLint state, allowed = ~0;
  86. static GLboolean doubleBuffer = GL_TRUE;
  87. static GLdouble plane[4] = {1.0, 0.0, -1.0, 0.0};
  88. static GLuint surf1, surf2, surf3;
  89. static GLboolean PrintInfo = GL_FALSE;
  90. static GLubyte halftone[] = {
  91. 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA,
  92. 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
  93. 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA,
  94. 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
  95. 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA,
  96. 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
  97. 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA,
  98. 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
  99. 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA,
  100. 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
  101. 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55};
  102. /* forward decl */
  103. int BuildVertexList( int mode );
  104. int BuildArrayEltList( int mode );
  105. int BuildDrawArraysList( int mode );
  106. static void read_surface( char *filename )
  107. {
  108. FILE *f;
  109. f = fopen(filename,"r");
  110. if (!f) {
  111. printf("couldn't read %s\n", filename);
  112. exit(1);
  113. }
  114. numverts = 0;
  115. while (!feof(f) && numverts<maxverts) {
  116. fscanf( f, "%f %f %f %f %f %f",
  117. &data[numverts][0], &data[numverts][1], &data[numverts][2],
  118. &data[numverts][3], &data[numverts][4], &data[numverts][5] );
  119. numverts++;
  120. }
  121. numverts--;
  122. printf("%d vertices, %d triangles\n", numverts, numverts-2);
  123. fclose(f);
  124. }
  125. struct data_idx {
  126. float *data;
  127. int idx;
  128. int uniq_idx;
  129. };
  130. #define COMPARE_FUNC( AXIS ) \
  131. static int compare_axis_##AXIS( const void *a, const void *b ) \
  132. { \
  133. float t = ( (*(struct data_idx *)a).data[AXIS] - \
  134. (*(struct data_idx *)b).data[AXIS] ); \
  135. \
  136. if (t < 0) return -1; \
  137. if (t > 0) return 1; \
  138. return 0; \
  139. }
  140. COMPARE_FUNC(0)
  141. COMPARE_FUNC(1)
  142. COMPARE_FUNC(2)
  143. COMPARE_FUNC(3)
  144. COMPARE_FUNC(4)
  145. COMPARE_FUNC(5)
  146. COMPARE_FUNC(6)
  147. int (*(compare[7]))( const void *a, const void *b ) =
  148. {
  149. compare_axis_0,
  150. compare_axis_1,
  151. compare_axis_2,
  152. compare_axis_3,
  153. compare_axis_4,
  154. compare_axis_5,
  155. compare_axis_6,
  156. };
  157. #define VEC_ELT(f, s, i) (float *)(((char *)f) + s * i)
  158. static int sort_axis( int axis,
  159. int vec_size,
  160. int vec_stride,
  161. struct data_idx *indices,
  162. int start,
  163. int finish,
  164. float *out,
  165. int uniq,
  166. const float fudge )
  167. {
  168. int i;
  169. if (finish-start > 2)
  170. {
  171. qsort( indices+start, finish-start, sizeof(*indices), compare[axis] );
  172. }
  173. else if (indices[start].data[axis] > indices[start+1].data[axis])
  174. {
  175. struct data_idx tmp = indices[start];
  176. indices[start] = indices[start+1];
  177. indices[start+1] = tmp;
  178. }
  179. if (axis == vec_size-1) {
  180. for (i = start ; i < finish ; ) {
  181. float max = indices[i].data[axis] + fudge;
  182. float *dest = VEC_ELT(out, vec_stride, uniq);
  183. int j;
  184. for (j = 0 ; j < vec_size ; j++)
  185. dest[j] = indices[i].data[j];
  186. for ( ; i < finish && max >= indices[i].data[axis]; i++)
  187. indices[i].uniq_idx = uniq;
  188. uniq++;
  189. }
  190. } else {
  191. for (i = start ; i < finish ; ) {
  192. int j = i + 1;
  193. float max = indices[i].data[axis] + fudge;
  194. while (j < finish && max >= indices[j].data[axis]) j++;
  195. if (j == i+1) {
  196. float *dest = VEC_ELT(out, vec_stride, uniq);
  197. int k;
  198. indices[i].uniq_idx = uniq;
  199. for (k = 0 ; k < vec_size ; k++)
  200. dest[k] = indices[i].data[k];
  201. uniq++;
  202. } else {
  203. uniq = sort_axis( axis+1, vec_size, vec_stride,
  204. indices, i, j, out, uniq, fudge );
  205. }
  206. i = j;
  207. }
  208. }
  209. return uniq;
  210. }
  211. static void extract_indices1( const struct data_idx *in, unsigned int *out,
  212. int n )
  213. {
  214. int i;
  215. for ( i = 0 ; i < n ; i++ ) {
  216. out[in[i].idx] = in[i].uniq_idx;
  217. }
  218. }
  219. static void compactify_arrays(void)
  220. {
  221. int i;
  222. struct data_idx *ind;
  223. ind = (struct data_idx *) malloc( sizeof(struct data_idx) * numverts );
  224. for (i = 0 ; i < numverts ; i++) {
  225. ind[i].idx = i;
  226. ind[i].data = data[i];
  227. }
  228. numuniq = sort_axis(0,
  229. sizeof(compressed_data[0])/sizeof(float),
  230. sizeof(compressed_data[0]),
  231. ind,
  232. 0,
  233. numverts,
  234. (float *)compressed_data,
  235. 0,
  236. 1e-6);
  237. printf("Nr unique vertex/normal pairs: %d\n", numuniq);
  238. extract_indices1( ind, indices, numverts );
  239. free( ind );
  240. }
  241. static float myrand( float max )
  242. {
  243. return max*rand()/(RAND_MAX+1.0);
  244. }
  245. static void make_tri_indices( void )
  246. {
  247. unsigned int *v = tri_indices;
  248. unsigned int parity = 0;
  249. unsigned int i, j;
  250. for (j=2;j<numverts;j++,parity^=1) {
  251. if (parity) {
  252. *v++ = indices[j-1];
  253. *v++ = indices[j-2];
  254. *v++ = indices[j];
  255. } else {
  256. *v++ = indices[j-2];
  257. *v++ = indices[j-1];
  258. *v++ = indices[j];
  259. }
  260. }
  261. num_tri_verts = v - tri_indices;
  262. printf("num_tri_verts: %d\n", num_tri_verts);
  263. for (i = j = 0 ; i < num_tri_verts ; i += 600, j++) {
  264. col[j][3] = 1;
  265. col[j][2] = myrand(1);
  266. col[j][1] = myrand(1);
  267. col[j][0] = myrand(1);
  268. }
  269. }
  270. #define MIN(x,y) (x < y) ? x : y
  271. static void draw_surface( int with_state )
  272. {
  273. GLuint i, j;
  274. switch (with_state & (COMPILED_MASK|RENDER_STYLE_MASK|PRIMITIVE_MASK)) {
  275. #ifdef GL_EXT_vertex_array
  276. case (IMMEDIATE|DRAW_ARRAYS|TRIANGLES):
  277. case (COMPILED|DRAW_ARRAYS|TRIANGLES):
  278. if (with_state & MATERIALS) {
  279. for (j = i = 0 ; i < num_tri_verts ; i += 600, j++) {
  280. GLuint nr = MIN(num_tri_verts-i, 600);
  281. glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, col[j]);
  282. glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, col[j]);
  283. glDrawElements( GL_TRIANGLES, nr, GL_UNSIGNED_INT, tri_indices+i );
  284. }
  285. } else {
  286. glDrawElements( GL_TRIANGLES, num_tri_verts, GL_UNSIGNED_INT,
  287. tri_indices );
  288. }
  289. break;
  290. case (IMMEDIATE|ARRAY_ELT|TRIANGLES):
  291. case (COMPILED|ARRAY_ELT|TRIANGLES):
  292. if (with_state & MATERIALS) {
  293. for (j = i = 0 ; i < num_tri_verts ; i += 600, j++) {
  294. GLuint nr = MIN(num_tri_verts-i, 600);
  295. GLuint k;
  296. glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, col[j]);
  297. glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, col[j]);
  298. glBegin( GL_TRIANGLES );
  299. for (k = 0 ; k < nr ; k++)
  300. glArrayElement( tri_indices[i+k] );
  301. glEnd();
  302. }
  303. } else {
  304. glBegin( GL_TRIANGLES );
  305. for (i = 0 ; i < num_tri_verts ; i++)
  306. glArrayElement( tri_indices[i] );
  307. glEnd();
  308. }
  309. break;
  310. /* Uses the original arrays (including duplicate elements):
  311. */
  312. case (IMMEDIATE|DRAW_ARRAYS|STRIPS):
  313. glDrawArraysEXT( GL_TRIANGLE_STRIP, 0, numverts );
  314. break;
  315. case (COMPILED|DRAW_ARRAYS|STRIPS):
  316. glDrawElements( GL_TRIANGLE_STRIP, numverts, GL_UNSIGNED_INT, indices );
  317. break;
  318. /* Uses the original arrays (including duplicate elements):
  319. */
  320. case (IMMEDIATE|ARRAY_ELT|STRIPS):
  321. glBegin( GL_TRIANGLE_STRIP );
  322. for (i = 0 ; i < numverts ; i++)
  323. glArrayElement( i );
  324. glEnd();
  325. break;
  326. case (COMPILED|ARRAY_ELT|STRIPS):
  327. glBegin( GL_TRIANGLE_STRIP );
  328. for (i = 0 ; i < numverts ; i++)
  329. glArrayElement( indices[i] );
  330. glEnd();
  331. break;
  332. case (DISPLAYLIST|GLVERTEX|STRIPS):
  333. glCallList(surf1);
  334. break;
  335. case (DISPLAYLIST|ARRAY_ELT|STRIPS):
  336. glCallList(surf2);
  337. break;
  338. case (DISPLAYLIST|DRAW_ARRAYS|STRIPS):
  339. glCallList(surf3);
  340. break;
  341. case (IMMEDIATE|DRAW_ARRAYS|POINTS):
  342. glDrawArraysEXT( GL_POINTS, 0, numverts );
  343. break;
  344. case (COMPILED|DRAW_ARRAYS|POINTS):
  345. glDrawElements( GL_POINTS, numverts, GL_UNSIGNED_INT, indices );
  346. break;
  347. case (IMMEDIATE|ARRAY_ELT|POINTS):
  348. case (COMPILED|ARRAY_ELT|POINTS):
  349. glBegin( GL_POINTS );
  350. for (i = 0 ; i < numverts ; i++)
  351. glArrayElement( indices[i] );
  352. glEnd();
  353. break;
  354. #endif
  355. case (IMMEDIATE|GLVERTEX|TRIANGLES):
  356. if (with_state & MATERIALS) {
  357. for (j = i = 0 ; i < num_tri_verts ; i += 600, j++) {
  358. GLuint nr = MIN(num_tri_verts-i, 600);
  359. GLuint k;
  360. glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, col[j]);
  361. glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, col[j]);
  362. glBegin( GL_TRIANGLES );
  363. for (k = 0 ; k < nr ; k++) {
  364. glNormal3fv( &compressed_data[tri_indices[i+k]][3] );
  365. glVertex3fv( &compressed_data[tri_indices[i+k]][0] );
  366. }
  367. glEnd();
  368. }
  369. } else {
  370. glBegin( GL_TRIANGLES );
  371. for (i = 0 ; i < num_tri_verts ; i++) {
  372. glNormal3fv( &compressed_data[tri_indices[i]][3] );
  373. glVertex3fv( &compressed_data[tri_indices[i]][0] );
  374. }
  375. glEnd();
  376. }
  377. break;
  378. case (IMMEDIATE|GLVERTEX|POINTS):
  379. glBegin( GL_POINTS );
  380. for ( i = 0 ; i < numverts ; i++ ) {
  381. glNormal3fv( &data[i][3] );
  382. glVertex3fv( &data[i][0] );
  383. }
  384. glEnd();
  385. break;
  386. /* Uses the original arrays (including duplicate elements):
  387. */
  388. default:
  389. glBegin( GL_TRIANGLE_STRIP );
  390. for (i=0;i<numverts;i++) {
  391. glNormal3fv( &data[i][3] );
  392. glVertex3fv( &data[i][0] );
  393. }
  394. glEnd();
  395. }
  396. }
  397. static void Display(void)
  398. {
  399. glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
  400. draw_surface( state );
  401. glFlush();
  402. if (doubleBuffer) glutSwapBuffers();
  403. }
  404. int BuildVertexList( int mode )
  405. {
  406. int rv = glGenLists(1);
  407. glNewList(rv, mode );
  408. draw_surface( IMMEDIATE|GLVERTEX|STRIPS );
  409. glEndList();
  410. return rv;
  411. }
  412. int BuildArrayEltList( int mode )
  413. {
  414. int rv = glGenLists(1);
  415. glNewList(rv, mode );
  416. draw_surface( IMMEDIATE|ARRAY_ELT|STRIPS );
  417. glEndList();
  418. return rv;
  419. }
  420. int BuildDrawArraysList( int mode )
  421. {
  422. int rv = glGenLists(1);
  423. glNewList(rv, mode );
  424. draw_surface( IMMEDIATE|DRAW_ARRAYS|STRIPS );
  425. glEndList();
  426. return rv;
  427. }
  428. /* KW: only do this when necessary, so CVA can re-use results.
  429. */
  430. static void set_matrix( void )
  431. {
  432. glMatrixMode(GL_MODELVIEW);
  433. glLoadIdentity();
  434. glTranslatef( 0.0, 0.0, dist );
  435. glRotatef( yrot, 0.0, 1.0, 0.0 );
  436. glRotatef( xrot, 1.0, 0.0, 0.0 );
  437. }
  438. static void Benchmark( float xdiff, float ydiff )
  439. {
  440. int startTime, endTime;
  441. int draws;
  442. double seconds, fps, triPerSecond;
  443. printf("Benchmarking...\n");
  444. draws = 0;
  445. startTime = glutGet(GLUT_ELAPSED_TIME);
  446. xrot = 0.0;
  447. do {
  448. xrot += xdiff;
  449. yrot += ydiff;
  450. set_matrix();
  451. Display();
  452. draws++;
  453. endTime = glutGet(GLUT_ELAPSED_TIME);
  454. } while (endTime - startTime < 5000); /* 5 seconds */
  455. /* Results */
  456. seconds = (double) (endTime - startTime) / 1000.0;
  457. triPerSecond = (numverts - 2) * draws / seconds;
  458. fps = draws / seconds;
  459. printf("Result: triangles/sec: %g fps: %g\n", triPerSecond, fps);
  460. }
  461. static void InitMaterials(void)
  462. {
  463. static float ambient[] = {0.1, 0.1, 0.1, 1.0};
  464. static float diffuse[] = {0.5, 1.0, 1.0, 1.0};
  465. static float position0[] = {0.0, 0.0, 20.0, 0.0};
  466. static float position1[] = {0.0, 0.0, -20.0, 0.0};
  467. static float front_mat_shininess[] = {60.0};
  468. static float front_mat_specular[] = {0.2, 0.2, 0.2, 1.0};
  469. static float front_mat_diffuse[] = {0.5, 0.28, 0.38, 1.0};
  470. /*
  471. static float back_mat_shininess[] = {60.0};
  472. static float back_mat_specular[] = {0.5, 0.5, 0.2, 1.0};
  473. static float back_mat_diffuse[] = {1.0, 1.0, 0.2, 1.0};
  474. */
  475. static float lmodel_ambient[] = {1.0, 1.0, 1.0, 1.0};
  476. static float lmodel_twoside[] = {GL_FALSE};
  477. glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
  478. glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
  479. glLightfv(GL_LIGHT0, GL_POSITION, position0);
  480. glEnable(GL_LIGHT0);
  481. glLightfv(GL_LIGHT1, GL_AMBIENT, ambient);
  482. glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse);
  483. glLightfv(GL_LIGHT1, GL_POSITION, position1);
  484. glEnable(GL_LIGHT1);
  485. glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
  486. glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE, lmodel_twoside);
  487. glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, front_mat_shininess);
  488. glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, front_mat_specular);
  489. glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, front_mat_diffuse);
  490. glPolygonStipple (halftone);
  491. }
  492. #define UPDATE(o,n,mask) (o&=~mask, o|=n&mask)
  493. #define CHANGED(o,n,mask) ((n&mask) && \
  494. (n&mask) != (o&mask) ? UPDATE(o,n,mask) : 0)
  495. static void ModeMenu(int m)
  496. {
  497. m &= allowed;
  498. if (!m) return;
  499. if (m==QUIT)
  500. exit(0);
  501. if (m==GLINFO) {
  502. printf("GL_VERSION: %s\n", (char *) glGetString(GL_VERSION));
  503. printf("GL_EXTENSIONS: %s\n", (char *) glGetString(GL_EXTENSIONS));
  504. printf("GL_RENDERER: %s\n", (char *) glGetString(GL_RENDERER));
  505. return;
  506. }
  507. if (CHANGED(state, m, FILTER_MASK)) {
  508. if (m & LINEAR_FILTER) {
  509. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  510. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  511. } else {
  512. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  513. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  514. }
  515. }
  516. if (CHANGED(state, m, LIGHT_MASK)) {
  517. if (m & LIT)
  518. glEnable(GL_LIGHTING);
  519. else
  520. glDisable(GL_LIGHTING);
  521. }
  522. if (CHANGED(state, m, SHADE_MASK)) {
  523. if (m & SHADE_SMOOTH)
  524. glShadeModel(GL_SMOOTH);
  525. else
  526. glShadeModel(GL_FLAT);
  527. }
  528. if (CHANGED(state, m, TEXTURE_MASK)) {
  529. if (m & TEXTURE)
  530. glEnable(GL_TEXTURE_2D);
  531. else
  532. glDisable(GL_TEXTURE_2D);
  533. }
  534. if (CHANGED(state, m, REFLECT_MASK)) {
  535. if (m & REFLECT) {
  536. glEnable(GL_TEXTURE_GEN_S);
  537. glEnable(GL_TEXTURE_GEN_T);
  538. } else {
  539. glDisable(GL_TEXTURE_GEN_S);
  540. glDisable(GL_TEXTURE_GEN_T);
  541. }
  542. }
  543. if (CHANGED(state, m, CLIP_MASK)) {
  544. if (m & USER_CLIP) {
  545. glEnable(GL_CLIP_PLANE0);
  546. } else {
  547. glDisable(GL_CLIP_PLANE0);
  548. }
  549. }
  550. if (CHANGED(state, m, FOG_MASK)) {
  551. if (m & FOG)
  552. {
  553. glEnable(GL_FOG);
  554. printf("FOG enable\n");
  555. }
  556. else
  557. {
  558. glDisable(GL_FOG);
  559. printf("FOG disable\n");
  560. }
  561. }
  562. if (CHANGED(state, m, STIPPLE_MASK)) {
  563. if (m & STIPPLE)
  564. {
  565. glEnable(GL_POLYGON_STIPPLE);
  566. printf("STIPPLE enable\n");
  567. }
  568. else
  569. {
  570. glDisable(GL_POLYGON_STIPPLE);
  571. printf("STIPPLE disable\n");
  572. }
  573. }
  574. #ifdef GL_EXT_vertex_array
  575. if (CHANGED(state, m, (COMPILED_MASK|RENDER_STYLE_MASK|PRIMITIVE_MASK)))
  576. {
  577. if ((m & (COMPILED_MASK|PRIMITIVE_MASK)) == (IMMEDIATE|STRIPS))
  578. {
  579. glVertexPointerEXT( 3, GL_FLOAT, sizeof(data[0]), numverts, data );
  580. glNormalPointerEXT( GL_FLOAT, sizeof(data[0]), numverts, &data[0][3]);
  581. }
  582. else
  583. {
  584. glVertexPointerEXT( 3, GL_FLOAT, sizeof(data[0]), numuniq,
  585. compressed_data );
  586. glNormalPointerEXT( GL_FLOAT, sizeof(data[0]), numuniq,
  587. &compressed_data[0][3]);
  588. }
  589. #ifdef GL_EXT_compiled_vertex_array
  590. if (allowed & COMPILED) {
  591. if (m & COMPILED) {
  592. glLockArraysEXT( 0, numuniq );
  593. } else {
  594. glUnlockArraysEXT();
  595. }
  596. }
  597. #endif
  598. }
  599. #endif
  600. if (m & (RENDER_STYLE_MASK|PRIMITIVE_MASK)) {
  601. UPDATE(state, m, (RENDER_STYLE_MASK|PRIMITIVE_MASK));
  602. }
  603. if (m & MATERIAL_MASK) {
  604. UPDATE(state, m, MATERIAL_MASK);
  605. }
  606. glutPostRedisplay();
  607. }
  608. static void Init(int argc, char *argv[])
  609. {
  610. GLfloat fogColor[4] = {0.5,1.0,0.5,1.0};
  611. glClearColor(0.0, 0.0, 1.0, 0.0);
  612. glEnable( GL_DEPTH_TEST );
  613. glEnable( GL_VERTEX_ARRAY_EXT );
  614. glEnable( GL_NORMAL_ARRAY_EXT );
  615. InitMaterials();
  616. glMatrixMode(GL_PROJECTION);
  617. glLoadIdentity();
  618. glFrustum( -1.0, 1.0, -1.0, 1.0, 5, 25 );
  619. glMatrixMode(GL_MODELVIEW);
  620. glLoadIdentity();
  621. glClipPlane(GL_CLIP_PLANE0, plane);
  622. set_matrix();
  623. glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
  624. glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
  625. glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
  626. glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
  627. if (!LoadRGBMipmaps(TEXTURE_FILE, GL_RGB)) {
  628. printf("Error: couldn't load texture image\n");
  629. exit(1);
  630. }
  631. /* Green fog is easy to see */
  632. glFogi(GL_FOG_MODE,GL_EXP2);
  633. glFogfv(GL_FOG_COLOR,fogColor);
  634. glFogf(GL_FOG_DENSITY,0.15);
  635. glHint(GL_FOG_HINT,GL_DONT_CARE);
  636. compactify_arrays();
  637. make_tri_indices();
  638. ModeMenu(SHADE_SMOOTH|
  639. LIT|
  640. NO_TEXTURE|
  641. NO_REFLECT|
  642. POINT_FILTER|
  643. IMMEDIATE|
  644. NO_USER_CLIP|
  645. NO_MATERIALS|
  646. NO_FOG|
  647. NO_STIPPLE|
  648. GLVERTEX);
  649. surf1 = BuildVertexList( GL_COMPILE );
  650. surf2 = BuildArrayEltList( GL_COMPILE );
  651. surf3 = BuildDrawArraysList( GL_COMPILE );
  652. if (PrintInfo) {
  653. printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
  654. printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION));
  655. printf("GL_VENDOR = %s\n", (char *) glGetString(GL_VENDOR));
  656. printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS));
  657. }
  658. }
  659. static void Reshape(int width, int height)
  660. {
  661. glViewport(0, 0, (GLint)width, (GLint)height);
  662. }
  663. static void Key( unsigned char key, int x, int y )
  664. {
  665. (void) x;
  666. (void) y;
  667. switch (key) {
  668. case 27:
  669. exit(0);
  670. case 'f':
  671. ModeMenu((state ^ FOG_MASK) & FOG_MASK);
  672. break;
  673. case 's':
  674. ModeMenu((state ^ SHADE_MASK) & SHADE_MASK);
  675. break;
  676. case 't':
  677. ModeMenu((state ^ STIPPLE_MASK) & STIPPLE_MASK);
  678. break;
  679. case 'l':
  680. ModeMenu((state ^ LIGHT_MASK) & LIGHT_MASK);
  681. break;
  682. case 'm':
  683. ModeMenu((state ^ MATERIAL_MASK) & MATERIAL_MASK);
  684. break;
  685. case 'c':
  686. ModeMenu((state ^ CLIP_MASK) & CLIP_MASK);
  687. break;
  688. case 'v':
  689. if (allowed&COMPILED)
  690. ModeMenu(COMPILED|DRAW_ARRAYS|TRIANGLES);
  691. break;
  692. case 'V':
  693. ModeMenu(IMMEDIATE|GLVERTEX|STRIPS);
  694. break;
  695. case 'b':
  696. Benchmark(5.0, 0);
  697. break;
  698. case 'B':
  699. Benchmark(0, 5.0);
  700. break;
  701. case 'i':
  702. dist += .25;
  703. set_matrix();
  704. glutPostRedisplay();
  705. break;
  706. case 'I':
  707. dist -= .25;
  708. set_matrix();
  709. glutPostRedisplay();
  710. break;
  711. case '-':
  712. case '_':
  713. plane[3] += 2.0;
  714. glMatrixMode(GL_MODELVIEW);
  715. glLoadIdentity();
  716. glClipPlane(GL_CLIP_PLANE0, plane);
  717. set_matrix();
  718. glutPostRedisplay();
  719. break;
  720. case '+':
  721. case '=':
  722. plane[3] -= 2.0;
  723. glMatrixMode(GL_MODELVIEW);
  724. glLoadIdentity();
  725. glClipPlane(GL_CLIP_PLANE0, plane);
  726. set_matrix();
  727. glutPostRedisplay();
  728. break;
  729. }
  730. }
  731. static void SpecialKey( int key, int x, int y )
  732. {
  733. (void) x;
  734. (void) y;
  735. switch (key) {
  736. case GLUT_KEY_LEFT:
  737. yrot -= 15.0;
  738. break;
  739. case GLUT_KEY_RIGHT:
  740. yrot += 15.0;
  741. break;
  742. case GLUT_KEY_UP:
  743. xrot += 15.0;
  744. break;
  745. case GLUT_KEY_DOWN:
  746. xrot -= 15.0;
  747. break;
  748. default:
  749. return;
  750. }
  751. set_matrix();
  752. glutPostRedisplay();
  753. }
  754. static GLint Args(int argc, char **argv)
  755. {
  756. GLint i;
  757. GLint mode = 0;
  758. for (i = 1; i < argc; i++) {
  759. if (strcmp(argv[i], "-sb") == 0) {
  760. doubleBuffer = GL_FALSE;
  761. }
  762. else if (strcmp(argv[i], "-db") == 0) {
  763. doubleBuffer = GL_TRUE;
  764. }
  765. else if (strcmp(argv[i], "-info") == 0) {
  766. PrintInfo = GL_TRUE;
  767. }
  768. else if (strcmp(argv[i], "-10") == 0) {
  769. maxverts = 10;
  770. }
  771. else if (strcmp(argv[i], "-100") == 0) {
  772. maxverts = 100;
  773. }
  774. else if (strcmp(argv[i], "-1000") == 0) {
  775. maxverts = 1000;
  776. }
  777. else {
  778. printf("%s (Bad option).\n", argv[i]);
  779. return QUIT;
  780. }
  781. }
  782. return mode;
  783. }
  784. int main(int argc, char **argv)
  785. {
  786. GLenum type;
  787. char *extensions;
  788. GLuint arg_mode = Args(argc, argv);
  789. if (arg_mode & QUIT)
  790. exit(0);
  791. read_surface( "isosurf.dat" );
  792. glutInitWindowPosition(0, 0);
  793. glutInitWindowSize(400, 400);
  794. type = GLUT_DEPTH;
  795. type |= GLUT_RGB;
  796. type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
  797. glutInitDisplayMode(type);
  798. if (glutCreateWindow("Isosurface") <= 0) {
  799. exit(0);
  800. }
  801. /* Make sure server supports the vertex array extension */
  802. extensions = (char *) glGetString( GL_EXTENSIONS );
  803. if (!strstr( extensions, "GL_EXT_vertex_array" ))
  804. {
  805. printf("Vertex arrays not supported by this renderer\n");
  806. allowed &= ~(COMPILED|DRAW_ARRAYS|ARRAY_ELT);
  807. }
  808. else if (!strstr( extensions, "GL_EXT_compiled_vertex_array" ))
  809. {
  810. printf("Compiled vertex arrays not supported by this renderer\n");
  811. allowed &= ~COMPILED;
  812. }
  813. Init(argc, argv);
  814. ModeMenu(arg_mode);
  815. glutCreateMenu(ModeMenu);
  816. glutAddMenuEntry("GL info", GLINFO);
  817. glutAddMenuEntry("", 0);
  818. glutAddMenuEntry("Lit", LIT|NO_TEXTURE|NO_REFLECT);
  819. glutAddMenuEntry("Unlit", UNLIT|NO_TEXTURE|NO_REFLECT);
  820. /* glutAddMenuEntry("Textured", TEXTURE); */
  821. glutAddMenuEntry("Reflect", TEXTURE|REFLECT);
  822. glutAddMenuEntry("", 0);
  823. glutAddMenuEntry("Smooth", SHADE_SMOOTH);
  824. glutAddMenuEntry("Flat", SHADE_FLAT);
  825. glutAddMenuEntry("", 0);
  826. glutAddMenuEntry("Fog", FOG);
  827. glutAddMenuEntry("No Fog", NO_FOG);
  828. glutAddMenuEntry("", 0);
  829. glutAddMenuEntry("Stipple", STIPPLE);
  830. glutAddMenuEntry("No Stipple", NO_STIPPLE);
  831. glutAddMenuEntry("", 0);
  832. glutAddMenuEntry("Point Filtered", POINT_FILTER);
  833. glutAddMenuEntry("Linear Filtered", LINEAR_FILTER);
  834. glutAddMenuEntry("", 0);
  835. glutAddMenuEntry("glVertex (TRIANGLES)", IMMEDIATE|GLVERTEX|TRIANGLES);
  836. glutAddMenuEntry("glVertex (STRIPS)", IMMEDIATE|GLVERTEX|STRIPS);
  837. glutAddMenuEntry("glVertex (POINTS)", IMMEDIATE|GLVERTEX|POINTS);
  838. glutAddMenuEntry("", 0);
  839. glutAddMenuEntry("glVertex display list (STRIPS)",
  840. DISPLAYLIST|GLVERTEX|STRIPS);
  841. glutAddMenuEntry("glArrayElement display list (STRIPS)",
  842. DISPLAYLIST|GLVERTEX|STRIPS);
  843. glutAddMenuEntry("glDrawArrays display list (STRIPS)",
  844. DISPLAYLIST|GLVERTEX|STRIPS);
  845. glutAddMenuEntry("", 0);
  846. if (allowed & DRAW_ARRAYS) {
  847. glutAddMenuEntry("DrawElements (TRIANGLES)",
  848. IMMEDIATE|DRAW_ARRAYS|TRIANGLES);
  849. glutAddMenuEntry("DrawArrays (STRIPS)",
  850. IMMEDIATE|DRAW_ARRAYS|STRIPS);
  851. glutAddMenuEntry("DrawArrays (POINTS)",
  852. IMMEDIATE|DRAW_ARRAYS|POINTS);
  853. glutAddMenuEntry("ArrayElement (TRIANGLES)",
  854. IMMEDIATE|ARRAY_ELT|TRIANGLES);
  855. glutAddMenuEntry("ArrayElement (STRIPS)",
  856. IMMEDIATE|ARRAY_ELT|STRIPS);
  857. glutAddMenuEntry("ArrayElement (POINTS)",
  858. IMMEDIATE|ARRAY_ELT|POINTS);
  859. glutAddMenuEntry("", 0);
  860. }
  861. if (allowed & COMPILED) {
  862. glutAddMenuEntry("Compiled DrawElements (TRIANGLES)",
  863. COMPILED|DRAW_ARRAYS|TRIANGLES);
  864. glutAddMenuEntry("Compiled DrawElements (STRIPS)",
  865. COMPILED|DRAW_ARRAYS|STRIPS);
  866. glutAddMenuEntry("Compiled DrawElements (POINTS)",
  867. COMPILED|DRAW_ARRAYS|POINTS);
  868. glutAddMenuEntry("Compiled ArrayElement (TRIANGLES)",
  869. COMPILED|ARRAY_ELT|TRIANGLES);
  870. glutAddMenuEntry("Compiled ArrayElement (STRIPS)",
  871. COMPILED|ARRAY_ELT|STRIPS);
  872. glutAddMenuEntry("Compiled ArrayElement (POINTS)",
  873. COMPILED|ARRAY_ELT|POINTS);
  874. glutAddMenuEntry("", 0);
  875. }
  876. glutAddMenuEntry("Quit", QUIT);
  877. glutAttachMenu(GLUT_RIGHT_BUTTON);
  878. glutReshapeFunc(Reshape);
  879. glutKeyboardFunc(Key);
  880. glutSpecialFunc(SpecialKey);
  881. glutDisplayFunc(Display);
  882. glutMainLoop();
  883. return 0;
  884. }