From 2ca743d8df36f8cf863caa9c40f965398f72ef2e Mon Sep 17 00:00:00 2001 From: sanine-a Date: Sun, 24 May 2020 18:49:46 -0500 Subject: add blinn-phong lighting demo --- demo.c | 49 ++++++++++++++++++++++++++++++++++--------------- demo.fs | 26 ++++++++++++++++++++++++-- demo.vs | 7 ++++++- include/shader.h | 11 +++++++++++ src/shader.c | 10 ++++++++++ 5 files changed, 85 insertions(+), 18 deletions(-) diff --git a/demo.c b/demo.c index 83ea93a..17ef747 100644 --- a/demo.c +++ b/demo.c @@ -17,7 +17,9 @@ honey_texture container; honey_texture happy_face; honey_mesh light_cube; -vec3 light_color = { 1, 0, 0 }; +vec3 ambient_color = { 0, 0.2, 0.2 }; +vec3 light_color = { 1, 1, 1 }; +vec3 light_position = { 2, 2, 2 }; mat4 light_model; honey_shader light_shader; @@ -70,7 +72,7 @@ void toggle_wireframe(void* data, int action) { void update(float dt) { glfwPollEvents(); - glm_rotate_x(model, glm_rad(10*dt), model); + //glm_rotate_x(model, glm_rad(10*dt), model); if (honey_key_down(HONEY_KEY_ESCAPE)) { glfwSetWindowShouldClose(window, true); @@ -101,7 +103,7 @@ void update(float dt) { /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ void draw() { - glClearColor(0.4f, 0.4f, 0.4f, 1.0); + glClearColor(0, 0, 0, 1); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); if (wireframe) { @@ -113,8 +115,15 @@ void draw() { honey_camera_calculate_view(&camera); honey_shader_set_mat4(cube_shader, "view", camera.view); - honey_shader_set_mat4(light_shader, "view", camera.view); honey_shader_set_mat4(cube_shader, "model", model); + mat4 normal4; + mat3 normal; + glm_mat4_copy(model, normal4); + glm_mat4_inv_fast(normal4, normal4); + glm_mat4_pick3t(normal4, normal); + honey_shader_set_mat3(cube_shader, "normal_mat", normal); + + honey_shader_set_mat4(light_shader, "view", camera.view); honey_shader_set_mat4(light_shader, "model", light_model); honey_texture_use(container, 0); @@ -154,28 +163,19 @@ int main() { return 1; } - honey_shader_set_vec3(light_shader, "light_color", light_color); - if (honey_mesh_new_textured_cube(&cube, 1, 1, 1) != MESH_OK) { fprintf(stderr, "Failed to load cube\n"); return 1; } - if (honey_mesh_new_cube(&light_cube, 0.5, 0.5, 0.5) != MESH_OK) { + if (honey_mesh_new_cube(&light_cube, 0.1, 0.1, 0.1) != MESH_OK) { return 1; } glm_mat4_identity(light_model); - glm_translate(light_model, (vec3){4, 5, 0}); - honey_shader_set_mat4(light_shader, "model", light_model); - - honey_shader_set_int(cube_shader, "box_texture", 0); - honey_shader_set_int(cube_shader, "happy_texture", 1); - honey_shader_set_vec3(cube_shader, "light_color", light_color); + glm_translate(light_model, light_position); glm_mat4_identity(model); - //glm_rotate_x(model, glm_rad(-55), model); - honey_shader_set_mat4(cube_shader, "model", model); vec3 camera_pos = { -4, 0, 0 }; vec3 camera_angle = { 0, 0, 0 }; @@ -189,9 +189,28 @@ int main() { camera_aspect_ratio, camera_near, camera_far, camera_fov); + /* set cube_shader uniforms */ + honey_shader_set_int(cube_shader, "box_texture", 0); + honey_shader_set_int(cube_shader, "happy_texture", 1); + honey_shader_set_vec3(cube_shader, "light_color", light_color); + honey_shader_set_vec3(cube_shader, "light_position", light_position); + honey_shader_set_vec3(cube_shader, "ambient_color", ambient_color); + honey_shader_set_mat4(cube_shader, "model", model); + mat4 normal4; + mat3 normal; + glm_mat4_copy(model, normal4); + glm_mat4_inv_fast(normal4, normal4); + glm_mat4_pick3t(normal4, normal); + honey_shader_set_mat3(cube_shader, "normal_mat", normal); honey_shader_set_mat4(cube_shader, "view", camera.view); honey_shader_set_mat4(cube_shader, "projection", camera.projection); + + /* set light_shader uniforms */ + honey_shader_set_vec3(light_shader, "light_color", light_color); + + honey_shader_set_mat4(light_shader, "model", light_model); + honey_shader_set_mat4(light_shader, "view", camera.view); honey_shader_set_mat4(light_shader, "projection", camera.projection); glEnable(GL_DEPTH_TEST); diff --git a/demo.fs b/demo.fs index a9a0275..65700b7 100644 --- a/demo.fs +++ b/demo.fs @@ -1,15 +1,37 @@ #version 330 core +in vec3 normal; in vec2 texture_coordinate; +in vec3 fragment_position; + +uniform vec3 ambient_color; uniform vec3 light_color; +uniform vec3 light_position; uniform sampler2D box_texture; uniform sampler2D happy_texture; +uniform mat4 model; +uniform mat4 view; + out vec4 fragment_color; void main() { - fragment_color = texture(box_texture, texture_coordinate) * vec4(light_color.xyz, 1.0); -} + /* diffuse light */ + vec3 norm = normalize(normal); + vec3 light_pos = vec3(view * vec4(light_position.xyz, 1.0)); + vec3 light_direction = normalize(light_pos - fragment_position); + float diffuse = max( dot(norm, light_direction), 0 ); + vec3 diffuse_light = light_color * diffuse; + + /* specular reflection */ + vec3 view_direction = normalize(-fragment_position); + vec3 reflection_direction = reflect(-light_direction, norm); + float specular = pow(max(dot(view_direction, reflection_direction), 0), 32); + vec3 specular_light = 1.0 * specular * light_color; + + vec4 total_light = vec4((ambient_color + diffuse_light + specular_light).xyz, 1.0); + fragment_color = total_light * texture(box_texture, texture_coordinate); +} diff --git a/demo.vs b/demo.vs index 37fe02f..c1ec38f 100644 --- a/demo.vs +++ b/demo.vs @@ -1,11 +1,14 @@ #version 330 core layout (location = 0) in vec3 position; -layout (location = 1) in vec3 normal; +layout (location = 1) in vec3 in_normal; layout (location = 2) in vec2 texCoord; out vec2 texture_coordinate; +out vec3 normal; +out vec3 fragment_position; uniform mat4 model; +uniform mat3 normal_mat; uniform mat4 view; uniform mat4 projection; @@ -13,4 +16,6 @@ void main() { gl_Position = projection * view * model * vec4(position.xyz, 1.0); texture_coordinate = texCoord; + normal = mat3(view) * normal_mat * in_normal; + fragment_position = vec3(view * model * vec4(position.xyz, 1.0)); } \ No newline at end of file diff --git a/include/shader.h b/include/shader.h index 40561d4..771ea4a 100644 --- a/include/shader.h +++ b/include/shader.h @@ -63,6 +63,17 @@ void honey_shader_set_vec3(honey_shader shader, char* vector_name, vec3 value); + +/** @brief Set a mat3 uniform. + * + * @param[in] shader The shader to which the uniform belongs + * @param[in] matrix_name The name of the matrix uniform + * @param[in] value The value of the matrix uniform + */ +void honey_shader_set_mat3(honey_shader shader, + char* matrix_name, + mat3 value); + /** @brief Set a mat4 uniform. * * @param[in] shader The shader to which the uniform belongs diff --git a/src/shader.c b/src/shader.c index e9d79a6..cba83f7 100644 --- a/src/shader.c +++ b/src/shader.c @@ -119,6 +119,16 @@ void honey_shader_set_vec3(honey_shader shader, /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ +void honey_shader_set_mat3(honey_shader shader, + char* matrix_name, + mat3 value) { + glUseProgram(shader); + unsigned int matrix_location = glGetUniformLocation(shader, matrix_name); + glUniformMatrix3fv(matrix_location, 1, GL_FALSE, (float*) value); +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + void honey_shader_set_mat4(honey_shader shader, char* matrix_name, mat4 value) { -- cgit v1.2.1