1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the Qt scene graph research project.
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 QSGGEOMETRY_H
41#define QSGGEOMETRY_H
42
43#include <QtQuick/qtquickglobal.h>
44#include <QtGui/qopengl.h>
45#include <QtCore/QRectF>
46
47QT_BEGIN_NAMESPACE
48
49class QSGGeometryData;
50
51class Q_QUICK_EXPORT QSGGeometry
52{
53public:
54 enum AttributeType {
55 UnknownAttribute,
56 PositionAttribute,
57 ColorAttribute,
58 TexCoordAttribute,
59 TexCoord1Attribute,
60 TexCoord2Attribute
61 };
62
63 enum DataPattern {
64 AlwaysUploadPattern = 0,
65 StreamPattern = 1,
66 DynamicPattern = 2,
67 StaticPattern = 3
68 };
69
70 // Equivalents to GL_* drawing modes.
71 // Keep in sync with GL headers.
72 enum DrawingMode {
73 DrawPoints = 0x0000,
74 DrawLines = 0x0001,
75 DrawLineLoop = 0x0002,
76 DrawLineStrip = 0x0003,
77 DrawTriangles = 0x0004,
78 DrawTriangleStrip = 0x0005,
79 DrawTriangleFan = 0x0006
80 };
81
82 // Equivalents to GL_BYTE and similar type constants.
83 // Keep in sync with GL headers.
84 enum Type {
85 ByteType = 0x1400,
86 UnsignedByteType = 0x1401,
87 ShortType = 0x1402,
88 UnsignedShortType = 0x1403,
89 IntType = 0x1404,
90 UnsignedIntType = 0x1405,
91 FloatType = 0x1406,
92 Bytes2Type = 0x1407,
93 Bytes3Type = 0x1408,
94 Bytes4Type = 0x1409,
95 DoubleType = 0x140A
96 };
97
98 struct Q_QUICK_EXPORT Attribute
99 {
100 int position;
101 int tupleSize;
102 int type;
103
104 uint isVertexCoordinate : 1;
105
106 AttributeType attributeType : 4;
107
108 uint reserved : 27;
109
110 static Attribute create(int pos, int tupleSize, int primitiveType, bool isPosition = false);
111 static Attribute createWithAttributeType(int pos, int tupleSize, int primitiveType, AttributeType attributeType);
112 };
113
114 struct AttributeSet {
115 int count;
116 int stride;
117 const Attribute *attributes;
118 };
119
120 struct Point2D {
121 float x, y;
122 void set(float nx, float ny) {
123 x = nx; y = ny;
124 }
125 };
126 struct TexturedPoint2D {
127 float x, y;
128 float tx, ty;
129 void set(float nx, float ny, float ntx, float nty) {
130 x = nx; y = ny; tx = ntx; ty = nty;
131 }
132 };
133 struct ColoredPoint2D {
134 float x, y;
135 unsigned char r, g, b, a;
136 void set(float nx, float ny, uchar nr, uchar ng, uchar nb, uchar na) {
137 x = nx; y = ny;
138 r = nr; g = ng, b = nb; a = na;
139 }
140 };
141
142 static const AttributeSet &defaultAttributes_Point2D();
143 static const AttributeSet &defaultAttributes_TexturedPoint2D();
144 static const AttributeSet &defaultAttributes_ColoredPoint2D();
145
146 QSGGeometry(const QSGGeometry::AttributeSet &attribs,
147 int vertexCount,
148 int indexCount = 0,
149 int indexType = UnsignedShortType);
150 virtual ~QSGGeometry();
151
152 // must use unsigned int to be compatible with the old GLenum to keep BC
153 void setDrawingMode(unsigned int mode);
154 inline unsigned int drawingMode() const { return m_drawing_mode; }
155
156 void allocate(int vertexCount, int indexCount = 0);
157
158 int vertexCount() const { return m_vertex_count; }
159
160 void *vertexData() { return m_data; }
161 inline Point2D *vertexDataAsPoint2D();
162 inline TexturedPoint2D *vertexDataAsTexturedPoint2D();
163 inline ColoredPoint2D *vertexDataAsColoredPoint2D();
164
165 inline const void *vertexData() const { return m_data; }
166 inline const Point2D *vertexDataAsPoint2D() const;
167 inline const TexturedPoint2D *vertexDataAsTexturedPoint2D() const;
168 inline const ColoredPoint2D *vertexDataAsColoredPoint2D() const;
169
170 inline int indexType() const { return m_index_type; }
171
172 int indexCount() const { return m_index_count; }
173
174 void *indexData();
175 inline uint *indexDataAsUInt();
176 inline quint16 *indexDataAsUShort();
177
178 inline int sizeOfIndex() const;
179
180 const void *indexData() const;
181 inline const uint *indexDataAsUInt() const;
182 inline const quint16 *indexDataAsUShort() const;
183
184 inline int attributeCount() const { return m_attributes.count; }
185 inline const Attribute *attributes() const { return m_attributes.attributes; }
186 inline int sizeOfVertex() const { return m_attributes.stride; }
187
188 static void updateRectGeometry(QSGGeometry *g, const QRectF &rect);
189 static void updateTexturedRectGeometry(QSGGeometry *g, const QRectF &rect, const QRectF &sourceRect);
190 static void updateColoredRectGeometry(QSGGeometry *g, const QRectF &rect);
191
192 void setIndexDataPattern(DataPattern p);
193 DataPattern indexDataPattern() const { return DataPattern(m_index_usage_pattern); }
194
195 void setVertexDataPattern(DataPattern p);
196 DataPattern vertexDataPattern() const { return DataPattern(m_vertex_usage_pattern); }
197
198 void markIndexDataDirty();
199 void markVertexDataDirty();
200
201 float lineWidth() const;
202 void setLineWidth(float w);
203
204private:
205 friend class QSGGeometryData;
206
207 int m_drawing_mode;
208 int m_vertex_count;
209 int m_index_count;
210 int m_index_type;
211 const AttributeSet &m_attributes;
212 void *m_data;
213 int m_index_data_offset;
214
215 QSGGeometryData *m_server_data;
216
217 uint m_owns_data : 1;
218 uint m_index_usage_pattern : 2;
219 uint m_vertex_usage_pattern : 2;
220 uint m_dirty_index_data : 1;
221 uint m_dirty_vertex_data : 1;
222 uint m_reserved_bits : 25;
223
224 float m_prealloc[16];
225
226 float m_line_width;
227};
228
229inline uint *QSGGeometry::indexDataAsUInt()
230{
231 Q_ASSERT(m_index_type == UnsignedIntType);
232 return static_cast<uint *>(indexData());
233}
234
235inline quint16 *QSGGeometry::indexDataAsUShort()
236{
237 Q_ASSERT(m_index_type == UnsignedShortType);
238 return static_cast<quint16 *>(indexData());
239}
240
241inline const uint *QSGGeometry::indexDataAsUInt() const
242{
243 Q_ASSERT(m_index_type == UnsignedIntType);
244 return static_cast<const uint *>(indexData());
245}
246
247inline const quint16 *QSGGeometry::indexDataAsUShort() const
248{
249 Q_ASSERT(m_index_type == UnsignedShortType);
250 return static_cast<const quint16 *>(indexData());
251}
252
253inline QSGGeometry::Point2D *QSGGeometry::vertexDataAsPoint2D()
254{
255 Q_ASSERT(m_attributes.count == 1);
256 Q_ASSERT(m_attributes.stride == 2 * sizeof(float));
257 Q_ASSERT(m_attributes.attributes[0].tupleSize == 2);
258 Q_ASSERT(m_attributes.attributes[0].type == FloatType);
259 Q_ASSERT(m_attributes.attributes[0].position == 0);
260 return static_cast<Point2D *>(m_data);
261}
262
263inline QSGGeometry::TexturedPoint2D *QSGGeometry::vertexDataAsTexturedPoint2D()
264{
265 Q_ASSERT(m_attributes.count == 2);
266 Q_ASSERT(m_attributes.stride == 4 * sizeof(float));
267 Q_ASSERT(m_attributes.attributes[0].position == 0);
268 Q_ASSERT(m_attributes.attributes[0].tupleSize == 2);
269 Q_ASSERT(m_attributes.attributes[0].type == FloatType);
270 Q_ASSERT(m_attributes.attributes[1].position == 1);
271 Q_ASSERT(m_attributes.attributes[1].tupleSize == 2);
272 Q_ASSERT(m_attributes.attributes[1].type == FloatType);
273 return static_cast<TexturedPoint2D *>(m_data);
274}
275
276inline QSGGeometry::ColoredPoint2D *QSGGeometry::vertexDataAsColoredPoint2D()
277{
278 Q_ASSERT(m_attributes.count == 2);
279 Q_ASSERT(m_attributes.stride == 2 * sizeof(float) + 4 * sizeof(char));
280 Q_ASSERT(m_attributes.attributes[0].position == 0);
281 Q_ASSERT(m_attributes.attributes[0].tupleSize == 2);
282 Q_ASSERT(m_attributes.attributes[0].type == FloatType);
283 Q_ASSERT(m_attributes.attributes[1].position == 1);
284 Q_ASSERT(m_attributes.attributes[1].tupleSize == 4);
285 Q_ASSERT(m_attributes.attributes[1].type == UnsignedByteType);
286 return static_cast<ColoredPoint2D *>(m_data);
287}
288
289inline const QSGGeometry::Point2D *QSGGeometry::vertexDataAsPoint2D() const
290{
291 Q_ASSERT(m_attributes.count == 1);
292 Q_ASSERT(m_attributes.stride == 2 * sizeof(float));
293 Q_ASSERT(m_attributes.attributes[0].tupleSize == 2);
294 Q_ASSERT(m_attributes.attributes[0].type == FloatType);
295 Q_ASSERT(m_attributes.attributes[0].position == 0);
296 return static_cast<const Point2D *>(m_data);
297}
298
299inline const QSGGeometry::TexturedPoint2D *QSGGeometry::vertexDataAsTexturedPoint2D() const
300{
301 Q_ASSERT(m_attributes.count == 2);
302 Q_ASSERT(m_attributes.stride == 4 * sizeof(float));
303 Q_ASSERT(m_attributes.attributes[0].position == 0);
304 Q_ASSERT(m_attributes.attributes[0].tupleSize == 2);
305 Q_ASSERT(m_attributes.attributes[0].type == FloatType);
306 Q_ASSERT(m_attributes.attributes[1].position == 1);
307 Q_ASSERT(m_attributes.attributes[1].tupleSize == 2);
308 Q_ASSERT(m_attributes.attributes[1].type == FloatType);
309 return static_cast<const TexturedPoint2D *>(m_data);
310}
311
312inline const QSGGeometry::ColoredPoint2D *QSGGeometry::vertexDataAsColoredPoint2D() const
313{
314 Q_ASSERT(m_attributes.count == 2);
315 Q_ASSERT(m_attributes.stride == 2 * sizeof(float) + 4 * sizeof(char));
316 Q_ASSERT(m_attributes.attributes[0].position == 0);
317 Q_ASSERT(m_attributes.attributes[0].tupleSize == 2);
318 Q_ASSERT(m_attributes.attributes[0].type == FloatType);
319 Q_ASSERT(m_attributes.attributes[1].position == 1);
320 Q_ASSERT(m_attributes.attributes[1].tupleSize == 4);
321 Q_ASSERT(m_attributes.attributes[1].type == UnsignedByteType);
322 return static_cast<const ColoredPoint2D *>(m_data);
323}
324
325int QSGGeometry::sizeOfIndex() const
326{
327 if (m_index_type == UnsignedShortType) return 2;
328 else if (m_index_type == UnsignedByteType) return 1;
329 else if (m_index_type == UnsignedIntType) return 4;
330 return 0;
331}
332
333QT_END_NAMESPACE
334
335#endif // QSGGEOMETRY_H
336