File: multiview.hpp

package info (click to toggle)
openmw 0.49.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 33,992 kB
  • sloc: cpp: 372,479; xml: 2,149; sh: 1,403; python: 797; makefile: 26
file content (159 lines) | stat: -rw-r--r-- 6,256 bytes parent folder | download
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