commit 9cb807c52a03be40dd03fc91695b1efd4684638b
parent a3c25be3ed443829edb81e32c125b8ce4403cfea
Author: Matsuda Kenji <info@mtkn.jp>
Date: Wed, 20 Nov 2024 16:58:21 +0900
use reflect to upload uniforms
Diffstat:
2 files changed, 63 insertions(+), 18 deletions(-)
diff --git a/cmd/sample/main.go b/cmd/sample/main.go
@@ -75,8 +75,29 @@ func watchCursor(app *App) {
}
}
-var teapot *tofu.Object
+type Uniform struct {
+ Sun
+}
+type Sun struct {
+ Dir tofu.Vec3 `tofu:"sun.dir"`
+ Ambient tofu.Vec3 `tofu:"sun.ambient"`
+ Diffuse tofu.Vec3 `tofu:"sun.diffuse"`
+ Specular tofu.Vec3 `tofu:"sun.specular"`
+}
+
+var (
+ sunCol = tofu.Vec3{1, 1, 1}
+ sunDir = tofu.Vec3{-0.2, -1.0, -0.3}
+ sun = Sun{
+ Dir: sunDir,
+ Ambient: sunCol.MulF(0.5),
+ Diffuse: sunCol.MulF(0.3),
+ Specular: sunCol,
+ }
+)
+
+var teapot *tofu.Object
var object = &tofu.Object{
Vertices: []tofu.Vec3{
tofu.Vec3{0.5, 0.5, -0.5},
@@ -116,6 +137,7 @@ var object = &tofu.Object{
{{4, 5, 0}, {5, 5, 1}, {6, 5, 2}},
{{4, 5, 0}, {6, 5, 2}, {7, 5, 3}},
},
+ Uniforms: Uniform{Sun: sun},
}
var cubePositions = []tofu.Vec3{
@@ -157,9 +179,6 @@ func (app *App) Update() error {
view := camera.View()
projection := tofu.Perspective(80*math.Pi/180, 800/600, 0.1, 100)
- sunCol := tofu.Vec3{1, 1, 1}
- sunDir := tofu.Vec3{-0.2, -1.0, -0.3}
-
lightCol := tofu.Vec3{1, 1, 1}
lightModel := tofu.Rotate(now, tofu.Vec3{0, 1, 0}).
Mul(tofu.Translate(tofu.Vec3{5, 4.5, 0})).
@@ -174,10 +193,6 @@ func (app *App) Update() error {
app.program.SetTexture("material.diffuse", app.texture)
app.program.SetTexture("material.specular", app.specularMap)
app.program.SetFloat32("material.shiness", 32)
- app.program.SetVec3("sun.dir", sunDir)
- app.program.SetVec3("sun.ambient", sunCol.MulF(0.5))
- app.program.SetVec3("sun.diffuse", sunCol.MulF(0.3))
- app.program.SetVec3("sun.specular", sunCol)
app.program.SetVec3("light.pos", lightPos)
app.program.SetVec3("light.dir", tofu.Vec3{0, 0, 0}.Sub(lightPos))
app.program.SetFloat32("light.cutOff", float32(math.Cos(25*math.Pi/180)))
@@ -192,7 +207,7 @@ func (app *App) Update() error {
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()
+ object.Draw(app.program)
}
app.teapotProgram.Use()
app.teapotProgram.SetMat4("view", view)
@@ -202,28 +217,24 @@ func (app *App) Update() error {
app.teapotProgram.SetVec3("material.diffuse", tofu.Vec3{0.3, 0.4, 0.4})
app.teapotProgram.SetVec3("material.specular", tofu.Vec3{0.3, 0.4, 0.4})
app.teapotProgram.SetFloat32("material.shiness", 32)
- app.teapotProgram.SetVec3("sun.dir", sunDir)
- app.teapotProgram.SetVec3("sun.ambient", sunCol.MulF(0.5))
- app.teapotProgram.SetVec3("sun.diffuse", sunCol.MulF(0.3))
- app.teapotProgram.SetVec3("sun.specular", sunCol)
app.teapotProgram.SetVec3("light.pos", lightPos)
app.teapotProgram.SetVec3("light.dir", tofu.Vec3{0, 0, 0}.Sub(lightPos))
app.teapotProgram.SetFloat32("light.outerCutOff", float32(math.Cos(35*math.Pi/180)))
app.teapotProgram.SetFloat32("light.cutOff", float32(math.Cos(25*math.Pi/180)))
- app.teapotProgram.SetVec3("light.ambient", lightCol.MulF(0.4))
- app.teapotProgram.SetVec3("light.diffuse", lightCol.MulF(0.9))
+ app.teapotProgram.SetVec3("light.ambient", lightCol.MulF(0.9))
+ app.teapotProgram.SetVec3("light.diffuse", lightCol.MulF(0.1))
app.teapotProgram.SetVec3("light.specular", lightCol)
app.teapotProgram.SetFloat32("light.Kc", 1.0)
app.teapotProgram.SetFloat32("light.Kl", 0.0009)
app.teapotProgram.SetFloat32("light.Kq", 0.00032)
- teapot.Draw()
+ teapot.Draw(app.teapotProgram)
app.lightProgram.Use()
app.program.SetMat4("view", view)
app.program.SetMat4("projection", projection)
app.program.SetMat4("model", lightModel)
app.lightProgram.SetVec3("lightCol", lightCol)
- object.Draw()
+ object.Draw(app.lightProgram)
return nil
}
@@ -261,6 +272,7 @@ func main() {
log.Fatal(err)
}
// teapot.SetNormals()
+ teapot.Uniforms = sun
teapot.Load()
app.program, err = tofu.NewProgram(vpath, fpath)
diff --git a/object.go b/object.go
@@ -6,6 +6,7 @@ import (
"log"
"math"
"os"
+ "reflect"
"strconv"
"strings"
@@ -17,6 +18,7 @@ type Object struct {
TexCoords []Vec2
Normals []Vec3
Faces []Face
+ Uniforms interface{}
vao *VAO
}
@@ -237,9 +239,40 @@ func (obj *Object) Load() {
obj.vao = newVAO(obj)
}
-func (obj *Object) Draw() {
+func (obj *Object) setUniforms(prog *Program) {
+ if obj.Uniforms == nil {
+ return
+ }
+ setUniforms(obj.Uniforms, prog)
+}
+
+func setUniforms(uniforms interface{}, prog *Program) {
+ s := reflect.ValueOf(uniforms)
+ fields := reflect.VisibleFields(s.Type())
+ for i := 0; i < s.NumField(); i++ {
+ fv := s.Field(i)
+ ft := fields[i]
+ if fv.Kind() == reflect.Struct {
+ setUniforms(fv.Interface(), prog)
+ continue
+ }
+ tag, ok := ft.Tag.Lookup("tofu")
+ if !ok {
+ continue
+ }
+ switch ft.Type.String() {
+ case "tofu.Vec3":
+ log.Println(prog.SetVec3(tag, fv.Interface().(Vec3)))
+ default:
+ log.Printf("unknown uniform type: %s", ft.Type)
+ }
+ }
+}
+
+func (obj *Object) Draw(prog *Program) {
// TODO: performance?
obj.vao.bind()
+ obj.setUniforms(prog)
gl.DrawElements(gl.TRIANGLES,
int32(obj.stride()*3*len(obj.Faces)),
gl.UNSIGNED_INT, nil)