arcade icon indicating copy to clipboard operation
arcade copied to clipboard

DefaultTextureAtlas.render_into and arcade.draw_texture_rect does nothing if atlas is resized

Open bunny-therapist opened this issue 4 months ago • 1 comments

If you within a DefaultTextureAtlas.render_into context yo use arcade.draw_texture_rect, passing it the current atlas and a texture that is not already in the atlas, then the atlas will get resized so fit the new texture, but the draw command will fail to render anything. I am sure it is the resizing that causes it, since starting out with a big atlas or adding the texture to draw to the atlas beforehand both fixes the problem.

MRE:


from typing import Literal
import arcade


def mre(fix: None | Literal["big-atlas", "pre-add-texture"]) -> None:
    atlas_size = (1000, 1000) if fix == "big-atlas" else (100, 100)
    atlas = arcade.DefaultTextureAtlas(size=atlas_size)
    green_background_texture = arcade.Texture.create_empty(name="background", size=(100, 100), color=arcade.color.GREEN)
    red_overlay_texture = arcade.Texture.create_empty(name="overlay", size=(500, 500), color=arcade.color.RED)
    atlas.add(green_background_texture)
    if fix == "pre-add-texture":
        atlas.add(red_overlay_texture)
    with atlas.render_into(green_background_texture):
        arcade.draw_texture_rect(
            texture=red_overlay_texture,
            rect=arcade.Rect.from_kwargs(
                x=green_background_texture.width * 0.5,
                y=green_background_texture.height * 0.5,
                width=green_background_texture.width * 0.9,
                height=green_background_texture.height * 0.9,
            ),
            atlas=atlas,
        )
    atlas.update_texture_image_from_atlas(green_background_texture)
    green_background_texture.image.show(fix or "broken")


if __name__ == "__main__":
    _ = arcade.Window(visible=False)
    mre(fix=None)  # The green background texture does NOT have any red drawn on top of it
    mre(fix="big-atlas")  # The green background texture has a red square drawn on top of it, as it should
    mre(fix="pre-add-texture")  # The green background texture has a red square drawn on top of it, as it should

Arcade 3.2.0

vendor: Intel renderer: Intel(R) UHD Graphics version: (4, 6) python: 3.13.3 (tags/v3.13.3:6280bb5, Apr 8 2025, 14:47:33) [MSC v.1943 64 bit (AMD64)] platform: win32 pyglet version: 2.1.6 PIL version: 11.0.0

bunny-therapist avatar Aug 18 '25 16:08 bunny-therapist

Im going to investigate this later in the week, but I'll drop my initial thoughts here in case someone else wants to try.

I suspect during the resize method, the atlas framebuffer gets deactivated at the end, and/or the viewport gets reset. This then leads to the render into context-manager breaking. To test this, firstly print arcade.get_window().ctx.active_framebuffer (can get the ctx another way. This is just for clarity), secondly save the atlas image (with texture outlines) to see if the texture has been drawn elsewhere in the altas. The texture should appear twice, once inside a region as the texture. Secondly, outside any region as the texture drawn with the wrong viewport. if someone does these tests before I do put them here. They'll help narrow down possibilities.

DragonMoffon avatar Aug 19 '25 06:08 DragonMoffon