webgl
FreeBodyEngine.graphics.webgl
#
WebGL2Framebuffer(width, height, attachments, transparent=False)
#
Bases: Framebuffer
The WebGL2 implementation of Framebuffer - see GLFramebuffer's own
docstring, same shape: one GL_TEXTURE_2D per color attachment, a
shared renderbuffer for depth/stencil/depth-stencil. Floating-point
color attachments (RGBA16F/RGBA32F/R32F/RG32F - used throughout this
engine's HDR/compute-emulation paths) need the EXT_color_buffer_float
extension explicitly requested up front; unlike desktop GL 3.3 (where
float render targets are core), WebGL2 only guarantees 8-bit/sRGB
color-renderable formats without it.
depth_renderbuffer = None
instance-attribute
#
depth_texture_name = None
instance-attribute
#
fbo = gl.createFramebuffer()
instance-attribute
#
gl = get_service('renderer').gl
instance-attribute
#
textures = {}
instance-attribute
#
bind()
#
Binds this FBO and sets the viewport to its full size.
clear_color_attachment(name, value=(0.0, 0.0, 0.0, 0.0))
#
See GLFramebuffer.clear_color_attachment() - clearBufferfv
targets one draw-buffer index at a time, same as desktop GL.
draw(attachment, size=None)
#
Blits a named color attachment to the currently bound
framebuffer (the default/window framebuffer, in the common case -
see FramePresenter-style callers) via blitFramebuffer, which
WebGL2 has natively (unlike WebGL1, which needed a fullscreen-quad
shader trick for this).
get_attachment_texture(attachment_name)
#
Returns the raw WebGLTexture backing the named color attachment.
read(attachment_name)
#
Synchronous GPU->CPU readback via readPixels - see the
abstract method's own docstring for when that's acceptable.
readPixels needs a pre-sized JS typed array to write into
(unlike PyOpenGL's glReadPixels, which allocates and returns one),
so one is created up front and copied back out via .to_py().
resize(size)
#
Recreates every attachment's storage at the new size - deletes
and regenerates each one (WebGL2, like desktop GL, can't resize a
texture/renderbuffer's storage in place).
set_draw_buffers(names)
#
See Framebuffer.set_draw_buffers(). Assumes this FBO is already bound.
Unlike desktop GL (glDrawBuffers there can list attachments in any
order or subset - array index N just means "fragment output N
goes to whichever attachment is listed here"), WebGL2 requires
array index i to be either NONE or exactly COLOR_ATTACHMENTi -
the array position IS the attachment index, and can't reorder or
compact them. So this can't just be gl.drawBuffers([self.
attachments[n] for n in names]) the way GLFramebuffer's desktop
equivalent is (that mapped straight through and failed the
instant names requested a non-contiguous-from-zero subset, e.g.
a G-buffer's attachments 1-3 without attachment 0 - the WebGL2
error is literally "drawBuffers: COLOR_ATTACHMENTi_EXT or NONE").
Building a full-width array covering every color attachment this
FBO has, with NONE at every index not in names, satisfies that
restriction regardless of which subset was requested.
unbind()
#
Rebinds the default framebuffer (the canvas's own backbuffer).
WebGL2Image(data)
#
WebGL2Mesh(attributes, indices=None, primitive=None, index_type=None, usage=None)
#
Bases: Mesh
The WebGL2 implementation of Mesh - see GLMesh's own docstring, same
shape: one real VAO, one VBO per vertex attribute, an optional EBO for
indexed drawing. WebGL2 (unlike WebGL1) has native createVertexArray/
bindVertexArray, so this needs no OES_vertex_array_object shim.
ebo = gl.createBuffer() if indices is not None else None
instance-attribute
#
gl = get_service('renderer').gl
instance-attribute
#
vao = gl.createVertexArray()
instance-attribute
#
vbos = {}
instance-attribute
#
destroy()
#
Deletes every attribute VBO, the EBO if this mesh has one, and the VAO itself.
draw()
#
Issues the draw call - drawElements against the EBO if this
mesh has indices, else drawArrays (same non-indexed vertex-count
assumption GLMesh.draw() makes: the first attribute is a 3-wide
channel).
upload()
#
(Re)creates one VBO per entry in self.attributes and uploads
its data, wiring each up as a sequential vertex attribute starting
at location 0, in the same declaration order GLMesh.upload() uses
- see its own docstring for why that order matters.