How do I draw a simple line in Qt3D?

后端 未结 3 857
隐瞒了意图╮
隐瞒了意图╮ 2021-02-06 09:59

I feel like this should be pretty straightforward, but for my life I can\'t figure out how to draw a basic line using Qt 3D. The only guidance I\'ve been able to find on the sub

相关标签:
3条回答
  • 2021-02-06 10:17

    I'd suggest looking at https://doc-snapshots.qt.io/qt5-5.9/qt3d-basicshapes-cpp-example.html , as a while ago I asked myself a similar question, namely, how to draw a circle. Well, a circle in 3D is a torus with a special proportion of its radii:

    // thin Torus = Circle in 3D
    Qt3DCore::QEntity *torusEntity0 = new Qt3DCore::QEntity(rootEntity);
    Qt3DExtras::QTorusMesh *torusMesh0 = new Qt3DExtras::QTorusMesh;
    torusMesh0->setRadius(15);
    torusMesh0->setMinorRadius(0.01f);
    torusMesh0->setRings(100);
    torusMesh0->setSlices(20);
    torusEntity0->addComponent(torusMesh0);
    torusEntity0->addComponent(material);
    

    So what would be a line in 3D? It would be a cylinder with a very small outer radius.

    0 讨论(0)
  • 2021-02-06 10:22

    From the video you linked, I came up with the code below (also posted in Qt forums: https://forum.qt.io/topic/66808/qt3d-draw-grid-axis-lines/3).

    First, you need to create your QGeometry. As it is a simple line, it is only composed of 2 vertices (start point, end point), and 2 indices (that links the vertices). To do so, you need to create 2 QByteArray and store them into a QBuffer. In the first one, you store the 2 vertices (x, y, and z coordinates for each). In the second, you just say that you want to link your first vertex to the second. As we use Qt3DRender::QGeometryRenderer::Lines on the renderer, only 2 indices are required.

    Once it is done, you just have to put your QGeometry in a QGeometryRenderer to have a mesh, and put the mesh in a QEntity so it appears in the tree and it is rendered.

    #include <Qt3DCore/QEntity>
    #include <Qt3DCore/QTransform>
    #include <Qt3DExtras/QPhongMaterial>
    #include <Qt3DRender/QAttribute>
    #include <Qt3DRender/QBuffer>
    #include <Qt3DRender/QGeometry>
    
    void drawLine(const QVector3D& start, const QVector3D& end, const QColor& color, Qt3DCore::QEntity *_rootEntity)
    {
        auto *geometry = new Qt3DRender::QGeometry(_rootEntity);
    
        // position vertices (start and end)
        QByteArray bufferBytes;
        bufferBytes.resize(3 * 2 * sizeof(float)); // start.x, start.y, start.end + end.x, end.y, end.z
        float *positions = reinterpret_cast<float*>(bufferBytes.data());
        *positions++ = start.x();
        *positions++ = start.y();
        *positions++ = start.z();
        *positions++ = end.x();
        *positions++ = end.y();
        *positions++ = end.z();
    
        auto *buf = new Qt3DRender::QBuffer(geometry);
        buf->setData(bufferBytes);
    
        auto *positionAttribute = new Qt3DRender::QAttribute(geometry);
        positionAttribute->setName(Qt3DRender::QAttribute::defaultPositionAttributeName());
        positionAttribute->setVertexBaseType(Qt3DRender::QAttribute::Float);
        positionAttribute->setVertexSize(3);
        positionAttribute->setAttributeType(Qt3DRender::QAttribute::VertexAttribute);
        positionAttribute->setBuffer(buf);
        positionAttribute->setByteStride(3 * sizeof(float));
        positionAttribute->setCount(2);
        geometry->addAttribute(positionAttribute); // We add the vertices in the geometry
    
        // connectivity between vertices
        QByteArray indexBytes;
        indexBytes.resize(2 * sizeof(unsigned int)); // start to end
        unsigned int *indices = reinterpret_cast<unsigned int*>(indexBytes.data());
        *indices++ = 0;
        *indices++ = 1;
    
        auto *indexBuffer = new Qt3DRender::QBuffer(geometry);
        indexBuffer->setData(indexBytes);
    
        auto *indexAttribute = new Qt3DRender::QAttribute(geometry);
        indexAttribute->setVertexBaseType(Qt3DRender::QAttribute::UnsignedInt);
        indexAttribute->setAttributeType(Qt3DRender::QAttribute::IndexAttribute);
        indexAttribute->setBuffer(indexBuffer);
        indexAttribute->setCount(2);
        geometry->addAttribute(indexAttribute); // We add the indices linking the points in the geometry
    
        // mesh
        auto *line = new Qt3DRender::QGeometryRenderer(_rootEntity);
        line->setGeometry(geometry);
        line->setPrimitiveType(Qt3DRender::QGeometryRenderer::Lines);
        auto *material = new Qt3DExtras::QPhongMaterial(_rootEntity);
        material->setAmbient(color);
    
        // entity
        auto *lineEntity = new Qt3DCore::QEntity(_rootEntity);
        lineEntity->addComponent(line);
        lineEntity->addComponent(material);
    }
    
    0 讨论(0)
  • 2021-02-06 10:27

    Here's the correction I had to do on buffer type (I assume its deprecated now), respectively:

    auto *buf = new Qt3DRender::QBuffer(Qt3DRender::QBuffer::VertexBuffer, geometry);
    auto *indexBuffer = new Qt3DRender::QBuffer(Qt3DRender::QBuffer::IndexBuffer, geometry);
    

    Mine is Qt 5.9 on Win 10.

    0 讨论(0)
提交回复
热议问题