diff options
author | pryazha <pryadeiniv@mail.ru> | 2025-02-19 22:26:48 +0500 |
---|---|---|
committer | pryazha <pryadeiniv@mail.ru> | 2025-02-19 22:26:48 +0500 |
commit | f9ad6fa902c1167d7622ee7af2617d14b62bee21 (patch) | |
tree | 9d78792cf360ed871616a9ea66c4237018292aa7 | |
parent | 926cbd0d49890772f911e6a6bedb7835605ced89 (diff) |
quite a lot of changes that I, of course, are not going to describe;)
-rw-r--r-- | advanced_lighting/1.blinn_phong/blinn_phong.c | 364 | ||||
-rw-r--r-- | advanced_lighting/1.blinn_phong/shaders/blinn_phong.frag (renamed from advanced_lighting/1.blinn_phong/shaders/blinn_phong.fs) | 10 | ||||
-rw-r--r-- | advanced_lighting/1.blinn_phong/shaders/blinn_phong.vert (renamed from advanced_lighting/2.gamma_correction/shaders/blinn_phong.vs) | 7 | ||||
-rw-r--r-- | advanced_lighting/1.blinn_phong/shaders/light.frag (renamed from advanced_lighting/2.gamma_correction/shaders/light.fs) | 3 | ||||
-rw-r--r-- | advanced_lighting/1.blinn_phong/shaders/light.vert (renamed from advanced_lighting/2.gamma_correction/shaders/light.vs) | 7 | ||||
-rw-r--r-- | advanced_lighting/2.gamma_correction/gamma_correction.c | 450 | ||||
-rw-r--r-- | advanced_lighting/2.gamma_correction/shaders/blinn_phong.frag (renamed from advanced_lighting/2.gamma_correction/shaders/blinn_phong.fs) | 11 | ||||
-rw-r--r-- | advanced_lighting/2.gamma_correction/shaders/blinn_phong.vert (renamed from advanced_lighting/1.blinn_phong/shaders/blinn_phong.vs) | 7 | ||||
-rw-r--r-- | advanced_lighting/2.gamma_correction/shaders/light.frag (renamed from advanced_lighting/3.1.shadow_mapping/shaders/color.fs) | 3 | ||||
-rw-r--r-- | advanced_lighting/2.gamma_correction/shaders/light.vert (renamed from advanced_lighting/3.1.shadow_mapping/shaders/color.vs) | 7 | ||||
-rwxr-xr-x | advanced_lighting/3.1.shadow_mapping/build.sh | 2 | ||||
-rw-r--r-- | advanced_lighting/3.1.shadow_mapping/shaders/color.frag (renamed from advanced_lighting/1.blinn_phong/shaders/light.fs) | 3 | ||||
-rw-r--r-- | advanced_lighting/3.1.shadow_mapping/shaders/color.vert (renamed from advanced_opengl/10.antialiasing/shaders/color.vs) | 7 | ||||
-rw-r--r-- | advanced_lighting/3.1.shadow_mapping/shaders/debug_quad.frag (renamed from advanced_lighting/3.1.shadow_mapping/shaders/debug_quad.fs) | 6 | ||||
-rw-r--r-- | advanced_lighting/3.1.shadow_mapping/shaders/debug_quad.vert (renamed from advanced_lighting/3.1.shadow_mapping/shaders/debug_quad.vs) | 0 | ||||
-rw-r--r-- | advanced_lighting/3.1.shadow_mapping/shaders/shadow.frag (renamed from advanced_lighting/3.1.shadow_mapping/shaders/shadow.fs) | 6 | ||||
-rw-r--r-- | advanced_lighting/3.1.shadow_mapping/shaders/shadow.vert (renamed from advanced_lighting/3.1.shadow_mapping/shaders/shadow.vs) | 7 | ||||
-rw-r--r-- | advanced_lighting/3.1.shadow_mapping/shaders/simple_depth.frag (renamed from advanced_lighting/3.1.shadow_mapping/shaders/simple_depth.fs) | 3 | ||||
-rw-r--r-- | advanced_lighting/3.1.shadow_mapping/shaders/simple_depth.vert (renamed from advanced_lighting/3.1.shadow_mapping/shaders/simple_depth.vs) | 3 | ||||
-rw-r--r-- | advanced_lighting/3.1.shadow_mapping/shadow_mapping.c | 668 | ||||
-rwxr-xr-x | advanced_lighting/3.2.point_shadows/point_shadows | bin | 1065440 -> 1289368 bytes | |||
-rw-r--r-- | advanced_lighting/3.2.point_shadows/point_shadows.c | 620 | ||||
-rw-r--r-- | advanced_lighting/3.2.point_shadows/shaders/depth.frag (renamed from advanced_lighting/3.2.point_shadows/shaders/depth.fs) | 3 | ||||
-rw-r--r-- | advanced_lighting/3.2.point_shadows/shaders/depth.geom (renamed from advanced_lighting/3.2.point_shadows/shaders/depth.gs) | 13 | ||||
-rw-r--r-- | advanced_lighting/3.2.point_shadows/shaders/depth.vert (renamed from advanced_lighting/3.2.point_shadows/shaders/depth.vs) | 3 | ||||
-rw-r--r-- | advanced_lighting/3.2.point_shadows/shaders/shadow.frag (renamed from advanced_lighting/3.2.point_shadows/shaders/shadow.fs) | 6 | ||||
-rw-r--r-- | advanced_lighting/3.2.point_shadows/shaders/shadow.vert (renamed from advanced_lighting/3.2.point_shadows/shaders/shadow.vs) | 7 | ||||
-rwxr-xr-x | advanced_lighting/4.normal_mapping/normal_mapping | bin | 1289656 -> 1289432 bytes | |||
-rw-r--r-- | advanced_lighting/4.normal_mapping/normal_mapping.c | 521 | ||||
-rw-r--r-- | advanced_lighting/4.normal_mapping/shaders/color.frag | 8 | ||||
-rw-r--r-- | advanced_lighting/4.normal_mapping/shaders/color.vert (renamed from advanced_lighting/1.blinn_phong/shaders/light.vs) | 7 | ||||
-rw-r--r-- | advanced_lighting/4.normal_mapping/shaders/depth.fs | 14 | ||||
-rw-r--r-- | advanced_lighting/4.normal_mapping/shaders/depth.gs | 27 | ||||
-rw-r--r-- | advanced_lighting/4.normal_mapping/shaders/depth.vs | 10 | ||||
-rw-r--r-- | advanced_lighting/4.normal_mapping/shaders/normal_map.frag | 51 | ||||
-rw-r--r-- | advanced_lighting/4.normal_mapping/shaders/normal_map.vert | 36 | ||||
-rw-r--r-- | advanced_lighting/4.normal_mapping/shaders/normals_debug.frag | 10 | ||||
-rw-r--r-- | advanced_lighting/4.normal_mapping/shaders/normals_debug.geom | 44 | ||||
-rw-r--r-- | advanced_lighting/4.normal_mapping/shaders/normals_debug.vert | 22 | ||||
-rw-r--r-- | advanced_lighting/4.normal_mapping/shaders/shadow.fs | 105 | ||||
-rw-r--r-- | advanced_lighting/4.normal_mapping/shaders/shadow.vs | 29 | ||||
-rwxr-xr-x | advanced_opengl/1.depth/depth | bin | 1282544 -> 1283928 bytes | |||
-rw-r--r-- | advanced_opengl/1.depth/depth.c | 433 | ||||
-rw-r--r-- | advanced_opengl/1.depth/shaders/depth.frag (renamed from advanced_opengl/1.depth/shaders/depth.fs) | 10 | ||||
-rw-r--r-- | advanced_opengl/1.depth/shaders/depth.vert (renamed from advanced_opengl/1.depth/shaders/depth.vs) | 7 | ||||
-rwxr-xr-x | advanced_opengl/10.antialiasing/anti_aliasing_msaa | bin | 1277808 -> 1279192 bytes | |||
-rw-r--r-- | advanced_opengl/10.antialiasing/anti_aliasing_msaa.c | 309 | ||||
-rwxr-xr-x | advanced_opengl/10.antialiasing/anti_aliasing_offscreen | bin | 1278840 -> 1284864 bytes | |||
-rw-r--r-- | advanced_opengl/10.antialiasing/anti_aliasing_offscreen.c | 453 | ||||
-rw-r--r-- | advanced_opengl/10.antialiasing/shaders/color.frag (renamed from advanced_opengl/2.stencil/shaders/outline.fs) | 3 | ||||
-rw-r--r-- | advanced_opengl/10.antialiasing/shaders/color.vert | 11 | ||||
-rw-r--r-- | advanced_opengl/10.antialiasing/shaders/screen.frag (renamed from advanced_opengl/10.antialiasing/shaders/screen.fs) | 21 | ||||
-rw-r--r-- | advanced_opengl/10.antialiasing/shaders/screen.vert (renamed from advanced_opengl/10.antialiasing/shaders/screen.vs) | 3 | ||||
-rw-r--r-- | advanced_opengl/2.stencil/shaders/outline.frag (renamed from advanced_opengl/10.antialiasing/shaders/color.fs) | 3 | ||||
-rw-r--r-- | advanced_opengl/2.stencil/shaders/stencil.frag (renamed from advanced_opengl/2.stencil/shaders/stencil.fs) | 0 | ||||
-rw-r--r-- | advanced_opengl/2.stencil/shaders/stencil.vert (renamed from advanced_opengl/4.face_culling/shaders/face_culling.vs) | 7 | ||||
-rwxr-xr-x | advanced_opengl/2.stencil/stencil | bin | 1282928 -> 1284368 bytes | |||
-rw-r--r-- | advanced_opengl/2.stencil/stencil.c | 486 | ||||
-rwxr-xr-x | advanced_opengl/3.blending/blending | bin | 1287936 -> 1289368 bytes | |||
-rw-r--r-- | advanced_opengl/3.blending/blending.c | 625 | ||||
-rw-r--r-- | advanced_opengl/3.blending/shaders/blending.frag (renamed from advanced_opengl/6.cubemaps/shaders/cube.fs) | 3 | ||||
-rw-r--r-- | advanced_opengl/3.blending/shaders/blending.vert (renamed from advanced_opengl/3.blending/shaders/blending.vs) | 7 | ||||
-rw-r--r-- | advanced_opengl/3.blending/shaders/grass.frag (renamed from advanced_opengl/3.blending/shaders/grass.fs) | 6 | ||||
-rwxr-xr-x | advanced_opengl/4.face_culling/face_culling | bin | 1283016 -> 1288616 bytes | |||
-rw-r--r-- | advanced_opengl/4.face_culling/face_culling.c | 515 | ||||
-rw-r--r-- | advanced_opengl/4.face_culling/shaders/face_culling.frag (renamed from advanced_opengl/3.blending/shaders/blending.fs) | 3 | ||||
-rw-r--r-- | advanced_opengl/4.face_culling/shaders/face_culling.vert (renamed from advanced_opengl/2.stencil/shaders/stencil.vs) | 7 | ||||
-rwxr-xr-x | advanced_opengl/5.framebuffers/framebuffers | bin | 1288768 -> 1294320 bytes | |||
-rw-r--r-- | advanced_opengl/5.framebuffers/framebuffers.c | 735 | ||||
-rw-r--r-- | advanced_opengl/5.framebuffers/shaders/cube.frag (renamed from advanced_opengl/5.framebuffers/shaders/cube.fs) | 3 | ||||
-rw-r--r-- | advanced_opengl/5.framebuffers/shaders/cube.vert (renamed from advanced_opengl/5.framebuffers/shaders/cube.vs) | 7 | ||||
-rw-r--r-- | advanced_opengl/5.framebuffers/shaders/screen.frag (renamed from advanced_opengl/5.framebuffers/shaders/screen.fs) | 24 | ||||
-rw-r--r-- | advanced_opengl/5.framebuffers/shaders/screen.vert (renamed from advanced_opengl/5.framebuffers/shaders/screen.vs) | 3 | ||||
-rwxr-xr-x | advanced_opengl/6.cubemaps/cubemaps | bin | 1288160 -> 1293704 bytes | |||
-rw-r--r-- | advanced_opengl/6.cubemaps/cubemaps.c | 774 | ||||
-rw-r--r-- | advanced_opengl/6.cubemaps/shaders/cube.frag (renamed from advanced_opengl/4.face_culling/shaders/face_culling.fs) | 3 | ||||
-rw-r--r-- | advanced_opengl/6.cubemaps/shaders/cube.vert (renamed from advanced_opengl/6.cubemaps/shaders/cube.vs) | 7 | ||||
-rw-r--r-- | advanced_opengl/6.cubemaps/shaders/reflection.frag (renamed from advanced_opengl/6.cubemaps/shaders/reflection.fs) | 3 | ||||
-rw-r--r-- | advanced_opengl/6.cubemaps/shaders/reflection.vert (renamed from advanced_opengl/6.cubemaps/shaders/reflection.vs) | 7 | ||||
-rw-r--r-- | advanced_opengl/6.cubemaps/shaders/refraction.frag (renamed from advanced_opengl/6.cubemaps/shaders/refraction.fs) | 3 | ||||
-rw-r--r-- | advanced_opengl/6.cubemaps/shaders/refraction.vert (renamed from advanced_opengl/6.cubemaps/shaders/refraction.vs) | 7 | ||||
-rw-r--r-- | advanced_opengl/6.cubemaps/shaders/skybox.frag (renamed from advanced_opengl/6.cubemaps/shaders/skybox.fs) | 3 | ||||
-rw-r--r-- | advanced_opengl/6.cubemaps/shaders/skybox.vert (renamed from advanced_opengl/6.cubemaps/shaders/skybox.vs) | 7 | ||||
-rw-r--r-- | advanced_opengl/7.uniform_buffer/shaders/color_cube.frag (renamed from advanced_opengl/8.geometry_shader/shaders/normals.fs) | 3 | ||||
-rw-r--r-- | advanced_opengl/7.uniform_buffer/shaders/color_cube.vert (renamed from advanced_opengl/7.uniform_buffer/shaders/color_cube.vs) | 7 | ||||
-rw-r--r-- | advanced_opengl/7.uniform_buffer/shaders/cube.frag | 12 | ||||
-rw-r--r-- | advanced_opengl/7.uniform_buffer/shaders/cube.fs | 13 | ||||
-rw-r--r-- | advanced_opengl/7.uniform_buffer/shaders/cube.vert (renamed from advanced_opengl/7.uniform_buffer/shaders/cube.vs) | 7 | ||||
-rw-r--r-- | advanced_opengl/7.uniform_buffer/shaders/skybox.frag (renamed from advanced_opengl/7.uniform_buffer/shaders/skybox.fs) | 3 | ||||
-rw-r--r-- | advanced_opengl/7.uniform_buffer/shaders/skybox.vert (renamed from advanced_opengl/7.uniform_buffer/shaders/skybox.vs) | 7 | ||||
-rwxr-xr-x | advanced_opengl/7.uniform_buffer/uniform_buffer | bin | 1288448 -> 1289904 bytes | |||
-rw-r--r-- | advanced_opengl/7.uniform_buffer/uniform_buffer.c | 667 | ||||
-rwxr-xr-x | advanced_opengl/8.geometry_shader/geometry_shader | bin | 1282768 -> 1288776 bytes | |||
-rw-r--r-- | advanced_opengl/8.geometry_shader/geometry_shader.c | 611 | ||||
-rw-r--r-- | advanced_opengl/8.geometry_shader/shaders/base.frag (renamed from advanced_opengl/8.geometry_shader/shaders/base.fs) | 3 | ||||
-rw-r--r-- | advanced_opengl/8.geometry_shader/shaders/base.geom (renamed from advanced_opengl/8.geometry_shader/shaders/base.gs) | 3 | ||||
-rw-r--r-- | advanced_opengl/8.geometry_shader/shaders/base.vert (renamed from advanced_opengl/8.geometry_shader/shaders/base.vs) | 3 | ||||
-rw-r--r-- | advanced_opengl/8.geometry_shader/shaders/basic.frag | 12 | ||||
-rw-r--r-- | advanced_opengl/8.geometry_shader/shaders/basic.fs | 13 | ||||
-rw-r--r-- | advanced_opengl/8.geometry_shader/shaders/basic.vert (renamed from advanced_opengl/8.geometry_shader/shaders/basic.vs) | 7 | ||||
-rw-r--r-- | advanced_opengl/8.geometry_shader/shaders/explosion.frag (renamed from advanced_opengl/8.geometry_shader/shaders/explosion.fs) | 3 | ||||
-rw-r--r-- | advanced_opengl/8.geometry_shader/shaders/explosion.geom (renamed from advanced_opengl/8.geometry_shader/shaders/explosion.gs) | 9 | ||||
-rw-r--r-- | advanced_opengl/8.geometry_shader/shaders/explosion.vert (renamed from advanced_opengl/8.geometry_shader/shaders/explosion.vs) | 7 | ||||
-rw-r--r-- | advanced_opengl/8.geometry_shader/shaders/normals.frag (renamed from advanced_opengl/7.uniform_buffer/shaders/color_cube.fs) | 3 | ||||
-rw-r--r-- | advanced_opengl/8.geometry_shader/shaders/normals.geom (renamed from advanced_opengl/8.geometry_shader/shaders/normals.gs) | 16 | ||||
-rw-r--r-- | advanced_opengl/8.geometry_shader/shaders/normals.vert (renamed from advanced_opengl/8.geometry_shader/shaders/normals.vs) | 3 | ||||
-rwxr-xr-x | advanced_opengl/9.instancing/instancing | bin | 1065104 -> 1065224 bytes | |||
-rw-r--r-- | advanced_opengl/9.instancing/instancing.c | 672 | ||||
-rw-r--r-- | advanced_opengl/9.instancing/shaders/default.frag (renamed from advanced_opengl/9.instancing/shaders/default.fs) | 5 | ||||
-rw-r--r-- | advanced_opengl/9.instancing/shaders/default.vert (renamed from advanced_opengl/9.instancing/shaders/default.vs) | 7 | ||||
-rw-r--r-- | advanced_opengl/9.instancing/shaders/instanced_arrays.frag (renamed from advanced_opengl/9.instancing/shaders/instanced_arrays.fs) | 3 | ||||
-rw-r--r-- | advanced_opengl/9.instancing/shaders/instanced_arrays.vert (renamed from advanced_opengl/9.instancing/shaders/instanced_arrays.vs) | 3 | ||||
-rw-r--r-- | advanced_opengl/9.instancing/shaders/instanced_mat4.frag (renamed from advanced_opengl/9.instancing/shaders/instanced_mat4.fs) | 3 | ||||
-rw-r--r-- | advanced_opengl/9.instancing/shaders/instanced_mat4.vert (renamed from advanced_opengl/9.instancing/shaders/instanced_mat4.vs) | 7 | ||||
-rw-r--r-- | advanced_opengl/9.instancing/shaders/instancing_uniform_array.frag (renamed from advanced_opengl/9.instancing/shaders/instancing_uniform_array.fs) | 3 | ||||
-rw-r--r-- | advanced_opengl/9.instancing/shaders/instancing_uniform_array.vert (renamed from advanced_opengl/9.instancing/shaders/instancing_uniform_array.vs) | 3 | ||||
-rw-r--r-- | data/textures/brickwall.jpg | bin | 0 -> 198744 bytes | |||
-rw-r--r-- | data/textures/brickwall_normal.jpg | bin | 0 -> 572443 bytes | |||
-rw-r--r-- | libs/common.h | 1360 |
119 files changed, 4734 insertions, 6352 deletions
diff --git a/advanced_lighting/1.blinn_phong/blinn_phong.c b/advanced_lighting/1.blinn_phong/blinn_phong.c index 6bbd70a..404df05 100644 --- a/advanced_lighting/1.blinn_phong/blinn_phong.c +++ b/advanced_lighting/1.blinn_phong/blinn_phong.c @@ -1,258 +1,134 @@ -#include "pwyazh.h" - #include "GL/glew.h" #include "GLFW/glfw3.h" +#include "pwyazh.h" #include "pwyazh_GL.h" #include "common.h" -static S32 global_width = 1024, global_height = 768; -static Input global_input; -static V3F camera_dp = (V3F){ 0.0f, 0.0f, 0.0f }; -static V3F light_pos = (V3F){ 0.0f, 0.0f, 0.0f }; -static S32 blinn = 0; - -void -key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) +int main(void) { - switch (action) - { - case GLFW_PRESS: { - switch (key) - { - case GLFW_KEY_D: { - global_input.move_right.state = KeyState_PRESS; - } break; - case GLFW_KEY_W: { - global_input.move_forward.state = KeyState_PRESS; - } break; - case GLFW_KEY_A: { - global_input.move_left.state = KeyState_PRESS; - } break; - case GLFW_KEY_S: { - global_input.move_backward.state = KeyState_PRESS; - } break; - case GLFW_KEY_E: { - global_input.move_up.state = KeyState_PRESS; - } break; - case GLFW_KEY_Q: { - global_input.move_down.state = KeyState_PRESS; - } break; - case GLFW_KEY_SPACE: { - global_input.jump.state = KeyState_PRESS; - } break; - case GLFW_KEY_RIGHT: { - global_input.action_right.state = KeyState_PRESS; - } break; - case GLFW_KEY_UP: { - global_input.action_up.state = KeyState_PRESS; - } break; - case GLFW_KEY_LEFT: { - global_input.action_left.state = KeyState_PRESS; - } break; - case GLFW_KEY_ESCAPE: { - global_input.exit.state = KeyState_PRESS; - } break; - } - } break; - - case GLFW_RELEASE: { - switch (key) - { - case GLFW_KEY_D: { - global_input.move_right.state = KeyState_RELEASE; - } break; - case GLFW_KEY_W: { - global_input.move_forward.state = KeyState_RELEASE; - } break; - case GLFW_KEY_A: { - global_input.move_left.state = KeyState_RELEASE; - } break; - case GLFW_KEY_S: { - global_input.move_backward.state = KeyState_RELEASE; - } break; - case GLFW_KEY_E: { - global_input.move_up.state = KeyState_RELEASE; - } break; - case GLFW_KEY_Q: { - global_input.move_down.state = KeyState_RELEASE; - } break; - case GLFW_KEY_SPACE: { - global_input.jump.state = KeyState_RELEASE; - } break; - case GLFW_KEY_RIGHT: { - global_input.action_right.state = KeyState_RELEASE; - } break; - case GLFW_KEY_UP: { - global_input.action_up.state = KeyState_RELEASE; - } break; - case GLFW_KEY_LEFT: { - global_input.action_left.state = KeyState_RELEASE; - } break; - case GLFW_KEY_ESCAPE: { - global_input.exit.state = KeyState_RELEASE; - } break; - } - } break; - } -} + GLFWwindow *window; + State state; + S32 width, height; + Input input; + Arena *arena; + F64 time, last_time; + U32 texture; + S32 blinn = 0; + V3F light_pos = (V3F){ 0.0f, 0.0f, 0.0f }; -void -resize_callback(GLFWwindow* window, int width, int height) -{ - global_width = width; - global_height = height; - glViewport(0, 0, global_width, global_height); -} + glfwSetErrorCallback(error_callback); -void -error_callback(int error, const char *desc) -{ - fprintf(stderr, "[ERROR] GLFW: %s\n", desc); -} + if (glfwInit() == GLFW_FALSE) + return(1); -void -update(State *state) -{ - V3F camera_dv = get_dv_camera_orbital(&global_input, state->camera.pos, - v3f_zero(), state->dt, 2.0f); - if (key_is_pressed(global_input.action_up)) { - camera_dv = v3f_scalef(camera_dv, 3.0f); - } - camera_dp = v3f_add(camera_dp, camera_dv); - camera_dp = v3f_scalef(camera_dp, 0.7f); - state->camera.pos = v3f_add(state->camera.pos, camera_dp); - - if (key_first_press(global_input.jump)) - blinn = blinn ? 0 : 1; - - input_update_last_state(&global_input); -} + width = 1024; + height = 768; -void -render(State *state, U32 *shaders, U32 texture, Mesh **meshes) -{ - MAT4 projection, view, model; - U32 shader; - Mesh *mesh; - - glClearColor(0.15f, 0.15f, 0.15f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - projection = perspective(state->camera.fovx, (F32)global_width/(F32)global_height, - state->camera.near, state->camera.far); - view = look_at(state->camera.pos, v3f_zero(), v3f(0.0f, 1.0f, 0.0f)); - model = mat4_identity(); - - U32 mesh_index = 0; - shader = shaders[mesh_index]; - mesh = meshes[mesh_index]; - glUseProgram(shader); - shader_set_mat4fv(shader, "projection", projection); - shader_set_mat4fv(shader, "view", view); - shader_set_mat4fv(shader, "model", model); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, texture); - shader_set_3fv(shader, "light_pos", light_pos); - shader_set_3fv(shader, "view_pos", state->camera.pos); - shader_set_1i(shader, "blinn", blinn); - mesh_draw(mesh); - mesh_index++; - - shader = shaders[mesh_index]; - mesh = meshes[mesh_index]; - glUseProgram(shader); - shader_set_mat4fv(shader, "projection", projection); - shader_set_mat4fv(shader, "view", view); - model = mat4_make_scale(v3f(0.1f, 0.1f, 0.1f)); - shader_set_mat4fv(shader, "model", model); - mesh_draw(mesh); - - glBindTexture(GL_TEXTURE_2D, 0); -} + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); + glfwWindowHint(GLFW_SAMPLES, 4); + window = glfwCreateWindow(width, height, "Blinn-Phong shading", 0, 0); + if (!window) + goto error; -int -main(void) -{ - GLFWwindow *window; - Arena *arena; - State state; - Mesh *meshes[2]; - U32 shaders[2]; - F64 time, last_time; - U32 texture; - - glfwSetErrorCallback(error_callback); - - if (glfwInit() == GLFW_FALSE) - return(1); - - glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); - glfwWindowHint(GLFW_SAMPLES, 4); - window = glfwCreateWindow(global_width, global_height, "Blinn-Phong shading", 0, 0); - if (!window) - goto error; - - glfwSetKeyCallback(window, key_callback); - glfwSetWindowSizeCallback(window, resize_callback); - - glfwMakeContextCurrent(window); - - if (glewInit() != GLEW_OK) - goto error; - - glEnable(GL_DEPTH_TEST); - glEnable(GL_MULTISAMPLE); - - /* NOTE(pryazha): init */ - arena = arena_alloc(Megabytes(64)); - - state.camera = (Camera){ v3f(0.0f, 0.0f, 3.0f), 90.0f, 0.1f, 1000.0f }; - - Vertex vertices[] = { - // positions // normals // texcoords - vertex(v3f( 10.0f, -0.5f, 10.0f), v3f(0.0f, 1.0f, 0.0f), v2f(10.0f, 0.0f)), - vertex(v3f(-10.0f, -0.5f, 10.0f), v3f(0.0f, 1.0f, 0.0f), v2f( 0.0f, 0.0f)), - vertex(v3f(-10.0f, -0.5f, -10.0f), v3f(0.0f, 1.0f, 0.0f), v2f( 0.0f, 10.0f)), - - vertex(v3f( 10.0f, -0.5f, 10.0f), v3f(0.0f, 1.0f, 0.0f), v2f(10.0f, 0.0f)), - vertex(v3f(-10.0f, -0.5f, -10.0f), v3f(0.0f, 1.0f, 0.0f), v2f( 0.0f, 10.0f)), - vertex(v3f( 10.0f, -0.5f, -10.0f), v3f(0.0f, 1.0f, 0.0f), v2f(10.0f, 10.0f)) - }; - U32 indices[] = { 0, 1, 2, 3, 4, 5 }; - meshes[0] = mesh_init(arena, vertices, 6, indices, 6); - meshes[1] = mesh_load_obj(arena, "../../data/models/cube.obj"); - - shaders[0] = create_shader_program("shaders/blinn_phong.vs", "shaders/blinn_phong.fs"); - shaders[1] = create_shader_program("shaders/light.vs", "shaders/light.fs"); - - texture = load_texture("../../data/textures/wood.png"); - - last_time = glfwGetTime(); - - while (!glfwWindowShouldClose(window)) - { - glfwPollEvents(); - if (key_first_press(global_input.exit)) - glfwSetWindowShouldClose(window, GLFW_TRUE); - update(&state); - render(&state, shaders, texture, meshes); - glfwSwapBuffers(window); - - time = glfwGetTime(); - state.dt = time-last_time; - last_time = time; -#if 0 - fprintf(stdout, "[INFO]: dt: %f\n", state.dt); -#endif - } - - glfwTerminate(); - return(0); - - error: - glfwTerminate(); - return(1); + glfwMakeContextCurrent(window); + + if (glewInit() != GLEW_OK) + goto error; + + glEnable(GL_DEPTH_TEST); + glEnable(GL_MULTISAMPLE); + + /* NOTE(pryazha): init */ + arena = arena_alloc(Megabytes(64)); + + state.camera = (Camera){ v3f(0.0f, 0.0f, 3.0f), 90.0f, 0.1f, 1000.0f, 0.0f, 0.0f }; + + Vertex vertices[] = { + // positions // normals // texcoords + vertex(v3f( 10.0f, -0.5f, 10.0f), v3f(0.0f, 1.0f, 0.0f), v2f(10.0f, 0.0f)), + vertex(v3f(-10.0f, -0.5f, 10.0f), v3f(0.0f, 1.0f, 0.0f), v2f( 0.0f, 0.0f)), + vertex(v3f(-10.0f, -0.5f, -10.0f), v3f(0.0f, 1.0f, 0.0f), v2f( 0.0f, 10.0f)), + + vertex(v3f( 10.0f, -0.5f, 10.0f), v3f(0.0f, 1.0f, 0.0f), v2f(10.0f, 0.0f)), + vertex(v3f(-10.0f, -0.5f, -10.0f), v3f(0.0f, 1.0f, 0.0f), v2f( 0.0f, 10.0f)), + vertex(v3f( 10.0f, -0.5f, -10.0f), v3f(0.0f, 1.0f, 0.0f), v2f(10.0f, 10.0f)) + }; + U32 indices[] = { 0, 1, 2, 3, 4, 5 }; + 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"); + + texture = load_texture("../../data/textures/wood.png"); + + last_time = glfwGetTime(); + + while (!glfwWindowShouldClose(window)) { + glfwPollEvents(); + + /* INFO(pryazha): Update */ + process_glfw_keyboard(window, &input); + glfwGetFramebufferSize(window, &width, &height); + + V3F target = v3f_zero(); + + if (key_first_press(input.exit)) + glfwSetWindowShouldClose(window, GLFW_TRUE); + + if (key_first_press(input.jump)) + blinn = blinn ? 0 : 1; + + 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); + + /* NOTE(pryazha): Render */ + MAT4 proj, view, model; + + view = look_at(state.camera.pos, target, v3f(0.0f, 1.0f, 0.0f)); + proj = perspective(state.camera.fovx, (F32)width/(F32)height, + state.camera.near, state.camera.far); + model = mat4_identity(); + + glViewport(0, 0, width, height); + glClearColor(0.15f, 0.15f, 0.15f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glUseProgram(blinn_phong_shader); + shader_set_mat4fv(blinn_phong_shader, "proj", proj); + shader_set_mat4fv(blinn_phong_shader, "view", view); + shader_set_mat4fv(blinn_phong_shader, "model", model); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, texture); + shader_set_3fv(blinn_phong_shader, "light_pos", light_pos); + shader_set_3fv(blinn_phong_shader, "view_pos", state.camera.pos); + shader_set_1i(blinn_phong_shader, "blinn", blinn); + mesh_draw(quad); + + glUseProgram(light_shader); + shader_set_mat4fv(light_shader, "proj", proj); + shader_set_mat4fv(light_shader, "view", view); + model = mat4_make_scale(v3f(0.1f, 0.1f, 0.1f)); + shader_set_mat4fv(light_shader, "model", model); + mesh_draw(cube); + + glfwSwapBuffers(window); + + time = glfwGetTime(); + state.dt = time-last_time; + last_time = time; + } + + glfwTerminate(); + return(0); + +error: + glfwTerminate(); + return(1); } diff --git a/advanced_lighting/1.blinn_phong/shaders/blinn_phong.fs b/advanced_lighting/1.blinn_phong/shaders/blinn_phong.frag index 5c66b3e..80f3e47 100644 --- a/advanced_lighting/1.blinn_phong/shaders/blinn_phong.fs +++ b/advanced_lighting/1.blinn_phong/shaders/blinn_phong.frag @@ -13,8 +13,7 @@ uniform vec3 light_pos; uniform vec3 view_pos; uniform bool blinn; -void -main(void) +void main(void) { vec3 light_dir = normalize(light_pos-fs_in.frag_pos); vec3 view_dir = normalize(view_pos-fs_in.frag_pos); @@ -25,13 +24,10 @@ main(void) float diff = max(dot(normal, light_dir), 0.0); float spec = 0.0; - if (blinn) - { + if (blinn) { vec3 halfway_dir = normalize(light_dir+view_dir); spec = pow(max(dot(normal, halfway_dir), 0.0), 16.0); - } - else - { + } else { vec3 reflect_dir = reflect(-light_dir, normal); spec = pow(max(dot(view_dir, reflect_dir), 0.0), 8.0); } diff --git a/advanced_lighting/2.gamma_correction/shaders/blinn_phong.vs b/advanced_lighting/1.blinn_phong/shaders/blinn_phong.vert index 4d1b792..870e7dc 100644 --- a/advanced_lighting/2.gamma_correction/shaders/blinn_phong.vs +++ b/advanced_lighting/1.blinn_phong/shaders/blinn_phong.vert @@ -9,15 +9,14 @@ out VS_OUT { vec2 tex_coords; } vs_out; -uniform mat4 projection; +uniform mat4 proj; uniform mat4 view; uniform mat4 model; -void -main(void) +void main(void) { vs_out.frag_pos = vec3(model*vec4(apos, 1.0)); vs_out.normal = mat3(transpose(inverse(model)))*anormal; vs_out.tex_coords = atex_coords; - gl_Position = projection*view*model*vec4(apos, 1.0); + gl_Position = proj*view*model*vec4(apos, 1.0); } diff --git a/advanced_lighting/2.gamma_correction/shaders/light.fs b/advanced_lighting/1.blinn_phong/shaders/light.frag index bd00d82..c01da99 100644 --- a/advanced_lighting/2.gamma_correction/shaders/light.fs +++ b/advanced_lighting/1.blinn_phong/shaders/light.frag @@ -2,8 +2,7 @@ out vec4 frag_color; -void -main(void) +void main(void) { frag_color = vec4(1.0); } diff --git a/advanced_lighting/2.gamma_correction/shaders/light.vs b/advanced_lighting/1.blinn_phong/shaders/light.vert index ade669b..a8b1247 100644 --- a/advanced_lighting/2.gamma_correction/shaders/light.vs +++ b/advanced_lighting/1.blinn_phong/shaders/light.vert @@ -1,12 +1,11 @@ #version 330 core layout(location = 0) in vec3 apos; -uniform mat4 projection; +uniform mat4 proj; uniform mat4 view; uniform mat4 model; -void -main(void) +void main(void) { - gl_Position = projection*view*model*vec4(apos, 1.0); + gl_Position = proj*view*model*vec4(apos, 1.0); } diff --git a/advanced_lighting/2.gamma_correction/gamma_correction.c b/advanced_lighting/2.gamma_correction/gamma_correction.c index 68edae7..a027722 100644 --- a/advanced_lighting/2.gamma_correction/gamma_correction.c +++ b/advanced_lighting/2.gamma_correction/gamma_correction.c @@ -1,297 +1,171 @@ -#include "pwyazh.h" - #include "GL/glew.h" #include "GLFW/glfw3.h" +#include "pwyazh.h" #include "pwyazh_GL.h" #include "common.h" -static S32 global_width = 1024, global_height = 768; -static Input global_input; -static V3F camera_dp = (V3F){ 0.0f, 0.0f, 0.0f }; -static V3F light_pos = (V3F){ 0.0f, 0.0f, 0.0f }; -static U32 gamma_correction = 0; - -static V3F light_positions[] = { - (V3F){-3.0f, 0.0f, 0.0f}, - (V3F){-1.0f, 0.0f, 0.0f}, - (V3F){1.0f, 0.0f, 0.0f}, - (V3F){3.0f, 0.0f, 0.0} -}; -static V3F light_colors[] = { - (V3F){0.25f, 0.25f, 0.25f}, - (V3F){0.50f, 0.50f, 0.50f}, - (V3F){0.75f, 0.75f, 0.75f}, - (V3F){1.0f, 1.0f, 1.0} -}; - -void -key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) -{ - switch (action) - { - case GLFW_PRESS: { - switch (key) - { - case GLFW_KEY_D: { - global_input.move_right.state = KeyState_PRESS; - } break; - case GLFW_KEY_W: { - global_input.move_forward.state = KeyState_PRESS; - } break; - case GLFW_KEY_A: { - global_input.move_left.state = KeyState_PRESS; - } break; - case GLFW_KEY_S: { - global_input.move_backward.state = KeyState_PRESS; - } break; - case GLFW_KEY_E: { - global_input.move_up.state = KeyState_PRESS; - } break; - case GLFW_KEY_Q: { - global_input.move_down.state = KeyState_PRESS; - } break; - case GLFW_KEY_SPACE: { - global_input.jump.state = KeyState_PRESS; - } break; - case GLFW_KEY_RIGHT: { - global_input.action_right.state = KeyState_PRESS; - } break; - case GLFW_KEY_UP: { - global_input.action_up.state = KeyState_PRESS; - } break; - case GLFW_KEY_LEFT: { - global_input.action_left.state = KeyState_PRESS; - } break; - case GLFW_KEY_ESCAPE: { - global_input.exit.state = KeyState_PRESS; - } break; - } - } break; - - case GLFW_RELEASE: { - switch (key) - { - case GLFW_KEY_D: { - global_input.move_right.state = KeyState_RELEASE; - } break; - case GLFW_KEY_W: { - global_input.move_forward.state = KeyState_RELEASE; - } break; - case GLFW_KEY_A: { - global_input.move_left.state = KeyState_RELEASE; - } break; - case GLFW_KEY_S: { - global_input.move_backward.state = KeyState_RELEASE; - } break; - case GLFW_KEY_E: { - global_input.move_up.state = KeyState_RELEASE; - } break; - case GLFW_KEY_Q: { - global_input.move_down.state = KeyState_RELEASE; - } break; - case GLFW_KEY_SPACE: { - global_input.jump.state = KeyState_RELEASE; - } break; - case GLFW_KEY_RIGHT: { - global_input.action_right.state = KeyState_RELEASE; - } break; - case GLFW_KEY_UP: { - global_input.action_up.state = KeyState_RELEASE; - } break; - case GLFW_KEY_LEFT: { - global_input.action_left.state = KeyState_RELEASE; - } break; - case GLFW_KEY_ESCAPE: { - global_input.exit.state = KeyState_RELEASE; - } break; - } - } break; - } -} - -void -resize_callback(GLFWwindow* window, int width, int height) -{ - global_width = width; - global_height = height; - glViewport(0, 0, global_width, global_height); -} - -void -error_callback(int error, const char *desc) -{ - fprintf(stderr, "[ERROR] GLFW: %s\n", desc); -} - -void -update(State *state) -{ - V3F camera_dv = get_dv_camera_orbital(&global_input, state->camera.pos, - v3f_zero(), state->dt, 2.0f); - if (key_is_pressed(global_input.action_up)) - camera_dv = v3f_scalef(camera_dv, 3.0f); - camera_dp = v3f_add(camera_dp, camera_dv); - camera_dp = v3f_scalef(camera_dp, 0.7f); - state->camera.pos = v3f_add(state->camera.pos, camera_dp); - - if (key_first_press(global_input.action_right)) - gamma_correction = !gamma_correction; - - F32 time = glfwGetTime(); - for (S32 position_index = 0; - position_index < (S32)ArrayCount(light_positions); - position_index++) - { - F32 radius = position_index*2.0+2.0; - F32 angle = time*position_index*pi_F32/6.0; - F32 x = f32_sin(angle)*radius; - F32 z = f32_cos(angle)*radius; - light_positions[position_index] = v3f(x, light_positions[position_index].y, z); - } - - input_update_last_state(&global_input); -} - -void -render(State *state, U32 *shaders, U32 texture, U32 texture_gamma_corrected, Mesh **meshes) -{ - MAT4 projection, view, model; - U32 shader; - Mesh *mesh; - - glClearColor(0.15f, 0.15f, 0.15f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - projection = perspective(state->camera.fovx, (F32)global_width/(F32)global_height, - state->camera.near, state->camera.far); - view = look_at(state->camera.pos, v3f_zero(), v3f(0.0f, 1.0f, 0.0f)); - model = mat4_identity(); - - U32 mesh_index = 0; - shader = shaders[mesh_index]; - mesh = meshes[mesh_index]; - glUseProgram(shader); - shader_set_mat4fv(shader, "projection", projection); - shader_set_mat4fv(shader, "view", view); - shader_set_mat4fv(shader, "model", model); - if (gamma_correction) - glBindTexture(GL_TEXTURE_2D, texture_gamma_corrected); - else - glBindTexture(GL_TEXTURE_2D, texture); - shader_set_3fv(shader, "light_pos", light_pos); - shader_set_3fv(shader, "view_pos", state->camera.pos); - shader_set_1i(shader, "gamma_correction", gamma_correction); - U32 light_positions_location = glGetUniformLocation(shader, "light_positions"); - glUniform3fv(light_positions_location, 4, (F32 *)&light_positions[0]); - U32 light_colors_location = glGetUniformLocation(shader, "light_colors"); - glUniform3fv(light_colors_location, 4, (F32 *)&light_colors[0]); - mesh_draw(mesh); - mesh_index++; - - shader = shaders[mesh_index]; - mesh = meshes[mesh_index]; - glUseProgram(shader); - shader_set_mat4fv(shader, "projection", projection); - shader_set_mat4fv(shader, "view", view); - for (S32 light_index = 0; - light_index < (S32)ArrayCount(light_positions); - light_index++) - { - model = mat4_make_scale(v3f(0.1f, 0.1f, 0.1f)); - model = mat4_translate(model, light_positions[light_index]); - shader_set_mat4fv(shader, "model", model); - mesh_draw(mesh); - } - glBindTexture(GL_TEXTURE_2D, 0); -} - -int -main(void) +int main(void) { - GLFWwindow *window; - Arena *arena; - State state; - Mesh *meshes[2]; - U32 shaders[2]; - F64 time, last_time; - U32 texture, texture_gamma_corrected; - - glfwSetErrorCallback(error_callback); - - if (glfwInit() == GLFW_FALSE) - return(1); - - glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); - glfwWindowHint(GLFW_SAMPLES, 4); - window = glfwCreateWindow(global_width, global_height, "Gamma correction", 0, 0); - if (!window) - goto error; - - glfwSetKeyCallback(window, key_callback); - glfwSetWindowSizeCallback(window, resize_callback); - - glfwMakeContextCurrent(window); - - if (glewInit() != GLEW_OK) - goto error; - - glEnable(GL_DEPTH_TEST); - glEnable(GL_MULTISAMPLE); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - /* NOTE(pryazha): A less controlled method of applying gamma correction */ - /* glEnable(GL_FRAMEBUFFER_SRGB); */ - - /* NOTE(pryazha): init */ - arena = arena_alloc(Megabytes(64)); - - state.camera = (Camera){ v3f(0.0f, 0.0f, 3.0f), 90.0f, 0.1f, 1000.0f }; - - Vertex vertices[] = { - // positions // normals // texcoords - vertex(v3f( 10.0f, -0.5f, 10.0f), v3f(0.0f, 1.0f, 0.0f), v2f(10.0f, 0.0f)), - vertex(v3f(-10.0f, -0.5f, 10.0f), v3f(0.0f, 1.0f, 0.0f), v2f( 0.0f, 0.0f)), - vertex(v3f(-10.0f, -0.5f, -10.0f), v3f(0.0f, 1.0f, 0.0f), v2f( 0.0f, 10.0f)), - - vertex(v3f( 10.0f, -0.5f, 10.0f), v3f(0.0f, 1.0f, 0.0f), v2f(10.0f, 0.0f)), - vertex(v3f(-10.0f, -0.5f, -10.0f), v3f(0.0f, 1.0f, 0.0f), v2f( 0.0f, 10.0f)), - vertex(v3f( 10.0f, -0.5f, -10.0f), v3f(0.0f, 1.0f, 0.0f), v2f(10.0f, 10.0f)) - }; - U32 indices[] = { 0, 1, 2, 3, 4, 5 }; - meshes[0] = mesh_init(arena, vertices, 6, indices, 6); - meshes[1] = mesh_load_obj(arena, "../../data/models/cube.obj"); - - shaders[0] = create_shader_program("shaders/blinn_phong.vs", "shaders/blinn_phong.fs"); - shaders[1] = create_shader_program("shaders/light.vs", "shaders/light.fs"); - - texture = load_texture_gamma("../../data/textures/wood.png", 0); - texture_gamma_corrected = load_texture_gamma("../../data/textures/wood.png", 1); - - last_time = glfwGetTime(); - - while (!glfwWindowShouldClose(window)) - { - glfwPollEvents(); - if (key_first_press(global_input.exit)) - glfwSetWindowShouldClose(window, GLFW_TRUE); - update(&state); - render(&state, shaders, texture, texture_gamma_corrected, meshes); - glfwSwapBuffers(window); - - time = glfwGetTime(); - state.dt = time-last_time; - last_time = time; -#if 0 - fprintf(stdout, "[INFO]: dt: %f\n", state.dt); -#endif - } - - glfwTerminate(); - return(0); - - error: - glfwTerminate(); - return(1); + GLFWwindow *window; + Arena *arena; + State state; + Input input; + F64 time, last_time; + V3F light_pos = (V3F){ 0.0f, 0.0f, 0.0f }; + U32 gamma_correction = 0; + MAT4 proj, view, model; + S32 width, height; + B32 blinn; + + V3F light_positions[] = { + (V3F){-3.0f, 0.0f, 0.0f}, + (V3F){-1.0f, 0.0f, 0.0f}, + (V3F){1.0f, 0.0f, 0.0f}, + (V3F){3.0f, 0.0f, 0.0} + }; + V3F light_colors[] = { + (V3F){0.25f, 0.25f, 0.25f}, + (V3F){0.50f, 0.50f, 0.50f}, + (V3F){0.75f, 0.75f, 0.75f}, + (V3F){1.0f, 1.0f, 1.0} + }; + + glfwSetErrorCallback(error_callback); + + if (glfwInit() == GLFW_FALSE) + return(1); + + width = 1024; + height = 768; + + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); + glfwWindowHint(GLFW_SAMPLES, 4); + window = glfwCreateWindow(width, height, "Gamma correction", 0, 0); + if (!window) + goto error; + + glfwMakeContextCurrent(window); + + if (glewInit() != GLEW_OK) + goto error; + + glEnable(GL_DEPTH_TEST); + glEnable(GL_MULTISAMPLE); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + /* NOTE(pryazha): A less controlled method of applying gamma correction */ + /* glEnable(GL_FRAMEBUFFER_SRGB); */ + + /* NOTE(pryazha): init */ + arena = arena_alloc(Megabytes(64)); + + state.camera = (Camera){ v3f(0.0f, 0.0f, 3.0f), 90.0f, 0.1f, 1000.0f, 0.0f, 0.0f }; + + Vertex vertices[] = { + // positions // normals // texcoords + vertex(v3f( 10.0f, -0.5f, 10.0f), v3f(0.0f, 1.0f, 0.0f), v2f(10.0f, 0.0f)), + vertex(v3f(-10.0f, -0.5f, 10.0f), v3f(0.0f, 1.0f, 0.0f), v2f( 0.0f, 0.0f)), + vertex(v3f(-10.0f, -0.5f, -10.0f), v3f(0.0f, 1.0f, 0.0f), v2f( 0.0f, 10.0f)), + + vertex(v3f( 10.0f, -0.5f, 10.0f), v3f(0.0f, 1.0f, 0.0f), v2f(10.0f, 0.0f)), + vertex(v3f(-10.0f, -0.5f, -10.0f), v3f(0.0f, 1.0f, 0.0f), v2f( 0.0f, 10.0f)), + vertex(v3f( 10.0f, -0.5f, -10.0f), v3f(0.0f, 1.0f, 0.0f), v2f(10.0f, 10.0f)) + }; + U32 indices[] = { 0, 1, 2, 3, 4, 5 }; + 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 texture = load_texture_gamma("../../data/textures/wood.png", 0); + U32 texture_gamma_corrected = load_texture_gamma("../../data/textures/wood.png", 1); + + last_time = glfwGetTime(); + + while (!glfwWindowShouldClose(window)) { + glfwPollEvents(); + + /* NOTE(pryazha): Update */ + process_glfw_keyboard(window, &input); + glfwGetFramebufferSize(window, &width, &height); + + V3F target = v3f_zero(); + + if (key_first_press(input.exit)) + glfwSetWindowShouldClose(window, GLFW_TRUE); + + if (key_first_press(input.jump)) + blinn = blinn ? 0 : 1; + + V3F dv = get_dv_camera_orbital(&input, state.camera.pos, + target, state.dt, 3.0f); + state.camera.pos = v3f_add(state.camera.pos, dv); + + if (key_first_press(input.action_right)) + gamma_correction = !gamma_correction; + + for (S32 i = 0; i < (S32)ArrayCount(light_positions); i++) { + F32 radius = i*2.0+2.0; + F32 angle = time*i*pi_F32/6.0; + F32 x = f32_sin(angle)*radius; + F32 z = f32_cos(angle)*radius; + light_positions[i] = v3f(x, light_positions[i].y, z); + } + + input_update_last_state(&input); + + proj = perspective(state.camera.fovx, (F32)width/(F32)height, + state.camera.near, state.camera.far); + view = look_at(state.camera.pos, v3f_zero(), v3f(0.0f, 1.0f, 0.0f)); + model = mat4_identity(); + + /* NOTE(pryazha): Render */ + glViewport(0, 0, width, height); + glClearColor(0.15f, 0.15f, 0.15f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glUseProgram(blinn_phong_shader); + shader_set_mat4fv(blinn_phong_shader, "proj", proj); + shader_set_mat4fv(blinn_phong_shader, "view", view); + shader_set_mat4fv(blinn_phong_shader, "model", model); + if (gamma_correction) + glBindTexture(GL_TEXTURE_2D, texture_gamma_corrected); + else + glBindTexture(GL_TEXTURE_2D, texture); + shader_set_3fv(blinn_phong_shader, "light_pos", light_pos); + shader_set_3fv(blinn_phong_shader, "view_pos", state.camera.pos); + shader_set_1i(blinn_phong_shader, "gamma_correction", gamma_correction); + U32 light_positions_location = glGetUniformLocation(blinn_phong_shader, "light_positions"); + glUniform3fv(light_positions_location, 4, (F32 *)&light_positions[0]); + U32 light_colors_location = glGetUniformLocation(blinn_phong_shader, "light_colors"); + glUniform3fv(light_colors_location, 4, (F32 *)&light_colors[0]); + mesh_draw(quad); + + glUseProgram(light_shader); + shader_set_mat4fv(light_shader, "proj", proj); + shader_set_mat4fv(light_shader, "view", view); + for (S32 i = 0; i < (S32)ArrayCount(light_positions); i++) { + model = mat4_make_scale(v3f(0.1f, 0.1f, 0.1f)); + model = mat4_translate(model, light_positions[i]); + shader_set_mat4fv(light_shader, "model", model); + mesh_draw(cube); + } + glBindTexture(GL_TEXTURE_2D, 0); + + glfwSwapBuffers(window); + + time = glfwGetTime(); + state.dt = time-last_time; + last_time = time; + } + + glfwTerminate(); + return(0); + +error: + glfwTerminate(); + return(1); } diff --git a/advanced_lighting/2.gamma_correction/shaders/blinn_phong.fs b/advanced_lighting/2.gamma_correction/shaders/blinn_phong.frag index 35e701c..331fc8b 100644 --- a/advanced_lighting/2.gamma_correction/shaders/blinn_phong.fs +++ b/advanced_lighting/2.gamma_correction/shaders/blinn_phong.frag @@ -14,9 +14,8 @@ uniform vec3 light_colors[4]; uniform vec3 view_pos; uniform bool gamma_correction; -vec3 -blinn_phong(vec3 light_dir, vec3 view_dir, vec3 normal, - vec3 light_pos, vec3 light_color) +vec3 blinn_phong(vec3 light_dir, vec3 view_dir, vec3 normal, + vec3 light_pos, vec3 light_color) { float diff = max(dot(normal, light_dir), 0.0); vec3 diffuse = diff*light_color; @@ -31,16 +30,14 @@ blinn_phong(vec3 light_dir, vec3 view_dir, vec3 normal, return((diffuse+specular)*attenuation); } -void -main(void) +void main(void) { vec3 view_dir = normalize(view_pos-fs_in.frag_pos); vec3 normal = normalize(fs_in.normal); vec3 texture_color = texture(texture0, fs_in.tex_coords).rgb; vec3 lighting = vec3(0.0); - for (int i = 0; i < 4; i++) - { + for (int i = 0; i < 4; i++) { vec3 light_pos = light_positions[i]; vec3 light_color = light_colors[i]; vec3 light_dir = normalize(light_pos-fs_in.frag_pos); diff --git a/advanced_lighting/1.blinn_phong/shaders/blinn_phong.vs b/advanced_lighting/2.gamma_correction/shaders/blinn_phong.vert index 4d1b792..870e7dc 100644 --- a/advanced_lighting/1.blinn_phong/shaders/blinn_phong.vs +++ b/advanced_lighting/2.gamma_correction/shaders/blinn_phong.vert @@ -9,15 +9,14 @@ out VS_OUT { vec2 tex_coords; } vs_out; -uniform mat4 projection; +uniform mat4 proj; uniform mat4 view; uniform mat4 model; -void -main(void) +void main(void) { vs_out.frag_pos = vec3(model*vec4(apos, 1.0)); vs_out.normal = mat3(transpose(inverse(model)))*anormal; vs_out.tex_coords = atex_coords; - gl_Position = projection*view*model*vec4(apos, 1.0); + gl_Position = proj*view*model*vec4(apos, 1.0); } diff --git a/advanced_lighting/3.1.shadow_mapping/shaders/color.fs b/advanced_lighting/2.gamma_correction/shaders/light.frag index bd00d82..c01da99 100644 --- a/advanced_lighting/3.1.shadow_mapping/shaders/color.fs +++ b/advanced_lighting/2.gamma_correction/shaders/light.frag @@ -2,8 +2,7 @@ out vec4 frag_color; -void -main(void) +void main(void) { frag_color = vec4(1.0); } diff --git a/advanced_lighting/3.1.shadow_mapping/shaders/color.vs b/advanced_lighting/2.gamma_correction/shaders/light.vert index ade669b..a8b1247 100644 --- a/advanced_lighting/3.1.shadow_mapping/shaders/color.vs +++ b/advanced_lighting/2.gamma_correction/shaders/light.vert @@ -1,12 +1,11 @@ #version 330 core layout(location = 0) in vec3 apos; -uniform mat4 projection; +uniform mat4 proj; uniform mat4 view; uniform mat4 model; -void -main(void) +void main(void) { - gl_Position = projection*view*model*vec4(apos, 1.0); + gl_Position = proj*view*model*vec4(apos, 1.0); } diff --git a/advanced_lighting/3.1.shadow_mapping/build.sh b/advanced_lighting/3.1.shadow_mapping/build.sh index bba445d..79ca088 100755 --- a/advanced_lighting/3.1.shadow_mapping/build.sh +++ b/advanced_lighting/3.1.shadow_mapping/build.sh @@ -2,4 +2,4 @@ . ../../config TARGET='shadow_mapping' set -x -gcc -o $TARGET $CFLAGS $INCLUDE $LFLAGS $TARGET.c $LIBS +gcc -o $TARGET $CFLAGS $INCLUDE $LFLAGS $TARGET.c $LIBS && ./$TARGET diff --git a/advanced_lighting/1.blinn_phong/shaders/light.fs b/advanced_lighting/3.1.shadow_mapping/shaders/color.frag index bd00d82..c01da99 100644 --- a/advanced_lighting/1.blinn_phong/shaders/light.fs +++ b/advanced_lighting/3.1.shadow_mapping/shaders/color.frag @@ -2,8 +2,7 @@ out vec4 frag_color; -void -main(void) +void main(void) { frag_color = vec4(1.0); } diff --git a/advanced_opengl/10.antialiasing/shaders/color.vs b/advanced_lighting/3.1.shadow_mapping/shaders/color.vert index ade669b..6aa621e 100644 --- a/advanced_opengl/10.antialiasing/shaders/color.vs +++ b/advanced_lighting/3.1.shadow_mapping/shaders/color.vert @@ -1,12 +1,11 @@ #version 330 core layout(location = 0) in vec3 apos; -uniform mat4 projection; +uniform mat4 proj; uniform mat4 view; uniform mat4 model; -void -main(void) +void main(void) { - gl_Position = projection*view*model*vec4(apos, 1.0); + gl_Position = proj * view * model * vec4(apos, 1.0); } diff --git a/advanced_lighting/3.1.shadow_mapping/shaders/debug_quad.fs b/advanced_lighting/3.1.shadow_mapping/shaders/debug_quad.frag index d250894..4cb6df1 100644 --- a/advanced_lighting/3.1.shadow_mapping/shaders/debug_quad.fs +++ b/advanced_lighting/3.1.shadow_mapping/shaders/debug_quad.frag @@ -8,15 +8,13 @@ uniform sampler2D depth_map; uniform float near; uniform float far; -float -linearize_depth(float depth) +float linearize_depth(float depth) { float z = (depth+1.0)*0.5; return((2.0*near*far)/(far+near-z*(far-near))); } -void -main(void) +void main(void) { float depth = texture(depth_map, tex_coords).r; diff --git a/advanced_lighting/3.1.shadow_mapping/shaders/debug_quad.vs b/advanced_lighting/3.1.shadow_mapping/shaders/debug_quad.vert index 5717608..5717608 100644 --- a/advanced_lighting/3.1.shadow_mapping/shaders/debug_quad.vs +++ b/advanced_lighting/3.1.shadow_mapping/shaders/debug_quad.vert diff --git a/advanced_lighting/3.1.shadow_mapping/shaders/shadow.fs b/advanced_lighting/3.1.shadow_mapping/shaders/shadow.frag index 1c7018a..3403d1d 100644 --- a/advanced_lighting/3.1.shadow_mapping/shaders/shadow.fs +++ b/advanced_lighting/3.1.shadow_mapping/shaders/shadow.frag @@ -15,8 +15,7 @@ uniform vec3 view_pos; uniform sampler2D diffuse_texture; uniform sampler2D shadow_map; -float -calculate_shadow() +float calculate_shadow() { vec3 proj_coords = fs_in.frag_pos_light_space.xyz/fs_in.frag_pos_light_space.w; proj_coords = proj_coords*0.5+0.5; @@ -43,8 +42,7 @@ calculate_shadow() return(shadow); } -void -main(void) +void main(void) { vec3 color = texture(diffuse_texture, fs_in.tex_coords).rgb; vec3 normal = normalize(fs_in.normal); diff --git a/advanced_lighting/3.1.shadow_mapping/shaders/shadow.vs b/advanced_lighting/3.1.shadow_mapping/shaders/shadow.vert index 3ecd5b1..3f14663 100644 --- a/advanced_lighting/3.1.shadow_mapping/shaders/shadow.vs +++ b/advanced_lighting/3.1.shadow_mapping/shaders/shadow.vert @@ -10,17 +10,16 @@ out VS_OUT { vec2 tex_coords; } vs_out; -uniform mat4 projection; +uniform mat4 proj; uniform mat4 view; uniform mat4 model; uniform mat4 light_space_matrix; -void -main(void) +void main(void) { vs_out.frag_pos = vec3(model*vec4(apos, 1.0)); vs_out.frag_pos_light_space = light_space_matrix*vec4(vs_out.frag_pos, 1.0); vs_out.normal = mat3(transpose(inverse(model)))*anormal; vs_out.tex_coords = atex_coords; - gl_Position = projection*view*vec4(vs_out.frag_pos, 1.0); + gl_Position = proj*view*vec4(vs_out.frag_pos, 1.0); } diff --git a/advanced_lighting/3.1.shadow_mapping/shaders/simple_depth.fs b/advanced_lighting/3.1.shadow_mapping/shaders/simple_depth.frag index 16b9908..d99aab2 100644 --- a/advanced_lighting/3.1.shadow_mapping/shaders/simple_depth.fs +++ b/advanced_lighting/3.1.shadow_mapping/shaders/simple_depth.frag @@ -1,6 +1,5 @@ #version 330 core -void -main(void) +void main(void) { } diff --git a/advanced_lighting/3.1.shadow_mapping/shaders/simple_depth.vs b/advanced_lighting/3.1.shadow_mapping/shaders/simple_depth.vert index b9752ed..d3adca9 100644 --- a/advanced_lighting/3.1.shadow_mapping/shaders/simple_depth.vs +++ b/advanced_lighting/3.1.shadow_mapping/shaders/simple_depth.vert @@ -4,8 +4,7 @@ layout(location = 0) in vec3 apos; uniform mat4 light_space_matrix; uniform mat4 model; -void -main(void) +void main(void) { gl_Position = light_space_matrix*model*vec4(apos, 1.0); } diff --git a/advanced_lighting/3.1.shadow_mapping/shadow_mapping.c b/advanced_lighting/3.1.shadow_mapping/shadow_mapping.c index 7f03415..fd03ed9 100644 --- a/advanced_lighting/3.1.shadow_mapping/shadow_mapping.c +++ b/advanced_lighting/3.1.shadow_mapping/shadow_mapping.c @@ -1,417 +1,275 @@ -#include "pwyazh.h" - #include "GL/glew.h" #include "GLFW/glfw3.h" +#include "pwyazh.h" #include "pwyazh_GL.h" #include "common.h" -static S32 global_screen_width = 800, global_screen_height = 600; -static U32 global_shadow_width = 1024, global_shadow_height = 1024; - -static Input global_input; - -static V3F camera_dp = (V3F){ 0.0f, 0.0f, 0.0f }; - -static U32 global_depth_map_fbo, global_depth_map; - -static U32 global_debug_quad_shader, global_simple_depth_shader, - global_shadow_shader, global_color_shader; - -static U32 global_wood_texture; - -static U32 global_quad_vao; - -static U32 shadows_ortho = 1; - -static V3F light_pos; - -void -glfw_key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) -{ - switch (action) - { - case GLFW_PRESS: { - switch (key) - { - case GLFW_KEY_D: { - global_input.move_right.state = KeyState_PRESS; - } break; - case GLFW_KEY_W: { - global_input.move_forward.state = KeyState_PRESS; - } break; - case GLFW_KEY_A: { - global_input.move_left.state = KeyState_PRESS; - } break; - case GLFW_KEY_S: { - global_input.move_backward.state = KeyState_PRESS; - } break; - case GLFW_KEY_E: { - global_input.move_up.state = KeyState_PRESS; - } break; - case GLFW_KEY_Q: { - global_input.move_down.state = KeyState_PRESS; - } break; - case GLFW_KEY_SPACE: { - global_input.jump.state = KeyState_PRESS; - } break; - case GLFW_KEY_RIGHT: { - global_input.action_right.state = KeyState_PRESS; - } break; - case GLFW_KEY_UP: { - global_input.action_up.state = KeyState_PRESS; - } break; - case GLFW_KEY_LEFT: { - global_input.action_left.state = KeyState_PRESS; - } break; - case GLFW_KEY_DOWN: { - global_input.action_down.state = KeyState_PRESS; - } break; - case GLFW_KEY_ESCAPE: { - global_input.exit.state = KeyState_PRESS; - } break; - } - } break; - - case GLFW_RELEASE: { - switch (key) - { - case GLFW_KEY_D: { - global_input.move_right.state = KeyState_RELEASE; - } break; - case GLFW_KEY_W: { - global_input.move_forward.state = KeyState_RELEASE; - } break; - case GLFW_KEY_A: { - global_input.move_left.state = KeyState_RELEASE; - } break; - case GLFW_KEY_S: { - global_input.move_backward.state = KeyState_RELEASE; - } break; - case GLFW_KEY_E: { - global_input.move_up.state = KeyState_RELEASE; - } break; - case GLFW_KEY_Q: { - global_input.move_down.state = KeyState_RELEASE; - } break; - case GLFW_KEY_SPACE: { - global_input.jump.state = KeyState_RELEASE; - } break; - case GLFW_KEY_RIGHT: { - global_input.action_right.state = KeyState_RELEASE; - } break; - case GLFW_KEY_UP: { - global_input.action_up.state = KeyState_RELEASE; - } break; - case GLFW_KEY_LEFT: { - global_input.action_left.state = KeyState_RELEASE; - } break; - case GLFW_KEY_DOWN: { - global_input.action_down.state = KeyState_RELEASE; - } break; - case GLFW_KEY_ESCAPE: { - global_input.exit.state = KeyState_RELEASE; - } break; - } - } break; - } -} - -void -resize_callback(GLFWwindow* window, int width, int height) -{ - global_screen_width = width; - global_screen_height = height; - glViewport(0, 0, global_screen_width, global_screen_height); -} - -void -error_callback(int error, const char *desc) -{ - fprintf(stderr, "[ERROR] GLFW: %s\n", desc); -} - -void -update(State *state, F32 time) -{ - F32 radius; - - V3F camera_dv = get_dv_camera_orbital(&global_input, state->camera.pos, - v3f_zero(), state->dt, 2.0f); - if (key_is_pressed(global_input.action_up)) - camera_dv = v3f_scalef(camera_dv, 3.0f); - camera_dp = v3f_add(camera_dp, camera_dv); - camera_dp = v3f_scalef(camera_dp, 0.8f); - state->camera.pos = v3f_add(state->camera.pos, camera_dp); - - if (key_first_press(global_input.action_down)) - shadows_ortho = !shadows_ortho; - - input_update_last_state(&global_input); - - F32 x, z, angular_speed; - - angular_speed = 1.0f; - radius = 4.0f; - x = f32_sin(time*angular_speed)*radius; - z = f32_cos(time*angular_speed)*radius; - - light_pos = v3f(x, 4.0f, z); -} - -void -render_scene(U32 shader, Mesh *cube, Mesh *plane) -{ - MAT4 model; - - model = mat4_identity(); - shader_set_mat4fv(shader, "model", model); - mesh_draw(plane); - - /* - model = mat4_identity(); - model = mat4_make_scale(v3f(10.0f, 0.1f, 10.0f)); - model = mat4_translate(model, v3f(0.0f, -0.6f, 0.0f)); - shader_set_mat4fv(shader, "model", model); - mesh_draw(cube); - */ - - model = mat4_identity(); - model = mat4_make_scale(v3f(0.5f, 0.5f, 0.5f)); - model = mat4_translate(model, v3f(0.0f, 1.5f, 0.0f)); - shader_set_mat4fv(shader, "model", model); - mesh_draw(cube); - - model = mat4_identity(); - model = mat4_make_scale(v3f(0.5f, 0.5f, 0.5f)); - model = mat4_translate(model, v3f(2.0f, 0.0f, 1.0f)); - shader_set_mat4fv(shader, "model", model); - mesh_draw(cube); - - model = mat4_identity(); - model = mat4_make_scale(v3f(0.25f, 0.25f, 0.25f)); - model = mat4_rotate_angles(model, v3f(60.0f, 0.0f, 0.0f)); - model = mat4_translate(model, v3f(-1.0f, 0.0f, 2.0f)); - shader_set_mat4fv(shader, "model", model); - mesh_draw(cube); -} - -void -render(State *state, Mesh *cube, Mesh *plane) +void render_scene(U32 shader, Mesh *cube, Mesh *plane) { - /* MAT4 projection, view, model; */ - MAT4 light_projection, light_view, model; - F32 near, far, fovx; - V3F target, up; - - if (shadows_ortho) - { - near = 1.0f; - far = 10.0f; - F32 half_side = 10.0f; - light_projection = ortho(-half_side, half_side, -half_side, half_side, near, far); - } - else - { - fovx = 90.0f; - near = 1.0f; - far = 50.0f; - light_projection = perspective(fovx, (F32)global_shadow_width/(F32)global_shadow_height, - near, far); - } - - target = v3f_zero(); - up = v3f(0.0f, 1.0f, 0.0f); - light_view = look_at(light_pos, target, up); - MAT4 light_space_matrix = mat4_mul(light_projection, light_view); - - glUseProgram(global_simple_depth_shader); - shader_set_mat4fv(global_simple_depth_shader, "light_space_matrix", light_space_matrix); - glViewport(0, 0, global_shadow_width, global_shadow_height); - glBindFramebuffer(GL_FRAMEBUFFER, global_depth_map_fbo); - glClear(GL_DEPTH_BUFFER_BIT); - // glCullFace(GL_FRONT); - render_scene(global_simple_depth_shader, cube, plane); - // glCullFace(GL_BACK); - glBindFramebuffer(GL_FRAMEBUFFER, 0); - - glViewport(0, 0, global_screen_width, global_screen_height); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - MAT4 projection = perspective(state->camera.fovx, (F32)global_screen_width/(F32)global_screen_height, - state->camera.near, state->camera.far); - MAT4 view = look_at(state->camera.pos, v3f_zero(), v3f(0.0f, 1.0f, 0.0f)); - glUseProgram(global_shadow_shader); - shader_set_mat4fv(global_shadow_shader, "projection", projection); - shader_set_mat4fv(global_shadow_shader, "view", view); - - shader_set_3fv(global_shadow_shader, "light_pos", light_pos); - shader_set_3fv(global_shadow_shader, "view_pos", state->camera.pos); - shader_set_mat4fv(global_shadow_shader, "light_space_matrix", light_space_matrix); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, global_wood_texture); - glActiveTexture(GL_TEXTURE1); - glBindTexture(GL_TEXTURE_2D, global_depth_map); - render_scene(global_shadow_shader, cube, plane); - - glUseProgram(global_color_shader); - shader_set_mat4fv(global_shadow_shader, "projection", projection); - shader_set_mat4fv(global_shadow_shader, "view", view); - model = mat4_make_scale(v3f(0.1f, 0.1f, 0.1f)); - model = mat4_translate(model, light_pos); - shader_set_mat4fv(global_shadow_shader, "model", model); - mesh_draw(cube); - - glDisable(GL_DEPTH_TEST); - glUseProgram(global_debug_quad_shader); - F32 scale = 0.3f; - Transform transform = transform_make_scale_translate(v3f(scale, scale, scale), - v3f(1.0f-scale, 1.0f-scale, 0.0f)); - model = transform_apply(transform); - shader_set_mat4fv(global_debug_quad_shader, "model", model); - shader_set_1f(global_debug_quad_shader, "near", near); - shader_set_1f(global_debug_quad_shader, "far", far); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, global_depth_map); - glBindVertexArray(global_quad_vao); - glDrawArrays(GL_TRIANGLES, 0, 6); - glBindVertexArray(0); - glEnable(GL_DEPTH_TEST); + MAT4 model; + + model = mat4_identity(); + shader_set_mat4fv(shader, "model", model); + mesh_draw(plane); + + /* + model = mat4_identity(); + model = mat4_make_scale(v3f(10.0f, 0.1f, 10.0f)); + model = mat4_translate(model, v3f(0.0f, -0.6f, 0.0f)); + shader_set_mat4fv(shader, "model", model); + mesh_draw(cube); + */ + + model = mat4_identity(); + model = mat4_make_scale(v3f(0.5f, 0.5f, 0.5f)); + model = mat4_translate(model, v3f(0.0f, 1.5f, 0.0f)); + shader_set_mat4fv(shader, "model", model); + mesh_draw(cube); + + model = mat4_identity(); + model = mat4_make_scale(v3f(0.5f, 0.5f, 0.5f)); + model = mat4_translate(model, v3f(2.0f, 0.0f, 1.0f)); + shader_set_mat4fv(shader, "model", model); + mesh_draw(cube); + + model = mat4_identity(); + model = mat4_make_scale(v3f(0.25f, 0.25f, 0.25f)); + model = mat4_rotate_angles(model, v3f(60.0f, 0.0f, 0.0f)); + model = mat4_translate(model, v3f(-1.0f, 0.0f, 2.0f)); + shader_set_mat4fv(shader, "model", model); + mesh_draw(cube); } -int -main(void) +int main(void) { - GLFWwindow *window; - Arena *arena; - State state; - Mesh *cube_mesh, *plane_mesh; - F64 time, last_time; - - glfwSetErrorCallback(error_callback); - - if (glfwInit() == GLFW_FALSE) - return(1); - - glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); - glfwWindowHint(GLFW_SAMPLES, 4); - window = glfwCreateWindow(global_screen_width, global_screen_height, "Shadow mapping", 0, 0); - if (!window) - goto error; - - glfwSetKeyCallback(window, glfw_key_callback); - glfwSetWindowSizeCallback(window, resize_callback); - - glfwMakeContextCurrent(window); - - if (glewInit() != GLEW_OK) - goto error; - - glEnable(GL_DEPTH_TEST); - // glEnable(GL_CULL_FACE); - - /* NOTE(pryazha): Init */ - arena = arena_alloc(Megabytes(64)); - - state.camera = (Camera){ v3f(0.0f, 1.0f, 3.0f), 90.0f, 0.1f, 100.0f }; - light_pos = v3f(-2.0f, 4.0f, -2.0f); - - /* NOTE(pryazha): Meshes */ - Vertex plane_vertices[] = { - // positions // normals // texcoords - vertex(v3f(-25.0f, -0.5f, 25.0f), v3f(0.0f, 1.0f, 0.0f), v2f(0.0f, 0.0f)), - vertex(v3f(25.0f, -0.5f, 25.0f), v3f(0.0f, 1.0f, 0.0f), v2f(25.0f, 0.0f)), - vertex(v3f(-25.0f, -0.5f, -25.0f), v3f(0.0f, 1.0f, 0.0f), v2f(0.0f, 25.0f)), - - vertex(v3f(25.0f, -0.5f, 25.0f), v3f(0.0f, 1.0f, 0.0f), v2f(25.0f, 0.0f)), - vertex(v3f(25.0f, -0.5f, -25.0f), v3f(0.0f, 1.0f, 0.0f), v2f(25.0f, 25.0f)), - vertex(v3f(-25.0f, -0.5f, -25.0f), v3f(0.0f, 1.0f, 0.0f), v2f(0.0f, 25.0f)), - }; - U32 indices[] = { 0, 1, 2, 3, 4, 5 }; - plane_mesh = mesh_init(arena, plane_vertices, ArrayCount(plane_vertices), indices, ArrayCount(indices)); - cube_mesh = mesh_load_obj(arena, "../../data/models/cube.obj"); - - F32 quad_vertices[] = { - -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, - 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, - 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, - -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, - 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, - -1.0f, 1.0f, 0.0f, 0.0f, 1.0f - }; - - U32 vbo; - glGenVertexArrays(1, &global_quad_vao); - glBindVertexArray(global_quad_vao); - glGenBuffers(1, &vbo); - glBindBuffer(GL_ARRAY_BUFFER, vbo); - glBufferData(GL_ARRAY_BUFFER, sizeof(quad_vertices), quad_vertices, GL_STATIC_DRAW); - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5*sizeof(F32), (void *)0); - glEnableVertexAttribArray(1); - glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5*sizeof(F32), (void *)(3*sizeof(F32))); - glBindVertexArray(0); - - /* NOTE(pryazha): Shaders */ - global_debug_quad_shader = create_shader_program("shaders/debug_quad.vs", - "shaders/debug_quad.fs"); - global_simple_depth_shader = create_shader_program("shaders/simple_depth.vs", - "shaders/simple_depth.fs"); - global_shadow_shader = create_shader_program("shaders/shadow.vs", "shaders/shadow.fs"); - global_color_shader = create_shader_program("shaders/color.vs", "shaders/color.fs"); - - glUseProgram(global_shadow_shader); - shader_set_1i(global_shadow_shader, "diffuse_texture", 0); - shader_set_1i(global_shadow_shader, "shadow_map", 1); - glUseProgram(0); - - global_wood_texture = load_texture_gamma("../../data/textures/wood.png", 1); - - glGenFramebuffers(1, &global_depth_map_fbo); - glGenTextures(1, &global_depth_map); - glBindTexture(GL_TEXTURE_2D, global_depth_map); - glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, global_shadow_width, - global_shadow_height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); - glBindFramebuffer(GL_FRAMEBUFFER, global_depth_map_fbo); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, - global_depth_map, 0); - V4F border_color = v4f(1.0f, 1.0f, 1.0f, 1.0f); - glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, (const F32 *)&border_color); - glDrawBuffer(GL_NONE); - glReadBuffer(GL_NONE); - if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) - fprintf(stderr, "[ERROR]: Failed to complete depth map framebuffer.\n"); - glBindFramebuffer(GL_FRAMEBUFFER, 0); - - last_time = glfwGetTime(); - - while (!glfwWindowShouldClose(window)) - { - glfwPollEvents(); - if (key_first_press(global_input.exit)) - glfwSetWindowShouldClose(window, GLFW_TRUE); - update(&state, time); - render(&state, cube_mesh, plane_mesh); - glfwSwapBuffers(window); - - time = glfwGetTime(); - state.dt = time-last_time; - last_time = time; -#if 0 - fprintf(stdout, "[INFO]: dt: %f\n", state.dt); -#endif - } - - glfwTerminate(); - return(0); - - error: - glfwTerminate(); - return(1); + GLFWwindow *window; + Arena *arena; + State state; + F64 time, last_time; + S32 screen_width = 800, screen_height = 600; + U32 shadow_width = 1024, shadow_height = 1024; + Input input; + U32 shadows_ortho = 1; + V3F light_pos = v3f(-2.0f, 4.0f, -2.0f); + + glfwSetErrorCallback(error_callback); + + if (glfwInit() == GLFW_FALSE) + return(1); + + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); + glfwWindowHint(GLFW_SAMPLES, 4); + window = glfwCreateWindow(screen_width, screen_height, "Shadow mapping", 0, 0); + if (!window) + goto error; + + glfwMakeContextCurrent(window); + + if (glewInit() != GLEW_OK) + goto error; + + glEnable(GL_DEPTH_TEST); + // glEnable(GL_CULL_FACE); + + /* NOTE(pryazha): Init */ + arena = arena_alloc(Megabytes(64)); + + state.camera = (Camera){ v3f(0.0f, 1.0f, 3.0f), 90.0f, 0.1f, 100.0f, 0.0f, 0.0f }; + + /* NOTE(pryazha): Meshes */ + Vertex plane_vertices[] = { + // positions // normals // texcoords + vertex(v3f(-25.0f, -0.5f, 25.0f), v3f(0.0f, 1.0f, 0.0f), v2f( 0.0f, 0.0f)), + vertex(v3f( 25.0f, -0.5f, 25.0f), v3f(0.0f, 1.0f, 0.0f), v2f(25.0f, 0.0f)), + vertex(v3f(-25.0f, -0.5f, -25.0f), v3f(0.0f, 1.0f, 0.0f), v2f( 0.0f, 25.0f)), + + vertex(v3f( 25.0f, -0.5f, 25.0f), v3f(0.0f, 1.0f, 0.0f), v2f(25.0f, 0.0f)), + vertex(v3f( 25.0f, -0.5f, -25.0f), v3f(0.0f, 1.0f, 0.0f), v2f(25.0f, 25.0f)), + vertex(v3f(-25.0f, -0.5f, -25.0f), v3f(0.0f, 1.0f, 0.0f), v2f( 0.0f, 25.0f)), + }; + U32 indices[] = { 0, 1, 2, 3, 4, 5 }; + Mesh *plane = mesh_init(arena, plane_vertices, ArrayCount(plane_vertices), + indices, ArrayCount(indices)); + Mesh *cube = mesh_load_obj(arena, "../../data/models/cube.obj"); + + F32 quad_vertices[] = { + -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, + 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, + -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, + 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, + -1.0f, 1.0f, 0.0f, 0.0f, 1.0f + }; + + U32 quad_vao, vbo; + glGenVertexArrays(1, &quad_vao); + glBindVertexArray(quad_vao); + glGenBuffers(1, &vbo); + glBindBuffer(GL_ARRAY_BUFFER, vbo); + glBufferData(GL_ARRAY_BUFFER, sizeof(quad_vertices), quad_vertices, GL_STATIC_DRAW); + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5*sizeof(F32), (void *)0); + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5*sizeof(F32), (void *)(3*sizeof(F32))); + glBindVertexArray(0); + + /* NOTE(pryazha): Shaders */ + U32 debug_quad_shader = create_shader_program("shaders/debug_quad.vert", + "shaders/debug_quad.frag"); + U32 simple_depth_shader = create_shader_program("shaders/simple_depth.vert", + "shaders/simple_depth.frag"); + U32 shadow_shader = create_shader_program("shaders/shadow.vert", + "shaders/shadow.frag"); + U32 color_shader = create_shader_program("shaders/color.vert", + "shaders/color.frag"); + + glUseProgram(shadow_shader); + shader_set_1i(shadow_shader, "diffuse_texture", 0); + shader_set_1i(shadow_shader, "shadow_map", 1); + glUseProgram(0); + + U32 wood_texture = load_texture_gamma("../../data/textures/wood.png", 1); + + U32 depth_map_fbo, depth_map; + glGenFramebuffers(1, &depth_map_fbo); + glGenTextures(1, &depth_map); + glBindTexture(GL_TEXTURE_2D, depth_map); + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, shadow_width, + shadow_height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); + glBindFramebuffer(GL_FRAMEBUFFER, depth_map_fbo); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, + depth_map, 0); + V4F border_color = v4f(1.0f, 1.0f, 1.0f, 1.0f); + glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, (const F32 *)&border_color); + glDrawBuffer(GL_NONE); + glReadBuffer(GL_NONE); + if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) + fprintf(stderr, "[ERROR]: Failed to complete depth map framebuffer.\n"); + glBindFramebuffer(GL_FRAMEBUFFER, 0); + + last_time = glfwGetTime(); + + while (!glfwWindowShouldClose(window)) { + glfwPollEvents(); + + /* NOTE(pryazha): Update */ + process_glfw_keyboard(window, &input); + glfwGetFramebufferSize(window, &screen_width, &screen_height); + + V3F target = v3f_zero(); + + if (key_first_press(input.exit)) + glfwSetWindowShouldClose(window, GLFW_TRUE); + + V3F dv = get_dv_camera_orbital(&input, state.camera.pos, + target, state.dt, 3.0f); + state.camera.pos = v3f_add(state.camera.pos, dv); + + if (key_first_press(input.action_down)) + shadows_ortho = !shadows_ortho; + + input_update_last_state(&input); + + F32 radius, angular_speed, x, z; + + angular_speed = 1.0f; + radius = 4.0f; + x = f32_sin(time*angular_speed)*radius; + z = f32_cos(time*angular_speed)*radius; + + light_pos = v3f(x, 4.0f, z); + + /* NOTE(pryazha): Render */ + MAT4 proj, view, model, light_proj; + F32 fovx, near, far; + + if (shadows_ortho) { + near = 1.0f; + far = 10.0f; + F32 half_side = 10.0f; + light_proj = ortho(-half_side, half_side, -half_side, half_side, near, far); + } else { + fovx = 90.0f; + near = 1.0f; + far = 50.0f; + light_proj = perspective(fovx, (F32)shadow_width/(F32)shadow_height, + near, far); + } + + V3F up = v3f(0.0f, 1.0f, 0.0f); + MAT4 light_view = look_at(light_pos, target, up); + MAT4 light_space_matrix = mat4_mul(light_proj, light_view); + + glUseProgram(simple_depth_shader); + shader_set_mat4fv(simple_depth_shader, "light_space_matrix", light_space_matrix); + glViewport(0, 0, shadow_width, shadow_height); + glBindFramebuffer(GL_FRAMEBUFFER, depth_map_fbo); + glClear(GL_DEPTH_BUFFER_BIT); + // glCullFace(GL_FRONT); + render_scene(simple_depth_shader, cube, plane); + // glCullFace(GL_BACK); + glBindFramebuffer(GL_FRAMEBUFFER, 0); + + glViewport(0, 0, screen_width, screen_height); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + proj = perspective(state.camera.fovx, (F32)screen_width/(F32)screen_height, + state.camera.near, state.camera.far); + view = look_at(state.camera.pos, v3f_zero(), v3f(0.0f, 1.0f, 0.0f)); + + glUseProgram(shadow_shader); + shader_set_mat4fv(shadow_shader, "proj", proj); + shader_set_mat4fv(shadow_shader, "view", view); + shader_set_3fv(shadow_shader, "light_pos", light_pos); + shader_set_3fv(shadow_shader, "view_pos", state.camera.pos); + shader_set_mat4fv(shadow_shader, "light_space_matrix", light_space_matrix); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, wood_texture); + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, depth_map); + render_scene(shadow_shader, cube, plane); + + glUseProgram(color_shader); + shader_set_mat4fv(shadow_shader, "proj", proj); + shader_set_mat4fv(shadow_shader, "view", view); + model = mat4_make_scale(v3f(0.1f, 0.1f, 0.1f)); + model = mat4_translate(model, light_pos); + shader_set_mat4fv(shadow_shader, "model", model); + mesh_draw(cube); + + glDisable(GL_DEPTH_TEST); + glUseProgram(debug_quad_shader); + F32 scale = 0.3f; + Transform transform = transform_make_scale_translate(v3f(scale, scale, scale), + v3f(1.0f-scale, 1.0f-scale, 0.0f)); + model = transform_apply(transform); + shader_set_mat4fv(debug_quad_shader, "model", model); + shader_set_1f(debug_quad_shader, "near", near); + shader_set_1f(debug_quad_shader, "far", far); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, depth_map); + glBindVertexArray(quad_vao); + glDrawArrays(GL_TRIANGLES, 0, 6); + glBindVertexArray(0); + glEnable(GL_DEPTH_TEST); + glfwSwapBuffers(window); + + time = glfwGetTime(); + state.dt = time-last_time; + last_time = time; + } + + glfwTerminate(); + return(0); + +error: + glfwTerminate(); + return(1); } diff --git a/advanced_lighting/3.2.point_shadows/point_shadows b/advanced_lighting/3.2.point_shadows/point_shadows Binary files differindex c4668ab..452a2a2 100755 --- a/advanced_lighting/3.2.point_shadows/point_shadows +++ b/advanced_lighting/3.2.point_shadows/point_shadows diff --git a/advanced_lighting/3.2.point_shadows/point_shadows.c b/advanced_lighting/3.2.point_shadows/point_shadows.c index 0f60565..e622f6c 100644 --- a/advanced_lighting/3.2.point_shadows/point_shadows.c +++ b/advanced_lighting/3.2.point_shadows/point_shadows.c @@ -1,383 +1,261 @@ -#include "pwyazh.h" - #include "GL/glew.h" #include "GLFW/glfw3.h" +#include "pwyazh.h" #include "pwyazh_GL.h" #include "common.h" -static S32 global_screen_width = 800, global_screen_height = 600; -static Input global_input; -static B32 first_mouse = 1; - -void -glfw_key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) -{ - switch (action) - { - case GLFW_PRESS: { - switch (key) - { - case GLFW_KEY_D: { - global_input.move_right.state = KeyState_PRESS; - } break; - case GLFW_KEY_W: { - global_input.move_forward.state = KeyState_PRESS; - } break; - case GLFW_KEY_A: { - global_input.move_left.state = KeyState_PRESS; - } break; - case GLFW_KEY_S: { - global_input.move_backward.state = KeyState_PRESS; - } break; - case GLFW_KEY_E: { - global_input.move_up.state = KeyState_PRESS; - } break; - case GLFW_KEY_Q: { - global_input.move_down.state = KeyState_PRESS; - } break; - case GLFW_KEY_SPACE: { - global_input.jump.state = KeyState_PRESS; - } break; - case GLFW_KEY_RIGHT: { - global_input.action_right.state = KeyState_PRESS; - } break; - case GLFW_KEY_UP: { - global_input.action_up.state = KeyState_PRESS; - } break; - case GLFW_KEY_LEFT: { - global_input.action_left.state = KeyState_PRESS; - } break; - case GLFW_KEY_DOWN: { - global_input.action_down.state = KeyState_PRESS; - } break; - case GLFW_KEY_ESCAPE: { - global_input.exit.state = KeyState_PRESS; - } break; - } - } break; - - case GLFW_RELEASE: { - switch (key) - { - case GLFW_KEY_D: { - global_input.move_right.state = KeyState_RELEASE; - } break; - case GLFW_KEY_W: { - global_input.move_forward.state = KeyState_RELEASE; - } break; - case GLFW_KEY_A: { - global_input.move_left.state = KeyState_RELEASE; - } break; - case GLFW_KEY_S: { - global_input.move_backward.state = KeyState_RELEASE; - } break; - case GLFW_KEY_E: { - global_input.move_up.state = KeyState_RELEASE; - } break; - case GLFW_KEY_Q: { - global_input.move_down.state = KeyState_RELEASE; - } break; - case GLFW_KEY_SPACE: { - global_input.jump.state = KeyState_RELEASE; - } break; - case GLFW_KEY_RIGHT: { - global_input.action_right.state = KeyState_RELEASE; - } break; - case GLFW_KEY_UP: { - global_input.action_up.state = KeyState_RELEASE; - } break; - case GLFW_KEY_LEFT: { - global_input.action_left.state = KeyState_RELEASE; - } break; - case GLFW_KEY_DOWN: { - global_input.action_down.state = KeyState_RELEASE; - } break; - case GLFW_KEY_ESCAPE: { - global_input.exit.state = KeyState_RELEASE; - } break; - } - } break; - } -} - -void -resize_callback(GLFWwindow* window, int width, int height) -{ - global_screen_width = width; - global_screen_height = height; - /* glViewport(0, 0, global_screen_width, global_screen_height); */ -} - -void -error_callback(int error, const char *desc) -{ - fprintf(stderr, "[ERROR] GLFW: %s\n", desc); -} - -void -cursor_pos_callback(GLFWwindow* window, double xpos, double ypos) -{ - if (first_mouse) - { - global_input.last_mouse_pos = v2f(xpos, ypos); - first_mouse = 0; - } - global_input.mouse_offset = v2f(global_input.mouse_offset.x+((F32)xpos-global_input.last_mouse_pos.x), - global_input.mouse_offset.y+((F32)ypos-global_input.last_mouse_pos.y)); - global_input.last_mouse_pos = v2f((F32)xpos, (F32)ypos); -} - - -void -render_scene(U32 shader, Mesh *cube) +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) +int main(void) { - GLFWwindow *window; - Arena *arena; - State state; - Mesh *cube; - F64 time, last_time; - V3F light_pos; - MAT4 shadow_transforms[6]; - MAT4 proj, view; - - glfwSetErrorCallback(error_callback); - - if (glfwInit() == GLFW_FALSE) - return(1); - - glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); - glfwWindowHint(GLFW_SAMPLES, 4); - window = glfwCreateWindow(global_screen_width, global_screen_height, "Point shadows", 0, 0); - if (!window) - goto error; - - glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); - - glfwSetKeyCallback(window, glfw_key_callback); - glfwSetWindowSizeCallback(window, resize_callback); - glfwSetCursorPosCallback(window, cursor_pos_callback); - - glfwMakeContextCurrent(window); - - if (glewInit() != GLEW_OK) - goto error; - - glEnable(GL_DEPTH_TEST); - glEnable(GL_CULL_FACE); - - /* NOTE(pryazha): Init */ - arena = arena_alloc(Megabytes(64)); - - state.camera = (Camera){ - .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 */ - 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.vs", - "shaders/depth.fs", - "shaders/depth.gs"); - U32 shadow_shader = create_shader_program("shaders/shadow.vs", "shaders/shadow.fs"); - - 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(); - if (key_first_press(global_input.exit)) - glfwSetWindowShouldClose(window, GLFW_TRUE); - - /* 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; - V3F camera_dv; - - camera_dv = get_dv_camera_first_person(&global_input, &state.camera, - 1.0f, state.dt); - if (key_is_pressed(global_input.action_up)) - camera_dv = v3f_scalef(camera_dv, 3.0f); - camera_dp = v3f_add(camera_dp, camera_dv); - camera_dp = v3f_scalef(camera_dp, 0.8f); - state.camera.pos = v3f_add(state.camera.pos, camera_dp); - - F32 sensitivity = 0.1f; - global_input.mouse_offset = v2f_scalef(global_input.mouse_offset, sensitivity); - state.camera.yaw += global_input.mouse_offset.x; - state.camera.pitch += global_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(&global_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, global_screen_width, global_screen_height); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - glUseProgram(shadow_shader); - - aspect = (F32)global_screen_width/(F32)global_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, "projection", 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); + 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); + +error: + glfwTerminate(); + return(1); } diff --git a/advanced_lighting/3.2.point_shadows/shaders/depth.fs b/advanced_lighting/3.2.point_shadows/shaders/depth.frag index 88fb9e6..f95c0f8 100644 --- a/advanced_lighting/3.2.point_shadows/shaders/depth.fs +++ b/advanced_lighting/3.2.point_shadows/shaders/depth.frag @@ -5,8 +5,7 @@ in vec4 frag_pos; uniform vec3 light_pos; uniform float far; -void -main(void) +void main(void) { float light_distance = length(frag_pos.xyz-light_pos); light_distance = light_distance/far; diff --git a/advanced_lighting/3.2.point_shadows/shaders/depth.gs b/advanced_lighting/3.2.point_shadows/shaders/depth.geom index 638e2b9..de39788 100644 --- a/advanced_lighting/3.2.point_shadows/shaders/depth.gs +++ b/advanced_lighting/3.2.point_shadows/shaders/depth.geom @@ -6,18 +6,11 @@ uniform mat4 shadow_transforms[6]; out vec4 frag_pos; -void -main(void) +void main(void) { - for (int face = 0; - face < 6; - ++face) - { + for (int face = 0; face < 6; ++face) { gl_Layer = face; - for (int vertex = 0; - vertex < 3; - ++vertex) - { + for (int vertex = 0; vertex < 3; ++vertex) { frag_pos = gl_in[vertex].gl_Position; gl_Position = shadow_transforms[face]*frag_pos; EmitVertex(); diff --git a/advanced_lighting/3.2.point_shadows/shaders/depth.vs b/advanced_lighting/3.2.point_shadows/shaders/depth.vert index 37a3484..37ffd1b 100644 --- a/advanced_lighting/3.2.point_shadows/shaders/depth.vs +++ b/advanced_lighting/3.2.point_shadows/shaders/depth.vert @@ -3,8 +3,7 @@ layout(location = 0) in vec3 apos; uniform mat4 model; -void -main(void) +void main(void) { gl_Position = model*vec4(apos, 1.0); } diff --git a/advanced_lighting/3.2.point_shadows/shaders/shadow.fs b/advanced_lighting/3.2.point_shadows/shaders/shadow.frag index 6a3a8b0..bb006ca 100644 --- a/advanced_lighting/3.2.point_shadows/shaders/shadow.fs +++ b/advanced_lighting/3.2.point_shadows/shaders/shadow.frag @@ -24,8 +24,7 @@ vec3 grid_sampling_disk[20] = vec3[] vec3(0, 1, 1), vec3( 0, -1, 1), vec3( 0, -1, -1), vec3( 0, 1, -1) ); -float -calculate_shadow(vec3 frag_pos) +float calculate_shadow(vec3 frag_pos) { vec3 frag_to_light = frag_pos-light_pos; /* float closest_depth = texture(depth_cubemap, frag_to_light).r; */ @@ -80,8 +79,7 @@ calculate_shadow(vec3 frag_pos) return(shadow); } -void -main(void) +void main(void) { vec3 color = texture(diffuse_texture, fs_in.tex_coords).rgb; vec3 normal = normalize(fs_in.normal); diff --git a/advanced_lighting/3.2.point_shadows/shaders/shadow.vs b/advanced_lighting/3.2.point_shadows/shaders/shadow.vert index ac8ee4f..dccaa76 100644 --- a/advanced_lighting/3.2.point_shadows/shaders/shadow.vs +++ b/advanced_lighting/3.2.point_shadows/shaders/shadow.vert @@ -9,14 +9,13 @@ out VS_OUT { vec2 tex_coords; } vs_out; -uniform mat4 projection; +uniform mat4 proj; uniform mat4 view; uniform mat4 model; uniform bool reverse_normals; -void -main(void) +void main(void) { vs_out.frag_pos = vec3(model*vec4(apos, 1.0)); if (reverse_normals) @@ -25,5 +24,5 @@ main(void) vs_out.normal = mat3(transpose(inverse(model)))*anormal; vs_out.tex_coords = atex_coords; - gl_Position = projection*view*vec4(vs_out.frag_pos, 1.0); + gl_Position = proj*view*vec4(vs_out.frag_pos, 1.0); } diff --git a/advanced_lighting/4.normal_mapping/normal_mapping b/advanced_lighting/4.normal_mapping/normal_mapping Binary files differindex 6d33c26..1fbb26b 100755 --- a/advanced_lighting/4.normal_mapping/normal_mapping +++ b/advanced_lighting/4.normal_mapping/normal_mapping diff --git a/advanced_lighting/4.normal_mapping/normal_mapping.c b/advanced_lighting/4.normal_mapping/normal_mapping.c index 1d65b49..980f4a0 100644 --- a/advanced_lighting/4.normal_mapping/normal_mapping.c +++ b/advanced_lighting/4.normal_mapping/normal_mapping.c @@ -1,288 +1,251 @@ -#include "pwyazh.h" - #include "GL/glew.h" #include "GLFW/glfw3.h" +#include "pwyazh.h" #include "pwyazh_GL.h" #include "common.h" -static S32 global_screen_width = 800, global_screen_height = 600; -static Input global_input; -static B32 first_mouse = 1; - -void -resize_callback(GLFWwindow* window, int width, int height) -{ - global_screen_width = width; - global_screen_height = height; - glViewport(0, 0, global_screen_width, global_screen_height); -} - -void -cursor_pos_callback(GLFWwindow* window, double xpos, double ypos) -{ - if (first_mouse) - { - global_input.last_mouse_pos = v2f(xpos, ypos); - first_mouse = 0; - } - global_input.mouse_offset = v2f(global_input.mouse_offset.x+((F32)xpos-global_input.last_mouse_pos.x), - global_input.mouse_offset.y+((F32)ypos-global_input.last_mouse_pos.y)); - global_input.last_mouse_pos = v2f((F32)xpos, (F32)ypos); -} - -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); -} - -int -main(void) +int main(void) { - GLFWwindow *window; - Arena *arena; - State state; - Mesh *cube; - F64 time, last_time; - V3F light_pos; - MAT4 shadow_transforms[6]; - MAT4 proj, view; - - glfwSetErrorCallback(error_callback); - - if (glfwInit() == GLFW_FALSE) - return(1); - - glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); - glfwWindowHint(GLFW_SAMPLES, 4); - window = glfwCreateWindow(global_screen_width, global_screen_height, "Point shadows", 0, 0); - if (!window) - goto error; - - glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); - - glfwSetWindowSizeCallback(window, resize_callback); - glfwSetCursorPosCallback(window, cursor_pos_callback); - - glfwMakeContextCurrent(window); - - if (glewInit() != GLEW_OK) - goto error; - - glEnable(GL_DEPTH_TEST); - glEnable(GL_CULL_FACE); - - /* NOTE(pryazha): Init */ - arena = arena_alloc(Megabytes(64)); - - state.camera = (Camera){ - .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 */ - 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.vs", - "shaders/depth.fs", - "shaders/depth.gs"); - U32 shadow_shader = create_shader_program("shaders/shadow.vs", "shaders/shadow.fs"); - - 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 */ - process_glfw_keyboard(window, &global_input); - - if (key_first_press(global_input.exit)) - glfwSetWindowShouldClose(window, GLFW_TRUE); - - F32 x, y, z, angular_speed, radius; - V3F camera_dv; - - camera_dv = get_dv_camera_first_person(&global_input, &state.camera, - 1.0f, state.dt); - if (key_is_pressed(global_input.action_up)) - camera_dv = v3f_scalef(camera_dv, 3.0f); - camera_dp = v3f_add(camera_dp, camera_dv); - camera_dp = v3f_scalef(camera_dp, 0.8f); - state.camera.pos = v3f_add(state.camera.pos, camera_dp); - - F32 sensitivity = 0.1f; - global_input.mouse_offset = v2f_scalef(global_input.mouse_offset, sensitivity); - state.camera.yaw += global_input.mouse_offset.x; - state.camera.pitch += global_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(&global_input); - - angular_speed = 1.0f; - radius = 4.0f; - x = f32_sin(time*angular_speed)*radius; - y = 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, global_screen_width, global_screen_height); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - glUseProgram(shadow_shader); - - aspect = (F32)global_screen_width/(F32)global_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, "projection", 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); + GLFWwindow *window; + State state; + Input input; + F64 time, last_time; + V3F light_pos; + MAT4 proj, view, model; + F32 aspect, angle = 0.0f; + Mesh *cube = 0; + Arena *arena = 0; + S32 width, height; + + glfwSetErrorCallback(error_callback); + + if (glfwInit() == GLFW_FALSE) + return(1); + + width = 800; + height = 600; + + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); + glfwWindowHint(GLFW_SAMPLES, 4); + window = glfwCreateWindow(width, 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(Kilobytes(4)); + + state.camera = (Camera){ v3f(0.0f, 1.0f, 3.0f), 100.0f, 0.1f, 100.0f, 0.0f, 0.0f }; + V3F camera_dp = v3f_zero(); + F32 x, y, z; + + /* NOTE(pryazha): Meshes */ + cube = mesh_load_obj(arena, "../../data/models/cube.obj"); + + /* Positions */ + V3F p1 = v3f(-1.0f, 1.0f, 0.0f); + V3F p2 = v3f(-1.0f, -1.0f, 0.0f); + V3F p3 = v3f(1.0f, -1.0f, 0.0f); + V3F p4 = v3f(1.0f, 1.0f, 0.0f); + /* Texture ccoordinates */ + V2F uv1 = v2f(0.0f, 1.0f); + V2F uv2 = v2f(0.0f, 0.0f); + V2F uv3 = v2f(1.0f, 0.0f); + V2F uv4 = v2f(1.0f, 1.0f); + /* Normal vector */ + V3F nm = v3f(0.0f, 0.0f, 1.0f); + + V3F edge1, edge2; + V2F duv1, duv2; + F32 f; + V3F t1, bit1, t2, bit2; + + edge1 = v3f_sub(p2, p1); + edge2 = v3f_sub(p3, p1); + duv1 = v2f_sub(uv2, uv1); + duv2 = v2f_sub(uv3, uv1); + + f = 1.0f/(duv1.x*duv2.y-duv2.x*duv1.y); + + t1.x = f*(duv2.y*edge1.x-duv1.y*edge2.x); + t1.y = f*(duv2.y*edge1.y-duv1.y*edge2.y); + t1.z = f*(duv2.y*edge1.z-duv1.y*edge2.z); + + bit1.x = f*(-duv2.x*edge1.x+duv1.x*edge2.x); + bit1.y = f*(-duv2.x*edge1.y+duv1.x*edge2.y); + bit1.z = f*(-duv2.x*edge1.z+duv1.x*edge2.z); + + edge1 = v3f_sub(p3, p1); + edge2 = v3f_sub(p4, p1); + duv1 = v2f_sub(uv3, uv1); + duv2 = v2f_sub(uv4, uv1); + + f = 1.0f/(duv1.x*duv2.y-duv2.x*duv1.y); + + t2.x = f*(duv2.y*edge1.x-duv1.y*edge2.x); + t2.y = f*(duv2.y*edge1.y-duv1.y*edge2.y); + t2.z = f*(duv2.y*edge1.z-duv1.y*edge2.z); + + bit2.x = f*(-duv2.x*edge1.x+duv1.x*edge2.x); + bit2.y = f*(-duv2.x*edge1.y+duv1.x*edge2.y); + bit2.z = f*(-duv2.x*edge1.z+duv1.x*edge2.z); + + F32 quad_vertices[] = { + p1.x, p1.y, p1.z, nm.x, nm.y, nm.z, uv1.x, uv1.y, t1.x, t1.y, t1.z, bit1.x, bit1.y, bit1.z, + p2.x, p2.y, p2.z, nm.x, nm.y, nm.z, uv2.x, uv2.y, t1.x, t1.y, t1.z, bit1.x, bit1.y, bit1.z, + p3.x, p3.y, p3.z, nm.x, nm.y, nm.z, uv3.x, uv3.y, t1.x, t1.y, t1.z, bit1.x, bit1.y, bit1.z, + + p1.x, p1.y, p1.z, nm.x, nm.y, nm.z, uv1.x, uv1.y, t2.x, t2.y, t2.z, bit2.x, bit2.y, bit2.z, + p3.x, p3.y, p3.z, nm.x, nm.y, nm.z, uv3.x, uv3.y, t2.x, t2.y, t2.z, bit2.x, bit2.y, bit2.z, + p4.x, p4.y, p4.z, nm.x, nm.y, nm.z, uv4.x, uv4.y, t2.x, t2.y, t2.z, bit2.x, bit2.y, bit2.z + }; + 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, 14*sizeof(F32), (void *)0); + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 14*sizeof(F32), (void *)(3*sizeof(F32))); + glEnableVertexAttribArray(2); + glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 14*sizeof(F32), (void *)(6*sizeof(F32))); + glEnableVertexAttribArray(3); + glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, 14*sizeof(F32), (void *)(8*sizeof(F32))); + glEnableVertexAttribArray(4); + glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, 14*sizeof(F32), (void *)(11*sizeof(F32))); + 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"); + + glUseProgram(normal_map_shader); + shader_set_1i(normal_map_shader, "diffuse_texture", 0); + shader_set_1i(normal_map_shader, "normal_map", 1); + glUseProgram(0); + + U32 brickwall_diffuse_texture = load_texture("../../data/textures/brickwall.jpg"); + U32 brickwall_normal_texture = load_texture("../../data/textures/brickwall_normal.jpg"); + + 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 */ + 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, &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); + + angle += 40.0f*state.dt; + + x = f32_cos((F32)time); + y = f32_sin((F32)time); + z = 1.0f; + light_pos = v3f(x, y, z); + + /* NOTE(pryazha): Render */ + aspect = (F32)width/(F32)height; + proj = perspective(state.camera.fovx, aspect, + state.camera.near, state.camera.far); + view = get_view_matrix(&state.camera); + + glViewport(0, 0, width, height); + glClearColor(0.15f, 0.15f, 0.15f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glUseProgram(normal_map_shader); + shader_set_mat4fv(normal_map_shader, "proj", proj); + shader_set_mat4fv(normal_map_shader, "view", view); + shader_set_3fv(normal_map_shader, "light_pos", light_pos); + shader_set_3fv(normal_map_shader, "view_pos", state.camera.pos); + model = mat4_rotate_angles(mat4_identity(), v3f(angle, angle, angle)); + shader_set_mat4fv(normal_map_shader, "model", model); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, brickwall_diffuse_texture); + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, brickwall_normal_texture); + glBindVertexArray(quad_vao); + glDrawArrays(GL_TRIANGLES, 0, 6); + glBindVertexArray(0); + glUseProgram(0); + + glUseProgram(color_shader); + shader_set_mat4fv(color_shader, "proj", proj); + shader_set_mat4fv(color_shader, "view", view); + model = mat4_make_scale(v3f(0.05f, 0.05f, 0.05f)); + model = mat4_translate(model, light_pos); + shader_set_mat4fv(color_shader, "model", model); + mesh_draw(cube); + glUseProgram(0); + + glUseProgram(normals_debug_shader); + shader_set_mat4fv(normals_debug_shader, "proj", proj); + shader_set_mat4fv(normals_debug_shader, "view", view); + model = mat4_rotate_angles(mat4_identity(), v3f(angle, angle, angle)); + shader_set_mat4fv(normals_debug_shader, "model", model); + glBindVertexArray(quad_vao); + glDrawArrays(GL_TRIANGLES, 0, 6); + glBindVertexArray(0); + glUseProgram(0); + + glfwSwapBuffers(window); + + time = glfwGetTime(); + state.dt = time-last_time; + last_time = time; + } + + arena_release(arena); + glfwTerminate(); + return(0); + +error: + arena_release(arena); + glfwTerminate(); + return(1); } diff --git a/advanced_lighting/4.normal_mapping/shaders/color.frag b/advanced_lighting/4.normal_mapping/shaders/color.frag new file mode 100644 index 0000000..c01da99 --- /dev/null +++ b/advanced_lighting/4.normal_mapping/shaders/color.frag @@ -0,0 +1,8 @@ +#version 330 core + +out vec4 frag_color; + +void main(void) +{ + frag_color = vec4(1.0); +} diff --git a/advanced_lighting/1.blinn_phong/shaders/light.vs b/advanced_lighting/4.normal_mapping/shaders/color.vert index ade669b..a8b1247 100644 --- a/advanced_lighting/1.blinn_phong/shaders/light.vs +++ b/advanced_lighting/4.normal_mapping/shaders/color.vert @@ -1,12 +1,11 @@ #version 330 core layout(location = 0) in vec3 apos; -uniform mat4 projection; +uniform mat4 proj; uniform mat4 view; uniform mat4 model; -void -main(void) +void main(void) { - gl_Position = projection*view*model*vec4(apos, 1.0); + gl_Position = proj*view*model*vec4(apos, 1.0); } diff --git a/advanced_lighting/4.normal_mapping/shaders/depth.fs b/advanced_lighting/4.normal_mapping/shaders/depth.fs deleted file mode 100644 index 88fb9e6..0000000 --- a/advanced_lighting/4.normal_mapping/shaders/depth.fs +++ /dev/null @@ -1,14 +0,0 @@ -#version 330 core - -in vec4 frag_pos; - -uniform vec3 light_pos; -uniform float far; - -void -main(void) -{ - float light_distance = length(frag_pos.xyz-light_pos); - light_distance = light_distance/far; - gl_FragDepth = light_distance; -} diff --git a/advanced_lighting/4.normal_mapping/shaders/depth.gs b/advanced_lighting/4.normal_mapping/shaders/depth.gs deleted file mode 100644 index 638e2b9..0000000 --- a/advanced_lighting/4.normal_mapping/shaders/depth.gs +++ /dev/null @@ -1,27 +0,0 @@ -#version 330 core -layout(triangles) in; -layout(triangle_strip, max_vertices=18) out; - -uniform mat4 shadow_transforms[6]; - -out vec4 frag_pos; - -void -main(void) -{ - for (int face = 0; - face < 6; - ++face) - { - gl_Layer = face; - for (int vertex = 0; - vertex < 3; - ++vertex) - { - frag_pos = gl_in[vertex].gl_Position; - gl_Position = shadow_transforms[face]*frag_pos; - EmitVertex(); - } - EndPrimitive(); - } -} diff --git a/advanced_lighting/4.normal_mapping/shaders/depth.vs b/advanced_lighting/4.normal_mapping/shaders/depth.vs deleted file mode 100644 index 37a3484..0000000 --- a/advanced_lighting/4.normal_mapping/shaders/depth.vs +++ /dev/null @@ -1,10 +0,0 @@ -#version 330 core -layout(location = 0) in vec3 apos; - -uniform mat4 model; - -void -main(void) -{ - gl_Position = model*vec4(apos, 1.0); -} diff --git a/advanced_lighting/4.normal_mapping/shaders/normal_map.frag b/advanced_lighting/4.normal_mapping/shaders/normal_map.frag new file mode 100644 index 0000000..964d6f8 --- /dev/null +++ b/advanced_lighting/4.normal_mapping/shaders/normal_map.frag @@ -0,0 +1,51 @@ +#version 330 core + +in VS_OUT { + /* mat3 TBN; */ + vec3 frag_pos; + vec3 tangent_light_pos; + vec3 tangent_view_pos; + vec3 tangent_frag_pos; + vec2 tex_coords; +} fs_in; + +out vec4 frag_color; + +/* uniform vec3 light_pos; */ +/* uniform vec3 view_pos; */ + +uniform sampler2D diffuse_texture; +uniform sampler2D normal_map; + +void main(void) +{ + vec3 color = vec3(texture(diffuse_texture, fs_in.tex_coords)); + vec3 normal = vec3(texture(normal_map, fs_in.tex_coords)); + normal = normalize((normal*2.0)-1.0); + /* + normal = normalize(fs_in.TBN*normal); + + vec3 light_dir = fs_in.TBN * normalize(light_pos - fs_in.frag_pos); + vec3 view_dir = fs_in.TBN * normalize(view_pos - fs_in.frag_pos); + */ + + vec3 light_color = vec3(1.0); + + float ambient = 0.01; + + /* vec3 light_dir = normalize(light_pos-fs_in.frag_pos); */ + vec3 light_dir = normalize(fs_in.tangent_light_pos - fs_in.tangent_frag_pos); + float diff = max(dot(light_dir, normal), 0.0); + vec3 diffuse = diff*light_color; + + /* vec3 view_dir = normalize(view_pos-fs_in.frag_pos); */ + vec3 view_dir = normalize(fs_in.tangent_view_pos-fs_in.frag_pos); + vec3 halfway_dir = normalize(light_dir+view_dir); + float spec = pow(max(dot(halfway_dir, normal), 0.0), 64.0); + float spec_strength = 1.0; + vec3 specular = spec_strength*spec*light_color; + + vec3 result = (ambient+diffuse+specular)*color; + + frag_color = vec4(result, 1.0); +} diff --git a/advanced_lighting/4.normal_mapping/shaders/normal_map.vert b/advanced_lighting/4.normal_mapping/shaders/normal_map.vert new file mode 100644 index 0000000..3b089b5 --- /dev/null +++ b/advanced_lighting/4.normal_mapping/shaders/normal_map.vert @@ -0,0 +1,36 @@ +#version 330 core +layout(location = 0) in vec3 apos; +layout(location = 1) in vec3 anormal; +layout(location = 2) in vec2 atex_coords; +layout(location = 3) in vec3 atangent; +layout(location = 4) in vec3 abitangent; + +out VS_OUT { + /* mat3 TBN; */ + vec3 frag_pos; + vec3 tangent_light_pos; + vec3 tangent_view_pos; + vec3 tangent_frag_pos; + vec2 tex_coords; +} vs_out; + +uniform mat4 proj; +uniform mat4 view; +uniform mat4 model; + +uniform vec3 light_pos; +uniform vec3 view_pos; + +void main(void) +{ + vs_out.frag_pos = vec3(model * vec4(apos, 1.0)); + vs_out.tex_coords = atex_coords; + vec3 T = normalize(vec3(model * vec4(atangent, 0.0))); + vec3 B = normalize(vec3(model * vec4(abitangent, 0.0))); + vec3 N = normalize(vec3(model * vec4(anormal, 0.0))); + mat3 TBN = transpose(mat3(T, B, N)); + vs_out.tangent_light_pos = TBN * light_pos; + vs_out.tangent_view_pos = TBN * view_pos; + vs_out.tangent_frag_pos = TBN * vec3(model * vec4(apos, 0.0)); + gl_Position = proj * view * vec4(vs_out.frag_pos, 1.0); +} diff --git a/advanced_lighting/4.normal_mapping/shaders/normals_debug.frag b/advanced_lighting/4.normal_mapping/shaders/normals_debug.frag new file mode 100644 index 0000000..04dadd4 --- /dev/null +++ b/advanced_lighting/4.normal_mapping/shaders/normals_debug.frag @@ -0,0 +1,10 @@ +#version 330 core + +in vec3 vcolor; + +out vec4 frag_color; + +void main(void) +{ + frag_color = vec4(vcolor, 1.0); +} diff --git a/advanced_lighting/4.normal_mapping/shaders/normals_debug.geom b/advanced_lighting/4.normal_mapping/shaders/normals_debug.geom new file mode 100644 index 0000000..666c08a --- /dev/null +++ b/advanced_lighting/4.normal_mapping/shaders/normals_debug.geom @@ -0,0 +1,44 @@ +#version 330 core +layout(triangles) in; +layout(line_strip, max_vertices=18) out; + +in VS_OUT { + vec4 tangent; + vec4 bitangent; + vec4 normal; +} gs_in[]; + +out vec3 vcolor; + +uniform mat4 proj; + +void gen_normals(int index) +{ + vcolor = vec3(1.0, 0.0, 0.0); + gl_Position = proj*(gl_in[index].gl_Position); + EmitVertex(); + gl_Position = proj*(gl_in[index].gl_Position+0.5*gs_in[index].tangent); + EmitVertex(); + EndPrimitive(); + + vcolor = vec3(0.0, 0.0, 1.0); + gl_Position = proj*(gl_in[index].gl_Position); + EmitVertex(); + gl_Position = proj*(gl_in[index].gl_Position+0.5*gs_in[index].bitangent); + EmitVertex(); + EndPrimitive(); + + vcolor = vec3(0.0, 1.0, 0.0); + gl_Position = proj*(gl_in[index].gl_Position); + EmitVertex(); + gl_Position = proj*(gl_in[index].gl_Position+0.5*gs_in[index].normal); + EmitVertex(); + EndPrimitive(); +} + +void main(void) +{ + gen_normals(0); + gen_normals(1); + gen_normals(2); +} diff --git a/advanced_lighting/4.normal_mapping/shaders/normals_debug.vert b/advanced_lighting/4.normal_mapping/shaders/normals_debug.vert new file mode 100644 index 0000000..d3eed77 --- /dev/null +++ b/advanced_lighting/4.normal_mapping/shaders/normals_debug.vert @@ -0,0 +1,22 @@ +#version 330 core +layout(location = 0) in vec3 apos; +layout(location = 1) in vec3 anormal; +layout(location = 3) in vec3 atangent; +layout(location = 4) in vec3 abitangent; + +out VS_OUT { + vec4 tangent; + vec4 bitangent; + vec4 normal; +} vs_out; + +uniform mat4 view; +uniform mat4 model; + +void main(void) +{ + vs_out.tangent = view*model*vec4(normalize(atangent), 0.0); + vs_out.bitangent = view*model*vec4(normalize(abitangent), 0.0); + vs_out.normal = view*model*vec4(normalize(anormal), 0.0); + gl_Position = view*model*vec4(apos, 1.0); +} diff --git a/advanced_lighting/4.normal_mapping/shaders/shadow.fs b/advanced_lighting/4.normal_mapping/shaders/shadow.fs deleted file mode 100644 index 6a3a8b0..0000000 --- a/advanced_lighting/4.normal_mapping/shaders/shadow.fs +++ /dev/null @@ -1,105 +0,0 @@ -#version 330 core - -in VS_OUT { - vec3 frag_pos; - vec3 normal; - vec2 tex_coords; -} fs_in; - -out vec4 frag_color; - -uniform vec3 light_pos; -uniform vec3 view_pos; -uniform float far; - -uniform sampler2D diffuse_texture; -uniform samplerCube depth_cubemap; - -vec3 grid_sampling_disk[20] = vec3[] -( - vec3(1, 1, 1), vec3( 1, -1, 1), vec3(-1, -1, 1), vec3(-1, 1, 1), - vec3(1, 1, -1), vec3( 1, -1, -1), vec3(-1, -1, -1), vec3(-1, 1, -1), - vec3(1, 1, 0), vec3( 1, -1, 0), vec3(-1, -1, 0), vec3(-1, 1, 0), - vec3(1, 0, 1), vec3(-1, 0, 1), vec3( 1, 0, -1), vec3(-1, 0, -1), - vec3(0, 1, 1), vec3( 0, -1, 1), vec3( 0, -1, -1), vec3( 0, 1, -1) -); - -float -calculate_shadow(vec3 frag_pos) -{ - vec3 frag_to_light = frag_pos-light_pos; - /* float closest_depth = texture(depth_cubemap, frag_to_light).r; */ - /* closest_depth *= far; */ - float current_depth = length(frag_to_light); - /* float bias = 0.05; */ - /* float shadow = current_depth-bias > closest_depth ? 1.0 : 0.0; */ - /* NOTE(pryazha): Display depth value for debugging */ - /* frag_color = vec4(vec3(closest_depth/far), 1.0); */ - /* - float shadow = 0.0; - float offset = 0.1; - float samples = 4.0; - for (float x = -offset; - x < offset; - x += offset/(samples*0.5)) - { - for (float y = -offset; - y < offset; - y += offset/(samples*0.5)) - { - for (float z = -offset; - z < offset; - z += offset/(samples*0.5)) - { - float closest_depth = texture(depth_cubemap, frag_to_light+vec3(x, y, z)).r; - closest_depth *= far; - if (current_depth-bias > closest_depth) - shadow += 1.0; - } - } - } - shadow /= (samples*samples*samples); - */ - - float shadow = 0.0; - float bias = 0.15; - int samples = 20; - float view_distance = length(view_pos-frag_pos); - float disk_radius = (1.0+(view_distance/far))/25.0; - for (int sample = 0; - sample < samples; - ++sample) - { - float closest_depth = texture(depth_cubemap, frag_to_light+ - grid_sampling_disk[sample]*disk_radius).r; - closest_depth *= far; - if (current_depth-bias > closest_depth) - shadow += 1.0; - } - shadow /= float(samples); - return(shadow); -} - -void -main(void) -{ - vec3 color = texture(diffuse_texture, fs_in.tex_coords).rgb; - vec3 normal = normalize(fs_in.normal); - vec3 light_color = vec3(0.5); - - vec3 ambient = 0.5*light_color; - - vec3 light_dir = normalize(light_pos-fs_in.frag_pos); - float diff = max(dot(light_dir, normal), 0.0); - vec3 diffuse = diff*light_color; - - vec3 view_dir = normalize(view_pos-fs_in.frag_pos); - vec3 halfway_dir = normalize(light_dir+view_dir); - float spec = pow(max(dot(halfway_dir, normal), 0.0), 64.0); - vec3 specular = spec*light_color; - - float shadow = calculate_shadow(fs_in.frag_pos); - vec3 lighting = (ambient+(1.0-shadow)*(diffuse+specular))*color; - - frag_color = vec4(lighting, 1.0); -} diff --git a/advanced_lighting/4.normal_mapping/shaders/shadow.vs b/advanced_lighting/4.normal_mapping/shaders/shadow.vs deleted file mode 100644 index ac8ee4f..0000000 --- a/advanced_lighting/4.normal_mapping/shaders/shadow.vs +++ /dev/null @@ -1,29 +0,0 @@ -#version 330 core -layout(location = 0) in vec3 apos; -layout(location = 1) in vec3 anormal; -layout(location = 2) in vec2 atex_coords; - -out VS_OUT { - vec3 frag_pos; - vec3 normal; - vec2 tex_coords; -} vs_out; - -uniform mat4 projection; -uniform mat4 view; -uniform mat4 model; - -uniform bool reverse_normals; - -void -main(void) -{ - vs_out.frag_pos = vec3(model*vec4(apos, 1.0)); - if (reverse_normals) - vs_out.normal = mat3(transpose(inverse(model)))*(-1.0*anormal); - else - vs_out.normal = mat3(transpose(inverse(model)))*anormal; - - vs_out.tex_coords = atex_coords; - gl_Position = projection*view*vec4(vs_out.frag_pos, 1.0); -} diff --git a/advanced_opengl/1.depth/depth b/advanced_opengl/1.depth/depth Binary files differindex 68f04d6..80da145 100755 --- a/advanced_opengl/1.depth/depth +++ b/advanced_opengl/1.depth/depth diff --git a/advanced_opengl/1.depth/depth.c b/advanced_opengl/1.depth/depth.c index eb79c1c..03092df 100644 --- a/advanced_opengl/1.depth/depth.c +++ b/advanced_opengl/1.depth/depth.c @@ -2,273 +2,184 @@ #include "GLFW/glfw3.h" #include "pwyazh.h" - #include "pwyazh_GL.h" #include "common.h" -#include <unistd.h> +int main(void) +{ + GLFWwindow *window; + State state; + S32 width, height; + Input input; -#define WIDTH 1280 -#define HEIGHT 720 + if (glfwInit() == GLFW_FALSE) { + fprintf(stderr, "[ERROR] Failed to initialize glfw.\n"); + return(1); + } -static V3F camera_pos; -static F32 dt; -static Input input; + width = 1024; + height = 768; -void -key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) -{ - switch (action) - { - case GLFW_PRESS: { - switch (key) - { - case GLFW_KEY_D: { - input.move_right.state = KeyState_PRESS; - } break; - case GLFW_KEY_W: { - input.move_forward.state = KeyState_PRESS; - } break; - case GLFW_KEY_A: { - input.move_left.state = KeyState_PRESS; - } break; - case GLFW_KEY_S: { - input.move_backward.state = KeyState_PRESS; - } break; - case GLFW_KEY_E: { - input.move_up.state = KeyState_PRESS; - } break; - case GLFW_KEY_Q: { - input.move_down.state = KeyState_PRESS; - } break; - } - } break; - - case GLFW_RELEASE: { - switch (key) - { - case GLFW_KEY_D: { - input.move_right.state = KeyState_RELEASE; - } break; - case GLFW_KEY_W: { - input.move_forward.state = KeyState_RELEASE; - } break; - case GLFW_KEY_A: { - input.move_left.state = KeyState_RELEASE; - } break; - case GLFW_KEY_S: { - input.move_backward.state = KeyState_RELEASE; - } break; - case GLFW_KEY_E: { - input.move_up.state = KeyState_RELEASE; - } break; - case GLFW_KEY_Q: { - input.move_down.state = KeyState_RELEASE; - } break; - } - } break; - } -} + 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); + } -int -main(void) -{ - GLFWwindow *window; - - if (glfwInit() == GLFW_FALSE) - { - fprintf(stderr, "[ERROR] Failed to initialize glfw.\n"); - return(1); - } - - glfwWindowHint(GLFW_RESIZABLE, 0); - 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); - - glfwSetKeyCallback(window, key_callback); - - 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.vs", "shaders/depth.fs"); - 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)) - }; - - Transform platform_position = - transform_make_scale_translate(v3f(10.0f, 0.2f, 10.0f), - v3f(0.0f, -(a+(a*0.2f)+0.01f), 0.0f)); - - 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); - - F32 target_fps = 60.0f; - F32 target_spf = 1.0f/target_fps; - camera_pos = v3f(0.0f, 0.0f, 3.0f); - - /* glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); */ - - F32 last_time = glfwGetTime(); - - while (!glfwWindowShouldClose(window)) - { - glfwPollEvents(); - - /* INFO(pryazha): update */ - V3F left, up, forward; - V3F world_up = v3f(0.0f, 1.0f, 0.0f); - - forward = v3f_norm(v3f_sub(v3f(0.0f, 0.0f, 0.0f), camera_pos)); - left = v3f_norm(v3f_cross(world_up, forward)); - up = v3f_cross(forward, left); - - V3F dp = v3f_zero(); - - F32 speed = 2.0f; - if (key_is_pressed(input.move_right)) - dp = v3f_add(dp, v3f_scalef(left, -speed*dt)); - if (key_is_pressed(input.move_forward)) - dp = v3f_add(dp, v3f_scalef(forward, speed*dt)); - if (key_is_pressed(input.move_left)) - dp = v3f_add(dp, v3f_scalef(left, speed*dt)); - if (key_is_pressed(input.move_backward)) - dp = v3f_add(dp, v3f_scalef(forward, -speed*dt)); - if (key_is_pressed(input.move_up)) - dp = v3f_add(dp, v3f_scalef(up, speed*dt)); - if (key_is_pressed(input.move_down)) - dp = v3f_add(dp, v3f_scalef(up, -speed*dt)); - - input_update_last_state(&input); - - camera_pos = v3f_add(camera_pos, dp); - - /* INFO(pryazha): render */ - glClearColor(0.15f, 0.15f, 0.15f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - glUseProgram(shader); - MAT4 model, view, projection; - - view = look_at(camera_pos, v3f(0.0f, 0.0f, 0.0f), v3f(0.0f, 1.0f, 0.0f)); - shader_set_mat4fv(shader, "view", view); - - /* projection = ortho(-5.0f, 5.0f, -5.0f, 5.0f, 0.1f, 100.0f); */ - F32 fovx = 90.0f; - F32 near = 0.1f; - F32 far = 100.0f; - projection = perspective(fovx, (F32)WIDTH/(F32)HEIGHT, near, far); - - shader_set_mat4fv(shader, "projection", projection); - - glBindTexture(GL_TEXTURE_2D, marble_texture); - glBindVertexArray(VAO); - for (S32 transform_index = 0; - transform_index < (S32)ArrayCount(cube_positions); - ++transform_index) - { - model = transform_apply(cube_positions[transform_index]); - shader_set_mat4fv(shader, "model", model); - glDrawArrays(GL_TRIANGLES, 0, 36); - } - - glBindTexture(GL_TEXTURE_2D, metal_texture); - model = transform_apply(platform_position); - shader_set_mat4fv(shader, "model", model); - glDrawArrays(GL_TRIANGLES, 0, 36); - - 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(); - dt = current_time-last_time; - last_time = current_time; - } - - glfwTerminate(); - return(0); + 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); } diff --git a/advanced_opengl/1.depth/shaders/depth.fs b/advanced_opengl/1.depth/shaders/depth.frag index a515c15..710b0d2 100644 --- a/advanced_opengl/1.depth/shaders/depth.fs +++ b/advanced_opengl/1.depth/shaders/depth.frag @@ -9,19 +9,15 @@ uniform sampler2D our_texture; float near = 0.1; float far = 100.0; -float -linearize_depth(float depth) +float linearize_depth(float depth) { float ndc_z = 2.0*depth-1.0; return((2.0*near*far)/(far+near-ndc_z*(far-near))); } -void -main(void) +void main(void) { - /* - frag_color = texture(our_texture, tex_coords); - */ + /* frag_color = texture(our_texture, tex_coords); */ float depth = linearize_depth(gl_FragCoord.z)/far; frag_color = vec4(vec3(depth), 1.0); } diff --git a/advanced_opengl/1.depth/shaders/depth.vs b/advanced_opengl/1.depth/shaders/depth.vert index 62e71a2..68b8fe2 100644 --- a/advanced_opengl/1.depth/shaders/depth.vs +++ b/advanced_opengl/1.depth/shaders/depth.vert @@ -4,13 +4,12 @@ layout(location = 1) in vec2 atex_coords; uniform mat4 model; uniform mat4 view; -uniform mat4 projection; +uniform mat4 proj; out vec2 tex_coords; -void -main(void) +void main(void) { - gl_Position = projection*view*model*vec4(apos, 1.0); + gl_Position = proj*view*model*vec4(apos, 1.0); tex_coords = atex_coords; } diff --git a/advanced_opengl/10.antialiasing/anti_aliasing_msaa b/advanced_opengl/10.antialiasing/anti_aliasing_msaa Binary files differindex 36811f7..694aa7d 100755 --- a/advanced_opengl/10.antialiasing/anti_aliasing_msaa +++ b/advanced_opengl/10.antialiasing/anti_aliasing_msaa diff --git a/advanced_opengl/10.antialiasing/anti_aliasing_msaa.c b/advanced_opengl/10.antialiasing/anti_aliasing_msaa.c index 65a5b01..250ab97 100644 --- a/advanced_opengl/10.antialiasing/anti_aliasing_msaa.c +++ b/advanced_opengl/10.antialiasing/anti_aliasing_msaa.c @@ -2,207 +2,126 @@ #include "GLFW/glfw3.h" #include "pwyazh.h" - #include "pwyazh_GL.h" #include "common.h" -#include <unistd.h> +int main(void) +{ + GLFWwindow *window; + Arena *arena = 0; + Mesh *cube; + Input input; + F32 target_fps, target_spf, last_time; + MAT4 proj, view, model; + State state; + S32 width, height; + U32 color_shader; -static S32 global_width = 1024, global_height = 768; -static Input global_input; + if (glfwInit() == GLFW_FALSE) { + fprintf(stderr, "[ERROR] Failed to initialize glfw.\n"); + return(1); + } -void -key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) -{ - switch (action) - { - case GLFW_PRESS: { - switch (key) - { - case GLFW_KEY_D: { - global_input.move_right.state = KeyState_PRESS; - } break; - case GLFW_KEY_W: { - global_input.move_forward.state = KeyState_PRESS; - } break; - case GLFW_KEY_A: { - global_input.move_left.state = KeyState_PRESS; - } break; - case GLFW_KEY_S: { - global_input.move_backward.state = KeyState_PRESS; - } break; - case GLFW_KEY_E: { - global_input.move_up.state = KeyState_PRESS; - } break; - case GLFW_KEY_Q: { - global_input.move_down.state = KeyState_PRESS; - } break; - case GLFW_KEY_SPACE: { - global_input.jump.state = KeyState_PRESS; - } break; - case GLFW_KEY_RIGHT: { - global_input.action_right.state = KeyState_PRESS; - } break; - case GLFW_KEY_LEFT: { - global_input.action_left.state = KeyState_PRESS; - } break; - case GLFW_KEY_ESCAPE: { - global_input.exit.state = KeyState_PRESS; - } break; - } - } break; - - case GLFW_RELEASE: { - switch (key) - { - case GLFW_KEY_D: { - global_input.move_right.state = KeyState_RELEASE; - } break; - case GLFW_KEY_W: { - global_input.move_forward.state = KeyState_RELEASE; - } break; - case GLFW_KEY_A: { - global_input.move_left.state = KeyState_RELEASE; - } break; - case GLFW_KEY_S: { - global_input.move_backward.state = KeyState_RELEASE; - } break; - case GLFW_KEY_E: { - global_input.move_up.state = KeyState_RELEASE; - } break; - case GLFW_KEY_Q: { - global_input.move_down.state = KeyState_RELEASE; - } break; - case GLFW_KEY_SPACE: { - global_input.jump.state = KeyState_RELEASE; - } break; - case GLFW_KEY_RIGHT: { - global_input.action_right.state = KeyState_RELEASE; - } break; - case GLFW_KEY_LEFT: { - global_input.action_left.state = KeyState_RELEASE; - } break; - case GLFW_KEY_ESCAPE: { - global_input.exit.state = KeyState_RELEASE; - } break; - } - } break; - } -} + width = 1024; + height = 768; -void -window_resize_callback(GLFWwindow* window, int width, int height) -{ - global_width = width; - global_height = height; - glViewport(0, 0, global_width, global_height); -} + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); + glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); + glfwWindowHint(GLFW_SAMPLES, 4); + window = glfwCreateWindow(width, height, "Anti Aliasing (MSAA)", 0, 0); + if (!window) { + fprintf(stderr, "[ERROR] Failed to create window.\n"); + glfwTerminate(); + return(1); + } -int -main(void) -{ - GLFWwindow *window; - Arena *arena = 0; - F32 target_fps, target_spf, - last_time, dt; - MAT4 projection, view, model; - V3F camera_pos; - F32 camera_speed, fovx, near, far; - U32 color_shader; - - 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); - glfwWindowHint(GLFW_SAMPLES, 4); - window = glfwCreateWindow(global_width, global_height, "Anti Aliasing (MSAA)", 0, 0); - if (!window) - { - fprintf(stderr, "[ERROR] Failed to create window.\n"); - glfwTerminate(); - return(1); - } - - glfwMakeContextCurrent(window); - - glfwSetKeyCallback(window, key_callback); - glfwSetWindowSizeCallback(window, window_resize_callback); - - if (glewInit() != GLEW_OK) - { - fprintf(stderr, "[ERROR] Failed to initialize glew.\n"); - glfwTerminate(); - return(1); - } - - glEnable(GL_DEPTH_TEST); - glEnable(GL_MULTISAMPLE); - - arena = arena_alloc(Megabytes(64)); - - Mesh *cube_mesh = mesh_load_obj(arena, "../../data/models/cube.obj"); - color_shader = create_shader_program("shaders/color.vs", - "shaders/color.fs"); - - target_fps = 60.0f; - target_spf = 1.0f/target_fps; - - camera_pos = v3f(0.0f, 0.0f, 3.0f); - camera_speed = 2.0f; - fovx = 90.0f; - near = 0.1f; - far = 1000.0f; - - last_time = glfwGetTime(); - - while (!glfwWindowShouldClose(window)) - { - glfwPollEvents(); - - /* NOTE(pryazha): Update */ - if (key_is_pressed(global_input.exit)) - glfwSetWindowShouldClose(window, GLFW_TRUE); - - V3F camera_dv = get_dv_camera_orbital(&global_input, camera_pos, - v3f_zero(), dt, camera_speed); - camera_pos = v3f_add(camera_pos, camera_dv); - - projection = perspective(fovx, (F32)global_width/(F32)global_height, near, far); - view = look_at(camera_pos, v3f_zero(), v3f(0.0f, 1.0f, 0.0f)); - model = mat4_identity(); - - input_update_last_state(&global_input); - - /* NOTE(pryazha): Render */ - glClearColor(0.15f, 0.15f, 0.15f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glUseProgram(color_shader); - shader_set_mat4fv(color_shader, "projection", projection); - shader_set_mat4fv(color_shader, "view", view); - shader_set_mat4fv(color_shader, "model", model); - mesh_draw(cube_mesh); - - 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(); - dt = current_time-last_time; - last_time = current_time; - } - - arena_release(arena); - glfwTerminate(); - return(0); + glfwMakeContextCurrent(window); + + glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); + + if (glewInit() != GLEW_OK) { + fprintf(stderr, "[ERROR] Failed to initialize glew.\n"); + glfwTerminate(); + return(1); + } + + glEnable(GL_DEPTH_TEST); + glEnable(GL_MULTISAMPLE); + + 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"); + + state.camera = (Camera) { + v3f(0.0f, 0.0f, 3.0f), + 90.0f, 0.1f, 1000.0f, + 0.0f, 0.0f + }; + input = input_init(); + + target_fps = 60.0f; + target_spf = 1.0f/target_fps; + last_time = glfwGetTime(); + + while (!glfwWindowShouldClose(window)) { + glfwPollEvents(); + + /* NOTE(pryazha): Update */ + 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); + + V3F dv = get_dv_camera_first_person(&input, &state.camera, + 4.0f, state.dt); + state.camera.pos = v3f_add(state.camera.pos, dv); + + 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); + + view = get_view_matrix(&state.camera); + proj = perspective(state.camera.fovx, (F32)width/(F32)height, + state.camera.near, state.camera.far); + model = mat4_identity(); + + /* NOTE(pryazha): Render */ + glClearColor(0.15f, 0.15f, 0.15f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glUseProgram(color_shader); + shader_set_mat4fv(color_shader, "proj", proj); + shader_set_mat4fv(color_shader, "view", view); + shader_set_mat4fv(color_shader, "model", model); + mesh_draw(cube); + + 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; + } + + arena_release(arena); + glfwTerminate(); + return(0); } diff --git a/advanced_opengl/10.antialiasing/anti_aliasing_offscreen b/advanced_opengl/10.antialiasing/anti_aliasing_offscreen Binary files differindex c8a241c..db7f6ec 100755 --- a/advanced_opengl/10.antialiasing/anti_aliasing_offscreen +++ b/advanced_opengl/10.antialiasing/anti_aliasing_offscreen diff --git a/advanced_opengl/10.antialiasing/anti_aliasing_offscreen.c b/advanced_opengl/10.antialiasing/anti_aliasing_offscreen.c index 5c6debb..31f3cae 100644 --- a/advanced_opengl/10.antialiasing/anti_aliasing_offscreen.c +++ b/advanced_opengl/10.antialiasing/anti_aliasing_offscreen.c @@ -2,275 +2,200 @@ #include "GLFW/glfw3.h" #include "pwyazh.h" - #include "pwyazh_GL.h" #include "common.h" -#include <unistd.h> +int main(void) +{ + GLFWwindow *window; + Arena *arena = 0; + Mesh *cube; + F32 target_fps, target_spf, last_time; + MAT4 proj, view, model; + U32 fbo, intermediate_fbo, color_tex, + screen_texture, rbo, + quad_vao, vbo, color_shader, + screen_shader; + S32 width, height; + State state; + Input input; -#define WIDTH 1024 -#define HEIGHT 768 -static Input global_input; + if (glfwInit() == GLFW_FALSE) { + fprintf(stderr, "[ERROR] Failed to initialize glfw.\n"); + return(1); + } -void -key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) -{ - switch (action) - { - case GLFW_PRESS: { - switch (key) - { - case GLFW_KEY_D: { - global_input.move_right.state = KeyState_PRESS; - } break; - case GLFW_KEY_W: { - global_input.move_forward.state = KeyState_PRESS; - } break; - case GLFW_KEY_A: { - global_input.move_left.state = KeyState_PRESS; - } break; - case GLFW_KEY_S: { - global_input.move_backward.state = KeyState_PRESS; - } break; - case GLFW_KEY_E: { - global_input.move_up.state = KeyState_PRESS; - } break; - case GLFW_KEY_Q: { - global_input.move_down.state = KeyState_PRESS; - } break; - case GLFW_KEY_SPACE: { - global_input.jump.state = KeyState_PRESS; - } break; - case GLFW_KEY_RIGHT: { - global_input.action_right.state = KeyState_PRESS; - } break; - case GLFW_KEY_LEFT: { - global_input.action_left.state = KeyState_PRESS; - } break; - case GLFW_KEY_ESCAPE: { - global_input.exit.state = KeyState_PRESS; - } break; - } - } break; - - case GLFW_RELEASE: { - switch (key) - { - case GLFW_KEY_D: { - global_input.move_right.state = KeyState_RELEASE; - } break; - case GLFW_KEY_W: { - global_input.move_forward.state = KeyState_RELEASE; - } break; - case GLFW_KEY_A: { - global_input.move_left.state = KeyState_RELEASE; - } break; - case GLFW_KEY_S: { - global_input.move_backward.state = KeyState_RELEASE; - } break; - case GLFW_KEY_E: { - global_input.move_up.state = KeyState_RELEASE; - } break; - case GLFW_KEY_Q: { - global_input.move_down.state = KeyState_RELEASE; - } break; - case GLFW_KEY_SPACE: { - global_input.jump.state = KeyState_RELEASE; - } break; - case GLFW_KEY_RIGHT: { - global_input.action_right.state = KeyState_RELEASE; - } break; - case GLFW_KEY_LEFT: { - global_input.action_left.state = KeyState_RELEASE; - } break; - case GLFW_KEY_ESCAPE: { - global_input.exit.state = KeyState_RELEASE; - } break; - } - } break; - } -} + width = 1024; + height = 768; -int -main(void) -{ - GLFWwindow *window; - Arena *arena = 0; - F32 target_fps, target_spf, - last_time, dt; - MAT4 projection, view, model; - V3F camera_pos; - F32 camera_speed, fovx, near, far; - U32 fbo, intermediate_fbo, color_tex, - screen_texture, rbo, - quad_vao, vbo, - color_shader, screen_shader; - - if (glfwInit() == GLFW_FALSE) - { - fprintf(stderr, "[ERROR] Failed to initialize glfw.\n"); - return(1); - } - - glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); - glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); - glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); - window = glfwCreateWindow(WIDTH, HEIGHT, "Anti Aliasing (Off-screen)", 0, 0); - if (!window) - { - fprintf(stderr, "[ERROR] Failed to create window.\n"); - glfwTerminate(); - return(1); - } - - glfwMakeContextCurrent(window); - - glfwSetKeyCallback(window, key_callback); - - if (glewInit() != GLEW_OK) - { - fprintf(stderr, "[ERROR] Failed to initialize glew.\n"); - glfwTerminate(); - return(1); - } - - arena = arena_alloc(Megabytes(64)); - - Mesh *cube_mesh = mesh_load_obj(arena, "../../data/models/cube.obj"); - color_shader = create_shader_program("shaders/color.vs", - "shaders/color.fs"); - screen_shader = create_shader_program("shaders/screen.vs", - "shaders/screen.fs"); - glGenFramebuffers(1, &fbo); - glBindFramebuffer(GL_FRAMEBUFFER, fbo); - glGenTextures(1, &color_tex); - glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, color_tex); - glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGB, - WIDTH, HEIGHT, GL_TRUE); - glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, - GL_TEXTURE_2D_MULTISAMPLE, color_tex, 0); - glGenRenderbuffers(1, &rbo); - glBindRenderbuffer(GL_RENDERBUFFER, rbo); - glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_DEPTH24_STENCIL8, - WIDTH, HEIGHT); - glBindRenderbuffer(GL_RENDERBUFFER, 0); - 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"); - fprintf(stdout, "[INFO]: Multisample fbo complete.\n"); - glBindFramebuffer(GL_FRAMEBUFFER, 0); - - glGenFramebuffers(1, &intermediate_fbo); - glBindFramebuffer(GL_FRAMEBUFFER, intermediate_fbo); - glGenTextures(1, &screen_texture); - glBindTexture(GL_TEXTURE_2D, screen_texture); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, WIDTH, HEIGHT, - 0, GL_RGB, GL_UNSIGNED_BYTE, 0); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, - GL_TEXTURE_2D, screen_texture, 0); - if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) - fprintf(stderr, "[ERROR]: Framebuffer is not complete.\n"); - fprintf(stdout, "[INFO]: Intermediate fbo complete.\n"); - glBindFramebuffer(GL_FRAMEBUFFER, 0); - - 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 - }; - - 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); - - target_fps = 60.0f; - target_spf = 1.0f/target_fps; - - camera_pos = v3f(0.0f, 0.0f, 3.0f); - camera_speed = 2.0f; - fovx = 90.0f; - near = 0.1f; - far = 1000.0f; - - last_time = glfwGetTime(); - - while (!glfwWindowShouldClose(window)) - { - glfwPollEvents(); - - /* NOTE(pryazha): Update */ - if (key_is_pressed(global_input.exit)) - glfwSetWindowShouldClose(window, GLFW_TRUE); - - V3F camera_dv = get_dv_camera_orbital(&global_input, camera_pos, - v3f_zero(), dt, camera_speed); - camera_pos = v3f_add(camera_pos, camera_dv); - - projection = perspective(fovx, (F32)WIDTH/(F32)HEIGHT, near, far); - view = look_at(camera_pos, v3f_zero(), v3f(0.0f, 1.0f, 0.0f)); - model = mat4_identity(); - - input_update_last_state(&global_input); - - /* NOTE(pryazha): Render */ - glBindFramebuffer(GL_FRAMEBUFFER, fbo); - glClearColor(0.15f, 0.15f, 0.15f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glEnable(GL_DEPTH_TEST); - glUseProgram(color_shader); - shader_set_mat4fv(color_shader, "projection", projection); - shader_set_mat4fv(color_shader, "view", view); - shader_set_mat4fv(color_shader, "model", model); - mesh_draw(cube_mesh); - - glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, intermediate_fbo); - /* TODO(pryazha): Update width and height */ - glBlitFramebuffer(0, 0, WIDTH, HEIGHT, - 0, 0, WIDTH, HEIGHT, - GL_COLOR_BUFFER_BIT, GL_NEAREST); - - glBindFramebuffer(GL_FRAMEBUFFER, 0); - glClearColor(1.0f, 1.0f, 1.0f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT); - glUseProgram(screen_shader); - glDisable(GL_DEPTH_TEST); - glBindTexture(GL_TEXTURE_2D, screen_texture); - glBindVertexArray(quad_vao); - glDrawArrays(GL_TRIANGLES, 0, 6); - 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(); - dt = current_time-last_time; - last_time = current_time; - } - - arena_release(arena); - glfwTerminate(); - return(0); + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); + glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); + window = glfwCreateWindow(width, height, "Anti Aliasing (Off-screen)", 0, 0); + if (!window) { + fprintf(stderr, "[ERROR] Failed to create window.\n"); + glfwTerminate(); + return(1); + } + + glfwMakeContextCurrent(window); + + glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); + + if (glewInit() != GLEW_OK) { + fprintf(stderr, "[ERROR] Failed to initialize glew.\n"); + glfwTerminate(); + return(1); + } + + 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"); + glGenFramebuffers(1, &fbo); + glBindFramebuffer(GL_FRAMEBUFFER, fbo); + glGenTextures(1, &color_tex); + glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, color_tex); + glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGB, + width, height, GL_TRUE); + glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, + GL_TEXTURE_2D_MULTISAMPLE, color_tex, 0); + glGenRenderbuffers(1, &rbo); + glBindRenderbuffer(GL_RENDERBUFFER, rbo); + glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_DEPTH24_STENCIL8, + width, height); + glBindRenderbuffer(GL_RENDERBUFFER, 0); + 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"); + fprintf(stdout, "[INFO]: Multisample fbo complete.\n"); + glBindFramebuffer(GL_FRAMEBUFFER, 0); + + glGenFramebuffers(1, &intermediate_fbo); + glBindFramebuffer(GL_FRAMEBUFFER, intermediate_fbo); + glGenTextures(1, &screen_texture); + glBindTexture(GL_TEXTURE_2D, screen_texture); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, + 0, GL_RGB, GL_UNSIGNED_BYTE, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, + GL_TEXTURE_2D, screen_texture, 0); + if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) + fprintf(stderr, "[ERROR]: Framebuffer is not complete.\n"); + fprintf(stdout, "[INFO]: Intermediate fbo complete.\n"); + glBindFramebuffer(GL_FRAMEBUFFER, 0); + + 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 + }; + + 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); + + state.camera = (Camera) { + v3f(0.0f, 0.0f, 3.0f), + 90.0f, 0.1f, 1000.0f, + 0.0f, 0.0f + }; + input = input_init(); + + target_fps = 60.0f; + target_spf = 1.0f/target_fps; + last_time = glfwGetTime(); + + while (!glfwWindowShouldClose(window)) + { + glfwPollEvents(); + + /* NOTE(pryazha): Update */ + 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); + + V3F dv = get_dv_camera_first_person(&input, &state.camera, + 4.0f, state.dt); + state.camera.pos = v3f_add(state.camera.pos, dv); + + 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); + + view = get_view_matrix(&state.camera); + proj = perspective(state.camera.fovx, (F32)width/(F32)height, + state.camera.near, state.camera.far); + model = mat4_identity(); + + /* NOTE(pryazha): Render */ + glBindFramebuffer(GL_FRAMEBUFFER, fbo); + glClearColor(0.15f, 0.15f, 0.15f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glEnable(GL_DEPTH_TEST); + glUseProgram(color_shader); + shader_set_mat4fv(color_shader, "proj", proj); + shader_set_mat4fv(color_shader, "view", view); + shader_set_mat4fv(color_shader, "model", model); + mesh_draw(cube); + + glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, intermediate_fbo); + glBlitFramebuffer(0, 0, width, height, + 0, 0, width, height, + GL_COLOR_BUFFER_BIT, GL_NEAREST); + + glBindFramebuffer(GL_FRAMEBUFFER, 0); + glClearColor(1.0f, 1.0f, 1.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + glUseProgram(screen_shader); + glDisable(GL_DEPTH_TEST); + glBindTexture(GL_TEXTURE_2D, screen_texture); + glBindVertexArray(quad_vao); + glDrawArrays(GL_TRIANGLES, 0, 6); + 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; + } + + arena_release(arena); + glfwTerminate(); + return(0); } diff --git a/advanced_opengl/2.stencil/shaders/outline.fs b/advanced_opengl/10.antialiasing/shaders/color.frag index 542143e..b4a31df 100644 --- a/advanced_opengl/2.stencil/shaders/outline.fs +++ b/advanced_opengl/10.antialiasing/shaders/color.frag @@ -2,8 +2,7 @@ out vec4 frag_color; -void -main(void) +void main(void) { frag_color = vec4(0.76, 0.47, 0.84, 1.0); } diff --git a/advanced_opengl/10.antialiasing/shaders/color.vert b/advanced_opengl/10.antialiasing/shaders/color.vert new file mode 100644 index 0000000..a8b1247 --- /dev/null +++ b/advanced_opengl/10.antialiasing/shaders/color.vert @@ -0,0 +1,11 @@ +#version 330 core +layout(location = 0) in vec3 apos; + +uniform mat4 proj; +uniform mat4 view; +uniform mat4 model; + +void main(void) +{ + gl_Position = proj*view*model*vec4(apos, 1.0); +} diff --git a/advanced_opengl/10.antialiasing/shaders/screen.fs b/advanced_opengl/10.antialiasing/shaders/screen.frag index 183d490..5ccc843 100644 --- a/advanced_opengl/10.antialiasing/shaders/screen.fs +++ b/advanced_opengl/10.antialiasing/shaders/screen.frag @@ -6,15 +6,13 @@ in vec2 tex_coords; uniform sampler2D texture1; -vec4 -inversion() +vec4 inversion() { vec4 result = vec4(1.0-vec3(texture(texture1, tex_coords)), 1.0); return(result); } -vec4 -grayscale_average() +vec4 grayscale_average() { vec4 tex_color = texture(texture1, tex_coords); float average = (tex_color.r+tex_color.g+tex_color.b)/3.0; @@ -22,8 +20,7 @@ grayscale_average() return(result); } -vec4 -grayscale_weights() +vec4 grayscale_weights() { vec4 tex_color = texture(texture1, tex_coords); float average = 0.2126*tex_color.r+0.7152*tex_color.g+0.0722*tex_color.b; @@ -33,8 +30,7 @@ grayscale_weights() const float offset = 1.0/300.0; -vec4 -kernel_effect(float[9] kernel) +vec4 kernel_effect(float[9] kernel) { vec2 offsets[9] = vec2[]( vec2(-offset, offset), /* top-left */ @@ -49,13 +45,8 @@ kernel_effect(float[9] kernel) ); vec3 sample_texture[9]; - for (int offset_index = 0; - offset_index < 9; - ++offset_index) - { - sample_texture[offset_index] = - vec3(texture(texture1, tex_coords+offsets[offset_index])); - } + for (int i = 0; i < 9; ++i) + sample_texture[i] = vec3(texture(texture1, tex_coords+offsets[i])); vec3 color = vec3(0.0); for (int i = 0; i < 9; ++i) diff --git a/advanced_opengl/10.antialiasing/shaders/screen.vs b/advanced_opengl/10.antialiasing/shaders/screen.vert index 1f233ee..e473ddd 100644 --- a/advanced_opengl/10.antialiasing/shaders/screen.vs +++ b/advanced_opengl/10.antialiasing/shaders/screen.vert @@ -4,8 +4,7 @@ layout(location = 1) in vec2 atex_coords; out vec2 tex_coords; -void -main(void) +void main(void) { gl_Position = vec4(apos, 1.0); tex_coords = atex_coords; diff --git a/advanced_opengl/10.antialiasing/shaders/color.fs b/advanced_opengl/2.stencil/shaders/outline.frag index 542143e..b4a31df 100644 --- a/advanced_opengl/10.antialiasing/shaders/color.fs +++ b/advanced_opengl/2.stencil/shaders/outline.frag @@ -2,8 +2,7 @@ out vec4 frag_color; -void -main(void) +void main(void) { frag_color = vec4(0.76, 0.47, 0.84, 1.0); } diff --git a/advanced_opengl/2.stencil/shaders/stencil.fs b/advanced_opengl/2.stencil/shaders/stencil.frag index ff7dd9b..ff7dd9b 100644 --- a/advanced_opengl/2.stencil/shaders/stencil.fs +++ b/advanced_opengl/2.stencil/shaders/stencil.frag diff --git a/advanced_opengl/4.face_culling/shaders/face_culling.vs b/advanced_opengl/2.stencil/shaders/stencil.vert index 62e71a2..68b8fe2 100644 --- a/advanced_opengl/4.face_culling/shaders/face_culling.vs +++ b/advanced_opengl/2.stencil/shaders/stencil.vert @@ -4,13 +4,12 @@ layout(location = 1) in vec2 atex_coords; uniform mat4 model; uniform mat4 view; -uniform mat4 projection; +uniform mat4 proj; out vec2 tex_coords; -void -main(void) +void main(void) { - gl_Position = projection*view*model*vec4(apos, 1.0); + gl_Position = proj*view*model*vec4(apos, 1.0); tex_coords = atex_coords; } diff --git a/advanced_opengl/2.stencil/stencil b/advanced_opengl/2.stencil/stencil Binary files differindex eb4eac5..a20d0bb 100755 --- a/advanced_opengl/2.stencil/stencil +++ b/advanced_opengl/2.stencil/stencil diff --git a/advanced_opengl/2.stencil/stencil.c b/advanced_opengl/2.stencil/stencil.c index 9f45048..3b01f5b 100644 --- a/advanced_opengl/2.stencil/stencil.c +++ b/advanced_opengl/2.stencil/stencil.c @@ -2,298 +2,212 @@ #include "GLFW/glfw3.h" #include "pwyazh.h" - #include "pwyazh_GL.h" #include "common.h" -#include <unistd.h> +int main(void) +{ + GLFWwindow *window; + State state; + S32 width, height; + Input input; -#define WIDTH 1280 -#define HEIGHT 720 + if (glfwInit() == GLFW_FALSE) { + fprintf(stderr, "[ERROR] Failed to initialize glfw.\n"); + return(1); + } -static V3F camera_pos; -static F32 dt; -static Input input; + width = 1024; + height = 768; -void -key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) -{ - switch (action) - { - case GLFW_PRESS: { - switch (key) - { - case GLFW_KEY_D: { - input.move_right.state = KeyState_PRESS; - } break; - case GLFW_KEY_W: { - input.move_forward.state = KeyState_PRESS; - } break; - case GLFW_KEY_A: { - input.move_left.state = KeyState_PRESS; - } break; - case GLFW_KEY_S: { - input.move_backward.state = KeyState_PRESS; - } break; - case GLFW_KEY_E: { - input.move_up.state = KeyState_PRESS; - } break; - case GLFW_KEY_Q: { - input.move_down.state = KeyState_PRESS; - } break; - } - } break; - - case GLFW_RELEASE: { - switch (key) - { - case GLFW_KEY_D: { - input.move_right.state = KeyState_RELEASE; - } break; - case GLFW_KEY_W: { - input.move_forward.state = KeyState_RELEASE; - } break; - case GLFW_KEY_A: { - input.move_left.state = KeyState_RELEASE; - } break; - case GLFW_KEY_S: { - input.move_backward.state = KeyState_RELEASE; - } break; - case GLFW_KEY_E: { - input.move_up.state = KeyState_RELEASE; - } break; - case GLFW_KEY_Q: { - input.move_down.state = KeyState_RELEASE; - } break; - } - } break; - } -} + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); + glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); + window = glfwCreateWindow(width, height, "Stencil testing", 0, 0); + if (!window) { + fprintf(stderr, "[ERROR] Failed to create window.\n"); + glfwTerminate(); + return(1); + } -int -main(void) -{ - GLFWwindow *window; - - if (glfwInit() == GLFW_FALSE) - { - fprintf(stderr, "[ERROR] Failed to initialize glfw.\n"); - return(1); - } - - glfwWindowHint(GLFW_RESIZABLE, 0); - glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); - glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); - window = glfwCreateWindow(WIDTH, HEIGHT, "Stencil testing", 0, 0); - if (!window) - { - fprintf(stderr, "[ERROR] Failed to create window.\n"); - glfwTerminate(); - return(1); - } - - glfwMakeContextCurrent(window); - - glfwSetKeyCallback(window, key_callback); - - if (glewInit() != GLEW_OK) - { - fprintf(stderr, "[ERROR] Failed to initialize glew.\n"); - glfwTerminate(); - return(1); - } - - glEnable(GL_DEPTH_TEST); - - glEnable(GL_STENCIL_TEST); - glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); - - U32 shader = create_shader_program("shaders/stencil.vs", "shaders/stencil.fs"); - U32 outline_shader = create_shader_program("shaders/stencil.vs", "shaders/outline.fs"); - 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)) - }; - - Transform platform_position = - transform_make_scale_translate(v3f(10.0f, 0.2f, 10.0f), - v3f(0.0f, -(a+(a*0.2f)+0.01f), 0.0f)); - - 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); - - F32 target_fps = 60.0f; - F32 target_spf = 1.0f/target_fps; - camera_pos = v3f(0.0f, 0.0f, 3.0f); - - /* glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); */ - - F32 last_time = glfwGetTime(); - - while (!glfwWindowShouldClose(window)) - { - glfwPollEvents(); - - /* INFO(pryazha): update */ - V3F left, up, forward; - V3F world_up = v3f(0.0f, 1.0f, 0.0f); - - forward = v3f_norm(v3f_sub(v3f(0.0f, 0.0f, 0.0f), camera_pos)); - left = v3f_norm(v3f_cross(world_up, forward)); - up = v3f_cross(forward, left); - - V3F dp = v3f_zero(); - - F32 speed = 2.0f; - if (key_is_pressed(input.move_right)) - dp = v3f_add(dp, v3f_scalef(left, -speed*dt)); - if (key_is_pressed(input.move_forward)) - dp = v3f_add(dp, v3f_scalef(forward, speed*dt)); - if (key_is_pressed(input.move_left)) - dp = v3f_add(dp, v3f_scalef(left, speed*dt)); - if (key_is_pressed(input.move_backward)) - dp = v3f_add(dp, v3f_scalef(forward, -speed*dt)); - if (key_is_pressed(input.move_up)) - dp = v3f_add(dp, v3f_scalef(up, speed*dt)); - if (key_is_pressed(input.move_down)) - dp = v3f_add(dp, v3f_scalef(up, -speed*dt)); - input_update_last_state(&input); - - camera_pos = v3f_add(camera_pos, dp); - - /* INFO(pryazha): Render */ - glClearColor(0.15f, 0.15f, 0.15f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); - - /* NOTE(pryazha): Update stencil buffer with ones while drawing the cubes */ - glStencilFunc(GL_ALWAYS, 1, 0xFF); - glStencilMask(0xFF); - - MAT4 model, view, projection; - view = look_at(camera_pos, v3f(0.0f, 0.0f, 0.0f), v3f(0.0f, 1.0f, 0.0f)); - projection = perspective(90.0f, (F32)WIDTH/(F32)HEIGHT, 0.1f, 100.0f); - - glUseProgram(shader); - shader_set_mat4fv(shader, "view", view); - shader_set_mat4fv(shader, "projection", projection); - - glBindTexture(GL_TEXTURE_2D, marble_texture); - glBindVertexArray(VAO); - for (S32 transform_index = 0; - transform_index < (S32)ArrayCount(cube_positions); - ++transform_index) - { - model = transform_apply(cube_positions[transform_index]); - shader_set_mat4fv(shader, "model", model); - glDrawArrays(GL_TRIANGLES, 0, 36); - } - - /* NOTE(pryazha): Don't update stencil buffer while drawing the floor */ - glStencilMask(0x00); - - glBindTexture(GL_TEXTURE_2D, metal_texture); - model = transform_apply(platform_position); - shader_set_mat4fv(shader, "model", model); - glDrawArrays(GL_TRIANGLES, 0, 36); - - glStencilFunc(GL_NOTEQUAL, 1, 0xFF); - glStencilMask(0x00); - glDisable(GL_DEPTH_TEST); - - glUseProgram(outline_shader); - shader_set_mat4fv(outline_shader, "view", view); - shader_set_mat4fv(outline_shader, "projection", projection); - - for (S32 transform_index = 0; - transform_index < (S32)ArrayCount(cube_positions); - ++transform_index) - { - Transform transform = cube_positions[transform_index]; - transform = transform_scale(transform, v3f(1.1f, 1.1f, 1.1f)); - shader_set_mat4fv(outline_shader, "model", transform_apply(transform)); - glDrawArrays(GL_TRIANGLES, 0, 36); - } - - glStencilMask(0xFF); - glStencilFunc(GL_ALWAYS, 1, 0xFF); - glEnable(GL_DEPTH_TEST); - - 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(); - dt = current_time-last_time; - last_time = current_time; - } - - glfwTerminate(); - return(0); + glfwMakeContextCurrent(window); + + if (glewInit() != GLEW_OK) { + fprintf(stderr, "[ERROR] Failed to initialize glew.\n"); + glfwTerminate(); + return(1); + } + + glEnable(GL_DEPTH_TEST); + 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 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 = 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 | GL_STENCIL_BUFFER_BIT); + + /* NOTE(pryazha): Update stencil buffer with ones while drawing the cubes */ + glStencilFunc(GL_ALWAYS, 1, 0xFF); + glStencilMask(0xFF); + + 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); + } + + /* NOTE(pryazha): Don't update stencil buffer while drawing the floor */ + glStencilMask(0x00); + + glBindTexture(GL_TEXTURE_2D, metal_texture); + model = transform_apply(platform_transform); + shader_set_mat4fv(shader, "model", model); + glDrawArrays(GL_TRIANGLES, 0, 36); + + glStencilFunc(GL_NOTEQUAL, 1, 0xFF); + glStencilMask(0x00); + glDisable(GL_DEPTH_TEST); + + glUseProgram(outline_shader); + shader_set_mat4fv(outline_shader, "view", view); + shader_set_mat4fv(outline_shader, "proj", proj); + for (S32 i = 0; i < (S32)ArrayCount(cube_positions); ++i) { + Transform transform = cube_positions[i]; + transform = transform_scale(transform, v3f(1.1f, 1.1f, 1.1f)); + model = transform_apply(transform); + shader_set_mat4fv(outline_shader, "model", model); + glDrawArrays(GL_TRIANGLES, 0, 36); + } + + glStencilMask(0xFF); + glStencilFunc(GL_ALWAYS, 1, 0xFF); + glEnable(GL_DEPTH_TEST); + + 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/3.blending/blending b/advanced_opengl/3.blending/blending Binary files differindex 40fe12a..c7a5ea0 100755 --- a/advanced_opengl/3.blending/blending +++ b/advanced_opengl/3.blending/blending diff --git a/advanced_opengl/3.blending/blending.c b/advanced_opengl/3.blending/blending.c index 9ac92ea..8142ab3 100644 --- a/advanced_opengl/3.blending/blending.c +++ b/advanced_opengl/3.blending/blending.c @@ -2,372 +2,277 @@ #include "GLFW/glfw3.h" #include "pwyazh.h" - #include "pwyazh_GL.h" #include "common.h" -#include <unistd.h> +int main(void) +{ + GLFWwindow *window; + State state; + S32 width, height; + Input input; -#define WIDTH 1280 -#define HEIGHT 720 + if (glfwInit() == GLFW_FALSE) { + fprintf(stderr, "[ERROR] Failed to initialize glfw.\n"); + return(1); + } -static V3F camera_pos; -static F32 dt; -static Input input; + width = 1024; + height = 768; -void -key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) -{ - switch (action) - { - case GLFW_PRESS: { - switch (key) - { - case GLFW_KEY_D: { - input.move_right.state = KeyState_PRESS; - } break; - case GLFW_KEY_W: { - input.move_forward.state = KeyState_PRESS; - } break; - case GLFW_KEY_A: { - input.move_left.state = KeyState_PRESS; - } break; - case GLFW_KEY_S: { - input.move_backward.state = KeyState_PRESS; - } break; - case GLFW_KEY_E: { - input.move_up.state = KeyState_PRESS; - } break; - case GLFW_KEY_Q: { - input.move_down.state = KeyState_PRESS; - } break; - } - } break; - - case GLFW_RELEASE: { - switch (key) - { - case GLFW_KEY_D: { - input.move_right.state = KeyState_RELEASE; - } break; - case GLFW_KEY_W: { - input.move_forward.state = KeyState_RELEASE; - } break; - case GLFW_KEY_A: { - input.move_left.state = KeyState_RELEASE; - } break; - case GLFW_KEY_S: { - input.move_backward.state = KeyState_RELEASE; - } break; - case GLFW_KEY_E: { - input.move_up.state = KeyState_RELEASE; - } break; - case GLFW_KEY_Q: { - input.move_down.state = KeyState_RELEASE; - } break; - } - } break; - } -} + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); + glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); + window = glfwCreateWindow(width, height, "Stencil testing", 0, 0); + if (!window) { + fprintf(stderr, "[ERROR] Failed to create window.\n"); + glfwTerminate(); + return(1); + } -int -main(void) -{ - GLFWwindow *window; - - if (glfwInit() == GLFW_FALSE) - { - fprintf(stderr, "[ERROR] Failed to initialize glfw.\n"); - return(1); - } - - glfwWindowHint(GLFW_RESIZABLE, 0); - glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); - glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); - window = glfwCreateWindow(WIDTH, HEIGHT, "Blending", 0, 0); - if (!window) - { - fprintf(stderr, "[ERROR] Failed to create window.\n"); - glfwTerminate(); - return(1); - } - - glfwMakeContextCurrent(window); - - glfwSetKeyCallback(window, key_callback); - - if (glewInit() != GLEW_OK) - { - fprintf(stderr, "[ERROR] Failed to initialize glew.\n"); - glfwTerminate(); - return(1); - } - - glEnable(GL_DEPTH_TEST); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - U32 shader = create_shader_program("shaders/blending.vs", "shaders/blending.fs"); - U32 grass_shader = create_shader_program("shaders/blending.vs", "shaders/grass.fs"); - 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"); - U32 window_texture = load_texture("../../data/textures/window.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.0f*a)) - }; - - Transform platform_position = - transform_make_scale_translate(v3f(10.0f, 0.2f, 10.0f), - v3f(0.0f, -(a+(a*0.2f)+0.01f), 0.0f)); - - U32 cube_vao, quad_vao, vbo; - - glGenVertexArrays(1, &cube_vao); - glBindVertexArray(cube_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); - - F32 quad_side = 1.0f; - F32 quad_vertices[] = { - /* NOTE(pryazha): left top triangle */ - -quad_side/2.0f, 0.0f, 0.0f, 0.0f, 0.0f, - -quad_side/2.0f, quad_side, 0.0f, 0.0f, 1.0f, - quad_side/2.0f, quad_side, 0.0f, 1.0f, 1.0f, - - /* NOTE(pryazha): right bottom triangle */ - -quad_side/2.0f, 0.0f, 0.0f, 0.0f, 0.0f, - quad_side/2.0f, quad_side, 0.0f, 1.0f, 1.0f, - quad_side/2.0f, 0.0f, 0.0f, 1.0f, 0.0f - }; - - 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); - - Transform grass_positions[] = { - transform_make_scale_translate(v3f(0.5f, 0.5f, 0.5f), v3f(1.0f, -0.5f, 0.0f)), - transform_make_scale_translate(v3f(0.5f, 0.5f, 0.5f), v3f(-1.5f, -0.5f, 2.0f)), - transform_make_scale_translate(v3f(0.5f, 0.5f, 0.5f), v3f(0.0f, -0.5f, -1.0f)), - transform_make_scale_translate(v3f(0.5f, 0.5f, 0.5f), v3f(3.0f, -0.5f, 1.0f)), - transform_make_scale_translate(v3f(0.5f, 0.5f, 0.5f), v3f(-2.0f, -0.5f, -3.0f)) - }; - - Transform window_transforms[] = { - transform_make_translate(v3f(0.0f, -0.5f, a+0.1f)), - transform_make_translate(v3f(0.0f, -0.5f, 2.0f)), - transform_make_translate(v3f(1.0f, -0.5f, -1.0f)), - transform_make_translate(v3f(-2.0f, -0.5f, 0.5f)), - transform_make_translate(v3f(-3.0f, -0.5f, -3.0f)), - transform_make_translate(v3f(3.0f, -0.5f, 0.2)), - }; - - F32 angle = 0.0f; - for (S32 window_index = 0; - window_index < (S32)ArrayCount(window_transforms); - ++window_index) - { - Transform *transform = window_transforms+window_index; - *transform = transform_rotate(*transform, v3f(0.0f, angle, 0.0f)); - angle += 30.0f; - } - - F32 target_fps = 60.0f; - F32 target_spf = 1.0f/target_fps; - camera_pos = v3f(0.0f, 0.0f, 3.0f); - - /* glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); */ - - F32 last_time = glfwGetTime(); - - while (!glfwWindowShouldClose(window)) - { - glfwPollEvents(); - - /* INFO(pryazha): update */ - V3F left, up, forward; - V3F world_up = v3f(0.0f, 1.0f, 0.0f); - - forward = v3f_norm(v3f_sub(v3f(0.0f, 0.0f, 0.0f), camera_pos)); - left = v3f_norm(v3f_cross(world_up, forward)); - up = v3f_cross(forward, left); - - V3F dp = v3f_zero(); - - F32 speed = 2.0f; - if (key_is_pressed(input.move_right)) - dp = v3f_add(dp, v3f_scalef(left, -speed*dt)); - if (key_is_pressed(input.move_forward)) - dp = v3f_add(dp, v3f_scalef(forward, speed*dt)); - if (key_is_pressed(input.move_left)) - dp = v3f_add(dp, v3f_scalef(left, speed*dt)); - if (key_is_pressed(input.move_backward)) - dp = v3f_add(dp, v3f_scalef(forward, -speed*dt)); - if (key_is_pressed(input.move_up)) - dp = v3f_add(dp, v3f_scalef(up, speed*dt)); - if (key_is_pressed(input.move_down)) - dp = v3f_add(dp, v3f_scalef(up, -speed*dt)); - - input_update_last_state(&input); - - camera_pos = v3f_add(camera_pos, dp); - - Transform sorted_window_transforms[ArrayCount(window_transforms)]; - MemoryCopyArray(sorted_window_transforms, window_transforms); - for (S32 i = 0; i < (S32)ArrayCount(sorted_window_transforms); ++i) { - for (S32 pos_index = 1; - pos_index < (S32)ArrayCount(sorted_window_transforms); - ++pos_index) - { - F32 distance_left = v3f_length(v3f_sub(sorted_window_transforms[pos_index-1].translate, camera_pos)); - F32 distance_right = v3f_length(v3f_sub(sorted_window_transforms[pos_index].translate, camera_pos)); - if (distance_left < distance_right) { - Transform temp = sorted_window_transforms[pos_index]; - sorted_window_transforms[pos_index] = sorted_window_transforms[pos_index-1]; - sorted_window_transforms[pos_index-1] = temp; - } - } - } - - /* INFO(pryazha): Render */ - glClearColor(0.15f, 0.15f, 0.15f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - MAT4 model, view, projection; - view = look_at(camera_pos, v3f(0.0f, 0.0f, 0.0f), v3f(0.0f, 1.0f, 0.0f)); - projection = perspective(90.0f, (F32)WIDTH/(F32)HEIGHT, 0.1f, 100.0f); - - glUseProgram(shader); - shader_set_mat4fv(shader, "view", view); - shader_set_mat4fv(shader, "projection", projection); - - glBindTexture(GL_TEXTURE_2D, marble_texture); - glBindVertexArray(cube_vao); - for (S32 transform_index = 0; - transform_index < (S32)ArrayCount(cube_positions); - ++transform_index) - { - model = transform_apply(cube_positions[transform_index]); - shader_set_mat4fv(shader, "model", model); - glDrawArrays(GL_TRIANGLES, 0, 36); - } - - glBindTexture(GL_TEXTURE_2D, metal_texture); - model = transform_apply(platform_position); - shader_set_mat4fv(shader, "model", model); - glDrawArrays(GL_TRIANGLES, 0, 36); - - glUseProgram(grass_shader); - glBindTexture(GL_TEXTURE_2D, grass_texture); - shader_set_mat4fv(shader, "view", view); - shader_set_mat4fv(shader, "projection", projection); - glBindVertexArray(quad_vao); - - F32 angle = 0.0f; - for (S32 transform_index = 0; - transform_index < (S32)ArrayCount(grass_positions); - ++transform_index) - { - Transform *transform = grass_positions+transform_index; - Transform new_transform = transform_rotate(*transform, v3f(0.0f, angle, 0.0f)); - shader_set_mat4fv(shader, "model", transform_apply(new_transform)); - glDrawArrays(GL_TRIANGLES, 0, 6); - angle += 30.0f; - } - - glUseProgram(shader); - glBindTexture(GL_TEXTURE_2D, window_texture); - shader_set_mat4fv(shader, "view", view); - shader_set_mat4fv(shader, "projection", projection); - for (S32 window_index = 0; - window_index < (S32)ArrayCount(sorted_window_transforms); - ++window_index) - { - MAT4 model = transform_apply(sorted_window_transforms[window_index]); - shader_set_mat4fv(shader, "model", model); - glDrawArrays(GL_TRIANGLES, 0, 6); - } - - 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(); - dt = current_time-last_time; - last_time = current_time; - } - - glfwTerminate(); - return(0); + glfwMakeContextCurrent(window); + + if (glewInit() != GLEW_OK) { + fprintf(stderr, "[ERROR] Failed to initialize glew.\n"); + glfwTerminate(); + return(1); + } + + glEnable(GL_DEPTH_TEST); + 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 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"); + U32 window_texture = load_texture("../../data/textures/window.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.0f*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 cube_vao, quad_vao, vbo; + glGenVertexArrays(1, &cube_vao); + glBindVertexArray(cube_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); + + F32 quad_side = 1.0f; + F32 quad_vertices[] = { + /* NOTE(pryazha): left top triangle */ + -quad_side/2.0f, 0.0f, 0.0f, 0.0f, 0.0f, + -quad_side/2.0f, quad_side, 0.0f, 0.0f, 1.0f, + quad_side/2.0f, quad_side, 0.0f, 1.0f, 1.0f, + + /* NOTE(pryazha): right bottom triangle */ + -quad_side/2.0f, 0.0f, 0.0f, 0.0f, 0.0f, + quad_side/2.0f, quad_side, 0.0f, 1.0f, 1.0f, + quad_side/2.0f, 0.0f, 0.0f, 1.0f, 0.0f + }; + + 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); + + Transform grass_positions[] = { + transform_make_scale_translate(v3f(0.5f, 0.5f, 0.5f), v3f(1.0f, -0.5f, 0.0f)), + transform_make_scale_translate(v3f(0.5f, 0.5f, 0.5f), v3f(-1.5f, -0.5f, 2.0f)), + transform_make_scale_translate(v3f(0.5f, 0.5f, 0.5f), v3f(0.0f, -0.5f, -1.0f)), + transform_make_scale_translate(v3f(0.5f, 0.5f, 0.5f), v3f(3.0f, -0.5f, 1.0f)), + transform_make_scale_translate(v3f(0.5f, 0.5f, 0.5f), v3f(-2.0f, -0.5f, -3.0f)) + }; + + Transform window_transforms[] = { + transform_make_translate(v3f(0.0f, -0.5f, a+0.1f)), + transform_make_translate(v3f(0.0f, -0.5f, 2.0f)), + transform_make_translate(v3f(1.0f, -0.5f, -1.0f)), + transform_make_translate(v3f(-2.0f, -0.5f, 0.5f)), + transform_make_translate(v3f(-3.0f, -0.5f, -3.0f)), + transform_make_translate(v3f(3.0f, -0.5f, 0.2)), + }; + + F32 angle = 0.0f; + for (S32 i = 0; i < (S32)ArrayCount(window_transforms); ++i) { + Transform *transform = window_transforms+i; + *transform = transform_rotate(*transform, v3f(0.0f, angle, 0.0f)); + angle += 30.0f; + } + + 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); + + Transform sorted[ArrayCount(window_transforms)]; + MemoryCopyArray(sorted, window_transforms); + for (S32 i = 0; i < (S32)ArrayCount(sorted); ++i) { + for (S32 j = 1; j < (S32)ArrayCount(sorted); ++j) { + F32 dist_left = v3f_length(v3f_sub(sorted[j-1].translate, state.camera.pos)); + F32 dist_right = v3f_length(v3f_sub(sorted[j].translate, state.camera.pos)); + if (dist_left < dist_right) { + Transform temp = sorted[j]; + sorted[j] = sorted[j-1]; + sorted[j-1] = temp; + } + } + } + + /* INFO(pryazha): Render */ + MAT4 model, view, proj; + view = look_at(state.camera.pos, target, v3f(0.0f, 1.0f, 0.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(cube_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); + + glUseProgram(grass_shader); + glBindTexture(GL_TEXTURE_2D, grass_texture); + shader_set_mat4fv(shader, "view", view); + shader_set_mat4fv(shader, "proj", proj); + glBindVertexArray(quad_vao); + F32 angle = 0.0f; + for (S32 i = 0; i < (S32)ArrayCount(grass_positions); ++i) { + Transform *transform = grass_positions+i; + Transform new_transform = transform_rotate(*transform, v3f(0.0f, angle, 0.0f)); + model = transform_apply(new_transform); + shader_set_mat4fv(shader, "model", model); + glDrawArrays(GL_TRIANGLES, 0, 6); + angle += 30.0f; + } + + glUseProgram(shader); + glBindTexture(GL_TEXTURE_2D, window_texture); + shader_set_mat4fv(shader, "view", view); + shader_set_mat4fv(shader, "proj", proj); + for (S32 i = 0; i < (S32)ArrayCount(sorted); ++i) { + MAT4 model = transform_apply(sorted[i]); + shader_set_mat4fv(shader, "model", model); + glDrawArrays(GL_TRIANGLES, 0, 6); + } + 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/6.cubemaps/shaders/cube.fs b/advanced_opengl/3.blending/shaders/blending.frag index f58c5d3..71892a7 100644 --- a/advanced_opengl/6.cubemaps/shaders/cube.fs +++ b/advanced_opengl/3.blending/shaders/blending.frag @@ -6,8 +6,7 @@ in vec2 tex_coords; uniform sampler2D texture1; -void -main(void) +void main(void) { frag_color = texture(texture1, tex_coords); } diff --git a/advanced_opengl/3.blending/shaders/blending.vs b/advanced_opengl/3.blending/shaders/blending.vert index 62e71a2..68b8fe2 100644 --- a/advanced_opengl/3.blending/shaders/blending.vs +++ b/advanced_opengl/3.blending/shaders/blending.vert @@ -4,13 +4,12 @@ layout(location = 1) in vec2 atex_coords; uniform mat4 model; uniform mat4 view; -uniform mat4 projection; +uniform mat4 proj; out vec2 tex_coords; -void -main(void) +void main(void) { - gl_Position = projection*view*model*vec4(apos, 1.0); + gl_Position = proj*view*model*vec4(apos, 1.0); tex_coords = atex_coords; } diff --git a/advanced_opengl/3.blending/shaders/grass.fs b/advanced_opengl/3.blending/shaders/grass.frag index cecb0ce..85c806f 100644 --- a/advanced_opengl/3.blending/shaders/grass.fs +++ b/advanced_opengl/3.blending/shaders/grass.frag @@ -6,12 +6,10 @@ in vec2 tex_coords; uniform sampler2D texture1; -void -main(void) +void main(void) { vec4 tex_color = texture(texture1, tex_coords); - if (tex_color.a <= 0.2) { + if (tex_color.a <= 0.2) discard; - } frag_color = tex_color; } diff --git a/advanced_opengl/4.face_culling/face_culling b/advanced_opengl/4.face_culling/face_culling Binary files differindex eb6e3e9..c00eeaa 100755 --- a/advanced_opengl/4.face_culling/face_culling +++ b/advanced_opengl/4.face_culling/face_culling diff --git a/advanced_opengl/4.face_culling/face_culling.c b/advanced_opengl/4.face_culling/face_culling.c index 9769b53..c3a31c0 100644 --- a/advanced_opengl/4.face_culling/face_culling.c +++ b/advanced_opengl/4.face_culling/face_culling.c @@ -2,305 +2,234 @@ #include "GLFW/glfw3.h" #include "pwyazh.h" - #include "pwyazh_GL.h" #include "common.h" -#include <unistd.h> +int main(void) +{ + GLFWwindow *window; + State state; + S32 width, height; + Input input; -#define WIDTH 1280 -#define HEIGHT 720 + if (glfwInit() == GLFW_FALSE) { + fprintf(stderr, "[ERROR] Failed to initialize glfw.\n"); + return(1); + } -static V3F camera_pos; -static F32 dt; -static Input input; + width = 1024; + height = 768; -void -key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) -{ - switch (action) - { - case GLFW_PRESS: { - switch (key) - { - case GLFW_KEY_D: { - input.move_right.state = KeyState_PRESS; - } break; - case GLFW_KEY_W: { - input.move_forward.state = KeyState_PRESS; - } break; - case GLFW_KEY_A: { - input.move_left.state = KeyState_PRESS; - } break; - case GLFW_KEY_S: { - input.move_backward.state = KeyState_PRESS; - } break; - case GLFW_KEY_E: { - input.move_up.state = KeyState_PRESS; - } break; - case GLFW_KEY_Q: { - input.move_down.state = KeyState_PRESS; - } break; - } - } break; - - case GLFW_RELEASE: { - switch (key) - { - case GLFW_KEY_D: { - input.move_right.state = KeyState_RELEASE; - } break; - case GLFW_KEY_W: { - input.move_forward.state = KeyState_RELEASE; - } break; - case GLFW_KEY_A: { - input.move_left.state = KeyState_RELEASE; - } break; - case GLFW_KEY_S: { - input.move_backward.state = KeyState_RELEASE; - } break; - case GLFW_KEY_E: { - input.move_up.state = KeyState_RELEASE; - } break; - case GLFW_KEY_Q: { - input.move_down.state = KeyState_RELEASE; - } break; - } - } break; - } -} + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); + glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); + window = glfwCreateWindow(width, height, "Face culling", 0, 0); + if (!window) { + fprintf(stderr, "[ERROR] Failed to create window.\n"); + glfwTerminate(); + return(1); + } -int -main(void) -{ - GLFWwindow *window; - - if (glfwInit() == GLFW_FALSE) - { - fprintf(stderr, "[ERROR] Failed to initialize glfw.\n"); - return(1); - } - - glfwWindowHint(GLFW_RESIZABLE, 0); - glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); - glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); - window = glfwCreateWindow(WIDTH, HEIGHT, "Face culling", 0, 0); - if (!window) - { - fprintf(stderr, "[ERROR] Failed to create window.\n"); - glfwTerminate(); - return(1); - } - - glfwMakeContextCurrent(window); - - glfwSetKeyCallback(window, key_callback); - - if (glewInit() != GLEW_OK) - { - fprintf(stderr, "[ERROR] Failed to initialize glew.\n"); - glfwTerminate(); - return(1); - } - - glEnable(GL_DEPTH_TEST); - glEnable(GL_CULL_FACE); - glFrontFace(GL_CW); - glCullFace(GL_BACK); - - U32 shader = create_shader_program("shaders/face_culling.vs", "shaders/face_culling.fs"); - - U32 grid_texture = load_texture("../../data/textures/grid.png"); - - F32 a = 0.5f; - /* NOTE(pryazha): Counter-clockwise order */ - F32 cube_vertices_ccw[] = { - /* NOTE(pryazha): Back face */ - a, -a, -a, 0.0f, 0.0f, /* bottom-left */ - -a, a, -a, 1.0f, 1.0f, /* top-right */ - a, a, -a, 0.0f, 1.0f, /* top-left */ - a, -a, -a, 0.0f, 0.0f, /* bottom-left */ - -a, -a, -a, 1.0f, 0.0f, /* bottom-right */ - -a, a, -a, 1.0f, 1.0f, /* top-right */ - - /* NOTE(pryazha): Front face */ - -a, -a, a, 0.0f, 0.0f, /* bottom-left */ - a, a, a, 1.0f, 1.0f, /* top-right */ - -a, a, a, 0.0f, 1.0f, /* top-left */ - -a, -a, a, 0.0f, 0.0f, /* bottom-left */ - a, -a, a, 1.0f, 0.0f, /* bottom-right */ - a, a, a, 1.0f, 1.0f, /* top-right */ - - /* NOTE(pryazha): Left face */ - -a, -a, -a, 0.0f, 0.0f, /* bottom-left */ - -a, a, a, 1.0f, 1.0f, /* top-right */ - -a, a, -a, 0.0f, 1.0f, /* top-left */ - -a, -a, -a, 0.0f, 0.0f, /* bottom-left */ - -a, -a, a, 1.0f, 0.0f, /* bottom-right */ - -a, a, a, 1.0f, 1.0f, /* top-right */ - - /* NOTE(pryazha): Right face */ - a, -a, a, 0.0f, 0.0f, /* bottom-left */ - a, a, -a, 1.0f, 1.0f, /* top-right */ - a, a, a, 0.0f, 1.0f, /* top-left */ - a, -a, a, 0.0f, 0.0f, /* bottom-left */ - a, -a, -a, 1.0f, 0.0f, /* bottom-right */ - a, a, -a, 1.0f, 1.0f, /* top-right */ - - /* NOTE(pryazha): Top face */ - -a, a, a, 0.0f, 0.0f, /* bottom-left */ - a, a, -a, 1.0f, 1.0f, /* top-right */ - -a, a, -a, 0.0f, 1.0f, /* top-left */ - -a, a, a, 0.0f, 0.0f, /* bottom-left */ - a, a, a, 1.0f, 0.0f, /* bottom-right */ - a, a, -a, 1.0f, 1.0f, /* top-right */ - - /* NOTE(pryazha): Bottom face */ - -a, -a, -a, 0.0f, 0.0f, /* bottom-left */ - a, -a, a, 1.0f, 1.0f, /* top-right */ - -a, -a, a, 0.0f, 1.0f, /* top-left */ - -a, -a, -a, 0.0f, 0.0f, /* bottom-left */ - a, -a, -a, 1.0f, 0.0f, /* bottom-right */ - a, -a, a, 1.0f, 1.0f, /* top-right */ - }; - - F32 cube_vertices_cw[] = { - /* NOTE(pryazha): Back face */ - a, -a, -a, 0.0f, 0.0f, /* bottom-left */ - -a, a, -a, 1.0f, 1.0f, /* top-right */ - -a, -a, -a, 1.0f, 0.0f, /* bottom-right */ - a, -a, -a, 0.0f, 0.0f, /* bottom-left */ - a, a, -a, 0.0f, 1.0f, /* top-left */ - -a, a, -a, 1.0f, 1.0f, /* top-right */ - - /* NOTE(pryazha): Front face */ - -a, -a, a, 0.0f, 0.0f, /* bottom-left */ - a, a, a, 1.0f, 1.0f, /* top-right */ - a, -a, a, 1.0f, 0.0f, /* bottom-right */ - -a, -a, a, 0.0f, 0.0f, /* bottom-left */ - -a, a, a, 0.0f, 1.0f, /* top-left */ - a, a, a, 1.0f, 1.0f, /* top-right */ - - /* NOTE(pryazha): Left face */ - -a, -a, -a, 0.0f, 0.0f, /* bottom-left */ - -a, a, a, 1.0f, 1.0f, /* top-right */ - -a, -a, a, 1.0f, 0.0f, /* bottom-right */ - -a, -a, -a, 0.0f, 0.0f, /* bottom-left */ - -a, a, -a, 0.0f, 1.0f, /* top-left */ - -a, a, a, 1.0f, 1.0f, /* top-right */ - - /* NOTE(pryazha): Right face */ - a, -a, a, 0.0f, 0.0f, /* bottom-left */ - a, a, -a, 1.0f, 1.0f, /* top-right */ - a, -a, -a, 1.0f, 0.0f, /* bottom-right */ - a, -a, a, 0.0f, 0.0f, /* bottom-left */ - a, a, a, 0.0f, 1.0f, /* top-left */ - a, a, -a, 1.0f, 1.0f, /* top-right */ - - /* NOTE(pryazha): Top face */ - -a, a, a, 0.0f, 0.0f, /* bottom-left */ - a, a, -a, 1.0f, 1.0f, /* top-right */ - a, a, a, 1.0f, 0.0f, /* bottom-right */ - -a, a, a, 0.0f, 0.0f, /* bottom-left */ - -a, a, -a, 0.0f, 1.0f, /* top-left */ - a, a, -a, 1.0f, 1.0f, /* top-right */ - - /* NOTE(pryazha): Bottom face */ - -a, -a, -a, 0.0f, 0.0f, /* bottom-left */ - a, -a, a, 1.0f, 1.0f, /* top-right */ - a, -a, -a, 1.0f, 0.0f, /* bottom-right */ - -a, -a, -a, 0.0f, 0.0f, /* bottom-left */ - -a, -a, a, 0.0f, 1.0f, /* top-left */ - a, -a, a, 1.0f, 1.0f, /* top-right */ - }; - - U32 cube_vao, vbo; - glGenVertexArrays(1, &cube_vao); - glBindVertexArray(cube_vao); - glGenBuffers(1, &vbo); - glBindBuffer(GL_ARRAY_BUFFER, vbo); - glBufferData(GL_ARRAY_BUFFER, sizeof(cube_vertices_cw), cube_vertices_cw, 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); - - Transform cube_transform = transform_default(); - - F32 target_fps = 60.0f; - F32 target_spf = 1.0f/target_fps; - camera_pos = v3f(0.0f, 1.0f, 3.0f); - - F32 last_time = glfwGetTime(); - - F32 d_angle = 45.0f; - - while (!glfwWindowShouldClose(window)) - { - glfwPollEvents(); - - /* INFO(pryazha): update */ - V3F left, up, forward; - V3F world_up = v3f(0.0f, 1.0f, 0.0f); - - forward = v3f_norm(v3f_sub(v3f(0.0f, 0.0f, 0.0f), camera_pos)); - left = v3f_norm(v3f_cross(world_up, forward)); - up = v3f_cross(forward, left); - - V3F dp = v3f_zero(); - F32 speed = 2.0f; - if (key_is_pressed(input.move_right)) - dp = v3f_add(dp, v3f_scalef(left, -speed*dt)); - if (key_is_pressed(input.move_forward)) - dp = v3f_add(dp, v3f_scalef(forward, speed*dt)); - if (key_is_pressed(input.move_left)) - dp = v3f_add(dp, v3f_scalef(left, speed*dt)); - if (key_is_pressed(input.move_backward)) - dp = v3f_add(dp, v3f_scalef(forward, -speed*dt)); - if (key_is_pressed(input.move_up)) - dp = v3f_add(dp, v3f_scalef(up, speed*dt)); - if (key_is_pressed(input.move_down)) - dp = v3f_add(dp, v3f_scalef(up, -speed*dt)); - - input_update_last_state(&input); - - camera_pos = v3f_add(camera_pos, dp); - - /* INFO(pryazha): Render */ - glClearColor(0.15f, 0.15f, 0.15f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - MAT4 model, view, projection; - cube_transform = transform_rotate(cube_transform, v3f(0.0f, d_angle*dt, 0.0f)); - model = transform_apply(cube_transform); - view = look_at(camera_pos, v3f(0.0f, 0.0f, 0.0f), v3f(0.0f, 1.0f, 0.0f)); - projection = perspective(90.0f, (F32)WIDTH/(F32)HEIGHT, 0.1f, 100.0f); - - glUseProgram(shader); - glBindTexture(GL_TEXTURE_2D, grid_texture); - shader_set_mat4fv(shader, "model", model); - shader_set_mat4fv(shader, "view", view); - shader_set_mat4fv(shader, "projection", projection); - glBindVertexArray(cube_vao); - glDrawArrays(GL_TRIANGLES, 0, 36); - - 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(); - dt = current_time-last_time; - last_time = current_time; - } - - glfwTerminate(); - return(0); + glfwMakeContextCurrent(window); + + if (glewInit() != GLEW_OK) { + fprintf(stderr, "[ERROR] Failed to initialize glew.\n"); + glfwTerminate(); + return(1); + } + + glEnable(GL_DEPTH_TEST); + glEnable(GL_CULL_FACE); + glFrontFace(GL_CW); + glCullFace(GL_BACK); + + U32 shader = create_shader_program("shaders/face_culling.vert", + "shaders/face_culling.frag"); + + U32 grid_texture = load_texture("../../data/textures/grid.png"); + + F32 a = 0.5f; + /* NOTE(pryazha): Counter-clockwise order */ + F32 cube_vertices_ccw[] = { + /* NOTE(pryazha): Back face */ + a, -a, -a, 0.0f, 0.0f, /* bottom-left */ + -a, a, -a, 1.0f, 1.0f, /* top-right */ + a, a, -a, 0.0f, 1.0f, /* top-left */ + a, -a, -a, 0.0f, 0.0f, /* bottom-left */ + -a, -a, -a, 1.0f, 0.0f, /* bottom-right */ + -a, a, -a, 1.0f, 1.0f, /* top-right */ + + /* NOTE(pryazha): Front face */ + -a, -a, a, 0.0f, 0.0f, /* bottom-left */ + a, a, a, 1.0f, 1.0f, /* top-right */ + -a, a, a, 0.0f, 1.0f, /* top-left */ + -a, -a, a, 0.0f, 0.0f, /* bottom-left */ + a, -a, a, 1.0f, 0.0f, /* bottom-right */ + a, a, a, 1.0f, 1.0f, /* top-right */ + + /* NOTE(pryazha): Left face */ + -a, -a, -a, 0.0f, 0.0f, /* bottom-left */ + -a, a, a, 1.0f, 1.0f, /* top-right */ + -a, a, -a, 0.0f, 1.0f, /* top-left */ + -a, -a, -a, 0.0f, 0.0f, /* bottom-left */ + -a, -a, a, 1.0f, 0.0f, /* bottom-right */ + -a, a, a, 1.0f, 1.0f, /* top-right */ + + /* NOTE(pryazha): Right face */ + a, -a, a, 0.0f, 0.0f, /* bottom-left */ + a, a, -a, 1.0f, 1.0f, /* top-right */ + a, a, a, 0.0f, 1.0f, /* top-left */ + a, -a, a, 0.0f, 0.0f, /* bottom-left */ + a, -a, -a, 1.0f, 0.0f, /* bottom-right */ + a, a, -a, 1.0f, 1.0f, /* top-right */ + + /* NOTE(pryazha): Top face */ + -a, a, a, 0.0f, 0.0f, /* bottom-left */ + a, a, -a, 1.0f, 1.0f, /* top-right */ + -a, a, -a, 0.0f, 1.0f, /* top-left */ + -a, a, a, 0.0f, 0.0f, /* bottom-left */ + a, a, a, 1.0f, 0.0f, /* bottom-right */ + a, a, -a, 1.0f, 1.0f, /* top-right */ + + /* NOTE(pryazha): Bottom face */ + -a, -a, -a, 0.0f, 0.0f, /* bottom-left */ + a, -a, a, 1.0f, 1.0f, /* top-right */ + -a, -a, a, 0.0f, 1.0f, /* top-left */ + -a, -a, -a, 0.0f, 0.0f, /* bottom-left */ + a, -a, -a, 1.0f, 0.0f, /* bottom-right */ + a, -a, a, 1.0f, 1.0f, /* top-right */ + }; + + F32 cube_vertices_cw[] = { + /* NOTE(pryazha): Back face */ + a, -a, -a, 0.0f, 0.0f, /* bottom-left */ + -a, a, -a, 1.0f, 1.0f, /* top-right */ + -a, -a, -a, 1.0f, 0.0f, /* bottom-right */ + a, -a, -a, 0.0f, 0.0f, /* bottom-left */ + a, a, -a, 0.0f, 1.0f, /* top-left */ + -a, a, -a, 1.0f, 1.0f, /* top-right */ + + /* NOTE(pryazha): Front face */ + -a, -a, a, 0.0f, 0.0f, /* bottom-left */ + a, a, a, 1.0f, 1.0f, /* top-right */ + a, -a, a, 1.0f, 0.0f, /* bottom-right */ + -a, -a, a, 0.0f, 0.0f, /* bottom-left */ + -a, a, a, 0.0f, 1.0f, /* top-left */ + a, a, a, 1.0f, 1.0f, /* top-right */ + + /* NOTE(pryazha): Left face */ + -a, -a, -a, 0.0f, 0.0f, /* bottom-left */ + -a, a, a, 1.0f, 1.0f, /* top-right */ + -a, -a, a, 1.0f, 0.0f, /* bottom-right */ + -a, -a, -a, 0.0f, 0.0f, /* bottom-left */ + -a, a, -a, 0.0f, 1.0f, /* top-left */ + -a, a, a, 1.0f, 1.0f, /* top-right */ + + /* NOTE(pryazha): Right face */ + a, -a, a, 0.0f, 0.0f, /* bottom-left */ + a, a, -a, 1.0f, 1.0f, /* top-right */ + a, -a, -a, 1.0f, 0.0f, /* bottom-right */ + a, -a, a, 0.0f, 0.0f, /* bottom-left */ + a, a, a, 0.0f, 1.0f, /* top-left */ + a, a, -a, 1.0f, 1.0f, /* top-right */ + + /* NOTE(pryazha): Top face */ + -a, a, a, 0.0f, 0.0f, /* bottom-left */ + a, a, -a, 1.0f, 1.0f, /* top-right */ + a, a, a, 1.0f, 0.0f, /* bottom-right */ + -a, a, a, 0.0f, 0.0f, /* bottom-left */ + -a, a, -a, 0.0f, 1.0f, /* top-left */ + a, a, -a, 1.0f, 1.0f, /* top-right */ + + /* NOTE(pryazha): Bottom face */ + -a, -a, -a, 0.0f, 0.0f, /* bottom-left */ + a, -a, a, 1.0f, 1.0f, /* top-right */ + a, -a, -a, 1.0f, 0.0f, /* bottom-right */ + -a, -a, -a, 0.0f, 0.0f, /* bottom-left */ + -a, -a, a, 0.0f, 1.0f, /* top-left */ + a, -a, a, 1.0f, 1.0f, /* top-right */ + }; + + U32 cube_vao, vbo; + glGenVertexArrays(1, &cube_vao); + glBindVertexArray(cube_vao); + glGenBuffers(1, &vbo); + glBindBuffer(GL_ARRAY_BUFFER, vbo); + glBufferData(GL_ARRAY_BUFFER, sizeof(cube_vertices_cw), cube_vertices_cw, 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); + + Transform cube_transform = transform_default(); + + 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(); + + F32 d_angle = 45.0f; + + 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 = perspective(state.camera.fovx, (F32)width/(F32)height, + state.camera.near, state.camera.far); + cube_transform = transform_rotate(cube_transform, + v3f(0.0f, d_angle*state.dt, 0.0f)); + model = transform_apply(cube_transform); + + 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); + glBindTexture(GL_TEXTURE_2D, grid_texture); + shader_set_mat4fv(shader, "model", model); + shader_set_mat4fv(shader, "view", view); + shader_set_mat4fv(shader, "proj", proj); + glBindVertexArray(cube_vao); + 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/3.blending/shaders/blending.fs b/advanced_opengl/4.face_culling/shaders/face_culling.frag index f58c5d3..71892a7 100644 --- a/advanced_opengl/3.blending/shaders/blending.fs +++ b/advanced_opengl/4.face_culling/shaders/face_culling.frag @@ -6,8 +6,7 @@ in vec2 tex_coords; uniform sampler2D texture1; -void -main(void) +void main(void) { frag_color = texture(texture1, tex_coords); } diff --git a/advanced_opengl/2.stencil/shaders/stencil.vs b/advanced_opengl/4.face_culling/shaders/face_culling.vert index 62e71a2..68b8fe2 100644 --- a/advanced_opengl/2.stencil/shaders/stencil.vs +++ b/advanced_opengl/4.face_culling/shaders/face_culling.vert @@ -4,13 +4,12 @@ layout(location = 1) in vec2 atex_coords; uniform mat4 model; uniform mat4 view; -uniform mat4 projection; +uniform mat4 proj; out vec2 tex_coords; -void -main(void) +void main(void) { - gl_Position = projection*view*model*vec4(apos, 1.0); + gl_Position = proj*view*model*vec4(apos, 1.0); tex_coords = atex_coords; } diff --git a/advanced_opengl/5.framebuffers/framebuffers b/advanced_opengl/5.framebuffers/framebuffers Binary files differindex a1f7170..4a3d49e 100755 --- a/advanced_opengl/5.framebuffers/framebuffers +++ b/advanced_opengl/5.framebuffers/framebuffers diff --git a/advanced_opengl/5.framebuffers/framebuffers.c b/advanced_opengl/5.framebuffers/framebuffers.c index a0523cc..7948a61 100644 --- a/advanced_opengl/5.framebuffers/framebuffers.c +++ b/advanced_opengl/5.framebuffers/framebuffers.c @@ -2,423 +2,336 @@ #include "GLFW/glfw3.h" #include "pwyazh.h" - #include "pwyazh_GL.h" #include "common.h" -#include <unistd.h> +int main(void) +{ + GLFWwindow *window; + State state; + S32 width, height; + Input input; -#define WIDTH 1024 -#define HEIGHT 768 + if (glfwInit() == GLFW_FALSE) { + fprintf(stderr, "[ERROR] Failed to initialize glfw.\n"); + return(1); + } -static V3F camera_pos; -static F32 dt; -static Input input; + width = 1024; + height = 768; -void -key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) -{ - switch (action) - { - case GLFW_PRESS: { - switch (key) - { - case GLFW_KEY_D: { - input.move_right.state = KeyState_PRESS; - } break; - case GLFW_KEY_W: { - input.move_forward.state = KeyState_PRESS; - } break; - case GLFW_KEY_A: { - input.move_left.state = KeyState_PRESS; - } break; - case GLFW_KEY_S: { - input.move_backward.state = KeyState_PRESS; - } break; - case GLFW_KEY_E: { - input.move_up.state = KeyState_PRESS; - } break; - case GLFW_KEY_Q: { - input.move_down.state = KeyState_PRESS; - } break; - } - } break; - - case GLFW_RELEASE: { - switch (key) - { - case GLFW_KEY_D: { - input.move_right.state = KeyState_RELEASE; - } break; - case GLFW_KEY_W: { - input.move_forward.state = KeyState_RELEASE; - } break; - case GLFW_KEY_A: { - input.move_left.state = KeyState_RELEASE; - } break; - case GLFW_KEY_S: { - input.move_backward.state = KeyState_RELEASE; - } break; - case GLFW_KEY_E: { - input.move_up.state = KeyState_RELEASE; - } break; - case GLFW_KEY_Q: { - input.move_down.state = KeyState_RELEASE; - } break; - } - } break; - } -} + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); + glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); + window = glfwCreateWindow(width, height, "Framebuffers", 0, 0); + if (!window) { + fprintf(stderr, "[ERROR] Failed to create window.\n"); + glfwTerminate(); + return(1); + } -int -main(void) -{ - GLFWwindow *window; - - if (glfwInit() == GLFW_FALSE) - { - fprintf(stderr, "[ERROR] Failed to initialize glfw.\n"); - return(1); - } - - glfwWindowHint(GLFW_RESIZABLE, 0); - glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); - glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); - window = glfwCreateWindow(WIDTH, HEIGHT, "Framebuffers", 0, 0); - if (!window) - { - fprintf(stderr, "[ERROR] Failed to create window.\n"); - glfwTerminate(); - return(1); - } - - glfwMakeContextCurrent(window); - - glfwSetKeyCallback(window, key_callback); - - if (glewInit() != GLEW_OK) - { - fprintf(stderr, "[ERROR] Failed to initialize glew.\n"); - glfwTerminate(); - return(1); - } - - U32 screen_shader = create_shader_program("shaders/screen.vs", "shaders/screen.fs"); - U32 cube_shader = create_shader_program("shaders/cube.vs", "shaders/cube.fs"); - 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"); - - U32 fbo; - glGenFramebuffers(1, &fbo); - glBindFramebuffer(GL_FRAMEBUFFER, fbo); - - U32 texture_colorbuffer; - glGenTextures(1, &texture_colorbuffer); - glBindTexture(GL_TEXTURE_2D, texture_colorbuffer); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, WIDTH, HEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); - 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); - - U32 rbo; - 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); - if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) - fprintf(stderr, "[ERROR]: Framebuffer is not complete.\n"); - glBindFramebuffer(GL_FRAMEBUFFER, 0); - - 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.0f*a)) - }; - - Transform platform_position = - transform_make_scale_translate(v3f(10.0f, 0.2f, 10.0f), - v3f(0.0f, -(a+(a*0.2f)+0.01f), 0.0f)); - - U32 cube_vao, quad_vao, vbo; - - glGenVertexArrays(1, &cube_vao); - glBindVertexArray(cube_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); - - 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 - }; - - 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); - - Transform window_transforms[] = { - transform_make_scale_translate(v3f(0.5f, 0.5f, 0.5f), v3f(0.0f, 0.0f, a+0.1f)), - transform_make_scale_translate(v3f(0.5f, 0.5f, 0.5f), v3f(0.0f, 0.0f, 2.0f)), - transform_make_scale_translate(v3f(0.5f, 0.5f, 0.5f), v3f(1.0f, 0.0f, -1.0f)), - transform_make_scale_translate(v3f(0.5f, 0.5f, 0.5f), v3f(-2.0f, 0.0f, 0.5f)), - transform_make_scale_translate(v3f(0.5f, 0.5f, 0.5f), v3f(-3.0f, 0.0f, -3.0f)), - transform_make_scale_translate(v3f(0.5f, 0.5f, 0.5f), v3f(3.0f, 0.0f, 0.2)), - }; - - F32 angle = 0.0f; - for (S32 window_index = 0; - window_index < (S32)ArrayCount(window_transforms); - ++window_index) - { - Transform *transform = window_transforms+window_index; - *transform = transform_rotate(*transform, v3f(0.0f, angle, 0.0f)); - angle += 30.0f; - } - - F32 target_fps = 60.0f; - F32 target_spf = 1.0f/target_fps; - camera_pos = v3f(0.0f, 1.0f, 3.0f); - - F32 last_time = glfwGetTime(); - - while (!glfwWindowShouldClose(window)) - { - glfwPollEvents(); - - /* INFO(pryazha): update */ - V3F left, up, forward; - V3F world_up = v3f(0.0f, 1.0f, 0.0f); - - forward = v3f_norm(v3f_sub(v3f(0.0f, 0.0f, 0.0f), camera_pos)); - left = v3f_norm(v3f_cross(world_up, forward)); - up = v3f_cross(forward, left); - - V3F dp = v3f_zero(); - F32 speed = 2.0f; - if (key_is_pressed(input.move_right)) - dp = v3f_add(dp, v3f_scalef(left, -speed*dt)); - if (key_is_pressed(input.move_forward)) - dp = v3f_add(dp, v3f_scalef(forward, speed*dt)); - if (key_is_pressed(input.move_left)) - dp = v3f_add(dp, v3f_scalef(left, speed*dt)); - if (key_is_pressed(input.move_backward)) - dp = v3f_add(dp, v3f_scalef(forward, -speed*dt)); - if (key_is_pressed(input.move_up)) - dp = v3f_add(dp, v3f_scalef(up, speed*dt)); - if (key_is_pressed(input.move_down)) - dp = v3f_add(dp, v3f_scalef(up, -speed*dt)); - - input_update_last_state(&input); - - camera_pos = v3f_add(camera_pos, dp); - - Transform sorted_window_transforms[ArrayCount(window_transforms)]; - MemoryCopyArray(sorted_window_transforms, window_transforms); - for (S32 i = 0; i < (S32)ArrayCount(sorted_window_transforms); ++i) { - for (S32 pos_index = 1; - pos_index < (S32)ArrayCount(sorted_window_transforms); - ++pos_index) - { - F32 distance_left = v3f_length(v3f_sub(sorted_window_transforms[pos_index-1].translate, camera_pos)); - F32 distance_right = v3f_length(v3f_sub(sorted_window_transforms[pos_index].translate, camera_pos)); - if (distance_left < distance_right) { - Transform temp = sorted_window_transforms[pos_index]; - sorted_window_transforms[pos_index] = sorted_window_transforms[pos_index-1]; - sorted_window_transforms[pos_index-1] = temp; - } - } - } - - /* INFO(pryazha): Render */ - glBindFramebuffer(GL_FRAMEBUFFER, fbo); - glClearColor(0.15f, 0.15f, 0.15f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glEnable(GL_DEPTH_TEST); - MAT4 view, projection; - view = look_at(camera_pos, v3f(0.0f, 0.0f, 0.0f), v3f(0.0f, 1.0f, 0.0f)); - projection = perspective(90.0f, (F32)WIDTH/(F32)HEIGHT, 0.1f, 100.0f); - glUseProgram(cube_shader); - shader_set_mat4fv(cube_shader, "view", view); - shader_set_mat4fv(cube_shader, "projection", projection); - glBindTexture(GL_TEXTURE_2D, marble_texture); - glBindVertexArray(cube_vao); - for (S32 transform_index = 0; - transform_index < (S32)ArrayCount(cube_positions); - ++transform_index) - { - shader_set_mat4fv(cube_shader, "model", transform_apply(cube_positions[transform_index])); - glDrawArrays(GL_TRIANGLES, 0, 36); - } - - glBindTexture(GL_TEXTURE_2D, metal_texture); - shader_set_mat4fv(cube_shader, "model", transform_apply(platform_position)); - glDrawArrays(GL_TRIANGLES, 0, 36); - glBindVertexArray(0); - - glEnable(GL_BLEND); - glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - glUseProgram(cube_shader); - glBindTexture(GL_TEXTURE_2D, window_texture); - shader_set_mat4fv(cube_shader, "view", view); - shader_set_mat4fv(cube_shader, "projection", projection); - glBindVertexArray(quad_vao); - for (S32 window_index = 0; - window_index < (S32)ArrayCount(sorted_window_transforms); - ++window_index) - { - shader_set_mat4fv(cube_shader, "model", transform_apply(sorted_window_transforms[window_index])); - glDrawArrays(GL_TRIANGLES, 0, 6); - } - glBindVertexArray(0); - glDisable(GL_BLEND); - - glBindFramebuffer(GL_FRAMEBUFFER, 0); - glClearColor(1.0f, 1.0f, 1.0f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT); - glUseProgram(screen_shader); - glDisable(GL_DEPTH_TEST); - glBindTexture(GL_TEXTURE_2D, texture_colorbuffer); - glBindVertexArray(quad_vao); - shader_set_mat4fv(screen_shader, "model", mat4_identity()); - glDrawArrays(GL_TRIANGLES, 0, 6); - glBindVertexArray(0); - - glBindFramebuffer(GL_FRAMEBUFFER, fbo); - glClearColor(0.15f, 0.15f, 0.15f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glEnable(GL_DEPTH_TEST); - V3F target = v3f_add(camera_pos, v3f_negate(forward)); - view = look_at(camera_pos, target, v3f(0.0f, 1.0f, 0.0f)); - glUseProgram(cube_shader); - shader_set_mat4fv(cube_shader, "view", view); - shader_set_mat4fv(cube_shader, "projection", projection); - glBindTexture(GL_TEXTURE_2D, marble_texture); - glBindVertexArray(cube_vao); - for (S32 transform_index = 0; - transform_index < (S32)ArrayCount(cube_positions); - ++transform_index) - { - shader_set_mat4fv(cube_shader, "model", transform_apply(cube_positions[transform_index])); - glDrawArrays(GL_TRIANGLES, 0, 36); - } - - glBindTexture(GL_TEXTURE_2D, metal_texture); - shader_set_mat4fv(cube_shader, "model", transform_apply(platform_position)); - glDrawArrays(GL_TRIANGLES, 0, 36); - glBindVertexArray(0); - - glEnable(GL_BLEND); - glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - glUseProgram(cube_shader); - glBindTexture(GL_TEXTURE_2D, window_texture); - shader_set_mat4fv(cube_shader, "view", view); - shader_set_mat4fv(cube_shader, "projection", projection); - glBindVertexArray(quad_vao); - for (S32 window_index = 0; - window_index < (S32)ArrayCount(sorted_window_transforms); - ++window_index) - { - shader_set_mat4fv(cube_shader, "model", transform_apply(sorted_window_transforms[window_index])); - glDrawArrays(GL_TRIANGLES, 0, 6); - } - glBindVertexArray(0); - glDisable(GL_BLEND); - - glBindFramebuffer(GL_FRAMEBUFFER, 0); - glUseProgram(screen_shader); - glDisable(GL_DEPTH_TEST); - glBindTexture(GL_TEXTURE_2D, texture_colorbuffer); - glBindVertexArray(quad_vao); - MAT4 model = transform_apply(transform_make_scale_translate(v3f(0.3f, 0.3f, 0.3f), v3f(-0.7f, 0.7f, 0.0f))); - shader_set_mat4fv(screen_shader, "model", model); - glDrawArrays(GL_TRIANGLES, 0, 6); - 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(); - dt = current_time-last_time; - last_time = current_time; - } - - glfwTerminate(); - return(0); + glfwMakeContextCurrent(window); + + if (glewInit() != GLEW_OK) { + fprintf(stderr, "[ERROR] Failed to initialize glew.\n"); + glfwTerminate(); + 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 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"); + + U32 fbo, texture_colorbuffer, rbo; + glGenFramebuffers(1, &fbo); + glBindFramebuffer(GL_FRAMEBUFFER, fbo); + glGenTextures(1, &texture_colorbuffer); + glBindTexture(GL_TEXTURE_2D, texture_colorbuffer); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); + 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); + 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); + if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) + fprintf(stderr, "[ERROR]: Framebuffer is not complete.\n"); + glBindFramebuffer(GL_FRAMEBUFFER, 0); + + 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.0f*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 cube_vao, quad_vao, vbo; + glGenVertexArrays(1, &cube_vao); + glBindVertexArray(cube_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); + + 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 + }; + + 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); + + Transform window_transforms[] = { + transform_make_scale_translate(v3f(0.5f, 0.5f, 0.5f), v3f(0.0f, 0.0f, a+0.1f)), + transform_make_scale_translate(v3f(0.5f, 0.5f, 0.5f), v3f(0.0f, 0.0f, 2.0f)), + transform_make_scale_translate(v3f(0.5f, 0.5f, 0.5f), v3f(1.0f, 0.0f, -1.0f)), + transform_make_scale_translate(v3f(0.5f, 0.5f, 0.5f), v3f(-2.0f, 0.0f, 0.5f)), + transform_make_scale_translate(v3f(0.5f, 0.5f, 0.5f), v3f(-3.0f, 0.0f, -3.0f)), + transform_make_scale_translate(v3f(0.5f, 0.5f, 0.5f), v3f(3.0f, 0.0f, 0.2)), + }; + + F32 angle = 0.0f; + for (S32 i = 0; i < (S32)ArrayCount(window_transforms); ++i) { + Transform *transform = window_transforms+i; + *transform = transform_rotate(*transform, v3f(0.0f, angle, 0.0f)); + angle += 30.0f; + } + + 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); + + Transform sorted[ArrayCount(window_transforms)]; + MemoryCopyArray(sorted, window_transforms); + for (S32 i = 0; i < (S32)ArrayCount(sorted); ++i) { + for (S32 j = 1; j < (S32)ArrayCount(sorted); ++j) { + F32 dist_left = v3f_length(v3f_sub(sorted[j-1].translate, state.camera.pos)); + F32 dist_right = v3f_length(v3f_sub(sorted[j].translate, state.camera.pos)); + if (dist_left < dist_right) { + Transform temp = sorted[j]; + sorted[j] = sorted[j-1]; + sorted[j-1] = temp; + } + } + } + + /* INFO(pryazha): Render */ + MAT4 model, view, proj; + + view = look_at(state.camera.pos, target, v3f(0.0f, 1.0f, 0.0f)); + proj = perspective(state.camera.fovx, (F32)width/(F32)height, + state.camera.near, state.camera.far); + + glBindFramebuffer(GL_FRAMEBUFFER, fbo); + glViewport(0, 0, width, height); + glClearColor(0.15f, 0.15f, 0.15f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glEnable(GL_DEPTH_TEST); + glUseProgram(cube_shader); + shader_set_mat4fv(cube_shader, "view", view); + shader_set_mat4fv(cube_shader, "proj", proj); + glBindTexture(GL_TEXTURE_2D, marble_texture); + glBindVertexArray(cube_vao); + for (S32 i = 0; i < (S32)ArrayCount(cube_positions); ++i) { + model = transform_apply(cube_positions[i]); + shader_set_mat4fv(cube_shader, "model", model); + glDrawArrays(GL_TRIANGLES, 0, 36); + } + + glBindTexture(GL_TEXTURE_2D, metal_texture); + model = transform_apply(platform_transform); + shader_set_mat4fv(cube_shader, "model", model); + glDrawArrays(GL_TRIANGLES, 0, 36); + glBindVertexArray(0); + + glEnable(GL_BLEND); + glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + glUseProgram(cube_shader); + glBindTexture(GL_TEXTURE_2D, window_texture); + shader_set_mat4fv(cube_shader, "view", view); + shader_set_mat4fv(cube_shader, "proj", proj); + glBindVertexArray(quad_vao); + for (S32 i = 0; i < (S32)ArrayCount(sorted); ++i) { + model = transform_apply(sorted[i]); + shader_set_mat4fv(cube_shader, "model", model); + glDrawArrays(GL_TRIANGLES, 0, 6); + } + glBindVertexArray(0); + glDisable(GL_BLEND); + + glBindFramebuffer(GL_FRAMEBUFFER, 0); + glViewport(0, 0, width, height); + glClearColor(1.0f, 1.0f, 1.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + glUseProgram(screen_shader); + glDisable(GL_DEPTH_TEST); + glBindTexture(GL_TEXTURE_2D, texture_colorbuffer); + glBindVertexArray(quad_vao); + shader_set_mat4fv(screen_shader, "model", mat4_identity()); + glDrawArrays(GL_TRIANGLES, 0, 6); + glBindVertexArray(0); + + glBindFramebuffer(GL_FRAMEBUFFER, fbo); + glViewport(0, 0, width, height); + glClearColor(0.15f, 0.15f, 0.15f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glEnable(GL_DEPTH_TEST); + V3F f = v3f(view.m2.x, view.m2.y, view.m2.z); + target = v3f_add(state.camera.pos, v3f_negate(f)); + view = look_at(state.camera.pos, target, v3f(0.0f, 1.0f, 0.0f)); + glUseProgram(cube_shader); + shader_set_mat4fv(cube_shader, "view", view); + shader_set_mat4fv(cube_shader, "proj", proj); + glBindTexture(GL_TEXTURE_2D, marble_texture); + glBindVertexArray(cube_vao); + for (S32 i = 0; i < (S32)ArrayCount(cube_positions); ++i) { + model = transform_apply(cube_positions[i]); + shader_set_mat4fv(cube_shader, "model", model); + glDrawArrays(GL_TRIANGLES, 0, 36); + } + + glBindTexture(GL_TEXTURE_2D, metal_texture); + model = transform_apply(platform_transform); + shader_set_mat4fv(cube_shader, "model", model); + glDrawArrays(GL_TRIANGLES, 0, 36); + glBindVertexArray(0); + + glEnable(GL_BLEND); + glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + glUseProgram(cube_shader); + glBindTexture(GL_TEXTURE_2D, window_texture); + shader_set_mat4fv(cube_shader, "view", view); + shader_set_mat4fv(cube_shader, "proj", proj); + glBindVertexArray(quad_vao); + for (S32 i = 0; i < (S32)ArrayCount(sorted); ++i) { + model = transform_apply(sorted[i]); + shader_set_mat4fv(cube_shader, "model", model); + glDrawArrays(GL_TRIANGLES, 0, 6); + } + glBindVertexArray(0); + glDisable(GL_BLEND); + + glBindFramebuffer(GL_FRAMEBUFFER, 0); + glViewport(0, 0, width, height); + glUseProgram(screen_shader); + glDisable(GL_DEPTH_TEST); + glBindTexture(GL_TEXTURE_2D, texture_colorbuffer); + glBindVertexArray(quad_vao); + model = transform_apply(transform_make_scale_translate(v3f(0.3f, 0.3f, 0.3f), v3f(-0.7f, 0.7f, 0.0f))); + shader_set_mat4fv(screen_shader, "model", model); + glDrawArrays(GL_TRIANGLES, 0, 6); + 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/5.framebuffers/shaders/cube.fs b/advanced_opengl/5.framebuffers/shaders/cube.frag index f58c5d3..71892a7 100644 --- a/advanced_opengl/5.framebuffers/shaders/cube.fs +++ b/advanced_opengl/5.framebuffers/shaders/cube.frag @@ -6,8 +6,7 @@ in vec2 tex_coords; uniform sampler2D texture1; -void -main(void) +void main(void) { frag_color = texture(texture1, tex_coords); } diff --git a/advanced_opengl/5.framebuffers/shaders/cube.vs b/advanced_opengl/5.framebuffers/shaders/cube.vert index aea5c2c..2436f35 100644 --- a/advanced_opengl/5.framebuffers/shaders/cube.vs +++ b/advanced_opengl/5.framebuffers/shaders/cube.vert @@ -5,13 +5,12 @@ layout(location = 1) in vec2 atex_coords; uniform mat4 model; uniform mat4 view; -uniform mat4 projection; +uniform mat4 proj; out vec2 tex_coords; -void -main(void) +void main(void) { - gl_Position = projection*view*model*vec4(apos, 1.0); + gl_Position = proj*view*model*vec4(apos, 1.0); tex_coords = atex_coords; } diff --git a/advanced_opengl/5.framebuffers/shaders/screen.fs b/advanced_opengl/5.framebuffers/shaders/screen.frag index 183d490..234b3fc 100644 --- a/advanced_opengl/5.framebuffers/shaders/screen.fs +++ b/advanced_opengl/5.framebuffers/shaders/screen.frag @@ -6,15 +6,13 @@ in vec2 tex_coords; uniform sampler2D texture1; -vec4 -inversion() +vec4 inversion() { vec4 result = vec4(1.0-vec3(texture(texture1, tex_coords)), 1.0); return(result); } -vec4 -grayscale_average() +vec4 grayscale_average() { vec4 tex_color = texture(texture1, tex_coords); float average = (tex_color.r+tex_color.g+tex_color.b)/3.0; @@ -22,8 +20,7 @@ grayscale_average() return(result); } -vec4 -grayscale_weights() +vec4 grayscale_weights() { vec4 tex_color = texture(texture1, tex_coords); float average = 0.2126*tex_color.r+0.7152*tex_color.g+0.0722*tex_color.b; @@ -33,8 +30,7 @@ grayscale_weights() const float offset = 1.0/300.0; -vec4 -kernel_effect(float[9] kernel) +vec4 kernel_effect(float[9] kernel) { vec2 offsets[9] = vec2[]( vec2(-offset, offset), /* top-left */ @@ -49,13 +45,8 @@ kernel_effect(float[9] kernel) ); vec3 sample_texture[9]; - for (int offset_index = 0; - offset_index < 9; - ++offset_index) - { - sample_texture[offset_index] = - vec3(texture(texture1, tex_coords+offsets[offset_index])); - } + for (int i = 0; i < 9; ++i) + sample_texture[i] = vec3(texture(texture1, tex_coords+offsets[i])); vec3 color = vec3(0.0); for (int i = 0; i < 9; ++i) @@ -64,8 +55,7 @@ kernel_effect(float[9] kernel) return(vec4(color, 1.0)); } -void -main(void) +void main(void) { float strange_kernel[9] = float[]( -1, -1, -1, diff --git a/advanced_opengl/5.framebuffers/shaders/screen.vs b/advanced_opengl/5.framebuffers/shaders/screen.vert index 8fdea55..92bc378 100644 --- a/advanced_opengl/5.framebuffers/shaders/screen.vs +++ b/advanced_opengl/5.framebuffers/shaders/screen.vert @@ -6,8 +6,7 @@ out vec2 tex_coords; uniform mat4 model; -void -main(void) +void main(void) { gl_Position = model*vec4(apos, 1.0); tex_coords = atex_coords; diff --git a/advanced_opengl/6.cubemaps/cubemaps b/advanced_opengl/6.cubemaps/cubemaps Binary files differindex bdf54f5..bc274ea 100755 --- a/advanced_opengl/6.cubemaps/cubemaps +++ b/advanced_opengl/6.cubemaps/cubemaps diff --git a/advanced_opengl/6.cubemaps/cubemaps.c b/advanced_opengl/6.cubemaps/cubemaps.c index 5ea5300..32a53d1 100644 --- a/advanced_opengl/6.cubemaps/cubemaps.c +++ b/advanced_opengl/6.cubemaps/cubemaps.c @@ -2,450 +2,350 @@ #include "GLFW/glfw3.h" #include "pwyazh.h" - #include "pwyazh_GL.h" #include "common.h" -#include <unistd.h> +int main(void) +{ + GLFWwindow *window; + State state; + S32 width, height; + Input input; -#define WIDTH 1024 -#define HEIGHT 768 + if (glfwInit() == GLFW_FALSE) { + fprintf(stderr, "[ERROR] Failed to initialize glfw.\n"); + return(1); + } -static V3F camera_pos; -static F32 dt; -static Input input; -static B32 first_mouse = 1; + width = 1024; + height = 768; -void -key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) -{ - switch (action) - { - case GLFW_PRESS: { - switch (key) - { - case GLFW_KEY_D: { - input.move_right.state = KeyState_PRESS; - } break; - case GLFW_KEY_W: { - input.move_forward.state = KeyState_PRESS; - } break; - case GLFW_KEY_A: { - input.move_left.state = KeyState_PRESS; - } break; - case GLFW_KEY_S: { - input.move_backward.state = KeyState_PRESS; - } break; - case GLFW_KEY_E: { - input.move_up.state = KeyState_PRESS; - } break; - case GLFW_KEY_Q: { - input.move_down.state = KeyState_PRESS; - } break; - } - } break; - - case GLFW_RELEASE: { - switch (key) - { - case GLFW_KEY_D: { - input.move_right.state = KeyState_RELEASE; - } break; - case GLFW_KEY_W: { - input.move_forward.state = KeyState_RELEASE; - } break; - case GLFW_KEY_A: { - input.move_left.state = KeyState_RELEASE; - } break; - case GLFW_KEY_S: { - input.move_backward.state = KeyState_RELEASE; - } break; - case GLFW_KEY_E: { - input.move_up.state = KeyState_RELEASE; - } break; - case GLFW_KEY_Q: { - input.move_down.state = KeyState_RELEASE; - } break; - } - } break; - } -} + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); + glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); + window = glfwCreateWindow(width, height, "Cubemaps", 0, 0); + if (!window) { + fprintf(stderr, "[ERROR] Failed to create window.\n"); + glfwTerminate(); + return(1); + } -void -cursor_pos_callback(GLFWwindow* window, double xpos, double ypos) -{ - if (first_mouse) - { - input.last_mouse_pos = v2f(xpos, ypos); - first_mouse = 0; - } - input.mouse_offset = v2f(input.mouse_offset.x+((F32)xpos-input.last_mouse_pos.x), - input.mouse_offset.y+((F32)ypos-input.last_mouse_pos.y)); - input.last_mouse_pos = v2f((F32)xpos, (F32)ypos); -} + glfwMakeContextCurrent(window); -int -main(void) -{ - GLFWwindow *window; - - if (glfwInit() == GLFW_FALSE) - { - fprintf(stderr, "[ERROR] Failed to initialize glfw.\n"); - return(1); - } - - glfwWindowHint(GLFW_RESIZABLE, 0); - glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); - glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); - window = glfwCreateWindow(WIDTH, HEIGHT, "Cubemaps", 0, 0); - if (!window) - { - fprintf(stderr, "[ERROR] Failed to create window.\n"); - glfwTerminate(); - return(1); - } - - glfwMakeContextCurrent(window); - - glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); - - glfwSetKeyCallback(window, key_callback); - glfwSetCursorPosCallback(window, cursor_pos_callback); - - if (glewInit() != GLEW_OK) - { - fprintf(stderr, "[ERROR] Failed to initialize glew.\n"); - glfwTerminate(); - return(1); - } - - U32 skybox_shader = create_shader_program("shaders/skybox.vs", "shaders/skybox.fs"); - U32 reflection_shader = create_shader_program("shaders/reflection.vs", "shaders/reflection.fs"); - U32 refraction_shader = create_shader_program("shaders/refraction.vs", "shaders/refraction.fs"); - U32 cube_shader = create_shader_program("shaders/cube.vs", "shaders/cube.fs"); - U32 grid_texture = load_texture("../../data/textures/grid.png"); - - const char *cube_texture_filenames[6] = { - "../../data/textures/skybox/right.jpg", - "../../data/textures/skybox/left.jpg", - "../../data/textures/skybox/top.jpg", - "../../data/textures/skybox/bottom.jpg", - "../../data/textures/skybox/front.jpg", - "../../data/textures/skybox/back.jpg" - }; - U32 skybox_texture = load_cubemap(cube_texture_filenames); - - 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.0f*a)) - }; - - Transform platform_position = - transform_make_scale_translate(v3f(10.0f, 0.2f, 10.0f), - v3f(0.0f, -(a+(a*0.2f)+0.01f), 0.0f)); - - U32 cube_vao, vbo; - - glGenVertexArrays(1, &cube_vao); - glBindVertexArray(cube_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); - - a = 1.0f; - F32 skybox_cube_vertices[] = { - -a, -a, -a, - a, -a, -a, - a, a, -a, - a, a, -a, - -a, a, -a, - -a, -a, -a, - - -a, -a, a, - a, -a, a, - a, a, a, - a, a, a, - -a, a, a, - -a, -a, a, - - -a, a, a, - -a, a, -a, - -a, -a, -a, - -a, -a, -a, - -a, -a, a, - -a, a, a, - - a, a, a, - a, a, -a, - a, -a, -a, - a, -a, -a, - a, -a, a, - a, a, a, - - -a, -a, -a, - a, -a, -a, - a, -a, a, - a, -a, a, - -a, -a, a, - -a, -a, -a, - - -a, a, -a, - a, a, -a, - a, a, a, - a, a, a, - -a, a, a, - -a, a, -a, - }; - - U32 skybox_cube_vao; - glGenVertexArrays(1, &skybox_cube_vao); - glBindVertexArray(skybox_cube_vao); - glGenBuffers(1, &vbo); - glBindBuffer(GL_ARRAY_BUFFER, vbo); - glBufferData(GL_ARRAY_BUFFER, sizeof(skybox_cube_vertices), skybox_cube_vertices, GL_STATIC_DRAW); - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3*sizeof(F32), (void *)0); - glBindVertexArray(0); - - F32 normals_cube_vertices[] = { - -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, - - -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - - -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, - -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, - - 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, - - -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, - 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, - 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, - 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, - -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, - -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, - - -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, - 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, - 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, - 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, - -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, - -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f - }; - U32 normals_cube_vao; - glGenVertexArrays(1, &normals_cube_vao); - glBindVertexArray(normals_cube_vao); - glGenBuffers(1, &vbo); - glBindBuffer(GL_ARRAY_BUFFER, vbo); - glBufferData(GL_ARRAY_BUFFER, sizeof(normals_cube_vertices), normals_cube_vertices, GL_STATIC_DRAW); - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6*sizeof(F32), (void *)0); - glEnableVertexAttribArray(1); - glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6*sizeof(F32), (void *)(3*sizeof(F32))); - glBindVertexArray(0); - - F32 target_fps = 60.0f; - F32 target_spf = 1.0f/target_fps; - camera_pos = v3f(0.0f, 1.0f, 3.0f); - F32 yaw = 0.0f, pitch = 0.0f; - - F32 last_time = glfwGetTime(); - - glEnable(GL_DEPTH_TEST); - glDepthFunc(GL_LEQUAL); - - MAT4 view, projection; - view = mat4_make_translate(v3f_negate(camera_pos)); - view = mat4_rotate_angles(view, v3f(pitch, yaw, 0.0f)); - projection = perspective(90.0f, (F32)WIDTH/(F32)HEIGHT, 0.1f, 100.0f); - - while (!glfwWindowShouldClose(window)) - { - glfwPollEvents(); - - /* INFO(pryazha): update */ - - V3F left, up, forward; - - left = v3f(-view.m0.x, -view.m1.x, -view.m2.x); - up = v3f(view.m0.y, view.m1.y, view.m2.y); - forward = v3f(-view.m0.z, -view.m1.z, -view.m2.z); - - V3F dp = v3f_zero(); - F32 speed = 2.0f; - if (key_is_pressed(input.move_right)) - dp = v3f_add(dp, v3f_scalef(left, -speed*dt)); - if (key_is_pressed(input.move_forward)) - dp = v3f_add(dp, v3f_scalef(forward, speed*dt)); - if (key_is_pressed(input.move_left)) - dp = v3f_add(dp, v3f_scalef(left, speed*dt)); - if (key_is_pressed(input.move_backward)) - dp = v3f_add(dp, v3f_scalef(forward, -speed*dt)); - if (key_is_pressed(input.move_up)) - dp = v3f_add(dp, v3f_scalef(up, speed*dt)); - if (key_is_pressed(input.move_down)) - dp = v3f_add(dp, v3f_scalef(up, -speed*dt)); - - camera_pos = v3f_add(camera_pos, dp); - - /* NOTE(pryazha): Mouse handling */ - F32 sensitivity = 0.1f; - input.mouse_offset = v2f_scalef(input.mouse_offset, sensitivity); - yaw += input.mouse_offset.x; - pitch += input.mouse_offset.y; - if (pitch > 89.0f) - pitch = 89.0f; - if (pitch < -89.0f) - pitch = -89.0f; - - view = mat4_make_translate(v3f_negate(camera_pos)); - view = mat4_rotate_angles(view, v3f(pitch, yaw, 0.0f)); - - input_update_last_state(&input); - - /* NOTE(pryazha): Render */ - glClearColor(0.15f, 0.15f, 0.15f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - glUseProgram(cube_shader); - shader_set_mat4fv(cube_shader, "view", view); - shader_set_mat4fv(cube_shader, "projection", projection); - glBindTexture(GL_TEXTURE_2D, grid_texture); - - glBindVertexArray(cube_vao); - for (S32 transform_index = 0; - transform_index < (S32)ArrayCount(cube_positions); - ++transform_index) - { - shader_set_mat4fv(cube_shader, "model", transform_apply(cube_positions[transform_index])); - glDrawArrays(GL_TRIANGLES, 0, 36); - } - - shader_set_mat4fv(cube_shader, "model", transform_apply(platform_position)); - glDrawArrays(GL_TRIANGLES, 0, 36); - glBindVertexArray(0); - - glUseProgram(reflection_shader); - shader_set_mat4fv(reflection_shader, "model", mat4_make_translate(v3f(0.0f, 2.0f, 0.0f))); - shader_set_mat4fv(reflection_shader, "view", view); - shader_set_mat4fv(reflection_shader, "projection", projection); - shader_set_3fv(reflection_shader, "camera_pos", camera_pos); - glBindVertexArray(normals_cube_vao); - glBindTexture(GL_TEXTURE_CUBE_MAP, skybox_texture); - glDrawArrays(GL_TRIANGLES, 0, 36); - glBindTexture(GL_TEXTURE_CUBE_MAP, 0); - glBindVertexArray(0); - - glUseProgram(refraction_shader); - shader_set_mat4fv(refraction_shader, "model", mat4_make_translate(v3f(2.0f, 2.0f, 0.0f))); - shader_set_mat4fv(refraction_shader, "view", view); - shader_set_mat4fv(refraction_shader, "projection", projection); - shader_set_3fv(refraction_shader, "camera_pos", camera_pos); - glBindVertexArray(normals_cube_vao); - glBindTexture(GL_TEXTURE_CUBE_MAP, skybox_texture); - glDrawArrays(GL_TRIANGLES, 0, 36); - glBindTexture(GL_TEXTURE_CUBE_MAP, 0); - glBindVertexArray(0); - - glUseProgram(skybox_shader); - MAT4 rotate_view = mat4_identity(); - rotate_view.m0 = v4f(view.m0.x, view.m0.y, view.m0.z, 0.0f); - rotate_view.m1 = v4f(view.m1.x, view.m1.y, view.m1.z, 0.0f); - rotate_view.m2 = v4f(view.m2.x, view.m2.y, view.m2.z, 0.0f); - shader_set_mat4fv(skybox_shader, "view", rotate_view); - shader_set_mat4fv(skybox_shader, "projection", projection); - glBindVertexArray(skybox_cube_vao); - glBindTexture(GL_TEXTURE_CUBE_MAP, skybox_texture); - 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(); - dt = current_time-last_time; - last_time = current_time; - } - - glfwTerminate(); - return(0); + glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); + + if (glewInit() != GLEW_OK) { + fprintf(stderr, "[ERROR] Failed to initialize glew.\n"); + glfwTerminate(); + return(1); + } + + 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 grid_texture = load_texture("../../data/textures/grid.png"); + + const char *cube_texture_filenames[6] = { + "../../data/textures/skybox/right.jpg", + "../../data/textures/skybox/left.jpg", + "../../data/textures/skybox/top.jpg", + "../../data/textures/skybox/bottom.jpg", + "../../data/textures/skybox/front.jpg", + "../../data/textures/skybox/back.jpg" + }; + U32 skybox_texture = load_cubemap(cube_texture_filenames); + + 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.0f*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 cube_vao, vbo; + glGenVertexArrays(1, &cube_vao); + glBindVertexArray(cube_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); + + a = 1.0f; + F32 skybox_cube_vertices[] = { + -a, -a, -a, + a, -a, -a, + a, a, -a, + a, a, -a, + -a, a, -a, + -a, -a, -a, + + -a, -a, a, + a, -a, a, + a, a, a, + a, a, a, + -a, a, a, + -a, -a, a, + + -a, a, a, + -a, a, -a, + -a, -a, -a, + -a, -a, -a, + -a, -a, a, + -a, a, a, + + a, a, a, + a, a, -a, + a, -a, -a, + a, -a, -a, + a, -a, a, + a, a, a, + + -a, -a, -a, + a, -a, -a, + a, -a, a, + a, -a, a, + -a, -a, a, + -a, -a, -a, + + -a, a, -a, + a, a, -a, + a, a, a, + a, a, a, + -a, a, a, + -a, a, -a, + }; + + U32 skybox_cube_vao; + glGenVertexArrays(1, &skybox_cube_vao); + glBindVertexArray(skybox_cube_vao); + glGenBuffers(1, &vbo); + glBindBuffer(GL_ARRAY_BUFFER, vbo); + glBufferData(GL_ARRAY_BUFFER, sizeof(skybox_cube_vertices), skybox_cube_vertices, GL_STATIC_DRAW); + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3*sizeof(F32), (void *)0); + glBindVertexArray(0); + + F32 normals_cube_vertices[] = { + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, + + -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, + + 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + + -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, + -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, + + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f + }; + U32 normals_cube_vao; + glGenVertexArrays(1, &normals_cube_vao); + glBindVertexArray(normals_cube_vao); + glGenBuffers(1, &vbo); + glBindBuffer(GL_ARRAY_BUFFER, vbo); + glBufferData(GL_ARRAY_BUFFER, sizeof(normals_cube_vertices), normals_cube_vertices, GL_STATIC_DRAW); + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6*sizeof(F32), (void *)0); + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6*sizeof(F32), (void *)(3*sizeof(F32))); + glBindVertexArray(0); + + state.camera = (Camera) { + v3f(0.0f, 1.0f, 3.0f), 100.0f, + 0.1f, 100.0f, 0.0f, 0.0f + }; + input = input_init(); + + F32 target_fps = 60.0f; + F32 target_spf = 1.0f/target_fps; + F32 last_time = glfwGetTime(); + + while (!glfwWindowShouldClose(window)) { + glfwPollEvents(); + + /* INFO(pryazha): update */ + 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); + + V3F dv = get_dv_camera_first_person(&input, &state.camera, + 4.0f, state.dt); + state.camera.pos = v3f_add(state.camera.pos, dv); + + 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); + + /* NOTE(pryazha): Render */ + MAT4 view, proj, model; + view = get_view_matrix(&state.camera); + proj = perspective(state.camera.fovx, (F32)width/(F32)height, + state.camera.near, state.camera.far); + + glClearColor(0.15f, 0.15f, 0.15f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glUseProgram(cube_shader); + shader_set_mat4fv(cube_shader, "view", view); + shader_set_mat4fv(cube_shader, "proj", proj); + glBindTexture(GL_TEXTURE_2D, grid_texture); + glBindVertexArray(cube_vao); + for (S32 i = 0; i < (S32)ArrayCount(cube_positions); ++i) { + model = transform_apply(cube_positions[i]); + shader_set_mat4fv(cube_shader, "model", model); + glDrawArrays(GL_TRIANGLES, 0, 36); + } + + model = transform_apply(platform_transform); + shader_set_mat4fv(cube_shader, "model", model); + glDrawArrays(GL_TRIANGLES, 0, 36); + glBindVertexArray(0); + + glUseProgram(reflection_shader); + model = mat4_make_translate(v3f(0.0f, 2.0f, 0.0f)); + shader_set_mat4fv(reflection_shader, "model", model); + shader_set_mat4fv(reflection_shader, "view", view); + shader_set_mat4fv(reflection_shader, "proj", proj); + shader_set_3fv(reflection_shader, "camera_pos", state.camera.pos); + glBindVertexArray(normals_cube_vao); + glBindTexture(GL_TEXTURE_CUBE_MAP, skybox_texture); + glDrawArrays(GL_TRIANGLES, 0, 36); + glBindTexture(GL_TEXTURE_CUBE_MAP, 0); + glBindVertexArray(0); + + glUseProgram(refraction_shader); + model = mat4_make_translate(v3f(2.0f, 2.0f, 0.0f)); + shader_set_mat4fv(refraction_shader, "model", model); + shader_set_mat4fv(refraction_shader, "view", view); + shader_set_mat4fv(refraction_shader, "proj", proj); + shader_set_3fv(refraction_shader, "camera_pos", state.camera.pos); + glBindVertexArray(normals_cube_vao); + glBindTexture(GL_TEXTURE_CUBE_MAP, skybox_texture); + glDrawArrays(GL_TRIANGLES, 0, 36); + glBindTexture(GL_TEXTURE_CUBE_MAP, 0); + glBindVertexArray(0); + + glUseProgram(skybox_shader); + MAT4 rotate_view = mat4_identity(); + rotate_view.m0 = v4f(view.m0.x, view.m0.y, view.m0.z, 0.0f); + rotate_view.m1 = v4f(view.m1.x, view.m1.y, view.m1.z, 0.0f); + rotate_view.m2 = v4f(view.m2.x, view.m2.y, view.m2.z, 0.0f); + shader_set_mat4fv(skybox_shader, "view", rotate_view); + shader_set_mat4fv(skybox_shader, "proj", proj); + glBindVertexArray(skybox_cube_vao); + glBindTexture(GL_TEXTURE_CUBE_MAP, skybox_texture); + 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/4.face_culling/shaders/face_culling.fs b/advanced_opengl/6.cubemaps/shaders/cube.frag index f58c5d3..71892a7 100644 --- a/advanced_opengl/4.face_culling/shaders/face_culling.fs +++ b/advanced_opengl/6.cubemaps/shaders/cube.frag @@ -6,8 +6,7 @@ in vec2 tex_coords; uniform sampler2D texture1; -void -main(void) +void main(void) { frag_color = texture(texture1, tex_coords); } diff --git a/advanced_opengl/6.cubemaps/shaders/cube.vs b/advanced_opengl/6.cubemaps/shaders/cube.vert index aea5c2c..2436f35 100644 --- a/advanced_opengl/6.cubemaps/shaders/cube.vs +++ b/advanced_opengl/6.cubemaps/shaders/cube.vert @@ -5,13 +5,12 @@ layout(location = 1) in vec2 atex_coords; uniform mat4 model; uniform mat4 view; -uniform mat4 projection; +uniform mat4 proj; out vec2 tex_coords; -void -main(void) +void main(void) { - gl_Position = projection*view*model*vec4(apos, 1.0); + gl_Position = proj*view*model*vec4(apos, 1.0); tex_coords = atex_coords; } diff --git a/advanced_opengl/6.cubemaps/shaders/reflection.fs b/advanced_opengl/6.cubemaps/shaders/reflection.frag index 3723ea9..72b1c0d 100644 --- a/advanced_opengl/6.cubemaps/shaders/reflection.fs +++ b/advanced_opengl/6.cubemaps/shaders/reflection.frag @@ -8,8 +8,7 @@ out vec4 frag_color; uniform vec3 camera_pos; uniform samplerCube skybox; -void -main(void) +void main(void) { vec3 i = pos-camera_pos; vec3 r = reflect(i, normalize(normal)); diff --git a/advanced_opengl/6.cubemaps/shaders/reflection.vs b/advanced_opengl/6.cubemaps/shaders/reflection.vert index c9a0698..d7070f2 100644 --- a/advanced_opengl/6.cubemaps/shaders/reflection.vs +++ b/advanced_opengl/6.cubemaps/shaders/reflection.vert @@ -8,12 +8,11 @@ out vec3 normal; uniform mat4 model; uniform mat4 view; -uniform mat4 projection; +uniform mat4 proj; -void -main(void) +void main(void) { pos = vec3(model*vec4(apos, 1.0)); normal = mat3(transpose(inverse(model)))*anormal; - gl_Position = projection*view*model*vec4(apos, 1.0); + gl_Position = proj*view*model*vec4(apos, 1.0); } diff --git a/advanced_opengl/6.cubemaps/shaders/refraction.fs b/advanced_opengl/6.cubemaps/shaders/refraction.frag index ef8c415..fa01b2c 100644 --- a/advanced_opengl/6.cubemaps/shaders/refraction.fs +++ b/advanced_opengl/6.cubemaps/shaders/refraction.frag @@ -8,8 +8,7 @@ out vec4 frag_color; uniform vec3 camera_pos; uniform samplerCube skybox; -void -main(void) +void main(void) { float ratio = 1.0/1.52; vec3 i = pos-camera_pos; diff --git a/advanced_opengl/6.cubemaps/shaders/refraction.vs b/advanced_opengl/6.cubemaps/shaders/refraction.vert index c9a0698..d7070f2 100644 --- a/advanced_opengl/6.cubemaps/shaders/refraction.vs +++ b/advanced_opengl/6.cubemaps/shaders/refraction.vert @@ -8,12 +8,11 @@ out vec3 normal; uniform mat4 model; uniform mat4 view; -uniform mat4 projection; +uniform mat4 proj; -void -main(void) +void main(void) { pos = vec3(model*vec4(apos, 1.0)); normal = mat3(transpose(inverse(model)))*anormal; - gl_Position = projection*view*model*vec4(apos, 1.0); + gl_Position = proj*view*model*vec4(apos, 1.0); } diff --git a/advanced_opengl/6.cubemaps/shaders/skybox.fs b/advanced_opengl/6.cubemaps/shaders/skybox.frag index bf69c8b..22be301 100644 --- a/advanced_opengl/6.cubemaps/shaders/skybox.fs +++ b/advanced_opengl/6.cubemaps/shaders/skybox.frag @@ -6,8 +6,7 @@ out vec4 frag_color; uniform samplerCube skybox; -void -main(void) +void main(void) { frag_color = texture(skybox, tex_coords); } diff --git a/advanced_opengl/6.cubemaps/shaders/skybox.vs b/advanced_opengl/6.cubemaps/shaders/skybox.vert index c790148..c7d91c9 100644 --- a/advanced_opengl/6.cubemaps/shaders/skybox.vs +++ b/advanced_opengl/6.cubemaps/shaders/skybox.vert @@ -5,12 +5,11 @@ layout(location = 0) in vec3 apos; out vec3 tex_coords; uniform mat4 view; -uniform mat4 projection; +uniform mat4 proj; -void -main(void) +void main(void) { tex_coords = apos; - vec4 pos = projection*view*vec4(apos, 1.0); + vec4 pos = proj*view*vec4(apos, 1.0); gl_Position = pos.xyww; } diff --git a/advanced_opengl/8.geometry_shader/shaders/normals.fs b/advanced_opengl/7.uniform_buffer/shaders/color_cube.frag index fbbafbf..d40d866 100644 --- a/advanced_opengl/8.geometry_shader/shaders/normals.fs +++ b/advanced_opengl/7.uniform_buffer/shaders/color_cube.frag @@ -2,8 +2,7 @@ out vec4 frag_color; -void -main(void) +void main(void) { frag_color = vec4(1.0, 0.0, 0.0, 1.0); } diff --git a/advanced_opengl/7.uniform_buffer/shaders/color_cube.vs b/advanced_opengl/7.uniform_buffer/shaders/color_cube.vert index 17a3448..67226f8 100644 --- a/advanced_opengl/7.uniform_buffer/shaders/color_cube.vs +++ b/advanced_opengl/7.uniform_buffer/shaders/color_cube.vert @@ -3,14 +3,13 @@ layout(location = 0) in vec3 apos; layout(std140) uniform Matrices { - mat4 projection; + mat4 proj; mat4 view; }; uniform mat4 model; -void -main(void) +void main(void) { - gl_Position = projection*view*model*vec4(apos, 1.0); + gl_Position = proj*view*model*vec4(apos, 1.0); } diff --git a/advanced_opengl/7.uniform_buffer/shaders/cube.frag b/advanced_opengl/7.uniform_buffer/shaders/cube.frag new file mode 100644 index 0000000..71892a7 --- /dev/null +++ b/advanced_opengl/7.uniform_buffer/shaders/cube.frag @@ -0,0 +1,12 @@ +#version 330 core + +out vec4 frag_color; + +in vec2 tex_coords; + +uniform sampler2D texture1; + +void main(void) +{ + frag_color = texture(texture1, tex_coords); +} diff --git a/advanced_opengl/7.uniform_buffer/shaders/cube.fs b/advanced_opengl/7.uniform_buffer/shaders/cube.fs deleted file mode 100644 index f58c5d3..0000000 --- a/advanced_opengl/7.uniform_buffer/shaders/cube.fs +++ /dev/null @@ -1,13 +0,0 @@ -#version 330 core - -out vec4 frag_color; - -in vec2 tex_coords; - -uniform sampler2D texture1; - -void -main(void) -{ - frag_color = texture(texture1, tex_coords); -} diff --git a/advanced_opengl/7.uniform_buffer/shaders/cube.vs b/advanced_opengl/7.uniform_buffer/shaders/cube.vert index 054164d..ec90f37 100644 --- a/advanced_opengl/7.uniform_buffer/shaders/cube.vs +++ b/advanced_opengl/7.uniform_buffer/shaders/cube.vert @@ -5,7 +5,7 @@ layout(location = 1) in vec2 atex_coords; layout(std140) uniform Matrices { - uniform mat4 projection; + uniform mat4 proj; uniform mat4 view; }; @@ -13,9 +13,8 @@ uniform mat4 model; out vec2 tex_coords; -void -main(void) +void main(void) { - gl_Position = projection*view*model*vec4(apos, 1.0); + gl_Position = proj*view*model*vec4(apos, 1.0); tex_coords = atex_coords; } diff --git a/advanced_opengl/7.uniform_buffer/shaders/skybox.fs b/advanced_opengl/7.uniform_buffer/shaders/skybox.frag index bf69c8b..22be301 100644 --- a/advanced_opengl/7.uniform_buffer/shaders/skybox.fs +++ b/advanced_opengl/7.uniform_buffer/shaders/skybox.frag @@ -6,8 +6,7 @@ out vec4 frag_color; uniform samplerCube skybox; -void -main(void) +void main(void) { frag_color = texture(skybox, tex_coords); } diff --git a/advanced_opengl/7.uniform_buffer/shaders/skybox.vs b/advanced_opengl/7.uniform_buffer/shaders/skybox.vert index 03b2171..ddbeb21 100644 --- a/advanced_opengl/7.uniform_buffer/shaders/skybox.vs +++ b/advanced_opengl/7.uniform_buffer/shaders/skybox.vert @@ -6,14 +6,13 @@ out vec3 tex_coords; layout(std140) uniform Matrices { - uniform mat4 projection; + uniform mat4 proj; uniform mat4 view; }; -void -main(void) +void main(void) { tex_coords = apos; - vec4 pos = projection*view*vec4(apos, 1.0); + vec4 pos = proj*view*vec4(apos, 1.0); gl_Position = pos.xyww; } diff --git a/advanced_opengl/7.uniform_buffer/uniform_buffer b/advanced_opengl/7.uniform_buffer/uniform_buffer Binary files differindex 57aa64d..154fb08 100755 --- a/advanced_opengl/7.uniform_buffer/uniform_buffer +++ b/advanced_opengl/7.uniform_buffer/uniform_buffer diff --git a/advanced_opengl/7.uniform_buffer/uniform_buffer.c b/advanced_opengl/7.uniform_buffer/uniform_buffer.c index e67b5c9..a27c115 100644 --- a/advanced_opengl/7.uniform_buffer/uniform_buffer.c +++ b/advanced_opengl/7.uniform_buffer/uniform_buffer.c @@ -2,391 +2,302 @@ #include "GLFW/glfw3.h" #include "pwyazh.h" - #include "pwyazh_GL.h" #include "common.h" -#include <unistd.h> +int main(void) +{ + GLFWwindow *window; + State state; + S32 width, height; + Input input; -#define WIDTH 1024 -#define HEIGHT 768 + if (glfwInit() == GLFW_FALSE) { + fprintf(stderr, "[ERROR] Failed to initialize glfw.\n"); + return(1); + } -static V3F camera_pos; -static F32 dt; -static Input input; -static B32 first_mouse = 1; + width = 1024; + height = 768; -void -key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) -{ - switch (action) - { - case GLFW_PRESS: { - switch (key) - { - case GLFW_KEY_D: { - input.move_right.state = KeyState_PRESS; - } break; - case GLFW_KEY_W: { - input.move_forward.state = KeyState_PRESS; - } break; - case GLFW_KEY_A: { - input.move_left.state = KeyState_PRESS; - } break; - case GLFW_KEY_S: { - input.move_backward.state = KeyState_PRESS; - } break; - case GLFW_KEY_E: { - input.move_up.state = KeyState_PRESS; - } break; - case GLFW_KEY_Q: { - input.move_down.state = KeyState_PRESS; - } break; - } - } break; - - case GLFW_RELEASE: { - switch (key) - { - case GLFW_KEY_D: { - input.move_right.state = KeyState_RELEASE; - } break; - case GLFW_KEY_W: { - input.move_forward.state = KeyState_RELEASE; - } break; - case GLFW_KEY_A: { - input.move_left.state = KeyState_RELEASE; - } break; - case GLFW_KEY_S: { - input.move_backward.state = KeyState_RELEASE; - } break; - case GLFW_KEY_E: { - input.move_up.state = KeyState_RELEASE; - } break; - case GLFW_KEY_Q: { - input.move_down.state = KeyState_RELEASE; - } break; - } - } break; - } -} + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); + glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); + window = glfwCreateWindow(width, height, "Advanced data (uniform buffer)", 0, 0); + if (!window) { + fprintf(stderr, "[ERROR] Failed to create window.\n"); + glfwTerminate(); + return(1); + } -void -cursor_pos_callback(GLFWwindow* window, double xpos, double ypos) -{ - if (first_mouse) - { - input.last_mouse_pos = v2f(xpos, ypos); - first_mouse = 0; - } - input.mouse_offset = v2f(input.mouse_offset.x+((F32)xpos-input.last_mouse_pos.x), - input.mouse_offset.y+((F32)ypos-input.last_mouse_pos.y)); - input.last_mouse_pos = v2f((F32)xpos, (F32)ypos); -} + glfwMakeContextCurrent(window); -int -main(void) -{ - GLFWwindow *window; - - if (glfwInit() == GLFW_FALSE) - { - fprintf(stderr, "[ERROR] Failed to initialize glfw.\n"); - return(1); - } - - glfwWindowHint(GLFW_RESIZABLE, 0); - glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); - glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); - window = glfwCreateWindow(WIDTH, HEIGHT, "Advanced data (uniform buffer)", 0, 0); - if (!window) - { - fprintf(stderr, "[ERROR] Failed to create window.\n"); - glfwTerminate(); - return(1); - } - - glfwMakeContextCurrent(window); - - glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); - - glfwSetKeyCallback(window, key_callback); - glfwSetCursorPosCallback(window, cursor_pos_callback); - - if (glewInit() != GLEW_OK) - { - fprintf(stderr, "[ERROR] Failed to initialize glew.\n"); - glfwTerminate(); - return(1); - } - - U32 skybox_shader = create_shader_program("shaders/skybox.vs", "shaders/skybox.fs"); - U32 cube_shader = create_shader_program("shaders/cube.vs", "shaders/cube.fs"); - U32 color_cube_shader = create_shader_program("shaders/color_cube.vs", - "shaders/color_cube.fs"); - - U32 skybox_matrices = glGetUniformBlockIndex(skybox_shader, "Matrices"); - U32 cube_matrices = glGetUniformBlockIndex(cube_shader, "Matrices"); - U32 color_cube_matrices = glGetUniformBlockIndex(color_cube_shader, "Matrices"); - - glUniformBlockBinding(skybox_shader, skybox_matrices, 0); - glUniformBlockBinding(cube_shader, cube_matrices, 0); - glUniformBlockBinding(color_cube_shader, color_cube_matrices, 0); - - U32 matrices_ubo; - glGenBuffers(1, &matrices_ubo); - glBindBuffer(GL_UNIFORM_BUFFER, matrices_ubo); - glBufferData(GL_UNIFORM_BUFFER, 2*sizeof(MAT4), 0, GL_STATIC_DRAW); - glBindBuffer(GL_UNIFORM_BUFFER, 0); - glBindBufferRange(GL_UNIFORM_BUFFER, 0, matrices_ubo, 0, 2*sizeof(MAT4)); - - U32 grid_texture = load_texture("../../data/textures/grid.png"); - - const char *cube_texture_filenames[6] = { - "../../data/textures/skybox/right.jpg", - "../../data/textures/skybox/left.jpg", - "../../data/textures/skybox/top.jpg", - "../../data/textures/skybox/bottom.jpg", - "../../data/textures/skybox/front.jpg", - "../../data/textures/skybox/back.jpg" - }; - U32 skybox_texture = load_cubemap(cube_texture_filenames); - - 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 platform_position = - transform_make_scale_translate(v3f(10.0f, 0.2f, 10.0f), - v3f(0.0f, -(a+(a*0.2f)+0.01f), 0.0f)); - - U32 cube_vao, vbo; - glGenVertexArrays(1, &cube_vao); - glBindVertexArray(cube_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); - - a = 1.0f; - F32 skybox_cube_vertices[] = { - -a, -a, -a, - a, -a, -a, - a, a, -a, - a, a, -a, - -a, a, -a, - -a, -a, -a, - - -a, -a, a, - a, -a, a, - a, a, a, - a, a, a, - -a, a, a, - -a, -a, a, - - -a, a, a, - -a, a, -a, - -a, -a, -a, - -a, -a, -a, - -a, -a, a, - -a, a, a, - - a, a, a, - a, a, -a, - a, -a, -a, - a, -a, -a, - a, -a, a, - a, a, a, - - -a, -a, -a, - a, -a, -a, - a, -a, a, - a, -a, a, - -a, -a, a, - -a, -a, -a, - - -a, a, -a, - a, a, -a, - a, a, a, - a, a, a, - -a, a, a, - -a, a, -a, - }; - - U32 skybox_cube_vao; - glGenVertexArrays(1, &skybox_cube_vao); - glBindVertexArray(skybox_cube_vao); - glGenBuffers(1, &vbo); - glBindBuffer(GL_ARRAY_BUFFER, vbo); - glBufferData(GL_ARRAY_BUFFER, sizeof(skybox_cube_vertices), skybox_cube_vertices, GL_STATIC_DRAW); - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3*sizeof(F32), (void *)0); - glBindVertexArray(0); - - F32 target_fps = 60.0f; - F32 target_spf = 1.0f/target_fps; - camera_pos = v3f(0.0f, 1.0f, 3.0f); - F32 yaw = 0.0f, pitch = 0.0f; - - F32 last_time = glfwGetTime(); - - glEnable(GL_DEPTH_TEST); - glDepthFunc(GL_LEQUAL); - - MAT4 view, projection; - projection = perspective(90.0f, (F32)WIDTH/(F32)HEIGHT, 0.1f, 100.0f); - glBindBuffer(GL_UNIFORM_BUFFER, matrices_ubo); - glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(MAT4), (const void *)&projection); - glBindBuffer(GL_UNIFORM_BUFFER, 0); - view = mat4_make_translate(v3f_negate(camera_pos)); - view = mat4_rotate_angles(view, v3f(pitch, yaw, 0.0f)); - - while (!glfwWindowShouldClose(window)) - { - glfwPollEvents(); - - /* INFO(pryazha): update */ - - V3F left, up, forward; - - left = v3f(-view.m0.x, -view.m1.x, -view.m2.x); - up = v3f(view.m0.y, view.m1.y, view.m2.y); - forward = v3f(-view.m0.z, -view.m1.z, -view.m2.z); - - V3F dp = v3f_zero(); - F32 speed = 2.0f; - if (key_is_pressed(input.move_right)) - dp = v3f_add(dp, v3f_scalef(left, -speed*dt)); - if (key_is_pressed(input.move_forward)) - dp = v3f_add(dp, v3f_scalef(forward, speed*dt)); - if (key_is_pressed(input.move_left)) - dp = v3f_add(dp, v3f_scalef(left, speed*dt)); - if (key_is_pressed(input.move_backward)) - dp = v3f_add(dp, v3f_scalef(forward, -speed*dt)); - if (key_is_pressed(input.move_up)) - dp = v3f_add(dp, v3f_scalef(up, speed*dt)); - if (key_is_pressed(input.move_down)) - dp = v3f_add(dp, v3f_scalef(up, -speed*dt)); - input_update_last_state(&input); - camera_pos = v3f_add(camera_pos, dp); - - /* NOTE(pryazha): Mouse handling */ - F32 sensitivity = 0.1f; - input.mouse_offset = v2f_scalef(input.mouse_offset, sensitivity); - yaw += input.mouse_offset.x; - pitch += input.mouse_offset.y; - if (pitch > 89.0f) - pitch = 89.0f; - if (pitch < -89.0f) - pitch = -89.0f; - input.mouse_offset = v2f_zero(); - - view = mat4_make_translate(v3f_negate(camera_pos)); - view = mat4_rotate_angles(view, v3f(pitch, yaw, 0.0f)); - glBindBuffer(GL_UNIFORM_BUFFER, matrices_ubo); - glBufferSubData(GL_UNIFORM_BUFFER, sizeof(MAT4), sizeof(MAT4), (const void *)&view); - glBindBuffer(GL_UNIFORM_BUFFER, 0); - - /* NOTE(pryazha): Render */ - glClearColor(0.15f, 0.15f, 0.15f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - glUseProgram(cube_shader); - shader_set_mat4fv(cube_shader, "model", mat4_make_translate(v3f(-2.0f, 0.0f, 0.0f))); - glBindTexture(GL_TEXTURE_2D, grid_texture); - glBindVertexArray(cube_vao); - glDrawArrays(GL_TRIANGLES, 0, 36); - glBindTexture(GL_TEXTURE_2D, 0); - glBindVertexArray(0); - - glUseProgram(cube_shader); - shader_set_mat4fv(cube_shader, "model", transform_apply(platform_position)); - glBindTexture(GL_TEXTURE_2D, grid_texture); - glBindVertexArray(cube_vao); - glDrawArrays(GL_TRIANGLES, 0, 36); - glBindTexture(GL_TEXTURE_2D, 0); - glBindVertexArray(0); - - glUseProgram(color_cube_shader); - shader_set_mat4fv(cube_shader, "model", mat4_make_translate(v3f(2.0f, 0.0f, 0.0f))); - glBindVertexArray(cube_vao); - glDrawArrays(GL_TRIANGLES, 0, 36); - glBindVertexArray(0); - - glUseProgram(skybox_shader); - MAT4 rotate_view = mat4_identity(); - rotate_view.m0 = v4f(view.m0.x, view.m0.y, view.m0.z, 0.0f); - rotate_view.m1 = v4f(view.m1.x, view.m1.y, view.m1.z, 0.0f); - rotate_view.m2 = v4f(view.m2.x, view.m2.y, view.m2.z, 0.0f); - glBindBuffer(GL_UNIFORM_BUFFER, matrices_ubo); - glBufferSubData(GL_UNIFORM_BUFFER, sizeof(MAT4), sizeof(MAT4), (const void *)&rotate_view); - glBindBuffer(GL_UNIFORM_BUFFER, 0); - glBindVertexArray(skybox_cube_vao); - glBindTexture(GL_TEXTURE_CUBE_MAP, skybox_texture); - 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(); - dt = current_time-last_time; - last_time = current_time; - } - - glfwTerminate(); - return(0); + glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); + + if (glewInit() != GLEW_OK) { + fprintf(stderr, "[ERROR] Failed to initialize glew.\n"); + glfwTerminate(); + return(1); + } + + 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_matrices = glGetUniformBlockIndex(skybox_shader, "Matrices"); + U32 cube_matrices = glGetUniformBlockIndex(cube_shader, "Matrices"); + U32 color_cube_matrices = glGetUniformBlockIndex(color_cube_shader, "Matrices"); + + glUniformBlockBinding(skybox_shader, skybox_matrices, 0); + glUniformBlockBinding(cube_shader, cube_matrices, 0); + glUniformBlockBinding(color_cube_shader, color_cube_matrices, 0); + + U32 matrices_ubo; + glGenBuffers(1, &matrices_ubo); + glBindBuffer(GL_UNIFORM_BUFFER, matrices_ubo); + glBufferData(GL_UNIFORM_BUFFER, 2*sizeof(MAT4), 0, GL_STATIC_DRAW); + glBindBuffer(GL_UNIFORM_BUFFER, 0); + glBindBufferRange(GL_UNIFORM_BUFFER, 0, matrices_ubo, 0, 2*sizeof(MAT4)); + + U32 grid_texture = load_texture("../../data/textures/grid.png"); + + const char *cube_texture_filenames[6] = { + "../../data/textures/skybox/right.jpg", + "../../data/textures/skybox/left.jpg", + "../../data/textures/skybox/top.jpg", + "../../data/textures/skybox/bottom.jpg", + "../../data/textures/skybox/front.jpg", + "../../data/textures/skybox/back.jpg" + }; + + U32 skybox_texture = load_cubemap(cube_texture_filenames); + + 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 + }; + + 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 cube_vao, vbo; + glGenVertexArrays(1, &cube_vao); + glBindVertexArray(cube_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); + + a = 1.0f; + F32 skybox_cube_vertices[] = { + -a, -a, -a, + a, -a, -a, + a, a, -a, + a, a, -a, + -a, a, -a, + -a, -a, -a, + + -a, -a, a, + a, -a, a, + a, a, a, + a, a, a, + -a, a, a, + -a, -a, a, + + -a, a, a, + -a, a, -a, + -a, -a, -a, + -a, -a, -a, + -a, -a, a, + -a, a, a, + + a, a, a, + a, a, -a, + a, -a, -a, + a, -a, -a, + a, -a, a, + a, a, a, + + -a, -a, -a, + a, -a, -a, + a, -a, a, + a, -a, a, + -a, -a, a, + -a, -a, -a, + + -a, a, -a, + a, a, -a, + a, a, a, + a, a, a, + -a, a, a, + -a, a, -a, + }; + + U32 skybox_cube_vao; + glGenVertexArrays(1, &skybox_cube_vao); + glBindVertexArray(skybox_cube_vao); + glGenBuffers(1, &vbo); + glBindBuffer(GL_ARRAY_BUFFER, vbo); + glBufferData(GL_ARRAY_BUFFER, sizeof(skybox_cube_vertices), skybox_cube_vertices, GL_STATIC_DRAW); + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3*sizeof(F32), (void *)0); + glBindVertexArray(0); + + state.camera = (Camera) { + v3f(0.0f, 1.0f, 3.0f), 100.0f, + 0.1f, 100.0f, 0.0f, 0.0f + }; + input = input_init(); + + F32 target_fps = 60.0f; + F32 target_spf = 1.0f/target_fps; + F32 last_time = glfwGetTime(); + + while (!glfwWindowShouldClose(window)) { + glfwPollEvents(); + + /* INFO(pryazha): Update */ + 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); + + V3F dv = get_dv_camera_first_person(&input, &state.camera, + 4.0f, state.dt); + state.camera.pos = v3f_add(state.camera.pos, dv); + + 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); + + /* NOTE(pryazha): Render */ + MAT4 view, proj, model; + view = get_view_matrix(&state.camera); + proj = perspective(state.camera.fovx, (F32)width/(F32)height, + state.camera.near, state.camera.far); + + glBindBuffer(GL_UNIFORM_BUFFER, matrices_ubo); + 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); + glBindBuffer(GL_UNIFORM_BUFFER, 0); + + glClearColor(0.15f, 0.15f, 0.15f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glUseProgram(cube_shader); + model = mat4_make_translate(v3f(-2.0f, 0.0f, 0.0f)); + shader_set_mat4fv(cube_shader, "model", model); + glBindTexture(GL_TEXTURE_2D, grid_texture); + glBindVertexArray(cube_vao); + glDrawArrays(GL_TRIANGLES, 0, 36); + glBindTexture(GL_TEXTURE_2D, 0); + glBindVertexArray(0); + + glUseProgram(cube_shader); + model = transform_apply(platform_transform); + shader_set_mat4fv(cube_shader, "model", model); + glBindTexture(GL_TEXTURE_2D, grid_texture); + glBindVertexArray(cube_vao); + glDrawArrays(GL_TRIANGLES, 0, 36); + glBindTexture(GL_TEXTURE_2D, 0); + glBindVertexArray(0); + + glUseProgram(color_cube_shader); + model = mat4_make_translate(v3f(2.0f, 0.0f, 0.0f)); + shader_set_mat4fv(cube_shader, "model", model); + glBindVertexArray(cube_vao); + glDrawArrays(GL_TRIANGLES, 0, 36); + glBindVertexArray(0); + + glUseProgram(skybox_shader); + MAT4 rotate_view = mat4_identity(); + rotate_view.m0 = v4f(view.m0.x, view.m0.y, view.m0.z, 0.0f); + rotate_view.m1 = v4f(view.m1.x, view.m1.y, view.m1.z, 0.0f); + rotate_view.m2 = v4f(view.m2.x, view.m2.y, view.m2.z, 0.0f); + glBindBuffer(GL_UNIFORM_BUFFER, matrices_ubo); + glBufferSubData(GL_UNIFORM_BUFFER, sizeof(MAT4), sizeof(MAT4), + (const void *)&rotate_view); + glBindBuffer(GL_UNIFORM_BUFFER, 0); + glBindVertexArray(skybox_cube_vao); + glBindTexture(GL_TEXTURE_CUBE_MAP, skybox_texture); + 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/8.geometry_shader/geometry_shader b/advanced_opengl/8.geometry_shader/geometry_shader Binary files differindex 77fcab4..0bea785 100755 --- a/advanced_opengl/8.geometry_shader/geometry_shader +++ b/advanced_opengl/8.geometry_shader/geometry_shader diff --git a/advanced_opengl/8.geometry_shader/geometry_shader.c b/advanced_opengl/8.geometry_shader/geometry_shader.c index 678708c..f242709 100644 --- a/advanced_opengl/8.geometry_shader/geometry_shader.c +++ b/advanced_opengl/8.geometry_shader/geometry_shader.c @@ -2,338 +2,299 @@ #include "GLFW/glfw3.h" #include "pwyazh.h" - #include "pwyazh_GL.h" #include "common.h" -#include <unistd.h> - -#define WIDTH 1024 -#define HEIGHT 768 - -static F32 dt; -static Input input; - -void -key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) +void draw_cube(U32 cube_vao, U32 texture) { - switch (action) - { - case GLFW_PRESS: { - switch (key) - { - case GLFW_KEY_SPACE: { - input.jump.state = KeyState_PRESS; - } break; - } - } break; - - case GLFW_RELEASE: { - switch (key) - { - case GLFW_KEY_SPACE: { - input.jump.state = KeyState_RELEASE; - } break; - } - } break; - } + glBindVertexArray(cube_vao); + glBindTexture(GL_TEXTURE_2D, texture); + glDrawArrays(GL_TRIANGLES, 0, 36); + glBindTexture(GL_TEXTURE_2D, 0); + glBindVertexArray(0); } -void -draw_cube(U32 cube_vao, U32 texture) +int main(void) { - glBindVertexArray(cube_vao); - glBindTexture(GL_TEXTURE_2D, texture); - glDrawArrays(GL_TRIANGLES, 0, 36); - glBindTexture(GL_TEXTURE_2D, 0); - glBindVertexArray(0); -} + GLFWwindow *window; + State state; + S32 width, height; + Input input; -int -main(void) -{ - GLFWwindow *window; - - if (glfwInit() == GLFW_FALSE) - { - fprintf(stderr, "[ERROR] Failed to initialize glfw.\n"); - return(1); - } - - glfwWindowHint(GLFW_RESIZABLE, 0); - 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); - - glfwSetKeyCallback(window, key_callback); - - if (glewInit() != GLEW_OK) - { - fprintf(stderr, "[ERROR] Failed to initialize glew.\n"); - glfwTerminate(); - return(1); - } - - glEnable(GL_DEPTH_TEST); - - U32 shader = create_shader_program_geom("shaders/base.vs", - "shaders/base.fs", - "shaders/base.gs"); - U32 explosion_shader = create_shader_program_geom("shaders/explosion.vs", - "shaders/explosion.fs", - "shaders/explosion.gs"); - U32 normals_shader = create_shader_program_geom("shaders/normals.vs", - "shaders/normals.fs", - "shaders/normals.gs"); - U32 basic_shader = create_shader_program("shaders/basic.vs", "shaders/basic.fs"); - - U32 grid_texture = load_texture("../../data/textures/grid.png"); - - F32 points[] = { - -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, - 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, - 0.5f, -0.5f, 0.0f, 0.0f, 1.0f, - -0.5f, -0.5f, 1.0f, 1.0f, 0.0f - }; - - GLuint points_vao, vbo; - glGenVertexArrays(1, &points_vao); - glBindVertexArray(points_vao); - glGenBuffers(1, &vbo); - glBindBuffer(GL_ARRAY_BUFFER, vbo); - glBufferData(GL_ARRAY_BUFFER, sizeof(points), points, GL_STATIC_DRAW); - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 5*sizeof(F32), (void *)0); - glEnableVertexAttribArray(1); - glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 5*sizeof(F32), (void *)(2*sizeof(F32))); - glBindVertexArray(0); - - F32 a = 0.5f; - /* NOTE(pryazha): Counter-clockwise order */ - F32 cube_vertices[] = { - /* NOTE(pryazha): Back face */ - a, -a, -a, 0.0f, 0.0f, /* bottom-left */ - -a, a, -a, 1.0f, 1.0f, /* top-right */ - a, a, -a, 0.0f, 1.0f, /* top-left */ - a, -a, -a, 0.0f, 0.0f, /* bottom-left */ - -a, -a, -a, 1.0f, 0.0f, /* bottom-right */ - -a, a, -a, 1.0f, 1.0f, /* top-right */ - - /* NOTE(pryazha): Front face */ - -a, -a, a, 0.0f, 0.0f, /* bottom-left */ - a, a, a, 1.0f, 1.0f, /* top-right */ - -a, a, a, 0.0f, 1.0f, /* top-left */ - -a, -a, a, 0.0f, 0.0f, /* bottom-left */ - a, -a, a, 1.0f, 0.0f, /* bottom-right */ - a, a, a, 1.0f, 1.0f, /* top-right */ - - /* NOTE(pryazha): Left face */ - -a, -a, -a, 0.0f, 0.0f, /* bottom-left */ - -a, a, a, 1.0f, 1.0f, /* top-right */ - -a, a, -a, 0.0f, 1.0f, /* top-left */ - -a, -a, -a, 0.0f, 0.0f, /* bottom-left */ - -a, -a, a, 1.0f, 0.0f, /* bottom-right */ - -a, a, a, 1.0f, 1.0f, /* top-right */ - - /* NOTE(pryazha): Right face */ - a, -a, a, 0.0f, 0.0f, /* bottom-left */ - a, a, -a, 1.0f, 1.0f, /* top-right */ - a, a, a, 0.0f, 1.0f, /* top-left */ - a, -a, a, 0.0f, 0.0f, /* bottom-left */ - a, -a, -a, 1.0f, 0.0f, /* bottom-right */ - a, a, -a, 1.0f, 1.0f, /* top-right */ - - /* NOTE(pryazha): Top face */ - -a, a, a, 0.0f, 0.0f, /* bottom-left */ - a, a, -a, 1.0f, 1.0f, /* top-right */ - -a, a, -a, 0.0f, 1.0f, /* top-left */ - -a, a, a, 0.0f, 0.0f, /* bottom-left */ - a, a, a, 1.0f, 0.0f, /* bottom-right */ - a, a, -a, 1.0f, 1.0f, /* top-right */ - - /* NOTE(pryazha): Bottom face */ - -a, -a, -a, 0.0f, 0.0f, /* bottom-left */ - a, -a, a, 1.0f, 1.0f, /* top-right */ - -a, -a, a, 0.0f, 1.0f, /* top-left */ - -a, -a, -a, 0.0f, 0.0f, /* bottom-left */ - a, -a, -a, 1.0f, 0.0f, /* bottom-right */ - a, -a, a, 1.0f, 1.0f, /* top-right */ - }; - - U32 cube_vao; - glGenVertexArrays(1, &cube_vao); - glBindVertexArray(cube_vao); - glGenBuffers(1, &vbo); - glBindBuffer(GL_ARRAY_BUFFER, vbo); - glBufferData(GL_ARRAY_BUFFER, sizeof(cube_vertices), cube_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); - - F32 vertices[] = { - -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, - 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f, - 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f, - 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f, - -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, - -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, - - -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, - 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, - 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, - 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, - -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, - -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, - - -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f, - -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, - -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, - -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, - -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, - -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f, - - 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, - 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, - 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, - 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, - 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, - 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, - - -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f, - 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 1.0f, - 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f, - 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f, - -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, - -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f, - - -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, - 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, - 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, - 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, - -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, - -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f - }; - - U32 normals_cube_vao; - glGenVertexArrays(1, &normals_cube_vao); - glBindVertexArray(normals_cube_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, 8*sizeof(F32), (void *)0); - glEnableVertexAttribArray(1); - glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8*sizeof(F32), (void *)(3*sizeof(F32))); - glEnableVertexAttribArray(2); - glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8*sizeof(F32), (void *)(6*sizeof(F32))); - glBindVertexArray(0); - - F32 target_fps = 60.0f; - F32 target_spf = 1.0f/target_fps; - - F32 last_time = glfwGetTime(); - F32 time = last_time; - - S32 scene = 0; - - while (!glfwWindowShouldClose(window)) - { - glfwPollEvents(); - - /* NOTE(pryazha): Update */ - if (key_first_press(input.jump)) - { - scene++; - scene %= 3; - } - - input_update_last_state(&input); - - /* NOTE(pryazha): Render */ - glClearColor(0.15f, 0.15f, 0.15f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - if (scene == 0) - { - glUseProgram(shader); - glBindVertexArray(points_vao); - glDrawArrays(GL_POINTS, 0, 4); - glBindVertexArray(0); - } - else if (scene == 1) - { - F32 radius = 2.0f; - F32 x = f32_sin(0.5*time)*radius; - F32 z = f32_cos(0.5*time)*radius; - MAT4 projection = perspective(90.0f, (F32)WIDTH/(F32)HEIGHT, 0.1f, 100.0f); - MAT4 view = look_at(v3f(x, 1.0f, z), v3f_zero(), v3f(0.0f, 1.0f, 0.0f)); - MAT4 model = mat4_identity(); - glUseProgram(explosion_shader); - shader_set_mat4fv(explosion_shader, "projection", projection); - shader_set_mat4fv(explosion_shader, "view", view); - shader_set_mat4fv(explosion_shader, "model", model); - shader_set_1f(explosion_shader, "time", time); - glBindVertexArray(cube_vao); - glBindTexture(GL_TEXTURE_2D, grid_texture); - glDrawArrays(GL_TRIANGLES, 0, 36); - glBindVertexArray(0); - } - else - { - MAT4 projection, view, model; - F32 radius, x, z; - - radius = 2.0f; - x = f32_sin(0.5*time)*radius; - z = f32_cos(0.5*time)*radius; - - projection = perspective(90.0f, (F32)WIDTH/(F32)HEIGHT, 0.1f, 100.0f); - view = look_at(v3f(x, 1.0f, z), v3f_zero(), v3f(0.0f, 1.0f, 0.0f)); - model = mat4_identity(); - - glUseProgram(basic_shader); - shader_set_mat4fv(basic_shader, "projection", projection); - shader_set_mat4fv(basic_shader, "view", view); - shader_set_mat4fv(basic_shader, "model", model); - draw_cube(normals_cube_vao, grid_texture); - - glUseProgram(normals_shader); - shader_set_mat4fv(normals_shader, "projection", projection); - shader_set_mat4fv(normals_shader, "view", view); - shader_set_mat4fv(normals_shader, "model", model); - draw_cube(normals_cube_vao, grid_texture); - } - - 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(); - dt = current_time-last_time; - time += dt; - last_time = current_time; - } - - glDeleteBuffers(1, &vbo); - glDeleteVertexArrays(1, &points_vao); - - glfwTerminate(); - return(0); + 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); + + 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 grid_texture = load_texture("../../data/textures/grid.png"); + + F32 points[] = { + -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, + 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, -0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, -0.5f, 1.0f, 1.0f, 0.0f + }; + + GLuint points_vao, vbo; + glGenVertexArrays(1, &points_vao); + glBindVertexArray(points_vao); + glGenBuffers(1, &vbo); + glBindBuffer(GL_ARRAY_BUFFER, vbo); + glBufferData(GL_ARRAY_BUFFER, sizeof(points), points, GL_STATIC_DRAW); + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 5*sizeof(F32), (void *)0); + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 5*sizeof(F32), (void *)(2*sizeof(F32))); + glBindVertexArray(0); + + F32 a = 0.5f; + /* NOTE(pryazha): Counter-clockwise order */ + F32 cube_vertices[] = { + /* NOTE(pryazha): Back face */ + a, -a, -a, 0.0f, 0.0f, /* bottom-left */ + -a, a, -a, 1.0f, 1.0f, /* top-right */ + a, a, -a, 0.0f, 1.0f, /* top-left */ + a, -a, -a, 0.0f, 0.0f, /* bottom-left */ + -a, -a, -a, 1.0f, 0.0f, /* bottom-right */ + -a, a, -a, 1.0f, 1.0f, /* top-right */ + + /* NOTE(pryazha): Front face */ + -a, -a, a, 0.0f, 0.0f, /* bottom-left */ + a, a, a, 1.0f, 1.0f, /* top-right */ + -a, a, a, 0.0f, 1.0f, /* top-left */ + -a, -a, a, 0.0f, 0.0f, /* bottom-left */ + a, -a, a, 1.0f, 0.0f, /* bottom-right */ + a, a, a, 1.0f, 1.0f, /* top-right */ + + /* NOTE(pryazha): Left face */ + -a, -a, -a, 0.0f, 0.0f, /* bottom-left */ + -a, a, a, 1.0f, 1.0f, /* top-right */ + -a, a, -a, 0.0f, 1.0f, /* top-left */ + -a, -a, -a, 0.0f, 0.0f, /* bottom-left */ + -a, -a, a, 1.0f, 0.0f, /* bottom-right */ + -a, a, a, 1.0f, 1.0f, /* top-right */ + + /* NOTE(pryazha): Right face */ + a, -a, a, 0.0f, 0.0f, /* bottom-left */ + a, a, -a, 1.0f, 1.0f, /* top-right */ + a, a, a, 0.0f, 1.0f, /* top-left */ + a, -a, a, 0.0f, 0.0f, /* bottom-left */ + a, -a, -a, 1.0f, 0.0f, /* bottom-right */ + a, a, -a, 1.0f, 1.0f, /* top-right */ + + /* NOTE(pryazha): Top face */ + -a, a, a, 0.0f, 0.0f, /* bottom-left */ + a, a, -a, 1.0f, 1.0f, /* top-right */ + -a, a, -a, 0.0f, 1.0f, /* top-left */ + -a, a, a, 0.0f, 0.0f, /* bottom-left */ + a, a, a, 1.0f, 0.0f, /* bottom-right */ + a, a, -a, 1.0f, 1.0f, /* top-right */ + + /* NOTE(pryazha): Bottom face */ + -a, -a, -a, 0.0f, 0.0f, /* bottom-left */ + a, -a, a, 1.0f, 1.0f, /* top-right */ + -a, -a, a, 0.0f, 1.0f, /* top-left */ + -a, -a, -a, 0.0f, 0.0f, /* bottom-left */ + a, -a, -a, 1.0f, 0.0f, /* bottom-right */ + a, -a, a, 1.0f, 1.0f, /* top-right */ + }; + + U32 cube_vao; + glGenVertexArrays(1, &cube_vao); + glBindVertexArray(cube_vao); + glGenBuffers(1, &vbo); + glBindBuffer(GL_ARRAY_BUFFER, vbo); + glBufferData(GL_ARRAY_BUFFER, sizeof(cube_vertices), cube_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); + + F32 vertices[] = { + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, + + -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, + -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, + + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, + -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f, + + 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, + 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, + + -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f, + 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 1.0f, + 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f, + 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f, + -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, + -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f, + + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, + 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, + -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f + }; + + U32 normals_cube_vao; + glGenVertexArrays(1, &normals_cube_vao); + glBindVertexArray(normals_cube_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, 8*sizeof(F32), (void *)0); + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8*sizeof(F32), (void *)(3*sizeof(F32))); + glEnableVertexAttribArray(2); + glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8*sizeof(F32), (void *)(6*sizeof(F32))); + glBindVertexArray(0); + + state.camera = (Camera) { + v3f(2.0f, 1.0f, 2.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(); + F32 time = last_time; + + S32 scene = 0; + + while (!glfwWindowShouldClose(window)) { + glfwPollEvents(); + + process_glfw_keyboard(window, &input); + glfwGetFramebufferSize(window, &width, &height); + + /* NOTE(pryazha): Update */ + V3F target = v3f_zero(); + + if (key_first_press(input.exit)) + glfwSetWindowShouldClose(window, GLFW_TRUE); + + if (key_first_press(input.jump)) { + scene++; + scene %= 3; + } + + input_update_last_state(&input); + + /* NOTE(pryazha): Render */ + MAT4 view, proj, model; + + view = look_at(state.camera.pos, target, v3f(0.0f, 1.0f, 0.0f)); + proj = perspective(state.camera.fovx, (F32)width/(F32)height, + state.camera.near, state.camera.far); + + model = mat4_identity(); + + glClearColor(0.15f, 0.15f, 0.15f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + if (scene == 0) { + glUseProgram(shader); + glBindVertexArray(points_vao); + glDrawArrays(GL_POINTS, 0, 4); + glBindVertexArray(0); + } else if (scene == 1) { + glUseProgram(explosion_shader); + shader_set_mat4fv(explosion_shader, "proj", proj); + shader_set_mat4fv(explosion_shader, "view", view); + shader_set_mat4fv(explosion_shader, "model", model); + shader_set_1f(explosion_shader, "time", time); + glBindVertexArray(cube_vao); + glBindTexture(GL_TEXTURE_2D, grid_texture); + glDrawArrays(GL_TRIANGLES, 0, 36); + glBindVertexArray(0); + } else { + glUseProgram(basic_shader); + shader_set_mat4fv(basic_shader, "proj", proj); + shader_set_mat4fv(basic_shader, "view", view); + shader_set_mat4fv(basic_shader, "model", model); + draw_cube(normals_cube_vao, grid_texture); + + glUseProgram(normals_shader); + shader_set_mat4fv(normals_shader, "proj", proj); + shader_set_mat4fv(normals_shader, "view", view); + shader_set_mat4fv(normals_shader, "model", model); + draw_cube(normals_cube_vao, grid_texture); + } + + 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; + time += state.dt; + last_time = current_time; + } + + glDeleteBuffers(1, &vbo); + glDeleteVertexArrays(1, &points_vao); + + glfwTerminate(); + return(0); } diff --git a/advanced_opengl/8.geometry_shader/shaders/base.fs b/advanced_opengl/8.geometry_shader/shaders/base.frag index 73897db..70d5585 100644 --- a/advanced_opengl/8.geometry_shader/shaders/base.fs +++ b/advanced_opengl/8.geometry_shader/shaders/base.frag @@ -4,8 +4,7 @@ in vec3 fcolor; out vec4 frag_color; -void -main(void) +void main(void) { frag_color = vec4(fcolor, 1.0); } diff --git a/advanced_opengl/8.geometry_shader/shaders/base.gs b/advanced_opengl/8.geometry_shader/shaders/base.geom index 6b140c5..10d5c45 100644 --- a/advanced_opengl/8.geometry_shader/shaders/base.gs +++ b/advanced_opengl/8.geometry_shader/shaders/base.geom @@ -8,8 +8,7 @@ in VS_OUT { out vec3 fcolor; -void -main(void) +void main(void) { fcolor = gs_in[0].color; gl_Position = gl_in[0].gl_Position+vec4(-0.2, -0.2, 0.0, 0.0); diff --git a/advanced_opengl/8.geometry_shader/shaders/base.vs b/advanced_opengl/8.geometry_shader/shaders/base.vert index 9ad9e7a..5178f92 100644 --- a/advanced_opengl/8.geometry_shader/shaders/base.vs +++ b/advanced_opengl/8.geometry_shader/shaders/base.vert @@ -6,8 +6,7 @@ out VS_OUT { vec3 color; } vs_out; -void -main(void) +void main(void) { vs_out.color = acolor; gl_Position = vec4(apos, 0.0, 1.0); diff --git a/advanced_opengl/8.geometry_shader/shaders/basic.frag b/advanced_opengl/8.geometry_shader/shaders/basic.frag new file mode 100644 index 0000000..09244b5 --- /dev/null +++ b/advanced_opengl/8.geometry_shader/shaders/basic.frag @@ -0,0 +1,12 @@ +#version 330 core + +in vec2 tex_coords; + +out vec4 frag_color; + +uniform sampler2D texture1; + +void main(void) +{ + frag_color = texture(texture1, tex_coords); +} diff --git a/advanced_opengl/8.geometry_shader/shaders/basic.fs b/advanced_opengl/8.geometry_shader/shaders/basic.fs deleted file mode 100644 index bdd4b9a..0000000 --- a/advanced_opengl/8.geometry_shader/shaders/basic.fs +++ /dev/null @@ -1,13 +0,0 @@ -#version 330 core - -in vec2 tex_coords; - -out vec4 frag_color; - -uniform sampler2D texture1; - -void -main(void) -{ - frag_color = texture(texture1, tex_coords); -} diff --git a/advanced_opengl/8.geometry_shader/shaders/basic.vs b/advanced_opengl/8.geometry_shader/shaders/basic.vert index 77e8b70..10ce805 100644 --- a/advanced_opengl/8.geometry_shader/shaders/basic.vs +++ b/advanced_opengl/8.geometry_shader/shaders/basic.vert @@ -6,11 +6,10 @@ out vec2 tex_coords; uniform mat4 model; uniform mat4 view; -uniform mat4 projection; +uniform mat4 proj; -void -main(void) +void main(void) { - gl_Position = projection*view*model*vec4(apos, 1.0); + gl_Position = proj*view*model*vec4(apos, 1.0); tex_coords = atex_coords; } diff --git a/advanced_opengl/8.geometry_shader/shaders/explosion.fs b/advanced_opengl/8.geometry_shader/shaders/explosion.frag index 70e7151..b751460 100644 --- a/advanced_opengl/8.geometry_shader/shaders/explosion.fs +++ b/advanced_opengl/8.geometry_shader/shaders/explosion.frag @@ -6,8 +6,7 @@ out vec4 frag_color; uniform sampler2D texture0; -void -main(void) +void main(void) { frag_color = texture(texture0, ftex_coords); } diff --git a/advanced_opengl/8.geometry_shader/shaders/explosion.gs b/advanced_opengl/8.geometry_shader/shaders/explosion.geom index 3498878..e708591 100644 --- a/advanced_opengl/8.geometry_shader/shaders/explosion.gs +++ b/advanced_opengl/8.geometry_shader/shaders/explosion.geom @@ -10,16 +10,14 @@ out vec2 ftex_coords; uniform float time; -vec3 -get_normal(void) +vec3 get_normal(void) { vec3 a = vec3(gl_in[0].gl_Position)-vec3(gl_in[1].gl_Position); vec3 b = vec3(gl_in[2].gl_Position)-vec3(gl_in[1].gl_Position); return(normalize(cross(a, b))); } -vec4 -explode(vec4 position, vec3 normal) +vec4 explode(vec4 position, vec3 normal) { float magnitude = 0.2; vec3 direction = normal*magnitude*((sin(time)+1.0)/2.0); @@ -27,8 +25,7 @@ explode(vec4 position, vec3 normal) return(result); } -void -main(void) +void main(void) { vec3 normal = get_normal(); gl_Position = explode(gl_in[0].gl_Position, normal); diff --git a/advanced_opengl/8.geometry_shader/shaders/explosion.vs b/advanced_opengl/8.geometry_shader/shaders/explosion.vert index 46abd27..a79b432 100644 --- a/advanced_opengl/8.geometry_shader/shaders/explosion.vs +++ b/advanced_opengl/8.geometry_shader/shaders/explosion.vert @@ -6,13 +6,12 @@ out VS_OUT { vec2 gtex_coords; } vs_out; -uniform mat4 projection; +uniform mat4 proj; uniform mat4 view; uniform mat4 model; -void -main(void) +void main(void) { vs_out.gtex_coords = atex_coords; - gl_Position = projection*view*model*vec4(apos, 1.0); + gl_Position = proj*view*model*vec4(apos, 1.0); } diff --git a/advanced_opengl/7.uniform_buffer/shaders/color_cube.fs b/advanced_opengl/8.geometry_shader/shaders/normals.frag index fbbafbf..d40d866 100644 --- a/advanced_opengl/7.uniform_buffer/shaders/color_cube.fs +++ b/advanced_opengl/8.geometry_shader/shaders/normals.frag @@ -2,8 +2,7 @@ out vec4 frag_color; -void -main(void) +void main(void) { frag_color = vec4(1.0, 0.0, 0.0, 1.0); } diff --git a/advanced_opengl/8.geometry_shader/shaders/normals.gs b/advanced_opengl/8.geometry_shader/shaders/normals.geom index 3720a5f..f0e1a75 100644 --- a/advanced_opengl/8.geometry_shader/shaders/normals.gs +++ b/advanced_opengl/8.geometry_shader/shaders/normals.geom @@ -6,23 +6,21 @@ in VS_OUT { vec3 normal; } gs_in[]; -uniform mat4 projection; +uniform mat4 proj; const float MAGNITUDE = 0.4; -void -generate_line(int index) +void generate_line(int index) { - gl_Position = projection*gl_in[index].gl_Position; + gl_Position = proj*gl_in[index].gl_Position; EmitVertex(); - gl_Position = projection*(gl_in[index].gl_Position+ + gl_Position = proj*(gl_in[index].gl_Position+ vec4(gs_in[index].normal, 0.0)*MAGNITUDE); EmitVertex(); EndPrimitive(); } -void -main(void) +void main(void) { /* vec4 center = (gl_in[0].gl_Position+ @@ -32,9 +30,9 @@ main(void) gs_in[1].normal+ gs_in[2].normal)/3.0), 0.0)*MAGNITUDE; - gl_Position = projection*center; + gl_Position = proj*center; EmitVertex(); - gl_Position = projection*end; + gl_Position = proj*end; EmitVertex(); EndPrimitive(); */ diff --git a/advanced_opengl/8.geometry_shader/shaders/normals.vs b/advanced_opengl/8.geometry_shader/shaders/normals.vert index 3b728e5..14f7d8b 100644 --- a/advanced_opengl/8.geometry_shader/shaders/normals.vs +++ b/advanced_opengl/8.geometry_shader/shaders/normals.vert @@ -9,8 +9,7 @@ out VS_OUT { uniform mat4 view; uniform mat4 model; -void -main(void) +void main(void) { mat3 normal_matrix = mat3(transpose(inverse(view*model))); vs_out.normal = normalize(normal_matrix*anormal); diff --git a/advanced_opengl/9.instancing/instancing b/advanced_opengl/9.instancing/instancing Binary files differindex c722860..c1a31f8 100755 --- a/advanced_opengl/9.instancing/instancing +++ b/advanced_opengl/9.instancing/instancing diff --git a/advanced_opengl/9.instancing/instancing.c b/advanced_opengl/9.instancing/instancing.c index f24a258..e77c693 100644 --- a/advanced_opengl/9.instancing/instancing.c +++ b/advanced_opengl/9.instancing/instancing.c @@ -2,403 +2,293 @@ #include "GLFW/glfw3.h" #include "pwyazh.h" - #include "pwyazh_GL.h" #include "common.h" -#include <unistd.h> +int main(void) +{ + GLFWwindow *window; + State state; + S32 width, height; + Input input; + Arena *arena = 0; + B32 move_camera; -static S32 global_width = 1024, global_height = 768; -static Input global_input; + if (glfwInit() == GLFW_FALSE) { + fprintf(stderr, "[ERROR] Failed to initialize glfw.\n"); + return(1); + } -void -key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) -{ - switch (action) - { - case GLFW_PRESS: { - switch (key) - { - case GLFW_KEY_D: { - global_input.move_right.state = KeyState_PRESS; - } break; - case GLFW_KEY_W: { - global_input.move_forward.state = KeyState_PRESS; - } break; - case GLFW_KEY_A: { - global_input.move_left.state = KeyState_PRESS; - } break; - case GLFW_KEY_S: { - global_input.move_backward.state = KeyState_PRESS; - } break; - case GLFW_KEY_E: { - global_input.move_up.state = KeyState_PRESS; - } break; - case GLFW_KEY_Q: { - global_input.move_down.state = KeyState_PRESS; - } break; - case GLFW_KEY_SPACE: { - global_input.jump.state = KeyState_PRESS; - } break; - case GLFW_KEY_RIGHT: { - global_input.action_right.state = KeyState_PRESS; - } break; - case GLFW_KEY_LEFT: { - global_input.action_left.state = KeyState_PRESS; - } break; - case GLFW_KEY_ESCAPE: { - global_input.exit.state = KeyState_PRESS; - } break; - } - } break; - - case GLFW_RELEASE: { - switch (key) - { - case GLFW_KEY_D: { - global_input.move_right.state = KeyState_RELEASE; - } break; - case GLFW_KEY_W: { - global_input.move_forward.state = KeyState_RELEASE; - } break; - case GLFW_KEY_A: { - global_input.move_left.state = KeyState_RELEASE; - } break; - case GLFW_KEY_S: { - global_input.move_backward.state = KeyState_RELEASE; - } break; - case GLFW_KEY_E: { - global_input.move_up.state = KeyState_RELEASE; - } break; - case GLFW_KEY_Q: { - global_input.move_down.state = KeyState_RELEASE; - } break; - case GLFW_KEY_SPACE: { - global_input.jump.state = KeyState_RELEASE; - } break; - case GLFW_KEY_RIGHT: { - global_input.action_right.state = KeyState_RELEASE; - } break; - case GLFW_KEY_LEFT: { - global_input.action_left.state = KeyState_RELEASE; - } break; - case GLFW_KEY_ESCAPE: { - global_input.exit.state = KeyState_RELEASE; - } break; - } - } break; - } -} + width = 1024; + height = 768; -void -window_resize_callback(GLFWwindow* window, int width, int height) -{ - global_width = width; - global_height = height; - glViewport(0, 0, global_width, global_height); -} + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); + glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); + window = glfwCreateWindow(width, height, "Instancing", 0, 0); + if (!window) { + fprintf(stderr, "[ERROR] Failed to create window.\n"); + glfwTerminate(); + return(1); + } -int -main(void) -{ - GLFWwindow *window; - Arena *arena = 0; - - if (glfwInit() == GLFW_FALSE) - { - fprintf(stderr, "[ERROR] Failed to initialize glfw.\n"); - return(1); - } - - /* glfwWindowHint(GLFW_RESIZABLE, 0); */ - glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); - glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); - window = glfwCreateWindow(global_width, global_height, "Instancing", 0, 0); - if (!window) - { - fprintf(stderr, "[ERROR] Failed to create window.\n"); - glfwTerminate(); - return(1); - } - - glfwMakeContextCurrent(window); - - glfwSetKeyCallback(window, key_callback); - glfwSetWindowSizeCallback(window, window_resize_callback); - - if (glewInit() != GLEW_OK) - { - fprintf(stderr, "[ERROR] Failed to initialize glew.\n"); - glfwTerminate(); - return(1); - } - - glEnable(GL_DEPTH_TEST); - - U32 instancing_uniform_array_shader = - create_shader_program("shaders/instancing_uniform_array.vs", - "shaders/instancing_uniform_array.fs"); - U32 instanced_arrays_shader = - create_shader_program("shaders/instanced_arrays.vs", - "shaders/instanced_arrays.fs"); - - F32 quad_vertices[] = { - -0.05f, 0.05f, 1.0f, 0.0f, 0.0f, - 0.05f, -0.05f, 0.0f, 1.0f, 0.0f, - -0.05f, -0.05f, 0.0f, 0.0f, 1.0f, - - -0.05f, 0.05f, 1.0f, 0.0f, 0.0f, - 0.05f, -0.05f, 0.0f, 1.0f, 0.0f, - 0.05f, 0.05f, 0.0f, 1.0f, 1.0f, - }; - - GLuint 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, 2, GL_FLOAT, GL_FALSE, 5*sizeof(F32), (void *)0); - glEnableVertexAttribArray(1); - glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 5*sizeof(F32), (void *)(2*sizeof(F32))); - glBindVertexArray(0); - - V2F translations[100]; - S32 index = 0; - F32 offset = 0.1f; - for (S32 y = -10; - y < 10; - y += 2) - { - for (S32 x = -10; - x < 10; - x += 2) - { - V2F translation = v2f((F32)x, (F32)y); - translation = v2f_scalef(translation, 1.0f/10.0f); - translation = v2f_add(translation, v2f(offset, offset)); - translations[index++] = translation; - } - } - - U32 instance_vbo; - glBindVertexArray(quad_vao); - glGenBuffers(1, &instance_vbo); - glBindBuffer(GL_ARRAY_BUFFER, instance_vbo); - glBufferData(GL_ARRAY_BUFFER, sizeof(translations), translations, GL_STATIC_DRAW); - glEnableVertexAttribArray(2); - glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(V2F), (void *)0); - glBindBuffer(GL_ARRAY_BUFFER, 0); - glVertexAttribDivisor(2, 1); - glBindVertexArray(0); - - arena = arena_alloc(Megabytes(64)); - - U32 default_shader = create_shader_program("shaders/default.vs", "shaders/default.fs"); - U32 instanced_shader = create_shader_program("shaders/instanced_mat4.vs", - "shaders/instanced_mat4.fs"); - Mesh *planet_mesh = mesh_load_obj(arena, "../../data/models/planet/planet.obj"); - U32 planet_texture = load_texture("../../data/models/planet/mars.png"); - Mesh *rock_mesh = mesh_load_obj(arena, "../../data/models/rock/rock.obj"); - U32 rock_texture = load_texture("../../data/models/rock/rock.png"); - - S32 amount = 80000; - F32 radius = 150.0f; - offset = 25.0f; - MAT4 trns[amount]; - for (S32 i = 0; i < amount; ++i) - { - F32 angle, displacement, x, y, z, scale; - MAT4 model = mat4_identity(); - - angle = rand()%360; - model = mat4_rotate_angles(model, v3f(angle, angle, angle)); - - scale = (rand()%20)/100.0f+0.05f; - model = mat4_scale(model, v3f(scale, scale, scale)); - - angle = ((F32)i/(F32)amount)*360.0f; - displacement = (rand()%(S32)(2.0f*offset))-offset; - x = f32_sin(DEG2RAD*angle)*radius+displacement; - displacement = (rand()%(S32)(2.0f*offset))-offset; - y = 0.4f*displacement; - displacement = (rand()%(S32)(2.0f*offset))-offset; - z = f32_cos(DEG2RAD*angle)*radius; - model = mat4_translate(model, v3f(x, y, z)); - - trns[i] = model; - } - - U32 buffer; - glGenBuffers(1, &buffer); - glBindBuffer(GL_ARRAY_BUFFER, buffer); - glBufferData(GL_ARRAY_BUFFER, amount*sizeof(MAT4), &trns[0], GL_STATIC_DRAW); - glBindVertexArray(rock_mesh->vao); - glEnableVertexAttribArray(3); - glVertexAttribPointer(3, 4, GL_FLOAT, GL_FALSE, 4*sizeof(V4F), (void *)0); - glEnableVertexAttribArray(4); - glVertexAttribPointer(4, 4, GL_FLOAT, GL_FALSE, 4*sizeof(V4F), (void *)(1*sizeof(V4F))); - glEnableVertexAttribArray(5); - glVertexAttribPointer(5, 4, GL_FLOAT, GL_FALSE, 4*sizeof(V4F), (void *)(2*sizeof(V4F))); - glEnableVertexAttribArray(6); - glVertexAttribPointer(6, 4, GL_FLOAT, GL_FALSE, 4*sizeof(V4F), (void *)(3*sizeof(V4F))); - - glVertexAttribDivisor(3, 1); - glVertexAttribDivisor(4, 1); - glVertexAttribDivisor(5, 1); - glVertexAttribDivisor(6, 1); - glBindVertexArray(0); - - F32 target_fps = 60.0f; - F32 target_spf = 1.0f/target_fps; - - F32 last_time = glfwGetTime(); - F32 time = last_time; - F32 dt; - - S32 scene = 0; - S32 number_scene = 4; - - MAT4 projection, view, model; - - V3F camera_pos = v3f(0.0f, 50.0f, 220.0f); - F32 camera_speed = 10.0f; - F32 fovx = 90.0f; - F32 near = 0.1f; - F32 far = 1000.0f; - - while (!glfwWindowShouldClose(window)) - { - glfwPollEvents(); - - /* NOTE(pryazha): Update */ - if (key_is_pressed(global_input.exit)) - { - glfwSetWindowShouldClose(window, GLFW_TRUE); - } - if (key_first_press(global_input.jump) || - key_first_press(global_input.action_right)) - { - scene++; - } - else if (key_first_press(global_input.action_left)) - { - scene--; - if (scene < 0) - scene = number_scene-1; - } - scene %= number_scene; - - /* NOTE(pryazha): Render */ - glClearColor(0.15f, 0.15f, 0.15f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - switch (scene) - { - case 0: { - glUseProgram(instancing_uniform_array_shader); - for (S32 translation_index = 0; - translation_index < 100; - ++translation_index) - { - char temp[256]; - snprintf(temp, 256, "offsets[%d]", translation_index); - shader_set_2fv(instancing_uniform_array_shader, - temp, translations[translation_index]); - } - glBindVertexArray(quad_vao); - glDrawArraysInstanced(GL_TRIANGLES, 0, 6, 100); - glBindVertexArray(0); - } break; - - case 1: { - glUseProgram(instanced_arrays_shader); - glBindVertexArray(quad_vao); - glDrawArraysInstanced(GL_TRIANGLES, 0, 6, 100); - glBindVertexArray(0); - } break; - - case 2: { - V3F camera_dv = get_dv_camera_orbital(&global_input, - camera_pos, v3f_zero(), - dt, camera_speed); - camera_pos = v3f_add(camera_pos, camera_dv); - - projection = perspective(fovx, (F32)global_width/(F32)global_height, near, far); - V3F world_up = v3f(0.0f, 1.0f, 0.0f); - view = look_at(camera_pos, v3f_zero(), world_up); - - glUseProgram(default_shader); - shader_set_mat4fv(default_shader, "projection", projection); - shader_set_mat4fv(default_shader, "view", view); - - F32 scale = 5.0f; - model = mat4_make_scale(v3f(scale, scale, scale)); - shader_set_mat4fv(default_shader, "model", model); - glBindTexture(GL_TEXTURE_2D, planet_texture); - mesh_draw(planet_mesh); - - glBindTexture(GL_TEXTURE_2D, rock_texture); - for (S32 i = 0; i < amount; ++i) - { - model = trns[i]; - shader_set_mat4fv(default_shader, "model", model); - mesh_draw(rock_mesh); - } - } break; - - case 3: { - V3F camera_dv = get_dv_camera_orbital(&global_input, - camera_pos, v3f_zero(), - dt, camera_speed); - camera_pos = v3f_add(camera_pos, camera_dv); - - projection = perspective(fovx, (F32)global_width/(F32)global_height, near, far); - V3F world_up = v3f(0.0f, 1.0f, 0.0f); - view = look_at(camera_pos, v3f_zero(), world_up); - - glUseProgram(default_shader); - shader_set_mat4fv(default_shader, "projection", projection); - shader_set_mat4fv(default_shader, "view", view); - F32 scale = 5.0f; - model = mat4_make_scale(v3f(scale, scale, scale)); - shader_set_mat4fv(default_shader, "model", model); - glBindTexture(GL_TEXTURE_2D, planet_texture); - mesh_draw(planet_mesh); - glBindTexture(GL_TEXTURE_2D, 0); - - glUseProgram(instanced_shader); - shader_set_mat4fv(default_shader, "projection", projection); - shader_set_mat4fv(default_shader, "view", view); - glBindTexture(GL_TEXTURE_2D, rock_texture); - glBindVertexArray(rock_mesh->vao); - glDrawElementsInstanced(GL_TRIANGLES, rock_mesh->index_count, - GL_UNSIGNED_INT, 0, amount); - glBindVertexArray(0); - glBindTexture(GL_TEXTURE_2D, 0); - } break; - } - - input_update_last_state(&global_input); - - 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(); - dt = current_time-last_time; - time += dt; - last_time = current_time; - } - - glfwTerminate(); - return(0); + glfwMakeContextCurrent(window); + glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); + + if (glewInit() != GLEW_OK) { + fprintf(stderr, "[ERROR] Failed to initialize glew.\n"); + glfwTerminate(); + return(1); + } + + glEnable(GL_DEPTH_TEST); + + U32 instancing_uniform_array_shader = create_shader_program("shaders/instancing_uniform_array.vert", + "shaders/instancing_uniform_array.frag"); + U32 instanced_arrays_shader = create_shader_program("shaders/instanced_arrays.vert", + "shaders/instanced_arrays.frag"); + U32 default_shader = create_shader_program("shaders/default.vert", + "shaders/default.frag"); + U32 instanced_shader = create_shader_program("shaders/instanced_mat4.vert", + "shaders/instanced_mat4.frag"); + + F32 quad_vertices[] = { + -0.05f, 0.05f, 1.0f, 0.0f, 0.0f, + 0.05f, -0.05f, 0.0f, 1.0f, 0.0f, + -0.05f, -0.05f, 0.0f, 0.0f, 1.0f, + + -0.05f, 0.05f, 1.0f, 0.0f, 0.0f, + 0.05f, -0.05f, 0.0f, 1.0f, 0.0f, + 0.05f, 0.05f, 0.0f, 1.0f, 1.0f, + }; + + GLuint 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, 2, GL_FLOAT, GL_FALSE, 5*sizeof(F32), (void *)0); + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 5*sizeof(F32), (void *)(2*sizeof(F32))); + glBindVertexArray(0); + + V2F translations[100]; + S32 index = 0; + F32 offset = 0.1f; + for (S32 y = -10; y < 10; y += 2) { + for (S32 x = -10; x < 10; x += 2) { + V2F translation = v2f((F32)x, (F32)y); + translation = v2f_scalef(translation, 1.0f/10.0f); + translation = v2f_add(translation, v2f(offset, offset)); + translations[index++] = translation; + } + } + + U32 instance_vbo; + glBindVertexArray(quad_vao); + glGenBuffers(1, &instance_vbo); + glBindBuffer(GL_ARRAY_BUFFER, instance_vbo); + glBufferData(GL_ARRAY_BUFFER, sizeof(translations), translations, GL_STATIC_DRAW); + glEnableVertexAttribArray(2); + glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(V2F), (void *)0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glVertexAttribDivisor(2, 1); + glBindVertexArray(0); + + arena = arena_alloc(Megabytes(64)); + + Mesh *planet_mesh = mesh_load_obj(arena, "../../data/models/planet/planet.obj"); + Mesh *rock_mesh = mesh_load_obj(arena, "../../data/models/rock/rock.obj"); + + U32 planet_texture = load_texture("../../data/models/planet/mars.png"); + U32 rock_texture = load_texture("../../data/models/rock/rock.png"); + + S32 amount = 80000; + F32 radius = 150.0f; + offset = 25.0f; + MAT4 trns[amount]; + for (S32 i = 0; i < amount; ++i) { + F32 angle, displacement, x, y, z, scale; + MAT4 model = mat4_identity(); + + angle = rand()%360; + model = mat4_rotate_angles(model, v3f(angle, angle, angle)); + + scale = (rand()%20)/100.0f+0.05f; + model = mat4_scale(model, v3f(scale, scale, scale)); + + angle = ((F32)i/(F32)amount)*360.0f; + displacement = (rand()%(S32)(2.0f*offset))-offset; + x = f32_sin(DEG2RAD*angle)*radius+displacement; + displacement = (rand()%(S32)(2.0f*offset))-offset; + y = 0.4f*displacement; + displacement = (rand()%(S32)(2.0f*offset))-offset; + z = f32_cos(DEG2RAD*angle)*radius; + model = mat4_translate(model, v3f(x, y, z)); + + trns[i] = model; + } + + U32 buffer; + glGenBuffers(1, &buffer); + glBindBuffer(GL_ARRAY_BUFFER, buffer); + glBufferData(GL_ARRAY_BUFFER, amount*sizeof(MAT4), &trns[0], GL_STATIC_DRAW); + glBindVertexArray(rock_mesh->vao); + glEnableVertexAttribArray(3); + glVertexAttribPointer(3, 4, GL_FLOAT, GL_FALSE, 4*sizeof(V4F), (void *)0); + glEnableVertexAttribArray(4); + glVertexAttribPointer(4, 4, GL_FLOAT, GL_FALSE, 4*sizeof(V4F), (void *)(1*sizeof(V4F))); + glEnableVertexAttribArray(5); + glVertexAttribPointer(5, 4, GL_FLOAT, GL_FALSE, 4*sizeof(V4F), (void *)(2*sizeof(V4F))); + glEnableVertexAttribArray(6); + glVertexAttribPointer(6, 4, GL_FLOAT, GL_FALSE, 4*sizeof(V4F), (void *)(3*sizeof(V4F))); + + glVertexAttribDivisor(3, 1); + glVertexAttribDivisor(4, 1); + glVertexAttribDivisor(5, 1); + glVertexAttribDivisor(6, 1); + glBindVertexArray(0); + + state.camera = (Camera) { + v3f(0.0f, 50.0f, 220.0f), + 90.0f, 0.1f, 1000.0f, + 0.0f, 0.0f + }; + F32 camera_speed = 10.0f; + + F32 target_fps = 60.0f; + F32 target_spf = 1.0f/target_fps; + F32 last_time = glfwGetTime(); + F32 time = last_time; + + S32 scene = 0; + S32 number_scene = 4; + + while (!glfwWindowShouldClose(window)) { + glfwPollEvents(); + + /* NOTE(pryazha): Update */ + glfwGetFramebufferSize(window, &width, &height); + process_glfw_keyboard(window, &input); + process_glfw_mouse_pos(window, &input); + + if (key_is_pressed(input.exit)) + glfwSetWindowShouldClose(window, GLFW_TRUE); + + if (key_first_press(input.jump) || + key_first_press(input.action_right)) { + scene++; + } else if (key_first_press(input.action_left)) { + scene--; + if (scene < 0) + scene = number_scene-1; + } + scene %= number_scene; + + move_camera = (scene > 1) ? 1 : 0; + + if (move_camera) { + V3F dv = get_dv_camera_first_person(&input, &state.camera, + 4.0f, state.dt); + state.camera.pos = v3f_add(state.camera.pos, dv); + 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); + + /* NOTE(pryazha): Render */ + MAT4 proj, view, model; + F32 scale = 5.0f; + + view = get_view_matrix(&state.camera); + proj = perspective(state.camera.fovx, (F32)width/(F32)height, + state.camera.near, state.camera.far); + + glClearColor(0.15f, 0.15f, 0.15f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + switch (scene) { + case 0: + glUseProgram(instancing_uniform_array_shader); + for (S32 i = 0; i < 100; ++i) { + char temp[256]; + snprintf(temp, 256, "offsets[%d]", i); + shader_set_2fv(instancing_uniform_array_shader, + temp, translations[i]); + } + glBindVertexArray(quad_vao); + glDrawArraysInstanced(GL_TRIANGLES, 0, 6, 100); + glBindVertexArray(0); + break; + case 1: + glUseProgram(instanced_arrays_shader); + glBindVertexArray(quad_vao); + glDrawArraysInstanced(GL_TRIANGLES, 0, 6, 100); + glBindVertexArray(0); + break; + case 2: + glUseProgram(default_shader); + shader_set_mat4fv(default_shader, "proj", proj); + shader_set_mat4fv(default_shader, "view", view); + + model = mat4_make_scale(v3f(scale, scale, scale)); + shader_set_mat4fv(default_shader, "model", model); + glBindTexture(GL_TEXTURE_2D, planet_texture); + mesh_draw(planet_mesh); + + glBindTexture(GL_TEXTURE_2D, rock_texture); + for (S32 i = 0; i < amount; ++i) { + model = trns[i]; + shader_set_mat4fv(default_shader, "model", model); + mesh_draw(rock_mesh); + } + break; + case 3: + glUseProgram(default_shader); + shader_set_mat4fv(default_shader, "proj", proj); + shader_set_mat4fv(default_shader, "view", view); + model = mat4_make_scale(v3f(scale, scale, scale)); + shader_set_mat4fv(default_shader, "model", model); + glBindTexture(GL_TEXTURE_2D, planet_texture); + mesh_draw(planet_mesh); + glBindTexture(GL_TEXTURE_2D, 0); + + glUseProgram(instanced_shader); + shader_set_mat4fv(default_shader, "proj", proj); + shader_set_mat4fv(default_shader, "view", view); + glBindTexture(GL_TEXTURE_2D, rock_texture); + glBindVertexArray(rock_mesh->vao); + glDrawElementsInstanced(GL_TRIANGLES, rock_mesh->index_count, + GL_UNSIGNED_INT, 0, amount); + glBindVertexArray(0); + glBindTexture(GL_TEXTURE_2D, 0); + break; + } + + 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; + time += state.dt; + last_time = current_time; + } + + glfwTerminate(); + return(0); } diff --git a/advanced_opengl/9.instancing/shaders/default.fs b/advanced_opengl/9.instancing/shaders/default.frag index c655ac8..8ae5c3b 100644 --- a/advanced_opengl/9.instancing/shaders/default.fs +++ b/advanced_opengl/9.instancing/shaders/default.frag @@ -6,8 +6,7 @@ out vec4 frag_color; uniform sampler2D texture0; -void -main(void) +void main(void) { frag_color = texture(texture0, tex_coords); -}
\ No newline at end of file +} diff --git a/advanced_opengl/9.instancing/shaders/default.vs b/advanced_opengl/9.instancing/shaders/default.vert index 85d3c19..87cb538 100644 --- a/advanced_opengl/9.instancing/shaders/default.vs +++ b/advanced_opengl/9.instancing/shaders/default.vert @@ -6,13 +6,12 @@ layout(location = 2) in vec2 atex_coords; out vec3 normal; out vec2 tex_coords; -uniform mat4 projection; +uniform mat4 proj; uniform mat4 view; uniform mat4 model; -void -main(void) +void main(void) { tex_coords = atex_coords; - gl_Position = projection*view*model*vec4(apos, 1.0); + gl_Position = proj*view*model*vec4(apos, 1.0); } diff --git a/advanced_opengl/9.instancing/shaders/instanced_arrays.fs b/advanced_opengl/9.instancing/shaders/instanced_arrays.frag index a32e52e..4865933 100644 --- a/advanced_opengl/9.instancing/shaders/instanced_arrays.fs +++ b/advanced_opengl/9.instancing/shaders/instanced_arrays.frag @@ -4,8 +4,7 @@ in vec3 color; out vec4 frag_color; -void -main(void) +void main(void) { frag_color = vec4(color, 1.0); } diff --git a/advanced_opengl/9.instancing/shaders/instanced_arrays.vs b/advanced_opengl/9.instancing/shaders/instanced_arrays.vert index 4ea0fe4..ce3ea7d 100644 --- a/advanced_opengl/9.instancing/shaders/instanced_arrays.vs +++ b/advanced_opengl/9.instancing/shaders/instanced_arrays.vert @@ -5,8 +5,7 @@ layout(location = 2) in vec2 aoffset; out vec3 color; -void -main(void) +void main(void) { color = acolor; vec2 pos = apos*(gl_InstanceID/100.0); diff --git a/advanced_opengl/9.instancing/shaders/instanced_mat4.fs b/advanced_opengl/9.instancing/shaders/instanced_mat4.frag index ae625b2..3b96d36 100644 --- a/advanced_opengl/9.instancing/shaders/instanced_mat4.fs +++ b/advanced_opengl/9.instancing/shaders/instanced_mat4.frag @@ -6,8 +6,7 @@ out vec4 frag_color; uniform sampler2D texture1; -void -main(void) +void main(void) { frag_color = texture(texture1, tex_coords); } diff --git a/advanced_opengl/9.instancing/shaders/instanced_mat4.vs b/advanced_opengl/9.instancing/shaders/instanced_mat4.vert index c65be90..835cc5d 100644 --- a/advanced_opengl/9.instancing/shaders/instanced_mat4.vs +++ b/advanced_opengl/9.instancing/shaders/instanced_mat4.vert @@ -5,12 +5,11 @@ layout(location = 3) in mat4 instance_matrix; out vec2 tex_coords; -uniform mat4 projection; +uniform mat4 proj; uniform mat4 view; -void -main(void) +void main(void) { tex_coords = atex_coords; - gl_Position = projection*view*instance_matrix*vec4(apos, 1.0); + gl_Position = proj*view*instance_matrix*vec4(apos, 1.0); } diff --git a/advanced_opengl/9.instancing/shaders/instancing_uniform_array.fs b/advanced_opengl/9.instancing/shaders/instancing_uniform_array.frag index a32e52e..4865933 100644 --- a/advanced_opengl/9.instancing/shaders/instancing_uniform_array.fs +++ b/advanced_opengl/9.instancing/shaders/instancing_uniform_array.frag @@ -4,8 +4,7 @@ in vec3 color; out vec4 frag_color; -void -main(void) +void main(void) { frag_color = vec4(color, 1.0); } diff --git a/advanced_opengl/9.instancing/shaders/instancing_uniform_array.vs b/advanced_opengl/9.instancing/shaders/instancing_uniform_array.vert index a77be31..61b07a0 100644 --- a/advanced_opengl/9.instancing/shaders/instancing_uniform_array.vs +++ b/advanced_opengl/9.instancing/shaders/instancing_uniform_array.vert @@ -6,8 +6,7 @@ out vec3 color; uniform vec2 offsets[100]; -void -main(void) +void main(void) { color = acolor; gl_Position = vec4(apos+offsets[gl_InstanceID], 0.0, 1.0); diff --git a/data/textures/brickwall.jpg b/data/textures/brickwall.jpg Binary files differnew file mode 100644 index 0000000..39478d3 --- /dev/null +++ b/data/textures/brickwall.jpg diff --git a/data/textures/brickwall_normal.jpg b/data/textures/brickwall_normal.jpg Binary files differnew file mode 100644 index 0000000..a0a5fb6 --- /dev/null +++ b/data/textures/brickwall_normal.jpg diff --git a/libs/common.h b/libs/common.h index c7513a2..b12e4a1 100644 --- a/libs/common.h +++ b/libs/common.h @@ -12,535 +12,520 @@ #include <sys/stat.h> #include <fcntl.h> -U8 * -read_entire_file(const char *filename) { - U8 *result; - FILE *f; - long file_size; - - result = 0; - - if (!filename) { - return(result); - } - - f = fopen(filename, "rb"); - if (!f) { - return(result); - } - - fseek(f, 0, SEEK_END); - file_size = ftell(f); - fseek(f, 0, SEEK_SET); - - result = malloc(file_size + 1); - fread(result, file_size, 1, f); - fclose(f); - - result[file_size] = 0; - - return(result); -} - -void * -mmap_file(size_t *len, const char *filename) -{ - struct stat sb; - char* p; - int fd; - - fd = open(filename, O_RDONLY); - if (fd == -1) { - perror("open"); - return NULL; - } - - if (fstat(fd, &sb) == -1) { - perror("fstat"); - return NULL; - } - - if (!S_ISREG(sb.st_mode)) { - fprintf(stderr, "%s is not a file\n", filename); - return NULL; - } - - p = (char*)mmap(0, sb.st_size, PROT_READ, MAP_SHARED, fd, 0); - - if (p == MAP_FAILED) { - perror("mmap"); - return NULL; - } - - if (close(fd) == -1) { - perror("close"); - return NULL; - } - - (*len) = sb.st_size; - - return p; -} - -void -read_entire_file_mmap(void* ctx, const char* filename, const int is_mtl, - const char* obj_filename, char** data, size_t* len) -{ - if (!filename) - { - fprintf(stderr, "[ERROR]: Filename not provided (null)\n"); - *data = 0; - *len = 0; - return; - } - - size_t data_len = 0; - - *data = mmap_file(&data_len, filename); - *len = data_len; -} - -Mesh * -mesh_load_obj(Arena *arena, const char *filename) -{ - tinyobj_attrib_t attrib; - tinyobj_shape_t *shapes = 0; - tinyobj_material_t *materials = 0; - size_t num_shapes, num_materials, num_triangles; - size_t i, j, face_offset; - U32 flags; - Mesh *mesh = 0; - - flags = TINYOBJ_FLAG_TRIANGULATE; - - S32 status = tinyobj_parse_obj(&attrib, &shapes, &num_shapes, - &materials, &num_materials, filename, - read_entire_file_mmap, 0, flags); - if (status != TINYOBJ_SUCCESS) - { - fprintf(stderr, "[ERROR]: Failed to parse \"%s\"\n", filename); - if (status == TINYOBJ_ERROR_INVALID_PARAMETER) - fprintf(stderr, "[ERROR]: TINYOBJ_ERROR_INVALID_PARAMETER\n"); - return(mesh); - } - - num_triangles = attrib.num_face_num_verts; - face_offset = 0; - - Vertex *vertices = arena_push_size(arena, sizeof(Vertex)*num_triangles*3); - U32 *indices = arena_push_size(arena, num_triangles*3*sizeof(U32)); - U32 vertex_count = 0; - U32 index_count = 0, index_index = 0; - for (i = 0; i < attrib.num_face_num_verts; ++i) - { - tinyobj_vertex_index_t idx; - V3F pos, normal; - V2F tex_coords; - - Assert(attrib.face_num_verts[i]%3 == 0); - - Assert(attrib.face_num_verts[i]/3 > 3); - - Assert(attrib.num_texcoords); - - for (j = 0; j < 3; ++j) - { - idx = attrib.faces[face_offset+j]; - Assert(idx.v_idx >= 0); - pos = v3f(attrib.vertices[3*idx.v_idx+0], - attrib.vertices[3*idx.v_idx+1], - attrib.vertices[3*idx.v_idx+2]); - - Assert(idx.vn_idx < (S32)attrib.num_normals); - normal = v3f(attrib.normals[3*idx.vn_idx+0], - attrib.normals[3*idx.vn_idx+1], - attrib.normals[3*idx.vn_idx+2]); - - Assert(idx.vt_idx < (S32)attrib.num_texcoords); - tex_coords = v2f(attrib.texcoords[2*idx.vt_idx+0], - attrib.texcoords[2*idx.vt_idx+1]); - - vertices[vertex_count++] = vertex(pos, normal, tex_coords); - Assert(index_count < attrib.num_faclibe_num_verts); - indices[index_index++] = index_count++; - } - - face_offset += 3; - } - - mesh = mesh_init(arena, vertices, vertex_count, - indices, num_triangles*3); - - tinyobj_attrib_free(&attrib); - tinyobj_shapes_free(shapes, num_shapes); - tinyobj_materials_free(materials, num_materials); - - return(mesh); -} - -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); - glShaderSource(shader, 1, &source, 0); - free((void *)source); - glCompileShader(shader); - 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); - } else { - fprintf(stdout, "[INFO]: \"%s\" compiled successfuly.\n", filename); - } - return(shader); -} - -U32 -create_shader_program(char *vertex_shader_filename, - char *fragment_shader_filename) -{ - 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 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); - if (success == GL_FALSE) { - glGetProgramInfoLog(shader_program, 512, 0, logs); - fprintf(stderr, "[ERROR]: Failed to link shader program:\n%s", - logs); - } else { - fprintf(stdout, "[INFO]: Shader program linked successfuly.\n\n"); - } - glDeleteShader(vertex_shader); - glDeleteShader(fragment_shader); - - return(shader_program); -} - -U32 -create_shader_program_geom(char *vertex_shader_filename, - char *fragment_shader_filename, - char *geometry_shader_filename) -{ - 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); - if (success == GL_FALSE) { - glGetProgramInfoLog(shader_program, 512, 0, logs); - fprintf(stderr, "[ERROR]: Failed to link shader program:\n%s", - logs); - } else { - fprintf(stdout, "[INFO]: Shader program linked successfuly.\n\n"); - } - glDeleteShader(vertex_shader); - glDeleteShader(fragment_shader); - glDeleteShader(geometry_shader); - - return(shader_program); -} - -void -shader_set_3f(U32 shader_program, char *uniform_name, F32 x, F32 y, F32 z) -{ - U32 uniform_location = glGetUniformLocation(shader_program, uniform_name); - glUniform3f(uniform_location, x, y, z); -} - -void -shader_set_1f(U32 shader_program, char *uniform_name, F32 value) -{ - U32 uniform_location = glGetUniformLocation(shader_program, uniform_name); - glUniform1f(uniform_location, value); -} - -void -shader_set_3fv(U32 shader_program, char *uniform_name, V3F value) -{ - U32 uniform_location = glGetUniformLocation(shader_program, uniform_name); - glUniform3fv(uniform_location, 1, (const GLfloat *)&value); -} - -void -shader_set_2fv(U32 shader_program, char *uniform_name, V2F value) -{ - U32 uniform_location = glGetUniformLocation(shader_program, uniform_name); - glUniform2fv(uniform_location, 1, (const GLfloat *)&value); -} - -void -shader_set_mat4fv(U32 shader_program, char *uniform_name, MAT4 value) -{ - U32 uniform_location = glGetUniformLocation(shader_program, uniform_name); - glUniformMatrix4fv(uniform_location, 1, GL_FALSE, (F32 *)&value); -} - -void -shader_set_1i(U32 shader_program, char *uniform_name, S32 value) -{ - U32 uniform_location = glGetUniformLocation(shader_program, uniform_name); - glUniform1i(uniform_location, 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); - U8 *data = stbi_load(texture_filename, &width, &height, &number_channels, 0); - if (data) { - GLenum format = 0; - if (number_channels == 1) - format = GL_RED; - else if (number_channels == 3) - format = GL_RGB; - else if (number_channels == 4) - format = GL_RGBA; - - glBindTexture(GL_TEXTURE_2D, texture_id); - glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, GL_UNSIGNED_BYTE, data); - glGenerateMipmap(GL_TEXTURE_2D); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); - 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); - } else { - fprintf(stderr, "[ERROR]: Failed to load texture: \"%s\"\n", - texture_filename); - } - stbi_image_free(data); - - return(texture_id); -} - -U32 -load_texture_gamma(char *filename, B32 gamma_correction) -{ - S32 width, height, number_channels; - U32 texture_id; - - glGenTextures(1, &texture_id); - - stbi_set_flip_vertically_on_load(1); - U8 *data = stbi_load(filename, &width, &height, &number_channels, 0); - if (data) { - GLenum internal_format, data_format; - if (number_channels == 1) - { - internal_format = data_format = GL_RED; - } - else if (number_channels == 3) - { - internal_format = gamma_correction ? GL_SRGB : GL_RGB; - data_format = GL_RGB; - } - else if (number_channels == 4) - { - internal_format = gamma_correction ? GL_SRGB_ALPHA : GL_RGBA; - data_format = GL_RGBA; - } - - glBindTexture(GL_TEXTURE_2D, texture_id); - glTexImage2D(GL_TEXTURE_2D, 0, internal_format, width, height, - 0, data_format, GL_UNSIGNED_BYTE, data); - glGenerateMipmap(GL_TEXTURE_2D); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glBindTexture(GL_TEXTURE_2D, 0); - - fprintf(stdout, "[INFO]: Texture (\"%s\") is loaded successfully\n", filename); - } else { - fprintf(stderr, "[ERROR]: Failed to load texture: \"%s\"\n", filename); - } - stbi_image_free(data); - - return(texture_id); -} - -U32 -load_cubemap(const char *texture_filenames[6]) -{ - U32 texture_id; - glGenTextures(1, &texture_id); - glBindTexture(GL_TEXTURE_CUBE_MAP, texture_id); - S32 width, height, number_channels; - U8 *data = 0; - stbi_set_flip_vertically_on_load(0); - for (U32 texture_index = 0; - texture_index < 6; - ++texture_index) - { - data = stbi_load(texture_filenames[texture_index], &width, &height, - &number_channels, 0); - if (data) { - glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X+texture_index, 0, GL_RGB, - width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data); - fprintf(stdout, "[INFO]: Texture (\"%s\") is loaded successfully\n", - texture_filenames[texture_index]); - } else { - fprintf(stderr, "[ERROR]: Failed to load texture: \"%s\"\n", - texture_filenames[texture_index]); - } - stbi_image_free(data); - } - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); - return(texture_id); +U8 * read_entire_file(const char *filename) +{ + U8 *result; + FILE *f; + long file_size; + + result = 0; + + if (!filename) + return(result); + + f = fopen(filename, "rb"); + if (!f) + return(result); + + fseek(f, 0, SEEK_END); + file_size = ftell(f); + fseek(f, 0, SEEK_SET); + + result = malloc(file_size + 1); + fread(result, file_size, 1, f); + fclose(f); + + result[file_size] = 0; + + return(result); +} + +void * mmap_file(size_t *len, const char *filename) +{ + struct stat sb; + char* p; + int fd; + + fd = open(filename, O_RDONLY); + if (fd == -1) { + perror("open"); + return NULL; + } + + if (fstat(fd, &sb) == -1) { + perror("fstat"); + return NULL; + } + + if (!S_ISREG(sb.st_mode)) { + fprintf(stderr, "%s is not a file\n", filename); + return NULL; + } + + p = (char*)mmap(0, sb.st_size, PROT_READ, MAP_SHARED, fd, 0); + + if (p == MAP_FAILED) { + perror("mmap"); + return NULL; + } + + if (close(fd) == -1) { + perror("close"); + return NULL; + } + + (*len) = sb.st_size; + + return p; +} + +void read_entire_file_mmap(void* ctx, const char* filename, const int is_mtl, + const char* obj_filename, char** data, size_t* len) +{ + if (!filename) { + fprintf(stderr, "[ERROR]: Filename not provided (null)\n"); + *data = 0; + *len = 0; + return; + } + + size_t data_len = 0; + + *data = mmap_file(&data_len, filename); + *len = data_len; +} + +Mesh * mesh_load_obj(Arena *arena, const char *filename) +{ + tinyobj_attrib_t attrib; + tinyobj_shape_t *shapes = 0; + tinyobj_material_t *materials = 0; + size_t num_shapes, num_materials, num_triangles; + size_t i, j, face_offset; + U32 flags; + Mesh *mesh = 0; + + flags = TINYOBJ_FLAG_TRIANGULATE; + + S32 status = tinyobj_parse_obj(&attrib, &shapes, &num_shapes, + &materials, &num_materials, filename, + read_entire_file_mmap, 0, flags); + + if (status != TINYOBJ_SUCCESS) { + fprintf(stderr, "[ERROR]: Failed to parse \"%s\"\n", filename); + if (status == TINYOBJ_ERROR_INVALID_PARAMETER) + fprintf(stderr, "[ERROR]: TINYOBJ_ERROR_INVALID_PARAMETER\n"); + return(mesh); + } + + num_triangles = attrib.num_face_num_verts; + face_offset = 0; + + Vertex *vertices = arena_push_size(arena, sizeof(Vertex)*num_triangles*3); + U32 *indices = arena_push_size(arena, num_triangles*3*sizeof(U32)); + U32 vertex_count = 0; + U32 index_count = 0, index_index = 0; + for (i = 0; i < attrib.num_face_num_verts; ++i) { + tinyobj_vertex_index_t idx; + V3F pos, normal; + V2F tex_coords; + + Assert(attrib.face_num_verts[i]%3 == 0); + + Assert(attrib.face_num_verts[i]/3 > 3); + + Assert(attrib.num_texcoords); + + for (j = 0; j < 3; ++j) { + idx = attrib.faces[face_offset+j]; + Assert(idx.v_idx >= 0); + pos = v3f(attrib.vertices[3*idx.v_idx+0], + attrib.vertices[3*idx.v_idx+1], + attrib.vertices[3*idx.v_idx+2]); + + Assert(idx.vn_idx < (S32)attrib.num_normals); + normal = v3f(attrib.normals[3*idx.vn_idx+0], + attrib.normals[3*idx.vn_idx+1], + attrib.normals[3*idx.vn_idx+2]); + + Assert(idx.vt_idx < (S32)attrib.num_texcoords); + tex_coords = v2f(attrib.texcoords[2*idx.vt_idx+0], + attrib.texcoords[2*idx.vt_idx+1]); + + vertices[vertex_count++] = vertex(pos, normal, tex_coords); + Assert(index_count < attrib.num_faclibe_num_verts); + indices[index_index++] = index_count++; + } + + face_offset += 3; + } + + mesh = mesh_init(arena, vertices, vertex_count, + indices, num_triangles*3); + + tinyobj_attrib_free(&attrib); + tinyobj_shapes_free(shapes, num_shapes); + tinyobj_materials_free(materials, num_materials); + + return(mesh); +} + +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); + glShaderSource(shader, 1, &source, 0); + free((void *)source); + glCompileShader(shader); + 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); + } else { + fprintf(stdout, "[INFO]: \"%s\" compiled successfuly.\n", filename); + } + return(shader); +} + +U32 create_shader_program(char *vertex_shader_filename, + char *fragment_shader_filename) +{ + 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 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); + if (success == GL_FALSE) { + glGetProgramInfoLog(shader_program, 512, 0, logs); + fprintf(stderr, "[ERROR]: Failed to link shader program:\n%s", logs); + } else { + fprintf(stdout, "[INFO]: Shader program linked successfuly.\n\n"); + } + glDeleteShader(vertex_shader); + glDeleteShader(fragment_shader); + + return(shader_program); +} + +U32 create_shader_program_geom(char *vertex_shader_filename, + char *fragment_shader_filename, + char *geometry_shader_filename) +{ + 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); + if (success == GL_FALSE) { + glGetProgramInfoLog(shader_program, 512, 0, logs); + fprintf(stderr, "[ERROR]: Failed to link shader program:\n%s", + logs); + } else { + fprintf(stdout, "[INFO]: Shader program linked successfuly.\n\n"); + } + glDeleteShader(vertex_shader); + glDeleteShader(fragment_shader); + glDeleteShader(geometry_shader); + + return(shader_program); +} + +void shader_set_3f(U32 shader_program, char *uniform_name, F32 x, F32 y, F32 z) +{ + U32 uniform_location = glGetUniformLocation(shader_program, uniform_name); + glUniform3f(uniform_location, x, y, z); +} + +void shader_set_1f(U32 shader_program, char *uniform_name, F32 value) +{ + U32 uniform_location = glGetUniformLocation(shader_program, uniform_name); + glUniform1f(uniform_location, value); +} + +void shader_set_3fv(U32 shader_program, char *uniform_name, V3F value) +{ + U32 uniform_location = glGetUniformLocation(shader_program, uniform_name); + glUniform3fv(uniform_location, 1, (const GLfloat *)&value); +} + +void shader_set_2fv(U32 shader_program, char *uniform_name, V2F value) +{ + U32 uniform_location = glGetUniformLocation(shader_program, uniform_name); + glUniform2fv(uniform_location, 1, (const GLfloat *)&value); +} + +void shader_set_mat4fv(U32 shader_program, char *uniform_name, MAT4 value) +{ + U32 uniform_location = glGetUniformLocation(shader_program, uniform_name); + glUniformMatrix4fv(uniform_location, 1, GL_FALSE, (F32 *)&value); +} + +void shader_set_1i(U32 shader_program, char *uniform_name, S32 value) +{ + U32 uniform_location = glGetUniformLocation(shader_program, uniform_name); + glUniform1i(uniform_location, 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); + U8 *data = stbi_load(texture_filename, &width, &height, &number_channels, 0); + if (data) { + GLenum format = 0; + if (number_channels == 1) + format = GL_RED; + else if (number_channels == 3) + format = GL_RGB; + else if (number_channels == 4) + format = GL_RGBA; + + glBindTexture(GL_TEXTURE_2D, texture_id); + glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, GL_UNSIGNED_BYTE, data); + glGenerateMipmap(GL_TEXTURE_2D); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + 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); + } else { + fprintf(stderr, "[ERROR]: Failed to load texture: \"%s\"\n", + texture_filename); + } + stbi_image_free(data); + + return(texture_id); +} + +U32 load_texture_gamma(char *filename, B32 gamma_correction) +{ + S32 width, height, number_channels; + U32 texture_id; + + glGenTextures(1, &texture_id); + + stbi_set_flip_vertically_on_load(1); + U8 *data = stbi_load(filename, &width, &height, &number_channels, 0); + if (data) { + GLenum internal_format, data_format; + if (number_channels == 1) { + internal_format = data_format = GL_RED; + } else if (number_channels == 3) { + internal_format = gamma_correction ? GL_SRGB : GL_RGB; + data_format = GL_RGB; + } else if (number_channels == 4) { + internal_format = gamma_correction ? GL_SRGB_ALPHA : GL_RGBA; + data_format = GL_RGBA; + } + + glBindTexture(GL_TEXTURE_2D, texture_id); + glTexImage2D(GL_TEXTURE_2D, 0, internal_format, width, height, + 0, data_format, GL_UNSIGNED_BYTE, data); + glGenerateMipmap(GL_TEXTURE_2D); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glBindTexture(GL_TEXTURE_2D, 0); + + fprintf(stdout, "[INFO]: Texture (\"%s\") is loaded successfully\n", filename); + } else { + fprintf(stderr, "[ERROR]: Failed to load texture: \"%s\"\n", filename); + } + stbi_image_free(data); + + return(texture_id); +} + +U32 load_cubemap(const char *texture_filenames[6]) +{ + U32 texture_id; + glGenTextures(1, &texture_id); + glBindTexture(GL_TEXTURE_CUBE_MAP, texture_id); + S32 width, height, number_channels; + U8 *data = 0; + stbi_set_flip_vertically_on_load(0); + for (U32 i = 0; i < 6; ++i) { + data = stbi_load(texture_filenames[i], &width, &height, + &number_channels, 0); + if (data) { + glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X+i, 0, GL_RGB, + width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data); + fprintf(stdout, "[INFO]: Texture (\"%s\") is loaded successfully\n", + texture_filenames[i]); + } else { + fprintf(stderr, "[ERROR]: Failed to load texture: \"%s\"\n", + texture_filenames[i]); + } + stbi_image_free(data); + } + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); + return(texture_id); } typedef struct { - V3F translate; - V3F scale; - V3F rotate; + V3F translate; + V3F scale; + V3F rotate; } Transform; enum KeyState_Enum { - KeyState_RELEASE = 0, - KeyState_PRESS = 1 + KeyState_RELEASE = 0, + KeyState_PRESS = 1 }; typedef struct { - enum KeyState_Enum last; - enum KeyState_Enum state; + enum KeyState_Enum last; + enum KeyState_Enum state; } Key; typedef struct { - Key move_right; - Key move_forward; - Key move_left; - Key move_backward; - Key move_up; - Key move_down; - Key jump; - Key action_right; - Key action_up; - Key action_left; - Key action_down; - Key exit; - V2F last_mouse_pos; - V2F mouse_offset; + Key move_right; + Key move_forward; + Key move_left; + Key move_backward; + Key move_up; + Key move_down; + Key jump; + Key action_right; + Key action_up; + Key action_left; + Key action_down; + Key exit; + V2F last_mouse_pos; + V2F mouse_offset; + B32 first_mouse; } Input; -void -input_update_last_state(Input *input) +Input input_init() { - input->move_right.last = input->move_right.state; - input->move_forward.last = input->move_forward.state; - input->move_left.last = input->move_left.state; - input->move_backward.last = input->move_backward.state; - input->move_up.last = input->move_up.state; - input->move_down.last = input->move_down.state; - input->jump.last = input->jump.state; - input->action_right.last = input->action_right.state; - input->action_up.last = input->action_up.state; - input->action_left.last = input->action_left.state; - input->action_down.last = input->action_down.state; - input->exit.last = input->exit.state; + Input r = {0}; + r.first_mouse = 1; + return(r); } -void -process_glfw_key(GLFWwindow *window, S32 glfw_keycode, Key *key) +void input_update_last_state(Input *input) { - if (glfwGetKey(window, glfw_keycode) == GLFW_PRESS) - key->state = KeyState_PRESS; - else - key->state = KeyState_RELEASE; + input->move_right.last = input->move_right.state; + input->move_forward.last = input->move_forward.state; + input->move_left.last = input->move_left.state; + input->move_backward.last = input->move_backward.state; + input->move_up.last = input->move_up.state; + input->move_down.last = input->move_down.state; + input->jump.last = input->jump.state; + input->action_right.last = input->action_right.state; + input->action_up.last = input->action_up.state; + input->action_left.last = input->action_left.state; + input->action_down.last = input->action_down.state; + input->exit.last = input->exit.state; } -void -process_glfw_keyboard(GLFWwindow *window, Input *input) +void process_glfw_key(GLFWwindow *window, S32 glfw_keycode, Key *key) { - process_glfw_key(window, GLFW_KEY_D, &input->move_right); - process_glfw_key(window, GLFW_KEY_W, &input->move_forward); - process_glfw_key(window, GLFW_KEY_A, &input->move_left); - process_glfw_key(window, GLFW_KEY_S, &input->move_backward); - process_glfw_key(window, GLFW_KEY_E, &input->move_up); - process_glfw_key(window, GLFW_KEY_Q, &input->move_down); - process_glfw_key(window, GLFW_KEY_SPACE, &input->jump); - process_glfw_key(window, GLFW_KEY_RIGHT, &input->action_right); - process_glfw_key(window, GLFW_KEY_UP, &input->action_up); - process_glfw_key(window, GLFW_KEY_LEFT, &input->action_left); - process_glfw_key(window, GLFW_KEY_DOWN, &input->action_down); - process_glfw_key(window, GLFW_KEY_ESCAPE, &input->exit); + if (glfwGetKey(window, glfw_keycode) == GLFW_PRESS) + key->state = KeyState_PRESS; + else + key->state = KeyState_RELEASE; } -void -error_callback(int error, const char *desc) +void process_glfw_keyboard(GLFWwindow *window, Input *input) { - fprintf(stderr, "[ERROR] GLFW: %s\n", desc); + process_glfw_key(window, GLFW_KEY_D, &input->move_right); + process_glfw_key(window, GLFW_KEY_W, &input->move_forward); + process_glfw_key(window, GLFW_KEY_A, &input->move_left); + process_glfw_key(window, GLFW_KEY_S, &input->move_backward); + process_glfw_key(window, GLFW_KEY_E, &input->move_up); + process_glfw_key(window, GLFW_KEY_Q, &input->move_down); + process_glfw_key(window, GLFW_KEY_SPACE, &input->jump); + process_glfw_key(window, GLFW_KEY_RIGHT, &input->action_right); + process_glfw_key(window, GLFW_KEY_UP, &input->action_up); + process_glfw_key(window, GLFW_KEY_LEFT, &input->action_left); + process_glfw_key(window, GLFW_KEY_DOWN, &input->action_down); + process_glfw_key(window, GLFW_KEY_ESCAPE, &input->exit); } -B32 -key_is_pressed(Key key) +void process_glfw_mouse_pos(GLFWwindow *window, Input *input) +{ + F64 xpos, ypos; + glfwGetCursorPos(window, &xpos, &ypos); + if (input->first_mouse) { + input->last_mouse_pos = v2f((F32)xpos, (F32)ypos); + input->first_mouse = 0; + } + input->mouse_offset = v2f(input->mouse_offset.x+((F32)xpos-input->last_mouse_pos.x), + input->mouse_offset.y+((F32)ypos-input->last_mouse_pos.y)); + input->last_mouse_pos = v2f((F32)xpos, (F32)ypos); +} + + +void error_callback(int error, const char *desc) { - B32 result = (key.state == KeyState_PRESS); - return(result); + fprintf(stderr, "[ERROR] GLFW: %s\n", desc); } -B32 -key_first_press(Key key) +B32 key_is_pressed(Key key) { - B32 result = ((key.last == KeyState_RELEASE) && - (key.state == KeyState_PRESS)); - return(result); + B32 result = (key.state == KeyState_PRESS); + return(result); } -B32 -key_was_pressed(Key key) +B32 key_first_press(Key key) { - B32 result = ((key.last == KeyState_PRESS) && - (key.state == KeyState_RELEASE)); - return(result); + B32 result = ((key.last == KeyState_RELEASE) && + (key.state == KeyState_PRESS)); + return(result); } -MAT4 -mat4_change_basis(V3F x, V3F y, V3F z) +B32 key_was_pressed(Key key) { - MAT4 result = mat4_identity(); - result.m0 = v4f(x.x, x.y, x.z, 0.0f); - result.m1 = v4f(y.x, y.y, y.z, 0.0f); - result.m2 = v4f(z.x, z.y, z.z, 0.0f); - return(result); + B32 result = ((key.last == KeyState_PRESS) && + (key.state == KeyState_RELEASE)); + return(result); +} + +MAT4 mat4_change_basis(V3F x, V3F y, V3F z) +{ + MAT4 result = mat4_identity(); + result.m0 = v4f(x.x, x.y, x.z, 0.0f); + result.m1 = v4f(y.x, y.y, y.z, 0.0f); + result.m2 = v4f(z.x, z.y, z.z, 0.0f); + return(result); } /* @@ -549,261 +534,242 @@ mat4_change_basis(V3F x, V3F y, V3F z) * | 0 cx -sx |*| 0 1 0 |*| sz cz 0 |=| sx*sy*cz+cx*sz -sx*sy*sz+cx*cz -sx*cy | * | 0 sx cx | | -sy 0 cy | | 0 0 1 | | -cx*sy*cz+sx*sz cx*sy*sz+sx*cz cx*cy | */ -MAT4 -mat4_make_rotate(V3F angles) +MAT4 mat4_make_rotate(V3F angles) { - F32 angle, cx, sx, cy, sy, cz, sz; - MAT4 result; - V3F newx, newy, newz; - - angle = DEG2RAD*angles.x; - cx = f32_cos(angle); - sx = f32_sin(angle); - angle = DEG2RAD*angles.y; - cy = f32_cos(angle); - sy = f32_sin(angle); - angle = DEG2RAD*angles.z; - cz = f32_cos(angle); - sz = f32_sin(angle); - - newx = v3f(cy*cz, sx*sy*cz+cx*sz, -cx*sy*cz+sx*sz); - newy = v3f(-cy*sz, -sx*sy*sz+cx*cz, cx*sy*sz+sx*cz); - newz = v3f(sy, -sx*cy, cx*cy); - result = mat4_change_basis(newx, newy, newz); - - return(result); + F32 angle, cx, sx, cy, sy, cz, sz; + MAT4 result; + V3F newx, newy, newz; + + angle = DEG2RAD*angles.x; + cx = f32_cos(angle); + sx = f32_sin(angle); + angle = DEG2RAD*angles.y; + cy = f32_cos(angle); + sy = f32_sin(angle); + angle = DEG2RAD*angles.z; + cz = f32_cos(angle); + sz = f32_sin(angle); + + newx = v3f(cy*cz, sx*sy*cz+cx*sz, -cx*sy*cz+sx*sz); + newy = v3f(-cy*sz, -sx*sy*sz+cx*cz, cx*sy*sz+sx*cz); + newz = v3f(sy, -sx*cy, cx*cy); + result = mat4_change_basis(newx, newy, newz); + + return(result); } -MAT4 -mat4_rotate_angles(MAT4 source, V3F angles) +MAT4 mat4_rotate_angles(MAT4 source, V3F angles) { - MAT4 rotate = mat4_make_rotate(angles); - MAT4 result = mat4_mul(rotate, source); - return(result); + MAT4 rotate = mat4_make_rotate(angles); + MAT4 result = mat4_mul(rotate, source); + return(result); } -Transform -transform_make(V3F translate, V3F scale, V3F rotate) +Transform transform_make(V3F translate, V3F scale, V3F rotate) { - Transform result; - result.translate = translate; - result.scale = scale; - result.rotate = rotate; - return(result); + Transform result; + result.translate = translate; + result.scale = scale; + result.rotate = rotate; + return(result); } -Transform -transform_default() +Transform transform_default() { - Transform result = transform_make(v3f_zero(), v3f_one(), v3f_zero()); - return(result); + Transform result = transform_make(v3f_zero(), v3f_one(), v3f_zero()); + return(result); } -Transform -transform_make_translate(V3F translate) +Transform transform_make_translate(V3F translate) { - Transform result = transform_default(); - result.translate = translate; - return(result); + Transform result = transform_default(); + result.translate = translate; + return(result); } -Transform -transform_make_scale(V3F scale) +Transform transform_make_scale(V3F scale) { - Transform result = transform_default(); - result.scale = scale; - return(result); + Transform result = transform_default(); + result.scale = scale; + return(result); } -Transform -transform_make_rotate(V3F angles) +Transform transform_make_rotate(V3F angles) { - Transform result = transform_default(); - result.rotate = angles; - return(result); + Transform result = transform_default(); + result.rotate = angles; + return(result); } -Transform -transform_translate(Transform source, V3F translate) +Transform transform_translate(Transform source, V3F translate) { - Transform result = source; - result.translate = v3f_add(source.translate, translate); - return(result); + Transform result = source; + result.translate = v3f_add(source.translate, translate); + return(result); } -Transform -transform_scale(Transform source, V3F scale) +Transform transform_scale(Transform source, V3F scale) { - Transform result = source; - result.scale = v3f_dot(source.scale, scale); - return(result); + Transform result = source; + result.scale = v3f_dot(source.scale, scale); + return(result); } -Transform -transform_rotate(Transform source, V3F angles) +Transform transform_rotate(Transform source, V3F angles) { - Transform result; - result.translate = source.translate; - result.scale = source.scale; - result.rotate = v3f_add(source.rotate, angles); - return(result); + Transform result; + result.translate = source.translate; + result.scale = source.scale; + result.rotate = v3f_add(source.rotate, angles); + return(result); } -Transform -transform_make_scale_translate(V3F scale, V3F translate) +Transform transform_make_scale_translate(V3F scale, V3F translate) { - Transform result = transform_default(); - result.translate = translate; - result.scale = scale; - return(result); + Transform result = transform_default(); + result.translate = translate; + result.scale = scale; + return(result); } -MAT4 -transform_apply(Transform transform) +MAT4 transform_apply(Transform transform) { - MAT4 result = mat4_identity(); - MAT4 translate = mat4_make_translate(transform.translate); - MAT4 scale = mat4_make_scale(transform.scale); - MAT4 rotate = mat4_make_rotate(transform.rotate); - result = mat4_mul(mat4_mul(translate, scale), rotate); - return(result); + MAT4 result = mat4_identity(); + MAT4 translate = mat4_make_translate(transform.translate); + MAT4 scale = mat4_make_scale(transform.scale); + MAT4 rotate = mat4_make_rotate(transform.rotate); + result = mat4_mul(mat4_mul(translate, scale), rotate); + return(result); } -MAT4 -ortho(F32 l, F32 r, F32 b, F32 t, F32 n, F32 f) +MAT4 ortho(F32 l, F32 r, F32 b, F32 t, F32 n, F32 f) { - MAT4 result = mat4_identity(); - result.m0.x = 2.0f/(r-l); - result.m1.y = 2.0f/(t-b); - result.m2.z = -2.0f/(f-n); - result.m3.x = -(r+l)/(r-l); - result.m3.y = -(t+b)/(t-b); - result.m3.z = -(f+n)/(f-n); - return(result); + MAT4 result = mat4_identity(); + result.m0.x = 2.0f/(r-l); + result.m1.y = 2.0f/(t-b); + result.m2.z = -2.0f/(f-n); + result.m3.x = -(r+l)/(r-l); + result.m3.y = -(t+b)/(t-b); + result.m3.z = -(f+n)/(f-n); + return(result); } -MAT4 -perspective(F32 fovx, F32 ar, F32 n, F32 f) +MAT4 perspective(F32 fovx, F32 ar, F32 n, F32 f) { - F32 r = n*f32_tan(fovx/2.0f*DEG2RAD); - F32 t = r/ar; - MAT4 result = mat4_identity(); - result.m0.x = n/r; - result.m1.y = n/t; - result.m2.z = -(f+n)/(f-n); - result.m2.w = -1.0f; - result.m3.z = (-2.0f*f*n)/(f-n); - result.m3.w = 0.0f; - return(result); + F32 r = n*f32_tan(fovx/2.0f*DEG2RAD); + F32 t = r/ar; + MAT4 result = mat4_identity(); + result.m0.x = n/r; + result.m1.y = n/t; + result.m2.z = -(f+n)/(f-n); + result.m2.w = -1.0f; + result.m3.z = (-2.0f*f*n)/(f-n); + result.m3.w = 0.0f; + return(result); } -MAT4 -look_at(V3F eye, V3F target, V3F up) +MAT4 look_at(V3F eye, V3F target, V3F up) { - V3F f = v3f_norm(v3f_sub(eye, target)); - V3F l = v3f_norm(v3f_cross(up, f)); - V3F u = v3f_cross(f, l); - MAT4 translate = mat4_make_translate(v3f_negate(eye)); - MAT4 rotate = mat4_change_basis(l, u, f); - MAT4 result = mat4_mul(mat4_transpose(rotate), translate); - return(result); + V3F f = v3f_norm(v3f_sub(eye, target)); + V3F l = v3f_norm(v3f_cross(up, f)); + V3F u = v3f_cross(f, l); + MAT4 translate = mat4_make_translate(v3f_negate(eye)); + MAT4 rotate = mat4_change_basis(l, u, f); + MAT4 result = mat4_mul(mat4_transpose(rotate), translate); + return(result); } typedef struct { - V3F pos; - F32 fovx; - F32 near; - F32 far; - - /* NOTE(pryazha): In degrees */ - F32 yaw; - F32 pitch; + V3F pos; + F32 fovx; + F32 near; + F32 far; + + /* NOTE(pryazha): In degrees */ + F32 yaw; + F32 pitch; } Camera; -MAT4 -get_view_matrix(Camera *camera) -{ - MAT4 view; - view = mat4_make_translate(v3f_negate(camera->pos)); - view = mat4_rotate_angles(view, v3f(camera->pitch, camera->yaw, 0.0f)); - return(view); -} - -V3F -get_dv_camera_orbital(Input *input, V3F pos, V3F target, - F32 dt, F32 acceleration) -{ - V3F up, f, l, u, dv; - - up = v3f(0.0f, 1.0f, 0.0f); - f = v3f_norm(v3f_sub(target, pos)); - l = v3f_norm(v3f_cross(up, f)); - u = v3f_cross(f, l); - - dv = v3f_zero(); - - if (key_is_pressed(input->move_right)) - dv = v3f_sub(dv, l); - if (key_is_pressed(input->move_forward)) - dv = v3f_add(dv, f); - if (key_is_pressed(input->move_left)) - dv = v3f_add(dv, l); - if (key_is_pressed(input->move_backward)) - dv = v3f_sub(dv, f); - if (key_is_pressed(input->move_up)) - dv = v3f_add(dv, u); - if (key_is_pressed(input->move_down)) - dv = v3f_sub(dv, u); - - dv = v3f_norm(dv); - - dv = v3f_scalef(dv, acceleration*dt); - - return(dv); -} - -void -get_camera_vectors(Camera *camera, V3F *l, V3F *u, V3F *f) -{ - MAT4 view; - view = get_view_matrix(camera); - *l = v3f(-view.m0.x, -view.m1.x, -view.m2.x); - *u = v3f(view.m0.y, view.m1.y, view.m2.y); - *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 f, l, u, dv; - get_camera_vectors(camera, &l, &u, &f); - - dv = v3f_zero(); - - if (key_is_pressed(input->move_right)) - dv = v3f_sub(dv, l); - if (key_is_pressed(input->move_forward)) - dv = v3f_add(dv, f); - if (key_is_pressed(input->move_left)) - dv = v3f_add(dv, l); - if (key_is_pressed(input->move_backward)) - dv = v3f_sub(dv, f); - if (key_is_pressed(input->move_up)) - dv = v3f_add(dv, u); - if (key_is_pressed(input->move_down)) - dv = v3f_sub(dv, u); - - dv = v3f_norm(dv); - - dv = v3f_scalef(dv, acceleration*dt); - - return(dv); +MAT4 get_view_matrix(Camera *camera) +{ + MAT4 view; + view = mat4_make_translate(v3f_negate(camera->pos)); + view = mat4_rotate_angles(view, v3f(camera->pitch, camera->yaw, 0.0f)); + return(view); +} + +V3F get_dv_camera_orbital(Input *input, V3F pos, V3F target, + F32 dt, F32 acceleration) +{ + V3F up, f, l, u, dv; + + up = v3f(0.0f, 1.0f, 0.0f); + f = v3f_norm(v3f_sub(target, pos)); + l = v3f_norm(v3f_cross(up, f)); + u = v3f_cross(f, l); + + dv = v3f_zero(); + + if (key_is_pressed(input->move_right)) + dv = v3f_sub(dv, l); + if (key_is_pressed(input->move_forward)) + dv = v3f_add(dv, f); + if (key_is_pressed(input->move_left)) + dv = v3f_add(dv, l); + if (key_is_pressed(input->move_backward)) + dv = v3f_sub(dv, f); + if (key_is_pressed(input->move_up)) + dv = v3f_add(dv, u); + if (key_is_pressed(input->move_down)) + dv = v3f_sub(dv, u); + + dv = v3f_norm(dv); + + dv = v3f_scalef(dv, acceleration*dt); + + return(dv); +} + +void get_camera_vectors(Camera *camera, V3F *l, V3F *u, V3F *f) +{ + MAT4 view; + view = get_view_matrix(camera); + *l = v3f(-view.m0.x, -view.m1.x, -view.m2.x); + *u = v3f(view.m0.y, view.m1.y, view.m2.y); + *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 f, l, u, dv; + get_camera_vectors(camera, &l, &u, &f); + + dv = v3f_zero(); + + if (key_is_pressed(input->move_right)) + dv = v3f_sub(dv, l); + if (key_is_pressed(input->move_forward)) + dv = v3f_add(dv, f); + if (key_is_pressed(input->move_left)) + dv = v3f_add(dv, l); + if (key_is_pressed(input->move_backward)) + dv = v3f_sub(dv, f); + if (key_is_pressed(input->move_up)) + dv = v3f_add(dv, u); + if (key_is_pressed(input->move_down)) + dv = v3f_sub(dv, u); + + dv = v3f_norm(dv); + + dv = v3f_scalef(dv, acceleration*dt); + + return(dv); } typedef struct { - Camera camera; - F32 dt; + Camera camera; + F32 dt; } State; #endif /* COMMON_H */ |