我正在尝试在执行计算着色器后从着色器存储缓冲区对象读回数据,一个简单的浮点数组。我需要将这些数据放入运行osg库的应用程序代码中。在osgssbo示例之后,我设置了着色器存储缓冲区对象回调,但是当我读取数据时,数组元素的初始值不变。 Ssbo和着色器看起来很好并且正确执行。 感谢
这是我的基本代码:
#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;
}
琐碎的着色器代码是:
#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;
}
回调函数写的输出是:
1.2 1.2 1.2 1.2
当我希望看到:
348 1.2 23 1.2
答案 0 :(得分:0)
您可以使用osg GLExtensions
来读取缓冲区数据,您可以阅读AtomicCounterBufferBinding::readData
函数以供参考。