1
votes

Im about to implement a very basic render module. now is time to change the old way to render primitives to a modern approach using VBO , so far i understand how it works but i cant get my PoC working.

Loading the basic model( a triangle) no opengl errors generated (glBindVertexArray is a macro to glBindVertexArrayAPPLE) :

    float pos[] = { 
    -1.0f, -1.0f,-5.0f, 
    -1.0f, 1.0f, -5.0f,
    1.0f,1.0f,-5.0f, 
    };

printf("%d %d", map_VAO, map_VBO);
checkGLError();
glGenVertexArrays(1, &map_VAO);

checkGLError();
glGenBuffers(1, &map_VBO);

printf("%d %d", map_VAO, map_VBO); // here with 4.1 map_VAO is 0

checkGLError();
glEnableClientState(GL_VERTEX_ARRAY);

glBindVertexArrays(map_VAO);
glBindBuffer(GL_ARRAY_BUFFER, map_VBO);
glBufferData(GL_ARRAY_BUFFER, 9 * sizeof(float), &pos[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL); 

glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArrays(0);

glDisableClientState(GL_VERTEX_ARRAY);

return 0;

And in the main loop (drawing part) :

// .. clear buffers load identity etc... 

glColor3f(0.33f,0.0f,0.0f);

glEnableClientState(GL_VERTEX_ARRAY);

glBindBuffer(GL_ARRAY_BUFFER, map_VBO);
glBindVertexArrayAPPLE(map_VAO);
glEnableVertexAttribArray(0); 

glDrawArrays(GL_TRIANGLES, 0, 3); 

glBindBuffer(GL_ARRAY_BUFFER, 0 );
glBindVertexArrayAPPLE(0);

glDisableClientState(GL_VERTEX_ARRAY);

New drawing part : (removing unnecessary clientstate and binds)

glColor3f(0.33f,0.0f,0.0f);

glBindVertexArrayAPPLE(map_VAO);

glDrawArrays(GL_TRIANGLES, 0, 3);

But nothing is displayed. I had tried changing the profiles and the OpenGL Version but other problems arise. I can draw a simple triangle with the old approach:

glBegin(GL_TRIANGLES);
glVertex3f( -1.0f, -1.0f, -5.0f);
glVertex3f( -1.0f, 1.0f, -5.0f);
glVertex3f(  1.0f, 1.0f,-5.0f);
glEnd();

Questing: What I'm doing wrong?, theres some kind of activation related to VBO and VAO?

Additional questions : why when i use open gl 4.1 Core profile i cant get a VAO name with genVertexArray? (it says invalid operation)

2

2 Answers

5
votes

A few things:

  1. glEnableClientState is deprecated. glEnableClientState is used to tell OpenGL you're using a vertex array for fixed-function functionality which you're not using anymore, so it's no use calling this function (and probably causes weird results).
  2. glEnableVertexAttribArray(0); There is no need to enable it again in your drawing function. Enabling the 0th vertex attribute was stored in your VAO.
  3. glBindBuffer(GL_ARRAY_BUFFER, map_VBO); Also, no need to call this function in the drawing function. glVertexAttribPointer stores the VBO binding while you configured the VAO.

So, remove the glEnable/Disable-ClientState functions and remember that you just need to bind the VAO in your case. I believe the cause of your error is point 1. Points 2 and 3 are just to improve your code ;)

4
votes

You did not wrap glGenVertexArrays around glGenVertexArraysAPPLE did you? (like you mentioned doing for glBindVertexArray)

That function does not exist in core profiles on OS X, you will notice a distinct lack of GL_APPLE_vertex_array_object from the extensions string. It exists in Legacy (2.1) profiles as seen here but not in Core (3.2+) as seen here.

You are supposed to #include <OpenGL/gl3.h> when using a core profile on OS X and call glGenVertexArrays (...) instead of glGenVertexArraysAPPLE (...).

Only call VertexArray*APPLE functions in an OpenGL 2.1 context on OS X or you will get GL_INVALID_OPERATION errors.