OpenGL 4.5 — Расположение объектов буфера хранилища шейдеров

Я пробую свои силы в буферных объектах шейдерного хранилища (Buffer Blocks), и есть пара вещей, которые я до конца не понимаю. Я пытаюсь сохранить (упрощенные) данные неопределенного количества источников света. n в них, так что мой шейдер может перебирать их и выполнять вычисления.

Позвольте мне начать с того, что я получаю правильные результаты и никаких ошибок от OpenGL. Тем не менее, меня беспокоит не знать, почему это является за работой.

Итак, в моем шейдере я получил следующее:

struct PointLight {
vec3 pos;
float intensity;
};

layout (std430, binding = 0) buffer PointLights {
PointLight pointLights[];
};

void main() {
PointLight light;
for (int i = 0; i < pointLights.length(); i++) {
light = pointLights[i];
// etc
}
}

и в моем приложении:

struct PointLightData {
glm::vec3 pos;
float intensity;
};

class PointLight {
//  ...
PointLightData data;
// ...
};

std::vector<PointLight*> pointLights;

glGenBuffers(1, &BBO);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, BBO);
glNamedBufferStorage(BBO, n * sizeof(PointLightData), NULL, GL_DYNAMIC_STORAGE_BIT);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, BBO);

...

for (unsigned int i = 0; i < pointLights.size(); i++) {
glNamedBufferSubData(BBO, i * sizeof(PointLightData), sizeof(PointLightData), &(pointLights[i]->data));
}

В этом последнем цикле я храню PointLightData структура со смещением, равным его размеру, умноженному на количество их я уже сохранил (так смещение 0 для первого).

Итак, как я уже сказал, все кажется правильным. Точки привязки правильно установлены на ноль, у меня достаточно памяти для моих объектов и т. Д. Графические результаты в порядке.

Теперь к моим вопросам. я использую std430 как макет — на самом деле, если я изменю его на std140 как я изначально делал это ломается. Это почему? Моя гипотеза состоит в том, что макет, сгенерированный std430 для шейдеров PointLights буферный блок успешно совпадает с тем, что сгенерировано компилятором для моего приложения PointLightData struct (как вы можете видеть в этом цикле, я слепо храню один за другим). Вы думаете, что это так?

Теперь, предполагая, что я прав в этом предположении, очевидным решением было бы сделать сопоставление размеров и смещений самостоятельно, запросив opengl с помощью glGetUniformIndices а также glGetActiveUniformsiv (последний звонил с GL_UNIFORM_SIZE а также GL_UNIFORM_OFFSET), но у меня появилось подозрение, что эти два парня работают только с единообразными блоками, а не с буферными блоками, как я пытаюсь сделать. По крайней мере, когда я делаю следующее OpenGL бросает истерику, возвращает мне 1281 ошибка и возвращает очень странное число в качестве индексов (что-то вроде 3432898282 или что угодно)

const char * names[2] = {
"pos", "intensity"};

GLuint indices[2];
GLint size[2];
GLint offset[2];

glGetUniformIndices(shaderProgram->id, 2, names, indices);
glGetActiveUniformsiv(shaderProgram->id, 2, indices, GL_UNIFORM_SIZE, size);
glGetActiveUniformsiv(shaderProgram->id, 2, indices, GL_UNIFORM_OFFSET, offset);

Правильно ли я сказал, что glGetUniformIndices а также glGetActiveUniformsiv не применяются к буферным блокам?

Если они этого не делают, или тот факт, что он работает, как будто я представляю просто совпадение, как я могу сделать сопоставление вручную? Я проверил приложение H к руководству по программированию и формулировку массив структур несколько сбивает с толку. Если я не могу запросить OpenGL о размерах / смещениях для того, что я пытаюсь сделать, я думаю, я мог бы вычислить их вручную (как бы это было громоздко), но я также был бы признателен за помощь.

4

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]