/
model.go
107 lines (91 loc) · 3.2 KB
/
model.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
package model
import (
"image/color"
"log"
"github.com/go-gl/mathgl/mgl32"
"github.com/goxjs/gl"
"github.com/omustardo/gome/core/entity"
"github.com/omustardo/gome/model/mesh"
"github.com/omustardo/gome/shader"
)
type Model struct {
// Tag is a human readable string for debugging.
// NOTE: If this field starts being used for anything but human use, something is wrong.
Tag string
// Hidden determines whether the model will be rendered or not. False by default.
Hidden bool
mesh.Mesh
entity.Entity
}
func (m *Model) Render() {
if m == nil {
log.Panic("Attempted to draw a nil model") // TODO: Not fatal error with better logging
return
}
if m.Hidden || (m.Mesh == mesh.Mesh{}) {
return
}
if m.Scale.X() == 0 && m.Scale.Y() == 0 && m.Scale.Z() == 0 {
log.Println("Attempted to draw a model with scale [0,0,0]")
return
}
if !m.Mesh.VertexVBO().Valid() {
log.Println("Attempted to draw a model with no vertices")
return
}
shader.Model.SetTranslationMatrix(m.Position.X(), m.Position.Y(), m.Position.Z())
shader.Model.SetRotationMatrixQ(m.Rotation.Mul(m.Mesh.BaseRotation))
shader.Model.SetScaleMatrix(m.Scale.X(), m.Scale.Y(), m.Scale.Z())
shader.Model.SetColor(m.Mesh.Color)
shader.Model.SetTexture(m.Mesh.Texture())
gl.BindBuffer(gl.ARRAY_BUFFER, m.Mesh.VertexVBO())
gl.EnableVertexAttribArray(shader.Model.VertexPositionAttrib) // TODO: Can these VertexAttribArrays be enabled a single time in shader initialization and then just always used?
gl.VertexAttribPointer(shader.Model.VertexPositionAttrib, 3, gl.FLOAT, false, 0, 0)
gl.BindBuffer(gl.ARRAY_BUFFER, m.Mesh.NormalVBO())
gl.EnableVertexAttribArray(shader.Model.NormalAttrib)
gl.VertexAttribPointer(shader.Model.NormalAttrib, 3, gl.FLOAT, false, 0, 0)
gl.BindBuffer(gl.ARRAY_BUFFER, m.Mesh.TextureCoords())
gl.EnableVertexAttribArray(shader.Model.TextureCoordAttrib)
gl.VertexAttribPointer(shader.Model.TextureCoordAttrib, 2, gl.FLOAT, false, 0, 0)
if m.VertexIndices().Valid() {
gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, m.Mesh.VertexIndices())
gl.DrawElements(m.VBOMode(), m.ItemCount(), gl.UNSIGNED_SHORT, 0)
} else {
gl.DrawArrays(m.VBOMode(), 0, m.ItemCount())
}
}
const axisLength = 1e6
// DrawXYZAxes draws the three basic X,Y,Z axes colored red, green, and blue respectively.
func RenderXYZAxes() {
axes := Model{
Mesh: mesh.Axes,
Entity: entity.Entity{
Scale: mgl32.Vec3{axisLength, axisLength, axisLength},
},
}
axes.Render()
}
func (m *Model) RenderRotationAxes() {
axes := Model{
Mesh: mesh.Axes,
Entity: m.Entity,
}
axes.Scale = axes.Scale.Mul(2) //1.25)
axes.Render()
}
// RenderDebugSphere draws three circles that live in the bounding sphere of the model.
func (m *Model) RenderDebugSphere() {
r := Model{
Mesh: mesh.NewCircleOutline(&color.NRGBA{255, 0, 0, 255}),
Entity: m.Entity,
}
r.Render()
r.ModifyRotationLocal(mgl32.Vec3{0, mgl32.DegToRad(90), 0})
r.Color = &color.NRGBA{0, 255, 0, 255}
r.Render()
r.ModifyRotationLocal(mgl32.Vec3{mgl32.DegToRad(90), 0, 0})
r.Color = &color.NRGBA{0, 0, 255, 255}
r.Render()
}
// TODO: Make sure there's documentation that all Index Buffers must be of type gl.UNSIGNED_SHORT (golang's uint16)
// and all other buffers must be gl.Float (golang's float32).