texture
FreeBodyEngine.graphics.webgl.texture
#
WebGL2TextureManager(*args, **kwargs)
#
Bases: TextureManager
The WebGL2 implementation of TextureManager - see GLTextureManager's
own docstring, same shape (standalone textures + a slot-allocation
scheme mapping an engine-side id to a live texture unit for the
current draw). Texture stacks (sampler2DArray - used for tilemap/
sprite-sheet spritesheets, see graphics/texture.py's own docstring)
aren't implemented yet for the web backend - _create_texture_stack/
_create_standalone_texture_stack/bind_texture_stack raise a clear
error instead of silently doing nothing, so a project that needs one
finds out immediately rather than getting a blank texture at runtime.
gl = get_service('renderer').gl
instance-attribute
#
max_texture_slots = self.gl.getParameter(self.gl.MAX_COMBINED_TEXTURE_IMAGE_UNITS)
instance-attribute
#
next_texture_slot = 0
instance-attribute
#
slot_textures = {}
instance-attribute
#
texture_slots = {}
instance-attribute
#
begin_draw()
#
See GLTextureManager.begin_draw() - resets texture-unit allocation for a fresh draw call. Unlike the desktop GL33/GL44 equivalents, this also does a REAL gl.bindTexture(..., None) on every unit the previous draw used, not just a Python-side bookkeeping reset. WebGL2 raises GL_INVALID_OPERATION ("Feedback loop formed between Framebuffer and active Texture") the moment ANY texture image unit still has a texture bound that is also one of the CURRENTLY bound draw framebuffer's attachments - even one the active program's samplers don't actually read this draw call (unlike desktop GL, which only cares about what's actually sampled). A framebuffer's own color/burn texture, once wrapped via wrap_external_texture() and sampled for a ping-pong effect (e.g. phonon's VisualizerPipeline reading last frame's output), gets a slot allocated on first use and - without a real unbind here - stays physically resident in that unit forever after. Once the ping-pong flips and that same framebuffer becomes the draw target again, its own texture is still sitting in some other unit and WebGL2 refuses to draw.
bind_texture(id)
#
See GLTextureManager.bind_texture().
bind_texture_stack(id)
#
gen_id()
#
Generates a fresh unique engine-side texture id.
reload_standalone_texture(id, data)
#
See GLTextureManager.reload_standalone_texture() - re-decodes
data into the same WebGL texture this id already wraps, for
dev-mode hot reload.
set_texture_filter(id, nearest)
#
See GLTextureManager.set_texture_filter() - same NEAREST_MIPMAP_NEAREST-for-minification reasoning.
wrap_external_texture(gl_texture)
#
Registers a WebGLTexture that wasn't created by this manager (e.g. a pipeline's own framebuffer color attachment - see WebGL2Framebuffer.get_attachment_texture()) under a generated id, so it can flow through the same Texture/slot-binding machinery as any other texture. Same use case as GLTextureManager's own wrap_external_texture() (a fullscreen-effect pipeline sampling its own previous frame - see phonon's VisualizerPipeline for the pattern this exists for).