From 590982cde37aac46830a222c88e45c7a02fa67ad Mon Sep 17 00:00:00 2001 From: Jack Christensen Date: Tue, 13 Aug 2024 17:47:16 -0400 Subject: [PATCH] Add FBO class. Still need to add functionality --- include/fbo.h | 22 ++++++ include/scene.h | 21 ++--- source/fbo.cpp | 62 +++++++++++++++ source/scene.cpp | 196 +++++------------------------------------------ 4 files changed, 112 insertions(+), 189 deletions(-) create mode 100644 include/fbo.h create mode 100644 source/fbo.cpp diff --git a/include/fbo.h b/include/fbo.h new file mode 100644 index 0000000..e7927d4 --- /dev/null +++ b/include/fbo.h @@ -0,0 +1,22 @@ +#ifndef FBO_H_ +#define FBO_H_ + +#include + +class FBO { + public: + FBO(); + ~FBO(); + + GLuint fbo_id_; + GLuint color_texture_id_; + GLuint depth_rbo_id_; + + void Init(int width, int height); + void Bind(); + void Unbind(); + void Cleanup(); + GLuint GetColorTexture() const; +}; + +#endif // FBO_H_ \ No newline at end of file diff --git a/include/scene.h b/include/scene.h index ac07787..48dc117 100644 --- a/include/scene.h +++ b/include/scene.h @@ -4,6 +4,8 @@ #include #include +#include "fbo.h" + class Scene { public: Scene(); @@ -15,10 +17,14 @@ class Scene { void Idle(); void ReloadShader(); + int window_width; + int window_height; + private: void InitBuffers(); void InitShaders(); + FBO fbo_; GLuint shader_program_; GLuint vao_; float angle_; @@ -32,19 +38,6 @@ class Scene { glm::mat4 projection_matrix_; void UpdateCamera(); - }; -#endif // SCENE_H_ - -// namespace scene -// { -// extern const int kInitWindowWidth; -// extern const int kInitWindowHeight; - -// void Display(GLFWwindow* window); -// void DrawGUI(GLFWwindow* window); -// void Idle(); -// void ReloadShader(); -// void Init(); -// } // namespace scene \ No newline at end of file +#endif // SCENE_H_ \ No newline at end of file diff --git a/source/fbo.cpp b/source/fbo.cpp new file mode 100644 index 0000000..256c6cb --- /dev/null +++ b/source/fbo.cpp @@ -0,0 +1,62 @@ +#include +#include +#include + +#include "fbo.h" + +FBO::FBO() : fbo_id_(-1), color_texture_id_(-1), depth_rbo_id_(-1) {} + +FBO::~FBO() { + Cleanup(); +} + +void FBO::Init(int width, int height) { + // Generate the framebuffer + glGenFramebuffers(1, &fbo_id_); + glBindFramebuffer(GL_FRAMEBUFFER, fbo_id_); + + // Generate the color texture + glGenTextures(1, &color_texture_id_); + glBindTexture(GL_TEXTURE_2D, color_texture_id_); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color_texture_id_, 0); + + // Generate the Depth renderbuffer + glGenRenderbuffers(1, &depth_rbo_id_); + glBindRenderbuffer(GL_RENDERBUFFER, depth_rbo_id_); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width, height); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depth_rbo_id_); + + // Check if the framebuffer is complete + if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { + std::cerr << "Error: Framebuffer is not complete!" << std::endl; + } + + glBindFramebuffer(GL_FRAMEBUFFER, 0); +} + +void FBO::Bind() { + glBindFramebuffer(GL_FRAMEBUFFER, fbo_id_); +} + +void FBO::Unbind() { + glBindFramebuffer(GL_FRAMEBUFFER, 0); +} + +void FBO::Cleanup() { + if (color_texture_id_ != -1) { + glDeleteTextures(1, &color_texture_id_); + } + if (depth_rbo_id_ != -1) { + glDeleteTextures(1, &depth_rbo_id_); + } + if (fbo_id_ != -1) { + glDeleteFramebuffers(1, &fbo_id_); + } +} + +GLuint FBO::GetColorTexture() const { + return color_texture_id_; +} \ No newline at end of file diff --git a/source/scene.cpp b/source/scene.cpp index b64c6fc..8853efc 100644 --- a/source/scene.cpp +++ b/source/scene.cpp @@ -29,11 +29,22 @@ const std::string kFragmentShaderPath = "shaders/fragment.glsl"; } // namespace -Scene::Scene() : shader_program_(-1), vao_(-1), angle_(0.0f), scale_(1.0f), aspect_(1280.0f / 720.0f), near_z_(0.1f), far_z_(100.0f), fov_(glm::pi() / 4.0f) {}; +Scene::Scene() : window_width(1280), + window_height(720), + shader_program_(-1), + vao_(-1), + angle_(0.0f), + scale_(1.0f), + aspect_(1280.0f / 720.0f), + near_z_(0.1f), far_z_(100.0f), + fov_(glm::pi() / 4.0f) + {}; Scene::~Scene() { glDeleteProgram(shader_program_); glDeleteVertexArrays(1, &vao_); + + fbo_.~FBO(); } void Scene::Init() { @@ -42,7 +53,8 @@ void Scene::Init() { glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); - //InitTri(); + fbo_.Init(window_width, window_height); + InitBuffers(); ReloadShader(); @@ -50,6 +62,7 @@ void Scene::Init() { Uniforms::Init(); } +// Currently creates a test triangle and initializes its buffers void Scene::InitBuffers() { GLuint vbo; float vertices[] = { @@ -68,6 +81,7 @@ void Scene::InitBuffers() { glEnableVertexAttribArray(0); } +// Allows for runtime shader updates void Scene::ReloadShader() { GLuint new_shader = InitShader(kVertexShaderPath.c_str(), kFragmentShaderPath.c_str()); if (new_shader == -1) { @@ -85,6 +99,8 @@ void Scene::ReloadShader() { void Scene::Display(GLFWwindow* window) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + fbo_.Bind(); + view_matrix_ = glm::lookAt(glm::vec3(Uniforms::SceneData.eye_w), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f)); Uniforms::SceneData.PV = projection_matrix_ * view_matrix_; // Projection-View matrix Uniforms::BufferSceneData(); @@ -96,6 +112,8 @@ void Scene::Display(GLFWwindow* window) { glBindVertexArray(vao_); glDrawArrays(GL_TRIANGLES, 0, 3); + fbo_.Unbind(); + DrawGui(window); glfwSwapBuffers(window); } @@ -168,176 +186,4 @@ void Scene::Idle() { void Scene::UpdateCamera() { projection_matrix_ = glm::perspective(fov_, aspect_, near_z_, far_z_); -} - -// namespace scene { - -// const int kInitWindowWidth = 1280; -// const int kInitWindowHeight = 720; - -// static const std::string kVertexShader("shaders/vertex.glsl"); -// static const std::string kFragmentShader("shaders/fragment.glsl"); - -// GLuint shader_program = -1; - -// // Vertex data for a basic triangle. Testing use only -// float vertices[] = { -// -0.5f, -0.5f, 0.0f, -// 0.5f, -0.5f, 0.0f, -// 0.0f, 0.5f, 0.0f -// }; - -// unsigned int VAO = -1; - -// float angle = 0.0f; -// float scale = 1.0f; - -// namespace camera { -// glm::mat4 V, P; - -// float aspect = static_cast(kInitWindowWidth) / static_cast(kInitWindowHeight); -// float near_z = 0.1f; -// float far_z = 100.0f; -// float fov = glm::pi() / 4.0f; - -// void UpdateP() { -// P = glm::perspective(fov, aspect, near_z, far_z); -// } -// } // namespace camera - -// // Temp function to test shader pipline with basic triangle -// void InitTri() { -// unsigned int vbo; -// glGenBuffers(1, &vbo); -// glBindBuffer(GL_ARRAY_BUFFER, vbo); -// glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); - -// glGenVertexArrays(1, &VAO); -// glBindVertexArray(VAO); -// glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0); -// glEnableVertexAttribArray(0); -// } - - -// void Display(GLFWwindow* window) { -// // Clear the color and depth buffers -// glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - -// camera::V = glm::lookAt(glm::vec3(Uniforms::SceneData.eye_w), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f)); -// Uniforms::SceneData.PV = camera::P * camera::V; // Projection-View matrix -// Uniforms::BufferSceneData(); - -// // Model matrix -// glm::mat4 M = glm::rotate(angle, glm::vec3(0.0f, 1.0f, 0.0f)) * glm::scale(glm::vec3(scale)); -// glUniformMatrix4fv(Uniforms::UniformLocs::M, 1, false, glm::value_ptr(M)); - -// glUseProgram(shader_program); - -// glBindVertexArray(VAO); -// glDrawArrays(GL_TRIANGLES, 0, 3); - -// DrawGUI(window); -// glfwSwapBuffers(window); -// } - - - -// void DrawGUI(GLFWwindow* window) { -// // Begin ImGui frame -// ImGui_ImplOpenGL3_NewFrame(); -// ImGui_ImplGlfw_NewFrame(); - -// // Enable docking -// ImGuiIO& io = ImGui::GetIO(); -// io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; - -// ImGui::NewFrame(); - -// static ImGuiDockNodeFlags dockspace_flags = ImGuiDockNodeFlags_PassthruCentralNode; - -// // Add menu bar -// ImGuiWindowFlags window_flags = ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoDocking; - -// // Style windows -// const ImGuiViewport* viewport = ImGui::GetMainViewport(); -// ImGui::SetNextWindowPos(viewport->WorkPos); -// ImGui::SetNextWindowSize(viewport->WorkSize); -// ImGui::SetNextWindowViewport(viewport->ID); -// ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f); -// ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f); -// window_flags |= ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove; -// window_flags |= ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoNavFocus; -// window_flags |= ImGuiWindowFlags_NoBackground; - -// ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f)); -// ImGui::Begin("TerraVisor", nullptr, window_flags); -// ImGui::PopStyleVar(3); - -// // Submit the DockSpace -// if (io.ConfigFlags & ImGuiConfigFlags_DockingEnable) { -// ImGuiID dockspace_id = ImGui::GetID("MyDockSpace"); -// ImGui::DockSpace(dockspace_id, ImVec2(0.0f, 0.0f), dockspace_flags); -// } - -// if (ImGui::BeginMenuBar()) { -// if (ImGui::BeginMenu("Options")) { -// ImGui::Text("Nothing Here Yet, Check Back Later!"); - -// ImGui::EndMenu(); -// } - -// ImGui::EndMenuBar(); -// } - -// ImGui::End(); - -// //Draw Gui -// ImGui::Begin("Terrain Controls"); -// if (ImGui::Button("Quit")) { -// glfwSetWindowShouldClose(window, GLFW_TRUE); -// } - -// ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); -// ImGui::End(); - -// ImGui::Render(); -// ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); -// } - -// void Idle() { -// // Idle function to update the scene when no rendering is performed. -// } - -// void ReloadShader() -// { -// GLuint new_shader = InitShader(kVertexShader.c_str(), kFragmentShader.c_str()); - -// if (new_shader == -1) { // loading failed -// DEBUG_BREAK(); //alert user by breaking and showing debugger -// glClearColor(1.0f, 0.0f, 1.0f, 0.0f); //change clear color if shader can't be compiled -// } -// else { -// glClearColor(0.35f, 0.35f, 0.35f, 0.0f); - -// if (shader_program != -1) { -// glDeleteProgram(shader_program); -// } -// shader_program = new_shader; -// } -// } - -// void Init() { -// glewInit(); - -// glEnable(GL_DEPTH_TEST); -// glEnable(GL_CULL_FACE); - -// InitTri(); - -// ReloadShader(); - -// camera::UpdateP(); -// Uniforms::Init(); -// } - -// } // namespace scene \ No newline at end of file +} \ No newline at end of file