@@ -222,6 +222,7 @@ struct Vertex {
222222 float x, y;
223223 float u, v;
224224 float r, g, b, a;
225+ float viewX, viewY, viewW, viewH;
225226 float texId;
226227};
227228
@@ -238,6 +239,7 @@ struct Batch {
238239 GLint uvAttr;
239240 GLint tintAttr;
240241 GLint texIdAttr;
242+ GLint viewportAttr;
241243
242244 std::vector<Vertex> vertices;
243245
@@ -251,13 +253,15 @@ Batch::Batch(GLuint prog)
251253 uvAttr = glGetAttribLocation (prog, " a_texcoord" );
252254 tintAttr = glGetAttribLocation (prog, " a_tint" );
253255 texIdAttr = glGetAttribLocation (prog, " a_texId" );
256+ viewportAttr = glGetAttribLocation (prog, " a_viewport" );
254257}
255258
256259Batch::Batch (Batch&& rhs)
257260 : prog(rhs.prog)
258261 , xyAttr(rhs.xyAttr)
259262 , uvAttr(rhs.uvAttr)
260263 , tintAttr(rhs.tintAttr)
264+ , viewportAttr(rhs.viewportAttr)
261265 , vertices(std::move(rhs.vertices))
262266{
263267}
@@ -267,6 +271,8 @@ Batch& Batch::operator = (Batch&& rhs) {
267271 xyAttr = rhs.xyAttr ;
268272 uvAttr = rhs.uvAttr ;
269273 tintAttr = rhs.tintAttr ;
274+ texIdAttr = rhs.texIdAttr ;
275+ viewportAttr = rhs.viewportAttr ;
270276 vertices = std::move (rhs.vertices );
271277
272278 return *this ;
@@ -289,15 +295,18 @@ void Batch::Execute(GLuint sharedVbo, size_t vertexBase)
289295 glVertexAttribPointer (uvAttr, 2 , GL_FLOAT , GL_FALSE , sizeof (Vertex), (void const *)offsetof (Vertex, u));
290296 glVertexAttribPointer (tintAttr, 4 , GL_FLOAT , GL_FALSE , sizeof (Vertex), (void const *)offsetof (Vertex, r));
291297 glVertexAttribPointer (texIdAttr, 1 , GL_FLOAT , GL_FALSE , sizeof (Vertex), (void const *)offsetof (Vertex, texId));
298+ glVertexAttribPointer (viewportAttr, 4 , GL_FLOAT , GL_FALSE , sizeof (Vertex), (void const *)offsetof (Vertex, viewX));
292299 glEnableVertexAttribArray (xyAttr);
293300 glEnableVertexAttribArray (uvAttr);
294301 glEnableVertexAttribArray (tintAttr);
295302 glEnableVertexAttribArray (texIdAttr);
303+ glEnableVertexAttribArray (viewportAttr);
296304 glDrawArrays (GL_TRIANGLES , 0 , (GLsizei)vertices.size ());
297305 glDisableVertexAttribArray (xyAttr);
298306 glDisableVertexAttribArray (uvAttr);
299307 glDisableVertexAttribArray (tintAttr);
300308 glDisableVertexAttribArray (texIdAttr);
309+ glDisableVertexAttribArray (viewportAttr);
301310 glBindBuffer (GL_ARRAY_BUFFER , 0 );
302311 vertices.clear ();
303312}
@@ -340,22 +349,9 @@ struct AdjacentMergeStrategy : RenderStrategy {
340349 }
341350
342351 struct BatchKey {
343- r_viewport_s viewport = { -1 , -1 , -1 , -1 };
344352 int blendMode = -1 ;
345353
346354 bool operator < (BatchKey const & rhs) const {
347- if (viewport.x != rhs.viewport .x ) {
348- return viewport.x < rhs.viewport .x ;
349- }
350- if (viewport.y != rhs.viewport .y ) {
351- return viewport.y < rhs.viewport .y ;
352- }
353- if (viewport.width != rhs.viewport .width ) {
354- return viewport.width < rhs.viewport .width ;
355- }
356- if (viewport.height != rhs.viewport .height ) {
357- return viewport.height < rhs.viewport .height ;
358- }
359355 return blendMode < rhs.blendMode ;
360356 }
361357
@@ -371,7 +367,7 @@ struct AdjacentMergeStrategy : RenderStrategy {
371367 void ProcessCommand (r_layerCmd_s* cmd) override {
372368 switch (cmd->cmd ) {
373369 case r_layerCmd_s::VIEWPORT :
374- latchKey_. viewport = cmd->viewport ;
370+ nextViewport_ = cmd->viewport ;
375371 if (showStats_) {
376372 // ImGui::Text("VIEWPORT: %dx%d @ %d,%d", cmd->viewport.width, cmd->viewport.height, cmd->viewport.x, cmd->viewport.y);
377373 }
@@ -421,15 +417,21 @@ struct AdjacentMergeStrategy : RenderStrategy {
421417
422418 Vertex quad[4 ];
423419 for (int v = 0 ; v < 4 ; v++) {
424- quad[v].u = (float )cmd->quad .s [v];
425- quad[v].v = (float )cmd->quad .t [v];
426- quad[v].x = (float )cmd->quad .x [v];
427- quad[v].y = (float )cmd->quad .y [v];
428- quad[v].r = tint_[0 ];
429- quad[v].g = tint_[1 ];
430- quad[v].b = tint_[2 ];
431- quad[v].a = tint_[3 ];
432- quad[v].texId = (float )texSlot;
420+ auto & q = quad[v];
421+ auto & vp = nextViewport_;
422+ q.u = (float )cmd->quad .s [v];
423+ q.v = (float )cmd->quad .t [v];
424+ q.x = (float )cmd->quad .x [v];
425+ q.y = (float )cmd->quad .y [v];
426+ q.r = tint_[0 ];
427+ q.g = tint_[1 ];
428+ q.b = tint_[2 ];
429+ q.a = tint_[3 ];
430+ q.texId = (float )texSlot;
431+ q.viewX = (float )vp.x ;
432+ q.viewY = (float )vp.y ;
433+ q.viewW = (float )vp.width ;
434+ q.viewH = (float )vp.height ;
433435 }
434436 // 3-2
435437 // |/|
@@ -468,23 +470,15 @@ struct AdjacentMergeStrategy : RenderStrategy {
468470 ImGui::Text (" Batch %d" , batchIndex);
469471 ImGui::Text (" %d verts" , batch.vertices .size ());
470472 }
471- if (!lastKey || lastKey->viewport .x != key.viewport .x || lastKey->viewport .y != key.viewport .y ||
472- lastKey->viewport .width != key.viewport .width || lastKey->viewport .height != key.viewport .height )
473+
473474 {
474- if (showStats_) {
475- ImGui::Text (" New viewport %dx%d @ %d,%d" ,
476- key.viewport .width , key.viewport .height , key.viewport .x , key.viewport .y );
477- }
478475 auto & vid = renderer_->sys ->video ->vid ;
479476 float fbScaleX = vid.fbSize [0 ] / (float )vid.size [0 ];
480477 float fbScaleY = vid.fbSize [1 ] / (float )vid.size [1 ];
478+ int virtualW = renderer_->VirtualScreenWidth ();
481479 int virtualH = renderer_->VirtualScreenHeight ();
482- float x = key.viewport .x * fbScaleX;
483- float y = (virtualH - key.viewport .y - key.viewport .height ) * fbScaleY;
484- float width = key.viewport .width * fbScaleX;
485- float height = key.viewport .height * fbScaleY;
486- glViewport ((int )x, (int )y, (int )width, (int )height);
487- Mat4 mvpMatrix = OrthoMatrix (0 , key.viewport .width , key.viewport .height , 0 , -9999 , 9999 );
480+ glViewport (0 , 0 , virtualW, virtualH);
481+ Mat4 mvpMatrix = OrthoMatrix (0 , virtualW, virtualH, 0 , -9999 , 9999 );
488482 glUniformMatrix4fv (mvpMatrixLoc_, 1 , GL_FALSE , mvpMatrix.data ());
489483 }
490484 if (!lastKey || lastKey->blendMode != key.blendMode ) {
@@ -552,6 +546,7 @@ struct AdjacentMergeStrategy : RenderStrategy {
552546 };
553547
554548 BatchKey latchKey_{};
549+ r_viewport_s nextViewport_{};
555550 r_tex_c* nextTex_{};
556551 std::optional<BatchKey> lastDispatchKey_;
557552 TexturedBatch batch_;
@@ -645,7 +640,7 @@ r_renderer_c::r_renderer_c(sys_IMain* sysHnd)
645640 r_compress = sys->con ->Cvar_Add (" r_compress" , CV_ARCHIVE , " 0" );
646641 r_screenshotFormat = sys->con ->Cvar_Add (" r_screenshotFormat" , CV_ARCHIVE , " jpg" );
647642 r_layerDebug = sys->con ->Cvar_Add (" r_layerDebug" , CV_ARCHIVE , " 0" );
648- r_layerOptimize = sys->con ->Cvar_Add (" r_layerOptimize" , CV_ARCHIVE | CV_CLAMP , " 0 " , 0 , 2 );
643+ r_layerOptimize = sys->con ->Cvar_Add (" r_layerOptimize" , CV_ARCHIVE | CV_CLAMP , " 1 " , 0 , 1 );
649644 r_layerShuffle = sys->con ->Cvar_Add (" r_layerShuffle" , CV_ARCHIVE | CV_CLAMP , " 0" , 0 , 1 );
650645 r_elideFrames = sys->con ->Cvar_Add (" r_elideFrames" , CV_ARCHIVE | CV_CLAMP , " 1" , 0 , 1 );
651646
@@ -692,17 +687,27 @@ attribute vec2 a_vertex;
692687attribute vec2 a_texcoord;
693688attribute vec4 a_tint;
694689attribute float a_texId;
690+ attribute vec4 a_viewport;
695691
692+ varying vec2 v_screenPos;
696693varying vec2 v_texcoord;
697694varying vec4 v_tint;
698695varying float v_texId;
696+ varying vec4 v_viewport;
699697
700698void main(void)
701699{
702700 v_texcoord = a_texcoord;
703701 v_tint = a_tint;
704702 v_texId = a_texId;
705- gl_Position = mvp_matrix * vec4(a_vertex, 0.0, 1.0);
703+ vec2 vp0 = a_viewport.xy + vec2(0.0, a_viewport.w);
704+ vec2 vp1 = a_viewport.xy + vec2(a_viewport.z, 0.0);
705+ v_viewport = vec4(
706+ (mvp_matrix * vec4(vp0, 0.0, 1.0)).xy,
707+ (mvp_matrix * vec4(vp1, 0.0, 1.0)).xy);
708+ vec4 pos = mvp_matrix * vec4(a_vertex + a_viewport.xy, 0.0, 1.0);
709+ v_screenPos = pos.xy;
710+ gl_Position = pos;
706711}
707712)" ;
708713
@@ -712,12 +717,21 @@ precision mediump float;
712717uniform sampler2D s_tex[{SG_TEXTURE_COUNT}];
713718uniform vec4 i_tint;
714719
720+ varying vec2 v_screenPos;
715721varying vec2 v_texcoord;
716722varying vec4 v_tint;
717723varying float v_texId;
724+ varying vec4 v_viewport; // x0, y0, x1, y1
718725
719726void main(void)
720727{{
728+ float x = v_screenPos[0], y = v_screenPos[1];
729+ if (x < v_viewport[0] ||
730+ y < v_viewport[1] ||
731+ x >= v_viewport[2] ||
732+ y >= v_viewport[3]) {{
733+ discard;
734+ }}
721735 vec4 color;
722736 {SG_TEXTURE_SWITCH}
723737 gl_FragColor = color * v_tint;
0 commit comments