diff --git a/images/container2_specular.png b/images/container2_specular.png new file mode 100644 index 0000000..681bf6e Binary files /dev/null and b/images/container2_specular.png differ diff --git a/shaders/frag.glsl b/shaders/frag.glsl index 32e9b20..4a6b971 100644 --- a/shaders/frag.glsl +++ b/shaders/frag.glsl @@ -2,7 +2,7 @@ struct Material { sampler2D diffuse; - vec3 specular; + sampler2D specular; float shininess; }; @@ -35,7 +35,7 @@ void main() { 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); + vec3 specular = light.specular * (spec * vec3(texture(material.specular, uv_coords))); color = vec4(ambient + diffuse + specular, 1.0); }; diff --git a/src/main.cc b/src/main.cc index ec0c26a..2d75f87 100644 --- a/src/main.cc +++ b/src/main.cc @@ -66,6 +66,20 @@ class Shader { static const char *get_shader_type_string(GLenum shader_type); }; +class Texture2D { + public: + Texture2D(const char *filename, GLint texture_unit); + ~Texture2D(); + void activate(); + int width; + int height; + int channels; + private: + GLuint texture; + GLint texture_unit; + GLint format; +}; + int main() { if (SDL_Init(SDL_INIT_EVERYTHING) != 0) { return EXIT_CODE_SDL_INIT_FAILED; @@ -181,28 +195,10 @@ 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); - } + Texture2D diffuse_map = Texture2D("images/container2.png", GL_TEXTURE0); + Texture2D specular_map = Texture2D("images/container2_specular.png", GL_TEXTURE1); + main_shader.set_int("material.diffuse", 0); + main_shader.set_int("material.specular", 1); const float camera_speed = 25.0f; glm::vec3 camera_position = glm::vec3(-2.0f, 0.0f, 6.0f); @@ -323,8 +319,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); + diffuse_map.activate(); + specular_map.activate(); glBindVertexArray(vao); glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, (void *)0); @@ -477,3 +473,34 @@ const char *Shader::get_shader_type_string(GLenum shader_type) { return output; } + +Texture2D::Texture2D(const char *filename, GLint texture_unit) : texture_unit(texture_unit) { + uint8_t *image = stbi_load(filename, &width, &height, &channels, 0); + if (!image) { + return; + } + + // TODO (Abdelrahman): This doesn't handle all formats + format = channels > 3 ? GL_RGBA : GL_RGB; + + glGenTextures(1, &texture); + activate(); + + 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, format, width, height, 0, format, GL_UNSIGNED_BYTE, image); + glGenerateMipmap(GL_TEXTURE_2D); + + glBindTexture(GL_TEXTURE_2D, 0); + stbi_image_free(image); +} + +Texture2D::~Texture2D() {} + +void Texture2D::activate() { + glActiveTexture(texture_unit); + glBindTexture(GL_TEXTURE_2D, texture); +}