took a while, but finally got around to matching perspective screen xy !!
… simple, use the same perspective matrix you gave to the projection matrix.
found the deprecated glulookAt and gluPerspective code, especially lookat was ugly - rewritten.
working example **********************************
('cause no one else knew how, someone had to do it.)
functions not included, are in the file.
#define NORMALIZE4(V) { \
V[0]/=V[3]; \
V[1]/=V[3]; \
V[2]/=V[3]; \
}
#define popmatrix4( U, M, V ) { \
U[0] = V[0]*M[0]+V[1]*M[4]+V[2]*M[8]+V[3]*M[12]; \
U[1] = V[0]*M[1]+V[1]*M[5]+V[2]*M[9]+V[3]*M[13]; \
U[2] = V[0]*M[2]+V[1]*M[6]+V[2]*M[10]+V[3]*M[14]; \
U[3] = V[0]*M[3]+V[1]*M[7]+V[2]*M[11]+V[3]*M[15]; \
if (U[3]) NORMALIZE4(U); \
} /// != 0.0)&& (U[3] != 1) 1 changes nothing, NOT 0
double pmat[16] = { 0,0,0,0,0,0,0,0,0,0,0,-1,0,0,0,0 } ;
void setpmat() {
double fl; // = tan(dtor(90-fovx/aspect/2)); /// UNIT focal len
fl = 1/tan(dtor(fov/Aspect/2)); /// same number /// fl * cx = actual focal length
pmat[0] = fl/Aspect;
pmat[5] = fl;
pmat[10] = (farclip + nearclip) / (nearclip - farclip);
pmat[14] = 2*farclip*nearclip / (nearclip - farclip);
}
void fovmat(double v[],double p[]) {
int cx = (int)(_Width/2),cy = (int)(_Height/2);
double pnt2[4], pnt[4] = { 0,0,0,1 } ;
COPYVECTOR(pnt,p);NORMALIZE(pnt); /// matrix in unit form, normalize
popmatrix4(pnt2,pmat,pnt);
COPYVECTOR(v,pnt2);
v[0] *= -cx; v[1] *= -cy;
v[0] += cx; v[1] += cy;
}
In the gl scheme,
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMultMatrixd(pmat); //perspective
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
Camera(); // invertmatrix()
And for 2D - a 3D radius to 2D screen points.
first invert cam matrix to world wmatrix -
apply perspective to points in front.
SUBV(v,v,campos);
if (VLEN(v) < farclip) {
popmatrix(v2,wmatrix,v);
if (v2[2] < 0.0) { /// reversed
fovmat(v,v2); // FIN
// label down one radius
INITVECTOR(w,0,elem[i].radius,0);
ADDV(w,w,v2);
fovmat(v2,w);
SUBV2(v2,v2,v);
sub = 10 + (int)VLEN2(v2);
printstring(v[0],v[1]-sub,0.0,elem[i].name,3);
// not some 3d point bouncing around dependent on z roll
// sticks like glue at any fov angle.
//or return a perspective size for an image -- fsize(1,12);
double fsize(double x, double z) { // Z focal len
double v[3], p[3] = { x,0,z } ;
fovmat(v,p);
return v[0] - _Width / 2;
}