Skip to content

Commit 2e59603

Browse files
committed
Fix scissor test to be relative to viewport.
1 parent fbfc4d0 commit 2e59603

1 file changed

Lines changed: 11 additions & 5 deletions

File tree

Sources/ObjectivelyGPU/RenderPass.c

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -205,11 +205,17 @@ static void setScissor(RenderPass *self, const SDL_Rect *scissor) {
205205
// so w/h never exceed the space remaining from the clamped origin. A fully
206206
// offscreen scissor collapses to zero w/h, scissoring out the draw.
207207
// RenderPass does not yet capture the target dimensions, so the viewport
208-
// (which the caller is expected to have set) stands in for them.
209-
const int x = SDL_clamp(scissor->x, 0, (int) self->viewport.w);
210-
const int y = SDL_clamp(scissor->y, 0, (int) self->viewport.h);
211-
const int r = SDL_clamp(scissor->x + scissor->w, 0, (int) self->viewport.w);
212-
const int b = SDL_clamp(scissor->y + scissor->h, 0, (int) self->viewport.h);
208+
// (which the caller is expected to have set) stands in for them. The bounds
209+
// are relative to the viewport *origin*, not (0, 0): a viewport offset into
210+
// the target (e.g. shadow atlas tiles) must not collapse the scissor.
211+
const int vx = (int) self->viewport.x;
212+
const int vy = (int) self->viewport.y;
213+
const int vw = (int) self->viewport.w;
214+
const int vh = (int) self->viewport.h;
215+
const int x = SDL_clamp(scissor->x, vx, vx + vw);
216+
const int y = SDL_clamp(scissor->y, vy, vy + vh);
217+
const int r = SDL_clamp(scissor->x + scissor->w, vx, vx + vw);
218+
const int b = SDL_clamp(scissor->y + scissor->h, vy, vy + vh);
213219
self->scissor = (SDL_Rect) { .x = x, .y = y, .w = r - x, .h = b - y };
214220
} else {
215221
// Reset to the full render target. RenderPass does not yet capture the

0 commit comments

Comments
 (0)