@@ -237,10 +237,9 @@ struct Batch {
237237 GLint uvAttr;
238238 GLint tintAttr;
239239
240- GLuint vbo;
241240 std::vector<Vertex> vertices;
242241
243- void Execute ();
242+ void Execute (GLuint sharedVbo, size_t vertexBase );
244243};
245244
246245Batch::Batch (GLuint prog)
@@ -249,46 +248,40 @@ Batch::Batch(GLuint prog)
249248 xyAttr = glGetAttribLocation (prog, " a_vertex" );
250249 uvAttr = glGetAttribLocation (prog, " a_texcoord" );
251250 tintAttr = glGetAttribLocation (prog, " a_tint" );
252- glGenBuffers (1 , &vbo);
253251}
254252
255253Batch::Batch (Batch&& rhs)
256254 : prog(rhs.prog)
257255 , xyAttr(rhs.xyAttr)
258256 , uvAttr(rhs.uvAttr)
259257 , tintAttr(rhs.tintAttr)
260- , vbo(rhs.vbo)
261258 , vertices(std::move(rhs.vertices))
262259{
263- rhs.vbo = 0 ;
264260}
265261
266262Batch& Batch::operator = (Batch&& rhs) {
267263 prog = rhs.prog ;
268264 xyAttr = rhs.xyAttr ;
269265 uvAttr = rhs.uvAttr ;
270266 tintAttr = rhs.tintAttr ;
271- vbo = rhs.vbo ;
272267 vertices = std::move (rhs.vertices );
273- rhs.vbo = 0 ;
274268
275269 return *this ;
276270}
277271
278- Batch::~Batch () {
279- if (vbo) {
280- glDeleteBuffers (1 , &vbo);
281- }
282- }
272+ Batch::~Batch () {}
283273
284- void Batch::Execute ()
274+ void Batch::Execute (GLuint sharedVbo, size_t vertexBase )
285275{
286276 if (vertices.empty ()) {
287277 return ;
288278 }
289279
290- glBindBuffer (GL_ARRAY_BUFFER , vbo);
291- glBufferData (GL_ARRAY_BUFFER , vertices.size () * sizeof (Vertex), vertices.data (), GL_STREAM_DRAW );
280+ glBindBuffer (GL_ARRAY_BUFFER , sharedVbo);
281+ auto dataPtr = (uint8_t const *)vertices.data ();
282+ auto dataOff = vertexBase * sizeof (Vertex);
283+ auto dataSize = vertices.size () * sizeof (Vertex);
284+ glBufferSubData (GL_ARRAY_BUFFER , dataOff, dataSize, dataPtr);
292285 glVertexAttribPointer (xyAttr, 2 , GL_FLOAT , GL_FALSE , sizeof (Vertex), (void const *)offsetof (Vertex, x));
293286 glVertexAttribPointer (uvAttr, 2 , GL_FLOAT , GL_FALSE , sizeof (Vertex), (void const *)offsetof (Vertex, u));
294287 glVertexAttribPointer (tintAttr, 4 , GL_FLOAT , GL_FALSE , sizeof (Vertex), (void const *)offsetof (Vertex, r));
@@ -352,6 +345,7 @@ void r_layer_c::Render()
352345 glUniform1i (texLoc, 0 );
353346 }
354347
348+ size_t vertexCount = 0 ;
355349 std::vector<Batch> batches;
356350 std::vector<BatchKey> batchKeys;
357351 std::map<BatchKey, size_t > batchIndices;
@@ -403,6 +397,7 @@ void r_layer_c::Render()
403397 for (auto idx : indices) {
404398 batch->vertices .push_back (quad[idx]);
405399 }
400+ vertexCount += std::size (indices);
406401 } break ;
407402 case r_layerCmd_s::COLOR :
408403 std::copy_n (cmd->col , 4 , tint);
@@ -431,6 +426,13 @@ void r_layer_c::Render()
431426 showStats = ImGui::CollapsingHeader (heading.c_str (), ImGuiTreeNodeFlags_DefaultOpen);
432427 }
433428 }
429+
430+ GLuint sharedVbo{};
431+ glGenBuffers (1 , &sharedVbo);
432+ glBindBuffer (GL_ARRAY_BUFFER , sharedVbo);
433+ glBufferData (GL_ARRAY_BUFFER , vertexCount * sizeof (Vertex), nullptr , GL_STREAM_DRAW );
434+
435+ size_t vertexBase = 0 ;
434436 for (int i = 0 ; i < numBatches; ++i) {
435437 auto & batch = batches[batchPermutation[i]];
436438 auto & key = batchKeys[batchPermutation[i]];
@@ -485,10 +487,12 @@ void r_layer_c::Render()
485487 key.tex ->Bind ();
486488 }
487489
488- batch.Execute ();
490+ batch.Execute (sharedVbo, vertexBase);
491+ vertexBase += batch.vertices .size ();
489492
490493 lastKey = key;
491494 }
495+ glDeleteBuffers (1 , &sharedVbo);
492496 glUseProgram (0 );
493497 if (renderer->debugLayers ) {
494498 ImGui::End ();
0 commit comments