重新分配QSGGeometryNode顶点数据

时间:2018-05-30 13:41:40

标签: qt qml

我使用的是Qt 5.8。我试图使用SGGeometry::DrawPoints绘制圆点(使用Q setVertexDataPattern(QSGGeometry::StreamPattern);绘制点作为矩形/正方形 - 不需要)。为了做到这一点,我绘制了8个三角形,给出了圆形的幻觉。每个数据点将有8个与之关联的三角形。数据点的数量可以在任何给定时间变化。在添加(用户)指定的时间量作为数据点之后,移除一个数据点。在绘制数据时,数据分配似乎存在错误。我在构造QSGGeometryNode时使用了m_geometry.allocate(m_pts.size() * MAX_VERTICES);希望获得理想的输出。 在每次绘制调用时,我调用GL_POLYGON,其中MAX_VERTICES = 24,以防自上次绘制调用以来的点数发生变化。我试图使用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} } } } (因为它需要更少的顶点),但同样的问题发生了。似乎尝试从第一个数据点的一个切片到最后一个数据点的另一个切片绘制一个形状。每次抽奖调用重新分配是否有问题?处理不同尺寸的绘图数据的正确方法是什么?

更新我认为它可能会解决尺寸问题。我有示例代码只绘制1个三角形(而不是8),一旦达到约25000(每个三角形乘以3),奇数线就会出现并且似乎停止绘制其他三角形。在以下示例代码中(使用较少数量的点时),最后一个三角形为白色。

main.qml

#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.h

#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);
}

TestItem.cpp

node.js server run on a .bat file inside the working folder: 
http-server -p 8000
exit

on address bar:
http://localhost:8000/mypage.html

有关确定这是Qt错误还是我的错误的任何帮助? enter image description here

1 个答案:

答案 0 :(得分:0)

事实证明我需要更改几何体的构造函数以使用UnsignedIntType;它默认为UnsignedShortType。

geometry = new QSGGeometry(QSGGeometry::defaultAttributes_ColoredPoint2D(), m_ptCount * 3, 0, QSGGeometry::UnsignedIntType);