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