1 /**************************************************************************** 2 ** 3 ** Copyright (C) 2020 The Qt Company Ltd. 4 ** Contact: https://www.qt.io/licensing/ 5 ** 6 ** This file is part of Qt Quick 3D. 7 ** 8 ** $QT_BEGIN_LICENSE:GPL$ 9 ** Commercial License Usage 10 ** Licensees holding valid commercial Qt licenses may use this file in 11 ** accordance with the commercial license agreement provided with the 12 ** Software or, alternatively, in accordance with the terms contained in 13 ** a written agreement between you and The Qt Company. For licensing terms 14 ** and conditions see https://www.qt.io/terms-conditions. For further 15 ** information use the contact form at https://www.qt.io/contact-us. 16 ** 17 ** GNU General Public License Usage 18 ** Alternatively, this file may be used under the terms of the GNU 19 ** General Public License version 3 or (at your option) any later version 20 ** approved by the KDE Free Qt Foundation. The licenses are as published by 21 ** the Free Software Foundation and appearing in the file LICENSE.GPL3 22 ** included in the packaging of this file. Please review the following 23 ** information to ensure the GNU General Public License requirements will 24 ** be met: https://www.gnu.org/licenses/gpl-3.0.html. 25 ** 26 ** $QT_END_LICENSE$ 27 ** 28 ****************************************************************************/ 29 30 #ifndef QQUICK3DSHADERUTILS_H 31 #define QQUICK3DSHADERUTILS_H 32 33 // 34 // W A R N I N G 35 // ------------- 36 // 37 // This file is not part of the Qt API. It exists purely as an 38 // implementation detail. This header file may change from version to 39 // version without notice, or even be removed. 40 // 41 // We mean it. 42 // 43 44 #include <QtQuick3D/qtquick3dglobal.h> 45 #include <QtQuick3D/private/qquick3dobject_p.h> 46 #include <QtQuick3D/private/qquick3dtexture_p.h> 47 #include <QtQuick3D/private/qquick3dmaterial_p.h> 48 49 #include <QtQuick3DRender/private/qssgrenderbasetypes_p.h> 50 51 #include <QtQuick3DRuntimeRender/private/qssgrenderdynamicobjectsystemcommands_p.h> 52 53 QT_BEGIN_NAMESPACE 54 55 class QQuick3DShaderUtilsShader; 56 57 namespace QSSGShaderUtils 58 { 59 void addSnapperSampler(const QByteArray &texName, QByteArray &shaderPrefix); 60 QByteArray resolveShader(const QByteArray &shader, QByteArray &shaderPath, const QObject *qmlObj); 61 QByteArray mergeShaderCode(const QByteArray &shared, 62 const QByteArray &uniforms, 63 const QByteArray &textures, 64 const QByteArray &vertex, 65 const QByteArray &geometry, 66 const QByteArray &fragment); 67 } 68 69 class Q_QUICK3D_EXPORT QQuick3DShaderUtilsTextureInput : public QObject 70 { 71 Q_OBJECT 72 Q_PROPERTY(QQuick3DTexture *texture READ texture WRITE setTexture) 73 Q_PROPERTY(bool enabled MEMBER enabled) 74 75 public: 76 QQuick3DShaderUtilsTextureInput() = default; 77 virtual ~QQuick3DShaderUtilsTextureInput() = default; 78 QQuick3DTexture *m_texture = nullptr; 79 bool enabled = true; 80 QByteArray name; texture()81 QQuick3DTexture *texture() const 82 { 83 return m_texture; 84 } 85 86 public Q_SLOTS: 87 void setTexture(QQuick3DTexture *texture); 88 89 Q_SIGNALS: 90 void textureDirty(QQuick3DShaderUtilsTextureInput *texture); 91 }; 92 93 class Q_QUICK3D_EXPORT QQuick3DShaderUtilsBuffer : public QObject 94 { 95 Q_OBJECT 96 Q_PROPERTY(TextureFormat format READ format WRITE setFormat) 97 Q_PROPERTY(TextureFilterOperation textureFilterOperation READ textureFilterOperation WRITE setTextureFilterOperation) 98 Q_PROPERTY(TextureCoordOperation textureCoordOperation READ textureCoordOperation WRITE setTextureCoordOperation) 99 Q_PROPERTY(float sizeMultiplier MEMBER sizeMultiplier) 100 Q_PROPERTY(AllocateBufferFlagValues bufferFlags READ bufferFlags WRITE setBufferFlags) 101 Q_PROPERTY(QByteArray name MEMBER name) 102 public: 103 QQuick3DShaderUtilsBuffer() = default; 104 ~QQuick3DShaderUtilsBuffer() override = default; 105 106 enum class TextureFilterOperation 107 { 108 Unknown = 0, 109 Nearest, 110 Linear 111 }; 112 Q_ENUM(TextureFilterOperation) 113 114 enum class TextureCoordOperation 115 { 116 Unknown = 0, 117 ClampToEdge, 118 MirroredRepeat, 119 Repeat 120 }; 121 Q_ENUM(TextureCoordOperation) 122 123 enum class AllocateBufferFlagValues 124 { 125 None = 0, 126 SceneLifetime = 1 127 }; 128 Q_ENUM(AllocateBufferFlagValues) 129 130 enum class TextureFormat { 131 Unknown = 0, 132 R8, 133 R16, 134 R16F, 135 R32I, 136 R32UI, 137 R32F, 138 RG8, 139 RGBA8, 140 RGB8, 141 SRGB8, 142 SRGB8A8, 143 RGB565, 144 RGBA16F, 145 RG16F, 146 RG32F, 147 RGB32F, 148 RGBA32F, 149 R11G11B10, 150 RGB9E5, 151 Depth16, 152 Depth24, 153 Depth32, 154 Depth24Stencil8 155 }; Q_ENUM(TextureFormat)156 Q_ENUM(TextureFormat) 157 158 dynamic::QSSGAllocateBuffer command {}; textureFilterOperation()159 TextureFilterOperation textureFilterOperation() const { return TextureFilterOperation(command.m_filterOp); } setTextureFilterOperation(TextureFilterOperation op)160 void setTextureFilterOperation(TextureFilterOperation op) { command.m_filterOp = QSSGRenderTextureMagnifyingOp(op); } 161 textureCoordOperation()162 TextureCoordOperation textureCoordOperation() const { return TextureCoordOperation(command.m_texCoordOp); } setTextureCoordOperation(TextureCoordOperation texCoordOp)163 void setTextureCoordOperation(TextureCoordOperation texCoordOp) { command.m_texCoordOp = QSSGRenderTextureCoordOp(texCoordOp); } 164 float &sizeMultiplier = command.m_sizeMultiplier; getCommand()165 dynamic::QSSGCommand *getCommand() { return &command; } 166 167 TextureFormat format() const; 168 void setFormat(TextureFormat format); 169 bufferFlags()170 AllocateBufferFlagValues bufferFlags() const { return AllocateBufferFlagValues(int(command.m_bufferFlags)); } setBufferFlags(AllocateBufferFlagValues flag)171 void setBufferFlags(AllocateBufferFlagValues flag) { command.m_bufferFlags = quint32(flag);} 172 173 QByteArray &name = command.m_name; 174 175 static QSSGRenderTextureFormat::Format mapTextureFormat(QQuick3DShaderUtilsBuffer::TextureFormat fmt); 176 static QQuick3DShaderUtilsBuffer::TextureFormat mapRenderTextureFormat(QSSGRenderTextureFormat::Format fmt); 177 }; 178 179 class Q_QUICK3D_EXPORT QQuick3DShaderUtilsRenderCommand : public QObject 180 { 181 Q_OBJECT 182 public: 183 QQuick3DShaderUtilsRenderCommand() = default; 184 ~QQuick3DShaderUtilsRenderCommand() override = default; getCommand()185 virtual dynamic::QSSGCommand *getCommand() { Q_ASSERT(0); return nullptr; } bufferCount()186 virtual int bufferCount() const { return 0; } bufferAt(int idx)187 virtual QQuick3DShaderUtilsBuffer *bufferAt(int idx) const { Q_UNUSED(idx) return nullptr; } 188 }; 189 190 class Q_QUICK3D_EXPORT QQuick3DShaderUtilsBufferInput : public QQuick3DShaderUtilsRenderCommand 191 { 192 Q_OBJECT 193 Q_PROPERTY(QQuick3DShaderUtilsBuffer *buffer READ buffer WRITE setBuffer) 194 Q_PROPERTY(QByteArray param MEMBER param) 195 public: 196 QQuick3DShaderUtilsBufferInput() = default; 197 ~QQuick3DShaderUtilsBufferInput() override = default; 198 dynamic::QSSGApplyBufferValue command { QByteArray(), QByteArray() }; 199 QByteArray ¶m = command.m_paramName; getCommand()200 dynamic::QSSGCommand *getCommand() override { return &command; } 201 bufferCount()202 int bufferCount() const override { return (m_buffer != nullptr) ? 1 : 0; } bufferAt(int idx)203 QQuick3DShaderUtilsBuffer *bufferAt(int idx) const override 204 { 205 Q_ASSERT(idx < 1 && idx >= 0); 206 return (m_buffer && idx == 0) ? m_buffer : nullptr; 207 } 208 buffer()209 QQuick3DShaderUtilsBuffer *buffer() const { return m_buffer; } setBuffer(QQuick3DShaderUtilsBuffer * buffer)210 void setBuffer(QQuick3DShaderUtilsBuffer *buffer) { 211 if (m_buffer == buffer) 212 return; 213 214 if (buffer) { 215 Q_ASSERT(!buffer->name.isEmpty()); 216 command.m_bufferName = buffer->name; 217 } 218 m_buffer = buffer; 219 } 220 221 QQuick3DShaderUtilsBuffer *m_buffer = nullptr; 222 223 }; 224 225 class Q_QUICK3D_EXPORT QQuick3DShaderUtilsBufferBlit : public QQuick3DShaderUtilsRenderCommand 226 { 227 Q_OBJECT 228 Q_PROPERTY(QQuick3DShaderUtilsBuffer *source READ source WRITE setSource) 229 Q_PROPERTY(QQuick3DShaderUtilsBuffer *destination READ destination WRITE setDestination) 230 public: 231 QQuick3DShaderUtilsBufferBlit() = default; 232 ~QQuick3DShaderUtilsBufferBlit() override = default; 233 dynamic::QSSGApplyBlitFramebuffer command { QByteArray(), QByteArray() }; getCommand()234 dynamic::QSSGCommand *getCommand() override { return &command; } 235 bufferCount()236 int bufferCount() const override { 237 if (m_source != nullptr && m_destination != nullptr) 238 return 2; 239 if (m_source || m_destination) 240 return 1; 241 242 return 0; 243 } 244 bufferAt(int idx)245 QQuick3DShaderUtilsBuffer *bufferAt(int idx) const override 246 { 247 Q_ASSERT(idx < 2 && idx >= 0); 248 if (idx == 0) 249 return m_source ? m_source : m_destination; 250 if (idx == 1 && m_destination) 251 return m_destination; 252 253 return nullptr; 254 } 255 source()256 QQuick3DShaderUtilsBuffer *source() const { return m_source; } setSource(QQuick3DShaderUtilsBuffer * src)257 void setSource(QQuick3DShaderUtilsBuffer *src) 258 { 259 if (src == m_source) 260 return; 261 262 if (src) { 263 Q_ASSERT(!src->name.isEmpty()); 264 command.m_sourceBufferName = src->name; 265 } 266 m_source = src; 267 } 268 destination()269 QQuick3DShaderUtilsBuffer *destination() const { return m_destination; } setDestination(QQuick3DShaderUtilsBuffer * dest)270 void setDestination(QQuick3DShaderUtilsBuffer *dest) 271 { 272 if (dest == m_destination) 273 return; 274 275 if (dest) { 276 Q_ASSERT(!dest->name.isEmpty()); 277 command.m_destBufferName = dest->name; 278 } 279 m_destination = dest; 280 } 281 282 QQuick3DShaderUtilsBuffer *m_source = nullptr; 283 QQuick3DShaderUtilsBuffer *m_destination = nullptr; 284 }; 285 286 class Q_QUICK3D_EXPORT QQuick3DShaderUtilsBlending : public QQuick3DShaderUtilsRenderCommand 287 { 288 Q_OBJECT 289 Q_PROPERTY(SrcBlending srcBlending READ srcBlending WRITE setSrcBlending) 290 Q_PROPERTY(DestBlending destBlending READ destBlending WRITE setDestBlending) 291 292 public: 293 enum class SrcBlending 294 { 295 Unknown = 0, 296 Zero, 297 One, 298 SrcColor, 299 OneMinusSrcColor, 300 DstColor, 301 OneMinusDstColor, 302 SrcAlpha, 303 OneMinusSrcAlpha, 304 DstAlpha, 305 OneMinusDstAlpha, 306 ConstantColor, 307 OneMinusConstantColor, 308 ConstantAlpha, 309 OneMinusConstantAlpha, 310 SrcAlphaSaturate 311 }; 312 Q_ENUM(SrcBlending) 313 314 enum class DestBlending 315 { 316 Unknown = 0, 317 Zero, 318 One, 319 SrcColor, 320 OneMinusSrcColor, 321 DstColor, 322 OneMinusDstColor, 323 SrcAlpha, 324 OneMinusSrcAlpha, 325 DstAlpha, 326 OneMinusDstAlpha, 327 ConstantColor, 328 OneMinusConstantColor, 329 ConstantAlpha, 330 OneMinusConstantAlpha 331 }; 332 Q_ENUM(DestBlending) 333 334 QQuick3DShaderUtilsBlending() = default; 335 ~QQuick3DShaderUtilsBlending() override = default; 336 dynamic::QSSGApplyBlending command { QSSGRenderSrcBlendFunc::Unknown, QSSGRenderDstBlendFunc::Unknown }; destBlending()337 DestBlending destBlending() const 338 { 339 return DestBlending(command.m_dstBlendFunc); 340 } srcBlending()341 SrcBlending srcBlending() const 342 { 343 return SrcBlending(command.m_srcBlendFunc); 344 } 345 getCommand()346 dynamic::QSSGCommand *getCommand() override { return &command; } 347 348 public Q_SLOTS: setDestBlending(DestBlending destBlending)349 void setDestBlending(DestBlending destBlending) 350 { 351 command.m_dstBlendFunc = QSSGRenderDstBlendFunc(destBlending); 352 } setSrcBlending(SrcBlending srcBlending)353 void setSrcBlending(SrcBlending srcBlending) 354 { 355 command.m_srcBlendFunc= QSSGRenderSrcBlendFunc(srcBlending); 356 } 357 }; 358 359 class Q_QUICK3D_EXPORT QQuick3DShaderUtilsRenderState : public QQuick3DShaderUtilsRenderCommand 360 { 361 Q_OBJECT 362 Q_PROPERTY(RenderState renderState READ renderState WRITE setRenderState) 363 Q_PROPERTY(bool enabled MEMBER enabled) 364 365 public: 366 enum class RenderState 367 { 368 Unknown = 0, 369 Blend, 370 CullFace, 371 DepthTest, 372 StencilTest, 373 ScissorTest, 374 DepthWrite, 375 Multisample 376 }; 377 Q_ENUM(RenderState) 378 379 QQuick3DShaderUtilsRenderState() = default; 380 ~QQuick3DShaderUtilsRenderState() override = default; 381 dynamic::QSSGApplyRenderState command { QSSGRenderState::Unknown, false }; 382 bool &enabled = command.m_enabled; renderState()383 RenderState renderState() const 384 { 385 return RenderState(command.m_renderState); 386 } 387 getCommand()388 dynamic::QSSGCommand *getCommand() override { return &command; } 389 public Q_SLOTS: setRenderState(RenderState renderState)390 void setRenderState(RenderState renderState) 391 { 392 command.m_renderState = QSSGRenderState(renderState); 393 } 394 }; 395 396 class Q_QUICK3D_EXPORT QQuick3DShaderUtilsCullMode : public QQuick3DShaderUtilsRenderCommand 397 { 398 Q_OBJECT 399 Q_PROPERTY(QQuick3DMaterial::CullMode cullMode READ cullMode WRITE setCullMode) 400 401 public: 402 QQuick3DShaderUtilsCullMode() = default; 403 ~QQuick3DShaderUtilsCullMode() override = default; 404 405 dynamic::QSSGApplyCullMode command { QSSGCullFaceMode::Back }; 406 cullMode()407 QQuick3DMaterial::CullMode cullMode() const 408 { 409 return QQuick3DMaterial::CullMode(command.m_cullMode); 410 } getCommand()411 dynamic::QSSGCommand *getCommand() override { return &command; } 412 public Q_SLOTS: setCullMode(QQuick3DMaterial::CullMode cullMode)413 void setCullMode(QQuick3DMaterial::CullMode cullMode) 414 { 415 command.m_cullMode = QSSGCullFaceMode(cullMode); 416 } 417 }; 418 419 class Q_QUICK3D_EXPORT QQuick3DShaderApplyDepthValue : public QQuick3DShaderUtilsRenderCommand 420 { 421 Q_OBJECT 422 Q_PROPERTY(QByteArray param MEMBER param) 423 424 public: 425 QQuick3DShaderApplyDepthValue() = default; 426 ~QQuick3DShaderApplyDepthValue() override = default; 427 428 dynamic::QSSGApplyDepthValue command { QByteArray() }; 429 getCommand()430 dynamic::QSSGCommand *getCommand() override { return &command; } 431 QByteArray ¶m = command.m_paramName; 432 }; 433 434 class Q_QUICK3D_EXPORT QQuick3DShaderUtilsApplyValue : public QQuick3DShaderUtilsRenderCommand 435 { 436 Q_OBJECT 437 Q_PROPERTY(QByteArray target MEMBER target) 438 Q_PROPERTY(QVariant value MEMBER value) 439 440 public: 441 QQuick3DShaderUtilsApplyValue() = default; 442 ~QQuick3DShaderUtilsApplyValue() override = default; getCommand()443 dynamic::QSSGCommand *getCommand() override { return &command; } 444 dynamic::QSSGApplyValue command { }; 445 QVariant &value = command.m_value; 446 QByteArray &target = command.m_propertyName; 447 }; 448 449 class Q_QUICK3D_EXPORT QQuick3DShaderUtilsRenderPass : public QObject 450 { 451 Q_OBJECT 452 Q_PROPERTY(QQmlListProperty<QQuick3DShaderUtilsRenderCommand> commands READ commands) 453 Q_PROPERTY(QQuick3DShaderUtilsBuffer *output MEMBER outputBuffer) 454 Q_PROPERTY(QQmlListProperty<QQuick3DShaderUtilsShader> shaders READ shaders) 455 public: 456 QQuick3DShaderUtilsRenderPass() = default; 457 ~QQuick3DShaderUtilsRenderPass() override = default; 458 459 static void qmlAppendCommand(QQmlListProperty<QQuick3DShaderUtilsRenderCommand> *list, QQuick3DShaderUtilsRenderCommand *command); 460 static QQuick3DShaderUtilsRenderCommand *qmlCommandAt(QQmlListProperty<QQuick3DShaderUtilsRenderCommand> *list, int index); 461 static int qmlCommandCount(QQmlListProperty<QQuick3DShaderUtilsRenderCommand> *list); 462 static void qmlCommandClear(QQmlListProperty<QQuick3DShaderUtilsRenderCommand> *list); 463 464 static void qmlAppendShader(QQmlListProperty<QQuick3DShaderUtilsShader> *list, QQuick3DShaderUtilsShader *shader); 465 static QQuick3DShaderUtilsShader *qmlShaderAt(QQmlListProperty<QQuick3DShaderUtilsShader> *list, int index); 466 static int qmlShaderCount(QQmlListProperty<QQuick3DShaderUtilsShader> *list); 467 static void qmlShaderClear(QQmlListProperty<QQuick3DShaderUtilsShader> *list); 468 469 QQmlListProperty<QQuick3DShaderUtilsRenderCommand> commands(); 470 QVector<QQuick3DShaderUtilsRenderCommand *> m_commands; 471 QQuick3DShaderUtilsBuffer *outputBuffer = nullptr; 472 QQmlListProperty<QQuick3DShaderUtilsShader> shaders(); 473 QVarLengthArray<QQuick3DShaderUtilsShader *, 5> m_shaders { nullptr, nullptr, nullptr, nullptr, nullptr }; 474 }; 475 476 class Q_QUICK3D_EXPORT QQuick3DShaderUtilsShaderInfo : public QObject 477 { 478 Q_OBJECT 479 Q_PROPERTY(QByteArray version MEMBER version) 480 Q_PROPERTY(QByteArray type MEMBER type) 481 Q_PROPERTY(qint32 shaderKey MEMBER shaderKey) 482 public: 483 QQuick3DShaderUtilsShaderInfo() = default; 484 ~QQuick3DShaderUtilsShaderInfo() override = default; 485 QByteArray version; 486 QByteArray type; // I.e., GLSL 487 488 enum class MaterialShaderKeyValues 489 { 490 Diffuse = 1 << 0, 491 Specular = 1 << 1, 492 Cutout = 1 << 2, 493 Refraction = 1 << 3, 494 Transparent = 1 << 4, 495 Displace = 1 << 5, 496 Transmissive = 1 << 6, 497 Glossy = Diffuse | Specular 498 }; 499 Q_ENUM(MaterialShaderKeyValues) Q_DECLARE_FLAGS(MaterialShaderKeyFlags,MaterialShaderKeyValues)500 Q_DECLARE_FLAGS(MaterialShaderKeyFlags, MaterialShaderKeyValues) 501 502 qint32 shaderKey {0}; isValid()503 bool isValid() const { return !(version.isEmpty() && type.isEmpty()); } 504 }; 505 506 class Q_QUICK3D_EXPORT QQuick3DShaderUtilsShader : public QObject 507 { 508 Q_OBJECT 509 Q_PROPERTY(QByteArray shader MEMBER shader) 510 Q_PROPERTY(Stage stage MEMBER stage) 511 public: 512 QQuick3DShaderUtilsShader() = default; 513 virtual ~QQuick3DShaderUtilsShader() = default; 514 enum class Stage : quint8 515 { 516 Shared, 517 Vertex, 518 Fragment, 519 Geometry, 520 Compute 521 }; 522 Q_ENUM(Stage) 523 524 QByteArray shader; 525 Stage stage = Stage::Shared; 526 }; 527 528 QT_END_NAMESPACE 529 530 #endif // QQUICK3DSHADERUTILS_H 531