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 2877 deletions
153
.drone.yml
153
.drone.yml
|
@ -1,57 +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
|
||||
type: docker
|
||||
name: clang format
|
||||
clone:
|
||||
recursive: true
|
||||
submodule_update_remote: true
|
||||
|
||||
name: amd64 — gcc
|
||||
trigger:
|
||||
branch:
|
||||
- main
|
||||
|
||||
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
|
||||
image: clang_format:latest
|
||||
pull: if-not-exists
|
||||
commands:
|
||||
- |
|
||||
set -e
|
||||
clang-format --version
|
||||
HAS_ISSUES=0
|
||||
- ./tools/ci/static_analysis/clang_format.sh
|
||||
|
||||
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_ISSUES=1
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$HAS_ISSUES" -eq 0 ]; then
|
||||
echo "✅ All files are properly formatted! Well done! ^~^"
|
||||
else
|
||||
echo "❌ Senpai! There was some formatting issues :c"
|
||||
fi
|
||||
|
||||
exit $HAS_ISSUES
|
||||
---
|
||||
|
||||
kind: pipeline
|
||||
type: docker
|
||||
name: static analysis
|
||||
clone:
|
||||
recursive: true
|
||||
submodule_update_remote: true
|
||||
|
||||
name: documentation — development
|
||||
node:
|
||||
environment: ryali
|
||||
trigger:
|
||||
branch:
|
||||
- main
|
||||
|
||||
steps:
|
||||
- name: static_analysis
|
||||
image: static_analysis:latest
|
||||
- name: build and deploy
|
||||
image: documentation:latest
|
||||
pull: if-not-exists
|
||||
privileged: true
|
||||
commands:
|
||||
- git submodule update --init --recursive
|
||||
- conan build . -s build_type=Release -o enable_static_analysis=True --build=missing
|
||||
- pwd
|
||||
- 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)
|
||||
project(Light)
|
||||
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)
|
||||
set(CMAKE_CXX_CLANG_TIDY "clang-tidy;--warnings-as-errors=*;--allow-no-checks")
|
||||
endif ()
|
||||
|
||||
if(WIN32)
|
||||
add_compile_definitions(LIGHT_PLATFORM_WINDOWS)
|
||||
elseif(UNIX)
|
||||
add_compile_definitions(LIGHT_PLATFORM_LINUX)
|
||||
endif()
|
||||
add_option(ENABLE_LLVM_COVERAGE "Enables the code coverage instrumentation for clang")
|
||||
if(ENABLE_LLVM_COVERAGE)
|
||||
if (NOT "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
|
||||
message(FATAL_ERROR "ENABLE_LLVM_COVERAGE only supports the clang compiler")
|
||||
endif ()
|
||||
|
||||
find_package(glfw3 REQUIRED)
|
||||
find_package(glm REQUIRED)
|
||||
find_package(spdlog REQUIRED)
|
||||
find_package(stb REQUIRED)
|
||||
find_package(yaml-cpp REQUIRED)
|
||||
find_package(EnTT REQUIRED)
|
||||
find_package(opengl_system REQUIRED)
|
||||
find_package(nlohmann_json REQUIRED)
|
||||
find_package(lz4 REQUIRED)
|
||||
# Check for libc++
|
||||
check_cxx_source_compiles("
|
||||
#include <string>
|
||||
#ifdef _LIBCPP_VERSION
|
||||
int main() { return 0; }
|
||||
#else
|
||||
#error Not using libc++
|
||||
#endif
|
||||
" USING_LIBCXX)
|
||||
if(NOT USING_LIBCXX)
|
||||
message(FATAL_ERROR "ENABLE_LLVM_COVERAGE requires libc++, please compile with -stdlib=libc++")
|
||||
endif()
|
||||
|
||||
add_subdirectory(./modules)
|
||||
add_subdirectory(./external)
|
||||
add_compile_options(-fprofile-instr-generate -fcoverage-mapping)
|
||||
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
|
||||
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"
|
||||
|
||||
options = {
|
||||
"enable_unit_tests": [True, False],
|
||||
"enable_fuzz_tests": [True, False],
|
||||
"enable_llvm_coverage": [True, False],
|
||||
"enable_static_analysis": [True, False],
|
||||
"use_mold": [True, False],
|
||||
"export_compile_commands": [True, False],
|
||||
}
|
||||
|
||||
default_options = {
|
||||
"export_compile_commands": True,
|
||||
"enable_unit_tests": True,
|
||||
"enable_fuzz_tests": False,
|
||||
"enable_llvm_coverage": False,
|
||||
"enable_static_analysis": False,
|
||||
"use_mold": False,
|
||||
"export_compile_commands": True,
|
||||
}
|
||||
|
||||
def requirements(self):
|
||||
self.requires("gtest/1.16.0")
|
||||
self.requires("imgui/1.92.0-docking")
|
||||
self.requires("entt/3.15.0")
|
||||
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("volk/1.3.296.0")
|
||||
self.requires("yaml-cpp/0.8.0")
|
||||
self.requires("nlohmann_json/3.12.0")
|
||||
self.requires("lz4/1.10.0")
|
||||
|
||||
def layout(self):
|
||||
|
@ -41,7 +44,13 @@ class LightRecipe(ConanFile):
|
|||
|
||||
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["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
|
||||
|
||||
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
|
||||
===================================================================================================
|
||||
Layout
|
||||
|
||||
On Disk (file) Layout
|
||||
---------------------------------------------------------------------------------------------------
|
||||
{version} | 4 bytes, ie. uint32_t
|
||||
{general metadata} | sizeof(AssetMetadata)
|
||||
{specialized metadata} | sizeof(XXXAssetMetadata), eg. TextureAssetMetadata
|
||||
{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
|
||||
|
||||
.. code-block:: md
|
||||
|
||||
{version} | 4 bytes, ie. uint32_t
|
||||
{general metadata} | sizeof(AssetMetadata)
|
||||
{specialized metadata} | sizeof(XXXAssetMetadata), eg. TextureAssetMetadata
|
||||
{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
|
||||
---------------------------------------------------------------------------------------------------
|
||||
version -> The version of the asset for forward compatibility
|
||||
general metadata -> Common asset metadata such as file-path, asset-type, creator, etc.
|
||||
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.
|
||||
|
||||
.. code-block:: md
|
||||
|
||||
version -> The version of the asset for forward compatibility
|
||||
general metadata -> Common asset metadata such as file-path, asset-type, creator, etc.
|
||||
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
|
||||
---------------------------------------------------------------------------------------------------
|
||||
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
|
||||
|
||||
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. SomeOtherImgLoader -> outputs TextureAsset
|
||||
|
||||
Multiple `Loader`s SHOULD NOT have as input same extension types
|
||||
eg. .jpg, .png -> if supported, should only be supported by 1 `Loader` class
|
||||
Multiple **Loader**\s SHOULD NOT have as input same extension types
|
||||
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
|
||||
understandable by a `Packer` (not the engine itself).
|
||||
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).
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
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
|
||||
---------------------------------------------------------------------------------------------------
|
||||
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. 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)
|
||||
|
||||
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.
|
||||
|
||||
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. 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(./logger)
|
||||
add_subdirectory(./debug)
|
||||
|
||||
add_subdirectory(./math)
|
||||
#
|
||||
add_subdirectory(./asset_baker)
|
||||
add_subdirectory(./asset_parser)
|
||||
add_subdirectory(./asset_manager)
|
||||
|
||||
# add_subdirectory(./asset_manager)
|
||||
#
|
||||
add_subdirectory(./camera)
|
||||
add_subdirectory(./input)
|
||||
add_subdirectory(./ui)
|
||||
|
||||
add_subdirectory(./window)
|
||||
add_subdirectory(./renderer)
|
||||
# add_subdirectory(./input)
|
||||
# add_subdirectory(./ui)
|
||||
#
|
||||
add_subdirectory(./surface)
|
||||
# add_subdirectory(./renderer)
|
||||
add_subdirectory(./ecs)
|
||||
|
||||
#
|
||||
add_subdirectory(./app)
|
||||
|
||||
# apps
|
||||
add_subdirectory(./mirror)
|
||||
|
||||
add_subdirectory(test)
|
||||
|
|
|
@ -1,21 +1,2 @@
|
|||
add_library_module(app
|
||||
application.cpp
|
||||
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
|
||||
)
|
||||
add_library_module(app application.cpp)
|
||||
target_link_libraries(app PRIVATE lt_debug)
|
||||
|
|
|
@ -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>
|
||||
|
||||
int main(int argc, char *argv[]) // NOLINT
|
||||
auto main(int argc, char *argv[]) -> int32_t
|
||||
try
|
||||
{
|
||||
std::ignore = argc;
|
||||
std::ignore = argv;
|
||||
|
||||
auto application = lt::Scope<lt::Application> {};
|
||||
auto application = lt::Scope<lt::app::Application> {};
|
||||
|
||||
application = lt::create_application();
|
||||
|
||||
lt::ensure(application, "Failed to create application");
|
||||
lt::ensure(application->sanity_check(), "Failed to verify the sanity of the application");
|
||||
application = lt::app::create_application();
|
||||
if (!application)
|
||||
{
|
||||
throw std::runtime_error { "Failed to create application\n" };
|
||||
}
|
||||
|
||||
application->game_loop();
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
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(
|
||||
asset_baker baker.cpp
|
||||
asset_baker entrypoint/baker.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(
|
||||
|
|
|
@ -131,7 +131,8 @@ public:
|
|||
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 };
|
||||
if (!stream.good())
|
|
@ -5,5 +5,5 @@ add_library_module(asset_manager
|
|||
target_link_libraries(
|
||||
asset_manager
|
||||
PUBLIC asset_parser
|
||||
PRIVATE renderer
|
||||
PRIVATE logger
|
||||
)
|
||||
|
|
|
@ -6,7 +6,6 @@ add_library_module(asset_parser
|
|||
|
||||
target_link_libraries(
|
||||
asset_parser
|
||||
PUBLIC LZ4::lz4_static
|
||||
PUBLIC nlohmann_json::nlohmann_json
|
||||
PUBLIC logger
|
||||
PRIVATE LZ4::lz4_static
|
||||
PRIVATE logger
|
||||
)
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
#include <asset_parser/assets/text.hpp>
|
||||
#include <lz4.h>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
namespace Assets {
|
||||
|
|
@ -1,6 +1,5 @@
|
|||
#include <asset_parser/assets/texture.hpp>
|
||||
#include <lz4.h>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
namespace Assets {
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <asset_parser/compressors/compressors.hpp>
|
||||
#include <asset_parser/parser.hpp>
|
||||
#include <compressors/compressors.hpp>
|
||||
#include <cstdint>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
|
@ -1,7 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <asset_parser/compressors/compressors.hpp>
|
||||
#include <asset_parser/parser.hpp>
|
||||
#include <compressors/compressors.hpp>
|
||||
#include <cstdint>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
|
@ -1,6 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include <compressors/compressors.hpp>
|
||||
#include <asset_parser/compressors/compressors.hpp>
|
||||
#include <cstdint>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
|
@ -1,3 +1,2 @@
|
|||
add_library_module(base)
|
||||
|
||||
target_precompile_headers(base INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/src/pch.hpp)
|
||||
target_precompile_headers(base INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/private/pch.hpp)
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
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 <glm/gtc/matrix_transform.hpp>
|
||||
#include <math/algebra.hpp>
|
||||
#include <math/trig.hpp>
|
||||
|
||||
namespace lt {
|
||||
|
||||
SceneCamera::SceneCamera()
|
||||
: 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,
|
||||
.far_plane = 10000.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()
|
||||
{
|
||||
// TODO(Light): implement ortho perspective
|
||||
if (m_projection_type == ProjectionType::Orthographic)
|
||||
{
|
||||
m_projection = glm::ortho(
|
||||
-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
|
||||
);
|
||||
// throw std::runtime_error { "ortho perspective not supported yet" };
|
||||
}
|
||||
|
||||
// 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
|
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
|
||||
|
||||
#include <camera/scene.hpp>
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
namespace lt {
|
||||
|
|
@ -1,3 +1,3 @@
|
|||
add_library_module(lt_debug instrumentor.cpp)
|
||||
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 <lt_debug/instrumentor.hpp>
|
||||
|
||||
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
|
||||
PUBLIC logger lt_debug EnTT::EnTT renderer input camera
|
||||
PRIVATE yaml-cpp::yaml-cpp asset_manager
|
||||
PUBLIC logger lt_debug EnTT::EnTT input camera math
|
||||
)
|
||||
|
|
|
@ -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 <ecs/components.hpp>
|
||||
#include <ecs/serializer.hpp>
|
||||
#include <math/vec3.hpp>
|
||||
#include <math/vec4.hpp>
|
||||
#include <yaml-cpp/yaml.h>
|
||||
|
||||
namespace YAML {
|
||||
|
||||
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 {};
|
||||
node.push_back(rhs.x);
|
||||
|
@ -18,7 +20,7 @@ struct convert<glm::vec3>
|
|||
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)
|
||||
{
|
||||
|
@ -33,9 +35,9 @@ struct convert<glm::vec3>
|
|||
};
|
||||
|
||||
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 {};
|
||||
node.push_back(rhs.x);
|
||||
|
@ -45,7 +47,7 @@ struct convert<glm::vec4>
|
|||
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)
|
||||
{
|
||||
|
@ -63,14 +65,14 @@ struct convert<glm::vec4>
|
|||
|
||||
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::BeginSeq << v.x << v.y << v.z << YAML::EndSeq;
|
||||
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::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>();
|
||||
|
||||
entityTransforomComponent.translation = transformComponent["Translation"]
|
||||
.as<glm::vec3>();
|
||||
entityTransforomComponent.rotation = transformComponent["Rotation"].as<glm::vec3>();
|
||||
entityTransforomComponent.scale = transformComponent["Scale"].as<glm::vec3>();
|
||||
.as<math::vec3>();
|
||||
entityTransforomComponent.rotation = transformComponent["Rotation"]
|
||||
.as<math::vec3>();
|
||||
entityTransforomComponent.scale = transformComponent["Scale"].as<math::vec3>();
|
||||
}
|
||||
|
||||
/* #TEMPORARY SOLUTION# */
|
||||
|
@ -168,7 +171,7 @@ auto SceneSerializer::deserialize(const std::string &file_path) -> bool
|
|||
auto &entitySpriteRendererComponent = deserializedEntity
|
||||
.add_component<SpriteRendererComponent>();
|
||||
entitySpriteRendererComponent.tint = spriteRendererComponent["Tint"]
|
||||
.as<glm::vec4>();
|
||||
.as<math::vec4>();
|
||||
|
||||
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(
|
||||
cameraSpecifications["BackgroundColor"].as<glm::vec4>()
|
||||
cameraSpecifications["BackgroundColor"].as<math::vec4>()
|
||||
);
|
||||
|
||||
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
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <math/vec4.hpp>
|
||||
#include <utility>
|
||||
|
||||
namespace lt {
|
||||
|
@ -15,7 +15,7 @@ struct SpriteRendererComponent
|
|||
|
||||
SpriteRendererComponent(
|
||||
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)))
|
||||
, tint(_tint)
|
||||
|
@ -29,7 +29,7 @@ struct SpriteRendererComponent
|
|||
|
||||
Ref<Texture> texture;
|
||||
|
||||
glm::vec4 tint {};
|
||||
math::vec4 tint {};
|
||||
};
|
||||
|
||||
} // 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/uuid.hpp>
|
||||
#include <entt/entt.hpp>
|
||||
#include <glm/glm.hpp>
|
||||
#include <functional>
|
||||
|
||||
namespace lt {
|
||||
|
||||
|
@ -13,11 +13,17 @@ class Framebuffer;
|
|||
class Scene
|
||||
{
|
||||
public:
|
||||
void on_create();
|
||||
template<typename... T>
|
||||
auto group()
|
||||
{
|
||||
return m_registry.group(entt::get<T...>);
|
||||
}
|
||||
|
||||
void on_update(float deltaTime);
|
||||
|
||||
void on_render(const Ref<Framebuffer> &targetFrameBuffer = nullptr);
|
||||
template<typename T>
|
||||
auto view()
|
||||
{
|
||||
return m_registry.view<T>();
|
||||
}
|
||||
|
||||
auto create_entity(
|
||||
const std::string &name,
|
||||
|
@ -26,6 +32,12 @@ public:
|
|||
|
||||
auto get_entity_by_tag(const std::string &tag) -> Entity;
|
||||
|
||||
auto get_entt_registry() -> entt::registry &
|
||||
{
|
||||
return m_registry;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
friend class Entity;
|
||||
|
||||
|
@ -42,4 +54,12 @@ private:
|
|||
) -> Entity;
|
||||
};
|
||||
|
||||
namespace ecs {
|
||||
|
||||
using Registry = Scene;
|
||||
|
||||
using Entity = ::lt::Entity;
|
||||
|
||||
} // namespace ecs
|
||||
|
||||
} // 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)
|
||||
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 <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/key_codes.hpp>
|
||||
#include <logger/logger.hpp>
|
||||
|
||||
namespace lt {
|
||||
|
@ -36,8 +31,8 @@ void Input::restart_input_state()
|
|||
m_keyboad_keys.fill(false);
|
||||
m_mouse_buttons.fill(false);
|
||||
|
||||
m_mouse_position = glm::vec2(0.0f);
|
||||
m_mouse_delta = glm::vec2(0.0f);
|
||||
m_mouse_position = math::vec2(0.0f);
|
||||
m_mouse_delta = math::vec2(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
|
||||
|
||||
#include <array>
|
||||
#include <glm/glm.hpp>
|
||||
#include <math/vec2.hpp>
|
||||
|
||||
namespace lt {
|
||||
|
||||
|
@ -36,7 +36,7 @@ public:
|
|||
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;
|
||||
}
|
||||
|
@ -66,9 +66,9 @@ private:
|
|||
|
||||
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 {};
|
||||
|
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)
|
||||
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
|
||||
|
||||
#include <format>
|
||||
#include <memory>
|
||||
#include <spdlog/sinks/basic_file_sink.h>
|
||||
#include <spdlog/sinks/stdout_color_sinks.h>
|
||||
#include <spdlog/spdlog.h>
|
||||
#include <print>
|
||||
|
||||
/** @brief Severity of a log message.
|
||||
*
|
||||
* @note Values reflect spdlog::lvl
|
||||
*/
|
||||
/** Severity of a log message. */
|
||||
enum class LogLvl : uint8_t
|
||||
{
|
||||
/** Lowest and most vebose log level, for tracing execution paths and events */
|
||||
|
@ -34,11 +28,7 @@ enum class LogLvl : uint8_t
|
|||
off = 6,
|
||||
};
|
||||
|
||||
namespace spdlog {
|
||||
class logger;
|
||||
}
|
||||
|
||||
/** Responsible for logging */
|
||||
/** Simple console logger */
|
||||
class Logger
|
||||
{
|
||||
public:
|
||||
|
@ -47,26 +37,19 @@ public:
|
|||
template<typename... Args>
|
||||
void static log(LogLvl lvl, std::format_string<Args...> fmt, Args &&...args)
|
||||
{
|
||||
instance().spd_logger->log(
|
||||
(spdlog::level::level_enum)lvl,
|
||||
std::format(fmt, std::forward<Args>(args)...)
|
||||
);
|
||||
std::ignore = lvl;
|
||||
std::println(fmt, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
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:
|
||||
Logger();
|
||||
|
||||
~Logger();
|
||||
|
||||
auto static instance() -> Logger &;
|
||||
|
||||
std::shared_ptr<spdlog::logger> spd_logger;
|
||||
Logger() = default;
|
||||
};
|
||||
|
||||
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