1
+ #include " OpenGLWindow.hpp"
2
+ #include " OpenGLShader.hpp"
3
+ #include " OpenGLCamera.hpp"
4
+ #include " OpenGLModel.hpp"
5
+
6
+ #include < glm\gtc\matrix_inverse.hpp>
7
+ #include < glm\gtc\matrix_transform.hpp>
8
+ #include < glm\gtc\type_ptr.hpp>
9
+
10
+ #include < string>
11
+
12
+ class Tutorial_07 : public OpenGLWindow {
13
+
14
+ public:
15
+ Tutorial_07 () :
16
+ luz_position{ 0 , 4.5 , 0 },
17
+ luz_direction{ 0 , 4 , 3 },
18
+ spot_cutoff{ 0 .8f },
19
+ spot_exponent{ 0 .1f },
20
+ luz{ ' b' },
21
+ luz_vao{ 0 } { }
22
+
23
+ private:
24
+ void onstart () override {
25
+ glEnable (GL_DEPTH_TEST);
26
+ glClearColor (0 .25f , 0 .80f , 0 .75f , 1 .0f );
27
+
28
+ camera.setWindow (this ->window );
29
+
30
+ dir_shader.compile (" shaders/directional.vertex_shader" , " shaders/directional.fragment_shader" );
31
+ spot_shader.compile (" shaders/spot.vertex_shader" , " shaders/spot.fragment_shader" );
32
+ point_shader.compile (" shaders/point.vertex_shader" , " shaders/point.fragment_shader" );
33
+
34
+ model.init (" model/scene.assbin" );
35
+
36
+ createLightPosition ();
37
+ }
38
+
39
+ void onrender (double time) override {
40
+
41
+ glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
42
+
43
+ switch (luz)
44
+ {
45
+ case ' c' : luzDirectional (dir_shader, time ); break ;
46
+ case ' b' : luzPuntual (point_shader, time ); break ;
47
+ case ' a' : luzFocal (spot_shader, time ); break ;
48
+ }
49
+ }
50
+
51
+ void luzDirectional (OpenGLShader& shader, double time) {
52
+ shader.use ();
53
+
54
+ glm::mat4 Model;
55
+ glm::mat4 MV = camera.getViewMatrix () * Model;
56
+ glm::mat4 MVP = camera.getProjectionMatrix () * MV;
57
+ glm::mat3 N = glm::inverseTranspose (glm::mat3 (MV));
58
+
59
+ glUniformMatrix4fv (shader.getUniformLocation (" mvp_matrix" ), 1 , GL_FALSE, glm::value_ptr (MVP));
60
+ glUniformMatrix4fv (shader.getUniformLocation (" mv_matrix" ), 1 , GL_FALSE, glm::value_ptr (MV));
61
+ glUniformMatrix3fv (shader.getUniformLocation (" n_matrix" ), 1 , GL_FALSE, glm::value_ptr (N));
62
+
63
+ // direccion de la luz
64
+ glm::vec3 lightDir = glm::vec3 (MV * glm::vec4 (luz_direction, 0 ));
65
+ glUniform3fv (shader.getUniformLocation (" light_direction" ), 1 , glm::value_ptr (lightDir));
66
+
67
+ model.draw ();
68
+ shader.unUse ();
69
+ }
70
+
71
+ void luzFocal (OpenGLShader& shader, double time) {
72
+ shader.use ();
73
+ updateLight (shader, time );
74
+
75
+ // matrices
76
+ glm::mat4 Model;
77
+ glm::mat4 MV = camera.getViewMatrix () * Model;
78
+ glm::mat4 MVP = camera.getProjectionMatrix () * MV;
79
+ glm::mat3 N = glm::inverseTranspose (glm::mat3 (MV));
80
+
81
+ glUniformMatrix4fv (shader.getUniformLocation (" mvp_matrix" ), 1 , GL_FALSE, glm::value_ptr (MVP));
82
+ glUniformMatrix4fv (shader.getUniformLocation (" mv_matrix" ), 1 , GL_FALSE, glm::value_ptr (MV));
83
+ glUniformMatrix3fv (shader.getUniformLocation (" n_matrix" ), 1 , GL_FALSE, glm::value_ptr (N));
84
+
85
+ glm::vec3 spotPos (luz_position.x , 0 , luz_position.z );
86
+ glm::vec3 spotDir = glm::normalize (glm::vec3 (MV * glm::vec4 (spotPos - luz_position, 0 )));
87
+
88
+ glUniform3fv (shader.getUniformLocation (" spot_direction" ), 1 , glm::value_ptr (spotDir));
89
+ glUniform1f (shader.getUniformLocation (" spot_exponent" ), spot_exponent);
90
+ glUniform1f (shader.getUniformLocation (" spot_cutoff" ), spot_cutoff);
91
+
92
+ model.draw ();
93
+ shader.unUse ();
94
+ }
95
+
96
+ void luzPuntual (OpenGLShader& shader, double time) {
97
+ shader.use ();
98
+ updateLight (shader, time );
99
+
100
+ // matrices
101
+ glm::mat4 Model;
102
+ glm::mat4 MV = camera.getViewMatrix () * Model;
103
+ glm::mat4 MVP = camera.getProjectionMatrix () * MV;
104
+ glm::mat3 N = glm::inverseTranspose (glm::mat3 (MV));
105
+
106
+ glUniformMatrix4fv (shader.getUniformLocation (" mvp_matrix" ), 1 , GL_FALSE, glm::value_ptr (MVP));
107
+ glUniformMatrix4fv (shader.getUniformLocation (" mv_matrix" ), 1 , GL_FALSE, glm::value_ptr (MV));
108
+ glUniformMatrix3fv (shader.getUniformLocation (" n_matrix" ), 1 , GL_FALSE, glm::value_ptr (N));
109
+
110
+ model.draw ();
111
+ shader.unUse ();
112
+ }
113
+
114
+ void updateLight (OpenGLShader& shader, double time) {
115
+ updateLightPosition (shader.getUniformLocation (" light_pos" ), static_cast <float >(time ));
116
+ drawLightPosition (shader);
117
+ }
118
+
119
+ void updateLightPosition (GLuint pos_loc, float time) {
120
+ GLfloat radius = 2 .5f ;
121
+
122
+ luz_position.x = sin (time ) * radius;
123
+ luz_position.z = cos (time ) * radius;
124
+
125
+ glUniform3fv (pos_loc, 1 , glm::value_ptr (luz_position));
126
+ }
127
+
128
+ void drawLightPosition (OpenGLShader& shader) {
129
+ glm::mat4 Model;
130
+ Model = glm::translate (Model, luz_position);
131
+
132
+ glm::mat4 MV = camera.getViewMatrix () * Model;
133
+ glm::mat4 MVP = camera.getProjectionMatrix () * MV;
134
+ glm::mat3 N = glm::inverseTranspose (glm::mat3 (MV));
135
+
136
+ glUniformMatrix4fv (shader.getUniformLocation (" mvp_matrix" ), 1 , GL_FALSE, glm::value_ptr (MVP));
137
+ glUniformMatrix4fv (shader.getUniformLocation (" mv_matrix" ), 1 , GL_FALSE, glm::value_ptr (MV));
138
+ glUniformMatrix3fv (shader.getUniformLocation (" n_matrix" ), 1 , GL_FALSE, glm::value_ptr (N));
139
+
140
+ glBindVertexArray (luz_vao);
141
+ glDrawArrays (GL_LINES, 0 , 6 );
142
+ glBindVertexArray (0 );
143
+ }
144
+
145
+ void createLightPosition () {
146
+ glGenVertexArrays (1 , &luz_vao);
147
+ glBindVertexArray (luz_vao);
148
+
149
+ static const float vertex[] =
150
+ {
151
+ 1 .0f , 0 .0f , 0 .0f , 1 .0f , -1 .0f , 0 .0f , 0 .0f , 1 .0f ,
152
+ 0 .0f , 1 .0f , 0 .0f , 1 .0f , 0 .0f , -1 .0f , 0 .0f , 1 .0f ,
153
+ 0 .0f , 0 .0f , 1 .0f , 1 .0f , 0 .0f , 0 .0f , -1 .0f , 1 .0f ,
154
+ };
155
+
156
+ GLuint buffer;
157
+ glGenBuffers (1 , &buffer);
158
+ glBindBuffer (GL_ARRAY_BUFFER, buffer);
159
+ glBufferData (GL_ARRAY_BUFFER, sizeof (vertex), vertex, GL_STATIC_DRAW);
160
+ glVertexAttribPointer (0 , 4 , GL_FLOAT, GL_FALSE, 0 , NULL );
161
+ glEnableVertexAttribArray (0 );
162
+
163
+ glBindVertexArray (0 );
164
+ }
165
+
166
+ void onkey (int key, int scancode, int action, int mods) override {
167
+ if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
168
+ glfwSetWindowShouldClose (window, GL_TRUE);
169
+
170
+ if (key == GLFW_KEY_C)
171
+ spot_cutoff += 0 .01f ;
172
+ if (key == GLFW_KEY_V)
173
+ spot_cutoff -= 0 .01f ;
174
+ if (key == GLFW_KEY_F)
175
+ spot_exponent += 0 .1f ;
176
+ if (key == GLFW_KEY_G)
177
+ spot_exponent -= 0 .1f ;
178
+
179
+ if (key == GLFW_KEY_LEFT)
180
+ luz_direction.x += 0 .1f ;
181
+ if (key == GLFW_KEY_RIGHT)
182
+ luz_direction.x -= 0 .1f ;
183
+
184
+ if (key == GLFW_KEY_SPACE && action == GLFW_RELEASE)
185
+ luz = (luz == ' c' ) ? ' a' : luz + 1 ;
186
+ }
187
+
188
+ Model model;
189
+ OpenGLShader point_shader, spot_shader, dir_shader;
190
+ OpenGLCamera camera;
191
+
192
+ GLuint luz_vao;
193
+ glm::vec3 luz_position, luz_direction;
194
+
195
+ float spot_cutoff, spot_exponent;
196
+ char luz;
197
+ };
198
+
199
+ int main () {
200
+ Tutorial_07 win_app;
201
+
202
+ if (win_app.init (" OpenGL Moderno - Luces" , 1280 , 720 )) {
203
+
204
+ // ocultar el cursor y ubicarlo en el centro de la ventana
205
+ glfwSetInputMode (win_app.getGLFWwindow (), GLFW_CURSOR, GLFW_CURSOR_DISABLED);
206
+ glfwSetCursorPos (win_app.getGLFWwindow (), 1280 / 2 , 720 / 2 );
207
+
208
+ win_app.info ();
209
+ win_app.run ();
210
+ }
211
+
212
+ return 0 ;
213
+ }
0 commit comments