Projecting a 3d position to 2d screen in OGL

Started by
2 comments, last by elithiomel 17 years ago
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!
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?
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.
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;}

This topic is closed to new replies.

Advertisement