mirror of
https://github.com/OpenMW/openmw.git
synced 2025-02-23 11:09:42 +00:00
Retain final draw callback as a member variable in ScreenshotManager, and do not call setFinalDrawCallback after init.
This commit is contained in:
parent
3d61d7ec9a
commit
5b9a2b73b0
2 changed files with 34 additions and 17 deletions
|
@ -36,8 +36,8 @@ namespace MWRender
|
||||||
class NotifyDrawCompletedCallback : public osg::Camera::DrawCallback
|
class NotifyDrawCompletedCallback : public osg::Camera::DrawCallback
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NotifyDrawCompletedCallback(unsigned int frame)
|
NotifyDrawCompletedCallback()
|
||||||
: mDone(false), mFrame(frame)
|
: mDone(false), mFrame(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,6 +59,12 @@ namespace MWRender
|
||||||
mCondition.wait(lock);
|
mCondition.wait(lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void reset(unsigned int frame)
|
||||||
|
{
|
||||||
|
mDone = false;
|
||||||
|
mFrame = frame;
|
||||||
|
}
|
||||||
|
|
||||||
mutable std::condition_variable mCondition;
|
mutable std::condition_variable mCondition;
|
||||||
mutable std::mutex mMutex;
|
mutable std::mutex mMutex;
|
||||||
mutable bool mDone;
|
mutable bool mDone;
|
||||||
|
@ -94,8 +100,18 @@ namespace MWRender
|
||||||
: mViewer(viewer)
|
: mViewer(viewer)
|
||||||
, mRootNode(rootNode)
|
, mRootNode(rootNode)
|
||||||
, mSceneRoot(sceneRoot)
|
, mSceneRoot(sceneRoot)
|
||||||
|
, mDrawCompleteCallback(new NotifyDrawCompletedCallback)
|
||||||
, mResourceSystem(resourceSystem)
|
, mResourceSystem(resourceSystem)
|
||||||
, mWater(water)
|
, mWater(water)
|
||||||
|
{
|
||||||
|
// Note: This assumes no other final draw callbacks are set anywhere and that this callback will remain set until the application exits.
|
||||||
|
// This works around *DrawCallback manipulation being unsafe in OSG >= 3.5.10 for release 0.47
|
||||||
|
// If you need to set other final draw callbacks, read the comments of issue 6013 for a suggestion
|
||||||
|
// Ref https://gitlab.com/OpenMW/openmw/-/issues/6013
|
||||||
|
mViewer->getCamera()->setFinalDrawCallback(mDrawCompleteCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
ScreenshotManager::~ScreenshotManager()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,16 +123,10 @@ namespace MWRender
|
||||||
tempDrw->setCullingActive(false);
|
tempDrw->setCullingActive(false);
|
||||||
tempDrw->getOrCreateStateSet()->setRenderBinDetails(100, "RenderBin", osg::StateSet::USE_RENDERBIN_DETAILS); // so its after all scene bins but before POST_RENDER gui camera
|
tempDrw->getOrCreateStateSet()->setRenderBinDetails(100, "RenderBin", osg::StateSet::USE_RENDERBIN_DETAILS); // so its after all scene bins but before POST_RENDER gui camera
|
||||||
camera->addChild(tempDrw);
|
camera->addChild(tempDrw);
|
||||||
osg::ref_ptr<NotifyDrawCompletedCallback> callback (new NotifyDrawCompletedCallback(mViewer->getFrameStamp()->getFrameNumber()));
|
traversalsAndWait(mViewer->getFrameStamp()->getFrameNumber());
|
||||||
camera->setFinalDrawCallback(callback);
|
|
||||||
mViewer->eventTraversal();
|
|
||||||
mViewer->updateTraversal();
|
|
||||||
mViewer->renderingTraversals();
|
|
||||||
callback->waitTillDone();
|
|
||||||
// now that we've "used up" the current frame, get a fresh frame number for the next frame() following after the screenshot is completed
|
// now that we've "used up" the current frame, get a fresh frame number for the next frame() following after the screenshot is completed
|
||||||
mViewer->advance(mViewer->getFrameStamp()->getSimulationTime());
|
mViewer->advance(mViewer->getFrameStamp()->getSimulationTime());
|
||||||
camera->removeChild(tempDrw);
|
camera->removeChild(tempDrw);
|
||||||
camera->setFinalDrawCallback(nullptr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ScreenshotManager::screenshot360(osg::Image* image)
|
bool ScreenshotManager::screenshot360(osg::Image* image)
|
||||||
|
@ -257,6 +267,15 @@ namespace MWRender
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ScreenshotManager::traversalsAndWait(unsigned int frame)
|
||||||
|
{
|
||||||
|
mDrawCompleteCallback->reset(frame);
|
||||||
|
mViewer->eventTraversal();
|
||||||
|
mViewer->updateTraversal();
|
||||||
|
mViewer->renderingTraversals();
|
||||||
|
mDrawCompleteCallback->waitTillDone();
|
||||||
|
}
|
||||||
|
|
||||||
void ScreenshotManager::renderCameraToImage(osg::Camera *camera, osg::Image *image, int w, int h)
|
void ScreenshotManager::renderCameraToImage(osg::Camera *camera, osg::Image *image, int w, int h)
|
||||||
{
|
{
|
||||||
camera->setNodeMask(Mask_RenderToTexture);
|
camera->setNodeMask(Mask_RenderToTexture);
|
||||||
|
@ -280,16 +299,10 @@ namespace MWRender
|
||||||
|
|
||||||
mRootNode->addChild(camera);
|
mRootNode->addChild(camera);
|
||||||
|
|
||||||
// The draw needs to complete before we can copy back our image.
|
|
||||||
osg::ref_ptr<NotifyDrawCompletedCallback> callback (new NotifyDrawCompletedCallback(0));
|
|
||||||
camera->setFinalDrawCallback(callback);
|
|
||||||
|
|
||||||
MWBase::Environment::get().getWindowManager()->getLoadingScreen()->loadingOn(false);
|
MWBase::Environment::get().getWindowManager()->getLoadingScreen()->loadingOn(false);
|
||||||
|
|
||||||
mViewer->eventTraversal();
|
// The draw needs to complete before we can copy back our image.
|
||||||
mViewer->updateTraversal();
|
traversalsAndWait(0);
|
||||||
mViewer->renderingTraversals();
|
|
||||||
callback->waitTillDone();
|
|
||||||
|
|
||||||
MWBase::Environment::get().getWindowManager()->getLoadingScreen()->loadingOff();
|
MWBase::Environment::get().getWindowManager()->getLoadingScreen()->loadingOff();
|
||||||
|
|
||||||
|
|
|
@ -16,11 +16,13 @@ namespace Resource
|
||||||
namespace MWRender
|
namespace MWRender
|
||||||
{
|
{
|
||||||
class Water;
|
class Water;
|
||||||
|
class NotifyDrawCompletedCallback;
|
||||||
|
|
||||||
class ScreenshotManager
|
class ScreenshotManager
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ScreenshotManager(osgViewer::Viewer* viewer, osg::ref_ptr<osg::Group> rootNode, osg::ref_ptr<osg::Group> sceneRoot, Resource::ResourceSystem* resourceSystem, Water* water);
|
ScreenshotManager(osgViewer::Viewer* viewer, osg::ref_ptr<osg::Group> rootNode, osg::ref_ptr<osg::Group> sceneRoot, Resource::ResourceSystem* resourceSystem, Water* water);
|
||||||
|
~ScreenshotManager();
|
||||||
|
|
||||||
void screenshot(osg::Image* image, int w, int h);
|
void screenshot(osg::Image* image, int w, int h);
|
||||||
bool screenshot360(osg::Image* image);
|
bool screenshot360(osg::Image* image);
|
||||||
|
@ -29,9 +31,11 @@ namespace MWRender
|
||||||
osg::ref_ptr<osgViewer::Viewer> mViewer;
|
osg::ref_ptr<osgViewer::Viewer> mViewer;
|
||||||
osg::ref_ptr<osg::Group> mRootNode;
|
osg::ref_ptr<osg::Group> mRootNode;
|
||||||
osg::ref_ptr<osg::Group> mSceneRoot;
|
osg::ref_ptr<osg::Group> mSceneRoot;
|
||||||
|
osg::ref_ptr<NotifyDrawCompletedCallback> mDrawCompleteCallback;
|
||||||
Resource::ResourceSystem* mResourceSystem;
|
Resource::ResourceSystem* mResourceSystem;
|
||||||
Water* mWater;
|
Water* mWater;
|
||||||
|
|
||||||
|
void traversalsAndWait(unsigned int frame);
|
||||||
void renderCameraToImage(osg::Camera *camera, osg::Image *image, int w, int h);
|
void renderCameraToImage(osg::Camera *camera, osg::Image *image, int w, int h);
|
||||||
void makeCubemapScreenshot(osg::Image* image, int w, int h, osg::Matrixd cameraTransform=osg::Matrixd());
|
void makeCubemapScreenshot(osg::Image* image, int w, int h, osg::Matrixd cameraTransform=osg::Matrixd());
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue