tofu

Making something with OpenGL in Go
Log | Files | Refs

commit 5ff24aefbda018b22918a9a626fe522dc4297192
parent 0173f61f241aa6dacb77ebc03894e89489ec0bc7
Author: Matsuda Kenji <info@mtkn.jp>
Date:   Tue, 10 Dec 2024 09:04:54 +0900

need tangent

Diffstat:
Mcmd/sample/teapot.glsl | 2+-
Mcmd/sample/vertex.glsl | 4++++
Mobject.go | 99++++++++++++++++++++++++++++++++++++++++---------------------------------------
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