#include "buttons.h" #include "windows.h" #include "curves.h" /****************************************/ /* Displays target in TARGET window. */ /****************************************/ void SET_LIGHTING(void) { GLfloat MatAmbient[] = {1.0, 0.9, 0.2, 1.0}; GLfloat MatDiffuse[] = {1.0, 0.9, 0.3, 1.0}; GLfloat Light1Diffuse[] = {1.0, 1.0, 1.0, 1.0}; GLfloat Light1Position[] = {0.0, 100.0, -1000.0, 1.0}; GLfloat MatShininess[] = {4.0}; GLfloat MatSpecular[] = {0.1, 0.1, 1.0, 1.0}; GLfloat Light2Specular[] = {1.0, 1.0, 1.0, 1.0}; GLfloat Light2Position[] = {100.0, 100.0, -1000.0, 1.0}; glLoadIdentity(); glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_FALSE); glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_TRUE); // Ambient "light source". glMaterialfv(GL_FRONT, GL_AMBIENT, MatAmbient); // Diffuse light source. glMaterialfv(GL_FRONT, GL_DIFFUSE, MatDiffuse); glLightfv(GL_LIGHT1, GL_DIFFUSE, Light1Diffuse); glLightfv(GL_LIGHT1, GL_POSITION, Light1Position); // Spectral light source. glMaterialfv(GL_FRONT, GL_SPECULAR, MatSpecular); glMaterialfv(GL_FRONT, GL_SHININESS, MatShininess); glLightfv(GL_LIGHT2, GL_SPECULAR, Light2Specular); glLightfv(GL_LIGHT2, GL_POSITION, Light2Position); } /****************************************/ /* Displays target in TARGET window. */ /****************************************/ void BEZIER_CURVE(void) { int i; glTranslated(300, 200, 0); glScaled(40, 40, 40); // Curve. glColor3f(1.0, 1.0, 1.0); glMap1f(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 4, &cPoints[0][0]); glEnable(GL_MAP1_VERTEX_3); glBegin(GL_LINE_STRIP); for (i = 0; i <= 25 ; i++) { glEvalCoord1f((GLfloat)i/25.0); } glEnd(); // Control points. glPointSize(4); glColor3f(1.0, 0.0, 1.0); glBegin(GL_POINTS); for (i = 0; i < 4; i++) { glVertex3fv(&cPoints[i][0]); } glEnd(); glPointSize(1); } void BEZIER_SURFACE(void) { int i, j; glTranslated(300, 200, 0); glScaled(40, 40, 40); // Surface. glColor3f(1.0, 1.0, 1.0); glMap2f(GL_MAP2_VERTEX_3, 0, 1, 3, 4, 0, 1, 12, 4, &sPoints[0][0][0]); glEnable(GL_MAP2_VERTEX_3); glMapGrid2f(20, 0.0, 1.0, 20, 0.0, 1.0); glRotatef(R, 0.0, 0.0, 1.0); glRotatef(Y, 1.0, 0.0, 0.0); glRotatef(P, 0.0, 1.0, 0.0); for (j = 0; j <= panels; j++) { glBegin(GL_LINE_STRIP); for (i = 0; i <= 25 ; i++) { glEvalCoord2f((GLfloat)i/25.0, (GLfloat)j/(GLfloat)panels); } glEnd(); glBegin(GL_LINE_STRIP); for (i = 0; i <= 25 ; i++) { glEvalCoord2f((GLfloat)j/(GLfloat)panels, (GLfloat)i/25.0); } glEnd(); } // Control points. glPointSize(4); for (i = 0; i < 4; i++) { if (i == 0) glColor3f(1.0, 0.0, 0.0); if (i == 1) glColor3f(0.0, 1.0, 0.0); if (i == 2) glColor3f(0.0, 0.0, 1.0); if (i == 3) glColor3f(1.0, 0.0, 1.0); glBegin(GL_LINE_STRIP); for (j = 0; j < 4; j++) { glVertex3fv(&sPoints[i][j][0]); } glEnd(); glBegin(GL_POINTS); for (j = 0; j < 4; j++) { glVertex3fv(&sPoints[i][j][0]); } glEnd(); } glPointSize(1); } void BEZIER_SURFACE2(void) { int i, j; // Lighting. SET_LIGHTING(); glEnable(GL_LIGHTING); glEnable(GL_LIGHT1); glEnable(GL_LIGHT2); glShadeModel(GL_FLAT); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glTranslated(300, 200, 0); glScaled(40, 40, 40); // Surface. glMap2f(GL_MAP2_VERTEX_3, 0, 1, 3, 4, 0, 1, 12, 4, &sPoints[0][0][0]); glEnable(GL_MAP2_VERTEX_3); glEnable(GL_AUTO_NORMAL); glEnable(GL_DEPTH_TEST); glClear(GL_DEPTH_BUFFER_BIT); glRotatef(R, 0.0, 0.0, 1.0); glRotatef(Y, 1.0, 0.0, 0.0); glRotatef(P, 0.0, 1.0, 0.0); for (j = 0; j <= panels; j++) { glBegin(GL_QUAD_STRIP); for (i = 0; i <= 25 ; i++) { glEvalCoord2f((GLfloat)i/25.0, (GLfloat)j/(GLfloat)panels); glEvalCoord2f((GLfloat)j/(GLfloat)panels, (GLfloat)i/25.0); } glEnd(); } // glMapGrid2f(panels, 0.0, 1.0, panels, 0.0, 1.0); // glEvalMesh2(GL_FILL, 0, panels, 0, panels); glDisable(GL_DEPTH_TEST); glDisable(GL_LIGHTING); } /****************************************/ /* Displays object in TARGET window. */ /****************************************/ void TARGET_DISPLAY(void) { glLoadIdentity(); TARGET_WINDOW.CLEAR(); glDrawBuffer(GL_BACK); if (flag == 1) BEZIER_CURVE(); if (flag == 2) BEZIER_SURFACE(); if (flag == 3) BEZIER_SURFACE2(); glutSwapBuffers(); } /****************************************/ /* Main window display. */ /****************************************/ void MAIN_WINDOW(void) { glDrawBuffer(GL_BACK); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glColor3f(0.6, 0.6, 0.6); glBegin(GL_QUADS); glVertex2i( 0, 0); glVertex2i(winWidth, 0); glVertex2i(winWidth, winHeight); glVertex2i( 0, winHeight); glEnd(); CRVE_BUTTON.DRAW(); PNT1_BUTTON.DRAW(); PNT2_BUTTON.DRAW(); SRFC_BUTTON.DRAW(); PANL_BUTTON.DRAW(); FILL_BUTTON.DRAW(); ROLL_BUTTON.DRAW(); PITH_BUTTON.DRAW(); YAW__BUTTON.DRAW(); EXIT_BUTTON.DRAW_HILITE(0.7, 0.0, 0.0); TARGET_WINDOW.DRAW(); TARGET_WINDOW.CLEAR(); glutSwapBuffers(); } /************************************************************/ /* CALLBACK FUNTIONS. */ /************************************************************/ /****************************************/ /* Mouse control. */ /****************************************/ void myMouse(int button, int state, int x, int y) { y = (winHeight - y); if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) { glFinish(); if (point1Flag == 1) { cPoints[1][0] = ((GLfloat)x - 300.0) / 30.0; cPoints[1][1] = ((GLfloat)y - 200.0) / 30.0; TARGET_DISPLAY(); point1Flag = 0; } if (point2Flag == 1) { cPoints[2][0] = ((GLfloat)x - 300.0) / 30.0; cPoints[2][1] = ((GLfloat)y - 200.0) / 30.0; TARGET_DISPLAY(); point2Flag = 0; } if (CRVE_BUTTON.SELECTED(x, y)) { CRVE_BUTTON.CLICK(); flag = 1; TARGET_DISPLAY(); } if (PNT1_BUTTON.SELECTED(x, y)) { PNT1_BUTTON.CLICK(); point1Flag = 1; } if (PNT2_BUTTON.SELECTED(x, y)) { PNT2_BUTTON.CLICK(); point2Flag = 1; } if (SRFC_BUTTON.SELECTED(x, y)) { SRFC_BUTTON.CLICK(); flag = 2; TARGET_DISPLAY(); } if (PANL_BUTTON.SELECTED(x, y)) { PANL_BUTTON.CLICK(); panels += 2; if (panels >= 20) panels = 2; TARGET_DISPLAY(); } if (FILL_BUTTON.SELECTED(x, y)) { FILL_BUTTON.CLICK(); flag = 3; TARGET_DISPLAY(); } if (ROLL_BUTTON.SELECTED(x, y)) { ROLL_BUTTON.CLICK(); R += 5.0; if (R >= 360.0) R = 0.0; TARGET_DISPLAY(); } if (PITH_BUTTON.SELECTED(x, y)) { PITH_BUTTON.CLICK(); P += 5.0; if (P >= 360.0) P = 0.0; TARGET_DISPLAY(); } if (YAW__BUTTON.SELECTED(x, y)) { YAW__BUTTON.CLICK(); Y += 5.0; if (Y >= 360.0) Y = 0.0; TARGET_DISPLAY(); } if (EXIT_BUTTON.SELECTED(x, y)) { EXIT_BUTTON.CLICK(); glutDestroyWindow(window); exit(0); } } } /****************************************/ /* Resizes screen (if required) */ /****************************************/ void myResize(int width, int height) { glutReshapeWindow(winWidth, winHeight); } /****************************************/ /* Redisplays screen (if required) */ /****************************************/ void myDisplay(void) { drawFlag = glutLayerGet(GLUT_NORMAL_DAMAGED); if (drawFlag == 1) { MAIN_WINDOW(); drawFlag = 0; } else { glutSwapBuffers(); } } /****************************************/ /* Initializes OPENGL parameters */ /****************************************/ void myInit(void) { glPointSize(1); glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClear(GL_COLOR_BUFFER_BIT); glMatrixMode(GL_PROJECTION); glOrtho(0.0, (GLdouble)winWidth, 0.0, (GLdouble)winHeight, -1000.0, 1000.0); glMatrixMode(GL_MODELVIEW); glEnable(GL_NORMALIZE); glLoadIdentity(); } /************************************************************/ /* MAIN. */ /************************************************************/ int main(int argc, char **argv) { glutInit(&argc, argv) ; glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); glutInitWindowSize(winWidth, winHeight); glutInitWindowPosition(winX, winY); window = glutCreateWindow("NURBS by R. Marsh."); glutDisplayFunc(myDisplay); glutReshapeFunc(myResize); glutMouseFunc(myMouse); myInit(); glutMainLoop(); return 1; }