Быстро нарисуйте много одного и того же объекта в OpenGL - PullRequest
13 голосов
/ 19 февраля 2012

Итак, я работаю над игрой, и мне нужно нарисовать много одного и того же объекта.Та же форма, тот же размер, тот же цвет, только разные места.

Сейчас моя установка такая:

У меня есть некоторый класс 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, если вышеизложенное смущает, извините.

Как я могу улучшить это, чтобы учесть как многоугольники?

Ответы [ 2 ]

21 голосов
/ 19 февраля 2012

На современном оборудовании instancing - путь.

Идея состоит в том, что вы отправляете геометрию в свой графический процессор один раз (один вызов рисования), указывая, сколько экземпляров вы хотите нарисовать (primCount параметр).

Затем в вершинном шейдере вы можете использовать внутреннюю входную переменную gl_InstanceID, чтобы узнать, какой экземпляр рендерится, а затем использовать соответствующее преобразование для него. Этот подход подразумевает, что у вас должны быть преобразования для всех ваших экземпляров, доступных в вершинном шейдере, например в объекте равномерного буфера .

Редактировать: glVertexAttribDivisor функция очень полезна вместе с экземплярами; в основном это позволяет иметь некоторые атрибуты для каждой вершины вместе с некоторыми атрибутами для каждого экземпляра.

1 голос
/ 19 февраля 2012

В OpenGL есть красивая вещь, которая называется Показать список .На NeHe Production есть учебник , в котором должна быть вся необходимая информация и примеры.Но в основном:

GLuint displayList; // This should be class attribute
displayList = glGenLists(1);    
glNewList(displayList,GL_COMPILE);
Renderer::draw();
glEndList();

А в режиме реального рисования просто:

glCallList( displayList);

Не забывайте актуализировать предварительно скомпилированный список отображения каждый раз, когда вы добавляете / удаляете что-то.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...