Jump to content
  • Advertisement
Sign in to follow this  

picking problem...

This topic is 4731 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, I have a problem with picking. I'll trie to discribe my situation : I have a set of display lists generated, in a 'display' function I do each time this void GlScene::displayScene(){ for(uint i = 0; i < m_widgets_to_display.size(); i++){ glPushName(m_widgets_to_display.elementAt(i)->getPickingID()); m_widgets_to_display.elementAt(i)->display(); //The display function calls the displaylist glPopName(); } } Now, that works fine. But now I want to implement picking in my scene. So every object has a 'name' (see abov the glPushName and glPopName). I do picking on the 'normal way' - see code below - and have some troubles with the result. Sometimes an object is dedected where isn't one, otherewise there isn't an object when there is one (-> the picking fails). I trie to dedect an object on mouseclick and print the result on the console. This is my picking code : void GlScene::picking(int x, int y){ GLuint selectBuf[512]; glSelectBuffer(512,selectBuf); glRenderMode(GL_SELECT); glInitNames(); GLint viewport[4]; glGetIntegerv(GL_VIEWPORT,viewport); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); gluPickMatrix(x,viewport[3]-y, 5,5,viewport); gluPerspective(60.0f, (GLfloat)viewport[2]/(GLfloat)viewport[3] , 1.0f, 150.0f); glMatrixMode(GL_MODELVIEW); displayScene(); int hits; glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glFlush(); // returning to normal rendering mode hits = glRenderMode(GL_RENDER); // if there are hits process them if (hits != 0) processHits(hits,selectBuf); else cout<<"no hits..."<<endl; } the processHits function is a 'classical one' : void GlScene::processHits (GLint hits, GLuint buffer[]) { unsigned int i, j; GLuint names, *ptr, minZ,*ptrNames, numberOfNames; cout<<"hits = "<<hits; ptr = (GLuint *) buffer; minZ = 0xffffffff; for (i = 0; i < hits; i++) { names = *ptr; ptr++; if (*ptr < minZ) { numberOfNames = names; minZ = *ptr; ptrNames = ptr+2; } ptr += names+2; } cout<<"The closest hit names are "<<endl; ptr = ptrNames; for (j = 0; j < numberOfNames; j++,ptr++) { cout<<*ptr<<" , "<<endl; } cout<<endl; } Is there anywone who knows what I'm doing wrong? I have tried so much and can 't find a solution. Thanx, Jan

Share this post

Link to post
Share on other sites
I've build these code with the 'Nehe picking tutorial', but I don't see what I'm doing wrong (when I compare my code with the nehe Code I don't see significant differences). Is there anyone, probably more experienced than me, who sees anything I'm doing wrong?

Share this post

Link to post
Share on other sites
Have you tried pushing at least one name into the stack before pushing the one that you want to identify the object you are creating?

Example from gametutorials.com:

glInitNames(); // This clears the name stack so we always start with 0 names.

// This next line is important. If you don't push on at least ONE name,
// The selection won't work. Instead of glLoadName()/glEnd() you can use
// glPushName(TheID) and glPopName(); Then you don't need to glPushName(0);

glPushName(0); // This starts off the first object in the stack

GLUquadricObj *pObj = gluNewQuadric(); // Get a new Quadric off the stack

gluQuadricTexture(pObj, true); // This turns on texture coordinates for our Quadrics

// Bind the sun texture to the sun quadratic
glBindTexture(GL_TEXTURE_2D, g_Texture[0]); // Bind the Sun texture to the sun

// Below we call glLoadName(). We need to pass in an ID that we can check later that will
// be associated with the polygons drawn next. Here is how it works. We call glLoadName()
// and pass an ID. Then we draw any primitives or shapes, then we call glEnd() which
// stops assigning polys to that object name. We now have a group of polygons that are
// given an ID. Our ID SUN now refers to the sun Quadric we draw below.

glLoadName(SUN); // Push on our SUN label (IMPORTANT)

// If we use glLoadName(), then we need to end it with glEnd(). There is a problem
// though with some video cards that MUST have a glBegin()/glEnd() between
// the calls to glLoadName()/glEnd(). This is strange but some cards grind
// to a 2 FPS speed (VoodooCards). Since we are using Quadrics there is
// no glBegin()/glEnd() being called explicitly, so we need to fake it.
// *Remember, you only have to do this if you are using Quadrics.* So, to fix
// this we just put a empty glBegin()/glEnd() statement between each object ID passed in.

// Here we push on a new matrix so we don't affect any other quadrics.
// We first translate the quadric to the origin (0, 0, 0), Then we rotate it
// about the Y axis. This gives it the spinning effect. Then we draw the
// largest of the spheres. This represents the sun with its texture map.

glPushMatrix(); // Push on a new matrix scope
glTranslatef(0, 0, 0); // Translate this sphere to the left
glRotatef(SunRotation, 0, 1.0, 0); // Rotate the sphere around the Y axis to make it spin
gluSphere(pObj, 0.5f, 20, 20); // Draw the sunwith a radius of 0.5
glPopMatrix(); // End the current scope of this matrix

// Now that we drew the sun, we want to end our Object name. We call glPopName()
// to do that. Now nothing else will be associated with the SUN ID.

glEnd(); // Stop assigning polygons to the SUN label (IMPORTANT)

Share this post

Link to post
Share on other sites
Sign in to follow this  

  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!