shader
FreeBodyEngine.graphics.gl33.shader
#
GL_TYPE_NAMES = {GL_INT: 'int', GL_INT_VEC2: 'ivec2', GL_INT_VEC3: 'ivec3', GL_INT_VEC4: 'ivec4', GL_FLOAT: 'float', GL_FLOAT_VEC2: 'vec2', GL_FLOAT_VEC3: 'vec3', GL_FLOAT_VEC4: 'vec4', GL_FLOAT_MAT2: 'mat2', GL_FLOAT_MAT3: 'mat3', GL_FLOAT_MAT4: 'mat4', GL_BOOL: 'bool', GL_SAMPLER_2D: 'sampler2D', GL_SAMPLER_2D_ARRAY: 'sampler2DArray'}
module-attribute
#
GLShader(vertex_source, fragment_source, injector, geometry_source=None)
#
Bases: Shader
The GL 3.3 implementation of Shader: compiles FBUSL source via GL33Generator into a real GL program, introspects its uniforms, and caches each uniform's last-set value so set_uniform() can skip a redundant glUniform* call when the value hasn't actually changed.
generator_cls is a class attribute (not hardcoded inline in
init) specifically so graphics/gles/shader.py's GLESShader can
reuse every method here unchanged and only override which generator
produces the GLSL text - the real GL program creation/introspection/
uniform dispatch below is all plain PyOpenGL calls, valid against a
GLES 3.0 context exactly the same as a desktop 3.3 one.
Compiles vertex_source/fragment_source(/geometry_source)
into a linked GL program (via self.generator_cls) and
introspects its active uniforms into self.uniforms, seeding
uniform_cache with None for each so the first set_uniform()
call for any uniform always goes through.
generator_cls = GL33Generator
class-attribute
instance-attribute
#
uniform_cache = {}
instance-attribute
#
uniforms = {}
instance-attribute
#
check_val_type(val, gl_type, name)
#
Validates that val is an acceptable Python value for a uniform
of GL type gl_type - logging an engine error and returning False
if not. Color/Vector/Vector3 are accepted directly for the
vector GL types they map onto, alongside a plain tuple/list/ndarray
of the right length.
get_uniform(name)
#
Returns the introspected GLUniform record (location/size/type)
for uniform name.
rebuild(injector=..., vertex_source=None, fragment_source=None, geometry_source=...)
#
Recompiles this shader in place (same object, new GL program) -
used by dev-mode hot reload (see Material.reload_shader()). Passing
vertex_source/fragment_source re-fetches from those (a fresh
FileResource, not whatever's cached on self already) rather than
this shader's existing ones, since a stale FileResource can be
holding a file handle to a since-replaced inode (editors that save
via write-to-temp-then-rename) and silently never see new content.
geometry_source defaults to self.geometry_source unchanged
(... rather than None, since None is itself a valid "no
geometry shader" value some callers legitimately want to keep).
set_buffer(name, buffer)
#
Binds buffer to the uniform block declared as name in this
shader's source (self.data['buffers'], populated by
generator-produced metadata) - warns instead of raising if name
isn't a known buffer block.
set_uniform(name, val)
#
Sets uniform name to val, after check_val_type() validates
it. Skips the actual glUniform* call (and the cache update) if val
equals the value already cached for this uniform, avoiding redundant
driver calls when the same value is set every frame - as material
properties typically are.
setup_uniforms()
#
Populates self.uniforms from the program's active uniforms
(glGetActiveUniform), normalizing the name PyOpenGL hands back
(which can come as str, bytes, or a numpy array depending on
driver/binding) to a plain, null-terminated string.
use()
#
Activates this shader's program, updates the TIME builtin
uniform if the shader declares one, and binds every currently-cached
texture/texture-stack uniform (see _bind_textures).
GLUniform(location, size, type)
dataclass
#
compile_shader(source, shader_type)
#
Compiles source as a shader_type GL shader object, raising
RuntimeError with the driver's compile log on failure.
create_shader_program(vertex_src, fragment_src, geometry_src=None)
#
Compiles and links vertex_src/fragment_src (and geometry_src,
if given) into a linked GL program, raising RuntimeError with the
driver's log on a compile or link failure. The per-stage shader objects
are deleted once linked - only the program is kept.
set_gl_uniform(loc, gl_type, val)
#
The actual glUniform/glUniformMatrix dispatch, factored out of GLShader.set_uniform so GLComputeShader (graphics/gl33/compute.py) can reuse it instead of duplicating this same type-dispatch table. Assumes the target program is already current (glUseProgram).