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 "qeffect.h"
41#include "qeffect_p.h"
42#include "qtechnique.h"
43#include "qparameter.h"
44
45QT_BEGIN_NAMESPACE
46
47using namespace Qt3DCore;
48
49namespace Qt3DRender {
50
51QEffectPrivate::QEffectPrivate()
52 : QNodePrivate()
53{
54}
55
56/*!
57 \class Qt3DRender::QEffect
58 \inmodule Qt3DRender
59 \inherits Qt3DCore::QNode
60 \since 5.7
61 \brief The base class for effects in a Qt 3D scene.
62
63 The QEffect class combines a set of techniques and parameters used by those techniques to
64 produce a rendering effect for a material.
65
66 An QEffect instance should be shared among several QMaterial instances when possible.
67
68 \note QEffect node can not be disabled.
69
70 \code
71 QEffect *effect = new QEffect();
72
73 // Create technique, render pass and shader
74 QTechnique *gl3Technique = new QTechnique();
75 QRenderPass *gl3Pass = new QRenderPass();
76 QShaderProgram *glShader = new QShaderProgram();
77
78 // Set the shader on the render pass
79 gl3Pass->setShaderProgram(glShader);
80
81 // Add the pass to the technique
82 gl3Technique->addRenderPass(gl3Pass);
83
84 // Set the targeted GL version for the technique
85 gl3Technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGL);
86 gl3Technique->graphicsApiFilter()->setMajorVersion(3);
87 gl3Technique->graphicsApiFilter()->setMinorVersion(1);
88 gl3Technique->graphicsApiFilter()->setProfile(QGraphicsApiFilter::CoreProfile);
89
90 // Add the technique to the effect
91 effect->addTechnique(gl3Technique);
92 \endcode
93
94 A QParameter defined on a QEffect overrides parameter (of the same
95 name) defined in QTechnique and QRenderPass, but are overridden by parameter in
96 QRenderPassFilter, QTechniqueFilter and QMaterial.
97
98 \sa QMaterial, QTechnique, QParameter
99*/
100
101/*!
102 \qmltype Effect
103 \instantiates Qt3DRender::QEffect
104 \inherits Node
105 \inqmlmodule Qt3D.Render
106 \since 5.7
107 \brief The base class for effects in a Qt 3D scene.
108
109 The Effect type combines a set of techniques and parameters used by those techniques to
110 produce a rendering effect for a material.
111
112 An Effect instance should be shared among several Material instances when possible.
113
114 A Parameter defined on a Effect overrides parameter (of the same
115 name) defined in Technique and RenderPass, but are overridden by parameter in
116 RenderPassFilter, TechniqueFilter and Material.
117
118 \note Effect node can not be disabled.
119
120 \code
121 Effect {
122 id: effect
123
124 technique: [
125 Technique {
126 id: gl3Technique
127 graphicsApiFilter {
128 api: GraphicsApiFilter.OpenGL
129 profile: GraphicsApiFilter.CoreProfile
130 majorVersion: 3
131 minorVersion: 1
132 }
133 renderPasses: [
134 RenderPass {
135 id: gl3Pass
136 shaderProgram: ShaderProgram {
137 ...
138 }
139 }
140 ]
141 }
142 ]
143 }
144 \endcode
145
146 \sa Material, Technique, Parameter
147*/
148
149QEffect::QEffect(QNode *parent)
150 : QNode(*new QEffectPrivate, parent)
151{
152}
153
154QEffect::~QEffect()
155{
156}
157
158/*! \internal */
159QEffect::QEffect(QEffectPrivate &dd, QNode *parent)
160 : QNode(dd, parent)
161{
162}
163
164/*!
165 \qmlproperty list<Technique> Effect::techniques
166
167 Holds the list of techniques used by this effect.
168*/
169/*!
170 \qmlproperty list<Parameter> Effect::parameters
171
172 Holds the list of parameters used by this effect.
173 A parameter is used to set a corresponding uniform value in the shader used by this effect.
174*/
175
176/*!
177 * Adds \a parameter to the effect. It sends an update to the backend.
178 * The \a parameter will be used to set a corresponding uniform value in the shader used
179 * by this effect.
180 */
181void QEffect::addParameter(QParameter *parameter)
182{
183 Q_D(QEffect);
184 if (parameter && !d->m_parameters.contains(t: parameter)) {
185 d->m_parameters.append(t: parameter);
186
187 // Ensures proper bookkeeping
188 d->registerDestructionHelper(node: parameter, func: &QEffect::removeParameter, d->m_parameters);
189
190 // We need to add it as a child of the current node if it has been declared inline
191 // Or not previously added as a child of the current node so that
192 // 1) The backend gets notified about it's creation
193 // 2) When the current node is destroyed, it gets destroyed as well
194 if (!parameter->parent())
195 parameter->setParent(this);
196
197 d->updateNode(node: parameter, property: "parameter", change: Qt3DCore::PropertyValueAdded);
198 }
199}
200
201/*!
202 * Removes a parameter \a parameter from the effect.
203 */
204void QEffect::removeParameter(QParameter *parameter)
205{
206 Q_D(QEffect);
207
208 if (!d->m_parameters.removeOne(t: parameter))
209 return;
210 // Remove bookkeeping connection
211 d->unregisterDestructionHelper(node: parameter);
212 d->updateNode(node: parameter, property: "parameter", change: Qt3DCore::PropertyValueRemoved);
213}
214
215/*!
216 * Returns the list of parameters used by the effect.
217 */
218QVector<QParameter *> QEffect::parameters() const
219{
220 Q_D(const QEffect);
221 return d->m_parameters;
222}
223
224/*!
225 * Adds a new technique \a t to the effect. It sends an update to the backend.
226 */
227void QEffect::addTechnique(QTechnique *t)
228{
229 Q_ASSERT(t);
230 Q_D(QEffect);
231 if (t && !d->m_techniques.contains(t)) {
232 d->m_techniques.append(t);
233
234 // Ensures proper bookkeeping
235 d->registerDestructionHelper(node: t, func: &QEffect::removeTechnique, d->m_techniques);
236
237 // We need to add it as a child of the current node if it has been declared inline
238 // Or not previously added as a child of the current node so that
239 // 1) The backend gets notified about it's creation
240 // 2) When the current node is destroyed, tit gets destroyed as well
241 if (!t->parent())
242 t->setParent(this);
243
244 d->updateNode(node: t, property: "technique", change: Qt3DCore::PropertyValueAdded);
245 }
246}
247
248/*!
249 * Removes a technique \a t from the effect.
250 */
251void QEffect::removeTechnique(QTechnique *t)
252{
253 Q_D(QEffect);
254 if (!d->m_techniques.removeOne(t))
255 return;
256 d->updateNode(node: t, property: "technique", change: Qt3DCore::PropertyValueRemoved);
257 // Remove bookkeeping connection
258 d->unregisterDestructionHelper(node: t);
259}
260
261/*!
262 * Returns the list of techniques used by the effect.
263 */
264QVector<QTechnique *> QEffect::techniques() const
265{
266 Q_D(const QEffect);
267 return d->m_techniques;
268}
269
270Qt3DCore::QNodeCreatedChangeBasePtr QEffect::createNodeCreationChange() const
271{
272 auto creationChange = Qt3DCore::QNodeCreatedChangePtr<QEffectData>::create(arguments: this);
273 auto &data = creationChange->data;
274 Q_D(const QEffect);
275 data.parameterIds = qIdsForNodes(nodes: d->m_parameters);
276 data.techniqueIds = qIdsForNodes(nodes: d->m_techniques);
277 return creationChange;
278}
279
280} // namespace Qt3DRender
281
282QT_END_NAMESPACE
283

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