Я использую объект буфера вершин (VBO) в OpenGL ES 2.0.
У меня есть набор данных вершин, которые постоянно хранятся в обычном ОЗУ. Причина в том, что вычисление позиций вершин с нуля является дорогостоящим, но дельта может быть добавлена к последней позиции, чтобы дешево ее обновить.
Фактическое количество отображаемых вершин быстро меняется со временем. В одном кадре у меня может быть 1000, а в следующем 2500. Следуя совету, полученному здесь ранее, я теперь задаю целое число UPPER
в качестве верхней границы для числа вершин, которые когда-либо будут нарисованы. Я malloc
мои массивы данных вершин и индексов только один раз при запуске на основе этого значения.
Я передаю подсказку GL_STREAM_DRAW
на каждый вызов glBindBuffer
, чтобы указать, что данные меняются в каждом кадре.
Пытаясь быть максимально эффективным, я создал следующую настройку:
// SETUP: Called only once.
glBindBuffer(GL_ARRAY_BUFFER,...);
glBufferData(GL_ARRAY_BUFFER,...); // Pass vertex data for UPPER vertices.
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,...);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,...); // Pass index values 0 - (UPPER-1).
glEnableVertexAttribArray(...); // Setup vertex attributes.
glVertexAttribPointer(...);
glUseProgram(...); // Use program with custom shaders.
glUniformMatrix4fv(...); // Identify shader uniforms.
// UPDATE: Called when vertex data changes (on each frame).
glBindBuffer(GL_ARRAY_BUFFER,...);
glBufferSubData(GL_ARRAY_BUFFER,...); // Update VBO data.
// RENDER: Called on each frame.
glDrawElements(GL_TRIANGLES, numberOfVerticesThisFrame, ...); // Number of vertices and indices to be used is inherently specified in here.
Однако это нарушается с EXC_BAD_ACCESS
на glDrawElements
, и я знаю, что это из-за моего порядка команд gl
.
У меня ранее была похожая настройка, которая работала:
// UPDATE: Called when vertex data changes (on each frame).
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,...);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,...); // Pass index values 0 - (actual number of vertices to draw - 1)
// RENDER: Called on each frame.
glBindBuffer(GL_ARRAY_BUFFER,...);
glBufferData(GL_ARRAY_BUFFER,...); // Pass vertex data for actual number of vertices (not UPPER).
glEnableVertexAttribArray(...); // Setup vertex attributes.
glVertexAttribPointer(...);
glUseProgram(...); // Use program with custom shaders.
glUniformMatrix4fv(...); // Identify shader uniforms.
glDrawElements(GL_TRIANGLES, numberOfVerticesThisFrame, ...);
Однако эта настройка требует гораздо больше работы для каждого кадра, и, как вы можете видеть, включает в себя изменение размеров VBO (так как он использует фактический размер, а не UPPER
), что, как мне сказали, является большой потерей производительности. 1025 *
Может, кто-нибудь объяснит мне какие-либо очевидные проблемы с моей новой установкой и, что наиболее важно, какие команды мне приходится вызывать каждый кадр до glDrawElements
? Мое предположение, что я могу подготовить все возможные индексы заранее и затем передать фактическое число вершин в glDrawElements
, явно неверно.