/* * simple glass model viewer * * Copyright (C) 2001-2003 Robert Ancell * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* compile with make */ #include #include #include #include void init(void); void reshape(int x, int y); void keyboard(unsigned char, int, int); void mouse(int, int, int, int); void mouse_motion(int, int); void display(void); int main(int argc, char **argv); GlassModel *example_model; int nvariables, npoints; int mbutton, oldx, oldy, current_variable = 0; float view_theta = 0.0f, view_phi = 0.0f, view_radius = 50.0f; int screen_width, screen_height; int is_light = 0; void init(void) { /* Set up glut */ glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH); glutInitWindowSize(400, 400); glutCreateWindow("simple glass model viewer"); /* Attach the functions */ glutMouseFunc(mouse); glutMotionFunc(mouse_motion); glutKeyboardFunc(keyboard); glutReshapeFunc(reshape); glutDisplayFunc(display); glEnable(GL_CULL_FACE); glEnable(GL_DEPTH_TEST); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_LIGHT0); glEnable(GL_TEXTURE_2D); glPointSize(5.0); glLineWidth(2.0); } void reshape(int w, int h) { glViewport(0, 0, (GLsizei) w, (GLsizei) h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(60.0, (GLfloat) w/(GLfloat) h, 0.5, 10000.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); screen_width = w; screen_height = h; } void keyboard(unsigned char key, int x, int y) { GLfloat min, max; switch(key) { case '\t': /* tab */ current_variable++; if(current_variable >= nvariables) current_variable = 0; break; case '+': min = glassGetVariableMin(example_model, current_variable); max = glassGetVariableMax(example_model, current_variable); glassIncVariable(example_model, current_variable, 0.01 * (max-min)); break; case '-': min = glassGetVariableMin(example_model, current_variable); max = glassGetVariableMax(example_model, current_variable); glassIncVariable(example_model, current_variable, 0.01 * (min-max)); break; case 'l': case 'L': is_light = !is_light; if(is_light) glEnable(GL_LIGHTING); else glDisable(GL_LIGHTING); break; case 27: /* esc */ exit(0); break; } glutPostRedisplay(); } void mouse(int button, int state, int x, int y) { mbutton = button; oldx = x; oldy = y; } void mouse_motion(int x, int y) { int dx = x - oldx, dy = y - oldy; switch(mbutton) { case GLUT_LEFT_BUTTON: view_theta += 1.0f * (float) dx; view_phi += 1.0f * (float) dy; break; case GLUT_RIGHT_BUTTON: view_radius += 1.0f * (float) dy; break; } oldx = x; oldy = y; glutPostRedisplay(); } void display(void) { int i; float percent; GLfloat *pos, *dir, value, max, min; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(0.0f, 0.0f, -view_radius); glRotatef(view_phi, 1.0f, 0.0f, 0.0f); glRotatef(view_theta, 0.0f, 1.0f, 0.0f); /* Draws our glass model */ glEnable(GL_TEXTURE_2D); glassDrawModel(example_model); /* Disable lighting and depth testing for apoints, and overlay */ glPushAttrib(GL_DEPTH_BUFFER_BIT | GL_LIGHTING_BIT); glDisable(GL_DEPTH_TEST); glDisable(GL_LIGHTING); glDisable(GL_TEXTURE_2D); /* Draw the active points */ glColor3f(1.0, 1.0, 0.0); for(i = 0; i < npoints; i++) { pos = glassGetActivePointPos(example_model, i); dir = glassGetActivePointDir(example_model, i); glBegin(GL_POINTS); glVertex3f(pos[0], pos[1], pos[2]); glEnd(); glBegin(GL_LINES); glVertex3f(pos[0], pos[1], pos[2]); glVertex3f(pos[0] + 2.0 * dir[0], pos[1] + 2.0 * dir[1], pos[2] + 2.0 * dir[2]); glEnd(); } /* Draw the overlay */ glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0.0f, screen_width, 0.0f, screen_height, -1.0f, 0.0f); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glBegin(GL_QUADS); for(i = 0; i < nvariables; i++) { if(i == current_variable) glColor3f(1.0, 0.0f, 0.0f); else glColor3f(0.0, 0.0f, 1.0f); glVertex3f(i * 20.0f + 10.0f, 50.0f, 0.5f); glVertex3f(i * 20.0f + 10.0f, 10.0f, 0.5f); glVertex3f(i * 20.0f + 20.0f, 10.0f, 0.5f); glVertex3f(i * 20.0f + 20.0f, 50.0f, 0.5f); } glColor3f(1.0, 1.0f, 1.0f); for(i = 0; i < nvariables; i++) { value = glassGetVariableValue(example_model, i); min = glassGetVariableMin(example_model, i); max = glassGetVariableMax(example_model, i); percent = (value - min) / (max - min); glVertex3f(i * 20.0f + 12.0f, 12.0f + 36.0f * percent, 0.6f); glVertex3f(i * 20.0f + 12.0f, 12.0f, 0.6f); glVertex3f(i * 20.0f + 17.0f, 12.0f, 0.6f); glVertex3f(i * 20.0f + 17.0f, 12.0f + 36.0f * percent, 0.6f); } glEnd(); glPopAttrib(); /* GL_DEPTH_BUFFER_BIT | GL_LIGHTING_BIT */ glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(60.0, (GLfloat) screen_width/(GLfloat) screen_height, 0.5, 10000.0); glutSwapBuffers(); } int main(int argc, char **argv) { if(argc == 1) { printf("Simple glass model viewer\n" "Views model in the glass format\n" "\n" "Usage: viewer [GLASS_MODEL]\n" "example: viewer foo.glm\n"); exit(0); } glutInit(&argc, argv); init(); /* Load the glass model */ if((example_model = glassLoadModel(argv[1])) == NULL) exit(0); nvariables = glassGetNumVariables(example_model); npoints = glassGetNumActivePoints(example_model); glutMainLoop(); return 0; }