tofu

Making something with OpenGL in Go
Log | Files | Refs

commit 9ab1beb74baa87e5635793b2201c9d3716a4994f
parent 7c7d3b856a7f34a9f9e1e32bdb43a38d90dd0ec7
Author: Matsuda Kenji <info@mtkn.jp>
Date:   Thu, 14 Nov 2024 08:57:40 +0900

euler angle, light cast

Diffstat:
Mcamera.go | 35+++++++++++++++++++++++++++++++++--
Mcmd/sample/fragment.glsl | 9+++------
Mcmd/sample/main.go | 58++++++++++++++++++++++++----------------------------------
Mtofu.go | 2+-
4 files changed, 61 insertions(+), 43 deletions(-)

diff --git a/camera.go b/camera.go @@ -1,7 +1,13 @@ package tofu +import ( + "log" + "math" +) + type Camera struct { Pos, Front, Up, Right Vec3 + Yaw, Pitch float32 } func NewCamera() *Camera { @@ -10,6 +16,8 @@ func NewCamera() *Camera { Front: Vec3{0, 0, 1}, Up: Vec3{0, 1, 0}, Right: Vec3{1, 0, 0}, + Yaw: -math.Pi / 2, + Pitch: 0, } } @@ -23,19 +31,42 @@ func (cam *Camera) Move(right, up, back float32) { Add(cam.Front.MulF(-back)) } -func (cam *Camera) Yaw(delta float32) { +// TODO: name +func (cam *Camera) YawPitch(dy, dp float32) { + const eps = 0.0000001 + log.Println(cam.Yaw, cam.Pitch, cam.Right) + cam.Yaw -= dy + cam.Pitch -= dp + if cam.Pitch > math.Pi/2 { + cam.Pitch = math.Pi/2 - eps + } else if cam.Pitch < -math.Pi/2 { + cam.Pitch = -math.Pi/2 + eps + } + y, p := float64(cam.Yaw), float64(cam.Pitch) + cam.Front[0] = float32(math.Cos(y) * math.Cos(p)) + cam.Front[1] = float32(math.Sin(p)) + cam.Front[2] = float32(math.Sin(y) * math.Cos(p)) + cam.Front = cam.Front.Normalize() + cam.Right = cam.Front.Cross(Vec3{0, 1, 0}).Normalize() + cam.Up = cam.Right.Cross(cam.Front).Normalize() +} + +func (cam *Camera) AddYaw(delta float32) { + cam.Yaw += delta rot := Rotate3(delta, cam.Up) cam.Front = rot.MulV(cam.Front) cam.Right = rot.MulV(cam.Right) } -func (cam *Camera) Pitch(delta float32) { +func (cam *Camera) AddPitch(delta float32) { + cam.Pitch += delta rot := Rotate3(-delta, cam.Right) cam.Front = rot.MulV(cam.Front) cam.Up = rot.MulV(cam.Up) } func (cam *Camera) LookAt(target Vec3) { + // TODO: update Yaw and Pitch cam.Front = target.Sub(cam.Pos).Normalize() cam.Right = cam.Up.Cross(cam.Front.Inverse()).Normalize() } diff --git a/cmd/sample/fragment.glsl b/cmd/sample/fragment.glsl @@ -3,12 +3,11 @@ struct Material { sampler2D diffuse; sampler2D specular; - sampler2D emission; float shiness; }; struct Light { - vec3 position; + vec3 direction; vec3 ambient; vec3 diffuse; vec3 specular; @@ -28,7 +27,7 @@ out vec4 fcol; void main() { vec3 ambient = vec3(texture(material.diffuse, texPos)) * light.ambient; - vec3 lightDir = normalize(light.position - fpos); + vec3 lightDir = normalize(-light.direction); float diff = max(dot(fnormal, lightDir), 0.0); vec3 diffuse = diff * vec3(texture(material.diffuse, texPos)) * light.diffuse; @@ -37,8 +36,6 @@ void main() { float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shiness); vec3 specular = vec3(texture(material.specular, texPos)) * spec * light.specular; - vec3 emission = texture(material.emission, texPos).rgb; - - fcol = vec4(ambient + diffuse + specular + emission, 1.0); + fcol = vec4(ambient + diffuse + specular, 1.0); } diff --git a/cmd/sample/main.go b/cmd/sample/main.go @@ -72,8 +72,7 @@ func watchCursor(app *App) { dx *= sensitivity dy *= sensitivity app.cur = cur - camera.Yaw(dx) - camera.Pitch(-dy) + camera.YawPitch(dx, -dy) } } @@ -128,6 +127,19 @@ var object = tofu.Object{ }, } +var cubePositions = []tofu.Vec3{ + {4.24, 0.94, -1.94}, + {0.79, 2.40, 2.87}, + {-0.64, -1.68, 2.79}, + {-3.99, 2.85, 3.35}, + {2.61, -0.04, -0.74}, + {4.46, 3.22, 2.09}, + {-3.42, -3.80, 4.10}, + {3.68, -0.51, 2.05}, + {-1.00, 1.45, 1.96}, + {-2.00, 0.92, 4.57}, +} + var alpha float32 = 0.2 type App struct { @@ -141,53 +153,36 @@ type App struct { startedAt time.Time texture *tofu.Texture specularMap *tofu.Texture - emission *tofu.Texture } func (app *App) Update() error { now := float32(time.Since(app.startedAt).Seconds()) - now = 0 processInput(app) if app.termination { return tofu.Termination } - 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, 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)} + lightCol := tofu.Vec3{1, 1, 1} app.program.Use() - 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.direction", tofu.Vec3{-0.2, -1.0, -0.3}) + app.program.SetVec3("light.ambient", lightCol.MulF(0.8)) + app.program.SetVec3("light.diffuse", lightCol.MulF(0.9)) 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("camPos", camera.Pos) app.program.SetTexture("material.diffuse", app.texture) app.program.SetTexture("material.specular", app.specularMap) - app.program.SetTexture("material.emission", app.emission) 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) - object.Draw() - - app.lightProgram.Use() - app.lightProgram.SetMat4("view", view) - app.lightProgram.SetMat4("projection", projection) - app.lightProgram.SetMat4("model", lightModel) - app.lightProgram.SetVec3("lightCol", lightCol) - object.Draw() + for i, p := range cubePositions { + model := tofu.Translate(p.Inverse()). + Mul(tofu.Rotate(20*float32(i)+now, tofu.Vec3{math.Sqrt2 / 2, -math.Sqrt2 / 2, 0})) + app.program.SetMat4("model", model) + object.Draw() + } return nil } @@ -217,7 +212,6 @@ func main() { lightFpath := filepath.Join(filepath.Dir(f), "light_fragment.glsl") texturePath := filepath.Join(filepath.Dir(f), "container2.png") specularMapPath := filepath.Join(filepath.Dir(f), "container2_specular.png") - emissionPath := filepath.Join(filepath.Dir(f), "matrix.jpg") app.program, err = tofu.NewProgram(vpath, fpath) if err != nil { @@ -235,10 +229,6 @@ func main() { if err != nil { log.Fatalf("NewTesture: %v", err) } - app.emission, err = tofu.NewTexture(emissionPath) - if err != nil { - log.Fatalf("NewTesture: %v", err) - } camera = tofu.NewCamera() camera.MoveTo(tofu.Vec3{0, 0, 3}) diff --git a/tofu.go b/tofu.go @@ -60,7 +60,7 @@ func Run(app App) error { defer close(c) } for !window.ShouldClose() { - gl.ClearColor(0.1, 0.2, 0.2, 1.0) + gl.ClearColor(1.0, 1.0, 0.918, 1.0) gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT) err := app.Update() if err == Termination {