QQuick3DGeometry Class
用于定义自定义几何体的基类。更多
Header: | #include <QQuick3DGeometry> |
In QML: | Geometry |
Inherits: | QQuick3DObject |
公共函数
void | addAttribute(QQuick3DGeometry::Attribute::Semantic semantic, int offset, QQuick3DGeometry::Attribute::ComponentType componentType) |
void | addAttribute(const QQuick3DGeometry::Attribute &attribute) |
void | addSubset(int offset, int count, const QVector3D &boundsMin, const QVector3D &boundsMax, const QString &name = {}) |
(since 6.6) void | addTargetAttribute(quint32 targetId, QQuick3DGeometry::Attribute::Semantic semantic, int offset, int stride = 0) |
(since 6.6) void | addTargetAttribute(const QQuick3DGeometry::TargetAttribute &attribute) |
QQuick3DGeometry::Attribute | attribute(int index) const |
int | attributeCount() const |
QVector3D | boundsMax() const |
QVector3D | boundsMin() const |
void | clear() |
QByteArray | indexData() 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) |
(since 6.6) void | setTargetData(const QByteArray &data) |
(since 6.6) void | setTargetData(int offset, const QByteArray &data) |
void | setVertexData(const QByteArray &data) |
void | setVertexData(int offset, const QByteArray &data) |
int | stride() const |
QVector3D | subsetBoundsMax(int subset) const |
QVector3D | subsetBoundsMin(int subset) const |
int | subsetCount() const |
int | subsetCount(int subset) const |
QString | subsetName(int subset) const |
int | subsetOffset(int subset) const |
(since 6.6) QQuick3DGeometry::TargetAttribute | targetAttribute(int index) const |
(since 6.6) int | targetAttributeCount() const |
(since 6.6) QByteArray | targetData() const |
QByteArray | vertexData() const |
详细说明
QQuick3DGeometry 可用于在Qt Quick 3D 场景中为模型指定自定义几何体。
虽然并非严格要求,但典型的用法是从该类继承。然后,通过在类型系统中注册,子类就会暴露在 QML 中。然后,Model 的geometry 属性就可以设置为引用已注册类型的实例。
这种类的高层结构通常与下面类似:
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); ... } };
然后,这个类就可以注册为 QML 类型,并与Model 一起使用。
在 Qt 5 中,类型注册是通过qmlRegisterType 进行的:
qmlRegisterType<CustomGeometry>("Example", 1, 0, "CustomGeometry");
在 Qt 6 中,默认的方法是在构建系统的帮助下使用自动注册。在.pro
文件中,不再调用qmlRegisterType :
CONFIG += qmltypes QML_IMPORT_NAME = Example QML_IMPORT_MAJOR_VERSION = 1
在 CMake 中,自动注册是默认行为,因此除了基本的 QML 模块设置外,无需其他特殊设置:
qt_add_qml_module(application
URI Example
VERSION 1.0
)
类实现应添加QML_NAMED_ELEMENT :
class CustomGeometry : public QQuick3DGeometry { Q_OBJECT QML_NAMED_ELEMENT(CustomGeometry) ... };
然后,QML 代码就可以使用自定义类型:
import Example 1.0 Model { id: customModel geometry: CustomGeometry { } }
自定义几何体至少应指定以下内容:
- 顶点数据、
- 顶点跨距、
- 原始类型、
- 一个具有 PositionSemantic(位置语义)的属性。
这些足以渲染网格。对于索引绘图,还需要指定索引缓冲区数据和一个具有 IndexSemantic 的属性。为了支持拾取(输入),该类必须使用setBounds() 指定边界体积。为了获得适当的光照,需要指定一个 NormalSemantic 属性。当材质使用纹理时,必须提供至少一组 UV 坐标,并在 TexCoord0Semantic 或 TexCoord1Semantic 属性中进行描述。有些材质可能还需要切线和二项式。
作为一个具体、简约的例子,下面的类将为单个三角形提供几何体:
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); }
根据场景中的光照情况,从模型中引用该几何体的结果如下所示:
注: 顶点数据应遵循 OpenGL 约定。这意味着在提供数据时,必须假定 Y 轴在规范化设备坐标系中指向上方,并且正面具有逆时针方向的卷绕。
成员函数文档
void QQuick3DGeometry::addAttribute(QQuick3DGeometry::Attribute::Semantic semantic, int offset, QQuick3DGeometry::Attribute::ComponentType componentType)
添加顶点属性描述。每个属性都有一个semantic ,它指定了属性的用途和它的组件数,一个从顶点开始到顶点内属性位置的offset ,以及一个指定属性的数据类型和大小的componentType 。
语义可以是以下其中之一:
常量 | 说明 |
---|---|
PositionSemantic | 属性是一个位置。3 个分量:X、Y 和Z |
NormalSemantic | 属性是法向量。3 个分量:X、Y 和Z |
TexCoord0Semantic | 属性是纹理坐标。2 个分量:u和v |
TexCoord1Semantic | 属性为纹理坐标。2 个分量:u和v |
TangentSemantic | 属性为切线向量。3 个分量:x、y 和z |
BinormalSemantic | 属性是一个双法向量。3 个分量:x、y 和z |
JointSemantic | 属性为联合索引向量,用于剥皮。4 个分量:联合索引 1-4 |
WeightSemantic | 该属性是用于剥皮的权重向量。4 个分量:联合权重 1-4 |
ColorSemantic | 属性是顶点颜色向量。4 个分量:R、G、B 和A |
TargetPositionSemantic | 属性是第一个变形目标的位置。3 个分量:X、Y 和Z |
TargetNormalSemantic | 属性是第一个变形目标的法向量。3 个分量:x、y 和z |
TargetTangentSemantic | 属性是第一个变形目标的切线向量。3 个分量:x、y 和z |
TargetBinormalSemantic | 属性是第一个变形目标的双法线向量。3 个分量:x、y 和z |
此外,semantic 可以是IndexSemantic
。在这种情况下,属性并不代表顶点缓冲区中的条目,而是描述索引缓冲区中的索引数据。由于每个顶点始终只有一个索引,因此offset 对索引缓冲区没有意义,应保持为零。
组件类型可以是以下类型之一:
常量 | 说明 |
---|---|
U16Type | 索引组件类型是无符号 16 位整数。仅支持IndexSemantic 。 |
U32Type | 属性(或索引组件)是无符号 32 位整数。 |
I32Type | 属性为有符号 32 位整数。请注意,旧的 OpenGL 版本(如 2.1 或 OpenGL ES 2.0)可能不支持此数据类型。 |
F32Type | 属性为单精度浮点数。 |
注: 联合索引数据通常为I32Type
。也支持F32Type
,以便与不支持整数顶点输入属性的 API(如 OpenGL ES 2.0)配合使用。
注: 对于索引数据 (IndexSemantic
),只有 U16Type 和 U32Type 才是合理的并受支持。
注: TargetXXXSemantics 将被弃用。addTargetAttribute 可用于变形目标。现在支持这些语义只是为了向后兼容。如果与addTargetAttribute 和setTargetData 混合使用,则无法保证结果。
void QQuick3DGeometry::addAttribute(const QQuick3DGeometry::Attribute &attribute)
这是一个重载函数。
添加顶点属性描述。每个属性都有一个语义,其中指定了属性的用途及其组件的数量,一个从顶点开始到顶点内属性位置的偏移量,以及一个指定属性数据类型和大小的 componentType。
void QQuick3DGeometry::addSubset(int offset, int count, const QVector3D &boundsMin, const QVector3D &boundsMax, const QString &name = {})
为几何体添加新的子集。子集允许使用不同的材质渲染几何体的各个部分。材料在model 中指定。
如果几何体有索引缓冲区,offset 和count 是子集中的基元偏移和索引计数。如果几何体只有顶点缓冲区,偏移量是顶点偏移量,计数是子集中的顶点数。
子集的边界boundsMin 和boundsMax 应与几何体边界一样包围子集。此外,子集还可以有一个name 。
[since 6.6]
void QQuick3DGeometry::addTargetAttribute(quint32 targetId, QQuick3DGeometry::Attribute::Semantic semantic, int offset, int stride = 0)
添加变形目标属性描述。每个属性都有一个属性所属的targetId ,一个semantic ,它指定了属性的用途和它的组件数,一个从顶点开始到顶点内属性位置的offset ,以及一个stride ,它是元素之间的字节大小。
注: targetId 应从 0 开始增加,不能跳过任何数字,所有目标都应具有相同的属性。
注: 语义与顶点属性相同,但目标属性不允许使用 IndexSemantic、JointSementic 和 WeightSemantic。
注: 所有目标属性的 componentType 都必须是 F32Type。
注: 如果未给定跨距或跨距小于或等于零,则认为该属性紧密堆积。
此函数在 Qt 6.6 中引入。
另请参阅 addAttribute 。
[since 6.6]
void QQuick3DGeometry::addTargetAttribute(const QQuick3DGeometry::TargetAttribute &attribute)
这是一个重载函数。
添加变形目标属性描述。每个属性都有一个属性所属的 targetId、一个语义(指定属性的用途及其组件数量)、一个从顶点开始到顶点内属性位置的偏移量,以及一个跨距(元素之间的字节大小)。
该函数在 Qt 6.6 中引入。
QQuick3DGeometry::Attribute QQuick3DGeometry::attribute(int index) const
返回属性定义编号index
属性定义的编号从 0 到attributeCount() - 1
int QQuick3DGeometry::attributeCount() const
返回为该几何体定义的属性数量。
另请参阅 attribute 。
QVector3D QQuick3DGeometry::boundsMax() const
返回包围体的最大坐标。
另请参见 setBounds 。
QVector3D QQuick3DGeometry::boundsMin() const
返回包围体的最小坐标。
另请参见 setBounds 。
void QQuick3DGeometry::clear()
将几何体重置为初始状态,清除之前设置的顶点和索引数据以及属性。
QByteArray QQuick3DGeometry::indexData() const
返回索引缓冲区数据。
另请参见 setIndexData()。
QQuick3DGeometry::PrimitiveType QQuick3DGeometry::primitiveType() const
返回渲染时使用的基元类型。默认为Triangles
。
另请参阅 setPrimitiveType 。
void QQuick3DGeometry::setBounds(const QVector3D &min, const QVector3D &max)
将几何体的边界体积设置为由点min 和max 定义的立方体。这用于picking 。
void QQuick3DGeometry::setIndexData(const QByteArray &data)
将索引缓冲区设置为data 。要使用索引绘图,请添加一个带有IndexSemantic
另请参阅 indexData() 和addAttribute 。
void QQuick3DGeometry::setIndexData(int offset, const QByteArray &data)
这是一个重载函数。
offset 指定以字节为单位的偏移量,data 指定大小和数据。
该函数不会调整缓冲区的大小。如果offset + data.size()
大于缓冲区的当前大小,则超调数据将被忽略。
注意: 顶点、索引和变形目标数据的部分更新函数无法保证内部如何执行此类更改。根据底层实现的不同,即使是部分更改也可能导致更新整个图形资源。
void QQuick3DGeometry::setPrimitiveType(QQuick3DGeometry::PrimitiveType type)
将用于渲染的基元类型设置为type 。
常量 | 描述 |
---|---|
Points | 基元为点。 |
LineStrip | 基元为条形图中的线。 |
Lines | 基元为列表中的线条。 |
TriangleStrip | 基元是条形图中的三角形。 |
TriangleFan | 基元是扇形中的三角形。请注意,根据底层图形 API 的不同,运行时可能不支持三角形扇形。 |
Triangles | 基元是一个列表中的三角形。 |
初始值为Triangles
。
注: 请注意,根据底层图形 API 的不同,运行时可能不支持三角形扇形 (TriangleFan)。例如,在使用 Direct 3D 时,这种拓扑结构根本无法运行。
注: 点(Points)的点尺寸以及线(Lines)和线条(LineStrip)的线宽由material 控制。但请注意,根据底层图形 API 的不同,运行时可能不支持 1 以上的尺寸。
另请参见 primitiveType().
void QQuick3DGeometry::setStride(int stride)
将顶点缓冲区的跨距设置为stride ,单位为字节。这是缓冲区中两个连续顶点之间的距离。
例如,对于使用PositionSemantic
、IndexSemantic
和ColorSemantic
的几何体,如果顶点缓冲区紧密排列、交错,则其跨距为28
(共有七个浮点数:三个浮点数表示位置,四个浮点数表示颜色,没有浮点数表示索引,索引不在顶点缓冲区中)。
注意: QQuick3DGeometry 希望并只能使用具有交错属性布局的顶点数据。
另请参见 stride() 和addAttribute 。
[since 6.6]
void QQuick3DGeometry::setTargetData(const QByteArray &data)
设置变形目标缓冲区data 。缓冲区应保存所有 morph target 数据。
此函数在 Qt 6.6 中引入。
另请参阅 targetData() 和addTargetAttribute 。
[since 6.6]
void QQuick3DGeometry::setTargetData(int offset, const QByteArray &data)
这是一个重载函数。
offset 指定以字节为单位的偏移量,data 指定大小和数据。
此函数不会调整缓冲区的大小。如果offset + data.size()
大于缓冲区的当前大小,超调数据将被忽略。
注意: 顶点、索引和变形目标数据的部分更新函数无法保证内部如何执行此类更改。根据底层实现的不同,即使是部分更改也可能导致更新整个图形资源。
此函数在 Qt 6.6 中引入。
void QQuick3DGeometry::setVertexData(const QByteArray &data)
设置顶点缓冲区data 。该缓冲区应包含数组中的所有顶点数据,如属性定义所述。请注意,这不包括IndexSemantic
的属性,这些属性属于索引缓冲区。
另请参阅 vertexData(),addAttribute,setStride, 和setIndexData 。
void QQuick3DGeometry::setVertexData(int offset, const QByteArray &data)
这是一个重载函数。
offset 指定以字节为单位的偏移量,data 指定大小和数据。
此函数不会调整缓冲区的大小。如果offset + data.size()
大于缓冲区的当前大小,则会忽略超量数据。
注: 顶点、索引和变形目标数据的部分更新函数并不保证内部如何执行此类更改。根据底层执行情况,即使是部分更改也可能导致更新整个图形资源。
int QQuick3DGeometry::stride() const
返回顶点缓冲区的字节跨距。
另请参阅 setStride 。
QVector3D QQuick3DGeometry::subsetBoundsMax(int subset) const
返回subset 的最大边界数。
另请参见 subsetBoundsMin 。
QVector3D QQuick3DGeometry::subsetBoundsMin(int subset) const
返回subset 的最小边界数。
另请参见 subsetBoundsMax 。
int QQuick3DGeometry::subsetCount() const
返回子集的数量。
int QQuick3DGeometry::subsetCount(int subset) const
返回子集基元计数。
另请参见 subsetOffset 。
QString QQuick3DGeometry::subsetName(int subset) const
返回subset 名称。
int QQuick3DGeometry::subsetOffset(int subset) const
返回顶点或索引缓冲区的subset 偏移量。
另请参阅 subsetCount 。
[since 6.6]
QQuick3DGeometry::TargetAttribute QQuick3DGeometry::targetAttribute(int index) const
返回变形目标属性定义编号index
属性定义的编号从 0 到attributeCount() - 1
此函数在 Qt 6.6 中引入。
[since 6.6]
int QQuick3DGeometry::targetAttributeCount() const
返回为该几何体定义的变形目标属性的数量。
此函数在 Qt 6.6 中引入。
另请参阅 targetAttribute 。
[since 6.6]
QByteArray QQuick3DGeometry::targetData() const
返回由setTargetData 设置的目标缓冲区数据。
此函数在 Qt 6.6 中引入。
另请参阅 setTargetData() 。
QByteArray QQuick3DGeometry::vertexData() const
返回由setVertexData 设置的顶点缓冲区数据。
另请参见 setVertexData().
© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.