Skip to content

generator

FreeBodyEngine.graphics.webgl.generator #

WebGL2Generator(*args, **kwargs) #

Bases: GL33Generator

Emits GLSL ES 3.00 (WebGL2's shading language) - inherits GL33Generator wholesale (the actual codegen for expressions/statements/functions is identical between desktop GLSL 330 and GLSL ES 300; they diverged from the same OpenGL ES lineage and neither this engine nor FBUSL uses any construct where they differ) and overrides only what actually differs: the version header, ES's mandatory float precision qualifier that desktop GLSL doesn't have at all, and the "sample" builtin's generated function name (see _WEBGL2_IMPLEMENTATIONS above - sample itself is a reserved word in GLSL ES, unlike desktop GLSL 330).

CAPABILITIES covers everything GL33Generator's does except "geometry.native" - WebGL2 genuinely has no geometry shader stage at all (that's ES 3.2/desktop only), so @geometry still raises a clear FBUSL "capability not supported" error targeting web. Compute/raytrace support (buffer_read/dispatch/invocation_id/image_read/ query_emulated), though, carries over just fine - GL33's own emulation of all of it is already built entirely from ordinary draw calls, framebuffers and textures (see graphics/gl33/compute.py's module docstring), none of which are desktop-only. The one piece that genuinely doesn't exist in WebGL2 is samplerBuffer/GL_TEXTURE_BUFFER itself (ES 3.2+/desktop-only, no WebGL2 extension exposes it) - see generate_buffer_block()/_generate_raytrace_intrinsics() below for the 2D-data-texture emulation (graphics/webgl/buffer.py's WebGL2TextureBuffer) that replaces it.

Same as GL33Generator.init(), except self.implementations is the WebGL2-specific table above (renamed "sample") instead of GL33Generator's own.

CAPABILITIES = frozenset({'compute.dispatch', 'compute.invocation_id', 'compute.buffer_read', 'compute.image_read', 'raytrace.query_emulated'}) class-attribute instance-attribute #

implementations = _WEBGL2_IMPLEMENTATIONS instance-attribute #

generate() #

Same shape as GL33Generator.generate() - version/extension header, then IMPLEMENTATIONS injections, then (for a RAYTRACE stage) the ray-intrinsics, then one generated line per top-level AST node - but with a GLSL ES header instead of desktop GLSL's, no geometry-layout handling (CAPABILITIES above still has no "geometry.native", so reaching that FBUSL construct raises first), and the _ENGINE_buf_idx() overload pair every buffer- block/raytrace-intrinsic access below calls to turn a 1D index into this backend's 2D-data-texture coordinates.

generate_buffer_block(node) #

Same contract as GL33Generator.generate_buffer_block() (declares one uniform per field, plus a _load_<struct>_<block>_<field>() loader for struct-typed fields) but backed by sampler2D instead of samplerBuffer - see this module's own docstring and graphics/webgl/buffer.py's WebGL2TextureBuffer for why. Every field here is float data (even an int-typed struct field - see _generate_struct_field_loader's int() cast), matching GL33Generator's own choice to always use samplerBuffer (never isamplerBuffer) for ordinary buffer blocks; only the raytrace intrinsics' bvh_meta needs a real int texture (see _generate_raytrace_intrinsics).

generate_inout(node) #

Same as GL33Generator.generate_inout(), except layout(location= ...) is only emitted where GLSL ES 3.00 core actually allows it: a vertex shader's in (attribute) declarations, and a fragment shader's out (color attachment) declarations. Desktop GLSL 330 can put an explicit location on every in/out, including a vertex shader's out varyings and a fragment shader's matching in varyings, because GL33Generator's header enables GL_ARB_separate_shader_objects - WebGL2 has no equivalent extension at all, and ES 3.00 core requires varyings to match between stages by name instead, with no location qualifier on either side. Emitting one anyway compiled fine in isolation but failed exactly at the vertex stage (before this was ever caught) with "invalid layout qualifier: only valid on program inputs and outputs" - GLSL ES's own error wording for "not a real attribute/ fragment-output".

self.input_index/self.output_index still advance on every Input/Output regardless of whether a location actually gets printed, matching GL33Generator's own counting so mixed vertex/ fragment field ordering behaves identically to desktop wherever a location is emitted.