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 
QGeometryRendererPrivate()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 
~QGeometryRendererPrivate()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  */
QGeometryRenderer(QNode * parent)223 QGeometryRenderer::QGeometryRenderer(QNode *parent)
224     : QComponent(*new QGeometryRendererPrivate(), parent)
225 {
226 }
227 
228 /*!
229     \internal
230  */
~QGeometryRenderer()231 QGeometryRenderer::~QGeometryRenderer()
232 {
233 }
234 
235 /*!
236     \internal
237  */
QGeometryRenderer(QGeometryRendererPrivate & dd,QNode * parent)238 QGeometryRenderer::QGeometryRenderer(QGeometryRendererPrivate &dd, QNode *parent)
239     : QComponent(dd, parent)
240 {
241 }
242 
243 // TODO Unused remove in Qt6
sceneChangeEvent(const QSceneChangePtr &)244 void QGeometryRenderer::sceneChangeEvent(const QSceneChangePtr &)
245 {
246 }
247 
248 /*!
249     \property QGeometryRenderer::instanceCount
250 
251     Holds the instance count.
252  */
instanceCount() const253 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  */
vertexCount() const264 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  */
indexOffset() const275 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  */
firstInstance() const286 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  */
firstVertex() const297 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  */
indexBufferByteOffset() const308 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  */
restartIndexValue() const319 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  */
verticesPerPatch() const330 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  */
primitiveRestartEnabled() const341 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  */
geometry() const352 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  */
primitiveType() const363 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  */
geometryFactory() const372 QGeometryFactoryPtr QGeometryRenderer::geometryFactory() const
373 {
374     Q_D(const QGeometryRenderer);
375     return d->m_geometryFactory;
376 }
377 
setInstanceCount(int instanceCount)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 
setVertexCount(int vertexCount)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 
setIndexOffset(int indexOffset)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 
setFirstInstance(int firstInstance)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 
setFirstVertex(int firstVertex)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 
setIndexBufferByteOffset(int offset)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 
setRestartIndexValue(int index)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(index);
446 }
447 
setVerticesPerPatch(int verticesPerPatch)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 
setPrimitiveRestartEnabled(bool enabled)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(enabled);
465 }
466 
setGeometry(QGeometry * geometry)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(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(d->m_geometry, &QGeometryRenderer::setGeometry, d->m_geometry);
484 
485     emit geometryChanged(geometry);
486 }
487 
setPrimitiveType(QGeometryRenderer::PrimitiveType primitiveType)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  */
setGeometryFactory(const QGeometryFactoryPtr & factory)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 
createNodeCreationChange() const510 Qt3DCore::QNodeCreatedChangeBasePtr QGeometryRenderer::createNodeCreationChange() const
511 {
512     auto creationChange = Qt3DCore::QNodeCreatedChangePtr<QGeometryRendererData>::create(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(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