From f77dc55a682d665a22ed1473c627c4d2c4ac3d96 Mon Sep 17 00:00:00 2001 From: illegitimate-egg Date: Thu, 17 Oct 2024 21:08:32 +0100 Subject: [PATCH] Add Multiwindowed docking ui wowie viewport simulator --- .gitmodules | 3 -- TODO.md | 3 +- extern/imGuIZMO.quat | 1 - extern/imgui | 2 +- shaders/basic.frag | 2 +- shaders/basic_lit.frag | 2 +- src/engine.cpp | 104 ++++++++++++++++++++++++++++++++++++++++- 7 files changed, 108 insertions(+), 9 deletions(-) delete mode 160000 extern/imGuIZMO.quat diff --git a/.gitmodules b/.gitmodules index d235396..ca047d9 100644 --- a/.gitmodules +++ b/.gitmodules @@ -22,6 +22,3 @@ [submodule "extern/glad"] path = extern/glad url = https://github.com/Dav1dde/glad.git -[submodule "extern/imGuIZMO.quat"] - path = extern/imGuIZMO.quat - url = https://github.com/BrutPitt/imGuIZMO.quat diff --git a/TODO.md b/TODO.md index f6cf7e9..709544f 100644 --- a/TODO.md +++ b/TODO.md @@ -2,7 +2,6 @@ - [ ] Finish modularization - [ ] Lightmapped/Shadowmapped Lighting -- [ ] Get ziggy with it - [ ] Convert manual memory alloc to shared and unique pointers - [ ] Text - [ ] RT/texture rendering @@ -12,6 +11,8 @@ - [ ] Physics - [ ] Sound - [ ] Mesh deformation/animation +- [ ] BSP Mapping +- [ ] Window Resizing ### In progress diff --git a/extern/imGuIZMO.quat b/extern/imGuIZMO.quat deleted file mode 160000 index 6c038a9..0000000 --- a/extern/imGuIZMO.quat +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 6c038a90fdadae580b357fbaf26f83cafeb83a6a diff --git a/extern/imgui b/extern/imgui index cb16568..b0185ef 160000 --- a/extern/imgui +++ b/extern/imgui @@ -1 +1 @@ -Subproject commit cb16568fca5297512ff6a8f3b877f461c4323fbe +Subproject commit b0185efd248e5d56a6728da6a4746d5826a14370 diff --git a/shaders/basic.frag b/shaders/basic.frag index b05318b..82ca0e5 100644 --- a/shaders/basic.frag +++ b/shaders/basic.frag @@ -3,7 +3,7 @@ // Interpolated vals from vert shaders in vec2 UV; -out vec3 color; +layout(location = 0) out vec3 color; // Values stay constant uniform sampler2D textureSampler; diff --git a/shaders/basic_lit.frag b/shaders/basic_lit.frag index 8fe196d..a99eb03 100644 --- a/shaders/basic_lit.frag +++ b/shaders/basic_lit.frag @@ -6,7 +6,7 @@ in vec3 normal_cameraspace; in vec3 eyeDirection_cameraspace; in vec3 lightDirection_cameraspace; -out vec3 color; +layout(location = 0) out vec3 color; uniform sampler2D albedoSampler; uniform sampler2D specularSampler; diff --git a/src/engine.cpp b/src/engine.cpp index 362fd86..07b1311 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -268,6 +269,9 @@ public: GLFWwindow *window; GLuint vertexArrayID; +GLuint frameBufferName = 0; +GLuint renderedTexture; + float deltaTime = 0; float deltaTimeMultiplier = 1.0f; @@ -324,6 +328,8 @@ static int initWindow() { (void)io; io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; + io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; + //io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; ImGui::StyleColorsDark(); @@ -337,6 +343,32 @@ static int initWindow() { glClearColor(0.1f, 0.1f, 0.1f, 1.0f); + glGenFramebuffers(1, &frameBufferName); + glBindFramebuffer(GL_FRAMEBUFFER, frameBufferName); + + glGenTextures(1, &renderedTexture); + + glBindTexture(GL_TEXTURE_2D, renderedTexture); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1024, 768, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + // Depth + GLuint depthRenderBuffer; + glad_glGenRenderbuffers(1, &depthRenderBuffer); + glBindRenderbuffer(GL_RENDERBUFFER, depthRenderBuffer); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, 1024, 768); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthRenderBuffer); + + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, renderedTexture, 0); + + GLenum drawBuffers[1] = {GL_COLOR_ATTACHMENT0}; + glDrawBuffers(1, drawBuffers); + + if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { + return false; + } + glGenVertexArrays(1, &vertexArrayID); glBindVertexArray(vertexArrayID); @@ -371,6 +403,20 @@ void destroy() { /*}*/ void render(Scene scene) { + static ImVec2 viewportSize = ImVec2(1024, 768); + static ImVec2 viewportSizeOld = viewportSize; + if (viewportSizeOld != viewportSize) { + glBindTexture(GL_TEXTURE_2D, renderedTexture); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, viewportSize.x, viewportSize.y, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, viewportSize.x, viewportSize.y); + } + viewportSizeOld = viewportSize; + // Clear imgui viewport (already on primary framebuffer from end of call) + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + // Use viewport framebuffer + glBindFramebuffer(GL_FRAMEBUFFER, frameBufferName); + glViewport(0, 0, viewportSize.x, viewportSize.y); + // Clear this mf glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -383,11 +429,53 @@ void render(Scene scene) { ImGui_ImplGlfw_NewFrame(); ImGui::NewFrame(); + static ImGuiDockNodeFlags dockspaceFlags = ImGuiDockNodeFlags_PassthruCentralNode; + ImGuiWindowFlags windowFlags = ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoDocking; + + ImGuiViewport *viewport = ImGui::GetMainViewport(); + ImGui::SetNextWindowPos(viewport->Pos); + ImGui::SetNextWindowSize(viewport->Size); + ImGui::SetNextWindowViewport(viewport->ID); + ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f); + ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f); + windowFlags |= ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoNavFocus; + + if (dockspaceFlags & ImGuiDockNodeFlags_PassthruCentralNode) { + windowFlags |= ImGuiWindowFlags_NoBackground; + } + + ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f)); + ImGui::Begin("DockSpace", nullptr, windowFlags); + ImGui::PopStyleVar(); + ImGui::PopStyleVar(2); + + ImGuiIO &io = ImGui::GetIO(); + if (io.ConfigFlags & ImGuiConfigFlags_DockingEnable) { + ImGuiID dockspace_id = ImGui::GetID("myDockSpace"); + ImGui::DockSpace(dockspace_id, ImVec2(0.0f, 0.0f), dockspaceFlags); + + static bool firstTime = true; + if (firstTime) { + firstTime = false; + ImGui::DockBuilderRemoveNode(dockspace_id); + ImGui::DockBuilderAddNode(dockspace_id, dockspaceFlags | ImGuiDockNodeFlags_DockSpace); + ImGui::DockBuilderSetNodeSize(dockspace_id, viewport->Size); + + ImGuiID dock_id_left = ImGui::DockBuilderSplitNode(dockspace_id, ImGuiDir_Left, 0.2f, nullptr, &dockspace_id); + ImGuiID dock_id_down = ImGui::DockBuilderSplitNode(dockspace_id, ImGuiDir_Down, 0.25f, nullptr, &dockspace_id); + + ImGui::DockBuilderDockWindow("Down", dock_id_down); + ImGui::DockBuilderDockWindow("Left", dock_id_left); + ImGui::DockBuilderFinish(dockspace_id); + } + } + ImGui::End(); // Dockspace + Camera *currentCamera = scene.cameras[scene.activeCamera]; // Compute the V and P for the MVP glm::mat4 viewMatrix = glm::inverse(glm::translate(glm::mat4(1), currentCamera->position) * (mat4_cast(currentCamera->rotation))); - glm::mat4 projectionMatrix = glm::perspective(currentCamera->fov, (float)WIDTH / (float)HEIGHT, currentCamera->nearPlane, currentCamera->farPlane); + glm::mat4 projectionMatrix = glm::perspective(currentCamera->fov, (float)viewportSize.x / (float)viewportSize.y, currentCamera->nearPlane, currentCamera->farPlane); for (int i = 0; i < scene.assets.size(); i++) { Asset *currentAsset = scene.assets[i]; @@ -464,8 +552,22 @@ void render(Scene scene) { scene.renderCallback(); } + ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0)); + ImGui::Begin("Viewport"); + ImGui::Image((ImTextureID)frameBufferName, viewportSize, ImVec2(0, 1), ImVec2(1, 0)); + viewportSize = ImGui::GetWindowContentRegionMax() - ImGui::GetWindowContentRegionMin(); + ImGui::End(); + ImGui::PopStyleVar(); + + + glBindFramebuffer(GL_FRAMEBUFFER, 0); + glViewport(0, 0, WIDTH, HEIGHT); + ImGui::Render(); ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); + //ImGui::UpdatePlatformWindows(); + //ImGui::RenderPlatformWindowsDefault(); + //glfwMakeContextCurrent(window); // Swap buffers glfwSwapBuffers(window);