diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index a06faa4d71..d03891fdc6 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -40,6 +40,8 @@ #include +#include + #include "mwinput/inputmanagerimp.hpp" #include "mwgui/windowmanagerimp.hpp" @@ -781,54 +783,6 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings) } } -class WriteScreenshotToFileOperation : public osgViewer::ScreenCaptureHandler::CaptureOperation -{ -public: - WriteScreenshotToFileOperation(const std::string& screenshotPath, const std::string& screenshotFormat) - : mScreenshotPath(screenshotPath) - , mScreenshotFormat(screenshotFormat) - { - } - - void operator()(const osg::Image& image, const unsigned int context_id) override - { - // Count screenshots. - int shotCount = 0; - - // Find the first unused filename with a do-while - std::ostringstream stream; - do - { - // Reset the stream - stream.str(""); - stream.clear(); - - stream << mScreenshotPath << "/screenshot" << std::setw(3) << std::setfill('0') << shotCount++ << "." << mScreenshotFormat; - - } while (boost::filesystem::exists(stream.str())); - - boost::filesystem::ofstream outStream; - outStream.open(boost::filesystem::path(stream.str()), std::ios::binary); - - osgDB::ReaderWriter* readerwriter = osgDB::Registry::instance()->getReaderWriterForExtension(mScreenshotFormat); - if (!readerwriter) - { - Log(Debug::Error) << "Error: Can't write screenshot, no '" << mScreenshotFormat << "' readerwriter found"; - return; - } - - osgDB::ReaderWriter::WriteResult result = readerwriter->writeImage(image, outStream); - if (!result.success()) - { - Log(Debug::Error) << "Error: Can't write screenshot: " << result.message() << " code " << result.status(); - } - } - -private: - std::string mScreenshotPath; - std::string mScreenshotFormat; -}; - // Initialise and enter main loop. void OMW::Engine::go() { @@ -860,7 +814,7 @@ void OMW::Engine::go() mViewer->setUseConfigureAffinity(false); #endif - mScreenCaptureOperation = new WriteScreenshotToFileOperation( + mScreenCaptureOperation = new SceneUtil::WriteScreenshotToFileOperation( mCfgMgr.getScreenshotPath().string(), Settings::Manager::getString("screenshot format", "General")); diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index 7860f492ce..43987d6c7b 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -53,6 +53,7 @@ add_component_dir (sceneutil clone attach visitor util statesetupdater controller skeleton riggeometry morphgeometry lightcontroller lightmanager lightutil positionattitudetransform workqueue unrefqueue pathgridutil waterutil writescene serialize optimizer actorutil detourdebugdraw navmesh agentpath shadow mwshadowtechnique recastmesh shadowsbin osgacontroller + screencapture ) add_component_dir (nif diff --git a/components/sceneutil/screencapture.cpp b/components/sceneutil/screencapture.cpp new file mode 100644 index 0000000000..660f296b63 --- /dev/null +++ b/components/sceneutil/screencapture.cpp @@ -0,0 +1,73 @@ +#include "screencapture.hpp" + +#include +#include + +#include +#include +#include + +#include +#include + +#include +#include +#include + +namespace SceneUtil +{ + void writeScreenshotToFile(const std::string& screenshotPath, const std::string& screenshotFormat, + const osg::Image& image) + { + // Count screenshots. + int shotCount = 0; + + // Find the first unused filename with a do-while + std::ostringstream stream; + do + { + // Reset the stream + stream.str(""); + stream.clear(); + + stream << screenshotPath << "/screenshot" << std::setw(3) << std::setfill('0') << shotCount++ << "." << screenshotFormat; + + } while (boost::filesystem::exists(stream.str())); + + boost::filesystem::ofstream outStream; + outStream.open(boost::filesystem::path(stream.str()), std::ios::binary); + + osgDB::ReaderWriter* readerwriter = osgDB::Registry::instance()->getReaderWriterForExtension(screenshotFormat); + if (!readerwriter) + { + Log(Debug::Error) << "Error: Can't write screenshot, no '" << screenshotFormat << "' readerwriter found"; + return; + } + + osgDB::ReaderWriter::WriteResult result = readerwriter->writeImage(image, outStream); + if (!result.success()) + { + Log(Debug::Error) << "Error: Can't write screenshot: " << result.message() << " code " << result.status(); + } + } + + WriteScreenshotToFileOperation::WriteScreenshotToFileOperation(const std::string& screenshotPath, + const std::string& screenshotFormat) + : mScreenshotPath(screenshotPath) + , mScreenshotFormat(screenshotFormat) + { + } + + void WriteScreenshotToFileOperation::operator()(const osg::Image& image, const unsigned int /*context_id*/) + { + try + { + writeScreenshotToFile(mScreenshotPath, mScreenshotFormat, image); + } + catch (const std::exception& e) + { + Log(Debug::Error) << "Failed to write screenshot to file with path=\"" << mScreenshotPath + << "\", format=\"" << mScreenshotFormat << "\": " << e.what(); + } + } +} diff --git a/components/sceneutil/screencapture.hpp b/components/sceneutil/screencapture.hpp new file mode 100644 index 0000000000..37ff5e39cc --- /dev/null +++ b/components/sceneutil/screencapture.hpp @@ -0,0 +1,31 @@ +#ifndef OPENMW_COMPONENTS_SCENEUTIL_SCREENCAPTURE_H +#define OPENMW_COMPONENTS_SCENEUTIL_SCREENCAPTURE_H + +#include + +#include + +namespace osg +{ + class Image; +} + +namespace SceneUtil +{ + void writeScreenshotToFile(const std::string& screenshotPath, const std::string& screenshotFormat, + const osg::Image& image); + + class WriteScreenshotToFileOperation : public osgViewer::ScreenCaptureHandler::CaptureOperation + { + public: + WriteScreenshotToFileOperation(const std::string& screenshotPath, const std::string& screenshotFormat); + + void operator()(const osg::Image& image, const unsigned int /*context_id*/) override; + + private: + const std::string mScreenshotPath; + const std::string mScreenshotFormat; + }; +} + +#endif