/* light_dat.c Rotating *.dat with lighting */ /* Utah Graphics ASCII data *.dat of *.det */ /* Demonstration of use of homogeneous coordinate */ /* transformations and simple data structure for representing */ /* lighting model, needs normal vectors */ /* Mouse buttons control direction of rotation */ #include #include #include #include #include static FILE * infile; static char file_name[127]; static char input_line[255]; static int num_pts; static int num_pys; typedef struct {GLfloat x; GLfloat y; GLfloat z; GLfloat nx; GLfloat ny; GLfloat nz;} dpts; static dpts * data_points; /* malloc'd space for vertices */ static int * polys; /* malloc'd space for polygon index to vertices */ static int ipoly = 0; /* index to polys: count, indices, ... */ static int npoly = 0; static int debug = 0; static GLuint dataList; static GLfloat size = 1.0; /* default, may get larger */ static int background = 0; static GLfloat theta[3] = {0.0, 0.0, 0.0}; static GLfloat dtheta = 2.0; static GLint axis = 2; 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}; static GLfloat spe[4] = { 0.992157, 0.941176, 0.807843, 1.0}; static GLfloat shiney = 0.21794872; static GLfloat position[] = {0.0, 3.0, 4.0, 0.0}; /* Initialize depth buffer, projection matrix, */ /* light source, and lighting model. */ /* Do not specify a material property here. */ void init(void) { int i, j, k, pts; /* light source */ GLfloat ambient[] = {0.0, 0.0, 0.0, 1.0}; /* no ambient */ GLfloat diffuse[] = {1.0, 1.0, 1.0, 1.0}; /* strong diffuse */ GLfloat specular[] = {1.0, 1.0, 1.0, 1.0}; /* strong specular */ GLfloat lmodel_ambient[] = {0.2, 0.2, 0.2, 1.0}; GLfloat local_view[] = {0.0}; glLightfv(GL_LIGHT0, GL_AMBIENT, ambient); glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse); glLightfv(GL_LIGHT0, GL_POSITION, position); glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient); glLightModelfv(GL_LIGHT_MODEL_LOCAL_VIEWER, local_view); glFrontFace(GL_CCW); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_AUTO_NORMAL); glEnable(GL_NORMALIZE); glEnable(GL_DEPTH_TEST); glClearColor(1.0, 1.0, 1.0, 1.0); /* be efficient--make data display list */ dataList = glGenLists(1); glNewList(dataList, GL_COMPILE); /* use pys to do surfaces */ ipoly = 0; for(i=0; i 360.0) theta[axis] = theta[axis] - 360.0; glutPostRedisplay(); } void mouse(int btn, int state, int x, int y) { /* mouse callback, selects an axis about which to rotate */ if(btn==GLUT_LEFT_BUTTON && state == GLUT_DOWN) axis = 0; if(btn==GLUT_MIDDLE_BUTTON && state == GLUT_DOWN) axis = 1; if(btn==GLUT_RIGHT_BUTTON && state == GLUT_DOWN) axis = 2; } void myReshape(int w, int h) { glViewport(0, 0, w, h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); if(w <= h) glOrtho(-size, size, -size * (GLfloat)h / (GLfloat)w, size * (GLfloat)h / (GLfloat)w, -5.0*size, 5.0*size); else glOrtho(-size * (GLfloat)w / (GLfloat)h, size * (GLfloat)w / (GLfloat)h, -size, size, -5.0*size, 5.0*size); glMatrixMode(GL_MODELVIEW); } void keyboard (unsigned char key, int x, int y) { switch (key) { case 'S': dtheta = dtheta + 0.25; glutPostRedisplay(); break; case 's': dtheta = dtheta - 0.25; glutPostRedisplay(); break; case 'x': axis = 0; /* same as left mouse button */ glutPostRedisplay(); break; case 'y': axis = 1; /* same as middle mouse button */ glutPostRedisplay(); break; case 'z': axis = 2; /* same as right mouse button */ glutPostRedisplay(); break; case 'W': /* also arrow key */ background = 1; break; case 'w': background = 1; break; case 'B': background = 0; break; case 'b': background = 0; break; case 27: exit(0); break; default: break; } } #undef abs #define abs(x) (((x)<0.0)?(-(x)):(x)) int main(int argc, char *argv[]) { int i, j, k, pts; GLfloat v[3][3]; int kk[3]; GLfloat ax, ay, az, bx, by, bz, nx, ny, nz, s; /* get file name of data to render */ if(argc<2) { printf("supply a file name of a Utah data file\n"); exit(0); } else { printf("open %s for reading\n", argv[1]); infile = fopen(argv[1], "r"); if(infile == NULL) { printf("could not open %s for reading\n", argv[1]); exit(0); } strcpy(file_name, argv[1]); fgets(input_line, 254, infile); printf("first line %s \n", input_line); if(!strncmp("data", input_line, 4)) { sscanf(input_line, "data%d %d", &num_pts, &num_pys); } else { sscanf(input_line, "%d %d", &num_pts, &num_pys); } printf("num_pts=%d, num_pys=%d\n", num_pts, num_pys); data_points = (dpts *)malloc(sizeof(dpts)*num_pts); if(data_points == NULL) { printf("can not allocate enough space for points\n"); exit(0); } } for(i=0; isize) size = abs(data_points[i].x); if(abs(data_points[i].y)>size) size = abs(data_points[i].y); if(abs(data_points[i].z)>size) size = abs(data_points[i].z); } printf("scaling to size=%g\n", size); size = size * 2.0; /* for spinning */ position[2] = 2.0*size; /* now bring in polygon vertex indices */ polys = (int *)malloc(sizeof(int)*10*num_pys); if(polys == NULL) { printf("can not allocate enough space for polygon indices\n"); exit(0); } npoly = 0; for(i=0; i