1
votes

I was going along just fine working on an opengles 2.0 application until I tested it on an older phone that doesn't support VAO and now I seem to have fallen into a marsh.

I started using opengl after VAO's were sorta standard and everywhere so I never had to render without using one. Now that I have to write code that supports it I am having some trouble.

vertex shader

attribute vec3 position;
attribute vec4 icolor;
varying vec4 fcolor;

void main()
{
    gl_Position =  vec4(position, 1.0);
    fcolor = icolor;
}

fragment shader

precision mediump float;
varying vec4 fcolor;
void main (void)
{
gl_FragColor = fcolor;
}

application side of things

init code:

glGenBuffers(1, &verticesBuffer);
glBindBuffer(GL_ARRAY_BUFFER, verticesBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(rend2d->vertices), rend2d->vertices, GL_STATIC_DRAW);

glGenBuffers(1, &indicesBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indicesBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(rend2d->indices), rend2d->indices, GL_STATIC_DRAW);

glGenBuffers(1, &colorBuffer);
glBindBuffer(GL_ARRAY_BUFFER, colorBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(rend2d->colors), rend2d->colors, GL_STATIC_DRAW);

rendering code: glClearColor(1.0f, 1.0f, 1.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); glUseProgram(sp);

GLint posLoc = glGetAttribLocation(sp, "position"); 
GLint colLoc = glGetAttribLocation(sp, "icolor");

glBindBuffer(GL_ARRAY_BUFFER, verticesBuffer);
glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, 0, 0);

glBindBuffer(GL_ARRAY_BUFFER, colorBuffer);
glVertexAttribPointer(colLoc, 4, GL_FLOAT, GL_FALSE, 0, 0);

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indicesBuffer);

glDrawElements(GL_TRIANGLES, rend2d->vertexCount, GL_UNSIGNED_INT, 0);

my error might be glaringly obvious but I just don't see what part I am currently not doing correctly and hoping to get some help with semi-modern opengl. This is mainly to provide support for apps that are opengles 2.0 but do not support the GL_OES_vertex_array_object extension.

2
I don't see any glEnableVertexAttribArray() calls in your code. The enable state per attribute is also stored in VAOs. - derhass

2 Answers

1
votes

I wanted to post the answer because it was many little things that were wrong. First I'll post the data structure that I was using to hold my gl data.

typedef struct
{
    GLuint vertexCount;

    GLfloat vertices[12];
    GLfloat colors[16];
    GLuint  indices[6];
    GLfloat texCoords[8];

} renderable2d;

the first problem was here. As @derhass pointed out on the irc channel opengles 2.0 doesn't support 32bit indices. So the first step was to change that gluint above to glushort

typedef struct
{
    GLushort vertexCount; //I made this a short as well

    GLfloat vertices[12];
    GLfloat colors[16];
    GLushort  indices[6]; //make this a short instead of an int
    GLfloat texCoords[8];

} 

once that part was fixed, then I had to generate my buffers, bind them and put the data in them, then unbind.

//bind n setup vertices
glGenBuffers(1, &verticesBuffer);
glBindBuffer(GL_ARRAY_BUFFER, verticesBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(rend2d->vertices), rend2d->vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);

//bind n setup colors
glGenBuffers(1, &colorBuffer);
glBindBuffer(GL_ARRAY_BUFFER, colorBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(rend2d->colors), rend2d->colors, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);

//bind n setup indices
glGenBuffers(1, &indicesBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indicesBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(rend2d->indices), rend2d->indices, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);

and finally on to the rendering code

glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);

glUseProgram(sp);

glBindBuffer(GL_ARRAY_BUFFER, verticesBuffer);
glEnableVertexAttribArray(posLoc);
glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, 0, 0);

glBindBuffer(GL_ARRAY_BUFFER, colorBuffer);
glEnableVertexAttribArray(colLoc);
glVertexAttribPointer(colLoc, 4, GL_FLOAT, GL_FALSE, 0, 0);

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indicesBuffer);
glDrawElements(GL_TRIANGLES, rend2d->vertexCount, GL_UNSIGNED_SHORT, 0);

after doing all that I got things sorted out on both devices. Just for clarity rend2d is just a textured quad so rend2d->vertexCount = 6; With more complex models well you'll get that info somewhere else.

0
votes

1) GL_UNSIGNED_INT is not officially supported in ES 2.0 as an index type

your GL_UNSIGNED_INT must be either one GL_UNSIGNED_BYTE or GL_UNSIGNED_SHORT

2) Assume they are friends when you use VBO without VAO.

glBindBuffer();
glVertexAttribPointer();
glEnableVertexAttribArray(); // you don't call it

In init()

GLint posLoc = glGetAttribLocation(sp, "position"); 
GLint colLoc = glGetAttribLocation(sp, "icolor");

glGenBuffers(1, &verticesBuffer);
glBindBuffer(GL_ARRAY_BUFFER, verticesBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(rend2d->vertices), rend2d->vertices, GL_STATIC_DRAW);
glEnableVertexAttribArray(posLoc);
glVertexAttribPointer(posLoc, GL_FLOAT,0,0,0);

glGenBuffers(1, &colorBuffer);
glBindBuffer(GL_ARRAY_BUFFER, colorBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(rend2d->colors), rend2d->colors, GL_STATIC_DRAW);
glEnableVertexAttribArray(colLoc)
glVertexAttribPointer(colLoc, GL_FLOAT,0,0,0);

In rendering()

glBindBuffer(GL_ARRAY_BUFFER, verticesBuffer);
glEnableVertexAttribArray(posLoc);
glVertexAttribPointer(posLoc, GL_FLOAT,0,0,0);

glBindBuffer(GL_ARRAY_BUFFER, colorBuffer);
glEnableVertexAttribArray(colLoc)
glVertexAttribPointer(colLoc, GL_FLOAT,0,0,0);

3) Just don't use VAOs in ES 2.0 in which, VAO is not officially supported. However, IOS does as an exception.