summaryrefslogtreecommitdiffstats
path: root/src/Runtime/Source/Qt3DSRuntimeRender/Include/Qt3DSRenderEffectSystem.h
blob: 119564da9793b1d5e18357c2bfb77a61e2f6d957 (plain)
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
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
/****************************************************************************
**
** Copyright (C) 2008-2012 NVIDIA Corporation.
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt 3D Studio.
**
** $QT_BEGIN_LICENSE:GPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 or (at your option) any later version
** approved by the KDE Free Qt Foundation. The licenses are as published by
** the Free Software Foundation and appearing in the file LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#pragma once
#ifndef QT3DS_RENDER_EFFECT_SYSTEM_H
#define QT3DS_RENDER_EFFECT_SYSTEM_H
#include "Qt3DSRender.h"
#include "foundation/Qt3DSRefCounted.h"
#include "render/Qt3DSRenderBaseTypes.h"
#include "foundation/StringTable.h"
#include "foundation/Qt3DSVec2.h"
#include "Qt3DSRenderDynamicObjectSystem.h"

namespace qt3ds {
namespace render {
    struct SEffect;
    struct SEffectContext;
    namespace dynamic {
        struct SCommand; // UICRenderEffectCommands.h
    }

    struct SEffectRenderArgument
    {
        SEffect &m_Effect;
        NVRenderTexture2D &m_ColorBuffer;
        // Some effects need the camera near and far ranges.
        QT3DSVec2 m_CameraClipRange;
        // Some effects require the depth buffer from the rendering of thelayer
        // most do not.
        NVRenderTexture2D *m_DepthTexture;
        // this is a depth preapass texture we need for some effects like bloom
        // actually we need the stencil values
        NVRenderTexture2D *m_DepthStencilBuffer;

        SEffectRenderArgument(SEffect &inEffect, NVRenderTexture2D &inColorBuffer,
                              const QT3DSVec2 &inCameraClipRange,
                              NVRenderTexture2D *inDepthTexture = NULL,
                              NVRenderTexture2D *inDepthBuffer = NULL)
            : m_Effect(inEffect)
            , m_ColorBuffer(inColorBuffer)
            , m_CameraClipRange(inCameraClipRange)
            , m_DepthTexture(inDepthTexture)
            , m_DepthStencilBuffer(inDepthBuffer)
        {
        }
    };

    class IEffectSystemCore : public NVRefCounted
    {
    public:
        virtual bool IsEffectRegistered(CRegisteredString inStr) = 0;
        virtual NVConstDataRef<CRegisteredString> GetRegisteredEffects() = 0;
        // Register an effect class that uses exactly these commands to render.
        // Effect properties cannot change after the effect is created because that would invalidate
        // existing effect instances.
        // Effect commands, which are stored on the effect class, can change.
        virtual bool RegisterEffect(CRegisteredString inName,
                                    NVConstDataRef<dynamic::SPropertyDeclaration> inProperties) = 0;

        virtual bool UnregisterEffect(CRegisteredString inName) = 0;

        // Shorthand method that creates an effect and auto-generates the effect commands like such:
        // BindShader(inPathToEffect)
        // foreach( propdec in inProperties ) ApplyValue( propDecType )
        // ApplyShader()
        virtual bool
        RegisterGLSLEffect(CRegisteredString inName, const char8_t *inPathToEffect,
                           NVConstDataRef<dynamic::SPropertyDeclaration> inProperties) = 0;
        // Set the default value.  THis is unnecessary if the default is zero as that is what it is
        // assumed to be.
        virtual void SetEffectPropertyDefaultValue(CRegisteredString inName,
                                                   CRegisteredString inPropName,
                                                   NVConstDataRef<QT3DSU8> inDefaultData) = 0;
        virtual void SetEffectPropertyEnumNames(CRegisteredString inName,
                                                CRegisteredString inPropName,
                                                NVConstDataRef<CRegisteredString> inNames) = 0;
        virtual NVConstDataRef<CRegisteredString>
        GetEffectPropertyEnumNames(CRegisteredString inName,
                                   CRegisteredString inPropName) const = 0;

        virtual NVConstDataRef<dynamic::SPropertyDefinition>
        GetEffectProperties(CRegisteredString inEffectName) const = 0;

        virtual void SetEffectPropertyTextureSettings(
            CRegisteredString inEffectName, CRegisteredString inPropName,
            CRegisteredString inPropPath, NVRenderTextureTypeValue::Enum inTexType,
            NVRenderTextureCoordOp::Enum inCoordOp, NVRenderTextureMagnifyingOp::Enum inMagFilterOp,
            NVRenderTextureMinifyingOp::Enum inMinFilterOp) = 0;

        // Setting the effect commands also sets this as if there isn't a specific "apply depth
        // value"
        // command then this effect does not require the depth texture.
        // So the setter here is completely optional.
        virtual void SetEffectRequiresDepthTexture(CRegisteredString inEffectName,
                                                   bool inValue) = 0;
        virtual bool DoesEffectRequireDepthTexture(CRegisteredString inEffectName) const = 0;

        virtual void SetEffectRequiresCompilation(CRegisteredString inEffectName,
                                                  bool inValue) = 0;
        virtual bool DoesEffectRequireCompilation(CRegisteredString inEffectName) const = 0;

        // The effect commands are the actual commands that run for a given effect.  The tell the
        // system exactly
        // explicitly things like bind this shader, bind this render target, apply this property,
        // run this shader
        // See UICRenderEffectCommands.h for the list of commands.
        // These commands are copied into the effect.
        virtual void SetEffectCommands(CRegisteredString inEffectName,
                                       NVConstDataRef<dynamic::SCommand *> inCommands) = 0;
        virtual NVConstDataRef<dynamic::SCommand *>
        GetEffectCommands(CRegisteredString inEffectName) const = 0;

        // Set the shader data for a given path.  Used when a path doesn't correspond to a file but
        // the data has been
        // auto-generated.  The system will look for data under this path key during the BindShader
        // effect command.
        virtual void SetShaderData(CRegisteredString inPath, const char8_t *inData,
                                   const char8_t *inShaderType = NULL,
                                   const char8_t *inShaderVersion = NULL,
                                   bool inHasGeomShader = false,
                                   bool inIsComputeShader = false) = 0;

        // An effect instance is just a property bag along with the name of the effect to run.
        // This instance is what is placed into the object graph.
        virtual SEffect *CreateEffectInstance(CRegisteredString inEffectName,
                                              NVAllocatorCallback &inSceneGraphAllocator) = 0;

        virtual void Save(qt3ds::render::SWriteBuffer &ioBuffer,
                          const qt3ds::render::SStrRemapMap &inRemapMap,
                          const char8_t *inProjectDir) const = 0;
        virtual void Load(NVDataRef<QT3DSU8> inData, CStrTableOrDataRef inStrDataBlock,
                          const char8_t *inProjectDir) = 0;

        virtual IEffectSystem &GetEffectSystem(IQt3DSRenderContext &context) = 0;

        virtual IResourceManager &GetResourceManager() = 0;

        static IEffectSystemCore &CreateEffectSystemCore(IQt3DSRenderContextCore &context);
    };

    /**
      * An effect is essentially a function that takes a image and produces a new image.  The source
      *and dest images
      *	aren't guaranteed to be the same size, the effect may enlarge or shrink the result.
      * A specialization is when you want the effect to render to the final render target instead of
      *to a separate image.
      * In this case the effect cannot enlarge or shrink the final target and it will render to the
      *destination buffer
      *	using the given MVP.
      */
    class IEffectSystem : public IEffectSystemCore
    {
    protected:
        virtual ~IEffectSystem() {}

    public:
        // Calling release effect context with no context results in no problems.
        virtual void ReleaseEffectContext(SEffectContext *inEffect) = 0;

        // If the effect has a context you can call this to clear persistent buffers back to their
        // original value.
        virtual void ResetEffectFrameData(SEffectContext &inContext) = 0;

        // Render this effect.  Returns false in the case the effect wasn't rendered and the render
        // state
        // is guaranteed to be the same as before.
        // The texture returned is allocated using the resource manager, and it is up to the caller
        // to deallocate it or return it to the temporary pool if items when necessary
        // Pass in true if you want the result image premultiplied.  Most of the functions in the
        // system
        // assume non-premultiplied color for images so probably this is false.
        virtual NVRenderTexture2D *RenderEffect(SEffectRenderArgument inRenderArgument) = 0;

        // Render the effect to the currently bound render target using this MVP and optionally
        // enabling blending when rendering to the target
        virtual bool RenderEffect(SEffectRenderArgument inRenderArgument, QT3DSMat44 &inMVP,
                                  bool inEnableBlendWhenRenderToTarget) = 0;
    };
}
}
#endif