VBO glDrawElements и glVertexAttribPointer на GLES2.0 ничего не отображает - PullRequest
4 голосов
/ 03 августа 2011

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

Init

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))

Init

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);

Draw

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);

Ответы [ 2 ]

4 голосов
/ 03 августа 2011

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

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

1 голос
/ 03 августа 2011

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

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

...