commit 5ff24aefbda018b22918a9a626fe522dc4297192
parent 0173f61f241aa6dacb77ebc03894e89489ec0bc7
Author: Matsuda Kenji <info@mtkn.jp>
Date:   Tue, 10 Dec 2024 09:04:54 +0900
need tangent
Diffstat:
3 files changed, 55 insertions(+), 50 deletions(-)
diff --git a/cmd/sample/teapot.glsl b/cmd/sample/teapot.glsl
@@ -111,7 +111,7 @@ vec3 calcSpotLight(SpotLight l, Material m, vec3 camPos) {
 	float theta, epsilon, intensity;
 
 	if (m.useTexture) {
-		normal = normalize(vec3(texture(m.map_Bump, texPos)));
+		normal = normalize(vec3(texture(m.map_Bump, texPos))*2 - 1);
 	} else {
 		normal = fnormal;
 	}
diff --git a/cmd/sample/vertex.glsl b/cmd/sample/vertex.glsl
@@ -3,6 +3,7 @@ layout (location = 0) in vec3 pos;
 layout (location = 1) in vec3 col;
 layout (location = 2) in vec2 vTexPos;
 layout (location = 3) in vec3 normal;
+layout (location = 4) in vec3 tangent;
 
 struct trans {
 	mat4 Projection;
@@ -12,11 +13,14 @@ struct trans {
 
 uniform trans Trans;
 out vec3 fnormal;
+//out vec3 ftangent;
 out vec3 fpos;
 out vec2 texPos;
+
 void main() {
 	gl_Position = Trans.Projection * Trans.View * Trans.Model * vec4(pos, 1.0);
 	fnormal = normalize(mat3(transpose(inverse(Trans.Model))) * normal);
+//	ftangent = normalize(mat3(transpose(inverse(Trans.Model))) * tangent);
 	fpos = vec3(Trans.Model * vec4(pos, 1.0));
 	texPos = vTexPos;
 }
diff --git a/object.go b/object.go
@@ -20,10 +20,19 @@ func (e ErrUnsupported) Error() string {
 	return string(e) + " unsupported, ignoring"
 }
 
+var NoIndex = math.MinInt
+
+type VertexIndex struct {
+	V, N, T int
+}
+
+type Face [3]VertexIndex
+
 type Object struct {
 	Vertices  []Vec3
 	TexCoords []Vec2
 	Normals   []Vec3
+	Tangents  []Vec3
 	Faces     []Face
 	Materials map[string]*Material
 	vao       *VAO
@@ -185,60 +194,47 @@ func (obj *Object) addFace(s []string) error {
 	return nil
 }
 
-var NoIndex = math.MinInt
-
-type VertexIndex struct {
-	V, N, T int
+func (obj *Object) hasNormals() bool {
+	return obj.Faces[0][0].N != NoIndex
 }
 
-type Face [3]VertexIndex
+func (obj *Object) hasTexCoords() bool {
+	return obj.Faces[0][0].T != NoIndex
+}
 
-func (obj Object) stride() int {
-	if len(obj.Faces) < 1 {
-		return 0
-	}
-	var stride int = 3
-	if obj.Faces[0][0].N != NoIndex {
-		stride += 3
-	}
-	if obj.Faces[0][0].T != NoIndex {
-		stride += 2
-	}
-	return stride
+func (obj *Object) hasTangents() bool {
+	return obj.Tangents != nil
 }
 
-func (obj Object) data() []float32 {
-	stride := obj.stride()
-	if stride == 0 {
-		return nil
-	}
+const stride = 3 + 2 + 3 + 3
+
+func (obj *Object) data() []float32 {
 	data := make([]float32, stride*3*len(obj.Faces))
 	for i, f := range obj.Faces {
 		for j := 0; j < 3; j++ {
 			data[stride*(3*i+j)] = obj.Vertices[f[j].V][0]
 			data[stride*(3*i+j)+1] = obj.Vertices[f[j].V][1]
 			data[stride*(3*i+j)+2] = obj.Vertices[f[j].V][2]
-			switch stride {
-			case 5:
-				data[stride*(3*i+j)+3] = obj.TexCoords[f[j].T][0]
-				data[stride*(3*i+j)+4] = obj.TexCoords[f[j].T][1]
-			case 6:
-				data[stride*(3*i+j)+3] = obj.Normals[f[j].N][0]
-				data[stride*(3*i+j)+4] = obj.Normals[f[j].N][1]
-				data[stride*(3*i+j)+5] = obj.Normals[f[j].N][2]
-			case 8:
+			if obj.hasTexCoords() {
 				data[stride*(3*i+j)+3] = obj.TexCoords[f[j].T][0]
 				data[stride*(3*i+j)+4] = obj.TexCoords[f[j].T][1]
+			}
+			if obj.hasNormals() {
 				data[stride*(3*i+j)+5] = obj.Normals[f[j].N][0]
 				data[stride*(3*i+j)+6] = obj.Normals[f[j].N][1]
 				data[stride*(3*i+j)+7] = obj.Normals[f[j].N][2]
 			}
+			if obj.hasTangents() {
+				data[stride*(3*i+j)+8] = obj.Tangents[f[j].N][0]
+				data[stride*(3*i+j)+9] = obj.Tangents[f[j].N][1]
+				data[stride*(3*i+j)+10] = obj.Tangents[f[j].N][2]
+			}
 		}
 	}
 	return data
 }
 
-func (obj Object) faceData() []uint32 {
+func (obj *Object) faceData() []uint32 {
 	fdata := make([]uint32, 3*len(obj.Faces))
 	for i := 0; i < 3*len(obj.Faces); i++ {
 		fdata[i] = uint32(i)
@@ -259,6 +255,19 @@ func (obj *Object) SetNormals() {
 	}
 }
 
+func (obj *Object) SetTangents() {
+	if !obj.hasNormals() {
+		panic(fmt.Errorf("object does not have normals"))
+	}
+	if !obj.hasTexCoords() {
+		panic(fmt.Errorf("object does not have texCoords"))
+	}
+	obj.Tangents = make([]Vec3, len(obj.Normals))
+	for i, f := range obj.Normals {
+// WIP
+	}
+}
+
 // Load copies object data into the GPU.
 func (obj *Object) Load() {
 	obj.vao = newVAO(obj)
@@ -274,7 +283,7 @@ func (obj *Object) Draw(prog *Program) {
 		prog.SetTexture("Teapot.map_Ks", m.map_Ks)
 	}
 	gl.DrawElements(gl.TRIANGLES,
-		int32(obj.stride()*3*len(obj.Faces)),
+		int32(stride*3*len(obj.Faces)),
 		gl.UNSIGNED_INT, nil)
 }
 
@@ -285,17 +294,14 @@ type VAO struct {
 }
 
 const (
-	UniformVertex = iota
-	UniformColor
-	UniformTexCoords
-	UniformNormal
+	UniformVertex    = 0
+	UniformColor     = 1
+	UniformTexCoords = 2
+	UniformNormal    = 3
+	UniformTangent   = 4
 )
 
 func newVAO(obj *Object) *VAO {
-	stride := obj.stride()
-	if stride == 0 {
-		return nil
-	}
 	var id uint32
 	gl.GenVertexArrays(1, &id)
 	vao := &VAO{id: id, vbo: newBuffer(), ebo: newBuffer()}
@@ -303,14 +309,9 @@ func newVAO(obj *Object) *VAO {
 	data := obj.data()
 	vao.setData(data)
 	vao.setAttribute(UniformVertex, 3, stride, 0)
-	if stride == 5 {
-		vao.setAttribute(UniformTexCoords, 2, stride, 3)
-	} else if stride == 6 {
-		vao.setAttribute(UniformNormal, 3, stride, 3)
-	} else if stride == 8 {
-		vao.setAttribute(UniformTexCoords, 2, stride, 3)
-		vao.setAttribute(UniformNormal, 3, stride, 5)
-	}
+	vao.setAttribute(UniformTexCoords, 2, stride, 3)
+	vao.setAttribute(UniformNormal, 3, stride, 5)
+	vao.setAttribute(UniformTangent, 3, stride, 8)
 	fdata := obj.faceData()
 	vao.setFaces(fdata)
 	return vao