You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
openmw/components/stereo/stereomanager.hpp

134 lines
4.4 KiB
C++

#ifndef STEREO_MANAGER_H
#define STEREO_MANAGER_H
#include <osg/Matrix>
#include <osg/Vec3>
#include <osg/Camera>
#include <osg/StateSet>
#include <osgUtil/CullVisitor>
#include <memory>
#include <array>
#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();
//! 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<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;
//! 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.
//! 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();
};
}
#endif