# Projecting a 3d position to 2d screen in OGL

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

## Recommended Posts

Hi there, I seem to be having a lot of trouble doing what's apparently a fairly simple task: I'm designing a targeting system for my uni project and need to be able to project a 3d position onto the screen. I looked a similar thread on this site where the author wanted to do the same thing, but they were using dx and for some reason, I simply can't replicate the code in OGL. I've been led to believe that to transform a 3d coord into 2d screen space (-1<=x/y/z<=1) you simply do the following transform: 3dPosition * ModelViewMatrix * ProjectionMatrix however when I do this, I just get results which seem a little mad. The code I'm using is this:
VECTOR MathEx::OGLProjectToScreen(VECTOR f4Point, VECTOR f4CamRight, VECTOR f4CamUp, VECTOR f4CamLook, VECTOR f4CamPos)
{
VECTOR f4ReturnValue;
IEFloat4x4 f4x4View, f4x4Projection;

/*
Rx	Ry	Rz	0
Ux	Uy	Uz	0
Lx	Ly	Lz	0
Px	Py	Pz	1
*/

glGetFloatv(GL_MODELVIEW_MATRIX,f4x4View.f);
glGetFloatv(GL_PROJECTION_MATRIX,f4x4Projection.f);

f4ReturnValue=f4Point*f4x4View*f4x4Projection;

return f4ReturnValue;
}
The supposed 2d screen position is correct in that when the target is at the centre of the screen, the value is 0,0. However the further away I am from the target, the larger the max x and y values get (max defining the edge of the screen). I'm obviously missing some kind of transform here, but I'm not sure what, any help would be greatly appreciated!

##### Share on other sites
I seem to have fixed the problem by dividing the 2d x and y position by the distance between the camera and the 3d point, the code looks like this:

VECTOR MathEx::OGLProjectToScreen(VECTOR f4Point, VECTOR f4CamRight, VECTOR f4CamUp, VECTOR f4CamLook, VECTOR f4CamPos)
{
VECTOR f4ReturnValue;
IEFloat4x4 f4x4View, f4x4Projection;
float fRatio=(f4Point-f4CamPos).Magnitude();

/*
Rx Ry Rz 0
Ux Uy Uz 0
Lx Ly Lz 0
Px Py Pz 1
*/

glGetFloatv(GL_MODELVIEW_MATRIX,f4x4View.f);
glGetFloatv(GL_PROJECTION_MATRIX,f4x4Projection.f);

f4ReturnValue=f4Point*f4x4View*f4x4Projection;
f4ReturnValue=f4ReturnValue/fRatio;

return f4ReturnValue;
}

However, there's a way to do this with just matrices... Could my projection matrix be broken in some way?

##### Share on other sites
I think from what I can remember you need to divide the x and y values by the w(or the 4th float) value from your matrix calculations. It should be close to what your doing there but the ratio is actually givin to you.

##### Share on other sites
Yeah that makes sense, a 'quick and dirty' method I looked up does the same thing (albeit in a more complex way as it doesn't use matrices). In any case, it's all working as intended now, thanks :)

There's also a *lot* of redundant variables in that function, for reference, here's the cleaned up version:

//Convert a 3d world position into a 2d screen coordinate, the use of memcpy implies that
//matrices and vectors store their values in float arrays, eg f4Vector.f[3], f4x4Matrix.f[15]
VECTOR MathEx::OGLProjectToScreen(VECTOR f4Point)
{
VECTOR f4ReturnValue, f4CamPos;
IEFloat4x4 f4x4View, f4x4Projection;

glGetFloatv(GL_MODELVIEW_MATRIX,f4x4View.f);
glGetFloatv(GL_PROJECTION_MATRIX,f4x4Projection.f);

memcpy(&f4CamPos.f[0],&f4x4View.f[12],3*sizeof(float));
float fRatio=(f4Point-f4CamPos).Magnitude();

f4ReturnValue=f4Point*f4x4View*f4x4Projection;
f4ReturnValue=f4ReturnValue/fRatio;

return f4ReturnValue;
}

1. 1
2. 2
Rutin
17
3. 3
4. 4
5. 5

• 13
• 26
• 10
• 11
• 9
• ### Forum Statistics

• Total Topics
633735
• Total Posts
3013596
×