Я пробую свои силы в буферных объектах шейдерного хранилища (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 о размерах / смещениях для того, что я пытаюсь сделать, я думаю, я мог бы вычислить их вручную (как бы это было громоздко), но я также был бы признателен за помощь.
Задача ещё не решена.
Других решений пока нет …