diff options
Diffstat (limited to 'source/main.cpp')
-rw-r--r-- | source/main.cpp | 311 |
1 files changed, 234 insertions, 77 deletions
diff --git a/source/main.cpp b/source/main.cpp index 2f07c0e..650799d 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -10,6 +10,9 @@ #include "stb_image.h" /* @lookup: +* - understand kernals, how they work and how they affect post processing +* - Check to see why it is necessary to do glBindTexture() +* - understand the difference between binding textures, and activating a texture unit * - I do not understand how floating point numbers work, so I should probably look into that. * - The normal matrix calculation in the fragment shader for the object affected by light has been mainly copied. * I have tried to understand the formula, and whilst it made some sense, it is not fully clear to me, and I cannot picture it yet. @@ -159,7 +162,6 @@ s32 gl_load_texture(u32 texture_id, const char* path) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 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 @@ -181,6 +183,12 @@ s32 gl_load_texture(u32 texture_id, const char* path) s32 TextureFromFile(const char* filepath, std::string directory) { + // @note: this function is stupid as it already became outdated as I needed to tweak the parameters + // for wrapping. Either those become function parameters (Which makes sense I guess) or I look at + // exactly what steps I am reusing and just make that a function so the function is called fewer times. + // + // I am guessing this won't look good from a design point of view for all those jobs and postings, even if + // this may be the simpler and faster thing to do, albeit at the cost of typing. std::string filename = std::string(filepath); filename = directory + '/' + filename; @@ -454,6 +462,52 @@ std::vector<Texture> Model::load_material_textures(aiMaterial *mat, aiTextureTyp return textures; } +class Shader { + // @note: this is a draft, I think frankly, it's a stupid idea to be making this at this point + // but my goal is to look at my code at this stage (which is in the second half of (or so I think) + // learnopengl and identify repeated code that I think I can yank out and can make convenient to write. + // The precondition for all of this is that I do not remodel the program based off of some vague idea of + // cleanliness in my head. This is all still very procedural, I just want to minimize the amount I type + // and at the same time see how well I can identify good abstractions + // + // + // I much prefer to have things be not a class, especially if I look at how I did my lovely + // math functions, which are so simple and straightforward + public: + u32 id; + + // @note: all well and good until you get compute shaders + // then the entire thing shits the bed + Shader(char* vertex_shader_source, char* fragment_shader_source) { + id = gl_shader_program(vertex_shader_source, fragment_shader_source); + } + + void use() { + glUseProgram(id); + } + + void draw_triangles(u32 vao, u32 count) { + glBindVertexArray(vao); + glDrawArrays(GL_TRIANGLES, 0, count); + } + + void set_1i(char* variable, s32 value) { + s32 loc = glGetUniformLocation(id, variable); + glUniform1i(loc, value); + } + + void set_matrix4fv(char* variable, Mat4 value, int count) { + s32 loc = glGetUniformLocation(id, variable); + glUniformMatrix4fv(loc, count, GL_TRUE, value.buffer); + }; + + ~Shader() { + // @note: this can literally be replaced by another function that goes over the entire list + // of shader_programs near the program exit and deletes them, if I even need to do that. + glDeleteProgram(id); + } +}; + int main(int argc, char* argv[]) { @@ -503,78 +557,103 @@ int main(int argc, char* argv[]) 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* blend_shader_source = (char*)SDL_LoadFile("./source/shaders/blend_test.fs.glsl", &read_count); + char* fbo_vs = (char*)SDL_LoadFile("./source/shaders/fbo.vs.glsl", &read_count); + char* fbo_fs = (char*)SDL_LoadFile("./source/shaders/fbo.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); printf("Successfully compiled shaders.\n"); float cubeVertices[] = { - // positions // texture Coords - -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, - 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, - 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, - 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, - -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, - -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, - - -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, - 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, - 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, - 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, - -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, - -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, - - -0.5f, 0.5f, 0.5f, 1.0f, 0.0f, - -0.5f, 0.5f, -0.5f, 1.0f, 1.0f, - -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, - -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, - -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, - -0.5f, 0.5f, 0.5f, 1.0f, 0.0f, - - 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, - 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, - 0.5f, -0.5f, -0.5f, 0.0f, 1.0f, - 0.5f, -0.5f, -0.5f, 0.0f, 1.0f, - 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, - 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, - - -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, - 0.5f, -0.5f, -0.5f, 1.0f, 1.0f, - 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, - 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, - -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, - -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, - - -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, - 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, - 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, - 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, - -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, - -0.5f, 0.5f, -0.5f, 0.0f, 1.0f - }; + // Back face + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, // Bottom-left + 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, // top-right + 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, // bottom-right + 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, // top-right + -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, // bottom-left + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, // top-left + // Front face + -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, // bottom-left + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, // bottom-right + 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, // top-right + 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, // top-right + -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, // top-left + -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, // bottom-left + // Left face + -0.5f, 0.5f, 0.5f, 1.0f, 0.0f, // top-right + -0.5f, 0.5f, -0.5f, 1.0f, 1.0f, // top-left + -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, // bottom-left + -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, // bottom-left + -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, // bottom-right + -0.5f, 0.5f, 0.5f, 1.0f, 0.0f, // top-right + // Right face + 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, // top-left + 0.5f, -0.5f, -0.5f, 0.0f, 1.0f, // bottom-right + 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, // top-right + 0.5f, -0.5f, -0.5f, 0.0f, 1.0f, // bottom-right + 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, // top-left + 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, // bottom-left + // Bottom face + -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, // top-right + 0.5f, -0.5f, -0.5f, 1.0f, 1.0f, // top-left + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, // bottom-left + 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, // bottom-left + -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, // bottom-right + -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, // top-right + // Top face + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, // top-left + 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, // bottom-right + 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, // top-right + 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, // bottom-right + -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, // top-left + -0.5f, 0.5f, 0.5f, 0.0f, 0.0f // bottom-left + }; float planeVertices[] = { - // positions // texture Coords (note we set these higher than 1 (together with GL_REPEAT as texture wrapping mode). this will cause the floor texture to repeat) - 5.0f, -0.5f, 5.0f, 2.0f, 0.0f, - -5.0f, -0.5f, 5.0f, 0.0f, 0.0f, - -5.0f, -0.5f, -5.0f, 0.0f, 2.0f, - - 5.0f, -0.5f, 5.0f, 2.0f, 0.0f, - -5.0f, -0.5f, -5.0f, 0.0f, 2.0f, - 5.0f, -0.5f, -5.0f, 2.0f, 2.0f + // positions // texture Coords (note we set these higher than 1 (together with GL_REPEAT as texture wrapping mode). this will cause the floor texture to repeat) + // BottomFace + -5.0f, -1.0f, -5.0f, 0.0f, 2.0f, // top-right + 5.0f, -1.0f, -5.0f, 2.0f, 2.0f, // top-left + 5.0f, -1.0f, 5.0f, 2.0f, 0.0f, // bottom-left + 5.0f, -1.0f, 5.0f, 2.0f, 0.0f, // bottom-left + -5.0f, -1.0f, 5.0f, 0.0f, 0.0f, // bottom-right + -5.0f, -1.0f, -5.0f, 0.0f, 2.0f, // top-right + // Top face + -5.0f, -0.5f, -5.0f, 0.0f, 2.0f, // top-left + 5.0f, -0.5f, 5.0f, 2.0f, 0.0f, // bottom-right + 5.0f, -0.5f, -5.0f, 2.0f, 2.0f, // top-right + 5.0f, -0.5f, 5.0f, 2.0f, 0.0f, // bottom-right + -5.0f, -0.5f, -5.0f, 0.0f, 2.0f, // top-left + -5.0f, -0.5f, 5.0f, 0.0f, 0.0f // bottom-left }; 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, + // Front face + -0.5f, -0.5f, 0.0f, 0.0f, // bottom-left + 0.5f, -0.5f, 1.0f, 0.0f, // bottom-right + 0.5f, 0.5f, 1.0f, 1.0f, // top-right + 0.5f, 0.5f, 1.0f, 1.0f, // top-right + -0.5f, 0.5f, 0.0f, 1.0f, // top-left + -0.5f, -0.5f, 0.0f, 0.0f, // bottom-left + // Back face + -0.5f, -0.5f, 0.0f, 0.0f, // Bottom-left + 0.5f, 0.5f, 1.0f, 1.0f, // top-right + 0.5f, -0.5f, 1.0f, 0.0f, // bottom-right + 0.5f, 0.5f, 1.0f, 1.0f, // top-right + -0.5f, -0.5f, 0.0f, 0.0f, // bottom-left + -0.5f, 0.5f, 0.0f, 1.0f, // top-left }; + float fboVertices[] = { + -1.0f, -1.0f, 0.0f, 0.0f, // bottom-left + 1.0f, -1.0f, 1.0f, 0.0f, // bottom-right + 1.0f, 1.0f, 1.0f, 1.0f, // top-right + 1.0f, 1.0f, 1.0f, 1.0f, // top-right + -1.0f, 1.0f, 0.0f, 1.0f, // top-left + -1.0f, -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; + u32 cube_vao, cube_vbo, plane_vao, plane_vbo, quad_vao, quad_vbo, fbo_vao, fbo_vbo; glGenVertexArrays(1, &cube_vao); glGenBuffers(1, &cube_vbo); @@ -612,24 +691,26 @@ int main(int argc, char* argv[]) 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); - gl_load_texture(cube_tex_id, "assets/container.jpg"); + // framebuffer objects + glGenVertexArrays(1, &fbo_vao); + glGenBuffers(1, &fbo_vbo); - u32 plane_tex_id; - glGenTextures(1, &plane_tex_id); - glActiveTexture(GL_TEXTURE1); - gl_load_texture(plane_tex_id, "assets/smiling.png"); + glBindVertexArray(fbo_vao); + glBindBuffer(GL_ARRAY_BUFFER, fbo_vbo); + glBufferData(GL_ARRAY_BUFFER, sizeof(fboVertices), &fboVertices, 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 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); + s32 _width, _height, nrChannels; + unsigned char *data = stbi_load(path, &_width, &_height, &nrChannels, 0); if (data) { GLenum format; @@ -640,8 +721,8 @@ int main(int argc, char* argv[]) 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); + glBindTexture(GL_TEXTURE_2D, window_tex_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); @@ -657,7 +738,17 @@ int main(int argc, char* argv[]) stbi_image_free(data); } -} + } + + u32 cube_tex_id; + glGenTextures(1, &cube_tex_id); + glActiveTexture(GL_TEXTURE0); + gl_load_texture(cube_tex_id, "assets/container.jpg"); + + u32 plane_tex_id; + glGenTextures(1, &plane_tex_id); + glActiveTexture(GL_TEXTURE1); + gl_load_texture(plane_tex_id, "assets/smiling.png"); // objects Vec3 model_translations[] = { @@ -700,7 +791,40 @@ int main(int argc, char* argv[]) glEnable(GL_DEPTH_TEST); glEnable(GL_BLEND); + glEnable(GL_CULL_FACE); glDepthFunc(GL_LESS); + glCullFace(GL_BACK); + //glFrontFace(GL_CW); // front-faces are clock-wise, this will make the back-faces visible (since the arrays used were + // setup as counter-clockwise) + u32 fbo; + glGenFramebuffers(1, &fbo); + glBindFramebuffer(GL_FRAMEBUFFER, fbo); + + // create a texture for the framebuffer to render data to + u32 fbo_tex; + glGenTextures(1, &fbo_tex); + glActiveTexture(GL_TEXTURE3); + glBindTexture(GL_TEXTURE_2D, fbo_tex); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glBindTexture(GL_TEXTURE_2D, 0); + + u32 rbo; + glGenRenderbuffers(1, &rbo); + glBindRenderbuffer(GL_RENDERBUFFER, rbo); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height); + glBindRenderbuffer(GL_RENDERBUFFER, 0); + + // attach to current bound framebuffer object + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fbo_tex, 0); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo); + + if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { + printf("Error! Framebuffer is not completely setup\n"); + return -1; + } + glBindFramebuffer(GL_FRAMEBUFFER, 0); u8 game_running = true; @@ -832,12 +956,15 @@ int main(int argc, char* argv[]) time_prev = time_curr; // OUTPUT + glBindFramebuffer(GL_FRAMEBUFFER, fbo); + glEnable(GL_DEPTH_TEST); glClearColor(1.0f, 0.6f, .6f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glDisable(GL_BLEND); { //plane glUseProgram(shader_program); + // @note: this is just a test, I dont need to do this here; s32 tex_id_loc = glGetUniformLocation(shader_program, "TexId"); glUniform1i(tex_id_loc, 1); Vec3 translation_iter = model_translations[1]; @@ -847,13 +974,15 @@ int main(int argc, char* argv[]) uint32_t model_loc = glGetUniformLocation(shader_program, "Model"); glUniformMatrix4fv(model_loc, 1, GL_TRUE, model.buffer); glBindVertexArray(plane_vao); - glDrawArrays(GL_TRIANGLES, 0, 6); + glBindTexture(GL_TEXTURE_2D, plane_tex_id); + glDrawArrays(GL_TRIANGLES, 0, 12); } glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); {//origin square glUseProgram(shader_program); + glBindTexture(GL_TEXTURE_2D, cube_tex_id); s32 tex_id_loc = glGetUniformLocation(shader_program, "TexId"); glUniform1i(tex_id_loc, 0); Vec3 translation_iter = model_translations[0]; @@ -867,6 +996,7 @@ int main(int argc, char* argv[]) } {//square to the left glUseProgram(shader_program); + glBindTexture(GL_TEXTURE_2D, cube_tex_id); s32 tex_id_loc = glGetUniformLocation(shader_program, "TexId"); glUniform1i(tex_id_loc, 0); Vec3 translation_iter = model_translations[4]; @@ -889,6 +1019,7 @@ int main(int argc, char* argv[]) uint32_t model_loc = glGetUniformLocation(shader_program, "Model"); glUniformMatrix4fv(model_loc, 1, GL_TRUE, model.buffer); glBindVertexArray(cube_vao); + glBindTexture(GL_TEXTURE_2D, cube_tex_id); glDrawArrays(GL_TRIANGLES, 0, 36); } // @note: this is to demonstrate the limitations of blending with the depth buffer. @@ -910,7 +1041,8 @@ int main(int argc, char* argv[]) 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); + glBindTexture(GL_TEXTURE_2D, window_tex_id); + glDrawArrays(GL_TRIANGLES, 0, 12); } {//window between squares glUseProgram(blend_shader_program); @@ -923,8 +1055,32 @@ int main(int argc, char* argv[]) uint32_t model_loc = glGetUniformLocation(blend_shader_program, "Model"); glUniformMatrix4fv(model_loc, 1, GL_TRUE, model.buffer); glBindVertexArray(quad_vao); + glBindTexture(GL_TEXTURE_2D, window_tex_id); + glDrawArrays(GL_TRIANGLES, 0, 12); + } + glBindFramebuffer(GL_FRAMEBUFFER, 0); + + // draw everything to a framebuffer object + glDisable(GL_DEPTH_TEST); + glClearColor(1.0f, 1.0f, 1.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + { + glUseProgram(fbo_shader_program); + glBindVertexArray(fbo_vao); + // @note: this glActiveTexture call was the bane of my existence for the day, this is done to check this particular + // thing regarding which texture unit the framebuffer object gets called to and it turns out, it needs a glActiveTexture + // call (atleast in my case) since I am rendering multiple textures which are bound to different texture units, + // primarily because of the different shaders I am using. + // + // So this is why I need to call this, but what I could also do is call glActiveTexture when creating the texture + // and it would have the same effect as this + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, fbo_tex); + s32 tex_id_loc = glGetUniformLocation(fbo_shader_program, "TexId"); + glUniform1i(tex_id_loc, 0); glDrawArrays(GL_TRIANGLES, 0, 6); } + glEnable(GL_DEPTH_TEST); SDL_GL_SwapWindow(window); } @@ -933,6 +1089,7 @@ int main(int argc, char* argv[]) //glDeleteBuffers(1, &VBO); glDeleteProgram(shader_program); glDeleteProgram(blend_shader_program); + glDeleteProgram(fbo_shader_program); // sdl free calls SDL_GL_DeleteContext(context); |