From 9d944f26d359e4bc1ffd8e44350b0df9f0935b18 Mon Sep 17 00:00:00 2001 From: pryazha Date: Sun, 15 Jun 2025 16:11:31 +0500 Subject: something --- advanced_lighting/1.blinn_phong/blinn_phong.c | 5 +- advanced_lighting/1.blinn_phong/build | 5 + advanced_lighting/1.blinn_phong/build.sh | 5 - advanced_lighting/2.gamma_correction/build | 5 + advanced_lighting/2.gamma_correction/build.sh | 5 - .../2.gamma_correction/gamma_correction.c | 4 +- advanced_lighting/3.1.shadow_mapping/build | 5 + advanced_lighting/3.1.shadow_mapping/build.sh | 5 - .../3.1.shadow_mapping/shadow_mapping.c | 12 +- advanced_lighting/3.2.point_shadows/build | 5 + advanced_lighting/3.2.point_shadows/build.sh | 5 - .../3.2.point_shadows/point_shadows.c | 481 ++++++++++----------- advanced_lighting/4.normal_mapping/build | 5 + advanced_lighting/4.normal_mapping/build.sh | 5 - .../4.normal_mapping/normal_mapping.c | 10 +- advanced_lighting/5.parallax_mapping/build | 5 + advanced_lighting/5.parallax_mapping/build.sh | 5 - .../5.parallax_mapping/parallax_mapping.c | 6 +- advanced_lighting/6.hdr/build | 5 + advanced_lighting/6.hdr/build.sh | 5 - advanced_lighting/6.hdr/hdr.c | 86 ++-- advanced_lighting/7.bloom/bloom.c | 287 ++++++++++++ advanced_lighting/7.bloom/build | 5 + advanced_lighting/7.bloom/shaders/bloom.frag | 45 ++ advanced_lighting/7.bloom/shaders/bloom.vert | 24 + advanced_lighting/7.bloom/shaders/blur.frag | 29 ++ advanced_lighting/7.bloom/shaders/blur.vert | 14 + advanced_lighting/7.bloom/shaders/final.frag | 25 ++ advanced_lighting/7.bloom/shaders/final.vert | 14 + advanced_lighting/7.bloom/shaders/light.frag | 22 + advanced_lighting/7.bloom/shaders/test_blur.frag | 28 ++ advanced_lighting/7.bloom/shaders/test_blur.vert | 14 + advanced_lighting/8.deferred_shading/build | 5 + advanced_lighting/8.deferred_shading/deferred.c | 274 ++++++++++++ .../8.deferred_shading/shaders/deferred.frag | 46 ++ .../8.deferred_shading/shaders/gbuffer.frag | 23 + .../8.deferred_shading/shaders/gbuffer.vert | 24 + .../8.deferred_shading/shaders/light.frag | 11 + .../8.deferred_shading/shaders/light.vert | 12 + .../8.deferred_shading/shaders/screen.frag | 14 + .../8.deferred_shading/shaders/screen.vert | 16 + .../8.deferred_shading/shaders/specular.frag | 14 + advanced_lighting/9.ssao/build | 5 + advanced_lighting/9.ssao/deferred.frag | 44 ++ advanced_lighting/9.ssao/deferred.vert | 16 + advanced_lighting/9.ssao/gbuffer.frag | 17 + advanced_lighting/9.ssao/gbuffer.vert | 21 + advanced_lighting/9.ssao/occlusion.frag | 14 + advanced_lighting/9.ssao/screen.frag | 14 + advanced_lighting/9.ssao/screen.vert | 16 + advanced_lighting/9.ssao/ssao | Bin 0 -> 1291232 bytes advanced_lighting/9.ssao/ssao.c | 331 ++++++++++++++ advanced_lighting/9.ssao/ssao.frag | 45 ++ advanced_lighting/9.ssao/ssao.vert | 16 + advanced_lighting/9.ssao/xoshiro128plus.c | 28 ++ advanced_lighting/build | 9 + advanced_lighting/build.sh | 9 - advanced_opengl/1.depth/build | 5 + advanced_opengl/1.depth/build.sh | 5 - advanced_opengl/1.depth/depth.c | 340 +++++++-------- .../10.antialiasing/anti_aliasing_msaa.c | 9 +- .../10.antialiasing/anti_aliasing_offscreen.c | 7 +- advanced_opengl/10.antialiasing/build | 5 + advanced_opengl/10.antialiasing/build.sh | 5 - advanced_opengl/2.stencil/build | 5 + advanced_opengl/2.stencil/build.sh | 5 - advanced_opengl/2.stencil/stencil.c | 4 +- advanced_opengl/3.blending/blending.c | 4 +- advanced_opengl/3.blending/build | 5 + advanced_opengl/3.blending/build.sh | 5 - advanced_opengl/4.face_culling/build | 5 + advanced_opengl/4.face_culling/build.sh | 5 - advanced_opengl/4.face_culling/face_culling.c | 3 +- advanced_opengl/5.framebuffers/build | 5 + advanced_opengl/5.framebuffers/build.sh | 5 - advanced_opengl/5.framebuffers/framebuffers.c | 16 +- advanced_opengl/6.cubemaps/build | 5 + advanced_opengl/6.cubemaps/build.sh | 5 - advanced_opengl/6.cubemaps/cubemaps.c | 9 +- advanced_opengl/7.uniform_buffer/build | 5 + advanced_opengl/7.uniform_buffer/build.sh | 5 - advanced_opengl/7.uniform_buffer/uniform_buffer.c | 13 +- advanced_opengl/8.geometry_shader/build | 5 + advanced_opengl/8.geometry_shader/build.sh | 5 - .../8.geometry_shader/geometry_shader.c | 16 +- advanced_opengl/9.instancing/build | 6 + advanced_opengl/9.instancing/build.sh | 6 - advanced_opengl/9.instancing/instancing.c | 9 +- advanced_opengl/build | 9 + advanced_opengl/build.sh | 9 - libs/common.h | 187 ++++---- libs/pwyazh/v3f.h | 7 + 92 files changed, 2196 insertions(+), 753 deletions(-) create mode 100755 advanced_lighting/1.blinn_phong/build delete mode 100755 advanced_lighting/1.blinn_phong/build.sh create mode 100755 advanced_lighting/2.gamma_correction/build delete mode 100755 advanced_lighting/2.gamma_correction/build.sh create mode 100755 advanced_lighting/3.1.shadow_mapping/build delete mode 100755 advanced_lighting/3.1.shadow_mapping/build.sh create mode 100755 advanced_lighting/3.2.point_shadows/build delete mode 100755 advanced_lighting/3.2.point_shadows/build.sh create mode 100755 advanced_lighting/4.normal_mapping/build delete mode 100755 advanced_lighting/4.normal_mapping/build.sh create mode 100755 advanced_lighting/5.parallax_mapping/build delete mode 100755 advanced_lighting/5.parallax_mapping/build.sh create mode 100755 advanced_lighting/6.hdr/build delete mode 100755 advanced_lighting/6.hdr/build.sh create mode 100644 advanced_lighting/7.bloom/bloom.c create mode 100755 advanced_lighting/7.bloom/build create mode 100644 advanced_lighting/7.bloom/shaders/bloom.frag create mode 100644 advanced_lighting/7.bloom/shaders/bloom.vert create mode 100644 advanced_lighting/7.bloom/shaders/blur.frag create mode 100644 advanced_lighting/7.bloom/shaders/blur.vert create mode 100644 advanced_lighting/7.bloom/shaders/final.frag create mode 100644 advanced_lighting/7.bloom/shaders/final.vert create mode 100644 advanced_lighting/7.bloom/shaders/light.frag create mode 100644 advanced_lighting/7.bloom/shaders/test_blur.frag create mode 100644 advanced_lighting/7.bloom/shaders/test_blur.vert create mode 100755 advanced_lighting/8.deferred_shading/build create mode 100644 advanced_lighting/8.deferred_shading/deferred.c create mode 100644 advanced_lighting/8.deferred_shading/shaders/deferred.frag create mode 100644 advanced_lighting/8.deferred_shading/shaders/gbuffer.frag create mode 100644 advanced_lighting/8.deferred_shading/shaders/gbuffer.vert create mode 100644 advanced_lighting/8.deferred_shading/shaders/light.frag create mode 100644 advanced_lighting/8.deferred_shading/shaders/light.vert create mode 100644 advanced_lighting/8.deferred_shading/shaders/screen.frag create mode 100644 advanced_lighting/8.deferred_shading/shaders/screen.vert create mode 100644 advanced_lighting/8.deferred_shading/shaders/specular.frag create mode 100755 advanced_lighting/9.ssao/build create mode 100644 advanced_lighting/9.ssao/deferred.frag create mode 100644 advanced_lighting/9.ssao/deferred.vert create mode 100644 advanced_lighting/9.ssao/gbuffer.frag create mode 100644 advanced_lighting/9.ssao/gbuffer.vert create mode 100644 advanced_lighting/9.ssao/occlusion.frag create mode 100644 advanced_lighting/9.ssao/screen.frag create mode 100644 advanced_lighting/9.ssao/screen.vert create mode 100755 advanced_lighting/9.ssao/ssao create mode 100644 advanced_lighting/9.ssao/ssao.c create mode 100644 advanced_lighting/9.ssao/ssao.frag create mode 100644 advanced_lighting/9.ssao/ssao.vert create mode 100644 advanced_lighting/9.ssao/xoshiro128plus.c create mode 100755 advanced_lighting/build delete mode 100755 advanced_lighting/build.sh create mode 100755 advanced_opengl/1.depth/build delete mode 100755 advanced_opengl/1.depth/build.sh create mode 100755 advanced_opengl/10.antialiasing/build delete mode 100755 advanced_opengl/10.antialiasing/build.sh create mode 100755 advanced_opengl/2.stencil/build delete mode 100755 advanced_opengl/2.stencil/build.sh create mode 100755 advanced_opengl/3.blending/build delete mode 100755 advanced_opengl/3.blending/build.sh create mode 100755 advanced_opengl/4.face_culling/build delete mode 100755 advanced_opengl/4.face_culling/build.sh create mode 100755 advanced_opengl/5.framebuffers/build delete mode 100755 advanced_opengl/5.framebuffers/build.sh create mode 100755 advanced_opengl/6.cubemaps/build delete mode 100755 advanced_opengl/6.cubemaps/build.sh create mode 100755 advanced_opengl/7.uniform_buffer/build delete mode 100755 advanced_opengl/7.uniform_buffer/build.sh create mode 100755 advanced_opengl/8.geometry_shader/build delete mode 100755 advanced_opengl/8.geometry_shader/build.sh create mode 100755 advanced_opengl/9.instancing/build delete mode 100755 advanced_opengl/9.instancing/build.sh create mode 100755 advanced_opengl/build delete mode 100755 advanced_opengl/build.sh diff --git a/advanced_lighting/1.blinn_phong/blinn_phong.c b/advanced_lighting/1.blinn_phong/blinn_phong.c index 404df05..3974243 100644 --- a/advanced_lighting/1.blinn_phong/blinn_phong.c +++ b/advanced_lighting/1.blinn_phong/blinn_phong.c @@ -28,6 +28,7 @@ int main(void) glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); + glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE); glfwWindowHint(GLFW_SAMPLES, 4); window = glfwCreateWindow(width, height, "Blinn-Phong shading", 0, 0); if (!window) @@ -60,8 +61,8 @@ int main(void) Mesh *quad = mesh_init(arena, vertices, 6, indices, 6); Mesh *cube = mesh_load_obj(arena, "../../data/models/cube.obj"); - U32 blinn_phong_shader = create_shader_program("shaders/blinn_phong.vert", "shaders/blinn_phong.frag"); - U32 light_shader = create_shader_program("shaders/light.vert", "shaders/light.frag"); + U32 blinn_phong_shader = load_shader("shaders/blinn_phong.vert", "shaders/blinn_phong.frag"); + U32 light_shader = load_shader("shaders/light.vert", "shaders/light.frag"); texture = load_texture("../../data/textures/wood.png"); diff --git a/advanced_lighting/1.blinn_phong/build b/advanced_lighting/1.blinn_phong/build new file mode 100755 index 0000000..41fb831 --- /dev/null +++ b/advanced_lighting/1.blinn_phong/build @@ -0,0 +1,5 @@ +#!/bin/sh +. ../../config +TARGET='blinn_phong' +set -x +gcc -o $TARGET $CFLAGS $INCLUDE $LFLAGS $TARGET.c $LIBS diff --git a/advanced_lighting/1.blinn_phong/build.sh b/advanced_lighting/1.blinn_phong/build.sh deleted file mode 100755 index 41fb831..0000000 --- a/advanced_lighting/1.blinn_phong/build.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh -. ../../config -TARGET='blinn_phong' -set -x -gcc -o $TARGET $CFLAGS $INCLUDE $LFLAGS $TARGET.c $LIBS diff --git a/advanced_lighting/2.gamma_correction/build b/advanced_lighting/2.gamma_correction/build new file mode 100755 index 0000000..2b65776 --- /dev/null +++ b/advanced_lighting/2.gamma_correction/build @@ -0,0 +1,5 @@ +#!/bin/sh +. ../../config +TARGET='gamma_correction' +set -x +gcc -o $TARGET $CFLAGS $INCLUDE $LFLAGS $TARGET.c $LIBS diff --git a/advanced_lighting/2.gamma_correction/build.sh b/advanced_lighting/2.gamma_correction/build.sh deleted file mode 100755 index 2b65776..0000000 --- a/advanced_lighting/2.gamma_correction/build.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh -. ../../config -TARGET='gamma_correction' -set -x -gcc -o $TARGET $CFLAGS $INCLUDE $LFLAGS $TARGET.c $LIBS diff --git a/advanced_lighting/2.gamma_correction/gamma_correction.c b/advanced_lighting/2.gamma_correction/gamma_correction.c index a027722..65d1d58 100644 --- a/advanced_lighting/2.gamma_correction/gamma_correction.c +++ b/advanced_lighting/2.gamma_correction/gamma_correction.c @@ -77,8 +77,8 @@ int main(void) Mesh *quad = mesh_init(arena, vertices, 6, indices, 6); Mesh *cube = mesh_load_obj(arena, "../../data/models/cube.obj"); - U32 blinn_phong_shader = create_shader_program("shaders/blinn_phong.vert", "shaders/blinn_phong.frag"); - U32 light_shader = create_shader_program("shaders/light.vert", "shaders/light.frag"); + U32 blinn_phong_shader = load_shader("shaders/blinn_phong.vert", "shaders/blinn_phong.frag"); + U32 light_shader = load_shader("shaders/light.vert", "shaders/light.frag"); U32 texture = load_texture_gamma("../../data/textures/wood.png", 0); U32 texture_gamma_corrected = load_texture_gamma("../../data/textures/wood.png", 1); diff --git a/advanced_lighting/3.1.shadow_mapping/build b/advanced_lighting/3.1.shadow_mapping/build new file mode 100755 index 0000000..bba445d --- /dev/null +++ b/advanced_lighting/3.1.shadow_mapping/build @@ -0,0 +1,5 @@ +#!/bin/sh +. ../../config +TARGET='shadow_mapping' +set -x +gcc -o $TARGET $CFLAGS $INCLUDE $LFLAGS $TARGET.c $LIBS diff --git a/advanced_lighting/3.1.shadow_mapping/build.sh b/advanced_lighting/3.1.shadow_mapping/build.sh deleted file mode 100755 index bba445d..0000000 --- a/advanced_lighting/3.1.shadow_mapping/build.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh -. ../../config -TARGET='shadow_mapping' -set -x -gcc -o $TARGET $CFLAGS $INCLUDE $LFLAGS $TARGET.c $LIBS diff --git a/advanced_lighting/3.1.shadow_mapping/shadow_mapping.c b/advanced_lighting/3.1.shadow_mapping/shadow_mapping.c index fd03ed9..f691035 100644 --- a/advanced_lighting/3.1.shadow_mapping/shadow_mapping.c +++ b/advanced_lighting/3.1.shadow_mapping/shadow_mapping.c @@ -117,14 +117,10 @@ int main(void) 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"); + U32 debug_quad_shader = load_shader("shaders/debug_quad.vert", "shaders/debug_quad.frag"); + U32 simple_depth_shader = load_shader("shaders/simple_depth.vert", "shaders/simple_depth.frag"); + U32 shadow_shader = load_shader("shaders/shadow.vert", "shaders/shadow.frag"); + U32 color_shader = load_shader("shaders/color.vert", "shaders/color.frag"); glUseProgram(shadow_shader); shader_set_1i(shadow_shader, "diffuse_texture", 0); diff --git a/advanced_lighting/3.2.point_shadows/build b/advanced_lighting/3.2.point_shadows/build new file mode 100755 index 0000000..bf934b6 --- /dev/null +++ b/advanced_lighting/3.2.point_shadows/build @@ -0,0 +1,5 @@ +#!/bin/sh +. ../../config +TARGET='point_shadows' +set -x +gcc -o $TARGET $CFLAGS $INCLUDE $LFLAGS $TARGET.c $LIBS diff --git a/advanced_lighting/3.2.point_shadows/build.sh b/advanced_lighting/3.2.point_shadows/build.sh deleted file mode 100755 index bf934b6..0000000 --- a/advanced_lighting/3.2.point_shadows/build.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh -. ../../config -TARGET='point_shadows' -set -x -gcc -o $TARGET $CFLAGS $INCLUDE $LFLAGS $TARGET.c $LIBS diff --git a/advanced_lighting/3.2.point_shadows/point_shadows.c b/advanced_lighting/3.2.point_shadows/point_shadows.c index e622f6c..8989bff 100644 --- a/advanced_lighting/3.2.point_shadows/point_shadows.c +++ b/advanced_lighting/3.2.point_shadows/point_shadows.c @@ -8,254 +8,247 @@ void render_scene(U32 shader, Mesh *cube) { - MAT4 model; - - model = mat4_identity(); - model = mat4_make_scale(v3f(5.0f, 5.0f, 5.0f)); - shader_set_mat4fv(shader, "model", model); - glDisable(GL_CULL_FACE); - shader_set_1i(shader, "reverse_normals", 1); - mesh_draw(cube); - shader_set_1i(shader, "reverse_normals", 0); - glEnable(GL_CULL_FACE); - - 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); + MAT4 model; + + model = mat4_identity(); + model = mat4_make_scale(v3f(5.0f, 5.0f, 5.0f)); + shader_set_mat4fv(shader, "model", model); + glDisable(GL_CULL_FACE); + shader_set_1i(shader, "reverse_normals", 1); + mesh_draw(cube); + shader_set_1i(shader, "reverse_normals", 0); + glEnable(GL_CULL_FACE); + + 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) { - GLFWwindow *window; - Arena *arena; - State state; - Input input; - F64 time, last_time; - V3F light_pos; - MAT4 shadow_transforms[6]; - MAT4 proj, view; - S32 screen_width, screen_height; - - glfwSetErrorCallback(error_callback); - - if (glfwInit() == GLFW_FALSE) - return(1); - - screen_width = 800; - screen_height = 600; - - glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); - glfwWindowHint(GLFW_SAMPLES, 4); - window = glfwCreateWindow(screen_width, screen_height, "Point shadows", 0, 0); - if (!window) - goto error; - - glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); - - 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){ - .pos = v3f(0.0f, 1.0f, 3.0f), - .fovx = 100.0f, - .near = 0.1f, - .far = 100.0f, - .yaw = 0.0f, - .pitch = 0.0f - }; - V3F camera_dp = v3f_zero(); - /* light_pos = v3f(-2.0f, 4.0f, -2.0f); */ - light_pos = v3f_zero(); - - /* NOTE(pryazha): Meshes */ - 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 depth_shader = create_shader_program_geom("shaders/depth.vert", - "shaders/depth.frag", - "shaders/depth.geom"); - U32 shadow_shader = create_shader_program("shaders/shadow.vert", - "shaders/shadow.frag"); - - glUseProgram(shadow_shader); - shader_set_1i(shadow_shader, "diffuse_texture", 0); - shader_set_1i(shadow_shader, "depth_cubemap", 1); - glUseProgram(0); - - U32 wood_texture = load_texture_gamma("../../data/textures/wood.png", 0); - - /* NOTE(pryazha): Depth framebuffer init */ - U32 depth_cubemap_fbo, depth_cubemap; - U32 shadow_width = 1024, shadow_height = 1024; - glGenFramebuffers(1, &depth_cubemap_fbo); - glGenTextures(1, &depth_cubemap); - glBindTexture(GL_TEXTURE_CUBE_MAP, depth_cubemap); - for (U32 cubemap_side = 0; cubemap_side < 6; ++cubemap_side) - glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X+cubemap_side, 0, GL_DEPTH_COMPONENT, - shadow_width, shadow_height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0); - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_BORDER); - glBindFramebuffer(GL_FRAMEBUFFER, depth_cubemap_fbo); - glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depth_cubemap, 0); - 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): For now it's easier to write all of the logic in the main loop */ - /* NOTE(pryazha): Update */ - F32 x, y, z, angular_speed, radius; - - glfwGetFramebufferSize(window, &screen_width, &screen_height); - process_glfw_keyboard(window, &input); - process_glfw_mouse_pos(window, &input); - - if (key_first_press(input.exit)) - glfwSetWindowShouldClose(window, GLFW_TRUE); - - F32 speed = 4.0f; - V3F dv = get_dv_camera_first_person(&input, &state.camera, - speed, state.dt); - if (key_is_pressed(input.action_up)) - dv = v3f_scalef(dv, 3.0f); - camera_dp = v3f_add(camera_dp, dv); - camera_dp = v3f_scalef(camera_dp, 0.8f); - state.camera.pos = v3f_add(state.camera.pos, camera_dp); - - F32 sensitivity = 0.1f; - input.mouse_offset = v2f_scalef(input.mouse_offset, sensitivity); - state.camera.yaw += input.mouse_offset.x; - state.camera.pitch += input.mouse_offset.y; - if (state.camera.pitch > 89.0f) - state.camera.pitch = 89.0f; - if (state.camera.pitch < -89.0f) - state.camera.pitch = -89.0f; - - input_update_last_state(&input); - - angular_speed = 1.0f; - radius = 4.0f; - x = f32_sin(time*angular_speed)*radius; - y = f32_sin(time*angular_speed)*f32_sin(time*angular_speed)*radius; - z = f32_cos(time*angular_speed)*radius; - - light_pos = v3f(x, y, z); - - /* NOTE(pryazha): Render */ - - /* NOTE(pryazha): Render the depth cubemap */ - F32 fovx, aspect, near, far; - fovx = 90.0f; - aspect = (F32)shadow_width/(F32)shadow_height; - near = 1.0f; - far = 25.0f; - proj = perspective(fovx, aspect, near, far); - shadow_transforms[0] = mat4_mul(proj, look_at(light_pos, v3f_add(light_pos, v3f( 1.0f, 0.0f, 0.0f)), v3f(0.0f, -1.0f, 0.0f))); /* right */ - shadow_transforms[1] = mat4_mul(proj, look_at(light_pos, v3f_add(light_pos, v3f(-1.0f, 0.0f, 0.0f)), v3f(0.0f, -1.0f, 0.0f))); /* left */ - shadow_transforms[2] = mat4_mul(proj, look_at(light_pos, v3f_add(light_pos, v3f( 0.0f, 1.0f, 0.0f)), v3f(0.0f, 0.0f, 1.0f))); /* top */ - shadow_transforms[3] = mat4_mul(proj, look_at(light_pos, v3f_add(light_pos, v3f( 0.0f, -1.0f, 0.0f)), v3f(0.0f, 0.0f, -1.0f))); /* bottom */ - shadow_transforms[4] = mat4_mul(proj, look_at(light_pos, v3f_add(light_pos, v3f( 0.0f, 0.0f, 1.0f)), v3f(0.0f, -1.0f, 0.0f))); /* near */ - shadow_transforms[5] = mat4_mul(proj, look_at(light_pos, v3f_add(light_pos, v3f( 0.0f, 0.0f, -1.0f)), v3f(0.0f, -1.0f, 0.0f))); /* far */ - glViewport(0, 0, shadow_width, shadow_height); - glBindFramebuffer(GL_FRAMEBUFFER, depth_cubemap_fbo); - glClear(GL_DEPTH_BUFFER_BIT); - glUseProgram(depth_shader); - shader_set_1f(depth_shader, "far", far); - shader_set_3fv(depth_shader, "light_pos", light_pos); - for (U32 i = 0; i < 6; ++i) { - char uniform_name[256]; - snprintf(uniform_name, 256, "shadow_transforms[%d]", i); - shader_set_mat4fv(depth_shader, uniform_name, shadow_transforms[i]); - } - render_scene(depth_shader, cube); - glBindFramebuffer(GL_FRAMEBUFFER, 0); - - /* NOTE(pryazha): Render the scene as normal */ - glViewport(0, 0, screen_width, screen_height); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - glUseProgram(shadow_shader); - - aspect = (F32)screen_width/(F32)screen_height; - proj = perspective(state.camera.fovx, aspect, state.camera.near, state.camera.far); - view = get_view_matrix(&state.camera); - - 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_1f(shadow_shader, "far", far); - - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, wood_texture); - glActiveTexture(GL_TEXTURE1); - glBindTexture(GL_TEXTURE_CUBE_MAP, depth_cubemap); - render_scene(shadow_shader, cube); - - glfwSwapBuffers(window); - - time = glfwGetTime(); - state.dt = time-last_time; - last_time = time; - } - - glfwTerminate(); - return(0); + Input input; + F64 time, last_time; + V3F light_pos; + MAT4 shadow_transforms[6]; + MAT4 proj, view; + + glfwSetErrorCallback(error_callback); + + if (glfwInit() == GLFW_FALSE) + return(1); + + S32 screen_width = 800; + S32 screen_height = 600; + + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); + glfwWindowHint(GLFW_SAMPLES, 4); + GLFWwindow *window = glfwCreateWindow(screen_width, screen_height, "Point shadows", 0, 0); + if (!window) + goto error; + + glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); + + glfwMakeContextCurrent(window); + + if (glewInit() != GLEW_OK) + goto error; + + glEnable(GL_DEPTH_TEST); + glEnable(GL_CULL_FACE); + + /* NOTE(pryazha): Init */ + Arena *arena = arena_alloc(Megabytes(64)); + + State state = {0}; + state.camera = (Camera){ + .pos = v3f(0.0f, 1.0f, 3.0f), + .fovx = 100.0f, + .near = 0.1f, + .far = 100.0f, + .yaw = 0.0f, + .pitch = 0.0f + }; + V3F camera_dp = v3f_zero(); + light_pos = v3f_zero(); + + /* NOTE(pryazha): Meshes */ + 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 depth_shader = load_shader_geom("shaders/depth.vert", "shaders/depth.frag", "shaders/depth.geom"); + U32 shadow_shader = load_shader("shaders/shadow.vert", "shaders/shadow.frag"); + + glUseProgram(shadow_shader); + shader_set_1i(shadow_shader, "diffuse_texture", 0); + shader_set_1i(shadow_shader, "depth_cubemap", 1); + glUseProgram(0); + + U32 wood_texture = load_texture_gamma("../../data/textures/wood.png", 0); + + /* NOTE(pryazha): Depth framebuffer init */ + U32 depth_cubemap_fbo, depth_cubemap; + U32 shadow_width = 1024, shadow_height = 1024; + glGenFramebuffers(1, &depth_cubemap_fbo); + glGenTextures(1, &depth_cubemap); + glBindTexture(GL_TEXTURE_CUBE_MAP, depth_cubemap); + for (U32 cubemap_side = 0; cubemap_side < 6; ++cubemap_side) + glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X+cubemap_side, 0, GL_DEPTH_COMPONENT, + shadow_width, shadow_height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_BORDER); + glBindFramebuffer(GL_FRAMEBUFFER, depth_cubemap_fbo); + glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depth_cubemap, 0); + 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): For now it's easier to write all of the logic in the main loop */ + /* NOTE(pryazha): Update */ + F32 x, y, z, angular_speed, radius; + + glfwGetFramebufferSize(window, &screen_width, &screen_height); + process_glfw_keyboard(window, &input); + process_glfw_mouse_pos(window, &input); + + if (key_first_press(input.exit)) + glfwSetWindowShouldClose(window, GLFW_TRUE); + + F32 speed = 4.0f; + V3F dv = get_dv_camera_first_person(&input, &state.camera, + speed, state.dt); + if (key_is_pressed(input.action_up)) + dv = v3f_scalef(dv, 3.0f); + camera_dp = v3f_add(camera_dp, dv); + camera_dp = v3f_scalef(camera_dp, 0.8f); + state.camera.pos = v3f_add(state.camera.pos, camera_dp); + + F32 sensitivity = 0.1f; + input.mouse_offset = v2f_scalef(input.mouse_offset, sensitivity); + state.camera.yaw += input.mouse_offset.x; + state.camera.pitch += input.mouse_offset.y; + if (state.camera.pitch > 89.0f) + state.camera.pitch = 89.0f; + if (state.camera.pitch < -89.0f) + state.camera.pitch = -89.0f; + + input_update_last_state(&input); + + angular_speed = 1.0f; + radius = 4.0f; + x = f32_sin(time*angular_speed)*radius; + y = f32_sin(time*angular_speed)*f32_sin(time*angular_speed)*radius; + z = f32_cos(time*angular_speed)*radius; + + light_pos = v3f(x, y, z); + + /* NOTE(pryazha): Render */ + + /* NOTE(pryazha): Render the depth cubemap */ + F32 fovx, aspect, near, far; + fovx = 90.0f; + aspect = (F32)shadow_width/(F32)shadow_height; + near = 1.0f; + far = 25.0f; + proj = perspective(fovx, aspect, near, far); + shadow_transforms[0] = mat4_mul(proj, look_at(light_pos, v3f_add(light_pos, v3f( 1.0f, 0.0f, 0.0f)), v3f(0.0f, -1.0f, 0.0f))); /* right */ + shadow_transforms[1] = mat4_mul(proj, look_at(light_pos, v3f_add(light_pos, v3f(-1.0f, 0.0f, 0.0f)), v3f(0.0f, -1.0f, 0.0f))); /* left */ + shadow_transforms[2] = mat4_mul(proj, look_at(light_pos, v3f_add(light_pos, v3f( 0.0f, 1.0f, 0.0f)), v3f(0.0f, 0.0f, 1.0f))); /* top */ + shadow_transforms[3] = mat4_mul(proj, look_at(light_pos, v3f_add(light_pos, v3f( 0.0f, -1.0f, 0.0f)), v3f(0.0f, 0.0f, -1.0f))); /* bottom */ + shadow_transforms[4] = mat4_mul(proj, look_at(light_pos, v3f_add(light_pos, v3f( 0.0f, 0.0f, 1.0f)), v3f(0.0f, -1.0f, 0.0f))); /* near */ + shadow_transforms[5] = mat4_mul(proj, look_at(light_pos, v3f_add(light_pos, v3f( 0.0f, 0.0f, -1.0f)), v3f(0.0f, -1.0f, 0.0f))); /* far */ + glViewport(0, 0, shadow_width, shadow_height); + glBindFramebuffer(GL_FRAMEBUFFER, depth_cubemap_fbo); + glClear(GL_DEPTH_BUFFER_BIT); + glUseProgram(depth_shader); + shader_set_1f(depth_shader, "far", far); + shader_set_3fv(depth_shader, "light_pos", light_pos); + for (U32 i = 0; i < 6; ++i) { + char uniform_name[256]; + snprintf(uniform_name, 256, "shadow_transforms[%d]", i); + shader_set_mat4fv(depth_shader, uniform_name, shadow_transforms[i]); + } + render_scene(depth_shader, cube); + glBindFramebuffer(GL_FRAMEBUFFER, 0); + + /* NOTE(pryazha): Render the scene as normal */ + glViewport(0, 0, screen_width, screen_height); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glUseProgram(shadow_shader); + + aspect = (F32)screen_width/(F32)screen_height; + proj = perspective(state.camera.fovx, aspect, state.camera.near, state.camera.far); + view = get_view_matrix(&state.camera); + + 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_1f(shadow_shader, "far", far); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, wood_texture); + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_CUBE_MAP, depth_cubemap); + render_scene(shadow_shader, cube); + + glfwSwapBuffers(window); + + time = glfwGetTime(); + state.dt = time-last_time; + last_time = time; + } + + glfwTerminate(); + return(0); error: - glfwTerminate(); - return(1); + glfwTerminate(); + return(1); } diff --git a/advanced_lighting/4.normal_mapping/build b/advanced_lighting/4.normal_mapping/build new file mode 100755 index 0000000..4209fd0 --- /dev/null +++ b/advanced_lighting/4.normal_mapping/build @@ -0,0 +1,5 @@ +#!/bin/sh +. ../../config +TARGET='normal_mapping' +set -x +gcc -o $TARGET $CFLAGS $INCLUDE $LFLAGS $TARGET.c $LIBS diff --git a/advanced_lighting/4.normal_mapping/build.sh b/advanced_lighting/4.normal_mapping/build.sh deleted file mode 100755 index 4209fd0..0000000 --- a/advanced_lighting/4.normal_mapping/build.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh -. ../../config -TARGET='normal_mapping' -set -x -gcc -o $TARGET $CFLAGS $INCLUDE $LFLAGS $TARGET.c $LIBS diff --git a/advanced_lighting/4.normal_mapping/normal_mapping.c b/advanced_lighting/4.normal_mapping/normal_mapping.c index 980f4a0..5051cb7 100644 --- a/advanced_lighting/4.normal_mapping/normal_mapping.c +++ b/advanced_lighting/4.normal_mapping/normal_mapping.c @@ -130,13 +130,9 @@ int main(void) glBindVertexArray(0); /* NOTE(pryazha): Shaders */ - U32 normal_map_shader = create_shader_program("shaders/normal_map.vert", - "shaders/normal_map.frag"); - U32 normals_debug_shader = create_shader_program_geom("shaders/normals_debug.vert", - "shaders/normals_debug.frag", - "shaders/normals_debug.geom"); - U32 color_shader = create_shader_program("shaders/color.vert", - "shaders/color.frag"); + U32 normal_map_shader = load_shader("shaders/normal_map.vert", "shaders/normal_map.frag"); + U32 normals_debug_shader = load_shader_geom("shaders/normals_debug.vert", "shaders/normals_debug.frag", "shaders/normals_debug.geom"); + U32 color_shader = load_shader("shaders/color.vert", "shaders/color.frag"); glUseProgram(normal_map_shader); shader_set_1i(normal_map_shader, "diffuse_texture", 0); diff --git a/advanced_lighting/5.parallax_mapping/build b/advanced_lighting/5.parallax_mapping/build new file mode 100755 index 0000000..e36f110 --- /dev/null +++ b/advanced_lighting/5.parallax_mapping/build @@ -0,0 +1,5 @@ +#!/bin/sh +. ../../config +TARGET='parallax_mapping' +set -x +gcc -o $TARGET $CFLAGS $INCLUDE $LFLAGS $TARGET.c $LIBS diff --git a/advanced_lighting/5.parallax_mapping/build.sh b/advanced_lighting/5.parallax_mapping/build.sh deleted file mode 100755 index e36f110..0000000 --- a/advanced_lighting/5.parallax_mapping/build.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh -. ../../config -TARGET='parallax_mapping' -set -x -gcc -o $TARGET $CFLAGS $INCLUDE $LFLAGS $TARGET.c $LIBS diff --git a/advanced_lighting/5.parallax_mapping/parallax_mapping.c b/advanced_lighting/5.parallax_mapping/parallax_mapping.c index 35859d2..e877926 100644 --- a/advanced_lighting/5.parallax_mapping/parallax_mapping.c +++ b/advanced_lighting/5.parallax_mapping/parallax_mapping.c @@ -142,10 +142,8 @@ int main(void) depth_texture = load_texture("../../data/textures/bricks2_disp.jpg"); /* NOTE(pryazha): Shaders */ - parallax_shader = create_shader_program("shaders/parallax.vert", "shaders/parallax.frag"); - normals_debug_shader = create_shader_program_geom("shaders/normals_debug.vert", - "shaders/normals_debug.frag", - "shaders/normals_debug.geom"); + parallax_shader = load_shader("shaders/parallax.vert", "shaders/parallax.frag"); + normals_debug_shader = load_shader_geom("shaders/normals_debug.vert", "shaders/normals_debug.frag", "shaders/normals_debug.geom"); glUseProgram(parallax_shader); shader_set_1i(parallax_shader, "diffuse_texture", 0); diff --git a/advanced_lighting/6.hdr/build b/advanced_lighting/6.hdr/build new file mode 100755 index 0000000..3957e1d --- /dev/null +++ b/advanced_lighting/6.hdr/build @@ -0,0 +1,5 @@ +#!/bin/sh +. ../../config +TARGET='hdr' +set -x +gcc -o $TARGET $CFLAGS $INCLUDE $LFLAGS $TARGET.c $LIBS diff --git a/advanced_lighting/6.hdr/build.sh b/advanced_lighting/6.hdr/build.sh deleted file mode 100755 index 3957e1d..0000000 --- a/advanced_lighting/6.hdr/build.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh -. ../../config -TARGET='hdr' -set -x -gcc -o $TARGET $CFLAGS $INCLUDE $LFLAGS $TARGET.c $LIBS diff --git a/advanced_lighting/6.hdr/hdr.c b/advanced_lighting/6.hdr/hdr.c index 911f9da..655ab06 100644 --- a/advanced_lighting/6.hdr/hdr.c +++ b/advanced_lighting/6.hdr/hdr.c @@ -10,39 +10,8 @@ int main(void) { - S32 width, height; - - GLFWwindow *window; - F64 time, last_time; - - State state = {0}; - - U32 wooodtex; - - Mesh *quad, - *cube, - *tubecube; - - U32 blinn_shader, - hdr_shader, - light_shader, - normals_debug_shader; - - U32 hdrfbo, - hdrcolorbuf, - hdrrbo; - - S32 i; - - F32 a, da, r; - V3F lpos[LCOUNT]; - - F32 exposure; - - S32 show_normals, show_lights; - - width = 800; - height = 600; + S32 width = 800; + S32 height = 600; /* NOTE(pryazha): GLFW init */ glfwSetErrorCallback(error_callback); @@ -53,7 +22,7 @@ int main(void) glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE); - window = glfwCreateWindow(width, height, "HDR", 0, 0); + GLFWwindow *window = glfwCreateWindow(width, height, "HDR", 0, 0); if (!window) goto error; @@ -67,46 +36,49 @@ int main(void) glEnable(GL_DEPTH_TEST); /* NOTE(pryazha): Program init */ + State state = {0}; state.arena = arena_alloc(Kilobytes(256)); - state.input.first_mouse = 1; - state.camera = (Camera){ v3f(0.0f, 0.0f, 3.0f), 90.0f, 0.1f, 100.0f, 0.0f, 0.0f }; state.camera_dp = v3f_zero(); - da = 2.0f*pi_F32/LCOUNT; - for (i = 0, a = 0.0f, r = 2.0f; i < LCOUNT; i++, a += da) + F32 da = 2.0f*pi_F32/LCOUNT; + F32 a = 0.0f; + F32 r = 2.0f; + V3F lpos[LCOUNT]; + for (S32 i = 0; i < LCOUNT; i++, a += da) lpos[i] = v3f(f32_sin(a)*r, 0.0f, f32_cos(a)*r); - exposure = 1.0f; + F32 exposure = 1.0f; - show_normals = 0; - show_lights = 1; + S32 show_normals = 0; + S32 show_lights = 1; /* NOTE(pryazha): Textures */ - wooodtex = load_texture_gamma("../../data/textures/wood.png", 1); + U32 wooodtex = load_texture_gamma("../../data/textures/wood.png", 1); /* NOTE(pryazha): Meshes */ - quad = mesh_gen_quad(state.arena); - cube = mesh_load_obj(state.arena, "../../data/models/cube.obj"); - tubecube = mesh_load_obj(state.arena, "../../data/models/tube_with_cube.obj"); + Mesh *quad = mesh_gen_quad(state.arena); + Mesh *cube = mesh_load_obj(state.arena, "../../data/models/cube.obj"); + Mesh *tubecube = mesh_load_obj(state.arena, "../../data/models/tube_with_cube.obj"); /* NOTE(pryazha): Shaders */ - blinn_shader = create_shader_program("shaders/blinn.vert", "shaders/blinn.frag"); - hdr_shader = create_shader_program("shaders/hdr.vert", "shaders/hdr.frag"); - light_shader = create_shader_program("shaders/light.vert", "shaders/light.frag"); - normals_debug_shader = create_shader_program_geom("shaders/normals_debug.vert", - "shaders/normals_debug.frag", - "shaders/normals_debug.geom"); + U32 blinn_shader = load_shader("shaders/blinn.vert", "shaders/blinn.frag"); + U32 hdr_shader = load_shader("shaders/hdr.vert", "shaders/hdr.frag"); + U32 light_shader = load_shader("shaders/light.vert", "shaders/light.frag"); + U32 normals_debug_shader = load_shader_geom("shaders/normals_debug.vert", "shaders/normals_debug.frag", "shaders/normals_debug.geom"); /* NOTE(pryazha): Create HDR framebuffer, color buffer texture and * renderbuffer */ + U32 hdrfbo, hdrcolorbuf; glGenFramebuffers(1, &hdrfbo); glGenTextures(1, &hdrcolorbuf); glBindTexture(GL_TEXTURE_2D, hdrcolorbuf); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, width, height, 0, GL_RGBA, GL_FLOAT, 0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + U32 hdrrbo; glGenRenderbuffers(1, &hdrrbo); glBindRenderbuffer(GL_RENDERBUFFER, hdrrbo); glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width, height); @@ -121,7 +93,7 @@ int main(void) glBindTexture(GL_TEXTURE_2D, 0); glBindFramebuffer(GL_FRAMEBUFFER, 0); - last_time = glfwGetTime(); + F64 last_time = glfwGetTime(); while (!glfwWindowShouldClose(window)) { glfwPollEvents(); @@ -161,7 +133,9 @@ int main(void) if (key_is_pressed(state.input.action_up)) exposure += 0.01f; - for (i = 0; i < LCOUNT; i++) + printf("exposure = %f\n", exposure); + + for (S32 i = 0; i < LCOUNT; i++) lpos[i].y = f32_sin(glfwGetTime()+i); /* NOTE(pryazha): Render */ @@ -188,7 +162,7 @@ int main(void) shader_set_mat4fv(blinn_shader, "view", view); shader_set_mat4fv(blinn_shader, "model", model); shader_set_1i(blinn_shader, "lcount", LCOUNT); - for (i = 0; i < LCOUNT; i++) { + for (S32 i = 0; i < LCOUNT; i++) { snprintf(lstr, 1024, "lpos[%d]", i); shader_set_3fv(blinn_shader, lstr, lpos[i]); } @@ -204,7 +178,7 @@ int main(void) glUseProgram(light_shader); shader_set_mat4fv(light_shader, "proj", proj); shader_set_mat4fv(light_shader, "view", view); - for (i = 0; i < LCOUNT; i++) { + for (S32 i = 0; i < LCOUNT; i++) { model = mat4_make_scale(v3f(0.2f, 0.2f, 0.2f)); model = mat4_translate(model, lpos[i]); shader_set_mat4fv(light_shader, "model", model); @@ -236,7 +210,7 @@ int main(void) glfwSwapBuffers(window); - time = glfwGetTime(); + F64 time = glfwGetTime(); state.dt = time-last_time; last_time = time; diff --git a/advanced_lighting/7.bloom/bloom.c b/advanced_lighting/7.bloom/bloom.c new file mode 100644 index 0000000..70adcfe --- /dev/null +++ b/advanced_lighting/7.bloom/bloom.c @@ -0,0 +1,287 @@ +#include "GL/glew.h" +#include "GLFW/glfw3.h" + +#include "pwyazh.h" +#include "pwyazh_GL.h" + +#include "common.h" + +#define LIGHT_COUNT 3 + +int main(void) +{ + S32 width = 1600; + S32 height = 900; + + /* NOTE(pryazha): GLFW init */ + glfwSetErrorCallback(error_callback); + if (glfwInit() == GLFW_FALSE) + return 1; + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); + glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE); + GLFWwindow *window = glfwCreateWindow(width, height, "Bloom", 0, 0); + if (!window) + return 1; + glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); + glfwMakeContextCurrent(window); + if (glewInit() != GLEW_OK) + return 1; + + glEnable(GL_DEPTH_TEST); + + /* NOTE(pryazha): Program init */ + State state = {0}; + state.arena = arena_alloc(Kilobytes(256)); + state.input.first_mouse = 1; + state.camera = (Camera){ v3f(0.0f, 0.0f, 3.0f), 90.0f, 0.1f, 100.0f, 0.0f, 0.0f }; + + V3F light_positions[LIGHT_COUNT]; + F32 da = 2.0f*pi_F32/LIGHT_COUNT; + F32 a = 0.0f; + F32 r = 2.0f; + for (S32 i = 0; i < LIGHT_COUNT; i++, a += da) + light_positions[i] = v3f(f32_sin(a)*r, 0.0f, f32_cos(a)*r); + + V3F light_colors[LIGHT_COUNT] = { + {5.0f, 5.0f, 5.0f}, + {10.0f, 0.0f, 0.0f}, + {0.0f, 5.0f, 0.0f}, + }; + + S32 bloom = 0; + F32 exposure = 1.0f; + + /* NOTE(pryazha): Textures */ + U32 woood_texture = load_texture_gamma("../../data/textures/wood.png", 1); + + /* NOTE(pryazha): Meshes */ + Mesh *quad = mesh_gen_quad(state.arena); + Mesh *cube = mesh_load_obj(state.arena, "../../data/models/cube.obj"); + + /* NOTE(pryazha): Shaders */ + U32 shader = load_shader("shaders/bloom.vert", "shaders/bloom.frag"); + U32 shader_light = load_shader("shaders/bloom.vert", "shaders/light.frag"); + U32 shader_blur = load_shader("shaders/blur.vert", "shaders/blur.frag"); + U32 shader_test_blur = load_shader("shaders/test_blur.vert", "shaders/test_blur.frag"); + U32 shader_final = load_shader("shaders/final.vert", "shaders/final.frag"); + + glUseProgram(shader_final); + shader_set_1i(shader_final, "scene", 0); + shader_set_1i(shader_final, "blur", 1); + + /* NOTE(pryazha): Framebuffers */ + U32 hdrfbo; + glGenFramebuffers(1, &hdrfbo); + glBindFramebuffer(GL_FRAMEBUFFER, hdrfbo); + + U32 colorbuffers[2]; + glGenTextures(2, colorbuffers); + for (S32 i = 0; i < 2; ++i) { + glBindTexture(GL_TEXTURE_2D, colorbuffers[i]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, width, height, 0, GL_RGBA, GL_FLOAT, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0+i, GL_TEXTURE_2D, colorbuffers[i], 0); + } + + U32 hdrrbo; + glGenRenderbuffers(1, &hdrrbo); + glBindRenderbuffer(GL_RENDERBUFFER, hdrrbo); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width, height); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, hdrrbo); + + U32 attachments[2] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1}; + glDrawBuffers(2, attachments); + + if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) + fprintf(stderr, "error: framebuffer not complete\n"); + + glBindRenderbuffer(GL_RENDERBUFFER, 0); + glBindTexture(GL_TEXTURE_2D, 0); + glBindFramebuffer(GL_FRAMEBUFFER, 0); + + U32 pingpong_fbo[2]; + U32 pingpong_colorbuffers[2]; + glGenFramebuffers(2, pingpong_fbo); + glGenTextures(2, pingpong_colorbuffers); + for (S32 i = 0; i < 2; i++) { + glBindFramebuffer(GL_FRAMEBUFFER, pingpong_fbo[i]); + glBindTexture(GL_TEXTURE_2D, pingpong_colorbuffers[i]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, width, height, 0, GL_RGBA, GL_FLOAT, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, pingpong_colorbuffers[i], 0); + if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) + fprintf(stderr, "error: framebuffer not complete\n"); + } + glBindFramebuffer(GL_FRAMEBUFFER, 0); + + U32 blur_fbo; + glGenFramebuffers(1, &blur_fbo); + glBindFramebuffer(GL_FRAMEBUFFER, blur_fbo); + U32 blur_colorbuffer; + glGenTextures(1, &blur_colorbuffer); + glBindTexture(GL_TEXTURE_2D, blur_colorbuffer); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, width, height, 0, GL_RGBA, GL_FLOAT, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, blur_colorbuffer, 0); + if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) + fprintf(stderr, "error: blur framebuffer not complete\n"); + glBindTexture(GL_TEXTURE_2D, 0); + glBindFramebuffer(GL_FRAMEBUFFER, 0); + + S32 myblur = 0; + + F64 last_time = glfwGetTime(); + while (!glfwWindowShouldClose(window)) { + glfwPollEvents(); + glfwGetFramebufferSize(window, &width, &height); + process_glfw_keyboard(window, &state.input); + process_glfw_mouse_pos(window, &state.input); + + if (key_first_press(state.input.exit)) + glfwSetWindowShouldClose(window, GLFW_TRUE); + + F32 speed = 2.0f; + V3F dv = get_dv_camera_first_person(&state.input, &state.camera, speed, state.dt); + state.camera_dp = v3f_add(state.camera_dp, dv); + state.camera_dp = v3f_scalef(state.camera_dp, 0.8f); + state.camera.pos = v3f_add(state.camera.pos, state.camera_dp); + + F32 sensitivity = 0.1f; + state.input.mouse_offset = v2f_scalef(state.input.mouse_offset, sensitivity); + state.camera.yaw += state.input.mouse_offset.x; + state.camera.pitch += state.input.mouse_offset.y; + if (state.camera.pitch > 89.0f) + state.camera.pitch = 89.0f; + if (state.camera.pitch < -89.0f) + state.camera.pitch = -89.0f; + + /* NOTE(pryazha): Update */ + if (key_is_pressed(state.input.action_down)) + exposure -= 0.01f; + if (key_is_pressed(state.input.action_up)) + exposure += 0.01f; + + if (key_first_press(state.input.jump)) + bloom = !bloom; + + if (key_first_press(state.input.action_left)) + myblur = !myblur; + + for (S32 i = 0; i < LIGHT_COUNT; i++) + light_positions[i].y = f32_sin(glfwGetTime()+i); + + /* NOTE(pryazha): Render */ + glClearColor(0.15f, 0.15f, 0.15f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + /* Render to HDR framebuffer */ + glBindFramebuffer(GL_FRAMEBUFFER, hdrfbo); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + F32 ar = (F32)width/(F32)height; + MAT4 projection = camera_persp(state.camera, ar); + MAT4 view = get_view_matrix(&state.camera); + + glUseProgram(shader); + shader_set_mat4fv(shader, "projection", projection); + shader_set_mat4fv(shader, "view", view); + for (S32 i = 0; i < LIGHT_COUNT; i++) { + char light_string[1024]; + snprintf(light_string, 1024, "lights[%d].position", i); + shader_set_3fv(shader, light_string, light_positions[i]); + snprintf(light_string, 1024, "lights[%d].color", i); + shader_set_3fv(shader, light_string, light_colors[i]); + } + shader_set_3fv(shader, "view_pos", state.camera.pos); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, woood_texture); + + MAT4 model = mat4_make_scale(v3f(10.0f, 0.25f, 10.0f)); + model = mat4_translate(model, v3f(0.0f, -2.0f, 0.0f)); + shader_set_mat4fv(shader, "model", model); + mesh_draw(cube); + + model = mat4_make_scale(v3f(0.5f, 0.5f, 0.5f)); + model = mat4_rotate_angles(model, v3f(30.0f, 45.0f, 0.0f)); + model = mat4_translate(model, v3f(-0.5f, -1.0f, -2.0f)); + shader_set_mat4fv(shader, "model", model); + mesh_draw(cube); + + model = mat4_make_scale(v3f(0.5f, 0.5f, 0.5f)); + model = mat4_rotate_angles(model, v3f(-30.0f, 45.0f, 90.0f)); + model = mat4_translate(model, v3f(0.75f, -1.5f, 1.0f)); + shader_set_mat4fv(shader, "model", model); + mesh_draw(cube); + + glBindTexture(GL_TEXTURE_2D, 0); + glUseProgram(0); + + glUseProgram(shader_light); + shader_set_mat4fv(shader_light, "projection", projection); + shader_set_mat4fv(shader_light, "view", view); + for (S32 i = 0; i < LIGHT_COUNT; i++) { + model = mat4_make_scale(v3f(0.2f, 0.2f, 0.2f)); + model = mat4_translate(model, light_positions[i]); + shader_set_mat4fv(shader_light, "model", model); + shader_set_3fv(shader_light, "light_color", light_colors[i]); + mesh_draw(cube); + } + glUseProgram(0); + + S32 horizontal = 1, first = 1, amount = 10; + glUseProgram(shader_blur); + for (S32 i = 0; i < amount; i++) { + glBindFramebuffer(GL_FRAMEBUFFER, pingpong_fbo[horizontal]); + shader_set_1i(shader_blur, "horizontal", horizontal); + glBindTexture(GL_TEXTURE_2D, first ? colorbuffers[1] : pingpong_colorbuffers[!horizontal]); + mesh_draw(quad); + horizontal = !horizontal; + if (first) + first = 0; + } + glUseProgram(0); + + glBindFramebuffer(GL_FRAMEBUFFER, blur_fbo); + glUseProgram(shader_test_blur); + glActiveTexture(0); + glBindTexture(GL_TEXTURE_2D, colorbuffers[1]); + mesh_draw(quad); + glUseProgram(0); + + glBindFramebuffer(GL_FRAMEBUFFER, 0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glUseProgram(shader_final); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, colorbuffers[0]); + glActiveTexture(GL_TEXTURE1); + if (myblur) { + glBindTexture(GL_TEXTURE_2D, blur_colorbuffer); + } else { + glBindTexture(GL_TEXTURE_2D, pingpong_colorbuffers[!horizontal]); + } + shader_set_1i(shader_final, "bloom", bloom); + shader_set_1f(shader_final, "exposure", exposure); + mesh_draw(quad); + + glfwSwapBuffers(window); + + F64 time = glfwGetTime(); + state.dt = time - last_time; + last_time = time; + + input_update_last_state(&state.input); + } + + return 0; +} diff --git a/advanced_lighting/7.bloom/build b/advanced_lighting/7.bloom/build new file mode 100755 index 0000000..99df29a --- /dev/null +++ b/advanced_lighting/7.bloom/build @@ -0,0 +1,5 @@ +#!/bin/sh +. ../../config +TARGET='bloom' +set -x +gcc -o $TARGET $CFLAGS $INCLUDE $LFLAGS $TARGET.c $LIBS diff --git a/advanced_lighting/7.bloom/shaders/bloom.frag b/advanced_lighting/7.bloom/shaders/bloom.frag new file mode 100644 index 0000000..88decf8 --- /dev/null +++ b/advanced_lighting/7.bloom/shaders/bloom.frag @@ -0,0 +1,45 @@ +#version 330 core + +in VS_OUT { + vec3 position; + vec3 normal; + vec2 tex_coords; +} vs_out; + +layout(location = 0) out vec4 frag_color; +layout(location = 1) out vec4 bright_color; + +struct light_t { + vec3 position; + vec3 color; +}; + +uniform light_t lights[3]; +uniform sampler2D diffuse_texture; +uniform vec3 view_pos; + +const int light_count = 3; + +void main(void) +{ + vec3 color = texture(diffuse_texture, vs_out.tex_coords).rgb; + vec3 ambient = 0.01 * color; + vec3 lighting = vec3(0.0); + vec3 view_dir = normalize(view_pos - vs_out.position); + for (int i = 0; i < light_count; i++) { + vec3 light_dir = normalize(lights[i].position - vs_out.position); + float diff = max(dot(light_dir, vs_out.normal), 0.0); + vec3 result = lights[i].color * diff * color; + float distance = length(vs_out.position - lights[i].position); + result *= 1.0 / (distance * distance); + lighting += result; + } + vec3 result = ambient + lighting; + float brightness = dot(result, vec3(0.2126, 0.7152, 0.0722)); + if (brightness > 1.0) { + bright_color = vec4(result, 1.0); + } else { + bright_color = vec4(0.0, 0.0, 0.0, 1.0); + } + frag_color = vec4(result, 1.0); +} diff --git a/advanced_lighting/7.bloom/shaders/bloom.vert b/advanced_lighting/7.bloom/shaders/bloom.vert new file mode 100644 index 0000000..0c9dc02 --- /dev/null +++ b/advanced_lighting/7.bloom/shaders/bloom.vert @@ -0,0 +1,24 @@ +#version 330 core + +layout (location = 0) in vec3 position; +layout (location = 1) in vec3 normal; +layout (location = 2) in vec2 tex_coords; + +out VS_OUT { + vec3 position; + vec3 normal; + vec2 tex_coords; +} vs_out; + +uniform mat4 projection; +uniform mat4 view; +uniform mat4 model; + +void main() +{ + vs_out.position = vec3(model * vec4(position, 1.0)); + mat3 normal_matrix = transpose(inverse(mat3(model))); + vs_out.normal = normalize(normal_matrix * normal); + vs_out.tex_coords = tex_coords; + gl_Position = projection * view * model * vec4(position, 1.0); +} diff --git a/advanced_lighting/7.bloom/shaders/blur.frag b/advanced_lighting/7.bloom/shaders/blur.frag new file mode 100644 index 0000000..67b7e43 --- /dev/null +++ b/advanced_lighting/7.bloom/shaders/blur.frag @@ -0,0 +1,29 @@ +#version 330 core + +in VS_OUT { + vec2 tex_coords; +} vs_out; + +out vec4 frag_color; + +uniform sampler2D image; +uniform bool horizontal; +uniform float weights[5] = float[](0.2270270270, 0.1945945946, 0.1216216216, 0.0540540541, 0.0162162162); + +void main(void) +{ + vec2 tex_offset = 1.0 / textureSize(image, 0); + vec3 result = texture(image, vs_out.tex_coords).rgb * weights[0]; + if (horizontal) { + for (int i = 1; i < 5; i++) { + result += texture(image, vs_out.tex_coords + vec2(tex_offset.x * i, 0.0)).rgb * weights[i]; + result += texture(image, vs_out.tex_coords - vec2(tex_offset.x * i, 0.0)).rgb * weights[i]; + } + } else { + for (int i = 1; i < 5; i++) { + result += texture(image, vs_out.tex_coords + vec2(0.0, tex_offset.y * i)).rgb * weights[i]; + result += texture(image, vs_out.tex_coords - vec2(0.0, tex_offset.y * i)).rgb * weights[i]; + } + } + frag_color = vec4(result, 1.0); +} diff --git a/advanced_lighting/7.bloom/shaders/blur.vert b/advanced_lighting/7.bloom/shaders/blur.vert new file mode 100644 index 0000000..e4ced24 --- /dev/null +++ b/advanced_lighting/7.bloom/shaders/blur.vert @@ -0,0 +1,14 @@ +#version 330 core + +layout (location = 0) in vec3 position; +layout (location = 2) in vec2 tex_coords; + +out VS_OUT { + vec2 tex_coords; +} vs_out; + +void main(void) +{ + vs_out.tex_coords = tex_coords; + gl_Position = vec4(position, 1.0); +} diff --git a/advanced_lighting/7.bloom/shaders/final.frag b/advanced_lighting/7.bloom/shaders/final.frag new file mode 100644 index 0000000..fe9f5d7 --- /dev/null +++ b/advanced_lighting/7.bloom/shaders/final.frag @@ -0,0 +1,25 @@ +#version 330 core + +in VS_OUT { + vec2 tex_coords; +} vs_out; + +out vec4 frag_color; + +uniform sampler2D scene; +uniform sampler2D blur; +uniform bool bloom; +uniform float exposure; + +void main() +{ + const float gamma = 2.2; + vec3 scene_color = texture(scene, vs_out.tex_coords).rgb; + vec3 blur_color = texture(blur, vs_out.tex_coords).rgb; + if (bloom) { + scene_color += blur_color; + } + vec3 result = vec3(1.0) - exp(-scene_color * exposure); + result = pow(result, vec3(1.0 / gamma)); + frag_color = vec4(result, 1.0); +} diff --git a/advanced_lighting/7.bloom/shaders/final.vert b/advanced_lighting/7.bloom/shaders/final.vert new file mode 100644 index 0000000..f6a4e38 --- /dev/null +++ b/advanced_lighting/7.bloom/shaders/final.vert @@ -0,0 +1,14 @@ +#version 330 core + +layout (location = 0) in vec3 position; +layout (location = 2) in vec2 tex_coords; + +out VS_OUT { + vec2 tex_coords; +} vs_out; + +void main() +{ + vs_out.tex_coords = tex_coords; + gl_Position = vec4(position, 1.0); +} diff --git a/advanced_lighting/7.bloom/shaders/light.frag b/advanced_lighting/7.bloom/shaders/light.frag new file mode 100644 index 0000000..72a2874 --- /dev/null +++ b/advanced_lighting/7.bloom/shaders/light.frag @@ -0,0 +1,22 @@ +#version 330 core + +in VS_OUT { + vec3 position; + vec3 normal; + vec2 tex_coords; +} vs_out; + +layout(location = 0) out vec4 frag_color; +layout(location = 1) out vec4 bright_color; + +uniform vec3 light_color; + +void main() +{ + frag_color = vec4(light_color, 1.0); + float brightness = dot(vec3(frag_color), vec3(0.2126, 0.7152, 0.0722)); + if (brightness > 1.0) + bright_color = vec4(vec3(frag_color), 1.0); + else + bright_color = vec4(0.0, 0.0, 0.0, 1.0); +} diff --git a/advanced_lighting/7.bloom/shaders/test_blur.frag b/advanced_lighting/7.bloom/shaders/test_blur.frag new file mode 100644 index 0000000..8d7ee9a --- /dev/null +++ b/advanced_lighting/7.bloom/shaders/test_blur.frag @@ -0,0 +1,28 @@ +#version 330 core + +in vert_t { + vec2 tex_coords; +} vert; + +out vec4 frag_color; + +uniform sampler2D colorbuffer; + +uniform float weights[5] = float[](0.2270270270, 0.1945945946, 0.1216216216, 0.0540540541, 0.0162162162); + +void main() +{ + vec2 texture_offset = 1.0 / textureSize(colorbuffer, 0); + vec3 result = texture(colorbuffer, vert.tex_coords).rgb * weights[0]; + for (int x = 1; x < weights.length(); x++) { + vec2 offset = vec2(texture_offset.x * x, 0.0f); + result += texture(colorbuffer, vert.tex_coords + offset).rgb * weights[x]; + result += texture(colorbuffer, vert.tex_coords - offset).rgb * weights[x]; + } + for (int y = 1; y < weights.length(); y++) { + vec2 offset = vec2(0.0f, texture_offset.y * y); + result += texture(colorbuffer, vert.tex_coords + offset).rgb * weights[y]; + result += texture(colorbuffer, vert.tex_coords - offset).rgb * weights[y]; + } + frag_color = vec4(result, 1.0); +} diff --git a/advanced_lighting/7.bloom/shaders/test_blur.vert b/advanced_lighting/7.bloom/shaders/test_blur.vert new file mode 100644 index 0000000..eed3be3 --- /dev/null +++ b/advanced_lighting/7.bloom/shaders/test_blur.vert @@ -0,0 +1,14 @@ +#version 330 core + +layout(location = 0) in vec3 position; +layout(location = 2) in vec2 tex_coords; + +out vert_t { + vec2 tex_coords; +} vert; + +void main() +{ + vert.tex_coords = tex_coords; + gl_Position = vec4(position, 1.0); +} diff --git a/advanced_lighting/8.deferred_shading/build b/advanced_lighting/8.deferred_shading/build new file mode 100755 index 0000000..fc81382 --- /dev/null +++ b/advanced_lighting/8.deferred_shading/build @@ -0,0 +1,5 @@ +#!/bin/sh +. ../../config +TARGET='deferred' +set -x +gcc -o $TARGET $CFLAGS $INCLUDE $LFLAGS $TARGET.c $LIBS diff --git a/advanced_lighting/8.deferred_shading/deferred.c b/advanced_lighting/8.deferred_shading/deferred.c new file mode 100644 index 0000000..d411b41 --- /dev/null +++ b/advanced_lighting/8.deferred_shading/deferred.c @@ -0,0 +1,274 @@ +#include "GL/glew.h" +#include "GLFW/glfw3.h" + +#include "pwyazh.h" +#include "pwyazh_GL.h" + +#include "common.h" + +#define LIGHT_COUNT 200 +#define CUBE_COUNT 1000 + +int main(void) +{ + /* NOTE(pryazha): GLFW init */ + glfwSetErrorCallback(error_callback); + if (glfwInit() == GLFW_FALSE) + return 1; + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); + glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE); + S32 width = 1600; + S32 height = 900; + GLFWwindow *window = glfwCreateWindow(width, height, "deferred", 0, 0); + if (!window) + return 1; + glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); + glfwMakeContextCurrent(window); + if (glewInit() != GLEW_OK) + return 1; + glEnable(GL_DEPTH_TEST); + + /* NOTE(pryazha): Program init */ + State state = {0}; + state.arena = arena_alloc(Kilobytes(256)); + state.input.first_mouse = 1; + state.camera = (Camera){ v3f(0.0f, 2.0f, 5.0f), 90.0f, 0.1f, 100.0f, 0.0f, 0.0f }; + + /* NOTE(pryazha): Textures */ + U32 woood_texture = load_texture("../../data/textures/wood.png"); + + /* NOTE(pryazha): Meshes */ + Mesh *quad = mesh_gen_quad(state.arena); + Mesh *cube = mesh_load_obj(state.arena, "../../data/models/cube.obj"); + + /* NOTE(pryazha): Framebuffers */ + U32 gbuffer; + glGenFramebuffers(1, &gbuffer); + glBindFramebuffer(GL_FRAMEBUFFER, gbuffer); + + // position color buffer + U32 gpositions; + glGenTextures(1, &gpositions); + glBindTexture(GL_TEXTURE_2D, gpositions); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, width, height, 0, GL_RGBA, GL_FLOAT, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, gpositions, 0); + // normal + U32 gnormals; + glGenTextures(1, &gnormals); + glBindTexture(GL_TEXTURE_2D, gnormals); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, width, height, 0, GL_RGBA, GL_FLOAT, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, gnormals, 0); + // color + specular + U32 gcolor_specular; + glGenTextures(1, &gcolor_specular); + glBindTexture(GL_TEXTURE_2D, gcolor_specular); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, gcolor_specular, 0); + U32 attachments[3] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2}; + glDrawBuffers(3, attachments); + U32 rbo; + glGenRenderbuffers(1, &rbo); + glBindRenderbuffer(GL_RENDERBUFFER, rbo); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width, height); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbo); + if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) + fprintf(stderr, "error: gbuffer not complete\n"); + fprintf(stdout, "info: gbuffer complete\n"); + + /* NOTE(pryazha): Shaders */ + U32 shader_gbuffer = load_shader("shaders/gbuffer.vert", "shaders/gbuffer.frag"); + U32 shader_screen = load_shader("shaders/screen.vert", "shaders/screen.frag"); + U32 shader_specular = load_shader("shaders/screen.vert", "shaders/specular.frag"); + U32 shader_deferred = load_shader("shaders/screen.vert", "shaders/deferred.frag"); + U32 shader_light = load_shader("shaders/light.vert", "shaders/light.frag"); + + glUseProgram(shader_deferred); + shader_set_1i(shader_deferred, "positions", 0); + shader_set_1i(shader_deferred, "normals", 1); + shader_set_1i(shader_deferred, "color_specular", 2); + glUseProgram(0); + + V3F cube_positions[CUBE_COUNT]; + S32 cols = 30; + F32 spacing = 3.0f; + for (S32 i = 0; i < CUBE_COUNT; i++) { + S32 col = i % cols; + S32 row = i / cols; + cube_positions[i] = v3f(col * spacing, 0.0f, row * spacing); + } + + light_t lights[LIGHT_COUNT]; +#if 0 + V3F origin = {50.0f, 3.0f, 50.0f}; + F32 da = 2.0f*pi_F32/LIGHT_COUNT; + F32 a = 0.0f; + F32 radius = 20.0f; + for (S32 i = 0; i < LIGHT_COUNT; i++, a += da) { + lights[i].position = v3f_add(v3f(f32_sin(a) * radius, 0.0f, f32_cos(a) * radius), origin); + F32 r = (F32)(rand() % 100) / 100.0f; + F32 g = (F32)(rand() % 100) / 100.0f; + F32 b = (F32)(rand() % 100) / 100.0f; + lights[i].color = v3f(r, g, b); + } +#else + V3F origin = {0.0f, 3.0f, 0.0f}; + cols = 30; + spacing = 3.0f; + for (S32 i = 0; i < LIGHT_COUNT; i++) { + S32 col = i % cols; + S32 row = i / cols; + lights[i].position = v3f_add(v3f(col * spacing, 0.0f, row * spacing), origin); + F32 r = (F32)(rand() % 100) / 100.0f; + F32 g = (F32)(rand() % 100) / 100.0f; + F32 b = (F32)(rand() % 100) / 100.0f; + lights[i].color = v3f(r, g, b); + } +#endif + + S32 show_gbuffer = 0; + + F64 last_time = glfwGetTime(); + while (!glfwWindowShouldClose(window)) { + F64 time = glfwGetTime(); + state.dt = time - last_time; + last_time = time; + + input_update_last_state(&state.input); + + glfwPollEvents(); + glfwGetFramebufferSize(window, &width, &height); + process_glfw_keyboard(window, &state.input); + process_glfw_mouse_pos(window, &state.input); + + if (key_first_press(state.input.exit)) + glfwSetWindowShouldClose(window, GLFW_TRUE); + + F32 speed = 2.0f; + V3F dv = get_dv_camera_first_person(&state.input, &state.camera, speed, state.dt); + state.camera_dp = v3f_add(state.camera_dp, dv); + state.camera_dp = v3f_scalef(state.camera_dp, 0.8f); + state.camera.pos = v3f_add(state.camera.pos, state.camera_dp); + + F32 sensitivity = 0.1f; + state.input.mouse_offset = v2f_scalef(state.input.mouse_offset, sensitivity); + state.camera.yaw += state.input.mouse_offset.x; + state.camera.pitch += state.input.mouse_offset.y; + if (state.camera.pitch > 89.0f) + state.camera.pitch = 89.0f; + if (state.camera.pitch < -89.0f) + state.camera.pitch = -89.0f; + + /* NOTE(pryazha): Update */ + for (S32 i = 0; i < LIGHT_COUNT; i++) + lights[i].position.y = origin.y + f32_sin(glfwGetTime() + i); + + if (key_first_press(state.input.jump)) { + show_gbuffer = !show_gbuffer; + } + + /* NOTE(pryazha): Render */ + F32 ar = (F32)width/(F32)height; + MAT4 projection = camera_persp(state.camera, ar); + MAT4 view = get_view_matrix(&state.camera); + + glBindFramebuffer(GL_FRAMEBUFFER, gbuffer); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glUseProgram(shader_gbuffer); + shader_set_mat4fv(shader_gbuffer, "projection", projection); + shader_set_mat4fv(shader_gbuffer, "view", view); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, woood_texture); + + for (S32 i = 0; i < CUBE_COUNT; i++) { + MAT4 model = mat4_make_translate(cube_positions[i]); + shader_set_mat4fv(shader_gbuffer, "model", model); + mesh_draw(cube); + } + + glUseProgram(0); + glBindFramebuffer(GL_FRAMEBUFFER, 0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + if (show_gbuffer) { + glDisable(GL_DEPTH_TEST); + glUseProgram(shader_screen); + MAT4 model = mat4_make_scale(v3f(0.5f, 0.5f, 0.5f)); + model = mat4_translate(model, v3f(-0.5f, 0.5f, 0.0f)); + shader_set_mat4fv(shader_screen, "model", model); + glBindTexture(GL_TEXTURE_2D, gpositions); + mesh_draw(quad); + + model = mat4_make_scale(v3f(0.5f, 0.5f, 0.5f)); + model = mat4_translate(model, v3f(0.5f, 0.5f, 0.0f)); + shader_set_mat4fv(shader_screen, "model", model); + glBindTexture(GL_TEXTURE_2D, gnormals); + mesh_draw(quad); + + model = mat4_make_scale(v3f(0.5f, 0.5f, 0.5f)); + model = mat4_translate(model, v3f(-0.5f, -0.5f, 0.0f)); + shader_set_mat4fv(shader_screen, "model", model); + glBindTexture(GL_TEXTURE_2D, gcolor_specular); + mesh_draw(quad); + glUseProgram(0); + + glUseProgram(shader_specular); + model = mat4_make_scale(v3f(0.5f, 0.5f, 0.5f)); + model = mat4_translate(model, v3f(0.5f, -0.5f, 0.0f)); + shader_set_mat4fv(shader_specular, "model", model); + glBindTexture(GL_TEXTURE_2D, gcolor_specular); + mesh_draw(quad); + glUseProgram(0); + glEnable(GL_DEPTH_TEST); + } else { + glUseProgram(shader_deferred); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, gpositions); + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, gnormals); + glActiveTexture(GL_TEXTURE2); + glBindTexture(GL_TEXTURE_2D, gcolor_specular); + shader_set_3fv(shader_deferred, "view_position", state.camera.pos); + for (S32 i = 0; i < LIGHT_COUNT; i++) { + char light_string[512]; + snprintf(light_string, 512, "lights[%d].position", i); + shader_set_3fv(shader_deferred, light_string, lights[i].position); + snprintf(light_string, 512, "lights[%d].color", i); + shader_set_3fv(shader_deferred, light_string, lights[i].color); + } + MAT4 model = mat4_identity(); + shader_set_mat4fv(shader_deferred, "model", model); + mesh_draw(quad); + glUseProgram(0); + glEnable(GL_DEPTH_TEST); + + glBindFramebuffer(GL_READ_FRAMEBUFFER, gbuffer); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, + GL_DEPTH_BUFFER_BIT, GL_NEAREST); + glBindFramebuffer(GL_FRAMEBUFFER, 0); + + glUseProgram(shader_light); + shader_set_mat4fv(shader_light, "projection", projection); + shader_set_mat4fv(shader_light, "view", view); + for (S32 i = 0; i < LIGHT_COUNT; i++) { + shader_set_3fv(shader_light, "light_color", lights[i].color); + model = mat4_make_scale(v3f(0.2f, 0.2f, 0.2f)); + model = mat4_translate(model, lights[i].position); + shader_set_mat4fv(shader_light, "model", model); + mesh_draw(cube); + } + glUseProgram(0); + } + + glfwSwapBuffers(window); + } + + return 0; +} diff --git a/advanced_lighting/8.deferred_shading/shaders/deferred.frag b/advanced_lighting/8.deferred_shading/shaders/deferred.frag new file mode 100644 index 0000000..56e5f58 --- /dev/null +++ b/advanced_lighting/8.deferred_shading/shaders/deferred.frag @@ -0,0 +1,46 @@ +#version 330 core + +in vert_t { + vec2 tex_coords; +} vert; + +out vec4 frag_color; + +uniform sampler2D positions; +uniform sampler2D normals; +uniform sampler2D color_specular; + +uniform vec3 view_position; + +struct light_t { + vec3 position; + vec3 color; +}; + +const int light_count = 200; +uniform light_t lights[light_count]; + +const float linear = 0.7f; +const float quadratic = 1.8f; + +void main() +{ + vec3 position = texture(positions, vert.tex_coords).rgb; + vec3 normal = texture(normals, vert.tex_coords).rgb; + vec3 color = texture(color_specular, vert.tex_coords).rgb; + float specular = texture(color_specular, vert.tex_coords).a; + + vec3 ambient = 0.1 * color; + vec3 view_dir = normalize(view_position - position); + vec3 result = ambient; + for (int i = 0; i < light_count; i++) { + vec3 light_dir = normalize(lights[i].position - position); + vec3 diffuse = max(dot(normal, light_dir), 0.0) * color * lights[i].color; + float distance = length(lights[i].position - position); + float attenuation = 1.0 / (1.0 + linear * distance + quadratic * distance * distance); + vec3 halfway_dir = normalize(view_dir + light_dir); + vec3 specular = pow(max(dot(halfway_dir, normal), 0.0), 32.0) * vec3(0.5); + result += (diffuse + specular) * attenuation; + } + frag_color = vec4(result, 1.0); +} diff --git a/advanced_lighting/8.deferred_shading/shaders/gbuffer.frag b/advanced_lighting/8.deferred_shading/shaders/gbuffer.frag new file mode 100644 index 0000000..5f82c0b --- /dev/null +++ b/advanced_lighting/8.deferred_shading/shaders/gbuffer.frag @@ -0,0 +1,23 @@ +#version 330 core + +in vert_t { + vec3 position; + vec3 normal; + vec2 tex_coords; +} vert; + +layout (location = 0) out vec3 position; +layout (location = 1) out vec3 normal; +layout (location = 2) out vec4 color_specular; + +uniform sampler2D texture_diffuse; + +void main() +{ + position = vert.position; + normal = vert.normal; + color_specular.rgb = texture(texture_diffuse, vert.tex_coords).rgb; + // TODO(pryazha): add specular texture + // color_specular.a = texture(texture_specular, vert.tex_coords).r; + color_specular.a = 1; +} diff --git a/advanced_lighting/8.deferred_shading/shaders/gbuffer.vert b/advanced_lighting/8.deferred_shading/shaders/gbuffer.vert new file mode 100644 index 0000000..1e825c8 --- /dev/null +++ b/advanced_lighting/8.deferred_shading/shaders/gbuffer.vert @@ -0,0 +1,24 @@ +#version 330 core + +layout (location = 0) in vec3 position; +layout (location = 1) in vec3 normal; +layout (location = 2) in vec2 tex_coords; + +out vert_t { + vec3 position; + vec3 normal; + vec2 tex_coords; +} vert; + +uniform mat4 projection; +uniform mat4 view; +uniform mat4 model; + +void main() +{ + vert.position = vec3(model * vec4(position, 1.0)); + mat3 matrix_normal = transpose(inverse(mat3(model))); + vert.normal = matrix_normal * normal; + vert.tex_coords = tex_coords; + gl_Position = projection * view * model * vec4(position, 1.0); +} diff --git a/advanced_lighting/8.deferred_shading/shaders/light.frag b/advanced_lighting/8.deferred_shading/shaders/light.frag new file mode 100644 index 0000000..e654b0e --- /dev/null +++ b/advanced_lighting/8.deferred_shading/shaders/light.frag @@ -0,0 +1,11 @@ +#version 330 core + +out vec4 frag_color; + +uniform vec3 light_color; + +void main() +{ + frag_color = vec4(light_color, 1.0); +} + diff --git a/advanced_lighting/8.deferred_shading/shaders/light.vert b/advanced_lighting/8.deferred_shading/shaders/light.vert new file mode 100644 index 0000000..03ac7e2 --- /dev/null +++ b/advanced_lighting/8.deferred_shading/shaders/light.vert @@ -0,0 +1,12 @@ +#version 330 core + +layout(location = 0) in vec3 position; + +uniform mat4 projection; +uniform mat4 view; +uniform mat4 model; + +void main() +{ + gl_Position = projection * view * model * vec4(position, 1.0); +} diff --git a/advanced_lighting/8.deferred_shading/shaders/screen.frag b/advanced_lighting/8.deferred_shading/shaders/screen.frag new file mode 100644 index 0000000..3ae592d --- /dev/null +++ b/advanced_lighting/8.deferred_shading/shaders/screen.frag @@ -0,0 +1,14 @@ +#version 330 core + +in vert_t { + vec2 tex_coords; +} vert; + +out vec4 frag_color; + +uniform sampler2D colorbuffer; + +void main() +{ + frag_color = vec4(texture(colorbuffer, vert.tex_coords).rgb, 1.0); +} diff --git a/advanced_lighting/8.deferred_shading/shaders/screen.vert b/advanced_lighting/8.deferred_shading/shaders/screen.vert new file mode 100644 index 0000000..335635b --- /dev/null +++ b/advanced_lighting/8.deferred_shading/shaders/screen.vert @@ -0,0 +1,16 @@ +#version 330 core + +layout (location = 0) in vec3 position; +layout (location = 2) in vec2 tex_coords; + +out vert_t { + vec2 tex_coords; +} vert; + +uniform mat4 model; + +void main() +{ + vert.tex_coords = tex_coords; + gl_Position = model * vec4(position, 1.0); +} diff --git a/advanced_lighting/8.deferred_shading/shaders/specular.frag b/advanced_lighting/8.deferred_shading/shaders/specular.frag new file mode 100644 index 0000000..e6ea10e --- /dev/null +++ b/advanced_lighting/8.deferred_shading/shaders/specular.frag @@ -0,0 +1,14 @@ +#version 330 core + +in vert_t { + vec2 tex_coords; +} vert; + +out vec4 frag_color; + +uniform sampler2D colorbuffer; + +void main() +{ + frag_color = vec4(vec3(texture(colorbuffer, vert.tex_coords).a), 1.0); +} diff --git a/advanced_lighting/9.ssao/build b/advanced_lighting/9.ssao/build new file mode 100755 index 0000000..dc6929a --- /dev/null +++ b/advanced_lighting/9.ssao/build @@ -0,0 +1,5 @@ +#!/bin/sh +. ../../config +TARGET='ssao' +set -x +gcc -o $TARGET $CFLAGS $INCLUDE $LFLAGS $TARGET.c $LIBS diff --git a/advanced_lighting/9.ssao/deferred.frag b/advanced_lighting/9.ssao/deferred.frag new file mode 100644 index 0000000..5a3cc33 --- /dev/null +++ b/advanced_lighting/9.ssao/deferred.frag @@ -0,0 +1,44 @@ +#version 330 core + +in vert_t { + vec2 tex_coords; +} vert; + +out vec4 frag_color; + +uniform sampler2D positions; +uniform sampler2D normals; +uniform sampler2D albedo; +uniform sampler2D ssao; + +uniform vec3 view_position; + +struct light_t { + vec3 position; + vec3 color; +}; + +uniform light_t light; + +const float linear = 0.7f; +const float quadratic = 1.8f; + +void main() +{ + vec3 position = texture(positions, vert.tex_coords).xyz; + vec3 normal = texture(normals, vert.tex_coords).xyz; + vec3 color = texture(albedo, vert.tex_coords).rgb; + float occlusion = texture(ssao, vert.tex_coords).r; + + vec3 ambient = 0.1 * color * occlusion; + vec3 result = ambient; + vec3 view_dir = normalize(-position); + vec3 light_dir = normalize(light.position - position); + vec3 diffuse = max(dot(normal, light_dir), 0.0) * color * light.color; + vec3 halfway_dir = normalize(view_dir + light_dir); + vec3 specular = pow(max(dot(halfway_dir, normal), 0.0), 16.0) * vec3(0.5); + float distance = length(light.position - position); + float attenuation = 1.0 / (1.0 + linear * distance + quadratic * distance * distance); + result += (diffuse + specular) * attenuation; + frag_color = vec4(result, 1.0); +} diff --git a/advanced_lighting/9.ssao/deferred.vert b/advanced_lighting/9.ssao/deferred.vert new file mode 100644 index 0000000..335635b --- /dev/null +++ b/advanced_lighting/9.ssao/deferred.vert @@ -0,0 +1,16 @@ +#version 330 core + +layout (location = 0) in vec3 position; +layout (location = 2) in vec2 tex_coords; + +out vert_t { + vec2 tex_coords; +} vert; + +uniform mat4 model; + +void main() +{ + vert.tex_coords = tex_coords; + gl_Position = model * vec4(position, 1.0); +} diff --git a/advanced_lighting/9.ssao/gbuffer.frag b/advanced_lighting/9.ssao/gbuffer.frag new file mode 100644 index 0000000..7755107 --- /dev/null +++ b/advanced_lighting/9.ssao/gbuffer.frag @@ -0,0 +1,17 @@ +#version 330 core + +in vert_t { + vec3 position; + vec3 normal; +} vert; + +layout(location = 0) out vec3 position; +layout(location = 1) out vec3 normal; +layout(location = 2) out vec3 albedo; + +void main() +{ + position = vert.position; + normal = normalize(vert.normal); + albedo.rgb = vec3(0.95); +} diff --git a/advanced_lighting/9.ssao/gbuffer.vert b/advanced_lighting/9.ssao/gbuffer.vert new file mode 100644 index 0000000..81ab951 --- /dev/null +++ b/advanced_lighting/9.ssao/gbuffer.vert @@ -0,0 +1,21 @@ +#version 330 core + +layout (location = 0) in vec3 position; +layout (location = 1) in vec3 normal; + +out vert_t { + vec3 position; + vec3 normal; +} vert; + +uniform mat4 projection; +uniform mat4 view; +uniform mat4 model; + +void main() +{ + vert.position = vec3(view * model * vec4(position, 1.0)); + mat3 matrix_normal = transpose(inverse(mat3(view * model))); + vert.normal = matrix_normal * normal; + gl_Position = projection * view * model * vec4(position, 1.0); +} diff --git a/advanced_lighting/9.ssao/occlusion.frag b/advanced_lighting/9.ssao/occlusion.frag new file mode 100644 index 0000000..41a436b --- /dev/null +++ b/advanced_lighting/9.ssao/occlusion.frag @@ -0,0 +1,14 @@ +#version 330 core + +in vert_t { + vec2 tex_coords; +} vert; + +out vec4 frag_color; + +uniform sampler2D colorbuffer; + +void main() +{ + frag_color = vec4(vec3(texture(colorbuffer, vert.tex_coords).r), 1.0); +} diff --git a/advanced_lighting/9.ssao/screen.frag b/advanced_lighting/9.ssao/screen.frag new file mode 100644 index 0000000..3ae592d --- /dev/null +++ b/advanced_lighting/9.ssao/screen.frag @@ -0,0 +1,14 @@ +#version 330 core + +in vert_t { + vec2 tex_coords; +} vert; + +out vec4 frag_color; + +uniform sampler2D colorbuffer; + +void main() +{ + frag_color = vec4(texture(colorbuffer, vert.tex_coords).rgb, 1.0); +} diff --git a/advanced_lighting/9.ssao/screen.vert b/advanced_lighting/9.ssao/screen.vert new file mode 100644 index 0000000..335635b --- /dev/null +++ b/advanced_lighting/9.ssao/screen.vert @@ -0,0 +1,16 @@ +#version 330 core + +layout (location = 0) in vec3 position; +layout (location = 2) in vec2 tex_coords; + +out vert_t { + vec2 tex_coords; +} vert; + +uniform mat4 model; + +void main() +{ + vert.tex_coords = tex_coords; + gl_Position = model * vec4(position, 1.0); +} diff --git a/advanced_lighting/9.ssao/ssao b/advanced_lighting/9.ssao/ssao new file mode 100755 index 0000000..72a9677 Binary files /dev/null and b/advanced_lighting/9.ssao/ssao differ diff --git a/advanced_lighting/9.ssao/ssao.c b/advanced_lighting/9.ssao/ssao.c new file mode 100644 index 0000000..3cfca03 --- /dev/null +++ b/advanced_lighting/9.ssao/ssao.c @@ -0,0 +1,331 @@ +#include "GL/glew.h" +#include "GLFW/glfw3.h" + +#include "pwyazh.h" +#include "pwyazh_GL.h" + +#include "xoshiro128plus.c" + +#include "common.h" + +#include "assert.h" + +int main(void) +{ + // glfw init + glfwSetErrorCallback(error_callback); + if (glfwInit() == GLFW_FALSE) + return 1; + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); + glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE); + S32 width = 1600; + S32 height = 900; + GLFWwindow *window = glfwCreateWindow(width, height, "ssao", 0, 0); + if (!window) + return 1; + glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); + glfwMakeContextCurrent(window); + if (glewInit() != GLEW_OK) + return 1; + glEnable(GL_DEPTH_TEST); + + // program init + Arena *arena = arena_alloc(Kilobytes(256)); + Input input = input_init(); + Camera camera = { + .pos = v3f(0.0f, 2.0f, 5.0f), + .fovx = 90.0f, + .near = 0.1f, + .far = 100.0f, + .yaw = 0.0f, + .pitch = 0.0f + }; + V3F camera_dp = {0}; + light_t light = {{2.0f, 2.0f, 2.0f}, {5.0f, 5.0f, 10.0f}}; + + // meshes + Mesh *quad = mesh_gen_quad(arena); + Mesh *cube = mesh_load_obj(arena, "../../data/models/cube.obj"); + + // framebuffers + U32 gbuffer; + glGenFramebuffers(1, &gbuffer); + glBindFramebuffer(GL_FRAMEBUFFER, gbuffer); + + U32 gpositions; + glGenTextures(1, &gpositions); + glBindTexture(GL_TEXTURE_2D, gpositions); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, width, height, 0, GL_RGBA, 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_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, gpositions, 0); + + U32 gnormals; + glGenTextures(1, &gnormals); + glBindTexture(GL_TEXTURE_2D, gnormals); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, width, height, 0, GL_RGBA, GL_FLOAT, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, gnormals, 0); + + U32 galbedo; + glGenTextures(1, &galbedo); + glBindTexture(GL_TEXTURE_2D, galbedo); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, galbedo, 0); + U32 attachments[3] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2}; + glDrawBuffers(3, attachments); + + U32 rbo; + glGenRenderbuffers(1, &rbo); + glBindRenderbuffer(GL_RENDERBUFFER, rbo); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width, height); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbo); + + if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) + fprintf(stderr, "error: gbuffer not complete\n"); + fprintf(stdout, "info: gbuffer complete\n"); + + // shaders + U32 shader_gbuffer = load_shader("gbuffer.vert", "gbuffer.frag"); + U32 shader_ssao = load_shader("ssao.vert", "ssao.frag"); + U32 shader_deferred = load_shader("deferred.vert", "deferred.frag"); + U32 shader_screen = load_shader("screen.vert", "screen.frag"); + U32 shader_occlusion = load_shader("screen.vert", "occlusion.frag"); + + glUseProgram(shader_ssao); + shader_set_1i(shader_ssao, "positions", 0); + shader_set_1i(shader_ssao, "normals", 1); + shader_set_1i(shader_ssao, "noise", 2); + glUseProgram(shader_deferred); + shader_set_1i(shader_deferred, "positions", 0); + shader_set_1i(shader_deferred, "normals", 1); + shader_set_1i(shader_deferred, "albedo", 2); + shader_set_1i(shader_deferred, "ssao", 3); + glUseProgram(0); + + S32 show_gbuffer = 0; + + S32 nsamples = 64; + V3F *samples = malloc(nsamples * sizeof(V3F)); + S32 file = open("/dev/urandom", O_RDONLY); + if (file < 0) { + perror("error:"); + return 1; + } + U32 seed[4]; + if (read(file, seed, sizeof(seed)) < 0) { + perror("error"); + return 1; + } + for (S32 i = 0; i < nsamples; i++) { + V3F sample = { + nextf(seed) * 2.0f - 1.0f, + nextf(seed) * 2.0f - 1.0f, + nextf(seed) + }; + sample = v3f_norm(sample); + float scale = (F32)i / 64.0f; + scale = lerp(0.1f, 1.0f, scale * scale); + sample = v3f_scalef(sample, scale); + samples[i] = sample; + assert(-1.0f < sample.x && sample.x < 1.0f); + assert(-1.0f < sample.y && sample.y < 1.0f); + assert(0.0f < sample.z && sample.z < 1.0f); + // printf("color:\t%f\t%f\t%f\n", sample.x, sample.y, sample.z); + } + V3F noise[16]; + for (S32 i = 0; i < 16; i++) { + noise[i] = (V3F){ + nextf(seed) * 2.0f - 1.0f, + nextf(seed) * 2.0f - 1.0f, + 0.0f, + }; + } + close(file); + + U32 noise_texture; + glGenTextures(1, &noise_texture); + glBindTexture(GL_TEXTURE_2D, noise_texture); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, 4, 4, 0, GL_RGB, GL_FLOAT, noise); + 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_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glBindTexture(GL_TEXTURE_2D, 0); + + U32 ssao_fbo; + glGenFramebuffers(1, &ssao_fbo); + glBindFramebuffer(GL_FRAMEBUFFER, ssao_fbo); + U32 ssao_colorbuffer; + glGenTextures(1, &ssao_colorbuffer); + glBindTexture(GL_TEXTURE_2D, ssao_colorbuffer); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, width, height, 0, GL_RED, GL_FLOAT, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, ssao_colorbuffer, 0); + glBindTexture(GL_TEXTURE_2D, 0); + + F64 last_time = glfwGetTime(); + while (!glfwWindowShouldClose(window)) { + F64 time = glfwGetTime(); + F32 dt = time - last_time; + last_time = time; + + input_update_last_state(&input); + + glfwPollEvents(); + glfwGetFramebufferSize(window, &width, &height); + process_glfw_keyboard(window, &input); + process_glfw_mouse_pos(window, &input); + + if (key_first_press(input.exit)) + glfwSetWindowShouldClose(window, GLFW_TRUE); + + F32 speed = 2.0f; + V3F dv = get_dv_camera_first_person(&input, &camera, speed, dt); + camera_dp = v3f_add(camera_dp, dv); + camera_dp = v3f_scalef(camera_dp, 0.8f); + camera.pos = v3f_add(camera.pos, camera_dp); + + F32 sensitivity = 0.1f; + input.mouse_offset = v2f_scalef(input.mouse_offset, sensitivity); + camera.yaw += input.mouse_offset.x; + camera.pitch += input.mouse_offset.y; + if (camera.pitch > 89.0f) + camera.pitch = 89.0f; + if (camera.pitch < -89.0f) + camera.pitch = -89.0f; + + // update + if (key_first_press(input.jump)) + show_gbuffer = !show_gbuffer; + + // render + F32 ar = (F32)width / (F32)height; + MAT4 projection = camera_persp(camera, ar); + MAT4 view = get_view_matrix(&camera); + + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + // render stuff into gbuffer + glBindFramebuffer(GL_FRAMEBUFFER, gbuffer); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glUseProgram(shader_gbuffer); + + shader_set_mat4fv(shader_gbuffer, "projection", projection); + shader_set_mat4fv(shader_gbuffer, "view", view); + + shader_set_mat4fv(shader_gbuffer, "model", mat4_identity()); + mesh_draw(cube); + + MAT4 model = mat4_make_scale(v3f(10.0f, 0.2f, 10.0f)); + model = mat4_translate(model, v3f(0.0f, -1.25f, 0.0f)); + shader_set_mat4fv(shader_gbuffer, "model", model); + mesh_draw(cube); + + glUseProgram(0); + + glBindFramebuffer(GL_FRAMEBUFFER, 0); + + // render ssao texture + glBindFramebuffer(GL_FRAMEBUFFER, ssao_fbo); + glClear(GL_COLOR_BUFFER_BIT); + + glUseProgram(shader_ssao); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, gpositions); + + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, gnormals); + + glActiveTexture(GL_TEXTURE2); + glBindTexture(GL_TEXTURE_2D, noise_texture); + + for (S32 i = 0; i < nsamples; i++) { + + char str[512] = {0}; + snprintf(str, 512, "samples[%d]", i); + shader_set_3fv(shader_ssao, str, samples[i]); + } + shader_set_mat4fv(shader_ssao, "projection", projection); + + mesh_draw(quad); + + glUseProgram(0); + + glBindFramebuffer(GL_FRAMEBUFFER, 0); + + if (show_gbuffer) { + MAT4 scale = mat4_make_scale(v3f(0.5f, 0.5f, 0.5f)); + MAT4 leftup = mat4_translate(scale, v3f(-0.5f, 0.5f, 0.0f)); + MAT4 rightup = mat4_translate(scale, v3f(0.5f, 0.5f, 0.0f)); + MAT4 leftdown = mat4_translate(scale, v3f(-0.5f, -0.5f, 0.0f)); + MAT4 rightdown = mat4_translate(scale, v3f(0.5f, -0.5f, 0.0f)); + + glDisable(GL_DEPTH_TEST); + + glUseProgram(shader_screen); + shader_set_mat4fv(shader_screen, "model", leftup); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, gpositions); + mesh_draw(quad); + + shader_set_mat4fv(shader_screen, "model", rightup); + glBindTexture(GL_TEXTURE_2D, gnormals); + mesh_draw(quad); + + shader_set_mat4fv(shader_screen, "model", leftdown); + glBindTexture(GL_TEXTURE_2D, galbedo); + mesh_draw(quad); + glUseProgram(0); + + glUseProgram(shader_occlusion); + shader_set_mat4fv(shader_occlusion, "model", rightdown); + glBindTexture(GL_TEXTURE_2D, ssao_colorbuffer); + mesh_draw(quad); + glUseProgram(0); + + glEnable(GL_DEPTH_TEST); + } else { + // render scene lighting + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glUseProgram(shader_deferred); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, gpositions); + + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, gnormals); + + glActiveTexture(GL_TEXTURE2); + glBindTexture(GL_TEXTURE_2D, galbedo); + + glActiveTexture(GL_TEXTURE3); + glBindTexture(GL_TEXTURE_2D, ssao_colorbuffer); + + V4F light_pos_v4 = v4f(light.position.x, light.position.y, light.position.z, 1.0f); + V4F light_view_pos = mat4_v4f_mul(view, light_pos_v4); + shader_set_3fv(shader_deferred, "light.position", v3f_from_v4f(light_view_pos)); + shader_set_3fv(shader_deferred, "light.color", light.color); + shader_set_mat4fv(shader_deferred, "model", mat4_identity()); + + mesh_draw(quad); + + glUseProgram(0); + } + + glfwSwapBuffers(window); + } + + return 0; +} diff --git a/advanced_lighting/9.ssao/ssao.frag b/advanced_lighting/9.ssao/ssao.frag new file mode 100644 index 0000000..e4d04b1 --- /dev/null +++ b/advanced_lighting/9.ssao/ssao.frag @@ -0,0 +1,45 @@ +#version 330 core + +in vert_t { + vec2 tex_coords; +} vert; + +out float frag_color; + +uniform sampler2D positions; +uniform sampler2D normals; +uniform sampler2D noise; + +uniform vec3 samples[64]; +uniform mat4 projection; + +const vec2 noise_scale = vec2(1600.0 / 4.0, 900.0 / 4.0) + +void main() +{ + vec3 position = texture(positions, vert.tex_coords).rgb; + vec3 normal = texture(normals, vert.tex_coords).rgb; + vec3 random = texture(noise, vert.tex_coords * noise_scale).rgb; + + vec3 tangent = normalize(random - normal * dot(random, normal)); + vec3 bitangent = cross(normal, tangent); + mat3 TBN = mat3(tangent, bitangent, normal); + + int nsamples = 64; + float radius = 0.5; + float bias = 0.025; + float occlusion = 0.0; + for (int i = 0; i < nsamples; i++) { + vec3 sample = TBN * samples[i]; + sample = position + sample * radius; + vec4 offset = vec4(sample, 1.0); + offset = projection * offset; + offset.xyz /= offset.w; + offset.xyz = offset.xyz * 0.5 + 0.5; + float depth = texture(positions, offset.xy).z; + // float range_check = smoothstep(0.0, 1.0, radius / abs(position.z - depth)); + occlusion += (depth >= sample.z + bias ? 1.0 : 0.0); // * range_check; + } + occlusion = 1.0 - (occlusion / nsamples); + frag_color = occlusion; +} diff --git a/advanced_lighting/9.ssao/ssao.vert b/advanced_lighting/9.ssao/ssao.vert new file mode 100644 index 0000000..3ce6fb2 --- /dev/null +++ b/advanced_lighting/9.ssao/ssao.vert @@ -0,0 +1,16 @@ +#version 330 core + +layout(location = 0) in vec3 position; +layout(location = 2) in vec2 tex_coords; + +out vert_t { + vec2 tex_coords; +} vert; + +uniform mat4 model; + +void main() +{ + vert.tex_coords = tex_coords; + gl_Position = model * vec4(position, 1.0); +} diff --git a/advanced_lighting/9.ssao/xoshiro128plus.c b/advanced_lighting/9.ssao/xoshiro128plus.c new file mode 100644 index 0000000..b55c63b --- /dev/null +++ b/advanced_lighting/9.ssao/xoshiro128plus.c @@ -0,0 +1,28 @@ +#include + +/* --- xoshiro128+ --- */ +static inline uint32_t rotl(const uint32_t x, int k) { + return (x << k) | (x >> (32 - k)); +} + +uint32_t next(uint32_t *s) { + const uint32_t result = s[0] + s[3]; + const uint32_t t = s[1] << 9; + s[2] ^= s[0]; + s[3] ^= s[1]; + s[1] ^= s[2]; + s[0] ^= s[3]; + s[2] ^= t; + s[3] = rotl(s[3], 11); + return result; +} +/* --- /xoshiro128+ --- */ + +float int_to_float(uint32_t random) { + union { uint32_t u32; float f; } u = { .u32 = random >> 9 | 0x3f800000 }; + return u.f - 1.0; +} + +float nextf(uint32_t* s) { + return int_to_float(next(s)); +} diff --git a/advanced_lighting/build b/advanced_lighting/build new file mode 100755 index 0000000..1168d91 --- /dev/null +++ b/advanced_lighting/build @@ -0,0 +1,9 @@ +#!/bin/sh +targets=$(ls) +for target in $targets ; do + if [ $target != 'build' ] ; then + cd $target + ./build + cd .. + fi +done diff --git a/advanced_lighting/build.sh b/advanced_lighting/build.sh deleted file mode 100755 index 4829c7d..0000000 --- a/advanced_lighting/build.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/sh -targets=$(ls) -for target in $targets ; do - if [ $target != 'build.sh' ] ; then - cd $target - ./build.sh - cd .. - fi -done diff --git a/advanced_opengl/1.depth/build b/advanced_opengl/1.depth/build new file mode 100755 index 0000000..04fe803 --- /dev/null +++ b/advanced_opengl/1.depth/build @@ -0,0 +1,5 @@ +#!/bin/sh +. ../../config +TARGET='depth' +set -x +gcc -o $TARGET $CFLAGS $INCLUDE $LFLAGS $TARGET.c $LIBS diff --git a/advanced_opengl/1.depth/build.sh b/advanced_opengl/1.depth/build.sh deleted file mode 100755 index 04fe803..0000000 --- a/advanced_opengl/1.depth/build.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh -. ../../config -TARGET='depth' -set -x -gcc -o $TARGET $CFLAGS $INCLUDE $LFLAGS $TARGET.c $LIBS diff --git a/advanced_opengl/1.depth/depth.c b/advanced_opengl/1.depth/depth.c index 03092df..71a7ffc 100644 --- a/advanced_opengl/1.depth/depth.c +++ b/advanced_opengl/1.depth/depth.c @@ -8,178 +8,170 @@ int main(void) { - GLFWwindow *window; - State state; - S32 width, height; - Input input; - - if (glfwInit() == GLFW_FALSE) { - fprintf(stderr, "[ERROR] Failed to initialize glfw.\n"); - return(1); - } - - width = 1024; - height = 768; - - glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); - glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); - window = glfwCreateWindow(width, height, "Depth testing.", 0, 0); - if (!window) { - fprintf(stderr, "[ERROR] Failed to create window.\n"); - glfwTerminate(); - return(1); - } - - glfwMakeContextCurrent(window); - - if (glewInit() != GLEW_OK) { - fprintf(stderr, "[ERROR] Failed to initialize glew.\n"); - glfwTerminate(); - return(1); - } - - glEnable(GL_DEPTH_TEST); - glDepthFunc(GL_LESS); - - U32 shader = create_shader_program("shaders/depth.vert", "shaders/depth.frag"); - U32 marble_texture = load_texture("../../data/textures/marble.jpg"); - U32 metal_texture = load_texture("../../data/textures/metal.png"); - - F32 a = 0.5f; - F32 vertices[] = { - -a, -a, -a, 0.0f, 0.0f, - a, -a, -a, 1.0f, 0.0f, - a, a, -a, 1.0f, 1.0f, - a, a, -a, 1.0f, 1.0f, - -a, a, -a, 0.0f, 1.0f, - -a, -a, -a, 0.0f, 0.0f, - - -a, -a, a, 0.0f, 0.0f, - a, -a, a, 1.0f, 0.0f, - a, a, a, 1.0f, 1.0f, - a, a, a, 1.0f, 1.0f, - -a, a, a, 0.0f, 1.0f, - -a, -a, a, 0.0f, 0.0f, - - -a, a, a, 1.0f, 0.0f, - -a, a, -a, 1.0f, 1.0f, - -a, -a, -a, 0.0f, 1.0f, - -a, -a, -a, 0.0f, 1.0f, - -a, -a, a, 0.0f, 0.0f, - -a, a, a, 1.0f, 0.0f, - - a, a, a, 1.0f, 0.0f, - a, a, -a, 1.0f, 1.0f, - a, -a, -a, 0.0f, 1.0f, - a, -a, -a, 0.0f, 1.0f, - a, -a, a, 0.0f, 0.0f, - a, a, a, 1.0f, 0.0f, - - -a, -a, -a, 0.0f, 1.0f, - a, -a, -a, 1.0f, 1.0f, - a, -a, a, 1.0f, 0.0f, - a, -a, a, 1.0f, 0.0f, - -a, -a, a, 0.0f, 0.0f, - -a, -a, -a, 0.0f, 1.0f, - - -a, a, -a, 0.0f, 1.0f, - a, a, -a, 1.0f, 1.0f, - a, a, a, 1.0f, 0.0f, - a, a, a, 1.0f, 0.0f, - -a, a, a, 0.0f, 0.0f, - -a, a, -a, 0.0f, 1.0f - }; - - Transform cube_positions[] = { - transform_default(), - transform_make_translate(v3f(a, 0.0f, -4*a)) - }; - - V3F platform_pos = v3f(10.0f, 0.2f, 10.0f); - V3F platform_scale = v3f(0.0f, -(a+(a*0.2f)+0.01f), 0.0f); - Transform platform_transform = transform_make_scale_translate(platform_pos, platform_scale); - - U32 VAO, VBO; - glGenVertexArrays(1, &VAO); - glBindVertexArray(VAO); - glGenBuffers(1, &VBO); - glBindBuffer(GL_ARRAY_BUFFER, VBO); - glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), 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); - - state.camera = (Camera) { - v3f(0.0f, 0.0f, 3.0f), - 90.0f, 0.1f, 100.0f, - 0.0f, 0.0f - }; - - F32 target_fps = 60.0f; - F32 target_spf = 1.0f/target_fps; - F32 last_time = glfwGetTime(); - - while (!glfwWindowShouldClose(window)) { - glfwPollEvents(); - - process_glfw_keyboard(window, &input); - glfwGetFramebufferSize(window, &width, &height); - - /* INFO(pryazha): Update */ - 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); - - input_update_last_state(&input); - - /* INFO(pryazha): Render */ - MAT4 model, view, proj; - view = look_at(state.camera.pos, target, v3f(0.0f, 1.0f, 0.0f)); - /* proj = ortho(-5.0f, 5.0f, -5.0f, 5.0f, 0.1f, 100.0f); */ - proj = perspective(state.camera.fovx, (F32)width/(F32)height, - state.camera.near, state.camera.far); - - glViewport(0, 0, width, height); - glClearColor(0.15f, 0.15f, 0.15f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - glUseProgram(shader); - shader_set_mat4fv(shader, "view", view); - shader_set_mat4fv(shader, "proj", proj); - glBindTexture(GL_TEXTURE_2D, marble_texture); - glBindVertexArray(VAO); - for (S32 i = 0; i < (S32)ArrayCount(cube_positions); ++i) { - model = transform_apply(cube_positions[i]); - shader_set_mat4fv(shader, "model", model); - glDrawArrays(GL_TRIANGLES, 0, 36); - } - glBindTexture(GL_TEXTURE_2D, metal_texture); - model = transform_apply(platform_transform); - shader_set_mat4fv(shader, "model", model); - glDrawArrays(GL_TRIANGLES, 0, 36); - glBindVertexArray(0); - - glfwSwapBuffers(window); - - F32 elapsed = glfwGetTime()-last_time; - if (elapsed < target_spf) { - U32 sleep_time = (U32)(target_spf-elapsed); - if (sleep_time > 0) - sleep(sleep_time); - } - F32 current_time = glfwGetTime(); - state.dt = current_time-last_time; - last_time = current_time; - } - - glfwTerminate(); - return(0); + if (glfwInit() == GLFW_FALSE) { + fprintf(stderr, "[ERROR] Failed to initialize glfw.\n"); + return(1); + } + + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); + glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); + S32 width = 1024; + S32 height = 768; + GLFWwindow *window = glfwCreateWindow(width, height, "Depth testing.", 0, 0); + if (!window) { + fprintf(stderr, "[ERROR] Failed to create window.\n"); + glfwTerminate(); + return(1); + } + + glfwMakeContextCurrent(window); + + if (glewInit() != GLEW_OK) { + fprintf(stderr, "[ERROR] Failed to initialize glew.\n"); + glfwTerminate(); + return(1); + } + + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_LESS); + + U32 shader = load_shader("shaders/depth.vert", "shaders/depth.frag"); + U32 marble_texture = load_texture("../../data/textures/marble.jpg"); + U32 metal_texture = load_texture("../../data/textures/metal.png"); + + F32 a = 0.5f; + F32 vertices[] = { + -a, -a, -a, 0.0f, 0.0f, + a, -a, -a, 1.0f, 0.0f, + a, a, -a, 1.0f, 1.0f, + a, a, -a, 1.0f, 1.0f, + -a, a, -a, 0.0f, 1.0f, + -a, -a, -a, 0.0f, 0.0f, + + -a, -a, a, 0.0f, 0.0f, + a, -a, a, 1.0f, 0.0f, + a, a, a, 1.0f, 1.0f, + a, a, a, 1.0f, 1.0f, + -a, a, a, 0.0f, 1.0f, + -a, -a, a, 0.0f, 0.0f, + + -a, a, a, 1.0f, 0.0f, + -a, a, -a, 1.0f, 1.0f, + -a, -a, -a, 0.0f, 1.0f, + -a, -a, -a, 0.0f, 1.0f, + -a, -a, a, 0.0f, 0.0f, + -a, a, a, 1.0f, 0.0f, + + a, a, a, 1.0f, 0.0f, + a, a, -a, 1.0f, 1.0f, + a, -a, -a, 0.0f, 1.0f, + a, -a, -a, 0.0f, 1.0f, + a, -a, a, 0.0f, 0.0f, + a, a, a, 1.0f, 0.0f, + + -a, -a, -a, 0.0f, 1.0f, + a, -a, -a, 1.0f, 1.0f, + a, -a, a, 1.0f, 0.0f, + a, -a, a, 1.0f, 0.0f, + -a, -a, a, 0.0f, 0.0f, + -a, -a, -a, 0.0f, 1.0f, + + -a, a, -a, 0.0f, 1.0f, + a, a, -a, 1.0f, 1.0f, + a, a, a, 1.0f, 0.0f, + a, a, a, 1.0f, 0.0f, + -a, a, a, 0.0f, 0.0f, + -a, a, -a, 0.0f, 1.0f + }; + + Transform cube_positions[] = { + transform_default(), + transform_make_translate(v3f(a, 0.0f, -4*a)) + }; + + V3F platform_pos = v3f(10.0f, 0.2f, 10.0f); + V3F platform_scale = v3f(0.0f, -(a+(a*0.2f)+0.01f), 0.0f); + Transform platform_transform = transform_make_scale_translate(platform_pos, platform_scale); + + U32 VAO, VBO; + glGenVertexArrays(1, &VAO); + glBindVertexArray(VAO); + glGenBuffers(1, &VBO); + glBindBuffer(GL_ARRAY_BUFFER, VBO); + glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), 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); + + State state = {0}; + Input input = {0}; + state.camera = (Camera){v3f(0.0f, 0.0f, 3.0f), 90.0f, 0.1f, 100.0f, 0.0f, 0.0f}; + + F32 target_fps = 60.0f; + F32 target_spf = 1.0f/target_fps; + F32 last_time = glfwGetTime(); + + while (!glfwWindowShouldClose(window)) { + glfwPollEvents(); + + process_glfw_keyboard(window, &input); + glfwGetFramebufferSize(window, &width, &height); + + /* INFO(pryazha): Update */ + 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); + + input_update_last_state(&input); + + /* INFO(pryazha): Render */ + MAT4 model, view, proj; + view = look_at(state.camera.pos, target, v3f(0.0f, 1.0f, 0.0f)); + /* proj = ortho(-5.0f, 5.0f, -5.0f, 5.0f, 0.1f, 100.0f); */ + proj = perspective(state.camera.fovx, (F32)width/(F32)height, + state.camera.near, state.camera.far); + + glViewport(0, 0, width, height); + glClearColor(0.15f, 0.15f, 0.15f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glUseProgram(shader); + shader_set_mat4fv(shader, "view", view); + shader_set_mat4fv(shader, "proj", proj); + glBindTexture(GL_TEXTURE_2D, marble_texture); + glBindVertexArray(VAO); + for (S32 i = 0; i < (S32)ArrayCount(cube_positions); ++i) { + model = transform_apply(cube_positions[i]); + shader_set_mat4fv(shader, "model", model); + glDrawArrays(GL_TRIANGLES, 0, 36); + } + glBindTexture(GL_TEXTURE_2D, metal_texture); + model = transform_apply(platform_transform); + shader_set_mat4fv(shader, "model", model); + glDrawArrays(GL_TRIANGLES, 0, 36); + glBindVertexArray(0); + + glfwSwapBuffers(window); + + F32 elapsed = glfwGetTime()-last_time; + if (elapsed < target_spf) { + U32 sleep_time = (U32)(target_spf-elapsed); + if (sleep_time > 0) + sleep(sleep_time); + } + F32 current_time = glfwGetTime(); + state.dt = current_time-last_time; + last_time = current_time; + } + + glfwTerminate(); + return(0); } diff --git a/advanced_opengl/10.antialiasing/anti_aliasing_msaa.c b/advanced_opengl/10.antialiasing/anti_aliasing_msaa.c index 250ab97..07c82c7 100644 --- a/advanced_opengl/10.antialiasing/anti_aliasing_msaa.c +++ b/advanced_opengl/10.antialiasing/anti_aliasing_msaa.c @@ -15,7 +15,6 @@ int main(void) F32 target_fps, target_spf, last_time; MAT4 proj, view, model; State state; - S32 width, height; U32 color_shader; if (glfwInit() == GLFW_FALSE) { @@ -23,12 +22,13 @@ int main(void) return(1); } - width = 1024; - height = 768; + S32 width = 1024; + S32 height = 768; glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); + glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE); glfwWindowHint(GLFW_SAMPLES, 4); window = glfwCreateWindow(width, height, "Anti Aliasing (MSAA)", 0, 0); if (!window) { @@ -53,8 +53,7 @@ int main(void) arena = arena_alloc(Kilobytes(4)); cube = mesh_load_obj(arena, "../../data/models/cube.obj"); - color_shader = create_shader_program("shaders/color.vert", - "shaders/color.frag"); + color_shader = load_shader("shaders/color.vert", "shaders/color.frag"); state.camera = (Camera) { v3f(0.0f, 0.0f, 3.0f), diff --git a/advanced_opengl/10.antialiasing/anti_aliasing_offscreen.c b/advanced_opengl/10.antialiasing/anti_aliasing_offscreen.c index 31f3cae..beb0d12 100644 --- a/advanced_opengl/10.antialiasing/anti_aliasing_offscreen.c +++ b/advanced_opengl/10.antialiasing/anti_aliasing_offscreen.c @@ -32,6 +32,7 @@ int main(void) glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); + glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE); window = glfwCreateWindow(width, height, "Anti Aliasing (Off-screen)", 0, 0); if (!window) { fprintf(stderr, "[ERROR] Failed to create window.\n"); @@ -52,10 +53,8 @@ int main(void) arena = arena_alloc(Kilobytes(4)); cube = mesh_load_obj(arena, "../../data/models/cube.obj"); - color_shader = create_shader_program("shaders/color.vert", - "shaders/color.frag"); - screen_shader = create_shader_program("shaders/screen.vert", - "shaders/screen.frag"); + color_shader = load_shader("shaders/color.vert", "shaders/color.frag"); + screen_shader = load_shader("shaders/screen.vert", "shaders/screen.frag"); glGenFramebuffers(1, &fbo); glBindFramebuffer(GL_FRAMEBUFFER, fbo); glGenTextures(1, &color_tex); diff --git a/advanced_opengl/10.antialiasing/build b/advanced_opengl/10.antialiasing/build new file mode 100755 index 0000000..9d1011a --- /dev/null +++ b/advanced_opengl/10.antialiasing/build @@ -0,0 +1,5 @@ +#!/bin/sh +. ../../config +set -x +gcc -o anti_aliasing_msaa $CFLAGS $INCLUDE $LFLAGS anti_aliasing_msaa.c $LIBS +gcc -o anti_aliasing_offscreen $CFLAGS $INCLUDE $LFLAGS anti_aliasing_offscreen.c $LIBS diff --git a/advanced_opengl/10.antialiasing/build.sh b/advanced_opengl/10.antialiasing/build.sh deleted file mode 100755 index 9d1011a..0000000 --- a/advanced_opengl/10.antialiasing/build.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh -. ../../config -set -x -gcc -o anti_aliasing_msaa $CFLAGS $INCLUDE $LFLAGS anti_aliasing_msaa.c $LIBS -gcc -o anti_aliasing_offscreen $CFLAGS $INCLUDE $LFLAGS anti_aliasing_offscreen.c $LIBS diff --git a/advanced_opengl/2.stencil/build b/advanced_opengl/2.stencil/build new file mode 100755 index 0000000..c4aa562 --- /dev/null +++ b/advanced_opengl/2.stencil/build @@ -0,0 +1,5 @@ +#!/bin/sh +. ../../config +TARGET='stencil' +set -x +gcc -o $TARGET $CFLAGS $INCLUDE $LFLAGS $TARGET.c $LIBS diff --git a/advanced_opengl/2.stencil/build.sh b/advanced_opengl/2.stencil/build.sh deleted file mode 100755 index c4aa562..0000000 --- a/advanced_opengl/2.stencil/build.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh -. ../../config -TARGET='stencil' -set -x -gcc -o $TARGET $CFLAGS $INCLUDE $LFLAGS $TARGET.c $LIBS diff --git a/advanced_opengl/2.stencil/stencil.c b/advanced_opengl/2.stencil/stencil.c index 3b01f5b..924d8f6 100644 --- a/advanced_opengl/2.stencil/stencil.c +++ b/advanced_opengl/2.stencil/stencil.c @@ -43,8 +43,8 @@ int main(void) glEnable(GL_STENCIL_TEST); glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); - U32 shader = create_shader_program("shaders/stencil.vert", "shaders/stencil.frag"); - U32 outline_shader = create_shader_program("shaders/stencil.vert", "shaders/outline.frag"); + U32 shader = load_shader("shaders/stencil.vert", "shaders/stencil.frag"); + U32 outline_shader = load_shader("shaders/stencil.vert", "shaders/outline.frag"); U32 marble_texture = load_texture("../../data/textures/marble.jpg"); U32 metal_texture = load_texture("../../data/textures/metal.png"); diff --git a/advanced_opengl/3.blending/blending.c b/advanced_opengl/3.blending/blending.c index 8142ab3..dcc189f 100644 --- a/advanced_opengl/3.blending/blending.c +++ b/advanced_opengl/3.blending/blending.c @@ -43,8 +43,8 @@ int main(void) glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - U32 shader = create_shader_program("shaders/blending.vert", "shaders/blending.frag"); - U32 grass_shader = create_shader_program("shaders/blending.vert", "shaders/grass.frag"); + U32 shader = load_shader("shaders/blending.vert", "shaders/blending.frag"); + U32 grass_shader = load_shader("shaders/blending.vert", "shaders/grass.frag"); U32 marble_texture = load_texture("../../data/textures/marble.jpg"); U32 metal_texture = load_texture("../../data/textures/metal.png"); U32 grass_texture = load_texture("../../data/textures/grass.png"); diff --git a/advanced_opengl/3.blending/build b/advanced_opengl/3.blending/build new file mode 100755 index 0000000..51f3629 --- /dev/null +++ b/advanced_opengl/3.blending/build @@ -0,0 +1,5 @@ +#!/bin/sh +. ../../config +TARGET='blending' +set -x +gcc -o $TARGET $CFLAGS $INCLUDE $LFLAGS $TARGET.c $LIBS diff --git a/advanced_opengl/3.blending/build.sh b/advanced_opengl/3.blending/build.sh deleted file mode 100755 index 51f3629..0000000 --- a/advanced_opengl/3.blending/build.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh -. ../../config -TARGET='blending' -set -x -gcc -o $TARGET $CFLAGS $INCLUDE $LFLAGS $TARGET.c $LIBS diff --git a/advanced_opengl/4.face_culling/build b/advanced_opengl/4.face_culling/build new file mode 100755 index 0000000..d67eefa --- /dev/null +++ b/advanced_opengl/4.face_culling/build @@ -0,0 +1,5 @@ +#!/bin/sh +. ../../config +TARGET='face_culling' +set -x +gcc -o $TARGET $CFLAGS $INCLUDE $LFLAGS $TARGET.c $LIBS diff --git a/advanced_opengl/4.face_culling/build.sh b/advanced_opengl/4.face_culling/build.sh deleted file mode 100755 index d67eefa..0000000 --- a/advanced_opengl/4.face_culling/build.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh -. ../../config -TARGET='face_culling' -set -x -gcc -o $TARGET $CFLAGS $INCLUDE $LFLAGS $TARGET.c $LIBS diff --git a/advanced_opengl/4.face_culling/face_culling.c b/advanced_opengl/4.face_culling/face_culling.c index c3a31c0..0e65e08 100644 --- a/advanced_opengl/4.face_culling/face_culling.c +++ b/advanced_opengl/4.face_culling/face_culling.c @@ -44,8 +44,7 @@ int main(void) glFrontFace(GL_CW); glCullFace(GL_BACK); - U32 shader = create_shader_program("shaders/face_culling.vert", - "shaders/face_culling.frag"); + U32 shader = load_shader("shaders/face_culling.vert", "shaders/face_culling.frag"); U32 grid_texture = load_texture("../../data/textures/grid.png"); diff --git a/advanced_opengl/5.framebuffers/build b/advanced_opengl/5.framebuffers/build new file mode 100755 index 0000000..cb55ebf --- /dev/null +++ b/advanced_opengl/5.framebuffers/build @@ -0,0 +1,5 @@ +#!/bin/sh +. ../../config +TARGET='framebuffers' +set -x +gcc -o $TARGET $CFLAGS $INCLUDE $LFLAGS $TARGET.c $LIBS diff --git a/advanced_opengl/5.framebuffers/build.sh b/advanced_opengl/5.framebuffers/build.sh deleted file mode 100755 index cb55ebf..0000000 --- a/advanced_opengl/5.framebuffers/build.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh -. ../../config -TARGET='framebuffers' -set -x -gcc -o $TARGET $CFLAGS $INCLUDE $LFLAGS $TARGET.c $LIBS diff --git a/advanced_opengl/5.framebuffers/framebuffers.c b/advanced_opengl/5.framebuffers/framebuffers.c index 7948a61..67745ef 100644 --- a/advanced_opengl/5.framebuffers/framebuffers.c +++ b/advanced_opengl/5.framebuffers/framebuffers.c @@ -24,6 +24,7 @@ int main(void) glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); + glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE); window = glfwCreateWindow(width, height, "Framebuffers", 0, 0); if (!window) { fprintf(stderr, "[ERROR] Failed to create window.\n"); @@ -39,10 +40,8 @@ int main(void) return(1); } - U32 screen_shader = create_shader_program("shaders/screen.vert", - "shaders/screen.frag"); - U32 cube_shader = create_shader_program("shaders/cube.vert", - "shaders/cube.frag"); + U32 screen_shader = load_shader("shaders/screen.vert", "shaders/screen.frag"); + U32 cube_shader = load_shader("shaders/cube.vert", "shaders/cube.frag"); U32 marble_texture = load_texture("../../data/textures/marble.jpg"); U32 metal_texture = load_texture("../../data/textures/metal.png"); U32 window_texture = load_texture("../../data/textures/window.png"); @@ -56,14 +55,12 @@ int main(void) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glBindTexture(GL_TEXTURE_2D, 0); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, - GL_TEXTURE_2D, texture_colorbuffer, 0); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture_colorbuffer, 0); glGenRenderbuffers(1, &rbo); glBindRenderbuffer(GL_RENDERBUFFER, rbo); glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height); glBindRenderbuffer(GL_RENDERBUFFER, 0); - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, - GL_RENDERBUFFER, rbo); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo); if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) fprintf(stderr, "[ERROR]: Framebuffer is not complete.\n"); glBindFramebuffer(GL_FRAMEBUFFER, 0); @@ -120,8 +117,7 @@ int main(void) V3F platform_pos = v3f(10.0f, 0.2f, 10.0f); V3F platform_scale = v3f(0.0f, -(a+(a*0.2f)+0.01f), 0.0f); - Transform platform_transform = transform_make_scale_translate(platform_pos, - platform_scale); + Transform platform_transform = transform_make_scale_translate(platform_pos, platform_scale); U32 cube_vao, quad_vao, vbo; glGenVertexArrays(1, &cube_vao); glBindVertexArray(cube_vao); diff --git a/advanced_opengl/6.cubemaps/build b/advanced_opengl/6.cubemaps/build new file mode 100755 index 0000000..9bda0bc --- /dev/null +++ b/advanced_opengl/6.cubemaps/build @@ -0,0 +1,5 @@ +#!/bin/sh +. ../../config +TARGET='cubemaps' +set -x +gcc -o $TARGET $CFLAGS $INCLUDE $LFLAGS $TARGET.c $LIBS diff --git a/advanced_opengl/6.cubemaps/build.sh b/advanced_opengl/6.cubemaps/build.sh deleted file mode 100755 index 9bda0bc..0000000 --- a/advanced_opengl/6.cubemaps/build.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh -. ../../config -TARGET='cubemaps' -set -x -gcc -o $TARGET $CFLAGS $INCLUDE $LFLAGS $TARGET.c $LIBS diff --git a/advanced_opengl/6.cubemaps/cubemaps.c b/advanced_opengl/6.cubemaps/cubemaps.c index 32a53d1..d1088a4 100644 --- a/advanced_opengl/6.cubemaps/cubemaps.c +++ b/advanced_opengl/6.cubemaps/cubemaps.c @@ -24,6 +24,7 @@ int main(void) glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); + glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE); window = glfwCreateWindow(width, height, "Cubemaps", 0, 0); if (!window) { fprintf(stderr, "[ERROR] Failed to create window.\n"); @@ -44,10 +45,10 @@ int main(void) glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); - U32 skybox_shader = create_shader_program("shaders/skybox.vert", "shaders/skybox.frag"); - U32 reflection_shader = create_shader_program("shaders/reflection.vert", "shaders/reflection.frag"); - U32 refraction_shader = create_shader_program("shaders/refraction.vert", "shaders/refraction.frag"); - U32 cube_shader = create_shader_program("shaders/cube.vert", "shaders/cube.frag"); + U32 skybox_shader = load_shader("shaders/skybox.vert", "shaders/skybox.frag"); + U32 reflection_shader = load_shader("shaders/reflection.vert", "shaders/reflection.frag"); + U32 refraction_shader = load_shader("shaders/refraction.vert", "shaders/refraction.frag"); + U32 cube_shader = load_shader("shaders/cube.vert", "shaders/cube.frag"); U32 grid_texture = load_texture("../../data/textures/grid.png"); const char *cube_texture_filenames[6] = { diff --git a/advanced_opengl/7.uniform_buffer/build b/advanced_opengl/7.uniform_buffer/build new file mode 100755 index 0000000..54642df --- /dev/null +++ b/advanced_opengl/7.uniform_buffer/build @@ -0,0 +1,5 @@ +#!/bin/sh +. ../../config +TARGET='uniform_buffer' +set -x +gcc -o $TARGET $CFLAGS $INCLUDE $LFLAGS $TARGET.c $LIBS diff --git a/advanced_opengl/7.uniform_buffer/build.sh b/advanced_opengl/7.uniform_buffer/build.sh deleted file mode 100755 index 54642df..0000000 --- a/advanced_opengl/7.uniform_buffer/build.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh -. ../../config -TARGET='uniform_buffer' -set -x -gcc -o $TARGET $CFLAGS $INCLUDE $LFLAGS $TARGET.c $LIBS diff --git a/advanced_opengl/7.uniform_buffer/uniform_buffer.c b/advanced_opengl/7.uniform_buffer/uniform_buffer.c index a27c115..752b171 100644 --- a/advanced_opengl/7.uniform_buffer/uniform_buffer.c +++ b/advanced_opengl/7.uniform_buffer/uniform_buffer.c @@ -24,6 +24,7 @@ int main(void) glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); + glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE); window = glfwCreateWindow(width, height, "Advanced data (uniform buffer)", 0, 0); if (!window) { fprintf(stderr, "[ERROR] Failed to create window.\n"); @@ -44,9 +45,9 @@ int main(void) glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); - U32 skybox_shader = create_shader_program("shaders/skybox.vert", "shaders/skybox.frag"); - U32 cube_shader = create_shader_program("shaders/cube.vert", "shaders/cube.frag"); - U32 color_cube_shader = create_shader_program("shaders/color_cube.vert", "shaders/color_cube.frag"); + U32 skybox_shader = load_shader("shaders/skybox.vert", "shaders/skybox.frag"); + U32 cube_shader = load_shader("shaders/cube.vert", "shaders/cube.frag"); + U32 color_cube_shader = load_shader("shaders/color_cube.vert", "shaders/color_cube.frag"); U32 skybox_matrices = glGetUniformBlockIndex(skybox_shader, "Matrices"); U32 cube_matrices = glGetUniformBlockIndex(cube_shader, "Matrices"); @@ -235,12 +236,10 @@ int main(void) state.camera.near, state.camera.far); glBindBuffer(GL_UNIFORM_BUFFER, matrices_ubo); - glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(MAT4), - (const void *)&proj); + glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(MAT4), (const void *)&proj); glBindBuffer(GL_UNIFORM_BUFFER, 0); glBindBuffer(GL_UNIFORM_BUFFER, matrices_ubo); - glBufferSubData(GL_UNIFORM_BUFFER, sizeof(MAT4), - sizeof(MAT4), (const void *)&view); + glBufferSubData(GL_UNIFORM_BUFFER, sizeof(MAT4), sizeof(MAT4), (const void *)&view); glBindBuffer(GL_UNIFORM_BUFFER, 0); glClearColor(0.15f, 0.15f, 0.15f, 1.0f); diff --git a/advanced_opengl/8.geometry_shader/build b/advanced_opengl/8.geometry_shader/build new file mode 100755 index 0000000..f3339cb --- /dev/null +++ b/advanced_opengl/8.geometry_shader/build @@ -0,0 +1,5 @@ +#!/bin/sh +. ../../config +TARGET='geometry_shader' +set -x +gcc -o $TARGET $CFLAGS $INCLUDE $LFLAGS $TARGET.c $LIBS diff --git a/advanced_opengl/8.geometry_shader/build.sh b/advanced_opengl/8.geometry_shader/build.sh deleted file mode 100755 index f3339cb..0000000 --- a/advanced_opengl/8.geometry_shader/build.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh -. ../../config -TARGET='geometry_shader' -set -x -gcc -o $TARGET $CFLAGS $INCLUDE $LFLAGS $TARGET.c $LIBS diff --git a/advanced_opengl/8.geometry_shader/geometry_shader.c b/advanced_opengl/8.geometry_shader/geometry_shader.c index f242709..03bb7b9 100644 --- a/advanced_opengl/8.geometry_shader/geometry_shader.c +++ b/advanced_opengl/8.geometry_shader/geometry_shader.c @@ -33,6 +33,7 @@ int main(void) glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); + glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE); window = glfwCreateWindow(width, height, "depth testing", 0, 0); if (!window) { fprintf(stderr, "[ERROR] Failed to create window.\n"); @@ -50,17 +51,10 @@ int main(void) glEnable(GL_DEPTH_TEST); - U32 shader = create_shader_program_geom("shaders/base.vert", - "shaders/base.frag", - "shaders/base.geom"); - U32 explosion_shader = create_shader_program_geom("shaders/explosion.vert", - "shaders/explosion.frag", - "shaders/explosion.geom"); - U32 normals_shader = create_shader_program_geom("shaders/normals.vert", - "shaders/normals.frag", - "shaders/normals.geom"); - U32 basic_shader = create_shader_program("shaders/basic.vert", - "shaders/basic.frag"); + U32 shader = load_shader_geom("shaders/base.vert", "shaders/base.frag", "shaders/base.geom"); + U32 explosion_shader = load_shader_geom("shaders/explosion.vert", "shaders/explosion.frag", "shaders/explosion.geom"); + U32 normals_shader = load_shader_geom("shaders/normals.vert", "shaders/normals.frag", "shaders/normals.geom"); + U32 basic_shader = load_shader("shaders/basic.vert", "shaders/basic.frag"); U32 grid_texture = load_texture("../../data/textures/grid.png"); diff --git a/advanced_opengl/9.instancing/build b/advanced_opengl/9.instancing/build new file mode 100755 index 0000000..ebb6a01 --- /dev/null +++ b/advanced_opengl/9.instancing/build @@ -0,0 +1,6 @@ +#!/bin/sh +. ../../config +CFLAGS='-O2' +TARGET='instancing' +set -x +gcc -o $TARGET $CFLAGS $INCLUDE $LFLAGS $TARGET.c $LIBS diff --git a/advanced_opengl/9.instancing/build.sh b/advanced_opengl/9.instancing/build.sh deleted file mode 100755 index ebb6a01..0000000 --- a/advanced_opengl/9.instancing/build.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh -. ../../config -CFLAGS='-O2' -TARGET='instancing' -set -x -gcc -o $TARGET $CFLAGS $INCLUDE $LFLAGS $TARGET.c $LIBS diff --git a/advanced_opengl/9.instancing/instancing.c b/advanced_opengl/9.instancing/instancing.c index e77c693..16fd373 100644 --- a/advanced_opengl/9.instancing/instancing.c +++ b/advanced_opengl/9.instancing/instancing.c @@ -26,6 +26,7 @@ int main(void) glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); + glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE); window = glfwCreateWindow(width, height, "Instancing", 0, 0); if (!window) { fprintf(stderr, "[ERROR] Failed to create window.\n"); @@ -44,13 +45,13 @@ int main(void) glEnable(GL_DEPTH_TEST); - U32 instancing_uniform_array_shader = create_shader_program("shaders/instancing_uniform_array.vert", + U32 instancing_uniform_array_shader = load_shader("shaders/instancing_uniform_array.vert", "shaders/instancing_uniform_array.frag"); - U32 instanced_arrays_shader = create_shader_program("shaders/instanced_arrays.vert", + U32 instanced_arrays_shader = load_shader("shaders/instanced_arrays.vert", "shaders/instanced_arrays.frag"); - U32 default_shader = create_shader_program("shaders/default.vert", + U32 default_shader = load_shader("shaders/default.vert", "shaders/default.frag"); - U32 instanced_shader = create_shader_program("shaders/instanced_mat4.vert", + U32 instanced_shader = load_shader("shaders/instanced_mat4.vert", "shaders/instanced_mat4.frag"); F32 quad_vertices[] = { diff --git a/advanced_opengl/build b/advanced_opengl/build new file mode 100755 index 0000000..4829c7d --- /dev/null +++ b/advanced_opengl/build @@ -0,0 +1,9 @@ +#!/bin/sh +targets=$(ls) +for target in $targets ; do + if [ $target != 'build.sh' ] ; then + cd $target + ./build.sh + cd .. + fi +done diff --git a/advanced_opengl/build.sh b/advanced_opengl/build.sh deleted file mode 100755 index 4829c7d..0000000 --- a/advanced_opengl/build.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/sh -targets=$(ls) -for target in $targets ; do - if [ $target != 'build.sh' ] ; then - cd $target - ./build.sh - cd .. - fi -done diff --git a/libs/common.h b/libs/common.h index b535c72..c373e9a 100644 --- a/libs/common.h +++ b/libs/common.h @@ -12,28 +12,24 @@ #include #include -U8 *read_entire_file(const char *filename) +char *read_entire_file(const char *filename) { - U8 *result; - FILE *f; - long file_size; - - result = 0; + char *result = 0; if (!filename) return(result); - f = fopen(filename, "rb"); - if (!f) + FILE *file = fopen(filename, "rb"); + if (!file) return(result); - fseek(f, 0, SEEK_END); - file_size = ftell(f); - fseek(f, 0, SEEK_SET); + fseek(file, 0, SEEK_END); + long file_size = ftell(file); + fseek(file, 0, SEEK_SET); - result = malloc(file_size + 1); - fread(result, file_size, 1, f); - fclose(f); + result = malloc(file_size+1); + fread(result, file_size, 1, file); + fclose(file); result[file_size] = 0; @@ -42,16 +38,13 @@ U8 *read_entire_file(const char *filename) void *mmap_file(size_t *len, const char *filename) { - struct stat sb; - char* p; - int fd; - - fd = open(filename, O_RDONLY); + int fd = open(filename, O_RDONLY); if (fd == -1) { perror("open"); return NULL; } + struct stat sb; if (fstat(fd, &sb) == -1) { perror("fstat"); return NULL; @@ -62,7 +55,7 @@ void *mmap_file(size_t *len, const char *filename) return NULL; } - p = (char*)mmap(0, sb.st_size, PROT_READ, MAP_SHARED, fd, 0); + char *p = (char*)mmap(0, sb.st_size, PROT_READ, MAP_SHARED, fd, 0); if (p == MAP_FAILED) { perror("mmap"); @@ -97,28 +90,21 @@ void read_entire_file_mmap(void* ctx, const char* filename, const int is_mtl, Mesh *mesh_gen_quad(Arena *arena) { - Mesh *m; - Vertex verts[4]; - U32 ids[6]; - - m = 0; - - verts[0] = vertex(v3f( 1.0f, 1.0f, 0.0f), v3f_zero(), v2f(1.0f, 1.0f)); - verts[1] = vertex(v3f(-1.0f, 1.0f, 0.0f), v3f_zero(), v2f(0.0f, 1.0f)); - verts[2] = vertex(v3f(-1.0f, -1.0f, 0.0f), v3f_zero(), v2f(0.0f, 0.0f)); - verts[3] = vertex(v3f( 1.0f, -1.0f, 0.0f), v3f_zero(), v2f(1.0f, 0.0f)); + Vertex verts[4] = { + vertex(v3f( 1.0f, 1.0f, 0.0f), v3f_zero(), v2f(1.0f, 1.0f)), + vertex(v3f(-1.0f, 1.0f, 0.0f), v3f_zero(), v2f(0.0f, 1.0f)), + vertex(v3f(-1.0f, -1.0f, 0.0f), v3f_zero(), v2f(0.0f, 0.0f)), + vertex(v3f( 1.0f, -1.0f, 0.0f), v3f_zero(), v2f(1.0f, 0.0f)), + }; - ids[0] = 0; - ids[1] = 1; - ids[2] = 2; + U32 ids[6] = { + 0, 1, 2, + 0, 2, 3 + }; - ids[3] = 0; - ids[4] = 2; - ids[5] = 3; + Mesh *mesh = mesh_init(arena, verts, 4, ids, 6); - m = mesh_init(arena, verts, 4, ids, 6); - - return m; + return mesh; } Mesh *mesh_load_obj(Arena *arena, const char *filename) @@ -158,7 +144,7 @@ Mesh *mesh_load_obj(Arena *arena, const char *filename) Assert(attrib.face_num_verts[i]%3 == 0); - Assert(attrib.face_num_verts[i]/3 > 3); + Assert(attrib.face_num_verts[i]/3 > 0); Assert(attrib.num_texcoords); @@ -198,87 +184,80 @@ Mesh *mesh_load_obj(Arena *arena, const char *filename) U32 compile_shader(GLenum type, const char *filename) { - U32 shader; - S32 status; - char logs[512]; - const char *source = (const char *)read_entire_file(filename); if (!source) { fprintf(stderr, "[ERROR]: Failed to read the file \"%s\"\n", filename); return(0); } - shader = glCreateShader(type); + U32 shader = glCreateShader(type); glShaderSource(shader, 1, &source, 0); free((void *)source); glCompileShader(shader); + + S32 status; glGetShaderiv(shader, GL_COMPILE_STATUS, &status); if (status == GL_FALSE) { - glGetShaderInfoLog(shader, 512, 0, logs); - fprintf(stderr, "[ERROR]: Failed to compile: \"%s\"\n%s", filename, logs); + char log[512]; + glGetShaderInfoLog(shader, 512, 0, log); + fprintf(stderr, "error: failed to compile: \"%s\"\n%s", filename, log); } else { - fprintf(stdout, "[INFO]: \"%s\" compiled successfuly.\n", filename); + fprintf(stdout, "info: \"%s\" compiled successfuly.\n", filename); } return(shader); } -U32 create_shader_program(char *vertex_shader_filename, - char *fragment_shader_filename) +U32 load_shader(const char *vert_filename, const char *frag_filename) { - S32 success; - char logs[512]; + U32 vert = compile_shader(GL_VERTEX_SHADER, vert_filename); + U32 frag = compile_shader(GL_FRAGMENT_SHADER, frag_filename); - U32 vertex_shader = compile_shader(GL_VERTEX_SHADER, vertex_shader_filename); - U32 fragment_shader = compile_shader(GL_FRAGMENT_SHADER, fragment_shader_filename); + U32 program = glCreateProgram(); + glAttachShader(program, vert); + glAttachShader(program, frag); + glLinkProgram(program); - U32 shader_program; - shader_program = glCreateProgram(); - glAttachShader(shader_program, vertex_shader); - glAttachShader(shader_program, fragment_shader); - glLinkProgram(shader_program); - glGetProgramiv(shader_program, GL_LINK_STATUS, &success); + S32 success; + glGetProgramiv(program, GL_LINK_STATUS, &success); if (success == GL_FALSE) { - glGetProgramInfoLog(shader_program, 512, 0, logs); - fprintf(stderr, "[ERROR]: Failed to link shader program:\n%s", logs); + char log[512]; + glGetProgramInfoLog(program, 512, 0, log); + fprintf(stderr, "error: failed to link program:\n%s\n", log); } else { - fprintf(stdout, "[INFO]: Shader program linked successfuly.\n\n"); + fprintf(stdout, "info: compiled successully\n\n"); } - glDeleteShader(vertex_shader); - glDeleteShader(fragment_shader); + glDeleteShader(vert); + glDeleteShader(frag); - return(shader_program); + return(program); } -U32 create_shader_program_geom(char *vertex_shader_filename, - char *fragment_shader_filename, - char *geometry_shader_filename) +U32 load_shader_geom(const char *vert_filename, const char *frag_filename, const char *geom_filename) { + U32 vert = compile_shader(GL_VERTEX_SHADER, vert_filename); + U32 frag = compile_shader(GL_FRAGMENT_SHADER, frag_filename); + U32 geom = compile_shader(GL_GEOMETRY_SHADER, geom_filename); + + U32 program = glCreateProgram(); + glAttachShader(program, vert); + glAttachShader(program, frag); + glAttachShader(program, geom); + glLinkProgram(program); + S32 success; - char logs[512]; - - U32 vertex_shader = compile_shader(GL_VERTEX_SHADER, vertex_shader_filename); - U32 fragment_shader = compile_shader(GL_FRAGMENT_SHADER, fragment_shader_filename); - U32 geometry_shader = compile_shader(GL_GEOMETRY_SHADER, geometry_shader_filename); - - U32 shader_program; - shader_program = glCreateProgram(); - glAttachShader(shader_program, vertex_shader); - glAttachShader(shader_program, fragment_shader); - glAttachShader(shader_program, geometry_shader); - glLinkProgram(shader_program); - glGetProgramiv(shader_program, GL_LINK_STATUS, &success); + glGetProgramiv(program, GL_LINK_STATUS, &success); if (success == GL_FALSE) { - glGetProgramInfoLog(shader_program, 512, 0, logs); - fprintf(stderr, "[ERROR]: Failed to link shader program:\n%s", - logs); + char log[512]; + glGetProgramInfoLog(program, 512, 0, log); + fprintf(stderr, "error: failed to link shader program:\n%s\n", log); } else { - fprintf(stdout, "[INFO]: Shader program linked successfuly.\n\n"); + fprintf(stdout, "info: shader program linked successfuly.\n\n"); } - glDeleteShader(vertex_shader); - glDeleteShader(fragment_shader); - glDeleteShader(geometry_shader); + glDeleteShader(vert); + glDeleteShader(frag); + glDeleteShader(geom); - return(shader_program); + return(program); } void shader_set_3f(U32 shader_program, char *uniform_name, F32 x, F32 y, F32 z) @@ -319,12 +298,11 @@ void shader_set_1i(U32 shader_program, char *uniform_name, S32 value) U32 load_texture(char *texture_filename) { - S32 width, height, number_channels; U32 texture_id; - glGenTextures(1, &texture_id); stbi_set_flip_vertically_on_load(1); + S32 width, height, number_channels; U8 *data = stbi_load(texture_filename, &width, &height, &number_channels, 0); if (data) { GLenum format = 0; @@ -344,11 +322,9 @@ U32 load_texture(char *texture_filename) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glBindTexture(GL_TEXTURE_2D, 0); - fprintf(stdout, "[INFO]: Texture (\"%s\") is loaded successfully\n", - texture_filename); + fprintf(stdout, "info: texture (\"%s\") is loaded successfully\n", texture_filename); } else { - fprintf(stderr, "[ERROR]: Failed to load texture: \"%s\"\n", - texture_filename); + fprintf(stderr, "error: failed to load texture: \"%s\"\n", texture_filename); } stbi_image_free(data); @@ -461,9 +437,9 @@ typedef struct { Input input_init() { - Input r = {0}; - r.first_mouse = 1; - return(r); + Input input = {0}; + input.first_mouse = 1; + return(input); } void input_update_last_state(Input *input) @@ -765,8 +741,7 @@ void get_camera_vectors(Camera *camera, V3F *l, V3F *u, V3F *f) *f = v3f(-view.m0.z, -view.m1.z, -view.m2.z); } -V3F get_dv_camera_first_person(Input *input, Camera *camera, - F32 acceleration, F32 dt) +V3F get_dv_camera_first_person(Input *input, Camera *camera, F32 acceleration, F32 dt) { V3F f, l, u, dv; get_camera_vectors(camera, &l, &u, &f); @@ -800,6 +775,11 @@ MAT4 camera_persp(Camera camera, F32 ar) return result; } +typedef struct { + V3F position; + V3F color; +} light_t; + typedef struct { Arena *arena; @@ -811,4 +791,9 @@ typedef struct { F32 dt; } State; +F32 lerp(F32 a, F32 b, F32 f) +{ + return a + f * (b - a); +} + #endif /* COMMON_H */ diff --git a/libs/pwyazh/v3f.h b/libs/pwyazh/v3f.h index ba2e140..f1b4ff7 100644 --- a/libs/pwyazh/v3f.h +++ b/libs/pwyazh/v3f.h @@ -8,6 +8,13 @@ v3f(F32 x, F32 y, F32 z) return(result); } +V3F +v3f_from_v4f(V4F a) +{ + V3F result = { a.x, a.y, a.z }; + return(result); +} + V3F v3f_zero() { -- cgit v1.2.3-70-g09d2