main.go (2555B)
1 package main 2 3 import ( 4 "log" 5 "path/filepath" 6 "runtime" 7 "sync" 8 9 "git.mtkn.jp/tofu" 10 ) 11 12 type App struct { 13 m *sync.Mutex 14 program *tofu.Program 15 cursor tofu.Cursor 16 cursorChan chan tofu.Cursor 17 scrollChan chan tofu.Scroll 18 magnitude float32 19 center tofu.Vec2 20 } 21 22 func (app *App) Update() error { 23 app.m.Lock() 24 defer app.m.Unlock() 25 const delta = 0.01 26 if tofu.IsKeyPressed(tofu.KeyQ) { 27 return tofu.Termination 28 } 29 if tofu.IsKeyPressed(tofu.KeyRight) { 30 app.center[0] += delta * app.magnitude 31 } 32 if tofu.IsKeyPressed(tofu.KeyLeft) { 33 app.center[0] -= delta * app.magnitude 34 } 35 if tofu.IsKeyPressed(tofu.KeyUp) { 36 app.center[1] += delta * app.magnitude 37 } 38 if tofu.IsKeyPressed(tofu.KeyDown) { 39 app.center[1] -= delta * app.magnitude 40 } 41 app.program.Use() 42 app.program.SetFloat32("magnitude", app.magnitude) 43 app.program.SetVec2("center", app.center) 44 object.Draw() 45 return nil 46 } 47 48 func (app *App) CursorChan() chan<- tofu.Cursor { 49 return app.cursorChan 50 } 51 52 func (app *App) ScrollChan() chan<- tofu.Scroll { 53 return app.scrollChan 54 } 55 56 func main() { 57 var err error 58 app := &App{ 59 m: new(sync.Mutex), 60 cursorChan: make(chan tofu.Cursor), 61 scrollChan: make(chan tofu.Scroll), 62 magnitude: 1, 63 } 64 go func() { 65 for c := range app.cursorChan { 66 app.m.Lock() 67 app.cursor = c 68 app.m.Unlock() 69 } 70 }() 71 go func() { 72 const speed = 0.9 73 for s := range app.scrollChan { 74 app.m.Lock() 75 if s.Dy > 0 { 76 app.magnitude *= speed 77 } else { 78 app.magnitude /= speed 79 } 80 app.m.Unlock() 81 } 82 }() 83 84 tofu.SetWindowSize(800, 600) 85 tofu.SetWindowTitle("mandelbrot") 86 if err = tofu.Init(); err != nil { 87 log.Fatal(err) 88 } 89 object.Load() 90 _, f, _, ok := runtime.Caller(0) 91 if !ok { 92 log.Fatalf("unable to get source file information") 93 } 94 vpath := filepath.Join(filepath.Dir(f), "vertex.glsl") 95 fpath := filepath.Join(filepath.Dir(f), "fragment.glsl") 96 app.program, err = tofu.NewProgram(vpath, fpath) 97 if err != nil { 98 log.Fatalf("create shader program: %v", err) 99 } 100 if err := tofu.Run(app); err != nil { 101 log.Fatal(err) 102 } 103 } 104 105 var object = tofu.Object{ 106 Vertices: []tofu.Vec3{ 107 tofu.Vec3{1, 1, 0}, 108 tofu.Vec3{1, -1, 0}, 109 tofu.Vec3{-1, -1, 0}, 110 tofu.Vec3{-1, 1, 0}, 111 }, 112 Faces: []tofu.Face{ 113 {[3]tofu.VertexIndex{{V: 0, N: tofu.NoIndex, T: tofu.NoIndex}, 114 {V: 1, N: tofu.NoIndex, T: tofu.NoIndex}, 115 {V: 2, N: tofu.NoIndex, T: tofu.NoIndex}}}, 116 {[3]tofu.VertexIndex{{V: 0, N: tofu.NoIndex, T: tofu.NoIndex}, 117 {V: 2, N: tofu.NoIndex, T: tofu.NoIndex}, 118 {V: 3, N: tofu.NoIndex, T: tofu.NoIndex}}}, 119 }, 120 }