Render Contexts

Trial is "backend agnostic" in that it can work with several underlying libraries to handle the OpenGL context and window management. The standard and most well-tested backend is the GLFW integration through trial-glfw.

Typically, management of the context is handled by main and the associated launch. For highest convenience, you'll probably just want to create your own wrapper around launch that passes the appropriate arguments for context construction via the :context initarg.

Context Objects

The context combines both a window and an OpenGL context, treating them as the same. It is expected that games do not utilise multiple windows, instead using virtual windows within the main game window if required.

There may be multiple context instances in flight at once, in order to allow asynchronous upload of resources such as textures through shared contexts in background threads. However, there can only be one primary context in flight at a time, and only one context of any kind can be current to any one thread at a time.

In order to issue OpenGL commands, an appropriate context must be current on the thread. Many commands are only available on the primary context. Typically you will only need one context, and with the render-loop class, all the drawing will be contained on one thread anyway.

The base context object has a rather wide API to interact with. The context itself has a handler to which it sends events whenever input or other changes come along. Typically the handler will be a main instance, which then sends the events along to the scene for delivery. See the event-loop.

Context Interaction

Window Interaction

Note that these functions may be no-ops on some backends where the concept of a "window" does not apply.

System Interaction

Some interactions with the rest of the operating system are also provided:

Video Modes and Monitors

One important part is the handling of "video modes" or screen resolution and refresh rate. Trial defines a video mode "structure" as a list composed out of: (width height [refresh-rate [display-descriptor-string]]).

A user may have multiple monitors connected, and the available list of video modes for each may be different. To list the available monitors, use list-monitors, and the current monitor the window is on can be retrieved with current-monitor.

The monitor structure is backend-dependent, but must support getting its string name. To get the monitor back from its name, use find-monitor. If the monitor has since been removed or is not present, it may not be returned even with a valid name.

To get the video modes available, use list-video-modes. To activate one, pass the mode to show. If the mode came from a monitor listing, it will include the monitor's name, ensuring that the window will be shown on the correct monitor.


Aside from the keyboard and mouse input events, the context is also responsible for sending the following events:

Context Management

Typically managing a context directly is cumbersome and a lot of extra scaffolding is needed. The first part is the render-loop. On its own, the render loop does not care about a context at all. ALl it does is, after being started, it maintains a thread that calls update and render on the loop in regular intervals – fixed timestep intervals for update and as much as possible under the constraints of frame limits and such for render.

The display as a render-loop upgrade then ties the loop behaviour to an actual context instance, manages the cleanup and setup of the context, and so on. It introduces setup-rendering for initial setup of GL attributes and modes.

Finally, the main instance ties everything together with a scene for event management, and a loader for resource management (see resources). This is typically what you want to subclass for your own games, as it provides most of the convenience and is required for many of the other integrations with other subsystems.