查看: 4020|回复: 16

用一个主相机,两个从相机同时渲染一个场景。在程序中显示不了CEGUI的界面

[复制链接]

该用户从未签到

发表于 2012-10-31 17:37:29 | 显示全部楼层 |阅读模式
如题:
在程序中我用一个主相机,两个从相机来渲染同一个场景,在程序中用CEGUI做的界面,可是刚开始运行的时候,界面就显示不出来了,不知道用主相机和从相机来渲染同一个场景的时候,CEGUI界面应该怎么处理呢?
一些代码:
osg::Camera* createCamera(int x, int y, int w, int h)
{
        osg::ref_ptr<osg::GraphicsContext::Traits> trait = new osg::GraphicsContext::Traits();
        trait->x = x;
        trait->y = y;
        trait->width = w;
        trait->height = h;
        trait->windowDecoration = false;
        trait->doubleBuffer = true;

        double fov;
        double ratio;
        double nearPlane;
        double farPlane;

        double newAspectRaito = double(trait->width)/double(trait->height);

        osg:isplaySettings *ds = osg::DisplaySettings::instance();
        trait->alpha = ds->getMinimumNumAlphaBits();
        trait->stencil = ds->getMinimumNumStencilBits();
        trait->sampleBuffers = ds->getMultiSamples();
        trait->samples = ds->getNumMultiSamples();

        osg::ref_ptr<osg::GraphicsContext> gc = osg::GraphicsContext::createGraphicsContext(trait.get());
        osg::ref_ptr<osg::Camera> camera = new osg::Camera();
        camera->setGraphicsContext(gc.get());
        camera->setViewport(new osg::Viewport(0,0,w,h));
        //设置视景参数,将yz平面视野角度设为50°
        //换取对称视景个参数并显示,每个屏幕都有对应的ratio,所以必须先get再set
        camera->getProjectionMatrixAsPerspective( fov,ratio,nearPlane,farPlane);
        camera->setProjectionMatrixAsPerspective(50.0f, newAspectRaito, 1, 1000.0);
        camera->setNearFarRatio(0.000003f);
        camera->setClearColor(osg::Vec4(0.0,0.0,0.0,0.5));
        return camera.release();
}
main函数相关代码:
        //得到窗口的图形环境
        osg::GraphicsContext::WindowingSystemInterface* wsi = osg::GraphicsContext::getWindowingSystemInterface();
        if (!wsi)
        {
                osg::notify(osg::NOTICE)<<"Error, no WindowSystemInterface available, cannot create windows."<<std::endl;
        }
        unsigned int tileWidth, tileHeight;
        wsi->getScreenResolution(osg::GraphicsContext::ScreenIdentifier(0), tileWidth ,tileHeight);

        //初始化主相机
        osg::ref_ptr<osg::GraphicsContext::Traits> mastertrait = new osg::GraphicsContext::Traits();
        mastertrait->x = tileWidth/3+5;
        mastertrait->y = 0;
        mastertrait->width = tileWidth/3;
        mastertrait->height = tileHeight;
        mastertrait->windowDecoration = false;
        mastertrait->doubleBuffer = true;

        osg::DisplaySettings *ds = osg::DisplaySettings::instance();
        mastertrait->alpha = ds->getMinimumNumAlphaBits();
        mastertrait->stencil = ds->getMinimumNumStencilBits();
        mastertrait->sampleBuffers = ds->getMultiSamples();
        mastertrait->samples = ds->getNumMultiSamples();

        osg::ref_ptr<osg::GraphicsContext> mastergc = osg::GraphicsContext::createGraphicsContext(mastertrait.get());
        osg::ref_ptr<osg::Camera> masterCamera = new osg::Camera();
        masterCamera = viewer->getCamera();
        masterCamera->setGraphicsContext(mastergc.get());
        masterCamera->setViewport(new osg::Viewport(0,0,mastertrait->width,mastertrait->height));
                //添加从相机
        viewer->addSlave(createCamera(0,0,tileWidth/3,tileHeight),osg::Matrixd::translate(2.0,0.0,0.0),osg::Matrixd());
        viewer->addSlave(createCamera(2*tileWidth/3,0,tileWidth/3,tileHeight),osg::Matrixd::translate(-2.0,0.0,0.0),osg::Matrixd());
       
                osg::ref_ptr<osgViewer::GraphicsWindowWin32> gcwin32=dynamic_cast<osgViewer::GraphicsWindowWin32*>(masterCamera->getGraphicsContext());


        //UI
        masterCamera->getGraphicsContext()->makeCurrent();                                                //创建背景图片
        osg::ref_ptr<osg::Geode> geode = new osg::Geode;


        osg::ref_ptr<CEGUIDrawable> cd = new CEGUIDrawable(sceneMgr,KeySoundNode,viewer,ClickSoundNode,gcwin32/*,printer.get()*/);//界面节点
        geode->addDrawable(cd.get());

该用户从未签到

发表于 2012-11-1 08:10:48 | 显示全部楼层
CEGUI的Drawable放在HUD中 清空depthbuffer

该用户从未签到

 楼主| 发表于 2012-11-1 09:07:46 | 显示全部楼层
liuzhiyu123 发表于 2012-11-1 08:10
CEGUI的Drawable放在HUD中 清空depthbuffer

呃。。。。直接挂在根节点下边为何不行呢?之前用一个相机的时候是直接挂在root下边的。不知道后来用三个相机渲染的时候为什么界面消失不见了!

该用户从未签到

发表于 2012-11-1 09:33:24 | 显示全部楼层
buptronin 发表于 2012-11-1 09:07
呃。。。。直接挂在根节点下边为何不行呢?之前用一个相机的时候是直接挂在root下边的。不知道后来用三个 ...

看不见有一下几种可能:被裁剪,ZBuffer被覆盖

该用户从未签到

 楼主| 发表于 2012-11-1 09:51:47 | 显示全部楼层
liuzhiyu123 发表于 2012-11-1 09:33
看不见有一下几种可能:被裁剪,ZBuffer被覆盖

//创建HUD相机
                osg::ref_ptr<osg::Camera> HUDCamera = new osg::Camera();
                HUDCamera->setProjectionMatrix(osg::Matrix:rtho2D(0,tileWidth/3,0,tileHeight));
                HUDCamera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
                HUDCamera->setViewMatrix(osg::Matrix::identity());
                HUDCamera->setClearMask(GL_DEPTH_BUFFER_BIT);
                HUDCamera->setRenderOrder(osg::Camera:OST_RENDER);
       
        //root->addChild(CreateBackground());                                                        //创建背景图片
        osg::ref_ptr<osg::Geode> geode = new osg::Geode;
        osg::ref_ptr<CEGUIDrawable> cd = new CEGUIDrawable(sceneMgr,KeySoundNode,viewer,ClickSoundNode,gcwin32/*,printer.get()*/);//界面节点
        geode->addDrawable(cd.get());
        geode->getOrCreateStateSet()->setMode(GL_LIGHTING,osg::StateAttribute::ON);
        geode->getOrCreateStateSet()->setMode(GL_DEPTH_TEST,osg::StateAttribute::OFF);
        cd->Init();//初始化事件处理函数pinfo
        HUDCamera->addChild(geode.get());                                //初始化UI
        root->addChild(HUDCamera);

修改后大体是这样,可还是没有了界面!不知道是不是程序哪个地方出错了,还是没有考虑到别的东西!

该用户从未签到

发表于 2012-11-1 09:55:40 | 显示全部楼层
检查摄像机的方向是否正确

该用户从未签到

 楼主| 发表于 2012-11-1 10:10:49 | 显示全部楼层
liuzhiyu123 发表于 2012-11-1 09:55
检查摄像机的方向是否正确

摄像机方向?程序里边好像确实没操作过摄像机方向。那正确的方向是应该什么呢?应该使用的是默认的方向吧。不好意思,麻烦版主了!

该用户从未签到

发表于 2012-11-1 10:23:53 | 显示全部楼层
HUDCamera->setProjectionMatrix(osg::Matrix:rtho2D(0,tileWidth/3,0,tileHeight)); 是多少?

该用户从未签到

 楼主| 发表于 2012-11-1 10:55:15 | 显示全部楼层
liuzhiyu123 发表于 2012-11-1 10:23
HUDCamera->setProjectionMatrix(osg::Matrix:rtho2D(0,tileWidth/3,0,tileHeight)); 是多少?

是这样的,我用一台主机接了三个显示器,(tileWidth/3,tileHeight)应该就是一个显示器的长宽吧!

该用户从未签到

发表于 2012-11-1 11:01:00 | 显示全部楼层
buptronin 发表于 2012-11-1 10:55
是这样的,我用一台主机接了三个显示器,(tileWidth/3,tileHeight)应该就是一个显示器的长宽吧!

设置的大一点,估计是这里的问题了,透视矩阵 全部裁剪了

该用户从未签到

 楼主| 发表于 2012-11-1 14:10:23 | 显示全部楼层
liuzhiyu123 发表于 2012-11-1 11:01
设置的大一点,估计是这里的问题了,透视矩阵 全部裁剪了

现在设置成HUDCamera->setProjectionMatrix(osg::Matrix:rtho2D(0,tileWidth,0,tileHeight)); 应该最大的了。还是不能显示界面!不知道是不是CEGUI界面在用多个相机渲染的时候,应该去设置一些什么!之前只用主相机渲染的时候,必须添加viewer->getCamera()->getGraphicsContext()->makeCurrent();但是现在有三个相机了,
主相机:osg::ref_ptr<osg::Camera> masterCamera = new osg::Camera();
              masterCamera = viewer->getCamera();
两个从相机:
       viewer->addSlave(createCamera(0,0,tileWidth/3,tileHeight),osg::Matrixd::translate(2.0,0.0,0.0),osg::Matrixd());
            viewer->addSlave(createCamera(2*tileWidth/3,0,tileWidth/3,tileHeight),osg::Matrixd::translate(-2.0,0.0,0.0),osg::Matrixd());
如果单独对主相机设置masterCamera ->getGraphicsContext()->makeCurrent();是不是这个地方会对界面的显示产生影响呢?

该用户从未签到

发表于 2012-11-1 15:22:50 | 显示全部楼层
buptronin 发表于 2012-11-1 14:10
现在设置成HUDCamera->setProjectionMatrix(osg::Matrix:rtho2D(0,tileWidth,0,tileHeight)); 应该最大的 ...

HUDCamera->setProjectionMatrix(osg::Matrix:rtho2D(0,tileWidth,0,tileHeight)) 具体是多少和您的CEGUI的场景是多大可以进行比较。不知道您的代码具体是怎么写的,还是对比一下其他工程中cegui的实现,osgRecipes或者osgXI中都实现。

该用户从未签到

 楼主| 发表于 2012-11-1 15:26:48 | 显示全部楼层
liuzhiyu123 发表于 2012-11-1 11:01
设置的大一点,估计是这里的问题了,透视矩阵 全部裁剪了

发现问题出在哪了!但是不能解决!
问题程序部分:
//初始化主相机图形环境
        osg::ref_ptr<osg::GraphicsContext::Traits> mastertrait = new osg::GraphicsContext::Traits();
        mastertrait->x = 0;
        mastertrait->y = 0;
        mastertrait->width = tileWidth;
        mastertrait->height = tileHeight;
        mastertrait->windowDecoration = false;
        mastertrait->doubleBuffer = true;
        mastertrait->useCursor = false;
        osg:isplaySettings *ds = osg::DisplaySettings::instance();
        mastertrait->alpha = ds->getMinimumNumAlphaBits();
        mastertrait->stencil = ds->getMinimumNumStencilBits();
        mastertrait->sampleBuffers = ds->getMultiSamples();
        mastertrait->samples = ds->getNumMultiSamples();

        osg::ref_ptr<osg::GraphicsContext> mastergc = osg::GraphicsContext::createGraphicsContext(mastertrait.get());
        osg::ref_ptr<osg::Camera> masterCamera = new osg::Camera();
        masterCamera = viewer->getCamera();
        masterCamera->setGraphicsContext(mastergc.get());
        masterCamera->setViewport(new osg::Viewport(0,0,mastertrait->width,mastertrait->height));

对上边的程序,如果我不使用这句masterCamera->setGraphicsContext(mastergc.get());界面就绝对不会有问题,如果加上了这句话,也就是设置了图形环境,即便只用一个主相机渲染,界面也显示不了!
为什么不能对主相机设置图形环境呢?这对CEGUI界面有什么影响?

该用户从未签到

发表于 2012-11-1 17:29:02 | 显示全部楼层
buptronin 发表于 2012-11-1 15:26
发现问题出在哪了!但是不能解决!
问题程序部分:
//初始化主相机图形环境

你试试图形上下文可以设置为透明的不

该用户从未签到

发表于 2012-11-2 07:59:43 | 显示全部楼层
跟设置gc有什么关系?

该用户从未签到

 楼主| 发表于 2012-11-2 08:55:53 | 显示全部楼层
liuzhiyu123 发表于 2012-11-2 07:59
跟设置gc有什么关系?

嗯,我也诧异啊!设置gc跟界面有什么关系呢?原本用三个相机渲染的,现在我即便只用一个主相机,并对主相机设置gc,别的程序不修改,结果就是界面显示不了了。但是如果不对主相机重新设置gc的话就可以显示界面!不知道这个里面存在什么问题?

该用户从未签到

发表于 2017-5-10 15:05:29 | 显示全部楼层
请问这个问题搞清楚了吗?能否讲解一下
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

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

联系我们

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