func (t *TestSuite) TestScaledBox() { filename := "expected_box_scaled.png" t.rlControl.drawFunc <- func() { w, h := t.renderState.window.GetSize() world := newWorld(w, h) box := shapes.NewBox(t.renderState.boxProgram, 100, 100) // Color is yellow box.SetColor(color.RGBA{0, 0, 255, 255}) box.AttachToWorld(world) box.MoveTo(float32(w/2), 0) box.Scale(1.5, 1.5) gl.Clear(gl.COLOR_BUFFER_BIT) box.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) } }
func (t *TestSuite) TestRotatedBox() { filename := "expected_box_rotated_20.png" t.rlControl.drawFunc <- func() { w, h := t.renderState.window.GetSize() world := newWorld(w, h) // Create a 100x100 pixel² box box := shapes.NewBox(t.renderState.boxProgram, 100, 100) box.AttachToWorld(world) // Place the box at the center of the screen box.MoveTo(float32(w/2), 0) // Rotate the box 20 degrees box.Rotate(20.0) gl.Clear(gl.COLOR_BUFFER_BIT) box.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) } }
func (t *TestSuite) TestGroup() { filename := "expected_group.png" t.rlControl.drawFunc <- func() { w, h := t.renderState.window.GetSize() world := newWorld(w, h) // Create first group, 2 small boxes group1 := shapes.NewGroup() b1 := shapes.NewBox(t.renderState.boxProgram, 20, 20) b1.MoveTo(30, 40) b2 := shapes.NewBox(t.renderState.boxProgram, 50, 50) b2.MoveTo(45, -25) b2.Rotate(20.0) group1.Append(b1) group1.Append(b2) // Create the main group group := shapes.NewGroup() group.Append(group1) group.Append(shapes.NewBox(t.renderState.boxProgram, 100, 100)) // Get the second element of the group b3 := group.GetAt(1) b3.MoveTo(float32(w/2), 0) group.AttachToWorld(world) gl.Clear(gl.COLOR_BUFFER_BIT) group.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) } }
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) } }
func (t *TestSuite) TestPartialTextureRotatedBox() { filename := "expected_box_partial_texture_rotated_20.png" t.rlControl.drawFunc <- func() { w, h := t.renderState.window.GetSize() world := newWorld(w, h) // Create a box box := shapes.NewBox(t.renderState.boxProgram, 100, 100) box.AttachToWorld(world) gl.Clear(gl.COLOR_BUFFER_BIT) box.MoveTo(float32(w/2), 0) // Add an image as a texture gopherTexture := world.addImageAsTexture(texFilename) texCoords := []float32{ 0, 0, 0.5, 0, 0, 0.5, 0.5, 0.5, } box.SetTexture(gopherTexture, texCoords) box.Rotate(20.0) box.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 < texDistThreshold, distanceError(distance, filename)) if t.Failed() { saveExpAct(t.outputPath, "failed_"+filename, exp, act) } }
func (t *TestSuite) TestTranslatedBox() { filename := "expected_box_translated_10_10.png" t.rlControl.drawFunc <- func() { w, h := t.renderState.window.GetSize() world := newWorld(w, h) // Place a box on the center of the window box := shapes.NewBox(t.renderState.boxProgram, 100, 100) box.AttachToWorld(world) box.MoveTo(111, 0) gl.Clear(gl.COLOR_BUFFER_BIT) box.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) } }
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) } }
func (t *TestSuite) TestSegment() { filename := "expected_line.png" t.rlControl.drawFunc <- func() { w, h := t.renderState.window.GetSize() world := newWorld(w, h) segment := shapes.NewSegment(t.renderState.segmentProgram, 81.5, -40, 238.5, 44) // Color is yellow segment.SetColor(color.RGBA{255, 0, 0, 255}) segment.AttachToWorld(world) gl.Clear(gl.COLOR_BUFFER_BIT) segment.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 < 0.0009, 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 (t *TestSuite) renderLoopFunc(control *renderLoopControl) loop.LoopFunc { return func(loop loop.Loop) error { // renderState stores rendering state variables such // as the EGL state renderState := new(renderState) // 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(1) ticker.Stop() for { select { case window := <-control.window: renderState.init(window) // restart the ticker with the right // duration ticker = time.NewTicker(time.Duration(time.Second / time.Duration(FramesPerSecond))) // At each tick render a frame and swap buffers. case <-ticker.C: renderState.draw() renderState.window.SwapBuffers() t.testDraw <- testlib.Screenshot(renderState.window) } } } }