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")