mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-10-28 23:26:42 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			166 lines
		
	
	
	
		
			5.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			166 lines
		
	
	
	
		
			5.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| #ifndef STEREO_MANAGER_H
 | |
| #define STEREO_MANAGER_H
 | |
| 
 | |
| #include <osg/Camera>
 | |
| #include <osg/Matrix>
 | |
| #include <osg/StateSet>
 | |
| #include <osg/Vec3>
 | |
| #include <osgUtil/CullVisitor>
 | |
| 
 | |
| #include <array>
 | |
| #include <memory>
 | |
| 
 | |
| #include <components/shader/shadermanager.hpp>
 | |
| 
 | |
| #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();
 | |
| 
 | |
|     //! Sets up any definitions necessary for stereo rendering
 | |
|     void shaderStereoDefines(Shader::ShaderManager::DefineMap& defines);
 | |
| 
 | |
|     //! 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;
 | |
|         };
 | |
| 
 | |
|         //! 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();
 | |
| 
 | |
|         //! 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();
 | |
| 
 | |
|         //! 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);
 | |
| 
 | |
|         //! Set the cull callback on the appropriate camera object
 | |
|         void setCullCallback(osg::ref_ptr<osg::NodeCallback> cb);
 | |
| 
 | |
|         osg::Matrixd computeEyeProjection(int view, bool reverseZ) const;
 | |
|         osg::Matrixd computeEyeViewOffset(int view) const;
 | |
| 
 | |
|         const std::shared_ptr<MultiviewFramebuffer>& 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<osgViewer::Viewer> mViewer;
 | |
|         osg::ref_ptr<osg::Camera> mMainCamera;
 | |
|         osg::ref_ptr<osg::Callback> mUpdateCallback;
 | |
|         std::string mError;
 | |
|         osg::Matrixd mMasterProjectionMatrix;
 | |
|         std::shared_ptr<MultiviewFramebuffer> mMultiviewFramebuffer;
 | |
|         bool mEyeResolutionOverriden;
 | |
|         osg::Vec2i mEyeResolutionOverride;
 | |
| 
 | |
|         std::array<View, 2> mView;
 | |
|         std::array<osg::Matrixd, 2> mViewOffsetMatrix;
 | |
|         std::array<osg::Matrixd, 2> mProjectionMatrix;
 | |
|         std::array<osg::Matrixd, 2> mProjectionMatrixReverseZ;
 | |
| 
 | |
|         std::unique_ptr<StereoFrustumManager> mFrustumManager;
 | |
|         std::shared_ptr<UpdateViewCallback> mUpdateViewCallback;
 | |
| 
 | |
|         using Identifier = osgUtil::CullVisitor::Identifier;
 | |
|         osg::ref_ptr<Identifier> mIdentifierMain = new Identifier();
 | |
|         osg::ref_ptr<Identifier> mIdentifierLeft = new Identifier();
 | |
|         osg::ref_ptr<Identifier> mIdentifierRight = new Identifier();
 | |
|     };
 | |
| 
 | |
|     //! Performs stereo-specific initialization operations.
 | |
|     class InitializeStereoOperation final : public osg::GraphicsOperation
 | |
|     {
 | |
|     public:
 | |
|         InitializeStereoOperation();
 | |
| 
 | |
|         void operator()(osg::GraphicsContext* graphicsContext) override;
 | |
|     };
 | |
| }
 | |
| 
 | |
| #endif
 |