From 9900ffe840ee0e9f914b0e7956a4e80ffb553e9e Mon Sep 17 00:00:00 2001 From: talha Date: Tue, 16 Apr 2024 02:04:23 +0500 Subject: Added refraction, albeit slightly limited --- source/main.cpp | 81 ++++++++++++++++++++++++++++++++++++++++----- source/shaders/refr.fs.glsl | 15 +++++++++ source/shaders/refr.vs.glsl | 20 +++++++++++ 3 files changed, 107 insertions(+), 9 deletions(-) create mode 100644 source/shaders/refr.fs.glsl create mode 100644 source/shaders/refr.vs.glsl (limited to 'source') diff --git a/source/main.cpp b/source/main.cpp index ede861f..b4b9e2c 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -563,12 +563,15 @@ int main(int argc, char* argv[]) char* cubemap_fs = (char*)SDL_LoadFile("./source/shaders/cubemap.fs.glsl", &read_count); char* refl_vs = (char*)SDL_LoadFile("./source/shaders/refl.vs.glsl", &read_count); char* refl_fs = (char*)SDL_LoadFile("./source/shaders/refl.fs.glsl", &read_count); + char* refr_vs = (char*)SDL_LoadFile("./source/shaders/refr.vs.glsl", &read_count); + char* refr_fs = (char*)SDL_LoadFile("./source/shaders/refr.fs.glsl", &read_count); u32 shader_program = gl_shader_program(vertex_source, fragment_source); u32 blend_shader_program = gl_shader_program(vertex_source, blend_shader_source); u32 fbo_shader_program = gl_shader_program(fbo_vs, fbo_fs); u32 cubemap_shader_program = gl_shader_program(cubemap_vs, cubemap_fs); u32 refl_shader_program = gl_shader_program(refl_vs, refl_fs); + u32 refr_shader_program = gl_shader_program(refr_vs, refr_fs); printf("Successfully compiled shaders.\n"); @@ -714,6 +717,7 @@ int main(int argc, char* argv[]) // 5.0f, 0.5f, 5.0f, 0.0f, 1.0f, 0.0f,// bottom-right //-5.0f, 0.5f, -5.0f, 0.0f, 1.0f, 0.0f,// top-left //-5.0f, 0.5f, 5.0f, 0.0f, 1.0f, 0.0f,// bottom-left +#if REFLECTIVE_PLANE // Back face -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, // Bottom-left 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, // top-right @@ -749,19 +753,37 @@ int main(int argc, char* argv[]) 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, // bottom-left -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, // bottom-right -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, // top-right +#endif // Top face - -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, // top-left - 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, // bottom-right - 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, // top-right - 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, // bottom-right - -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, // top-left - -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f // bottom-left + -4.0f, 0.0f, -4.0f, 0.0f, 1.0f, 0.0f, // top-left + 4.0f, 0.0f, 4.0f, 0.0f, 1.0f, 0.0f, // bottom-right + 4.0f, 0.0f, -4.0f, 0.0f, 1.0f, 0.0f, // top-right + 4.0f, 0.0f, 4.0f, 0.0f, 1.0f, 0.0f, // bottom-right + -4.0f, 0.0f, -4.0f, 0.0f, 1.0f, 0.0f, // top-left + -4.0f, 0.0f, 4.0f, 0.0f, 1.0f, 0.0f // bottom-left + }; + + float refrVertices[] = { + // Left face + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, // top-right + -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, // top-left + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, // bottom-left + -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, // bottom-left + -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, // bottom-right + -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, // top-right + // Right face + -0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, // top-left + -0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, // bottom-right + -0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, // top-right + -0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, // bottom-right + -0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, // top-left + -0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, // bottom-left }; stbi_set_flip_vertically_on_load(1); u32 cube_vao, cube_vbo, plane_vao, plane_vbo, quad_vao, quad_vbo, fbo_vao, fbo_vbo, - skybox_vao, skybox_vbo, refl_vao, refl_vbo; + skybox_vao, skybox_vbo, refl_vao, refl_vbo, refr_vao, refr_vbo; glGenVertexArrays(1, &cube_vao); glGenBuffers(1, &cube_vbo); @@ -836,6 +858,19 @@ int main(int argc, char* argv[]) glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3*sizeof(float))); glBindVertexArray(0); + // refractive surface objects + glGenVertexArrays(1, &refr_vao); + glGenBuffers(1, &refr_vbo); + + glBindVertexArray(refr_vao); + glBindBuffer(GL_ARRAY_BUFFER, refr_vbo); + glBufferData(GL_ARRAY_BUFFER, sizeof(refrVertices), &refrVertices, GL_STATIC_DRAW); + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0); + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3*sizeof(float))); + glBindVertexArray(0); + u32 window_tex_id; glGenTextures(1, &window_tex_id); glActiveTexture(GL_TEXTURE2); @@ -869,7 +904,6 @@ int main(int argc, char* argv[]) printf("failed to load image texture at path: %s", path); stbi_image_free(data); } - } u32 cube_tex_id; @@ -891,6 +925,7 @@ int main(int argc, char* argv[]) Vec3{ -2.5, 0.0, -0.5}, // 4: square to the left Vec3{ -1.0, 0.0, -1.5}, // 5: random square behind window between squares Vec3{ -1.0, 0.0, -8.0}, // 6: reflective plane + Vec3{ -1.0, 2.0, -8.0}, // 6: refractive "window" }; r32 FOV = 90.0; @@ -930,6 +965,9 @@ int main(int argc, char* argv[]) proj_loc = glGetUniformLocation(refl_shader_program, "Projection"); glUniformMatrix4fv(proj_loc, 1, GL_TRUE, proj.buffer); + glUseProgram(refr_shader_program); + proj_loc = glGetUniformLocation(refr_shader_program, "Projection"); + glUniformMatrix4fv(proj_loc, 1, GL_TRUE, proj.buffer); glEnable(GL_DEPTH_TEST); glEnable(GL_BLEND); @@ -1022,6 +1060,12 @@ int main(int argc, char* argv[]) glUniform1i(skybox_loc, 0); } + { + glUseProgram(refr_shader_program); + s32 skybox_loc = glGetUniformLocation(refr_shader_program, "skybox"); + glUniform1i(skybox_loc, 0); + } + u8 game_running = true; u8 hold_lshift = false; @@ -1153,6 +1197,10 @@ int main(int argc, char* argv[]) view_loc = glGetUniformLocation(refl_shader_program, "View"); glUniformMatrix4fv(view_loc, 1, GL_TRUE, view.buffer); + glUseProgram(refr_shader_program); + view_loc = glGetUniformLocation(refr_shader_program, "View"); + glUniformMatrix4fv(view_loc, 1, GL_TRUE, view.buffer); + glUseProgram(cubemap_shader_program); view_loc = glGetUniformLocation(cubemap_shader_program, "View"); view.xyzw[0].w = 0.0f; @@ -1242,7 +1290,22 @@ int main(int argc, char* argv[]) uint32_t camera_pos_loc = glGetUniformLocation(refl_shader_program, "cameraPos"); glUniform3fv(camera_pos_loc, 1, camera_pos.data); glBindVertexArray(refl_vao); - glDrawArrays(GL_TRIANGLES, 0, 36); + glDrawArrays(GL_TRIANGLES, 0, 6); + } + { // reflective plane + glUseProgram(refr_shader_program); + Vec3 translation_iter = model_translations[7]; + Mat4 model = init_value4m(1.0); + Mat4 model_translation = translation_matrix4m(translation_iter.x, translation_iter.y, translation_iter.z); + + model = multiply4m(model_translation, model); + uint32_t model_loc = glGetUniformLocation(refr_shader_program, "Model"); + glUniformMatrix4fv(model_loc, 1, GL_TRUE, model.buffer); + + uint32_t camera_pos_loc = glGetUniformLocation(refr_shader_program, "cameraPos"); + glUniform3fv(camera_pos_loc, 1, camera_pos.data); + glBindVertexArray(refr_vao); + glDrawArrays(GL_TRIANGLES, 0, 12); } { glDepthFunc(GL_LEQUAL); diff --git a/source/shaders/refr.fs.glsl b/source/shaders/refr.fs.glsl new file mode 100644 index 0000000..6747ded --- /dev/null +++ b/source/shaders/refr.fs.glsl @@ -0,0 +1,15 @@ +#version 330 core + +in vec3 Normal; +in vec3 Position; + +uniform samplerCube skybox; +uniform vec3 cameraPos; +out vec4 FragColor; + +void main() { + float refr_ratio = 1.0/1.52; + vec3 I = normalize(Position - cameraPos); + vec3 R = refract(I, normalize(Normal), refr_ratio); + FragColor = vec4(texture(skybox, R).rgb, 1.0); +}; diff --git a/source/shaders/refr.vs.glsl b/source/shaders/refr.vs.glsl new file mode 100644 index 0000000..0554f0a --- /dev/null +++ b/source/shaders/refr.vs.glsl @@ -0,0 +1,20 @@ +#version 330 core +layout(location=0) in vec3 aPos; +layout(location=1) in vec3 aNormal; + +uniform mat4 View; +uniform mat4 Model; +uniform mat4 Projection; + +out vec3 Normal; +out vec3 Position; + +void main() { + // @note: This is the calculation for getting the normal vector + // one that is unaffected by non-uniform scaling that is. + // look at the lighting chapter in learnopengl.com to understand this more + Normal = mat3(transpose(inverse(Model))) * aNormal; + Position = vec3(Model * vec4(aPos, 1.0)); + gl_Position = Projection * View * Model * vec4(aPos, 1.0); +}; + -- cgit v1.2.3