Skip to content

Commit 4803e40

Browse files
committed
Build a single shared vertex buffer for all draws
1 parent 15c9cc1 commit 4803e40

1 file changed

Lines changed: 20 additions & 16 deletions

File tree

engine/render/r_main.cpp

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -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

246245
Batch::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

255253
Batch::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

266262
Batch& 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

Comments
 (0)