Hey guys,
I have followed NeHe's tutorial on selection / picking and have a problem.
It seem to work ok, in that I know I am clicking something, the problem is knowing what I have clicked.
Here is the code, with minimal changes :
int objectSelection(int mouseX, int mouseY) // This Is Where Selection Is Done
{
GLuint buffer[512]; // Set Up A Selection Buffer
GLint hits; // The Number Of Objects That We Selected
GLint hitID = 0;
if (gameOver) // Is Game Over?
return 0; // If So, Don't Bother Checking For Hits
// The Size Of The Viewport. [0] Is <x>, [1] Is <y>, [2] Is <length>, [3] Is <width>
GLint viewport[4];
// This Sets The Array <viewport> To The Size And Location Of The Screen Relative To The Window
glGetIntegerv(GL_VIEWPORT, viewport);
glSelectBuffer(512, buffer); // Tell OpenGL To Use Our Array For Selection
// Puts OpenGL In Selection Mode. Nothing Will Be Drawn. Object ID's and Extents Are Stored In The Buffer.
(void) glRenderMode(GL_SELECT);
glInitNames(); // Initializes The Name Stack
glPushName(0); // Push 0 (At Least One Entry) Onto The Stack
glMatrixMode(GL_PROJECTION); // Selects The Projection Matrix
glPushMatrix(); // Push The Projection Matrix
glLoadIdentity(); // Resets The Matrix
// This Creates A Matrix That Will Zoom Up To A Small Portion Of The Screen, Where The Mouse Is.
gluPickMatrix((GLdouble) clickXcoord, (GLdouble) (viewport[3] - clickYcoord), 1.0f, 1.0f, viewport);
// Apply The Perspective Matrix
gluPerspective(45.0f, (GLfloat) (viewport[2]-viewport[0])/(GLfloat) (viewport[3]-viewport[1]), 0.1f, 100.0f);
glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
//DrawTargets(); // Render The Targets To The Selection Buffer
DrawGLScene();
glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
glPopMatrix(); // Pop The Projection Matrix
glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
hits=glRenderMode(GL_RENDER); // Switch To Render Mode, Find Out How Many
// Objects Were Drawn Where The Mouse Was
if (hits > 0) // If There Were More Than 0 Hits
{
int choose = buffer[3]; // Make Our Selection The First Object
int depth = buffer[1]; // Store How Far Away It Is
for (int loop = 1; loop < hits; loop++) // Loop Through All The Detected Hits
{
// If This Object Is Closer To Us Than The One We Have Selected
if (buffer[loop*4+1] < GLuint(depth))
{
choose = buffer[loop*4+3]; // Select The Closer Object
depth = buffer[loop*4+1]; // Store How Far Away It Is
}
}
hitID = choose;
/*
if (!object[choose].hit) // If The Object Hasn't Already Been Hit
{
object[choose].hit=TRUE; // Mark The Object As Being Hit
score+=1; // Increase Score
kills+=1; // Increase Level Kills
if (kills>level*5) // New Level Yet?
{
miss=0; // Misses Reset Back To Zero
kills=0; // Reset Level Kills
level+=1; // Increase Level
if (level>30) // Higher Than 30?
level=30; // Set Level To 30 (Are You A God?)
}
}
*/
return hitID;
}
return 0;
}
Note: changes include, some variable names for the mouse co-ords,
the gameOver variable.
Then the code refering to object hits.
All I need is the object ID, which I think is 'choose' - and I want to assign this to 'hitID = choose;' and return it.
My DrawGLScene code :
glLoadName(100); // Push on our label (IMPORTANT)
// 3D SPHERE CENTER
glPushMatrix();
glColor3f(0.0f, 1.0f, 0.0f);
glTranslatef(0.0f, 0.0f, 0.0f);
Draw_Sphere();
glPopMatrix();
glLoadName(200); // Push on our label (IMPORTANT)
// 3D SPHERE LEFT
glPushMatrix();
glColor3f(1.0f, 0.0f, 0.0f);
glTranslatef(-10.0f, 5.0f, 0.0f);
Draw_Sphere();
glPopMatrix();
glLoadName(300); // Push on our label (IMPORTANT)
// 3D SPHERE RIGHT
glPushMatrix();
glColor3f(0.0f, 0.0f, 1.0f);
glTranslatef(10.0f, 5.0f, 0.0f);
Draw_Sphere();
glPopMatrix();
glLoadName(666); // Push on our label (IMPORTANT)
// render Cube
glPushMatrix();
glColor3f(1.0f, 1.0f, 1.0f);
glTranslatef(0.0f, 1.0f, 50.0f);
Draw_Box();
glPopMatrix();
// more objects
OK the problem comes when I click anything, the value returned is always the LAST ID assigned.
As in the code above 'glLoadName(666);' the value returned is always 666.
I expected that for any objects 'AFTER glLoadName(666);' because I don't care about those.
But clicking anything before that point, ie any of the spheres rendered all return 666.
Everything I have been reading suggests using glLoadName and not glPushName, as I have searched the forum, I just can't spot the problem.
Any ideas guys, THANKS ;-)
[Edited by - darren_mfuk on March 9, 2007 8:47:13 PM]
----------------------------------------Now just hit that link that says 'Rate This User' [wink]