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...@qt-project.org] On Behalf 
Of Esch Lorenz TU Ilmenau
Sent: Tuesday, January 16, 2018 6:29 PM
To: interest@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

 

_______________________________________________
Interest mailing list
Interest@qt-project.org
http://lists.qt-project.org/mailman/listinfo/interest

Reply via email to