/* read_file1.c This is a basic CAVE programing, that will read * in a set of data points, and then display them as white points. */ /* parts of this code originally came from Dave Pape, EVL, UIC. */ #include #include #include /* Create a simple data structure to hold the point data */ typedef struct { float x; float y; float z; } point; void init_gl(void); void draw(void); void navigate(void); void readData(char *file); /* The is the data that needs to be shared. Even though pointCount will * only hold one integer value, it also must be a pointer, so we can put * it into the shared memory arena. */ point *dataPoints; int *pointCount; main(int argc,char **argv) { CAVEConfigure(&argc,argv,NULL); /* Make sure a file name has been specified, then read in the data file */ if (argc < 2) { fprintf(stderr, "Usage: %s \n", argv[0]); exit(1); } else { readData(argv[1]); } CAVEInit(); CAVEInitApplication(init_gl,0); CAVEDisplay(draw,0); while (!CAVEgetbutton(CAVE_ESCKEY)) { navigate(); sginap(1); } CAVEExit(); } /* simple function to read in the data from an acii file. Notice we just * pass the file name as an argument, since our data structure is a global * variable. */ void readData(char *file) { FILE *fp; int i, number_of_points; if((fp = fopen(file, "r"))==NULL) { printf("Unable to open data file %s\n", file); exit(1); } if (!fscanf(fp, "%d", &number_of_points)) { fprintf(stderr, "Error Reading data file\n"); exit(1); } /* This is where the shared memory variables get initialized.*/ pointCount = (int*)CAVEMalloc(sizeof(int)); *pointCount = number_of_points; dataPoints = (point*)CAVEMalloc(sizeof(point) * number_of_points); for(i = 0; i < number_of_points; i++) { if (!fscanf(fp, "%f %f %f", &dataPoints[i].x, &dataPoints[i].y, &dataPoints[i].z)) { fprintf(stderr, "Error Reading data file\n"); exit(1); } } fclose(fp); } #define SPEED 5.0f void navigate(void) { float jx=CAVE_JOYSTICK_X,jy=CAVE_JOYSTICK_Y,dt,t; static float prevtime = 0; t = CAVEGetTime(); dt = t - prevtime; prevtime = t; if (fabs(jy)>0.2) { float wandFront[3]; CAVEGetVector(CAVE_WAND_FRONT,wandFront); CAVENavTranslate(wandFront[0]*jy*SPEED*dt, 0, wandFront[2]*jy*SPEED*dt); } if (fabs(jx)>0.2) CAVENavRot(-jx*90.0f*dt,'y'); } /* This holds the value for the floor display list. We will * use a display list to draw the floor this time, instead of * a seperate function. */ static GLuint floorList; void init_gl(void) { static float blueMaterial[] = { 0, 0, 1, 1 }; static float whiteMaterial[] = { 1, 1, 1, 1 }; int i, j; /* Notice the code to generate the floor is almost identical * to the code that was in the DrawFloor function. The main * difference is that we are now putting it into a display * list. When the display list is created, it expands and * reorganizes the OpenGL calls for speed. */ floorList = glGenLists(1); glNewList(floorList, GL_COMPILE); glBegin(GL_QUADS); glNormal3f(0, 1, 0); glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, whiteMaterial); glVertex3f(-100, 0, -100); glVertex3f(100, 0, -100); glVertex3f(100, 0, 100); glVertex3f(-100, 0, 100); glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, blueMaterial); for (i = -100; i <100; i+=20) { for(j = -100; j <100; j+=20) { glVertex3f(i, 0.1, j); glVertex3f(i+10, 0.1, j); glVertex3f(i+10, 0.1, j+10); glVertex3f(i, 0.1, j+10); } } for (i = -90; i < 100; i+=20) { for(j = -90; j < 100; j+=20) { glVertex3f(i, 0.1, j); glVertex3f(i+10, 0.1, j); glVertex3f(i+10, 0.1, j+10); glVertex3f(i, 0.1, j+10); } } glEnd(); glEndList(); glEnable(GL_LIGHT0); } /* draw the objects. */ void draw(void) { int i; glClearColor(0., 0., 0., 1.); glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT); glEnable(GL_LIGHTING); CAVENavTransform(); /* This is how we draw the floor we created in init_gl. */ glCallList(floorList); /* This just puts the data out in front of us, so we can see it better. */ glPushMatrix(); glTranslatef(0, 5, -8); /* Draw the data. */ /* first, we turn off the light, so the points get drawn as a color only, * with no lighting effects. */ glDisable(GL_LIGHTING); /* Draw the points 3 pixels wide */ glPointSize(3.0); /* use white for the color. Since we are not using lighting to draw the * points, we can just set a color, and not worry about material properties. */ glColor3f(1, 1, 1); glBegin(GL_POINTS); for (i = 0; i < *pointCount; i ++) { glVertex3f(dataPoints[i].x, dataPoints[i].y, dataPoints[i].z); } glEnd(); glPopMatrix(); glDisable(GL_LIGHTING); }