1/****************************************************************************
2**
3** Copyright (C) 2016 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:GPL-EXCEPT$
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 General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU
19** General Public License version 3 as published by the Free Software
20** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21** included in the packaging of this file. Please review the following
22** information to ensure the GNU General Public License requirements will
23** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24**
25** $QT_END_LICENSE$
26**
27****************************************************************************/
28
29#include <QtTest/QTest>
30#include <Qt3DCore/qentity.h>
31#include <Qt3DCore/qtransform.h>
32#include <Qt3DCore/private/qaspectjobmanager_p.h>
33#include <Qt3DCore/private/qnodevisitor_p.h>
34#include <Qt3DCore/private/qnode_p.h>
35
36#include <Qt3DRender/private/nodemanagers_p.h>
37#include <Qt3DRender/private/managers_p.h>
38#include <Qt3DRender/private/entity_p.h>
39#include <materialparametergathererjob_p.h>
40#include <Qt3DRender/private/techniquefilternode_p.h>
41#include <Qt3DRender/private/technique_p.h>
42#include <Qt3DRender/private/techniquemanager_p.h>
43#include <Qt3DRender/private/renderpassfilternode_p.h>
44#include <Qt3DRender/qrendersettings.h>
45#include <Qt3DRender/qrenderaspect.h>
46#include <Qt3DRender/qeffect.h>
47#include <Qt3DRender/qmaterial.h>
48#include <Qt3DRender/qparameter.h>
49#include <Qt3DRender/qtechniquefilter.h>
50#include <Qt3DRender/qtechnique.h>
51#include <Qt3DRender/qrenderpassfilter.h>
52#include <Qt3DRender/qrenderpass.h>
53#include <Qt3DRender/qshaderprogram.h>
54#include <Qt3DRender/qviewport.h>
55#include <Qt3DRender/private/qrenderaspect_p.h>
56
57QT_BEGIN_NAMESPACE
58
59namespace Qt3DRender {
60
61class TestAspect : public Qt3DRender::QRenderAspect
62{
63public:
64 TestAspect(Qt3DCore::QNode *root)
65 : Qt3DRender::QRenderAspect(Qt3DRender::QRenderAspect::Synchronous)
66 , m_jobManager(new Qt3DCore::QAspectJobManager())
67 {
68 Qt3DCore::QAbstractAspectPrivate::get(aspect: this)->m_jobManager = m_jobManager.data();
69 QRenderAspect::onRegistered();
70
71 QVector<Qt3DCore::QNode *> nodes;
72 Qt3DCore::QNodeVisitor v;
73 v.traverse(rootNode_: root, fN: [&nodes](Qt3DCore::QNode *node) {
74 Qt3DCore::QNodePrivate *d = Qt3DCore::QNodePrivate::get(q: node);
75 d->m_typeInfo = const_cast<QMetaObject*>(Qt3DCore::QNodePrivate::findStaticMetaObject(metaObject: node->metaObject()));
76 d->m_hasBackendNode = true;
77 nodes << node;
78 });
79
80 for (const auto node: nodes)
81 d_func()->createBackendNode(change: {
82 .id: node->id(),
83 .metaObj: Qt3DCore::QNodePrivate::get(q: node)->m_typeInfo,
84 .type: Qt3DCore::NodeTreeChange::Added,
85 .node: node
86 });
87
88 const auto handles = nodeManagers()->techniqueManager()->activeHandles();
89 for (const auto &handle: handles) {
90 Render::Technique *technique = nodeManagers()->techniqueManager()->data(handle);
91 technique->setCompatibleWithRenderer(true);
92 }
93 }
94
95 ~TestAspect()
96 {
97 QRenderAspect::onUnregistered();
98 }
99
100 Qt3DRender::Render::NodeManagers *nodeManagers() const
101 {
102 return d_func()->m_renderer->nodeManagers();
103 }
104
105 void initializeRenderer()
106 {
107 d_func()->m_renderer->initialize();
108 }
109
110 Render::OpenGL::MaterialParameterGathererJobPtr materialGathererJob() const
111 {
112 Render::OpenGL::MaterialParameterGathererJobPtr job = Render::OpenGL::MaterialParameterGathererJobPtr::create();
113 job->setNodeManagers(nodeManagers());
114 return job;
115 }
116
117 void onRegistered() { QRenderAspect::onRegistered(); }
118 void onUnregistered() { QRenderAspect::onUnregistered(); }
119
120private:
121 QScopedPointer<Qt3DCore::QAspectJobManager> m_jobManager;
122};
123
124} // namespace Qt3DRender
125
126QT_END_NAMESPACE
127
128namespace {
129
130class TestMaterial : public Qt3DRender::QMaterial
131{
132 Q_OBJECT
133public:
134 explicit TestMaterial(Qt3DCore::QNode *parent = nullptr)
135 : Qt3DRender::QMaterial(parent)
136 , m_effect(new Qt3DRender::QEffect())
137 , m_gl3Technique(new Qt3DRender::QTechnique())
138 , m_gl2Technique(new Qt3DRender::QTechnique())
139 , m_es2Technique(new Qt3DRender::QTechnique())
140 , m_gl3Pass(new Qt3DRender::QRenderPass())
141 , m_gl2Pass(new Qt3DRender::QRenderPass())
142 , m_es2Pass(new Qt3DRender::QRenderPass())
143 , m_gl3Program(new Qt3DRender::QShaderProgram())
144 , m_gl2es2Program(new Qt3DRender::QShaderProgram())
145 {
146 m_gl3Pass->setShaderProgram(m_gl3Program);
147 m_gl2Pass->setShaderProgram(m_gl2es2Program);
148 m_es2Pass->setShaderProgram(m_gl2es2Program);
149
150 m_gl3Technique->addRenderPass(pass: m_gl3Pass);
151 m_gl2Technique->addRenderPass(pass: m_gl2Pass);
152 m_es2Technique->addRenderPass(pass: m_es2Pass);
153
154 m_effect->addTechnique(t: m_gl3Technique);
155 m_effect->addTechnique(t: m_gl2Technique);
156 m_effect->addTechnique(t: m_es2Technique);
157
158 setEffect(m_effect);
159 }
160
161 Qt3DRender::QTechnique *gl3Technique() const { return m_gl3Technique; }
162 Qt3DRender::QTechnique *gl2Technique() const { return m_gl2Technique; }
163 Qt3DRender::QTechnique *es2Technique() const { return m_es2Technique; }
164
165 Qt3DRender::QRenderPass *gl3Pass() const { return m_gl3Pass; }
166 Qt3DRender::QRenderPass *gl2Pass() const { return m_gl2Pass; }
167 Qt3DRender::QRenderPass *es2Pass() const { return m_es2Pass; }
168
169 Qt3DRender::QShaderProgram *gl3Shader() const { return m_gl3Program; }
170 Qt3DRender::QShaderProgram *gl2shader() const { return m_gl2es2Program; }
171 Qt3DRender::QShaderProgram *es2Shader() const { return m_gl2es2Program; }
172
173private:
174 Qt3DRender::QEffect *m_effect;
175 Qt3DRender::QTechnique *m_gl3Technique;
176 Qt3DRender::QTechnique *m_gl2Technique;
177 Qt3DRender::QTechnique *m_es2Technique;
178 Qt3DRender::QRenderPass *m_gl3Pass;
179 Qt3DRender::QRenderPass *m_gl2Pass;
180 Qt3DRender::QRenderPass *m_es2Pass;
181 Qt3DRender::QShaderProgram *m_gl3Program;
182 Qt3DRender::QShaderProgram *m_gl2es2Program;
183};
184
185Qt3DRender::QViewport *viewportFrameGraph()
186{
187 Qt3DRender::QViewport *viewport = new Qt3DRender::QViewport();
188 return viewport;
189}
190
191Qt3DRender::QTechniqueFilter *techniqueFilterFrameGraph()
192{
193 Qt3DRender::QTechniqueFilter *techniqueFilter = new Qt3DRender::QTechniqueFilter();
194 return techniqueFilter;
195}
196
197Qt3DRender::QRenderPassFilter *renderPassFilter()
198{
199 Qt3DRender::QRenderPassFilter *passFilter = new Qt3DRender::QRenderPassFilter();
200 return passFilter;
201}
202
203Qt3DCore::QEntity *buildScene(Qt3DRender::QFrameGraphNode *frameGraph, Qt3DRender::QMaterial *material = nullptr)
204{
205 Qt3DCore::QEntity *root = new Qt3DCore::QEntity();
206
207 // FrameGraph
208 Qt3DRender::QRenderSettings* renderSettings = new Qt3DRender::QRenderSettings();
209 renderSettings->setActiveFrameGraph(frameGraph);
210 root->addComponent(comp: renderSettings);
211
212 // Scene
213 for (int i = 0; i < 10; i++) {
214 Qt3DCore::QEntity *e = new Qt3DCore::QEntity();
215 if (material != nullptr)
216 e->addComponent(comp: material);
217 e->setParent(root);
218 }
219
220 return root;
221}
222
223} // anonymous
224
225class tst_MaterialParameterGatherer : public QObject
226{
227 Q_OBJECT
228private Q_SLOTS:
229
230 void checkRunNoHandlesNoTechniqueFilterNoPassFilter()
231 {
232 // GIVEN
233 Qt3DCore::QEntity *sceneRoot = buildScene(frameGraph: viewportFrameGraph());
234 Qt3DRender::TestAspect testAspect(sceneRoot);
235 Qt3DRender::Render::OpenGL::MaterialParameterGathererJobPtr gatherer = testAspect.materialGathererJob();
236
237 testAspect.initializeRenderer();
238
239 // THEN
240 QCOMPARE(testAspect.nodeManagers()->materialManager()->activeHandles().size(), 0);
241
242 // WHEN
243 gatherer->run();
244
245 // THEN
246 QCOMPARE(gatherer->materialToPassAndParameter().size(), 0);
247 }
248
249 void checkRunSelectAllNoTechniqueFilterNoPassFilter()
250 {
251 // GIVEN
252 TestMaterial material;
253 Qt3DCore::QEntity *sceneRoot = buildScene(frameGraph: viewportFrameGraph(), material: &material);
254 Qt3DRender::TestAspect testAspect(sceneRoot);
255 Qt3DRender::Render::OpenGL::MaterialParameterGathererJobPtr gatherer = testAspect.materialGathererJob();
256
257 testAspect.initializeRenderer();
258
259 // THEN
260 QCOMPARE(testAspect.nodeManagers()->materialManager()->activeHandles().size(), 1);
261
262 // WHEN
263 gatherer->setHandles(testAspect.nodeManagers()->materialManager()->activeHandles());
264 gatherer->run();
265
266 // THEN
267 QCOMPARE(gatherer->materialToPassAndParameter().size(), 1);
268 }
269
270 void checkRunDisabledMaterial()
271 {
272 // GIVEN
273 TestMaterial material;
274 material.setEnabled(false);
275 Qt3DCore::QEntity *sceneRoot = buildScene(frameGraph: viewportFrameGraph(), material: &material);
276 Qt3DRender::TestAspect testAspect(sceneRoot);
277 Qt3DRender::Render::OpenGL::MaterialParameterGathererJobPtr gatherer = testAspect.materialGathererJob();
278
279 testAspect.initializeRenderer();
280
281 // THEN
282 QCOMPARE(testAspect.nodeManagers()->materialManager()->activeHandles().size(), 1);
283
284 // WHEN
285 gatherer->setHandles(testAspect.nodeManagers()->materialManager()->activeHandles());
286 gatherer->run();
287
288 // THEN
289 QCOMPARE(gatherer->materialToPassAndParameter().size(), 0);
290 }
291
292 void checkRunSelectAllTechniqueFilterWithNoFilterNoPassFilter()
293 {
294 // GIVEN
295 Qt3DRender::QTechniqueFilter *frameGraphFilter = techniqueFilterFrameGraph();
296
297 TestMaterial material;
298
299 Qt3DRender::QFilterKey techniqueFilterKey;
300 techniqueFilterKey.setName(QStringLiteral("renderingStyle"));
301 techniqueFilterKey.setValue(QVariant(QStringLiteral("backward")));
302
303 material.gl2Technique()->addFilterKey(filterKey: &techniqueFilterKey);
304 material.gl3Technique()->addFilterKey(filterKey: &techniqueFilterKey);
305 material.es2Technique()->addFilterKey(filterKey: &techniqueFilterKey);
306
307 Qt3DCore::QEntity *sceneRoot = buildScene(frameGraph: frameGraphFilter, material: &material);
308 Qt3DRender::TestAspect testAspect(sceneRoot);
309 Qt3DRender::Render::OpenGL::MaterialParameterGathererJobPtr gatherer = testAspect.materialGathererJob();
310
311 testAspect.initializeRenderer();
312
313 // THEN
314 QCOMPARE(testAspect.nodeManagers()->materialManager()->activeHandles().size(), 1);
315 Qt3DRender::Render::TechniqueFilter *backendTechniqueFilter = static_cast<Qt3DRender::Render::TechniqueFilter *>(testAspect.nodeManagers()->frameGraphManager()->lookupNode(id: frameGraphFilter->id()));
316 QVERIFY(backendTechniqueFilter != nullptr);
317
318 // WHEN
319 gatherer->setHandles(testAspect.nodeManagers()->materialManager()->activeHandles());
320 gatherer->setTechniqueFilter(backendTechniqueFilter);
321 gatherer->run();
322
323 // THEN
324 QCOMPARE(gatherer->materialToPassAndParameter().size(), 1);
325 }
326
327 void checkRunSelectAllTechniqueFilterWithIncompatibleFilterNoPassFilter()
328 {
329 // GIVEN
330 Qt3DRender::QTechniqueFilter *frameGraphFilter = techniqueFilterFrameGraph();
331 TestMaterial material;
332
333 Qt3DRender::QFilterKey techniqueFilterFilterKey;
334 techniqueFilterFilterKey.setName(QStringLiteral("renderingStyle"));
335 techniqueFilterFilterKey.setValue(QVariant(QStringLiteral("forward")));
336
337 Qt3DRender::QFilterKey techniqueFilterKey;
338 techniqueFilterKey.setName(QStringLiteral("renderingStyle"));
339 techniqueFilterKey.setValue(QVariant(QStringLiteral("backward")));
340
341 frameGraphFilter->addMatch(filterKey: &techniqueFilterFilterKey);
342
343 material.gl2Technique()->addFilterKey(filterKey: &techniqueFilterKey);
344 material.gl3Technique()->addFilterKey(filterKey: &techniqueFilterKey);
345 material.es2Technique()->addFilterKey(filterKey: &techniqueFilterKey);
346
347 Qt3DCore::QEntity *sceneRoot = buildScene(frameGraph: frameGraphFilter, material: &material);
348 Qt3DRender::TestAspect testAspect(sceneRoot);
349 Qt3DRender::Render::OpenGL::MaterialParameterGathererJobPtr gatherer = testAspect.materialGathererJob();
350
351 testAspect.initializeRenderer();
352
353 // THEN
354 QCOMPARE(testAspect.nodeManagers()->materialManager()->activeHandles().size(), 1);
355 Qt3DRender::Render::TechniqueFilter *backendTechniqueFilter = static_cast<Qt3DRender::Render::TechniqueFilter *>(testAspect.nodeManagers()->frameGraphManager()->lookupNode(id: frameGraphFilter->id()));
356 QVERIFY(backendTechniqueFilter != nullptr);
357
358 // WHEN
359 gatherer->setHandles(testAspect.nodeManagers()->materialManager()->activeHandles());
360 gatherer->setTechniqueFilter(backendTechniqueFilter);
361 gatherer->run();
362
363 // THEN
364 QCOMPARE(gatherer->materialToPassAndParameter().size(), 0);
365 }
366
367 void checkRunSelectAllTechniqueFilterWithCompatibleFilterNoPassFilter()
368 {
369 // GIVEN
370 Qt3DRender::QTechniqueFilter *frameGraphFilter = techniqueFilterFrameGraph();
371 TestMaterial material;
372
373 Qt3DRender::QFilterKey techniqueFilterKey;
374 techniqueFilterKey.setName(QStringLiteral("renderingStyle"));
375 techniqueFilterKey.setValue(QVariant(QStringLiteral("backward")));
376
377 frameGraphFilter->addMatch(filterKey: &techniqueFilterKey);
378
379 material.gl2Technique()->addFilterKey(filterKey: &techniqueFilterKey);
380 material.gl3Technique()->addFilterKey(filterKey: &techniqueFilterKey);
381 material.es2Technique()->addFilterKey(filterKey: &techniqueFilterKey);
382
383 Qt3DCore::QEntity *sceneRoot = buildScene(frameGraph: frameGraphFilter, material: &material);
384 Qt3DRender::TestAspect testAspect(sceneRoot);
385 Qt3DRender::Render::OpenGL::MaterialParameterGathererJobPtr gatherer = testAspect.materialGathererJob();
386
387 testAspect.initializeRenderer();
388
389 // THEN
390 QCOMPARE(testAspect.nodeManagers()->materialManager()->activeHandles().size(), 1);
391 Qt3DRender::Render::TechniqueFilter *backendTechniqueFilter = static_cast<Qt3DRender::Render::TechniqueFilter *>(testAspect.nodeManagers()->frameGraphManager()->lookupNode(id: frameGraphFilter->id()));
392 QVERIFY(backendTechniqueFilter != nullptr);
393
394 // WHEN
395 gatherer->setHandles(testAspect.nodeManagers()->materialManager()->activeHandles());
396 gatherer->setTechniqueFilter(backendTechniqueFilter);
397 gatherer->run();
398
399 // THEN
400 QCOMPARE(gatherer->materialToPassAndParameter().size(), 1);
401 }
402
403 void checkRunSelectAllNoTechniqueFilterPassFilterWithNoFilter()
404 {
405 // GIVEN
406 Qt3DRender::QRenderPassFilter *frameGraphFilter = renderPassFilter();
407 TestMaterial material;
408
409 Qt3DRender::QFilterKey passFilterKey;
410 passFilterKey.setName(QStringLiteral("renderingStyle"));
411 passFilterKey.setValue(QVariant(QStringLiteral("backward")));
412
413 material.gl3Pass()->addFilterKey(filterKey: &passFilterKey);
414 material.gl2Pass()->addFilterKey(filterKey: &passFilterKey);
415 material.es2Pass()->addFilterKey(filterKey: &passFilterKey);
416
417 Qt3DCore::QEntity *sceneRoot = buildScene(frameGraph: frameGraphFilter, material: &material);
418 Qt3DRender::TestAspect testAspect(sceneRoot);
419 Qt3DRender::Render::OpenGL::MaterialParameterGathererJobPtr gatherer = testAspect.materialGathererJob();
420
421 testAspect.initializeRenderer();
422
423 // THEN
424 QCOMPARE(testAspect.nodeManagers()->materialManager()->activeHandles().size(), 1);
425 Qt3DRender::Render::RenderPassFilter *backendPassFilter = static_cast<Qt3DRender::Render::RenderPassFilter *>(testAspect.nodeManagers()->frameGraphManager()->lookupNode(id: frameGraphFilter->id()));
426 QVERIFY(backendPassFilter != nullptr);
427
428 // WHEN
429 gatherer->setHandles(testAspect.nodeManagers()->materialManager()->activeHandles());
430 gatherer->setRenderPassFilter(backendPassFilter);
431 gatherer->run();
432
433 // THEN
434 QCOMPARE(gatherer->materialToPassAndParameter().size(), 1);
435 }
436
437 void checkRunSelectAllNoTechniqueFilterPassFilterWithIncompatibleFilter()
438 {
439 // GIVEN
440 Qt3DRender::QRenderPassFilter *frameGraphFilter = renderPassFilter();
441 TestMaterial material;
442
443 Qt3DRender::QFilterKey passFilterFilterKey;
444 passFilterFilterKey.setName(QStringLiteral("renderingStyle"));
445 passFilterFilterKey.setValue(QVariant(QStringLiteral("forward")));
446
447 Qt3DRender::QFilterKey passFilterKey;
448 passFilterKey.setName(QStringLiteral("renderingStyle"));
449 passFilterKey.setValue(QVariant(QStringLiteral("backward")));
450
451 frameGraphFilter->addMatch(filterKey: &passFilterFilterKey);
452
453 material.gl3Pass()->addFilterKey(filterKey: &passFilterKey);
454 material.gl2Pass()->addFilterKey(filterKey: &passFilterKey);
455 material.es2Pass()->addFilterKey(filterKey: &passFilterKey);
456
457 Qt3DCore::QEntity *sceneRoot = buildScene(frameGraph: frameGraphFilter, material: &material);
458 Qt3DRender::TestAspect testAspect(sceneRoot);
459 Qt3DRender::Render::OpenGL::MaterialParameterGathererJobPtr gatherer = testAspect.materialGathererJob();
460
461 testAspect.initializeRenderer();
462
463 // THEN
464 QCOMPARE(testAspect.nodeManagers()->materialManager()->activeHandles().size(), 1);
465 Qt3DRender::Render::RenderPassFilter *backendPassFilter = static_cast<Qt3DRender::Render::RenderPassFilter *>(testAspect.nodeManagers()->frameGraphManager()->lookupNode(id: frameGraphFilter->id()));
466 QVERIFY(backendPassFilter != nullptr);
467
468 // WHEN
469 gatherer->setHandles(testAspect.nodeManagers()->materialManager()->activeHandles());
470 gatherer->setRenderPassFilter(backendPassFilter);
471 gatherer->run();
472
473 // THEN
474 QCOMPARE(gatherer->materialToPassAndParameter().size(), 0);
475 }
476
477 void checkParameterPriorityGathering()
478 {
479 {
480 // GIVEN
481 Qt3DRender::QTechniqueFilter *techniqueFilterFG = techniqueFilterFrameGraph();
482 Qt3DRender::QRenderPassFilter *renderPassFG = renderPassFilter();
483
484 renderPassFG->setParent(techniqueFilterFG);
485
486 TestMaterial material;
487
488 Qt3DCore::QEntity *sceneRoot = buildScene(frameGraph: techniqueFilterFG, material: &material);
489
490 // WHEN
491 techniqueFilterFG->addParameter(p: new Qt3DRender::QParameter(QStringLiteral("color"), QVariant(QColor(Qt::red))));
492
493 auto renderPassParameter = new Qt3DRender::QParameter(QStringLiteral("color"), QVariant(QColor(Qt::cyan)));
494
495 renderPassFG->addParameter(parameter: renderPassParameter);
496 material.addParameter(parameter: new Qt3DRender::QParameter(QStringLiteral("color"), QVariant(QColor(Qt::green))));
497 material.effect()->addParameter(parameter: new Qt3DRender::QParameter(QStringLiteral("color"), QVariant(QColor(Qt::blue))));
498
499 auto techniqueParam = new Qt3DRender::QParameter(QStringLiteral("color"), QVariant(QColor(Qt::white)));
500
501 material.gl3Technique()->addParameter(p: techniqueParam);
502 material.gl2Technique()->addParameter(p: techniqueParam);
503 material.es2Technique()->addParameter(p: techniqueParam);
504
505 auto passParam = new Qt3DRender::QParameter(QStringLiteral("color"), QVariant(QColor(Qt::gray)));
506
507 material.gl3Pass()->addParameter(p: passParam);
508 material.gl2Pass()->addParameter(p: passParam);
509 material.es2Pass()->addParameter(p: passParam);
510
511 Qt3DRender::TestAspect testAspect(sceneRoot);
512 Qt3DRender::Render::OpenGL::MaterialParameterGathererJobPtr gatherer = testAspect.materialGathererJob();
513 testAspect.initializeRenderer();
514
515 QCOMPARE(testAspect.nodeManagers()->materialManager()->activeHandles().size(), 1);
516 Qt3DRender::Render::TechniqueFilter *backendTechniqueFilter = static_cast<Qt3DRender::Render::TechniqueFilter *>(testAspect.nodeManagers()->frameGraphManager()->lookupNode(id: techniqueFilterFG->id()));
517 Qt3DRender::Render::RenderPassFilter *backendRenderPassFilter = static_cast<Qt3DRender::Render::RenderPassFilter *>(testAspect.nodeManagers()->frameGraphManager()->lookupNode(id: renderPassFG->id()));
518 QVERIFY(backendTechniqueFilter != nullptr);
519 QVERIFY(backendRenderPassFilter != nullptr);
520
521 gatherer->setHandles(testAspect.nodeManagers()->materialManager()->activeHandles());
522 gatherer->setRenderPassFilter(backendRenderPassFilter);
523 gatherer->setTechniqueFilter(backendTechniqueFilter);
524 gatherer->run();
525
526 // THEN -> RenderPassFilter wins
527 QCOMPARE(gatherer->materialToPassAndParameter().size(), 1);
528
529 const QVector<Qt3DRender::Render::OpenGL::RenderPassParameterData> passParameterData = gatherer->materialToPassAndParameter().begin().value();
530 QCOMPARE(passParameterData.size(), 1);
531
532 const Qt3DRender::Render::OpenGL::RenderPassParameterData data = passParameterData.first();
533
534 QCOMPARE(data.parameterInfo.size(), 1);
535 QCOMPARE(data.parameterInfo.first().handle, testAspect.nodeManagers()->parameterManager()->lookupHandle(renderPassParameter->id()));
536 }
537 {
538 // GIVEN
539 Qt3DRender::QTechniqueFilter *techniqueFilterFG = techniqueFilterFrameGraph();
540 Qt3DRender::QRenderPassFilter *renderPassFG = renderPassFilter();
541
542 renderPassFG->setParent(techniqueFilterFG);
543
544 TestMaterial material;
545
546 Qt3DCore::QEntity *sceneRoot = buildScene(frameGraph: techniqueFilterFG, material: &material);
547
548 // WHEN
549 auto techniqueFilterParameter = new Qt3DRender::QParameter(QStringLiteral("color"), QVariant(QColor(Qt::cyan)));
550 techniqueFilterFG->addParameter(p: techniqueFilterParameter);
551
552 material.addParameter(parameter: new Qt3DRender::QParameter(QStringLiteral("color"), QVariant(QColor(Qt::green))));
553 material.effect()->addParameter(parameter: new Qt3DRender::QParameter(QStringLiteral("color"), QVariant(QColor(Qt::blue))));
554
555 auto techniqueParam = new Qt3DRender::QParameter(QStringLiteral("color"), QVariant(QColor(Qt::white)));
556
557 material.gl3Technique()->addParameter(p: techniqueParam);
558 material.gl2Technique()->addParameter(p: techniqueParam);
559 material.es2Technique()->addParameter(p: techniqueParam);
560
561 auto passParam = new Qt3DRender::QParameter(QStringLiteral("color"), QVariant(QColor(Qt::gray)));
562
563 material.gl3Pass()->addParameter(p: passParam);
564 material.gl2Pass()->addParameter(p: passParam);
565 material.es2Pass()->addParameter(p: passParam);
566
567 Qt3DRender::TestAspect testAspect(sceneRoot);
568 Qt3DRender::Render::OpenGL::MaterialParameterGathererJobPtr gatherer = testAspect.materialGathererJob();
569 testAspect.initializeRenderer();
570
571 QCOMPARE(testAspect.nodeManagers()->materialManager()->activeHandles().size(), 1);
572 Qt3DRender::Render::TechniqueFilter *backendTechniqueFilter = static_cast<Qt3DRender::Render::TechniqueFilter *>(testAspect.nodeManagers()->frameGraphManager()->lookupNode(id: techniqueFilterFG->id()));
573 Qt3DRender::Render::RenderPassFilter *backendRenderPassFilter = static_cast<Qt3DRender::Render::RenderPassFilter *>(testAspect.nodeManagers()->frameGraphManager()->lookupNode(id: renderPassFG->id()));
574 QVERIFY(backendTechniqueFilter != nullptr);
575 QVERIFY(backendRenderPassFilter != nullptr);
576
577 gatherer->setHandles(testAspect.nodeManagers()->materialManager()->activeHandles());
578 gatherer->setRenderPassFilter(backendRenderPassFilter);
579 gatherer->setTechniqueFilter(backendTechniqueFilter);
580 gatherer->run();
581
582 // THEN -> TechniqueFilter wins
583 QCOMPARE(gatherer->materialToPassAndParameter().size(), 1);
584
585 const QVector<Qt3DRender::Render::OpenGL::RenderPassParameterData> passParameterData = gatherer->materialToPassAndParameter().begin().value();
586 QCOMPARE(passParameterData.size(), 1);
587
588 const Qt3DRender::Render::OpenGL::RenderPassParameterData data = passParameterData.first();
589
590 QCOMPARE(data.parameterInfo.size(), 1);
591 QCOMPARE(data.parameterInfo.first().handle, testAspect.nodeManagers()->parameterManager()->lookupHandle(techniqueFilterParameter->id()));
592 }
593 {
594 // GIVEN
595 Qt3DRender::QTechniqueFilter *techniqueFilterFG = techniqueFilterFrameGraph();
596 Qt3DRender::QRenderPassFilter *renderPassFG = renderPassFilter();
597
598 renderPassFG->setParent(techniqueFilterFG);
599
600 TestMaterial material;
601
602 Qt3DCore::QEntity *sceneRoot = buildScene(frameGraph: techniqueFilterFG, material: &material);
603
604 // WHEN
605 auto materialParameter = new Qt3DRender::QParameter(QStringLiteral("color"), QVariant(QColor(Qt::cyan)));
606
607 material.addParameter(parameter: materialParameter);
608 material.effect()->addParameter(parameter: new Qt3DRender::QParameter(QStringLiteral("color"), QVariant(QColor(Qt::blue))));
609
610 auto techniqueParam = new Qt3DRender::QParameter(QStringLiteral("color"), QVariant(QColor(Qt::white)));
611
612 material.gl3Technique()->addParameter(p: techniqueParam);
613 material.gl2Technique()->addParameter(p: techniqueParam);
614 material.es2Technique()->addParameter(p: techniqueParam);
615
616 auto passParam = new Qt3DRender::QParameter(QStringLiteral("color"), QVariant(QColor(Qt::gray)));
617
618 material.gl3Pass()->addParameter(p: passParam);
619 material.gl2Pass()->addParameter(p: passParam);
620 material.es2Pass()->addParameter(p: passParam);
621
622 Qt3DRender::TestAspect testAspect(sceneRoot);
623 Qt3DRender::Render::OpenGL::MaterialParameterGathererJobPtr gatherer = testAspect.materialGathererJob();
624 testAspect.initializeRenderer();
625
626 QCOMPARE(testAspect.nodeManagers()->materialManager()->activeHandles().size(), 1);
627 Qt3DRender::Render::TechniqueFilter *backendTechniqueFilter = static_cast<Qt3DRender::Render::TechniqueFilter *>(testAspect.nodeManagers()->frameGraphManager()->lookupNode(id: techniqueFilterFG->id()));
628 Qt3DRender::Render::RenderPassFilter *backendRenderPassFilter = static_cast<Qt3DRender::Render::RenderPassFilter *>(testAspect.nodeManagers()->frameGraphManager()->lookupNode(id: renderPassFG->id()));
629 QVERIFY(backendTechniqueFilter != nullptr);
630 QVERIFY(backendRenderPassFilter != nullptr);
631
632 gatherer->setHandles(testAspect.nodeManagers()->materialManager()->activeHandles());
633 gatherer->setRenderPassFilter(backendRenderPassFilter);
634 gatherer->setTechniqueFilter(backendTechniqueFilter);
635 gatherer->run();
636
637 // THEN -> TechniqueFilter wins
638 QCOMPARE(gatherer->materialToPassAndParameter().size(), 1);
639
640 const QVector<Qt3DRender::Render::OpenGL::RenderPassParameterData> passParameterData = gatherer->materialToPassAndParameter().begin().value();
641 QCOMPARE(passParameterData.size(), 1);
642
643 const Qt3DRender::Render::OpenGL::RenderPassParameterData data = passParameterData.first();
644
645 QCOMPARE(data.parameterInfo.size(), 1);
646 QCOMPARE(data.parameterInfo.first().handle, testAspect.nodeManagers()->parameterManager()->lookupHandle(materialParameter->id()));
647 }
648 {
649 // GIVEN
650 Qt3DRender::QTechniqueFilter *techniqueFilterFG = techniqueFilterFrameGraph();
651 Qt3DRender::QRenderPassFilter *renderPassFG = renderPassFilter();
652
653 renderPassFG->setParent(techniqueFilterFG);
654
655 TestMaterial material;
656
657 Qt3DCore::QEntity *sceneRoot = buildScene(frameGraph: techniqueFilterFG, material: &material);
658
659 // WHEN
660 auto effectParameter = new Qt3DRender::QParameter(QStringLiteral("color"), QVariant(QColor(Qt::cyan)));
661
662 material.effect()->addParameter(parameter: effectParameter);
663
664 auto techniqueParam = new Qt3DRender::QParameter(QStringLiteral("color"), QVariant(QColor(Qt::white)));
665
666 material.gl3Technique()->addParameter(p: techniqueParam);
667 material.gl2Technique()->addParameter(p: techniqueParam);
668 material.es2Technique()->addParameter(p: techniqueParam);
669
670 auto passParam = new Qt3DRender::QParameter(QStringLiteral("color"), QVariant(QColor(Qt::gray)));
671
672 material.gl3Pass()->addParameter(p: passParam);
673 material.gl2Pass()->addParameter(p: passParam);
674 material.es2Pass()->addParameter(p: passParam);
675
676 Qt3DRender::TestAspect testAspect(sceneRoot);
677 Qt3DRender::Render::OpenGL::MaterialParameterGathererJobPtr gatherer = testAspect.materialGathererJob();
678 testAspect.initializeRenderer();
679
680 QCOMPARE(testAspect.nodeManagers()->materialManager()->activeHandles().size(), 1);
681 Qt3DRender::Render::TechniqueFilter *backendTechniqueFilter = static_cast<Qt3DRender::Render::TechniqueFilter *>(testAspect.nodeManagers()->frameGraphManager()->lookupNode(id: techniqueFilterFG->id()));
682 Qt3DRender::Render::RenderPassFilter *backendRenderPassFilter = static_cast<Qt3DRender::Render::RenderPassFilter *>(testAspect.nodeManagers()->frameGraphManager()->lookupNode(id: renderPassFG->id()));
683 QVERIFY(backendTechniqueFilter != nullptr);
684 QVERIFY(backendRenderPassFilter != nullptr);
685
686 gatherer->setHandles(testAspect.nodeManagers()->materialManager()->activeHandles());
687 gatherer->setRenderPassFilter(backendRenderPassFilter);
688 gatherer->setTechniqueFilter(backendTechniqueFilter);
689 gatherer->run();
690
691 // THEN -> TechniqueFilter wins
692 QCOMPARE(gatherer->materialToPassAndParameter().size(), 1);
693
694 const QVector<Qt3DRender::Render::OpenGL::RenderPassParameterData> passParameterData = gatherer->materialToPassAndParameter().begin().value();
695 QCOMPARE(passParameterData.size(), 1);
696
697 const Qt3DRender::Render::OpenGL::RenderPassParameterData data = passParameterData.first();
698
699 QCOMPARE(data.parameterInfo.size(), 1);
700 QCOMPARE(data.parameterInfo.first().handle, testAspect.nodeManagers()->parameterManager()->lookupHandle(effectParameter->id()));
701 }
702 {
703 // GIVEN
704 Qt3DRender::QTechniqueFilter *techniqueFilterFG = techniqueFilterFrameGraph();
705 Qt3DRender::QRenderPassFilter *renderPassFG = renderPassFilter();
706
707 renderPassFG->setParent(techniqueFilterFG);
708
709 TestMaterial material;
710
711 Qt3DCore::QEntity *sceneRoot = buildScene(frameGraph: techniqueFilterFG, material: &material);
712
713 // WHEN
714 auto techniqueParam = new Qt3DRender::QParameter(QStringLiteral("color"), QVariant(QColor(Qt::white)));
715
716 material.gl3Technique()->addParameter(p: techniqueParam);
717 material.gl2Technique()->addParameter(p: techniqueParam);
718 material.es2Technique()->addParameter(p: techniqueParam);
719
720 auto passParam = new Qt3DRender::QParameter(QStringLiteral("color"), QVariant(QColor(Qt::gray)));
721
722 material.gl3Pass()->addParameter(p: passParam);
723 material.gl2Pass()->addParameter(p: passParam);
724 material.es2Pass()->addParameter(p: passParam);
725
726 Qt3DRender::TestAspect testAspect(sceneRoot);
727 Qt3DRender::Render::OpenGL::MaterialParameterGathererJobPtr gatherer = testAspect.materialGathererJob();
728 testAspect.initializeRenderer();
729
730 QCOMPARE(testAspect.nodeManagers()->materialManager()->activeHandles().size(), 1);
731 Qt3DRender::Render::TechniqueFilter *backendTechniqueFilter = static_cast<Qt3DRender::Render::TechniqueFilter *>(testAspect.nodeManagers()->frameGraphManager()->lookupNode(id: techniqueFilterFG->id()));
732 Qt3DRender::Render::RenderPassFilter *backendRenderPassFilter = static_cast<Qt3DRender::Render::RenderPassFilter *>(testAspect.nodeManagers()->frameGraphManager()->lookupNode(id: renderPassFG->id()));
733 QVERIFY(backendTechniqueFilter != nullptr);
734 QVERIFY(backendRenderPassFilter != nullptr);
735
736 gatherer->setHandles(testAspect.nodeManagers()->materialManager()->activeHandles());
737 gatherer->setRenderPassFilter(backendRenderPassFilter);
738 gatherer->setTechniqueFilter(backendTechniqueFilter);
739 gatherer->run();
740
741 // THEN -> TechniqueFilter wins
742 QCOMPARE(gatherer->materialToPassAndParameter().size(), 1);
743
744 const QVector<Qt3DRender::Render::OpenGL::RenderPassParameterData> passParameterData = gatherer->materialToPassAndParameter().begin().value();
745 QCOMPARE(passParameterData.size(), 1);
746
747 const Qt3DRender::Render::OpenGL::RenderPassParameterData data = passParameterData.first();
748
749 QCOMPARE(data.parameterInfo.size(), 1);
750 QCOMPARE(data.parameterInfo.first().handle, testAspect.nodeManagers()->parameterManager()->lookupHandle(techniqueParam->id()));
751 }
752 {
753 // GIVEN
754 Qt3DRender::QTechniqueFilter *techniqueFilterFG = techniqueFilterFrameGraph();
755 Qt3DRender::QRenderPassFilter *renderPassFG = renderPassFilter();
756
757 renderPassFG->setParent(techniqueFilterFG);
758
759 TestMaterial material;
760
761 Qt3DCore::QEntity *sceneRoot = buildScene(frameGraph: techniqueFilterFG, material: &material);
762
763 // WHEN
764 auto passParam = new Qt3DRender::QParameter(QStringLiteral("color"), QVariant(QColor(Qt::gray)));
765
766 material.gl3Pass()->addParameter(p: passParam);
767 material.gl2Pass()->addParameter(p: passParam);
768 material.es2Pass()->addParameter(p: passParam);
769
770 Qt3DRender::TestAspect testAspect(sceneRoot);
771 Qt3DRender::Render::OpenGL::MaterialParameterGathererJobPtr gatherer = testAspect.materialGathererJob();
772 testAspect.initializeRenderer();
773
774 QCOMPARE(testAspect.nodeManagers()->materialManager()->activeHandles().size(), 1);
775 Qt3DRender::Render::TechniqueFilter *backendTechniqueFilter = static_cast<Qt3DRender::Render::TechniqueFilter *>(testAspect.nodeManagers()->frameGraphManager()->lookupNode(id: techniqueFilterFG->id()));
776 Qt3DRender::Render::RenderPassFilter *backendRenderPassFilter = static_cast<Qt3DRender::Render::RenderPassFilter *>(testAspect.nodeManagers()->frameGraphManager()->lookupNode(id: renderPassFG->id()));
777 QVERIFY(backendTechniqueFilter != nullptr);
778 QVERIFY(backendRenderPassFilter != nullptr);
779
780 gatherer->setHandles(testAspect.nodeManagers()->materialManager()->activeHandles());
781 gatherer->setRenderPassFilter(backendRenderPassFilter);
782 gatherer->setTechniqueFilter(backendTechniqueFilter);
783 gatherer->run();
784
785 // THEN -> TechniqueFilter wins
786 QCOMPARE(gatherer->materialToPassAndParameter().size(), 1);
787
788 const QVector<Qt3DRender::Render::OpenGL::RenderPassParameterData> passParameterData = gatherer->materialToPassAndParameter().begin().value();
789 QCOMPARE(passParameterData.size(), 1);
790
791 const Qt3DRender::Render::OpenGL::RenderPassParameterData data = passParameterData.first();
792
793 QCOMPARE(data.parameterInfo.size(), 1);
794 QCOMPARE(data.parameterInfo.first().handle, testAspect.nodeManagers()->parameterManager()->lookupHandle(passParam->id()));
795 }
796 }
797};
798
799QTEST_MAIN(tst_MaterialParameterGatherer)
800
801#include "tst_materialparametergathererjob.moc"
802

source code of qt3d/tests/auto/render/opengl/materialparametergathererjob/tst_materialparametergathererjob.cpp