In this post I want to share an easy implementation of picking through unProject method. The demo is realized in C, so we have only the main.cpp file and vector3.h file. In the demo we have a cube in the center of the scene, when we click on the cube, the cube changes its color.
If you open the main.cpp source file you can note the following lines of code:
GLdouble posX, posY, posZ;
GLdouble cubeX=0,cubeY=0.5,cubeZ=0;
GLdouble cubeSize=1.f;
bool cubePicked;
The variables posX,posY and posZ give us the unproject mouse click coordinates.
The variables cubeX,cubeY and cubeZ save the cube position.
The variable cubSize set the size of the cube;
The boolean variable cubePick is true when the cube is clicked;
When we click in the scene, the unProject method is called:
void unProject(){
GLint viewport[4]; // Where The Viewport Values Will Be Stored
glGetIntegerv(GL_VIEWPORT, viewport); // Retrieves The Viewport Values (X, Y, Width, Height)
GLdouble modelview[16]; // Where The 16 Doubles Of The Modelview Matrix Are To Be Stored
glGetDoublev(GL_MODELVIEW_MATRIX, modelview); // Retrieve The Modelview Matrix
GLdouble projection[16]; // Where The 16 Doubles Of The Projection Matrix Are To Be Stored
glGetDoublev(GL_PROJECTION_MATRIX, projection); // Retrieve The Projection Matrix
GLfloat winX, winY, winZ; // Holds Our X, Y and Z Coordinates
winX = (float)mouse2D.x; // Holds The Mouse X Coordinate
winY = (float)mouse2D.y; // Holds The Mouse Y Coordinate
glReadPixels(winX, winY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ);
gluUnProject( winX, winY, winZ, modelview, projection, viewport, &posX, &posY, &posZ);
//ROUND 2 DECIMAL
posX= ((int)(posX * 10 + .5) / 10.0);
posY= ((int)(posY * 10+ .5) / 10.0);
posZ= ((int)(posZ * 10 + .5) / 10.0);
}
the method saves posX,posY and posZ variables. After the pickingCheck method is called:
void pickingCheck(){
cubePicked=false;
if( posX>=cubeX-(cubeSize/2) && posX<=cubeX+(cubeSize/2)){
if( posY>=cubeY-(cubeSize/2) && posY<=cubeY+(cubeSize/2) ){
if( posZ>=cubeZ-(cubeSize/2) && posZ<=cubeZ+(cubeSize/2)){
cubePicked=true;
}
}
}
}
the method checks the posX,posY,posZ range values. If this values are inside the cube, the cube is picked.
Download the code from here:
Sources