I'm trying to read back data, a simple float array, from a shader storage buffer object after execution of a compute shader. I need this data into my application code running osg library. Following the osgssbo example I setup a shader storage buffer object callback but when I read data in it array elements appear at their initial value unchanged. Ssbo and shader seems linked well and correctly executed. Thanks
Here is my basic code:
#include <osgViewer/Viewer>
#include <osg/BufferIndexBinding>
#include <osgGA/TrackballManipulator>
#include <osg/GLExtensions>
using namespace osg;
class ShaderStorageBufferCBK : public osg::StateAttributeCallback
{
public:
void operator() (osg::StateAttribute* attr, osg::NodeVisitor* nv)
{
//if you need to process the data in your app-code , better leaving it on GPU and processing there, uploading per frame will make it slow
osg::ShaderStorageBufferBinding* ssbb = static_cast<osg::ShaderStorageBufferBinding*>(attr);
osg::ShaderStorageBufferObject* ssbo
= static_cast<osg::ShaderStorageBufferObject*>(ssbb->getBufferObject());
osg::FloatArray* array = static_cast<osg::FloatArray*>(ssbo->getBufferData(0));
for (int i = 0; i < array->size(); ++i){
osg::notify(INFO) << array->at(i) << " ";
}
osg::notify(INFO) << std::endl;
}
};
int mymain(){
FloatArray * dati = new FloatArray;
dati->push_back(1.2);
dati->push_back(1.2);
dati->push_back(1.2);
dati->push_back(1.2);
ShaderStorageBufferObject *ssbo = new osg::ShaderStorageBufferObject;
dati->setBufferObject(ssbo);
ShaderStorageBufferBinding * ssbb = new ShaderStorageBufferBinding(0, ssbo, 0, dati->size() * sizeof(GLfloat));
ssbb->setUpdateCallback(new ShaderStorageBufferCBK);
Shader * shader = new osg::Shader(osg::Shader::COMPUTE);
shader->loadShaderSourceFromFile("shaders/lightpixels.cs");
osg::ref_ptr<osg::Program> computeProg = new osg::Program;
computeProg->setComputeGroups(1, 1, 1);
shader->setType(Shader::COMPUTE);
computeProg->addShader(shader);
osg::Geometry * geom = createTexturedQuadGeometry(Vec3(-0.5, 0, -0.5), Vec3(1.0, 0, 0.0), Vec3(0, 0, 1.0));
geom->getOrCreateStateSet()->setAttributeAndModes(computeProg);
geom->getOrCreateStateSet()->setAttributeAndModes(ssbb, osg::StateAttribute::ON);
osgViewer::Viewer viewer;
viewer.setSceneData(geom);
viewer.setUpViewInWindow(100, 100, 640, 480);
viewer.realize();
viewer.setCameraManipulator(new osgGA::TrackballManipulator());
while (!viewer.done())
{
viewer.frame();
}
return 0;
}
And the trivial shader code is:
#version 430
layout (local_size_x = 1) in;
layout(std430, binding = 0) buffer destBuffer
{
float data[];
};
void main() {
data[0] = 348.0;
data[2] = 23.0;
}
Output written by callback function is:
1.2 1.2 1.2 1.2
when i expect to see:
348 1.2 23 1.2