diff --git a/examples/quick3d/customgeometry/doc/images/customgeometry-example.jpg b/examples/quick3d/customgeometry/doc/images/customgeometry-example.jpg index 50a4fd6edb60e37d38f0bc604ace5eec96889128..8f443c3e9777853b1a01b38c1f0e747e40a4029b 100644 Binary files a/examples/quick3d/customgeometry/doc/images/customgeometry-example.jpg and b/examples/quick3d/customgeometry/doc/images/customgeometry-example.jpg differ diff --git a/examples/quick3d/customgeometry/doc/src/qtquick3d-examples-customgeometry.qdoc b/examples/quick3d/customgeometry/doc/src/qtquick3d-examples-customgeometry.qdoc index 228633bc7c98877f8f1d4253c4f022c7d68a10d1..c9946275cb578f8619072416bf74006b7d2b758b 100644 --- a/examples/quick3d/customgeometry/doc/src/qtquick3d-examples-customgeometry.qdoc +++ b/examples/quick3d/customgeometry/doc/src/qtquick3d-examples-customgeometry.qdoc @@ -39,4 +39,42 @@ In addition, the \l GridGeometry is also demonstrated. GridGeometry is a built-in QQuick3DGeometry implementation that provides a mesh with line primitives suitable for displaying a grid. + + The focus on this example will be on the code that provides the custom + geometry, so let's first have a look at the \c ExampleTriangleGeometry C++ + header file: + + \snippet customgeometry/examplegeometry.h triangle geometry + + The most important thing to notice is that our \c ExampleTriangleGeometry + class inherits from QQuick3DGeometry and that we call the \c + QML_NAMED_ELEMENT(ExampleTriangleGeometry) macro, making our class + accessible in QML. There are also a few properties defined through the \c + Q_PROPERTY macro which are automatically exposed in our QML object. Now, + let's look at the QML Model: + + \snippet customgeometry/main.qml model triangle + + Note that we specify the \c geometry property to use our \c + ExampleTriangleGeometry class, with the relevant properties specified. This + is all that is needed on the QML side to use a custom geometry. + + Now, lets look at the other important part of the C++ code, namely the \c + updateData() method. This method creates and uploads the data for our custom + geometry whenever a \c ExampleTriangleGeometry class is created or any of + its QML properties are updated. + + \snippet customgeometry/examplegeometry.cpp update data + + The method starts by calling \c clear() to clear all previously uploaded + data. It then computes the stride for the vertices, taking into account the + presence of normals and uv coordinates. Then a byte array is created to hold + the vertex buffer, which is then filled with vertices for a single triangle + with corners in (-1, -1, 0), (1, -1, 0) and (0, 1, 0). + + Then the vertex data is uploaded and the stride is set by calling \c + setVertexData() and \c setStride(). Then the primitive type is set by + calling \c setPrimitiveType(). Lastly, we specify how the attributes for + position, normal and uv coords are laid out in memory in the previously + uploaded buffer by calling \c addAttribute() for each attribute. */ diff --git a/examples/quick3d/customgeometry/examplegeometry.cpp b/examples/quick3d/customgeometry/examplegeometry.cpp index be5090989c787c23496242067eb79107a0ca20e8..f67bbf32c011a834ad75aac541caea0c4dd7f7df 100644 --- a/examples/quick3d/customgeometry/examplegeometry.cpp +++ b/examples/quick3d/customgeometry/examplegeometry.cpp @@ -100,7 +100,7 @@ void ExampleTriangleGeometry::setUVAdjust(float f) update(); } - +//! [update data] void ExampleTriangleGeometry::updateData() { clear(); @@ -111,9 +111,8 @@ void ExampleTriangleGeometry::updateData() if (m_hasUV) stride += 2 * sizeof(float); - QByteArray v; - v.resize(3 * stride); - float *p = reinterpret_cast<float *>(v.data()); + QByteArray vertexData(3 * stride, Qt::Initialization::Uninitialized); + float *p = reinterpret_cast<float *>(vertexData.data()); // a triangle, front face = counter-clockwise *p++ = -1.0f; *p++ = -1.0f; *p++ = 0.0f; @@ -138,7 +137,7 @@ void ExampleTriangleGeometry::updateData() *p++ = 1.0f - m_uvAdjust; *p++ = 1.0f - m_uvAdjust; } - setVertexData(v); + setVertexData(vertexData); setStride(stride); setPrimitiveType(QQuick3DGeometry::PrimitiveType::Triangles); @@ -159,8 +158,7 @@ void ExampleTriangleGeometry::updateData() QQuick3DGeometry::Attribute::F32Type); } } - - +//! [update data] ExamplePointGeometry::ExamplePointGeometry() { @@ -171,15 +169,14 @@ void ExamplePointGeometry::updateData() { clear(); - const int N = 2000; - - const int stride = 3 * sizeof(float); + constexpr int NUM_POINTS = 2000; + constexpr int stride = 3 * sizeof(float); - QByteArray v; - v.resize(N * stride); - float *p = reinterpret_cast<float *>(v.data()); + QByteArray vertexData; + vertexData.resize(NUM_POINTS * stride); + float *p = reinterpret_cast<float *>(vertexData.data()); - for (int i = 0; i < N; ++i) { + for (int i = 0; i < NUM_POINTS; ++i) { const float x = float(QRandomGenerator::global()->bounded(200.0f) - 100.0f) / 20.0f; const float y = float(QRandomGenerator::global()->bounded(200.0f) - 100.0f) / 20.0f; *p++ = x; @@ -187,7 +184,7 @@ void ExamplePointGeometry::updateData() *p++ = 0.0f; } - setVertexData(v); + setVertexData(vertexData); setStride(stride); setPrimitiveType(QQuick3DGeometry::PrimitiveType::Points); diff --git a/examples/quick3d/customgeometry/examplegeometry.h b/examples/quick3d/customgeometry/examplegeometry.h index e0d173ba9f08540e459a9fd888ca98f9228dafd9..d0eba30de64b678d38b97daf3f788fe353490a17 100644 --- a/examples/quick3d/customgeometry/examplegeometry.h +++ b/examples/quick3d/customgeometry/examplegeometry.h @@ -53,6 +53,7 @@ #include <QQuick3DGeometry> +//! [triangle geometry] class ExampleTriangleGeometry : public QQuick3DGeometry { Q_OBJECT @@ -91,6 +92,7 @@ private: bool m_hasUV = false; float m_uvAdjust = 0.0f; }; +//! [triangle geometry] class ExamplePointGeometry : public QQuick3DGeometry { diff --git a/examples/quick3d/customgeometry/main.qml b/examples/quick3d/customgeometry/main.qml index 9d6de28e92e55e1990b0f32ba7936620c3b71ff4..1ff37c7e24bed028bb03bf103042249961db5385 100644 --- a/examples/quick3d/customgeometry/main.qml +++ b/examples/quick3d/customgeometry/main.qml @@ -99,6 +99,7 @@ Window { ] } + //! [model triangle] Model { visible: radioCustGeom.checked scale: Qt.vector3d(100, 100, 100) @@ -120,6 +121,7 @@ Window { } ] } + //! [model triangle] Model { visible: radioPointGeom.checked