Что такое glBufferData для OpenGL ES?

Я просматриваю образец кода OpenGL, который я портировал на OpenGL ES 2.0 (на самом деле не так много было сделано), но я не могу не задаться вопросом, для чего предназначена функция glBufferData. Исходный источник выглядит следующим образом:

glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 2 * 6, quad, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 2, (void *) 0);

Но я могу с успехом упростить его как:

glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 2, quad);

То есть я могу опустить функцию glBufferData, просто используя действительный указатель на квадратный массив в glVertexAttribPointer.

Итак, может ли кто-нибудь объяснить, для чего предназначена функция glBufferData? Из того, что я делаю, это кажется излишним, но это должно быть из-за моего серьезного незнания API. На самом деле я пробовал читать документы в khronos.org, но это не помогло мне понять его использование.

Ответ 1

Если вы повторно используете одни и те же данные в нескольких фреймах, использование glBufferData как части вашей установки/инициализации будет передавать данные из CPU на GPU только один раз. В то время как glVertexAttribPointer должен вызываться каждый кадр, поэтому его использование для передачи данных приводит к использованию большей пропускной способности шины.

Если вы обновляете массив атрибутов в каждом фрейме, не так много преимуществ в том или ином виде.

Ответ 2

Это странно. Если оставить значение glBufferData одинаковым, то ни буфер не привязан, либо раньше в программе есть вызов glBufferData. Я был смущен, может ли OpenGL ES иметь несколько существенно отличающееся "особое поведение", но я проверил спецификации и, как я вижу, он работает точно так же, как в "нормальном" OpenGL.

Рисование (через glDraw [Элементы | Массивы]) будет считываться с указателя, ранее предоставленного glVertexAttribPointer, если привязан буфер no (клиентская память). Он будет считываться из буфера, если он связан, рассматривая аргумент указателя glVertexAttribPointer как смещение в буфер. Рисование из буфера, который не был инициализирован, явно не определен.

Что делает glBufferData?

glBufferData выполняет как минимум две вещи, и, возможно, третью. Он выделяет буферное хранилище и устанавливает использование буфера. Необязательно, если аргумент указателя не равен нулю, он будет заполнять буфер указанными данными. Подобная glBufferSubData отличается тем, что она только обновляет (возможно, подменю) данные, она не выделяет память или что-то еще.