Skip to content

sdl2-compat SDL_RenderSetScale not compatible with SDL2 #425

@LordOfTrident

Description

@LordOfTrident

In my game, I draw a menu background, and then a menu overlay with a scale up/down animation using SDL_RenderSetScale:

	Rect viewport = Rect_new(CANVAS_X, CANVAS_Y, CANVAS_W, CANVAS_H);
	setViewport(viewport);

	SDL_SetRenderDrawColor(core.ren, 0, 0, 0, state.darken);
	SDL_RenderFillRect(core.ren, NULL);

	setViewport(Rect_lerpSize(viewport, state.scale));
	SDL_RenderSetScale(core.ren, state.scale, state.scale);
        ...

setViewport directly calls SDL_RenderSetViewport with the global renderer.

On original SDL2, this code worked fine. The menu background got rendered with regular scale and then the overlay with a scaling animation. With sdl2-compat, it seems to apply the SDL_RenderSetScale call to everything rendered in that frame, instead of only the subsequent render calls.

Expected outcome (with original SDL2):

demo.mp4

What I get with sdl2-compat:

2025-03-23.16-08-47.mp4

Activity

added this to the 2.32.54 milestone on Mar 23, 2025
icculus

icculus commented on Mar 29, 2025

@icculus
Collaborator

This is significantly better with the latest in revision control, but it's not perfect yet.

You can see that the menu looks like it's sliding in/out to the top/left. In SDL2, it scales from the center. Maybe the viewport is getting reset unexpectedly.

Screencast.from.2025-03-28.21-51-43.webm

Most of the fix was SDL_SetRenderTarget() not resetting viewport/scaling/etc, like SDL2 does. SDL3 lets each texture have its own state, and it isn't reset when setting a new render target.

I'll poke at the last problem some more.

icculus

icculus commented on Mar 30, 2025

@icculus
Collaborator

Okay, in SDL2, SDL_RenderSetViewport() sets a viewport modulated by the current scale, and SDL_RenderSetScale() just sets a new scale for later drawing. In SDL3, SDL_SetRenderViewport() sets a new viewport for later drawing, and SDL_SetRenderScale adjusts the current viewport for the new scale.

Noike's intro_scene.c's render() does this:

	setViewport(Rect_lerpSize(viewport, state.scale));
	SDL_RenderSetScale(core.ren, state.scale, state.scale);

So in SDL2, this sets a new viewport times the current scale (whatever it might be), then changes the current scale. In sdl2-compat, this sets a new viewport, then changes the current viewport and scale.

I haven't done the math to see if this is actually where it's going wrong, but it's a likely culprit.

icculus

icculus commented on Mar 30, 2025

@icculus
Collaborator

Kinda feeling like we're going to run into a million more of these little rendering quirks unless we copy the SDL2 scale/viewport/logicalpresent logic wholesale into sdl2-compat, and never set any of this stuff at the SDL3 level, but that might be a serious nuclear option.

icculus

icculus commented on Mar 31, 2025

@icculus
Collaborator

copy the SDL2 scale/viewport/logicalpresent logic wholesale into sdl2-compat

I think I'm going to take a run at this, but let's ship the milestone before I do, since it's going to be a bigger change, and Noike is now playable with the latest in revision control.

removed this from the 2.32.54 milestone on Mar 31, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

    Development

    No branches or pull requests

      Participants

      @icculus@slouken@LordOfTrident

      Issue actions

        sdl2-compat SDL_RenderSetScale not compatible with SDL2 · Issue #425 · libsdl-org/sdl2-compat