0
votes

I have a compute shader operating on my buffer in my QML (5.8) app, the problem is that I cannot seem to read this buffer, only write to it.

My buffer is a Qt3DRender::QBuffer, I set its contents with

Qt3DRender::QBuffer::setData(QByteArray::fromRawData(reinterpret_cast<const char*>(points_.linearize()), static_cast<int>(sizeof(PointType) * pc)));

where pc is the number of points.

To use it, I created a QGeometry which sets up QAttributes, and apply the computer shader as a material component to the Entity

My material:

Material {
    property PointBuffer dataBuffer;

    ShaderProgram {
        id: computeShader
        computeShaderCode:  loadSource("qrc:/shaders/pointcloud.comp")
    }

    effect: Effect {
        techniques: [
            Technique {
                renderPasses: [
                    RenderPass {
                        shaderProgram: computeShader
                        parameters: [
                            // Point buffer
                            Parameter { name: "Particles"; value: dataBuffer }
                        ]
                    }
                ] // renderpasses
                filterKeys: [
                    FilterKey { name: "type"; value: "compute" }
                ]
                graphicsApiFilter {
                    api: GraphicsApiFilter.OpenGL
                    profile: GraphicsApiFilter.CoreProfile
                    majorVersion: 4
                    minorVersion: 3
                }
            } // technique
        ] // techniques
    }
}

In my buffer code though, whenever I read from the buffer (Qt3DRender::buffer::data()), I only get the data I wrote to it, not the result of the compute shader.

I've tried setting the usage to various things, but no dice.

In my OpenGL book, I see that one can glMapBuffer to have read/write access, and there's even a QOpenGLBuffer that has an ENUM to set the access in a similar way, but I can't seem to make use of either of these; i.e. I can't find a way to map my buffer, and the QOpenGLBuffer doesn't seem compatible with any of the renderers.

1
Though I haven't been able to get this working I received an answer on the Qt Interest mailing list that states in Qt 5.9, there will be a BufferCapture component that is able to read in an OpenGL buffer. I however found a different way (using a scene graph similar to the Squickle example) to get direct access to my OpenGL buffer - Matt

1 Answers

0
votes

I think the solution is to use BufferCapture, a feature added in 5.9 (who's alpha was only released this month.)

I haven't been able to try this solution yet, and will update this answer when I do.

There is an example of this in qt5/qt3d/tests/manual/buffercapture-qml

Info Source: Qt Interest Mailing List

For a pre-5.9 solution, I re-wrote everything to be similar to the Squircle SceneGraph example, where I use "raw" OpenGL calls to draw what I need. One huge advantage of this is that since I can append to an QOpenGLBuffer, I don't even need to read the buffer anymore.