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 | #include "qsggeometry.h" |
41 | #include "qsggeometry_p.h" |
42 | #if QT_CONFIG(opengl) |
43 | # include <qopenglcontext.h> |
44 | # include <qopenglfunctions.h> |
45 | # include <private/qopenglextensions_p.h> |
46 | #endif |
47 | |
48 | #ifdef Q_OS_QNX |
49 | #include <malloc.h> |
50 | #endif |
51 | |
52 | QT_BEGIN_NAMESPACE |
53 | |
54 | |
55 | QSGGeometry::Attribute QSGGeometry::Attribute::create(int attributeIndex, int tupleSize, int primitiveType, bool isPrimitive) |
56 | { |
57 | Attribute a = { .position: attributeIndex, .tupleSize: tupleSize, .type: primitiveType, .isVertexCoordinate: isPrimitive, .attributeType: UnknownAttribute, .reserved: 0 }; |
58 | return a; |
59 | } |
60 | |
61 | QSGGeometry::Attribute QSGGeometry::Attribute::createWithAttributeType(int pos, int tupleSize, int primitiveType, AttributeType attributeType) |
62 | { |
63 | Attribute a; |
64 | a.position = pos; |
65 | a.tupleSize = tupleSize; |
66 | a.type = primitiveType; |
67 | a.isVertexCoordinate = attributeType == PositionAttribute; |
68 | a.attributeType = attributeType; |
69 | a.reserved = 0; |
70 | return a; |
71 | } |
72 | |
73 | /*! |
74 | Convenience function which returns attributes to be used for 2D solid |
75 | color drawing. |
76 | */ |
77 | |
78 | const QSGGeometry::AttributeSet &QSGGeometry::defaultAttributes_Point2D() |
79 | { |
80 | static Attribute data[] = { |
81 | Attribute::createWithAttributeType(pos: 0, tupleSize: 2, primitiveType: FloatType, attributeType: PositionAttribute) |
82 | }; |
83 | static AttributeSet attrs = { .count: 1, .stride: sizeof(float) * 2, .attributes: data }; |
84 | return attrs; |
85 | } |
86 | |
87 | /*! |
88 | Convenience function which returns attributes to be used for textured 2D drawing. |
89 | */ |
90 | |
91 | const QSGGeometry::AttributeSet &QSGGeometry::defaultAttributes_TexturedPoint2D() |
92 | { |
93 | static Attribute data[] = { |
94 | Attribute::createWithAttributeType(pos: 0, tupleSize: 2, primitiveType: FloatType, attributeType: PositionAttribute), |
95 | Attribute::createWithAttributeType(pos: 1, tupleSize: 2, primitiveType: FloatType, attributeType: TexCoordAttribute) |
96 | }; |
97 | static AttributeSet attrs = { .count: 2, .stride: sizeof(float) * 4, .attributes: data }; |
98 | return attrs; |
99 | } |
100 | |
101 | /*! |
102 | Convenience function which returns attributes to be used for per vertex colored 2D drawing. |
103 | */ |
104 | |
105 | const QSGGeometry::AttributeSet &QSGGeometry::defaultAttributes_ColoredPoint2D() |
106 | { |
107 | static Attribute data[] = { |
108 | Attribute::createWithAttributeType(pos: 0, tupleSize: 2, primitiveType: FloatType, attributeType: PositionAttribute), |
109 | Attribute::createWithAttributeType(pos: 1, tupleSize: 4, primitiveType: UnsignedByteType, attributeType: ColorAttribute) |
110 | }; |
111 | static AttributeSet attrs = { .count: 2, .stride: 2 * sizeof(float) + 4 * sizeof(char), .attributes: data }; |
112 | return attrs; |
113 | } |
114 | |
115 | |
116 | /*! |
117 | \class QSGGeometry::Attribute |
118 | \brief The QSGGeometry::Attribute describes a single vertex attribute in a QSGGeometry. |
119 | \inmodule QtQuick |
120 | |
121 | The QSGGeometry::Attribute struct describes the attribute register position, |
122 | the size of the attribute tuple and the attribute type. |
123 | |
124 | It also contains a hint to the renderer if this attribute is the attribute |
125 | describing the position. The scene graph renderer may use this information |
126 | to perform optimizations. |
127 | |
128 | It contains a number of bits which are reserved for future use. |
129 | |
130 | \sa QSGGeometry |
131 | */ |
132 | |
133 | /*! |
134 | \fn QSGGeometry::Attribute QSGGeometry::Attribute::create(int pos, int tupleSize, int primitiveType, bool isPosition) |
135 | |
136 | Creates a new QSGGeometry::Attribute for attribute register \a pos with \a |
137 | tupleSize. The \a primitiveType can be any of the supported types from |
138 | QSGGeometry::Type, such as QSGGeometry::FloatType or |
139 | QSGGeometry::UnsignedByteType. |
140 | |
141 | If the attribute describes the position for the vertex, the \a isPosition |
142 | hint should be set to \c true. The scene graph renderer may use this |
143 | information to perform optimizations. |
144 | |
145 | \note Scene graph backends for APIs other than OpenGL may require an |
146 | accurate description of attributes' usage, and therefore it is recommended |
147 | to use createWithAttributeType() instead. |
148 | |
149 | Use the create function to construct the attribute, rather than an |
150 | initialization list, to ensure that all fields are initialized. |
151 | */ |
152 | |
153 | /*! |
154 | \fn QSGGeometry::Attribute QSGGeometry::Attribute::createWithAttributeType(int pos, int tupleSize, int primitiveType, AttributeType attributeType) |
155 | |
156 | Creates a new QSGGeometry::Attribute for attribute register \a pos with \a |
157 | tupleSize. The \a primitiveType can be any of the supported types from |
158 | QSGGeometry::Type, such as QSGGeometry::FloatType or |
159 | QSGGeometry::UnsignedByteType. |
160 | |
161 | \a attributeType describes the intended use of the attribute. |
162 | |
163 | Use the create function to construct the attribute, rather than an |
164 | initialization list, to ensure that all fields are initialized. |
165 | */ |
166 | |
167 | |
168 | /*! |
169 | \class QSGGeometry::AttributeSet |
170 | \brief The QSGGeometry::AttributeSet describes how the vertices in a QSGGeometry |
171 | are built up. |
172 | \inmodule QtQuick |
173 | |
174 | \sa QSGGeometry |
175 | */ |
176 | |
177 | |
178 | /*! |
179 | \class QSGGeometry::Point2D |
180 | \brief The QSGGeometry::Point2D struct is a convenience struct for accessing |
181 | 2D Points. |
182 | |
183 | \inmodule QtQuick |
184 | */ |
185 | |
186 | |
187 | /*! |
188 | \fn void QSGGeometry::Point2D::set(float x, float y) |
189 | |
190 | Sets the x and y values of this point to \a x and \a y. |
191 | */ |
192 | |
193 | |
194 | /*! |
195 | \class QSGGeometry::ColoredPoint2D |
196 | \brief The QSGGeometry::ColoredPoint2D struct is a convenience struct for accessing |
197 | 2D Points with a color. |
198 | |
199 | \inmodule QtQuick |
200 | */ |
201 | |
202 | |
203 | /*! |
204 | \fn void QSGGeometry::ColoredPoint2D::set(float x, float y, uchar red, uchar green, uchar blue, uchar alpha) |
205 | |
206 | Sets the position of the vertex to \a x and \a y and the color to \a red, \a |
207 | green, \a blue, and \a alpha. |
208 | */ |
209 | |
210 | |
211 | /*! |
212 | \class QSGGeometry::TexturedPoint2D |
213 | \brief The QSGGeometry::TexturedPoint2D struct is a convenience struct for accessing |
214 | 2D Points with texture coordinates. |
215 | |
216 | \inmodule QtQuick |
217 | */ |
218 | |
219 | |
220 | /*! |
221 | \fn void QSGGeometry::TexturedPoint2D::set(float x, float y, float tx, float ty) |
222 | |
223 | Sets the position of the vertex to \a x and \a y and the texture coordinate |
224 | to \a tx and \a ty. |
225 | */ |
226 | |
227 | |
228 | |
229 | /*! |
230 | \class QSGGeometry |
231 | |
232 | \brief The QSGGeometry class provides low-level |
233 | storage for graphics primitives in the \l{Qt Quick Scene Graph}. |
234 | |
235 | \inmodule QtQuick |
236 | |
237 | The QSGGeometry class stores the geometry of the primitives |
238 | rendered with the scene graph. It contains vertex data and |
239 | optionally index data. The mode used to draw the geometry is |
240 | specified with setDrawingMode(), which maps directly to the graphics API's |
241 | drawing mode, such as \c GL_TRIANGLE_STRIP, \c GL_TRIANGLES, or |
242 | \c GL_POINTS in case of OpenGL. |
243 | |
244 | Vertices can be as simple as points defined by x and y values or |
245 | can be more complex where each vertex contains a normal, texture |
246 | coordinates and a 3D position. The QSGGeometry::AttributeSet is |
247 | used to describe how the vertex data is built up. The attribute |
248 | set can only be specified on construction. The QSGGeometry class |
249 | provides a few convenience attributes and attribute sets by |
250 | default. The defaultAttributes_Point2D() function returns an |
251 | attribute set to be used in normal solid color rectangles, while |
252 | the defaultAttributes_TexturedPoint2D function returns attributes |
253 | to be used for textured 2D geometry. The vertex data is internally |
254 | stored as a \c {void *} and is accessible with the vertexData() |
255 | function. Convenience accessors for the common attribute sets are |
256 | available with vertexDataAsPoint2D() and |
257 | vertexDataAsTexturedPoint2D(). Vertex data is allocated by passing |
258 | a vertex count to the constructor or by calling allocate() later. |
259 | |
260 | The QSGGeometry can optionally contain indices of either unsigned |
261 | 32-bit, unsigned 16-bit, or unsigned 8-bit integers. The index type |
262 | must be specified during construction and cannot be changed. |
263 | |
264 | Below is a snippet illustrating how a geometry composed of |
265 | position and color vertices can be built. |
266 | |
267 | \code |
268 | struct MyPoint2D { |
269 | float x; |
270 | float y; |
271 | float r; |
272 | float g; |
273 | float b; |
274 | float a; |
275 | |
276 | void set(float x_, float y_, float r_, float g_, float b_, float a_) { |
277 | x = x_; |
278 | y = y_; |
279 | r = r_; |
280 | g = g_; |
281 | b = b_; |
282 | a = a_; |
283 | } |
284 | }; |
285 | |
286 | QSGGeometry::Attribute MyPoint2D_Attributes[] = { |
287 | QSGGeometry::Attribute::create(0, 2, GL_FLOAT, true), |
288 | QSGGeometry::Attribute::create(1, 4, GL_FLOAT, false) |
289 | }; |
290 | |
291 | QSGGeometry::AttributeSet MyPoint2D_AttributeSet = { |
292 | 2, |
293 | sizeof(MyPoint2D), |
294 | MyPoint2D_Attributes |
295 | }; |
296 | |
297 | ... |
298 | |
299 | geometry = new QSGGeometry(MyPoint2D_AttributeSet, 2); |
300 | geometry->setDrawingMode(GL_LINES); |
301 | |
302 | MyPoint2D *vertices = static_cast<MyPoint2D *>(geometry->vertexData()); |
303 | vertices[0].set(0, 0, 1, 0, 0, 1); |
304 | vertices[1].set(width(), height(), 0, 0, 1, 1); |
305 | \endcode |
306 | |
307 | The QSGGeometry is a software buffer and client-side in terms of |
308 | OpenGL rendering, as the buffers used in 2D graphics typically consist of |
309 | many small buffers that change every frame and do not benefit from |
310 | being uploaded to graphics memory. However, the QSGGeometry |
311 | supports hinting to the renderer that a buffer should be |
312 | uploaded using the setVertexDataPattern() and |
313 | setIndexDataPattern() functions. Whether this hint is respected or |
314 | not is implementation specific. |
315 | |
316 | \sa QSGGeometryNode, {Scene Graph - Custom Geometry} |
317 | |
318 | \note All classes with QSG prefix should be used solely on the scene graph's |
319 | rendering thread. See \l {Scene Graph and Rendering} for more information. |
320 | |
321 | */ |
322 | |
323 | /*! |
324 | \fn int QSGGeometry::attributeCount() const |
325 | |
326 | Returns the number of attributes in the attrbute set used by this geometry. |
327 | */ |
328 | |
329 | /*! |
330 | \fn QSGGeometry::Attribute *QSGGeometry::attributes() const |
331 | |
332 | Returns an array with the attributes of this geometry. The size of the array |
333 | is given with attributeCount(). |
334 | */ |
335 | |
336 | /*! |
337 | \fn uint *QSGGeometry::indexDataAsUInt() |
338 | |
339 | Convenience function to access the index data as a mutable array of |
340 | 32-bit unsigned integers. |
341 | */ |
342 | |
343 | /*! |
344 | \fn const uint *QSGGeometry::indexDataAsUInt() const |
345 | |
346 | Convenience function to access the index data as an immutable array of |
347 | 32-bit unsigned integers. |
348 | */ |
349 | |
350 | /*! |
351 | \fn quint16 *QSGGeometry::indexDataAsUShort() |
352 | |
353 | Convenience function to access the index data as a mutable array of |
354 | 16-bit unsigned integers. |
355 | */ |
356 | |
357 | /*! |
358 | \fn const quint16 *QSGGeometry::indexDataAsUShort() const |
359 | |
360 | Convenience function to access the index data as an immutable array of |
361 | 16-bit unsigned integers. |
362 | */ |
363 | |
364 | /*! |
365 | \fn const QSGGeometry::ColoredPoint2D *QSGGeometry::vertexDataAsColoredPoint2D() const |
366 | |
367 | Convenience function to access the vertex data as an immutable |
368 | array of QSGGeometry::ColoredPoint2D. |
369 | */ |
370 | |
371 | /*! |
372 | \fn QSGGeometry::ColoredPoint2D *QSGGeometry::vertexDataAsColoredPoint2D() |
373 | |
374 | Convenience function to access the vertex data as a mutable |
375 | array of QSGGeometry::ColoredPoint2D. |
376 | */ |
377 | |
378 | /*! |
379 | \fn const QSGGeometry::TexturedPoint2D *QSGGeometry::vertexDataAsTexturedPoint2D() const |
380 | |
381 | Convenience function to access the vertex data as an immutable |
382 | array of QSGGeometry::TexturedPoint2D. |
383 | */ |
384 | |
385 | /*! |
386 | \fn QSGGeometry::TexturedPoint2D *QSGGeometry::vertexDataAsTexturedPoint2D() |
387 | |
388 | Convenience function to access the vertex data as a mutable |
389 | array of QSGGeometry::TexturedPoint2D. |
390 | */ |
391 | |
392 | /*! |
393 | \fn const QSGGeometry::Point2D *QSGGeometry::vertexDataAsPoint2D() const |
394 | |
395 | Convenience function to access the vertex data as an immutable |
396 | array of QSGGeometry::Point2D. |
397 | */ |
398 | |
399 | /*! |
400 | \fn QSGGeometry::Point2D *QSGGeometry::vertexDataAsPoint2D() |
401 | |
402 | Convenience function to access the vertex data as a mutable |
403 | array of QSGGeometry::Point2D. |
404 | */ |
405 | |
406 | |
407 | /*! |
408 | Constructs a geometry object based on \a attributes. |
409 | |
410 | The object allocate space for \a vertexCount vertices based on the |
411 | accumulated size in \a attributes and for \a indexCount. |
412 | |
413 | The \a indexType maps to the OpenGL index type and can be |
414 | \c GL_UNSIGNED_SHORT and \c GL_UNSIGNED_BYTE. On OpenGL implementations that |
415 | support it, such as desktop OpenGL, \c GL_UNSIGNED_INT can also be used. |
416 | |
417 | Geometry objects are constructed with \c GL_TRIANGLE_STRIP as default |
418 | drawing mode. |
419 | |
420 | The attribute structure is assumed to be POD and the geometry object |
421 | assumes this will not go away. There is no memory management involved. |
422 | */ |
423 | |
424 | QSGGeometry::QSGGeometry(const QSGGeometry::AttributeSet &attributes, |
425 | int vertexCount, |
426 | int indexCount, |
427 | int indexType) |
428 | : m_drawing_mode(DrawTriangleStrip) |
429 | , m_vertex_count(0) |
430 | , m_index_count(0) |
431 | , m_index_type(indexType) |
432 | , m_attributes(attributes) |
433 | , m_data(nullptr) |
434 | , m_index_data_offset(-1) |
435 | , m_server_data(nullptr) |
436 | , m_owns_data(false) |
437 | , m_index_usage_pattern(AlwaysUploadPattern) |
438 | , m_vertex_usage_pattern(AlwaysUploadPattern) |
439 | , m_line_width(1.0) |
440 | { |
441 | Q_UNUSED(m_reserved_bits); |
442 | Q_ASSERT(m_attributes.count > 0); |
443 | Q_ASSERT(m_attributes.stride > 0); |
444 | #if QT_CONFIG(opengl) |
445 | Q_ASSERT_X(indexType != GL_UNSIGNED_INT |
446 | || !QOpenGLContext::currentContext() // rhi, support for uint cannot be checked here |
447 | || static_cast<QOpenGLExtensions *>(QOpenGLContext::currentContext()->functions()) |
448 | ->hasOpenGLExtension(QOpenGLExtensions::ElementIndexUint), |
449 | "QSGGeometry::QSGGeometry" , |
450 | "GL_UNSIGNED_INT is not supported, geometry will not render" |
451 | ); |
452 | #endif |
453 | if (indexType != UnsignedByteType |
454 | && indexType != UnsignedShortType |
455 | && indexType != UnsignedIntType) { |
456 | qFatal(msg: "QSGGeometry: Unsupported index type, %x.\n" , indexType); |
457 | } |
458 | |
459 | // Because allocate reads m_vertex_count, m_index_count and m_owns_data, these |
460 | // need to be set before calling allocate... |
461 | allocate(vertexCount, indexCount); |
462 | } |
463 | |
464 | /*! |
465 | \fn int QSGGeometry::sizeOfVertex() const |
466 | |
467 | Returns the size in bytes of one vertex. |
468 | |
469 | This value comes from the attributes. |
470 | */ |
471 | |
472 | /*! |
473 | \fn int QSGGeometry::sizeOfIndex() const |
474 | |
475 | Returns the byte size of the index type. |
476 | |
477 | This value is either \c 1 when index type is \c GL_UNSIGNED_BYTE or \c 2 |
478 | when index type is \c GL_UNSIGNED_SHORT. For Desktop OpenGL, |
479 | \c GL_UNSIGNED_INT with the value \c 4 is also supported. |
480 | */ |
481 | |
482 | /*! |
483 | Destroys the geometry object and the vertex and index data it has allocated. |
484 | */ |
485 | |
486 | QSGGeometry::~QSGGeometry() |
487 | { |
488 | if (m_owns_data) |
489 | free(ptr: m_data); |
490 | |
491 | if (m_server_data) |
492 | delete m_server_data; |
493 | } |
494 | |
495 | /*! |
496 | \fn int QSGGeometry::vertexCount() const |
497 | |
498 | Returns the number of vertices in this geometry object. |
499 | */ |
500 | |
501 | /*! |
502 | \fn int QSGGeometry::indexCount() const |
503 | |
504 | Returns the number of indices in this geometry object. |
505 | */ |
506 | |
507 | |
508 | |
509 | /*! |
510 | \fn void *QSGGeometry::vertexData() |
511 | |
512 | Returns a pointer to the raw vertex data of this geometry object. |
513 | |
514 | \sa vertexDataAsPoint2D(), vertexDataAsTexturedPoint2D() |
515 | */ |
516 | |
517 | /*! |
518 | \fn const void *QSGGeometry::vertexData() const |
519 | |
520 | Returns a pointer to the raw vertex data of this geometry object. |
521 | |
522 | \sa vertexDataAsPoint2D(), vertexDataAsTexturedPoint2D() |
523 | */ |
524 | |
525 | /*! |
526 | Returns a pointer to the raw index data of this geometry object. |
527 | |
528 | \sa indexDataAsUShort(), indexDataAsUInt() |
529 | */ |
530 | void *QSGGeometry::indexData() |
531 | { |
532 | return m_index_data_offset < 0 |
533 | ? nullptr |
534 | : ((char *) m_data + m_index_data_offset); |
535 | } |
536 | |
537 | /*! |
538 | Returns a pointer to the raw index data of this geometry object. |
539 | |
540 | \sa indexDataAsUShort(), indexDataAsUInt() |
541 | */ |
542 | const void *QSGGeometry::indexData() const |
543 | { |
544 | return m_index_data_offset < 0 |
545 | ? nullptr |
546 | : ((char *) m_data + m_index_data_offset); |
547 | } |
548 | |
549 | /*! |
550 | \enum QSGGeometry::DrawingMode |
551 | |
552 | The values correspond to OpenGL enum values like \c GL_POINTS, \c GL_LINES, |
553 | etc. QSGGeometry provies its own type in order to be able to provide the |
554 | same API with non-OpenGL backends as well. |
555 | |
556 | \value DrawPoints |
557 | \value DrawLines |
558 | \value DrawLineLoop |
559 | \value DrawLineStrip |
560 | \value DrawTriangles |
561 | \value DrawTriangleStrip |
562 | \value DrawTriangleFan |
563 | */ |
564 | |
565 | /*! |
566 | \enum QSGGeometry::Type |
567 | |
568 | The values correspond to OpenGL type constants like \c GL_BYTE, \c |
569 | GL_UNSIGNED_BYTE, etc. QSGGeometry provies its own type in order to be able |
570 | to provide the same API with non-OpenGL backends as well. |
571 | |
572 | \value ByteType |
573 | \value UnsignedByteType |
574 | \value ShortType |
575 | \value UnsignedShortType |
576 | \value IntType |
577 | \value UnsignedIntType |
578 | \value FloatType |
579 | \value Bytes2Type Added in Qt 5.14. |
580 | \value Bytes3Type Added in Qt 5.14. |
581 | \value Bytes4Type Added in Qt 5.14. |
582 | \value DoubleType Added in Qt 5.14. |
583 | */ |
584 | |
585 | /*! |
586 | Sets the \a mode to be used for drawing this geometry. |
587 | |
588 | The default value is QSGGeometry::DrawTriangleStrip. |
589 | |
590 | \sa DrawingMode |
591 | */ |
592 | void QSGGeometry::setDrawingMode(unsigned int mode) |
593 | { |
594 | m_drawing_mode = mode; |
595 | } |
596 | |
597 | /*! |
598 | Gets the current line or point width or to be used for this geometry. This |
599 | property only applies to line width when the drawingMode is DrawLines, |
600 | DarwLineStrip, or DrawLineLoop. For desktop OpenGL, it also applies to |
601 | point size when the drawingMode is DrawPoints. |
602 | |
603 | The default value is \c 1.0 |
604 | |
605 | \note When not using OpenGL, support for point and line drawing may be |
606 | limited. For example, some APIs do not support point sprites and so setting |
607 | a size other than 1 is not possible. Some backends may be able implement |
608 | support via geometry shaders, but this is not guaranteed to be always |
609 | available. |
610 | |
611 | \sa setLineWidth(), drawingMode() |
612 | */ |
613 | float QSGGeometry::lineWidth() const |
614 | { |
615 | return m_line_width; |
616 | } |
617 | |
618 | /*! |
619 | Sets the line or point width to be used for this geometry to \a width. This |
620 | property only applies to line width when the drawingMode is DrawLines, |
621 | DrawLineStrip, or DrawLineLoop. For Desktop OpenGL, it also applies to |
622 | point size when the drawingMode is DrawPoints. |
623 | |
624 | \note How line width and point size are treated is implementation |
625 | dependent: The application should not rely on these, but rather create |
626 | triangles or similar to draw areas. On OpenGL ES, line width support is |
627 | limited and point size is unsupported. |
628 | |
629 | \sa lineWidth(), drawingMode() |
630 | */ |
631 | void QSGGeometry::setLineWidth(float width) |
632 | { |
633 | m_line_width = width; |
634 | } |
635 | |
636 | /*! |
637 | \fn int QSGGeometry::drawingMode() const |
638 | |
639 | Returns the drawing mode of this geometry. |
640 | |
641 | The default value is \c GL_TRIANGLE_STRIP. |
642 | */ |
643 | |
644 | /*! |
645 | \fn int QSGGeometry::indexType() const |
646 | |
647 | Returns the primitive type used for indices in this |
648 | geometry object. |
649 | */ |
650 | |
651 | |
652 | /*! |
653 | Resizes the vertex and index data of this geometry object to fit \a vertexCount |
654 | vertices and \a indexCount indices. |
655 | |
656 | Vertex and index data will be invalidated after this call and the caller must |
657 | mark the associated geometry node as dirty, by calling |
658 | node->markDirty(QSGNode::DirtyGeometry) to ensure that the renderer has |
659 | a chance to update internal buffers. |
660 | */ |
661 | void QSGGeometry::allocate(int vertexCount, int indexCount) |
662 | { |
663 | if (vertexCount == m_vertex_count && indexCount == m_index_count) |
664 | return; |
665 | |
666 | m_vertex_count = vertexCount; |
667 | m_index_count = indexCount; |
668 | |
669 | bool canUsePrealloc = m_index_count <= 0; |
670 | int vertexByteSize = m_attributes.stride * m_vertex_count; |
671 | |
672 | if (m_owns_data) |
673 | free(ptr: m_data); |
674 | |
675 | if (canUsePrealloc && vertexByteSize <= (int) sizeof(m_prealloc)) { |
676 | m_data = (void *) &m_prealloc[0]; |
677 | m_index_data_offset = -1; |
678 | m_owns_data = false; |
679 | } else { |
680 | Q_ASSERT(m_index_type == UnsignedIntType || m_index_type == UnsignedShortType); |
681 | int indexByteSize = indexCount * (m_index_type == UnsignedShortType ? sizeof(quint16) : sizeof(quint32)); |
682 | m_data = (void *) malloc(size: vertexByteSize + indexByteSize); |
683 | Q_CHECK_PTR(m_data); |
684 | m_index_data_offset = vertexByteSize; |
685 | m_owns_data = true; |
686 | } |
687 | |
688 | // If we have associated vbo data we could potentially crash later if |
689 | // the old buffers are used with the new vertex and index count, so we force |
690 | // an update in the renderer in that case. This is really the users responsibility |
691 | // but it is cheap for us to enforce this, so why not... |
692 | if (m_server_data) { |
693 | markIndexDataDirty(); |
694 | markVertexDataDirty(); |
695 | } |
696 | |
697 | } |
698 | |
699 | /*! |
700 | Updates the geometry \a g with the coordinates in \a rect. |
701 | |
702 | The function assumes the geometry object contains a single triangle strip |
703 | of QSGGeometry::Point2D vertices |
704 | */ |
705 | void QSGGeometry::updateRectGeometry(QSGGeometry *g, const QRectF &rect) |
706 | { |
707 | Point2D *v = g->vertexDataAsPoint2D(); |
708 | v[0].x = rect.left(); |
709 | v[0].y = rect.top(); |
710 | |
711 | v[1].x = rect.left(); |
712 | v[1].y = rect.bottom(); |
713 | |
714 | v[2].x = rect.right(); |
715 | v[2].y = rect.top(); |
716 | |
717 | v[3].x = rect.right(); |
718 | v[3].y = rect.bottom(); |
719 | } |
720 | |
721 | /*! |
722 | Updates the geometry \a g with the coordinates in \a rect and texture |
723 | coordinates from \a textureRect. |
724 | |
725 | \a textureRect should be in normalized coordinates. |
726 | |
727 | \a g is assumed to be a triangle strip of four vertices of type |
728 | QSGGeometry::TexturedPoint2D. |
729 | */ |
730 | void QSGGeometry::updateTexturedRectGeometry(QSGGeometry *g, const QRectF &rect, const QRectF &textureRect) |
731 | { |
732 | TexturedPoint2D *v = g->vertexDataAsTexturedPoint2D(); |
733 | v[0].x = rect.left(); |
734 | v[0].y = rect.top(); |
735 | v[0].tx = textureRect.left(); |
736 | v[0].ty = textureRect.top(); |
737 | |
738 | v[1].x = rect.left(); |
739 | v[1].y = rect.bottom(); |
740 | v[1].tx = textureRect.left(); |
741 | v[1].ty = textureRect.bottom(); |
742 | |
743 | v[2].x = rect.right(); |
744 | v[2].y = rect.top(); |
745 | v[2].tx = textureRect.right(); |
746 | v[2].ty = textureRect.top(); |
747 | |
748 | v[3].x = rect.right(); |
749 | v[3].y = rect.bottom(); |
750 | v[3].tx = textureRect.right(); |
751 | v[3].ty = textureRect.bottom(); |
752 | } |
753 | |
754 | /*! |
755 | Updates the geometry \a g with the coordinates in \a rect. |
756 | |
757 | The function assumes the geometry object contains a single triangle strip |
758 | of QSGGeometry::ColoredPoint2D vertices |
759 | */ |
760 | void QSGGeometry::updateColoredRectGeometry(QSGGeometry *g, const QRectF &rect) |
761 | { |
762 | ColoredPoint2D *v = g->vertexDataAsColoredPoint2D(); |
763 | v[0].x = rect.left(); |
764 | v[0].y = rect.top(); |
765 | |
766 | v[1].x = rect.left(); |
767 | v[1].y = rect.bottom(); |
768 | |
769 | v[2].x = rect.right(); |
770 | v[2].y = rect.top(); |
771 | |
772 | v[3].x = rect.right(); |
773 | v[3].y = rect.bottom(); |
774 | } |
775 | |
776 | /*! |
777 | \enum QSGGeometry::AttributeType |
778 | |
779 | This enum identifies several attribute types. |
780 | |
781 | \value UnknownAttribute Don't care |
782 | \value PositionAttribute Position |
783 | \value ColorAttribute Color |
784 | \value TexCoordAttribute Texture coordinate |
785 | \value TexCoord1Attribute Texture coordinate 1 |
786 | \value TexCoord2Attribute Texture coordinate 2 |
787 | |
788 | */ |
789 | |
790 | /*! |
791 | \enum QSGGeometry::DataPattern |
792 | |
793 | The DataPattern enum is used to specify the use pattern for the |
794 | vertex and index data in a geometry object. |
795 | |
796 | \value AlwaysUploadPattern The data is always uploaded. This means |
797 | that the user does not need to explicitly mark index and vertex |
798 | data as dirty after changing it. This is the default. |
799 | |
800 | \value DynamicPattern The data is modified repeatedly and drawn |
801 | many times. This is a hint that may provide better |
802 | performance. When set the user must make sure to mark the data as |
803 | dirty after changing it. |
804 | |
805 | \value StaticPattern The data is modified once and drawn many |
806 | times. This is a hint that may provide better performance. When |
807 | set the user must make sure to mark the data as dirty after |
808 | changing it. |
809 | |
810 | \value StreamPattern The data is modified for almost every time it |
811 | is drawn. This is a hint that may provide better performance. When |
812 | set, the user must make sure to mark the data as dirty after |
813 | changing it. |
814 | */ |
815 | |
816 | |
817 | /*! |
818 | \fn QSGGeometry::DataPattern QSGGeometry::indexDataPattern() const |
819 | |
820 | Returns the usage pattern for indices in this geometry. The default |
821 | pattern is AlwaysUploadPattern. |
822 | */ |
823 | |
824 | /*! |
825 | Sets the usage pattern for indices to \a p. |
826 | |
827 | The default is AlwaysUploadPattern. When set to anything other than |
828 | the default, the user must call markIndexDataDirty() after changing |
829 | the index data, in addition to calling QSGNode::markDirty() with |
830 | QSGNode::DirtyGeometry. |
831 | */ |
832 | |
833 | void QSGGeometry::setIndexDataPattern(DataPattern p) |
834 | { |
835 | m_index_usage_pattern = p; |
836 | } |
837 | |
838 | |
839 | |
840 | |
841 | /*! |
842 | \fn QSGGeometry::DataPattern QSGGeometry::vertexDataPattern() const |
843 | |
844 | Returns the usage pattern for vertices in this geometry. The default |
845 | pattern is AlwaysUploadPattern. |
846 | */ |
847 | |
848 | /*! |
849 | Sets the usage pattern for vertices to \a p. |
850 | |
851 | The default is AlwaysUploadPattern. When set to anything other than |
852 | the default, the user must call markVertexDataDirty() after changing |
853 | the vertex data, in addition to calling QSGNode::markDirty() with |
854 | QSGNode::DirtyGeometry. |
855 | */ |
856 | |
857 | void QSGGeometry::setVertexDataPattern(DataPattern p) |
858 | { |
859 | m_vertex_usage_pattern = p; |
860 | } |
861 | |
862 | |
863 | |
864 | |
865 | /*! |
866 | Mark that the vertices in this geometry has changed and must be uploaded |
867 | again. |
868 | |
869 | This function only has an effect when the usage pattern for vertices is |
870 | StaticData and the renderer that renders this geometry uploads the geometry |
871 | into Vertex Buffer Objects (VBOs). |
872 | */ |
873 | void QSGGeometry::markIndexDataDirty() |
874 | { |
875 | m_dirty_index_data = true; |
876 | } |
877 | |
878 | |
879 | |
880 | /*! |
881 | Mark that the vertices in this geometry has changed and must be uploaded |
882 | again. |
883 | |
884 | This function only has an effect when the usage pattern for vertices is |
885 | StaticData and the renderer that renders this geometry uploads the geometry |
886 | into Vertex Buffer Objects (VBOs). |
887 | */ |
888 | void QSGGeometry::markVertexDataDirty() |
889 | { |
890 | m_dirty_vertex_data = true; |
891 | } |
892 | |
893 | |
894 | QT_END_NAMESPACE |
895 | |