From eb67c1deaf63d9c7a5f9ef7b35e0851b0b43785b Mon Sep 17 00:00:00 2001 From: Martin Felis Date: Sat, 15 Dec 2018 15:58:47 +0100 Subject: [PATCH] Switch to the docking code of dear imgui --- .../imgui/examples/imgui_impl_opengl3.cpp | 14 +- CMakeLists.txt | 10 +- src/main.cc | 132 ++++++++++++++---- src/modules/RenderModule.cc | 23 ++- src/modules/RenderModule.h | 13 +- src/modules/RenderUtils.cc | 1 + src/modules/RenderUtils.h | 2 +- src/modules/TestModule.cc | 2 +- 8 files changed, 139 insertions(+), 58 deletions(-) diff --git a/3rdparty/imgui/examples/imgui_impl_opengl3.cpp b/3rdparty/imgui/examples/imgui_impl_opengl3.cpp index 6f62cb8..eefdf6a 100644 --- a/3rdparty/imgui/examples/imgui_impl_opengl3.cpp +++ b/3rdparty/imgui/examples/imgui_impl_opengl3.cpp @@ -263,8 +263,18 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data) else glScissor((int)clip_rect.x, (int)clip_rect.y, (int)clip_rect.z, (int)clip_rect.w); // Support for GL 4.5's glClipControl(GL_UPPER_LEFT) - // Bind texture, Draw - glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); + // MOD START (martin), 2018-03-09: support texture references that point to an address of a texture id + intptr_t ptr = (intptr_t)pcmd->TextureId; + if (ptr > 1024 * 1024) + { + GLTextureRef* texture_ref = (GLTextureRef*)pcmd->TextureId; + GLuint* texture_ptr = (GLuint*) texture_ref->mTextureIdPtr; + glBindTexture(GL_TEXTURE_2D, *texture_ptr); + } else { + glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); + } + // MOD END (martin), 2018-03-09: support texture references that point to an address of a texture id + glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer_offset); } } diff --git a/CMakeLists.txt b/CMakeLists.txt index ef6ebbb..5eebb94 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,9 +19,9 @@ include(CheckCXXCompilerFlag) CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11) CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X) if(COMPILER_SUPPORTS_CXX11) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fPIC") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") elseif(COMPILER_SUPPORTS_CXX0X) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x -fPIC") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x") else() message(STATUS "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.") endif() @@ -31,6 +31,7 @@ set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_GLIBCXX_DEBUG") message(STATUS "Using compiler flags ${CMAKE_CXX_FLAGS}") +add_definitions("-DIMGUI_IMPL_OPENGL_LOADER_GLAD") INCLUDE_DIRECTORIES ( ${CMAKE_CURRENT_BINARY_DIR} @@ -53,7 +54,6 @@ INCLUDE_DIRECTORIES ( 3rdparty/imgui 3rdparty/imgui/examples/ - 3rdparty/imgui/examples/libs/gl3w ) SUBDIRS ( @@ -72,15 +72,15 @@ SET ( protot_SRCS src/RuntimeModuleManager.cc src/Utils.cc + 3rdparty/glfw/deps/glad.c 3rdparty/imgui/imgui.cpp 3rdparty/imgui/imgui_draw.cpp 3rdparty/imgui/imgui_widgets.cpp 3rdparty/imgui/imgui_demo.cpp - 3rdparty/imgui/examples/libs/gl3w/GL/gl3w.c 3rdparty/imgui/examples/imgui_impl_glfw.cpp 3rdparty/imgui/examples/imgui_impl_opengl3.cpp - 3rdparty/imgui_dock_lumix/imgui_dock.cpp +# 3rdparty/imgui_dock_lumix/imgui_dock.cpp ) SET (PROTOT_SOURCE_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR}) diff --git a/src/main.cc b/src/main.cc index f76a1f0..71a51f2 100644 --- a/src/main.cc +++ b/src/main.cc @@ -1,6 +1,6 @@ -#include // This example is using gl3w to access OpenGL functions (because it is small). You may use glew/glad/glLoadGen/etc. whatever already works for you. +#include // This example is using gl3w to access OpenGL functions (because it is small). You may use glew/glad/glLoadGen/etc. whatever already works for you. #include -#include +//#include #include "Globals.h" @@ -55,9 +55,9 @@ static void opengl_error_callback( const GLchar* message, const void* userParam ) { - gLog ("OpenGL Error: %s type %0x%x, severity = 0x%x, message = %s", - ( type == GL_DEBUG_TYPE_ERROR ? "** GL ERROR **" : "" ), - type, severity, message ); +// gLog ("OpenGL Error: %s type %0x%x, severity = 0x%x, message = %s", +// ( type == GL_DEBUG_TYPE_ERROR ? "** GL ERROR **" : "" ), +// type, severity, message ); } static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) @@ -110,24 +110,24 @@ int main(void) glfwSetErrorCallback(error_callback); glfwInit(); - const char* glsl_version = "#version 150"; + const char* glsl_version = "#version 130"; glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_API); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0); glfwWindowHint(GLFW_SAMPLES, 16); - glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); +// glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); #if __APPLE__ glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); #endif gWindow = glfwCreateWindow(800, 600, "ProtoT", NULL, NULL); + assert(gWindow != NULL); glfwMakeContextCurrent(gWindow); glfwSwapInterval(1); - gl3wInit(); - int width, height; - glfwGetWindowSize(gWindow, &width, &height); + // Initialize OpenGL loader + gladLoadGLLoader((GLADloadproc) glfwGetProcAddress); glfwSetKeyCallback(gWindow, key_callback); glfwSetScrollCallback (gWindow, mouse_scroll_callback); @@ -136,17 +136,31 @@ int main(void) std::cout << "GLSL Version : " << glGetString(GL_SHADING_LANGUAGE_VERSION) << endl; // During init, enable debug output - glEnable ( GL_DEBUG_OUTPUT ); - glDebugMessageCallback( (GLDEBUGPROC) opengl_error_callback, 0 ); +// glEnable ( GL_DEBUG_OUTPUT ); +// glDebugMessageCallback( (GLDEBUGPROC) opengl_error_callback, 0 ); // imgui initialization. + IMGUI_CHECKVERSION(); ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); (void)io; + io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; +// io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; + GuiInputState gui_input_state; gGuiInputState = &gui_input_state; + ImGui_ImplGlfw_InitForOpenGL(gWindow, true); ImGui_ImplOpenGL3_Init(glsl_version); + // Setup Style + ImGui::StyleColorsDark(); + //ImGui::StyleColorsClassic(); + + ImGuiStyle& style = ImGui::GetStyle(); + style.WindowRounding = 0.0f; // When viewports are enabled it is preferable to disable WinodwRounding + style.Colors[ImGuiCol_WindowBg].w = 1.0f; // When viewports are enabled it is preferable to disable WindowBg alpha + + // FileModificationObserver FileModificationObserver file_modification_observer; gFileModificationObserver = &file_modification_observer; @@ -176,19 +190,23 @@ int main(void) double frame_delta_time = 0.0; uint64_t frame_counter = 0; - bool draw_imgui_demo = false; + bool show_demo_window = false; + ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); while(!glfwWindowShouldClose(gWindow)) { frame_counter++; // Start the imgui frame such that widgets can be submitted handle_mouse(); - glfwGetWindowSize(gWindow, &width, &height); - glViewport(0, 0, width, height); glfwPollEvents(); + ImGui_ImplOpenGL3_NewFrame(); ImGui_ImplGlfw_NewFrame(); + ImGui::NewFrame(); + + if (show_demo_window) + ImGui::ShowDemoWindow(&show_demo_window); if (module_manager.CheckModulesChanged()) { gLog("Detected module update at frame %d. Unloading all modules.", frame_counter); @@ -200,7 +218,7 @@ int main(void) frame_time_last = frame_time_current; frame_time_current = glfwGetTime(); frame_delta_time = frame_time_current - frame_time_last; - + gTimer->mFrameTime = (float)(frame_delta_time); if (!gTimer->mPaused) { gTimer->mDeltaTime = gTimer->mFrameTime; @@ -211,30 +229,87 @@ int main(void) assert (gTimer->mDeltaTime >= 0.0f); int width, height; - glfwGetWindowSize(gWindow, &width, &height); - ImGui::BeginMainMenuBar(); if (ImGui::BeginMenu("Dialogs")) { - ImGui::Checkbox("ImGui Demo", &draw_imgui_demo); + ImGui::Checkbox("ImGui Demo", &show_demo_window); ImGui::EndMenu(); } float menu_bar_height = ImGui::GetWindowHeight(); ImGui::EndMainMenuBar(); - if (draw_imgui_demo) + if (show_demo_window) ImGui::ShowDemoWindow(); + static bool opt_fullscreen_persistant = true; + static ImGuiDockNodeFlags opt_flags = ImGuiDockNodeFlags_None; + bool opt_fullscreen = opt_fullscreen_persistant; - ImGui::RootDock(ImVec2(0.0f, menu_bar_height), ImVec2(width, height - menu_bar_height)); + // We are using the ImGuiWindowFlags_NoDocking flag to make the parent window not dockable into, + // because it would be confusing to have two docking targets within each others. + ImGuiWindowFlags window_flags = ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoDocking; + if (opt_fullscreen) + { + 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); + window_flags |= ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove; + window_flags |= ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoNavFocus; + } + + // When using ImGuiDockNodeFlags_PassthruDockspace, DockSpace() will render our background and handle the pass-thru hole, so we ask Begin() to not render a background. + if (opt_flags & ImGuiDockNodeFlags_PassthruDockspace) + window_flags |= ImGuiWindowFlags_NoBackground; + + ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f)); + ImGui::Begin("DockSpace Demo", NULL, window_flags); + ImGui::PopStyleVar(); + + if (opt_fullscreen) + ImGui::PopStyleVar(2); + + if (io.ConfigFlags & ImGuiConfigFlags_DockingEnable) { + ImGuiID dockspace_id = ImGui::GetID("MyDockspace"); + ImGui::DockSpace(dockspace_id, ImVec2(0.0f, 0.0f), opt_flags); + } else { + gLog("Error: no docking not enabled"); + } + ImGui::End(); module_manager.Update(gTimer->mDeltaTime); - ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); - // Send the application to sleep if we have some time left for this frame + + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + + // Rendering + ImGui::Render(); + int display_w, display_h; + glfwMakeContextCurrent(gWindow); + glfwGetFramebufferSize(gWindow, &display_w, &display_h); + glViewport(0, 0, display_w, display_h); + glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); + glClear(GL_COLOR_BUFFER_BIT); + ImDrawData* draw_data = ImGui::GetDrawData(); + assert (draw_data != NULL); + ImGui_ImplOpenGL3_RenderDrawData(draw_data); + + // Update and Render additional Platform Windows + if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) + { + ImGui::UpdatePlatformWindows(); + ImGui::RenderPlatformWindowsDefault(); + } + + glfwMakeContextCurrent(gWindow); + glfwSwapBuffers(gWindow); + + // Send the application to sleep if we have some time left for this frame double frame_target_time = 1.0 / module_manager.mTargetFPS; if (frame_delta_time < frame_target_time) { usleep ((frame_target_time - frame_delta_time) * 1000000 * 0.98); @@ -242,18 +317,13 @@ int main(void) if (glfwGetKey(gWindow, GLFW_KEY_F5) == GLFW_PRESS) { gFileModificationObserver->Update(); - } - - glfwSwapBuffers(gWindow); + } } - ImGui::SaveDock(); - module_manager.UnregisterModules(); + module_manager.UnregisterModules(); gRenderer = nullptr; - ImGui::ShutdownDock(); - ImGui_ImplOpenGL3_Shutdown(); ImGui_ImplGlfw_Shutdown(); ImGui::DestroyContext(); diff --git a/src/modules/RenderModule.cc b/src/modules/RenderModule.cc index 5a2775b..f321b7c 100644 --- a/src/modules/RenderModule.cc +++ b/src/modules/RenderModule.cc @@ -8,7 +8,6 @@ #include "Serializer.h" #include "imgui/imgui.h" -#include "imgui_dock.h" using namespace SimpleMath::GL; @@ -284,8 +283,8 @@ void Light::UpdateSplits(const Camera& camera) { Matrix44f light_matrix = LookAt (mPosition, mPosition + mDirection, Vector3f (0.f, 1.0f, 0.0f)); Matrix44f light_matrix_inv = light_matrix.inverse(); - mShadowSplits[0] = near + length * 0.05; - mShadowSplits[1] = near + length * 0.15; + mShadowSplits[0] = near + length * 0.03; + mShadowSplits[1] = near + length * 0.10; mShadowSplits[2] = near + length * 0.4; mShadowSplits[3] = far; @@ -1013,7 +1012,7 @@ void Renderer::RenderScene(RenderProgram &program, const Camera& camera) { // TranslateMat44(0.0f, 2.0f, 2.0f), // Vector3f (0.4f, 0.2f, 0.9f) // ); -// + DebugDrawBone( program, @@ -1024,7 +1023,7 @@ void Renderer::RenderScene(RenderProgram &program, const Camera& camera) { } void Renderer::DrawGui() { - if (ImGui::BeginDock("Scene")) { + if (ImGui::Begin("Scene")) { ImGui::RadioButton("Default", &sRendererSettings.RenderMode, 0); ImGui::SameLine(); ImGui::RadioButton("Color", &sRendererSettings.RenderMode, 1); ImGui::SameLine(); ImGui::RadioButton("Depth", &sRendererSettings.RenderMode, 2); ImGui::SameLine(); @@ -1067,14 +1066,14 @@ void Renderer::DrawGui() { ); } - ImGui::EndDock(); + ImGui::End(); - if (ImGui::BeginDock("Light Settings")) { + if (ImGui::Begin("Light Settings")) { mLight.DrawGui(); } - ImGui::EndDock(); + ImGui::End(); - if (ImGui::BeginDock("Render Settings")) { + if (ImGui::Begin("Render Settings")) { ImGui::Text("Camera"); mCamera.DrawGui(); @@ -1095,12 +1094,12 @@ void Renderer::DrawGui() { } } } - ImGui::EndDock(); + ImGui::End(); - if (ImGui::BeginDock("Asset")) { + if (ImGui::Begin("Asset")) { gAssetFile.DrawGui(); } - ImGui::EndDock(); + ImGui::End(); } void Renderer::InitializeSSAOKernelAndNoise() { diff --git a/src/modules/RenderModule.h b/src/modules/RenderModule.h index 49e27ff..ebd78ed 100644 --- a/src/modules/RenderModule.h +++ b/src/modules/RenderModule.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include @@ -31,13 +32,13 @@ struct Light { float mShadowBias = 0.003; float mShowCascadesAlpha = 0.0f; - bool mDebugDrawSplitViewBounds = true; - bool mDebugDrawSplitWorldBounds = true; - bool mDebugDrawSplitLightBounds = true; + bool mDebugDrawSplitViewBounds = false; + bool mDebugDrawSplitWorldBounds = false; + bool mDebugDrawSplitLightBounds = false; Matrix44f mLightSpaceMatrix; - Vector4f mShadowSplits = Vector4f (0.0, 0.1, 0.4, 1.0); + Vector4f mShadowSplits = Vector4f (0.0, 0.05, 0.3, 1.0); Matrix44f mSplitViewFrustum[4]; Matrix44f mSplitLightFrustum[4]; @@ -51,7 +52,7 @@ struct Light { mPosition (Vector3f(0.f, 3, 0.0f)), mDirection (Vector3f(1.f, 1.f, 1.f)), mShadowMapBias (0.004f), - mShadowMapSize (512), + mShadowMapSize (2048), mNear (-10.0f), mFar (15.f), mBBoxSize (35.f), @@ -73,7 +74,7 @@ struct Renderer { bool mInitialized = false; bool mIsSSAOEnabled = false; bool mUseDeferred = false; - bool mDrawDebugCamera = true; + bool mDrawDebugCamera = false; uint32_t mWidth = 1; uint32_t mHeight = 1; diff --git a/src/modules/RenderUtils.cc b/src/modules/RenderUtils.cc index 7bac33c..52f756f 100644 --- a/src/modules/RenderUtils.cc +++ b/src/modules/RenderUtils.cc @@ -761,6 +761,7 @@ void VertexArrayMesh::SetIndexData(const GLuint* indices, const int& count) { } void VertexArrayMesh::Draw(GLenum mode) { + this->mVertexArray->Bind(); assert(mVertexArray->IsBound()); if (mIndexBuffer == -1) { diff --git a/src/modules/RenderUtils.h b/src/modules/RenderUtils.h index 4349fd9..79435dd 100644 --- a/src/modules/RenderUtils.h +++ b/src/modules/RenderUtils.h @@ -3,7 +3,7 @@ #pragma once -#include // This example is using gl3w to access OpenGL functions (because it is small). You may use glew/glad/glLoadGen/etc. whatever already works for you. +#include // This example is using gl3w to access OpenGL functions (because it is small). You may use glew/glad/glLoadGen/etc. whatever already works for you. #include "FileModificationObserver.h" diff --git a/src/modules/TestModule.cc b/src/modules/TestModule.cc index f17290b..1329d14 100644 --- a/src/modules/TestModule.cc +++ b/src/modules/TestModule.cc @@ -1,7 +1,7 @@ #include "RuntimeModule.h" #include "Globals.h" -#include // This example is using gl3w to access OpenGL functions (because it is small). You may use glew/glad/glLoadGen/etc. whatever already works for you. +#include // This example is using gl3w to access OpenGL functions (because it is small). You may use glew/glad/glLoadGen/etc. whatever already works for you. #include "imgui/imgui.h" #include