Skip to content

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).