func ExampleRebase() { parent1 := NewTransformStack() scale := mgl32.Scale3D(2, 2, 2) rot := mgl32.HomogRotate3DY(mgl32.DegToRad(90)) trans := mgl32.Translate3D(5, 5, 5) parent1.Push(trans) parent1.Push(rot) parent1.Push(scale) parent2 := parent1.Copy() trans2 := mgl32.Translate3D(1, 1, 1) rot2 := mgl32.HomogRotate3DX(mgl32.DegToRad(45)) parent1.Push(trans2) parent1.Push(rot2) // Replay the pushes the changes from parent1 after the copy onto parent2, as if // they had been done on parent2 instead parent2, err := Rebase(parent1, 4, parent2) if err != nil { panic(err) } // Now parent2 and parent 1 should be the same! fmt.Println(parent2.Peek().ApproxEqualThreshold(parent1.Peek(), 1e-4)) // Output: true }
func main() { document := js.Global.Get("document") var viewportScale float32 = 2.0 canvas := document.Call("createElement", "canvas") canvas.Set("id", "canvas") canvas.Set("width", viewportWidth*viewportScale) canvas.Set("height", viewportHeight*viewportScale) canvas.Get("style").Set("width", fmt.Sprintf("%dpx", int(viewportWidth))) canvas.Get("style").Set("height", fmt.Sprintf("%dpx", int(viewportHeight))) document.Get("body").Call("appendChild", canvas) textCanvas := document.Call("createElement", "canvas") textCanvas.Set("id", "text-canvas") textCanvas.Set("width", viewportWidth*viewportScale) textCanvas.Set("height", viewportHeight*viewportScale) textCanvas.Get("style").Set("width", fmt.Sprintf("%dpx", int(viewportWidth))) textCanvas.Get("style").Set("height", fmt.Sprintf("%dpx", int(viewportHeight))) document.Get("body").Call("appendChild", textCanvas) textContext := textCanvas.Call("getContext", "2d") textContext.Call("setTransform", viewportScale, 0, 0, viewportScale, 0, 0) attrs := webgl.DefaultAttributes() attrs.Alpha = false gl, err := webgl.NewContext(canvas, attrs) if err != nil { goggles.Error(err.Error()) return } fragmentShader := gl.CreateShader(gl.FRAGMENT_SHADER) gl.ShaderSource(fragmentShader, fragmentShaderSource) gl.CompileShader(fragmentShader) if !gl.GetShaderParameterb(fragmentShader, gl.COMPILE_STATUS) { goggles.Error(gl.GetShaderInfoLog(fragmentShader)) return } vertexShader := gl.CreateShader(gl.VERTEX_SHADER) gl.ShaderSource(vertexShader, vertexShaderSource) gl.CompileShader(vertexShader) if !gl.GetShaderParameterb(vertexShader, gl.COMPILE_STATUS) { goggles.Error(gl.GetShaderInfoLog(vertexShader)) return } program := gl.CreateProgram() gl.AttachShader(program, vertexShader) gl.AttachShader(program, fragmentShader) gl.LinkProgram(program) if !gl.GetProgramParameterb(program, gl.LINK_STATUS) { goggles.Error(gl.GetProgramInfoLog(program)) return } gl.UseProgram(program) inVertexPositionLocation := gl.GetAttribLocation(program, "inVertexPosition") inVertexColorLocation := gl.GetAttribLocation(program, "inVertexColor") modelViewMatrixLocation := gl.GetUniformLocation(program, "modelViewMatrix") projectionMatrixLocation := gl.GetUniformLocation(program, "projectionMatrix") gl.EnableVertexAttribArray(inVertexPositionLocation) gl.EnableVertexAttribArray(inVertexColorLocation) vertexPositionBuffer := gl.CreateBuffer() gl.BindBuffer(gl.ARRAY_BUFFER, vertexPositionBuffer) gl.BufferData(gl.ARRAY_BUFFER, vertexPositionData, gl.STATIC_DRAW) vertexColorBuffer := gl.CreateBuffer() gl.BindBuffer(gl.ARRAY_BUFFER, vertexColorBuffer) gl.BufferData(gl.ARRAY_BUFFER, vertexColorData, gl.STATIC_DRAW) indexBuffer := gl.CreateBuffer() gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer) gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, indexData, gl.STATIC_DRAW) gl.Viewport(0, 0, int(viewportWidth*viewportScale), int(viewportHeight*viewportScale)) var pitch float32 = 0.0 var yaw float32 = 0.0 var tweenTime float32 = 0.0 var tick func(float32) tick = func(timeMs float32) { textContext.Call("clearRect", 0, 0, viewportWidth, viewportHeight) textContext.Set("font", "12px sans-serif") textContext.Set("fillStyle", "rgb(255, 255, 255)") textContext.Call("fillText", "Hello, world!", 10, 20) time := timeMs / 1000 if tweenTime == 0.0 { tweenTime = time + 1.0 } for tweenTime < time { tweenTime += 1.0 pitch = float32(math.Mod(float64(pitch)+60.0, 360.0)) yaw = float32(math.Mod(float64(yaw)+40.0, 360.0)) } factor := tweenTime - time if factor < 0.0 { factor = 0.0 } else if factor > 1.0 { factor = 1.0 } factor = 1.0 - float32(math.Pow(float64(factor), 4.0)) tweenPitch := pitch + (60.0 * factor) tweenYaw := yaw + (40.0 * factor) gl.ClearColor(0, 0, 0, 1) gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT) gl.Enable(gl.CULL_FACE) gl.FrontFace(gl.CW) modelViewMatrix := mgl32.Ident4(). Mul4(mgl32.Translate3D(0, 0, -4)). Mul4(mgl32.HomogRotate3DX(goggles.DegToRad(tweenPitch))). Mul4(mgl32.HomogRotate3DY(goggles.DegToRad(tweenYaw))) gl.UniformMatrix4fv(modelViewMatrixLocation, false, modelViewMatrix[:]) projectionMatrix := mgl32.Perspective(goggles.DegToRad(60), viewportWidth/viewportHeight, 0.1, 2048) gl.UniformMatrix4fv(projectionMatrixLocation, false, projectionMatrix[:]) gl.BindBuffer(gl.ARRAY_BUFFER, vertexPositionBuffer) gl.VertexAttribPointer(inVertexPositionLocation, 3, gl.FLOAT, false, 0, 0) gl.BindBuffer(gl.ARRAY_BUFFER, vertexColorBuffer) gl.VertexAttribPointer(inVertexColorLocation, 3, gl.FLOAT, false, 0, 0) gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer) gl.DrawElements(gl.TRIANGLES, len(indexData), gl.UNSIGNED_SHORT, 0) goggles.RequestAnimationFrame(tick) } goggles.RequestAnimationFrame(tick) }
func main() { // init glfw if err := glfw.Init(); err != nil { panic(err) } defer glfw.Terminate() glfw.WindowHint(glfw.Resizable, glfw.False) glfw.WindowHint(glfw.ContextVersionMajor, 4) glfw.WindowHint(glfw.ContextVersionMinor, 1) glfw.WindowHint(glfw.OpenGLProfile, glfw.OpenGLCoreProfile) glfw.WindowHint(glfw.OpenGLForwardCompatible, glfw.True) // make an application window window, err := glfw.CreateWindow(windowWidth, windowHeight, "Transform", nil, nil) if err != nil { panic(err) } window.MakeContextCurrent() // init gl if err := gl.Init(); err != nil { panic(err) } fmt.Println("OpenGL version", gl.GoStr(gl.GetString(gl.VERSION))) // create vertex & fragment shader program, err := newProgram(vertexShader, fragmentShader) if err != nil { panic(err) } gl.UseProgram(program) projection := mgl32.Perspective(mgl32.DegToRad(45.0), float32(windowWidth)/windowHeight, 0.1, 10.0) projectionUniform := gl.GetUniformLocation(program, gl.Str("projection\x00")) gl.UniformMatrix4fv(projectionUniform, 1, false, &projection[0]) camera := mgl32.LookAtV( mgl32.Vec3{3, 3, 3}, mgl32.Vec3{0, 0, 0}, mgl32.Vec3{0, 1, 0}, ) cameraUniform := gl.GetUniformLocation(program, gl.Str("camera\x00")) gl.UniformMatrix4fv(cameraUniform, 1, false, &camera[0]) model := mgl32.Ident4() modelUniform := gl.GetUniformLocation(program, gl.Str("model\x00")) gl.UniformMatrix4fv(modelUniform, 1, false, &model[0]) gl.BindFragDataLocation(program, 0, gl.Str("vert\x00")) points := []float32{ -0.9, -0.9, -0.9, 0.9, -0.9, -0.9, 0.9, -0.9, 0.9, -0.9, -0.9, 0.9, -0.9, 0.9, -0.9, 0.9, 0.9, -0.9, 0.9, 0.9, 0.9, -0.9, 0.9, 0.9, } vertices := []uint32{ 0, 1, 1, 2, 2, 3, 3, 0, 0, 4, 1, 5, 2, 6, 3, 7, 4, 5, 5, 6, 6, 7, 7, 4, } // configure the vertex data var vao uint32 gl.GenVertexArrays(1, &vao) gl.BindVertexArray(vao) defer gl.BindVertexArray(0) var vbo uint32 gl.GenBuffers(1, &vbo) gl.BindBuffer(gl.ARRAY_BUFFER, vbo) gl.BufferData(gl.ARRAY_BUFFER, len(points)*4, gl.Ptr(points), gl.STATIC_DRAW) var ibo uint32 gl.GenBuffers(1, &ibo) gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, ibo) gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, len(vertices)*4, gl.Ptr(vertices), gl.STATIC_DRAW) vertAttrib := uint32(gl.GetAttribLocation(program, gl.Str("vert\x00"))) gl.EnableVertexAttribArray(vertAttrib) gl.VertexAttribPointer(vertAttrib, 3, gl.FLOAT, false, 3*4, gl.PtrOffset(0)) // global settings gl.Enable(gl.DEPTH_TEST) gl.DepthFunc(gl.LESS) gl.ClearColor(0.0, 0.0, 0.0, 1.0) angleX := 0.0 angleY := 0.0 angleZ := 0.0 previousTime := glfw.GetTime() for !window.ShouldClose() { gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT) time := glfw.GetTime() elapsed := time - previousTime previousTime = time angleX += math.Sin((elapsed / period) * math.Pi * 2.0) angleY += math.Sin((elapsed / period) / 6.0 * math.Pi * 2.0) angleZ += math.Sin((elapsed / period) / 3.0 * math.Pi * 2.0) model = mgl32.HomogRotate3DY(float32(angleY)).Mul4(mgl32.HomogRotate3DX(float32(angleX))).Mul4(mgl32.HomogRotate3DZ(float32(angleZ))) gl.UseProgram(program) gl.UniformMatrix4fv(modelUniform, 1, false, &model[0]) gl.BindVertexArray(vao) gl.DrawElements(gl.LINES, int32(len(vertices)), gl.UNSIGNED_INT, gl.PtrOffset(0)) window.SwapBuffers() glfw.PollEvents() } }