picking problem...

Started by
2 comments, last by Xiachunyi 18 years, 10 months ago
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
Advertisement
Check out NeHe's Picking Tutorial! It may help you out.
Take back the internet with the most awsome browser around, FireFox
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?
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.	glBegin(GL_LINES);								glEnd();	// 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)

This topic is closed to new replies.

Advertisement