py-sdl2
py-sdl2 copied to clipboard
SpriteRenderer::render behavior change
Originally reported by: Robert Winkler (Bitbucket: rswinkle, GitHub: rswinkle)
Proposal
Remove SDL_RenderPresent/SDL_UpdateWindowSurface from SpriteRenderer::render() as in this commit
Why
While working on this project
I ran into an issue with SpriteRenderer::render calling RenderPresent (or UpdateWindow) To prevent flickering this requires all sprites that are created in their own functions to be returned back to the main loop and rendered at once in a single call to SpriteRender::render in a list. This is very inconvenient and limiting and leads to ugly code.
If you look at the games, you can see I mostly tried for a 1 to 1 port from pygame. This assumed equivalency with pygame's surface blit function, and the general code structure suggested by the SDL API, would suggest this equivalency:
SpriteRenderer::render = SDL_RenderCopy/SDL_BlitSurface
leaving the user the freedom/flexibility/responsibility to call
Renderer::present = SDL_RenderPresent
once per loop/frame at the appropriate time.
This would allow users to update the back buffer in the most convenient/intuitive manner, breaking into functions drawing (including sdlgfx functions) and sprite rendering and anything else and being able to call present once at the end of the outer scope loop. As it is, using vanilla PySDL2 you have to treat SpriteRenderer::render as Renderer::present with the added overhead of collecting all sprites in a single place.
Removing the UpdateWindow/RenderPresent calls from SpriteRenderer would also make it consistent with the drawing functions, Renderer::fill/draw_point/draw_rect which of course only update the back buffer and do not immediately get presented to the screen. In a program that only used drawing, the programmer must call Renderer.present at the end but if he uses SpriteRenderer.render at all he must not and instead treat the latter as the former.
For an example here is tetromino in pygame and my pysdl version.
Please look at any/all of the games I've ported and compare to the pygame version. Think about what changes would be necessary if I had not changed SpriteRenderer::render behavior.
I apologize for ugly/unpolished code in inventwithpython_pysdl2. Also I originally tried to do it without patching pysdl2 so there might be some remnants of that in a couple of games. I added a patched version of pysdl2 in this commit so you can try reverting just before that to look at/run the games to see the difference.
- Bitbucket: https://bitbucket.org/marcusva/py-sdl2/issue/91
Pretty sure this is addressed by the new sdl2.ext.Renderer API, which is the new and preferred way of rendering things in PySDL2.