#ifndef STEREO_MANAGER_H #define STEREO_MANAGER_H #include #include #include #include #include #include #include #include #include "types.hpp" namespace osg { class FrameBufferObject; class Texture2D; class Texture2DArray; } namespace osgViewer { class Viewer; } namespace SceneUtil { class MWShadowTechnique; } namespace Stereo { class MultiviewFramebuffer; class StereoFrustumManager; class MultiviewStereoStatesetUpdateCallback; bool getStereo(); //! Class that provides tools for managing stereo mode class Manager { public: struct UpdateViewCallback { virtual ~UpdateViewCallback() = default; //! Called during the update traversal of every frame to update stereo views. virtual void updateView(View& left, View& right) = 0; }; //! Gets the singleton instance static Manager& instance(); Manager(osgViewer::Viewer* viewer); ~Manager(); //! Called during update traversal void update(); void initializeStereo(osg::GraphicsContext* gc); //! Callback that updates stereo configuration during the update pass void setUpdateViewCallback(std::shared_ptr cb); //! Set the cull callback on the appropriate camera object void setCullCallback(osg::ref_ptr cb); 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() { return mMultiviewFramebuffer; }; //! Sets rendering resolution of each eye to eyeResolution. //! Once set, there will no longer be any connection between rendering resolution and screen/window resolution. void overrideEyeResolution(const osg::Vec2i& eyeResolution); //! Notify stereo manager that the screen/window resolution has changed. void screenResolutionChanged(); //! Get current eye resolution osg::Vec2i eyeResolution(); //! The projection intended for rendering. When reverse Z is enabled, this is not the same as the camera's projection matrix, //! and therefore must be provided to the manager explicitly. void setMasterProjectionMatrix(const osg::Matrixd& projectionMatrix) { mMasterProjectionMatrix = projectionMatrix; } //! Causes the subgraph represented by the node to draw to the full viewport. //! This has no effect if stereo is not enabled void disableStereoForNode(osg::Node* node); void setShadowTechnique(SceneUtil::MWShadowTechnique* shadowTechnique); /// Determine which view the cull visitor belongs to Eye getEye(const osgUtil::CullVisitor* cv) const; private: friend class MultiviewStereoStatesetUpdateCallback; void updateMultiviewStateset(osg::StateSet* stateset); void updateStereoFramebuffer(); void setupBruteForceTechnique(); void setupOVRMultiView2Technique(); osg::ref_ptr mViewer; osg::ref_ptr mMainCamera; osg::ref_ptr mUpdateCallback; std::string mError; osg::Matrixd mMasterProjectionMatrix; std::shared_ptr mMultiviewFramebuffer; bool mEyeResolutionOverriden; osg::Vec2i mEyeResolutionOverride; std::array mView; std::array mViewOffsetMatrix; std::array mProjectionMatrix; std::array mProjectionMatrixReverseZ; std::unique_ptr mFrustumManager; std::shared_ptr mUpdateViewCallback; using Identifier = osgUtil::CullVisitor::Identifier; osg::ref_ptr mIdentifierMain = new Identifier(); osg::ref_ptr mIdentifierLeft = new Identifier(); osg::ref_ptr mIdentifierRight = new Identifier(); }; } #endif