Hi Michael.
We support several stereo modes, including none, anaglyph, side-by-
side, and active.
For side-by-side, we simply create two viewports in one window. In
width, one viewport extends from 0.0 to 0.5, the other extends from 0.5
to 1.0.
For a 16x9 projection surface, we create a 32x9 window with side-by-
side 16x9 viewports. The window spans across two projectors with
polarizing filters, aligned to project each 16x9 viewport onto the
same surface.
Here's some code:
// Create an OpenSG PassiveBackground and PassiveWindow that don't mess
with
// the GL state. This allows us to implement alternative stereo modes
and
// custom render features.
//
// In OpenSg 2.0, PassiveWindow derives from NativeWindow, which is a
// typedef for the system-specific window class -- e.g., WIN32Window.
int width, height;
glfwGetWindowSize (&width, &height);
m_Background = OSG::PassiveBackground::create();
m_Window = OSG::PassiveWindow::create();
m_Window->resize (width, height);
#ifdef WIN32
m_Window->setHwnd (m_HWND);
m_Window->setHdc (m_HDC);
m_Window->setHglrc (m_HGLRC);
#endif
// Determine the viewport bounds and the stereo camera separation.
//
// NOTE: The OSG::PassiveViewport isn't passive enough! Its render()
// function calls glGetIntegerv(GL_VIEWPORT, vp) to reset the OSG
viewport
// limits. If we don't explicitly call glViewport() ourselves before
each
// render(), it sets the viewport to the entire window. In contrast,
the
// basic OSG::Viewport preserves the viewport boundaries that we set
here.
// Its activateSize() function calls glViewport() for us.
float left_min, left_max, right_min, right_max;
switch (m_StereoMode)
{
case ACTIVE_STEREO:
case ANAGLYPH_STEREO:
left_min = right_min = 0.0f;
left_max = right_max = 1.0f;
break;
case SPLIT_LR_STEREO:
left_min = 0.0f;
left_max = 0.5f;
right_min = 0.5f;
right_max = 1.0f;
break;
case SPLIT_RL_STEREO: // for cross-eyed stereo.
left_min = 0.5f;
left_max = 1.0f;
right_min = 0.0f;
right_max = 0.5f;
break;
case NO_STEREO:
default:
m_StereoMode = NO_STEREO;
stereo_sep = 0.0f;
left_min = right_min = 0.0f;
left_max = right_max = 1.0f;
break;
}
// The SceneManager defines the user transform relative to the camera.
OSG::NodeRefPtr user = SceneManager::getUserTransform (camera);
// Get the corners of the display surface.
const gmtl::Point3f * corners = m_DisplaySurface.getCorners();
OSG::MFPnt3f * deco_surface;
// Create the camera decorator and viewport for the mono or left eye.
m_CameraDecoratorLeft = OSG::ProjectionCameraDecorator::create();
m_CameraDecoratorLeft->setUser (user);
m_CameraDecoratorLeft->setDecoratee (camera);
m_CameraDecoratorLeft->setLeftEye (true);
m_CameraDecoratorLeft->setEyeSeparation (stereo_sep);
deco_surface = m_CameraDecoratorLeft->editMFSurface();
deco_surface->clear();
deco_surface->push_back (toOSG (corners[0]));
deco_surface->push_back (toOSG (corners[1]));
deco_surface->push_back (toOSG (corners[2]));
deco_surface->push_back (toOSG (corners[3]));
m_ViewportLeft = OSG::Viewport::create();
m_ViewportLeft->setBackground (m_Background);
m_ViewportLeft->setSize (left_min, 0.f, left_max, 1.f);
m_ViewportLeft->setRoot (root);
m_ViewportLeft->setCamera (m_CameraDecoratorLeft);
m_Window->addPort (m_ViewportLeft);
// Create the camera decorator and viewport for the right eye.
if (m_StereoMode != NO_STEREO)
{
m_CameraDecoratorRight =
OSG::ProjectionCameraDecorator::create();
m_CameraDecoratorRight->setUser (user);
m_CameraDecoratorRight->setDecoratee (camera);
m_CameraDecoratorRight->setLeftEye (false);
m_CameraDecoratorRight->setEyeSeparation (stereo_sep);
deco_surface = m_CameraDecoratorRight->editMFSurface();
deco_surface->clear();
deco_surface->push_back (toOSG (corners[0]));
deco_surface->push_back (toOSG (corners[1]));
deco_surface->push_back (toOSG (corners[2]));
deco_surface->push_back (toOSG (corners[3]));
m_ViewportRight = OSG::Viewport::create();
m_ViewportRight->setBackground (m_Background);
m_ViewportRight->setSize (right_min, 0.f, right_max, 1.f);
m_ViewportRight->setRoot (root);
m_ViewportRight->setCamera (m_CameraDecoratorRight);
m_Window->addPort (m_ViewportRight);
}
m_Window->init();
Hope this helps.
-- Ted
-----Original Message-----
From: Michael Raab [mailto:[email protected]]
Sent: Thursday, February 24, 2011 07:38
To: [email protected]
Subject: [Opensg-users] OpenSG1.8 - Side by Side Stereo
Hi all,
we're thinking about implementing side by side stereo output format for our
OpenSG based application. Our approach would be to render left eye and right
eye each in a separate FBO, map the two resulting textures on a quad (left eye
0.0->0.5 and right eye 0.5->1.0) and render this with a orthographic camera to
receive the final output.
First question, has someone tried to implement side by side before? Are there
any proven (or better) ways of doing this with OpenSG?
A special condition is that we're using OpenSG shadows (by osg::ShadowViewport)
in our application. Is it possible to render shadowed scenes to an OpenSG
FBOViewport? At the moment I don't see how.
Thanks & Best regards,
Michael
------------------------------------------------------------------------------
Free Software Download: Index, Search & Analyze Logs and other IT data in
Real-Time with Splunk. Collect, index and harness all the fast moving IT data
generated by your applications, servers and devices whether physical, virtual
or in the cloud. Deliver compliance at lower cost and gain new business
insights. http://p.sf.net/sfu/splunk-dev2dev
_______________________________________________
Opensg-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensg-users