tofu

Making something with OpenGL in Go
Log | Files | Refs

commit 0cea544387e27db1adc96b54e3d63ad74f8b010c
parent a8b156fbd2bca8873e8b09d678ba134a0cffc4bb
Author: Matsuda Kenji <info@mtkn.jp>
Date:   Tue, 12 Nov 2024 17:45:15 +0900

gofmt

Diffstat:
Mcamera.go | 7+++----
Mcmd/sample/fragment.glsl | 37++++++++++++++++++++++++++-----------
Mcmd/sample/main.go | 35++++++++++++++++++++++-------------
Merror.go | 3+--
Mmath.go | 24++++++++++++------------
Mshader.go | 12++++++------
Mtexture.go | 6+++---
Mtofu.go | 76+++++++++++++++++++++++++++++++++++++++++-----------------------------------
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")