mirror of
https://github.com/OpenMW/openmw.git
synced 2025-03-06 01:49:42 +00:00
Write screenshots to file asynchronously
This commit is contained in:
parent
33aa4d0822
commit
f8e02000ec
4 changed files with 81 additions and 11 deletions
|
@ -17,6 +17,7 @@
|
|||
Bug #6129: Player avatar not displayed correctly for large window sizes when GUI scaling active
|
||||
Bug #6131: Item selection in the avatar window not working correctly for large window sizes
|
||||
Bug #6133: Cannot reliably sneak or steal in the sight of the NPCs siding with player
|
||||
Bug #6143: Capturing a screenshot makes engine to be a temporary unresponsive
|
||||
Feature #2780: A way to see current OpenMW version in the console
|
||||
Feature #5489: MCP: Telekinesis fix for activators
|
||||
Feature #6017: Separate persistent and temporary cell references when saving
|
||||
|
|
|
@ -670,6 +670,18 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings)
|
|||
throw std::runtime_error("Invalid setting: 'preload num threads' must be >0");
|
||||
mWorkQueue = new SceneUtil::WorkQueue(numThreads);
|
||||
|
||||
mScreenCaptureOperation = new SceneUtil::AsyncScreenCaptureOperation(
|
||||
mWorkQueue,
|
||||
new SceneUtil::WriteScreenshotToFileOperation(
|
||||
mCfgMgr.getScreenshotPath().string(),
|
||||
Settings::Manager::getString("screenshot format", "General")
|
||||
)
|
||||
);
|
||||
|
||||
mScreenCaptureHandler = new osgViewer::ScreenCaptureHandler(mScreenCaptureOperation);
|
||||
|
||||
mViewer->addEventHandler(mScreenCaptureHandler);
|
||||
|
||||
// Create input and UI first to set up a bootstrapping environment for
|
||||
// showing a loading screen and keeping the window responsive while doing so
|
||||
|
||||
|
@ -814,14 +826,6 @@ void OMW::Engine::go()
|
|||
mViewer->setUseConfigureAffinity(false);
|
||||
#endif
|
||||
|
||||
mScreenCaptureOperation = new SceneUtil::WriteScreenshotToFileOperation(
|
||||
mCfgMgr.getScreenshotPath().string(),
|
||||
Settings::Manager::getString("screenshot format", "General"));
|
||||
|
||||
mScreenCaptureHandler = new osgViewer::ScreenCaptureHandler(mScreenCaptureOperation);
|
||||
|
||||
mViewer->addEventHandler(mScreenCaptureHandler);
|
||||
|
||||
mEnvironment.setFrameRateLimit(Settings::Manager::getFloat("framerate limit", "Video"));
|
||||
|
||||
prepareEngine (settings);
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include <components/debug/debuglog.hpp>
|
||||
#include <components/sceneutil/workqueue.hpp>
|
||||
|
||||
#include <osg/ref_ptr>
|
||||
#include <osg/Image>
|
||||
#include <osgDB/ReaderWriter>
|
||||
#include <osgDB/Registry>
|
||||
|
@ -10,9 +11,43 @@
|
|||
#include <boost/filesystem/fstream.hpp>
|
||||
#include <boost/filesystem/operations.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <cassert>
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
namespace
|
||||
{
|
||||
class ScreenCaptureWorkItem : public SceneUtil::WorkItem
|
||||
{
|
||||
public:
|
||||
ScreenCaptureWorkItem(const osg::ref_ptr<osgViewer::ScreenCaptureHandler::CaptureOperation>& impl,
|
||||
const osg::Image& image, unsigned int contextId)
|
||||
: mImpl(impl),
|
||||
mImage(new osg::Image(image)),
|
||||
mContextId(contextId)
|
||||
{
|
||||
assert(mImpl != nullptr);
|
||||
}
|
||||
|
||||
void doWork() override
|
||||
{
|
||||
try
|
||||
{
|
||||
(*mImpl)(*mImage, mContextId);
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
Log(Debug::Error) << "ScreenCaptureWorkItem exception: " << e.what();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
const osg::ref_ptr<osgViewer::ScreenCaptureHandler::CaptureOperation> mImpl;
|
||||
const osg::ref_ptr<const osg::Image> mImage;
|
||||
const unsigned int mContextId;
|
||||
};
|
||||
}
|
||||
|
||||
namespace SceneUtil
|
||||
{
|
||||
|
@ -70,4 +105,18 @@ namespace SceneUtil
|
|||
<< "\", format=\"" << mScreenshotFormat << "\": " << e.what();
|
||||
}
|
||||
}
|
||||
|
||||
AsyncScreenCaptureOperation::AsyncScreenCaptureOperation(osg::ref_ptr<WorkQueue> queue,
|
||||
osg::ref_ptr<CaptureOperation> impl)
|
||||
: mQueue(std::move(queue)),
|
||||
mImpl(std::move(impl))
|
||||
{
|
||||
assert(mQueue != nullptr);
|
||||
assert(mImpl != nullptr);
|
||||
}
|
||||
|
||||
void AsyncScreenCaptureOperation::operator()(const osg::Image& image, const unsigned int context_id)
|
||||
{
|
||||
mQueue->addWorkItem(new ScreenCaptureWorkItem(mImpl, image, context_id));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#ifndef OPENMW_COMPONENTS_SCENEUTIL_SCREENCAPTURE_H
|
||||
#define OPENMW_COMPONENTS_SCENEUTIL_SCREENCAPTURE_H
|
||||
|
||||
#include <osg/ref_ptr>
|
||||
#include <osgViewer/ViewerEventHandlers>
|
||||
|
||||
#include <string>
|
||||
|
@ -12,6 +13,8 @@ namespace osg
|
|||
|
||||
namespace SceneUtil
|
||||
{
|
||||
class WorkQueue;
|
||||
|
||||
void writeScreenshotToFile(const std::string& screenshotPath, const std::string& screenshotFormat,
|
||||
const osg::Image& image);
|
||||
|
||||
|
@ -20,12 +23,25 @@ namespace SceneUtil
|
|||
public:
|
||||
WriteScreenshotToFileOperation(const std::string& screenshotPath, const std::string& screenshotFormat);
|
||||
|
||||
void operator()(const osg::Image& image, const unsigned int /*context_id*/) override;
|
||||
void operator()(const osg::Image& image, const unsigned int context_id) override;
|
||||
|
||||
private:
|
||||
const std::string mScreenshotPath;
|
||||
const std::string mScreenshotFormat;
|
||||
};
|
||||
|
||||
class AsyncScreenCaptureOperation : public osgViewer::ScreenCaptureHandler::CaptureOperation
|
||||
{
|
||||
public:
|
||||
AsyncScreenCaptureOperation(osg::ref_ptr<SceneUtil::WorkQueue> queue,
|
||||
osg::ref_ptr<osgViewer::ScreenCaptureHandler::CaptureOperation> impl);
|
||||
|
||||
void operator()(const osg::Image& image, const unsigned int context_id) override;
|
||||
|
||||
private:
|
||||
const osg::ref_ptr<SceneUtil::WorkQueue> mQueue;
|
||||
const osg::ref_ptr<osgViewer::ScreenCaptureHandler::CaptureOperation> mImpl;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue