mouse click detection glRenderMode(GL_SELECT)

dear all, I’m new to the forums so a big Hello to all and well done to Zach & team!!

I’m trying to implement a mouse click on 3D object detection as per NeHe’s Lesson 32…(http://nehe.gamedev.net/data/lessons/le-…-?lesson=32)
but within the openframeswork structure, for some reason, it aint working :frowning:

any ideas or solutions :slight_smile: would be greatly appreciated
Ben

Could you post the code you have so far?

Someone I know was dealing with this same issue - I’ll see if he has the code for it handy.

Theo

hi Theo, thanks for posting -

I dont know if there are forum conventions for posting code but here goes:

I call the Selection function from mousePressed

this Selection code is almost duplicate of Nehe’s lesson 32 selection code

cheers,
ben

//=======================
int testApp::Selection(int x,int y) // This Is Where Selection Is Done
{

glClearDepth(1.0f); // Depth Buffer Setup
glDepthFunc(GL_LEQUAL); // Type Of Depth Testing
glEnable(GL_DEPTH_TEST); // Enable Depth Testing

GLuint buffer[512]; // Set Up A Selection Buffer
GLint hits; // The Number Of Objects That We Selected

// The Size Of The Viewport. [0] Is , [1] Is , [2] Is , [3] Is
GLint viewport[4];

// This Sets The Array 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) x, (GLdouble) (viewport[3]-y), 1.0f, 1.0f, viewport);

// Apply The Perspective Matrix

//==============
ofSetupScreen();
// Render The Targets To The Selection Buffer
draw();

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
}
}

}

return choose;
}

Cool - I have zoom in on mouse position working - just a sort of test to see how this stuff works.

Going to try the selection stuff now.

Zoom camera in on mouse - place this in testApp::draw()

  
	//THIS IS JUST OF SETUPSCREEN   
	//PLUS SOME A COUPLE OF EXTRA THINGS  
	//TO ZOOM IN ON THE MOUSE CURSOR  
	  
	int w, h;  
  
	w = glutGet(GLUT_WINDOW_WIDTH);  
	h = glutGet(GLUT_WINDOW_HEIGHT);  
  
	float halfFov, theTan, screenFov, aspect;  
	screenFov 		= 60.0f;  
  
	float eyeX 		= (float)w / 2.0;  
	float eyeY 		= (float)h / 2.0;  
	halfFov 		= PI * screenFov / 360.0;  
	theTan 			= tanf(halfFov);  
	float dist 		= eyeY / theTan;  
	float nearDist 	= dist / 10.0;	// near / far clip plane  
	float farDist 	= dist * 10.0;  
	aspect 			= (float)w/(float)h;  
  
	glMatrixMode(GL_PROJECTION);  
	glLoadIdentity();  
  
	// ----NEW STUFF  
	// from [http://www.opengl.org/resources/faq/technical/selection.htm](http://www.opengl.org/resources/faq/technical/selection.htm)  
	  
	GLint	viewport[4];   
	glGetIntegerv(GL_VIEWPORT, viewport);   
	  
	//window aspect ratio - so are shapes look right  
	float ratio = (float)h/w;  
	  
	//specify the amount around the mouse cursor you want to zoom   
	// 300 by 300 * ratio - adjust the height so that aspect  
	// ratio stays the same  
	  
	// we also do window h - the mouse - so the coordinate system   
	// matches up  
	gluPickMatrix(mouseX, h  - mouseY, 300, 300 * ratio, viewport);  
  
	  
	// ----- THE REST OF OFSETUPSCREEN  
	  
	gluPerspective(screenFov, aspect, nearDist, farDist);  
	  
	gluLookAt(eyeX, eyeY, dist,  
	eyeX, eyeY, 0.0, 0.0, 1.0, 0.0);  
	glMatrixMode(GL_MODELVIEW);  
	glLoadIdentity();  
  
	glScalef(1, -1, 1);           // invert Y axis so increasing Y goes down.  
  	glTranslatef(0, -h, 0);       // shift origin up to upper-left corner.  
  
	  
	// ---- OUR NORMAL DRAWING STUFF  
	  
	//draw some circles to test  
	ofSetColor(0xFF00FF);  
	ofCircle(100, 100, 40);  
  
	ofSetColor(0x0000FF);  
	ofCircle(400, 400, 20);  
  

cheers Theo, yep that worked for zoomin…

when I debug my selection code, it seems I’m always getting all objects in the hit buffer…

b

Don’t know if that this happens for you - but 300 by 300 * ratio made the selection quite inaccurate - 2 by 2 * ratio made it super accurate though.

Theo

yep - i noticed when i actually tried to use it practically :slight_smile:
cheers theo, i’m getting on with the next challenge now !

ben