diff --git a/CHANGELOG.md b/CHANGELOG.md index 7e962c3622..8bb1487c5a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,14 @@ You can grab pre-release versions from PyPi. See the available versions from the Arcade [PyPi Release History](https://pypi.org/project/arcade/#history) page. +## 3.3.1 + +- Fixed an issue causing NinePatch to not render correctly +- TextureAtlas now as a `version` attribute that is incremented when the + atlas is resized or rebuilt. This way it's easy to track when texture coordinates + has changed. +- Added `Text.visible` (bool) property to control the visibility of text objects. + ## 3.3.0 - Fixed an issue causing a crash when closing the window diff --git a/arcade/gui/nine_patch.py b/arcade/gui/nine_patch.py index 424ac3fa98..7fd4a96b68 100644 --- a/arcade/gui/nine_patch.py +++ b/arcade/gui/nine_patch.py @@ -78,7 +78,7 @@ def __init__( self._initialized = False self._texture = texture self._custom_atlas = atlas - self._geometry_cache: tuple[int, int, int, int, Rect] | None = None + self._geometry_cache: tuple[int, int, int, int, int, Rect] | None = None # pixel texture co-ordinate start and end of central box. self._left = left @@ -325,16 +325,20 @@ def _init_deferred(self): # References for the texture self._atlas = self._custom_atlas or self._ctx.default_atlas self._add_to_atlas(self.texture) - - # NOTE: Important to create geometry after the texture is added to the atlas - # self._create_geometry(LBWH(0, 0, self.width, self.height)) self._initialized = True def _create_geometry(self, rect: Rect): """Create vertices for the 9-patch texture.""" # NOTE: This was ported from glsl geometry shader to python # Simulate old uniforms - cache_key = (self._left, self._right, self._bottom, self._top, rect) + cache_key = ( + self._atlas.version, + self._left, + self._right, + self._bottom, + self._top, + rect, + ) if cache_key == self._geometry_cache: return self._geometry_cache = cache_key diff --git a/arcade/texture_atlas/atlas_default.py b/arcade/texture_atlas/atlas_default.py index 52ec23823e..e804083231 100644 --- a/arcade/texture_atlas/atlas_default.py +++ b/arcade/texture_atlas/atlas_default.py @@ -112,6 +112,7 @@ def __init__( self._ctx = ctx or get_window().ctx self._max_size = self._ctx.info.MAX_VIEWPORT_DIMS self._size: tuple[int, int] = size + self._version = 0 self._allocator = Allocator(*self._size) self._auto_resize = auto_resize self._capacity = capacity @@ -736,6 +737,7 @@ def resize(self, size: tuple[int, int], force=False) -> None: vertices=UV_TEXTURE_WIDTH * self._capacity * 6, ) + self._version += 1 # duration = time.perf_counter() - resize_start # LOG.info("[%s] Atlas resize took %s seconds", id(self), duration) @@ -769,6 +771,8 @@ def rebuild(self) -> None: for texture in sorted(textures, key=lambda x: x.image.size[1]): self._add(texture, create_finalizer=False) + self._version += 1 + def use_uv_texture(self, unit: int = 0) -> None: """ Bind the texture coordinate texture to a channel. diff --git a/arcade/texture_atlas/base.py b/arcade/texture_atlas/base.py index 1a089f83da..1ec5142b5f 100644 --- a/arcade/texture_atlas/base.py +++ b/arcade/texture_atlas/base.py @@ -64,6 +64,7 @@ def __init__(self, ctx: ArcadeContext | None): self._ctx = ctx or arcade.get_window().ctx self._size: tuple[int, int] = 0, 0 self._layers: int = 1 + self._version = 0 @property def ctx(self) -> ArcadeContext: @@ -85,6 +86,17 @@ def texture(self) -> Texture2D: """The OpenGL texture for this atlas.""" return self._texture + @property + def version(self) -> int: + """ + The version of the atlas. + + This is incremented every time the atlas is rebuilt or resized. + It can be used to check if the atlas has changed since last + time it was used. + """ + return self._version + @property def width(self) -> int: """Hight of the atlas in pixels.""" diff --git a/tests/unit/atlas/test_basics.py b/tests/unit/atlas/test_basics.py index 018ab9e09b..7cfcf0bea8 100644 --- a/tests/unit/atlas/test_basics.py +++ b/tests/unit/atlas/test_basics.py @@ -137,7 +137,12 @@ def buf_check(atlas): assert len(atlas._texture_uvs._data.tobytes()) == len(atlas._texture_uvs.texture.read()) buf_check(atlas) + version = atlas.version atlas.resize((200, 200)) + assert atlas.version != version buf_check(atlas) + + version = atlas.version atlas.rebuild() + assert atlas.version != version buf_check(atlas)