PDA

View Full Version : How to temporary disable stereo in stereo mode ?



lekeno
09-28-2003, 05:45 PM
Hi,

I first tried the beginner forum with no success. /me thought that maybe Gurus could help :-) :


I have made a stereo application with two different algorithms: toe-in and off-axis.

I can also cycle through Toe-in, Off-axis and
no stereo.
However in non stereo mode the app slows down
(it looks like the same view of the scene is rendered 2 times)...

Here is a bit of my code:

code:


render() :

m_hudManager.update(elapsedMilliseconds);
m_scene3D.animate(elapsedMilliseconds);

ViewClipper::getInstance()->unapply();
s_3D->clearAllBuffers();
// s_3D is a just an abstraction layer
ViewClipper::getInstance()->apply();

// the following line is a bit complex but basically it is the same as if '(stereoActive)'
if (((SimpleSetting<bool> *) Settings::getInstance()->getSetting(Settings::STEREO))->getValue())
{
// LEFT EYE
s_Stereolizer.lookWithLeftEye();
// Render the scene
_renderScene();
// I had to add following line because left and right buffers are shared (Nvidia quadro, before we had a 3DLabs oxygen which worked fine without).
glClear(GL_DEPTH_BUFFER_BIT);
glClear(GL_STENCIL_BUFFER_BIT);

// RIGHT EYE
s_Stereolizer.lookWithRightEye();
// Render the scene
_renderScene();
}
else
{
s_3D->modelViewMode();
s_3D->loadIdentity();
s_3D->initBackBuffer();
getStudio().action(); // place the camera which is between LEFT_EYE and RIGHT_EYE positions
// render the scene
_renderScene();
}

s_WAbs->swapBuffers();
}

The clearAllBuffers is :

code:


clearAllBuffers()
{
// We select back buffer so that nicely written opengl drivers should clear
// right and left buffer when in stereo mode at the same time.
glDrawBuffer(GL_BACK);

if (((SimpleSetting<bool> *) Settings::getInstance()->getSetting(Settings::SHADOWS))->getValue()
| | ((SimpleSetting<bool> *) Settings::getInstance()->getSetting(Settings::REFLECTIONS))->getValue()
| | ((SimpleSetting<bool> *) Settings::getInstance()->getSetting(Settings::HALOS))->getValue())
{
glClearStencil(0);
glStencilMask(0xff);
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
}
else
{
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
}

initBackbuffer is :

code:


initBackBuffer()
{
glDrawBuffer( GL_BACK );
}

I feel like it might be because of initBackBuffer ?! If stereo mode is enable maybe I should select either left or right back buffer and not GL_BACK ???

Anyone ?

--- recent Addition

Well, I tried to change the call (in initBackBuffer) to select the left back buffer, and then animation went smooth.
Unfortunelately, doing so is not enough because the right buffer is of course black, so animation is flickering http://www.opengl.org/discussion_boards/ubb/frown.gifscene/black/scene/black...).

If after drawing in the left back buffer, I draw in the right back buffer (without changing the point of view), animation is smooth and there is no more flickering but as slow as in stereo (which is logic).

My very first try was to select the back buffer (GL_BACK) and draw once the scene, and call swap buffer but in that case animation is choppy (which is strange)...

What I would like is to be able to get a smooth animation and ALSO an increase in FPS when switching to non-stereo rendering in my stereo enabled app...

Anyone? ...please.

Lekeno

XaVinci
09-29-2003, 05:16 AM
>Well, I tried to change the call (in >initBackBuffer) to select the left back >buffer, and then animation went smooth.
>Unfortunelately, doing so is not enough >because the right buffer is of course >black, so animation is flickering >scene/black/scene/black...).

I have encountered this problem as well on nvidia quadro cards. I think specifying GL_BACK might indicate rendering into both GL_BACK_LEFT and GL_BACK_RIGHT buffers or something. I m not sure why it is different on nvidia cards.

To overcome the problem that your right buffer is black, you can do the following

glDrawBuffer (GL_BACK_LEFT);
GLenum bufferToCopy = GL_BACK_LEFT;
rendermonoscene;
glDrawBuffer (GL_BACK_RIGHT);
glReadBuffer(bufferToCopy);
glCopyPixels(0,0,_windowWidth,_windowHeight,GL_COL OR);

This would ensure you have the same contents in both GL_BACK_LEFT and GL_BACK_RIGHT buffers. glCopyPixels in this situation is very fast.


Cheers
XaVinci

Relic
09-30-2003, 12:11 AM
You are aware that there is only one depth buffer spec'ed in stereo?

You're stereo code should actually look like this:



{
// the following line is a bit complex but basically it is the same as if '(stereoActive)'
if (((SimpleSetting<bool> *) Settings::getInstance()->getSetting(Settings::STEREO))->getValue())
{
// LEFT EYE
glDrawBuffer(GL_BACK_LEFT);
clearAllBuffers();
s_Stereolizer.lookWithLeftEye();
// Render the scene
_renderScene();

// RIGHT EYE
glDrawBuffer(GL_BACK_RIGHT);
clearAllBuffers();
s_Stereolizer.lookWithRightEye();
// Render the scene
_renderScene();
}
else
{
s_3D->modelViewMode();
s_3D->loadIdentity();
getStudio().action(); // place the camera which is between LEFT_EYE and RIGHT_EYE positions
// render the scene
glDrawBuffer(GL_BACK);
clearAllBuffers();
_renderScene();
}
s_WAbs->swapBuffers();
}


clearAllBuffers()
{
if (((SimpleSetting<bool> *) Settings::getInstance()->getSetting(Settings::SHADOWS))->getValue()
| | ((SimpleSetting<bool> *) Settings::getInstance()->getSetting(Settings::REFLECTIONS))->getValue()
| | ((SimpleSetting<bool> *) Settings::getInstance()->getSetting(Settings::HALOS))->getValue())
{
glClearStencil(0);
glStencilMask(0xff);
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
}
else
{
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
}
}



Clearing GL_BACK clears the back left and right buffers and the depth buffer. But when you render the back left image you've set depth values. Without clearing them you'll get not what you want on the right eye.
And the above code also works in case the OpenGL implementation supports two depth buffers, like some older boards did.

In case you experience a slowdown with the GL_BACK mode XaVinci has presented a valid workaround (he got from me http://www.opengl.org/discussion_boards/ubb/Forum3/HTML/008578.html http://www.opengl.org/discussion_boards/ubb/wink.gif).
You could also use the same buffer selection as in the real stereo case using the monoscopic viewing matrix, but this might be slower than the glCopyPixels.

In general, also try newer drivers if you experience problems.

lekeno
10-01-2003, 06:42 PM
Hi,
Thanks so much for those answers.




// LEFT EYE
glDrawBuffer(GL_BACK_LEFT);
clearAllBuffers();
s_Stereolizer.lookWithLeftEye();
// Render the scene
_renderScene();

// RIGHT EYE
glDrawBuffer(GL_BACK_RIGHT);
clearAllBuffers();
s_Stereolizer.lookWithRightEye();
// Render the scene
_renderScene();


Well indeed it was not clear at all but the Left/Right buffer was performed inside the method lookWith{Left/Right}Eye() in my Stereolizer class.

I did the glCopyPixels solution, and it's working !

Thanks a lot !

Lekeno.

[This message has been edited by lekeno (edited 10-01-2003).]

lekeno
10-02-2003, 12:54 AM
Well It was working until I play with my MIRROR-THE-SCREEN option (we need to mirror the screen because the screen is reflected on a half mirror).

So when I toggle the MIRROR-THE-SCREEN stuff,
the copy didn't work on non-mirrored mode and no longer on mirrored mode... http://www.opengl.org/discussion_boards/ubb/confused.gif

I search many things there and on the web (how do to a proper mirror-the-screen, how to use copyppixel, then I search for glRasterPos...).

Finally I found an interesting post in opengl forums. So I thought I will just share with everybody http://www.opengl.org/discussion_boards/ubb/cool.gif

I need to do that before calling glCopyPixel:




// from here....
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
// ... to there

// previous code (I changed to BACK buffers otherwise it was flickering)
glReadBuffer(GL_BACK_LEFT);
glDrawBuffer(GL_BACK_RIGHT);
glClear(GL_COLOR_BUFFER_BIT);
// I add this part too...
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glOrtho(0, width(), 0, height(), -1, 1);
glRasterPos2i(0,0);
// ...until there

// previous code
glCopyPixels(0,0,width(),height(),GL_COLOR);

// popping out
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();


Given that I didn't find much explanation about how to mirror the whole framebuffer, I include my solution as bonus. I hope it's correct (feel free to comment):




void reshape(const Point & topLeft, const Point & bottomRight)
{
GLsizei width = (GLsizei) (bottomRight - topLeft).x();
GLsizei height = (GLsizei) (bottomRight - topLeft).y();
// Dimensions must be strictly superior to zero
width = ((width <= 0) ? 1 : width);
height = ((height<= 0) ? 1 : height);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glutReshapeWindow(width, height);
glViewport(0, 0, width, height);

if (((SimpleSetting<bool> *) Settings::getInstance()->getSetting(Settings::MIRROR))->getValue())
{
// left, right, bottom, top, znear zfar
glOrtho(-1.0, 1.0, 1.0, -1.0, 1.0, -1.0);
// Cull front faces (because of ortho mirroring)
glCullFace(GL_FRONT);
}
else
{
// Cull back faces (usual setting)
glCullFace(GL_BACK);
}
glEnable(GL_CULL_FACE);

gluPerspective(FOV,(GLfloat)width/(GLfloat)height, NEAR, FAR);

glMatrixMode(GL_MODELVIEW);
}


Thanks.

Lekeno