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
+ #include < glm\gtx\euler_angles.hpp>
8
+ #include < glm\gtx\matrix_cross_product.hpp>
9
+
10
+ #include < string>
11
+ #include < vector>
12
+ #include < memory>
13
+
14
+ #include < assimp/Importer.hpp> // C++ importer interface
15
+ #include < assimp/scene.h> // Output data structure
16
+ #include < assimp/postprocess.h> // Post processing flags
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
+ class Tutorial_09 : public OpenGLWindow {
167
+
168
+ public:
169
+ Tutorial_09 () {
170
+ mv_matrix = 0 ;
171
+ view_matrix = 0 ;
172
+ proj_matrix = 0 ;
173
+ }
174
+
175
+ private:
176
+ void onstart () override {
177
+ glEnable (GL_DEPTH_TEST);
178
+ glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
179
+
180
+ glClearColor (0 .25f , 0 .80f , 0 .75f , 1 .0f );
181
+
182
+ GLuint program = shader_simple.compile (" shaders/phong.vertex_shader" , " shaders/phong.fragment_shader" );
183
+
184
+ mv_matrix = glGetUniformLocation (program, " mv_matrix" );
185
+ view_matrix = glGetUniformLocation (program, " view_matrix" );
186
+ proj_matrix = glGetUniformLocation (program, " proj_matrix" );
187
+
188
+ model.init (" model/grid.assbin" );
189
+ }
190
+
191
+ void onrender (double time) override {
192
+
193
+ glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
194
+
195
+ // Usar el shader
196
+ shader_simple.use ();
197
+
198
+ // obtener los parametros de visualizacion
199
+ glm::mat4 R = glm::yawPitchRoll (glm::radians (yaw), glm::radians (pitch), 0 .0f );
200
+ cameraFront = glm::vec3 (R * glm::vec4 (0 , 0 , -1 , 0 ));
201
+ cameraUp = glm::vec3 (R * glm::vec4 (0 , 1 , 0 , 0 ));
202
+
203
+ // craer la matriz de vista
204
+ glm::mat4 View = glm::lookAt (cameraPos, cameraPos + cameraFront, cameraUp);
205
+
206
+ // Matriz de modelo, se aplica una rotacion sobre el eje Y
207
+ glm::mat4 Model;
208
+ Model = glm::scale (Model, glm::vec3 (0 .5f ));
209
+
210
+ // Matriz de proyeccion y visualizacion
211
+ glm::mat4 Projection = glm::perspective (45 .0f , aspect_ratio, 0 .1f , 100 .0f );
212
+
213
+ // Establecer las matrices
214
+ glUniformMatrix4fv (mv_matrix, 1 , GL_FALSE, glm::value_ptr (View * Model));
215
+ glUniformMatrix4fv (view_matrix, 1 , GL_FALSE, glm::value_ptr (View));
216
+ glUniformMatrix4fv (proj_matrix, 1 , GL_FALSE, glm::value_ptr (Projection));
217
+
218
+ // dibujar el modelo
219
+ model.draw ();
220
+
221
+ // desactivar el uso del shader
222
+ shader_simple.unUse ();
223
+
224
+ // actualizar el desplazamiento y ratacion de la camara
225
+ chechKeys ();
226
+ }
227
+
228
+ void chechKeys () {
229
+ if (isKeyPress (GLFW_KEY_W))
230
+ cameraPos += cameraSpeed * cameraFront;
231
+ if (isKeyPress (GLFW_KEY_S))
232
+ cameraPos -= cameraSpeed * cameraFront;
233
+ if (isKeyPress (GLFW_KEY_A))
234
+ cameraPos -= glm::normalize (glm::cross (cameraFront, cameraUp)) * cameraSpeed;
235
+ if (isKeyPress (GLFW_KEY_D))
236
+ cameraPos += glm::normalize (glm::cross (cameraFront, cameraUp)) * cameraSpeed;
237
+ }
238
+
239
+ inline bool isKeyPress (int key) {
240
+ return (glfwGetKey (window, key) == GLFW_PRESS);
241
+ }
242
+
243
+ void onkey (int key, int scancode, int action, int mods) override {
244
+
245
+ if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
246
+ glfwSetWindowShouldClose (window, GL_TRUE);
247
+
248
+ // if (key == GLFW_KEY_W)
249
+ // cameraPos += cameraSpeed * cameraFront;
250
+ // if (key == GLFW_KEY_S)
251
+ // cameraPos -= cameraSpeed * cameraFront;
252
+ // if (key == GLFW_KEY_A)
253
+ // cameraPos -= glm::normalize(glm::cross(cameraFront, cameraUp)) * cameraSpeed;
254
+ // if (key == GLFW_KEY_D)
255
+ // cameraPos += glm::normalize(glm::cross(cameraFront, cameraUp)) * cameraSpeed;
256
+
257
+ // if (key == GLFW_KEY_E)
258
+ // yaw += cameraSpeed / 2.0f;
259
+ // if (key == GLFW_KEY_R)
260
+ // yaw -= cameraSpeed / 2.0f;
261
+
262
+ // if (key == GLFW_KEY_Q)
263
+ // pitch += cameraSpeed / 2.0f;
264
+ // if (key == GLFW_KEY_Z)
265
+ // pitch -= cameraSpeed / 2.0f;
266
+ }
267
+
268
+ void onmouse (double xpos, double ypos) override {
269
+
270
+ int width, height;
271
+ glfwGetWindowSize (window, &width, &height);
272
+ glfwSetCursorPos (window, width / 2.0 , height / 2.0 );
273
+
274
+ GLfloat xoffset = ((width / 2.0 ) - xpos) * mouseSensitive;
275
+ GLfloat yoffset = ((height / 2.0 ) - ypos) * mouseSensitive;
276
+
277
+ yaw += xoffset;
278
+ pitch += yoffset;
279
+ }
280
+
281
+ Model model;
282
+ OpenGLShader shader_simple;
283
+ GLuint mv_matrix, view_matrix, proj_matrix;
284
+
285
+ // variables utilizadas para la camara
286
+
287
+ glm::vec3 cameraPos = glm::vec3(0 .0f , 0 .5f , 3 .0f ); // posicion inicial de la camara
288
+ glm::vec3 cameraFront = glm::vec3(0 .0f , 0 .0f , -1 .0f );
289
+ glm::vec3 cameraUp = glm::vec3(0 .0f , 1 .0f , 0 .0f );
290
+
291
+ float yaw = 0 , pitch = 0 ;
292
+
293
+ GLfloat cameraSpeed = 0 .05f ; // velocidad de movimiento
294
+ GLfloat mouseSensitive = 0 .15f ; // velocidad de rotacion
295
+ };
296
+
297
+ int main () {
298
+ Tutorial_09 win_app;
299
+
300
+ if (win_app.init (" OpenGL Moderno - Camara" , 1280 , 720 )) {
301
+
302
+ // ocultar el cursor y ubicarlo en el centro de la ventana
303
+ glfwSetInputMode (win_app.getGLFWwindow (), GLFW_CURSOR, GLFW_CURSOR_DISABLED);
304
+ glfwSetCursorPos (win_app.getGLFWwindow (), 1280 / 2 , 720 / 2 );
305
+
306
+ win_app.info ();
307
+ win_app.run ();
308
+ }
309
+
310
+ return 0 ;
311
+ }
0 commit comments