Reputation: 23
I know that StackOverflow is full of similar questions (Like this one or that one) but the solutions given don't seem to work for me.
My goal is to use gluProject
to get the screen coordinates of some point from the 3D-space. Before that, I'm expected to get the matrices by doing the following:
GLint view[4]={0};
GLdouble proj[16]={0};
GLdouble model[16]={0};
glGetDoublev(GL_PROJECTION_MATRIX,proj);
glGetDoublev(GL_MODELVIEW_MATRIX,model);
glGetIntegerv(GL_VIEWPORT,view);
Knowing these three allows to compute the screen coordinates of the point. However, when I call these functions I get weird results:
VIEWPORT
0 0 1366 768
PROJECTION
-536 870 912 1 073 460 858 0 0
0 0 -536 870 912 1 073 460 858
0 0 0 0
0 0 0 0
MODELVIEW
1 073 741 824 1 073 741 824 -1 073 741 824 1 071 119 123
0 0 1 073 741 824 1 072 511 075
-1 073 741 824 1 072 523 682 0 -1 077 637 615
-2 147 483 648 -1 069 923 613 0 -1 071 413 844
The matrices are generated using gluPerspective
and gluLookAt
.
The Viewport is obviously correct but the matrices are wrong, not only because of their values which don't seem very normal to me but because of the value's distribution across the elements of the matrices (see that the [1,2] element of the Projection matrix should be zero but it isn't, while the [3,3] element is zero, and it shouldn't).
These strange values point to some problem in the call of the glGet()
functions, but I can't figure it out. I have checked that I'm not calling glGet()
between glBegin()
and glEnd()
. Actually, I call glGet()
just after correctly drawing some points and just before correctly drawing some spheres by using the same ModelView and Projection matrices.
There's the a bigger snippet of my code (the calling sequence is main->CheckForPlanetPosition->Planet::GetScreenLocation
):
typedef struct position {
int x,y,z;
};
int main()
{
glEnable(GL_DEPTH_TEST);
glViewport(0,0,1366,768);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60,16.0f/9.0f,1,1000);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(Camera.x,Camera.y,Camera.z,Camera.cx,Camera.cy,Camera.cz,0,1,0);
//calls to glEnable
//some drawing
glBegin(GL_LINES);
for(float i=1;i<15;i++)
{
glColor4f(0,120.0f/255.0f,210.0f/255.0f,1.0f);
glVertex3f(0,0.5f,i*100.0f/15.0f);
glVertex3f(100,0.5f,i*100.0f/15.0f);
glVertex3f(i*100.0f/15.0f,0.5f,0);
glVertex3f(i*100.0f/15.0f,0,100);
}
glEnd();
CheckForPlanetsLocation();
//other stuff...
return 0;
}
bool CheckForPlanetsLocation()
{
position pos;
pos=SomePlanet.GetScreenLocation();
//check that the mouse is over the returned region...
}
position Planet::GetScreenLocation()
{
GLint view[4]={0};
GLdouble proj[16]={0};
GLdouble model[16]={0};
GLdouble x,y,z;
glGetDoublev(GL_PROJECTION_MATRIX,proj);
glGetDoublev(GL_MODELVIEW_MATRIX,model);
glGetIntegerv(GL_VIEWPORT,view);
gluProject(pos.x,pos.y,pos.z,model,proj,view,&x,&y,&z);
position res;
res.x=(int)x;
res.y=(int)y;
res.z=(int)z;
return res;
}
Hope you can help me this time! Thanks in advance for your answers :)
Upvotes: 0
Views: 1458
Reputation: 124
The problem is that gluProject
expects an array of type double
while you're passing it a float
. When it goes to iterate, it'll iterate using the size of a double
, which is twice the size of a float! Therefore, it'll skip over some elements and give you garbage for others. Swap out those float arrays with double and use glGetDoublev
to get the values you want.
Also, your gluPerspective
code has a small error in it -- the 16/9 will integer truncate to 1 before it's passed into the function. It's not the cause of your projection problems, but it's good to remember that integer truncation is a thing that will screw up your floating point calculations.
Finally, I'm gonna be that guy and say in this day and age learning OldenGL(as I call it) does more harm than good. There are plenty of great online tutorials for modern OpenGL, such as these:
Anything that mentions OpenGL 2 and above is what you want.
Upvotes: 2