用Qt3D绘制三角形

Draw triangle with Qt3D

我需要用 Qt3D 画一个多边形,但我发现了如何用三角形来画。所以。我找到了一个代码,可以更紧密地与 Qt3D 的 OpenGL 配合使用。它正在画线,但我改变了一个画三角形。当我设置 setPrimitiveType(Qt3DRender::QGeometryRenderer::TriangleStrip); 时,它就起作用了。但我想用 setPrimitiveType(Qt3DRender::QGeometryRenderer::Triangles);,由于某种原因不起作用并且不绘制任何东西。也许我对顶点和索引属性的配置有误?或者也许我使用了不正确的输入? (我的输入示例在底部)

void MainWindow::drawTriangles(const QPolygonF polygon, QColor color, Qt3DCore::QEntity *_rootEntity)
{
    int numOfVertices = polygon.size();
    auto *geometry = new Qt3DRender::QGeometry(_rootEntity);

    // Create and fill vertex buffer
    QByteArray bufferBytes;
    bufferBytes.resize(3 * numOfVertices * static_cast<int>(sizeof(float)));
    float *positions = reinterpret_cast<float*>(bufferBytes.data());

    for(auto point : polygon){
        float fHalfMapWidth = (dFittedMaxMapX_ - dFittedMinMapX_) / 2;
        float fHalfMapHeight = (dFittedMaxMapY_ - dFittedMinMapY_) / 2;

        *positions++ = static_cast<float>(point.x() - (dFittedMinMapX_ + fHalfMapWidth));
        *positions++ = 0.0f; //We need to drow only on the surface
        *positions++ = static_cast<float>(point.y() - (dFittedMinMapY_ + fHalfMapHeight));
    }

    auto *buf = new Qt3DRender::QBuffer(geometry);
    buf->setData(bufferBytes);

    auto *positionAttribute = new Qt3DRender::QAttribute(geometry); // Create a vertex attribute
    positionAttribute->setName(Qt3DRender::QAttribute::defaultPositionAttributeName());
    positionAttribute->setVertexBaseType(Qt3DRender::QAttribute::Float); // In vertex buffer we store floats
    positionAttribute->setVertexSize(3); // Size of a vertex
    positionAttribute->setAttributeType(Qt3DRender::QAttribute::VertexAttribute); // Type of an attribute
    positionAttribute->setBuffer(buf); // Set vertex buffer
    positionAttribute->setByteStride(3 * sizeof(float)); // Stride between vertices
    geometry->addAttribute(positionAttribute); // Add the attribute in our  Qt3DRender::QGeometry

    // Create and fill an index buffer
    QByteArray indexBytes;
    indexBytes.resize(numOfVertices * static_cast<int>(sizeof(unsigned int))); // start to end
    unsigned int *indices = reinterpret_cast<unsigned int*>(indexBytes.data());
    for(unsigned int i = 0; i < static_cast<unsigned int>(numOfVertices); ++i) {
        *indices++ = i;
    }

    auto *indexBuffer = new Qt3DRender::QBuffer(geometry);
    indexBuffer->setData(indexBytes);

    auto *indexAttribute = new Qt3DRender::QAttribute(geometry); // Create an index attribute
    indexAttribute->setVertexBaseType(Qt3DRender::QAttribute::UnsignedInt); // In the index buffer we will store Unsigned int
    indexAttribute->setAttributeType(Qt3DRender::QAttribute::IndexAttribute); // Type of an attribute
    indexAttribute->setBuffer(indexBuffer); // Set the index buffer
    indexAttribute->setCount(static_cast<unsigned int>(numOfVertices)); // As i understand, this is a number of vertices
    geometry->addAttribute(indexAttribute); // Add attribute in our Qt3DRender::QGeometry


    auto *poly = new Qt3DRender::QGeometryRenderer(_rootEntity);
    poly->setGeometry(geometry); 
    //poly->setPrimitiveType(Qt3DRender::QGeometryRenderer::TriangleStrip); - Working variant
    poly->setPrimitiveType(Qt3DRender::QGeometryRenderer::Triangles); // - This is not working variant

    //Create a material
    auto *material = new Qt3DExtras::QPhongMaterial(_rootEntity);
    material->setAmbient(color);

    auto *trianglesEntity = new Qt3DCore::QEntity(_rootEntity);
    trianglesEntity->addComponent(poly); // Add our primitives
    trianglesEntity->addComponent(material); // Add material
}

我试过用三点和四点。当我使用 4 个点时,如果我将原始类型设置为 "TriangleStrip",它就会绘制。但是 "Triangles" 在这两种情况下都不起作用。

mapBorder << QPointF(300,200) << QPointF(100,200) << QPointF(200,0) << QPointF(300,200) << QPointF(200,0) << QPointF(500,200) << QPointF(500,300); 
drawTriangles(mapBorder, QColor(Qt::black), mapEntity_);

或者你能给我另一个如何绘制多边形或三角形的建议吗?

您的点按顺时针顺序设置,您可以重新排序或通过此 link 设置不同的行为:doc.qt.io/qt-5.11/qt3drender-qcullface.html

如果你两者都需要,我会尝试 Qt3DRender::QCullFace::NoCulling