Start the lighting chapters

This commit is contained in:
Abdelrahman Said 2024-12-01 22:30:42 +00:00
parent e9baa0ebe3
commit babe58f0a5
4 changed files with 72 additions and 113 deletions

View File

@ -1,13 +1,10 @@
#version 330 core #version 330 core
in vec2 tex_coords;
out vec4 color; out vec4 color;
uniform float mix_factor; uniform vec3 object_color;
uniform sampler2D texture0; uniform vec3 light_color;
uniform sampler2D texture1;
void main() { void main() {
color = mix(texture(texture0, tex_coords), texture(texture1, tex_coords), mix_factor); color = vec4(object_color * light_color, 1.0);
}; };

7
shaders/light_frag.glsl Normal file
View File

@ -0,0 +1,7 @@
#version 330 core
out vec4 color;
void main() {
color = vec4(1.0);
}

View File

@ -1,15 +1,11 @@
#version 330 core #version 330 core
layout(location=0) in vec3 position; layout(location=0) in vec3 position;
layout(location=1) in vec2 uv;
uniform mat4 model; uniform mat4 model;
uniform mat4 view; uniform mat4 view;
uniform mat4 projection; uniform mat4 projection;
out vec2 tex_coords;
void main() { void main() {
tex_coords = uv;
gl_Position = projection * view * model * vec4(position, 1.0); gl_Position = projection * view * model * vec4(position, 1.0);
}; };

View File

@ -10,10 +10,6 @@
#include "glm/gtx/rotate_vector.hpp" #include "glm/gtx/rotate_vector.hpp"
#include "glm/gtx/string_cast.hpp" #include "glm/gtx/string_cast.hpp"
// STB Image
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
// SDL // SDL
#include <SDL2/SDL.h> #include <SDL2/SDL.h>
#include <SDL2/SDL_timer.h> #include <SDL2/SDL_timer.h>
@ -49,6 +45,9 @@ class Shader {
Shader(const std::string &vert_file, const std::string &frag_file); Shader(const std::string &vert_file, const std::string &frag_file);
~Shader(); ~Shader();
void activate(); void activate();
void set_float(const char *name, float value);
void set_vec3(const char *name, glm::vec3 vector);
void set_mat4(const char *name, glm::mat4 matrix);
GLuint program; GLuint program;
private: private:
void link_program(GLuint vert, GLuint frag); void link_program(GLuint vert, GLuint frag);
@ -86,34 +85,28 @@ int main() {
SDL_SetRelativeMouseMode(SDL_TRUE); SDL_SetRelativeMouseMode(SDL_TRUE);
SDL_WarpMouseInWindow(window, WINDOW_HALF_WIDTH, WINDOW_HALF_HEIGHT); SDL_WarpMouseInWindow(window, WINDOW_HALF_WIDTH, WINDOW_HALF_HEIGHT);
// Set texture options
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glViewport(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT); glViewport(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);
glEnable(GL_DEPTH_TEST); glEnable(GL_DEPTH_TEST);
std::vector<GLfloat> vertices = { std::vector<GLfloat> vertices = {
0.5f, -0.5f, 0.5f, 0.0f, 0.0f, // position, uv 0.5f, -0.5f, 0.5f, // position
-0.5f, 0.5f, 0.5f, 1.0f, 0.0f, // position, uv -0.5f, 0.5f, 0.5f, // position
0.5f, 0.5f, 0.5f, 1.0f, 0.0f, // position, uv 0.5f, 0.5f, 0.5f, // position
0.5f, -0.5f, 0.5f, 1.0f, 0.0f, // position, uv 0.5f, -0.5f, 0.5f, // position
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, // position, uv -0.5f, -0.5f, 0.5f, // position
0.5f, -0.5f, -0.5f, 1.0f, 0.0f, // position, uv 0.5f, -0.5f, -0.5f, // position
-0.5f, 0.5f, -0.5f, 1.0f, 1.0f, // position, uv -0.5f, 0.5f, -0.5f, // position
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f, // position, uv -0.5f, 0.5f, -0.5f, // position
-0.5f, 0.5f, 0.5f, 0.0f, 1.0f, // position, uv -0.5f, 0.5f, 0.5f, // position
0.5f, 0.5f, -0.5f, 1.0f, 1.0f, // position, uv 0.5f, 0.5f, -0.5f, // position
0.5f, -0.5f, -0.5f, 1.0f, 1.0f, // position, uv 0.5f, -0.5f, -0.5f, // position
-0.5f, 0.5f, 0.5f, 0.0f, 0.0f, // position, uv -0.5f, 0.5f, 0.5f, // position
0.5f, 0.5f, 0.5f, 1.0f, 1.0f, // position, uv 0.5f, 0.5f, 0.5f, // position
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f, // position, uv -0.5f, -0.5f, -0.5f, // position
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, // position, uv -0.5f, -0.5f, -0.5f, // position
0.5f, -0.5f, -0.5f, 0.0f, 1.0f, // position, uv 0.5f, -0.5f, -0.5f, // position
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f // position, uv -0.5f, 0.5f, -0.5f, // position
}; };
std::vector<GLuint> indices = { std::vector<GLuint> indices = {
@ -145,68 +138,27 @@ int main() {
glBindBuffer(GL_ARRAY_BUFFER, vbo); glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(GLfloat), vertices.data(), GL_STATIC_DRAW); glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(GLfloat), vertices.data(), GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (void *)0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (void *)0);
glEnableVertexAttribArray(0);
GLuint light_vao = 0;
glGenVertexArrays(1, &light_vao);
glBindVertexArray(light_vao);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (void *)0);
glEnableVertexAttribArray(0); glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (void *)(3 * sizeof(GLfloat)));
glEnableVertexAttribArray(1);
glBindVertexArray(0); glBindVertexArray(0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ARRAY_BUFFER, 0);
stbi_set_flip_vertically_on_load(true);
// Load texture
int32_t width[2], height[2], channels[2];
uint8_t *container = stbi_load("images/container.jpg", &width[0], &height[0], &channels[0], 0);
uint8_t *awesomeface = stbi_load("images/awesomeface.png", &width[1], &height[1], &channels[1], 0);
GLuint textures[2];
glGenTextures(2, textures);
glActiveTexture(GL_TEXTURE0); // activate the texture unit first before binding texture
glBindTexture(GL_TEXTURE_2D, textures[0]);
if (container) {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width[0], height[0], 0, GL_RGB, GL_UNSIGNED_BYTE, container);
glGenerateMipmap(GL_TEXTURE_2D);
stbi_image_free(container);
} else {
printf("Failed to load container texture \n");
}
glActiveTexture(GL_TEXTURE1); // activate the texture unit first before binding texture
glBindTexture(GL_TEXTURE_2D, textures[1]);
if (container) {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width[1], height[1], 0, GL_RGBA, GL_UNSIGNED_BYTE, awesomeface);
glGenerateMipmap(GL_TEXTURE_2D);
stbi_image_free(awesomeface);
} else {
printf("Failed to load container texture \n");
}
glBindTexture(GL_TEXTURE_2D, 0);
Shader main_shader {"shaders/vert.glsl", "shaders/frag.glsl"}; Shader main_shader {"shaders/vert.glsl", "shaders/frag.glsl"};
main_shader.activate(); Shader light_shader {"shaders/vert.glsl", "shaders/light_frag.glsl"};
glUniform1i(glGetUniformLocation(main_shader.program, "texture0"), 0);
glUniform1i(glGetUniformLocation(main_shader.program, "texture1"), 1);
float texture_mix_factor = 0.2f; main_shader.set_vec3("object_color", glm::vec3(1.0f, 0.5f, 0.31f));
main_shader.set_vec3("light_color", glm::vec3(1.0f, 1.0f, 1.0f));
glm::vec3 cube_positions[] = {
glm::vec3( 0.0f, 0.0f, 0.0f),
glm::vec3( 4.0f, 6.0f, -15.0f),
glm::vec3(-3.5f, -3.2f, -2.5f),
glm::vec3(-5.8f, -3.0f, -12.3f),
glm::vec3( 4.4f, -1.4f, -3.5f),
glm::vec3(-3.7f, 4.0f, -7.5f),
glm::vec3( 3.3f, -3.0f, -2.5f),
glm::vec3( 3.5f, 3.0f, -2.5f),
glm::vec3( 3.5f, 1.2f, -1.5f),
glm::vec3(-3.3f, 2.0f, -1.5f)
};
const float camera_speed = 25.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(0.0f, 0.0f, 4.0f);
@ -220,7 +172,8 @@ int main() {
glm::mat4 view = 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::mat4 projection = glm::perspective(glm::radians(45.0f), (float)WINDOW_WIDTH / (float)WINDOW_HEIGHT, 0.1f, 100.0f);
glUniformMatrix4fv(glGetUniformLocation(main_shader.program, "projection"), 1, GL_FALSE, glm::value_ptr(projection)); main_shader.set_mat4("projection", projection);
light_shader.set_mat4("projection", projection);
const float sensitivity = 0.1f; const float sensitivity = 0.1f;
int last_mouse_x = WINDOW_HALF_WIDTH; int last_mouse_x = WINDOW_HALF_WIDTH;
@ -243,10 +196,6 @@ int main() {
case SDL_KEYDOWN: case SDL_KEYDOWN:
if (event.key.keysym.sym == SDLK_ESCAPE) { if (event.key.keysym.sym == SDLK_ESCAPE) {
running = false; running = false;
} else if (event.key.keysym.sym == SDLK_UP) {
texture_mix_factor += 0.1f;
} else if (event.key.keysym.sym == SDLK_DOWN) {
texture_mix_factor -= 0.1f;
} else if (event.key.keysym.sym == SDLK_w) { } else if (event.key.keysym.sym == SDLK_w) {
camera_position += camera_speed * delta * camera_forward; camera_position += camera_speed * delta * camera_forward;
} else if (event.key.keysym.sym == SDLK_s) { } else if (event.key.keysym.sym == SDLK_s) {
@ -294,36 +243,31 @@ int main() {
} }
} }
texture_mix_factor = texture_mix_factor < 0.0f ?
0.0f : texture_mix_factor > 1.0f ?
1.0f : texture_mix_factor;
camera_forward.x = cos(glm::radians(yaw)) * cos(glm::radians(pitch)); camera_forward.x = cos(glm::radians(yaw)) * cos(glm::radians(pitch));
camera_forward.y = sin(glm::radians(pitch)); camera_forward.y = sin(glm::radians(pitch));
camera_forward.z = sin(glm::radians(yaw)) * cos(glm::radians(pitch)); camera_forward.z = sin(glm::radians(yaw)) * cos(glm::radians(pitch));
camera_forward = glm::normalize(camera_forward); camera_forward = glm::normalize(camera_forward);
view = glm::lookAt(camera_position, camera_position + camera_forward, world_up); view = glm::lookAt(camera_position, camera_position + camera_forward, world_up);
glUniformMatrix4fv(glGetUniformLocation(main_shader.program, "view"), 1, GL_FALSE, glm::value_ptr(view)); main_shader.set_mat4("view", view);
light_shader.set_mat4("view", view);
glClearColor(0.2f, 0.3f, 0.3f, 1.0f); glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
model = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, 0.0f));
main_shader.activate(); main_shader.activate();
glUniform1f(glGetUniformLocation(main_shader.program, "mix_factor"), texture_mix_factor); main_shader.set_mat4("model", model);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, textures[0]);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, textures[1]);
glBindVertexArray(vao); glBindVertexArray(vao);
glUniformMatrix4fv(glGetUniformLocation(main_shader.program, "model"), 1, GL_FALSE, glm::value_ptr(model));
glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, (void *)0);
for (int i = 0; i < sizeof(cube_positions) / sizeof(cube_positions[0]); ++i) { model = glm::translate(glm::mat4(1.0f), glm::vec3(1.2f, 1.0f, 2.0f));
float angle = 20.0f * i; model = glm::scale(model, glm::vec3(0.2f));
model = glm::translate(glm::mat4(1.0f), cube_positions[i]); light_shader.activate();
model = glm::rotate(model, glm::radians(angle), glm::vec3(1.0f, 0.3f, 0.5f)); light_shader.set_mat4("model", model);
glUniformMatrix4fv(glGetUniformLocation(main_shader.program, "model"), 1, GL_FALSE, glm::value_ptr(model)); glBindVertexArray(light_vao);
glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, (void *)0); glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, (void *)0);
}
SDL_GL_SwapWindow(window); SDL_GL_SwapWindow(window);
} }
@ -356,6 +300,21 @@ void Shader::activate() {
} }
} }
void Shader::set_float(const char *name, float value) {
activate();
glUniform1f(glGetUniformLocation(program, name), value);
}
void Shader::set_vec3(const char *name, glm::vec3 vector) {
activate();
glUniform3f(glGetUniformLocation(program, name), vector.x, vector.y, vector.z);
}
void Shader::set_mat4(const char *name, glm::mat4 matrix) {
activate();
glUniformMatrix4fv(glGetUniformLocation(program, name), 1, GL_FALSE, glm::value_ptr(matrix));
}
void Shader::link_program(GLuint vert, GLuint frag) { void Shader::link_program(GLuint vert, GLuint frag) {
program = glCreateProgram(); program = glCreateProgram();
glAttachShader(program, vert); glAttachShader(program, vert);