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 newBox(width, height float32) *box { var err error box := new(box) // Sound player box.player, err = mandala.NewAudioPlayer() if err != nil { mandala.Fatalf("%s\n", err.Error()) } // Chipmunk body box.physicsShape = chipmunk.NewBox( vect.Vect{0, 0}, vect.Float(width), vect.Float(height), ) box.physicsShape.SetElasticity(BoxElasticity) box.physicsBody = chipmunk.NewBody(vect.Float(BoxMass), box.physicsShape.Moment(float32(BoxMass))) box.physicsBody.AddShape(box.physicsShape) box.physicsBody.CallbackHandler = callbacks{} // OpenGL shape box.openglShape = shapes.NewBox(width, height) return box }
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) } }
// loadFont loads the given font data. This does not deal with font scaling. // Scaling should be handled by the independent Bitmap/Truetype loaders. // We therefore expect the supplied image and charset to already be adjusted // to the correct font scale. // // The image should hold a sprite sheet, defining the graphical layout for // every glyph. The config describes font metadata. func loadFont(texture Texture, config *FontConfig) (f *Font, err error) { f = new(Font) f.program = shaders.NewProgram(shapes.DefaultBoxFS, shapes.DefaultBoxVS) f.config = config // // Resize image to next power-of-two. // img = glh.Pow2Image(img).(*image.RGBA) ib := texture.Bounds() texWidth := float32(ib.Dx()) texHeight := float32(ib.Dy()) for _, glyph := range config.Glyphs { // Update max glyph bounds. if glyph.Width > f.maxGlyphWidth { f.maxGlyphWidth = glyph.Width } if glyph.Height > f.maxGlyphHeight { f.maxGlyphHeight = glyph.Height } // Quad width/height vw := float32(glyph.Width) vh := float32(glyph.Height) // Texture coordinate offsets. glyph.tx1 = float32(glyph.X) / texWidth glyph.ty1 = 1.0 - float32(glyph.Y)/texHeight glyph.tx2 = (float32(glyph.X) + vw) / texWidth glyph.ty2 = 1.0 - (float32(glyph.Y)+vh)/texHeight // Advance width (or height if we render top-to-bottom) // adv := float32(glyph.Advance) shape := shapes.NewBox(f.program, vw, vh) // shape.SetColor(color.White) shape.SetTexture( texture.Id(), []float32{ glyph.tx1, glyph.ty2, glyph.tx2, glyph.ty2, glyph.tx1, glyph.ty1, glyph.tx2, glyph.ty1, }, ) f.listbase = append(f.listbase, shape) } return }
func (t *TestSuite) TestShape() { box := shapes.NewBox(t.renderState.boxProgram, 10, 20) // Color c := box.Color() nc := box.NColor() t.Equal(color.RGBA{0, 0, 255, 255}, c) t.Equal([4]float32{0, 0, 1, 1}, nc) box.SetColor(color.RGBA{0xaa, 0xaa, 0xaa, 0xff}) c = box.Color() nc = box.NColor() t.Equal(color.RGBA{170, 170, 170, 255}, c) t.Equal([4]float32{0.6666667, 0.6666667, 0.6666667, 1}, nc) // GetSize size := box.Bounds().Size() w, h := size.X, size.Y t.True(w == 10) t.True(h == 20) // Center x, y := box.Center() t.Equal(float32(0), x) t.Equal(float32(0), y) // Center after translation winW, winH := t.renderState.window.GetSize() world := newWorld(winW, winH) box.AttachToWorld(world) box.MoveTo(10, 20) x, y = box.Center() t.Equal(float32(10), x) t.Equal(float32(20), y) // Angle after rotation box.Rotate(10) angle := box.Angle() t.Equal(float32(10), angle) // String representation t.Equal("(5,10)-(15,30)", box.String()) }
func newBox(world *World, width, height float32) *Box { box := new(Box) // Chipmunk body box.physicsShape = chipmunk.NewBox( vect.Vect{0, 0}, vect.Float(width), vect.Float(height), ) box.physicsShape.SetElasticity(BoxElasticity) box.physicsBody = chipmunk.NewBody(vect.Float(BoxMass), box.physicsShape.Moment(float32(BoxMass))) box.physicsBody.AddShape(box.physicsShape) box.physicsBody.CallbackHandler = callbacks{} // OpenGL shape box.openglShape = shapes.NewBox(world.boxProgramShader, width, height) return box }
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) } }