From 7e8d56668a9d65946d568af6b38dfa75cd98e899 Mon Sep 17 00:00:00 2001 From: Minh Date: Thu, 5 Mar 2026 16:18:55 -0800 Subject: [PATCH] Fixes #2821: Improve Textures guide wording, layers, uniqueness, and cache --- doc/programming_guide/textures.rst | 74 ++++++++++++++++++++++-------- 1 file changed, 56 insertions(+), 18 deletions(-) diff --git a/doc/programming_guide/textures.rst b/doc/programming_guide/textures.rst index fe6393951e..025370b2e2 100644 --- a/doc/programming_guide/textures.rst +++ b/doc/programming_guide/textures.rst @@ -8,9 +8,8 @@ Introduction The :py:class:`arcade.Texture` type is how Arcade normally interacts with images either loaded from disk or created manually. This is basically a wrapper for PIL/Pillow images including detection for hit box data -using pymunk depending on the selected hit box algorithm. These texture -objects are in other words responsible to provide raw RGBA pixel -data to OpenGL and hit box geometry to the sprite engine. +using pymunk depending on the selected hit box algorithm. These texture objects are responsible for providing raw RGBA pixel +data to OpenGL and hit box geometry used when rendering sprites. There is another texture type in Arcade in the lower level OpenGL API: :py:class:`arcade.gl.Texture2D`. This represents an @@ -20,29 +19,62 @@ with the low level rendering API. Textures can be created/loaded before or after the window is created because they don't interact with OpenGL directly. +Texture Layers +-------------- + +Textures in Arcade interact with several layers of the rendering system: + +* **Arcade (Python / RAM)** + The :py:class:`arcade.Texture` object stores image data and metadata + in system memory, including raw pixel data and hit box information. + +* **pyglet** + Arcade relies on pyglet to manage the window and communicate with the + graphics system. + +* **OpenGL / GPU** + When rendering occurs, the texture data is uploaded to the GPU so it + can be used efficiently when drawing sprites. + Texture Uniqueness ------------------ -When a texture is created a ``hash/name`` is required. This should be a unique -string. If two more more textures have the same name we will run into -trouble. When loading textures the absolute path to the file is used -as part of the name including vertical/horizontal/diagonal, size and -other parameter for a truly unique name. +Each texture in Arcade has a ``name`` (sometimes referred to as a hash) +that uniquely identifies it in the texture cache. This value is used as +the cache key when textures are loaded or created. + +A *unique* name means that no two textures should share the same +identifier. If multiple textures use the same name, the cache may return +the wrong texture instance. This can lead to incorrect sprite rendering +or invalid hit box data. -When loading texture through Arcade the name of the texture will be -the absolute path to the image and various parameters such as size, -flipping, xy position etc. +When textures are loaded from files using functions such as +:py:func:`arcade.load_texture`, Arcade automatically generates a unique +name based on several pieces of information, including: -Also remember that the texture class do hit box detection with pymunk -by looking at the raw pixel data. This means for example a texture with -different flipping will be loaded multiple times (or fetched from cache) -because we rely in the transformed pixel data to get the hit box. +* The absolute path to the image file +* The selected image region or size +* Flipping options (horizontal, vertical, or diagonal) +* Other transformation parameters + +Using the absolute file path ensures that textures loaded from +different relative paths still resolve to the same cached texture. + +Flipping options also affect the generated name. For example, +loading a texture with ``flipped_vertically=True`` produces a different +texture instance because the underlying pixel data changes. This is +important because hit box detection relies on the transformed pixel +data. + +For implementation details, see the texture loading logic in +``arcade/cache/texture.py``. Texture Cache ------------- -Arcade is caching texture instances based on the ``name/hash`` attribute -to significantly speed up loading times. +Each :py:class:`arcade.Texture` has a ``name`` attribute that uniquely +identifies it. Arcade uses this attribute in the +:py:class:`arcade.cache.TextureCache` to speed up texture loading. .. code:: python @@ -59,7 +91,13 @@ to significantly speed up loading times. The above also applies when using :py:func:`arcade.load_texture` or other texture loading functions. -Arcade's default texture cache can be cleared using ``arcade.texture.default_texture_cache.flush()`` +Arcade stores texture instances in the default texture cache +(:py:class:`arcade.cache.TextureCache`). To clear all cached textures, +use the :py:meth:`arcade.cache.TextureCache.flush` method: + +.. code:: python + + arcade.texture.default_texture_cache.flush() Custom Textures ---------------