Author Topic: Desktop VR openGL perspective projection issues  (Read 12296 times)

Offline Veranderlike

  • *
  • Posts: 2
  • Karma: +1/-0
    • View Profile
on: January 21, 2008, 03:38:42 PM
I implemented the DesktopVR project in OpenGL but I'm having some issues getting the perspective projection to work right. The original Direct X app uses a method called Matrix.PerspectiveOffCenterLH to calculate the perspective matrix. The openGL equivalent method is glFrustrum (after switching to the projection matrix mode :P) wich accepts the same basic arguments (as dictated by parameter names anyway).  However it is painfully obvious that the way these two methods work is very different, and I'm having trouble finding documentation explaining the Matrix.PerspectiveOffCenterLH method in more detail (apart from: Builds a customized, left-handed perspective projection matrix.) I did find some resourses on the OpenGL method though : http://www.glprogramming.com/red/chapter03.html#name3

My linear algrebra is really horrible and if anyone has implemented this in openGL or can help explain how I might solve the problem I would be eternally greatful.

changing the original paramters from :
(nearPlane*(-.5f * screenAspect + headX)/headDist,nearPlane*(.5f * screenAspect + headX)/headDist, nearPlane*(-.5f - headY)/headDist,nearPlane*(.5f - headY)/headDist,nearPlane, 100);
to
(nearPlane*(-.5f * screenAspect + headX)*headDist,nearPlane*(.5f * screenAspect + headX)*headDist, nearPlane*(-.5f - headY)*headDist,nearPlane*(.5f - headY)*headDist,nearPlane, 100);

seemed to produce more accurate results but it still doesnt look as cool as it does in the video :P

Also, openGL provides another method called glPerspective(GLdouble fovy, GLdouble aspect,
GLdouble near, GLdouble far) but then I need to calculate the FOV parameter (more detail in the link I posted)

I also read a reply on another form where the following solution was suggested:

For lateral (X-Y) headtracking, you need to rmultiply the projection matrix with M=
1 0 X X*znear
0 1 Y Y*znear
0 0 1 0
0 0 0 1

(newP = oldP*M)

X Y being the head position, znear being the near clipping pane distance.

http://www.ogre3d.org/phpBB2/viewtopic.php?t=38030&postdays=0&postorder=asc&start=50&sid=5085e0cd34bb1c6c8ff88d508aa21631

But I had no luck implementing that either :(

Any help would be greatly appreciated!




Offline braddabug

  • *
  • Posts: 1
  • Karma: +0/-0
    • View Profile
Reply #1 on: January 28, 2008, 11:44:55 PM
I'm trying to do the same thing, but without much luck. Did you ever get it to work?



Offline OasisGames

  • *
  • Posts: 10
  • Karma: +2/-0
    • View Profile
Reply #2 on: January 31, 2008, 03:59:44 PM
The following should give the desired result, assuming your scene's transformation matrix is zTransform, x y and z are your head coordinates, and you set up your screenAspect properly.
Code: [Select]
float nearPlane = 0.05; // Our near rendering plane
float screenAspect = 1.0; // Leave this for future fixes
glMatrixMode(GL_PROJECTION); // We're going to modify the projection matrix
glLoadIdentity(); // Clear it first
// Set our frustum view matrix.
glFrustum( nearPlane*(-0.5 * screenAspect + x)/z,
nearPlane*(0.5 * screenAspect + x)/z,
nearPlane*(-0.5 + y)/z,
nearPlane*(0.5 + y)/z,
nearPlane, 100.0);

glMatrixMode(GL_MODELVIEW); // Switch back to model matrix
// Move our scene so that it appears to actually be the screen
matrixTranslate (&zTransform, x, y, 1 - z);

This code works flawlessly for me, so hopefully it will work for you as well.



Offline Veranderlike

  • *
  • Posts: 2
  • Karma: +1/-0
    • View Profile
Reply #3 on: February 20, 2008, 02:43:12 AM
Thanx for your input OasisGames, i thought nobody was going to respond...

I have some questions regarding your solution:

1.
I assume the method matrixTranslate  is a custom method, is this the same as going:

glMatrixMode(GL_MODELVIEW);
glLoadIndentity();
glTranslatef(x, y, 1 - z);

2.
Is this the correct order of the steps for the renedering loop?
 1 load the projection matrix (glMatrixMode)
 2 perform the perspective projection (glFrustum)
 3 set the modelview matrix
 4 translate the matrix by the head pos (glTranslateF)
 5 set the camera by calling the lookat method with the head coords as indicated in the original project (gluLookAt)
 6 render all objects in the scene

Thanx again :)

P.S I'm busy coding a simple game with this idea where you move through a tunnel specified with a BSpline and dodge objects with you head. If i can just get the perspective working right it will look awesome! If I manage to do it I'll upload the game...


« Last Edit: February 21, 2008, 04:04:24 AM by Veranderlike »



Offline OasisGames

  • *
  • Posts: 10
  • Karma: +2/-0
    • View Profile
Reply #4 on: March 05, 2008, 10:03:35 AM
Oops, completely forgot that was a custom function of Compiz.
It looks like this:
Code: [Select]
void
matrixTranslate (CompTransform *transform,
float        x,
float        y,
float        z)
{
    float *m = transform->m;

    m[12] = m[0] * x + m[4] * y + m[8]  * z + m[12];
    m[13] = m[1] * x + m[5] * y + m[9]  * z + m[13];
    m[14] = m[2] * x + m[6] * y + m[10] * z + m[14];
    m[15] = m[3] * x + m[7] * y + m[11] * z + m[15];
}
CompTransform is simply a class with a matrix in it for the transformation, so use that instead...



Offline thom42

  • *
  • Posts: 1
  • Karma: +0/-0
    • View Profile
Reply #5 on: March 20, 2008, 04:17:41 PM
I'd really be curious to hear more peoples opinions about doing this in OpenGL... I still have some things that don't quite make sense to me:

1. Those coordinates would be the position of a person's head in relation to the actual coordinates of the VR world? As in, I need to measure the size of the screen and the size of the room, and be able to turn the difference of at least 2 IR points to determine distance as well as X and Y of the person, and that should all line up to the placement of the monitor in the room and its dimensions, resolution, and aspect ratio?

2. For objects in front of the screen I need a "cadre" (like Johnny's laptop) in order to give visual cues? And that becomes the maximum negative Z for objects (anything beyond that is hidden?)

3. This involves a frustum-within-frustum to be able to account for positive and negative Z perspectives from the screen towards the viewer, even though this isn't the world's origin?

Sorry, but thoughts are greatly appreciated. I guess maybe I'm making this too difficult, but also, in the code above, &zTransform (the matrix to give to the transform function) comes from where? GL_MODELVIEW_MATRIX ?

Thank you,

Thomas



Offline freakTheMighty

  • *
  • Posts: 1
  • Karma: +0/-0
    • View Profile
Reply #6 on: May 18, 2008, 01:33:01 AM
What does this mean?
Quote
   // Move our scene so that it appears to actually be the screen
   matrixTranslate (&zTransform, x, y, 1 - z);