github.com/coming-chat/gomobile@v0.0.0-20220601074111-56995f7d7aba/example/basic/main.go (about) 1 // Copyright 2014 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 //go:build darwin || linux || windows 6 // +build darwin linux windows 7 8 // An app that draws a green triangle on a red background. 9 // 10 // In order to build this program as an Android APK, using the gomobile tool. 11 // 12 // See http://godoc.org/golang.org/x/mobile/cmd/gomobile to install gomobile. 13 // 14 // Get the basic example and use gomobile to build or install it on your device. 15 // 16 // $ go get -d golang.org/x/mobile/example/basic 17 // $ gomobile build golang.org/x/mobile/example/basic # will build an APK 18 // 19 // # plug your Android device to your computer or start an Android emulator. 20 // # if you have adb installed on your machine, use gomobile install to 21 // # build and deploy the APK to an Android target. 22 // $ gomobile install golang.org/x/mobile/example/basic 23 // 24 // Switch to your device or emulator to start the Basic application from 25 // the launcher. 26 // You can also run the application on your desktop by running the command 27 // below. (Note: It currently doesn't work on Windows.) 28 // 29 // $ go install golang.org/x/mobile/example/basic && basic 30 package main 31 32 import ( 33 "encoding/binary" 34 "log" 35 36 "golang.org/x/mobile/app" 37 "golang.org/x/mobile/event/lifecycle" 38 "golang.org/x/mobile/event/paint" 39 "golang.org/x/mobile/event/size" 40 "golang.org/x/mobile/event/touch" 41 "golang.org/x/mobile/exp/app/debug" 42 "golang.org/x/mobile/exp/f32" 43 "golang.org/x/mobile/exp/gl/glutil" 44 "golang.org/x/mobile/gl" 45 ) 46 47 var ( 48 images *glutil.Images 49 fps *debug.FPS 50 program gl.Program 51 position gl.Attrib 52 offset gl.Uniform 53 color gl.Uniform 54 buf gl.Buffer 55 56 green float32 57 touchX float32 58 touchY float32 59 ) 60 61 func main() { 62 app.Main(func(a app.App) { 63 var glctx gl.Context 64 var sz size.Event 65 for e := range a.Events() { 66 switch e := a.Filter(e).(type) { 67 case lifecycle.Event: 68 switch e.Crosses(lifecycle.StageVisible) { 69 case lifecycle.CrossOn: 70 glctx, _ = e.DrawContext.(gl.Context) 71 onStart(glctx) 72 a.Send(paint.Event{}) 73 case lifecycle.CrossOff: 74 onStop(glctx) 75 glctx = nil 76 } 77 case size.Event: 78 sz = e 79 touchX = float32(sz.WidthPx / 2) 80 touchY = float32(sz.HeightPx / 2) 81 case paint.Event: 82 if glctx == nil || e.External { 83 // As we are actively painting as fast as 84 // we can (usually 60 FPS), skip any paint 85 // events sent by the system. 86 continue 87 } 88 89 onPaint(glctx, sz) 90 a.Publish() 91 // Drive the animation by preparing to paint the next frame 92 // after this one is shown. 93 a.Send(paint.Event{}) 94 case touch.Event: 95 touchX = e.X 96 touchY = e.Y 97 } 98 } 99 }) 100 } 101 102 func onStart(glctx gl.Context) { 103 var err error 104 program, err = glutil.CreateProgram(glctx, vertexShader, fragmentShader) 105 if err != nil { 106 log.Printf("error creating GL program: %v", err) 107 return 108 } 109 110 buf = glctx.CreateBuffer() 111 glctx.BindBuffer(gl.ARRAY_BUFFER, buf) 112 glctx.BufferData(gl.ARRAY_BUFFER, triangleData, gl.STATIC_DRAW) 113 114 position = glctx.GetAttribLocation(program, "position") 115 color = glctx.GetUniformLocation(program, "color") 116 offset = glctx.GetUniformLocation(program, "offset") 117 118 images = glutil.NewImages(glctx) 119 fps = debug.NewFPS(images) 120 } 121 122 func onStop(glctx gl.Context) { 123 glctx.DeleteProgram(program) 124 glctx.DeleteBuffer(buf) 125 fps.Release() 126 images.Release() 127 } 128 129 func onPaint(glctx gl.Context, sz size.Event) { 130 glctx.ClearColor(1, 0, 0, 1) 131 glctx.Clear(gl.COLOR_BUFFER_BIT) 132 133 glctx.UseProgram(program) 134 135 green += 0.01 136 if green > 1 { 137 green = 0 138 } 139 glctx.Uniform4f(color, 0, green, 0, 1) 140 141 glctx.Uniform2f(offset, touchX/float32(sz.WidthPx), touchY/float32(sz.HeightPx)) 142 143 glctx.BindBuffer(gl.ARRAY_BUFFER, buf) 144 glctx.EnableVertexAttribArray(position) 145 glctx.VertexAttribPointer(position, coordsPerVertex, gl.FLOAT, false, 0, 0) 146 glctx.DrawArrays(gl.TRIANGLES, 0, vertexCount) 147 glctx.DisableVertexAttribArray(position) 148 149 fps.Draw(sz) 150 } 151 152 var triangleData = f32.Bytes(binary.LittleEndian, 153 0.0, 0.4, 0.0, // top left 154 0.0, 0.0, 0.0, // bottom left 155 0.4, 0.0, 0.0, // bottom right 156 ) 157 158 const ( 159 coordsPerVertex = 3 160 vertexCount = 3 161 ) 162 163 const vertexShader = `#version 100 164 uniform vec2 offset; 165 166 attribute vec4 position; 167 void main() { 168 // offset comes in with x/y values between 0 and 1. 169 // position bounds are -1 to 1. 170 vec4 offset4 = vec4(2.0*offset.x-1.0, 1.0-2.0*offset.y, 0, 0); 171 gl_Position = position + offset4; 172 }` 173 174 const fragmentShader = `#version 100 175 precision mediump float; 176 uniform vec4 color; 177 void main() { 178 gl_FragColor = color; 179 }`