QQuick3DGeometry Class
Base class for defining custom geometry. More...
Header: | #include <QQuick3DGeometry> |
Since: | Qt 5.15 |
Instantiated By: | Geometry |
Inherits: | QQuick3DObject |
Public Functions
void | addAttribute(Attribute::Semantic semantic, int offset, Attribute::ComponentType componentType) |
void | addAttribute(const QQuick3DGeometry::Attribute &attribute) |
QQuick3DGeometry::Attribute | attribute(int index) const |
int | attributeCount() const |
QVector3D | boundsMax() const |
QVector3D | boundsMin() const |
void | clear() |
QByteArray | indexBuffer() const |
QQuick3DGeometry::PrimitiveType | primitiveType() const |
void | setBounds(const QVector3D &min, const QVector3D &max) |
void | setIndexData(const QByteArray &data) |
void | setIndexData(int offset, const QByteArray &data) |
void | setPrimitiveType(QQuick3DGeometry::PrimitiveType type) |
void | setStride(int stride) |
void | setVertexData(const QByteArray &data) |
void | setVertexData(int offset, const QByteArray &data) |
int | stride() const |
QByteArray | vertexBuffer() const |
Detailed Description
The QQuick3DGeometry can be used to specify custom geometry for a Model in the Qt Quick 3D scene.
While not strictly required, the typical usage is to inherit from this class. The subclass is then exposed to QML by registering it to the type system. The geometry property of a Model can then be set to reference an instance of the registered type.
The high-level structure of such a class is typically similar to the following:
class CustomGeometry : public QQuick3DGeometry { public: CustomGeometry() { rebuildGeometry(); } void setSomething() { // Change relevant internal data. // ... // Then rebuild the vertex and index data and pass it to QQuick3DGeometry. rebuildGeometry(); // Finally, trigger an update. This is relevant in case nothing else // is changing in the scene; this way we make sure a new frame will // be rendered. update(); } private: void rebuildGeometry() { QByteArray vertices; QByteArray indices; ... setPrimitiveType(Lines); setVertexBuffer(vertices); setIndexBuffer(indices); setStride(3 * sizeof(float)); // e.g. when having 3 components per vertex setBounds(...); // minimum and maximum extents, for picking addAttribute(PositionSemantic, 0, F32Type); ... } };
This class can then be registered as a QML type and used with Model.
In Qt 5 type registration happened with qmlRegisterType:
qmlRegisterType<CustomGeometry>("Example", 1, 0, "CustomGeometry");
In Qt 6 the default approach is to use automatic registration with the help of the build system. Instead of calling qmlRegisterType, the .pro
file can now contain:
CONFIG += qmltypes QML_IMPORT_NAME = Example QML_IMPORT_MAJOR_VERSION = 1
Alternatively, with CMake the equivalent is:
set_target_properties(application PROPERTIES
QT_QML_MODULE_VERSION 1.0
QT_QML_MODULE_URI Example
)
qt6_qml_type_registration(application)
The class implementation should add QML_NAMED_ELEMENT:
class CustomGeometry : public QQuick3DGeometry { Q_OBJECT QML_NAMED_ELEMENT(CustomGeometry) ... };
The QML code can then use the custom type:
import Example 1.0
Model {
id: customModel
geometry: CustomGeometry {
}
}
At minimum, a custom geometry should have the following specified:
- vertex data,
- vertex stride,
- primitive type,
- an attribute with PositionSemantic.
These are sufficient to render the mesh. For indexed drawing, the index buffer data and an attribute with IndexSemantic needs to be specified as well. To support picking (input), the bounds have to be provided as well. For proper lighting, an attribute with NormalSemantic is needed. When the material uses texturing, at least one set of UV coordinates must be provided and described in an TexCoordSemantic attribute. Some materials may require tangents and binormals as well.
As a concrete, minimal example, the following class would provide geometry for a single triangle:
class ExampleGeometry : public QQuick3DGeometry { Q_OBJECT QML_NAMED_ELEMENT(ExampleGeometry) public: ExampleGeometry(); private: void updateData(); }; ExampleGeometry::ExampleGeometry() { updateData(); } void ExampleGeometry::updateData() { QByteArray v; v.resize(3 * 3 * sizeof(float)); float *p = reinterpret_cast<float *>(v.data()); // a triangle, front face = counter-clockwise *p++ = -1.0f; *p++ = -1.0f; *p++ = 0.0f; *p++ = 1.0f; *p++ = -1.0f; *p++ = 0.0f; *p++ = 0.0f; *p++ = 1.0f; *p++ = 0.0f; setVertexData(v); setStride(3 * sizeof(float)); setPrimitiveType(QQuick3DGeometry::PrimitiveType::Triangles); addAttribute(QQuick3DGeometry::Attribute::PositionSemantic, 0, QQuick3DGeometry::Attribute::F32Type); }
Depending on the lighting in the scene, the result of referencing this geometry from a Model:
Note: Vertex data is expected to follow OpenGL conventions. This means the data must be provided with the assumption that the Y axis is pointing up in the normalized device coordinate system, and that front faces have a counter clockwise winding.
Member Function Documentation
void QQuick3DGeometry::addAttribute(Attribute::Semantic semantic, int offset, Attribute::ComponentType componentType)
Adds vertex attribute description. Each attribute has a semantic, which specifies the usage of the attribute and the number of components it has, an offset from the beginning to the vertex to the attribute location inside a vertex and a componentType specifying the datatype and size of the attribute.
The semantic can be one of the following:
Constant | Description |
---|---|
IndexSemantic | The attribute is not a real vertex input, but rather describes the index data in the index buffer. |
PositionSemantic | The attribute is a position. |
NormalSemantic | The attribute is a normal vector. |
TexCoordSemantic | The attribute is a texture coordinate. |
TangentSemantic | The attribute is a tangent vector. |
BinormalSemantic | The attribute is a binormal vector. |
JointSemantic | The attribute is a joint index vector for skinning. |
WeightSemantic | The attribute is a weight vector for skinning. |
ColorSemantic | The attribute is a vertex color vector. |
The component type can be one of the following:
Constant | Description |
---|---|
U16Type | The attribute is an unsigned 16-bit integer. |
U32Type | The attribute is an unsigned 32-bit integer. |
I32Type | The attribute is a signed 32-bit integer. |
F32Type | The attribute is a single-precision float. |
Note: The joint index data is I32Type typically. F32Type is also supported in order to enable functioning with APIs, such as OpenGL ES 2.0, that do not support integer vertex input attributes.
void QQuick3DGeometry::addAttribute(const QQuick3DGeometry::Attribute &attribute)
Adds vertex attribute description. Each attribute has a semantic, which specifies the usage of the attribute and the number of components it has, an offset from the beginning to the vertex to the attribute location inside a vertex and a componentType specifying the datatype and size of the attribute.
QQuick3DGeometry::Attribute QQuick3DGeometry::attribute(int index) const
Returns an attribute at index
int QQuick3DGeometry::attributeCount() const
Returns the attribute count.
QVector3D QQuick3DGeometry::boundsMax() const
Returns the maximum bound coordinate.
QVector3D QQuick3DGeometry::boundsMin() const
Returns the minimum bound coordinate.
void QQuick3DGeometry::clear()
Clears previously set vertex- and index data as well as attributes.
QByteArray QQuick3DGeometry::indexBuffer() const
Returns the index buffer data.
QQuick3DGeometry::PrimitiveType QQuick3DGeometry::primitiveType() const
Returns the primitive type. The default is Triangles
.
Constant | Description |
---|---|
Points | The primitives are points. |
LineStrip | The primitives are lines in a strip. |
Lines | The primitives are lines in a list. |
TriangleStrip | The primitives are triangles in a strip. |
TriangleFan | The primitives are triangles in a fan. |
Triangles | The primitives are triangles in a list. |
Note: Be aware that triangle fans (TriangleFan) may not be supported at run time, depending on the underlying graphics API. For example, with Direct 3D this topology will not be functional at all.
Note: The point size for Points and the line width for Lines and LineStrip are controlled by the material. Be aware however that sizes other than 1 may not be supported at run time, depending on the underlying graphics API.
See also setPrimitiveType().
void QQuick3DGeometry::setBounds(const QVector3D &min, const QVector3D &max)
Sets the bounds of the geometry with min and max point.
void QQuick3DGeometry::setIndexData(const QByteArray &data)
Sets the index buffer data. If the index buffer is not set, the vertex buffer is used as is for the vertices.
void QQuick3DGeometry::setIndexData(int offset, const QByteArray &data)
Updates a subset of the index buffer. offset specifies the offset in bytes, data specifies the size and the data.
The update attempt will be ignored if offset is greater or equal to the size of current size of the buffer data set by a previous call to setIndexData(). The exception is an offset of 0, in which case calling this function is equivalent to calling setIndexData() without an offset.
If offset plus the size of data exceeds the current size of the buffer data set by a previous call to setIndexData(), only the range within the current size is updated, the rest of data is ignored.
void QQuick3DGeometry::setPrimitiveType(QQuick3DGeometry::PrimitiveType type)
Sets the primitive type.
Constant | Description |
---|---|
Points | The primitives are points. |
LineStrip | The primitives are lines in a strip. |
Lines | The primitives are lines in a list. |
TriangleStrip | The primitives are triangles in a strip. |
TriangleFan | The primitives are triangles in a fan. Be aware that triangle fans may not be supported at run time, depending on the underlying graphics API. |
Triangles | The primitives are triangles in a list. |
See also primitiveType().
void QQuick3DGeometry::setStride(int stride)
Sets the byte stride of the vertex.
See also stride().
void QQuick3DGeometry::setVertexData(const QByteArray &data)
Sets the vertex buffer data. The buffer should hold all the vertex data packed in the array described by the attributes.
void QQuick3DGeometry::setVertexData(int offset, const QByteArray &data)
Updates a subset of the vertex buffer. offset specifies the offset in bytes, data specifies the size and the data.
The update attempt will be ignored if offset is greater or equal to the size of current size of the buffer data set by a previous call to setVertexData(). The exception is an offset of 0, in which case calling this function is equivalent to calling setVertexData() without an offset.
If offset plus the size of data exceeds the current size of the buffer data set by a previous call to setVertexData(), only the range within the current size is updated, the rest of data is ignored.
Note: The partial update functions for vertex and index data do not offer any guarantee on how such changes are implemented internally. Depending on the underlying implementation, even partial changes may lead to updating the entire graphics resource.
int QQuick3DGeometry::stride() const
Returns the byte stride of the vertex buffer.
See also setStride().
QByteArray QQuick3DGeometry::vertexBuffer() const
Returns the vertex buffer data.