2015-08-19 5 views
4

Мне нужен вычислительный шейдер, который записывает 1 в выходной буфер. Я скомпилирую шейдер и присоединяю его к программе без проблем, затем вызываю функцию glDispatchCompute() и жду, пока закончится вычисление шейдера. Но когда я вижу массив, есть только 0.OpenGL Compute Shader SSBO

Может ли кто-нибудь сказать мне, где ошибка?

Это мой Compute Shader код:

#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; 

EDIT: Наконец он работает. Спасибо, 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; 

EDIT: Спасибо заградительных М. Коулмана.

Я прочитал только буфер записи. Вот строка фиксированной:

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

Держите ... здесь что-то серьезно. Вы не отображаете память как *** только запись ***, а затем поворачиваетесь и ничего не делаете, кроме *** читаете *** эту память. Вам необходимо исправить это как можно скорее. Вы должны отображать его «GL_READ_ONLY'; вы читаете из неопределенной памяти. –

ответ

5

glBufferData копии содержание initPos в SSBO. Затем шейдер работает на буфере, а не на массиве памяти процессора. Если вы не прочтете буфер обратно с GPU на память процессора, initPos никогда не изменится.

Смежные вопросы