summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/main.cpp190
-rw-r--r--source/shaders/stencil_outline.fs.glsl12
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;
+}