├── .gitignore ├── .gitmodules ├── .vscode └── settings.json ├── LICENSE ├── README.md ├── assets ├── icons │ └── filetypes │ │ ├── BMP.png │ │ ├── CSV.png │ │ ├── DEFAULT.png │ │ ├── DOC.png │ │ ├── DOXC.png │ │ ├── GIF.png │ │ ├── JPEG.png │ │ ├── JPG.png │ │ ├── PDF.png │ │ ├── PNG.png │ │ ├── PPTX.png │ │ ├── RAR.png │ │ ├── XLS.png │ │ ├── XLSX.png │ │ ├── ZIP.png │ │ ├── folder.png │ │ └── folder_up.png └── shaders │ ├── basic │ ├── fs_basic.glsl │ ├── varying.def.glsl │ └── vs_basic.glsl │ └── common │ ├── bgfx_compute.glsl │ ├── bgfx_shader.glsl │ ├── common.glsl │ └── shaderlib.glsl ├── code_metrices.exe ├── docs ├── Makefile ├── building.rst ├── conf.py ├── design.rst ├── index.rst ├── make.bat └── requirements.txt ├── include ├── ari │ ├── Delegate.hpp │ ├── Engine.hpp │ ├── JsonCast.h │ ├── JsonCast.inl │ ├── Plugin.hpp │ ├── PluginManager.hpp │ ├── Program.hpp │ ├── Resource.hpp │ ├── ResourceLoader.hpp │ ├── ResourceManager.hpp │ ├── StringCast.h │ ├── aridef.hpp │ ├── en │ │ ├── 2d │ │ │ └── Viewport.hpp │ │ ├── 3d │ │ │ ├── BoxShape.hpp │ │ │ ├── Camera.hpp │ │ │ ├── Node3D.hpp │ │ │ ├── RenderSystem.hpp │ │ │ └── SceneSystem.hpp │ │ ├── Component.hpp │ │ ├── Entity.hpp │ │ ├── EventSubscriber.hpp │ │ ├── Node.hpp │ │ ├── System.hpp │ │ ├── World.hpp │ │ ├── WorldManager.hpp │ │ └── gui │ │ │ ├── Button.hpp │ │ │ ├── CheckBox.hpp │ │ │ ├── Dock.hpp │ │ │ ├── DockSpace.hpp │ │ │ ├── DockableWindow.hpp │ │ │ ├── Gui.hpp │ │ │ ├── GuiSystem.hpp │ │ │ ├── Image.hpp │ │ │ ├── Label.hpp │ │ │ ├── Popup.hpp │ │ │ ├── TextBox.hpp │ │ │ └── Window.hpp │ ├── gfx │ │ ├── FrameData.hpp │ │ ├── Texture.hpp │ │ ├── TextureManager.hpp │ │ └── Vertices.hpp │ ├── io │ │ ├── Input.hpp │ │ ├── IoEnums.hpp │ │ ├── IoEvents.hpp │ │ └── PlatformWindow.hpp │ └── math │ │ ├── Matrix.hpp │ │ ├── Rect.hpp │ │ ├── Vector.hpp │ │ └── arimath.hpp └── shiva │ ├── DirectoryTree.hpp │ ├── Editor.hpp │ ├── EditorSettings.hpp │ ├── Project.hpp │ ├── shivadef.hpp │ └── windows │ ├── AssetBrowser.hpp │ ├── DockWindow.hpp │ ├── EditorWindowManager.hpp │ ├── PIE.hpp │ ├── ProjectBrowser.hpp │ ├── PropertyEditor.hpp │ ├── Tools.hpp │ └── Viewport.hpp ├── scripts ├── ariengine.lua ├── genie.lua ├── plugins.lua └── shivaeditor.lua └── src ├── editor ├── DirectoryTree.cpp ├── Editor.cpp ├── EditorSettings.cpp ├── Project.cpp ├── main.cpp └── windows │ ├── AssetBrowser.cpp │ ├── AssetGui.cpp │ ├── AssetGui.hpp │ ├── DockWindow.cpp │ ├── EditorWindowManager.cpp │ ├── ProjectBrowser.cpp │ ├── PropertyEditor.cpp │ └── Viewport.cpp ├── engine ├── Engine.cpp ├── PluginManager.cpp ├── ResourceLoader.cpp ├── StringCast.cpp ├── en │ ├── 3d │ │ ├── BoxShape.cpp │ │ ├── Camera.cpp │ │ ├── RenderSystem.cpp │ │ └── SceneSystem.cpp │ ├── Component.cpp │ ├── Entity.cpp │ ├── Node.cpp │ ├── World.cpp │ └── gui │ │ ├── Button.cpp │ │ ├── CheckBox.cpp │ │ ├── Dock.cpp │ │ ├── DockSpace.cpp │ │ ├── DockableWindow.cpp │ │ ├── GuiSystem.cpp │ │ ├── Image.cpp │ │ ├── Imw │ │ ├── ImwPlatformWindowAri.cpp │ │ ├── ImwPlatformWindowAri.hpp │ │ ├── ImwWindowManagerAri.cpp │ │ └── ImwWindowManagerAri.hpp │ │ ├── Label.cpp │ │ ├── Popup.cpp │ │ ├── TextBox.cpp │ │ └── Window.cpp ├── gfx │ ├── ShadersCode.hpp │ ├── Texture.cpp │ └── TextureManager.cpp ├── io │ ├── Input.cpp │ ├── IoEvents.cpp │ ├── PlatformWindow.cpp │ ├── SdlWindow.cpp │ ├── SdlWindow.hpp │ ├── WindowWin32.cpp │ └── WindowWin32.hpp ├── main.cpp └── math │ └── Matrix.cpp ├── plugins └── bimg │ ├── BimgLoader.cpp │ ├── BimgLoader.hpp │ └── bimgPlugin.cpp └── shiva └── main.cpp /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | *.obj 9 | 10 | # Precompiled Headers 11 | *.gch 12 | *.pch 13 | 14 | # Compiled Dynamic libraries 15 | *.so 16 | *.dylib 17 | *.dll 18 | 19 | # Fortran module files 20 | *.mod 21 | *.smod 22 | 23 | # Compiled Static libraries 24 | *.lai 25 | *.la 26 | *.a 27 | *.lib 28 | 29 | # Executables 30 | *.exe 31 | *.out 32 | *.app 33 | 34 | # docs 35 | *.doctree 36 | *.pickle 37 | 38 | # Folders 39 | /_build/ 40 | .build/ 41 | docs/api 42 | docs/doctrees 43 | docs/doxyoutput 44 | docs/html -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "deps/bx"] 2 | path = deps/bx 3 | url = https://github.com/kochol/bx.git 4 | [submodule "deps/bimg"] 5 | path = deps/bimg 6 | url = https://github.com/kochol/bimg.git 7 | [submodule "deps/bgfx"] 8 | path = deps/bgfx 9 | url = https://github.com/kochol/bgfx.git 10 | [submodule "deps/arideps"] 11 | path = deps/arideps 12 | url = https://github.com/kochol/arideps.git 13 | [submodule "deps/spdlog"] 14 | path = deps/spdlog 15 | url = https://github.com/gabime/spdlog.git 16 | [submodule "tests"] 17 | path = tests 18 | url = https://github.com/kochol/ariyana_tests.git 19 | [submodule "deps/brtshaderc"] 20 | path = deps/brtshaderc 21 | url = https://github.com/kochol/brtshaderc.git 22 | [submodule "deps/MetaStuff"] 23 | path = deps/MetaStuff 24 | url = https://github.com/eliasdaler/MetaStuff.git 25 | [submodule "deps/imguiDock"] 26 | path = deps/imguiDock 27 | url = https://github.com/kochol/imguiDock.git 28 | [submodule "deps/ImWindow"] 29 | path = deps/ImWindow 30 | url = https://github.com/kochol/ImWindow.git 31 | [submodule "deps/cr"] 32 | path = deps/cr 33 | url = https://github.com/kochol/cr.git 34 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "restructuredtext.confPath": "${workspaceFolder}\\docs", 3 | "files.associations": { 4 | "xmemory0": "cpp", 5 | "memory": "cpp", 6 | "mutex": "cpp", 7 | "atomic": "cpp", 8 | "xxatomic": "cpp" 9 | } 10 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Ali Akbar Mohammadi 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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Ariyana 2 | 3 | [![Contribute!](https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat)](https://github.com/kochol/ariyana/issues) 4 | [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/kochol/ariyana/blob/master/LICENSE) 5 | 6 | Ariyana is a WIP game engine that is planned to include these features. 7 | 8 | ## Planned features 9 | 10 | - Cross-platform 11 | - Windows 12 | - Linux 13 | - Android 14 | - Fast 15 | - I try to make the engine easy to use but the performance is the high priority, There are many easy to use engine out there already. 16 | - Using fibers to jobify the engine 17 | - Using frame buffers that is introduced in GDC talk by Christian Gyrling in his 2015 GDC Talk 'Parallelizing the Naughty Dog Engine Using Fibers' 18 | - Entity component system 19 | - Editor 20 | - Easy to use 21 | - Animate every thing 22 | - Json save and load for easy team support and Git. 23 | 24 | ## How to build 25 | https://github.com/kochol/ariyana/blob/master/docs/building.rst 26 | 27 | ## Dependencies 28 | 29 | - [bgfx](https://github.com/bkaradzic/bgfx) rendering library 30 | - [bimg](https://github.com/bkaradzic/bimg) image library 31 | - [bx](https://github.com/bkaradzic/bx) core library 32 | - [brtshaderc](https://github.com/fredakilla/brtshaderc) runtime shader compiler for bgfx 33 | - [dear imgui](https://github.com/ocornut/imgui) gui library 34 | - [imwindow](https://github.com/thennequin/ImWindow) window docking library for imgui 35 | - [MetaStuff](https://github.com/eliasdaler/MetaStuff) serialization/deserialization/introspection stuff 36 | - [spdlog](https://github.com/gabime/spdlog) Fast c++ logging library 37 | -------------------------------------------------------------------------------- /assets/icons/filetypes/BMP.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kochol/ariyana_old/efdd20eea0f1fafa803fb254d4775aa1915ba3a1/assets/icons/filetypes/BMP.png -------------------------------------------------------------------------------- /assets/icons/filetypes/CSV.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kochol/ariyana_old/efdd20eea0f1fafa803fb254d4775aa1915ba3a1/assets/icons/filetypes/CSV.png -------------------------------------------------------------------------------- /assets/icons/filetypes/DEFAULT.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kochol/ariyana_old/efdd20eea0f1fafa803fb254d4775aa1915ba3a1/assets/icons/filetypes/DEFAULT.png -------------------------------------------------------------------------------- /assets/icons/filetypes/DOC.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kochol/ariyana_old/efdd20eea0f1fafa803fb254d4775aa1915ba3a1/assets/icons/filetypes/DOC.png -------------------------------------------------------------------------------- /assets/icons/filetypes/DOXC.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kochol/ariyana_old/efdd20eea0f1fafa803fb254d4775aa1915ba3a1/assets/icons/filetypes/DOXC.png -------------------------------------------------------------------------------- /assets/icons/filetypes/GIF.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kochol/ariyana_old/efdd20eea0f1fafa803fb254d4775aa1915ba3a1/assets/icons/filetypes/GIF.png -------------------------------------------------------------------------------- /assets/icons/filetypes/JPEG.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kochol/ariyana_old/efdd20eea0f1fafa803fb254d4775aa1915ba3a1/assets/icons/filetypes/JPEG.png -------------------------------------------------------------------------------- /assets/icons/filetypes/JPG.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kochol/ariyana_old/efdd20eea0f1fafa803fb254d4775aa1915ba3a1/assets/icons/filetypes/JPG.png -------------------------------------------------------------------------------- /assets/icons/filetypes/PDF.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kochol/ariyana_old/efdd20eea0f1fafa803fb254d4775aa1915ba3a1/assets/icons/filetypes/PDF.png -------------------------------------------------------------------------------- /assets/icons/filetypes/PNG.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kochol/ariyana_old/efdd20eea0f1fafa803fb254d4775aa1915ba3a1/assets/icons/filetypes/PNG.png -------------------------------------------------------------------------------- /assets/icons/filetypes/PPTX.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kochol/ariyana_old/efdd20eea0f1fafa803fb254d4775aa1915ba3a1/assets/icons/filetypes/PPTX.png -------------------------------------------------------------------------------- /assets/icons/filetypes/RAR.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kochol/ariyana_old/efdd20eea0f1fafa803fb254d4775aa1915ba3a1/assets/icons/filetypes/RAR.png -------------------------------------------------------------------------------- /assets/icons/filetypes/XLS.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kochol/ariyana_old/efdd20eea0f1fafa803fb254d4775aa1915ba3a1/assets/icons/filetypes/XLS.png -------------------------------------------------------------------------------- /assets/icons/filetypes/XLSX.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kochol/ariyana_old/efdd20eea0f1fafa803fb254d4775aa1915ba3a1/assets/icons/filetypes/XLSX.png -------------------------------------------------------------------------------- /assets/icons/filetypes/ZIP.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kochol/ariyana_old/efdd20eea0f1fafa803fb254d4775aa1915ba3a1/assets/icons/filetypes/ZIP.png -------------------------------------------------------------------------------- /assets/icons/filetypes/folder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kochol/ariyana_old/efdd20eea0f1fafa803fb254d4775aa1915ba3a1/assets/icons/filetypes/folder.png -------------------------------------------------------------------------------- /assets/icons/filetypes/folder_up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kochol/ariyana_old/efdd20eea0f1fafa803fb254d4775aa1915ba3a1/assets/icons/filetypes/folder_up.png -------------------------------------------------------------------------------- /assets/shaders/basic/fs_basic.glsl: -------------------------------------------------------------------------------- 1 | $input v_color0 2 | 3 | /* 4 | * Copyright 2011-2018 Branimir Karadzic. All rights reserved. 5 | * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause 6 | */ 7 | 8 | #include "../common/common.glsl" 9 | 10 | void main() 11 | { 12 | gl_FragColor = v_color0; 13 | } 14 | -------------------------------------------------------------------------------- /assets/shaders/basic/varying.def.glsl: -------------------------------------------------------------------------------- 1 | vec4 v_color0 : COLOR0 = vec4(1.0, 0.0, 0.0, 1.0); 2 | 3 | vec3 a_position : POSITION; 4 | vec4 a_color0 : COLOR0; 5 | -------------------------------------------------------------------------------- /assets/shaders/basic/vs_basic.glsl: -------------------------------------------------------------------------------- 1 | $input a_position, a_color0 2 | $output v_color0 3 | 4 | /* 5 | * Copyright 2011-2018 Branimir Karadzic. All rights reserved. 6 | * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause 7 | */ 8 | 9 | #include "../common/common.glsl" 10 | 11 | void main() 12 | { 13 | gl_Position = mul(u_modelViewProj, vec4(a_position, 1.0) ); 14 | v_color0 = a_color0; 15 | } 16 | -------------------------------------------------------------------------------- /assets/shaders/common/common.glsl: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011-2018 Branimir Karadzic. All rights reserved. 3 | * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause 4 | */ 5 | 6 | #include "bgfx_shader.glsl" 7 | #include "shaderlib.glsl" 8 | -------------------------------------------------------------------------------- /code_metrices.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kochol/ariyana_old/efdd20eea0f1fafa803fb254d4775aa1915ba3a1/code_metrices.exe -------------------------------------------------------------------------------- /docs/Makefile: -------------------------------------------------------------------------------- 1 | # Minimal makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line. 5 | SPHINXOPTS = 6 | SPHINXBUILD = sphinx-build 7 | SPHINXPROJ = Ariyana 8 | SOURCEDIR = . 9 | BUILDDIR = _build 10 | 11 | # Put it first so that "make" without argument is like "make help". 12 | help: 13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 14 | 15 | .PHONY: help Makefile 16 | 17 | # Catch-all target: route all unknown targets to Sphinx using the new 18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). 19 | %: Makefile 20 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) -------------------------------------------------------------------------------- /docs/building.rst: -------------------------------------------------------------------------------- 1 | Building 2 | ======== 3 | 4 | Getting Source 5 | -------------- 6 | 7 | .. code-block:: shell 8 | 9 | git clone https://github.com/kochol/ariyana.git 10 | cd ariyana 11 | git submodule update --init 12 | 13 | Quick Start 14 | ----------- 15 | 16 | These are step for users who use Windows with Visual Studio. 17 | 18 | Enter ariyana directory: 19 | 20 | .. code-block:: shell 21 | 22 | cd ariyana 23 | 24 | Generate Visual Studio 2017 project files: 25 | 26 | .. code-block:: shell 27 | 28 | deps\bx\tools\bin\windows\genie vs2017 29 | 30 | Open ariyana solution in Visual Studio 2017: 31 | 32 | .. code-block:: shell 33 | 34 | start .build\projects\vs2017\ariyana.sln 35 | 36 | Generate Visual Studio 2017 project files with test projects: 37 | 38 | .. code-block:: shell 39 | 40 | deps\bx\tools\bin\windows\genie --with-tests vs2017 41 | -------------------------------------------------------------------------------- /docs/conf.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # Configuration file for the Sphinx documentation builder. 4 | # 5 | # This file does only contain a selection of the most common options. For a 6 | # full list see the documentation: 7 | # http://www.sphinx-doc.org/en/master/config 8 | 9 | # -- Path setup -------------------------------------------------------------- 10 | 11 | # If extensions (or modules to document with autodoc) are in another directory, 12 | # add these directories to sys.path here. If the directory is relative to the 13 | # documentation root, use os.path.abspath to make it absolute, like shown here. 14 | # 15 | # import os 16 | # import sys 17 | # sys.path.insert(0, os.path.abspath('.')) 18 | 19 | 20 | # -- Project information ----------------------------------------------------- 21 | 22 | project = u'Ariyana' 23 | copyright = u'2018, Ali Akbar Mohammadi' 24 | author = u'Ali Akbar Mohammadi' 25 | 26 | # The short X.Y version 27 | version = u'0.1' 28 | # The full version, including alpha/beta/rc tags 29 | release = u'0.1' 30 | 31 | 32 | # -- General configuration --------------------------------------------------- 33 | 34 | # If your documentation needs a minimal Sphinx version, state it here. 35 | # 36 | # needs_sphinx = '1.0' 37 | 38 | # Add any Sphinx extension module names here, as strings. They can be 39 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom 40 | # ones. 41 | extensions = [ 42 | 'sphinx.ext.intersphinx', 43 | 'sphinx.ext.todo', 44 | 'sphinx.ext.githubpages', 45 | 'breathe', 46 | 'exhale' 47 | ] 48 | 49 | # Setup the breathe extension 50 | breathe_projects = { 51 | 'Ariyana engine': 'doxyoutput/xml' 52 | } 53 | breathe_default_project = "Ariyana engine" 54 | 55 | # Setup the exhale extension 56 | exhale_args = { 57 | # These arguments are required 58 | "containmentFolder": "./api", 59 | "rootFileName": "library_root.rst", 60 | "rootFileTitle": "API Reference", 61 | "doxygenStripFromPath": "..", 62 | # Suggested optional arguments 63 | "createTreeView": True, 64 | # TIP: if using the sphinx-bootstrap-theme, you need 65 | # "treeViewIsBootstrap": True, 66 | "exhaleExecutesDoxygen": True, 67 | "exhaleDoxygenStdin": "INPUT = ../include" 68 | } 69 | 70 | # Tell sphinx what the primary language being documented is. 71 | primary_domain = 'cpp' 72 | 73 | # Tell sphinx what the pygments highlight language should be. 74 | highlight_language = 'cpp' 75 | 76 | # Add any paths that contain templates here, relative to this directory. 77 | templates_path = ['_templates'] 78 | 79 | # The suffix(es) of source filenames. 80 | # You can specify multiple suffix as a list of string: 81 | # 82 | # source_suffix = ['.rst', '.md'] 83 | source_suffix = '.rst' 84 | 85 | # The master toctree document. 86 | master_doc = 'index' 87 | 88 | # The language for content autogenerated by Sphinx. Refer to documentation 89 | # for a list of supported languages. 90 | # 91 | # This is also used if you do content translation via gettext catalogs. 92 | # Usually you set "language" from the command line for these cases. 93 | language = None 94 | 95 | # List of patterns, relative to source directory, that match files and 96 | # directories to ignore when looking for source files. 97 | # This pattern also affects html_static_path and html_extra_path . 98 | exclude_patterns = [u'_build', 'Thumbs.db', '.DS_Store'] 99 | 100 | # The name of the Pygments (syntax highlighting) style to use. 101 | pygments_style = 'sphinx' 102 | 103 | 104 | # -- Options for HTML output ------------------------------------------------- 105 | 106 | # The theme to use for HTML and HTML Help pages. See the documentation for 107 | # a list of builtin themes. 108 | # 109 | html_theme = 'sphinx_rtd_theme' 110 | 111 | # Theme options are theme-specific and customize the look and feel of a theme 112 | # further. For a list of options available for each theme, see the 113 | # documentation. 114 | # 115 | # html_theme_options = {} 116 | 117 | # Add any paths that contain custom static files (such as style sheets) here, 118 | # relative to this directory. They are copied after the builtin static files, 119 | # so a file named "default.css" will overwrite the builtin "default.css". 120 | html_static_path = ['_static'] 121 | 122 | # Custom sidebar templates, must be a dictionary that maps document names 123 | # to template names. 124 | # 125 | # The default sidebars (for documents that don't match any pattern) are 126 | # defined by theme itself. Builtin themes are using these templates by 127 | # default: ``['localtoc.html', 'relations.html', 'sourcelink.html', 128 | # 'searchbox.html']``. 129 | # 130 | # html_sidebars = {} 131 | 132 | 133 | # -- Options for HTMLHelp output --------------------------------------------- 134 | 135 | # Output file base name for HTML help builder. 136 | htmlhelp_basename = 'Ariyanadoc' 137 | 138 | 139 | # -- Options for LaTeX output ------------------------------------------------ 140 | 141 | latex_elements = { 142 | # The paper size ('letterpaper' or 'a4paper'). 143 | # 144 | # 'papersize': 'letterpaper', 145 | 146 | # The font size ('10pt', '11pt' or '12pt'). 147 | # 148 | # 'pointsize': '10pt', 149 | 150 | # Additional stuff for the LaTeX preamble. 151 | # 152 | # 'preamble': '', 153 | 154 | # Latex figure (float) alignment 155 | # 156 | # 'figure_align': 'htbp', 157 | } 158 | 159 | # Grouping the document tree into LaTeX files. List of tuples 160 | # (source start file, target name, title, 161 | # author, documentclass [howto, manual, or own class]). 162 | latex_documents = [ 163 | (master_doc, 'Ariyana.tex', u'Ariyana Documentation', 164 | u'Ali Akbar Mohammadi', 'manual'), 165 | ] 166 | 167 | 168 | # -- Options for manual page output ------------------------------------------ 169 | 170 | # One entry per manual page. List of tuples 171 | # (source start file, name, description, authors, manual section). 172 | man_pages = [ 173 | (master_doc, 'ariyana', u'Ariyana Documentation', 174 | [author], 1) 175 | ] 176 | 177 | 178 | # -- Options for Texinfo output ---------------------------------------------- 179 | 180 | # Grouping the document tree into Texinfo files. List of tuples 181 | # (source start file, target name, title, author, 182 | # dir menu entry, description, category) 183 | texinfo_documents = [ 184 | (master_doc, 'Ariyana', u'Ariyana Documentation', 185 | author, 'Ariyana', 'One line description of project.', 186 | 'Miscellaneous'), 187 | ] 188 | 189 | 190 | # -- Extension configuration ------------------------------------------------- 191 | 192 | # -- Options for intersphinx extension --------------------------------------- 193 | 194 | # Example configuration for intersphinx: refer to the Python standard library. 195 | intersphinx_mapping = {'https://docs.python.org/': None} 196 | 197 | # -- Options for todo extension ---------------------------------------------- 198 | 199 | # If true, `todo` and `todoList` produce output, else they produce nothing. 200 | todo_include_todos = True -------------------------------------------------------------------------------- /docs/design.rst: -------------------------------------------------------------------------------- 1 | Design goals 2 | ============ 3 | 4 | The goal of this engine design is to make a fast engine. 5 | 6 | Jobify the engine with fibers 7 | ----------------------------- 8 | 9 | The first design goal is using fibers to jobify the engine and use all of the CPU cores. 10 | For more info see 11 | GDC talk by Christian Gyrling in his 2015 GDC Talk 'Parallelizing the Naughty Dog Engine Using Fibers' 12 | 13 | Frame data 14 | ---------- 15 | 16 | Use frame data to enable the parallel work of different parts of the engine without waiting for 17 | each other to finish their job. 18 | For example gameplay systems update entities and send them to scene system then scene system store 19 | them to perform culling and sorting next frame after that sends it to render system for next frame 20 | rendering so rendering is always two frame behind gameplay systems this design makes every thing 21 | works in parallel. 22 | For more info see 23 | GDC talk by Christian Gyrling in his 2015 GDC Talk 'Parallelizing the Naughty Dog Engine Using Fibers' 24 | 25 | For this system to work I made different update stages that be called for every system that needs it. 26 | 27 | Entity, Component and Node 28 | -------------------------- 29 | 30 | This part of the design I got inspired by Godot engine where Components can attach to each other and 31 | creates a tree. 32 | The base class here is Node class that Entity and Component class are inherited from them so Components 33 | can attach to entities and vice versa. 34 | This design works well for example when you work on a project with your colleges and everyone can 35 | work on a different entity without conflict. 36 | 37 | Also, entities are useful when later we add networking to the engine. -------------------------------------------------------------------------------- /docs/index.rst: -------------------------------------------------------------------------------- 1 | .. Ariyana documentation master file, created by 2 | sphinx-quickstart on Tue Jul 10 10:49:18 2018. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | Welcome to Ariyana's documentation! 7 | =================================== 8 | 9 | Ariyana is an open source and free WIP game engine. 10 | 11 | .. toctree:: 12 | :maxdepth: 2 13 | :caption: Contents: 14 | 15 | building 16 | design 17 | api/library_root 18 | 19 | Indices and tables 20 | ================== 21 | 22 | * :ref:`genindex` 23 | -------------------------------------------------------------------------------- /docs/make.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | pushd %~dp0 4 | 5 | REM Command file for Sphinx documentation 6 | 7 | if "%SPHINXBUILD%" == "" ( 8 | set SPHINXBUILD=sphinx-build 9 | ) 10 | set SOURCEDIR=. 11 | set BUILDDIR=..\docs 12 | set SPHINXPROJ=Ariyana 13 | 14 | if "%1" == "" goto help 15 | 16 | %SPHINXBUILD% >NUL 2>NUL 17 | if errorlevel 9009 ( 18 | echo. 19 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx 20 | echo.installed, then set the SPHINXBUILD environment variable to point 21 | echo.to the full path of the 'sphinx-build' executable. Alternatively you 22 | echo.may add the Sphinx directory to PATH. 23 | echo. 24 | echo.If you don't have Sphinx installed, grab it from 25 | echo.http://sphinx-doc.org/ 26 | exit /b 1 27 | ) 28 | 29 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% 30 | goto end 31 | 32 | :help 33 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% 34 | 35 | :end 36 | popd 37 | -------------------------------------------------------------------------------- /docs/requirements.txt: -------------------------------------------------------------------------------- 1 | exhale 2 | -------------------------------------------------------------------------------- /include/ari/Engine.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "aridef.hpp" 3 | #include 4 | #include "io/IoEnums.hpp" 5 | #include "io/PlatformWindow.hpp" 6 | #include "Program.hpp" 7 | #include "PluginManager.hpp" 8 | #include "gfx/TextureManager.hpp" 9 | 10 | namespace bx 11 | { 12 | class Thread; 13 | class Mutex; 14 | } 15 | namespace spdlog 16 | { 17 | class logger; 18 | } 19 | namespace ftl 20 | { 21 | class TaskScheduler; 22 | } 23 | 24 | namespace ari 25 | { 26 | struct Event; 27 | 28 | struct InitParams 29 | { 30 | InitParams(): Height(600), Width(800), FullScreen(false) 31 | {} 32 | 33 | uint32_t Height, 34 | Width; 35 | 36 | bool FullScreen; 37 | IProgram* Program; 38 | 39 | }; // InitParams 40 | 41 | class ARI_API Engine 42 | { 43 | friend class PlatformWindow; 44 | friend class GuiSystem; 45 | public: 46 | 47 | //! Constructor 48 | Engine(); 49 | 50 | //! Destructor 51 | ~Engine(); 52 | 53 | static Engine& GetSingleton(); 54 | 55 | //! Init the engine device 56 | bool Init(InitParams* params); 57 | 58 | bool Run(); 59 | 60 | void LockUpdateThread(); 61 | 62 | void UnlockUpdateThread(); 63 | 64 | Event* Poll(); 65 | 66 | void Release(const Event * _event); 67 | 68 | uint32_t GetCurrentFrameNumber() const { return m_frame_number; } 69 | 70 | std::shared_ptr GetLogger() const { return Logger; } 71 | 72 | InitParams* GetParams() const { return m_params; } 73 | 74 | void SetParams(InitParams* _params) { m_params = _params; } 75 | 76 | PlatformWindow* GetMainWindow() const { return m_pWindow; } 77 | 78 | PlatformWindow* NewWindow(PlatformWindow::Type _type); 79 | 80 | uint16_t GetNewViewId(); 81 | 82 | uint32_t GetMsaaFlags() const; 83 | 84 | float GetElapsedTime() const { return m_fElapsedTime; } 85 | 86 | float GetDeltaTime() const { return m_fDeltaTime; } 87 | 88 | PluginManager plugin_manager; 89 | TextureManager texture_manager; 90 | 91 | protected: 92 | 93 | static int InitBgfxInThread(bx::Thread* _thread, void* _userData); 94 | 95 | InitParams * m_params; 96 | std::shared_ptr Logger; 97 | PlatformWindow * m_pWindow; 98 | uint32_t m_debug, m_reset, m_frame_number; 99 | uint16_t m_viewId = 0; 100 | int64_t m_time_offset; 101 | bx::Thread * m_pGfxThread; 102 | bx::Mutex * m_pMutex = nullptr; 103 | int m_iLockStatus = 0; //! 0 = No action, 1 = Lock, 2 = Unlock the update thread. 104 | ftl::TaskScheduler * m_pTaskMgr; 105 | MouseState m_MouseState; 106 | bool m_bRun; 107 | bool m_bNeedReset; 108 | float m_fElapsedTime = 0.0f, 109 | m_fDeltaTime = 0.0f; 110 | 111 | }; // Engine 112 | 113 | extern ARI_API Engine* g_pEngine; 114 | 115 | } 116 | 117 | -------------------------------------------------------------------------------- /include/ari/JsonCast.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #include 10 | #include "StringCast.h" 11 | 12 | using json = nlohmann::json; 13 | 14 | template 15 | void to_json(json& j, const T& obj); 16 | 17 | template 18 | void from_json(const json& j, T& obj); 19 | 20 | namespace meta 21 | { 22 | 23 | /////////////////// SERIALIZATION 24 | 25 | template ()>> 27 | json serialize(const Class& obj); 28 | 29 | template ()>, 31 | typename = void> 32 | json serialize(const Class& obj); 33 | 34 | template 35 | json serialize_basic(const Class& obj); 36 | 37 | // specialization for std::vector 38 | template 39 | json serialize_basic(const std::vector& obj); 40 | 41 | // specialization for std::unodered_map 42 | template 43 | json serialize_basic(const std::unordered_map& obj); 44 | 45 | 46 | /////////////////// DESERIALIZATION 47 | // 48 | //template 49 | //Class deserialize(const json& obj); 50 | 51 | template ()>> 53 | void deserialize(Class& obj, const json& object); 54 | 55 | template ()>, 57 | typename = void> 58 | void deserialize(Class& obj, const json& object); 59 | 60 | // specialization for std::vector 61 | template 62 | void deserialize(std::vector& obj, const json& object); 63 | 64 | // specialization for std::unodered_map 65 | template 66 | void deserialize(std::unordered_map& obj, const json& object); 67 | 68 | } 69 | 70 | #include "JsonCast.inl" -------------------------------------------------------------------------------- /include/ari/JsonCast.inl: -------------------------------------------------------------------------------- 1 | #include "JsonCast.h" 2 | 3 | template 4 | void to_json(json& j, const T& obj) 5 | { 6 | j = meta::serialize(obj); 7 | } 8 | 9 | template 10 | void from_json(const json& j, T& obj) 11 | { 12 | meta::deserialize(obj, j); 13 | } 14 | 15 | namespace meta 16 | { 17 | 18 | /////////////////// SERIALIZATION 19 | 20 | template 22 | json serialize(const Class& obj) 23 | { 24 | json value; 25 | meta::doForAllMembers( 26 | [&obj, &value](auto& member) 27 | { 28 | auto& valueName = value[member.getName()]; 29 | if (member.canGetConstRef()) { 30 | valueName = member.get(obj); 31 | } else if (member.hasGetter()) { 32 | valueName = member.getCopy(obj); // passing copy as const ref, it's okay 33 | } 34 | } 35 | ); 36 | return value; 37 | } 38 | 39 | template 41 | json serialize(const Class& obj) 42 | { 43 | return serialize_basic(obj); 44 | } 45 | 46 | template 47 | json serialize_basic(const Class& obj) 48 | { 49 | return json(obj); 50 | } 51 | 52 | // specialization for std::vector 53 | template 54 | json serialize_basic(const std::vector& obj) 55 | { 56 | json value; 57 | int i = 0; 58 | for (auto& elem : obj) { 59 | value[i] = elem; 60 | ++i; 61 | } 62 | return value; 63 | } 64 | 65 | // specialization for std::unordered_map 66 | template 67 | json serialize_basic(const std::unordered_map& obj) 68 | { 69 | json value; 70 | for (auto& pair : obj) { 71 | value.emplace(castToString(pair.first), pair.second); 72 | } 73 | return value; 74 | } 75 | 76 | /////////////////// DESERIALIZATION 77 | 78 | template 79 | Class deserialize(const json& obj) 80 | { 81 | Class c; 82 | deserialize(c, obj); 83 | return c; 84 | } 85 | 86 | template 88 | void deserialize(Class& obj, const json& object) 89 | { 90 | if (object.is_object()) { 91 | meta::doForAllMembers( 92 | [&obj, &object](auto& member) 93 | { 94 | auto& objName = object[member.getName()]; 95 | if (!objName.is_null()) { 96 | using MemberT = meta::get_member_type; 97 | if (member.hasSetter()) { 98 | member.set(obj, objName.template get()); 99 | } else if (member.canGetRef()) { 100 | member.getRef(obj) = objName.template get(); 101 | } else { 102 | throw std::runtime_error("Error: can't deserialize member because it's read only"); 103 | } 104 | } 105 | } 106 | ); 107 | } else { 108 | throw std::runtime_error("Error: can't deserialize from Json::json to Class."); 109 | } 110 | } 111 | 112 | template 114 | void deserialize(Class& obj, const json& object) 115 | { 116 | obj = object.get(); 117 | } 118 | 119 | // specialization for std::vector 120 | template 121 | void deserialize(std::vector& obj, const json& object) 122 | { 123 | obj.reserve(object.size()); // vector.resize() works only for default constructible types 124 | for (auto& elem : object) { 125 | obj.push_back(elem); // push rvalue 126 | } 127 | } 128 | 129 | // specialization for std::unodered_map 130 | template 131 | void deserialize(std::unordered_map& obj, const json& object) 132 | { 133 | for (auto it = object.begin(); it != object.end(); ++it) { 134 | obj.emplace(fromString(it.key()), it.value()); 135 | } 136 | } 137 | 138 | } 139 | -------------------------------------------------------------------------------- /include/ari/Plugin.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Resource.hpp" 3 | 4 | namespace ari 5 | { 6 | class Plugin: public Resource 7 | { 8 | public: 9 | 10 | enum class Type 11 | { 12 | TextureLoader, 13 | MeshLoader, 14 | 15 | Unknown 16 | }; 17 | 18 | Plugin(const uint32_t& _handel, const std::string& _fileName) 19 | : Resource(_handel, _fileName) 20 | { 21 | } 22 | 23 | virtual ~Plugin() = default; 24 | 25 | virtual void* Create() = 0; 26 | 27 | protected: 28 | 29 | Type m_eType = Type::Unknown; 30 | 31 | }; // Plugin 32 | 33 | } // ari 34 | -------------------------------------------------------------------------------- /include/ari/PluginManager.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "ResourceManager.hpp" 3 | #include "Plugin.hpp" 4 | #include "aridef.hpp" 5 | 6 | namespace ari 7 | { 8 | class ARI_API PluginManager: public ResourceManager 9 | { 10 | protected: 11 | 12 | bool LoadResource(Plugin** ppOut, uint32_t handle, 13 | const std::string& filename, void* extraParams) override; 14 | 15 | }; 16 | 17 | } // ari 18 | -------------------------------------------------------------------------------- /include/ari/Program.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | namespace ari 5 | { 6 | class IProgram 7 | { 8 | public: 9 | IProgram(const char* programName): m_sProgramName(programName) 10 | { } 11 | 12 | virtual ~IProgram() = default; 13 | 14 | virtual void Init() = 0; 15 | 16 | virtual bool Update(uint32_t frame_number, float elasped) = 0; 17 | 18 | virtual int Shutdown() = 0; 19 | 20 | tinystl::string GetProgramName() const { return m_sProgramName; } 21 | 22 | protected: 23 | 24 | tinystl::string m_sProgramName; 25 | }; 26 | } 27 | -------------------------------------------------------------------------------- /include/ari/Resource.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "aridef.hpp" 4 | 5 | namespace ari 6 | { 7 | class ARI_API Resource 8 | { 9 | template 10 | friend class ResourceManager; 11 | 12 | public: 13 | 14 | Resource(): m_iHandle(0) { } 15 | 16 | Resource(const uint32_t& _handel, const std::string& _fileName): 17 | m_iHandle(_handel), m_sFileName(_fileName) { } 18 | 19 | virtual ~Resource() = default; 20 | 21 | uint32_t GetHandel() const { return m_iHandle; } 22 | 23 | std::string GetFileName() const { return m_sFileName; } 24 | 25 | protected: 26 | 27 | uint32_t m_iHandle; 28 | std::string m_sFileName; 29 | }; 30 | 31 | } // ari 32 | -------------------------------------------------------------------------------- /include/ari/ResourceLoader.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "aridef.hpp" 3 | #include 4 | #include "bx/readerwriter.h" 5 | #include "bx/file.h" 6 | 7 | namespace ari 8 | { 9 | class Resource; 10 | 11 | class ARI_API ResourceLoader 12 | { 13 | public: 14 | 15 | //! Constructor 16 | ResourceLoader() : m_bSwapEndian(false) 17 | {} 18 | 19 | //! Destructor 20 | virtual ~ResourceLoader() = default; 21 | 22 | //! returns true if the file maybe is able to be loaded by this Loader 23 | //! based on the file extension (e.g. ".mesh") 24 | virtual bool IsALoadableFileExtension(std::string _extention); 25 | 26 | //! Loads a resource from a FileSystem and return its pointer. 27 | /*! 28 | \param pStream 29 | \param _extraParams 30 | \return Returns the created resource pointer. Note resource may not loaded yet. 31 | */ 32 | virtual Resource* LoadResource(bx::FileReaderI* pStream, uint32_t _handle, 33 | const std::string& _filename, void* _extraParams) = 0; 34 | 35 | protected: 36 | 37 | std::vector m_aFileExtension; //!< The file extension list that this loader is capable to load 38 | bool m_bSwapEndian; //!< Swap the loaded data or not 39 | 40 | }; 41 | 42 | } // ari 43 | -------------------------------------------------------------------------------- /include/ari/ResourceManager.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | 6 | namespace ari 7 | { 8 | class ResourceLoader; 9 | 10 | template 11 | class ResourceManager 12 | { 13 | public: 14 | 15 | virtual ~ResourceManager() = default; 16 | 17 | std::shared_ptr Load(const std::string& filename, void* extraParams) 18 | { 19 | // Searching for resource. 20 | for (const auto& res: m_vResources) 21 | { 22 | if (res) 23 | { 24 | if (!res->GetFileName().empty() && !filename.empty()) 25 | { 26 | if (res->GetFileName() == filename) 27 | { 28 | return res; 29 | } 30 | } 31 | } 32 | } 33 | 34 | // Resource not loaded yet. 35 | T* pResource = nullptr; 36 | const uint32_t handle = GetNewHandle(); 37 | 38 | if (!LoadResource(&pResource, handle, filename, extraParams)) 39 | return nullptr; 40 | 41 | return AddResource(pResource); 42 | } 43 | 44 | void AddLoader(ResourceLoader* pLoader) 45 | { 46 | m_vLoaders.push_back(pLoader); 47 | } 48 | 49 | uint32_t GetNewHandle() 50 | { 51 | uint32_t handle; 52 | if (!m_sHandles.empty()) 53 | { 54 | handle = m_sHandles.top(); 55 | m_sHandles.pop(); 56 | } 57 | else 58 | { 59 | handle = uint32_t(m_vResources.size()); 60 | } 61 | return handle; 62 | } 63 | 64 | std::shared_ptr AddResource(T* _resource) 65 | { 66 | std::shared_ptr sp(_resource); 67 | if (_resource->m_iHandle >= m_vResources.size()) 68 | m_vResources.push_back(sp); 69 | else 70 | m_vResources[_resource->m_iHandle] = sp; 71 | 72 | return sp; 73 | } 74 | 75 | protected: 76 | 77 | virtual bool LoadResource(T** ppOut, uint32_t handle, const std::string& filename, 78 | void* extraParams) = 0; 79 | 80 | std::vector> m_vResources; /**< Stores the resources */ 81 | std::stack m_sHandles; /**< Stores the unused handles number*/ 82 | std::vector m_vLoaders; //!< Stores the resource loaders 83 | 84 | }; 85 | } // ari 86 | -------------------------------------------------------------------------------- /include/ari/StringCast.h: -------------------------------------------------------------------------------- 1 | // In JSON map keys can only be strings, so here's a class which makes conversion to/from string easy 2 | #pragma once 3 | 4 | #include 5 | 6 | template 7 | std::string castToString(const T& value); 8 | 9 | // template specializations 10 | 11 | std::string castToString(const bool& value); 12 | std::string castToString(const int& value); 13 | std::string castToString(const float& value); 14 | std::string castToString(const std::string& value); 15 | 16 | template 17 | T fromString(const std::string& value); 18 | 19 | template <> 20 | bool fromString(const std::string& valueStr); 21 | 22 | template <> 23 | int fromString(const std::string& valueStr); 24 | 25 | template <> 26 | float fromString(const std::string& valueStr); 27 | 28 | template <> 29 | std::string fromString(const std::string& valueStr); 30 | 31 | 32 | // return empty string if no conversion possible 33 | template 34 | std::string castToString(const T& /* value */) 35 | { 36 | return std::string(); 37 | } 38 | 39 | template 40 | T fromString(const std::string& /* value */) 41 | { 42 | return T(); 43 | } 44 | -------------------------------------------------------------------------------- /include/ari/aridef.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #if defined( _MSC_VER ) 4 | # pragma warning(disable:4251) // dll interface for std types 5 | # define ARI_EXPORT_DLL __declspec(dllexport) 6 | # define ARI_IMPORT_DLL __declspec(dllimport) 7 | #else 8 | # define ARI_EXPORT_DLL __attribute__((visibility("default"))) 9 | # define ARI_IMPORT_DLL 10 | #endif 11 | 12 | #ifdef ARI_EXPORT 13 | # define ARI_API ARI_EXPORT_DLL 14 | #else 15 | # define ARI_API ARI_IMPORT_DLL 16 | #endif 17 | 18 | #ifdef ARI_PLUGIN_EXPORT 19 | # define ARI_PLUGIN_API ARI_EXPORT_DLL 20 | #else 21 | # define ARI_PLUGIN_API ARI_IMPORT_DLL 22 | #endif 23 | 24 | #define ARI_CONFIG_MAX_WINDOW 8 25 | #define ENTRY_CONFIG_MAX_GAMEPADS 4 26 | #define ENTRY_WINDOW_FLAG_NONE UINT32_C(0x00000000) 27 | #define ENTRY_WINDOW_FLAG_ASPECT_RATIO UINT32_C(0x00000001) 28 | #define ENTRY_WINDOW_FLAG_FRAME UINT32_C(0x00000002) 29 | 30 | // Define ARI_NO_RTTI to turn off RTTI. This requires using the ARI_DEFINE_TYPE and ARI_DECLARE_TYPE macros on all types 31 | // that you wish to use as components or events. If you use ARI_NO_RTTI, also place ARI_TYPE_IMPLEMENTATION in a single cpp file. 32 | //#define ARI_NO_RTTI 33 | 34 | #ifndef ARI_NO_RTTI 35 | 36 | #include 37 | #include 38 | #define ARI_TYPE_IMPLEMENTATION 39 | 40 | #else 41 | 42 | #define ARI_TYPE_IMPLEMENTATION \ 43 | ari::TypeIndex ari::Internal::TypeRegistry::nextIndex = 1; \ 44 | \ 45 | ARI_DEFINE_TYPE(ari::Events::OnEntityCreated);\ 46 | ARI_DEFINE_TYPE(ari::Events::OnEntityDestroyed); \ 47 | 48 | #endif 49 | 50 | namespace bx 51 | { 52 | struct AllocatorI; 53 | } 54 | namespace ari 55 | { 56 | ARI_API bx::AllocatorI* getDefaultAllocator(); 57 | 58 | struct ARI_API TinyStlAllocator 59 | { 60 | static void* static_allocate(size_t _bytes); 61 | static void static_deallocate(void* _ptr, size_t /*_bytes*/); 62 | }; 63 | 64 | #ifndef ARI_NO_RTTI 65 | typedef std::type_index TypeIndex; 66 | 67 | #define ARI_DECLARE_TYPE 68 | #define ARI_DEFINE_TYPE(name) 69 | 70 | template 71 | TypeIndex getTypeIndex() 72 | { 73 | return std::type_index(typeid(T)); 74 | } 75 | 76 | #else 77 | typedef uint32_t TypeIndex; 78 | 79 | namespace Internal 80 | { 81 | class TypeRegistry 82 | { 83 | public: 84 | TypeRegistry() 85 | { 86 | index = nextIndex; 87 | ++nextIndex; 88 | } 89 | 90 | TypeIndex getIndex() const 91 | { 92 | return index; 93 | } 94 | 95 | private: 96 | static TypeIndex nextIndex; 97 | TypeIndex index; 98 | }; 99 | } 100 | 101 | #define ARI_DECLARE_TYPE public: static ari::Internal::TypeRegistry __ari_type_reg 102 | #define ARI_DEFINE_TYPE(name) ari::Internal::TypeRegistry name::__ari_type_reg 103 | 104 | template 105 | TypeIndex getTypeIndex() 106 | { 107 | return T::__ari_type_reg.getIndex(); 108 | } 109 | #endif 110 | 111 | } // namespace ari 112 | 113 | # define TINYSTL_ALLOCATOR ari::TinyStlAllocator 114 | -------------------------------------------------------------------------------- /include/ari/en/2d/Viewport.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../Component.hpp" 3 | #include "../../math/Rect.hpp" 4 | #include 5 | #include "../../gfx/Texture.hpp" 6 | 7 | namespace ari 8 | { 9 | class ARI_API Viewport: public Component 10 | { 11 | public: 12 | 13 | RectI Rect; 14 | bgfx::TextureFormat::Enum TextureFormat = bgfx::TextureFormat::Count; 15 | bool CreateDepth = false; 16 | bool UseMSAA = false; 17 | 18 | // internal 19 | 20 | bgfx::FrameBufferHandle m_frame_buffer_handle = BGFX_INVALID_HANDLE; 21 | RectI m_last_rect; 22 | bgfx::ViewId m_view_id = 0; 23 | Texture m_texture, 24 | m_depth_texture; 25 | }; 26 | 27 | } // ari 28 | -------------------------------------------------------------------------------- /include/ari/en/3d/BoxShape.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Node3D.hpp" 3 | 4 | namespace bgfx 5 | { 6 | struct VertexBufferHandle; 7 | struct IndexBufferHandle; 8 | struct ProgramHandle; 9 | } 10 | 11 | namespace ari 12 | { 13 | class RenderSystem; 14 | 15 | class ARI_API BoxShape: public Node3D 16 | { 17 | public: 18 | 19 | // Constructor 20 | BoxShape() { _isRenderable = true; } 21 | 22 | //! Destructor 23 | virtual ~BoxShape() = default; 24 | 25 | //! Render 26 | virtual void Render(const Matrix& matrix, bgfx::Encoder* encoder, uint16_t _view_id) override; 27 | 28 | static void Init(RenderSystem* render_system); 29 | static void Shutdown(); 30 | 31 | static bgfx::VertexBufferHandle m_sVBPos; 32 | static bgfx::VertexBufferHandle m_sVBColor; 33 | static bgfx::IndexBufferHandle m_sIB; 34 | static bgfx::ProgramHandle m_sProgram; 35 | 36 | }; // BoxShape 37 | } 38 | -------------------------------------------------------------------------------- /include/ari/en/3d/Camera.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Node3D.hpp" 4 | #include "../../math/Matrix.hpp" 5 | 6 | namespace ari 7 | { 8 | class ARI_API Camera: public Node3D 9 | { 10 | public: 11 | 12 | //! Constructor 13 | Camera() : Up(0.0f, 1.0f, 0.0f), _isActive(false) { } 14 | 15 | //! Destructor 16 | virtual ~Camera() = default; 17 | 18 | Vector3 Target, 19 | Up, 20 | Right; 21 | Matrix _view, 22 | _proj; 23 | bool _isActive; 24 | 25 | //! Rotate the camera around an axis. 26 | void Rotate(float _angle, const Vector3& _axis); 27 | 28 | //! Rotate by mouse movement 29 | void RotateByMouse(int _x, int _y, float _speed); 30 | 31 | //! Move back & forward 32 | void MoveBF(const float& _speed); 33 | 34 | //! Move left & right 35 | void MoveLR(const float& _speed); 36 | 37 | //! Move up & down 38 | void MoveUD(const float& _speed); 39 | 40 | protected: 41 | 42 | float m_fCurRotX = 0.0f, // Current Rotation X 43 | m_fLastRotX = 0.0f; // Last Rotation X 44 | 45 | }; // Camera 46 | 47 | } // ari 48 | -------------------------------------------------------------------------------- /include/ari/en/3d/Node3D.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../Component.hpp" 4 | #include "../../math/Vector.hpp" 5 | #include "../../math/Matrix.hpp" 6 | 7 | namespace bgfx 8 | { 9 | struct Encoder; 10 | } 11 | namespace ari 12 | { 13 | class ARI_API Node3D: public Component 14 | { 15 | public: 16 | 17 | //! Constructor 18 | Node3D() : Scale(1.0f, 1.0f, 1.0f), _isRenderable(false) { _isFromNode3D = true; } 19 | 20 | //! Destructor 21 | virtual ~Node3D() = default; 22 | 23 | //! Render 24 | virtual void Render(const Matrix& matrix, bgfx::Encoder* encoder, uint16_t _view_id) { BX_UNUSED(matrix, encoder); } 25 | 26 | Vector3 Position, 27 | Rotation, 28 | Scale; 29 | 30 | Matrix _finalMat; 31 | bool _isRenderable; 32 | 33 | }; // Node3D 34 | 35 | } // ari 36 | -------------------------------------------------------------------------------- /include/ari/en/3d/RenderSystem.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../System.hpp" 3 | #include "../EventSubscriber.hpp" 4 | 5 | namespace bgfx 6 | { 7 | struct VertexDecl; 8 | struct ProgramHandle; 9 | } 10 | 11 | namespace ari 12 | { 13 | class BoxShape; 14 | 15 | class ARI_API RenderSystem: public System, 16 | public EventSubscriber>, 17 | public EventSubscriber 18 | { 19 | public: 20 | 21 | enum class VertexType 22 | { 23 | Pos, 24 | Color, 25 | Count 26 | }; 27 | 28 | RenderSystem(); 29 | ~RenderSystem(); 30 | 31 | void Update(World* p_world, UpdateState state) override; 32 | void Configure(World* p_world) override; 33 | void Unconfigure(World* p_world) override; 34 | Type GetSystemType() override 35 | { 36 | return Type::RenderSystem; 37 | } 38 | bool NeedUpdateOnState(UpdateState state) override; 39 | 40 | void Receive(World* world, const events::OnComponentAssigned& event) override; 41 | void Receive(World* world, const events::OnFrameData& event) override; 42 | 43 | bgfx::VertexDecl* GetVertexDecl(VertexType vertex_type) const; 44 | 45 | bgfx::ProgramHandle* GetProgram() const { return m_Program; } 46 | 47 | protected: 48 | 49 | bgfx::VertexDecl * m_pVertexDeclArray; 50 | bgfx::ProgramHandle * m_Program; 51 | FrameData * m_pFrameDataCurrent, 52 | * m_pFrameDataNext; 53 | uint16_t m_view_id = 0; 54 | }; 55 | 56 | } // ari 57 | -------------------------------------------------------------------------------- /include/ari/en/3d/SceneSystem.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../System.hpp" 3 | #include "../EventSubscriber.hpp" 4 | #include "../../gfx/FrameData.hpp" 5 | 6 | namespace ari 7 | { 8 | class Camera; 9 | class BoxShape; 10 | class Node; 11 | 12 | class ARI_API SceneSystem: public System, 13 | public EventSubscriber, 14 | public EventSubscriber, 15 | public EventSubscriber>, 16 | public EventSubscriber>, 17 | public EventSubscriber>, 18 | public EventSubscriber> 19 | { 20 | public: 21 | 22 | //! Constructor 23 | SceneSystem(); 24 | 25 | //! Destructor 26 | ~SceneSystem(); 27 | 28 | void Update(World* p_world, UpdateState state) override; 29 | void Configure(World* p_world) override; 30 | void Unconfigure(World* p_world) override; 31 | Type GetSystemType() override 32 | { 33 | return Type::SceneSystem; 34 | } 35 | bool NeedUpdateOnState(UpdateState state) override; 36 | 37 | void Receive(World* world, const events::OnEntityCreated& event) override; 38 | void Receive(World* world, const events::OnEntityDestroyed& event) override; 39 | void Receive(World* world, const events::OnComponentAssigned& event) override; 40 | void Receive(World* world, const events::OnComponentRemoved& event) override; 41 | void Receive(World* world, const events::OnComponentAssigned& event) override; 42 | void Receive(World* world, const events::OnComponentRemoved& event) override; 43 | 44 | protected: 45 | 46 | Camera * m_pActiveCamera; 47 | FrameData * m_FrameDatasUnused, // This is the unused frame data pointers 48 | * m_FrameDatasTransforms, // This is the transform calculated nodes 49 | * m_FrameDatasVisible; // This is the visible nodes that must be rendered. 50 | 51 | void CalcTransform(Node* node, Matrix* parentMat); 52 | 53 | }; // SceneSystem 54 | 55 | } // ari 56 | -------------------------------------------------------------------------------- /include/ari/en/Component.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Node.hpp" 3 | 4 | namespace ari 5 | { 6 | class ARI_API Component: public Node 7 | { 8 | public: 9 | 10 | //! Constructor 11 | Component(); 12 | 13 | //! Destructor 14 | virtual ~Component() = default; 15 | 16 | bool _isFromNode3D; 17 | bool _isFromGui; 18 | 19 | }; // Component 20 | 21 | } // ari 22 | -------------------------------------------------------------------------------- /include/ari/en/Entity.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Node.hpp" 3 | 4 | namespace ari 5 | { 6 | class ARI_API Entity: public Node 7 | { 8 | public: 9 | 10 | //! Constuctor 11 | Entity(); 12 | 13 | //! Destructor 14 | ~Entity(); 15 | 16 | }; // Entity 17 | 18 | } // ari 19 | -------------------------------------------------------------------------------- /include/ari/en/EventSubscriber.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../aridef.hpp" 3 | #include 4 | 5 | namespace ari 6 | { 7 | class World; 8 | class Entity; 9 | class Component; 10 | class FrameData; 11 | 12 | namespace Internal 13 | { 14 | class ARI_API BaseEventSubscriber 15 | { 16 | public: 17 | 18 | virtual ~BaseEventSubscriber() = default; 19 | }; 20 | 21 | } // Internal 22 | 23 | /** 24 | * Subclass this as EventSubscriber and then call World::subscribe() in order to subscribe to events. Make sure 25 | * to call World::unsubscribe() or World::unsubscribeAll() when your subscriber is deleted! 26 | */ 27 | template 28 | class ARI_API EventSubscriber: public Internal::BaseEventSubscriber 29 | { 30 | public: 31 | 32 | virtual ~EventSubscriber() = default; 33 | 34 | /** 35 | * Called when an event is emitted by the world. 36 | */ 37 | virtual void Receive(World* world, const T& event) = 0; 38 | 39 | }; // EventSubscriber 40 | 41 | 42 | namespace events 43 | { 44 | // Called when a new entity is created. 45 | struct OnEntityCreated 46 | { 47 | ARI_DECLARE_TYPE; 48 | 49 | Entity* entity; 50 | }; 51 | 52 | // Called when an entity is about to be destroyed. 53 | struct OnEntityDestroyed 54 | { 55 | ARI_DECLARE_TYPE; 56 | 57 | Entity* entity; 58 | }; 59 | 60 | // Called when a component is assigned (not necessarily created). 61 | template 62 | struct OnComponentAssigned 63 | { 64 | ARI_DECLARE_TYPE; 65 | 66 | Entity* entity; 67 | T* component; 68 | }; 69 | 70 | // Called when a component is removed 71 | template 72 | struct OnComponentRemoved 73 | { 74 | ARI_DECLARE_TYPE; 75 | 76 | Entity* entity; 77 | T* component; 78 | }; 79 | 80 | struct OnFrameData 81 | { 82 | ARI_DECLARE_TYPE; 83 | 84 | FrameData* frame_data; 85 | 86 | }; 87 | 88 | } // events 89 | 90 | } // ari 91 | -------------------------------------------------------------------------------- /include/ari/en/Node.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../aridef.hpp" 4 | #include "tinystl/vector.h" 5 | #include 6 | #include 7 | #include 8 | 9 | namespace ari 10 | { 11 | class World; 12 | class Entity; 13 | 14 | class ARI_API Node 15 | { 16 | friend class World; 17 | 18 | public: 19 | 20 | enum class Type 21 | { 22 | Entity = 0, 23 | Component, 24 | 25 | Unknown 26 | 27 | }; 28 | 29 | //! Constructor 30 | Node(); 31 | 32 | //! Destructor 33 | virtual ~Node(); 34 | 35 | //! Adds a node as child. 36 | template 37 | T* AddChild(T* child) 38 | { 39 | m_vChilds.push_back(child); 40 | child->m_pWorld = m_pWorld; 41 | child->SetParent(this); 42 | 43 | // Add the child to map 44 | auto index = getTypeIndex(); 45 | auto found = childs.find(index); 46 | if (found == childs.end()) 47 | { 48 | tinystl::vector subList; 49 | subList.push_back(child); 50 | 51 | childs.insert({ index, subList }); 52 | } 53 | else 54 | { 55 | found->second.push_back(child); 56 | } 57 | 58 | if (child->m_eNodeType == Type::Component) 59 | { 60 | assert(m_pWorld); 61 | m_pWorld->emit>({ child->GetParentEntity(), child }); 62 | } 63 | 64 | return child; 65 | 66 | } // AddChild 67 | 68 | // Returns the first attached Node. 69 | template 70 | T* GetChild() 71 | { 72 | auto found = childs.find(getTypeIndex()); 73 | if (found != childs.end()) 74 | { 75 | return reinterpret_cast(found->second[0]); 76 | } 77 | return nullptr; 78 | } 79 | 80 | template 81 | tinystl::vector GetChildren() 82 | { 83 | auto found = childs.find(getTypeIndex()); 84 | if (found != childs.end()) 85 | { 86 | return found->second; 87 | } 88 | return tinystl::vector(); 89 | } 90 | 91 | /*! Removes a child from this node. 92 | \param child The pointer to the child. 93 | */ 94 | template 95 | void RemoveChild(T* child) 96 | { 97 | for (tinystl::vector::iterator it = m_vChilds.begin(); 98 | it != m_vChilds.end(); ++it) 99 | { 100 | if ((*it) == child) 101 | { 102 | child->m_pParent = nullptr; 103 | m_vChilds.erase(it); 104 | 105 | // Remove it from map 106 | auto index = getTypeIndex(); 107 | auto found = childs.find(index); 108 | if (found != childs.end()) 109 | { 110 | found->second.erase(std::remove(found->second.begin(), found->second.end(), child), found->second.end()); 111 | if (found->second.size() == 0) 112 | { 113 | childs.erase(found); 114 | } 115 | } 116 | 117 | if (child->m_eNodeType == Type::Component) 118 | { 119 | assert(m_pWorld); 120 | m_pWorld->emit>({ child->GetParentEntity(), child }); 121 | } 122 | return; 123 | } 124 | } 125 | 126 | } // RemoveChild 127 | 128 | //! Removes all children of this node. 129 | void RemoveChildren(bool _delete = false); 130 | 131 | //! Returns the node parent. 132 | virtual Node* GetParent() { return m_pParent; } 133 | 134 | //! Sets the node parent. 135 | virtual void SetParent(Node* parent); 136 | 137 | //! Returns the node type. 138 | Node::Type GetType() const { return m_eNodeType; } 139 | 140 | //! Returns the parent Entity in the tree 141 | Entity* GetParentEntity() const; 142 | 143 | const tinystl::vector& GetChildren() const { return m_vChilds; } 144 | 145 | World* GetWorld() const { return m_pWorld; } 146 | 147 | /** 148 | * Send the node to the destroy queue. 149 | * It will be deleted in next two frame; 150 | */ 151 | void Destroy(bool addToDestroyQueue = true); 152 | 153 | uint32_t IsInDestroyQueue() const { return m_iIsInDestroyQueue; } 154 | 155 | protected: 156 | 157 | Node* m_pParent; 158 | tinystl::vector m_vChilds; 159 | Node::Type m_eNodeType; 160 | World* m_pWorld; 161 | uint32_t m_iIsInDestroyQueue = 0; 162 | std::unordered_map> childs; 164 | 165 | }; // Node 166 | 167 | } // ari 168 | -------------------------------------------------------------------------------- /include/ari/en/System.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../aridef.hpp" 3 | 4 | namespace ari 5 | { 6 | class World; 7 | 8 | class ARI_API System 9 | { 10 | public: 11 | 12 | enum class Type 13 | { 14 | GameplaySystem, 15 | SceneSystem, 16 | RenderSystem 17 | }; 18 | 19 | enum class UpdateState 20 | { 21 | GameplayState, 22 | SceneManagerState, 23 | MainThreadState 24 | }; 25 | 26 | //! Constructor 27 | System() = default; 28 | 29 | //! Destructor 30 | virtual ~System() = default; 31 | 32 | //! Update the system 33 | virtual void Update(World* p_world, UpdateState state) = 0; 34 | 35 | //! Configure the system after adding it to the world 36 | virtual void Configure(World* p_world) = 0; 37 | 38 | //! Unconfigure the system before removing it from the world 39 | virtual void Unconfigure(World* p_world) = 0; 40 | 41 | //! Returns the system type 42 | virtual Type GetSystemType() = 0; 43 | 44 | //! Ask the system if needs update on different states 45 | virtual bool NeedUpdateOnState(UpdateState state) = 0; 46 | 47 | }; // System 48 | 49 | } // ari 50 | -------------------------------------------------------------------------------- /include/ari/en/World.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../aridef.hpp" 3 | #include "tinystl/vector.h" 4 | #include "EventSubscriber.hpp" 5 | #include 6 | #include 7 | #include "bx/spscqueue.h" 8 | 9 | namespace ftl 10 | { 11 | class TaskScheduler; 12 | } 13 | 14 | namespace ari 15 | { 16 | class Node; 17 | class System; 18 | class Entity; 19 | 20 | class ARI_API World 21 | { 22 | public: 23 | 24 | enum class UpdateType 25 | { 26 | Sync, 27 | Async 28 | }; 29 | 30 | //! Constructor 31 | World(); 32 | 33 | //! Destructor 34 | ~World(); 35 | 36 | void SetUpdateType(UpdateType type) { m_UpdateType = type; } 37 | 38 | UpdateType GetUpdateType() const { return m_UpdateType; } 39 | 40 | /** 41 | * Add a new system to the world 42 | */ 43 | void AddSystem(System* p_system); 44 | 45 | /** 46 | * Removes a system from world 47 | */ 48 | void RemoveSystem(System* p_system); 49 | 50 | /** 51 | * Adds a new entity to the world 52 | */ 53 | void AddEntity(Entity* p_entity); 54 | 55 | /** 56 | * Removes an entity from world 57 | */ 58 | void RemoveEntity(Entity* p_entity); 59 | 60 | /** 61 | * Updates the world 62 | */ 63 | void Update(float tick); 64 | 65 | /** 66 | * internal use Node::Destroy() instead. 67 | * Add a node to destroy queue 68 | */ 69 | void _AddToDestroyQueue(Node* node); 70 | 71 | /** 72 | * Subscribe to an event. 73 | */ 74 | template 75 | void subscribe(EventSubscriber* subscriber) 76 | { 77 | auto index = getTypeIndex(); 78 | auto found = subscribers.find(index); 79 | if (found == subscribers.end()) 80 | { 81 | tinystl::vector subList; 82 | subList.push_back(subscriber); 83 | 84 | subscribers.insert({ index, subList }); 85 | } 86 | else 87 | { 88 | found->second.push_back(subscriber); 89 | } 90 | } 91 | 92 | /** 93 | * Unsubscribe from an event. 94 | */ 95 | template 96 | void unsubscribe(EventSubscriber* subscriber) 97 | { 98 | auto index = getTypeIndex(); 99 | auto found = subscribers.find(index); 100 | if (found != subscribers.end()) 101 | { 102 | found->second.erase(std::remove(found->second.begin(), found->second.end(), subscriber), found->second.end()); 103 | if (found->second.size() == 0) 104 | { 105 | subscribers.erase(found); 106 | } 107 | } 108 | } 109 | 110 | /** 111 | * Unsubscribe from all events. Don't be afraid of the void pointer, just pass in your subscriber as normal. 112 | */ 113 | void unsubscribeAll(void* subscriber) 114 | { 115 | for (auto kv : subscribers) 116 | { 117 | kv.second.erase(std::remove(kv.second.begin(), kv.second.end(), subscriber), kv.second.end()); 118 | if (kv.second.empty()) 119 | { 120 | subscribers.erase(subscribers.find(kv.first)); 121 | } 122 | } 123 | } 124 | 125 | 126 | /** 127 | * Emit an event. This will do nothing if there are no subscribers for the event type. 128 | */ 129 | template 130 | void emit(const T& event) 131 | { 132 | auto found = subscribers.find(getTypeIndex()); 133 | if (found != subscribers.end()) 134 | { 135 | for (auto* base : found->second) 136 | { 137 | auto* sub = reinterpret_cast*>(base); 138 | sub->Receive(this, event); 139 | } 140 | } 141 | } 142 | 143 | const tinystl::vector& GetAllEntities() const { return Entities; } 144 | 145 | ftl::TaskScheduler* GetTaskScheduler() const { return m_pTaskScheduler; } 146 | 147 | protected: 148 | 149 | std::unordered_map> subscribers; 151 | bx::SpScUnboundedQueueT m_qDestroyQueue; 152 | tinystl::vector systems; 153 | tinystl::vector Entities; 154 | ftl::TaskScheduler * m_pTaskScheduler; 155 | UpdateType m_UpdateType; 156 | 157 | void CheckDestroyQueue(); 158 | 159 | }; // World 160 | 161 | } // ari 162 | -------------------------------------------------------------------------------- /include/ari/en/WorldManager.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace ari 4 | { 5 | 6 | } // ari 7 | -------------------------------------------------------------------------------- /include/ari/en/gui/Button.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Gui.hpp" 3 | #include "../../Delegate.hpp" 4 | 5 | namespace ari 6 | { 7 | class ARI_API Button: public Gui 8 | { 9 | public: 10 | 11 | bool BeginRender() override; 12 | 13 | DelegateNoParam OnClick; 14 | 15 | char* Label; 16 | }; 17 | } // ari 18 | -------------------------------------------------------------------------------- /include/ari/en/gui/CheckBox.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Gui.hpp" 3 | 4 | namespace ari 5 | { 6 | class ARI_API CheckBox: public Gui 7 | { 8 | public: 9 | 10 | CheckBox(); 11 | 12 | ~CheckBox() = default; 13 | 14 | bool BeginRender() override; 15 | 16 | bool Checked; 17 | char * Label; 18 | }; 19 | 20 | } // ari 21 | -------------------------------------------------------------------------------- /include/ari/en/gui/Dock.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Gui.hpp" 3 | #include "dear-imgui/imgui.h" 4 | 5 | namespace ari 6 | { 7 | class ARI_API Dock: public Gui 8 | { 9 | public: 10 | 11 | Dock(); 12 | 13 | ~Dock() = default; 14 | 15 | bool BeginRender() override; 16 | 17 | void EndRender() override; 18 | 19 | bool isOpened; 20 | char* Label; 21 | 22 | }; // Dock 23 | 24 | } // ari 25 | -------------------------------------------------------------------------------- /include/ari/en/gui/DockSpace.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Gui.hpp" 3 | 4 | namespace ari 5 | { 6 | class ARI_API DockSpace: public Gui 7 | { 8 | public: 9 | 10 | bool BeginRender() override; 11 | void EndRender() override; 12 | 13 | }; // DockSpace 14 | 15 | } // ari 16 | -------------------------------------------------------------------------------- /include/ari/en/gui/DockableWindow.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Gui.hpp" 3 | #include "../../Delegate.hpp" 4 | 5 | namespace ImWindow 6 | { 7 | class ImwWindow; 8 | } 9 | 10 | namespace ari 11 | { 12 | class GuiSystem; 13 | class PlatformWindow; 14 | 15 | class ARI_API DockableWindow: public Gui 16 | { 17 | friend class AriImwWindow; 18 | 19 | public: 20 | enum class Oriention 21 | { 22 | Center, 23 | Top, 24 | Left, 25 | Right, 26 | Botton 27 | }; 28 | 29 | DockableWindow(GuiSystem* _pGuiSystem); 30 | ~DockableWindow() override; 31 | 32 | bool BeginRender() override; 33 | 34 | void Dock(Oriention _oriention = Oriention::Center, float _raito = 0.5f) const; 35 | 36 | void DockWith(DockableWindow* _pOtherDock, Oriention _oriention = Oriention::Center, 37 | float _raito = 0.5f) const; 38 | 39 | void SetTitle(const char* _pTitle) const; 40 | void SetAlone(bool _alone) const; 41 | void SetClosable(bool _closable) const; 42 | void SetFillingSpace(bool _fill) const; 43 | 44 | void GetLastPosition(float& _x, float& _y) const; 45 | void GetLastSize(float& _width, float& _height) const; 46 | 47 | /** 48 | * This is a callback for when we want to draw the Guis good to get the window size here. 49 | */ 50 | DelegateNoParam OnGui; 51 | 52 | /** 53 | * This callback is for when platform window change or assigned. 54 | * Good for setting the event listeners. 55 | */ 56 | DelegateNoParam OnWindowChanged; 57 | 58 | /** 59 | * @note: only call this function on OnGui callback 60 | */ 61 | PlatformWindow* GetPlatformWindow() const; 62 | 63 | protected: 64 | 65 | GuiSystem * m_pGuiSystem; 66 | ImWindow::ImwWindow * m_pWindow; 67 | PlatformWindow * m_pPlatformWindow; 68 | 69 | }; 70 | 71 | } // ari 72 | -------------------------------------------------------------------------------- /include/ari/en/gui/Gui.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../Component.hpp" 3 | 4 | namespace ari 5 | { 6 | class ARI_API Gui: public Component 7 | { 8 | public: 9 | 10 | // Constructor 11 | Gui() { _isFromGui = true; } 12 | 13 | virtual ~Gui() = default; 14 | 15 | virtual bool BeginRender() { return true; } 16 | 17 | virtual void EndRender() { } 18 | 19 | bool SameLine = false; 20 | 21 | bool Separator = false; 22 | 23 | bool Visible = true; 24 | 25 | }; // Gui 26 | 27 | } // ari 28 | -------------------------------------------------------------------------------- /include/ari/en/gui/GuiSystem.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../System.hpp" 3 | #include "../EventSubscriber.hpp" 4 | 5 | namespace ari 6 | { 7 | class Node; 8 | class Dock; 9 | 10 | class ARI_API GuiSystem: public System, 11 | public EventSubscriber> 12 | { 13 | friend class AriImwWindow; 14 | 15 | public: 16 | 17 | GuiSystem(); 18 | virtual ~GuiSystem(); 19 | 20 | void Update(World* p_world, UpdateState state) override; 21 | void Configure(World* p_world) override; 22 | void Unconfigure(World* p_world) override; 23 | Type GetSystemType() override; 24 | bool NeedUpdateOnState(UpdateState state) override; 25 | 26 | void Receive(World* world, const events::OnComponentAssigned& event) override; 27 | 28 | protected: 29 | bool m_bIsDockCreated; 30 | 31 | void RenderGui(Node* node); 32 | }; 33 | } 34 | -------------------------------------------------------------------------------- /include/ari/en/gui/Image.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Gui.hpp" 3 | #include "../../gfx/Texture.hpp" 4 | #include "dear-imgui/imgui.h" 5 | #include "../../Delegate.hpp" 6 | 7 | namespace ari 8 | { 9 | class ARI_API Image: public Gui 10 | { 11 | public: 12 | bool BeginRender() override; 13 | 14 | std::shared_ptr ImageTexture; 15 | ImVec2 Size; 16 | DelegateNoParam OnHovered; 17 | 18 | }; // Image 19 | 20 | } // ari 21 | -------------------------------------------------------------------------------- /include/ari/en/gui/Label.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Gui.hpp" 3 | 4 | namespace ari 5 | { 6 | class ARI_API Label : public Gui 7 | { 8 | public: 9 | 10 | //! Constructor 11 | Label(); 12 | 13 | ~Label() = default; 14 | 15 | bool BeginRender() override; 16 | 17 | const char * Text; 18 | }; 19 | 20 | } 21 | -------------------------------------------------------------------------------- /include/ari/en/gui/Popup.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Gui.hpp" 3 | 4 | namespace ari 5 | { 6 | class ARI_API Popup: public Gui 7 | { 8 | public: 9 | 10 | bool BeginRender() override; 11 | 12 | void EndRender() override; 13 | 14 | void Show(); 15 | 16 | void Hide(); 17 | 18 | //! Name must be unique. 19 | char* Name = nullptr; 20 | 21 | protected: 22 | 23 | bool m_bDoEndPopup = false; 24 | bool m_bOpenPopup = false; 25 | bool m_bClosePopup = false; 26 | 27 | }; // Popup 28 | 29 | } // ari 30 | -------------------------------------------------------------------------------- /include/ari/en/gui/TextBox.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Gui.hpp" 3 | 4 | namespace ari 5 | { 6 | class ARI_API TextBox: public Gui 7 | { 8 | public: 9 | 10 | TextBox(size_t maxLength = 128); 11 | 12 | ~TextBox() override; 13 | 14 | bool BeginRender() override; 15 | 16 | void SetText(const char* _text) const; 17 | 18 | char* Text; 19 | char* Label; 20 | 21 | private: 22 | size_t m_MaxLength; 23 | 24 | }; 25 | 26 | } // ari 27 | -------------------------------------------------------------------------------- /include/ari/en/gui/Window.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Gui.hpp" 3 | #include "dear-imgui/imgui.h" 4 | 5 | namespace ari 6 | { 7 | class ARI_API Window: public Gui 8 | { 9 | public: 10 | Window(); 11 | 12 | ~Window() = default; 13 | 14 | bool BeginRender() override; 15 | void EndRender() override; 16 | 17 | char * Name; 18 | bool CloseButton, 19 | isOpen; 20 | ImVec2 Pos, 21 | Size; 22 | ImGuiWindowFlags Flags; 23 | 24 | }; // Window 25 | 26 | } // ari 27 | -------------------------------------------------------------------------------- /include/ari/gfx/FrameData.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../aridef.hpp" 3 | #include "../math/Matrix.hpp" 4 | #include 5 | 6 | namespace ari 7 | { 8 | class Node3D; 9 | class Camera; 10 | 11 | class ARI_API FrameData 12 | { 13 | public: 14 | FrameData(): FrameNumber(0) 15 | {} 16 | 17 | tinystl::vector Nodes; 18 | tinystl::vector WorldMatrices; 19 | uint32_t FrameNumber; 20 | Camera* Camera; 21 | 22 | }; // FrameData 23 | 24 | } // ari 25 | -------------------------------------------------------------------------------- /include/ari/gfx/Texture.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../aridef.hpp" 3 | #include "../Resource.hpp" 4 | #include "bgfx/bgfx.h" 5 | #include "bimg/bimg.h" 6 | 7 | namespace ari 8 | { 9 | struct TextureParams 10 | { 11 | uint32_t Flags = BGFX_TEXTURE_NONE; 12 | bgfx::TextureInfo* Info = nullptr; 13 | bimg::Orientation::Enum* Orientation = nullptr; 14 | }; 15 | 16 | class ARI_API Texture: public Resource 17 | { 18 | public: 19 | 20 | Texture() = default; 21 | 22 | Texture(const uint32_t& _handel, const std::string& _fileName); 23 | 24 | ~Texture() override; 25 | 26 | bgfx::TextureHandle Handle = BGFX_INVALID_HANDLE; 27 | 28 | }; 29 | 30 | } // ari 31 | -------------------------------------------------------------------------------- /include/ari/gfx/TextureManager.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../ResourceManager.hpp" 3 | #include "Texture.hpp" 4 | 5 | namespace ari 6 | { 7 | class ARI_API TextureManager: public ResourceManager 8 | { 9 | public: 10 | ~TextureManager() override; 11 | 12 | protected: 13 | 14 | bool LoadResource(Texture** ppOut, uint32_t handle, 15 | const std::string& filename, void* extraParams) override; 16 | 17 | }; 18 | 19 | } // ari 20 | -------------------------------------------------------------------------------- /include/ari/gfx/Vertices.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace ari 4 | { 5 | struct PosVertex 6 | { 7 | float x, y, z; 8 | }; 9 | 10 | struct ColorVertex 11 | { 12 | uint32_t argb; 13 | }; 14 | 15 | } // ari 16 | -------------------------------------------------------------------------------- /include/ari/io/Input.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "IoEnums.hpp" 3 | #include "../aridef.hpp" 4 | 5 | namespace ari 6 | { 7 | typedef void(*InputBindingFn)(const void* _userData); 8 | 9 | struct ARI_API InputBinding 10 | { 11 | void set(Key::Enum _key, uint8_t _modifiers, uint8_t _flags, InputBindingFn _fn, const void* _userData = NULL) 12 | { 13 | m_key = _key; 14 | m_modifiers = _modifiers; 15 | m_flags = _flags; 16 | m_fn = _fn; 17 | m_userData = _userData; 18 | } 19 | 20 | void end() 21 | { 22 | m_key = Key::None; 23 | m_modifiers = Modifier::None; 24 | m_flags = 0; 25 | m_fn = NULL; 26 | m_userData = NULL; 27 | } 28 | 29 | Key::Enum m_key; 30 | uint8_t m_modifiers; 31 | uint8_t m_flags; 32 | InputBindingFn m_fn; 33 | const void* m_userData; 34 | }; 35 | 36 | #define INPUT_BINDING_END { Key::None, Modifier::None, 0, NULL, NULL } 37 | 38 | /// 39 | void inputInit(); 40 | 41 | /// 42 | void inputShutdown(); 43 | 44 | /// 45 | void inputAddBindings(const char* _name, const InputBinding* _bindings); 46 | 47 | /// 48 | void inputRemoveBindings(const char* _name); 49 | 50 | /// 51 | void inputProcess(); 52 | 53 | /// 54 | void inputSetKeyState(Key::Enum _key, uint8_t _modifiers, bool _down); 55 | 56 | /// 57 | bool inputGetKeyState(Key::Enum _key, uint8_t* _modifiers = NULL); 58 | 59 | /// 60 | uint8_t inputGetModifiersState(); 61 | 62 | /// Adds single UTF-8 encoded character into input buffer. 63 | void inputChar(uint8_t _len, const uint8_t _char[4]); 64 | 65 | /// Returns single UTF-8 encoded character from input buffer. 66 | const uint8_t* inputGetChar(); 67 | 68 | /// Flush internal input buffer. 69 | void inputCharFlush(); 70 | 71 | /// 72 | void inputSetMouseResolution(uint16_t _width, uint16_t _height); 73 | 74 | /// 75 | void inputSetMousePos(int32_t _mx, int32_t _my, int32_t _mz); 76 | 77 | /// 78 | void inputSetMouseButtonState(MouseButton::Enum _button, uint8_t _state); 79 | 80 | /// 81 | void inputSetMouseLock(bool _lock); 82 | 83 | /// 84 | void inputGetMouse(float _mouse[3]); 85 | 86 | /// 87 | bool inputIsMouseLocked(); 88 | 89 | /// 90 | void inputSetGamepadAxis(GamepadHandle _handle, GamepadAxis::Enum _axis, int32_t _value); 91 | 92 | /// 93 | int32_t inputGetGamepadAxis(GamepadHandle _handle, GamepadAxis::Enum _axis); 94 | 95 | } 96 | -------------------------------------------------------------------------------- /include/ari/io/IoEnums.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "bx/bx.h" 3 | #include "bx/filepath.h" 4 | 5 | namespace ari 6 | { 7 | struct WindowHandle { uint16_t idx; }; 8 | inline bool isValid(WindowHandle _handle) { return UINT16_MAX != _handle.idx; } 9 | 10 | struct GamepadHandle { uint16_t idx; }; 11 | inline bool isValid(GamepadHandle _handle) { return UINT16_MAX != _handle.idx; } 12 | 13 | struct MouseButton 14 | { 15 | enum Enum 16 | { 17 | None, 18 | Left, 19 | Middle, 20 | Right, 21 | 22 | Count 23 | }; 24 | }; 25 | 26 | struct GamepadAxis 27 | { 28 | enum Enum 29 | { 30 | LeftX, 31 | LeftY, 32 | LeftZ, 33 | RightX, 34 | RightY, 35 | RightZ, 36 | 37 | Count 38 | }; 39 | }; 40 | 41 | struct Modifier 42 | { 43 | enum Enum 44 | { 45 | None = 0, 46 | LeftAlt = 0x01, 47 | RightAlt = 0x02, 48 | LeftCtrl = 0x04, 49 | RightCtrl = 0x08, 50 | LeftShift = 0x10, 51 | RightShift = 0x20, 52 | LeftMeta = 0x40, 53 | RightMeta = 0x80, 54 | }; 55 | }; 56 | 57 | struct Key 58 | { 59 | enum Enum 60 | { 61 | None = 0, 62 | Esc, 63 | Return, 64 | Tab, 65 | Space, 66 | Backspace, 67 | Up, 68 | Down, 69 | Left, 70 | Right, 71 | Insert, 72 | Delete, 73 | Home, 74 | End, 75 | PageUp, 76 | PageDown, 77 | Print, 78 | Plus, 79 | Minus, 80 | LeftBracket, 81 | RightBracket, 82 | Semicolon, 83 | Quote, 84 | Comma, 85 | Period, 86 | Slash, 87 | Backslash, 88 | Tilde, 89 | F1, 90 | F2, 91 | F3, 92 | F4, 93 | F5, 94 | F6, 95 | F7, 96 | F8, 97 | F9, 98 | F10, 99 | F11, 100 | F12, 101 | NumPad0, 102 | NumPad1, 103 | NumPad2, 104 | NumPad3, 105 | NumPad4, 106 | NumPad5, 107 | NumPad6, 108 | NumPad7, 109 | NumPad8, 110 | NumPad9, 111 | Key0, 112 | Key1, 113 | Key2, 114 | Key3, 115 | Key4, 116 | Key5, 117 | Key6, 118 | Key7, 119 | Key8, 120 | Key9, 121 | KeyA, 122 | KeyB, 123 | KeyC, 124 | KeyD, 125 | KeyE, 126 | KeyF, 127 | KeyG, 128 | KeyH, 129 | KeyI, 130 | KeyJ, 131 | KeyK, 132 | KeyL, 133 | KeyM, 134 | KeyN, 135 | KeyO, 136 | KeyP, 137 | KeyQ, 138 | KeyR, 139 | KeyS, 140 | KeyT, 141 | KeyU, 142 | KeyV, 143 | KeyW, 144 | KeyX, 145 | KeyY, 146 | KeyZ, 147 | 148 | GamepadA, 149 | GamepadB, 150 | GamepadX, 151 | GamepadY, 152 | GamepadThumbL, 153 | GamepadThumbR, 154 | GamepadShoulderL, 155 | GamepadShoulderR, 156 | GamepadUp, 157 | GamepadDown, 158 | GamepadLeft, 159 | GamepadRight, 160 | GamepadBack, 161 | GamepadStart, 162 | GamepadGuide, 163 | 164 | Count 165 | }; 166 | }; 167 | 168 | struct Suspend 169 | { 170 | enum Enum 171 | { 172 | WillSuspend, 173 | DidSuspend, 174 | WillResume, 175 | DidResume, 176 | 177 | Count 178 | }; 179 | }; 180 | 181 | const char* getName(Key::Enum _key); 182 | 183 | struct MouseState 184 | { 185 | MouseState() 186 | : m_mx(0) 187 | , m_my(0) 188 | , m_mz(0) 189 | { 190 | for (unsigned char & m_button : m_buttons) 191 | { 192 | m_button = MouseButton::None; 193 | } 194 | } 195 | 196 | int32_t m_mx; 197 | int32_t m_my; 198 | int32_t m_mz; 199 | uint8_t m_buttons[MouseButton::Count]; 200 | }; 201 | 202 | struct GamepadState 203 | { 204 | GamepadState() 205 | { 206 | bx::memSet(m_axis, 0, sizeof(m_axis) ); 207 | } 208 | 209 | int32_t m_axis[GamepadAxis::Count]; 210 | }; 211 | 212 | struct WindowState 213 | { 214 | WindowState() 215 | : m_width(0) 216 | , m_height(0) 217 | , m_nwh(NULL) 218 | { 219 | m_handle.idx = UINT16_MAX; 220 | } 221 | 222 | WindowHandle m_handle; 223 | uint32_t m_width; 224 | uint32_t m_height; 225 | MouseState m_mouse; 226 | void* m_nwh; 227 | bx::FilePath m_dropFile; 228 | }; 229 | 230 | 231 | } // ari -------------------------------------------------------------------------------- /include/ari/io/IoEvents.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "IoEnums.hpp" 4 | #include "bx/filepath.h" 5 | #include "bx/spscqueue.h" 6 | #include "../en/EventSubscriber.hpp" 7 | 8 | #define ENTRY_IMPLEMENT_EVENT(_class, _type) \ 9 | _class() : Event(_type) {} 10 | 11 | extern bx::AllocatorI* g_allocator; 12 | 13 | namespace ari 14 | { 15 | struct Event 16 | { 17 | enum Enum 18 | { 19 | Axis, 20 | Char, 21 | Exit, 22 | Gamepad, 23 | Key, 24 | Mouse, 25 | Size, 26 | Window, 27 | Suspend, 28 | DropFile, 29 | }; 30 | 31 | Event(Enum _type) 32 | : m_type(_type) 33 | { 34 | } 35 | 36 | 37 | Event::Enum m_type; 38 | }; 39 | 40 | struct AxisEvent : public Event 41 | { 42 | ENTRY_IMPLEMENT_EVENT(AxisEvent, Event::Axis); 43 | 44 | GamepadAxis::Enum m_axis; 45 | int32_t m_value; 46 | GamepadHandle m_gamepad; 47 | }; 48 | 49 | struct CharEvent : public Event 50 | { 51 | ENTRY_IMPLEMENT_EVENT(CharEvent, Event::Char); 52 | 53 | uint8_t m_len; 54 | uint8_t m_char[4]; 55 | }; 56 | 57 | struct GamepadEvent : public Event 58 | { 59 | ENTRY_IMPLEMENT_EVENT(GamepadEvent, Event::Gamepad); 60 | 61 | GamepadHandle m_gamepad; 62 | bool m_connected; 63 | }; 64 | 65 | struct KeyEvent : public Event 66 | { 67 | ENTRY_IMPLEMENT_EVENT(KeyEvent, Event::Key); 68 | 69 | Key::Enum m_key; 70 | uint8_t m_modifiers; 71 | bool m_down; 72 | }; 73 | 74 | struct MouseEvent : public Event 75 | { 76 | ENTRY_IMPLEMENT_EVENT(MouseEvent, Event::Mouse); 77 | 78 | int32_t m_mx; 79 | int32_t m_my; 80 | int32_t m_mz; 81 | MouseButton::Enum m_button; 82 | bool m_down; 83 | bool m_move; 84 | }; 85 | 86 | struct SizeEvent : public Event 87 | { 88 | ENTRY_IMPLEMENT_EVENT(SizeEvent, Event::Size); 89 | 90 | uint32_t m_width; 91 | uint32_t m_height; 92 | }; 93 | 94 | struct WindowEvent : public Event 95 | { 96 | ENTRY_IMPLEMENT_EVENT(WindowEvent, Event::Window); 97 | 98 | void* m_nwh; 99 | }; 100 | 101 | struct SuspendEvent : public Event 102 | { 103 | ENTRY_IMPLEMENT_EVENT(SuspendEvent, Event::Suspend); 104 | 105 | Suspend::Enum m_state; 106 | }; 107 | 108 | struct DropFileEvent : public Event 109 | { 110 | ENTRY_IMPLEMENT_EVENT(DropFileEvent, Event::DropFile); 111 | 112 | bx::FilePath m_filePath; 113 | }; 114 | 115 | const Event* poll(); 116 | const Event* poll(WindowHandle ); 117 | void release(const Event* _event); 118 | 119 | class EventQueue 120 | { 121 | public: 122 | EventQueue() 123 | : m_queue(g_allocator) 124 | { 125 | } 126 | 127 | ~EventQueue() 128 | { 129 | for (const Event* ev = poll(); NULL != ev; ev = poll() ) 130 | { 131 | release(ev); 132 | } 133 | } 134 | 135 | void postAxisEvent(GamepadHandle _gamepad, GamepadAxis::Enum _axis, int32_t _value) 136 | { 137 | AxisEvent* ev = BX_NEW(g_allocator, AxisEvent)(); 138 | ev->m_gamepad = _gamepad; 139 | ev->m_axis = _axis; 140 | ev->m_value = _value; 141 | m_queue.push(ev); 142 | } 143 | 144 | void postCharEvent(uint8_t _len, const uint8_t _char[4]) 145 | { 146 | CharEvent* ev = BX_NEW(g_allocator, CharEvent)(); 147 | ev->m_len = _len; 148 | bx::memCopy(ev->m_char, _char, 4); 149 | m_queue.push(ev); 150 | } 151 | 152 | void postExitEvent() 153 | { 154 | Event* ev = BX_NEW(g_allocator, Event)(Event::Exit); 155 | m_queue.push(ev); 156 | } 157 | 158 | void postGamepadEvent(GamepadHandle _gamepad, bool _connected) 159 | { 160 | GamepadEvent* ev = BX_NEW(g_allocator, GamepadEvent)(); 161 | ev->m_gamepad = _gamepad; 162 | ev->m_connected = _connected; 163 | m_queue.push(ev); 164 | } 165 | 166 | void postKeyEvent(Key::Enum _key, uint8_t _modifiers, bool _down) 167 | { 168 | KeyEvent* ev = BX_NEW(g_allocator, KeyEvent)(); 169 | ev->m_key = _key; 170 | ev->m_modifiers = _modifiers; 171 | ev->m_down = _down; 172 | m_queue.push(ev); 173 | } 174 | 175 | void postMouseEvent(int32_t _mx, int32_t _my, int32_t _mz) 176 | { 177 | MouseEvent* ev = BX_NEW(g_allocator, MouseEvent)(); 178 | ev->m_mx = _mx; 179 | ev->m_my = _my; 180 | ev->m_mz = _mz; 181 | ev->m_button = MouseButton::None; 182 | ev->m_down = false; 183 | ev->m_move = true; 184 | m_queue.push(ev); 185 | } 186 | 187 | void postMouseEvent(int32_t _mx, int32_t _my, int32_t _mz, MouseButton::Enum _button, bool _down) 188 | { 189 | MouseEvent* ev = BX_NEW(g_allocator, MouseEvent)(); 190 | ev->m_mx = _mx; 191 | ev->m_my = _my; 192 | ev->m_mz = _mz; 193 | ev->m_button = _button; 194 | ev->m_down = _down; 195 | ev->m_move = false; 196 | m_queue.push(ev); 197 | } 198 | 199 | void postSizeEvent(uint32_t _width, uint32_t _height) 200 | { 201 | SizeEvent* ev = BX_NEW(g_allocator, SizeEvent)(); 202 | ev->m_width = _width; 203 | ev->m_height = _height; 204 | m_queue.push(ev); 205 | } 206 | 207 | void postWindowEvent(void* _nwh = NULL) 208 | { 209 | WindowEvent* ev = BX_NEW(g_allocator, WindowEvent)(); 210 | ev->m_nwh = _nwh; 211 | m_queue.push(ev); 212 | } 213 | 214 | void postSuspendEvent(Suspend::Enum _state) 215 | { 216 | SuspendEvent* ev = BX_NEW(g_allocator, SuspendEvent)(); 217 | ev->m_state = _state; 218 | m_queue.push(ev); 219 | } 220 | 221 | void postDropFileEvent(const bx::FilePath& _filePath) 222 | { 223 | DropFileEvent* ev = BX_NEW(g_allocator, DropFileEvent)(); 224 | ev->m_filePath = _filePath; 225 | m_queue.push(ev); 226 | } 227 | 228 | const Event* poll() 229 | { 230 | return m_queue.pop(); 231 | } 232 | 233 | void release(const Event* _event) const 234 | { 235 | BX_DELETE(g_allocator, const_cast(_event) ); 236 | } 237 | 238 | private: 239 | bx::SpScUnboundedQueueT m_queue; 240 | }; 241 | 242 | } // ari 243 | -------------------------------------------------------------------------------- /include/ari/io/PlatformWindow.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../aridef.hpp" 3 | #include 4 | #include "IoEvents.hpp" 5 | #include "../Delegate.hpp" 6 | #include "tinystl/vector.h" 7 | 8 | namespace ari 9 | { 10 | class ARI_API PlatformWindow 11 | { 12 | friend class Engine; 13 | 14 | public: 15 | 16 | enum class Type 17 | { 18 | Main, 19 | Child, 20 | Popup 21 | }; 22 | 23 | PlatformWindow(Type _type): m_Type(_type) {} 24 | virtual ~PlatformWindow() {} 25 | 26 | virtual bool Init(int _posx, int _posy, int _width, int _height, uint32_t _flags, 27 | const char* _title) = 0; 28 | 29 | virtual bool Run() = 0; 30 | 31 | virtual void Show(bool _show) = 0; 32 | 33 | virtual void SetMousePos(int _x, int _y) = 0; 34 | 35 | virtual void SetTitle(const char* _title) = 0; 36 | 37 | virtual void SetFlags(uint32_t _flags, bool _addFlags = false) = 0; 38 | 39 | virtual void GetPos(int& _x, int& _y) = 0; 40 | virtual void SetPos(int _x, int _y) = 0; 41 | 42 | virtual void GetSize(int& _width, int& _height); 43 | virtual void SetSize(int _width, int _height) = 0; 44 | 45 | virtual void SetAlpha(unsigned char _alpha) = 0; 46 | 47 | virtual void SetMouseLock(bool _lock) = 0; 48 | 49 | virtual void ToggleFrame() = 0; 50 | 51 | virtual bool IsWindowMaximized() = 0; 52 | virtual void SetWindowMaximized(bool _maximize) = 0; 53 | virtual bool IsWindowMinimized() = 0; 54 | virtual void SetWindowMinimized(bool _minimize) = 0; 55 | 56 | virtual void* GetHandle() = 0; 57 | 58 | void AddOnKeyDelegate(DelegateTwoParam* _pDelegate); 59 | void RemoveOnKeyDelegate(DelegateTwoParam* _pDelegate); 60 | 61 | void AddOnCharDelegate(DelegateTwoParam* _pDelegate); 62 | void RemoveOnCharDelegate(DelegateTwoParam* _pDelegate); 63 | 64 | void AddOnMouseButtonDelegate(DelegateTwoParam* _pDelegate); 65 | void RemoveOnMouseButtonDelegate(DelegateTwoParam* _pDelegate); 66 | 67 | void AddOnMouseMoveDelegate(DelegateTwoParam* _pDelegate); 68 | void RemoveOnMouseMoveDelegate(DelegateTwoParam* _pDelegate); 69 | 70 | void AddOnMouseWheelDelegate(DelegateOneParam* _pDelegate); 71 | void RemoveOnMouseWheelDelegate(DelegateOneParam* _pDelegate); 72 | 73 | void AddOnSizeDelegate(DelegateTwoParam* _pDelegate); 74 | void RemoveOnSizeDelegate(DelegateTwoParam* _pDelegate); 75 | 76 | bool ProcessEvents(uint32_t& _width, uint32_t& _height, uint32_t& _debug, uint32_t& _reset, 77 | MouseState* _mouse); 78 | 79 | protected: 80 | 81 | Type m_Type; 82 | uint32_t m_width; 83 | uint32_t m_height; 84 | uint32_t m_oldWidth; 85 | uint32_t m_oldHeight; 86 | uint32_t m_frameWidth; 87 | uint32_t m_frameHeight; 88 | float m_aspectRatio; 89 | EventQueue m_eventQueue; 90 | tinystl::vector*> 91 | m_vOnKeys; 92 | tinystl::vector*> 93 | m_vOnChar; 94 | tinystl::vector*> 95 | m_vOnMouseButtons; 96 | tinystl::vector*> 97 | m_vOnMouseMove; 98 | tinystl::vector*> 99 | m_vOnMouseWheel; 100 | tinystl::vector*> 101 | m_vOnSize; 102 | 103 | }; // Window 104 | 105 | } // ari 106 | -------------------------------------------------------------------------------- /include/ari/math/Matrix.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../aridef.hpp" 4 | #include "bx/macros.h" 5 | #include "bx/float4x4_t.h" 6 | #include "Vector.hpp" 7 | 8 | namespace ari 9 | { 10 | BX_ALIGN_DECL_16(struct) Matrix 11 | { 12 | union 13 | { 14 | float v[16]; 15 | struct 16 | { 17 | float _11, _12, _13, _14; 18 | float _21, _22, _23, _24; 19 | float _31, _32, _33, _34; 20 | float _41, _42, _43, _44; 21 | }; 22 | bx::float4x4_t f; 23 | }; 24 | 25 | //! Constructor: Identity the matrix. 26 | Matrix() : 27 | _11(1.0f), _12(0.0f), _13(0.0f), _14(0.0f), 28 | _21(0.0f), _22(1.0f), _23(0.0f), _24(0.0f), 29 | _31(0.0f), _32(0.0f), _33(1.0f), _34(0.0f), 30 | _41(0.0f), _42(0.0f), _43(0.0f), _44(1.0f) 31 | { } 32 | 33 | //! make identity matrix 34 | void Identity(); 35 | 36 | //! Multiply of two matrices. 37 | Matrix operator *(const Matrix &m) const; 38 | 39 | //! Multiply of two matrices. 40 | void operator *=(const Matrix &m); 41 | 42 | //! Set position and rotation 43 | void SetPositionRotation(const Vector3& position, 44 | const Vector3& rotation); 45 | 46 | //! Optimized function to set position, rotation and scale at once. 47 | void SetTransform(const Vector3& position, 48 | const Vector3& rotation, 49 | const Vector3& scale); 50 | 51 | }; // Matrix 52 | 53 | } // ari 54 | -------------------------------------------------------------------------------- /include/ari/math/Rect.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace ari 4 | { 5 | template 6 | struct Rect 7 | { 8 | Rect() : x(0), y(0), width(0), height(0) { } 9 | 10 | Rect(const T _x, const T _y, const T _width, const T _height): 11 | x(_x), y(_y), width(_width), height(_height) { } 12 | 13 | void Set(const T _x, const T _y, const T _width, const T _height) 14 | { 15 | x = _x; 16 | y = _y; 17 | width = _width; 18 | height = _height; 19 | } 20 | 21 | bool operator == (const Rect &v) const 22 | { 23 | return (width == v.width && height == v.height && x == v.x && y == v.y); 24 | } 25 | 26 | bool operator != (const Rect &v) const 27 | { 28 | return (width != v.width || height != v.height || x != v.x || y != v.y); 29 | } 30 | 31 | union 32 | { 33 | T p[4]; 34 | struct 35 | { 36 | T x, 37 | y, 38 | width, 39 | height; 40 | }; 41 | }; 42 | }; 43 | 44 | typedef Rect RectU16; 45 | typedef Rect RectI; 46 | typedef Rect RectF; 47 | 48 | } // ari 49 | -------------------------------------------------------------------------------- /include/ari/math/Vector.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "arimath.hpp" 5 | 6 | namespace ari 7 | { 8 | struct Vector3 9 | { 10 | Vector3(): x(0.0f), y(0.0f), z(0.0f) { } 11 | 12 | Vector3(const float _x, const float _y, const float _z): x(_x), y(_y), z(_z) { } 13 | 14 | void Set(const float _x, const float _y, const float _z) 15 | { 16 | x = _x; 17 | y = _y; 18 | z = _z; 19 | } 20 | 21 | Vector3 operator-(const Vector3& v) const 22 | { 23 | return { x - v.x, y - v.y, z - v.z }; 24 | } 25 | 26 | void Cross(const Vector3& _v1, const Vector3& _v2) 27 | { 28 | x = _v1.y*_v2.z - _v1.z*_v2.y; 29 | y = _v1.z*_v2.x - _v1.x*_v2.z; 30 | z = _v1.x*_v2.y - _v1.y*_v2.x; 31 | } 32 | 33 | //! Returns the vector length 34 | float GetLength() const 35 | { 36 | return sqrtf(x*x + y * y + z * z); 37 | } 38 | 39 | void Normalize() 40 | { 41 | float length = GetLength(); 42 | length = fEpsilon > length ? fEpsilon : length; 43 | x /= length; 44 | y /= length; 45 | z /= length; 46 | } 47 | 48 | bx::Vec3 ToVec3() const 49 | { 50 | return { 51 | x, 52 | y, 53 | z 54 | }; 55 | } 56 | 57 | union 58 | { 59 | float v[3]; 60 | struct { 61 | float x, 62 | y, 63 | z; 64 | }; 65 | }; 66 | }; // Vector3 67 | 68 | } // ari 69 | -------------------------------------------------------------------------------- /include/ari/math/arimath.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | 4 | namespace ari 5 | { 6 | //! P number. 7 | const float PI = 3.141592654f; 8 | const float TwoPI = 6.283185307f; 9 | const float PiOver2 = 1.570796326f; 10 | 11 | const float fDegToRad = 0.0174532925f; 12 | const float fRadToDeg = 57.295779513f; 13 | 14 | const float fEpsilon = 0.000001f; 15 | 16 | } // ari 17 | -------------------------------------------------------------------------------- /include/shiva/DirectoryTree.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "shivadef.hpp" 3 | #include 4 | #include "bx/file.h" 5 | #include 6 | 7 | namespace shiva 8 | { 9 | struct FileInfo 10 | { 11 | std::string Name; 12 | }; 13 | 14 | class SHIVA_API DirectoryTree 15 | { 16 | public: 17 | 18 | std::string Name; 19 | bx::FilePath Path; 20 | std::vector FileList; 21 | std::vector Directories; 22 | bool IsRoot = false; 23 | 24 | void Update(); 25 | 26 | }; 27 | 28 | } // shiva 29 | -------------------------------------------------------------------------------- /include/shiva/Editor.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "shivadef.hpp" 3 | #include "ari/en/World.hpp" 4 | #include "ari/en/gui/GuiSystem.hpp" 5 | #include "ari/en/3d/RenderSystem.hpp" 6 | #include "ari/en/3d/SceneSystem.hpp" 7 | #include "windows/ProjectBrowser.hpp" 8 | #include "windows/EditorWindowManager.hpp" 9 | 10 | namespace shiva 11 | { 12 | class Project; 13 | 14 | class SHIVA_API Editor 15 | { 16 | public: 17 | 18 | Editor(); 19 | 20 | ~Editor(); 21 | 22 | void Init(); 23 | 24 | void Update(float elasped); 25 | 26 | void LoadProject(Project* project); 27 | 28 | Project* GetCurrentProject() const { return m_pCurrentProject; } 29 | 30 | ari::GuiSystem* GetGuiSystem() { return &m_GuiSystem; } 31 | 32 | protected: 33 | 34 | ari::World m_EditorWorld; 35 | ari::GuiSystem m_GuiSystem; 36 | ari::RenderSystem m_RenderSystem; 37 | ari::SceneSystem m_SceneSystem; 38 | ProjectBrowser m_ProjectBrowser; 39 | EditorWindowManager m_EditorWindow; 40 | Project * m_pCurrentProject = nullptr; 41 | 42 | }; // Editor 43 | 44 | extern SHIVA_API Editor* g_pEditor; 45 | 46 | } // shiva 47 | -------------------------------------------------------------------------------- /include/shiva/EditorSettings.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | namespace shiva 5 | { 6 | class EditorSettings 7 | { 8 | public: 9 | 10 | std::string LastProjectPath; 11 | 12 | static EditorSettings& Get(); 13 | static void Save(); 14 | static void Load(); 15 | }; 16 | 17 | } // shiva 18 | 19 | namespace meta { 20 | 21 | template <> 22 | inline auto registerMembers() 23 | { 24 | return members( 25 | member("last_project_path", &shiva::EditorSettings::LastProjectPath) 26 | ); 27 | } 28 | 29 | } // end of namespace meta -------------------------------------------------------------------------------- /include/shiva/Project.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "bx/filepath.h" 3 | #include 4 | #include 5 | #include 6 | #include "DirectoryTree.hpp" 7 | 8 | BX_ERROR_RESULT(SH_ERROR_NOT_EMPTY_DIRECTPRY, BX_MAKEFOURCC('s', 'h', 0, 0)); 9 | 10 | namespace shiva 11 | { 12 | class Project 13 | { 14 | friend auto meta::registerMembers(); 15 | public: 16 | Project(); 17 | 18 | ~Project(); 19 | 20 | static Project* New(bx::FilePath projectPath, std::string name, bx::Error* err); 21 | 22 | void Save(); 23 | static Project* Load(bx::FilePath path, bx::Error* err); 24 | 25 | void UpdateProjectTree(); 26 | 27 | const DirectoryTree& GetTree() const { return m_Tree; } 28 | 29 | const bx::FilePath& GetPath() const { return m_ProjectPath; } 30 | 31 | private: 32 | 33 | bx::FilePath m_ProjectPath; 34 | std::string m_ProjectName; 35 | DirectoryTree m_Tree; 36 | 37 | }; // Project 38 | 39 | } // shiva 40 | 41 | namespace meta { 42 | 43 | template <> 44 | inline auto registerMembers() 45 | { 46 | return members( 47 | member("name", &shiva::Project::m_ProjectName) 48 | ); 49 | } 50 | 51 | } // end of namespace meta 52 | -------------------------------------------------------------------------------- /include/shiva/shivadef.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #if defined( _MSC_VER ) 4 | # pragma warning(disable:4251) // dll interface for std types 5 | # ifdef SHIVA_EXPORT 6 | # define SHIVA_API __declspec(dllexport) 7 | # else 8 | # define SHIVA_API __declspec(dllimport) 9 | # endif 10 | #else 11 | # ifdef SHIVA_EXPORT 12 | # define SHIVA_API __attribute__((visibility("default"))) 13 | # else 14 | # define SHIVA_API 15 | # endif 16 | #endif 17 | -------------------------------------------------------------------------------- /include/shiva/windows/AssetBrowser.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "shiva/shivadef.hpp" 3 | #include "shiva/DirectoryTree.hpp" 4 | #include "../../../src/editor/windows/AssetGui.hpp" 5 | #include "ari/en/gui/DockableWindow.hpp" 6 | #include "DockWindow.hpp" 7 | 8 | namespace ari { 9 | class Button; 10 | class Dock; 11 | class DockSpace; 12 | } 13 | 14 | namespace shiva 15 | { 16 | class AssetGui; 17 | 18 | class SHIVA_API AssetBrowser : public DockWindow 19 | { 20 | public: 21 | 22 | ~AssetBrowser(); 23 | 24 | void Init(ari::World* p_world); 25 | 26 | private: 27 | 28 | void UpdateAssets(const DirectoryTree& _tree); 29 | static DirectoryTree* FindPathTree(DirectoryTree* _tree, const std::string& _path); 30 | void OnDblClick(AssetGui* _sender); 31 | void OnRightClick(AssetGui* _sender); 32 | 33 | std::vector m_vAssets; 34 | 35 | }; // AssetBrowser 36 | 37 | } // shiva 38 | -------------------------------------------------------------------------------- /include/shiva/windows/DockWindow.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "shiva/shivadef.hpp" 3 | #include "ari/en/gui/DockableWindow.hpp" 4 | #include "ari/en/Entity.hpp" 5 | 6 | namespace shiva 7 | { 8 | /*! 9 | * DockWindow is the base class for other windows in editor. 10 | */ 11 | class SHIVA_API DockWindow 12 | { 13 | public: 14 | 15 | virtual ~DockWindow() = default; 16 | 17 | ari::DockableWindow* GetDock() const { return m_pWindow; } 18 | 19 | virtual void Init(ari::World* p_world); 20 | 21 | virtual void Shutdown(); 22 | 23 | protected: 24 | 25 | ari::Entity * m_pEntity = nullptr; 26 | ari::DockableWindow * m_pWindow = nullptr; 27 | 28 | }; 29 | 30 | } // shiva 31 | -------------------------------------------------------------------------------- /include/shiva/windows/EditorWindowManager.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "shiva/shivadef.hpp" 3 | 4 | namespace ari 5 | { 6 | class World; 7 | class Entity; 8 | class DockSpace; 9 | class Window; 10 | } 11 | 12 | namespace shiva 13 | { 14 | class AssetBrowser; 15 | class Viewport; 16 | class Project; 17 | class PropertyEditor; 18 | 19 | class SHIVA_API EditorWindowManager 20 | { 21 | public: 22 | 23 | EditorWindowManager(); 24 | 25 | ~EditorWindowManager(); 26 | 27 | void Init(ari::World* pWorld); 28 | 29 | void Shutdown(); 30 | 31 | protected: 32 | 33 | ari::Entity * m_pEntity = nullptr; 34 | AssetBrowser * m_pAssetBrowser = nullptr; 35 | Viewport * m_pViewport = nullptr; 36 | PropertyEditor * m_pPropertyEditor = nullptr; 37 | 38 | }; // EditorWindowManager 39 | 40 | } // shiva 41 | -------------------------------------------------------------------------------- /include/shiva/windows/PIE.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace shiva 4 | { 5 | 6 | } // shiva 7 | -------------------------------------------------------------------------------- /include/shiva/windows/ProjectBrowser.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "shiva/shivadef.hpp" 3 | #include "ari/en/Entity.hpp" 4 | #include "ari/en/gui/Gui.hpp" 5 | #include "ari/en/gui/Button.hpp" 6 | #include "ari/en/gui/Label.hpp" 7 | #include "DockWindow.hpp" 8 | 9 | namespace ari 10 | { 11 | class DockableWindow; 12 | class World; 13 | class TextBox; 14 | class Popup; 15 | 16 | } // ari 17 | 18 | namespace shiva 19 | { 20 | class Project; 21 | 22 | /*! 23 | * Custom GUI component to show a project in the list. 24 | */ 25 | class ProjectGui: public ari::Gui 26 | { 27 | public: 28 | bool BeginRender() override; 29 | void EndRender() override; 30 | 31 | }; // ProjectGui 32 | 33 | class SHIVA_API ProjectBrowser : DockWindow 34 | { 35 | public: 36 | ProjectBrowser(); 37 | 38 | ~ProjectBrowser(); 39 | 40 | void Init(ari::World* p_world) override; 41 | 42 | void Shutdown() override; 43 | 44 | protected: 45 | 46 | ari::TextBox * m_pNewProjectName; 47 | ari::TextBox * m_pNewProjectPath; 48 | ari::Button * m_pNewProjectBtn; 49 | ari::TextBox * m_pOpenProjectPath; 50 | ari::Button * m_pOpenProjectBtn; 51 | ari::Popup * m_pMessageBox; 52 | ari::Label * m_pMbLabel; 53 | ari::Button * m_pMbOkBtn; 54 | 55 | void OnNewProjectClick(); 56 | void OnOpenProjectClick(); 57 | 58 | void OnClickMbOk(); 59 | 60 | void ProjectOpened(Project* project); 61 | 62 | }; // ProjectBrowser 63 | 64 | } // shiva 65 | -------------------------------------------------------------------------------- /include/shiva/windows/PropertyEditor.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "DockWindow.hpp" 3 | 4 | namespace shiva 5 | { 6 | class SHIVA_API PropertyEditor : public DockWindow 7 | { 8 | public: 9 | 10 | void Init(ari::World* p_world) override; 11 | 12 | }; 13 | 14 | } // shiva 15 | -------------------------------------------------------------------------------- /include/shiva/windows/Tools.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace shiva 4 | { 5 | 6 | } // shiva 7 | -------------------------------------------------------------------------------- /include/shiva/windows/Viewport.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "DockWindow.hpp" 3 | 4 | namespace ari 5 | { 6 | class Camera; 7 | class Viewport; 8 | class Image; 9 | } 10 | 11 | namespace shiva 12 | { 13 | class SHIVA_API Viewport : public DockWindow 14 | { 15 | public: 16 | 17 | void Init(ari::World* p_world) override; 18 | 19 | protected: 20 | 21 | ari::Camera * m_pCamera = nullptr; 22 | ari::Viewport * m_pViewport = nullptr; 23 | ari::Image * m_pView = nullptr; 24 | ari::PlatformWindow * m_pPlatformWindow = nullptr; 25 | ari::DelegateTwoParam 26 | m_OnMouseMove; 27 | 28 | void OnGui(); 29 | void OnHovered(); 30 | 31 | }; 32 | 33 | } // shiva 34 | -------------------------------------------------------------------------------- /scripts/ariengine.lua: -------------------------------------------------------------------------------- 1 | project ("ariengine") 2 | kind "SharedLib" 3 | 4 | includedirs { 5 | path.join(BGFX_DIR, "include"), 6 | path.join(BGFX_DIR, "3rdparty"), 7 | path.join(BX_DIR, "include"), 8 | path.join(BIMG_DIR, "include"), 9 | path.join(ARIDEPS_DIR, "FiberTaskingLib/include"), 10 | path.join(ARIDEPS_DIR, "FiberTaskingLib/third_party/boost_context/include"), 11 | path.join(ARIDEPS_DIR, "SDL2/include"), 12 | path.join(MODULE_DIR, "deps/spdlog/include"), 13 | path.join(MODULE_DIR, "deps/brtshaderc/tools/brtshaderc"), 14 | path.join(MODULE_DIR, "deps/MetaStuff/include"), 15 | path.join(MODULE_DIR, "deps/MetaStuff/example/nlohmann_json"), 16 | path.join(MODULE_DIR, "deps/ImWindow"), 17 | path.join(MODULE_DIR, "deps/ImWindow/ImWindow"), 18 | } 19 | 20 | links { 21 | "bx", 22 | "bimg", 23 | "bgfx", 24 | "SDL2", 25 | "brtshaderc" 26 | } 27 | 28 | files { 29 | "../include/ari/**.hpp", 30 | "../include/ari/**.inl", 31 | "../src/engine/**.cpp", 32 | "../src/engine/**.hpp", 33 | "../deps/spdlog/include/**.h", 34 | "../assets/shaders/**.glsl", 35 | "../deps/bgfx/3rdparty/dear-imgui/**.h", 36 | "../deps/bgfx/3rdparty/dear-imgui/**.inl", 37 | "../deps/bgfx/3rdparty/dear-imgui/**.cpp", 38 | "../deps/bgfx/examples/common/imgui/*.h", 39 | "../deps/bgfx/examples/common/imgui/*.cpp", 40 | "../deps/imguiDock/*.cpp", 41 | "../deps/imguiDock/*.h", 42 | "../deps/ImWindow/*.h", 43 | "../deps/ImWindow/ImWindow/*.h", 44 | "../deps/ImWindow/ImWindow/*.cpp", 45 | } 46 | 47 | defines { 48 | "ARI_EXPORT", 49 | "ASSETS_DIR=\"" .. ASSETS_DIR .. "\"", 50 | } 51 | 52 | 53 | configuration {"Debug"} 54 | links { "ftlDebug", "boost_contextDebug" } 55 | 56 | configuration { "Release" } 57 | links { "ftl", "boost_context" } 58 | 59 | configuration { "vs*", "x32" } 60 | libdirs { path.join(ARIDEPS_DIR, "libs/win32") } 61 | 62 | configuration { "vs*", "x64" } 63 | libdirs { path.join(ARIDEPS_DIR, "libs/win64") } 64 | 65 | configuration { "vs*" } 66 | buildoptions { "/EHsc" } 67 | 68 | if string.find(_ACTION, "vs") then 69 | if os.isdir(path.join(MODULE_DIR, ".build/win32_" .. _ACTION .. "/bin")) == false then 70 | os.mkdir(path.join(MODULE_DIR, ".build/win32_" .. _ACTION .. "/bin")) 71 | end 72 | if os.isdir(path.join(MODULE_DIR, ".build/win64_" .. _ACTION .. "/bin")) == false then 73 | os.mkdir(path.join(MODULE_DIR, ".build/win64_" .. _ACTION .. "/bin")) 74 | end 75 | os.copyfile(path.join(ARIDEPS_DIR, "libs/win32/SDL2.dll"), path.join(MODULE_DIR, ".build/win32_" .. _ACTION .. "/bin/SDL2.dll")) 76 | os.copyfile(path.join(ARIDEPS_DIR, "libs/win64/SDL2.dll"), path.join(MODULE_DIR, ".build/win64_" .. _ACTION .. "/bin/SDL2.dll")) 77 | end 78 | -------------------------------------------------------------------------------- /scripts/genie.lua: -------------------------------------------------------------------------------- 1 | newoption { 2 | trigger = "with-tests", 3 | description = "Enable building tests.", 4 | } 5 | 6 | solution "Ariyana" 7 | configurations { 8 | "Debug", 9 | "Release", 10 | } 11 | 12 | if _ACTION == "xcode4" then 13 | platforms { 14 | "Universal", 15 | } 16 | else 17 | platforms { 18 | "x32", 19 | "x64", 20 | "Native", -- for targets where bitness is not specified 21 | } 22 | end 23 | 24 | language "C++" 25 | startproject "Shiva" 26 | 27 | MODULE_DIR = path.getabsolute("../") 28 | ASSETS_DIR = "../../../assets" 29 | ARIDEPS_DIR = path.getabsolute("../deps/arideps") 30 | BGFX_DIR = path.getabsolute("../deps/bgfx") 31 | BX_DIR = path.getabsolute("../deps/bx") 32 | BIMG_DIR = path.getabsolute("../deps/bimg") 33 | 34 | function getBuildDir() 35 | configuration { "x32", "vs*" } 36 | BUILD_DIR = path.getabsolute("../.build/" .. "win32_" .. _ACTION .. "/bin") 37 | defines { 38 | "BUILD_DIR=\"" .. BUILD_DIR .. "/\"", 39 | } 40 | 41 | configuration { "x64", "vs*" } 42 | BUILD_DIR = path.getabsolute("../.build/" .. "win64_" .. _ACTION .. "/bin") 43 | defines { 44 | "BUILD_DIR=\"" .. BUILD_DIR .. "/\"", 45 | } 46 | 47 | configuration {} 48 | 49 | end 50 | 51 | local BGFX_BUILD_DIR = path.join(MODULE_DIR, ".build") 52 | local BGFX_THIRD_PARTY_DIR = path.join(BGFX_DIR, "3rdparty") 53 | 54 | dofile (path.join(BX_DIR, "scripts/toolchain.lua")) 55 | if not toolchain(BGFX_BUILD_DIR, BGFX_THIRD_PARTY_DIR) then 56 | return -- no action specified 57 | end 58 | 59 | function copyLib() 60 | end 61 | 62 | dofile("ariengine.lua") 63 | dofile("shivaeditor.lua") 64 | 65 | dofile(path.join(BGFX_DIR, "scripts/bgfx.lua")) 66 | 67 | group "deps" 68 | bgfxProject("", "SharedLib", {}) 69 | 70 | dofile(path.join(BX_DIR, "scripts/bx.lua")) 71 | dofile(path.join(BIMG_DIR, "scripts/bimg.lua")) 72 | dofile(path.join(BIMG_DIR, "scripts/bimg_decode.lua")) 73 | dofile(path.join(MODULE_DIR, "deps/brtshaderc/scripts/brtshaderc.lua")) 74 | 75 | function testProject(...) 76 | for _, name in ipairs({...}) do 77 | project ("test-" .. name) 78 | uuid (os.uuid("test-" .. name)) 79 | kind "ConsoleApp" 80 | 81 | files { 82 | path.join(MODULE_DIR, "tests", name, "**.cpp"), 83 | path.join(MODULE_DIR, "tests", name, "**.hpp"), 84 | } 85 | 86 | includedirs { 87 | path.join(MODULE_DIR, "include"), 88 | path.join(BX_DIR, "include"), 89 | path.join(BIMG_DIR, "include"), 90 | path.join(BGFX_DIR, "3rdparty"), 91 | path.join(BGFX_DIR, "include"), 92 | } 93 | 94 | links { 95 | "ariengine", 96 | } 97 | 98 | end 99 | end 100 | 101 | if _OPTIONS["with-tests"] then 102 | group "tests" 103 | 104 | testProject("00-init", 105 | "01-cubes", 106 | "02-gui") 107 | end 108 | 109 | group "plugins" 110 | dofile("plugins.lua") 111 | -------------------------------------------------------------------------------- /scripts/plugins.lua: -------------------------------------------------------------------------------- 1 | project ("plugin_bimg") 2 | kind "SharedLib" 3 | 4 | includedirs { 5 | path.join(BX_DIR, "include"), 6 | path.join(BIMG_DIR, "include"), 7 | path.join(BGFX_DIR, "include"), 8 | } 9 | 10 | links { 11 | "bx", 12 | "bimg", 13 | "bimg_decode", 14 | "bgfx", 15 | "ariengine", 16 | } 17 | 18 | files { 19 | "../src/plugins/bimg/**.cpp", 20 | "../src/plugins/bimg/**.hpp", 21 | } 22 | 23 | defines { 24 | "ARI_PLUGIN_EXPORT", 25 | "ASSETS_DIR=\"" .. ASSETS_DIR .. "\"", 26 | } 27 | 28 | configuration { "vs*" } 29 | buildoptions { "/EHsc" } 30 | -------------------------------------------------------------------------------- /scripts/shivaeditor.lua: -------------------------------------------------------------------------------- 1 | project ("shivaeditor") 2 | kind "SharedLib" 3 | 4 | includedirs { 5 | path.join(BX_DIR, "include"), 6 | path.join(BIMG_DIR, "include"), 7 | path.join(BGFX_DIR, "include"), 8 | path.join(BGFX_DIR, "3rdparty"), 9 | path.join(MODULE_DIR, "deps/MetaStuff/include"), 10 | path.join(MODULE_DIR, "deps/MetaStuff/example/nlohmann_json"), 11 | "../include", 12 | } 13 | 14 | links { 15 | "bx", 16 | "ariengine", 17 | } 18 | 19 | files { 20 | "../include/shiva/**.hpp", 21 | "../src/editor/**.cpp", 22 | "../src/editor/**.hpp", 23 | } 24 | 25 | defines { 26 | "SHIVA_EXPORT", 27 | "ASSETS_DIR=\"" .. ASSETS_DIR .. "\"", 28 | } 29 | 30 | configuration { "vs*" } 31 | buildoptions { "/EHsc" } 32 | 33 | project ("Shiva") 34 | kind "ConsoleApp" 35 | 36 | includedirs { 37 | path.join(BX_DIR, "include"), 38 | path.join(BIMG_DIR, "include"), 39 | path.join(BGFX_DIR, "include"), 40 | path.join(BGFX_DIR, "3rdparty"), 41 | "../include" 42 | } 43 | 44 | files { 45 | "../src/shiva/**.cpp", 46 | "../src/shiva/**.hpp", 47 | } 48 | 49 | getBuildDir() 50 | 51 | configuration { "vs*" } 52 | buildoptions { "/EHsc" } 53 | -------------------------------------------------------------------------------- /src/editor/DirectoryTree.cpp: -------------------------------------------------------------------------------- 1 | #include "..\..\include\shiva\DirectoryTree.hpp" 2 | #include "dirent.h" 3 | 4 | namespace shiva 5 | { 6 | void DirectoryTree::Update() 7 | { 8 | if (Name.length() == 0) 9 | { 10 | bx::StringView p = Path.get(); 11 | const char* slash = bx::strRFind(p, '/').getPtr(); 12 | slash++; 13 | Name = slash; 14 | } 15 | 16 | // clear the childs. 17 | Directories.clear(); 18 | FileList.clear(); 19 | 20 | // get file list. 21 | DIR* dir = opendir(Path.get()); 22 | dirent* next; 23 | do 24 | { 25 | next = readdir(dir); 26 | if (next) 27 | { 28 | if (next->d_name[0] == '.') 29 | continue; 30 | 31 | if (next->d_type == DT_DIR) 32 | { 33 | DirectoryTree child; 34 | child.Path = Path; 35 | child.Path.join(next->d_name); 36 | Directories.push_back(child); 37 | Directories[Directories.size() - 1].Update(); 38 | } 39 | else if (next->d_type == DT_REG) 40 | { 41 | FileList.push_back({ next->d_name }); 42 | } 43 | else 44 | { 45 | printf("Unknown file type.\n"); 46 | } 47 | } 48 | } 49 | while (next); 50 | } 51 | 52 | } // shiva 53 | -------------------------------------------------------------------------------- /src/editor/Editor.cpp: -------------------------------------------------------------------------------- 1 | #include "../../include/shiva/Editor.hpp" 2 | #include "shiva/Project.hpp" 3 | #include "shiva/EditorSettings.hpp" 4 | 5 | namespace shiva 6 | { 7 | Editor* g_pEditor = nullptr; 8 | 9 | Editor::Editor() 10 | { 11 | g_pEditor = this; 12 | } 13 | 14 | Editor::~Editor() 15 | { 16 | g_pEditor = nullptr; 17 | } 18 | 19 | void Editor::Init() 20 | { 21 | // Load editor settings 22 | EditorSettings::Load(); 23 | 24 | // Add Systems 25 | m_EditorWorld.AddSystem(&m_GuiSystem); 26 | m_EditorWorld.AddSystem(&m_RenderSystem); 27 | m_EditorWorld.AddSystem(&m_SceneSystem); 28 | //m_EditorWorld.SetUpdateType(ari::World::UpdateType::Sync); 29 | 30 | // Init project browser 31 | m_ProjectBrowser.Init(&m_EditorWorld); 32 | } 33 | 34 | void Editor::Update(float elasped) 35 | { 36 | m_EditorWorld.Update(elasped); 37 | } 38 | 39 | void Editor::LoadProject(Project* project) 40 | { 41 | delete m_pCurrentProject; 42 | m_pCurrentProject = project; 43 | 44 | EditorSettings::Get().LastProjectPath = project->GetPath().get(); 45 | EditorSettings::Save(); 46 | 47 | m_EditorWindow.Init(&m_EditorWorld); 48 | } 49 | 50 | } // shiva 51 | -------------------------------------------------------------------------------- /src/editor/EditorSettings.cpp: -------------------------------------------------------------------------------- 1 | #include "..\..\include\shiva\EditorSettings.hpp" 2 | #include 3 | #include 4 | #include 5 | #include "bx/file.h" 6 | 7 | namespace shiva 8 | { 9 | EditorSettings & EditorSettings::Get() 10 | { 11 | static EditorSettings settings; 12 | return settings; 13 | } 14 | 15 | void EditorSettings::Save() 16 | { 17 | json root; 18 | to_json(root, Get()); 19 | std::ofstream out("editor_settings.json"); 20 | 21 | out << std::setw(4) << root << std::endl; 22 | 23 | } // Save 24 | 25 | void EditorSettings::Load() 26 | { 27 | bx::FileReader file; 28 | bx::Error err; 29 | if (!file.open("editor_settings.json", &err)) 30 | { 31 | 32 | return; 33 | } 34 | const int32_t size = static_cast(file.seek(0, bx::Whence::End)); 35 | file.seek(0, bx::Whence::Begin); 36 | char* data = new char[size + 1]; 37 | file.read(data, size, &err); 38 | data[size] = 0; 39 | 40 | json root = json::parse(data); 41 | delete[] data; 42 | from_json(root, Get()); 43 | 44 | } // Load 45 | 46 | 47 | } // shiva 48 | -------------------------------------------------------------------------------- /src/editor/Project.cpp: -------------------------------------------------------------------------------- 1 | #include "..\..\include\shiva\Project.hpp" 2 | #include "ari/Engine.hpp" 3 | #include 4 | #include 5 | #include 6 | #include "bx/file.h" 7 | 8 | namespace shiva 9 | { 10 | Project::Project() 11 | { 12 | } 13 | 14 | Project::~Project() 15 | { 16 | } 17 | 18 | Project * Project::New(bx::FilePath projectPath, std::string name, bx::Error* err) 19 | { 20 | projectPath.join(name.c_str()); 21 | 22 | // check the folder is empty 23 | bx::FileInfo fi; 24 | if (bx::stat(projectPath, fi)) 25 | { 26 | BX_ERROR_SET(err, SH_ERROR_NOT_EMPTY_DIRECTPRY, "The directory is already exist."); 27 | return nullptr; 28 | } 29 | 30 | // 1st Create the folders 31 | if (!bx::makeAll(projectPath, err)) 32 | { 33 | return nullptr; 34 | } 35 | bx::FilePath tmp = projectPath; 36 | tmp.join("src"); 37 | bx::make(tmp, err); 38 | tmp = projectPath; 39 | tmp.join("scripts"); 40 | bx::make(tmp, err); 41 | tmp = projectPath; 42 | tmp.join("assets"); 43 | bx::make(tmp, err); 44 | tmp = projectPath; 45 | tmp.join(".import"); 46 | bx::make(tmp, err); 47 | 48 | Project* p = new Project(); 49 | p->m_ProjectName = name; 50 | p->m_Tree.Path = projectPath; 51 | p->m_Tree.IsRoot = true; 52 | projectPath.join(name.append(".shiva").c_str()); 53 | p->m_ProjectPath = projectPath; 54 | p->Save(); 55 | p->UpdateProjectTree(); 56 | 57 | return p; 58 | } 59 | 60 | void Project::Save() 61 | { 62 | json root; 63 | to_json(root, *this); 64 | std::ofstream out(m_ProjectPath.get()); 65 | 66 | out << std::setw(4) << root << std::endl; 67 | } 68 | 69 | Project * Project::Load(bx::FilePath path, bx::Error* err) 70 | { 71 | bx::FileReader file; 72 | if (!file.open(path, err)) 73 | { 74 | return nullptr; 75 | } 76 | const int32_t size = static_cast(file.seek(0, bx::Whence::End)); 77 | file.seek(0, bx::Whence::Begin); 78 | char* data = new char[size + 1]; 79 | file.read(data, size, err); 80 | data[size] = 0; 81 | json root = json::parse(data); 82 | delete[] data; 83 | Project* p = new Project(); 84 | from_json(root, *p); 85 | p->m_ProjectPath = path; 86 | char* str_path = (char*)path.getPath().getPtr(); 87 | str_path[path.getPath().getLength() - 1] = 0; 88 | p->m_Tree.Path.set(str_path); 89 | p->m_Tree.IsRoot = true; 90 | p->UpdateProjectTree(); 91 | return p; 92 | } 93 | 94 | void Project::UpdateProjectTree() 95 | { 96 | m_Tree.Update(); 97 | } 98 | 99 | } // shiva 100 | -------------------------------------------------------------------------------- /src/editor/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "ari/Program.hpp" 3 | #include "ari/en/World.hpp" 4 | #include "ari/en/Entity.hpp" 5 | #include "ari/en/gui/GuiSystem.hpp" 6 | #include "ari/en/gui/Window.hpp" 7 | #include "ari/en/gui/CheckBox.hpp" 8 | #include "ari/en/gui/Label.hpp" 9 | #include "ari/en/gui/Dock.hpp" 10 | #include "shiva/Editor.hpp" 11 | 12 | #include "../../deps/cr/cr.h" 13 | 14 | class ShivaEditor : public ari::IProgram 15 | { 16 | public: 17 | explicit ShivaEditor(const char* programName) 18 | : IProgram(programName) 19 | { 20 | } 21 | 22 | ~ShivaEditor() override = default; 23 | 24 | void Init() override 25 | { 26 | // Init editor 27 | m_editor.Init(); 28 | } 29 | 30 | bool Update(uint32_t frame_number, float elasped) override 31 | { 32 | m_editor.Update(elasped); 33 | return true; 34 | } 35 | 36 | int Shutdown() override 37 | { 38 | return 0; 39 | } 40 | 41 | shiva::Editor m_editor; 42 | }; 43 | 44 | static CR_STATE ari::Engine* p_device = nullptr; 45 | static CR_STATE ari::InitParams* p = new ari::InitParams; 46 | static CR_STATE ShivaEditor* prog = new ShivaEditor("ShivaEditor"); 47 | 48 | extern "C" 49 | { 50 | CR_EXPORT int cr_main(struct cr_plugin *ctx, enum cr_op operation) 51 | { 52 | assert(ctx); 53 | switch (operation) { 54 | case CR_LOAD: 55 | { 56 | if (p_device == nullptr) 57 | { 58 | printf("CR_LOAD\n"); 59 | p_device = new ari::Engine(); 60 | p->Program = prog; 61 | p_device->Init(p); 62 | p_device->plugin_manager.Load("bimg", nullptr); 63 | } 64 | else 65 | { 66 | printf("Reloaded: %d\n", ctx->version); 67 | ari::g_pEngine = p_device; 68 | p->Program = prog; 69 | p_device->SetParams(p); 70 | p_device->UnlockUpdateThread(); 71 | } 72 | return 0; 73 | } 74 | case CR_UNLOAD: 75 | { 76 | printf("CR_UNLOAD\n"); 77 | p->Program = nullptr; 78 | p_device->LockUpdateThread(); 79 | } 80 | case CR_STEP: 81 | { 82 | return p_device->Run(); 83 | } 84 | } 85 | return 0; 86 | } 87 | } -------------------------------------------------------------------------------- /src/editor/windows/AssetBrowser.cpp: -------------------------------------------------------------------------------- 1 | #include "../../../include/shiva/windows/AssetBrowser.hpp" 2 | #include "ari/en/gui/Dock.hpp" 3 | #include "ari/en/gui/Button.hpp" 4 | #include "ari/en/gui/DockSpace.hpp" 5 | #include "ari/en/World.hpp" 6 | #include "AssetGui.hpp" 7 | #include "shiva/Editor.hpp" 8 | #include "shiva/Project.hpp" 9 | #include "ari/Engine.hpp" 10 | 11 | namespace shiva 12 | { 13 | AssetBrowser::~AssetBrowser() 14 | { 15 | Shutdown(); 16 | } 17 | 18 | void AssetBrowser::Init(ari::World* p_world) 19 | { 20 | DockWindow::Init(p_world); 21 | 22 | m_pWindow->SetTitle("Asset browser"); 23 | m_pWindow->Dock(ari::DockableWindow::Oriention::Left, 0.25f); 24 | UpdateAssets(g_pEditor->GetCurrentProject()->GetTree()); 25 | } 26 | 27 | void AssetBrowser::UpdateAssets(const DirectoryTree & _tree) 28 | { 29 | size_t c = 0; 30 | std::string strFile = ASSETS_DIR; 31 | strFile += "/icons/filetypes/DEFAULT.png"; 32 | std::string strFolder = ASSETS_DIR; 33 | strFolder += "/icons/filetypes/folder.png"; 34 | if (!_tree.IsRoot) 35 | { 36 | std::string strUp = ASSETS_DIR; 37 | strUp += "/icons/filetypes/folder_up.png"; 38 | m_vAssets[0]->Image = ari::g_pEngine->texture_manager.Load(strUp, nullptr); 39 | m_vAssets[0]->Path = _tree.Path.get(); 40 | m_vAssets[0]->Path = m_vAssets[0]->Path.substr(0, m_vAssets[0]->Path.rfind('/')); 41 | m_vAssets[0]->FileName = ".."; 42 | m_vAssets[0]->IsDirectory = true; 43 | c++; 44 | } 45 | for (size_t i = 0; i < _tree.Directories.size(); ++i) 46 | { 47 | if (m_vAssets.size() <= c) 48 | { 49 | AssetGui* p_gui = new AssetGui; 50 | p_gui->Image = ari::g_pEngine->texture_manager.Load(strFolder, nullptr); 51 | p_gui->FileName = _tree.Directories[i].Name; 52 | p_gui->Path = _tree.Directories[i].Path.get(); 53 | p_gui->IsDirectory = true; 54 | p_gui->OnDblClick.Bind(this, &AssetBrowser::OnDblClick); 55 | p_gui->OnRightClick.Bind(this, &AssetBrowser::OnRightClick); 56 | if (c % 2 == 1) 57 | p_gui->SameLine = true; 58 | m_pWindow->AddChild(p_gui); 59 | m_vAssets.push_back(p_gui); 60 | } 61 | else 62 | { 63 | m_vAssets[c]->Image = ari::g_pEngine->texture_manager.Load(strFolder, nullptr); 64 | m_vAssets[c]->FileName = _tree.Directories[i].Name; 65 | m_vAssets[c]->Visible = true; 66 | m_vAssets[c]->Path = _tree.Directories[i].Path.get(); 67 | m_vAssets[c]->IsDirectory = true; 68 | } 69 | c++; 70 | } 71 | for (size_t i = 0; i < _tree.FileList.size(); ++i) 72 | { 73 | if (m_vAssets.size() <= c) 74 | { 75 | AssetGui* p_gui = new AssetGui; 76 | p_gui->Image = ari::g_pEngine->texture_manager.Load(strFile, nullptr); 77 | p_gui->FileName = _tree.FileList[i].Name; 78 | p_gui->Path = _tree.Path.get(); 79 | p_gui->IsDirectory = false; 80 | p_gui->OnDblClick.Bind(this, &AssetBrowser::OnDblClick); 81 | p_gui->OnRightClick.Bind(this, &AssetBrowser::OnRightClick); 82 | if (c % 2 == 1) 83 | p_gui->SameLine = true; 84 | m_pWindow->AddChild(p_gui); 85 | m_vAssets.push_back(p_gui); 86 | } 87 | else 88 | { 89 | m_vAssets[c]->Image = ari::g_pEngine->texture_manager.Load(strFile, nullptr); 90 | m_vAssets[c]->FileName = _tree.FileList[i].Name; 91 | m_vAssets[c]->Visible = true; 92 | m_vAssets[c]->Path = _tree.Path.get(); 93 | m_vAssets[c]->IsDirectory = false; 94 | } 95 | c++; 96 | } 97 | for (size_t i = c; i < m_vAssets.size(); i++) 98 | { 99 | m_vAssets[i]->Visible = false; 100 | } 101 | } 102 | 103 | DirectoryTree* AssetBrowser::FindPathTree(DirectoryTree* _tree, const std::string& _path) 104 | { 105 | if (_tree->Path.get() == _path) 106 | return _tree; 107 | for (size_t i = 0; i < _tree->Directories.size(); i++) 108 | { 109 | const auto r = FindPathTree(&_tree->Directories[i], _path); 110 | if (r) 111 | return r; 112 | } 113 | return nullptr; 114 | } 115 | 116 | void AssetBrowser::OnDblClick(AssetGui* _sender) 117 | { 118 | if (_sender->IsDirectory) 119 | { 120 | DirectoryTree tree = g_pEditor->GetCurrentProject()->GetTree(); 121 | auto r = FindPathTree(&tree, _sender->Path); 122 | if (r) 123 | UpdateAssets(*r); 124 | else 125 | printf("Can't find the directory %s.", _sender->Path.c_str()); 126 | } 127 | } 128 | 129 | void AssetBrowser::OnRightClick(AssetGui* _sender) 130 | { 131 | } 132 | 133 | } // shiva 134 | -------------------------------------------------------------------------------- /src/editor/windows/AssetGui.cpp: -------------------------------------------------------------------------------- 1 | #include "AssetGui.hpp" 2 | #include "../../../deps/bgfx/examples/common/imgui/imgui.h" 3 | #include "ari/Engine.hpp" 4 | 5 | namespace shiva 6 | { 7 | AssetGui::AssetGui() 8 | { 9 | } 10 | 11 | AssetGui::~AssetGui() 12 | { 13 | } 14 | 15 | bool AssetGui::BeginRender() 16 | { 17 | ImGui::BeginGroup(); 18 | ImGui::Image(Image->Handle, ImVec2(64, 64)); 19 | ImGui::TextWrapped(FileName.c_str()); 20 | ImGui::EndGroup(); 21 | if (ImGui::IsItemHovered()) 22 | { 23 | if (OnDblClick.IsBound()) 24 | if (ImGui::IsMouseDoubleClicked(0)) 25 | OnDblClick.Execute(this); 26 | if (OnRightClick.IsBound()) 27 | if (ImGui::IsMouseClicked(1)) 28 | OnRightClick.Execute(this); 29 | } 30 | return false; 31 | } 32 | 33 | } // shiva 34 | -------------------------------------------------------------------------------- /src/editor/windows/AssetGui.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "ari/en/gui/Gui.hpp" 3 | #include "ari/gfx/Texture.hpp" 4 | #include "ari/Delegate.hpp" 5 | 6 | namespace shiva 7 | { 8 | class AssetGui: public ari::Gui 9 | { 10 | public: 11 | AssetGui(); 12 | ~AssetGui() override; 13 | bool BeginRender() override; 14 | 15 | std::shared_ptr Image; 16 | std::string FileName, 17 | Path; 18 | bool IsDirectory; 19 | ari::DelegateOneParam 20 | OnDblClick, 21 | OnRightClick; 22 | }; 23 | 24 | } // shiva 25 | -------------------------------------------------------------------------------- /src/editor/windows/DockWindow.cpp: -------------------------------------------------------------------------------- 1 | #include "shiva/windows/DockWindow.hpp" 2 | #include "ari/en/World.hpp" 3 | #include "shiva/Editor.hpp" 4 | 5 | namespace shiva 6 | { 7 | void DockWindow::Init(ari::World* p_world) 8 | { 9 | m_pEntity = new ari::Entity; 10 | p_world->AddEntity(m_pEntity); 11 | m_pWindow = new ari::DockableWindow(g_pEditor->GetGuiSystem()); 12 | m_pEntity->AddChild(m_pWindow); 13 | } 14 | 15 | void DockWindow::Shutdown() 16 | { 17 | if (m_pEntity) 18 | { 19 | m_pEntity->Destroy(); 20 | m_pWindow = nullptr; 21 | } 22 | } 23 | 24 | } // shiva 25 | -------------------------------------------------------------------------------- /src/editor/windows/EditorWindowManager.cpp: -------------------------------------------------------------------------------- 1 | #include "../../../include/shiva/windows/EditorWindowManager.hpp" 2 | #include "ari/en/Entity.hpp" 3 | #include "ari/en/World.hpp" 4 | #include "ari/en/gui/Window.hpp" 5 | #include "ari/en/gui/DockSpace.hpp" 6 | #include "shiva/windows/AssetBrowser.hpp" 7 | #include "shiva/windows/Viewport.hpp" 8 | #include "shiva/windows/PropertyEditor.hpp" 9 | #include "ari/Engine.hpp" 10 | 11 | namespace shiva 12 | { 13 | EditorWindowManager::EditorWindowManager() = default; 14 | 15 | EditorWindowManager::~EditorWindowManager() 16 | { 17 | Shutdown(); 18 | delete m_pAssetBrowser; 19 | } 20 | 21 | void EditorWindowManager::Init(ari::World* pWorld) 22 | { 23 | m_pEntity = new ari::Entity; 24 | pWorld->AddEntity(m_pEntity); 25 | 26 | // Init Viewport 27 | if (!m_pViewport) 28 | m_pViewport = new Viewport; 29 | m_pViewport->Init(pWorld); 30 | 31 | // Init Asset Browser 32 | if (!m_pAssetBrowser) 33 | m_pAssetBrowser = new AssetBrowser; 34 | m_pAssetBrowser->Init(pWorld); 35 | 36 | // Init Property Editor 37 | if (!m_pPropertyEditor) 38 | m_pPropertyEditor = new PropertyEditor; 39 | m_pPropertyEditor->Init(pWorld); 40 | 41 | } // Init 42 | 43 | void EditorWindowManager::Shutdown() 44 | { 45 | if (m_pEntity) 46 | m_pEntity->Destroy(); 47 | m_pEntity = nullptr; 48 | m_pAssetBrowser->Shutdown(); 49 | m_pViewport->Shutdown(); 50 | m_pPropertyEditor->Shutdown(); 51 | 52 | } // ShutDown 53 | 54 | } // shiva 55 | -------------------------------------------------------------------------------- /src/editor/windows/ProjectBrowser.cpp: -------------------------------------------------------------------------------- 1 | #include "..\..\..\include\shiva\windows\ProjectBrowser.hpp" 2 | #include "ari/en/gui/Window.hpp" 3 | #include "ari/en/World.hpp" 4 | #include "ari/en/gui/TextBox.hpp" 5 | #include "bx/string.h" 6 | #include "bx/filepath.h" 7 | #include "shiva/Project.hpp" 8 | #include "ari/en/gui/Popup.hpp" 9 | #include "shiva/Editor.hpp" 10 | #include "ari/en/gui/DockableWindow.hpp" 11 | #include "shiva/EditorSettings.hpp" 12 | 13 | void testOnClick() 14 | { 15 | printf("new project button clicked\n"); 16 | } 17 | 18 | namespace shiva 19 | { 20 | ProjectBrowser::ProjectBrowser(): m_pNewProjectName(nullptr), 21 | m_pNewProjectPath(nullptr), m_pOpenProjectPath(nullptr), 22 | m_pOpenProjectBtn(nullptr), 23 | m_pNewProjectBtn(nullptr), m_pMessageBox(nullptr), m_pMbLabel(nullptr), 24 | m_pMbOkBtn(nullptr) 25 | { 26 | } 27 | 28 | ProjectBrowser::~ProjectBrowser() 29 | { 30 | Shutdown(); 31 | } 32 | 33 | void ProjectBrowser::Init(ari::World* p_world) 34 | { 35 | DockWindow::Init(p_world); 36 | 37 | // Init Project browser window. 38 | m_pWindow->SetTitle("Project Browser"); 39 | m_pNewProjectName = new ari::TextBox(32); 40 | m_pNewProjectName->Label = "Project name"; 41 | m_pNewProjectName->SetText("New project"); 42 | m_pWindow->AddChild(m_pNewProjectName); 43 | m_pNewProjectPath = new ari::TextBox(512); 44 | m_pNewProjectPath->Label = "Project path"; 45 | m_pNewProjectPath->SetText(bx::FilePath(bx::Dir::Home).get()); 46 | m_pWindow->AddChild(m_pNewProjectPath); 47 | m_pNewProjectBtn = new ari::Button(); 48 | m_pNewProjectBtn->Label = "New project"; 49 | m_pNewProjectBtn->OnClick.Bind(this, &ProjectBrowser::OnNewProjectClick); 50 | m_pWindow->AddChild(m_pNewProjectBtn); 51 | 52 | // Init open project textbox 53 | m_pOpenProjectPath = new ari::TextBox(512); 54 | m_pOpenProjectPath->Label = "Project path to open"; 55 | m_pOpenProjectPath->Separator = true; 56 | m_pOpenProjectPath->SetText(EditorSettings::Get().LastProjectPath.c_str()); 57 | m_pWindow->AddChild(m_pOpenProjectPath); 58 | m_pOpenProjectBtn = new ari::Button(); 59 | m_pOpenProjectBtn->Label = "Open project"; 60 | m_pOpenProjectBtn->OnClick.Bind(this, &ProjectBrowser::OnOpenProjectClick); 61 | m_pWindow->AddChild(m_pOpenProjectBtn); 62 | 63 | // Init message window 64 | m_pMessageBox = new ari::Popup; 65 | m_pMessageBox->Name = "MessageBox"; 66 | ari::Window* p_window = new ari::Window; 67 | p_window->Name = "M"; 68 | p_window->Pos.x = -1000; 69 | p_window->Flags = ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoInputs | 70 | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoTitleBar; 71 | m_pEntity->AddChild(p_window); 72 | p_window->AddChild(m_pMessageBox); 73 | m_pMbLabel = new ari::Label; 74 | m_pMessageBox->AddChild(m_pMbLabel); 75 | m_pMbOkBtn = new ari::Button; 76 | m_pMbOkBtn->Label = "OK"; 77 | m_pMbOkBtn->OnClick.Bind(this, &ProjectBrowser::OnClickMbOk); 78 | m_pMessageBox->AddChild(m_pMbOkBtn); 79 | } 80 | 81 | void ProjectBrowser::Shutdown() 82 | { 83 | if (m_pEntity) 84 | { 85 | m_pEntity->Destroy(); 86 | m_pEntity = nullptr; 87 | m_pWindow = nullptr; 88 | m_pNewProjectName = nullptr; 89 | m_pNewProjectPath = nullptr; 90 | m_pNewProjectBtn = nullptr; 91 | m_pOpenProjectPath = nullptr; 92 | m_pOpenProjectBtn = nullptr; 93 | m_pMessageBox = nullptr; 94 | m_pMbLabel = nullptr; 95 | m_pMbOkBtn = nullptr; 96 | } 97 | } 98 | 99 | void ProjectBrowser::OnNewProjectClick() 100 | { 101 | bx::Error err; 102 | Project* p = Project::New(bx::FilePath(m_pNewProjectPath->Text), m_pNewProjectName->Text, &err); 103 | if (p) 104 | { 105 | ProjectOpened(p); 106 | } 107 | else 108 | { 109 | m_pMbLabel->Text = err.getMessage().getPtr(); 110 | m_pMessageBox->Show(); 111 | } 112 | } 113 | 114 | void ProjectBrowser::OnOpenProjectClick() 115 | { 116 | bx::Error err; 117 | Project* p = Project::Load(bx::FilePath(m_pOpenProjectPath->Text), &err); 118 | if (p) 119 | { 120 | ProjectOpened(p); 121 | } 122 | else 123 | { 124 | m_pMbLabel->Text = err.getMessage().getPtr(); 125 | m_pMessageBox->Show(); 126 | } 127 | } 128 | 129 | void ProjectBrowser::OnClickMbOk() 130 | { 131 | m_pMessageBox->Hide(); 132 | } 133 | 134 | void ProjectBrowser::ProjectOpened(Project* project) 135 | { 136 | g_pEditor->LoadProject(project); 137 | Shutdown(); 138 | } 139 | 140 | bool ProjectGui::BeginRender() 141 | { 142 | ImGui::BeginGroup(); 143 | { 144 | ImGui::BeginGroup(); 145 | ImGui::Button("AAA"); 146 | ImGui::SameLine(); 147 | ImGui::Button("BBB"); 148 | ImGui::SameLine(); 149 | ImGui::BeginGroup(); 150 | ImGui::Button("CCC"); 151 | ImGui::Button("DDD"); 152 | ImGui::EndGroup(); 153 | ImGui::SameLine(); 154 | ImGui::Button("EEE"); 155 | ImGui::EndGroup(); 156 | if (ImGui::IsItemHovered()) 157 | ImGui::SetTooltip("First group hovered"); 158 | } 159 | // Capture the group size and create widgets using the same size 160 | ImVec2 size = ImGui::GetItemRectSize(); 161 | const float values[5] = { 0.5f, 0.20f, 0.80f, 0.60f, 0.25f }; 162 | ImGui::PlotHistogram("##values", values, IM_ARRAYSIZE(values), 0, NULL, 0.0f, 1.0f, size); 163 | 164 | ImGui::Button("ACTION", ImVec2((size.x - ImGui::GetStyle().ItemSpacing.x)*0.5f, size.y)); 165 | ImGui::SameLine(); 166 | ImGui::Button("REACTION", ImVec2((size.x - ImGui::GetStyle().ItemSpacing.x)*0.5f, size.y)); 167 | ImGui::EndGroup(); 168 | 169 | return false; 170 | } 171 | 172 | void ProjectGui::EndRender() 173 | { 174 | } 175 | 176 | } // shiva 177 | -------------------------------------------------------------------------------- /src/editor/windows/PropertyEditor.cpp: -------------------------------------------------------------------------------- 1 | #include "../../../include/shiva/windows/PropertyEditor.hpp" 2 | 3 | namespace shiva 4 | { 5 | void PropertyEditor::Init(ari::World * p_world) 6 | { 7 | DockWindow::Init(p_world); 8 | 9 | m_pWindow->SetTitle("Property Editor"); 10 | m_pWindow->Dock(ari::DockableWindow::Oriention::Right, 0.2f); 11 | } 12 | } // shiva 13 | -------------------------------------------------------------------------------- /src/editor/windows/Viewport.cpp: -------------------------------------------------------------------------------- 1 | #include "../../../include/shiva/windows/Viewport.hpp" 2 | #include "ari/en/2d/Viewport.hpp" 3 | #include "ari/en/3d/Camera.hpp" 4 | #include "ari/en/3d/BoxShape.hpp" 5 | #include "ari/en/World.hpp" 6 | #include "ari/en/gui/Image.hpp" 7 | #include "ari/Engine.hpp" 8 | 9 | namespace shiva 10 | { 11 | void Viewport::OnGui() 12 | { 13 | float w, h; 14 | m_pWindow->GetLastSize(w, h); 15 | m_pView->Size.x = w; 16 | m_pView->Size.y = h; 17 | m_pViewport->Rect.Set(0, 0, int(w), int(h)); 18 | } 19 | 20 | void Viewport::OnHovered() 21 | { 22 | // Rotate camera by right click 23 | if (ImGui::IsMouseDragging(1)) 24 | { 25 | const auto d = ImGui::GetMouseDragDelta(1); 26 | m_pCamera->RotateByMouse(int(d.x), int(d.y), 0.3f * ari::g_pEngine->GetDeltaTime()); 27 | ImGui::ResetMouseDragDelta(1); 28 | 29 | const float speed = 0.3f * ari::g_pEngine->GetDeltaTime(); 30 | if (ImGui::IsKeyDown(ari::Key::KeyW)) 31 | m_pCamera->MoveBF(speed); 32 | if (ImGui::IsKeyDown(ari::Key::KeyS)) 33 | m_pCamera->MoveBF(-speed); 34 | if (ImGui::IsKeyDown(ari::Key::KeyA)) 35 | m_pCamera->MoveLR(-speed); 36 | if (ImGui::IsKeyDown(ari::Key::KeyD)) 37 | m_pCamera->MoveLR(speed); 38 | } 39 | if (ImGui::IsMouseDragging(2)) 40 | { 41 | const auto d = ImGui::GetMouseDragDelta(2); 42 | m_pCamera->MoveUD(d.y * -0.3f * ari::g_pEngine->GetDeltaTime()); 43 | m_pCamera->MoveLR(d.x * 0.5f * ari::g_pEngine->GetDeltaTime()); 44 | ImGui::ResetMouseDragDelta(2); 45 | } 46 | m_pCamera->MoveBF(ImGui::GetIO().MouseWheel * ari::g_pEngine->GetDeltaTime()); 47 | } 48 | 49 | void Viewport::Init(ari::World * p_world) 50 | { 51 | DockWindow::Init(p_world); 52 | 53 | m_pWindow->SetTitle("Viewport"); 54 | //m_pWindow->SetAlone(true); 55 | m_pWindow->Dock(); 56 | m_pWindow->SetFillingSpace(true); 57 | m_pWindow->OnGui.Bind(this, &Viewport::OnGui); 58 | 59 | // Init Camera & Viewport 60 | m_pCamera = new ari::Camera(); 61 | m_pCamera->Position.Set(4.0f, 4.0f, 4.0f); 62 | m_pEntity->AddChild(m_pCamera); 63 | m_pViewport = new ari::Viewport; 64 | m_pViewport->Rect.Set(0, 0, 300, 300); 65 | m_pViewport->CreateDepth = true; 66 | m_pViewport->TextureFormat = bgfx::TextureFormat::BGRA8; 67 | m_pViewport->UseMSAA = true; 68 | m_pCamera->AddChild(m_pViewport); 69 | // Add a box for test. 70 | m_pEntity->AddChild(new ari::BoxShape); 71 | 72 | // Add image 73 | m_pView = new ari::Image; 74 | m_pView->ImageTexture = std::shared_ptr(&m_pViewport->m_texture); 75 | m_pView->Size.x = m_pView->Size.y = 300; 76 | m_pView->OnHovered.Bind(this, &Viewport::OnHovered); 77 | m_pWindow->AddChild(m_pView); 78 | 79 | } // Init 80 | 81 | } // shiva 82 | -------------------------------------------------------------------------------- /src/engine/Engine.cpp: -------------------------------------------------------------------------------- 1 | #include "..\..\include\ari\Engine.hpp" 2 | #include "..\..\include\ari\Program.hpp" 3 | #include 4 | #include 5 | #include "io/SdlWindow.hpp" 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include "../../include/ari/io/Input.hpp" 11 | #include "../../deps/bgfx/src/renderer.h" 12 | #include "io/WindowWin32.hpp" 13 | 14 | extern bx::AllocatorI* g_allocator; 15 | 16 | namespace ari 17 | { 18 | Engine* g_pEngine = nullptr; 19 | 20 | Engine::Engine() : m_pWindow(nullptr), m_debug(0), m_reset(0), 21 | m_frame_number(0), m_time_offset(0), m_pGfxThread(nullptr), 22 | m_bRun(true), m_bNeedReset(false) 23 | { 24 | Logger = spdlog::stdout_color_mt("main"); 25 | Logger->set_level(spdlog::level::trace); 26 | g_pEngine = this; 27 | m_pTaskMgr = new ftl::TaskScheduler(); 28 | } 29 | 30 | Engine::~Engine() 31 | { 32 | printf("Shutting down the Ariyana engine.\n"); 33 | m_bRun = false; 34 | 35 | m_pGfxThread->shutdown(); 36 | delete m_pGfxThread; 37 | 38 | delete m_pWindow; 39 | g_pEngine = nullptr; 40 | delete m_pTaskMgr; 41 | } 42 | 43 | Engine & Engine::GetSingleton() 44 | { 45 | return *g_pEngine; 46 | } 47 | 48 | bool Engine::Init(InitParams* params) 49 | { 50 | inputInit(); 51 | m_params = params; 52 | m_debug = BGFX_DEBUG_TEXT; 53 | m_reset = BGFX_RESET_VSYNC; 54 | 55 | m_pWindow = NewWindow(PlatformWindow::Type::Main); 56 | 57 | char* windowName = "Ariyana"; 58 | if (params->Program) 59 | windowName = (char*)params->Program->GetProgramName().c_str(); 60 | if (!m_pWindow->Init(0, 0, params->Width, params->Height, 0, windowName)) 61 | { 62 | Logger->error("Can't create window"); 63 | return false; 64 | } 65 | 66 | m_pMutex = new bx::Mutex; 67 | 68 | m_pGfxThread = new bx::Thread(); 69 | m_pGfxThread->init(Engine::InitBgfxInThread, this); 70 | 71 | return true; 72 | } 73 | 74 | bool Engine::Run() 75 | { 76 | // if (m_time_offset > 0) 77 | 78 | m_bRun = m_pWindow->Run(); 79 | uint32_t reset = m_reset; 80 | m_bRun &= m_pWindow->ProcessEvents(m_params->Width, m_params->Height, m_debug, reset, &m_MouseState); 81 | bgfx::renderFrame(); 82 | return m_bRun; 83 | } 84 | 85 | void Engine::LockUpdateThread() 86 | { 87 | m_iLockStatus = 1; 88 | bgfx::renderFrame(); 89 | } 90 | 91 | void Engine::UnlockUpdateThread() 92 | { 93 | m_pMutex->unlock(); 94 | } 95 | 96 | Event * Engine::Poll() 97 | { 98 | return const_cast(m_pWindow->m_eventQueue.poll()); 99 | } 100 | 101 | void Engine::Release(const Event * _event) 102 | { 103 | m_pWindow->m_eventQueue.release(_event); 104 | } 105 | 106 | PlatformWindow * Engine::NewWindow(PlatformWindow::Type _type) 107 | { 108 | // Create a window 109 | #if BX_PLATFORM_WINDOWS 110 | return new WindowWin32(_type); 111 | #else 112 | Logger->error("Windowing in this platform not supported yet."); 113 | return nullptr; 114 | #endif 115 | } 116 | 117 | uint16_t Engine::GetNewViewId() 118 | { 119 | return ++m_viewId; 120 | } 121 | 122 | uint32_t Engine::GetMsaaFlags() const 123 | { 124 | return (m_reset & BGFX_RESET_MSAA_MASK) >> BGFX_RESET_MSAA_SHIFT; 125 | } 126 | 127 | int Engine::InitBgfxInThread(bx::Thread * _thread, void * _userData) 128 | { 129 | BX_UNUSED(_thread, _userData); 130 | 131 | // Init bgfx 132 | bgfx::Init init; 133 | init.resolution.width = g_pEngine->m_params->Width; 134 | init.resolution.height = g_pEngine->m_params->Height; 135 | init.resolution.reset = g_pEngine->m_reset; 136 | 137 | bgfx::init(init); 138 | 139 | // Enable debug text. 140 | bgfx::setDebug(g_pEngine->m_debug); 141 | 142 | // Set view 0 clear state. 143 | bgfx::setViewClear(0 144 | , BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH 145 | , 0x00000000 146 | , 1.0f 147 | , 0 148 | ); 149 | 150 | if (g_pEngine->m_params->Program) 151 | g_pEngine->m_params->Program->Init(); 152 | 153 | g_pEngine->m_time_offset = bx::getHPCounter(); 154 | 155 | while (g_pEngine->m_bRun) 156 | { 157 | g_pEngine->m_pMutex->lock(); 158 | 159 | if (g_pEngine->m_bNeedReset) 160 | { 161 | bgfx::reset(g_pEngine->m_params->Width, g_pEngine->m_params->Height, g_pEngine->m_reset); 162 | g_pEngine->m_bNeedReset = false; 163 | } 164 | // Set view 0 default viewport. 165 | bgfx::setViewRect(0, 0, 0, uint16_t(g_pEngine->m_params->Width), uint16_t(g_pEngine->m_params->Height)); 166 | 167 | // This dummy draw call is here to make sure that view 0 is cleared 168 | // if no other draw calls are submitted to view 0. 169 | bgfx::touch(0); 170 | 171 | g_pEngine->m_fDeltaTime = -g_pEngine->m_fElapsedTime; 172 | g_pEngine->m_fElapsedTime = float((bx::getHPCounter() - g_pEngine->m_time_offset) / double(bx::getHPFrequency())); 173 | g_pEngine->m_fDeltaTime += g_pEngine->m_fElapsedTime; 174 | 175 | if (g_pEngine->m_params->Program) 176 | g_pEngine->m_params->Program->Update(g_pEngine->m_frame_number, g_pEngine->m_fDeltaTime); 177 | 178 | bgfx::frame(); 179 | g_pEngine->m_frame_number++; 180 | 181 | if (g_pEngine->m_iLockStatus != 1) 182 | g_pEngine->m_pMutex->unlock(); 183 | } 184 | int exit_code = 0; 185 | if (g_pEngine->m_params->Program) 186 | exit_code = g_pEngine->m_params->Program->Shutdown(); 187 | 188 | // bgfx::shutdown(); 189 | 190 | return exit_code; 191 | } 192 | 193 | } // ari 194 | -------------------------------------------------------------------------------- /src/engine/PluginManager.cpp: -------------------------------------------------------------------------------- 1 | #include "..\..\include\ari\PluginManager.hpp" 2 | #include 3 | #include "../../include/ari/Engine.hpp" 4 | 5 | #if BX_PLATFORM_WINDOWS 6 | 7 | #include 8 | 9 | #else 10 | 11 | #include 12 | 13 | #endif 14 | 15 | namespace ari 16 | { 17 | bool PluginManager::LoadResource(Plugin ** ppOut, uint32_t handle, 18 | const std::string& filename, void * extraParams) 19 | { 20 | // RegisterPlugin function pointer 21 | typedef Plugin*(*RegisterPlugin) (Engine*, const uint32_t&, const std::string&); 22 | 23 | bool bLoadFailed = false; 24 | RegisterPlugin pFn = NULL; 25 | 26 | 27 | #if BX_PLATFORM_WINDOWS 28 | // Load .dll files under windows OS 29 | std::string strPluginName = "plugin_"; 30 | strPluginName += filename; 31 | # ifdef _DEBUG 32 | strPluginName += "Debug"; 33 | # else 34 | strPluginName += "Release"; 35 | # endif 36 | strPluginName += ".dll"; 37 | 38 | // Load dll and check for success 39 | HMODULE hMod = LoadLibrary(strPluginName.c_str()); 40 | 41 | if (hMod) 42 | { 43 | pFn = (RegisterPlugin)GetProcAddress(hMod, "RegisterPlugin"); 44 | if (!pFn) 45 | { 46 | //io::Logger::Error("RegisterPlugin function dose not find in %s plugin.", strPluginName.c_str()); 47 | return false; 48 | } 49 | } 50 | else 51 | { 52 | // io::Logger::Error("can't load the %s plugin. (file not found) %d", strPluginName.c_str(), GetLastError()); 53 | return false; 54 | } 55 | 56 | #else 57 | 58 | std::string strPluginName; 59 | strPluginName = "libplugin_"; 60 | strPluginName += filename; 61 | # ifdef _DEBUG 62 | strPluginName += "Debug"; 63 | # else 64 | strPluginName += "Release"; 65 | # endif 66 | strPluginName += ".so"; 67 | 68 | void* handle = dlopen(strPluginName.c_str(), RTLD_LAZY); 69 | 70 | char* error; 71 | 72 | if (!handle) 73 | { 74 | //io::Logger::Error("can't load the %s plugin. (%s)", strPluginName.c_str(), dlerror()); 75 | return false; 76 | } 77 | // Clear any exiting error 78 | dlerror(); 79 | 80 | // Load the RegisterPlugin function 81 | pFn = (RegisterPlugin)dlsym(handle, "RegisterPlugin"); 82 | if ((error = (char*)dlerror()) != NULL || !pFn) 83 | { 84 | //io::Logger::Error("RegisterPlugin function dose not find in %s plugin.\n%s", strPluginName.c_str(), error); 85 | return false; 86 | } 87 | 88 | #endif 89 | 90 | // Call the RegisterPlugin function 91 | *ppOut = (*pFn)(g_pEngine, handle, filename); 92 | //io::Logger::SuccessKGE("Plugin %s loaded successfully.", strPluginName.c_str()); 93 | 94 | return true; 95 | } 96 | 97 | } // ari 98 | -------------------------------------------------------------------------------- /src/engine/ResourceLoader.cpp: -------------------------------------------------------------------------------- 1 | #include "..\..\include\ari\ResourceLoader.hpp" 2 | 3 | namespace ari 4 | { 5 | bool ResourceLoader::IsALoadableFileExtension(std::string _extention) 6 | { 7 | for (const auto & ext : m_aFileExtension) 8 | { 9 | if (_extention.find_last_of(ext) > 0) 10 | return true; 11 | } 12 | 13 | return false; 14 | } 15 | } // ari 16 | -------------------------------------------------------------------------------- /src/engine/StringCast.cpp: -------------------------------------------------------------------------------- 1 | #include "..\..\include\ari\StringCast.h" 2 | 3 | std::string castToString(const bool& value) 4 | { 5 | return value ? "true" : "false"; 6 | } 7 | 8 | std::string castToString(const int& value) 9 | { 10 | return std::to_string(value); 11 | } 12 | 13 | std::string castToString(const float& value) 14 | { 15 | return std::to_string(value); 16 | } 17 | 18 | std::string castToString(const std::string& value) 19 | { 20 | return value; 21 | } 22 | 23 | // from string 24 | 25 | template <> 26 | bool fromString(const std::string& valueStr) 27 | { 28 | if (valueStr == "true") { 29 | return true; 30 | } else if (valueStr == "false") { 31 | return false; 32 | } 33 | } 34 | 35 | template <> 36 | int fromString(const std::string& valueStr) 37 | { 38 | return std::stoi(valueStr); 39 | } 40 | 41 | template <> 42 | float fromString(const std::string& valueStr) 43 | { 44 | return std::stof(valueStr); 45 | } 46 | 47 | template <> 48 | std::string fromString(const std::string& valueStr) 49 | { 50 | return valueStr; 51 | } 52 | -------------------------------------------------------------------------------- /src/engine/en/3d/BoxShape.cpp: -------------------------------------------------------------------------------- 1 | #include "bgfx/bgfx.h" 2 | #include "../../../../include/ari/en/3d/BoxShape.hpp" 3 | #include "../../../../include/ari/en/3d/RenderSystem.hpp" 4 | #include "../../../../include/ari/gfx/Vertices.hpp" 5 | 6 | namespace ari 7 | { 8 | bgfx::VertexBufferHandle BoxShape::m_sVBPos BGFX_INVALID_HANDLE; 9 | bgfx::VertexBufferHandle BoxShape::m_sVBColor BGFX_INVALID_HANDLE; 10 | bgfx::IndexBufferHandle BoxShape::m_sIB BGFX_INVALID_HANDLE; 11 | bgfx::ProgramHandle BoxShape::m_sProgram BGFX_INVALID_HANDLE; 12 | 13 | static PosVertex s_cubePosVertices[] = 14 | { 15 | { -1.0f, 1.0f, 1.0f }, 16 | { 1.0f, 1.0f, 1.0f }, 17 | { -1.0f, -1.0f, 1.0f }, 18 | { 1.0f, -1.0f, 1.0f }, 19 | { -1.0f, 1.0f, -1.0f }, 20 | { 1.0f, 1.0f, -1.0f }, 21 | { -1.0f, -1.0f, -1.0f }, 22 | { 1.0f, -1.0f, -1.0f }, 23 | }; 24 | 25 | static ColorVertex s_cubeColorVertices[] = 26 | { 27 | { 0xff000000 }, 28 | { 0xff0000ff }, 29 | { 0xff00ff00 }, 30 | { 0xff00ffff }, 31 | { 0xffff0000 }, 32 | { 0xffff00ff }, 33 | { 0xffffff00 }, 34 | { 0xffffffff }, 35 | }; 36 | 37 | static const uint16_t s_cubeTriList[] = 38 | { 39 | 0, 1, 2, // 0 40 | 1, 3, 2, 41 | 4, 6, 5, // 2 42 | 5, 6, 7, 43 | 0, 2, 4, // 4 44 | 4, 2, 6, 45 | 1, 5, 3, // 6 46 | 5, 7, 3, 47 | 0, 4, 1, // 8 48 | 4, 5, 1, 49 | 2, 3, 6, // 10 50 | 6, 3, 7, 51 | }; 52 | 53 | void BoxShape::Render(const Matrix & matrix, bgfx::Encoder* encoder, uint16_t _view_id) 54 | { 55 | encoder->setTransform(matrix.v); 56 | encoder->setVertexBuffer(0, m_sVBPos); 57 | encoder->setVertexBuffer(1, m_sVBColor); 58 | encoder->setIndexBuffer(m_sIB); 59 | encoder->submit(_view_id, m_sProgram); 60 | } 61 | 62 | void BoxShape::Init(RenderSystem * render_system) 63 | { 64 | if (!bgfx::isValid(m_sVBPos)) 65 | { 66 | // Create static vertex buffer. 67 | m_sVBPos = bgfx::createVertexBuffer( 68 | // Static data can be passed with bgfx::makeRef 69 | bgfx::makeRef(s_cubePosVertices, sizeof(s_cubePosVertices)) 70 | , *render_system->GetVertexDecl(RenderSystem::VertexType::Pos) 71 | ); 72 | 73 | m_sVBColor = bgfx::createVertexBuffer( 74 | // Static data can be passed with bgfx::makeRef 75 | bgfx::makeRef(s_cubeColorVertices, sizeof(s_cubeColorVertices)) 76 | , *render_system->GetVertexDecl(RenderSystem::VertexType::Color) 77 | ); 78 | 79 | // Create static index buffer. 80 | m_sIB = bgfx::createIndexBuffer( 81 | // Static data can be passed with bgfx::makeRef 82 | bgfx::makeRef(s_cubeTriList, sizeof(s_cubeTriList)) 83 | ); 84 | 85 | m_sProgram = *render_system->GetProgram(); 86 | } 87 | } 88 | 89 | void BoxShape::Shutdown() 90 | { 91 | if (bgfx::isValid(m_sVBPos)) 92 | bgfx::destroy(m_sVBPos); 93 | if (bgfx::isValid(m_sVBColor)) 94 | bgfx::destroy(m_sVBColor); 95 | if (bgfx::isValid(m_sIB)) 96 | bgfx::destroy(m_sIB); 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /src/engine/en/3d/Camera.cpp: -------------------------------------------------------------------------------- 1 | #include "../../../../include/ari/en/3d/Camera.hpp" 2 | 3 | namespace ari 4 | { 5 | void Camera::Rotate(float _angle, const Vector3 & _axis) 6 | { 7 | Vector3 vLook; // Looking point. 8 | 9 | const Vector3 vDir = Target - Position; // Looking direction. 10 | 11 | const float cost = bx::cos(_angle); 12 | const float sint = bx::sin(_angle); 13 | 14 | // Find the new x position for the new rotated point 15 | vLook.x = (cost + (1 - cost) * _axis.x * _axis.x) * vDir.x; 16 | vLook.x += ((1 - cost) * _axis.x * _axis.y - _axis.z * sint) * vDir.y; 17 | vLook.x += ((1 - cost) * _axis.x * _axis.z + _axis.y * sint) * vDir.z; 18 | 19 | // Find the new y position for the new rotated point 20 | vLook.y = ((1 - cost) * _axis.x * _axis.y + _axis.z * sint) * vDir.x; 21 | vLook.y += (cost + (1 - cost) * _axis.y * _axis.y) * vDir.y; 22 | vLook.y += ((1 - cost) * _axis.y * _axis.z - _axis.x * sint) * vDir.z; 23 | 24 | // Find the new z position for the new rotated point 25 | vLook.z = ((1 - cost) * _axis.x * _axis.z - _axis.y * sint) * vDir.x; 26 | vLook.z += ((1 - cost) * _axis.y * _axis.z + _axis.x * sint) * vDir.y; 27 | vLook.z += (cost + (1 - cost) * _axis.z * _axis.z) * vDir.z; 28 | 29 | 30 | // Now we just add the newly rotated vector to our position to set 31 | // our new rotated view of our camera. 32 | Target.x = Position.x + vLook.x; 33 | Target.y = Position.y + vLook.y; 34 | Target.z = Position.z + vLook.z; 35 | 36 | } // Rotate 37 | 38 | void Camera::RotateByMouse(int _x, int _y, float _speed) 39 | { 40 | if ((_x == 0) && (_y == 0)) 41 | return; 42 | 43 | _x *= -1; 44 | _y *= -1; 45 | float angleY = 0.0f; 46 | float angleZ = 0.0f; 47 | 48 | angleY = float(_x) * _speed; 49 | angleZ = float(_y) * _speed; 50 | 51 | m_fLastRotX = m_fCurRotX; 52 | 53 | m_fCurRotX += angleZ; 54 | 55 | // calculate the correct up 56 | Vector3 view = Target - Position; 57 | view.Normalize(); 58 | Vector3 right; 59 | right.Cross(Up, view); 60 | right.Normalize(); 61 | Vector3 up; 62 | up.Cross(view, right); 63 | 64 | Vector3 vAxis; 65 | vAxis.Cross(view, up); 66 | vAxis.Normalize(); 67 | 68 | if (m_fCurRotX > 1.0f) 69 | { 70 | m_fCurRotX = 1.0f; 71 | if (m_fLastRotX < 1.0f) 72 | { 73 | Rotate(1.0f - m_fLastRotX, vAxis); 74 | } // if (LastRotX != 1.0f) 75 | 76 | } // if (m_fCurRotX > 1.0f) 77 | else if (m_fCurRotX < -1.0f) 78 | { 79 | m_fCurRotX = -1.0f; 80 | if (m_fLastRotX > -1.0f) 81 | { 82 | Rotate(-1.0f - m_fLastRotX, vAxis); 83 | } // if (m_fLastRotX < -1.0f) 84 | 85 | } // if (m_fCurRotX < -1.0f) 86 | else 87 | { 88 | Rotate(angleZ, vAxis); 89 | } 90 | Rotate(-angleY, Vector3(0.0f, 1.0f, 0.0f)); 91 | } 92 | 93 | void Camera::MoveBF(const float & _speed) 94 | { 95 | Vector3 v = Target - Position; 96 | v.Normalize(); 97 | Position.x += v.x * _speed; 98 | Position.y += v.y * _speed; 99 | Position.z += v.z * _speed; 100 | 101 | Target.x += v.x * _speed; 102 | Target.y += v.y * _speed; 103 | Target.z += v.z * _speed; 104 | } 105 | 106 | void Camera::MoveLR(const float & _speed) 107 | { 108 | // calculate the correct up 109 | Vector3 view = Target - Position; 110 | view.Normalize(); 111 | Vector3 right; 112 | right.Cross(Up, view); 113 | right.Normalize(); 114 | 115 | Position.x += right.x * _speed; 116 | Position.y += right.y * _speed; 117 | Position.z += right.z * _speed; 118 | 119 | Target.x += right.x * _speed; 120 | Target.y += right.y * _speed; 121 | Target.z += right.z * _speed; 122 | } 123 | 124 | void Camera::MoveUD(const float & _speed) 125 | { 126 | Position.y += _speed; 127 | Target.y += _speed; 128 | } 129 | 130 | } 131 | -------------------------------------------------------------------------------- /src/engine/en/3d/RenderSystem.cpp: -------------------------------------------------------------------------------- 1 | #include "../../../../include/ari/en/3d/RenderSystem.hpp" 2 | #include "../../../../include/ari/en/3d/BoxShape.hpp" 3 | #include "../../../../include/ari/en/3d/Camera.hpp" 4 | #include "../../../../include/ari/en/2d/Viewport.hpp" 5 | #include "../../../../include/ari/en/World.hpp" 6 | #include "../../../../include/ari/gfx/FrameData.hpp" 7 | #include 8 | #include 9 | #include "tinystl/string.h" 10 | #include "../../../../include/ari/Engine.hpp" 11 | 12 | namespace ari 13 | { 14 | char* g_AssetDir = ASSETS_DIR; 15 | 16 | RenderSystem::RenderSystem(): m_pVertexDeclArray(nullptr), m_Program(nullptr), m_pFrameDataCurrent(nullptr), 17 | m_pFrameDataNext(nullptr) 18 | { 19 | } 20 | 21 | RenderSystem::~RenderSystem() 22 | { 23 | delete[] m_pVertexDeclArray; 24 | BoxShape::Shutdown(); 25 | bgfx::destroy(*m_Program); 26 | delete m_Program; 27 | } 28 | 29 | void RenderSystem::Update(World * p_world, UpdateState state) 30 | { 31 | if (state == UpdateState::MainThreadState) 32 | { 33 | m_view_id = 0; 34 | m_pFrameDataCurrent = m_pFrameDataNext; 35 | if (m_pFrameDataCurrent) 36 | // Set the camera 37 | if (m_pFrameDataCurrent->Camera) 38 | { 39 | // Set viewport 40 | Viewport* pViewport = m_pFrameDataCurrent->Camera->GetChild(); 41 | if (pViewport) 42 | { 43 | m_view_id = pViewport->m_view_id; 44 | 45 | // Check if we need create a frame buffer or not. 46 | if (pViewport->TextureFormat != bgfx::TextureFormat::Count 47 | && (!bgfx::isValid(pViewport->m_frame_buffer_handle) 48 | || pViewport->Rect != pViewport->m_last_rect)) 49 | { 50 | pViewport->m_last_rect = pViewport->Rect; 51 | uint32_t msaa = g_pEngine->GetMsaaFlags(); 52 | if (!pViewport->UseMSAA) 53 | msaa = 0; 54 | 55 | if (bgfx::isValid(pViewport->m_frame_buffer_handle)) 56 | { 57 | bgfx::destroy(pViewport->m_frame_buffer_handle); 58 | } 59 | else 60 | { 61 | pViewport->m_view_id = g_pEngine->GetNewViewId(); 62 | m_view_id = pViewport->m_view_id; 63 | } 64 | 65 | bgfx::TextureHandle th[2]; 66 | 67 | th[0] = bgfx::createTexture2D( 68 | pViewport->Rect.width - pViewport->Rect.x, 69 | pViewport->Rect.height - pViewport->Rect.y, 70 | false, 71 | 1, 72 | pViewport->TextureFormat, 73 | (uint64_t(msaa + 1) << BGFX_TEXTURE_RT_MSAA_SHIFT) | BGFX_SAMPLER_U_CLAMP | BGFX_SAMPLER_V_CLAMP 74 | ); 75 | 76 | pViewport->m_texture.Handle = th[0]; 77 | 78 | // Create depth buffer 79 | if (pViewport->CreateDepth) 80 | { 81 | const uint64_t textureFlags = BGFX_TEXTURE_RT_WRITE_ONLY | (uint64_t(msaa + 1) << BGFX_TEXTURE_RT_MSAA_SHIFT); 82 | 83 | bgfx::TextureFormat::Enum depthFormat = 84 | bgfx::isTextureValid(0, false, 1, bgfx::TextureFormat::D16, textureFlags) ? bgfx::TextureFormat::D16 85 | : bgfx::isTextureValid(0, false, 1, bgfx::TextureFormat::D24S8, textureFlags) ? bgfx::TextureFormat::D24S8 86 | : bgfx::TextureFormat::D32 87 | ; 88 | 89 | th[1] = bgfx::createTexture2D( 90 | pViewport->Rect.width - pViewport->Rect.x, 91 | pViewport->Rect.height - pViewport->Rect.y, 92 | false, 93 | 1, 94 | depthFormat, 95 | textureFlags 96 | ); 97 | 98 | pViewport->m_depth_texture.Handle = th[1]; 99 | } 100 | 101 | // Create frame buffer 102 | pViewport->m_frame_buffer_handle = bgfx::createFrameBuffer( 103 | pViewport->CreateDepth ? 2 : 1, 104 | th, 105 | true 106 | ); 107 | } 108 | 109 | if (bgfx::isValid(pViewport->m_frame_buffer_handle)) 110 | { 111 | bgfx::setViewFrameBuffer(pViewport->m_view_id, pViewport->m_frame_buffer_handle); 112 | bgfx::setViewClear(pViewport->m_view_id, BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH, 113 | 0x303030ff, 1.0f, 0); 114 | } 115 | 116 | bgfx::setViewRect(pViewport->m_view_id, pViewport->Rect.x, pViewport->Rect.y, 117 | pViewport->Rect.width, pViewport->Rect.height); 118 | 119 | } 120 | bgfx::setViewTransform(m_view_id, m_pFrameDataCurrent->Camera->_view.v, 121 | m_pFrameDataCurrent->Camera->_proj.v); 122 | } 123 | } 124 | else if (state == UpdateState::GameplayState) 125 | { 126 | bgfx::Encoder* encoder = nullptr; 127 | if (p_world->GetUpdateType() == World::UpdateType::Async) 128 | { 129 | encoder = bgfx::begin(); 130 | } 131 | else 132 | { 133 | encoder = bgfx::getEncoder0(); 134 | } 135 | if (m_pFrameDataCurrent) 136 | { 137 | for (size_t i = 0; i < m_pFrameDataCurrent->Nodes.size(); i++) 138 | { 139 | m_pFrameDataCurrent->Nodes[i]->Render(m_pFrameDataCurrent->WorldMatrices[i], encoder, m_view_id); 140 | } 141 | delete m_pFrameDataCurrent; 142 | } 143 | if (p_world->GetUpdateType() == World::UpdateType::Async) 144 | { 145 | bgfx::end(encoder); 146 | } 147 | } 148 | } // Update 149 | 150 | void RenderSystem::Configure(World * p_world) 151 | { 152 | // Create vertex declarations 153 | m_pVertexDeclArray = new bgfx::VertexDecl[(int)VertexType::Count]; 154 | m_pVertexDeclArray[(int)VertexType::Pos] 155 | .begin() 156 | .add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float) 157 | .end(); 158 | m_pVertexDeclArray[(int)VertexType::Color] 159 | .begin() 160 | .add(bgfx::Attrib::Color0, 4, bgfx::AttribType::Uint8, true) 161 | .end(); 162 | 163 | // compile vertex shader, with default arguments. 164 | tinystl::string shaderFile = g_AssetDir; 165 | shaderFile.append("/shaders/basic/vs_basic.glsl"); 166 | const bgfx::Memory* memVsh = shaderc::compileShader(shaderc::ST_VERTEX, shaderFile.c_str()); 167 | bgfx::ShaderHandle vsh = bgfx::createShader(memVsh); 168 | 169 | // compile fragment shader, with specific arguments for defines, varying def file, shader profile. 170 | shaderFile = g_AssetDir; 171 | shaderFile.append("/shaders/basic/fs_basic.glsl"); 172 | const bgfx::Memory* memFsh = shaderc::compileShader(shaderc::ST_FRAGMENT, shaderFile.c_str()); 173 | bgfx::ShaderHandle fsh = bgfx::createShader(memFsh); 174 | 175 | // build program using shaders 176 | m_Program = new bgfx::ProgramHandle(); 177 | *m_Program = bgfx::createProgram(vsh, fsh, true); 178 | 179 | p_world->subscribe>(this); 180 | p_world->subscribe(this); 181 | 182 | } // Configure 183 | 184 | void RenderSystem::Unconfigure(World * p_world) 185 | { 186 | p_world->unsubscribeAll(this); 187 | 188 | } // Unconfigure 189 | 190 | bool RenderSystem::NeedUpdateOnState(UpdateState state) 191 | { 192 | switch (state) 193 | { 194 | case UpdateState::GameplayState: 195 | case UpdateState::MainThreadState: 196 | return true; 197 | default: 198 | return false; 199 | } 200 | } 201 | 202 | void RenderSystem::Receive(World * world, const events::OnComponentAssigned& event) 203 | { 204 | BX_UNUSED(world, event); 205 | BoxShape::Init(this); 206 | } 207 | 208 | void RenderSystem::Receive(World * world, const events::OnFrameData & event) 209 | { 210 | BX_UNUSED(world); 211 | m_pFrameDataNext = event.frame_data; 212 | } 213 | 214 | bgfx::VertexDecl * RenderSystem::GetVertexDecl(VertexType vertex_type) const 215 | { 216 | return &m_pVertexDeclArray[(int)vertex_type]; 217 | } 218 | 219 | } // ari 220 | -------------------------------------------------------------------------------- /src/engine/en/3d/SceneSystem.cpp: -------------------------------------------------------------------------------- 1 | #include "../../../../include/ari/en/3d/SceneSystem.hpp" 2 | #include "../../../../include/ari/en/World.hpp" 3 | #include "../../../../include/ari/en/Entity.hpp" 4 | #include "../../../../include/ari/en/3d/Camera.hpp" 5 | #include 6 | #include "../../../../include/ari/Engine.hpp" 7 | #include "../../../../include/ari/en/2d/Viewport.hpp" 8 | #include 9 | #include "bgfx/bgfx.h" 10 | 11 | namespace ari 12 | { 13 | SceneSystem::SceneSystem(): m_pActiveCamera(nullptr), m_FrameDatasUnused(nullptr), m_FrameDatasTransforms(nullptr), 14 | m_FrameDatasVisible(nullptr) 15 | { 16 | } 17 | 18 | SceneSystem::~SceneSystem() 19 | { 20 | } 21 | 22 | void SceneSystem::Update(World* p_world, UpdateState state) 23 | { 24 | if (state == UpdateState::SceneManagerState) 25 | { 26 | if (m_FrameDatasTransforms) 27 | { 28 | events::OnFrameData frame_data = { m_FrameDatasTransforms }; 29 | p_world->emit(frame_data); 30 | } 31 | m_FrameDatasTransforms = new FrameData; 32 | m_FrameDatasTransforms->FrameNumber = g_pEngine->GetCurrentFrameNumber(); 33 | m_FrameDatasTransforms->Camera = m_pActiveCamera; 34 | // Get all entities and calc transforms 35 | const auto& entities = p_world->GetAllEntities(); 36 | for (auto e : entities) 37 | { 38 | CalcTransform(e, nullptr); 39 | } 40 | 41 | if (m_pActiveCamera) 42 | { 43 | bx::mtxLookAt(m_pActiveCamera->_view.v, m_pActiveCamera->Position.ToVec3(), 44 | m_pActiveCamera->Target.ToVec3(), m_pActiveCamera->Up.ToVec3()); 45 | 46 | RectI rect; 47 | Viewport* p = m_pActiveCamera->GetChild(); 48 | if (p) 49 | rect = p->Rect; 50 | else 51 | { 52 | g_pEngine->GetMainWindow()->GetSize(rect.width, rect.height); 53 | } 54 | bx::mtxProj(m_pActiveCamera->_proj.v, 60.0f, float(rect.width) / float(rect.height), 1.0f, 1000.0f, 55 | bgfx::getCaps()->homogeneousDepth); 56 | } 57 | } 58 | } 59 | 60 | void SceneSystem::Configure(World * p_world) 61 | { 62 | p_world->subscribe(this); 63 | p_world->subscribe(this); 64 | p_world->subscribe>(this); 65 | p_world->subscribe>(this); 66 | p_world->subscribe>(this); 67 | p_world->subscribe>(this); 68 | } 69 | 70 | void SceneSystem::Unconfigure(World * p_world) 71 | { 72 | p_world->unsubscribeAll(this); 73 | } 74 | 75 | bool SceneSystem::NeedUpdateOnState(UpdateState state) 76 | { 77 | switch (state) 78 | { 79 | case UpdateState::GameplayState: 80 | case UpdateState::SceneManagerState: 81 | return true; 82 | default: 83 | return false; 84 | } 85 | } 86 | 87 | void SceneSystem::Receive(World * world, const events::OnEntityCreated & event) 88 | { 89 | BX_UNUSED(world, event); 90 | } 91 | 92 | void SceneSystem::Receive(World * world, const events::OnEntityDestroyed & event) 93 | { 94 | BX_UNUSED(world, event); 95 | } 96 | 97 | void SceneSystem::Receive(World * world, const events::OnComponentAssigned& event) 98 | { 99 | BX_UNUSED(world); 100 | if (!m_pActiveCamera) 101 | { 102 | m_pActiveCamera = event.component; 103 | m_pActiveCamera->_isActive = true; 104 | } 105 | } 106 | 107 | void SceneSystem::Receive(World * world, const events::OnComponentRemoved& event) 108 | { 109 | BX_UNUSED(world); 110 | if (m_pActiveCamera == event.component) 111 | { 112 | m_pActiveCamera = nullptr; 113 | } 114 | } 115 | 116 | void SceneSystem::Receive(World* world, const events::OnComponentAssigned& event) 117 | { 118 | BX_UNUSED(world, event); 119 | } 120 | 121 | void SceneSystem::Receive(World* world, const events::OnComponentRemoved& event) 122 | { 123 | BX_UNUSED(world, event); 124 | } 125 | 126 | void SceneSystem::CalcTransform(Node* node, Matrix* parentMat) 127 | { 128 | if (node->GetType() == Node::Type::Component) 129 | { 130 | Component* c = reinterpret_cast(node); 131 | if (c->_isFromNode3D) 132 | { 133 | Node3D* n = reinterpret_cast(node); 134 | Matrix m; 135 | m.SetTransform(n->Position, n->Rotation, n->Scale); 136 | if (parentMat) 137 | n->_finalMat = m * (*parentMat); 138 | else 139 | n->_finalMat = m; 140 | parentMat = &n->_finalMat; 141 | 142 | if (n->_isRenderable) 143 | { 144 | // Add it to frame data 145 | m_FrameDatasTransforms->Nodes.push_back(n); 146 | m_FrameDatasTransforms->WorldMatrices.push_back(n->_finalMat); 147 | } 148 | } 149 | } 150 | for (auto child: node->GetChildren()) 151 | { 152 | CalcTransform(child, parentMat); 153 | } 154 | } // CalcTransform 155 | 156 | } // ari 157 | -------------------------------------------------------------------------------- /src/engine/en/Component.cpp: -------------------------------------------------------------------------------- 1 | #include "../../../include/ari/en/Component.hpp" 2 | 3 | namespace ari 4 | { 5 | Component::Component(): _isFromNode3D(false), _isFromGui(false) 6 | { 7 | m_eNodeType = Type::Component; 8 | } 9 | 10 | } // ari 11 | -------------------------------------------------------------------------------- /src/engine/en/Entity.cpp: -------------------------------------------------------------------------------- 1 | #include "../../../include/ari/en/Entity.hpp" 2 | 3 | namespace ari 4 | { 5 | Entity::Entity() 6 | { 7 | m_eNodeType = Type::Entity; 8 | } 9 | 10 | Entity::~Entity() 11 | = default; 12 | 13 | } // ari 14 | -------------------------------------------------------------------------------- /src/engine/en/Node.cpp: -------------------------------------------------------------------------------- 1 | #include "../../../include/ari/en/Node.hpp" 2 | #include "../../../include/ari/en/World.hpp" 3 | #include "../../../include/ari/en/Component.hpp" 4 | #include "../../../include/ari/en/Entity.hpp" 5 | #include 6 | #include "../../../include/ari/Engine.hpp" 7 | 8 | namespace ari 9 | { 10 | Node::Node() : m_pParent(nullptr), m_eNodeType(Type::Unknown), m_pWorld(nullptr) 11 | { 12 | } 13 | 14 | Node::~Node() 15 | { 16 | RemoveChildren(true); 17 | } 18 | 19 | void Node::RemoveChildren(bool _delete) 20 | { 21 | childs.clear(); 22 | 23 | if (_delete) 24 | for (auto & node : m_vChilds) 25 | { 26 | delete node; 27 | } 28 | else 29 | { 30 | for (auto & node : m_vChilds) 31 | { 32 | node->m_pParent = nullptr; 33 | } 34 | 35 | m_vChilds.clear(); 36 | } 37 | 38 | } // RemoveChildren 39 | 40 | void Node::SetParent(Node* parent) 41 | { 42 | if (m_pParent) 43 | { 44 | m_pParent->RemoveChild(this); 45 | } 46 | m_pParent = parent; 47 | 48 | } // SetParent 49 | 50 | Entity* Node::GetParentEntity() const 51 | { 52 | if (m_pParent) 53 | { 54 | if (m_pParent->m_eNodeType == Type::Entity) 55 | { 56 | return static_cast(m_pParent); 57 | } 58 | return m_pParent->GetParentEntity(); 59 | } 60 | return nullptr; 61 | } 62 | 63 | void Node::Destroy(bool addToDestroyQueue) 64 | { 65 | assert(m_pWorld); 66 | m_iIsInDestroyQueue = g_pEngine->GetCurrentFrameNumber() + 2; 67 | for (auto child : m_vChilds) 68 | { 69 | child->Destroy(false); 70 | } 71 | if (addToDestroyQueue) 72 | m_pWorld->_AddToDestroyQueue(this); 73 | } 74 | 75 | } // ari 76 | -------------------------------------------------------------------------------- /src/engine/en/World.cpp: -------------------------------------------------------------------------------- 1 | #include "../../../include/ari/en/World.hpp" 2 | #include "../../../include/ari/en/System.hpp" 3 | #include "../../../include/ari/en/Entity.hpp" 4 | #include 5 | #include 6 | #include "../../../include/ari/Engine.hpp" 7 | 8 | extern bx::AllocatorI* g_allocator; 9 | 10 | namespace ari 11 | { 12 | //--------------------------------------------------------- 13 | // T A S K F U N C T I O N S 14 | 15 | struct SystemUpdateTaskData 16 | { 17 | World* world; 18 | System* system; 19 | System::UpdateState state; 20 | }; 21 | 22 | void SystemUpdateTask(ftl::TaskScheduler *taskScheduler, void *arg) 23 | { 24 | auto data = reinterpret_cast(arg); 25 | data->system->Update(data->world, data->state); 26 | delete data; 27 | } 28 | 29 | struct MainTaskArg 30 | { 31 | World* world; 32 | tinystl::vector systems; 33 | }; 34 | 35 | void MainTask(ftl::TaskScheduler *taskScheduler, void *arg) 36 | { 37 | MainTaskArg* task_arg = 38 | reinterpret_cast(arg); 39 | 40 | // Start the Gameplay state tasks 41 | ftl::AtomicCounter gameplayCounter(taskScheduler), 42 | inCounter(taskScheduler), 43 | sceneCounter(taskScheduler); 44 | tinystl::vector gameplay_tasks, 45 | independent_tasks, 46 | scene_tasks; 47 | for (auto s: task_arg->systems) 48 | { 49 | if (s->NeedUpdateOnState(System::UpdateState::GameplayState)) 50 | { 51 | auto update_arg = new SystemUpdateTaskData; 52 | update_arg->system = s; 53 | update_arg->state = System::UpdateState::GameplayState; 54 | update_arg->world = task_arg->world; 55 | if (s->GetSystemType() == System::Type::GameplaySystem) 56 | { 57 | gameplay_tasks.push_back({ SystemUpdateTask, update_arg }); 58 | } 59 | else 60 | { 61 | independent_tasks.push_back({ SystemUpdateTask , update_arg }); 62 | } 63 | } 64 | if (s->NeedUpdateOnState(System::UpdateState::SceneManagerState)) 65 | { 66 | auto update_arg = new SystemUpdateTaskData; 67 | update_arg->system = s; 68 | update_arg->state = System::UpdateState::SceneManagerState; 69 | update_arg->world = task_arg->world; 70 | scene_tasks.push_back({ SystemUpdateTask, update_arg }); 71 | } 72 | } 73 | 74 | // Add gameplay tasks to the taskScheduler 75 | if (!gameplay_tasks.empty()) 76 | taskScheduler->AddTasks(gameplay_tasks.size(), &gameplay_tasks[0], &gameplayCounter); 77 | if (!independent_tasks.empty()) 78 | taskScheduler->AddTasks(independent_tasks.size(), &independent_tasks[0], &inCounter); 79 | 80 | // Wait for gameplay tasks to start scene manager tasks 81 | taskScheduler->WaitForCounter(&gameplayCounter, 0); 82 | if (!scene_tasks.empty()) 83 | taskScheduler->AddTasks(scene_tasks.size(), &scene_tasks[0], &sceneCounter); 84 | 85 | taskScheduler->WaitForCounter(&sceneCounter, 0); 86 | taskScheduler->WaitForCounter(&inCounter, 0); 87 | 88 | } 89 | 90 | // T A S K F U N C T I O N S 91 | //--------------------------------------------------------- 92 | 93 | World::World(): m_UpdateType(UpdateType::Async), m_qDestroyQueue(g_allocator) 94 | { 95 | m_pTaskScheduler = new ftl::TaskScheduler(); 96 | 97 | } // Constructor 98 | 99 | World::~World() 100 | { 101 | delete m_pTaskScheduler; 102 | 103 | } // Destructor 104 | 105 | void World::AddSystem(System * p_system) 106 | { 107 | systems.push_back(p_system); 108 | p_system->Configure(this); 109 | } 110 | 111 | void World::RemoveSystem(System * p_system) 112 | { 113 | int c = 0; 114 | for (auto s: systems) 115 | { 116 | if (s == p_system) 117 | { 118 | p_system->Unconfigure(this); 119 | systems.erase(systems.begin() + c); 120 | return; 121 | } 122 | c++; 123 | } 124 | } 125 | 126 | void World::AddEntity(Entity * p_entity) 127 | { 128 | assert(p_entity->GetType() == Node::Type::Entity); 129 | Entities.push_back(p_entity); 130 | p_entity->m_pWorld = this; 131 | emit({ p_entity }); 132 | } 133 | 134 | void World::RemoveEntity(Entity* p_entity) 135 | { 136 | assert(p_entity->GetType() == Node::Type::Entity); 137 | int c = 0; 138 | for (auto e: Entities) 139 | { 140 | if (e == p_entity) 141 | { 142 | emit({ p_entity }); 143 | e->m_pWorld = nullptr; 144 | Entities.erase(Entities.begin() + c); 145 | return; 146 | } 147 | c++; 148 | } 149 | } 150 | 151 | void World::Update(float tick) 152 | { 153 | CheckDestroyQueue(); 154 | for (auto s : systems) 155 | if (s->NeedUpdateOnState(System::UpdateState::MainThreadState)) 156 | s->Update(this, System::UpdateState::MainThreadState); 157 | if (m_UpdateType == UpdateType::Sync) 158 | { 159 | for (auto s : systems) 160 | if (s->NeedUpdateOnState(System::UpdateState::GameplayState)) 161 | s->Update(this, System::UpdateState::GameplayState); 162 | for (auto s: systems) 163 | if (s->NeedUpdateOnState(System::UpdateState::SceneManagerState)) 164 | s->Update(this, System::UpdateState::SceneManagerState); 165 | } 166 | else if (m_UpdateType == UpdateType::Async) 167 | { 168 | MainTaskArg arg = { this, systems }; 169 | m_pTaskScheduler->Run(25, MainTask, &arg); 170 | } 171 | } 172 | 173 | void World::_AddToDestroyQueue(Node* node) 174 | { 175 | m_qDestroyQueue.push(node); 176 | } 177 | 178 | void World::CheckDestroyQueue() 179 | { 180 | Node* node; 181 | uint32_t fn = g_pEngine->GetCurrentFrameNumber(); 182 | do 183 | { 184 | node = m_qDestroyQueue.peek(); 185 | if (node && node->m_iIsInDestroyQueue < fn) 186 | { 187 | if (node->GetType() == Node::Type::Entity) 188 | { 189 | Entity* entity = reinterpret_cast(node); 190 | RemoveEntity(entity); 191 | } 192 | node->SetParent(nullptr); 193 | delete node; 194 | m_qDestroyQueue.pop(); 195 | } 196 | else return; 197 | } 198 | while (node); 199 | } 200 | 201 | } // ari 202 | -------------------------------------------------------------------------------- /src/engine/en/gui/Button.cpp: -------------------------------------------------------------------------------- 1 | #include "..\..\..\..\include\ari\en\gui\Button.hpp" 2 | #include "../../../../include/ari/en/gui/Dock.hpp" 3 | 4 | namespace ari 5 | { 6 | bool Button::BeginRender() 7 | { 8 | if (ImGui::Button(Label) && OnClick.IsBound()) 9 | { 10 | OnClick.Execute(); 11 | } 12 | return false; 13 | } 14 | 15 | } // ari 16 | -------------------------------------------------------------------------------- /src/engine/en/gui/CheckBox.cpp: -------------------------------------------------------------------------------- 1 | #include "../../../../include/ari/en/gui/CheckBox.hpp" 2 | #include "../../../../include/ari/en/gui/Dock.hpp" 3 | 4 | namespace ari 5 | { 6 | CheckBox::CheckBox(): Checked(false), Label("") 7 | { 8 | } 9 | 10 | bool CheckBox::BeginRender() 11 | { 12 | ImGui::Checkbox(Label, &Checked); 13 | return true; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/engine/en/gui/Dock.cpp: -------------------------------------------------------------------------------- 1 | #include "..\..\..\..\include\ari\en\gui\Dock.hpp" 2 | #include "../../../../deps/imguiDock/imgui_dock.h" 3 | 4 | namespace ari 5 | { 6 | Dock::Dock(): isOpened(true), Label(nullptr) 7 | { 8 | } 9 | 10 | bool Dock::BeginRender() 11 | { 12 | return ImGui::BeginDock(Label, &isOpened); 13 | } 14 | 15 | void Dock::EndRender() 16 | { 17 | ImGui::EndDock(); 18 | } 19 | 20 | } // ari 21 | -------------------------------------------------------------------------------- /src/engine/en/gui/DockSpace.cpp: -------------------------------------------------------------------------------- 1 | #include "../../../../include/ari/en/gui/DockSpace.hpp" 2 | #include "../../../../deps/imguiDock/imgui_dock.h" 3 | 4 | namespace ari 5 | { 6 | bool DockSpace::BeginRender() 7 | { 8 | ImGui::BeginDockspace(); 9 | return true; 10 | } 11 | 12 | void DockSpace::EndRender() 13 | { 14 | ImGui::EndDockspace(); 15 | } 16 | 17 | } // ari 18 | -------------------------------------------------------------------------------- /src/engine/en/gui/DockableWindow.cpp: -------------------------------------------------------------------------------- 1 | #include "../../../../include/ari/en/gui/DockableWindow.hpp" 2 | #include "ImwWindow.h" 3 | #include "../../../../include/ari/en/gui/GuiSystem.hpp" 4 | #include "ImwWindowManager.h" 5 | #include "Imw/ImwWindowManagerAri.hpp" 6 | #include "imw/ImwPlatformWindowAri.hpp" 7 | 8 | namespace ari 9 | { 10 | class AriImwWindow: public ImWindow::ImwWindow 11 | { 12 | public: 13 | AriImwWindow(DockableWindow* _pDock): m_pDockable(_pDock) 14 | { 15 | } 16 | 17 | void OnGui() override 18 | { 19 | auto p_window_manager = ImWindow::ImwWindowManager::GetInstance(); 20 | const auto win = reinterpret_cast 21 | (p_window_manager->GetCurrentPlatformWindow())->GetPlatformWindow(); 22 | 23 | if (win != m_pDockable->m_pPlatformWindow && m_pDockable->OnWindowChanged.IsBound()) 24 | { 25 | m_pDockable->m_pPlatformWindow = win; 26 | m_pDockable->OnWindowChanged.Execute(); 27 | } 28 | m_pDockable->m_pPlatformWindow = win; 29 | 30 | if (m_pDockable->OnGui.IsBound()) 31 | m_pDockable->OnGui.Execute(); 32 | 33 | for (auto c : m_pDockable->m_vChilds) 34 | m_pDockable->m_pGuiSystem->RenderGui(c); 35 | } 36 | 37 | protected: 38 | 39 | DockableWindow * m_pDockable; 40 | }; 41 | 42 | DockableWindow::DockableWindow(GuiSystem * _pGuiSystem): m_pGuiSystem(_pGuiSystem), m_pPlatformWindow(nullptr) 43 | { 44 | // Check window manager Init 45 | ImWindow::ImwWindowManager* p_window_manager = ImWindow::ImwWindowManager::GetInstance(); 46 | if (!p_window_manager) 47 | { 48 | p_window_manager = new ImwWindowManagerAri(); 49 | p_window_manager->Init(); 50 | } 51 | 52 | m_pWindow = new AriImwWindow(this); 53 | Dock(); 54 | } 55 | 56 | DockableWindow::~DockableWindow() 57 | { 58 | // TODO: Add some function to delete it. 59 | // The ImwWill delete it later on shutdown 60 | // delete m_pWindow; 61 | ImWindow::ImwWindowManager* p_window_manager = ImWindow::ImwWindowManager::GetInstance(); 62 | p_window_manager->DestroyWindow(m_pWindow); 63 | } 64 | 65 | bool DockableWindow::BeginRender() 66 | { 67 | return false; 68 | } 69 | 70 | void DockableWindow::Dock(Oriention _oriention, float _raito) const 71 | { 72 | ImWindow::ImwWindowManager* p_window_manager = ImWindow::ImwWindowManager::GetInstance(); 73 | p_window_manager->Dock(m_pWindow, ImWindow::EDockOrientation(_oriention), _raito); 74 | } 75 | 76 | void DockableWindow::DockWith(DockableWindow * _pOtherDock, Oriention _oriention, float _raito) const 77 | { 78 | ImWindow::ImwWindowManager* p_window_manager = ImWindow::ImwWindowManager::GetInstance(); 79 | p_window_manager->DockWith(m_pWindow, _pOtherDock->m_pWindow, 80 | ImWindow::EDockOrientation(_oriention), _raito); 81 | } 82 | 83 | void DockableWindow::SetTitle(const char * _pTitle) const 84 | { 85 | m_pWindow->SetTitle(_pTitle); 86 | } 87 | 88 | void DockableWindow::SetAlone(bool _alone) const 89 | { 90 | m_pWindow->SetAlone(_alone); 91 | } 92 | 93 | void DockableWindow::SetClosable(bool _closable) const 94 | { 95 | m_pWindow->SetClosable(_closable); 96 | } 97 | 98 | void DockableWindow::SetFillingSpace(bool _fill) const 99 | { 100 | m_pWindow->SetFillingSpace(_fill); 101 | } 102 | 103 | void DockableWindow::GetLastPosition(float & _x, float & _y) const 104 | { 105 | auto p = m_pWindow->GetLastPosition(); 106 | _x = p.x; 107 | _y = p.y; 108 | } 109 | 110 | void DockableWindow::GetLastSize(float & _width, float & _height) const 111 | { 112 | auto s = m_pWindow->GetLastSize(); 113 | _width = s.x; 114 | _height = s.y; 115 | } 116 | 117 | PlatformWindow * DockableWindow::GetPlatformWindow() const 118 | { 119 | return m_pPlatformWindow; 120 | } 121 | 122 | } // ari 123 | -------------------------------------------------------------------------------- /src/engine/en/gui/GuiSystem.cpp: -------------------------------------------------------------------------------- 1 | #include "../../../../include/ari/en/gui/GuiSystem.hpp" 2 | #include "../../../../include/ari/en/World.hpp" 3 | #include "../../../../include/ari/en/Entity.hpp" 4 | #include "../../../../include/ari/en/Component.hpp" 5 | #include "../../../../deps/bgfx/examples/common/imgui/imgui.h" 6 | #include "../../../../include/ari/en/gui/Gui.hpp" 7 | #include "bx/macros.h" 8 | #include "../../../../include/ari/Engine.hpp" 9 | #include "../../../../deps/imguiDock/imgui_dock.h" 10 | #include "ImwWindowManager.h" 11 | 12 | namespace ari 13 | { 14 | GuiSystem::GuiSystem(): m_bIsDockCreated(false) 15 | { 16 | } 17 | 18 | GuiSystem::~GuiSystem() 19 | { 20 | if (m_bIsDockCreated) 21 | ImGui::ShutdownDock(); 22 | } 23 | 24 | void GuiSystem::Update(World * p_world, UpdateState state) 25 | { 26 | if (state == UpdateState::MainThreadState) 27 | { 28 | imguiBeginFrame(g_pEngine->m_MouseState.m_mx 29 | , g_pEngine->m_MouseState.m_my 30 | , (g_pEngine->m_MouseState.m_buttons[MouseButton::Left] ? IMGUI_MBUT_LEFT : 0) 31 | | (g_pEngine->m_MouseState.m_buttons[MouseButton::Right] ? IMGUI_MBUT_RIGHT : 0) 32 | | (g_pEngine->m_MouseState.m_buttons[MouseButton::Middle] ? IMGUI_MBUT_MIDDLE : 0) 33 | , g_pEngine->m_MouseState.m_mz 34 | , uint16_t(g_pEngine->m_params->Width) 35 | , uint16_t(g_pEngine->m_params->Height) 36 | ); 37 | 38 | for (auto e: p_world->GetAllEntities()) 39 | { 40 | RenderGui(e); 41 | } 42 | 43 | ImWindow::ImwWindowManager* p_window_manager = ImWindow::ImwWindowManager::GetInstance(); 44 | if (p_window_manager) 45 | { 46 | p_window_manager->Run(false); 47 | p_window_manager->Run(true); 48 | } 49 | 50 | imguiEndFrame(); 51 | 52 | } 53 | } 54 | 55 | void GuiSystem::Configure(World * p_world) 56 | { 57 | imguiCreate(); 58 | p_world->subscribe>(this); 59 | } 60 | 61 | void GuiSystem::Unconfigure(World * p_world) 62 | { 63 | imguiDestroy(); 64 | p_world->unsubscribeAll(this); 65 | } 66 | 67 | System::Type GuiSystem::GetSystemType() 68 | { 69 | return Type::RenderSystem; 70 | } 71 | 72 | bool GuiSystem::NeedUpdateOnState(UpdateState state) 73 | { 74 | return state == UpdateState::MainThreadState; 75 | } 76 | 77 | void GuiSystem::Receive(World * world, const events::OnComponentAssigned& event) 78 | { 79 | BX_UNUSED(world, event); 80 | if (!m_bIsDockCreated) 81 | { 82 | ImGui::InitDock(); 83 | m_bIsDockCreated = true; 84 | } 85 | } 86 | 87 | void GuiSystem::RenderGui(Node * node) 88 | { 89 | if (node->IsInDestroyQueue()) 90 | return; 91 | 92 | Gui* gui = nullptr; 93 | bool renderChilds = true; 94 | if (node->GetType() == Node::Type::Component) 95 | { 96 | Component* cmp = reinterpret_cast(node); 97 | if (cmp->_isFromGui) 98 | { 99 | gui = reinterpret_cast(cmp); 100 | 101 | if (!gui->Visible) 102 | return; 103 | 104 | if (gui->SameLine) 105 | ImGui::SameLine(); 106 | 107 | if (gui->Separator) 108 | ImGui::Separator(); 109 | 110 | renderChilds = gui->BeginRender(); 111 | } 112 | } 113 | if (renderChilds) 114 | for (auto child : node->GetChildren()) 115 | { 116 | RenderGui(child); 117 | } 118 | if (gui) 119 | gui->EndRender(); 120 | } 121 | 122 | } // ari 123 | -------------------------------------------------------------------------------- /src/engine/en/gui/Image.cpp: -------------------------------------------------------------------------------- 1 | #include "../../../../include/ari/en/gui/Image.hpp" 2 | #include "../../../../deps/bgfx/examples/common/imgui/imgui.h" 3 | 4 | namespace ari 5 | { 6 | bool Image::BeginRender() 7 | { 8 | ImGui::Image(ImageTexture->Handle, Size); 9 | 10 | if (OnHovered.IsBound() && ImGui::IsItemHovered()) 11 | OnHovered.Execute(); 12 | 13 | return false; 14 | } 15 | 16 | } // ari 17 | -------------------------------------------------------------------------------- /src/engine/en/gui/Imw/ImwPlatformWindowAri.cpp: -------------------------------------------------------------------------------- 1 | #include "ImwPlatformWindowAri.hpp" 2 | #include "../../../../../include/ari/Engine.hpp" 3 | #include "../../../../../deps/bgfx/examples/common/imgui/imgui.h" 4 | 5 | namespace ari 6 | { 7 | ImwPlatformWindowAri::ImwPlatformWindowAri(ImWindow::EPlatformWindowType eType, bool bCreateContext): 8 | ImwPlatformWindow(eType, bCreateContext) 9 | { 10 | if (eType == ImWindow::E_PLATFORM_WINDOW_TYPE_MAIN) 11 | m_pWindow = g_pEngine->GetMainWindow(); 12 | else if (eType == ImWindow::E_PLATFORM_WINDOW_TYPE_DRAG_PREVIEW) 13 | m_pWindow = g_pEngine->NewWindow(PlatformWindow::Type::Popup); 14 | else 15 | m_pWindow = g_pEngine->NewWindow(PlatformWindow::Type::Child); 16 | } 17 | 18 | ImwPlatformWindowAri::~ImwPlatformWindowAri() 19 | { 20 | if (m_eType != ImWindow::E_PLATFORM_WINDOW_TYPE_MAIN) 21 | delete m_pWindow; 22 | } 23 | 24 | bool ImwPlatformWindowAri::Init(ImwPlatformWindow* pParent) 25 | { 26 | // Init frame buffers 27 | if (m_eType == ImWindow::E_PLATFORM_WINDOW_TYPE_MAIN) 28 | { 29 | m_iViewId = 0; 30 | return true; 31 | } 32 | 33 | m_iViewId = g_pEngine->GetNewViewId(); 34 | bgfx::setViewName(m_iViewId, "ImWindow"); 35 | 36 | // Init key bindings 37 | ImGuiIO& io = GetContext()->IO; 38 | io.KeyMap[ImGuiKey_Tab] = (int)ari::Key::Tab; 39 | io.KeyMap[ImGuiKey_LeftArrow] = (int)ari::Key::Left; 40 | io.KeyMap[ImGuiKey_RightArrow] = (int)ari::Key::Right; 41 | io.KeyMap[ImGuiKey_UpArrow] = (int)ari::Key::Up; 42 | io.KeyMap[ImGuiKey_DownArrow] = (int)ari::Key::Down; 43 | io.KeyMap[ImGuiKey_PageUp] = (int)ari::Key::PageUp; 44 | io.KeyMap[ImGuiKey_PageDown] = (int)ari::Key::PageDown; 45 | io.KeyMap[ImGuiKey_Home] = (int)ari::Key::Home; 46 | io.KeyMap[ImGuiKey_End] = (int)ari::Key::End; 47 | io.KeyMap[ImGuiKey_Insert] = (int)ari::Key::Insert; 48 | io.KeyMap[ImGuiKey_Delete] = (int)ari::Key::Delete; 49 | io.KeyMap[ImGuiKey_Backspace] = (int)ari::Key::Backspace; 50 | io.KeyMap[ImGuiKey_Space] = (int)ari::Key::Space; 51 | io.KeyMap[ImGuiKey_Enter] = (int)ari::Key::Return; 52 | io.KeyMap[ImGuiKey_Escape] = (int)ari::Key::Esc; 53 | io.KeyMap[ImGuiKey_A] = (int)ari::Key::KeyA; 54 | io.KeyMap[ImGuiKey_C] = (int)ari::Key::KeyC; 55 | io.KeyMap[ImGuiKey_V] = (int)ari::Key::KeyV; 56 | io.KeyMap[ImGuiKey_X] = (int)ari::Key::KeyX; 57 | io.KeyMap[ImGuiKey_Y] = (int)ari::Key::KeyY; 58 | io.KeyMap[ImGuiKey_Z] = (int)ari::Key::KeyZ; 59 | 60 | // Setup on events. 61 | m_onKey.Bind(this, &ImwPlatformWindowAri::OnKey); 62 | m_pWindow->AddOnKeyDelegate(&m_onKey); 63 | m_onChar.Bind(this, &ImwPlatformWindowAri::OnChar); 64 | m_pWindow->AddOnCharDelegate(&m_onChar); 65 | m_onMouseBtn.Bind(this, &ImwPlatformWindowAri::OnMouseKey); 66 | m_pWindow->AddOnMouseButtonDelegate(&m_onMouseBtn); 67 | m_onMouseMove.Bind(this, &ImwPlatformWindowAri::OnMouseMove); 68 | m_pWindow->AddOnMouseMoveDelegate(&m_onMouseMove); 69 | m_onMouseWheel.Bind(this, &ImwPlatformWindowAri::OnMouseWheel); 70 | m_onSize.Bind(this, &ImwPlatformWindowAri::OnSize); 71 | m_pWindow->AddOnSizeDelegate(&m_onSize); 72 | 73 | if (m_pWindow->Init(0, 0, 800, 600, 0, "Test")) 74 | { 75 | if (m_eType == ImWindow::E_PLATFORM_WINDOW_TYPE_DRAG_PREVIEW) 76 | m_pWindow->SetAlpha(128); 77 | 78 | m_hFrameBufferHandle = bgfx::createFrameBuffer(m_pWindow->GetHandle(), 800, 600); 79 | bgfx::setViewFrameBuffer(m_iViewId, m_hFrameBufferHandle); 80 | 81 | return true; 82 | } 83 | 84 | return false; 85 | } 86 | 87 | ImVec2 ImwPlatformWindowAri::GetPosition() const 88 | { 89 | int x, y; 90 | m_pWindow->GetPos(x, y); 91 | 92 | return {float(x), float(y)}; 93 | } 94 | 95 | ImVec2 ImwPlatformWindowAri::GetSize() const 96 | { 97 | int w, h; 98 | m_pWindow->GetSize(w, h); 99 | 100 | return { float(w), float(h)}; 101 | } 102 | 103 | bool ImwPlatformWindowAri::IsWindowMaximized() const 104 | { 105 | return m_pWindow->IsWindowMaximized(); 106 | } 107 | 108 | bool ImwPlatformWindowAri::IsWindowMinimized() const 109 | { 110 | return m_pWindow->IsWindowMinimized(); 111 | } 112 | 113 | void ImwPlatformWindowAri::Show(bool bShow) 114 | { 115 | m_pWindow->Show(bShow); 116 | } 117 | 118 | void ImwPlatformWindowAri::SetSize(int iWidth, int iHeight) 119 | { 120 | m_pWindow->SetSize(iWidth, iHeight); 121 | } 122 | 123 | void ImwPlatformWindowAri::SetPosition(int iX, int iY) 124 | { 125 | m_pWindow->SetPos(iX, iY); 126 | } 127 | 128 | void ImwPlatformWindowAri::SetWindowMaximized(bool bMaximized) 129 | { 130 | m_pWindow->SetWindowMaximized(bMaximized); 131 | } 132 | 133 | void ImwPlatformWindowAri::SetWindowMinimized(bool bMinimized) 134 | { 135 | m_pWindow->SetWindowMinimized(bMinimized); 136 | } 137 | 138 | void ImwPlatformWindowAri::SetTitle(const char* pTtile) 139 | { 140 | m_pWindow->SetTitle(pTtile); 141 | } 142 | 143 | void ImwPlatformWindowAri::PreUpdate() 144 | { 145 | m_pWindow->Run(); 146 | 147 | } 148 | 149 | void ImwPlatformWindowAri::RenderDrawLists(ImDrawData* pDrawData) 150 | { 151 | if (m_iViewId != 0) 152 | bgfx::setViewFrameBuffer(m_iViewId, m_hFrameBufferHandle); 153 | imguiRender(m_iViewId, pDrawData); 154 | } 155 | 156 | void ImwPlatformWindowAri::OnKey(Key::Enum _key, bool _down) 157 | { 158 | GetContext()->IO.KeysDown[_key] = _down; 159 | } 160 | 161 | void ImwPlatformWindowAri::OnChar(uint8_t _len, uint8_t * _utf8) 162 | { 163 | for (uint8_t i = 0; i < _len; i++) 164 | GetContext()->IO.AddInputCharactersUTF8(reinterpret_cast(&_utf8[i * 4])); 165 | } 166 | 167 | void ImwPlatformWindowAri::OnMouseKey(MouseButton::Enum _btn, bool _down) 168 | { 169 | switch (_btn) 170 | { 171 | case MouseButton::Left: 172 | GetContext()->IO.MouseDown[0] = _down; 173 | break; 174 | case MouseButton::Middle: 175 | GetContext()->IO.MouseDown[2] = _down; 176 | break; 177 | case MouseButton::Right: 178 | GetContext()->IO.MouseDown[1] = _down; 179 | break; 180 | default: 181 | break; 182 | } 183 | } 184 | 185 | void ImwPlatformWindowAri::OnMouseMove(int _x, int _y) 186 | { 187 | GetContext()->IO.MousePos.x = _x; 188 | GetContext()->IO.MousePos.y = _y; 189 | } 190 | 191 | void ImwPlatformWindowAri::OnMouseWheel(int _z) 192 | { 193 | GetContext()->IO.MouseWheel = _z; 194 | } 195 | 196 | void ImwPlatformWindowAri::OnSize(int _w, int _h) 197 | { 198 | if (bgfx::isValid(m_hFrameBufferHandle)) 199 | bgfx::destroy(m_hFrameBufferHandle); 200 | 201 | GetContext()->IO.DisplaySize = ImVec2(float(_w), float(_h)); 202 | 203 | m_hFrameBufferHandle = bgfx::createFrameBuffer(m_pWindow->GetHandle(), uint16_t(_w), uint16_t(_h)); 204 | 205 | if (m_eType == ImWindow::E_PLATFORM_WINDOW_TYPE_MAIN) 206 | { 207 | bgfx::setViewFrameBuffer(m_iViewId, m_hFrameBufferHandle); 208 | bgfx::reset(_w, _h); 209 | } 210 | 211 | } 212 | 213 | } // ari 214 | -------------------------------------------------------------------------------- /src/engine/en/gui/Imw/ImwPlatformWindowAri.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "ImwPlatformWindow.h" 3 | #include "../../../../../include/ari/io/PlatformWindow.hpp" 4 | #include 5 | 6 | namespace ari 7 | { 8 | class ImwPlatformWindowAri: public ImWindow::ImwPlatformWindow 9 | { 10 | public: 11 | ImwPlatformWindowAri(ImWindow::EPlatformWindowType eType, bool bCreateContext); 12 | ~ImwPlatformWindowAri() override; 13 | 14 | bool Init(ImwPlatformWindow* pParent) override; 15 | 16 | ImVec2 GetPosition() const override; 17 | ImVec2 GetSize() const override; 18 | 19 | bool IsWindowMaximized() const override; 20 | bool IsWindowMinimized() const override; 21 | 22 | void Show(bool bShow) override; 23 | void SetSize(int iWidth, int iHeight) override; 24 | void SetPosition(int iX, int iY) override; 25 | void SetWindowMaximized(bool bMaximized) override; 26 | void SetWindowMinimized(bool bMinimized) override; 27 | void SetTitle(const char* pTtile) override; 28 | 29 | PlatformWindow* GetPlatformWindow() const { return m_pWindow; } 30 | 31 | protected: 32 | void PreUpdate() override; 33 | void RenderDrawLists(ImDrawData* pDrawData) override; 34 | 35 | void OnKey(Key::Enum _key, bool _down); 36 | void OnChar(uint8_t len, uint8_t* utf8); 37 | void OnMouseKey(MouseButton::Enum _btn, bool _down); 38 | void OnMouseMove(int _x, int _y); 39 | void OnMouseWheel(int _z); 40 | void OnSize(int _w, int _h); 41 | 42 | PlatformWindow * m_pWindow = nullptr; 43 | DelegateTwoParam 44 | m_onKey; 45 | DelegateTwoParam 46 | m_onChar; 47 | DelegateTwoParam 48 | m_onMouseBtn; 49 | DelegateTwoParam m_onMouseMove, 50 | m_onSize; 51 | DelegateOneParam m_onMouseWheel; 52 | bgfx::ViewId m_iViewId; 53 | bgfx::FrameBufferHandle m_hFrameBufferHandle; 54 | }; 55 | 56 | } // ari 57 | -------------------------------------------------------------------------------- /src/engine/en/gui/Imw/ImwWindowManagerAri.cpp: -------------------------------------------------------------------------------- 1 | #include "ImwWindowManagerAri.hpp" 2 | #include 3 | #include "bgfx/bgfx.h" 4 | #include "ImwPlatformWindowAri.hpp" 5 | 6 | #if BX_PLATFORM_WINDOWS 7 | #include 8 | #endif 9 | 10 | namespace ari 11 | { 12 | bool ImwWindowManagerAri::CanCreateMultipleWindow() 13 | { 14 | const bgfx::Caps* caps = bgfx::getCaps(); 15 | return 0 != (caps->supported & BGFX_CAPS_SWAP_CHAIN); 16 | } 17 | 18 | ImWindow::ImwPlatformWindow* ImwWindowManagerAri::CreatePlatformWindow(ImWindow::EPlatformWindowType eType, 19 | ImWindow::ImwPlatformWindow* pParent) 20 | { 21 | bool createContex = eType == ImWindow::E_PLATFORM_WINDOW_TYPE_MAIN ? false : CanCreateMultipleWindow(); 22 | ImwPlatformWindowAri* pWindow = new ImwPlatformWindowAri(eType, createContex); 23 | if (pWindow->Init(pParent)) 24 | { 25 | return pWindow; 26 | } 27 | delete pWindow; 28 | return nullptr; 29 | } 30 | 31 | ImVec2 ImwWindowManagerAri::GetCursorPos() 32 | { 33 | #if BX_PLATFORM_WINDOWS 34 | POINT pt = { 0, 0 }; 35 | ::GetCursorPos(&pt); 36 | return { float(pt.x), float(pt.y) }; 37 | #endif 38 | 39 | // TODO: Add other os codes 40 | } 41 | 42 | bool ImwWindowManagerAri::IsLeftClickDown() 43 | { 44 | #if BX_PLATFORM_WINDOWS 45 | return GetAsyncKeyState(VK_LBUTTON) & 0x8000; 46 | #endif 47 | // TODO: Add other os codes 48 | } 49 | 50 | } // ari 51 | -------------------------------------------------------------------------------- /src/engine/en/gui/Imw/ImwWindowManagerAri.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "ImwWindowManager.h" 3 | 4 | namespace ari 5 | { 6 | class ImwWindowManagerAri: public ImWindow::ImwWindowManager 7 | { 8 | protected: 9 | bool CanCreateMultipleWindow() override; 10 | 11 | ImWindow::ImwPlatformWindow* CreatePlatformWindow(ImWindow::EPlatformWindowType eType, 12 | ImWindow::ImwPlatformWindow* pParent) override; 13 | 14 | ImVec2 GetCursorPos() override; 15 | 16 | bool IsLeftClickDown() override; 17 | }; 18 | 19 | } // ari 20 | -------------------------------------------------------------------------------- /src/engine/en/gui/Label.cpp: -------------------------------------------------------------------------------- 1 | #include "../../../../include/ari/en/gui/Label.hpp" 2 | #include "../../../../include/ari/en/gui/Dock.hpp" 3 | 4 | namespace ari 5 | { 6 | Label::Label(): Text(nullptr) 7 | { 8 | } 9 | 10 | bool Label::BeginRender() 11 | { 12 | ImGui::Text(Text); 13 | return true; 14 | } 15 | 16 | } // ari 17 | -------------------------------------------------------------------------------- /src/engine/en/gui/Popup.cpp: -------------------------------------------------------------------------------- 1 | #include "../../../../include/ari/en/gui/Popup.hpp" 2 | #include 3 | 4 | namespace ari 5 | { 6 | bool Popup::BeginRender() 7 | { 8 | if (m_bOpenPopup) 9 | { 10 | ImGui::OpenPopup(Name); 11 | m_bOpenPopup = false; 12 | } 13 | m_bDoEndPopup = ImGui::BeginPopup(Name); 14 | return m_bDoEndPopup; 15 | } 16 | 17 | void Popup::EndRender() 18 | { 19 | if (m_bDoEndPopup) 20 | { 21 | if (m_bClosePopup) 22 | { 23 | ImGui::CloseCurrentPopup(); 24 | m_bClosePopup = false; 25 | } 26 | ImGui::EndPopup(); 27 | } 28 | } 29 | 30 | void Popup::Show() 31 | { 32 | m_bOpenPopup = true; 33 | } 34 | 35 | void Popup::Hide() 36 | { 37 | m_bClosePopup = true; 38 | } 39 | 40 | } // ari 41 | -------------------------------------------------------------------------------- /src/engine/en/gui/TextBox.cpp: -------------------------------------------------------------------------------- 1 | #include "..\..\..\..\include\ari\en\gui\TextBox.hpp" 2 | #include "dear-imgui/imgui.h" 3 | #include "bx/bx.h" 4 | #include "bx/string.h" 5 | 6 | ari::TextBox::TextBox(size_t maxLength): Label(nullptr), m_MaxLength(maxLength) 7 | { 8 | Text = new char[maxLength]; 9 | bx::memSet(Text, 0, maxLength); 10 | } 11 | 12 | ari::TextBox::~TextBox() 13 | { 14 | delete[] Text; 15 | } 16 | 17 | bool ari::TextBox::BeginRender() 18 | { 19 | ImGui::InputText(Label, Text, m_MaxLength); 20 | return true; 21 | } 22 | 23 | void ari::TextBox::SetText(const char * _text) const 24 | { 25 | bx::strCopy(Text, m_MaxLength, _text); 26 | } 27 | -------------------------------------------------------------------------------- /src/engine/en/gui/Window.cpp: -------------------------------------------------------------------------------- 1 | #include "../../../../include/ari/en/gui/Window.hpp" 2 | 3 | namespace ari 4 | { 5 | Window::Window(): Name(nullptr), CloseButton(false), isOpen(true), Flags(0) 6 | { 7 | } 8 | 9 | bool Window::BeginRender() 10 | { 11 | ImGui::SetNextWindowPos( 12 | Pos 13 | , ImGuiCond_FirstUseEver 14 | ); 15 | ImGui::SetNextWindowSize( 16 | Size 17 | , ImGuiCond_FirstUseEver 18 | ); 19 | if (CloseButton) 20 | return ImGui::Begin(Name 21 | , &isOpen 22 | , Flags 23 | ); 24 | return ImGui::Begin(Name 25 | , nullptr 26 | , Flags 27 | ); 28 | } 29 | 30 | void Window::EndRender() 31 | { 32 | ImGui::End(); 33 | } 34 | 35 | } // ari 36 | -------------------------------------------------------------------------------- /src/engine/gfx/ShadersCode.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace ari 4 | { 5 | const char* vsCode = 6 | "$input a_position, a_color0 \ 7 | $output v_color0 \ 8 | void main() \ 9 | { \ 10 | gl_Position = mul(u_modelViewProj, vec4(a_position, 1.0)); \ 11 | v_color0 = a_color0; \ 12 | } \ 13 | "; 14 | 15 | const char* psCode = 16 | "$input v_color0 \ 17 | void main() \ 18 | { \ 19 | gl_FragColor = v_color0; \ 20 | } \ 21 | "; 22 | } // ari 23 | -------------------------------------------------------------------------------- /src/engine/gfx/Texture.cpp: -------------------------------------------------------------------------------- 1 | #include "..\..\..\include\ari\gfx\Texture.hpp" 2 | 3 | namespace ari 4 | { 5 | Texture::Texture(const uint32_t & _handel, const std::string & _fileName) 6 | : Resource(_handel, _fileName) 7 | { 8 | } 9 | 10 | Texture::~Texture() 11 | { 12 | } 13 | 14 | 15 | } // ari 16 | -------------------------------------------------------------------------------- /src/engine/gfx/TextureManager.cpp: -------------------------------------------------------------------------------- 1 | #include "..\..\..\include\ari\gfx\TextureManager.hpp" 2 | #include "../../../include/ari/ResourceLoader.hpp" 3 | 4 | namespace ari 5 | { 6 | TextureManager::~TextureManager() 7 | { 8 | } 9 | 10 | bool TextureManager::LoadResource(Texture ** ppOut, uint32_t handle, const std::string& filename, 11 | void * extraParams) 12 | { 13 | bx::FilePath path = filename.c_str(); 14 | std::string ext = path.getExt().getPtr(); 15 | for (auto loader: m_vLoaders) 16 | { 17 | if (loader->IsALoadableFileExtension(ext)) 18 | { 19 | bx::FileReader r; 20 | bx::Error err; 21 | if (r.open(path, &err)) 22 | { 23 | *ppOut = reinterpret_cast(loader->LoadResource 24 | (&r, handle, filename, extraParams)); 25 | if (*ppOut) 26 | return true; 27 | } 28 | } 29 | } 30 | return false; 31 | } 32 | 33 | } // ari 34 | -------------------------------------------------------------------------------- /src/engine/io/IoEvents.cpp: -------------------------------------------------------------------------------- 1 | #include "../../../include/ari/io/IoEvents.hpp" 2 | #include "../../../include/ari/Engine.hpp" 3 | 4 | namespace ari 5 | { 6 | const Event * poll() 7 | { 8 | return g_pEngine->Poll(); 9 | } 10 | 11 | const Event * poll(WindowHandle _handle) 12 | { 13 | BX_UNUSED(_handle); 14 | return nullptr; 15 | } 16 | 17 | void release(const Event * _event) 18 | { 19 | g_pEngine->Release(_event); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/engine/io/PlatformWindow.cpp: -------------------------------------------------------------------------------- 1 | #include "../../../include/ari/io/PlatformWindow.hpp" 2 | #include "../../../include/ari/Engine.hpp" 3 | #include "../../../include/ari/io/Input.hpp" 4 | 5 | namespace ari 6 | { 7 | void PlatformWindow::GetSize(int& _width, int& _height) 8 | { 9 | _width = m_width; 10 | _height = m_height; 11 | } 12 | 13 | void PlatformWindow::AddOnKeyDelegate(DelegateTwoParam* _pDelegate) 14 | { 15 | m_vOnKeys.push_back(_pDelegate); 16 | } 17 | 18 | void PlatformWindow::RemoveOnKeyDelegate(DelegateTwoParam* _pDelegate) 19 | { 20 | for (auto it = m_vOnKeys.begin(); it != m_vOnKeys.end(); it++) 21 | if (*it == _pDelegate) 22 | { 23 | m_vOnKeys.erase(it); 24 | return; 25 | } 26 | } 27 | 28 | void PlatformWindow::AddOnCharDelegate(DelegateTwoParam* _pDelegate) 29 | { 30 | m_vOnChar.push_back(_pDelegate); 31 | } 32 | 33 | void PlatformWindow::RemoveOnCharDelegate(DelegateTwoParam* _pDelegate) 34 | { 35 | for (auto it = m_vOnChar.begin(); it != m_vOnChar.end(); it++) 36 | if (*it == _pDelegate) 37 | { 38 | m_vOnChar.erase(it); 39 | return; 40 | } 41 | } 42 | 43 | void PlatformWindow::AddOnMouseButtonDelegate(DelegateTwoParam* _pDelegate) 44 | { 45 | m_vOnMouseButtons.push_back(_pDelegate); 46 | } 47 | 48 | void PlatformWindow::RemoveOnMouseButtonDelegate(DelegateTwoParam* _pDelegate) 49 | { 50 | for (auto it = m_vOnMouseButtons.begin(); it != m_vOnMouseButtons.end(); it++) 51 | if (*it == _pDelegate) 52 | { 53 | m_vOnMouseButtons.erase(it); 54 | return; 55 | } 56 | } 57 | 58 | void PlatformWindow::AddOnMouseMoveDelegate(DelegateTwoParam* _pDelegate) 59 | { 60 | m_vOnMouseMove.push_back(_pDelegate); 61 | } 62 | 63 | void PlatformWindow::RemoveOnMouseMoveDelegate(DelegateTwoParam* _pDelegate) 64 | { 65 | for (auto it = m_vOnMouseMove.begin(); it != m_vOnMouseMove.end(); it++) 66 | if (*it == _pDelegate) 67 | { 68 | m_vOnMouseMove.erase(it); 69 | return; 70 | } 71 | } 72 | 73 | void PlatformWindow::AddOnMouseWheelDelegate(DelegateOneParam* _pDelegate) 74 | { 75 | m_vOnMouseWheel.push_back(_pDelegate); 76 | } 77 | 78 | void PlatformWindow::RemoveOnMouseWheelDelegate(DelegateOneParam* _pDelegate) 79 | { 80 | for (auto it = m_vOnMouseWheel.begin(); it != m_vOnMouseWheel.end(); it++) 81 | if (*it == _pDelegate) 82 | { 83 | m_vOnMouseWheel.erase(it); 84 | return; 85 | } 86 | } 87 | 88 | void PlatformWindow::AddOnSizeDelegate(DelegateTwoParam* _pDelegate) 89 | { 90 | m_vOnSize.push_back(_pDelegate); 91 | } 92 | 93 | void PlatformWindow::RemoveOnSizeDelegate(DelegateTwoParam* _pDelegate) 94 | { 95 | for (auto it = m_vOnSize.begin(); it != m_vOnSize.end(); it++) 96 | if (*it == _pDelegate) 97 | { 98 | m_vOnSize.erase(it); 99 | return; 100 | } 101 | } 102 | 103 | bool PlatformWindow::ProcessEvents(uint32_t & _width, uint32_t & _height, uint32_t & _debug, uint32_t & _reset, MouseState * _mouse) 104 | { 105 | g_pEngine->m_debug = _debug; 106 | g_pEngine->m_reset = _reset; 107 | 108 | const bool mouseLock = inputIsMouseLocked(); 109 | 110 | const Event* ev; 111 | do 112 | { 113 | struct SE { const Event* m_ev; SE() : m_ev(poll()) {} ~SE() { if (NULL != m_ev) { release(m_ev); } } } scopeEvent; 114 | ev = scopeEvent.m_ev; 115 | 116 | if (NULL != ev) 117 | { 118 | switch (ev->m_type) 119 | { 120 | case Event::Axis: 121 | { 122 | const AxisEvent* axis = static_cast(ev); 123 | inputSetGamepadAxis(axis->m_gamepad, axis->m_axis, axis->m_value); 124 | } 125 | break; 126 | 127 | case Event::Char: 128 | { 129 | const CharEvent* chev = static_cast(ev); 130 | inputChar(chev->m_len, chev->m_char); 131 | } 132 | break; 133 | 134 | case Event::Exit: 135 | return false; 136 | 137 | case Event::Gamepad: 138 | { 139 | // const GamepadEvent* gev = static_cast(ev); 140 | // DBG("gamepad %d, %d", gev->m_gamepad.idx, gev->m_connected); 141 | } 142 | break; 143 | 144 | case Event::Mouse: 145 | { 146 | const MouseEvent* mouse = static_cast(ev); 147 | 148 | inputSetMousePos(mouse->m_mx, mouse->m_my, mouse->m_mz); 149 | if (!mouse->m_move) 150 | { 151 | inputSetMouseButtonState(mouse->m_button, mouse->m_down); 152 | } 153 | 154 | if (NULL != _mouse 155 | && !mouseLock) 156 | { 157 | _mouse->m_mx = mouse->m_mx; 158 | _mouse->m_my = mouse->m_my; 159 | _mouse->m_mz = mouse->m_mz; 160 | if (!mouse->m_move) 161 | { 162 | _mouse->m_buttons[mouse->m_button] = mouse->m_down; 163 | } 164 | } 165 | } 166 | break; 167 | 168 | case Event::Key: 169 | { 170 | const KeyEvent* key = static_cast(ev); 171 | 172 | inputSetKeyState(key->m_key, key->m_modifiers, key->m_down); 173 | } 174 | break; 175 | 176 | case Event::Size: 177 | { 178 | const SizeEvent* size = static_cast(ev); 179 | 180 | _width = size->m_width; 181 | _height = size->m_height; 182 | _reset = !g_pEngine->m_reset; // force reset 183 | } 184 | break; 185 | 186 | case Event::Window: 187 | break; 188 | 189 | case Event::Suspend: 190 | break; 191 | 192 | case Event::DropFile: 193 | { 194 | // const DropFileEvent* drop = static_cast(ev); 195 | //DBG("%s", drop->m_filePath.get()); 196 | } 197 | break; 198 | 199 | default: 200 | break; 201 | } 202 | } 203 | 204 | inputProcess(); 205 | 206 | } while (NULL != ev); 207 | 208 | if (m_Type == Type::Main 209 | && _reset != g_pEngine->m_reset) 210 | { 211 | _reset = g_pEngine->m_reset; 212 | g_pEngine->m_bNeedReset = true; 213 | inputSetMouseResolution(uint16_t(_width), uint16_t(_height)); 214 | } 215 | 216 | _debug = g_pEngine->m_debug; 217 | 218 | g_pEngine->m_params->Width = _width; 219 | g_pEngine->m_params->Height = _height; 220 | 221 | 222 | return true; // s_exit 223 | } 224 | } // ari 225 | -------------------------------------------------------------------------------- /src/engine/io/SdlWindow.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #ifdef ARI_USE_SDL 3 | 4 | #include "../../../include/ari/Engine.hpp" 5 | #include "../../../include/ari/io/IoEvents.hpp" 6 | #include "bx/handlealloc.h" 7 | #include "bx/mutex.h" 8 | #include 9 | 10 | namespace ari 11 | { 12 | struct GamepadSDL 13 | { 14 | GamepadSDL(); 15 | 16 | void create(const SDL_JoyDeviceEvent& _jev); 17 | 18 | void create(const SDL_ControllerDeviceEvent& _cev); 19 | 20 | void update(EventQueue& _eventQueue, WindowHandle _handle, GamepadHandle _gamepad, 21 | GamepadAxis::Enum _axis, int32_t _value); 22 | 23 | void destroy(); 24 | 25 | bool filter(GamepadAxis::Enum _axis, int32_t* _value); 26 | int32_t m_value[GamepadAxis::Count]; 27 | int32_t m_deadzone[GamepadAxis::Count]; 28 | 29 | SDL_Joystick* m_joystick; 30 | SDL_GameController* m_controller; 31 | // SDL_Haptic* m_haptic; 32 | SDL_JoystickID m_jid; 33 | }; 34 | 35 | class SdlWindow 36 | { 37 | friend class Engine; 38 | 39 | public: 40 | 41 | bool Init(std::shared_ptr params); 42 | 43 | void setWindowSize(WindowHandle _handle, uint32_t _width, uint32_t _height, bool _force); 44 | 45 | bool Run(); 46 | 47 | static void setMouseLock(WindowHandle _handle, bool _lock); 48 | 49 | bool processEvents(uint32_t& _width, uint32_t& _height, uint32_t& _debug, uint32_t& _reset, 50 | MouseState* _mouse); 51 | 52 | protected: 53 | 54 | 55 | WindowHandle findHandle(uint32_t _windowId); 56 | 57 | WindowHandle findHandle(SDL_Window * _window); 58 | 59 | GamepadHandle findGamepad(int _jid); 60 | 61 | bx::HandleAllocT m_windowAlloc; 62 | SDL_Window* m_window[ARI_CONFIG_MAX_WINDOW]; 63 | uint32_t m_flags[ARI_CONFIG_MAX_WINDOW]; 64 | bx::HandleAllocT m_gamepadAlloc; 65 | GamepadSDL m_gamepad[ENTRY_CONFIG_MAX_GAMEPADS]; 66 | std::shared_ptr m_params; 67 | bx::Mutex m_lock; 68 | int m_mx, m_my, m_mz; 69 | EventQueue m_eventQueue; 70 | WindowHandle defaultWindow; 71 | 72 | }; // SdlWindow 73 | 74 | } // ari 75 | 76 | #endif ARI_USE_SDL 77 | -------------------------------------------------------------------------------- /src/engine/io/WindowWin32.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #if BX_PLATFORM_WINDOWS 5 | 6 | #include "../../../include/ari/io/PlatformWindow.hpp" 7 | #include 8 | 9 | namespace ari 10 | { 11 | class WindowWin32: public PlatformWindow 12 | { 13 | public: 14 | WindowWin32(Type _type); 15 | ~WindowWin32() override; 16 | 17 | bool Init(int _posx, int _posy, int _width, int _height, uint32_t _flags, 18 | const char* _title) override; 19 | 20 | bool Run() override; 21 | void Show(bool _show) override; 22 | 23 | void SetMousePos(int _x, int _y) override; 24 | 25 | void SetTitle(const char* _title) override; 26 | 27 | void SetFlags(uint32_t _flags, bool _addFlags) override; 28 | 29 | void GetPos(int& _x, int& _y) override; 30 | void SetPos(int _x, int _y) override; 31 | 32 | void SetSize(int _width, int _height) override; 33 | 34 | void SetAlpha(unsigned char _alpha) override; 35 | 36 | void SetMouseLock(bool _lock) override; 37 | 38 | void ToggleFrame() override; 39 | 40 | bool IsWindowMaximized() override; 41 | void SetWindowMaximized(bool _maximize) override; 42 | bool IsWindowMinimized() override; 43 | void SetWindowMinimized(bool _minimize) override; 44 | 45 | void* GetHandle() override; 46 | 47 | LRESULT Process(HWND _hwnd, UINT _id, WPARAM _wparam, LPARAM _lparam); 48 | 49 | protected: 50 | 51 | void Adjust(uint32_t _width, uint32_t _height, bool _windowFrame); 52 | void Clear(); 53 | 54 | protected: 55 | 56 | HWND m_hwnd; 57 | uint32_t m_flags; 58 | RECT m_rect; 59 | DWORD m_style; 60 | bool m_frame = true; 61 | bool m_init = false; 62 | bool m_exit = false; 63 | bool m_mouseLock = false; 64 | int m_mx = 0, 65 | m_my = 0, 66 | m_mz = 0; 67 | }; 68 | } // ari 69 | 70 | #endif 71 | -------------------------------------------------------------------------------- /src/engine/main.cpp: -------------------------------------------------------------------------------- 1 | #include "../../include/ari/aridef.hpp" 2 | #include "bx/allocator.h" 3 | 4 | bx::AllocatorI* g_allocator = ari::getDefaultAllocator(); 5 | 6 | namespace ari 7 | { 8 | bx::AllocatorI* getDefaultAllocator() 9 | { 10 | BX_PRAGMA_DIAGNOSTIC_PUSH(); 11 | BX_PRAGMA_DIAGNOSTIC_IGNORED_MSVC(4459); // warning C4459: declaration of 's_allocator' hides global declaration 12 | BX_PRAGMA_DIAGNOSTIC_IGNORED_CLANG_GCC("-Wshadow"); 13 | static bx::DefaultAllocator s_allocator; 14 | return &s_allocator; 15 | BX_PRAGMA_DIAGNOSTIC_POP(); 16 | } 17 | 18 | void* TinyStlAllocator::static_allocate(size_t _bytes) 19 | { 20 | return BX_ALLOC(g_allocator, _bytes); 21 | } 22 | 23 | void TinyStlAllocator::static_deallocate(void* _ptr, size_t) 24 | { 25 | if (_ptr) 26 | { 27 | BX_FREE(g_allocator, _ptr); 28 | } 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/engine/math/Matrix.cpp: -------------------------------------------------------------------------------- 1 | #include "../../../include/ari/math/Matrix.hpp" 2 | #include "bx/math.h" 3 | 4 | namespace ari 5 | { 6 | void Matrix::Identity() 7 | { 8 | bx::mtxIdentity(v); 9 | } 10 | 11 | Matrix Matrix::operator*(const Matrix& m) const 12 | { 13 | Matrix r; 14 | bx::float4x4_mul(&r.f, &f, &m.f); 15 | return r; 16 | } 17 | 18 | void Matrix::operator*=(const Matrix& m) 19 | { 20 | bx::float4x4_mul(&f, &f, &m.f); 21 | } 22 | 23 | void Matrix::SetPositionRotation(const Vector3& position, const Vector3& rotation) 24 | { 25 | bx::mtxRotateXYZ(v, rotation.x, rotation.y, rotation.z); 26 | _41 = position.x; 27 | _42 = position.y; 28 | _43 = position.z; 29 | } 30 | 31 | void Matrix::SetTransform(const Vector3& position, const Vector3& rotation, const Vector3& scale) 32 | { 33 | bx::mtxSRT(v, scale.x, scale.y, scale.z, 34 | rotation.x, rotation.y, rotation.z, 35 | position.x, position.y, position.z); 36 | } 37 | } // ari 38 | -------------------------------------------------------------------------------- /src/plugins/bimg/BimgLoader.cpp: -------------------------------------------------------------------------------- 1 | #include "BimgLoader.hpp" 2 | #include "bgfx/bgfx.h" 3 | #include "bimg/bimg.h" 4 | #include "bimg/decode.h" 5 | #include "../../../include/ari/gfx/Texture.hpp" 6 | 7 | namespace ari 8 | { 9 | void* load(bx::FileReaderI* _reader, bx::AllocatorI* _allocator, uint32_t* _size) 10 | { 11 | uint32_t size = (uint32_t)bx::getSize(_reader); 12 | void* data = BX_ALLOC(_allocator, size); 13 | bx::read(_reader, data, size); 14 | bx::close(_reader); 15 | if (nullptr != _size) 16 | { 17 | *_size = size; 18 | } 19 | return data; 20 | } 21 | 22 | void unload(void* _ptr) 23 | { 24 | BX_FREE(getDefaultAllocator(), _ptr); 25 | } 26 | 27 | static void imageReleaseCb(void* _ptr, void* _userData) 28 | { 29 | BX_UNUSED(_ptr); 30 | bimg::ImageContainer* imageContainer = (bimg::ImageContainer*)_userData; 31 | bimg::imageFree(imageContainer); 32 | } 33 | 34 | BimgLoader::BimgLoader() 35 | { 36 | m_aFileExtension.push_back("png"); 37 | m_aFileExtension.push_back("jpg"); 38 | m_aFileExtension.push_back("bmp"); 39 | m_aFileExtension.push_back("jpeg"); 40 | m_aFileExtension.push_back("tga"); 41 | m_aFileExtension.push_back("dds"); 42 | 43 | } 44 | 45 | Resource * BimgLoader::LoadResource(bx::FileReaderI * pStream, uint32_t _handle, 46 | const std::string& _filename, void* _extraParams) 47 | { 48 | bgfx::TextureHandle bgfx_handle = BGFX_INVALID_HANDLE; 49 | 50 | TextureParams temp_params; 51 | TextureParams* params; 52 | if (_extraParams) 53 | params = reinterpret_cast(_extraParams); 54 | else 55 | params = &temp_params; 56 | 57 | uint32_t size; 58 | void* data = load(pStream, getDefaultAllocator(), &size); 59 | if (nullptr != data) 60 | { 61 | bimg::ImageContainer* imageContainer = bimg::imageParse(getDefaultAllocator(), data, size); 62 | 63 | if (nullptr != imageContainer) 64 | { 65 | if (nullptr != params->Orientation) 66 | { 67 | *params->Orientation = imageContainer->m_orientation; 68 | } 69 | 70 | const bgfx::Memory* mem = bgfx::makeRef( 71 | imageContainer->m_data 72 | , imageContainer->m_size 73 | , imageReleaseCb 74 | , imageContainer 75 | ); 76 | unload(data); 77 | 78 | if (imageContainer->m_cubeMap) 79 | { 80 | bgfx_handle = bgfx::createTextureCube( 81 | uint16_t(imageContainer->m_width) 82 | , 1 < imageContainer->m_numMips 83 | , imageContainer->m_numLayers 84 | , bgfx::TextureFormat::Enum(imageContainer->m_format) 85 | , params->Flags 86 | , mem 87 | ); 88 | } 89 | else if (1 < imageContainer->m_depth) 90 | { 91 | bgfx_handle = bgfx::createTexture3D( 92 | uint16_t(imageContainer->m_width) 93 | , uint16_t(imageContainer->m_height) 94 | , uint16_t(imageContainer->m_depth) 95 | , 1 < imageContainer->m_numMips 96 | , bgfx::TextureFormat::Enum(imageContainer->m_format) 97 | , params->Flags 98 | , mem 99 | ); 100 | } 101 | else if (bgfx::isTextureValid(0, false, imageContainer->m_numLayers, bgfx::TextureFormat::Enum(imageContainer->m_format), params->Flags)) 102 | { 103 | bgfx_handle = bgfx::createTexture2D( 104 | uint16_t(imageContainer->m_width) 105 | , uint16_t(imageContainer->m_height) 106 | , 1 < imageContainer->m_numMips 107 | , imageContainer->m_numLayers 108 | , bgfx::TextureFormat::Enum(imageContainer->m_format) 109 | , params->Flags 110 | , mem 111 | ); 112 | } 113 | 114 | if (NULL != params->Info) 115 | { 116 | bgfx::calcTextureSize( 117 | *params->Info 118 | , uint16_t(imageContainer->m_width) 119 | , uint16_t(imageContainer->m_height) 120 | , uint16_t(imageContainer->m_depth) 121 | , imageContainer->m_cubeMap 122 | , 1 < imageContainer->m_numMips 123 | , imageContainer->m_numLayers 124 | , bgfx::TextureFormat::Enum(imageContainer->m_format) 125 | ); 126 | } 127 | 128 | if (bgfx::isValid(bgfx_handle)) 129 | { 130 | bgfx::setName(bgfx_handle, _filename.c_str()); 131 | Texture* t = new Texture(_handle, _filename); 132 | t->Handle = bgfx_handle; 133 | return t; 134 | } 135 | } 136 | } 137 | 138 | return nullptr; 139 | } 140 | 141 | } // ari 142 | -------------------------------------------------------------------------------- /src/plugins/bimg/BimgLoader.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../../../include/ari/ResourceLoader.hpp" 3 | 4 | namespace ari 5 | { 6 | class BimgLoader: public ResourceLoader 7 | { 8 | public: 9 | BimgLoader(); 10 | 11 | ~BimgLoader() override = default; 12 | 13 | Resource* LoadResource(bx::FileReaderI* pStream, uint32_t _handle, 14 | const std::string& _filename, void* _extraParams) override; 15 | 16 | }; // BimgLoader 17 | 18 | } // ari 19 | -------------------------------------------------------------------------------- /src/plugins/bimg/bimgPlugin.cpp: -------------------------------------------------------------------------------- 1 | #include "../../../include/ari/Plugin.hpp" 2 | #include "../../../include/ari/Engine.hpp" 3 | #include "BimgLoader.hpp" 4 | 5 | namespace ari 6 | { 7 | class BimgPlugin : public Plugin 8 | { 9 | public: 10 | 11 | BimgPlugin(const uint32_t& _handel, const std::string& _fileName) 12 | : Plugin(_handel, _fileName) 13 | { 14 | m_eType = Type::TextureLoader; 15 | } 16 | 17 | void* Create() override 18 | { 19 | BimgLoader* p = new BimgLoader(); 20 | return reinterpret_cast(p); 21 | } 22 | 23 | }; 24 | } // ari 25 | 26 | extern "C" 27 | { 28 | ARI_PLUGIN_API ari::Plugin* RegisterPlugin(ari::Engine* pEngine, const uint32_t& _handel, 29 | const std::string& _fileName) 30 | { 31 | ari::BimgPlugin* p = new ari::BimgPlugin(_handel, _fileName); 32 | pEngine->texture_manager.AddLoader(reinterpret_cast(p->Create())); 33 | return p; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/shiva/main.cpp: -------------------------------------------------------------------------------- 1 | #define CR_HOST // required in the host only and before including cr.h 2 | #include "../../deps/cr/cr.h" 3 | 4 | const char *plugin = BUILD_DIR CR_PLUGIN("shivaeditorDebug"); 5 | 6 | int main(int argc, char *argv[]) { 7 | cr_plugin ctx; 8 | // the host application should initalize a plugin with a context, a plugin 9 | // filename without extension and the full path to the plugin 10 | cr_plugin_load(ctx, plugin); 11 | 12 | // call the plugin update function with the plugin context to execute it 13 | // at any frequency matters to you 14 | while (cr_plugin_update(ctx)) { 15 | 16 | } 17 | 18 | // at the end do not forget to cleanup the plugin context, as it needs to 19 | // allocate some memory to track internal and plugin states 20 | cr_plugin_close(ctx); 21 | return 0; 22 | } 23 | --------------------------------------------------------------------------------