vbo содержит только вершину того же размера?

#iphone #opengl-es #vbo

#iPhone #opengl-es #vbo

Вопрос:

Содержит ли OpenGL / OpenGLES VBO только вершины одинакового размера?

Я спрашиваю, потому что обнаружил, что параметры для glDrawElements имеют значение смещения только для индексного буфера (его последний параметр), это означает: 1. я должен вручную смещать свои индексы, прежде чем отправлять их в IBO, если буферы уже частично заполнены. в любом случае, вручную смещать индексы легко, поэтому здесь это не проблема. 2. VBO, используемый в качестве буфера вершин, должен содержать вершины одинакового размера, иначе индексы не имеют смысла.

Это поведение отличается от буфера вершин DirectX, в directx есть SetStreamSource, который можно использовать для смещения буфера вершин, наряду с DrawIndexedPrimitive, ваш VB может содержать вершины произвольного размера.

возможно, версия SetStreamSource для OpenGLES 1.1 недоступна? может быть, OpenGLES 2.0 будет поддерживать это?

Моя целевая платформа — iPhone OpenGLES 1.1, поэтому, если SetStreamSource версии GL недоступен, я собираюсь отказаться от использования VBO, потому что : 1. это приносит больше проблем (мне придется выделить много VBO, содержащих вершины разного размера). 2. в любом случае улучшения производительности нет (аппаратная поддержка в OpenGLES 1.1 отсутствует)

спасибо за чтение и большое спасибо за то, что поделились своим опытом о правильных способах использования VBO в OpenGLES 1.1., спасибо.

Комментарии:

1. Что вы понимаете под «вершиной одинакового размера»?

Ответ №1:

Объекты буфера OpenGL (VBO — один из шаблонов использования) могут содержать произвольную информацию. Но функции рисования (например glDrawElements ) работают с непрерывным массивом информации о вершинах одинакового формата (очевидно, что каждая вершина занимает одинаковый размер). Если это тот размер, о котором вы спрашивали, тогда я не вижу, как его можно изменить.

Если вы хотите использовать VBO с определенным смещением (например, содержащий вершины другого формата) — тогда для вас есть последний параметр glVertexAttribPointer . Когда VBO привязан, этот последний параметр представляет собой смещение в байтах сегмента данных, используемого для атрибутов вершины.

Комментарии:

1. спасибо, кварк, я понял, как решить мою проблему, как только я увидел ваш ‘glVertexAttribPointer’, это очень поучительно (на самом деле это должен быть ‘glVertexPointer’ в моем случае), я использовал эту функцию много раз, к сожалению, я полностью забыл ее, пока я смотрел на ‘glDrawElements’ в недоумении. Спасибо.

Ответ №2:

Я не уверен, что полностью понимаю, что вы имеете в виду, когда говорите, что у вас разные размеры вершин. Но OpenGL может обрабатывать любые форматы вершин, доступные D3D.

Чего нет в OpenGL, так это концепции вершинных «потоков». Это потому, что они ему не нужны; думайте о каждом отдельном атрибуте (позиции, нормали, цвета и т.д.) Как о отдельном потоке. Но все они могут поступать из одного буфера и все они могут быть переплетены друг с другом.

Способ работы объектов буфера довольно прост. Объект buffer — это просто размерный блок памяти, управляемый OpenGL. Вы можете поместить в него любые байты, какие захотите.

Чтобы указать OpenGL, как извлекать из него данные о вершинах, вы должны определить несколько массивов, каждый из которых связан с атрибутом. Функциями для этого являются glVertexPointer, glNormalPointer и т.д.; Все они имеют вид gl * Pointer. Это вы, кажется, уже поняли.

Чего вы, возможно, не понимаете, так это того, что формат вершины, определенный этими функциями, не связан постоянно с объектом buffer. Например, вы можете использовать 3D-позиции с байтовыми цветами, все из одного объекта buffer:

 glBindBuffer(GL_ARRAY_BUFFER, bufferObject);
glEnableClientState(GL_VERTEX_ARRAY);   //Our vertices contain positions.
glVertexPointer(3, GL_FLOAT, 16, (void*)0);  //The last parameter is the byte offset from the beginning of the buffer to where the data starts.
glEnableClientState(GL_COLOR_ARRAY);    //Our vertices contain colors.
glColorPointer(4, GL_UNSIGNED_BYTE, 16, (void*)12); //Offset must add in the 3 floats from the vertex.
//Draw stuff.
  

Затем позже вы можете переопределить этот указатель, изменив формат по своему усмотрению. На этот раз мы используем 2D позиции, определенные как короткие, и вообще никаких цветов:

 glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(2, GL_SHORT, 4, (void*)1024);
glDisableClientState(GL_COLOR_ARRAY);  //Our vertices contain no colors.
//Draw stuff.
  

Привязка буфера не была изменена между этими вызовами. Этот новый массив начинается с 1024 байт от начала буфера. Таким образом, вы можете поместить данные для нескольких объектов в один буфер.

Теперь, есть одна вещь, которую OpenGL ES 1.1 не предлагает, что делает D3D. Когда вы вызываете DrawIndexedPrimitives, вы можете указать смещение, которое добавляется к каждому индексу перед извлечением вершин из массивов. Desktop OpenGL 3.2 и выше предоставляет это (и более низкие версии через расширения), но не ES 1.1.

Комментарии:

1. Я предполагаю, что магические числа приведены только для иллюстрации? Реальный код должен использовать sizeof и offsetof .

2. Спасибо Николу Боласу и подробному объяснению. вы правы в том, что «Способ работы объектов буфера довольно прост»: P. Я решил свою проблему с помощью glVertexPointer, не знаю, почему я полностью игнорирую это, когда публикую свой вопрос, мой плохой. еще раз спасибо вам и хорошего дня.