#include "exp004mouse.h" #include "exp004processhits.h" #include "../view/exp004geometry.h" #include "../view/exp004state0.h" #include "../util/check_error.h" #include #include #define SIZE 500 #define N 3 void exp004mouse (int button, int state, int x, int y) { if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) { /* * "Specify the array to be used for the returned hit records * with glSelectBuffer () [Redbook]." */ GLuint select_buf[SIZE]; glSelectBuffer (SIZE, select_buf); /* * "Enter selection mode by specifying GL_SELECT with * glRenderMode () [Redbook]." */ glRenderMode (GL_SELECT); /* * "Initialize the name stack using glInitNames () and glPush * Names () [Redbook]." */ glInitNames (); glPushName (0); /* * "Define the viewing volume you want to use for selection. * Usually this is different from the viewing volume you * originally used to draw the scene, so you probably want to * save and then restore the current transformation state with * glPushMatrix () and glPopMatrix () [Redbook]." */ glMatrixMode (GL_PROJECTION); glPushMatrix (); glLoadIdentity (); GLint viewport[4]; glGetIntegerv (GL_VIEWPORT, viewport); gluPickMatrix ((GLdouble) x, (GLdouble) (viewport[3] - y), N, N, viewport); gluOrtho2D(exp004state0.ortho.min_x, exp004state0.ortho.max_x, exp004state0.ortho.min_y, exp004state0.ortho.max_y); /* * "Alternately issue primitive drawing commands and commands to * manipulate the name stack so that each primitive of interest * has appropriate names assigned [Redbook]." */ exp004geometry (GL_SELECT); glMatrixMode (GL_PROJECTION); glPopMatrix (); glutSwapBuffers (); /* * "Exit selection mode and process the returned selection data * (the hit records) [Redbook]." */ GLint hits = glRenderMode (GL_RENDER); check_error (__FILE__, __LINE__); /* "process hits from selection mode rendering [Angel,2008]." */ exp004processhits (hits, select_buf); /* "normal render [Angel,2008]." */ glutPostRedisplay (); } return; }