From 9cbfa55c8952ab0dd9891a819c9d89c4f7a5b358 Mon Sep 17 00:00:00 2001 From: Abdelrahman Date: Tue, 3 Dec 2024 20:08:40 +0000 Subject: [PATCH] Move light around the scene --- shaders/frag.glsl | 19 +++++++- shaders/vert.glsl | 9 +++- src/main.cc | 112 ++++++++++++++++++++++++++++------------------ 3 files changed, 94 insertions(+), 46 deletions(-) diff --git a/shaders/frag.glsl b/shaders/frag.glsl index cc48556..b9a6c9e 100644 --- a/shaders/frag.glsl +++ b/shaders/frag.glsl @@ -1,10 +1,27 @@ #version 330 core +in vec3 vert_normal; +in vec3 frag_position; + out vec4 color; +uniform vec3 camera_position; uniform vec3 object_color; uniform vec3 light_color; +uniform vec3 light_position; void main() { - color = vec4(object_color * light_color, 1.0); + float ambient_strength = 0.15; + float specular_strength = 0.5; + vec3 normal = normalize(vert_normal); + vec3 light_direction = normalize(light_position - frag_position); + vec3 view_direction = normalize(camera_position - frag_position); + vec3 reflect_direction = reflect(-light_direction, normal); + float diff = max(dot(normal, light_direction), 0.0); + float spec = pow(max(dot(reflect_direction, view_direction), 0.0), 32); + vec3 ambient = light_color * ambient_strength; + vec3 diffuse = diff * light_color; + vec3 specular = specular_strength * spec * light_color; + + color = vec4(object_color * (ambient + diffuse + specular), 1.0); }; diff --git a/shaders/vert.glsl b/shaders/vert.glsl index 4560048..a3efab0 100644 --- a/shaders/vert.glsl +++ b/shaders/vert.glsl @@ -1,11 +1,18 @@ #version 330 core layout(location=0) in vec3 position; +layout(location=1) in vec3 normal; +out vec3 vert_normal; +out vec3 frag_position; + +uniform mat3 normal_mat; uniform mat4 model; uniform mat4 view; uniform mat4 projection; void main() { - gl_Position = projection * view * model * vec4(position, 1.0); + vert_normal = normal_mat * normal; + frag_position = vec3(model * vec4(position, 1.0)); + gl_Position = projection * view * model * vec4(position, 1.0); }; diff --git a/src/main.cc b/src/main.cc index 389adf2..0d29f13 100644 --- a/src/main.cc +++ b/src/main.cc @@ -47,6 +47,7 @@ class Shader { void activate(); void set_float(const char *name, float value); void set_vec3(const char *name, glm::vec3 vector); + void set_mat3(const char *name, glm::mat3 matrix); void set_mat4(const char *name, glm::mat4 matrix); GLuint program; private: @@ -90,38 +91,46 @@ int main() { glEnable(GL_DEPTH_TEST); std::vector vertices = { - 0.5f, -0.5f, 0.5f, // position - -0.5f, 0.5f, 0.5f, // position - 0.5f, 0.5f, 0.5f, // position - 0.5f, -0.5f, 0.5f, // position - -0.5f, -0.5f, 0.5f, // position - 0.5f, -0.5f, -0.5f, // position - -0.5f, 0.5f, -0.5f, // position - -0.5f, 0.5f, -0.5f, // position - -0.5f, 0.5f, 0.5f, // position - 0.5f, 0.5f, -0.5f, // position - 0.5f, -0.5f, -0.5f, // position - -0.5f, 0.5f, 0.5f, // position - 0.5f, 0.5f, 0.5f, // position - -0.5f, -0.5f, -0.5f, // position - -0.5f, -0.5f, -0.5f, // position - 0.5f, -0.5f, -0.5f, // position - -0.5f, 0.5f, -0.5f, // position + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, // position, normal + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, // position, normal + 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, // position, normal + 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, // position, normal + -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, // position, normal + 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, // position, normal + -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, // position, normal + -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, // position, normal + -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, // position, normal + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, // position, normal + 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, // position, normal + 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, // position, normal + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, // position, normal + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, // position, normal + -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, // position, normal + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, // position, normal + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, // position, normal + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, // position, normal + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, // position, normal + 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, // position, normal + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, // position, normal + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, // position, normal + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, // position, normal + -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, // position, normal + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, // position, normal }; std::vector indices = { - 14, 5, 9, - 9, 7, 14, - 4, 3, 12, - 12, 8, 4, - 1, 6, 13, - 13, 4, 1, - 2, 9, 15, - 15, 0, 2, - 13, 10, 3, - 3, 4, 13, - 7, 9, 2, - 2, 11, 16, + 20, 11, 0, + 0, 6, 20, + 7, 1, 3, + 3, 16, 7, + 24, 14, 21, + 21, 4, 24, + 2, 12, 10, + 10, 22, 2, + 8, 9, 19, + 19, 18, 8, + 13, 5, 17, + 17, 23, 15 }; GLuint vao = 0; @@ -138,8 +147,10 @@ int main() { glBindBuffer(GL_ARRAY_BUFFER, vbo); glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(GLfloat), vertices.data(), GL_STATIC_DRAW); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (void *)0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (void *)0); glEnableVertexAttribArray(0); + glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (void *)(3 * sizeof(GLfloat))); + glEnableVertexAttribArray(1); GLuint light_vao = 0; glGenVertexArrays(1, &light_vao); @@ -147,7 +158,7 @@ int main() { glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo); glBindBuffer(GL_ARRAY_BUFFER, vbo); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (void *)0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (void *)0); glEnableVertexAttribArray(0); glBindVertexArray(0); @@ -161,31 +172,36 @@ int main() { main_shader.set_vec3("light_color", glm::vec3(1.0f, 1.0f, 1.0f)); const float camera_speed = 25.0f; - glm::vec3 camera_position = glm::vec3(0.0f, 0.0f, 4.0f); + glm::vec3 camera_position = glm::vec3(-2.0f, 0.0f, 6.0f); glm::vec3 camera_forward = glm::vec3(0.0f); glm::vec3 world_up = glm::vec3(0.0f, 1.0f, 0.0f); + glm::vec3 light_position = glm::vec3(1.0f, 0.5f, 0.0f); - float yaw = -90.0f; + float yaw = -70.0f; float pitch = 0.0f; glm::mat4 model = glm::mat4(1.0f); glm::mat4 view = glm::mat4(1.0f); glm::mat4 projection = glm::perspective(glm::radians(45.0f), (float)WINDOW_WIDTH / (float)WINDOW_HEIGHT, 0.1f, 100.0f); + glm::mat3 normal_mat = glm::mat3(1.0f); main_shader.set_mat4("projection", projection); light_shader.set_mat4("projection", projection); - const float sensitivity = 0.1f; - int last_mouse_x = WINDOW_HALF_WIDTH; - int last_mouse_y = WINDOW_HALF_HEIGHT; - uint32_t last_frame = SDL_GetTicks(); - float delta = 0.0f; - bool running = true; - SDL_Event event = {}; + const float light_radius = 3.0f; + const float sensitivity = 0.1f; + int last_mouse_x = WINDOW_HALF_WIDTH; + int last_mouse_y = WINDOW_HALF_HEIGHT; + uint32_t last_frame = SDL_GetTicks(); + float delta = 0.0f; + bool running = true; + SDL_Event event = {}; while (running) { uint32_t ticks = SDL_GetTicks(); + float seconds = ticks * 0.001f; delta = (ticks - last_frame) * 0.001f; + light_position = glm::vec3(sin(seconds) * light_radius, light_position.y, cos(seconds) * light_radius); last_frame = ticks; while (SDL_PollEvent(&event)) { @@ -249,6 +265,7 @@ int main() { camera_forward = glm::normalize(camera_forward); view = glm::lookAt(camera_position, camera_position + camera_forward, world_up); + main_shader.set_vec3("camera_position", camera_position); main_shader.set_mat4("view", view); light_shader.set_mat4("view", view); @@ -256,18 +273,20 @@ int main() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); model = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, 0.0f)); + normal_mat = glm::transpose(glm::inverse(model)); main_shader.activate(); + main_shader.set_vec3("light_position", light_position); main_shader.set_mat4("model", model); + main_shader.set_mat3("normal_mat", normal_mat); glBindVertexArray(vao); - glUniformMatrix4fv(glGetUniformLocation(main_shader.program, "model"), 1, GL_FALSE, glm::value_ptr(model)); - glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, (void *)0); + glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, (void *)0); - model = glm::translate(glm::mat4(1.0f), glm::vec3(1.2f, 1.0f, 2.0f)); + model = glm::translate(glm::mat4(1.0f), light_position); model = glm::scale(model, glm::vec3(0.2f)); light_shader.activate(); light_shader.set_mat4("model", model); glBindVertexArray(light_vao); - glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, (void *)0); + glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, (void *)0); SDL_GL_SwapWindow(window); } @@ -310,6 +329,11 @@ void Shader::set_vec3(const char *name, glm::vec3 vector) { glUniform3f(glGetUniformLocation(program, name), vector.x, vector.y, vector.z); } +void Shader::set_mat3(const char *name, glm::mat3 matrix) { + activate(); + glUniformMatrix3fv(glGetUniformLocation(program, name), 1, GL_FALSE, glm::value_ptr(matrix)); +} + void Shader::set_mat4(const char *name, glm::mat4 matrix) { activate(); glUniformMatrix4fv(glGetUniformLocation(program, name), 1, GL_FALSE, glm::value_ptr(matrix));