forked from mirror/openmw-tes3mp
Write savegame screenshot
This commit is contained in:
parent
24551c7bab
commit
2a85a22dba
7 changed files with 101 additions and 13 deletions
|
@ -23,6 +23,7 @@ namespace osg
|
|||
{
|
||||
class Vec3f;
|
||||
class Quat;
|
||||
class Image;
|
||||
}
|
||||
|
||||
namespace Loading
|
||||
|
@ -438,7 +439,7 @@ namespace MWBase
|
|||
virtual void reattachPlayerCamera() = 0;
|
||||
|
||||
/// \todo this does not belong here
|
||||
virtual void screenshot (Ogre::Image& image, int w, int h) = 0;
|
||||
virtual void screenshot (osg::Image* image, int w, int h) = 0;
|
||||
|
||||
/// Find default position inside exterior cell specified by name
|
||||
/// \return false if exterior with given name not exists, true otherwise
|
||||
|
|
|
@ -379,6 +379,65 @@ namespace MWRender
|
|||
mWater->setHeight(height);
|
||||
}
|
||||
|
||||
class NotifyDrawCompletedCallback : public osg::Camera::DrawCallback
|
||||
{
|
||||
public:
|
||||
virtual void operator () (osg::RenderInfo& renderInfo) const
|
||||
{
|
||||
mCondition.signal();
|
||||
}
|
||||
|
||||
mutable OpenThreads::Condition mCondition;
|
||||
};
|
||||
|
||||
void RenderingManager::screenshot(osg::Image *image, int w, int h)
|
||||
{
|
||||
int oldCullMask = mViewer->getCamera()->getCullMask();
|
||||
mViewer->getCamera()->setCullMask(oldCullMask & (~Mask_GUI));
|
||||
|
||||
osg::ref_ptr<osg::Camera> rttCamera (new osg::Camera);
|
||||
rttCamera->setNodeMask(Mask_RenderToTexture);
|
||||
rttCamera->attach(osg::Camera::COLOR_BUFFER, image);
|
||||
rttCamera->setRenderOrder(osg::Camera::PRE_RENDER);
|
||||
rttCamera->setReferenceFrame(osg::Camera::ABSOLUTE_RF);
|
||||
rttCamera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT, osg::Camera::PIXEL_BUFFER_RTT);
|
||||
rttCamera->setClearColor(mViewer->getCamera()->getClearColor());
|
||||
rttCamera->setClearMask(mViewer->getCamera()->getClearMask());
|
||||
rttCamera->setProjectionMatrixAsPerspective(mFieldOfView, w/float(h), mNearClip, mViewDistance);
|
||||
rttCamera->setViewMatrix(mViewer->getCamera()->getViewMatrix());
|
||||
rttCamera->setViewport(0, 0, w, h);
|
||||
rttCamera->setGraphicsContext(mViewer->getCamera()->getGraphicsContext());
|
||||
|
||||
osg::ref_ptr<osg::Texture2D> texture (new osg::Texture2D);
|
||||
texture->setInternalFormat(GL_RGB);
|
||||
texture->setTextureSize(w, h);
|
||||
texture->setResizeNonPowerOfTwoHint(false);
|
||||
rttCamera->attach(osg::Camera::COLOR_BUFFER, texture);
|
||||
|
||||
image->setDataType(GL_UNSIGNED_BYTE);
|
||||
image->setPixelFormat(texture->getInternalFormat());
|
||||
|
||||
rttCamera->addChild(mLightRoot);
|
||||
|
||||
mRootNode->addChild(rttCamera);
|
||||
|
||||
mViewer->frame();
|
||||
|
||||
// The draw needs to complete before we can copy back our image.
|
||||
osg::ref_ptr<NotifyDrawCompletedCallback> callback (new NotifyDrawCompletedCallback);
|
||||
rttCamera->setFinalDrawCallback(callback);
|
||||
OpenThreads::Mutex m;
|
||||
m.lock();
|
||||
callback->mCondition.wait(&m);
|
||||
m.unlock();
|
||||
|
||||
rttCamera->removeChildren(0, rttCamera->getNumChildren());
|
||||
rttCamera->setGraphicsContext(NULL);
|
||||
mRootNode->removeChild(rttCamera);
|
||||
|
||||
mViewer->getCamera()->setCullMask(oldCullMask);
|
||||
}
|
||||
|
||||
void RenderingManager::getCameraToViewportRay(float nX, float nY, osg::Vec3f &origin, osg::Vec3f &dest)
|
||||
{
|
||||
osg::Matrix viewProj = mViewer->getCamera()->getViewMatrix() * mViewer->getCamera()->getProjectionMatrix();
|
||||
|
|
|
@ -82,6 +82,9 @@ namespace MWRender
|
|||
void setWaterEnabled(bool enabled);
|
||||
void setWaterHeight(float level);
|
||||
|
||||
/// Take a screenshot of w*h onto the given image, not including the GUI.
|
||||
void screenshot(osg::Image* image, int w, int h);
|
||||
|
||||
/// Return the object under the mouse cursor / crosshair position, given by nX and nY normalized screen coordinates,
|
||||
/// where (0,0) is the top left corner.
|
||||
MWWorld::Ptr getFacedObject(const float nX, const float nY, float maxDistance, bool ignorePlayer);
|
||||
|
|
|
@ -10,7 +10,9 @@
|
|||
|
||||
#include <components/settings/settings.hpp>
|
||||
|
||||
#include <OgreImage.h>
|
||||
#include <osg/Image>
|
||||
|
||||
#include <osgDB/Registry>
|
||||
|
||||
#include <boost/filesystem/fstream.hpp>
|
||||
#include <boost/filesystem/operations.hpp>
|
||||
|
@ -179,14 +181,7 @@ void MWState::StateManager::saveGame (const std::string& description, const Slot
|
|||
profile.mTimePlayed = mTimePlayed;
|
||||
profile.mDescription = description;
|
||||
|
||||
/*
|
||||
int screenshotW = 259*2, screenshotH = 133*2; // *2 to get some nice antialiasing
|
||||
Ogre::Image screenshot;
|
||||
world.screenshot(screenshot, screenshotW, screenshotH);
|
||||
Ogre::DataStreamPtr encoded = screenshot.encode("jpg");
|
||||
profile.mScreenshot.resize(encoded->size());
|
||||
encoded->read(&profile.mScreenshot[0], encoded->size());
|
||||
*/
|
||||
writeScreenshot(profile.mScreenshot);
|
||||
|
||||
if (!slot)
|
||||
slot = getCurrentCharacter()->createSlot (profile);
|
||||
|
@ -572,3 +567,31 @@ bool MWState::StateManager::verifyProfile(const ESM::SavedGame& profile) const
|
|||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void MWState::StateManager::writeScreenshot(std::vector<char> &imageData) const
|
||||
{
|
||||
int screenshotW = 259*2, screenshotH = 133*2; // *2 to get some nice antialiasing
|
||||
|
||||
osg::ref_ptr<osg::Image> screenshot (new osg::Image);
|
||||
|
||||
MWBase::Environment::get().getWorld()->screenshot(screenshot.get(), screenshotW, screenshotH);
|
||||
|
||||
osgDB::ReaderWriter* readerwriter = osgDB::Registry::instance()->getReaderWriterForExtension("jpg");
|
||||
if (!readerwriter)
|
||||
{
|
||||
std::cerr << "Unable to write screenshot, can't find a jpg ReaderWriter" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
std::ostringstream ostream;
|
||||
osgDB::ReaderWriter::WriteResult result = readerwriter->writeImage(*screenshot, ostream);
|
||||
if (!result.success())
|
||||
{
|
||||
std::cerr << "Unable to write screenshot: " << result.message() << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
std::string data = ostream.str();
|
||||
imageData = std::vector<char>(data.begin(), data.end());
|
||||
|
||||
}
|
||||
|
|
|
@ -25,6 +25,8 @@ namespace MWState
|
|||
|
||||
bool verifyProfile (const ESM::SavedGame& profile) const;
|
||||
|
||||
void writeScreenshot (std::vector<char>& imageData) const;
|
||||
|
||||
std::map<int, int> buildContentFileIndexMap (const ESM::ESMReader& reader) const;
|
||||
|
||||
public:
|
||||
|
|
|
@ -2128,9 +2128,9 @@ namespace MWWorld
|
|||
return mRendering->getAnimation(ptr);
|
||||
}
|
||||
|
||||
void World::screenshot(Ogre::Image &image, int w, int h)
|
||||
void World::screenshot(osg::Image* image, int w, int h)
|
||||
{
|
||||
//mRendering->screenshot(image, w, h);
|
||||
mRendering->screenshot(image, w, h);
|
||||
}
|
||||
|
||||
void World::activateDoor(const MWWorld::Ptr& door)
|
||||
|
|
|
@ -524,7 +524,7 @@ namespace MWWorld
|
|||
virtual void reattachPlayerCamera();
|
||||
|
||||
/// \todo this does not belong here
|
||||
virtual void screenshot (Ogre::Image& image, int w, int h);
|
||||
virtual void screenshot (osg::Image* image, int w, int h);
|
||||
|
||||
/// Find center of exterior cell above land surface
|
||||
/// \return false if exterior with given name not exists, true otherwise
|
||||
|
|
Loading…
Reference in a new issue