1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
|
#ifndef STEREO_MULTIVIEW_H
#define STEREO_MULTIVIEW_H
#include <osg/Camera>
#include <osg/FrameBufferObject>
#include <osg/GL>
#include <osg/ref_ptr>
#include <array>
#include <memory>
namespace osg
{
class FrameBufferObject;
class Texture;
class Texture2D;
class Texture2DArray;
}
namespace osgUtil
{
class RenderStage;
}
namespace Stereo
{
class UpdateRenderStagesCallback;
//! Check if TextureView is supported. Results are undefined if called before configureExtensions().
bool getTextureViewSupported();
//! Check if Multiview should be used. Results are undefined if called before configureExtensions().
bool getMultiview();
//! Use the provided context to check what extensions are supported and configure use of multiview based on
//! extensions and settings.
void configureExtensions(unsigned int contextID, bool enableMultiview);
//! Sets the appropriate vertex buffer hint on OSG's display settings if needed
void setVertexBufferHint(bool enableMultiview, bool allowDisplayListsForMultiview);
//! Creates a Texture2D as a texture view into a Texture2DArray
osg::ref_ptr<osg::Texture2D> createTextureView_Texture2DFromTexture2DArray(
osg::Texture2DArray* textureArray, int layer);
//! Class that manages the specifics of GL_OVR_Multiview aware framebuffers, separating the layers into separate
//! framebuffers, and disabling
class MultiviewFramebuffer
{
public:
MultiviewFramebuffer(int width, int height, int samples);
~MultiviewFramebuffer();
void attachColorComponent(GLint sourceFormat, GLint sourceType, GLint internalFormat);
void attachDepthComponent(GLint sourceFormat, GLint sourceType, GLint internalFormat);
osg::FrameBufferObject* multiviewFbo();
osg::FrameBufferObject* layerFbo(int i);
osg::FrameBufferObject* layerMsaaFbo(int i);
osg::Texture2DArray* multiviewColorBuffer();
osg::Texture2DArray* multiviewDepthBuffer();
osg::Texture2D* layerColorBuffer(int i);
osg::Texture2D* layerDepthBuffer(int i);
void attachTo(osg::Camera* camera);
void detachFrom(osg::Camera* camera);
int width() const { return mWidth; }
int height() const { return mHeight; }
int samples() const { return mSamples; }
private:
osg::Texture2D* createTexture(GLint sourceFormat, GLint sourceType, GLint internalFormat);
osg::Texture2DArray* createTextureArray(GLint sourceFormat, GLint sourceType, GLint internalFormat);
int mWidth;
int mHeight;
int mSamples;
bool mMultiview;
osg::ref_ptr<UpdateRenderStagesCallback> mCullCallback;
osg::ref_ptr<osg::FrameBufferObject> mMultiviewFbo;
std::array<osg::ref_ptr<osg::FrameBufferObject>, 2> mLayerFbo;
std::array<osg::ref_ptr<osg::FrameBufferObject>, 2> mLayerMsaaFbo;
osg::ref_ptr<osg::Texture2DArray> mMultiviewColorTexture;
osg::ref_ptr<osg::Texture2DArray> mMultiviewDepthTexture;
std::array<osg::ref_ptr<osg::Texture2D>, 2> mColorTexture;
std::array<osg::ref_ptr<osg::Texture2D>, 2> mDepthTexture;
};
//! Sets up a draw callback on the render stage that performs the MSAA resolve operation
void setMultiviewMSAAResolveCallback(osgUtil::RenderStage* renderStage);
//! Sets up or updates multiview matrices for the given stateset
void setMultiviewMatrices(
osg::StateSet* stateset, const std::array<osg::Matrix, 2>& projection, bool createInverseMatrices = false);
//! Sets the width/height of a texture by first down-casting it to the appropriate type. Sets depth to 2 always for
//! Texture2DArray and Texture2DMultisampleArray.
void setMultiviewCompatibleTextureSize(osg::Texture* tex, int w, int h);
//! Creates a texture (Texture2D, Texture2DMultisample, Texture2DArray, or Texture2DMultisampleArray) based on
//! multiview settings and sample count.
osg::ref_ptr<osg::Texture> createMultiviewCompatibleTexture(int width, int height, int samples);
//! Returns a framebuffer attachment from the texture, returning a multiview attachment if the texture is one of
//! Texture2DArray or Texture2DMultisampleArray
osg::FrameBufferAttachment createMultiviewCompatibleAttachment(osg::Texture* tex);
//! If OSG has multiview, returns the magic number used to tell OSG to create a multiview attachment. Otherwise
//! returns 0.
unsigned int osgFaceControlledByMultiviewShader();
//! Implements resolving a multisamples multiview framebuffer. Does not automatically reflect changes to the fbo
//! attachments, must call dirty() when the fbo attachments change.
class MultiviewFramebufferResolve
{
public:
MultiviewFramebufferResolve(
osg::FrameBufferObject* msaaFbo, osg::FrameBufferObject* resolveFbo, GLbitfield blitMask);
void resolveImplementation(osg::State& state);
void dirty() { mDirtyLayers = true; }
const osg::FrameBufferObject* resolveFbo() const { return mResolveFbo; }
const osg::FrameBufferObject* msaaFbo() const { return mMsaaFbo; }
void setResolveFbo(osg::FrameBufferObject* resolveFbo);
void setMsaaFbo(osg::FrameBufferObject* msaaFbo);
private:
void setupLayers();
osg::ref_ptr<osg::FrameBufferObject> mResolveFbo;
std::array<osg::ref_ptr<osg::FrameBufferObject>, 2> mResolveLayers{};
osg::ref_ptr<osg::FrameBufferObject> mMsaaFbo;
std::array<osg::ref_ptr<osg::FrameBufferObject>, 2> mMsaaLayers{};
GLbitfield mBlitMask;
bool mDirtyLayers = true;
int mWidth = -1;
int mHeight = -1;
};
//! Wrapper for osg::CullSettings::InitialFrustumCallback, to avoid exposing osg multiview interfaces outside of
//! multiview.cpp
struct InitialFrustumCallback
{
InitialFrustumCallback(osg::Camera* camera);
virtual ~InitialFrustumCallback();
virtual void setInitialFrustum(
osg::CullStack& cullStack, osg::BoundingBoxd& bb, bool& nearCulling, bool& farCulling) const = 0;
osg::observer_ptr<osg::Camera> mCamera;
};
}
#endif
|