Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Qt3D Qt3DRender:QBuffer update -> No Frame update ?



  • Hi guyz,

    I created a C++ class to provide vertices data to QML stored in a Qt3DRender::QBuffer.
    So the C++ is very basic. I have a qByteArray ready with many vertices.

    Header:
        Q_PROPERTY(Qt3DRender::QBuffer *buffer READ buffer WRITE setBuffer NOTIFY bufferChanged)
        Qt3DRender::QBuffer * m_pBuffer;
    Source:
        m_pBuffer = new Qt3DRender::QBuffer( nullptr);
        m_pBuffer->setData(qByteArray);
    

    I use the example QML that declares the Geometry as below:
    There is a binding with my C++ class property pointsCloud.buffer at the bottom.

    Geometry {
           id: idPointsCloudVertexGeometry
           Attribute {
               id: idPointsCloudAttribute
               attributeType: Attribute.VertexAttribute
               vertexBaseType: Attribute.Float
               vertexSize: 3
               byteOffset: 0
               // One float is four bytes, we have 3 coordinates for one vertex
               // Each vertex is close to the next one
               // So the stride is only 3 * 3 * 4
               byteStride:  3 * 3 * 4
               // the vertices count is the array length
               // divided by 3 coordinates for each vertexBaseType:
               count: pointsCloud.pointsCount
               // name found in the vertex shader
               name: "vertexPosition"
               buffer: pointsCloud.buffer
           }
       }
    

    This is working fine (well I have an issue with number of elements, I shall register a Qt Bug later maybe, but if the number is reasonnable, say 20000 vertices, this works fine and display a shape EDIT: I solved this by changing the stride value to 3 * 4 instead of 3 * 3 * 4!)
    Now I would like to update the data regularly and have a Frame refresh for the new data.
    For this I rely on the updateData method from Qt3DRender::QBuffer
    And I override data for the entire buffer, vertex per vertex with a local qByteArray of 3*4 bytes (x, y, and z as float)

    m_pBuffer->updateData(iCurrentVertex * 3  * sizeof(float), qByteArraySingle);
    

    But the problem is that I don't get any redraw of the frame, or at least nothing that I can see.
    So I added an

    emit bufferChanged();
    

    => It does not help.

    I even added a QML Connection in the QML part to make sure the buffer had changed. => it does not help

    QQ2.Connections {
            target: pointsCloud
            onBufferChanged: {
                console.log("buffer had changed")
                idPointsCloudAttribute.buffer = pointsCloud.buffer
            }
        }
    

    I even tried to set null to the buffer, and the frame is not refreshed, but I get an error message:

    calculateLocalBoundingVolume: Position attribute not referencing a valid buffer
    

    Does any one has any idea why the frame is not refreshed with the new data.
    I suspect a CPU/GPU wrong sync at some point, but I don't know how to work this out.
    Any help is welcome.
    Thank you,

    Bill



  • Hi guyz,

    I finally decided to copy data all the time, for each new data, and then the 3D Frame is refreshed correctly. I wish I knew a better option though.

    I will set this topic as solved.
    Thank you
    Bill




Log in to reply