It seems that everything I do today just won't work. :(
I have this vertex projection function I've been using for years now, and it has always worked before. Right now, it's returning bogus results. Not sure why, and I've never had problems with it before. Here's what it looks like:
/*
* Name: project_vertex
* Desc: Takes a point in 3D space and returns a 2D screen coordinate. This func-
* ion is useful when drawing 2D shapes over 3D objects, picking, etc.
* Keep in mind that this code does not work for orthographic projections
* and assumes the depth range is 0.0-1.0f. Also, if win_coord.z's value is
* greater than 1.0, then the object is behind the camera.
*/
int project_vertex( VmathVector3* obj, float* modelview, float* projection, int* viewport, VmathVector3* win_coord )
{
/* Transformation vectors */
VmathVector4 tv1, tv2;
/* Modelview transformation */
tv1.x = modelview[0]*obj->x+modelview[4]*obj->y+modelview[8]*obj->z+modelview[12];
tv1.y = modelview[1]*obj->x+modelview[5]*obj->y+modelview[9]*obj->z+modelview[13];
tv1.z = modelview[2]*obj->x+modelview[6]*obj->y+modelview[10]*obj->z+modelview[14];
tv1.w = modelview[3]*obj->x+modelview[7]*obj->y+modelview[11]*obj->z+modelview[15];
/* Projection transformation */
tv2.x = projection[0]*tv1.x+projection[4]*tv1.y+projection[8]*tv1.z+projection[12]*tv1.w;
tv2.y = projection[1]*tv1.x+projection[5]*tv1.y+projection[9]*tv1.z+projection[13]*tv1.w;
tv2.z = projection[2]*tv1.x+projection[6]*tv1.y+projection[10]*tv1.z+projection[14]*tv1.w;
tv2.w = -tv1.z;
/* Normalize result between -1 and 1 */
if( tv2.w == 0.0f )
return 0;
tv2.w = 1.0f / tv2.w;
/* Perspective division */
tv2.x *= tv2.w;
tv2.y *= tv2.w;
tv2.z *= tv2.w;
/* Calculate window coordinates */
win_coord->x = (tv2.x*0.5f+0.5f)*viewport[2]+viewport[0];
win_coord->y = (tv2.y*0.5f+0.5f)*viewport[3]+viewport[1];
win_coord->z = (1.0f+tv2.z)*0.5f;
return 1;
}
An implementation of it:
void project_position( Vector3 pos, Vector3* projected_pos )
{
int iViewport[4];
float modelview[16], projection[16];
// Get the current viewport.
glGetIntegerv( GL_VIEWPORT, iViewport );
// Project
glGetFloatv( GL_PROJECTION, projection );
glGetFloatv( GL_MODELVIEW, modelview );
modelview[13] = -modelview[13];
pos.y = -pos.y;
project_vertex( &pos, modelview, projection, iViewport, projected_pos );
if( projected_pos->y < 0 )
projected_pos->y *= -1.0f;
}
Now, when I rotate my camera, I just use translate and rotate commands to do it. Once again, no idea what the problem is, but I did notice one thing: it only works properly when the camera is directly in front of the point being projected. If I move to the left/right, the value becomes garbage. Any ideas? Thanks.
Shogun.