From 069a64005f032f4c7f416ff707a3f9d102ee519b Mon Sep 17 00:00:00 2001 From: "Z.A" Date: Sun, 21 Feb 2021 20:55:26 -0800 Subject: [PATCH 01/12] Add ImGui, ImPlot integration Implement Magnum's ImGui integration, and also include ImPlot (a handy plotting library for ImGui). ImPlot is not part of the ImGui integration, so its context must be managed manually. Add a simple FPS counter in OSPMagnum for now; need a better GUI system --- .gitmodules | 6 + 3rdparty/CMakeLists.txt | 4 + 3rdparty/imgui | 1 + 3rdparty/implot | 1 + 3rdparty/magnum-integration | 1 + modules/FindImGui.cmake | 207 +++++++++++++++++++ modules/FindMagnumIntegration.cmake | 309 ++++++++++++++++++++++++++++ src/CMakeLists.txt | 11 +- src/test_application/OSPMagnum.cpp | 41 ++++ src/test_application/OSPMagnum.h | 6 + 10 files changed, 586 insertions(+), 1 deletion(-) create mode 160000 3rdparty/imgui create mode 160000 3rdparty/implot create mode 160000 3rdparty/magnum-integration create mode 100644 modules/FindImGui.cmake create mode 100644 modules/FindMagnumIntegration.cmake diff --git a/.gitmodules b/.gitmodules index 912eba1c..c5077452 100644 --- a/.gitmodules +++ b/.gitmodules @@ -22,3 +22,9 @@ [submodule "3rdparty/toml11"] path = 3rdparty/toml11 url = https://github.com/ToruNiina/toml11 +[submodule "3rdparty/imgui"] + path = 3rdparty/imgui + url = https://github.com/ocornut/imgui.git +[submodule "3rdparty/implot"] + path = 3rdparty/implot + url = https://github.com/epezent/implot.git diff --git a/3rdparty/CMakeLists.txt b/3rdparty/CMakeLists.txt index 26c96cb6..06e5a697 100644 --- a/3rdparty/CMakeLists.txt +++ b/3rdparty/CMakeLists.txt @@ -44,5 +44,9 @@ SET(NEWTON_BUILD_SANDBOX_DEMOS OFF CACHE BOOL "" FORCE) SET(NEWTON_BUILD_SHARED_LIBS ON CACHE BOOL "" FORCE) ADD_SUBDIRECTORY(newton-dynamics) +set(IMGUI_DIR ${CMAKE_CURRENT_SOURCE_DIR}/imgui) +set(WITH_IMGUI ON CACHE BOOL "" FORCE) +ADD_SUBDIRECTORY(magnum-integration EXCLUDE_FROM_ALL) + ADD_SUBDIRECTORY(entt) ADD_SUBDIRECTORY(toml11) diff --git a/3rdparty/imgui b/3rdparty/imgui new file mode 160000 index 00000000..c9fafd5e --- /dev/null +++ b/3rdparty/imgui @@ -0,0 +1 @@ +Subproject commit c9fafd5ea4e316996f20067882600676decc97e6 diff --git a/3rdparty/implot b/3rdparty/implot new file mode 160000 index 00000000..f9a15a71 --- /dev/null +++ b/3rdparty/implot @@ -0,0 +1 @@ +Subproject commit f9a15a71475ec5d2bdae5d441796e46e279e882e diff --git a/3rdparty/magnum-integration b/3rdparty/magnum-integration new file mode 160000 index 00000000..b400f096 --- /dev/null +++ b/3rdparty/magnum-integration @@ -0,0 +1 @@ +Subproject commit b400f0966ac9f0c05891c14321d11afc363c905a diff --git a/modules/FindImGui.cmake b/modules/FindImGui.cmake new file mode 100644 index 00000000..85a32e97 --- /dev/null +++ b/modules/FindImGui.cmake @@ -0,0 +1,207 @@ +#.rst: +# Find ImGui +# ------------- +# +# Finds the ImGui library. This module defines: +# +# ImGui_FOUND - True if ImGui is found +# ImGui::ImGui - ImGui interface target +# ImGui::Sources - ImGui source target for core functionality +# ImGui::SourcesMiscCpp - ImGui source target for misc/cpp +# +# Additionally these variables are defined for internal usage: +# +# ImGui_INCLUDE_DIR - Include dir +# +# The find module first tries to find ``imgui`` via a CMake config file (which +# is distributed this way via Vcpkg, for example). If that's found, the +# ``ImGui::ImGui`` target is an alias to it and the ``ImGui::Sources`` target +# is empty except for having ``ImGui::ImGui`` as a dependency. +# +# If ``imgui`` is not found, as a fallback it tries to find the C++ sources. +# You can supply their location via an ``IMGUI_DIR`` variable. Once found, the +# ``ImGui::ImGui`` target contains just the header file, while +# ``ImGui::Sources`` contains the source files in ``INTERFACE_SOURCES``. +# +# The ``ImGui::SourcesMiscCpp`` component, if requested, is always searched for +# in the form of C++ sources. Vcpkg doesn't distribute these. +# +# The desired usage that covers both cases is to link ``ImGui::Sources`` +# ``PRIVATE``\ ly to a *single* target, which will then contain either the +# sources or be linked to the imgui library from Vcpkg; and linking +# ``ImGui::ImGui`` to this target ``PUBLIC``\ ly. +# + +# +# This file is part of Magnum. +# +# Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, +# 2020 Vladimír VondruÅ¡ +# Copyright © 2018 Jonathan Hale +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +# DEALINGS IN THE SOFTWARE. +# + +# In 1.71 ImGui depends on the ApplicationServices framework for macOS +# clipboard support. It's removed again in 1.72. TODO: remove once obsolete +if(CORRADE_TARGET_APPLE) + find_library(_IMGUI_ApplicationServices_LIBRARY ApplicationServices) + mark_as_advanced(_IMGUI_ApplicationServices_LIBRARY) + set(_IMGUI_EXTRA_LIBRARIES ${_IMGUI_ApplicationServices_LIBRARY}) +endif() + +# Vcpkg distributes imgui as a library with a config file, so try that first -- +# but only if IMGUI_DIR wasn't explicitly passed, in which case we'll look +# there instead +if(NOT IMGUI_DIR AND NOT TARGET imgui::imgui) + find_package(imgui CONFIG QUIET) +endif() +if(NOT IMGUI_DIR AND TARGET imgui::imgui) + if(NOT TARGET ImGui::ImGui) + add_library(ImGui::ImGui INTERFACE IMPORTED) + # TODO: remove once 1.71 is obsolete + set_property(TARGET ImGui::ImGui APPEND PROPERTY + INTERFACE_LINK_LIBRARIES imgui::imgui ${_IMGUI_EXTRA_LIBRARIES}) + + # Retrieve include directory for FindPackageHandleStandardArgs later + get_target_property(ImGui_INCLUDE_DIR imgui::imgui + INTERFACE_INCLUDE_DIRECTORIES) + + add_library(ImGui::Sources INTERFACE IMPORTED) + set_property(TARGET ImGui::Sources APPEND PROPERTY + INTERFACE_LINK_LIBRARIES ImGui::ImGui) + endif() + +# Otherwise find the source files and compile them as part of the library they +# get linked to +else() + # Disable the find root path here, it overrides the + # CMAKE_FIND_ROOT_PATH_MODE_INCLUDE setting potentially set in + # toolchains. + find_path(ImGui_INCLUDE_DIR NAMES imgui.h + HINTS ${IMGUI_DIR} + PATH_SUFFIXES MagnumExternal/ImGui + NO_CMAKE_FIND_ROOT_PATH) + mark_as_advanced(ImGui_INCLUDE_DIR) + + if(NOT TARGET ImGui::ImGui) + add_library(ImGui::ImGui INTERFACE IMPORTED) + set_property(TARGET ImGui::ImGui APPEND PROPERTY + INTERFACE_INCLUDE_DIRECTORIES ${ImGui_INCLUDE_DIR}) + # TODO: remove once 1.71 is obsolete + if(_IMGUI_EXTRA_LIBRARIES) + set_property(TARGET ImGui::ImGui APPEND PROPERTY + INTERFACE_LINK_LIBRARIES ${_IMGUI_EXTRA_LIBRARIES}) + endif() + + # Handle export and import of imgui symbols via IMGUI_API definition + # in visibility.h of Magnum ImGuiIntegration. + set_property(TARGET ImGui::ImGui APPEND PROPERTY INTERFACE_COMPILE_DEFINITIONS + "IMGUI_USER_CONFIG=\"Magnum/ImGuiIntegration/visibility.h\"") + endif() +endif() + +macro(_imgui_setup_source_file source_var) + # Handle export and import of imgui symbols via IMGUI_API + # definition in visibility.h of Magnum ImGuiIntegration. + set_property(SOURCE ${${source_var}} APPEND PROPERTY COMPILE_DEFINITIONS + "IMGUI_USER_CONFIG=\"Magnum/ImGuiIntegration/visibility.h\"") + + # Hide warnings from imgui source files + + # GCC- and Clang-specific flags + if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR (CMAKE_CXX_COMPILER_ID MATCHES "(Apple)?Clang" + AND NOT CMAKE_CXX_SIMULATE_ID STREQUAL "MSVC") OR CORRADE_TARGET_EMSCRIPTEN) + set_property(SOURCE ${${source_var}} APPEND_STRING PROPERTY COMPILE_FLAGS + " -Wno-old-style-cast -Wno-zero-as-null-pointer-constant") + endif() + + # GCC-specific flags + if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + set_property(SOURCE ${${source_var}} APPEND_STRING PROPERTY COMPILE_FLAGS + " -Wno-double-promotion") + endif() + + mark_as_advanced(${source_var}) +endmacro() + +# Find components +foreach(_component IN LISTS ImGui_FIND_COMPONENTS) + if(_component STREQUAL "Sources") + if(NOT TARGET ImGui::Sources) + set(ImGui_Sources_FOUND TRUE) + set(ImGui_SOURCES ) + + foreach(_file imgui imgui_widgets imgui_draw imgui_demo) + # Disable the find root path here, it overrides the + # CMAKE_FIND_ROOT_PATH_MODE_INCLUDE setting potentially set in + # toolchains. + find_file(ImGui_${_file}_SOURCE NAMES ${_file}.cpp + HINTS ${IMGUI_DIR} NO_CMAKE_FIND_ROOT_PATH) + list(APPEND ImGui_SOURCES ${ImGui_${_file}_SOURCE}) + + if(NOT ImGui_${_file}_SOURCE) + set(ImGui_Sources_FOUND FALSE) + break() + endif() + + _imgui_setup_source_file(ImGui_${_file}_SOURCE) + endforeach() + + add_library(ImGui::Sources INTERFACE IMPORTED) + set_property(TARGET ImGui::Sources APPEND PROPERTY + INTERFACE_SOURCES "${ImGui_SOURCES}") + set_property(TARGET ImGui::Sources APPEND PROPERTY + INTERFACE_LINK_LIBRARIES ImGui::ImGui) + else() + set(ImGui_Sources_FOUND TRUE) + endif() + elseif(_component STREQUAL "SourcesMiscCpp") + set(ImGui_SourcesMiscCpp_FOUND TRUE) + set(ImGui_MISC_CPP_SOURCES ) + + foreach(_file imgui_stdlib) + # Disable the find root path here, it overrides the + # CMAKE_FIND_ROOT_PATH_MODE_INCLUDE setting potentially set in + # toolchains. + find_file(ImGui_${_file}_MISC_CPP_SOURCE NAMES ${_file}.cpp + HINTS ${IMGUI_DIR}/misc/cpp NO_CMAKE_FIND_ROOT_PATH) + list(APPEND ImGui_MISC_CPP_SOURCES ${ImGui_${_file}_MISC_CPP_SOURCE}) + + if(NOT ImGui_${_file}_MISC_CPP_SOURCE) + set(ImGui_SourcesMiscCpp_FOUND FALSE) + break() + endif() + + _imgui_setup_source_file(ImGui_${_file}_MISC_CPP_SOURCE) + endforeach() + + if(NOT TARGET ImGui::SourcesMiscCpp) + add_library(ImGui::SourcesMiscCpp INTERFACE IMPORTED) + set_property(TARGET ImGui::SourcesMiscCpp APPEND PROPERTY + INTERFACE_SOURCES "${ImGui_MISC_CPP_SOURCES}") + set_property(TARGET ImGui::SourcesMiscCpp APPEND PROPERTY + INTERFACE_LINK_LIBRARIES ImGui::ImGui) + endif() + endif() +endforeach() + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(ImGui + REQUIRED_VARS ImGui_INCLUDE_DIR HANDLE_COMPONENTS) diff --git a/modules/FindMagnumIntegration.cmake b/modules/FindMagnumIntegration.cmake new file mode 100644 index 00000000..46957956 --- /dev/null +++ b/modules/FindMagnumIntegration.cmake @@ -0,0 +1,309 @@ +#.rst: +# Find Magnum integration library +# ------------------------------- +# +# Finds the Magnum integration library. Basic usage:: +# +# find_package(MagnumIntegration REQUIRED) +# +# This command tries to find Magnum integration library and then defines the +# following: +# +# MagnumIntegration_FOUND - Whether the library was found +# +# This command alone is useless without specifying the components: +# +# Bullet - Bullet Physics integration library +# Dart - Dart Physics integration library +# Eigen - Eigen integration library +# Glm - GLM integration library +# ImGui - ImGui integration library +# Ovr - Oculus SDK integration library +# +# Example usage with specifying additional components is: +# +# find_package(MagnumIntegration REQUIRED Bullet) +# +# For each component is then defined: +# +# MagnumIntegration_*_FOUND - Whether the component was found +# MagnumIntegration::* - Component imported target +# +# The package is found if either debug or release version of each requested +# library is found. If both debug and release libraries are found, proper +# version is chosen based on actual build configuration of the project (i.e. +# Debug build is linked to debug libraries, Release build to release +# libraries). +# +# Additionally these variables are defined for internal usage: +# +# MAGNUMINTEGRATION_INCLUDE_DIR - Magnum integration include dir (w/o +# dependencies) +# MAGNUMINTEGRATION_*_LIBRARY_DEBUG - Debug version of given library, if found +# MAGNUMINTEGRATION_*_LIBRARY_RELEASE - Release version of given library, if +# found +# + +# +# This file is part of Magnum. +# +# Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, +# 2020 Vladimír VondruÅ¡ +# Copyright © 2018 Konstantinos Chatzilygeroudis +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +# DEALINGS IN THE SOFTWARE. +# + +# Magnum library dependencies +set(_MAGNUMINTEGRATION_DEPENDENCIES ) +foreach(_component ${MagnumIntegration_FIND_COMPONENTS}) + if(_component STREQUAL Bullet) + set(_MAGNUMINTEGRATION_${_component}_MAGNUM_DEPENDENCIES SceneGraph Shaders GL) + elseif(_component STREQUAL Dart) + set(_MAGNUMINTEGRATION_${_component}_MAGNUM_DEPENDENCIES SceneGraph Primitives MeshTools GL) + elseif(_component STREQUAL ImGui) + set(_MAGNUMINTEGRATION_${_component}_MAGNUM_DEPENDENCIES GL Shaders) + endif() + + list(APPEND _MAGNUMINTEGRATION_DEPENDENCIES ${_MAGNUMINTEGRATION_${_component}_MAGNUM_DEPENDENCIES}) + list(APPEND _MAGNUMINTEGRATION_OPTIONAL_DEPENDENCIES ${_MAGNUMINTEGRATION_${_component}_MAGNUM_OPTIONAL_DEPENDENCIES}) +endforeach() +find_package(Magnum REQUIRED ${_MAGNUMINTEGRATION_DEPENDENCIES}) +if(_MAGNUMINTEGRATION_OPTIONAL_DEPENDENCIES) + find_package(Magnum OPTIONAL_COMPONENTS ${_MAGNUMINTEGRATION_OPTIONAL_DEPENDENCIES}) +endif() + +# Global integration include dir +find_path(MAGNUMINTEGRATION_INCLUDE_DIR Magnum + HINTS ${MAGNUM_INCLUDE_DIR}) +mark_as_advanced(MAGNUMINTEGRATION_INCLUDE_DIR) + +# Component distinction (listing them explicitly to avoid mistakes with finding +# components from other repositories) +set(_MAGNUMINTEGRATION_LIBRARY_COMPONENT_LIST Bullet Dart Eigen ImGui Glm Ovr) +set(_MAGNUMINTEGRATION_HEADER_ONLY_COMPONENT_LIST Eigen) + +# Inter-component dependencies (none yet) +# set(_MAGNUMINTEGRATION_Component_DEPENDENCIES Dependency) + +# Ensure that all inter-component dependencies are specified as well +set(_MAGNUMINTEGRATION_ADDITIONAL_COMPONENTS ) +foreach(_component ${MagnumIntegration_FIND_COMPONENTS}) + # Mark the dependencies as required if the component is also required + if(MagnumIntegration_FIND_REQUIRED_${_component}) + foreach(_dependency ${_MAGNUMINTEGRATION_${_component}_DEPENDENCIES}) + set(MagnumIntegration_FIND_REQUIRED_${_dependency} TRUE) + endforeach() + endif() + + list(APPEND _MAGNUMINTEGRATION_ADDITIONAL_COMPONENTS ${_MAGNUMINTEGRATION_${_component}_DEPENDENCIES}) +endforeach() + +# Join the lists, remove duplicate components +if(_MAGNUMINTEGRATION_ADDITIONAL_COMPONENTS) + list(INSERT MagnumIntegration_FIND_COMPONENTS 0 ${_MAGNUMINTEGRATION_ADDITIONAL_COMPONENTS}) +endif() +if(MagnumIntegration_FIND_COMPONENTS) + list(REMOVE_DUPLICATES MagnumIntegration_FIND_COMPONENTS) +endif() + +# Convert components lists to regular expressions so I can use if(MATCHES). +# TODO: Drop this once CMake 3.3 and if(IN_LIST) can be used +foreach(_WHAT LIBRARY HEADER_ONLY) + string(REPLACE ";" "|" _MAGNUMINTEGRATION_${_WHAT}_COMPONENTS "${_MAGNUMINTEGRATION_${_WHAT}_COMPONENT_LIST}") + set(_MAGNUMINTEGRATION_${_WHAT}_COMPONENTS "^(${_MAGNUMINTEGRATION_${_WHAT}_COMPONENTS})$") +endforeach() + +# Find all components +foreach(_component ${MagnumIntegration_FIND_COMPONENTS}) + string(TOUPPER ${_component} _COMPONENT) + + # Create imported target in case the library is found. If the project is + # added as subproject to CMake, the target already exists and all the + # required setup is already done from the build tree. + if(TARGET MagnumIntegration::${_component}) + set(MagnumIntegration_${_component}_FOUND TRUE) + else() + # Library components + if(_component MATCHES ${_MAGNUMINTEGRATION_LIBRARY_COMPONENTS} AND NOT _component MATCHES ${_MAGNUMINTEGRATION_HEADER_ONLY_COMPONENTS}) + add_library(MagnumIntegration::${_component} UNKNOWN IMPORTED) + + # Try to find both debug and release version + find_library(MAGNUMINTEGRATION_${_COMPONENT}_LIBRARY_DEBUG Magnum${_component}Integration-d) + find_library(MAGNUMINTEGRATION_${_COMPONENT}_LIBRARY_RELEASE Magnum${_component}Integration) + mark_as_advanced(MAGNUMINTEGRATION_${_COMPONENT}_LIBRARY_DEBUG + MAGNUMINTEGRATION_${_COMPONENT}_LIBRARY_RELEASE) + + if(MAGNUMINTEGRATION_${_COMPONENT}_LIBRARY_RELEASE) + set_property(TARGET MagnumIntegration::${_component} APPEND PROPERTY + IMPORTED_CONFIGURATIONS RELEASE) + set_property(TARGET MagnumIntegration::${_component} PROPERTY + IMPORTED_LOCATION_RELEASE ${MAGNUMINTEGRATION_${_COMPONENT}_LIBRARY_RELEASE}) + endif() + + if(MAGNUMINTEGRATION_${_COMPONENT}_LIBRARY_DEBUG) + set_property(TARGET MagnumIntegration::${_component} APPEND PROPERTY + IMPORTED_CONFIGURATIONS DEBUG) + set_property(TARGET MagnumIntegration::${_component} PROPERTY + IMPORTED_LOCATION_DEBUG ${MAGNUMINTEGRATION_${_COMPONENT}_LIBRARY_DEBUG}) + endif() + endif() + + # Header-only library components + if(_component MATCHES ${_MAGNUMINTEGRATION_HEADER_ONLY_COMPONENTS}) + add_library(MagnumIntegration::${_component} INTERFACE IMPORTED) + endif() + + # Bullet integration library + if(_component STREQUAL Bullet) + # On Emscripten, Bullet could be taken from ports. If that's the + # case, propagate proper compiler flag. + if(CORRADE_TARGET_EMSCRIPTEN) + find_file(_MAGNUMINTEGRATION_${_COMPONENT}_CONFIGURE_FILE configure.h + HINTS ${MAGNUMINTEGRATION_INCLUDE_DIR}/Magnum/${_component}Integration) + file(READ ${_MAGNUMINTEGRATION_${_COMPONENT}_CONFIGURE_FILE} _magnum${_component}IntegrationConfigure) + string(FIND "${_magnum${_component}IntegrationConfigure}" "#define MAGNUM_USE_EMSCRIPTEN_PORTS_BULLET" _magnum${_component}Integration_USE_EMSCRIPTEN_PORTS_BULLET) + if(NOT _magnum${_component}Integration_USE_EMSCRIPTEN_PORTS_BULLET EQUAL -1) + set(MAGNUM_USE_EMSCRIPTEN_PORTS_BULLET 1) + endif() + endif() + + if(MAGNUM_USE_EMSCRIPTEN_PORTS_BULLET) + if(CMAKE_VERSION VERSION_LESS 3.13) + message(FATAL_ERROR "BulletIntegration was compiled against emscripten-ports version but linking to it requires CMake 3.13 at least") + endif() + set_property(TARGET MagnumIntegration::${_component} APPEND PROPERTY + INTERFACE_COMPILE_OPTIONS "SHELL:-s USE_BULLET=1") + set_property(TARGET MagnumIntegration::${_component} APPEND PROPERTY + INTERFACE_LINK_OPTIONS "SHELL:-s USE_BULLET=1") + else() + find_package(Bullet) + + set_property(TARGET MagnumIntegration::${_component} APPEND PROPERTY + INTERFACE_INCLUDE_DIRECTORIES ${BULLET_INCLUDE_DIRS}) + # Need to handle special cases where both debug and release + # libraries are available (in form of debug;A;optimized;B in + # BULLET_LIBRARIES), thus appending them one by one + foreach(lib BULLET_DYNAMICS_LIBRARY BULLET_COLLISION_LIBRARY BULLET_MATH_LIBRARY BULLET_SOFTBODY_LIBRARY) + if(${lib}_DEBUG) + set_property(TARGET MagnumIntegration::${_component} APPEND PROPERTY + INTERFACE_LINK_LIBRARIES "$<$>:${${lib}}>;$<$:${${lib}_DEBUG}>") + else() + set_property(TARGET MagnumIntegration::${_component} APPEND PROPERTY + INTERFACE_LINK_LIBRARIES ${${lib}}) + endif() + endforeach() + endif() + + set(_MAGNUMINTEGRATION_${_COMPONENT}_INCLUDE_PATH_NAMES MotionState.h) + + # Eigen integration library + elseif(_component STREQUAL Eigen) + find_package(Eigen3) + # We could drop this once we can use at least 3.3.1 (Ubuntu 16.04 + # has only 3.3 beta, which doesn't have this target yet), however + # for Travis and AppVeyor we're using FindEigen3.cmake from the + # downloaded sources (because the Eigen3Config.cmake, which + # produces the actual targets, is not there -- only + # Eigen3Config.cmake.in). See the YML files for an extended rant. + # Also, FindEigen3 only defines EIGEN3_INCLUDE_DIR, not even + # EIGEN3_INCLUDE_DIRS, so be extra careful. + # http://eigen.tuxfamily.org/index.php?title=ChangeLog#Eigen_3.3.1 + set_property(TARGET MagnumIntegration::${_component} APPEND PROPERTY + INTERFACE_INCLUDE_DIRECTORIES ${EIGEN3_INCLUDE_DIR}) + + set(_MAGNUMINTEGRATION_${_COMPONENT}_INCLUDE_PATH_NAMES Integration.h) + + # ImGui integration library + elseif(_component STREQUAL ImGui) + find_package(ImGui) + set_property(TARGET MagnumIntegration::${_component} APPEND PROPERTY + INTERFACE_LINK_LIBRARIES ImGui::ImGui) + + set(_MAGNUMINTEGRATION_${_COMPONENT}_INCLUDE_PATH_NAMES Integration.h) + + # GLM integration library + elseif(_component STREQUAL Glm) + find_package(GLM) + set_property(TARGET MagnumIntegration::${_component} APPEND PROPERTY + INTERFACE_LINK_LIBRARIES GLM::GLM) + + set(_MAGNUMINTEGRATION_${_COMPONENT}_INCLUDE_PATH_NAMES Integration.h) + + # Dart integration library + elseif(_component STREQUAL Dart) + find_package(DART 6.0.0 CONFIG REQUIRED) + set_property(TARGET MagnumIntegration::${_component} APPEND PROPERTY + INTERFACE_LINK_LIBRARIES dart) + + set(_MAGNUMINTEGRATION_${_COMPONENT}_INCLUDE_PATH_NAMES ConvertShapeNode.h) + + # Oculus SDK integration library + elseif(_component STREQUAL Ovr) + find_package(OVR) + set_property(TARGET MagnumIntegration::${_component} APPEND PROPERTY + INTERFACE_LINK_LIBRARIES OVR::OVR) + + set(_MAGNUMINTEGRATION_${_COMPONENT}_INCLUDE_PATH_NAMES OvrIntegration.h) + endif() + + # Find library includes + if(_component MATCHES ${_MAGNUMINTEGRATION_LIBRARY_COMPONENTS}) + find_path(_MAGNUMINTEGRATION_${_COMPONENT}_INCLUDE_DIR + NAMES ${_MAGNUMINTEGRATION_${_COMPONENT}_INCLUDE_PATH_NAMES} + HINTS ${MAGNUMINTEGRATION_INCLUDE_DIR}/Magnum/${_component}Integration) + mark_as_advanced(_MAGNUMINTEGRATION_${_COMPONENT}_INCLUDE_DIR) + endif() + + if(_component MATCHES ${_MAGNUMINTEGRATION_LIBRARY_COMPONENTS}) + # Link to core Magnum library, add other Magnum required and + # optional dependencies + set_property(TARGET MagnumIntegration::${_component} APPEND PROPERTY + INTERFACE_LINK_LIBRARIES Magnum::Magnum) + foreach(_dependency ${_MAGNUMINTEGRATION_${_component}_MAGNUM_DEPENDENCIES}) + set_property(TARGET MagnumIntegration::${_component} APPEND PROPERTY + INTERFACE_LINK_LIBRARIES Magnum::${_dependency}) + endforeach() + foreach(_dependency ${_MAGNUMINTEGRATION_${_component}_MAGNUM_OPTIONAL_DEPENDENCIES}) + if(Magnum_${_dependency}_FOUND) + set_property(TARGET MagnumIntegration::${_component} APPEND PROPERTY + INTERFACE_LINK_LIBRARIES Magnum::${_dependency}) + endif() + endforeach() + + # Add inter-project dependencies + foreach(_dependency ${_MAGNUMINTEGRATION_${_component}_DEPENDENCIES}) + set_property(TARGET MagnumIntegration::${_component} APPEND PROPERTY + INTERFACE_LINK_LIBRARIES MagnumIntegration::${_dependency}) + endforeach() + endif() + + # Decide if the library was found + if(_component MATCHES ${_MAGNUMINTEGRATION_LIBRARY_COMPONENTS} AND _MAGNUMINTEGRATION_${_COMPONENT}_INCLUDE_DIR AND (_component MATCHES ${_MAGNUMINTEGRATION_HEADER_ONLY_COMPONENTS} OR MAGNUMINTEGRATION_${_COMPONENT}_LIBRARY_DEBUG OR MAGNUMINTEGRATION_${_COMPONENT}_LIBRARY_RELEASE)) + set(MagnumIntegration_${_component}_FOUND TRUE) + else() + set(MagnumIntegration_${_component}_FOUND FALSE) + endif() + endif() +endforeach() + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(MagnumIntegration + REQUIRED_VARS MAGNUMINTEGRATION_INCLUDE_DIR + HANDLE_COMPONENTS) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d7146f42..2f2896f4 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -39,11 +39,16 @@ find_package(MagnumPlugins REQUIRED TinyGltfImporter StbImageImporter) +find_package(MagnumIntegration REQUIRED ImGui) find_package(Threads) # Gather paths to OSP headers and sources file (GLOB_RECURSE CPP_FILES *.cpp) file (GLOB_RECURSE H_FILES *.h) +# Append implot source files +list (APPEND CPP_FILES + ../3rdparty/implot/implot.cpp + ../3rdparty/implot/implot_items.cpp) set (SOURCE_FILES ${CPP_FILES} ${H_FILES}) add_executable(osp-magnum ${CPP_FILES}) @@ -93,6 +98,9 @@ endif() # Include ENTT (header only lib) target_include_directories(osp-magnum PRIVATE ../3rdparty/entt/src) +# Include ImPlot (simple library that depends on magnum-integration's imgui) +target_include_directories(osp-magnum PRIVATE ../3rdparty/implot) + # Put executable in the bin folder set_target_properties(osp-magnum PROPERTIES RUNTIME_OUTPUT_DIRECTORY ../bin) @@ -111,6 +119,7 @@ target_link_libraries(osp-magnum PRIVATE Magnum::AnyImageImporter MagnumPlugins::TinyGltfImporter MagnumPlugins::StbImageImporter + MagnumIntegration::ImGui dNewton dScene dModel dVehicle toml11 ) @@ -137,4 +146,4 @@ if(OSP_ENABLE_CLANG_TIDY) endif() # Copy root/bin to build/bin -FILE (COPY "${CMAKE_SOURCE_DIR}/bin/" DESTINATION "${CMAKE_BINARY_DIR}/bin/") \ No newline at end of file +FILE (COPY "${CMAKE_SOURCE_DIR}/bin/" DESTINATION "${CMAKE_BINARY_DIR}/bin/") diff --git a/src/test_application/OSPMagnum.cpp b/src/test_application/OSPMagnum.cpp index c7f0b8b6..7146fb43 100644 --- a/src/test_application/OSPMagnum.cpp +++ b/src/test_application/OSPMagnum.cpp @@ -28,6 +28,7 @@ #include #include +#include #include @@ -45,16 +46,49 @@ OSPMagnum::OSPMagnum(const Magnum::Platform::Application::Arguments& arguments, { //.setWindowFlags(Configuration::WindowFlag::Hidden) + // Initialize ImGui + m_imgui = Magnum::ImGuiIntegration::Context( + Magnum::Vector2{windowSize()} / dpiScaling(), + windowSize(), framebufferSize()); + m_implot = ImPlot::CreateContext(); + m_timeline.start(); } OSPMagnum::~OSPMagnum() { + // Free ImPlot + // ImPlot is not part of Magnum's imgui integration, and is handled manually + ImPlot::DestroyContext(m_implot); + // Clear scene data before GL resources are freed m_scenes.clear(); } +void OSPMagnum::draw_GUI() +{ + using namespace Magnum; + + m_imgui.newFrame(); + + { + ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", + 1000.0 / Double(ImGui::GetIO().Framerate), Double(ImGui::GetIO().Framerate)); + } + + m_imgui.updateApplicationCursor(*this); + GL::Renderer::enable(GL::Renderer::Feature::Blending); + GL::Renderer::enable(GL::Renderer::Feature::ScissorTest); + GL::Renderer::disable(GL::Renderer::Feature::FaceCulling); + GL::Renderer::disable(GL::Renderer::Feature::DepthTest); + m_imgui.drawFrame(); + GL::Renderer::enable(GL::Renderer::Feature::DepthTest); + GL::Renderer::enable(GL::Renderer::Feature::FaceCulling); + GL::Renderer::disable(GL::Renderer::Feature::ScissorTest); + GL::Renderer::disable(GL::Renderer::Feature::Blending); +} + void OSPMagnum::drawEvent() { @@ -101,6 +135,7 @@ void OSPMagnum::drawEvent() // TODO: GUI and stuff + draw_GUI(); swapBuffers(); m_timeline.nextFrame(); @@ -112,6 +147,7 @@ void OSPMagnum::drawEvent() void OSPMagnum::keyPressEvent(KeyEvent& event) { if (event.isRepeated()) { return; } + if (m_imgui.handleKeyPressEvent(event)) { return; } m_userInput.event_raw(osp::sc_keyboard, (int) event.key(), osp::UserInputHandler::ButtonRawEvent::PRESSED); } @@ -119,29 +155,34 @@ void OSPMagnum::keyPressEvent(KeyEvent& event) void OSPMagnum::keyReleaseEvent(KeyEvent& event) { if (event.isRepeated()) { return; } + if (m_imgui.handleKeyReleaseEvent(event)) { return; } m_userInput.event_raw(osp::sc_keyboard, (int) event.key(), osp::UserInputHandler::ButtonRawEvent::RELEASED); } void OSPMagnum::mousePressEvent(MouseEvent& event) { + if (m_imgui.handleMousePressEvent(event)) { return; } m_userInput.event_raw(osp::sc_mouse, (int) event.button(), osp::UserInputHandler::ButtonRawEvent::PRESSED); } void OSPMagnum::mouseReleaseEvent(MouseEvent& event) { + if (m_imgui.handleMouseReleaseEvent(event)) { return; } m_userInput.event_raw(osp::sc_mouse, (int) event.button(), osp::UserInputHandler::ButtonRawEvent::RELEASED); } void OSPMagnum::mouseMoveEvent(MouseMoveEvent& event) { + if (m_imgui.handleMouseMoveEvent(event)) { return; } m_userInput.mouse_delta(event.relativePosition()); } void OSPMagnum::mouseScrollEvent(MouseScrollEvent & event) { + if (m_imgui.handleMouseMoveEvent(event)) { return; } m_userInput.scroll_delta(static_cast(event.offset())); } diff --git a/src/test_application/OSPMagnum.h b/src/test_application/OSPMagnum.h index 60bd66f8..afeb4350 100644 --- a/src/test_application/OSPMagnum.h +++ b/src/test_application/OSPMagnum.h @@ -39,6 +39,8 @@ #include #include #include +#include +#include #include @@ -75,6 +77,10 @@ class OSPMagnum : public Magnum::Platform::Application constexpr MapActiveScene_t& get_scenes() { return m_scenes; } private: + Magnum::ImGuiIntegration::Context m_imgui{Magnum::NoCreate}; + ImPlotContext* m_implot; + + void draw_GUI(); void drawEvent() override; From a87c0286605087237868e6f6fea924e006bb0851 Mon Sep 17 00:00:00 2001 From: "Z.A" Date: Mon, 22 Feb 2021 00:18:26 -0800 Subject: [PATCH 02/12] basic flight info --- src/osp/Active/ActiveScene.cpp | 8 ++++ src/osp/Active/ActiveScene.h | 9 +++++ src/osp/Active/SysMachine.h | 1 + src/test_application/OSPMagnum.cpp | 20 +++++----- src/test_application/flight.cpp | 63 ++++++++++++++++++++++++++++++ 5 files changed, 90 insertions(+), 11 deletions(-) diff --git a/src/osp/Active/ActiveScene.cpp b/src/osp/Active/ActiveScene.cpp index 5d73227a..5aa49318 100644 --- a/src/osp/Active/ActiveScene.cpp +++ b/src/osp/Active/ActiveScene.cpp @@ -239,6 +239,14 @@ void ActiveScene::draw(ActiveEnt camera) m_renderOrder.call(cameraComp); } +void ActiveScene::drawUI() +{ + for (auto& describeElement : m_GUIelements) + { + describeElement(*this); + } +} + MapSysMachine_t::iterator ActiveScene::system_machine_add(std::string_view name, std::unique_ptr sysMachine) { diff --git a/src/osp/Active/ActiveScene.h b/src/osp/Active/ActiveScene.h index 1729bf63..5d0e5ce0 100644 --- a/src/osp/Active/ActiveScene.h +++ b/src/osp/Active/ActiveScene.h @@ -26,6 +26,7 @@ #include #include +#include #include #include "../OSPApplication.h" @@ -168,6 +169,11 @@ class ActiveScene */ void draw(ActiveEnt camera); + /** + * Draw GUI elements + */ + void drawUI(); + constexpr UserInputHandler& get_user_input() { return m_userInput; } constexpr UpdateOrder_t& get_update_order() { return m_updateOrder; } @@ -233,6 +239,8 @@ class ActiveScene bool dynamic_system_it_valid(MapDynamicSys_t::iterator it); Package& get_context_resources() { return m_context; } + + std::vector>& get_GUI_elements() { return m_GUIelements; } private: void on_hierarchy_construct(ActiveReg_t& reg, ActiveEnt ent); @@ -258,6 +266,7 @@ class ActiveScene MapSysMachine_t m_sysMachines; // TODO: Put this in SysVehicle MapDynamicSys_t m_dynamicSys; + std::vector> m_GUIelements; // TODO: base class and a list for Systems (or not) //SysDebugRender m_render; //SysPhysics m_physics; diff --git a/src/osp/Active/SysMachine.h b/src/osp/Active/SysMachine.h index ec0f4b19..c9a7091e 100644 --- a/src/osp/Active/SysMachine.h +++ b/src/osp/Active/SysMachine.h @@ -92,6 +92,7 @@ class Machine : public IWireElement constexpr void enable(void) noexcept; constexpr void disable(void) noexcept; + constexpr bool is_enabled() const noexcept { return m_enable; } protected: bool m_enable = false; diff --git a/src/test_application/OSPMagnum.cpp b/src/test_application/OSPMagnum.cpp index 7146fb43..a4772c11 100644 --- a/src/test_application/OSPMagnum.cpp +++ b/src/test_application/OSPMagnum.cpp @@ -70,13 +70,6 @@ void OSPMagnum::draw_GUI() { using namespace Magnum; - m_imgui.newFrame(); - - { - ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", - 1000.0 / Double(ImGui::GetIO().Framerate), Double(ImGui::GetIO().Framerate)); - } - m_imgui.updateApplicationCursor(*this); GL::Renderer::enable(GL::Renderer::Feature::Blending); GL::Renderer::enable(GL::Renderer::Feature::ScissorTest); @@ -91,9 +84,13 @@ void OSPMagnum::draw_GUI() void OSPMagnum::drawEvent() { + using Magnum::GL::FramebufferClear; - Magnum::GL::defaultFramebuffer.clear(Magnum::GL::FramebufferClear::Color - | Magnum::GL::FramebufferClear::Depth); + // Clear framebuffer + Magnum::GL::defaultFramebuffer.clear(FramebufferClear::Color | FramebufferClear::Depth); + + // Initialize new GUI frame + m_imgui.newFrame(); // if (m_area) // { @@ -128,11 +125,12 @@ void OSPMagnum::drawEvent() { scene.update_hierarchy_transforms(); - // temporary: draw using first camera component found scene.draw(scene.get_registry().view().front()); - } + // Draw GUI + scene.drawUI(); + } // TODO: GUI and stuff draw_GUI(); diff --git a/src/test_application/flight.cpp b/src/test_application/flight.cpp index 18c6510a..edb6852a 100644 --- a/src/test_application/flight.cpp +++ b/src/test_application/flight.cpp @@ -43,6 +43,8 @@ #include #include +#include + using namespace testapp; using osp::Vector2; @@ -149,6 +151,67 @@ void testapp::test_flight(std::unique_ptr& pMagnumApp, // Add a ACompDebugObject to camera to manage camObj's lifetime scene.reg_emplace(camera, std::move(camObj)); + // Create GUI definitions + + // Debug FPS + scene.get_GUI_elements().push_back( + [](osp::active::ActiveScene& rScene) + { + using namespace Magnum; + + ImGui::Begin("Debug"); + ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", + 1000.0 / Double(ImGui::GetIO().Framerate), Double(ImGui::GetIO().Framerate)); + ImGui::End(); + }); + + // Show active MUC velocity + scene.get_GUI_elements().push_back( + [](osp::active::ActiveScene& rScene) + { + using adera::active::machines::MachineUserControl; + using namespace osp::active; + + ActiveEnt activeShip{entt::null}; + for (auto [ent, muc] : rScene.get_registry().view().each()) + { + if (muc.is_enabled()) + { + activeShip = ent; + break; + } + } + + if (activeShip == entt::null) + { + ImGui::Begin("Ship Status"); + ImGui::Text("Ship: null"); + ImGui::Text("Velocity: null"); + ImGui::Text("Position: null"); + ImGui::Text("Orientation: null"); + ImGui::End(); + return; + } + + ACompRigidbodyAncestor* rba = + SysPhysics_t::try_get_or_find_rigidbody_ancestor(rScene, activeShip); + ActiveEnt rigidbody = rba->m_ancestor; + auto const& rb = rScene.reg_get(rigidbody); + auto const& tf = rScene.reg_get(rigidbody); + + Vector3 velocity = rb.m_velocity; + Vector3 position = tf.m_transformWorld.translation(); + Vector3 orientation = tf.m_transformWorld.rotation() * Vector3{0.0f, -1.0f, 0.0f}; + + ImGui::Begin("Ship Status"); + ImGui::Text("Ship: %d", static_cast(activeShip)); + ImGui::Text("Velocity: (%f, %f, %f)", velocity.x(), velocity.y(), velocity.z()); + ImGui::Text("Position: (%f, %f, %f)", position.x(), position.y(), position.z()); + ImGui::Text("Orientation: (%f, %f, %f)", + orientation.x(), orientation.y(), orientation.z()); + ImGui::End(); + }); + // Starts the game loop. This function is blocking, and will only return // when the window is closed. See OSPMagnum::drawEvent pMagnumApp->exec(); From 70fe7ec0f9840a827c0c2e41c28d910d26c4b020 Mon Sep 17 00:00:00 2001 From: "Z.A" Date: Tue, 23 Feb 2021 23:21:45 -0800 Subject: [PATCH 03/12] tmp stash old sysgui --- src/osp/Active/SysGUI.cpp | 41 +++++++++++++++++++++++++++++ src/osp/Active/SysGUI.h | 55 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 96 insertions(+) create mode 100644 src/osp/Active/SysGUI.cpp create mode 100644 src/osp/Active/SysGUI.h diff --git a/src/osp/Active/SysGUI.cpp b/src/osp/Active/SysGUI.cpp new file mode 100644 index 00000000..614d8654 --- /dev/null +++ b/src/osp/Active/SysGUI.cpp @@ -0,0 +1,41 @@ +/** + * Open Space Program + * Copyright © 2019-2020 Open Space Program Project + * + * MIT License + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#if 0 +#include "SysGUI.h" + +using namespace osp::active; + +SysGUI::SysGUI(ActiveScene& rScene) +{} + +SysGUI::~SysGUI() +{} + +void SysGUI::update_GUI(ActiveScene& rScene) +{} + +void SysGUI::draw_GUI(ActiveScene& rScene, ACompCamera const&) +{} +#endif diff --git a/src/osp/Active/SysGUI.h b/src/osp/Active/SysGUI.h new file mode 100644 index 00000000..2beb4dbf --- /dev/null +++ b/src/osp/Active/SysGUI.h @@ -0,0 +1,55 @@ +/** + * Open Space Program + * Copyright © 2019-2020 Open Space Program Project + * + * MIT License + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#if 0 +#include + +#include "osp/Active/activetypes.h" +#include + +namespace osp::active +{ + +struct CompGUIWindow +{ + std::function m_function; +}; + +class SysGUI : public IDynamicSystem +{ +public: + static inline std::string smc_name = "GUI"; + + SysGUI(ActiveScene& rScene); + ~SysGUI(); + + static void update_GUI(ActiveScene& rScene); + +private: + UpdateOrderHandle_t m_updateGUI; + RenderOrderHandle_t m_drawGUI; +}; + +} // osp::active +#endif From 4fde368077166db81c8f38d67664128841e0e7f5 Mon Sep 17 00:00:00 2001 From: "Z.A" Date: Fri, 5 Mar 2021 00:06:42 -0800 Subject: [PATCH 04/12] Slightly less abominable GUI system --- src/osp/Active/ActiveScene.cpp | 8 -------- src/osp/Active/ActiveScene.h | 7 ------- src/osp/Active/SysGUI.cpp | 19 ++++++++++--------- src/osp/Active/SysGUI.h | 10 ++++------ src/osp/Active/SysNewton.cpp | 1 + src/test_application/OSPMagnum.cpp | 3 --- src/test_application/OSPMagnum.h | 2 +- src/test_application/flight.cpp | 8 ++++++-- 8 files changed, 22 insertions(+), 36 deletions(-) diff --git a/src/osp/Active/ActiveScene.cpp b/src/osp/Active/ActiveScene.cpp index 5aa49318..5d73227a 100644 --- a/src/osp/Active/ActiveScene.cpp +++ b/src/osp/Active/ActiveScene.cpp @@ -239,14 +239,6 @@ void ActiveScene::draw(ActiveEnt camera) m_renderOrder.call(cameraComp); } -void ActiveScene::drawUI() -{ - for (auto& describeElement : m_GUIelements) - { - describeElement(*this); - } -} - MapSysMachine_t::iterator ActiveScene::system_machine_add(std::string_view name, std::unique_ptr sysMachine) { diff --git a/src/osp/Active/ActiveScene.h b/src/osp/Active/ActiveScene.h index 5d0e5ce0..a207fbf9 100644 --- a/src/osp/Active/ActiveScene.h +++ b/src/osp/Active/ActiveScene.h @@ -169,11 +169,6 @@ class ActiveScene */ void draw(ActiveEnt camera); - /** - * Draw GUI elements - */ - void drawUI(); - constexpr UserInputHandler& get_user_input() { return m_userInput; } constexpr UpdateOrder_t& get_update_order() { return m_updateOrder; } @@ -240,7 +235,6 @@ class ActiveScene Package& get_context_resources() { return m_context; } - std::vector>& get_GUI_elements() { return m_GUIelements; } private: void on_hierarchy_construct(ActiveReg_t& reg, ActiveEnt ent); @@ -266,7 +260,6 @@ class ActiveScene MapSysMachine_t m_sysMachines; // TODO: Put this in SysVehicle MapDynamicSys_t m_dynamicSys; - std::vector> m_GUIelements; // TODO: base class and a list for Systems (or not) //SysDebugRender m_render; //SysPhysics m_physics; diff --git a/src/osp/Active/SysGUI.cpp b/src/osp/Active/SysGUI.cpp index 614d8654..c547dffc 100644 --- a/src/osp/Active/SysGUI.cpp +++ b/src/osp/Active/SysGUI.cpp @@ -22,20 +22,21 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -#if 0 #include "SysGUI.h" +#include using namespace osp::active; SysGUI::SysGUI(ActiveScene& rScene) -{} - -SysGUI::~SysGUI() -{} - -void SysGUI::update_GUI(ActiveScene& rScene) + : m_drawGUI(rScene.get_render_order(), "gui", "debug", "", + [&rScene](ACompCamera const& camera) { draw_GUI(rScene, camera); }) {} void SysGUI::draw_GUI(ActiveScene& rScene, ACompCamera const&) -{} -#endif +{ + for (auto [ent, describeElement] + : rScene.get_registry().view().each()) + { + describeElement.m_function(rScene); + } +} \ No newline at end of file diff --git a/src/osp/Active/SysGUI.h b/src/osp/Active/SysGUI.h index 2beb4dbf..35f6e88d 100644 --- a/src/osp/Active/SysGUI.h +++ b/src/osp/Active/SysGUI.h @@ -22,7 +22,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -#if 0 + #include #include "osp/Active/activetypes.h" @@ -31,7 +31,7 @@ namespace osp::active { -struct CompGUIWindow +struct ACompGUIWindow { std::function m_function; }; @@ -42,14 +42,12 @@ class SysGUI : public IDynamicSystem static inline std::string smc_name = "GUI"; SysGUI(ActiveScene& rScene); - ~SysGUI(); + ~SysGUI() = default; - static void update_GUI(ActiveScene& rScene); + static void draw_GUI(ActiveScene& rScene, ACompCamera const&); private: - UpdateOrderHandle_t m_updateGUI; RenderOrderHandle_t m_drawGUI; }; } // osp::active -#endif diff --git a/src/osp/Active/SysNewton.cpp b/src/osp/Active/SysNewton.cpp index 6ef9fc31..991d6baa 100644 --- a/src/osp/Active/SysNewton.cpp +++ b/src/osp/Active/SysNewton.cpp @@ -192,6 +192,7 @@ void SysNewton::update_world(ActiveScene& rScene) // Get new transform matrix from newton NewtonBodyGetMatrix(entBody.m_body, entTransform.m_transform.data()); + NewtonBodyGetVelocity(entBody.m_body, entBody.m_velocity.data()); } } } diff --git a/src/test_application/OSPMagnum.cpp b/src/test_application/OSPMagnum.cpp index a4772c11..42381ca0 100644 --- a/src/test_application/OSPMagnum.cpp +++ b/src/test_application/OSPMagnum.cpp @@ -127,9 +127,6 @@ void OSPMagnum::drawEvent() // temporary: draw using first camera component found scene.draw(scene.get_registry().view().front()); - - // Draw GUI - scene.drawUI(); } // TODO: GUI and stuff diff --git a/src/test_application/OSPMagnum.h b/src/test_application/OSPMagnum.h index afeb4350..9623185f 100644 --- a/src/test_application/OSPMagnum.h +++ b/src/test_application/OSPMagnum.h @@ -37,7 +37,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/test_application/flight.cpp b/src/test_application/flight.cpp index edb6852a..b05c2b2f 100644 --- a/src/test_application/flight.cpp +++ b/src/test_application/flight.cpp @@ -32,6 +32,7 @@ #include #include #include +#include #include @@ -98,6 +99,7 @@ void testapp::test_flight(std::unique_ptr& pMagnumApp, scene.dynamic_system_create(); scene.dynamic_system_create(); scene.dynamic_system_create(); + scene.dynamic_system_create(); scene.dynamic_system_create(); scene.dynamic_system_create(); scene.dynamic_system_create(); @@ -154,7 +156,8 @@ void testapp::test_flight(std::unique_ptr& pMagnumApp, // Create GUI definitions // Debug FPS - scene.get_GUI_elements().push_back( + ActiveEnt fpsWindow = scene.get_registry().create(); + scene.reg_emplace(fpsWindow, [](osp::active::ActiveScene& rScene) { using namespace Magnum; @@ -166,7 +169,8 @@ void testapp::test_flight(std::unique_ptr& pMagnumApp, }); // Show active MUC velocity - scene.get_GUI_elements().push_back( + ActiveEnt shipStatus = scene.get_registry().create(); + scene.reg_emplace(shipStatus, [](osp::active::ActiveScene& rScene) { using adera::active::machines::MachineUserControl; From 525b56857bc26323f911fd72959e8ecf45552cb0 Mon Sep 17 00:00:00 2001 From: "Z.A" Date: Fri, 5 Mar 2021 00:07:20 -0800 Subject: [PATCH 05/12] fix erronious OSPMagnum commit --- src/test_application/OSPMagnum.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test_application/OSPMagnum.h b/src/test_application/OSPMagnum.h index 9623185f..afeb4350 100644 --- a/src/test_application/OSPMagnum.h +++ b/src/test_application/OSPMagnum.h @@ -37,7 +37,7 @@ #include #include #include -#include +#include #include #include #include From ac90694823f82d7563a4289610f7391661251bca Mon Sep 17 00:00:00 2001 From: "Z.A" Date: Fri, 5 Mar 2021 20:32:33 -0800 Subject: [PATCH 06/12] pre-pr fixes --- src/osp/Active/ActiveScene.h | 2 -- src/osp/Active/SysGUI.cpp | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/osp/Active/ActiveScene.h b/src/osp/Active/ActiveScene.h index a207fbf9..1729bf63 100644 --- a/src/osp/Active/ActiveScene.h +++ b/src/osp/Active/ActiveScene.h @@ -26,7 +26,6 @@ #include #include -#include #include #include "../OSPApplication.h" @@ -234,7 +233,6 @@ class ActiveScene bool dynamic_system_it_valid(MapDynamicSys_t::iterator it); Package& get_context_resources() { return m_context; } - private: void on_hierarchy_construct(ActiveReg_t& reg, ActiveEnt ent); diff --git a/src/osp/Active/SysGUI.cpp b/src/osp/Active/SysGUI.cpp index c547dffc..a9ee7351 100644 --- a/src/osp/Active/SysGUI.cpp +++ b/src/osp/Active/SysGUI.cpp @@ -39,4 +39,4 @@ void SysGUI::draw_GUI(ActiveScene& rScene, ACompCamera const&) { describeElement.m_function(rScene); } -} \ No newline at end of file +} From 163a1541c51715de737461271963c52ab91b47e2 Mon Sep 17 00:00:00 2001 From: "Z.A" Date: Fri, 5 Mar 2021 20:47:19 -0800 Subject: [PATCH 07/12] hopefully fix include --- src/osp/Active/SysGUI.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/osp/Active/SysGUI.cpp b/src/osp/Active/SysGUI.cpp index a9ee7351..ce0a567f 100644 --- a/src/osp/Active/SysGUI.cpp +++ b/src/osp/Active/SysGUI.cpp @@ -23,7 +23,7 @@ * SOFTWARE. */ #include "SysGUI.h" -#include +#include "ActiveScene.h" using namespace osp::active; From 93d18dec03302fac9365dbf8121449abf50b635d Mon Sep 17 00:00:00 2001 From: "Z.A" Date: Sun, 7 Mar 2021 23:27:44 -0800 Subject: [PATCH 08/12] ImPlot fps example --- src/test_application/flight.cpp | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/src/test_application/flight.cpp b/src/test_application/flight.cpp index b05c2b2f..17c9ea36 100644 --- a/src/test_application/flight.cpp +++ b/src/test_application/flight.cpp @@ -46,6 +46,8 @@ #include +#include + using namespace testapp; using osp::Vector2; @@ -156,22 +158,41 @@ void testapp::test_flight(std::unique_ptr& pMagnumApp, // Create GUI definitions // Debug FPS + std::array times; + for (int i = 0; i < 120; i++) + { + times[i] = static_cast(i); + } ActiveEnt fpsWindow = scene.get_registry().create(); scene.reg_emplace(fpsWindow, - [](osp::active::ActiveScene& rScene) + [data = std::array{0.0f}, index = 0, ×](osp::active::ActiveScene& rScene) mutable { using namespace Magnum; ImGui::Begin("Debug"); + + double framerate = ImGui::GetIO().Framerate; ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", - 1000.0 / Double(ImGui::GetIO().Framerate), Double(ImGui::GetIO().Framerate)); + 1000.0 / Double(ImGui::GetIO().Framerate), Double(framerate)); + + data[index] = framerate; + index++; + if (index >= 120) { index = 0; } + + if (ImPlot::BeginPlot("Framerate", "t", "fps", {-1, -1})) + { + //ImPlot::SetNextMarkerStyle(ImPlotMarker_Circle); + //int offset = index; + ImPlot::PlotLine("Framerate", times.data(), data.data(), data.size(), 0); + ImPlot::EndPlot(); + } ImGui::End(); }); // Show active MUC velocity ActiveEnt shipStatus = scene.get_registry().create(); scene.reg_emplace(shipStatus, - [](osp::active::ActiveScene& rScene) + [] (osp::active::ActiveScene& rScene) { using adera::active::machines::MachineUserControl; using namespace osp::active; From 081c718e4cf3acaf8df85af903ac1d114c1da1ae Mon Sep 17 00:00:00 2001 From: "Z.A" Date: Sat, 20 Mar 2021 14:32:40 -0700 Subject: [PATCH 09/12] Quick custom deleter --- src/test_application/OSPMagnum.cpp | 14 +++++++------- src/test_application/OSPMagnum.h | 4 +++- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/test_application/OSPMagnum.cpp b/src/test_application/OSPMagnum.cpp index 42381ca0..9f8861f4 100644 --- a/src/test_application/OSPMagnum.cpp +++ b/src/test_application/OSPMagnum.cpp @@ -37,12 +37,13 @@ using namespace testapp; OSPMagnum::OSPMagnum(const Magnum::Platform::Application::Arguments& arguments, - osp::OSPApplication &rOspApp) : - Magnum::Platform::Application{ + osp::OSPApplication &rOspApp) + : Magnum::Platform::Application{ arguments, - Configuration{}.setTitle("OSP-Magnum").setSize({1280, 720})}, - m_userInput(12), - m_ospApp(rOspApp) + Configuration{}.setTitle("OSP-Magnum").setSize({1280, 720})} + , m_userInput(12) + , m_ospApp(rOspApp) + , m_implot(ImPlot::CreateContext(), &destroy_implot) { //.setWindowFlags(Configuration::WindowFlag::Hidden) @@ -50,7 +51,6 @@ OSPMagnum::OSPMagnum(const Magnum::Platform::Application::Arguments& arguments, m_imgui = Magnum::ImGuiIntegration::Context( Magnum::Vector2{windowSize()} / dpiScaling(), windowSize(), framebufferSize()); - m_implot = ImPlot::CreateContext(); m_timeline.start(); @@ -60,7 +60,7 @@ OSPMagnum::~OSPMagnum() { // Free ImPlot // ImPlot is not part of Magnum's imgui integration, and is handled manually - ImPlot::DestroyContext(m_implot); + //ImPlot::DestroyContext(m_implot); // Clear scene data before GL resources are freed m_scenes.clear(); diff --git a/src/test_application/OSPMagnum.h b/src/test_application/OSPMagnum.h index afeb4350..655c18c7 100644 --- a/src/test_application/OSPMagnum.h +++ b/src/test_application/OSPMagnum.h @@ -78,7 +78,9 @@ class OSPMagnum : public Magnum::Platform::Application private: Magnum::ImGuiIntegration::Context m_imgui{Magnum::NoCreate}; - ImPlotContext* m_implot; + + static void destroy_implot(ImPlotContext* ctx) { ImPlot::DestroyContext(ctx); } + std::unique_ptr m_implot; void draw_GUI(); From e8d36f69fdb781d40f3146881ca3b86f0f8b2ab3 Mon Sep 17 00:00:00 2001 From: "Z.A" Date: Sat, 20 Mar 2021 21:30:18 -0700 Subject: [PATCH 10/12] decoupling from OSPMagnum (a bit) --- src/osp/Active/ActiveScene.cpp | 6 ++++++ src/osp/Active/ActiveScene.h | 5 ++++- src/osp/Active/SysGUI.cpp | 13 ++++++++++++- src/osp/Active/SysGUI.h | 23 ++++++++++++++++++++++- src/test_application/OSPMagnum.cpp | 26 +++++++++----------------- src/test_application/OSPMagnum.h | 5 +---- src/test_application/flight.cpp | 28 +++++++++++++++++++++++----- 7 files changed, 77 insertions(+), 29 deletions(-) diff --git a/src/osp/Active/ActiveScene.cpp b/src/osp/Active/ActiveScene.cpp index 5d73227a..36355d56 100644 --- a/src/osp/Active/ActiveScene.cpp +++ b/src/osp/Active/ActiveScene.cpp @@ -239,6 +239,12 @@ void ActiveScene::draw(ActiveEnt camera) m_renderOrder.call(cameraComp); } +ACompImGuiContext* ActiveScene::find_GUI_context() +{ + ActiveEnt sceneRoot = hier_get_root(); + return m_registry.try_get(sceneRoot); +} + MapSysMachine_t::iterator ActiveScene::system_machine_add(std::string_view name, std::unique_ptr sysMachine) { diff --git a/src/osp/Active/ActiveScene.h b/src/osp/Active/ActiveScene.h index 1729bf63..1c3b0454 100644 --- a/src/osp/Active/ActiveScene.h +++ b/src/osp/Active/ActiveScene.h @@ -30,6 +30,7 @@ #include "../OSPApplication.h" #include "../UserInputHandler.h" +#include #include "../types.h" #include "activetypes.h" @@ -40,11 +41,11 @@ #include "SysMachine.h" //#include "SysVehicle.h" #include "SysWire.h" +#include "SysGUI.h" #include "adera/SysExhaustPlume.h" namespace osp::active { - /** * An ECS 3D Game Engine scene that implements a scene graph hierarchy. * @@ -174,6 +175,8 @@ class ActiveScene constexpr RenderOrder_t& get_render_order() { return m_renderOrder; } + ACompImGuiContext* find_GUI_context(); + // TODO constexpr float get_time_delta_fixed() const { return 1.0f / 60.0f; } diff --git a/src/osp/Active/SysGUI.cpp b/src/osp/Active/SysGUI.cpp index ce0a567f..ceebd1bc 100644 --- a/src/osp/Active/SysGUI.cpp +++ b/src/osp/Active/SysGUI.cpp @@ -34,9 +34,20 @@ SysGUI::SysGUI(ActiveScene& rScene) void SysGUI::draw_GUI(ActiveScene& rScene, ACompCamera const&) { + ActiveEnt sceneRoot = rScene.hier_get_root(); + ACompImGuiContext* imgui = rScene.reg_try_get(sceneRoot); + if (imgui == nullptr) { return; } + ImGui::SetCurrentContext(imgui->m_imgui.context()); + + ACompImPlotContext* implot = rScene.reg_try_get(sceneRoot); + if (implot != nullptr) + { + ImPlot::SetCurrentContext(implot->m_implot.get()); + } + for (auto [ent, describeElement] : rScene.get_registry().view().each()) { - describeElement.m_function(rScene); + describeElement.m_function(rScene, describeElement.m_visible); } } diff --git a/src/osp/Active/SysGUI.h b/src/osp/Active/SysGUI.h index 35f6e88d..9ccf5b47 100644 --- a/src/osp/Active/SysGUI.h +++ b/src/osp/Active/SysGUI.h @@ -22,18 +22,39 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ +#pragma once #include #include "osp/Active/activetypes.h" #include +#include namespace osp::active { +// TMP +struct ACompImGuiContext +{ + Magnum::ImGuiIntegration::Context m_imgui; +}; + +using ImPlotContext_t = std::unique_ptr>; + +struct ACompImPlotContext +{ + ImPlotContext_t m_implot; + + static void free_ctx(ImPlotContext* ctx) + { + ImPlot::DestroyContext(ctx); + } +}; + struct ACompGUIWindow { - std::function m_function; + std::function m_function; + bool m_visible; }; class SysGUI : public IDynamicSystem diff --git a/src/test_application/OSPMagnum.cpp b/src/test_application/OSPMagnum.cpp index 9f8861f4..40a84d29 100644 --- a/src/test_application/OSPMagnum.cpp +++ b/src/test_application/OSPMagnum.cpp @@ -43,15 +43,9 @@ OSPMagnum::OSPMagnum(const Magnum::Platform::Application::Arguments& arguments, Configuration{}.setTitle("OSP-Magnum").setSize({1280, 720})} , m_userInput(12) , m_ospApp(rOspApp) - , m_implot(ImPlot::CreateContext(), &destroy_implot) { //.setWindowFlags(Configuration::WindowFlag::Hidden) - // Initialize ImGui - m_imgui = Magnum::ImGuiIntegration::Context( - Magnum::Vector2{windowSize()} / dpiScaling(), - windowSize(), framebufferSize()); - m_timeline.start(); } @@ -70,12 +64,12 @@ void OSPMagnum::draw_GUI() { using namespace Magnum; - m_imgui.updateApplicationCursor(*this); + m_activeImgui->updateApplicationCursor(*this); GL::Renderer::enable(GL::Renderer::Feature::Blending); GL::Renderer::enable(GL::Renderer::Feature::ScissorTest); GL::Renderer::disable(GL::Renderer::Feature::FaceCulling); GL::Renderer::disable(GL::Renderer::Feature::DepthTest); - m_imgui.drawFrame(); + m_activeImgui->drawFrame(); GL::Renderer::enable(GL::Renderer::Feature::DepthTest); GL::Renderer::enable(GL::Renderer::Feature::FaceCulling); GL::Renderer::disable(GL::Renderer::Feature::ScissorTest); @@ -90,7 +84,7 @@ void OSPMagnum::drawEvent() Magnum::GL::defaultFramebuffer.clear(FramebufferClear::Color | FramebufferClear::Depth); // Initialize new GUI frame - m_imgui.newFrame(); + m_activeImgui->newFrame(); // if (m_area) // { @@ -137,12 +131,10 @@ void OSPMagnum::drawEvent() redraw(); } - - void OSPMagnum::keyPressEvent(KeyEvent& event) { if (event.isRepeated()) { return; } - if (m_imgui.handleKeyPressEvent(event)) { return; } + if (m_activeImgui != nullptr && m_activeImgui->handleKeyPressEvent(event)) { return; } m_userInput.event_raw(osp::sc_keyboard, (int) event.key(), osp::UserInputHandler::ButtonRawEvent::PRESSED); } @@ -150,34 +142,34 @@ void OSPMagnum::keyPressEvent(KeyEvent& event) void OSPMagnum::keyReleaseEvent(KeyEvent& event) { if (event.isRepeated()) { return; } - if (m_imgui.handleKeyReleaseEvent(event)) { return; } + if (m_activeImgui != nullptr && m_activeImgui->handleKeyReleaseEvent(event)) { return; } m_userInput.event_raw(osp::sc_keyboard, (int) event.key(), osp::UserInputHandler::ButtonRawEvent::RELEASED); } void OSPMagnum::mousePressEvent(MouseEvent& event) { - if (m_imgui.handleMousePressEvent(event)) { return; } + if (m_activeImgui != nullptr && m_activeImgui->handleMousePressEvent(event)) { return; } m_userInput.event_raw(osp::sc_mouse, (int) event.button(), osp::UserInputHandler::ButtonRawEvent::PRESSED); } void OSPMagnum::mouseReleaseEvent(MouseEvent& event) { - if (m_imgui.handleMouseReleaseEvent(event)) { return; } + if (m_activeImgui != nullptr && m_activeImgui->handleMouseReleaseEvent(event)) { return; } m_userInput.event_raw(osp::sc_mouse, (int) event.button(), osp::UserInputHandler::ButtonRawEvent::RELEASED); } void OSPMagnum::mouseMoveEvent(MouseMoveEvent& event) { - if (m_imgui.handleMouseMoveEvent(event)) { return; } + if (m_activeImgui != nullptr && m_activeImgui->handleMouseMoveEvent(event)) { return; } m_userInput.mouse_delta(event.relativePosition()); } void OSPMagnum::mouseScrollEvent(MouseScrollEvent & event) { - if (m_imgui.handleMouseMoveEvent(event)) { return; } + if (m_activeImgui != nullptr && m_activeImgui->handleMouseMoveEvent(event)) { return; } m_userInput.scroll_delta(static_cast(event.offset())); } diff --git a/src/test_application/OSPMagnum.h b/src/test_application/OSPMagnum.h index 655c18c7..c2808fa1 100644 --- a/src/test_application/OSPMagnum.h +++ b/src/test_application/OSPMagnum.h @@ -76,11 +76,8 @@ class OSPMagnum : public Magnum::Platform::Application constexpr osp::UserInputHandler& get_input_handler() { return m_userInput; } constexpr MapActiveScene_t& get_scenes() { return m_scenes; } + Magnum::ImGuiIntegration::Context* m_activeImgui; private: - Magnum::ImGuiIntegration::Context m_imgui{Magnum::NoCreate}; - - static void destroy_implot(ImPlotContext* ctx) { ImPlot::DestroyContext(ctx); } - std::unique_ptr m_implot; void draw_GUI(); diff --git a/src/test_application/flight.cpp b/src/test_application/flight.cpp index 17c9ea36..efb2d994 100644 --- a/src/test_application/flight.cpp +++ b/src/test_application/flight.cpp @@ -127,16 +127,33 @@ void testapp::test_flight(std::unique_ptr& pMagnumApp, // Link ActiveArea to scene using the AreaAssociate osp::active::SysAreaAssociate::connect(scene, rUni, areaSat); + ActiveEnt sceneRoot = scene.hier_get_root(); + auto& reg = scene.get_registry(); + // Add default-constructed physics world to scene - scene.get_registry().emplace(scene.hier_get_root()); + reg.emplace(sceneRoot); + + // Add GUI contexts to scene + { + auto imguiCtx = Magnum::ImGuiIntegration::Context( + Magnum::Vector2{pMagnumApp->windowSize()} / pMagnumApp->dpiScaling(), + pMagnumApp->windowSize(), pMagnumApp->framebufferSize()); + auto& imgui = reg.emplace(sceneRoot, std::move(imguiCtx)); + + pMagnumApp->m_activeImgui = &imgui.m_imgui; + + osp::active::ImPlotContext_t implotCtx = osp::active::ImPlotContext_t( + ImPlot::CreateContext(), osp::active::ACompImPlotContext::free_ctx); + reg.emplace(sceneRoot, std::move(implotCtx)); + } // Add a camera to the scene // Create the camera entity - ActiveEnt camera = scene.hier_create_child(scene.hier_get_root(), + ActiveEnt camera = scene.hier_create_child(sceneRoot, "Camera"); auto &cameraTransform = scene.reg_emplace(camera); - auto &cameraComp = scene.get_registry().emplace(camera); + auto &cameraComp = reg.emplace(camera); cameraTransform.m_transform = Matrix4::translation(Vector3(0, 0, 25)); scene.reg_emplace(camera); @@ -165,7 +182,8 @@ void testapp::test_flight(std::unique_ptr& pMagnumApp, } ActiveEnt fpsWindow = scene.get_registry().create(); scene.reg_emplace(fpsWindow, - [data = std::array{0.0f}, index = 0, ×](osp::active::ActiveScene& rScene) mutable + [data = std::array{0.0f}, index = 0, ×] + (osp::active::ActiveScene& rScene, bool& visible) mutable { using namespace Magnum; @@ -192,7 +210,7 @@ void testapp::test_flight(std::unique_ptr& pMagnumApp, // Show active MUC velocity ActiveEnt shipStatus = scene.get_registry().create(); scene.reg_emplace(shipStatus, - [] (osp::active::ActiveScene& rScene) + [] (osp::active::ActiveScene& rScene, bool& visible) { using adera::active::machines::MachineUserControl; using namespace osp::active; From 88c956ae5eab6c2a4baa1a33acccc956ea7e1c62 Mon Sep 17 00:00:00 2001 From: "Z.A" Date: Sat, 20 Mar 2021 23:16:38 -0700 Subject: [PATCH 11/12] Cleanup --- src/osp/Active/ActiveScene.cpp | 10 ++++++-- src/osp/Active/ActiveScene.h | 3 +-- src/osp/Active/SysGUI.cpp | 38 ++++++++++++++++++++++++++---- src/osp/Active/SysGUI.h | 6 ++--- src/test_application/OSPMagnum.cpp | 29 ++++++----------------- src/test_application/OSPMagnum.h | 8 +++---- src/test_application/flight.cpp | 19 ++++++++------- 7 files changed, 66 insertions(+), 47 deletions(-) diff --git a/src/osp/Active/ActiveScene.cpp b/src/osp/Active/ActiveScene.cpp index 36355d56..381dc4c8 100644 --- a/src/osp/Active/ActiveScene.cpp +++ b/src/osp/Active/ActiveScene.cpp @@ -25,6 +25,7 @@ #include #include "ActiveScene.h" +#include "SysGUI.h" using namespace osp; using namespace osp::active; @@ -239,10 +240,15 @@ void ActiveScene::draw(ActiveEnt camera) m_renderOrder.call(cameraComp); } -ACompImGuiContext* ActiveScene::find_GUI_context() +Magnum::ImGuiIntegration::Context* ActiveScene::try_get_GUI_context() { ActiveEnt sceneRoot = hier_get_root(); - return m_registry.try_get(sceneRoot); + auto* compCtxt = m_registry.try_get(sceneRoot); + if (compCtxt != nullptr) + { + return &compCtxt->m_imgui; + } + return nullptr; } MapSysMachine_t::iterator ActiveScene::system_machine_add(std::string_view name, diff --git a/src/osp/Active/ActiveScene.h b/src/osp/Active/ActiveScene.h index 1c3b0454..2a303cd3 100644 --- a/src/osp/Active/ActiveScene.h +++ b/src/osp/Active/ActiveScene.h @@ -41,7 +41,6 @@ #include "SysMachine.h" //#include "SysVehicle.h" #include "SysWire.h" -#include "SysGUI.h" #include "adera/SysExhaustPlume.h" namespace osp::active @@ -175,7 +174,7 @@ class ActiveScene constexpr RenderOrder_t& get_render_order() { return m_renderOrder; } - ACompImGuiContext* find_GUI_context(); + Magnum::ImGuiIntegration::Context* try_get_GUI_context(); // TODO constexpr float get_time_delta_fixed() const { return 1.0f / 60.0f; } diff --git a/src/osp/Active/SysGUI.cpp b/src/osp/Active/SysGUI.cpp index ceebd1bc..185139c8 100644 --- a/src/osp/Active/SysGUI.cpp +++ b/src/osp/Active/SysGUI.cpp @@ -24,30 +24,60 @@ */ #include "SysGUI.h" #include "ActiveScene.h" - +#include using namespace osp::active; SysGUI::SysGUI(ActiveScene& rScene) - : m_drawGUI(rScene.get_render_order(), "gui", "debug", "", - [&rScene](ACompCamera const& camera) { draw_GUI(rScene, camera); }) + : m_updateGUI(rScene.get_update_order(), "gui", "physics", "", + [](ActiveScene& rScene) { update_GUI(rScene); }) + , m_drawGUI(rScene.get_render_order(), "gui", "debug", "", + [&rScene](ACompCamera const& camera) { render_GUI(rScene, camera); }) {} -void SysGUI::draw_GUI(ActiveScene& rScene, ACompCamera const&) +void SysGUI::update_GUI(ActiveScene& rScene) { + // Fetch ImGui context from scene root ActiveEnt sceneRoot = rScene.hier_get_root(); ACompImGuiContext* imgui = rScene.reg_try_get(sceneRoot); if (imgui == nullptr) { return; } ImGui::SetCurrentContext(imgui->m_imgui.context()); + // Fetch ImPlot context from scene root, if it exists ACompImPlotContext* implot = rScene.reg_try_get(sceneRoot); if (implot != nullptr) { ImPlot::SetCurrentContext(implot->m_implot.get()); } + // Initialize new GUI frame + imgui->m_imgui.newFrame(); + + // Process GUI elements for (auto [ent, describeElement] : rScene.get_registry().view().each()) { describeElement.m_function(rScene, describeElement.m_visible); } } + +void SysGUI::render_GUI(ActiveScene& rScene, ACompCamera const& camera) +{ + ActiveEnt sceneRoot = rScene.hier_get_root(); + ACompImGuiContext* imgui = rScene.reg_try_get(sceneRoot); + if (imgui == nullptr) { return; } + ImGui::SetCurrentContext(imgui->m_imgui.context()); + + using namespace Magnum::GL; + + Renderer::enable(Renderer::Feature::Blending); + Renderer::enable(Renderer::Feature::ScissorTest); + Renderer::disable(Renderer::Feature::FaceCulling); + Renderer::disable(Renderer::Feature::DepthTest); + imgui->m_imgui.drawFrame(); + Renderer::enable(Renderer::Feature::DepthTest); + Renderer::enable(Renderer::Feature::FaceCulling); + Renderer::disable(Renderer::Feature::ScissorTest); + Renderer::disable(Renderer::Feature::Blending); +} + + diff --git a/src/osp/Active/SysGUI.h b/src/osp/Active/SysGUI.h index 9ccf5b47..9502d421 100644 --- a/src/osp/Active/SysGUI.h +++ b/src/osp/Active/SysGUI.h @@ -33,7 +33,6 @@ namespace osp::active { -// TMP struct ACompImGuiContext { Magnum::ImGuiIntegration::Context m_imgui; @@ -65,9 +64,10 @@ class SysGUI : public IDynamicSystem SysGUI(ActiveScene& rScene); ~SysGUI() = default; - static void draw_GUI(ActiveScene& rScene, ACompCamera const&); - + static void update_GUI(ActiveScene& rScene); + static void render_GUI(ActiveScene& rScene, ACompCamera const& camera); private: + UpdateOrderHandle_t m_updateGUI; RenderOrderHandle_t m_drawGUI; }; diff --git a/src/test_application/OSPMagnum.cpp b/src/test_application/OSPMagnum.cpp index 40a84d29..97785c5c 100644 --- a/src/test_application/OSPMagnum.cpp +++ b/src/test_application/OSPMagnum.cpp @@ -52,28 +52,13 @@ OSPMagnum::OSPMagnum(const Magnum::Platform::Application::Arguments& arguments, OSPMagnum::~OSPMagnum() { - // Free ImPlot - // ImPlot is not part of Magnum's imgui integration, and is handled manually - //ImPlot::DestroyContext(m_implot); - // Clear scene data before GL resources are freed m_scenes.clear(); } -void OSPMagnum::draw_GUI() +void OSPMagnum::set_active_GUI(osp::active::ActiveScene& rScene) { - using namespace Magnum; - - m_activeImgui->updateApplicationCursor(*this); - GL::Renderer::enable(GL::Renderer::Feature::Blending); - GL::Renderer::enable(GL::Renderer::Feature::ScissorTest); - GL::Renderer::disable(GL::Renderer::Feature::FaceCulling); - GL::Renderer::disable(GL::Renderer::Feature::DepthTest); - m_activeImgui->drawFrame(); - GL::Renderer::enable(GL::Renderer::Feature::DepthTest); - GL::Renderer::enable(GL::Renderer::Feature::FaceCulling); - GL::Renderer::disable(GL::Renderer::Feature::ScissorTest); - GL::Renderer::disable(GL::Renderer::Feature::Blending); + m_activeImgui = rScene.try_get_GUI_context(); } void OSPMagnum::drawEvent() @@ -83,9 +68,6 @@ void OSPMagnum::drawEvent() // Clear framebuffer Magnum::GL::defaultFramebuffer.clear(FramebufferClear::Color | FramebufferClear::Depth); - // Initialize new GUI frame - m_activeImgui->newFrame(); - // if (m_area) // { // //Scene3D& scene = m_area->get_scene(); @@ -123,8 +105,11 @@ void OSPMagnum::drawEvent() scene.draw(scene.get_registry().view().front()); } - // TODO: GUI and stuff - draw_GUI(); + // Update the cursor type ("dragging" hand, rescale arrows, text cursor, etc) + if (m_activeImgui != nullptr) + { + m_activeImgui->updateApplicationCursor(*this); + } swapBuffers(); m_timeline.nextFrame(); diff --git a/src/test_application/OSPMagnum.h b/src/test_application/OSPMagnum.h index c2808fa1..f70e0735 100644 --- a/src/test_application/OSPMagnum.h +++ b/src/test_application/OSPMagnum.h @@ -40,7 +40,6 @@ #include #include #include -#include #include @@ -76,15 +75,14 @@ class OSPMagnum : public Magnum::Platform::Application constexpr osp::UserInputHandler& get_input_handler() { return m_userInput; } constexpr MapActiveScene_t& get_scenes() { return m_scenes; } - Magnum::ImGuiIntegration::Context* m_activeImgui; + void set_active_GUI(osp::active::ActiveScene& rScene); private: - - void draw_GUI(); - void drawEvent() override; osp::UserInputHandler m_userInput; + Magnum::ImGuiIntegration::Context* m_activeImgui{nullptr}; + MapActiveScene_t m_scenes; osp::Package m_glResources{"gl", "gl-resources"}; diff --git a/src/test_application/flight.cpp b/src/test_application/flight.cpp index efb2d994..ff24e7c2 100644 --- a/src/test_application/flight.cpp +++ b/src/test_application/flight.cpp @@ -45,8 +45,7 @@ #include #include - -#include +#include using namespace testapp; @@ -135,23 +134,25 @@ void testapp::test_flight(std::unique_ptr& pMagnumApp, // Add GUI contexts to scene { + // Initialize ImGui context auto imguiCtx = Magnum::ImGuiIntegration::Context( Magnum::Vector2{pMagnumApp->windowSize()} / pMagnumApp->dpiScaling(), pMagnumApp->windowSize(), pMagnumApp->framebufferSize()); auto& imgui = reg.emplace(sceneRoot, std::move(imguiCtx)); - pMagnumApp->m_activeImgui = &imgui.m_imgui; - + // Initialize ImPlot context osp::active::ImPlotContext_t implotCtx = osp::active::ImPlotContext_t( ImPlot::CreateContext(), osp::active::ACompImPlotContext::free_ctx); reg.emplace(sceneRoot, std::move(implotCtx)); + + // Set scene's GUI as active (capture events) + pMagnumApp->set_active_GUI(scene); } // Add a camera to the scene // Create the camera entity - ActiveEnt camera = scene.hier_create_child(sceneRoot, - "Camera"); + ActiveEnt camera = scene.hier_create_child(sceneRoot, "Camera"); auto &cameraTransform = scene.reg_emplace(camera); auto &cameraComp = reg.emplace(camera); @@ -182,12 +183,12 @@ void testapp::test_flight(std::unique_ptr& pMagnumApp, } ActiveEnt fpsWindow = scene.get_registry().create(); scene.reg_emplace(fpsWindow, - [data = std::array{0.0f}, index = 0, ×] + [data = std::array{0.0f}, index = 0, times] (osp::active::ActiveScene& rScene, bool& visible) mutable { using namespace Magnum; - ImGui::Begin("Debug"); + ImGui::Begin("Application Status"); double framerate = ImGui::GetIO().Framerate; ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", @@ -210,7 +211,7 @@ void testapp::test_flight(std::unique_ptr& pMagnumApp, // Show active MUC velocity ActiveEnt shipStatus = scene.get_registry().create(); scene.reg_emplace(shipStatus, - [] (osp::active::ActiveScene& rScene, bool& visible) + [](osp::active::ActiveScene& rScene, bool& visible) { using adera::active::machines::MachineUserControl; using namespace osp::active; From 5ac7633403eb33deddcaa815a1e77cbbb5987200 Mon Sep 17 00:00:00 2001 From: "Z.A" Date: Sat, 20 Mar 2021 23:44:41 -0700 Subject: [PATCH 12/12] PR cleanup stuff --- src/osp/Active/SysGUI.cpp | 6 +++--- src/osp/Active/SysGUI.h | 11 +++++++---- src/test_application/flight.cpp | 3 ++- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/osp/Active/SysGUI.cpp b/src/osp/Active/SysGUI.cpp index 185139c8..d4e7a719 100644 --- a/src/osp/Active/SysGUI.cpp +++ b/src/osp/Active/SysGUI.cpp @@ -38,12 +38,12 @@ void SysGUI::update_GUI(ActiveScene& rScene) { // Fetch ImGui context from scene root ActiveEnt sceneRoot = rScene.hier_get_root(); - ACompImGuiContext* imgui = rScene.reg_try_get(sceneRoot); + auto* imgui = rScene.reg_try_get(sceneRoot); if (imgui == nullptr) { return; } ImGui::SetCurrentContext(imgui->m_imgui.context()); // Fetch ImPlot context from scene root, if it exists - ACompImPlotContext* implot = rScene.reg_try_get(sceneRoot); + auto* implot = rScene.reg_try_get(sceneRoot); if (implot != nullptr) { ImPlot::SetCurrentContext(implot->m_implot.get()); @@ -63,7 +63,7 @@ void SysGUI::update_GUI(ActiveScene& rScene) void SysGUI::render_GUI(ActiveScene& rScene, ACompCamera const& camera) { ActiveEnt sceneRoot = rScene.hier_get_root(); - ACompImGuiContext* imgui = rScene.reg_try_get(sceneRoot); + auto* imgui = rScene.reg_try_get(sceneRoot); if (imgui == nullptr) { return; } ImGui::SetCurrentContext(imgui->m_imgui.context()); diff --git a/src/osp/Active/SysGUI.h b/src/osp/Active/SysGUI.h index 9502d421..026c0340 100644 --- a/src/osp/Active/SysGUI.h +++ b/src/osp/Active/SysGUI.h @@ -38,16 +38,19 @@ struct ACompImGuiContext Magnum::ImGuiIntegration::Context m_imgui; }; -using ImPlotContext_t = std::unique_ptr>; - struct ACompImPlotContext { - ImPlotContext_t m_implot; - static void free_ctx(ImPlotContext* ctx) { ImPlot::DestroyContext(ctx); } + + using ImPlotContext_t = std::unique_ptr< + ImPlotContext, + decltype(&ACompImPlotContext::free_ctx)>; + + ImPlotContext_t m_implot; + }; struct ACompGUIWindow diff --git a/src/test_application/flight.cpp b/src/test_application/flight.cpp index ff24e7c2..18362873 100644 --- a/src/test_application/flight.cpp +++ b/src/test_application/flight.cpp @@ -141,7 +141,8 @@ void testapp::test_flight(std::unique_ptr& pMagnumApp, auto& imgui = reg.emplace(sceneRoot, std::move(imguiCtx)); // Initialize ImPlot context - osp::active::ImPlotContext_t implotCtx = osp::active::ImPlotContext_t( + using ImPlotContext_t = osp::active::ACompImPlotContext::ImPlotContext_t; + ImPlotContext_t implotCtx = ImPlotContext_t( ImPlot::CreateContext(), osp::active::ACompImPlotContext::free_ctx); reg.emplace(sceneRoot, std::move(implotCtx));