Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SDL_gfx: Circle radius greater than 1023 results in deformation #272

Open
atomicdad opened this issue Oct 24, 2023 · 1 comment
Open

SDL_gfx: Circle radius greater than 1023 results in deformation #272

atomicdad opened this issue Oct 24, 2023 · 1 comment

Comments

@atomicdad
Copy link

I don't know if this is the correct place to bring up this issue...partially because I don't know the exact cause. It looks like the pysdl2-dll package uses version 1.0.4 of the SDL_gfx library, but I don't know exactly how to confirm this. I say this because the change log at https://www.ferzkopp.net/wordpress/2016/01/02/sdl_gfx-sdl2_gfx/ shows a fix in 1.0.4 for large radius values resulting in an int overflow. I'm not sure if this is related or not.

import sdl2
import sdl2.sdlgfx
import sdl2.ext


def run():

    sdl2.ext.init()
    window = sdl2.ext.Window("circle test", size=(1700, 900))
    window.show()

    if "-hardware" in sys.argv:
        renderflags = sdl2.render.SDL_RENDERER_ACCELERATED | sdl2.render.SDL_RENDERER_PRESENTVSYNC
    else:
        renderflags = sdl2.render.SDL_RENDERER_SOFTWARE
    context = sdl2.ext.Renderer(window, flags=renderflags)

    color = 0xFFFFFFFF
    x, y = -400, 450
    r = 1023
    sdl2.sdlgfx.circleColor(context.sdlrenderer, x, y, r, color)
    x, y = 0, 450
    r = 1024
    sdl2.sdlgfx.circleColor(context.sdlrenderer, x, y, r, color)
    
    context.present()
    running = True
    while running:
        events = sdl2.ext.get_events()
        for event in events:
            if event.type == sdl2.SDL_QUIT:
                running = False
                break
    sdl2.ext.quit()
    return 0


if __name__ == "__main__":
    sys.exit(run())
  • OS: Windows 10 64-bit
  • Python Version: 3.11
  • PySDL2 Version: 0.9.16
  • Using pysdl2-dll: Yes

Here is an image of the result.
https://i.stack.imgur.com/Cpmvh.png

@a-hurst
Copy link
Member

a-hurst commented Oct 24, 2023

@atomicdad This is the right place, thanks for reporting the issue!

pysdl2-dll does indeed bundle the latest version of sdl2_gfx (1.0.4), so I don't think an out-of-date library is the issue. Additionally I double-checked the Python bindings to make sure all the argument types were being bound correctly and those were fine as well. Finally, I looked a quick look at the sdl2_gfx source code and found this, which was added in as part of the patch fixing large-radius circles you mentioned:

	if (rxi >= 512 || ryi >= 512)
	{
		ellipseOverscan = DEFAULT_ELLIPSE_OVERSCAN / 4;
	} 
	else if (rxi >= 256 || ryi >= 256)
	{
		ellipseOverscan = DEFAULT_ELLIPSE_OVERSCAN / 2;
	}
	else
	{
		ellipseOverscan = DEFAULT_ELLIPSE_OVERSCAN / 1;
	}

Given that the overscan value is set to change every time the radius increases by a power of 2 beyond 256, I'm guessing the author never imagined circles with a radius of 1024 being an issue and didn't think to add an if (rxi >= 1024 || ryi >= 1024) statement dividing the default overscan by 8 (and also didn't think of writing a more generalizable patch).

Unfortunately the sdl2_gfx source code hasn't been updated by its author since 2018, and I don't think anyone else has attempted to keep an up-to-date fork, so I don't think the odds are good on this getting fixed. If you're open to using other drawing libraries with SDL2, you can use Pillow's ImageDraw module along with sdl2.ext.pillow_to_surface. It's a more Pythonic API and also supports proper anti-aliasing (unlike gfx). I personally use aggdraw for all my PySDL2 shape rendering, although the API's a bit wonky and ImageDraw probably supports most of the same functionality nowadays so I'd try that first.

Hope this helps!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants