Вызов glBindVertexArray(vao): что он делает, если 'vao' уже связан, и как соответствующим образом спроектировать классы фигур?

Я снова пробую OpenGL, и мне интересно, как спроектировать классы, которые будут отображаться позже. Прямо сейчас есть только один тип фигур, и поэтому я создал класс Shape со статическим членом VAO, который glGenVertexArrays(1, &vao) вызывается, когда первый экземпляр Shape создано. Теперь есть метод void Shape::render():

void Shape::render()
{
  glBindVertexArray(vao);
  glDrawArrays(GL_TRIANGLES, foo, bar);
}

Это хороший путь? Я имею в виду, когда все случаи Shape нарисованы в самой программе, есть повторяющийся вызов связывания Shape::vao, но я думаю, что это на самом деле ничего не делает, если vao уже связан в настоящее время. Это предположение правильно?

Кроме того, я видел учебник, который раньше вызывал glBindVertexArray(0) в конце render(), Не будет ли это потенциальной потерей производительности, когда есть много форм?

1 ответ

Решение

но я думаю, что на самом деле он ничего не делает, если vao уже связан в настоящее время. Это предположение правильно?

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

Это может добавить небольшое снижение производительности, однако. Разумная реализация GL, вероятно, в этом случае мало что даст, но у вас все еще есть вызов в библиотеку GL, и он должен найти текущий контекст потока, прежде чем у него появится шанс ничего не делать. Так что, возможно, вам все же будет лучше, если вы кешируете текущий VAO на вашей стороне и вызываете GL, только если он действительно изменится. Но это то, что может сказать вам только профилирование / бенчмаркинг. Если у вас есть много тысяч или даже миллионов экземпляров, это может стать реальной проблемой - ОТО, вы все равно облажались, если у вас есть отдельный вызов отрисовки для каждого экземпляра - в этом случае вы должны рассмотреть экземплярный рендеринг.

Кроме того, некоторое время назад я видел учебник, который вызывал glBindVertexArray(0) в конце render(). Не будет ли это потенциальной потерей производительности, когда есть много форм?

Да. Большинство уроков делают это для некоторой "чистоты", но в большинстве случаев это действительно пустая трата времени. Отмена привязки некоторого объекта GL является только полезной операцией, если вы можете (и на самом деле намерены) сделать что-то в "свободном" состоянии - например, FBO 0, который является просто кадровым буфером по умолчанию. Для VAO, в профиле ядра, VAO 0 совершенно бесполезен, и вы должны связать его в любом случае, прежде чем сможете рисовать - так что вы ничего не выиграете, не связывая другие промежуточные звенья.

Другие вопросы по тегам