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 | |
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')
-rwxr-xr-x | advanced_lighting/3.1.shadow_mapping/build.sh | 2 | ||||
-rw-r--r-- | advanced_lighting/3.1.shadow_mapping/shaders/color.frag (renamed from advanced_lighting/3.1.shadow_mapping/shaders/color.fs) | 3 | ||||
-rw-r--r-- | advanced_lighting/3.1.shadow_mapping/shaders/color.vert (renamed from advanced_lighting/3.1.shadow_mapping/shaders/color.vs) | 7 | ||||
-rw-r--r-- | advanced_lighting/3.1.shadow_mapping/shaders/debug_quad.frag (renamed from advanced_lighting/3.1.shadow_mapping/shaders/debug_quad.fs) | 6 | ||||
-rw-r--r-- | advanced_lighting/3.1.shadow_mapping/shaders/debug_quad.vert (renamed from advanced_lighting/3.1.shadow_mapping/shaders/debug_quad.vs) | 0 | ||||
-rw-r--r-- | advanced_lighting/3.1.shadow_mapping/shaders/shadow.frag (renamed from advanced_lighting/3.1.shadow_mapping/shaders/shadow.fs) | 6 | ||||
-rw-r--r-- | advanced_lighting/3.1.shadow_mapping/shaders/shadow.vert (renamed from advanced_lighting/3.1.shadow_mapping/shaders/shadow.vs) | 7 | ||||
-rw-r--r-- | advanced_lighting/3.1.shadow_mapping/shaders/simple_depth.frag (renamed from advanced_lighting/3.1.shadow_mapping/shaders/simple_depth.fs) | 3 | ||||
-rw-r--r-- | advanced_lighting/3.1.shadow_mapping/shaders/simple_depth.vert (renamed from advanced_lighting/3.1.shadow_mapping/shaders/simple_depth.vs) | 3 | ||||
-rw-r--r-- | advanced_lighting/3.1.shadow_mapping/shadow_mapping.c | 668 |
10 files changed, 277 insertions, 428 deletions
diff --git a/advanced_lighting/3.1.shadow_mapping/build.sh b/advanced_lighting/3.1.shadow_mapping/build.sh index bba445d..79ca088 100755 --- a/advanced_lighting/3.1.shadow_mapping/build.sh +++ b/advanced_lighting/3.1.shadow_mapping/build.sh @@ -2,4 +2,4 @@ . ../../config TARGET='shadow_mapping' set -x -gcc -o $TARGET $CFLAGS $INCLUDE $LFLAGS $TARGET.c $LIBS +gcc -o $TARGET $CFLAGS $INCLUDE $LFLAGS $TARGET.c $LIBS && ./$TARGET diff --git a/advanced_lighting/3.1.shadow_mapping/shaders/color.fs b/advanced_lighting/3.1.shadow_mapping/shaders/color.frag index bd00d82..c01da99 100644 --- a/advanced_lighting/3.1.shadow_mapping/shaders/color.fs +++ b/advanced_lighting/3.1.shadow_mapping/shaders/color.frag @@ -2,8 +2,7 @@ out vec4 frag_color; -void -main(void) +void main(void) { frag_color = vec4(1.0); } diff --git a/advanced_lighting/3.1.shadow_mapping/shaders/color.vs b/advanced_lighting/3.1.shadow_mapping/shaders/color.vert index ade669b..6aa621e 100644 --- a/advanced_lighting/3.1.shadow_mapping/shaders/color.vs +++ b/advanced_lighting/3.1.shadow_mapping/shaders/color.vert @@ -1,12 +1,11 @@ #version 330 core layout(location = 0) in vec3 apos; -uniform mat4 projection; +uniform mat4 proj; uniform mat4 view; uniform mat4 model; -void -main(void) +void main(void) { - gl_Position = projection*view*model*vec4(apos, 1.0); + gl_Position = proj * view * model * vec4(apos, 1.0); } diff --git a/advanced_lighting/3.1.shadow_mapping/shaders/debug_quad.fs b/advanced_lighting/3.1.shadow_mapping/shaders/debug_quad.frag index d250894..4cb6df1 100644 --- a/advanced_lighting/3.1.shadow_mapping/shaders/debug_quad.fs +++ b/advanced_lighting/3.1.shadow_mapping/shaders/debug_quad.frag @@ -8,15 +8,13 @@ uniform sampler2D depth_map; uniform float near; uniform float far; -float -linearize_depth(float depth) +float linearize_depth(float depth) { float z = (depth+1.0)*0.5; return((2.0*near*far)/(far+near-z*(far-near))); } -void -main(void) +void main(void) { float depth = texture(depth_map, tex_coords).r; diff --git a/advanced_lighting/3.1.shadow_mapping/shaders/debug_quad.vs b/advanced_lighting/3.1.shadow_mapping/shaders/debug_quad.vert index 5717608..5717608 100644 --- a/advanced_lighting/3.1.shadow_mapping/shaders/debug_quad.vs +++ b/advanced_lighting/3.1.shadow_mapping/shaders/debug_quad.vert diff --git a/advanced_lighting/3.1.shadow_mapping/shaders/shadow.fs b/advanced_lighting/3.1.shadow_mapping/shaders/shadow.frag index 1c7018a..3403d1d 100644 --- a/advanced_lighting/3.1.shadow_mapping/shaders/shadow.fs +++ b/advanced_lighting/3.1.shadow_mapping/shaders/shadow.frag @@ -15,8 +15,7 @@ uniform vec3 view_pos; uniform sampler2D diffuse_texture; uniform sampler2D shadow_map; -float -calculate_shadow() +float calculate_shadow() { vec3 proj_coords = fs_in.frag_pos_light_space.xyz/fs_in.frag_pos_light_space.w; proj_coords = proj_coords*0.5+0.5; @@ -43,8 +42,7 @@ calculate_shadow() return(shadow); } -void -main(void) +void main(void) { vec3 color = texture(diffuse_texture, fs_in.tex_coords).rgb; vec3 normal = normalize(fs_in.normal); diff --git a/advanced_lighting/3.1.shadow_mapping/shaders/shadow.vs b/advanced_lighting/3.1.shadow_mapping/shaders/shadow.vert index 3ecd5b1..3f14663 100644 --- a/advanced_lighting/3.1.shadow_mapping/shaders/shadow.vs +++ b/advanced_lighting/3.1.shadow_mapping/shaders/shadow.vert @@ -10,17 +10,16 @@ out VS_OUT { vec2 tex_coords; } vs_out; -uniform mat4 projection; +uniform mat4 proj; uniform mat4 view; uniform mat4 model; uniform mat4 light_space_matrix; -void -main(void) +void main(void) { vs_out.frag_pos = vec3(model*vec4(apos, 1.0)); vs_out.frag_pos_light_space = light_space_matrix*vec4(vs_out.frag_pos, 1.0); vs_out.normal = mat3(transpose(inverse(model)))*anormal; vs_out.tex_coords = atex_coords; - gl_Position = projection*view*vec4(vs_out.frag_pos, 1.0); + gl_Position = proj*view*vec4(vs_out.frag_pos, 1.0); } diff --git a/advanced_lighting/3.1.shadow_mapping/shaders/simple_depth.fs b/advanced_lighting/3.1.shadow_mapping/shaders/simple_depth.frag index 16b9908..d99aab2 100644 --- a/advanced_lighting/3.1.shadow_mapping/shaders/simple_depth.fs +++ b/advanced_lighting/3.1.shadow_mapping/shaders/simple_depth.frag @@ -1,6 +1,5 @@ #version 330 core -void -main(void) +void main(void) { } diff --git a/advanced_lighting/3.1.shadow_mapping/shaders/simple_depth.vs b/advanced_lighting/3.1.shadow_mapping/shaders/simple_depth.vert index b9752ed..d3adca9 100644 --- a/advanced_lighting/3.1.shadow_mapping/shaders/simple_depth.vs +++ b/advanced_lighting/3.1.shadow_mapping/shaders/simple_depth.vert @@ -4,8 +4,7 @@ layout(location = 0) in vec3 apos; uniform mat4 light_space_matrix; uniform mat4 model; -void -main(void) +void main(void) { gl_Position = light_space_matrix*model*vec4(apos, 1.0); } 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); } |