From 2457abfa933359127604439c70a08e42e527a669 Mon Sep 17 00:00:00 2001 From: Nigel Tao Date: Wed, 29 Oct 2014 09:19:38 +1100 Subject: [PATCH] go.mobile/f32: add a f32.Bytes function. LGTM=crawshaw R=crawshaw CC=golang-codereviews https://golang.org/cl/166720044 --- example/basic/main.go | 34 ++++++++++++---------------------- f32/f32.go | 36 +++++++++++++++++++++++++++++++++++- f32/f32_test.go | 31 +++++++++++++++++++++++++++++++ gl/glutil/glimage.go | 18 ++++-------------- 4 files changed, 82 insertions(+), 37 deletions(-) diff --git a/example/basic/main.go b/example/basic/main.go index e4909d5..c03f508 100644 --- a/example/basic/main.go +++ b/example/basic/main.go @@ -2,17 +2,17 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// An android app that draws a green triangle on a red background. +// An app that draws a green triangle on a red background. package main import ( - "bytes" "encoding/binary" "log" "code.google.com/p/go.mobile/app" "code.google.com/p/go.mobile/app/debug" "code.google.com/p/go.mobile/event" + "code.google.com/p/go.mobile/f32" "code.google.com/p/go.mobile/geom" "code.google.com/p/go.mobile/gl" "code.google.com/p/go.mobile/gl/glutil" @@ -30,7 +30,6 @@ var ( ) func main() { - log.Printf("basic example starting") app.Run(app.Callbacks{ Draw: draw, Touch: touch, @@ -64,11 +63,10 @@ func touch(t event.Touch) { func draw() { if program.Value == 0 { initGL() - log.Printf("example/basic rendering initialized") } gl.ClearColor(1, 0, 0, 1) - gl.Clear(gl.DEPTH_BUFFER_BIT | gl.COLOR_BUFFER_BIT) + gl.Clear(gl.COLOR_BUFFER_BIT) gl.UseProgram(program) @@ -89,24 +87,16 @@ func draw() { debug.DrawFPS() } -var triangleData []byte +var triangleData = f32.Bytes(binary.LittleEndian, + 0.0, 0.4, 0.0, // top left + 0.0, 0.0, 0.0, // bottom left + 0.4, 0.0, 0.0, // bottom right +) -func init() { - buf := new(bytes.Buffer) - if err := binary.Write(buf, binary.LittleEndian, triangleCoords); err != nil { - log.Fatal(err) - } - triangleData = buf.Bytes() -} - -const coordsPerVertex = 3 - -var triangleCoords = []float32{ - 0, 0.4, 0, // top left - 0, 0, 0, // bottom left - 0.4, 0, 0, // bottom right -} -var vertexCount = len(triangleCoords) / coordsPerVertex +const ( + coordsPerVertex = 3 + vertexCount = 3 +) const vertexShader = `#version 100 uniform vec2 offset; diff --git a/f32/f32.go b/f32/f32.go index e194a4b..b466d9f 100644 --- a/f32/f32.go +++ b/f32/f32.go @@ -25,7 +25,11 @@ // non-obvious. Be prepared for the package name to change. package f32 -import "math" +import ( + "encoding/binary" + "fmt" + "math" +) type Radian float32 @@ -57,3 +61,33 @@ func Sqrt(x float32) float32 { func Tan(x float32) float32 { return float32(math.Tan(float64(x))) // TODO(crawshaw): fast version } + +// Bytes returns the byte representation of float32 values in the given byte +// order. byteOrder must be either binary.BigEndian or binary.LittleEndian. +func Bytes(byteOrder binary.ByteOrder, values ...float32) []byte { + le := false + switch byteOrder { + case binary.BigEndian: + case binary.LittleEndian: + le = true + default: + panic(fmt.Sprintf("invalid byte order %v", byteOrder)) + } + + b := make([]byte, 4*len(values)) + for i, v := range values { + u := math.Float32bits(v) + if le { + b[4*i+0] = byte(u >> 0) + b[4*i+1] = byte(u >> 8) + b[4*i+2] = byte(u >> 16) + b[4*i+3] = byte(u >> 24) + } else { + b[4*i+0] = byte(u >> 24) + b[4*i+1] = byte(u >> 16) + b[4*i+2] = byte(u >> 8) + b[4*i+3] = byte(u >> 0) + } + } + return b +} diff --git a/f32/f32_test.go b/f32/f32_test.go index 457891f..d662fe6 100644 --- a/f32/f32_test.go +++ b/f32/f32_test.go @@ -5,6 +5,8 @@ package f32 import ( + "bytes" + "encoding/binary" "math" "testing" ) @@ -328,3 +330,32 @@ func BenchmarkSin(b *testing.B) { } } } + +func TestBytes(t *testing.T) { + testCases := []struct { + byteOrder binary.ByteOrder + want []byte + }{{ + binary.BigEndian, + []byte{ + // The IEEE 754 binary32 format is 1 sign bit, 8 exponent bits and 23 fraction bits. + 0x00, 0x00, 0x00, 0x00, // float32(+0.00) is 0 0000000_0 0000000_00000000_00000000 + 0x3f, 0xa0, 0x00, 0x00, // float32(+1.25) is 0 0111111_1 0100000_00000000_00000000 + 0xc0, 0x00, 0x00, 0x00, // float32(-2.00) is 1 1000000_0 0000000_00000000_00000000 + }, + }, { + binary.LittleEndian, + []byte{ + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xa0, 0x3f, + 0x00, 0x00, 0x00, 0xc0, + }, + }} + + for _, tc := range testCases { + got := Bytes(tc.byteOrder, +0.00, +1.25, -2.00) + if !bytes.Equal(got, tc.want) { + t.Errorf("%v:\ngot % x\nwant % x", tc.byteOrder, got, tc.want) + } + } +} diff --git a/gl/glutil/glimage.go b/gl/glutil/glimage.go index 66c9437..e0b21c8 100644 --- a/gl/glutil/glimage.go +++ b/gl/glutil/glimage.go @@ -5,10 +5,8 @@ package glutil import ( - "bytes" "encoding/binary" "image" - "log" "math" "sync" @@ -238,24 +236,16 @@ func (img *Image) Draw(dstBounds geom.Rectangle, srcBounds image.Rectangle) { gl.DisableVertexAttribArray(glimage.inUV) } -var quadXYCoords = toBytes([]float32{ +var quadXYCoords = f32.Bytes(binary.LittleEndian, -1, -1, // bottom left +1, -1, // bottom right -1, +1, // top left +1, +1, // top right -}) +) -var quadUVCoords = toBytes([]float32{ +var quadUVCoords = f32.Bytes(binary.LittleEndian, 0, 1, // bottom left 1, 1, // bottom right 0, 0, // top left 1, 0, // top right -}) - -func toBytes(v []float32) []byte { - buf := new(bytes.Buffer) - if err := binary.Write(buf, binary.LittleEndian, v); err != nil { - log.Fatal(err) - } - return buf.Bytes() -} +)