gl44
FreeBodyEngine.graphics.gl44
#
The OpenGL 4.4 implementation of the FB graphics system - a complete, separate backend from gl33/ (see gl44/renderer.py's docstring). Real compute shaders live in gl44/compute.py (GL44ComputeShader).
GL44Framebuffer(width, height, attachments, transparent=False)
#
Bases: Framebuffer
The GL 4.4 implementation of Framebuffer: creates a real GL FBO with one 2D texture per color attachment and a shared renderbuffer for a depth/stencil/combined depth-stencil attachment (GL 4.4 has no functional need for a separate depth-only vs. combined path beyond which GL enum each is attached under).
Creates the FBO and, for each entry in attachments, its backing
GPU resource: a texture for a COLOR attachment (assigned sequential
GL_COLOR_ATTACHMENT0+n slots and registered as a draw buffer), or a
renderbuffer for DEPTH/STENCIL/DEPTH_STENCIL. Raises RuntimeError if
the resulting FBO isn't GL_FRAMEBUFFER_COMPLETE. transparent
enables standard alpha blending for subsequent draws into this
framebuffer.
depth_renderbuffer = glGenRenderbuffers(1)
instance-attribute
#
fbo = glGenFramebuffers(1)
instance-attribute
#
textures = {}
instance-attribute
#
bind()
#
Binds this FBO as the current draw/read target and sets the GL viewport to its full size, so subsequent draw calls render into its attachments instead of the screen.
clear_color_attachment(name, value=(0.0, 0.0, 0.0, 0.0))
#
Clears the named color attachment to value via
glClearBufferfv(GL_COLOR, draw_buffer_index, ...) - see
GLFramebuffer.clear_color_attachment (gl33) for why this targets
only one draw buffer rather than every bound one. This was missing
entirely from GL44Framebuffer (PBRPipeline.draw() calls it
unconditionally to keep gWorldPos.w a reliable sentinel), so
PBRPipeline could never actually run on GL44Renderer before this.
draw(attachment, size=None)
#
Draw a named attachment to the screen.
get_attachment_texture(attachment_name)
#
Returns the raw GL texture name backing color attachment
attachment_name (e.g. for wrapping via
TextureManager.wrap_external_texture), logging an error instead of
raising if it doesn't exist.
read(attachment_name)
#
Synchronously reads back color attachment attachment_name
(glReadPixels, always as GL_FLOAT) into a (height, width,
channels) numpy array - a GPU/CPU sync point, so only meant for
compute-emulation-style result readback, not per-frame use. Raises
ValueError if attachment_name doesn't exist or isn't a color
attachment.
resize(size)
#
Recreates every attachment's backing texture/renderbuffer at the
new size in place (same FBO, same attachment slots) - deletes each
old GL object first rather than leaking it. Raises RuntimeError if
the FBO isn't complete afterward, and leaves the GL viewport set to
the new size.
set_draw_buffers(names)
#
See Framebuffer.set_draw_buffers / GLFramebuffer.set_draw_buffers (gl33) - identical implementation. Assumes this FBO is already bound.
unbind()
#
Rebinds the default framebuffer (id 0, the screen) - does not restore the previous viewport, so callers that resized it should reset that themselves.
GL44Image(data)
#
Bases: Image
The GL 4.4 implementation of Image - identical to GLImage (graphics/gl33/image.py), since exposing a Texture's pixel data doesn't involve anything backend-specific beyond the Texture/TextureManager machinery both backends already share.
Wraps the given texture-backed data via the base Image
constructor.
GL44Mesh(attributes, indices=None, primitive=None, index_type=None, usage=None)
#
Bases: Mesh
The GL 4.4 implementation of Mesh: one VAO with one VBO per attribute
(bound to sequential vertex attribute locations in attributes' dict
order) plus an optional EBO for indexed drawing. Identical in mechanism
to GLMesh (graphics/gl33/mesh.py) - core vertex array/buffer upload
hasn't changed between GL 3.3 and 4.4.
Creates the VAO/VBOs/EBO (the EBO only if indices is given),
picks the GL primitive enum matching primitive, and immediately
uploads the given attribute/index data via upload().
ebo = glGenBuffers(1) if indices is not None else None
instance-attribute
#
vao = glGenVertexArrays(1)
instance-attribute
#
vbos = {}
instance-attribute
#
destroy()
#
Deletes every VBO, the EBO (if any), and the VAO itself.
draw()
#
Issues the draw call for this mesh's currently uploaded buffers:
glDrawElements if it has an index buffer, otherwise
glDrawArrays sized off the first attribute's vertex count (its
raw element count divided by 3, so this assumes that attribute is
3-component - e.g. positions).
upload()
#
Uploads every attribute in self.attributes to its own VBO and
wires it to a sequential vertex attribute location (location 0, 1,
2, ... in dict iteration order - so the order attributes are passed
in matters), then uploads self.indices to the EBO if present.
Raises ValueError for an AttributeType this backend doesn't know how
to map to a GL type/size (MAT3/MAT4/VEC5/VEC6/IVEC5/IVEC6).
GL44Renderer()
#
Bases: Renderer
The OpenGL renderer. Uses OpenGL version 4.4 core - real compute shaders (glDispatchCompute), writable SSBOs, and image load/store, unlike GL33Renderer's fullscreen-fragment-shader compute emulation. A completely separate, independently selectable backend (see graphics/get_renderer()) - GL33Renderer is untouched and still exists for hardware/platforms that can't do better than 3.3.
Sets the backend's Mesh subclass; GPU context creation happens in on_initialize() instead, since it depends on a window (or lack thereof) that doesn't exist yet at construction time.
create_framebuffer
property
#
Returns GL44Framebuffer.
mesh_class = GL44Mesh
instance-attribute
#
clear(color)
#
Clears the color and depth buffers of the currently bound framebuffer to color.
clear_scissor()
#
See Renderer.clear_scissor().
create_buffer(data)
#
Wraps data in a UBOBuffer, GL44's Buffer implementation.
destroy()
#
Releases the OpenGL context (win32 only - wglMakeCurrent/wglDeleteContext are Windows-specific).
disable_depth_testing()
#
Disables GL_DEPTH_TEST.
draw_circle(radius, position, color)
#
Not yet implemented - always a no-op.
draw_line(start, end, width, color)
#
Draws a line segment from start to end using a dedicated line
shader program (self.line_program), building a fresh 2-point
VAO/VBO every call.
draw_mesh(mesh, material)
#
Binds material and draws mesh's indexed triangles. Temporarily
switches to wireframe polygon mode if material.data['render_mode']
== "wireframe".
draw_mesh_instanced(mesh, material, model_matrices, camera)
#
Draws one copy of mesh per row of model_matrices (shape
(N, 4, 4)) in a single glDrawElementsInstanced call - see
GL33Renderer.draw_mesh_instanced for the identical implementation
and its docstring (GL44 doesn't need anything version-specific for
instanced vertex-attribute arrays, so this is deliberately not
using GL44-only features like SSBOs).
enable_depth_testing()
#
Enables GL_DEPTH_TEST.
get_max_buffer_size()
#
Returns the max size of a UBOBuffer, in bytes.
get_mesh_class()
#
Returns GL44Mesh.
load_shader(vertex, fragment, injector=Injector(), geometry=None)
#
Compiles vertex/fragment (and optional geometry) FBUSL source into a GL44Shader, using injector to resolve engine-provided builtins.
on_initialize()
#
Creates (or attaches to) the OpenGL context for the current window backend (glfw/wayland/win32/x11), or - if no 'window' service is registered at all - assumes a raw offscreen context already exists and is current (a true headless compute session, see graphics.ensure_gpu_context()). Then warns (but doesn't raise) if the resulting context is below MIN_GL_VERSION, and enables GL_DEBUG_OUTPUT plus the initial viewport.
resize(size)
#
Updates the GL viewport to size, and resizes the platform-specific window surface (wayland/x11) to match.
set_blend_mode(mode)
#
See Renderer.set_blend_mode. Skips the actual GL calls if mode
already matches the last mode set, since flush() calls this between
every group even when consecutive groups share a mode.
set_scissor(x, y, width, height)
#
See Renderer.set_scissor(). x/y come in top-left-origin,
Y-down (UIRenderer's convention) - glScissor wants bottom-left
origin, so y is flipped against the framebuffer height.
swap_buffers()
#
Swaps the front/back buffers for a manually-created wayland/x11 context. glfw drives its own swap directly (see core/window/glfw.py) instead of going through the renderer, so this is a no-op there.
GL44Shader(vertex_source, fragment_source, injector, geometry_source=None)
#
Bases: Shader
The GL 4.4 implementation of Shader: compiles FBUSL source via GL44Generator 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.
Compiles vertex_source/fragment_source(/geometry_source)
into a linked GL program (via GL44Generator) 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.
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 GL44Uniform record (location/size/type)
for uniform name.
rebuild(injector=..., vertex_source=None, fragment_source=None, geometry_source=...)
#
See GLShader.rebuild() (graphics/gl33/shader.py) for why
vertex_source/fragment_source default to re-using self's existing
ones rather than being required, and why geometry_source's default
is the ... sentinel rather than None.
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).