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_OpenGL_Moderno : public OpenGLWindow {
13
+
14
+ public:
15
+ Tutorial_OpenGL_Moderno () { }
16
+
17
+ private:
18
+ void onstart () override {
19
+ glEnable (GL_DEPTH_TEST);
20
+
21
+ glClearDepth (1 .0f );
22
+ glClearColor (0 .0f , 0 .5f , 0 .5f , 1 .0f );
23
+
24
+ camera.setWindow (this ->window );
25
+
26
+ light_shadow_shader.compile (" shaders/shadows.vs.glsl" , " shaders/shadows.fs.glsl" );
27
+ shadow_shader.compile (" shaders/shadow-map.vs.glsl" , " shaders/shadow-map.fs.glsl" );
28
+ debug_shader.compile (" shaders/shadow-map-debug.vs.glsl" , " shaders/shadow-map-debug.fs.glsl" );
29
+
30
+ model.init (" model/test.assbin" );
31
+
32
+ createShadowMap ();
33
+
34
+ // ocultar el cursor y ubicarlo en el centro de la ventana
35
+ glfwSetInputMode (this ->window , GLFW_CURSOR, GLFW_CURSOR_DISABLED);
36
+ glfwSetCursorPos (this ->window , 1280 / 2 , 720 / 2 );
37
+ }
38
+
39
+ void createShadowMap () {
40
+ glGenTextures (1 , &shadowMapTexID);
41
+ glBindTexture (GL_TEXTURE_2D, shadowMapTexID);
42
+
43
+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
44
+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
45
+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
46
+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
47
+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
48
+
49
+ static GLfloat border[4 ] = { 1 , 0 , 0 , 0 };
50
+ glTexParameterfv (GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, border);
51
+
52
+ glTexStorage2D (GL_TEXTURE_2D, 1 , GL_DEPTH_COMPONENT32, SHADOW_MAP_SIZE, SHADOW_MAP_SIZE);
53
+ glGenFramebuffers (1 , &fboID);
54
+ glBindFramebuffer (GL_FRAMEBUFFER, fboID);
55
+
56
+ glFramebufferTexture (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, shadowMapTexID, 0 );
57
+
58
+ if (glCheckFramebufferStatus (GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
59
+ cout << " Error al inicializar FBO." << endl;
60
+ }
61
+
62
+ glDrawBuffer (GL_NONE);
63
+ glBindFramebuffer (GL_FRAMEBUFFER, 0 );
64
+ }
65
+
66
+ void onrender (double time) override {
67
+
68
+ if (showDepthMap) glDisable (GL_CULL_FACE);
69
+ else glEnable (GL_CULL_FACE);
70
+
71
+ shadow_shader.use ();
72
+
73
+ float X = sin (static_cast <float >(time )) * 10 .0f ;
74
+ float Z = cos (static_cast <float >(time )) * 10 .0f ;
75
+
76
+ glm::vec3 lightPosOS (X, 8 .0f , Z);
77
+
78
+ glm::mat4 P_L = glm::frustum (-1 .0f , 1 .0f , -1 .0f , 1 .0f , 1 .0f , 100 .0f );
79
+ glm::mat4 MV_L = glm::lookAt (lightPosOS, glm::vec3 (0 ), glm::vec3 (0 , 1 , 0 ));
80
+
81
+ glUniformMatrix4fv (shadow_shader.getUniformLocation (" MVP" ), 1 , GL_FALSE, glm::value_ptr (P_L * MV_L));
82
+
83
+ glBindFramebuffer (GL_FRAMEBUFFER, fboID);
84
+ glViewport (0 , 0 , SHADOW_MAP_SIZE, SHADOW_MAP_SIZE);
85
+ glClear (GL_DEPTH_BUFFER_BIT);
86
+ glCullFace (GL_FRONT);
87
+ glEnable (GL_POLYGON_OFFSET_FILL);
88
+ glPolygonOffset (1 .0f , 1 .0f );
89
+
90
+ model.draw ();
91
+
92
+ glDisable (GL_POLYGON_OFFSET_FILL);
93
+ glCullFace (GL_BACK);
94
+ glBindFramebuffer (GL_FRAMEBUFFER, 0 );
95
+
96
+ shadow_shader.unUse ();
97
+
98
+
99
+ // Restablecer viewport para dibujar de modo normal
100
+ glViewport (0 , 0 , 1280 , 720 );
101
+ glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
102
+
103
+ // Visualizar mapa de profundidad
104
+ if (showDepthMap) {
105
+ debug_shader.use ();
106
+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);
107
+ RenderQuad ();
108
+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
109
+ debug_shader.unUse ();
110
+ }
111
+
112
+ light_shadow_shader.use ();
113
+
114
+ glm::mat4 B (0.5 , 0.0 , 0.0 , 0.0 ,
115
+ 0.0 , 0.5 , 0.0 , 0.0 ,
116
+ 0.0 , 0.0 , 0.5 , 0.0 ,
117
+ 0.5 , 0.5 , 0.5 , 1.0 );
118
+
119
+ glm::mat4 S = B * P_L * MV_L;
120
+
121
+ glm::mat4 M = glm::mat4 (1 );
122
+ glm::mat4 MV = camera.getViewMatrix () * M;
123
+ glm::mat4 MVP = camera.getProjectionMatrix () * MV;
124
+ glm::mat3 N = glm::inverseTranspose (glm::mat3 (MV));
125
+
126
+ glUniformMatrix4fv (light_shadow_shader.getUniformLocation (" MVP" ), 1 , GL_FALSE, glm::value_ptr (MVP));
127
+ glUniformMatrix4fv (light_shadow_shader.getUniformLocation (" MV" ), 1 , GL_FALSE, glm::value_ptr (MV));
128
+ glUniformMatrix4fv (light_shadow_shader.getUniformLocation (" M" ), 1 , GL_FALSE, glm::value_ptr (M));
129
+ glUniformMatrix4fv (light_shadow_shader.getUniformLocation (" S" ), 1 , GL_FALSE, glm::value_ptr (S));
130
+ glUniformMatrix3fv (light_shadow_shader.getUniformLocation (" N" ), 1 , GL_FALSE, glm::value_ptr (N));
131
+
132
+ glm::vec3 lightPosES = glm::vec3 (MV * glm::vec4 (lightPosOS, 0 ));
133
+
134
+ glUniform3fv (light_shadow_shader.getUniformLocation (" light_position" ), 1 , glm::value_ptr (lightPosES));
135
+ glUniform3fv (light_shadow_shader.getUniformLocation (" diffuse_color" ), 1 , glm::value_ptr (glm::vec3 (0 .75f )));
136
+
137
+ model.draw ();
138
+
139
+ light_shadow_shader.unUse ();
140
+
141
+ }
142
+
143
+ GLuint quadVAO = 0 ;
144
+ GLuint quadVBO;
145
+ void RenderQuad ()
146
+ {
147
+ if (quadVAO == 0 )
148
+ {
149
+ GLfloat quadVertices[] = {
150
+ // Positions // Texture Coords
151
+ -1 .0f , 1 .0f , 0 .0f , 0 .0f , 1 .0f ,
152
+ -1 .0f , -1 .0f , 0 .0f , 0 .0f , 0 .0f ,
153
+ 1 .0f , 1 .0f , 0 .0f , 1 .0f , 1 .0f ,
154
+ 1 .0f , -1 .0f , 0 .0f , 1 .0f , 0 .0f ,
155
+ };
156
+
157
+ glGenVertexArrays (1 , &quadVAO);
158
+ glGenBuffers (1 , &quadVBO);
159
+ glBindVertexArray (quadVAO);
160
+ glBindBuffer (GL_ARRAY_BUFFER, quadVBO);
161
+ glBufferData (GL_ARRAY_BUFFER, sizeof (quadVertices), &quadVertices, GL_STATIC_DRAW);
162
+ glEnableVertexAttribArray (0 );
163
+ glVertexAttribPointer (0 , 3 , GL_FLOAT, GL_FALSE, 5 * sizeof (GLfloat), (GLvoid*)0 );
164
+ glEnableVertexAttribArray (1 );
165
+ glVertexAttribPointer (1 , 2 , GL_FLOAT, GL_FALSE, 5 * sizeof (GLfloat), (GLvoid*)(3 * sizeof (GLfloat)));
166
+ }
167
+
168
+ glBindVertexArray (quadVAO);
169
+ glDrawArrays (GL_TRIANGLE_STRIP, 0 , 4 );
170
+ glBindVertexArray (0 );
171
+ }
172
+
173
+ void onkey (int key, int scancode, int action, int mods) override {
174
+ if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
175
+ glfwSetWindowShouldClose (window, GL_TRUE);
176
+
177
+ if (key == GLFW_KEY_SPACE && action == GLFW_PRESS)
178
+ showDepthMap = !showDepthMap;
179
+ }
180
+
181
+ Model model;
182
+ OpenGLShader light_shadow_shader, shadow_shader, debug_shader;
183
+ OpenGLCamera camera;
184
+
185
+ const GLsizei SHADOW_MAP_SIZE = 1024 * 2 ;
186
+
187
+ GLuint shadowMapTexID, fboID;
188
+ GLuint vao, index_buffer;
189
+ GLuint buffer[2 ];
190
+
191
+ bool showDepthMap = false ;
192
+ };
193
+
194
+ int main () {
195
+ Tutorial_OpenGL_Moderno win_app;
196
+
197
+ if (win_app.init (" OpenGL Moderno - Shadow Maps" , 1280 , 720 )) {
198
+ win_app.info ();
199
+
200
+ cout << " TOTURIALES OPENGL MODERNO - SHADOW MAP" << endl << endl;
201
+ cout << " Presione la tecla [SPACE] para (mostrar/ocultar) el depth map." << endl;
202
+ cout << " Usar la tecla [Esc] para salir." << endl << endl;
203
+
204
+ win_app.run ();
205
+ }
206
+
207
+ return 0 ;
208
+ }
0 commit comments