Important: Please read the Qt Code of Conduct -

Data limitation using QSGGeometryNode?

  • I am using Qt 5.8. I am attempting to draw circular points using QSGGeometry::DrawTriangles (using QSGGeometry::DrawPoints draws points as rectangles/squares--not desired). In order to do this I am drawing 8 triangles that gives the illusion of a circle. Each data point will have 8 triangles associated with it. The number of data points can vary at any given time. After a (user) specified amount of time as a data point is added, one data point is removed. There seems to be an error in the allocation of data when a certain amount of points are to be drawn. I used setVertexDataPattern(QSGGeometry::StreamPattern); in the construction of the QSGGeometryNode; in hopes of getting the desired output. On each draw call, I call m_geometry.allocate(m_pts.size() * MAX_VERTICES), where MAX_VERTICES = 24 in case the number of points since the last draw call has changed. I have attempted to use GL_POLYGON (since it would require fewer vertices), but the same problem happens.
    What is the proper way to handle drawing lots of data with varying sizes? I have created a sample that allows you to change the number of points displayed.


    import QtQuick 2.8
    import QtQuick.Window 2.2
    import TestModule 1.0
    Window {
        visible: true
        width: 640
        height: 480
        title: qsTr("Hello World")
        Rectangle {
            color: "black"
            width: parent.width
            height: parent.height * .90
            MouseArea {
               anchors.fill: parent
               onClicked: {
           TestItem {
               id: testItem
               anchors.fill: parent
               ptCount: 25000
               color: "green"
        Rectangle {
            anchors.horizontalCenter: parent.horizontalCenter
            anchors.bottom: parent.bottom
            height: parent.height * .10
            width: parent.width
            border.color: "pink"
            color: "lightgray"
            TextInput {
                anchors.fill: parent
                anchors.centerIn: parent
                id: textInput
                text: "enter max number of points here"
                horizontalAlignment: TextInput.AlignHCenter
                verticalAlignment: TextInput.AlignVCenter
                color: "steelblue"
                onEditingFinished: testItem.ptCount = parseInt(textInput.text)
                validator: IntValidator{bottom: 1}


    #include <QQuickItem>
    class QSGGeometryNode;
    class TestItem : public QQuickItem
            Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY  colorChanged)
            Q_PROPERTY(qint32 ptCount READ ptCount WRITE setPtCount NOTIFY ptCountChanged)
            explicit TestItem(QQuickItem *parent = 0);
            QColor color();
            void setColor(const QColor &color);
            void setPtCount(const qint32& newVal);
            qint32 ptCount();
            void colorChanged();
            void ptCountChanged();
            QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *);
            void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry);
            QColor m_color;
            qint32 m_ptCount;


    #include "TestItem.h"
    #include <QSGNode>
    #include <QSGVertexColorMaterial>
    TestItem::TestItem(QQuickItem *parent) : QQuickItem(parent), m_color(Qt::green), m_ptCount(25000)
        setFlag(ItemHasContents, true);
    QColor TestItem::color()
        return m_color;
    void TestItem::setColor(const QColor &color)
        m_color = color;
        emit colorChanged();
    void TestItem::setPtCount(const qint32 &newVal)
        if (newVal < 0)
            m_ptCount = 25000;
            m_ptCount = newVal;
        emit ptCountChanged();
    qint32 TestItem::ptCount()
        return m_ptCount;
    QSGNode *TestItem::updatePaintNode(QSGNode *oldNode, QQuickItem::UpdatePaintNodeData *)
        QSGGeometryNode *node = nullptr;
        QSGGeometry *geometry = nullptr;
        if (!oldNode)
            node = new QSGGeometryNode;
            geometry = new QSGGeometry(QSGGeometry::defaultAttributes_ColoredPoint2D(), m_ptCount * 3);
            QSGVertexColorMaterial *material = new QSGVertexColorMaterial;
            node = static_cast<QSGGeometryNode *>(oldNode);
            geometry = node->geometry();
            geometry->allocate(m_ptCount * 3);
        QSGGeometry::ColoredPoint2D *vertices = geometry->vertexDataAsColoredPoint2D();
        qreal triWidth = 250/boundingRect().width() + 10;
        for (int i = 0; i < m_ptCount; ++i)
            QColor color;
            if (i == m_ptCount - 1)
                color = Qt::white;
                color = m_color;
            qreal x0 = (boundingRect().width() * .90/m_ptCount) * i ;
            qreal y0 = 60 * sinf(x0* 3.14/180); // 60 just varies the height of the wave
            qreal x1 = x0 + 0.05 * boundingRect().width(); // 0.05 so that we have 5% space on each side
            qreal y1 = y0 + boundingRect().height()/2;
            vertices[i * 3].set(x1, y1,,,, color.alpha());
            vertices[i * 3 + 1].set(x1 + triWidth, y1,,,, color.alpha());
            vertices[i * 3 + 2].set(x1 + triWidth, y1 + triWidth,,,, color.alpha());
        return node;
    void TestItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
        QQuickItem::geometryChanged(newGeometry, oldGeometry);

Log in to reply