Gosigl: A really simple Go OpenGL wrapper for really simple rendering
December 28, 2018
A quick project I spent the last couple of evenings writing, while I was working on https://github.com/Galaco/Gource-Engine. I found my basic data structures were becoming polluted with a bunch of graphics api calls. Several modules had a bunch of magic openGL calls to correctlybind themselves for rendering by a client, even though its common code that may not require a rendering context.
I came around to wanting to refactor this out, and allow all GPU bindings to exist solely in the client module. I quickly came up with a 2 step process for this; the first was to replace all api calls with a simplied minimal-call api. Later this can be removed entirely quickly and cleanly, with the secondary benefit of simplify a change in what api to use (hopefully OpenGL->Vulkan).
For now though, I wrote Gosigl (Go Simplified OpenGL). A super lightweight OpenGL abstraction to minimise api calls to do common things, like texture and mesh generation and binding.
Texture
Creating and binding a glTexture2D
is now this simple:
buf := gosigl.CreateTexture2D(
gosigl.TextureSlot(0), // Assign texture slot
width, // texture width
height, // texture height
pixelData, // []byte raw colour data
gosigl.RGB, // colour data format
false) // true = clamp to edge, false = repeat
gosigl.BindTexture2D(gosigl.TextureSlot(0), buf)
Mesh
Creating VAO/VBO’s for meshes is also really simple:
mesh := gosigl.NewMesh(vertices) // vertices = []float32
gosigl.CreateVertexAttribute(mesh, uvs, 2) // uvs = []float32, 2 = numPerVertex
gosigl.CreateVertexAttribute(mesh, normals, 3)
gosigl.FinishMesh()
To draw that mesh:
gosigl.BindMesh(mesh) // bind vbo
gosigl.DrawArray(offset, length) // draw from bound
And thats all there is to it. 1 call to create a Texture, 1 call to bind it. 1 calls to create a renderable VAO, with a single additional call per additional attribute.