0
\$\begingroup\$

Until now, I have been using a vertexData structure to store data for a Vertex Buffer Object (VBO); vertexData holds a static array of 6 vertices (2 triangles). I then save them to a vector of the vertexData type, before finally using this vertexData in the buffering method:

struct vertexData {

    Vertex vertices[6]; // position, color, UVs
};

std::vector<vertexData> _DATA;

void SpriteBatch::createVBO() {

    glBindBuffer(GL_ARRAY_BUFFER,_VBO);

    glBufferData(GL_ARRAY_BUFFER,_DATA.size()*sizeof(vertexData),nullptr,GL_DYNAMIC_DRAW);
    glBufferSubData(GL_ARRAY_BUFFER,0,_DATA.size()*sizeof(vertexData),_DATA.data());

    glBindBuffer(GL_ARRAY_BUFFER,0);
}

This works good, as everything in my vector is contiguous. However, I want to work with other vertex sizes, for different shapes. I tried a vector of vector types, in oder to work with dynamically allocated arrays, but it did not work, as it was not contiguous.

At first, I thought about using a polymorphic class to be stored as a vector, where every child would have a different array size; but then I recognized that this vertex buffer does not work with pointers

The second idea was to create a generic SpriteBatch. For example, a batch for 6 vertices, and then a batch for 2 vertices, etc. etc.

What is the best way to store Vertex Buffer Object data?

\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

My knee jerk (operative work jerk?) reaction:

Leave your contiguous vector as it is but make it just 3 or 1 vertices (depending on the rest of your code), store all your different shapes into the same contiguous space as you do now. Then use an index (map) to record the offset of each polygon/shape.

Then when you use the VBO, just remember to offset your pointers by the index depending on what shape you want.

Example (warning, haven't touched C++ in years)...

std::map<int,int> _shapeOffsets;
_shapeOffsets[_myPolygonsCustomIdentifier] = _theOffsetOfMyPolygonInTheVertexData;
MyPolygonDrawingFunc(_DATA.data() + _shapeOffsets[_myPolygonsCustomIdentifier]);

Pro: Not much of a change from what you're doing now Con: Could have complications if you wanted to 'delete' a shape and remove vertices. If this is an issue, we can brainstorm an alternative solution.

Hope that was clear enough, hope I didn't miss the point somewhere :)

\$\endgroup\$
4
  • \$\begingroup\$ i tried the version with 1 vertex in the past and (maybe i did it wrong way) it was a real shock for performance (instead of putting 1 struct into vector i was putting 6 per gameObject). (i added some of my opinions into the question [because space for comments is small], if you want you can check them out) \$\endgroup\$
    – Pins
    Commented Mar 26, 2017 at 19:58
  • \$\begingroup\$ It doesn't make sense that OpenGL would suffer any performance loss when your vertexData struct only holds one vertex, because to OpenGL, it's just a contiguous set of data at that pointer location. I can only imagine that the performance issue lay in how you built up your vertex data, perhaps? \$\endgroup\$
    – PlaceboZA
    Commented Mar 27, 2017 at 16:03
  • \$\begingroup\$ Btw, I found a nice explanation of VBOs here, for whoever reads this and needs to understand them :) antongerdelan.net/opengl/vertexbuffers.html \$\endgroup\$
    – PlaceboZA
    Commented Mar 27, 2017 at 16:11
  • \$\begingroup\$ the performance problem wasn´t with GPU, but with CPU, because it had to process 6x more calls than before(i mean, put calls, instead of 1 struct i was putting 6 vertices 1 by one). About link- very nice thank you, i don´t know how did i miss this one \$\endgroup\$
    – Pins
    Commented Mar 27, 2017 at 16:56

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .