GlEnableClientState с современным OpenGL (glVertexAttribPointer и т.д.)
Я хотел бы рассказать о некоторых вещах, которые, как я думаю, узнал, но я не уверен:
- VBOs - это путь. Они создаются с помощью
glGenBuffers
и glBufferData
.
- Для максимальной гибкости лучше передать общие атрибуты вершин в шейдеры с
glVertexAttribPointer
, а не glVertex
, glNormal
и т.д.
-
glDrawElements
может использоваться с буферами вершин и буфером индексов для эффективного рендеринга геометрии с большим количеством общих вершин, таких как ландшафтная сетка.
Предполагая, что все это правильно, вот мой вопрос. Все обучающие материалы, которые я прочитал о современном OpenGL, полностью опускают glEnableClientState
. Но man-страницы OpenGL говорят, что без glEnableClientState
, glDrawElements
ничего не сделает:
http://www.opengl.org/sdk/docs/man/xhtml/glDrawElements.xml
Ключевой проход: "Если GL_VERTEX_ARRAY
не включен, геометрические примитивы не создаются".
Это приводит меня к следующим вопросам:
- Ни один из руководств не использует
glEnableClientState
перед вызовом glDrawElements
. Означает ли это, что страница руководства неверна или устарела?
-
GL_VERTEX_ARRAY
, похоже, будет тем, что вы включите, если вы собираетесь использовать glVertexPointer
, а также использовать GL_NORMAL_ARRAY
с glNormalPointer
и так далее. Но если я не использую эти функции и вместо этого использую общие атрибуты вершин с glVertexAttribPointer
, то зачем нужно включать GL_VERTEX_ARRAY
?
Ответы
Ответ 1
Если GL_VERTEX_ARRAY не включен, геометрические примитивы не создаются.
Это потому, что справочная страница неверна. Страница руководства охватывает GL 2.1 (и это по-прежнему не так), и по любой причине люди, обновляющие справочную страницу, отказываются обновлять старые версии GL для исправлений ошибок.
В GL 2.1 вы должны использовать либо общий индекс атрибута 0, либо GL_VERTEX_ARRAY
. В GL 3.1+ вам не нужно использовать какие-либо конкретные индексы атрибутов.
Это связано с тем, что в версиях GL до 3.1 все функции рендеринга массива были определены в терминах вызовов glArrayElement
, которые использовали немедленный рендеринг на основе режима. Это означает, что вам нужно что-то спровоцировать вершину. Напомним, что в непосредственном режиме вызов glVertex*()
не только устанавливает положение вершины, но также вызывает отправку вершин с другими атрибутами. Вызов glVertexAttrib*(0, ...)
делает то же самое. Поэтому для более старых версий вам потребуется использовать либо атрибут 0, либо GL_VERTEX_ARRAY
.
В GL 3.1+, как только они выберут немедленный режим, им пришлось указывать рендеринг массива по-разному. И из-за этого им не пришлось ограничивать себя использованием атрибута 0.
Если вы хотите, чтобы документы API для ядра GL 3.3 работали, я предлагаю вам посмотреть фактические документы API для основного GL 3.3. Хотя, если честно, я бы просто посмотрел на спецификацию, если вам нужна точная информация. В этих документах много дезинформации. И поскольку они не являются вики-страницами, эта информация никогда не исправляется.
Ответ 2
Ваши первые 3 балла верны. И чтобы ответить на вашу последнюю половину вопроса, не используйте glEnableClientState
для современного OpenGL. Начните кодирование!
Ответ 3
VBOS - это путь. Они созданы с помощью glGenBuffers и glBufferData.
VBOs часто используются в высокопроизводительных приложениях. Сначала вы можете сделать что-то более простое. Вершинные массивы могут быть хорошим способом быстро начать работу. Поскольку VBOs сидят поверх вершинных массивов в любом случае, вы будете использовать большую часть того же кода при переключении на VBOs, и может быть полезно запустить тест с использованием вершинных массивов или индексированных массивов вершин.
Для максимальной гибкости лучше всего передать общие атрибуты вершин для шейдеров с glVertexAttribPointer, а не glVertex, glNormal, и т.д..
Это хороший подход.
glDrawElements может использоваться с буферами вершин и буфером индексов для эффективно выполнять геометрию с множеством общих вершин, например ландшафтная сетка.
Может быть. Однако вы должны быть уверены, что вершины действительно разделены. Вершина, находящаяся в одном и том же месте, но имеющая обычную нормальную (например, для плоского затенения), по-настоящему не разделена.