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.

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