tofu

Making something with OpenGL in Go
Log | Files | Refs

commit de0d6cb74f630c090bd547e1dd7506bfbdef1e53
parent 9f41cd151bdb38a4c2f457014764e744ccb36f2d
Author: Matsuda Kenji <info@mtkn.jp>
Date:   Mon, 11 Nov 2024 09:13:51 +0900

use cursor chan

Diffstat:
Mcmd/sample/main.go | 117++++++++++++++++++++++++++++++++++++++++---------------------------------------
Mtofu.go | 31+++++++++++++++++++++++++------
2 files changed, 84 insertions(+), 64 deletions(-)

diff --git a/cmd/sample/main.go b/cmd/sample/main.go @@ -23,14 +23,7 @@ func init() { runtime.LockOSThread() } -func framebufferSizeCallback(w *glfw.Window, width int, height int) { - if width > math.MaxInt32 || height > math.MaxInt32 { - log.Fatal("framebufferSizeCallback: integer overflow") - } - gl.Viewport(0, 0, int32(width), int32(height)) -} - -func keyboardCallback(w *glfw.Window, key glfw.Key, scancode int, action glfw.Action, mods glfw.ModifierKey) { +func keyboardCallback(w *glfw.Window) { const speed = 0.1 if w.GetKey(glfw.KeyQ) == glfw.Press { w.SetShouldClose(true) @@ -68,23 +61,25 @@ func keyboardCallback(w *glfw.Window, key glfw.Key, scancode int, action glfw.Ac } var ( - cursorX, cursorY float32 + cursorX, cursorY float32 mouseCallbackFirstTime = true ) -func mouseCallback(w *glfw.Window, x, y float64) { +func watchCursor(app App) { const sensitivity = 0.005 - if mouseCallbackFirstTime { - cursorX, cursorY = float32(x), float32(y) - mouseCallbackFirstTime = false - return + for cur := range app.cursorChan { + if app.cursorFirstTime { + app.cur = cur + app.cursorFirstTime = false + continue + } + dx, dy := float32(app.cur.X-cur.X), float32(app.cur.Y-cur.Y) + dx *= sensitivity + dy *= sensitivity + app.cur = cur + camera.Yaw(dx) + camera.Pitch(-dy) } - dx, dy := cursorX - float32(x), float32(y) - cursorY - cursorX, cursorY = float32(x), float32(y) - dx *= sensitivity - dy *= sensitivity - camera.Yaw(dx) - camera.Pitch(dy) } var object = tofu.Object{ @@ -144,51 +139,59 @@ var object = tofu.Object{ var alpha float32 = 0.2 -type App struct{ - program *tofu.Program - lightProgram *tofu.Program - lightCol tofu.Vec3 - objCol tofu.Vec3 +type App struct { + program *tofu.Program + lightProgram *tofu.Program + lightCol tofu.Vec3 + objCol tofu.Vec3 + cursorChan chan tofu.Cursor + cur tofu.Cursor + cursorFirstTime bool + camera *tofu.Camera } func (app App) Update() error { - lightModel := tofu.Rotate(float32(glfw.GetTime()), tofu.Vec3{0, 1.41421356/2, 1.41421356/2}). - Mul(tofu.Translate(tofu.Vec3{3, 0, 0})). - Mul(tofu.Scale(0.1)) - lightPos := tofu.Rotate(float32(glfw.GetTime()), tofu.Vec3{0, 1.41421356/2, 1.41421356/2}). - MulVec(tofu.Vec4{3, 0, 0, 0}).Vec3() - - view := camera.View() - projection := tofu.Perspective(80*math.Pi/180, 800/600, 0.1, 100) - app.program.Use() - app.program.SetVec3("lightPos", lightPos) - app.program.SetMat4("view", view) - app.program.SetMat4("projection", projection) - app.program.SetVec3("lightCol", app.lightCol) - app.program.SetVec3("camPos", camera.Pos) - model := tofu.Translate(tofu.Vec3{0, 0, 0}) -// Mul(tofu.Rotate(float32(glfw.GetTime()), tofu.Vec3{0, 0, 1})). -// Mul(tofu.Rotate(float32(glfw.GetTime()), tofu.Vec3{0, 1, 0})) - app.program.SetMat4("model", model) - app.program.SetVec3("objCol", app.objCol) - - gl.DrawElements(gl.TRIANGLES, 36, gl.UNSIGNED_INT, nil) - app.lightProgram.Use() - app.lightProgram.SetMat4("view", view) - app.lightProgram.SetMat4("projection", projection) - app.lightProgram.SetMat4("model", lightModel) - app.lightProgram.SetVec3("lightCol", app.lightCol) - gl.DrawElements(gl.TRIANGLES, 36, gl.UNSIGNED_INT, nil) - - glfw.PollEvents() - return nil + lightModel := tofu.Rotate(float32(glfw.GetTime()), tofu.Vec3{0, 1.41421356 / 2, 1.41421356 / 2}). + Mul(tofu.Translate(tofu.Vec3{3, 0, 0})). + Mul(tofu.Scale(0.1)) + lightPos := tofu.Rotate(float32(glfw.GetTime()), tofu.Vec3{0, 1.41421356 / 2, 1.41421356 / 2}). + MulVec(tofu.Vec4{3, 0, 0, 0}).Vec3() + + view := camera.View() + projection := tofu.Perspective(80*math.Pi/180, 800/600, 0.1, 100) + app.program.Use() + app.program.SetVec3("lightPos", lightPos) + app.program.SetMat4("view", view) + app.program.SetMat4("projection", projection) + app.program.SetVec3("lightCol", app.lightCol) + app.program.SetVec3("camPos", camera.Pos) + model := tofu.Translate(tofu.Vec3{0, 0, 0}). + Mul(tofu.Rotate(float32(glfw.GetTime()), tofu.Vec3{math.Sqrt2 / 2, -math.Sqrt2 / 2, 0})) + app.program.SetMat4("model", model) + app.program.SetVec3("objCol", app.objCol) + + gl.DrawElements(gl.TRIANGLES, 36, gl.UNSIGNED_INT, nil) + app.lightProgram.Use() + app.lightProgram.SetMat4("view", view) + app.lightProgram.SetMat4("projection", projection) + app.lightProgram.SetMat4("model", lightModel) + app.lightProgram.SetVec3("lightCol", app.lightCol) + gl.DrawElements(gl.TRIANGLES, 36, gl.UNSIGNED_INT, nil) + + return nil +} + +func (app App) CursorChan() chan<- tofu.Cursor { + return app.cursorChan } func main() { var err error - app := App{} + app := App{cursorFirstTime: true} app.lightCol = tofu.Vec3{1, 1, 1} app.objCol = tofu.Vec3{1.0, 0.5, 0.32} + app.cursorChan = make(chan tofu.Cursor) + go watchCursor(app) tofu.SetWindowSize(winW, winH) tofu.Init() @@ -215,8 +218,6 @@ func main() { camera.MoveTo(tofu.Vec3{0, 0, 3}) camera.LookAt(tofu.Vec3{0, 0, 0}) - tofu.SetFramebufferSizeCallback(framebufferSizeCallback) - tofu.SetCursorPosCallback(mouseCallback) tofu.SetKeyCallback(keyboardCallback) if err := tofu.Run(app); err != nil { diff --git a/tofu.go b/tofu.go @@ -11,10 +11,16 @@ import ( type App interface { Update() error + CursorChan() chan<- Cursor +} + +type Cursor struct { + X, Y int } var window *glfw.Window var winW, winH int = 800, 600 +var keyCallback func(*glfw.Window) func Init() error { err := glfw.Init() @@ -37,6 +43,7 @@ func Init() error { gl.Viewport(0, 0, int32(winW), int32(winH)) gl.Enable(gl.DEBUG_OUTPUT) gl.DebugMessageCallback(messageCallback, nil) + window.SetFramebufferSizeCallback(framebufferSizeCallback) gl.Enable(gl.DEPTH_TEST) @@ -45,30 +52,42 @@ func Init() error { } func Run(app App) error { + if c := app.CursorChan(); c != nil { + watchCursor(c) + defer close(c) + } for !window.ShouldClose() { + keyCallback(window) gl.ClearColor(0.1, 0.2, 0.2, 1.0) gl.Clear(gl.COLOR_BUFFER_BIT|gl.DEPTH_BUFFER_BIT) app.Update() window.SwapBuffers() + glfw.PollEvents() } glfw.Terminate() return nil } +func watchCursor(c chan<- Cursor) { + callback := func(w *glfw.Window, x, y float64) { + c <- Cursor{X: int(x), Y: int(y)} + } + window.SetCursorPosCallback(callback) +} + func messageCallback(source, gltype, id, severity uint32, length int32, message string, userProgram unsafe.Pointer) { log.Printf("debug: type = 0x%x, severity = 0x%x, message = %s", gltype, severity, message) } -func SetFramebufferSizeCallback(f glfw.FramebufferSizeCallback) { - window.SetFramebufferSizeCallback(f) +func framebufferSizeCallback(w *glfw.Window, width int, height int) { + gl.Viewport(0, 0, int32(width), int32(height)) } -func SetCursorPosCallback(f glfw.CursorPosCallback) { - window.SetCursorPosCallback(f) +func SetFramebufferSizeCallback(f glfw.FramebufferSizeCallback) { } -func SetKeyCallback(f glfw.KeyCallback) { - window.SetKeyCallback(f) +func SetKeyCallback(f func(*glfw.Window)) { + keyCallback = f } func SetWindowSize(w, h int) {