carpy-breakout/pkg/globject/face.go

158 lines
3.2 KiB
Go

package globject
import (
"log"
"git.wisellama.rocks/Wisellama/carpy-breakout/pkg/glshader"
"git.wisellama.rocks/Wisellama/carpy-breakout/pkg/math"
gl "github.com/go-gl/gl/v3.1/gles2"
"github.com/go-gl/mathgl/mgl32"
)
type Face struct {
Material *Material
Triangles []*Triangle
LineLoopVertexArray []float32
GLLineLoopVertexArrayID uint32
GLLineLoopVertexBufferID uint32
}
func NewFace(
width, height float32,
center, normal mgl32.Vec3,
material *Material) *Face {
// top left, shared
v1 := newFaceVertex(
-1*width/2.0,
height/2.0,
center,
normal,
mgl32.Vec2{0, 1})
// bottom left
v2 := newFaceVertex(
-1*width/2.0,
-1*height/2.0,
center,
normal,
mgl32.Vec2{0, 0})
// bottom right, shared
v3 := newFaceVertex(
width/2.0,
-1*height/2.0,
center,
normal,
mgl32.Vec2{1, 0})
// top right
v4 := newFaceVertex(
width/2.0,
height/2.0,
center,
normal,
mgl32.Vec2{1, 1})
t1 := NewTriangle(v1, v2, v3)
t2 := NewTriangle(v3, v4, v1)
face := Face{
Material: material,
Triangles: []*Triangle{t1, t2},
}
face.LineLoopVertexArray = face.GetLineLoopVertexArray()
return &face
}
func newFaceVertex(
xoffset, zoffset float32,
center, normal mgl32.Vec3,
texture mgl32.Vec2) *Vertex {
// We'll create the face as though the normal were simply upward
// {0, 1, 0} and then rotate all the points to fit the actual
// normal.
// Create the vertex offset from zero
v := mgl32.Vec3{xoffset, 0, zoffset}
up := mgl32.Vec3{0, 1, 0}
angle, err := math.AngleBetweenVectors(up, normal)
if err != nil {
log.Println(err)
return nil
}
rotationAxis := up.Cross(normal)
// rotate
quat := mgl32.QuatRotate(angle, rotationAxis)
v = quat.Rotate(v)
// add the center so we get the correct absolute position
v = v.Add(center)
vertex := NewVertex(
v.X(), v.Y(), v.Z(),
normal.X(), normal.Y(), normal.Z(),
texture[0], texture[1])
return vertex
}
func (f *Face) GetVertexArray() []float32 {
a := make([]float32, 2*3*VertexSize)
i := 0
for _, triangle := range f.Triangles {
for _, vertex := range triangle.Vertices {
va := vertex.GetVertexArray()
for _, v := range va {
a[i] = v
i++
}
}
}
return a
}
func (f *Face) GetLineLoopVertexArray() []float32 {
a := make([]float32, 4*VertexSize)
i := 0
for _, vertex := range f.Triangles[0].Vertices {
v := *vertex
for _, elem := range v.GetVertexArray() {
a[i] = elem
i++
}
}
fourthV := *f.Triangles[1].Vertices[1]
for _, elem := range fourthV.GetVertexArray() {
a[i] = elem
i++
}
return a
}
func (f *Face) GLDrawLineLoop(glProgram uint32) {
gl.BindVertexArray(f.GLLineLoopVertexArrayID)
gl.BindBuffer(gl.ARRAY_BUFFER, f.GLLineLoopVertexBufferID)
glshader.UpdateVertexAttribs(glProgram, VertexSize)
gl.DrawArrays(gl.LINE_LOOP, 0, 4)
}
func (f *Face) GLInit(glProgram uint32) {
glshader.UpdateVertexAttribs(glProgram, VertexSize)
// LineLoop setup
gl.GenVertexArrays(1, &f.GLLineLoopVertexArrayID)
gl.BindVertexArray(f.GLLineLoopVertexArrayID)
gl.GenBuffers(1, &f.GLLineLoopVertexBufferID)
gl.BindBuffer(gl.ARRAY_BUFFER, f.GLLineLoopVertexBufferID)
sizeOfFloat := 4
gl.BufferData(gl.ARRAY_BUFFER, len(f.LineLoopVertexArray)*sizeOfFloat, gl.Ptr(f.LineLoopVertexArray), gl.STATIC_DRAW)
}