diff options
Diffstat (limited to 'source')
-rw-r--r-- | source/main.cpp | 190 | ||||
-rw-r--r-- | source/shaders/stencil_outline.fs.glsl | 12 |
2 files changed, 128 insertions, 74 deletions
diff --git a/source/main.cpp b/source/main.cpp index 80eb2d6..5f45782 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -102,6 +102,15 @@ unsigned int gl_create_shader_program(unsigned int vertex_shader, unsigned int f return shader_program; } +unsigned int gl_shader_program(char* vertex_shader_source, char* fragment_shader_source) +{ + unsigned int vertex_shader = gl_create_vertex_shader(vertex_shader_source); + unsigned int fragment_shader = gl_create_fragment_shader(fragment_shader_source); + unsigned int shader_program = gl_create_shader_program(vertex_shader, fragment_shader); + + return shader_program; +} + Mat4 camera_create4m(Vec3 camera_pos, Vec3 camera_look, Vec3 camera_up) { // @note: We do this because this allows the camera to have the axis it looks at @@ -462,6 +471,7 @@ int main(int argc, char* argv[]) SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3); SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); + SDL_GL_SetAttribute( SDL_GL_STENCIL_SIZE, 8 ); // initialise window with opengl flag SDL_Window* window = SDL_CreateWindow("SDL Test", @@ -492,10 +502,11 @@ 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); - GLuint vertex_shader = gl_create_vertex_shader(vertex_source); - GLuint fragment_shader = gl_create_fragment_shader(fragment_source); - GLuint shader_program = gl_create_shader_program(vertex_shader, fragment_shader); + u32 shader_program = gl_shader_program(vertex_source, fragment_source); + u32 outline_shader_program = gl_shader_program(vertex_source, outline_shader_source); + printf("Successfully compiled shaders.\n"); float cubeVertices[] = { @@ -591,56 +602,11 @@ int main(int argc, char* argv[]) glActiveTexture(GL_TEXTURE1); gl_load_texture(plane_tex_id, "assets/smiling.png"); - glUseProgram(shader_program); - - - // directional light things - // - directional light params - Vec3 DL_direction = Vec3{ 0.0f, -0.5f, -1.0f }; - Vec3 DL_ambient = Vec3{ 0.2f, 0.2f, 0.2f }; - Vec3 DL_diffuse = Vec3{ 0.5f, 0.5f, 0.5f }; - Vec3 DL_specular = Vec3{ 1.0f, 1.0f, 1.0f }; - - //int DL_ambient_loc = glGetUniformLocation(shader_program, "dirLight.ambient"); - //int DL_diffuse_loc = glGetUniformLocation(shader_program, "dirLight.diffuse"); - //int DL_specular_loc = glGetUniformLocation(shader_program, "dirLight.specular"); - //int DL_dir_loc = glGetUniformLocation(shader_program, "dirLight.direction"); - - //glUniform3fv(DL_dir_loc, 1, DL_direction.data); - //glUniform3fv(DL_ambient_loc, 1, DL_ambient.data); - //glUniform3fv(DL_diffuse_loc, 1, DL_diffuse.data); - //glUniform3fv(DL_specular_loc, 1, DL_specular.data); - - // load point light - Vec3 PL_position = Vec3{ 0.0f, 0.0f, 3.0f }; - Vec3 PL_ambient = Vec3{ 0.2f, 0.2f, 0.2f }; - Vec3 PL_diffuse = Vec3{ 0.5f, 0.5f, 0.5f }; - Vec3 PL_specular = Vec3{ 1.0f, 1.0f, 1.0f }; - - //s32 PL_pos_loc = glGetUniformLocation(shader_program, "pointLight.position"); - //s32 PL_ambient_loc = glGetUniformLocation(shader_program, "pointLight.ambient"); - //s32 PL_diffuse_loc = glGetUniformLocation(shader_program, "pointLight.diffuse"); - //s32 PL_specular_loc = glGetUniformLocation(shader_program, "pointLight.specular"); - //s32 PL_kc_loc = glGetUniformLocation(shader_program, "pointLight.kC"); - //s32 PL_kl_loc = glGetUniformLocation(shader_program, "pointLight.kL"); - //s32 PL_kq_loc = glGetUniformLocation(shader_program, "pointLight.kQ"); - - //glUniform3fv(PL_pos_loc, 1, PL_position.data); - //glUniform3fv(PL_ambient_loc, 1, PL_ambient.data); - //glUniform3fv(PL_diffuse_loc, 1, PL_diffuse.data); - //glUniform3fv(PL_specular_loc, 1, PL_specular.data); - //// attenuation factors - //glUniform1f(PL_kc_loc, 1.0f); - //glUniform1f(PL_kl_loc, 0.09f); - //glUniform1f(PL_kq_loc, 0.032f); - - //int camera_pos_loc = glGetUniformLocation(shader_program, "cameraPosition"); - // objects Vec3 model_translations[] = { Vec3{ 0.0, 0.0, 0.0}, Vec3{ -1.0, 0.0, -2.0}, - Vec3{ 2.0, 0.0, -5.0}, + Vec3{ -1.0, 0.0, -2.0}, Vec3{ -3.0, 5.0, -6.0}, Vec3{ 3.0, -7.0, -6.0}, }; @@ -648,8 +614,6 @@ int main(int argc, char* argv[]) r32 FOV = 90.0; r32 time_curr; r32 time_prev = SDL_GetTicks64() / 100.0; - uint32_t model_loc = glGetUniformLocation(shader_program, "Model"); - // camera stuff Vec3 camera_pos = Vec3{ 0.0, 0.0, 10.0f}; Vec3 preset_up_dir = Vec3{ 0.0, 1.0, 0.0 }; @@ -666,16 +630,20 @@ int main(int argc, char* argv[]) Mat4 view = camera_create4m(camera_pos, camera_look, preset_up_dir); - uint32_t view_loc = glGetUniformLocation(shader_program, "View"); - glUniformMatrix4fv(view_loc, 1, GL_TRUE, view.buffer); - Mat4 proj = perspective4m((r32)To_Radian(90.0), (r32)width / (r32)height, 0.1f, 100.0f); + // needs this + glUseProgram(shader_program); 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"); + glUniformMatrix4fv(proj_loc, 1, GL_TRUE, proj.buffer); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LESS); - + glEnable(GL_STENCIL_TEST); + u8 game_running = true; u8 hold_lshift = false; @@ -795,50 +763,123 @@ int main(int argc, char* argv[]) view = camera_create4m(camera_pos, add3v(camera_pos, camera_look), preset_up_dir); // object shader program stuff - glUseProgram(shader_program); - + glUseProgram(shader_program); + 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"); glUniformMatrix4fv(view_loc, 1, GL_TRUE, view.buffer); - //glUniform3fv(camera_pos_loc, 1, camera_pos.data); 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); - //glClearColor(0.0f, 0.0f, 0.0f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - + 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); { + glUseProgram(shader_program); + s32 tex_id_loc = glGetUniformLocation(shader_program, "TexId"); + glUniform1i(tex_id_loc, 1); + Vec3 translation_iter = model_translations[1]; + 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(shader_program, "Model"); + glUniformMatrix4fv(model_loc, 1, GL_TRUE, model.buffer); + glBindVertexArray(plane_vao); + 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); + { + glUseProgram(shader_program); s32 tex_id_loc = glGetUniformLocation(shader_program, "TexId"); glUniform1i(tex_id_loc, 0); Vec3 translation_iter = model_translations[0]; 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(shader_program, "Model"); glUniformMatrix4fv(model_loc, 1, GL_TRUE, model.buffer); glBindVertexArray(cube_vao); glDrawArrays(GL_TRIANGLES, 0, 36); } { + glUseProgram(shader_program); s32 tex_id_loc = glGetUniformLocation(shader_program, "TexId"); - glUniform1i(tex_id_loc, 1); - Vec3 translation_iter = model_translations[1]; + glUniform1i(tex_id_loc, 0); + Vec3 translation_iter = model_translations[2]; 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(shader_program, "Model"); glUniformMatrix4fv(model_loc, 1, GL_TRUE, model.buffer); - glBindVertexArray(plane_vao); - glDrawArrays(GL_TRIANGLES, 0, 6); + glBindVertexArray(cube_vao); + glDrawArrays(GL_TRIANGLES, 0, 36); } - //for (int i = 0; i < 2; i++) - //{ - // Vec3 translation_iter = model_translations[i]; - // 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); - // glUniformMatrix4fv(model_loc, 1, GL_TRUE, model.buffer); - //} - + // 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 infront + // will cover the stencil values whereever it is. There is a subtle difference when this happens + // but from what I have seen it just looks better and makes more sense when we have don't write to the + // stencil mask because. I guess it also means that we donot want the highlights we draw to affect other + // highlights + glStencilMask(0x00); + glStencilFunc(GL_NOTEQUAL, 1, 0xFF); + { + 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, 1.0f, 0.0f, 0.0f, 1.0f); + Vec3 translation_iter = model_translations[0]; + 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"); + 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); + 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"); + glUniformMatrix4fv(model_loc, 1, GL_TRUE, model.buffer); + glBindVertexArray(cube_vao); + glDrawArrays(GL_TRIANGLES, 0, 36); + } + // 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); } @@ -846,6 +887,7 @@ int main(int argc, char* argv[]) //glDeleteVertexArrays(1, &VAO); //glDeleteBuffers(1, &VBO); glDeleteProgram(shader_program); + glDeleteProgram(outline_shader_program); // sdl free calls SDL_GL_DeleteContext(context); diff --git a/source/shaders/stencil_outline.fs.glsl b/source/shaders/stencil_outline.fs.glsl new file mode 100644 index 0000000..63d6a75 --- /dev/null +++ b/source/shaders/stencil_outline.fs.glsl @@ -0,0 +1,12 @@ +#version 330 core + + +in vec2 TexCoords; +in vec3 VertexWorldPos; +uniform sampler2D TexId; +uniform vec4 hlt_color; +out vec4 FragColor; + +void main() { + FragColor = hlt_color; +} |