1// Copyright (C) 2019 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3
4#include "qquick3dmaterial_p.h"
5#include "qquick3dobject_p.h"
6#include "qquick3dscenemanager_p.h"
7
8#include <QtQuick3DRuntimeRender/private/qssgrenderdefaultmaterial_p.h>
9#include <QtQuick3DRuntimeRender/private/qssgrendercustommaterial_p.h>
10#include <QtQuick3DUtils/private/qssgutils_p.h>
11
12QT_BEGIN_NAMESPACE
13
14/*!
15 \qmltype Material
16 \inherits Object3D
17 \inqmlmodule QtQuick3D
18 \brief Abstract base type providing functionality common to materials.
19*/
20
21/*!
22 \qmlproperty Texture Material::lightProbe
23
24 This property defines a Texture for overriding or setting an image based
25 lighting Texture for use with this material only.
26
27 \note Setting a light probe on the material will override the
28 \l {SceneEnvironment::lightProbe} {scene's light probe} for models using this material.
29
30 \note This property is ignored when Reflection Probe is used to show
31 reflections on the Model using this material because Reflection Probe uses
32 the \l {SceneEnvironment::lightProbe} {scene's light probe}.
33
34 \sa SceneEnvironment::lightProbe
35*/
36
37/*!
38 \qmlproperty enumeration Material::cullMode
39
40 This property defines whether primitive culling is enabled, and, when
41 enabled, which primitives are discarded.
42
43 The default value is Material.BackFaceCulling.
44
45 A triangle is considered front-facing if it has a counter-clockwise
46 winding, meaning its vertices in framebuffer coordinates are in
47 counter-clockwise order.
48
49 \value Material.BackFaceCulling Back-facing triangles are discarded.
50 \value Material.FrontFaceCulling Front-facing triangles are discarded.
51 \value Material.NoCulling No triangles are discarded.
52*/
53
54/*!
55 \qmlproperty enumeration Material::depthDrawMode
56
57 This property determines if and when depth rendering takes place for this
58 material. The default behavior when \l {SceneEnvironment::depthTestEnabled}
59 is set to \c true is that during the main render pass only opaque materials
60 will write to the depth buffer. This property makes it possible to change
61 this behavior to fine tune the rendering of a material.
62
63 The default value is Material.OqaqueOnlyDepthDraw
64
65 \value Material.OpaqueOnlyDepthDraw Depth rendering is only performed if
66 the material is opaque.
67 \value Material.AlwaysDepthDraw Depth rendering is always performed
68 regardless of the material type.
69 \value Material.NeverDepthDraw Depth rendering is never performed.
70 \value Material.OpaquePrePassDepthDraw Depth rendering is performed in a
71 separate depth pass, but only opaque values are written. This mode also
72 enables transparent materials to be used in combination with shadows.
73
74 \note If \l {SceneEnvironment::depthPrePassEnabled} is set to \c true then all
75 depth writes will take place as a result of the depth prepass, but it is
76 still necessary to explicitly set \c Material.OpaquePrePassDepthDraw to only
77 write the opaque fragments in the depth and shadow passes.
78
79*/
80
81
82QQuick3DMaterial::QQuick3DMaterial(QQuick3DObjectPrivate &dd, QQuick3DObject *parent)
83 : QQuick3DObject(dd, parent) {}
84
85QQuick3DMaterial::~QQuick3DMaterial()
86{
87}
88
89QQuick3DTexture *QQuick3DMaterial::lightProbe() const
90{
91 return m_iblProbe;
92}
93
94QQuick3DMaterial::CullMode QQuick3DMaterial::cullMode() const
95{
96 return m_cullMode;
97}
98
99QQuick3DMaterial::DepthDrawMode QQuick3DMaterial::depthDrawMode() const
100{
101 return m_depthDrawMode;
102}
103
104void QQuick3DMaterial::setLightProbe(QQuick3DTexture *iblProbe)
105{
106 if (m_iblProbe == iblProbe)
107 return;
108
109 QQuick3DObjectPrivate::attachWatcher(context: this, setter: &QQuick3DMaterial::setLightProbe, newO: iblProbe, oldO: m_iblProbe);
110
111 m_iblProbe = iblProbe;
112 emit lightProbeChanged(lightProbe: m_iblProbe);
113 update();
114}
115
116void QQuick3DMaterial::setCullMode(QQuick3DMaterial::CullMode cullMode)
117{
118 if (m_cullMode == cullMode)
119 return;
120
121 m_cullMode = cullMode;
122 emit cullModeChanged(cullMode: m_cullMode);
123 update();
124}
125
126void QQuick3DMaterial::setDepthDrawMode(QQuick3DMaterial::DepthDrawMode depthDrawMode)
127{
128 if (m_depthDrawMode == depthDrawMode)
129 return;
130
131 m_depthDrawMode = depthDrawMode;
132 emit depthDrawModeChanged(depthDrawMode: m_depthDrawMode);
133 update();
134}
135
136QSSGRenderGraphObject *QQuick3DMaterial::updateSpatialNode(QSSGRenderGraphObject *node)
137{
138 if (!node)
139 return nullptr;
140
141 QQuick3DObject::updateSpatialNode(node);
142
143 // Set the common properties
144 if (node->type == QSSGRenderGraphObject::Type::DefaultMaterial ||
145 node->type == QSSGRenderGraphObject::Type::PrincipledMaterial ||
146 node->type == QSSGRenderGraphObject::Type::SpecularGlossyMaterial) {
147 auto defaultMaterial = static_cast<QSSGRenderDefaultMaterial *>(node);
148
149 if (!m_iblProbe)
150 defaultMaterial->iblProbe = nullptr;
151 else
152 defaultMaterial->iblProbe = m_iblProbe->getRenderImage();
153
154 defaultMaterial->cullMode = QSSGCullFaceMode(m_cullMode);
155 defaultMaterial->depthDrawMode = QSSGDepthDrawMode(m_depthDrawMode);
156
157 DebugViewHelpers::ensureDebugObjectName(node: defaultMaterial, src: this);
158
159 node = defaultMaterial;
160 } else if (node->type == QSSGRenderGraphObject::Type::CustomMaterial) {
161 auto customMaterial = static_cast<QSSGRenderCustomMaterial *>(node);
162
163 if (!m_iblProbe)
164 customMaterial->m_iblProbe = nullptr;
165 else
166 customMaterial->m_iblProbe = m_iblProbe->getRenderImage();
167
168 customMaterial->m_cullMode = QSSGCullFaceMode(m_cullMode);
169 customMaterial->m_depthDrawMode = QSSGDepthDrawMode(m_depthDrawMode);
170
171 DebugViewHelpers::ensureDebugObjectName(node: customMaterial, src: this);
172
173 node = customMaterial;
174 }
175
176 return node;
177}
178
179void QQuick3DMaterial::itemChange(QQuick3DObject::ItemChange change, const QQuick3DObject::ItemChangeData &value)
180{
181 if (change == QQuick3DObject::ItemSceneChange)
182 updateSceneManager(sceneManager: value.sceneManager);
183}
184
185void QQuick3DMaterial::updateSceneManager(QQuick3DSceneManager *sceneManager)
186{
187 if (sceneManager) {
188 QQuick3DObjectPrivate::refSceneManager(obj: m_iblProbe, mgr&: *sceneManager);
189 } else {
190 QQuick3DObjectPrivate::derefSceneManager(obj: m_iblProbe);
191 }
192}
193
194QT_END_NAMESPACE
195

source code of qtquick3d/src/quick3d/qquick3dmaterial.cpp