Skip to content

Commit 08c57d9

Browse files
committed
Use vertex buffers, merge adjacent colored draws
1 parent e307939 commit 08c57d9

1 file changed

Lines changed: 84 additions & 21 deletions

File tree

engine/render/r_main.cpp

Lines changed: 84 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -206,22 +206,84 @@ void r_layer_c::Quad(double s0, double t0, double x0, double y0, double s1, doub
206206
cmd->quad.y[0] = y0; cmd->quad.y[1] = y1; cmd->quad.y[2] = y2; cmd->quad.y[3] = y3;
207207
}
208208

209+
struct Vertex {
210+
float x, y;
211+
float u, v;
212+
float r, g, b, a;
213+
};
214+
215+
struct Batch {
216+
explicit Batch(GLuint prog);
217+
Batch(Batch const&) = delete;
218+
Batch& operator = (Batch const&) = delete;
219+
~Batch();
220+
221+
GLuint prog;
222+
GLint xyAttr;
223+
GLint uvAttr;
224+
GLint tintAttr;
225+
226+
GLuint vbo;
227+
std::vector<Vertex> vertices;
228+
229+
void FlushBatch();
230+
};
231+
232+
Batch::Batch(GLuint prog)
233+
: prog(prog)
234+
{
235+
xyAttr = glGetAttribLocation(prog, "a_vertex");
236+
uvAttr = glGetAttribLocation(prog, "a_texcoord");
237+
tintAttr = glGetAttribLocation(prog, "a_tint");
238+
glGenBuffers(1, &vbo);
239+
}
240+
241+
Batch::~Batch() {
242+
glDeleteBuffers(1, &vbo);
243+
}
244+
245+
void Batch::FlushBatch()
246+
{
247+
if (vertices.empty()) {
248+
return;
249+
}
250+
251+
glBindBuffer(GL_ARRAY_BUFFER, vbo);
252+
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(Vertex), vertices.data(), GL_STREAM_DRAW);
253+
glVertexAttribPointer(xyAttr, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void const*)offsetof(Vertex, x));
254+
glVertexAttribPointer(uvAttr, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void const*)offsetof(Vertex, u));
255+
glVertexAttribPointer(tintAttr, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void const*)offsetof(Vertex, r));
256+
glEnableVertexAttribArray(xyAttr);
257+
glEnableVertexAttribArray(uvAttr);
258+
glEnableVertexAttribArray(tintAttr);
259+
glDrawArrays(GL_TRIANGLES, 0, vertices.size());
260+
glDisableVertexAttribArray(xyAttr);
261+
glDisableVertexAttribArray(uvAttr);
262+
glDisableVertexAttribArray(tintAttr);
263+
glBindBuffer(GL_ARRAY_BUFFER, 0);
264+
vertices.clear();
265+
}
266+
209267
void r_layer_c::Render()
210268
{
211269
r_viewport_s curViewPort = { -1, -1, -1, -1 };
212270
int curBlendMode = -1;
213271
r_tex_c* curTex = NULL;
214272
GLuint prog = renderer->tintedTextureProgram;
273+
float tint[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
215274
glUseProgram(prog);
216275
{
217-
GLint tintLoc = glGetUniformLocation(prog, "i_tint");
218-
glUniform4f(tintLoc, 1.0f, 1.0f, 1.0f, 1.0f);
276+
GLint texLoc = glGetUniformLocation(prog, "t_tex");
277+
glUniform1i(texLoc, 0);
219278
}
279+
Batch batch{ prog };
280+
220281
for (int i = 0; i < numCmd; i++) {
221282
r_layerCmd_s* cmd = cmdList[i];
222283
switch (cmd->cmd) {
223284
case r_layerCmd_s::VIEWPORT:
224285
if (cmd->viewport.x != curViewPort.x || cmd->viewport.y != curViewPort.y || cmd->viewport.width != curViewPort.width || cmd->viewport.height != curViewPort.height) {
286+
batch.FlushBatch();
225287
auto& vid = renderer->sys->video->vid;
226288
float fbScaleX = vid.fbSize[0] / (float)vid.size[0];
227289
float fbScaleY = vid.fbSize[1] / (float)vid.size[1];
@@ -237,6 +299,7 @@ void r_layer_c::Render()
237299
break;
238300
case r_layerCmd_s::BLEND:
239301
if (cmd->blendMode != curBlendMode) {
302+
batch.FlushBatch();
240303
switch (cmd->blendMode) {
241304
case RB_ALPHA:
242305
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
@@ -252,37 +315,32 @@ void r_layer_c::Render()
252315
break;
253316
case r_layerCmd_s::BIND:
254317
if (cmd->tex != curTex) {
318+
batch.FlushBatch();
255319
cmd->tex->Bind();
256320
curTex = cmd->tex;
257321
}
258322
break;
259323
case r_layerCmd_s::QUAD: {
260-
struct Vertex {
261-
float x, y;
262-
float u, v;
263-
};
264324
Vertex quad[4];
265325
for (int v = 0; v < 4; v++) {
266326
quad[v].u = (float)cmd->quad.s[v];
267327
quad[v].v = (float)cmd->quad.t[v];
268328
quad[v].x = (float)cmd->quad.x[v];
269329
quad[v].y = (float)cmd->quad.y[v];
330+
quad[v].r = tint[0];
331+
quad[v].g = tint[1];
332+
quad[v].b = tint[2];
333+
quad[v].a = tint[3];
334+
}
335+
// 3 2
336+
// 0 1
337+
size_t indices[] = { 0, 1, 2, 0, 2, 3 };
338+
for (auto idx : indices) {
339+
batch.vertices.push_back(quad[idx]);
270340
}
271-
GLint texLoc = glGetUniformLocation(prog, "t_tex");
272-
glUniform1i(texLoc, 0);
273-
int xyAttr = glGetAttribLocation(prog, "a_vertex");
274-
int uvAttr = glGetAttribLocation(prog, "a_texcoord");
275-
glVertexAttribPointer(xyAttr, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), offsetof(Vertex, x) + (char const*)quad);
276-
glVertexAttribPointer(uvAttr, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), offsetof(Vertex, u) + (char const*)quad);
277-
glEnableVertexAttribArray(xyAttr);
278-
glEnableVertexAttribArray(uvAttr);
279-
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
280-
glDisableVertexAttribArray(xyAttr);
281-
glDisableVertexAttribArray(uvAttr);
282341
} break;
283342
case r_layerCmd_s::COLOR: {
284-
GLint tintLoc = glGetUniformLocation(prog, "i_tint");
285-
glUniform4fv(tintLoc, 1, cmd->col);
343+
std::copy_n(cmd->col, 4, tint);
286344
} break;
287345
}
288346
if (renderer->layerCmdBinCount == renderer->layerCmdBinSize) {
@@ -291,6 +349,8 @@ void r_layer_c::Render()
291349
}
292350
renderer->layerCmdBin[renderer->layerCmdBinCount++] = cmd;
293351
}
352+
// Draw the last batch
353+
batch.FlushBatch();
294354
glUseProgram(0);
295355
numCmd = 0;
296356
}
@@ -357,12 +417,15 @@ uniform mat4 mvp_matrix;
357417
358418
attribute vec2 a_vertex;
359419
attribute vec2 a_texcoord;
420+
attribute vec4 a_tint;
360421
361422
varying vec2 v_texcoord;
423+
varying vec4 v_tint;
362424
363425
void main(void)
364426
{
365427
v_texcoord = a_texcoord;
428+
v_tint = a_tint;
366429
gl_Position = mvp_matrix * vec4(a_vertex, 0.0, 1.0);
367430
}
368431
)";
@@ -374,12 +437,12 @@ uniform sampler2D t_tex;
374437
uniform vec4 i_tint;
375438
376439
varying vec2 v_texcoord;
440+
varying vec4 v_tint;
377441
378442
void main(void)
379443
{
380444
vec4 color = texture2D(t_tex, v_texcoord);
381-
// color = vec4(1.0, 1.0, 1.0, 1.0);
382-
gl_FragColor = color * i_tint;
445+
gl_FragColor = color * v_tint;
383446
}
384447
)";
385448

0 commit comments

Comments
 (0)