1. Marcus von Appen
  2. py-sdl2
  3. Issues
Issue #8 resolved

Can't render to Sprite

Bil Bas
created an issue

Sprites can only be static or dynamic (init() passed a boolean, "static"). The problem with this is that it doesn't allow you to create the texture with the other option: SDL_TEXTUREACCESS_TARGET (which must be set to render to the texture).

I've monkey-patched Sprite/SpriteFactory in my code to replace the static option with a more sensible access=Sprite.ACCESS_STATIC, Sprite.ACCESS_STREAMING or Sprite.ACCESS_TARGET (where Sprite.ACCESS_TARGET = sdl2.SDL_TEXTUREACCESS_TARGET). Not sure if this is how you'd want it done in pysdl2 ext though.

Comments (5)

  1. Marcus von Appen repo owner

    Only SpriteFactory.create_texture_sprite() and repr(TextureSprite) should be affected regarding that problem. I think, we can keep sdl2.SDL_TEXTUREACCESS_* as direct arguments to the method, though - this also saves us some superfluous mapping.

    If you have a patch around, it'd be highly appreciated (since it'd save me some typing work ;-).

  2. Bil Bas reporter

    Yeah, more friendly in the end to just use the sdl2 constants directly (and they are better documented, anyway).

    I just monkey-patched at run-time, rather than updating pysdl2 itself. Thus, I'll be lazy and just paste the new version of the method, which is better than nothing!

        def create_texture_sprite(self, renderer, size,
                                      pformat=sdl2.SDL_PIXELFORMAT_RGBA8888,
                                      access=sdl2.SDL_TEXTUREACCESS_STATIC):
    
                if isinstance(renderer, sdl2.SDL_Renderer):
                    sdlrenderer = renderer
                elif isinstance(renderer, sdl2ext.RenderContext):
                    sdlrenderer = renderer.renderer
                else:
                    raise TypeError("renderer must be a Renderer or SDL_Renderer")
    
                if access not in (sdl2.SDL_TEXTUREACCESS_STATIC,
                                  sdl2.SDL_TEXTUREACCESS_STREAMING,
                                  sdl2.SDL_TEXTUREACCESS_TARGET):
                    raise sdl2.SDLError("Bad access - should be SDL_TEXTUREACCESS_STATIC, SDL_TEXTUREACCESS_STREAMING or SDL_TEXTUREACCESS_TARGET")
    
                if access == sdl2.SDL_TEXTUREACCESS_TARGET:
                    render_info = sdl2.SDL_RendererInfo()
                    sdl2.SDL_GetRendererInfo(sdlrenderer, render_info)
                    if not (render_info.flags & sdl2.SDL_RENDERER_TARGETTEXTURE):
                       raise sdl2.SDLError("Renderer must have been created with flag SDL_RENDERER_TARGETTEXTURE to use SDL_TEXTUREACCESS_TARGET")
    
                texture = sdl2.SDL_CreateTexture(sdlrenderer, pformat, access,
                                                   size[0], size[1])
                if not texture:
                    raise sdl2.SDLError()
    
                return sdl2ext.TextureSprite(texture.contents)
    
  3. Marcus von Appen repo owner

    I left out your checks intentionally, since I hold the underlying SDL2 library responsible for performing the checks and raise errors on incorrect or invalid flags.

    Right now, this does not seem to be the case for the tests I made, so either my renderers are almighty or SDL2 does not validate the access flag. This needs to be checked in the SDL2 code and fixed there.

  4. Bil Bas reporter

    Yeah, it happily accepts SDL_TEXTUREACCESS_TARGET even if the renderer isn't told to deal with it (in which case it is a no-op, which is why I check it). As you say, it should be fixed in SDL2 itself.

  5. Log in to comment