Picking and selection...
http://www.opengl.org/resources/faq/tech...ection.htm
What I try to do it's to generate an event when I click on object in my 3D univers
Someone can give me an example using this approach with opengl and win 32 api?
I will really appreciate!
/////////////////////////////////////////////////////////////////////
Another method is to generate the ray in eye coordinates, and transform it by the inverse of the ModelView matrix. In eye coordinates, the pick ray origin is simply (0, 0, 0). You can build the pick ray vector from the perspective projection parameters, for example, by setting up your perspective projection this way
aspect = double(window_width)/double(window_height); glMatrixMode( GL_PROJECTION ); glLoadIdentity(); glFrustum(-near_height * aspect, near_height * aspect, -near_height, near_height, zNear, zFar );
you can build your pick ray vector like this:
int window_y = (window_height - mouse_y) - window_height/2; double norm_y = double(window_y)/double(window_height/2); int window_x = mouse_x - window_width/2; double norm_x = double(window_x)/double(window_width/2);
(Note that most window systems place the mouse coordinate origin in the upper left of the window instead of the lower left. That's why window_y is calculated the way it is in the above code. When using a glViewport() that doesn't match the window height, the viewport height and viewport Y are used to determine the values for window_y and norm_y.)
The variables norm_x and norm_y are scaled between -1.0 and 1.0. Use them to find the mouse location on your zNear clipping plane like so:
float y = near_height * norm_y; float x = near_height * aspect * norm_x;
Now your pick ray vector is (x, y, -zNear).
To transform this eye coordinate pick ray into object coordinates, multiply it by the inverse of the ModelView matrix in use when the scene was rendered. When performing this multiplication, remember that the pick ray is made up of a vector and a point, and that vectors and points transform differently. You can translate and rotate points, but vectors only rotate. The way to guarantee that this is working correctly is to define your point and vector as four-element arrays, as the following pseudo-code shows:
float ray_pnt[4] = {0.f, 0.f, 0.f, 1.f}; float ray_vec[4] = {x, y, -near_distance, 0.f};
The one and zero in the last element determines whether an array transforms as a point or a vector when multiplied by the inverse of the ModelView matrix.
////////////////////////////////////////////
What I try to do it's to generate an event when I click on object in my 3D univers
Someone can give me an example using this approach with opengl and win 32 api?
I will really appreciate!
/////////////////////////////////////////////////////////////////////
Another method is to generate the ray in eye coordinates, and transform it by the inverse of the ModelView matrix. In eye coordinates, the pick ray origin is simply (0, 0, 0). You can build the pick ray vector from the perspective projection parameters, for example, by setting up your perspective projection this way
aspect = double(window_width)/double(window_height); glMatrixMode( GL_PROJECTION ); glLoadIdentity(); glFrustum(-near_height * aspect, near_height * aspect, -near_height, near_height, zNear, zFar );
you can build your pick ray vector like this:
int window_y = (window_height - mouse_y) - window_height/2; double norm_y = double(window_y)/double(window_height/2); int window_x = mouse_x - window_width/2; double norm_x = double(window_x)/double(window_width/2);
(Note that most window systems place the mouse coordinate origin in the upper left of the window instead of the lower left. That's why window_y is calculated the way it is in the above code. When using a glViewport() that doesn't match the window height, the viewport height and viewport Y are used to determine the values for window_y and norm_y.)
The variables norm_x and norm_y are scaled between -1.0 and 1.0. Use them to find the mouse location on your zNear clipping plane like so:
float y = near_height * norm_y; float x = near_height * aspect * norm_x;
Now your pick ray vector is (x, y, -zNear).
To transform this eye coordinate pick ray into object coordinates, multiply it by the inverse of the ModelView matrix in use when the scene was rendered. When performing this multiplication, remember that the pick ray is made up of a vector and a point, and that vectors and points transform differently. You can translate and rotate points, but vectors only rotate. The way to guarantee that this is working correctly is to define your point and vector as four-element arrays, as the following pseudo-code shows:
float ray_pnt[4] = {0.f, 0.f, 0.f, 1.f}; float ray_vec[4] = {x, y, -near_distance, 0.f};
The one and zero in the last element determines whether an array transforms as a point or a vector when multiplied by the inverse of the ModelView matrix.
////////////////////////////////////////////
You won't find much help here since this is a Macintosh forum, but we do OpenGL here so there's a bridge.
In my work I do picking by means colliding pick-rays with geometry. I'm using ODE for my physics and collision detection so it's really easy.
I've also done picking -- really crudely I might add -- by rendering the scene into the backbuffer with each "pickable" object rendering a unique color. Think of the color as a unique ID for the object. Then I use glReadPixels to grab the single pixel corresponding to the mouse point. I get the color out, convert it back to an ID, and check against a table which maps the IDs to objects in my graph.
It works really well, and is easy to implement.
That being said, I never grokked OpenGL's built-in picking.
In my work I do picking by means colliding pick-rays with geometry. I'm using ODE for my physics and collision detection so it's really easy.
I've also done picking -- really crudely I might add -- by rendering the scene into the backbuffer with each "pickable" object rendering a unique color. Think of the color as a unique ID for the object. Then I use glReadPixels to grab the single pixel corresponding to the mouse point. I get the color out, convert it back to an ID, and check against a table which maps the IDs to objects in my graph.
It works really well, and is easy to implement.
That being said, I never grokked OpenGL's built-in picking.
sorry about my post last night; I was tired 
Here's some code that uses glutPicking that I obtained from somewhere back when I was writing my first game:
where theAnims is an array of objects that contains a method to dray polygons in OpenGL.
Again, sorry about my previous post; hope this helps
-wyrmmage

Here's some code that uses glutPicking that I obtained from somewhere back when I was writing my first game:
Code:
int clientDLL::pickClosest(anim* theAnims[], int numOfAnims)
{
assert(windowHeight != 0);
assert(windowWidth != 0);
assert(theAnims != NULL);
//numOfAnims starts at 1
glSelectBuffer(512,selectBuffer);
glRenderMode(GL_SELECT);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glGetIntegerv(GL_VIEWPORT,viewport);
gluPickMatrix(mouseX,viewport[3]-mouseY,5,5,viewport);
gluPerspective(45.0f,(GLfloat)windowWidth/(GLfloat)windowHeight,0.1f,100.0f);
glMatrixMode(GL_MODELVIEW);
glInitNames(); // Initializes The Name Stack
glLoadIdentity();
glTranslatef(0.0f,0.0f,-6.0f);
for(int i=0; i<numOfAnims; i++)
{
glPushName(i);
theAnims[i]->drawBounding();
if(i != numOfAnims-1)
{
glPopName();
}
}
// restoring the original projection matrix
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
//glFlush();
//glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
int hits=glRenderMode(GL_RENDER); // Switch To Render Mode, Find Out How Many
if (hits != 0) // If There Were More Than 0 Hits
{
int choose = selectBuffer[3]; // Make Our Selection The First Object
int depth = selectBuffer[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 (selectBuffer[loop*4+1] < GLuint(depth))
{
choose = selectBuffer[loop*4+3]; // Select The Closer Object
depth = selectBuffer[loop*4+1]; // Store How Far Away It Is
}
}
cout << "clicked: " << choose << "\n";
return choose;
}
else
{
cout << "clicked nothing \n";
return -1;
}
}where theAnims is an array of objects that contains a method to dray polygons in OpenGL.
Again, sorry about my previous post; hope this helps

-wyrmmage
Worlds at War (Current Project) - http://www.awkward-games.com/forum/
Possibly Related Threads...
| Thread: | Author | Replies: | Views: | Last Post | |
| How do I do Color Picking? | dockode | 2 | 4,130 |
Sep 24, 2011 08:02 PM Last Post: dockode |
|
| Issues with picking | FFaqui | 0 | 1,898 |
Nov 21, 2009 04:37 PM Last Post: FFaqui |
|
| Opengl picking problem (zip file) | papillon68 | 1 | 3,746 |
Mar 1, 2009 08:49 PM Last Post: chronus |
|
| glut picking clashes with drawing | wyrmmage | 2 | 3,133 |
Jan 24, 2008 06:39 PM Last Post: wyrmmage |
|
| picking glOrtho vs gluPerspective | rhiannon | 0 | 3,084 |
Jun 6, 2005 02:20 PM Last Post: rhiannon |
|

