1 | // Copyright (C) 2021 The Qt Company Ltd. |
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only |
3 | |
4 | #ifndef CUSTOMMATERIAL_H |
5 | #define CUSTOMMATERIAL_H |
6 | |
7 | #include <QtQuick3DAssetUtils/private/qssgscenedesc_p.h> |
8 | |
9 | QT_BEGIN_NAMESPACE |
10 | |
11 | class CustomMaterial |
12 | { |
13 | public: |
14 | struct Uniform |
15 | { |
16 | enum class Type |
17 | { |
18 | Bool, |
19 | Int, |
20 | Float, |
21 | Vec2, |
22 | Vec3, |
23 | Vec4, |
24 | Mat44, |
25 | Sampler, |
26 | Last |
27 | }; |
28 | union { |
29 | bool b; |
30 | int i; |
31 | float f; |
32 | QVector2D vec2; |
33 | QVector3D vec3; |
34 | QVector4D vec4; |
35 | quintptr d; |
36 | }; |
37 | Type type; |
38 | QByteArray name; |
39 | QMatrix4x4 m44; |
40 | QString imagePath; |
41 | }; |
42 | using UniformTable = QList<Uniform>; |
43 | using TextureStore = QList<QImage *>; |
44 | |
45 | struct Properties |
46 | { |
47 | QQuick3DCustomMaterial::CullMode cullMode { QQuick3DCustomMaterial::CullMode::BackFaceCulling }; |
48 | QQuick3DCustomMaterial::DepthDrawMode depthDrawMode { QQuick3DCustomMaterial::DepthDrawMode::OpaqueOnlyDepthDraw }; |
49 | QQuick3DCustomMaterial::ShadingMode shadingMode { QQuick3DCustomMaterial::ShadingMode::Shaded }; |
50 | QQuick3DCustomMaterial::BlendMode sourceBlend { QQuick3DCustomMaterial::BlendMode::NoBlend }; |
51 | QQuick3DCustomMaterial::BlendMode destinationBlend { QQuick3DCustomMaterial::BlendMode::NoBlend }; |
52 | } properties; |
53 | |
54 | struct Shaders |
55 | { |
56 | QUrl vert; |
57 | QUrl frag; |
58 | }; |
59 | |
60 | static void setUniform(QSSGSceneDesc::Material &material, const Uniform &uniform); |
61 | QPointer<QQuick3DCustomMaterial> create(QQuick3DNode &parent, const UniformTable &uniforms, const Properties &properties, const Shaders &shaders); |
62 | bool isValid() const; |
63 | friend QTextStream &operator<<(QTextStream &stream, const CustomMaterial &material) |
64 | { |
65 | using namespace QSSGSceneDesc; |
66 | const auto &scene = material.scene; |
67 | if (auto node = scene.root) { |
68 | Q_ASSERT(node->runtimeType == Material::RuntimeType::CustomMaterial); |
69 | writeQmlComponent(material: static_cast<const QSSGSceneDesc::Material &>(*node), stream); |
70 | } |
71 | return stream; |
72 | } |
73 | |
74 | friend QDataStream &operator<<(QDataStream &stream, const CustomMaterial::Uniform &uniform) { return writeToDataStream(stream, uniform); } |
75 | friend QDataStream &operator>>(QDataStream &stream, CustomMaterial::Uniform &uniform) { return readFromDataStream(stream, uniform); } |
76 | |
77 | private: |
78 | static QDataStream &readFromDataStream(QDataStream &stream, Uniform &uniform); |
79 | static QDataStream &writeToDataStream(QDataStream &stream, const Uniform &uniform); |
80 | static void writeQmlComponent(const QSSGSceneDesc::Material &material, QTextStream &stream); |
81 | QSSGSceneDesc::Scene scene; |
82 | }; |
83 | |
84 | QT_END_NAMESPACE |
85 | |
86 | #endif // CUSTOMMATERIAL_H |
87 | |