Вызов 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 совершенно бесполезен, и вы должны связать его в любом случае, прежде чем сможете рисовать - так что вы ничего не выиграете, не связывая другие промежуточные звенья.