/* File: glutdemo2d.cpp Author: J.K. Johnstone Created: 5 January 2004, from interpolate.cpp Last Modified: 5 January 2004 Purpose: An illustration of an OpenGL/GLUT program. Input: None History: 1/5/04: Extracted code from interpolate.cpp (CVS allows history to be ignored) */ #include #include #include #include #include #include #include #include using std::string; #include #define WINDOWS 0 // running under Windows? static char *RoutineName; static void usage() { cout << "Usage is " << RoutineName << endl; cout << "\t[-p] (colour square hot pink rather than red)" << endl; cout << "\t[-h] (this help message)" << endl; } static GLfloat transxob, transyob, zoomob; static GLboolean leftMouseDown=0; static GLboolean middleMouseDown=0; static GLboolean firstx=1,firsty=1; // first MOUSEX (MOUSEY) reading? static int oldx,oldy; // previous value of MOUSEX and MOUSEY static GLboolean DRAWHOTPINK=0; // shall we draw square hot pink? static GLboolean DRAWSQUARE=1; // draw square? static GLboolean DRAWVERT=0; // draw vertices of square? static GLboolean LABELVERT=0; // number the vertices? float pt[4][2] = {{0,0},{1,0},{1,1},{0,1}}; int win; // window identifier float Red[3] = {1,0,0}; float HotPink[3] = {1, 0.411765, 0.705882}; float Grey[3] = {0.745098, 0.745098, 0.745098}; /******************************************************************************/ /******************************************************************************/ void gfxinit(void) { glClearColor (1.0, 1.0, 1.0, 1.0); glEnable (GL_BLEND); glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable (GL_LINE_SMOOTH); glHint (GL_LINE_SMOOTH_HINT, GL_FASTEST); glEnable (GL_POINT_SMOOTH); glHint (GL_POINT_SMOOTH_HINT, GL_FASTEST); glPointSize (6.0); transxob = transyob = 0.0; zoomob = 1.0; } /******************************************************************************/ /******************************************************************************/ void reshape(GLsizei w, GLsizei h) { glViewport(0, 0, w, h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D (-2.0*(GLfloat)w/(GLfloat)h, 2.0*(GLfloat)w/(GLfloat)h, -2.0, 2.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } /******************************************************************************/ /******************************************************************************/ void visibility (int status) { if (status != GLUT_VISIBLE) glutIdleFunc (NULL); } /******************************************************************************/ /******************************************************************************/ void mouse (int button, int state, int x, int y) { switch (button) { case GLUT_LEFT_BUTTON: switch (state) { case GLUT_DOWN: leftMouseDown = firstx = firsty = 1; glutSetCursor (GLUT_CURSOR_UP_DOWN); break; case GLUT_UP: leftMouseDown = 0; glutSetCursor (GLUT_CURSOR_INHERIT); break; default: break; } break; case GLUT_MIDDLE_BUTTON: switch (state) { case GLUT_DOWN: middleMouseDown = firstx = firsty = 1; glutSetCursor (GLUT_CURSOR_CYCLE); break; case GLUT_UP: middleMouseDown = 0; glutSetCursor (GLUT_CURSOR_INHERIT); break; default: break; } break; default: break; } } /******************************************************************************/ /******************************************************************************/ void motionob (int x, int y) { if (leftMouseDown && !middleMouseDown) { if (firstx) firstx=0; else zoomob -= (float).01*(x-oldx); if (zoomob < 0.0) zoomob = 0.0; } else if (leftMouseDown && middleMouseDown) { if (firstx) firstx=0; else transxob += .01*(x-oldx); /* TRANSLATION: X */ if (firsty) firsty=0; else transyob += .01*(y-oldy); /* TRANSLATION: Y */ } oldx = x; oldy = y; glutPostRedisplay(); } /******************************************************************************/ /******************************************************************************/ void keyboard (unsigned char key, int x, int y) { switch (key) { case 27: exit(1); break; // ESCAPE case 's': DRAWSQUARE = !DRAWSQUARE; break; case 'v': DRAWVERT = !DRAWVERT; break; case 'a': LABELVERT = !LABELVERT; break; default: break; } glutPostRedisplay(); } /******************************************************************************/ /******************************************************************************/ void menuOb (int value) { switch (value) { case 0: DRAWSQUARE = !DRAWSQUARE; break; case 1: DRAWVERT = !DRAWVERT; break; case 2: LABELVERT = !LABELVERT; break; default: break; } glutPostRedisplay(); } /************************************************************************** (No, I don't know why this isn't part of any existing library.) From Kernighan and Ritchie, 2nd ed., p. 62. **************************************************************************/ void reverse (char *s) { for (int i=0, j=strlen(s)-1; i0); // generate digits in reverse order if (sign<0) s[i++] = '-'; s[i] = '\0'; reverse(s); } /******************************************************************************/ /******************************************************************************/ void displayOb () { int i,j; glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix(); glTranslatef (transxob, transyob, 0); glScalef (zoomob, zoomob, zoomob); glPolygonMode (GL_FRONT_AND_BACK, GL_LINE); if (DRAWSQUARE) { glColor3fv (DRAWHOTPINK ? HotPink : Red); glBegin(GL_LINE_LOOP); for (i=0; i<4; i++) glVertex2fv (pt[i]); glEnd(); } if (DRAWVERT) { glColor3f (0,0,0); // black if (WINDOWS) // GL_POINTS does not work properly under Windows for (i=0; i<4; i++) { glBegin(GL_POLYGON); float x = pt[i][0], y = pt[i][1], eps = .01; glVertex2f (x+eps, y+eps); glVertex2f (x-eps, y+eps); glVertex2f (x-eps, y-eps); glVertex2f (x+eps, y-eps); glEnd(); } else { glBegin(GL_POINTS); for (i=0; i<4; i++) glVertex2f (pt[i][0], pt[i][1]); glEnd(); } } if (LABELVERT) { glColor3fv (Grey); char str[10]; for (i=0; i<4; i++) // label the vertices { glRasterPos2f (pt[i][0]+.01, pt[i][1]+.01); itoa (i, str); for (j=0; j 3) { usage(); exit(-1); } while (ArgsParsed < argc) { if ('-' == argv[ArgsParsed][0]) switch (argv[ArgsParsed++][1]) { case 'p': DRAWHOTPINK=1; break; case 'h': default: usage(); exit(-1); break; } else ArgsParsed++; } /************************************************************/ glutInit (&argc, argv); glutInitDisplayMode (GLUT_RGB | GLUT_DOUBLE); int xleft; // x-coord of lefthand side int titleht; // top titlebar height int xsize,ysize; // window size if (WINDOWS) { xleft = 0; xsize = 500; ysize = 500; titleht = 12; } else { xleft = 0; xsize = ysize = 600; titleht = 20; } glutInitWindowPosition (xleft,titleht); glutInitWindowSize (xsize,ysize); char titlebar[100]; strcpy (titlebar, "A demo of OpenGL/GLUT"); win = glutCreateWindow (titlebar); glutDisplayFunc (displayOb); glutKeyboardFunc (keyboard); glutMouseFunc (mouse); glutMotionFunc (motionob); glutVisibilityFunc (visibility); glutReshapeFunc (reshape); gfxinit(); glutCreateMenu (menuOb); glutAddMenuEntry ("Square [s]", 0); glutAddMenuEntry ("Vertices [v]", 1); glutAddMenuEntry ("Labels [a]", 2); glutAttachMenu (GLUT_RIGHT_BUTTON); glutMainLoop(); return 0; }