OpenGL Stereo Camera Setup and Convergence
Edit: I think that my baseline needs to change to get rid of the 0.5 up front, but everything else still broken:
I've been stuck for the past few days trying to get my cameras set up. I finally understand why I need to put all the eye releated transforms in the Projection transform and not the ModelView transform, but now everything seems to be either ultra-zoomed in or out. The other question I have is related to the application of the Rift orientation matrix which I apply before rendering everything else then apply a pushmatrix to render the world in there. It seems like even if I look straight down I can still see things that are directly ahead stretched out to the top of the monitor like I'm in a fun-house mirror. Seems like my FOV isn't really the 90 degrees that I thought. Here are some of the relevant snippets of code in case anyone has some suggestions.
Here is the projection code. What's odd is that modifying the near plane causes the zoom effect, larger values zoom out, smaller ones zoom in. If the formulas were right shouldn't it maintain the aspect ratio and zoom regardless of the near and far plane separation? The math looks right to me but for some reason it makes a huge difference. Also, I can't pick an IOD that works for moving the two rendered images to match the lens IPD on the Rift so nothing converges! At a distance the convergence seems ok, but as I walk closer in the VR world the distance widens so as to be unviewable. The walking and looking transforms are in the second code snippet.
Here is my ModelView code. It might be an effect of the bad projection matrix, but it always seems like the world is pivoting weirdly around my head orientation, so it isn't like I'm looking around but that everything is sort of rotating but when looking down I can still see the stuff that was directly infront of me but just sort of stretched out to infinity at the top of the monitor with an extreme perspective effect.
float const baselength = near_ * std::tan(M_PI * (fov_/2.0 / 180.0));
I've been stuck for the past few days trying to get my cameras set up. I finally understand why I need to put all the eye releated transforms in the Projection transform and not the ModelView transform, but now everything seems to be either ultra-zoomed in or out. The other question I have is related to the application of the Rift orientation matrix which I apply before rendering everything else then apply a pushmatrix to render the world in there. It seems like even if I look straight down I can still see things that are directly ahead stretched out to the top of the monitor like I'm in a fun-house mirror. Seems like my FOV isn't really the 90 degrees that I thought. Here are some of the relevant snippets of code in case anyone has some suggestions.
Here is the projection code. What's odd is that modifying the near plane causes the zoom effect, larger values zoom out, smaller ones zoom in. If the formulas were right shouldn't it maintain the aspect ratio and zoom regardless of the near and far plane separation? The math looks right to me but for some reason it makes a huge difference. Also, I can't pick an IOD that works for moving the two rendered images to match the lens IPD on the Rift so nothing converges! At a distance the convergence seems ok, but as I walk closer in the VR world the distance widens so as to be unviewable. The walking and looking transforms are in the second code snippet.
void stereoscopicPerspective(float fov_, float aspect, float near_, float far_, float stereo_offset, bool isLeft)
{
float const baselength =0.5 * near_ * std::tan(M_PI * (fov_ / 180.0));
if(isLeft) {
glFrustum(-aspect * baselength-stereo_offset , aspect * baselength-stereo_offset, -baselength, baselength, near_, far_);
} else {
glFrustum(-aspect * baselength+stereo_offset , aspect * baselength+stereo_offset, -baselength, baselength, near_, far_);
}
}
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
double IOD = 0.03;//0.5/2.0;
stereoscopicPerspective(89.0f, textureWidth/textureHeight, 0.005f, 1000.0f, IOD, isLeft);
double eyeOffset = (isLeft) ? -IOD : IOD;
glTranslatef(eyeOffset, 0.0f, 0.0f);
Here is my ModelView code. It might be an effect of the bad projection matrix, but it always seems like the world is pivoting weirdly around my head orientation, so it isn't like I'm looking around but that everything is sort of rotating but when looking down I can still see the stuff that was directly infront of me but just sort of stretched out to infinity at the top of the monitor with an extreme perspective effect.
double *orientation = getRiftOrientation();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glPushMatrix();
{
// head orientation
glMultMatrixd(orientation);
glRotated(loc.getXRotation(), 1, 0, 0);
glRotated(loc.getYRotation(), 0, 1, 0);
// translate world down so you have some height
glTranslated(0, -0.5, 0);
renderSkybox();
// walking position
glTranslated(loc.getXPosition(), loc.getYPosition(), loc.getZPosition());
glPushMatrix();
{
// rest of rendering code
