查看: 4174|回复: 4

addslave添加多个从相机渲染场景,不能显示CEGUI的界面了,提示makecurrent()失败!

[复制链接]

该用户从未签到

发表于 2012-11-8 13:13:41 | 显示全部楼层 |阅读模式
如题:
我想在我的程序当中用多个相机渲染场景,其中一个主相机,两个从相机,我的程序当中有CEGUI做的界面。用一个主相机渲染的时候,界面是可以显示的。但是如果在主相机下添加两个从相机以后,界面就不能显示了,或者直接中断报错!不知道是不是CEGUI的问题?
部分代码如下:
osg::Camera* createCamera(int x, int y, int w, int h,osg::Vec4 color)
{
        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;
        //trait->sharedContext = 0;
        trait->setInheritedWindowPixelFormat = true;
        //trait->inheritedWindowData = windata;
        osg:isplaySettings *ds = osg::DisplaySettings::instance();
        trait->alpha = ds->getMinimumNumAlphaBits();
        trait->stencil = ds->getMinimumNumStencilBits();
        trait->sampleBuffers = ds->getMultiSamples();
        trait->samples = ds->getNumMultiSamples();

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


        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));
        camera->setProjectionResizePolicy(osg::Camera:rojectionResizePolicy::FIXED);
        //换取对称视景个参数并显示,每个屏幕都有对应的ratio,所以必须先get在set
        camera->getProjectionMatrixAsPerspective( fov,ratio,nearPlane,farPlane);
        //设置视景参数,将yz平面视野角度设为50°
        camera->setProjectionMatrixAsPerspective(50.0f, ratio, 1, 500.0);
        camera->setNearFarRatio(0.000003f);
        camera->setClearColor(color);

        return camera.release();
}

int main(int argc, char *argv[])
{
        pathPoint = new osg::Vec3Array;
        softwareRigister softwareRegister;

        //防止程序启动多个
        HANDLE   hMutex   =   CreateMutex(NULL,true, "xxxx-xxxx");
        if(hMutex   !=0&&GetLastError()==ERROR_ALREADY_EXISTS)
        {
                MessageBoxA(NULL, "A INSTANCE HAS ALREADY BEEN STARTED!", "Warning", MB_OK);
                return   0;
        }

        HWND hwnd=GetForegroundWindow();//
        SendMessage(hwnd,WM_SETICON,ICON_SMALL,(LPARAM)LoadIcon(NULL,(LPCSTR)IDI_ICON1));

        //场景根节点
        osg::ref_ptr<osg::Group> root = new osg::Group;

        SpecialEffect *specialEffect = new SpecialEffect();
        InfoVisitor* infoVisitor = new InfoVisitor();

        //物理世界根节点
        PhysicsManager *physicsMgr = new PhysicsManager(infoVisitor);
        btDynamicsWorld* world = physicsMgr->initializePhysicWorld();
       
        //场景Viewer
        osg::ref_ptr<osgViewer::Viewer> viewer=new osgViewer::Viewer();  
        //        viewer->setUpViewInWindow(-10,0,800,800);
        //viewer->getCamera()->setClearMask(GL_DEPTH_TEST);//深度测试

        //场景漫游器
        osg::ref_ptr<TravelManipulator> mainCamera =new TravelManipulator(physicsMgr,viewer);
        viewer->setCameraManipulator(mainCamera);
        mainCamera->m_pHostViewer =viewer;  

        //场景管理器
        SceneManager* sceneMgr=new SceneManager(root,world,viewer,mainCamera,physicsMgr,specialEffect,infoVisitor);
        PhysicsManager::_scene = sceneMgr;
        PhysicsManager::m_pInfovisitor=infoVisitor;
        PhysicsManager::_root=root;
       
        //得到窗口的图形环境
        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);
       
        // 局部变量存放窗口矩形
        RECT rect;
        HWND m_hWnd;

        // 得到当前窗口矩形
        ::GetWindowRect(m_hWnd, &rect);

        // 初始化窗口变量,为OSG所用
        osg::ref_ptr<osg::Referenced> windata = new osgViewer::GraphicsWindowWin32::WindowData(m_hWnd);
       
        //初始化主相机图形环境
        osg::ref_ptr<osg::GraphicsContext::Traits> mastertrait = new osg::GraphicsContext::Traits();
        mastertrait->x = (rect.right - rect.left)/3;
        mastertrait->y = 0;
        mastertrait->width = (rect.right - rect.left)/3;//rect.right - rect.left
        mastertrait->height = rect.bottom - rect.top;//rect.bottom - rect.top;
        mastertrait->windowDecoration = false;
        mastertrait->doubleBuffer = true;
        mastertrait->useCursor = false;
        //mastertrait->sharedContext = 0;
        mastertrait->setInheritedWindowPixelFormat = true;
        mastertrait->inheritedWindowData = windata;

        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));
       

        GLenum buffer = mastertrait->doubleBuffer ? GL_BACK : GL_FRONT;

        masterCamera->setDrawBuffer(buffer);
        masterCamera->setReadBuffer(buffer);


        double fov;
        double aspectRatio;
        double nearPlane;
        double farPlane;
        double newAspectRatio;

        masterCamera->setProjectionResizePolicy(osg::Camera::ProjectionResizePolicy::FIXED);
        //换取对称视景个参数并显示,每个屏幕都有对应的ratio,所以必须先get在set
        masterCamera->getProjectionMatrixAsPerspective( fov,aspectRatio,nearPlane,farPlane);
        newAspectRatio = double(tileWidth)/double(tileHeight);
        double aspectRatiochange = newAspectRatio/aspectRatio;
        //设置视景参数,将yz平面视野角度设为50°
        masterCamera->setProjectionMatrixAsPerspective(90.0f, aspectRatio, 1, 500.0);
        masterCamera->setNearFarRatio(0.000003f);       
        //viewer->setUpViewAcrossAllScreens();//必须干掉这句话
        viewer->setReleaseContextAtEndOfFrameHint(false);
        viewer->setKeyEventSetsDone(0);//ESC
        viewer->setLightingMode(osg::View:ightingMode::HEADLIGHT);
        masterCamera->setClearColor(osg::Vec4(0.0,0.0,0.0,0.5));

        viewer->addSlave(createCamera(0,0,mastertrait->width,mastertrait->height,osg::Vec4(1.0,0.0,0.0,0.5)),osg::Matrixd::translate(2.0,0.0,0.0),osg::Matrixd());
        viewer->addSlave(createCamera(2*mastertrait->width,0,mastertrait->width,mastertrait->height,osg::Vec4(0.0,1.0,0.0,0.5)),osg::Matrixd::translate(-2.0,0.0,0.0),osg::Matrixd());

        //SceneSoundManager SoundCreate;
        osg::ref_ptr<osgAudio::SoundNode> KeySoundNode = SoundCreate->createKeystrokeSound("../Media/Sound/KeyWater.WAV");
        root->addChild(KeySoundNode);
        osg::ref_ptr<osgAudio::SoundNode> ClickSoundNode = SoundCreate->createClickstrokeSound("../Media/Sound/strokeball.WAV");
        root->addChild(ClickSoundNode);

        //Weather
        Weather* weather = NULL;
        weather        = Weather::getInstance();
        weather->setViewer(viewer);
        weather->setPhysics(physicsMgr);
        root->addEventCallback(weather);
       

        osg::ref_ptr<osgViewer::GraphicsWindowWin32> gcwin32=dynamic_cast<osgViewer::GraphicsWindowWin32*>(masterCamera->getGraphicsContext());
        //root->addEventCallback(new TestMinimizeHandler(gcwin32));


        //UI
        viewer->setThreadingModel(osgViewer::Viewer::SingleThreaded);
        viewer->realize();
        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());
        cd->Init();//初始化事件处理函数pinfo
        root->addChild(geode.get());       
        geode->getOrCreateStateSet()->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
        geode->getOrCreateStateSet()->setAttributeAndModes( new osg::BlendFunc );//初始化UI
        root->addEventCallback(new CEGUIUpdateCallback(geode,cd,sceneMgr,physicsMgr));

        viewer->setSceneData( root );



        softwareRegister.detecInstanseFunction();
        //传感器
        root->addUpdateCallback(new InputDataUpdateCallback(physicsMgr,viewer,mainCamera));




        osg::Timer_t frame_tick = osg::Timer::instance()->tick();
        while(!viewer->done())
        {       
                // Physics update

                osg::Timer_t now_tick = osg::Timer::instance()->tick();
                float dt = osg::Timer::instance()->delta_s(frame_tick, now_tick);
                frame_tick = now_tick;
                /* int numSimSteps = */
                world->stepSimulation(dt, maxSubStep, btScalar(1.)/btScalar(fixedTimeStep)); //, 10, 0.01);
                //world->stepSimulation(1.0/fixedTimeStep);
                world->updateAabbs();

                viewer->frame();  
        }

}

该用户从未签到

发表于 2012-11-9 14:34:52 | 显示全部楼层
您的CEGUI结合方案是什么?取自哪里?osg cookbook的例子还是别的什么,否则别人如何去进行试验

该用户从未签到

 楼主| 发表于 2012-11-10 00:12:17 | 显示全部楼层
array 发表于 2012-11-9 14:34
您的CEGUI结合方案是什么?取自哪里?osg cookbook的例子还是别的什么,否则别人如何去进行试验

没有参考osgcookbook,就是osg自带的那个例子,后来慢慢在这个上面自己各种拓展测试写的,现在想用多个相机的原因是因为一台主机接三个显示器显示场景两侧显示器显示的场景有拉伸变形,所以想用加两个从相机来渲染,但是,这个时候CEGUI界面又加不上了,报错的地方在makecurrent(),以上是cegui的一些代码,其余的代码太多了,没法弄上来,不知道array哥有没有用多相机添加上CEGUI界面的情况,后来在网上查,有一个帖子说是CEGUI不支持多个graphiccontext,不知道是不是真的!

该用户从未签到

发表于 2012-11-12 14:32:52 | 显示全部楼层
我记得CEGUI应该是不支持多个screen共享的,建立三个一样的cegui对象放在三个屏显示倒是应该没问题,您遇到的可能就是这个问题

该用户从未签到

发表于 2017-5-10 14:57:21 | 显示全部楼层
buptronin 发表于 2012-11-10 00:12
没有参考osgcookbook,就是osg自带的那个例子,后来慢慢在这个上面自己各种拓展测试写的,现在想用多个相 ...

请问这个问题怎么解决的
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

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

联系我们

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