PDA

View Full Version : Problems with Picking objects



Kumar K
05-11-2004, 09:49 PM
iam using openGL GL_SELECT mode to select the objects on the screen , iam facing some problems while picking objects , i will attach my code below here ,plz find out where is problem and can any one help me how to manage the selection mechanism.
Thanks
kumar

MY code :-

/********* DRAW PART ************/
// Called to draw scene
void RenderScene(void)
{
// Clear the window with current clearing color
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

// Save the matrix state and do the rotations
glMatrixMode(GL_MODELVIEW);
glPushMatrix();

// Translate the whole scene out and into view
glTranslatef(0.0f, 0.0f, -300.0f);
glRotatef(xAngle,1.0,1.0,0.0);

// Initialize the names stack
glInitNames();
glPushName(0);

// Draw the Earth
glPushMatrix();
glRGB(0,0,255);
glTranslatef(-100.0f,0.0f,0.0f);
glLoadName(EARTH);
glutSolidSphere(30.0f, 15, 15);

// Draw the Moon
glTranslatef(45.0f, 0.0f, 0.0f);
glRGB(220,220,220);
glPushName(MOON1);
glutSolidSphere(5.0f, 15, 15);
glPopName();
glPopMatrix();

// Draw Mars
glRGB(255,0,0);
glPushMatrix();
glTranslatef(100.0f, 0.0f, 0.0f);
glLoadName(MARS);
glutSolidSphere(20.0f, 15, 15);

// Draw Moon1
glTranslatef(-40.0f, 40.0f, 0.0f);
glRGB(220,220,220);
glPushName(MOON1);
glutSolidSphere(5.0f, 15, 15);
glPopName();

// Draw Moon2
glTranslatef(0.0f, -80.0f, 0.0f);
glPushName(MOON2);
glutSolidSphere(5.0f, 15, 15);
glPopName();
glPopMatrix();

glPushMatrix();
glTranslatef(0.0f, 0.0f, 40.0f);
glColor3f(1.0f,1.0f,0.0f);
glLoadName(WALL);
glBegin(GL_POLYGON);
glVertex3f(0.0f,0.0f,0.0f);
glVertex3f(0.0f,80.0f,0.0f);
glVertex3f(80.0f,80.0f,0.0f);
glVertex3f(80.0f,0.0f,0.0f);
glEnd();
glPopMatrix();



// Restore the matrix state
glPopMatrix(); // Modelview matrix

glutSwapBuffers();
}

/****** MOUSE FUNC *********/

// Process the mouse click
void MouseCallback(int button, int state, int x, int y)
{
if(button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
ProcessSelection(x, y);
}

/******** process fucntion *********/

// Process the selection, which is triggered by a right mouse
// click at (xPos, yPos).
#define BUFFER_LENGTH 64

void ProcessSelection(int xPos, int yPos)
{
// Space for selection buffer
GLuint selectBuff[BUFFER_LENGTH];

// Hit counter and viewport storeage
GLint hits, viewport[4];

// Setup selection buffer
glSelectBuffer(BUFFER_LENGTH, selectBuff);

// Get the viewport
glGetIntegerv(GL_VIEWPORT, viewport);

// Switch to projection and save the matrix
glMatrixMode(GL_PROJECTION);
glPushMatrix();

// Change render mode
glRenderMode(GL_SELECT);

// Establish new clipping volume to be unit cube around
// mouse cursor point (xPos, yPos) and extending two pixels
// in the vertical and horzontal direction. Remember OpenGL specifies the
// y coordinate from the bottom, Windows from the top. So windows position
// (as measured from the top) subtract the height and you get it in terms
// OpenGL Likes.
glLoadIdentity();
gluPickMatrix(xPos, viewport[3] - yPos, 2,2, viewport);

// Apply perspective matrix
gluPerspective(45.0f, fAspect, 1.0, 425.0);

// Draw the scene
RenderScene();

// Collect the hits
hits = glRenderMode(GL_RENDER);

// If a single hit occured, display the info.
if(hits == 1)
ProcessPlanet(selectBuff);

// Restore the projection matrix
glMatrixMode(GL_PROJECTION);
glPopMatrix();

// Go back to modelview for normal rendering
glMatrixMode(GL_MODELVIEW);
}

/********* display picked info ********/
// Parse the selection buffer to see which planet/moon was selected
void ProcessPlanet(GLuint *pSelectBuff)
{
int id,count;
char cMessage[64];

// How many names on the name stack
count = pSelectBuff[0];

// Bottom of the name stack
id = pSelectBuff[3];

// Select on earth or mars, whichever was picked
switch(id)
{
case EARTH:
strcpy(cMessage,"You clicked Earth.");

// If there is another name on the name stack,
// then it must be the moon that was selected
// This is what was actually clicked on
if(count == 2)
strcat(cMessage,"\nSpecifically the moon.");

break;

case MARS:
strcpy(cMessage,"You clicked Mars.");

// We know the name stack is only two deep. The precise
// moon that was selected will be here.
if(count == 2)
{
if(pSelectBuff[4] == MOON1)
strcat(cMessage,"\nSpecifically Moon #1.");
else
strcat(cMessage,"\nSpecifically Moon #2.");
}
break;
case WALL :
strcpy(cMessage," You clicked WALL");
break;

// If nothing was clicked we shouldn't be here!
default:
strcpy(cMessage,"Error - Nothing was clicked on!");
break;
}

// Display the message about planet and moon selection
MessageBox(NULL,cMessage,"Selection Message",MB_OK);
}

mikael_aronsson
05-11-2004, 10:08 PM
Hi !

Could you specify what kind of problems you have ?

The code look's ok to me, but you only display a hit if the hit count is 1, and you use glPushName to put the names on the stack (multiple names will be placed there), is this what you intend yo do ?

Mikael