1

I have written a small program that is supposed to display several cubes with OpenGL 4.3. I use SDL 2.0 to create a context but I don't think my problem comes from there.

I have a class Cube that has several attributes, including a GLuint m_vao for the Vertex Array and a GLuint m_vbo for the Vertex Buffer.

To display several cubes, I create several instances of this class with different coordinates. I use glGenVertexArrays(1, &m_vao) and glGenBuffers(1, &m_vbo) in the constructor of the Cube.

I have no issue when creating cubes like this :

Cube c(-4, 0, -4, "texture.jpg");
Cube c2(4, 0, 2, "texture.jpg");
Cube c3(2, 1, 2, "texture.jpg");
Cube c4(-2, 1, 2, "texture.jpg");

This creates four cubes with unique m_vao and m_vbo attributes (1 for c, 2 for c2, 3 for c3 and 4 for c4).

However, when I create my cubes like this:

std::vector<std::vector<Cube>> cubes;
for (int i = 0; i < 9; i++) {
    cubes.push_back(std::vector<Cube>());
    for (int j = 0; j < 9; j++) {
        Cube temp = Cube(i, 0, j, "texture.jpg");
        cubes[i].push_back(temp);
    }
}

All the cubes inside my vector have the same m_vao and m_vbo attributes, in this case they all have 1 as m_vao and m_vbo. If I do it after creating the cubes c, c2, c3 and c4 manually, they all get 4. Of course, since they all use the same VBO, they all have the same coordinates and only one cube appears in the end.

So my question is: what is different between creating the cubes manually (which works fine) and creating them inside a std::vector with a for loop (which generates the same VAO and VBO for all the cubes) ?

genpfault
  • 51,148
  • 11
  • 85
  • 139
Sunreef
  • 4,452
  • 21
  • 33
  • 1
    See http://stackoverflow.com/questions/28929452/mesh-class-called-with-default-constructor-not-working-opengl-c. – Reto Koradi Aug 18 '15 at 15:18
  • Thanks a lot for this link. Your answer was extremely clear. I upvoted it (even though it won't appear before I reach 15 reputation). – Sunreef Aug 18 '15 at 15:34

1 Answers1

1

I'm assuming, that you call glDeleteBuffers in the destructor? When pushing the temporary cube into the vector, temp::~Cube() is called when temp goes out of context, which releases the buffers. The next cube will then get the already freed id.

for (int j = 0; j < 9; j++)
{

    // Calls Cube(...)
    Cube temp = Cube(i, 0, j, "texture.jpg");

    // Copies or movies temp into the vector
    // In cases where cubes has to resize, also Cube::~Cube() is called
    cubes[i].push_back(temp);

    // temp goes here out of scope so temp::~Cube() is called
} 
BDL
  • 21,052
  • 22
  • 49
  • 55
  • Thank you for your answer. I am indeed calling glDeleteBuffers in the destructor. However, I tried before without using the temp variable and pushing a new cube directly inside the vector. And it still wasn't working correctly. Is it a problem of scope there too ? – Sunreef Aug 18 '15 at 15:20
  • Yes. It doesn't matter if the temporary variable has a name. When it is created in scope it will be destroyed when going out of scope. The answer from @RetoKoradi has some more explanations on how to handle such situations. – BDL Aug 18 '15 at 15:29
  • Thank you. I looked at @RetoKoradi link and it has the answer I was searching for. – Sunreef Aug 18 '15 at 15:39