Skip to content

Commit 3e462a0

Browse files
committed
Tutorial 10 - Tipos de luces
Creación de luces direccionales, puntuales y luz de foco.
1 parent c643b39 commit 3e462a0

10 files changed

+481
-1
lines changed

CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,5 @@ add_subdirectory(Tutorial-05)
2626
add_subdirectory(Tutorial-06)
2727
add_subdirectory(Tutorial-07)
2828
add_subdirectory(Tutorial-08)
29-
add_subdirectory(Tutorial-09)
29+
add_subdirectory(Tutorial-09)
30+
add_subdirectory(Tutorial-10)

Tutorial-10/CMakeLists.txt

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
file(COPY directional.vertex_shader directional.fragment_shader DESTINATION shaders)
2+
file(COPY point.vertex_shader point.fragment_shader DESTINATION shaders)
3+
file(COPY spot.vertex_shader spot.fragment_shader DESTINATION shaders)
4+
file(COPY scene.assbin DESTINATION model)
5+
6+
set(ASSIMP_DIR $ENV{ASSIMP_DIR} CACHE PATH "Assimp Directory")
7+
8+
find_package(ASSIMP REQUIRED)
9+
10+
link_directories(${ASSIMP_LIBRARY_DIRS})
11+
include_directories(${ASSIMP_INCLUDE_DIRS})
12+
13+
add_executable( 10-Luces luces.cpp
14+
shaders/spot.vertex_shader
15+
shaders/spot.fragment_shader
16+
shaders/point.vertex_shader
17+
shaders/point.fragment_shader
18+
shaders/directional.vertex_shader
19+
shaders/directional.fragment_shader
20+
../common/openglwindow.hpp
21+
../common/openglshader.hpp
22+
../common/openglcamera.hpp
23+
../common/openglmodel.hpp )
24+
25+
target_link_libraries( 10-Luces ${GRAPHIC_LIBS} ${ASSIMP_LIBRARIES})
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#version 330 core
2+
3+
out vec4 color;
4+
5+
in vec3 N1;
6+
in vec3 V1;
7+
in vec3 P;
8+
9+
uniform mat4 mv_matrix;
10+
uniform vec3 light_direction;
11+
uniform vec3 light_color = vec3(0.75, 0.75, 0.75);
12+
uniform vec3 ambient_color = vec3(0.1);
13+
14+
uniform float ka = 0.10;
15+
uniform float kd = 0.55;
16+
uniform float ks = 0.80;
17+
uniform float n = 32;
18+
19+
const float k0 = 1.0; //constant attenuation
20+
const float k1 = 0.0; //linear attenuation
21+
const float k2 = 0.0; //quadratic attenuation
22+
23+
void main()
24+
{
25+
// Normalize the incoming N, L, and V vectors
26+
vec3 N = normalize(N1);
27+
vec3 L = normalize(light_direction);
28+
vec3 V = normalize(V1);
29+
30+
// Calculate R by reflecting -L around the plane defined by N
31+
vec3 R = reflect(-L, N);
32+
33+
// Calculate ambient, difusse, specular contribution
34+
vec3 ambient = ka * ambient_color;
35+
vec3 diffuse = kd * light_color * max(0.0, dot(N, L));
36+
vec3 specular = ks * light_color * pow(max(0.0, dot(R, V)), n);
37+
38+
// Send the color output to the fragment shader
39+
vec3 frag_color = ambient + diffuse + specular;
40+
color = vec4(frag_color, 1.0);
41+
}

Tutorial-10/directional.vertex_shader

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#version 330 core
2+
3+
layout (location = 0) in vec3 position;
4+
layout (location = 1) in vec2 texture;
5+
layout (location = 2) in vec3 normal;
6+
7+
uniform mat4 mvp_matrix;
8+
uniform mat4 mv_matrix;
9+
uniform mat3 n_matrix;
10+
11+
out vec3 N1;
12+
out vec3 V1;
13+
out vec3 P;
14+
15+
void main(void)
16+
{
17+
// Calculate view-space coordinate
18+
P = (mv_matrix * vec4(position, 1)).xyz;
19+
20+
// Calculate normal in view-space
21+
N1 = n_matrix * normal;
22+
23+
// Calculate view vector
24+
V1 = -P;
25+
26+
// Calculate the clip-space position of each vertex
27+
gl_Position = mvp_matrix * vec4(position, 1);
28+
}

Tutorial-10/luces.cpp

Lines changed: 213 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,213 @@
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+
}

Tutorial-10/point.fragment_shader

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
#version 330 core
2+
3+
out vec4 color;
4+
5+
in vec3 N1;
6+
in vec3 V1;
7+
in vec3 P;
8+
9+
uniform mat4 mv_matrix;
10+
uniform vec3 light_pos;
11+
uniform vec3 light_color = vec3(0.75, 0.75, 0.75);
12+
uniform vec3 ambient_color = vec3(0.1);
13+
14+
uniform float ka = 0.10;
15+
uniform float kd = 0.55;
16+
uniform float ks = 0.80;
17+
uniform float n = 32;
18+
19+
const float k0 = 1.0; //constant attenuation
20+
const float k1 = 0.0; //linear attenuation
21+
const float k2 = 0.0; //quadratic attenuation
22+
23+
void main()
24+
{
25+
// point light
26+
vec3 light_position = (mv_matrix * vec4(light_pos, 1)).xyz;
27+
vec3 L1 = light_position - P;
28+
float d = length(L1);
29+
30+
// Normalize the incoming N, L, and V vectors
31+
vec3 N = normalize(N1);
32+
vec3 L = normalize(L1);
33+
vec3 V = normalize(V1);
34+
35+
// Calculate R by reflecting -L around the plane defined by N
36+
vec3 R = reflect(-L, N);
37+
38+
// Calculate ambient, difusse, specular contribution
39+
vec3 ambient = ka * ambient_color;
40+
vec3 diffuse = kd * light_color * max(0.0, dot(N, L));
41+
vec3 specular = ks * light_color * pow(max(0.0, dot(R, V)), n);
42+
43+
float attenuationAmount = 1.0 / (k0 + (k1*d) + (k2*d*d));
44+
45+
diffuse *= attenuationAmount;
46+
specular *= attenuationAmount;
47+
ambient *= attenuationAmount;
48+
49+
// Send the color output to the fragment shader
50+
vec3 frag_color = ambient + diffuse + specular;
51+
color = vec4(frag_color, 1.0);
52+
}

0 commit comments

Comments
 (0)