Tilengine - The 2D retro graphics engine forum

Full Version: [Suggestion] Reziseable window on runtime, limited FPS, and shaders
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hi, I hope you're fine
I have a suggestion for the engine. We can change the size of the window to 1x, 2x, 3x, 4x and 5x. But as far as I know, we cannot change the size on runtime. Is it possible to do this? If yes, it would be a nice idea to have this feature.

Another suggestion is being able to limit FPS on Tilengine. VSync is nice, but the problem is some people (me for example) have a screen with an higher refresh rate (my screen is 144Hz), so, the game will run faster. I can limit the FPS manually with something like sleep(); but wouldn't the frame callback still be affected by the refresh rate?

I also have another question. Is it possible to use a shader with Tilengine (since SDL2 supports shaders) or do I have to use Tilengine as a slave renderer, then use the raw pixel data generated by Tilengine as a texture?

Thanks a lot for your answers!
Hi!

I'm fine, thanks :-) hope you too.

1. Window resizing: It could be possible to change the window at runtime, of course. I limited the ability to dinamically resize it in order to keep consistent integer scaling. Pixel art doesn't play well with arbitrary scaling. The only exception is fullscreen scaling, where non-integer scaling happens. This gets mitigated by the use of CRT post-processing. Talking about CRT effect, the overlay texture gets built for whatever resolution the window is using. Should I add dinamyc resizing, the current overlay would be kept during resizing until releasing the mouse button, where the new overlay would be built. Rebuilding it in realtime for each mouse event during drag would be overkill.

2. Framerate limiting. This feature has been already mentioned in the past, but it can be tricky. Let me explain. In modern 3D games, keyframed animation uses natural time as pacekeeping (milliseconds), and the game engine interpolates intermediate frames in realtime. So having different refresh rates is quite trivial, as the source material is expressed in time, not frames. However, hand-drawn pixel art has a finite set of discrete frames that have been pre-drawn with a specific frame-rate in mind. Game logic usually has the frame as the basic unit of pacekeeping, not time. Like "set sprite animation and keep it 4 frames before setting the next one" instead of "delay 66.6666 ms". This leads to smooth, predictable animation speed at the cost of flexibility. Pacekeeping with time instead of frame is possible, but it will lead to jerky animation, as rounding time to the nearest frame won't get integer results, and rounding errors will translate to uneven frame rate.

Sure I could add a mechanism to set a target frame-rate for animations so the engine would delay or skip frames as needed. But the main issue is that Tilengine only handles graphics, but the game logic itself, implemented on the application layer, should be variable frame-rate-aware, too. Your game character can't have the speed expressed in pixels/frame, for example. So it's not just a problem on the graphics side, but of the game implementation in general.

3. Shaders. SDL2 doesn't support shaders per se, it's the underlying OpenGL context that allows you to play with them. For built-in window rendering I  use basic SDL2 primitives, not direct OpenGL access. Of course you could implement a Window.c replacement that uses GLSL shaders instead of SDL2 primitives. But I find much more convenient to just ship the game bundled with reshade with just crt-lottes shader included and configured for whatever resolution your framebuffer uses. Have you tried it?
(04-05-2023, 01:05 AM)megamarc Wrote: [ -> ]Hi!

I'm fine, thanks :-) hope you too.

1. Window resizing: It could be possible to change the window at runtime, of course. I limited the ability to dinamically resize it in order to keep consistent integer scaling. Pixel art doesn't play well with arbitrary scaling. The only exception is fullscreen scaling, where non-integer scaling happens. This gets mitigated by the use of CRT post-processing. Talking about CRT effect, the overlay texture gets built for whatever resolution the window is using. Should I add dinamyc resizing, the current overlay would be kept during resizing until releasing the mouse button, where the new overlay would be built. Rebuilding it in realtime for each mouse event during drag would be overkill.

2. Framerate limiting. This feature has been already mentioned in the past, but it can be tricky. Let me explain. In modern 3D games, keyframed animation uses natural time as pacekeeping (milliseconds), and the game engine interpolates intermediate frames in realtime. So having different refresh rates is quite trivial, as the source material is expressed in time, not frames. However, hand-drawn pixel art has a finite set of discrete frames that have been pre-drawn with a specific frame-rate in mind. Game logic usually has the frame as the basic unit of pacekeeping, not time. Like "set sprite animation and keep it 4 frames before setting the next one" instead of "delay 66.6666 ms". This leads to smooth, predictable animation speed at the cost of flexibility. Pacekeeping with time instead of frame is possible, but it will lead to jerky animation, as rounding time to the nearest frame won't get integer results, and rounding errors will translate to uneven frame rate.

Sure I could add a mechanism to set a target frame-rate for animations so the engine would delay or skip frames as needed. But the main issue is that Tilengine only handles graphics, but the game logic itself, implemented on the application layer, should be variable frame-rate-aware, too. Your game character can't have the speed expressed in pixels/frame, for example. So it's not just a problem on the graphics side, but of the game implementation in general.

3. Shaders. SDL2 doesn't support shaders per se, it's the underlying OpenGL context that allows you to play with them. For built-in window rendering I  use basic SDL2 primitives, not direct OpenGL access. Of course you could implement a Window.c replacement that uses GLSL shaders instead of SDL2 primitives. But I find much more convenient to just ship the game bundled with reshade with just crt-lottes shader included and configured for whatever resolution your framebuffer uses. Have you tried it?

Hi!
For Windows resizing, it can be limited to integer scale only. I suggested that because it would be quite weird if when the user wants to change the size of the window, he has to restart the game because the resize is not effective on runtime. (I think you can encapsulate the window loop in another infinite loop and then recreate a window. It is still an option.)

The reason I mentionned target framerates is because some people have 144Hz monitors, some others 90Hz, or it can even be 30Hz. So the game won't rune at a consistant speed depending on the monitors. This is why it would be nice to process the game 60 times per seconds, no matter what.

For shaders, I tried to use Tilengine as a slave renderer on Raylib, and it works very well. I have easy to use shaders and window resize at runtime. The only sad thing is you lose the Tilengine's CRT and color bleeding effect (the effect that removes dithering). Another problem are shaders that are made of multiple files. Thoses are not trivial to implement.
About slave rendering, I think a found a bug. It generates a BGRA frame buffer instead of RGBA. The red and blue values are swapped. Maybe an endianess error?