Я снова пробую 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()
, Не будет ли это потенциальной потерей производительности, когда есть много форм?
но я думаю, что это на самом деле ничего не делает, если Vao
уже связаны в настоящее время. Это предположение правильно?
Да. Что касается правильности, то повторное связывание того, что уже связано, не является проблемой.
Это может добавить небольшое снижение производительности, однако. Разумная реализация GL, вероятно, в этом случае мало что даст, но у вас все еще есть вызов в библиотеку GL, и он должен найти текущий контекст потока, прежде чем он сможет ничего не делать. Так что может быть Вполне возможно, что вам все еще лучше, если вы кешируете текущий VAO на вашей стороне и вызываете GL, только если он действительно изменится. Но это то, что может сказать вам только профилирование / бенчмаркинг. Если у вас есть много тысяч или даже миллионов экземпляров, это может стать реальной проблемой — ОТО, вы все равно облажались, если у вас есть отдельный вызов отрисовки для каждого экземпляра — в этом случае вы должны рассмотреть экземплярный рендеринг.
Кроме того, я видел учебник, который раньше вызывал
glBindVertexArray (0) в конце рендера (). Разве это не было бы
потенциальная потеря производительности, когда есть много форм?
Да. Большинство уроков делают это для некоторой «чистоты», но в большинстве случаев это действительно пустая трата времени. Отмена привязки некоторого объекта GL является только полезной операцией, если вы можете (и на самом деле намерены) сделать что-то в «свободном» состоянии — например, FBO 0, который является просто кадровым буфером по умолчанию. Для VAO, в профиле ядра, VAO 0 совершенно бесполезен, и вы должны связать его в любом случае, прежде чем сможете рисовать — так что вы ничего не выиграете, не связывая другие промежуточные звенья.