// NewGameState creates a new game state. It needs a window onto which // render the scene. func NewGameState(window mandala.Window) *GameState { s := new(GameState) s.window = window s.window.MakeContextCurrent() w, h := window.GetSize() s.World = NewWorld(w, h) s.Fps = DefaultFps // Uncomment the following lines to generate the world // starting from a string (defined in world.go) // s.World.CreateFromString(pyramid) // s.World.setGround(newGround(s.World, 0, float32(10), float32(w), float32(10))) s.World.CreateFromSvg("raw/world.svg") gl.Enable(gl.BLEND) gl.BlendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA) gl.ClearColor(0.0, 0.0, 0.0, 1.0) gl.Clear(gl.COLOR_BUFFER_BIT) return s }
// Run runs renderLoop. The loop renders a frame and swaps the buffer // at each tick received. func renderLoopFunc(control *renderLoopControl) loop.LoopFunc { return func(loop loop.Loop) error { var window mandala.Window // Lock/unlock the loop to the current OS thread. This is // necessary because OpenGL functions should be called from // the same thread. runtime.LockOSThread() defer runtime.UnlockOSThread() // Create an instance of ticker and immediately stop // it because we don't want to swap buffers before // initializing a rendering state. ticker := time.NewTicker(time.Duration(1e9 / int(FRAMES_PER_SECOND))) ticker.Stop() for { select { case window = <-control.window: ticker.Stop() window.MakeContextCurrent() width, height := window.GetSize() gl.Viewport(0, 0, width, height) mandala.Logf("Restarting rendering loop...") ticker = time.NewTicker(time.Duration(1e9 / int(FRAMES_PER_SECOND))) // Compute window radius windowRadius = math.Sqrt(math.Pow(float64(height), 2) + math.Pow(float64(width), 2)) //gl.Init() gl.Disable(gl.DEPTH_TEST) // antialiasing gl.Enable(gl.BLEND) gl.BlendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA) //gl.Enable(gl.LINE_SMOOTH) // At each tick render a frame and swap buffers. case <-ticker.C: draw() window.SwapBuffers() case event := <-control.pause: ticker.Stop() event.Paused <- true case <-control.resume: case <-loop.ShallStop(): ticker.Stop() return nil } } } }
func NewWorld(width, height int) *World { gl.Enable(gl.DEPTH_TEST) gl.ClearColor(0.0, 0.0, 0.0, 0.0) gl.Viewport(0, 0, gl.Sizei(width), gl.Sizei(height)) return &World{ Width: width, Height: height, objects: make([]*Cube, 0), projection: mathgl.Perspective(60, float32(width)/float32(height), 1, 20), view: mathgl.Ident4f(), } }
func (t *TestSuite) TestRotate() { filename := "expected_hello_world_rotated.png" t.rlControl.drawFunc <- func() { w, h := t.renderState.window.GetSize() world := newWorld(w, h) // Render an "Hello World" string text, err := world.font.Printf("%s", "Hello World!") if err != nil { panic(err) } text.AttachToWorld(world) text.MoveTo(float32(world.width/2)+5, -5.0) text.Rotate(45) gl.Enable(gl.BLEND) gl.BlendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA) gl.Clear(gl.COLOR_BUFFER_BIT) text.Draw() t.testDraw <- testlib.Screenshot(t.renderState.window) t.renderState.window.SwapBuffers() } distance, exp, act, err := testlib.TestImage(filename, <-t.testDraw, imagetest.Center) if err != nil { panic(err) } t.True(distance < distanceThreshold, distanceError(distance, filename)) if t.Failed() { saveExpAct(t.outputPath, "failed_"+filename, exp, act) } }