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