1
votes

I have a struct to store vertex data for 2 distinct models one is a cube the other a pyramid.

struct Model{
    GLuint vboID;
    GLfloat* vbo;
    GLuint vaoID;
    GLfloat* vao; 
    GLuint vertexStart;
    GLuint vertexCount;
};

I create the vbos and generate their buffers like this:

Model cubeModel;
Model pyramidModel;

cubeModel.vbo = cubeVerts; //A GLfloat array I created earlier in code earlier. 
cubeModel.vertexCount= sizeof(cubeVerts);//size of the GLfloat array in bytes

pyramidModel.vbo = pyVerts; 
pyramidModel.vertexCount= sizeof(pyVerts);

glGenBuffers(1, &cubeModel.vboID); //Generate a buffer for the vertices
glBindBuffer(GL_ARRAY_BUFFER, cubeModel.vboID); //Bind the vertex buffer
glBufferData(GL_ARRAY_BUFFER, cubeModel.vertexCount, cubeModel.vbo, GL_STATIC_DRAW);

And then to draw I use:

glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, 0);
glDrawArrays(GL_TRIANGLES, 0, cubeModel.vertexCount);
glDisableClientState(GL_VERTEX_ARRAY);

Which works, and I successfully draw the cube, But i've been trying multiple ways to draw the pyramid as well.

What do I need to do to render both on screen at the same time?

EDIT: Here's what i've tried specifically, duplicating the glBufferData() call and passing in the pyramid data then making glDrawArays(GL_TRIANGLES,0,cubeModel.drawcount+pyramidModel.drawCount) figuring the vertex data would stack and glDrawArrays would go through all the geometry passed in one go.

I've also tried making 2 sets of instructions from glGenBuffers() to glDisableClientState() but instead using all of pyramid model's data. This was interesting because my glDrawArrays was:

glDrawArrays(GL_TRIANGLES, 0, cubeModel.drawCount);
glTranslatef(4.0f,0.0f,0.0f);
glDrawArrays(GL_TRIANGLES, 0, pyramidModel.drawCount);

and it ended up drawing a really messed up pyramid 2 times, leading me to believe that when I cal glBufferData() twice the second time Overwrites the data previously passed.

EDIT 2:After Reading Andon's comment I edited some of my code to clarify things, drawCount is now vertexCount, and m_vertexBuffer is now correctly referencing the handle I stored in cubeModel, cubeModel.vboID, instead of using an old class variable I was using to store the handle.

1
You have the wrong idea about VBOs here... When I see a class/struct with a field named vbo the first thing that comes to my mind is: "this must be an OpenGL name (handle) to a VBO". You, on the other hand, are using this field to store the actual data that you will fill the VBO with. Instead of doing it the way you have it now, try making vbo a GLuint and doing something like: glGenBuffers (1, &cubeModel.vbo). You can store your vertex data wherever you want, because after you feed it to a VBO you do not need it anymore. Also use vertexCount instead of drawCount for clarity. - Andon M. Coleman
I knew I would have a facepalm moment as soon as someone said something. I do have that stored in the struct as well. GLuint vboID in the Model struct. so in this case cubeModel.vboID - Snowdrama

1 Answers

2
votes

I do not want to muddy up the comments section, because there are a lot of things wrong with your code. But I also do not have time to go through all of them right now, so this is a sort of temporary answer.

glBufferData (...) does not technically overwrite previously passed data, it does something far worse. Every time you call glBufferData (...) it creates a new data store of the size you pass and (optionally) fills it with the data you supply (if you pass something non-NULL). Think of it more like calling free (...) and then malloc (...) or delete [] ... and new Type [...].

glBufferSubData (...) is the preferred technique for appending vertices to a vertex buffer. Unfortunately it does not resize the data store. Sometimes it is handy to over-allocate your VBO and defer supplying it data until later on (using glBufferSubData).

If you use one VBO to store both of your models, you need to know the starting vertex and the vertex count for each model as it relates to your VBO's data. Right now all you know is the number of vertices (and you have it named strangely drawCount instead of vertexCount). To most people, drawCount indicates the number of times you want to draw something, rather than the number of vertices or elements it contains.

The size field of a call to glBufferData (...) is supposed to be the size in bytes of your vertex data. Right now you're passing the number of vertices. More than likely you meant to use sizeof (YourVertexDataStructure) for the size of an individual vertex (sizeof (float [3]) in this case), and something like sizeof (cubeVerts) / sizeof (YourVertexDataStructure) to calculate the number of vertices actually stored in this array. Then the size you pass to glBufferData (...) would be: _size * count_