#include #include #include #include #include #define MAXLINE 2412 void display(void); void init_window(int argc, char** argv); void other_init(); void keyboard(unsigned char key, int x, int y); void draw_object(); GLint width = 600; GLint height = 400; GLint count; GLint numPoints; FILE *fp; float target[MAXLINE][3]; float maxX, maxY, maxZ, minX, minY, minZ, avgX, avgY, avgZ; // Object variables GLfloat xRot, yRot, zRot; GLfloat xPos, yPos, zPos; GLfloat scale; // Viewport variables GLfloat scaleViewport; GLfloat xPosViewport, yPosViewport; // Ortho values GLfloat orth_near, orth_far, orth_left, orth_right, orth_top, orth_bottom; // Perspective values GLfloat pers_near, pers_far, cop; // Original ortho sizes GLfloat orth_vertical_size, orth_horizontal_size; // Status variables bool ortho_mode; bool multiple_viewports; int current_view; void prompt_open_file() { int flag = 1; int file_name_length; char file_name[256]; while(flag) { printf("Enter file name : "); scanf("%s", file_name); if ((fp = fopen(file_name, "r")) == NULL) // if ((fp = fopen("img4.dat", "r")) == NULL) printf("\n%s file can't readable !\n", file_name); else flag = 0; } } void read_data() { char buffer[50]; int x, y, z; maxX = maxY = maxZ = -9999; minX = minY = minZ = 9999; avgX = avgY = avgZ = 0; numPoints = 0; while ((fgets(buffer, 50, fp)) != NULL) { if (buffer[0] == 'j' || buffer[0] == 'J') { target[count][0] = -9999; count++; } else { sscanf(buffer, "%d %d %d", &x, &y,&z); target[count][0] = x; target[count][1] = y; target[count][2] = z; avgX += x; avgY += y; avgZ += z; if (x > maxX) maxX = x; if (y > maxY) maxY = y; if (z > maxZ) maxZ = z; if (x < minX) minX = x; if (y < minY) minY = y; if (z < minZ) minZ = z; count++; numPoints++; } } avgX = avgX / numPoints; avgY = avgY / numPoints; avgZ = avgZ / numPoints; for (int i = 0; i < count; i++) { if (target[i][0] == -9999) { continue; } else { target[i][0] -= avgX; target[i][1] -= avgY; target[i][2] -= avgZ; } } } void keyboard(unsigned char key, int x, int y) { GLfloat old; switch (key) { // Object position case 'U': yPos += (maxY - minY) * .10; break; case 'D': yPos -= (maxY - minY) * .10; break; case 'R': xPos += (maxX - minX) * .10; break; case 'L': xPos -= (maxX - minX) * .10; break; // Object Rotation case 'x': xRot += 15.0f; break; case 'X': xRot -= 15.0f; break; case 'y': yRot += 15.0f; break; case 'Y': yRot -= 15.0f; break; case 'z': zRot += 15.0f; break; case 'Z': // Object scaling zRot -= 15.0f; break; case '-': case '_': scale -= .1f; if (scale <= .1f) scale = .1f; break; case '=': case '+': scale += .1f; if (scale >= 5.0f) scale = 5.0f; break; // Object reset case 'i': case 'I': xRot = yRot = zRot = 0.0f; xPos = yPos = zPos = 0.0f; scale = 1.0f; break; // Viewport scaling case 'E': old = scaleViewport; scaleViewport += 0.1f; if (scaleViewport > 1.0f) scaleViewport = 1.0f; // Update viewport xPosViewport += (old - scaleViewport) * width / 2.0f; yPosViewport += (old - scaleViewport) * height / 2.0f; orth_top += orth_vertical_size * (old - scaleViewport) / 2.0f; orth_bottom -= orth_vertical_size * (old - scaleViewport) / 2.0f; orth_left -= orth_horizontal_size * (old - scaleViewport) / 2.0f; orth_right += orth_horizontal_size * (old - scaleViewport) / 2.0f; break; case 'e': old = scaleViewport; scaleViewport -= 0.1f; if (scaleViewport * height < 10.0f) scaleViewport = 10.0f / height; // Update viewport xPosViewport += (old - scaleViewport) * width / 2.0f; yPosViewport += (old - scaleViewport) * height / 2.0f; orth_top += orth_vertical_size * (old - scaleViewport) / 2.0f; orth_bottom -= orth_vertical_size * (old - scaleViewport) / 2.0f; orth_left -= orth_horizontal_size * (old - scaleViewport) / 2.0f; orth_right += orth_horizontal_size * (old - scaleViewport) / 2.0f; break; // Viewport movement case 'u': yPosViewport += (0.1f * height); orth_top -= (0.1f * orth_vertical_size); orth_bottom -= (0.1f * orth_vertical_size); break; case 'd': yPosViewport -= (0.1f * height); orth_top += (0.1f * orth_vertical_size); orth_bottom += (0.1f * orth_vertical_size); break; case 'l': xPosViewport -= (0.1f * width); orth_left += (0.1f * orth_horizontal_size); orth_right += (0.1f * orth_horizontal_size); break; case 'r': xPosViewport += (0.1f * width); orth_left -= (0.1f * orth_horizontal_size); orth_right -= (0.1f * orth_horizontal_size); break; // Projection controls case 'O': case 'o': ortho_mode = 1; current_view = 0; multiple_viewports = 0; break; case 'P': case 'p': ortho_mode = 0; current_view = 0; multiple_viewports = 0; break; case 'T': case 't': current_view = 1; multiple_viewports = 0; break; case 'S': case 's': current_view = 2; multiple_viewports = 0; break; case 'N': case 'n': if (cop > 3000) { cop -= 100; // pers_near -= 100; // pers_far -= 200; } break; case 'F': case 'f': cop += 100; // pers_near += 200; pers_far += 100; break; // Multiple viewports case 'V': case 'v': multiple_viewports = !multiple_viewports; break; // Exit Application case 'q': case 'Q': exit(0); } // Make sure that viewport is within the boundaries of the window if (xPosViewport < 0) { float scaleFactor = xPosViewport; xPosViewport = 0; orth_left += (scaleFactor / width) * orth_horizontal_size; orth_right += (scaleFactor / width) * orth_horizontal_size; } else if (xPosViewport + width * scaleViewport >= width) { float scaleFactor = xPosViewport + width * scaleViewport - width; xPosViewport = width - (scaleViewport * width); orth_left += (scaleFactor / width) * orth_horizontal_size; orth_right += (scaleFactor / width) * orth_horizontal_size; } if (yPosViewport < 0) { float scaleFactor = yPosViewport; yPosViewport = 0; orth_top += (scaleFactor / height) * orth_vertical_size; orth_bottom += (scaleFactor / height) * orth_vertical_size; } else if (yPosViewport + height * scaleViewport >= height) { float scaleFactor = yPosViewport + height * scaleViewport - height; yPosViewport = height - (scaleViewport * height); orth_top += (scaleFactor / height) * orth_vertical_size; orth_bottom += (scaleFactor / height) * orth_vertical_size; } glutPostRedisplay(); } void drawBorder() { glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(orth_left, orth_right, orth_bottom, orth_top, orth_near, orth_far); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); // Viewport position and size glViewport(xPosViewport, yPosViewport, width * scaleViewport, height * scaleViewport); // Draw border glColor3f(1.0f, 0.0f, 0.0f); glLineWidth(2.0f); glBegin(GL_LINE_STRIP); glVertex3f(orth_left, orth_bottom, 0); glVertex3f(orth_left, orth_top - 1, 0); glVertex3f(orth_right - 1, orth_top - 1, 0); glVertex3f(orth_right - 1, orth_bottom, 0); glVertex3f(orth_left, orth_bottom, 0); glEnd(); glLineWidth(1.0f); } void display(void) { glClear(GL_COLOR_BUFFER_BIT); glLoadIdentity(); // Projection mode if (ortho_mode && !multiple_viewports) { drawBorder(); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(orth_left, orth_right, orth_bottom, orth_top, orth_near, orth_far); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); // Viewport position and size glViewport(xPosViewport, yPosViewport, width * scaleViewport, height * scaleViewport); if (current_view == 0) { gluLookAt(0.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f); } else if (current_view == 1) { gluLookAt(0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, -1.0f); } else if (current_view == 2) { gluLookAt(0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f); } draw_object(); } // Perspective view else if (!multiple_viewports) { drawBorder(); glMatrixMode(GL_PROJECTION); glLoadIdentity(); //gluPerspective(90, 1.0f, pers_near, pers_far); glFrustum(orth_left, orth_right, orth_bottom, orth_top, pers_near, pers_far); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glViewport(xPosViewport, yPosViewport, width * scaleViewport, height * scaleViewport); if (current_view == 0) { //gluLookAt(0.0f, 0.0f, 5000.0f - cop, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f); gluLookAt(.0f, .0f, cop, 0, 0, 0.0f, 0.0f, 1.0f, 0.0f); } else if (current_view == 1) { //gluLookAt(0.0f, 5000.0f - cop, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f); gluLookAt(0.0f, cop, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f); } else if (current_view == 2) { //gluLookAt(-5000.0f + cop, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f); gluLookAt(-cop, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f); } draw_object(); } // Multiple viewports else { // Bottom Left viewport - Front view glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(-2500, 2500, -2500, 2500, -7500, 7500); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glViewport(0, 0, width / 2, height / 2); gluLookAt(0.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f); draw_object(); // Bottom Right viewport - left view glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(-2500, 2500, -2500, 2500, -7500, 7500); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glViewport(width / 2, 0, width / 2, height / 2); gluLookAt(0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f); draw_object(); // Top Left viewport - Top View glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(-2500, 2500, -2500, 2500, -7500, 7500); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glViewport(0, height / 2, width / 2, height / 2); gluLookAt(0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, -1.0f); draw_object(); // Top Right viewport - Perspective glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(90, 1.0f, pers_near, pers_far); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glViewport(width / 2, height / 2, width / 2, height / 2); //gluLookAt(7500.0f, 7500.0f, 7500.0f, 5000.0f, 5000.0f, 5000.0f, 0.0f, 1.0f, 0.0f); gluLookAt(-2500.0f, 2500.0f, 2500.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f); draw_object(); } glutSwapBuffers(); } // Draw object void draw_object() { glColor3f(0.0f, 0.0f, 0.0f); glTranslatef(xPos, yPos, zPos); glScalef(scale, scale, scale); glRotatef(xRot, 1.0f, 0.0f, 0.0f); glRotatef(yRot, 0.0f, 1.0f, 0.0f); glRotatef(zRot, 0.0f, 0.0f, 1.0f); int i, flag; for (i = 0; i < count; i++) { if (target[i][0] == -9999) { flag = 0; } else { if (flag == 1) { glBegin(GL_LINES); glVertex3f(target[i - 1][0], target[i - 1][1], target[i - 1][2]); glVertex3f(target[i][0], target[i][1], target[i][2]); glEnd(); } else flag = 1; } } glFlush(); } void init_window(int argc, char** argv) { glutInit(&argc,argv); glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); glutInitWindowSize(width, height); glutInitWindowPosition(0,0); glutCreateWindow("Project 4"); } void other_init() { glClearColor(1.0, 1.0, 1.0, 1.0); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(orth_left, orth_right, orth_bottom, orth_top, orth_near, orth_far); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glEnable(GL_CULL_FACE); } void read_file() { prompt_open_file(); read_data(); } void main(int argc, char** argv) { read_file(); fclose(fp); // Initial variable values xRot = yRot = zRot = 0.0f; xPos = yPos = zPos = 0.0f; scale = 1.0f; // Viewport settings xPosViewport = width / 4.0f; yPosViewport = height / 4.0f; scaleViewport = 0.5f; orth_near = -2500; orth_bottom = -2500; orth_left = -2500; orth_far = 2500; orth_right = 2500; orth_top = 2500; pers_near = 2000.0f; pers_far = pers_near + 8000; cop = 4000.0f; orth_vertical_size = orth_bottom - orth_top; orth_horizontal_size = orth_left - orth_right; ortho_mode = 1; multiple_viewports = 0; current_view = 0; // Shrink the initial viewport size orth_top -= 1250.0f; orth_bottom += 1250.0f; orth_left += 1250.0f; orth_right -= 1250.0f; // Initializations init_window(argc,argv); other_init(); glutDisplayFunc(display); glutKeyboardFunc(keyboard); glutMainLoop(); }