Hi Lionel,
Could you please resend you modified file as a separate attachement,
as mentioned by David last week. I can't review your changes as
inlining of files breaks the indention and line endings so the end
result isn't the same file you sent.
Robert.
On Feb 6, 2008 8:59 AM, Lionel Lagarde <[EMAIL PROTECTED]> wrote:
> Hi,
>
> An osg::Texture can unref its image after its apply. A Texture2D unref
> its image if areAllTextureObjectsLoaded method returns true.
>
> This method checks the if a texture object has been allocated for each
> graphic context. The number of graphic context is given by the
> DisplaySettings::getMaxNumberOfGraphicsContexts method.
>
>
> The 1.2 version of OSG (with Producer) updates the maximum number of
> graphic context for each created window.
>
> The 2.x version of OSG updates the maximum number of graphic context
> only if the new context ID is greater than the current number of graphic
> context.
>
> The attached fix updates the DisplaySettings instance for each created
> GraphicsContext.
>
> /* -*-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 <stdlib.h>
>
> #include <osg/GraphicsContext>
> #include <osg/Camera>
> #include <osg/View>
> #include <osg/GLObjects>
>
> #include <osg/FrameBufferObject>
> #include <osg/Program>
> #include <osg/Drawable>
> #include <osg/FragmentProgram>
> #include <osg/VertexProgram>
>
> #include <OpenThreads/ReentrantMutex>
>
> #include <osg/Notify>
>
> #include <map>
> #include <sstream>
> #include <algorithm>
>
> using namespace osg;
>
> /////////////////////////////////////////////////////////////////////////////
>
>
> // Use a static reference pointer to hold the window system interface.
> // Wrap this within a function, in order to control the order in which
> // the static pointer's constructor is executed.
>
> static ref_ptr<GraphicsContext::WindowingSystemInterface>
> &windowingSystemInterfaceRef()
> {
> static ref_ptr<GraphicsContext::WindowingSystemInterface>
> s_WindowingSystemInterface;
> return s_WindowingSystemInterface;
> }
>
>
> // GraphicsContext static method implementations
>
> void GraphicsContext::setWindowingSystemInterface(WindowingSystemInterface*
> callback)
> {
> ref_ptr<GraphicsContext::WindowingSystemInterface> &wsref =
> windowingSystemInterfaceRef();
> wsref = callback;
> osg::notify(osg::INFO)<<"GraphicsContext::setWindowingSystemInterface()
> "<<wsref.get()<<"\t"<<&wsref<<std::endl;
> }
>
> GraphicsContext::WindowingSystemInterface*
> GraphicsContext::getWindowingSystemInterface()
> {
> ref_ptr<GraphicsContext::WindowingSystemInterface> &wsref =
> windowingSystemInterfaceRef();
> osg::notify(osg::INFO)<<"GraphicsContext::getWindowingSystemInterface()
> "<<wsref.get()<<"\t"<<&wsref<<std::endl;
> return wsref.get();
> }
>
> GraphicsContext* GraphicsContext::createGraphicsContext(Traits* traits)
> {
> ref_ptr<GraphicsContext::WindowingSystemInterface> &wsref =
> windowingSystemInterfaceRef();
> if ( wsref.valid())
> {
> // catch any undefined values.
> if (traits) traits->setUndefinedScreenDetailsToDefaultScreen();
>
> return wsref->createGraphicsContext(traits);
> }
> else
> return 0;
> }
>
> GraphicsContext::ScreenIdentifier::ScreenIdentifier():
> displayNum(0),
> screenNum(0) {}
>
> GraphicsContext::ScreenIdentifier::ScreenIdentifier(int in_screenNum):
> displayNum(0),
> screenNum(in_screenNum) {}
>
> GraphicsContext::ScreenIdentifier::ScreenIdentifier(const std::string&
> in_hostName,int in_displayNum, int in_screenNum):
> hostName(in_hostName),
> displayNum(in_displayNum),
> screenNum(in_screenNum) {}
>
> std::string GraphicsContext::ScreenIdentifier::displayName() const
> {
> std::stringstream ostr;
> ostr<<hostName<<":"<<displayNum<<"."<<screenNum;
> return ostr.str();
> }
>
> void GraphicsContext::ScreenIdentifier::readDISPLAY()
> {
> const char* ptr = 0;
> if ((ptr=getenv("DISPLAY")) != 0)
> {
> setScreenIdentifier(ptr);
> }
> }
>
> void GraphicsContext::ScreenIdentifier::setScreenIdentifier(const
> std::string& displayName)
> {
> std::string::size_type colon = displayName.find_last_of(':');
> std::string::size_type point = displayName.find_last_of('.');
>
> if (point!=std::string::npos &&
> colon==std::string::npos &&
> point < colon) point = std::string::npos;
>
> if (colon==std::string::npos)
> {
> hostName = "";
> }
> else
> {
> hostName = displayName.substr(0,colon);
> }
>
> std::string::size_type startOfDisplayNum = (colon==std::string::npos) ? 0
> : colon+1;
> std::string::size_type endOfDisplayNum = (point==std::string::npos) ?
> displayName.size() : point;
>
> if (startOfDisplayNum<endOfDisplayNum)
> {
> displayNum =
> atoi(displayName.substr(startOfDisplayNum,endOfDisplayNum-startOfDisplayNum).c_str());
> }
> else
> {
> displayNum = -1;
> }
>
> if (point!=std::string::npos && point+1<displayName.size())
> {
> screenNum =
> atoi(displayName.substr(point+1,displayName.size()-point-1).c_str());
> }
> else
> {
> screenNum = -1;
> }
>
> #if 0
> osg::notify(osg::NOTICE)<<" hostName ["<<hostName<<"]"<<std::endl;
> osg::notify(osg::NOTICE)<<" displayNum "<<displayNum<<std::endl;
> osg::notify(osg::NOTICE)<<" screenNum "<<screenNum<<std::endl;
> #endif
> }
>
> class ContextData
> {
> public:
>
> ContextData():
> _numContexts(0) {}
>
> unsigned int _numContexts;
>
> void incrementUsageCount() { ++_numContexts; }
>
> void decrementUsageCount()
> {
> --_numContexts;
>
>
> osg::notify(osg::INFO)<<"decrementUsageCount()"<<_numContexts<<std::endl;
>
> if (_numContexts <= 1 && _compileContext.valid())
> {
> osg::notify(osg::INFO)<<"resetting compileContext
> "<<_compileContext.get()<<" refCount
> "<<_compileContext->referenceCount()<<std::endl;
>
> _compileContext = 0;
> }
> }
>
> osg::ref_ptr<osg::GraphicsContext> _compileContext;
>
> };
>
>
> typedef std::map<unsigned int, ContextData> ContextIDMap;
> static ContextIDMap s_contextIDMap;
> static OpenThreads::ReentrantMutex s_contextIDMapMutex;
> static GraphicsContext::GraphicsContexts s_registeredContexts;
>
> unsigned int GraphicsContext::createNewContextID()
> {
> OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_contextIDMapMutex);
>
> // first check to see if we can reuse contextID;
> for(ContextIDMap::iterator itr = s_contextIDMap.begin();
> itr != s_contextIDMap.end();
> ++itr)
> {
> if (itr->second._numContexts == 0)
> {
>
> // reuse contextID;
> itr->second._numContexts = 1;
>
> osg::notify(osg::INFO)<<"GraphicsContext::createNewContextID()
> reusing contextID="<<itr->first<<std::endl;
>
> return itr->first;
> }
> }
>
> unsigned int contextID = s_contextIDMap.size();
> s_contextIDMap[contextID]._numContexts = 1;
>
> osg::notify(osg::INFO)<<"GraphicsContext::createNewContextID() creating
> contextID="<<contextID<<std::endl;
>
>
> /*if ( (contextID+1) >
> osg::DisplaySettings::instance()->getMaxNumberOfGraphicsContexts() )
> {
> osg::notify(osg::INFO)<<"Updating the MaxNumberOfGraphicsContexts to
> "<<contextID+1<<std::endl;
>
> // update the the maximum number of graphics contexts,
> // to ensure that texture objects and display buffers are configured
> to the correct size.
> osg::DisplaySettings::instance()->setMaxNumberOfGraphicsContexts(
> contextID + 1 );
> }*/
>
> // Update the maximum number of graphics contexts
>
> osg::DisplaySettings::instance()->setMaxNumberOfGraphicsContexts(contextID +
> 1);
>
> return contextID;
> }
>
> unsigned int GraphicsContext::getMaxContextID()
> {
> OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_contextIDMapMutex);
> unsigned int maxContextID = 0;
> for(ContextIDMap::iterator itr = s_contextIDMap.begin();
> itr != s_contextIDMap.end();
> ++itr)
> {
> if (itr->first > maxContextID) maxContextID = itr->first;
> }
> return maxContextID;
> }
>
>
> void GraphicsContext::incrementContextIDUsageCount(unsigned int contextID)
> {
> OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_contextIDMapMutex);
>
>
> osg::notify(osg::INFO)<<"GraphicsContext::incrementContextIDUsageCount("<<contextID<<")
> to "<<s_contextIDMap[contextID]._numContexts<<std::endl;
>
> s_contextIDMap[contextID].incrementUsageCount();
> }
>
> void GraphicsContext::decrementContextIDUsageCount(unsigned int contextID)
> {
>
> OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_contextIDMapMutex);
>
> if (s_contextIDMap[contextID]._numContexts!=0)
> {
> s_contextIDMap[contextID].decrementUsageCount();
> }
> else
> {
> osg::notify(osg::NOTICE)<<"Warning:
> decrementContextIDUsageCount("<<contextID<<") called on expired
> contextID."<<std::endl;
> }
>
>
> osg::notify(osg::INFO)<<"GraphicsContext::decrementContextIDUsageCount("<<contextID<<")
> to "<<s_contextIDMap[contextID]._numContexts<<std::endl;
>
> }
>
>
> void GraphicsContext::registerGraphicsContext(GraphicsContext* gc)
> {
> osg::notify(osg::INFO)<<"GraphicsContext::registerGraphicsContext
> "<<gc<<std::endl;
>
> if (!gc) return;
>
> OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_contextIDMapMutex);
>
> GraphicsContexts::iterator itr = std::find(s_registeredContexts.begin(),
> s_registeredContexts.end(), gc);
> if (itr != s_registeredContexts.end()) s_registeredContexts.erase(itr);
>
> s_registeredContexts.push_back(gc);
> }
>
> void GraphicsContext::unregisterGraphicsContext(GraphicsContext* gc)
> {
> osg::notify(osg::INFO)<<"GraphicsContext::unregisterGraphicsContext
> "<<gc<<std::endl;
>
> if (!gc) return;
>
> OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_contextIDMapMutex);
>
> GraphicsContexts::iterator itr = std::find(s_registeredContexts.begin(),
> s_registeredContexts.end(), gc);
> if (itr != s_registeredContexts.end()) s_registeredContexts.erase(itr);
> }
>
> GraphicsContext::GraphicsContexts
> GraphicsContext::getAllRegisteredGraphicsContexts()
> {
>
> osg::notify(osg::INFO)<<"GraphicsContext::getAllRegisteredGraphicsContexts
> s_registeredContexts.size()="<<s_registeredContexts.size()<<std::endl;
> OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_contextIDMapMutex);
> return s_registeredContexts;
> }
>
> GraphicsContext::GraphicsContexts
> GraphicsContext::getRegisteredGraphicsContexts(unsigned int contextID)
> {
> GraphicsContexts contexts;
>
> OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_contextIDMapMutex);
> for(GraphicsContexts::iterator itr = s_registeredContexts.begin();
> itr != s_registeredContexts.end();
> ++itr)
> {
> GraphicsContext* gc = *itr;
> if (gc->getState() && gc->getState()->getContextID()==contextID)
> contexts.push_back(gc);
> }
>
> osg::notify(osg::INFO)<<"GraphicsContext::getRegisteredGraphicsContexts
> "<<contextID<<" contexts.size()="<<contexts.size()<<std::endl;
>
> return contexts;
> }
>
> GraphicsContext* GraphicsContext::getOrCreateCompileContext(unsigned int
> contextID)
> {
>
> osg::notify(osg::INFO)<<"GraphicsContext::createCompileContext."<<std::endl;
>
> {
> OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_contextIDMapMutex);
> if (s_contextIDMap[contextID]._compileContext.valid()) return
> s_contextIDMap[contextID]._compileContext.get();
> }
>
> GraphicsContext::GraphicsContexts contexts =
> GraphicsContext::getRegisteredGraphicsContexts(contextID);
> if (contexts.empty()) return 0;
>
> GraphicsContext* src_gc = contexts.front();
> const osg::GraphicsContext::Traits* src_traits = src_gc->getTraits();
>
> osg::GraphicsContext::Traits* traits = new osg::GraphicsContext::Traits;
> traits->screenNum = src_traits->screenNum;
> traits->displayNum = src_traits->displayNum;
> traits->hostName = src_traits->hostName;
> traits->width = 100;
> traits->height = 100;
> traits->red = src_traits->red;
> traits->green = src_traits->green;
> traits->blue = src_traits->blue;
> traits->alpha = src_traits->alpha;
> traits->depth = src_traits->depth;
> traits->sharedContext = src_gc;
> traits->pbuffer = true;
>
> osg::ref_ptr<osg::GraphicsContext> gc =
> osg::GraphicsContext::createGraphicsContext(traits);
> if (gc.valid() && gc->realize())
> {
> OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_contextIDMapMutex);
> s_contextIDMap[contextID]._compileContext = gc;
> osg::notify(osg::INFO)<<" succeeded
> GraphicsContext::createCompileContext."<<std::endl;
> return gc.release();
> }
> else
> {
> return 0;
> }
>
> }
>
> void GraphicsContext::setCompileContext(unsigned int contextID,
> GraphicsContext* gc)
> {
> OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_contextIDMapMutex);
> s_contextIDMap[contextID]._compileContext = gc;
> }
>
> GraphicsContext* GraphicsContext::getCompileContext(unsigned int contextID)
> {
> // osg::notify(osg::NOTICE)<<"GraphicsContext::getCompileContext
> "<<contextID<<std::endl;
> OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_contextIDMapMutex);
> ContextIDMap::iterator itr = s_contextIDMap.find(contextID);
> if (itr != s_contextIDMap.end()) return itr->second._compileContext.get();
> else return 0;
> }
>
>
> /////////////////////////////////////////////////////////////////////////////
> //
> // GraphicsContext standard method implementations
> //
> GraphicsContext::GraphicsContext():
> _clearColor(osg::Vec4(0.0f,0.0f,0.0f,1.0f)),
> _clearMask(0),
> _threadOfLastMakeCurrent(0)
> {
> setThreadSafeRefUnref(true);
> _operationsBlock = new RefBlock;
>
> registerGraphicsContext(this);
> }
>
> GraphicsContext::GraphicsContext(const GraphicsContext&, const osg::CopyOp&):
> _clearColor(osg::Vec4(0.0f,0.0f,0.0f,1.0f)),
> _clearMask(0),
> _threadOfLastMakeCurrent(0)
> {
> setThreadSafeRefUnref(true);
> _operationsBlock = new RefBlock;
>
> registerGraphicsContext(this);
> }
>
> GraphicsContext::~GraphicsContext()
> {
> close(false);
>
> unregisterGraphicsContext(this);
> }
>
> void GraphicsContext::clear()
> {
> if (_clearMask==0 || !_traits) return;
>
> glViewport(0, 0, _traits->width, _traits->height);
> glScissor(0, 0, _traits->width, _traits->height);
>
> glClearColor( _clearColor[0], _clearColor[1], _clearColor[2],
> _clearColor[3]);
>
> glClear( _clearMask );
> }
>
> bool GraphicsContext::realize()
> {
> if (realizeImplementation())
> {
> return true;
> }
> else
> {
> return false;
> }
> }
>
> void GraphicsContext::close(bool callCloseImplementation)
> {
>
> osg::notify(osg::INFO)<<"close("<<callCloseImplementation<<")"<<this<<std::endl;
>
> // switch off the graphics thread...
> setGraphicsThread(0);
>
>
> bool sharedContextExists = false;
>
> if (_state.valid())
> {
> OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_contextIDMapMutex);
> if (s_contextIDMap[_state->getContextID()]._numContexts>1)
> sharedContextExists = true;
> }
>
> // release all the OpenGL objects in the scene graphs associated with this
> for(Cameras::iterator itr = _cameras.begin();
> itr != _cameras.end();
> ++itr)
> {
> Camera* camera = (*itr);
> if (camera)
> {
> osg::notify(osg::INFO)<<"Releasing GL objects for
> Camera="<<camera<<" _state="<<_state.get()<<std::endl;
> camera->releaseGLObjects(_state.get());
> }
> }
>
>
> if (callCloseImplementation && _state.valid() && isRealized())
> {
> osg::notify(osg::INFO)<<"Closing still viable window
> "<<sharedContextExists<<"
> _state->getContextID()="<<_state->getContextID()<<std::endl;
>
> if (makeCurrent())
> {
>
> osg::notify(osg::INFO)<<"Doing Flush"<<std::endl;
>
> osg::flushAllDeletedGLObjects(_state->getContextID());
>
> osg::notify(osg::INFO)<<"Done Flush "<<std::endl;
>
> _state->reset();
>
> releaseContext();
> }
> else
> {
> osg::notify(osg::INFO)<<"makeCurrent did not succeed, could not
> do flush/deletion of OpenGL objects."<<std::endl;
> }
> }
>
> if (callCloseImplementation) closeImplementation();
>
>
> // now discard any deleted deleted OpenGL objects that the are still
> hanging around - such as due to
> // the the flushDelete*() methods not being invoked, such as when using
> GraphicContextEmbedded where makeCurrent
> // does not work.
> if (_state.valid())
> {
> osg::notify(osg::INFO)<<"Doing discard of deleted OpenGL
> objects."<<std::endl;
>
> osg::discardAllDeletedGLObjects(_state->getContextID());
> }
>
> if (_state.valid())
> {
> decrementContextIDUsageCount(_state->getContextID());
>
> _state = 0;
> }
> }
>
>
> bool GraphicsContext::makeCurrent()
> {
> bool result = makeCurrentImplementation();
>
> if (result)
> {
> _threadOfLastMakeCurrent = OpenThreads::Thread::CurrentThread();
>
> // initialize extension process, not only initializes on first
> // call, will be a non-op on subsequent calls.
> getState()->initializeExtensionProcs();
> }
>
> return result;
> }
>
> bool GraphicsContext::makeContextCurrent(GraphicsContext* readContext)
> {
> bool result = makeContextCurrentImplementation(readContext);
>
> if (result)
> {
> _threadOfLastMakeCurrent = OpenThreads::Thread::CurrentThread();
>
> // initialize extension process, not only initializes on first
> // call, will be a non-op on subsequent calls.
> getState()->initializeExtensionProcs();
> }
>
> return result;
> }
>
> bool GraphicsContext::releaseContext()
> {
> bool result = releaseContextImplementation();
>
> _threadOfLastMakeCurrent = (OpenThreads::Thread*)(-1);
>
> return result;
> }
>
> void GraphicsContext::swapBuffers()
> {
> if (isCurrent())
> {
> swapBuffersImplementation();
> clear();
> }
> else if (_graphicsThread.valid() &&
> _threadOfLastMakeCurrent == _graphicsThread.get())
> {
> _graphicsThread->add(new SwapBuffersOperation);
> }
> else
> {
> makeCurrent();
> swapBuffersImplementation();
> clear();
> }
> }
>
>
>
> void GraphicsContext::createGraphicsThread()
> {
> if (!_graphicsThread)
> {
> setGraphicsThread(new GraphicsThread);
> }
> }
>
> void GraphicsContext::setGraphicsThread(GraphicsThread* gt)
> {
> if (_graphicsThread==gt) return;
>
> if (_graphicsThread.valid())
> {
> // need to kill the thread in some way...
> _graphicsThread->cancel();
> _graphicsThread->setParent(0);
> }
>
> _graphicsThread = gt;
>
> if (_graphicsThread.valid())
> {
> _graphicsThread->setParent(this);
> }
> }
>
> void GraphicsContext::add(Operation* operation)
> {
> osg::notify(osg::INFO)<<"Doing add"<<std::endl;
>
> // acquire the lock on the operations queue to prevent anyone else for
> modifying it at the same time
> OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_operationsMutex);
>
> // add the operation to the end of the list
> _operations.push_back(operation);
>
> _operationsBlock->set(true);
> }
>
> void GraphicsContext::remove(Operation* operation)
> {
> osg::notify(osg::INFO)<<"Doing remove operation"<<std::endl;
>
> // acquire the lock on the operations queue to prevent anyone else for
> modifying it at the same time
> OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_operationsMutex);
>
> for(OperationQueue::iterator itr = _operations.begin();
> itr!=_operations.end();)
> {
> if ((*itr)==operation) itr = _operations.erase(itr);
> else ++itr;
> }
>
> if (_operations.empty())
> {
> _operationsBlock->set(false);
> }
> }
>
> void GraphicsContext::remove(const std::string& name)
> {
> osg::notify(osg::INFO)<<"Doing remove named operation"<<std::endl;
>
> // acquire the lock on the operations queue to prevent anyone else for
> modifying it at the same time
> OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_operationsMutex);
>
> // find the remove all operations with specified name
> for(OperationQueue::iterator itr = _operations.begin();
> itr!=_operations.end();)
> {
> if ((*itr)->getName()==name) itr = _operations.erase(itr);
> else ++itr;
> }
>
> if (_operations.empty())
> {
> _operationsBlock->set(false);
> }
> }
>
> void GraphicsContext::removeAllOperations()
> {
> osg::notify(osg::INFO)<<"Doing remove all operations"<<std::endl;
>
> OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_operationsMutex);
> _operations.clear();
> _operationsBlock->set(false);
> }
>
>
> struct CameraRenderOrderSortOp
> {
> inline bool operator() (const Camera* lhs,const Camera* rhs) const
> {
> if (lhs->getRenderOrder()<rhs->getRenderOrder()) return true;
> if (rhs->getRenderOrder()<lhs->getRenderOrder()) return false;
> return lhs->getRenderOrderNum()<lhs->getRenderOrderNum();
> }
> };
>
>
> void GraphicsContext::runOperations()
> {
> // sort the cameras into order
> typedef std::vector<Camera*> CameraVector;
> CameraVector camerasCopy;
> std::copy(_cameras.begin(), _cameras.end(),
> std::back_inserter(camerasCopy));
> std::sort(camerasCopy.begin(), camerasCopy.end(),
> CameraRenderOrderSortOp());
>
> for(CameraVector::iterator itr = camerasCopy.begin();
> itr != camerasCopy.end();
> ++itr)
> {
> osg::Camera* camera = *itr;
> if (camera->getRenderer()) (*(camera->getRenderer()))(this);
> }
>
> for(OperationQueue::iterator itr = _operations.begin();
> itr != _operations.end();
> )
> {
> {
> OpenThreads::ScopedLock<OpenThreads::Mutex>
> lock(_operationsMutex);
> _currentOperation = *itr;
>
> if (!_currentOperation->getKeep())
> {
> itr = _operations.erase(itr);
>
> if (_operations.empty())
> {
> _operationsBlock->set(false);
> }
> }
> else
> {
> ++itr;
> }
> }
>
> if (_currentOperation.valid())
> {
> // osg::notify(osg::INFO)<<"Doing op
> "<<_currentOperation->getName()<<" "<<this<<std::endl;
>
> // call the graphics operation.
> (*_currentOperation)(this);
>
> {
> OpenThreads::ScopedLock<OpenThreads::Mutex>
> lock(_operationsMutex);
> _currentOperation = 0;
> }
> }
> }
> }
>
> void GraphicsContext::addCamera(osg::Camera* camera)
> {
> _cameras.push_back(camera);
> }
>
> void GraphicsContext::removeCamera(osg::Camera* camera)
> {
> for(Cameras::iterator itr = _cameras.begin();
> itr != _cameras.end();
> ++itr)
> {
> if (*itr == camera)
> {
> _cameras.erase(itr);
> return;
> }
> }
> }
>
> void GraphicsContext::resizedImplementation(int x, int y, int width, int
> height)
> {
> if (!_traits) return;
>
> double widthChangeRatio = double(width) / double(_traits->width);
> double heigtChangeRatio = double(height) / double(_traits->height);
> double aspectRatioChange = widthChangeRatio / heigtChangeRatio;
>
> for(Cameras::iterator itr = _cameras.begin();
> itr != _cameras.end();
> ++itr)
> {
> Camera* camera = (*itr);
> Viewport* viewport = camera->getViewport();
> if (viewport)
> {
> if (viewport->x()==0 && viewport->y()==0 &&
> viewport->width()>=_traits->width &&
> viewport->height()>=_traits->height)
> {
> viewport->setViewport(0,0,width,height);
> }
> else
> {
> viewport->x() =
> static_cast<osg::Viewport::value_type>(double(viewport->x())*widthChangeRatio);
> viewport->y() =
> static_cast<osg::Viewport::value_type>(double(viewport->y())*heigtChangeRatio);
> viewport->width() =
> static_cast<osg::Viewport::value_type>(double(viewport->width())*widthChangeRatio);
> viewport->height() =
> static_cast<osg::Viewport::value_type>(double(viewport->height())*heigtChangeRatio);
> }
> }
>
> // if aspect ratio adjusted change the project matrix to suit.
> if (aspectRatioChange != 1.0)
> {
> osg::View* view = camera->getView();
> osg::View::Slave* slave = view ? view->findSlaveForCamera(camera)
> : 0;
>
> if (slave &&
> camera->getReferenceFrame()==osg::Transform::RELATIVE_RF)
> {
> switch(view->getCamera()->getProjectionResizePolicy())
> {
> case(osg::Camera::HORIZONTAL): slave->_projectionOffset
> *= osg::Matrix::scale(1.0/aspectRatioChange,1.0,1.0); break;
> case(osg::Camera::VERTICAL): slave->_projectionOffset *=
> osg::Matrix::scale(1.0, aspectRatioChange,1.0); break;
> default: break;
> }
> }
> else
> {
> Camera::ProjectionResizePolicy policy = view ?
> view->getCamera()->getProjectionResizePolicy() :
> camera->getProjectionResizePolicy();
> switch(policy)
> {
> case(osg::Camera::HORIZONTAL):
> camera->getProjectionMatrix() *=
> osg::Matrix::scale(1.0/aspectRatioChange,1.0,1.0); break;
> case(osg::Camera::VERTICAL):
> camera->getProjectionMatrix() *= osg::Matrix::scale(1.0,
> aspectRatioChange,1.0); break;
> default: break;
> }
> }
>
> }
>
> }
>
> _traits->x = x;
> _traits->y = y;
> _traits->width = width;
> _traits->height = height;
> }
>
> _______________________________________________
> osg-submissions mailing list
> [email protected]
> http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.org
>
>
_______________________________________________
osg-submissions mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.org