OpenGL Context#

class arcade.ArcadeContext(window: BaseWindow, gc_mode: str = 'context_gc', gl_api: str = 'gl')[source]#

Bases: Context

An OpenGL context implementation for Arcade with added custom features. This context is normally accessed through arcade.Window.ctx.

Pyglet users can use the base Context class and extend that as they please.

This is part of the low level rendering API in arcade and is mainly for more advanced usage

Parameters:
  • window – The pyglet window

  • gc_mode – The garbage collection mode for opengl objects. auto is just what we would expect in python while context_gc (default) requires you to call Context.gc(). The latter can be useful when using multiple threads when it’s not clear what thread will gc the object.

🧙 delattr(selfname, /)#

Implement delattr(self, name).

🧙 dir(self)#

Default dir() implementation.

🧙 self == value#

Return self==value.

🧙 format(selfformat_spec, /)#

Default object formatter.

🧙 self >= value#

Return self>=value.

🧙 self > value#

Return self>value.

🧙 hash(self)#

Return hash(self).

🧙 self <= value#

Return self<=value.

🧙 self < value#

Return self<value.

🧙 self != value#

Return self!=value.

🧙 repr(self)#

Return repr(self).

🧙 setattr(selfname, value, /)#

Implement setattr(self, name, value).

🧙 sys.getsizeof(self)#

Size of object in memory, in bytes.

🧙 str(self)#

Return str(self).

classmethod activate(ctx: Context)#

Mark a context as the currently active one.

Warning

Never call this unless you know exactly what you are doing.

bind_window_block() None[source]#

Binds the projection and view uniform buffer object. This should always be bound to index 0 so all shaders have access to them.

buffer(*, data: ByteString | memoryview | array | Array | None = None, reserve: int = 0, usage: str = 'static') Buffer#

Create an OpenGL Buffer object. The buffer will contain all zero-bytes if no data is supplied.

Examples:

# Create 1024 byte buffer
ctx.buffer(reserve=1024)
# Create a buffer with 1000 float values using python's array.array
from array import array
ctx.buffer(data=array('f', [i for in in range(1000)])
# Create a buffer with 1000 random 32 bit floats using numpy
self.ctx.buffer(data=np.random.random(1000).astype("f4"))

The data parameter can be anything that implements the Buffer Protocol.

This includes bytes, bytearray, array.array, and more. You may need to use typing workarounds for non-builtin types. See Writing Raw Bytes to GL Buffers & Textures for more information.

The usage parameter enables the GL implementation to make more intelligent decisions that may impact buffer object performance. It does not add any restrictions. If in doubt, skip this parameter and revisit when optimizing. The result are likely to be different between vendors/drivers or may not have any effect.

The available values mean the following:

stream
    The data contents will be modified once and used at most a few times.
static
    The data contents will be modified once and used many times.
dynamic
    The data contents will be modified repeatedly and used many times.
Parameters:
  • data – The buffer data. This can be a bytes instance or any any other object supporting the buffer protocol.

  • reserve – The number of bytes to reserve

  • usage – Buffer usage. ‘static’, ‘dynamic’ or ‘stream’

compute_shader(*, source: str, common: Iterable[str] = ()) ComputeShader#

Create a compute shader.

Parameters:
  • source – The glsl source

  • common – Common / library source injected into compute shader

copy_framebuffer(src: Framebuffer, dst: Framebuffer)#

Copies/blits a framebuffer to another one.

This operation has many restrictions to ensure it works across different platforms and drivers:

  • The source and destination framebuffer must be the same size

  • The formats of the attachments must be the same

  • Only the source framebuffer can be multisampled

  • Framebuffers cannot have integer attachments

Parameters:
  • src – The framebuffer to copy from

  • dst – The framebuffer we copy to

depth_texture(size: Tuple[int, int], *, data: ByteString | memoryview | array | Array | None = None) Texture2D#

Create a 2D depth texture. Can be used as a depth attachment in a Framebuffer.

Parameters:
  • size (Tuple[int, int]) – The size of the texture

  • data – The texture data (optional). Can be bytes or any object supporting the buffer protocol.

disable(*args)#

Disable one or more context flags:

# Single flag
ctx.disable(ctx.BLEND)
# Multiple flags
ctx.disable(ctx.DEPTH_TEST, ctx.CULL_FACE)
enable(*flags)#

Enables one or more context flags:

# Single flag
ctx.enable(ctx.BLEND)
# Multiple flags
ctx.enable(ctx.DEPTH_TEST, ctx.CULL_FACE)
enable_only(*args)#

Enable only some flags. This will disable all other flags. This is a simple way to ensure that context flag states are not lingering from other sections of your code base:

# Ensure all flags are disabled (enable no flags)
ctx.enable_only()
# Make sure only blending is enabled
ctx.enable_only(ctx.BLEND)
# Make sure only depth test and culling is enabled
ctx.enable_only(ctx.DEPTH_TEST, ctx.CULL_FACE)
enabled(*flags)#

Temporarily change enabled flags.

Flags that was enabled initially will stay enabled. Only new enabled flags will be reversed when exiting the context.

Example:

with ctx.enabled(ctx.BLEND, ctx.CULL_FACE):
    # Render something
enabled_only(*flags)#

Temporarily change enabled flags.

Only the supplied flags with be enabled in in the context. When exiting the context the old flags will be restored.

Example:

with ctx.enabled_only(ctx.BLEND, ctx.CULL_FACE):
    # Render something
finish() None#

Wait until all OpenGL rendering commands are completed.

This function will actually stall until all work is done and may have severe performance implications.

flush() None#

A suggestion to the driver to execute all the queued drawing calls even if the queue is not full yet. This is not a blocking call and only a suggestion. This can potentially be used for speedups when we don’t have anything else to render.

framebuffer(*, color_attachments: Texture2D | List[Texture2D] | None = None, depth_attachment: Texture2D | None = None) Framebuffer#

Create a Framebuffer.

Parameters:
  • color_attachments – List of textures we want to render into

  • depth_attachment – Depth texture

gc() int#

Run garbage collection of OpenGL objects for this context. This is only needed when gc_mode is context_gc.

Returns:

The number of resources destroyed

geometry(content: Sequence[BufferDescription] | None = None, index_buffer: Buffer | None = None, mode: int | None = None, index_element_size: int = 4)#

Create a Geometry instance. This is Arcade’s version of a vertex array adding a lot of convenience for the user. Geometry objects are fairly light. They are mainly responsible for automatically map buffer inputs to your shader(s) and provide various methods for rendering or processing this geometry,

The same geometry can be rendered with different programs as long as your shader is using one or more of the input attribute. This means geometry with positions and colors can be rendered with a program only using the positions. We will automatically map what is necessary and cache these mappings internally for performace.

In short, the geometry object is a light object that describes what buffers contains and automatically negotiate with shaders/programs. This is a very complex field in OpenGL so the Geometry object provides substantial time savings and greatly reduces the complexity of your code.

Geometry also provide rendering methods supporting the following:

  • Rendering geometry with and without index buffer

  • Rendering your geometry using instancing. Per instance buffers can be provided or the current instance can be looked up using gl_InstanceID in shaders.

  • Running transform feedback shaders that writes to buffers instead the screen. This can write to one or multiple buffer.

  • Render your geometry with indirect rendering. This means packing multiple meshes into the same buffer(s) and batch drawing them.

Examples:

# Single buffer geometry with a vec2 vertex position attribute
ctx.geometry([BufferDescription(buffer, '2f', ["in_vert"])], mode=ctx.TRIANGLES)

# Single interlaved buffer with two attributes. A vec2 position and vec2 velocity
ctx.geometry([
        BufferDescription(buffer, '2f 2f', ["in_vert", "in_velocity"])
    ],
    mode=ctx.POINTS,
)

# Geometry with index buffer
ctx.geometry(
    [BufferDescription(buffer, '2f', ["in_vert"])],
    index_buffer=ibo,
    mode=ctx.TRIANGLES,
)

# Separate buffers
ctx.geometry([
        BufferDescription(buffer_pos, '2f', ["in_vert"])
        BufferDescription(buffer_vel, '2f', ["in_velocity"])
    ],
    mode=ctx.POINTS,
)

# Providing per-instance data for instancing
ctx.geometry([
        BufferDescription(buffer_pos, '2f', ["in_vert"])
        BufferDescription(buffer_instance_pos, '2f', ["in_offset"], instanced=True)
    ],
    mode=ctx.POINTS,
)
Parameters:
  • content – List of BufferDescription (optional)

  • index_buffer – Index/element buffer (optional)

  • mode – The default draw mode (optional)

  • mode – The default draw mode (optional)

  • index_element_size – Byte size of a single index/element in the index buffer. In other words, the index buffer can be 8, 16 or 32 bit integers. Can be 1, 2 or 4 (8, 16 or 32 bit unsigned integer)

get_framebuffer_image(fbo: Framebuffer, components: int = 4, flip: bool = True) Image[source]#

Shortcut method for reading data from a framebuffer and converting it to a PIL image.

Parameters:
  • fbo – Framebuffer to get image from

  • components – Number of components to read

  • flip – Flip the image upside down

is_enabled(flag) bool#

Check if a context flag is enabled

Type:

bool

load_compute_shader(path: str | Path, common: Iterable[str | Path] = ()) ComputeShader[source]#

Loads a compute shader from file. This methods supports resource handles.

Example:

ctx.load_compute_shader(":shader:compute/do_work.glsl")
Parameters:
  • path – Path to texture

  • common – Common source injected into compute shader

load_program(*, vertex_shader: str | Path, fragment_shader: str | Path | None = None, geometry_shader: str | Path | None = None, tess_control_shader: str | Path | None = None, tess_evaluation_shader: str | Path | None = None, common: Iterable[str | Path] = (), defines: Dict[str, Any] | None = None, varyings: Sequence[str] | None = None, varyings_capture_mode: str = 'interleaved') Program[source]#

Create a new program given a file names that contain the vertex shader and fragment shader. Note that fragment and geometry shader are optional for when transform shaders are loaded.

This method also supports the resource handles.

Example:

# The most common use case if having a vertex and fragment shader
program = window.ctx.load_program(
    vertex_shader="vert.glsl",
    fragment_shader="frag.glsl",
)
Parameters:
  • vertex_shader – path to vertex shader

  • fragment_shader – path to fragment shader (optional)

  • geometry_shader – path to geometry shader (optional)

  • tess_control_shader – Tessellation Control Shader

  • tess_evaluation_shader – Tessellation Evaluation Shader

  • common – Common files to be included in all shaders

  • defines – Substitute #define values in the source

  • varyings – The name of the out attributes in a transform shader. This is normally not necessary since we auto detect them, but some more complex out structures we can’t detect.

  • varyings_capture_mode – The capture mode for transforms. "interleaved" means all out attribute will be written to a single buffer. "separate" means each out attribute will be written separate buffers. Based on these settings the transform() method will accept a single buffer or a list of buffer.

load_texture(path: str | Path, *, flip: bool = True, build_mipmaps: bool = False) Texture2D[source]#

Loads and creates an OpenGL 2D texture. Currently, all textures are converted to RGBA for simplicity.

Example:

# Load a texture in current working directory
texture = window.ctx.load_texture("background.png")
# Load a texture using Arcade resource handle
texture = window.ctx.load_texture(":textures:background.png")
Parameters:
  • path – Path to texture

  • flip – Flips the image upside down

  • build_mipmaps – Build mipmaps for the texture

program(*, vertex_shader: str, fragment_shader: str | None = None, geometry_shader: str | None = None, tess_control_shader: str | None = None, tess_evaluation_shader: str | None = None, common: List[str] | None = None, defines: Dict[str, str] | None = None, varyings: Sequence[str] | None = None, varyings_capture_mode: str = 'interleaved') Program#

Create a Program given the vertex, fragment and geometry shader.

Parameters:
  • vertex_shader – vertex shader source

  • fragment_shader – fragment shader source (optional)

  • geometry_shader – geometry shader source (optional)

  • tess_control_shader – tessellation control shader source (optional)

  • tess_evaluation_shader – tessellation evaluation shader source (optional)

  • common – Common shader sources injected into all shaders

  • defines – Substitute #defines values in the source (optional)

  • varyings – The name of the out attributes in a transform shader. This is normally not necessary since we auto detect them, but some more complex out structures we can’t detect.

  • varyings_capture_mode – The capture mode for transforms. "interleaved" means all out attribute will be written to a single buffer. "separate" means each out attribute will be written separate buffers. Based on these settings the transform() method will accept a single buffer or a list of buffer.

pyglet_rendering()[source]#

Context manager for doing rendering with pyglet ensuring context states are reverted. This affects things like blending.

query(*, samples=True, time=True, primitives=True) Query#

Create a query object for measuring rendering calls in opengl.

Parameters:
  • samples – Collect written samples

  • time – Measure rendering duration

  • primitives – Collect the number of primitives emitted

reset() None[source]#

Reset context flags and other states. This is mostly used in unit testing.

shader_inc(source: str) str[source]#

Parse a shader source looking for #include directives and replace them with the contents of the included file.

The #include directive must be on its own line and the file and the path should use a resource handle.

Example:

#include :my_shader:lib/common.glsl
Parameters:

source – Shader

texture(size: Tuple[int, int], *, components: int = 4, dtype: str = 'f1', data: ByteString | memoryview | array | Array | None = None, wrap_x: int | None = None, wrap_y: int | None = None, filter: Tuple[int, int] | None = None, samples: int = 0, immutable: bool = False) Texture2D#

Create a 2D Texture.

Wrap modes: GL_REPEAT, GL_MIRRORED_REPEAT, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_BORDER

Minifying filters: GL_NEAREST, GL_LINEAR, GL_NEAREST_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_NEAREST GL_NEAREST_MIPMAP_LINEAR, GL_LINEAR_MIPMAP_LINEAR

Magnifying filters: GL_NEAREST, GL_LINEAR

Parameters:
  • size (Tuple[int, int]) – The size of the texture

  • components – Number of components (1: R, 2: RG, 3: RGB, 4: RGBA)

  • dtype – The data type of each component: f1, f2, f4 / i1, i2, i4 / u1, u2, u4

  • data – The texture data (optional). Can be bytes or any object supporting the buffer protocol.

  • wrap_x – How the texture wraps in x direction

  • wrap_y – How the texture wraps in y direction

  • filter – Minification and magnification filter

  • samples – Creates a multisampled texture for values > 0

  • immutable – Make the storage (not the contents) immutable. This can sometimes be required when using textures with compute shaders.

BLEND = 3042#

Blending

Type:

Context flag

BLEND_ADDITIVE = (1, 1)#

ONE, ONE

Type:

Blend mode shortcut for additive blending

BLEND_DEFAULT = (770, 771)#

SRC_ALPHA, ONE_MINUS_SRC_ALPHA

Type:

Blend mode shortcut for default blend mode

BLEND_PREMULTIPLIED_ALPHA = (770, 1)#

SRC_ALPHA, ONE

Type:

Blend mode shortcut for pre-multiplied alpha

CLAMP_TO_BORDER = 33069#
CLAMP_TO_EDGE = 33071#
CULL_FACE = 2884#

Face culling

Type:

Context flag

DEPTH_TEST = 2929#

Depth testing

Type:

Context flag

DST_ALPHA = 772#

Blend function

DST_COLOR = 774#

Blend function

FUNC_ADD = 32774#

source + destination

FUNC_REVERSE_SUBTRACT = 32779#

destination - source

Type:

Blend equations

FUNC_SUBTRACT = 32778#

source - destination

Type:

Blend equations

LINEAR = 9729#

Linear interpolate

Type:

Texture interpolation

LINEAR_MIPMAP_LINEAR = 9987#

Minification filter for mipmaps

Type:

Texture interpolation

LINEAR_MIPMAP_NEAREST = 9985#

Minification filter for mipmaps

Type:

Texture interpolation

LINES = 1#

Primitive mode

LINES_ADJACENCY = 10#

Primitive mode

LINE_LOOP = 2#

Primitive mode

LINE_STRIP = 3#

Primitive mode

LINE_STRIP_ADJACENCY = 11#

Primitive mode

MAX = 32776#

Maximum of source and destination

Type:

Blend equations

MIN = 32775#

Minimum of source and destination

Type:

Blend equations

MIRRORED_REPEAT = 33648#
NEAREST = 9728#

Nearest pixel

Type:

Texture interpolation

NEAREST_MIPMAP_LINEAR = 9986#

Minification filter for mipmaps

Type:

Texture interpolation

NEAREST_MIPMAP_NEAREST = 9984#

Minification filter for mipmaps

Type:

Texture interpolation

ONE = 1#

Blend function

ONE_MINUS_DST_ALPHA = 773#

Blend function

ONE_MINUS_DST_COLOR = 775#

Blend function

ONE_MINUS_SRC_ALPHA = 771#

Blend function

ONE_MINUS_SRC_COLOR = 769#

Blend function

PATCHES = 14#

Patch mode (tessellation)

POINTS = 0#

Primitive mode

PROGRAM_POINT_SIZE = 34370#

Enables gl_PointSize in vertex or geometry shaders.

When enabled we can write to gl_PointSize in the vertex shader to specify the point size for each individual point.

If this value is not set in the shader the behavior is undefined. This means the points may or may not appear depending if the drivers enforce some default value for gl_PointSize.

When disabled Context.point_size is used.

Type:

Context flag

REPEAT = 10497#

Repeat

Type:

Texture wrap mode

SRC_ALPHA = 770#

Blend function

SRC_COLOR = 768#

Blend function

TRIANGLES = 4#

Primitive mode

TRIANGLES_ADJACENCY = 12#

Primitive mode

TRIANGLE_FAN = 6#

Primitive mode

TRIANGLE_STRIP = 5#

Primitive mode

TRIANGLE_STRIP_ADJACENCY = 13#

Primitive mode

ZERO = 0#

Blend function

active: 'Context' | None = None#

The active context

atlas_size: Tuple[int, int] = (512, 512)#
blend_func#

Get or set the blend function. This is tuple specifying how the color and alpha blending factors are computed for the source and destination pixel.

When using a two component tuple you specify the blend function for the source and the destination.

When using a four component tuple you specify the blend function for the source color, source alpha destination color and destination alpha. (separate blend functions for color and alpha)

Supported blend functions are:

ZERO
ONE
SRC_COLOR
ONE_MINUS_SRC_COLOR
DST_COLOR
ONE_MINUS_DST_COLOR
SRC_ALPHA
ONE_MINUS_SRC_ALPHA
DST_ALPHA
ONE_MINUS_DST_ALPHA

# Shortcuts
DEFAULT_BLENDING     # (SRC_ALPHA, ONE_MINUS_SRC_ALPHA)
ADDITIVE_BLENDING    # (ONE, ONE)
PREMULTIPLIED_ALPHA  # (SRC_ALPHA, ONE)

These enums can be accessed in the arcade.gl module or simply as attributes of the context object. The raw enums from pyglet.gl can also be used.

Example:

# Using constants from the context object
ctx.blend_func = ctx.ONE, ctx.ONE
# from the gl module
from arcade import gl
ctx.blend_func = gl.ONE, gl.ONE
Type:

tuple (src, dst)

cull_face#

The face side to cull when face culling is enabled.

By default the back face is culled. This can be set to front, back or front_and_back:

ctx.cull_face = "front"
ctx.cull_face = "back"
ctx.cull_face = "front_and_back"
default_atlas#

The default texture atlas. This is created when arcade is initialized. All sprite lists will use use this atlas unless a different atlas is passed in the arcade.SpriteList constructor.

Type:

TextureAtlas

error#

Check OpenGL error

Returns a string representation of the occurring error or None of no errors has occurred.

Example:

err = ctx.error
if err:
    raise RuntimeError("OpenGL error: {err}")
Type:

str

fbo#

Get the currently active framebuffer. This property is read-only

Type:

arcade.gl.Framebuffer

front_face#

Configure front face winding order of triangles.

By default the counter-clockwise winding side is the front face. This can be set set to clockwise or counter-clockwise:

ctx.front_face = "cw"
ctx.front_face = "ccw"
gc_mode#

Set the garbage collection mode for OpenGL resources. Supported modes are:

# Default:
# Defer garbage collection until ctx.gc() is called
# This can be useful to enforce the main thread to
# run garbage collection of opengl resources
ctx.gc_mode = "context_gc"

# Auto collect is similar to python garbage collection.
# This is a risky mode. Know what you are doing before using this.
ctx.gc_mode = "auto"
gl_api: str = 'gl'#

The OpenGL api. Usually “gl” or “gles”.

gl_version#

The OpenGL version as a 2 component tuple. This is the reported OpenGL version from drivers and might be a higher version than you requested.

Type:

tuple (major, minor) version

info#

Get the Limits object for this context containing information about hardware/driver limits and other context information.

Example:

>> ctx.info.MAX_TEXTURE_SIZE
(16384, 16384)
>> ctx.info.VENDOR
NVIDIA Corporation
>> ctx.info.RENDERER
NVIDIA GeForce RTX 2080 SUPER/PCIe/SSE2
limits#

Get the Limits object for this context containing information about hardware/driver limits and other context information.

Warning

This an old alias for info and is only around for backwards compatibility.

Example:

>> ctx.limits.MAX_TEXTURE_SIZE
(16384, 16384)
>> ctx.limits.VENDOR
NVIDIA Corporation
>> ctx.limits.RENDERER
NVIDIA GeForce RTX 2080 SUPER/PCIe/SSE2
objects: Deque[Any]#

Collected objects to gc when gc_mode is “context_gc”. This can be used during debugging.

patch_vertices#

Get or set number of vertices that will be used to make up a single patch primitive. Patch primitives are consumed by the tessellation control shader (if present) and subsequently used for tessellation.

Type:

int

point_size#

Set or get the point size. Default is 1.0.

Point size changes the pixel size of rendered points. The min and max values are limited by POINT_SIZE_RANGE. This value usually at least (1, 100), but this depends on the drivers/vendors.

If variable point size is needed you can enable PROGRAM_POINT_SIZE and write to gl_PointSize in the vertex or geometry shader.

Note

Using a geometry shader to create triangle strips from points is often a safer way to render large points since you don’t have have any size restrictions.

primitive_restart_index#

Get or set the primitive restart index. Default is -1. The primitive restart index can be used in index buffers to restart a primitive. This is for example useful when you use triangle strips or line strips and want to start on a new strip in the same buffer / draw call.

projection_2d#

Get or set the global orthogonal projection for arcade.

This projection is used by sprites and shapes and is represented by four floats: (left, right, bottom, top)

When reading this property we reconstruct the projection parameters from pyglet’s projection matrix. When setting this property we construct an orthogonal projection matrix and set it in pyglet.

Type:

Tuple[float, float, float, float]

projection_2d_matrix#

Get the current projection matrix. This 4x4 float32 matrix is calculated when setting projection_2d.

This property simply gets and sets pyglet’s projection matrix.

Type:

pyglet.math.Mat4

scissor#

Get or set the scissor box for the active framebuffer. This is a shortcut for scissor().

By default the scissor box is disabled and has no effect and will have an initial value of None. The scissor box is enabled when setting a value and disabled when set to None.

Example:

# Set and enable scissor box only drawing
# in a 100 x 100 pixel lower left area
ctx.scissor = 0, 0, 100, 100
# Disable scissoring
ctx.scissor = None
Type:

tuple (x, y, width, height)

screen#

The framebuffer for the window.

Type:

Framebuffer

stats#

Get the stats instance containing runtime information about creation and destruction of OpenGL objects.

Example:

>> ctx.limits.MAX_TEXTURE_SIZE
(16384, 16384)
>> ctx.limits.VENDOR
NVIDIA Corporation
>> ctx.limits.RENDERER
NVIDIA GeForce RTX 2080 SUPER/PCIe/SSE2
view_matrix_2d#

Get the current view matrix. This 4x4 float32 matrix is calculated when setting view_matrix_2d.

This property simply gets and sets pyglet’s view matrix.

Type:

pyglet.math.Mat4

viewport#

Get or set the viewport for the currently active framebuffer. The viewport simply describes what pixels of the screen OpenGL should render to. Normally it would be the size of the window’s framebuffer:

# 4:3 screen
ctx.viewport = 0, 0, 800, 600
# 1080p
ctx.viewport = 0, 0, 1920, 1080
# Using the current framebuffer size
ctx.viewport = 0, 0, *ctx.screen.size
Type:

tuple (x, y, width, height)

window#

The window this context belongs to.

Type:

pyglet.Window

wireframe#

Get or set the wireframe mode. When enabled all primitives will be rendered as lines.

Type:

bool