Нарисуйте много одного и того же объекта в OpenGL
Итак, я работаю над игрой, и мне нужно рисовать много одного и того же объекта. Такая же форма, того же размера, того же цвета, только в разных местах.
Прямо сейчас моя настройка такая.
У меня есть класс Renderer
, где объект, который хочет рисовать на экране, может вызвать static void addVertex(float x, float y, float z);
, который сохранит вершину в std::vector
. Когда все делается, вызывается static void draw();
в Renderer
, где все набивается в VBO и нарисовано на экране.
рисунок выглядит следующим образом:
void Renderer::draw() {
glBindBufferARB(GL_ARRAY_BUFFER_ARB, _quadID);
glBufferSubDataARB(GL_QUADS, 0, _vertexBuffer.dataSize(), _vertexBuffer.toArray());
glColorPointer(4, GL_FLOAT, 0, _colorBuffer.toArray());
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, _vertexBuffer.toArray());
glDrawArrays(GL_QUADS, 0, (_vertexBuffer.size() / 3));
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
_vertexBuffer.clear();
_colorBuffer.clear();
}
Где _vertexBuffer
и _colorBuffer
имеют класс template <class T> Buffer
, который является более или менее управляемым std::vector<T>
для моих целей.
С помощью этой настройки я могу получить около 300 вещей на экране, прежде чем я начну замедляться. Сейчас все это GL_QUAD. Имейте в виду, я немного новичок в OpenGL, если выше неловко, извините.
Как я могу улучшить это, чтобы учитывать как многоугольники?
Ответы
Ответ 1
На современном оборудовании instancing - это путь.
Идея состоит в том, что вы отправляете геометрию на свой GPU один раз (один вызов вызова), указав, сколько экземпляров вы хотите нарисовать (параметр primCount
).
Затем в вершинном шейдере вы можете использовать внутреннюю входную переменную gl_InstanceID
, чтобы узнать, какой экземпляр визуализируется, а затем использовать для нее соответствующее преобразование. Этот подход подразумевает, что вы должны иметь преобразования для всех ваших экземпляров, доступных в вершинном шейдере, например, в Uniform Buffer Object.
Изменить: функция glVertexAttribDivisor
очень полезна вместе с instancing; он в основном позволяет иметь некоторые атрибуты per-vertex вместе с некоторыми атрибутами каждого экземпляра.
Ответ 2
В OpenGL есть красивая вещь, называемая Показать список. Производство NeHe tutorial на них должно содержать всю необходимую информацию и примеры. Но в основном:
GLuint displayList; // This should be class attribute
displayList = glGenLists(1);
glNewList(displayList,GL_COMPILE);
Renderer::draw();
glEndList();
И в реальном методе рисования просто:
glCallList( displayList);
Не забудьте активировать предварительно скомпилированный список отображения при каждом добавлении/удалении.