tofu

Making something with OpenGL in Go
Log | Files | Refs

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 }