commit e98182433ed2b1ed8837709822e058bd44df9867
parent 9cbd64c0f6b6b78cade5f36c16eb80af3313dae6
Author: Matsuda Kenji <info@mtkn.jp>
Date:   Sun, 10 Nov 2024 15:16:04 +0900
make App
Diffstat:
| M | cmd/sample/main.go |  |  | 121 | ++++++++++++++++++++++++++++++++++--------------------------------------------- | 
| A | tofu.go |  |  | 77 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | 
2 files changed, 129 insertions(+), 69 deletions(-)
diff --git a/cmd/sample/main.go b/cmd/sample/main.go
@@ -6,7 +6,6 @@ import (
 	"math"
 	"path/filepath"
 	"runtime"
-	"unsafe"
 
 	"github.com/go-gl/gl/v3.3-core/gl"
 	"github.com/go-gl/glfw/v3.3/glfw"
@@ -31,7 +30,7 @@ func framebufferSizeCallback(w *glfw.Window, width int, height int) {
 	gl.Viewport(0, 0, int32(width), int32(height))
 }
 
-func keyboardCallback(w *glfw.Window) {
+func keyboardCallback(w *glfw.Window, key glfw.Key, scancode int, action glfw.Action, mods glfw.ModifierKey) {
 	const speed = 0.1
 	if w.GetKey(glfw.KeyQ) == glfw.Press {
 		w.SetShouldClose(true)
@@ -88,10 +87,6 @@ func mouseCallback(w *glfw.Window, x, y float64) {
 	camera.Pitch(dy)
 }
 
-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)
-}
-
 var object = tofu.Object{
 	Vertices: []tofu.Vec3{
 		tofu.Vec3{0.5, 0.5, -0.5},
@@ -149,28 +144,52 @@ var object = tofu.Object{
 
 var alpha float32 = 0.2
 
-func main() {
-	err := glfw.Init()
-	if err != nil {
-		log.Fatalf("init glfw: %v", err)
-	}
-	defer glfw.Terminate()
-	glfw.WindowHint(glfw.ContextVersionMajor, 3)
-	glfw.WindowHint(glfw.ContextVersionMinor, 3)
-	glfw.WindowHint(glfw.OpenGLProfile, glfw.OpenGLCoreProfile)
+type App struct{
+	program *tofu.Program
+	lightProgram *tofu.Program
+	lightCol tofu.Vec3
+	objCol tofu.Vec3
+}
 
-	window, err := glfw.CreateWindow(winW, winH, "Testing", nil, nil)
-	if err != nil {
-		log.Fatalf("create window: %v", err)
-	}
-	window.MakeContextCurrent()
-	if err = gl.Init(); err != nil {
-		log.Fatalf("init gl: %v", err)
-	}
-	gl.Viewport(0, 0, winW, winH)
+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}))
+		lightPos := tofu.Rotate(float32(glfw.GetTime()), tofu.Vec3{0, 1.41421356/2, 1.41421356/2}).
+			MulVec(tofu.Vec4{3, 0, 0, 0}).Vec3()
 
-	gl.Enable(gl.DEBUG_OUTPUT)
-	gl.DebugMessageCallback(messageCallback, nil)
+		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
+}
+
+func main() {
+	var err error
+	app := App{}
+	app.lightCol = tofu.Vec3{1, 1, 1}
+	app.objCol = tofu.Vec3{1.0, 0.5, 0.32}
+	tofu.SetWindowSize(winW, winH)
+	tofu.Init()
 
 	_, f, _, ok := runtime.Caller(0)
 	if !ok {
@@ -182,60 +201,24 @@ func main() {
 
 	object.Load()
 
-	program, err := tofu.NewProgram(vpath, fpath)
+	app.program, err = tofu.NewProgram(vpath, fpath)
 	if err != nil {
 		log.Fatalf("create shader program: %v", err)
 	}
-	lightProgram, err := tofu.NewProgram(vpath, lightFpath)
+	app.lightProgram, err = tofu.NewProgram(vpath, lightFpath)
 	if err != nil {
 		log.Fatalf("create light shader program: %v", err)
 	}
-	objCol := tofu.Vec3{1.0, 0.5, 0.32}
-	lightCol := tofu.Vec3{1.0, 1.0, 1.0}
-
-	gl.Enable(gl.DEPTH_TEST)
 
 	camera = tofu.NewCamera()
 	camera.MoveTo(tofu.Vec3{0, 0, 3})
 	camera.LookAt(tofu.Vec3{0, 0, 0})
 
-	window.SetFramebufferSizeCallback(framebufferSizeCallback)
-	window.SetCursorPosCallback(mouseCallback)
-	window.SetInputMode(glfw.CursorMode, glfw.CursorDisabled)
-
-	for !window.ShouldClose() {
-		keyboardCallback(window)
-		gl.ClearColor(0.1, 0.2, 0.2, 1.0)
-		gl.Clear(gl.COLOR_BUFFER_BIT|gl.DEPTH_BUFFER_BIT)
-
-		lightModel := tofu.Rotate(float32(glfw.GetTime()), tofu.Vec3{0, 1.41421356/2, 1.41421356/2}).
-			Mul(tofu.Translate(tofu.Vec3{3, 0, 0}))
-		lightPos := tofu.Rotate(float32(glfw.GetTime()), tofu.Vec3{0, 1.41421356/2, 1.41421356/2}).
-			MulVec(tofu.Vec4{3, 0, 0, 0}).Vec3()
+	tofu.SetFramebufferSizeCallback(framebufferSizeCallback)
+	tofu.SetCursorPosCallback(mouseCallback)
+	tofu.SetKeyCallback(keyboardCallback)
 
-		view := camera.View()
-		projection := tofu.Perspective(80*math.Pi/180, 800/600, 0.1, 100)
-		program.Use()
-		program.SetVec3("lightPos", lightPos)
-		program.SetMat4("view", view)
-		program.SetMat4("projection", projection)
-		program.SetVec3("lightCol", lightCol)
-		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}))
-		program.SetMat4("model", model)
-		program.SetVec3("objCol", objCol)
-
-		gl.DrawElements(gl.TRIANGLES, 36, gl.UNSIGNED_INT, nil)
-		lightProgram.Use()
-		lightProgram.SetMat4("view", view)
-		lightProgram.SetMat4("projection", projection)
-		lightProgram.SetMat4("model", lightModel)
-		lightProgram.SetVec3("lightCol", lightCol)
-		gl.DrawElements(gl.TRIANGLES, 36, gl.UNSIGNED_INT, nil)
-
-		window.SwapBuffers()
-		glfw.PollEvents()
+	if err := tofu.Run(app); err != nil {
+		log.Fatal(err)
 	}
 }
diff --git a/tofu.go b/tofu.go
@@ -0,0 +1,76 @@
+package tofu
+
+import (
+	"fmt"
+	"log"
+	"unsafe"
+
+	"github.com/go-gl/gl/v3.3-core/gl"
+	"github.com/go-gl/glfw/v3.3/glfw"
+)
+
+type App interface {
+	Update() error
+}
+
+var window *glfw.Window
+var winW, winH int = 800, 600
+
+func Init() error {
+	err := glfw.Init()
+	if err != nil {
+		return fmt.Errorf("init glfw: %v", err)
+	}
+
+	glfw.WindowHint(glfw.ContextVersionMajor, 3)
+	glfw.WindowHint(glfw.ContextVersionMinor, 3)
+	glfw.WindowHint(glfw.OpenGLProfile, glfw.OpenGLCoreProfile)
+
+	window, err = glfw.CreateWindow(winW, winH, "Testing", nil, nil)
+	if err != nil {
+		return fmt.Errorf("create window: %v", err)
+	}
+	window.MakeContextCurrent()
+	if err = gl.Init(); err != nil {
+		return fmt.Errorf("init gl: %v", err)
+	}
+	gl.Viewport(0, 0, int32(winW), int32(winH))
+	gl.Enable(gl.DEBUG_OUTPUT)
+	gl.DebugMessageCallback(messageCallback, nil)
+
+	gl.Enable(gl.DEPTH_TEST)
+
+	window.SetInputMode(glfw.CursorMode, glfw.CursorDisabled)
+	return nil
+}
+
+func Run(app App) error {
+	for !window.ShouldClose() {
+		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.Terminate()
+	return nil
+}
+
+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 SetCursorPosCallback(f glfw.CursorPosCallback) {
+	window.SetCursorPosCallback(f)
+}
+
+func SetKeyCallback(f glfw.KeyCallback) {
+	window.SetKeyCallback(f)
+}
+
+func SetWindowSize(w, h int) {
+	winW, winH = w, h
+}
+\ No newline at end of file