| 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 | Q_DECLARE_OPAQUE_POINTER(QQuick3DShaderUtilsTextureInput) | 
|---|
| 282 |  | 
|---|
| 283 | #endif // QQUICK3DSHADERUTILS_H | 
|---|
| 284 |  | 
|---|