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 "qtechnique.h"
5#include "qtechnique_p.h"
6#include "qparameter.h"
7#include "qgraphicsapifilter.h"
8
9QT_BEGIN_NAMESPACE
10
11
12namespace Qt3DRender {
13
14using namespace Qt3DCore;
15
16QTechniquePrivate::QTechniquePrivate()
17 : QNodePrivate()
18{
19}
20
21QTechniquePrivate::~QTechniquePrivate()
22{
23}
24
25/*!
26 \qmltype Technique
27 \nativetype Qt3DRender::QTechnique
28 \inqmlmodule Qt3D.Render
29 \inherits Qt3DCore::QNode
30 \since 5.7
31 \brief Encapsulates a Technique.
32
33 A Technique specifies a set of RenderPass objects, FilterKey objects,
34 Parameter objects and a GraphicsApiFilter, which together define a
35 rendering technique the given graphics API can render. The filter keys are
36 used by TechniqueFilter to select specific techniques at specific parts of
37 the FrameGraph. A Parameter defined on a Technique overrides parameter
38 (of the same name) defined in RenderPass, but are overridden by
39 parameter in RenderPassFilter, TechniqueFilter, Material and Effect.
40
41 When creating an Effect that targets several versions of a graphics API, it
42 is useful to create several Technique nodes each with a graphicsApiFilter
43 set to match one of the targeted versions. At runtime, the Qt3D renderer
44 will select the most appropriate Technique based on which graphics API
45 versions are supported and (if specified) the FilterKey nodes that satisfy
46 a given TechniqueFilter in the FrameGraph.
47
48 \note When using OpenGL as the graphics API for rendering, Qt3D relies on
49 the QSurfaceFormat returned by QSurfaceFormat::defaultFormat() at runtime
50 to decide what is the most appropriate GL version available. If you need to
51 customize the QSurfaceFormat, do not forget to apply it with
52 QSurfaceFormat::setDefaultFormat(). Setting the QSurfaceFormat on the view
53 will likely have no effect on Qt3D related rendering.
54
55 \note Technique node can not be disabled.
56
57 \qml
58 Technique {
59 id: gl3Technique
60 parameters: [
61 Parameter { name: "color"; value: "orange" }
62 ]
63 filterKeys: [
64 FilterKey { name: "renderingStyle"; value: "forward" }
65 ]
66 graphicsApiFilter: {
67 api: GraphicsApiFilter.OpenGL
68 profile: GraphicsApiFilter.CoreProfile
69 majorVersion: 3
70 minorVersion: 1
71 }
72 renderPasses: [
73 RenderPass {
74 id: firstPass
75 shaderProgram: ShaderProgram {
76 // ...
77 }
78 },
79 RenderPass {
80 id: secondPass
81 shaderProgram: ShaderProgram {
82 // ...
83 }
84 }
85 ]
86 }
87 \endqml
88
89 \sa Effect, RenderPass, TechniqueFilter
90 */
91
92/*!
93 \class Qt3DRender::QTechnique
94 \inmodule Qt3DRender
95 \inherits Node
96 \since 5.7
97 \brief Encapsulates a Technique.
98
99 A Qt3DRender::QTechnique specifies a set of Qt3DRender::QRenderPass
100 objects, Qt3DRender::QFilterKey objects, Qt3DRender::QParameter objects and
101 a Qt3DRender::QGraphicsApiFilter, which together define a rendering
102 technique the given graphics API can render. The filter keys are used by
103 Qt3DRender::QTechniqueFilter to select specific techniques at specific
104 parts of the FrameGraph. A QParameter defined on a QTechnique overrides parameter
105 (of the same name) defined in QRenderPass, but are overridden by
106 parameter in QRenderPassFilter, QTechniqueFilter, QMaterial and QEffect.
107
108 When creating an QEffect that targets several versions of a graphics API,
109 it is useful to create several QTechnique nodes each with a
110 graphicsApiFilter set to match one of the targeted GL versions. At runtime,
111 the Qt3D renderer will select the most appropriate QTechnique based on
112 which graphics API versions are supported and (if specified) the QFilterKey
113 nodes that satisfy a given QTechniqueFilter in the FrameGraph.
114
115 \note When using OpenGL as the graphics API for rendering, Qt3D relies on
116 the QSurfaceFormat returned by QSurfaceFormat::defaultFormat() at runtime
117 to decide what is the most appropriate GL version available. If you need to
118 customize the QSurfaceFormat, do not forget to apply it with
119 QSurfaceFormat::setDefaultFormat(). Setting the QSurfaceFormat on the view
120 will likely have no effect on Qt3D related rendering.
121
122 \note QTechnique node can not be disabled.
123
124 \code
125 QTechnique *gl3Technique = new QTechnique();
126
127 // Create the render passes
128 QRenderPass *firstPass = new QRenderPass();
129 QRenderPass *secondPass = new QRenderPass();
130
131 // Add the passes to the technique
132 gl3Technique->addRenderPass(firstPass);
133 gl3Technique->addRenderPass(secondPass);
134
135 // Set the targeted GL version for the technique
136 gl3Technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGL);
137 gl3Technique->graphicsApiFilter()->setMajorVersion(3);
138 gl3Technique->graphicsApiFilter()->setMinorVersion(1);
139 gl3Technique->graphicsApiFilter()->setProfile(QGraphicsApiFilter::CoreProfile);
140
141 // Create a FilterKey
142 QFilterKey *filterKey = new QFilterKey();
143 filterKey->setName(QStringLiteral("name"));
144 fitlerKey->setValue(QStringLiteral("zFillPass"));
145
146 // Add the FilterKey to the Technique
147 gl3Technique->addFilterKey(filterKey);
148
149 // Create a QParameter
150 QParameter *colorParameter = new QParameter(QStringLiteral("color"), QColor::fromRgbF(0.0f, 0.0f, 1.0f, 1.0f));
151
152 // Add parameter to technique
153 gl3Technique->addParameter(colorParameter);
154 \endcode
155
156 \sa QEffect, QRenderPass, QTechniqueFilter
157 */
158
159/*!
160 \qmlproperty GraphicsApiFilter Qt3D.Render::Technique::graphicsApiFilter
161 Specifies the graphics API filter being used
162*/
163/*!
164 \qmlproperty list<FilterKey> Qt3D.Render::Technique::filterKeys
165 Specifies the list of filter keys enabling this technique
166*/
167/*!
168 \qmlproperty list<RenderPass> Qt3D.Render::Technique::renderPasses
169 Specifies the render passes used by the tehcnique
170*/
171/*!
172 \qmlproperty list<Parameter> Qt3D.Render::Technique::parameters
173 Specifies the parameters used by the technique
174*/
175/*!
176 \property Qt3DRender::QTechnique::graphicsApiFilter
177 Specifies the graphics API filter being used
178 */
179
180QTechnique::QTechnique(QNode *parent)
181 : QNode(*new QTechniquePrivate, parent)
182{
183 Q_D(QTechnique);
184 QObject::connect(sender: &d->m_graphicsApiFilter, SIGNAL(graphicsApiFilterChanged()), receiver: this, SLOT(_q_graphicsApiFilterChanged()));
185}
186
187/*! \internal */
188QTechnique::~QTechnique()
189{
190}
191
192/*! \internal */
193QTechnique::QTechnique(QTechniquePrivate &dd, QNode *parent)
194 : QNode(dd, parent)
195{
196 Q_D(QTechnique);
197 QObject::connect(sender: &d->m_graphicsApiFilter, SIGNAL(graphicsApiFilterChanged()), receiver: this, SLOT(_q_graphicsApiFilterChanged()));
198}
199
200/*! \internal */
201void QTechniquePrivate::_q_graphicsApiFilterChanged()
202{
203 update();
204}
205
206/*!
207 Add \a filterKey to the Qt3DRender::QTechnique local filter keys.
208 */
209void QTechnique::addFilterKey(QFilterKey *filterKey)
210{
211 Q_ASSERT(filterKey);
212 Q_D(QTechnique);
213 if (!d->m_filterKeys.contains(t: filterKey)) {
214 d->m_filterKeys.append(t: filterKey);
215
216 // Ensures proper bookkeeping
217 d->registerDestructionHelper(node: filterKey, func: &QTechnique::removeFilterKey, d->m_filterKeys);
218
219 // We need to add it as a child of the current node if it has been declared inline
220 // Or not previously added as a child of the current node so that
221 // 1) The backend gets notified about it's creation
222 // 2) When the current node is destroyed, it gets destroyed as well
223 if (!filterKey->parent())
224 filterKey->setParent(this);
225
226 d->update();
227 }
228}
229
230/*!
231 Removes \a filterKey from the Qt3DRender::QTechnique local filter keys.
232 */
233void QTechnique::removeFilterKey(QFilterKey *filterKey)
234{
235 Q_ASSERT(filterKey);
236 Q_D(QTechnique);
237 if (!d->m_filterKeys.removeOne(t: filterKey))
238 return;
239 d->update();
240 // Remove bookkeeping connection
241 d->unregisterDestructionHelper(node: filterKey);
242}
243
244/*!
245 Returns the list of Qt3DCore::QFilterKey key objects making up the filter keys
246 of the Qt3DRender::QTechnique.
247 */
248QList<QFilterKey *> QTechnique::filterKeys() const
249{
250 Q_D(const QTechnique);
251 return d->m_filterKeys;
252}
253
254/*!
255 Add \a parameter to the technique's parameters.
256 */
257void QTechnique::addParameter(QParameter *parameter)
258{
259 Q_ASSERT(parameter);
260 Q_D(QTechnique);
261 if (!d->m_parameters.contains(t: parameter)) {
262 d->m_parameters.append(t: parameter);
263
264 // Ensures proper bookkeeping
265 d->registerDestructionHelper(node: parameter, func: &QTechnique::removeParameter, d->m_parameters);
266
267 // We need to add it as a child of the current node if it has been declared inline
268 // Or not previously added as a child of the current node so that
269 // 1) The backend gets notified about it's creation
270 // 2) When the current node is destroyed, the child parameters get destroyed as well
271 if (!parameter->parent())
272 parameter->setParent(this);
273
274 d->update();
275 }
276}
277
278/*!
279 Remove \a parameter from the technique's parameters.
280 */
281void QTechnique::removeParameter(QParameter *parameter)
282{
283 Q_ASSERT(parameter);
284 Q_D(QTechnique);
285 if (!d->m_parameters.removeOne(t: parameter))
286 return;
287 d->update();
288 // Remove bookkeeping connection
289 d->unregisterDestructionHelper(node: parameter);
290}
291
292/*!
293 Appends a \a pass to the technique.
294 */
295void QTechnique::addRenderPass(QRenderPass *pass)
296{
297 Q_ASSERT(pass);
298 Q_D(QTechnique);
299 if (!d->m_renderPasses.contains(t: pass)) {
300 d->m_renderPasses.append(t: pass);
301
302 // Ensures proper bookkeeping
303 d->registerDestructionHelper(node: pass, func: &QTechnique::removeRenderPass, d->m_renderPasses);
304
305 // We need to add it as a child of the current node if it has been declared inline
306 // Or not previously added as a child of the current node so that
307 // 1) The backend gets notified about it's creation
308 // 2) When the current node is destroyed, it gets destroyed as well
309 if (!pass->parent())
310 pass->setParent(this);
311
312 d->update();
313 }
314}
315
316/*!
317 Removes a \a pass from the technique.
318 */
319void QTechnique::removeRenderPass(QRenderPass *pass)
320{
321 Q_ASSERT(pass);
322 Q_D(QTechnique);
323 if (!d->m_renderPasses.removeOne(t: pass))
324 return;
325 d->update();
326 // Remove bookkeeping connection
327 d->unregisterDestructionHelper(node: pass);
328}
329
330/*!
331 Returns the list of render passes contained in the technique.
332 */
333QList<QRenderPass *> QTechnique::renderPasses() const
334{
335 Q_D(const QTechnique);
336 return d->m_renderPasses;
337}
338
339/*!
340 Returns a vector of the techniques current parameters
341 */
342QList<QParameter *> QTechnique::parameters() const
343{
344 Q_D(const QTechnique);
345 return d->m_parameters;
346}
347
348QGraphicsApiFilter *QTechnique::graphicsApiFilter()
349{
350 Q_D(QTechnique);
351 return &d->m_graphicsApiFilter;
352}
353
354const QGraphicsApiFilter *QTechnique::graphicsApiFilter() const
355{
356 Q_D(const QTechnique);
357 return &d->m_graphicsApiFilter;
358}
359
360} // of namespace Qt3DRender
361
362QT_END_NAMESPACE
363
364#include "moc_qtechnique.cpp"
365

Provided by KDAB

Privacy Policy
Learn to use CMake with our Intro Training
Find out more

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