// TODO this should walk a seperate visibility structure. func (r *GLRenderer) Render(world *World) { r.View.Update() m := r.View.Matrix(r.View.Position) // Take the inverse of the camera matrix r.ViewMatrix = s3dm.Mat4{ m[0], m[4], m[8], 0, m[1], m[5], m[9], 0, m[2], m[6], m[10], 0, -(m[0]*m[12] + m[1]*m[13] + m[2]*m[14]), -(m[4]*m[12] + m[5]*m[13] + m[6]*m[14]), -(m[8]*m[12] + m[9]*m[13] + m[10]*m[14]), 1} GL <- func() { gl33.Clear(gl33.COLOR_BUFFER_BIT | gl33.DEPTH_BUFFER_BIT) vpMatrix := r.PerspectiveMatrix.Mul(r.ViewMatrix) pass := PassOpaque hud := false render := func(leaf Leaf) { if pass&leaf.Passes() == 0 { return } var modelMatrix s3dm.Mat4 if hud { modelMatrix = leaf.XformNode().WorldXform.Matrix(s3dm.Position{}) } else { modelMatrix = leaf.XformNode().WorldXform.Matrix(r.View.Position) } mvpMatrix := vpMatrix.Mul(modelMatrix) if !hud { if leaf.AABB().IntersectsFrustum(r.View.Frustum) < 0 { return } } leaf.Render(r.View, mvpMatrix, pass) } world.Root.Walk(render) pass = PassTranslucent world.Root.Walk(render) if world.Skybox != nil { world.Skybox.Render(r.View, vpMatrix, PassOpaque) } vpMatrix = r.OrthographicMatrix hud = true pass = PassOpaque world.Gui.Walk(render) pass = PassTranslucent world.Gui.Walk(render) sdl.GL_SwapBuffers() } }
func main() { runtime.LockOSThread() flag.Parse() if *workers <= 0 { *workers = 1 } runtime.GOMAXPROCS(*workers + 1) buildPalette() sdl.Init(sdl.INIT_VIDEO) defer sdl.Quit() if !*noVSync { sdl.GL_SetAttribute(sdl.GL_SWAP_CONTROL, 1) } if sdl.SetVideoMode(512, 512, 32, sdl.OPENGL) == nil { panic("sdl error") } sdl.WM_SetCaption("Gomandel", "Gomandel") if err := gl.Init(); err != nil { panic(err) } gl.Enable(gl.TEXTURE_2D) gl.Viewport(0, 0, 512, 512) gl.MatrixMode(gl.PROJECTION) gl.LoadIdentity() gl.Ortho(0, 512, 512, 0, -1, 1) gl.ClearColor(0, 0, 0, 0) //----------------------------------------------------------------------------- var dndDragging bool = false var dnd3 bool = false var dndStart Point var dndEnd Point initialRect := Rect{-1.5, -1.5, 3, 3} rect := initialRect tm := NewTileManager(512, 512) tm.ZoomRequest(&rect) running := true for running { for { var event interface{} select { case event = <-sdl.Events: default: } if event == nil { break } switch e := event.(type) { case sdl.QuitEvent: running = false case sdl.MouseButtonEvent: if e.Type == sdl.MOUSEBUTTONDOWN { dndDragging = true dndStart.X = gl.Int(e.X) dndStart.Y = gl.Int(e.Y) dndEnd = dndStart if e.Button == 3 { dnd3 = true } else { dndDragging = true } } else { dndDragging = false dndEnd.X = gl.Int(e.X) dndEnd.Y = gl.Int(e.Y) switch e.Button { case 1: rect = rectFromSelection(dndStart, dndEnd, 512, 512, rect) tm.ZoomRequest(&rect) case 2: rect = initialRect tm.ZoomRequest(&rect) case 3: dnd3 = false } } case sdl.MouseMotionEvent: if dnd3 { dndEnd.X = gl.Int(e.X) dndEnd.Y = gl.Int(e.Y) rect = moveRectBy(rect, dndStart, dndEnd, 512, 512) tm.MoveRequest(rect) dndStart = dndEnd } else if dndDragging { dndEnd.X = gl.Int(e.X) dndEnd.Y = gl.Int(e.Y) } } } tm.Update() gl.Clear(gl.COLOR_BUFFER_BIT) tm.Draw() gl.BindTexture(gl.TEXTURE_2D, 0) if dndDragging { drawSelection(dndStart, dndEnd) } sdl.GL_SwapBuffers() } }