func (t *TestSuite) TestRenderWorld() { filename := "expected_world.png" t.rlControl.drawFunc <- func() { // initialize the default source to a deterministic // state rand.Seed(1234) state := lib.NewGameState(t.renderState.window) state.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) } }
// 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 state *lib.GameState // 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(FramesPerSecond))) ticker.Stop() fpsTicker := time.NewTicker(time.Duration(time.Second)) fpsTicker.Stop() for { select { case init := <-control.init: window := init.window activity := init.activity ticker.Stop() state = lib.NewGameState(window) width, height := window.GetSize() gl.Viewport(0, 0, gl.Sizei(width), gl.Sizei(height)) ShowAdPopup(activity) ticker = time.NewTicker(time.Duration(time.Second / time.Duration(FramesPerSecond))) fpsTicker = time.NewTicker(time.Duration(time.Second)) case tap := <-control.tapEvent: state.World.Remove(tap[0], tap[1]) // At each tick render a frame and swap buffers. case <-ticker.C: state.Frames++ state.Draw() state.SwapBuffers() case <-fpsTicker.C: state.Fps = state.Frames state.Frames = 0 case event := <-control.pause: ticker.Stop() fpsTicker.Stop() state.World.Destroy() event.Paused <- true case <-control.resume: case <-loop.ShallStop(): ticker.Stop() return nil } } } }