/* simple example of code for picking in 3d - prints the "name" of the object hit - either cone= 4 or cyl=4 ZJ Wood */ #include #include #include #include #include #include #define CONE 4 #define CYL 3 #define DRAW 1 #define SELECT 2 #define BUFSIZE 512 #define BASE_HEIGHT 2.0 #define BASE_RADIUS 1.5 #define CONE_HEIGHT 4.0 /*globals for picking, etc. */ GLuint selectBuf[BUFSIZE]; float pickbuf; int mouseX, mouseY; float fov; int GW, GH; typedef struct Vector3 { float x; float y; float z; Vector3() : x(0), y(0), z(0) {} } Vector3; Vector3 eye, la; GLUquadricObj *b; /* pointer to quadric object */ GLUquadricObj *t; /* pointer to quadric object */ /*forward function declaration */ void processHits(GLint hits, GLuint buffer[]); void draw_objs(); //globals for lighting GLfloat light_pos0[4] = {0.0, 1.0, 1.0, 0.0}; GLfloat light_diff0[4] = {0.7, 0.7, 0.7, 1.0}; GLfloat light_spec0[4] = {0.6, 0.6, 0.6, 1.0}; GLfloat light_amb0[4] = {0.3, 0.3, 0.3, 1.0}; //playing with materials typedef struct materialStruct { GLfloat ambient[4]; GLfloat diffuse[4]; GLfloat specular[4]; GLfloat shininess[1]; } materialStruct; materialStruct brownMaterials = { {0.1, 0.1, 0.0, 1.0}, {0.6, 0.6, 0.0, 1.0}, {0.3, 0.3, 0.0,1.0}, {0.0} }; materialStruct DarkPMaterials = { {0.2, 0.00, 0.2, 1.0}, {0.1, 0.0, 0.1, 1.0}, {0.1, 0.0, 0.1, 1.0}, {0} }; materialStruct BlackMaterials = { {0.0, 0.0, 0, 1.0}, {0.0, 0.0, 0.0, 1.0}, {0.0, 0.0, 0.0, 1.0}, {100.0} }; //sets up a specific material void materials(materialStruct materials) { glMaterialfv(GL_FRONT, GL_AMBIENT, materials.ambient); glMaterialfv(GL_FRONT, GL_DIFFUSE, materials.diffuse); glMaterialfv(GL_FRONT, GL_SPECULAR, materials.specular); glMaterialfv(GL_FRONT, GL_SHININESS, materials.shininess); } //initialization calls for opengl for static light void init_lighting() { glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glLightfv(GL_LIGHT0, GL_POSITION, light_pos0); glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diff0); glLightfv(GL_LIGHT0, GL_SPECULAR, light_spec0); glLightfv(GL_LIGHT0, GL_AMBIENT, light_amb0); glShadeModel(GL_SMOOTH); glEnable(GL_NORMALIZE); } void pos_light() { //set the light's position glMatrixMode(GL_MODELVIEW); glLightfv(GL_LIGHT0, GL_POSITION, light_pos0); } /*routine to set up for picking */ void DoPicking() { int hits; GLint viewport[4]; //get values on the size of the viewport glGetIntegerv(GL_VIEWPORT,viewport); glSelectBuffer(BUFSIZE,selectBuf); //set the mode glRenderMode(GL_SELECT); //initialize the namestack glInitNames(); //load a junk name to start glPushName(0xffffffff); //store the current viewing as we'll modify it for picking glMatrixMode(GL_PROJECTION); glPushMatrix(); //clear the top of the stack for picking projection glLoadIdentity(); //set up projection such that the pixel picking region is near the mouse gluPickMatrix((GLdouble)mouseX,(GLdouble)viewport[3]-mouseY,pickbuf, pickbuf,viewport); //set up projection - should match what is called in reshape gluPerspective(fov, (float)GW/GH, 1, 20); //return to model matrix glMatrixMode(GL_MODELVIEW); glPushMatrix(); //draw the objects gluLookAt(eye.x, eye.y, eye.z, la.x, la.y, la.z, 0, 1,0); draw_objs(); glPopMatrix(); // restoring the original projection matrix glMatrixMode(GL_PROJECTION); glPopMatrix(); //return to model matrix glMatrixMode(GL_MODELVIEW); glFlush(); // returning to normal rendering mode - check if we have any hits hits = glRenderMode(GL_RENDER); printf("number of hits %i\n", hits); // if there are hits process them if (hits != 0) processHits(hits,selectBuf); } /*process the hits from picking - format of the picking array are nitem, zmin, zmax, list of names on the name stack when the pick happened...*/ void processHits(GLint hits, GLuint buffer[]) { int i; unsigned int j; GLuint names, *ptr; ptr = (GLuint *) buffer; //go through the hit list and print the names of the objects hit for (i = 0; i < hits; i++) { names = *ptr; //advance the pointer to the 4th element in the array (because we are in 2d no zmin/zmax) ptr = ptr+3; printf("the name of the object(s) hit: "); for (j = 0; j