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
27QT_BEGIN_NAMESPACE
28
29class QQuick3DShaderUtilsShader;
30class QQmlContext;
31
32namespace QSSGShaderUtils {
33
34using MetaTypeList = QList<QMetaType::Type>;
35using ResolveFunction = bool (*)(const QUrl &url, const QQmlContext *context, QByteArray &shaderData, QByteArray &shaderPathKey);
36Q_QUICK3D_EXPORT void setResolveFunction(ResolveFunction fn);
37Q_QUICK3D_EXPORT QByteArray resolveShader(const QUrl &fileUrl, const QQmlContext *context, QByteArray &shaderPathKey);
38Q_QUICK3D_EXPORT MetaTypeList supportedMetatypes();
39
40
41template<QMetaType::Type>
42struct ShaderType
43{
44};
45
46Q_QUICK3D_EXPORT QByteArray uniformTypeName(QMetaType type);
47Q_QUICK3D_EXPORT QByteArray uniformTypeName(QSSGRenderShaderValue::Type type);
48Q_QUICK3D_EXPORT QSSGRenderShaderValue::Type uniformType(QMetaType type);
49}
50
51class 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
59public:
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
70public Q_SLOTS:
71 void setTexture(QQuick3DTexture *texture);
72
73Q_SIGNALS:
74 void textureChanged();
75 void enabledChanged();
76};
77
78class 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
90public:
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
151class Q_QUICK3D_EXPORT QQuick3DShaderUtilsRenderCommand : public QObject
152{
153 Q_OBJECT
154
155 QML_NAMED_ELEMENT(Command)
156
157public:
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
165class 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
173public:
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
203class 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
211public:
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
220class 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
229public:
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
249Q_SIGNALS:
250 void changed();
251};
252
253class 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
261public:
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
274Q_SIGNALS:
275 void shaderChanged();
276 void stageChanged();
277};
278
279QT_END_NAMESPACE
280
281#endif // QQUICK3DSHADERUTILS_H
282

source code of qtquick3d/src/quick3d/qquick3dshaderutils_p.h