Compare commits
89 commits
fix/clang-
...
main
Author | SHA1 | Date | |
---|---|---|---|
4a7a220af8 | |||
a43243ca3f | |||
5d30a56e22 | |||
51e044065a | |||
b0caeded2a | |||
585d37b31b | |||
4cd258bcb6 | |||
052ac6dd5b | |||
b005857c31 | |||
9389dfe7fb | |||
40503239df | |||
552602f0af | |||
76fc5dd572 | |||
cd571d4a9d | |||
813e8a3a3a | |||
d6aa5fc91d | |||
bd2f74b120 | |||
af4ce09838 | |||
f7591a23f4 | |||
51990599a7 | |||
459b3b961d | |||
d58f8994aa | |||
c57e5a56ac | |||
ea8986b764 | |||
e36991e6de | |||
60ad7cdc70 | |||
638a009047 | |||
a102db0699 | |||
2b96a85b62 | |||
d9229ad912 | |||
6a814bd177 | |||
2d019878a5 | |||
b0ad9ff964 | |||
22c62bf5f9 | |||
d83e269432 | |||
65f0d3bb73 | |||
0b94aaffa7 | |||
026f97ad0b | |||
8720fdcebf | |||
46505a6c24 | |||
754b6361ad | |||
bf485e354a | |||
688c88f255 | |||
3998c4127a | |||
798732632a | |||
28010e9a92 | |||
9c071493c5 | |||
cd886aa8c9 | |||
2b27f5d82b | |||
9012869bf1 | |||
8094f0cf86 | |||
bd5196a9c9 | |||
dac89f64ce | |||
05f6fab1b8 | |||
d453982acf | |||
4ff69dea7c | |||
ecd2d7b8b6 | |||
49cd9fecf8 | |||
4a15c5c213 | |||
e02b208771 | |||
3791916a32 | |||
e85374b97e | |||
e4c59bb51f | |||
01d85accac | |||
e65b6b3f83 | |||
f9ce347ca0 | |||
d6b7c774bd | |||
8268a07e1b | |||
207cd48a7a | |||
44baac6a52 | |||
a56f11f2a4 | |||
3cc0801e8f | |||
3cc3da4dbe | |||
8970fa87a3 | |||
52bf0f22f0 | |||
c4b9bd8359 | |||
f457e5ae19 | |||
61c898f47f | |||
c76d6e8019 | |||
5f1c65d72d | |||
60944b9d49 | |||
5bcb4cfdd3 | |||
5748e0a496 | |||
a88aa739b1 | |||
b25ea41096 | |||
a54885b02e | |||
5d1862f493 | |||
8b3990959b | |||
ff2a2d3bb3 |
263 changed files with 8461 additions and 2875 deletions
151
.drone.yml
151
.drone.yml
|
@ -1,55 +1,140 @@
|
||||||
|
---
|
||||||
|
kind: pipeline
|
||||||
|
type: exec
|
||||||
|
name: amd64 — msvc
|
||||||
|
trigger:
|
||||||
|
branch:
|
||||||
|
- main
|
||||||
|
platform:
|
||||||
|
os: windows
|
||||||
|
arch: amd64
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: unit tests
|
||||||
|
shell: powershell
|
||||||
|
commands:
|
||||||
|
- ./tools/ci/amd64/msvc/unit_tests.ps1
|
||||||
|
|
||||||
|
---
|
||||||
kind: pipeline
|
kind: pipeline
|
||||||
type: docker
|
type: docker
|
||||||
name: clang format
|
name: amd64 — gcc
|
||||||
clone:
|
|
||||||
recursive: true
|
|
||||||
submodule_update_remote: true
|
|
||||||
|
|
||||||
trigger:
|
trigger:
|
||||||
branch:
|
branch:
|
||||||
- main
|
- main
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
|
- name: unit tests
|
||||||
|
image: amd64_gcc_unit_tests:latest
|
||||||
|
pull: if-not-exists
|
||||||
|
commands:
|
||||||
|
- ./tools/ci/amd64/gcc/unit_tests.sh
|
||||||
|
|
||||||
|
- name: valgrind
|
||||||
|
image: amd64_gcc_valgrind:latest
|
||||||
|
pull: if-not-exists
|
||||||
|
commands:
|
||||||
|
- ./tools/ci/amd64/gcc/valgrind.sh
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: pipeline
|
||||||
|
type: docker
|
||||||
|
name: amd64 — clang
|
||||||
|
trigger:
|
||||||
|
branch:
|
||||||
|
- main
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: code coverage
|
||||||
|
image: amd64_clang_coverage:latest
|
||||||
|
pull: if-not-exists
|
||||||
|
environment:
|
||||||
|
CODECOV_TOKEN:
|
||||||
|
from_secret: CODECOV_TOKEN
|
||||||
|
commands:
|
||||||
|
- ./tools/ci/amd64/clang/coverage.sh
|
||||||
|
|
||||||
|
- name: leak sanitizer
|
||||||
|
image: amd64_clang_lsan:latest
|
||||||
|
pull: if-not-exists
|
||||||
|
commands:
|
||||||
|
- ./tools/ci/amd64/clang/lsan.sh
|
||||||
|
|
||||||
|
- name: memory sanitizer
|
||||||
|
image: amd64_clang_msan:latest
|
||||||
|
pull: if-not-exists
|
||||||
|
commands:
|
||||||
|
- ./tools/ci/amd64/clang/msan.sh
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: pipeline
|
||||||
|
type: docker
|
||||||
|
name: static analysis
|
||||||
|
trigger:
|
||||||
|
branch:
|
||||||
|
- main
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: clang tidy
|
||||||
|
image: clang_tidy:latest
|
||||||
|
pull: if-not-exists
|
||||||
|
privileged: true
|
||||||
|
commands:
|
||||||
|
- ./tools/ci/static_analysis/clang_tidy.sh
|
||||||
|
|
||||||
- name: clang format
|
- name: clang format
|
||||||
image: clang_format:latest
|
image: clang_format:latest
|
||||||
pull: if-not-exists
|
pull: if-not-exists
|
||||||
commands:
|
commands:
|
||||||
- |
|
- ./tools/ci/static_analysis/clang_format.sh
|
||||||
set -e
|
|
||||||
clang-format --version
|
|
||||||
has_fomatting_issues=0
|
|
||||||
|
|
||||||
for file in $(find ./modules -name '*.?pp'); do
|
|
||||||
echo "Checking format for $file"
|
|
||||||
if ! clang-format --dry-run --Werror "$file"; then
|
|
||||||
echo "❌ Formatting issue detected in $file"
|
|
||||||
has_fomatting_issues=1
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
if [ "$has_fomatting_issues" -eq 0 ]; then
|
|
||||||
echo "✅ All files are properly formatted! Well done! ^~^"
|
|
||||||
fi
|
|
||||||
|
|
||||||
exit ${has_fomatting_issues}
|
|
||||||
---
|
---
|
||||||
|
|
||||||
kind: pipeline
|
kind: pipeline
|
||||||
type: docker
|
type: docker
|
||||||
name: static analysis
|
name: documentation — development
|
||||||
clone:
|
node:
|
||||||
recursive: true
|
environment: ryali
|
||||||
submodule_update_remote: true
|
|
||||||
|
|
||||||
trigger:
|
trigger:
|
||||||
branch:
|
branch:
|
||||||
- main
|
- main
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: static_analysis
|
- name: build and deploy
|
||||||
image: static_analysis:latest
|
image: documentation:latest
|
||||||
pull: if-not-exists
|
pull: if-not-exists
|
||||||
privileged: true
|
|
||||||
commands:
|
commands:
|
||||||
- git submodule update --init --recursive
|
- pwd
|
||||||
- conan build . -s build_type=Release -o enable_static_analysis=True --build=missing
|
- cd docs
|
||||||
|
- mkdir generated
|
||||||
|
- touch generated/changelogs.rst
|
||||||
|
- touch generated/api.rst
|
||||||
|
- sphinx-build -M html . .
|
||||||
|
|
||||||
|
- rm -rf /light_docs_dev/*
|
||||||
|
- mv ./html/* /light_docs_dev/
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
kind: pipeline
|
||||||
|
type: docker
|
||||||
|
name: documentation — production
|
||||||
|
node:
|
||||||
|
environment: ryali
|
||||||
|
trigger:
|
||||||
|
event:
|
||||||
|
- tag
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: build and deploy
|
||||||
|
image: documentation:latest
|
||||||
|
pull: if-not-exists
|
||||||
|
commands:
|
||||||
|
- pwd
|
||||||
|
- cd docs
|
||||||
|
- mkdir generated
|
||||||
|
- touch generated/changelogs.rst
|
||||||
|
- touch generated/api.rst
|
||||||
|
- sphinx-build -M html . .
|
||||||
|
|
||||||
|
- rm -rf /light_docs/*
|
||||||
|
- mv ./html/* /light_docs/
|
||||||
|
|
36
.github/ISSUE_TEMPLATE/bug_report.md
vendored
36
.github/ISSUE_TEMPLATE/bug_report.md
vendored
|
@ -1,36 +0,0 @@
|
||||||
---
|
|
||||||
name: Bug report
|
|
||||||
about: Create a report to help us improve
|
|
||||||
title: "[BUG]: "
|
|
||||||
labels: ''
|
|
||||||
assignees: Light3039
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Describe the bug**
|
|
||||||
A clear and concise description of what the bug is.
|
|
||||||
|
|
||||||
**Expected behavior**
|
|
||||||
A clear and concise description of what you expected to happen.
|
|
||||||
|
|
||||||
**To Reproduce**
|
|
||||||
Steps to reproduce the behavior:
|
|
||||||
1. Make projects "..."
|
|
||||||
2. Build projects "..."
|
|
||||||
3. Run project (Mirror/Sandbox) "..."
|
|
||||||
4. Do "..."
|
|
||||||
5. See bug "..."
|
|
||||||
|
|
||||||
**System (you can omit any of the fields except OS and Console's debug output):**
|
|
||||||
- OS: [e.g. Manjaro Linux v21.1.0]
|
|
||||||
- GPU: [e.g. NVIDIA GeForce GTX 1050 Ti Mobile]
|
|
||||||
- CPU: [e.g. Intel i7-7700HQ (8) @ 3.800GHz]
|
|
||||||
|
|
||||||
- Console's debug output (omit if bug occurs before running the program):
|
|
||||||
|
|
||||||
**Screenshots**
|
|
||||||
If applicable, add screenshots to help explain your problem.
|
|
||||||
If possible add screen shot of console's debug output and neofetch.
|
|
||||||
|
|
||||||
**Additional context**
|
|
||||||
Add any other context about the problem here.
|
|
4
.gitmodules
vendored
4
.gitmodules
vendored
|
@ -1,4 +0,0 @@
|
||||||
[submodule "external/imgui"]
|
|
||||||
path = external/imgui
|
|
||||||
url = https://github.com/ocornut/imgui
|
|
||||||
branch = docking
|
|
|
@ -1,30 +1,43 @@
|
||||||
cmake_minimum_required(VERSION 3.14)
|
cmake_minimum_required(VERSION 3.14)
|
||||||
project(Light)
|
project(Light)
|
||||||
set(CMAKE_CXX_STANDARD 23)
|
set(CMAKE_CXX_STANDARD 23)
|
||||||
|
set(CMAKE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/tools/cmake)
|
||||||
|
|
||||||
include(${CMAKE_CURRENT_SOURCE_DIR}/tools/cmake/macros.cmake)
|
include(CheckCXXSourceCompiles)
|
||||||
|
include(${CMAKE_DIR}/functions.cmake)
|
||||||
|
include(${CMAKE_DIR}/definitions.cmake)
|
||||||
|
include(${CMAKE_DIR}/dependencies.cmake)
|
||||||
|
|
||||||
add_option(ENABLE_STATIC_ANALYSIS "Enables clang-tidy static analysis")
|
add_option(ENABLE_UNIT_TESTS "Enables the building of the unit test modules")
|
||||||
|
add_option(ENABLE_FUZZ_TESTS "Enables the building of the fuzz test modules")
|
||||||
|
|
||||||
|
add_option(ENABLE_STATIC_ANALYSIS "Makes clang-tidy checks mandatory for compilation")
|
||||||
if (ENABLE_STATIC_ANALYSIS)
|
if (ENABLE_STATIC_ANALYSIS)
|
||||||
set(CMAKE_CXX_CLANG_TIDY "clang-tidy;--warnings-as-errors=*;--allow-no-checks")
|
set(CMAKE_CXX_CLANG_TIDY "clang-tidy;--warnings-as-errors=*;--allow-no-checks")
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
if(WIN32)
|
add_option(ENABLE_LLVM_COVERAGE "Enables the code coverage instrumentation for clang")
|
||||||
add_compile_definitions(LIGHT_PLATFORM_WINDOWS)
|
if(ENABLE_LLVM_COVERAGE)
|
||||||
elseif(UNIX)
|
if (NOT "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
|
||||||
add_compile_definitions(LIGHT_PLATFORM_LINUX)
|
message(FATAL_ERROR "ENABLE_LLVM_COVERAGE only supports the clang compiler")
|
||||||
endif()
|
endif ()
|
||||||
|
|
||||||
find_package(glfw3 REQUIRED)
|
# Check for libc++
|
||||||
find_package(glm REQUIRED)
|
check_cxx_source_compiles("
|
||||||
find_package(spdlog REQUIRED)
|
#include <string>
|
||||||
find_package(stb REQUIRED)
|
#ifdef _LIBCPP_VERSION
|
||||||
find_package(yaml-cpp REQUIRED)
|
int main() { return 0; }
|
||||||
find_package(EnTT REQUIRED)
|
#else
|
||||||
find_package(opengl_system REQUIRED)
|
#error Not using libc++
|
||||||
find_package(nlohmann_json REQUIRED)
|
#endif
|
||||||
find_package(lz4 REQUIRED)
|
" USING_LIBCXX)
|
||||||
|
if(NOT USING_LIBCXX)
|
||||||
|
message(FATAL_ERROR "ENABLE_LLVM_COVERAGE requires libc++, please compile with -stdlib=libc++")
|
||||||
|
endif()
|
||||||
|
|
||||||
add_subdirectory(./modules)
|
add_compile_options(-fprofile-instr-generate -fcoverage-mapping)
|
||||||
add_subdirectory(./external)
|
add_link_options(-fprofile-instr-generate -fcoverage-mapping)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/modules)
|
||||||
|
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/external/glad)
|
||||||
|
|
|
@ -1,2 +1,6 @@
|
||||||
# Light
|
# Light
|
||||||
See docs.light7734.com for a comprehensive project documentation
|
See docs.light7734.com for a comprehensive project documentation
|
||||||
|
|
||||||
|
<!---FUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUCK
|
||||||
|
MEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
|
||||||
|
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA!!!!!!!!-->
|
||||||
|
|
23
conanfile.py
23
conanfile.py
|
@ -11,26 +11,29 @@ class LightRecipe(ConanFile):
|
||||||
generators = "CMakeDeps"
|
generators = "CMakeDeps"
|
||||||
|
|
||||||
options = {
|
options = {
|
||||||
|
"enable_unit_tests": [True, False],
|
||||||
|
"enable_fuzz_tests": [True, False],
|
||||||
|
"enable_llvm_coverage": [True, False],
|
||||||
"enable_static_analysis": [True, False],
|
"enable_static_analysis": [True, False],
|
||||||
|
"use_mold": [True, False],
|
||||||
"export_compile_commands": [True, False],
|
"export_compile_commands": [True, False],
|
||||||
}
|
}
|
||||||
|
|
||||||
default_options = {
|
default_options = {
|
||||||
"export_compile_commands": True,
|
"enable_unit_tests": True,
|
||||||
|
"enable_fuzz_tests": False,
|
||||||
|
"enable_llvm_coverage": False,
|
||||||
"enable_static_analysis": False,
|
"enable_static_analysis": False,
|
||||||
|
"use_mold": False,
|
||||||
|
"export_compile_commands": True,
|
||||||
}
|
}
|
||||||
|
|
||||||
def requirements(self):
|
def requirements(self):
|
||||||
self.requires("gtest/1.16.0")
|
self.requires("imgui/1.92.0-docking")
|
||||||
self.requires("entt/3.15.0")
|
self.requires("entt/3.15.0")
|
||||||
self.requires("glfw/3.4")
|
self.requires("glfw/3.4")
|
||||||
self.requires("glm/1.0.1")
|
|
||||||
self.requires("spdlog/1.15.3")
|
|
||||||
self.requires("spirv-cross/1.4.313.0")
|
|
||||||
self.requires("stb/cci.20240531")
|
self.requires("stb/cci.20240531")
|
||||||
self.requires("volk/1.3.296.0")
|
|
||||||
self.requires("yaml-cpp/0.8.0")
|
self.requires("yaml-cpp/0.8.0")
|
||||||
self.requires("nlohmann_json/3.12.0")
|
|
||||||
self.requires("lz4/1.10.0")
|
self.requires("lz4/1.10.0")
|
||||||
|
|
||||||
def layout(self):
|
def layout(self):
|
||||||
|
@ -41,7 +44,13 @@ class LightRecipe(ConanFile):
|
||||||
|
|
||||||
tc.variables["CMAKE_BUILD_TYPE"] = self.settings.build_type
|
tc.variables["CMAKE_BUILD_TYPE"] = self.settings.build_type
|
||||||
|
|
||||||
|
if self.options.use_mold:
|
||||||
|
tc.cache_variables["CMAKE_LINKER_TYPE"] = "MOLD"
|
||||||
|
|
||||||
tc.cache_variables["CMAKE_EXPORT_COMPILE_COMMANDS"] = self.options.export_compile_commands
|
tc.cache_variables["CMAKE_EXPORT_COMPILE_COMMANDS"] = self.options.export_compile_commands
|
||||||
|
tc.cache_variables["ENABLE_UNIT_TESTS"] = self.options.enable_unit_tests
|
||||||
|
tc.cache_variables["ENABLE_FUZZ_TESTS"] = self.options.enable_fuzz_tests
|
||||||
|
tc.cache_variables["ENABLE_LLVM_COVERAGE"] = self.options.enable_llvm_coverage
|
||||||
tc.cache_variables["ENABLE_STATIC_ANALYSIS"] = self.options.enable_static_analysis
|
tc.cache_variables["ENABLE_STATIC_ANALYSIS"] = self.options.enable_static_analysis
|
||||||
|
|
||||||
repo = git.Repo(search_parent_directories=True)
|
repo = git.Repo(search_parent_directories=True)
|
||||||
|
|
3
docs/.gitignore
vendored
Normal file
3
docs/.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
_build/
|
||||||
|
generated/
|
||||||
|
|
|
@ -1,62 +1,72 @@
|
||||||
Asset Management
|
Asset Management
|
||||||
===================================================================================================
|
===================================================================================================
|
||||||
Layout
|
|
||||||
|
On Disk (file) Layout
|
||||||
---------------------------------------------------------------------------------------------------
|
---------------------------------------------------------------------------------------------------
|
||||||
{version} | 4 bytes, ie. uint32_t
|
|
||||||
{general metadata} | sizeof(AssetMetadata)
|
.. code-block:: md
|
||||||
{specialized metadata} | sizeof(XXXAssetMetadata), eg. TextureAssetMetadata
|
|
||||||
{n} | 4 bytes, ie. uint32_t
|
{version} | 4 bytes, ie. uint32_t
|
||||||
{blob_0...n metadata} | n * sizeof(BlobMetadata)
|
{general metadata} | sizeof(AssetMetadata)
|
||||||
{blob_0...n data} | variable size based on actual data
|
{specialized metadata} | sizeof(XXXAssetMetadata), eg. TextureAssetMetadata
|
||||||
{end marker} | 8 byte, ie size_t for marking the END
|
{n} | 4 bytes, ie. uint32_t
|
||||||
|
{blob_0...n metadata} | n * sizeof(BlobMetadata)
|
||||||
|
{blob_0...n data} | variable size based on actual data
|
||||||
|
{end marker} | 8 byte, ie size_t for marking the END
|
||||||
|
|
||||||
Sections
|
Sections
|
||||||
---------------------------------------------------------------------------------------------------
|
---------------------------------------------------------------------------------------------------
|
||||||
version -> The version of the asset for forward compatibility
|
|
||||||
general metadata -> Common asset metadata such as file-path, asset-type, creator, etc.
|
.. code-block:: md
|
||||||
specialized metadata -> Metadata specific to the asset, eg. texture dimensions for Textures.
|
|
||||||
n -> The number of blobs.
|
version -> The version of the asset for forward compatibility
|
||||||
blob_0...n metadata -> Metadata specifying how the actual data is packed, required for unpacking.
|
general metadata -> Common asset metadata such as file-path, asset-type, creator, etc.
|
||||||
blob_0...n data -> The actual data, packed and compressed to be reacdy for direct engine consumption.
|
specialized metadata -> Metadata specific to the asset, eg. texture dimensions for Textures.
|
||||||
|
n -> The number of blobs.
|
||||||
|
blob_0...n metadata -> Metadata specifying how the actual data is packed, required for unpacking.
|
||||||
|
blob_0...n data -> The actual data, packed and compressed to be reacdy for direct engine consumption.
|
||||||
|
|
||||||
Loading
|
Loading
|
||||||
---------------------------------------------------------------------------------------------------
|
---------------------------------------------------------------------------------------------------
|
||||||
Each `Loader` has ONE OR MORE supported input file types (detected via the file extension): eg. StbLoader -> Can read in .jpg, .png, .bmp, etc.... files
|
Loading pre-baked asset files (like .png files) for baking:
|
||||||
|
|
||||||
Each `Loader` has ONLY ONE supported output asset type:
|
|
||||||
|
Each **Loader** has ONE OR MORE supported input file types (detected via the file extension): eg. StbLoader -> Can read in .jpg, .png, .bmp, etc.... files
|
||||||
|
|
||||||
|
Each **Loader** has ONLY ONE supported output asset type:
|
||||||
eg. StbLoader -> outputs TextureAsset
|
eg. StbLoader -> outputs TextureAsset
|
||||||
|
|
||||||
Multiple `Loader`s MAY have as output the same asset type:
|
Multiple **Loader**\s MAY have as output the same asset type:
|
||||||
eg. StbLoader -> outputs TextureAsset
|
eg. StbLoader -> outputs TextureAsset
|
||||||
eg. SomeOtherImgLoader -> outputs TextureAsset
|
eg. SomeOtherImgLoader -> outputs TextureAsset
|
||||||
|
|
||||||
Multiple `Loader`s SHOULD NOT have as input same extension types
|
Multiple **Loader**\s SHOULD NOT have as input same extension types
|
||||||
eg. .jpg, .png -> if supported, should only be supported by 1 `Loader` class
|
eg. .jpg, .png -> if supported, should only be supported by 1 **Loader** class
|
||||||
|
|
||||||
Each `Loader` SHOULD read and turn the data from a file (eg. .png for textures) into something
|
Each **Loader** SHOULD read and turn the data from a file (eg. .png for textures) into something
|
||||||
understandable by a `Packer` (not the engine itself).
|
understandable by a **Packer** (not the engine itself).
|
||||||
|
|
||||||
A `Loader` SHOULD NOT be responsible for packing the parsed file data into asset data,
|
A **Loader** SHOULD NOT be responsible for packing the parsed file data into asset data,
|
||||||
as that implies direct understanding of the layout required by the engine.
|
as that implies direct understanding of the layout required by the engine.
|
||||||
|
|
||||||
And if that layout changes, ALL `Loader`s should change accordingly;
|
And if that layout changes, ALL **Loader**s should change accordingly;
|
||||||
which makes a class that's responsible for reading files dependant on the engine's (potentially frequent) internal changes.
|
which makes a class that's responsible for reading files dependant on the engine's (potentially frequent) internal changes.
|
||||||
The logic is to reduce many-to-one dependency into a one-to-one dependency by redirecting the packing process to `Packer` classes
|
The logic is to reduce many-to-one dependency into a one-to-one dependency by redirecting the packing process to **Packer** classes
|
||||||
|
|
||||||
Packing
|
Packing
|
||||||
---------------------------------------------------------------------------------------------------
|
---------------------------------------------------------------------------------------------------
|
||||||
Each `Packer` is responsible for packing ONLY ONE asset type:
|
Each **Packer** is responsible for packing ONLY ONE asset type:
|
||||||
eg. TexturePacker for packing texture assets from parsed image files.
|
eg. TexturePacker for packing texture assets from parsed image files.
|
||||||
eg. ModelPacker for packing model assets from parsed model files.
|
eg. ModelPacker for packing model assets from parsed model files.
|
||||||
|
|
||||||
Each `Packer` will output ONE OR MORE blobs of data,
|
Each **Packer** will output ONE OR MORE blobs of data,
|
||||||
and for EACH blob of data, it'll write a BlobMetadata, AFTER the specialized metadata (eg. TextureAssetMetadata)
|
and for EACH blob of data, it'll write a BlobMetadata, AFTER the specialized metadata (eg. TextureAssetMetadata)
|
||||||
|
|
||||||
A `Packer` will make use of the `Compressor` classes to compress the data,
|
A **Packer** will make use of the **Compressor** classes to compress the data,
|
||||||
and lay it out in a way that is suitable for the engine's consumption.
|
and lay it out in a way that is suitable for the engine's consumption.
|
||||||
|
|
||||||
Unpacking
|
Unpacking
|
||||||
---------------------------------------------------------------------------------------------------
|
---------------------------------------------------------------------------------------------------
|
||||||
A `Parser` is responsible for parsing ONLY ONE asset type:
|
A **Parser** is responsible for parsing ONLY ONE asset type:
|
||||||
eg. TextureParser for parsing texture assets for direct engine consumption.
|
eg. TextureParser for parsing texture assets for direct engine consumption.
|
||||||
eg. ModelParser for parsing model assets for direct engine consumption.
|
eg. ModelParser for parsing model assets for direct engine consumption.
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
Resource Management
|
.. architecture/resources
|
||||||
|
|
||||||
|
Resource Management
|
||||||
===================================================================================================
|
===================================================================================================
|
||||||
|
|
||||||
|
|
27
docs/conf.py
Normal file
27
docs/conf.py
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
# Configuration file for the Sphinx documentation builder.
|
||||||
|
#
|
||||||
|
# For the full list of built-in configuration values, see the documentation:
|
||||||
|
# https://www.sphinx-doc.org/en/master/usage/configuration.html
|
||||||
|
|
||||||
|
# -- Project information -----------------------------------------------------
|
||||||
|
# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
|
||||||
|
|
||||||
|
project = 'light'
|
||||||
|
copyright = '2025, light7734'
|
||||||
|
author = 'light7734'
|
||||||
|
|
||||||
|
# -- General configuration ---------------------------------------------------
|
||||||
|
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
|
||||||
|
|
||||||
|
extensions = []
|
||||||
|
|
||||||
|
templates_path = ['_templates']
|
||||||
|
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# -- Options for HTML output -------------------------------------------------
|
||||||
|
# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output
|
||||||
|
|
||||||
|
html_theme = 'sphinx_rtd_theme'
|
||||||
|
html_static_path = ['_static']
|
68
docs/generate_changelog.py
Normal file
68
docs/generate_changelog.py
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
from git import Repo
|
||||||
|
import re
|
||||||
|
|
||||||
|
repo = Repo(search_parent_directories=True)
|
||||||
|
assert not repo.bare
|
||||||
|
|
||||||
|
file_path = "generated/changelog.rst"
|
||||||
|
|
||||||
|
messages = []
|
||||||
|
short_shas = []
|
||||||
|
hex_shas = []
|
||||||
|
logs = []
|
||||||
|
|
||||||
|
remote_url = "https://git.light7734.com/light7734/light/commit"
|
||||||
|
def format_log(commit_type, message, major, minor, patch, short_sha, hex_sha):
|
||||||
|
href = f"{remote_url}/{hex_sha}"
|
||||||
|
version = f"{major}.{minor}.{patch}-kitten+{short_sha}";
|
||||||
|
link = f"`{version} <{remote_url}/{hex_sha}>`__"
|
||||||
|
return f"| **{message}** ({link})"
|
||||||
|
|
||||||
|
for commit in repo.iter_commits():
|
||||||
|
messages.append(commit.summary)
|
||||||
|
short_shas.append(repo.git.rev_parse(commit.hexsha, short=5))
|
||||||
|
hex_shas.append(commit.hexsha)
|
||||||
|
|
||||||
|
ver_major = 0
|
||||||
|
ver_minor = 0
|
||||||
|
ver_patch = 0
|
||||||
|
|
||||||
|
idx = len(messages)
|
||||||
|
for message in reversed(messages):
|
||||||
|
idx = idx - 1;
|
||||||
|
|
||||||
|
commit_type = re.match("^(feat|fix|refactor|perf|build|asset|test|chore|ci|docs)", message)
|
||||||
|
if not commit_type:
|
||||||
|
continue
|
||||||
|
|
||||||
|
match commit_type.group(0):
|
||||||
|
case "feat":
|
||||||
|
ver_minor = ver_minor + 1
|
||||||
|
ver_patch = 0
|
||||||
|
|
||||||
|
case "fix":
|
||||||
|
ver_patch = ver_patch + 1
|
||||||
|
|
||||||
|
case "refactor":
|
||||||
|
ver_patch = ver_patch + 1
|
||||||
|
|
||||||
|
case "perf":
|
||||||
|
ver_patch = ver_patch + 1
|
||||||
|
|
||||||
|
case "build":
|
||||||
|
ver_patch = ver_patch + 1
|
||||||
|
|
||||||
|
case "asset":
|
||||||
|
ver_patch = ver_patch + 1
|
||||||
|
|
||||||
|
logs.append(format_log(commit_type, message, ver_major, ver_minor, ver_patch, short_shas[idx], hex_shas[idx]))
|
||||||
|
|
||||||
|
with open(file_path, "w") as f:
|
||||||
|
f.write(".. changelogs\n\n\n")
|
||||||
|
f.write("Changelogs\n")
|
||||||
|
f.write("==================================================\n\n")
|
||||||
|
|
||||||
|
f.write("KITTEN\n")
|
||||||
|
f.write("--------------------------------------------------\n\n")
|
||||||
|
for log in reversed(logs):
|
||||||
|
f.write(log + '\n')
|
10
docs/guidelines/conventions.rst
Normal file
10
docs/guidelines/conventions.rst
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
.. guidelines/conventions
|
||||||
|
|
||||||
|
Coding Conventions
|
||||||
|
===================================================================================================
|
||||||
|
Any line of code added to the engine, must abide by following conventions.
|
||||||
|
They may seem arbitrary, and sometimes they are. But to achieve **consistency**, which is not an arbitrary goal, is to
|
||||||
|
follow these guidelines.
|
||||||
|
|
||||||
|
AAA
|
||||||
|
--------------------
|
147
docs/guidelines/development.rst
Normal file
147
docs/guidelines/development.rst
Normal file
|
@ -0,0 +1,147 @@
|
||||||
|
.. guidelines/development
|
||||||
|
|
||||||
|
Development
|
||||||
|
===================================================================================================
|
||||||
|
As a solo-project, I am not only the **developer**, but also the **manager**.
|
||||||
|
Therefore there is a need, if this project is to succeed, to have a development plan.
|
||||||
|
|
||||||
|
Such a plan should:
|
||||||
|
|
||||||
|
- Define a way to **distribute work** (across time, since there's only 1 developer).
|
||||||
|
- Define what is a **unit of work** (cycles).
|
||||||
|
- Provide a way to **track productivity**, which helps projecting the future and **detecting patterns** early on.
|
||||||
|
- Provide a **pipeline** for the work to go through and **minimize ambiguity**.
|
||||||
|
|
||||||
|
These are the **management** aspects of the project, which help the development goals to be more **pragmatic**
|
||||||
|
---by pulling my mind out of its **engineering dreamland**, and make it focus on the **broader picture**.
|
||||||
|
|
||||||
|
Cycle
|
||||||
|
---------------------------------------------------------------------------------------------------
|
||||||
|
A cycle is one **step** in development, one cycle = one ticket, and it consists of 4 stages:
|
||||||
|
|
||||||
|
1 - Make it known
|
||||||
|
- Write the commit message.
|
||||||
|
- This limits the **scope of changes** and gives you a very specific **goal** to work towards.
|
||||||
|
- If something outside of this scope really bothers you, fix and stash for a future cycle.
|
||||||
|
- Make a ticket if stash-fix is implausible ---**DO NOT** write **todo** comments.
|
||||||
|
- The message should follow the project's **commit message specifications**.
|
||||||
|
|
||||||
|
- Make a ticket.
|
||||||
|
- Version control (git) is a **development-tool**, not a **management-tool**.
|
||||||
|
- Provide a very brief description ---This may be used in the commit message's body.
|
||||||
|
|
||||||
|
2 - Make it work
|
||||||
|
- Write high-level tests that confirms the cycle's requirements are met.
|
||||||
|
- That is, specify requirements in a programming language instead of English.
|
||||||
|
- You're done when all the tests pass.
|
||||||
|
- Preferably write the tests first, but it's okay to start with the interface.
|
||||||
|
- Tests may not be necessary depending on the requirements and commit type.
|
||||||
|
|
||||||
|
- "Make it work" doesn't mean liberally producing shit code, you should:
|
||||||
|
- Follow project's **conventions**.
|
||||||
|
- Follow **best practices** and **proven swe principles**.
|
||||||
|
- Enable **warnings as errors**.
|
||||||
|
- Enable **static analysis**.
|
||||||
|
- Don't break any pre-existing-tests.
|
||||||
|
- Have the over-all picture in mind.
|
||||||
|
|
||||||
|
3 - Make it right
|
||||||
|
- Test driven refactoring
|
||||||
|
- Now you have a better picture of how things relate and work.
|
||||||
|
- Switch to a TDD-style development to do the refactoring while following swe best-practices and proven-principles.
|
||||||
|
|
||||||
|
4 - Make it fast
|
||||||
|
- This is an engine, at the end of the day, **performance** is king.
|
||||||
|
- Get a performance and/or memory profile and try to alleviate the bottlenecks.
|
||||||
|
- Avoid premature optimizations, be certain what you change has performance benefits.
|
||||||
|
|
||||||
|
|
||||||
|
Sprint
|
||||||
|
---------------------------------------------------------------------------------------------------
|
||||||
|
A sprint is the collection of all the finished cycles in one week.
|
||||||
|
It's meant to provide insight on development speed and help projecting the future.
|
||||||
|
|
||||||
|
|
||||||
|
Commit Message Specification
|
||||||
|
---------------------------------------------------------------------------------------------------
|
||||||
|
The project follows the `Conventional Commits Specification <https://www.conventionalcommits.org/en/v1.0.0-beta.4>`_.
|
||||||
|
|
||||||
|
.. code-block:: md
|
||||||
|
|
||||||
|
<type>[optional scope]: <description>
|
||||||
|
|
||||||
|
[optional body]
|
||||||
|
|
||||||
|
[optional footer]
|
||||||
|
|
||||||
|
With the following commit types:
|
||||||
|
|
||||||
|
- feat
|
||||||
|
- For adding a new feature.
|
||||||
|
- Causes a **minor** bump in version.
|
||||||
|
|
||||||
|
- fix
|
||||||
|
- For changes that fix one or more bug.
|
||||||
|
- Causes a **patch** bump in version.
|
||||||
|
|
||||||
|
- refactor
|
||||||
|
- For non feat/fix changes that improve the implementation and/or the interface.
|
||||||
|
- Causes a **patch** bump in version.
|
||||||
|
|
||||||
|
- perf
|
||||||
|
- For changes that (hopefully) improve the performance.
|
||||||
|
- Causes a **patch** bump in version.
|
||||||
|
|
||||||
|
- build
|
||||||
|
- For changes that affect the build system or external dependencies.
|
||||||
|
- Causes a **patch** bump in version.
|
||||||
|
|
||||||
|
- asset
|
||||||
|
- For changes to the files under the ``/data`` directory.
|
||||||
|
- Causes a **patch** bump in version.
|
||||||
|
|
||||||
|
- test
|
||||||
|
- For adding missing tests or correcting the existing tests.
|
||||||
|
- Does not affect the version.
|
||||||
|
|
||||||
|
- chore
|
||||||
|
- For releases, .gitignore changes, deleting unused files, etc.
|
||||||
|
- Does not affect the version.
|
||||||
|
|
||||||
|
- ci
|
||||||
|
- For changes to our CI configuration files and scripts, including files under ``/tools/ci``.
|
||||||
|
- Does not affect the version.
|
||||||
|
|
||||||
|
- docs
|
||||||
|
- For changes to the documentations.
|
||||||
|
- Does not affect the version.
|
||||||
|
|
||||||
|
Semantic Versioning
|
||||||
|
---------------------------------------------------------------------------------------------------
|
||||||
|
Coupled with conventional commit style messages, we can automajically version the project following
|
||||||
|
the **Semantic Versioning 2.0.0** specifications.
|
||||||
|
|
||||||
|
The full version identifier consits of a version core (major.minor.patch) + label + hexsha of the commit.
|
||||||
|
Using the following format:
|
||||||
|
|
||||||
|
|
||||||
|
.. code-block:: md
|
||||||
|
|
||||||
|
<major>.<minor>.<patch>-<label>+<short_hexsha>
|
||||||
|
|
||||||
|
eg.
|
||||||
|
0.8.1-kitten+ea898
|
||||||
|
0.5.0-kitten+01d85
|
||||||
|
1.5.0-akasha+7de53
|
||||||
|
|
||||||
|
kitten refers to all pre-release (1.0.0) versions
|
||||||
|
|
||||||
|
|
||||||
|
The shortened hexsha of a commit is obtained by:
|
||||||
|
``git rev-parse --short=5 <commit_hexsha>``
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
7
docs/guidelines/philosophy.rst
Normal file
7
docs/guidelines/philosophy.rst
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
.. guidelines/philosophy
|
||||||
|
|
||||||
|
Philosophy
|
||||||
|
===================================================================================================
|
||||||
|
|
||||||
|
| **A theory or attitude that acts as a guiding principle for behaviour.**
|
||||||
|
| --- Oxford Languages
|
32
docs/index.rst
Normal file
32
docs/index.rst
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
.. light documentation
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 2
|
||||||
|
:caption: Light Engine
|
||||||
|
|
||||||
|
light/showcase.rst
|
||||||
|
light/features.rst
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 2
|
||||||
|
:caption: Software Architecture
|
||||||
|
|
||||||
|
architecture/assets.rst
|
||||||
|
architecture/resource.rst
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 2
|
||||||
|
:caption: Development Guidelines
|
||||||
|
|
||||||
|
guidelines/philosophy.rst
|
||||||
|
guidelines/development.rst
|
||||||
|
guidelines/conventions.rst
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 2
|
||||||
|
:caption: Generated Docs
|
||||||
|
|
||||||
|
generated/api.rst
|
||||||
|
generated/changelog.rst
|
||||||
|
|
||||||
|
|
4
docs/light/features.rst
Normal file
4
docs/light/features.rst
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
.. light/features
|
||||||
|
|
||||||
|
Features
|
||||||
|
===================================================================================================
|
4
docs/light/showcase.rst
Normal file
4
docs/light/showcase.rst
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
.. light/demos
|
||||||
|
|
||||||
|
Showcase
|
||||||
|
===================================================================================================
|
35
docs/make.bat
Normal file
35
docs/make.bat
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
@ECHO OFF
|
||||||
|
|
||||||
|
pushd %~dp0
|
||||||
|
|
||||||
|
REM Command file for Sphinx documentation
|
||||||
|
|
||||||
|
if "%SPHINXBUILD%" == "" (
|
||||||
|
set SPHINXBUILD=sphinx-build
|
||||||
|
)
|
||||||
|
set SOURCEDIR=.
|
||||||
|
set BUILDDIR=_build
|
||||||
|
|
||||||
|
%SPHINXBUILD% >NUL 2>NUL
|
||||||
|
if errorlevel 9009 (
|
||||||
|
echo.
|
||||||
|
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
|
||||||
|
echo.installed, then set the SPHINXBUILD environment variable to point
|
||||||
|
echo.to the full path of the 'sphinx-build' executable. Alternatively you
|
||||||
|
echo.may add the Sphinx directory to PATH.
|
||||||
|
echo.
|
||||||
|
echo.If you don't have Sphinx installed, grab it from
|
||||||
|
echo.https://www.sphinx-doc.org/
|
||||||
|
exit /b 1
|
||||||
|
)
|
||||||
|
|
||||||
|
if "%1" == "" goto help
|
||||||
|
|
||||||
|
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
|
||||||
|
goto end
|
||||||
|
|
||||||
|
:help
|
||||||
|
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
|
||||||
|
|
||||||
|
:end
|
||||||
|
popd
|
58
external/CMakeLists.txt
vendored
58
external/CMakeLists.txt
vendored
|
@ -1,58 +0,0 @@
|
||||||
# GLAD #
|
|
||||||
add_subdirectory(./glad)
|
|
||||||
|
|
||||||
set(MIRROR_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../modules/mirror/)
|
|
||||||
set(DEPENDENCIES_DIR ${CMAKE_CURRENT_SOURCE_DIR}/)
|
|
||||||
|
|
||||||
if (CMAKE_COMPILER_IS_GNUCC)
|
|
||||||
add_compile_options(-w)
|
|
||||||
endif()
|
|
||||||
if(MSVC)
|
|
||||||
add_compile_options(/MP)
|
|
||||||
add_compile_options(/W0)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
file(GLOB IMGUI_FILES true ABSOLUTE
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/imgui/imgui.cpp
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/imgui/imgui_tables.cpp
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/imgui/imgui_widgets.cpp
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/imgui/imgui_draw.cpp
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/imgui/imgui_demo.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
set(BACKENDS_DIR ${CMAKE_CURRENT_SOURCE_DIR}/imgui/backends/)
|
|
||||||
|
|
||||||
|
|
||||||
file(GLOB IMGUI_BACKEND_FILES true ABSOLUTE
|
|
||||||
${BACKENDS_DIR}imgui_impl_opengl3.cpp
|
|
||||||
${BACKENDS_DIR}imgui_impl_glfw.cpp
|
|
||||||
# ${BACKENDS_DIR}imgui_impl_vulkan.cpp ${BACKENDS_DIR}imgui_impl_vulkan.h
|
|
||||||
)
|
|
||||||
|
|
||||||
if(WIN32)
|
|
||||||
file(GLOB IMGUI_WINDOWS_BACKEND_FILES true ABSOLUTE ${CMAKE_CURRENT_SOURCE_DIR}/backends/
|
|
||||||
${BACKENDS_DIR}imgui_impl_dx11.cpp
|
|
||||||
${BACKENDS_DIR}imgui_impl_win32.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
list(APPEND IMGUI_BACKEND_FILES ${IMGUI_WINDOWS_BACKEND_FILES})
|
|
||||||
endif()
|
|
||||||
|
|
||||||
add_compile_definitions(IMGUI_IMPL_OPENGL_LOADER_GLAD)
|
|
||||||
include_directories(${DEPENDENCIES_DIR}GLFW/include)
|
|
||||||
include_directories(${DEPENDENCIES_DIR}glm/)
|
|
||||||
|
|
||||||
add_library(imgui STATIC ${IMGUI_FILES} ${IMGUI_BACKEND_FILES})
|
|
||||||
|
|
||||||
target_include_directories(imgui PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/imgui)
|
|
||||||
target_link_libraries(
|
|
||||||
imgui
|
|
||||||
PUBLIC glad
|
|
||||||
PUBLIC opengl::opengl
|
|
||||||
PUBLIC glm::glm
|
|
||||||
PUBLIC glfw
|
|
||||||
)
|
|
||||||
|
|
||||||
# Copy imconfig.h over
|
|
||||||
file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/configurations/imgui/imconfig.h
|
|
||||||
DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/imgui/)
|
|
131
external/configurations/imgui/imconfig.h
vendored
131
external/configurations/imgui/imconfig.h
vendored
|
@ -1,131 +0,0 @@
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// COMPILE-TIME OPTIONS FOR DEAR IMGUI
|
|
||||||
// Runtime options (clipboard callbacks, enabling various features, etc.) can generally be set via the ImGuiIO structure.
|
|
||||||
// You can use ImGui::SetAllocatorFunctions() before calling ImGui::CreateContext() to rewire memory allocation functions.
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// A) You may edit imconfig.h (and not overwrite it when updating Dear ImGui, or maintain a patch/rebased branch with your modifications to it)
|
|
||||||
// B) or '#define IMGUI_USER_CONFIG "my_imgui_config.h"' in your project and then add directives in your own file without touching this template.
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// You need to make sure that configuration settings are defined consistently _everywhere_ Dear ImGui is used, which include the imgui*.cpp
|
|
||||||
// files but also _any_ of your code that uses Dear ImGui. This is because some compile-time options have an affect on data structures.
|
|
||||||
// Defining those options in imconfig.h will ensure every compilation unit gets to see the same data structure layouts.
|
|
||||||
// Call IMGUI_CHECKVERSION() from your .cpp files to verify that the data structures your files are using are matching the ones imgui.cpp is using.
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
//---- Define assertion handler. Defaults to calling assert().
|
|
||||||
// If your macro uses multiple statements, make sure is enclosed in a 'do { .. } while (0)' block so it can be used as a single statement.
|
|
||||||
//#define IM_ASSERT(_EXPR) MyAssert(_EXPR)
|
|
||||||
//#define IM_ASSERT(_EXPR) ((void)(_EXPR)) // Disable asserts
|
|
||||||
|
|
||||||
//---- Define attributes of all API symbols declarations, e.g. for DLL under Windows
|
|
||||||
// Using Dear ImGui via a shared library is not recommended, because of function call overhead and because we don't guarantee backward nor forward ABI compatibility.
|
|
||||||
// DLL users: heaps and globals are not shared across DLL boundaries! You will need to call SetCurrentContext() + SetAllocatorFunctions()
|
|
||||||
// for each static/DLL boundary you are calling from. Read "Context and Memory Allocators" section of imgui.cpp for more details.
|
|
||||||
//#define IMGUI_API __declspec( dllexport )
|
|
||||||
//#define IMGUI_API __declspec( dllimport )
|
|
||||||
|
|
||||||
//---- Don't define obsolete functions/enums/behaviors. Consider enabling from time to time after updating to avoid using soon-to-be obsolete function/names.
|
|
||||||
//#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
|
||||||
//#define IMGUI_DISABLE_OBSOLETE_KEYIO // 1.87: disable legacy io.KeyMap[]+io.KeysDown[] in favor io.AddKeyEvent(). This will be folded into IMGUI_DISABLE_OBSOLETE_FUNCTIONS in a few versions.
|
|
||||||
|
|
||||||
//---- Disable all of Dear ImGui or don't implement standard windows.
|
|
||||||
// It is very strongly recommended to NOT disable the demo windows during development. Please read comments in imgui_demo.cpp.
|
|
||||||
//#define IMGUI_DISABLE // Disable everything: all headers and source files will be empty.
|
|
||||||
//#define IMGUI_DISABLE_DEMO_WINDOWS // Disable demo windows: ShowDemoWindow()/ShowStyleEditor() will be empty. Not recommended.
|
|
||||||
//#define IMGUI_DISABLE_METRICS_WINDOW // Disable metrics/debugger and other debug tools: ShowMetricsWindow() and ShowStackToolWindow() will be empty.
|
|
||||||
|
|
||||||
//---- Don't implement some functions to reduce linkage requirements.
|
|
||||||
//#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS // [Win32] Don't implement default clipboard handler. Won't use and link with OpenClipboard/GetClipboardData/CloseClipboard etc. (user32.lib/.a, kernel32.lib/.a)
|
|
||||||
//#define IMGUI_ENABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] [Default with Visual Studio] Implement default IME handler (require imm32.lib/.a, auto-link for Visual Studio, -limm32 on command-line for MinGW)
|
|
||||||
//#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] [Default with non-Visual Studio compilers] Don't implement default IME handler (won't require imm32.lib/.a)
|
|
||||||
//#define IMGUI_DISABLE_WIN32_FUNCTIONS // [Win32] Won't use and link with any Win32 function (clipboard, ime).
|
|
||||||
//#define IMGUI_ENABLE_OSX_DEFAULT_CLIPBOARD_FUNCTIONS // [OSX] Implement default OSX clipboard handler (need to link with '-framework ApplicationServices', this is why this is not the default).
|
|
||||||
//#define IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS // Don't implement ImFormatString/ImFormatStringV so you can implement them yourself (e.g. if you don't want to link with vsnprintf)
|
|
||||||
//#define IMGUI_DISABLE_DEFAULT_MATH_FUNCTIONS // Don't implement ImFabs/ImSqrt/ImPow/ImFmod/ImCos/ImSin/ImAcos/ImAtan2 so you can implement them yourself.
|
|
||||||
//#define IMGUI_DISABLE_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite and ImFileHandle at all (replace them with dummies)
|
|
||||||
//#define IMGUI_DISABLE_DEFAULT_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite and ImFileHandle so you can implement them yourself if you don't want to link with fopen/fclose/fread/fwrite. This will also disable the LogToTTY() function.
|
|
||||||
//#define IMGUI_DISABLE_DEFAULT_ALLOCATORS // Don't implement default allocators calling malloc()/free() to avoid linking with them. You will need to call ImGui::SetAllocatorFunctions().
|
|
||||||
//#define IMGUI_DISABLE_SSE // Disable use of SSE intrinsics even if available
|
|
||||||
|
|
||||||
//---- Include imgui_user.h at the end of imgui.h as a convenience
|
|
||||||
//#define IMGUI_INCLUDE_IMGUI_USER_H
|
|
||||||
|
|
||||||
//---- Pack colors to BGRA8 instead of RGBA8 (to avoid converting from one to another)
|
|
||||||
//#define IMGUI_USE_BGRA_PACKED_COLOR
|
|
||||||
|
|
||||||
//---- Use 32-bit for ImWchar (default is 16-bit) to support unicode planes 1-16. (e.g. point beyond 0xFFFF like emoticons, dingbats, symbols, shapes, ancient languages, etc...)
|
|
||||||
//#define IMGUI_USE_WCHAR32
|
|
||||||
|
|
||||||
//---- Avoid multiple STB libraries implementations, or redefine path/filenames to prioritize another version
|
|
||||||
// By default the embedded implementations are declared static and not available outside of Dear ImGui sources files.
|
|
||||||
//#define IMGUI_STB_TRUETYPE_FILENAME "my_folder/stb_truetype.h"
|
|
||||||
//#define IMGUI_STB_RECT_PACK_FILENAME "my_folder/stb_rect_pack.h"
|
|
||||||
//#define IMGUI_DISABLE_STB_TRUETYPE_IMPLEMENTATION
|
|
||||||
//#define IMGUI_DISABLE_STB_RECT_PACK_IMPLEMENTATION
|
|
||||||
|
|
||||||
//---- Use stb_printf's faster implementation of vsnprintf instead of the one from libc (unless IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS is defined)
|
|
||||||
// Requires 'stb_sprintf.h' to be available in the include path. Compatibility checks of arguments and formats done by clang and GCC will be disabled in order to support the extra formats provided by STB sprintf.
|
|
||||||
// #define IMGUI_USE_STB_SPRINTF
|
|
||||||
|
|
||||||
//---- Use FreeType to build and rasterize the font atlas (instead of stb_truetype which is embedded by default in Dear ImGui)
|
|
||||||
// Requires FreeType headers to be available in the include path. Requires program to be compiled with 'misc/freetype/imgui_freetype.cpp' (in this repository) + the FreeType library (not provided).
|
|
||||||
// On Windows you may use vcpkg with 'vcpkg install freetype --triplet=x64-windows' + 'vcpkg integrate install'.
|
|
||||||
//#define IMGUI_ENABLE_FREETYPE
|
|
||||||
|
|
||||||
//---- Use stb_truetype to build and rasterize the font atlas (default)
|
|
||||||
// The only purpose of this define is if you want force compilation of the stb_truetype backend ALONG with the FreeType backend.
|
|
||||||
//#define IMGUI_ENABLE_STB_TRUETYPE
|
|
||||||
|
|
||||||
//---- Define constructor and implicit cast operators to convert back<>forth between your math types and ImVec2/ImVec4.
|
|
||||||
// This will be inlined as part of ImVec2 and ImVec4 class declarations.
|
|
||||||
|
|
||||||
#include <glm/glm.hpp>
|
|
||||||
|
|
||||||
#define IM_VEC2_CLASS_EXTRA \
|
|
||||||
bool operator==(glm::vec2 rhs) { return x == rhs.x && y == rhs.y; } \
|
|
||||||
bool operator!=(glm::vec2 rhs) { return (*this) == rhs; } \
|
|
||||||
bool operator==(ImVec2 rhs) { return x == rhs.x && y == rhs.y; } \
|
|
||||||
bool operator!=(ImVec2 rhs) { return (*this) == rhs; }
|
|
||||||
|
|
||||||
|
|
||||||
#define IM_VEC4_CLASS_EXTRA \
|
|
||||||
bool operator==(glm::vec4 rhs) { return x == rhs.x && y == rhs.y && z == rhs.z && w == rhs.w; } \
|
|
||||||
bool operator!=(glm::vec4 rhs) { return (*this) == rhs; } \
|
|
||||||
bool operator==(ImVec4 rhs) { return x == rhs.x && y == rhs.y && z == rhs.z && w == rhs.w; } \
|
|
||||||
bool operator!=(ImVec4 rhs) { return (*this) == rhs; }
|
|
||||||
|
|
||||||
|
|
||||||
//---- Use 32-bit vertex indices (default is 16-bit) is one way to allow large meshes with more than 64K vertices.
|
|
||||||
// Your renderer backend will need to support it (most example renderer backends support both 16/32-bit indices).
|
|
||||||
// Another way to allow large meshes while keeping 16-bit indices is to handle ImDrawCmd::VtxOffset in your renderer.
|
|
||||||
// Read about ImGuiBackendFlags_RendererHasVtxOffset for details.
|
|
||||||
//#define ImDrawIdx unsigned int
|
|
||||||
|
|
||||||
//---- Override ImDrawCallback signature (will need to modify renderer backends accordingly)
|
|
||||||
//struct ImDrawList;
|
|
||||||
//struct ImDrawCmd;
|
|
||||||
//typedef void (*MyImDrawCallback)(const ImDrawList* draw_list, const ImDrawCmd* cmd, void* my_renderer_user_data);
|
|
||||||
//#define ImDrawCallback MyImDrawCallback
|
|
||||||
|
|
||||||
//---- Debug Tools: Macro to break in Debugger
|
|
||||||
// (use 'Metrics->Tools->Item Picker' to pick widgets with the mouse and break into them for easy debugging.)
|
|
||||||
//#define IM_DEBUG_BREAK IM_ASSERT(0)
|
|
||||||
//#define IM_DEBUG_BREAK __debugbreak()
|
|
||||||
|
|
||||||
//---- Debug Tools: Have the Item Picker break in the ItemAdd() function instead of ItemHoverable(),
|
|
||||||
// (which comes earlier in the code, will catch a few extra items, allow picking items other than Hovered one.)
|
|
||||||
// This adds a small runtime cost which is why it is not enabled by default.
|
|
||||||
//#define IMGUI_DEBUG_TOOL_ITEM_PICKER_EX
|
|
||||||
|
|
||||||
//---- Debug Tools: Enable slower asserts
|
|
||||||
//#define IMGUI_DEBUG_PARANOID
|
|
||||||
|
|
||||||
//---- Tip: You can add extra functions within the ImGui:: namespace, here or in your own headers files.
|
|
||||||
/*
|
|
||||||
namespace ImGui
|
|
||||||
{
|
|
||||||
void MyFunction(const char* name, const MyMatrix44& v);
|
|
||||||
}
|
|
||||||
*/
|
|
1
external/imgui
vendored
1
external/imgui
vendored
|
@ -1 +0,0 @@
|
||||||
Subproject commit 250333d895b1067533533dcfab137512745b9689
|
|
|
@ -3,22 +3,22 @@ add_subdirectory(./base)
|
||||||
add_subdirectory(./time)
|
add_subdirectory(./time)
|
||||||
add_subdirectory(./logger)
|
add_subdirectory(./logger)
|
||||||
add_subdirectory(./debug)
|
add_subdirectory(./debug)
|
||||||
|
add_subdirectory(./math)
|
||||||
|
#
|
||||||
add_subdirectory(./asset_baker)
|
add_subdirectory(./asset_baker)
|
||||||
add_subdirectory(./asset_parser)
|
add_subdirectory(./asset_parser)
|
||||||
add_subdirectory(./asset_manager)
|
# add_subdirectory(./asset_manager)
|
||||||
|
#
|
||||||
add_subdirectory(./camera)
|
add_subdirectory(./camera)
|
||||||
add_subdirectory(./input)
|
# add_subdirectory(./input)
|
||||||
add_subdirectory(./ui)
|
# add_subdirectory(./ui)
|
||||||
|
#
|
||||||
add_subdirectory(./window)
|
add_subdirectory(./surface)
|
||||||
add_subdirectory(./renderer)
|
# add_subdirectory(./renderer)
|
||||||
add_subdirectory(./ecs)
|
add_subdirectory(./ecs)
|
||||||
|
#
|
||||||
add_subdirectory(./app)
|
add_subdirectory(./app)
|
||||||
|
|
||||||
# apps
|
# apps
|
||||||
add_subdirectory(./mirror)
|
add_subdirectory(./mirror)
|
||||||
|
|
||||||
add_subdirectory(test)
|
add_subdirectory(test)
|
||||||
|
|
|
@ -1,21 +1,2 @@
|
||||||
add_library_module(app
|
add_library_module(app application.cpp)
|
||||||
application.cpp
|
target_link_libraries(app PRIVATE lt_debug)
|
||||||
layer.cpp
|
|
||||||
layer_stack.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
target_link_libraries(app
|
|
||||||
PUBLIC
|
|
||||||
renderer
|
|
||||||
logger
|
|
||||||
ui
|
|
||||||
asset_parser
|
|
||||||
asset_manager
|
|
||||||
lt_debug
|
|
||||||
ecs
|
|
||||||
window
|
|
||||||
glad
|
|
||||||
time
|
|
||||||
opengl::opengl
|
|
||||||
EnTT::EnTT
|
|
||||||
)
|
|
||||||
|
|
|
@ -1,77 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <time/timer.hpp>
|
|
||||||
|
|
||||||
namespace lt {
|
|
||||||
|
|
||||||
class Renderer;
|
|
||||||
class Window;
|
|
||||||
class Event;
|
|
||||||
class GraphicsContext;
|
|
||||||
class UserInterface;
|
|
||||||
class LayerStack;
|
|
||||||
|
|
||||||
extern Scope<class Application> create_application();
|
|
||||||
|
|
||||||
class Application
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Application(const Application &) = delete;
|
|
||||||
|
|
||||||
Application(Application &&) = delete;
|
|
||||||
|
|
||||||
auto operator=(const Application &) -> Application & = delete;
|
|
||||||
|
|
||||||
auto operator=(Application &&) -> Application & = delete;
|
|
||||||
|
|
||||||
virtual ~Application();
|
|
||||||
|
|
||||||
[[nodiscard]] auto sanity_check() const -> bool;
|
|
||||||
|
|
||||||
void game_loop();
|
|
||||||
|
|
||||||
[[nodiscard]] auto get_window() -> Window &
|
|
||||||
{
|
|
||||||
return *m_window;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] auto get_layer_stack() -> LayerStack &
|
|
||||||
{
|
|
||||||
return *m_layer_stack;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void quit();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
Application();
|
|
||||||
|
|
||||||
private:
|
|
||||||
void update_layers();
|
|
||||||
|
|
||||||
void render_layers();
|
|
||||||
|
|
||||||
void render_user_interface();
|
|
||||||
|
|
||||||
void poll_events();
|
|
||||||
|
|
||||||
void on_event(const Event &event);
|
|
||||||
|
|
||||||
void log_debug_data() const;
|
|
||||||
|
|
||||||
Timer m_timer;
|
|
||||||
|
|
||||||
Scope<Window> m_window;
|
|
||||||
|
|
||||||
Scope<UserInterface> m_user_interface;
|
|
||||||
|
|
||||||
Scope<GraphicsContext> m_graphics_context;
|
|
||||||
|
|
||||||
Scope<Renderer> m_renderer;
|
|
||||||
|
|
||||||
Scope<LayerStack> m_layer_stack;
|
|
||||||
|
|
||||||
static Application *s_instance;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace lt
|
|
|
@ -1,116 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
namespace lt {
|
|
||||||
|
|
||||||
class Event;
|
|
||||||
|
|
||||||
class MouseMovedEvent;
|
|
||||||
class ButtonPressedEvent;
|
|
||||||
class ButtonReleasedEvent;
|
|
||||||
class WheelScrolledEvent;
|
|
||||||
class KeyPressedEvent;
|
|
||||||
class KeyRepeatEvent;
|
|
||||||
class KeyReleasedEvent;
|
|
||||||
class SetCharEvent;
|
|
||||||
class WindowClosedEvent;
|
|
||||||
class WindowResizedEvent;
|
|
||||||
class WindowMovedEvent;
|
|
||||||
class WindowLostFocusEvent;
|
|
||||||
class WindowGainFocusEvent;
|
|
||||||
|
|
||||||
class Layer
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Layer(std::string name);
|
|
||||||
|
|
||||||
virtual ~Layer() = default;
|
|
||||||
|
|
||||||
[[nodiscard]] auto get_name() const -> const std::string &
|
|
||||||
{
|
|
||||||
return m_layer_name;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void on_update(float deltaTime)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void on_user_interface_update()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void on_render()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
auto on_event(const Event &event) -> bool;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
std::string m_layer_name;
|
|
||||||
|
|
||||||
virtual auto on_mouse_moved(const MouseMovedEvent & /*event*/) -> bool
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual auto on_button_pressed(const ButtonPressedEvent & /*event*/) -> bool
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual auto on_button_released(const ButtonReleasedEvent & /*event*/) -> bool
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual auto on_wheel_scrolled(const WheelScrolledEvent & /*event*/) -> bool
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual auto on_key_pressed(const KeyPressedEvent & /*event*/) -> bool
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual auto on_key_repeat(const KeyRepeatEvent & /*event*/) -> bool
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual auto on_key_released(const KeyReleasedEvent & /*event*/) -> bool
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual auto on_set_char(const SetCharEvent & /*event*/) -> bool
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual auto on_window_closed(const WindowClosedEvent & /*event*/) -> bool
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual auto on_window_resized(const WindowResizedEvent & /*event*/) -> bool
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual auto on_window_moved(const WindowMovedEvent & /*event*/) -> bool
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual auto on_window_lost_focus(const WindowLostFocusEvent & /*event*/) -> bool
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual auto on_window_gain_focus(const WindowGainFocusEvent & /*event*/) -> bool
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace lt
|
|
|
@ -1,50 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
namespace lt {
|
|
||||||
|
|
||||||
class Layer;
|
|
||||||
class Event;
|
|
||||||
|
|
||||||
class LayerStack
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
template<typename Layer_T, typename... Args>
|
|
||||||
void emplace_layer(Args &&...args)
|
|
||||||
{
|
|
||||||
attach_layer(create_ref<Layer_T>(std::forward<Args>(args)...));
|
|
||||||
}
|
|
||||||
|
|
||||||
void attach_layer(Ref<Layer> layer);
|
|
||||||
|
|
||||||
void detach_layer(const Ref<Layer> &layer);
|
|
||||||
|
|
||||||
[[nodiscard]] auto is_empty() const -> bool
|
|
||||||
{
|
|
||||||
return m_layers.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] auto begin() -> std::vector<Ref<Layer>>::iterator
|
|
||||||
{
|
|
||||||
return m_layers.begin();
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] auto end() -> std::vector<Ref<Layer>>::iterator
|
|
||||||
{
|
|
||||||
return m_layers.end();
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] auto rbegin() -> std::vector<Ref<Layer>>::reverse_iterator
|
|
||||||
{
|
|
||||||
return m_layers.rbegin();
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] auto rend() -> std::vector<Ref<Layer>>::reverse_iterator
|
|
||||||
{
|
|
||||||
return m_layers.rend();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::vector<Ref<Layer>> m_layers;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace lt
|
|
48
modules/app/private/application.cpp
Normal file
48
modules/app/private/application.cpp
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
#include <app/application.hpp>
|
||||||
|
#include <app/system.hpp>
|
||||||
|
|
||||||
|
namespace lt::app {
|
||||||
|
|
||||||
|
void Application::game_loop()
|
||||||
|
{
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
for (auto &system : m_systems)
|
||||||
|
{
|
||||||
|
if (system->tick())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto &system : m_systems_to_be_registered)
|
||||||
|
{
|
||||||
|
m_systems.emplace_back(system)->on_register();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto &system : m_systems_to_be_unregistered)
|
||||||
|
{
|
||||||
|
m_systems.erase(
|
||||||
|
std::remove(m_systems.begin(), m_systems.end(), system),
|
||||||
|
m_systems.end()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_systems.empty())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::register_system(Ref<app::ISystem> system)
|
||||||
|
{
|
||||||
|
m_systems.emplace_back(std::move(system));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::unregister_system(Ref<app::ISystem> system)
|
||||||
|
{
|
||||||
|
m_systems_to_be_unregistered.emplace_back(std::move(system));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace lt::app
|
44
modules/app/public/application.hpp
Normal file
44
modules/app/public/application.hpp
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace lt::app {
|
||||||
|
|
||||||
|
class ISystem;
|
||||||
|
|
||||||
|
extern Scope<class Application> create_application();
|
||||||
|
|
||||||
|
/** The main application class.
|
||||||
|
* Think of this like an aggregate of systems, you register systems through this interface.
|
||||||
|
* Then they'll tick every "application frame".
|
||||||
|
*/
|
||||||
|
class Application
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Application(const Application &) = delete;
|
||||||
|
|
||||||
|
Application(Application &&) = delete;
|
||||||
|
|
||||||
|
auto operator=(const Application &) -> Application & = delete;
|
||||||
|
|
||||||
|
auto operator=(Application &&) -> Application & = delete;
|
||||||
|
|
||||||
|
virtual ~Application() = default;
|
||||||
|
|
||||||
|
void game_loop();
|
||||||
|
|
||||||
|
void register_system(Ref<app::ISystem> system);
|
||||||
|
|
||||||
|
void unregister_system(Ref<app::ISystem> system);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Application() = default;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<Ref<app::ISystem>> m_systems;
|
||||||
|
|
||||||
|
std::vector<Ref<app::ISystem>> m_systems_to_be_unregistered;
|
||||||
|
|
||||||
|
std::vector<Ref<app::ISystem>> m_systems_to_be_registered;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace lt::app
|
|
@ -2,21 +2,21 @@
|
||||||
|
|
||||||
#include <app/application.hpp>
|
#include <app/application.hpp>
|
||||||
|
|
||||||
int main(int argc, char *argv[]) // NOLINT
|
auto main(int argc, char *argv[]) -> int32_t
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
std::ignore = argc;
|
std::ignore = argc;
|
||||||
std::ignore = argv;
|
std::ignore = argv;
|
||||||
|
|
||||||
auto application = lt::Scope<lt::Application> {};
|
auto application = lt::Scope<lt::app::Application> {};
|
||||||
|
|
||||||
application = lt::create_application();
|
application = lt::app::create_application();
|
||||||
|
if (!application)
|
||||||
lt::ensure(application, "Failed to create application");
|
{
|
||||||
lt::ensure(application->sanity_check(), "Failed to verify the sanity of the application");
|
throw std::runtime_error { "Failed to create application\n" };
|
||||||
|
}
|
||||||
|
|
||||||
application->game_loop();
|
application->game_loop();
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
catch (const std::exception &exp)
|
catch (const std::exception &exp)
|
27
modules/app/public/system.hpp
Normal file
27
modules/app/public/system.hpp
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace lt::app {
|
||||||
|
|
||||||
|
class ISystem
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ISystem() = default;
|
||||||
|
|
||||||
|
virtual ~ISystem() = default;
|
||||||
|
|
||||||
|
ISystem(ISystem &&) = default;
|
||||||
|
|
||||||
|
ISystem(const ISystem &) = delete;
|
||||||
|
|
||||||
|
auto operator=(ISystem &&) -> ISystem & = default;
|
||||||
|
|
||||||
|
auto operator=(const ISystem &) -> ISystem & = delete;
|
||||||
|
|
||||||
|
virtual void on_register() = 0;
|
||||||
|
|
||||||
|
virtual void on_unregister() = 0;
|
||||||
|
|
||||||
|
virtual auto tick() -> bool = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace lt::app
|
|
@ -1,203 +0,0 @@
|
||||||
#include <app/application.hpp>
|
|
||||||
#include <app/layer.hpp>
|
|
||||||
#include <app/layer_stack.hpp>
|
|
||||||
#include <asset_manager/asset_manager.hpp>
|
|
||||||
#include <debug/assertions.hpp>
|
|
||||||
#include <input/events/event.hpp>
|
|
||||||
#include <input/events/keyboard.hpp>
|
|
||||||
#include <input/events/window.hpp>
|
|
||||||
#include <input/input.hpp>
|
|
||||||
#include <ranges>
|
|
||||||
#include <renderer/blender.hpp>
|
|
||||||
#include <renderer/graphics_context.hpp>
|
|
||||||
#include <renderer/render_command.hpp>
|
|
||||||
#include <renderer/renderer.hpp>
|
|
||||||
#include <ui/ui.hpp>
|
|
||||||
#include <window/linux/window.hpp>
|
|
||||||
|
|
||||||
namespace lt {
|
|
||||||
|
|
||||||
Application *Application::s_instance = nullptr;
|
|
||||||
|
|
||||||
Application::Application(): m_window(nullptr)
|
|
||||||
{
|
|
||||||
ensure(!s_instance, "Application constructed twice");
|
|
||||||
s_instance = this;
|
|
||||||
|
|
||||||
m_window = Window::create([this](auto &&PH1) { on_event(std::forward<decltype(PH1)>(PH1)); });
|
|
||||||
|
|
||||||
// create graphics context
|
|
||||||
m_graphics_context = GraphicsContext::create(
|
|
||||||
GraphicsAPI::OpenGL,
|
|
||||||
(GLFWwindow *)m_window->get_handle()
|
|
||||||
);
|
|
||||||
|
|
||||||
AssetManager::load_shader(
|
|
||||||
"LT_ENGINE_RESOURCES_TEXTURE_SHADER",
|
|
||||||
"data/assets/shaders/texture/vs.asset",
|
|
||||||
"data/assets/shaders/texture/ps.asset"
|
|
||||||
);
|
|
||||||
|
|
||||||
AssetManager::load_shader(
|
|
||||||
"LT_ENGINE_RESOURCES_TINTED_TEXTURE_SHADER",
|
|
||||||
"data/assets/shaders/tinted_texture/vs.asset",
|
|
||||||
"data/assets/shaders/tinted_texture/ps.asset"
|
|
||||||
);
|
|
||||||
|
|
||||||
AssetManager::load_shader(
|
|
||||||
"LT_ENGINE_RESOURCES_QUAD_SHADER",
|
|
||||||
"data/assets/shaders/quads/vs.asset",
|
|
||||||
"data/assets/shaders/quads/ps.asset"
|
|
||||||
);
|
|
||||||
|
|
||||||
m_renderer = Renderer::create(
|
|
||||||
(GLFWwindow *)m_window->get_handle(),
|
|
||||||
lt::GraphicsContext::get_shared_context(),
|
|
||||||
Renderer::CreateInfo {
|
|
||||||
.quad_renderer_shader = AssetManager::get_shader("LT_ENGINE_RESOURCES_QUAD_SHADER"),
|
|
||||||
.texture_renderer_shader = AssetManager::get_shader(
|
|
||||||
"LT_ENGINE_RESOURCES_TEXTURE_SHADER"
|
|
||||||
),
|
|
||||||
.tinted_texture_renderer_shader = AssetManager::get_shader(
|
|
||||||
"LT_ENGINE_RESOURCES_TINTED_"
|
|
||||||
"TEXTURE_SHADER"
|
|
||||||
),
|
|
||||||
}
|
|
||||||
);
|
|
||||||
ensure(m_graphics_context, "lWindow::lWindow: failed to create 'GraphicsContext'");
|
|
||||||
|
|
||||||
m_user_interface = UserInterface::create(
|
|
||||||
(GLFWwindow *)m_window->get_handle(),
|
|
||||||
lt::GraphicsContext::get_shared_context()
|
|
||||||
);
|
|
||||||
|
|
||||||
m_layer_stack = create_scope<LayerStack>();
|
|
||||||
}
|
|
||||||
|
|
||||||
Application::~Application()
|
|
||||||
{
|
|
||||||
/** This is required to make forward-declarations possible:
|
|
||||||
* https://stackoverflow.com/questions/34072862/why-is-error-invalid-application-of-sizeof-to-an-incomplete-type-using-uniqu
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
void Application::game_loop()
|
|
||||||
{
|
|
||||||
m_window->set_visibility(true);
|
|
||||||
|
|
||||||
while (!m_window->is_closed())
|
|
||||||
{
|
|
||||||
update_layers();
|
|
||||||
render_layers();
|
|
||||||
render_user_interface();
|
|
||||||
poll_events();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Application::quit()
|
|
||||||
{
|
|
||||||
s_instance->m_window->close();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Application::update_layers()
|
|
||||||
{
|
|
||||||
for (auto &it : *m_layer_stack)
|
|
||||||
{
|
|
||||||
// narrowing double -> float
|
|
||||||
it->on_update(static_cast<float>(m_timer.elapsed_time().count()));
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO(Light): each layer should have their own "delta time"
|
|
||||||
m_timer.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Application::render_layers()
|
|
||||||
{
|
|
||||||
m_renderer->begin_frame();
|
|
||||||
|
|
||||||
for (auto &it : *m_layer_stack)
|
|
||||||
{
|
|
||||||
it->on_render();
|
|
||||||
}
|
|
||||||
|
|
||||||
m_renderer->end_frame();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Application::render_user_interface()
|
|
||||||
{
|
|
||||||
m_user_interface->begin();
|
|
||||||
|
|
||||||
for (auto &it : *m_layer_stack)
|
|
||||||
{
|
|
||||||
it->on_user_interface_update();
|
|
||||||
}
|
|
||||||
|
|
||||||
m_user_interface->end();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Application::poll_events()
|
|
||||||
{
|
|
||||||
m_window->poll_events();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Application::on_event(const Event &event)
|
|
||||||
{
|
|
||||||
// window
|
|
||||||
if (event.has_category(WindowEventCategory))
|
|
||||||
{
|
|
||||||
m_window->on_event(event);
|
|
||||||
|
|
||||||
if (event.get_event_type() == EventType::WindowResized)
|
|
||||||
{
|
|
||||||
m_renderer->on_window_resize(dynamic_cast<const WindowResizedEvent &>(event));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// input
|
|
||||||
if (event.has_category(InputEventCategory))
|
|
||||||
{
|
|
||||||
Input::instance().on_event(event);
|
|
||||||
|
|
||||||
if (!Input::instance().is_receiving_game_events())
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto &it : std::ranges::reverse_view(*m_layer_stack))
|
|
||||||
{
|
|
||||||
if (it->on_event(event))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] auto Application::sanity_check() const -> bool
|
|
||||||
{
|
|
||||||
log_inf("Checking application sanity...");
|
|
||||||
ensure(s_instance, "Application not constructed!?");
|
|
||||||
ensure(m_window, "Window is not initialized");
|
|
||||||
ensure(m_user_interface, "User interface is not initialized");
|
|
||||||
ensure(m_graphics_context, "Graphics context is not initialized");
|
|
||||||
ensure(m_renderer, "Renderer is not initialized");
|
|
||||||
ensure(m_layer_stack, "Layer_stack is not initialized");
|
|
||||||
ensure(!m_layer_stack->is_empty(), "Layer_stack is empty");
|
|
||||||
|
|
||||||
log_inf("Logging application state...");
|
|
||||||
this->log_debug_data();
|
|
||||||
m_graphics_context->log_debug_data();
|
|
||||||
m_user_interface->log_debug_data();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Application::log_debug_data() const
|
|
||||||
{
|
|
||||||
log_inf("Platform::");
|
|
||||||
log_inf(" Platform name: {}", constants::platform_name);
|
|
||||||
log_inf(" Platform identifier: {}", std::to_underlying(constants::platform));
|
|
||||||
log_inf(" CWD: {}", std::filesystem::current_path().generic_string());
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace lt
|
|
|
@ -1,47 +0,0 @@
|
||||||
#include <app/layer.hpp>
|
|
||||||
#include <input/events/char.hpp>
|
|
||||||
#include <input/events/event.hpp>
|
|
||||||
#include <input/events/keyboard.hpp>
|
|
||||||
#include <input/events/mouse.hpp>
|
|
||||||
#include <input/events/window.hpp>
|
|
||||||
|
|
||||||
namespace lt {
|
|
||||||
|
|
||||||
Layer::Layer(std::string name): m_layer_name(std::move(name))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
auto Layer::on_event(const Event &event) -> bool
|
|
||||||
{
|
|
||||||
switch (event.get_event_type())
|
|
||||||
{
|
|
||||||
case EventType::MouseMoved: return on_mouse_moved(dynamic_cast<const MouseMovedEvent &>(event));
|
|
||||||
case EventType::ButtonPressed:
|
|
||||||
return on_button_pressed(dynamic_cast<const ButtonPressedEvent &>(event));
|
|
||||||
case EventType::ButtonReleased:
|
|
||||||
return on_button_released(dynamic_cast<const ButtonReleasedEvent &>(event));
|
|
||||||
case EventType::WheelScrolled:
|
|
||||||
return on_wheel_scrolled(dynamic_cast<const WheelScrolledEvent &>(event));
|
|
||||||
|
|
||||||
case EventType::KeyPressed: return on_key_pressed(dynamic_cast<const KeyPressedEvent &>(event));
|
|
||||||
case EventType::KeyRepeated: return on_key_repeat(dynamic_cast<const KeyRepeatEvent &>(event));
|
|
||||||
case EventType::KeyReleased:
|
|
||||||
return on_key_released(dynamic_cast<const KeyReleasedEvent &>(event));
|
|
||||||
case EventType::SetChar: return on_set_char(dynamic_cast<const SetCharEvent &>(event));
|
|
||||||
|
|
||||||
case EventType::WindowClosed:
|
|
||||||
return on_window_closed(dynamic_cast<const WindowClosedEvent &>(event));
|
|
||||||
case EventType::WindowResized:
|
|
||||||
return on_window_resized(dynamic_cast<const WindowResizedEvent &>(event));
|
|
||||||
case EventType::WindowMoved:
|
|
||||||
return on_window_moved(dynamic_cast<const WindowMovedEvent &>(event));
|
|
||||||
case EventType::WindowLostFocus:
|
|
||||||
return on_window_lost_focus(dynamic_cast<const WindowLostFocusEvent &>(event));
|
|
||||||
case EventType::WindowGainFocus:
|
|
||||||
return on_window_gain_focus(dynamic_cast<const WindowGainFocusEvent &>(event));
|
|
||||||
|
|
||||||
default: ensure(false, "Invalid event: {}", event.get_info_lt_log());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace lt
|
|
|
@ -1,18 +0,0 @@
|
||||||
#include <app/layer.hpp>
|
|
||||||
#include <app/layer_stack.hpp>
|
|
||||||
|
|
||||||
namespace lt {
|
|
||||||
|
|
||||||
void LayerStack::attach_layer(Ref<Layer> layer)
|
|
||||||
{
|
|
||||||
log_trc("Attaching layer [{}]", layer->get_name());
|
|
||||||
m_layers.emplace_back(std::move(layer));
|
|
||||||
}
|
|
||||||
|
|
||||||
void LayerStack::detach_layer(const Ref<Layer> &layer)
|
|
||||||
{
|
|
||||||
log_trc("Detaching layer [{}]", layer->get_name());
|
|
||||||
m_layers.erase(std::find(m_layers.begin(), m_layers.end(), layer));
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace lt
|
|
|
@ -1,5 +1,5 @@
|
||||||
add_executable_module(
|
add_executable_module(
|
||||||
asset_baker baker.cpp
|
asset_baker entrypoint/baker.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(
|
target_link_libraries(
|
||||||
|
|
|
@ -131,7 +131,8 @@ public:
|
||||||
return "TextLoader";
|
return "TextLoader";
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] auto load(const std::filesystem::path& file_path) const -> Assets::TextAsset::PackageData
|
[[nodiscard]] auto load(const std::filesystem::path &file_path) const
|
||||||
|
-> Assets::TextAsset::PackageData
|
||||||
{
|
{
|
||||||
auto stream = std::ifstream { file_path, std::ios::binary };
|
auto stream = std::ifstream { file_path, std::ios::binary };
|
||||||
if (!stream.good())
|
if (!stream.good())
|
|
@ -5,5 +5,5 @@ add_library_module(asset_manager
|
||||||
target_link_libraries(
|
target_link_libraries(
|
||||||
asset_manager
|
asset_manager
|
||||||
PUBLIC asset_parser
|
PUBLIC asset_parser
|
||||||
PRIVATE renderer
|
PRIVATE logger
|
||||||
)
|
)
|
||||||
|
|
|
@ -6,7 +6,6 @@ add_library_module(asset_parser
|
||||||
|
|
||||||
target_link_libraries(
|
target_link_libraries(
|
||||||
asset_parser
|
asset_parser
|
||||||
PUBLIC LZ4::lz4_static
|
PRIVATE LZ4::lz4_static
|
||||||
PUBLIC nlohmann_json::nlohmann_json
|
PRIVATE logger
|
||||||
PUBLIC logger
|
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
#include <asset_parser/assets/text.hpp>
|
#include <asset_parser/assets/text.hpp>
|
||||||
#include <lz4.h>
|
#include <lz4.h>
|
||||||
#include <nlohmann/json.hpp>
|
|
||||||
|
|
||||||
namespace Assets {
|
namespace Assets {
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
#include <asset_parser/assets/texture.hpp>
|
#include <asset_parser/assets/texture.hpp>
|
||||||
#include <lz4.h>
|
#include <lz4.h>
|
||||||
#include <nlohmann/json.hpp>
|
|
||||||
|
|
||||||
namespace Assets {
|
namespace Assets {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <asset_parser/compressors/compressors.hpp>
|
||||||
#include <asset_parser/parser.hpp>
|
#include <asset_parser/parser.hpp>
|
||||||
#include <compressors/compressors.hpp>
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <fstream>
|
#include <fstream>
|
|
@ -1,7 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <asset_parser/compressors/compressors.hpp>
|
||||||
#include <asset_parser/parser.hpp>
|
#include <asset_parser/parser.hpp>
|
||||||
#include <compressors/compressors.hpp>
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <fstream>
|
#include <fstream>
|
|
@ -1,6 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <compressors/compressors.hpp>
|
#include <asset_parser/compressors/compressors.hpp>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <fstream>
|
#include <fstream>
|
|
@ -1,3 +1,2 @@
|
||||||
add_library_module(base)
|
add_library_module(base)
|
||||||
|
target_precompile_headers(base INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/private/pch.hpp)
|
||||||
target_precompile_headers(base INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/src/pch.hpp)
|
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
add_library_module(camera camera.cpp scene.cpp)
|
add_library_module(camera camera.cpp scene.cpp)
|
||||||
|
|
||||||
target_link_libraries(camera PUBLIC glm::glm)
|
target_link_libraries(camera PUBLIC math)
|
||||||
|
|
|
@ -1,34 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <glm/glm.hpp>
|
|
||||||
|
|
||||||
namespace lt {
|
|
||||||
|
|
||||||
class Camera
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Camera() = default;
|
|
||||||
|
|
||||||
[[nodiscard]] auto get_projection() const -> const glm::mat4 &
|
|
||||||
{
|
|
||||||
return m_projection;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] auto get_background_color() const -> const glm::vec4 &
|
|
||||||
{
|
|
||||||
return m_background_color;
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_background_color(const glm::vec4 &color)
|
|
||||||
{
|
|
||||||
m_background_color = color;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
glm::mat4 m_projection {};
|
|
||||||
|
|
||||||
private:
|
|
||||||
glm::vec4 m_background_color = glm::vec4(1.0f, 0.0f, 0.0f, 1.0f);
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace lt
|
|
|
@ -1,11 +1,12 @@
|
||||||
#include <camera/scene.hpp>
|
#include <camera/scene.hpp>
|
||||||
#include <glm/gtc/matrix_transform.hpp>
|
#include <math/algebra.hpp>
|
||||||
|
#include <math/trig.hpp>
|
||||||
|
|
||||||
namespace lt {
|
namespace lt {
|
||||||
|
|
||||||
SceneCamera::SceneCamera()
|
SceneCamera::SceneCamera()
|
||||||
: m_orthographic_specification { .size = 1000.0f, .near_plane = -1.0f, .far_plane = 10000.0f }
|
: m_orthographic_specification { .size = 1000.0f, .near_plane = -1.0f, .far_plane = 10000.0f }
|
||||||
, m_perspective_specification { .vertical_fov = glm::radians(45.0f),
|
, m_perspective_specification { .vertical_fov = math::radians(45.0f),
|
||||||
.near_plane = 0.01f,
|
.near_plane = 0.01f,
|
||||||
.far_plane = 10000.0f }
|
.far_plane = 10000.0f }
|
||||||
, m_aspect_ratio(16.0f / 9.0f)
|
, m_aspect_ratio(16.0f / 9.0f)
|
||||||
|
@ -64,26 +65,19 @@ void SceneCamera::set_perspective_near_plane(float near_plane)
|
||||||
|
|
||||||
void SceneCamera::calculate_projection()
|
void SceneCamera::calculate_projection()
|
||||||
{
|
{
|
||||||
|
// TODO(Light): implement ortho perspective
|
||||||
if (m_projection_type == ProjectionType::Orthographic)
|
if (m_projection_type == ProjectionType::Orthographic)
|
||||||
{
|
{
|
||||||
m_projection = glm::ortho(
|
// throw std::runtime_error { "ortho perspective not supported yet" };
|
||||||
-m_orthographic_specification.size * 0.5f * m_aspect_ratio,
|
|
||||||
m_orthographic_specification.size * 0.5f * m_aspect_ratio,
|
|
||||||
-m_orthographic_specification.size * 0.5f,
|
|
||||||
m_orthographic_specification.size * 0.5f,
|
|
||||||
m_orthographic_specification.far_plane,
|
|
||||||
m_orthographic_specification.near_plane
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else // perspective
|
|
||||||
{
|
|
||||||
m_projection = glm::perspective(
|
|
||||||
m_perspective_specification.vertical_fov,
|
|
||||||
m_aspect_ratio,
|
|
||||||
m_perspective_specification.near_plane,
|
|
||||||
m_perspective_specification.far_plane
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// defaults to perspective for now...
|
||||||
|
m_projection = math::perspective(
|
||||||
|
m_perspective_specification.vertical_fov,
|
||||||
|
m_aspect_ratio,
|
||||||
|
m_perspective_specification.near_plane,
|
||||||
|
m_perspective_specification.far_plane
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace lt
|
} // namespace lt
|
35
modules/camera/public/camera.hpp
Normal file
35
modules/camera/public/camera.hpp
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <math/mat4.hpp>
|
||||||
|
#include <math/vec4.hpp>
|
||||||
|
|
||||||
|
namespace lt {
|
||||||
|
|
||||||
|
class Camera
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Camera() = default;
|
||||||
|
|
||||||
|
[[nodiscard]] auto get_projection() const -> const math::mat4 &
|
||||||
|
{
|
||||||
|
return m_projection;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] auto get_background_color() const -> const math::vec4 &
|
||||||
|
{
|
||||||
|
return m_background_color;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_background_color(const math::vec4 &color)
|
||||||
|
{
|
||||||
|
m_background_color = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
math::mat4 m_projection;
|
||||||
|
|
||||||
|
private:
|
||||||
|
math::vec4 m_background_color = math::vec4(1.0f, 0.0f, 0.0f, 1.0f);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace lt
|
|
@ -1,7 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <camera/scene.hpp>
|
#include <camera/scene.hpp>
|
||||||
#include <glm/glm.hpp>
|
|
||||||
|
|
||||||
namespace lt {
|
namespace lt {
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
add_library_module(lt_debug instrumentor.cpp)
|
add_library_module(lt_debug instrumentor.cpp)
|
||||||
target_link_libraries(lt_debug PUBLIC logger)
|
target_link_libraries(lt_debug PUBLIC logger)
|
||||||
target_precompile_headers(lt_debug PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src/pch.hpp)
|
target_precompile_headers(lt_debug PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/private/pch.hpp)
|
||||||
|
|
|
@ -1,36 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <logger/logger.hpp>
|
|
||||||
|
|
||||||
namespace lt {
|
|
||||||
|
|
||||||
struct FailedAssertion: std::exception
|
|
||||||
{
|
|
||||||
FailedAssertion(const char *file, int line)
|
|
||||||
{
|
|
||||||
log_crt("Assertion failed in: {} (line {})", file, line);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
template<typename Expression_T, typename... Args>
|
|
||||||
constexpr void ensure(Expression_T &&expression, std::format_string<Args...> fmt, Args &&...args)
|
|
||||||
{
|
|
||||||
if (!static_cast<bool>(expression))
|
|
||||||
{
|
|
||||||
Logger::log(LogLvl::critical, fmt, std::forward<Args>(args)...);
|
|
||||||
throw ::lt::FailedAssertion(__FILE__, __LINE__);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Expression_T>
|
|
||||||
constexpr void ensure(Expression_T &&expression, const char *message)
|
|
||||||
{
|
|
||||||
if (!static_cast<bool>(expression))
|
|
||||||
{
|
|
||||||
Logger::log(LogLvl::critical, message);
|
|
||||||
throw ::lt::FailedAssertion(__FILE__, __LINE__);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace lt
|
|
|
@ -1,5 +1,5 @@
|
||||||
#include <debug/instrumentor.hpp>
|
|
||||||
#include <logger/logger.hpp>
|
#include <logger/logger.hpp>
|
||||||
|
#include <lt_debug/instrumentor.hpp>
|
||||||
|
|
||||||
namespace lt {
|
namespace lt {
|
||||||
|
|
3
modules/debug/private/pch.hpp
Normal file
3
modules/debug/private/pch.hpp
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <lt_debug/assertions.hpp>
|
36
modules/debug/public/assertions.hpp
Normal file
36
modules/debug/public/assertions.hpp
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <format>
|
||||||
|
#include <logger/logger.hpp>
|
||||||
|
#include <source_location>
|
||||||
|
|
||||||
|
namespace lt {
|
||||||
|
|
||||||
|
template<typename Expression_T, typename... Args_T>
|
||||||
|
struct ensure
|
||||||
|
{
|
||||||
|
ensure(
|
||||||
|
Expression_T expression,
|
||||||
|
std::format_string<Args_T...> fmt,
|
||||||
|
Args_T &&...args,
|
||||||
|
const std::source_location &location = std::source_location::current()
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (!static_cast<bool>(expression))
|
||||||
|
{
|
||||||
|
throw std::runtime_error { std::format(
|
||||||
|
"exception: {}\nlocation: {}:{}",
|
||||||
|
std::format(fmt, std::forward<Args_T>(args)...),
|
||||||
|
location.file_name(),
|
||||||
|
location.line()
|
||||||
|
) };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template<typename Expression_T, typename... Args_T>
|
||||||
|
ensure(Expression_T, std::format_string<Args_T...>, Args_T &&...)
|
||||||
|
-> ensure<Expression_T, Args_T...>;
|
||||||
|
|
||||||
|
} // namespace lt
|
|
@ -1,3 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <debug/assertions.hpp>
|
|
|
@ -1,5 +1,4 @@
|
||||||
add_library_module(ecs entity.cpp scene.cpp uuid.cpp serializer.cpp)
|
add_library_module(ecs entity.cpp scene.cpp uuid.cpp )
|
||||||
target_link_libraries(ecs
|
target_link_libraries(ecs
|
||||||
PUBLIC logger lt_debug EnTT::EnTT renderer input camera
|
PUBLIC logger lt_debug EnTT::EnTT input camera math
|
||||||
PRIVATE yaml-cpp::yaml-cpp asset_manager
|
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,45 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#define GLM_ENABLE_EXPERIMENTAL
|
|
||||||
|
|
||||||
#include <glm/glm.hpp>
|
|
||||||
#include <glm/gtc/matrix_transform.hpp>
|
|
||||||
#include <glm/gtx/transform.hpp>
|
|
||||||
|
|
||||||
namespace lt {
|
|
||||||
|
|
||||||
struct TransformComponent
|
|
||||||
{
|
|
||||||
TransformComponent(const TransformComponent &) = default;
|
|
||||||
|
|
||||||
TransformComponent(
|
|
||||||
const glm::vec3 &_translation = glm::vec3(0.0f, 0.0f, 0.0f),
|
|
||||||
const glm::vec3 &_scale = glm::vec3(1.0f, 1.0f, 1.0f),
|
|
||||||
const glm::vec3 &_rotation = glm::vec3(0.0f, 0.0f, 0.0f)
|
|
||||||
)
|
|
||||||
|
|
||||||
: translation(_translation)
|
|
||||||
, scale(_scale)
|
|
||||||
, rotation(_rotation)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] auto get_transform() const -> glm::mat4
|
|
||||||
{
|
|
||||||
return glm::translate(translation) * glm::rotate(rotation.z, glm::vec3(0.0f, 0.0f, 1.0f))
|
|
||||||
* glm::scale(scale);
|
|
||||||
}
|
|
||||||
|
|
||||||
operator const glm::mat4() const
|
|
||||||
{
|
|
||||||
return get_transform();
|
|
||||||
}
|
|
||||||
|
|
||||||
glm::vec3 translation;
|
|
||||||
|
|
||||||
glm::vec3 scale;
|
|
||||||
|
|
||||||
glm::vec3 rotation;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace lt
|
|
31
modules/ecs/private/scene.cpp
Normal file
31
modules/ecs/private/scene.cpp
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
#include <ecs/components.hpp>
|
||||||
|
#include <ecs/entity.hpp>
|
||||||
|
#include <ecs/scene.hpp>
|
||||||
|
|
||||||
|
namespace lt {
|
||||||
|
|
||||||
|
auto Scene::create_entity(const std::string &name, const TransformComponent &transform) -> Entity
|
||||||
|
{
|
||||||
|
return create_entity_with_uuid(name, UUID(), transform);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto Scene::get_entity_by_tag(const std::string &tag) -> Entity
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
auto Scene::create_entity_with_uuid(
|
||||||
|
const std::string &name,
|
||||||
|
UUID uuid,
|
||||||
|
const TransformComponent &transform
|
||||||
|
) -> Entity
|
||||||
|
{
|
||||||
|
auto entity = Entity { m_registry.create(), this };
|
||||||
|
entity.add_component<TagComponent>(name);
|
||||||
|
entity.add_component<TransformComponent>(transform);
|
||||||
|
entity.add_component<UUIDComponent>(uuid);
|
||||||
|
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace lt
|
|
@ -2,14 +2,16 @@
|
||||||
#include <camera/component.hpp>
|
#include <camera/component.hpp>
|
||||||
#include <ecs/components.hpp>
|
#include <ecs/components.hpp>
|
||||||
#include <ecs/serializer.hpp>
|
#include <ecs/serializer.hpp>
|
||||||
|
#include <math/vec3.hpp>
|
||||||
|
#include <math/vec4.hpp>
|
||||||
#include <yaml-cpp/yaml.h>
|
#include <yaml-cpp/yaml.h>
|
||||||
|
|
||||||
namespace YAML {
|
namespace YAML {
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
struct convert<glm::vec3>
|
struct convert<lt::math::vec3>
|
||||||
{
|
{
|
||||||
static auto encode(const glm::vec3 &rhs) -> Node
|
static auto encode(const lt::math::vec3 &rhs) -> Node
|
||||||
{
|
{
|
||||||
auto node = Node {};
|
auto node = Node {};
|
||||||
node.push_back(rhs.x);
|
node.push_back(rhs.x);
|
||||||
|
@ -18,7 +20,7 @@ struct convert<glm::vec3>
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
static auto decode(const Node &node, glm::vec3 &rhs) -> bool
|
static auto decode(const Node &node, lt::math::vec3 &rhs) -> bool
|
||||||
{
|
{
|
||||||
if (!node.IsSequence() || node.size() != 3)
|
if (!node.IsSequence() || node.size() != 3)
|
||||||
{
|
{
|
||||||
|
@ -33,9 +35,9 @@ struct convert<glm::vec3>
|
||||||
};
|
};
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
struct convert<glm::vec4>
|
struct convert<lt::math::vec4>
|
||||||
{
|
{
|
||||||
static auto encode(const glm::vec4 &rhs) -> Node
|
static auto encode(const lt::math::vec4 &rhs) -> Node
|
||||||
{
|
{
|
||||||
auto node = Node {};
|
auto node = Node {};
|
||||||
node.push_back(rhs.x);
|
node.push_back(rhs.x);
|
||||||
|
@ -45,7 +47,7 @@ struct convert<glm::vec4>
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
static auto decode(const Node &node, glm::vec4 &rhs) -> bool
|
static auto decode(const Node &node, lt::math::vec4 &rhs) -> bool
|
||||||
{
|
{
|
||||||
if (!node.IsSequence() || node.size() != 4)
|
if (!node.IsSequence() || node.size() != 4)
|
||||||
{
|
{
|
||||||
|
@ -63,14 +65,14 @@ struct convert<glm::vec4>
|
||||||
|
|
||||||
namespace lt {
|
namespace lt {
|
||||||
|
|
||||||
auto operator<<(YAML::Emitter &out, const glm::vec3 &v) -> YAML::Emitter &
|
auto operator<<(YAML::Emitter &out, const math::vec3 &v) -> YAML::Emitter &
|
||||||
{
|
{
|
||||||
out << YAML::Flow;
|
out << YAML::Flow;
|
||||||
out << YAML::BeginSeq << v.x << v.y << v.z << YAML::EndSeq;
|
out << YAML::BeginSeq << v.x << v.y << v.z << YAML::EndSeq;
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto operator<<(YAML::Emitter &out, const glm::vec4 &v) -> YAML::Emitter &
|
auto operator<<(YAML::Emitter &out, const math::vec4 &v) -> YAML::Emitter &
|
||||||
{
|
{
|
||||||
out << YAML::Flow;
|
out << YAML::Flow;
|
||||||
out << YAML::BeginSeq << v.x << v.y << v.z << v.w << YAML::EndSeq;
|
out << YAML::BeginSeq << v.x << v.y << v.z << v.w << YAML::EndSeq;
|
||||||
|
@ -156,9 +158,10 @@ auto SceneSerializer::deserialize(const std::string &file_path) -> bool
|
||||||
.get_component<TransformComponent>();
|
.get_component<TransformComponent>();
|
||||||
|
|
||||||
entityTransforomComponent.translation = transformComponent["Translation"]
|
entityTransforomComponent.translation = transformComponent["Translation"]
|
||||||
.as<glm::vec3>();
|
.as<math::vec3>();
|
||||||
entityTransforomComponent.rotation = transformComponent["Rotation"].as<glm::vec3>();
|
entityTransforomComponent.rotation = transformComponent["Rotation"]
|
||||||
entityTransforomComponent.scale = transformComponent["Scale"].as<glm::vec3>();
|
.as<math::vec3>();
|
||||||
|
entityTransforomComponent.scale = transformComponent["Scale"].as<math::vec3>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* #TEMPORARY SOLUTION# */
|
/* #TEMPORARY SOLUTION# */
|
||||||
|
@ -168,7 +171,7 @@ auto SceneSerializer::deserialize(const std::string &file_path) -> bool
|
||||||
auto &entitySpriteRendererComponent = deserializedEntity
|
auto &entitySpriteRendererComponent = deserializedEntity
|
||||||
.add_component<SpriteRendererComponent>();
|
.add_component<SpriteRendererComponent>();
|
||||||
entitySpriteRendererComponent.tint = spriteRendererComponent["Tint"]
|
entitySpriteRendererComponent.tint = spriteRendererComponent["Tint"]
|
||||||
.as<glm::vec4>();
|
.as<math::vec4>();
|
||||||
|
|
||||||
auto texturePath = spriteRendererComponent["Texture"].as<std::string>();
|
auto texturePath = spriteRendererComponent["Texture"].as<std::string>();
|
||||||
|
|
||||||
|
@ -213,7 +216,7 @@ auto SceneSerializer::deserialize(const std::string &file_path) -> bool
|
||||||
);
|
);
|
||||||
|
|
||||||
entityCameraComponent.camera.set_background_color(
|
entityCameraComponent.camera.set_background_color(
|
||||||
cameraSpecifications["BackgroundColor"].as<glm::vec4>()
|
cameraSpecifications["BackgroundColor"].as<math::vec4>()
|
||||||
);
|
);
|
||||||
|
|
||||||
entityCameraComponent.isPrimary = cameraComponent["IsPrimary"].as<bool>();
|
entityCameraComponent.isPrimary = cameraComponent["IsPrimary"].as<bool>();
|
14
modules/ecs/private/uuid.cpp
Normal file
14
modules/ecs/private/uuid.cpp
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
#include <ecs/uuid.hpp>
|
||||||
|
|
||||||
|
namespace lt {
|
||||||
|
|
||||||
|
std::mt19937_64 UUID::s_engine = std::mt19937_64(std::random_device()());
|
||||||
|
|
||||||
|
std::uniform_int_distribution<uint64_t>
|
||||||
|
UUID::s_distribution = std::uniform_int_distribution<uint64_t> {};
|
||||||
|
|
||||||
|
UUID::UUID(uint64_t uuid /* = -1 */): m_uuid(uuid == -1 ? s_distribution(s_engine) : uuid)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace lt
|
|
@ -1,6 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <glm/glm.hpp>
|
#include <math/vec4.hpp>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
namespace lt {
|
namespace lt {
|
||||||
|
@ -15,7 +15,7 @@ struct SpriteRendererComponent
|
||||||
|
|
||||||
SpriteRendererComponent(
|
SpriteRendererComponent(
|
||||||
Ref<Texture> _texture,
|
Ref<Texture> _texture,
|
||||||
const glm::vec4 &_tint = glm::vec4(1.0f, 1.0f, 1.0f, 1.0f)
|
const math::vec4 &_tint = math::vec4 { 1.0f, 1.0f, 1.0f, 1.0f }
|
||||||
)
|
)
|
||||||
: texture(std::move(std::move(_texture)))
|
: texture(std::move(std::move(_texture)))
|
||||||
, tint(_tint)
|
, tint(_tint)
|
||||||
|
@ -29,7 +29,7 @@ struct SpriteRendererComponent
|
||||||
|
|
||||||
Ref<Texture> texture;
|
Ref<Texture> texture;
|
||||||
|
|
||||||
glm::vec4 tint {};
|
math::vec4 tint {};
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace lt
|
} // namespace lt
|
43
modules/ecs/public/components/transform.hpp
Normal file
43
modules/ecs/public/components/transform.hpp
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <math/mat4.hpp>
|
||||||
|
#include <math/vec3.hpp>
|
||||||
|
|
||||||
|
namespace lt {
|
||||||
|
|
||||||
|
struct TransformComponent
|
||||||
|
{
|
||||||
|
TransformComponent(const TransformComponent &) = default;
|
||||||
|
|
||||||
|
TransformComponent(
|
||||||
|
const math::vec3 &_translation = math::vec3(0.0f, 0.0f, 0.0f),
|
||||||
|
const math::vec3 &_scale = math::vec3(1.0f, 1.0f, 1.0f),
|
||||||
|
const math::vec3 &_rotation = math::vec3(0.0f, 0.0f, 0.0f)
|
||||||
|
)
|
||||||
|
|
||||||
|
: translation(_translation)
|
||||||
|
, scale(_scale)
|
||||||
|
, rotation(_rotation)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] auto get_transform() const -> math::mat4
|
||||||
|
{
|
||||||
|
return math::translate(translation)
|
||||||
|
* math::rotate(rotation.z, math::vec3 { 0.0f, 0.0f, 1.0f }) //
|
||||||
|
* math::scale(scale);
|
||||||
|
}
|
||||||
|
|
||||||
|
operator const math::mat4() const
|
||||||
|
{
|
||||||
|
return get_transform();
|
||||||
|
}
|
||||||
|
|
||||||
|
math::vec3 translation;
|
||||||
|
|
||||||
|
math::vec3 scale;
|
||||||
|
|
||||||
|
math::vec3 rotation;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace lt
|
|
@ -3,7 +3,7 @@
|
||||||
#include <ecs/components/transform.hpp>
|
#include <ecs/components/transform.hpp>
|
||||||
#include <ecs/uuid.hpp>
|
#include <ecs/uuid.hpp>
|
||||||
#include <entt/entt.hpp>
|
#include <entt/entt.hpp>
|
||||||
#include <glm/glm.hpp>
|
#include <functional>
|
||||||
|
|
||||||
namespace lt {
|
namespace lt {
|
||||||
|
|
||||||
|
@ -13,11 +13,17 @@ class Framebuffer;
|
||||||
class Scene
|
class Scene
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void on_create();
|
template<typename... T>
|
||||||
|
auto group()
|
||||||
|
{
|
||||||
|
return m_registry.group(entt::get<T...>);
|
||||||
|
}
|
||||||
|
|
||||||
void on_update(float deltaTime);
|
template<typename T>
|
||||||
|
auto view()
|
||||||
void on_render(const Ref<Framebuffer> &targetFrameBuffer = nullptr);
|
{
|
||||||
|
return m_registry.view<T>();
|
||||||
|
}
|
||||||
|
|
||||||
auto create_entity(
|
auto create_entity(
|
||||||
const std::string &name,
|
const std::string &name,
|
||||||
|
@ -26,6 +32,12 @@ public:
|
||||||
|
|
||||||
auto get_entity_by_tag(const std::string &tag) -> Entity;
|
auto get_entity_by_tag(const std::string &tag) -> Entity;
|
||||||
|
|
||||||
|
auto get_entt_registry() -> entt::registry &
|
||||||
|
{
|
||||||
|
return m_registry;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class Entity;
|
friend class Entity;
|
||||||
|
|
||||||
|
@ -42,4 +54,12 @@ private:
|
||||||
) -> Entity;
|
) -> Entity;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
namespace ecs {
|
||||||
|
|
||||||
|
using Registry = Scene;
|
||||||
|
|
||||||
|
using Entity = ::lt::Entity;
|
||||||
|
|
||||||
|
} // namespace ecs
|
||||||
|
|
||||||
} // namespace lt
|
} // namespace lt
|
|
@ -1,111 +0,0 @@
|
||||||
#include <camera/component.hpp>
|
|
||||||
#include <ecs/components.hpp>
|
|
||||||
#include <ecs/entity.hpp>
|
|
||||||
#include <ecs/scene.hpp>
|
|
||||||
#include <glm/glm.hpp>
|
|
||||||
#include <renderer/renderer.hpp>
|
|
||||||
|
|
||||||
namespace lt {
|
|
||||||
|
|
||||||
void Scene::on_create()
|
|
||||||
{
|
|
||||||
/* native scripts */
|
|
||||||
{
|
|
||||||
m_registry.view<NativeScriptComponent>().each([](NativeScriptComponent &nsc) {
|
|
||||||
if (nsc.instance == nullptr)
|
|
||||||
{
|
|
||||||
nsc.instance = nsc.CreateInstance();
|
|
||||||
nsc.instance->on_create();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Scene::on_update(float deltaTime)
|
|
||||||
{
|
|
||||||
/* native scripts */
|
|
||||||
{
|
|
||||||
m_registry.view<NativeScriptComponent>().each([=](NativeScriptComponent &nsc) {
|
|
||||||
nsc.instance->on_update(deltaTime);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Scene::on_render(const Ref<Framebuffer> &targetFrameBuffer /* = nullptr */)
|
|
||||||
{
|
|
||||||
auto *sceneCamera = (Camera *)nullptr;
|
|
||||||
auto *sceneCameraTransform = (TransformComponent *)nullptr;
|
|
||||||
|
|
||||||
/* scene camera */
|
|
||||||
{
|
|
||||||
m_registry.group(entt::get<TransformComponent, CameraComponent>)
|
|
||||||
.each([&](TransformComponent &transformComp, CameraComponent &cameraComp) {
|
|
||||||
if (cameraComp.isPrimary)
|
|
||||||
{
|
|
||||||
sceneCamera = &cameraComp.camera;
|
|
||||||
sceneCameraTransform = &transformComp;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/* draw quads */
|
|
||||||
{
|
|
||||||
if (sceneCamera)
|
|
||||||
{
|
|
||||||
Renderer::begin_scene(sceneCamera, *sceneCameraTransform, targetFrameBuffer);
|
|
||||||
|
|
||||||
m_registry.group(entt::get<TransformComponent, SpriteRendererComponent>)
|
|
||||||
.each([](TransformComponent &transformComp,
|
|
||||||
SpriteRendererComponent &spriteRendererComp) {
|
|
||||||
Renderer::draw_quad(
|
|
||||||
transformComp,
|
|
||||||
spriteRendererComp.tint,
|
|
||||||
spriteRendererComp.texture
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
Renderer::end_scene();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
auto Scene::create_entity(const std::string &name, const TransformComponent &transform) -> Entity
|
|
||||||
{
|
|
||||||
return create_entity_with_uuid(name, UUID(), transform);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto Scene::get_entity_by_tag(const std::string &tag) -> Entity
|
|
||||||
{
|
|
||||||
// TagComponent tagComp(tag);
|
|
||||||
// entt::entity entity = entt::to_entity(m_registry, tagComp);
|
|
||||||
auto entity = Entity {};
|
|
||||||
|
|
||||||
m_registry.view<TagComponent>().each([&](TagComponent &tagComp) {
|
|
||||||
// if (tagComp.tag == tag)
|
|
||||||
// entity = entity(entt::to_entity(m_registry, tagComp), this);
|
|
||||||
});
|
|
||||||
|
|
||||||
if (entity.is_valid())
|
|
||||||
{
|
|
||||||
return entity;
|
|
||||||
}
|
|
||||||
|
|
||||||
ensure(false, "Scene::get_entity_by_tag: failed to find entity by tag: {}", tag);
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
auto Scene::create_entity_with_uuid(
|
|
||||||
const std::string &name,
|
|
||||||
UUID uuid,
|
|
||||||
const TransformComponent &transform
|
|
||||||
) -> Entity
|
|
||||||
{
|
|
||||||
auto entity = Entity { m_registry.create(), this };
|
|
||||||
entity.add_component<TagComponent>(name);
|
|
||||||
entity.add_component<TransformComponent>(transform);
|
|
||||||
entity.add_component<UUIDComponent>(uuid);
|
|
||||||
|
|
||||||
return entity;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace lt
|
|
|
@ -1,12 +0,0 @@
|
||||||
#include <ecs/uuid.hpp>
|
|
||||||
|
|
||||||
namespace lt {
|
|
||||||
|
|
||||||
auto UUID::s_engine = std::mt19937_64(std::random_device()());
|
|
||||||
auto UUID::s_distribution = std::uniform_int_distribution<uint64_t> {};
|
|
||||||
|
|
||||||
UUID::UUID(uint64_t uuid /* = -1 */): m_uuid(uuid == -1 ? s_distribution(s_engine) : uuid)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace lt
|
|
|
@ -1,2 +1,2 @@
|
||||||
add_library_module(input input.cpp)
|
add_library_module(input input.cpp)
|
||||||
target_link_libraries(input PUBLIC spdlog::spdlog glm::glm imgui logger)
|
target_link_libraries(input PUBLIC surface math imgui::imgui logger)
|
||||||
|
|
|
@ -1,41 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <input/events/event.hpp>
|
|
||||||
#include <sstream>
|
|
||||||
|
|
||||||
namespace lt {
|
|
||||||
|
|
||||||
class SetCharEvent: public Event
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
SetCharEvent(unsigned int character): m_character(character)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] auto get_character() const -> int
|
|
||||||
{
|
|
||||||
return m_character;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] auto get_info_lt_log() const -> std::string override
|
|
||||||
{
|
|
||||||
std::stringstream ss;
|
|
||||||
ss << "CharSet: " << m_character;
|
|
||||||
return ss.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] auto get_event_type() const -> EventType override
|
|
||||||
{
|
|
||||||
return ::lt::EventType::SetChar;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] auto has_category(EventCategory category) const -> bool override
|
|
||||||
{
|
|
||||||
return static_cast<uint8_t>(InputEventCategory | KeyboardEventCategory) & category;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
const unsigned int m_character;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace lt
|
|
|
@ -1,56 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
namespace lt {
|
|
||||||
|
|
||||||
enum class EventType : uint8_t
|
|
||||||
{
|
|
||||||
None = 0,
|
|
||||||
|
|
||||||
// input
|
|
||||||
MouseMoved,
|
|
||||||
WheelScrolled,
|
|
||||||
ButtonPressed,
|
|
||||||
ButtonReleased,
|
|
||||||
KeyPressed,
|
|
||||||
KeyRepeated,
|
|
||||||
KeyReleased,
|
|
||||||
SetChar,
|
|
||||||
|
|
||||||
// window
|
|
||||||
WindowMoved,
|
|
||||||
WindowResized,
|
|
||||||
WindowClosed,
|
|
||||||
WindowLostFocus,
|
|
||||||
WindowGainFocus,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum EventCategory : uint8_t
|
|
||||||
{
|
|
||||||
None = 0,
|
|
||||||
|
|
||||||
WindowEventCategory = bit(0),
|
|
||||||
InputEventCategory = bit(1),
|
|
||||||
KeyboardEventCategory = bit(2),
|
|
||||||
MouseEventCategory = bit(3),
|
|
||||||
};
|
|
||||||
|
|
||||||
class Event
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Event() = default;
|
|
||||||
|
|
||||||
virtual ~Event() = default;
|
|
||||||
|
|
||||||
[[nodiscard]] virtual auto get_event_type() const -> EventType = 0;
|
|
||||||
|
|
||||||
[[nodiscard]] virtual auto get_info_lt_log() const -> std::string = 0;
|
|
||||||
|
|
||||||
[[nodiscard]] virtual auto has_category(EventCategory category) const -> bool = 0;
|
|
||||||
|
|
||||||
friend auto operator<<(std::ostream &os, const Event &e) -> std::ostream &
|
|
||||||
{
|
|
||||||
return os << e.get_info_lt_log();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace lt
|
|
|
@ -1,107 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <input/events/event.hpp>
|
|
||||||
#include <sstream>
|
|
||||||
|
|
||||||
namespace lt {
|
|
||||||
|
|
||||||
class KeyPressedEvent: public Event
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
KeyPressedEvent(int key): m_key(key)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] auto get_key() const -> int
|
|
||||||
{
|
|
||||||
return m_key;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] auto get_info_lt_log() const -> std::string override
|
|
||||||
{
|
|
||||||
std::stringstream ss;
|
|
||||||
ss << "KeyPressed: " << m_key;
|
|
||||||
return ss.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] auto get_event_type() const -> EventType override
|
|
||||||
{
|
|
||||||
return ::lt::EventType::KeyPressed;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] auto has_category(EventCategory category) const -> bool override
|
|
||||||
{
|
|
||||||
return static_cast<uint8_t>(InputEventCategory | KeyboardEventCategory) & category;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
const int m_key;
|
|
||||||
};
|
|
||||||
|
|
||||||
class KeyRepeatEvent: public Event
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
KeyRepeatEvent(int key): m_key(key)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] auto get_key() const -> int
|
|
||||||
{
|
|
||||||
return m_key;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] auto get_info_lt_log() const -> std::string override
|
|
||||||
{
|
|
||||||
std::stringstream ss;
|
|
||||||
ss << "KeyRepeated: " << m_key;
|
|
||||||
return ss.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] auto get_event_type() const -> EventType override
|
|
||||||
{
|
|
||||||
return ::lt::EventType::KeyRepeated;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] auto has_category(EventCategory category) const -> bool override
|
|
||||||
{
|
|
||||||
return static_cast<uint8_t>(InputEventCategory | KeyboardEventCategory) & category;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
const int m_key;
|
|
||||||
};
|
|
||||||
|
|
||||||
class KeyReleasedEvent: public Event
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
KeyReleasedEvent(int key): m_key(key)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] auto get_key() const -> int
|
|
||||||
{
|
|
||||||
return m_key;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] auto get_info_lt_log() const -> std::string override
|
|
||||||
{
|
|
||||||
std::stringstream ss;
|
|
||||||
ss << "KeyReleased: " << m_key;
|
|
||||||
return ss.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] auto get_event_type() const -> EventType override
|
|
||||||
{
|
|
||||||
return ::lt::EventType::KeyReleased;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] auto has_category(EventCategory category) const -> bool override
|
|
||||||
{
|
|
||||||
return static_cast<uint8_t>(InputEventCategory | KeyboardEventCategory) & category;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
const int m_key;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace lt
|
|
|
@ -1,151 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <glm/glm.hpp>
|
|
||||||
#include <input/events/event.hpp>
|
|
||||||
#include <sstream>
|
|
||||||
|
|
||||||
namespace lt {
|
|
||||||
|
|
||||||
class MouseMovedEvent: public Event
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
MouseMovedEvent(float x, float y): m_position(x, y)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] auto get_position() const -> const glm::vec2 &
|
|
||||||
{
|
|
||||||
return m_position;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] auto get_x() const -> float
|
|
||||||
{
|
|
||||||
return m_position.x;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] auto get_y() const -> float
|
|
||||||
{
|
|
||||||
return m_position.y;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] auto get_info_lt_log() const -> std::string override
|
|
||||||
{
|
|
||||||
std::stringstream ss;
|
|
||||||
ss << "MouseMoved: " << m_position.x << ", " << m_position.y;
|
|
||||||
return ss.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] auto get_event_type() const -> EventType override
|
|
||||||
{
|
|
||||||
return ::lt::EventType::MouseMoved;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] auto has_category(EventCategory category) const -> bool override
|
|
||||||
{
|
|
||||||
return static_cast<uint8_t>(InputEventCategory | MouseEventCategory) & category;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
const glm::vec2 m_position;
|
|
||||||
};
|
|
||||||
|
|
||||||
class WheelScrolledEvent: public Event
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
WheelScrolledEvent(float offset): m_offset(offset)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] auto get_offset() const -> float
|
|
||||||
{
|
|
||||||
return m_offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] auto get_info_lt_log() const -> std::string override
|
|
||||||
{
|
|
||||||
std::stringstream ss;
|
|
||||||
ss << "WheelScrolled: " << m_offset;
|
|
||||||
return ss.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] auto get_event_type() const -> EventType override
|
|
||||||
{
|
|
||||||
return ::lt::EventType::WheelScrolled;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] auto has_category(EventCategory category) const -> bool override
|
|
||||||
{
|
|
||||||
return static_cast<uint8_t>(InputEventCategory | MouseEventCategory) & category;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
const float m_offset;
|
|
||||||
};
|
|
||||||
|
|
||||||
class ButtonPressedEvent: public Event
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ButtonPressedEvent(int button): m_button(button)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] auto get_button() const -> int
|
|
||||||
{
|
|
||||||
return m_button;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] auto get_info_lt_log() const -> std::string override
|
|
||||||
{
|
|
||||||
std::stringstream ss;
|
|
||||||
ss << "ButtonPressed: " << m_button;
|
|
||||||
return ss.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] auto get_event_type() const -> EventType override
|
|
||||||
{
|
|
||||||
return ::lt::EventType::ButtonPressed;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] auto has_category(EventCategory category) const -> bool override
|
|
||||||
{
|
|
||||||
return static_cast<uint8_t>(InputEventCategory | MouseEventCategory) & category;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
const int m_button;
|
|
||||||
};
|
|
||||||
|
|
||||||
class ButtonReleasedEvent: public Event
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ButtonReleasedEvent(int button): m_button(button)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] auto get_button() const -> int
|
|
||||||
{
|
|
||||||
return m_button;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] auto get_info_lt_log() const -> std::string override
|
|
||||||
{
|
|
||||||
std::stringstream ss;
|
|
||||||
ss << "ButtonReleased: " << m_button;
|
|
||||||
return ss.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] auto get_event_type() const -> EventType override
|
|
||||||
{
|
|
||||||
return ::lt::EventType::ButtonReleased;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] auto has_category(EventCategory category) const -> bool override
|
|
||||||
{
|
|
||||||
return static_cast<uint8_t>(InputEventCategory | MouseEventCategory) & category;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
const int m_button;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace lt
|
|
|
@ -1,133 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <glm/glm.hpp>
|
|
||||||
#include <input/events/event.hpp>
|
|
||||||
#include <sstream>
|
|
||||||
|
|
||||||
namespace lt {
|
|
||||||
|
|
||||||
class WindowClosedEvent: public Event
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
[[nodiscard]] auto get_info_lt_log() const -> std::string override
|
|
||||||
{
|
|
||||||
return "WindowClosedEvent";
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] auto get_event_type() const -> EventType override
|
|
||||||
{
|
|
||||||
return ::lt::EventType::WindowClosed;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] auto has_category(EventCategory category) const -> bool override
|
|
||||||
{
|
|
||||||
return static_cast<uint8_t>(WindowEventCategory) & category;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class WindowMovedEvent: public Event
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
WindowMovedEvent(int x, int y): m_position(x, y)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] auto get_position() const -> const glm::ivec2 &
|
|
||||||
{
|
|
||||||
return m_position;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] auto get_info_lt_log() const -> std::string override
|
|
||||||
{
|
|
||||||
std::stringstream ss;
|
|
||||||
ss << "WindwoMoved: " << m_position.x << ", " << m_position.y;
|
|
||||||
return ss.str();
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] auto get_event_type() const -> EventType override
|
|
||||||
{
|
|
||||||
return ::lt::EventType::WindowMoved;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] auto has_category(EventCategory category) const -> bool override
|
|
||||||
{
|
|
||||||
return static_cast<uint8_t>(WindowEventCategory) & category;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
const glm::ivec2 m_position;
|
|
||||||
};
|
|
||||||
|
|
||||||
class WindowResizedEvent: public Event
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
WindowResizedEvent(unsigned int width, unsigned int height): m_size(width, height)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] auto get_size() const -> const glm::uvec2 &
|
|
||||||
{
|
|
||||||
return m_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] auto get_info_lt_log() const -> std::string override
|
|
||||||
{
|
|
||||||
std::stringstream ss;
|
|
||||||
ss << "WindowResized: " << m_size.x << ", " << m_size.y;
|
|
||||||
return ss.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] auto get_event_type() const -> EventType override
|
|
||||||
{
|
|
||||||
return ::lt::EventType::WindowResized;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] auto has_category(EventCategory category) const -> bool override
|
|
||||||
{
|
|
||||||
return static_cast<uint8_t>(WindowEventCategory) & category;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
const glm::uvec2 m_size;
|
|
||||||
};
|
|
||||||
|
|
||||||
class WindowLostFocusEvent: public Event
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
[[nodiscard]] auto get_info_lt_log() const -> std::string override
|
|
||||||
{
|
|
||||||
return "WindowLostFocus";
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] auto get_event_type() const -> EventType override
|
|
||||||
{
|
|
||||||
return ::lt::EventType::WindowLostFocus;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] auto has_category(EventCategory category) const -> bool override
|
|
||||||
{
|
|
||||||
return static_cast<uint8_t>(WindowEventCategory) & category;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class WindowGainFocusEvent: public Event
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
[[nodiscard]] auto get_info_lt_log() const -> std::string override
|
|
||||||
{
|
|
||||||
return "WindowGainFocus";
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] auto get_event_type() const -> EventType override
|
|
||||||
{
|
|
||||||
return ::lt::EventType::WindowGainFocus;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] auto has_category(EventCategory category) const -> bool override
|
|
||||||
{
|
|
||||||
return static_cast<uint8_t>(WindowEventCategory) & category;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace lt
|
|
|
@ -1,10 +1,5 @@
|
||||||
#include <imgui.h>
|
#include <imgui.h>
|
||||||
#include <input/events/char.hpp>
|
|
||||||
#include <input/events/event.hpp>
|
|
||||||
#include <input/events/keyboard.hpp>
|
|
||||||
#include <input/events/mouse.hpp>
|
|
||||||
#include <input/input.hpp>
|
#include <input/input.hpp>
|
||||||
#include <input/key_codes.hpp>
|
|
||||||
#include <logger/logger.hpp>
|
#include <logger/logger.hpp>
|
||||||
|
|
||||||
namespace lt {
|
namespace lt {
|
||||||
|
@ -36,8 +31,8 @@ void Input::restart_input_state()
|
||||||
m_keyboad_keys.fill(false);
|
m_keyboad_keys.fill(false);
|
||||||
m_mouse_buttons.fill(false);
|
m_mouse_buttons.fill(false);
|
||||||
|
|
||||||
m_mouse_position = glm::vec2(0.0f);
|
m_mouse_position = math::vec2(0.0f);
|
||||||
m_mouse_delta = glm::vec2(0.0f);
|
m_mouse_delta = math::vec2(0.0f);
|
||||||
m_mouse_wheel_delta = 0.0f;
|
m_mouse_wheel_delta = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
5
modules/input/private/system.cpp
Normal file
5
modules/input/private/system.cpp
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
#include <input/system.hpp>
|
||||||
|
|
||||||
|
namespace lt::input {
|
||||||
|
|
||||||
|
} // namespace lt::input
|
|
@ -1,7 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <glm/glm.hpp>
|
#include <math/vec2.hpp>
|
||||||
|
|
||||||
namespace lt {
|
namespace lt {
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ public:
|
||||||
return instance().m_mouse_buttons[code];
|
return instance().m_mouse_buttons[code];
|
||||||
}
|
}
|
||||||
|
|
||||||
static auto get_mouse_position(int /*code*/) -> const glm::vec2 &
|
static auto get_mouse_position(int /*code*/) -> const math::vec2 &
|
||||||
{
|
{
|
||||||
return instance().m_mouse_position;
|
return instance().m_mouse_position;
|
||||||
}
|
}
|
||||||
|
@ -66,9 +66,9 @@ private:
|
||||||
|
|
||||||
std::array<bool, 8> m_mouse_buttons {};
|
std::array<bool, 8> m_mouse_buttons {};
|
||||||
|
|
||||||
glm::vec2 m_mouse_position;
|
math::vec2 m_mouse_position;
|
||||||
|
|
||||||
glm::vec2 m_mouse_delta;
|
math::vec2 m_mouse_delta;
|
||||||
|
|
||||||
float m_mouse_wheel_delta {};
|
float m_mouse_wheel_delta {};
|
||||||
|
|
64
modules/input/public/system.hpp
Normal file
64
modules/input/public/system.hpp
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <surface/system.hpp>
|
||||||
|
|
||||||
|
namespace lt::input {
|
||||||
|
|
||||||
|
template<class... Ts>
|
||||||
|
struct overloads: Ts...
|
||||||
|
{
|
||||||
|
using Ts::operator()...;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @note If this system is attached, it will always consume the input events f rom surface.
|
||||||
|
* Therefore if you want any input detection mechanism, callbacks should be setup with this
|
||||||
|
* system and not directly with surface.
|
||||||
|
*/
|
||||||
|
class System
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
System(lt::surface::System &surface_system)
|
||||||
|
{
|
||||||
|
surface_system.add_event_listener([this](auto &&event) {
|
||||||
|
return handle_event(std::forward<decltype(event)>(event));
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
auto handle_event(const lt::surface::System::Event &event) -> bool
|
||||||
|
{
|
||||||
|
const auto visitor = overloads {
|
||||||
|
[this](const lt::surface::KeyPressedEvent &event) {
|
||||||
|
m_keys[event.get_key()] = true;
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
|
||||||
|
[](const lt::surface::KeyRepeatEvent &) { return false; },
|
||||||
|
|
||||||
|
[](const lt::surface::KeyReleasedEvent &) { return false; },
|
||||||
|
|
||||||
|
[](const lt::surface::KeySetCharEvent &) { return false; },
|
||||||
|
|
||||||
|
[](const lt::surface::MouseMovedEvent &) { return false; },
|
||||||
|
|
||||||
|
[](const lt::surface::WheelScrolledEvent &) { return false; },
|
||||||
|
|
||||||
|
[](const lt::surface::ButtonPressedEvent &) { return false; },
|
||||||
|
|
||||||
|
[](const lt::surface::ButtonReleasedEvent &) { return false; },
|
||||||
|
|
||||||
|
[](const auto &) { return false; },
|
||||||
|
};
|
||||||
|
|
||||||
|
return std::visit(visitor, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setup_callbacks(GLFWwindow *handle);
|
||||||
|
|
||||||
|
std::array<bool, 512> m_keys {};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace lt::input
|
|
@ -1,2 +1 @@
|
||||||
add_library_module(logger logger.cpp)
|
add_library_module(logger logger.cpp)
|
||||||
target_link_libraries(logger PUBLIC spdlog::spdlog)
|
|
||||||
|
|
1
modules/logger/private/logger.cpp
Normal file
1
modules/logger/private/logger.cpp
Normal file
|
@ -0,0 +1 @@
|
||||||
|
#include <logger/logger.hpp>
|
|
@ -1,15 +1,9 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <format>
|
#include <format>
|
||||||
#include <memory>
|
#include <print>
|
||||||
#include <spdlog/sinks/basic_file_sink.h>
|
|
||||||
#include <spdlog/sinks/stdout_color_sinks.h>
|
|
||||||
#include <spdlog/spdlog.h>
|
|
||||||
|
|
||||||
/** @brief Severity of a log message.
|
/** Severity of a log message. */
|
||||||
*
|
|
||||||
* @note Values reflect spdlog::lvl
|
|
||||||
*/
|
|
||||||
enum class LogLvl : uint8_t
|
enum class LogLvl : uint8_t
|
||||||
{
|
{
|
||||||
/** Lowest and most vebose log level, for tracing execution paths and events */
|
/** Lowest and most vebose log level, for tracing execution paths and events */
|
||||||
|
@ -34,11 +28,7 @@ enum class LogLvl : uint8_t
|
||||||
off = 6,
|
off = 6,
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace spdlog {
|
/** Simple console logger */
|
||||||
class logger;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Responsible for logging */
|
|
||||||
class Logger
|
class Logger
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -47,26 +37,19 @@ public:
|
||||||
template<typename... Args>
|
template<typename... Args>
|
||||||
void static log(LogLvl lvl, std::format_string<Args...> fmt, Args &&...args)
|
void static log(LogLvl lvl, std::format_string<Args...> fmt, Args &&...args)
|
||||||
{
|
{
|
||||||
instance().spd_logger->log(
|
std::ignore = lvl;
|
||||||
(spdlog::level::level_enum)lvl,
|
std::println(fmt, std::forward<Args>(args)...);
|
||||||
std::format(fmt, std::forward<Args>(args)...)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void static log(LogLvl lvl, const char *message)
|
void static log(LogLvl lvl, const char *message)
|
||||||
{
|
{
|
||||||
instance().spd_logger->log((spdlog::level::level_enum)lvl, message);
|
std::ignore = lvl;
|
||||||
|
std::println("{}", message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Logger();
|
Logger() = default;
|
||||||
|
|
||||||
~Logger();
|
|
||||||
|
|
||||||
auto static instance() -> Logger &;
|
|
||||||
|
|
||||||
std::shared_ptr<spdlog::logger> spd_logger;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename... Args>
|
template<typename... Args>
|
|
@ -1,18 +0,0 @@
|
||||||
#include <logger/logger.hpp>
|
|
||||||
|
|
||||||
Logger::Logger(): spd_logger(spdlog::stdout_color_mt("Logger"))
|
|
||||||
{
|
|
||||||
spd_logger->set_pattern("%^%v%$");
|
|
||||||
spd_logger->set_level(spdlog::level::level_enum::trace);
|
|
||||||
}
|
|
||||||
|
|
||||||
Logger::~Logger()
|
|
||||||
{
|
|
||||||
spdlog::drop_all();
|
|
||||||
}
|
|
||||||
|
|
||||||
auto Logger::instance() -> Logger &
|
|
||||||
{
|
|
||||||
static auto logger = Logger {};
|
|
||||||
return logger;
|
|
||||||
}
|
|
1
modules/math/CMakeLists.txt
Normal file
1
modules/math/CMakeLists.txt
Normal file
|
@ -0,0 +1 @@
|
||||||
|
add_library_module(math)
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue