Problem drawing triangles with QSGGeometryNode (Scene Graph).



  • Hello, I have problem with topic. I extend customgeometry example from Qt Docs (http://doc.qt.io/qt-5/qtquick-scenegraph-customgeometry-example.html) and try to draw sequence of triangles. Bellow my code:

    main.cpp:

    #include <QGuiApplication>
    #include <QQmlApplicationEngine>
    
    #include "TestOpenGL.h"
    
    int main(int argc, char *argv[])
    {
        QGuiApplication app(argc, argv);
    
        qmlRegisterType<TestOpenGL>("TestModule", 1, 0, "TestOpenGL");
    
        QQmlApplicationEngine engine;
        engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    
        return app.exec();
    }
    

    TestOpenGL.h:

    #ifndef TESTOPENGL_H
    #define TESTOPENGL_H
    
    #include <QQuickItem>
    
    class QSGGeometryNode;
    
    class TestOpenGL : public QQuickItem
    {
        Q_OBJECT
        Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
        Q_PROPERTY(QList<qreal> vertices READ vertices WRITE setVertices NOTIFY verticesChanged)
    
    public:
        explicit TestOpenGL(QQuickItem *parent = 0);
    
        QColor color();
        void setColor(const QColor &color);
    
        QList<qreal> &vertices();
        void setVertices(const QList<qreal>& newVal);
    
    signals:
        void colorChanged();
        void verticesChanged();
    
    protected:
        QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *);
        QSGGeometryNode *drawBorder();
    
    protected:
        QColor          m_color;
        QList<qreal>    m_vertices;
    };
    
    #endif // TESTOPENGL_H
    

    TestOpenGL.cpp:

    #include "TestOpenGL.h"
    
    #include <QtMath>
    #include <QSGNode>
    #include <QSGVertexColorMaterial>
    
    TestOpenGL::TestOpenGL(QQuickItem *parent)
        : QQuickItem(parent)
        , m_color(0, 0, 0, 0)
    {
        setFlag(ItemHasContents, true);
    }
    
    QColor TestOpenGL::color()
    {
        return m_color;
    }
    
    void TestOpenGL::setColor(const QColor &color)
    {
        m_color = color;
        update();
        emit colorChanged();
    }
    
    QList<qreal> &TestOpenGL::vertices()
    {
        return m_vertices;
    }
    
    void TestOpenGL::setVertices(const QList<qreal>& newVal)
    {
        m_vertices = newVal;
        update();
        emit verticesChanged();
    }
    
    QSGNode *TestOpenGL::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
    {
        QSGNode *pNode = 0;
    
        if (!oldNode) {
            pNode = drawBorder();
        }
        pNode->markDirty(QSGNode::DirtyGeometry);
    
        return pNode;
    }
    
    QSGGeometryNode *TestOpenGL::drawBorder()
    {
        QSGGeometryNode *ret = new QSGGeometryNode();
        QSGGeometry *geometry;
        QSGVertexColorMaterial *material = new QSGVertexColorMaterial;
        geometry = new QSGGeometry(QSGGeometry::defaultAttributes_ColoredPoint2D(), 0);
    
        ret->setMaterial(material);
        ret->setFlag(QSGNode::OwnsMaterial);
    
        ret->setGeometry(geometry);
    //    ret->setFlag(QSGNode::OwnsGeometry);
    
        geometry->setDrawingMode(GL_TRIANGLE_STRIP);
        int vertexStride = geometry->sizeOfVertex();
    
        int innerVertexCount = m_vertices.size() / 2;
        int vertexCount = innerVertexCount;
    //    int vertexCount = innerVertexCount * 3;
    //    int vertexCount = innerVertexCount * 6;
    
        int fillIndexCount = innerVertexCount;
        int indexCount = innerVertexCount;
    
        geometry->allocate(vertexCount, indexCount);
        QSGGeometry::ColoredPoint2D* vertices = geometry->vertexDataAsColoredPoint2D();
        memset(vertices, 0, vertexCount * vertexStride);
        quint16 *indices = geometry->indexDataAsUShort();
    
        for (int i = 0; i < fillIndexCount; ++i)
        {
            vertices[i].set(m_vertices[i * 2], m_vertices[i * 2 + 1], 255, 0, 0, 255);
            indices[i * 2] = i * 2;
            indices[i * 2 + 1] = i * 2 + 1;
        }
    
        return ret;
    }
    

    main.qml:

    import QtQuick 2.5
    import QtQuick.Window 2.2
    import TestModule 1.0
    
    Window {
        visible: true
        width: 640
        height: 480
        title: qsTr("Test OpenGL")
    
        MouseArea {
            anchors.fill: parent
            onClicked: {
                Qt.quit();
            }
        }
    
        TestOpenGL {
            anchors.fill: parent
            vertices: [
                0, 0
                , 0, 100
                , 50, 0
                , 50, 100       //working with int vertexCount = innerVertexCount. On exit no warning only "The program has unexpectedly finished." message
    //            , 100, 0        //working with int vertexCount = innerVertexCount but show warnings when application stopped
    //            , 100, 100      //working with int vertexCount = innerVertexCount but show warnings when application stopped
    //            , 150, 0        //working with int vertexCount = innerVertexCount * 3
    //            , 150, 100      //not working
            ]
        }
    }
    

    Problem here: I can't draw more than few triangles. And I can't understand where is an error. E.g. if use vertices property with 8 vertices - exceptrion occur in qlist.cpp (realloc_grow(int growth): 153):

    Debugging starts
    QML debugging is enabled. Only use this in a safe environment.
    Qt: gdb: -nograb added to command-line options.
    	 Use the -dograb option to enforce grabbing.
    QML Debugger: Waiting for connection on port 41807...
    *** Error in `/home/leon/Documents/progs/qt/test_apps/build-TestOpenGL-Manual_Qt_5_7_0_gcc_64-Debug/TestOpenGL': realloc(): invalid next size: 0x00007fffd011f670 ***
    ======= Backtrace: =========
    /lib/x86_64-linux-gnu/libc.so.6(+0x777e5)[0x7ffff5bce7e5]
    /lib/x86_64-linux-gnu/libc.so.6(+0x82a5a)[0x7ffff5bd9a5a]
    /lib/x86_64-linux-gnu/libc.so.6(realloc+0x179)[0x7ffff5bdac89]
    /home/leon/src/qt5/5.7.0/gcc_64/lib/libQt5Core.so.5(_ZN9QListData12realloc_growEi+0x8f)[0x7ffff6618c19]
    /home/leon/src/qt5/5.7.0/gcc_64/lib/libQt5Core.so.5(_ZN9QListData6appendEi+0xff)[0x7ffff6618da3]
    /home/leon/src/qt5/5.7.0/gcc_64/lib/libQt5Core.so.5(_ZN9QListData6appendEv+0x1d)[0x7ffff6618deb]
    /home/leon/src/qt5/5.7.0/gcc_64/lib/libQt5Quick.so.5(+0x24cc2a)[0x7ffff7a5dc2a]
    /home/leon/src/qt5/5.7.0/gcc_64/lib/libQt5Quick.so.5(+0x24e179)[0x7ffff7a5f179]
    /home/leon/src/qt5/5.7.0/gcc_64/lib/libQt5Quick.so.5(_ZN19QQuickWindowPrivate15updateDirtyNodeEP10QQuickItem+0x122e)[0x7ffff7a58d32]
    /home/leon/src/qt5/5.7.0/gcc_64/lib/libQt5Quick.so.5(_ZN19QQuickWindowPrivate16updateDirtyNodesEv+0x290)[0x7ffff7a57712]
    /home/leon/src/qt5/5.7.0/gcc_64/lib/libQt5Quick.so.5(_ZN19QQuickWindowPrivate14syncSceneGraphEv+0x143)[0x7ffff7a4a93f]
    /home/leon/src/qt5/5.7.0/gcc_64/lib/libQt5Quick.so.5(+0x1fafaf)[0x7ffff7a0bfaf]
    /home/leon/src/qt5/5.7.0/gcc_64/lib/libQt5Quick.so.5(+0x1fb4a7)[0x7ffff7a0c4a7]
    /home/leon/src/qt5/5.7.0/gcc_64/lib/libQt5Quick.so.5(+0x1fc197)[0x7ffff7a0d197]
    /home/leon/src/qt5/5.7.0/gcc_64/lib/libQt5Core.so.5(+0xc61fa)[0x7ffff657e1fa]
    /lib/x86_64-linux-gnu/libpthread.so.0(+0x76ba)[0x7ffff54596ba]
    /lib/x86_64-linux-gnu/libc.so.6(clone+0x6d)[0x7ffff5c5d82d]
    .
    .
    .
    

    Please help me
    My platform: Ubuntu 16.04 64bit, Qt 5.7.0.
    On my Windows 10 application works only with FTH enabled. I got message: FTH: *** Fault tolerant heap shim applied to current process. This is usually due to previous crashes. *** So I conclude that problem presented on Windows 10 too.



  • I found a reason. Wrong is 2 lines from TestOpenGL.cpp file, need replace them with only one line:

            indices[i] = i;
    //        indices[i * 2] = i * 2;
    //        indices[i * 2 + 1] = i * 2 + 1;
    


Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.