Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. Data limitation using QSGGeometryNode?
Forum Update on Monday, May 27th 2025

Data limitation using QSGGeometryNode?

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
1 Posts 1 Posters 431 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • K Offline
    K Offline
    kmbar2013
    wrote on last edited by
    #1

    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.

    main.qml

    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
            anchors.top: parent.top
    
            MouseArea {
               anchors.fill: parent
               onClicked: {
                   Qt.quit();
               }
           }
    
           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}
            }
        }
    }
    

    TestItem.h

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

    TestItem.cpp

    #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;
        update();
        emit colorChanged();
    }
    
    void TestItem::setPtCount(const qint32 &newVal)
    {
        if (newVal < 0)
            m_ptCount = 25000;
        else
            m_ptCount = newVal;
        update();
        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);
            geometry->setDrawingMode(GL_TRIANGLES);
            node->setGeometry(geometry);
            node->setFlag(QSGNode::OwnsGeometry);
    
            QSGVertexColorMaterial *material = new QSGVertexColorMaterial;
            node->setMaterial(material);
            node->setFlag(QSGNode::OwnsMaterial);
        }
        else
        {
            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;
            else
                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.red(), color.green(), color.blue(), color.alpha());
            vertices[i * 3 + 1].set(x1 + triWidth, y1, color.red(), color.green(), color.blue(), color.alpha());
            vertices[i * 3 + 2].set(x1 + triWidth, y1 + triWidth, color.red(), color.green(), color.blue(), color.alpha());
        }
        node->markDirty(QSGNode::DirtyGeometry);
    
        return node;
    }
    
    void TestItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
    {
        update();
        QQuickItem::geometryChanged(newGeometry, oldGeometry);
    }
    
    1 Reply Last reply
    0

    • Login

    • Login or register to search.
    • First post
      Last post
    0
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Get Qt Extensions
    • Unsolved