diff options
author | pryazha <pryadeiniv@mail.ru> | 2025-02-19 22:26:48 +0500 |
---|---|---|
committer | pryazha <pryadeiniv@mail.ru> | 2025-02-19 22:26:48 +0500 |
commit | f9ad6fa902c1167d7622ee7af2617d14b62bee21 (patch) | |
tree | 9d78792cf360ed871616a9ea66c4237018292aa7 /advanced_lighting/3.1.shadow_mapping/shadow_mapping.c | |
parent | 926cbd0d49890772f911e6a6bedb7835605ced89 (diff) |
quite a lot of changes that I, of course, are not going to describe;)
Diffstat (limited to 'advanced_lighting/3.1.shadow_mapping/shadow_mapping.c')
-rw-r--r-- | advanced_lighting/3.1.shadow_mapping/shadow_mapping.c | 668 |
1 files changed, 263 insertions, 405 deletions
diff --git a/advanced_lighting/3.1.shadow_mapping/shadow_mapping.c b/advanced_lighting/3.1.shadow_mapping/shadow_mapping.c index 7f03415..fd03ed9 100644 --- a/advanced_lighting/3.1.shadow_mapping/shadow_mapping.c +++ b/advanced_lighting/3.1.shadow_mapping/shadow_mapping.c @@ -1,417 +1,275 @@ -#include "pwyazh.h" - #include "GL/glew.h" #include "GLFW/glfw3.h" +#include "pwyazh.h" #include "pwyazh_GL.h" #include "common.h" -static S32 global_screen_width = 800, global_screen_height = 600; -static U32 global_shadow_width = 1024, global_shadow_height = 1024; - -static Input global_input; - -static V3F camera_dp = (V3F){ 0.0f, 0.0f, 0.0f }; - -static U32 global_depth_map_fbo, global_depth_map; - -static U32 global_debug_quad_shader, global_simple_depth_shader, - global_shadow_shader, global_color_shader; - -static U32 global_wood_texture; - -static U32 global_quad_vao; - -static U32 shadows_ortho = 1; - -static V3F light_pos; - -void -glfw_key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) -{ - switch (action) - { - case GLFW_PRESS: { - switch (key) - { - case GLFW_KEY_D: { - global_input.move_right.state = KeyState_PRESS; - } break; - case GLFW_KEY_W: { - global_input.move_forward.state = KeyState_PRESS; - } break; - case GLFW_KEY_A: { - global_input.move_left.state = KeyState_PRESS; - } break; - case GLFW_KEY_S: { - global_input.move_backward.state = KeyState_PRESS; - } break; - case GLFW_KEY_E: { - global_input.move_up.state = KeyState_PRESS; - } break; - case GLFW_KEY_Q: { - global_input.move_down.state = KeyState_PRESS; - } break; - case GLFW_KEY_SPACE: { - global_input.jump.state = KeyState_PRESS; - } break; - case GLFW_KEY_RIGHT: { - global_input.action_right.state = KeyState_PRESS; - } break; - case GLFW_KEY_UP: { - global_input.action_up.state = KeyState_PRESS; - } break; - case GLFW_KEY_LEFT: { - global_input.action_left.state = KeyState_PRESS; - } break; - case GLFW_KEY_DOWN: { - global_input.action_down.state = KeyState_PRESS; - } break; - case GLFW_KEY_ESCAPE: { - global_input.exit.state = KeyState_PRESS; - } break; - } - } break; - - case GLFW_RELEASE: { - switch (key) - { - case GLFW_KEY_D: { - global_input.move_right.state = KeyState_RELEASE; - } break; - case GLFW_KEY_W: { - global_input.move_forward.state = KeyState_RELEASE; - } break; - case GLFW_KEY_A: { - global_input.move_left.state = KeyState_RELEASE; - } break; - case GLFW_KEY_S: { - global_input.move_backward.state = KeyState_RELEASE; - } break; - case GLFW_KEY_E: { - global_input.move_up.state = KeyState_RELEASE; - } break; - case GLFW_KEY_Q: { - global_input.move_down.state = KeyState_RELEASE; - } break; - case GLFW_KEY_SPACE: { - global_input.jump.state = KeyState_RELEASE; - } break; - case GLFW_KEY_RIGHT: { - global_input.action_right.state = KeyState_RELEASE; - } break; - case GLFW_KEY_UP: { - global_input.action_up.state = KeyState_RELEASE; - } break; - case GLFW_KEY_LEFT: { - global_input.action_left.state = KeyState_RELEASE; - } break; - case GLFW_KEY_DOWN: { - global_input.action_down.state = KeyState_RELEASE; - } break; - case GLFW_KEY_ESCAPE: { - global_input.exit.state = KeyState_RELEASE; - } break; - } - } break; - } -} - -void -resize_callback(GLFWwindow* window, int width, int height) -{ - global_screen_width = width; - global_screen_height = height; - glViewport(0, 0, global_screen_width, global_screen_height); -} - -void -error_callback(int error, const char *desc) -{ - fprintf(stderr, "[ERROR] GLFW: %s\n", desc); -} - -void -update(State *state, F32 time) -{ - F32 radius; - - V3F camera_dv = get_dv_camera_orbital(&global_input, state->camera.pos, - v3f_zero(), state->dt, 2.0f); - if (key_is_pressed(global_input.action_up)) - camera_dv = v3f_scalef(camera_dv, 3.0f); - camera_dp = v3f_add(camera_dp, camera_dv); - camera_dp = v3f_scalef(camera_dp, 0.8f); - state->camera.pos = v3f_add(state->camera.pos, camera_dp); - - if (key_first_press(global_input.action_down)) - shadows_ortho = !shadows_ortho; - - input_update_last_state(&global_input); - - F32 x, z, angular_speed; - - angular_speed = 1.0f; - radius = 4.0f; - x = f32_sin(time*angular_speed)*radius; - z = f32_cos(time*angular_speed)*radius; - - light_pos = v3f(x, 4.0f, z); -} - -void -render_scene(U32 shader, Mesh *cube, Mesh *plane) -{ - MAT4 model; - - model = mat4_identity(); - shader_set_mat4fv(shader, "model", model); - mesh_draw(plane); - - /* - model = mat4_identity(); - model = mat4_make_scale(v3f(10.0f, 0.1f, 10.0f)); - model = mat4_translate(model, v3f(0.0f, -0.6f, 0.0f)); - shader_set_mat4fv(shader, "model", model); - mesh_draw(cube); - */ - - model = mat4_identity(); - model = mat4_make_scale(v3f(0.5f, 0.5f, 0.5f)); - model = mat4_translate(model, v3f(0.0f, 1.5f, 0.0f)); - shader_set_mat4fv(shader, "model", model); - mesh_draw(cube); - - model = mat4_identity(); - model = mat4_make_scale(v3f(0.5f, 0.5f, 0.5f)); - model = mat4_translate(model, v3f(2.0f, 0.0f, 1.0f)); - shader_set_mat4fv(shader, "model", model); - mesh_draw(cube); - - model = mat4_identity(); - model = mat4_make_scale(v3f(0.25f, 0.25f, 0.25f)); - model = mat4_rotate_angles(model, v3f(60.0f, 0.0f, 0.0f)); - model = mat4_translate(model, v3f(-1.0f, 0.0f, 2.0f)); - shader_set_mat4fv(shader, "model", model); - mesh_draw(cube); -} - -void -render(State *state, Mesh *cube, Mesh *plane) +void render_scene(U32 shader, Mesh *cube, Mesh *plane) { - /* MAT4 projection, view, model; */ - MAT4 light_projection, light_view, model; - F32 near, far, fovx; - V3F target, up; - - if (shadows_ortho) - { - near = 1.0f; - far = 10.0f; - F32 half_side = 10.0f; - light_projection = ortho(-half_side, half_side, -half_side, half_side, near, far); - } - else - { - fovx = 90.0f; - near = 1.0f; - far = 50.0f; - light_projection = perspective(fovx, (F32)global_shadow_width/(F32)global_shadow_height, - near, far); - } - - target = v3f_zero(); - up = v3f(0.0f, 1.0f, 0.0f); - light_view = look_at(light_pos, target, up); - MAT4 light_space_matrix = mat4_mul(light_projection, light_view); - - glUseProgram(global_simple_depth_shader); - shader_set_mat4fv(global_simple_depth_shader, "light_space_matrix", light_space_matrix); - glViewport(0, 0, global_shadow_width, global_shadow_height); - glBindFramebuffer(GL_FRAMEBUFFER, global_depth_map_fbo); - glClear(GL_DEPTH_BUFFER_BIT); - // glCullFace(GL_FRONT); - render_scene(global_simple_depth_shader, cube, plane); - // glCullFace(GL_BACK); - glBindFramebuffer(GL_FRAMEBUFFER, 0); - - glViewport(0, 0, global_screen_width, global_screen_height); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - MAT4 projection = perspective(state->camera.fovx, (F32)global_screen_width/(F32)global_screen_height, - state->camera.near, state->camera.far); - MAT4 view = look_at(state->camera.pos, v3f_zero(), v3f(0.0f, 1.0f, 0.0f)); - glUseProgram(global_shadow_shader); - shader_set_mat4fv(global_shadow_shader, "projection", projection); - shader_set_mat4fv(global_shadow_shader, "view", view); - - shader_set_3fv(global_shadow_shader, "light_pos", light_pos); - shader_set_3fv(global_shadow_shader, "view_pos", state->camera.pos); - shader_set_mat4fv(global_shadow_shader, "light_space_matrix", light_space_matrix); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, global_wood_texture); - glActiveTexture(GL_TEXTURE1); - glBindTexture(GL_TEXTURE_2D, global_depth_map); - render_scene(global_shadow_shader, cube, plane); - - glUseProgram(global_color_shader); - shader_set_mat4fv(global_shadow_shader, "projection", projection); - shader_set_mat4fv(global_shadow_shader, "view", view); - model = mat4_make_scale(v3f(0.1f, 0.1f, 0.1f)); - model = mat4_translate(model, light_pos); - shader_set_mat4fv(global_shadow_shader, "model", model); - mesh_draw(cube); - - glDisable(GL_DEPTH_TEST); - glUseProgram(global_debug_quad_shader); - F32 scale = 0.3f; - Transform transform = transform_make_scale_translate(v3f(scale, scale, scale), - v3f(1.0f-scale, 1.0f-scale, 0.0f)); - model = transform_apply(transform); - shader_set_mat4fv(global_debug_quad_shader, "model", model); - shader_set_1f(global_debug_quad_shader, "near", near); - shader_set_1f(global_debug_quad_shader, "far", far); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, global_depth_map); - glBindVertexArray(global_quad_vao); - glDrawArrays(GL_TRIANGLES, 0, 6); - glBindVertexArray(0); - glEnable(GL_DEPTH_TEST); + MAT4 model; + + model = mat4_identity(); + shader_set_mat4fv(shader, "model", model); + mesh_draw(plane); + + /* + model = mat4_identity(); + model = mat4_make_scale(v3f(10.0f, 0.1f, 10.0f)); + model = mat4_translate(model, v3f(0.0f, -0.6f, 0.0f)); + shader_set_mat4fv(shader, "model", model); + mesh_draw(cube); + */ + + model = mat4_identity(); + model = mat4_make_scale(v3f(0.5f, 0.5f, 0.5f)); + model = mat4_translate(model, v3f(0.0f, 1.5f, 0.0f)); + shader_set_mat4fv(shader, "model", model); + mesh_draw(cube); + + model = mat4_identity(); + model = mat4_make_scale(v3f(0.5f, 0.5f, 0.5f)); + model = mat4_translate(model, v3f(2.0f, 0.0f, 1.0f)); + shader_set_mat4fv(shader, "model", model); + mesh_draw(cube); + + model = mat4_identity(); + model = mat4_make_scale(v3f(0.25f, 0.25f, 0.25f)); + model = mat4_rotate_angles(model, v3f(60.0f, 0.0f, 0.0f)); + model = mat4_translate(model, v3f(-1.0f, 0.0f, 2.0f)); + shader_set_mat4fv(shader, "model", model); + mesh_draw(cube); } -int -main(void) +int main(void) { - GLFWwindow *window; - Arena *arena; - State state; - Mesh *cube_mesh, *plane_mesh; - F64 time, last_time; - - glfwSetErrorCallback(error_callback); - - if (glfwInit() == GLFW_FALSE) - return(1); - - glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); - glfwWindowHint(GLFW_SAMPLES, 4); - window = glfwCreateWindow(global_screen_width, global_screen_height, "Shadow mapping", 0, 0); - if (!window) - goto error; - - glfwSetKeyCallback(window, glfw_key_callback); - glfwSetWindowSizeCallback(window, resize_callback); - - glfwMakeContextCurrent(window); - - if (glewInit() != GLEW_OK) - goto error; - - glEnable(GL_DEPTH_TEST); - // glEnable(GL_CULL_FACE); - - /* NOTE(pryazha): Init */ - arena = arena_alloc(Megabytes(64)); - - state.camera = (Camera){ v3f(0.0f, 1.0f, 3.0f), 90.0f, 0.1f, 100.0f }; - light_pos = v3f(-2.0f, 4.0f, -2.0f); - - /* NOTE(pryazha): Meshes */ - Vertex plane_vertices[] = { - // positions // normals // texcoords - vertex(v3f(-25.0f, -0.5f, 25.0f), v3f(0.0f, 1.0f, 0.0f), v2f(0.0f, 0.0f)), - vertex(v3f(25.0f, -0.5f, 25.0f), v3f(0.0f, 1.0f, 0.0f), v2f(25.0f, 0.0f)), - vertex(v3f(-25.0f, -0.5f, -25.0f), v3f(0.0f, 1.0f, 0.0f), v2f(0.0f, 25.0f)), - - vertex(v3f(25.0f, -0.5f, 25.0f), v3f(0.0f, 1.0f, 0.0f), v2f(25.0f, 0.0f)), - vertex(v3f(25.0f, -0.5f, -25.0f), v3f(0.0f, 1.0f, 0.0f), v2f(25.0f, 25.0f)), - vertex(v3f(-25.0f, -0.5f, -25.0f), v3f(0.0f, 1.0f, 0.0f), v2f(0.0f, 25.0f)), - }; - U32 indices[] = { 0, 1, 2, 3, 4, 5 }; - plane_mesh = mesh_init(arena, plane_vertices, ArrayCount(plane_vertices), indices, ArrayCount(indices)); - cube_mesh = mesh_load_obj(arena, "../../data/models/cube.obj"); - - F32 quad_vertices[] = { - -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, - 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, - 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, - -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, - 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, - -1.0f, 1.0f, 0.0f, 0.0f, 1.0f - }; - - U32 vbo; - glGenVertexArrays(1, &global_quad_vao); - glBindVertexArray(global_quad_vao); - glGenBuffers(1, &vbo); - glBindBuffer(GL_ARRAY_BUFFER, vbo); - glBufferData(GL_ARRAY_BUFFER, sizeof(quad_vertices), quad_vertices, GL_STATIC_DRAW); - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5*sizeof(F32), (void *)0); - glEnableVertexAttribArray(1); - glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5*sizeof(F32), (void *)(3*sizeof(F32))); - glBindVertexArray(0); - - /* NOTE(pryazha): Shaders */ - global_debug_quad_shader = create_shader_program("shaders/debug_quad.vs", - "shaders/debug_quad.fs"); - global_simple_depth_shader = create_shader_program("shaders/simple_depth.vs", - "shaders/simple_depth.fs"); - global_shadow_shader = create_shader_program("shaders/shadow.vs", "shaders/shadow.fs"); - global_color_shader = create_shader_program("shaders/color.vs", "shaders/color.fs"); - - glUseProgram(global_shadow_shader); - shader_set_1i(global_shadow_shader, "diffuse_texture", 0); - shader_set_1i(global_shadow_shader, "shadow_map", 1); - glUseProgram(0); - - global_wood_texture = load_texture_gamma("../../data/textures/wood.png", 1); - - glGenFramebuffers(1, &global_depth_map_fbo); - glGenTextures(1, &global_depth_map); - glBindTexture(GL_TEXTURE_2D, global_depth_map); - glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, global_shadow_width, - global_shadow_height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); - glBindFramebuffer(GL_FRAMEBUFFER, global_depth_map_fbo); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, - global_depth_map, 0); - V4F border_color = v4f(1.0f, 1.0f, 1.0f, 1.0f); - glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, (const F32 *)&border_color); - glDrawBuffer(GL_NONE); - glReadBuffer(GL_NONE); - if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) - fprintf(stderr, "[ERROR]: Failed to complete depth map framebuffer.\n"); - glBindFramebuffer(GL_FRAMEBUFFER, 0); - - last_time = glfwGetTime(); - - while (!glfwWindowShouldClose(window)) - { - glfwPollEvents(); - if (key_first_press(global_input.exit)) - glfwSetWindowShouldClose(window, GLFW_TRUE); - update(&state, time); - render(&state, cube_mesh, plane_mesh); - glfwSwapBuffers(window); - - time = glfwGetTime(); - state.dt = time-last_time; - last_time = time; -#if 0 - fprintf(stdout, "[INFO]: dt: %f\n", state.dt); -#endif - } - - glfwTerminate(); - return(0); - - error: - glfwTerminate(); - return(1); + GLFWwindow *window; + Arena *arena; + State state; + F64 time, last_time; + S32 screen_width = 800, screen_height = 600; + U32 shadow_width = 1024, shadow_height = 1024; + Input input; + U32 shadows_ortho = 1; + V3F light_pos = v3f(-2.0f, 4.0f, -2.0f); + + glfwSetErrorCallback(error_callback); + + if (glfwInit() == GLFW_FALSE) + return(1); + + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); + glfwWindowHint(GLFW_SAMPLES, 4); + window = glfwCreateWindow(screen_width, screen_height, "Shadow mapping", 0, 0); + if (!window) + goto error; + + glfwMakeContextCurrent(window); + + if (glewInit() != GLEW_OK) + goto error; + + glEnable(GL_DEPTH_TEST); + // glEnable(GL_CULL_FACE); + + /* NOTE(pryazha): Init */ + arena = arena_alloc(Megabytes(64)); + + state.camera = (Camera){ v3f(0.0f, 1.0f, 3.0f), 90.0f, 0.1f, 100.0f, 0.0f, 0.0f }; + + /* NOTE(pryazha): Meshes */ + Vertex plane_vertices[] = { + // positions // normals // texcoords + vertex(v3f(-25.0f, -0.5f, 25.0f), v3f(0.0f, 1.0f, 0.0f), v2f( 0.0f, 0.0f)), + vertex(v3f( 25.0f, -0.5f, 25.0f), v3f(0.0f, 1.0f, 0.0f), v2f(25.0f, 0.0f)), + vertex(v3f(-25.0f, -0.5f, -25.0f), v3f(0.0f, 1.0f, 0.0f), v2f( 0.0f, 25.0f)), + + vertex(v3f( 25.0f, -0.5f, 25.0f), v3f(0.0f, 1.0f, 0.0f), v2f(25.0f, 0.0f)), + vertex(v3f( 25.0f, -0.5f, -25.0f), v3f(0.0f, 1.0f, 0.0f), v2f(25.0f, 25.0f)), + vertex(v3f(-25.0f, -0.5f, -25.0f), v3f(0.0f, 1.0f, 0.0f), v2f( 0.0f, 25.0f)), + }; + U32 indices[] = { 0, 1, 2, 3, 4, 5 }; + Mesh *plane = mesh_init(arena, plane_vertices, ArrayCount(plane_vertices), + indices, ArrayCount(indices)); + Mesh *cube = mesh_load_obj(arena, "../../data/models/cube.obj"); + + F32 quad_vertices[] = { + -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, + 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, + -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, + 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, + -1.0f, 1.0f, 0.0f, 0.0f, 1.0f + }; + + U32 quad_vao, vbo; + glGenVertexArrays(1, &quad_vao); + glBindVertexArray(quad_vao); + glGenBuffers(1, &vbo); + glBindBuffer(GL_ARRAY_BUFFER, vbo); + glBufferData(GL_ARRAY_BUFFER, sizeof(quad_vertices), quad_vertices, GL_STATIC_DRAW); + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5*sizeof(F32), (void *)0); + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5*sizeof(F32), (void *)(3*sizeof(F32))); + glBindVertexArray(0); + + /* NOTE(pryazha): Shaders */ + U32 debug_quad_shader = create_shader_program("shaders/debug_quad.vert", + "shaders/debug_quad.frag"); + U32 simple_depth_shader = create_shader_program("shaders/simple_depth.vert", + "shaders/simple_depth.frag"); + U32 shadow_shader = create_shader_program("shaders/shadow.vert", + "shaders/shadow.frag"); + U32 color_shader = create_shader_program("shaders/color.vert", + "shaders/color.frag"); + + glUseProgram(shadow_shader); + shader_set_1i(shadow_shader, "diffuse_texture", 0); + shader_set_1i(shadow_shader, "shadow_map", 1); + glUseProgram(0); + + U32 wood_texture = load_texture_gamma("../../data/textures/wood.png", 1); + + U32 depth_map_fbo, depth_map; + glGenFramebuffers(1, &depth_map_fbo); + glGenTextures(1, &depth_map); + glBindTexture(GL_TEXTURE_2D, depth_map); + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, shadow_width, + shadow_height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); + glBindFramebuffer(GL_FRAMEBUFFER, depth_map_fbo); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, + depth_map, 0); + V4F border_color = v4f(1.0f, 1.0f, 1.0f, 1.0f); + glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, (const F32 *)&border_color); + glDrawBuffer(GL_NONE); + glReadBuffer(GL_NONE); + if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) + fprintf(stderr, "[ERROR]: Failed to complete depth map framebuffer.\n"); + glBindFramebuffer(GL_FRAMEBUFFER, 0); + + last_time = glfwGetTime(); + + while (!glfwWindowShouldClose(window)) { + glfwPollEvents(); + + /* NOTE(pryazha): Update */ + process_glfw_keyboard(window, &input); + glfwGetFramebufferSize(window, &screen_width, &screen_height); + + V3F target = v3f_zero(); + + if (key_first_press(input.exit)) + glfwSetWindowShouldClose(window, GLFW_TRUE); + + V3F dv = get_dv_camera_orbital(&input, state.camera.pos, + target, state.dt, 3.0f); + state.camera.pos = v3f_add(state.camera.pos, dv); + + if (key_first_press(input.action_down)) + shadows_ortho = !shadows_ortho; + + input_update_last_state(&input); + + F32 radius, angular_speed, x, z; + + angular_speed = 1.0f; + radius = 4.0f; + x = f32_sin(time*angular_speed)*radius; + z = f32_cos(time*angular_speed)*radius; + + light_pos = v3f(x, 4.0f, z); + + /* NOTE(pryazha): Render */ + MAT4 proj, view, model, light_proj; + F32 fovx, near, far; + + if (shadows_ortho) { + near = 1.0f; + far = 10.0f; + F32 half_side = 10.0f; + light_proj = ortho(-half_side, half_side, -half_side, half_side, near, far); + } else { + fovx = 90.0f; + near = 1.0f; + far = 50.0f; + light_proj = perspective(fovx, (F32)shadow_width/(F32)shadow_height, + near, far); + } + + V3F up = v3f(0.0f, 1.0f, 0.0f); + MAT4 light_view = look_at(light_pos, target, up); + MAT4 light_space_matrix = mat4_mul(light_proj, light_view); + + glUseProgram(simple_depth_shader); + shader_set_mat4fv(simple_depth_shader, "light_space_matrix", light_space_matrix); + glViewport(0, 0, shadow_width, shadow_height); + glBindFramebuffer(GL_FRAMEBUFFER, depth_map_fbo); + glClear(GL_DEPTH_BUFFER_BIT); + // glCullFace(GL_FRONT); + render_scene(simple_depth_shader, cube, plane); + // glCullFace(GL_BACK); + glBindFramebuffer(GL_FRAMEBUFFER, 0); + + glViewport(0, 0, screen_width, screen_height); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + proj = perspective(state.camera.fovx, (F32)screen_width/(F32)screen_height, + state.camera.near, state.camera.far); + view = look_at(state.camera.pos, v3f_zero(), v3f(0.0f, 1.0f, 0.0f)); + + glUseProgram(shadow_shader); + shader_set_mat4fv(shadow_shader, "proj", proj); + shader_set_mat4fv(shadow_shader, "view", view); + shader_set_3fv(shadow_shader, "light_pos", light_pos); + shader_set_3fv(shadow_shader, "view_pos", state.camera.pos); + shader_set_mat4fv(shadow_shader, "light_space_matrix", light_space_matrix); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, wood_texture); + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, depth_map); + render_scene(shadow_shader, cube, plane); + + glUseProgram(color_shader); + shader_set_mat4fv(shadow_shader, "proj", proj); + shader_set_mat4fv(shadow_shader, "view", view); + model = mat4_make_scale(v3f(0.1f, 0.1f, 0.1f)); + model = mat4_translate(model, light_pos); + shader_set_mat4fv(shadow_shader, "model", model); + mesh_draw(cube); + + glDisable(GL_DEPTH_TEST); + glUseProgram(debug_quad_shader); + F32 scale = 0.3f; + Transform transform = transform_make_scale_translate(v3f(scale, scale, scale), + v3f(1.0f-scale, 1.0f-scale, 0.0f)); + model = transform_apply(transform); + shader_set_mat4fv(debug_quad_shader, "model", model); + shader_set_1f(debug_quad_shader, "near", near); + shader_set_1f(debug_quad_shader, "far", far); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, depth_map); + glBindVertexArray(quad_vao); + glDrawArrays(GL_TRIANGLES, 0, 6); + glBindVertexArray(0); + glEnable(GL_DEPTH_TEST); + glfwSwapBuffers(window); + + time = glfwGetTime(); + state.dt = time-last_time; + last_time = time; + } + + glfwTerminate(); + return(0); + +error: + glfwTerminate(); + return(1); } |