Skip to content

Commit 4f85d98

Browse files
committed
Fix scissor
1 parent b9f15d9 commit 4f85d98

1 file changed

Lines changed: 16 additions & 1 deletion

File tree

Sources/ObjectivelyGPU/RenderPass.c

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@ static void dealloc(Object *self) {
4141
SDL_EndGPURenderPass(this->pass);
4242
}
4343

44+
if (this->commands) {
45+
this->commands->pass = NULL;
46+
}
47+
4448
super(Object, self, dealloc);
4549
}
4650

@@ -195,7 +199,18 @@ static void setBlendConstants(RenderPass *self, SDL_FColor blendConstants) {
195199
static void setScissor(RenderPass *self, const SDL_Rect *scissor) {
196200

197201
if (scissor) {
198-
self->scissor = *scissor;
202+
// Clamp to the render target bounds: a scissor that extends past the edge
203+
// (e.g. a view dragged partly offscreen) is invalid to SDL and would drop
204+
// the whole draw. Clamp each edge against the viewport, then subtract back
205+
// so w/h never exceed the space remaining from the clamped origin. A fully
206+
// offscreen scissor collapses to zero w/h, scissoring out the draw.
207+
// 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);
213+
self->scissor = (SDL_Rect) { .x = x, .y = y, .w = r - x, .h = b - y };
199214
} else {
200215
// Reset to the full render target. RenderPass does not yet capture the
201216
// target dimensions, so fall back to the current viewport, which the

0 commit comments

Comments
 (0)