#include class Polygon { protected: GLfloat x, y; GLfloat *color; GLint id; public: Polygon(GLfloat x, GLfloat y, GLfloat *c, GLint id) { this->x = x; this->y = y; this->id=id; color=c; }; void setXY( GLfloat x, GLfloat y) { this->x = x; this->y = y; } virtual void draw(GLenum mode) abstract {}; }; class Triangle : public Polygon { public: Triangle(GLfloat x, GLfloat y, GLfloat *color, GLint id) : Polygon(x, y, color, id){ }; virtual void draw(GLenum mode) { if( mode == GL_SELECT) glLoadName(id); glColor3fv(color); glBegin(GL_POLYGON); glVertex2f(x-1.5, y-1.5); glVertex2f(x+1.0, y+1.0); glVertex2f(x+1.5, y+0.5); glEnd(); } }; class Rectangle : public Polygon { public: Rectangle(GLfloat x, GLfloat y, GLfloat *color, GLint id) : Polygon(x, y, color, id){ }; virtual void draw(GLenum mode) { if( mode == GL_SELECT) glLoadName(id); glColor3fv(color); glRectf(x-0.5, y-0.5, x+0.5, y+0.5); } }; #define TRIANGLE 6 #define RECTANGLE 9 Triangle *triangle; Rectangle *rectangle; Polygon *object; double d2w( int d ) { return (d/500.0)*4.0-2.0; } void display() { glClear(GL_COLOR_BUFFER_BIT); triangle->draw(GL_RENDER); rectangle->draw(GL_RENDER); glFlush(); } /* processHits */ void processHits (GLint hits, GLuint buffer[], int x, int y) { unsigned int i, j; GLuint *ptr; ptr = (GLuint *) buffer+3; if(hits == 0) return; switch (*ptr) { case TRIANGLE : object = triangle; break; case RECTANGLE : object = rectangle; } } #define SIZE 8 void click( int x, int y ) { GLuint selectBuf[SIZE]; GLint hits; GLint viewport[4]; glGetIntegerv (GL_VIEWPORT, viewport); glSelectBuffer (SIZE, selectBuf); glRenderMode(GL_SELECT); glInitNames(); glPushName(0); glMatrixMode (GL_PROJECTION); glPushMatrix (); glLoadIdentity (); /* create 5x5 pixel picking region near cursor location */ gluPickMatrix ((GLdouble) x, (GLdouble) (viewport[3] - y), 5.0, 5.0, viewport); gluOrtho2D (-2.0, 2.0, -2.0, 2.0); triangle->draw(GL_SELECT); rectangle->draw(GL_SELECT); glMatrixMode (GL_PROJECTION); glPopMatrix (); glFlush (); hits = glRenderMode (GL_RENDER); processHits (hits, selectBuf, x, y); glutPostRedisplay(); } void mouse(int button, int state, int x, int y) { if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) click(x, y); } void motion(int x, int y){ object->setXY(d2w(x), d2w(500-y)); glutPostRedisplay(); } void reshape(int w, int h) { glViewport(0, 0, w, h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D (-2.0, 2.0, -2.0, 2.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } int main(int argc, char** argv) { GLfloat red[] = {1.0,0.0,0.0}, blue[]={0.0,0.0,1.0}; triangle = new Triangle(0,0,red, TRIANGLE); rectangle = new Rectangle(0,0,blue, RECTANGLE); glutInit(&argc, argv); glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB); glutInitWindowSize (500, 500); glutInitWindowPosition (0, 0); glutCreateWindow ("Carry"); glClearColor (0.0, 0.0, 0.0, 0.0); glutReshapeFunc (reshape); glutDisplayFunc(display); glutMouseFunc (mouse); glutMotionFunc (motion); glutMainLoop(); }