www.pudn.com > nurbs++3_0_10.zip > tngl.C
// the code was adapted from test/glut/bigtest.c from the glut distribution // see that file for more details. #include#ifdef WITH_OPENGL #include #include using namespace PLib ; #define Boolean GLboolean #define TRUE GL_TRUE #define FALSE GL_FALSE Boolean timerOn = FALSE; /* timer active */ //Boolean animation = FALSE; /* idle func animation on */ int animation = 0 ; Boolean debug = FALSE; /* dump all events */ Boolean showKeys = FALSE; /* dump key events */ Boolean demoMode = FALSE; /* run automatic demo */ Boolean backdrop = FALSE; /* use backdrop polygon */ Boolean passive = FALSE; /* report passive motions */ Boolean leftDown = FALSE; /* left button down ? */ Boolean middleDown = FALSE; /* middle button down ? */ int editMode = 0 ; // are we editing the curve/surface ? float rotationAngle = 0.0; /* global rotation angle */ #define PR if(debug)printf enum { RGBA, INDEX, SINGLE, DOUBLEBUFFER, DEPTH, ACCUM, ALPHA, STENCIL, MULTISAMPLE, STEREO, MODES }; /*int glutMode[] = {GLUT_RGBA, GLUT_INDEX, GLUT_SINGLE, GLUT_DOUBLE, GLUT_DEPTH, GLUT_ACCUM, GLUT_ALPHA, GLUT_STENCIL, GLUT_MULTISAMPLE, GLUT_STEREO}; int modes[MODES] = {0}; */ GLboolean menuButton[3] = {0, 0, 1}; enum { MOUSEBUTTON, MOUSEMOTION, APPLY, RESET }; int lineWidth = 1; /* line width */ int shapeId = 1 ; int winId = 0 ; float u = 0.5 ; float v = 0.5 ; void trackBall(int mode, int button, int state, int x, int y); void drawScene(void); void updateAll(void) { if (lineWidth < 1) lineWidth = 1; glutSetWindow(winId); glutPostRedisplay(); } NurbsCurveGL c ; NurbsSurfaceGL s ; void gfxInit(int index) { GLfloat grey10[] = {0.10, 0.10, 0.10, 1.0}; GLfloat grey20[] = {0.2, 0.2, 0.2, 1.0}; GLfloat black[] = {0.0, 0.0, 0.0, 0.0}; GLfloat diffuse0[] = {1.0, 0.0, 0.0, 1.0}; GLfloat diffuse1[] = {0.0, 1.0, 0.0, 1.0}; GLfloat diffuse2[] = {1.0, 1.0, 0.0, 1.0}; GLfloat diffuse3[] = {0.0, 1.0, 1.0, 1.0}; GLfloat diffuse4[] = {1.0, 0.0, 1.0, 1.0}; #define XX 3 #define YY 3 #define ZZ -2.5 float vertex[][3] = { {-XX, -YY, ZZ}, {+XX, -YY, ZZ}, {+XX, +YY, ZZ}, {-XX, +YY, ZZ} }; /* warning: This func mixes RGBA and CMAP calls in an ugly fashion */ glutSetWindow(winId); if(glIsList(0)) glDeleteLists(0,2) ; glNewList(1,GL_COMPILE); // glutWireSphere(1.5, 10, 10); GLUnurbsObj *theNurb; theNurb = gluNewNurbsRenderer(); gluNurbsProperty(theNurb, GLU_SAMPLING_TOLERANCE, 25.0); gluNurbsProperty(theNurb, GLU_DISPLAY_MODE, GLU_FILL); c.ObjectGL::read("tngl.nc") ; MatrixRT M ; M.scale(0.01,0.01,0.01) ; c.transform(M) ; c.setNurbsRenderer(theNurb) ; c.setObjectColor(Color(200,100,255),Color(255,255,255),Color(255,255,255)) ; c.glObject() ; glEndList() ; glNewList(2,GL_COMPILE) ; s.ObjectGL::read("tngl.ns") ; GLUnurbsObj *theNurb2; theNurb2 = gluNewNurbsRenderer(); gluNurbsProperty(theNurb2, GLU_SAMPLING_TOLERANCE, 25.0); gluNurbsProperty(theNurb2, GLU_DISPLAY_MODE, GLU_OUTLINE_PATCH); s.setNurbsRenderer(theNurb2) ; s.setObjectColor(Color(100,200,255),Color(255,255,255),Color(255,255,255)) ; s.glObject() ; glEndList() ; glNewList(3,GL_COMPILE) ; NurbsDisplayMode = NURBS_DISPLAY_TESSELATION ; theNurb2 = gluNewNurbsRenderer(); gluNurbsProperty(theNurb2, GLU_SAMPLING_TOLERANCE, 25.0); gluNurbsProperty(theNurb2, GLU_DISPLAY_MODE, GLU_OUTLINE_PATCH); s.setNurbsRenderer(theNurb2) ; s.setObjectColor(Color(100,200,255),Color(255,255,255),Color(255,255,255)) ; s.glObject() ; glEndList() ; glutSetWindow(winId); /* hack - redefineShapes changes glut win */ /* Shaded backdrop square (RGB or CMAP) */ glNewList(100, GL_COMPILE); glPushAttrib(GL_LIGHTING); glDisable(GL_LIGHTING); glBegin(GL_POLYGON); glColor4fv(black); glIndexi(0); glVertex3fv(vertex[0]); glColor4fv(grey10); glIndexi(3); glVertex3fv(vertex[1]); glColor4fv(grey20); glIndexi(4); glVertex3fv(vertex[2]); glColor4fv(grey10); glIndexi(7); glVertex3fv(vertex[3]); glEnd(); glPopAttrib(); glIndexi(9); glEndList(); /* Set proj+view */ glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(40.0, 1.0, -200.0, 200.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.); glTranslatef(0.0, 0.0, -1.0); /* Set basic material, lighting for RGB windows */ //glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse0); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_DEPTH_TEST); glClearColor(0.1, 0.1, 0.1, 1.0); } void keyFunc(unsigned char key, int x, int y) { int i, ii; //if (debug || showKeys) // printf("Ascii key '%c' 0x%02x\n", key, key); switch (key) { case 0x1b: exit(0); break; case 'a': animation != animation ; PR("animation = %d",animation) ; drawScene() ; break ; case 's': // changing shape // good shapes are 1 and 2 (for now) ++shapeId; shapeId = shapeId%4 ; if(!shapeId) shapeId = 1 ; drawScene() ; break ; case 'e': // change mode if(editMode) editMode = 0 ; else editMode = 1 ; drawScene() ; break ; case 'q': //killWindow(idToIndex(glutGetWindow())); exit(0) ; break; case 'r': trackBall(RESET, 0, 0, 0, 0); drawScene() ; break; case 'd': shapeId = ( shapeId == 2) ? 3 : 2 ; drawScene(); break ; case 'D': debug = !debug; break; case 'l': lineWidth += 1; updateAll(); break; case 'L': lineWidth -= 1; if (lineWidth < 1) lineWidth = 1; updateAll(); break; default: ; } } /* specialFunc - Special keys callback (F keys, cursor keys etc. */ /* ARGSUSED1 */ /* void specialFunc(int key, int x, int y) { if (debug || showKeys) printf("Special key %d\n", key); switch (key) { case GLUT_KEY_PAGE_DOWN: scrollLine += 10; updateHelp(); updateText(); break; case GLUT_KEY_PAGE_UP: scrollLine -= 10; updateHelp(); updateText(); break; case GLUT_KEY_DOWN: scrollLine += 1; updateHelp(); updateText(); break; case GLUT_KEY_UP: scrollLine -= 1; updateHelp(); updateText(); break; case GLUT_KEY_HOME: scrollLine = 0; updateHelp(); updateText(); break; case GLUT_KEY_END: scrollLine = 9999; updateHelp(); updateText(); break; case GLUT_KEY_RIGHT: scrollCol -= 1; updateHelp(); updateText(); break; case GLUT_KEY_LEFT: scrollCol += 1; updateHelp(); updateText(); break; } } */ /* trackBall - A simple trackball (not with proper rotations). */ /** A simple trackball with spin = left button pan = middle button zoom = left + middle Doesn't have proper trackball rotation, ie axes which remain fixed in the scene. We should use the trackball code from 4Dgifts. */ #define STARTROTATE(x, y) \ { \ startMX = x; \ startMY = y; \ } #define STOPROTATE(x, y) \ { \ steadyXangle = varXangle; \ steadyYangle = varYangle; \ } #define STARTPAN(x, y) \ { \ startMX = x; \ startMY = y; \ } #define STOPPAN(x, y) \ { \ steadyX = varX; \ steadyY = varY; \ } #define STARTZOOM(x, y) \ { \ startMX = x; \ startMY = y; \ } #define STOPZOOM(x, y) \ { \ steadyZ = varZ; \ } void trackBall(int mode, int button, int state, int x, int y) { static int startMX = 0, startMY = 0; /* initial mouse pos */ static int deltaMX = 0, deltaMY = 0; /* initial mouse pos */ static int startMU = 0, startMV = 0; /* initial mouse pos */ static int deltaMU = 0, deltaMV = 0; /* initial mouse pos */ static float steadyXangle = 0.0, steadyYangle = 0.0; static float varXangle = 0.0, varYangle = 0.0; static float steadyX = 0.0, steadyY = 0.0, steadyZ = 0.0; static float varX = 0.0, varY = 0.0, varZ = 0.0; if(editMode){ switch(mode){ case RESET: u = v = 0.5 ; break; case APPLY: if (leftDown && !middleDown) { glTranslatef(steadyX, steadyY, steadyZ); glRotatef(varXangle, 0, 1, 0); glRotatef(varYangle, 1, 0, 0); } /* Middle button pan */ else if (middleDown && !leftDown) { glTranslatef(varX, varY, steadyZ); glRotatef(steadyXangle, 0, 1, 0); glRotatef(steadyYangle, 1, 0, 0); } /* Left + middle zoom. */ else if (leftDown && middleDown) { glTranslatef(steadyX, steadyY, varZ); glRotatef(steadyXangle, 0, 1, 0); glRotatef(steadyYangle, 1, 0, 0); } /* Nothing down. */ else { glTranslatef(steadyX, steadyY, steadyZ); glRotatef(steadyXangle, 0, 1, 0); glRotatef(steadyYangle, 1, 0, 0); } break; case MOUSEBUTTON: if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN && !middleDown) { startMU = x ; startMV = y ; leftDown = TRUE ; } else if (button == GLUT_MIDDLE_BUTTON && state == GLUT_DOWN && !leftDown) { startMU = x ; startMV = y ; } else{ leftDown = FALSE ; middleDown = FALSE ; } break; case MOUSEMOTION: deltaMU = x - startMU ; deltaMV = startMV - y; startMU = x ; startMV = y ; if (leftDown) { u += deltaMU/100.0 ; v += deltaMV/100.0 ; if(shapeId==1) u+=deltaMV/100.0 ; } else { u += deltaMU/1000.0 ; v += deltaMV/1000.0 ; if(shapeId==1) u+=deltaMV/1000.0 ; } if(u<0.0) u = 0.0 ; if(v<0.0) v = 0.0 ; if(u>1.0) u = 1.0 ; if(v>1.0) v = 1.0 ; break; } } else switch (mode) { case RESET: steadyXangle = steadyYangle = steadyX = steadyY = steadyZ = 0.0; break; case MOUSEBUTTON: if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN && !middleDown) { STARTROTATE(x, y); leftDown = TRUE; } else if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN && middleDown) { STOPPAN(x, y); STARTZOOM(x, y); leftDown = TRUE; } else if (button == GLUT_MIDDLE_BUTTON && state == GLUT_DOWN && !leftDown) { STARTPAN(x, y); middleDown = TRUE; } else if (button == GLUT_MIDDLE_BUTTON && state == GLUT_DOWN && leftDown) { STOPROTATE(x, y); STARTZOOM(x, y); middleDown = TRUE; } else if (state == GLUT_UP && button == GLUT_LEFT_BUTTON && !middleDown) { STOPROTATE(x, y); leftDown = FALSE; } else if (state == GLUT_UP && button == GLUT_LEFT_BUTTON && middleDown) { STOPZOOM(x, y); STARTROTATE(x, y); leftDown = FALSE; } else if (state == GLUT_UP && button == GLUT_MIDDLE_BUTTON && !leftDown) { STOPPAN(x, y); middleDown = FALSE; } else if (state == GLUT_UP && button == GLUT_MIDDLE_BUTTON && leftDown) { STOPZOOM(x, y); STARTROTATE(x, y); middleDown = FALSE; } break; case APPLY: if (leftDown && !middleDown) { glTranslatef(steadyX, steadyY, steadyZ); glRotatef(varXangle, 0, 1, 0); glRotatef(varYangle, 1, 0, 0); } /* Middle button pan */ else if (middleDown && !leftDown) { glTranslatef(varX, varY, steadyZ); glRotatef(steadyXangle, 0, 1, 0); glRotatef(steadyYangle, 1, 0, 0); } /* Left + middle zoom. */ else if (leftDown && middleDown) { glTranslatef(steadyX, steadyY, varZ); glRotatef(steadyXangle, 0, 1, 0); glRotatef(steadyYangle, 1, 0, 0); } /* Nothing down. */ else { glTranslatef(steadyX, steadyY, steadyZ); glRotatef(steadyXangle, 0, 1, 0); glRotatef(steadyYangle, 1, 0, 0); } break; case MOUSEMOTION: deltaMX = x - startMX; deltaMY = startMY - y; if (leftDown && !middleDown) { varXangle = steadyXangle + deltaMX; varYangle = steadyYangle + deltaMY; } else if (middleDown && !leftDown) { varX = steadyX + deltaMX / 100.0; varY = steadyY + deltaMY / 100.0; } else if (leftDown && middleDown) { varZ = steadyZ - deltaMY / 50.0; } break; } } /* mouseFunc - Mouse button callback */ void mouseFunc(int button, int state, int x, int y) { PR("Mouse button %d, state %d, at pos %d, %d\n", button, state, x, y); trackBall(MOUSEBUTTON, button, state, x, y); } /* motionFunc - Mouse movement (with a button down) callback */ void motionFunc(int x, int y) { PR("Mouse motion at %d, %d\n", x, y); trackBall(MOUSEMOTION, 0, 0, x, y); glutPostRedisplay(); } /* passiveMotionFunc - Mouse movement (with no button down) callback */ void passiveMotionFunc(int x, int y) { printf("Mouse motion at %d, %y\n", x, y); } /* entryFunc - Window entry event callback */ void entryFunc(int state) { int winId = glutGetWindow(); PR("Entry event: window id %d (index %d), state %d \n", winId, 0 , state); } void idleFunc(void) { int i; if (!leftDown && !middleDown) rotationAngle += 1; glutSetWindow(winId); glutPostRedisplay(); } void drawScene(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); /* printf("drawScene for index %d, id %d\n", winIndex, glutGetWindow()); */ glPushMatrix(); glLineWidth(lineWidth); if (backdrop) glCallList(100); /* Left button spinning */ trackBall(APPLY, 0, 0, 0, 0); /* Apply continuous spinning */ glRotatef(rotationAngle, 0, 1, 0); glCallList(shapeId) ; if(editMode){ switch(shapeId){ case 1: // the curve c.point(u,v,5,Color(255,0,0)) ; break ; default: // the surface s.point(u,v,5,Color(255,0,0)) ; } } glPopMatrix(); glutSwapBuffers(); if(animation) glutIdleFunc(idleFunc); else glutIdleFunc(NULL); } /*void visible(int state) { if (animation) glutIdleFunc(idleFunc); else glutIdleFunc(NULL); } */ void reshapeFunc(int width, int height) { int winId; float aspect; winId = glutGetWindow(); PR("reshape callback for window id %d \n", winId); glViewport(0, 0, width, height); aspect = (float) width / height; glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(40.0, aspect, 1.0, 20.0); glMatrixMode(GL_MODELVIEW); } void addCallbacks(void) { glutDisplayFunc(drawScene); //glutVisibilityFunc(visible); glutReshapeFunc(reshapeFunc); glutKeyboardFunc(keyFunc); // glutSpecialFunc(specialFunc); glutMouseFunc(mouseFunc); glutMotionFunc(motionFunc); } int main(int argc, char **argv){ glutInit(&argc, argv); /* Set initial display mode */ int displayMode = GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH; glutInitDisplayMode(displayMode); if (!glutGet(GLUT_DISPLAY_MODE_POSSIBLE)){ Error err("testing OpenGL for NURBS"); err << "This display mode is not supported\n"; err.warning() ; } int index = 0 ; glutInitWindowPosition(50, 150) ; glutInitWindowSize(400,400); winId = glutCreateWindow("Testing OpenGL support"); //PR("Window %d id = %d \n", index, winId); gfxInit(index); addCallbacks(); char str[99] ; sprintf(str, "window %d (RGB)", index); glutSetWindowTitle(str); sprintf(str, "icon %d", index); glutSetIconTitle(str); //glutSetMenu(menu1); //glutAttachMenu(GLUT_RIGHT_BUTTON); glutIdleFunc(idleFunc); glutMainLoop(); return 0 ; } #else #include int main(){ cout << "This test requires OpenGL (or Mesa) support.\n" ; return 0 ; } #endif