| 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 | |