PDA

View Full Version : Problem with selection



Mighty
04-14-2004, 09:11 AM
Having a problem with selection of objects.

Ultimately, I want to be able to right-click on an object, which results in pop up messagewindow with a list of moves the object can make (checkers prog)

I thought I had a pretty good understanding of how selection works (via select_mode). However, I'm not getting any results.


int RetrieveObjectID(int x, int y)
{
int objectsFound = 0; // This will hold the amount of objects clicked
int viewportCoords[4] = {0}; // We need an array to hold our view port coordinates

// This will hold the ID's of the objects we click on.
unsigned int selectBuffer[32] = {0};

// glSelectBuffer is what we register our selection buffer with. The first parameter
// is the size of our array. The next parameter is the buffer to store the information found.
// More information on the information that will be stored in selectBuffer is further below.
glSelectBuffer(32, selectBuffer); // Setup our selection buffer to accept object ID's

// This function returns information about many things in OpenGL. We pass in GL_VIEWPORT
// to get the view port coordinates. It saves it like a RECT with {top, left, bottom, right}

glGetIntegerv(GL_VIEWPORT, viewportCoords); // Get the current view port coordinates

// Now we want to get out of our GL_MODELVIEW matrix and start effecting our
// GL_PROJECTION matrix. This allows us to check our X and Y coords against 3D space.

glMatrixMode(GL_PROJECTION); // We want to now effect our projection matrix

glPushMatrix(); // We push on a new matrix so we don't effect our 3D projection

glRenderMode(GL_SELECT); // Allows us to render the objects, but not change the frame buffer

glLoadIdentity(); // Reset our projection matrix

gluPickMatrix(x, viewportCoords[3] - y, 2, 2, viewportCoords);
cout<< x << " x value, " << viewportCoords[3] - y << " y value, "<< 2 << " " << 2 <<endl;

// Next, we just call our normal gluPerspective() function, exactly as we did on startup.
// This is to multiply the perspective matrix by the pick matrix we created up above.

gluPerspective(45.0f,(float)g_rRect.right/(float)g_rRect.bottom,1.0f,300.0f);

glMatrixMode(GL_MODELVIEW); // Go back into our model view matrix

glutDisplay(); // Now we render into our selective mode to pinpoint clicked objects

objectsFound = glRenderMode(GL_RENDER); // Return to render mode and get the number of objects found

glMatrixMode(GL_PROJECTION); // Put our projection matrix back to normal.

glPopMatrix(); // Stop effecting our projection matrix

glMatrixMode(GL_MODELVIEW); // Go back to our normal model view matrix

if (objectsFound > 0)
{
// Set the lowest depth to the first object to start it off.
// 1 is the first object's minimum Z value.
// We use an unsigned int so we don't get a warning with selectBuffer below.
unsigned int lowestDepth = selectBuffer[1];

// Set the selected object to the first object to start it off.
// 3 is the first object's object ID we passed into glLoadName().
int selectedObject = selectBuffer[3];

// Go through all of the objects found, but start at the second one
for(int i = 1; i < objectsFound; i++)
{
// Check if the current objects depth is lower than the current lowest
// Notice we times i by 4 (4 values for each object) and add 1 for the depth.
if(selectBuffer[(i * 4) + 1] < lowestDepth)
{
// Set the current lowest depth
lowestDepth = selectBuffer[(i * 4) + 1];

// Set the current object ID
selectedObject = selectBuffer[(i * 4) + 3];
}
}

// Return the selected object
return selectedObject;
}

// We didn't click on any objects so return 0
return 0;
} This was from an example on the internet.
Its called from the GlutMouse function.
Also here's the display function i use


void glutDisplay(void)
{
glDisable(GL_LIGHTING);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glClearColor(1.0,1.0,1.0,1.0);


if (wireframe)
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
else
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);


glPushMatrix();

/* translate camera to the coordinates provided by eye array */
glTranslatef (-eye[0], -eye[1], -eye[2]);

/* rotates the screen by the angles provided by rot array */
glRotatef(rot[0], 1.0f, 0.0f, 0.0f);
glRotatef(rot[1], 0.0f, 1.0f, 0.0f);
glRotatef(rot[2], 0.0f, 0.0f, 1.0f);

glBindTexture(GL_TEXTURE_2D, g_TexturesArray[0]);

//**** Call display list for checker board
glCallList(displayLists);

glPopMatrix();


for(int i = 0; i < 12; i++)
{


if(Piece_Alive[1][i] == true)
{
double dimX, dimY;

glPushName(i + 100);
glPushMatrix();

/* translate camera to the coordinates provided by eye array */
glTranslatef (-eye[0], -eye[1], -eye[2]);

/* rotates the screen by the angles provided by rot array */
glRotatef(rot[0], 1.0f, 0.0f, 0.0f);
glRotatef(rot[1], 0.0f, 1.0f, 0.0f);
glRotatef(rot[2], 0.0f, 0.0f, 1.0f);
// We translate the cylinder over by half of it's length so it's centered on the screen
glColor3f(0.1f,0.1f,0.1f);
getCoordinateValues(dimX, dimY, Piece_CoordinateX[i], Piece_CoordinateY[i]);
// cout << dimX << " x value "<< dimY <<" y value "<<endl;
glTranslatef(dimX - 1, 1.11, dimY +.25); // Move the cylinder over so it's centered around (0, 0, 0)
glRotatef(90, 1.0f, 0.0f, 0.0f);
glCallList(displayLists + 1);

glPopMatrix();
glPopName();
}
}

for(int j = 12; j < 24; j++)
{


if(Piece_Alive[0][j] == true)
{
double dimX, dimY;
glPushName(j + 100);
glPushMatrix();

/* translate camera to the coordinates provided by eye array */
glTranslatef (-eye[0], -eye[1], -eye[2]);

/* rotates the screen by the angles provided by rot array */
glRotatef(rot[0], 1.0f, 0.0f, 0.0f);
glRotatef(rot[1], 0.0f, 1.0f, 0.0f);
glRotatef(rot[2], 0.0f, 0.0f, 1.0f);
// We translate the cylinder over by half of it's length so it's centered on the screen
glColor3f(1.0f,0.0f,0.0f);
getCoordinateValues(dimX, dimY, Piece_CoordinateX[j], Piece_CoordinateY[j]);
// cout << dimX << " x value "<< dimY <<" y value "<<endl;
glTranslatef(dimX - 1, 1.11, dimY - 2.25); // Move the cylinder over so it's centered around (0, 0, 0)
glRotatef(90, 1.0f, 0.0f, 0.0f);
glCallList(displayLists + 1);

glPopMatrix();
glPopName();
}
}

CalculateFrameRate();

glFlush();
glutSwapBuffers();

} My only guesses of whats wrong is maybe my selection buffer is too small, I read somewhere that it holds all kinds of info on objects and I have 24 pieces which are to be selected. Also would the transformations I do before created the object have anything do with it?

plasmonster
04-14-2004, 04:06 PM
Make sure that somewhere in your program you have
some code to initialize selection:




const int bufferSize = 1024;
uint buffer[bufferSize];

glSelectBuffer( bufferSize , buffer );
glRenderMode( GL_SELECT );
glInitNames();You need this before picking can begin; when you clear the screen, for example.

Another area that can be problematic is the selection rectangle itself. Your code looks ok, but for santity, I draw the selection rect on
the screen so I can verify that it is where I think it is.
You posted alot of code, perhaps I missed sometihng else...

Mighty
04-14-2004, 08:10 PM
Actually, I don't think I quite fully understand this part of the code.


glMatrixMode(GL_PROJECTION);
glPushMatrix();
glRenderMode(GL_SELECT);
glLoadIdentity();
gluPickMatrix(x, viewportCoords[3] - y, 2, 2, viewportCoords);
gluPerspective(45.0f,(float)g_rRect.right/(float)g_rRect.bottom,1.0f,300.0f);
I understand it's switching to the Projection Matrix, which as I understand projects the 3-d dimensional into a 2D space. Then pushing the current matrix in place. Loading an identity matrix, but I don't quite get the gluPickMatrix() part which i assume creates the new matrix. Does it multiply the Identity or whatever matrix is in use? Understanding this would help me make the bounding square (btw good idea). Any explanations?