summaryrefslogtreecommitdiff
path: root/source/main.cpp
diff options
context:
space:
mode:
authortalha <talha@talhaamir.xyz>2024-04-06 20:25:30 +0500
committertalha <talha@talhaamir.xyz>2024-04-06 20:25:30 +0500
commitdcf84e28b5367dfa737cc2dfbf8d4c1afbf21cba (patch)
treeddec195c8813455e330934063655f51e0dea2a00 /source/main.cpp
parentf2e3f39b15bd22e2aa727bf4669b6e52186e31c7 (diff)
Completed blending
Diffstat (limited to 'source/main.cpp')
-rw-r--r--source/main.cpp179
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);