mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-16 15:29:55 +00:00
Merge branch 'stufftheminasack' into 'master'
Drop 360-degree screenshot support (#7720) Closes #7720 See merge request OpenMW/openmw!4158
This commit is contained in:
commit
176e6490c5
29 changed files with 31 additions and 484 deletions
|
@ -252,6 +252,7 @@
|
|||
Task #7117: Replace boost::scoped_array with std::vector
|
||||
Task #7151: Do not use std::strerror to get errno error message
|
||||
Task #7394: Drop support for --fs-strict
|
||||
Task #7720: Drop 360-degree screenshot support
|
||||
|
||||
0.48.0
|
||||
------
|
||||
|
|
|
@ -812,8 +812,8 @@ void OMW::Engine::prepareEngine()
|
|||
Version::getOpenmwVersionDescription(), shadersSupported, mCfgMgr);
|
||||
mEnvironment.setWindowManager(*mWindowManager);
|
||||
|
||||
mInputManager = std::make_unique<MWInput::InputManager>(mWindow, mViewer, mScreenCaptureHandler,
|
||||
mScreenCaptureOperation, keybinderUser, keybinderUserExists, userGameControllerdb, gameControllerdb, mGrab);
|
||||
mInputManager = std::make_unique<MWInput::InputManager>(mWindow, mViewer, mScreenCaptureHandler, keybinderUser,
|
||||
keybinderUserExists, userGameControllerdb, gameControllerdb, mGrab);
|
||||
mEnvironment.setInputManager(*mInputManager);
|
||||
|
||||
// Create sound system
|
||||
|
|
|
@ -425,7 +425,6 @@ namespace MWBase
|
|||
|
||||
/// \todo this does not belong here
|
||||
virtual void screenshot(osg::Image* image, int w, int h) = 0;
|
||||
virtual bool screenshot360(osg::Image* image) = 0;
|
||||
|
||||
/// Find default position inside exterior cell specified by name
|
||||
/// \return empty RefId if exterior with given name not exists, the cell's RefId otherwise
|
||||
|
|
|
@ -39,7 +39,6 @@ namespace MWGui
|
|||
, mLastRenderTime(0.0)
|
||||
, mLoadingOnTime(0.0)
|
||||
, mImportantLabel(false)
|
||||
, mVisible(false)
|
||||
, mNestedLoadingCount(0)
|
||||
, mProgress(0)
|
||||
, mShowWallpaper(true)
|
||||
|
@ -142,7 +141,7 @@ namespace MWGui
|
|||
osg::BoundingSphere computeBound(const osg::Node&) const override { return osg::BoundingSphere(); }
|
||||
};
|
||||
|
||||
void LoadingScreen::loadingOn(bool visible)
|
||||
void LoadingScreen::loadingOn()
|
||||
{
|
||||
// Early-out if already on
|
||||
if (mNestedLoadingCount++ > 0 && mMainWidget->getVisible())
|
||||
|
@ -161,17 +160,8 @@ namespace MWGui
|
|||
mOldIcoMax = ico->getMaximumNumOfObjectsToCompilePerFrame();
|
||||
}
|
||||
|
||||
mVisible = visible;
|
||||
mLoadingBox->setVisible(mVisible);
|
||||
setVisible(true);
|
||||
|
||||
if (!mVisible)
|
||||
{
|
||||
mShowWallpaper = false;
|
||||
draw();
|
||||
return;
|
||||
}
|
||||
|
||||
mShowWallpaper = MWBase::Environment::get().getStateManager()->getState() == MWBase::StateManager::State_NoGame;
|
||||
|
||||
if (mShowWallpaper)
|
||||
|
@ -186,7 +176,6 @@ namespace MWGui
|
|||
{
|
||||
if (--mNestedLoadingCount > 0)
|
||||
return;
|
||||
mLoadingBox->setVisible(true); // restore
|
||||
|
||||
if (mLastRenderTime < mLoadingOnTime)
|
||||
{
|
||||
|
@ -327,7 +316,7 @@ namespace MWGui
|
|||
|
||||
void LoadingScreen::draw()
|
||||
{
|
||||
if (mVisible && !needToDrawLoadingScreen())
|
||||
if (!needToDrawLoadingScreen())
|
||||
return;
|
||||
|
||||
if (mShowWallpaper && mTimer.time_m() > mLastWallpaperChangeTime + 5000 * 1)
|
||||
|
|
|
@ -38,7 +38,7 @@ namespace MWGui
|
|||
|
||||
/// Overridden from Loading::Listener, see the Loading::Listener documentation for usage details
|
||||
void setLabel(const std::string& label, bool important) override;
|
||||
void loadingOn(bool visible = true) override;
|
||||
void loadingOn() override;
|
||||
void loadingOff() override;
|
||||
void setProgressRange(size_t range) override;
|
||||
void setProgress(size_t value) override;
|
||||
|
@ -66,7 +66,6 @@ namespace MWGui
|
|||
|
||||
bool mImportantLabel;
|
||||
|
||||
bool mVisible;
|
||||
int mNestedLoadingCount;
|
||||
|
||||
size_t mProgress;
|
||||
|
|
|
@ -27,13 +27,11 @@
|
|||
namespace MWInput
|
||||
{
|
||||
|
||||
ActionManager::ActionManager(BindingsManager* bindingsManager,
|
||||
osgViewer::ScreenCaptureHandler::CaptureOperation* screenCaptureOperation,
|
||||
osg::ref_ptr<osgViewer::Viewer> viewer, osg::ref_ptr<osgViewer::ScreenCaptureHandler> screenCaptureHandler)
|
||||
ActionManager::ActionManager(BindingsManager* bindingsManager, osg::ref_ptr<osgViewer::Viewer> viewer,
|
||||
osg::ref_ptr<osgViewer::ScreenCaptureHandler> screenCaptureHandler)
|
||||
: mBindingsManager(bindingsManager)
|
||||
, mViewer(std::move(viewer))
|
||||
, mScreenCaptureHandler(std::move(screenCaptureHandler))
|
||||
, mScreenCaptureOperation(screenCaptureOperation)
|
||||
, mTimeIdle(0.f)
|
||||
{
|
||||
}
|
||||
|
@ -169,25 +167,10 @@ namespace MWInput
|
|||
}
|
||||
|
||||
void ActionManager::screenshot()
|
||||
{
|
||||
const Settings::ScreenshotSettings& settings = Settings::video().mScreenshotType;
|
||||
|
||||
if (settings.mType == Settings::ScreenshotType::Regular)
|
||||
{
|
||||
mScreenCaptureHandler->setFramesToCapture(1);
|
||||
mScreenCaptureHandler->captureNextFrame(*mViewer);
|
||||
}
|
||||
else
|
||||
{
|
||||
osg::ref_ptr<osg::Image> screenshot(new osg::Image);
|
||||
|
||||
if (MWBase::Environment::get().getWorld()->screenshot360(screenshot.get()))
|
||||
{
|
||||
(*mScreenCaptureOperation)(*(screenshot.get()), 0);
|
||||
// FIXME: mScreenCaptureHandler->getCaptureOperation() causes crash for some reason
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ActionManager::toggleMainMenu()
|
||||
{
|
||||
|
|
|
@ -17,9 +17,8 @@ namespace MWInput
|
|||
class ActionManager
|
||||
{
|
||||
public:
|
||||
ActionManager(BindingsManager* bindingsManager,
|
||||
osgViewer::ScreenCaptureHandler::CaptureOperation* screenCaptureOperation,
|
||||
osg::ref_ptr<osgViewer::Viewer> viewer, osg::ref_ptr<osgViewer::ScreenCaptureHandler> screenCaptureHandler);
|
||||
ActionManager(BindingsManager* bindingsManager, osg::ref_ptr<osgViewer::Viewer> viewer,
|
||||
osg::ref_ptr<osgViewer::ScreenCaptureHandler> screenCaptureHandler);
|
||||
|
||||
void update(float dt);
|
||||
|
||||
|
@ -48,7 +47,6 @@ namespace MWInput
|
|||
BindingsManager* mBindingsManager;
|
||||
osg::ref_ptr<osgViewer::Viewer> mViewer;
|
||||
osg::ref_ptr<osgViewer::ScreenCaptureHandler> mScreenCaptureHandler;
|
||||
osgViewer::ScreenCaptureHandler::CaptureOperation* mScreenCaptureOperation;
|
||||
|
||||
float mTimeIdle;
|
||||
};
|
||||
|
|
|
@ -25,17 +25,14 @@
|
|||
namespace MWInput
|
||||
{
|
||||
InputManager::InputManager(SDL_Window* window, osg::ref_ptr<osgViewer::Viewer> viewer,
|
||||
osg::ref_ptr<osgViewer::ScreenCaptureHandler> screenCaptureHandler,
|
||||
osgViewer::ScreenCaptureHandler::CaptureOperation* screenCaptureOperation,
|
||||
const std::filesystem::path& userFile, bool userFileExists,
|
||||
const std::filesystem::path& userControllerBindingsFile, const std::filesystem::path& controllerBindingsFile,
|
||||
bool grab)
|
||||
osg::ref_ptr<osgViewer::ScreenCaptureHandler> screenCaptureHandler, const std::filesystem::path& userFile,
|
||||
bool userFileExists, const std::filesystem::path& userControllerBindingsFile,
|
||||
const std::filesystem::path& controllerBindingsFile, bool grab)
|
||||
: mControlsDisabled(false)
|
||||
, mInputWrapper(std::make_unique<SDLUtil::InputWrapper>(window, viewer, grab))
|
||||
, mBindingsManager(std::make_unique<BindingsManager>(userFile, userFileExists))
|
||||
, mControlSwitch(std::make_unique<ControlSwitch>())
|
||||
, mActionManager(std::make_unique<ActionManager>(
|
||||
mBindingsManager.get(), screenCaptureOperation, viewer, screenCaptureHandler))
|
||||
, mActionManager(std::make_unique<ActionManager>(mBindingsManager.get(), viewer, screenCaptureHandler))
|
||||
, mKeyboardManager(std::make_unique<KeyboardManager>(mBindingsManager.get()))
|
||||
, mMouseManager(std::make_unique<MouseManager>(mBindingsManager.get(), mInputWrapper.get(), window))
|
||||
, mControllerManager(std::make_unique<ControllerManager>(
|
||||
|
|
|
@ -49,10 +49,8 @@ namespace MWInput
|
|||
{
|
||||
public:
|
||||
InputManager(SDL_Window* window, osg::ref_ptr<osgViewer::Viewer> viewer,
|
||||
osg::ref_ptr<osgViewer::ScreenCaptureHandler> screenCaptureHandler,
|
||||
osgViewer::ScreenCaptureHandler::CaptureOperation* screenCaptureOperation,
|
||||
const std::filesystem::path& userFile, bool userFileExists,
|
||||
const std::filesystem::path& userControllerBindingsFile,
|
||||
osg::ref_ptr<osgViewer::ScreenCaptureHandler> screenCaptureHandler, const std::filesystem::path& userFile,
|
||||
bool userFileExists, const std::filesystem::path& userControllerBindingsFile,
|
||||
const std::filesystem::path& controllerBindingsFile, bool grab);
|
||||
|
||||
~InputManager() final;
|
||||
|
|
|
@ -521,8 +521,7 @@ namespace MWRender
|
|||
|
||||
mCamera = std::make_unique<Camera>(mViewer->getCamera());
|
||||
|
||||
mScreenshotManager
|
||||
= std::make_unique<ScreenshotManager>(viewer, mRootNode, sceneRoot, mResourceSystem, mWater.get());
|
||||
mScreenshotManager = std::make_unique<ScreenshotManager>(viewer);
|
||||
|
||||
mViewer->setLightingMode(osgViewer::View::NO_LIGHT);
|
||||
|
||||
|
@ -1019,19 +1018,6 @@ namespace MWRender
|
|||
mScreenshotManager->screenshot(image, w, h);
|
||||
}
|
||||
|
||||
bool RenderingManager::screenshot360(osg::Image* image)
|
||||
{
|
||||
if (mCamera->isVanityOrPreviewModeEnabled())
|
||||
{
|
||||
Log(Debug::Warning) << "Spherical screenshots are not allowed in preview mode.";
|
||||
return false;
|
||||
}
|
||||
|
||||
mScreenshotManager->screenshot360(image);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
osg::Vec4f RenderingManager::getScreenBounds(const osg::BoundingBox& worldbb)
|
||||
{
|
||||
if (!worldbb.valid())
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
|
||||
#include <span>
|
||||
|
||||
#include <osg/Camera>
|
||||
#include <osg/Light>
|
||||
#include <osg/ref_ptr>
|
||||
|
||||
|
@ -168,7 +167,6 @@ namespace MWRender
|
|||
|
||||
/// Take a screenshot of w*h onto the given image, not including the GUI.
|
||||
void screenshot(osg::Image* image, int w, int h);
|
||||
bool screenshot360(osg::Image* image);
|
||||
|
||||
struct RayResult
|
||||
{
|
||||
|
|
|
@ -3,40 +3,16 @@
|
|||
#include <condition_variable>
|
||||
#include <mutex>
|
||||
|
||||
#include <osg/ImageUtils>
|
||||
#include <osg/ShapeDrawable>
|
||||
#include <osg/Texture2D>
|
||||
#include <osg/TextureCubeMap>
|
||||
|
||||
#include <components/loadinglistener/loadinglistener.hpp>
|
||||
#include <components/misc/strings/algorithm.hpp>
|
||||
#include <components/misc/strings/conversion.hpp>
|
||||
#include <components/resource/resourcesystem.hpp>
|
||||
#include <components/resource/scenemanager.hpp>
|
||||
#include <components/sceneutil/depth.hpp>
|
||||
#include <components/settings/values.hpp>
|
||||
#include <components/shader/shadermanager.hpp>
|
||||
#include <components/stereo/multiview.hpp>
|
||||
#include <components/stereo/stereomanager.hpp>
|
||||
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwbase/windowmanager.hpp"
|
||||
#include "../mwbase/world.hpp"
|
||||
|
||||
#include "postprocessor.hpp"
|
||||
#include "util.hpp"
|
||||
#include "vismask.hpp"
|
||||
#include "water.hpp"
|
||||
|
||||
namespace MWRender
|
||||
{
|
||||
enum class Screenshot360Type
|
||||
{
|
||||
Spherical,
|
||||
Cylindrical,
|
||||
Planet,
|
||||
RawCubemap
|
||||
};
|
||||
|
||||
class NotifyDrawCompletedCallback : public osg::Camera::DrawCallback
|
||||
{
|
||||
|
@ -113,14 +89,9 @@ namespace MWRender
|
|||
osg::ref_ptr<osg::Image> mImage;
|
||||
};
|
||||
|
||||
ScreenshotManager::ScreenshotManager(osgViewer::Viewer* viewer, osg::ref_ptr<osg::Group> rootNode,
|
||||
osg::ref_ptr<osg::Group> sceneRoot, Resource::ResourceSystem* resourceSystem, Water* water)
|
||||
ScreenshotManager::ScreenshotManager(osgViewer::Viewer* viewer)
|
||||
: mViewer(viewer)
|
||||
, mRootNode(std::move(rootNode))
|
||||
, mSceneRoot(std::move(sceneRoot))
|
||||
, mDrawCompleteCallback(new NotifyDrawCompletedCallback)
|
||||
, mResourceSystem(resourceSystem)
|
||||
, mWater(water)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -135,204 +106,18 @@ namespace MWRender
|
|||
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);
|
||||
traversalsAndWait(mViewer->getFrameStamp()->getFrameNumber());
|
||||
|
||||
// Ref https://gitlab.com/OpenMW/openmw/-/issues/6013
|
||||
mDrawCompleteCallback->reset(mViewer->getFrameStamp()->getFrameNumber());
|
||||
mViewer->getCamera()->setFinalDrawCallback(mDrawCompleteCallback);
|
||||
mViewer->eventTraversal();
|
||||
mViewer->updateTraversal();
|
||||
mViewer->renderingTraversals();
|
||||
mDrawCompleteCallback->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
|
||||
mViewer->advance(mViewer->getFrameStamp()->getSimulationTime());
|
||||
camera->removeChild(tempDrw);
|
||||
}
|
||||
|
||||
bool ScreenshotManager::screenshot360(osg::Image* image)
|
||||
{
|
||||
const Settings::ScreenshotSettings& settings = Settings::video().mScreenshotType;
|
||||
|
||||
Screenshot360Type screenshotMapping = Screenshot360Type::Spherical;
|
||||
|
||||
switch (settings.mType)
|
||||
{
|
||||
case Settings::ScreenshotType::Regular:
|
||||
Log(Debug::Warning) << "Wrong screenshot 360 type: regular.";
|
||||
return false;
|
||||
case Settings::ScreenshotType::Cylindrical:
|
||||
screenshotMapping = Screenshot360Type::Cylindrical;
|
||||
break;
|
||||
case Settings::ScreenshotType::Spherical:
|
||||
screenshotMapping = Screenshot360Type::Spherical;
|
||||
break;
|
||||
case Settings::ScreenshotType::Planet:
|
||||
screenshotMapping = Screenshot360Type::Planet;
|
||||
break;
|
||||
case Settings::ScreenshotType::Cubemap:
|
||||
screenshotMapping = Screenshot360Type::RawCubemap;
|
||||
break;
|
||||
}
|
||||
|
||||
int screenshotW = mViewer->getCamera()->getViewport()->width();
|
||||
|
||||
if (settings.mWidth.has_value())
|
||||
screenshotW = *settings.mWidth;
|
||||
|
||||
int screenshotH = mViewer->getCamera()->getViewport()->height();
|
||||
|
||||
if (settings.mHeight.has_value())
|
||||
screenshotH = *settings.mHeight;
|
||||
|
||||
// planet mapping needs higher resolution
|
||||
const int cubeSize = screenshotMapping == Screenshot360Type::Planet ? screenshotW : screenshotW / 2;
|
||||
const bool rawCubemap = screenshotMapping == Screenshot360Type::RawCubemap;
|
||||
|
||||
if (rawCubemap)
|
||||
screenshotW = cubeSize * 6; // the image will consist of 6 cube sides in a row
|
||||
else if (screenshotMapping == Screenshot360Type::Planet)
|
||||
screenshotH = screenshotW; // use square resolution for planet mapping
|
||||
|
||||
std::vector<osg::ref_ptr<osg::Image>> images;
|
||||
images.reserve(6);
|
||||
|
||||
for (int i = 0; i < 6; ++i)
|
||||
images.push_back(new osg::Image);
|
||||
|
||||
osg::Vec3 directions[6]
|
||||
= { rawCubemap ? osg::Vec3(1, 0, 0) : osg::Vec3(0, 0, 1), osg::Vec3(0, 0, -1), osg::Vec3(-1, 0, 0),
|
||||
rawCubemap ? osg::Vec3(0, 0, 1) : osg::Vec3(1, 0, 0), osg::Vec3(0, 1, 0), osg::Vec3(0, -1, 0) };
|
||||
|
||||
double rotations[] = { -osg::PI / 2.0, osg::PI / 2.0, osg::PI, 0, osg::PI / 2.0, osg::PI / 2.0 };
|
||||
|
||||
for (int i = 0; i < 6; ++i) // for each cubemap side
|
||||
{
|
||||
osg::Matrixd transform = osg::Matrixd::rotate(osg::Vec3(0, 0, -1), directions[i]);
|
||||
|
||||
if (!rawCubemap)
|
||||
transform *= osg::Matrixd::rotate(rotations[i], osg::Vec3(0, 0, -1));
|
||||
|
||||
osg::Image* sideImage = images[i].get();
|
||||
makeCubemapScreenshot(sideImage, cubeSize, cubeSize, transform);
|
||||
|
||||
if (!rawCubemap)
|
||||
sideImage->flipHorizontal();
|
||||
}
|
||||
|
||||
if (rawCubemap) // for raw cubemap don't run on GPU, just merge the images
|
||||
{
|
||||
image->allocateImage(
|
||||
cubeSize * 6, cubeSize, images[0]->r(), images[0]->getPixelFormat(), images[0]->getDataType());
|
||||
|
||||
for (int i = 0; i < 6; ++i)
|
||||
osg::copyImage(images[i].get(), 0, 0, 0, images[i]->s(), images[i]->t(), images[i]->r(), image,
|
||||
i * cubeSize, 0, 0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// run on GPU now:
|
||||
osg::ref_ptr<osg::TextureCubeMap> cubeTexture(new osg::TextureCubeMap);
|
||||
cubeTexture->setResizeNonPowerOfTwoHint(false);
|
||||
|
||||
cubeTexture->setFilter(osg::Texture::MIN_FILTER, osg::Texture::NEAREST);
|
||||
cubeTexture->setFilter(osg::Texture::MAG_FILTER, osg::Texture::NEAREST);
|
||||
|
||||
cubeTexture->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE);
|
||||
cubeTexture->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE);
|
||||
|
||||
for (int i = 0; i < 6; ++i)
|
||||
cubeTexture->setImage(i, images[i].get());
|
||||
|
||||
osg::ref_ptr<osg::Camera> screenshotCamera(new osg::Camera);
|
||||
osg::ref_ptr<osg::ShapeDrawable> quad(new osg::ShapeDrawable(new osg::Box(osg::Vec3(0, 0, 0), 2.0)));
|
||||
|
||||
osg::ref_ptr<osg::StateSet> stateset = quad->getOrCreateStateSet();
|
||||
|
||||
Shader::ShaderManager& shaderMgr = mResourceSystem->getSceneManager()->getShaderManager();
|
||||
stateset->setAttributeAndModes(shaderMgr.getProgram("s360"), osg::StateAttribute::ON);
|
||||
|
||||
stateset->addUniform(new osg::Uniform("cubeMap", 0));
|
||||
stateset->addUniform(new osg::Uniform("mapping", static_cast<int>(screenshotMapping)));
|
||||
stateset->setTextureAttributeAndModes(0, cubeTexture, osg::StateAttribute::ON);
|
||||
|
||||
screenshotCamera->addChild(quad);
|
||||
|
||||
renderCameraToImage(screenshotCamera, image, screenshotW, screenshotH);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ScreenshotManager::traversalsAndWait(unsigned int frame)
|
||||
{
|
||||
// Ref https://gitlab.com/OpenMW/openmw/-/issues/6013
|
||||
mDrawCompleteCallback->reset(frame);
|
||||
mViewer->getCamera()->setFinalDrawCallback(mDrawCompleteCallback);
|
||||
|
||||
mViewer->eventTraversal();
|
||||
mViewer->updateTraversal();
|
||||
mViewer->renderingTraversals();
|
||||
mDrawCompleteCallback->waitTillDone();
|
||||
}
|
||||
|
||||
void ScreenshotManager::renderCameraToImage(osg::Camera* camera, osg::Image* image, int w, int h)
|
||||
{
|
||||
camera->setNodeMask(Mask_RenderToTexture);
|
||||
camera->attach(osg::Camera::COLOR_BUFFER, image);
|
||||
camera->setRenderOrder(osg::Camera::PRE_RENDER);
|
||||
camera->setReferenceFrame(osg::Camera::ABSOLUTE_RF);
|
||||
camera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT, osg::Camera::PIXEL_BUFFER_RTT);
|
||||
camera->setViewport(0, 0, w, h);
|
||||
|
||||
SceneUtil::setCameraClearDepth(camera);
|
||||
|
||||
osg::ref_ptr<osg::Texture2D> texture(new osg::Texture2D);
|
||||
texture->setInternalFormat(GL_RGB);
|
||||
texture->setTextureSize(w, h);
|
||||
texture->setResizeNonPowerOfTwoHint(false);
|
||||
texture->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR);
|
||||
texture->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);
|
||||
texture->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE);
|
||||
texture->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE);
|
||||
camera->attach(osg::Camera::COLOR_BUFFER, texture);
|
||||
|
||||
image->setDataType(GL_UNSIGNED_BYTE);
|
||||
image->setPixelFormat(texture->getInternalFormat());
|
||||
|
||||
mRootNode->addChild(camera);
|
||||
|
||||
MWBase::Environment::get().getWindowManager()->getLoadingScreen()->loadingOn(false);
|
||||
|
||||
// The draw needs to complete before we can copy back our image.
|
||||
traversalsAndWait(0);
|
||||
|
||||
MWBase::Environment::get().getWindowManager()->getLoadingScreen()->loadingOff();
|
||||
|
||||
// now that we've "used up" the current frame, get a fresh framenumber for the next frame() following after the
|
||||
// screenshot is completed
|
||||
mViewer->advance(mViewer->getFrameStamp()->getSimulationTime());
|
||||
|
||||
camera->removeChildren(0, camera->getNumChildren());
|
||||
mRootNode->removeChild(camera);
|
||||
}
|
||||
|
||||
void ScreenshotManager::makeCubemapScreenshot(osg::Image* image, int w, int h, const osg::Matrixd& cameraTransform)
|
||||
{
|
||||
osg::ref_ptr<osg::Camera> rttCamera(new osg::Camera);
|
||||
const float nearClip = Settings::camera().mNearClip;
|
||||
const float viewDistance = Settings::camera().mViewingDistance;
|
||||
// each cubemap side sees 90 degrees
|
||||
if (SceneUtil::AutoDepth::isReversed())
|
||||
rttCamera->setProjectionMatrix(
|
||||
SceneUtil::getReversedZProjectionMatrixAsPerspectiveInf(90.0, w / float(h), nearClip));
|
||||
else
|
||||
rttCamera->setProjectionMatrixAsPerspective(90.0, w / float(h), nearClip, viewDistance);
|
||||
rttCamera->setViewMatrix(mViewer->getCamera()->getViewMatrix() * cameraTransform);
|
||||
|
||||
rttCamera->setUpdateCallback(new NoTraverseCallback);
|
||||
rttCamera->addChild(mSceneRoot);
|
||||
|
||||
rttCamera->addChild(mWater->getReflectionNode());
|
||||
rttCamera->addChild(mWater->getRefractionNode());
|
||||
|
||||
rttCamera->setCullMask(
|
||||
MWBase::Environment::get().getWindowManager()->getCullMask() & ~(Mask_GUI | Mask_FirstPerson));
|
||||
|
||||
rttCamera->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||
|
||||
renderCameraToImage(rttCamera.get(), image, w, h);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,45 +1,25 @@
|
|||
#ifndef MWRENDER_SCREENSHOTMANAGER_H
|
||||
#define MWRENDER_SCREENSHOTMANAGER_H
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <osg/Group>
|
||||
#include <osg/ref_ptr>
|
||||
|
||||
#include <osgViewer/Viewer>
|
||||
|
||||
namespace Resource
|
||||
{
|
||||
class ResourceSystem;
|
||||
}
|
||||
|
||||
namespace MWRender
|
||||
{
|
||||
class Water;
|
||||
class NotifyDrawCompletedCallback;
|
||||
|
||||
class ScreenshotManager
|
||||
{
|
||||
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);
|
||||
~ScreenshotManager();
|
||||
|
||||
void screenshot(osg::Image* image, int w, int h);
|
||||
bool screenshot360(osg::Image* image);
|
||||
|
||||
private:
|
||||
osg::ref_ptr<osgViewer::Viewer> mViewer;
|
||||
osg::ref_ptr<osg::Group> mRootNode;
|
||||
osg::ref_ptr<osg::Group> mSceneRoot;
|
||||
osg::ref_ptr<NotifyDrawCompletedCallback> mDrawCompleteCallback;
|
||||
Resource::ResourceSystem* mResourceSystem;
|
||||
Water* mWater;
|
||||
|
||||
void traversalsAndWait(unsigned int frame);
|
||||
void renderCameraToImage(osg::Camera* camera, osg::Image* image, int w, int h);
|
||||
void makeCubemapScreenshot(
|
||||
osg::Image* image, int w, int h, const osg::Matrixd& cameraTransform = osg::Matrixd());
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -568,16 +568,6 @@ namespace MWRender
|
|||
updateVisible();
|
||||
}
|
||||
|
||||
osg::Node* Water::getReflectionNode()
|
||||
{
|
||||
return mReflection;
|
||||
}
|
||||
|
||||
osg::Node* Water::getRefractionNode()
|
||||
{
|
||||
return mRefraction;
|
||||
}
|
||||
|
||||
osg::Vec3d Water::getPosition() const
|
||||
{
|
||||
return mWaterNode->getPosition();
|
||||
|
|
|
@ -117,9 +117,6 @@ namespace MWRender
|
|||
|
||||
void update(float dt, bool paused);
|
||||
|
||||
osg::Node* getReflectionNode();
|
||||
osg::Node* getRefractionNode();
|
||||
|
||||
osg::Vec3d getPosition() const;
|
||||
|
||||
void processChangedSettings(const Settings::CategorySettingVector& settings);
|
||||
|
|
|
@ -2385,11 +2385,6 @@ namespace MWWorld
|
|||
mRendering->screenshot(image, w, h);
|
||||
}
|
||||
|
||||
bool World::screenshot360(osg::Image* image)
|
||||
{
|
||||
return mRendering->screenshot360(image);
|
||||
}
|
||||
|
||||
void World::activateDoor(const MWWorld::Ptr& door)
|
||||
{
|
||||
auto state = door.getClass().getDoorState(door);
|
||||
|
|
|
@ -517,7 +517,6 @@ namespace MWWorld
|
|||
|
||||
/// \todo this does not belong here
|
||||
void screenshot(osg::Image* image, int w, int h) override;
|
||||
bool screenshot360(osg::Image* image) override;
|
||||
|
||||
/// Find center of exterior cell above land surface
|
||||
/// \return false if exterior with given name not exists, true otherwise
|
||||
|
|
|
@ -103,7 +103,6 @@ add_component_dir (settings
|
|||
settingvalue
|
||||
shadermanager
|
||||
values
|
||||
screenshotsettings
|
||||
windowmode
|
||||
)
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ namespace Loading
|
|||
/// periodically.
|
||||
/// @note It is best to use the ScopedLoad object instead of using loadingOn()/loadingOff() directly,
|
||||
/// so that the loading is exception safe.
|
||||
virtual void loadingOn(bool visible = true) {}
|
||||
virtual void loadingOn() {}
|
||||
virtual void loadingOff() {}
|
||||
|
||||
/// Set the total range of progress (e.g. the number of objects to load).
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
|
||||
#include <components/sdlutil/vsyncmode.hpp>
|
||||
#include <components/settings/sanitizerimpl.hpp>
|
||||
#include <components/settings/screenshotsettings.hpp>
|
||||
#include <components/settings/settingvalue.hpp>
|
||||
#include <components/settings/windowmode.hpp>
|
||||
|
||||
|
@ -32,7 +31,6 @@ namespace Settings
|
|||
SettingValue<float> mFramerateLimit{ mIndex, "Video", "framerate limit", makeMaxSanitizerFloat(0) };
|
||||
SettingValue<float> mContrast{ mIndex, "Video", "contrast", makeMaxStrictSanitizerFloat(0) };
|
||||
SettingValue<float> mGamma{ mIndex, "Video", "gamma", makeMaxStrictSanitizerFloat(0) };
|
||||
SettingValue<ScreenshotSettings> mScreenshotType{ mIndex, "Video", "screenshot type" };
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
#ifndef OPENMW_COMPONENTS_SETTINGS_SCREENSHOTSETTINGS_H
|
||||
#define OPENMW_COMPONENTS_SETTINGS_SCREENSHOTSETTINGS_H
|
||||
|
||||
#include <optional>
|
||||
#include <ostream>
|
||||
|
||||
namespace Settings
|
||||
{
|
||||
enum class ScreenshotType
|
||||
{
|
||||
Regular,
|
||||
Cylindrical,
|
||||
Spherical,
|
||||
Planet,
|
||||
Cubemap,
|
||||
};
|
||||
|
||||
struct ScreenshotSettings
|
||||
{
|
||||
ScreenshotType mType;
|
||||
std::optional<int> mWidth;
|
||||
std::optional<int> mHeight;
|
||||
std::optional<int> mCubeSize;
|
||||
|
||||
auto operator<=>(const ScreenshotSettings& value) const = default;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -119,23 +119,6 @@ namespace Settings
|
|||
Log(Debug::Warning) << "Invalid HRTF mode value: " << static_cast<int>(value) << ", fallback to auto (-1)";
|
||||
return -1;
|
||||
}
|
||||
|
||||
ScreenshotType parseScreenshotType(std::string_view value)
|
||||
{
|
||||
if (value == "regular")
|
||||
return ScreenshotType::Regular;
|
||||
if (value == "spherical")
|
||||
return ScreenshotType::Spherical;
|
||||
if (value == "cylindrical")
|
||||
return ScreenshotType::Cylindrical;
|
||||
if (value == "planet")
|
||||
return ScreenshotType::Planet;
|
||||
if (value == "cubemap")
|
||||
return ScreenshotType::Cubemap;
|
||||
|
||||
Log(Debug::Warning) << "Invalid screenshot type: " << value << ", fallback to regular";
|
||||
return ScreenshotType::Regular;
|
||||
}
|
||||
}
|
||||
|
||||
CategorySettingValueMap Manager::mDefaultSettings = CategorySettingValueMap();
|
||||
|
@ -576,28 +559,4 @@ namespace Settings
|
|||
Log(Debug::Warning) << "Unknown lighting method '" << value << "', returning fallback '" << fallback << "'";
|
||||
return SceneUtil::LightingMethod::PerObjectUniform;
|
||||
}
|
||||
|
||||
ScreenshotSettings parseScreenshotSettings(std::string_view value)
|
||||
{
|
||||
std::vector<std::string_view> settingArgs;
|
||||
Misc::StringUtils::split(value, settingArgs);
|
||||
|
||||
ScreenshotSettings result;
|
||||
|
||||
if (settingArgs.size() > 0)
|
||||
result.mType = parseScreenshotType(settingArgs[0]);
|
||||
else
|
||||
result.mType = ScreenshotType::Regular;
|
||||
|
||||
if (settingArgs.size() > 1)
|
||||
result.mWidth = std::min(10000, Misc::StringUtils::toNumeric<int>(settingArgs[1], 0));
|
||||
|
||||
if (settingArgs.size() > 2)
|
||||
result.mHeight = std::min(10000, Misc::StringUtils::toNumeric<int>(settingArgs[2], 0));
|
||||
|
||||
if (settingArgs.size() > 3)
|
||||
result.mCubeSize = std::min(5000, Misc::StringUtils::toNumeric<int>(settingArgs[3], 0));
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
#include "gyroscopeaxis.hpp"
|
||||
#include "hrtfmode.hpp"
|
||||
#include "navmeshrendermode.hpp"
|
||||
#include "screenshotsettings.hpp"
|
||||
#include "windowmode.hpp"
|
||||
|
||||
#include <components/detournavigator/collisionshapetype.hpp>
|
||||
|
@ -264,14 +263,6 @@ namespace Settings
|
|||
return SDLUtil::VSyncMode::Disabled;
|
||||
return static_cast<SDLUtil::VSyncMode>(value);
|
||||
}
|
||||
|
||||
ScreenshotSettings parseScreenshotSettings(std::string_view value);
|
||||
|
||||
template <>
|
||||
inline ScreenshotSettings Manager::getImpl<ScreenshotSettings>(std::string_view setting, std::string_view category)
|
||||
{
|
||||
return parseScreenshotSettings(getString(setting, category));
|
||||
}
|
||||
}
|
||||
|
||||
#endif // COMPONENTS_SETTINGS_H
|
||||
|
|
|
@ -44,7 +44,6 @@ namespace Settings
|
|||
HrtfMode,
|
||||
WindowMode,
|
||||
VSyncMode,
|
||||
ScreenshotSettings,
|
||||
};
|
||||
|
||||
template <class T>
|
||||
|
@ -176,12 +175,6 @@ namespace Settings
|
|||
return SettingValueType::VSyncMode;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline constexpr SettingValueType getSettingValueType<ScreenshotSettings>()
|
||||
{
|
||||
return SettingValueType::ScreenshotSettings;
|
||||
}
|
||||
|
||||
inline constexpr std::string_view getSettingValueTypeName(SettingValueType type)
|
||||
{
|
||||
switch (type)
|
||||
|
@ -228,8 +221,6 @@ namespace Settings
|
|||
return "window mode";
|
||||
case SettingValueType::VSyncMode:
|
||||
return "vsync mode";
|
||||
case SettingValueType::ScreenshotSettings:
|
||||
return "screenshot settings";
|
||||
}
|
||||
return "unsupported";
|
||||
}
|
||||
|
@ -397,17 +388,6 @@ namespace Settings
|
|||
}
|
||||
return stream;
|
||||
}
|
||||
else if constexpr (std::is_same_v<T, ScreenshotSettings>)
|
||||
{
|
||||
stream << "ScreenshotSettings{ .mType = " << static_cast<int>(value.mValue.mType);
|
||||
if (value.mValue.mWidth.has_value())
|
||||
stream << ", .mWidth = " << *value.mValue.mWidth;
|
||||
if (value.mValue.mHeight.has_value())
|
||||
stream << ", .mHeight = " << *value.mValue.mHeight;
|
||||
if (value.mValue.mCubeSize.has_value())
|
||||
stream << ", .mCubeSize = " << *value.mValue.mCubeSize;
|
||||
return stream << " }";
|
||||
}
|
||||
else
|
||||
return stream << value.mValue;
|
||||
}
|
||||
|
|
|
@ -194,12 +194,3 @@ Gamma is an exponent that makes colors brighter if greater than 1.0 and darker i
|
|||
This setting can be changed in the Detail tab of the Video panel of the Options menu.
|
||||
It has been reported to not work on some Linux systems,
|
||||
and therefore the in-game setting in the Options menu has been disabled on Linux systems.
|
||||
|
||||
screenshot type
|
||||
---------------
|
||||
|
||||
:Type: screenshot settings
|
||||
:Default: regular
|
||||
|
||||
Type of screenshot to take (regular, cylindrical, spherical, planet or cubemap), optionally followed by
|
||||
screenshot width, height and cubemap resolution in pixels (e.g. spherical 1600 1000 1200).
|
||||
|
|
|
@ -652,10 +652,6 @@ contrast = 1.0
|
|||
# Video gamma setting. (>0.0). No effect in Linux.
|
||||
gamma = 1.0
|
||||
|
||||
# Type of screenshot to take (regular, cylindrical, spherical, planet or cubemap), optionally followed by
|
||||
# screenshot width, height and cubemap resolution in pixels. (e.g. spherical 1600 1000 1200)
|
||||
screenshot type = regular
|
||||
|
||||
[Water]
|
||||
|
||||
# Enable water shader with reflections and optionally refraction.
|
||||
|
|
|
@ -39,8 +39,6 @@ set(SHADER_FILES
|
|||
compatibility/objects.frag
|
||||
compatibility/terrain.vert
|
||||
compatibility/terrain.frag
|
||||
compatibility/s360.frag
|
||||
compatibility/s360.vert
|
||||
compatibility/shadows_vertex.glsl
|
||||
compatibility/shadows_fragment.glsl
|
||||
compatibility/shadowcasting.vert
|
||||
|
|
|
@ -1,21 +0,0 @@
|
|||
#version 120
|
||||
|
||||
varying vec2 uv;
|
||||
uniform samplerCube cubeMap;
|
||||
uniform int mapping;
|
||||
|
||||
#include "lib/util/coordinates.glsl"
|
||||
|
||||
void main(void)
|
||||
{
|
||||
vec3 c;
|
||||
|
||||
if (mapping == 0)
|
||||
c = sphericalCoords(uv);
|
||||
else if (mapping == 1)
|
||||
c = cylindricalCoords(uv);
|
||||
else
|
||||
c = planetCoords(uv);
|
||||
|
||||
gl_FragData[0] = textureCube(cubeMap,c);
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
#version 120
|
||||
|
||||
varying vec2 uv;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
gl_Position = gl_Vertex;
|
||||
uv = (gl_Vertex.xy * vec2(1.0,-1.0) + vec2(1.0)) / 2;
|
||||
}
|
Loading…
Reference in a new issue