|
5 | 5 | // |
6 | 6 |
|
7 | 7 | #define GLAD_GLES2_IMPLEMENTATION |
| 8 | +#define IMGUI_DEFINE_MATH_OPERATORS |
8 | 9 | #include "r_local.h" |
9 | 10 |
|
10 | 11 | #include <array> |
@@ -218,6 +219,49 @@ void r_layer_c::Quad(double s0, double t0, double x0, double y0, double s1, doub |
218 | 219 | cmd->quad.y[0] = y0; cmd->quad.y[1] = y1; cmd->quad.y[2] = y2; cmd->quad.y[3] = y3; |
219 | 220 | } |
220 | 221 |
|
| 222 | +// ================= |
| 223 | +// Geometric queries |
| 224 | +// ================= |
| 225 | + |
| 226 | +struct r_aabb_s { |
| 227 | + float lo[2]; |
| 228 | + float hi[2]; |
| 229 | +}; |
| 230 | + |
| 231 | +r_aabb_s AabbFromCmdQuad(decltype(r_layerCmd_s::quad)& q, r_viewport_s& vp) |
| 232 | +{ |
| 233 | + r_aabb_s r{ |
| 234 | + {+FLT_MAX, +FLT_MAX}, |
| 235 | + {-FLT_MAX, -FLT_MAX}, |
| 236 | + }; |
| 237 | + for (size_t i = 0; i < 4; ++i) { |
| 238 | + r.lo[0] = (std::min)(r.lo[0], (float)q.x[i]); |
| 239 | + r.lo[1] = (std::min)(r.lo[1], (float)q.y[i]); |
| 240 | + r.hi[0] = (std::max)(r.hi[0], (float)q.x[i]); |
| 241 | + r.hi[1] = (std::max)(r.hi[1], (float)q.y[i]); |
| 242 | + } |
| 243 | + r.lo[0] += vp.x; |
| 244 | + r.lo[1] += vp.y; |
| 245 | + r.hi[0] += vp.x; |
| 246 | + r.hi[1] += vp.y; |
| 247 | + return r; |
| 248 | +} |
| 249 | + |
| 250 | +r_aabb_s AabbFromViewport(r_viewport_s& vp) |
| 251 | +{ |
| 252 | + r_aabb_s r{ |
| 253 | + {(float)vp.x, (float)vp.y }, |
| 254 | + {(float)(vp.x + vp.width), (float)(vp.y + vp.height) }, |
| 255 | + }; |
| 256 | + return r; |
| 257 | +} |
| 258 | + |
| 259 | +bool AabbAabbIntersects(r_aabb_s& a, r_aabb_s& b) |
| 260 | +{ |
| 261 | + // A.lo <= B.hi && A.hi >= B.lo |
| 262 | + return a.lo[0] <= b.hi[0] && a.lo[1] <= b.hi[1] && a.hi[0] >= b.lo[0] && a.hi[1] >= b.lo[1]; |
| 263 | +} |
| 264 | + |
221 | 265 | struct Vertex { |
222 | 266 | float x, y; |
223 | 267 | float u, v; |
@@ -392,6 +436,16 @@ struct AdjacentMergeStrategy : RenderStrategy { |
392 | 436 | // ImGui::Text("QUAD"); |
393 | 437 | } |
394 | 438 |
|
| 439 | + // Cull the quad first before it influences any boundary cuts. |
| 440 | + if (!!renderer_->r_drawCull->intVal) { |
| 441 | + auto a = AabbFromCmdQuad(cmd->quad, nextViewport_); |
| 442 | + auto b = AabbFromViewport(nextViewport_); |
| 443 | + bool intersects = AabbAabbIntersects(a, b); |
| 444 | + if (!intersects) { |
| 445 | + break; |
| 446 | + } |
| 447 | + } |
| 448 | + |
395 | 449 | // If the current batch is incompatible key-wise, dispatch it to get a fresh |
396 | 450 | // batch to grow in. |
397 | 451 | if (!batch_.batch.vertices.empty() && batch_.key != latchKey_) { |
@@ -643,6 +697,7 @@ r_renderer_c::r_renderer_c(sys_IMain* sysHnd) |
643 | 697 | r_layerOptimize = sys->con->Cvar_Add("r_layerOptimize", CV_ARCHIVE | CV_CLAMP, "1", 0, 1); |
644 | 698 | r_layerShuffle = sys->con->Cvar_Add("r_layerShuffle", CV_ARCHIVE | CV_CLAMP, "0", 0, 1); |
645 | 699 | r_elideFrames = sys->con->Cvar_Add("r_elideFrames", CV_ARCHIVE | CV_CLAMP, "1", 0, 1); |
| 700 | + r_drawCull = sys->con->Cvar_Add("r_drawCull", CV_ARCHIVE | CV_CLAMP, "1", 0, 1); |
646 | 701 |
|
647 | 702 | Cmd_Add("screenshot", 0, "[<format>]", this, &r_renderer_c::C_Screenshot); |
648 | 703 | } |
@@ -1142,6 +1197,7 @@ void r_renderer_c::EndFrame() |
1142 | 1197 | ImGui::Text("%d out of %d frames drawn, %d saved.", drawnFrames, totalFrames, savedFrames); |
1143 | 1198 | CVarSliderInt("Optimization", r_layerOptimize); |
1144 | 1199 | CVarCheckbox("Elide identical frames", r_elideFrames); |
| 1200 | + CVarCheckbox("Draw command culling", r_drawCull); |
1145 | 1201 |
|
1146 | 1202 | int totalCmd{}; |
1147 | 1203 | if (ImGui::BeginTable("Layer stats", 5, ImGuiTableFlags_Borders | ImGuiTableFlags_SizingFixedFit)) { |
|
0 commit comments