Я написал простой графический движок с использованием OpenGL и GLSL. До этого момента, когда мне нужно было создать новый узел сцены сетки, я создал VAO, VBO и IBO для каждой сетки. Я загрузил атрибуты вершин для каждого меша следующим образом:
glBufferData(GL_ARRAY_BUFFER, this->GetVerticesByteSize(VERTEX_POSITION)
+ this->GetVerticesByteSize(VERTEX_TEXTURE) + this->GetVerticesByteSize(VERTEX_NORMAL), NULL, this->m_Usage);
glBufferSubData(GL_ARRAY_BUFFER, 0, this->GetVerticesByteSize(VERTEX_POSITION), &this->m_VertexBuffer[VERTEX_POSITION][0]);
if (!this->m_VertexBuffer[VERTEX_TEXTURE].empty())
glBufferSubData(GL_ARRAY_BUFFER, this->GetVerticesByteSize(VERTEX_POSITION),
this->GetVerticesByteSize(VERTEX_TEXTURE), &this->m_VertexBuffer[VERTEX_TEXTURE][0]);
if (!this->m_VertexBuffer[VERTEX_NORMAL].empty())
glBufferSubData(GL_ARRAY_BUFFER, this->GetVerticesByteSize(
VERTEX_POSITION) + this->GetVerticesByteSize(VERTEX_TEXTURE),
this->GetVerticesByteSize(VERTEX_NORMAL), &this->m_VertexBuffer[VERTEX_NORMAL][0]);
Но если сцена состоит из большого количества мешей, это неверно для производительности (слишком много изменений состояния). Итак, я решил создать уникальные VAO, VBO и IBO (одноэлементные классы) для всей геометрии моей сцены.
Это можно сделать следующим образом:
Загрузите все атрибуты вершин в определенный класс (назовем его «VertexAttributes») для каждой сетки. После того, как все сетки загружены, мы можем разместить большой буфер вершин в уникальном VBO. Как и выше, я сначала вызываю функцию glBufferData, чтобы выделить всю память с размером всех атрибутов вершины в моей сцене, а затем вызываю функцию glBufferSubData для каждого типа атрибута вершины в цикле.
Но можно ли вызвать glBufferData несколько раз (для каждой сетки) и заполнить VBO во время загрузки сцены (шаг за шагом для каждой сетки). Так это похоже на перераспределение. Можно ли сделать это с помощью OpenGL, или мой первый метод подойдет?
realloc (...)
. В OpenGL нет такой функции, вы можете легко выделить новое хранилище для буферного объекта (и освободить предыдущее хранилище, если в конвейере нет ожидающей команды, которая ссылается на него), но это новое хранилище будет иметь неопределенное содержимое. - person Andon M. Coleman   schedule 18.05.2014