diff --git a/examples/osgcamera/osgcamera.cpp b/examples/osgcamera/osgcamera.cpp index 0b5955cc6..bbfc13a54 100644 --- a/examples/osgcamera/osgcamera.cpp +++ b/examples/osgcamera/osgcamera.cpp @@ -7,42 +7,16 @@ #include #include #include +#include #include -int main( int argc, char **argv ) +void singleWindowMultipleCameras(osgViewer::Viewer& viewer) { - if (argc<2) - { - std::cout << argv[0] <<": requires filename argument." << std::endl; - return 1; - } - - - osg::DisplaySettings::instance()->setMaxNumberOfGraphicsContexts(2); - osg::Referenced::setThreadSafeReferenceCounting(true); - - // load the scene. - osg::ref_ptr loadedModel = osgDB::readNodeFile(argv[1]); - if (!loadedModel) - { - std::cout << argv[0] <<": No data loaded." << std::endl; - return 1; - } - - osgViewer::Viewer viewer; - - viewer.setSceneData(loadedModel.get()); - - viewer.setCameraManipulator(new osgGA::TrackballManipulator()); - viewer.getCamera()->setClearColor(osg::Vec4f(0.6f,0.6f,0.8f,1.0f)); - -#if 0 - osg::GraphicsContext::WindowingSystemInterface* wsi = osg::GraphicsContext::getWindowingSystemInterface(); if (!wsi) { osg::notify(osg::NOTICE)<<"View::setUpViewAcrossAllScreens() : Error, no WindowSystemInterface available, cannot create windows."<getScreenResolution(osg::GraphicsContext::ScreenIdentifier(0), width, height); + + + unsigned int numCameras = 2; + double aspectRatioScale = (double)numCameras; + double translate_x = double(numCameras)-1; + for(unsigned int i=0; i traits = new osg::GraphicsContext::Traits; + traits->x = (i*width)/numCameras; + traits->y = 0; + traits->width = width/numCameras-1; + traits->height = height; + #if 1 + traits->windowDecoration = false; + #else + traits->windowDecoration = true; + #endif + traits->doubleBuffer = true; + traits->sharedContext = 0; + + osg::ref_ptr gc = osg::GraphicsContext::createGraphicsContext(traits.get()); + + osgViewer::GraphicsWindow* gw = dynamic_cast(gc.get()); + if (gw) + { + osg::notify(osg::NOTICE)<<" GraphicsWindow has been created successfully."<getEventQueue()->getCurrentEventState()->setWindowRectangle(0, 0, traits->width, traits->height ); + } + else + { + osg::notify(osg::NOTICE)<<" GraphicsWindow has not been created successfully."< camera = new osg::Camera; + camera->setGraphicsContext(gc.get()); + camera->setViewport(new osg::Viewport(0,0, width/numCameras, height)); + GLenum buffer = traits->doubleBuffer ? GL_BACK : GL_FRONT; + camera->setDrawBuffer(buffer); + camera->setReadBuffer(buffer); + + viewer.addSlave(camera.get(), osg::Matrix::scale(aspectRatioScale, 1.0, 1.0)*osg::Matrix::translate(translate_x, 0.0, 0.0), osg::Matrix() ); + } + + viewer.setUpRenderingSupport(); + viewer.assignSceneDataToCameras(); +} + +int main( int argc, char **argv ) +{ + // use an ArgumentParser object to manage the program arguments. + osg::ArgumentParser arguments(&argc,argv); + + if (argc<2) + { + std::cout << argv[0] <<": requires filename argument." << std::endl; + return 1; + } + + + std::string pathfile; + osg::ref_ptr apm = 0; + while (arguments.read("-p",pathfile)) + { + apm = new osgGA::AnimationPathManipulator(pathfile); + if(!apm.valid() || !(apm->valid()) ) + { + apm = 0; + } + } + + osg::DisplaySettings::instance()->setMaxNumberOfGraphicsContexts(2); + osg::Referenced::setThreadSafeReferenceCounting(true); + + // load the scene. + osg::ref_ptr loadedModel = osgDB::readNodeFiles(arguments); + if (!loadedModel) + { + std::cout << argv[0] <<": No data loaded." << std::endl; + return 1; + } + + osgViewer::Viewer viewer; + + while (arguments.read("-s")) { viewer.setThreadingModel(osgViewer::Viewer::SingleThreaded); } + while (arguments.read("-g")) { viewer.setThreadingModel(osgViewer::Viewer::ThreadPerContext); } + while (arguments.read("-c")) { viewer.setThreadingModel(osgViewer::Viewer::ThreadPerCamera); } + + viewer.setSceneData(loadedModel.get()); + + if (apm.valid()) viewer.setCameraManipulator(apm.get()); + else viewer.setCameraManipulator( new osgGA::TrackballManipulator() ); + viewer.getCamera()->setClearColor(osg::Vec4f(0.6f,0.6f,0.8f,1.0f)); + +#if 1 + + // singleWindowMultipleCameras(viewer); + + multipleWindowMultipleCameras(viewer); + #else diff --git a/include/osgViewer/Viewer b/include/osgViewer/Viewer index 8d8448229..448982bd1 100644 --- a/include/osgViewer/Viewer +++ b/include/osgViewer/Viewer @@ -35,6 +35,19 @@ class OSGVIEWER_EXPORT Viewer : public osgViewer::View void setDone(bool done) { _done = done; } bool done() { return _done; } + + enum ThreadingModel + { + SingleThreaded, + ThreadPerContext, + ThreadPerCamera + }; + + /** Set the threading model the rendering traversals will use.*/ + void setThreadingModel(ThreadingModel threadingModel); + + /** Get the threading model the rendering traversals will use.*/ + ThreadingModel getThreadingModel() const { return _threadingModel; } /** Render a complete new frame. * Calls frameAdvance(), frameEventTraversal(), frameUpateTraversal(), frameRenderingTraversals(). */ @@ -70,6 +83,8 @@ class OSGVIEWER_EXPORT Viewer : public osgViewer::View bool _firstFrame; bool _done; + + ThreadingModel _threadingModel; osg::ref_ptr _startRenderingBarrier; osg::ref_ptr _endRenderingDispatchBarrier; diff --git a/src/osgViewer/View.cpp b/src/osgViewer/View.cpp index 8840229d2..a830a9c69 100644 --- a/src/osgViewer/View.cpp +++ b/src/osgViewer/View.cpp @@ -147,7 +147,7 @@ void View::setUpViewAcrossAllScreens() { osg::notify(osg::INFO)<<" GraphicsWindow has been created successfully."<getEventQueue()->getCurrentEventState()->setWindowRectangle(0, 0, width, height ); + gw->getEventQueue()->getCurrentEventState()->setWindowRectangle(traits->x, traits->y, traits->width, traits->height ); } else { @@ -193,7 +193,7 @@ void View::setUpViewAcrossAllScreens() { osg::notify(osg::INFO)<<" GraphicsWindow has been created successfully."<getEventQueue()->getCurrentEventState()->setWindowRectangle(0, 0, width, height ); + gw->getEventQueue()->getCurrentEventState()->setWindowRectangle(traits->x, traits->y, traits->width, traits->height ); } else { diff --git a/src/osgViewer/Viewer.cpp b/src/osgViewer/Viewer.cpp index 9b5e84a41..cb919fe7f 100644 --- a/src/osgViewer/Viewer.cpp +++ b/src/osgViewer/Viewer.cpp @@ -24,7 +24,8 @@ using namespace osgViewer; Viewer::Viewer(): _firstFrame(true), - _done(false) + _done(false), + _threadingModel(ThreadPerContext) { } @@ -51,6 +52,11 @@ Viewer::~Viewer() #endif } +void Viewer::setThreadingModel(ThreadingModel threadingModel) +{ + _threadingModel = threadingModel; +} + void Viewer::init() { osg::notify(osg::INFO)<<"Viewer::init()"< 1; + bool multiThreaded = contexts.size() > 1 && _threadingModel>=ThreadPerContext; if (multiThreaded) { - _startRenderingBarrier = new osg::BarrierOperation(contexts.size()+1, osg::BarrierOperation::NO_OPERATION); - _endRenderingDispatchBarrier = new osg::BarrierOperation(contexts.size()+1, osg::BarrierOperation::NO_OPERATION); + bool firstContextAsMainThread = _threadingModel==ThreadPerContext; + unsigned int numThreadsIncludingMainThread = firstContextAsMainThread ? contexts.size() : contexts.size()+1; + + osg::notify(osg::NOTICE)<<"numThreadsIncludingMainThread=="< swapOp = new osg::SwapBuffersOperation(); - for(citr = contexts.begin(); + citr = contexts.begin(); + if (firstContextAsMainThread) ++citr; + + for(; citr != contexts.end(); ++citr) { @@ -255,7 +269,7 @@ void Viewer::realize() ++citr) { osg::GraphicsContext* gc = (*citr); - if (!gc->getGraphicsThread()->isRunning()) + if (gc->getGraphicsThread() && !gc->getGraphicsThread()->isRunning()) { gc->getGraphicsThread()->startThread(); OpenThreads::Thread::YieldCurrentThread(); @@ -569,49 +583,42 @@ void Viewer::frameRenderingTraversals() dp->signalBeginFrame(_scene->getFrameStamp()); } - bool multiThreaded = _startRenderingBarrier.valid(); - - if (multiThreaded) + // osg::notify(osg::NOTICE)<block(); + + Contexts::iterator itr; + for(itr = contexts.begin(); + itr != contexts.end(); + ++itr) { - // sleep(1); - - // osg::notify(osg::NOTICE)<block(); - - // osg::notify(osg::NOTICE)<<"Joing _endRenderingDispatchBarrier block"<block(); - - // osg::notify(osg::NOTICE)<<"Leaving _endRenderingDispatchBarrier block"<getGraphicsThread())) + { (*itr)->makeCurrent(); (*itr)->runOperations(); } + } + // osg::notify(osg::NOTICE)<<"Joing _endRenderingDispatchBarrier block"<block(); + + for(itr = contexts.begin(); + itr != contexts.end(); + ++itr) + { + if (_done) return; + if (!((*itr)->getGraphicsThread())) + { (*itr)->makeCurrent(); (*itr)->swapBuffers(); } - } if (dp)