1// Copyright (C) 2015 Paul Lemire paul.lemire350@gmail.com
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#ifndef QT3DRENDER_RENDER_VISITORUTILS_P_H
5#define QT3DRENDER_RENDER_VISITORUTILS_P_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It exists for the convenience
12// of other Qt classes. This header file may change from version to
13// version without notice, or even be removed.
14//
15// We mean it.
16//
17
18#include <QtGlobal>
19#include <private/qglobal_p.h>
20
21QT_BEGIN_NAMESPACE
22
23namespace Qt3DRender {
24
25namespace Render {
26
27namespace Visitor {
28
29template <Qt3DCore::QAttribute::VertexBaseType> struct EnumToType;
30template <> struct EnumToType<Qt3DCore::QAttribute::Byte> { typedef const char type; };
31template <> struct EnumToType<Qt3DCore::QAttribute::UnsignedByte> { typedef const uchar type; };
32template <> struct EnumToType<Qt3DCore::QAttribute::Short> { typedef const short type; };
33template <> struct EnumToType<Qt3DCore::QAttribute::UnsignedShort> { typedef const ushort type; };
34template <> struct EnumToType<Qt3DCore::QAttribute::Int> { typedef const int type; };
35template <> struct EnumToType<Qt3DCore::QAttribute::UnsignedInt> { typedef const uint type; };
36template <> struct EnumToType<Qt3DCore::QAttribute::Float> { typedef const float type; };
37template <> struct EnumToType<Qt3DCore::QAttribute::Double> { typedef const double type; };
38
39template<Qt3DCore::QAttribute::VertexBaseType v>
40inline typename EnumToType<v>::type *castToType(const QByteArray &u, uint byteOffset)
41{
42 return reinterpret_cast< typename EnumToType<v>::type *>(u.constData() + byteOffset);
43}
44
45template<typename Func>
46void processBuffer(const BufferInfo &info, Func &f)
47{
48 switch (info.type) {
49 case Qt3DCore::QAttribute::Byte: f(info, castToType<Qt3DCore::QAttribute::Byte>(u: info.data, byteOffset: info.byteOffset));
50 return;
51 case Qt3DCore::QAttribute::UnsignedByte: f(info, castToType<Qt3DCore::QAttribute::UnsignedByte>(u: info.data, byteOffset: info.byteOffset));
52 return;
53 case Qt3DCore::QAttribute::Short: f(info, castToType<Qt3DCore::QAttribute::Short>(u: info.data, byteOffset: info.byteOffset));
54 return;
55 case Qt3DCore::QAttribute::UnsignedShort: f(info, castToType<Qt3DCore::QAttribute::UnsignedShort>(u: info.data, byteOffset: info.byteOffset));
56 return;
57 case Qt3DCore::QAttribute::Int: f(info, castToType<Qt3DCore::QAttribute::Int>(u: info.data, byteOffset: info.byteOffset));
58 return;
59 case Qt3DCore::QAttribute::UnsignedInt: f(info, castToType<Qt3DCore::QAttribute::UnsignedInt>(u: info.data, byteOffset: info.byteOffset));
60 return;
61 case Qt3DCore::QAttribute::Float: f(info, castToType<Qt3DCore::QAttribute::Float>(u: info.data, byteOffset: info.byteOffset));
62 return;
63 case Qt3DCore::QAttribute::Double: f(info, castToType<Qt3DCore::QAttribute::Double>(u: info.data, byteOffset: info.byteOffset));
64 return;
65 default:
66 return;
67 }
68}
69
70template<typename GeometryProvider, typename VertexExecutor, typename IndexExecutor, typename Visitor>
71void visitPrimitives(NodeManagers *manager, const GeometryProvider *renderer, Visitor* visitor)
72{
73 Geometry *geom = manager->lookupResource<Geometry, GeometryManager>(renderer->geometryId());
74 Attribute *positionAttribute = nullptr;
75 Attribute *indexAttribute = nullptr;
76 Buffer *positionBuffer = nullptr;
77 Buffer *indexBuffer = nullptr;
78
79 auto updateStride = [](BufferInfo &info, int stride) {
80 if (stride) {
81 info.byteStride = stride;
82 return;
83 }
84 switch (info.type) {
85 case Qt3DCore::QAttribute::Byte: info.byteStride = sizeof(qint8) * info.dataSize; return;
86 case Qt3DCore::QAttribute::UnsignedByte: info.byteStride = sizeof(quint8) * info.dataSize; return;
87 case Qt3DCore::QAttribute::Short: info.byteStride = sizeof(qint16) * info.dataSize; return;
88 case Qt3DCore::QAttribute::UnsignedShort: info.byteStride = sizeof(quint16) * info.dataSize; return;
89 case Qt3DCore::QAttribute::Int: info.byteStride = sizeof(qint32) * info.dataSize; return;
90 case Qt3DCore::QAttribute::UnsignedInt: info.byteStride = sizeof(quint32) * info.dataSize; return;
91 case Qt3DCore::QAttribute::Float: info.byteStride = sizeof(float) * info.dataSize; return;
92 case Qt3DCore::QAttribute::Double: info.byteStride = sizeof(double) * info.dataSize; return;
93 default: return;
94 }
95 };
96
97 if (geom) {
98 Qt3DRender::Render::Attribute *attribute = nullptr;
99 const auto attrIds = geom->attributes();
100 for (const Qt3DCore::QNodeId &attrId : attrIds) {
101 attribute = manager->lookupResource<Attribute, AttributeManager>(id: attrId);
102 if (attribute){
103 if (!positionAttribute && attribute->name() == Qt3DCore::QAttribute::defaultPositionAttributeName())
104 positionAttribute = attribute;
105 else if (attribute->attributeType() == Qt3DCore::QAttribute::IndexAttribute)
106 indexAttribute = attribute;
107 }
108 }
109
110 if (positionAttribute)
111 positionBuffer = manager->lookupResource<Buffer, BufferManager>(id: positionAttribute->bufferId());
112 if (indexAttribute)
113 indexBuffer = manager->lookupResource<Buffer, BufferManager>(id: indexAttribute->bufferId());
114
115 if (positionBuffer) {
116
117 BufferInfo vertexBufferInfo;
118 vertexBufferInfo.data = positionBuffer->data();
119 vertexBufferInfo.type = positionAttribute->vertexBaseType();
120 vertexBufferInfo.byteOffset = positionAttribute->byteOffset();
121 vertexBufferInfo.dataSize = positionAttribute->vertexSize();
122 vertexBufferInfo.count = positionAttribute->count();
123 updateStride(vertexBufferInfo, positionAttribute->byteStride());
124
125 if (indexBuffer) { // Indexed
126
127 BufferInfo indexBufferInfo;
128 indexBufferInfo.data = indexBuffer->data();
129 indexBufferInfo.type = indexAttribute->vertexBaseType();
130 indexBufferInfo.byteOffset = indexAttribute->byteOffset();
131 indexBufferInfo.count = indexAttribute->count();
132 indexBufferInfo.restartEnabled = renderer->primitiveRestartEnabled();
133 indexBufferInfo.restartIndexValue = renderer->restartIndexValue();
134 updateStride(indexBufferInfo, indexAttribute->byteStride());
135
136 IndexExecutor executor;
137 executor.m_vertexBufferInfo = vertexBufferInfo;
138 executor.m_primitiveType = static_cast<Qt3DRender::QGeometryRenderer::PrimitiveType>(renderer->primitiveType());
139 executor.m_visitor = visitor;
140
141 return processBuffer(indexBufferInfo, executor);
142
143 } else { // Non Indexed
144
145 // Check into which type the buffer needs to be casted
146 VertexExecutor executor;
147 executor.m_primitiveType = static_cast<Qt3DRender::QGeometryRenderer::PrimitiveType>(renderer->primitiveType());
148 executor.m_visitor = visitor;
149
150 return processBuffer(vertexBufferInfo, executor);
151 }
152 }
153 }
154}
155
156} // namespace Visitor
157
158} // namespace Render
159
160} // namespace Qt3DRender
161
162QT_END_NAMESPACE
163
164#endif // QT3DRENDER_RENDER_VISITORUTILS_P_H
165

source code of qt3d/src/render/backend/visitorutils_p.h