VBO glDrawElements и glVertexAttribPointer на GLES2.0 ничего не отображают

Я могу отобразить текстуру с помощью шейдеров, glVertexAttribPointer и glDrawArrays следующим образом:

В этом

const GLfloat squareVertices[] = {
    -0.5f, -0.33f,
    0.5f, -0.33f,
    -0.5f,  0.33f,
    0.5f,  0.33f
};


const GLfloat squareTex[] = {
    0, 0,
    1, 0,
    0, 1,
    1, 1
};


glEnableVertexAttribArray(PositionTag);
glEnableVertexAttribArray(TexCoord0Tag);

glVertexAttribPointer(PositionTag, 2, GL_FLOAT, GL_FALSE, 0, squareVertices);
glVertexAttribPointer(TexCoord0Tag, 2, GL_FLOAT, GL_FALSE, 0, squareTex);

И для розыгрыша

glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

Но у меня возникают трудности с преобразованием в VBO, шейдеры и glDrawElements. Это код, который у меня есть до сих пор, но ничего не отображается:

Заголовок

typedef struct MyVertex
{
    float x, y, z;        //Vertex
    float nx, ny, nz;     //Normal
    float s0, t0;         //Texcoord0
} MyVertex;

#define BUFFER_OFFSET(i) ((char *)NULL + (i))

В этом

glGenBuffers(1, &VertexVBOID);

glBindBuffer(GL_ARRAY_BUFFER, VertexVBOID);

MyVertex pvertices[4];
//Fill the pvertices array
pvertices[0].x = -0.5f;
pvertices[0].y = -0.33f;
pvertices[0].z = 0.0;
pvertices[0].nx = 0.0;
pvertices[0].ny = 0.0;
pvertices[0].nz = 1.0;
pvertices[0].s0 = 0.0;
pvertices[0].t0 = 0.0;

pvertices[1].x = 0.5f;
pvertices[1].y = -0.33f;
pvertices[1].z = 0.0;
pvertices[1].nx = 0.0;
pvertices[1].ny = 0.0;
pvertices[1].nz = 1.0;
pvertices[1].s0 = 1.0;
pvertices[1].t0 = 0.0;

pvertices[2].x = -0.5f;
pvertices[2].y = 0.33f;
pvertices[2].z = 0.0;
pvertices[2].nx = 0.0;
pvertices[2].ny = 0.0;
pvertices[2].nz = 1.0;
pvertices[2].s0 = 0.0;
pvertices[2].t0 = 1.0;

pvertices[3].x = 0.5f;
pvertices[3].y = 0.33f;
pvertices[3].z = 0.0;
pvertices[3].nx = 0.0;
pvertices[3].ny = 0.0;
pvertices[3].nz = 1.0;
pvertices[3].s0 = 1.0;
pvertices[3].t0 = 1.0;

glBufferData(GL_ARRAY_BUFFER, sizeof(MyVertex)*4, NULL, GL_STATIC_DRAW);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(MyVertex)*4, pvertices);


glGenBuffers(1, &IndexVBOID);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexVBOID);

int pindices[6];
pindices[0]=0;
pindices[1]=1;
pindices[2]=2;
pindices[3]=2;
pindices[4]=1;
pindices[5]=3;
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(int)*6, NULL, GL_STATIC_DRAW);
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, sizeof(int)*6, pindices);

Рисовать

glBindBuffer(GL_ARRAY_BUFFER, VertexVBOID);

glEnableVertexAttribArray(PositionTag);
glEnableVertexAttribArray(NormalTag);
glEnableVertexAttribArray(TexCoord0Tag);

glVertexAttribPointer(PositionTag, 3, GL_FLOAT, GL_FALSE, 32, BUFFER_OFFSET(0));
glVertexAttribPointer(NormalTag, 3, GL_FLOAT, GL_FALSE, 32, BUFFER_OFFSET(12));
glVertexAttribPointer(TexCoord0Tag, 2, GL_FLOAT, GL_FALSE, 32, BUFFER_OFFSET(24));

//    glDrawRangeElements(GL_TRIANGLES, x, y, z, GL_UNSIGNED_SHORT, BUFFER_OFFSET(0));
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexVBOID);
glDrawElements(GL_TRIANGLES, 3, GL_INT, 0);

person Zeophlite    schedule 03.08.2011    source источник


Ответы (2)


Согласно здесь, GL_INT не является допустимым типом для использования индексы в glDrawElements. Попробуйте использовать unsigned int для ваших индексов (и, конечно же, GL_UNSIGNED_INT в glDrawElements). Вы по-прежнему можете использовать свои данные int в качестве индексов, но поскольку glDrawElements требуется GL_UNSIGNED_INT, было бы более последовательно сделать массив unsigned int.

РЕДАКТИРОВАТЬ: Изучив спецификацию (основываясь на ваших тегах, я взял спецификацию ES 2.0), они, похоже, еще больше ограничивают ее беззнаковым байтом и беззнаковым коротким. Я не знаю, ограничено ли это в iOS, но мы можем сделать вывод, что данные должны быть как минимум неподписанными. С другой стороны, я не нашел никаких утверждений о возможной ошибке GL_INVALID_ENUM, которая возникает при неправильном аргументе типа, но было бы разумно получить ее.

person Christian Rau    schedule 03.08.2011
comment
что поднимает следующий вопрос: Zeophlite должен проверить, сообщает ли GL об ошибках в отладке. Тогда glDrawElements должен сообщить GL_INVALID_ENUM. - person Bahbar; 03.08.2011
comment
@Bahbar Хотя очевидно, что аргумент неправильного типа не указан в данной справочной ссылке в качестве источника для GL_INVALID_ENUM. Вот почему я не указал это прямо в своем ответе. Но ссылка по-прежнему говорит, что действительны только беззнаковые. Может быть, я должен проверить спецификацию для уточнения. - person Christian Rau; 03.08.2011
comment
Да, спецификация ошибок применяется ко всем перечислениям, а не конкретно к каждой команде. Если команде, требующей перечисляемого значения, передается символическая константа, которая не является одной из тех, которые указаны как допустимые для этой команды, генерируется ошибка INVALID_ENUM. - person Bahbar; 03.08.2011
comment
Спасибо за ответ, Кристиан, я действительно понял это заранее, но StackOverflow не позволил мне опубликовать ответ. Также @Bahbar, ошибки не было! (Я удалил свой код проверки ошибок для своего поста) - person Zeophlite; 04.08.2011
comment
@Zeophlite: тогда это ошибка драйвера. Файл это :D ? - person Bahbar; 04.08.2011
comment
@Bahbar Это не обязательно ошибка драйвера, может быть, просто неточность спецификации. Как я уже сказал, они перечисляют все ошибки, которые могут быть сгенерированы неправильными аргументами для glDrawElements, за исключением ошибок для аргумента неправильного типа, возможно, их нет. - person Christian Rau; 04.08.2011
comment
Цитата, которую я дал, взята из спецификации и недвусмысленна. И он охватывает все команды GLES. Итак... если он не указывает на ошибку, это это ошибка драйвера. И это определенно ошибка справочной страницы. - person Bahbar; 04.08.2011

Ваш код не выглядит ужасно неправильным, так что на этот раз дьявол где-то в деталях. Я предполагаю, что ваше использование структуры и выравнивание ее полей данных не соответствуют смещениям, переданным в OpenGL.

Я предлагаю вам использовать макрос offsetof() из файла stddef.h для переноса получить смещения полей данных.

person datenwolf    schedule 03.08.2011