Merge remote-tracking branch 'remotes/origin/multiview_test_branch' into openxr_vr_geometryshader_feature_branch

pull/615/head
Mads Buvik Sandvei 4 years ago
commit 823bda139a

@ -602,6 +602,12 @@ if (WIN32)
5031 # #pragma warning(pop): likely mismatch, popping warning state pushed in different file (config_begin.hpp, config_end.hpp)
)
endif()
if( "${MyGUI_VERSION}" VERSION_LESS_EQUAL "3.4.0" )
set(WARNINGS_DISABLE ${WARNINGS_DISABLE}
4866 # compiler may not enforce left-to-right evaluation order for call
)
endif()
foreach(d ${WARNINGS_DISABLE})
set(WARNINGS "${WARNINGS} /wd${d}")

@ -675,19 +675,7 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings)
Settings::Manager::getInt("anisotropy", "General")
);
// geometry shader must be enabled before the RenderingManager sets up any shaders
// therefore this part is separate from the rest of stereo setup.
mStereoEnabled = mEnvironment.getVrMode() || Settings::Manager::getBool("stereo enabled", "Stereo");
if (mStereoEnabled)
{
mResourceSystem->getSceneManager()->getShaderManager().setStereoGeometryShaderEnabled(Misc::getStereoTechnique() == Misc::StereoView::Technique::GeometryShader_IndexedViewports);
// Mask in everything that does not currently use shaders.
// Remove that altogether when the sky finally uses them.
auto noShaderMask = MWRender::VisMask::Mask_Sky | MWRender::VisMask::Mask_Sun | MWRender::VisMask::Mask_WeatherParticles;
// Since shaders are not yet created, we need to use the brute force technique initially
mStereoView.reset(new Misc::StereoView(mViewer, Misc::StereoView::Technique::BruteForce, noShaderMask, MWRender::VisMask::Mask_Scene));
}
int numThreads = Settings::Manager::getInt("preload num threads", "Cells");
if (numThreads <= 0)
@ -771,6 +759,16 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings)
// Create sound system
mEnvironment.setSoundManager (new MWSound::SoundManager(mVFS.get(), mUseSound));
if (mStereoEnabled)
{
// Set up stereo
// Stereo setup is split in two because the GeometryShader approach cannot be used before the RenderingManager has been created.
// To be able to see the logo and initial loading screen the BruteForce technique must be set up here.
mStereoView->initializeStereo(mViewer, Misc::StereoView::Technique::BruteForce);
mResourceSystem->getSceneManager()->getShaderManager().setStereoGeometryShaderEnabled(Misc::getStereoTechnique() == Misc::StereoView::Technique::GeometryShader_IndexedViewports);
}
#ifdef USE_OPENXR
mXrEnvironment.setGUIManager(new MWVR::VRGUIManager(mViewer, mResourceSystem.get(), rootNode));
mXrEnvironment.getViewer()->configureCallbacks();
@ -797,9 +795,9 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings)
mStartupScript, mResDir.string(), mCfgMgr.getUserDataPath().string()));
mEnvironment.getWorld()->setupPlayer();
// Set up stereo
if (mStereoEnabled)
{
// Stereo shader technique can be set up now.
mStereoView->setStereoTechnique(Misc::getStereoTechnique());
mStereoView->initializeScene();
mStereoView->setCullMask(mStereoView->getCullMask());
@ -921,6 +919,18 @@ void OMW::Engine::go()
// Create encoder
mEncoder = new ToUTF8::Utf8Encoder(mEncoding);
// geometry shader must be enabled before the RenderingManager sets up any shaders
// therefore this part is separate from the rest of stereo setup.
mStereoEnabled = Settings::Manager::getBool("stereo enabled", "Stereo");
if (mStereoEnabled)
{
// Mask in everything that does not currently use shaders.
// Remove that altogether when the sky finally uses them.
auto noShaderMask = MWRender::VisMask::Mask_Sky | MWRender::VisMask::Mask_Sun | MWRender::VisMask::Mask_WeatherParticles;
// Since shaders are not yet created, we need to use the brute force technique initially
mStereoView.reset(new Misc::StereoView(noShaderMask, MWRender::VisMask::Mask_Scene));
}
// Setup viewer
mViewer = new osgViewer::Viewer;
mViewer->setReleaseContextAtEndOfFrameHint(false);

@ -6,6 +6,7 @@
#include <osgUtil/CullVisitor>
#include <osgViewer/Renderer>
#include <osgViewer/Viewer>
#include <iostream>
@ -252,26 +253,20 @@ namespace Misc
return camera;
}
StereoView::StereoView(osgViewer::Viewer* viewer, Technique technique, osg::Node::NodeMask noShaderMask, osg::Node::NodeMask sceneMask)
: mViewer(viewer)
, mMainCamera(mViewer->getCamera())
, mRoot(mViewer->getSceneData()->asGroup())
StereoView::StereoView(osg::Node::NodeMask noShaderMask, osg::Node::NodeMask sceneMask)
: mViewer(nullptr)
, mMainCamera(nullptr)
, mRoot(nullptr)
, mStereoRoot(new osg::Group)
, mUpdateCallback(new StereoUpdateCallback(this))
, mTechnique(Technique::None)
, mNoShaderMask(noShaderMask)
, mSceneMask(sceneMask)
, mCullMask(mMainCamera->getCullMask())
, mCullMask(0)
, mMasterConfig(new SharedShadowMapConfig)
, mSlaveConfig(new SharedShadowMapConfig)
, mSharedShadowMaps(Settings::Manager::getBool("shared shadow maps", "Stereo"))
{
if (technique == Technique::None)
// Do nothing
return;
mRoot->setDataVariance(osg::Object::STATIC);
mMasterConfig->_id = "STEREO";
mMasterConfig->_master = true;
mSlaveConfig->_id = "STEREO";
@ -283,42 +278,92 @@ namespace Misc
mStereoRoot->addChild(mStereoBruteForceRoot);
mStereoRoot->addCullCallback(new StereoStatesetUpdateCallback(this));
setStereoTechnique(technique);
if (sInstance)
throw std::logic_error("Double instance og StereoView");
sInstance = this;
auto* ds = osg::DisplaySettings::instance().get();
ds->setStereo(true);
ds->setStereoMode(osg::DisplaySettings::StereoMode::HORIZONTAL_SPLIT);
ds->setUseSceneViewForStereoHint(true);
}
void StereoView::setupBruteForceTechnique()
void StereoView::initializeStereo(osgViewer::Viewer* viewer, Technique technique)
{
mLeftCamera = createCamera("Stereo Left", GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
mRightCamera = createCamera("Stereo Right", GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
mViewer = viewer;
mRoot = viewer->getSceneData()->asGroup();
mMainCamera = viewer->getCamera();
mCullMask = mMainCamera->getCullMask();
setStereoTechnique(technique);
}
if (mSharedShadowMaps)
void StereoView::initializeScene()
{
SceneUtil::FindByNameVisitor findScene("Scene Root");
mRoot->accept(findScene);
mScene = findScene.mFoundNode;
if (!mScene)
throw std::logic_error("Couldn't find scene root");
if (mTechnique == Technique::GeometryShader_IndexedViewports)
{
mLeftCamera->setUserData(mSlaveConfig);
mRightCamera->setUserData(mMasterConfig);
mLeftCamera->addChild(mScene); // Use scene directly to avoid redundant shadow computation.
mRightCamera->addChild(mScene);
}
}
// Slave cameras must have their viewports defined immediately
auto width = mMainCamera->getViewport()->width();
auto height = mMainCamera->getViewport()->height();
mLeftCamera->setViewport(0, 0, width / 2, height);
mRightCamera->setViewport(width / 2, 0, width / 2, height);
void StereoView::setupBruteForceTechnique()
{
auto* ds = osg::DisplaySettings::instance().get();
ds->setStereo(true);
ds->setStereoMode(osg::DisplaySettings::StereoMode::HORIZONTAL_SPLIT);
ds->setUseSceneViewForStereoHint(true);
struct ComputeStereoMatricesCallback : public osgUtil::SceneView::ComputeStereoMatricesCallback
{
ComputeStereoMatricesCallback(StereoView* sv)
: mStereoView(sv)
{
}
osg::Matrixd computeLeftEyeProjection(const osg::Matrixd& projection) const override
{
return mStereoView->computeLeftEyeProjection(projection);
}
osg::Matrixd computeLeftEyeView(const osg::Matrixd& view) const override
{
return mStereoView->computeLeftEyeView(view);
}
osg::Matrixd computeRightEyeProjection(const osg::Matrixd& projection) const override
{
return mStereoView->computeRightEyeProjection(projection);
}
osg::Matrixd computeRightEyeView(const osg::Matrixd& view) const override
{
return mStereoView->computeRightEyeView(view);
}
// Threading should be stopped before adding new slave cameras
mViewer->stopThreading();
mViewer->addSlave(mRightCamera, true);
mViewer->addSlave(mLeftCamera, true);
mRightCamera->setGraphicsContext(mViewer->getCamera()->getGraphicsContext());
mLeftCamera->setGraphicsContext(mViewer->getCamera()->getGraphicsContext());
StereoView* mStereoView;
};
// Remove main camera's graphics context to ensure it does not do any work
mViewer->getCamera()->setGraphicsContext(nullptr);
auto* renderer = static_cast<osgViewer::Renderer*>(mMainCamera->getRenderer());
// Re-realize to ensure slave cameras are set up with appropriate settings
mViewer->realize();
// osgViewer::Renderer always has two scene views
for (auto* sceneView : { renderer->getSceneView(0), renderer->getSceneView(1) })
{
sceneView->setComputeStereoMatricesCallback(new ComputeStereoMatricesCallback(this));
if (mSharedShadowMaps)
{
sceneView->getCullVisitorLeft()->setUserData(mMasterConfig);
sceneView->getCullVisitorRight()->setUserData(mSlaveConfig);
}
}
}
void StereoView::setupGeometryShaderIndexedViewportTechnique()
@ -338,7 +383,7 @@ namespace Misc
for (unsigned int i = 0; i < viewer->getNumSlaves(); i++)
{
auto& slave = viewer->getSlave(i);
if (slave._camera == camera);
if (slave._camera == camera)
{
viewer->removeSlave(i);
return;
@ -348,17 +393,10 @@ namespace Misc
void StereoView::removeBruteForceTechnique()
{
mViewer->stopThreading();
removeSlave(mViewer, mRightCamera);
removeSlave(mViewer, mLeftCamera);
mLeftCamera->setUserData(nullptr);
mRightCamera->setUserData(nullptr);
mMainCamera->setGraphicsContext(mRightCamera->getGraphicsContext());
mLeftCamera = nullptr;
mRightCamera = nullptr;
mViewer->realize();
auto* ds = osg::DisplaySettings::instance().get();
ds->setStereo(false);
if(mMainCamera->getUserData() == mMasterConfig)
mMainCamera->setUserData(nullptr);
}
void StereoView::removeGeometryShaderIndexedViewportTechnique()
@ -589,21 +627,6 @@ namespace Misc
mUpdateViewCallback = cb;
}
void StereoView::initializeScene()
{
SceneUtil::FindByNameVisitor findScene("Scene Root");
mRoot->accept(findScene);
mScene = findScene.mFoundNode;
if (!mScene)
throw std::logic_error("Couldn't find scene root");
if (mTechnique == Technique::GeometryShader_IndexedViewports)
{
mLeftCamera->addChild(mScene); // Use scene directly to avoid redundant shadow computation.
mRightCamera->addChild(mScene);
}
}
void disableStereoForCamera(osg::Camera* camera)
{
auto* viewport = camera->getViewport();
@ -735,4 +758,20 @@ namespace Misc
{
return mCullMask;
}
osg::Matrixd StereoView::computeLeftEyeProjection(const osg::Matrixd& projection) const
{
return mLeftCamera->getProjectionMatrix();
}
osg::Matrixd StereoView::computeLeftEyeView(const osg::Matrixd& view) const
{
return mLeftCamera->getViewMatrix();
}
osg::Matrixd StereoView::computeRightEyeProjection(const osg::Matrixd& projection) const
{
return mRightCamera->getProjectionMatrix();
}
osg::Matrixd StereoView::computeRightEyeView(const osg::Matrixd& view) const
{
return mRightCamera->getViewMatrix();
}
}

@ -96,13 +96,14 @@ namespace Misc
//! \param noShaderMask mask in all nodes that do not use shaders and must be rendered brute force.
//! \param sceneMask must equal MWRender::VisMask::Mask_Scene. Necessary while VisMask is still not in components/
//! \note the masks apply only to the GeometryShader_IndexdViewports technique and can be 0 for the BruteForce technique.
StereoView(osgViewer::Viewer* viewer, Technique technique, osg::Node::NodeMask noShaderMask, osg::Node::NodeMask sceneMask);
StereoView(osg::Node::NodeMask noShaderMask, osg::Node::NodeMask sceneMask);
//! Updates uniforms with the view and projection matrices of each stereo view, and replaces the camera's view and projection matrix
//! with a view and projection that closely envelopes the frustums of the two eyes.
void update();
void updateStateset(osg::StateSet* stateset);
void initializeStereo(osgViewer::Viewer* viewer, Technique technique);
//! Initialized scene. Call when the "scene root" node has been created
void initializeScene();
@ -129,6 +130,13 @@ namespace Misc
//! Get the last applied cullmask.
osg::Node::NodeMask getCullMask();
osg::Matrixd computeLeftEyeProjection(const osg::Matrixd& projection) const;
osg::Matrixd computeLeftEyeView(const osg::Matrixd& view) const;
osg::Matrixd computeRightEyeProjection(const osg::Matrixd& projection) const;
osg::Matrixd computeRightEyeView(const osg::Matrixd& view) const;
private:
void setupBruteForceTechnique();
void setupGeometryShaderIndexedViewportTechnique();

@ -967,7 +967,9 @@ void SceneUtil::MWShadowTechnique::shareShadowMap(osgUtil::CullVisitor& cv, View
bool MWShadowTechnique::trySharedShadowMap(osgUtil::CullVisitor& cv, ViewDependentData* vdd)
{
auto* sharedConfig = dynamic_cast<SharedShadowMapConfig*>(cv.getCurrentCamera()->getUserData());
auto* sharedConfig = dynamic_cast<SharedShadowMapConfig*>(cv.getUserData());
if (!sharedConfig)
sharedConfig = dynamic_cast<SharedShadowMapConfig*>(cv.getCurrentCamera()->getUserData());
if (!sharedConfig)
{
return false;
@ -1002,7 +1004,9 @@ bool MWShadowTechnique::trySharedShadowMap(osgUtil::CullVisitor& cv, ViewDepende
void SceneUtil::MWShadowTechnique::endSharedShadowMap(osgUtil::CullVisitor& cv)
{
auto* sharedConfig = dynamic_cast<SharedShadowMapConfig*>(cv.getCurrentCamera()->getUserData());
auto* sharedConfig = dynamic_cast<SharedShadowMapConfig*>(cv.getUserData());
if (!sharedConfig)
sharedConfig = dynamic_cast<SharedShadowMapConfig*>(cv.getCurrentCamera()->getUserData());
if (!sharedConfig)
{
return;

Loading…
Cancel
Save