tofu

Making something with OpenGL in Go
Log | Files | Refs

commit 0173f61f241aa6dacb77ebc03894e89489ec0bc7
parent 7b2d19954b7f75dfe6c90e7618d60010f261277d
Author: Matsuda Kenji <info@mtkn.jp>
Date:   Tue,  3 Dec 2024 12:42:21 +0900

tinker

Diffstat:
Mcmd/sample/main.go | 12+++---------
Mcmd/sample/teapot.glsl | 71++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------
Mobject.go | 6++++++
Mshader.go | 13+++++++++++++
4 files changed, 80 insertions(+), 22 deletions(-)

diff --git a/cmd/sample/main.go b/cmd/sample/main.go @@ -237,16 +237,10 @@ var cubeUniforms = struct { var teapotUniforms = struct { CamPos tofu.Vec3 Trans Trans - Teapot Material //Sun *DirLight - Light *SpotLight - PointLights []PointLight + Light *SpotLight + // PointLights []PointLight }{ - Teapot: Material{ - Diffuse: tofu.Vec3{0.3, 0.4, 0.4}, - Specular: tofu.Vec3{0.3, 0.4, 0.4}, - Shiness: 32, - }, //Sun: sun, Light: spotLight, } @@ -427,7 +421,7 @@ func main() { } } cubeUniforms.PointLights = pointLights - teapotUniforms.PointLights = pointLights + // teapotUniforms.PointLights = pointLights camera = tofu.NewCamera() camera.MoveTo(tofu.Vec3{0, 0, 3}) camera.LookAt(tofu.Vec3{0, 0, 0}) diff --git a/cmd/sample/teapot.glsl b/cmd/sample/teapot.glsl @@ -1,8 +1,12 @@ #version 330 core struct Material { + bool useTexture; vec3 Diffuse; vec3 Specular; + sampler2D map_Kd; + sampler2D map_Bump; + sampler2D map_Ks; float Shiness; }; @@ -51,55 +55,96 @@ void main() { fcol = vec4(0, 0, 0, 1); fcol += vec4(calcSpotLight(Light, Teapot, CamPos), 0); // fcol += vec4(calcDirLight(Sun, Teapot, CamPos), 0); +/* for (int i = 0; i < PointLights.length(); i++) { fcol += vec4(calcPointLight(PointLights[i], Teapot, CamPos), 0); } +*/ } vec3 calcPointLight(PointLight l, Material m, vec3 camPos) { vec3 ambient, diffuse, specular; vec3 lightDir, viewDir, reflectDir; + vec3 normal; float diff, spec, dist, attenuation; + if (m.useTexture) { + normal = normalize(vec3(texture(m.map_Bump, texPos))); + } else { + normal = fnormal; + } + dist = length(l.Pos - fpos); attenuation = 1 / (l.Kc + l.Kl * dist + l.Kq * dist * dist); - ambient = m.Diffuse * l.Ambient; + if (m.useTexture) { + ambient = vec3(texture(m.map_Kd, texPos)) * l.Ambient; + } else { + ambient = m.Diffuse * l.Ambient; + } lightDir = normalize(l.Pos - fpos); - diff = max(dot(fnormal, lightDir), 0.0); - diffuse = diff * m.Diffuse * l.Diffuse; + diff = max(dot(normal, lightDir), 0.0); + if (m.useTexture) { + diffuse = diff * vec3(texture(m.map_Kd, texPos)) * l.Diffuse; + } else { + diffuse = diff * m.Diffuse * l.Diffuse; + } viewDir = normalize(camPos - fpos); - reflectDir = reflect(-lightDir, fnormal); - spec = pow(max(dot(viewDir, reflectDir), 0.0), m.Shiness); - specular = m.Specular * spec * l.Specular; - + reflectDir = reflect(-lightDir, normal); + if (m.useTexture) { + spec = pow(max(dot(viewDir, reflectDir), 0.0), 32); + specular = vec3(texture(m.map_Ks, texPos)) * spec * l.Specular; + } else { + spec = pow(max(dot(viewDir, reflectDir), 0.0), m.Shiness); + specular = m.Specular * spec * l.Specular; + } return (ambient + diffuse + specular) * attenuation; } vec3 calcSpotLight(SpotLight l, Material m, vec3 camPos) { vec3 ambient, diffuse, specular; vec3 lightDir, viewDir, reflectDir; + vec3 normal; float diff, spec, dist, attenuation; float theta, epsilon, intensity; + if (m.useTexture) { + normal = normalize(vec3(texture(m.map_Bump, texPos))); + } else { + normal = fnormal; + } + dist = length(l.Pos - fpos); attenuation = 1 / (l.Kc + l.Kl * dist + l.Kq * dist * dist); - ambient = m.Diffuse * l.Ambient; + if (m.useTexture) { + ambient = vec3(texture(m.map_Kd, texPos)) * l.Ambient; + } else { + ambient = m.Diffuse * l.Ambient; + } lightDir = normalize(l.Pos - fpos); theta = dot(lightDir, normalize(-l.Dir)); epsilon = l.CutOff - l.OuterCutOff; intensity = clamp((theta - l.OuterCutOff) / epsilon, 0.0, 1.0); - diff = max(dot(fnormal, lightDir), 0.0); - diffuse = diff * m.Diffuse * l.Diffuse * intensity; + diff = max(dot(normal, lightDir), 0.0); + if (m.useTexture) { + diffuse = diff * vec3(texture(m.map_Kd, texPos)) * l.Diffuse * intensity; + } else { + diffuse = diff * m.Diffuse * l.Diffuse * intensity; + } viewDir = normalize(camPos - fpos); - reflectDir = reflect(-lightDir, fnormal); - spec = pow(max(dot(viewDir, reflectDir), 0.0), m.Shiness); - specular = m.Specular * spec * l.Specular * intensity; + reflectDir = reflect(-lightDir, normal); + if (m.useTexture) { + spec = pow(max(dot(viewDir, reflectDir), 0.0), 32); + specular = vec3(texture(m.map_Ks, texPos)) * spec * l.Specular * intensity; + } else { + spec = pow(max(dot(viewDir, reflectDir), 0.0), m.Shiness); + specular = m.Specular * spec * l.Specular * intensity; + } return (ambient + diffuse + specular) * attenuation; } diff --git a/object.go b/object.go @@ -267,6 +267,12 @@ func (obj *Object) Load() { func (obj *Object) Draw(prog *Program) { // TODO: performance? obj.vao.bind() + for _, m := range obj.Materials { + prog.SetBool("Teapot.useTexture", true) + prog.SetTexture("Teapot.map_Kd", m.map_Kd) + prog.SetTexture("Teapot.map_Bump", m.map_Bump) + prog.SetTexture("Teapot.map_Ks", m.map_Ks) + } gl.DrawElements(gl.TRIANGLES, int32(obj.stride()*3*len(obj.Faces)), gl.UNSIGNED_INT, nil) diff --git a/shader.go b/shader.go @@ -210,3 +210,16 @@ func (p *Program) SetTexture(name string, t *Texture) error { p.nextTextureUnit++ return nil } + +func (p *Program) SetBool(name string, t bool) error { + l := gl.GetUniformLocation(p.id, gl.Str(name+"\x00")) + if l == -1 { + return fmt.Errorf("no such uniform: %s", name) + } + if t { + gl.Uniform1i(l, gl.TRUE) + } else { + gl.Uniform1i(l, gl.FALSE) + } + return nil +}