1/****************************************************************************
2**
3** Copyright (C) 2015 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// TODO Remove in Qt6
30#include <QtCore/qcompilerdetection.h>
31QT_WARNING_DISABLE_DEPRECATED
32
33#include <QtTest/QTest>
34#include <qbackendnodetester.h>
35#include <Qt3DRender/private/geometry_p.h>
36#include <Qt3DRender/qgeometry.h>
37#include <Qt3DRender/qattribute.h>
38#include <Qt3DCore/qpropertyupdatedchange.h>
39#include <Qt3DCore/private/qbackendnode_p.h>
40#include "testrenderer.h"
41#include "testpostmanarbiter.h"
42
43class DummyAttribute : public Qt3DRender::QAttribute
44{
45 Q_OBJECT
46public:
47 DummyAttribute(Qt3DCore::QNode *parent = nullptr)
48 : Qt3DRender::QAttribute(parent)
49 {}
50};
51
52class tst_RenderGeometry : public Qt3DCore::QBackendNodeTester
53{
54 Q_OBJECT
55
56private Q_SLOTS:
57
58 void checkPeerPropertyMirroring()
59 {
60 // GIVEN
61 Qt3DRender::Render::Geometry renderGeometry;
62 TestRenderer renderer;
63
64 Qt3DRender::QGeometry geometry;
65 Qt3DRender::QAttribute attr1;
66 Qt3DRender::QAttribute attr2;
67 Qt3DRender::QAttribute attr4;
68 Qt3DRender::QAttribute attr3;
69
70 geometry.addAttribute(attribute: &attr1);
71 geometry.addAttribute(attribute: &attr2);
72 geometry.addAttribute(attribute: &attr3);
73 geometry.addAttribute(attribute: &attr4);
74 geometry.setBoundingVolumePositionAttribute(&attr1);
75 renderGeometry.setRenderer(&renderer);
76
77 // WHEN
78 simulateInitializationSync(frontend: &geometry, backend: &renderGeometry);
79
80 // THEN
81 QCOMPARE(renderGeometry.peerId(), geometry.id());
82 QCOMPARE(renderGeometry.isDirty(), true);
83 QCOMPARE(renderGeometry.attributes().count(), 4);
84 QCOMPARE(renderGeometry.boundingPositionAttribute(), attr1.id());
85
86 Qt3DCore::QNodeIdVector attribs = Qt3DCore::qIdsForNodes(nodes: geometry.attributes());
87 std::sort(first: std::begin(cont&: attribs), last: std::end(cont&: attribs));
88 QCOMPARE(attribs, renderGeometry.attributes());
89 }
90
91 void checkSetRendererDirtyOnInitialization()
92 {
93 // GIVEN
94 Qt3DRender::Render::Geometry renderGeometry;
95 Qt3DRender::QGeometry geometry;
96 TestRenderer renderer;
97
98 renderGeometry.setRenderer(&renderer);
99
100 // THEN
101 QCOMPARE(renderer.dirtyBits(), 0);
102
103 // WHEN
104 simulateInitializationSync(frontend: &geometry, backend: &renderGeometry);
105
106 // THEN
107 QCOMPARE(renderer.dirtyBits(), Qt3DRender::Render::AbstractRenderer::GeometryDirty);
108 }
109
110 void checkInitialAndCleanedUpState()
111 {
112 // GIVEN
113 TestRenderer renderer;
114 Qt3DRender::Render::Geometry renderGeometry;
115 renderGeometry.setRenderer(&renderer);
116
117 // THEN
118 QCOMPARE(renderGeometry.isDirty(), false);
119 QVERIFY(renderGeometry.attributes().isEmpty());
120 QVERIFY(renderGeometry.peerId().isNull());
121 QCOMPARE(renderGeometry.boundingPositionAttribute(), Qt3DCore::QNodeId());
122
123 // GIVEN
124 Qt3DRender::QGeometry geometry;
125 Qt3DRender::QAttribute attr1;
126 Qt3DRender::QAttribute attr2;
127 Qt3DRender::QAttribute attr4;
128 Qt3DRender::QAttribute attr3;
129 geometry.setBoundingVolumePositionAttribute(&attr1);
130
131 geometry.addAttribute(attribute: &attr1);
132 geometry.addAttribute(attribute: &attr2);
133 geometry.addAttribute(attribute: &attr3);
134 geometry.addAttribute(attribute: &attr4);
135
136 // WHEN
137 simulateInitializationSync(frontend: &geometry, backend: &renderGeometry);
138 renderGeometry.cleanup();
139
140 // THEN
141 QCOMPARE(renderGeometry.isDirty(), false);
142 QVERIFY(renderGeometry.attributes().isEmpty());
143 QCOMPARE(renderGeometry.boundingPositionAttribute(), Qt3DCore::QNodeId());
144 }
145
146 void checkPropertyChanges()
147 {
148 // GIVEN
149 TestRenderer renderer;
150 Qt3DRender::Render::Geometry renderGeometry;
151 renderGeometry.setRenderer(&renderer);
152 Qt3DRender::QGeometry geometry;
153
154 simulateInitializationSync(frontend: &geometry, backend: &renderGeometry);
155
156 DummyAttribute attribute;
157
158 // WHEN
159 geometry.addAttribute(attribute: &attribute);
160 renderGeometry.syncFromFrontEnd(frontEnd: &geometry, firstTime: false);
161
162 // THEN
163 QCOMPARE(renderGeometry.attributes().count(), 1);
164 QVERIFY(renderGeometry.isDirty());
165 QVERIFY(renderer.dirtyBits() & Qt3DRender::Render::AbstractRenderer::GeometryDirty);
166 renderer.clearDirtyBits(changes: Qt3DRender::Render::AbstractRenderer::AllDirty);
167
168 renderGeometry.unsetDirty();
169 QVERIFY(!renderGeometry.isDirty());
170
171 // WHEN
172 geometry.removeAttribute(attribute: &attribute);
173 renderGeometry.syncFromFrontEnd(frontEnd: &geometry, firstTime: false);
174
175 // THEN
176 QCOMPARE(renderGeometry.attributes().count(), 0);
177 QVERIFY(renderGeometry.isDirty());
178 QVERIFY(renderer.dirtyBits() & Qt3DRender::Render::AbstractRenderer::GeometryDirty);
179 renderer.clearDirtyBits(changes: Qt3DRender::Render::AbstractRenderer::AllDirty);
180
181 renderGeometry.unsetDirty();
182 QVERIFY(!renderGeometry.isDirty());
183
184 // WHEN
185 geometry.setBoundingVolumePositionAttribute(&attribute);
186 renderGeometry.syncFromFrontEnd(frontEnd: &geometry, firstTime: false);
187
188 // THEN
189 QCOMPARE(renderGeometry.boundingPositionAttribute(), attribute.id());
190 QVERIFY(!renderGeometry.isDirty());
191 QVERIFY(renderer.dirtyBits() & Qt3DRender::Render::AbstractRenderer::GeometryDirty);
192 renderer.clearDirtyBits(changes: Qt3DRender::Render::AbstractRenderer::AllDirty);
193 }
194
195 void checkExtentTransmission()
196 {
197 // GIVEN
198 TestRenderer renderer;
199 TestArbiter arbiter;
200 Qt3DRender::Render::Geometry renderGeometry;
201
202 Qt3DCore::QBackendNodePrivate::get(n: &renderGeometry)->setArbiter(&arbiter);
203 renderGeometry.setRenderer(&renderer);
204
205 // WHEN
206 renderGeometry.updateExtent(min: QVector3D(-1.0f, -1.0f, -1.0f), max: QVector3D(1.0f, 1.0f, 1.0f));
207 renderGeometry.notifyExtentChanged();
208
209 // THEN
210 QCOMPARE(arbiter.events.count(), 1);
211
212 Qt3DCore::QPropertyUpdatedChangePtr change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>();
213 QCOMPARE(change->propertyName(), "extent");
214 const QPair<QVector3D, QVector3D> v = change->value().value<QPair<QVector3D, QVector3D>>();
215 QCOMPARE(v.first, QVector3D(-1.0f, -1.0f, -1.0f));
216 QCOMPARE(v.second, QVector3D(1.0f, 1.0f, 1.0f));
217
218 arbiter.events.clear();
219 }
220};
221
222
223QTEST_APPLESS_MAIN(tst_RenderGeometry)
224
225#include "tst_geometry.moc"
226

source code of qt3d/tests/auto/render/geometry/tst_geometry.cpp