openGL - пакетный рендеринг - обновление матриц объектов и т. д. - PullRequest
0 голосов
/ 22 декабря 2018

Я пытаюсь обернуть голову вокруг некоторых опций рендеринга openGL.

Пока мой код sudo выглядит примерно так:

void paint() {
    ...
    for (auto &obj:objList) {
        obj.draw(matrix)
    }
}


void draw(matrix &m){
    shaderProgram->bind();
    meshVao->bind();
    meshVertex->bind();
    meshIndices->bind();
    shaderProgram->setUniformValue("mvp_matrix", m * getObjTrans());
    shaderProgram->setUniformValue("un_color", QVector4D(1, 1, 1, 1));
    shaderProgram->enableAttributeArray("position");
    shaderProgram->setAttributeBuffer("position", GL_FLOAT, 0, 3);
    glDrawElements(GL_TRIANGLES, mMeshData->mIndices.size(), GL_UNSIGNED_INT, 0);
}

Теперь это просто связывает каждый объект 1 на 1, устанавливает его матрицу и рисует его.Это довольно неэффективно, скажем, 5-20k + объектов.

Теперь я читал в последнее время, и, насколько я могу сказать, я мог также загрузить все данные объектов в 1-2 VBO при 1 VAO и затем нарисовать их всев 1 звонок.Поэтому, если я возьму все индексы в 1 вектор и все вершины в 1 вектор, я смогу связать только эти 2 объекта VBO и нарисовать все объекты за 1 вызов.Задача, которую я пытаюсь понять, состоит в том, как передать матрицу для каждого объекта в векторах?В вышеприведенной функции я передаю матрицу каждому объекту перед его рисованием, но если все мои объекты находятся в 1-2 векторах, как мне передать матрицу им по отдельности?

Грубая последняя вторая идея будетсоздать векторную матрицу.И передать все матрицы в этот 1 вектор и передать его во фрагмент / пиксельный шейдер.Затем добавьте счетчик смещения и каждый следующий объект рендеринга, просто выполните matrix[offset*16], и это даст мне матрицу для этого объекта.После того, как это все, что мне нужно, это от matrix[offset*16] до matrix[offset*16+16], чтобы получить все 16 поплавков для создания матрицы и использования для рисования объекта?

Это правильное направление?

1 Ответ

0 голосов
/ 22 декабря 2018

Взгляните на Приближение к техникам с нулевой нагрузкой на драйвер (ADZO) В частности, обратите внимание на ARB_multi_draw_indirect (в ядре начиная с OpenGL 4.3) и ARB_shader_draw_parameters (в ядре начиная с OpenGL 4.6).Последний даст вам gl_DrawID вход для вашего вершинного шейдера, который можно использовать для индексации в UBO, SSBO или TBO, содержащих данные для каждого объекта, такие как матрицы моделей, слой массива текстур, материалы и т. Д.

ДляВ случаях, когда gl_DrawID недоступен (поддержка GL 4.6 в настоящее время не универсальна), существует довольно хитрый обходной путь: http://www.g-truc.net/post-0518.html.Используя glglVertexAttribDivisor из 1, одно значение атрибута используется для всех данных одного экземпляра - и только что определяется вызов экземпляра без экземпляра, который эквивалентен вызову экземпляра с отрисовкой экземпляра с числом экземпляров 1, поэтомувы получаете одинаковое значение для всех вершин в этом конкретном вызове отрисовки. Таким образом, вам нужен только относительно небольшой буфер с одним идентификатором на объект, вам не нужно дублировать его для каждой вершины объекта.А с косвенным вызовом multi draw вы можете указать многие из них, используя только один фактический вызов draw.

...