1// Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qparameter.h"
5#include "qparameter_p.h"
6#include <Qt3DRender/private/renderlogging_p.h>
7#include <Qt3DRender/qtexture.h>
8#include <QtCore/qiterable.h>
9#include <QtCore/qsequentialiterable.h>
10
11/*!
12 \qmltype Parameter
13 \instantiates Qt3DRender::QParameter
14 \inqmlmodule Qt3D.Render
15 \brief Provides storage for a name and value pair. This maps to a shader uniform.
16
17 A Parameter can be referenced by a RenderPass, Technique, Effect, Material,
18 TechniqueFilter, RenderPassFilter. At runtime, depending on which shader is
19 selected for a given step of the rendering, the value contained in a
20 Parameter will be converted and uploaded if the shader contains a uniform
21 with a name matching that of the Parameter.
22
23 \code
24 Parameter {
25 name: "diffuseColor"
26 value: "blue"
27 }
28
29 // Works with the following GLSL uniform shader declarations
30 // uniform vec4 diffuseColor;
31 // uniform vec3 diffuseColor;
32 // uniform vec2 diffuseColor;
33 // uniform float diffuseColor;
34 \endcode
35
36 \note some care must be taken to ensure the value wrapped by a Parameter
37 can actually be converted to what the real uniform expect. Giving a value
38 stored as an int where the actual shader uniform is of type float could
39 result in undefined behaviors.
40
41 \note when the targeted uniform is an array, the name should be the name
42 of the uniform with [0] appended to it.
43
44 \note Parameter node can not be disabled.
45
46 \code
47 Parameter {
48 name: "diffuseValues[0]"
49 value: [0.0, 1.0. 2.0, 3.0, 4.0, 883.0, 1340.0, 1584.0]
50 }
51
52 // Matching GLSL shader uniform declaration
53 // uniform float diffuseValues[8];
54 \endcode
55
56 When it comes to texture support, the Parameter value should be set to the
57 appropriate \l {Qt3DRender::QAbstractTexture}{texture} subclass that matches the sampler type of the shader
58 uniform.
59
60 \code
61 Parameter {
62 name: "diffuseTexture"
63 value: Texture2D { ... }
64 }
65
66 // Works with the following GLSL uniform shader declaration
67 // uniform sampler2D diffuseTexture
68 \endcode
69
70 \sa Qt3DRender::QAbstractTexture
71 */
72
73/*!
74 \class Qt3DRender::QParameter
75 \inheaderfile Qt3DRender/QParameter
76 \inmodule Qt3DRender
77 \brief Provides storage for a name and value pair. This maps to a shader uniform.
78
79 A QParameter can be referenced by a QRenderPass, QTechnique, QEffect, QMaterial,
80 QTechniqueFilter, QRenderPassFilter. At runtime, depending on which shader is
81 selected for a given step of the rendering, the value contained in a
82 QParameter will be converted and uploaded if the shader contains a uniform
83 with a name matching that of the QParameter.
84
85 \code
86 QParameter *param = new QParameter();
87 param->setName(QStringLiteral("diffuseColor"));
88 param->setValue(QColor::fromRgbF(0.0f, 0.0f, 1.0f, 1.0f));
89
90 // Alternatively you can create and set a QParameter this way
91 QParameter *param2 = new QParameter(QStringLiteral("diffuseColor"), QColor::fromRgbF(0.0f, 0.0f, 1.0f, 1.0f));
92
93 // Such QParameters will work with the following GLSL uniform shader declarations
94 // uniform vec4 diffuseColor;
95 // uniform vec3 diffuseColor;
96 // uniform vec2 diffuseColor;
97 // uniform float diffuseColor;
98 \endcode
99
100 \note some care must be taken to ensure the value wrapped by a QParameter
101 can actually be converted to what the real uniform expect. Giving a value
102 stored as an int where the actual shader uniform is of type float could
103 result in undefined behaviors.
104
105 \note when the targeted uniform is an array, the name should be the name
106 of the uniform with [0] appended to it.
107
108 \note QParameter node can not be disabled.
109
110 \code
111 QParameter *param = new QParameter();
112 QVariantList values = QVariantList() << 0.0f << 1.0f << 2.0f << 3.0f << 4.0f << 883.0f << 1340.0f << 1584.0f;
113
114 param->setName(QStringLiteral("diffuseValues[0]"));
115 param->setValue(values);
116
117 // Matching GLSL shader uniform declaration
118 // uniform float diffuseValues[8];
119 \endcode
120
121 When it comes to texture support, the QParameter value should be set to the
122 appropriate QAbstractTexture subclass that matches the sampler type of the shader
123 uniform.
124
125 \code
126 QTexture2D *texture = new QTexture2D();
127 ...
128 QParameter *param = new QParameter();
129 param->setName(QStringLiteral("diffuseTexture"));
130 param->setValue(QVariant::fromValue(texture));
131
132 // Works with the following GLSL uniform shader declaration
133 // uniform sampler2D diffuseTexture
134 \endcode
135
136 \sa QAbstractTexture
137 */
138
139QT_BEGIN_NAMESPACE
140
141using namespace Qt3DCore;
142
143namespace Qt3DRender {
144
145QParameterPrivate::QParameterPrivate()
146 : QNodePrivate()
147{
148}
149
150namespace {
151
152/*! \internal */
153inline QVariant toBackendValue(const QVariant &v)
154{
155 if (auto nodeValue = v.value<Qt3DCore::QNode*>())
156 return QVariant::fromValue(value: nodeValue->id());
157 return v;
158}
159
160} // anonymous
161
162void QParameterPrivate::setValue(const QVariant &v)
163{
164 if (v.metaType().id() == QMetaType::QVariantList) {
165 QSequentialIterable iterable = v.value<QSequentialIterable>();
166 QVariantList variants;
167 variants.reserve(asize: iterable.size());
168 for (const auto &v : iterable)
169 variants.append(t: toBackendValue(v));
170 m_backendValue = variants;
171 } else {
172 m_backendValue = toBackendValue(v);
173 }
174 m_value = v;
175}
176
177/*! \internal */
178QParameter::QParameter(QParameterPrivate &dd, QNode *parent)
179 : QNode(dd, parent)
180{
181}
182
183/*!
184 \fn Qt3DRender::QParameter::QParameter(Qt3DCore::QNode *parent)
185 Constructs a new QParameter with the specified \a parent.
186 */
187QParameter::QParameter(QNode *parent)
188 : QNode(*new QParameterPrivate, parent)
189{
190}
191
192/*!
193 \fn Qt3DRender::QParameter::QParameter(const QString &name, const QVariant &value, QNode *parent)
194 Constructs a new QParameter with the specified \a parent \a name and \a value.
195 */
196QParameter::QParameter(const QString &name, const QVariant &value, QNode *parent)
197 : QNode(*new QParameterPrivate, parent)
198{
199 Q_D(QParameter);
200 d->m_name = name;
201 setValue(value);
202}
203
204/*!
205 \fn Qt3DRender::QParameter::QParameter(const QString &name, QAbstractTexture *texture, QNode *parent)
206 Constructs a new QParameter with the specified \a parent \a name and takes its value from \a texture.
207 */
208QParameter::QParameter(const QString &name, QAbstractTexture *texture, QNode *parent)
209 : QNode(*new QParameterPrivate, parent)
210{
211 Q_D(QParameter);
212 d->m_name = name;
213 setValue(QVariant::fromValue(value: texture));
214}
215
216/*! \internal */
217QParameter::~QParameter()
218{
219}
220
221/*!
222 \qmlproperty QString Qt3D.Render::Parameter::name
223 Specifies the name of the parameter
224*/
225
226/*!
227 \property Qt3DRender::QParameter::name
228 Specifies the name of the parameter
229 */
230void QParameter::setName(const QString &name)
231{
232 Q_D(QParameter);
233 if (d->m_name != name) {
234 d->m_name = name;
235 emit nameChanged(name);
236 }
237}
238
239QString QParameter::name() const
240{
241 Q_D(const QParameter);
242 return d->m_name;
243}
244
245/*!
246 \qmlproperty QVariant Qt3D.Render::Parameter::value
247 Specifies the value of the parameter
248*/
249
250/*!
251 \property Qt3DRender::QParameter::value
252 Specifies the value of the parameter
253 */
254void QParameter::setValue(const QVariant &dv)
255{
256 Q_D(QParameter);
257 if (d->m_value != dv) {
258
259 QNode *oldNodeValue = d->m_value.value<QNode *>();
260 if (oldNodeValue != nullptr)
261 d->unregisterDestructionHelper(node: oldNodeValue);
262
263 // In case node values are declared inline
264 QNode *nodeValue = dv.value<QNode *>();
265 if (nodeValue != nullptr && !nodeValue->parent())
266 nodeValue->setParent(this);
267
268 d->setValue(dv);
269
270 // Ensures proper bookkeeping
271 if (nodeValue != nullptr)
272 d->registerDestructionHelper(node: nodeValue, func: &QParameter::setValue, nodeValue, resetValue: QVariant());
273
274 emit valueChanged(value: dv);
275 }
276}
277
278QVariant QParameter::value() const
279{
280 Q_D(const QParameter);
281 return d->m_value;
282}
283
284} // namespace Qt3DRender
285
286QT_END_NAMESPACE
287
288#include "moc_qparameter.cpp"
289

source code of qt3d/src/render/materialsystem/qparameter.cpp