github.com/SkycoinProject/gomobile@v0.0.0-20190312151609-d3739f865fa6/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  // +build darwin linux windows
     6  
     7  // An app that draws a green triangle on a red background.
     8  //
     9  // Note: This demo is an early preview of Go 1.5. In order to build this
    10  // 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  //   $ go install golang.org/x/mobile/example/basic && basic
    29  package main
    30  
    31  import (
    32  	"encoding/binary"
    33  	"log"
    34  
    35  	"golang.org/x/mobile/app"
    36  	"golang.org/x/mobile/event/lifecycle"
    37  	"golang.org/x/mobile/event/paint"
    38  	"golang.org/x/mobile/event/size"
    39  	"golang.org/x/mobile/event/touch"
    40  	"golang.org/x/mobile/exp/app/debug"
    41  	"golang.org/x/mobile/exp/f32"
    42  	"golang.org/x/mobile/exp/gl/glutil"
    43  	"golang.org/x/mobile/gl"
    44  )
    45  
    46  var (
    47  	images   *glutil.Images
    48  	fps      *debug.FPS
    49  	program  gl.Program
    50  	position gl.Attrib
    51  	offset   gl.Uniform
    52  	color    gl.Uniform
    53  	buf      gl.Buffer
    54  
    55  	green  float32
    56  	touchX float32
    57  	touchY float32
    58  )
    59  
    60  func main() {
    61  	app.Main(func(a app.App) {
    62  		var glctx gl.Context
    63  		var sz size.Event
    64  		for e := range a.Events() {
    65  			switch e := a.Filter(e).(type) {
    66  			case lifecycle.Event:
    67  				switch e.Crosses(lifecycle.StageVisible) {
    68  				case lifecycle.CrossOn:
    69  					glctx, _ = e.DrawContext.(gl.Context)
    70  					onStart(glctx)
    71  					a.Send(paint.Event{})
    72  				case lifecycle.CrossOff:
    73  					onStop(glctx)
    74  					glctx = nil
    75  				}
    76  			case size.Event:
    77  				sz = e
    78  				touchX = float32(sz.WidthPx / 2)
    79  				touchY = float32(sz.HeightPx / 2)
    80  			case paint.Event:
    81  				if glctx == nil || e.External {
    82  					// As we are actively painting as fast as
    83  					// we can (usually 60 FPS), skip any paint
    84  					// events sent by the system.
    85  					continue
    86  				}
    87  
    88  				onPaint(glctx, sz)
    89  				a.Publish()
    90  				// Drive the animation by preparing to paint the next frame
    91  				// after this one is shown.
    92  				a.Send(paint.Event{})
    93  			case touch.Event:
    94  				touchX = e.X
    95  				touchY = e.Y
    96  			}
    97  		}
    98  	})
    99  }
   100  
   101  func onStart(glctx gl.Context) {
   102  	var err error
   103  	program, err = glutil.CreateProgram(glctx, vertexShader, fragmentShader)
   104  	if err != nil {
   105  		log.Printf("error creating GL program: %v", err)
   106  		return
   107  	}
   108  
   109  	buf = glctx.CreateBuffer()
   110  	glctx.BindBuffer(gl.ARRAY_BUFFER, buf)
   111  	glctx.BufferData(gl.ARRAY_BUFFER, triangleData, gl.STATIC_DRAW)
   112  
   113  	position = glctx.GetAttribLocation(program, "position")
   114  	color = glctx.GetUniformLocation(program, "color")
   115  	offset = glctx.GetUniformLocation(program, "offset")
   116  
   117  	images = glutil.NewImages(glctx)
   118  	fps = debug.NewFPS(images)
   119  }
   120  
   121  func onStop(glctx gl.Context) {
   122  	glctx.DeleteProgram(program)
   123  	glctx.DeleteBuffer(buf)
   124  	fps.Release()
   125  	images.Release()
   126  }
   127  
   128  func onPaint(glctx gl.Context, sz size.Event) {
   129  	glctx.ClearColor(1, 0, 0, 1)
   130  	glctx.Clear(gl.COLOR_BUFFER_BIT)
   131  
   132  	glctx.UseProgram(program)
   133  
   134  	green += 0.01
   135  	if green > 1 {
   136  		green = 0
   137  	}
   138  	glctx.Uniform4f(color, 0, green, 0, 1)
   139  
   140  	glctx.Uniform2f(offset, touchX/float32(sz.WidthPx), touchY/float32(sz.HeightPx))
   141  
   142  	glctx.BindBuffer(gl.ARRAY_BUFFER, buf)
   143  	glctx.EnableVertexAttribArray(position)
   144  	glctx.VertexAttribPointer(position, coordsPerVertex, gl.FLOAT, false, 0, 0)
   145  	glctx.DrawArrays(gl.TRIANGLES, 0, vertexCount)
   146  	glctx.DisableVertexAttribArray(position)
   147  
   148  	fps.Draw(sz)
   149  }
   150  
   151  var triangleData = f32.Bytes(binary.LittleEndian,
   152  	0.0, 0.4, 0.0, // top left
   153  	0.0, 0.0, 0.0, // bottom left
   154  	0.4, 0.0, 0.0, // bottom right
   155  )
   156  
   157  const (
   158  	coordsPerVertex = 3
   159  	vertexCount     = 3
   160  )
   161  
   162  const vertexShader = `#version 100
   163  uniform vec2 offset;
   164  
   165  attribute vec4 position;
   166  void main() {
   167  	// offset comes in with x/y values between 0 and 1.
   168  	// position bounds are -1 to 1.
   169  	vec4 offset4 = vec4(2.0*offset.x-1.0, 1.0-2.0*offset.y, 0, 0);
   170  	gl_Position = position + offset4;
   171  }`
   172  
   173  const fragmentShader = `#version 100
   174  precision mediump float;
   175  uniform vec4 color;
   176  void main() {
   177  	gl_FragColor = color;
   178  }`