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 buffer
View 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
}