├── .editorconfig ├── .github ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── bug_report.yml │ └── feature_request.yml └── workflows │ ├── build_engine.yml │ └── deploy_docs.yml ├── .gitignore ├── .gitmodules ├── CMakeLists.txt ├── CODE_OF_CONDUCT.md ├── Doxyfile ├── LICENSE.txt ├── README.md ├── branding ├── README.md ├── doxygen │ └── header_logo.png ├── github │ └── readme_banner.png └── steam │ ├── avatars │ └── spider.png │ ├── community │ ├── capsule.png │ ├── community_group_header.png │ ├── community_icon.ico │ ├── community_icon.png │ ├── devhub_banner.png │ └── workshop_banner.png │ ├── library │ ├── library_capsule.png │ ├── library_hero.png │ └── library_logo.png │ └── store │ ├── store_header_capsule.png │ ├── store_main_capsule.png │ ├── store_small_capsule.png │ └── store_vertical_capsule.png ├── docs ├── layout │ ├── custom.css │ └── header.html └── pages │ ├── filespec │ ├── filespec.md │ ├── material-spec.md │ ├── model-spec.md │ ├── spec-mesh.md │ ├── spec-scene.md │ └── texture-spec.md │ ├── reference │ ├── pluginapi.md │ └── reference.md │ └── tutorial │ ├── setup.md │ └── tutorial.md ├── engine ├── config │ ├── CMakeLists.txt │ ├── ConEntry.cpp │ ├── ConEntry.h │ ├── Config.cpp │ ├── Config.h │ └── generated │ │ └── Config.h.in ├── core │ ├── Assertions.cpp │ ├── Assertions.h │ ├── CMakeLists.txt │ ├── CommandLine.cpp │ ├── CommandLine.h │ ├── Engine.cpp │ ├── Engine.h │ ├── Logger.cpp │ ├── Logger.h │ └── Platform.h ├── engine.cmake ├── entity │ ├── CMakeLists.txt │ ├── Entity.h │ ├── Scene.cpp │ ├── Scene.h │ ├── Viewport.cpp │ ├── Viewport.h │ └── component │ │ ├── AudioNoiseComponent.h │ │ ├── AudioSfxrComponent.h │ │ ├── AudioSpeechComponent.h │ │ ├── AudioWavComponent.h │ │ ├── AudioWavStreamComponent.h │ │ ├── BillboardComponent.h │ │ ├── CMakeLists.txt │ │ ├── CameraComponent.h │ │ ├── LayerComponents.h │ │ ├── LightComponents.h │ │ ├── MeshComponent.h │ │ ├── MeshDynamicComponent.h │ │ ├── MeshSpriteComponent.h │ │ ├── NameComponent.h │ │ ├── SkyboxComponent.h │ │ ├── TagComponents.h │ │ ├── TransformComponent.h │ │ └── UUIDComponent.h ├── i18n │ ├── CMakeLists.txt │ ├── TranslationFileResource.cpp │ ├── TranslationFileResource.h │ ├── TranslationManager.cpp │ └── TranslationManager.h ├── input │ ├── CMakeLists.txt │ ├── InputManager.cpp │ └── InputManager.h ├── loader │ ├── CMakeLists.txt │ ├── image │ │ ├── CMakeLists.txt │ │ ├── Image.cpp │ │ └── Image.h │ ├── mesh │ │ ├── CMakeLists.txt │ │ ├── ChiraMeshLoader.cpp │ │ ├── ChiraMeshLoader.h │ │ ├── IMeshLoader.cpp │ │ ├── IMeshLoader.h │ │ ├── OBJMeshLoader.cpp │ │ └── OBJMeshLoader.h │ └── settings │ │ ├── CMakeLists.txt │ │ ├── ISettingsLoader.cpp │ │ ├── ISettingsLoader.h │ │ ├── JSONSettingsLoader.cpp │ │ └── JSONSettingsLoader.h ├── math │ ├── Axis.h │ ├── CMakeLists.txt │ ├── Color.h │ ├── Graph.h │ ├── Matrix.h │ ├── Types.h │ └── Vertex.h ├── module │ ├── CMakeLists.txt │ ├── Module.cpp │ ├── Module.h │ ├── audio │ │ ├── Audio.cpp │ │ ├── Audio.h │ │ └── CMakeLists.txt │ ├── discord │ │ ├── CMakeLists.txt │ │ ├── Discord.cpp │ │ └── Discord.h │ └── steam │ │ ├── CMakeLists.txt │ │ ├── Steam.cpp │ │ └── Steam.h ├── render │ ├── CMakeLists.txt │ ├── backend │ │ ├── CMakeLists.txt │ │ ├── RenderBackend.h │ │ ├── RenderDevice.h │ │ ├── RenderTypes.cpp │ │ ├── RenderTypes.h │ │ ├── api │ │ │ ├── BackendGL.cpp │ │ │ ├── BackendGL.h │ │ │ ├── BackendSDL.cpp │ │ │ ├── BackendSDL.h │ │ │ └── CMakeLists.txt │ │ └── device │ │ │ ├── CMakeLists.txt │ │ │ ├── DeviceGL.cpp │ │ │ ├── DeviceGL.h │ │ │ ├── DeviceSDL.cpp │ │ │ └── DeviceSDL.h │ ├── material │ │ ├── CMakeLists.txt │ │ ├── MaterialCubemap.cpp │ │ ├── MaterialCubemap.h │ │ ├── MaterialFactory.cpp │ │ ├── MaterialFactory.h │ │ ├── MaterialFrameBuffer.cpp │ │ ├── MaterialFrameBuffer.h │ │ ├── MaterialPhong.cpp │ │ ├── MaterialPhong.h │ │ ├── MaterialTextured.cpp │ │ ├── MaterialTextured.h │ │ ├── MaterialUntextured.cpp │ │ └── MaterialUntextured.h │ ├── mesh │ │ ├── CMakeLists.txt │ │ ├── MeshData.cpp │ │ ├── MeshData.h │ │ ├── MeshDataBuilder.cpp │ │ ├── MeshDataBuilder.h │ │ ├── MeshDataResource.cpp │ │ └── MeshDataResource.h │ ├── shader │ │ ├── CMakeLists.txt │ │ ├── Shader.cpp │ │ ├── Shader.h │ │ ├── UBO.cpp │ │ └── UBO.h │ └── texture │ │ ├── CMakeLists.txt │ │ ├── ITexture.h │ │ ├── Texture.cpp │ │ ├── Texture.h │ │ ├── TextureCubemap.cpp │ │ └── TextureCubemap.h ├── resource │ ├── BinaryResource.cpp │ ├── BinaryResource.h │ ├── CMakeLists.txt │ ├── JSONResource.cpp │ ├── JSONResource.h │ ├── Resource.cpp │ ├── Resource.h │ ├── StringResource.cpp │ ├── StringResource.h │ └── provider │ │ ├── CMakeLists.txt │ │ ├── FilesystemResourceProvider.cpp │ │ ├── FilesystemResourceProvider.h │ │ └── IResourceProvider.h ├── script │ ├── CMakeLists.txt │ ├── Lua.cpp │ └── Lua.h ├── thirdparty │ ├── glad │ │ ├── 40 │ │ │ ├── include │ │ │ │ ├── KHR │ │ │ │ │ └── khrplatform.h │ │ │ │ └── glad │ │ │ │ │ ├── gl.h │ │ │ │ │ └── glversion.h │ │ │ └── src │ │ │ │ └── gl.c │ │ ├── 41 │ │ │ ├── include │ │ │ │ ├── KHR │ │ │ │ │ └── khrplatform.h │ │ │ │ └── glad │ │ │ │ │ ├── gl.h │ │ │ │ │ └── glversion.h │ │ │ └── src │ │ │ │ └── gl.c │ │ ├── 43 │ │ │ ├── include │ │ │ │ ├── KHR │ │ │ │ │ └── khrplatform.h │ │ │ │ └── glad │ │ │ │ │ ├── gl.h │ │ │ │ │ └── glversion.h │ │ │ └── src │ │ │ │ └── gl.c │ │ └── CMakeLists.txt │ └── stb │ │ ├── CMakeLists.txt │ │ └── stb_image.h ├── ui │ ├── CMakeLists.txt │ ├── Font.cpp │ ├── Font.h │ ├── IPanel.cpp │ ├── IPanel.h │ ├── IViewportPanel.cpp │ ├── IViewportPanel.h │ └── debug │ │ ├── CMakeLists.txt │ │ ├── ConsolePanel.cpp │ │ ├── ConsolePanel.h │ │ ├── ResourceUsageTrackerPanel.cpp │ │ └── ResourceUsageTrackerPanel.h └── utility │ ├── AbstractFactory.h │ ├── CMakeLists.txt │ ├── Concepts.h │ ├── DependencyGraph.h │ ├── NoCopyOrMove.h │ ├── Serial.h │ ├── SharedPointer.h │ ├── String.cpp │ ├── String.h │ ├── TypeString.h │ ├── Types.h │ ├── UUIDGenerator.cpp │ └── UUIDGenerator.h ├── resources ├── editor │ ├── i18n │ │ ├── editor_en.json │ │ └── editor_universal.json │ ├── materials │ │ └── teapot.json │ ├── meshes │ │ ├── teapot.cmdl │ │ └── teapot.json │ ├── platform │ │ └── macOS │ │ │ ├── AppIcon.icns │ │ │ └── Info.plist │ └── textures │ │ ├── container_diffuse.json │ │ ├── container_diffuse.png │ │ ├── container_specular.json │ │ └── container_specular.png ├── engine │ ├── bin │ │ ├── LICENSE.md │ │ ├── steam_api32.dll │ │ ├── steam_api32.so │ │ ├── steam_api64.dll │ │ ├── steam_api64.dylib │ │ └── steam_api64.so │ ├── fonts │ │ ├── console_en.json │ │ ├── console_jp.json │ │ ├── default_en.json │ │ ├── default_jp.json │ │ ├── dejavu_sans_mono │ │ │ ├── AUTHORS │ │ │ ├── DejaVuSansMono.ttf │ │ │ └── LICENSE │ │ ├── noto_sans_jp │ │ │ ├── NotoSansJP-Black.otf │ │ │ ├── NotoSansJP-Bold.otf │ │ │ ├── NotoSansJP-Light.otf │ │ │ ├── NotoSansJP-Medium.otf │ │ │ ├── NotoSansJP-Regular.otf │ │ │ ├── NotoSansJP-Thin.otf │ │ │ └── OFL.txt │ │ └── noto_sans_mono │ │ │ └── NotoSansMonoCJKjp-Regular.otf │ ├── i18n │ │ └── engine_en.json │ ├── materials │ │ ├── phong.json │ │ ├── skybox.json │ │ ├── splashscreen.json │ │ ├── unlit.json │ │ ├── unlitTextured.json │ │ └── window.json │ ├── meshes │ │ ├── missing.cmdl │ │ └── missing.json │ ├── platform │ │ └── windows │ │ │ ├── app.manifest │ │ │ ├── app.rc │ │ │ └── icon.ico │ ├── shaders │ │ ├── phonglit.fsh │ │ ├── phonglit.json │ │ ├── phonglit.vsh │ │ ├── skybox.fsh │ │ ├── skybox.json │ │ ├── skybox.vsh │ │ ├── ubo │ │ │ ├── lights.glsl │ │ │ └── pv.glsl │ │ ├── ui.fsh │ │ ├── ui.json │ │ ├── ui.vsh │ │ ├── uniform │ │ │ └── m.glsl │ │ ├── unlit.fsh │ │ ├── unlit.json │ │ ├── unlit.vsh │ │ ├── unlitTextured.fsh │ │ ├── unlitTextured.json │ │ ├── unlitTextured.vsh │ │ └── utility │ │ │ └── when.glsl │ ├── sounds │ │ └── missing.wav │ └── textures │ │ ├── black.json │ │ ├── black.png │ │ ├── missing.json │ │ ├── missing.png │ │ ├── missingSkybox.json │ │ └── ui │ │ ├── icon.json │ │ ├── icon.png │ │ ├── splashscreen.json │ │ └── splashscreen.png └── tests │ └── string_resource_test.txt ├── tests ├── TestHelpers.h ├── engine │ ├── config │ │ └── ConEntryTest.cpp │ ├── core │ │ └── CommandLine.cpp │ ├── math │ │ └── GraphTest.cpp │ ├── resource │ │ └── provider │ │ │ └── FilesystemResourceProviderTest.cpp │ ├── ui │ │ └── debug │ │ │ └── ConsolePanelTest.cpp │ └── utility │ │ ├── ConceptsTest.cpp │ │ ├── DependencyGraphTest.cpp │ │ ├── StringTest.cpp │ │ ├── TypeStringTest.cpp │ │ └── UUIDGeneratorTest.cpp └── tests.cmake └── tools ├── ToolHelpers.h ├── cmdltool ├── README.md ├── cmdltool.cmake └── cmdltool.cpp └── editor ├── editor.cmake ├── editor.cpp └── ui ├── CMakeLists.txt ├── ControlsPanel.cpp ├── ControlsPanel.h ├── EntitySelectPanel.cpp ├── EntitySelectPanel.h ├── InspectorPanel.cpp ├── InspectorPanel.h ├── ScriptEditorPanel.cpp └── ScriptEditorPanel.h /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | ko_fi: craftablescience 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.yml: -------------------------------------------------------------------------------- 1 | name: Bug Report 2 | description: Report a bug 3 | title: Bug Title Here 4 | labels: [bug] 5 | body: 6 | - type: textarea 7 | attributes: 8 | label: Describe the Bug 9 | description: A clear description of what the bug is. Feel free to add pictures or videos. 10 | placeholder: | 11 | When I do X then Y happens. 12 | validations: 13 | required: true 14 | - type: textarea 15 | attributes: 16 | label: To Reproduce 17 | description: Steps to reproduce the bug. 18 | placeholder: | 19 | 1. Launch ... 20 | 2. Open ... 21 | 3. Do ... 22 | 4. See error ... 23 | validations: 24 | required: true 25 | - type: input 26 | attributes: 27 | label: Operating System 28 | placeholder: Windows, Linux, etc. 29 | validations: 30 | required: true 31 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.yml: -------------------------------------------------------------------------------- 1 | name: Feature Request 2 | description: Request a feature 3 | title: Feature Title Here 4 | labels: [enhancement] 5 | body: 6 | - type: dropdown 7 | attributes: 8 | label: Component to Improve 9 | options: [Audio, Documentation, Render, "Core Engine", UI/UX, Other] 10 | validations: 11 | required: true 12 | - type: textarea 13 | attributes: 14 | label: Describe Your Suggestion 15 | description: Give a clear explanation of what you want to be added. Feel free to add pictures or video. 16 | placeholder: | 17 | Please don't give vague suggestions. 18 | How does it work? What is the expected outcome? 19 | validations: 20 | required: true 21 | -------------------------------------------------------------------------------- /.github/workflows/deploy_docs.yml: -------------------------------------------------------------------------------- 1 | name: Deploy Docs 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | jobs: 9 | deploy-docs: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: DenverCoder1/doxygen-github-pages-action@v1.2.0 13 | with: 14 | github_token: ${{ secrets.GITHUB_TOKEN }} 15 | branch: docs 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # IDE 2 | .idea/ 3 | .vs/ 4 | .vscode/ 5 | 6 | CMakeSettings.json 7 | 8 | # Build 9 | cmake-build-*/ 10 | build*/ 11 | out*/ 12 | 13 | .ccls-cache 14 | 15 | # Doxygen 16 | docs/html 17 | 18 | # macOS 19 | */.DS_Store 20 | .DS_Store 21 | 22 | # Generated 23 | !generated/*.in 24 | generated/ 25 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "engine/thirdparty/discord"] 2 | path = engine/thirdparty/discord 3 | url = https://github.com/craftablescience/discord-rpc-clean 4 | [submodule "engine/thirdparty/fmt"] 5 | path = engine/thirdparty/fmt 6 | url = https://github.com/fmtlib/fmt 7 | [submodule "engine/thirdparty/glm"] 8 | path = engine/thirdparty/glm 9 | url = https://github.com/g-truc/glm 10 | [submodule "engine/thirdparty/imgui"] 11 | path = engine/thirdparty/imgui 12 | url = https://github.com/ocornut/imgui 13 | [submodule "engine/thirdparty/json"] 14 | path = engine/thirdparty/json 15 | url = https://github.com/nlohmann/json 16 | [submodule "engine/thirdparty/libloader"] 17 | path = engine/thirdparty/libloader 18 | url = https://github.com/craftablescience/LibLoader 19 | [submodule "engine/thirdparty/stduuid"] 20 | path = engine/thirdparty/stduuid 21 | url = https://github.com/mariusbancila/stduuid 22 | [submodule "engine/thirdparty/imgui-filebrowser"] 23 | path = engine/thirdparty/imgui-filebrowser 24 | url = https://github.com/AirGuanZ/imgui-filebrowser 25 | [submodule "engine/thirdparty/sdl2"] 26 | path = engine/thirdparty/sdl2 27 | url = https://github.com/libsdl-org/SDL 28 | [submodule "engine/thirdparty/magic_enum"] 29 | path = engine/thirdparty/magic_enum 30 | url = https://github.com/Neargye/magic_enum 31 | [submodule "engine/thirdparty/entt"] 32 | path = engine/thirdparty/entt 33 | url = https://github.com/skypjack/entt 34 | [submodule "engine/thirdparty/soloud"] 35 | path = engine/thirdparty/soloud 36 | url = https://github.com/craftablescience/soloud 37 | [submodule "docs/layout/doxygen-awesome-css"] 38 | path = docs/layout/doxygen-awesome-css 39 | url = https://github.com/jothepro/doxygen-awesome-css 40 | [submodule "engine/thirdparty/imguizmo"] 41 | path = engine/thirdparty/imguizmo 42 | url = https://github.com/CedricGuillemet/ImGuizmo 43 | [submodule "engine/thirdparty/imgui-colortextedit"] 44 | path = engine/thirdparty/imgui-colortextedit 45 | url = https://github.com/BalazsJako/ImGuiColorTextEdit 46 | [submodule "engine/thirdparty/cereal"] 47 | path = engine/thirdparty/cereal 48 | url = https://github.com/craftablescience/cereal 49 | [submodule "engine/thirdparty/lua"] 50 | path = engine/thirdparty/lua 51 | url = https://github.com/craftablescience/lua 52 | [submodule "engine/thirdparty/sol2"] 53 | path = engine/thirdparty/sol2 54 | url = https://github.com/ThePhD/sol2 55 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Brendan Lewis 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /branding/README.md: -------------------------------------------------------------------------------- 1 | Logo font is `UD Digi Kyokasho NP-R` 2 | -------------------------------------------------------------------------------- /branding/doxygen/header_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/craftablescience/ChiraEngine/ebb306844057a85d37f56b09002f02a5c0d4d894/branding/doxygen/header_logo.png -------------------------------------------------------------------------------- /branding/github/readme_banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/craftablescience/ChiraEngine/ebb306844057a85d37f56b09002f02a5c0d4d894/branding/github/readme_banner.png -------------------------------------------------------------------------------- /branding/steam/avatars/spider.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/craftablescience/ChiraEngine/ebb306844057a85d37f56b09002f02a5c0d4d894/branding/steam/avatars/spider.png -------------------------------------------------------------------------------- /branding/steam/community/capsule.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/craftablescience/ChiraEngine/ebb306844057a85d37f56b09002f02a5c0d4d894/branding/steam/community/capsule.png -------------------------------------------------------------------------------- /branding/steam/community/community_group_header.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/craftablescience/ChiraEngine/ebb306844057a85d37f56b09002f02a5c0d4d894/branding/steam/community/community_group_header.png -------------------------------------------------------------------------------- /branding/steam/community/community_icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/craftablescience/ChiraEngine/ebb306844057a85d37f56b09002f02a5c0d4d894/branding/steam/community/community_icon.ico -------------------------------------------------------------------------------- /branding/steam/community/community_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/craftablescience/ChiraEngine/ebb306844057a85d37f56b09002f02a5c0d4d894/branding/steam/community/community_icon.png -------------------------------------------------------------------------------- /branding/steam/community/devhub_banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/craftablescience/ChiraEngine/ebb306844057a85d37f56b09002f02a5c0d4d894/branding/steam/community/devhub_banner.png -------------------------------------------------------------------------------- /branding/steam/community/workshop_banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/craftablescience/ChiraEngine/ebb306844057a85d37f56b09002f02a5c0d4d894/branding/steam/community/workshop_banner.png -------------------------------------------------------------------------------- /branding/steam/library/library_capsule.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/craftablescience/ChiraEngine/ebb306844057a85d37f56b09002f02a5c0d4d894/branding/steam/library/library_capsule.png -------------------------------------------------------------------------------- /branding/steam/library/library_hero.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/craftablescience/ChiraEngine/ebb306844057a85d37f56b09002f02a5c0d4d894/branding/steam/library/library_hero.png -------------------------------------------------------------------------------- /branding/steam/library/library_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/craftablescience/ChiraEngine/ebb306844057a85d37f56b09002f02a5c0d4d894/branding/steam/library/library_logo.png -------------------------------------------------------------------------------- /branding/steam/store/store_header_capsule.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/craftablescience/ChiraEngine/ebb306844057a85d37f56b09002f02a5c0d4d894/branding/steam/store/store_header_capsule.png -------------------------------------------------------------------------------- /branding/steam/store/store_main_capsule.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/craftablescience/ChiraEngine/ebb306844057a85d37f56b09002f02a5c0d4d894/branding/steam/store/store_main_capsule.png -------------------------------------------------------------------------------- /branding/steam/store/store_small_capsule.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/craftablescience/ChiraEngine/ebb306844057a85d37f56b09002f02a5c0d4d894/branding/steam/store/store_small_capsule.png -------------------------------------------------------------------------------- /branding/steam/store/store_vertical_capsule.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/craftablescience/ChiraEngine/ebb306844057a85d37f56b09002f02a5c0d4d894/branding/steam/store/store_vertical_capsule.png -------------------------------------------------------------------------------- /docs/layout/custom.css: -------------------------------------------------------------------------------- 1 | @media (prefers-color-scheme: dark) { 2 | html:not(.light-mode) { 3 | --primary-color : #AB54D1; 4 | --primary-dark-color : #AB54D1; 5 | --primary-light-color : #AB54D1; 6 | 7 | /* --code-background: #29175E; 8 | --fragment-background: #29175E; */ 9 | 10 | --code-background: #303033; 11 | --fragment-background: #303033; 12 | 13 | --page-background-color: #0F0F0F; 14 | --side-nav-background: #242424; 15 | --header-background: var(--side-nav-background); 16 | 17 | --searchbar-background-color: #29175E; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /docs/pages/filespec/filespec.md: -------------------------------------------------------------------------------- 1 | # Chira Engine File Formats 2 | Unsurprisingly, Chira Engine does have it's fair share of unique file formats. As such we have dedicated a section of this documentation purely to detailing what these files are and how they are setup alonside any tools you may use to create or modify them. 3 | 4 | [TOC] 5 | 6 | ## Common info 7 | Most of the file formats used by Chira are written in some form of JSON. So they're relatively easy to parse. That being said, there **are** some exceptions to this and any formats that aren't JSON will have this information clearly mentioned. 8 | 9 | The pages themselves are formatted in the following structure (headers disabled for better reading experience) 10 | 11 | \#\# Example Section 12 | info on section 13 | 14 | \#\#\# Section property
15 | `Default Value: ` 16 | 17 | Specifications: 18 | 19 | | Spec | Value | 20 | |----------|-----------------| 21 | | Type | Example | 22 | 23 | ## Formats 24 | > NOTE: The following list is based on a currently private branch dedicated to reworking file extensions separate from `editor-extended` 25 | 26 | Here is a complete (as of writing) list of ChiraEngine unique formats. Any formats that have pages will have them linked here. 27 | - @subpage cscnspec 28 | - @subpage cmdlspec 29 | - @subpage cmshspec 30 | - CTEX 31 | - CMAT 32 | - CSH 33 | 34 | ## Tools 35 | Currently there are no external parsers, generators, or editors for any of the formats. -------------------------------------------------------------------------------- /docs/pages/filespec/material-spec.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/craftablescience/ChiraEngine/ebb306844057a85d37f56b09002f02a5c0d4d894/docs/pages/filespec/material-spec.md -------------------------------------------------------------------------------- /docs/pages/filespec/model-spec.md: -------------------------------------------------------------------------------- 1 | # CMDL Files {#cmdlspec} 2 | `.cmdl` is the file extension of the Chira Model file. The following info is contained within these files: 3 | - Mesh info 4 | - Material info 5 | - Mesh Loader 6 | 7 | No mesh, material, or texture data is present within CMDL files. only the info on what file should be used to get that info. 8 | 9 | > WARNING: This file format has not been fully developed and is still being added onto. Features may be added and removed as time goes on. 10 | 11 | [TOC] 12 | 13 | ## Format 14 | Just like most other Chira Engine specific resource info, CMDL files use a JSON format to store their data. Right now they only contain some basic information but the format is currently being expanded to provide more info such as 15 | - Animations 16 | - Actions 17 | - Multiple Textures 18 | - Multiple Meshes 19 | 20 | ## Properties 21 | The following properties are currently implemented into the CMDL format 22 | 23 | ### Material Type 24 | `Default Value: None` 25 | 26 | This property determines what material type Chira will use when rendering the material defined in the [material](### Material) property. 27 | 28 | Specifications: 29 | 30 | | Spec | Value | 31 | |----------|------------| 32 | | Value Type | Material Type (String) | 33 | | Optional | False | 34 | 35 | ### Material 36 | `Default Value: None` 37 | 38 | This property determines what material Chira will use when rendering the mesh defined in the [model](### Model) property. 39 | 40 | Specifications: 41 | 42 | | Spec | Value | 43 | |----------|------------| 44 | | Value Type | Resource Path (String) | 45 | | Optional | False | 46 | 47 | ### Model 48 | `Default Value: None` 49 | 50 | This property determines what mesh Chira will load for this specific model 51 | 52 | > **NOTE: Make sure the value you set in the [loader](### Loader) property matches the fomat of this mesh!** 53 | 54 | Specifications: 55 | 56 | | Spec | Value | 57 | |----------|------------| 58 | | Value Type | Resource Path (String) | 59 | | Optional | False | 60 | 61 | ### Loader 62 | `Default Value: None` 63 | 64 | This property determines what type of mesh Chira will attempt to load the mesh defined in [model](### Model) as. 65 | 66 | Specifications: 67 | 68 | | Spec | Value | 69 | |----------|------------| 70 | | Value Type | Model Type Extension (String) | 71 | | Supported Values| obj
cmsh | 72 | | Optional | False | 73 | -------------------------------------------------------------------------------- /docs/pages/filespec/spec-mesh.md: -------------------------------------------------------------------------------- 1 | # CMSH Files {#cmshspec} 2 | `.cmsh` files are Chira Engine Mesh files. No concrete info can be given as to how they're laid out nor are they as easy to parse as other formats. They can be created from an OBJ file using [ChiraEditor]() 3 | 4 | [TOC] 5 | 6 | ## Format 7 | CMSH files are a modified^*[citation needed]*^ OBJ format. Due to this modification they require their own loader to be loaded in. -------------------------------------------------------------------------------- /docs/pages/filespec/spec-scene.md: -------------------------------------------------------------------------------- 1 | # CSCN Files {#cscnspec} 2 | This file explains in detail exactly how the ChiraEngine Scene files (`.cscn`) work and what most if not all fields do and what their possible values (if applicable) are. 3 | 4 | [TOC] 5 | 6 | ## Format 7 | The Scene file itself is written in JSON meaning it's quite easy to parse. Allowing the creation of external editors for game specific tools (EX. No Return's Bismuth Editor) to be easier than most. only needing a JSON parser to actually read data out of the file. 8 | 9 | How this data is used is left entirely up to the creator of the tool or game as most values are stored in the most basic manner possible to allow for maximum amount of ease in creating other tools. 10 | 11 | ## Example scene file 12 | Here is an example of a scene file that contains a simple blue sky environment and a single cube object on a static plane.
13 | Due to the simplicity of this example this doesn't show off a good chunk of the values that exist. This is only to be used as a basic example to visually see how these files are structured. 14 | 15 | > NOTE: Actual `.cscn` files cannot host comments. They only exist here to provide pointers as to what is what at a glace. 16 | 17 | ```JSON 18 | { 19 | "Entities": [ 20 | { 21 | "id": "Example Entity", 22 | "type": "MeshEntity", 23 | "trsnf": { 24 | "pos": [0,0,0], 25 | "scale": [0,0,0], 26 | "rotate": [0,0,0], 27 | }, 28 | }, 29 | //... 30 | ], 31 | "LevelData": [ 32 | { 33 | // TODO: Create a system for level data (Most likely something like the source 2 mesh system?) 34 | }, 35 | ] 36 | } 37 | ``` 38 | 39 | # SceneInfo 40 | `TODO: Implement these values as support is added` 41 | 42 | # Entities 43 | The Entities property is used to store a hierarchical, order respecting list of entities inside of a scene. Each entity is placed into the list at the exact position that it's placed inside of the Editor's visual entities dock. 44 | 45 | The list below details the structure that makes up a given entity. 46 | 47 | | -------------------------------------------------------------------------------- /docs/pages/filespec/texture-spec.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/craftablescience/ChiraEngine/ebb306844057a85d37f56b09002f02a5c0d4d894/docs/pages/filespec/texture-spec.md -------------------------------------------------------------------------------- /docs/pages/reference/pluginapi.md: -------------------------------------------------------------------------------- 1 | # Editor Plugin API {#editpluginapi} 2 | This page contains a complete list of all methods, properties, etc. that are available to AngelScript for EditorPlugins. 3 | ## List of Methods 4 | | Method | Parameters | Description | 5 | |--------|------------|-------------| -------------------------------------------------------------------------------- /docs/pages/reference/reference.md: -------------------------------------------------------------------------------- 1 | # Reference 2 | All documentation related to APIs for scripting and C++ Classes 3 | 4 | ------------------------ 5 | 6 | - @subpage editpluginapi -------------------------------------------------------------------------------- /docs/pages/tutorial/tutorial.md: -------------------------------------------------------------------------------- 1 | # Tutorials 2 | A complete list of all tutorials related to Chira Engine development. 3 | 4 | ------------------ 5 | - @subpage createchiraengproj -------------------------------------------------------------------------------- /engine/config/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | configure_file(${CMAKE_CURRENT_LIST_DIR}/generated/Config.h.in ${CMAKE_CURRENT_LIST_DIR}/generated/Config.h) 2 | 3 | list(APPEND CHIRA_ENGINE_HEADERS 4 | ${CMAKE_CURRENT_LIST_DIR}/ConEntry.h 5 | ${CMAKE_CURRENT_LIST_DIR}/Config.h) 6 | 7 | list(APPEND CHIRA_ENGINE_SOURCES 8 | ${CMAKE_CURRENT_LIST_DIR}/ConEntry.cpp 9 | ${CMAKE_CURRENT_LIST_DIR}/Config.cpp) 10 | -------------------------------------------------------------------------------- /engine/config/Config.cpp: -------------------------------------------------------------------------------- 1 | #include "Config.h" 2 | 3 | #if defined(CHIRA_PLATFORM_APPLE) || defined(CHIRA_PLATFORM_LINUX) 4 | // Using std::ignore to absorb system()'s return value 5 | #include 6 | #endif 7 | 8 | #include 9 | #ifdef CHIRA_PLATFORM_WINDOWS 10 | #define WIN32_LEAN_AND_MEAN 11 | #include 12 | #include 13 | #else // Should work on any other platform besides Windows? macOS and Linux work at least 14 | #include 15 | #include 16 | #endif 17 | #include 18 | 19 | #include "ConEntry.h" 20 | 21 | using namespace chira; 22 | 23 | [[maybe_unused]] 24 | ConCommand open_config_dir{"open_config_dir", "Opens the config directory in the OS's graphical file browser.", [] { 25 | std::string dir = Config::getConfigDirectory().data(); 26 | #if defined(CHIRA_PLATFORM_WINDOWS) 27 | ShellExecute(nullptr, "open", dir.c_str(), nullptr, nullptr, SW_SHOWNORMAL); 28 | #elif defined(CHIRA_PLATFORM_APPLE) 29 | dir = "open " + dir; 30 | std::ignore = system(dir.c_str()); 31 | #elif defined(CHIRA_PLATFORM_LINUX) 32 | dir = "xdg-open " + dir; 33 | std::ignore = system(dir.c_str()); 34 | #else 35 | #error "fixme: need code for specific platform!" 36 | #endif 37 | }}; 38 | 39 | std::string_view Config::getConfigDirectory() { 40 | // e.g. "C:\Users\\AppData\Local\ChiraEngine\" 41 | // this will not change while the program is running (or ever for that matter) 42 | static std::string pathString; 43 | if (!pathString.empty()) 44 | return pathString; 45 | 46 | #ifndef CHIRA_PLATFORM_WINDOWS 47 | const char* homePath = getenv("HOME"); 48 | if (!homePath) { 49 | if (passwd* pwd = getpwuid(getuid())) { 50 | homePath = pwd->pw_dir; 51 | } 52 | } 53 | pathString.append(homePath); 54 | #if defined(CHIRA_PLATFORM_APPLE) 55 | pathString.append("/Library/Application Support/ChiraEngine/"); 56 | #elif defined(CHIRA_PLATFORM_LINUX) 57 | pathString.append("/.local/ChiraEngine/"); 58 | #else 59 | #error "fixme: need code for specific platform!" 60 | #endif 61 | #else // We are on Windows 62 | // Get the environment variable for the user on Windows 63 | pathString = getenv("USERPROFILE"); 64 | pathString.append(R"(\AppData\Local\ChiraEngine\)"); 65 | #endif 66 | return pathString; 67 | } 68 | 69 | std::string Config::getConfigFile(std::string_view file) { 70 | return std::string{Config::getConfigDirectory()} + file.data(); 71 | } 72 | -------------------------------------------------------------------------------- /engine/config/Config.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "generated/Config.h" 4 | -------------------------------------------------------------------------------- /engine/config/generated/Config.h.in: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #define CHIRA_PROJECT_NAME "${PROJECT_NAME}" 7 | 8 | namespace chira::Config { 9 | 10 | [[nodiscard]] std::string_view getConfigDirectory(); 11 | [[nodiscard]] std::string getConfigFile(std::string_view file); 12 | 13 | } // namespace chira::Config 14 | -------------------------------------------------------------------------------- /engine/core/Assertions.cpp: -------------------------------------------------------------------------------- 1 | #include "Assertions.h" 2 | 3 | #include 4 | #include "Logger.h" 5 | 6 | #ifdef DEBUG 7 | #include 8 | #endif 9 | 10 | using namespace chira; 11 | 12 | CHIRA_CREATE_LOG(ASSERT); 13 | 14 | #ifdef CHIRA_USE_SOURCE_LOCATION 15 | void runtime_assert(bool shouldAssert, std::string_view message, const std::source_location& location) { 16 | runtime_assert_internal(shouldAssert, message, location.file_name(), location.line(), location.function_name()); 17 | } 18 | #endif 19 | 20 | void runtime_assert_internal(bool shouldAssert, std::string_view message, const char* file, unsigned int line, const char* function) { 21 | // Assertions fail when false 22 | if (shouldAssert) 23 | return; 24 | 25 | auto assertMsg = std::string{"Assertion failed at "} + file + "::" + function + "::L" + std::to_string(line) + ":\n" + message.data(); 26 | LOG_ASSERT.error(assertMsg); 27 | 28 | #ifdef DEBUG 29 | if (!chira::Device::popupChoice(assertMsg + "\n\nPress Break to break in debugger, Continue to continue.", "Assertion Failed", chira::Device::POPUP_ERROR, "Continue", "Break")) { 30 | chira::breakInDebugger(); 31 | } 32 | #endif 33 | } 34 | -------------------------------------------------------------------------------- /engine/core/Assertions.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include "Platform.h" 7 | 8 | #ifndef CHIRA_COMPILER_MSVC 9 | #include 10 | #endif 11 | 12 | // Have to do this crap pile because std::source_location can be unimplemented even if the header exists 13 | #if __has_include() 14 | #include 15 | // This macro is defined in if its implemented 16 | #ifdef __cpp_lib_source_location 17 | #define CHIRA_USE_SOURCE_LOCATION 18 | #endif 19 | #endif 20 | 21 | // Leave outside the Chira namespace so it can be conditionally replaced with a macro 22 | #ifdef CHIRA_BUILD_WITH_ASSERTS 23 | // (why did modern compilers not implement this??) 24 | #ifdef CHIRA_USE_SOURCE_LOCATION 25 | void runtime_assert(bool shouldAssert, std::string_view message, const std::source_location& location = std::source_location::current()); 26 | #else 27 | #define runtime_assert(shouldAssert, message) runtime_assert_internal(shouldAssert, message, __FILE__, __LINE__, __FUNCTION__) 28 | #endif 29 | void runtime_assert_internal(bool shouldAssert, std::string_view message, const char* file, unsigned int line, const char* function); 30 | #else 31 | #define runtime_assert(shouldAssert, message) 32 | #endif 33 | 34 | namespace chira { 35 | 36 | template 37 | inline T assert_cast(auto obj) { 38 | #ifdef DEBUG 39 | if (!obj) 40 | return nullptr; 41 | auto cast = dynamic_cast(obj); 42 | runtime_assert(cast, "Object could not be cast"); 43 | return cast; 44 | #else 45 | return static_cast(obj); 46 | #endif 47 | } 48 | 49 | inline void breakInDebugger() { 50 | #ifdef CHIRA_COMPILER_MSVC 51 | __debugbreak(); 52 | #else 53 | std::raise(SIGINT); 54 | #endif 55 | } 56 | 57 | /// Thank you cppreference.com! 58 | /// This is a C++23 thing, std::unreachable, creates undefined behaviour 59 | [[noreturn]] inline void unreachable(std::string_view rationale = "Unreachable code reached!") { 60 | runtime_assert(false, rationale); 61 | #if defined(__cpp_lib_unreachable) 62 | std::unreachable(); 63 | #elif defined(CHIRA_COMPILER_GNU) || defined(CHIRA_COMPILER_CLANG) 64 | __builtin_unreachable(); 65 | #elif defined(CHIRA_COMPILER_MSVC) || defined(CHIRA_COMPILER_INTEL) 66 | __assume(false); 67 | #endif 68 | } 69 | #define CHIRA_NO_DEFAULT default: chira::unreachable("Hit the default case in a NO_DEFAULT switch!"); break 70 | 71 | } // namespace chira 72 | -------------------------------------------------------------------------------- /engine/core/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | list(APPEND CHIRA_ENGINE_HEADERS 2 | ${CMAKE_CURRENT_LIST_DIR}/Assertions.h 3 | ${CMAKE_CURRENT_LIST_DIR}/CommandLine.h 4 | ${CMAKE_CURRENT_LIST_DIR}/Engine.h 5 | ${CMAKE_CURRENT_LIST_DIR}/Logger.h 6 | ${CMAKE_CURRENT_LIST_DIR}/Platform.h) 7 | 8 | list(APPEND CHIRA_ENGINE_SOURCES 9 | ${CMAKE_CURRENT_LIST_DIR}/CommandLine.cpp 10 | ${CMAKE_CURRENT_LIST_DIR}/Engine.cpp 11 | ${CMAKE_CURRENT_LIST_DIR}/Logger.cpp) 12 | 13 | if(CHIRA_BUILD_WITH_ASSERTS) 14 | list(APPEND CHIRA_ENGINE_SOURCES 15 | ${CMAKE_CURRENT_LIST_DIR}/Assertions.cpp) 16 | endif() 17 | -------------------------------------------------------------------------------- /engine/core/CommandLine.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace chira::CommandLine { 6 | 7 | /// Initialization is only meant to happen once per program instantiation. 8 | void init(int argc, const char* argv[]); 9 | 10 | [[nodiscard]] bool has(std::string_view argument); 11 | 12 | [[nodiscard]] std::string_view get(std::string_view argument); 13 | 14 | [[nodiscard]] std::string_view getOr(std::string_view argument, std::string_view default_); 15 | 16 | [[nodiscard]] bool hasDefaultArgument(); 17 | 18 | [[nodiscard]] std::string_view getDefaultArgument(); 19 | 20 | [[nodiscard]] std::string_view getDefaultArgumentOr(std::string_view default_); 21 | 22 | [[nodiscard]] std::string_view getProgramName(); 23 | 24 | } // namespace chira::CommandLine 25 | -------------------------------------------------------------------------------- /engine/core/Engine.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | namespace chira { 12 | 13 | const std::string ENGINE_FILESYSTEM_PATH = "engine"; 14 | 15 | class Engine { 16 | public: 17 | Engine() = delete; 18 | 19 | /// Ran at the very start of your program. Readies the engine for you to add features before init(). 20 | static void preinit(int argc, const char* argv[]); 21 | static void init(bool visibleSplashScreen = true); 22 | static void run(); 23 | 24 | /// Returns a pointer to the main window of the application. 25 | [[nodiscard]] static Device::WindowHandle* getMainWindow() { return Engine::mainWindow; } 26 | [[nodiscard]] static bool isStarted(); 27 | /// Only guaranteed to work after run() in a render method 28 | [[nodiscard]] static uint64_t getDeltaTicks(); 29 | private: 30 | static inline Device::WindowHandle* mainWindow = nullptr; 31 | static inline bool started = false; 32 | static inline uint64_t lastTime = 0, currentTime = 0; 33 | }; 34 | 35 | } // namespace chira 36 | -------------------------------------------------------------------------------- /engine/core/Platform.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | // 64-bit or 32-bit? 8 | #if INTPTR_MAX == INT32_MAX 9 | #define CHIRA_32BIT 10 | #elif INTPTR_MAX == INT64_MAX 11 | #define CHIRA_64BIT 12 | #else 13 | #error "Environment is not 32-bit or 64-bit! What kind of machine are you even using?" 14 | #endif 15 | 16 | #if defined(_MSC_VER) && !defined(__INTEL_COMPILER) 17 | #define CHIRA_COMPILER_MSVC 18 | #else 19 | #define CHIRA_COMPILER_INTEL 20 | #endif 21 | #if defined(__GNUC__) && !defined(__clang__) 22 | #define CHIRA_COMPILER_GNU 23 | #endif 24 | #if defined(__clang__) 25 | #define CHIRA_COMPILER_CLANG 26 | #endif 27 | 28 | #if defined(_WIN32) 29 | #define CHIRA_PLATFORM_WINDOWS 30 | #elif defined(__APPLE__) && defined(__MACH__) 31 | #define CHIRA_PLATFORM_APPLE 32 | #elif defined(__linux__) 33 | #define CHIRA_PLATFORM_LINUX 34 | #elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) 35 | #define CHIRA_PLATFORM_BSD 36 | #elif defined(__sun) 37 | #define CHIRA_PLATFORM_SOLARIS 38 | #else 39 | #error "Unknown platform! Please make a bug report on our GitHub" 40 | #endif 41 | 42 | namespace chira { 43 | 44 | // This makes it a bit easier to use in strings and such 45 | #if defined(CHIRA_32BIT) 46 | constexpr int ENVIRONMENT_TYPE = 32; 47 | #elif defined(CHIRA_64BIT) 48 | constexpr int ENVIRONMENT_TYPE = 64; 49 | #else 50 | #error "A CHIRA_XXBIT macro must be set!" 51 | #endif 52 | 53 | } // namespace chira 54 | -------------------------------------------------------------------------------- /engine/entity/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | include(${CMAKE_CURRENT_LIST_DIR}/component/CMakeLists.txt) 2 | 3 | list(APPEND CHIRA_ENGINE_HEADERS 4 | ${CMAKE_CURRENT_LIST_DIR}/Entity.h 5 | ${CMAKE_CURRENT_LIST_DIR}/Viewport.h 6 | ${CMAKE_CURRENT_LIST_DIR}/Scene.h) 7 | 8 | list(APPEND CHIRA_ENGINE_SOURCES 9 | ${CMAKE_CURRENT_LIST_DIR}/Viewport.cpp 10 | ${CMAKE_CURRENT_LIST_DIR}/Scene.cpp) 11 | -------------------------------------------------------------------------------- /engine/entity/Viewport.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "Scene.h" 5 | 6 | namespace chira { 7 | 8 | class Viewport { 9 | public: 10 | explicit Viewport(glm::vec2i size_, ColorRGB backgroundColor_ = {}, bool linearFiltering_ = true); 11 | 12 | Scene* addScene(); 13 | 14 | Scene* addScene(const std::string& name); 15 | 16 | Scene* addScene(uuids::uuid uuid); 17 | 18 | Scene* addScene(uuids::uuid uuid, const std::string& name); 19 | 20 | [[nodiscard]] Scene* getScene(uuids::uuid sceneID); 21 | 22 | [[nodiscard]] const auto& getScenes() const { 23 | return this->scenes; 24 | } 25 | 26 | [[nodiscard]] bool hasScene(uuids::uuid sceneID); 27 | 28 | void removeScene(uuids::uuid sceneID); 29 | 30 | void removeAllScenes(); 31 | 32 | void update(); 33 | 34 | void render(); 35 | 36 | [[nodiscard]] CameraComponent* getCamera() const { 37 | for (const auto& [uuid, scene] : this->scenes) { 38 | if (auto* camera = scene->getCamera()) { 39 | return camera; 40 | } 41 | } 42 | return nullptr; 43 | } 44 | 45 | [[nodiscard]] ColorRGB getBackgroundColor() const { 46 | return this->backgroundColor; 47 | } 48 | 49 | void setBackgroundColor(ColorRGB color) { 50 | this->backgroundColor = color; 51 | } 52 | 53 | [[nodiscard]] glm::vec2i getSize() const { 54 | return this->size; 55 | } 56 | 57 | void setSize(glm::vec2i size_) { 58 | this->size = size_; 59 | this->recreateFrameBuffer(); 60 | } 61 | 62 | [[nodiscard]] bool isLinearFiltered() const { 63 | return this->linearFiltering; 64 | } 65 | 66 | void setLinearFiltering(bool enable) { 67 | this->linearFiltering = enable; 68 | this->recreateFrameBuffer(); 69 | } 70 | 71 | [[nodiscard]] Renderer::FrameBufferHandle* getRawHandle() { 72 | return &this->frameBufferHandle; 73 | } 74 | 75 | private: 76 | void recreateFrameBuffer(); 77 | 78 | private: 79 | std::unordered_map> scenes; 80 | Renderer::FrameBufferHandle frameBufferHandle; 81 | glm::vec2i size; 82 | ColorRGB backgroundColor; 83 | bool linearFiltering; 84 | }; 85 | 86 | } // namespace chira 87 | -------------------------------------------------------------------------------- /engine/entity/component/AudioNoiseComponent.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "TransformComponent.h" 8 | 9 | namespace chira { 10 | 11 | struct AudioNoiseComponent { 12 | static constexpr auto in_place_delete = true; 13 | 14 | explicit AudioNoiseComponent(SoLoud::Noise::NOISETYPES noise = SoLoud::Noise::NOISETYPES::WHITE) 15 | : noiseType(noise) { 16 | this->noise.setType(noise); 17 | } 18 | 19 | AudioNoiseComponent(float o0, float o1, float o2, float o3, float o4, float o5, float o6, float o7, float o8, float o9) 20 | : noiseType(static_cast(-1)) { 21 | this->noise.setOctaveScale(o0, o1, o2, o3, o4, o5, o6, o7, o8, o9); 22 | } 23 | 24 | [[nodiscard]] SoLoud::Noise::NOISETYPES getNoiseType() const { 25 | return this->noiseType; 26 | } 27 | 28 | void setNoiseType(SoLoud::Noise::NOISETYPES noiseType_) { 29 | if (noiseType_ >= 0) { 30 | this->noise.setType(noiseType_); 31 | } 32 | this->noiseType = noiseType_; 33 | } 34 | 35 | public: 36 | TransformComponent* transform = nullptr; 37 | SoLoud::Noise noise; 38 | 39 | protected: 40 | /// Can be -1 to indicate a custom noise setup 41 | SoLoud::Noise::NOISETYPES noiseType; 42 | }; 43 | 44 | } // namespace chira 45 | -------------------------------------------------------------------------------- /engine/entity/component/AudioSfxrComponent.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "TransformComponent.h" 9 | 10 | namespace chira { 11 | 12 | struct AudioSfxrComponent { 13 | static constexpr auto in_place_delete = true; 14 | 15 | explicit AudioSfxrComponent(SoLoud::Sfxr::SFXR_PRESETS preset = SoLoud::Sfxr::SFXR_PRESETS::COIN, int seed_ = 0) 16 | : sfxrPreset(preset) 17 | , seed(seed_) { 18 | this->setSfxrFromPreset(this->sfxrPreset, this->seed); 19 | } 20 | 21 | explicit AudioSfxrComponent(std::string cfgId) 22 | : sfxrPreset(static_cast(-1)) 23 | , seed(0) 24 | , cfgFile(std::move(cfgId)) { 25 | this->setSfxrFromConfig(this->cfgFile); 26 | } 27 | 28 | [[nodiscard]] SoLoud::Sfxr::SFXR_PRESETS getSfxrPreset() const { 29 | return this->sfxrPreset; 30 | } 31 | 32 | [[nodiscard]] int getSfxrSeed() const { 33 | return this->seed; 34 | } 35 | 36 | [[nodiscard]] std::string_view getSfxrConfigID() const { 37 | return this->cfgFile; 38 | } 39 | 40 | void setSfxrFromPreset(SoLoud::Sfxr::SFXR_PRESETS sfxrPreset_, int seed_ = 0) { 41 | if (sfxrPreset_ >= 0) { 42 | this->sfxr.resetParams(); 43 | this->sfxr.loadPreset(sfxrPreset_, seed_); 44 | } 45 | this->sfxrPreset = sfxrPreset_; 46 | this->seed = seed_; 47 | } 48 | 49 | void setSfxrFromConfig(std::string cfgId) { 50 | this->cfgFile = std::move(cfgId); 51 | auto config = Resource::getUniqueUncachedResource(this->cfgFile); 52 | this->sfxr.resetParams(); 53 | this->sfxr.loadParamsMem(const_cast(config->getBuffer()), static_cast(config->getBufferLength()), true, true); 54 | } 55 | 56 | public: 57 | TransformComponent* transform = nullptr; 58 | SoLoud::Sfxr sfxr; 59 | 60 | protected: 61 | /// Can be -1 to indicate it's loaded from a config file 62 | SoLoud::Sfxr::SFXR_PRESETS sfxrPreset; 63 | int seed = 0; 64 | std::string cfgFile; 65 | }; 66 | 67 | } // namespace chira 68 | -------------------------------------------------------------------------------- /engine/entity/component/AudioSpeechComponent.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "TransformComponent.h" 8 | 9 | namespace chira { 10 | 11 | struct AudioSpeechComponent { 12 | static constexpr auto in_place_delete = true; 13 | 14 | explicit AudioSpeechComponent(std::string_view speechText_ = "") 15 | : speechText(speechText_.data()) { 16 | this->speech.setText(this->speechText.c_str()); 17 | } 18 | 19 | [[nodiscard]] std::string_view getSpeechText() const { 20 | return this->speechText; 21 | } 22 | 23 | void setSpeechText(std::string_view speechText_) { 24 | this->speechText = speechText_.data(); 25 | this->speech.setText(this->speechText.c_str()); 26 | } 27 | 28 | public: 29 | TransformComponent* transform = nullptr; 30 | SoLoud::Speech speech; 31 | 32 | protected: 33 | std::string speechText; 34 | }; 35 | 36 | } // namespace chira 37 | -------------------------------------------------------------------------------- /engine/entity/component/AudioWavComponent.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "TransformComponent.h" 8 | 9 | namespace chira { 10 | 11 | struct AudioWavComponent { 12 | static constexpr auto in_place_delete = true; 13 | 14 | explicit AudioWavComponent(const std::string& wavId = "file://sounds/missing.wav") { 15 | this->wavFile = Resource::getResource(wavId); 16 | this->wav.loadMem(const_cast(this->wavFile->getBuffer()), static_cast(this->wavFile->getBufferLength()), false, false); 17 | } 18 | 19 | public: 20 | TransformComponent* transform = nullptr; 21 | SharedPointer wavFile; 22 | SoLoud::Wav wav; 23 | }; 24 | 25 | } // namespace chira 26 | -------------------------------------------------------------------------------- /engine/entity/component/AudioWavStreamComponent.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "TransformComponent.h" 8 | 9 | namespace chira { 10 | 11 | struct AudioWavStreamComponent { 12 | static constexpr auto in_place_delete = true; 13 | 14 | explicit AudioWavStreamComponent(const std::string& wavStreamId = "file://sounds/missing.wav") { 15 | this->wavFile = Resource::getResource(wavStreamId); 16 | this->wavStream.loadMem(const_cast(this->wavFile->getBuffer()), static_cast(this->wavFile->getBufferLength()), false, false); 17 | } 18 | 19 | public: 20 | TransformComponent* transform = nullptr; 21 | SharedPointer wavFile; 22 | SoLoud::WavStream wavStream; 23 | }; 24 | 25 | } // namespace chira 26 | -------------------------------------------------------------------------------- /engine/entity/component/BillboardComponent.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "TransformComponent.h" 4 | 5 | namespace chira { 6 | 7 | struct BillboardComponent { 8 | explicit BillboardComponent(bool xAxis = true, bool yAxis = true, bool zAxis = true) 9 | : x(xAxis) 10 | , y(yAxis) 11 | , z(zAxis) {} 12 | 13 | public: 14 | TransformComponent* transform; 15 | bool x; 16 | bool y; 17 | bool z; 18 | }; 19 | 20 | } // namespace chira 21 | -------------------------------------------------------------------------------- /engine/entity/component/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | list(APPEND CHIRA_ENGINE_HEADERS 2 | ${CMAKE_CURRENT_LIST_DIR}/AudioNoiseComponent.h 3 | ${CMAKE_CURRENT_LIST_DIR}/AudioSfxrComponent.h 4 | ${CMAKE_CURRENT_LIST_DIR}/AudioSpeechComponent.h 5 | ${CMAKE_CURRENT_LIST_DIR}/AudioWavComponent.h 6 | ${CMAKE_CURRENT_LIST_DIR}/AudioWavStreamComponent.h 7 | ${CMAKE_CURRENT_LIST_DIR}/CameraComponent.h 8 | ${CMAKE_CURRENT_LIST_DIR}/NameComponent.h 9 | ${CMAKE_CURRENT_LIST_DIR}/LightComponents.h 10 | ${CMAKE_CURRENT_LIST_DIR}/MeshComponent.h 11 | ${CMAKE_CURRENT_LIST_DIR}/MeshDynamicComponent.h 12 | ${CMAKE_CURRENT_LIST_DIR}/SkyboxComponent.h 13 | ${CMAKE_CURRENT_LIST_DIR}/TagComponents.h 14 | ${CMAKE_CURRENT_LIST_DIR}/TransformComponent.h 15 | ${CMAKE_CURRENT_LIST_DIR}/UUIDComponent.h 16 | ${CMAKE_CURRENT_LIST_DIR}/MeshSpriteComponent.h 17 | ${CMAKE_CURRENT_LIST_DIR}/LayerComponents.h) 18 | -------------------------------------------------------------------------------- /engine/entity/component/LayerComponents.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace chira { 6 | 7 | // The maximum amount of layers 8 | constexpr int MAX_LAYER_COMPONENTS = 16; 9 | 10 | template 11 | struct LayerComponent { 12 | static constexpr std::size_t index = 1 << LayerIndex; 13 | }; 14 | 15 | template 16 | consteval auto createLayerComponentsTuple(std::integer_sequence) { 17 | static_assert(MAX_LAYER_COMPONENTS > 0, "There must be at least one layer component!"); 18 | return std::make_tuple(LayerComponent()...); 19 | } 20 | 21 | constexpr auto LAYER_COMPONENTS = createLayerComponentsTuple(std::make_integer_sequence{}); 22 | 23 | } // namespace chira 24 | -------------------------------------------------------------------------------- /engine/entity/component/LightComponents.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "TransformComponent.h" 4 | 5 | namespace chira { 6 | 7 | // These are arbitrary amounts, be careful not to increase by too much or the GPU will hate you 8 | constexpr int DIRECTIONAL_LIGHT_MAX = 4; 9 | constexpr int POINT_LIGHT_MAX = 32; 10 | constexpr int SPOT_LIGHT_MAX = 16; 11 | 12 | struct DirectionalLightComponent { 13 | TransformComponent* transform; 14 | glm::vec3 ambient{0.1f}; 15 | glm::vec3 diffuse{0.8f}; 16 | glm::vec3 specular{0.1f}; 17 | }; 18 | 19 | struct PointLightComponent { 20 | TransformComponent* transform; 21 | glm::vec3 ambient{0.1f}; 22 | glm::vec3 diffuse{0.8f}; 23 | glm::vec3 specular{0.1f}; 24 | // x: constant, y: linear, z: quadratic 25 | // default is 100 units 26 | glm::vec3 falloff{1.f, 0.045f, 0.0075f}; 27 | }; 28 | 29 | struct SpotLightComponent { 30 | TransformComponent* transform; 31 | glm::vec3 diffuse{0.8f}; 32 | glm::vec3 specular{0.1f}; 33 | // x: constant, y: linear, z: quadratic 34 | // default is 100 units 35 | glm::vec3 falloff{1.f, 0.045f, 0.0075f}; 36 | // x: inner cutoff angle, y: outer cutoff angle 37 | glm::vec2 cutoff{glm::radians(45.f), glm::radians(60.f)}; 38 | }; 39 | 40 | } // namespace chira 41 | -------------------------------------------------------------------------------- /engine/entity/component/MeshComponent.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "TransformComponent.h" 5 | 6 | namespace chira { 7 | 8 | struct MeshComponent { 9 | explicit MeshComponent(const std::string& meshId = "file://meshes/missing.json") 10 | : transform(nullptr) 11 | , mesh(Resource::getResource(meshId)) {} 12 | 13 | public: 14 | TransformComponent* transform; 15 | SharedPointer mesh; 16 | }; 17 | 18 | } // namespace chira 19 | -------------------------------------------------------------------------------- /engine/entity/component/MeshDynamicComponent.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "TransformComponent.h" 5 | 6 | namespace chira { 7 | 8 | struct MeshDynamicComponent { 9 | public: 10 | TransformComponent* transform = nullptr; 11 | MeshDataBuilder meshBuilder{}; 12 | }; 13 | 14 | } // namespace chira 15 | -------------------------------------------------------------------------------- /engine/entity/component/MeshSpriteComponent.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | namespace chira { 7 | 8 | struct MeshSpriteComponent { 9 | explicit MeshSpriteComponent(glm::vec2 size_ = {1.f, 1.f}, const std::string& materialID = "file://materials/unlitTextured.json", const std::string& materialType = "MaterialTextured") 10 | : size(size_) { 11 | this->sprite.addSquare({}, size, SignedAxis::ZP); 12 | this->sprite.update(); 13 | this->sprite.setMaterial(CHIRA_GET_MATERIAL(materialType, materialID)); 14 | } 15 | 16 | public: 17 | TransformComponent* transform = nullptr; 18 | MeshDataBuilder sprite{}; 19 | glm::vec2 size; 20 | }; 21 | 22 | } // namespace chira 23 | -------------------------------------------------------------------------------- /engine/entity/component/NameComponent.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace chira { 6 | 7 | struct NameComponent { 8 | explicit NameComponent(std::string name_) 9 | : name(std::move(name_)) {} 10 | 11 | public: 12 | std::string name; 13 | }; 14 | 15 | } // namespace chira 16 | -------------------------------------------------------------------------------- /engine/entity/component/SkyboxComponent.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | namespace chira { 7 | 8 | struct SkyboxComponent { 9 | explicit SkyboxComponent(const std::string& cubemapId = "file://materials/skybox.json") { 10 | this->skybox.addCube({}, {1, 1, 1}, false); 11 | this->skybox.update(); 12 | this->skybox.setMaterial(Resource::getResource(cubemapId).cast()); 13 | } 14 | 15 | public: 16 | MeshDataBuilder skybox{}; 17 | }; 18 | 19 | } // namespace chira 20 | -------------------------------------------------------------------------------- /engine/entity/component/TagComponents.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace chira { 4 | 5 | struct NoRenderTagComponent {}; 6 | 7 | struct SceneTagComponent {}; 8 | 9 | } // namespace chira 10 | -------------------------------------------------------------------------------- /engine/entity/component/UUIDComponent.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace chira { 6 | 7 | struct UUIDComponent { 8 | UUIDComponent() 9 | : uuid(UUIDGenerator::getNewUUID()) {} 10 | 11 | explicit UUIDComponent(uuids::uuid uuid_) 12 | : uuid(uuid_) {} 13 | 14 | public: 15 | uuids::uuid uuid; 16 | }; 17 | 18 | } // namespace chira 19 | -------------------------------------------------------------------------------- /engine/i18n/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | list(APPEND CHIRA_ENGINE_HEADERS 2 | ${CMAKE_CURRENT_LIST_DIR}/TranslationFileResource.h 3 | ${CMAKE_CURRENT_LIST_DIR}/TranslationManager.h) 4 | 5 | list(APPEND CHIRA_ENGINE_SOURCES 6 | ${CMAKE_CURRENT_LIST_DIR}/TranslationFileResource.cpp 7 | ${CMAKE_CURRENT_LIST_DIR}/TranslationManager.cpp) 8 | -------------------------------------------------------------------------------- /engine/i18n/TranslationFileResource.cpp: -------------------------------------------------------------------------------- 1 | #include "TranslationFileResource.h" 2 | 3 | using namespace chira; 4 | 5 | std::string_view TranslationFileResource::getLanguage() const { 6 | return this->language; 7 | } 8 | 9 | bool TranslationFileResource::hasTranslation(const std::string& key) const { 10 | return this->strings.contains(key); 11 | } 12 | 13 | std::string TranslationFileResource::getTranslation(const std::string& key) const { 14 | if (this->strings.contains(key)) { 15 | return this->strings.at(key); 16 | } 17 | return key + "#" + this->language; 18 | } 19 | 20 | std::unordered_map TranslationFileResource::getAllTranslations() const { 21 | return this->strings.get>(); 22 | } 23 | -------------------------------------------------------------------------------- /engine/i18n/TranslationFileResource.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | namespace chira { 8 | 9 | class TranslationFileResource : public JSONResource { 10 | public: 11 | TranslationFileResource(std::string identifier_, std::string language_) 12 | : JSONResource(std::move(identifier_)) 13 | , language(std::move(language_)) {} 14 | 15 | void compile(const nlohmann::json& translations) override { 16 | this->strings = translations; 17 | } 18 | 19 | [[nodiscard]] std::string_view getLanguage() const; 20 | 21 | [[nodiscard]] bool hasTranslation(const std::string& key) const; 22 | 23 | /// Note: Currently nlohmann::json does not support string_view unfortunately. 24 | /// If this ever changes, please change this function to use it! 25 | [[nodiscard]] std::string getTranslation(const std::string& key) const; 26 | 27 | [[nodiscard]] std::unordered_map getAllTranslations() const; 28 | 29 | private: 30 | std::string language; 31 | nlohmann::json strings; 32 | }; 33 | 34 | } // namespace chira 35 | -------------------------------------------------------------------------------- /engine/i18n/TranslationManager.cpp: -------------------------------------------------------------------------------- 1 | #include "TranslationManager.h" 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace chira; 8 | 9 | CHIRA_CREATE_LOG(I18N); 10 | 11 | [[maybe_unused]] // todo: set language based on system language 12 | ConVar ui_language{"ui_language", std::string{"en"}, "The language code used to get translated strings.", CON_FLAG_CACHE}; 13 | 14 | const std::unordered_map& TranslationManager::getCodeAndNamePairs() { 15 | static std::unordered_map languageDefinitions { 16 | {"en", "English"}, 17 | {"jp", "Japanese"}, 18 | }; // todo: add all major language definitions 19 | return languageDefinitions; 20 | } 21 | 22 | std::string_view TranslationManager::getLanguageNameFromCode(const std::string& code) { 23 | return TranslationManager::getCodeAndNamePairs().at(code); 24 | } 25 | 26 | bool TranslationManager::isValidCode(const std::string& code) { 27 | return TranslationManager::getCodeAndNamePairs().count(code) > 0; 28 | } 29 | 30 | void TranslationManager::addTranslationFile(const std::string& identifier) { 31 | auto file = Resource::getResource(identifier + "_" + ui_language.getValue() + ".json", ui_language.getValue()); 32 | for (const auto& [id, value] : file->getAllTranslations()) { 33 | TranslationManager::languageStrings[id] = value; 34 | } 35 | } 36 | 37 | void TranslationManager::addUniversalFile(const std::string& identifier) { 38 | auto file = Resource::getResource(identifier + "_" + "universal.json", "universal"); 39 | for (const auto& [id, value] : file->getAllTranslations()) { 40 | TranslationManager::languageStrings[id] = value; 41 | } 42 | } 43 | 44 | std::string TranslationManager::getTranslation(const std::string& identifier) { // NOLINT(misc-no-recursion) 45 | if (TranslationManager::languageStrings.contains(identifier)) 46 | return TranslationManager::languageStrings[identifier]; 47 | else if (TranslationManager::languageStrings.contains("error.translation_manager.missing_translation")) 48 | LOG_I18N.error(TRF("error.translation_manager.missing_translation", TranslationManager::getLanguageNameFromCode(ui_language.getValue()), identifier)); 49 | else 50 | // Turns out if we're missing one string, we could be missing all of them! Just default to English 51 | LOG_I18N.error(fmt::format("Missing {} translation of \"{}\"", TranslationManager::getLanguageNameFromCode(ui_language.getValue()), identifier)); 52 | // Fallback 53 | return identifier + "#" + ui_language.getValue(); 54 | } 55 | -------------------------------------------------------------------------------- /engine/i18n/TranslationManager.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "TranslationFileResource.h" 4 | #include 5 | 6 | namespace chira { 7 | 8 | class TranslationManager { 9 | public: 10 | static const std::unordered_map& getCodeAndNamePairs(); 11 | static std::string_view getLanguageNameFromCode(const std::string& code); 12 | static bool isValidCode(const std::string& code); 13 | static void addTranslationFile(const std::string& identifier); 14 | static void addUniversalFile(const std::string& identifier); 15 | static std::string getTranslation(const std::string& identifier); 16 | template static std::string getTranslation(const std::string& identifier, Params... params) { 17 | return fmt::format(fmt::runtime(TranslationManager::getTranslation(identifier)), params...); 18 | } 19 | private: 20 | static inline std::unordered_map languageStrings; 21 | }; 22 | 23 | } // namespace chira 24 | 25 | /// Get translation from identifier 26 | #define TR(ID) chira::TranslationManager::getTranslation(ID) 27 | /// Get translation from identifier as const char* 28 | #define TRC(ID) TR(ID).c_str() 29 | /// Get translation from identifier for use in fmt::format 30 | #define TRF(ID, ...) chira::TranslationManager::getTranslation(ID, __VA_ARGS__) 31 | -------------------------------------------------------------------------------- /engine/input/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | list(APPEND CHIRA_ENGINE_HEADERS 2 | ${CMAKE_CURRENT_LIST_DIR}/InputManager.h) 3 | 4 | list(APPEND CHIRA_ENGINE_SOURCES 5 | ${CMAKE_CURRENT_LIST_DIR}/InputManager.cpp) 6 | -------------------------------------------------------------------------------- /engine/input/InputManager.cpp: -------------------------------------------------------------------------------- 1 | #include "InputManager.h" 2 | 3 | #include 4 | 5 | using namespace chira; 6 | 7 | [[maybe_unused]] 8 | ConVar input_invert_x_axis{"input_invert_x_axis", false, "Invert the X axis for a mouse or controller.", CON_FLAG_CACHE}; 9 | [[maybe_unused]] 10 | ConVar input_invert_y_axis{"input_invert_y_axis", false, "Invert the Y axis for a mouse or controller.", CON_FLAG_CACHE}; 11 | -------------------------------------------------------------------------------- /engine/input/InputManager.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | namespace chira::Input { 10 | 11 | template 12 | class Event { 13 | public: 14 | Event(T event_, U eventType_, std::function func_) 15 | : event(event_) 16 | , eventType(eventType_) 17 | , func(std::move(func_)) {} 18 | [[nodiscard]] inline T getEvent() const { 19 | return this->event; 20 | } 21 | [[nodiscard]] inline U getEventType() const { 22 | return this->eventType; 23 | } 24 | inline void operator()(CallbackArgs... args) const { 25 | this->func(args...); 26 | } 27 | 28 | static inline void create(T event, U eventType, std::function func) { 29 | Event::events.emplace_back(event, eventType, std::move(func)); 30 | } 31 | 32 | static inline const std::vector>& getEvents() { 33 | return Event::events; 34 | } 35 | protected: 36 | T event; 37 | U eventType; 38 | std::function func; 39 | 40 | static inline std::vector> events; 41 | }; 42 | 43 | using Key = SDL_KeyCode; 44 | enum class KeyEventType { 45 | RELEASED, 46 | PRESSED, 47 | REPEATED, 48 | }; 49 | using KeyEvent = Event; 50 | 51 | // Match SDL_BUTTON_ 52 | enum class Mouse : uint8_t { 53 | BUTTON_LEFT = 1, 54 | BUTTON_MIDDLE = 2, 55 | BUTTON_RIGHT = 3, 56 | BUTTON_X1 = 4, 57 | BUTTON_X2 = 5, 58 | }; 59 | enum class MouseEventType { 60 | RELEASED, 61 | CLICKED, 62 | }; 63 | using MouseEvent = Event; 64 | 65 | enum class MouseMotion { 66 | MOVEMENT, 67 | SCROLL, 68 | }; 69 | enum class MouseMotionEventType { 70 | NOT_APPLICABLE, 71 | }; 72 | using MouseMotionEvent = Event; 73 | 74 | } // namespace chira::Input 75 | -------------------------------------------------------------------------------- /engine/loader/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | include(${CMAKE_CURRENT_LIST_DIR}/image/CMakeLists.txt) 2 | include(${CMAKE_CURRENT_LIST_DIR}/mesh/CMakeLists.txt) 3 | include(${CMAKE_CURRENT_LIST_DIR}/settings/CMakeLists.txt) 4 | -------------------------------------------------------------------------------- /engine/loader/image/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | list(APPEND CHIRA_ENGINE_HEADERS 2 | ${CMAKE_CURRENT_LIST_DIR}/Image.h) 3 | 4 | list(APPEND CHIRA_ENGINE_SOURCES 5 | ${CMAKE_CURRENT_LIST_DIR}/Image.cpp) 6 | -------------------------------------------------------------------------------- /engine/loader/image/Image.cpp: -------------------------------------------------------------------------------- 1 | #include "Image.h" 2 | 3 | #define STB_IMAGE_IMPLEMENTATION 4 | #include 5 | 6 | using namespace chira; 7 | 8 | Image::~Image() { 9 | if (this->image) { 10 | stbi_image_free(image); 11 | } 12 | } 13 | 14 | Image::Image(std::string identifier_, bool vFlip) 15 | : Resource(std::move(identifier_)) 16 | , verticalFlip(vFlip) {} 17 | 18 | void Image::compile(const byte buffer[], std::size_t bufferLen) { 19 | int w, h, bd; 20 | this->image = Image::getUncompressedImage(buffer, static_cast(bufferLen) - 1, &w, &h, &bd, 0, this->isVerticallyFlipped()); 21 | this->width = w; 22 | this->height = h; 23 | this->bitDepth = bd; 24 | } 25 | 26 | byte* Image::getUncompressedImage(const byte buffer[], int bufferLen, int* width, int* height, int* fileChannels, int desiredChannels, bool vflip) { 27 | stbi_set_flip_vertically_on_load(vflip); 28 | return stbi_load_from_memory(buffer, bufferLen, width, height, fileChannels, desiredChannels); 29 | } 30 | 31 | byte* Image::getUncompressedImage(const byte buffer[], int bufferLen, int desiredChannels, bool vflip) { 32 | int width, height, fileChannels; 33 | return Image::getUncompressedImage(buffer, bufferLen, &width, &height, &fileChannels, desiredChannels, vflip); 34 | } 35 | 36 | byte* Image::getUncompressedImage(std::string_view filepath, int* width, int* height, int* fileChannels, int desiredChannels, bool vflip) { 37 | stbi_set_flip_vertically_on_load(vflip); 38 | return stbi_load(filepath.data(), width, height, fileChannels, desiredChannels); 39 | } 40 | 41 | byte* Image::getUncompressedImage(std::string_view filepath, int desiredChannels, bool vflip) { 42 | int width, height, fileChannels; 43 | return Image::getUncompressedImage(filepath, &width, &height, &fileChannels, desiredChannels, vflip); 44 | } 45 | 46 | void Image::deleteUncompressedImage(byte* image) { 47 | if (image) { 48 | stbi_image_free(image); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /engine/loader/image/Image.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | namespace chira { 7 | 8 | class Image : public Resource { 9 | public: 10 | explicit Image(std::string identifier_, bool vFlip = true); 11 | ~Image() override; 12 | Image(const Image& other) = delete; 13 | Image& operator=(const Image& other) = delete; 14 | Image(Image&& other) noexcept = default; 15 | Image& operator=(Image&& other) noexcept = default; 16 | 17 | void compile(const byte buffer[], std::size_t bufferLen) override; 18 | [[nodiscard]] inline byte* getData() const { 19 | return this->image; 20 | } 21 | [[nodiscard]] inline int getWidth() const { 22 | return this->width; 23 | } 24 | [[nodiscard]] inline int getHeight() const { 25 | return this->height; 26 | } 27 | [[nodiscard]] inline int getBitDepth() const { 28 | return this->bitDepth; 29 | } 30 | [[nodiscard]] inline bool isVerticallyFlipped() const { 31 | return this->verticalFlip; 32 | } 33 | 34 | [[nodiscard]] static byte* getUncompressedImage(const byte buffer[], int bufferLen, int* width, int* height, int* fileChannels, int desiredChannels, bool vflip); 35 | [[nodiscard]] static byte* getUncompressedImage(const byte buffer[], int bufferLen, int desiredChannels, bool vflip); 36 | [[nodiscard]] static byte* getUncompressedImage(std::string_view filepath, int* width, int* height, int* fileChannels, int desiredChannels, bool vflip); 37 | [[nodiscard]] static byte* getUncompressedImage(std::string_view filepath, int desiredChannels, bool vflip); 38 | static void deleteUncompressedImage(byte* image); 39 | protected: 40 | byte* image = nullptr; 41 | int width = -1; 42 | int height = -1; 43 | int bitDepth = -1; 44 | bool verticalFlip = true; 45 | private: 46 | CHIRA_REGISTER_DEFAULT_RESOURCE(Image, "file://textures/missing.png"); 47 | }; 48 | 49 | } // namespace chira 50 | -------------------------------------------------------------------------------- /engine/loader/mesh/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | list(APPEND CHIRA_ENGINE_HEADERS 2 | ${CMAKE_CURRENT_LIST_DIR}/ChiraMeshLoader.h 3 | ${CMAKE_CURRENT_LIST_DIR}/IMeshLoader.h 4 | ${CMAKE_CURRENT_LIST_DIR}/OBJMeshLoader.h) 5 | 6 | list(APPEND CHIRA_ENGINE_SOURCES 7 | ${CMAKE_CURRENT_LIST_DIR}/ChiraMeshLoader.cpp 8 | ${CMAKE_CURRENT_LIST_DIR}/IMeshLoader.cpp 9 | ${CMAKE_CURRENT_LIST_DIR}/OBJMeshLoader.cpp) 10 | -------------------------------------------------------------------------------- /engine/loader/mesh/ChiraMeshLoader.cpp: -------------------------------------------------------------------------------- 1 | #include "ChiraMeshLoader.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | using namespace chira; 10 | 11 | CHIRA_CREATE_LOG(CMDL); 12 | 13 | void ChiraMeshLoader::loadMesh(const std::string& identifier, std::vector& vertices, std::vector& indices) const { 14 | auto meshData = Resource::getResource(identifier); 15 | if (meshData->getBufferLength() < CHIRA_MESH_HEADER_SIZE) { 16 | // die 17 | LOG_CMDL.error(TRF("error.cmdl_loader.invalid_data", identifier)); 18 | return; 19 | } 20 | ChiraMeshHeader header; 21 | std::memcpy(&header, meshData->getBuffer(), CHIRA_MESH_HEADER_SIZE); 22 | 23 | // read mesh data 24 | if (header.version == 1) { 25 | vertices.resize(header.vertexCount); 26 | std::memcpy(vertices.data(), meshData->getBuffer() + CHIRA_MESH_HEADER_SIZE, header.vertexCount * sizeof(Vertex)); 27 | indices.resize(header.indexCount); 28 | std::memcpy(indices.data(), meshData->getBuffer() + CHIRA_MESH_HEADER_SIZE + (header.vertexCount * sizeof(Vertex)), header.indexCount * sizeof(Index)); 29 | } 30 | } 31 | 32 | std::vector ChiraMeshLoader::createMesh(const std::vector& vertices, const std::vector& indices) const { 33 | std::vector bytebuffer; 34 | ChiraMeshHeader header; 35 | header.version = 1; 36 | header.vertexCount = static_cast(vertices.size()); 37 | header.indexCount = static_cast(indices.size()); 38 | const unsigned int VERTEX_SIZE = (sizeof(Vertex) * header.vertexCount); 39 | const unsigned int INDEX_SIZE = (sizeof(Index) * header.indexCount); 40 | 41 | // Since each element in bytebuffer is one byte wide, this works 42 | bytebuffer.resize(CHIRA_MESH_HEADER_SIZE + VERTEX_SIZE + INDEX_SIZE); 43 | std::memcpy(bytebuffer.data(), &header, CHIRA_MESH_HEADER_SIZE); 44 | std::memcpy(bytebuffer.data() + CHIRA_MESH_HEADER_SIZE, vertices.data(), VERTEX_SIZE); 45 | std::memcpy(bytebuffer.data() + CHIRA_MESH_HEADER_SIZE + VERTEX_SIZE, indices.data(), INDEX_SIZE); 46 | 47 | return bytebuffer; 48 | } 49 | -------------------------------------------------------------------------------- /engine/loader/mesh/ChiraMeshLoader.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "IMeshLoader.h" 4 | 5 | namespace chira { 6 | 7 | class ChiraMeshLoader : public IMeshLoader { 8 | public: 9 | void loadMesh(const std::string& identifier, std::vector& vertices, std::vector& indices) const override; 10 | [[nodiscard]] std::vector createMesh(const std::vector& vertices, const std::vector& indices) const override; 11 | }; 12 | 13 | struct ChiraMeshHeader { 14 | unsigned int version = 0; 15 | unsigned int vertexCount = 0; 16 | unsigned int indexCount = 0; 17 | }; 18 | constexpr unsigned short CHIRA_MESH_HEADER_SIZE = sizeof(ChiraMeshHeader); 19 | 20 | } // namespace chira 21 | -------------------------------------------------------------------------------- /engine/loader/mesh/IMeshLoader.cpp: -------------------------------------------------------------------------------- 1 | #include "IMeshLoader.h" 2 | 3 | using namespace chira; 4 | 5 | void IMeshLoader::addMeshLoader(const std::string& name, IMeshLoader* meshLoader) { 6 | IMeshLoader::meshLoaders[name] = std::unique_ptr(meshLoader); 7 | } 8 | 9 | IMeshLoader* IMeshLoader::getMeshLoader(const std::string& name) { 10 | return IMeshLoader::meshLoaders[name].get(); 11 | } 12 | -------------------------------------------------------------------------------- /engine/loader/mesh/IMeshLoader.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | namespace chira { 11 | 12 | class IMeshLoader { 13 | public: 14 | virtual ~IMeshLoader() = default; 15 | virtual void loadMesh(const std::string& identifier, std::vector& vertices, std::vector& indices) const = 0; 16 | [[nodiscard]] virtual std::vector createMesh(const std::vector& vertices, const std::vector& indices) const = 0; 17 | static void addMeshLoader(const std::string& name, IMeshLoader* meshLoader); 18 | static IMeshLoader* getMeshLoader(const std::string& name); 19 | private: 20 | static inline std::unordered_map> meshLoaders; 21 | }; 22 | 23 | } // namespace chira 24 | -------------------------------------------------------------------------------- /engine/loader/mesh/OBJMeshLoader.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "IMeshLoader.h" 4 | 5 | namespace chira { 6 | 7 | class OBJMeshLoader : public IMeshLoader { 8 | public: 9 | void loadMesh(const std::string& identifier, std::vector& vertices, std::vector& indices) const override; 10 | [[nodiscard]] std::vector createMesh(const std::vector& vertices, const std::vector& indices) const override; 11 | private: 12 | static void addVertex(Vertex v, Index* currentIndex, std::vector& vertices, std::vector& indices); 13 | }; 14 | 15 | } // namespace chira 16 | -------------------------------------------------------------------------------- /engine/loader/settings/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | list(APPEND CHIRA_ENGINE_HEADERS 2 | ${CMAKE_CURRENT_LIST_DIR}/ISettingsLoader.h 3 | ${CMAKE_CURRENT_LIST_DIR}/JSONSettingsLoader.h) 4 | 5 | list(APPEND CHIRA_ENGINE_SOURCES 6 | ${CMAKE_CURRENT_LIST_DIR}/ISettingsLoader.cpp 7 | ${CMAKE_CURRENT_LIST_DIR}/JSONSettingsLoader.cpp) 8 | -------------------------------------------------------------------------------- /engine/loader/settings/ISettingsLoader.cpp: -------------------------------------------------------------------------------- 1 | #include "ISettingsLoader.h" 2 | 3 | #include 4 | 5 | using namespace chira; 6 | 7 | ISettingsLoader::ISettingsLoader(std::string_view filename, std::string_view path, bool relative /*= false*/) { 8 | std::string pathStr; 9 | if (relative) { 10 | pathStr = std::filesystem::current_path().append(path).string(); 11 | } else { 12 | pathStr = path; 13 | } 14 | 15 | // Test for the path's existence and create it if it doesn't exist 16 | if (!std::filesystem::exists(pathStr)) { 17 | std::filesystem::create_directory(pathStr); 18 | } 19 | this->filepath = pathStr; 20 | this->filepath.append(filename); 21 | } 22 | -------------------------------------------------------------------------------- /engine/loader/settings/ISettingsLoader.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | namespace chira { 7 | 8 | class ISettingsLoader { 9 | public: 10 | explicit ISettingsLoader(std::string_view filename, std::string_view path, bool relative = false); 11 | virtual ~ISettingsLoader() = default; 12 | 13 | virtual void getValue(const std::string& name, int* value) const = 0; 14 | virtual void getValue(const std::string& name, double* value) const = 0; 15 | virtual void getValue(const std::string& name, std::string* value) const = 0; 16 | virtual void getValue(const std::string& name, bool* value) const = 0; 17 | 18 | virtual void setValue(const std::string& name, int value, bool overwrite, bool save) = 0; 19 | virtual void setValue(const std::string& name, double value, bool overwrite, bool save) = 0; 20 | virtual void setValue(const std::string& name, const std::string& value, bool overwrite, bool save) = 0; 21 | virtual void setValue(const std::string& name, bool value, bool overwrite, bool save) = 0; 22 | 23 | [[nodiscard]] virtual bool hasValue(const std::string& name) const = 0; 24 | 25 | virtual void load() = 0; 26 | virtual void save() = 0; 27 | 28 | [[nodiscard]] std::string_view getFilePath() const { 29 | return this->filepath; 30 | } 31 | private: 32 | std::string filepath; 33 | }; 34 | 35 | } // namespace chira 36 | -------------------------------------------------------------------------------- /engine/loader/settings/JSONSettingsLoader.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "ISettingsLoader.h" 6 | 7 | namespace chira { 8 | 9 | class JSONSettingsLoader : public ISettingsLoader { 10 | public: 11 | explicit JSONSettingsLoader(std::string_view filename); 12 | JSONSettingsLoader(std::string_view filename, std::string_view path, bool relative = false); 13 | 14 | void getValue(const std::string& name, int* value) const override; 15 | void getValue(const std::string& name, double* value) const override; 16 | void getValue(const std::string& name, std::string* value) const override; 17 | void getValue(const std::string& name, bool* value) const override; 18 | 19 | void setValue(const std::string& name, int value, bool overwrite, bool save) override; 20 | void setValue(const std::string& name, double value, bool overwrite, bool save) override; 21 | void setValue(const std::string& name, const std::string& value, bool overwrite, bool save) override; 22 | void setValue(const std::string& name, bool value, bool overwrite, bool save) override; 23 | 24 | [[nodiscard]] bool hasValue(const std::string& name) const override; 25 | 26 | void load() final; 27 | void save() final; 28 | private: 29 | nlohmann::json settings{}; 30 | }; 31 | 32 | } // namespace chira 33 | -------------------------------------------------------------------------------- /engine/math/Axis.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace chira { 4 | 5 | enum class Axis { 6 | X, 7 | Y, 8 | Z, 9 | }; 10 | 11 | enum class SignedAxis { 12 | XP, 13 | XN, 14 | YP, 15 | YN, 16 | ZP, 17 | ZN, 18 | }; 19 | 20 | } // namespace chira 21 | -------------------------------------------------------------------------------- /engine/math/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | list(APPEND CHIRA_ENGINE_HEADERS 2 | ${CMAKE_CURRENT_LIST_DIR}/Axis.h 3 | ${CMAKE_CURRENT_LIST_DIR}/Color.h 4 | ${CMAKE_CURRENT_LIST_DIR}/Graph.h 5 | ${CMAKE_CURRENT_LIST_DIR}/Matrix.h 6 | ${CMAKE_CURRENT_LIST_DIR}/Types.h 7 | ${CMAKE_CURRENT_LIST_DIR}/Vertex.h) 8 | -------------------------------------------------------------------------------- /engine/math/Color.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace chira { 6 | 7 | struct ColorR { 8 | float r; 9 | ColorR(float R) // NOLINT(google-explicit-constructor) 10 | : r(std::clamp(R, 0.f, 1.f)) {} 11 | ColorR() 12 | : ColorR(0) {} 13 | bool operator==(const ColorR& other) const { 14 | return this->r == other.r; 15 | } 16 | bool operator!=(const ColorR& other) const { 17 | return !this->operator==(other); 18 | } 19 | }; 20 | 21 | struct ColorRG { 22 | float r; 23 | float g; 24 | ColorRG(float R, float G) 25 | : r(std::clamp(R, 0.f, 1.f)) 26 | , g(std::clamp(G, 0.f, 1.f)) {} 27 | ColorRG(float all) // NOLINT(google-explicit-constructor) 28 | : ColorRG(all, all) {} 29 | ColorRG() 30 | : ColorRG(0) {} 31 | bool operator==(const ColorRG& other) const { 32 | return this->r == other.r && this->g == other.g; 33 | } 34 | bool operator!=(const ColorRG& other) const { 35 | return !this->operator==(other); 36 | } 37 | }; 38 | 39 | struct ColorRGB { 40 | float r; 41 | float g; 42 | float b; 43 | ColorRGB(float R, float G, float B) 44 | : r(std::clamp(R, 0.f, 1.f)) 45 | , g(std::clamp(G, 0.f, 1.f)) 46 | , b(std::clamp(B, 0.f, 1.f)) {} 47 | ColorRGB(float all) // NOLINT(google-explicit-constructor) 48 | : ColorRGB(all, all, all) {} 49 | ColorRGB() 50 | : ColorRGB(0) {} 51 | bool operator==(const ColorRGB& other) const { 52 | return this->r == other.r && this->g == other.g && this->b == other.b; 53 | } 54 | bool operator!=(const ColorRGB& other) const { 55 | return !this->operator==(other); 56 | } 57 | }; 58 | 59 | struct ColorRGBA { 60 | float r; 61 | float g; 62 | float b; 63 | float a; 64 | ColorRGBA(float R, float G, float B, float A = 1.f) 65 | : r(std::clamp(R, 0.f, 1.f)) 66 | , g(std::clamp(G, 0.f, 1.f)) 67 | , b(std::clamp(B, 0.f, 1.f)) 68 | , a(std::clamp(A, 0.f, 1.f)) {} 69 | ColorRGBA(float all, float A = 1.f) // NOLINT(google-explicit-constructor) 70 | : ColorRGBA(all, all, all, A) {} 71 | ColorRGBA(ColorRGB color, float A = 1.f) // NOLINT(google-explicit-constructor) 72 | : ColorRGBA(color.r, color.g, color.b, A) {} 73 | ColorRGBA() 74 | : ColorRGBA(0) {} 75 | bool operator==(const ColorRGBA& other) const { 76 | return this->r == other.r && this->g == other.g && this->b == other.b && this->a == other.a; 77 | } 78 | bool operator!=(const ColorRGBA& other) const { 79 | return !this->operator==(other); 80 | } 81 | }; 82 | 83 | } // namespace chira 84 | -------------------------------------------------------------------------------- /engine/math/Graph.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | namespace chira { 9 | 10 | class UnweightedDirectedGraph { 11 | public: 12 | struct Node { 13 | private: 14 | friend class UnweightedDirectedGraph; 15 | public: 16 | void addEdge(Node* node) { 17 | this->edges.push_back(node); 18 | } 19 | 20 | void removeEdge(Node* node) { 21 | this->edges.erase(std::remove(this->edges.begin(), this->edges.end(), node), this->edges.end()); 22 | } 23 | 24 | std::string name; 25 | std::vector edges; 26 | 27 | private: 28 | explicit Node(std::string name_) 29 | : name(std::move(name_)) {} 30 | }; 31 | 32 | UnweightedDirectedGraph() = default; 33 | 34 | Node* addNode(const std::string& name) { 35 | auto node = new Node{name}; 36 | this->nodes.emplace_back(node); 37 | return node; 38 | } 39 | 40 | [[nodiscard]] Node* getNode(const std::string& name) const { 41 | if (auto node = std::find_if(this->nodes.begin(), this->nodes.end(), [name](const std::unique_ptr& item) { 42 | return item->name == name; 43 | }); node != this->nodes.end()) { 44 | return node->get(); 45 | } 46 | return nullptr; 47 | } 48 | 49 | void removeNode(Node** nodeToRemove) { 50 | for (const auto& node : this->nodes) { 51 | node->removeEdge(*nodeToRemove); 52 | } 53 | this->nodes.erase(std::remove_if(this->nodes.begin(), this->nodes.end(), [nodeToRemove] (const std::unique_ptr& node) { 54 | return node.get() == *nodeToRemove; 55 | }), this->nodes.end()); 56 | *nodeToRemove = nullptr; 57 | } 58 | 59 | [[nodiscard]] const std::vector>& getNodes() const { 60 | return this->nodes; 61 | } 62 | 63 | protected: 64 | std::vector> nodes; 65 | }; 66 | 67 | } // namespace chira 68 | -------------------------------------------------------------------------------- /engine/math/Matrix.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | namespace chira { 8 | 9 | inline glm::mat4 transformToMatrix(const glm::mat4& startMatrix = glm::identity(), const glm::vec2& position = glm::vec2{}, const glm::quat& rotation = glm::identity()) { 10 | return glm::translate(startMatrix, glm::vec3{position, 0}) * glm::mat4_cast(rotation); 11 | } 12 | inline glm::mat4 transformToMatrixScaled(const glm::mat4& startMatrix = glm::identity(), const glm::vec2& position = glm::vec2{}, const glm::quat& rotation = glm::identity(), const glm::vec3& scale = glm::vec3{1}) { 13 | return glm::scale(transformToMatrix(startMatrix, position, rotation), scale); 14 | } 15 | inline glm::mat4 transformToMatrix(const glm::mat4& startMatrix = glm::identity(), const glm::vec3& position = glm::vec3{}, const glm::quat& rotation = glm::identity()) { 16 | return glm::translate(startMatrix, position) * glm::mat4_cast(rotation); 17 | } 18 | inline glm::mat4 transformToMatrixScaled(const glm::mat4& startMatrix = glm::identity(), const glm::vec3& position = glm::vec3{}, const glm::quat& rotation = glm::identity(), const glm::vec3& scale = glm::vec3{1}) { 19 | return glm::scale(transformToMatrix(startMatrix, position, rotation), scale); 20 | } 21 | 22 | } // namespace chira 23 | -------------------------------------------------------------------------------- /engine/math/Types.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | // Defined outside the chira namespace so it looks better in headers 9 | using byte = std::uint8_t; 10 | 11 | namespace glm { 12 | 13 | using vec2b = vec<2, bool>; 14 | using vec2i = vec<2, int>; 15 | using vec2u = vec<2, unsigned int>; 16 | using vec2f = vec<2, float>; 17 | using vec2d = vec<2, double>; 18 | 19 | using vec3b = vec<3, bool>; 20 | using vec3i = vec<3, int>; 21 | using vec3u = vec<3, unsigned int>; 22 | using vec3f = vec<3, float>; 23 | using vec3d = vec<3, double>; 24 | 25 | using vec4b = vec<4, bool>; 26 | using vec4i = vec<4, int>; 27 | using vec4u = vec<4, unsigned int>; 28 | using vec4f = vec<4, float>; 29 | using vec4d = vec<4, double>; 30 | 31 | constexpr const std::size_t VEC4F_SIZE = sizeof(vec4f); 32 | constexpr const std::size_t MAT4_SIZE = sizeof(mat4); 33 | 34 | NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(vec2b, x, y) 35 | NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(vec2i, x, y) 36 | NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(vec2u, x, y) 37 | NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(vec2f, x, y) 38 | NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(vec2d, x, y) 39 | 40 | NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(vec3b, x, y, z) 41 | NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(vec3i, x, y, z) 42 | NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(vec3u, x, y, z) 43 | NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(vec3f, x, y, z) 44 | NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(vec3d, x, y, z) 45 | 46 | NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(vec4b, x, y, z, w) 47 | NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(vec4i, x, y, z, w) 48 | NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(vec4u, x, y, z, w) 49 | NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(vec4f, x, y, z, w) 50 | NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(vec4d, x, y, z, w) 51 | 52 | NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(quat, x, y, z, w) 53 | 54 | } // namespace glm 55 | -------------------------------------------------------------------------------- /engine/math/Vertex.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "Color.h" 6 | 7 | namespace chira { 8 | 9 | struct Vertex { 10 | glm::vec3 position; 11 | ColorRGB normal; 12 | ColorRGB color; 13 | ColorRG uv; 14 | 15 | Vertex() 16 | : position() 17 | , normal() 18 | , color(1, 1, 1) 19 | , uv() {} 20 | explicit Vertex(glm::vec3 pos) 21 | : position(pos) 22 | , normal() 23 | , color(1, 1, 1) 24 | , uv() {} 25 | Vertex(glm::vec3 pos, ColorRGB norm) 26 | : position(pos) 27 | , normal(norm) 28 | , color(1, 1, 1) 29 | , uv() {} 30 | Vertex(glm::vec3 pos, ColorRGB norm, ColorRGB col) 31 | : position(pos) 32 | , normal(norm) 33 | , color(col) 34 | , uv() {} 35 | Vertex(glm::vec3 pos, ColorRGB norm, ColorRGB col, ColorRG tex) 36 | : position(pos) 37 | , normal(norm) 38 | , color(col) 39 | , uv(tex) {} 40 | Vertex(glm::vec3 pos, ColorRGB norm, ColorRG tex) 41 | : position(pos) 42 | , normal(norm) 43 | , color(1, 1, 1) 44 | , uv(tex) {} 45 | Vertex(glm::vec3 pos, ColorRG tex) 46 | : position(pos) 47 | , normal() 48 | , color(1, 1, 1) 49 | , uv(tex) {} 50 | 51 | bool operator==(const Vertex& other) const { 52 | return this->position == other.position && 53 | this->normal == other.normal && 54 | this->color == other.color && 55 | this->uv == other.uv; 56 | } 57 | 58 | bool operator!=(const Vertex& other) const { 59 | return !this->operator==(other); 60 | } 61 | }; 62 | 63 | using Index = unsigned int; 64 | 65 | } // namespace chira 66 | -------------------------------------------------------------------------------- /engine/module/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | include(${CMAKE_CURRENT_LIST_DIR}/audio/CMakeLists.txt) 2 | 3 | if(CHIRA_USE_DISCORD) 4 | include(${CMAKE_CURRENT_LIST_DIR}/discord/CMakeLists.txt) 5 | endif() 6 | 7 | if(CHIRA_USE_STEAMWORKS) 8 | include(${CMAKE_CURRENT_LIST_DIR}/steam/CMakeLists.txt) 9 | endif() 10 | 11 | list(APPEND CHIRA_ENGINE_HEADERS 12 | ${CMAKE_CURRENT_LIST_DIR}/Module.h) 13 | 14 | list(APPEND CHIRA_ENGINE_SOURCES 15 | ${CMAKE_CURRENT_LIST_DIR}/Module.cpp) 16 | -------------------------------------------------------------------------------- /engine/module/Module.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | namespace chira { 13 | 14 | struct IModule : public NoCopyOrMove { 15 | virtual void preinit() {}; 16 | virtual void init() {}; 17 | virtual void update() {}; 18 | virtual void render() {}; 19 | virtual void deinit() {}; 20 | 21 | [[nodiscard]] bool isInitialized() const { 22 | return this->initialized; 23 | } 24 | 25 | protected: 26 | bool initialized = false; 27 | }; 28 | 29 | template 30 | concept CModule = std::derived_from && requires(T) { 31 | {T::DEPS} -> std::same_as&>; 32 | }; 33 | 34 | namespace ModuleRegistry { 35 | 36 | void addModule(IModule* instance, std::string_view name, const std::vector& deps); 37 | 38 | template 39 | inline void addModule(M* instance, std::string_view name) { 40 | addModule(instance, name, M::DEPS); 41 | } 42 | 43 | [[nodiscard]] bool preinitAll(); 44 | 45 | void initAll(); 46 | 47 | void updateAll(); 48 | 49 | void renderAll(); 50 | 51 | void deinitAll(); 52 | 53 | } // namespace ModuleRegistry 54 | 55 | } // namespace chira 56 | 57 | #define CHIRA_CREATE_MODULE(name) \ 58 | struct name##Module final : public IModule 59 | 60 | #define CHIRA_REGISTER_MODULE(name) \ 61 | const auto get##name##ModuleSingleton = [] { \ 62 | static name##Module singleton##name{}; \ 63 | static bool registered = false; \ 64 | if (!registered) { \ 65 | chira::ModuleRegistry::addModule(&singleton##name, #name); \ 66 | registered = true; \ 67 | } \ 68 | return &singleton##name; \ 69 | }; \ 70 | [[maybe_unused]] name##Module* g_##name = get##name##ModuleSingleton() 71 | 72 | #define CHIRA_GET_MODULE(name) \ 73 | extern name##Module* g_##name 74 | -------------------------------------------------------------------------------- /engine/module/audio/Audio.cpp: -------------------------------------------------------------------------------- 1 | #include "Audio.h" 2 | 3 | #include 4 | 5 | using namespace chira; 6 | 7 | CHIRA_REGISTER_MODULE(Audio); 8 | 9 | [[maybe_unused]] 10 | ConVar snd_volume{"snd_volume", 1.0, "Control the volume of the entire application.", CON_FLAG_CACHE, [](ConVar::CallbackArg arg) { 11 | if (!g_Audio->isInitialized()) 12 | return; 13 | float volume = std::stof(arg.data()); 14 | volume = std::clamp(volume, 0.0f, 1.0f); 15 | g_Audio->get().setGlobalVolume(volume); 16 | }}; 17 | -------------------------------------------------------------------------------- /engine/module/audio/Audio.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include 6 | 7 | namespace chira { 8 | 9 | CHIRA_CREATE_MODULE(Audio) { 10 | static inline const std::vector DEPS; 11 | 12 | void init() override { 13 | if (this->initialized) 14 | return; 15 | this->soundEngine.init(); 16 | this->initialized = true; 17 | } 18 | 19 | void deinit() override { 20 | this->soundEngine.deinit(); 21 | } 22 | 23 | [[nodiscard]] SoLoud::Soloud& get() { 24 | if (!this->initialized) { 25 | // This is bad, but whatever 26 | this->init(); 27 | } 28 | return soundEngine; 29 | } 30 | 31 | private: 32 | SoLoud::Soloud soundEngine; 33 | }; 34 | 35 | } // namespace chira 36 | -------------------------------------------------------------------------------- /engine/module/audio/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | list(APPEND CHIRA_ENGINE_HEADERS 2 | ${CMAKE_CURRENT_LIST_DIR}/Audio.h) 3 | 4 | list(APPEND CHIRA_ENGINE_SOURCES 5 | ${CMAKE_CURRENT_LIST_DIR}/Audio.cpp) 6 | -------------------------------------------------------------------------------- /engine/module/discord/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | list(APPEND CHIRA_ENGINE_HEADERS 2 | ${CMAKE_CURRENT_LIST_DIR}/Discord.h) 3 | 4 | list(APPEND CHIRA_ENGINE_SOURCES 5 | ${CMAKE_CURRENT_LIST_DIR}/Discord.cpp) 6 | -------------------------------------------------------------------------------- /engine/module/discord/Discord.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | struct DiscordUser; 10 | 11 | namespace chira { 12 | 13 | struct DiscordButtonData { 14 | std::string name; 15 | std::string url; 16 | }; 17 | 18 | /// Discord should be initialized manually before Engine::init. 19 | /// Setter functions will change the status after update(). 20 | CHIRA_CREATE_MODULE(Discord) { 21 | static inline const std::vector DEPS; 22 | 23 | void init(std::string_view appId); 24 | 25 | void update() override; 26 | 27 | void deinit() override; 28 | 29 | void setState(const std::string& state_); 30 | void setDetails(const std::string& details_); 31 | void setLargeImage(const std::string& imageKey); 32 | void setLargeImageText(const std::string& text); 33 | void setSmallImage(const std::string& imageKey); 34 | void setSmallImageText(const std::string& text); 35 | void setStartTimestamp(std::int64_t time); 36 | void setEndTimestamp(std::int64_t time); 37 | void setTopButton(const DiscordButtonData& button); 38 | void setBottomButton(const DiscordButtonData& button); 39 | 40 | void resetPresence(); 41 | 42 | private: 43 | bool dirty = false; 44 | std::string state; 45 | std::string details; 46 | std::string largeImage; 47 | std::string largeImageText; 48 | std::string smallImage; 49 | std::string smallImageText; 50 | std::int64_t startTimestamp = -1; 51 | std::int64_t endTimestamp = -1; 52 | DiscordButtonData button1, button2; 53 | 54 | using IModule::init; 55 | }; 56 | 57 | } // namespace chira 58 | -------------------------------------------------------------------------------- /engine/module/steam/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | list(APPEND CHIRA_ENGINE_HEADERS 2 | ${CMAKE_CURRENT_LIST_DIR}/Steam.h) 3 | 4 | list(APPEND CHIRA_ENGINE_SOURCES 5 | ${CMAKE_CURRENT_LIST_DIR}/Steam.cpp) 6 | -------------------------------------------------------------------------------- /engine/render/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | include(${CMAKE_CURRENT_LIST_DIR}/backend/CMakeLists.txt) 2 | include(${CMAKE_CURRENT_LIST_DIR}/material/CMakeLists.txt) 3 | include(${CMAKE_CURRENT_LIST_DIR}/mesh/CMakeLists.txt) 4 | include(${CMAKE_CURRENT_LIST_DIR}/shader/CMakeLists.txt) 5 | include(${CMAKE_CURRENT_LIST_DIR}/texture/CMakeLists.txt) 6 | -------------------------------------------------------------------------------- /engine/render/backend/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | include(${CMAKE_CURRENT_LIST_DIR}/api/CMakeLists.txt) 2 | include(${CMAKE_CURRENT_LIST_DIR}/device/CMakeLists.txt) 3 | 4 | list(APPEND CHIRA_ENGINE_HEADERS 5 | ${CMAKE_CURRENT_LIST_DIR}/RenderBackend.h 6 | ${CMAKE_CURRENT_LIST_DIR}/RenderDevice.h 7 | ${CMAKE_CURRENT_LIST_DIR}/RenderTypes.h) 8 | 9 | list(APPEND CHIRA_ENGINE_SOURCES 10 | ${CMAKE_CURRENT_LIST_DIR}/RenderTypes.cpp) 11 | -------------------------------------------------------------------------------- /engine/render/backend/RenderBackend.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #if defined(CHIRA_USE_RENDER_BACKEND_GL) 4 | #include "api/BackendGL.h" 5 | #elif defined(CHIRA_USE_RENDER_BACKEND_SDLRENDERER) 6 | #include "api/BackendSDL.h" 7 | #else 8 | #error "No render backend present!" 9 | #endif 10 | -------------------------------------------------------------------------------- /engine/render/backend/RenderDevice.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #if defined(CHIRA_USE_RENDER_BACKEND_GL) 4 | #include "device/DeviceGL.h" 5 | #elif defined(CHIRA_USE_RENDER_BACKEND_SDLRENDERER) 6 | #include "device/DeviceSDL.h" 7 | #else 8 | #error "No render device present!" 9 | #endif 10 | -------------------------------------------------------------------------------- /engine/render/backend/RenderTypes.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | namespace chira { 8 | 9 | enum class TextureType { 10 | TWO_DIMENSIONAL, 11 | CUBEMAP, 12 | }; 13 | 14 | enum class TextureUnit : int { 15 | G0 = 0, G1, G2, G3, G4, G5, G6, G7, G8, G9, G10, G11, G12, G13, G14, G15, 16 | }; 17 | 18 | enum class TextureFormat { 19 | RED, 20 | RG, 21 | RGB, 22 | RGBA, 23 | BGR, 24 | BGRA, 25 | RED_INT, 26 | RG_INT, 27 | RGB_INT, 28 | RGBA_INT, 29 | BGR_INT, 30 | BGRA_INT, 31 | STENCIL, 32 | DEPTH, 33 | DEPTH_STENCIL, 34 | }; 35 | 36 | enum class WrapMode { 37 | REPEAT, 38 | MIRRORED_REPEAT, 39 | CLAMP_TO_EDGE, 40 | CLAMP_TO_BORDER, 41 | }; 42 | 43 | enum class FilterMode { 44 | NEAREST, 45 | LINEAR, 46 | }; 47 | 48 | [[nodiscard]] TextureFormat getTextureFormatFromString(std::string_view format); 49 | [[nodiscard]] TextureFormat getTextureFormatFromBitDepth(int bd, bool flipRB = false, bool useInts = false); 50 | [[nodiscard]] WrapMode getWrapModeFromString(std::string_view mode); 51 | [[nodiscard]] FilterMode getFilterModeFromString(std::string_view mode); 52 | 53 | enum class ShaderModuleType { 54 | VERTEX, 55 | FRAGMENT, 56 | }; 57 | 58 | template 59 | concept ShaderUniformValueTypes = 60 | std::same_as || 61 | std::same_as || 62 | std::same_as || 63 | std::same_as || 64 | 65 | std::same_as || 66 | std::same_as || 67 | std::same_as || 68 | std::same_as || 69 | 70 | std::same_as || 71 | std::same_as || 72 | std::same_as || 73 | std::same_as || 74 | 75 | std::same_as || 76 | std::same_as || 77 | std::same_as || 78 | std::same_as || 79 | std::same_as; 80 | 81 | enum class MeshDrawMode { 82 | STATIC, 83 | DYNAMIC, 84 | }; 85 | 86 | enum class MeshDepthFunction { 87 | NEVER, 88 | ALWAYS, 89 | EQUAL, 90 | NOTEQUAL, 91 | LESS, 92 | LEQUAL, 93 | GREATER, 94 | GEQUAL, 95 | }; 96 | 97 | enum class MeshCullType { 98 | BACK, 99 | FRONT, 100 | NONE, 101 | }; 102 | 103 | [[nodiscard]] MeshDepthFunction getMeshDepthFunctionFromString(std::string_view function); 104 | [[nodiscard]] MeshCullType getMeshCullTypeFromString(std::string_view type); 105 | 106 | } // namespace chira 107 | -------------------------------------------------------------------------------- /engine/render/backend/api/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | if((CHIRA_RENDER_BACKEND STREQUAL "GL40") OR (CHIRA_RENDER_BACKEND STREQUAL "GL41") OR (CHIRA_RENDER_BACKEND STREQUAL "GL43")) 2 | list(APPEND CHIRA_ENGINE_HEADERS 3 | ${CMAKE_CURRENT_LIST_DIR}/BackendGL.h) 4 | list(APPEND CHIRA_ENGINE_SOURCES 5 | ${CMAKE_CURRENT_LIST_DIR}/BackendGL.cpp) 6 | elseif(CHIRA_RENDER_BACKEND STREQUAL "SDLRENDERER") 7 | list(APPEND CHIRA_ENGINE_HEADERS 8 | ${CMAKE_CURRENT_LIST_DIR}/BackendSDL.h) 9 | list(APPEND CHIRA_ENGINE_SOURCES 10 | ${CMAKE_CURRENT_LIST_DIR}/BackendSDL.cpp) 11 | endif() 12 | -------------------------------------------------------------------------------- /engine/render/backend/device/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | if((CHIRA_RENDER_BACKEND STREQUAL "GL40") OR (CHIRA_RENDER_BACKEND STREQUAL "GL41") OR (CHIRA_RENDER_BACKEND STREQUAL "GL43")) 2 | list(APPEND CHIRA_ENGINE_HEADERS 3 | ${CMAKE_CURRENT_LIST_DIR}/DeviceGL.h) 4 | list(APPEND CHIRA_ENGINE_SOURCES 5 | ${CMAKE_CURRENT_LIST_DIR}/DeviceGL.cpp) 6 | elseif(CHIRA_RENDER_BACKEND STREQUAL "SDLRENDERER") 7 | list(APPEND CHIRA_ENGINE_HEADERS 8 | ${CMAKE_CURRENT_LIST_DIR}/DeviceSDL.h) 9 | list(APPEND CHIRA_ENGINE_SOURCES 10 | ${CMAKE_CURRENT_LIST_DIR}/DeviceSDL.cpp) 11 | endif() 12 | -------------------------------------------------------------------------------- /engine/render/material/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | list(APPEND CHIRA_ENGINE_HEADERS 2 | ${CMAKE_CURRENT_LIST_DIR}/MaterialCubemap.h 3 | ${CMAKE_CURRENT_LIST_DIR}/MaterialFactory.h 4 | ${CMAKE_CURRENT_LIST_DIR}/MaterialFrameBuffer.h 5 | ${CMAKE_CURRENT_LIST_DIR}/MaterialPhong.h 6 | ${CMAKE_CURRENT_LIST_DIR}/MaterialTextured.h 7 | ${CMAKE_CURRENT_LIST_DIR}/MaterialUntextured.h) 8 | 9 | list(APPEND CHIRA_ENGINE_SOURCES 10 | ${CMAKE_CURRENT_LIST_DIR}/MaterialCubemap.cpp 11 | ${CMAKE_CURRENT_LIST_DIR}/MaterialFactory.cpp 12 | ${CMAKE_CURRENT_LIST_DIR}/MaterialFrameBuffer.cpp 13 | ${CMAKE_CURRENT_LIST_DIR}/MaterialPhong.cpp 14 | ${CMAKE_CURRENT_LIST_DIR}/MaterialTextured.cpp 15 | ${CMAKE_CURRENT_LIST_DIR}/MaterialUntextured.cpp) 16 | -------------------------------------------------------------------------------- /engine/render/material/MaterialCubemap.cpp: -------------------------------------------------------------------------------- 1 | #include "MaterialCubemap.h" 2 | 3 | #include 4 | 5 | using namespace chira; 6 | 7 | void MaterialCubemap::compile(const byte buffer[], std::size_t bufferLength) { 8 | Serial::loadFromBuffer(this, buffer, bufferLength); 9 | 10 | this->shader = Resource::getResource(this->shaderPath); 11 | this->setTextureCubemap(this->cubemapPath); 12 | } 13 | 14 | void MaterialCubemap::use() const { 15 | IMaterial::use(); 16 | this->cubemap->use(); 17 | } 18 | 19 | SharedPointer MaterialCubemap::getTextureCubemap() const { 20 | return this->cubemap; 21 | } 22 | 23 | void MaterialCubemap::setTextureCubemap(std::string path) { 24 | this->cubemapPath = std::move(path); 25 | this->cubemap = Resource::getResource(this->cubemapPath); 26 | this->shader->use(); 27 | this->shader->setUniform("cubemap", 0); 28 | } 29 | -------------------------------------------------------------------------------- /engine/render/material/MaterialCubemap.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "MaterialUntextured.h" 5 | 6 | namespace chira { 7 | 8 | class MaterialCubemap final : public IMaterial { 9 | public: 10 | explicit MaterialCubemap(std::string identifier_) : IMaterial(std::move(identifier_)) {} 11 | void compile(const byte buffer[], std::size_t bufferLength) override; 12 | void use() const override; 13 | [[nodiscard]] SharedPointer getTextureCubemap() const; 14 | void setTextureCubemap(std::string path); 15 | 16 | protected: 17 | SharedPointer cubemap; 18 | std::string cubemapPath{"file://textures/missing.json"}; 19 | 20 | public: 21 | template 22 | void serialize(Archive& ar) { 23 | ar( 24 | cereal::make_nvp("shader", this->shaderPath), 25 | cereal::make_nvp("cubemap", this->cubemapPath) 26 | ); 27 | } 28 | 29 | private: 30 | CHIRA_REGISTER_MATERIAL_TYPE(MaterialCubemap); 31 | }; 32 | 33 | } // namespace chira 34 | -------------------------------------------------------------------------------- /engine/render/material/MaterialFactory.cpp: -------------------------------------------------------------------------------- 1 | #include "MaterialFactory.h" 2 | 3 | using namespace chira; 4 | 5 | IMaterial::IMaterial(std::string identifier_) 6 | : Resource(std::move(identifier_)) {} 7 | 8 | void IMaterial::compile(const byte buffer[], std::size_t bufferLength) { 9 | Serial::loadFromBuffer(this, buffer, bufferLength); 10 | 11 | this->shader = Resource::getResource(this->shaderPath); 12 | } 13 | 14 | void IMaterial::use() const { 15 | this->shader->use(); 16 | } 17 | 18 | SharedPointer IMaterial::getShader() const { 19 | return this->shader; 20 | } 21 | -------------------------------------------------------------------------------- /engine/render/material/MaterialFactory.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | namespace chira { 11 | 12 | class IMaterial : public Resource { 13 | public: 14 | explicit IMaterial(std::string identifier_); 15 | void compile(const byte buffer[], std::size_t bufferLength) override; 16 | virtual void use() const; 17 | [[nodiscard]] SharedPointer getShader() const; 18 | 19 | protected: 20 | SharedPointer shader; 21 | std::string shaderPath{"file://shaders/unlitTextured.json"}; 22 | 23 | public: 24 | template 25 | void serialize(Archive& ar) { 26 | ar( 27 | cereal::make_nvp("shader", this->shaderPath) 28 | ); 29 | } 30 | }; 31 | 32 | using MaterialFactory = AbstractFactory>; 33 | 34 | } // namespace chira 35 | 36 | #define CHIRA_REGISTER_MATERIAL_TYPE(ResourceClassName) \ 37 | static inline const bool ResourceClassName##FactoryRegistryHelper = \ 38 | chira::MaterialFactory::registerTypeFactory( \ 39 | #ResourceClassName, \ 40 | [](const std::string& materialId) -> chira::SharedPointer { \ 41 | return chira::Resource::getResource(materialId) \ 42 | .cast(); \ 43 | } \ 44 | ) 45 | 46 | #define CHIRA_GET_MATERIAL(type, identifier) \ 47 | chira::MaterialFactory::getTypeFactory(type)(identifier) 48 | -------------------------------------------------------------------------------- /engine/render/material/MaterialFrameBuffer.cpp: -------------------------------------------------------------------------------- 1 | #include "MaterialFrameBuffer.h" 2 | 3 | using namespace chira; 4 | 5 | void MaterialFrameBuffer::compile(const byte buffer[], std::size_t bufferLength) { 6 | IMaterial::compile(buffer, bufferLength); 7 | 8 | this->shader->use(); 9 | this->shader->setUniform("texture0", 0); 10 | } 11 | 12 | void MaterialFrameBuffer::use() const { 13 | IMaterial::use(); 14 | Renderer::useFrameBufferTexture(*this->handle, TextureUnit::G0); 15 | } 16 | -------------------------------------------------------------------------------- /engine/render/material/MaterialFrameBuffer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "MaterialFactory.h" 4 | 5 | namespace chira { 6 | 7 | class Frame; 8 | 9 | class MaterialFrameBuffer final : public IMaterial { 10 | public: 11 | MaterialFrameBuffer(std::string identifier_, Renderer::FrameBufferHandle* handle_) 12 | : IMaterial(std::move(identifier_)) 13 | , handle(handle_) {} 14 | void compile(const byte buffer[], std::size_t bufferLength) override; 15 | void use() const override; 16 | 17 | protected: 18 | Renderer::FrameBufferHandle* handle; 19 | 20 | public: 21 | template 22 | void serialize(Archive& ar) { 23 | ar( 24 | cereal::make_nvp("shader", this->shaderPath) 25 | ); 26 | } 27 | }; 28 | 29 | } // namespace chira 30 | -------------------------------------------------------------------------------- /engine/render/material/MaterialPhong.cpp: -------------------------------------------------------------------------------- 1 | #include "MaterialPhong.h" 2 | 3 | #include 4 | 5 | using namespace chira; 6 | 7 | void MaterialPhong::compile(const byte buffer[], std::size_t bufferLength) { 8 | Serial::loadFromBuffer(this, buffer, bufferLength); 9 | 10 | this->shader = Resource::getResource(this->shaderPath); 11 | this->setTextureDiffuse(this->diffusePath); 12 | this->setTextureSpecular(this->specularPath); 13 | this->setShininess(this->shininess); 14 | this->setLambertFactor(this->lambertFactor); 15 | } 16 | 17 | void MaterialPhong::use() const { 18 | IMaterial::use(); 19 | this->diffuse->use(TextureUnit::G0); 20 | this->specular->use(TextureUnit::G1); 21 | this->shader->setUniform("material.shininess", this->shininess); 22 | this->shader->setUniform("material.lambertFactor", this->lambertFactor); 23 | } 24 | 25 | SharedPointer MaterialPhong::getTextureDiffuse() const { 26 | return this->diffuse; 27 | } 28 | 29 | void MaterialPhong::setTextureDiffuse(std::string path) { 30 | this->diffusePath = std::move(path); 31 | this->diffuse = Resource::getResource(this->diffusePath); 32 | this->shader->use(); 33 | this->shader->setUniform("material.diffuse", 0); 34 | } 35 | 36 | SharedPointer MaterialPhong::getTextureSpecular() const { 37 | return this->specular; 38 | } 39 | 40 | void MaterialPhong::setTextureSpecular(std::string path) { 41 | this->specularPath = std::move(path); 42 | this->specular = Resource::getResource(this->specularPath); 43 | this->shader->use(); 44 | this->shader->setUniform("material.specular", 1); 45 | } 46 | 47 | float MaterialPhong::getShininess() const { 48 | return this->shininess; 49 | } 50 | 51 | void MaterialPhong::setShininess(float shininess_) { 52 | this->shininess = shininess_; 53 | this->shader->use(); 54 | this->shader->setUniform("material.shininess", this->shininess); 55 | } 56 | 57 | float MaterialPhong::getLambertFactor() const { 58 | return this->lambertFactor; 59 | } 60 | 61 | void MaterialPhong::setLambertFactor(float lambertFactor_) { 62 | this->lambertFactor = lambertFactor_; 63 | this->shader->use(); 64 | this->shader->setUniform("material.lambertFactor", this->lambertFactor); 65 | } 66 | -------------------------------------------------------------------------------- /engine/render/material/MaterialPhong.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "MaterialUntextured.h" 5 | 6 | namespace chira { 7 | 8 | class MaterialPhong final : public IMaterial { 9 | public: 10 | explicit MaterialPhong(std::string identifier_) : IMaterial(std::move(identifier_)) {} 11 | void compile(const byte buffer[], std::size_t bufferLength) override; 12 | void use() const override; 13 | [[nodiscard]] SharedPointer getTextureDiffuse() const; 14 | void setTextureDiffuse(std::string path); 15 | [[nodiscard]] SharedPointer getTextureSpecular() const; 16 | void setTextureSpecular(std::string path); 17 | [[nodiscard]] float getShininess() const; 18 | void setShininess(float shininess); 19 | [[nodiscard]] float getLambertFactor() const; 20 | void setLambertFactor(float lambertFactor); 21 | 22 | protected: 23 | SharedPointer diffuse; 24 | std::string diffusePath{"file://textures/missing.json"}; 25 | SharedPointer specular; 26 | std::string specularPath{"file://textures/missing.json"}; 27 | float shininess = 32.f; 28 | float lambertFactor = 1.f; 29 | 30 | public: 31 | template 32 | void serialize(Archive& ar) { 33 | ar( 34 | cereal::make_nvp("shader", this->shaderPath), 35 | cereal::make_nvp("diffuse", this->diffusePath), 36 | cereal::make_nvp("specular", this->specularPath), 37 | cereal::make_nvp("shininess", this->shininess), 38 | cereal::make_nvp("lambertFactor", this->lambertFactor) 39 | ); 40 | } 41 | 42 | private: 43 | CHIRA_REGISTER_MATERIAL_TYPE(MaterialPhong); 44 | }; 45 | 46 | } // namespace chira 47 | -------------------------------------------------------------------------------- /engine/render/material/MaterialTextured.cpp: -------------------------------------------------------------------------------- 1 | #include "MaterialTextured.h" 2 | 3 | using namespace chira; 4 | 5 | void MaterialTextured::compile(const byte buffer[], std::size_t bufferLength) { 6 | Serial::loadFromBuffer(this, buffer, bufferLength); 7 | 8 | this->shader = Resource::getResource(this->shaderPath); 9 | this->setTexture(this->texturePath); 10 | } 11 | 12 | void MaterialTextured::use() const { 13 | IMaterial::use(); 14 | this->texture->use(); 15 | } 16 | 17 | SharedPointer MaterialTextured::getTexture() const { 18 | return this->texture; 19 | } 20 | 21 | void MaterialTextured::setTexture(std::string path) { 22 | this->texturePath = std::move(path); 23 | this->texture = Resource::getResource(this->texturePath); 24 | this->shader->use(); 25 | this->shader->setUniform("texture0", 0); 26 | } 27 | -------------------------------------------------------------------------------- /engine/render/material/MaterialTextured.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "MaterialUntextured.h" 5 | 6 | namespace chira { 7 | 8 | class MaterialTextured final : public IMaterial { 9 | public: 10 | explicit MaterialTextured(std::string identifier_) : IMaterial(std::move(identifier_)) {} 11 | void compile(const byte buffer[], std::size_t bufferLength) override; 12 | void use() const override; 13 | [[nodiscard]] SharedPointer getTexture() const; 14 | void setTexture(std::string path); 15 | 16 | protected: 17 | SharedPointer texture; 18 | std::string texturePath{"file://textures/missing.json"}; 19 | 20 | public: 21 | template 22 | void serialize(Archive& ar) { 23 | ar( 24 | cereal::make_nvp("shader", this->shaderPath), 25 | cereal::make_nvp("texture", this->texturePath) 26 | ); 27 | } 28 | 29 | private: 30 | CHIRA_REGISTER_MATERIAL_TYPE(MaterialTextured); 31 | }; 32 | 33 | } // namespace chira 34 | -------------------------------------------------------------------------------- /engine/render/material/MaterialUntextured.cpp: -------------------------------------------------------------------------------- 1 | #include "MaterialUntextured.h" 2 | 3 | using namespace chira; 4 | 5 | void MaterialUntextured::compile(const byte buffer[], std::size_t bufferLength) { 6 | Serial::loadFromBuffer(this, buffer, bufferLength); 7 | 8 | this->shader = Resource::getResource(this->shaderPath); 9 | } 10 | -------------------------------------------------------------------------------- /engine/render/material/MaterialUntextured.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "MaterialFactory.h" 4 | 5 | namespace chira { 6 | 7 | class MaterialUntextured final : public IMaterial { 8 | public: 9 | explicit MaterialUntextured(std::string identifier_) : IMaterial(std::move(identifier_)) {} 10 | void compile(const byte buffer[], std::size_t bufferLength) override; 11 | 12 | public: 13 | template 14 | void serialize(Archive& ar) { 15 | ar( 16 | cereal::make_nvp("shader", this->shaderPath) 17 | ); 18 | } 19 | 20 | private: 21 | CHIRA_REGISTER_MATERIAL_TYPE(MaterialUntextured); 22 | }; 23 | 24 | } // namespace chira 25 | -------------------------------------------------------------------------------- /engine/render/mesh/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | list(APPEND CHIRA_ENGINE_HEADERS 2 | ${CMAKE_CURRENT_LIST_DIR}/MeshData.h 3 | ${CMAKE_CURRENT_LIST_DIR}/MeshDataBuilder.h 4 | ${CMAKE_CURRENT_LIST_DIR}/MeshDataResource.h) 5 | 6 | list(APPEND CHIRA_ENGINE_SOURCES 7 | ${CMAKE_CURRENT_LIST_DIR}/MeshData.cpp 8 | ${CMAKE_CURRENT_LIST_DIR}/MeshDataBuilder.cpp 9 | ${CMAKE_CURRENT_LIST_DIR}/MeshDataResource.cpp) 10 | -------------------------------------------------------------------------------- /engine/render/mesh/MeshData.cpp: -------------------------------------------------------------------------------- 1 | #include "MeshData.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | using namespace chira; 9 | 10 | void MeshData::setupForRendering() { 11 | this->handle = Renderer::createMesh(this->vertices, this->indices, MeshDrawMode::STATIC); 12 | this->initialized = true; 13 | } 14 | 15 | void MeshData::updateMeshData() { 16 | if (!this->initialized) 17 | return; 18 | Renderer::updateMesh(&this->handle, this->vertices, this->indices, this->drawMode); 19 | } 20 | 21 | void MeshData::render(glm::mat4 model, MeshCullType cullType /*= MeshCullType::BACK*/) { 22 | if (!this->initialized) 23 | this->setupForRendering(); 24 | if (this->material) { 25 | this->material->use(); 26 | if (this->material->getShader()->usesModelMatrix()) 27 | this->material->getShader()->setUniform("m", model); 28 | } 29 | Renderer::drawMesh(this->handle, this->depthFunction, cullType); 30 | } 31 | 32 | MeshData::~MeshData() { 33 | if (this->initialized) { 34 | Renderer::destroyMesh(this->handle); 35 | } 36 | } 37 | 38 | SharedPointer MeshData::getMaterial() const { 39 | return this->material; 40 | } 41 | 42 | void MeshData::setMaterial(SharedPointer newMaterial) { 43 | this->material = std::move(newMaterial); 44 | } 45 | 46 | MeshDepthFunction MeshData::getDepthFunction() const { 47 | return this->depthFunction; 48 | } 49 | 50 | void MeshData::setDepthFunction(MeshDepthFunction function) { 51 | this->depthFunction = function; 52 | } 53 | 54 | std::vector MeshData::getMeshData(const std::string& meshLoader) const { 55 | return IMeshLoader::getMeshLoader(meshLoader)->createMesh(this->vertices, this->indices); 56 | } 57 | 58 | void MeshData::appendMeshData(const std::string& loader, const std::string& identifier) { 59 | IMeshLoader::getMeshLoader(loader)->loadMesh(identifier, this->vertices, this->indices); 60 | } 61 | 62 | void MeshData::clearMeshData() { 63 | this->vertices.clear(); 64 | this->indices.clear(); 65 | } 66 | -------------------------------------------------------------------------------- /engine/render/mesh/MeshData.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | namespace chira { 10 | 11 | class MeshData { 12 | public: 13 | MeshData() = default; 14 | void render(glm::mat4 model, MeshCullType cullType = MeshCullType::BACK); 15 | virtual ~MeshData(); 16 | [[nodiscard]] SharedPointer getMaterial() const; 17 | void setMaterial(SharedPointer newMaterial); 18 | [[nodiscard]] MeshDepthFunction getDepthFunction() const; 19 | void setDepthFunction(MeshDepthFunction function); 20 | [[nodiscard]] std::vector getMeshData(const std::string& meshLoader) const; 21 | void appendMeshData(const std::string& loader, const std::string& identifier); 22 | protected: 23 | bool initialized = false; 24 | Renderer::MeshHandle handle{}; 25 | MeshDrawMode drawMode = MeshDrawMode::STATIC; 26 | MeshDepthFunction depthFunction = MeshDepthFunction::LEQUAL; 27 | SharedPointer material; 28 | std::vector vertices; 29 | std::vector indices; 30 | /// Establishes the vertex buffers and copies the current mesh data into them. 31 | void setupForRendering(); 32 | /// Updates the vertex buffers with the current mesh data. 33 | void updateMeshData(); 34 | /// Does not call updateMeshData(). 35 | void clearMeshData(); 36 | }; 37 | 38 | } // namespace chira 39 | -------------------------------------------------------------------------------- /engine/render/mesh/MeshDataBuilder.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | namespace chira { 7 | 8 | class MeshDataBuilder : public MeshData { 9 | public: 10 | MeshDataBuilder(); 11 | 12 | void addTriangle(Vertex v1, Vertex v2, Vertex v3, bool addDuplicate = false); 13 | /// Vertex v4 forms a face with vertex v1 and v3. 14 | void addSquare(Vertex v1, Vertex v2, Vertex v3, Vertex v4, bool addDuplicate = false); 15 | void addSquare(Vertex center, glm::vec2 size, SignedAxis normal, float offset = 0, bool addDuplicate = false); 16 | void addCube(Vertex center, glm::vec3 size, bool visibleOutside = true, bool addDuplicate = false); 17 | void update(); 18 | /// Does not call update(). 19 | void clear(); 20 | 21 | protected: 22 | Index currentIndex = 0; 23 | /// Pass true to addDuplicate if you don't want to scan the entire vertex vector to calculate the index. 24 | /// This will make a duplicate vertex if one already exists. 25 | void addVertex(Vertex vertex, bool addDuplicate = false); 26 | }; 27 | 28 | } // namespace chira 29 | -------------------------------------------------------------------------------- /engine/render/mesh/MeshDataResource.cpp: -------------------------------------------------------------------------------- 1 | #include "MeshDataResource.h" 2 | 3 | #include 4 | #include 5 | 6 | #include 7 | 8 | using namespace chira; 9 | 10 | CHIRA_CREATE_LOG(MESHDATARESOURCE); 11 | 12 | void MeshDataResource::compile(const byte buffer[], std::size_t bufferLength) { 13 | Serial::loadFromBuffer(this, buffer, bufferLength); 14 | 15 | if (!this->materialSetInCode) { 16 | this->material = CHIRA_GET_MATERIAL(this->materialType, this->materialPath); 17 | } 18 | this->appendMeshData(this->modelLoader, this->modelPath); 19 | this->setupForRendering(); 20 | } 21 | -------------------------------------------------------------------------------- /engine/render/mesh/MeshDataResource.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | namespace chira { 9 | 10 | class MeshDataResource : public Resource, public MeshData { 11 | public: 12 | explicit MeshDataResource(std::string identifier_) : Resource(std::move(identifier_)), MeshData() {} 13 | void compile(const byte buffer[], std::size_t bufferLength) override; 14 | 15 | private: 16 | bool materialSetInCode = false; 17 | std::string materialType{"MaterialTextured"}; 18 | std::string materialPath{"file://materials/unlitTextured.json"}; 19 | std::string modelPath{"file://meshes/missing.cmdl"}; 20 | std::string modelLoader{"cmdl"}; 21 | 22 | public: 23 | template 24 | void serialize(Archive& ar) { 25 | ar( 26 | cereal::make_nvp("materialSetInCode", this->materialSetInCode), 27 | cereal::make_nvp("materialType", this->materialType), 28 | cereal::make_nvp("material", this->materialPath), 29 | cereal::make_nvp("model", this->modelPath), 30 | cereal::make_nvp("modelLoader", this->modelLoader), 31 | cereal::make_nvp("depthFunction", this->depthFunction) 32 | ); 33 | } 34 | 35 | private: 36 | CHIRA_REGISTER_DEFAULT_RESOURCE(MeshDataResource, "file://meshes/missing.json"); 37 | }; 38 | 39 | } // namespace chira 40 | -------------------------------------------------------------------------------- /engine/render/shader/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | list(APPEND CHIRA_ENGINE_HEADERS 2 | ${CMAKE_CURRENT_LIST_DIR}/Shader.h 3 | ${CMAKE_CURRENT_LIST_DIR}/UBO.h) 4 | 5 | list(APPEND CHIRA_ENGINE_SOURCES 6 | ${CMAKE_CURRENT_LIST_DIR}/Shader.cpp 7 | ${CMAKE_CURRENT_LIST_DIR}/UBO.cpp) 8 | -------------------------------------------------------------------------------- /engine/render/shader/UBO.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | namespace chira { 10 | 11 | template 12 | class UniformBufferObject { 13 | protected: 14 | explicit UniformBufferObject(std::string name_) 15 | : name(std::move(name_)) 16 | , handle(Renderer::createUniformBuffer(Size)) {} 17 | public: 18 | virtual ~UniformBufferObject() { 19 | Renderer::destroyUniformBuffer(this->handle); 20 | } 21 | inline void bindToShader(Renderer::ShaderHandle shaderHandle) { 22 | Renderer::bindUniformBufferToShader(shaderHandle, this->handle, this->name); 23 | } 24 | protected: 25 | std::string name; 26 | Renderer::UniformBufferHandle handle; 27 | 28 | static constexpr std::ptrdiff_t size = Size; 29 | }; 30 | 31 | /// Stores two mat4 values, named PV 32 | struct PerspectiveViewUBO final : public UniformBufferObject<(3 * glm::MAT4_SIZE) + (2 * glm::VEC4F_SIZE)> { 33 | static PerspectiveViewUBO& get(); 34 | void update(glm::mat4 proj, glm::mat4 view, glm::vec3 viewPos, glm::vec3 viewLookDir) const; 35 | private: 36 | PerspectiveViewUBO(); 37 | }; 38 | 39 | /// Stores lights 40 | struct LightsUBO final : public UniformBufferObject<((4 * glm::VEC4F_SIZE) * DIRECTIONAL_LIGHT_MAX) + 41 | ((5 * glm::VEC4F_SIZE) * POINT_LIGHT_MAX) + 42 | ((6 * glm::VEC4F_SIZE) * SPOT_LIGHT_MAX) + 43 | glm::VEC4F_SIZE> { 44 | static LightsUBO& get(); 45 | void update(DirectionalLightComponent* directionalLights[], PointLightComponent* pointLights[], SpotLightComponent* spotLights[], glm::vec3i numberOfLights) const; 46 | private: 47 | LightsUBO(); 48 | }; 49 | 50 | } // namespace chira 51 | -------------------------------------------------------------------------------- /engine/render/texture/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | list(APPEND CHIRA_ENGINE_HEADERS 2 | ${CMAKE_CURRENT_LIST_DIR}/ITexture.h 3 | ${CMAKE_CURRENT_LIST_DIR}/Texture.h 4 | ${CMAKE_CURRENT_LIST_DIR}/TextureCubemap.h) 5 | 6 | list(APPEND CHIRA_ENGINE_SOURCES 7 | ${CMAKE_CURRENT_LIST_DIR}/Texture.cpp 8 | ${CMAKE_CURRENT_LIST_DIR}/TextureCubemap.cpp) 9 | -------------------------------------------------------------------------------- /engine/render/texture/ITexture.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | namespace chira { 10 | 11 | class ITexture : public Resource { 12 | public: 13 | explicit ITexture(std::string identifier_) 14 | : Resource(std::move(identifier_)) {} 15 | 16 | virtual void use() const = 0; 17 | virtual void use(TextureUnit activeTextureUnit) const = 0; 18 | 19 | protected: 20 | Renderer::TextureHandle handle{}; 21 | }; 22 | 23 | } // namespace chira 24 | -------------------------------------------------------------------------------- /engine/render/texture/Texture.cpp: -------------------------------------------------------------------------------- 1 | #include "Texture.h" 2 | 3 | #include 4 | #include 5 | 6 | using namespace chira; 7 | 8 | CHIRA_CREATE_LOG(TEXTURE); 9 | 10 | Texture::Texture(std::string identifier_, bool cacheTexture /*= true*/) 11 | : ITexture(std::move(identifier_)) 12 | , cache(cacheTexture) {} 13 | 14 | Texture::~Texture() { 15 | if (this->handle) 16 | Renderer::destroyTexture(this->handle); 17 | } 18 | 19 | void Texture::compile(const byte buffer[], std::size_t bufferLength) { 20 | Serial::loadFromBuffer(this, buffer, bufferLength); 21 | 22 | auto imageFile = Resource::getResource(this->filePath, this->verticalFlip); 23 | 24 | this->handle = Renderer::createTexture2D(*imageFile, this->wrapModeS, this->wrapModeT, this->filterMode, 25 | this->mipmaps, TextureUnit::G0); 26 | if (this->cache) { 27 | this->file = imageFile; 28 | } 29 | } 30 | 31 | void Texture::use() const { 32 | Renderer::useTexture(this->handle, TextureUnit::G0); 33 | } 34 | 35 | void Texture::use(TextureUnit activeTextureUnit) const { 36 | Renderer::useTexture(this->handle, activeTextureUnit); 37 | } 38 | -------------------------------------------------------------------------------- /engine/render/texture/Texture.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include "ITexture.h" 6 | 7 | namespace chira { 8 | 9 | class Texture final : public ITexture { 10 | public: 11 | explicit Texture(std::string identifier_, bool cacheTexture = true); 12 | ~Texture() override; 13 | void compile(const byte buffer[], std::size_t bufferLength) override; 14 | void use() const override; 15 | void use(TextureUnit activeTextureUnit) const override; 16 | 17 | protected: 18 | SharedPointer file; 19 | std::string filePath{"file://textures/missing.png"}; 20 | WrapMode wrapModeS = WrapMode::REPEAT; 21 | WrapMode wrapModeT = WrapMode::REPEAT; 22 | FilterMode filterMode = FilterMode::LINEAR; 23 | bool mipmaps = true; 24 | bool verticalFlip = true; 25 | bool cache; 26 | 27 | public: 28 | template 29 | void serialize(Archive& ar) { 30 | ar( 31 | cereal::make_nvp("verticalFlip", this->verticalFlip), 32 | cereal::make_nvp("mipmaps", this->mipmaps), 33 | cereal::make_nvp("image", this->filePath), 34 | cereal::make_nvp("wrapModeS", this->wrapModeS), 35 | cereal::make_nvp("wrapModeT", this->wrapModeT), 36 | cereal::make_nvp("filterMode", this->filterMode) 37 | ); 38 | } 39 | }; 40 | 41 | } // namespace chira 42 | -------------------------------------------------------------------------------- /engine/render/texture/TextureCubemap.cpp: -------------------------------------------------------------------------------- 1 | #include "TextureCubemap.h" 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace chira; 8 | 9 | CHIRA_CREATE_LOG(TEXTURECUBEMAP); 10 | 11 | TextureCubemap::TextureCubemap(std::string identifier_) 12 | : ITexture(std::move(identifier_)) {} 13 | 14 | TextureCubemap::~TextureCubemap() { 15 | if (this->handle) 16 | Renderer::destroyTexture(this->handle); 17 | } 18 | 19 | void TextureCubemap::compile(const byte buffer[], std::size_t bufferLength) { 20 | Serial::loadFromBuffer(this, buffer, bufferLength); 21 | 22 | auto fileFD = Resource::getResource(this->imageFD, this->verticalFlipFD); 23 | auto fileBK = Resource::getResource(this->imageBK, this->verticalFlipBK); 24 | auto fileUP = Resource::getResource(this->imageUP, this->verticalFlipUP); 25 | auto fileDN = Resource::getResource(this->imageDN, this->verticalFlipDN); 26 | auto fileLT = Resource::getResource(this->imageLT, this->verticalFlipLT); 27 | auto fileRT = Resource::getResource(this->imageRT, this->verticalFlipRT); 28 | 29 | this->handle = Renderer::createTextureCubemap(*fileRT, *fileLT, *fileUP, *fileDN, *fileFD, *fileBK, 30 | this->wrapModeS, this->wrapModeT, this->wrapModeR, this->filterMode, 31 | this->mipmaps, TextureUnit::G0); 32 | } 33 | 34 | void TextureCubemap::use() const { 35 | Renderer::useTexture(this->handle, TextureUnit::G0); 36 | } 37 | 38 | void TextureCubemap::use(TextureUnit activeTextureUnit) const { 39 | Renderer::useTexture(this->handle, activeTextureUnit); 40 | } 41 | -------------------------------------------------------------------------------- /engine/render/texture/TextureCubemap.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include "ITexture.h" 6 | 7 | namespace chira { 8 | 9 | class TextureCubemap final : public ITexture { 10 | public: 11 | explicit TextureCubemap(std::string identifier_); 12 | ~TextureCubemap() override; 13 | void compile(const byte buffer[], std::size_t bufferLength) override; 14 | void use() const override; 15 | void use(TextureUnit activeTextureUnit) const override; 16 | 17 | protected: 18 | std::string imageFD{"file://textures/missing.png"}; 19 | std::string imageBK{"file://textures/missing.png"}; 20 | std::string imageUP{"file://textures/missing.png"}; 21 | std::string imageDN{"file://textures/missing.png"}; 22 | std::string imageLT{"file://textures/missing.png"}; 23 | std::string imageRT{"file://textures/missing.png"}; 24 | bool verticalFlipFD = false; 25 | bool verticalFlipBK = false; 26 | bool verticalFlipUP = false; 27 | bool verticalFlipDN = false; 28 | bool verticalFlipLT = false; 29 | bool verticalFlipRT = false; 30 | bool mipmaps = true; 31 | FilterMode filterMode = FilterMode::LINEAR; 32 | WrapMode wrapModeS = WrapMode::REPEAT; 33 | WrapMode wrapModeT = WrapMode::REPEAT; 34 | WrapMode wrapModeR = WrapMode::REPEAT; 35 | 36 | public: 37 | template 38 | void serialize(Archive& ar) { 39 | ar( 40 | cereal::make_nvp("verticalFlipFD", this->verticalFlipFD), 41 | cereal::make_nvp("verticalFlipBK", this->verticalFlipBK), 42 | cereal::make_nvp("verticalFlipUP", this->verticalFlipUP), 43 | cereal::make_nvp("verticalFlipDN", this->verticalFlipDN), 44 | cereal::make_nvp("verticalFlipLT", this->verticalFlipLT), 45 | cereal::make_nvp("verticalFlipRT", this->verticalFlipRT), 46 | cereal::make_nvp("mipmaps", this->mipmaps), 47 | cereal::make_nvp("imageFD", this->imageFD), 48 | cereal::make_nvp("imageBK", this->imageBK), 49 | cereal::make_nvp("imageUP", this->imageUP), 50 | cereal::make_nvp("imageDN", this->imageDN), 51 | cereal::make_nvp("imageLT", this->imageLT), 52 | cereal::make_nvp("imageRT", this->imageRT), 53 | cereal::make_nvp("wrapModeS", this->wrapModeS), 54 | cereal::make_nvp("wrapModeT", this->wrapModeT), 55 | cereal::make_nvp("wrapModeR", this->wrapModeR), 56 | cereal::make_nvp("filterMode", this->filterMode) 57 | ); 58 | } 59 | }; 60 | 61 | } // namespace chira 62 | -------------------------------------------------------------------------------- /engine/resource/BinaryResource.cpp: -------------------------------------------------------------------------------- 1 | #include "BinaryResource.h" 2 | 3 | #include 4 | 5 | using namespace chira; 6 | 7 | void BinaryResource::compile(const byte buffer[], std::size_t bufferLength) { 8 | this->bufferLength_ = bufferLength - 1; 9 | this->buffer_ = new byte[this->bufferLength_]; 10 | std::memcpy(this->buffer_, buffer, this->bufferLength_); 11 | } 12 | 13 | BinaryResource::~BinaryResource() { 14 | delete[] this->buffer_; 15 | } 16 | 17 | const byte* BinaryResource::getBuffer() const { 18 | return this->buffer_; 19 | } 20 | 21 | std::size_t BinaryResource::getBufferLength() const { 22 | return this->bufferLength_; 23 | } 24 | -------------------------------------------------------------------------------- /engine/resource/BinaryResource.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Resource.h" 4 | 5 | namespace chira { 6 | 7 | class BinaryResource : public Resource { 8 | public: 9 | explicit BinaryResource(std::string identifier_) : Resource(std::move(identifier_)) {} 10 | void compile(const byte buffer[], std::size_t bufferLength) override; 11 | ~BinaryResource() override; 12 | [[nodiscard]] const byte* getBuffer() const; 13 | [[nodiscard]] std::size_t getBufferLength() const; 14 | protected: 15 | byte* buffer_ = nullptr; 16 | std::size_t bufferLength_ = 0; 17 | }; 18 | 19 | } // namespace chira 20 | -------------------------------------------------------------------------------- /engine/resource/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | include(${CMAKE_CURRENT_LIST_DIR}/provider/CMakeLists.txt) 2 | 3 | list(APPEND CHIRA_ENGINE_HEADERS 4 | ${CMAKE_CURRENT_LIST_DIR}/BinaryResource.h 5 | ${CMAKE_CURRENT_LIST_DIR}/JSONResource.h 6 | ${CMAKE_CURRENT_LIST_DIR}/Resource.h 7 | ${CMAKE_CURRENT_LIST_DIR}/StringResource.h) 8 | 9 | list(APPEND CHIRA_ENGINE_SOURCES 10 | ${CMAKE_CURRENT_LIST_DIR}/BinaryResource.cpp 11 | ${CMAKE_CURRENT_LIST_DIR}/JSONResource.cpp 12 | ${CMAKE_CURRENT_LIST_DIR}/Resource.cpp 13 | ${CMAKE_CURRENT_LIST_DIR}/StringResource.cpp) 14 | -------------------------------------------------------------------------------- /engine/resource/JSONResource.cpp: -------------------------------------------------------------------------------- 1 | #include "JSONResource.h" 2 | 3 | #include 4 | #include 5 | 6 | using namespace chira; 7 | 8 | CHIRA_CREATE_LOG(JSONRESOURCE); 9 | 10 | void JSONResource::compile(const byte buffer[], std::size_t bufferLength) { 11 | nlohmann::json props; 12 | try { 13 | props = nlohmann::json::parse(std::string{reinterpret_cast(buffer), bufferLength}); 14 | } catch (const nlohmann::json::exception&) { 15 | LOG_JSONRESOURCE.error(TRF("error.properties_resource.invalid_json", this->identifier)); 16 | } 17 | this->compile(props); 18 | } 19 | -------------------------------------------------------------------------------- /engine/resource/JSONResource.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Resource.h" 4 | 5 | namespace chira { 6 | 7 | class JSONResource : public Resource { 8 | public: 9 | explicit JSONResource(std::string identifier_) : Resource(std::move(identifier_)) {} 10 | void compile(const byte buffer[], std::size_t bufferLength) final; 11 | virtual void compile(const nlohmann::json& properties) = 0; 12 | 13 | template 14 | [[nodiscard]] static inline T getProperty(const nlohmann::json& properties, const std::string& key, T defaultValue) { 15 | if (properties.contains(key)) { 16 | return properties.at(key); 17 | } 18 | return defaultValue; 19 | } 20 | }; 21 | 22 | } // namespace chira 23 | -------------------------------------------------------------------------------- /engine/resource/StringResource.cpp: -------------------------------------------------------------------------------- 1 | #include "StringResource.h" 2 | 3 | #include 4 | 5 | using namespace chira; 6 | 7 | void StringResource::compile(const byte buffer[], std::size_t bufferLength) { 8 | this->data = {reinterpret_cast(buffer), bufferLength}; 9 | String::replace(this->data, "\r\n", "\n"); 10 | } 11 | 12 | const std::string& StringResource::getString() const { 13 | return this->data; 14 | } 15 | -------------------------------------------------------------------------------- /engine/resource/StringResource.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Resource.h" 4 | 5 | namespace chira { 6 | 7 | class StringResource : public Resource { 8 | public: 9 | explicit StringResource(std::string identifier_) : Resource(std::move(identifier_)) {} 10 | void compile(const byte buffer[], std::size_t bufferLength) override; 11 | [[nodiscard]] const std::string& getString() const; 12 | protected: 13 | std::string data; 14 | }; 15 | 16 | } // namespace chira 17 | -------------------------------------------------------------------------------- /engine/resource/provider/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | list(APPEND CHIRA_ENGINE_HEADERS 2 | ${CMAKE_CURRENT_LIST_DIR}/FilesystemResourceProvider.h 3 | ${CMAKE_CURRENT_LIST_DIR}/IResourceProvider.h) 4 | 5 | list(APPEND CHIRA_ENGINE_SOURCES 6 | ${CMAKE_CURRENT_LIST_DIR}/FilesystemResourceProvider.cpp) 7 | -------------------------------------------------------------------------------- /engine/resource/provider/FilesystemResourceProvider.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "IResourceProvider.h" 5 | 6 | namespace chira { 7 | 8 | const std::string FILESYSTEM_ROOT_FOLDER = "resources"; 9 | const std::string FILESYSTEM_PROVIDER_NAME = "file"; 10 | 11 | class FilesystemResourceProvider : public IResourceProvider { 12 | public: 13 | explicit FilesystemResourceProvider(std::string path_, bool isPathAbsolute = false, const std::string& name_ = FILESYSTEM_PROVIDER_NAME); 14 | [[nodiscard]] bool hasResource(std::string_view name) const override; 15 | void compileResource(std::string_view name, Resource* resource) const override; 16 | [[nodiscard]] std::string_view getPath() const { 17 | return this->path; 18 | } 19 | [[nodiscard]] bool isAbsolute() const { 20 | return this->absolute; 21 | } 22 | [[nodiscard]] std::string getFolder() const; 23 | [[nodiscard]] std::string getLocalResourceAbsolutePath(const std::string& identifier) const; 24 | 25 | /// Converts all backslashes in a string to forward slashes. 26 | static void nixifyPath(std::string& path); 27 | /// Takes an absolute path of a resource file and converts it to a resource identifier. 28 | /// Does not check if the resource identifier actually points to a valid resource. 29 | static std::string getResourceIdentifier(std::string_view absolutePath); 30 | /// Takes an absolute path of a resource folder and converts it to a valid input path 31 | /// for a FilesystemResourceProvider. Does not check if the resource identifier 32 | /// actually points to a valid resource. 33 | static std::string getResourceFolderPath(std::string_view absolutePath); 34 | /// Takes a resource identifier and returns the full absolute path, if it exists. 35 | static std::string getResourceAbsolutePath(const std::string& identifier); 36 | 37 | static constexpr inline short FILEPATH_MAX_LENGTH = 1024; 38 | private: 39 | std::string path; 40 | bool absolute; 41 | }; 42 | 43 | } // namespace chira 44 | -------------------------------------------------------------------------------- /engine/resource/provider/IResourceProvider.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | namespace chira { 7 | 8 | class Resource; 9 | 10 | class IResourceProvider { 11 | public: 12 | explicit IResourceProvider(std::string name) : providerName(std::move(name)) {} 13 | virtual ~IResourceProvider() = default; 14 | [[nodiscard]] std::string_view getName() const { 15 | return this->providerName; 16 | } 17 | [[nodiscard]] virtual bool hasResource(std::string_view name) const = 0; 18 | virtual void compileResource(std::string_view name, Resource* resource) const = 0; 19 | protected: 20 | std::string providerName; 21 | }; 22 | 23 | } // namespace chira 24 | -------------------------------------------------------------------------------- /engine/script/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | list(APPEND CHIRA_ENGINE_HEADERS 2 | ${CMAKE_CURRENT_LIST_DIR}/Lua.h) 3 | 4 | list(APPEND CHIRA_ENGINE_SOURCES 5 | ${CMAKE_CURRENT_LIST_DIR}/Lua.cpp) 6 | -------------------------------------------------------------------------------- /engine/script/Lua.cpp: -------------------------------------------------------------------------------- 1 | #include "Lua.h" 2 | 3 | #include 4 | 5 | #include 6 | #define SOL_ALL_SAFETIES_ON 1 7 | #include 8 | 9 | #include 10 | 11 | using namespace chira; 12 | 13 | CHIRA_CREATE_LOG(LUA); 14 | 15 | // todo(scripting): pull this into a DLL and register it into a list of providers 16 | 17 | static sol::state& luaState() { 18 | static sol::state state; 19 | return state; 20 | } 21 | 22 | static std::string toString(const sol::object& obj) { 23 | return luaState()["tostring"](obj).get(); 24 | } 25 | 26 | void Lua::init() { 27 | auto& lua = luaState(); 28 | 29 | lua.open_libraries(sol::lib::base, sol::lib::string, sol::lib::bit32, sol::lib::math, sol::lib::table, sol::lib::utf8); 30 | 31 | lua.set_function("print", [](const sol::object& message) { 32 | LOG_LUA.output(::toString(message)); 33 | }); 34 | 35 | lua.set_function("printf", [](std::string_view fmtStr, sol::variadic_args va) { 36 | fmt::dynamic_format_arg_store ds; 37 | for (auto v : va) { 38 | ds.push_back(::toString(v)); 39 | } 40 | LOG_LUA.output(fmt::vformat(fmtStr, ds)); 41 | }); 42 | 43 | lua.set_function("fmt", [](std::string_view fmtStr, sol::variadic_args va) { 44 | fmt::dynamic_format_arg_store ds; 45 | for (auto v : va) { 46 | ds.push_back(::toString(v)); 47 | } 48 | return fmt::vformat(fmtStr, ds); 49 | }); 50 | } 51 | 52 | void Lua::script(std::string_view code) { 53 | luaState().script(code, [](lua_State*, sol::protected_function_result result) { 54 | if (!result.valid()) { 55 | sol::error err = result; 56 | LOG_LUA.error("Failed to run given code: {}", err.what()); 57 | } 58 | return result; 59 | }); 60 | } 61 | -------------------------------------------------------------------------------- /engine/script/Lua.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace chira::Lua { 6 | 7 | void init(); 8 | void script(std::string_view code); 9 | 10 | } // namespace chira::Lua 11 | -------------------------------------------------------------------------------- /engine/thirdparty/glad/40/include/glad/glversion.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | constexpr const int GL_VERSION_MAJOR = 4; 6 | constexpr const int GL_VERSION_MINOR = 0; 7 | constexpr std::string_view GL_VERSION_STRING = "#version 400 core"; 8 | constexpr std::string_view GL_VERSION_STRING_PRETTY = "OpenGL 4.0 Core"; 9 | -------------------------------------------------------------------------------- /engine/thirdparty/glad/41/include/glad/glversion.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | constexpr const int GL_VERSION_MAJOR = 4; 6 | constexpr const int GL_VERSION_MINOR = 1; 7 | constexpr std::string_view GL_VERSION_STRING = "#version 410 core"; 8 | constexpr std::string_view GL_VERSION_STRING_PRETTY = "OpenGL 4.1 Core"; 9 | -------------------------------------------------------------------------------- /engine/thirdparty/glad/43/include/glad/glversion.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | constexpr const int GL_VERSION_MAJOR = 4; 6 | constexpr const int GL_VERSION_MINOR = 3; 7 | constexpr std::string_view GL_VERSION_STRING = "#version 430 core"; 8 | constexpr std::string_view GL_VERSION_STRING_PRETTY = "OpenGL 4.3 Core"; 9 | -------------------------------------------------------------------------------- /engine/thirdparty/glad/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.16) 2 | project(glad) 3 | set(CMAKE_CXX_STANDARD 20) 4 | 5 | find_package(OpenGL REQUIRED) 6 | 7 | if(NOT DEFINED GLAD_GL_VERSION) 8 | message(FATAL_ERROR "Must set GLAD_GL_VERSION variable to 40, 41, or 43!") 9 | endif() 10 | 11 | add_library(${PROJECT_NAME} STATIC 12 | ${CMAKE_CURRENT_SOURCE_DIR}/${GLAD_GL_VERSION}/include/glad/glversion.h 13 | ${CMAKE_CURRENT_SOURCE_DIR}/${GLAD_GL_VERSION}/include/glad/gl.h 14 | ${CMAKE_CURRENT_SOURCE_DIR}/${GLAD_GL_VERSION}/src/gl.c 15 | ${CMAKE_CURRENT_SOURCE_DIR}/${GLAD_GL_VERSION}/include/KHR/khrplatform.h) 16 | target_link_libraries(${PROJECT_NAME} PUBLIC ${OPENGL_LIBRARIES}) 17 | target_include_directories(${PROJECT_NAME} PUBLIC 18 | ${OPENGL_INCLUDE_DIRS} 19 | ${CMAKE_CURRENT_SOURCE_DIR}/${GLAD_GL_VERSION}/include) 20 | -------------------------------------------------------------------------------- /engine/thirdparty/stb/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # https://github.com/nothings/stb 2 | cmake_minimum_required(VERSION 3.15) 3 | project(stb) 4 | set(CMAKE_CXX_STANDARD 17) 5 | include(GNUInstallDirs) 6 | 7 | add_library(${PROJECT_NAME} INTERFACE) 8 | target_sources(${PROJECT_NAME} INTERFACE "$") 9 | target_include_directories(${PROJECT_NAME} SYSTEM INTERFACE $/include>) 10 | -------------------------------------------------------------------------------- /engine/ui/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | include(${CMAKE_CURRENT_LIST_DIR}/debug/CMakeLists.txt) 2 | 3 | list(APPEND CHIRA_ENGINE_HEADERS 4 | ${CMAKE_CURRENT_LIST_DIR}/Font.h 5 | ${CMAKE_CURRENT_LIST_DIR}/IPanel.h 6 | ${CMAKE_CURRENT_LIST_DIR}/IViewportPanel.h) 7 | 8 | list(APPEND CHIRA_ENGINE_SOURCES 9 | ${CMAKE_CURRENT_LIST_DIR}/Font.cpp 10 | ${CMAKE_CURRENT_LIST_DIR}/IPanel.cpp 11 | ${CMAKE_CURRENT_LIST_DIR}/IViewportPanel.cpp) 12 | -------------------------------------------------------------------------------- /engine/ui/Font.cpp: -------------------------------------------------------------------------------- 1 | #include "Font.h" 2 | 3 | #include 4 | 5 | using namespace chira; 6 | 7 | void Font::compile(const byte buffer[], std::size_t bufferLength) { 8 | Serial::loadFromBuffer(this, buffer, bufferLength); 9 | 10 | ImGuiIO& io = ImGui::GetIO(); 11 | this->range = Font::getRangeFromString(this->rangeStr); 12 | std::string path = FilesystemResourceProvider::getResourceAbsolutePath(this->fontPath); 13 | this->font = io.Fonts->AddFontFromFileTTF(path.c_str(), this->size, nullptr, this->range); 14 | } 15 | 16 | ImFont* Font::getFont() const { 17 | return this->font; 18 | } 19 | 20 | const std::string& Font::getName() const { 21 | return this->name; 22 | } 23 | 24 | float Font::getSize() const { 25 | return this->size; 26 | } 27 | 28 | const ImWchar* Font::getRangeFromString(std::string_view input) { 29 | ImGuiIO &io = ImGui::GetIO(); 30 | if (input == "chinese") 31 | return io.Fonts->GetGlyphRangesChineseFull(); 32 | else if (input == "simplified_chinese") 33 | return io.Fonts->GetGlyphRangesChineseSimplifiedCommon(); 34 | else if (input == "cyrillic") 35 | return io.Fonts->GetGlyphRangesCyrillic(); 36 | else if (input == "japanese") 37 | return io.Fonts->GetGlyphRangesJapanese(); 38 | else if (input == "korean") 39 | return io.Fonts->GetGlyphRangesKorean(); 40 | else if (input == "thai") 41 | return io.Fonts->GetGlyphRangesThai(); 42 | else if (input == "vietnamese") 43 | return io.Fonts->GetGlyphRangesVietnamese(); 44 | else if (input == "english") 45 | return io.Fonts->GetGlyphRangesDefault(); 46 | return io.Fonts->GetGlyphRangesDefault(); 47 | } 48 | -------------------------------------------------------------------------------- /engine/ui/Font.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | namespace chira { 8 | 9 | /// IMPORTANT: All font resources MUST be created before Device::createWindow is called! 10 | /// After this, the fonts will be baked, and there will be cake. 11 | class Font : public Resource { 12 | public: 13 | explicit Font(const std::string& identifier_) : Resource(identifier_) {} 14 | void compile(const byte buffer[], std::size_t bufferLength) override; 15 | [[nodiscard]] ImFont* getFont() const; 16 | [[nodiscard]] const std::string& getName() const; 17 | [[nodiscard]] float getSize() const; 18 | 19 | private: 20 | std::string name{"Noto Sans JP"}; 21 | float size = 22.f; 22 | const ImWchar* range = nullptr; 23 | std::string rangeStr{"english"}; 24 | ImFont* font = nullptr; 25 | std::string fontPath{"file://fonts/noto_sans_jp/NotoSansJP-Regular.otf"}; 26 | static const ImWchar* getRangeFromString(std::string_view input); 27 | 28 | public: 29 | template 30 | void serialize(Archive& ar) { 31 | ar( 32 | cereal::make_nvp("name", this->name), 33 | cereal::make_nvp("size", this->size), 34 | cereal::make_nvp("range", this->rangeStr), 35 | cereal::make_nvp("font", this->fontPath) 36 | ); 37 | } 38 | }; 39 | 40 | } // namespace chira 41 | -------------------------------------------------------------------------------- /engine/ui/IPanel.cpp: -------------------------------------------------------------------------------- 1 | #include "IPanel.h" 2 | 3 | using namespace chira; 4 | 5 | IPanel::IPanel(std::string title_, bool startVisible, ImVec2 windowSize, bool enforceSize) 6 | : title(std::move(title_)) 7 | , visible(startVisible) 8 | , activatedThisFrame(startVisible) 9 | , nextWindowSize(windowSize) 10 | , windowSizeCondition(enforceSize ? ImGuiCond_Always : ImGuiCond_FirstUseEver) 11 | , flags(0) {} 12 | 13 | void IPanel::render() { 14 | if (this->visible) { 15 | ImGui::SetNextWindowSize(this->nextWindowSize, this->windowSizeCondition); 16 | this->preRenderContents(); 17 | if (ImGui::Begin(this->title.c_str(), &this->visible, this->flags)) { 18 | this->renderContents(); 19 | } 20 | ImGui::End(); 21 | this->postRenderContents(); 22 | 23 | if (this->activatedThisFrame) 24 | this->activatedThisFrame = false; 25 | } 26 | } 27 | 28 | std::string_view IPanel::getTitle() const { 29 | return this->title; 30 | } 31 | 32 | void IPanel::setTitle(const std::string& newTitle) { 33 | this->title = newTitle; 34 | } 35 | 36 | bool IPanel::isVisible() const { 37 | return this->visible; 38 | } 39 | 40 | void IPanel::setVisible(bool visible_) { 41 | if (visible_) 42 | this->activatedThisFrame = true; 43 | this->visible = visible_; 44 | } 45 | 46 | bool IPanel::wasActivatedThisFrame() const { 47 | return this->activatedThisFrame; 48 | } 49 | 50 | glm::vec2 IPanel::getWindowSize() const { 51 | return {this->nextWindowSize.x, this->nextWindowSize.y}; 52 | } 53 | 54 | ImGuiWindowFlags& IPanel::getWindowFlags() { 55 | return this->flags; 56 | } 57 | 58 | void IPanel::setWindowSize(glm::vec2 size) { 59 | this->nextWindowSize.x = size.x; 60 | this->nextWindowSize.y = size.y; 61 | } 62 | -------------------------------------------------------------------------------- /engine/ui/IPanel.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | namespace chira { 9 | 10 | class IPanel { 11 | public: 12 | IPanel(std::string title_, bool startVisible, ImVec2 windowSize = {}, bool enforceSize = false); 13 | virtual ~IPanel() = default; 14 | void render(); 15 | virtual void preRenderContents() {}; 16 | virtual void renderContents() = 0; 17 | virtual void postRenderContents() {}; 18 | [[nodiscard]] std::string_view getTitle() const; 19 | void setTitle(const std::string& newTitle); 20 | [[nodiscard]] bool isVisible() const; 21 | void setVisible(bool visible_); 22 | [[nodiscard]] bool wasActivatedThisFrame() const; 23 | [[nodiscard]] glm::vec2 getWindowSize() const; 24 | void setWindowSize(glm::vec2 size); 25 | ImGuiWindowFlags& getWindowFlags(); 26 | protected: 27 | std::string title; 28 | bool visible; 29 | bool activatedThisFrame; 30 | ImVec2 nextWindowSize; 31 | ImGuiCond_ windowSizeCondition; 32 | ImGuiWindowFlags flags; 33 | }; 34 | 35 | } // namespace chira 36 | -------------------------------------------------------------------------------- /engine/ui/IViewportPanel.cpp: -------------------------------------------------------------------------------- 1 | #include "IViewportPanel.h" 2 | 3 | #include 4 | 5 | using namespace chira; 6 | 7 | IViewportPanel::IViewportPanel(const std::string& title_, Viewport* viewport_, bool resizeLayer_, bool startVisible, ImVec2 windowSize, bool enforceSize) 8 | : IPanel(title_, startVisible, windowSize, enforceSize) 9 | , viewport(viewport_) 10 | , currentSize(windowSize.x, windowSize.y) 11 | , shouldResize(resizeLayer_) {} 12 | 13 | void IViewportPanel::renderContents() { 14 | if (ImGui::BeginChild("__internal_frame__")) { 15 | ImVec2 guiSize = ImGui::GetWindowSize(); 16 | glm::vec2i size{guiSize.x, guiSize.y}; 17 | if (this->currentSize != size) { 18 | if (this->shouldResize) { 19 | this->viewport->setSize(size); 20 | } 21 | this->currentSize = size; 22 | } 23 | ImGui::Image(Renderer::getImGuiFrameBufferHandle(*this->viewport->getRawHandle()), guiSize, ImVec2(0, 1), ImVec2(1, 0)); 24 | this->renderViewportContents(); 25 | } 26 | ImGui::EndChild(); 27 | } 28 | -------------------------------------------------------------------------------- /engine/ui/IViewportPanel.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "IPanel.h" 5 | 6 | namespace chira { 7 | 8 | class Viewport; 9 | 10 | class IViewportPanel : public IPanel { 11 | public: 12 | IViewportPanel(const std::string& title_, Viewport* viewport_, bool resizeLayer, bool startVisible, ImVec2 windowSize = {}, bool enforceSize = false); 13 | void renderContents() final; 14 | virtual void renderViewportContents() = 0; 15 | protected: 16 | Viewport* viewport; 17 | glm::vec2i currentSize; 18 | bool shouldResize; 19 | }; 20 | 21 | } // namespace chira 22 | -------------------------------------------------------------------------------- /engine/ui/debug/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | list(APPEND CHIRA_ENGINE_HEADERS 2 | ${CMAKE_CURRENT_LIST_DIR}/ConsolePanel.h 3 | ${CMAKE_CURRENT_LIST_DIR}/ResourceUsageTrackerPanel.h) 4 | 5 | list(APPEND CHIRA_ENGINE_SOURCES 6 | ${CMAKE_CURRENT_LIST_DIR}/ConsolePanel.cpp 7 | ${CMAKE_CURRENT_LIST_DIR}/ResourceUsageTrackerPanel.cpp) 8 | -------------------------------------------------------------------------------- /engine/ui/debug/ConsolePanel.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include 6 | #include "../Font.h" 7 | #include "../IPanel.h" 8 | 9 | namespace chira { 10 | 11 | class ConsolePanel : public IPanel { 12 | public: 13 | explicit ConsolePanel(ImVec2 windowSize = ImVec2{800, 600}); 14 | ~ConsolePanel() override; 15 | void renderContents() override; 16 | void clear(); 17 | void addLog(const std::string& message); 18 | void setTheme(); 19 | void resetTheme() const; 20 | 21 | static constexpr int MAX_ITEM_COUNT = 512; 22 | private: 23 | void processConsoleMessage(std::string_view message); 24 | SharedPointer font; 25 | std::deque items; 26 | bool autoScroll; 27 | uuids::uuid loggingId; 28 | }; 29 | 30 | } // namespace chira 31 | -------------------------------------------------------------------------------- /engine/ui/debug/ResourceUsageTrackerPanel.cpp: -------------------------------------------------------------------------------- 1 | #include "ResourceUsageTrackerPanel.h" 2 | 3 | #include 4 | 5 | using namespace chira; 6 | 7 | ResourceUsageTrackerPanel::ResourceUsageTrackerPanel(ImVec2 windowSize) : IPanel(TR("ui.resource_usage_tracker.title"), false, windowSize) {} 8 | 9 | void ResourceUsageTrackerPanel::renderContents() { 10 | if (ImGui::BeginTable("Default Resources", 2)) { 11 | for (const auto& [resourceHash, resource]: Resource::defaultResources) { 12 | ImGui::TableNextRow(); 13 | ImGui::TableSetColumnIndex(0); 14 | ImGui::Text("%s", resource->getIdentifier().data()); 15 | ImGui::TableSetColumnIndex(1); 16 | ImGui::Text("%d", resource.useCount()); 17 | } 18 | ImGui::EndTable(); 19 | } 20 | ImGui::Separator(); 21 | if (ImGui::BeginTable("Resources", 3)) { 22 | for (const auto& [providerName, resourceMap] : Resource::resources) { 23 | for (const auto& [resourceName, resource] : resourceMap) { 24 | ImGui::TableNextRow(); 25 | ImGui::TableSetColumnIndex(0); 26 | ImGui::Text("%s", providerName.c_str()); 27 | ImGui::TableSetColumnIndex(1); 28 | ImGui::Text("%s", resourceName.c_str()); 29 | ImGui::TableSetColumnIndex(2); 30 | ImGui::Text("%d", resource.useCount()); 31 | } 32 | } 33 | ImGui::EndTable(); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /engine/ui/debug/ResourceUsageTrackerPanel.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace chira { 6 | 7 | class ResourceUsageTrackerPanel : public IPanel { 8 | public: 9 | explicit ResourceUsageTrackerPanel(ImVec2 windowSize = ImVec2{800, 600}); 10 | void renderContents() override; 11 | }; 12 | 13 | } // namespace chira 14 | -------------------------------------------------------------------------------- /engine/utility/AbstractFactory.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | namespace chira { 8 | 9 | // check render/material/MaterialFactory.h:L21 for example usage 10 | 11 | template 12 | class AbstractFactory { 13 | using factoryFunction = std::function; 14 | public: 15 | AbstractFactory() = delete; 16 | static bool registerTypeFactory(const std::string& name, factoryFunction createFunc) { 17 | if (AbstractFactory::getFactoryMethods().contains(name)) 18 | return false; 19 | AbstractFactory::getFactoryMethods()[name] = createFunc; 20 | return true; 21 | } 22 | static const factoryFunction& getTypeFactory(const std::string& name) { 23 | return AbstractFactory::getFactoryMethods().at(name); 24 | } 25 | protected: 26 | static std::unordered_map& getFactoryMethods() { 27 | static std::unordered_map factoryFunctions; 28 | return factoryFunctions; 29 | } 30 | }; 31 | 32 | } // namespace chira 33 | -------------------------------------------------------------------------------- /engine/utility/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | list(APPEND CHIRA_ENGINE_HEADERS 2 | ${CMAKE_CURRENT_LIST_DIR}/AbstractFactory.h 3 | ${CMAKE_CURRENT_LIST_DIR}/Concepts.h 4 | ${CMAKE_CURRENT_LIST_DIR}/DependencyGraph.h 5 | ${CMAKE_CURRENT_LIST_DIR}/NoCopyOrMove.h 6 | ${CMAKE_CURRENT_LIST_DIR}/Serial.h 7 | ${CMAKE_CURRENT_LIST_DIR}/SharedPointer.h 8 | ${CMAKE_CURRENT_LIST_DIR}/String.h 9 | ${CMAKE_CURRENT_LIST_DIR}/Types.h 10 | ${CMAKE_CURRENT_LIST_DIR}/TypeString.h 11 | ${CMAKE_CURRENT_LIST_DIR}/UUIDGenerator.h) 12 | 13 | list(APPEND CHIRA_ENGINE_SOURCES 14 | ${CMAKE_CURRENT_LIST_DIR}/String.cpp 15 | ${CMAKE_CURRENT_LIST_DIR}/UUIDGenerator.cpp) 16 | -------------------------------------------------------------------------------- /engine/utility/Concepts.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | namespace chira { 7 | 8 | template 9 | concept CArithmetic = std::is_arithmetic_v; 10 | 11 | template 12 | concept CNonArithmetic = !std::is_arithmetic_v; 13 | 14 | } // namespace chira 15 | -------------------------------------------------------------------------------- /engine/utility/DependencyGraph.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include 6 | 7 | namespace chira { 8 | 9 | class DependencyGraph : public UnweightedDirectedGraph { 10 | public: 11 | DependencyGraph() 12 | : UnweightedDirectedGraph() {} 13 | 14 | /// Get the order that dependencies should be initialized in, or std::nullopt if there is a cycle 15 | [[nodiscard]] std::optional> resolveDependencyOrder() const { 16 | std::vector resolved; 17 | std::vector unresolved; 18 | for (const auto& node : this->nodes) { 19 | const auto* edge = node.get(); 20 | if (std::find(resolved.begin(), resolved.end(), edge) != resolved.end()) { 21 | continue; 22 | } 23 | if (std::find(unresolved.begin(), unresolved.end(), edge) != unresolved.end()) { 24 | return std::nullopt; 25 | } 26 | if (!resolveDependencyOrderRecurse(edge, resolved, unresolved)) { 27 | return std::nullopt; 28 | } 29 | } 30 | return resolved; 31 | } 32 | 33 | /// Get the order that dependencies should be initialized in, or std::nullopt if there is a cycle 34 | [[nodiscard]] static std::optional> resolveDependencyOrder(const Node* root) { 35 | std::vector resolved; 36 | std::vector unresolved; 37 | if (!resolveDependencyOrderRecurse(root, resolved, unresolved)) { 38 | return std::nullopt; 39 | } 40 | return resolved; 41 | } 42 | 43 | protected: 44 | // NOLINTNEXTLINE(misc-no-recursion) 45 | static bool resolveDependencyOrderRecurse(const Node* node, std::vector& resolved, std::vector& unresolved) { 46 | unresolved.push_back(node); 47 | for (const auto* edge : node->edges) { 48 | if (std::find(resolved.begin(), resolved.end(), edge) != resolved.end()) { 49 | continue; 50 | } 51 | if (std::find(unresolved.begin(), unresolved.end(), edge) != unresolved.end()) { 52 | return false; 53 | } 54 | if (!resolveDependencyOrderRecurse(edge, resolved, unresolved)) { 55 | return false; 56 | } 57 | } 58 | unresolved.erase(std::remove(unresolved.begin(), unresolved.end(), node), unresolved.end()); 59 | resolved.push_back(node); 60 | return true; 61 | } 62 | }; 63 | 64 | } // namespace chira 65 | -------------------------------------------------------------------------------- /engine/utility/NoCopyOrMove.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace chira { 4 | 5 | struct NoCopy { 6 | NoCopy() = default; 7 | NoCopy(const NoCopy&) = delete; 8 | NoCopy& operator=(const NoCopy&) = delete; 9 | }; 10 | 11 | struct NoMove { 12 | NoMove() = default; 13 | NoMove(NoMove&&) = delete; 14 | NoMove& operator=(NoMove&&) = delete; 15 | }; 16 | 17 | struct NoCopyOrMove : public NoCopy, public NoMove { 18 | NoCopyOrMove() = default; 19 | }; 20 | 21 | } // namespace chira 22 | -------------------------------------------------------------------------------- /engine/utility/Serial.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | namespace chira::Serial { 11 | 12 | template 13 | void loadFromBuffer(T* that, const byte buffer[], std::size_t bufferLength) { 14 | std::istringstream stream{std::string{reinterpret_cast(buffer), bufferLength}}; 15 | cereal::JSONInputArchive archive{stream}; 16 | that->serialize(archive); 17 | } 18 | 19 | } // namespace chira::Serial 20 | -------------------------------------------------------------------------------- /engine/utility/Types.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | namespace chira { 10 | 11 | namespace detail { 12 | 13 | //inline std::uint64_t typeIDSequenceController = 0; 14 | 15 | template 16 | constexpr void enumerateImpl(T&& t, F&& f, std::index_sequence) { 17 | (f(static_cast(std::integral_constant{}), std::get(t)), ...); 18 | } 19 | 20 | template 21 | constexpr void forindexImpl(F&& f, std::index_sequence) { 22 | (f(static_cast(std::integral_constant{})), ...); 23 | } 24 | 25 | template 26 | constexpr void foreachImpl(T&& t, F&& f, std::index_sequence) { 27 | (f(std::get(t)), ...); 28 | } 29 | 30 | } // namespace detail 31 | 32 | //template 33 | //inline const std::uint64_t typeID = detail::typeIDSequenceController++; 34 | 35 | // todo(c++): switch to typeID variable template 36 | template 37 | std::type_index typeHash() { 38 | return typeid(T); 39 | } 40 | 41 | template>> 42 | constexpr void enumerate(T&& t, F&& f) { 43 | detail::enumerateImpl(t, std::forward(f), std::make_index_sequence{}); 44 | } 45 | 46 | template>> 47 | constexpr void forindex(T&&, F&& f) { 48 | detail::forindexImpl(std::forward(f), std::make_index_sequence{}); 49 | } 50 | 51 | template>> 52 | constexpr void foreach(T&& t, F&& f) { 53 | detail::foreachImpl(t, std::forward(f), std::make_index_sequence{}); 54 | } 55 | 56 | } // namespace chira 57 | -------------------------------------------------------------------------------- /engine/utility/UUIDGenerator.cpp: -------------------------------------------------------------------------------- 1 | #include "UUIDGenerator.h" 2 | 3 | using namespace chira; 4 | 5 | UUIDGenerator::UUIDGeneratorInstance::UUIDGeneratorInstance() { 6 | std::generate(std::begin(this->seedData), std::end(this->seedData), std::ref(this->rd)); 7 | std::seed_seq seq(std::begin(this->seedData), std::end(this->seedData)); 8 | this->generator = std::make_unique(seq); 9 | } 10 | 11 | [[nodiscard]] std::mt19937* UUIDGenerator::UUIDGeneratorInstance::getGenerator() const { 12 | return this->generator.get(); 13 | } 14 | 15 | uuids::uuid UUIDGenerator::getNewUUID() { 16 | if (!UUIDGenerator::generator) { 17 | UUIDGenerator::generator = std::make_unique(); 18 | } 19 | return uuids::uuid_random_generator{*UUIDGenerator::generator->getGenerator()}(); 20 | } 21 | 22 | std::string UUIDGenerator::getNewUUIDString() { 23 | return uuids::to_string(UUIDGenerator::getNewUUID()); 24 | } 25 | -------------------------------------------------------------------------------- /engine/utility/UUIDGenerator.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | namespace chira { 8 | 9 | class UUIDGenerator { 10 | class UUIDGeneratorInstance { 11 | public: 12 | UUIDGeneratorInstance(); 13 | [[nodiscard]] std::mt19937* getGenerator() const; 14 | private: 15 | std::random_device rd{}; 16 | std::array seedData{}; 17 | std::unique_ptr generator; 18 | }; 19 | 20 | public: 21 | static uuids::uuid getNewUUID(); 22 | static std::string getNewUUIDString(); 23 | private: 24 | static inline std::unique_ptr generator{}; 25 | }; 26 | 27 | } // namespace chira 28 | 29 | namespace uuids { 30 | 31 | inline void to_json(nlohmann::json& j, const uuid& u) { 32 | j = {to_string(u)}; 33 | } 34 | 35 | inline void from_json(const nlohmann::json& j, uuid& u) { 36 | u = *uuid::from_string(j.get()); 37 | } 38 | 39 | } // namespace uuids 40 | -------------------------------------------------------------------------------- /resources/editor/i18n/editor_en.json: -------------------------------------------------------------------------------- 1 | { 2 | "ui.window.title": "Chira Editor", 3 | 4 | "ui.entities": "Entities", 5 | 6 | "ui.menubar.open_model": "Open Model...", 7 | "ui.menubar.add_resource_folder": "Add Resource Folder...", 8 | "ui.menubar.convert": "Convert", 9 | "ui.menubar.convert_to_obj": "Convert to OBJ...", 10 | "ui.menubar.convert_to_cmdl": "Convert to CMDL...", 11 | 12 | "ui.editor.show_grid": "Show Grid", 13 | 14 | "ui.settings.title": "Settings", 15 | "ui.settings.window_width": "Window Width", 16 | "ui.settings.window_height": "Window Height", 17 | "ui.settings.start_maximized": "Start Maximized", 18 | "ui.settings.fullscreen": "Fullscreen", 19 | "ui.settings.vsync": "Vertical Sync", 20 | "ui.settings.raw_mouse_motion": "Raw Mouse Motion", 21 | "ui.settings.invert_y_axis": "Invert Y Axis", 22 | "ui.settings.language": "Language", 23 | "ui.settings.discord_integration": "Discord Rich Presence", 24 | "ui.settings.apply": "Apply", 25 | 26 | "error.modelviewer.filename_empty": "Please specify a proper path and filename.", 27 | "error.modelviewer.no_model_present": "There is no model present to convert.", 28 | "error.modelviewer.file_is_not_resource": "File selected is not a resource.", 29 | "error.modelviewer.resource_folder_already_registered": "Resource folder is already registered.", 30 | "error.modelviewer.resource_folder_not_valid": "Please select a valid folder in the resources folder.", 31 | "error.modelviewer.resource_is_invalid": "Resource identifier {} does not point to a visible resource." 32 | } 33 | -------------------------------------------------------------------------------- /resources/editor/i18n/editor_universal.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.discord.application_id": "875778280899358720" 3 | } 4 | -------------------------------------------------------------------------------- /resources/editor/materials/teapot.json: -------------------------------------------------------------------------------- 1 | { 2 | "shader": "file://shaders/phonglit.json", 3 | "diffuse": "file://textures/container_diffuse.json", 4 | "specular": "file://textures/container_specular.json", 5 | "shininess": 32, 6 | "lambertFactor": 1 7 | } 8 | -------------------------------------------------------------------------------- /resources/editor/meshes/teapot.cmdl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/craftablescience/ChiraEngine/ebb306844057a85d37f56b09002f02a5c0d4d894/resources/editor/meshes/teapot.cmdl -------------------------------------------------------------------------------- /resources/editor/meshes/teapot.json: -------------------------------------------------------------------------------- 1 | { 2 | "materialSetInCode": false, 3 | "materialType": "MaterialPhong", 4 | "material": "file://materials/teapot.json", 5 | "model": "file://meshes/teapot.cmdl", 6 | "modelLoader": "cmdl", 7 | "depthFunction": "LESS" 8 | } 9 | -------------------------------------------------------------------------------- /resources/editor/platform/macOS/AppIcon.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/craftablescience/ChiraEngine/ebb306844057a85d37f56b09002f02a5c0d4d894/resources/editor/platform/macOS/AppIcon.icns -------------------------------------------------------------------------------- /resources/editor/platform/macOS/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleDisplayName 8 | Chira Engine 9 | CFBundleExecutable 10 | editor 11 | CFBundleGetInfoString 12 | 13 | CFBundleIconFile 14 | AppIcon.icns 15 | CFBundleIdentifier 16 | 17 | CFBundleInfoDictionaryVersion 18 | 6.0 19 | CFBundleLongVersionString 20 | 21 | CFBundleName 22 | Chira Engine 23 | CFBundlePackageType 24 | APPL 25 | CFBundleShortVersionString 26 | 27 | CFBundleSignature 28 | ???? 29 | CFBundleVersion 30 | 1.0 31 | CSResourcesFileMapped 32 | 33 | NSHumanReadableCopyright 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /resources/editor/textures/container_diffuse.json: -------------------------------------------------------------------------------- 1 | { 2 | "verticalFlip": true, 3 | "mipmaps": true, 4 | "image": "file://textures/container_diffuse.png", 5 | "wrapModeS": "REPEAT", 6 | "wrapModeT": "REPEAT", 7 | "filterMode": "LINEAR" 8 | } 9 | -------------------------------------------------------------------------------- /resources/editor/textures/container_diffuse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/craftablescience/ChiraEngine/ebb306844057a85d37f56b09002f02a5c0d4d894/resources/editor/textures/container_diffuse.png -------------------------------------------------------------------------------- /resources/editor/textures/container_specular.json: -------------------------------------------------------------------------------- 1 | { 2 | "verticalFlip": true, 3 | "mipmaps": true, 4 | "image": "file://textures/container_specular.png", 5 | "wrapModeS": "REPEAT", 6 | "wrapModeT": "REPEAT", 7 | "filterMode": "LINEAR" 8 | } 9 | -------------------------------------------------------------------------------- /resources/editor/textures/container_specular.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/craftablescience/ChiraEngine/ebb306844057a85d37f56b09002f02a5c0d4d894/resources/editor/textures/container_specular.png -------------------------------------------------------------------------------- /resources/engine/bin/LICENSE.md: -------------------------------------------------------------------------------- 1 | The Steam API redistributable binaries are created and maintained solely by the Valve Corporation (Valve LLC). 2 | 3 | Before removing these binaries (if you do not plan on utilizing the Steamworks API), 4 | add `-DCHIRA_USE_STEAMWORKS=OFF` to your CMake build command and rebuild the engine. 5 | -------------------------------------------------------------------------------- /resources/engine/bin/steam_api32.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/craftablescience/ChiraEngine/ebb306844057a85d37f56b09002f02a5c0d4d894/resources/engine/bin/steam_api32.dll -------------------------------------------------------------------------------- /resources/engine/bin/steam_api32.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/craftablescience/ChiraEngine/ebb306844057a85d37f56b09002f02a5c0d4d894/resources/engine/bin/steam_api32.so -------------------------------------------------------------------------------- /resources/engine/bin/steam_api64.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/craftablescience/ChiraEngine/ebb306844057a85d37f56b09002f02a5c0d4d894/resources/engine/bin/steam_api64.dll -------------------------------------------------------------------------------- /resources/engine/bin/steam_api64.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/craftablescience/ChiraEngine/ebb306844057a85d37f56b09002f02a5c0d4d894/resources/engine/bin/steam_api64.dylib -------------------------------------------------------------------------------- /resources/engine/bin/steam_api64.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/craftablescience/ChiraEngine/ebb306844057a85d37f56b09002f02a5c0d4d894/resources/engine/bin/steam_api64.so -------------------------------------------------------------------------------- /resources/engine/fonts/console_en.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "DejaVu Sans Mono", 3 | "size": 18.0, 4 | "range": "english", 5 | "font": "file://fonts/dejavu_sans_mono/DejaVuSansMono.ttf" 6 | } 7 | -------------------------------------------------------------------------------- /resources/engine/fonts/console_jp.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Noto Sans Mono CJK JP", 3 | "size": 24.0, 4 | "range": "japanese", 5 | "font": "file://fonts/noto_sans_mono/NotoSansMonoCJKjp-Regular.otf" 6 | } 7 | -------------------------------------------------------------------------------- /resources/engine/fonts/default_en.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Noto Sans JP", 3 | "size": 22.0, 4 | "range": "english", 5 | "font": "file://fonts/noto_sans_jp/NotoSansJP-Regular.otf" 6 | } 7 | -------------------------------------------------------------------------------- /resources/engine/fonts/default_jp.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Noto Sans JP", 3 | "size": 22.0, 4 | "range": "japanese", 5 | "font": "file://fonts/noto_sans_jp/NotoSansJP-Regular.otf" 6 | } 7 | -------------------------------------------------------------------------------- /resources/engine/fonts/dejavu_sans_mono/AUTHORS: -------------------------------------------------------------------------------- 1 | abysta at yandex.ru 2 | Adrian Schroeter 3 | Aleksey Chalabyan 4 | Andrey Valentinovich Panov 5 | Ben Laenen 6 | Besarion Gugushvili 7 | Bhikkhu Pesala 8 | Clayborne Arevalo 9 | Dafydd Harries 10 | Danilo Segan 11 | Davide Viti 12 | David Jez 13 | David Lawrence Ramsey 14 | Denis Jacquerye 15 | Dwayne Bailey 16 | Eugeniy Meshcheryakov 17 | Frédéric Wang 18 | Gee Fung Sit 19 | Heikki Lindroos 20 | James Cloos 21 | James Crippen 22 | John Karp 23 | Keenan Pepper 24 | Lars Næsbye Christensen 25 | Lior Halphon 26 | MaEr 27 | Mashrab Kuvatov 28 | Max Berger 29 | Mederic Boquien 30 | Michael Everson 31 | MihailJP 32 | Misu Moldovan 33 | Nguyen Thai Ngoc Duy 34 | Nicolas Mailhot 35 | Norayr Chilingarian 36 | Olleg Samoylov 37 | Ognyan Kulev 38 | Ondrej Koala Vacha 39 | Peter Cernak 40 | Remy Oudompheng 41 | Roozbeh Pournader 42 | Rouben Hakobian 43 | Sahak Petrosyan 44 | Sami Tarazi 45 | Sander Vesik 46 | Stepan Roh 47 | Stephen Hartke 48 | Steve Tinney 49 | Tavmjong Bah 50 | Thomas Henlich 51 | Tim May 52 | Valentin Stoykov 53 | Vasek Stodulka 54 | Wesley Transue 55 | Yoshiki Ohshima 56 | 57 | $Id$ 58 | -------------------------------------------------------------------------------- /resources/engine/fonts/dejavu_sans_mono/DejaVuSansMono.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/craftablescience/ChiraEngine/ebb306844057a85d37f56b09002f02a5c0d4d894/resources/engine/fonts/dejavu_sans_mono/DejaVuSansMono.ttf -------------------------------------------------------------------------------- /resources/engine/fonts/noto_sans_jp/NotoSansJP-Black.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/craftablescience/ChiraEngine/ebb306844057a85d37f56b09002f02a5c0d4d894/resources/engine/fonts/noto_sans_jp/NotoSansJP-Black.otf -------------------------------------------------------------------------------- /resources/engine/fonts/noto_sans_jp/NotoSansJP-Bold.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/craftablescience/ChiraEngine/ebb306844057a85d37f56b09002f02a5c0d4d894/resources/engine/fonts/noto_sans_jp/NotoSansJP-Bold.otf -------------------------------------------------------------------------------- /resources/engine/fonts/noto_sans_jp/NotoSansJP-Light.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/craftablescience/ChiraEngine/ebb306844057a85d37f56b09002f02a5c0d4d894/resources/engine/fonts/noto_sans_jp/NotoSansJP-Light.otf -------------------------------------------------------------------------------- /resources/engine/fonts/noto_sans_jp/NotoSansJP-Medium.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/craftablescience/ChiraEngine/ebb306844057a85d37f56b09002f02a5c0d4d894/resources/engine/fonts/noto_sans_jp/NotoSansJP-Medium.otf -------------------------------------------------------------------------------- /resources/engine/fonts/noto_sans_jp/NotoSansJP-Regular.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/craftablescience/ChiraEngine/ebb306844057a85d37f56b09002f02a5c0d4d894/resources/engine/fonts/noto_sans_jp/NotoSansJP-Regular.otf -------------------------------------------------------------------------------- /resources/engine/fonts/noto_sans_jp/NotoSansJP-Thin.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/craftablescience/ChiraEngine/ebb306844057a85d37f56b09002f02a5c0d4d894/resources/engine/fonts/noto_sans_jp/NotoSansJP-Thin.otf -------------------------------------------------------------------------------- /resources/engine/fonts/noto_sans_mono/NotoSansMonoCJKjp-Regular.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/craftablescience/ChiraEngine/ebb306844057a85d37f56b09002f02a5c0d4d894/resources/engine/fonts/noto_sans_mono/NotoSansMonoCJKjp-Regular.otf -------------------------------------------------------------------------------- /resources/engine/i18n/engine_en.json: -------------------------------------------------------------------------------- 1 | { 2 | "resource.font.default": "file://fonts/default_en.json", 3 | "resource.font.console": "file://fonts/console_en.json", 4 | 5 | "ui.window.title": "Chira Engine", 6 | 7 | "ui.console.title": "Console", 8 | "ui.resource_usage_tracker.title": "Resource Usage", 9 | 10 | "ui.window.select_file": "Select File", 11 | "ui.window.save_file": "Save File", 12 | 13 | "ui.menubar.file": "File", 14 | "ui.menubar.new": "New", 15 | "ui.menubar.open": "Open", 16 | "ui.menubar.save": "Save", 17 | "ui.menubar.save_as": "Save As...", 18 | "ui.menubar.exit": "Exit", 19 | "ui.menubar.edit": "Edit", 20 | "ui.menubar.undo": "Undo", 21 | "ui.menubar.redo": "Redo", 22 | 23 | "generic.operation.cancelled": "Operation cancelled", 24 | 25 | "debug.discord.user_disconnected": "Discord user disconnected, code {}: {}", 26 | "debug.discord.generic_error": "Discord error {}: {}", 27 | 28 | "warn.obj_loader.not_triangulated": "OBJ file at {} is not triangulated, this will cause problems", 29 | "warn.properties_resource.missing_property": "Resource \"{}\" missing property \"{}\", using fallback...", 30 | "warn.resource.deleting_resource_at_exit": "Deleting \"{}\" (refcount {}) that was not already deleted!", 31 | "error.axis.invalid_value": "Invalid axis type \"{}\" does not map to any value in the {} enum", 32 | "error.cmdl_loader.invalid_data": "Mesh at \"{}\" has invalid data!", 33 | "error.file_input_stream.file_inaccessible": "File at \"{}\" is not accessible: error {}", 34 | "error.entity.duplicate_child_name": "Attempted to add child \"{}\", but a child with this name already exists!", 35 | "error.engine.not_initialized": "Engine is not started: have you called Engine::preInit() and Engine::init()?", 36 | "error.translation_manager.missing_translation": "Could not find {} translation of \"{}\"", 37 | "error.resource.resource_not_found": "Resource {} was not found", 38 | "error.resource.cached_resource_not_found": "Supposedly cached resource {} was not found", 39 | "error.resource.cannot_split_identifier": "Cannot split resource identifier \"{}\"", 40 | "error.properties_resource.invalid_json": "Invalid JSON read for resource at \"{}\", resource will have no properties!" 41 | } 42 | -------------------------------------------------------------------------------- /resources/engine/materials/phong.json: -------------------------------------------------------------------------------- 1 | { 2 | "shader": "file://shaders/phonglit.json", 3 | "diffuse": "file://textures/missing.json", 4 | "specular": "file://textures/black.json", 5 | "shininess": 32, 6 | "lambertFactor": 1 7 | } 8 | -------------------------------------------------------------------------------- /resources/engine/materials/skybox.json: -------------------------------------------------------------------------------- 1 | { 2 | "shader": "file://shaders/skybox.json", 3 | "cubemap": "file://textures/missingSkybox.json" 4 | } 5 | -------------------------------------------------------------------------------- /resources/engine/materials/splashscreen.json: -------------------------------------------------------------------------------- 1 | { 2 | "shader": "file://shaders/ui.json", 3 | "texture": "file://textures/ui/splashscreen.json" 4 | } 5 | -------------------------------------------------------------------------------- /resources/engine/materials/unlit.json: -------------------------------------------------------------------------------- 1 | { 2 | "shader": "file://shaders/unlit.json" 3 | } 4 | -------------------------------------------------------------------------------- /resources/engine/materials/unlitTextured.json: -------------------------------------------------------------------------------- 1 | { 2 | "shader": "file://shaders/unlitTextured.json", 3 | "texture": "file://textures/missing.json" 4 | } 5 | -------------------------------------------------------------------------------- /resources/engine/materials/window.json: -------------------------------------------------------------------------------- 1 | { 2 | "shader": "file://shaders/ui.json" 3 | } 4 | -------------------------------------------------------------------------------- /resources/engine/meshes/missing.cmdl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/craftablescience/ChiraEngine/ebb306844057a85d37f56b09002f02a5c0d4d894/resources/engine/meshes/missing.cmdl -------------------------------------------------------------------------------- /resources/engine/meshes/missing.json: -------------------------------------------------------------------------------- 1 | { 2 | "materialSetInCode": false, 3 | "materialType": "MaterialTextured", 4 | "material": "file://materials/unlitTextured.json", 5 | "model": "file://meshes/missing.cmdl", 6 | "modelLoader": "cmdl", 7 | "depthFunction": "LESS" 8 | } 9 | -------------------------------------------------------------------------------- /resources/engine/platform/windows/app.manifest: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /resources/engine/platform/windows/app.rc: -------------------------------------------------------------------------------- 1 | IDI_ICON1 ICON DISCARDABLE "resources/engine/platform/windows/icon.ico" 2 | CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "resources/engine/platform/windows/app.manifest" 3 | -------------------------------------------------------------------------------- /resources/engine/platform/windows/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/craftablescience/ChiraEngine/ebb306844057a85d37f56b09002f02a5c0d4d894/resources/engine/platform/windows/icon.ico -------------------------------------------------------------------------------- /resources/engine/shaders/phonglit.json: -------------------------------------------------------------------------------- 1 | { 2 | "vertex": "file://shaders/phonglit.vsh", 3 | "fragment": "file://shaders/phonglit.fsh", 4 | "usesPV": true, 5 | "usesM": true, 6 | "lit": true 7 | } 8 | -------------------------------------------------------------------------------- /resources/engine/shaders/phonglit.vsh: -------------------------------------------------------------------------------- 1 | layout (location = 0) in vec3 iPos; 2 | layout (location = 1) in vec3 iNormal; 3 | layout (location = 2) in vec3 iColor; 4 | layout (location = 3) in vec2 iTexCoords; 5 | 6 | out VS_OUT { 7 | vec3 color; 8 | vec3 normal; 9 | vec2 texCoords; 10 | vec3 worldPosition; 11 | vec3 viewPosition; 12 | vec3 viewDirection; 13 | vec3 fragPosition; 14 | } o; 15 | 16 | #include file://shaders/ubo/pv.glsl# 17 | #include file://shaders/uniform/m.glsl# 18 | 19 | 20 | void main() { 21 | o.color = iColor; 22 | o.normal = mat3(transpose(inverse(m))) * iNormal; 23 | o.texCoords = iTexCoords; 24 | o.worldPosition = vec3(v * m * vec4(iPos, 1.0)); 25 | o.viewPosition = viewPosition.xyz; 26 | o.viewDirection = normalize(viewLookDirection.xyz); 27 | o.fragPosition = vec3(m * vec4(iPos, 1.0)); 28 | gl_Position = pv * vec4(o.fragPosition, 1.0); 29 | } 30 | -------------------------------------------------------------------------------- /resources/engine/shaders/skybox.fsh: -------------------------------------------------------------------------------- 1 | out vec4 FragColor; 2 | 3 | in vec3 TexCoords; 4 | 5 | uniform samplerCube cubemap; 6 | 7 | 8 | void main() { 9 | FragColor = texture(cubemap, TexCoords); 10 | } 11 | -------------------------------------------------------------------------------- /resources/engine/shaders/skybox.json: -------------------------------------------------------------------------------- 1 | { 2 | "vertex": "file://shaders/skybox.vsh", 3 | "fragment": "file://shaders/skybox.fsh", 4 | "usesPV": true, 5 | "usesM": false, 6 | "lit": false 7 | } 8 | -------------------------------------------------------------------------------- /resources/engine/shaders/skybox.vsh: -------------------------------------------------------------------------------- 1 | layout (location = 0) in vec3 iPos; 2 | layout (location = 1) in vec3 iNormal; 3 | layout (location = 2) in vec3 iColor; 4 | layout (location = 3) in vec2 iTexCoord; 5 | 6 | out vec3 TexCoords; 7 | 8 | #include file://shaders/ubo/pv.glsl# 9 | 10 | 11 | void main() { 12 | TexCoords = iPos; 13 | vec4 pos = p * mat4(mat3(v)) * vec4(iPos, 1.0); 14 | gl_Position = pos.xyww; 15 | } 16 | -------------------------------------------------------------------------------- /resources/engine/shaders/ubo/lights.glsl: -------------------------------------------------------------------------------- 1 | struct DirectionalLight { 2 | vec4 direction; 3 | vec4 ambient; 4 | vec4 diffuse; 5 | vec4 specular; 6 | }; 7 | #define DIRECTIONAL_LIGHT_MAX #DIRECTIONAL_LIGHT_MAX# 8 | 9 | struct PointLight { 10 | vec4 position; 11 | vec4 ambient; 12 | vec4 diffuse; 13 | vec4 specular; 14 | vec4 falloff; // x is constant, y is linear, z is quadratic 15 | }; 16 | #define POINT_LIGHT_MAX #POINT_LIGHT_MAX# 17 | 18 | struct SpotLight { 19 | vec4 position; 20 | vec4 direction; 21 | vec4 diffuse; 22 | vec4 specular; 23 | vec4 falloff; // x is constant, y is linear, z is quadratic 24 | vec4 cutoff; // x is cutoff inner angle, y is cutoff outer angle 25 | }; 26 | #define SPOT_LIGHT_MAX #SPOT_LIGHT_MAX# 27 | 28 | layout (std140) uniform LIGHTS { 29 | DirectionalLight directionalLights[DIRECTIONAL_LIGHT_MAX]; 30 | PointLight pointLights[POINT_LIGHT_MAX]; 31 | SpotLight spotLights[SPOT_LIGHT_MAX]; 32 | vec4 numberOfLights; // x is directional lights, y is point lights, z is spot lights 33 | }; 34 | -------------------------------------------------------------------------------- /resources/engine/shaders/ubo/pv.glsl: -------------------------------------------------------------------------------- 1 | layout (std140) uniform PV { 2 | mat4 p; 3 | mat4 v; 4 | mat4 pv; 5 | vec4 viewPosition; 6 | vec4 viewLookDirection; 7 | }; 8 | -------------------------------------------------------------------------------- /resources/engine/shaders/ui.fsh: -------------------------------------------------------------------------------- 1 | out vec4 FragColor; 2 | 3 | in VS_OUT { 4 | vec3 Color; 5 | vec3 Normal; 6 | vec2 TexCoord; 7 | } i; 8 | 9 | uniform sampler2D texture0; 10 | 11 | 12 | void main() { 13 | FragColor = texture(texture0, i.TexCoord); 14 | } 15 | -------------------------------------------------------------------------------- /resources/engine/shaders/ui.json: -------------------------------------------------------------------------------- 1 | { 2 | "vertex": "file://shaders/ui.vsh", 3 | "fragment": "file://shaders/ui.fsh", 4 | "usesPV": false, 5 | "usesM": false, 6 | "lit": false 7 | } 8 | -------------------------------------------------------------------------------- /resources/engine/shaders/ui.vsh: -------------------------------------------------------------------------------- 1 | layout (location = 0) in vec3 iPos; 2 | layout (location = 1) in vec3 iNormal; 3 | layout (location = 2) in vec3 iColor; 4 | layout (location = 3) in vec2 iTexCoord; 5 | 6 | out VS_OUT { 7 | vec3 Color; 8 | vec3 Normal; 9 | vec2 TexCoord; 10 | } o; 11 | 12 | 13 | void main() { 14 | gl_Position = vec4(iPos, 1.0); 15 | o.Color = iColor; 16 | o.Normal = iNormal; 17 | o.TexCoord = iTexCoord; 18 | } 19 | -------------------------------------------------------------------------------- /resources/engine/shaders/uniform/m.glsl: -------------------------------------------------------------------------------- 1 | uniform mat4 m; 2 | -------------------------------------------------------------------------------- /resources/engine/shaders/unlit.fsh: -------------------------------------------------------------------------------- 1 | out vec4 FragColor; 2 | 3 | in VS_OUT { 4 | vec3 Color; 5 | vec3 Normal; 6 | vec2 TexCoord; 7 | } i; 8 | 9 | 10 | void main() { 11 | FragColor = vec4(i.Color, 1.0); 12 | } 13 | -------------------------------------------------------------------------------- /resources/engine/shaders/unlit.json: -------------------------------------------------------------------------------- 1 | { 2 | "vertex": "file://shaders/unlit.vsh", 3 | "fragment": "file://shaders/unlit.fsh", 4 | "usesPV": true, 5 | "usesM": true, 6 | "lit": false 7 | } 8 | -------------------------------------------------------------------------------- /resources/engine/shaders/unlit.vsh: -------------------------------------------------------------------------------- 1 | layout (location = 0) in vec3 iPos; 2 | layout (location = 1) in vec3 iNormal; 3 | layout (location = 2) in vec3 iColor; 4 | layout (location = 3) in vec2 iTexCoord; 5 | 6 | out VS_OUT { 7 | vec3 Color; 8 | vec3 Normal; 9 | vec2 TexCoord; 10 | } o; 11 | 12 | #include file://shaders/ubo/pv.glsl# 13 | #include file://shaders/uniform/m.glsl# 14 | 15 | 16 | void main() { 17 | gl_Position = pv * m * vec4(iPos, 1.0); 18 | o.Color = iColor; 19 | o.Normal = iNormal; 20 | o.TexCoord = iTexCoord; 21 | } 22 | -------------------------------------------------------------------------------- /resources/engine/shaders/unlitTextured.fsh: -------------------------------------------------------------------------------- 1 | out vec4 FragColor; 2 | 3 | in VS_OUT { 4 | vec3 Color; 5 | vec3 Normal; 6 | vec2 TexCoord; 7 | } i; 8 | 9 | uniform sampler2D texture0; 10 | 11 | 12 | void main() { 13 | FragColor = texture(texture0, i.TexCoord) * vec4(i.Color, 1.0); 14 | } 15 | -------------------------------------------------------------------------------- /resources/engine/shaders/unlitTextured.json: -------------------------------------------------------------------------------- 1 | { 2 | "vertex": "file://shaders/unlitTextured.vsh", 3 | "fragment": "file://shaders/unlitTextured.fsh", 4 | "usesPV": true, 5 | "usesM": true, 6 | "lit": false 7 | } 8 | -------------------------------------------------------------------------------- /resources/engine/shaders/unlitTextured.vsh: -------------------------------------------------------------------------------- 1 | layout (location = 0) in vec3 iPos; 2 | layout (location = 1) in vec3 iNormal; 3 | layout (location = 2) in vec3 iColor; 4 | layout (location = 3) in vec2 iTexCoord; 5 | 6 | out VS_OUT { 7 | vec3 Color; 8 | vec3 Normal; 9 | vec2 TexCoord; 10 | } o; 11 | 12 | #include file://shaders/ubo/pv.glsl# 13 | #include file://shaders/uniform/m.glsl# 14 | 15 | 16 | void main() { 17 | gl_Position = pv * m * vec4(iPos, 1.0); 18 | o.Color = iColor; 19 | o.Normal = iNormal; 20 | o.TexCoord = iTexCoord; 21 | } 22 | -------------------------------------------------------------------------------- /resources/engine/shaders/utility/when.glsl: -------------------------------------------------------------------------------- 1 | /* 2 | Taken from https://theorangeduck.com/page/avoiding-shader-conditionals 3 | 4 | Old and slow: 5 | 6 | if (x == 0) { 7 | y += 5; 8 | } 9 | 10 | New and fast: 11 | 12 | y += 5 * when_eq(x, 0) 13 | 14 | */ 15 | 16 | vec4 when_eq(vec4 x, vec4 y) { 17 | return 1.0 - abs(sign(x - y)); 18 | } 19 | 20 | vec4 when_neq(vec4 x, vec4 y) { 21 | return abs(sign(x - y)); 22 | } 23 | 24 | vec4 when_gt(vec4 x, vec4 y) { 25 | return max(sign(x - y), 0.0); 26 | } 27 | 28 | vec4 when_lt(vec4 x, vec4 y) { 29 | return max(sign(y - x), 0.0); 30 | } 31 | 32 | vec4 when_ge(vec4 x, vec4 y) { 33 | return 1.0 - when_lt(x, y); 34 | } 35 | 36 | vec4 when_le(vec4 x, vec4 y) { 37 | return 1.0 - when_gt(x, y); 38 | } 39 | 40 | vec4 when_and(vec4 a, vec4 b) { 41 | return a * b; 42 | } 43 | 44 | vec4 when_or(vec4 a, vec4 b) { 45 | return min(a + b, 1.0); 46 | } 47 | 48 | vec4 when_xor(vec4 a, vec4 b) { 49 | return mod(a + b, 2.0); 50 | } 51 | 52 | vec4 when_not(vec4 a) { 53 | return 1.0 - a; 54 | } 55 | -------------------------------------------------------------------------------- /resources/engine/sounds/missing.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/craftablescience/ChiraEngine/ebb306844057a85d37f56b09002f02a5c0d4d894/resources/engine/sounds/missing.wav -------------------------------------------------------------------------------- /resources/engine/textures/black.json: -------------------------------------------------------------------------------- 1 | { 2 | "verticalFlip": true, 3 | "mipmaps": false, 4 | "image": "file://textures/black.png", 5 | "wrapModeS": "REPEAT", 6 | "wrapModeT": "REPEAT", 7 | "filterMode": "LINEAR" 8 | } 9 | -------------------------------------------------------------------------------- /resources/engine/textures/black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/craftablescience/ChiraEngine/ebb306844057a85d37f56b09002f02a5c0d4d894/resources/engine/textures/black.png -------------------------------------------------------------------------------- /resources/engine/textures/missing.json: -------------------------------------------------------------------------------- 1 | { 2 | "verticalFlip": true, 3 | "mipmaps": true, 4 | "image": "file://textures/missing.png", 5 | "wrapModeS": "REPEAT", 6 | "wrapModeT": "REPEAT", 7 | "filterMode": "LINEAR" 8 | } 9 | -------------------------------------------------------------------------------- /resources/engine/textures/missing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/craftablescience/ChiraEngine/ebb306844057a85d37f56b09002f02a5c0d4d894/resources/engine/textures/missing.png -------------------------------------------------------------------------------- /resources/engine/textures/missingSkybox.json: -------------------------------------------------------------------------------- 1 | { 2 | "verticalFlipFD": true, 3 | "verticalFlipBK": true, 4 | "verticalFlipUP": true, 5 | "verticalFlipDN": true, 6 | "verticalFlipLT": true, 7 | "verticalFlipRT": true, 8 | "mipmaps": true, 9 | "imageFD": "file://textures/missing.png", 10 | "imageBK": "file://textures/missing.png", 11 | "imageUP": "file://textures/missing.png", 12 | "imageDN": "file://textures/missing.png", 13 | "imageLT": "file://textures/missing.png", 14 | "imageRT": "file://textures/missing.png", 15 | "wrapModeS": "REPEAT", 16 | "wrapModeT": "REPEAT", 17 | "wrapModeR": "REPEAT", 18 | "filterMode": "LINEAR" 19 | } 20 | -------------------------------------------------------------------------------- /resources/engine/textures/ui/icon.json: -------------------------------------------------------------------------------- 1 | { 2 | "verticalFlip": false, 3 | "mipmaps": false, 4 | "image": "file://textures/ui/icon.png", 5 | "wrapModeS": "REPEAT", 6 | "wrapModeT": "REPEAT", 7 | "filterMode": "LINEAR" 8 | } 9 | -------------------------------------------------------------------------------- /resources/engine/textures/ui/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/craftablescience/ChiraEngine/ebb306844057a85d37f56b09002f02a5c0d4d894/resources/engine/textures/ui/icon.png -------------------------------------------------------------------------------- /resources/engine/textures/ui/splashscreen.json: -------------------------------------------------------------------------------- 1 | { 2 | "verticalFlip": true, 3 | "mipmaps": false, 4 | "image": "file://textures/ui/splashscreen.png", 5 | "wrapModeS": "REPEAT", 6 | "wrapModeT": "REPEAT", 7 | "filterMode": "LINEAR" 8 | } 9 | -------------------------------------------------------------------------------- /resources/engine/textures/ui/splashscreen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/craftablescience/ChiraEngine/ebb306844057a85d37f56b09002f02a5c0d4d894/resources/engine/textures/ui/splashscreen.png -------------------------------------------------------------------------------- /resources/tests/string_resource_test.txt: -------------------------------------------------------------------------------- 1 | test -------------------------------------------------------------------------------- /tests/TestHelpers.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #define PREINIT_ENGINE() \ 8 | const char* argv[] = {"ChiraTest"}; \ 9 | chira::Engine::preinit(sizeof(argv) / sizeof(argv[0]), argv); \ 10 | chira::Resource::addResourceProvider(new chira::FilesystemResourceProvider{"tests"}) 11 | 12 | #define PREINIT_ENGINE_WITH_ARGS(argv) \ 13 | chira::Engine::preinit(sizeof(argv) / sizeof((argv)[0]), argv); \ 14 | chira::Resource::addResourceProvider(new chira::FilesystemResourceProvider{"tests"}) 15 | 16 | #define LOG_BEGIN() \ 17 | std::vector logMessageTypes; \ 18 | std::vector logMessageSources; \ 19 | std::vector logMessageMessages; \ 20 | uuids::uuid logMessageID = chira::Logger::addCallback( \ 21 | [&logMessageTypes, &logMessageSources, &logMessageMessages] \ 22 | (chira::LogType type, std::string_view source, std::string_view message) { \ 23 | logMessageTypes.push_back(type); \ 24 | logMessageSources.emplace_back(source.data()); \ 25 | logMessageMessages.emplace_back(message.data()); \ 26 | }); \ 27 | logMessageTypes.push_back(chira::LogType::LOG_ERROR); \ 28 | logMessageSources.emplace_back(""); \ 29 | logMessageMessages.emplace_back("") 30 | 31 | #define LOG_TYPES_LIST logMessageTypes 32 | #define LOG_SOURCES_LIST logMessageTypes 33 | #define LOG_MESSAGES_LIST logMessageTypes 34 | 35 | #define LOG_IS_NOT_EMPTY !logMessageMessages.empty() 36 | 37 | #define LOG_LAST_TYPE logMessageTypes[logMessageTypes.size() - 1] 38 | #define LOG_LAST_SOURCE logMessageSources[logMessageSources.size() - 1].c_str() 39 | #define LOG_LAST_MESSAGE logMessageMessages[logMessageMessages.size() - 1].c_str() 40 | 41 | #define LOG_HAS_TYPE(t) \ 42 | [&] { \ 43 | bool exists = false; \ 44 | for (const auto& type : logMessageTypes) { \ 45 | if (type == (t)) exists = true; \ 46 | } \ 47 | return exists; \ 48 | }() 49 | 50 | #define LOG_HAS_SOURCE(s) \ 51 | [&] { \ 52 | bool exists = false; \ 53 | for (const auto& src : logMessageSources) { \ 54 | if (src == (s)) exists = true; \ 55 | } \ 56 | return exists; \ 57 | }() 58 | 59 | #define LOG_HAS_MESSAGE(m) \ 60 | [&] { \ 61 | bool exists = false; \ 62 | for (const auto& msg : logMessageMessages) { \ 63 | if (msg == (m)) exists = true; \ 64 | } \ 65 | return exists; \ 66 | }() 67 | 68 | #define LOG_CLEAR() \ 69 | logMessageTypes.clear(); \ 70 | logMessageSources.clear(); \ 71 | logMessageMessages.clear() 72 | 73 | #define LOG_END() \ 74 | chira::Logger::removeCallback(logMessageID) 75 | -------------------------------------------------------------------------------- /tests/engine/core/CommandLine.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | 6 | using namespace chira; 7 | 8 | TEST(CommandLine, has) { 9 | const char* argv[] = {"ChiraTest", "-foo"}; 10 | PREINIT_ENGINE_WITH_ARGS(argv); 11 | 12 | EXPECT_TRUE(CommandLine::has("-foo")); 13 | EXPECT_FALSE(CommandLine::has("-bar")); 14 | } 15 | 16 | TEST(CommandLine, get) { 17 | const char* argv[] = {"ChiraTest", "-foo", "bar"}; 18 | PREINIT_ENGINE_WITH_ARGS(argv); 19 | 20 | EXPECT_TRUE(CommandLine::has("-foo")); 21 | EXPECT_TRUE(CommandLine::has("bar")); 22 | EXPECT_STREQ(CommandLine::get("-foo").data(), "bar"); 23 | } 24 | 25 | TEST(CommandLine, getProgramName) { 26 | const char* argv[] = {"ChiraTest"}; 27 | PREINIT_ENGINE_WITH_ARGS(argv); 28 | 29 | EXPECT_FALSE(CommandLine::has("ChiraTest")); 30 | EXPECT_STREQ(CommandLine::getProgramName().data(), "ChiraTest"); 31 | } 32 | -------------------------------------------------------------------------------- /tests/engine/math/GraphTest.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | 6 | using namespace chira; 7 | 8 | TEST(UnweightedDirectedGraph, addAndRemoveNodes) { 9 | UnweightedDirectedGraph graph; 10 | 11 | auto* a = graph.addNode("a"); 12 | graph.addNode("b"); 13 | EXPECT_EQ(graph.getNodes().size(), 2); 14 | 15 | graph.removeNode(&a); 16 | EXPECT_EQ(graph.getNodes().size(), 1); 17 | EXPECT_EQ(a, nullptr); 18 | } 19 | -------------------------------------------------------------------------------- /tests/engine/resource/provider/FilesystemResourceProviderTest.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | 6 | using namespace chira; 7 | 8 | TEST(FilesystemResourceProvider, getStringResource) { 9 | PREINIT_ENGINE(); 10 | 11 | auto missing = Resource::getResource("file://string_resource_test.txt"); 12 | EXPECT_EQ(missing.useCount(), 2); 13 | EXPECT_STREQ(missing->getString().c_str(), "test"); 14 | Resource::removeResource(missing->getIdentifier().data()); 15 | Resource::discardAll(); 16 | } 17 | 18 | TEST(FilesystemResourceProvider, getResourceIdentifier) { 19 | auto path1 = FilesystemResourceProvider::getResourceIdentifier(R"(C:\this\is\a\path\)" + FILESYSTEM_ROOT_FOLDER + R"(\test\files\file.txt)"); 20 | EXPECT_STREQ(path1.c_str(), (FILESYSTEM_PROVIDER_NAME + RESOURCE_ID_SEPARATOR.data() + "files/file.txt").c_str()); 21 | 22 | auto path2 = FilesystemResourceProvider::getResourceIdentifier("/this/is/a/path/" + FILESYSTEM_ROOT_FOLDER + "/test/files/file.txt"); 23 | EXPECT_STREQ(path2.c_str(), (FILESYSTEM_PROVIDER_NAME + RESOURCE_ID_SEPARATOR.data() + "files/file.txt").c_str()); 24 | 25 | auto path3 = FilesystemResourceProvider::getResourceIdentifier(R"(C:\this\is\not\a\valid\path\file.txt)"); 26 | EXPECT_STREQ(path3.c_str(), ""); 27 | 28 | auto path4 = FilesystemResourceProvider::getResourceIdentifier("/this/is/not/a/valid/path/file.txt"); 29 | EXPECT_STREQ(path4.c_str(), ""); 30 | } 31 | -------------------------------------------------------------------------------- /tests/engine/ui/debug/ConsolePanelTest.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | 6 | using namespace chira; 7 | 8 | TEST(ConsolePanel, printConEntry) { 9 | LOG_BEGIN(); 10 | 11 | ConCommand my_concommand{"my_concommand", "hi", [] {}}; 12 | ASSERT_TRUE(ConEntryRegistry::hasConCommand("my_concommand")); 13 | 14 | ASSERT_TRUE(ConEntryRegistry::hasConCommand("con_entries")); 15 | ConEntryRegistry::getConCommand("con_entries")->fire({}); 16 | 17 | ASSERT_TRUE(LOG_HAS_MESSAGE("my_concommand - hi")); 18 | 19 | LOG_END(); 20 | } 21 | 22 | TEST(ConsolePanel, hiddenConEntry) { 23 | LOG_BEGIN(); 24 | 25 | ConCommand my_hidden_concommand{"my_hidden_concommand", "hi", [] {}, CON_FLAG_HIDDEN}; 26 | ASSERT_TRUE(ConEntryRegistry::hasConCommand("my_hidden_concommand")); 27 | 28 | ASSERT_TRUE(ConEntryRegistry::hasConCommand("con_entries")); 29 | ConEntryRegistry::getConCommand("con_entries")->fire({}); 30 | 31 | ASSERT_FALSE(LOG_HAS_MESSAGE("my_hidden_concommand - hi")); 32 | 33 | LOG_END(); 34 | } 35 | -------------------------------------------------------------------------------- /tests/engine/utility/ConceptsTest.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | using namespace chira; 6 | 7 | TEST(Concepts, arithmetic) { 8 | EXPECT_TRUE(CArithmetic); 9 | EXPECT_TRUE(CArithmetic); 10 | EXPECT_TRUE(CArithmetic); 11 | 12 | EXPECT_FALSE(CNonArithmetic); 13 | EXPECT_FALSE(CNonArithmetic); 14 | EXPECT_FALSE(CNonArithmetic); 15 | } 16 | -------------------------------------------------------------------------------- /tests/engine/utility/UUIDGeneratorTest.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | using namespace chira; 6 | 7 | TEST(UUIDGenerator, getNewUUID) { 8 | EXPECT_FALSE(UUIDGenerator::getNewUUID().is_nil()); 9 | } 10 | 11 | TEST(UUIDGenerator, getNewUUIDString) { 12 | EXPECT_EQ(UUIDGenerator::getNewUUIDString().length(), 36); 13 | } 14 | -------------------------------------------------------------------------------- /tests/tests.cmake: -------------------------------------------------------------------------------- 1 | list(APPEND CHIRA_TEST_SOURCES 2 | ${CMAKE_CURRENT_LIST_DIR}/TestHelpers.h 3 | ${CMAKE_CURRENT_LIST_DIR}/engine/config/ConEntryTest.cpp 4 | ${CMAKE_CURRENT_LIST_DIR}/engine/core/CommandLine.cpp 5 | ${CMAKE_CURRENT_LIST_DIR}/engine/math/GraphTest.cpp 6 | ${CMAKE_CURRENT_LIST_DIR}/engine/resource/provider/FilesystemResourceProviderTest.cpp 7 | ${CMAKE_CURRENT_LIST_DIR}/engine/ui/debug/ConsolePanelTest.cpp 8 | ${CMAKE_CURRENT_LIST_DIR}/engine/utility/ConceptsTest.cpp 9 | ${CMAKE_CURRENT_LIST_DIR}/engine/utility/DependencyGraphTest.cpp 10 | ${CMAKE_CURRENT_LIST_DIR}/engine/utility/StringTest.cpp 11 | ${CMAKE_CURRENT_LIST_DIR}/engine/utility/TypeStringTest.cpp 12 | ${CMAKE_CURRENT_LIST_DIR}/engine/utility/UUIDGeneratorTest.cpp) 13 | 14 | FetchContent_Declare( 15 | googletest 16 | GIT_REPOSITORY https://github.com/google/googletest.git 17 | GIT_TAG release-1.12.1) 18 | FetchContent_MakeAvailable(googletest) 19 | enable_testing() 20 | 21 | set(CHIRA_TEST_NAME "ChiraTest") 22 | add_executable(${CHIRA_TEST_NAME} ${CHIRA_TEST_SOURCES}) 23 | target_link_libraries(${CHIRA_TEST_NAME} PUBLIC ${CHIRA_ENGINE_NAME} gtest_main) 24 | target_include_directories(${CHIRA_TEST_NAME} PRIVATE ${CMAKE_CURRENT_LIST_DIR}) 25 | 26 | include(GoogleTest) 27 | gtest_discover_tests(${CHIRA_TEST_NAME}) 28 | -------------------------------------------------------------------------------- /tools/ToolHelpers.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #define CHIRA_SETUP_CLI_TOOL(name, version, helpText) \ 8 | CHIRA_CREATE_LOG(name); \ 9 | static void printHelp() { \ 10 | LOG_##name.infoImportant( \ 11 | "\n" #name " v" version "\n" helpText \ 12 | ); \ 13 | } \ 14 | constexpr std::string_view name##_VERSION = version 15 | 16 | #ifndef CHIRA_PLATFORM_WINDOWS 17 | #define CHIRA_SETUP_GUI_TOOL(name) \ 18 | CHIRA_CREATE_LOG(name) 19 | #else 20 | // Use the best available GPU on Windows 21 | #define CHIRA_SETUP_GUI_TOOL(name) \ 22 | extern "C" { \ 23 | [[maybe_unused]] \ 24 | __declspec(dllexport) unsigned long NvOptimusEnablement = 0x01; \ 25 | [[maybe_unused]] \ 26 | __declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 0x01; \ 27 | } \ 28 | CHIRA_CREATE_LOG(name) 29 | #endif 30 | -------------------------------------------------------------------------------- /tools/cmdltool/README.md: -------------------------------------------------------------------------------- 1 | # CMDLTool 2 | Command line utility for converting compatible meshes to the CMDL format. 3 | 4 | **Parameters:** 5 | ``` 6 | -h : Display a help message 7 | -i