Кажется, что вы в основном там, но есть несколько вещей, на которые стоит обратить внимание.
Согласна ли компоновка в обеих программах?
макет (std140, связывание = 1) буферной сетки
Вы должны быть осторожны с этим макетом. std140 будет округлять выравнивания до vec4, поэтому больше не будет совпадать с данными, которые вы предоставляете из кода C. В этом случае у вас должен работать std430.
Должен ли я также связать SSBO со второй программой вне цикла рендеринга? По-другому, чем первая привязка?
После того, как вы один раз связали SSBO, предполагая, что обе программы используют одну и ту же точку привязки (в вашем примере это так), тогда у вас все будет хорошо. Обмен данными между программами в порядке, но требуется синхронизация. Вы можете применить это с помощью барьера памяти.
Вы не упоминаете VAO, но вы сможете использовать SSBO только после того, как привязали VAO (а не по умолчанию).
Я думаю, это лучше всего объяснить на примере.
Вершинный шейдер для первой программы. Он использует данные буфера для своих координат позиции и текстуры, а затем переворачивает позиции в Y.
layout(std430, binding = 1) buffer mesh {
vec4 points[3];
vec2 texs[3];
} mesh_data;
out highp vec2 coords;
void main() {
coords = mesh_data.texs[gl_VertexID];
gl_Position = mesh_data.points[gl_VertexID];
mesh_data.points[gl_VertexID] = vec4(gl_Position.x, -gl_Position.y, gl_Position.zw);
}
Проверенный шейдер для второй программы. Он просто использует данные, но не изменяет их.
layout(std430, binding = 1) buffer mesh {
vec4 points[3];
vec2 texs[3];
} mesh_data;
out highp vec2 coords;
void main() {
coords = mesh_data.texs[gl_VertexID];
gl_Position = mesh_data.points[gl_VertexID];
}
В приложении необходимо связать VAO.
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
Затем настройте SSBO.
float const data[] = {
-0.5f, -0.5f, 0.0f, 1.0,
0.0f, 0.5f, 0.0f, 1.0,
0.5f, -0.5f, 0.0f, 1.0,
0.0f, 0.0f,
0.5f, 1.0f,
1.0f, 0.0f
};
glGenBuffers(1, &ssbo);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo);
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(data), data, GL_DYNAMIC_COPY);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, ssbo);
Выполните вызовы на ничью, используя первую программу.
glUseProgram(first_program);
glDrawArrays(GL_TRIANGLES, 0, 3);
Вставьте барьер памяти, чтобы обеспечить завершение записи из предыдущего вызова отрисовки, прежде чем следующий вызов отрисовки попытается прочитать из буфера.
glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
Сделайте вызовы отрисовки с помощью второй программы.
glUseProgram(second_program);
glDrawArrays(GL_TRIANGLES, 0, 3);
Надеюсь, это прояснит ситуацию! Дайте мне знать, если у вас есть дополнительные вопросы.