[Interest] Qt3D: Correct way of using QBuffer and a compute shader

Michael Sué sue at sf.mpg.de
Wed Jan 17 10:56:24 CET 2018


Hi,

 

I use attributes, like positionAttributes (for the vertices) and normalAttributes (for the normal vectors). Attributes contain the buffer, datatype and size information. But I think this is not essential. The buffer for vertices and normal are usual one big array, used in two blocks: 

 

    m_positionAttribute=new Qt3DRender::QAttribute();

    m_normalAttribute=new Qt3DRender::QAttribute();

    m_vertexBuffer=new Qt3DRender::QBuffer(Qt3DRender::QBuffer::VertexBuffer,this);

    m_vertexBuffer->setUsage(Qt3DRender::QBuffer::StaticDraw);

 

    m_positionAttribute->setName(Qt3DRender::QAttribute::defaultPositionAttributeName());

    m_positionAttribute->setDataType(Qt3DRender::QAttribute::Float);

    m_positionAttribute->setDataSize(3);

    m_positionAttribute->setAttributeType(Qt3DRender::QAttribute::VertexAttribute);

    m_positionAttribute->setBuffer(m_vertexBuffer);

    m_positionAttribute->setByteStride(3 * sizeof(float));

 

    m_normalAttribute->setName(Qt3DRender::QAttribute::defaultNormalAttributeName());

    m_normalAttribute->setDataType(Qt3DRender::QAttribute::Float);

    m_normalAttribute->setDataSize(3);

    m_normalAttribute->setAttributeType(Qt3DRender::QAttribute::VertexAttribute);

    m_normalAttribute->setBuffer(m_vertexBuffer);

    m_normalAttribute->setByteStride(3 * sizeof(float));

 

    sizeChanged(m_iNumVertices);

 

void VGeometry::sizeChanged(const int iNumVertices)

{

    m_positionAttribute->setByteOffset(0);

    m_positionAttribute->setCount(iNumVertices);

    m_normalAttribute->setByteOffset(iNumVertices * 3 * sizeof(float));

    m_normalAttribute->setCount(iNumVertices);

 

    if (m_iNumVertices > 0) {

        addAttribute(m_positionAttribute);

        addAttribute(m_normalAttribute);

    }

}

 

What you should do during change, though, is to remove the attributes

    removeAttribute(m_normalAttribute);

    removeAttribute(m_positionAttribute);

change the buffer, vertices and normal contents, re-assign the buffer and change the size information and re- add the attributes again 

    sizeChanged(m_iNumVertices);

in some kind of updateVertices function.

 

Best, Michael.

 

From: Interest [mailto:interest-bounces+sue=sf.mpg.de at qt-project.org] On Behalf Of Esch Lorenz TU Ilmenau
Sent: Tuesday, January 16, 2018 6:29 PM
To: interest at qt-project.org
Subject: [Interest] Qt3D: Correct way of using QBuffer and a compute shader

 

Dear Qt Community,

 

I am writing my first application using a compute shader based on Qt3D in C++. My question: What is the correct way of updating the data needed by the compute shader during run-time? This is what I tried so far:

 

I created a QBuffer object (in form of a QPointer) and fill it with data. The pointer is kept as a member in a class. I set the buffer via .data() to a QVariant and set it as data to the corresponding QParameter. The following is a code snippet showing the basic idea:

 

QByteArray interpolationBufferData = buildInterpolationMatrixBuffer(matInterpolationMatrix); //Builds the data array from a large Eigen Matrix 

m_pInterpolationMatBuffer = new Qt3DRender::QBuffer(Qt3DRender::QBuffer::ShaderStorageBuffer);

m_pInterpolationMatBuffer->setData(interpolationBufferData);

m_pParameter ->setValue(QVariant::fromValue(m_pInterpolationMatBuffer.data()), QStringLiteral("InterpolationMat"));

m_pInterpolationMatBuffer->setData(interpolationBufferData);

 

Everything works fine until here. The visualization is doing what it is supposed to do and the compute shader works fine. After a new input matrix arrives I create a new QByteArray and try to load it to the QBuffer object via updateData (I also tried setData). Once I try to update the data in the QBuffer the application crashes.

 

QByteArray interpolationBufferData = buildInterpolationMatrixBuffer(matInterpolationMatrix); //Builds the data array from an incoming Eigen Matrix

m_pInterpolationMatBuffer->updateData(0, interpolationBufferData);

 

Am I missing something? Is there a better way to update data used by the compute shader? Should I pay attention to the usage type (StreamDraw, StaticDraw, etc.)? Also, is the complete QByteArray internally copied to the GPU when setting only the pointer to the QVariant? Maybe I should create a new buffer every time I receive new data? Questions over questions 😊 

 

Thanks,

 

Lorenz

 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.qt-project.org/pipermail/interest/attachments/20180117/988ada46/attachment.html>


More information about the Interest mailing list