Я хочу переключаться между данными ssbo, чтобы рисовать вещи с разными настройками. Чтобы это произошло, мне нужно использовать glBindBufferRange()
с подходящим смещением.
Я читал, что смещение должно быть кратным GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT
для UBO, но с ssbo все может измениться, поскольку вместо std140 используется std430.
Я пытался сделать это самым простым способом
struct Color
{
float r, g, b, a;
};
struct V2
{
float x, y;
};
struct Uniform
{
Color c1;
Color c2;
V2 v2;
float r;
float f;
int t;
};
GLuint ssbo = 0;
std::vector<Uniform> uniform;
int main()
{
//create window, context etc.
glCreateBuffers(1, &ssbo);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo);
Uniform u;
u.c1 = {255, 0, 255, 255 };
u.c2 = {255, 0, 255, 255 };
u.v2 = { 0.0f, 0.0f };
u.r = 0.0f;
u.f = 100.0f;
u.t = 0;
uniform.push_back(u);
u.c1 = {255, 255, 0, 255 };
u.c2 = {255, 255, 0, 255 };
u.v2 = { 0.0f, 0.0f };
u.r = 100.0f;
u.f = 100.0f;
u.t = 1;
uniform.push_back(u);
u.c1 = {255, 0, 0, 255 };
u.c2 = {255, 0, 0, 255 };
u.v2 = { 0.0f, 0.0f };
u.r = 100.0f;
u.f = 0.0f;
u.t = 0;
uniform.push_back(u);
glNamedBufferData(ssbo, sizeof(Uniform) * uniform.size(), uniform.data(), GL_STREAM_DRAW);
for(int i = 0; i < uniform.size(); ++i) {
glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 1, ssbo, sizeof(Uniform) * i, sizeof(Uniform));
glDrawArrays(...);
}
//swap buffer etc.
return 0;
}
#version 460 core
layout(location = 0) out vec4 f_color;
layout(std430, binding = 1) buffer Unif
{
vec4 c1;
vec4 c2;
vec2 v2;
float r;
float f;
int t;
};
void main()
{
f_color = vec4(t, 0, 0, 1);
}
Конечно, есть vao, vbo, структура вершин и так далее, но они не влияют на ssbo.
Я получил GL_INVALID_VALUE
glBindBufferRange()
ошибку, хотя. И это должно исходить из смещения, потому что моя следующая попытка передает данные, но с неправильным порядком.
Моя следующая попытка была использовать GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT
и формула, которую я нашел в интернете
int align = 4;
glGetIntegerv(GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT, &align);
int ssboSize = sizeof(Uniform) + align - sizeof(Uniform) % align;
так что просто меняя glNamedBufferData
и glBindBufferRange
это выглядит так
glNamedBufferData(ssbo, ssboSize * uniform.size(), uniform.data(), GL_STREAM_DRAW);
glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 1, ssbo, ssboSize * i, sizeof(Uniform));
и таким образом, это почти сработало. Как видите, t
s
0;
1;
0;
так что opengl должен нарисовать 3 фигуры с цветами -
vec4(0, 0, 0, 1);
vec4(1, 0, 0, 1);
vec4(0, 0, 0, 1);
рисует их в неправильном порядке
vec4(1, 0, 0, 1);
vec4(0, 0, 0, 1);
vec4(0, 0, 0, 1);
Как я могу заставить его правильно передавать данные?