3D Mesh Golang
Table of Contents
1 Go 3D
Adventures in OpenGL
2 Why?
- Port my Javascript Engine (wasm?)
- GPU jobs on low end hardware
- Signed distance function graphing
3 3rd Party Libs
require ( github.com/chsc/gogl v0.0.0-20131111203533-c411acc846b6 github.com/veandco/go-sdl2 v0.3.3 )Take a look
- You'll need CGo; CGO ENABLED=1
- GoGl - OpenGL bindings
- SDL - Simple DirectMedia Layer (SDL bindings (Windowing and sound))
4 Overview - GPU Hookup
- Create shared memory
- Fill shared memory
- Call a shader program
5 Overview - 3D Pipeline
- Pass useful "static" matrices / values
- Vertex shader
- Fragement shader
- Run shader
6 Setup
func initOpenGl(width, height int32) error { gl.Init() gl.Viewport(0, 0, gl.Sizei(width), gl.Sizei(height)) // OpenGL flags gl.Enable(gl.DEPTH_TEST) gl.DepthFunc(gl.LESS) gl.Enable(gl.BLEND) gl.BlendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA) if gl.GetError() != gl.NO_ERROR { return errors.New("Initialsation failed") } return nil }View Code
7 Create a buffer
var vertexBuffer gl.Uint gl.GenBuffers(1, &vertexBuffer) gl.BindBuffer(gl.ARRAY_BUFFER, vertexBuffer) gl.BufferData(gl.ARRAY_BUFFER, gl.Sizeiptr(len(verts)*SizeOfFloat), gl.Pointer(&verts[0]), gl.STATIC_DRAW) if gl.GetError() != gl.NO_ERROR { log.Printf("Vertex bind buffer") }View Code
8 Fill the buffer
buffer := make([]float32, vlen*int(geometry.VertexSize), vlen*int(geometry.VertexSize)) for i := 0; i < vlen; i++ { row := int(i * int(geometry.VertexSize)) buffer[row] = float32(vertices[i].Pos.X) buffer[row+1] = float32(vertices[i].Pos.Y) buffer[row+2] = float32(vertices[i].Pos.Z) ... buffer[row+8] = float32(vertices[i].Normal.X) buffer[row+9] = float32(vertices[i].Normal.Y) buffer[row+10] = float32(vertices[i].Normal.Z) ... } return bufferView Code Cube Data
9 Run a shader
mtw := matrixAsArray(modelToWorld) viewa := matrixAsArray(view) proja := matrixAsArray(proj) gl.UniformMatrix4fv(material.Shader.Program.UniWorld, gl.Sizei(1), gl.FALSE, &mtw[0]) gl.UniformMatrix4fv(material.Shader.Program.UniView, gl.Sizei(1), gl.FALSE, &viewa[0]) gl.UniformMatrix4fv(material.Shader.Program.UniProject, gl.Sizei(1), gl.FALSE, &proja[0]) return r.Draw(mesh, material, drawGl)View Code Vertex Code Fragment Code
10 3) Profit
- Yeah, there is no profit
- … but we can render a Cube
11 Gleaming the Cube
- To move the cube we need the maths.
12 Gotcha - CGo Buffer pointers
gl.DrawElements(gl.TRIANGLES, gl.Sizei(mesh.Resource.Size), gl.UNSIGNED_SHORT, gl.Offset(nil, 0))
13 Gotcha - No Generics
camera.ActiveCamera ccomp := s.ActiveCamera.GetComponent(core.ComponentTypeCamera) cc, ok := ccomp.(*core.ComponentCamera)
const ( ComponentTypeCamera = "*core.ComponentCamera" ComponentTypeRender = "*render.ComponentRender" )
func (ge *Entity) GetComponent(t string) Componenter { tt := "" for q := 0; q < len(ge.components); q++ { tt = fmt.Sprintf("%T", ge.components[q]) switch tt { case t: return ge.components[q] } } return nil }