/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield * * This library is open source and may be redistributed and/or modified under * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or * (at your option) any later version. The full license is in LICENSE file * included with this distribution, and on the openscenegraph.org website. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY { } without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * OpenSceneGraph Public License for more details. */ #include #include #include using namespace osgViewer; class ActionAdapter : public osgGA::GUIActionAdapter { public: virtual ~ActionAdapter() {} virtual void requestRedraw() { /*osg::notify(osg::NOTICE)<<"requestRedraw()"<setGraphicsThread(0); } if (_scene.valid() && _scene->getDatabasePager()) { _scene->getDatabasePager()->cancel(); _scene->setDatabasePager(0); } #endif } void Viewer::init() { osg::notify(osg::INFO)<<"Viewer::init()"< initEvent = _eventQueue->createEvent(); initEvent->setEventType(osgGA::GUIEventAdapter::FRAME); if (_cameraManipulator.valid()) { ActionAdapter aa; _cameraManipulator->init(*initEvent, aa); } } void Viewer::getContexts(Contexts& contexts) { typedef std::set ContextSet; ContextSet contextSet; if (_camera.valid() && _camera->getGraphicsContext()) { contextSet.insert(_camera->getGraphicsContext()); } for(unsigned int i=0; igetGraphicsContext()) { contextSet.insert(slave._camera->getGraphicsContext()); } } contexts.clear(); contexts.reserve(contextSet.size()); for(ContextSet::iterator itr = contextSet.begin(); itr != contextSet.end(); ++itr) { contexts.push_back(const_cast(*itr)); } } OpenThreads::Mutex mutex; // Compile operation, that compile OpenGL objects. struct CompileOperation : public osg::GraphicsOperation { CompileOperation(osg::Node* scene): osg::GraphicsOperation("Compile",false), _scene(scene) { } virtual void operator () (osg::GraphicsContext* context) { // OpenThreads::ScopedLock lock(mutex); // osg::notify(osg::NOTICE)<<"Compile "<makeCurrentImplementation(); osgUtil::GLObjectsVisitor compileVisitor; compileVisitor.setState(context->getState()); // do the compile traversal _scene->accept(compileVisitor); // osg::notify(osg::NOTICE)<<"Done Compile "< _scene; }; // Draw operation, that does a draw on the scene graph. struct RunOperations : public osg::GraphicsOperation { RunOperations(osg::GraphicsContext* gc): osg::GraphicsOperation("RunOperation",true), _originalContext(gc) { } virtual void operator () (osg::GraphicsContext* gc) { gc->runOperations(); } osg::GraphicsContext* _originalContext; }; void Viewer::realize() { osg::notify(osg::INFO)<<"Viewer::realize()"< 1; if (multiThreaded) { _startRenderingBarrier = new osg::BarrierOperation(contexts.size()+1, osg::BarrierOperation::NO_OPERATION); _endRenderingDispatchBarrier = new osg::BarrierOperation(contexts.size()+1, osg::BarrierOperation::NO_OPERATION); osg::ref_ptr swapOp = new osg::SwapBuffersOperation(); for(citr = contexts.begin(); citr != contexts.end(); ++citr) { osg::GraphicsContext* gc = (*citr); // create the a graphics thread for this context gc->createGraphicsThread(); gc->getGraphicsThread()->add(new CompileOperation(getSceneData())); // add the startRenderingBarrier gc->getGraphicsThread()->add(_startRenderingBarrier.get()); // add the rendering operation itself. gc->getGraphicsThread()->add(new RunOperations(gc)); // add the endRenderingDispatchBarrier gc->getGraphicsThread()->add(_endRenderingDispatchBarrier.get()); // add the swap buffers gc->getGraphicsThread()->add(swapOp.get()); } } for(citr = contexts.begin(); citr != contexts.end(); ++citr) { (*citr)->realize(); OpenThreads::Thread::YieldCurrentThread(); } bool grabFocus = true; if (grabFocus) { for(citr = contexts.begin(); citr != contexts.end(); ++citr) { osgViewer::GraphicsWindow* gw = dynamic_cast(*citr); if (gw) { gw->grabFocusIfPointerInWindow(); } } } // initialize the global timer to be relative to the current time. osg::Timer::instance()->setStartTick(); if (multiThreaded) { for(citr = contexts.begin(); citr != contexts.end(); ++citr) { osg::GraphicsContext* gc = (*citr); if (!gc->getGraphicsThread()->isRunning()) { gc->getGraphicsThread()->startThread(); OpenThreads::Thread::YieldCurrentThread(); } } } } void Viewer::frame() { if (_done) return; // osg::notify(osg::NOTICE)<frameAdvance(); } void Viewer::frameEventTraversal() { if (_done) return; // osg::notify(osg::NOTICE)<<"Viewer::frameEventTraversal()."<(*citr); if (gw) { gw->checkEvents(); gw->getEventQueue()->takeEvents(events); } } osgGA::GUIEventAdapter* eventState = getEventQueue()->getCurrentEventState(); for(osgGA::EventQueue::Events::iterator itr = events.begin(); itr != events.end(); ++itr) { osgGA::GUIEventAdapter* event = itr->get(); event->setInputRange(eventState->getXmin(), eventState->getYmin(), eventState->getXmax(), eventState->getYmax()); switch(event->getEventType()) { case(osgGA::GUIEventAdapter::PUSH): case(osgGA::GUIEventAdapter::RELEASE): case(osgGA::GUIEventAdapter::DRAG): case(osgGA::GUIEventAdapter::MOVE): eventState->setX(event->getX()); eventState->setY(event->getY()); eventState->setButtonMask(event->getButtonMask()); break; default: break; } } _eventQueue->frame( _scene->getFrameStamp()->getReferenceTime() ); _eventQueue->takeEvents(events); #if 0 // osg::notify(osg::NOTICE)<<"Events "<get(); switch(event->getEventType()) { case(osgGA::GUIEventAdapter::PUSH): osg::notify(osg::NOTICE)<<" PUSH "<getButton()<<" x="<getX()<<" y="<getY()<getButton()<<" x="<getX()<<" y="<getY()<getButtonMask()<<" x="<getX()<<" y="<getY()<getButtonMask()<<" x="<getX()<<" y="<getY()<getScrollingMotion()<getKey()<<"'"<getKey()<<"'"<get(); switch(event->getEventType()) { case(osgGA::GUIEventAdapter::KEYUP): if (event->getKey()=='q') _done = true; break; default: break; } } if (_done) return; ActionAdapter aa; for(osgGA::EventQueue::Events::iterator itr = events.begin(); itr != events.end(); ++itr) { osgGA::GUIEventAdapter* event = itr->get(); bool handled = false; if (_cameraManipulator.valid()) { _cameraManipulator->handle( *event, aa); } for(EventHandlers::iterator hitr = _eventHandlers.begin(); hitr != _eventHandlers.end() && !handled; ++hitr) { handled = (*hitr)->handle( *event, aa, 0, 0); } } } void Viewer::frameUpdateTraversal() { if (_done) return; if (_scene.valid()) _scene->frameUpdateTraversal(); if (_cameraManipulator.valid()) { _camera->setViewMatrix(_cameraManipulator->getInverseMatrix()); } updateSlaves(); } void Viewer::frameRenderingTraversals() { if (_done) return; osgDB::DatabasePager* dp = _scene->getDatabasePager(); if (dp) { dp->signalBeginFrame(_scene->getFrameStamp()); } bool multiThreaded = _startRenderingBarrier.valid(); if (multiThreaded) { // sleep(1); // osg::notify(osg::NOTICE)<block(); // osg::notify(osg::NOTICE)<<"Joing _endRenderingDispatchBarrier block"<block(); // osg::notify(osg::NOTICE)<<"Leaving _endRenderingDispatchBarrier block"<makeCurrent(); (*itr)->runOperations(); } for(itr = contexts.begin(); itr != contexts.end(); ++itr) { (*itr)->makeCurrent(); (*itr)->swapBuffers(); } } if (dp) { dp->signalEndFrame(); } } void Viewer::releaseAllGLObjects() { osg::notify(osg::NOTICE)<<"Viewer::releaseAllGLObjects() not implemented yet."<