commit 0173f61f241aa6dacb77ebc03894e89489ec0bc7
parent 7b2d19954b7f75dfe6c90e7618d60010f261277d
Author: Matsuda Kenji <info@mtkn.jp>
Date:   Tue,  3 Dec 2024 12:42:21 +0900
tinker
Diffstat:
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
+}