Hi all,
first of all, I apologize in advance if (or better when!) I’ll be using the wrong terminology: I’m not a game developer, and have only recently started playing with SDL2 to write a game engine for fun, so there’s good chances that I’ll describe my issues and attempted solutions poorly. In case there’s better ways to address things, please do let me know, as this is all part of a learning process for me!
As I was saying, I’m using SDL2 to write a game engine, specifically an open source point and click adventure engine called KIAVC. I only started a few months ago, and so far it’s been a great experience, since SDL2 definitely made a lot of things easy for me to handle. I did bump into a couple of obstacles when dealing with scaling, though, so I thought I’d ask the community about it.
Specifically, the demo I’m working on uses a lowres canvas (320x180) that I then scale up programmatically (it can be changed dynamically) as far as the actual window is concerned. By default, the demo enforces a 4x scale factor, which results in an actual 1280x720 resolution. Initially I took care of this scaling manually, using SDL_Rect accordingly, but then I found out about SDL_SetLogicalSize which did make all that much easier for me (I only had to scale mouse clicks accordingly, since unlike motion events those seem to refer to the actual resolution and not the logical one).
This works fine, but I’m encountering issues when it comes to scale the characters (actors, in my engine) I show on screen, which again can happen dynamically (e.g., character working towards the horizon). With a 4x scale factor and a small logical size, everything looks intentionally “blocky”, since pixels are basically 4x4 rather than 1x1, as most pixel-art games do: scaling a character down, though, this assumption seems to be broken, since they become more defined, as they’ll be rendered with pixels that are smaller than the 4x4 pixels everything else is rendered at. I guess this makes sense since SDL_SetLogicalSize under the curtain seems to only use viewports and SDL_rect to do its job (so basically what I was doing manually before), but that’s still a bummer, as it breaks the pixel-art-y nature of the game.
An example is presented in the image below, where I scaled the main actor at 0.20 of its actual size to demonstrate the problem: as you can see, it’s much more defined than everything else, since the scaling is taking into account the actual resolution (1280x720) rather than the logical one (320x180), despite me passing the logical scaled-down resolution in SDL_Rect object when calling SDL_RenderCopy.
Assuming this is the intended behaviour, is there any way to circumvent that? Is this something that SDL_SetRenderScale can help with? (I assume not, since from the documentation it looks like SDL_SetLogicalSize already uses it internally) Am I forced to make copies of the textures at different scale factors myself and then render those? This is something I’d rather avoid, since scaling can happen progressively in the engine, and this would force me to continually create/destroy textures as scaling occurs, possibly with additional reference counting since the same “costume” (animations) can be assigned to different actors in my engine, and these actors may be scaled differently or not, as part of their role in the game. I’m not sure how this is usually dealt with.
I have a few other doubts related to SDL_SetLogicalSize, but I’ll create different topics for them in the next few days: at the moment this is the main issue I’m trying to address.
Thanks in advance for any help or feedback you’ll be able to provide, and apologies again if I did a terrible job of explaining what I’ve been doing and what I’m struggling with