/************************************************************************ File: simple3.cpp Author: Michael L Gleicher, gleicher@cs.wisc.edu Modifier Yu-Chi Lai, yu-chi@cs.wisc.edu Comment: written 10/16/99, Michael L Gleicher For demoing the basic operation in OpenGL - do picking Platform: Visio Studio.Net 2003 *************************************************************************/ #include #include #include #include #include // for pick matrix #include #include #include // make a Gl window that draws something: class MyGlWindow : public Fl_Gl_Window { public: int selected; MyGlWindow(int x, int y, int w, int h) : Fl_Gl_Window(x,y,w,h,"My GL Window") { selected = 0; } private: // for clarity, we break the draw routine into 3 pieces void draw() { // the draw method must be private drawClear(); drawSetupTransform(); drawObjects(); }; // clear the screen and the projection transformation void drawClear() { glMatrixMode(GL_PROJECTION); // set up coord system glLoadIdentity(); // reset it glClearColor(0,0,0,0); // clear the window to black glClear(GL_COLOR_BUFFER_BIT); // clear the window } // notice that this doesn't reset the projection! // it must be that way so that picking can use it void drawSetupTransform() { glOrtho(-1,1,-1,1,-1,1); // set it to be -1 to 1 in each axis }; // draw 4 rectangles // notice that they each have "names" for picking // if the rectangle is selected, draw it in a different color void drawObjects() { // we don't assume that we're in the right matrix mode glMatrixMode(GL_MODELVIEW); // back to normal mode glLoadIdentity(); // clear what anyone else did // rectangle 1 glLoadName(1); if (selected == 1) glColor3f(1,0,0); else glColor3f(1,1,0); glRectd(-.7,-.7,-.3,-.3); // draw a filled rectangle // rectangle 2 glLoadName(2); if (selected == 2) glColor3f(1,0,0); else glColor3f(1,1,0); glRectd(.7,-.7,.3,-.3); // draw a filled rectangle // rectangle 3 glLoadName(3); if (selected == 3) glColor3f(1,0,0); else glColor3f(1,1,0); glRectd(-.7,.7,-.3,.3); // draw a filled rectangle // rectangle(4) glLoadName(4); if (selected == 4) glColor3f(1,0,0); else glColor3f(1,1,0); glRectd(.7,.7,.3,.3); // draw a filled rectangle }; // // handle events - basically, ignore everything except a mouse // push event. use that to select a rectangle // because this is a window, we must respond to the show event // otherwise we'll never get shown if we're a subwindow int handle(int e) { if (e==FL_PUSH) { int mx = Fl::event_x(); int my = Fl::event_y(); // do picking make_current(); // so we're drawing in our window // set up a special coordinate system centered at the mouse // remember, FlTk and Gl have opposite Y directions glMatrixMode(GL_PROJECTION); // set up special coordinate system glLoadIdentity(); // we need the size of the OpenGL window, in its own terms int viewport[4]; glGetIntegerv(GL_VIEWPORT, viewport); gluPickMatrix((double)mx, (double)(viewport[3]-my), 5, 5, viewport); drawSetupTransform(); // so object appear in right place // set up for picking - make a place to put the results GLuint buf[100]; glSelectBuffer(100,buf); glRenderMode(GL_SELECT); glInitNames(); glPushName(0); // now draw (but nothing is really drawn); drawObjects(); // go back to drawing mode, and see how picking did int hits = glRenderMode(GL_RENDER); printf("Hit %d objects\n!",hits); selected = 0; // all we care about is the first hit - see the book for // info on how to get the other info in the hit record if (hits) { printf(" the first hit had %d names [%d was first]\n",buf[0],buf[3]); selected = buf[3]; } damage(1); return 1; } if (e==FL_SHOW) { show(); return 1; } return 0; }; }; // the main routine makes the window, and then runs an even loop // until the window is closed main() { Fl_Double_Window* wind = new Fl_Double_Window(100,100,300,300,"GL Picking Sample"); wind->begin(); // put widgets inside of the window MyGlWindow* gl = new MyGlWindow(10,10,280,280); wind->end(); wind->show(); // this actually opens the window Fl::run(); delete wind; return 1; }