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 anemit 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 -
I shared a sample demo here: https://github.com/billouparis/pointsCloud#readme