@@ -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+
209267void 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
358418attribute vec2 a_vertex;
359419attribute vec2 a_texcoord;
420+ attribute vec4 a_tint;
360421
361422varying vec2 v_texcoord;
423+ varying vec4 v_tint;
362424
363425void 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;
374437uniform vec4 i_tint;
375438
376439varying vec2 v_texcoord;
440+ varying vec4 v_tint;
377441
378442void 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