1/****************************************************************************
2**
3** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the Qt3D module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
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 Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#include "qparameter.h"
41#include "qparameter_p.h"
42#include <Qt3DRender/private/renderlogging_p.h>
43#include <Qt3DRender/qtexture.h>
44
45
46/*!
47 \qmltype Parameter
48 \instantiates Qt3DRender::QParameter
49 \inqmlmodule Qt3D.Render
50 \brief Provides storage for a name and value pair. This maps to a shader uniform.
51
52 A Parameter can be referenced by a RenderPass, Technique, Effect, Material,
53 TechniqueFilter, RenderPassFilter. At runtime, depending on which shader is
54 selected for a given step of the rendering, the value contained in a
55 Parameter will be converted and uploaded if the shader contains a uniform
56 with a name matching that of the Parameter.
57
58 \code
59 Parameter {
60 name: "diffuseColor"
61 value: "blue"
62 }
63
64 // Works with the following GLSL uniform shader declarations
65 // uniform vec4 diffuseColor;
66 // uniform vec3 diffuseColor;
67 // uniform vec2 diffuseColor;
68 // uniform float diffuseColor;
69 \endcode
70
71 \note some care must be taken to ensure the value wrapped by a Parameter
72 can actually be converted to what the real uniform expect. Giving a value
73 stored as an int where the actual shader uniform is of type float could
74 result in undefined behaviors.
75
76 \note when the targeted uniform is an array, the name should be the name
77 of the uniform with [0] appended to it.
78
79 \note Parameter node can not be disabled.
80
81 \code
82 Parameter {
83 name: "diffuseValues[0]"
84 value: [0.0, 1.0. 2.0, 3.0, 4.0, 883.0, 1340.0, 1584.0]
85 }
86
87 // Matching GLSL shader uniform declaration
88 // uniform float diffuseValues[8];
89 \endcode
90
91 When it comes to texture support, the Parameter value should be set to the
92 appropriate \l {Qt3DRender::QAbstractTexture}{texture} subclass that matches the sampler type of the shader
93 uniform.
94
95 \code
96 Parameter {
97 name: "diffuseTexture"
98 value: Texture2D { ... }
99 }
100
101 // Works with the following GLSL uniform shader declaration
102 // uniform sampler2D diffuseTexture
103 \endcode
104
105 \sa Qt3DRender::QAbstractTexture
106 */
107
108/*!
109 \class Qt3DRender::QParameter
110 \inheaderfile Qt3DRender/QParameter
111 \inmodule Qt3DRender
112 \brief Provides storage for a name and value pair. This maps to a shader uniform.
113
114 A QParameter can be referenced by a QRenderPass, QTechnique, QEffect, QMaterial,
115 QTechniqueFilter, QRenderPassFilter. At runtime, depending on which shader is
116 selected for a given step of the rendering, the value contained in a
117 QParameter will be converted and uploaded if the shader contains a uniform
118 with a name matching that of the QParameter.
119
120 \code
121 QParameter *param = new QParameter();
122 param->setName(QStringLiteral("diffuseColor"));
123 param->setValue(QColor::fromRgbF(0.0f, 0.0f, 1.0f, 1.0f));
124
125 // Alternatively you can create and set a QParameter this way
126 QParameter *param2 = new QParameter(QStringLiteral("diffuseColor"), QColor::fromRgbF(0.0f, 0.0f, 1.0f, 1.0f));
127
128 // Such QParameters will work with the following GLSL uniform shader declarations
129 // uniform vec4 diffuseColor;
130 // uniform vec3 diffuseColor;
131 // uniform vec2 diffuseColor;
132 // uniform float diffuseColor;
133 \endcode
134
135 \note some care must be taken to ensure the value wrapped by a QParameter
136 can actually be converted to what the real uniform expect. Giving a value
137 stored as an int where the actual shader uniform is of type float could
138 result in undefined behaviors.
139
140 \note when the targeted uniform is an array, the name should be the name
141 of the uniform with [0] appended to it.
142
143 \note QParameter node can not be disabled.
144
145 \code
146 QParameter *param = new QParameter();
147 QVariantList values = QVariantList() << 0.0f << 1.0f << 2.0f << 3.0f << 4.0f << 883.0f << 1340.0f << 1584.0f;
148
149 param->setName(QStringLiteral("diffuseValues[0]"));
150 param->setValue(values);
151
152 // Matching GLSL shader uniform declaration
153 // uniform float diffuseValues[8];
154 \endcode
155
156 When it comes to texture support, the QParameter value should be set to the
157 appropriate QAbstractTexture subclass that matches the sampler type of the shader
158 uniform.
159
160 \code
161 QTexture2D *texture = new QTexture2D();
162 ...
163 QParameter *param = new QParameter();
164 param->setName(QStringLiteral("diffuseTexture"));
165 param->setValue(QVariant::fromValue(texture));
166
167 // Works with the following GLSL uniform shader declaration
168 // uniform sampler2D diffuseTexture
169 \endcode
170
171 \sa QAbstractTexture
172 */
173
174QT_BEGIN_NAMESPACE
175
176using namespace Qt3DCore;
177
178namespace Qt3DRender {
179
180QParameterPrivate::QParameterPrivate()
181 : QNodePrivate()
182{
183}
184
185namespace {
186
187/*! \internal */
188inline QVariant toBackendValue(const QVariant &v)
189{
190 if (auto nodeValue = v.value<Qt3DCore::QNode*>())
191 return QVariant::fromValue(value: nodeValue->id());
192 return v;
193}
194
195} // anonymous
196
197void QParameterPrivate::setValue(const QVariant &v)
198{
199 if (v.type() == QVariant::List) {
200 QSequentialIterable iterable = v.value<QSequentialIterable>();
201 QVariantList variants;
202 variants.reserve(alloc: iterable.size());
203 for (const auto &v : iterable)
204 variants.append(t: toBackendValue(v));
205 m_backendValue = variants;
206 } else {
207 m_backendValue = toBackendValue(v);
208 }
209 m_value = v;
210}
211
212/*! \internal */
213QParameter::QParameter(QParameterPrivate &dd, QNode *parent)
214 : QNode(dd, parent)
215{
216}
217
218/*!
219 \fn Qt3DRender::QParameter::QParameter(Qt3DCore::QNode *parent)
220 Constructs a new QParameter with the specified \a parent.
221 */
222QParameter::QParameter(QNode *parent)
223 : QNode(*new QParameterPrivate, parent)
224{
225}
226
227/*!
228 \fn Qt3DRender::QParameter::QParameter(const QString &name, const QVariant &value, QNode *parent)
229 Constructs a new QParameter with the specified \a parent \a name and \a value.
230 */
231QParameter::QParameter(const QString &name, const QVariant &value, QNode *parent)
232 : QNode(*new QParameterPrivate, parent)
233{
234 Q_D(QParameter);
235 d->m_name = name;
236 setValue(value);
237}
238
239/*!
240 \fn Qt3DRender::QParameter::QParameter(const QString &name, QAbstractTexture *texture, QNode *parent)
241 Constructs a new QParameter with the specified \a parent \a name and takes its value from \a texture.
242 */
243QParameter::QParameter(const QString &name, QAbstractTexture *texture, QNode *parent)
244 : QNode(*new QParameterPrivate, parent)
245{
246 Q_D(QParameter);
247 d->m_name = name;
248 setValue(QVariant::fromValue(value: texture));
249}
250
251/*! \internal */
252QParameter::~QParameter()
253{
254}
255
256/*!
257 \qmlproperty QString Qt3D.Render::Parameter::name
258 Specifies the name of the parameter
259*/
260
261/*!
262 \property Qt3DRender::QParameter::name
263 Specifies the name of the parameter
264 */
265void QParameter::setName(const QString &name)
266{
267 Q_D(QParameter);
268 if (d->m_name != name) {
269 d->m_name = name;
270 emit nameChanged(name);
271 }
272}
273
274QString QParameter::name() const
275{
276 Q_D(const QParameter);
277 return d->m_name;
278}
279
280/*!
281 \qmlproperty QVariant Qt3D.Render::Parameter::value
282 Specifies the value of the parameter
283*/
284
285/*!
286 \property Qt3DRender::QParameter::value
287 Specifies the value of the parameter
288 */
289void QParameter::setValue(const QVariant &dv)
290{
291 Q_D(QParameter);
292 if (d->m_value != dv) {
293
294 QNode *oldNodeValue = d->m_value.value<QNode *>();
295 if (oldNodeValue != nullptr)
296 d->unregisterDestructionHelper(node: oldNodeValue);
297
298 // In case node values are declared inline
299 QNode *nodeValue = dv.value<QNode *>();
300 if (nodeValue != nullptr && !nodeValue->parent())
301 nodeValue->setParent(this);
302
303 d->setValue(dv);
304
305 // Ensures proper bookkeeping
306 if (nodeValue != nullptr)
307 d->registerDestructionHelper(node: nodeValue, func: &QParameter::setValue, nodeValue, resetValue: QVariant());
308
309 emit valueChanged(value: dv);
310 }
311}
312
313QVariant QParameter::value() const
314{
315 Q_D(const QParameter);
316 return d->m_value;
317}
318
319Qt3DCore::QNodeCreatedChangeBasePtr QParameter::createNodeCreationChange() const
320{
321 auto creationChange = Qt3DCore::QNodeCreatedChangePtr<QParameterData>::create(arguments: this);
322 auto &data = creationChange->data;
323 Q_D(const QParameter);
324 data.name = d->m_name;
325 data.backendValue = d->m_backendValue;
326 return creationChange;
327}
328
329} // namespace Qt3DRender
330
331QT_END_NAMESPACE
332

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