mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-02-02 00:45:32 +00:00
Basic functions in place. Still bad handling of GUI
This commit is contained in:
commit
d03f55bc2d
8 changed files with 215 additions and 88 deletions
|
@ -755,19 +755,6 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings)
|
|||
// Create sound system
|
||||
mEnvironment.setSoundManager (new MWSound::SoundManager(mVFS.get(), mUseSound));
|
||||
|
||||
|
||||
#ifdef USE_OPENXR
|
||||
mXrEnvironment.setGUIManager(new MWVR::VRGUIManager(mViewer, mResourceSystem.get()));
|
||||
//mViewer->setThreadingModel(osgViewer::ViewerBase::SingleThreaded);
|
||||
#endif
|
||||
|
||||
if (!mSkipMenu)
|
||||
{
|
||||
const std::string& logo = Fallback::Map::getString("Movies_Company_Logo");
|
||||
if (!logo.empty())
|
||||
window->playVideo(logo, true);
|
||||
}
|
||||
|
||||
// VR mode will override this setting by setting mStereoOverride.
|
||||
mStereoEnabled = mEnvironment.getVrMode() || Settings::Manager::getBool("stereo enabled", "Stereo");
|
||||
|
||||
|
@ -776,6 +763,23 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings)
|
|||
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;
|
||||
auto geometryShaderMask = mViewer->getCamera()->getCullMask() & ~noShaderMask;
|
||||
mStereoView.reset(new Misc::StereoView(mViewer, Misc::getStereoTechnique(), geometryShaderMask, noShaderMask | MWRender::VisMask::Mask_Scene));
|
||||
}
|
||||
|
||||
#ifdef USE_OPENXR
|
||||
mXrEnvironment.setGUIManager(new MWVR::VRGUIManager(mViewer, mResourceSystem.get()));
|
||||
mXrEnvironment.getViewer()->configureCallbacks();
|
||||
#endif
|
||||
|
||||
if (!mSkipMenu)
|
||||
{
|
||||
const std::string& logo = Fallback::Map::getString("Movies_Company_Logo");
|
||||
if (!logo.empty())
|
||||
window->playVideo(logo, true);
|
||||
}
|
||||
|
||||
// Create the world
|
||||
|
@ -787,11 +791,7 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings)
|
|||
// Set up 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;
|
||||
auto geometryShaderMask = mViewer->getCamera()->getCullMask() & ~noShaderMask;
|
||||
mStereoView = new Misc::StereoView(mViewer, Misc::getStereoTechnique(), geometryShaderMask, noShaderMask | MWRender::VisMask::Mask_Scene);
|
||||
mStereoView->initializeScene();
|
||||
}
|
||||
|
||||
window->setStore(mEnvironment.getWorld()->getStore());
|
||||
|
|
|
@ -97,7 +97,7 @@ namespace OMW
|
|||
|
||||
bool mStereoEnabled;
|
||||
bool mStereoOverride;
|
||||
osg::ref_ptr<Misc::StereoView> mStereoView;
|
||||
std::unique_ptr<Misc::StereoView> mStereoView;
|
||||
|
||||
bool mSkipMenu;
|
||||
bool mUseSound;
|
||||
|
|
|
@ -97,7 +97,6 @@ namespace MWVR {
|
|||
void OpenXRSwapchainImpl::beginFrame(osg::GraphicsContext* gc)
|
||||
{
|
||||
acquire();
|
||||
renderBuffer()->bindFramebuffer(gc, GL_FRAMEBUFFER_EXT);
|
||||
}
|
||||
|
||||
int swapCount = 0;
|
||||
|
|
|
@ -187,22 +187,29 @@ namespace MWVR
|
|||
getFrame(FramePhase::Swap) = nullptr;
|
||||
}
|
||||
|
||||
mCondition.notify_one();
|
||||
mCondition.notify_all();
|
||||
}
|
||||
|
||||
void VRSession::beginPhase(FramePhase phase)
|
||||
{
|
||||
Log(Debug::Debug) << "beginPhase(" << ((int)phase) << ") " << std::this_thread::get_id();
|
||||
|
||||
auto& frame = getFrame(phase);
|
||||
if (frame)
|
||||
{
|
||||
// Happens once during startup but can be ignored that time.
|
||||
// TODO: This issue would be cleaned up if beginPhase(Update) was called at a more appropriate location.
|
||||
Log(Debug::Warning) << "advanceFramePhase called with a frame alreay in the target phase";
|
||||
return;
|
||||
std::unique_lock<std::mutex> lock(mMutex);
|
||||
while (getFrame(phase))
|
||||
mCondition.wait(lock);
|
||||
}
|
||||
|
||||
mCondition.notify_all();
|
||||
auto& frame = getFrame(phase);
|
||||
//if (frame)
|
||||
//{
|
||||
// // Happens once during startup but can be ignored that time.
|
||||
// // TODO: This issue would be cleaned up if beginPhase(Update) was called at a more appropriate location.
|
||||
// Log(Debug::Warning) << "advanceFramePhase called with a frame alreay in the target phase";
|
||||
// return;
|
||||
//}
|
||||
|
||||
|
||||
if (phase == FramePhase::Update)
|
||||
{
|
||||
|
@ -216,6 +223,7 @@ namespace MWVR
|
|||
throw std::logic_error("beginPhase called without a frame");
|
||||
frame = std::move(getFrame(previousPhase));
|
||||
}
|
||||
|
||||
if (phase == mXrSyncPhase && frame->mShouldSyncFrameLoop)
|
||||
{
|
||||
// We may reach this point before xrEndFrame of the previous frame
|
||||
|
@ -228,6 +236,8 @@ namespace MWVR
|
|||
|
||||
Environment::get().getManager()->beginFrame();
|
||||
}
|
||||
|
||||
mCondition.notify_all();
|
||||
}
|
||||
|
||||
std::unique_ptr<VRSession::VRFrameMeta>& VRSession::getFrame(FramePhase phase)
|
||||
|
|
|
@ -14,6 +14,9 @@
|
|||
#include <components/sceneutil/mwshadowtechnique.hpp>
|
||||
|
||||
#include <components/misc/stringops.hpp>
|
||||
#include <components/misc/stereo.hpp>
|
||||
|
||||
#include <components/sdlutil/sdlgraphicswindow.hpp>
|
||||
|
||||
namespace MWVR
|
||||
{
|
||||
|
@ -39,7 +42,8 @@ namespace MWVR
|
|||
: mViewer(viewer)
|
||||
, mPreDraw(new PredrawCallback(this))
|
||||
, mPostDraw(new PostdrawCallback(this))
|
||||
, mConfigured(false)
|
||||
, mOpenXRConfigured(false)
|
||||
, mCallbacksConfigured(false)
|
||||
, mMsaaResolveMirrorTexture{}
|
||||
, mMirrorTexture{ nullptr }
|
||||
{
|
||||
|
@ -90,19 +94,6 @@ namespace MWVR
|
|||
return VRViewer::MirrorTextureEye::Both;
|
||||
}
|
||||
|
||||
void VRViewer::InitialDrawCallback::operator()(osg::RenderInfo& renderInfo) const
|
||||
{
|
||||
Environment::get().getSession()->beginPhase(VRSession::FramePhase::Draw);
|
||||
|
||||
osg::GraphicsOperation* graphicsOperation = renderInfo.getCurrentCamera()->getRenderer();
|
||||
osgViewer::Renderer* renderer = dynamic_cast<osgViewer::Renderer*>(graphicsOperation);
|
||||
if (renderer != nullptr)
|
||||
{
|
||||
// Disable normal OSG FBO camera setup
|
||||
renderer->setCameraRequiresSetUp(false);
|
||||
}
|
||||
}
|
||||
|
||||
class CullCallback : public osg::NodeCallback
|
||||
{
|
||||
void operator()(osg::Node* node, osg::NodeVisitor* nv)
|
||||
|
@ -112,19 +103,15 @@ namespace MWVR
|
|||
}
|
||||
};
|
||||
|
||||
void VRViewer::realize(osg::GraphicsContext* context)
|
||||
void VRViewer::configureXR(osg::GraphicsContext* context)
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(mMutex);
|
||||
|
||||
if (mConfigured)
|
||||
if (mOpenXRConfigured)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Give the main camera an initial draw callback that disables camera setup (we don't want it)
|
||||
auto mainCamera = mViewer->getCamera();
|
||||
mainCamera->setName("Main");
|
||||
mainCamera->setInitialDrawCallback(new InitialDrawCallback());
|
||||
|
||||
auto* xr = Environment::get().getManager();
|
||||
xr->realize(context);
|
||||
|
@ -185,16 +172,25 @@ namespace MWVR
|
|||
mSubImages[0].swapchain = mSubImages[1].swapchain = mSwapchain.get();
|
||||
|
||||
mViewer->setReleaseContextAtEndOfFrameHint(false);
|
||||
mViewer->getCamera()->getGraphicsContext()->setSwapCallback(new VRViewer::SwapBuffersCallback(this));
|
||||
|
||||
setupMirrorTexture();
|
||||
Log(Debug::Verbose) << "XR configured";
|
||||
mOpenXRConfigured = true;
|
||||
}
|
||||
|
||||
mainCamera->getGraphicsContext()->setSwapCallback(new VRViewer::SwapBuffersCallback(this));
|
||||
mainCamera->setPreDrawCallback(mPreDraw);
|
||||
mainCamera->setPostDrawCallback(mPostDraw);
|
||||
mainCamera->setCullCallback(new CullCallback);
|
||||
mConfigured = true;
|
||||
void VRViewer::configureCallbacks()
|
||||
{
|
||||
if (mCallbacksConfigured)
|
||||
return;
|
||||
|
||||
Log(Debug::Verbose) << "Realized";
|
||||
// Give the main camera an initial draw callback that disables camera setup (we don't want it)
|
||||
Misc::StereoView::instance().setInitialDrawCallback(new InitialDrawCallback(this));
|
||||
Misc::StereoView::instance().setPredrawCallback(mPreDraw);
|
||||
Misc::StereoView::instance().setPostdrawCallback(mPostDraw);
|
||||
Misc::StereoView::instance().setCullCallback(new CullCallback);
|
||||
|
||||
mCallbacksConfigured = true;
|
||||
}
|
||||
|
||||
void VRViewer::setupMirrorTexture()
|
||||
|
@ -254,9 +250,9 @@ namespace MWVR
|
|||
if (!mMirrorTextureEnabled)
|
||||
return;
|
||||
|
||||
auto* camera = mViewer->getCamera();
|
||||
int screenWidth = camera->getGraphicsContext()->getTraits()->width;
|
||||
int screenHeight = camera->getGraphicsContext()->getTraits()->height;
|
||||
auto* traits = SDLUtil::GraphicsWindowSDL2::findContext(*mViewer)->getTraits();
|
||||
int screenWidth = traits->width;
|
||||
int screenHeight = traits->height;
|
||||
if (!mMirrorTexture)
|
||||
{
|
||||
;
|
||||
|
@ -307,20 +303,35 @@ namespace MWVR
|
|||
RealizeOperation::operator()(
|
||||
osg::GraphicsContext* gc)
|
||||
{
|
||||
return Environment::get().getViewer()->realize(gc);
|
||||
return Environment::get().getViewer()->configureXR(gc);
|
||||
}
|
||||
|
||||
bool
|
||||
RealizeOperation::realized()
|
||||
{
|
||||
return Environment::get().getViewer()->realized();
|
||||
return Environment::get().getViewer()->xrConfigured();
|
||||
}
|
||||
|
||||
void VRViewer::initialDrawCallback(osg::RenderInfo& info)
|
||||
{
|
||||
Environment::get().getSession()->beginPhase(VRSession::FramePhase::Draw);
|
||||
if (Environment::get().getSession()->getFrame(VRSession::FramePhase::Draw)->mShouldRender)
|
||||
mSwapchain->beginFrame(info.getState()->getGraphicsContext());
|
||||
mViewer->getCamera()->setViewport(0, 0, mSwapchainConfig.selectedWidth, mSwapchainConfig.selectedHeight);
|
||||
|
||||
osg::GraphicsOperation* graphicsOperation = info.getCurrentCamera()->getRenderer();
|
||||
osgViewer::Renderer* renderer = dynamic_cast<osgViewer::Renderer*>(graphicsOperation);
|
||||
if (renderer != nullptr)
|
||||
{
|
||||
// Disable normal OSG FBO camera setup
|
||||
renderer->setCameraRequiresSetUp(false);
|
||||
}
|
||||
}
|
||||
|
||||
void VRViewer::preDrawCallback(osg::RenderInfo& info)
|
||||
{
|
||||
if(Environment::get().getSession()->getFrame(VRSession::FramePhase::Draw)->mShouldRender)
|
||||
mSwapchain->beginFrame(info.getState()->getGraphicsContext());
|
||||
mViewer->getCamera()->setViewport(0, 0, mSwapchainConfig.selectedWidth, mSwapchainConfig.selectedHeight);
|
||||
if (Environment::get().getSession()->getFrame(VRSession::FramePhase::Draw)->mShouldRender)
|
||||
mSwapchain->renderBuffer()->bindFramebuffer(info.getState()->getGraphicsContext(), GL_FRAMEBUFFER_EXT);
|
||||
}
|
||||
|
||||
void VRViewer::postDrawCallback(osg::RenderInfo& info)
|
||||
|
@ -336,4 +347,7 @@ namespace MWVR
|
|||
Log(Debug::Warning) << ("osg overwrote predraw");
|
||||
}
|
||||
}
|
||||
VRViewer::InitialDrawCallback::~InitialDrawCallback()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
|
@ -68,7 +68,17 @@ namespace MWVR
|
|||
class InitialDrawCallback : public osg::Camera::DrawCallback
|
||||
{
|
||||
public:
|
||||
virtual void operator()(osg::RenderInfo& renderInfo) const;
|
||||
InitialDrawCallback(VRViewer* viewer)
|
||||
: mViewer(viewer)
|
||||
{}
|
||||
|
||||
~InitialDrawCallback();
|
||||
|
||||
void operator()(osg::RenderInfo& info) const override { mViewer->initialDrawCallback(info); };
|
||||
|
||||
private:
|
||||
|
||||
VRViewer* mViewer;
|
||||
};
|
||||
|
||||
static const std::array<const char*, 2> sViewNames;
|
||||
|
@ -86,19 +96,24 @@ namespace MWVR
|
|||
~VRViewer(void);
|
||||
|
||||
void traversals();
|
||||
void initialDrawCallback(osg::RenderInfo& info);
|
||||
void preDrawCallback(osg::RenderInfo& info);
|
||||
void postDrawCallback(osg::RenderInfo& info);
|
||||
void blitEyesToMirrorTexture(osg::GraphicsContext* gc);
|
||||
void realize(osg::GraphicsContext* gc);
|
||||
bool realized() { return mConfigured; }
|
||||
void configureXR(osg::GraphicsContext* gc);
|
||||
void configureCallbacks();
|
||||
void setupMirrorTexture();
|
||||
void processChangedSettings(const std::set< std::pair<std::string, std::string> >& changed);
|
||||
|
||||
SubImage subImage(Side side);
|
||||
|
||||
bool xrConfigured() { return mOpenXRConfigured; };
|
||||
bool callbacksConfigured() { return mCallbacksConfigured; };
|
||||
|
||||
private:
|
||||
std::mutex mMutex{};
|
||||
bool mConfigured{ false };
|
||||
bool mOpenXRConfigured{ false };
|
||||
bool mCallbacksConfigured{ false };
|
||||
|
||||
osg::ref_ptr<osgViewer::Viewer> mViewer = nullptr;
|
||||
osg::ref_ptr<PredrawCallback> mPreDraw{ nullptr };
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
#include <osgViewer/Viewer>
|
||||
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#include <components/debug/debuglog.hpp>
|
||||
|
||||
|
@ -225,11 +227,18 @@ namespace Misc
|
|||
StereoView* stereoView;
|
||||
};
|
||||
|
||||
StereoView* sInstance = nullptr;
|
||||
|
||||
StereoView& StereoView::instance()
|
||||
{
|
||||
return *sInstance;
|
||||
}
|
||||
|
||||
StereoView::StereoView(osgViewer::Viewer* viewer, Technique technique, osg::Node::NodeMask geometryShaderMask, osg::Node::NodeMask noShaderMask)
|
||||
: osg::Group()
|
||||
, mViewer(viewer)
|
||||
: mViewer(viewer)
|
||||
, mMainCamera(mViewer->getCamera())
|
||||
, mRoot(viewer->getSceneData()->asGroup())
|
||||
, mRoot(mViewer->getSceneData()->asGroup())
|
||||
, mStereoRoot(new osg::Group)
|
||||
, mTechnique(technique)
|
||||
, mGeometryShaderMask(geometryShaderMask)
|
||||
, mNoShaderMask(noShaderMask)
|
||||
|
@ -241,20 +250,13 @@ namespace Misc
|
|||
// Do nothing
|
||||
return;
|
||||
|
||||
mRoot->setDataVariance(osg::Object::STATIC);
|
||||
|
||||
mMasterConfig->_id = "STEREO";
|
||||
mMasterConfig->_master = true;
|
||||
mSlaveConfig->_id = "STEREO";
|
||||
mSlaveConfig->_master = false;
|
||||
|
||||
SceneUtil::FindByNameVisitor findScene("Scene Root");
|
||||
mRoot->accept(findScene);
|
||||
mScene = findScene.mFoundNode;
|
||||
if (!mScene)
|
||||
throw std::logic_error("Couldn't find scene root");
|
||||
|
||||
setName("Stereo Root");
|
||||
mRoot->setDataVariance(osg::Object::STATIC);
|
||||
setDataVariance(osg::Object::STATIC);
|
||||
mLeftCamera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
|
||||
mLeftCamera->setProjectionResizePolicy(osg::Camera::FIXED);
|
||||
mLeftCamera->setProjectionMatrix(osg::Matrix::identity());
|
||||
|
@ -287,6 +289,10 @@ namespace Misc
|
|||
{
|
||||
setupBruteForceTechnique();
|
||||
}
|
||||
|
||||
if (sInstance)
|
||||
throw std::logic_error("Double instance og StereoView");
|
||||
sInstance = this;
|
||||
}
|
||||
|
||||
void StereoView::setupBruteForceTechnique()
|
||||
|
@ -302,8 +308,8 @@ namespace Misc
|
|||
|
||||
if (mSharedShadowMaps)
|
||||
{
|
||||
mLeftCamera->setUserData(mMasterConfig);
|
||||
mRightCamera->setUserData(mSlaveConfig);
|
||||
mLeftCamera->setUserData(mSlaveConfig);
|
||||
mRightCamera->setUserData(mMasterConfig);
|
||||
}
|
||||
|
||||
// Slave cameras must have their viewports defined immediately
|
||||
|
@ -313,8 +319,8 @@ namespace Misc
|
|||
mRightCamera->setViewport(width / 2, 0, width / 2, height);
|
||||
|
||||
mViewer->stopThreading();
|
||||
mViewer->addSlave(mLeftCamera, true);
|
||||
mViewer->addSlave(mRightCamera, true);
|
||||
mViewer->addSlave(mLeftCamera, true);
|
||||
mRightCamera->setGraphicsContext(mViewer->getCamera()->getGraphicsContext());
|
||||
mLeftCamera->setGraphicsContext(mViewer->getCamera()->getGraphicsContext());
|
||||
mViewer->getCamera()->setGraphicsContext(nullptr);
|
||||
|
@ -331,18 +337,18 @@ namespace Misc
|
|||
mRightCamera->setCullMask(mNoShaderMask);
|
||||
mMainCamera->setCullMask(mGeometryShaderMask);
|
||||
|
||||
addChild(mStereoGeometryShaderRoot);
|
||||
mStereoGeometryShaderRoot->addChild(mRoot);
|
||||
addChild(mStereoBruteForceRoot);
|
||||
mStereoRoot->setName("Stereo Root");
|
||||
mStereoRoot->setDataVariance(osg::Object::STATIC);
|
||||
mStereoRoot->addChild(mStereoGeometryShaderRoot);
|
||||
mStereoRoot->addChild(mStereoBruteForceRoot);
|
||||
mStereoBruteForceRoot->addChild(mLeftCamera);
|
||||
mLeftCamera->addChild(mScene); // Use scene directly to avoid redundant shadow computation.
|
||||
mStereoBruteForceRoot->addChild(mRightCamera);
|
||||
mRightCamera->addChild(mScene);
|
||||
|
||||
addCullCallback(new StereoStatesetUpdateCallback(this));
|
||||
mStereoRoot->addCullCallback(new StereoStatesetUpdateCallback(this));
|
||||
|
||||
// Inject self as the root of the scene graph
|
||||
mViewer->setSceneData(this);
|
||||
mStereoGeometryShaderRoot->addChild(mRoot);
|
||||
mViewer->setSceneData(mStereoRoot);
|
||||
}
|
||||
|
||||
void StereoView::update()
|
||||
|
@ -494,6 +500,21 @@ namespace Misc
|
|||
cb = 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();
|
||||
|
@ -553,4 +574,54 @@ namespace Misc
|
|||
near = 1;
|
||||
far = 6656;
|
||||
}
|
||||
|
||||
void StereoView::setInitialDrawCallback(osg::ref_ptr<osg::Camera::DrawCallback> cb)
|
||||
{
|
||||
if (mTechnique == Technique::GeometryShader_IndexedViewports)
|
||||
{
|
||||
mMainCamera->setInitialDrawCallback(cb);
|
||||
}
|
||||
else
|
||||
{
|
||||
mRightCamera->setInitialDrawCallback(cb);
|
||||
}
|
||||
}
|
||||
|
||||
void StereoView::setPredrawCallback(osg::ref_ptr<osg::Camera::DrawCallback> cb)
|
||||
{
|
||||
if (mTechnique == Technique::GeometryShader_IndexedViewports)
|
||||
{
|
||||
mMainCamera->setPreDrawCallback(cb);
|
||||
}
|
||||
else
|
||||
{
|
||||
mLeftCamera->setPreDrawCallback(cb);
|
||||
mRightCamera->setPreDrawCallback(cb);
|
||||
}
|
||||
}
|
||||
|
||||
void StereoView::setPostdrawCallback(osg::ref_ptr<osg::Camera::DrawCallback> cb)
|
||||
{
|
||||
if (mTechnique == Technique::GeometryShader_IndexedViewports)
|
||||
{
|
||||
mMainCamera->setPostDrawCallback(cb);
|
||||
}
|
||||
else
|
||||
{
|
||||
mLeftCamera->setPostDrawCallback(cb);
|
||||
mRightCamera->setPostDrawCallback(cb);
|
||||
}
|
||||
}
|
||||
|
||||
void StereoView::setCullCallback(osg::ref_ptr<osg::NodeCallback> cb)
|
||||
{
|
||||
if (mTechnique == Technique::GeometryShader_IndexedViewports)
|
||||
{
|
||||
mMainCamera->setCullCallback(cb);
|
||||
}
|
||||
else
|
||||
{
|
||||
mRightCamera->setCullCallback(cb);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -68,7 +68,7 @@ namespace Misc
|
|||
};
|
||||
|
||||
//! Represent two eyes. The eyes are in relative terms, and are assumed to lie on the horizon plane.
|
||||
struct StereoView : public osg::Group
|
||||
struct StereoView
|
||||
{
|
||||
struct UpdateViewCallback
|
||||
{
|
||||
|
@ -89,6 +89,8 @@ namespace Misc
|
|||
GeometryShader_IndexedViewports, //!< Frustum camera culls and draws stereo into indexed viewports using an automatically generated geometry shader.
|
||||
};
|
||||
|
||||
static StereoView& instance();
|
||||
|
||||
//! Adds two cameras in stereo to the mainCamera.
|
||||
//! All nodes matching the mask are rendered in stereo using brute force via two camera transforms, the rest are rendered in stereo via a geometry shader.
|
||||
//! \param geometryShaderMask should mask in all nodes that use shaders.
|
||||
|
@ -101,9 +103,24 @@ namespace Misc
|
|||
void update();
|
||||
void updateStateset(osg::StateSet* stateset);
|
||||
|
||||
//! Initialized scene. Call when the "scene root" node has been created
|
||||
void initializeScene();
|
||||
|
||||
//! Callback that updates stereo configuration during the update pass
|
||||
void setUpdateViewCallback(std::shared_ptr<UpdateViewCallback> cb);
|
||||
|
||||
//! Set the initial draw callback on the appropriate camera object
|
||||
void setInitialDrawCallback(osg::ref_ptr<osg::Camera::DrawCallback> cb);
|
||||
|
||||
//! Set the predraw callback on the appropriate camera object
|
||||
void setPredrawCallback(osg::ref_ptr<osg::Camera::DrawCallback> cb);
|
||||
|
||||
//! Set the postdraw callback on the appropriate camera object
|
||||
void setPostdrawCallback(osg::ref_ptr<osg::Camera::DrawCallback> cb);
|
||||
|
||||
//! Set the cull callback on the appropriate camera object
|
||||
void setCullCallback(osg::ref_ptr<osg::NodeCallback> cb);
|
||||
|
||||
private:
|
||||
void setupBruteForceTechnique();
|
||||
void setupGeometryShaderIndexedViewportTechnique();
|
||||
|
@ -112,6 +129,7 @@ namespace Misc
|
|||
osg::ref_ptr<osg::Camera> mMainCamera;
|
||||
osg::ref_ptr<osg::Group> mRoot;
|
||||
osg::ref_ptr<osg::Group> mScene;
|
||||
osg::ref_ptr<osg::Group> mStereoRoot;
|
||||
Technique mTechnique;
|
||||
|
||||
// Keeps state relevant to doing stereo via the geometry shader
|
||||
|
|
Loading…
Reference in a new issue