diff --git a/images/container2.png b/images/container2.png new file mode 100644 index 0000000..596e8da Binary files /dev/null and b/images/container2.png differ diff --git a/shaders/frag.glsl b/shaders/frag.glsl index 3071b9d..32e9b20 100644 --- a/shaders/frag.glsl +++ b/shaders/frag.glsl @@ -1,8 +1,7 @@ #version 330 core struct Material { - vec3 ambient; - vec3 diffuse; + sampler2D diffuse; vec3 specular; float shininess; }; @@ -16,6 +15,7 @@ struct Light { in vec3 vert_normal; in vec3 frag_position; +in vec2 uv_coords; out vec4 color; @@ -32,8 +32,9 @@ void main() { 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), material.shininess); - vec3 ambient = light.ambient * material.ambient; - vec3 diffuse = light.diffuse * (diff * material.diffuse); + vec3 diff_tex = vec3(texture(material.diffuse, uv_coords)); + vec3 ambient = light.ambient * diff_tex; + vec3 diffuse = light.diffuse * (diff * diff_tex); vec3 specular = light.specular * (spec * material.specular); color = vec4(ambient + diffuse + specular, 1.0); diff --git a/shaders/vert.glsl b/shaders/vert.glsl index a3efab0..fc17666 100644 --- a/shaders/vert.glsl +++ b/shaders/vert.glsl @@ -2,9 +2,11 @@ layout(location=0) in vec3 position; layout(location=1) in vec3 normal; +layout(location=2) in vec2 uv; out vec3 vert_normal; out vec3 frag_position; +out vec2 uv_coords; uniform mat3 normal_mat; uniform mat4 model; @@ -14,5 +16,6 @@ uniform mat4 projection; void main() { vert_normal = normal_mat * normal; frag_position = vec3(model * vec4(position, 1.0)); + uv_coords = uv; gl_Position = projection * view * model * vec4(position, 1.0); }; diff --git a/src/main.cc b/src/main.cc index 1bafc1d..ec0c26a 100644 --- a/src/main.cc +++ b/src/main.cc @@ -1,6 +1,10 @@ // GLAD #include "glad/glad.h" +// STB Image +#define STB_IMAGE_IMPLEMENTATION +#include "stb_image.h" + // GLM #define GLM_ENABLE_EXPERIMENTAL #include "glm/ext/matrix_transform.hpp" @@ -49,6 +53,7 @@ class Shader { Shader(const std::string &vert_file, const std::string &frag_file); ~Shader(); void activate(); + void set_int(const char *name, int value); 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); @@ -90,51 +95,53 @@ int main() { SDL_SetRelativeMouseMode(SDL_TRUE); SDL_WarpMouseInWindow(window, WINDOW_HALF_WIDTH, WINDOW_HALF_HEIGHT); + stbi_set_flip_vertically_on_load(true); + glViewport(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT); glEnable(GL_DEPTH_TEST); std::vector vertices = { - 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 + // positions // normals // texture coords + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, + 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, + -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, + -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, + -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, }; std::vector indices = { - 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 + 6, 14, 12, + 12, 19, 6, + 17, 7, 9, + 9, 3, 17, + 22, 20, 0, + 0, 18, 22, + 1, 2, 23, + 23, 4, 1, + 8, 5, 10, + 10, 11, 8, + 16, 21, 13, + 13, 15, 16 }; GLuint vao = 0; @@ -151,10 +158,12 @@ 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, 6 * sizeof(GLfloat), (void *)0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (void *)0); glEnableVertexAttribArray(0); - glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (void *)(3 * sizeof(GLfloat))); + glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (void *)(3 * sizeof(GLfloat))); glEnableVertexAttribArray(1); + glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (void *)(6 * sizeof(GLfloat))); + glEnableVertexAttribArray(2); GLuint light_vao = 0; glGenVertexArrays(1, &light_vao); @@ -162,7 +171,7 @@ int main() { glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo); glBindBuffer(GL_ARRAY_BUFFER, vbo); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (void *)0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (void *)0); glEnableVertexAttribArray(0); glBindVertexArray(0); @@ -172,6 +181,29 @@ int main() { Shader main_shader {"shaders/vert.glsl", "shaders/frag.glsl"}; Shader light_shader {"shaders/vert.glsl", "shaders/light_frag.glsl"}; + int width, height, channels; + uint8_t *diffuse_map = stbi_load("images/container2.png", &width, &height, &channels, 0); + GLuint diffuse_texture = 0; + if (diffuse_map) { + glGenTextures(1, &diffuse_texture); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, diffuse_texture); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, diffuse_map); + glGenerateMipmap(GL_TEXTURE_2D); + + main_shader.set_int("material.diffuse", 0); + + glBindTexture(GL_TEXTURE_2D, 0); + stbi_image_free(diffuse_map); + } + const float camera_speed = 25.0f; glm::vec3 camera_position = glm::vec3(-2.0f, 0.0f, 6.0f); glm::vec3 camera_forward = glm::vec3(0.0f); @@ -188,8 +220,6 @@ int main() { glm::mat3 normal_mat = glm::mat3(1.0f); main_shader.set_mat4 ("projection", projection); - main_shader.set_vec3 ("material.ambient", glm::vec3(1.0f, 0.5f, 0.31f)); - main_shader.set_vec3 ("material.diffuse", glm::vec3(1.0f, 0.5f, 0.31f)); main_shader.set_vec3 ("material.specular", glm::vec3(0.5f, 0.5f, 0.5f)); main_shader.set_float("material.shininess", 32.0f); main_shader.set_vec3 ("light.ambient", glm::vec3(0.2f, 0.2f, 0.2f)); @@ -293,6 +323,8 @@ int main() { main_shader.set_vec3("light.diffuse", light_diffuse); main_shader.set_mat4("model", model); main_shader.set_mat3("normal_mat", normal_mat); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, diffuse_texture); glBindVertexArray(vao); glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, (void *)0); @@ -335,6 +367,11 @@ void Shader::activate() { } } +void Shader::set_int(const char *name, int value) { + activate(); + glUniform1i(glGetUniformLocation(program, name), value); +} + void Shader::set_float(const char *name, float value) { activate(); glUniform1f(glGetUniformLocation(program, name), value);