add more stuff
This commit is contained in:
15
.gitmodules
vendored
15
.gitmodules
vendored
@@ -4,3 +4,18 @@
|
||||
[submodule "magnum"]
|
||||
path = magnum
|
||||
url = https://github.com/mosra/magnum.git
|
||||
[submodule "entt"]
|
||||
path = entt
|
||||
url = https://github.com/skypjack/entt.git
|
||||
[submodule "magnum-integration"]
|
||||
path = magnum-integration
|
||||
url = https://github.com/mosra/magnum-integration.git
|
||||
[submodule "imgui"]
|
||||
path = imgui
|
||||
url = https://github.com/ocornut/imgui.git
|
||||
[submodule "magnum-plugins"]
|
||||
path = magnum-plugins
|
||||
url = https://github.com/mosra/magnum-plugins.git
|
||||
[submodule "ImGuiFileDialog"]
|
||||
path = ImGuiFileDialog
|
||||
url = https://github.com/aiekick/ImGuiFileDialog.git
|
||||
|
||||
@@ -8,7 +8,20 @@ add_subdirectory(corrade EXCLUDE_FROM_ALL)
|
||||
|
||||
# Add Magnum as a subproject, enable Sdl2Application
|
||||
set(CMAKE_PREFIX_PATH ${PROJECT_SOURCE_DIR}/SDL2-2.32.6 ${CMAKE_PREFIX_PATH})
|
||||
set(MAGNUM_WITH_ANYIMAGEIMPORTER ON CACHE BOOL "" FORCE)
|
||||
set(MAGNUM_WITH_ANYSCENEIMPORTER ON CACHE BOOL "" FORCE)
|
||||
set(MAGNUM_WITH_OBJIMPORTER ON CACHE BOOL "" FORCE)
|
||||
set(MAGNUM_WITH_SDL2APPLICATION ON CACHE BOOL "" FORCE)
|
||||
add_subdirectory(magnum EXCLUDE_FROM_ALL)
|
||||
|
||||
set(IMGUI_DIR ${CMAKE_CURRENT_SOURCE_DIR}/imgui)
|
||||
set(MAGNUM_WITH_IMGUIINTEGRATION ON CACHE BOOL "" FORCE)
|
||||
add_subdirectory(magnum-integration EXCLUDE_FROM_ALL)
|
||||
|
||||
set(MAGNUM_WITH_STBIMAGEIMPORTER ON CACHE BOOL "" FORCE)
|
||||
set(MAGNUM_WITH_GLTFIMPORTER ON CACHE BOOL "" FORCE)
|
||||
add_subdirectory(magnum-plugins EXCLUDE_FROM_ALL)
|
||||
|
||||
add_subdirectory(entt)
|
||||
|
||||
add_subdirectory(src)
|
||||
|
||||
1
ImGuiFileDialog
Submodule
1
ImGuiFileDialog
Submodule
Submodule ImGuiFileDialog added at e763838985
1
entt
Submodule
1
entt
Submodule
Submodule entt added at b4e58bdd36
1
imgui
Submodule
1
imgui
Submodule
Submodule imgui added at 960921f03a
1
magnum-integration
Submodule
1
magnum-integration
Submodule
Submodule magnum-integration added at 0184c8371d
1
magnum-plugins
Submodule
1
magnum-plugins
Submodule
Submodule magnum-plugins added at 0d212b5698
456
modules/FindMagnumIntegration.cmake
Normal file
456
modules/FindMagnumIntegration.cmake
Normal file
@@ -0,0 +1,456 @@
|
||||
#.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
|
||||
# Yoga - Yoga Layout 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, 2021, 2022, 2023, 2024, 2025, 2026
|
||||
# Vladimír Vondruš <mosra@centrum.cz>
|
||||
# Copyright © 2018 Konstantinos Chatzilygeroudis <costashatz@gmail.com>
|
||||
#
|
||||
# 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_MAGNUM_DEPENDENCIES )
|
||||
set(_MAGNUMINTEGRATION_MAGNUMEXTRAS_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)
|
||||
elseif(_component STREQUAL Yoga)
|
||||
set(_MAGNUMINTEGRATION_${_component}_MAGNUM_DEPENDENCIES GL Shaders)
|
||||
set(_MAGNUMINTEGRATION_${_component}_MAGNUMEXTRAS_DEPENDENCIES Ui)
|
||||
endif()
|
||||
|
||||
list(APPEND _MAGNUMINTEGRATION_MAGNUM_DEPENDENCIES ${_MAGNUMINTEGRATION_${_component}_MAGNUM_DEPENDENCIES})
|
||||
list(APPEND _MAGNUMINTEGRATION_MAGNUMEXTRAS_DEPENDENCIES ${_MAGNUMINTEGRATION_${_component}_MAGNUMEXTRAS_DEPENDENCIES})
|
||||
endforeach()
|
||||
find_package(Magnum REQUIRED ${_MAGNUMINTEGRATION_MAGNUM_DEPENDENCIES})
|
||||
if(_MAGNUMINTEGRATION_MAGNUMEXTRAS_DEPENDENCIES)
|
||||
find_package(MagnumExtras REQUIRED ${_MAGNUMINTEGRATION_MAGNUMEXTRAS_DEPENDENCIES})
|
||||
endif()
|
||||
|
||||
# Global include dir that's unique to Magnum Integration. Often it will be
|
||||
# installed alongside Magnum, which is why the hint, but if not, it shouldn't
|
||||
# just pick MAGNUM_INCLUDE_DIR because then _MAGNUMINTEGRATION_*_INCLUDE_DIR
|
||||
# will fail to be found. In case of CMake subprojects the versionIntegration.h
|
||||
# is generated inside the build dir so this won't find it, instead
|
||||
# src/CMakeLists.txt forcibly sets MAGNUMINTEGRATION_INCLUDE_DIR as an internal
|
||||
# cache value to make that work.
|
||||
find_path(MAGNUMINTEGRATION_INCLUDE_DIR Magnum/versionIntegration.h
|
||||
HINTS ${MAGNUM_INCLUDE_DIR})
|
||||
mark_as_advanced(MAGNUMINTEGRATION_INCLUDE_DIR)
|
||||
|
||||
# CMake module dir for dependencies. It might not be present at all if no
|
||||
# feature that needs them is enabled, in which case it'll be left at NOTFOUND.
|
||||
# But in that case it should also not be subsequently needed for any
|
||||
# find_package(). If this is called from a superproject, the
|
||||
# _MAGNUMINTEGRATION_DEPENDENCY_MODULE_DIR is already set by
|
||||
# modules/CMakeLists.txt.
|
||||
find_path(_MAGNUMINTEGRATION_DEPENDENCY_MODULE_DIR
|
||||
NAMES
|
||||
FindBullet.cmake FindGLM.cmake FindImGui.cmake FindOVR.cmake
|
||||
PATH_SUFFIXES share/cmake/MagnumIntegration/dependencies)
|
||||
mark_as_advanced(_MAGNUMINTEGRATION_DEPENDENCY_MODULE_DIR)
|
||||
|
||||
# If the module dir is found and is not present in CMAKE_MODULE_PATH already
|
||||
# (such as when someone explicitly added it, or if it's the Magnum's modules/
|
||||
# dir in case of a superproject), add it as the first before all other. Set a
|
||||
# flag to remove it again at the end, so the modules don't clash with Find
|
||||
# modules of the same name from other projects.
|
||||
if(_MAGNUMINTEGRATION_DEPENDENCY_MODULE_DIR AND NOT _MAGNUMINTEGRATION_DEPENDENCY_MODULE_DIR IN_LIST CMAKE_MODULE_PATH)
|
||||
set(CMAKE_MODULE_PATH ${_MAGNUMINTEGRATION_DEPENDENCY_MODULE_DIR} ${CMAKE_MODULE_PATH})
|
||||
set(_MAGNUMINTEGRATION_REMOVE_DEPENDENCY_MODULE_DIR_FROM_CMAKE_PATH ON)
|
||||
else()
|
||||
unset(_MAGNUMINTEGRATION_REMOVE_DEPENDENCY_MODULE_DIR_FROM_CMAKE_PATH)
|
||||
endif()
|
||||
|
||||
# Component distinction (listing them explicitly to avoid mistakes with finding
|
||||
# components from other repositories)
|
||||
set(_MAGNUMINTEGRATION_LIBRARY_COMPONENTS Bullet Dart Eigen ImGui Glm Yoga)
|
||||
if(CORRADE_TARGET_WINDOWS)
|
||||
list(APPEND _MAGNUMINTEGRATION_LIBRARY_COMPONENTS Ovr)
|
||||
endif()
|
||||
set(_MAGNUMINTEGRATION_HEADER_ONLY_COMPONENTS Eigen)
|
||||
# Nothing is enabled by default right now
|
||||
set(_MAGNUMINTEGRATION_IMPLICITLY_ENABLED_COMPONENTS )
|
||||
|
||||
# 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
|
||||
set(_MAGNUMINTEGRATION_ORIGINAL_FIND_COMPONENTS ${MagnumIntegration_FIND_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()
|
||||
|
||||
# Special cases of include paths for header-only libraries. Libraries not
|
||||
# listed here have a path suffix and include name derived from the library name
|
||||
# in the loop below. Non-header-only libraries have a configure.h file.
|
||||
set(_MAGNUMINTEGRATION_EIGEN_INCLUDE_PATH_NAMES GeometryIntegration.h)
|
||||
|
||||
# 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}") # Quotes to fix KDE's hiliter
|
||||
set(MagnumIntegration_${_component}_FOUND TRUE)
|
||||
else()
|
||||
# Find library include dir for header-only libraries
|
||||
if(_component IN_LIST _MAGNUMINTEGRATION_HEADER_ONLY_COMPONENTS)
|
||||
# Include path names to find, unless specified above
|
||||
if(NOT _MAGNUMINTEGRATION_${_COMPONENT}_INCLUDE_PATH_NAMES)
|
||||
set(_MAGNUMINTEGRATION_${_COMPONENT}_INCLUDE_PATH_NAMES ${_component}Integration.h)
|
||||
endif()
|
||||
|
||||
find_path(_MAGNUMINTEGRATION_${_COMPONENT}_INCLUDE_DIR
|
||||
NAMES ${_MAGNUMINTEGRATION_${_COMPONENT}_INCLUDE_PATH_NAMES}
|
||||
HINTS ${MAGNUMINTEGRATION_INCLUDE_DIR}/Magnum/${_component}Integration)
|
||||
mark_as_advanced(_MAGNUMINTEGRATION_${_COMPONENT}_CONFIGURE_FILE)
|
||||
|
||||
# Non-header-only libraries have a configure file which we need to
|
||||
# subsequently read, so find that one directly
|
||||
elseif(_component IN_LIST _MAGNUMINTEGRATION_LIBRARY_COMPONENTS)
|
||||
find_file(_MAGNUMINTEGRATION_${_COMPONENT}_CONFIGURE_FILE configure.h
|
||||
HINTS ${MAGNUMINTEGRATION_INCLUDE_DIR}/Magnum/${_component}Integration)
|
||||
mark_as_advanced(_MAGNUMINTEGRATION_${_COMPONENT}_CONFIGURE_FILE)
|
||||
endif()
|
||||
|
||||
# Library components
|
||||
if(_component IN_LIST _MAGNUMINTEGRATION_LIBRARY_COMPONENTS AND NOT _component IN_LIST _MAGNUMINTEGRATION_HEADER_ONLY_COMPONENTS)
|
||||
# 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)
|
||||
|
||||
# Determine if the library is static or dynamic by reading the
|
||||
# per-library config file. If the file wasn't found, skip this so
|
||||
# it fails on the FPHSA below and not right here.
|
||||
if(_MAGNUMINTEGRATION_${_COMPONENT}_CONFIGURE_FILE)
|
||||
file(READ ${_MAGNUMINTEGRATION_${_COMPONENT}_CONFIGURE_FILE} _magnumIntegrationConfigure)
|
||||
string(REGEX REPLACE ";" "\\\\;" _magnumIntegrationConfigure "${_magnumIntegrationConfigure}")
|
||||
string(REGEX REPLACE "\n" ";" _magnumIntegrationConfigure "${_magnumIntegrationConfigure}")
|
||||
list(FIND _magnumIntegrationConfigure "#define MAGNUM_${_COMPONENT}INTEGRATION_BUILD_STATIC" _magnumIntegrationBuildStatic)
|
||||
if(NOT _magnumIntegrationBuildStatic EQUAL -1)
|
||||
# The variable is inconsistently named between C++ and
|
||||
# CMake, so keep it underscored / private
|
||||
set(_MAGNUMINTEGRATION_${_COMPONENT}_BUILD_STATIC ON)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# On Windows, if we have a dynamic build of given library, find the
|
||||
# DLLs as well. Abuse find_program() since the DLLs should be
|
||||
# alongside usual executables. On MinGW they however have a lib
|
||||
# prefix.
|
||||
if(CORRADE_TARGET_WINDOWS AND NOT _MAGNUMINTEGRATION_${_COMPONENT}_BUILD_STATIC)
|
||||
find_program(MAGNUMINTEGRATION_${_COMPONENT}_DLL_DEBUG ${CMAKE_SHARED_LIBRARY_PREFIX}Magnum${_component}Integration-d.dll)
|
||||
find_program(MAGNUMINTEGRATION_${_COMPONENT}_DLL_RELEASE ${CMAKE_SHARED_LIBRARY_PREFIX}Magnum${_component}Integration.dll)
|
||||
mark_as_advanced(MAGNUMINTEGRATION_${_COMPONENT}_DLL_DEBUG
|
||||
MAGNUMINTEGRATION_${_COMPONENT}_DLL_RELEASE)
|
||||
# If not on Windows or on a static build, unset the DLL variables
|
||||
# to avoid leaks when switching shared and static builds
|
||||
else()
|
||||
unset(MAGNUMINTEGRATION_${_COMPONENT}_DLL_DEBUG CACHE)
|
||||
unset(MAGNUMINTEGRATION_${_COMPONENT}_DLL_RELEASE CACHE)
|
||||
endif()
|
||||
|
||||
# If not a header-only component it's something unknown, skip. FPHSA
|
||||
# will take care of handling this below.
|
||||
elseif(NOT _component IN_LIST _MAGNUMINTEGRATION_HEADER_ONLY_COMPONENTS)
|
||||
continue()
|
||||
endif()
|
||||
|
||||
# Decide if the library was found. If not, skip the rest, which
|
||||
# populates the target properties and finds additional dependencies.
|
||||
# This means that the rest can also rely on that e.g. FindGLM.cmake is
|
||||
# present in _MAGNUMPLUGINS_DEPENDENCY_MODULE_DIR -- given that the
|
||||
# library needing GLM was found, it likely also installed FindGLM for
|
||||
# itself.
|
||||
if(
|
||||
# If the component is a header-only library it should have an
|
||||
# include dir
|
||||
(_component IN_LIST _MAGNUMINTEGRATION_HEADER_ONLY_COMPONENTS AND _MAGNUMINTEGRATION_${_COMPONENT}_INCLUDE_DIR) OR
|
||||
# Or, if it's a real library, it should have a configure file
|
||||
(_component IN_LIST _MAGNUMINTEGRATION_LIBRARY_COMPONENTS AND _MAGNUMINTEGRATION_${_COMPONENT}_CONFIGURE_FILE AND (
|
||||
# Or have a debug library, and a DLL found if expected
|
||||
(MAGNUMINTEGRATION_${_COMPONENT}_LIBRARY_DEBUG AND (
|
||||
NOT DEFINED MAGNUMINTEGRATION_${_COMPONENT}_DLL_DEBUG OR
|
||||
MAGNUMINTEGRATION_${_COMPONENT}_DLL_DEBUG)) OR
|
||||
# Or have a release library, and a DLL found if expected
|
||||
(MAGNUMINTEGRATION_${_COMPONENT}_LIBRARY_RELEASE AND (
|
||||
NOT DEFINED MAGNUMINTEGRATION_${_COMPONENT}_DLL_RELEASE OR
|
||||
MAGNUMINTEGRATION_${_COMPONENT}_DLL_RELEASE))))
|
||||
)
|
||||
set(MagnumIntegration_${_component}_FOUND TRUE)
|
||||
else()
|
||||
set(MagnumIntegration_${_component}_FOUND FALSE)
|
||||
continue()
|
||||
endif()
|
||||
|
||||
# Target for header-only library components
|
||||
if(_component IN_LIST _MAGNUMINTEGRATION_HEADER_ONLY_COMPONENTS)
|
||||
add_library(MagnumIntegration::${_component} INTERFACE IMPORTED)
|
||||
|
||||
# Target and location for libraries
|
||||
elseif(_component IN_LIST _MAGNUMINTEGRATION_LIBRARY_COMPONENTS)
|
||||
if(_MAGNUMINTEGRATION_${_COMPONENT}_BUILD_STATIC)
|
||||
add_library(MagnumIntegration::${_component} STATIC IMPORTED)
|
||||
else()
|
||||
add_library(MagnumIntegration::${_component} SHARED IMPORTED)
|
||||
endif()
|
||||
|
||||
foreach(_CONFIG DEBUG RELEASE)
|
||||
if(NOT MAGNUMINTEGRATION_${_COMPONENT}_LIBRARY_${_CONFIG})
|
||||
continue()
|
||||
endif()
|
||||
|
||||
set_property(TARGET MagnumIntegration::${_component} APPEND PROPERTY
|
||||
IMPORTED_CONFIGURATIONS ${_CONFIG})
|
||||
# Unfortunately for a DLL the two properties are swapped out,
|
||||
# *.lib goes to IMPLIB, so it's duplicated like this
|
||||
if(DEFINED MAGNUMINTEGRATION_${_COMPONENT}_DLL_${_CONFIG})
|
||||
# Quotes to "fix" KDE's higlighter
|
||||
set_target_properties("MagnumIntegration::${_component}" PROPERTIES
|
||||
IMPORTED_LOCATION_${_CONFIG} ${MAGNUMINTEGRATION_${_COMPONENT}_DLL_${_CONFIG}}
|
||||
IMPORTED_IMPLIB_${_CONFIG} ${MAGNUMINTEGRATION_${_COMPONENT}_LIBRARY_${_CONFIG}})
|
||||
else()
|
||||
set_property(TARGET MagnumIntegration::${_component} PROPERTY
|
||||
IMPORTED_LOCATION_${_CONFIG} ${MAGNUMINTEGRATION_${_COMPONENT}_LIBRARY_${_CONFIG}})
|
||||
endif()
|
||||
endforeach()
|
||||
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)
|
||||
# The library-specific configure file was read above already
|
||||
list(FIND _magnumIntegrationConfigure "#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 "${_component}Integration was compiled against an emscripten-ports version of Bullet 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_LINK_LIBRARIES Bullet::LinearMath)
|
||||
endif()
|
||||
|
||||
# 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.
|
||||
# https://eigen.tuxfamily.org/index.php?title=ChangeLog#Eigen_3.3.1
|
||||
set_property(TARGET MagnumIntegration::${_component} APPEND PROPERTY
|
||||
INTERFACE_INCLUDE_DIRECTORIES ${EIGEN3_INCLUDE_DIR})
|
||||
|
||||
# ImGui integration library
|
||||
elseif(_component STREQUAL ImGui)
|
||||
find_package(ImGui)
|
||||
set_property(TARGET MagnumIntegration::${_component} APPEND PROPERTY
|
||||
INTERFACE_LINK_LIBRARIES ImGui::ImGui)
|
||||
|
||||
# GLM integration library
|
||||
elseif(_component STREQUAL Glm)
|
||||
find_package(GLM)
|
||||
set_property(TARGET MagnumIntegration::${_component} APPEND PROPERTY
|
||||
INTERFACE_LINK_LIBRARIES GLM::GLM)
|
||||
|
||||
# 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)
|
||||
|
||||
# Oculus SDK integration library
|
||||
elseif(_component STREQUAL Ovr)
|
||||
find_package(OVR)
|
||||
set_property(TARGET MagnumIntegration::${_component} APPEND PROPERTY
|
||||
INTERFACE_LINK_LIBRARIES OVR::OVR)
|
||||
|
||||
# Yoga integration library
|
||||
elseif(_component STREQUAL Yoga)
|
||||
# Since 2.0.0 the project provides a CMake config file, force it.
|
||||
# Before 2.0 it didn't even have an install target, so assume those
|
||||
# versions just aren't used at all.
|
||||
find_package(yoga CONFIG REQUIRED)
|
||||
set_property(TARGET MagnumIntegration::${_component} APPEND PROPERTY
|
||||
INTERFACE_LINK_LIBRARIES yoga::yogacore)
|
||||
endif()
|
||||
|
||||
if(_component IN_LIST _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}_MAGNUMEXTRAS_DEPENDENCIES})
|
||||
set_property(TARGET MagnumIntegration::${_component} APPEND PROPERTY
|
||||
INTERFACE_LINK_LIBRARIES MagnumExtras::${_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()
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
# For CMake 3.16+ with REASON_FAILURE_MESSAGE, provide additional potentially
|
||||
# useful info about the failed components.
|
||||
if(NOT CMAKE_VERSION VERSION_LESS 3.16)
|
||||
set(_MAGNUMINTEGRATION_REASON_FAILURE_MESSAGE )
|
||||
# Go only through the originally specified find_package() components, not
|
||||
# the dependencies added by us afterwards
|
||||
foreach(_component ${_MAGNUMINTEGRATION_ORIGINAL_FIND_COMPONENTS})
|
||||
if(MagnumIntegration_${_component}_FOUND)
|
||||
continue()
|
||||
endif()
|
||||
|
||||
# If it's not known at all, tell the user -- it might be a new library
|
||||
# and an old Find module, or something platform-specific.
|
||||
if(NOT _component IN_LIST _MAGNUMINTEGRATION_LIBRARY_COMPONENTS)
|
||||
list(APPEND _MAGNUMINTEGRATION_REASON_FAILURE_MESSAGE "${_component} is not a known component on this platform.")
|
||||
# Otherwise, if it's not among implicitly built components, hint that
|
||||
# the user may need to enable it
|
||||
# TODO: currently, the _FOUND variable doesn't reflect if dependencies
|
||||
# were found. When it will, this needs to be updated to avoid
|
||||
# misleading messages.
|
||||
elseif(NOT _component IN_LIST _MAGNUMINTEGRATION_IMPLICITLY_ENABLED_COMPONENTS)
|
||||
string(TOUPPER ${_component} _COMPONENT)
|
||||
list(APPEND _MAGNUMINTEGRATION_REASON_FAILURE_MESSAGE "${_component} is not built by default. Make sure you enabled MAGNUM_WITH_${_COMPONENT}INTEGRATION when building Magnum Integration.")
|
||||
# Otherwise we have no idea. Better be silent than to print something
|
||||
# misleading.
|
||||
else()
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
string(REPLACE ";" " " _MAGNUMINTEGRATION_REASON_FAILURE_MESSAGE "${_MAGNUMINTEGRATION_REASON_FAILURE_MESSAGE}")
|
||||
set(_MAGNUMINTEGRATION_REASON_FAILURE_MESSAGE REASON_FAILURE_MESSAGE "${_MAGNUMINTEGRATION_REASON_FAILURE_MESSAGE}")
|
||||
endif()
|
||||
|
||||
# Remove Magnum Integration dependency module dir from CMAKE_MODULE_PATH again.
|
||||
# Do it before the FPHSA call which may exit early in case of a failure.
|
||||
if(_MAGNUMINTEGRATION_REMOVE_DEPENDENCY_MODULE_DIR_FROM_CMAKE_PATH)
|
||||
list(REMOVE_ITEM CMAKE_MODULE_PATH ${_MAGNUMINTEGRATION_DEPENDENCY_MODULE_DIR})
|
||||
unset(_MAGNUMINTEGRATION_REMOVE_DEPENDENCY_MODULE_DIR_FROM_CMAKE_PATH)
|
||||
endif()
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(MagnumIntegration
|
||||
REQUIRED_VARS MAGNUMINTEGRATION_INCLUDE_DIR
|
||||
HANDLE_COMPONENTS
|
||||
${_MAGNUMINTEGRATION_REASON_FAILURE_MESSAGE})
|
||||
4
resources/resources.conf
Normal file
4
resources/resources.conf
Normal file
@@ -0,0 +1,4 @@
|
||||
group=texture-resources
|
||||
|
||||
[file]
|
||||
filename=stone.tga
|
||||
BIN
resources/stone.tga
Normal file
BIN
resources/stone.tga
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 192 KiB |
@@ -1,12 +1,55 @@
|
||||
find_package(Magnum REQUIRED GL Sdl2Application)
|
||||
find_package(Corrade REQUIRED Main)
|
||||
find_package(Magnum REQUIRED
|
||||
GL
|
||||
MeshTools
|
||||
Shaders
|
||||
SceneGraph
|
||||
Trade
|
||||
Sdl2Application)
|
||||
find_package(MagnumIntegration REQUIRED ImGui)
|
||||
|
||||
set_directory_properties(PROPERTIES CORRADE_USE_PEDANTIC_FLAGS ON)
|
||||
|
||||
add_executable(${PROJECT_NAME} Chocolate.cpp)
|
||||
add_executable(${PROJECT_NAME} WIN32
|
||||
Chocolate.h
|
||||
Chocolate.cpp
|
||||
Camera.h
|
||||
Camera.cpp
|
||||
MagnumDrawable.h
|
||||
MagnumDrawable.cpp
|
||||
Common.h
|
||||
${PROJECT_SOURCE_DIR}/ImGuiFileDialog/ImGuiFileDialog.cpp
|
||||
Components.cpp
|
||||
Components.h
|
||||
Scene.cpp
|
||||
Scene.h
|
||||
Materials.h
|
||||
UI.cpp
|
||||
UI.h
|
||||
)
|
||||
|
||||
target_include_directories(${PROJECT_NAME} PRIVATE ${PROJECT_SOURCE_DIR}/ImGuiFileDialog)
|
||||
|
||||
add_dependencies(${PROJECT_NAME}
|
||||
Magnum::AnyImageImporter
|
||||
Magnum::AnySceneImporter
|
||||
Magnum::ObjImporter
|
||||
MagnumPlugins::StbImageImporter
|
||||
MagnumPlugins::GltfImporter
|
||||
)
|
||||
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE
|
||||
Corrade::Main
|
||||
Magnum::Application
|
||||
Magnum::GL
|
||||
Magnum::Magnum)
|
||||
Magnum::Magnum
|
||||
Magnum::MeshTools
|
||||
Magnum::SceneGraph
|
||||
Magnum::Shaders
|
||||
Magnum::Trade
|
||||
EnTT::EnTT
|
||||
MagnumIntegration::ImGui
|
||||
)
|
||||
|
||||
# Make the executable a default target to build & run in Visual Studio
|
||||
set_property(DIRECTORY ${PROJECT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME})
|
||||
|
||||
42
src/Camera.cpp
Normal file
42
src/Camera.cpp
Normal file
@@ -0,0 +1,42 @@
|
||||
#include "Camera.h"
|
||||
|
||||
Camera::Camera(Scene3D& scene, const float aspectRatio, const float near, const float far)
|
||||
{
|
||||
_cameraObject
|
||||
.setParent(&scene)
|
||||
.translate(Vector3::zAxis(5.0f));
|
||||
(_camera = new SceneGraph::Camera3D{_cameraObject})
|
||||
->setAspectRatioPolicy(SceneGraph::AspectRatioPolicy::Extend)
|
||||
.setProjectionMatrix(
|
||||
Matrix4::perspectiveProjection(35.0_degf, aspectRatio, near, far)
|
||||
)
|
||||
.setViewport(GL::defaultFramebuffer.viewport().size());
|
||||
}
|
||||
|
||||
void Camera::Init(Scene3D& scene, float aspectRatio, float near, float far)
|
||||
{
|
||||
_cameraObject
|
||||
.setParent(&scene);
|
||||
|
||||
(_camera = new SceneGraph::Camera3D{_cameraObject})
|
||||
->setAspectRatioPolicy(SceneGraph::AspectRatioPolicy::Extend)
|
||||
.setProjectionMatrix(
|
||||
Matrix4::perspectiveProjection(35.0_degf, aspectRatio, near, far)
|
||||
)
|
||||
.setViewport(GL::defaultFramebuffer.viewport().size());
|
||||
}
|
||||
|
||||
void Camera::Draw(SceneGraph::DrawableGroup3D& _drawables) const
|
||||
{
|
||||
_camera->draw(_drawables);
|
||||
}
|
||||
|
||||
void Camera::SetViewport(const Vector2i& size) const
|
||||
{
|
||||
_camera->setViewport(size);
|
||||
}
|
||||
|
||||
void Camera::Translate(const Math::Vector3<Float>& vector)
|
||||
{
|
||||
_cameraObject.translate(vector);
|
||||
}
|
||||
32
src/Camera.h
Normal file
32
src/Camera.h
Normal file
@@ -0,0 +1,32 @@
|
||||
#ifndef CHOCOLATE_CAMERA_H
|
||||
#define CHOCOLATE_CAMERA_H
|
||||
|
||||
#include <Magnum/SceneGraph/Camera.h>
|
||||
#include <Magnum/SceneGraph/Drawable.h>
|
||||
#include <Magnum/SceneGraph/MatrixTransformation3D.h>
|
||||
#include <Magnum/SceneGraph/Scene.h>
|
||||
#include <Magnum/GL/DefaultFramebuffer.h>
|
||||
|
||||
#include "Common.h"
|
||||
|
||||
using namespace Magnum;
|
||||
using namespace Math::Literals;
|
||||
|
||||
class Camera
|
||||
{
|
||||
public:
|
||||
explicit Camera(): _camera(nullptr) {}
|
||||
explicit Camera(Scene3D& scene, float aspectRatio, float near, float far);
|
||||
|
||||
void Init(Scene3D& scene, float aspectRatio, float near, float far);
|
||||
void Draw(SceneGraph::DrawableGroup3D& _drawables) const;
|
||||
void SetViewport(const Vector2i& size) const;
|
||||
void Translate(const Math::Vector3<Float>& vector);
|
||||
private:
|
||||
Object3D _cameraObject;
|
||||
SceneGraph::Camera3D* _camera;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif //CHOCOLATE_CAMERA_H
|
||||
@@ -1,26 +1,395 @@
|
||||
#include <Magnum/GL/DefaultFramebuffer.h>
|
||||
#include <Magnum/Platform/Sdl2Application.h>
|
||||
#include "Chocolate.h"
|
||||
#include "MagnumDrawable.h"
|
||||
#include "Components.h"
|
||||
|
||||
using namespace Magnum;
|
||||
#include <Magnum/GL/Renderbuffer.h>
|
||||
#include <Magnum/GL/TextureFormat.h>
|
||||
#include <Magnum/GL/RenderbufferFormat.h>
|
||||
#include <Magnum/GL/Framebuffer.h>
|
||||
#include <Magnum/Math/Quaternion.h>
|
||||
#include <Magnum/Trade/SceneData.h>
|
||||
#include <Magnum/Trade/LightData.h>
|
||||
#include <imgui.h>
|
||||
#include <Magnum/ImGuiIntegration/Context.hpp>
|
||||
|
||||
class Chocolate: public Platform::Application {
|
||||
public:
|
||||
explicit Chocolate(const Arguments& arguments);
|
||||
#include "Magnum/ShaderTools/Stage.h"
|
||||
#include "Magnum/Trade/ObjectData2D.h"
|
||||
#include <Magnum/Trade/ImageData.h>
|
||||
|
||||
private:
|
||||
void drawEvent() override;
|
||||
};
|
||||
Chocolate::Chocolate(const Arguments& arguments) :
|
||||
Platform::Application{
|
||||
arguments, Configuration{}
|
||||
.setTitle("Chocolate")
|
||||
.setSize({1920, 1080})
|
||||
.setWindowFlags(Configuration::WindowFlag::Resizable)
|
||||
}
|
||||
{
|
||||
_imgui = ImGuiIntegration::Context(Vector2{windowSize()}/dpiScaling(),
|
||||
windowSize(), framebufferSize());
|
||||
|
||||
Chocolate::Chocolate(const Arguments& arguments): Platform::Application{arguments} {
|
||||
/* TODO: Add your initialization code here */
|
||||
/* Setup renderer and shader defaults */
|
||||
GL::Renderer::enable(GL::Renderer::Feature::DepthTest);
|
||||
GL::Renderer::enable(GL::Renderer::Feature::FaceCulling);
|
||||
|
||||
GL::Renderer::setBlendEquation(GL::Renderer::BlendEquation::Add,
|
||||
GL::Renderer::BlendEquation::Add);
|
||||
GL::Renderer::setBlendFunction(GL::Renderer::BlendFunction::SourceAlpha,
|
||||
GL::Renderer::BlendFunction::OneMinusSourceAlpha);
|
||||
|
||||
_camera.Init(_scene, 1.f, 0.01f, 1000.f);
|
||||
_camera.Translate(Vector3::zAxis(10.f));
|
||||
|
||||
_materials["matte_rubber"] = PhongMaterialConfig{
|
||||
{ 0.02, 0.02, 0.02, 1.f},
|
||||
{0.1, 0.1, 0.1, 1.f},
|
||||
{0.05, 0.05, 0.05, 1.f},
|
||||
2.f
|
||||
};
|
||||
|
||||
const auto viewportSize = GL::defaultFramebuffer.viewport().size();
|
||||
|
||||
Vector2i renderWindowSize = {static_cast<int>(viewportSize.x() * (1 - _sidebarWidth)), viewportSize.y()};
|
||||
Vector2i renderWindowPosition = {static_cast<int>(viewportSize.x() * _sidebarWidth), 0};
|
||||
_uiSceneRenderer = UI::RenderWindow(renderWindowSize, renderWindowPosition);
|
||||
_uiComponents.push_back(&_uiSceneRenderer);
|
||||
|
||||
Vector2i entityListPanelSize = {static_cast<int>(viewportSize.x() * _sidebarWidth), viewportSize.y() / 2};
|
||||
Vector2i entityListPanelPosition = {0, 0};
|
||||
_uiEntityListPanel = UI::EntityListPanel(entityListPanelSize, entityListPanelPosition, &_registry,
|
||||
[this](const std::string& file)
|
||||
{
|
||||
Import(file);
|
||||
},
|
||||
[this](entt::entity entitySelected)
|
||||
{
|
||||
EntitySelected(entitySelected);
|
||||
});
|
||||
_uiComponents.push_back(&_uiEntityListPanel);
|
||||
|
||||
Vector2i entityEditorWindowSize = {static_cast<int>(viewportSize.x() * _sidebarWidth), viewportSize.y() / 2};
|
||||
Vector2i entityEditorWindowPosition = {0, viewportSize.y() / 2};
|
||||
_uiEntityEditorWindow = UI::EntityEditorWindow(entityEditorWindowSize, entityEditorWindowPosition, &_registry);
|
||||
_uiComponents.push_back(&_uiEntityEditorWindow);
|
||||
}
|
||||
|
||||
void Chocolate::tickEvent()
|
||||
{
|
||||
UpdateMagnumObjects();
|
||||
}
|
||||
|
||||
void Chocolate::drawEvent() {
|
||||
GL::defaultFramebuffer.clear(GL::FramebufferClear::Color);
|
||||
|
||||
/* TODO: Add your drawing code here */
|
||||
RenderToFramebuffer(_uiSceneRenderer.Framebuffer());
|
||||
|
||||
DrawUI();
|
||||
|
||||
swapBuffers();
|
||||
redraw();
|
||||
}
|
||||
|
||||
void Chocolate::UpdateMagnumObjects()
|
||||
{
|
||||
for (const auto entity : _registry.view<Components::MagnumObject>())
|
||||
{
|
||||
const auto obj = _registry.get<Components::MagnumObject>(entity).obj;
|
||||
if (const auto transform = _registry.try_get<Components::Transform>(entity))
|
||||
{
|
||||
Matrix4 matrix = Matrix4::translation(transform->translation) * Matrix4{transform->rotation.toMatrix()} * Matrix4::scaling(transform->scale);
|
||||
obj->setTransformation(matrix);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Chocolate::viewportEvent(ViewportEvent& event) {
|
||||
GL::defaultFramebuffer.setViewport({{}, event.framebufferSize()});
|
||||
|
||||
_camera.SetViewport(event.windowSize());
|
||||
|
||||
_imgui.relayout(Vector2{event.windowSize()}/event.dpiScaling(),
|
||||
event.windowSize(), event.framebufferSize());
|
||||
|
||||
|
||||
auto windowSize = event.framebufferSize();
|
||||
ResizeUI(windowSize);
|
||||
}
|
||||
|
||||
void Chocolate::pointerPressEvent(PointerEvent& event) {
|
||||
_imgui.handlePointerPressEvent(event);
|
||||
}
|
||||
|
||||
void Chocolate::pointerReleaseEvent(PointerEvent& event) {
|
||||
_imgui.handlePointerReleaseEvent(event);
|
||||
}
|
||||
|
||||
void Chocolate::pointerMoveEvent(PointerMoveEvent& event) {
|
||||
_imgui.handlePointerMoveEvent(event);
|
||||
}
|
||||
|
||||
void Chocolate::keyPressEvent(KeyEvent& event) {
|
||||
if(_imgui.handleKeyPressEvent(event)) return;
|
||||
}
|
||||
|
||||
void Chocolate::keyReleaseEvent(KeyEvent& event) {
|
||||
if(_imgui.handleKeyReleaseEvent(event)) return;
|
||||
}
|
||||
|
||||
void Chocolate::textInputEvent(TextInputEvent& event) {
|
||||
if(_imgui.handleTextInputEvent(event)) return;
|
||||
}
|
||||
|
||||
void Chocolate::RenderToFramebuffer(GL::Framebuffer& framebuffer)
|
||||
{
|
||||
framebuffer
|
||||
.clear(GL::FramebufferClear::Color|GL::FramebufferClear::Depth)
|
||||
.bind();
|
||||
|
||||
_camera.Draw(_drawables);
|
||||
}
|
||||
|
||||
void Chocolate::DrawUI()
|
||||
{
|
||||
GL::defaultFramebuffer
|
||||
.clear(GL::FramebufferClear::Color|GL::FramebufferClear::Depth)
|
||||
.bind();
|
||||
|
||||
_imgui.newFrame();
|
||||
if(ImGui::GetIO().WantTextInput && !isTextInputActive())
|
||||
startTextInput();
|
||||
else if(!ImGui::GetIO().WantTextInput && isTextInputActive())
|
||||
stopTextInput();
|
||||
|
||||
for (const auto comp : _uiComponents)
|
||||
{
|
||||
comp->Draw();
|
||||
}
|
||||
|
||||
/* Update application cursor */
|
||||
_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);
|
||||
_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 Chocolate::ResizeUI(Vector2i windowSize)
|
||||
{
|
||||
Vector2i renderWindowSize = {static_cast<int>(windowSize.x() * (1 - _sidebarWidth)), windowSize.y()};
|
||||
Vector2i renderWindowPosition = {static_cast<int>(windowSize.x() * _sidebarWidth), 0};
|
||||
_uiSceneRenderer.SetPosition(renderWindowPosition);
|
||||
_uiSceneRenderer.Resize(renderWindowSize);
|
||||
|
||||
Vector2i entityListPanelSize = {static_cast<int>(windowSize.x() * _sidebarWidth), windowSize.y()};
|
||||
Vector2i entityListPanelPosition = {0, 0};
|
||||
_uiEntityListPanel.SetPosition(entityListPanelPosition);
|
||||
_uiEntityListPanel.Resize(entityListPanelSize);
|
||||
|
||||
Vector2i entityEditorWindowSize = {static_cast<int>(windowSize.x() * _sidebarWidth), windowSize.y() / 2};
|
||||
Vector2i entityEditorWindowPosition = {0, windowSize.y() / 2};
|
||||
_uiEntityEditorWindow.SetPosition(entityEditorWindowPosition);
|
||||
_uiEntityEditorWindow.Resize(entityEditorWindowSize);
|
||||
}
|
||||
|
||||
void Chocolate::Import(const std::string& file)
|
||||
{
|
||||
PluginManager::Manager<Trade::AbstractImporter> manager;
|
||||
Containers::Pointer<Trade::AbstractImporter> importer =
|
||||
manager.loadAndInstantiate("AnySceneImporter");
|
||||
|
||||
if (!importer || !importer->openFile(file))
|
||||
std::exit(1);
|
||||
|
||||
auto sceneMeshes = Containers::Array<Containers::Optional<GL::Mesh*>>{importer->meshCount()};
|
||||
for(UnsignedInt i = 0; i != importer->meshCount(); ++i) {
|
||||
Containers::Optional<Trade::MeshData> meshData = importer->mesh(i);
|
||||
|
||||
if(!meshData) {
|
||||
Warning{} << "Cannot load mesh" << i << importer->meshName(i);
|
||||
sceneMeshes[i] = nullptr;
|
||||
continue;
|
||||
}
|
||||
|
||||
MeshTools::CompileFlags flags;
|
||||
if(!meshData->hasAttribute(Trade::MeshAttribute::Normal))
|
||||
flags |= MeshTools::CompileFlag::GenerateFlatNormals;
|
||||
|
||||
GL::Mesh mesh = MeshTools::compile(*meshData, flags);
|
||||
|
||||
_meshes.push_back(std::make_unique<GL::Mesh>(std::move(mesh)));
|
||||
sceneMeshes[i] = _meshes.back().get();
|
||||
}
|
||||
|
||||
auto sceneTextures = Containers::Array<Containers::Optional<GL::Texture2D*>>{importer->textureCount()};
|
||||
for(UnsignedInt i = 0; i != importer->textureCount(); ++i) {
|
||||
Containers::Optional<Trade::TextureData> textureData =
|
||||
importer->texture(i);
|
||||
if(!textureData || textureData->type() != Trade::TextureType::Texture2D) {
|
||||
Warning{} << "Cannot load texture" << i
|
||||
<< importer->textureName(i);
|
||||
continue;
|
||||
}
|
||||
|
||||
Containers::Optional<Trade::ImageData2D> imageData =
|
||||
importer->image2D(textureData->image());
|
||||
if(!imageData || imageData->isCompressed()) {
|
||||
Warning{} << "Cannot load image" << textureData->image()
|
||||
<< importer->image2DName(textureData->image());
|
||||
continue;
|
||||
}
|
||||
|
||||
_textures.push_back(std::make_unique<GL::Texture2D>(std::move(GL::Texture2D{}
|
||||
.setMagnificationFilter(textureData->magnificationFilter())
|
||||
.setMinificationFilter(textureData->minificationFilter(),
|
||||
textureData->mipmapFilter())
|
||||
.setWrapping(textureData->wrapping().xy())
|
||||
.setStorage(Math::log2(imageData->size().max()) + 1,
|
||||
GL::textureFormat(imageData->format()), imageData->size())
|
||||
.setSubImage(0, {}, *imageData)
|
||||
.generateMipmap())));
|
||||
|
||||
auto texture = _textures.back().get();
|
||||
sceneTextures[i] = texture;
|
||||
}
|
||||
|
||||
Containers::Array<Containers::Optional<Trade::PhongMaterialData>> materials{importer->materialCount()};
|
||||
for(UnsignedInt i = 0; i != importer->materialCount(); ++i) {
|
||||
Containers::Optional<Trade::MaterialData> materialData = importer->material(i);
|
||||
|
||||
if(!materialData) {
|
||||
Warning{} << "Cannot load material" << i
|
||||
<< importer->materialName(i);
|
||||
continue;
|
||||
}
|
||||
|
||||
materials[i] = std::move(*materialData).as<Trade::PhongMaterialData>();
|
||||
}
|
||||
|
||||
if(importer->defaultScene() == -1 && !sceneMeshes.isEmpty() && sceneMeshes[0]) {
|
||||
const auto& entity = _registry.create();
|
||||
|
||||
_registry.emplace<Components::Label>(entity);
|
||||
_registry.emplace<Components::Transform>(entity);
|
||||
|
||||
auto& [mesh] = _registry.emplace<Components::Mesh>(entity);
|
||||
mesh = *sceneMeshes[0];
|
||||
|
||||
auto& [shader, config, texture] = _registry.emplace<Components::Material>(entity);
|
||||
shader = &_phongShader;
|
||||
config = &_materials["matte_rubber"];
|
||||
|
||||
auto& [obj, drawable] = _registry.emplace<Components::MagnumObject>(entity);
|
||||
obj = new Object3D{};
|
||||
obj->setParent(&_scene);
|
||||
drawable = new Rendering::Magnum::Drawable(obj, &_drawables, _registry, entity);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Containers::Optional<Trade::SceneData> scene = importer->scene(importer->defaultScene());
|
||||
|
||||
if(!scene ||
|
||||
!scene->is3D() ||
|
||||
!scene->hasField(Trade::SceneField::Parent) ||
|
||||
!scene->hasField(Trade::SceneField::Mesh))
|
||||
{
|
||||
Fatal{} << "Couldn't load scene" << importer->defaultScene()
|
||||
<< importer->sceneName(importer->defaultScene());
|
||||
}
|
||||
|
||||
Containers::Array<Object3D*> objects{scene->mappingBound()};
|
||||
Containers::Array<Containers::Pair<UnsignedInt, Int>> parents = scene->parentsAsArray();
|
||||
Containers::Array<Containers::Pair<UnsignedInt, Matrix4>> transforms = scene->transformations3DAsArray();
|
||||
Containers::Array<Containers::Pair<UnsignedInt, Containers::Pair<UnsignedInt, Int>>> meshMap = scene->meshesMaterialsAsArray();
|
||||
|
||||
for (const auto& parent : parents)
|
||||
{
|
||||
objects[parent.first()] = new Object3D{};
|
||||
}
|
||||
|
||||
for (const auto& parent : parents)
|
||||
{
|
||||
objects[parent.first()]->setParent(parent.second() == -1 ? &_scene : objects[parent.second()]);
|
||||
}
|
||||
|
||||
for (const auto& transform : transforms)
|
||||
{
|
||||
if (auto* obj = objects[transform.first()])
|
||||
{
|
||||
obj->setTransformation(transform.second());
|
||||
}
|
||||
}
|
||||
|
||||
for (UnsignedInt i = 0; i != objects.size(); ++i)
|
||||
{
|
||||
const auto& entity = _registry.create();
|
||||
_registry.emplace<Components::Label>(entity);
|
||||
|
||||
auto& [obj, drawable] = _registry.emplace<Components::MagnumObject>(entity);
|
||||
obj = objects[i];
|
||||
drawable = new Rendering::Magnum::Drawable(obj, &_drawables, _registry, entity);
|
||||
auto& [translation, rotation, scale] = _registry.emplace<Components::Transform>(entity);
|
||||
translation = obj->transformation().translation();
|
||||
scale = obj->transformation().scaling();
|
||||
rotation = Quaternion::fromMatrix(obj->transformation().rotation());
|
||||
|
||||
if (scene->hasFieldObject(Trade::SceneField::MeshMaterial, i))
|
||||
{
|
||||
auto meshMaterial = scene->meshesMaterialsFor(i)[0];
|
||||
|
||||
auto meshId = meshMaterial.first();
|
||||
auto materialId = meshMaterial.second();
|
||||
|
||||
if (meshId != -1 && sceneMeshes[meshId])
|
||||
{
|
||||
auto& [mesh] = _registry.emplace<Components::Mesh>(entity);
|
||||
mesh = *sceneMeshes[meshId];
|
||||
}
|
||||
|
||||
auto& [shader, config, texture] = _registry.emplace<Components::Material>(entity);
|
||||
shader = &_phongShader;
|
||||
|
||||
if (materialId == -1 || !materials[materialId])
|
||||
{
|
||||
config = &_materials["matte_rubber"];
|
||||
}
|
||||
else
|
||||
{
|
||||
auto& material = materials[materialId];
|
||||
|
||||
char buf [64] = {};
|
||||
sprintf(buf, "Material_%d", materialId);
|
||||
|
||||
std::string materialName = buf;
|
||||
|
||||
if (_materials.find(materialName) == _materials.end())
|
||||
{
|
||||
_materials[materialName] = PhongMaterialConfig{
|
||||
material->ambientColor(),
|
||||
material->diffuseColor(),
|
||||
material->specularColor(),
|
||||
material->shininess(),
|
||||
};
|
||||
}
|
||||
|
||||
config = &_materials[materialName];
|
||||
|
||||
if (material->hasAttribute(Trade::MaterialAttribute::DiffuseTexture))
|
||||
{
|
||||
texture = *sceneTextures[material->diffuseTexture()];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Chocolate::EntitySelected(entt::entity entity)
|
||||
{
|
||||
_uiEntityEditorWindow.SetEntity(entity);
|
||||
}
|
||||
|
||||
MAGNUM_APPLICATION_MAIN(Chocolate)
|
||||
100
src/Chocolate.h
Normal file
100
src/Chocolate.h
Normal file
@@ -0,0 +1,100 @@
|
||||
#ifndef CHOCOLATE_CHOCOLATE_H
|
||||
#define CHOCOLATE_CHOCOLATE_H
|
||||
|
||||
#include <Corrade/Containers/Optional.h>
|
||||
#include <Corrade/Containers/Pair.h>
|
||||
#include <Corrade/PluginManager/Manager.h>
|
||||
#include <Corrade/Utility/Arguments.h>
|
||||
|
||||
#include <Magnum/GL/Framebuffer.h>
|
||||
#include <Magnum/ImageView.h>
|
||||
#include <Magnum/Math/Time.h>
|
||||
#include <Magnum/Mesh.h>
|
||||
#include <Magnum/GL/DefaultFramebuffer.h>
|
||||
#include <Magnum/GL/Mesh.h>
|
||||
#include <Magnum/GL/Renderer.h>
|
||||
#include <Magnum/Math/Color.h>
|
||||
#include <Magnum/MeshTools/Compile.h>
|
||||
#include <Magnum/Platform/Sdl2Application.h>
|
||||
#include <Magnum/SceneGraph/Camera.h>
|
||||
#include <Magnum/SceneGraph/Drawable.h>
|
||||
#include <Magnum/SceneGraph/MatrixTransformation3D.h>
|
||||
#include <Magnum/SceneGraph/Scene.h>
|
||||
#include <Magnum/Shaders/PhongGL.h>
|
||||
#include <Magnum/Trade/AbstractImporter.h>
|
||||
#include <Magnum/Trade/MeshData.h>
|
||||
#include <Magnum/Trade/PhongMaterialData.h>
|
||||
#include <Magnum/Trade/TextureData.h>
|
||||
|
||||
|
||||
#include <entt/entt.hpp>
|
||||
|
||||
#include <imgui.h>
|
||||
#include <Magnum/ImGuiIntegration/Context.hpp>
|
||||
|
||||
#include "Camera.h"
|
||||
|
||||
#include "Materials.h"
|
||||
#include "UI.h"
|
||||
|
||||
using namespace Magnum;
|
||||
using namespace Math::Literals;
|
||||
|
||||
class Chocolate: public Platform::Application {
|
||||
public:
|
||||
virtual ~Chocolate() = default;
|
||||
explicit Chocolate(const Arguments& arguments);
|
||||
|
||||
private:
|
||||
//SDL 2 events
|
||||
void drawEvent() override;
|
||||
void tickEvent() override;
|
||||
void viewportEvent(ViewportEvent& event) override;
|
||||
void pointerPressEvent(PointerEvent& event) override;
|
||||
void pointerReleaseEvent(PointerEvent& event) override;
|
||||
void pointerMoveEvent(PointerMoveEvent& event) override;
|
||||
void keyPressEvent(KeyEvent& event) override;
|
||||
void keyReleaseEvent(KeyEvent& event) override;
|
||||
void textInputEvent(TextInputEvent& event) override;
|
||||
|
||||
// Render
|
||||
void RenderToFramebuffer(GL::Framebuffer& framebuffer);
|
||||
|
||||
// UI
|
||||
void DrawUI();
|
||||
void ResizeUI(Vector2i windowSize);
|
||||
|
||||
//Systems
|
||||
void UpdateMagnumObjects();
|
||||
|
||||
// Callbacks
|
||||
void Import(const std::string& file);
|
||||
void EntitySelected(entt::entity entity);
|
||||
|
||||
//Scene
|
||||
Scene3D _scene;
|
||||
SceneGraph::DrawableGroup3D _drawables;
|
||||
Camera _camera;
|
||||
|
||||
// Resources
|
||||
std::vector<std::unique_ptr<GL::Mesh>> _meshes;
|
||||
std::vector<std::unique_ptr<GL::Texture2D>> _textures;
|
||||
std::unordered_map<std::string, PhongMaterialConfig> _materials;
|
||||
|
||||
Shaders::PhongGL _phongShader;
|
||||
|
||||
entt::registry _registry;
|
||||
|
||||
entt::entity selectedEntityToEdit = entt::null;
|
||||
bool showEntityEditorWindow = false;
|
||||
ImGuiIntegration::Context _imgui{NoCreate};
|
||||
float _sidebarWidth = 0.17f;
|
||||
|
||||
std::vector<UI::Component*> _uiComponents;
|
||||
UI::RenderWindow _uiSceneRenderer;
|
||||
UI::EntityListPanel _uiEntityListPanel;
|
||||
UI::EntityEditorWindow _uiEntityEditorWindow;
|
||||
};
|
||||
|
||||
|
||||
#endif //CHOCOLATE_CHOCOLATE_H
|
||||
12
src/Common.h
Normal file
12
src/Common.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#ifndef CHOCOLATE_COMMON_H
|
||||
#define CHOCOLATE_COMMON_H
|
||||
|
||||
#include <Magnum/SceneGraph/MatrixTransformation3D.h>
|
||||
#include <Magnum/SceneGraph/Scene.h>
|
||||
|
||||
using namespace Magnum;
|
||||
|
||||
typedef SceneGraph::Object<SceneGraph::MatrixTransformation3D> Object3D;
|
||||
typedef SceneGraph::Scene<SceneGraph::MatrixTransformation3D> Scene3D;
|
||||
|
||||
#endif //CHOCOLATE_COMMON_H
|
||||
10
src/Components.cpp
Normal file
10
src/Components.cpp
Normal file
@@ -0,0 +1,10 @@
|
||||
//
|
||||
// Created by lbmas on 1/3/2026.
|
||||
//
|
||||
|
||||
#include "Components.h"
|
||||
|
||||
namespace Components
|
||||
{
|
||||
|
||||
}
|
||||
60
src/Components.h
Normal file
60
src/Components.h
Normal file
@@ -0,0 +1,60 @@
|
||||
#ifndef CHOCOLATE_COMPONENTS_H
|
||||
#define CHOCOLATE_COMPONENTS_H
|
||||
|
||||
#include <Magnum/Math/Quaternion.h>
|
||||
#include <Magnum/Math/Vector3.h>
|
||||
#include <Magnum/GL/Mesh.h>
|
||||
#include <Magnum/Math/Color.h>
|
||||
#include <Magnum/Shaders/PhongGL.h>
|
||||
|
||||
#include "Common.h"
|
||||
#include <entt/entt.hpp>
|
||||
|
||||
#include "MagnumDrawable.h"
|
||||
#include "Materials.h"
|
||||
|
||||
using namespace Magnum;
|
||||
|
||||
namespace Components
|
||||
{
|
||||
struct Transform
|
||||
{
|
||||
Vector3 translation{0.0f, 0.0f, 0.0f};
|
||||
Quaternion rotation {};
|
||||
Vector3 scale{1.0f, 1.0f, 1.0f};
|
||||
};
|
||||
|
||||
struct Mesh
|
||||
{
|
||||
GL::Mesh* mesh;
|
||||
};
|
||||
|
||||
struct Material
|
||||
{
|
||||
Shaders::PhongGL* _shader {nullptr};
|
||||
|
||||
PhongMaterialConfig* phongConfig {nullptr};
|
||||
|
||||
GL::Texture2D* texture {nullptr};
|
||||
};
|
||||
|
||||
struct Parent
|
||||
{
|
||||
entt::entity entity{entt::null};
|
||||
};
|
||||
|
||||
struct Label
|
||||
{
|
||||
std::string content;
|
||||
|
||||
static constexpr std::size_t MAX_SIZE = 128;
|
||||
};
|
||||
|
||||
struct MagnumObject
|
||||
{
|
||||
Object3D* obj {nullptr};
|
||||
Rendering::Magnum::Drawable* drawable {nullptr};
|
||||
};
|
||||
}
|
||||
|
||||
#endif //CHOCOLATE_COMPONENTS_H
|
||||
40
src/MagnumDrawable.cpp
Normal file
40
src/MagnumDrawable.cpp
Normal file
@@ -0,0 +1,40 @@
|
||||
#include "MagnumDrawable.h"
|
||||
|
||||
#include <Magnum/SceneGraph/Camera.h>
|
||||
|
||||
#include "Components.h"
|
||||
|
||||
namespace Rendering::Magnum
|
||||
{
|
||||
void Drawable::draw(const Matrix4& transformationMatrix, SceneGraph::Camera3D& camera)
|
||||
{
|
||||
const auto mesh = _registry.try_get<Components::Mesh>(_entity);
|
||||
if (!mesh) return;
|
||||
|
||||
if (const auto material = _registry.try_get<Components::Material>(_entity))
|
||||
{
|
||||
material->_shader->
|
||||
setDiffuseColor(material->phongConfig->diffuse)
|
||||
.setAmbientColor(material->phongConfig->ambient)
|
||||
.setSpecularColor(material->phongConfig->specular)
|
||||
.setShininess(material->phongConfig->shininess)
|
||||
.setLightPositions({
|
||||
{camera.cameraMatrix().transformPoint({-3.0f, 10.0f, 10.0f}), 0.0f}
|
||||
})
|
||||
.setTransformationMatrix(transformationMatrix)
|
||||
.setNormalMatrix(transformationMatrix.normalMatrix())
|
||||
.setProjectionMatrix(camera.projectionMatrix())
|
||||
.draw(*mesh->mesh);
|
||||
|
||||
if (material->texture)
|
||||
{
|
||||
material->_shader->bindDiffuseTexture(*material->texture);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: Have a default rendering method
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
30
src/MagnumDrawable.h
Normal file
30
src/MagnumDrawable.h
Normal file
@@ -0,0 +1,30 @@
|
||||
#ifndef CHOCOLATE_DRAWABLE_H
|
||||
#define CHOCOLATE_DRAWABLE_H
|
||||
|
||||
#include <Magnum/GL/Mesh.h>
|
||||
#include <Magnum/SceneGraph/Drawable.h>
|
||||
|
||||
#include "Common.h"
|
||||
|
||||
#include <entt/entt.hpp>
|
||||
|
||||
namespace Rendering::Magnum
|
||||
{
|
||||
class Drawable : public SceneGraph::Drawable3D{
|
||||
public:
|
||||
explicit Drawable(
|
||||
Object3D* object,
|
||||
SceneGraph::DrawableGroup3D* group,
|
||||
entt::registry& registry,
|
||||
entt::entity entity
|
||||
): SceneGraph::Drawable3D{*object, group}, _registry(registry), _entity(entity) {}
|
||||
|
||||
private:
|
||||
void draw(const Matrix4& transformationMatrix, SceneGraph::Camera3D& camera) override;
|
||||
|
||||
entt::registry& _registry;
|
||||
entt::entity _entity;
|
||||
};
|
||||
}
|
||||
|
||||
#endif //CHOCOLATE_DRAWABLE_H
|
||||
16
src/Materials.h
Normal file
16
src/Materials.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#ifndef CHOCOLATE_MATERIALS_H
|
||||
#define CHOCOLATE_MATERIALS_H
|
||||
|
||||
#include <Magnum/Math/Color.h>
|
||||
|
||||
using namespace Magnum;
|
||||
|
||||
struct PhongMaterialConfig
|
||||
{
|
||||
Color4 ambient{1.0f, 1.0f, 1.0f};
|
||||
Color4 diffuse{1.0f, 1.0f, 1.0f};
|
||||
Color4 specular{1.0f, 1.0f, 1.0f};
|
||||
float shininess{0.0f};
|
||||
};
|
||||
|
||||
#endif //CHOCOLATE_MATERIALS_H
|
||||
5
src/Scene.cpp
Normal file
5
src/Scene.cpp
Normal file
@@ -0,0 +1,5 @@
|
||||
//
|
||||
// Created by lbmas on 1/4/2026.
|
||||
//
|
||||
|
||||
#include "Scene.h"
|
||||
11
src/Scene.h
Normal file
11
src/Scene.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#ifndef CHOCOLATE_SCENE_H
|
||||
#define CHOCOLATE_SCENE_H
|
||||
|
||||
|
||||
struct Scene
|
||||
{
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif //CHOCOLATE_SCENE_H
|
||||
215
src/UI.cpp
Normal file
215
src/UI.cpp
Normal file
@@ -0,0 +1,215 @@
|
||||
//
|
||||
// Created by lbmas on 1/5/2026.
|
||||
//
|
||||
|
||||
#include "UI.h"
|
||||
#include "Components.h"
|
||||
|
||||
#include <Magnum/GL/TextureFormat.h>
|
||||
#include <Magnum/GL/RenderbufferFormat.h>
|
||||
|
||||
#include <imgui.h>
|
||||
#include <Magnum/ImGuiIntegration/Context.hpp>
|
||||
#include <ImGuiFileDialog.h>
|
||||
|
||||
#include "SDL_stdinc.h"
|
||||
|
||||
namespace UI
|
||||
{
|
||||
// RENDER WINDOW
|
||||
RenderWindow::RenderWindow() : _framebuffer(NoCreate), _size(Vector2i{}), _position(Vector2i{})
|
||||
{
|
||||
}
|
||||
|
||||
RenderWindow::RenderWindow(const Vector2i& size, const Vector2i& position) : _framebuffer({{}, size}), _size(size), _position(position)
|
||||
{
|
||||
_renderTexture.setStorage(1, GL::TextureFormat::RGBA8, size);
|
||||
_depthStencil.setStorage(GL::RenderbufferFormat::Depth24Stencil8, size);
|
||||
|
||||
_framebuffer.attachTexture(GL::Framebuffer::ColorAttachment{0}, _renderTexture, 0);
|
||||
_framebuffer.attachRenderbuffer(GL::Framebuffer::BufferAttachment::DepthStencil, _depthStencil);
|
||||
}
|
||||
|
||||
GL::Framebuffer& RenderWindow::Framebuffer()
|
||||
{
|
||||
return _framebuffer;
|
||||
}
|
||||
|
||||
void RenderWindow::Resize(const Vector2i& size)
|
||||
{
|
||||
_renderTexture.setStorage(1, GL::TextureFormat::RGBA8, size);
|
||||
_depthStencil.setStorage(GL::RenderbufferFormat::Depth24Stencil8, size);
|
||||
}
|
||||
|
||||
void RenderWindow::SetPosition(const Vector2i& position)
|
||||
{
|
||||
_position = position;
|
||||
}
|
||||
|
||||
void RenderWindow::Draw()
|
||||
{
|
||||
ImGui::Begin("Scene Preview", nullptr, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoDecoration);
|
||||
|
||||
ImGui::SetWindowSize({static_cast<float>(_size.x()), static_cast<float>(_size.y())});
|
||||
ImGui::SetWindowPos({static_cast<float>(_position.x()), static_cast<float>(_position.y())});
|
||||
|
||||
ImGui::Text("%.3f ms/frame (%.1f FPS)",
|
||||
1000.0/Double(ImGui::GetIO().Framerate), Double(ImGui::GetIO().Framerate));
|
||||
|
||||
const ImTextureID textureId = _renderTexture.id();
|
||||
const ImVec2 previewSize = ImGui::GetContentRegionAvail();
|
||||
ImGui::Image(textureId, previewSize, ImVec2(0, 1), ImVec2(1, 0));
|
||||
|
||||
ImGui::End();
|
||||
}
|
||||
// END RENDER WINDOW
|
||||
|
||||
|
||||
// ENTITY LIST PANEL
|
||||
EntityListPanel::EntityListPanel()
|
||||
: _size({0, 0}), _position({0, 0}), _reg(nullptr), _importFunc(nullptr), _entitySelectedFunc(nullptr), _selectedEntity(entt::null)
|
||||
{}
|
||||
|
||||
EntityListPanel::EntityListPanel(Vector2i size, Vector2i position, entt::registry* reg, std::function<void(Containers::StringView)> importFunc, std::function<void(entt::entity)> entitySelectedFunc)
|
||||
: _size(size), _position(position), _selectedEntity(entt::null), _reg(reg), _importFunc(std::move(importFunc)), _entitySelectedFunc(std::move(entitySelectedFunc))
|
||||
{
|
||||
}
|
||||
|
||||
void EntityListPanel::Resize(const Vector2i& size)
|
||||
{
|
||||
_size = size;
|
||||
}
|
||||
|
||||
void EntityListPanel::SetPosition(const Vector2i& position)
|
||||
{
|
||||
_position = position;
|
||||
}
|
||||
|
||||
void EntityListPanel::Draw()
|
||||
{
|
||||
ImGui::Begin("Entities", nullptr, ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoCollapse);
|
||||
ImGui::SetWindowSize({(float)_size.x(), (float)_size.y()});
|
||||
ImGui::SetWindowPos({(float)_position.x(), (float)_position.y()});
|
||||
|
||||
if (ImGui::BeginMenuBar())
|
||||
{
|
||||
if (ImGui::BeginMenu("File"))
|
||||
{
|
||||
if (ImGui::MenuItem("Open"))
|
||||
{
|
||||
IGFD::FileDialogConfig config;
|
||||
config.path = ".";
|
||||
ImGuiFileDialog::Instance()->OpenDialog("ChooseFileDlgKey", "Open Object File", ".obj,.glb", config);
|
||||
}
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
ImGui::EndMenuBar();
|
||||
}
|
||||
|
||||
if (ImGuiFileDialog::Instance()->Display("ChooseFileDlgKey", ImGuiWindowFlags_NoCollapse, ImVec2(800, 600))) {
|
||||
if (ImGuiFileDialog::Instance()->IsOk()) {
|
||||
std::string absolutePath = ImGuiFileDialog::Instance()->GetFilePathName();
|
||||
Debug{} << "Opening file: " << Containers::String(absolutePath);
|
||||
_importFunc(absolutePath);
|
||||
}
|
||||
|
||||
ImGuiFileDialog::Instance()->Close();
|
||||
}
|
||||
|
||||
if (ImGui::BeginTable("EntityTable", 2, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg)) {
|
||||
// Define columns
|
||||
ImGui::TableSetupColumn("ID", ImGuiTableColumnFlags_WidthFixed, 40.0f);
|
||||
ImGui::TableSetupColumn("Label");
|
||||
ImGui::TableHeadersRow();
|
||||
|
||||
for (const auto& entity : _reg->view<entt::entity>()) {
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
// Create a selectable that spans the entire row
|
||||
char id[32];
|
||||
sprintf(id, "%u", entity);
|
||||
|
||||
bool isSelected = _selectedEntity == entity;
|
||||
if (ImGui::Selectable(id, isSelected, ImGuiSelectableFlags_SpanAllColumns)) {
|
||||
_selectedEntity = entity;
|
||||
_entitySelectedFunc(_selectedEntity);
|
||||
}
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
const auto* label = _reg->try_get<Components::Label>(entity);
|
||||
ImGui::Text("%s", label ? label->content.data() : "");
|
||||
}
|
||||
ImGui::EndTable();
|
||||
}
|
||||
|
||||
ImGui::End(); // ENTITIES
|
||||
}
|
||||
// END ENTITY LIST PANEL
|
||||
|
||||
|
||||
// ENTITY EDITOR WINDOW
|
||||
EntityEditorWindow::EntityEditorWindow()
|
||||
: _size({0, 0}), _position({0, 0}), _reg(nullptr), _selectedEntity(entt::null)
|
||||
{}
|
||||
|
||||
EntityEditorWindow::EntityEditorWindow(Vector2i size, Vector2i position, entt::registry* reg)
|
||||
: _size(size), _position(position), _reg(reg), _selectedEntity(entt::null)
|
||||
{}
|
||||
|
||||
void EntityEditorWindow::SetEntity(entt::entity entity)
|
||||
{
|
||||
_selectedEntity = entity;
|
||||
}
|
||||
|
||||
void EntityEditorWindow::Resize(const Vector2i& size)
|
||||
{
|
||||
_size = size;
|
||||
}
|
||||
|
||||
void EntityEditorWindow::SetPosition(const Vector2i& position)
|
||||
{
|
||||
_position = position;
|
||||
}
|
||||
|
||||
void EntityEditorWindow::Draw()
|
||||
{
|
||||
ImGui::Begin("Entity Editor", nullptr, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoCollapse);
|
||||
ImGui::SetWindowSize({(float)_size.x(), (float)_size.y()});
|
||||
ImGui::SetWindowPos({(float)_position.x(), (float)_position.y()});
|
||||
|
||||
if (_selectedEntity != entt::null)
|
||||
{
|
||||
if (auto* label = _reg->try_get<Components::Label>(_selectedEntity))
|
||||
{
|
||||
static char entityLabelBuffer[Components::Label::MAX_SIZE] = {};
|
||||
memcpy(entityLabelBuffer, label->content.data(), label->content.size());
|
||||
if (ImGui::InputText("Label", entityLabelBuffer, Components::Label::MAX_SIZE))
|
||||
{
|
||||
label->content = std::string(entityLabelBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
if (auto* transform = _reg->try_get<Components::Transform>(_selectedEntity))
|
||||
{
|
||||
ImGui::SliderFloat3("Translation", transform->translation.data(), -10, 10);
|
||||
ImGui::SliderFloat3("Scale", transform->scale.data(), -10, 10);
|
||||
|
||||
// Vector3 eulerDegrees = Vector3{transform->rotation.toEuler()} * (180.0f / M_PI);
|
||||
// if (ImGui::SliderFloat3("Rotation", eulerDegrees.data(), -180.0f, 180.0f)) {
|
||||
// // 3. If changed, convert Degrees -> Radians -> Quaternion
|
||||
// Vector3 eulerRadians = eulerDegrees * (M_PI / 180.0f);
|
||||
//
|
||||
// // We recreate the quaternion from the updated Euler angles
|
||||
// transform->rotation = Quaternion::rotation(Rad(eulerRadians.x()), Vector3::xAxis())
|
||||
// * Quaternion::rotation(Rad(eulerRadians.y()), Vector3::yAxis())
|
||||
// * Quaternion::rotation(Rad(eulerRadians.z()), Vector3::zAxis());
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
// END ENTITY EDITOR WINDOW
|
||||
}
|
||||
89
src/UI.h
Normal file
89
src/UI.h
Normal file
@@ -0,0 +1,89 @@
|
||||
//
|
||||
// Created by lbmas on 1/5/2026.
|
||||
//
|
||||
|
||||
#ifndef CHOCOLATE_UI_H
|
||||
#define CHOCOLATE_UI_H
|
||||
|
||||
#include <Magnum/GL/Texture.h>
|
||||
#include <Magnum/GL/Renderbuffer.h>
|
||||
#include <Magnum/GL/Framebuffer.h>
|
||||
|
||||
#include <entt/entt.hpp>
|
||||
|
||||
#include <functional>
|
||||
|
||||
using namespace Magnum;
|
||||
|
||||
namespace UI
|
||||
{
|
||||
class Component
|
||||
{
|
||||
public:
|
||||
virtual ~Component() = default;
|
||||
|
||||
virtual void Draw() = 0;
|
||||
virtual void Resize(const Vector2i& size) = 0;
|
||||
virtual void SetPosition(const Vector2i& position) = 0;
|
||||
};
|
||||
|
||||
class RenderWindow : public Component
|
||||
{
|
||||
public:
|
||||
RenderWindow();
|
||||
RenderWindow(const Vector2i& size, const Vector2i& position);
|
||||
|
||||
[[nodiscard]] GL::Framebuffer& Framebuffer();
|
||||
|
||||
void Draw() final;
|
||||
void Resize(const Vector2i& size) final;
|
||||
void SetPosition(const Vector2i& position) final;
|
||||
private:
|
||||
GL::Texture2D _renderTexture;
|
||||
GL::Renderbuffer _depthStencil;
|
||||
GL::Framebuffer _framebuffer;
|
||||
|
||||
Vector2i _size;
|
||||
Vector2i _position;
|
||||
};
|
||||
|
||||
class EntityListPanel : public Component
|
||||
{
|
||||
public:
|
||||
EntityListPanel();
|
||||
explicit EntityListPanel(Vector2i size, Vector2i position, entt::registry* reg, std::function<void(Containers::StringView)> importFunc, std::function<void(entt::entity)> entitySelectedFunc);
|
||||
|
||||
void Draw() final;
|
||||
void Resize(const Vector2i& size) final;
|
||||
void SetPosition(const Vector2i& position) final;
|
||||
private:
|
||||
Vector2i _size;
|
||||
Vector2i _position;
|
||||
|
||||
entt::registry* _reg;
|
||||
std::function<void(Containers::StringView)> _importFunc;
|
||||
std::function<void(entt::entity)> _entitySelectedFunc;
|
||||
entt::entity _selectedEntity;
|
||||
};
|
||||
|
||||
class EntityEditorWindow : public Component
|
||||
{
|
||||
public:
|
||||
EntityEditorWindow();
|
||||
explicit EntityEditorWindow(Vector2i size, Vector2i position, entt::registry* reg);
|
||||
|
||||
void SetEntity(entt::entity entity);
|
||||
|
||||
void Draw() final;
|
||||
void Resize(const Vector2i& size) final;
|
||||
void SetPosition(const Vector2i& position) final;
|
||||
private:
|
||||
Vector2i _size;
|
||||
Vector2i _position;
|
||||
entt::registry* _reg;
|
||||
entt::entity _selectedEntity;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif //CHOCOLATE_UI_H
|
||||
Reference in New Issue
Block a user