OpenGL计算着色器SSBO

5
我希望您能够提供一个计算着色器,用于在输出缓冲区中写入1。我编译了着色器并将其附加到程序上,没有出现任何问题,然后我调用glDispatchCompute()函数,并等待计算着色器结束。但是当我查看数组时,只有0。
请问有谁能告诉我错在哪里?
这是我的计算着色器代码:
#version 430 core

layout  (local_size_x  =  2)  in;

layout(std430, binding=0) writeonly buffer Pos{
    float Position[];
};

void main(){
    Position[gl_GlobalInvocationID.x] = 1.0f;
}

以下是我的主要内容:

GLuint program_compute = 0, SSBO = 0;

//...(Create, compile and link the program with the shader)...

vector<GLfloat> initPos;
int num_numeros = 12;

for (int i = 0; i < num_numeros; i++){
    initPos.push_back(0.0f);
}

glUseProgram(program_compute);

glGenBuffers(1, &SSBO);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, SSBO);
glBufferData(GL_SHADER_STORAGE_BUFFER, num_numeros * sizeof(GLfloat), &initPos, GL_DYNAMIC_DRAW);

glDispatchCompute(num_numeros/2, 1, 1);
glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, 0);

for (int i = 0; i < num_numeros; i++){
    cout << "p" << i << ": " << initPos[i] <<  endl;
}
cout << endl;

编辑:最终它可以工作了。谢谢BDL。

正如BDL所说,我忘记了从GPU内存中读回缓冲区。现在它可以工作了。这是新代码:

GLuint program_compute = 0, SSBO = 0;

// ...The same code as above

glDispatchCompute(num_numeros/2, 1, 1);
glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, 0);

glBindBuffer(GL_SHADER_STORAGE_BUFFER, SSBO);

GLfloat *ptr;
ptr = (GLfloat *) glMapBuffer(GL_SHADER_STORAGE_BUFFER, GL_WRITE_ONLY);
initPos.clear();

for (int i = 0; i < num_numeros; i++){
    initPos.push_back(ptr[i]);
}

glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);

for (int i = 0; i < num_numeros; i++){
    cout << "p" << i << ": " << initPos[i] <<  endl;
}
cout << endl;

编辑:感谢安东·M·科尔曼。

我从只写缓冲区中读取。以下是已修复的行:

ptr = (GLfloat *) glMapBuffer(GL_SHADER_STORAGE_BUFFER, GL_READ_ONLY);

1
等一下...这里有严重的问题。你不能将内存映射为“只写”,然后又仅仅从中“读取”数据。你需要立即修复这个问题。你应该将其映射为GL_READ_ONLY,否则你就是在从未定义的内存中读取数据。 - Andon M. Coleman
1个回答

7

glBufferData将initPos的内容复制到SSBO中。然后着色器在缓冲区上操作,而不是在CPU内存数组上操作。除非在某个地方将缓冲区从GPU读回到CPU内存中,否则initPos将永远不会改变。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接