commit 0cea544387e27db1adc96b54e3d63ad74f8b010c
parent a8b156fbd2bca8873e8b09d678ba134a0cffc4bb
Author: Matsuda Kenji <info@mtkn.jp>
Date:   Tue, 12 Nov 2024 17:45:15 +0900
gofmt
Diffstat:
8 files changed, 114 insertions(+), 86 deletions(-)
diff --git a/camera.go b/camera.go
@@ -6,9 +6,9 @@ type Camera struct {
 
 func NewCamera() *Camera {
 	return &Camera{
-		Pos: Vec3{0, 0, 0},
+		Pos:   Vec3{0, 0, 0},
 		Front: Vec3{0, 0, 1},
-		Up: Vec3{0, 1, 0},
+		Up:    Vec3{0, 1, 0},
 		Right: Vec3{1, 0, 0},
 	}
 }
@@ -47,4 +47,4 @@ func (cam *Camera) View() Mat4 {
 		cam.Right[2], cam.Up[2], -cam.Front[2], 0,
 		0, 0, 0, 1,
 	}.Mul(Translate(cam.Pos.Inverse()))
-}
-\ No newline at end of file
+}
diff --git a/cmd/sample/fragment.glsl b/cmd/sample/fragment.glsl
@@ -1,26 +1,41 @@
 #version 330 core
+
+struct Material {
+	vec3 ambient;
+	vec3 diffuse;
+	vec3 specular;
+	float shiness;
+};
+
+struct Light {
+	vec3 position;
+	vec3 ambient;
+	vec3 diffuse;
+	vec3 specular;
+};
+
 in vec3 fnormal;
 in vec3 fpos;
-uniform vec3 lightCol;
-uniform vec3 lightPos;
+
 uniform vec3 camPos;
 uniform vec3 objCol;
+uniform Material material;
+uniform Light light;
+
 out vec4 fcol;
-void main() {
-	float ambientStrength = 0.1;
-	float specularStrength = 0;
 
-	vec3 ambient = ambientStrength * lightCol;
+void main() {
+	vec3 ambient = material.ambient * light.ambient;
 
-	vec3 lightDir = normalize(lightPos - fpos);
+	vec3 lightDir = normalize(light.position - fpos);
 	float diff = max(dot(fnormal, lightDir), 0.0);
-	vec3 diffuse = diff * lightCol;
+	vec3 diffuse = diff * material.diffuse * light.diffuse;
 
 	vec3 viewDir = normalize(camPos - fpos);
 	vec3 reflectDir = reflect(-lightDir, fnormal);
-	float spec = pow(max(dot(viewDir, reflectDir), 0.0), 32);
-	vec3 specular = specularStrength * spec * lightCol;
+	float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shiness);
+	vec3 specular = material.specular * spec * light.specular;
 
-	fcol = vec4(objCol * (ambient + diffuse + specular), 1.0);
+	fcol = vec4(ambient + diffuse + specular, 1.0);
 }
 
diff --git a/cmd/sample/main.go b/cmd/sample/main.go
@@ -137,8 +137,6 @@ var alpha float32 = 0.2
 type App struct {
 	program      *tofu.Program
 	lightProgram *tofu.Program
-	lightCol     tofu.Vec3
-	objCol       tofu.Vec3
 	cursorChan   chan tofu.Cursor
 	cur          tofu.Cursor
 	keyChan      chan struct{}
@@ -153,31 +151,43 @@ func (app *App) Update() error {
 	if app.termination {
 		return tofu.Termination
 	}
-	lightModel := tofu.Rotate(now, tofu.Vec3{0, 1.41421356 / 2, 1.41421356 / 2}).
+	lightModel := tofu.Rotate(now, tofu.Vec3{0, math.Sqrt2 / 2, math.Sqrt2 / 2}).
 		Mul(tofu.Translate(tofu.Vec3{3, 0, 0})).
 		Mul(tofu.Scale(0.1))
-	lightPos := tofu.Rotate(now, tofu.Vec3{0, 1.41421356 / 2, 1.41421356 / 2}).
+	lightPos := tofu.Rotate(now, tofu.Vec3{0, math.Sqrt2 / 2, math.Sqrt2 / 2}).
 		MulVec(tofu.Vec4{3, 0, 0, 0}).Vec3()
 
 	view := camera.View()
 	projection := tofu.Perspective(80*math.Pi/180, 800/600, 0.1, 100)
+	lightCol := tofu.Vec3{
+		float32(math.Sin(float64(now*2.0))/2 + 1),
+		float32(math.Sin(float64(now*0.7))/2 + 1),
+		float32(math.Sin(float64(now*1.3))/2 + 1)}
+	matCol := tofu.Vec3{1, 1, 1}
 	app.program.Use()
-	app.program.SetVec3("lightPos", lightPos)
+	app.program.SetVec3("light.position", lightPos)
+	app.program.SetVec3("light.ambient", lightCol.MulF(0.2))
+	app.program.SetVec3("light.diffuse", lightCol.MulF(0.5))
+	app.program.SetVec3("light.specular", lightCol)
+
+	app.program.SetVec3("light.position", lightPos)
 	app.program.SetMat4("view", view)
 	app.program.SetMat4("projection", projection)
-	app.program.SetVec3("lightCol", app.lightCol)
 	app.program.SetVec3("camPos", camera.Pos)
+	app.program.SetVec3("material.ambient", matCol.MulF(0.4))
+	app.program.SetVec3("material.diffuse", matCol.MulF(1.0))
+	app.program.SetVec3("material.specular", matCol.MulF(1.0))
+	app.program.SetFloat32("material.shiness", 32)
 	model := tofu.Translate(tofu.Vec3{0, 0, 0}).
 		Mul(tofu.Rotate(now, tofu.Vec3{math.Sqrt2 / 2, -math.Sqrt2 / 2, 0}))
 	app.program.SetMat4("model", model)
-	app.program.SetVec3("objCol", app.objCol)
-
 	object.Draw()
+
 	app.lightProgram.Use()
 	app.lightProgram.SetMat4("view", view)
 	app.lightProgram.SetMat4("projection", projection)
 	app.lightProgram.SetMat4("model", lightModel)
-	app.lightProgram.SetVec3("lightCol", app.lightCol)
+	app.lightProgram.SetVec3("lightCol", lightCol)
 	object.Draw()
 
 	return nil
@@ -190,14 +200,15 @@ func (app *App) CursorChan() chan<- tofu.Cursor {
 func main() {
 	var err error
 	app := &App{}
-	app.lightCol = tofu.Vec3{1, 1, 1}
-	app.objCol = tofu.Vec3{1.0, 0.5, 0.32}
 	app.cursorChan = make(chan tofu.Cursor)
 	app.startedAt = time.Now()
 	go watchCursor(app)
 	tofu.SetWindowSize(winW, winH)
+	tofu.SetWindowTitle("Sample")
 	tofu.Init()
 
+	object.Load()
+
 	_, f, _, ok := runtime.Caller(0)
 	if !ok {
 		log.Fatalf("unable to get source file information")
@@ -206,8 +217,6 @@ func main() {
 	fpath := filepath.Join(filepath.Dir(f), "fragment.glsl")
 	lightFpath := filepath.Join(filepath.Dir(f), "light_fragment.glsl")
 
-	object.Load()
-
 	app.program, err = tofu.NewProgram(vpath, fpath)
 	if err != nil {
 		log.Fatalf("create shader program: %v", err)
diff --git a/error.go b/error.go
@@ -11,4 +11,4 @@ func Error() error {
 		return nil
 	}
 	return fmt.Errorf("err: 0x%04X", errno)
-}
-\ No newline at end of file
+}
diff --git a/math.go b/math.go
@@ -11,11 +11,11 @@ func (v Vec3) Normalize() Vec3 {
 }
 
 func (v Vec3) Add(w Vec3) Vec3 {
-	return Vec3{v[0]+w[0], v[1]+w[1], v[2]+w[2]}
+	return Vec3{v[0] + w[0], v[1] + w[1], v[2] + w[2]}
 }
 
 func (v Vec3) Sub(w Vec3) Vec3 {
-	return Vec3{v[0]-w[0], v[1]-w[1], v[2]-w[2]}
+	return Vec3{v[0] - w[0], v[1] - w[1], v[2] - w[2]}
 }
 
 func (v Vec3) Inverse() Vec3 {
@@ -30,8 +30,8 @@ func (v Vec3) Cross(w Vec3) Vec3 {
 	}
 }
 
-func (v Vec3) MulF(x float32) Vec3{
-	return Vec3{v[0]*x, v[1]*x, v[2]*x}
+func (v Vec3) MulF(x float32) Vec3 {
+	return Vec3{v[0] * x, v[1] * x, v[2] * x}
 }
 
 type Vec4 [4]float32
@@ -54,9 +54,9 @@ func Rotate3(rad float32, axis Vec3) Mat3 {
 
 func (m Mat3) MulV(v Vec3) Vec3 {
 	return Vec3{
-		m[0]*v[0]+m[3]*v[1]+m[6]*v[2],
-		m[1]*v[0]+m[4]*v[1]+m[7]*v[2],
-		m[2]*v[0]+m[5]*v[1]+m[8]*v[2]}
+		m[0]*v[0] + m[3]*v[1] + m[6]*v[2],
+		m[1]*v[0] + m[4]*v[1] + m[7]*v[2],
+		m[2]*v[0] + m[5]*v[1] + m[8]*v[2]}
 }
 
 // column major
@@ -77,10 +77,10 @@ func (m Mat4) Mul(n Mat4) Mat4 {
 
 func (m Mat4) MulVec(v Vec4) Vec4 {
 	return Vec4{
-		m[0]*v[0]+m[4]*v[1]+m[8]*v[2]+m[12]*v[3],
-		m[1]*v[0]+m[5]*v[1]+m[9]*v[2]+m[13]*v[3],
-		m[2]*v[0]+m[6]*v[1]+m[10]*v[2]+m[14]*v[3],
-		m[3]*v[0]+m[7]*v[1]+m[11]*v[2]+m[15]*v[3],
+		m[0]*v[0] + m[4]*v[1] + m[8]*v[2] + m[12]*v[3],
+		m[1]*v[0] + m[5]*v[1] + m[9]*v[2] + m[13]*v[3],
+		m[2]*v[0] + m[6]*v[1] + m[10]*v[2] + m[14]*v[3],
+		m[3]*v[0] + m[7]*v[1] + m[11]*v[2] + m[15]*v[3],
 	}
 }
 
@@ -117,7 +117,7 @@ func Rotate(rad float32, axis Vec3) Mat4 {
 }
 
 func Perspective(fov, asp, min, max float32) Mat4 {
-	tan := float32(math.Tan(float64(fov/2)))
+	tan := float32(math.Tan(float64(fov / 2)))
 	w := min * tan
 	h := w / asp
 
diff --git a/shader.go b/shader.go
@@ -8,7 +8,7 @@ import (
 	"github.com/go-gl/gl/v3.3-core/gl"
 )
 
-// CompileShader compiles shaders of type xtype using the source file specified by path.
+// CompileShader compiles a shader of type xtype using the source file specified by path.
 // It returns the resulting shader ID.
 func compileShader(path string, xtype uint32) (shaderID uint32, err error) {
 	src, err := os.ReadFile(path)
@@ -90,7 +90,7 @@ func (p *Program) Use() {
 // SetFloat32 set the value of the uniform name.
 // TODO: Should I check error conditions?
 func (p *Program) SetFloat32(name string, val float32) error {
-	l := gl.GetUniformLocation(p.id, gl.Str(name + "\x00"))
+	l := gl.GetUniformLocation(p.id, gl.Str(name+"\x00"))
 	if l == -1 {
 		return fmt.Errorf("uniform %s not found", name)
 	}
@@ -99,7 +99,7 @@ func (p *Program) SetFloat32(name string, val float32) error {
 }
 
 func (p *Program) SetVec3(name string, val Vec3) error {
-	l := gl.GetUniformLocation(p.id, gl.Str(name + "\x00"))
+	l := gl.GetUniformLocation(p.id, gl.Str(name+"\x00"))
 	if l == -1 {
 		return fmt.Errorf("uniform %s not found", name)
 	}
@@ -108,7 +108,7 @@ func (p *Program) SetVec3(name string, val Vec3) error {
 }
 
 func (p *Program) SetMat4(name string, val Mat4) error {
-	l := gl.GetUniformLocation(p.id, gl.Str(name + "\x00"))
+	l := gl.GetUniformLocation(p.id, gl.Str(name+"\x00"))
 	if l == -1 {
 		return fmt.Errorf("uniform %s not found", name)
 	}
@@ -120,10 +120,10 @@ func (p *Program) SetTexture(t *Texture, name string) error {
 	p.Use()
 	gl.ActiveTexture(t.unit)
 	gl.BindTexture(gl.TEXTURE_2D, t.id)
-	l := gl.GetUniformLocation(p.id, gl.Str(name + "\x00"))
+	l := gl.GetUniformLocation(p.id, gl.Str(name+"\x00"))
 	if l == -1 {
 		return fmt.Errorf("no such uniform: %s", name)
 	}
-	gl.Uniform1i(l, int32(t.unit - gl.TEXTURE0))
+	gl.Uniform1i(l, int32(t.unit-gl.TEXTURE0))
 	return nil
 }
diff --git a/texture.go b/texture.go
@@ -25,7 +25,7 @@ func loadImage(name string) (image.Image, error) {
 }
 
 type Texture struct {
-	id uint32
+	id   uint32
 	unit uint32
 }
 
@@ -73,7 +73,7 @@ func flipV(img image.Image) image.Image {
 	xmax, ymax := dst.Bounds().Max.X, dst.Bounds().Max.Y
 	for y := ymin; y < ymax; y++ {
 		for x := xmin; x < xmax; x++ {
-			dst.Set(x, ymax + ymin - y, img.At(x, y))
+			dst.Set(x, ymax+ymin-y, img.At(x, y))
 		}
 	}
 	return dst
@@ -85,7 +85,7 @@ func flipH(img image.Image) image.Image {
 	xmax, ymax := dst.Bounds().Max.X, dst.Bounds().Max.Y
 	for y := ymin; y < ymax; y++ {
 		for x := xmin; x < xmax; x++ {
-			dst.Set(xmax + xmin - x, y, img.At(x, y))
+			dst.Set(xmax+xmin-x, y, img.At(x, y))
 		}
 	}
 	return dst
diff --git a/tofu.go b/tofu.go
@@ -19,21 +19,23 @@ type Cursor struct {
 	X, Y int
 }
 
-var window *glfw.Window
-var winW, winH int = 800, 600
-var keyCallback func(*glfw.Window)
+var (
+	window      *glfw.Window
+	winW, winH  int    = 800, 600
+	winTitle    string = "Tofu"
+	keyCallback func(*glfw.Window)
+)
 
 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)
+	window, err = glfw.CreateWindow(winW, winH, winTitle, nil, nil)
 	if err != nil {
 		return fmt.Errorf("create window: %v", err)
 	}
@@ -97,39 +99,43 @@ func SetWindowSize(w, h int) {
 	winW, winH = w, h
 }
 
+func SetWindowTitle(t string) {
+	winTitle = t
+}
+
 type Key int
 
 const (
-	KeyA     Key = Key(glfw.KeyA)
-	KeyB         = Key(glfw.KeyB)
-	KeyC         = Key(glfw.KeyC)
-	KeyD         = Key(glfw.KeyD)
-	KeyE         = Key(glfw.KeyE)
-	KeyF         = Key(glfw.KeyF)
-	KeyG         = Key(glfw.KeyG)
-	KeyH         = Key(glfw.KeyH)
-	KeyI         = Key(glfw.KeyI)
-	KeyJ         = Key(glfw.KeyJ)
-	KeyK         = Key(glfw.KeyK)
-	KeyL         = Key(glfw.KeyL)
-	KeyM         = Key(glfw.KeyM)
-	KeyN         = Key(glfw.KeyN)
-	KeyO         = Key(glfw.KeyO)
-	KeyP         = Key(glfw.KeyP)
-	KeyQ         = Key(glfw.KeyQ)
-	KeyR         = Key(glfw.KeyR)
-	KeyS         = Key(glfw.KeyS)
-	KeyT         = Key(glfw.KeyT)
-	KeyU         = Key(glfw.KeyU)
-	KeyV         = Key(glfw.KeyV)
-	KeyW         = Key(glfw.KeyW)
-	KeyX         = Key(glfw.KeyX)
-	KeyY         = Key(glfw.KeyY)
-	KeyZ         = Key(glfw.KeyZ)
-	KeySpace     = Key(glfw.KeySpace)
-	KeyLeftShift = Key(glfw.KeyLeftShift)
-	KeyUp        = Key(glfw.KeyUp)
-	KeyDown      = Key(glfw.KeyDown)
+	KeyA         Key = Key(glfw.KeyA)
+	KeyB             = Key(glfw.KeyB)
+	KeyC             = Key(glfw.KeyC)
+	KeyD             = Key(glfw.KeyD)
+	KeyE             = Key(glfw.KeyE)
+	KeyF             = Key(glfw.KeyF)
+	KeyG             = Key(glfw.KeyG)
+	KeyH             = Key(glfw.KeyH)
+	KeyI             = Key(glfw.KeyI)
+	KeyJ             = Key(glfw.KeyJ)
+	KeyK             = Key(glfw.KeyK)
+	KeyL             = Key(glfw.KeyL)
+	KeyM             = Key(glfw.KeyM)
+	KeyN             = Key(glfw.KeyN)
+	KeyO             = Key(glfw.KeyO)
+	KeyP             = Key(glfw.KeyP)
+	KeyQ             = Key(glfw.KeyQ)
+	KeyR             = Key(glfw.KeyR)
+	KeyS             = Key(glfw.KeyS)
+	KeyT             = Key(glfw.KeyT)
+	KeyU             = Key(glfw.KeyU)
+	KeyV             = Key(glfw.KeyV)
+	KeyW             = Key(glfw.KeyW)
+	KeyX             = Key(glfw.KeyX)
+	KeyY             = Key(glfw.KeyY)
+	KeyZ             = Key(glfw.KeyZ)
+	KeySpace         = Key(glfw.KeySpace)
+	KeyLeftShift     = Key(glfw.KeyLeftShift)
+	KeyUp            = Key(glfw.KeyUp)
+	KeyDown          = Key(glfw.KeyDown)
 )
 
 var Termination error = errors.New("Termination")