Я относительно хорошо знаком с рисованием экземпляров и данными по каждому экземпляру: я реализовал это в прошлом с успехом.
Сейчас я выполняю рефакторинг некоторого старого кода и ввел ошибку в том, как данные каждого экземпляра передаются в шейдеры.
Соответствующие биты следующие:
У меня есть VBO, хранящий трансформации мира моих объектов. Я использовал AMD CodeXL для отладки: буфер правильно заполнен данными и привязан при рисовании кадра.
glBindBuffer (GL_ARRAY_BUFFER, batch.mTransformBuffer);
glBufferData (GL_ARRAY_BUFFER, sizeof (glm :: mat4) * OBJ_NUM, &xforms, GL_DYNAMIC_DRAW);
Шейдер явно указывает местоположение ввода:
#version 450
layout(location = 0) in vec3 vertexPos;
layout(location = 1) in vec4 vertexCol;
//...
layout(location = 6)uniform mat4 ViewProj;
layout(location = 10)uniform mat4 Model;
ViewProj
Матрица одинакова для всех экземпляров и установлена правильно, используя:
glUniformMatrix4fv(6, 1, GL_FALSE, &viewProjMat[0][0]);
Model
для каждой матрицы мира это неправильно: содержит все нули.
После привязки буфера и перед рисованием каждого кадра я пытаюсь настроить указатели и делители атрибутов таким образом, чтобы каждый нарисованный экземпляр получал свое преобразование:
for (size_t i = 0; i < 4; ++i)
{
glEnableVertexAttribArray(10 + i);
glVertexAttribPointer(10 + i, 4, GL_FLOAT, GL_FALSE,
sizeof(GLfloat) * 16,
(const GLvoid*) (sizeof(GLfloat) * 4 * i));
glVertexAttribDivisor(10 + i, 1);
}
Теперь я посмотрел и код некоторое время, и я действительно не могу понять, что мне не хватает. CodeXL ясно показывает, что Модель (местоположение 10) заполнена неправильно. Ошибка OpenGL не генерируется.
Мой вопрос: кто-нибудь знает, при каких обстоятельствах настройка данных для каждого экземпляра может молча провалиться? Или есть какие-либо предложения по дальнейшей отладке этого вопроса?
layout(location = 6)uniform mat4 ViewProj; layout(location = 10)uniform mat4 Model;
Это униформа, а не входные значения. Они не питаются атрибутами; их кормят glUniform*
звонки. Если ты хочешь Model
чтобы быть входным значением, а затем квалифицировать его с in
не uniform
,
Не менее важно, что входные данные и униформа не имеют одинакового местоположения. Я имею в виду, что однородные местоположения имеют пространство, отличное от входных. Вход может иметь тот же индекс местоположения, что и униформа, и он не будет ссылаться на одно и то же. Места ввода относятся только к индексам атрибутов; единообразные местоположения относятся к однородным местоположениям.
Наконец, единообразные местоположения не работают как входные местоположения. С атрибутами, каждый vec4
-эквивалент использует отдельный индекс атрибута. При одинаковом расположении каждый базовый тип (все, что не является структурой или массивом) использует одно и то же местоположение. Так что если ViewProj
является однородным местоположением, тогда оно занимает только 1 местоположение. Но если Model
является входом, то он занимает 4 индекса атрибута.
Других решений пока нет …