cfyzium / bearlibterminal

Interface library for applications with text-based console-like output
Other
119 stars 18 forks source link

Migration to SDL #9

Open cfyzium opened 3 years ago

cfyzium commented 3 years ago

It has to be done. A featherweight built-in platform support is cool until you have to maintain it. OpenGL ES alongside usual OpenGL, Wayland finally shaping up, ARM popularity rising, etc., homebrew support for the multitude of platforms quickly becomes impractical.

(Apparently anything that happens on a feature branch stays almost invisible to the public.)

cfyzium commented 3 years ago

Directly porting the windowing code to SDL is fairly easy (61fa226). There are a few moments to check, e. g. the scaling bug on macOS that has finally set this in motion, but overall there should not be any significant problems.

Integrating SDL into the build process (where and which version to take, corresponding build instructions), packaging (bundling dependencies with runtime paths and other platform-specific stuff) and use of the library (from package management to drop-in inclusion into the project, including the case when application directly or indirectly links to another SDL) may require a bit more thought. I think I'll include SDL into BearLibTerminal binary (i. e. link statically) and rely on SDL's DynAPI for any cases when built-in version may not be optimal.

cfyzium commented 3 years ago

Finally got my hands on macOS and turns out the HiDPI mode does not work without a retina display. When using a regular display (e. g. a FullHD one) macOS does not present HiDPI options in settings, and simply selecting a lower screen resolution just scales the entire output.

The next thing I've found out is that macOS and iOS are pretty much the only platforms that SDL2 has HiDPI support for =/.

Okay, who else had an impression that SDL2 would just magically solve the scaling issue in a cross-platform way? =)

By the way, I get the feeling Windows 10 with moderate scaling (e. g. 125% or 150%) might be an even more frequent case than macOS with retina. Although almost any recent Apple device has retina display, there are still much more Windows PCs and high resolution displays became the norm recently.

Windows 10 high-DPI support API seems to be quite good (way more sane than in X11 and more flexible than in macOS) so I am somewhat confident I'll able to add a support for it on the "client side" even if SDL2 will drag it out.

cfyzium commented 3 years ago

The viewport/scene scaling code has been refactored (0975c4d) to take into account possible system and user scaling factors. At the low level the library has to use three coordinate units:

Simply calculating and applying these ratios correctly is enough to fix the most glaring bug with scene occupying only a portion of the whole window. However that obviously won't let the library take any advantage of the high-DPI mode.

Actually, by default the output may even look slightly worse on retina displays because of the most trivial scaling algorithm being used. A 8x16 glyph will be drawn 16x32 physical pixels in size using the OpenGL linear texture interpolation, thus lowering the quality. Linear interpolation is better than nothing in general, but in case of retina display with integer upscaling ratio it would be better to disable the interpolation (it is only possible to do manually right now, by pressing Alt+F).

In case of non-retina but still high-DPI displays (e. g. 125% or 150% scaling) everything will lose some quality, with or without OpenGL interpolation. A better interpolation filter should improve the quality but it is almost impossible to perfectly upscale anything by an arbitrary non-integer factor.

hero-clashes commented 2 years ago

I think porting it to raylib would be easier and better if there any interest hit me up

andrewgasson commented 2 years ago

I think porting it to raylib would be easier and better if there any interest hit me up

Last I checked (a few months ago), Raylib's game loop consumes a lot of CPU when "idle" because EndDrawing() is also in charge of handling the end of the current game loop, basically forcing you to redraw every loop, and then it does an inefficient sleep. SDL is still the better, more performant choice and is just as easy to implement.

Pretty sure Raylib still has those same high-DPI display issues as well, doesn't it?

hero-clashes commented 2 years ago

I think porting it to raylib would be easier and better if there any interest hit me up

Last I checked (a few months ago), Raylib's game loop consumes a lot of CPU when "idle" because EndDrawing() is also in charge of handling the end of the current game loop, basically forcing you to redraw every loop, and then it does an inefficient sleep. SDL is still the better, more performant choice and is just as easy to implement.

Pretty sure Raylib still has those same high-DPI display issues as well, doesn't it?

yeah I think raylib have couple issues with high-DPI display, but I am not sure about the EndDrawing() but I know you can set the fps limit before