/* $Id: isosurf.c,v 1.2 1999/09/03 14:56:40 keithw Exp $ */ /* * Display an isosurface of 3-D wind speed volume. * * Brian Paul This file in public domain. */ /* Keys: * ===== * * - Arrow keys to rotate * - 's' toggles smooth shading * - 'l' toggles lighting * - 'f' toggles fog * - 'I' and 'i' zoom in and out * - 'c' toggles a user clip plane * - 'm' toggles colorful materials in GL_TRIANGLES modes. * - '+' and '-' move the user clip plane * * Other options are available via the popup menu. */ /* * $Log: isosurf.c,v $ * Revision 1.2 1999/09/03 14:56:40 keithw * Fog, displaylist and zoom operations * * Revision 3.4 1999/04/24 01:10:47 keithw * clip planes, materials * * Revision 3.3 1999/03/31 19:42:14 keithw * support for cva * * Revision 3.1 1998/11/01 20:30:20 brianp * added benchmark feature (b key) * * Revision 3.0 1998/02/14 18:42:29 brianp * initial rev * */ #include #include #include #include #include "GL/glut.h" #include "../util/readtex.c" /* I know, this is a hack. KW: me too. */ #define TEXTURE_FILE "../images/reflect.rgb" #define LIT 0x1 #define UNLIT 0x2 #define TEXTURE 0x4 #define NO_TEXTURE 0x8 #define REFLECT 0x10 #define NO_REFLECT 0x20 #define POINT_FILTER 0x40 #define LINEAR_FILTER 0x80 #define GLVERTEX 0x100 #define DRAW_ARRAYS 0x200 /* or draw_elts, if compiled */ #define ARRAY_ELT 0x400 #define COMPILED 0x800 #define IMMEDIATE 0x1000 #define SHADE_SMOOTH 0x2000 #define SHADE_FLAT 0x4000 #define TRIANGLES 0x8000 #define STRIPS 0x10000 #define USER_CLIP 0x20000 #define NO_USER_CLIP 0x40000 #define MATERIALS 0x80000 #define NO_MATERIALS 0x100000 #define FOG 0x200000 #define NO_FOG 0x400000 #define QUIT 0x800000 #define DISPLAYLIST 0x1000000 #define LIGHT_MASK (LIT|UNLIT) #define TEXTURE_MASK (TEXTURE|NO_TEXTURE) #define REFLECT_MASK (REFLECT|NO_REFLECT) #define FILTER_MASK (POINT_FILTER|LINEAR_FILTER) #define RENDER_STYLE_MASK (GLVERTEX|DRAW_ARRAYS|ARRAY_ELT) #define COMPILED_MASK (COMPILED|IMMEDIATE|DISPLAYLIST) #define MATERIAL_MASK (MATERIALS|NO_MATERIALS) #define PRIMITIVE_MASK (TRIANGLES|STRIPS) #define CLIP_MASK (USER_CLIP|NO_USER_CLIP) #define SHADE_MASK (SHADE_SMOOTH|SHADE_FLAT) #define FOG_MASK (FOG|NO_FOG) #define MAXVERTS 10000 static float data[MAXVERTS][6]; static float compressed_data[MAXVERTS][6]; static GLuint indices[MAXVERTS]; static GLuint tri_indices[MAXVERTS*3]; static GLfloat col[100][4]; static GLint numverts, num_tri_verts, numuniq; static GLfloat xrot; static GLfloat yrot; static GLfloat dist = -6; static GLint state, allowed = ~0; static GLboolean doubleBuffer = GL_TRUE; static GLdouble plane[4] = {1.0, 0.0, -1.0, 0.0}; static GLuint surf1; static void read_surface( char *filename ) { FILE *f; f = fopen(filename,"r"); if (!f) { printf("couldn't read %s\n", filename); exit(1); } numverts = 0; while (!feof(f) && numverts 0) return 1; \ return 0; \ } COMPARE_FUNC(0) COMPARE_FUNC(1) COMPARE_FUNC(2) COMPARE_FUNC(3) COMPARE_FUNC(4) COMPARE_FUNC(5) COMPARE_FUNC(6) int (*(compare[7]))( const void *a, const void *b ) = { compare_axis_0, compare_axis_1, compare_axis_2, compare_axis_3, compare_axis_4, compare_axis_5, compare_axis_6, }; #define VEC_ELT(f, s, i) (float *)(((char *)f) + s * i) static int sort_axis( int axis, int vec_size, int vec_stride, struct data_idx *indices, int start, int finish, float *out, int uniq, const float fudge ) { int i; if (finish-start > 2) { qsort( indices+start, finish-start, sizeof(*indices), compare[axis] ); } else if (indices[start].data[axis] > indices[start+1].data[axis]) { struct data_idx tmp = indices[start]; indices[start] = indices[start+1]; indices[start+1] = tmp; } if (axis == vec_size-1) { for (i = start ; i < finish ; ) { float max = indices[i].data[axis] + fudge; float *dest = VEC_ELT(out, vec_stride, uniq); int j; for (j = 0 ; j < vec_size ; j++) dest[j] = indices[i].data[j]; for ( ; i < finish && max >= indices[i].data[axis]; i++) indices[i].uniq_idx = uniq; uniq++; } } else { for (i = start ; i < finish ; ) { int j = i + 1; float max = indices[i].data[axis] + fudge; while (j < finish && max >= indices[j].data[axis]) j++; if (j == i+1) { float *dest = VEC_ELT(out, vec_stride, uniq); int k; indices[i].uniq_idx = uniq; for (k = 0 ; k < vec_size ; k++) dest[k] = indices[i].data[k]; uniq++; } else { uniq = sort_axis( axis+1, vec_size, vec_stride, indices, i, j, out, uniq, fudge ); } i = j; } } return uniq; } static void extract_indices1( const struct data_idx *in, unsigned int *out, int n ) { int i; for ( i = 0 ; i < n ; i++ ) { out[in[i].idx] = in[i].uniq_idx; } } static void compactify_arrays() { int i; struct data_idx *ind; ind = (struct data_idx *) malloc( sizeof(struct data_idx) * numverts ); for (i = 0 ; i < numverts ; i++) { ind[i].idx = i; ind[i].data = data[i]; } numuniq = sort_axis(0, sizeof(compressed_data[0])/sizeof(float), sizeof(compressed_data[0]), ind, 0, numverts, (float *)compressed_data, 0, 1e-6); printf("Nr unique vertex/normal pairs: %d\n", numuniq); extract_indices1( ind, indices, numverts ); free( ind ); } static float myrand( float max ) { return max*rand()/(RAND_MAX+1.0); } static void make_tri_indices( void ) { unsigned int *v = tri_indices; unsigned int parity = 0; unsigned int i, j; for (j=2;j