Clean up of new DatabasePager code, and change of osgProducer so that
DatabasePager support is now integrated into the OsgSceneHandler.
This commit is contained in:
parent
fc68ccacb7
commit
1b31024cd5
@ -182,15 +182,11 @@ class OSGDB_EXPORT DatabasePager : public osg::NodeVisitor::DatabaseRequestHandl
|
||||
void getMaxAnisotropyPolicy(bool& changeAnisotropy, float& valueAnisotropy) const { changeAnisotropy = _changeAnisotropy; valueAnisotropy = _valueAnisotropy; }
|
||||
|
||||
|
||||
/** Iterate through the active PagedLOD nodes children removing
|
||||
* children which havn't been visited since specified expiryTime.
|
||||
* note, should be only be called from the update thread. */
|
||||
void removeExpiredSubgraphs(double currentFrameTime);
|
||||
/** Return trye if there are pending updates to the scene graph that require a call to updateSceneGraph(double). */
|
||||
bool requiresUpdateSceneGraph() const;
|
||||
|
||||
/** Add the loaded data to the scene graph.*/
|
||||
void addLoadedDataToSceneGraph(double currentFrameTime);
|
||||
|
||||
/** Merge the changes to the scene graph by calling calling removeExpiredSubgraphs then addLoadedDataToSceneGraph*/
|
||||
/** Merge the changes to the scene graph by calling calling removeExpiredSubgraphs then addLoadedDataToSceneGraph.
|
||||
* Note, must only be called from single thread update phase. */
|
||||
void updateSceneGraph(double currentFrameTime)
|
||||
{
|
||||
removeExpiredSubgraphs(currentFrameTime);
|
||||
@ -204,8 +200,13 @@ class OSGDB_EXPORT DatabasePager : public osg::NodeVisitor::DatabaseRequestHandl
|
||||
/** Get whether the compilation of rendering objects for specfied graphics context on (true) or off(false). */
|
||||
bool getCompileGLObjectsForContextID(unsigned int contextID);
|
||||
|
||||
/** Return true if there are pending compile operations that are required.
|
||||
* If requiresCompileGLObjects() return true the application should call compileGLObjects() .*/
|
||||
bool requiresCompileGLObjects() const;
|
||||
|
||||
/** Compile the rendering objects (display lists,texture objects, VBO's) on loaded subgraph.
|
||||
* note, should only be called from the draw thread.*/
|
||||
* note, should only be called from the draw thread.
|
||||
* Note, must only be called from a valid graphics context. */
|
||||
void compileGLObjects(osg::State& state,double& availableTime);
|
||||
|
||||
|
||||
@ -213,7 +214,7 @@ class OSGDB_EXPORT DatabasePager : public osg::NodeVisitor::DatabaseRequestHandl
|
||||
|
||||
typedef std::list< osg::ref_ptr<osg::PagedLOD> > PagedLODList;
|
||||
|
||||
typedef std::vector< osg::ref_ptr<osg::StateSet> > StateSetList;
|
||||
typedef std::set< osg::ref_ptr<osg::StateSet> > StateSetList;
|
||||
typedef std::vector< osg::ref_ptr<osg::Drawable> > DrawableList;
|
||||
typedef std::pair<StateSetList,DrawableList> DataToCompile;
|
||||
typedef std::map< unsigned int, DataToCompile > DataToCompileMap;
|
||||
@ -262,6 +263,15 @@ class OSGDB_EXPORT DatabasePager : public osg::NodeVisitor::DatabaseRequestHandl
|
||||
}
|
||||
|
||||
|
||||
/** Iterate through the active PagedLOD nodes children removing
|
||||
* children which havn't been visited since specified expiryTime.
|
||||
* note, should be only be called from the update thread. */
|
||||
void removeExpiredSubgraphs(double currentFrameTime);
|
||||
|
||||
/** Add the loaded data to the scene graph.*/
|
||||
void addLoadedDataToSceneGraph(double currentFrameTime);
|
||||
|
||||
|
||||
bool _done;
|
||||
bool _acceptNewRequests;
|
||||
bool _databasePagerThreadPaused;
|
||||
@ -274,10 +284,10 @@ class OSGDB_EXPORT DatabasePager : public osg::NodeVisitor::DatabaseRequestHandl
|
||||
ThreadPriority _threadPriorityOutwithFrame;
|
||||
|
||||
DatabaseRequestList _fileRequestList;
|
||||
OpenThreads::Mutex _fileRequestListMutex;
|
||||
mutable OpenThreads::Mutex _fileRequestListMutex;
|
||||
|
||||
DatabaseRequestList _dataToCompileList;
|
||||
OpenThreads::Mutex _dataToCompileListMutex;
|
||||
mutable OpenThreads::Mutex _dataToCompileListMutex;
|
||||
|
||||
bool _changeAutoUnRef;
|
||||
bool _valueAutoUnRef;
|
||||
@ -286,10 +296,10 @@ class OSGDB_EXPORT DatabasePager : public osg::NodeVisitor::DatabaseRequestHandl
|
||||
|
||||
bool _deleteRemovedSubgraphsInDatabaseThread;
|
||||
ObjectList _childrenToDeleteList;
|
||||
OpenThreads::Mutex _childrenToDeleteListMutex;
|
||||
mutable OpenThreads::Mutex _childrenToDeleteListMutex;
|
||||
|
||||
DatabaseRequestList _dataToMergeList;
|
||||
OpenThreads::Mutex _dataToMergeListMutex;
|
||||
mutable OpenThreads::Mutex _dataToMergeListMutex;
|
||||
|
||||
|
||||
PagedLODList _activePagedLODList;
|
||||
|
@ -14,10 +14,14 @@
|
||||
#ifndef OSGPRODUCER_OSGSCENEHANDLER
|
||||
#define OSGPRODUCER_OSGSCENEHANDLER 1
|
||||
|
||||
#include <osgProducer/Export>
|
||||
#include <osg/Timer>
|
||||
#include <osgUtil/SceneView>
|
||||
|
||||
#include <Producer/Camera>
|
||||
#include <osgUtil/SceneView>
|
||||
|
||||
#include <osgProducer/Export>
|
||||
|
||||
|
||||
|
||||
namespace osgProducer {
|
||||
|
||||
@ -99,6 +103,8 @@ class OSGPRODUCER_EXPORT OsgSceneHandler : public Producer::Camera::SceneHandler
|
||||
osg::ref_ptr<Callback> _clearCallback;
|
||||
osg::ref_ptr<Callback> _cullCallback;
|
||||
osg::ref_ptr<Callback> _drawCallback;
|
||||
|
||||
osg::Timer_t _frameStartTick;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -257,7 +257,7 @@ void TextureObjectManager::flushTextureObjects(unsigned int contextID,double cur
|
||||
itr!=tol.end() && elapsedTime<availableTime && tol.size()>s_minimumNumberOfTextureObjectsToRetainInCache && numObjectsDeleted<maxNumObjectsToDelete;
|
||||
)
|
||||
{
|
||||
if ((*itr)->_timeStamp<expiryTime)
|
||||
if ((*itr)->_timeStamp<=expiryTime)
|
||||
{
|
||||
--s_number;
|
||||
++Texture::s_numberDeletedTextureInLastFrame;
|
||||
|
@ -47,7 +47,7 @@ DatabasePager::DatabasePager()
|
||||
_deleteRemovedSubgraphsInDatabaseThread = false;
|
||||
#endif
|
||||
|
||||
_expiryDelay = 30;
|
||||
_expiryDelay = 10;
|
||||
|
||||
// make sure a SharedStateManager exists.
|
||||
//osgDB::Registry::instance()->getOrCreateSharedStateManager();
|
||||
@ -226,11 +226,6 @@ void DatabasePager::requestNodeFile(const std::string& fileName,osg::Group* grou
|
||||
}
|
||||
}
|
||||
|
||||
static double s_start_frame = 0;
|
||||
static double s_before_compile = 0;
|
||||
static double s_after_compile = 0;
|
||||
static osg::Timer_t startTick = 0;
|
||||
|
||||
void DatabasePager::signalBeginFrame(const osg::FrameStamp* framestamp)
|
||||
{
|
||||
|
||||
@ -239,58 +234,8 @@ void DatabasePager::signalBeginFrame(const osg::FrameStamp* framestamp)
|
||||
//osg::notify(osg::INFO) << "signalBeginFrame "<<framestamp->getFrameNumber()<<">>>>>>>>>>>>>>>>"<<std::endl;
|
||||
_frameNumber = framestamp->getFrameNumber();
|
||||
|
||||
|
||||
} //else osg::notify(osg::INFO) << "signalBeginFrame >>>>>>>>>>>>>>>>"<<std::endl;
|
||||
|
||||
if (startTick==0) startTick = osg::Timer::instance()->tick();
|
||||
|
||||
double timeStamp = osg::Timer::instance()->delta_s(startTick,osg::Timer::instance()->tick());
|
||||
|
||||
double drawTime = s_before_compile-s_start_frame;
|
||||
double compileTime = s_after_compile-s_before_compile;
|
||||
double timeDelta = timeStamp-s_start_frame;
|
||||
|
||||
unsigned int numFrames = (timeDelta*60.0074);
|
||||
/*
|
||||
if (timeDelta>0.02)
|
||||
{
|
||||
std::string str;
|
||||
if (osg::Texture::s_numberTextureReusedLastInLastFrame > 0) str += " RT ";
|
||||
if (osg::Texture::s_numberNewTextureInLastFrame > 0) str += " NT ";
|
||||
if (osg::Texture::s_numberDeletedTextureInLastFrame > 0) str += " DT ";
|
||||
if (osg::Drawable::s_numberDrawablesReusedLastInLastFrame > 0) str += " RD ";
|
||||
if (osg::Drawable::s_numberNewDrawablesInLastFrame > 0) str += " ND ";
|
||||
if (osg::Drawable::s_numberDeletedDrawablesInLastFrame > 0) str += " DD ";
|
||||
|
||||
if (str.empty()) str += " ?? ";
|
||||
|
||||
osg::notify(osg::NOTICE)<<" ************* frame="<<timeDelta<<"\tdraw="<<drawTime<<"\tcompile="<<compileTime<<" ***** FRAMES DROPPED ********** "<<str<<std::dec<<std::endl;
|
||||
osg::notify(osg::NOTICE)<<"\tosg::Texture::s_numberTextureReusedLastInLastFrame = "<<osg::Texture::s_numberTextureReusedLastInLastFrame<<std::endl;
|
||||
osg::notify(osg::NOTICE)<<"\tosg::Texture::s_numberNewTextureInLastFrame = "<<osg::Texture::s_numberNewTextureInLastFrame <<std::endl;
|
||||
osg::notify(osg::NOTICE)<<"\tosg::Texture::s_numberDeletedTextureInLastFrame = "<<osg::Texture::s_numberDeletedTextureInLastFrame <<std::endl;
|
||||
osg::notify(osg::NOTICE)<<"\tosg::Drawable::s_numberDrawablesReusedLastInLastFrame = "<<osg::Drawable::s_numberDrawablesReusedLastInLastFrame <<std::endl;
|
||||
osg::notify(osg::NOTICE)<<"\tosg::Drawable::s_numberNewDrawablesInLastFrame = "<<osg::Drawable::s_numberNewDrawablesInLastFrame <<std::endl;
|
||||
osg::notify(osg::NOTICE)<<"\tosg::Drawable::s_numberDeletedDrawablesInLastFrame = "<<osg::Drawable::s_numberDeletedDrawablesInLastFrame <<std::endl;
|
||||
|
||||
}
|
||||
*/
|
||||
s_start_frame = timeStamp;
|
||||
|
||||
osg::Texture::s_numberTextureReusedLastInLastFrame = 0;
|
||||
osg::Texture::s_numberNewTextureInLastFrame = 0;
|
||||
osg::Texture::s_numberDeletedTextureInLastFrame = 0;
|
||||
osg::Drawable::s_numberDrawablesReusedLastInLastFrame = 0;
|
||||
osg::Drawable::s_numberNewDrawablesInLastFrame = 0;
|
||||
osg::Drawable::s_numberDeletedDrawablesInLastFrame = 0;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
_frameBlock->reset();
|
||||
|
||||
@ -362,7 +307,7 @@ public:
|
||||
if (foundTextureState)
|
||||
{
|
||||
//osg::notify(osg::DEBUG_INFO)<<"Found compilable texture state"<<std::endl;
|
||||
_dataToCompile.first.push_back(stateset);
|
||||
_dataToCompile.first.insert(stateset);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -580,6 +525,19 @@ void DatabasePager::run()
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool DatabasePager::requiresUpdateSceneGraph() const
|
||||
{
|
||||
{
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_dataToMergeListMutex);
|
||||
if (!_dataToMergeList.empty()) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void DatabasePager::addLoadedDataToSceneGraph(double timeStamp)
|
||||
{
|
||||
|
||||
@ -623,6 +581,7 @@ void DatabasePager::addLoadedDataToSceneGraph(double timeStamp)
|
||||
|
||||
}
|
||||
|
||||
|
||||
void DatabasePager::removeExpiredSubgraphs(double currentFrameTime)
|
||||
{
|
||||
//osg::notify(osg::NOTICE)<<"DatabasePager::removeExpiredSubgraphs()"<<std::endl;
|
||||
@ -711,8 +670,7 @@ void DatabasePager::removeExpiredSubgraphs(double currentFrameTime)
|
||||
if (childrenRemoved.size()<targetNumOfRemovedChildPagedLODs)
|
||||
{
|
||||
// check for removing expired children.
|
||||
if (const_cast<osg::PagedLOD*>(plod)->removeExpiredChildren(currentFrameTime,childrenRemoved))
|
||||
// if (const_cast<osg::PagedLOD*>(plod)->removeExpiredChildren(expiryTime,childrenRemoved))
|
||||
if (const_cast<osg::PagedLOD*>(plod)->removeExpiredChildren(expiryTime,childrenRemoved))
|
||||
{
|
||||
//osg::notify(osg::NOTICE)<<"Some children removed from PLod"<<std::endl;
|
||||
}
|
||||
@ -794,6 +752,12 @@ void DatabasePager::registerPagedLODs(osg::Node* subgraph)
|
||||
if (subgraph) subgraph->accept(fplv);
|
||||
}
|
||||
|
||||
bool DatabasePager::requiresCompileGLObjects() const
|
||||
{
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_dataToCompileListMutex);
|
||||
return !_dataToCompileList.empty();
|
||||
}
|
||||
|
||||
void DatabasePager::setCompileGLObjectsForContextID(unsigned int contextID, bool on)
|
||||
{
|
||||
if (on)
|
||||
@ -816,19 +780,14 @@ void DatabasePager::compileGLObjects(osg::State& state, double& availableTime)
|
||||
{
|
||||
// osg::notify(osg::NOTICE)<<"DatabasePager::compileGLObjects "<<_frameNumber<<std::endl;
|
||||
|
||||
|
||||
s_before_compile = osg::Timer::instance()->delta_s(startTick,osg::Timer::instance()->tick());
|
||||
|
||||
|
||||
double drawTime = s_before_compile-s_start_frame;
|
||||
if (drawTime<0.01)
|
||||
if (availableTime>0.0)
|
||||
{
|
||||
|
||||
const osg::Timer& timer = *osg::Timer::instance();
|
||||
osg::Timer_t start_tick = timer.tick();
|
||||
double elapsedTime = 0.0;
|
||||
double estimatedTextureDuration = 0.0;
|
||||
double estimatedDrawableDuration = 0.0;
|
||||
double estimatedTextureDuration = 0.0001;
|
||||
double estimatedDrawableDuration = 0.0001;
|
||||
|
||||
osg::ref_ptr<DatabaseRequest> databaseRequest;
|
||||
|
||||
@ -930,8 +889,6 @@ void DatabasePager::compileGLObjects(osg::State& state, double& availableTime)
|
||||
// estimate the duration of the compile based on current compile duration.
|
||||
estimatedDrawableDuration = (elapsedTime-startCompileTime);
|
||||
|
||||
// osg::notify(osg::NOTICE)<<" Compiling drawable "<<estimatedDrawableDuration<<std::endl;
|
||||
|
||||
++numObjectsCompiled;
|
||||
|
||||
}
|
||||
@ -955,8 +912,6 @@ void DatabasePager::compileGLObjects(osg::State& state, double& availableTime)
|
||||
|
||||
if (allCompiled)
|
||||
{
|
||||
osg::notify(osg::INFO)<<"All compiled"<<std::endl;
|
||||
|
||||
// we've compile all of the current databaseRequest so we can now pop it off the
|
||||
// to compile list and place it on the merge list.
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_dataToCompileListMutex);
|
||||
@ -985,9 +940,9 @@ void DatabasePager::compileGLObjects(osg::State& state, double& availableTime)
|
||||
elapsedTime = timer.delta_s(start_tick,timer.tick());
|
||||
}
|
||||
|
||||
// availableTime -= elapsedTime;
|
||||
availableTime -= elapsedTime;
|
||||
|
||||
// osg::notify(osg::NOTICE)<<"elapsedTime="<<elapsedTime<<" time remaining ="<<availableTime<<std::endl;
|
||||
//osg::notify(osg::NOTICE)<<"elapsedTime="<<elapsedTime<<"\ttime remaining ="<<availableTime<<"\tnumObjectsCompiled = "<<numObjectsCompiled<<std::endl;
|
||||
//osg::notify(osg::NOTICE)<<"estimatedTextureDuration="<<estimatedTextureDuration;
|
||||
//osg::notify(osg::NOTICE)<<"\testimatedDrawableDuration="<<estimatedDrawableDuration<<std::endl;
|
||||
}
|
||||
@ -995,8 +950,5 @@ void DatabasePager::compileGLObjects(osg::State& state, double& availableTime)
|
||||
{
|
||||
availableTime = 0.0f;
|
||||
}
|
||||
|
||||
s_after_compile = osg::Timer::instance()->delta_s(startTick,osg::Timer::instance()->tick());
|
||||
|
||||
}
|
||||
|
||||
|
@ -13,6 +13,8 @@
|
||||
|
||||
#include <OpenThreads/Mutex>
|
||||
|
||||
#include <osgDB/Registry>
|
||||
|
||||
#include <osgProducer/OsgSceneHandler>
|
||||
|
||||
using namespace osgUtil;
|
||||
@ -39,6 +41,14 @@ void OsgSceneHandler::init()
|
||||
|
||||
void OsgSceneHandler::clearImplementation(Producer::Camera& /*camera*/)
|
||||
{
|
||||
_frameStartTick = osg::Timer::instance()->tick();
|
||||
|
||||
osgDB::DatabasePager* dp = osgDB::Registry::instance()->getDatabasePager();
|
||||
if (dp)
|
||||
{
|
||||
dp->signalBeginFrame(getSceneView()->getState()->getFrameStamp());
|
||||
}
|
||||
|
||||
// no-op right now as scene view manages its own clear.
|
||||
}
|
||||
|
||||
@ -63,7 +73,31 @@ void OsgSceneHandler::cullImplementation(Producer::Camera &cam)
|
||||
|
||||
void OsgSceneHandler::drawImplementation(Producer::Camera &)
|
||||
{
|
||||
// dipatch the draw traversal of the scene graph
|
||||
_sceneView->SceneView::draw();
|
||||
|
||||
|
||||
// for the database pager now manage any GL object operations that are required.
|
||||
osgDB::DatabasePager* dp = osgDB::Registry::instance()->getDatabasePager();
|
||||
if (dp)
|
||||
{
|
||||
double timeForCullAndDraw = osg::Timer::instance()->delta_s(_frameStartTick, osg::Timer::instance()->tick());
|
||||
|
||||
double targetMaxFrameTime = 0.010; // 10ms.
|
||||
|
||||
double availableTime = targetMaxFrameTime-timeForCullAndDraw;
|
||||
// availableTime = 0.1; // 2.5 ms
|
||||
|
||||
if (availableTime>0.0)
|
||||
{
|
||||
dp->compileGLObjects(*(getSceneView()->getState()),availableTime);
|
||||
|
||||
// flush deleted GL objects.
|
||||
getSceneView()->flushDeletedGLObjects(availableTime);
|
||||
}
|
||||
|
||||
dp->signalEndFrame();
|
||||
}
|
||||
}
|
||||
|
||||
void OsgSceneHandler::setContextID( int id )
|
||||
|
@ -478,77 +478,16 @@ bool Viewer::realize( ThreadingModel thread_model )
|
||||
return realize();
|
||||
}
|
||||
|
||||
class DatabasePagerStartCullCallback : public OsgSceneHandler::Callback
|
||||
class PostSwapFinishCallback : public Producer::Camera::Callback
|
||||
{
|
||||
public:
|
||||
|
||||
DatabasePagerStartCullCallback() {}
|
||||
|
||||
virtual void operator()(OsgSceneHandler& sh, Producer::Camera& camera)
|
||||
{
|
||||
osgDB::DatabasePager* dp = osgDB::Registry::instance()->getDatabasePager();
|
||||
if (dp) dp->signalBeginFrame(sh.getSceneView()->getState()->getFrameStamp());
|
||||
|
||||
sh.cullImplementation(camera);
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
class DatabasePagerCompileCallback : public OsgSceneHandler::Callback
|
||||
{
|
||||
public:
|
||||
|
||||
DatabasePagerCompileCallback() {}
|
||||
|
||||
virtual void operator()(OsgSceneHandler& sh, Producer::Camera& camera)
|
||||
{
|
||||
|
||||
sh.drawImplementation(camera);
|
||||
|
||||
osgDB::DatabasePager* dp = osgDB::Registry::instance()->getDatabasePager();
|
||||
#if 1
|
||||
double availableTime = 0.0025; // 2.5 ms
|
||||
|
||||
// compile any GL objects that are required.
|
||||
if (dp) dp->compileGLObjects(*(sh.getSceneView()->getState()),availableTime);
|
||||
|
||||
// flush deleted GL objects.
|
||||
sh.getSceneView()->flushDeletedGLObjects(availableTime);
|
||||
#endif
|
||||
|
||||
if (dp) dp->signalEndFrame();
|
||||
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
class PostSwapCompileCallback : public Producer::Camera::Callback
|
||||
{
|
||||
public:
|
||||
|
||||
PostSwapCompileCallback(osgUtil::SceneView* sceneView):
|
||||
_sceneView(sceneView)
|
||||
{}
|
||||
PostSwapFinishCallback() {}
|
||||
|
||||
virtual void operator()(const Producer::Camera&)
|
||||
{
|
||||
#if 0
|
||||
osgDB::DatabasePager* dp = osgDB::Registry::instance()->getDatabasePager();
|
||||
|
||||
double availableTime = 0.0025; // 2.5 ms
|
||||
|
||||
// flush deleted GL objects.
|
||||
_sceneView->flushDeletedGLObjects(availableTime);
|
||||
|
||||
// compile any GL objects that are required.
|
||||
if (dp) dp->compileGLObjects(*(_sceneView->getState()),availableTime);
|
||||
#endif
|
||||
|
||||
// glFinish();
|
||||
|
||||
}
|
||||
|
||||
osg::ref_ptr<osgUtil::SceneView> _sceneView;
|
||||
};
|
||||
|
||||
bool Viewer::realize()
|
||||
@ -572,13 +511,6 @@ bool Viewer::realize()
|
||||
// pass the database pager to the cull visitor so node can send requests to the pager.
|
||||
(*p)->getSceneView()->getCullVisitor()->setDatabaseRequestHandler(databasePager);
|
||||
|
||||
(*p)->setCullCallback(new DatabasePagerStartCullCallback());
|
||||
|
||||
// set up a draw callback to pre compile any rendering object of database has loaded,
|
||||
// but not yet merged with the main scene graph.
|
||||
(*p)->setDrawCallback(new DatabasePagerCompileCallback());
|
||||
|
||||
|
||||
// tell the database pager which graphic context the compile of rendering objexts is needed.
|
||||
databasePager->setCompileGLObjectsForContextID((*p)->getSceneView()->getState()->getContextID(),true);
|
||||
}
|
||||
@ -588,7 +520,7 @@ bool Viewer::realize()
|
||||
for(unsigned int cameraNum=0;cameraNum<getNumberOfCameras();++cameraNum)
|
||||
{
|
||||
Producer::Camera* camera=getCamera(cameraNum);
|
||||
camera->addPostSwapCallback(new PostSwapCompileCallback(_shvec[cameraNum]->getSceneView()));
|
||||
camera->addPostSwapCallback(new PostSwapFinishCallback());
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user