Я пытаюсь ускорить свой код OpenGL с помощью прямого доступа к состоянию и внимательно следил за кодом из Руководства по современным функциям OpenGL . У меня есть небольшой тестовый проект с некоторыми вершинами и цветами в виде:
std::vector<float> vertices;
for (float y = -1.0f; y < 1.1f; y += 1.0f) {
for (float x = -1.0f; x < 1.1f; x += 1.0f) {
vertices.emplace_back(x);
vertices.emplace_back(y);
vertices.emplace_back(0.5f);
vertices.emplace_back(0.5f);
vertices.emplace_back(0.5f);
}
}
Визуальное представление этих вершин и их индексов:
Мой основной код отрисовки примерно такой:
unsigned int vbo = 0;
glCreateBuffers(1, &vbo);
glNamedBufferStorage(vbo, sizeof(float) * vertices.size(), vertices.data(), GL_DYNAMIC_STORAGE_BIT);
// Indices
unsigned int indices[]{ 0,1,3,5,8,7 };
unsigned int ibo = 0;
glCreateBuffers(1, &ibo);
glNamedBufferStorage(ibo, sizeof(unsigned int) * 6, indices, GL_DYNAMIC_STORAGE_BIT);
int bindingindex_a = 1;
int bindingindex_b = 2;
int pos_location = 3;
int color_location = 4;
unsigned int vao = 0;
glCreateVertexArrays(1, &vao);
glVertexArrayVertexBuffer(vao, bindingindex_a, vbo, 0, 5 * sizeof(float));
glVertexArrayVertexBuffer(vao, bindingindex_b, vbo, 0, 5 * sizeof(float));
glVertexArrayElementBuffer(vao, ibo);
glEnableVertexArrayAttrib(vao, pos_location);
glEnableVertexArrayAttrib(vao, color_location);
glVertexArrayAttribFormat(vao, pos_location, 2, GL_FLOAT, GL_FALSE, 0);
glVertexArrayAttribFormat(vao, color_location, 3, GL_FLOAT, GL_FALSE, 2*sizeof(float));
glVertexArrayAttribBinding(vao, pos_location, bindingindex_a);
glVertexArrayAttribBinding(vao, color_location, bindingindex_b);
Итак, я рисую два серых треугольника с индексами 0,1,3 и 5,8,7. Расположение атрибутов в моем шейдере указано в коде cpp:
layout (location = 3) in vec2 pos;
layout (location = 4) in vec3 col;
И это работает!:
Даже когда я увеличиваю сложность и добавляю одно значение с плавающей запятой впереди, я могу отрегулировать смещение в функции glVertexArrayVertexBuffer()
на 4 байта.
Проблема в том, когда я хочу go из макета буфера A в B:
Я настраиваю заполнение данными l oop, чтобы сначала записать позиции, а затем цвета:
for (float y = -1.0f; y < 1.1f; y += 1.0f) {
for (float x = -1.0f; x < 1.1f; x += 1.0f) {
vertices.emplace_back(x);
vertices.emplace_back(y);
}
}
for (float y = -1.0f; y < 1.1f; y += 1.0f) {
for (float x = -1.0f; x < 1.1f; x += 1.0f) {
vertices.emplace_back(0.5f);
vertices.emplace_back(0.5f);
vertices.emplace_back(0.5f);
}
}
и настройте вызовы на glVertexArrayVertexBuffer()
и glVertexArrayAttribFormat()
:
glVertexArrayVertexBuffer(vao, bindingindex_a, vbo, 0, 2 * sizeof(float));
glVertexArrayVertexBuffer(vao, bindingindex_b, vbo, 18*sizeof(float), 3 * sizeof(float));
glVertexArrayAttribFormat(vao, pos_location, 2, GL_FLOAT, GL_FALSE, 0);
glVertexArrayAttribFormat(vao, color_location, 3, GL_FLOAT, GL_FALSE, 0);
Итак, теперь мое глобальное смещение цвета составляет 18 значений с плавающей запятой (9 позиций, умноженных на два компонента), а мое relativeoffset
(вот как khronos.org называет это) 0 для обоих. Это отображает серые вещи, но не так, как раньше. Моя ментальная модель того, как эти вещи работают, явно неверна - где?