1/****************************************************************************
2**
3** Copyright (C) 2015 Paul Lemire paul.lemire350@gmail.com
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#ifndef QT3DRENDER_RENDER_VISITORUTILS_P_H
41#define QT3DRENDER_RENDER_VISITORUTILS_P_H
42
43//
44// W A R N I N G
45// -------------
46//
47// This file is not part of the Qt API. It exists for the convenience
48// of other Qt classes. This header file may change from version to
49// version without notice, or even be removed.
50//
51// We mean it.
52//
53
54#include <QtGlobal>
55
56QT_BEGIN_NAMESPACE
57
58namespace Qt3DRender {
59
60namespace Render {
61
62namespace Visitor {
63
64template <QAttribute::VertexBaseType> struct EnumToType;
65template <> struct EnumToType<QAttribute::Byte> { typedef const char type; };
66template <> struct EnumToType<QAttribute::UnsignedByte> { typedef const uchar type; };
67template <> struct EnumToType<QAttribute::Short> { typedef const short type; };
68template <> struct EnumToType<QAttribute::UnsignedShort> { typedef const ushort type; };
69template <> struct EnumToType<QAttribute::Int> { typedef const int type; };
70template <> struct EnumToType<QAttribute::UnsignedInt> { typedef const uint type; };
71template <> struct EnumToType<QAttribute::Float> { typedef const float type; };
72template <> struct EnumToType<QAttribute::Double> { typedef const double type; };
73
74template<QAttribute::VertexBaseType v>
75inline typename EnumToType<v>::type *castToType(const QByteArray &u, uint byteOffset)
76{
77 return reinterpret_cast< typename EnumToType<v>::type *>(u.constData() + byteOffset);
78}
79
80template<typename Func>
81void processBuffer(const BufferInfo &info, Func &f)
82{
83 switch (info.type) {
84 case QAttribute::Byte: f(info, castToType<QAttribute::Byte>(u: info.data, byteOffset: info.byteOffset));
85 return;
86 case QAttribute::UnsignedByte: f(info, castToType<QAttribute::UnsignedByte>(u: info.data, byteOffset: info.byteOffset));
87 return;
88 case QAttribute::Short: f(info, castToType<QAttribute::Short>(u: info.data, byteOffset: info.byteOffset));
89 return;
90 case QAttribute::UnsignedShort: f(info, castToType<QAttribute::UnsignedShort>(u: info.data, byteOffset: info.byteOffset));
91 return;
92 case QAttribute::Int: f(info, castToType<QAttribute::Int>(u: info.data, byteOffset: info.byteOffset));
93 return;
94 case QAttribute::UnsignedInt: f(info, castToType<QAttribute::UnsignedInt>(u: info.data, byteOffset: info.byteOffset));
95 return;
96 case QAttribute::Float: f(info, castToType<QAttribute::Float>(u: info.data, byteOffset: info.byteOffset));
97 return;
98 case QAttribute::Double: f(info, castToType<QAttribute::Double>(u: info.data, byteOffset: info.byteOffset));
99 return;
100 default:
101 return;
102 }
103}
104
105template<typename VertexExecutor, typename IndexExecutor, typename Visitor>
106void visitPrimitives(NodeManagers *manager, const GeometryRenderer *renderer, Visitor* visitor)
107{
108 Geometry *geom = manager->lookupResource<Geometry, GeometryManager>(id: renderer->geometryId());
109 Attribute *positionAttribute = nullptr;
110 Attribute *indexAttribute = nullptr;
111 Buffer *positionBuffer = nullptr;
112 Buffer *indexBuffer = nullptr;
113
114 auto updateStride = [](BufferInfo &info, int stride) {
115 if (stride) {
116 info.byteStride = stride;
117 return;
118 }
119 switch (info.type) {
120 case QAttribute::Byte: info.byteStride = sizeof(qint8) * info.dataSize; return;
121 case QAttribute::UnsignedByte: info.byteStride = sizeof(quint8) * info.dataSize; return;
122 case QAttribute::Short: info.byteStride = sizeof(qint16) * info.dataSize; return;
123 case QAttribute::UnsignedShort: info.byteStride = sizeof(quint16) * info.dataSize; return;
124 case QAttribute::Int: info.byteStride = sizeof(qint32) * info.dataSize; return;
125 case QAttribute::UnsignedInt: info.byteStride = sizeof(quint32) * info.dataSize; return;
126 case QAttribute::Float: info.byteStride = sizeof(float) * info.dataSize; return;
127 case QAttribute::Double: info.byteStride = sizeof(double) * info.dataSize; return;
128 default: return;
129 }
130 };
131
132 if (geom) {
133 Qt3DRender::Render::Attribute *attribute = nullptr;
134 const auto attrIds = geom->attributes();
135 for (const Qt3DCore::QNodeId attrId : attrIds) {
136 attribute = manager->lookupResource<Attribute, AttributeManager>(id: attrId);
137 if (attribute){
138 if (!positionAttribute && attribute->name() == QAttribute::defaultPositionAttributeName())
139 positionAttribute = attribute;
140 else if (attribute->attributeType() == QAttribute::IndexAttribute)
141 indexAttribute = attribute;
142 }
143 }
144
145 if (positionAttribute)
146 positionBuffer = manager->lookupResource<Buffer, BufferManager>(id: positionAttribute->bufferId());
147 if (indexAttribute)
148 indexBuffer = manager->lookupResource<Buffer, BufferManager>(id: indexAttribute->bufferId());
149
150 if (positionBuffer) {
151
152 BufferInfo vertexBufferInfo;
153 vertexBufferInfo.data = positionBuffer->data();
154 vertexBufferInfo.type = positionAttribute->vertexBaseType();
155 vertexBufferInfo.byteOffset = positionAttribute->byteOffset();
156 vertexBufferInfo.dataSize = positionAttribute->vertexSize();
157 vertexBufferInfo.count = positionAttribute->count();
158 updateStride(vertexBufferInfo, positionAttribute->byteStride());
159
160 if (indexBuffer) { // Indexed
161
162 BufferInfo indexBufferInfo;
163 indexBufferInfo.data = indexBuffer->data();
164 indexBufferInfo.type = indexAttribute->vertexBaseType();
165 indexBufferInfo.byteOffset = indexAttribute->byteOffset();
166 indexBufferInfo.count = indexAttribute->count();
167 indexBufferInfo.restartEnabled = renderer->primitiveRestartEnabled();
168 indexBufferInfo.restartIndexValue = renderer->restartIndexValue();
169 updateStride(indexBufferInfo, indexAttribute->byteStride());
170
171 IndexExecutor executor;
172 executor.m_vertexBufferInfo = vertexBufferInfo;
173 executor.m_primitiveType = renderer->primitiveType();
174 executor.m_visitor = visitor;
175
176 return processBuffer(indexBufferInfo, executor);
177
178 } else { // Non Indexed
179
180 // Check into which type the buffer needs to be casted
181 VertexExecutor executor;
182 executor.m_primitiveType = renderer->primitiveType();
183 executor.m_visitor = visitor;
184
185 return processBuffer(vertexBufferInfo, executor);
186 }
187 }
188 }
189}
190
191} // namespace Visitor
192
193} // namespace Render
194
195} // namespace Qt3DRender
196
197QT_END_NAMESPACE
198
199#endif // QT3DRENDER_RENDER_VISITORUTILS_P_H
200

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