Jump to content
  • Advertisement
Sign in to follow this  
elithiomel

Projecting a 3d position to 2d screen in OGL

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

If you intended to correct an error in the post then please contact us.

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 this post


Link to post
Share on other sites
Advertisement
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 this post


Link to post
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 this post


Link to post
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 :)

[edit]
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;
}

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!