GL Contexts

All Jitter OpenGL rendering happens within a named context. An OpenGL context is typically created using jit.gl.render combined with one of three objects that serve as output for rendering. These output objects are jit.window, jit.pwindow, and jit.matrix. For simplicity, the jit.world object combines jit.gl.render and jit.window into a single object, and is recommended for most cases. The name given to the output object (most often jit.window) sets the rendering context name. Contexts that don’t have an explicit name are given an automatically generated name.

In order to draw, Jitter OpenGL objects must be associated with a valid context, either by giving the context name as an argument or implicitly (see below). The jit.gl.render and jit.world objects will automatically draw any jit.gl objects associated with them. For all jit.gl objects, the first argument sets the drawto attribute. It tells the object where to draw to. The jit.gl.render or jit.world object will drive the rendering of each frame to the output window, signaling all objects associated with their context to draw. By default, all jit.gl objects that draw geometry will be set to automatically draw (@automatic 1) when jit.gl.render signals.

Implicit Contexts

It is not necessary to specify a context name for every jit.gl or video object. Instead, we can make use of implicit contexts. Implicit contexts automatically assign a name to an object’s drawto attribute. This can be handy in patches where there is only one context in use and makes it easier to copy work from one patch to another.

If an object is in the same patcher as a valid OpenGL context, the jit.gl system will automatically assign the context name to the object’s drawto. Additionally, if a jit.gl or video object is in a sub-patch of a patch with a valid OpenGL context, it will be assigned to that context name.

GL objects added implicitly to a jit.world GL context

NOTE: Some care should be taken when using implicit contexts. Certain situations may produce unexpected results. If a patch with a GL context contains a sub-patch with another GL context (e.g. a jit.pwindow), which contains another sub-patch with jit.gl objects, those sub-sub-patch objects will be associated with the first GL context they find. In this case it will be the sub-patch jit.pwindow context rather than the parent patch context. For cases like this it is better to explicitly assign the context name to your jit.gl objects.

Shared Contexts

GL contexts by default are not able to display textures owned by other GL contexts. For example, if a jit.gl.texture object is associated with a context named ctx1 that texture cannot be drawn by a jit.gl.videoplane associated with a context named ctx2. This also applies to objects with internal jit.gl.texture resources, such as jit.movie and jit.gl.slab. However sometimes sharing texture resources is desirable. To enable sharing of textures between GL contexts, simply set @shared 1 on the jit.window, jit.pwindow, or jit.world object. The shared attribute must be set on both the context that owns the shared resource, and the context that needs to share the resource.

This technique is typically utilized to create a preview window in a patch. This allows users to efficiently have multiple windows displaying a single GL scene.

Creating a preview window via shared contexts

Sub-Contexts With jit.gl.node

A sub-context is a rendering context within a rendering context. Within a top-level context, there can be many sub-contexts. Sub-contexts are created by jit.gl.node objects. The name of a sub-context is given by jit.gl.node’s name attribute. Any object whose drawto attribute is set to the name of a jit.gl.node belongs to the node’s sub-context. There are no restrictions on how sub-contexts can be organized, so it’s perfectly valid to nest sub-contexts within each other by placing a jit.gl.node within another jit.gl.node’s sub-context.

To make organizing jit.gl objects into groups simpler, a patch cord can be connected from jit.gl.node’s middle inlet to any jit.gl objects. When the connection is made, the object’s drawto will automatically be set to the node’s name such that it becomes part of the sub-context.

jit.gl.node and Implicit Contexts

As described above, with implicit contexts jit.gl objects automatically attach to the first context that they encounter if they aren’t explicitly attached to a context with the drawto attribute. Since jit.gl.node also operates as a rendering context, jit.gl objects can attach to nodes implicitly.

If a jit.gl.node and a jit.window or jit.pwindow are in the same patch, the window will take priority over the node when objects search for an implicit context. A jit.gl object will only attach to a jit.gl.node implicitly if it is the only context generating object in the patch. A common idiom is to put a jit.gl.node object in a subpatch with other jit.gl objects, forcing them to implicitly attach to the node.

3 ways GL objects can be added to jit.gl.node sub-contexts

Grouping Objects Into "Scenes"

Using jit.gl.node, jit.gl objects can be grouped into "scenes". If an object belongs to a node’s sub-context, the node controls how and when the object draws. The spatial transformation attributes position, rotate, and scale on a node are applied to all of the objects in the node’s sub-context. The node itself doesn’t draw any geometry, it simply groups objects together. Common jit.gl attributes applied to jit.gl.node, will apply to every jit.gl object associated with that sub-context.

The jit.gl.node layer and enable attributes allow control of when the scene is drawn (relative to other objects in the parent context), and whether the scene is drawn at all. If a jit.gl.node’s enable attribute is set to 0, associated objects will not be drawn. This feature can be used to turn on and off the drawing of entire groups of objects from one point.

Controlling scene properties with jit.gl.node

Rendering Sub-Contexts to Texture

Jit.gl.node has a capture attribute that if enabled will render its sub-context to an internal texture. When capture is enabled, jit.gl.node outputs a jit.gl.texture out its left-most outlet every time it draws itself. In this mode, jit.gl.slab and jit.gl.pix objects can be chained to the node to create post-processing effects such as blurring, glow, temporal blending, etc.

jit.world

As mentioned above, the jit.world object encapsulates a GL context (jit.gl.render and jit.window) into a single object. In most cases, using jit.world will provide the most convenient way to get started in Jitter. The object also contains an internal jit.gl.node object, providing sub-context functionality as well. The first argument and name attribute of jit.world sets the name attribute of the internal jit.gl.node. For most purposes, the internal jit.gl.node can be ignored and jit.world can be treated like a master rendering context. To set the master render context name, use the drawto attribute. If not set explicitly, it will be automatically generated.

Any objects associated with the jit.world are included in the sub-context. This makes it very easy to render the scene to a texture or matrix. Two attributes expose this functionality - output_texture and output_matrix. Similar to jit.gl.node, the captured scene is output from the left-most outlet when capturing is enabled. Texture output (@output_texture 1) should be used in cases where scene renders will be passed back to OpenGL objects or used in inter-application systems like Syphon or Spout.

Another option for scene output from jit.world is matrix output, enabled via the output_matrix attribute. This causes the captured texture output to be rendered into an internal jit.matrix object, via matrix readback. When output_matrix is enabled, the matrix is sent out the left-most outlet instead of the texture. This is useful primarily for recording video captures or saving image files of the scene render.

Displaylink

The displaylink attribute enables a Mac only feature of jit.world. When enabled, the Mac OS will trigger the jit.world context rendering in sync with the connected hardware display’s refresh rate (typically 60 hz). This means every time the display redraws, the jit.world context will trigger a redraw in sync with the display. There is an unexpected side-effect of displaylink rendering, where GUI updates may cause stalls in the rendering, more so than if displaylink is disabled. Therefore, users are recommended to try both modes and determine which better fits their needs.