v0.0.0-...-793ea6c Latest Latest

This package is not in the latest version of its module.

Go to latest
Published: Oct 24, 2021 License: BSD-3-Clause Imports: 19 Imported by: 2



Package gl2 provides a OpenGL 2 based graphics device.

The behavior of the device is fully defined in the gfx package, and as such the following documentation only makes note of strictly OpenGL related caveats (like initialization, etc).

Window Toolkit

The device operates independently of the window toolkit in use. It can work well with any window toolkit that provides an OpenGL 2 feature-level context (GLFW, SDL, QT, etc).

If you just want to open a window and draw graphics to it and don't care about the specifics, the simpler gfx/window package should be used instead:

Feedback Loops

When performing render-to-texture (RTT), feedback loops are explicitly prohibited.

This means that the device will panic if you attempt to draw an object to a RTT canvas when the object uses the literal RTT texture in itself.

That is, drawing an object with a texture that of the final render destination will panic. Such recursive drawing is prohibited by OpenGL, and as such is now allowed.


The gfx package allows turning on and off mipmapping of a loaded texture dynamically by setting it's minification filter to a mipmapped or non-mipmapped one. This OpenGL device reflects this behavior, but with a small caveat:

Mipmapping can only be toggled post-load in the event that the texture was first loaded with a mipmapped filter, or else the request is ignored and the texture filter is not changed.

This is done for performance reasons, turning on mipmapping post-load time would require a full texture reload (and having it on by default would use more memory due to mipmaps always being generated).


A gfx.Shader will have all of it's inputs (from the Shader.Inputs map) mapped by name to uniforms within the fragment and vertex shader programs.

If you do not intend to utilize a uniform value, then omit it in your GLSL code and it will not be fed into the GLSL program.

The default uniforms are:

uniform mat4 Model;       -> Model matrix from gfx.Object.Transform
uniform mat4 View;        -> View matrix from gfx.Camera.Transform
uniform mat4 Projection;  -> Projection matrix from gfx.Camera.Projection
uniform mat4 MVP;         -> Premultiplied Model/View/Projection matrix.
uniform bool BinaryAlpha; -> See below.

BinaryAlpha is a boolean uniform value that informs the shader of the chosen alpha transparency mode of an object. It is set to true if the gfx.Object being drawn has a gfx.State.AlphaMode of gfx.BinaryAlpha or if the alpha mode is gfx.AlphaToCoverage but the GPU does not support it.

Vertex Attributes

A mesh will have all of it's attributes (from the Mesh.Attribs map) mapped by name to attributes within the GLSL fragment and vertex shader programs.

Like uniforms, if you do not intend to utilize a attribute value, then omit it in your GLSL code and it will simply not be fed into the GLSL program.

The default vertex attributes are:

attribute vec3 Vertex;      -> from gfx.Mesh.Vertices and gfx.Mesh.Indices
attribute vec4 Color;       -> from gfx.Mesh.Colors
attribute vec3 Bary;        -> from gfx.Mesh.Bary
attribute vec2 TexCoord[N]; -> [N] is the nth index of gfx.Mesh.TexCoords

Uniform And Attribute Types

In both the case of uniforms as well as attributes, data types from the gfx package are mapped directly to their GLSL equivilent:

gfx.Vec4     -> vec4
gfx.Vec3     -> vec3
gfx.Color    -> vec4 (GLSL does not have a dedicated color type)
gfx.TexCoord -> vec2 (GLSL does not have a dedicated texture coordinate type)

Slices are mapped directly to GLSL arrays, which can be fixed or dynamically sized, standard GLSL restrictions apply (such as a lack of dynamic indexing on dynamically sized arrays, etc).

Basic Usage

Functions recieved over the device's execution channel should be executed under the presence of the OpenGL context, when a device function returns true gfx.Device.Canvas.Render has been called meaning the frame is finished and the window's buffers should be swapped.

func main() {
    // Always make proper use of LockOSThread! The OpenGL context is tied
    // to the OS thread.

    // Initialize OpenGL, through your window toolkit of choice.

    // Initialize the device, under the OpenGL context.
    d, err := gl2.New()

    // Main loop, execute device functions.
    exec := device.Exec()
    for {
        if window.Closed() {
            // Cleanup the device.

        // Wait for a task from the device to execute.
        f := <-exec
        if f() {
            // A frame was rendered, swap the buffers.


User applications (i.e. not this device itself) can be debugged using the SetDebugOutput method of the Device interface exposed by this package. This has little to no overhead.

More extensive debugging can be enabled via the "gfxdebug" build tag, which enables debugging of the OpenGL device itself (not user code). Do not use this build tag except when debugging, as it's performance is purely driver implementation dependant. This form of debugging should be used with a debug OpenGL context.


The examples repository contains several examples which utilize the gfx core packages. Please see:



This section is empty.


View Source
var ErrInvalidVersion = errors.New("invalid OpenGL version; must be at least OpenGL 2.0")

ErrInvalidVersion is returned by New when attempting to create a OpenGL 2 device in a lesser version OpenGL context.


This section is empty.


type Device

type Device interface {

	// Exec returns the device's execution channel.
	// Whenever the device needs to perform a OpenGL task of any sort it is
	// done through this execution channel.
	// If a function returns true, it is effectively a signal that the device's
	// canvas had it's Render() method called. Thus the frame is complete and
	// has been fully rendered, and you should now swap the window's buffers.
	// The functions sent to this channel must be executed under the presence
	// of an OpenGL context.
	Exec() chan func() bool

	// UpdateBounds updates the effective bounding rectangle of this device.
	// It must be called whenever the OpenGL framebuffer should change (e.g. on
	// window resize).
	UpdateBounds(bounds image.Rectangle)

	// SetDebugOutput sets the writer, w, to write debug output to. It will
	// mostly contain just shader debug information, but other information may
	// be written in future versions as well.
	SetDebugOutput(w io.Writer)

	// RestoreState immediately restores the OpenGL state to what it was before
	// a call to Canvas.Draw, Canvas.Clear[Depth][Stencil], etc occurred.
	// This device keeps track in full of the OpenGL graphics state in it's
	// context. It does not expect for outsiders to touch the OpenGL state, and
	// as such can optimize many edge cases. It is able to carry OpenGL state
	// across multiple frames, even. For more information see:
	//  internal/glc/state.go
	// Using this function you may place OpenGL calls that modify the graphics
	// state inbetween Canvas operations, like so:
	//  canvas.Clear(...)
	//  canvas.Draw(...)
	//  glFoo()
	//  device.RestoreState()
	// This function must be called under the presence of an OpenGL context.

	// Destroy immediately destroys this device and it's associated assets.
	// This function must be called under the presence of an OpenGL context.

Device is a OpenGL 2 based graphics device.

It runs independant of the window management library being used (GLFW, SDL, QT, etc), all it needs is a valid OpenGL 2 context.

func New

func New(opts ...Option) (Device, error)

New returns a new OpenGL 2 graphics device. If any error occurs it is returned along with a nil device.

It is only safe to call this function under the presence of an OpenGL 2 feature level context.

type Option

type Option func(d *device)

Option represents a single option function.

func DebugOutput

func DebugOutput(w io.Writer) Option

DebugOutput specifies the writer, w, as the destination for the device to write debug output to.

It will mostly contain just shader debug information, but other information may be written in future versions as well.

func Share

func Share(other Device) Option

Share is an option that specifies that this device should request the other device to perform loading of all assets.

The given other device must be from this package specifically, or else a panic will occur.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL