I wrote this "Model" class to load .obj files and allocate data for them in a VBO. Its code is something like this: (notice how it doesn't use VAOs)
class Model {...}
void Model::LoadOBJ(const char *file)
{
//load vertices, normals, UVs, and put them all in _vec, which is a private data member of std::vector<glm::vec3>
...
//if an .obj file is loaded for the first time, generate a buffer object and bind it
if(glIsBuffer(_vbo) == GL_FALSE)
{
glGenBuffers(1, &_vbo);//_vbo is a private data member
glBindBuffer(GL_ARRAY_BUFFER, _vbo);
}
//load the data in the array buffer object
glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec3) * _vec.size(), &_vec[0][0], GL_STATIC_DRAW);
}
void Model::Draw()
{
glBindBuffer(GL_ARRAY_BUFFER, _vbo);
glDrawArrays(GL_TRIANGLES, 0, _numVertices);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
I used to think that the next code would work fine for rendering two different objects:
void init()
{
//vao dummy (?)
GLuint VAO;
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
//load 3d models
Model cube = load("cube.obj");
Model cow = load("cow.obj");
//the next two lines should be valid for both objects?
glVertexAttribPointer(prog.GetAttribLocation("vertex"), 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(prog.GetAttribLocation("vertex"));
}
void render()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//draw cube:
//some matrix transformations
...
cube.Draw();
//draw cow:
//some matrix transformations
...
cow.Draw()
glutSwapBuffers();
}
but it turns out that OpenGL will just draw two cows or two cubes. (depends on which model I load last in init())
By the way, I'm pretty sure that in the first image, opengl did try to draw two cows, but the glDrawArrays() function was called with the amount of vertices needed for a cube.
So what am I missing? Do I need a different VAO for every buffer object or something like that?