mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-29 17:45:34 +00:00
/components/ code should not access the stereo manager without checking whether or not stereo is enabled first. Stereo component code should not read settings itself, but rather take settings as parameters.
This commit is contained in:
parent
675dfb9725
commit
fe066069d7
14 changed files with 130 additions and 94 deletions
|
@ -155,7 +155,51 @@ namespace
|
|||
|
||||
void operator()(osg::GraphicsContext* graphicsContext) override
|
||||
{
|
||||
Stereo::Manager::instance().initializeStereo(graphicsContext);
|
||||
auto& sm = Stereo::Manager::instance();
|
||||
|
||||
if (Settings::Manager::getBool("use custom view", "Stereo"))
|
||||
{
|
||||
Stereo::View left;
|
||||
Stereo::View right;
|
||||
|
||||
left.pose.position.x() = Settings::Manager::getDouble("left eye offset x", "Stereo View");
|
||||
left.pose.position.y() = Settings::Manager::getDouble("left eye offset y", "Stereo View");
|
||||
left.pose.position.z() = Settings::Manager::getDouble("left eye offset z", "Stereo View");
|
||||
left.pose.orientation.x() = Settings::Manager::getDouble("left eye orientation x", "Stereo View");
|
||||
left.pose.orientation.y() = Settings::Manager::getDouble("left eye orientation y", "Stereo View");
|
||||
left.pose.orientation.z() = Settings::Manager::getDouble("left eye orientation z", "Stereo View");
|
||||
left.pose.orientation.w() = Settings::Manager::getDouble("left eye orientation w", "Stereo View");
|
||||
left.fov.angleLeft = Settings::Manager::getDouble("left eye fov left", "Stereo View");
|
||||
left.fov.angleRight = Settings::Manager::getDouble("left eye fov right", "Stereo View");
|
||||
left.fov.angleUp = Settings::Manager::getDouble("left eye fov up", "Stereo View");
|
||||
left.fov.angleDown = Settings::Manager::getDouble("left eye fov down", "Stereo View");
|
||||
|
||||
right.pose.position.x() = Settings::Manager::getDouble("right eye offset x", "Stereo View");
|
||||
right.pose.position.y() = Settings::Manager::getDouble("right eye offset y", "Stereo View");
|
||||
right.pose.position.z() = Settings::Manager::getDouble("right eye offset z", "Stereo View");
|
||||
right.pose.orientation.x() = Settings::Manager::getDouble("right eye orientation x", "Stereo View");
|
||||
right.pose.orientation.y() = Settings::Manager::getDouble("right eye orientation y", "Stereo View");
|
||||
right.pose.orientation.z() = Settings::Manager::getDouble("right eye orientation z", "Stereo View");
|
||||
right.pose.orientation.w() = Settings::Manager::getDouble("right eye orientation w", "Stereo View");
|
||||
right.fov.angleLeft = Settings::Manager::getDouble("right eye fov left", "Stereo View");
|
||||
right.fov.angleRight = Settings::Manager::getDouble("right eye fov right", "Stereo View");
|
||||
right.fov.angleUp = Settings::Manager::getDouble("right eye fov up", "Stereo View");
|
||||
right.fov.angleDown = Settings::Manager::getDouble("right eye fov down", "Stereo View");
|
||||
|
||||
auto customViewCallback = std::make_shared<Stereo::Manager::CustomViewCallback>(left, right);
|
||||
sm.setUpdateViewCallback(customViewCallback);
|
||||
}
|
||||
|
||||
if (Settings::Manager::getBool("use custom eye resolution", "Stereo"))
|
||||
{
|
||||
osg::Vec2i eyeResolution = osg::Vec2i();
|
||||
eyeResolution.x() = Settings::Manager::getInt("eye resolution x", "Stereo View");
|
||||
eyeResolution.y() = Settings::Manager::getInt("eye resolution y", "Stereo View");
|
||||
sm.overrideEyeResolution(eyeResolution);
|
||||
}
|
||||
|
||||
sm.initializeStereo(
|
||||
graphicsContext, Settings::Manager::getBool("multiview", "Stereo"));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -610,7 +654,7 @@ void OMW::Engine::createWindow()
|
|||
if (Stereo::getStereo())
|
||||
{
|
||||
realizeOperations->add(new InitializeStereoOperation());
|
||||
Stereo::setVertexBufferHint();
|
||||
Stereo::setVertexBufferHint(Settings::Manager::getBool("multiview", "Stereo"));
|
||||
}
|
||||
|
||||
mViewer->realize();
|
||||
|
@ -650,7 +694,9 @@ void OMW::Engine::prepareEngine()
|
|||
mStateManager = std::make_unique<MWState::StateManager>(mCfgMgr.getUserDataPath() / "saves", mContentFiles);
|
||||
mEnvironment.setStateManager(*mStateManager);
|
||||
|
||||
mStereoManager = std::make_unique<Stereo::Manager>(mViewer);
|
||||
bool stereoEnabled
|
||||
= Settings::Manager::getBool("stereo enabled", "Stereo") || osg::DisplaySettings::instance().get()->getStereo();
|
||||
mStereoManager = std::make_unique<Stereo::Manager>(mViewer, stereoEnabled);
|
||||
|
||||
osg::ref_ptr<osg::Group> rootNode(new osg::Group);
|
||||
mViewer->setSceneData(rootNode);
|
||||
|
|
|
@ -30,7 +30,7 @@ namespace MWRender
|
|||
mLuminanceCalculator.disable();
|
||||
|
||||
Shader::ShaderManager::DefineMap defines;
|
||||
Stereo::Manager::instance().shaderStereoDefines(defines);
|
||||
Stereo::shaderStereoDefines(defines);
|
||||
|
||||
mFallbackProgram = shaderManager.getProgram("fullscreen_tri");
|
||||
|
||||
|
|
|
@ -365,7 +365,7 @@ namespace MWRender
|
|||
if (mSceneManager->getForceShaders())
|
||||
{
|
||||
Shader::ShaderManager::DefineMap defines = {};
|
||||
Stereo::Manager::instance().shaderStereoDefines(defines);
|
||||
Stereo::shaderStereoDefines(defines);
|
||||
auto program = mSceneManager->getShaderManager().getProgram("sky", defines);
|
||||
mEarlyRenderBinRoot->getOrCreateStateSet()->addUniform(new osg::Uniform("pass", -1));
|
||||
mEarlyRenderBinRoot->getOrCreateStateSet()->setAttributeAndModes(
|
||||
|
|
|
@ -33,7 +33,7 @@ namespace MWRender
|
|||
mStateSet->setTextureAttributeAndModes(0, dummyTexture);
|
||||
|
||||
Shader::ShaderManager::DefineMap defines;
|
||||
Stereo::Manager::instance().shaderStereoDefines(defines);
|
||||
Stereo::shaderStereoDefines(defines);
|
||||
|
||||
mStateSet->setAttributeAndModes(new osg::BlendFunc, modeOff);
|
||||
mStateSet->setAttributeAndModes(shaderManager.getProgram("depthclipped", defines), modeOn);
|
||||
|
|
|
@ -695,7 +695,7 @@ namespace MWRender
|
|||
defineMap["ripple_map_world_scale"] = std::to_string(RipplesSurface::mWorldScaleFactor);
|
||||
defineMap["ripple_map_size"] = std::to_string(RipplesSurface::mRTTSize) + ".0";
|
||||
|
||||
Stereo::Manager::instance().shaderStereoDefines(defineMap);
|
||||
Stereo::shaderStereoDefines(defineMap);
|
||||
|
||||
Shader::ShaderManager& shaderMgr = mResourceSystem->getSceneManager()->getShaderManager();
|
||||
osg::ref_ptr<osg::Program> program = shaderMgr.getProgram("water", defineMap);
|
||||
|
|
|
@ -54,11 +54,14 @@ namespace SceneUtil
|
|||
if (frameNumber > vdd->mFrameNumber)
|
||||
{
|
||||
apply(vdd->mCamera);
|
||||
auto& sm = Stereo::Manager::instance();
|
||||
if (sm.getEye(cv) == Stereo::Eye::Left)
|
||||
applyLeft(vdd->mCamera);
|
||||
if (sm.getEye(cv) == Stereo::Eye::Right)
|
||||
applyRight(vdd->mCamera);
|
||||
if (Stereo::getStereo())
|
||||
{
|
||||
auto& sm = Stereo::Manager::instance();
|
||||
if (sm.getEye(cv) == Stereo::Eye::Left)
|
||||
applyLeft(vdd->mCamera);
|
||||
if (sm.getEye(cv) == Stereo::Eye::Right)
|
||||
applyRight(vdd->mCamera);
|
||||
}
|
||||
vdd->mCamera->accept(*cv);
|
||||
}
|
||||
vdd->mFrameNumber = frameNumber;
|
||||
|
|
|
@ -115,7 +115,9 @@ namespace SceneUtil
|
|||
, mIndoorShadowCastingMask(indoorShadowCastingMask)
|
||||
{
|
||||
mShadowedScene->setShadowTechnique(mShadowTechnique);
|
||||
Stereo::Manager::instance().setShadowTechnique(mShadowTechnique);
|
||||
|
||||
if (Stereo::getStereo())
|
||||
Stereo::Manager::instance().setShadowTechnique(mShadowTechnique);
|
||||
|
||||
mShadowedScene->addChild(sceneRoot);
|
||||
rootNode->addChild(mShadowedScene);
|
||||
|
@ -132,7 +134,8 @@ namespace SceneUtil
|
|||
|
||||
ShadowManager::~ShadowManager()
|
||||
{
|
||||
Stereo::Manager::instance().setShadowTechnique(nullptr);
|
||||
if (Stereo::getStereo())
|
||||
Stereo::Manager::instance().setShadowTechnique(nullptr);
|
||||
}
|
||||
|
||||
Shader::ShaderManager::DefineMap ShadowManager::getShadowDefines()
|
||||
|
|
|
@ -42,12 +42,13 @@ namespace SceneUtil
|
|||
{
|
||||
auto stateset = getCvDependentStateset(cv);
|
||||
apply(stateset, cv);
|
||||
auto* sm = &Stereo::Manager::instance();
|
||||
if (sm != nullptr)
|
||||
|
||||
if (Stereo::getStereo())
|
||||
{
|
||||
if (sm->getEye(cv) == Stereo::Eye::Left)
|
||||
auto& sm = Stereo::Manager::instance();
|
||||
if (sm.getEye(cv) == Stereo::Eye::Left)
|
||||
applyLeft(stateset, cv);
|
||||
if (sm->getEye(cv) == Stereo::Eye::Right)
|
||||
if (sm.getEye(cv) == Stereo::Eye::Right)
|
||||
applyRight(stateset, cv);
|
||||
}
|
||||
|
||||
|
|
|
@ -711,7 +711,7 @@ namespace Shader
|
|||
|
||||
defineMap["softParticles"] = reqs.mSoftParticles ? "1" : "0";
|
||||
|
||||
Stereo::Manager::instance().shaderStereoDefines(defineMap);
|
||||
Stereo::shaderStereoDefines(defineMap);
|
||||
|
||||
std::string shaderPrefix;
|
||||
if (!node.getUserValue("shaderPrefix", shaderPrefix))
|
||||
|
|
|
@ -74,12 +74,6 @@ namespace Stereo
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!Settings::Manager::getBool("multiview", "Stereo"))
|
||||
{
|
||||
Log(Debug::Verbose) << "Disabling Multiview (disabled by config)";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!getMultiviewSupported(contextID))
|
||||
{
|
||||
return false;
|
||||
|
@ -95,6 +89,8 @@ namespace Stereo
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool sMultiview = false;
|
||||
|
||||
bool getMultiview(unsigned int contextID)
|
||||
{
|
||||
static bool multiView = getMultiviewImpl(contextID);
|
||||
|
@ -112,16 +108,25 @@ namespace Stereo
|
|||
return getMultiview(0);
|
||||
}
|
||||
|
||||
void configureExtensions(unsigned int contextID)
|
||||
void configureExtensions(unsigned int contextID, bool enableMultiview)
|
||||
{
|
||||
getTextureViewSupported(contextID);
|
||||
getMultiviewSupported(contextID);
|
||||
getMultiview(contextID);
|
||||
|
||||
if (enableMultiview)
|
||||
{
|
||||
sMultiview = getMultiview(contextID);
|
||||
}
|
||||
else
|
||||
{
|
||||
Log(Debug::Verbose) << "Disabling Multiview (disabled by config)";
|
||||
sMultiview = false;
|
||||
}
|
||||
}
|
||||
|
||||
void setVertexBufferHint()
|
||||
void setVertexBufferHint(bool enableMultiview)
|
||||
{
|
||||
if (getStereo() && Settings::Manager::getBool("multiview", "Stereo"))
|
||||
if (getStereo() && enableMultiview)
|
||||
{
|
||||
auto* ds = osg::DisplaySettings::instance().get();
|
||||
if (!Settings::Manager::getBool("allow display lists for multiview", "Stereo")
|
||||
|
|
|
@ -34,10 +34,10 @@ namespace Stereo
|
|||
|
||||
//! Use the provided context to check what extensions are supported and configure use of multiview based on
|
||||
//! extensions and settings.
|
||||
void configureExtensions(unsigned int contextID);
|
||||
void configureExtensions(unsigned int contextID, bool enableMultiview);
|
||||
|
||||
//! Sets the appropriate vertex buffer hint on OSG's display settings if needed
|
||||
void setVertexBufferHint();
|
||||
void setVertexBufferHint(bool enableMultiview);
|
||||
|
||||
//! Creates a Texture2D as a texture view into a Texture2DArray
|
||||
osg::ref_ptr<osg::Texture2D> createTextureView_Texture2DFromTexture2DArray(
|
||||
|
|
|
@ -105,6 +105,8 @@ namespace Stereo
|
|||
Manager* mManager;
|
||||
};
|
||||
|
||||
static bool sStereoEnabled = false;
|
||||
|
||||
static Manager* sInstance = nullptr;
|
||||
|
||||
Manager& Manager::instance()
|
||||
|
@ -112,19 +114,7 @@ namespace Stereo
|
|||
return *sInstance;
|
||||
}
|
||||
|
||||
struct CustomViewCallback : public Manager::UpdateViewCallback
|
||||
{
|
||||
public:
|
||||
CustomViewCallback();
|
||||
|
||||
void updateView(View& left, View& right) override;
|
||||
|
||||
private:
|
||||
View mLeft;
|
||||
View mRight;
|
||||
};
|
||||
|
||||
Manager::Manager(osgViewer::Viewer* viewer)
|
||||
Manager::Manager(osgViewer::Viewer* viewer, bool enableStereo)
|
||||
: mViewer(viewer)
|
||||
, mMainCamera(mViewer->getCamera())
|
||||
, mUpdateCallback(new StereoUpdateCallback(this))
|
||||
|
@ -137,29 +127,19 @@ namespace Stereo
|
|||
if (sInstance)
|
||||
throw std::logic_error("Double instance of Stereo::Manager");
|
||||
sInstance = this;
|
||||
|
||||
if (Settings::Manager::getBool("use custom view", "Stereo"))
|
||||
mUpdateViewCallback = std::make_shared<CustomViewCallback>();
|
||||
|
||||
if (Settings::Manager::getBool("use custom eye resolution", "Stereo"))
|
||||
{
|
||||
osg::Vec2i eyeResolution = osg::Vec2i();
|
||||
eyeResolution.x() = Settings::Manager::getInt("eye resolution x", "Stereo View");
|
||||
eyeResolution.y() = Settings::Manager::getInt("eye resolution y", "Stereo View");
|
||||
overrideEyeResolution(eyeResolution);
|
||||
}
|
||||
sStereoEnabled = enableStereo;
|
||||
}
|
||||
|
||||
Manager::~Manager() {}
|
||||
|
||||
void Manager::initializeStereo(osg::GraphicsContext* gc)
|
||||
void Manager::initializeStereo(osg::GraphicsContext* gc, bool enableMultiview)
|
||||
{
|
||||
auto ci = gc->getState()->getContextID();
|
||||
configureExtensions(ci, enableMultiview);
|
||||
|
||||
mMainCamera->addUpdateCallback(mUpdateCallback);
|
||||
mFrustumManager = std::make_unique<StereoFrustumManager>(mViewer->getCamera());
|
||||
|
||||
auto ci = gc->getState()->getContextID();
|
||||
configureExtensions(ci);
|
||||
|
||||
if (getMultiview())
|
||||
setupOVRMultiView2Technique();
|
||||
else
|
||||
|
@ -168,7 +148,7 @@ namespace Stereo
|
|||
updateStereoFramebuffer();
|
||||
}
|
||||
|
||||
void Manager::shaderStereoDefines(Shader::ShaderManager::DefineMap& defines) const
|
||||
void shaderStereoDefines(Shader::ShaderManager::DefineMap& defines)
|
||||
{
|
||||
if (getMultiview())
|
||||
{
|
||||
|
@ -402,39 +382,16 @@ namespace Stereo
|
|||
|
||||
bool getStereo()
|
||||
{
|
||||
static bool stereo = Settings::Manager::getBool("stereo enabled", "Stereo")
|
||||
|| osg::DisplaySettings::instance().get()->getStereo();
|
||||
return stereo;
|
||||
return sStereoEnabled;
|
||||
}
|
||||
|
||||
CustomViewCallback::CustomViewCallback()
|
||||
Manager::CustomViewCallback::CustomViewCallback(View left, View right)
|
||||
: mLeft(left)
|
||||
, mRight(right)
|
||||
{
|
||||
mLeft.pose.position.x() = Settings::Manager::getDouble("left eye offset x", "Stereo View");
|
||||
mLeft.pose.position.y() = Settings::Manager::getDouble("left eye offset y", "Stereo View");
|
||||
mLeft.pose.position.z() = Settings::Manager::getDouble("left eye offset z", "Stereo View");
|
||||
mLeft.pose.orientation.x() = Settings::Manager::getDouble("left eye orientation x", "Stereo View");
|
||||
mLeft.pose.orientation.y() = Settings::Manager::getDouble("left eye orientation y", "Stereo View");
|
||||
mLeft.pose.orientation.z() = Settings::Manager::getDouble("left eye orientation z", "Stereo View");
|
||||
mLeft.pose.orientation.w() = Settings::Manager::getDouble("left eye orientation w", "Stereo View");
|
||||
mLeft.fov.angleLeft = Settings::Manager::getDouble("left eye fov left", "Stereo View");
|
||||
mLeft.fov.angleRight = Settings::Manager::getDouble("left eye fov right", "Stereo View");
|
||||
mLeft.fov.angleUp = Settings::Manager::getDouble("left eye fov up", "Stereo View");
|
||||
mLeft.fov.angleDown = Settings::Manager::getDouble("left eye fov down", "Stereo View");
|
||||
|
||||
mRight.pose.position.x() = Settings::Manager::getDouble("right eye offset x", "Stereo View");
|
||||
mRight.pose.position.y() = Settings::Manager::getDouble("right eye offset y", "Stereo View");
|
||||
mRight.pose.position.z() = Settings::Manager::getDouble("right eye offset z", "Stereo View");
|
||||
mRight.pose.orientation.x() = Settings::Manager::getDouble("right eye orientation x", "Stereo View");
|
||||
mRight.pose.orientation.y() = Settings::Manager::getDouble("right eye orientation y", "Stereo View");
|
||||
mRight.pose.orientation.z() = Settings::Manager::getDouble("right eye orientation z", "Stereo View");
|
||||
mRight.pose.orientation.w() = Settings::Manager::getDouble("right eye orientation w", "Stereo View");
|
||||
mRight.fov.angleLeft = Settings::Manager::getDouble("right eye fov left", "Stereo View");
|
||||
mRight.fov.angleRight = Settings::Manager::getDouble("right eye fov right", "Stereo View");
|
||||
mRight.fov.angleUp = Settings::Manager::getDouble("right eye fov up", "Stereo View");
|
||||
mRight.fov.angleDown = Settings::Manager::getDouble("right eye fov down", "Stereo View");
|
||||
}
|
||||
|
||||
void CustomViewCallback::updateView(View& left, View& right)
|
||||
void Manager::CustomViewCallback::updateView(View& left, View& right)
|
||||
{
|
||||
left = mLeft;
|
||||
right = mRight;
|
||||
|
|
|
@ -39,6 +39,9 @@ namespace Stereo
|
|||
|
||||
bool getStereo();
|
||||
|
||||
//! Sets up any definitions necessary for stereo rendering
|
||||
void shaderStereoDefines(Shader::ShaderManager::DefineMap& defines);
|
||||
|
||||
//! Class that provides tools for managing stereo mode
|
||||
class Manager
|
||||
{
|
||||
|
@ -51,16 +54,37 @@ namespace Stereo
|
|||
virtual void updateView(View& left, View& right) = 0;
|
||||
};
|
||||
|
||||
//! An UpdateViewCallback that supplies a fixed, custom view. Useful for debugging purposes,
|
||||
//! such as emulating a given HMD's view.
|
||||
struct CustomViewCallback : public UpdateViewCallback
|
||||
{
|
||||
public:
|
||||
CustomViewCallback(View left, View right);
|
||||
|
||||
void updateView(View& left, View& right) override;
|
||||
|
||||
private:
|
||||
View mLeft;
|
||||
View mRight;
|
||||
};
|
||||
|
||||
//! Gets the singleton instance
|
||||
static Manager& instance();
|
||||
|
||||
Manager(osgViewer::Viewer* viewer);
|
||||
//! Constructor
|
||||
//!
|
||||
//! @Param viewer the osg viewer whose stereo should be managed.
|
||||
//! @Param enableStereo whether or not stereo should be enabled.
|
||||
//! @Param enableMultiview whether or not to make use of the GL_OVR_Multiview extension, if supported.
|
||||
Manager(osgViewer::Viewer* viewer, bool enableStereo);
|
||||
~Manager();
|
||||
|
||||
//! Called during update traversal
|
||||
void update();
|
||||
|
||||
void initializeStereo(osg::GraphicsContext* gc);
|
||||
//! Initializes all details of stereo if applicable. If the constructor was called with enableMultiview=true,
|
||||
//! and the GL_OVR_Multiview extension is supported, Stereo::getMultiview() will return true after this call.
|
||||
void initializeStereo(osg::GraphicsContext* gc, bool enableMultiview);
|
||||
|
||||
//! Callback that updates stereo configuration during the update pass
|
||||
void setUpdateViewCallback(std::shared_ptr<UpdateViewCallback> cb);
|
||||
|
@ -71,9 +95,6 @@ namespace Stereo
|
|||
osg::Matrixd computeEyeProjection(int view, bool reverseZ) const;
|
||||
osg::Matrixd computeEyeViewOffset(int view) const;
|
||||
|
||||
//! Sets up any definitions necessary for stereo rendering
|
||||
void shaderStereoDefines(Shader::ShaderManager::DefineMap& defines) const;
|
||||
|
||||
const std::shared_ptr<MultiviewFramebuffer>& multiviewFramebuffer() { return mMultiviewFramebuffer; }
|
||||
|
||||
//! Sets rendering resolution of each eye to eyeResolution.
|
||||
|
|
|
@ -283,7 +283,7 @@ namespace Terrain
|
|||
defineMap["specularMap"] = it->mSpecular ? "1" : "0";
|
||||
defineMap["parallax"] = (it->mNormalMap && it->mParallax) ? "1" : "0";
|
||||
defineMap["writeNormals"] = (it == layers.end() - 1) ? "1" : "0";
|
||||
Stereo::Manager::instance().shaderStereoDefines(defineMap);
|
||||
Stereo::shaderStereoDefines(defineMap);
|
||||
|
||||
stateset->setAttributeAndModes(shaderManager.getProgram("terrain", defineMap));
|
||||
stateset->addUniform(UniformCollection::value().mColorMode);
|
||||
|
|
Loading…
Reference in a new issue