OpenGL 计算着色器 SSBO
OpenGL Compute Shader SSBO
我想要一个在输出缓冲区中写入 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;
编辑:谢谢 Andon M. Coleman。
我从一个只写缓冲区读取。这是固定的行:
ptr = (GLfloat *) glMapBuffer(GL_SHADER_STORAGE_BUFFER, GL_READ_ONLY);
glBufferData 复制 initPos 的内容到 SSBO 中。然后着色器在缓冲区上运行,而不是在 cpu 内存阵列上运行。除非你将缓冲区从 GPU 读回 CPU 某处的内存,否则 initPos 永远不会改变。
我想要一个在输出缓冲区中写入 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;
编辑:谢谢 Andon M. Coleman。
我从一个只写缓冲区读取。这是固定的行:
ptr = (GLfloat *) glMapBuffer(GL_SHADER_STORAGE_BUFFER, GL_READ_ONLY);
glBufferData 复制 initPos 的内容到 SSBO 中。然后着色器在缓冲区上运行,而不是在 cpu 内存阵列上运行。除非你将缓冲区从 GPU 读回 CPU 某处的内存,否则 initPos 永远不会改变。