查看: 2206|回复: 6

怎么样获得立体下的左右眼场景图

[复制链接]

该用户从未签到

发表于 2010-8-12 14:10:13 | 显示全部楼层 |阅读模式
我想用RTT相机输出分辨率高一点的立体图片,下为部分源码
osg:isplaySettings::instance()->setStereo(1);
osg::DisplaySettings::instance()->setStereoMode(osg::DisplaySettings::left_EYE);//开启立体右眼


createPreRenderSubGraph(subGraph,1920,1200,16,8,RTTCamera,RTTImage);//创建相机
{
// set the camera to render before the main camera.
  LCamera->setRenderOrder(osg::Camera:RE_RENDER);
  // tell the camera to use OpenGL frame buffer object where supported.
  LCamera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT);
  //osg::Image* LImage = new osg::Image;
  LImage->allocateImage(tex_width, tex_height, 1, GL_RGBA, GL_UNSIGNED_BYTE);
  // attach the image so its copied on each frame.
  LCamera->attach(osg::Camera::COLOR_BUFFER, LImage,
   samples, colorSamples);
   // add subgraph to render
  LCamera->addChild(subgraph);
}

RTTCamera->setViewMatrix(keyswitchManipulator.get()->getInverseMatrix());//绑定相机和场景相机位置
  RTTCamera->setProjectionMatrix(viewer.getCamera()->getProjectionMatrix());//绑定相机和场景相机投影

我用考屏的图和RTT相机输出的图比较发现:
输出的图像不和左眼图像一样,一点偏移都没有,和没有开启立体一样。怎么回事,请大侠指点。还有怎么获得左眼的RTT影像。

该用户从未签到

发表于 2010-8-12 14:50:31 | 显示全部楼层
简单来说,我不知道您的这段程序都做了什么

该用户从未签到

 楼主| 发表于 2010-8-12 16:36:25 | 显示全部楼层
我只写了关键的代码,我想你明白的。

该用户从未签到

 楼主| 发表于 2010-8-12 16:45:38 | 显示全部楼层
#include "stdafx.h"


#include <osgDB/ReadFile>
#include <osgUtil/Optimizer>
#include <osg/CoordinateSystemNode>

#include <osg/Switch>
#include <osgText/Text>

#include <osgViewer/Viewer>
#include <osgViewer/ViewerEventHandlers>

#include <osgGA/TrackballManipulator>
#include <osgGA/FlightManipulator>
#include <osgGA/DriveManipulator>
#include <osgGA/KeySwitchMatrixManipulator>
#include <osgGA/StateSetManipulator>
#include <osgGA/AnimationPathManipulator>
#include <osgGA/TerrainManipulator>

#include "planeManipulator.h"

#include <osg/Vec3>
#include <osg/Vec4>
#include <osg/Quat>
#include <osg/Matrix>
#include <osg/ShapeDrawable>
#include <osg/Geometry>
#include <osg/Geode>
#include <osg/Transform>
#include <osg/Material>
#include <osg/NodeCallback>
#include <osg/Depth>
#include <osg/CullFace>
#include <osg/TexMat>
#include <osg/TexGen>
#include <osg/TexEnv>
#include <osg/TexEnvCombine>
#include <osg/TextureCubeMap>
#include <osg/VertexProgram>

#include <osgDB/Registry>
#include <osgDB/ReadFile>
#include <osgDB/WriteFile>

#include <osgUtil/SmoothingVisitor>

#include "StereoTerrainManipulator.h"

#include <iostream>

bool g_bSave=false;

void createPreRenderSubGraph(osg::Node* subgraph,
         unsigned tex_width, unsigned tex_height,
         unsigned int samples, unsigned int colorSamples,osg::Camera *LCamera,osg::Image *LImage)


{   

         // set up the background color and clear mask.

         LCamera->setClearColor(osg::Vec4(0.0f,0.0f,0.0f,1.0f));
         LCamera->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

         // set view
         LCamera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
         // set viewport
         LCamera->setViewport(0,0,tex_width,tex_height);

         // set the camera to render before the main camera.
         LCamera->setRenderOrder(osg::Camera:RE_RENDER);

         // tell the camera to use OpenGL frame buffer object where supported.
         LCamera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT);
         //osg::Image* LImage = new osg::Image;
         LImage->allocateImage(tex_width, tex_height, 1, GL_RGBA, GL_UNSIGNED_BYTE);

         // attach the image so its copied on each frame.
         LCamera->attach(osg::Camera::COLOR_BUFFER, LImage,
                 samples, colorSamples);

         //  LCamera->setPostDrawCallback(new LMyCameraPostDrawCallback(LImage,"Left.bmp"));
         // add subgraph to render
         LCamera->addChild(subgraph);
}


class KeyboardEventHandler : public osgGA::GUIEventHandler
{
public:

        virtual bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter&)
        {

                switch(ea.getEventType())
                {
                case(osgGA::GUIEventAdapter::KEYDOWN):
                        {
                                switch(ea.getKey())
                                {
                                case('n'):
                                        {
                                       g_bSave=true;
                                        return true;
                                        }
                default:
                        return false;
                        }
                }

        }

};

int main(int argc, char** argv)
{
        setlocale(LC_ALL,"chinese-simplified" );

        osg::ArgumentParser arguments(&argc,argv);

        arguments.getApplicationUsage()->setApplicationName(arguments.getApplicationName());
        arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is the standard OpenSceneGraph example which loads and visualises 3d models.");
        arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] filename ...");
        arguments.getApplicationUsage()->addCommandLineOption("--image <filename>","Load an image and render it on a quad");
        arguments.getApplicationUsage()->addCommandLineOption("--dem <filename>","Load an image/DEM and render it on a HeightField");
        arguments.getApplicationUsage()->addCommandLineOption("--login <url> <username> <password>","rovide authentication information for http file access.");

        osgViewer::Viewer viewer(arguments);

        unsigned int helpType = 0;
        if ((helpType = arguments.readHelpType()))
        {
                arguments.getApplicationUsage()->write(std::cout, helpType);
                return 1;
        }

        // report any errors if they have occurred when parsing the program arguments.
        if (arguments.errors())
        {
                arguments.writeErrorMessages(std::cout);
                return 1;
        }

        /*if (arguments.argc()<=1)
        {
        arguments.getApplicationUsage()->write(std::cout,osg::ApplicationUsage::COMMAND_LINE_OPTION);
        return 1;
        }*/

        std::string url, username, password;
        while(arguments.read("--login",url, username, password))
        {
                if (!osgDB::Registry::instance()->getAuthenticationMap())
                {
                        osgDB::Registry::instance()->setAuthenticationMap(new osgDB::AuthenticationMap);
                        osgDB::Registry::instance()->getAuthenticationMap()->addAuthenticationDetails(
                                url,
                                new osgDB::AuthenticationDetails(username, password)
                                );
                }
        }

        // set up the camera manipulators.
       
                osg::ref_ptr<osgGA::KeySwitchMatrixManipulator> keyswitchManipulator = new osgGA::KeySwitchMatrixManipulator;

                keyswitchManipulator->addMatrixManipulator( '1', "Trackball", new osgGA::TrackballManipulator() );
                keyswitchManipulator->addMatrixManipulator( '2', "Flight", new osgGA::FlightManipulator() );
                keyswitchManipulator->addMatrixManipulator( '3', "Drive", new osgGA:riveManipulator() );
                keyswitchManipulator->addMatrixManipulator( '4', "Terrain", new osgGA::TerrainManipulator() );

                std::string pathfile;
                char keyForAnimationPath = '5';
                while (arguments.read("-p",pathfile))
                {
                //osgGA::AnimationPathManipulator* apm = new osgGA::AnimationPathManipulator("KeyPoint.path");
                osgGA::AnimationPathManipulator* apm = new osgGA::AnimationPathManipulator(pathfile);
                if (apm || !apm->valid())
                {
                        unsigned int num = keyswitchManipulator->getNumMatrixManipulators();
                        keyswitchManipulator->addMatrixManipulator( keyForAnimationPath, "Path", apm );
                        keyswitchManipulator->selectMatrixManipulator(num);
                        ++keyForAnimationPath;
                }
                }
               
                keyswitchManipulator->selectMatrixManipulator(3);
                viewer.setCameraManipulator( keyswitchManipulator.get() );
       
     osg::ref_ptr <osg::Camera>RTTCamera=new osg::Camera;//虚拟相机
     osg::Image *RTTImage=new osg::Image;//虚拟图像

        viewer.getCamera()->setClearColor(osg::Vec4(0.0,0.0,0.0,1));
        // add the state manipulator
        viewer.addEventHandler( new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()) );

        // add the thread model handler
        viewer.addEventHandler(new osgViewer::ThreadingHandler);

        // add the window size toggle handler
        viewer.addEventHandler(new osgViewer::WindowSizeHandler);

        // add the stats handler
        viewer.addEventHandler(new osgViewer::StatsHandler);

        // add the help handler
        viewer.addEventHandler(new osgViewer::HelpHandler(arguments.getApplicationUsage()));

        // add the record camera path handler
        viewer.addEventHandler(new osgViewer::RecordCameraPathHandler);

        // add the LOD Scale handler
        viewer.addEventHandler(new osgViewer:ODScaleHandler);

        // add the screen capture handler
        viewer.addEventHandler(new osgViewer::ScreenCaptureHandler);

        viewer.addEventHandler(new KeyboardEventHandler());

        osg::ref_ptr<osg::Node> loadedModel = osgDB::readNodeFile("cow.osg");
       
        if (!loadedModel)
        {
                std::cout << arguments.getApplicationName() <<": No data loaded" << std::endl;
                return 1;
        }

   

        // any option left unread are converted into errors to write out later.
        arguments.reportRemainingOptionsAsUnrecognized();

        // report any errors if they have occurred when parsing the program arguments.
        if (arguments.errors())
        {
                arguments.writeErrorMessages(std::cout);
                return 1;
        }

        osg::ref_ptr<osg::Group> root=new osg::Group();

        osg::ref_ptr<osg::Group>subGraph=new osg::Group();

   
        subGraph->addChild(loadedModel.get());
   
         createPreRenderSubGraph(subGraph,1920,1200,16,8,RTTCamera,RTTImage);
         
    root->addChild(RTTCamera);

    root->addChild(loadedModel.get());

        // optimize the scene graph, remove redundant nodes and state etc.
        osgUtil::Optimizer optimizer;

        optimizer.optimize(root.get());

        viewer.setSceneData( root.get() );

        Matrixd mProjection=viewer.getCamera()->getProjectionMatrix();

        osg::DisplaySettings::instance()->setStereo(1);
        osg::DisplaySettings::instance()->setStereoMode(osg::DisplaySettings::LEFT_EYE);//左眼立体

        viewer.realize();

        while( !viewer.done() )
        {
                RTTCamera->setViewMatrix(keyswitchManipulator.get()->getInverseMatrix());
    RTTCamera->setProjectionMatrix(viewer.getCamera()->getProjectionMatrix());
   
                if(g_bSave==true)
                {
                        osgDB::writeImageFile(*RTTImage,"Copy.bmp");
                        g_bSave=false;
                }

                viewer.frame();

        }
        return 0;
}

该用户从未签到

 楼主| 发表于 2010-8-12 16:45:55 | 显示全部楼层
本帖最后由 tty1960 于 2010-8-12 16:51 编辑

就是想通过RTT相机输出左眼图像,再通过RTT相机输出右眼图像,输出之后做出红绿立体图打印出来,却发现RTT相机输出的和屏幕上所见的不一样。还请指点~

该用户从未签到

发表于 2010-8-13 08:26:17 | 显示全部楼层
  1. while( !viewer.done() )
  2.         {
  3.                 RTTCamera->setViewMatrix(keyswitchManipulator.get()->getInverseMatrix());
  4.                 RTTCamera->setProjectionMatrix(viewer.getCamera()->getProjectionMatrix());
  5.                 ...
复制代码
恐怕您不能由此得到LEFT_EYE对应的观察和投影矩阵,因为它的计算结果是直接用于底层的cull和draw的,而并没有反馈到Camera节点上来。您可以尝试取消这两行,并取消RTTCamera的ABSOLUTE_RF属性,使其继承整个场景根的观察和投影矩阵

我只写了关键的代码,我想你明白的

很显然,最关键的代码并不是您已开始列出的那些~~

该用户从未签到

 楼主| 发表于 2010-8-13 09:49:04 | 显示全部楼层
万分感谢,搞定,看来对底层还要多了解下~
您需要登录后才可以回帖 登录 | 注册

本版积分规则

OSG中国官方论坛-有您OSG在中国才更好

网站简介:osgChina是国内首个三维相关技术开源社区,旨在为国内更多的技术开发人员提供最前沿的技术资讯,为更多的三维从业者提供一个学习、交流的技术平台。

联系我们

  • 工作时间:09:00--18:00
  • 反馈邮箱:1315785073@qq.com
快速回复 返回顶部 返回列表