1
+ #include " OpenGLWindow.hpp"
2
+ #include " OpenGLShader.hpp"
3
+
4
+ #include < glm\gtc\matrix_inverse.hpp>
5
+ #include < glm\gtc\matrix_transform.hpp>
6
+ #include < glm\gtc\type_ptr.hpp>
7
+
8
+ #include < string>
9
+ #include < vector>
10
+ #include < memory>
11
+
12
+ #include < assimp/Importer.hpp> // C++ importer interface
13
+ #include < assimp/scene.h> // Output data structure
14
+ #include < assimp/postprocess.h> // Post processing flags
15
+
16
+ using namespace std ;
17
+
18
+ class Mesh {
19
+
20
+ public:
21
+ Mesh (const aiMesh* mesh) {
22
+ load (mesh);
23
+ create ();
24
+ }
25
+
26
+ ~Mesh () {
27
+ glDeleteBuffers (4 , buffer);
28
+ glDeleteVertexArrays (1 , &vao);
29
+ }
30
+
31
+ // dibujar el mesh
32
+ void draw () {
33
+ glBindVertexArray (vao);
34
+ glDrawElements (GL_TRIANGLES, indices.size (), GL_UNSIGNED_INT, NULL );
35
+ glBindVertexArray (0 );
36
+ };
37
+
38
+ // inicializar el mesh
39
+ void init (const aiMesh* mesh) {
40
+ load (mesh);
41
+ create ();
42
+ };
43
+
44
+ private:
45
+ vector<glm::vec3> vertex;
46
+ vector<glm::vec3> normal;
47
+ vector<glm::vec2> uv;
48
+ vector<unsigned int > indices;
49
+
50
+ GLuint buffer[4 ];
51
+ GLuint vao;
52
+
53
+ // obtener los datos de cada mesh
54
+ void load (const aiMesh* mesh) {
55
+
56
+ vertex.reserve (mesh->mNumVertices );
57
+ uv.reserve (mesh->mNumVertices );
58
+ normal.reserve (mesh->mNumVertices );
59
+ indices.reserve (3 * mesh->mNumFaces );
60
+
61
+ for (unsigned int i = 0 ; i < mesh->mNumVertices ; i++) {
62
+ // Obtener la posicion de cada vertice
63
+ aiVector3D pos = mesh->mVertices [i];
64
+ vertex.push_back (glm::vec3 (pos.x , pos.y , pos.z ));
65
+
66
+ // Obtener las coordenadas de textura
67
+ if (mesh->HasTextureCoords (0 )) {
68
+ aiVector3D UVW = mesh->mTextureCoords [0 ][i];
69
+ uv.push_back (glm::vec2 (UVW.x , UVW.y ));
70
+ }
71
+
72
+ // Obtener los vectores normales
73
+ if (mesh->HasNormals ()) {
74
+ aiVector3D n = mesh->mNormals [i];
75
+ normal.push_back (glm::vec3 (n.x , n.y , n.z ));
76
+ }
77
+ }
78
+
79
+ // Obtener los indices
80
+ for (unsigned int i = 0 ; i < mesh->mNumFaces ; i++) {
81
+ indices.push_back (mesh->mFaces [i].mIndices [0 ]);
82
+ indices.push_back (mesh->mFaces [i].mIndices [1 ]);
83
+ indices.push_back (mesh->mFaces [i].mIndices [2 ]);
84
+ }
85
+ }
86
+
87
+ void create () {
88
+ // generar y activar el VAO
89
+ glGenVertexArrays (1 , &vao);
90
+ glBindVertexArray (vao);
91
+
92
+ // generar dos ids para los buffer
93
+ glGenBuffers (4 , buffer);
94
+
95
+ // buffer de vertices
96
+ glBindBuffer (GL_ARRAY_BUFFER, buffer[0 ]);
97
+ glBufferData (GL_ARRAY_BUFFER, vertex.size () * sizeof (glm::vec3), &vertex[0 ], GL_STATIC_DRAW);
98
+ glVertexAttribPointer (0 , 3 , GL_FLOAT, GL_FALSE, 0 , NULL );
99
+ glEnableVertexAttribArray (0 );
100
+
101
+ // buffer de textura
102
+ if (!uv.empty ()) {
103
+ glBindBuffer (GL_ARRAY_BUFFER, buffer[1 ]);
104
+ glBufferData (GL_ARRAY_BUFFER, uv.size () * sizeof (glm::vec2), &uv[0 ], GL_STATIC_DRAW);
105
+ glVertexAttribPointer (1 , 2 , GL_FLOAT, GL_FALSE, 0 , NULL );
106
+ glEnableVertexAttribArray (1 );
107
+ }
108
+
109
+ // buffer de normales
110
+ if (!normal.empty ()) {
111
+ glBindBuffer (GL_ARRAY_BUFFER, buffer[2 ]);
112
+ glBufferData (GL_ARRAY_BUFFER, normal.size () * sizeof (glm::vec3), &normal[0 ], GL_STATIC_DRAW);
113
+ glVertexAttribPointer (2 , 3 , GL_FLOAT, GL_FALSE, 0 , NULL );
114
+ glEnableVertexAttribArray (2 );
115
+ }
116
+
117
+ // buffer de indices
118
+ glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, buffer[3 ]);
119
+ glBufferData (GL_ELEMENT_ARRAY_BUFFER, indices.size () * sizeof (unsigned int ), &indices[0 ], GL_STATIC_DRAW);
120
+
121
+ // desactivar el VAO
122
+ glBindVertexArray (0 );
123
+ }
124
+
125
+ };
126
+
127
+ class Model {
128
+
129
+ private:
130
+ vector<shared_ptr<Mesh>> meshes;
131
+
132
+ // procesar recusivamente cada nodo de la escena
133
+ void processNode (const aiNode* node, const aiScene* scene)
134
+ {
135
+ // obtener los mesh de esta escena
136
+ for (unsigned int i = 0 ; i < node->mNumMeshes ; i++) {
137
+ shared_ptr<Mesh> mesh (new Mesh (scene->mMeshes [node->mMeshes [i]]));
138
+ meshes.push_back (mesh);
139
+ }
140
+
141
+ // procesar los hijos del nodo
142
+ for (unsigned int i = 0 ; i < node->mNumChildren ; i++)
143
+ this ->processNode (node->mChildren [i], scene);
144
+ }
145
+
146
+ public:
147
+ // cargar el archivo deseado
148
+ void init (const std::string& file_name) {
149
+ Assimp::Importer importer;
150
+ const aiScene* scene = importer.ReadFile (file_name, aiProcess_Triangulate);
151
+
152
+ if (scene && scene->mRootNode )
153
+ processNode (scene->mRootNode , scene);
154
+ else cout << importer.GetErrorString () << endl;
155
+ }
156
+
157
+ // dibujar la escena completa
158
+ void draw () {
159
+ for (auto m : meshes) m->draw ();
160
+ }
161
+ };
162
+
163
+ class Tutorial_08 : public OpenGLWindow {
164
+
165
+ public:
166
+ Tutorial_08 () {
167
+ mv_matrix = 0 ;
168
+ view_matrix = 0 ;
169
+ proj_matrix = 0 ;
170
+ }
171
+
172
+ private:
173
+ void onstart () override {
174
+
175
+ glEnable (GL_DEPTH_TEST);
176
+ glClearColor (0 .25f , 0 .80f , 0 .75f , 1 .0f );
177
+
178
+ GLuint program = shader_simple.compile (" shaders/phong.vertex_shader" , " shaders/phong.fragment_shader" );
179
+
180
+ mv_matrix = glGetUniformLocation (program, " mv_matrix" );
181
+ view_matrix = glGetUniformLocation (program, " view_matrix" );
182
+ proj_matrix = glGetUniformLocation (program, " proj_matrix" );
183
+
184
+ model.init (" model/cessna.assbin" );
185
+ }
186
+
187
+ void onrender (double time) override {
188
+
189
+ glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
190
+
191
+ // Usar el shader
192
+ shader_simple.use ();
193
+
194
+ // Matriz de modelo, se aplica una rotacion sobre el eje Y
195
+ glm::mat4 Model;
196
+ Model = glm::rotate (Model, (float )time, glm::vec3 (0 .0f , 1 .0f , 0 .0f ));
197
+ Model = glm::scale (Model, glm::vec3 (0 .5f ));
198
+
199
+ // Matriz de proyeccion y visualizacion
200
+ glm::mat4 Projection = glm::perspective (45 .0f , aspect_ratio, 0 .1f , 100 .0f );
201
+ glm::mat4 View = glm::lookAt (glm::vec3 (0 , 5 , 20 ), glm::vec3 (0 , 0 , 0 ), glm::vec3 (0 , 1 , 0 ));
202
+
203
+ // Establecer las matrices
204
+ glUniformMatrix4fv (mv_matrix, 1 , GL_FALSE, glm::value_ptr (View * Model));
205
+ glUniformMatrix4fv (view_matrix, 1 , GL_FALSE, glm::value_ptr (View));
206
+ glUniformMatrix4fv (proj_matrix, 1 , GL_FALSE, glm::value_ptr (Projection));
207
+
208
+ // dibujar el modelo
209
+ model.draw ();
210
+
211
+ // desactivar el uso del shader
212
+ shader_simple.unUse ();
213
+ }
214
+
215
+ void onstop () override {
216
+
217
+ }
218
+
219
+ Model model;
220
+ OpenGLShader shader_simple;
221
+ GLuint mv_matrix, view_matrix, proj_matrix;
222
+ };
223
+
224
+ int main () {
225
+ Tutorial_08 win_app;
226
+ if (win_app.init (" OpenGL Moderno - ASSIMP" , 1280 , 720 )) {
227
+ win_app.info ();
228
+ win_app.run ();
229
+ }
230
+ return 0 ;
231
+ }
0 commit comments