OpenGL Context#
arcade.ArcadeContext#
- class arcade.ArcadeContext(window: pyglet.window.BaseWindow, gc_mode: str = 'context_gc')[source]#
Bases:
arcade.gl.context.Context
An OpenGL context implementation for Arcade with added custom features. This context is normally accessed thought
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 (pyglet.window.Window) – The pyglet window
gc_mode (str) – The garbage collection mode for opengl objects.
auto
is just what we would expect in python whilecontext_gc
(default) requires you to callContext.gc()
. The latter can be useful when using multiple threads when it’s not clear what thread will gc the object.
- classmethod activate(ctx: arcade.gl.context.Context)#
Mark a context as the currently active one.
Warning
Never call this unless you know exactly what you are doing.
- property blend_func: Tuple[int, int]#
Get or set the blend function. This is tuple specifying how the red, green, blue, and alpha blending factors are computed for the source and destination pixel.
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 frompyglet.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)
- buffer(*, data: Optional[Any] = None, reserve: int = 0, usage: str = 'static') arcade.gl.buffer.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
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 means 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.
- compute_shader(*, source: str) arcade.gl.compute_shader.ComputeShader #
Create a compute shader.
- Parameters
source (str) – The glsl source
- copy_framebuffer(src: arcade.gl.framebuffer.Framebuffer, dst: arcade.gl.framebuffer.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 (Framebuffer) – The framebuffer to copy from
dst (Framebuffer) – The framebuffer we copy to
- property default_atlas: arcade.texture_atlas.TextureAtlas#
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
- depth_texture(size: Tuple[int, int], *, data=None) arcade.gl.texture.Texture #
Create a 2D depth texture. Can be used as a depth attachment in a
Framebuffer
.
- 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
- property error: Optional[str]#
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
- property fbo: arcade.gl.framebuffer.Framebuffer#
Get the currently active framebuffer. This property is read-only
- 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: Optional[Union[arcade.gl.texture.Texture, List[arcade.gl.texture.Texture]]] = None, depth_attachment: Optional[arcade.gl.texture.Texture] = None) arcade.gl.framebuffer.Framebuffer #
Create a Framebuffer.
- Parameters
color_attachments (List[arcade.gl.Texture]) – List of textures we want to render into
depth_attachment (arcade.gl.Texture) – Depth texture
- Return type
- gc() int #
Run garbage collection of OpenGL objects for this context. This is only needed when
gc_mode
iscontext_gc
.- Returns
The number of resources destroyed
- Return type
- property gc_mode: str#
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"
- geometry(content: Optional[Sequence[arcade.gl.types.BufferDescription]] = None, index_buffer: Optional[arcade.gl.buffer.Buffer] = None, mode: Optional[int] = None, index_element_size: int = 4)#
Create a Geomtry instance. This is Arcade’s version of a vertex array adding a lot of convenice 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) – List of
BufferDescription
(optional)index_buffer (Buffer) – Index/element buffer (optional)
mode (int) – The default draw mode (optional)
mode – The default draw mode (optional)
index_element_size (int) – 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)
- property gl_version: Tuple[int, int]#
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
- property info: arcade.gl.context.Limits#
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
- property limits: arcade.gl.context.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
- load_compute_shader(path: Union[str, pathlib.Path]) arcade.gl.compute_shader.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 (Union[str,pathlib.Path]) – Path to texture
- load_program(*, vertex_shader: Union[str, pathlib.Path], fragment_shader: Optional[Union[str, pathlib.Path]] = None, geometry_shader: Optional[Union[str, pathlib.Path]] = None, tess_control_shader: Optional[Union[str, pathlib.Path]] = None, tess_evaluation_shader: Optional[Union[str, pathlib.Path]] = None, defines: Optional[dict] = None) arcade.gl.program.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
:resources:
prefix. It’s recommended to use absolute paths, but not required.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 (Union[str,pathlib.Path]) – path to vertex shader
fragment_shader (Union[str,pathlib.Path]) – path to fragment shader (optional)
geometry_shader (Union[str,pathlib.Path]) – path to geometry shader (optional)
defines (dict) – Substitute
#define
values in the sourcetess_control_shader (Union[str,pathlib.Path]) – Tessellation Control Shader
tess_evaluation_shader (Union[str,pathlib.Path]) – Tessellation Evaluation Shader
- load_texture(path: Union[str, pathlib.Path], *, flip: bool = True, build_mipmaps: bool = False) arcade.gl.texture.Texture [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 (Union[str,pathlib.Path]) – Path to texture
flip (bool) – Flips the image upside down
build_mipmaps (bool) – Build mipmaps for the texture
- objects: Deque[Any]#
Collected objects to gc when gc_mode is “context_gc”. This can be used during debugging.
- property patch_vertices: int#
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
- property point_size: float#
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 togl_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.
- property primitive_restart_index: int#
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.
- program(*, vertex_shader: str, fragment_shader: Optional[str] = None, geometry_shader: Optional[str] = None, tess_control_shader: Optional[str] = None, tess_evaluation_shader: Optional[str] = None, defines: Optional[Dict[str, str]] = None, varyings: Optional[Sequence[str]] = None, varyings_capture_mode: str = 'interleaved') arcade.gl.program.Program #
Create a
Program
given the vertex, fragment and geometry shader.- Parameters
vertex_shader (str) – vertex shader source
fragment_shader (str) – fragment shader source (optional)
geometry_shader (str) – geometry shader source (optional)
tess_control_shader (str) – tessellation control shader source (optional)
tess_evaluation_shader (str) – tessellation evaluation shader source (optional)
defines (dict) – Substitute #defines values in the source (optional)
varyings (Optional[Sequence[str]]) – 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 (str) – 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.
- Return type
- property projection_2d: Tuple[float, float, float, float]#
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)
- property projection_2d_matrix: pyglet.math.Mat4#
Get the current projection matrix. This 4x4 float32 matrix is calculated when setting
projection_2d
.- Type
- pyglet_rendering()[source]#
Context manager for pyglet rendering. Since arcade and pyglet needs slightly different states we needs some initialization and cleanup.
Examples:
with window.ctx.pyglet_rendering(): # Draw with pyglet here
- query(*, samples=True, time=True, primitives=True)#
Create a query object for measuring rendering calls in opengl.
- property scissor: Optional[Tuple[int, int, int, int]]#
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 toNone
.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)
- property screen: arcade.gl.framebuffer.Framebuffer#
The framebuffer for the window.
- Type
Framebuffer
- property stats: arcade.gl.context.ContextStats#
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
- texture(size: Tuple[int, int], *, components: int = 4, dtype: str = 'f1', data: Optional[Any] = None, wrap_x: Optional[ctypes.c_uint] = None, wrap_y: Optional[ctypes.c_uint] = None, filter: Optional[Tuple[ctypes.c_uint, ctypes.c_uint]] = None, samples: int = 0) arcade.gl.texture.Texture #
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
components (int) – Number of components (1: R, 2: RG, 3: RGB, 4: RGBA)
dtype (str) – The data type of each component: f1, f2, f4 / i1, i2, i4 / u1, u2, u4
data (Any) – The texture data (optional). Can be bytes or an object supporting the buffer protocol.
wrap_x (GLenum) – How the texture wraps in x direction
wrap_y (GLenum) – How the texture wraps in y direction
filter (Tuple[GLenum,GLenum]) – Minification and magnification filter
samples (int) – Creates a multisampled texture for values > 0
- property viewport: Tuple[int, int, int, int]#
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)
- property window: pyglet.window.BaseWindow#
The window this context belongs to.
- Type
pyglet.Window