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
}