Рисование с использованием объектов Vertex Buffer в OpenGL ES 1.1 и ES 2.0 - PullRequest
4 голосов
/ 01 сентября 2011

Я новичок в openGL. Я использую документацию Apple в качестве моих основных референтов http://developer.apple.com/library/ios/#documentation/3DDrawing/Conceptual/OpenGLES_ProgrammingGuide/TechniquesforWorkingwithVertexData/TechniquesforWorkingwithVertexData.html#//apple_ref/doc/uid/TP40008793-CH107-SW6

Моя проблема в том, что я использую openGL ES 1.1 , а не 2 , таким образом, функции, которые используются в листинге 9-3, такие как glVertexAttribPointer , glEnableVertexAttribArray не распознаются ...:)

Я пытаюсь выполнить оптимизации, описанные в этой документации: хранить индексы и вершину как структуру со всеми ее данными: position, color (Листинг 9-1)

typedef struct _vertexStruct
{
  GLfloat position[3];
  GLubyte color[4];
} VertexStruct;

const VertexStruct vertices[] = {...};
const GLushort indices[] = {...};

и использовать VBO, такие как в Перечислении 9-2, 9-3

Как я уже упоминал, некоторые из используемых там функций не существуют в openGL ES 1.1. Мне интересно, есть ли способ сделать то же самое в ES 1.1, может быть, с другим кодом?

спасибо, Alex


Редактировать в соответствии с ответом христиан, пытался использовать glVertexPointer, glColorPointer. Вот код, он печатает куб, но без цветов ... :(. Кто-нибудь, можно ли использовать VBO в таком порядке, используя ES 1.1

typedef struct {
    GLubyte red;
    GLubyte green;
    GLubyte blue;
    GLubyte alpha;
} Color3D;

typedef struct {
    GLfloat x;
    GLfloat y;
    GLfloat z;
} Vertex3D;

typedef struct{
   Vector3D position;
   Color3D color;
} MeshVertex;

Данные куба:

static const MeshVertex meshVertices [] =
{

    { { 0.0, 1.0, 0.0 } , { 1.0, 0.0, 0.0 ,1.0 } },
    { { 0.0, 1.0, 1.0 } , { 0.0, 1.0, 0.0 ,1.0 } },
    { { 0.0, 0.0, 0.0 } , { 0.0, 0.0, 1.0 ,1.0 } },
    { { 0.0, 0.0, 1.0 } , { 1.0, 0.0, 0.0, 1.0 } },
    { { 1.0, 0.0, 0.0 } , { 0.0, 1.0, 0.0, 1.0 } },
    { { 1.0, 0.0, 1.0 } , { 0.0, 0.0, 1.0, 1.0 } },
    { { 1.0, 1.0, 0.0 } , { 1.0, 0.0, 0.0, 1.0 } },
    { { 1.0, 1.0, 1.0 } , { 0.0, 1.0, 0.0, 1.0 } }

};

static const GLushort meshIndices [] =
{   0, 1, 2 , 
    2, 1, 3 , 
    2, 3, 4 ,
    3, 5, 4 ,
    0, 2, 6 ,
    6, 2, 4 ,
    1, 7, 3 ,
    7, 5, 3 ,
    0, 6, 1 ,
    1, 6, 7 , 
    6, 4, 7 , 
    4, 5, 7 
};

Функция

GLuint vertexBuffer;
GLuint indexBuffer;

- (void) CreateVertexBuffers 
{ 
    glGenBuffers(1, &vertexBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(meshVertices), meshVertices, GL_STATIC_DRAW);

    glGenBuffers(1, &indexBuffer);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(meshIndices), meshIndices, GL_STATIC_DRAW);

}

- (void) DrawModelUsingVertexBuffers
{
    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
    glVertexPointer(3, GL_FLOAT, sizeof(MeshVertex), (void*)offsetof(MeshVertex,position));
    glEnableClientState(GL_VERTEX_ARRAY);


    glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(MeshVertex), (void*)offsetof(MeshVertex,color));
    glEnableClientState(GL_COLOR_ARRAY);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);  
    glDrawElements(GL_TRIANGLE_STRIP, sizeof(meshIndices)/sizeof(GLushort), GL_UNSIGNED_SHORT,    (void*)0);

    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_COLOR_ARRAY);
}

1 Ответ

4 голосов
/ 01 сентября 2011

Такие функции, как glVertexAttribPointer и glEnableVertexAttribArray, используются для общих пользовательских атрибутов вершин (которые являются единственным поддерживаемым методом представления данных вершин в OpenGL ES 2.0).

При использовании конвейера с фиксированными функциями (как и в OpenGL ES 1.1) вы просто используете встроенные атрибуты (вспомните вызовы glVertex и glColor, которые вы могли использовать до перехода к массивам вершин). Для каждого атрибута существуют функции, которые вызываются аналогично их аналогам в непосредственном режиме, например glVertexPointer или glColorPointer (вместо glVertexAttribPointer). Эти массивы включаются / отключаются путем вызова gl(En/Dis)ableClientState с такими константами, как GL_VERTEX_ARRAY или GL_COLOR_ARRAY (вместо gl(En/Dis)ableVertexAttribArray).

Но, как правило, вы не должны изучать программирование на OpenGL ES 1.1 с ресурсами 2.0, так как большая часть информации вам не пригодится (по крайней мере, если вы новичок в OpenGL). Например, некоторые методы, описанные на вашем связанном сайте, могут не поддерживаться в 1.1, такие как VBO или даже VAO. Но я также должен признать, что у меня нет опыта в ES, поэтому я не совсем уверен в этом.

РЕДАКТИРОВАТЬ: Относительно вашего обновленного кода: я предполагаю, что нет цветов означает, что куб имеет один цвет, возможно, белый. В своем первом примере кода вы использовали GLubyte color[4], а теперь его тип Color3D, может быть, это не подходит для вызова glColorPointer(4, GL_UNSIGNED_BYTE, ...) (где первый аргумент - это число компонентов, а второй - тип)?

Если ваш тип Color3D содержит только 3 цвета или цвета с плавающей точкой, я бы в любом случае предложил вам использовать 4-байтовые цвета, потому что вместе с вашими 3 плавающими позициями для позиции вы должны получить идеально выровненную вершину 16 байтов, Это также и оптимизация, которую они предлагают в предоставленной вами ссылке.

И, кстати, повторение создания индексного буфера в вашей CreateVertexBuffers функции - скорее опечатка, не так ли?

РЕДАКТИРОВАТЬ: Ваши цвета содержат ubytes (в диапазоне от 0 (черный) до 255 (полный цвет)), и вы инициализируете их с плавающей точкой. Таким образом, ваше значение с плавающей запятой 1.0 (которое, безусловно, должно означать полный цвет) преобразуется в ubyte, и вы получаете 1, который по сравнению со всем диапазоном [0,255] все еще очень мал, так что все черное. Когда вы используете ubytes, вы также должны инициализировать их ubytes, поэтому просто замените каждые 0.0 на 0 и каждые 1.0 на 255. В данных цвета.

И, кстати, так как вы используете VBO в ES 1.1 и по крайней мере что-то нарисовано, то ES 1.1, кажется, поддерживает VBO. Я этого не знал. Но я не уверен, что он также поддерживает VAO.

И, между прочим, вы должны вызвать glBindBuffer(GL_ARRAY_BUFFER, 0) и аналогично для буфера массива элементов после того, как вы закончите использовать их в конце этих двух функций. В противном случае вы можете получить проблемы в других функциях, которые не предполагают никаких буферов, но буферы все еще связаны. Всегда помните, что OpenGL является конечным автоматом, и каждое заданное вами состояние остается до тех пор, пока оно не будет изменено снова или контекст не будет уничтожен.

...