132001f49Smrg 232001f49Smrg/* 332001f49Smrg * Display an isosurface of 3-D wind speed volume. 432001f49Smrg * 532001f49Smrg * Command line options: 632001f49Smrg * -info print GL implementation information 732001f49Smrg * 832001f49Smrg * Brian Paul This file in public domain. 932001f49Smrg */ 1032001f49Smrg 1132001f49Smrg 1232001f49Smrg/* Keys: 1332001f49Smrg * ===== 1432001f49Smrg * 1532001f49Smrg * - Arrow keys to rotate 1632001f49Smrg * - 's' toggles smooth shading 1732001f49Smrg * - 'l' toggles lighting 1832001f49Smrg * - 'f' toggles fog 1932001f49Smrg * - 'I' and 'i' zoom in and out 2032001f49Smrg * - 'c' toggles a user clip plane 2132001f49Smrg * - 'm' toggles colorful materials in GL_TRIANGLES modes. 2232001f49Smrg * - '+' and '-' move the user clip plane 2332001f49Smrg * 2432001f49Smrg * Other options are available via the popup menu. 2532001f49Smrg */ 2632001f49Smrg 2732001f49Smrg#include <stdio.h> 2832001f49Smrg#include <string.h> 2932001f49Smrg#include <stdlib.h> 3032001f49Smrg#include <math.h> 3132001f49Smrg#ifdef _WIN32 3232001f49Smrg#include <windows.h> 3332001f49Smrg#undef CLIP_MASK 3432001f49Smrg#endif 3532001f49Smrg#include <GL/glew.h> 3632001f49Smrg#include "glut_wrap.h" 3732001f49Smrg 3832001f49Smrg#include "readtex.h" 3932001f49Smrg#define TEXTURE_FILE DEMOS_DATA_DIR "reflect.rgb" 4032001f49Smrg 4132001f49Smrg#define LIT 0x00000001 4232001f49Smrg#define UNLIT 0x00000002 4332001f49Smrg#define REFLECT 0x00000004 4432001f49Smrg#define POINT_FILTER 0x00000008 4532001f49Smrg#define LINEAR_FILTER 0x00000010 4632001f49Smrg#define GLVERTEX 0x00000020 4732001f49Smrg#define DRAW_ELTS 0x00000040 4832001f49Smrg#define DRAW_ARRAYS 0x00000080 4932001f49Smrg#define ARRAY_ELT 0x00000100 5032001f49Smrg#define LOCKED 0x00000200 5132001f49Smrg#define UNLOCKED 0x00000400 5232001f49Smrg#define IMMEDIATE 0x00000800 5332001f49Smrg#define DISPLAYLIST 0x00001000 5432001f49Smrg#define SHADE_SMOOTH 0x00002000 5532001f49Smrg#define SHADE_FLAT 0x00004000 5632001f49Smrg#define TRIANGLES 0x00008000 5732001f49Smrg#define STRIPS 0x00010000 5832001f49Smrg#define POINTS 0x00020000 5932001f49Smrg#define USER_CLIP 0x00040000 6032001f49Smrg#define NO_USER_CLIP 0x00080000 6132001f49Smrg#define MATERIALS 0x00100000 6232001f49Smrg#define NO_MATERIALS 0x00200000 6332001f49Smrg#define FOG 0x00400000 6432001f49Smrg#define NO_FOG 0x00800000 6532001f49Smrg#define QUIT 0x01000000 6632001f49Smrg#define GLINFO 0x02000000 6732001f49Smrg#define STIPPLE 0x04000000 6832001f49Smrg#define NO_STIPPLE 0x08000000 6932001f49Smrg#define POLYGON_FILL 0x10000000 7032001f49Smrg#define POLYGON_LINE 0x20000000 7132001f49Smrg#define POLYGON_POINT 0x40000000 7232001f49Smrg 7332001f49Smrg#define LIGHT_MASK (LIT|UNLIT|REFLECT) 7432001f49Smrg#define FILTER_MASK (POINT_FILTER|LINEAR_FILTER) 7532001f49Smrg#define RENDER_STYLE_MASK (GLVERTEX|DRAW_ARRAYS|DRAW_ELTS|ARRAY_ELT) 7632001f49Smrg#define DLIST_MASK (IMMEDIATE|DISPLAYLIST) 7732001f49Smrg#define LOCK_MASK (LOCKED|UNLOCKED) 7832001f49Smrg#define MATERIAL_MASK (MATERIALS|NO_MATERIALS) 7932001f49Smrg#define PRIMITIVE_MASK (TRIANGLES|STRIPS|POINTS) 8032001f49Smrg#define CLIP_MASK (USER_CLIP|NO_USER_CLIP) 8132001f49Smrg#define SHADE_MASK (SHADE_SMOOTH|SHADE_FLAT) 8232001f49Smrg#define FOG_MASK (FOG|NO_FOG) 8332001f49Smrg#define STIPPLE_MASK (STIPPLE|NO_STIPPLE) 8432001f49Smrg#define POLYGON_MASK (POLYGON_FILL|POLYGON_LINE|POLYGON_POINT) 8532001f49Smrg 8632001f49Smrg#define MAXVERTS 10000 8732001f49Smrgstatic GLint maxverts = MAXVERTS; 8832001f49Smrgstatic float data[MAXVERTS][6]; 8932001f49Smrgstatic float compressed_data[MAXVERTS][6]; 9032001f49Smrgstatic float expanded_data[MAXVERTS*3][6]; 9132001f49Smrgstatic GLuint indices[MAXVERTS]; 9232001f49Smrgstatic GLuint tri_indices[MAXVERTS*3]; 9332001f49Smrgstatic GLuint strip_indices[MAXVERTS]; 9432001f49Smrgstatic GLfloat col[100][4]; 9532001f49Smrgstatic GLint numverts, num_tri_verts, numuniq; 9632001f49Smrg 9732001f49Smrgstatic GLfloat xrot; 9832001f49Smrgstatic GLfloat yrot; 9932001f49Smrgstatic GLfloat dist; 10032001f49Smrgstatic GLint state, allowed = ~0; 10132001f49Smrgstatic GLboolean doubleBuffer = GL_TRUE; 10232001f49Smrgstatic GLdouble plane[4]; 10332001f49Smrgstatic GLuint surf1, dlist_state; 10432001f49Smrg 10532001f49Smrgstatic GLboolean PrintInfo = GL_FALSE; 10632001f49Smrg 10732001f49Smrg 10832001f49Smrgstatic GLubyte halftone[] = { 10932001f49Smrg 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 11032001f49Smrg 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 11132001f49Smrg 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 11232001f49Smrg 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 11332001f49Smrg 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 11432001f49Smrg 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 11532001f49Smrg 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 11632001f49Smrg 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 11732001f49Smrg 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 11832001f49Smrg 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 11932001f49Smrg 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55}; 12032001f49Smrg 12132001f49Smrg 12232001f49Smrgstatic void read_surface( char *filename ) 12332001f49Smrg{ 12432001f49Smrg FILE *f; 12532001f49Smrg 12632001f49Smrg f = fopen(filename,"r"); 12732001f49Smrg if (!f) { 12832001f49Smrg printf("couldn't read %s\n", filename); 12932001f49Smrg exit(1); 13032001f49Smrg } 13132001f49Smrg 13232001f49Smrg numverts = 0; 13332001f49Smrg while (!feof(f) && numverts<maxverts) { 13432001f49Smrg int result; 13532001f49Smrg result = fscanf( f, "%f %f %f %f %f %f", 13632001f49Smrg &data[numverts][0], &data[numverts][1], &data[numverts][2], 13732001f49Smrg &data[numverts][3], &data[numverts][4], &data[numverts][5] ); 13832001f49Smrg (void) result; 13932001f49Smrg numverts++; 14032001f49Smrg } 14132001f49Smrg numverts--; 14232001f49Smrg 14332001f49Smrg printf("%d vertices, %d triangles\n", numverts, numverts-2); 14432001f49Smrg fclose(f); 14532001f49Smrg} 14632001f49Smrg 14732001f49Smrg 14832001f49Smrg 14932001f49Smrgstatic void print_flags( const char *msg, GLuint flags ) 15032001f49Smrg{ 15132001f49Smrg fprintf(stderr, 15232001f49Smrg "%s (0x%x): %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n", 15332001f49Smrg msg, flags, 15432001f49Smrg (flags & GLVERTEX) ? "glVertex, " : "", 15532001f49Smrg (flags & DRAW_ARRAYS) ? "glDrawArrays, " : "", 15632001f49Smrg (flags & DRAW_ELTS) ? "glDrawElements, " : "", 15732001f49Smrg (flags & ARRAY_ELT) ? "glArrayElement, " : "", 15832001f49Smrg (flags & LOCKED) ? "locked arrays, " : "", 15932001f49Smrg (flags & TRIANGLES) ? "GL_TRIANGLES, " : "", 16032001f49Smrg (flags & STRIPS) ? "GL_TRIANGLE_STRIP, " : "", 16132001f49Smrg (flags & POINTS) ? "GL_POINTS, " : "", 16232001f49Smrg (flags & DISPLAYLIST) ? "as a displaylist, " : "", 16332001f49Smrg (flags & LIT) ? "lit, " : "", 16432001f49Smrg (flags & UNLIT) ? "unlit, " : "", 16532001f49Smrg (flags & REFLECT) ? "reflect, " : "", 16632001f49Smrg (flags & SHADE_FLAT) ? "flat-shaded, " : "", 16732001f49Smrg (flags & USER_CLIP) ? "user_clip, " : "", 16832001f49Smrg (flags & MATERIALS) ? "materials, " : "", 16932001f49Smrg (flags & FOG) ? "fog, " : "", 17032001f49Smrg (flags & STIPPLE) ? "stipple, " : "", 17132001f49Smrg (flags & POLYGON_LINE) ? "polygon mode line, " : "", 17232001f49Smrg (flags & POLYGON_POINT) ? "polygon mode point, " : ""); 17332001f49Smrg} 17432001f49Smrg 17532001f49Smrg 17632001f49Smrg 17732001f49Smrgstruct data_idx { 17832001f49Smrg float *data; 17932001f49Smrg int idx; 18032001f49Smrg int uniq_idx; 18132001f49Smrg}; 18232001f49Smrg 18332001f49Smrg 18432001f49Smrg#define COMPARE_FUNC( AXIS ) \ 18532001f49Smrgstatic int compare_axis_##AXIS( const void *a, const void *b ) \ 18632001f49Smrg{ \ 18732001f49Smrg float t = ( (*(struct data_idx *)a).data[AXIS] - \ 18832001f49Smrg (*(struct data_idx *)b).data[AXIS] ); \ 18932001f49Smrg \ 19032001f49Smrg if (t < 0) return -1; \ 19132001f49Smrg if (t > 0) return 1; \ 19232001f49Smrg return 0; \ 19332001f49Smrg} 19432001f49Smrg 19532001f49SmrgCOMPARE_FUNC(0) 19632001f49SmrgCOMPARE_FUNC(1) 19732001f49SmrgCOMPARE_FUNC(2) 19832001f49SmrgCOMPARE_FUNC(3) 19932001f49SmrgCOMPARE_FUNC(4) 20032001f49SmrgCOMPARE_FUNC(5) 20132001f49SmrgCOMPARE_FUNC(6) 20232001f49Smrg 20332001f49Smrgint (*(compare[7]))( const void *a, const void *b ) = 20432001f49Smrg{ 20532001f49Smrg compare_axis_0, 20632001f49Smrg compare_axis_1, 20732001f49Smrg compare_axis_2, 20832001f49Smrg compare_axis_3, 20932001f49Smrg compare_axis_4, 21032001f49Smrg compare_axis_5, 21132001f49Smrg compare_axis_6, 21232001f49Smrg}; 21332001f49Smrg 21432001f49Smrg 21532001f49Smrg#define VEC_ELT(f, s, i) (float *)(((char *)f) + s * i) 21632001f49Smrg 21732001f49Smrgstatic int sort_axis( int axis, 21832001f49Smrg int vec_size, 21932001f49Smrg int vec_stride, 22032001f49Smrg struct data_idx *indices, 22132001f49Smrg int start, 22232001f49Smrg int finish, 22332001f49Smrg float *out, 22432001f49Smrg int uniq, 22532001f49Smrg const float fudge ) 22632001f49Smrg{ 22732001f49Smrg int i; 22832001f49Smrg 22932001f49Smrg if (finish-start > 2) 23032001f49Smrg { 23132001f49Smrg qsort( indices+start, finish-start, sizeof(*indices), compare[axis] ); 23232001f49Smrg } 23332001f49Smrg else if (indices[start].data[axis] > indices[start+1].data[axis]) 23432001f49Smrg { 23532001f49Smrg struct data_idx tmp = indices[start]; 23632001f49Smrg indices[start] = indices[start+1]; 23732001f49Smrg indices[start+1] = tmp; 23832001f49Smrg } 23932001f49Smrg 24032001f49Smrg if (axis == vec_size-1) { 24132001f49Smrg for (i = start ; i < finish ; ) { 24232001f49Smrg float max = indices[i].data[axis] + fudge; 24332001f49Smrg float *dest = VEC_ELT(out, vec_stride, uniq); 24432001f49Smrg int j; 24532001f49Smrg 24632001f49Smrg for (j = 0 ; j < vec_size ; j++) 24732001f49Smrg dest[j] = indices[i].data[j]; 24832001f49Smrg 24932001f49Smrg for ( ; i < finish && max >= indices[i].data[axis]; i++) 25032001f49Smrg indices[i].uniq_idx = uniq; 25132001f49Smrg 25232001f49Smrg uniq++; 25332001f49Smrg } 25432001f49Smrg } else { 25532001f49Smrg for (i = start ; i < finish ; ) { 25632001f49Smrg int j = i + 1; 25732001f49Smrg float max = indices[i].data[axis] + fudge; 25832001f49Smrg while (j < finish && max >= indices[j].data[axis]) j++; 25932001f49Smrg if (j == i+1) { 26032001f49Smrg float *dest = VEC_ELT(out, vec_stride, uniq); 26132001f49Smrg int k; 26232001f49Smrg 26332001f49Smrg indices[i].uniq_idx = uniq; 26432001f49Smrg 26532001f49Smrg for (k = 0 ; k < vec_size ; k++) 26632001f49Smrg dest[k] = indices[i].data[k]; 26732001f49Smrg 26832001f49Smrg uniq++; 26932001f49Smrg } else { 27032001f49Smrg uniq = sort_axis( axis+1, vec_size, vec_stride, 27132001f49Smrg indices, i, j, out, uniq, fudge ); 27232001f49Smrg } 27332001f49Smrg i = j; 27432001f49Smrg } 27532001f49Smrg } 27632001f49Smrg 27732001f49Smrg return uniq; 27832001f49Smrg} 27932001f49Smrg 28032001f49Smrg 28132001f49Smrgstatic void extract_indices1( const struct data_idx *in, unsigned int *out, 28232001f49Smrg int n ) 28332001f49Smrg{ 28432001f49Smrg int i; 28532001f49Smrg for ( i = 0 ; i < n ; i++ ) { 28632001f49Smrg out[in[i].idx] = in[i].uniq_idx; 28732001f49Smrg } 28832001f49Smrg} 28932001f49Smrg 29032001f49Smrg 29132001f49Smrgstatic void compactify_arrays(void) 29232001f49Smrg{ 29332001f49Smrg int i; 29432001f49Smrg struct data_idx *ind; 29532001f49Smrg 29632001f49Smrg ind = (struct data_idx *) malloc( sizeof(struct data_idx) * numverts ); 29732001f49Smrg 29832001f49Smrg for (i = 0 ; i < numverts ; i++) { 29932001f49Smrg ind[i].idx = i; 30032001f49Smrg ind[i].data = data[i]; 30132001f49Smrg } 30232001f49Smrg 30332001f49Smrg numuniq = sort_axis(0, 30432001f49Smrg sizeof(compressed_data[0])/sizeof(float), 30532001f49Smrg sizeof(compressed_data[0]), 30632001f49Smrg ind, 30732001f49Smrg 0, 30832001f49Smrg numverts, 30932001f49Smrg (float *)compressed_data, 31032001f49Smrg 0, 31132001f49Smrg 1e-6); 31232001f49Smrg 31332001f49Smrg printf("Nr unique vertex/normal pairs: %d\n", numuniq); 31432001f49Smrg 31532001f49Smrg extract_indices1( ind, indices, numverts ); 31632001f49Smrg free( ind ); 31732001f49Smrg} 31832001f49Smrg 31932001f49Smrgstatic void expand_arrays(void) 32032001f49Smrg{ 32132001f49Smrg int i; 32232001f49Smrg int parity = 0; 32332001f49Smrg for (i = 2 ; i < numverts ; i++, parity ^= 1) { 32432001f49Smrg int v0 = i-2+parity; 32532001f49Smrg int v1 = i-1-parity; 32632001f49Smrg int v2 = i; 32732001f49Smrg memcpy( expanded_data[(i-2)*3+0], data[v0], sizeof(data[0]) ); 32832001f49Smrg memcpy( expanded_data[(i-2)*3+1], data[v1], sizeof(data[0]) ); 32932001f49Smrg memcpy( expanded_data[(i-2)*3+2], data[v2], sizeof(data[0]) ); 33032001f49Smrg } 33132001f49Smrg} 33232001f49Smrg 33332001f49Smrgstatic float myrand( float max ) 33432001f49Smrg{ 33532001f49Smrg return max*rand()/(RAND_MAX+1.0); 33632001f49Smrg} 33732001f49Smrg 33832001f49Smrg 33932001f49Smrgstatic void make_tri_indices( void ) 34032001f49Smrg{ 34132001f49Smrg unsigned int *v = tri_indices; 34232001f49Smrg unsigned int parity = 0; 34332001f49Smrg int i, j; 34432001f49Smrg 34532001f49Smrg for (j=2;j<numverts;j++,parity^=1) { 34632001f49Smrg if (parity) { 34732001f49Smrg *v++ = indices[j-1]; 34832001f49Smrg *v++ = indices[j-2]; 34932001f49Smrg *v++ = indices[j]; 35032001f49Smrg } else { 35132001f49Smrg *v++ = indices[j-2]; 35232001f49Smrg *v++ = indices[j-1]; 35332001f49Smrg *v++ = indices[j]; 35432001f49Smrg } 35532001f49Smrg } 35632001f49Smrg 35732001f49Smrg num_tri_verts = v - tri_indices; 35832001f49Smrg printf("num_tri_verts: %d\n", num_tri_verts); 35932001f49Smrg 36032001f49Smrg for (i = j = 0 ; i < num_tri_verts ; i += 600, j++) { 36132001f49Smrg col[j][3] = 1; 36232001f49Smrg col[j][2] = myrand(1); 36332001f49Smrg col[j][1] = myrand(1); 36432001f49Smrg col[j][0] = myrand(1); 36532001f49Smrg } 36632001f49Smrg 36732001f49Smrg for (i = 0; i < numverts ; i++) 36832001f49Smrg strip_indices[i] = i; 36932001f49Smrg} 37032001f49Smrg 37132001f49Smrg#define MIN(x,y) (x < y) ? x : y 37232001f49Smrg 37332001f49Smrgstatic void draw_surface( unsigned int with_state ) 37432001f49Smrg{ 37532001f49Smrg GLint i, j; 37632001f49Smrg 37732001f49Smrg if (with_state & DISPLAYLIST) { 37832001f49Smrg if ((with_state & (RENDER_STYLE_MASK|PRIMITIVE_MASK|MATERIAL_MASK)) != 37932001f49Smrg dlist_state) { 38032001f49Smrg /* 38132001f49Smrg */ 38232001f49Smrg fprintf(stderr, "rebuilding displaylist\n"); 38332001f49Smrg 38432001f49Smrg if (dlist_state) 38532001f49Smrg glDeleteLists( surf1, 1 ); 38632001f49Smrg 38732001f49Smrg dlist_state = with_state & (RENDER_STYLE_MASK|PRIMITIVE_MASK| 38832001f49Smrg MATERIAL_MASK); 38932001f49Smrg surf1 = glGenLists(1); 39032001f49Smrg glNewList(surf1, GL_COMPILE); 39132001f49Smrg draw_surface( dlist_state ); 39232001f49Smrg glEndList(); 39332001f49Smrg } 39432001f49Smrg 39532001f49Smrg glCallList( surf1 ); 39632001f49Smrg return; 39732001f49Smrg } 39832001f49Smrg 39932001f49Smrg switch (with_state & (RENDER_STYLE_MASK|PRIMITIVE_MASK)) { 40032001f49Smrg 40132001f49Smrg case (DRAW_ELTS|TRIANGLES): 40232001f49Smrg if (with_state & MATERIALS) { 40332001f49Smrg for (j = i = 0 ; i < num_tri_verts ; i += 600, j++) { 40432001f49Smrg GLuint nr = MIN(num_tri_verts-i, 600); 40532001f49Smrg glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, col[j]); 40632001f49Smrg glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, col[j]); 40732001f49Smrg glDrawElements( GL_TRIANGLES, nr, GL_UNSIGNED_INT, tri_indices+i ); 40832001f49Smrg } 40932001f49Smrg } else { 41032001f49Smrg glDrawElements( GL_TRIANGLES, num_tri_verts, GL_UNSIGNED_INT, 41132001f49Smrg tri_indices ); 41232001f49Smrg } 41332001f49Smrg break; 41432001f49Smrg 41532001f49Smrg case (DRAW_ARRAYS|TRIANGLES): 41632001f49Smrg glDrawArrays( GL_TRIANGLES, 0, (numverts-2)*3 ); 41732001f49Smrg break; 41832001f49Smrg 41932001f49Smrg case (ARRAY_ELT|TRIANGLES): 42032001f49Smrg if (with_state & MATERIALS) { 42132001f49Smrg for (j = i = 0 ; i < num_tri_verts ; i += 600, j++) { 42232001f49Smrg GLuint nr = MIN(num_tri_verts-i, 600); 42332001f49Smrg GLuint k; 42432001f49Smrg glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, col[j]); 42532001f49Smrg glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, col[j]); 42632001f49Smrg glBegin( GL_TRIANGLES ); 42732001f49Smrg for (k = 0 ; k < nr ; k++) 42832001f49Smrg glArrayElement( tri_indices[i+k] ); 42932001f49Smrg glEnd(); 43032001f49Smrg } 43132001f49Smrg } else { 43232001f49Smrg glBegin( GL_TRIANGLES ); 43332001f49Smrg for (i = 0 ; i < num_tri_verts ; i++) 43432001f49Smrg glArrayElement( tri_indices[i] ); 43532001f49Smrg 43632001f49Smrg glEnd(); 43732001f49Smrg } 43832001f49Smrg break; 43932001f49Smrg 44032001f49Smrg 44132001f49Smrg /* Uses the original arrays (including duplicate elements): 44232001f49Smrg */ 44332001f49Smrg case (DRAW_ARRAYS|STRIPS): 44432001f49Smrg glDrawArrays( GL_TRIANGLE_STRIP, 0, numverts ); 44532001f49Smrg break; 44632001f49Smrg case (DRAW_ELTS|STRIPS): 44732001f49Smrg glDrawElements( GL_TRIANGLE_STRIP, numverts, 44832001f49Smrg GL_UNSIGNED_INT, strip_indices ); 44932001f49Smrg break; 45032001f49Smrg 45132001f49Smrg /* Uses the original arrays (including duplicate elements): 45232001f49Smrg */ 45332001f49Smrg case (ARRAY_ELT|STRIPS): 45432001f49Smrg glBegin( GL_TRIANGLE_STRIP ); 45532001f49Smrg for (i = 0 ; i < numverts ; i++) 45632001f49Smrg glArrayElement( i ); 45732001f49Smrg glEnd(); 45832001f49Smrg break; 45932001f49Smrg 46032001f49Smrg case (DRAW_ARRAYS|POINTS): 46132001f49Smrg glDrawArrays( GL_POINTS, 0, numuniq ); 46232001f49Smrg break; 46332001f49Smrg case (DRAW_ELTS|POINTS): 46432001f49Smrg /* can use numuniq with strip_indices as strip_indices[i] == i. 46532001f49Smrg */ 46632001f49Smrg glDrawElements( GL_POINTS, numuniq, 46732001f49Smrg GL_UNSIGNED_INT, strip_indices ); 46832001f49Smrg break; 46932001f49Smrg case (ARRAY_ELT|POINTS): 47032001f49Smrg /* just emit each unique element once: 47132001f49Smrg */ 47232001f49Smrg glBegin( GL_POINTS ); 47332001f49Smrg for (i = 0 ; i < numuniq ; i++) 47432001f49Smrg glArrayElement( i ); 47532001f49Smrg glEnd(); 47632001f49Smrg break; 47732001f49Smrg 47832001f49Smrg case (GLVERTEX|TRIANGLES): 47932001f49Smrg if (with_state & MATERIALS) { 48032001f49Smrg for (j = i = 0 ; i < num_tri_verts ; i += 600, j++) { 48132001f49Smrg GLuint nr = MIN(num_tri_verts-i, 600); 48232001f49Smrg GLuint k; 48332001f49Smrg glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, col[j]); 48432001f49Smrg glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, col[j]); 48532001f49Smrg glBegin( GL_TRIANGLES ); 48632001f49Smrg for (k = 0 ; k < nr ; k++) { 48732001f49Smrg glNormal3fv( &compressed_data[tri_indices[i+k]][3] ); 48832001f49Smrg glVertex3fv( &compressed_data[tri_indices[i+k]][0] ); 48932001f49Smrg } 49032001f49Smrg glEnd(); 49132001f49Smrg } 49232001f49Smrg } else { 49332001f49Smrg glBegin( GL_TRIANGLES ); 49432001f49Smrg for (i = 0 ; i < num_tri_verts ; i++) { 49532001f49Smrg glNormal3fv( &compressed_data[tri_indices[i]][3] ); 49632001f49Smrg glVertex3fv( &compressed_data[tri_indices[i]][0] ); 49732001f49Smrg } 49832001f49Smrg glEnd(); 49932001f49Smrg } 50032001f49Smrg break; 50132001f49Smrg 50232001f49Smrg case (GLVERTEX|POINTS): 50332001f49Smrg /* Renders all points, but not in strip order... Shouldn't be a 50432001f49Smrg * problem, but people may be confused as to why points are so 50532001f49Smrg * much faster in this demo... And why cva doesn't help them... 50632001f49Smrg */ 50732001f49Smrg glBegin( GL_POINTS ); 50832001f49Smrg for ( i = 0 ; i < numuniq ; i++ ) { 50932001f49Smrg glNormal3fv( &compressed_data[i][3] ); 51032001f49Smrg glVertex3fv( &compressed_data[i][0] ); 51132001f49Smrg } 51232001f49Smrg glEnd(); 51332001f49Smrg break; 51432001f49Smrg 51532001f49Smrg case (GLVERTEX|STRIPS): 51632001f49Smrg if (with_state & MATERIALS) { 51732001f49Smrg glBegin( GL_TRIANGLE_STRIP ); 51832001f49Smrg for (i=0;i<numverts;i++) { 51932001f49Smrg if (i % 600 == 0 && i != 0) { 52032001f49Smrg unsigned j = i / 600; 52132001f49Smrg glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, col[j]); 52232001f49Smrg glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, col[j]); 52332001f49Smrg } 52432001f49Smrg glNormal3fv( &data[i][3] ); 52532001f49Smrg glVertex3fv( &data[i][0] ); 52632001f49Smrg } 52732001f49Smrg glEnd(); 52832001f49Smrg } 52932001f49Smrg else { 53032001f49Smrg glBegin( GL_TRIANGLE_STRIP ); 53132001f49Smrg for (i=0;i<numverts;i++) { 53232001f49Smrg glNormal3fv( &data[i][3] ); 53332001f49Smrg glVertex3fv( &data[i][0] ); 53432001f49Smrg } 53532001f49Smrg glEnd(); 53632001f49Smrg } 53732001f49Smrg break; 53832001f49Smrg 53932001f49Smrg default: 54032001f49Smrg fprintf(stderr, "unimplemented mode %x...\n", 54132001f49Smrg (with_state & (RENDER_STYLE_MASK|PRIMITIVE_MASK))); 54232001f49Smrg break; 54332001f49Smrg } 54432001f49Smrg} 54532001f49Smrg 54632001f49Smrg 54732001f49Smrg 54832001f49Smrgstatic void Display(void) 54932001f49Smrg{ 55032001f49Smrg glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); 55132001f49Smrg draw_surface( state ); 55232001f49Smrg glFlush(); 55332001f49Smrg if (doubleBuffer) glutSwapBuffers(); 55432001f49Smrg} 55532001f49Smrg 55632001f49Smrg 55732001f49Smrg/* KW: only do this when necessary, so CVA can re-use results. 55832001f49Smrg */ 55932001f49Smrgstatic void set_matrix( void ) 56032001f49Smrg{ 56132001f49Smrg glMatrixMode(GL_MODELVIEW); 56232001f49Smrg glLoadIdentity(); 56332001f49Smrg glTranslatef( 0.0, 0.0, dist ); 56432001f49Smrg glRotatef( yrot, 0.0, 1.0, 0.0 ); 56532001f49Smrg glRotatef( xrot, 1.0, 0.0, 0.0 ); 56632001f49Smrg} 56732001f49Smrg 56832001f49Smrgstatic void Benchmark( float xdiff, float ydiff ) 56932001f49Smrg{ 57032001f49Smrg int startTime, endTime; 57132001f49Smrg int draws; 57232001f49Smrg double seconds, fps, triPerSecond; 57332001f49Smrg 57432001f49Smrg printf("Benchmarking...\n"); 57532001f49Smrg 57632001f49Smrg draws = 0; 57732001f49Smrg startTime = glutGet(GLUT_ELAPSED_TIME); 57832001f49Smrg xrot = 0.0; 57932001f49Smrg do { 58032001f49Smrg xrot += xdiff; 58132001f49Smrg yrot += ydiff; 58232001f49Smrg set_matrix(); 58332001f49Smrg Display(); 58432001f49Smrg draws++; 58532001f49Smrg endTime = glutGet(GLUT_ELAPSED_TIME); 58632001f49Smrg } while (endTime - startTime < 5000); /* 5 seconds */ 58732001f49Smrg 58832001f49Smrg /* Results */ 58932001f49Smrg seconds = (double) (endTime - startTime) / 1000.0; 59032001f49Smrg triPerSecond = (numverts - 2) * draws / seconds; 59132001f49Smrg fps = draws / seconds; 59232001f49Smrg printf("Result: triangles/sec: %g fps: %g\n", triPerSecond, fps); 59332001f49Smrg} 59432001f49Smrg 59532001f49Smrg 59632001f49Smrgstatic void InitMaterials(void) 59732001f49Smrg{ 59832001f49Smrg static float ambient[] = {0.1, 0.1, 0.1, 1.0}; 59932001f49Smrg static float diffuse[] = {0.5, 1.0, 1.0, 1.0}; 60032001f49Smrg static float position0[] = {0.0, 0.0, 20.0, 0.0}; 60132001f49Smrg static float position1[] = {0.0, 0.0, -20.0, 0.0}; 60232001f49Smrg static float front_mat_shininess[] = {60.0}; 60332001f49Smrg static float front_mat_specular[] = {0.2, 0.2, 0.2, 1.0}; 60432001f49Smrg static float front_mat_diffuse[] = {0.5, 0.28, 0.38, 1.0}; 60532001f49Smrg /* 60632001f49Smrg static float back_mat_shininess[] = {60.0}; 60732001f49Smrg static float back_mat_specular[] = {0.5, 0.5, 0.2, 1.0}; 60832001f49Smrg static float back_mat_diffuse[] = {1.0, 1.0, 0.2, 1.0}; 60932001f49Smrg */ 61032001f49Smrg static float lmodel_ambient[] = {1.0, 1.0, 1.0, 1.0}; 61132001f49Smrg static float lmodel_twoside[] = {GL_FALSE}; 61232001f49Smrg 61332001f49Smrg glLightfv(GL_LIGHT0, GL_AMBIENT, ambient); 61432001f49Smrg glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse); 61532001f49Smrg glLightfv(GL_LIGHT0, GL_POSITION, position0); 61632001f49Smrg glEnable(GL_LIGHT0); 61732001f49Smrg 61832001f49Smrg glLightfv(GL_LIGHT1, GL_AMBIENT, ambient); 61932001f49Smrg glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse); 62032001f49Smrg glLightfv(GL_LIGHT1, GL_POSITION, position1); 62132001f49Smrg glEnable(GL_LIGHT1); 62232001f49Smrg 62332001f49Smrg glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient); 62432001f49Smrg glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE, lmodel_twoside); 62532001f49Smrg 62632001f49Smrg glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, front_mat_shininess); 62732001f49Smrg glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, front_mat_specular); 62832001f49Smrg glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, front_mat_diffuse); 62932001f49Smrg 63032001f49Smrg glPolygonStipple (halftone); 63132001f49Smrg} 63232001f49Smrg 63332001f49Smrg 63432001f49Smrg 63532001f49Smrg#define UPDATE(o,n,mask) (o&=~mask, o|=n&mask) 63632001f49Smrg#define CHANGED(o,n,mask) ((n&mask) && (n&mask) != (o&mask) ) 63732001f49Smrg 63832001f49Smrgstatic void ModeMenu(int m) 63932001f49Smrg{ 64032001f49Smrg m &= allowed; 64132001f49Smrg 64232001f49Smrg if (!m) return; 64332001f49Smrg 64432001f49Smrg if (m==QUIT) 64532001f49Smrg exit(0); 64632001f49Smrg 64732001f49Smrg if (m==GLINFO) { 64832001f49Smrg printf("GL_VERSION: %s\n", (char *) glGetString(GL_VERSION)); 64932001f49Smrg printf("GL_EXTENSIONS: %s\n", (char *) glGetString(GL_EXTENSIONS)); 65032001f49Smrg printf("GL_RENDERER: %s\n", (char *) glGetString(GL_RENDERER)); 65132001f49Smrg return; 65232001f49Smrg } 65332001f49Smrg 65432001f49Smrg if (CHANGED(state, m, FILTER_MASK)) { 65532001f49Smrg UPDATE(state, m, FILTER_MASK); 65632001f49Smrg if (m & LINEAR_FILTER) { 65732001f49Smrg glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 65832001f49Smrg glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 65932001f49Smrg } else { 66032001f49Smrg glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 66132001f49Smrg glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 66232001f49Smrg } 66332001f49Smrg } 66432001f49Smrg 66532001f49Smrg if (CHANGED(state, m, LIGHT_MASK)) { 66632001f49Smrg UPDATE(state, m, LIGHT_MASK); 66732001f49Smrg if (m & LIT) { 66832001f49Smrg glEnable(GL_LIGHTING); 66932001f49Smrg glDisable(GL_TEXTURE_GEN_S); 67032001f49Smrg glDisable(GL_TEXTURE_GEN_T); 67132001f49Smrg glDisable(GL_TEXTURE_2D); 67232001f49Smrg } 67332001f49Smrg else if (m & UNLIT) { 67432001f49Smrg glDisable(GL_LIGHTING); 67532001f49Smrg glDisable(GL_TEXTURE_GEN_S); 67632001f49Smrg glDisable(GL_TEXTURE_GEN_T); 67732001f49Smrg glDisable(GL_TEXTURE_2D); 67832001f49Smrg } 67932001f49Smrg else if (m & REFLECT) { 68032001f49Smrg glDisable(GL_LIGHTING); 68132001f49Smrg glEnable(GL_TEXTURE_GEN_S); 68232001f49Smrg glEnable(GL_TEXTURE_GEN_T); 68332001f49Smrg glEnable(GL_TEXTURE_2D); 68432001f49Smrg } 68532001f49Smrg } 68632001f49Smrg 68732001f49Smrg if (CHANGED(state, m, SHADE_MASK)) { 68832001f49Smrg UPDATE(state, m, SHADE_MASK); 68932001f49Smrg if (m & SHADE_SMOOTH) 69032001f49Smrg glShadeModel(GL_SMOOTH); 69132001f49Smrg else 69232001f49Smrg glShadeModel(GL_FLAT); 69332001f49Smrg } 69432001f49Smrg 69532001f49Smrg 69632001f49Smrg if (CHANGED(state, m, CLIP_MASK)) { 69732001f49Smrg UPDATE(state, m, CLIP_MASK); 69832001f49Smrg if (m & USER_CLIP) { 69932001f49Smrg glEnable(GL_CLIP_PLANE0); 70032001f49Smrg } else { 70132001f49Smrg glDisable(GL_CLIP_PLANE0); 70232001f49Smrg } 70332001f49Smrg } 70432001f49Smrg 70532001f49Smrg if (CHANGED(state, m, FOG_MASK)) { 70632001f49Smrg UPDATE(state, m, FOG_MASK); 70732001f49Smrg if (m & FOG) { 70832001f49Smrg glEnable(GL_FOG); 70932001f49Smrg } 71032001f49Smrg else { 71132001f49Smrg glDisable(GL_FOG); 71232001f49Smrg } 71332001f49Smrg } 71432001f49Smrg 71532001f49Smrg if (CHANGED(state, m, STIPPLE_MASK)) { 71632001f49Smrg UPDATE(state, m, STIPPLE_MASK); 71732001f49Smrg if (m & STIPPLE) { 71832001f49Smrg glEnable(GL_POLYGON_STIPPLE); 71932001f49Smrg } 72032001f49Smrg else { 72132001f49Smrg glDisable(GL_POLYGON_STIPPLE); 72232001f49Smrg } 72332001f49Smrg } 72432001f49Smrg 72532001f49Smrg if (CHANGED(state, m, POLYGON_MASK)) { 72632001f49Smrg UPDATE(state, m, POLYGON_MASK); 72732001f49Smrg if (m & POLYGON_FILL) { 72832001f49Smrg glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); 72932001f49Smrg } 73032001f49Smrg else if (m & POLYGON_LINE) { 73132001f49Smrg glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); 73232001f49Smrg } 73332001f49Smrg else { 73432001f49Smrg glPolygonMode(GL_FRONT_AND_BACK, GL_POINT); 73532001f49Smrg } 73632001f49Smrg } 73732001f49Smrg 73832001f49Smrg if (CHANGED(state, m, (LOCK_MASK|RENDER_STYLE_MASK|PRIMITIVE_MASK))) 73932001f49Smrg { 74032001f49Smrg if (m & (PRIMITIVE_MASK)) { 74132001f49Smrg UPDATE(state, m, (PRIMITIVE_MASK)); 74232001f49Smrg } 74332001f49Smrg 74432001f49Smrg if (m & (RENDER_STYLE_MASK)) { 74532001f49Smrg UPDATE(state, m, (RENDER_STYLE_MASK)); 74632001f49Smrg } 74732001f49Smrg 74832001f49Smrg if (m & LOCK_MASK) { 74932001f49Smrg UPDATE(state, m, (LOCK_MASK)); 75032001f49Smrg } 75132001f49Smrg 75232001f49Smrg 75332001f49Smrg print_flags("primitive", state & PRIMITIVE_MASK); 75432001f49Smrg print_flags("render style", state & RENDER_STYLE_MASK); 75532001f49Smrg 75632001f49Smrg if ((state & PRIMITIVE_MASK) != STRIPS && 75732001f49Smrg ((state & RENDER_STYLE_MASK) == DRAW_ELTS || 75832001f49Smrg (state & RENDER_STYLE_MASK) == ARRAY_ELT || 75932001f49Smrg (state & PRIMITIVE_MASK) == POINTS)) 76032001f49Smrg { 76132001f49Smrg fprintf(stderr, "enabling small arrays\n"); 76232001f49Smrg /* Rendering any primitive with draw-element/array-element 76332001f49Smrg * --> Can't do strips here as ordering has been lost in 76432001f49Smrg * compaction process... 76532001f49Smrg */ 76632001f49Smrg glVertexPointer( 3, GL_FLOAT, sizeof(data[0]), compressed_data ); 76732001f49Smrg glNormalPointer( GL_FLOAT, sizeof(data[0]), &compressed_data[0][3] ); 76832001f49Smrg#ifdef GL_EXT_compiled_vertex_array 76932001f49Smrg if (allowed & LOCKED) { 77032001f49Smrg if (state & LOCKED) { 77132001f49Smrg glLockArraysEXT( 0, numuniq ); 77232001f49Smrg } else { 77332001f49Smrg glUnlockArraysEXT(); 77432001f49Smrg } 77532001f49Smrg } 77632001f49Smrg#endif 77732001f49Smrg } 77832001f49Smrg else if ((state & PRIMITIVE_MASK) == TRIANGLES && 77932001f49Smrg (state & RENDER_STYLE_MASK) == DRAW_ARRAYS) { 78032001f49Smrg fprintf(stderr, "enabling big arrays\n"); 78132001f49Smrg /* Only get here for TRIANGLES and drawarrays 78232001f49Smrg */ 78332001f49Smrg glVertexPointer( 3, GL_FLOAT, sizeof(data[0]), expanded_data ); 78432001f49Smrg glNormalPointer( GL_FLOAT, sizeof(data[0]), &expanded_data[0][3] ); 78532001f49Smrg 78632001f49Smrg#ifdef GL_EXT_compiled_vertex_array 78732001f49Smrg if (allowed & LOCKED) { 78832001f49Smrg if (state & LOCKED) { 78932001f49Smrg glLockArraysEXT( 0, (numverts-2)*3 ); 79032001f49Smrg } else { 79132001f49Smrg glUnlockArraysEXT(); 79232001f49Smrg } 79332001f49Smrg } 79432001f49Smrg#endif 79532001f49Smrg } 79632001f49Smrg else { 79732001f49Smrg fprintf(stderr, "enabling normal arrays\n"); 79832001f49Smrg glVertexPointer( 3, GL_FLOAT, sizeof(data[0]), data ); 79932001f49Smrg glNormalPointer( GL_FLOAT, sizeof(data[0]), &data[0][3] ); 80032001f49Smrg#ifdef GL_EXT_compiled_vertex_array 80132001f49Smrg if (allowed & LOCKED) { 80232001f49Smrg if (state & LOCKED) { 80332001f49Smrg glLockArraysEXT( 0, numverts ); 80432001f49Smrg } else { 80532001f49Smrg glUnlockArraysEXT(); 80632001f49Smrg } 80732001f49Smrg } 80832001f49Smrg#endif 80932001f49Smrg } 81032001f49Smrg 81132001f49Smrg } 81232001f49Smrg 81332001f49Smrg 81432001f49Smrg if (m & DLIST_MASK) { 81532001f49Smrg UPDATE(state, m, DLIST_MASK); 81632001f49Smrg } 81732001f49Smrg 81832001f49Smrg if (m & MATERIAL_MASK) { 81932001f49Smrg UPDATE(state, m, MATERIAL_MASK); 82032001f49Smrg } 82132001f49Smrg 82232001f49Smrg print_flags("new flags", state); 82332001f49Smrg 82432001f49Smrg glutPostRedisplay(); 82532001f49Smrg} 82632001f49Smrg 82732001f49Smrg 82832001f49Smrg 82932001f49Smrgstatic void Init(int argc, char *argv[]) 83032001f49Smrg{ 83132001f49Smrg GLfloat fogColor[4] = {0.5,1.0,0.5,1.0}; 83232001f49Smrg 83332001f49Smrg xrot = 0; 83432001f49Smrg yrot = 0; 83532001f49Smrg dist = -6; 83632001f49Smrg plane[0] = 1.0; 83732001f49Smrg plane[1] = 0.0; 83832001f49Smrg plane[2] = -1.0; 83932001f49Smrg plane[3] = 0.0; 84032001f49Smrg 84132001f49Smrg glClearColor(0.0, 0.0, 1.0, 0.0); 84232001f49Smrg glEnable( GL_DEPTH_TEST ); 84332001f49Smrg glEnableClientState( GL_VERTEX_ARRAY ); 84432001f49Smrg glEnableClientState( GL_NORMAL_ARRAY ); 84532001f49Smrg 84632001f49Smrg glMatrixMode(GL_PROJECTION); 84732001f49Smrg glLoadIdentity(); 84832001f49Smrg glFrustum( -1.0, 1.0, -1.0, 1.0, 5, 25 ); 84932001f49Smrg 85032001f49Smrg glMatrixMode(GL_MODELVIEW); 85132001f49Smrg glLoadIdentity(); 85232001f49Smrg glClipPlane(GL_CLIP_PLANE0, plane); 85332001f49Smrg 85432001f49Smrg InitMaterials(); 85532001f49Smrg 85632001f49Smrg set_matrix(); 85732001f49Smrg 85832001f49Smrg glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 85932001f49Smrg glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST); 86032001f49Smrg 86132001f49Smrg glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); 86232001f49Smrg glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); 86332001f49Smrg 86432001f49Smrg 86532001f49Smrg /* Green fog is easy to see */ 86632001f49Smrg glFogi(GL_FOG_MODE,GL_EXP2); 86732001f49Smrg glFogfv(GL_FOG_COLOR,fogColor); 86832001f49Smrg glFogf(GL_FOG_DENSITY,0.15); 86932001f49Smrg glHint(GL_FOG_HINT,GL_DONT_CARE); 87032001f49Smrg 87132001f49Smrg { 87232001f49Smrg static int firsttime = 1; 87332001f49Smrg if (firsttime) { 87432001f49Smrg firsttime = 0; 87532001f49Smrg compactify_arrays(); 87632001f49Smrg expand_arrays(); 87732001f49Smrg make_tri_indices(); 87832001f49Smrg 87932001f49Smrg if (!LoadRGBMipmaps(TEXTURE_FILE, GL_RGB)) { 88032001f49Smrg printf("Error: couldn't load texture image\n"); 88132001f49Smrg exit(1); 88232001f49Smrg } 88332001f49Smrg } 88432001f49Smrg } 88532001f49Smrg 88632001f49Smrg ModeMenu(SHADE_SMOOTH| 88732001f49Smrg LIT| 88832001f49Smrg POINT_FILTER| 88932001f49Smrg NO_USER_CLIP| 89032001f49Smrg NO_MATERIALS| 89132001f49Smrg NO_FOG| 89232001f49Smrg NO_STIPPLE| 89332001f49Smrg IMMEDIATE| 89432001f49Smrg STRIPS| 89532001f49Smrg UNLOCKED| 89632001f49Smrg GLVERTEX); 89732001f49Smrg 89832001f49Smrg if (PrintInfo) { 89932001f49Smrg printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); 90032001f49Smrg printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION)); 90132001f49Smrg printf("GL_VENDOR = %s\n", (char *) glGetString(GL_VENDOR)); 90232001f49Smrg printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS)); 90332001f49Smrg } 90432001f49Smrg} 90532001f49Smrg 90632001f49Smrg 90732001f49Smrg 90832001f49Smrgstatic void Reshape(int width, int height) 90932001f49Smrg{ 91032001f49Smrg glViewport(0, 0, (GLint)width, (GLint)height); 91132001f49Smrg} 91232001f49Smrg 91332001f49Smrg 91432001f49Smrg 91532001f49Smrgstatic void Key( unsigned char key, int x, int y ) 91632001f49Smrg{ 91732001f49Smrg (void) x; 91832001f49Smrg (void) y; 91932001f49Smrg switch (key) { 92032001f49Smrg case 27: 92132001f49Smrg exit(0); 92232001f49Smrg case 'f': 92332001f49Smrg ModeMenu((state ^ FOG_MASK) & FOG_MASK); 92432001f49Smrg break; 92532001f49Smrg case 's': 92632001f49Smrg ModeMenu((state ^ SHADE_MASK) & SHADE_MASK); 92732001f49Smrg break; 92832001f49Smrg case 't': 92932001f49Smrg ModeMenu((state ^ STIPPLE_MASK) & STIPPLE_MASK); 93032001f49Smrg break; 93132001f49Smrg case 'l': 93232001f49Smrg ModeMenu((state ^ LIGHT_MASK) & (LIT|UNLIT)); 93332001f49Smrg break; 93432001f49Smrg case 'm': 93532001f49Smrg ModeMenu((state ^ MATERIAL_MASK) & MATERIAL_MASK); 93632001f49Smrg break; 93732001f49Smrg case 'c': 93832001f49Smrg ModeMenu((state ^ CLIP_MASK) & CLIP_MASK); 93932001f49Smrg break; 94032001f49Smrg case 'v': 94132001f49Smrg ModeMenu((LOCKED|IMMEDIATE|DRAW_ELTS|TRIANGLES) & allowed); 94232001f49Smrg break; 94332001f49Smrg case 'V': 94432001f49Smrg ModeMenu(UNLOCKED|IMMEDIATE|GLVERTEX|STRIPS); 94532001f49Smrg break; 94632001f49Smrg case 'b': 94732001f49Smrg Benchmark(5.0, 0); 94832001f49Smrg break; 94932001f49Smrg case 'B': 95032001f49Smrg Benchmark(0, 5.0); 95132001f49Smrg break; 95232001f49Smrg case 'i': 95332001f49Smrg dist += .25; 95432001f49Smrg set_matrix(); 95532001f49Smrg glutPostRedisplay(); 95632001f49Smrg break; 95732001f49Smrg case 'I': 95832001f49Smrg dist -= .25; 95932001f49Smrg set_matrix(); 96032001f49Smrg glutPostRedisplay(); 96132001f49Smrg break; 96232001f49Smrg case '-': 96332001f49Smrg case '_': 96432001f49Smrg plane[3] += 0.5; 96532001f49Smrg glMatrixMode(GL_MODELVIEW); 96632001f49Smrg glLoadIdentity(); 96732001f49Smrg glClipPlane(GL_CLIP_PLANE0, plane); 96832001f49Smrg set_matrix(); 96932001f49Smrg glutPostRedisplay(); 97032001f49Smrg break; 97132001f49Smrg case '+': 97232001f49Smrg case '=': 97332001f49Smrg plane[3] -= 0.5; 97432001f49Smrg glMatrixMode(GL_MODELVIEW); 97532001f49Smrg glLoadIdentity(); 97632001f49Smrg glClipPlane(GL_CLIP_PLANE0, plane); 97732001f49Smrg set_matrix(); 97832001f49Smrg glutPostRedisplay(); 97932001f49Smrg break; 98032001f49Smrg case ' ': 98132001f49Smrg Init(0,0); 98232001f49Smrg break; 98332001f49Smrg } 98432001f49Smrg} 98532001f49Smrg 98632001f49Smrg 98732001f49Smrgstatic void SpecialKey( int key, int x, int y ) 98832001f49Smrg{ 98932001f49Smrg (void) x; 99032001f49Smrg (void) y; 99132001f49Smrg switch (key) { 99232001f49Smrg case GLUT_KEY_LEFT: 99332001f49Smrg yrot -= 15.0; 99432001f49Smrg break; 99532001f49Smrg case GLUT_KEY_RIGHT: 99632001f49Smrg yrot += 15.0; 99732001f49Smrg break; 99832001f49Smrg case GLUT_KEY_UP: 99932001f49Smrg xrot += 15.0; 100032001f49Smrg break; 100132001f49Smrg case GLUT_KEY_DOWN: 100232001f49Smrg xrot -= 15.0; 100332001f49Smrg break; 100432001f49Smrg default: 100532001f49Smrg return; 100632001f49Smrg } 100732001f49Smrg set_matrix(); 100832001f49Smrg glutPostRedisplay(); 100932001f49Smrg} 101032001f49Smrg 101132001f49Smrg 101232001f49Smrg 101332001f49Smrgstatic GLint Args(int argc, char **argv) 101432001f49Smrg{ 101532001f49Smrg GLint i; 101632001f49Smrg GLint mode = 0; 101732001f49Smrg 101832001f49Smrg for (i = 1; i < argc; i++) { 101932001f49Smrg if (strcmp(argv[i], "-sb") == 0) { 102032001f49Smrg doubleBuffer = GL_FALSE; 102132001f49Smrg } 102232001f49Smrg else if (strcmp(argv[i], "-db") == 0) { 102332001f49Smrg doubleBuffer = GL_TRUE; 102432001f49Smrg } 102532001f49Smrg else if (strcmp(argv[i], "-info") == 0) { 102632001f49Smrg PrintInfo = GL_TRUE; 102732001f49Smrg } 102832001f49Smrg else if (strcmp(argv[i], "-10") == 0) { 102932001f49Smrg maxverts = 10; 103032001f49Smrg } 103132001f49Smrg else if (strcmp(argv[i], "-100") == 0) { 103232001f49Smrg maxverts = 100; 103332001f49Smrg } 103432001f49Smrg else if (strcmp(argv[i], "-1000") == 0) { 103532001f49Smrg maxverts = 1000; 103632001f49Smrg } 103732001f49Smrg else { 103832001f49Smrg printf("%s (Bad option).\n", argv[i]); 103932001f49Smrg return QUIT; 104032001f49Smrg } 104132001f49Smrg } 104232001f49Smrg 104332001f49Smrg return mode; 104432001f49Smrg} 104532001f49Smrg 104632001f49Smrgint main(int argc, char **argv) 104732001f49Smrg{ 104832001f49Smrg GLenum type; 104932001f49Smrg 105032001f49Smrg GLuint arg_mode = Args(argc, argv); 105132001f49Smrg 105232001f49Smrg if (arg_mode & QUIT) 105332001f49Smrg exit(0); 105432001f49Smrg 105532001f49Smrg read_surface(DEMOS_DATA_DIR "isosurf.dat"); 105632001f49Smrg 105732001f49Smrg glutInitWindowSize(400, 400); 105832001f49Smrg glutInit( &argc, argv); 105932001f49Smrg 106032001f49Smrg type = GLUT_DEPTH; 106132001f49Smrg type |= GLUT_RGB; 106232001f49Smrg type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE; 106332001f49Smrg glutInitDisplayMode(type); 106432001f49Smrg 106532001f49Smrg if (glutCreateWindow("Isosurface") <= 0) { 106632001f49Smrg exit(0); 106732001f49Smrg } 106832001f49Smrg 106932001f49Smrg glewInit(); 107032001f49Smrg 107132001f49Smrg /* Make sure server supports vertex arrays */ 107232001f49Smrg if (!GLEW_VERSION_1_1) 107332001f49Smrg { 107432001f49Smrg printf("Vertex arrays not supported by this renderer\n"); 107532001f49Smrg allowed &= ~(LOCKED|DRAW_ARRAYS|DRAW_ELTS|ARRAY_ELT); 107632001f49Smrg } 107732001f49Smrg else if (!GLEW_EXT_compiled_vertex_array) 107832001f49Smrg { 107932001f49Smrg printf("Compiled vertex arrays not supported by this renderer\n"); 108032001f49Smrg allowed &= ~LOCKED; 108132001f49Smrg } 108232001f49Smrg 108332001f49Smrg Init(argc, argv); 108432001f49Smrg ModeMenu(arg_mode); 108532001f49Smrg 108632001f49Smrg glutCreateMenu(ModeMenu); 108732001f49Smrg glutAddMenuEntry("GL info", GLINFO); 108832001f49Smrg glutAddMenuEntry("", 0); 108932001f49Smrg glutAddMenuEntry("Lit", LIT); 109032001f49Smrg glutAddMenuEntry("Unlit", UNLIT); 109132001f49Smrg glutAddMenuEntry("Reflect", REFLECT); 109232001f49Smrg glutAddMenuEntry("", 0); 109332001f49Smrg glutAddMenuEntry("Smooth", SHADE_SMOOTH); 109432001f49Smrg glutAddMenuEntry("Flat", SHADE_FLAT); 109532001f49Smrg glutAddMenuEntry("", 0); 109632001f49Smrg glutAddMenuEntry("Fog", FOG); 109732001f49Smrg glutAddMenuEntry("No Fog", NO_FOG); 109832001f49Smrg glutAddMenuEntry("", 0); 109932001f49Smrg glutAddMenuEntry("Stipple", STIPPLE); 110032001f49Smrg glutAddMenuEntry("No Stipple", NO_STIPPLE); 110132001f49Smrg glutAddMenuEntry("", 0); 110232001f49Smrg glutAddMenuEntry("Polygon Mode Fill", POLYGON_FILL); 110332001f49Smrg glutAddMenuEntry("Polygon Mode Line", POLYGON_LINE); 110432001f49Smrg glutAddMenuEntry("Polygon Mode Points", POLYGON_POINT); 110532001f49Smrg glutAddMenuEntry("", 0); 110632001f49Smrg glutAddMenuEntry("Point Filtered", POINT_FILTER); 110732001f49Smrg glutAddMenuEntry("Linear Filtered", LINEAR_FILTER); 110832001f49Smrg glutAddMenuEntry("", 0); 110932001f49Smrg glutAddMenuEntry("GL_TRIANGLES", TRIANGLES); 111032001f49Smrg glutAddMenuEntry("GL_TRIANGLE_STRIPS", STRIPS); 111132001f49Smrg glutAddMenuEntry("GL_POINTS", POINTS); 111232001f49Smrg glutAddMenuEntry("", 0); 111332001f49Smrg glutAddMenuEntry("Displaylist", DISPLAYLIST); 111432001f49Smrg glutAddMenuEntry("Immediate", IMMEDIATE); 111532001f49Smrg glutAddMenuEntry("", 0); 111632001f49Smrg if (allowed & LOCKED) { 111732001f49Smrg glutAddMenuEntry("Locked Arrays (CVA)", LOCKED); 111832001f49Smrg glutAddMenuEntry("Unlocked Arrays", UNLOCKED); 111932001f49Smrg glutAddMenuEntry("", 0); 112032001f49Smrg } 112132001f49Smrg glutAddMenuEntry("glVertex", GLVERTEX); 112232001f49Smrg if (allowed & DRAW_ARRAYS) { 112332001f49Smrg glutAddMenuEntry("glDrawElements", DRAW_ELTS); 112432001f49Smrg glutAddMenuEntry("glDrawArrays", DRAW_ARRAYS); 112532001f49Smrg glutAddMenuEntry("glArrayElement", ARRAY_ELT); 112632001f49Smrg } 112732001f49Smrg glutAddMenuEntry("", 0); 112832001f49Smrg glutAddMenuEntry("Quit", QUIT); 112932001f49Smrg glutAttachMenu(GLUT_RIGHT_BUTTON); 113032001f49Smrg 113132001f49Smrg glutReshapeFunc(Reshape); 113232001f49Smrg glutKeyboardFunc(Key); 113332001f49Smrg glutSpecialFunc(SpecialKey); 113432001f49Smrg glutDisplayFunc(Display); 113532001f49Smrg 113632001f49Smrg glutMainLoop(); 113732001f49Smrg return 0; 113832001f49Smrg} 1139