Skip to content

Commit 9eeebb2

Browse files
author
HUGE | Raed Atoui
committed
gob format test
1 parent e564988 commit 9eeebb2

File tree

3 files changed

+116
-66
lines changed

3 files changed

+116
-66
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
# OSX
22
.DS_Store
3-
.idea/
3+
.idea/
4+
*.gob

tutorial.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,8 @@ func setup() (*glfw.Window, error) {
165165
func setupSlides() []sections.Slide {
166166
// make a slice of pointers to sketch instances
167167
return []sections.Slide{
168+
new(modelloading.ModelLoading),
169+
168170
new(sections.TitleSlide),
169171
new(getstarted.HelloCube),
170172
new(sections.TitleSlide),
@@ -191,7 +193,7 @@ func setupSlides() []sections.Slide {
191193
new(lighting.BasicSpecular),
192194

193195
new(sections.TitleSlide),
194-
new(modelloading.ModelLoading),
196+
195197

196198
new(sections.TitleSlide),
197199
new(sections.TitleSlide),
@@ -281,7 +283,6 @@ func main() {
281283

282284
var maxAttrib int32
283285
gl.GetIntegerv(gl.MAX_VERTEX_ATTRIBS, &maxAttrib)
284-
fmt.Println(maxAttrib)
285286

286287
utils.InitFPS()
287288

utils/model.go

Lines changed: 111 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -3,56 +3,58 @@ package utils
33
import "C"
44

55
import (
6+
"encoding/gob"
67
"errors"
78
"fmt"
89
"github.com/go-gl/gl/v4.1-core/gl"
10+
"github.com/go-gl/mathgl/mgl32"
911
"github.com/raedatoui/assimp"
10-
"strconv"
1112
"os"
12-
"github.com/go-gl/mathgl/mgl32"
13+
"strconv"
14+
"strings"
1315
"unsafe"
1416
)
1517

1618
type Mesh struct {
17-
id int
18-
vertices []Vertex
19-
indices []uint32
20-
textures []Texture
21-
Vao uint32
19+
Id int
20+
Vertices []Vertex
21+
Indices []uint32
22+
Textures []Texture
23+
vao uint32
2224
vbo, ebo uint32
2325
}
2426

2527
func NewMesh(v []Vertex, i []uint32, t []Texture) Mesh {
2628
m := Mesh{
27-
vertices: v,
28-
indices: i,
29-
textures: t,
29+
Vertices: v,
30+
Indices: i,
31+
Textures: t,
3032
}
3133
m.setup()
3234
return m
3335
}
3436

3537
func (m *Mesh) setup() {
3638
// size of the Vertex struct
37-
dummy := m.vertices[0]
39+
dummy := m.Vertices[0]
3840
structSize := int(unsafe.Sizeof(dummy))
3941
structSize32 := int32(structSize)
4042

4143
// Create buffers/arrays
42-
gl.GenVertexArrays(1, &m.Vao)
44+
gl.GenVertexArrays(1, &m.vao)
4345
gl.GenBuffers(1, &m.vbo)
4446
gl.GenBuffers(1, &m.ebo)
4547

46-
gl.BindVertexArray(m.Vao)
48+
gl.BindVertexArray(m.vao)
4749
// Load data into vertex buffers
4850
gl.BindBuffer(gl.ARRAY_BUFFER, m.vbo)
4951
// A great thing about structs is that their memory layout is sequential for all its items.
5052
// The effect is that we can simply pass a pointer to the struct and it translates perfectly to a gl.m::vec3/2 array which
5153
// again translates to 3/2 floats which translates to a byte array.
52-
gl.BufferData(gl.ARRAY_BUFFER, len(m.vertices)* structSize, gl.Ptr(m.vertices), gl.STATIC_DRAW)
54+
gl.BufferData(gl.ARRAY_BUFFER, len(m.Vertices)*structSize, gl.Ptr(m.Vertices), gl.STATIC_DRAW)
5355

5456
gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, m.ebo)
55-
gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, len(m.indices)*GL_FLOAT32_SIZE, gl.Ptr(m.indices), gl.STATIC_DRAW)
57+
gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, len(m.Indices)*GL_FLOAT32_SIZE, gl.Ptr(m.Indices), gl.STATIC_DRAW)
5658

5759
// Set the vertex attribute pointers
5860
// Vertex Positions
@@ -91,12 +93,12 @@ func (m *Mesh) draw(program uint32) {
9193
normalNr = 1
9294
heightNr = 1
9395
i = 0
94-
for i = 0; i < uint32(len(m.textures)); i++ {
96+
for i = 0; i < uint32(len(m.Textures)); i++ {
9597
gl.ActiveTexture(gl.TEXTURE0 + i) // Active proper texture unit before binding
9698

9799
// Retrieve texture number (the N in diffuse_textureN)
98100
ss := ""
99-
switch m.textures[i].TextureType {
101+
switch m.Textures[i].TextureType {
100102
case "texture_diffuse":
101103
ss = ss + strconv.FormatUint(diffuseNr, 10) // Transfer GLuint to stream
102104
diffuseNr++
@@ -112,20 +114,20 @@ func (m *Mesh) draw(program uint32) {
112114
}
113115

114116
// Now set the sampler to the correct texture unit
115-
tu := m.textures[i].TextureType + ss + "\x00"
117+
tu := m.Textures[i].TextureType + ss + "\x00"
116118

117119
gl.Uniform1i(gl.GetUniformLocation(program, gl.Str(tu)), int32(i))
118120
// And finally bind the texture
119-
gl.BindTexture(gl.TEXTURE_2D, m.textures[i].Id)
121+
gl.BindTexture(gl.TEXTURE_2D, m.Textures[i].id)
120122
}
121123

122124
// Draw mesh
123-
gl.BindVertexArray(m.Vao)
124-
gl.DrawElements(gl.TRIANGLES, int32(len(m.indices)), gl.UNSIGNED_INT, gl.PtrOffset(0))
125+
gl.BindVertexArray(m.vao)
126+
gl.DrawElements(gl.TRIANGLES, int32(len(m.Indices)), gl.UNSIGNED_INT, gl.PtrOffset(0))
125127
gl.BindVertexArray(0)
126128

127129
// Always good practice to set everything back to defaults once configured.
128-
for i = 0; i < uint32(len(m.textures)); i++ {
130+
for i = 0; i < uint32(len(m.Textures)); i++ {
129131
gl.ActiveTexture(gl.TEXTURE0 + i)
130132
gl.BindTexture(gl.TEXTURE_2D, 0)
131133
}
@@ -140,47 +142,104 @@ type Vertex struct {
140142
}
141143

142144
type Texture struct {
143-
Id uint32
145+
id uint32
144146
TextureType string
145147
Path string
146148
}
147149

148150
type Model struct {
149151
texturesLoaded map[string]Texture
150-
meshes []Mesh
151-
director string
152-
gammaCorrection bool
153-
basePath string
154-
fileName string
152+
Meshes []Mesh
153+
GammaCorrection bool
154+
BasePath string
155+
FileName string
156+
GobName string
155157
}
156158

157159
func NewModel(b, f string, g bool) (Model, error) {
158-
160+
t := strings.Split(f, ".")
161+
gf := t[0] + ".gob"
159162
m := Model{
160-
basePath: b,
161-
fileName: f,
162-
gammaCorrection: g,
163+
BasePath: b,
164+
FileName: f,
165+
GobName: gf,
166+
GammaCorrection: g,
163167
}
164168
m.texturesLoaded = make(map[string]Texture)
165-
err := m.loadModel()
169+
gobFile := b + gf
170+
if _, err := os.Stat(gobFile); os.IsNotExist(err) {
171+
err := m.loadModel()
172+
//m.Export()
173+
return m, err
174+
}
175+
err := m.Import()
166176
return m, err
167177
}
168178

169179
func (m *Model) Draw(shader uint32) {
170-
for i := 0; i < len(m.meshes); i++ {
171-
m.meshes[i].draw(shader)
180+
for i := 0; i < len(m.Meshes); i++ {
181+
m.Meshes[i].draw(shader)
182+
}
183+
}
184+
185+
func (m *Model) Export() error {
186+
// export a gob file
187+
f := m.BasePath + m.GobName
188+
189+
dataFile, err := os.Create(f)
190+
if err != nil {
191+
return err
192+
}
193+
defer dataFile.Close()
194+
195+
dataEncoder := gob.NewEncoder(dataFile)
196+
dataEncoder.Encode(m)
197+
198+
return nil
199+
}
200+
201+
func (m *Model) Import() error {
202+
f := m.BasePath + m.GobName
203+
dataFile, err := os.Open(f)
204+
205+
if err != nil {
206+
return err
207+
}
208+
defer dataFile.Close()
209+
210+
dataDecoder := gob.NewDecoder(dataFile)
211+
err = dataDecoder.Decode(&m)
212+
213+
if err != nil {
214+
return nil
215+
}
216+
for _, mesh := range m.Meshes {
217+
mesh.setup()
218+
219+
fmt.Printf("vertices: %d, indices: %d, textures: %d\n", len(mesh.Vertices), len(mesh.Indices), len(mesh.Textures))
220+
221+
for _, tex := range mesh.Textures {
222+
if val, ok := m.texturesLoaded[tex.Path]; ok {
223+
fmt.Println( val)
224+
} else {
225+
226+
tex.id = m.textureFromFile(tex.Path)
227+
m.texturesLoaded[tex.Path] = tex
228+
}
229+
}
172230
}
231+
return nil
173232
}
174233

175234
// Loads a model with supported ASSIMP extensions from file and stores the resulting meshes in the meshes vector.
176235
func (m *Model) loadModel() error {
177236
// Read file via ASSIMP
178-
path := m.basePath + m.fileName
237+
path := m.BasePath + m.FileName
179238
scene := assimp.ImportFile(path, uint(
180239
assimp.Process_Triangulate|assimp.Process_FlipUVs))
181240

182241
// Check for errors
183-
if scene.Flags() & assimp.SceneFlags_Incomplete != 0 { // if is Not Zero
242+
if scene.Flags()&assimp.SceneFlags_Incomplete != 0 { // if is Not Zero
184243
fmt.Println("ERROR::ASSIMP:: %s\n", scene.Flags())
185244
return errors.New("shit failed")
186245
}
@@ -198,37 +257,30 @@ func (m *Model) processNode(n *assimp.Node, s *assimp.Scene) {
198257
// The scene contains all the data, node is just to keep stuff organized (like relations between nodes).
199258
mesh := s.Meshes()[n.Meshes()[i]]
200259
ms := m.processMesh(mesh, s)
201-
ms.id = i
202-
m.meshes = append(m.meshes, ms)
260+
ms.Id = i
261+
fmt.Printf("vertices: %d, indices: %d, textures: %d\n", len(ms.Vertices), len(ms.Indices), len(ms.Textures))
262+
m.Meshes = append(m.Meshes, ms)
203263
}
204264

205265
// After we've processed all of the meshes (if any) we then recursively process each of the children nodes
206266
c := n.Children()
207267
for j := 0; j < len(c); j++ {
268+
//go func(n *assimp.Node, s *assimp.Scene) {
208269
m.processNode(c[j], s)
270+
//}(c[j], s)
209271
}
210272
}
211273

212274
func (m *Model) processMeshVertices(mesh *assimp.Mesh) []Vertex {
213275
// Walk through each of the mesh's vertices
214276
vertices := []Vertex{}
215-
//p, _ := os.Create("data/positions"+ mesh.Name()+ ".txt")
216-
//n, _ := os.Create("data/normals"+ mesh.Name()+ ".txt")
217-
//t, _ := os.Create("data/texcoords"+ mesh.Name()+ ".txt")
218-
//
219-
//defer p.Close()
220-
//defer n.Close()
221-
//defer t.Close()
222-
//p.WriteString(mesh.Name() + "\n")
223-
//n.WriteString(mesh.Name() + "\n")
224-
//t.WriteString(mesh.Name() + "\n")
225277

226278
positions := mesh.Vertices()
227279

228280
normals := mesh.Normals()
229281
useNormals := len(normals) > 0
230282

231-
tex := mesh.TextureCoords(0)
283+
tex := mesh.TextureCoords(0)
232284
useTex := true
233285
if tex == nil {
234286
useTex = false
@@ -259,7 +311,7 @@ func (m *Model) processMeshVertices(mesh *assimp.Mesh) []Vertex {
259311
// Does the mesh contain texture coordinates?
260312
// A vertex can contain up to 8 different texture coordinates. We thus make the assumption that we won't
261313
// use models where a vertex can have multiple texture coordinates so we always take the first set (0).
262-
vertex.TexCoords = mgl32.Vec2{tex[i].X(), tex[i].Y()}
314+
vertex.TexCoords = mgl32.Vec2{tex[i].X(), tex[i].Y()}
263315
} else {
264316
vertex.TexCoords = mgl32.Vec2{0.0, 0.0}
265317
}
@@ -282,16 +334,12 @@ func (m *Model) processMeshVertices(mesh *assimp.Mesh) []Vertex {
282334

283335
func (m *Model) processMeshIndices(mesh *assimp.Mesh) []uint32 {
284336
indices := []uint32{}
285-
ind, _ := os.Create("data/indices"+ mesh.Name()+ ".txt")
286337
// Now wak through each of the mesh's faces (a face is a mesh its triangle) and retrieve the corresponding vertex indices.
287338
for i := 0; i < mesh.NumFaces(); i++ {
288339
face := mesh.Faces()[i]
289-
t := face.CopyIndices()
290-
ind.WriteString(fmt.Sprintf("[%d, %d, %d]\n", t[0], t[1], t[2]))
291340
// Retrieve all indices of the face and store them in the indices vector
292-
indices = append(indices,t ...)
341+
indices = append(indices, face.CopyIndices()...)
293342
}
294-
ind.WriteString("\n--------")
295343
return indices
296344
}
297345

@@ -324,12 +372,12 @@ func (m *Model) processMeshTextures(mesh *assimp.Mesh, s *assimp.Scene) []Textur
324372
return textures
325373
}
326374

327-
func (ml *Model) processMesh(m *assimp.Mesh, s *assimp.Scene) Mesh {
375+
func (m *Model) processMesh(ms *assimp.Mesh, s *assimp.Scene) Mesh {
328376
// Return a mesh object created from the extracted mesh data
329377
return NewMesh(
330-
ml.processMeshVertices(m),
331-
ml.processMeshIndices(m),
332-
ml.processMeshTextures(m, s))
378+
m.processMeshVertices(ms),
379+
m.processMeshIndices(ms),
380+
m.processMeshTextures(ms, s))
333381
}
334382

335383
func (m *Model) loadMaterialTextures(ms *assimp.Material, tm assimp.TextureMapping, tt string) []Texture {
@@ -339,20 +387,20 @@ func (m *Model) loadMaterialTextures(ms *assimp.Material, tm assimp.TextureMappi
339387

340388
for i := 0; i < textureCount; i++ {
341389
file, _, _, _, _, _, _, _ := ms.GetMaterialTexture(textureType, 0)
342-
filename := m.basePath + file
390+
filename := m.BasePath + file
343391
if val, ok := m.texturesLoaded[filename]; ok {
344392
result = append(result, val)
345393
} else {
346394
texId := m.textureFromFile(filename)
347-
texture := Texture{Id: texId, TextureType: tt, Path: file}
395+
texture := Texture{id: texId, TextureType: tt, Path: filename}
348396
result = append(result, texture)
349397
m.texturesLoaded[filename] = texture
350398
}
351399
}
352400
return result
353401
}
354402

355-
func (ml *Model) textureFromFile(f string) uint32 {
403+
func (m *Model) textureFromFile(f string) uint32 {
356404
//Generate texture ID and load texture data
357405
var textureID uint32
358406

0 commit comments

Comments
 (0)