/* light_dat3.c user controlled rotating *.dat with lighting */ /* Utah Graphics ASCII data *.dat of *.det */ /* lighted, wire frame and vertex display */ /* point selection and output */ #include #include #include #include #include #include "datread.h" #undef abs #define abs(x) ((x>=0.0)?x:(-x)) #undef max #define max(x,y) ((x)>(y)?(x):(y)) static int num_points; /* for datread and datwrite */ static int num_polys; static dpts * data_points; static int * data_verts; static int width = 600; /* user can change */ static int height = 600; static GLfloat size = 1.0; /* auto scale */ static GLfloat offs = 1.1; static char save_filename[100]; static int status = -1; static int debug = 0; static GLfloat roll = 0.0; /* rotate about Z axis 'r' */ static GLfloat pitch = 0.0; /* rotate about X axis 'p' */ static GLfloat heading = 0.0; /* rotate about Y axis 'h' */ static GLfloat pos[3] = {0.0, 0.0, 0.0}; static int background = 1; /* background color 'b' */ static int wire = 0; /* draw wireframe 'w' */ static int vert = 0; /* draw vertices 'v' */ static int colorz = 0; /* color based on z 'c' */ static int trimz = 0; /* trim farthest z 't' */ static int numvert = 0; /* number vertices 'n' */ static GLfloat zavg = 0.0; static GLfloat zmin = 0.0; static GLfloat zmax = 0.0; static int iselect = -1; /* non zero means vertex selected */ static GLfloat amb[4] = { 0.329412, 0.223529, 0.027451, 1.0}; /* brass */ static GLfloat dif[4] = { 0.780392, 0.568627, 0.113725, 1.0}; /* material */ static GLfloat spe[4] = { 0.992157, 0.941176, 0.807843, 1.0}; static GLfloat shiney = 0.21794872; /* light source */ static GLfloat ambient[] = {0.0, 0.0, 0.0, 1.0}; /* no ambient */ static GLfloat diffuse[] = {0.4, 0.4, 0.4, 1.0}; /* mid diffuse */ static GLfloat specular[] = {0.4, 0.4, 0.4, 1.0}; /* mid specular */ static GLfloat position[] = {0.0, 0.0, 3.0, 0.0}; static GLdouble mmatrix[16]; /* 4 by 4 model transformation matrix */ static GLdouble pmatrix[16]; /* 4 by 4 perspective transformation matrix */ static GLint viewport[4]; static int win_w, win_h; /* colorwf.c color wheel based on parameter 0 < x 1 */ /* colorf(X, &R, &G, &B) returns R,G,B in 0.0 to 1.0 */ static void colorf(float X, float *RR, float *GG, float *BB) { float A, AA, AAA; /* temporaries */ float R, G, B; /* red, green, blue intensities */ A = 2.0*X-1.0; /* -1.0 < A < 1.0 */ if(A<-1.0) A = -1.0; if(A>1.0) A = 1.0; R = 1.0 - abs(A); AA = A - 2.0/3.0; if(AA < -1.0) AA = 2.0+AA; G = 1.0 - abs(AA); AA = A + 2.0/3.0; if(AA > 1.0) AA = 2.0-AA; B = 1.0 - abs(AA); /* boost low end and normalize (this brightens colors) */ R = R+0.2; G = G+0.2; B = B+0.2; AAA = max(R, G); AAA = max(AAA, B); *RR = R/AAA; *GG = G/AAA; *BB = B/AAA; /* glColor3f(R, G, B); */ } /* end colorf */ static void draw_solid_dat(void) { int i, j, k, pts, pt; GLfloat v[3][3]; int kk[3]; GLfloat ax, ay, az, bx, by, bz, nx, ny, nz, s; if(debug) printf("draw_solid_dat\n"); glLightfv(GL_LIGHT0, GL_AMBIENT, ambient); glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse); glLightfv(GL_LIGHT0, GL_POSITION, position); glFrontFace(GL_CCW); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_NORMALIZE); glEnable(GL_AUTO_NORMAL); glEnable(GL_DEPTH_TEST); glLightfv(GL_LIGHT0, GL_POSITION, position); glPushMatrix(); glLoadIdentity(); glRotatef(pitch, 1.0, 0.0, 0.0); glRotatef(heading, 0.0, 1.0, 0.0); glRotatef(roll, 0.0, 0.0, 1.0); glTranslatef(pos[0], pos[1], pos[2]); glGetDoublev(GL_MODELVIEW_MATRIX, mmatrix); /* save transformation */ glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, amb); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, dif); glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, spe); glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shiney * 64.0); /* use pys to do surfaces */ k = 0; for(i=0; i2) printf("pts=%d\n", pts); glBegin(GL_POLYGON); for(j=0; j<3; j++) { pt = data_verts[k++]; if(debug>2) printf("j=%d, pt=%d\n", j, pt); kk[j] = pt; v[j][0] = data_points[pt-1].x; v[j][1] = data_points[pt-1].y; v[j][2] = data_points[pt-1].z; } /* compute normals, assuming planar, normalize */ ax = v[2][0] - v[1][0]; ay = v[2][1] - v[1][1]; az = v[2][2] - v[1][2]; bx = v[1][0] - v[0][0]; by = v[1][1] - v[0][1]; bz = v[1][2] - v[0][2]; nx = ay*bz-az*by; ny = az*bx-ax*bz; nz = ax*by-ay*bx; s = sqrt(nx*nx+ny*ny+nz*nz); nx = nx / s; ny = ny / s; nz = nz / s; if(debug>1) { printf("\nv0x=%f, v0y=%f, v0z=%f\n", v[0][0], v[0][1], v[0][2]); printf("v1x=%f, v1y=%f, v1z=%f\n", v[1][0], v[1][1], v[1][2]); printf("v2x=%f, v2y=%f, v2z=%f\n", v[2][0], v[2][1], v[2][2]); printf("nx=%f, ny=%f, nz=%f\n", nx, ny, nz); } for(j=0; j<3; j++) { glNormal3f(nx, ny, nz); glVertex3f(data_points[kk[j]-1].x, data_points[kk[j]-1].y, data_points[kk[j]-1].z); } for(j=3; j2) printf("j=%d, pt=%d\n", j, pt); glNormal3f(nx, ny, nz); glVertex3f(data_points[pt-1].x, data_points[pt-1].y, data_points[pt-1].z); } glEnd(); } /* end loop on num_polys */ glPopMatrix(); } /* end draw_solid_dat */ static void draw_wire_dat(void) { int i, j, k, pts, pt; int skipz=0; GLdouble winx, winy, winz; glDisable(GL_LIGHTING); glDisable(GL_LIGHT0); glDisable(GL_NORMALIZE); glDisable(GL_AUTO_NORMAL); glPointSize(3.0); glPushMatrix(); glLoadIdentity(); glRotatef(pitch, 1.0, 0.0, 0.0); glRotatef(heading, 0.0, 1.0, 0.0); glRotatef(roll, 0.0, 0.0, 1.0); glTranslatef(pos[0], pos[1], pos[2]); glGetDoublev(GL_MODELVIEW_MATRIX, mmatrix); /* save transformation */ glGetDoublev(GL_PROJECTION_MATRIX, pmatrix); glGetIntegerv (GL_VIEWPORT, viewport); if(trimz || colorz) { zavg = 0.0; for(i=0; i zmax) zmax = winz; } zavg = zavg/ (double)num_points; } /* use num_polys to do wire frame */ k = 0; for(i=0; i2) printf("wire pts=%d\n", pts); if(background) glColor3f(0.0, 0.0, 0.0); if(!background) glColor3f(1.0, 1.0, 1.0); for(j=0; j2) printf("j=%d, pt=%d\n", j, pt); glVertex3f(data_points[pt-1].x, data_points[pt-1].y, data_points[pt-1].z); } glEnd(); } /* end loop on num_polys */ glPopMatrix(); } /* end draw_wire_dat */ static void draw_vert_dat(void) { int i, j, k, pts, pt; GLdouble winx, winy, winz; GLfloat zc, R, G, B; glDisable(GL_LIGHTING); glDisable(GL_LIGHT0); glDisable(GL_NORMALIZE); glDisable(GL_AUTO_NORMAL); glPushMatrix(); glLoadIdentity(); glRotatef(pitch, 1.0, 0.0, 0.0); glRotatef(heading, 0.0, 1.0, 0.0); glRotatef(roll, 0.0, 0.0, 1.0); glTranslatef(pos[0], pos[1], pos[2]); glGetDoublev(GL_MODELVIEW_MATRIX, mmatrix); /* save transformation */ glGetDoublev(GL_PROJECTION_MATRIX, pmatrix); glGetIntegerv (GL_VIEWPORT, viewport); if(trimz || colorz) { zavg = 0.0; for(i=0; i zmax) zmax = winz; } zavg = zavg/ (double)num_points; } /* use num_polys to do vertices */ k = 0; for(i=0; i2) printf("vert pts=%d\n", pts); for(j=0; j zmax) zmax = winz; } zavg = zavg/ (double)num_points; /* use num_polys to do vertices */ k = 0; for(i=0; i3) datwrite(save_filename, data_points, num_points, data_verts, num_polys); } glutPostRedisplay(); } /* end keyboard */ int main(int argc, char *argv[]) { glutInit(&argc, argv); /* need both double buffering and z buffer */ glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); glutInitWindowSize(width, height); glutCreateWindow(argv[0]); glutReshapeFunc(myReshape); glutDisplayFunc(display); glutMouseFunc(mouse); /* "mouse" setup */ glutKeyboardFunc(keyboard); /* "keyboard" setup */ glEnable(GL_DEPTH_TEST); /* Enable hidden--surface--removal */ /* read a .dat file */ if(argc>1) { status = datread(argv[1], &data_points, &num_points, &data_verts, &num_polys, &size); } else { printf("a filename of a .dat file is required.\n"); return 0; } if(status!=0) { printf("%s file not read as a .dat file\n", argv[1]); return 0; } save_filename[0] = '\0'; if(argc>2) strcpy(save_filename, argv[2]); if(debug) printf("starting MainLoop num_points=%d, num_polys=%d, size=%g\n", num_points, num_polys, size); if(size<1.0) size=1.0; glutMainLoop(); return 0; } /* end main of light_dat3.c */