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

Reply via email to