1 | // Copyright (C) 2020 The Qt Company Ltd. |
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only |
3 | |
4 | #ifndef QQUICK3DSHADERUTILS_H |
5 | #define QQUICK3DSHADERUTILS_H |
6 | |
7 | // |
8 | // W A R N I N G |
9 | // ------------- |
10 | // |
11 | // This file is not part of the Qt API. It exists purely as an |
12 | // implementation detail. This header file may change from version to |
13 | // version without notice, or even be removed. |
14 | // |
15 | // We mean it. |
16 | // |
17 | |
18 | #include <QtQuick3D/qtquick3dglobal.h> |
19 | #include <QtQuick3D/private/qquick3dobject_p.h> |
20 | #include <QtQuick3D/private/qquick3dtexture_p.h> |
21 | #include <QtQuick3D/private/qquick3dmaterial_p.h> |
22 | |
23 | #include <QtQuick3DUtils/private/qssgrenderbasetypes_p.h> |
24 | |
25 | #include <QtQuick3DRuntimeRender/private/qssgrendercommands_p.h> |
26 | |
27 | QT_BEGIN_NAMESPACE |
28 | |
29 | class QQuick3DShaderUtilsShader; |
30 | class QQmlContext; |
31 | |
32 | namespace QSSGShaderUtils { |
33 | |
34 | using MetaTypeList = QList<QMetaType::Type>; |
35 | using ResolveFunction = bool (*)(const QUrl &url, const QQmlContext *context, QByteArray &shaderData, QByteArray &shaderPathKey); |
36 | Q_QUICK3D_EXPORT void setResolveFunction(ResolveFunction fn); |
37 | Q_QUICK3D_EXPORT QByteArray resolveShader(const QUrl &fileUrl, const QQmlContext *context, QByteArray &shaderPathKey); |
38 | Q_QUICK3D_EXPORT MetaTypeList supportedMetatypes(); |
39 | |
40 | |
41 | template<QMetaType::Type> |
42 | struct ShaderType |
43 | { |
44 | }; |
45 | |
46 | Q_QUICK3D_EXPORT QByteArray uniformTypeName(QMetaType type); |
47 | Q_QUICK3D_EXPORT QByteArray uniformTypeName(QSSGRenderShaderValue::Type type); |
48 | Q_QUICK3D_EXPORT QSSGRenderShaderValue::Type uniformType(QMetaType type); |
49 | } |
50 | |
51 | class Q_QUICK3D_EXPORT QQuick3DShaderUtilsTextureInput : public QObject |
52 | { |
53 | Q_OBJECT |
54 | Q_PROPERTY(QQuick3DTexture *texture READ texture WRITE setTexture NOTIFY textureChanged) |
55 | Q_PROPERTY(bool enabled MEMBER enabled NOTIFY enabledChanged) |
56 | |
57 | QML_NAMED_ELEMENT(TextureInput) |
58 | |
59 | public: |
60 | explicit QQuick3DShaderUtilsTextureInput(QObject *p = nullptr); |
61 | virtual ~QQuick3DShaderUtilsTextureInput(); |
62 | QQuick3DTexture *m_texture = nullptr; |
63 | bool enabled = true; |
64 | QByteArray name; |
65 | QQuick3DTexture *texture() const |
66 | { |
67 | return m_texture; |
68 | } |
69 | |
70 | public Q_SLOTS: |
71 | void setTexture(QQuick3DTexture *texture); |
72 | |
73 | Q_SIGNALS: |
74 | void textureChanged(); |
75 | void enabledChanged(); |
76 | }; |
77 | |
78 | class Q_QUICK3D_EXPORT QQuick3DShaderUtilsBuffer : public QObject |
79 | { |
80 | Q_OBJECT |
81 | Q_PROPERTY(TextureFormat format READ format WRITE setFormat) |
82 | Q_PROPERTY(TextureFilterOperation textureFilterOperation READ textureFilterOperation WRITE setTextureFilterOperation) |
83 | Q_PROPERTY(TextureCoordOperation textureCoordOperation READ textureCoordOperation WRITE setTextureCoordOperation) |
84 | Q_PROPERTY(float sizeMultiplier MEMBER sizeMultiplier) |
85 | Q_PROPERTY(AllocateBufferFlagValues bufferFlags READ bufferFlags WRITE setBufferFlags) |
86 | Q_PROPERTY(QByteArray name MEMBER name) |
87 | |
88 | QML_NAMED_ELEMENT(Buffer) |
89 | |
90 | public: |
91 | QQuick3DShaderUtilsBuffer() = default; |
92 | ~QQuick3DShaderUtilsBuffer() override = default; |
93 | |
94 | enum class TextureFilterOperation // must match QSSGRenderTextureFilterOp |
95 | { |
96 | Unknown = 0, |
97 | Nearest, |
98 | Linear |
99 | }; |
100 | Q_ENUM(TextureFilterOperation) |
101 | |
102 | enum class TextureCoordOperation // must match QSSGRenderTextureCoordOp |
103 | { |
104 | Unknown = 0, |
105 | ClampToEdge, |
106 | MirroredRepeat, |
107 | Repeat |
108 | }; |
109 | Q_ENUM(TextureCoordOperation) |
110 | |
111 | enum class AllocateBufferFlagValues |
112 | { |
113 | None = 0, |
114 | SceneLifetime = 1 |
115 | }; |
116 | Q_ENUM(AllocateBufferFlagValues) |
117 | |
118 | enum class TextureFormat { |
119 | Unknown = 0, |
120 | RGBA8, |
121 | RGBA16F, |
122 | RGBA32F, |
123 | R8, |
124 | R16, |
125 | R16F, |
126 | R32F |
127 | }; |
128 | Q_ENUM(TextureFormat) |
129 | |
130 | QSSGAllocateBuffer command {}; |
131 | TextureFilterOperation textureFilterOperation() const { return TextureFilterOperation(command.m_filterOp); } |
132 | void setTextureFilterOperation(TextureFilterOperation op) { command.m_filterOp = QSSGRenderTextureFilterOp(op); } |
133 | |
134 | TextureCoordOperation textureCoordOperation() const { return TextureCoordOperation(command.m_texCoordOp); } |
135 | void setTextureCoordOperation(TextureCoordOperation texCoordOp) { command.m_texCoordOp = QSSGRenderTextureCoordOp(texCoordOp); } |
136 | float &sizeMultiplier = command.m_sizeMultiplier; |
137 | QSSGCommand *getCommand() { return &command; } |
138 | |
139 | TextureFormat format() const; |
140 | void setFormat(TextureFormat format); |
141 | |
142 | AllocateBufferFlagValues bufferFlags() const { return AllocateBufferFlagValues(int(command.m_bufferFlags)); } |
143 | void setBufferFlags(AllocateBufferFlagValues flag) { command.m_bufferFlags = quint32(flag);} |
144 | |
145 | QByteArray &name = command.m_name; |
146 | |
147 | static QSSGRenderTextureFormat::Format mapTextureFormat(QQuick3DShaderUtilsBuffer::TextureFormat fmt); |
148 | static QQuick3DShaderUtilsBuffer::TextureFormat mapRenderTextureFormat(QSSGRenderTextureFormat::Format fmt); |
149 | }; |
150 | |
151 | class Q_QUICK3D_EXPORT QQuick3DShaderUtilsRenderCommand : public QObject |
152 | { |
153 | Q_OBJECT |
154 | |
155 | QML_NAMED_ELEMENT(Command) |
156 | |
157 | public: |
158 | QQuick3DShaderUtilsRenderCommand() = default; |
159 | ~QQuick3DShaderUtilsRenderCommand() override = default; |
160 | virtual QSSGCommand *getCommand() { Q_ASSERT(0); return nullptr; } |
161 | virtual int bufferCount() const { return 0; } |
162 | virtual QQuick3DShaderUtilsBuffer *bufferAt(int idx) const { Q_UNUSED(idx); return nullptr; } |
163 | }; |
164 | |
165 | class Q_QUICK3D_EXPORT QQuick3DShaderUtilsBufferInput : public QQuick3DShaderUtilsRenderCommand |
166 | { |
167 | Q_OBJECT |
168 | Q_PROPERTY(QQuick3DShaderUtilsBuffer *buffer READ buffer WRITE setBuffer) |
169 | Q_PROPERTY(QByteArray sampler MEMBER sampler) |
170 | |
171 | QML_NAMED_ELEMENT(BufferInput) |
172 | |
173 | public: |
174 | QQuick3DShaderUtilsBufferInput() = default; |
175 | ~QQuick3DShaderUtilsBufferInput() override = default; |
176 | QSSGApplyBufferValue command { QByteArray(), QByteArray() }; |
177 | QByteArray &sampler = command.m_samplerName; |
178 | QSSGCommand *getCommand() override { return &command; } |
179 | |
180 | int bufferCount() const override { return (m_buffer != nullptr) ? 1 : 0; } |
181 | QQuick3DShaderUtilsBuffer *bufferAt(int idx) const override |
182 | { |
183 | Q_ASSERT(idx < 1 && idx >= 0); |
184 | return (m_buffer && idx == 0) ? m_buffer : nullptr; |
185 | } |
186 | |
187 | QQuick3DShaderUtilsBuffer *buffer() const { return m_buffer; } |
188 | void setBuffer(QQuick3DShaderUtilsBuffer *buffer) { |
189 | if (m_buffer == buffer) |
190 | return; |
191 | |
192 | if (buffer) { |
193 | Q_ASSERT(!buffer->name.isEmpty()); |
194 | command.m_bufferName = buffer->name; |
195 | } |
196 | m_buffer = buffer; |
197 | } |
198 | |
199 | QQuick3DShaderUtilsBuffer *m_buffer = nullptr; |
200 | |
201 | }; |
202 | |
203 | class Q_QUICK3D_EXPORT QQuick3DShaderUtilsApplyValue : public QQuick3DShaderUtilsRenderCommand |
204 | { |
205 | Q_OBJECT |
206 | Q_PROPERTY(QByteArray target MEMBER target) |
207 | Q_PROPERTY(QVariant value MEMBER value) |
208 | |
209 | QML_NAMED_ELEMENT(SetUniformValue) |
210 | |
211 | public: |
212 | QQuick3DShaderUtilsApplyValue() = default; |
213 | ~QQuick3DShaderUtilsApplyValue() override = default; |
214 | QSSGCommand *getCommand() override { return &command; } |
215 | QSSGApplyValue command { }; |
216 | QVariant &value = command.m_value; |
217 | QByteArray &target = command.m_propertyName; |
218 | }; |
219 | |
220 | class Q_QUICK3D_EXPORT QQuick3DShaderUtilsRenderPass : public QObject |
221 | { |
222 | Q_OBJECT |
223 | Q_PROPERTY(QQmlListProperty<QQuick3DShaderUtilsRenderCommand> commands READ commands) |
224 | Q_PROPERTY(QQuick3DShaderUtilsBuffer *output MEMBER outputBuffer) |
225 | Q_PROPERTY(QQmlListProperty<QQuick3DShaderUtilsShader> shaders READ shaders) |
226 | |
227 | QML_NAMED_ELEMENT(Pass) |
228 | |
229 | public: |
230 | QQuick3DShaderUtilsRenderPass() = default; |
231 | ~QQuick3DShaderUtilsRenderPass() override = default; |
232 | |
233 | static void qmlAppendCommand(QQmlListProperty<QQuick3DShaderUtilsRenderCommand> *list, QQuick3DShaderUtilsRenderCommand *command); |
234 | static QQuick3DShaderUtilsRenderCommand *qmlCommandAt(QQmlListProperty<QQuick3DShaderUtilsRenderCommand> *list, qsizetype index); |
235 | static qsizetype qmlCommandCount(QQmlListProperty<QQuick3DShaderUtilsRenderCommand> *list); |
236 | static void qmlCommandClear(QQmlListProperty<QQuick3DShaderUtilsRenderCommand> *list); |
237 | |
238 | static void qmlAppendShader(QQmlListProperty<QQuick3DShaderUtilsShader> *list, QQuick3DShaderUtilsShader *shader); |
239 | static QQuick3DShaderUtilsShader *qmlShaderAt(QQmlListProperty<QQuick3DShaderUtilsShader> *list, qsizetype index); |
240 | static qsizetype qmlShaderCount(QQmlListProperty<QQuick3DShaderUtilsShader> *list); |
241 | static void qmlShaderClear(QQmlListProperty<QQuick3DShaderUtilsShader> *list); |
242 | |
243 | QQmlListProperty<QQuick3DShaderUtilsRenderCommand> commands(); |
244 | QVector<QQuick3DShaderUtilsRenderCommand *> m_commands; |
245 | QQuick3DShaderUtilsBuffer *outputBuffer = nullptr; |
246 | QQmlListProperty<QQuick3DShaderUtilsShader> shaders(); |
247 | QVarLengthArray<QQuick3DShaderUtilsShader *, 2> m_shaders; |
248 | |
249 | Q_SIGNALS: |
250 | void changed(); |
251 | }; |
252 | |
253 | class Q_QUICK3D_EXPORT QQuick3DShaderUtilsShader : public QObject |
254 | { |
255 | Q_OBJECT |
256 | Q_PROPERTY(QUrl shader MEMBER shader NOTIFY shaderChanged) |
257 | Q_PROPERTY(Stage stage MEMBER stage NOTIFY stageChanged) |
258 | |
259 | QML_NAMED_ELEMENT(Shader) |
260 | |
261 | public: |
262 | QQuick3DShaderUtilsShader() = default; |
263 | virtual ~QQuick3DShaderUtilsShader() = default; |
264 | enum class Stage : quint8 |
265 | { |
266 | Vertex = 0, |
267 | Fragment = 1 |
268 | }; |
269 | Q_ENUM(Stage) |
270 | |
271 | QUrl shader; |
272 | Stage stage = Stage::Fragment; |
273 | |
274 | Q_SIGNALS: |
275 | void shaderChanged(); |
276 | void stageChanged(); |
277 | }; |
278 | |
279 | QT_END_NAMESPACE |
280 | |
281 | #endif // QQUICK3DSHADERUTILS_H |
282 | |