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: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 "qgeometryrenderer.h" |
41 | #include "qgeometryrenderer_p.h" |
42 | |
43 | #include <private/qcomponent_p.h> |
44 | |
45 | QT_BEGIN_NAMESPACE |
46 | |
47 | using namespace Qt3DCore; |
48 | |
49 | namespace Qt3DRender { |
50 | |
51 | /* |
52 | \internal |
53 | |
54 | sortIndex property: overrides the sorting index when depth sorting is enabled. |
55 | |
56 | If depth sorting is enabled on the frame graph, the renderer will sort |
57 | objects based on how far the center of the bounding volume is from |
58 | the camera and render objects from the furthest to the closest. |
59 | |
60 | This property can be used to override the depth index and precisely |
61 | control the order in which objects are rendered. This is useful when |
62 | all objects are at the same physical distance from the camera. |
63 | |
64 | The actual values are not significant, only that they define an order |
65 | to sort the objects. These are sorted such as the object with the |
66 | smallest value is drawn first, then the second smallest, and so on. |
67 | |
68 | \note Setting this to -1.f will disable the explicit sorting for this |
69 | entity and revert to using the distance from the center of the bounding |
70 | volume. |
71 | */ |
72 | |
73 | QGeometryRendererPrivate::QGeometryRendererPrivate() |
74 | : QComponentPrivate() |
75 | , m_instanceCount(1) |
76 | , m_vertexCount(0) |
77 | , m_indexOffset(0) |
78 | , m_firstInstance(0) |
79 | , m_firstVertex(0) |
80 | , m_indexBufferByteOffset(0) |
81 | , m_restartIndexValue(-1) |
82 | , m_verticesPerPatch(0) |
83 | , m_primitiveRestart(false) |
84 | , m_geometry(nullptr) |
85 | , m_primitiveType(QGeometryRenderer::Triangles) |
86 | , m_sortIndex(-1.f) |
87 | { |
88 | } |
89 | |
90 | QGeometryRendererPrivate::~QGeometryRendererPrivate() |
91 | { |
92 | } |
93 | |
94 | /*! |
95 | \qmltype GeometryRenderer |
96 | \instantiates Qt3DRender::QGeometryRenderer |
97 | \inqmlmodule Qt3D.Render |
98 | \inherits Component3D |
99 | \since 5.7 |
100 | \brief Encapsulates geometry rendering. |
101 | |
102 | A GeometryRenderer holds all the information necessary to draw |
103 | a Geometry. A Geometry holds the coordinates of the geometry data - |
104 | GeometryRenderer specifies how to interpret that data. |
105 | */ |
106 | |
107 | /*! |
108 | \class Qt3DRender::QGeometryRenderer |
109 | \inmodule Qt3DRender |
110 | \since 5.7 |
111 | \brief Encapsulates geometry rendering. |
112 | |
113 | A Qt3DRender::QGeometryRenderer holds all the information necessary to draw |
114 | a Qt3DRender::QGeometry. A QGeometry holds the coordinates of the geometry data - |
115 | QGeometryRenderer specifies how to interpret that data. |
116 | */ |
117 | |
118 | |
119 | /*! |
120 | \enum QGeometryRenderer::PrimitiveType |
121 | |
122 | The type of the primitive. |
123 | |
124 | \value Points List of points |
125 | \value Lines List of lines |
126 | \value LineLoop Connected group of lines connected at ends forming a loop |
127 | \value LineStrip Connected group of lines |
128 | \value Triangles List of triangles |
129 | \value TriangleStrip List of connected triangles |
130 | \value TriangleFan List of connected triagles where all triangles share the first vertex |
131 | \value LinesAdjacency Allows geometry shader to access adjacent lines in a line list |
132 | \value TrianglesAdjacency Allows geometry shader to access adjacent triangles in a triangle list |
133 | \value LineStripAdjacency Allows geometry shader to access adjacent lines in a line strip |
134 | \value TriangleStripAdjacency Allows geometry shader to access adjacent triangles in a triangle strip |
135 | \value Patches Only primitive type accepted by tesselation shader where a patch consists of arbitrary number of vertices |
136 | */ |
137 | |
138 | /*! |
139 | \qmlproperty int GeometryRenderer::instanceCount |
140 | |
141 | Holds the instance count. |
142 | */ |
143 | |
144 | /*! |
145 | \qmlproperty int GeometryRenderer::vertexCount |
146 | |
147 | Holds the vertex count. |
148 | */ |
149 | |
150 | /*! |
151 | \qmlproperty int GeometryRenderer::indexOffset |
152 | |
153 | Holds the base vertex. |
154 | */ |
155 | |
156 | /*! |
157 | \qmlproperty int GeometryRenderer::firstInstance |
158 | |
159 | Holds the base instance. |
160 | */ |
161 | |
162 | /*! |
163 | \qmlproperty int GeometryRenderer::firstVertex |
164 | |
165 | Holds the first vertex. |
166 | */ |
167 | |
168 | /*! |
169 | \qmlproperty int GeometryRenderer::indexBufferByteOffset |
170 | |
171 | Holds the byte offset into the index buffer. |
172 | */ |
173 | |
174 | /*! |
175 | \qmlproperty int GeometryRenderer::restartIndexValue |
176 | |
177 | Holds the restart index. |
178 | */ |
179 | |
180 | /*! |
181 | \qmlproperty int GeometryRenderer::verticesPerPatch |
182 | |
183 | Holds vertices per patch. |
184 | */ |
185 | |
186 | /*! |
187 | \qmlproperty bool GeometryRenderer::primitiveRestartEnabled |
188 | |
189 | Holds the primitive restart flag. |
190 | */ |
191 | |
192 | /*! |
193 | \qmlproperty Geometry GeometryRenderer::geometry |
194 | |
195 | Holds the geometry. |
196 | */ |
197 | |
198 | /*! |
199 | \qmlproperty enumeration GeometryRenderer::primitiveType |
200 | |
201 | Holds the primitive type. |
202 | |
203 | \list |
204 | \li QGeometryRenderer.Points |
205 | \li QGeometryRenderer.Lines |
206 | \li QGeometryRenderer.LineLoop |
207 | \li QGeometryRenderer.LineStrip |
208 | \li QGeometryRenderer.Triangles |
209 | \li QGeometryRenderer.TriangleStrip |
210 | \li QGeometryRenderer.TriangleFan |
211 | \li QGeometryRenderer.LinesAdjacency |
212 | \li QGeometryRenderer.TrianglesAdjacency |
213 | \li QGeometryRenderer.LineStripAdjacency |
214 | \li QGeometryRenderer.TriangleStripAdjacency |
215 | \li QGeometryRenderer.Patches |
216 | \endlist |
217 | \sa Qt3DRender::QGeometryRenderer::PrimitiveType |
218 | */ |
219 | |
220 | /*! |
221 | Constructs a new QGeometryRenderer with \a parent. |
222 | */ |
223 | QGeometryRenderer::QGeometryRenderer(QNode *parent) |
224 | : QComponent(*new QGeometryRendererPrivate(), parent) |
225 | { |
226 | } |
227 | |
228 | /*! |
229 | \internal |
230 | */ |
231 | QGeometryRenderer::~QGeometryRenderer() |
232 | { |
233 | } |
234 | |
235 | /*! |
236 | \internal |
237 | */ |
238 | QGeometryRenderer::QGeometryRenderer(QGeometryRendererPrivate &dd, QNode *parent) |
239 | : QComponent(dd, parent) |
240 | { |
241 | } |
242 | |
243 | // TODO Unused remove in Qt6 |
244 | void QGeometryRenderer::sceneChangeEvent(const QSceneChangePtr &) |
245 | { |
246 | } |
247 | |
248 | /*! |
249 | \property QGeometryRenderer::instanceCount |
250 | |
251 | Holds the instance count. |
252 | */ |
253 | int QGeometryRenderer::instanceCount() const |
254 | { |
255 | Q_D(const QGeometryRenderer); |
256 | return d->m_instanceCount; |
257 | } |
258 | |
259 | /*! |
260 | \property QGeometryRenderer::vertexCount |
261 | |
262 | Holds the primitive count. |
263 | */ |
264 | int QGeometryRenderer::vertexCount() const |
265 | { |
266 | Q_D(const QGeometryRenderer); |
267 | return d->m_vertexCount; |
268 | } |
269 | |
270 | /*! |
271 | \property QGeometryRenderer::indexOffset |
272 | |
273 | Holds the base vertex. |
274 | */ |
275 | int QGeometryRenderer::indexOffset() const |
276 | { |
277 | Q_D(const QGeometryRenderer); |
278 | return d->m_indexOffset; |
279 | } |
280 | |
281 | /*! |
282 | \property QGeometryRenderer::firstInstance |
283 | |
284 | Holds the base instance. |
285 | */ |
286 | int QGeometryRenderer::firstInstance() const |
287 | { |
288 | Q_D(const QGeometryRenderer); |
289 | return d->m_firstInstance; |
290 | } |
291 | |
292 | /*! |
293 | \property QGeometryRenderer::firstVertex |
294 | |
295 | Holds the base vertex. |
296 | */ |
297 | int QGeometryRenderer::firstVertex() const |
298 | { |
299 | Q_D(const QGeometryRenderer); |
300 | return d->m_firstVertex; |
301 | } |
302 | |
303 | /*! |
304 | \property QGeometryRenderer::indexBufferByteOffset |
305 | |
306 | Holds the byte offset into the index buffer. |
307 | */ |
308 | int QGeometryRenderer::indexBufferByteOffset() const |
309 | { |
310 | Q_D(const QGeometryRenderer); |
311 | return d->m_indexBufferByteOffset; |
312 | } |
313 | |
314 | /*! |
315 | \property QGeometryRenderer::restartIndexValue |
316 | |
317 | Holds the restart index. |
318 | */ |
319 | int QGeometryRenderer::restartIndexValue() const |
320 | { |
321 | Q_D(const QGeometryRenderer); |
322 | return d->m_restartIndexValue; |
323 | } |
324 | |
325 | /*! |
326 | \property QGeometryRenderer::verticesPerPatch |
327 | |
328 | Holds vertices per patch. |
329 | */ |
330 | int QGeometryRenderer::verticesPerPatch() const |
331 | { |
332 | Q_D(const QGeometryRenderer); |
333 | return d->m_verticesPerPatch; |
334 | } |
335 | |
336 | /*! |
337 | \property QGeometryRenderer::primitiveRestartEnabled |
338 | |
339 | Holds the primitive restart flag. |
340 | */ |
341 | bool QGeometryRenderer::primitiveRestartEnabled() const |
342 | { |
343 | Q_D(const QGeometryRenderer); |
344 | return d->m_primitiveRestart; |
345 | } |
346 | |
347 | /*! |
348 | \property QGeometryRenderer::geometry |
349 | |
350 | Holds the geometry. |
351 | */ |
352 | QGeometry *QGeometryRenderer::geometry() const |
353 | { |
354 | Q_D(const QGeometryRenderer); |
355 | return d->m_geometry; |
356 | } |
357 | |
358 | /*! |
359 | \property QGeometryRenderer::primitiveType |
360 | |
361 | Holds the primitive type. |
362 | */ |
363 | QGeometryRenderer::PrimitiveType QGeometryRenderer::primitiveType() const |
364 | { |
365 | Q_D(const QGeometryRenderer); |
366 | return d->m_primitiveType; |
367 | } |
368 | |
369 | /*! |
370 | Returns the geometry functor. |
371 | */ |
372 | QGeometryFactoryPtr QGeometryRenderer::geometryFactory() const |
373 | { |
374 | Q_D(const QGeometryRenderer); |
375 | return d->m_geometryFactory; |
376 | } |
377 | |
378 | void QGeometryRenderer::setInstanceCount(int instanceCount) |
379 | { |
380 | Q_D(QGeometryRenderer); |
381 | if (d->m_instanceCount == instanceCount) |
382 | return; |
383 | |
384 | d->m_instanceCount = instanceCount; |
385 | emit instanceCountChanged(instanceCount); |
386 | } |
387 | |
388 | void QGeometryRenderer::setVertexCount(int vertexCount) |
389 | { |
390 | Q_D(QGeometryRenderer); |
391 | if (d->m_vertexCount == vertexCount) |
392 | return; |
393 | |
394 | d->m_vertexCount = vertexCount; |
395 | emit vertexCountChanged(vertexCount); |
396 | } |
397 | |
398 | void QGeometryRenderer::setIndexOffset(int indexOffset) |
399 | { |
400 | Q_D(QGeometryRenderer); |
401 | if (d->m_indexOffset == indexOffset) |
402 | return; |
403 | |
404 | d->m_indexOffset = indexOffset; |
405 | emit indexOffsetChanged(indexOffset); |
406 | } |
407 | |
408 | void QGeometryRenderer::setFirstInstance(int firstInstance) |
409 | { |
410 | Q_D(QGeometryRenderer); |
411 | if (d->m_firstInstance == firstInstance) |
412 | return; |
413 | |
414 | d->m_firstInstance = firstInstance; |
415 | emit firstInstanceChanged(firstInstance); |
416 | } |
417 | |
418 | void QGeometryRenderer::setFirstVertex(int firstVertex) |
419 | { |
420 | Q_D(QGeometryRenderer); |
421 | if (d->m_firstVertex == firstVertex) |
422 | return; |
423 | |
424 | d->m_firstVertex = firstVertex; |
425 | emit firstVertexChanged(firstVertex); |
426 | } |
427 | |
428 | void QGeometryRenderer::setIndexBufferByteOffset(int offset) |
429 | { |
430 | Q_D(QGeometryRenderer); |
431 | if (d->m_indexBufferByteOffset == offset) |
432 | return; |
433 | |
434 | d->m_indexBufferByteOffset = offset; |
435 | emit indexBufferByteOffsetChanged(offset); |
436 | } |
437 | |
438 | void QGeometryRenderer::setRestartIndexValue(int index) |
439 | { |
440 | Q_D(QGeometryRenderer); |
441 | if (index == d->m_restartIndexValue) |
442 | return; |
443 | |
444 | d->m_restartIndexValue = index; |
445 | emit restartIndexValueChanged(restartIndexValue: index); |
446 | } |
447 | |
448 | void QGeometryRenderer::setVerticesPerPatch(int verticesPerPatch) |
449 | { |
450 | Q_D(QGeometryRenderer); |
451 | if (d->m_verticesPerPatch != verticesPerPatch) { |
452 | d->m_verticesPerPatch = verticesPerPatch; |
453 | emit verticesPerPatchChanged(verticesPerPatch); |
454 | } |
455 | } |
456 | |
457 | void QGeometryRenderer::setPrimitiveRestartEnabled(bool enabled) |
458 | { |
459 | Q_D(QGeometryRenderer); |
460 | if (enabled == d->m_primitiveRestart) |
461 | return; |
462 | |
463 | d->m_primitiveRestart = enabled; |
464 | emit primitiveRestartEnabledChanged(primitiveRestartEnabled: enabled); |
465 | } |
466 | |
467 | void QGeometryRenderer::setGeometry(QGeometry *geometry) |
468 | { |
469 | Q_D(QGeometryRenderer); |
470 | if (d->m_geometry == geometry) |
471 | return; |
472 | |
473 | if (d->m_geometry) |
474 | d->unregisterDestructionHelper(node: d->m_geometry); |
475 | |
476 | if (geometry && !geometry->parent()) |
477 | geometry->setParent(this); |
478 | |
479 | d->m_geometry = geometry; |
480 | |
481 | // Ensures proper bookkeeping |
482 | if (d->m_geometry) |
483 | d->registerDestructionHelper(node: d->m_geometry, func: &QGeometryRenderer::setGeometry, d->m_geometry); |
484 | |
485 | emit geometryChanged(geometry); |
486 | } |
487 | |
488 | void QGeometryRenderer::setPrimitiveType(QGeometryRenderer::PrimitiveType primitiveType) |
489 | { |
490 | Q_D(QGeometryRenderer); |
491 | if (d->m_primitiveType == primitiveType) |
492 | return; |
493 | |
494 | d->m_primitiveType = primitiveType; |
495 | emit primitiveTypeChanged(primitiveType); |
496 | } |
497 | |
498 | /*! |
499 | Sets the geometry \a factory. |
500 | */ |
501 | void QGeometryRenderer::setGeometryFactory(const QGeometryFactoryPtr &factory) |
502 | { |
503 | Q_D(QGeometryRenderer); |
504 | if (factory && d->m_geometryFactory && *factory == *d->m_geometryFactory) |
505 | return; |
506 | d->m_geometryFactory = factory; |
507 | d->update(); |
508 | } |
509 | |
510 | Qt3DCore::QNodeCreatedChangeBasePtr QGeometryRenderer::createNodeCreationChange() const |
511 | { |
512 | auto creationChange = Qt3DCore::QNodeCreatedChangePtr<QGeometryRendererData>::create(arguments: this); |
513 | auto &data = creationChange->data; |
514 | Q_D(const QGeometryRenderer); |
515 | data.instanceCount = d->m_instanceCount; |
516 | data.vertexCount = d->m_vertexCount; |
517 | data.indexOffset = d->m_indexOffset; |
518 | data.firstInstance = d->m_firstInstance; |
519 | data.firstVertex = d->m_firstVertex; |
520 | data.indexBufferByteOffset = d->m_indexBufferByteOffset; |
521 | data.restartIndexValue = d->m_restartIndexValue; |
522 | data.verticesPerPatch = d->m_verticesPerPatch; |
523 | data.primitiveRestart = d->m_primitiveRestart; |
524 | data.geometryId = qIdForNode(node: d->m_geometry); |
525 | data.primitiveType = d->m_primitiveType; |
526 | data.geometryFactory = d->m_geometryFactory; |
527 | return creationChange; |
528 | } |
529 | |
530 | } // namespace Qt3DRender |
531 | |
532 | QT_END_NAMESPACE |
533 | |