diff options
Diffstat (limited to 'source/main.cpp')
-rw-r--r-- | source/main.cpp | 179 |
1 files changed, 113 insertions, 66 deletions
diff --git a/source/main.cpp b/source/main.cpp index 7a2ee9a..2f07c0e 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -502,10 +502,10 @@ int main(int argc, char* argv[]) size_t read_count; char* vertex_source = (char*)SDL_LoadFile("./source/shaders/depth_test.vs.glsl", &read_count); char* fragment_source = (char*)SDL_LoadFile("./source/shaders/depth_test.fs.glsl", &read_count); - char* outline_shader_source = (char*)SDL_LoadFile("./source/shaders/stencil_outline.fs.glsl", &read_count); + char* blend_shader_source = (char*)SDL_LoadFile("./source/shaders/blend_test.fs.glsl", &read_count); u32 shader_program = gl_shader_program(vertex_source, fragment_source); - u32 outline_shader_program = gl_shader_program(vertex_source, outline_shader_source); + u32 blend_shader_program = gl_shader_program(vertex_source, blend_shader_source); printf("Successfully compiled shaders.\n"); @@ -563,10 +563,18 @@ int main(int argc, char* argv[]) -5.0f, -0.5f, -5.0f, 0.0f, 2.0f, 5.0f, -0.5f, -5.0f, 2.0f, 2.0f }; - + float quadVertices[] = { + // positions // texture Coords + -0.5f, -0.5f, 0.0f, 0.0f, + 0.5f, -0.5f, 1.0f, 0.0f, + 0.5f, 0.5f, 1.0f, 1.0f, + 0.5f, 0.5f, 1.0f, 1.0f, + -0.5f, 0.5f, 0.0f, 1.0f, + -0.5f, -0.5f, 0.0f, 0.0f, + }; stbi_set_flip_vertically_on_load(1); - u32 cube_vao, cube_vbo, plane_vao, plane_vbo; + u32 cube_vao, cube_vbo, plane_vao, plane_vbo, quad_vao, quad_vbo; glGenVertexArrays(1, &cube_vao); glGenBuffers(1, &cube_vbo); @@ -592,6 +600,18 @@ int main(int argc, char* argv[]) glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3*sizeof(float))); glBindVertexArray(0); + glGenVertexArrays(1, &quad_vao); + glGenBuffers(1, &quad_vbo); + + glBindVertexArray(quad_vao); + glBindBuffer(GL_ARRAY_BUFFER, quad_vbo); + glBufferData(GL_ARRAY_BUFFER, sizeof(quadVertices), &quadVertices, GL_STATIC_DRAW); + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)0); + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)(2*sizeof(float))); + glBindVertexArray(0); + u32 cube_tex_id; glGenTextures(1, &cube_tex_id); glActiveTexture(GL_TEXTURE0); @@ -602,13 +622,51 @@ int main(int argc, char* argv[]) glActiveTexture(GL_TEXTURE1); gl_load_texture(plane_tex_id, "assets/smiling.png"); + u32 window_tex_id; + glGenTextures(1, &window_tex_id); + glActiveTexture(GL_TEXTURE2); + { + u32 texture_id = window_tex_id; + char *path = "assets/window.png"; + s32 width, height, nrChannels; + unsigned char *data = stbi_load(path, &width, &height, &nrChannels, 0); + if (data) + { + GLenum format; + if (nrChannels == 1) + format = GL_RED; + else if (nrChannels == 3) + format = GL_RGB; + else if (nrChannels == 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_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + stbi_image_free(data); + } + else + { + printf("failed to load image texture at path: %s", path); + stbi_image_free(data); + } + +} + // objects Vec3 model_translations[] = { - Vec3{ 0.0, 0.0, 0.0}, - Vec3{ -1.0, 0.0, -2.0}, - Vec3{ -1.0, 0.0, -2.0}, - Vec3{ -3.0, 5.0, -6.0}, - Vec3{ 3.0, -7.0, -6.0}, + Vec3{ 0.5, 0.0, 0.0}, //origin square + Vec3{ -1.0, 0.0, -1.0}, // plane + Vec3{ -1.0, 0.0, -0.5}, // window between squares + Vec3{ 0.0, 0.0, 3.0}, //window infront of origin square + Vec3{ -2.5, 0.0, -0.5}, // square to the left + Vec3{ -1.0, 0.0, -1.5}, // random square behind window between squares }; r32 FOV = 90.0; @@ -636,13 +694,13 @@ int main(int argc, char* argv[]) uint32_t proj_loc = glGetUniformLocation(shader_program, "Projection"); glUniformMatrix4fv(proj_loc, 1, GL_TRUE, proj.buffer); - glUseProgram(outline_shader_program); - proj_loc = glGetUniformLocation(outline_shader_program, "Projection"); + glUseProgram(blend_shader_program); + proj_loc = glGetUniformLocation(blend_shader_program, "Projection"); glUniformMatrix4fv(proj_loc, 1, GL_TRUE, proj.buffer); glEnable(GL_DEPTH_TEST); + glEnable(GL_BLEND); glDepthFunc(GL_LESS); - glEnable(GL_STENCIL_TEST); u8 game_running = true; @@ -767,25 +825,18 @@ int main(int argc, char* argv[]) uint32_t view_loc = glGetUniformLocation(shader_program, "View"); glUniformMatrix4fv(view_loc, 1, GL_TRUE, view.buffer); - glUseProgram(outline_shader_program); - view_loc = glGetUniformLocation(outline_shader_program, "View"); + glUseProgram(blend_shader_program); + view_loc = glGetUniformLocation(blend_shader_program, "View"); glUniformMatrix4fv(view_loc, 1, GL_TRUE, view.buffer); time_prev = time_curr; // OUTPUT - glEnable(GL_DEPTH_TEST); - glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); - glStencilFunc(GL_ALWAYS, 1, 0xFF); - glClearColor(1.0f, 0.6f, .6f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); - // if no outline - // @note: if we do not disable writing to the stencil buffer here, the data from the plane fills the stencil buffer. - // That gets treated as part of whatever fragments we are trying to outline - glStencilMask(0x00); - { + glDisable(GL_BLEND); + { //plane glUseProgram(shader_program); s32 tex_id_loc = glGetUniformLocation(shader_program, "TexId"); glUniform1i(tex_id_loc, 1); @@ -799,10 +850,9 @@ int main(int argc, char* argv[]) glDrawArrays(GL_TRIANGLES, 0, 6); } - // always pass stencil test so the stencil buffer is loaded wherever fragment exists - glStencilMask(0xFF); - glStencilFunc(GL_ALWAYS, 1, 0xFF); - { + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + {//origin square glUseProgram(shader_program); s32 tex_id_loc = glGetUniformLocation(shader_program, "TexId"); glUniform1i(tex_id_loc, 0); @@ -815,11 +865,11 @@ int main(int argc, char* argv[]) glBindVertexArray(cube_vao); glDrawArrays(GL_TRIANGLES, 0, 36); } - { + {//square to the left glUseProgram(shader_program); s32 tex_id_loc = glGetUniformLocation(shader_program, "TexId"); glUniform1i(tex_id_loc, 0); - Vec3 translation_iter = model_translations[2]; + Vec3 translation_iter = model_translations[4]; 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); @@ -828,56 +878,53 @@ int main(int argc, char* argv[]) glBindVertexArray(cube_vao); glDrawArrays(GL_TRIANGLES, 0, 36); } - - // drawing the outline - // @note: if we don't disable the depth buffer, then the objects will not be highlighted if something is in the - // view i.e, at a lower depth value - glDisable(GL_DEPTH_TEST); - // @note: im not entirely sure why we need to disable writing to the stencil buffer here - // based on my testing, if we don't disable this, the highlight color that gets drawn front - // will cover the stencil values wherever it is. If we disable this, then the highlight color - // that draws last will draw over the other highlights - glStencilMask(0x00); - glStencilFunc(GL_NOTEQUAL, 1, 0xFF); - { - glUseProgram(outline_shader_program); - s32 tex_id_loc = glGetUniformLocation(outline_shader_program, "TexId"); + {//random square behind window between squares + glUseProgram(shader_program); + s32 tex_id_loc = glGetUniformLocation(shader_program, "TexId"); glUniform1i(tex_id_loc, 0); - s32 hlt_loc = glGetUniformLocation(outline_shader_program, "hlt_color"); - glUniform4f(hlt_loc, 1.0f, 0.0f, 0.0f, 1.0f); - Vec3 translation_iter = model_translations[0]; + Vec3 translation_iter = model_translations[5]; Mat4 model = init_value4m(1.0); - Mat4 model_scale = scaling_matrix4m(1.1f, 1.1f, 1.1f); - model = multiply4m(model_scale, model); Mat4 model_translation = translation_matrix4m(translation_iter.x, translation_iter.y, translation_iter.z); model = multiply4m(model_translation, model); - uint32_t model_loc = glGetUniformLocation(outline_shader_program, "Model"); + uint32_t model_loc = glGetUniformLocation(shader_program, "Model"); glUniformMatrix4fv(model_loc, 1, GL_TRUE, model.buffer); glBindVertexArray(cube_vao); glDrawArrays(GL_TRIANGLES, 0, 36); } - { - glUseProgram(outline_shader_program); - s32 tex_id_loc = glGetUniformLocation(outline_shader_program, "TexId"); - glUniform1i(tex_id_loc, 0); - s32 hlt_loc = glGetUniformLocation(outline_shader_program, "hlt_color"); - glUniform4f(hlt_loc, 0.0f, 1.0f, 0.0f, 1.0f); + // @note: this is to demonstrate the limitations of blending with the depth buffer. + // Currently, this will show a weird behavior where since we render the transparent object + // closest to the camera first, the second window, further from the player will be discarded by the + // depth buffer and will be invisible. + // This is a limiation of transparent objects with the depth buffer. This does not happen with opaque objects. + // + // The "fix" if we can even call it that, is to render objects in order, furthest first and closest second, in layers. + + {//window infront of origin square + glUseProgram(blend_shader_program); + s32 tex_id_loc = glGetUniformLocation(blend_shader_program, "TexId"); + glUniform1i(tex_id_loc, 2); + Vec3 translation_iter = model_translations[3]; + 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(blend_shader_program, "Model"); + glUniformMatrix4fv(model_loc, 1, GL_TRUE, model.buffer); + glBindVertexArray(quad_vao); + glDrawArrays(GL_TRIANGLES, 0, 6); + } + {//window between squares + glUseProgram(blend_shader_program); + s32 tex_id_loc = glGetUniformLocation(blend_shader_program, "TexId"); + glUniform1i(tex_id_loc, 2); Vec3 translation_iter = model_translations[2]; Mat4 model = init_value4m(1.0); - Mat4 model_scale = scaling_matrix4m(1.1f, 1.1f, 1.1f); - model = multiply4m(model_scale, model); Mat4 model_translation = translation_matrix4m(translation_iter.x, translation_iter.y, translation_iter.z); model = multiply4m(model_translation, model); - uint32_t model_loc = glGetUniformLocation(outline_shader_program, "Model"); + uint32_t model_loc = glGetUniformLocation(blend_shader_program, "Model"); glUniformMatrix4fv(model_loc, 1, GL_TRUE, model.buffer); - glBindVertexArray(cube_vao); - glDrawArrays(GL_TRIANGLES, 0, 36); + glBindVertexArray(quad_vao); + glDrawArrays(GL_TRIANGLES, 0, 6); } - // re-enable the depth buffer and stencil buffer state and ops - glEnable(GL_DEPTH_TEST); - glStencilMask(0xFF); - glStencilFunc(GL_ALWAYS, 1, 0xFF); - SDL_GL_SwapWindow(window); } @@ -885,7 +932,7 @@ int main(int argc, char* argv[]) //glDeleteVertexArrays(1, &VAO); //glDeleteBuffers(1, &VBO); glDeleteProgram(shader_program); - glDeleteProgram(outline_shader_program); + glDeleteProgram(blend_shader_program); // sdl free calls SDL_GL_DeleteContext(context); |