1
+ #ifndef OPENGLMODEL_H
2
+ #define OPENGLMODEL_H
3
+
4
+ #include < GL\GL.h>
5
+ #include < GL\glew.h>
6
+
7
+ #include < assimp\Importer.hpp> // C++ importer interface
8
+ #include < assimp\scene.h> // Output data structure
9
+ #include < assimp\postprocess.h> // Post processing flags
10
+
11
+ #include < glm\glm.hpp>
12
+
13
+ #include < string>
14
+ #include < vector>
15
+ #include < memory>
16
+ #include < iostream>
17
+
18
+ using namespace std ;
19
+
20
+ class Mesh {
21
+
22
+ public:
23
+ Mesh (const aiMesh* mesh) {
24
+ load (mesh);
25
+ create ();
26
+ }
27
+
28
+ ~Mesh () {
29
+ glDeleteBuffers (4 , buffer);
30
+ glDeleteVertexArrays (1 , &vao);
31
+ }
32
+
33
+ // dibujar el mesh
34
+ void draw () {
35
+ glBindVertexArray (vao);
36
+ glDrawElements (GL_TRIANGLES, indices.size (), GL_UNSIGNED_INT, NULL );
37
+ glBindVertexArray (0 );
38
+ };
39
+
40
+ // inicializar el mesh
41
+ void init (const aiMesh* mesh) {
42
+ load (mesh);
43
+ create ();
44
+ };
45
+
46
+ private:
47
+ vector<glm::vec3> vertex;
48
+ vector<glm::vec3> normal;
49
+ vector<glm::vec2> uv;
50
+ vector<unsigned int > indices;
51
+
52
+ GLuint buffer[4 ];
53
+ GLuint vao;
54
+
55
+ // obtener los datos de cada mesh
56
+ void load (const aiMesh* mesh) {
57
+
58
+ vertex.reserve (mesh->mNumVertices );
59
+ uv.reserve (mesh->mNumVertices );
60
+ normal.reserve (mesh->mNumVertices );
61
+ indices.reserve (3 * mesh->mNumFaces );
62
+
63
+ for (unsigned int i = 0 ; i < mesh->mNumVertices ; i++) {
64
+
65
+ // Obtener la posicion de cada vertice
66
+ aiVector3D pos = mesh->mVertices [i];
67
+ vertex.push_back (glm::vec3 (pos.x , pos.y , pos.z ));
68
+
69
+ // Obtener las coordenadas de textura
70
+ if (mesh->HasTextureCoords (0 )) {
71
+ aiVector3D UVW = mesh->mTextureCoords [0 ][i];
72
+ uv.push_back (glm::vec2 (UVW.x , UVW.y ));
73
+ }
74
+
75
+ // Obtener los vectores normales
76
+ if (mesh->HasNormals ()) {
77
+ aiVector3D n = mesh->mNormals [i];
78
+ normal.push_back (glm::vec3 (n.x , n.y , n.z ));
79
+ }
80
+ }
81
+
82
+ // Obtener los indices
83
+ for (unsigned int i = 0 ; i < mesh->mNumFaces ; i++) {
84
+ indices.push_back (mesh->mFaces [i].mIndices [0 ]);
85
+ indices.push_back (mesh->mFaces [i].mIndices [1 ]);
86
+ indices.push_back (mesh->mFaces [i].mIndices [2 ]);
87
+ }
88
+ }
89
+
90
+ void create () {
91
+ // generar y activar el VAO
92
+ glGenVertexArrays (1 , &vao);
93
+ glBindVertexArray (vao);
94
+
95
+ // generar dos ids para los buffer
96
+ glGenBuffers (4 , buffer);
97
+
98
+ // buffer de vertices
99
+ glBindBuffer (GL_ARRAY_BUFFER, buffer[0 ]);
100
+ glBufferData (GL_ARRAY_BUFFER, vertex.size () * sizeof (glm::vec3), &vertex[0 ], GL_STATIC_DRAW);
101
+ glVertexAttribPointer (0 , 3 , GL_FLOAT, GL_FALSE, 0 , NULL );
102
+ glEnableVertexAttribArray (0 );
103
+
104
+ // buffer de textura
105
+ if (!uv.empty ()) {
106
+ glBindBuffer (GL_ARRAY_BUFFER, buffer[1 ]);
107
+ glBufferData (GL_ARRAY_BUFFER, uv.size () * sizeof (glm::vec2), &uv[0 ], GL_STATIC_DRAW);
108
+ glVertexAttribPointer (1 , 2 , GL_FLOAT, GL_FALSE, 0 , NULL );
109
+ glEnableVertexAttribArray (1 );
110
+ }
111
+
112
+ // buffer de normales
113
+ if (!normal.empty ()) {
114
+ glBindBuffer (GL_ARRAY_BUFFER, buffer[2 ]);
115
+ glBufferData (GL_ARRAY_BUFFER, normal.size () * sizeof (glm::vec3), &normal[0 ], GL_STATIC_DRAW);
116
+ glVertexAttribPointer (2 , 3 , GL_FLOAT, GL_FALSE, 0 , NULL );
117
+ glEnableVertexAttribArray (2 );
118
+ }
119
+
120
+ // buffer de indices
121
+ glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, buffer[3 ]);
122
+ glBufferData (GL_ELEMENT_ARRAY_BUFFER, indices.size () * sizeof (unsigned int ), &indices[0 ], GL_STATIC_DRAW);
123
+
124
+ // desactivar el VAO
125
+ glBindVertexArray (0 );
126
+ }
127
+
128
+ };
129
+
130
+ class Model {
131
+
132
+ private:
133
+ vector<shared_ptr<Mesh>> meshes;
134
+
135
+ // procesar recusivamente cada nodo de la escena
136
+ void processNode (const aiNode* node, const aiScene* scene)
137
+ {
138
+ // obtener los mesh de esta escena
139
+ for (unsigned int i = 0 ; i < node->mNumMeshes ; i++) {
140
+ shared_ptr<Mesh> mesh (new Mesh (scene->mMeshes [node->mMeshes [i]]));
141
+ meshes.push_back (mesh);
142
+ }
143
+
144
+ // procesar los hijos del nodo
145
+ for (unsigned int i = 0 ; i < node->mNumChildren ; i++)
146
+ this ->processNode (node->mChildren [i], scene);
147
+ }
148
+
149
+ public:
150
+ // cargar el archivo deseado
151
+ void init (const std::string& file_name) {
152
+ Assimp::Importer importer;
153
+ const aiScene* scene = importer.ReadFile (file_name, aiProcess_Triangulate);
154
+
155
+ if (scene && scene->mRootNode )
156
+ processNode (scene->mRootNode , scene);
157
+ else cout << importer.GetErrorString () << endl;
158
+ }
159
+
160
+ // dibujar la escena completa
161
+ void draw () {
162
+ for (auto m : meshes) m->draw ();
163
+ }
164
+ };
165
+
166
+ #endif
0 commit comments