Added support for GrapicsOpeations that are reused each frame, cleaned up
osgcamera example.
This commit is contained in:
parent
994192657a
commit
c02e91c1b4
@ -10,6 +10,7 @@
|
||||
#include <osgUtil/UpdateVisitor>
|
||||
#include <osgUtil/CullVisitor>
|
||||
#include <osgUtil/SceneView>
|
||||
#include <osgUtil/GLObjectsVisitor>
|
||||
|
||||
#include <osgDB/ReadFile>
|
||||
|
||||
@ -29,6 +30,28 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
struct CompileOperation : public osg::GraphicsThread::Operation
|
||||
{
|
||||
CompileOperation(osg::Node* scene):
|
||||
osg::GraphicsThread::Operation("Compile",false),
|
||||
_scene(scene)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void operator () (osg::GraphicsContext* context)
|
||||
{
|
||||
std::cout<<"Compile"<<std::endl;
|
||||
|
||||
osgUtil::GLObjectsVisitor compileVisitor;
|
||||
compileVisitor.setState(context->getState());
|
||||
|
||||
// do the compile traversal
|
||||
_scene->accept(compileVisitor);
|
||||
}
|
||||
|
||||
osg::ref_ptr<osg::Node> _scene;
|
||||
};
|
||||
|
||||
struct FrameOperation : public osg::GraphicsThread::Operation
|
||||
{
|
||||
FrameOperation(osg::CameraNode* camera, osg::FrameStamp* frameStamp):
|
||||
@ -100,6 +123,9 @@ int main( int argc, char **argv )
|
||||
CameraMap cameraMap;
|
||||
GraphicsContextSet graphicsContextSet;
|
||||
|
||||
|
||||
bool shareContexts = false;
|
||||
osg::GraphicsContext* previousContext = 0;
|
||||
for(unsigned int i=0; i< numberCameras; ++i)
|
||||
{
|
||||
osg::ref_ptr<osg::CameraNode> camera = new osg::CameraNode;
|
||||
@ -113,7 +139,8 @@ int main( int argc, char **argv )
|
||||
traits->_height = height;
|
||||
traits->_windowDecoration = true;
|
||||
traits->_doubleBuffer = true;
|
||||
|
||||
traits->_sharedContext = shareContexts ? previousContext : 0;
|
||||
|
||||
xpos += width;
|
||||
|
||||
osg::ref_ptr<osg::GraphicsContext> gfxc = osg::GraphicsContext::createGraphicsContext(traits.get());
|
||||
@ -139,6 +166,8 @@ int main( int argc, char **argv )
|
||||
gfxc->createGraphicsThread();
|
||||
|
||||
cameraMap[camera] = new FrameOperation(camera.get(), frameStamp.get());
|
||||
|
||||
previousContext = gfxc.get();
|
||||
}
|
||||
|
||||
|
||||
@ -150,9 +179,12 @@ int main( int argc, char **argv )
|
||||
graphicsContextSet.insert(const_cast<osg::GraphicsContext*>(citr->first->getGraphicsContext()));
|
||||
}
|
||||
|
||||
osg::ref_ptr<osg::SwapBuffersOperation> swapOp = new osg::SwapBuffersOperation();
|
||||
osg::ref_ptr<CompileOperation> compileOp = new CompileOperation(loadedModel.get());
|
||||
|
||||
osg::ref_ptr<osg::BarrierOperation> frameBeginBarrierOp = new osg::BarrierOperation(graphicsContextSet.size()+1, osg::BarrierOperation::NO_OPERATION);
|
||||
osg::ref_ptr<osg::BarrierOperation> frameEndBarrierOp = new osg::BarrierOperation(graphicsContextSet.size()+1, osg::BarrierOperation::NO_OPERATION);
|
||||
osg::ref_ptr<osg::BarrierOperation> preSwapBarrierOp = new osg::BarrierOperation(graphicsContextSet.size(), osg::BarrierOperation::GL_FLUSH);
|
||||
osg::ref_ptr<osg::SwapBuffersOperation> swapOp = new osg::SwapBuffersOperation();
|
||||
|
||||
std::cout<<"nubmer of gfx."<<graphicsContextSet.size()<<std::endl;
|
||||
|
||||
@ -162,7 +194,47 @@ int main( int argc, char **argv )
|
||||
|
||||
bool done = false;
|
||||
|
||||
// main loop (note, window toolkits which take control over the main loop will require a window redraw callback containing the code below.)
|
||||
// first the compile of the GL Objects, do it syncronously.
|
||||
GraphicsContextSet::iterator gitr;
|
||||
for(gitr = graphicsContextSet.begin();
|
||||
gitr != graphicsContextSet.end();
|
||||
++gitr)
|
||||
{
|
||||
osg::GraphicsContext* context = *gitr;
|
||||
context->getGraphicsThread()->add(compileOp.get(), true);
|
||||
}
|
||||
|
||||
|
||||
// second the begin frame barrier to all graphics threads
|
||||
for(gitr = graphicsContextSet.begin();
|
||||
gitr != graphicsContextSet.end();
|
||||
++gitr)
|
||||
{
|
||||
osg::GraphicsContext* context = *gitr;
|
||||
context->getGraphicsThread()->add(frameBeginBarrierOp.get(), false);
|
||||
}
|
||||
|
||||
// third add the frame for each camera.
|
||||
for(citr = cameraMap.begin();
|
||||
citr != cameraMap.end();
|
||||
++citr)
|
||||
{
|
||||
osg::CameraNode* camera = const_cast<osg::CameraNode*>(citr->first.get());
|
||||
camera->getGraphicsContext()->getGraphicsThread()->add( citr->second.get(), false);
|
||||
}
|
||||
|
||||
// fourth add the frame end barrier, the pre swap barrier and finally the swap buffers to each graphics thread
|
||||
for(gitr = graphicsContextSet.begin();
|
||||
gitr != graphicsContextSet.end();
|
||||
++gitr)
|
||||
{
|
||||
osg::GraphicsContext* context = *gitr;
|
||||
context->getGraphicsThread()->add(frameEndBarrierOp.get(), false);
|
||||
context->getGraphicsThread()->add(preSwapBarrierOp.get(), false);
|
||||
context->getGraphicsThread()->add(swapOp.get(), false);
|
||||
}
|
||||
|
||||
// main loop - update scene graph, dispatch frame, wait for frame done.
|
||||
while( !done )
|
||||
{
|
||||
|
||||
@ -178,43 +250,11 @@ int main( int argc, char **argv )
|
||||
// do the update traversal.
|
||||
loadedModel->accept(updateVisitor);
|
||||
|
||||
// issue the frame for each camera.
|
||||
for(citr = cameraMap.begin();
|
||||
citr != cameraMap.end();
|
||||
++citr)
|
||||
{
|
||||
osg::CameraNode* camera = const_cast<osg::CameraNode*>(citr->first.get());
|
||||
camera->getGraphicsContext()->getGraphicsThread()->add( citr->second.get(), false);
|
||||
}
|
||||
|
||||
GraphicsContextSet::iterator gitr;
|
||||
for(gitr = graphicsContextSet.begin();
|
||||
gitr != graphicsContextSet.end();
|
||||
++gitr)
|
||||
{
|
||||
osg::GraphicsContext* context = *gitr;
|
||||
context->getGraphicsThread()->add(frameEndBarrierOp.get(), false);
|
||||
context->getGraphicsThread()->add(preSwapBarrierOp.get(), false);
|
||||
}
|
||||
|
||||
osg::notify(osg::INFO)<<"Join frameEndBarrierOp block "<<std::endl;
|
||||
osg::Timer_t before_tick = osg::Timer::instance()->tick();
|
||||
// dispatch the frame.
|
||||
frameBeginBarrierOp->block();
|
||||
|
||||
// wait till the frame is done.
|
||||
frameEndBarrierOp->block();
|
||||
osg::Timer_t after_tick = osg::Timer::instance()->tick();
|
||||
osg::notify(osg::INFO)<<"Leave frameEndBarrierOp block "<<osg::Timer::instance()->delta_s(before_tick,after_tick)<<std::endl;
|
||||
|
||||
osg::notify(osg::INFO)<<"Join preSwapBarrierOp block "<<std::endl;
|
||||
before_tick = osg::Timer::instance()->tick();
|
||||
after_tick = osg::Timer::instance()->tick();
|
||||
osg::notify(osg::INFO)<<"Leave preSwapBarrierOp block "<<osg::Timer::instance()->delta_s(before_tick,after_tick)<<std::endl;
|
||||
|
||||
for(gitr = graphicsContextSet.begin();
|
||||
gitr != graphicsContextSet.end();
|
||||
++gitr)
|
||||
{
|
||||
osg::GraphicsContext* context = *gitr;
|
||||
context->getGraphicsThread()->add(swapOp.get(), true);
|
||||
}
|
||||
|
||||
// check if any of the windows are closed
|
||||
for(gitr = graphicsContextSet.begin();
|
||||
@ -226,6 +266,5 @@ int main( int argc, char **argv )
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -229,6 +229,8 @@ class DataConverter
|
||||
|
||||
void write(const osg::FrameStamp& fs)
|
||||
{
|
||||
osg::notify(osg::NOTICE)<<"writeFramestamp = "<<fs.getFrameNumber()<<" "<<fs.getReferenceTime()<<std::endl;
|
||||
|
||||
writeUInt(fs.getFrameNumber());
|
||||
return writeDouble(fs.getReferenceTime());
|
||||
|
||||
@ -238,6 +240,8 @@ class DataConverter
|
||||
{
|
||||
fs.setFrameNumber(readUInt());
|
||||
fs.setReferenceTime(readDouble());
|
||||
|
||||
osg::notify(osg::NOTICE)<<"readFramestamp = "<<fs.getFrameNumber()<<" "<<fs.getReferenceTime()<<std::endl;
|
||||
}
|
||||
|
||||
void write(const osg::Matrix& matrix)
|
||||
@ -261,6 +265,9 @@ class DataConverter
|
||||
writeDouble(matrix(3,1));
|
||||
writeDouble(matrix(3,2));
|
||||
writeDouble(matrix(3,3));
|
||||
|
||||
osg::notify(osg::NOTICE)<<"writeMatrix = "<<matrix<<std::endl;
|
||||
|
||||
}
|
||||
|
||||
void read(osg::Matrix& matrix)
|
||||
@ -284,6 +291,9 @@ class DataConverter
|
||||
matrix(3,1) = readDouble();
|
||||
matrix(3,2) = readDouble();
|
||||
matrix(3,3) = readDouble();
|
||||
|
||||
osg::notify(osg::NOTICE)<<"readMatrix = "<<matrix<<std::endl;
|
||||
|
||||
}
|
||||
|
||||
void write(const osgProducer::EventAdapter& event)
|
||||
|
@ -26,7 +26,7 @@ namespace osg {
|
||||
// forward declare GraphicsContext
|
||||
class GraphicsContext;
|
||||
|
||||
class Block: public osg::Referenced {
|
||||
class Block: virtual public osg::Referenced {
|
||||
public:
|
||||
Block():_released(false) {}
|
||||
|
||||
@ -82,17 +82,17 @@ class OSG_EXPORT GraphicsThread : public Referenced, public OpenThreads::Thread
|
||||
GraphicsThread();
|
||||
|
||||
/** Base class for implementing GraphicsThread operations.*/
|
||||
struct OSG_EXPORT Operation : public Referenced
|
||||
struct OSG_EXPORT Operation : virtual public Referenced
|
||||
{
|
||||
Operation(const std::string& name, bool keep):
|
||||
_name(name),
|
||||
_keep(true) {}
|
||||
_keep(keep) {}
|
||||
|
||||
/** Set the human readable name of the operation.*/
|
||||
void setName(const std::string& name) { _name = name; }
|
||||
|
||||
/** Get the human readable name of the operation.*/
|
||||
const std::string& gtName() const { return _name; }
|
||||
const std::string& getName() const { return _name; }
|
||||
|
||||
/** Set whether the operation should be kept once its been applied.*/
|
||||
void setKeep(bool keep) { _keep = keep; }
|
||||
|
@ -838,6 +838,9 @@ unsigned int Geometry::getGLObjectSizeHint() const
|
||||
|
||||
void Geometry::drawImplementation(State& state) const
|
||||
{
|
||||
|
||||
// osg::notify(osg::NOTICE)<<"Geometry::drawImplementation"<<std::endl;
|
||||
|
||||
if (_internalOptimizedGeometry.valid())
|
||||
{
|
||||
_internalOptimizedGeometry->drawImplementation(state);
|
||||
|
@ -83,7 +83,7 @@ void GraphicsThread::add(Operation* operation, bool waitForCompletion)
|
||||
{
|
||||
osg::notify(osg::INFO)<<"Doing add"<<std::endl;
|
||||
|
||||
BlockOperation* block = 0;
|
||||
ref_ptr<BlockOperation> block = 0;
|
||||
|
||||
{
|
||||
// aquire the lock on the operations queue to prevent anyone else for modifying it at the same time
|
||||
@ -95,13 +95,13 @@ void GraphicsThread::add(Operation* operation, bool waitForCompletion)
|
||||
if (waitForCompletion)
|
||||
{
|
||||
block = new BlockOperation;
|
||||
_operations.push_back(block);
|
||||
_operations.push_back(block.get());
|
||||
}
|
||||
|
||||
_operationsBlock->set(true);
|
||||
}
|
||||
|
||||
if (block)
|
||||
if (block.valid())
|
||||
{
|
||||
// now we wait till the barrier is joined by the graphics thread.
|
||||
block->block();
|
||||
@ -126,16 +126,24 @@ void GraphicsThread::run()
|
||||
|
||||
bool firstTime = true;
|
||||
|
||||
OperationQueue::iterator itr = _operations.begin();
|
||||
|
||||
do
|
||||
{
|
||||
// osg::notify(osg::NOTICE)<<"In main loop"<<std::endl;
|
||||
osg::notify(osg::INFO)<<"In main loop"<<std::endl;
|
||||
|
||||
if (_operations.empty())
|
||||
{
|
||||
_operationsBlock->block();
|
||||
|
||||
itr = _operations.begin();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (itr == _operations.end()) itr = _operations.begin();
|
||||
}
|
||||
|
||||
// osg::notify(osg::NOTICE)<<"get op"<<std::endl;
|
||||
osg::notify(osg::INFO)<<"get op"<<std::endl;
|
||||
|
||||
ref_ptr<Operation> operation;
|
||||
|
||||
@ -144,16 +152,32 @@ void GraphicsThread::run()
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_operationsMutex);
|
||||
if (!_operations.empty())
|
||||
{
|
||||
// get the front the queue
|
||||
operation = _operations.front();
|
||||
// get the next item
|
||||
operation = *itr;
|
||||
|
||||
// remove it from the opeations queue
|
||||
_operations.erase(_operations.begin());
|
||||
|
||||
if (_operations.empty())
|
||||
if (!operation->getKeep())
|
||||
{
|
||||
_operationsBlock->set(false);
|
||||
osg::notify(osg::INFO)<<"removing "<<operation->getName()<<std::endl;
|
||||
|
||||
// remove it from the opeations queue
|
||||
itr = _operations.erase(itr);
|
||||
|
||||
osg::notify(osg::INFO)<<"size "<<_operations.size()<<std::endl;
|
||||
|
||||
if (_operations.empty())
|
||||
{
|
||||
osg::notify(osg::INFO)<<"setting block "<<_operations.size()<<std::endl;
|
||||
_operationsBlock->set(false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
osg::notify(osg::INFO)<<"increment "<<operation->getName()<<std::endl;
|
||||
|
||||
// move on to the next operation in the list.
|
||||
++itr;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -161,7 +185,7 @@ void GraphicsThread::run()
|
||||
|
||||
if (operation.valid())
|
||||
{
|
||||
// osg::notify(osg::NOTICE)<<"Doing op"<<std::endl;
|
||||
osg::notify(osg::INFO)<<"Doing op "<<operation->getName()<<std::endl;
|
||||
|
||||
// call the graphics operation.
|
||||
(*operation)(_graphicsContext);
|
||||
|
Loading…
Reference in New Issue
Block a user