I am trying to do an off-axis projection of a scene with OpenGL and I gave a read to the document to Robert Kooima's off-axis projection and have a much better idea now of what actually has to be done but there are still some pieces which I am finding tricky here. I got to know of the off-axis projection code for OpenGL to be somewhat as follows:
Code 1:
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(fNear*(-fFov * ratio + headX),
fNear*(fFov * ratio + headX),
fNear*(-fFov + headY),
fNear*(fFov + headY),
fNear, fFar);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(headX*headZ, headY*headZ, 0, headX*headZ, headY*headZ, -1, 0, 1, 0);
glTranslatef(0.0,0.0,headZ);
Had this been a normal perspective projection with the user at the center of the screen, it is fairly easy to understand as I comprehend.
Screen
|
| h = H/2
|
x----- n -----------
|
| h = H/2
|
With the user at x and distance from screen being n, the top, bottom coordinates for glFrustum would be calculated as: (assume theta is the Field of View (fov) which I suppose is assumed as 30 degrees)
h = n * tan (theta/2);
tanValue = DEG_TO_RAD * theta/2;
[EDIT Line additon here>>]: fFov = tan(tanValue);
h = n * tan (tanValue);
Hence, top and bottom (negating top's value) are both obtained for glFrustum arguments. Left one's are left/right for now.
Now, Aspect Ratio, r = ofGetWidth()/ofGetHeight();
Right = n * (fFov * r); , where r is the aspect ratio [Edit1>> Was written tanValue*r earlier here]
Question 1) Is the above (tanValue*r) getting the horizontal fov angle and then applying the same to get left/right value?
double msX = (double)ofGetMouseX();
double msY = (double)ofGetMouseY();
double scrWidth = (double)ofGetWidth();
double scrHeight = (double)ofGetHeight();
headX = (msX / scrWidth) - 0.5;
headY = ((scrHeight - msY) / scrHeight) - 0.5;
headZ = -2.0;
Now, consider the projection off-axis and we have the headX and headY position computed (using mouse here instead of actual user's head):
Question 2) How is the headX and y being computed and what is the use subtracting -0.5 from the above? I observed that it brings the x-value to (-0.5 to 0.5) and y-value to (0.5 to -0.5) with msX and msY varying.
Question 3) In the above code (Code 1), how is headY being added to the calculated to the tan(fov/2) value?
-fFov + headY
fFov + headY
What does this value provide us with? -fFov was the calculated tan of theta/2 but how can headY be added to directly?
-fFov * ratio + headX
-fFov * ratio + headX
How does the abvoe give us a vlaue which wehn multiplied by n (near value) gives us left and right for the assymetric glFrustum call for off-axis projection?
Question 4) I understand that the glLookAt has to be done for View Point to shift the apex of the frustum to where the eye of the user is (in this case where the mouse is). Notice the line in the above code:
gluLookAt(headX*headZ, headY*headZ, 0, headX*headZ, headY*headZ, -1, 0, 1, 0);
How is headX*headZ
giving me the xPosition of the eye, headY*headZ
giving me the yPosition of the eye which I can use in gluLookAt()
here?
EDIT: Full problem description added here: pastebin.com/BiSHXspb