├── .github └── workflows │ └── main.yml ├── .gitignore ├── .gitmodules ├── .idea ├── .gitignore ├── .name ├── codeStyles │ ├── Project.xml │ └── codeStyleConfig.xml ├── deployment.xml ├── fileTemplates │ ├── includes │ │ └── C File Header.h │ └── internal │ │ └── C Header File.h ├── misc.xml ├── modules.xml ├── real-engine.iml └── vcs.xml ├── .vscode └── settings.json ├── CMakeLists.txt ├── CMakePresets.json ├── CMakeSettings.json ├── LICENSE ├── README.md ├── building.md ├── cmake ├── assets.cmake ├── build.cmake ├── compilerOptions.cmake ├── coverage.cmake ├── rdoc.cmake ├── sanitizers.cmake └── shaders.cmake ├── engine ├── CMakeLists.txt ├── include │ └── real │ │ ├── api │ │ └── gl │ │ │ ├── gl_array_vertex.hpp │ │ │ ├── gl_buffer_index.hpp │ │ │ ├── gl_buffer_vertex.hpp │ │ │ ├── gl_conversions.hpp │ │ │ ├── gl_headers.hpp │ │ │ ├── gl_renderer_api.hpp │ │ │ ├── gl_rendering_context.hpp │ │ │ ├── gl_shader.hpp │ │ │ └── gl_texture.hpp │ │ ├── application.hpp │ │ ├── assert.hpp │ │ ├── core.hpp │ │ ├── event.hpp │ │ ├── event │ │ ├── base_event.hpp │ │ ├── key_event.hpp │ │ ├── mouse_event.hpp │ │ └── window_event.hpp │ │ ├── input.hpp │ │ ├── input │ │ └── base_input.hpp │ │ ├── keycode.hpp │ │ ├── layer.hpp │ │ ├── layer │ │ ├── base_layer.hpp │ │ └── imgui_layer.hpp │ │ ├── layer_stack.hpp │ │ ├── logger.hpp │ │ ├── pch.hpp │ │ ├── platform │ │ └── windows │ │ │ ├── windows_input.hpp │ │ │ ├── windows_time.hpp │ │ │ └── windows_window.hpp │ │ ├── real.hpp │ │ ├── renderer.hpp │ │ ├── renderer │ │ ├── array_vertex.hpp │ │ ├── base_renderer.hpp │ │ ├── base_rendering_context.hpp │ │ ├── base_shader.hpp │ │ ├── base_texture.hpp │ │ ├── buffer_index.hpp │ │ ├── buffer_layout.hpp │ │ ├── buffer_vertex.hpp │ │ ├── camera.hpp │ │ ├── common.hpp │ │ ├── light.hpp │ │ ├── material.hpp │ │ ├── render_command.hpp │ │ ├── renderer_api.hpp │ │ └── shaders │ │ │ ├── base.glsl │ │ │ ├── material.glsl │ │ │ └── tex.glsl │ │ ├── time.hpp │ │ ├── time │ │ └── timestep.hpp │ │ ├── transform.hpp │ │ ├── util │ │ └── singleton.hpp │ │ ├── window.hpp │ │ └── window │ │ └── base_window.hpp └── src │ ├── api │ └── gl │ │ ├── gl_array_vertex.cpp │ │ ├── gl_buffer_index.cpp │ │ ├── gl_buffer_vertex.cpp │ │ ├── gl_renderer_api.cpp │ │ ├── gl_rendering_context.cpp │ │ ├── gl_shader.cpp │ │ ├── gl_texture.cpp │ │ └── imgui_build.cpp │ ├── application.cpp │ ├── base_input.cpp │ ├── base_layer.cpp │ ├── base_window.cpp │ ├── layer │ └── imgui_layer.cpp │ ├── layer_stack.cpp │ ├── logger.cpp │ ├── platform │ └── windows │ │ ├── windows_input.cpp │ │ ├── windows_time.cpp │ │ └── windows_window.cpp │ ├── renderer │ ├── array_vertex.cpp │ ├── base_renderer.cpp │ ├── base_rendering_context.cpp │ ├── base_shader.cpp │ ├── base_texture.cpp │ ├── buffer_index.cpp │ ├── buffer_layout.cpp │ ├── buffer_vertex.cpp │ ├── camera.cpp │ └── renderer_api.cpp │ └── stb.cpp ├── examples ├── CMakeLists.txt └── cube │ └── main.cpp ├── plan.md ├── rdoc └── settings.cap └── vendor ├── CMakeLists.txt └── stb ├── CMakeLists.txt └── include └── stb └── image.h /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: Build 2 | run-name: building main library 3 | on: [push] 4 | jobs: 5 | build: 6 | runs-on: windows-latest 7 | steps: 8 | - name: Checkout 9 | uses: actions/checkout@v3 10 | with: 11 | submodules: recursive 12 | - name: Build with CMake 13 | uses: lukka/run-cmake@v10.6 14 | with: 15 | configurePreset: base-win 16 | buildPreset: base-win 17 | 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### macOS template 3 | # General 4 | .DS_Store 5 | .AppleDouble 6 | .LSOverride 7 | 8 | # Icon must end with two \r 9 | Icon 10 | 11 | # Thumbnails 12 | ._* 13 | 14 | # Files that might appear in the root of a volume 15 | .DocumentRevisions-V100 16 | .fseventsd 17 | .Spotlight-V100 18 | .TemporaryItems 19 | .Trashes 20 | .VolumeIcon.icns 21 | .com.apple.timemachine.donotpresent 22 | 23 | # Directories potentially created on remote AFP share 24 | .AppleDB 25 | .AppleDesktop 26 | Network Trash Folder 27 | Temporary Items 28 | .apdisk 29 | 30 | ### C++ template 31 | # Prerequisites 32 | *.d 33 | 34 | # Compiled Object files 35 | *.slo 36 | *.lo 37 | *.o 38 | *.obj 39 | 40 | # Precompiled Headers 41 | *.gch 42 | *.pch 43 | 44 | # Compiled Dynamic libraries 45 | *.so 46 | *.dylib 47 | *.dll 48 | 49 | # Fortran module files 50 | *.mod 51 | *.smod 52 | 53 | # Compiled Static libraries 54 | *.lai 55 | *.la 56 | *.a 57 | *.lib 58 | 59 | # Executables 60 | *.exe 61 | *.out 62 | *.app 63 | 64 | ### C template 65 | # Prerequisites 66 | *.d 67 | 68 | # Object files 69 | *.o 70 | *.ko 71 | *.obj 72 | *.elf 73 | 74 | # Linker output 75 | *.ilk 76 | *.map 77 | *.exp 78 | 79 | # Precompiled Headers 80 | *.gch 81 | *.pch 82 | 83 | # Libraries 84 | *.lib 85 | *.a 86 | *.la 87 | *.lo 88 | 89 | # Shared objects (inc. Windows DLLs) 90 | *.dll 91 | *.so 92 | *.so.* 93 | *.dylib 94 | 95 | # Executables 96 | *.exe 97 | *.out 98 | *.app 99 | *.i*86 100 | *.x86_64 101 | *.hex 102 | 103 | # Debug files 104 | *.dSYM/ 105 | *.su 106 | *.idb 107 | *.pdb 108 | 109 | # Kernel Module Compile Results 110 | *.mod* 111 | *.cmd 112 | .tmp_versions/ 113 | modules.order 114 | Module.symvers 115 | Mkfile.old 116 | dkms.conf 117 | 118 | ### Windows template 119 | # Windows thumbnail cache files 120 | Thumbs.db 121 | Thumbs.db:encryptable 122 | ehthumbs.db 123 | ehthumbs_vista.db 124 | 125 | # Dump file 126 | *.stackdump 127 | 128 | # Folder config file 129 | [Dd]esktop.ini 130 | 131 | # Recycle Bin used on file shares 132 | $RECYCLE.BIN/ 133 | 134 | # Windows Installer files 135 | *.cab 136 | *.msi 137 | *.msix 138 | *.msm 139 | *.msp 140 | 141 | # Windows shortcuts 142 | *.lnk 143 | 144 | ### JetBrains template 145 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider 146 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 147 | 148 | # User-specific stuff 149 | .idea/**/workspace.xml 150 | .idea/**/tasks.xml 151 | .idea/**/usage.statistics.xml 152 | .idea/**/dictionaries 153 | .idea/**/shelf 154 | 155 | # Generated files 156 | .idea/**/contentModel.xml 157 | 158 | # Sensitive or high-churn files 159 | .idea/**/dataSources/ 160 | .idea/**/dataSources.ids 161 | .idea/**/dataSources.local.xml 162 | .idea/**/sqlDataSources.xml 163 | .idea/**/dynamic.xml 164 | .idea/**/uiDesigner.xml 165 | .idea/**/dbnavigator.xml 166 | 167 | # Gradle 168 | .idea/**/gradle.xml 169 | .idea/**/libraries 170 | 171 | # Gradle and Maven with auto-import 172 | # When using Gradle or Maven with auto-import, you should exclude module files, 173 | # since they will be recreated, and may cause churn. Uncomment if using 174 | # auto-import. 175 | # .idea/artifacts 176 | # .idea/compiler.xml 177 | # .idea/jarRepositories.xml 178 | # .idea/modules.xml 179 | # .idea/*.iml 180 | # .idea/modules 181 | # *.iml 182 | # *.ipr 183 | 184 | # CMake 185 | cmake-build-*/ 186 | build/ 187 | 188 | # Mongo Explorer plugin 189 | .idea/**/mongoSettings.xml 190 | 191 | # File-based project format 192 | *.iws 193 | 194 | # IntelliJ 195 | out/ 196 | 197 | # mpeltonen/sbt-idea plugin 198 | .idea_modules/ 199 | 200 | # JIRA plugin 201 | atlassian-ide-plugin.xml 202 | 203 | # Cursive Clojure plugin 204 | .idea/replstate.xml 205 | 206 | # Crashlytics plugin (for Android Studio and IntelliJ) 207 | com_crashlytics_export_strings.xml 208 | crashlytics.properties 209 | crashlytics-build.properties 210 | fabric.properties 211 | 212 | # Editor-based Rest Client 213 | .idea/httpRequests 214 | 215 | # Android studio 3.1+ serialized cache file 216 | .idea/caches/build_file_checksums.ser 217 | 218 | ### Python template 219 | # Byte-compiled / optimized / DLL files 220 | __pycache__/ 221 | *.py[cod] 222 | *$py.class 223 | 224 | # C extensions 225 | *.so 226 | 227 | # Distribution / packaging 228 | .Python 229 | build/ 230 | develop-eggs/ 231 | dist/ 232 | downloads/ 233 | eggs/ 234 | .eggs/ 235 | lib/ 236 | lib64/ 237 | parts/ 238 | sdist/ 239 | var/ 240 | wheels/ 241 | share/python-wheels/ 242 | *.egg-info/ 243 | .installed.cfg 244 | *.egg 245 | MANIFEST 246 | 247 | # PyInstaller 248 | # Usually these files are written by a python script from a template 249 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 250 | *.manifest 251 | *.spec 252 | 253 | # Installer logs 254 | pip-log.txt 255 | pip-delete-this-directory.txt 256 | 257 | # Unit test / coverage reports 258 | htmlcov/ 259 | .tox/ 260 | .nox/ 261 | .coverage 262 | .coverage.* 263 | .cache 264 | nosetests.xml 265 | coverage.xml 266 | *.cover 267 | *.py,cover 268 | .hypothesis/ 269 | .pytest_cache/ 270 | cover/ 271 | 272 | # Translations 273 | *.mo 274 | *.pot 275 | 276 | # Django stuff: 277 | *.log 278 | local_settings.py 279 | db.sqlite3 280 | db.sqlite3-journal 281 | 282 | # Flask stuff: 283 | instance/ 284 | .webassets-cache 285 | 286 | # Scrapy stuff: 287 | .scrapy 288 | 289 | # Sphinx documentation 290 | docs/_build/ 291 | 292 | # PyBuilder 293 | .pybuilder/ 294 | target/ 295 | 296 | # Jupyter Notebook 297 | .ipynb_checkpoints 298 | 299 | # IPython 300 | profile_default/ 301 | ipython_config.py 302 | 303 | # pyenv 304 | # For a library or package, you might want to ignore these files since the code is 305 | # intended to run in multiple environments; otherwise, check them in: 306 | # .python-version 307 | 308 | # pipenv 309 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 310 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 311 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 312 | # install all needed dependencies. 313 | #Pipfile.lock 314 | 315 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 316 | __pypackages__/ 317 | 318 | # Celery stuff 319 | celerybeat-schedule 320 | celerybeat.pid 321 | 322 | # SageMath parsed files 323 | *.sage.py 324 | 325 | # Environments 326 | .env 327 | .venv 328 | env/ 329 | venv/ 330 | ENV/ 331 | env.bak/ 332 | venv.bak/ 333 | 334 | # Spyder project settings 335 | .spyderproject 336 | .spyproject 337 | 338 | # Rope project settings 339 | .ropeproject 340 | 341 | # mkdocs documentation 342 | /site 343 | 344 | # mypy 345 | .mypy_cache/ 346 | .dmypy.json 347 | dmypy.json 348 | 349 | # Pyre type checker 350 | .pyre/ 351 | 352 | # pytype static type analyzer 353 | .pytype/ 354 | 355 | # Cython debug symbols 356 | cython_debug/ 357 | 358 | ### VisualStudioCode template 359 | .vscode/* 360 | !.vscode/settings.json 361 | !.vscode/tasks.json 362 | !.vscode/launch.json 363 | !.vscode/extensions.json 364 | *.code-workspace 365 | 366 | # Local History for Visual Studio Code 367 | .history/ 368 | 369 | ### CMake template 370 | CMakeLists.txt.user 371 | CMakeCache.txt 372 | CMakeFiles 373 | CMakeScripts 374 | Testing 375 | Makefile 376 | cmake_install.cmake 377 | install_manifest.txt 378 | compile_commands.json 379 | CTestTestfile.cmake 380 | _deps 381 | 382 | /.vs/ 383 | .vscode/settings.json 384 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "vendor/spdlog"] 2 | path = vendor/spdlog 3 | url = https://github.com/gabime/spdlog.git 4 | [submodule "vendor/glfw"] 5 | path = vendor/glfw 6 | url = https://github.com/glfw/glfw.git 7 | [submodule "vendor/glad"] 8 | path = vendor/glad 9 | url = https://github.com/Dav1dde/glad.git 10 | [submodule "vendor/imgui"] 11 | path = vendor/imgui 12 | url = https://github.com/udv-code/version-imgui.git 13 | [submodule "vendor/glm"] 14 | path = vendor/glm 15 | url = https://github.com/g-truc/glm.git 16 | -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | # Editor-based HTTP Client requests 5 | /httpRequests/ 6 | -------------------------------------------------------------------------------- /.idea/.name: -------------------------------------------------------------------------------- 1 | real-engine -------------------------------------------------------------------------------- /.idea/codeStyles/Project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 22 | -------------------------------------------------------------------------------- /.idea/codeStyles/codeStyleConfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /.idea/deployment.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /.idea/fileTemplates/includes/C File Header.h: -------------------------------------------------------------------------------- 1 | #if ($HEADER_COMMENTS) 2 | // Copyright (c) $YEAR ${USER_NAME}#if (!$USER_NAME.endsWith(".")).#end All rights reserved. 3 | #if ($ORGANIZATION_NAME && $ORGANIZATION_NAME != "") 4 | // Copyright (c) $YEAR ${ORGANIZATION_NAME}#if (!$ORGANIZATION_NAME.endsWith(".")).#end All rights reserved. 5 | #end 6 | #end 7 | 8 | -------------------------------------------------------------------------------- /.idea/fileTemplates/internal/C Header File.h: -------------------------------------------------------------------------------- 1 | #parse("C File Header.h") 2 | #[[#ifndef]]# ${INCLUDE_GUARD} 3 | #[[#define]]# ${INCLUDE_GUARD} 4 | 5 | #[[#include]]# "real/core.hpp" 6 | 7 | namespace real { 8 | 9 | } 10 | 11 | #[[#endif]]# //${INCLUDE_GUARD} 12 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 27 | 28 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/real-engine.iml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "C_Cpp.default.configurationProvider": "ms-vscode.cmake-tools", 3 | 4 | // Cmake 5 | "cmake.buildDirectory": "${workspaceFolder}/build/laptop/vscode/", 6 | "cmake.generator": "MinGW Makefiles", 7 | 8 | "cmake.configureSettings": { 9 | "OPTION_REAL_BUILD_EXAMPLES": "ON" 10 | }, 11 | } -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | ### CMake setup 2 | 3 | # Version 4 | cmake_minimum_required(VERSION 3.23 FATAL_ERROR) 5 | # Policies 6 | cmake_policy(SET CMP0077 NEW) # option honors normal variables 7 | 8 | ### Meta info 9 | 10 | # Names 11 | set(META_REAL_PROJECT_NAME "real") 12 | string(TOUPPER "real" META_REAL_PROJECT_NAME_PREFIX) 13 | string(TOUPPER ${META_REAL_PROJECT_NAME} META_REAL_PROJECT_NAME_UPPER) 14 | set(META_REAL_PROJECT_FULL_NAME "${META_REAL_PROJECT_NAME}-engine") 15 | set(META_REAL_PROJECT_DESCRIPTION "The Real 3D Rendering Engine") 16 | set(META_REAL_AUTHOR "udvsharp") 17 | set(META_REAL_AUTHOR_DOMAIN "https://github.com/${META_REAL_AUTHOR}/${META_REAL_PROJECT_NAME}") 18 | 19 | # Version 20 | set(META_REAL_VERSION_MAJOR "1") 21 | set(META_REAL_VERSION_MINOR "0") 22 | set(META_REAL_VERSION_PATCH "0") 23 | set(META_REAL_VERSION_TWEAK "0") 24 | set(META_REAL_VERSION "${META_REAL_VERSION_MAJOR}.${META_REAL_VERSION_MINOR}.${META_REAL_VERSION_PATCH}.${META_REAL_VERSION_TWEAK}") 25 | set(META_REAL_NAME_VERSION "${META_REAL_PROJECT_FULL_NAME} v${META_REAL_VERSION_MAJOR}.${META_REAL_VERSION_MINOR}.${META_REAL_VERSION_PATCH}.${META_REAL_VERSION_TWEAK}") 26 | 27 | # Targets 28 | set(REAL_LIBRARY_TARGET_NAME "${META_REAL_PROJECT_NAME}") 29 | 30 | ### Project config options 31 | 32 | option(BUILD_SHARED_LIBS "Build shared libraries" OFF) 33 | # Examples 34 | option(OPTION_REAL_BUILD_EXAMPLES "Build examples" OFF) 35 | # Detail examples 36 | option(OPTION_REAL_EXAMPLES_CUBE "Build rotating cube example" ON) 37 | # Analysis tools 38 | option(OPTION_REAL_ENABLE_COVERAGE "Enable code coverage" OFF) 39 | option(OPTION_REAL_ENABLE_SANITIZE "Enable sanitizers" OFF) 40 | # Tools 41 | option(OPTION_REAL_DEBUG_CMAKE "Enable CMake debugging information" OFF) 42 | 43 | # Configs 44 | list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake") 45 | set_property(GLOBAL PROPERTY USE_FOLDERS ON) 46 | 47 | ### Project 48 | project(${META_REAL_PROJECT_FULL_NAME} 49 | VERSION ${META_REAL_VERSION} 50 | DESCRIPTION ${META_REAL_PROJECT_DESCRIPTION} 51 | HOMEPAGE_URL ${META_REAL_AUTHOR_DOMAIN} 52 | LANGUAGES C CXX ASM) 53 | 54 | ### Language Options 55 | # C 56 | set(C_STANDARD_DEFAULT 11) 57 | set(CMAKE_C_STANDARD ${C_STANDARD_DEFAULT}) 58 | set(CMAKE_C_STANDARD_REQUIRED ON) 59 | set(CMAKE_C_EXTENSIONS OFF) 60 | # C++ 61 | set(CXX_STANDARD_DEFAULT 20) 62 | set(CMAKE_CXX_STANDARD ${CXX_STANDARD_DEFAULT}) 63 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 64 | set(CMAKE_CXX_EXTENSIONS OFF) 65 | # TODO: ASM 66 | 67 | ### Modules 68 | # Standard 69 | # include(WriteCompilerDetectionHeader) # Consider using https://nemequ.github.io/hedley/ instead 70 | include(GenerateExportHeader) 71 | 72 | # Own 73 | include(build) 74 | 75 | include(rdoc) 76 | include(assets) 77 | include(shaders) 78 | 79 | # TODO: get rid of dependencies 80 | ### Submodules 81 | add_subdirectory(vendor) 82 | 83 | ### Packages 84 | find_package(OpenGL REQUIRED) 85 | 86 | ### Code analysis 87 | # Coverage 88 | if (OPTION_REAL_ENABLE_COVERAGE) 89 | include(coverage) 90 | append_coverage_compiler_flags() 91 | endif () 92 | 93 | # Sanitizers 94 | if (OPTION_REAL_ENABLE_SANITIZE) 95 | include(sanitizers) 96 | # TODO: append_sanitizer_compiler_flags() 97 | endif () 98 | 99 | ### Engine 100 | add_subdirectory(engine) 101 | 102 | target_link_libraries( 103 | ${REAL_LIBRARY_TARGET_NAME} 104 | PUBLIC 105 | imgui 106 | glfw 107 | glad 108 | spdlog::spdlog 109 | OpenGL::GL 110 | glm::glm 111 | 112 | stb 113 | ) 114 | 115 | ### Examples 116 | if (OPTION_REAL_BUILD_EXAMPLES) 117 | add_subdirectory(examples) 118 | endif () -------------------------------------------------------------------------------- /CMakePresets.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 6, 3 | "cmakeMinimumRequired": { 4 | "major": 3, 5 | "minor": 23, 6 | "patch": 0 7 | }, 8 | "configurePresets": [ 9 | { 10 | "name": "base", 11 | "displayName": "Default Config", 12 | "description": "Default build preset", 13 | "binaryDir": "${sourceDir}/build/base", 14 | "cacheVariables": { 15 | "BUILD_SHARED_LIBS": false, 16 | "OPTION_REAL_BUILD_EXAMPLES": true, 17 | "OPTION_REAL_ENABLE_COVERAGE": true, 18 | "OPTION_REAL_ENABLE_SANITIZE": false, 19 | "OPTION_REAL_DEBUG_CMAKE": false 20 | }, 21 | "environment": { 22 | }, 23 | "vendor": { 24 | } 25 | }, 26 | { 27 | "name": "base-win", 28 | "inherits": [ 29 | "base" 30 | ], 31 | "description": "Base windows build preset", 32 | "binaryDir": "${sourceDir}/build/base", 33 | "generator": "Visual Studio 17 2022" 34 | } 35 | ], 36 | "buildPresets": [ 37 | { 38 | "name": "default", 39 | "configurePreset": "base-win" 40 | }, 41 | { 42 | "name": "base-win", 43 | "configurePreset": "base-win" 44 | } 45 | ], 46 | "testPresets": [ 47 | ], 48 | "packagePresets": [ 49 | ], 50 | "workflowPresets": [ 51 | { 52 | "name": "default", 53 | "steps": [ 54 | { 55 | "type": "configure", 56 | "name": "base-win" 57 | }, 58 | { 59 | "type": "build", 60 | "name": "base-win" 61 | } 62 | ] 63 | } 64 | ] 65 | } -------------------------------------------------------------------------------- /CMakeSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "configurations": [ 3 | { 4 | "name": "x64-Debug", 5 | "generator": "Visual Studio 16 2019", 6 | "configurationType": "Debug", 7 | "inheritEnvironments": [ "msvc_x64_x64" ], 8 | "buildRoot": "${projectDir}\\build\\vs\\${name}", 9 | "installRoot": "${projectDir}\\out\\install\\${name}", 10 | "cmakeCommandArgs": "-DOPTION_REAL_BUILD_EXAMPLES=ON", 11 | "buildCommandArgs": "", 12 | "ctestCommandArgs": "", 13 | "variables": [ 14 | { 15 | "name": "CMAKE_BUILD_TYPE", 16 | "value": "Debug", 17 | "type": "STRING" 18 | } 19 | ], 20 | "intelliSenseMode": "android-clang-arm64" 21 | }, 22 | { 23 | "name": "x64-Release", 24 | "generator": "Ninja", 25 | "configurationType": "Release", 26 | "buildRoot": "${projectDir}\\build\\vs\\${name}", 27 | "installRoot": "${projectDir}\\out\\install\\${name}", 28 | "cmakeCommandArgs": "", 29 | "buildCommandArgs": "", 30 | "ctestCommandArgs": "", 31 | "inheritEnvironments": [ "msvc_x64_x64" ], 32 | "variables": [] 33 | } 34 | ] 35 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Dmitry udv-code Vasyliev 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. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # The Real Engine 2 | [//]: # (TODO: add logo) 3 | 4 | **The Real Engine** is a cross-platform 3D rendering engine. 5 | **Currently Real Engine is not fully-implemented**. 6 | 7 | ## Getting started 8 | You can clone the repository to a local destination using git: 9 | 10 | - `git clone --recursive https://github.com/udv-code/real` 11 | 12 | You may do a `--recursive` clone to fetch all of the submodules. 13 | 14 | ## Instructions 15 | You can find build instructions [here](building.md) 16 | 17 | ## The Plan 18 | The plan is to create a 3D cross-platform rendering engine 19 | and learn "the best practices" of game engine development. 20 | 21 | That's the matter for development to be very slow and precise. 22 | 23 | You can view plans, issues, TODOs and more [here](plan.md). 24 | 25 | ### Mentions 26 | Inspired by [TheCherno's](https://github.com/TheCherno) [Hazel](https://github.com/TheCherno/Hazel) videos. 27 | -------------------------------------------------------------------------------- /building.md: -------------------------------------------------------------------------------- 1 | ### Requirements 2 | - CMake 3.17+ 3 | ### Instructions 4 | 1. Clone project from github: `git clone https://github.com/udv-code/real --recursive` 5 | 2. Create build directory: `mkdir build && cd build`. 6 | 3. Configure CMake project: `cmake ..` or with specific generator(for example, VS 2019) : `cmake -G "Visual Studio 16 2019" ..` 7 | - If you want to build sandbox project, you need to add `-DOPTION_REAL_BUILD_EXAMPLES=ON` to the end of your `cmake` command. 8 | 9 | Then you need to build generated project. 10 | 11 | ### OR 12 | Use CLion! 13 | 14 | ### MSVC 15 | Generate project files with `"Visual Studio 16 2019"` generator, open generated `.sln` file in Visual Studio and run build. 16 | 17 | ### Other 18 | Other build types are not tested for now so you can learn how to build CMake projects by yourself(example: [here](https://cliutils.gitlab.io/modern-cmake/chapters/intro/running.html)). 19 | -------------------------------------------------------------------------------- /cmake/assets.cmake: -------------------------------------------------------------------------------- 1 | macro (add_assets_dir DIRNAME) 2 | file(COPY "${DIRNAME}" DESTINATION "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}") 3 | endmacro () -------------------------------------------------------------------------------- /cmake/build.cmake: -------------------------------------------------------------------------------- 1 | function(build_log MSG SEVERITY) 2 | # Severity: ALWAYS, ... 3 | if (OPTION_REAL_DEBUG_CMAKE OR SEVERITY STREQUAL "ALWAYS") 4 | message(STATUS "${MSG}") 5 | endif () 6 | endfunction() 7 | 8 | ### Multi-config generator detection 9 | get_property(REAL_GENERATOR_IS_MULTI_CONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) 10 | if (REAL_GENERATOR_IS_MULTI_CONFIG) 11 | message(STATUS "Current CMake generator is multi-config generator(${CMAKE_GENERATOR})") 12 | message(STATUS "CMAKE_BUILD_TYPE variable is ignored!") 13 | else () 14 | message(STATUS "Current CMake generator is single-config generator(${CMAKE_GENERATOR})") 15 | endif () 16 | 17 | ### Updating Build types 18 | message(STATUS "Updating Build types...") 19 | set(CUSTOM_BUILD_TYPES "Debug;Release;RelWithDebInfo") 20 | if (REAL_GENERATOR_IS_MULTI_CONFIG) 21 | foreach (BUILD_TYPE IN LISTS CUSTOM_BUILD_TYPES) 22 | if (NOT "${BUILD_TYPE}" IN_LIST CMAKE_CONFIGURATION_TYPES) 23 | set(CMAKE_CONFIGURATION_TYPES ${CUSTOM_BUILD_TYPES} CACHE STRING "" FORCE) 24 | endif () 25 | endforeach () 26 | else () 27 | set_property(CACHE CMAKE_BUILD_TYPE PROPERTY 28 | STRINGS "${CUSTOM_BUILD_TYPES}") 29 | 30 | if (NOT CMAKE_BUILD_TYPE) 31 | set(CMAKE_BUILD_TYPE Debug CACHE STRING "" FORCE) 32 | elseif (NOT CMAKE_BUILD_TYPE IN_LIST CUSTOM_BUILD_TYPES) 33 | message(FATAL_ERROR "Invalid build type: ${CMAKE_BUILD_TYPE} (Supported: ${CUSTOM_BUILD_TYPES})") 34 | endif () 35 | endif () 36 | 37 | ### Build Directories 38 | message(STATUS "Updating build directories...") 39 | set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib") 40 | set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/int") 41 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin") 42 | 43 | if (REAL_GENERATOR_IS_MULTI_CONFIG) 44 | foreach (OUTPUT_CONFIG IN LISTS CMAKE_CONFIGURATION_TYPES) 45 | string(TOUPPER "${OUTPUT_CONFIG}" OUTPUT_CONFIG_UPPER) 46 | set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_${OUTPUT_CONFIG_UPPER} "${CMAKE_BINARY_DIR}/lib") 47 | set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${OUTPUT_CONFIG_UPPER} "${CMAKE_BINARY_DIR}/int") 48 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_${OUTPUT_CONFIG_UPPER} "${CMAKE_BINARY_DIR}/bin") 49 | endforeach () 50 | endif () 51 | 52 | include(compilerOptions) 53 | 54 | foreach (BUILD_TYPE IN LISTS CUSTOM_BUILD_TYPES) 55 | string(TOUPPER "${BUILD_TYPE}" BUILD_TYPE_UPPERCASE) 56 | # set(CMAKE_SHARED_LINKER_FLAGS_${BUILD_TYPE_UPPERCASE} ${DEFAULT_LINKER_OPTIONS}) 57 | # set(CMAKE_MODULE_LINKER_FLAGS_${BUILD_TYPE_UPPERCASE} ${DEFAULT_LINKER_OPTIONS}) 58 | # set(CMAKE_EXE_LINKER_FLAGS_${BUILD_TYPE_UPPERCASE} ${DEFAULT_LINKER_OPTIONS}) 59 | endforeach () -------------------------------------------------------------------------------- /cmake/compilerOptions.cmake: -------------------------------------------------------------------------------- 1 | ### Architecture setup 2 | 3 | # Determine architecture (32/64 bit) 4 | set(X64 OFF) 5 | if (CMAKE_SIZEOF_VOID_P EQUAL 8) 6 | set(X64 ON) 7 | endif () 8 | 9 | set(DEFAULT_COMPILE_DEFINITIONS) 10 | set(DEFAULT_COMPILE_OPTIONS) 11 | set(DEFAULT_LINKER_OPTIONS) 12 | 13 | ### MSVC TODO: modify options 14 | if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "MSVC") 15 | set(DEFAULT_COMPILE_DEFINITIONS ${DEFAULT_COMPILE_DEFINITIONS} 16 | _SCL_SECURE_NO_WARNINGS # Calling any one of the potentially unsafe methods in the Standard C++ Library 17 | _CRT_SECURE_NO_WARNINGS # Calling any one of the potentially unsafe methods in the CRT Library 18 | ) 19 | 20 | set(DEFAULT_COMPILE_OPTIONS ${DEFAULT_COMPILE_OPTIONS} 21 | PRIVATE 22 | /MP # -> build with multiple processes 23 | /W4 # -> warning level 4 24 | # /WX # -> treat warnings as errors 25 | 26 | /wd4251 # -> disable warning: 'identifier': class 'type' needs to have dll-interface to be used by clients of class 'type2' 27 | /wd4592 # -> disable warning: 'identifier': symbol will be dynamically initialized (implementation limitation) 28 | # /wd4201 # -> disable warning: nonstandard extension used: nameless struct/union (caused by GLM) 29 | # /wd4127 # -> disable warning: conditional expression is constant (caused by Qt) 30 | 31 | PUBLIC 32 | $<$>: 33 | /Zi 34 | > 35 | 36 | $<$: 37 | /Gw # -> whole program global optimization 38 | /GS- # -> buffer security check: no 39 | /GL # -> whole program optimization: enable link-time code generation (disables Zi) 40 | /GF # -> enable string pooling 41 | > 42 | ) 43 | 44 | set(DEFAULT_LINKER_OPTIONS ${DEFAULT_LINKER_OPTIONS} 45 | PRIVATE 46 | 47 | PUBLIC 48 | $<$>: 49 | /DEBUG 50 | > 51 | 52 | /INCREMENTAL 53 | ) 54 | endif () 55 | 56 | ### GCC and Clang compiler options TODO: modify options 57 | if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU" OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") 58 | set(DEFAULT_COMPILE_DEFINITIONS ${DEFAULT_COMPILE_DEFINITIONS}) 59 | 60 | set(DEFAULT_COMPILE_OPTIONS ${DEFAULT_COMPILE_OPTIONS} 61 | PRIVATE 62 | -Wall 63 | -Wextra 64 | -Wunused 65 | 66 | -Wreorder 67 | -Wignored-qualifiers 68 | -Wmissing-braces 69 | -Wreturn-type 70 | -Wswitch 71 | -Wswitch-default 72 | -Wuninitialized 73 | -Wmissing-field-initializers 74 | 75 | $<$: 76 | -Wmaybe-uninitialized 77 | 78 | $<$,4.8>: 79 | -Wpedantic 80 | 81 | -Wreturn-local-addr 82 | > 83 | > 84 | 85 | $<$: 86 | -Wpedantic 87 | 88 | # -Wreturn-stack-address # gives false positives 89 | > 90 | 91 | $<$: 92 | -fprofile-arcs 93 | -ftest-coverage 94 | > 95 | 96 | PUBLIC 97 | 98 | $<$: 99 | -pthread 100 | > 101 | 102 | # Required for CMake < 3.1; should be removed if minimum required CMake version is raised. 103 | $<$: 104 | -std=c++11 105 | > 106 | ) 107 | 108 | set(DEFAULT_LINKER_OPTIONS ${DEFAULT_LINKER_OPTIONS}) 109 | endif () 110 | 111 | # Use pthreads on mingw and linux 112 | if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU" OR "${CMAKE_SYSTEM_NAME}" MATCHES "Linux") 113 | set(DEFAULT_LINKER_OPTIONS 114 | ${DEFAULT_LINKER_OPTIONS} 115 | -pthread 116 | ) 117 | 118 | if (${OPTION_REAL_ENABLE_COVERAGE}) 119 | set(DEFAULT_LINKER_OPTIONS 120 | ${DEFAULT_LINKER_OPTIONS} 121 | -fprofile-arcs 122 | -ftest-coverage 123 | ) 124 | endif () 125 | endif () -------------------------------------------------------------------------------- /cmake/coverage.cmake: -------------------------------------------------------------------------------- 1 | find_program(GCOV_PATH gcov) 2 | # find_program(LCOV_PATH NAMES lcov lcov.bat lcov.exe lcov.perl) 3 | # find_program(GCOVR_PATH gcovr PATHS ${CMAKE_SOURCE_DIR}/scripts/test) 4 | # find_program(CPPFILT_PATH NAMES c++filt) 5 | 6 | include(CMakeParseArguments) 7 | 8 | if (NOT GCOV_PATH) 9 | message(FATAL_ERROR "gcov not found! Aborting...") 10 | else () 11 | message(STATUS "Found gcov: ${GCOV_PATH}") 12 | endif () 13 | 14 | if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "(Apple)?[Cc]lang") 15 | if ("${CMAKE_CXX_COMPILER_VERSION}" VERSION_LESS 3) 16 | message(FATAL_ERROR "Clang version must be 3.0.0 or greater! Aborting...") 17 | endif () 18 | elseif (NOT CMAKE_COMPILER_IS_GNUCXX) 19 | # Do something 20 | message(STATUS "Compiler is not GNUCXX") 21 | endif () 22 | 23 | set(COVERAGE_COMPILER_FLAGS "-g -fprofile-arcs -ftest-coverage" 24 | CACHE INTERNAL "") 25 | 26 | set(CMAKE_CXX_FLAGS_COVERAGE 27 | ${COVERAGE_COMPILER_FLAGS} 28 | CACHE STRING "Flags used by the C++ compiler during coverage builds." 29 | FORCE) 30 | set(CMAKE_C_FLAGS_COVERAGE 31 | ${COVERAGE_COMPILER_FLAGS} 32 | CACHE STRING "Flags used by the C compiler during coverage builds." 33 | FORCE) 34 | set(CMAKE_EXE_LINKER_FLAGS_COVERAGE 35 | "" 36 | CACHE STRING "Flags used for linking binaries during coverage builds." 37 | FORCE) 38 | set(CMAKE_SHARED_LINKER_FLAGS_COVERAGE 39 | "" 40 | CACHE STRING "Flags used by the shared libraries linker during coverage builds." 41 | FORCE) 42 | mark_as_advanced( 43 | CMAKE_CXX_FLAGS_COVERAGE 44 | CMAKE_C_FLAGS_COVERAGE 45 | CMAKE_EXE_LINKER_FLAGS_COVERAGE 46 | CMAKE_SHARED_LINKER_FLAGS_COVERAGE 47 | ) 48 | 49 | if (NOT CMAKE_BUILD_TYPE STREQUAL "Debug" AND NOT REAL_GENERATOR_IS_MULTI_CONFIG) 50 | message(WARNING "Code coverage results with an optimised (non-Debug) build may be misleading") 51 | endif () 52 | 53 | if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_Fortran_COMPILER_ID STREQUAL "GNU") 54 | link_libraries(gcov) 55 | endif () 56 | 57 | function (append_coverage_compiler_flags) 58 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CMAKE_C_FLAGS_COVERAGE}" PARENT_SCOPE) 59 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_COVERAGE}" PARENT_SCOPE) 60 | message(STATUS "Appending code coverage compiler flags: ${COVERAGE_COMPILER_FLAGS}") 61 | endfunction () -------------------------------------------------------------------------------- /cmake/rdoc.cmake: -------------------------------------------------------------------------------- 1 | ### Functions 2 | 3 | # Generates renderdoc settings file from given template 4 | function(generate_rdoc_settings_from TEMPLATE_FILENAME TARGET_NAME RDOC_CONFIG_OUTFOLDER) 5 | message(STATUS "Generating RenderDoc Settings for ${TARGET_NAME}") 6 | 7 | ## RenderDoc 8 | set(RDOC_WORKING_DIR "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}") 9 | set(RDOC_TARGET_FILE "$") 10 | 11 | set(RDOC_CONFIG_OUTFILE "${RDOC_CONFIG_OUTFOLDER}/rdoc/settings.cap") 12 | 13 | configure_file("${CMAKE_SOURCE_DIR}/rdoc/settings.cap" "${RDOC_CONFIG_OUTFILE}") 14 | 15 | if (REAL_GENERATOR_IS_MULTI_CONFIG) 16 | file( 17 | GENERATE 18 | OUTPUT "${RDOC_CONFIG_OUTFILE}.$" 19 | INPUT "${RDOC_CONFIG_OUTFILE}" 20 | ) 21 | else () 22 | file( 23 | GENERATE 24 | OUTPUT "${RDOC_CONFIG_OUTFILE}" 25 | INPUT "${RDOC_CONFIG_OUTFILE}" 26 | ) 27 | endif () 28 | 29 | endfunction() -------------------------------------------------------------------------------- /cmake/sanitizers.cmake: -------------------------------------------------------------------------------- 1 | set(WANTED_SANITIZE_THREAD ${SANITIZE_THREAD}) 2 | set(WANTED_SANITIZE_UNDEFINED ${SANITIZE_UNDEFINED}) 3 | set(WANTED_SANITIZE_MEMORY ${SANITIZE_MEMORY}) 4 | set(WANTED_SANITIZE_ADDRESS ${SANITIZE_ADDRESS}) 5 | 6 | function (check_sanitizer NAME PREFIX) 7 | if (${WANTED_SANITIZE_${NAME}}) 8 | if ("${${PREFIX}_${CMAKE_C_COMPILER_ID}_FLAGS}" STREQUAL "") 9 | message(FATAL_ERROR ${NAME} " sanitizer is NOT available") 10 | else () 11 | message(STATUS ${NAME} " sanitizer is available") 12 | endif () 13 | endif () 14 | endfunction () 15 | 16 | check_sanitizer(THREAD TSan) 17 | check_sanitizer(UNDEFINED UBSan) 18 | check_sanitizer(MEMORY MSan) 19 | check_sanitizer(ADDRESS ASan) 20 | 21 | # TODO: figure out what to do with sanitizers! 22 | -------------------------------------------------------------------------------- /cmake/shaders.cmake: -------------------------------------------------------------------------------- 1 | function (add_shaders TARGET_NAME) 2 | set(GENERATE_SHADERS_TARGET_NAME "${TARGET_NAME}-generate-shaders") 3 | set(SHADERS) 4 | set(SHADERS_OUTDIR "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/shaders") 5 | 6 | add_custom_command( 7 | OUTPUT "${SHADERS_OUTDIR}" 8 | COMMAND ${CMAKE_COMMAND} -E make_directory "${SHADERS_OUTDIR}" 9 | COMMENT "Creating shaders directory in ${SHADERS_OUTDIR}" 10 | 11 | VERBATIM 12 | ) 13 | 14 | foreach (SHADER_SOURCE IN LISTS ARGN) 15 | get_filename_component(SHADER_NAME "${SHADER_SOURCE}" NAME) 16 | set(SHADER_OUTFILE "${SHADERS_OUTDIR}/${SHADER_NAME}") 17 | 18 | message(STATUS "Adding shaders ${SHADER_SOURCE} to ${TARGET_NAME}") 19 | list(APPEND SHADERS "${SHADER_OUTFILE}") 20 | 21 | add_custom_command( 22 | OUTPUT "${SHADER_OUTFILE}" 23 | DEPENDS ${SHADERS_OUTDIR} ${SHADER_SOURCE} 24 | COMMAND ${CMAKE_COMMAND} -E copy ${SHADER_SOURCE} ${SHADERS_OUTDIR} 25 | 26 | 27 | COMMENT "Moving ${SHADER_SOURCE} to runtime directory..." 28 | 29 | VERBATIM 30 | ) 31 | endforeach () 32 | 33 | add_custom_target( 34 | ${GENERATE_SHADERS_TARGET_NAME} ALL 35 | DEPENDS ${SHADERS} 36 | ) 37 | add_dependencies(${TARGET_NAME} ${GENERATE_SHADERS_TARGET_NAME}) 38 | endfunction () 39 | -------------------------------------------------------------------------------- /engine/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | message(STATUS "Configuring ${META_REAL_NAME_VERSION}") 2 | 3 | # Target 4 | add_library( 5 | ${REAL_LIBRARY_TARGET_NAME} 6 | STATIC # It is necessary 7 | 8 | ### Headers 9 | # util 10 | include/real/util/singleton.hpp 11 | # Core 12 | include/real/real.hpp 13 | include/real/pch.hpp 14 | include/real/assert.hpp 15 | include/real/core.hpp 16 | include/real/application.hpp 17 | include/real/logger.hpp 18 | include/real/layer.hpp 19 | include/real/layer_stack.hpp 20 | include/real/input.hpp 21 | include/real/window.hpp 22 | include/real/event.hpp 23 | include/real/time.hpp 24 | include/real/transform.hpp 25 | # Layers 26 | include/real/layer/base_layer.hpp 27 | include/real/layer/imgui_layer.hpp 28 | # Window 29 | include/real/window/base_window.hpp 30 | # Input 31 | include/real/keycode.hpp 32 | include/real/input/base_input.hpp 33 | # Events 34 | include/real/event/base_event.hpp 35 | include/real/event/key_event.hpp 36 | include/real/event/mouse_event.hpp 37 | include/real/event/window_event.hpp 38 | # Renderer 39 | include/real/renderer.hpp 40 | include/real/renderer/base_rendering_context.hpp 41 | include/real/renderer/base_renderer.hpp 42 | include/real/renderer/render_command.hpp 43 | include/real/renderer/renderer_api.hpp 44 | include/real/renderer/base_shader.hpp 45 | include/real/renderer/base_texture.hpp 46 | include/real/renderer/buffer_layout.hpp 47 | include/real/renderer/buffer_vertex.hpp 48 | include/real/renderer/buffer_index.hpp 49 | include/real/renderer/array_vertex.hpp 50 | include/real/renderer/camera.hpp 51 | include/real/renderer/light.hpp 52 | include/real/renderer/material.hpp 53 | include/real/renderer/common.hpp 54 | # Time 55 | include/real/time/timestep.hpp 56 | ## Api 57 | ## GL 58 | include/real/api/gl/gl_rendering_context.hpp 59 | include/real/api/gl/gl_renderer_api.hpp 60 | include/real/api/gl/gl_buffer_vertex.hpp 61 | include/real/api/gl/gl_buffer_index.hpp 62 | include/real/api/gl/gl_array_vertex.hpp 63 | include/real/api/gl/gl_conversions.hpp 64 | include/real/api/gl/gl_shader.hpp 65 | include/real/api/gl/gl_texture.hpp 66 | 67 | ### Sources 68 | # Core 69 | src/application.cpp 70 | src/base_window.cpp 71 | src/layer_stack.cpp 72 | src/logger.cpp 73 | # Layers 74 | src/base_layer.cpp 75 | src/layer/imgui_layer.cpp 76 | # Input 77 | src/base_input.cpp 78 | # Renderer 79 | src/renderer/base_rendering_context.cpp 80 | src/renderer/base_renderer.cpp 81 | src/renderer/renderer_api.cpp 82 | src/renderer/buffer_vertex.cpp 83 | src/renderer/buffer_index.cpp 84 | src/renderer/buffer_layout.cpp 85 | src/renderer/array_vertex.cpp 86 | src/renderer/base_shader.cpp 87 | src/renderer/base_texture.cpp 88 | src/renderer/camera.cpp 89 | ## Api 90 | ## GL 91 | # Imgui 92 | src/api/gl/imgui_build.cpp 93 | # Renderer 94 | src/api/gl/gl_rendering_context.cpp 95 | src/api/gl/gl_renderer_api.cpp 96 | src/api/gl/gl_shader.cpp 97 | src/api/gl/gl_texture.cpp 98 | src/api/gl/gl_buffer_vertex.cpp 99 | src/api/gl/gl_buffer_index.cpp 100 | src/api/gl/gl_array_vertex.cpp 101 | ## Other 102 | src/stb.cpp 103 | ) 104 | 105 | target_precompile_headers( 106 | ${REAL_LIBRARY_TARGET_NAME} 107 | PRIVATE 108 | "include/real/pch.hpp" 109 | ) 110 | 111 | 112 | # Platform-dependent sources 113 | if (WIN32) 114 | target_sources( 115 | ${REAL_LIBRARY_TARGET_NAME} 116 | PUBLIC 117 | # Window 118 | include/real/platform/windows/windows_window.hpp 119 | # Input 120 | include/real/platform/windows/windows_input.hpp 121 | # Time 122 | include/real/platform/windows/windows_time.hpp 123 | PRIVATE 124 | # Window 125 | src/platform/windows/windows_window.cpp 126 | # Input 127 | src/platform/windows/windows_input.cpp 128 | # Time 129 | src/platform/windows/windows_time.cpp 130 | ) 131 | 132 | target_precompile_headers( 133 | ${REAL_LIBRARY_TARGET_NAME} 134 | PRIVATE 135 | 136 | # Platform-dependent headers 137 | 138 | ) 139 | endif () 140 | 141 | # Shaders 142 | add_shaders( 143 | ${REAL_LIBRARY_TARGET_NAME} 144 | "${CMAKE_CURRENT_SOURCE_DIR}/include/real/renderer/shaders/base.glsl" 145 | "${CMAKE_CURRENT_SOURCE_DIR}/include/real/renderer/shaders/material.glsl" 146 | "${CMAKE_CURRENT_SOURCE_DIR}/include/real/renderer/shaders/tex.glsl" 147 | ) 148 | 149 | # Properties 150 | target_include_directories( 151 | ${REAL_LIBRARY_TARGET_NAME} 152 | PUBLIC 153 | "include" 154 | "${CMAKE_CURRENT_BINARY_DIR}" 155 | PRIVATE 156 | "src" 157 | ) 158 | 159 | set_target_properties( 160 | ${REAL_LIBRARY_TARGET_NAME} PROPERTIES 161 | 162 | # Folder 163 | FOLDER ${META_REAL_PROJECT_FULL_NAME}/engine 164 | 165 | # Version 166 | VERSION ${META_REAL_VERSION} 167 | SOVERSION ${META_REAL_VERSION_MAJOR} 168 | 169 | # C++ 170 | CXX_STANDARD ${CXX_STANDARD_DEFAULT} 171 | CXX_STANDARD_REQUIRED ON 172 | CXX_EXTENSIONS OFF 173 | 174 | # C 175 | C_STANDARD ${C_STANDARD_DEFAULT} 176 | C_STANDARD_REQUIRED ON 177 | C_EXTENSIONS OFF 178 | 179 | # Other 180 | VS_DEBUGGER_WORKING_DIRECTORY "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}" 181 | ) 182 | 183 | target_compile_definitions( 184 | ${REAL_LIBRARY_TARGET_NAME} 185 | PRIVATE 186 | 187 | PUBLIC 188 | # Build type macros 189 | $<$:REAL_DEBUG> 190 | $<$:REAL_RELEASE> 191 | $<$:REAL_PROFILE> 192 | # Platform macros 193 | $<$:REAL_PLATFORM_WINDOWS> 194 | INTERFACE 195 | REAL_CLIENT 196 | ) 197 | 198 | target_compile_options( 199 | ${REAL_LIBRARY_TARGET_NAME} 200 | PUBLIC 201 | ${DEFAULT_COMPILE_OPTIONS} 202 | ) 203 | 204 | target_link_options( 205 | ${REAL_LIBRARY_TARGET_NAME} 206 | PUBLIC 207 | # ${DEFAULT_LINKER_OPTIONS} 208 | ) 209 | 210 | set_target_properties( 211 | ${REAL_LIBRARY_TARGET_NAME} PROPERTIES 212 | 213 | VISIBILITY_INLINES_HIDDEN YES 214 | CXX_VISIBILITY_PRESET hidden 215 | C_VISIBILITY_PRESET hidden 216 | ASM_VISIBILITY_PRESET hidden 217 | ) 218 | 219 | # Utility 220 | # Generated Files 221 | # write_compiler_detection_header( 222 | # FILE "${META_REAL_PROJECT_NAME}/core-compiler.hpp" 223 | # PREFIX ${META_REAL_PROJECT_NAME_PREFIX} 224 | # COMPILERS Clang GNU MSVC 225 | # FEATURES cxx_override 226 | # ) 227 | 228 | generate_export_header( 229 | ${REAL_LIBRARY_TARGET_NAME} 230 | BASE_NAME "${META_REAL_PROJECT_NAME_PREFIX}" 231 | PREFIX_NAME "${META_REAL_PROJECT_NAME_PREFIX}_" 232 | INCLUDE_GUARD_NAME "${META_REAL_PROJECT_NAME_PREFIX}_CORE_COMPILER" 233 | EXPORT_MACRO_NAME "API" 234 | EXPORT_FILE_NAME "${META_REAL_PROJECT_NAME}/core-export.hpp" 235 | NO_EXPORT_MACRO_NAME "NO_EXPORT" 236 | DEPRECATED_MACRO_NAME "DEPRECATED" 237 | INCLUDE_GUARD_NAME "${META_REAL_PROJECT_NAME_PREFIX}_CORE_API" 238 | STATIC_DEFINE "STATIC" 239 | NO_DEPRECATED_MACRO_NAME "NO_DEPRECATED" 240 | 241 | # DEFINE_NO_DEPRECATED 242 | ) 243 | 244 | # Custom commands 245 | set(LOGS_DIR "${CMAKE_CURRENT_BINARY_DIR}/logs") 246 | set(LOG_EXPORTS_FILE "${LOGS_DIR}/exports.txt") 247 | 248 | file(MAKE_DIRECTORY "${LOGS_DIR}") 249 | 250 | # TODO: add support for other platforms 251 | if (WIN32 AND MSVC) 252 | # Save DLL exports 253 | add_custom_command( 254 | TARGET ${REAL_LIBRARY_TARGET_NAME} POST_BUILD 255 | WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" 256 | COMMENT "Saving DLL file exports" 257 | BYPRODUCTS "${LOG_EXPORTS_FILE}" 258 | 259 | COMMAND dumpbin /exports $ > "${LOG_EXPORTS_FILE}" 260 | 261 | VERBATIM 262 | ) 263 | endif () -------------------------------------------------------------------------------- /engine/include/real/api/gl/gl_array_vertex.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 udv. All rights reserved. 2 | 3 | #ifndef REAL_GL_ARRAY_VERTEX 4 | #define REAL_GL_ARRAY_VERTEX 5 | 6 | #include "real/core.hpp" 7 | #include "real/renderer/array_vertex.hpp" 8 | 9 | namespace Real 10 | { 11 | class REAL_API GLVertexArray : public VertexArray 12 | { 13 | public: 14 | GLVertexArray(); 15 | ~GLVertexArray() override; 16 | 17 | [[nodiscard]] virtual const std::vector>& VertexBuffers() const override 18 | { return vertexBuffers; }; 19 | [[nodiscard]] virtual const std::vector>& IndexBuffers() const override 20 | { return indexBuffers; }; 21 | 22 | virtual void AddVertexBuffer( 23 | const Real::Reference& buffer) override; 24 | virtual void AddIndexBuffer( 25 | const Real::Reference& buffer) override; 26 | 27 | virtual int32_t Count() const override; 28 | 29 | virtual void Bind() const override; 30 | virtual void Unbind() const override; 31 | private: 32 | renderer_id_t rendererId; 33 | uint32_t count; 34 | 35 | std::vector> vertexBuffers; 36 | std::vector> indexBuffers; 37 | }; 38 | } 39 | 40 | #endif //REAL_GL_ARRAY_VERTEX 41 | -------------------------------------------------------------------------------- /engine/include/real/api/gl/gl_buffer_index.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 udv. All rights reserved. 2 | 3 | #ifndef REAL_GL_BUFFER_INDEX 4 | #define REAL_GL_BUFFER_INDEX 5 | 6 | #include "real/core.hpp" 7 | #include "real/renderer/buffer_index.hpp" 8 | 9 | namespace Real { 10 | class REAL_API GLIndexBuffer : public IndexBuffer { 11 | public: 12 | GLIndexBuffer(uint32_t *data, uint32_t size); 13 | ~GLIndexBuffer() override; 14 | 15 | void Bind() const override; 16 | void Unbind() const override; 17 | 18 | [[nodiscard]] uint32_t Count() const override; 19 | private: 20 | renderer_id_t rendererId; 21 | uint32_t count; 22 | }; 23 | } 24 | 25 | #endif //REAL_GL_BUFFER_INDEX 26 | -------------------------------------------------------------------------------- /engine/include/real/api/gl/gl_buffer_vertex.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 udv. All rights reserved. 2 | 3 | #ifndef REAL_GL_BUFFER_VERTEX 4 | #define REAL_GL_BUFFER_VERTEX 5 | 6 | #include 7 | 8 | #include "real/core.hpp" 9 | #include "real/renderer/buffer_vertex.hpp" 10 | 11 | namespace Real 12 | { 13 | class REAL_API GLVertexBuffer : public VertexBuffer 14 | { 15 | public: 16 | GLVertexBuffer(float* data, uint32_t size); 17 | ~GLVertexBuffer() override; 18 | 19 | [[nodiscard]] const BufferLayout& Layout() const override 20 | { return bufferLayout; }; 21 | 22 | void Layout(std::initializer_list attributes) override; 23 | 24 | void Bind() const override; 25 | void Unbind() const override; 26 | private: 27 | renderer_id_t rendererId; 28 | BufferLayout bufferLayout; 29 | }; 30 | } 31 | 32 | #endif //REAL_GL_BUFFER_VERTEX 33 | -------------------------------------------------------------------------------- /engine/include/real/api/gl/gl_conversions.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 udv. All rights reserved. 2 | 3 | #ifndef REAL_GL_CONVERSIONS 4 | #define REAL_GL_CONVERSIONS 5 | 6 | #include "real/core.hpp" 7 | #include "real/renderer/common.hpp" 8 | #include "real/api/gl/gl_headers.hpp" 9 | #include "real/logger.hpp" 10 | 11 | namespace Real 12 | { 13 | constexpr GLuint GLTypeFrom(shader_data_t type) noexcept 14 | { 15 | // @formatter:off 16 | switch (type) { 17 | case shader_data_t::vec : return GL_FLOAT; 18 | case shader_data_t::vec2 : return GL_FLOAT; 19 | case shader_data_t::vec3 : return GL_FLOAT; 20 | case shader_data_t::vec4 : return GL_FLOAT; 21 | case shader_data_t::mat3 : return GL_FLOAT; 22 | case shader_data_t::mat4 : return GL_FLOAT; 23 | case shader_data_t::ivec : return GL_INT; 24 | case shader_data_t::ivec2 : return GL_INT; 25 | case shader_data_t::ivec3 : return GL_INT; 26 | case shader_data_t::ivec4 : return GL_INT; 27 | case shader_data_t::bvec : return GL_BOOL; 28 | case shader_data_t::bvec2 : return GL_BOOL; 29 | case shader_data_t::bvec3 : return GL_BOOL; 30 | case shader_data_t::bvec4 : return GL_BOOL; 31 | 32 | default: 33 | case shader_data_t::none: REAL_CORE_ERROR("Unsupported data type: {}!", static_cast(type)); 34 | return 0; 35 | } 36 | // @formatter:on 37 | } 38 | 39 | inline GLenum GLShaderTypeFrom(std::string_view type) noexcept 40 | { 41 | if (type == "vertex") 42 | { 43 | return GL_VERTEX_SHADER; 44 | } 45 | 46 | if (type == "fragment") 47 | { 48 | return GL_FRAGMENT_SHADER; 49 | } 50 | 51 | REAL_CORE_ERROR("Unknown shader type {0}", type); 52 | return 0; 53 | } 54 | } 55 | 56 | #endif //REAL_GL_CONVERSIONS 57 | -------------------------------------------------------------------------------- /engine/include/real/api/gl/gl_headers.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 udv. All rights reserved. 2 | 3 | #ifndef REAL_GL_HEADERS 4 | #define REAL_GL_HEADERS 5 | 6 | #include 7 | #include 8 | 9 | #endif //REAL_GL_HEADERS 10 | -------------------------------------------------------------------------------- /engine/include/real/api/gl/gl_renderer_api.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 udv. All rights reserved. 2 | 3 | #ifndef REAL_GL_RENDERER_API 4 | #define REAL_GL_RENDERER_API 5 | 6 | #include "real/core.hpp" 7 | #include "real/renderer/renderer_api.hpp" 8 | #include "real/renderer/array_vertex.hpp" 9 | 10 | namespace Real 11 | { 12 | class REAL_API GLRendererApi : public RendererAPI 13 | { 14 | public: 15 | virtual void Init() override; 16 | void ClearColor(glm::fvec4 color) override; 17 | void Clear(int32_t bits) override; 18 | void DrawIndexed(const Real::Reference& vao) override; 19 | [[nodiscard]] API Value() const override; 20 | private: 21 | [[nodiscard]] int32_t DefaultClearBits() const noexcept override; 22 | }; 23 | } 24 | 25 | #endif //REAL_GL_RENDERER_API 26 | -------------------------------------------------------------------------------- /engine/include/real/api/gl/gl_rendering_context.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 udv. All rights reserved. 2 | 3 | #ifndef REAL_GL_RENDERING_CONTEXT 4 | #define REAL_GL_RENDERING_CONTEXT 5 | 6 | #include "real/renderer/base_rendering_context.hpp" 7 | 8 | // Avoid including glfw 9 | struct GLFWwindow; 10 | 11 | namespace Real 12 | { 13 | class REAL_API GLRenderingContext : public RenderingContext 14 | { 15 | public: 16 | explicit GLRenderingContext(GLFWwindow* windowHandle); 17 | virtual ~GLRenderingContext(); 18 | 19 | void Init() override; 20 | void SwapBuffers() override; 21 | void VSync(bool enabled) override; 22 | private: 23 | GLFWwindow* glfwWindowHandle; 24 | }; 25 | } 26 | 27 | #endif //REAL_GL_RENDERING_CONTEXT 28 | -------------------------------------------------------------------------------- /engine/include/real/api/gl/gl_shader.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 udv. All rights reserved. 2 | 3 | #ifndef REAL_GL_SHADER 4 | #define REAL_GL_SHADER 5 | 6 | #include 7 | 8 | #include "real/core.hpp" 9 | #include "real/renderer/base_shader.hpp" 10 | #include "real/api/gl/gl_headers.hpp" 11 | 12 | #define GL_SHADERS_MAX_COUNT SHADERS_MAX_COUNT 13 | #define GL_SHADERS_AVG_COUNT SHADERS_AVG_COUNT 14 | 15 | namespace Real 16 | { 17 | class REAL_API GLShader : public Real::Shader 18 | { 19 | public: 20 | GLShader(const std::string& filename); 21 | ~GLShader() override; 22 | 23 | // region Uniforms 24 | // Floats 25 | void UniformFloat(const std::string& name, glm::f32 value) override; 26 | void UniformFloat(const std::string& name, const glm::fvec2& value) override; 27 | void UniformFloat(const std::string& name, const glm::fvec3& value) override; 28 | void UniformFloat(const std::string& name, const glm::fvec4& value) override; 29 | 30 | // Matrices 31 | void UniformMatrix(const std::string& name, const glm::fmat3& matrix) override; 32 | void UniformMatrix(const std::string& name, const glm::fmat4& matrix) override; 33 | 34 | // Ints 35 | void UniformInt(const std::string& name, glm::int32 value) override; 36 | void UniformInt(const std::string& name, const glm::ivec2& value) override; 37 | void UniformInt(const std::string& name, const glm::ivec3& value) override; 38 | void UniformInt(const std::string& name, const glm::ivec4& value) override; 39 | // endregion 40 | 41 | const std::string& Name() const override 42 | { return this->shaderName; } 43 | void Name(std::string string) override 44 | { this->shaderName = string; } 45 | 46 | void Bind() const override; 47 | void Unbind() const override; 48 | private: 49 | //region Helpers 50 | static std::string ReadFile(const std::string& filepath); 51 | 52 | void Preprocess(std::string& source) const; 53 | std::unordered_map Split(const std::string& source) const; 54 | void Compile(const std::unordered_map& shader_srcs); 55 | void Link() const; 56 | 57 | static void CheckHandleProgramError(GLuint id, GLenum action); 58 | static void CheckHandleShaderError(GLuint id, GLenum action); 59 | //endregion 60 | 61 | inline GLint LocationOf(const std::string& name) const; 62 | private: 63 | GLuint programId; 64 | std::string shaderName; 65 | 66 | size_t count = 0; 67 | std::array shaders; 68 | 69 | mutable std::unordered_map uniformLocationsCache; 70 | }; 71 | } 72 | 73 | #endif //REAL_GL_SHADER 74 | -------------------------------------------------------------------------------- /engine/include/real/api/gl/gl_texture.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 udv. All rights reserved. 2 | 3 | #ifndef REAL_GL_TEXTURE 4 | #define REAL_GL_TEXTURE 5 | 6 | #include "real/core.hpp" 7 | #include "real/renderer/base_texture.hpp" 8 | 9 | namespace Real 10 | { 11 | 12 | class REAL_API GLTexture2D : public Real::Texture2D 13 | { 14 | public: 15 | GLTexture2D(const std::string& path); 16 | ~GLTexture2D(); 17 | 18 | virtual void Init() override; 19 | 20 | virtual texture_dimension_t Width() const override 21 | { return width; }; 22 | virtual texture_dimension_t Height() const override 23 | { return height; }; 24 | 25 | virtual void Bind(uint32_t slot = 0) const override; 26 | private: 27 | std::string path; 28 | 29 | texture_dimension_t width; 30 | texture_dimension_t height; 31 | 32 | renderer_id_t rendererId; 33 | }; 34 | } 35 | 36 | #endif //REAL_GL_TEXTURE 37 | -------------------------------------------------------------------------------- /engine/include/real/application.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 udv. All rights reserved. 2 | 3 | #ifndef REAL_APPLICATION 4 | #define REAL_APPLICATION 5 | 6 | #include 7 | 8 | #include "real/event.hpp" 9 | #include "real/core.hpp" 10 | #include "real/window.hpp" 11 | #include "real/input.hpp" 12 | #include "real/layer_stack.hpp" 13 | #include "real/renderer.hpp" 14 | #include "real/time.hpp" 15 | #include "real/util/singleton.hpp" 16 | 17 | namespace Real 18 | { 19 | class REAL_API SINGLETON(Application) 20 | { 21 | public: 22 | explicit Application(std::string name = REAL_APPLICATION_DEFAULT_NAME); 23 | virtual ~Application(); 24 | 25 | [[nodiscard]] LayerStack& Layers() noexcept 26 | { return this->layerStack; } 27 | [[nodiscard]] Window& Window() const noexcept 28 | { return *(this->window); } 29 | 30 | double Time() const; 31 | void Init(); 32 | void Run(); 33 | 34 | void PushLayer(Layer* layer); 35 | void PushOverlay(Layer* layer); 36 | protected: 37 | virtual void Update(Timestep ts); 38 | virtual void OnEvent(Event& e); 39 | private: 40 | void OnWindowClose(WindowClosedEvent& event); 41 | private: 42 | ImGUILayer* imGUILayer; 43 | 44 | std::string name; 45 | 46 | Real::Scope window; 47 | Real::Scope input; 48 | 49 | LayerStack layerStack; 50 | 51 | bool isRunning { true }; 52 | 53 | float frametime = 0.0f; 54 | }; 55 | 56 | // To be defined in client 57 | extern Real::Scope Make(); 58 | } 59 | 60 | #endif //REAL_APPLICATION 61 | -------------------------------------------------------------------------------- /engine/include/real/assert.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 udv. All rights reserved. 2 | 3 | #ifndef REAL_ASSERT 4 | #define REAL_ASSERT 5 | 6 | #include "real/logger.hpp" 7 | 8 | #define REAL_EXPAND_MACRO(x) x 9 | #define REAL_STRINGIFY_MACRO(x) #x 10 | 11 | //region real_dbg_assert and real_debugbreak() 12 | // Thanks https://github.com/nemequ/portable-snippets/tree/master/debug-trap for knowledge 13 | #if defined(__has_builtin) && !defined(__ibmxl__) 14 | # if __has_builtin(__builtin_debugtrap) 15 | # define real_debugbreak() __builtin_debugtrap() 16 | # elif __has_builtin(__debugbreak) 17 | # define real_debugbreak() __debugbreak() 18 | # endif 19 | #endif 20 | #if !defined(real_debugbreak) 21 | # if defined(_MSC_VER) || defined(__INTEL_COMPILER) 22 | # define real_debugbreak() __debugbreak() 23 | # elif defined(__ARMCC_VERSION) 24 | # define real_debugbreak() __breakpoint(42) 25 | # elif defined(__ibmxl__) || defined(__xlC__) 26 | # include 27 | # define real_debugbreak() __trap(42) 28 | # elif defined(__DMC__) && defined(_M_IX86) 29 | static inline void real_debugbreak(void) { __asm int 3h; } 30 | # elif defined(__i386__) || defined(__x86_64__) 31 | static inline void real_debugbreak(void) { __asm__ __volatile__("int3"); } 32 | # elif defined(__thumb__) 33 | static inline void real_debugbreak(void) { __asm__ __volatile__(".inst 0xde01"); } 34 | # elif defined(__aarch64__) 35 | static inline void real_debugbreak(void) { __asm__ __volatile__(".inst 0xd4200000"); } 36 | # elif defined(__arm__) 37 | static inline void real_debugbreak(void) { __asm__ __volatile__(".inst 0xe7f001f0"); } 38 | # elif defined (__alpha__) && !defined(__osf__) 39 | static inline void real_debugbreak(void) { __asm__ __volatile__("bpt"); } 40 | # elif defined(_54_) 41 | static inline void real_debugbreak(void) { __asm__ __volatile__("ESTOP"); } 42 | # elif defined(_55_) 43 | static inline void real_debugbreak(void) { __asm__ __volatile__(";\n .if (.MNEMONIC)\n ESTOP_1\n .else\n ESTOP_1()\n .endif\n NOP"); } 44 | # elif defined(_64P_) 45 | static inline void real_debugbreak(void) { __asm__ __volatile__("SWBP 0"); } 46 | # elif defined(_6x_) 47 | static inline void real_debugbreak(void) { __asm__ __volatile__("NOP\n .word 0x10000000"); } 48 | # elif defined(__STDC_HOSTED__) && (__STDC_HOSTED__ == 0) && defined(__GNUC__) 49 | # define real_debugbreak() __builtin_trap() 50 | # else 51 | # include 52 | # if defined(SIGTRAP) 53 | # define real_debugbreak() raise(SIGTRAP) 54 | # else 55 | # define real_debugbreak() raise(SIGABRT) 56 | # endif 57 | # endif 58 | #endif 59 | 60 | #if defined(HEDLEY_LIKELY) 61 | # define REAL_DBG_LIKELY(expr) HEDLEY_LIKELY(expr) 62 | #elif defined(__GNUC__) && (__GNUC__ >= 3) 63 | # define REAL_DBG_LIKELY(expr) __builtin_expect(!!(expr), 1) 64 | #else 65 | # define REAL_DBG_LIKELY(expr) (!!(expr)) 66 | #endif 67 | 68 | #if defined(REAL_DEBUG) 69 | # define real_dbg_assert(expr) do { \ 70 | if (!REAL_DBG_LIKELY(expr)) { \ 71 | real_debugbreak(); \ 72 | } \ 73 | } while (0) 74 | # define real_msg_assert(expr, ...) do { \ 75 | if (!REAL_DBG_LIKELY(expr)) { \ 76 | REAL_EXPAND_MACRO(REAL_CORE_ERROR)(__VA_ARGS__); \ 77 | real_debugbreak(); \ 78 | } \ 79 | } while (0) 80 | #else 81 | # define real_dbg_assert(expr) 82 | # define real_msg_assert(expr, ...) 83 | #endif 84 | 85 | //endregion 86 | 87 | #endif //REAL_ASSERT 88 | -------------------------------------------------------------------------------- /engine/include/real/core.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 udv. All rights reserved. 2 | 3 | #ifndef REAL_CORE 4 | #define REAL_CORE 5 | 6 | // region Configured By CMake 7 | // Export Macros 8 | #include "real/core-export.hpp" 9 | // Compilers 10 | // #include "real/core-compiler.hpp" 11 | // endregion 12 | 13 | #define REAL_APPLICATION_DEFAULT_NAME "Real Engine" 14 | #define REAL_DEFAULT_WINDOW_HEIGHT 720 15 | #define REAL_DEFAULT_WINDOW_WIDTH 1280 16 | #define REAL_DEFAULT_WINDOW_TITLE "Real Engine" 17 | #define REAL_DEFAULT_WINDOW_V_SYNC false 18 | 19 | #include "real/pch.hpp" 20 | #include "real/assert.hpp" 21 | 22 | namespace Real 23 | { 24 | // region types 25 | // Input 26 | using keycode_t = int32_t; 27 | using mouse_btn_t = int32_t; 28 | using mouse_position_t = int32_t; 29 | 30 | // Window 31 | using window_dimension_t = int32_t; 32 | using window_position_t = int32_t; 33 | 34 | // Renderer 35 | using renderer_id_t = uint32_t; 36 | //// Textures 37 | using texture_dimension_t = uint32_t; 38 | // endregion 39 | //region util 40 | constexpr uint16_t bit(uint16_t x) 41 | { 42 | return static_cast(1u << x); 43 | } 44 | // endregion 45 | // region Pointers 46 | // TODO: make own pointers 47 | template 48 | using Reference = std::shared_ptr; 49 | 50 | template 51 | constexpr Reference MakeReference(Args&& ... args) 52 | { 53 | return std::make_shared(std::forward(args)...); 54 | } 55 | 56 | template 57 | using Scope = std::unique_ptr; 58 | 59 | template 60 | constexpr Scope MakeScope(Args&& ... args) 61 | { 62 | return std::make_unique(std::forward(args)...); 63 | } 64 | // endregion 65 | } 66 | 67 | #endif //REAL_CORE -------------------------------------------------------------------------------- /engine/include/real/event.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 udv. All rights reserved. 2 | 3 | #ifndef REAL_EVENT 4 | #define REAL_EVENT 5 | 6 | #include "real/event/base_event.hpp" 7 | #include "real/event/window_event.hpp" 8 | #include "real/event/key_event.hpp" 9 | #include "real/event/mouse_event.hpp" 10 | 11 | #endif //REAL_EVENT 12 | 13 | -------------------------------------------------------------------------------- /engine/include/real/event/base_event.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 udv. All rights reserved. 2 | 3 | #ifndef REAL_EVENT_BASE 4 | #define REAL_EVENT_BASE 5 | 6 | #include 7 | #include 8 | 9 | #include 10 | 11 | #include "real/core.hpp" 12 | 13 | namespace Real 14 | { 15 | 16 | using ev_type_t = int32_t; 17 | using ev_category_t = int32_t; 18 | 19 | enum class EventType : ev_type_t 20 | { 21 | None = 0, 22 | 23 | // category_window types 24 | WindowClose, WindowResize, WindowFocus, WindowUnfocus, WindowMove, 25 | 26 | // key types 27 | KeyPressed, KeyReleased, KeyTyped, 28 | 29 | // category_mouse types 30 | MouseBtnPress, MouseBtnRelease, MouseMove, MouseScroll, 31 | }; 32 | 33 | enum class EventCategory : ev_category_t 34 | { 35 | None = 0, 36 | Window = bit(1u), 37 | Input = bit(2u), 38 | Mouse = bit(3u), 39 | MouseBtn = bit(4u), 40 | }; 41 | 42 | class Event 43 | { 44 | friend class EventDispatcher; 45 | 46 | friend std::ostream& operator<<(std::ostream& os, const Event& ev); 47 | public: 48 | [[nodiscard]] virtual ev_category_t Categories() const = 0; 49 | [[nodiscard]] virtual EventType Type() const = 0; 50 | 51 | [[nodiscard]] bool IsHandled() const 52 | { return handled; } 53 | 54 | #ifdef REAL_DEBUG 55 | [[nodiscard]] virtual std::string Name() const = 0; 56 | [[nodiscard]] virtual std::string ToString() const 57 | { return Name(); } 58 | #else 59 | [[nodiscard]] virtual std::string ToString() const { return "event"; } 60 | #endif 61 | 62 | [[nodiscard]] bool HasCategory(EventCategory c) const 63 | { 64 | return static_cast(static_cast(c) & Categories()); 65 | } 66 | protected: 67 | bool handled = false; 68 | }; 69 | 70 | template 71 | struct IsEvent 72 | { 73 | #pragma clang diagnostic push 74 | #pragma ide diagnostic ignored "NotImplementedFunctions" 75 | static int Detect(...); 76 | 77 | template 78 | static decltype(U::StaticType()) Detect(const U&); 79 | 80 | static constexpr bool value = std::is_same< 81 | EventType, 82 | decltype( 83 | Detect(std::declval< 84 | typename std::enable_if::value, T>::type 85 | >())) 86 | >::value; 87 | #pragma clang diagnostic pop 88 | }; 89 | 90 | class EventDispatcher 91 | { 92 | template 93 | using ev_function_t = std::function; 94 | public: 95 | 96 | explicit EventDispatcher(Event* ev) 97 | :event(ev) 98 | {} 99 | 100 | template 101 | bool Dispatch( 102 | ev_function_t< 103 | typename std::enable_if::value, T>::type 104 | > function 105 | ) noexcept 106 | { 107 | if (event->Type() == T::StaticType()) 108 | { 109 | event->handled = function(*((T*)event)); 110 | return true; 111 | } 112 | return false; 113 | } 114 | 115 | private: 116 | Event* event; 117 | }; 118 | 119 | inline std::ostream& operator<<(std::ostream& os, const Event& event) 120 | { 121 | os << event.ToString() << ", handled: " << event.handled; 122 | return os; 123 | } 124 | } 125 | 126 | #endif //REAL_EVENT_BASE -------------------------------------------------------------------------------- /engine/include/real/event/key_event.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 udv. All rights reserved. 2 | 3 | #ifndef REAL_EVENT_KEY 4 | #define REAL_EVENT_KEY 5 | 6 | #include "real/event/base_event.hpp" 7 | 8 | namespace Real 9 | { 10 | class KeyEvent : public Event 11 | { 12 | public: 13 | [[nodiscard]] ev_category_t Categories() const override 14 | { 15 | return static_cast(EventCategory::Input); 16 | } 17 | 18 | [[nodiscard]] EventType Type() const override 19 | { 20 | return EventType::None; 21 | } 22 | 23 | [[nodiscard]] static EventType StaticType() 24 | { 25 | return EventType::None; 26 | }; 27 | }; 28 | 29 | class KeyPressedEvent : public KeyEvent 30 | { 31 | private: 32 | keycode_t btnKeycode; 33 | public: 34 | explicit KeyPressedEvent(keycode_t btn) 35 | :btnKeycode(btn) 36 | {}; 37 | 38 | [[nodiscard]] mouse_btn_t KeyCode() const 39 | { return btnKeycode; } 40 | 41 | [[nodiscard]] EventType Type() const override 42 | { 43 | return EventType::KeyPressed; 44 | } 45 | 46 | [[nodiscard]] static EventType StaticType() 47 | { 48 | return EventType::KeyPressed; 49 | }; 50 | #ifdef REAL_DEBUG 51 | [[nodiscard]] std::string Name() const override 52 | { 53 | return "key_press_ev"; 54 | } 55 | #endif 56 | [[nodiscard]] std::string ToString() const override 57 | { 58 | std::stringstream ss; 59 | ss << "key_press_ev: ("; 60 | ss << btnKeycode; 61 | ss << ")"; 62 | return ss.str(); 63 | } 64 | 65 | }; 66 | 67 | class KeyReleasedEvent : public KeyEvent 68 | { 69 | private: 70 | keycode_t btnKeycode; 71 | public: 72 | explicit KeyReleasedEvent(keycode_t btn) 73 | :btnKeycode(btn) 74 | {}; 75 | 76 | [[nodiscard]] mouse_btn_t KeyCode() const 77 | { return btnKeycode; } 78 | 79 | [[nodiscard]] EventType Type() const override 80 | { 81 | return EventType::KeyReleased; 82 | } 83 | 84 | [[nodiscard]] static EventType StaticType() 85 | { 86 | return EventType::KeyReleased; 87 | }; 88 | 89 | #ifdef REAL_DEBUG 90 | [[nodiscard]] std::string Name() const override 91 | { 92 | return "key_release_ev"; 93 | } 94 | #endif 95 | [[nodiscard]] std::string ToString() const override 96 | { 97 | std::stringstream ss; 98 | ss << "key_release_ev: ("; 99 | ss << btnKeycode; 100 | ss << ")"; 101 | return ss.str(); 102 | } 103 | 104 | }; 105 | 106 | class KeyTypedEvent : public KeyEvent 107 | { 108 | private: 109 | keycode_t keycode; 110 | keycode_t repeatCount = 0; 111 | public: 112 | explicit KeyTypedEvent(keycode_t btn) 113 | :keycode(btn) 114 | {}; 115 | 116 | [[nodiscard]] mouse_btn_t KeyCode() const 117 | { return keycode; } 118 | [[nodiscard]] mouse_btn_t Repeats() const 119 | { return repeatCount; } 120 | 121 | [[nodiscard]] EventType Type() const override 122 | { 123 | return EventType::KeyTyped; 124 | } 125 | 126 | [[nodiscard]] static EventType StaticType() 127 | { 128 | return EventType::KeyTyped; 129 | }; 130 | 131 | #ifdef REAL_DEBUG 132 | [[nodiscard]] std::string Name() const override 133 | { 134 | return "key_typed_ev"; 135 | } 136 | #endif 137 | [[nodiscard]] std::string ToString() const override 138 | { 139 | std::stringstream ss; 140 | ss << "key_typed_ev: ("; 141 | ss << keycode << ", " << repeatCount; 142 | ss << ")"; 143 | return ss.str(); 144 | } 145 | 146 | }; 147 | } 148 | 149 | #endif //REAL_EVENT_KEY 150 | -------------------------------------------------------------------------------- /engine/include/real/event/mouse_event.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 udv. All rights reserved. 2 | 3 | #ifndef REAL_EVENT_MOUSE 4 | #define REAL_EVENT_MOUSE 5 | 6 | #include "real/event/base_event.hpp" 7 | 8 | namespace Real 9 | { 10 | 11 | class MouseEvent : public Event 12 | { 13 | public: 14 | [[nodiscard]] ev_category_t Categories() const override 15 | { 16 | return static_cast(EventCategory::Mouse); 17 | } 18 | 19 | [[nodiscard]] EventType Type() const override 20 | { 21 | return EventType::None; 22 | } 23 | 24 | [[nodiscard]] static EventType StaticType() 25 | { 26 | return EventType::None; 27 | }; 28 | }; 29 | 30 | class MouseBtnPressedEvent : public MouseEvent 31 | { 32 | private: 33 | mouse_btn_t mouseBtn; 34 | public: 35 | explicit MouseBtnPressedEvent(mouse_btn_t btn) 36 | :mouseBtn(btn) 37 | {}; 38 | 39 | [[nodiscard]] mouse_btn_t Button() const 40 | { return mouseBtn; } 41 | 42 | [[nodiscard]] EventType Type() const override 43 | { 44 | return EventType::MouseBtnPress; 45 | } 46 | 47 | [[nodiscard]] static EventType StaticType() 48 | { 49 | return EventType::MouseBtnPress; 50 | }; 51 | 52 | #ifdef REAL_DEBUG 53 | [[nodiscard]] std::string Name() const override 54 | { 55 | return "mouse_btn_press_ev"; 56 | } 57 | #endif 58 | [[nodiscard]] std::string ToString() const override 59 | { 60 | std::stringstream ss; 61 | ss << "mouse_btn_press_ev: ("; 62 | ss << mouseBtn; 63 | ss << ")"; 64 | return ss.str(); 65 | } 66 | 67 | }; 68 | 69 | class MouseBtnReleasedEvent : public MouseEvent 70 | { 71 | private: 72 | mouse_btn_t mouseBtn; 73 | public: 74 | explicit MouseBtnReleasedEvent(mouse_btn_t btn) 75 | :mouseBtn(btn) 76 | {}; 77 | 78 | [[nodiscard]] mouse_btn_t Button() const 79 | { return mouseBtn; } 80 | 81 | [[nodiscard]] EventType Type() const override 82 | { 83 | return EventType::MouseBtnRelease; 84 | } 85 | 86 | [[nodiscard]] static EventType StaticType() 87 | { 88 | return EventType::MouseBtnRelease; 89 | }; 90 | 91 | #ifdef REAL_DEBUG 92 | [[nodiscard]] std::string Name() const override 93 | { 94 | return "mouse_btn_release_ev"; 95 | } 96 | #endif 97 | [[nodiscard]] std::string ToString() const override 98 | { 99 | std::stringstream ss; 100 | ss << "mouse_btn_release_ev: ("; 101 | ss << mouseBtn; 102 | ss << ")"; 103 | return ss.str(); 104 | } 105 | 106 | }; 107 | 108 | class MouseMovedEvent : public MouseEvent 109 | { 110 | private: 111 | mouse_position_t xPos, yPos; 112 | public: 113 | MouseMovedEvent(mouse_position_t x, mouse_position_t y) 114 | :xPos(x), yPos(y) 115 | {} 116 | 117 | [[nodiscard]] mouse_position_t X() const 118 | { return xPos; } 119 | [[nodiscard]] mouse_position_t Y() const 120 | { return yPos; } 121 | 122 | [[nodiscard]] EventType Type() const override 123 | { 124 | return EventType::MouseMove; 125 | } 126 | 127 | [[nodiscard]] static EventType StaticType() 128 | { 129 | return EventType::MouseMove; 130 | }; 131 | 132 | #ifdef REAL_DEBUG 133 | [[nodiscard]] std::string Name() const override 134 | { 135 | return "mouse_move_ev"; 136 | } 137 | #endif 138 | [[nodiscard]] std::string ToString() const override 139 | { 140 | std::stringstream ss; 141 | ss << "mouse_move_ev: ("; 142 | ss << xPos << ", " << yPos; 143 | ss << ")"; 144 | return ss.str(); 145 | } 146 | 147 | }; 148 | 149 | class MouseScrolledEvent : public MouseEvent 150 | { 151 | public: 152 | MouseScrolledEvent(mouse_position_t x_offset, mouse_position_t y_offset) 153 | :xOffset(x_offset), 154 | yOffset(y_offset) 155 | {} 156 | 157 | [[nodiscard]] mouse_position_t XOffset() const 158 | { return xOffset; } 159 | [[nodiscard]] mouse_position_t YOffset() const 160 | { return yOffset; } 161 | 162 | [[nodiscard]] EventType Type() const override 163 | { 164 | return EventType::MouseScroll; 165 | } 166 | 167 | [[nodiscard]] static EventType StaticType() 168 | { 169 | return EventType::MouseScroll; 170 | }; 171 | 172 | #ifdef REAL_DEBUG 173 | [[nodiscard]] std::string Name() const override 174 | { 175 | return "mouse_scroll_ev"; 176 | } 177 | #endif 178 | 179 | [[nodiscard]] std::string ToString() const override 180 | { 181 | std::stringstream ss; 182 | ss << "mouse_btn_press_ev: ("; 183 | ss << xOffset << ", " << yOffset; 184 | ss << ")"; 185 | return ss.str(); 186 | } 187 | private: 188 | mouse_position_t xOffset; 189 | mouse_position_t yOffset; 190 | }; 191 | } 192 | 193 | #endif //REAL_EVENT_MOUSE 194 | -------------------------------------------------------------------------------- /engine/include/real/event/window_event.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 udv. All rights reserved. 2 | 3 | #ifndef REAL_EVENT_WINDOW 4 | #define REAL_EVENT_WINDOW 5 | 6 | #include 7 | 8 | #include "real/event/base_event.hpp" 9 | 10 | namespace Real 11 | { 12 | 13 | class WindowEvent : public Event 14 | { 15 | public: 16 | [[nodiscard]] ev_category_t Categories() const override 17 | { 18 | return static_cast(EventCategory::Window); 19 | } 20 | 21 | [[nodiscard]] EventType Type() const override 22 | { 23 | return EventType::None; 24 | } 25 | 26 | [[nodiscard]] static EventType StaticType() 27 | { 28 | return EventType::None; 29 | }; 30 | }; 31 | 32 | class WindowClosedEvent : public WindowEvent 33 | { 34 | public: 35 | WindowClosedEvent() = default; 36 | 37 | [[nodiscard]] EventType Type() const override 38 | { 39 | return EventType::WindowClose; 40 | } 41 | 42 | [[nodiscard]] static EventType StaticType() 43 | { 44 | return EventType::WindowClose; 45 | }; 46 | 47 | #ifdef REAL_DEBUG 48 | [[nodiscard]] std::string Name() const override 49 | { 50 | return "window_close_ev"; 51 | } 52 | #endif 53 | [[nodiscard]] std::string ToString() const override 54 | { 55 | return "window_close_ev"; 56 | } 57 | 58 | }; 59 | 60 | class WindowResizedEvent : public WindowEvent 61 | { 62 | private: 63 | window_dimension_t width, heigth; 64 | public: 65 | WindowResizedEvent(window_dimension_t w, window_dimension_t h) 66 | :width(w), heigth(h) 67 | {} 68 | 69 | [[nodiscard]] mouse_btn_t Width() const 70 | { return width; } 71 | [[nodiscard]] mouse_btn_t Height() const 72 | { return heigth; } 73 | 74 | [[nodiscard]] EventType Type() const override 75 | { 76 | return EventType::WindowResize; 77 | } 78 | 79 | [[nodiscard]] static EventType StaticType() 80 | { 81 | return EventType::WindowResize; 82 | }; 83 | 84 | #ifdef REAL_DEBUG 85 | [[nodiscard]] std::string Name() const override 86 | { 87 | return "window_resize_ev"; 88 | } 89 | #endif 90 | [[nodiscard]] std::string ToString() const override 91 | { 92 | std::stringstream ss; 93 | ss << "window_resize_ev: ("; 94 | ss << width << ", " << heigth; 95 | ss << ")"; 96 | return ss.str(); 97 | } 98 | 99 | }; 100 | 101 | class WindowMovedEvent : public WindowEvent 102 | { 103 | private: 104 | window_position_t xPos, yPos; 105 | public: 106 | WindowMovedEvent(window_position_t x, window_position_t y) 107 | :xPos(x), yPos(y) 108 | {} 109 | 110 | [[nodiscard]] mouse_btn_t X() const 111 | { return xPos; } 112 | [[nodiscard]] mouse_btn_t Y() const 113 | { return yPos; } 114 | 115 | [[nodiscard]] EventType Type() const override 116 | { 117 | return EventType::WindowMove; 118 | } 119 | 120 | [[nodiscard]] static EventType StaticType() 121 | { 122 | return EventType::WindowMove; 123 | }; 124 | 125 | #ifdef REAL_DEBUG 126 | [[nodiscard]] std::string Name() const override 127 | { 128 | return "window_move_ev"; 129 | } 130 | #endif 131 | 132 | [[nodiscard]] std::string ToString() const override 133 | { 134 | std::stringstream ss; 135 | ss << "window_move_ev: ("; 136 | ss << xPos << ", " << yPos; 137 | ss << ")"; 138 | return ss.str(); 139 | } 140 | 141 | }; 142 | 143 | class WindowFocusedEvent : public WindowEvent 144 | { 145 | public: 146 | WindowFocusedEvent() = default; 147 | 148 | [[nodiscard]] EventType Type() const override 149 | { 150 | return EventType::WindowFocus; 151 | } 152 | 153 | [[nodiscard]] static EventType StaticType() 154 | { 155 | return EventType::WindowFocus; 156 | }; 157 | 158 | #ifdef REAL_DEBUG 159 | [[nodiscard]] std::string Name() const override 160 | { 161 | return "window_focus_ev"; 162 | } 163 | #endif 164 | 165 | [[nodiscard]] std::string ToString() const override 166 | { 167 | std::stringstream ss; 168 | ss << "window_resize_ev"; 169 | return ss.str(); 170 | } 171 | 172 | }; 173 | 174 | class WindowUnfocusedEvent : public WindowEvent 175 | { 176 | public: 177 | WindowUnfocusedEvent() = default; 178 | 179 | [[nodiscard]] EventType Type() const override 180 | { 181 | return EventType::WindowUnfocus; 182 | } 183 | 184 | [[nodiscard]] static EventType StaticType() 185 | { 186 | return EventType::WindowUnfocus; 187 | }; 188 | 189 | #ifdef REAL_DEBUG 190 | [[nodiscard]] std::string Name() const override 191 | { 192 | return "window_unfocus_ev"; 193 | } 194 | #endif 195 | 196 | [[nodiscard]] std::string ToString() const override 197 | { 198 | std::stringstream ss; 199 | ss << "window_resize_ev"; 200 | return ss.str(); 201 | } 202 | 203 | }; 204 | } 205 | 206 | #endif //REAL_EVENT_WINDOW 207 | -------------------------------------------------------------------------------- /engine/include/real/input.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 udv. All rights reserved. 2 | 3 | #ifndef REAL_INPUT 4 | #define REAL_INPUT 5 | 6 | #include "real/core.hpp" 7 | #include "real/keycode.hpp" 8 | #include "real/input/base_input.hpp" 9 | 10 | #ifdef REAL_PLATFORM_WINDOWS 11 | #include "real/platform/windows/windows_input.hpp" 12 | #else 13 | #error Unsupported platform! 14 | #endif 15 | 16 | #endif //REAL_INPUT 17 | -------------------------------------------------------------------------------- /engine/include/real/input/base_input.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 udv. All rights reserved. 2 | 3 | #ifndef REAL_INPUT_BASE 4 | #define REAL_INPUT_BASE 5 | 6 | #include "real/core.hpp" 7 | #include "real/keycode.hpp" 8 | #include "real/util/singleton.hpp" 9 | 10 | namespace Real 11 | { 12 | class REAL_API SINGLETON(Input) 13 | { 14 | public: 15 | virtual ~Input() = default; 16 | 17 | virtual bool IsKeyPressed(KeyCode keycode) = 0; 18 | virtual bool IsMouseBtnPressed(mouse_btn_t mouseBtn) = 0; 19 | 20 | virtual std::pair MousePosition() = 0; 21 | virtual mouse_position_t MouseX() = 0; 22 | virtual mouse_position_t MouseY() = 0; 23 | 24 | static Real::Scope Make(); 25 | }; 26 | } 27 | 28 | #endif //REAL_INPUT_BASE 29 | -------------------------------------------------------------------------------- /engine/include/real/keycode.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 udv. All rights reserved. 2 | 3 | #ifndef REAL_KEYCODE 4 | #define REAL_KEYCODE 5 | 6 | #include 7 | 8 | #include "real/core.hpp" 9 | 10 | namespace Real { 11 | enum class KeyCode : keycode_t { 12 | // @formatter:off 13 | // From glfw3.h 14 | Space = 32, 15 | Apostrophe = 39, /* ' */ 16 | Comma = 44, /* , */ 17 | Minus = 45, /* - */ 18 | Period = 46, /* . */ 19 | Slash = 47, /* / */ 20 | 21 | D0 = 48, /* 0 */ 22 | D1 = 49, /* 1 */ 23 | D2 = 50, /* 2 */ 24 | D3 = 51, /* 3 */ 25 | D4 = 52, /* 4 */ 26 | D5 = 53, /* 5 */ 27 | D6 = 54, /* 6 */ 28 | D7 = 55, /* 7 */ 29 | D8 = 56, /* 8 */ 30 | D9 = 57, /* 9 */ 31 | 32 | Semicolon = 59, /* ; */ 33 | Equal = 61, /* = */ 34 | 35 | A = 65, 36 | B = 66, 37 | C = 67, 38 | D = 68, 39 | E = 69, 40 | F = 70, 41 | G = 71, 42 | H = 72, 43 | I = 73, 44 | J = 74, 45 | K = 75, 46 | L = 76, 47 | M = 77, 48 | N = 78, 49 | O = 79, 50 | P = 80, 51 | Q = 81, 52 | R = 82, 53 | S = 83, 54 | T = 84, 55 | U = 85, 56 | V = 86, 57 | W = 87, 58 | X = 88, 59 | Y = 89, 60 | Z = 90, 61 | 62 | LeftBracket = 91, /* [ */ 63 | Backslash = 92, /* \ */ 64 | RightBracket = 93, /* ] */ 65 | GraveAccent = 96, /* ` */ 66 | 67 | World1 = 161, /* non-US #1 */ 68 | World2 = 162, /* non-US #2 */ 69 | 70 | /* Function keys */ 71 | Escape = 256, 72 | Enter = 257, 73 | Tab = 258, 74 | Backspace = 259, 75 | Insert = 260, 76 | Delete = 261, 77 | Right = 262, 78 | Left = 263, 79 | Down = 264, 80 | Up = 265, 81 | PageUp = 266, 82 | PageDown = 267, 83 | Home = 268, 84 | End = 269, 85 | CapsLock = 280, 86 | ScrollLock = 281, 87 | NumLock = 282, 88 | PrintScreen = 283, 89 | Pause = 284, 90 | F1 = 290, 91 | F2 = 291, 92 | F3 = 292, 93 | F4 = 293, 94 | F5 = 294, 95 | F6 = 295, 96 | F7 = 296, 97 | F8 = 297, 98 | F9 = 298, 99 | F10 = 299, 100 | F11 = 300, 101 | F12 = 301, 102 | F13 = 302, 103 | F14 = 303, 104 | F15 = 304, 105 | F16 = 305, 106 | F17 = 306, 107 | F18 = 307, 108 | F19 = 308, 109 | F20 = 309, 110 | F21 = 310, 111 | F22 = 311, 112 | F23 = 312, 113 | F24 = 313, 114 | F25 = 314, 115 | 116 | /* Keypad */ 117 | KP0 = 320, 118 | KP1 = 321, 119 | KP2 = 322, 120 | KP3 = 323, 121 | KP4 = 324, 122 | KP5 = 325, 123 | KP6 = 326, 124 | KP7 = 327, 125 | KP8 = 328, 126 | KP9 = 329, 127 | KPDecimal = 330, 128 | KPDivide = 331, 129 | KPMultiply = 332, 130 | KPSubtract = 333, 131 | KPAdd = 334, 132 | KPEnter = 335, 133 | KPEqual = 336, 134 | 135 | LeftShift = 340, 136 | LeftControl = 341, 137 | LeftAlt = 342, 138 | LeftSuper = 343, 139 | RightShift = 344, 140 | RightControl = 345, 141 | RightAlt = 346, 142 | RightSuper = 347, 143 | Menu = 348, 144 | // @formatter:on 145 | }; 146 | 147 | inline std::ostream &operator<<(std::ostream &os, KeyCode keyCode) { 148 | os << static_cast(keyCode); 149 | return os; 150 | } 151 | } 152 | 153 | // @formatter:off 154 | #define REAL_KEY_SPACE ::Real::KeyCode::Space 155 | #define REAL_KEY_APOSTROPHE ::real::KeyCode::Apostrophe /* ' */ 156 | #define REAL_KEY_COMMA ::real::KeyCode::Comma /* , */ 157 | #define REAL_KEY_MINUS ::real::KeyCode::Minus /* - */ 158 | #define REAL_KEY_PERIOD ::real::KeyCode::Period /* . */ 159 | #define REAL_KEY_SLASH ::real::KeyCode::Slash /* / */ 160 | #define REAL_KEY_0 ::real::KeyCode::D0 161 | #define REAL_KEY_1 ::real::KeyCode::D1 162 | #define REAL_KEY_2 ::real::KeyCode::D2 163 | #define REAL_KEY_3 ::real::KeyCode::D3 164 | #define REAL_KEY_4 ::real::KeyCode::D4 165 | #define REAL_KEY_5 ::real::KeyCode::D5 166 | #define REAL_KEY_6 ::real::KeyCode::D6 167 | #define REAL_KEY_7 ::real::KeyCode::D7 168 | #define REAL_KEY_8 ::real::KeyCode::D8 169 | #define REAL_KEY_9 ::real::KeyCode::D9 170 | #define REAL_KEY_SEMICOLON ::real::KeyCode::Semicolon /* ; */ 171 | #define REAL_KEY_EQUAL ::real::KeyCode::Equal /* = */ 172 | #define REAL_KEY_A ::Real::KeyCode::A 173 | #define REAL_KEY_B ::real::KeyCode::B 174 | #define REAL_KEY_C ::Real::KeyCode::C 175 | #define REAL_KEY_D ::real::KeyCode::D 176 | #define REAL_KEY_E ::real::KeyCode::E 177 | #define REAL_KEY_F ::real::KeyCode::F 178 | #define REAL_KEY_G ::real::KeyCode::G 179 | #define REAL_KEY_H ::real::KeyCode::H 180 | #define REAL_KEY_I ::real::KeyCode::I 181 | #define REAL_KEY_J ::real::KeyCode::J 182 | #define REAL_KEY_K ::real::KeyCode::K 183 | #define REAL_KEY_L ::real::KeyCode::L 184 | #define REAL_KEY_M ::real::KeyCode::M 185 | #define REAL_KEY_N ::real::KeyCode::N 186 | #define REAL_KEY_O ::real::KeyCode::O 187 | #define REAL_KEY_P ::real::KeyCode::P 188 | #define REAL_KEY_Q ::real::KeyCode::Q 189 | #define REAL_KEY_R ::real::KeyCode::R 190 | #define REAL_KEY_S ::real::KeyCode::S 191 | #define REAL_KEY_T ::real::KeyCode::T 192 | #define REAL_KEY_U ::real::KeyCode::U 193 | #define REAL_KEY_V ::Real::KeyCode::V 194 | #define REAL_KEY_W ::real::KeyCode::W 195 | #define REAL_KEY_X ::Real::KeyCode::X 196 | #define REAL_KEY_Y ::Real::KeyCode::Y 197 | #define REAL_KEY_Z ::Real::KeyCode::Z 198 | #define REAL_KEY_LEFT_BRACKET ::real::KeyCode::LeftBracket /* [ */ 199 | #define REAL_KEY_BACKSLASH ::real::KeyCode::Backslash /* \ */ 200 | #define REAL_KEY_RIGHT_BRACKET ::real::KeyCode::RightBracket /* ] */ 201 | #define REAL_KEY_GRAVE_ACCENT ::real::KeyCode::GraveAccent /* ` */ 202 | #define REAL_KEY_WORLD_1 ::real::KeyCode::World1 /* non-US #1 */ 203 | #define REAL_KEY_WORLD_2 ::real::KeyCode::World2 /* non-US #2 */ 204 | 205 | /* Function keys */ 206 | #define REAL_KEY_ESCAPE ::Real::KeyCode::Escape 207 | #define REAL_KEY_ENTER ::Real::KeyCode::Enter 208 | #define REAL_KEY_TAB ::Real::KeyCode::Tab 209 | #define REAL_KEY_BACKSPACE ::Real::KeyCode::Backspace 210 | #define REAL_KEY_INSERT ::Real::KeyCode::Insert 211 | #define REAL_KEY_DELETE ::Real::KeyCode::Delete 212 | #define REAL_KEY_RIGHT ::Real::KeyCode::Right 213 | #define REAL_KEY_LEFT ::Real::KeyCode::Left 214 | #define REAL_KEY_DOWN ::Real::KeyCode::Down 215 | #define REAL_KEY_UP ::Real::KeyCode::Up 216 | #define REAL_KEY_PAGE_UP ::Real::KeyCode::PageUp 217 | #define REAL_KEY_PAGE_DOWN ::Real::KeyCode::PageDown 218 | #define REAL_KEY_HOME ::Real::KeyCode::Home 219 | #define REAL_KEY_END ::Real::KeyCode::End 220 | #define REAL_KEY_CAPS_LOCK ::real::KeyCode::CapsLock 221 | #define REAL_KEY_SCROLL_LOCK ::real::KeyCode::ScrollLock 222 | #define REAL_KEY_NUM_LOCK ::real::KeyCode::NumLock 223 | #define REAL_KEY_PRINT_SCREEN ::real::KeyCode::PrintScreen 224 | #define REAL_KEY_PAUSE ::real::KeyCode::Pause 225 | #define REAL_KEY_F1 ::real::KeyCode::F1 226 | #define REAL_KEY_F2 ::real::KeyCode::F2 227 | #define REAL_KEY_F3 ::real::KeyCode::F3 228 | #define REAL_KEY_F4 ::real::KeyCode::F4 229 | #define REAL_KEY_F5 ::real::KeyCode::F5 230 | #define REAL_KEY_F6 ::real::KeyCode::F6 231 | #define REAL_KEY_F7 ::real::KeyCode::F7 232 | #define REAL_KEY_F8 ::real::KeyCode::F8 233 | #define REAL_KEY_F9 ::real::KeyCode::F9 234 | #define REAL_KEY_F10 ::real::KeyCode::F10 235 | #define REAL_KEY_F11 ::real::KeyCode::F11 236 | #define REAL_KEY_F12 ::real::KeyCode::F12 237 | #define REAL_KEY_F13 ::real::KeyCode::F13 238 | #define REAL_KEY_F14 ::real::KeyCode::F14 239 | #define REAL_KEY_F15 ::real::KeyCode::F15 240 | #define REAL_KEY_F16 ::real::KeyCode::F16 241 | #define REAL_KEY_F17 ::real::KeyCode::F17 242 | #define REAL_KEY_F18 ::real::KeyCode::F18 243 | #define REAL_KEY_F19 ::real::KeyCode::F19 244 | #define REAL_KEY_F20 ::real::KeyCode::F20 245 | #define REAL_KEY_F21 ::real::KeyCode::F21 246 | #define REAL_KEY_F22 ::real::KeyCode::F22 247 | #define REAL_KEY_F23 ::real::KeyCode::F23 248 | #define REAL_KEY_F24 ::real::KeyCode::F24 249 | #define REAL_KEY_F25 ::real::KeyCode::F25 250 | 251 | /* Keypad */ 252 | #define REAL_KEY_KP_0 ::real::KeyCode::KP0 253 | #define REAL_KEY_KP_1 ::real::KeyCode::KP1 254 | #define REAL_KEY_KP_2 ::real::KeyCode::KP2 255 | #define REAL_KEY_KP_3 ::real::KeyCode::KP3 256 | #define REAL_KEY_KP_4 ::real::KeyCode::KP4 257 | #define REAL_KEY_KP_5 ::real::KeyCode::KP5 258 | #define REAL_KEY_KP_6 ::real::KeyCode::KP6 259 | #define REAL_KEY_KP_7 ::real::KeyCode::KP7 260 | #define REAL_KEY_KP_8 ::real::KeyCode::KP8 261 | #define REAL_KEY_KP_9 ::real::KeyCode::KP9 262 | #define REAL_KEY_KP_DECIMAL ::real::KeyCode::KPDecimal 263 | #define REAL_KEY_KP_DIVIDE ::real::KeyCode::KPDivide 264 | #define REAL_KEY_KP_MULTIPLY ::real::KeyCode::KPMultiply 265 | #define REAL_KEY_KP_SUBTRACT ::real::KeyCode::KPSubtract 266 | #define REAL_KEY_KP_ADD ::real::KeyCode::KPAdd 267 | #define REAL_KEY_KP_ENTER ::Real::KeyCode::KPEnter 268 | #define REAL_KEY_KP_EQUAL ::real::KeyCode::KPEqual 269 | 270 | #define REAL_KEY_LEFT_SHIFT ::Real::KeyCode::LeftShift 271 | #define REAL_KEY_LEFT_CONTROL ::Real::KeyCode::LeftControl 272 | #define REAL_KEY_LEFT_ALT ::Real::KeyCode::LeftAlt 273 | #define REAL_KEY_LEFT_SUPER ::Real::KeyCode::LeftSuper 274 | #define REAL_KEY_RIGHT_SHIFT ::Real::KeyCode::RightShift 275 | #define REAL_KEY_RIGHT_CONTROL ::Real::KeyCode::RightControl 276 | #define REAL_KEY_RIGHT_ALT ::Real::KeyCode::RightAlt 277 | #define REAL_KEY_RIGHT_SUPER ::Real::KeyCode::RightSuper 278 | #define REAL_KEY_MENU ::real::KeyCode::Menu 279 | // @formatter:on 280 | 281 | #endif //REAL_KEYCODE 282 | -------------------------------------------------------------------------------- /engine/include/real/layer.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 udv. All rights reserved. 2 | 3 | #ifndef REAL_LAYER 4 | #define REAL_LAYER 5 | 6 | #include "real/layer/base_layer.hpp" 7 | #include "real/layer/imgui_layer.hpp" 8 | 9 | #endif //REAL_BASE_LAYER 10 | -------------------------------------------------------------------------------- /engine/include/real/layer/base_layer.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 udv. All rights reserved. 2 | 3 | #ifndef REAL_LAYER_BASE 4 | #define REAL_LAYER_BASE 5 | 6 | #include "real/time/timestep.hpp" 7 | 8 | #include "real/core.hpp" 9 | #include "real/event.hpp" 10 | 11 | namespace Real 12 | { 13 | class REAL_API Layer 14 | { 15 | public: 16 | Layer() = default; 17 | virtual void OnImGUIRender(); 18 | 19 | virtual void Attach(); 20 | virtual void Detach(); 21 | virtual void Update(Timestep ts); 22 | virtual void HandleEvent(Event& e); 23 | }; 24 | } 25 | 26 | #endif //REAL_LAYER_BASE 27 | -------------------------------------------------------------------------------- /engine/include/real/layer/imgui_layer.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 udv. All rights reserved. 2 | 3 | #ifndef REAL_LAYER_IMGUI 4 | #define REAL_LAYER_IMGUI 5 | 6 | #include "real/core.hpp" 7 | #include "real/layer/base_layer.hpp" 8 | 9 | namespace Real { 10 | class REAL_API ImGUILayer : public Layer { 11 | public: 12 | ImGUILayer(); 13 | ~ImGUILayer(); 14 | 15 | void Begin(); 16 | void End(); 17 | 18 | void Attach() override; 19 | void Detach() override; 20 | void HandleEvent(Event &ev) override; 21 | }; 22 | } 23 | 24 | #endif //REAL_LAYER_IMGUI 25 | -------------------------------------------------------------------------------- /engine/include/real/layer_stack.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 udv. All rights reserved. 2 | 3 | #ifndef REAL_LAYER_STACK 4 | #define REAL_LAYER_STACK 5 | 6 | #include "real/core.hpp" 7 | #include "real/layer.hpp" 8 | 9 | namespace Real 10 | { 11 | class REAL_API LayerStack 12 | { 13 | using container = std::vector; 14 | using iterator = container::iterator; 15 | using const_iterator = container::const_iterator; 16 | private: 17 | // TODO: own vector 18 | container stack; 19 | typename container::size_type layerInsert; 20 | public: 21 | LayerStack(); 22 | ~LayerStack(); 23 | 24 | //region Iterators 25 | iterator begin() noexcept 26 | { return stack.begin(); }; 27 | const_iterator cbegin() const noexcept 28 | { return stack.begin(); }; 29 | const_iterator begin() const noexcept 30 | { return stack.begin(); }; 31 | 32 | iterator end() noexcept 33 | { return stack.end(); }; 34 | const_iterator end() const noexcept 35 | { return stack.end(); }; 36 | const_iterator cend() const noexcept 37 | { return stack.end(); }; 38 | //endregion 39 | 40 | void PushLayer(Layer* layer); 41 | void PopLayer(Layer* layer); 42 | 43 | void PushOverlay(Layer* overlay); 44 | void PopOverlay(Layer* overlay); 45 | }; 46 | } 47 | 48 | #endif //REAL_LAYER_STACK 49 | -------------------------------------------------------------------------------- /engine/include/real/logger.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 udv. All rights reserved. 2 | 3 | #ifndef REAL_LOGGER 4 | #define REAL_LOGGER 5 | 6 | #include 7 | 8 | #include 9 | #include 10 | 11 | #include "real/core.hpp" 12 | 13 | // TODO: new logging! 14 | namespace Real 15 | { 16 | class REAL_API Logger 17 | { 18 | public: 19 | static void Init(); 20 | 21 | static std::shared_ptr& Core() 22 | { return coreLogger; } 23 | static std::shared_ptr& Client() 24 | { return clientLogger; } 25 | private: 26 | static std::shared_ptr coreLogger; 27 | static std::shared_ptr clientLogger; 28 | }; 29 | } 30 | 31 | // @formatter:off 32 | // Core log macros 33 | #define REAL_CORE_TRACE(...) ::Real::Logger::Core()->trace(__VA_ARGS__) 34 | #define REAL_CORE_INFO(...) ::Real::Logger::Core()->info(__VA_ARGS__) 35 | #define REAL_CORE_WARN(...) ::real::Logger::Core()->warn(__VA_ARGS__) 36 | #define REAL_CORE_ERROR(...) ::Real::Logger::Core()->error(__VA_ARGS__) 37 | #define REAL_CORE_CRITICAL(...) ::real::Logger::Core()->critical(__VA_ARGS__) 38 | 39 | // Client log macros 40 | #define REAL_TRACE(...) ::Real::Logger::Client()->trace(__VA_ARGS__) 41 | #define REAL_INFO(...) ::real::Logger::Client()->info(__VA_ARGS__) 42 | #define REAL_WARN(...) ::real::Logger::Client()->warn(__VA_ARGS__) 43 | #define REAL_ERROR(...) ::real::Logger::Client()->error(__VA_ARGS__) 44 | #define REAL_CRITICAL(...) ::real::Logger::Client()->critical(__VA_ARGS__) 45 | // @formatter:on 46 | 47 | 48 | #endif //REAL_LOGGER 49 | -------------------------------------------------------------------------------- /engine/include/real/pch.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 udv. All rights reserved. 2 | 3 | #ifndef REAL_PCH 4 | #define REAL_PCH 5 | 6 | // Defines 7 | #include 8 | // Util 9 | #include 10 | #include 11 | #include 12 | // IO 13 | #include 14 | #include 15 | // Structures 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #endif //REAL_PCH 24 | -------------------------------------------------------------------------------- /engine/include/real/platform/windows/windows_input.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 udv. All rights reserved. 2 | 3 | #ifndef REAL_WINDOWS_INPUT 4 | #define REAL_WINDOWS_INPUT 5 | 6 | #include "real/core.hpp" 7 | #include "real/input/base_input.hpp" 8 | 9 | namespace Real::Platform 10 | { 11 | class REAL_API Input : public ::Real::Input 12 | { 13 | public: 14 | ~Input() override = default; 15 | 16 | bool IsKeyPressed(KeyCode keycode) override; 17 | bool IsMouseBtnPressed(mouse_btn_t mouse_btn) override; 18 | 19 | std::pair MousePosition() override; 20 | mouse_position_t MouseX() override; 21 | mouse_position_t MouseY() override; 22 | }; 23 | } 24 | 25 | #endif //REAL_WINDOWS_INPUT 26 | -------------------------------------------------------------------------------- /engine/include/real/platform/windows/windows_time.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 udv. All rights reserved. 2 | 3 | #ifndef REAL_WINDOWS_TIME 4 | #define REAL_WINDOWS_TIME 5 | 6 | #include "real/core.hpp" 7 | #include "real/api/gl/gl_headers.hpp" 8 | 9 | namespace Real::Platform 10 | { 11 | REAL_API double Time(); 12 | } 13 | 14 | #endif //REAL_WINDOWS_TIME 15 | -------------------------------------------------------------------------------- /engine/include/real/platform/windows/windows_window.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 udv. All rights reserved. 2 | 3 | #ifndef REAL_WINDOWS_WINDOW 4 | #define REAL_WINDOWS_WINDOW 5 | 6 | #include "real/time/timestep.hpp" 7 | 8 | // TODO: remove api dependency completely 9 | #include "real/api/gl/gl_headers.hpp" 10 | 11 | #include "real/core.hpp" 12 | #include "real/window/base_window.hpp" 13 | 14 | namespace Real::Platform 15 | { 16 | struct WindowData 17 | { 18 | std::string title; 19 | ::Real::window_dimension_t width; 20 | ::Real::window_dimension_t height; 21 | bool isVSync; 22 | event_callback_t ev_callback; 23 | 24 | explicit WindowData( 25 | std::string title = REAL_DEFAULT_WINDOW_TITLE, 26 | window_dimension_t width = REAL_DEFAULT_WINDOW_WIDTH, 27 | window_dimension_t height = REAL_DEFAULT_WINDOW_HEIGHT, 28 | bool is_v_sync = REAL_DEFAULT_WINDOW_V_SYNC, 29 | event_callback_t callback = nullptr 30 | ) 31 | :title(std::move(title)), width(width), height(height), 32 | isVSync(is_v_sync), 33 | ev_callback(std::move(callback)) 34 | {} 35 | 36 | explicit WindowData(const ::Real::WindowProperties& props, 37 | bool is_v_sync = REAL_DEFAULT_WINDOW_V_SYNC, 38 | event_callback_t callback = nullptr) 39 | :title { props.title }, width { props.width }, height { props.height }, 40 | isVSync { is_v_sync }, 41 | ev_callback { std::move(callback) } 42 | {} 43 | }; 44 | 45 | class REAL_API Window : public ::Real::Window 46 | { 47 | public: 48 | explicit Window(WindowData data); 49 | explicit Window(const WindowProperties& props) 50 | :Window(WindowData { props }) 51 | {}; 52 | 53 | ~Window() override; 54 | 55 | void Init() override; 56 | 57 | [[nodiscard]] window_dimension_t Width() const noexcept override 58 | { return windowData.width; }; 59 | [[nodiscard]] window_dimension_t Height() const noexcept override 60 | { return windowData.height; }; 61 | [[nodiscard]] bool IsVSync() const noexcept override 62 | { return windowData.isVSync; } 63 | 64 | [[nodiscard]] void* Native() const noexcept override 65 | { return nativeWindow; } 66 | [[nodiscard]] RenderingContext* Context() const noexcept override 67 | { return renderingContext; }; 68 | 69 | void EventCallback(const event_callback_t& callback) override; 70 | void VSync(bool enabled) override; 71 | 72 | void OnUpdate(Timestep ts) override; 73 | private: 74 | // Maybe this should be virtual? 75 | // void init(); 76 | // void shutdown(); 77 | 78 | void VSyncNative(bool enabled); 79 | private: 80 | // TODO: create window using Win32 API 81 | GLFWwindow* nativeWindow; 82 | RenderingContext* renderingContext; 83 | WindowData windowData; 84 | }; 85 | } 86 | 87 | #endif //REAL_WINDOWS_WINDOW 88 | -------------------------------------------------------------------------------- /engine/include/real/real.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 udv. All rights reserved. 2 | 3 | /* 4 | * This file contains all necessary headers 5 | * to develop applications using real engine. 6 | */ 7 | 8 | #ifndef REAL_ENGINE 9 | #define REAL_ENGINE 10 | 11 | //region core modules 12 | #include "real/core.hpp" 13 | #include "real/application.hpp" 14 | #include "real/logger.hpp" 15 | #include "real/event.hpp" 16 | #include "real/window.hpp" 17 | #include "real/keycode.hpp" 18 | #include "real/input.hpp" 19 | #include "real/layer.hpp" 20 | #include "real/layer_stack.hpp" 21 | #include "real/renderer.hpp" 22 | #include "real/time.hpp" 23 | //endregion 24 | 25 | #ifdef REAL_CLIENT 26 | // region Entry point 27 | int main([[maybe_unused]] int argc, [[maybe_unused]] char** argv) 28 | { 29 | Real::Logger::Init(); 30 | 31 | REAL_CORE_TRACE("Creating application..."); 32 | Real::Scope app = Real::Make(); 33 | app->Init(); 34 | app->Run(); 35 | 36 | return 0; 37 | } 38 | // endregion 39 | #endif 40 | 41 | #undef REAL_CORE_ERROR 42 | 43 | #endif //REAL_ENGINE 44 | -------------------------------------------------------------------------------- /engine/include/real/renderer.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 udv. All rights reserved. 2 | 3 | #ifndef REAL_RENDERER 4 | #define REAL_RENDERER 5 | 6 | #include "real/renderer/common.hpp" 7 | #include "real/renderer/base_renderer.hpp" 8 | #include "real/renderer/render_command.hpp" 9 | #include "real/renderer/base_rendering_context.hpp" 10 | #include "real/renderer/array_vertex.hpp" 11 | #include "real/renderer/buffer_vertex.hpp" 12 | #include "real/renderer/buffer_index.hpp" 13 | #include "real/renderer/buffer_layout.hpp" 14 | #include "real/renderer/base_shader.hpp" 15 | #include "real/renderer/base_texture.hpp" 16 | #include "real/renderer/camera.hpp" 17 | #include "real/renderer/light.hpp" 18 | #include "real/renderer/material.hpp" 19 | // region GL headers 20 | #include "real/api/gl/gl_headers.hpp" 21 | #include "real/api/gl/gl_rendering_context.hpp" 22 | #include "real/api/gl/gl_array_vertex.hpp" 23 | #include "real/api/gl/gl_buffer_vertex.hpp" 24 | #include "real/api/gl/gl_shader.hpp" 25 | #include "real/api/gl/gl_texture.hpp" 26 | #include "real/api/gl/gl_buffer_index.hpp" 27 | #include "real/api/gl/gl_conversions.hpp" 28 | // endregion 29 | 30 | #endif // REAL_RENDERER 31 | -------------------------------------------------------------------------------- /engine/include/real/renderer/array_vertex.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 udv. All rights reserved. 2 | 3 | #ifndef REAL_VERTEX_ARRAY 4 | #define REAL_VERTEX_ARRAY 5 | 6 | #include 7 | 8 | #include "real/core.hpp" 9 | 10 | namespace Real 11 | { 12 | class VertexBuffer; 13 | class IndexBuffer; 14 | 15 | class REAL_API VertexArray 16 | { 17 | public: 18 | virtual ~VertexArray(); 19 | 20 | [[nodiscard]] virtual const std::vector>& 21 | VertexBuffers() const = 0; 22 | [[nodiscard]] virtual const std::vector>& 23 | IndexBuffers() const = 0; 24 | 25 | virtual void AddVertexBuffer( 26 | const Real::Reference& buffer) = 0; 27 | virtual void AddIndexBuffer( 28 | const Real::Reference& buffer) = 0; 29 | 30 | virtual int32_t Count() const = 0; 31 | 32 | virtual void Bind() const = 0; 33 | virtual void Unbind() const = 0; 34 | public: 35 | static Real::Scope Make(); 36 | }; 37 | } 38 | 39 | #endif //REAL_VERTEX_ARRAY 40 | -------------------------------------------------------------------------------- /engine/include/real/renderer/base_renderer.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 udv. All rights reserved. 2 | 3 | #ifndef REAL_RENDERER_BASE 4 | #define REAL_RENDERER_BASE 5 | 6 | #include "real/transform.hpp" 7 | #include "real/core.hpp" 8 | #include "real/renderer/renderer_api.hpp" 9 | #include "real/renderer/camera.hpp" 10 | #include "real/renderer/base_shader.hpp" 11 | #include "real/renderer/material.hpp" 12 | 13 | namespace Real 14 | { 15 | class REAL_API Renderer 16 | { 17 | public: 18 | [[nodiscard]] static RendererAPI& Api() noexcept 19 | { return *api; } 20 | 21 | static void Init(); 22 | static void StartScene(Camera& camera) noexcept; 23 | static void EndScene() noexcept; 24 | 25 | static void Submit(const Real::Reference& vao, 26 | const Real::Reference& shader, 27 | const Real::Transform& model) noexcept; 28 | 29 | static void Submit(const Real::Reference& vao, 30 | const Real::Reference& material, 31 | const Real::Transform& model) noexcept; 32 | private: 33 | static RendererAPI* api; 34 | 35 | // TODO: remove this COMPLETELY Temporary stuff 36 | struct SceneData 37 | { 38 | glm::mat4 viewprojection; 39 | glm::vec3 viewPosition; 40 | }; 41 | 42 | static SceneData* sceneData; 43 | }; 44 | } 45 | 46 | #endif //REAL_RENDERER_BASE 47 | -------------------------------------------------------------------------------- /engine/include/real/renderer/base_rendering_context.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 udv. All rights reserved. 2 | 3 | #ifndef REAL_RENDERING_CONTEXT_BASE 4 | #define REAL_RENDERING_CONTEXT_BASE 5 | 6 | #include "real/core.hpp" 7 | #include "real/renderer/renderer_api.hpp" 8 | 9 | namespace Real { 10 | class REAL_API RenderingContext { 11 | public: 12 | virtual ~RenderingContext(); 13 | 14 | virtual void Init() = 0; 15 | virtual void SwapBuffers() = 0; 16 | virtual void VSync(bool enabled) = 0; 17 | }; 18 | } 19 | 20 | #endif //REAL_RENDERING_CONTEXT_BASE 21 | -------------------------------------------------------------------------------- /engine/include/real/renderer/base_shader.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 udv. All rights reserved. 2 | 3 | #ifndef REAL_BASE_SHADER 4 | #define REAL_BASE_SHADER 5 | 6 | #include "real/core.hpp" 7 | 8 | #define GL_SYNTAX_ERROR_MESSAGE "Syntax error" 9 | #define SHADERS_MAX_COUNT 4 10 | #define SHADERS_AVG_COUNT 2 11 | 12 | namespace Real { 13 | // TODO: Iterate over shader API again 14 | class REAL_API Shader { 15 | public: 16 | virtual ~Shader(); 17 | 18 | // region Uniforms 19 | // Floats 20 | virtual void UniformFloat(const std::string &name, glm::f32 value) = 0; 21 | virtual void UniformFloat(const std::string &name, const glm::fvec2 &value) = 0; 22 | virtual void UniformFloat(const std::string &name, const glm::fvec3 &value) = 0; 23 | virtual void UniformFloat(const std::string &name, const glm::fvec4 &value) = 0; 24 | virtual void 25 | UniformMatrix(const std::string &name, const glm::fmat3 &matrix) = 0; 26 | virtual void 27 | UniformMatrix(const std::string &name, const glm::fmat4 &matrix) = 0; 28 | 29 | // Ints 30 | virtual void UniformInt(const std::string &name, glm::int32 value) = 0; 31 | virtual void UniformInt(const std::string &name, const glm::ivec2 &value) = 0; 32 | virtual void UniformInt(const std::string &name, const glm::ivec3 &value) = 0; 33 | virtual void UniformInt(const std::string &name, const glm::ivec4 &value) = 0; 34 | // endregion 35 | 36 | virtual const std::string &Name() const = 0; 37 | virtual void Name(std::string name) = 0; 38 | 39 | virtual void Bind() const = 0; 40 | virtual void Unbind() const = 0; 41 | 42 | public: 43 | static Real::Reference Make(std::string filename); 44 | }; 45 | 46 | class REAL_API ShaderLibrary { 47 | public: 48 | ShaderLibrary() :shaderMap{} {} 49 | 50 | void Add(const Reference & shader); 51 | Real::Reference Load(const std::string &filename); 52 | Real::Reference 53 | Load(const std::string &name, const std::string &filename); 54 | 55 | Real::Reference Get(const std::string &name); 56 | 57 | bool Contains(const std::string &name); 58 | private: 59 | std::unordered_map> shaderMap; 60 | }; 61 | } 62 | 63 | #endif //REAL_BASE_SHADER 64 | -------------------------------------------------------------------------------- /engine/include/real/renderer/base_texture.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 udv. All rights reserved. 2 | 3 | #ifndef REAL_BASE_TEXTURE 4 | #define REAL_BASE_TEXTURE 5 | 6 | #include "real/core.hpp" 7 | 8 | namespace Real { 9 | class REAL_API Texture { 10 | public: 11 | ~Texture(); 12 | 13 | virtual void Init() = 0; 14 | 15 | virtual texture_dimension_t Width() const = 0; 16 | virtual texture_dimension_t Height() const = 0; 17 | 18 | virtual void Bind(uint32_t slot = 0) const = 0; 19 | }; 20 | 21 | class REAL_API Texture2D : public Texture { 22 | public: 23 | ~Texture2D(); 24 | public: 25 | static Real::Reference Make(const std::string &path); 26 | }; 27 | } 28 | 29 | #endif //REAL_BASE_TEXTURE 30 | -------------------------------------------------------------------------------- /engine/include/real/renderer/buffer_index.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 udv. All rights reserved. 2 | 3 | #ifndef REAL_INDEX_BUFFER 4 | #define REAL_INDEX_BUFFER 5 | 6 | #include "real/core.hpp" 7 | 8 | namespace Real { 9 | class REAL_API IndexBuffer { 10 | private: 11 | public: 12 | virtual ~IndexBuffer(); 13 | 14 | virtual void Bind() const = 0; 15 | virtual void Unbind() const = 0; 16 | 17 | [[nodiscard]] virtual uint32_t Count() const = 0; 18 | public: 19 | static Real::Scope Make(uint32_t *data, uint32_t size); 20 | }; 21 | } 22 | 23 | #endif //REAL_INDEX_BUFFER 24 | -------------------------------------------------------------------------------- /engine/include/real/renderer/buffer_layout.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 udv. All rights reserved. 2 | 3 | #ifndef REAL_BUFFER_LAYOUT 4 | #define REAL_BUFFER_LAYOUT 5 | 6 | #include 7 | 8 | #include "real/core.hpp" 9 | #include "real/logger.hpp" 10 | #include "real/renderer/base_renderer.hpp" 11 | #include "real/api/gl/gl_conversions.hpp" 12 | 13 | namespace Real 14 | { 15 | 16 | struct VertexAttribute 17 | { 18 | shader_data_t type; 19 | std::string name; 20 | uint32_t size; 21 | int64_t offset; 22 | bool normalized = false; 23 | 24 | VertexAttribute(const shader_data_t& type, std::string name) 25 | :type { type }, name { std::move(name) }, size { sizeofsdt(type) }, 26 | offset { 0 }, normalized { false } 27 | {} 28 | 29 | VertexAttribute(const shader_data_t& type, std::string name, bool normalized) 30 | :type { type }, name { std::move(name) }, size { sizeofsdt(type) }, 31 | offset { 0 }, normalized { normalized } 32 | {} 33 | 34 | VertexAttribute(const shader_data_t& type, std::string name, uint32_t size, 35 | int64_t offset, bool normalized) 36 | :type { type }, name { std::move(name) }, size { size }, 37 | offset { offset }, 38 | normalized { normalized } 39 | {} 40 | 41 | [[nodiscard]] uint32_t component_count() const noexcept 42 | { 43 | // @formatter:off 44 | switch (type) 45 | { 46 | case shader_data_t::vec : return 1; 47 | case shader_data_t::vec2 : return 1 * 2; 48 | case shader_data_t::vec3 : return 1 * 3; 49 | case shader_data_t::vec4 : return 1 * 4; 50 | case shader_data_t::mat3 : return 1 * 3 * 3; 51 | case shader_data_t::mat4 : return 1 * 4 * 4; 52 | case shader_data_t::ivec : return 1; 53 | case shader_data_t::ivec2 : return 1 * 2; 54 | case shader_data_t::ivec3 : return 1 * 3; 55 | case shader_data_t::ivec4 : return 1 * 4; 56 | case shader_data_t::bvec : return 1; 57 | case shader_data_t::bvec2 : return 1 * 2; 58 | case shader_data_t::bvec3 : return 1 * 3; 59 | case shader_data_t::bvec4 : return 1 * 4; 60 | 61 | default: 62 | case shader_data_t::none: REAL_CORE_ERROR("Unsupported data type: {}!", static_cast(type)); 63 | return 0; 64 | } 65 | // @formatter:on 66 | 67 | } 68 | 69 | [[nodiscard]] int32_t api_type() const noexcept 70 | { 71 | switch (Renderer::Api().Value()) 72 | { 73 | case RendererAPI::API::GL: 74 | return GLTypeFrom(type); 75 | 76 | default: 77 | case RendererAPI::API::None: 78 | REAL_CORE_ERROR("Invalid renderer api: {}", 79 | static_cast(RendererAPI::API::None)); 80 | return -1; 81 | } 82 | } 83 | }; 84 | 85 | class REAL_API BufferLayout 86 | { 87 | using container = std::vector; 88 | using iterator = container::iterator; 89 | using const_iterator = container::const_iterator; 90 | private: 91 | std::vector attributes; 92 | 93 | uint32_t stride = 0; 94 | public: 95 | BufferLayout(); 96 | BufferLayout(std::initializer_list attributes); 97 | 98 | //region Iterators 99 | [[nodiscard]] iterator begin() noexcept 100 | { return attributes.begin(); }; 101 | [[nodiscard]] const_iterator 102 | cbegin() const noexcept 103 | { return attributes.begin(); }; 104 | [[nodiscard]] const_iterator 105 | begin() const noexcept 106 | { return attributes.begin(); }; 107 | 108 | [[nodiscard]] iterator end() noexcept 109 | { return attributes.end(); }; 110 | [[nodiscard]] const_iterator end() const noexcept 111 | { return attributes.end(); }; 112 | [[nodiscard]] const_iterator cend() const noexcept 113 | { return attributes.end(); }; 114 | //endregion 115 | 116 | [[nodiscard]] std::vector Attributes() const 117 | { return this->attributes; } 118 | [[nodiscard]] uint32_t Stride() const 119 | { return this->stride; } 120 | 121 | private: 122 | void CalculateParams(); 123 | }; 124 | } 125 | 126 | #endif //REAL_BUFFER_LAYOUT 127 | -------------------------------------------------------------------------------- /engine/include/real/renderer/buffer_vertex.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 udv. All rights reserved. 2 | 3 | #ifndef REAL_VERTEX_BUFFER 4 | #define REAL_VERTEX_BUFFER 5 | 6 | #include 7 | 8 | #include "real/core.hpp" 9 | #include "real/renderer/base_rendering_context.hpp" 10 | #include "real/renderer/buffer_layout.hpp" 11 | 12 | namespace Real { 13 | class VertexArray; 14 | 15 | class REAL_API VertexBuffer { 16 | public: 17 | virtual ~VertexBuffer(); 18 | 19 | [[nodiscard]] virtual const BufferLayout &Layout() const = 0; 20 | 21 | virtual void Layout(std::initializer_list attributes) = 0; 22 | 23 | virtual void Bind() const = 0; 24 | virtual void Unbind() const = 0; 25 | public: 26 | static Real::Scope Make(float *data, uint32_t size); 27 | }; 28 | } 29 | 30 | #endif //REAL_VERTEX_BUFFER 31 | -------------------------------------------------------------------------------- /engine/include/real/renderer/camera.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 udv. All rights reserved. 2 | 3 | #ifndef REAL_CAMERA 4 | #define REAL_CAMERA 5 | 6 | #include 7 | #include 8 | 9 | #include "real/core.hpp" 10 | 11 | namespace Real 12 | { 13 | class REAL_API Camera 14 | { 15 | protected: 16 | glm::mat4 view; 17 | glm::mat4 projection; 18 | 19 | glm::mat4 cacheViewprojection; 20 | 21 | // TODO: migrate to quaternions 22 | glm::vec3 position; 23 | glm::vec3 direction; 24 | public: 25 | explicit Camera(const glm::mat4& projection = glm::identity(), 26 | glm::vec3 position = { 0.0f, 0.0f, 0.0f, }, 27 | glm::vec3 direction = { 0.0f, 0.0f, 0.0f, }); 28 | 29 | virtual void Init(); 30 | 31 | [[nodiscard]] virtual glm::vec3 Position() const noexcept 32 | { return this->position; }; 33 | virtual void Position(glm::vec3 _position) noexcept 34 | { 35 | this->position = _position; 36 | Update(); 37 | }; 38 | 39 | [[nodiscard]] glm::mat4 Projection() const noexcept 40 | { return this->projection; }; 41 | virtual void Projection(glm::mat4 _projection) noexcept 42 | { 43 | this->projection = _projection; 44 | UpdateViewprojection(); 45 | }; 46 | 47 | [[nodiscard]] virtual glm::mat4 View() const noexcept 48 | { return this->view; }; 49 | [[nodiscard]] virtual glm::mat4 Viewprojection() const noexcept 50 | { return this->cacheViewprojection; }; 51 | 52 | virtual void LookAt(glm::vec3 target); 53 | protected: 54 | virtual void Update(); 55 | virtual void UpdateView() = 0; 56 | virtual void UpdateViewprojection(); 57 | private: 58 | // Base vectors 59 | virtual glm::vec3 Up() const; 60 | virtual glm::vec3 Right() const; 61 | virtual glm::vec3 Direction() const; 62 | virtual glm::vec3 DirectionTo(glm::vec3 target) const; 63 | }; 64 | 65 | class REAL_API OrthographicCamera : public Camera 66 | { 67 | public: 68 | OrthographicCamera(float left, float right, float bottom, float top); 69 | private: 70 | virtual void UpdateView() override; 71 | }; 72 | 73 | class REAL_API PerspectiveCamera : public Camera 74 | { 75 | public: 76 | PerspectiveCamera(float yfov, float w, float h); 77 | private: 78 | virtual void UpdateView() override; 79 | }; 80 | } 81 | 82 | #endif //REAL_CAMERA 83 | -------------------------------------------------------------------------------- /engine/include/real/renderer/common.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 udv. All rights reserved. 2 | 3 | #ifndef REAL_RENDERER_COMMON 4 | #define REAL_RENDERER_COMMON 5 | 6 | #include "real/core.hpp" 7 | #include "real/logger.hpp" 8 | 9 | namespace Real 10 | { 11 | 12 | enum class shader_data_t : uint32_t 13 | { 14 | none = 0, 15 | vec, vec2, vec3, vec4, 16 | mat3, mat4, 17 | ivec, ivec2, ivec3, ivec4, 18 | bvec, bvec2, bvec3, bvec4, 19 | }; 20 | 21 | [[nodiscard]] static constexpr uint32_t sizeofsdt(shader_data_t type) noexcept 22 | { 23 | // @formatter:off 24 | switch (type) { 25 | case shader_data_t::vec : return 4; 26 | case shader_data_t::vec2 : return 4 * 2; 27 | case shader_data_t::vec3 : return 4 * 3; 28 | case shader_data_t::vec4 : return 4 * 4; 29 | case shader_data_t::mat3 : return 4 * 3 * 3; 30 | case shader_data_t::mat4 : return 4 * 4 * 4; 31 | case shader_data_t::ivec : return 4; 32 | case shader_data_t::ivec2 : return 4 * 2; 33 | case shader_data_t::ivec3 : return 4 * 3; 34 | case shader_data_t::ivec4 : return 4 * 4; 35 | case shader_data_t::bvec : return 1; 36 | case shader_data_t::bvec2 : return 1 * 2; 37 | case shader_data_t::bvec3 : return 1 * 3; 38 | case shader_data_t::bvec4 : return 1 * 4; 39 | 40 | default: 41 | case shader_data_t::none: REAL_CORE_ERROR("Unsupported data type: {}!", static_cast(type)); 42 | return 0; 43 | } 44 | // @formatter:on 45 | } 46 | } 47 | 48 | #endif //REAL_RENDERER_COMMON 49 | -------------------------------------------------------------------------------- /engine/include/real/renderer/light.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 udv. All rights reserved. 2 | 3 | #ifndef REAL_ENGINE_LIGHT 4 | #define REAL_ENGINE_LIGHT 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | #include "real/core.hpp" 11 | 12 | namespace Real 13 | { 14 | enum LightType 15 | { 16 | DIRECTIONAL_LIGHT, 17 | POINT_LIGHT, 18 | SPOTLIGHT, 19 | FLASHLIGHT, 20 | }; 21 | 22 | class REAL_API Light 23 | { 24 | public: 25 | // TODO: fix mess ? 26 | 27 | Light() 28 | :Light { 29 | { 1.0f, 1.0f, 1.0f, }, 30 | { 1.0f, 1.0f, 1.0f, }, 31 | { 1.0f, 1.0f, 1.0f, }, 32 | } 33 | {}; 34 | 35 | Light(const glm::vec3& ambient, const glm::vec3& diffuse, 36 | const glm::vec3& specular) 37 | :pos { 0.0f, 0.0f, 0.0f, }, 38 | direction { 0.0f, 0.0f, 0.0f, }, 39 | ambient { ambient }, 40 | diffuse { diffuse }, 41 | specular { specular } 42 | {} 43 | 44 | Light(glm::vec3&& ambient, glm::vec3&& diffuse, 45 | glm::vec3&& specular) 46 | :pos { 0.0f, 0.0f, 0.0f, }, 47 | direction { 0.0f, 0.0f, 0.0f, }, 48 | ambient { std::move(ambient) }, 49 | diffuse { std::move(diffuse) }, 50 | specular { std::move(specular) } 51 | {} 52 | 53 | const glm::vec3& Pos() const 54 | { return pos; } 55 | void Pos(const glm::vec3& pos_) 56 | { Light::pos = pos_; } 57 | 58 | const glm::vec3& Direction() const 59 | { return direction; } 60 | void Direction(const glm::vec3& dir_) 61 | { Light::direction = dir_; } 62 | 63 | const glm::vec3& Ambient() const 64 | { return ambient; } 65 | void Ambient(const glm::vec3& ambient_) 66 | { Light::ambient = ambient_; } 67 | 68 | const glm::vec3& Diffuse() const 69 | { return diffuse; } 70 | void Diffuse(const glm::vec3& diffuse_) 71 | { Light::diffuse = diffuse_; } 72 | 73 | const glm::vec3& Specular() const 74 | { return specular; } 75 | void Specular(const glm::vec3& specular_) 76 | { Light::specular = specular_; } 77 | 78 | // TODO: think about ImGui 79 | public: 80 | void ImGUIBegin() 81 | { 82 | ImGui::Text("Light"); 83 | ImGui::Separator(); 84 | ImGui::ColorEdit3("Light Ambient", glm::value_ptr(ambient)); 85 | ImGui::ColorEdit3("Light Diffuse", glm::value_ptr(diffuse)); 86 | ImGui::ColorEdit3("Light Specular", glm::value_ptr(specular)); 87 | } 88 | 89 | void ImGUIEnd() 90 | { 91 | ImGui::Separator(); 92 | } 93 | public: 94 | private: 95 | // TODO: add transform 96 | glm::vec3 pos; 97 | glm::vec3 direction; 98 | glm::vec3 ambient; 99 | glm::vec3 diffuse; 100 | glm::vec3 specular; 101 | Real::LightType type; 102 | }; 103 | } 104 | 105 | #endif //REAL_ENGINE_LIGHT 106 | -------------------------------------------------------------------------------- /engine/include/real/renderer/material.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 udv. All rights reserved. 2 | 3 | #ifndef REAL_ENGINE_MATERIAL 4 | #define REAL_ENGINE_MATERIAL 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | 12 | #include "real/core.hpp" 13 | #include "real/renderer/base_shader.hpp" 14 | 15 | namespace Real 16 | { 17 | // TODO: shader bindings? 18 | class REAL_API Material 19 | { 20 | public: 21 | Material() 22 | :Material { 23 | 32.0f, 24 | { 1.0f, 1.0f, 1.0f, }, 25 | { 1.0f, 1.0f, 1.0f, }, 26 | { 1.0f, 1.0f, 1.0f, }, 27 | } 28 | {}; 29 | 30 | Material(float shininess, const glm::vec3& ambient, const glm::vec3& diffuse, 31 | const glm::vec3& specular) 32 | :shininess { shininess }, ambient { ambient }, diffuse { diffuse }, 33 | specular { specular }, shader {} 34 | {} 35 | 36 | Material(float shininess, glm::vec3&& ambient, glm::vec3&& diffuse, 37 | glm::vec3&& specular) 38 | :shininess { shininess }, ambient { std::move(ambient) }, 39 | diffuse { std::move(diffuse) }, 40 | specular { std::move(specular) }, shader {} 41 | {} 42 | 43 | Material(float shininess, const glm::vec3& ambient, const glm::vec3& diffuse, 44 | const glm::vec3& specular, const Real::Reference& shader) 45 | :Material { shininess, ambient, diffuse, specular } 46 | { 47 | this->shader = shader; 48 | Update(); 49 | } 50 | 51 | Material(float shininess, glm::vec3&& ambient, glm::vec3&& diffuse, 52 | glm::vec3&& specular, const Real::Reference& shader) 53 | :Material { shininess, ambient, diffuse, specular } 54 | { 55 | this->shader = shader; 56 | Update(); 57 | } 58 | 59 | float Shininess() const 60 | { return shininess; } 61 | void Shininess(float shininess_) 62 | { 63 | Material::shininess = shininess_; 64 | shader->Bind(); 65 | shader->UniformFloat("u_Material.shininess", shininess); 66 | } 67 | 68 | const glm::vec3& Ambient() const 69 | { return ambient; } 70 | void Ambient(const glm::vec3& ambient_) 71 | { 72 | Material::ambient = ambient_; 73 | shader->Bind(); 74 | shader->UniformFloat("u_Material.ambient", ambient); 75 | } 76 | 77 | const glm::vec3& Diffuse() const 78 | { return diffuse; } 79 | void Diffuse(const glm::vec3& diffuse_) 80 | { 81 | Material::diffuse = diffuse_; 82 | shader->Bind(); 83 | shader->UniformFloat("u_Material.diffuse", diffuse); 84 | } 85 | 86 | const glm::vec3& Specular() const 87 | { return specular; } 88 | void Specular(const glm::vec3& specular_) 89 | { Material::specular = specular_; } 90 | 91 | void ImGUIBegin() 92 | { 93 | ImGui::Text("Material"); 94 | ImGui::Separator(); 95 | ImGui::SliderFloat("Material Shininess", &shininess, 32.0f, 256.0f, 96 | "%.0f"); 97 | ImGui::ColorEdit3("Material Ambient", glm::value_ptr(ambient)); 98 | ImGui::ColorEdit3("Material Diffuse", glm::value_ptr(diffuse)); 99 | ImGui::ColorEdit3("Material Specular", glm::value_ptr(specular)); 100 | } 101 | 102 | void ImGUIEnd() 103 | { 104 | ImGui::Separator(); 105 | } 106 | 107 | const Real::Reference& Shader() const 108 | { return shader; } 109 | void Rebind(const Real::Reference& new_shader) 110 | { 111 | *this = Real::Material { shininess, ambient, diffuse, specular, new_shader }; 112 | } 113 | 114 | void Update() const 115 | { 116 | // TODO: upgrade this 117 | shader->Bind(); 118 | shader->UniformFloat("u_Material.ambient", ambient); 119 | shader->UniformFloat("u_Material.diffuse", diffuse); 120 | shader->UniformFloat("u_Material.specular", specular); 121 | shader->UniformFloat("u_Material.shininess", shininess); 122 | } 123 | private: 124 | float shininess; 125 | glm::vec3 ambient; 126 | glm::vec3 diffuse; 127 | glm::vec3 specular; 128 | 129 | Real::Reference shader; 130 | }; 131 | } 132 | 133 | #endif //REAL_ENGINE_MATERIAL 134 | -------------------------------------------------------------------------------- /engine/include/real/renderer/render_command.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 udv. All rights reserved. 2 | 3 | #ifndef REAL_RENDER_COMMAND 4 | #define REAL_RENDER_COMMAND 5 | 6 | #include 7 | 8 | #include "real/core.hpp" 9 | #include "real/renderer/array_vertex.hpp" 10 | 11 | namespace Real 12 | { 13 | class REAL_API RenderCommand 14 | { 15 | public: 16 | static void ClearColor(glm::fvec4 color) 17 | { 18 | Renderer::Api().ClearColor(color); 19 | } 20 | 21 | static void Init() 22 | { 23 | Renderer::Api().Init(); 24 | } 25 | 26 | static void Clear() 27 | { 28 | Renderer::Api().clear(); 29 | } 30 | 31 | static void DrawIndexed(const Real::Reference& vertexArray) 32 | { 33 | Renderer::Api().DrawIndexed(vertexArray); 34 | } 35 | }; 36 | } 37 | 38 | #endif //REAL_RENDER_COMMAND 39 | -------------------------------------------------------------------------------- /engine/include/real/renderer/renderer_api.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 udv. All rights reserved. 2 | 3 | #ifndef REAL_RENDERER_API 4 | #define REAL_RENDERER_API 5 | 6 | #include 7 | #include 8 | 9 | #include "real/core.hpp" 10 | 11 | namespace Real { 12 | class VertexArray; 13 | 14 | class REAL_API RendererAPI { 15 | public: 16 | enum class API { 17 | None = 0, 18 | GL = 1, 19 | }; 20 | public: 21 | virtual void Init() = 0; 22 | virtual void ClearColor(glm::fvec4 color) = 0; 23 | void clear() { Clear(DefaultClearBits()); }; 24 | virtual void Clear(int32_t bits) = 0; 25 | 26 | [[nodiscard]] virtual API Value() const = 0; 27 | 28 | virtual void DrawIndexed(const Real::Reference &vao) = 0; 29 | private: 30 | [[nodiscard]] virtual constexpr int32_t DefaultClearBits() const noexcept = 0; 31 | // static api api_; 32 | }; 33 | } 34 | 35 | #endif //REAL_RENDERER_API 36 | -------------------------------------------------------------------------------- /engine/include/real/renderer/shaders/base.glsl: -------------------------------------------------------------------------------- 1 | #shader vertex 2 | #version 330 core 3 | 4 | layout(location = 0) in vec3 _pos; 5 | layout(location = 1) in vec3 _normal; 6 | layout(location = 2) in vec4 _color; 7 | 8 | uniform mat4 u_vp; 9 | uniform mat4 u_model; 10 | 11 | out vec3 v_pos; 12 | out vec3 v_normal; 13 | out vec4 v_color; 14 | 15 | void main() { 16 | gl_Position = u_vp * u_model * vec4(_pos.xyz, 1.0); 17 | 18 | // @formatter:off 19 | v_pos = _pos; 20 | v_color = _color; 21 | v_normal = _normal; 22 | // @formatter:on 23 | } 24 | 25 | #shader fragment 26 | #version 330 core 27 | in vec3 v_pos; 28 | in vec3 v_normal; 29 | in vec4 v_color; 30 | 31 | uniform vec4 u_color; 32 | uniform vec4 u_lightColor; 33 | 34 | out vec4 color_; 35 | 36 | void main() { 37 | color_ = u_lightColor * v_color; 38 | } -------------------------------------------------------------------------------- /engine/include/real/renderer/shaders/material.glsl: -------------------------------------------------------------------------------- 1 | #shader vertex 2 | #version 330 core 3 | 4 | layout(location = 0) in vec3 _pos; 5 | layout(location = 1) in vec3 _normal; 6 | 7 | uniform mat4 u_vp; 8 | uniform mat4 u_model; 9 | 10 | out vec3 FragPos; 11 | out vec3 FragNormal; 12 | 13 | void main() { 14 | vec4 o_pos = u_model * vec4(_pos.xyz, 1.0); 15 | gl_Position = u_vp * o_pos; 16 | 17 | // @formatter:off 18 | FragPos = vec3(o_pos); 19 | FragNormal = mat3(transpose(inverse(u_model))) * _normal; // TODO: calcaulate this in CPU 20 | // @formatter:on 21 | } 22 | 23 | #shader fragment 24 | #version 330 core 25 | 26 | struct Material { 27 | vec3 ambient; 28 | vec3 diffuse; 29 | vec3 specular; 30 | float shininess; 31 | }; 32 | 33 | struct Light { 34 | vec3 position; 35 | 36 | vec3 ambient; 37 | vec3 diffuse; 38 | vec3 specular; 39 | }; 40 | 41 | in vec3 FragPos; 42 | in vec3 FragNormal; 43 | 44 | uniform vec3 u_viewPos; 45 | uniform Material u_Material; 46 | uniform Light u_Light; 47 | 48 | out vec4 color_; 49 | 50 | void main() { 51 | // vec3 outColor = vec3(0.0f); 52 | // outColor += calculateDirectionalLight(); 53 | // for (int i = 0; i < nr_of_point_lights; i++) { 54 | // outColor += calculatePointLight(); 55 | // } 56 | // outColor += calculateSpotLight(); 57 | 58 | vec3 normal = normalize(FragNormal); 59 | 60 | // TODO: view space calculations? 61 | // Diffuse Lighting 62 | vec3 lightDir = normalize(u_Light.position - FragPos); 63 | float diff = max(dot(normal, lightDir), 0.0f); 64 | 65 | // Specular Lighting 66 | vec3 viewDir = normalize(u_viewPos - FragPos); 67 | vec3 reflectDir = reflect(-lightDir, normal); 68 | float spec = pow(max(dot(viewDir, reflectDir), 0.0f), u_Material.shininess); 69 | 70 | // Components 71 | vec3 ambient = u_Light.ambient * u_Material.ambient; 72 | vec3 diffuse = u_Light.diffuse * (diff * u_Material.diffuse); 73 | vec3 specular = u_Light.specular * (spec * u_Material.specular); 74 | 75 | vec3 result = ambient + diffuse + specular; 76 | color_ = vec4(result, 1.0f); 77 | } -------------------------------------------------------------------------------- /engine/include/real/renderer/shaders/tex.glsl: -------------------------------------------------------------------------------- 1 | #shader fragment 2 | #version 330 core 3 | 4 | in vec3 v_pos; 5 | in vec2 v_texcoord; 6 | 7 | uniform sampler2D u_texture; 8 | uniform vec4 u_color; 9 | 10 | out vec4 color_; 11 | 12 | void main() { 13 | color_ = texture(u_texture, v_texcoord); 14 | } 15 | 16 | #shader vertex 17 | #version 330 core 18 | 19 | layout(location = 0) in vec3 _pos; 20 | layout(location = 1) in vec2 _texcoord; 21 | 22 | uniform mat4 u_vp; 23 | uniform mat4 u_model; 24 | 25 | out vec3 v_pos; 26 | out vec2 v_texcoord; 27 | 28 | void main() { 29 | v_pos = _pos; 30 | v_texcoord = _texcoord; 31 | gl_Position = u_vp * u_model * vec4(_pos.xyz, 1.0); 32 | } 33 | -------------------------------------------------------------------------------- /engine/include/real/time.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 udv. All rights reserved. 2 | 3 | #ifndef REAL_TIME 4 | #define REAL_TIME 5 | 6 | #include "real/time/timestep.hpp" 7 | 8 | #ifdef REAL_PLATFORM_WINDOWS 9 | #include "real/platform/windows/windows_time.hpp" 10 | #else 11 | #error Unsupported platform! 12 | #endif 13 | 14 | namespace Real 15 | { 16 | inline double Time() 17 | { return Real::Platform::Time(); }; 18 | } 19 | 20 | #endif //REAL_TIME 21 | -------------------------------------------------------------------------------- /engine/include/real/time/timestep.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 udv. All rights reserved. 2 | 3 | #ifndef REAL_TIMESTEP 4 | #define REAL_TIMESTEP 5 | 6 | #include "real/core.hpp" 7 | 8 | namespace Real { 9 | class REAL_API Timestep { 10 | public: 11 | Timestep(double time = 0.0f) :time_{ time } {} 12 | 13 | [[nodiscard]] float seconds() const { return time_; }; 14 | [[nodiscard]] float milliseconds() const { return time_ * 1000.0f; }; 15 | private: 16 | double time_; 17 | }; 18 | } 19 | 20 | #endif //REAL_TIMESTEP 21 | -------------------------------------------------------------------------------- /engine/include/real/transform.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 udv. All rights reserved. 2 | 3 | #ifndef REAL_TRANSFORM 4 | #define REAL_TRANSFORM 5 | 6 | #include 7 | #include 8 | 9 | #include "real/core.hpp" 10 | 11 | namespace Real 12 | { 13 | class REAL_API Transform 14 | { 15 | public: 16 | Transform(glm::mat4&& transform = glm::identity()) 17 | :transformMat { std::move(transform) } 18 | {} 19 | 20 | Transform(const glm::mat4& transform = glm::identity()) 21 | :transformMat { transform } 22 | {} 23 | 24 | [[nodiscard]] glm::mat4 Matrix() const noexcept 25 | { return transformMat; } 26 | private: 27 | glm::mat4 transformMat; 28 | }; 29 | } 30 | 31 | #endif //REAL_TRANSFORM 32 | -------------------------------------------------------------------------------- /engine/include/real/util/singleton.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 udv. All rights reserved. 2 | 3 | #ifndef REAL_SINGLETON 4 | #define REAL_SINGLETON 5 | 6 | namespace Real 7 | { 8 | template 9 | class Singleton 10 | { 11 | using type = Singleton; 12 | private: 13 | static T* instance; 14 | public: 15 | Singleton() 16 | { 17 | real_msg_assert(instance == nullptr, 18 | "Only one instance of singleton is allowed!"); 19 | instance = static_cast(this); 20 | } 21 | 22 | ~Singleton() 23 | { 24 | instance = nullptr; 25 | } 26 | 27 | static T& Instance() 28 | { 29 | return *instance; 30 | } 31 | 32 | // region Forbidden Operations 33 | Singleton(type&) = delete; 34 | void operator=(const type&) = delete; 35 | // endregion 36 | }; 37 | 38 | template T* Singleton::instance = nullptr; 39 | } 40 | 41 | // region util macros 42 | #define SINGLETON(x) x : public Real::Singleton 43 | // endregion 44 | 45 | #endif //REAL_SINGLETON 46 | -------------------------------------------------------------------------------- /engine/include/real/window.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 udv. All rights reserved. 2 | 3 | #ifndef REAL_WINDOW 4 | #define REAL_WINDOW 5 | 6 | #include "real/core.hpp" 7 | #include "real/window/base_window.hpp" 8 | 9 | #ifdef REAL_PLATFORM_WINDOWS 10 | #include "real/platform/windows/windows_window.hpp" 11 | #else 12 | #error Unsupported platform! 13 | #endif 14 | 15 | #endif //REAL_WINDOW 16 | -------------------------------------------------------------------------------- /engine/include/real/window/base_window.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 udv. All rights reserved. 2 | 3 | #ifndef REAL_WINDOW_BASE 4 | #define REAL_WINDOW_BASE 5 | 6 | #include "real/time/timestep.hpp" 7 | 8 | #include "real/core.hpp" 9 | #include "real/event.hpp" 10 | #include "real/renderer.hpp" 11 | 12 | namespace Real 13 | { 14 | 15 | using event_callback_t = std::function; 16 | 17 | namespace Platform 18 | { 19 | // To be defined per platform 20 | struct WindowData; 21 | } 22 | 23 | struct WindowProperties 24 | { 25 | std::string title; 26 | window_dimension_t width; 27 | window_dimension_t height; 28 | 29 | explicit WindowProperties(std::string title = REAL_DEFAULT_WINDOW_TITLE, 30 | window_dimension_t width = REAL_DEFAULT_WINDOW_WIDTH, 31 | window_dimension_t height = REAL_DEFAULT_WINDOW_HEIGHT) 32 | :title { std::move(title) }, width { width }, height { height } 33 | {} 34 | }; 35 | 36 | class REAL_API Window 37 | { 38 | public: 39 | virtual ~Window(); 40 | 41 | virtual void OnUpdate(Timestep ts); 42 | 43 | virtual void Init() = 0; 44 | 45 | [[nodiscard]] virtual window_dimension_t Width() const = 0; 46 | [[nodiscard]] virtual window_dimension_t Height() const = 0; 47 | 48 | virtual void EventCallback(const event_callback_t& callback) = 0; 49 | virtual void VSync(bool enabled) = 0; 50 | [[nodiscard]] virtual bool IsVSync() const = 0; 51 | 52 | virtual void* Native() const = 0; 53 | virtual RenderingContext* Context() const = 0; 54 | 55 | // Generates window depending on platform 56 | static Real::Scope Make(const WindowProperties& props); 57 | }; 58 | } 59 | 60 | #endif //REAL_WINDOW_BASE 61 | -------------------------------------------------------------------------------- /engine/src/api/gl/gl_array_vertex.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 udv. All rights reserved. 2 | 3 | #include "real/api/gl/gl_headers.hpp" 4 | #include "real/api/gl/gl_array_vertex.hpp" 5 | #include "real/api/gl/gl_buffer_vertex.hpp" 6 | #include "real/api/gl/gl_buffer_index.hpp" 7 | 8 | namespace Real 9 | { 10 | GLVertexArray::GLVertexArray() 11 | :rendererId { 0 }, vertexBuffers {}, indexBuffers {}, count { 0 } 12 | { 13 | glCreateVertexArrays(1, &rendererId); 14 | } 15 | 16 | GLVertexArray::~GLVertexArray() 17 | { 18 | glDeleteVertexArrays(1, &rendererId); 19 | } 20 | 21 | void GLVertexArray::AddVertexBuffer( 22 | const Real::Reference& buffer) 23 | { 24 | real_msg_assert(!buffer->Layout().Attributes().empty(), 25 | "Vertex buffer has no Layout!"); 26 | 27 | glBindVertexArray(rendererId); 28 | buffer->Bind(); 29 | 30 | uint32_t index = 0; 31 | for (auto& a: buffer->Layout()) 32 | { 33 | glEnableVertexAttribArray(index); 34 | glVertexAttribPointer(index, a.component_count(), 35 | a.api_type(), 36 | a.normalized ? GL_TRUE : GL_FALSE, 37 | buffer->Layout().Stride(), (const void*)a.offset); 38 | 39 | ++index; 40 | } 41 | 42 | vertexBuffers.push_back(buffer); 43 | } 44 | 45 | void GLVertexArray::AddIndexBuffer(const Real::Reference& buffer) 46 | { 47 | glBindVertexArray(rendererId); 48 | buffer->Bind(); 49 | count += buffer->Count(); 50 | 51 | indexBuffers.push_back(buffer); 52 | } 53 | 54 | void GLVertexArray::Bind() const 55 | { 56 | glBindVertexArray(rendererId); 57 | } 58 | 59 | void GLVertexArray::Unbind() const 60 | { 61 | glBindVertexArray(0); 62 | } 63 | 64 | int32_t GLVertexArray::Count() const 65 | { 66 | return count; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /engine/src/api/gl/gl_buffer_index.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 udv. All rights reserved. 2 | 3 | #include "real/api/gl/gl_headers.hpp" 4 | #include "real/api/gl/gl_buffer_index.hpp" 5 | 6 | namespace Real 7 | { 8 | 9 | GLIndexBuffer::GLIndexBuffer(uint32_t* data, uint32_t size) 10 | :rendererId { 0 }, count { size } 11 | { 12 | glCreateBuffers(1, &rendererId); 13 | // TODO: remove hardcoded buffer data usage 14 | glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, rendererId); 15 | glBufferData(GL_ELEMENT_ARRAY_BUFFER, count * sizeof(uint32_t), data, 16 | GL_DYNAMIC_DRAW); 17 | } 18 | 19 | GLIndexBuffer::~GLIndexBuffer() 20 | { 21 | glDeleteBuffers(1, &rendererId); 22 | } 23 | 24 | void GLIndexBuffer::Bind() const 25 | { 26 | glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, rendererId); 27 | } 28 | 29 | void GLIndexBuffer::Unbind() const 30 | { 31 | glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); 32 | } 33 | 34 | uint32_t GLIndexBuffer::Count() const 35 | { 36 | return count; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /engine/src/api/gl/gl_buffer_vertex.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 udv. All rights reserved. 2 | 3 | #include "real/api/gl/gl_headers.hpp" 4 | #include "real/api/gl/gl_buffer_vertex.hpp" 5 | 6 | namespace Real 7 | { 8 | 9 | GLVertexBuffer::GLVertexBuffer(float* data, uint32_t size) 10 | :rendererId { 0 }, bufferLayout {} 11 | { 12 | glCreateBuffers(1, &rendererId); 13 | // TODO: remove hardcoded buffer data usage 14 | glBindBuffer(GL_ARRAY_BUFFER, rendererId); 15 | glBufferData(GL_ARRAY_BUFFER, size, data, GL_DYNAMIC_DRAW); 16 | } 17 | 18 | GLVertexBuffer::~GLVertexBuffer() 19 | { 20 | glDeleteBuffers(1, &rendererId); 21 | } 22 | 23 | void GLVertexBuffer::Bind() const 24 | { 25 | glBindBuffer(GL_ARRAY_BUFFER, rendererId); 26 | } 27 | 28 | void GLVertexBuffer::Unbind() const 29 | { 30 | glBindBuffer(GL_ARRAY_BUFFER, 0); 31 | } 32 | 33 | void GLVertexBuffer::Layout(std::initializer_list attributes) 34 | { 35 | bufferLayout = BufferLayout { attributes }; 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /engine/src/api/gl/gl_renderer_api.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 udv. All rights reserved. 2 | 3 | #include 4 | 5 | #include "real/api/gl/gl_headers.hpp" 6 | #include "real/api/gl/gl_renderer_api.hpp" 7 | 8 | namespace Real 9 | { 10 | 11 | void GLRendererApi::Init() 12 | { 13 | // Multisampling 14 | glEnable(GL_MULTISAMPLE); 15 | 16 | // Blending 17 | glEnable(GL_BLEND); 18 | glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 19 | 20 | // Extensions 21 | glEnable(GL_EXT_direct_state_access); 22 | 23 | // Enable depth test 24 | glEnable(GL_DEPTH_TEST); 25 | // Accept fragment if it closer to the camera than the former one 26 | glDepthFunc(GL_LESS); 27 | } 28 | 29 | void GLRendererApi::ClearColor(glm::fvec4 color) 30 | { 31 | glClearColor(color.r, color.g, color.b, color.a); 32 | } 33 | 34 | void GLRendererApi::Clear(int32_t bits) 35 | { 36 | glClear(bits); 37 | } 38 | 39 | void GLRendererApi::DrawIndexed(const Real::Reference& vao) 40 | { 41 | vao->Bind(); 42 | glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); // TODO: remove poly mode 43 | // glEnable(GL_DEPTH_TEST); 44 | // TODO: remove hardcoded mode 45 | glDrawElements(GL_TRIANGLES, vao->Count(), GL_UNSIGNED_INT, nullptr); 46 | } 47 | 48 | RendererAPI::API GLRendererApi::Value() const 49 | { 50 | return API::GL; 51 | } 52 | 53 | int32_t GLRendererApi::DefaultClearBits() const noexcept 54 | { 55 | return (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /engine/src/api/gl/gl_rendering_context.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 udv. All rights reserved. 2 | 3 | #include "real/logger.hpp" 4 | #include "real/api/gl/gl_headers.hpp" 5 | #include "real/api/gl/gl_rendering_context.hpp" 6 | 7 | namespace Real 8 | { 9 | GLRenderingContext::GLRenderingContext(GLFWwindow* windowHandle) 10 | { 11 | this->glfwWindowHandle = windowHandle; 12 | } 13 | 14 | GLRenderingContext::~GLRenderingContext() 15 | { 16 | REAL_CORE_TRACE("Destroying rendering context..."); 17 | glfwDestroyWindow(glfwWindowHandle); 18 | glfwTerminate(); 19 | } 20 | 21 | void GLRenderingContext::Init() 22 | { 23 | REAL_CORE_TRACE("Initializing GL rendering context..."); 24 | 25 | glfwMakeContextCurrent(glfwWindowHandle); 26 | 27 | if (glfwWindowHandle == nullptr) 28 | { 29 | REAL_CORE_ERROR("Failed to create window(handle is nullptr)!"); 30 | glfwTerminate(); 31 | std::terminate(); 32 | } 33 | 34 | // Glad 35 | REAL_CORE_TRACE("Loading GL..."); 36 | if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) 37 | { 38 | REAL_CORE_ERROR("Couldn't load GL!"); 39 | glfwTerminate(); 40 | std::terminate(); 41 | } 42 | REAL_CORE_INFO("Loaded GL successfully!"); 43 | 44 | // Info 45 | REAL_CORE_INFO( 46 | "\nOpenGL info:\n" 47 | "\tVendor : {}\n" 48 | "\tRenderer: {}\n" 49 | "\tVersion : {}", 50 | reinterpret_cast(glGetString(GL_VENDOR)), 51 | reinterpret_cast(glGetString(GL_RENDERER)), 52 | reinterpret_cast(glGetString(GL_VERSION)) 53 | ); 54 | } 55 | 56 | void GLRenderingContext::SwapBuffers() 57 | { 58 | glfwSwapBuffers(glfwWindowHandle); 59 | } 60 | 61 | void GLRenderingContext::VSync(bool enabled) 62 | { 63 | if (enabled) 64 | { 65 | glfwSwapInterval(1); 66 | } 67 | else 68 | { 69 | glfwSwapInterval(0); 70 | } 71 | } 72 | } -------------------------------------------------------------------------------- /engine/src/api/gl/gl_shader.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 udv. All rights reserved. 2 | 3 | 4 | 5 | #include 6 | 7 | #include "real/api/gl/gl_conversions.hpp" 8 | #include "real/api/gl/gl_shader.hpp" 9 | #include "real/logger.hpp" 10 | 11 | #define SYM_EOL "\r\n" 12 | 13 | namespace Real 14 | { 15 | 16 | GLShader::GLShader(const std::string& filename) 17 | :programId { 0 }, shaders {} 18 | { 19 | programId = glCreateProgram(); 20 | auto start = filename.find_last_of("/\\"); 21 | start = (start == std::string::npos) ? 0 : start + 1; 22 | auto end = filename.rfind("."); 23 | auto size = end == std::string::npos ? filename.size() - start : end - start; 24 | shaderName = filename.substr(start, size); 25 | 26 | std::string sources = ReadFile(filename); 27 | Preprocess(sources); 28 | const auto& shader_srcs = Split(sources); 29 | Compile(shader_srcs); 30 | Link(); 31 | } 32 | 33 | void GLShader::Bind() const 34 | { 35 | glUseProgram(programId); 36 | } 37 | 38 | void GLShader::Unbind() const 39 | { 40 | glUseProgram(0); 41 | } 42 | 43 | GLShader::~GLShader() 44 | { 45 | glDeleteProgram(programId); 46 | } 47 | 48 | // region Uniforms 49 | // IMP: migrate to "uniform" form 50 | // TODO: read uniforms from shader source code 51 | 52 | GLint GLShader::LocationOf(const std::string& name) const 53 | { 54 | if (uniformLocationsCache.find(name) != uniformLocationsCache.end()) 55 | { 56 | return uniformLocationsCache[name]; 57 | } 58 | 59 | GLint location = glGetUniformLocation(programId, name.c_str()); 60 | uniformLocationsCache[name] = location; 61 | return location; 62 | } 63 | 64 | void GLShader::UniformFloat(const std::string& name, glm::f32 value) 65 | { 66 | GLint location = LocationOf(name); 67 | glUniform1fv(location, 1, &value); 68 | } 69 | 70 | void GLShader::UniformFloat(const std::string& name, const glm::fvec2& value) 71 | { 72 | GLint location = LocationOf(name); 73 | glUniform2fv(location, 1, glm::value_ptr(value)); 74 | } 75 | 76 | void GLShader::UniformFloat(const std::string& name, const glm::fvec3& value) 77 | { 78 | GLint location = LocationOf(name); 79 | glUniform3fv(location, 1, glm::value_ptr(value)); 80 | } 81 | 82 | void GLShader::UniformFloat(const std::string& name, const glm::fvec4& value) 83 | { 84 | GLint location = LocationOf(name); 85 | glUniform4fv(location, 1, glm::value_ptr(value)); 86 | } 87 | 88 | void GLShader::UniformMatrix(const std::string& name, const glm::fmat3& matrix) 89 | { 90 | GLint location = LocationOf(name); 91 | glUniformMatrix3fv(location, 1, GL_FALSE, glm::value_ptr(matrix)); 92 | } 93 | 94 | void GLShader::UniformMatrix(const std::string& name, const glm::fmat4& matrix) 95 | { 96 | GLint location = LocationOf(name); 97 | glUniformMatrix4fv(location, 1, GL_FALSE, glm::value_ptr(matrix)); 98 | } 99 | 100 | void GLShader::UniformInt(const std::string& name, glm::int32 value) 101 | { 102 | GLint location = LocationOf(name); 103 | glUniform1iv(location, 1, &value); 104 | } 105 | 106 | void GLShader::UniformInt(const std::string& name, const glm::ivec2& value) 107 | { 108 | GLint location = LocationOf(name); 109 | glUniform2iv(location, 1, glm::value_ptr(value)); 110 | } 111 | 112 | void GLShader::UniformInt(const std::string& name, const glm::ivec3& value) 113 | { 114 | GLint location = LocationOf(name); 115 | glUniform3iv(location, 1, glm::value_ptr(value)); 116 | } 117 | 118 | void GLShader::UniformInt(const std::string& name, const glm::ivec4& value) 119 | { 120 | GLint location = LocationOf(name); 121 | glUniform3iv(location, 1, glm::value_ptr(value)); 122 | } 123 | // endregion 124 | 125 | //region Helpers 126 | void GLShader::Preprocess(std::string& source) const 127 | { 128 | // TODO: add preprocessing step 129 | } 130 | 131 | std::unordered_map 132 | GLShader::Split(const std::string& source) const 133 | { 134 | real_msg_assert(count < shaders.size(), "Reached max shaders count!"); 135 | std::unordered_map shader_sources; 136 | 137 | const char* token_type = "#shader"; 138 | auto pos = source.find(token_type); 139 | while (pos != std::string::npos) 140 | { 141 | auto eol = source.find_first_of(SYM_EOL, pos); 142 | real_msg_assert(eol != std::string::npos, GL_SYNTAX_ERROR_MESSAGE); 143 | auto begin = pos + std::strlen(token_type) + 1; 144 | std::string typestr = source.substr(begin, eol - begin); 145 | 146 | GLenum type = GLShaderTypeFrom(typestr); 147 | real_msg_assert(type, "Invalid shader type specified"); 148 | 149 | auto shader_code_start = source.find_first_not_of(SYM_EOL, eol); 150 | real_msg_assert(shader_code_start != std::string::npos, 151 | GL_SYNTAX_ERROR_MESSAGE); 152 | pos = source.find(token_type, shader_code_start); 153 | 154 | shader_sources[type] = (pos == std::string::npos) 155 | ? source.substr(shader_code_start) 156 | : source.substr(shader_code_start, 157 | pos - shader_code_start); 158 | } 159 | 160 | return shader_sources; 161 | } 162 | 163 | void GLShader::Compile( 164 | const std::unordered_map& shader_srcs) 165 | { 166 | for (auto it = shader_srcs.begin(); it != shader_srcs.end(); ++it) 167 | { 168 | auto type = it->first; 169 | auto src = it->second; 170 | const GLchar* const source_buffer = src.c_str(); 171 | 172 | GLuint shader_id; 173 | shader_id = glCreateShader(type); 174 | glShaderSource(shader_id, 1, &source_buffer, nullptr); 175 | glCompileShader(shader_id); 176 | CheckHandleShaderError(shader_id, GL_COMPILE_STATUS); 177 | shaders[count++] = shader_id; 178 | } 179 | } 180 | 181 | void GLShader::Link() const 182 | { 183 | for (size_t i = 0; i < count; ++i) 184 | { 185 | glAttachShader(programId, shaders[i]); 186 | } 187 | 188 | glLinkProgram(programId); 189 | CheckHandleProgramError(programId, GL_LINK_STATUS); 190 | 191 | for (size_t i = 0; i < count; ++i) 192 | { 193 | glDeleteShader(shaders[i]); 194 | } 195 | } 196 | 197 | std::string GLShader::ReadFile(const std::string& filepath) 198 | { 199 | 200 | std::string result; 201 | std::ifstream in(filepath, std::ios::in | std::ios::binary); 202 | if (in) 203 | { 204 | in.seekg(0, std::ios::end); 205 | int32_t size = in.tellg(); 206 | if (size != -1) 207 | { 208 | result.resize(size); 209 | in.seekg(0, std::ios::beg); 210 | in.read(&result[0], size); 211 | } 212 | else 213 | { 214 | REAL_CORE_ERROR("Could not read from file '{0}'", filepath); 215 | } 216 | } 217 | else 218 | { 219 | REAL_CORE_ERROR("Could not open file '{0}'", filepath); 220 | } 221 | 222 | return result; 223 | } 224 | 225 | void GLShader::CheckHandleShaderError(GLuint id, GLenum action) 226 | { 227 | int success; 228 | char info_log[512]; 229 | glGetShaderiv(id, action, &success); 230 | if (!success) 231 | { 232 | glGetShaderInfoLog(id, 512, nullptr, info_log); 233 | REAL_CORE_ERROR("GL Shader error: {}", info_log); 234 | } 235 | } 236 | 237 | void GLShader::CheckHandleProgramError(GLuint id, GLenum action) 238 | { 239 | int success; 240 | char info_log[512]; 241 | glGetProgramiv(id, action, &success); 242 | if (!success) 243 | { 244 | glGetProgramInfoLog(id, 512, nullptr, info_log); 245 | REAL_CORE_ERROR("GL Shader Program error: {}", info_log); 246 | } 247 | 248 | } 249 | //endregion 250 | } 251 | -------------------------------------------------------------------------------- /engine/src/api/gl/gl_texture.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 udv. All rights reserved. 2 | 3 | #include 4 | 5 | #include "real/logger.hpp" 6 | #include "real/api/gl/gl_headers.hpp" 7 | #include "real/api/gl/gl_texture.hpp" 8 | 9 | namespace Real 10 | { 11 | // region GL Texture2D 12 | GLTexture2D::GLTexture2D(const std::string& path) 13 | :path { path }, width { 0 }, height { 0 }, rendererId { 0 } 14 | {} 15 | 16 | void GLTexture2D::Init() 17 | { 18 | int w, h, channels; 19 | stbi_set_flip_vertically_on_load(true); 20 | stbi_uc* data = stbi_load(path.c_str(), &w, &h, &channels, 0); 21 | real_msg_assert(data, "Failed to load texture image!"); 22 | width = w; 23 | height = h; 24 | 25 | GLenum format_internal = 0, format_data = 0; 26 | if (channels == 4) 27 | { 28 | format_internal = GL_RGBA8; 29 | format_data = GL_RGBA; 30 | } 31 | else if (channels == 3) 32 | { 33 | format_internal = GL_RGB8; 34 | format_data = GL_RGB; 35 | } 36 | 37 | real_msg_assert(format_internal & format_data, "Format not supported!"); 38 | 39 | glCreateTextures(GL_TEXTURE_2D, 1, &rendererId); 40 | glTextureStorage2D(rendererId, 1, format_internal, width, height); 41 | glBindTexture(GL_TEXTURE_2D, rendererId); 42 | 43 | // TODO: add API support for parameters 44 | glTextureParameteri(rendererId, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 45 | glTextureParameteri(rendererId, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 46 | 47 | glTextureParameteri(rendererId, GL_TEXTURE_WRAP_S, GL_REPEAT); 48 | glTextureParameteri(rendererId, GL_TEXTURE_WRAP_T, GL_REPEAT); 49 | 50 | glTextureSubImage2D( 51 | rendererId, 0, 52 | 0, 0, width, height, 53 | format_data, 54 | GL_UNSIGNED_BYTE, data 55 | ); 56 | glGenerateMipmap(GL_TEXTURE_2D); 57 | 58 | stbi_image_free(data); 59 | } 60 | 61 | GLTexture2D::~GLTexture2D() 62 | { 63 | glDeleteTextures(1, &rendererId); 64 | } 65 | 66 | void GLTexture2D::Bind(uint32_t slot) const 67 | { 68 | glBindTextureUnit(slot, rendererId); 69 | } 70 | // endregion 71 | } 72 | -------------------------------------------------------------------------------- /engine/src/api/gl/imgui_build.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 udv. All rights reserved. 2 | 3 | #include 4 | #include 5 | -------------------------------------------------------------------------------- /engine/src/application.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 udv. All rights reserved. 2 | 3 | 4 | 5 | #include "real/application.hpp" 6 | 7 | namespace Real 8 | { 9 | 10 | Application::Application(std::string name) 11 | :Singleton {}, 12 | name { std::move(name) } 13 | { 14 | // Setup systems 15 | WindowProperties props {}; 16 | window = Window::Make(props); 17 | input = Input::Make(); 18 | 19 | window->Init(); 20 | window->EventCallback([this](Event& e) 21 | { 22 | Application::OnEvent(e); 23 | }); 24 | 25 | Renderer::Init(); 26 | 27 | imGUILayer = new Real::ImGUILayer {}; 28 | PushOverlay(imGUILayer); 29 | } 30 | 31 | void Application::Init() 32 | {} 33 | 34 | void Application::Run() 35 | { 36 | REAL_CORE_TRACE("Application is running!"); 37 | 38 | while (isRunning) 39 | { 40 | double time = Real::Time(); 41 | Timestep timestep = time - frametime; 42 | frametime = time; 43 | 44 | RenderCommand::ClearColor({ 0.1f, 0.1f, 0.1f, 1.0f }); 45 | RenderCommand::Clear(); 46 | 47 | for (auto* layer : layerStack) 48 | { 49 | layer->Update(timestep); 50 | } 51 | 52 | imGUILayer->Begin(); 53 | for (auto* layer : layerStack) 54 | { 55 | layer->OnImGUIRender(); 56 | } 57 | imGUILayer->End(); 58 | 59 | window->OnUpdate(timestep); 60 | Update(timestep); 61 | } 62 | 63 | REAL_CORE_TRACE("Closing application..."); 64 | } 65 | 66 | Application::~Application() 67 | { 68 | 69 | } 70 | 71 | void Application::PushLayer(Layer* layer) 72 | { 73 | layerStack.PushLayer(layer); 74 | } 75 | 76 | void Application::PushOverlay(Layer* layer) 77 | { 78 | layerStack.PushOverlay(layer); 79 | } 80 | 81 | void Application::Update(Timestep ts) 82 | {} 83 | 84 | void Application::OnEvent(Event& e) 85 | { 86 | // REAL_CORE_TRACE("Got event: {0}", e); 87 | 88 | EventDispatcher dispatcher { &e }; 89 | dispatcher.Dispatch([this](WindowClosedEvent& event) -> bool 90 | { 91 | this->OnWindowClose(event); 92 | return false; 93 | }); 94 | 95 | for (auto it = layerStack.end(); it != layerStack.begin();) 96 | { 97 | (*--it)->HandleEvent(e); 98 | if (e.IsHandled()) 99 | { 100 | break; 101 | } 102 | } 103 | } 104 | 105 | double Application::Time() const 106 | { 107 | return glfwGetTime(); 108 | } 109 | 110 | void Application::OnWindowClose(WindowClosedEvent& event) 111 | { 112 | this->isRunning = false; 113 | } 114 | } 115 | 116 | -------------------------------------------------------------------------------- /engine/src/base_input.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 udv. All rights reserved. 2 | 3 | #include "real/input.hpp" 4 | 5 | namespace Real 6 | { 7 | Real::Scope Input::Make() 8 | { 9 | Real::Scope input; 10 | 11 | #ifdef REAL_PLATFORM_WINDOWS 12 | input = Real::MakeScope(); 13 | #endif 14 | return input; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /engine/src/base_layer.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 udv. All rights reserved. 2 | 3 | 4 | 5 | #include "real/layer/base_layer.hpp" 6 | #include "real/logger.hpp" 7 | 8 | namespace Real 9 | { 10 | 11 | void Layer::Attach() 12 | { 13 | REAL_CORE_TRACE("Attached layer."); 14 | } 15 | 16 | void Layer::Detach() 17 | { 18 | REAL_CORE_TRACE("Detached layer."); 19 | } 20 | 21 | void Layer::Update(Timestep ts) 22 | { 23 | 24 | } 25 | 26 | void Layer::HandleEvent(Event& e) 27 | { 28 | 29 | } 30 | 31 | void Layer::OnImGUIRender() 32 | { 33 | 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /engine/src/base_window.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 udv. All rights reserved. 2 | 3 | #include "real/time/timestep.hpp" 4 | #include "real/window.hpp" 5 | 6 | namespace Real 7 | { 8 | Real::Scope Window::Make(const WindowProperties& props) 9 | { 10 | Real::Scope window; 11 | #ifdef REAL_PLATFORM_WINDOWS 12 | window = Real::MakeScope(props); 13 | #endif 14 | return window; 15 | } 16 | 17 | Window::~Window() = default; 18 | 19 | void Window::OnUpdate(Timestep ts) 20 | { 21 | 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /engine/src/layer/imgui_layer.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 udv. All rights reserved. 2 | 3 | #define GLFW_INCLUDE_NONE 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | #include "real/input.hpp" 10 | #include "real/layer/imgui_layer.hpp" 11 | #include "real/application.hpp" 12 | 13 | namespace Real 14 | { 15 | 16 | void ImGUILayer::Attach() 17 | { 18 | ImGui::CreateContext(); 19 | ImGui::StyleColorsDark(); 20 | 21 | ImGuiIO& io = ImGui::GetIO(); 22 | // @formatter:off 23 | io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional) 24 | io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used) 25 | io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; 26 | 27 | // Keyboard mapping. ImGui will use those indices to peek into the io.KeysDown[] array. 28 | io.KeyMap[ImGuiKey_Tab] = static_cast(REAL_KEY_TAB); 29 | io.KeyMap[ImGuiKey_LeftArrow] = static_cast(REAL_KEY_LEFT); 30 | io.KeyMap[ImGuiKey_RightArrow] = static_cast(REAL_KEY_RIGHT); 31 | io.KeyMap[ImGuiKey_UpArrow] = static_cast(REAL_KEY_UP); 32 | io.KeyMap[ImGuiKey_DownArrow] = static_cast(REAL_KEY_DOWN); 33 | io.KeyMap[ImGuiKey_PageUp] = static_cast(REAL_KEY_PAGE_UP); 34 | io.KeyMap[ImGuiKey_PageDown] = static_cast(REAL_KEY_PAGE_DOWN); 35 | io.KeyMap[ImGuiKey_Home] = static_cast(REAL_KEY_HOME); 36 | io.KeyMap[ImGuiKey_End] = static_cast(REAL_KEY_END); 37 | io.KeyMap[ImGuiKey_Insert] = static_cast(REAL_KEY_INSERT); 38 | io.KeyMap[ImGuiKey_Delete] = static_cast(REAL_KEY_DELETE); 39 | io.KeyMap[ImGuiKey_Backspace] = static_cast(REAL_KEY_BACKSPACE); 40 | io.KeyMap[ImGuiKey_Space] = static_cast(REAL_KEY_SPACE); 41 | io.KeyMap[ImGuiKey_Enter] = static_cast(REAL_KEY_ENTER); 42 | io.KeyMap[ImGuiKey_Escape] = static_cast(REAL_KEY_ESCAPE); 43 | io.KeyMap[ImGuiKey_KeyPadEnter] = static_cast(REAL_KEY_KP_ENTER); 44 | io.KeyMap[ImGuiKey_A] = static_cast(REAL_KEY_A); 45 | io.KeyMap[ImGuiKey_C] = static_cast(REAL_KEY_C); 46 | io.KeyMap[ImGuiKey_V] = static_cast(REAL_KEY_V); 47 | io.KeyMap[ImGuiKey_X] = static_cast(REAL_KEY_X); 48 | io.KeyMap[ImGuiKey_Y] = static_cast(REAL_KEY_Y); 49 | io.KeyMap[ImGuiKey_Z] = static_cast(REAL_KEY_Z); 50 | // @formatter:on 51 | 52 | Application& app = Application::Instance(); 53 | GLFWwindow* window = static_cast(app.Window().Native()); 54 | 55 | // Setup Platform/Renderer bindings 56 | ImGui_ImplGlfw_InitForOpenGL(window, true); 57 | ImGui_ImplOpenGL3_Init("#version 410 core"); 58 | } 59 | 60 | void ImGUILayer::Detach() 61 | { 62 | ImGui_ImplOpenGL3_Shutdown(); 63 | ImGui_ImplGlfw_Shutdown(); 64 | ImGui::DestroyContext(); 65 | } 66 | 67 | void ImGUILayer::Begin() 68 | { 69 | ImGui_ImplOpenGL3_NewFrame(); 70 | ImGui_ImplGlfw_NewFrame(); 71 | ImGui::NewFrame(); 72 | } 73 | 74 | void ImGUILayer::End() 75 | { 76 | ImGuiIO& io = ImGui::GetIO(); 77 | Window& window = Application::Instance().Window(); 78 | io.DisplaySize = ImVec2(static_cast(window.Width()), 79 | static_cast(window.Height())); 80 | 81 | ImGui::Render(); 82 | ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); 83 | 84 | if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) 85 | { 86 | GLFWwindow* backup_current_context = glfwGetCurrentContext(); 87 | ImGui::UpdatePlatformWindows(); 88 | ImGui::RenderPlatformWindowsDefault(); 89 | glfwMakeContextCurrent(backup_current_context); 90 | } 91 | } 92 | 93 | void ImGUILayer::HandleEvent(Event& ev) 94 | { 95 | Layer::HandleEvent(ev); 96 | 97 | ImGuiIO& io = ImGui::GetIO(); 98 | 99 | EventDispatcher dispatcher { &ev }; 100 | dispatcher.Dispatch([&io](MouseBtnPressedEvent& ev) -> bool 101 | { 102 | io.MouseDown[ev.Button()] = true; 103 | 104 | return false; 105 | }); 106 | dispatcher.Dispatch( 107 | [&io](MouseBtnReleasedEvent& ev) -> bool 108 | { 109 | io.MouseDown[ev.Button()] = false; 110 | 111 | return false; 112 | }); 113 | dispatcher.Dispatch([&io](MouseMovedEvent& ev) -> bool 114 | { 115 | io.MousePos = ImVec2(static_cast(ev.X()), static_cast(ev.Y())); 116 | 117 | return false; 118 | }); 119 | dispatcher.Dispatch([&io](MouseScrolledEvent& ev) -> bool 120 | { 121 | io.MouseWheel += static_cast(ev.XOffset()); 122 | io.MouseWheelH += static_cast(ev.YOffset()); 123 | 124 | return false; 125 | }); 126 | 127 | dispatcher.Dispatch([&io](WindowResizedEvent& ev) -> bool 128 | { 129 | io.DisplaySize = ImVec2(static_cast(ev.Width()), 130 | static_cast(ev.Height())); 131 | io.DisplayFramebufferScale = ImVec2(1.0f, 1.0f); 132 | glViewport(0, 0, ev.Width(), ev.Height()); 133 | 134 | return false; 135 | }); 136 | 137 | dispatcher.Dispatch([&io](KeyPressedEvent& ev) -> bool 138 | { 139 | io.KeysDown[ev.KeyCode()] = true; 140 | io.KeyCtrl = io.KeysDown[static_cast(REAL_KEY_LEFT_CONTROL)] || 141 | io.KeysDown[static_cast(REAL_KEY_RIGHT_CONTROL)]; 142 | io.KeyShift = io.KeysDown[static_cast(REAL_KEY_LEFT_SHIFT)] || 143 | io.KeysDown[static_cast(REAL_KEY_RIGHT_SHIFT)]; 144 | io.KeyAlt = io.KeysDown[static_cast(REAL_KEY_LEFT_ALT)] || 145 | io.KeysDown[static_cast(REAL_KEY_RIGHT_ALT)]; 146 | io.KeySuper = io.KeysDown[static_cast(REAL_KEY_LEFT_SUPER)] || 147 | io.KeysDown[static_cast(REAL_KEY_RIGHT_SUPER)]; 148 | 149 | return false; 150 | }); 151 | dispatcher.Dispatch([&io](KeyReleasedEvent& ev) -> bool 152 | { 153 | io.KeysDown[ev.KeyCode()] = false; 154 | 155 | return false; 156 | }); 157 | dispatcher.Dispatch([&io](KeyTypedEvent& ev) -> bool 158 | { 159 | io.AddInputCharacter(static_cast(ev.KeyCode())); 160 | 161 | return false; 162 | }); 163 | } 164 | 165 | ImGUILayer::ImGUILayer() 166 | :Layer() 167 | {} 168 | 169 | ImGUILayer::~ImGUILayer() = default; 170 | } 171 | -------------------------------------------------------------------------------- /engine/src/layer_stack.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 udv. All rights reserved. 2 | 3 | #include "real/layer_stack.hpp" 4 | 5 | namespace Real 6 | { 7 | LayerStack::LayerStack() 8 | :stack {}, layerInsert { 0 } 9 | { 10 | } 11 | 12 | LayerStack::~LayerStack() 13 | { 14 | for (auto* layer : stack) 15 | { 16 | delete layer; 17 | } 18 | } 19 | 20 | void LayerStack::PushLayer(Layer* layer) 21 | { 22 | stack.emplace(stack.begin() + layerInsert++, layer); 23 | layer->Attach(); 24 | } 25 | 26 | void LayerStack::PushOverlay(Layer* overlay) 27 | { 28 | stack.emplace_back(overlay); 29 | overlay->Attach(); 30 | } 31 | 32 | void LayerStack::PopLayer(Layer* layer) 33 | { 34 | auto it = std::find(begin(), end(), layer); 35 | if (it != stack.end()) 36 | { 37 | (*it)->Detach(); 38 | stack.erase(it); 39 | --layerInsert; 40 | } 41 | } 42 | 43 | void LayerStack::PopOverlay(Layer* overlay) 44 | { 45 | auto it = std::find(begin(), end(), overlay); 46 | if (it != stack.end()) 47 | { 48 | (*it)->Detach(); 49 | stack.erase(it); 50 | } 51 | } 52 | } -------------------------------------------------------------------------------- /engine/src/logger.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 udv. All rights reserved. 2 | 3 | #include 4 | #include 5 | 6 | #include "real/logger.hpp" 7 | 8 | namespace Real 9 | { 10 | std::shared_ptr Logger::coreLogger; 11 | std::shared_ptr Logger::clientLogger; 12 | 13 | void Logger::Init() 14 | { 15 | // TODO: improve spdlog usage 16 | std::vector log_sinks; 17 | log_sinks.emplace_back( 18 | Real::MakeReference()); 19 | log_sinks.emplace_back( 20 | Real::MakeReference("real.log", true)); 21 | 22 | log_sinks[0]->set_pattern("%^[%T] %n: %v%$"); 23 | log_sinks[1]->set_pattern("[%T] [%l] %n: %v"); 24 | 25 | coreLogger = Real::MakeReference("REAL", begin(log_sinks), 26 | end(log_sinks)); 27 | spdlog::register_logger(coreLogger); 28 | coreLogger->set_level(spdlog::level::trace); 29 | coreLogger->flush_on(spdlog::level::trace); 30 | 31 | clientLogger = Real::MakeReference("APP", begin(log_sinks), 32 | end(log_sinks)); 33 | spdlog::register_logger(clientLogger); 34 | clientLogger->set_level(spdlog::level::trace); 35 | clientLogger->flush_on(spdlog::level::trace); 36 | } 37 | } -------------------------------------------------------------------------------- /engine/src/platform/windows/windows_input.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 udv. All rights reserved. 2 | 3 | #include "real/keycode.hpp" 4 | #include "real/input.hpp" 5 | #include "real/application.hpp" 6 | 7 | namespace Real::Platform 8 | { 9 | bool Input::IsKeyPressed(KeyCode keycode) 10 | { 11 | auto window = static_cast(Application::Instance().Window().Native()); 12 | auto state = glfwGetKey(window, static_cast(keycode)); 13 | return state == GLFW_PRESS || state == GLFW_REPEAT; 14 | } 15 | 16 | bool Input::IsMouseBtnPressed(mouse_btn_t mouse_btn) 17 | { 18 | auto window = static_cast(Application::Instance().Window().Native()); 19 | auto state = glfwGetMouseButton(window, mouse_btn); 20 | return state == GLFW_PRESS; 21 | } 22 | 23 | std::pair Input::MousePosition() 24 | { 25 | auto window = static_cast(Application::Instance().Window().Native()); 26 | double x, y; 27 | glfwGetCursorPos(window, &x, &y); 28 | return { x, y }; 29 | } 30 | 31 | mouse_position_t Input::MouseX() 32 | { 33 | auto[x, y] = MousePosition(); 34 | return x; 35 | } 36 | 37 | mouse_position_t Input::MouseY() 38 | { 39 | auto[x, y] = MousePosition(); 40 | return y; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /engine/src/platform/windows/windows_time.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 udv. All rights reserved. 2 | 3 | #include "real/platform/windows/windows_time.hpp" 4 | 5 | namespace Real::Platform 6 | { 7 | double Time() 8 | { 9 | return glfwGetTime(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /engine/src/platform/windows/windows_window.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 udv. All rights reserved. 2 | 3 | 4 | #include "real/time/timestep.hpp" 5 | 6 | #include "real/logger.hpp" 7 | #include "real/event.hpp" 8 | #include "real/platform/windows/windows_window.hpp" 9 | 10 | namespace Real::Platform 11 | { 12 | 13 | static bool s_glfw_initialized = false; 14 | 15 | void GLFWErrorCallback(int32_t code, const char* msg) 16 | { 17 | REAL_CORE_ERROR("GLFW Error: ({:#x}) {}", code, msg); 18 | } 19 | 20 | Window::Window(WindowData data) 21 | :nativeWindow { nullptr }, renderingContext { nullptr }, 22 | windowData(std::move(data)) 23 | { 24 | } 25 | 26 | void Window::Init() 27 | { 28 | if (!s_glfw_initialized) 29 | { 30 | REAL_CORE_TRACE("Initializing GLFW..."); 31 | 32 | if (glfwInit() == GLFW_TRUE) 33 | { 34 | s_glfw_initialized = true; 35 | REAL_CORE_INFO("Successfully initialized GLFW"); 36 | } 37 | else 38 | { 39 | REAL_CORE_ERROR("Couldn't initialize GLFW!"); 40 | } 41 | 42 | glfwSetErrorCallback(GLFWErrorCallback); 43 | } 44 | 45 | REAL_CORE_TRACE("Creating window: {0}, {1}, {2}", 46 | windowData.title, 47 | windowData.width, 48 | windowData.height); 49 | 50 | glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); 51 | glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); 52 | glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); 53 | // Testing 54 | // Antialiasing 55 | glfwWindowHint(GLFW_SAMPLES, 4); 56 | nativeWindow = glfwCreateWindow( 57 | windowData.width, windowData.height, 58 | windowData.title.c_str(), 59 | nullptr, nullptr); 60 | // TODO: abstract api 61 | renderingContext = new GLRenderingContext { nativeWindow }; 62 | renderingContext->Init(); 63 | 64 | glfwSetWindowUserPointer(nativeWindow, &windowData); 65 | VSyncNative(windowData.isVSync); 66 | 67 | // GLFW callbacks 68 | glfwSetWindowSizeCallback(nativeWindow, 69 | [](GLFWwindow* window, int width, int height) 70 | { 71 | WindowData& data = *(WindowData*)glfwGetWindowUserPointer( 72 | window); 73 | 74 | data.width = width; 75 | data.height = height; 76 | 77 | WindowResizedEvent ev { 78 | static_cast(width), 79 | static_cast(height) }; 80 | data.ev_callback(ev); 81 | }); 82 | 83 | glfwSetWindowCloseCallback(nativeWindow, [](GLFWwindow* window) 84 | { 85 | WindowData& data = *(WindowData*)glfwGetWindowUserPointer(window); 86 | 87 | WindowClosedEvent ev {}; 88 | data.ev_callback(ev); 89 | }); 90 | 91 | glfwSetKeyCallback(nativeWindow, 92 | [](GLFWwindow* window, int key, int scancode, int action, 93 | int mods) 94 | { 95 | WindowData& data = *(WindowData*)glfwGetWindowUserPointer( 96 | window); 97 | 98 | switch (action) 99 | { 100 | case GLFW_PRESS: 101 | { 102 | KeyPressedEvent event(key); 103 | data.ev_callback(event); 104 | break; 105 | } 106 | case GLFW_RELEASE: 107 | { 108 | KeyReleasedEvent event(key); 109 | data.ev_callback(event); 110 | break; 111 | } 112 | case GLFW_REPEAT: 113 | { 114 | KeyPressedEvent event(key); 115 | data.ev_callback(event); 116 | break; 117 | } 118 | default: 119 | { 120 | REAL_CORE_ERROR("Unknown key action: {}", action); 121 | } 122 | } 123 | }); 124 | 125 | glfwSetCharCallback(nativeWindow, [](GLFWwindow* window, uint32_t character) 126 | { 127 | WindowData& data = *(WindowData*)glfwGetWindowUserPointer(window); 128 | KeyTypedEvent ev(character); 129 | data.ev_callback(ev); 130 | }); 131 | 132 | glfwSetMouseButtonCallback(nativeWindow, 133 | [](GLFWwindow* window, int button, int action, 134 | int mods) 135 | { 136 | WindowData& data = *(WindowData*)glfwGetWindowUserPointer( 137 | window); 138 | 139 | switch (action) 140 | { 141 | case GLFW_PRESS: 142 | { 143 | MouseBtnPressedEvent event(button); 144 | data.ev_callback(event); 145 | break; 146 | } 147 | case GLFW_RELEASE: 148 | { 149 | MouseBtnReleasedEvent event(button); 150 | data.ev_callback(event); 151 | break; 152 | } 153 | default: 154 | { 155 | REAL_CORE_ERROR("Unknown key action: {}", 156 | action); 157 | } 158 | } 159 | }); 160 | 161 | glfwSetScrollCallback(nativeWindow, 162 | [](GLFWwindow* window, double xOffset, double yOffset) 163 | { 164 | WindowData& data = *(WindowData*)glfwGetWindowUserPointer( 165 | window); 166 | 167 | MouseScrolledEvent event((float)xOffset, (float)yOffset); 168 | data.ev_callback(event); 169 | }); 170 | 171 | glfwSetCursorPosCallback(nativeWindow, 172 | [](GLFWwindow* window, double xPos, double yPos) 173 | { 174 | WindowData& data = *(WindowData*)glfwGetWindowUserPointer( 175 | window); 176 | 177 | MouseMovedEvent event((float)xPos, (float)yPos); 178 | data.ev_callback(event); 179 | }); 180 | } 181 | 182 | Window::~Window() 183 | { 184 | REAL_CORE_TRACE("Destroying native window..."); 185 | ::Real::Window::~Window(); 186 | delete renderingContext; 187 | } 188 | 189 | void Window::OnUpdate(Timestep ts) 190 | { 191 | ::Real::Window::OnUpdate(ts); 192 | glfwPollEvents(); 193 | renderingContext->SwapBuffers(); 194 | } 195 | 196 | void Window::VSyncNative(bool enabled) 197 | { 198 | renderingContext->VSync(enabled); 199 | } 200 | 201 | void Window::VSync(bool enabled) 202 | { 203 | VSyncNative(enabled); 204 | windowData.isVSync = enabled; 205 | } 206 | 207 | void Window::EventCallback(const event_callback_t& callback) 208 | { 209 | windowData.ev_callback = callback; 210 | } 211 | } -------------------------------------------------------------------------------- /engine/src/renderer/array_vertex.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 udv. All rights reserved. 2 | 3 | #include "real/logger.hpp" 4 | #include "real/renderer/base_renderer.hpp" 5 | #include "real/renderer/array_vertex.hpp" 6 | #include "real/api/gl/gl_array_vertex.hpp" 7 | 8 | namespace Real 9 | { 10 | Real::Scope VertexArray::Make() 11 | { 12 | 13 | switch (Renderer::Api().Value()) 14 | { 15 | case RendererAPI::API::GL: 16 | return Real::MakeScope(); 17 | 18 | default: 19 | case RendererAPI::API::None: 20 | REAL_CORE_ERROR("Invalid renderer api: {}", 21 | static_cast(RendererAPI::API::None)); 22 | return nullptr; 23 | } 24 | } 25 | 26 | VertexArray::~VertexArray() = default; 27 | } 28 | -------------------------------------------------------------------------------- /engine/src/renderer/base_renderer.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 udv. All rights reserved. 2 | 3 | #include "real/transform.hpp" 4 | #include "real/renderer/camera.hpp" 5 | #include "real/renderer/base_renderer.hpp" 6 | #include "real/renderer/render_command.hpp" 7 | #include "real/renderer/light.hpp" 8 | #include "real/api/gl/gl_renderer_api.hpp" 9 | 10 | namespace Real 11 | { 12 | // TODO: initialize dynamically 13 | RendererAPI* Renderer::api = new GLRendererApi {}; 14 | Renderer::SceneData* Renderer::sceneData = new Renderer::SceneData {}; 15 | 16 | void Renderer::StartScene(Real::Camera& camera) noexcept 17 | { 18 | sceneData->viewprojection = camera.Viewprojection(); 19 | sceneData->viewPosition = camera.Position(); 20 | } 21 | 22 | void Renderer::Init() 23 | { 24 | RenderCommand::Init(); 25 | } 26 | 27 | void Renderer::EndScene() noexcept 28 | { 29 | 30 | } 31 | 32 | void Renderer::Submit(const Reference & vao, 33 | const Real::Reference& shader, 34 | const Real::Transform& model) noexcept 35 | { 36 | shader->Bind(); 37 | shader->UniformFloat("u_viewPos", sceneData->viewPosition); 38 | shader->UniformMatrix("u_vp", sceneData->viewprojection); 39 | shader->UniformMatrix("u_model", model.Matrix()); 40 | // TODO: implement render command queue 41 | RenderCommand::DrawIndexed(vao); 42 | } 43 | 44 | // void Renderer::Submit(const Real::Reference& light) noexcept 45 | // { 46 | // light->Bind(); 47 | // light->UniformFloat("u_viewPos", sceneData->viewPosition); 48 | // light->UniformMatrix("u_vp", sceneData->viewprojection); 49 | // light->UniformMatrix("u_model", model.Matrix()); 50 | // // TODO: implement render command queue 51 | // RenderCommand::DrawIndexed(vao); 52 | // } 53 | 54 | 55 | void Renderer::Submit(const Reference & vao, 56 | const Real::Reference& material, 57 | const Real::Transform& model) noexcept 58 | { 59 | auto shader = material->Shader(); 60 | shader->Bind(); 61 | shader->UniformFloat("u_viewPos", sceneData->viewPosition); 62 | shader->UniformMatrix("u_vp", sceneData->viewprojection); 63 | shader->UniformMatrix("u_model", model.Matrix()); 64 | // TODO: implement render command queue 65 | RenderCommand::DrawIndexed(vao); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /engine/src/renderer/base_rendering_context.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 udv. All rights reserved. 2 | 3 | #include 4 | 5 | #include "real/logger.hpp" 6 | #include "real/renderer.hpp" 7 | 8 | namespace Real 9 | { 10 | RenderingContext::~RenderingContext() 11 | { 12 | 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /engine/src/renderer/base_shader.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 udv. All rights reserved. 2 | 3 | #include 4 | #include 5 | 6 | #include "real/logger.hpp" 7 | #include "real/renderer.hpp" 8 | 9 | namespace Real 10 | { 11 | Real::Reference Shader::Make(std::string filename) 12 | { 13 | switch (Renderer::Api().Value()) 14 | { 15 | case RendererAPI::API::GL: 16 | return Real::MakeReference(filename); 17 | 18 | default: 19 | case RendererAPI::API::None: 20 | REAL_CORE_ERROR("Invalid renderer api: {}", 21 | static_cast(RendererAPI::API::None)); 22 | return nullptr; 23 | } 24 | } 25 | 26 | Shader::~Shader() = default; 27 | 28 | // Shader library 29 | void ShaderLibrary::Add(const Real::Reference& shader) 30 | { 31 | if (shaderMap.contains(shader->Name())) 32 | { 33 | return; 34 | } 35 | 36 | auto& name = shader->Name(); 37 | shaderMap[name] = shader; 38 | } 39 | 40 | Real::Reference ShaderLibrary::Load(const std::string& filename) 41 | { 42 | auto shader = Shader::Make(filename); 43 | Add(shader); 44 | return shader; 45 | } 46 | 47 | Real::Reference ShaderLibrary::Load(const std::string& name, 48 | const std::string& filename) 49 | { 50 | auto shader = Shader::Make(filename); 51 | shader->Name(name); 52 | Add(shader); 53 | return shader; 54 | } 55 | 56 | bool ShaderLibrary::Contains(const std::string& name) 57 | { 58 | return shaderMap.contains(name); 59 | } 60 | 61 | Real::Reference ShaderLibrary::Get(const std::string& name) 62 | { 63 | real_msg_assert(Contains(name), "Shader not found!"); 64 | return shaderMap[name]; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /engine/src/renderer/base_texture.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 udv. All rights reserved. 2 | 3 | #include "real/renderer/base_texture.hpp" 4 | 5 | #include 6 | 7 | #include "real/renderer.hpp" 8 | 9 | namespace Real 10 | { 11 | 12 | // region Texture 13 | Texture::~Texture() = default; 14 | // endregion Texture 15 | // region Texture2D 16 | Real::Reference Texture2D::Make(const std::string& path) 17 | { 18 | switch (Renderer::Api().Value()) 19 | { 20 | case RendererAPI::API::GL: 21 | return Real::MakeReference(path); 22 | 23 | default: 24 | case RendererAPI::API::None: 25 | REAL_CORE_ERROR("Invalid renderer api: {}", 26 | static_cast(RendererAPI::API::None)); 27 | return nullptr; 28 | } 29 | } 30 | 31 | Texture2D::~Texture2D() = default; 32 | // endregion Texture2d 33 | } 34 | -------------------------------------------------------------------------------- /engine/src/renderer/buffer_index.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 udv. All rights reserved. 2 | 3 | #include "real/logger.hpp" 4 | #include "real/renderer/base_renderer.hpp" 5 | #include "real/api/gl/gl_buffer_index.hpp" 6 | 7 | namespace Real 8 | { 9 | 10 | Real::Scope IndexBuffer::Make(uint32_t* data, uint32_t size) 11 | { 12 | 13 | switch (Renderer::Api().Value()) 14 | { 15 | case RendererAPI::API::GL: 16 | return Real::MakeScope(data, size); 17 | 18 | default: 19 | case RendererAPI::API::None: 20 | REAL_CORE_ERROR("Invalid renderer api: {}", 21 | static_cast(RendererAPI::API::None)); 22 | return nullptr; 23 | } 24 | } 25 | 26 | IndexBuffer::~IndexBuffer() = default; 27 | 28 | } 29 | -------------------------------------------------------------------------------- /engine/src/renderer/buffer_layout.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 udv. All rights reserved. 2 | 3 | #include "real/renderer/buffer_layout.hpp" 4 | 5 | namespace Real 6 | { 7 | BufferLayout::BufferLayout(std::initializer_list attributes) 8 | :attributes { attributes } 9 | { 10 | CalculateParams(); 11 | } 12 | 13 | BufferLayout::BufferLayout() 14 | :attributes {} 15 | { 16 | 17 | } 18 | 19 | void BufferLayout::CalculateParams() 20 | { 21 | uint32_t offset = 0; 22 | 23 | for (auto& a : attributes) 24 | { 25 | a.offset = offset; 26 | offset += a.size; 27 | 28 | stride += a.size; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /engine/src/renderer/buffer_vertex.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 udv. All rights reserved. 2 | 3 | #include "real/logger.hpp" 4 | #include "real/renderer/base_renderer.hpp" 5 | #include "real/renderer/buffer_vertex.hpp" 6 | #include "real/api/gl/gl_buffer_vertex.hpp" 7 | #include "real/renderer/renderer_api.hpp" 8 | 9 | namespace Real 10 | { 11 | 12 | Real::Scope VertexBuffer::Make(float* data, uint32_t size) 13 | { 14 | switch (Renderer::Api().Value()) 15 | { 16 | case RendererAPI::API::GL: 17 | return Real::MakeScope(data, size); 18 | 19 | default: 20 | case RendererAPI::API::None: 21 | REAL_CORE_ERROR("Invalid renderer api: {}", 22 | static_cast(RendererAPI::API::None)); 23 | return nullptr; 24 | } 25 | 26 | } 27 | 28 | VertexBuffer::~VertexBuffer() = default; 29 | 30 | } 31 | -------------------------------------------------------------------------------- /engine/src/renderer/camera.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 udv. All rights reserved. 2 | 3 | #include 4 | 5 | #include "real/renderer/camera.hpp" 6 | 7 | namespace Real 8 | { 9 | // region Camera 10 | Camera::Camera(const glm::mat4& projection, glm::vec3 position, glm::vec3 direction) 11 | :position { position }, projection { projection }, direction { direction } 12 | {} 13 | 14 | void Camera::Update() 15 | { 16 | UpdateView(); 17 | UpdateViewprojection(); 18 | } 19 | 20 | void Camera::Init() 21 | { 22 | Update(); 23 | } 24 | 25 | void Camera::UpdateViewprojection() 26 | { 27 | // OpenGL needs this order. 28 | cacheViewprojection = projection * view; 29 | } 30 | 31 | glm::vec3 Camera::Up() const 32 | { 33 | return glm::cross(Direction(), Right()); 34 | } 35 | 36 | glm::vec3 Camera::Right() const 37 | { 38 | return glm::normalize(glm::cross({ 0.0f, 1.0f, 0.0f }, Direction())); 39 | } 40 | 41 | glm::vec3 Camera::Direction() const 42 | { 43 | return direction; 44 | } 45 | 46 | glm::vec3 Camera::DirectionTo(glm::vec3 target) const 47 | { 48 | return glm::normalize(position - target); 49 | } 50 | 51 | void Camera::LookAt(glm::vec3 target) 52 | { 53 | direction = DirectionTo(target); 54 | view = glm::lookAt(position, target, Up()); 55 | UpdateViewprojection(); 56 | } 57 | // endregion 58 | 59 | //region Orthographic camera 60 | OrthographicCamera::OrthographicCamera(float left, float right, float bottom, 61 | float top) 62 | :Camera { glm::ortho(left, right, bottom, top, 0.1f, 10.0f) } 63 | { 64 | } 65 | 66 | void OrthographicCamera::UpdateView() 67 | { 68 | // TODO: improve this 69 | glm::mat4 transform = 70 | glm::translate(glm::identity(), position) * 71 | glm::rotate(glm::identity(), glm::radians(0.0f), 72 | glm::vec3(0, 0, 1)); 73 | 74 | view = glm::inverse(transform); 75 | } 76 | 77 | //endregion 78 | //region Perspective camera 79 | PerspectiveCamera::PerspectiveCamera(float yfov, float w, float h) 80 | :Camera { glm::perspective(glm::radians(yfov), w / h, 0.1f, 10.0f) } 81 | { 82 | } 83 | 84 | void PerspectiveCamera::UpdateView() 85 | { 86 | // TODO: improve this 87 | glm::mat4 transform = 88 | glm::translate(glm::identity(), position) * 89 | glm::rotate(glm::identity(), glm::radians(0.0f), 90 | glm::vec3(0, 0, 1)); 91 | 92 | view = glm::inverse(transform); 93 | } 94 | 95 | //endregion 96 | } 97 | -------------------------------------------------------------------------------- /engine/src/renderer/renderer_api.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 udv. All rights reserved. 2 | 3 | #include "real/renderer/renderer_api.hpp" 4 | 5 | namespace Real { 6 | // renderer_api::api renderer_api::api_ = renderer_api::api::gl; 7 | } 8 | -------------------------------------------------------------------------------- /engine/src/stb.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 udv. All rights reserved. 2 | 3 | // TODO: get rid of this file maybe?) 4 | 5 | #define STB_IMAGE_IMPLEMENTATION 6 | #include 7 | -------------------------------------------------------------------------------- /examples/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | message(STATUS "Configuring examples") 2 | 3 | set(EXAMPLES) # List of all examples 4 | 5 | function (example_target_name_for EX_NAME TARGET_NAME) 6 | set(${TARGET_NAME} "${META_REAL_PROJECT_NAME}-example-${EX_NAME}" PARENT_SCOPE) 7 | endfunction () 8 | 9 | macro (add_example EX_NAME) 10 | ### Helpers 11 | set(EXAMPLE_TARGET_NAME) 12 | example_target_name_for(${EX_NAME} EXAMPLE_TARGET_NAME) 13 | 14 | set(EXAMPLE_SOURCES ${ARGN}) 15 | 16 | message(STATUS "Adding real example: ${EX_NAME}(${EXAMPLE_SOURCES})") 17 | ### Target 18 | add_executable( 19 | ${EXAMPLE_TARGET_NAME} 20 | EXCLUDE_FROM_ALL 21 | ${EXAMPLE_SOURCES} 22 | ) 23 | 24 | target_link_libraries( 25 | ${EXAMPLE_TARGET_NAME} 26 | PRIVATE 27 | ${REAL_LIBRARY_TARGET_NAME} 28 | ) 29 | 30 | # Properties 31 | set_target_properties( 32 | ${EXAMPLE_TARGET_NAME} PROPERTIES 33 | 34 | # Folder 35 | FOLDER ${META_REAL_PROJECT_FULL_NAME}/examples/${EX_NAME} 36 | 37 | # Version 38 | VERSION ${META_REAL_VERSION} 39 | SOVERSION ${META_REAL_VERSION_MAJOR} 40 | 41 | # C++ 42 | CXX_STANDARD ${CXX_STANDARD_DEFAULT} 43 | CXX_STANDARD_REQUIRED ON 44 | CXX_EXTENSIONS OFF 45 | 46 | # C 47 | C_STANDARD ${C_STANDARD_DEFAULT} 48 | C_STANDARD_REQUIRED ON 49 | C_EXTENSIONS OFF 50 | 51 | # Other 52 | VS_DEBUGGER_WORKING_DIRECTORY "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}" 53 | ) 54 | 55 | list(APPEND EXAMPLES ${EX_NAME}) 56 | endmacro () 57 | 58 | # Examples 59 | if (OPTION_REAL_EXAMPLES_CUBE) 60 | add_example( 61 | cube 62 | cube/main.cpp 63 | ) 64 | endif () 65 | 66 | # RenderDoc 67 | foreach (EX_NAME IN LISTS EXAMPLES) 68 | set(EXAMPLE_TARGET_NAME) 69 | example_target_name_for(${EX_NAME} EXAMPLE_TARGET_NAME) 70 | 71 | generate_rdoc_settings_from( 72 | "${PROJECT_SOURCE_DIR}/rdoc/settings.cap" 73 | ${EXAMPLE_TARGET_NAME} 74 | "${CMAKE_BINARY_DIR}/examples/${EX_NAME}" 75 | ) 76 | endforeach () -------------------------------------------------------------------------------- /examples/cube/main.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 udv. All rights reserved. 2 | 3 | #include 4 | #include // TODO: abstract imgui 5 | #include 6 | 7 | class SandboxLayer : public Real::Layer 8 | { 9 | private: 10 | // @formatter:off 11 | Real::Reference light; 12 | Real::Reference material; 13 | 14 | // Global 15 | float cameraYOffset = 2.0f; 16 | float lightYOffset = 2.0f; 17 | float lightAngle = 0.0f; 18 | float lightDistance = 5.0f; 19 | float cameraDistance = 5.0f; 20 | float rotationSpeed = 0.5f; 21 | // @formatter:on 22 | 23 | glm::mat4 transformMat = glm::identity(); 24 | 25 | // Rendering 26 | Real::Reference vao; 27 | Real::Camera* camera; 28 | Real::ShaderLibrary shaderLib; 29 | public: 30 | SandboxLayer() 31 | :Real::Layer() 32 | { 33 | // Perspective 34 | camera = new Real::PerspectiveCamera { 45.0f, 16.0f, 9.0f }; 35 | // TODO: fix redundant glm::vec3? 36 | light = Real::MakeReference( 37 | glm::vec3 { 1.0f, 1.0f, 1.0f, }, 38 | glm::vec3 { 1.0f, 1.0f, 1.0f, }, 39 | glm::vec3 { 1.0f, 1.0f, 1.0f, } 40 | ); 41 | material = Real::MakeReference( 42 | 32.0f, 43 | glm::vec3 { 1.0f, 0.5f, 0.31f }, 44 | glm::vec3 { 1.0f, 0.5f, 0.31f }, 45 | glm::vec3 { 0.5f, 0.5f, 0.5f }, 46 | shaderLib.Load("shaders/material.glsl") 47 | ); 48 | } 49 | 50 | virtual void OnImGUIRender() override 51 | { 52 | ImGui::Begin("Settings"); 53 | 54 | ImGui::Text("Global"); 55 | ImGui::Separator(); 56 | ImGui::SliderFloat("Rotation speed", &rotationSpeed, 0.1f, 1.0f, "%.1f"); 57 | ImGui::SliderFloat("Camera Distance", &cameraDistance, 2.0f, 7.0f, "%.1f"); 58 | ImGui::SliderFloat("Camera Y", &cameraYOffset, 2.0f, 7.0f, "%.1f"); 59 | ImGui::Separator(); 60 | 61 | light->ImGUIBegin(); 62 | ImGui::SliderFloat("Light Angle", &lightAngle, 0.0f, 360.0f, "%.1f"); 63 | ImGui::SliderFloat("Light Y", &lightYOffset, 2.0f, 5.0f, "%.1f"); 64 | light->ImGUIEnd(); 65 | 66 | material->ImGUIBegin(); 67 | material->ImGUIEnd(); 68 | 69 | ImGui::End(); 70 | } 71 | 72 | virtual void Attach() override 73 | { 74 | // region Setup rendering 75 | // Vertices 76 | // @formatter:off 77 | float vertices[] = { 78 | // TOP 79 | // Positions // Normals // Colors 80 | 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, // 1.0f, 0.0f, 0.0f, 1.0f, // FTR 81 | -1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, // 1.0f, 0.0f, 0.0f, 1.0f, // FTL 82 | 1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, // 1.0f, 0.0f, 0.0f, 1.0f, // RTR 83 | -1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, // 1.0f, 0.0f, 0.0f, 1.0f, // RTL 84 | 85 | // BOTTOM 86 | // Positions // Normals // Colors 87 | 1.0f, -1.0f, 1.0f, 0.0f, -1.0f, 0.0f, // 0.0f, 1.0f, 0.0f, 1.0f, // FBR 88 | -1.0f, -1.0f, 1.0f, 0.0f, -1.0f, 0.0f, // 0.0f, 1.0f, 0.0f, 1.0f, // FBL 89 | 1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, // 0.0f, 1.0f, 0.0f, 1.0f, // RBR 90 | -1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, // 0.0f, 1.0f, 0.0f, 1.0f, // RBL 91 | 92 | // FRONT 93 | // Positions // Normals // Colors 94 | 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, // 0.0f, 0.0f, 1.0f, 1.0f, // FTR 95 | -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, // 0.0f, 0.0f, 1.0f, 1.0f, // FTL 96 | 1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, // 0.0f, 0.0f, 1.0f, 1.0f, // FBR 97 | -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, // 0.0f, 0.0f, 1.0f, 1.0f, // FBL 98 | 99 | // BACK 100 | // Positions // Normals // Colors 101 | 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, // 0.5f, 0.5f, 0.0f, 1.0f, // RTR 102 | -1.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, // 0.5f, 0.5f, 0.0f, 1.0f, // RTL 103 | 1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, // 0.5f, 0.5f, 0.0f, 1.0f, // RBR 104 | -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, // 0.5f, 0.5f, 0.0f, 1.0f, // RBL 105 | 106 | // LEFT 107 | // Positions // Normals // Colors 108 | -1.0f, 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, // 0.0f, 0.5f, 0.5f, 1.0f, // FTL 109 | -1.0f, -1.0f, 1.0f, -1.0f, 0.0f, 0.0f, // 0.0f, 0.5f, 0.5f, 1.0f, // FBL 110 | -1.0f, 1.0f, -1.0f, -1.0f, 0.0f, 0.0f, // 0.0f, 0.5f, 0.5f, 1.0f, // RTL 111 | -1.0f, -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, // 0.0f, 0.5f, 0.5f, 1.0f, // RBL 112 | 113 | // RIGHT 114 | // Positions // Normals // Colors 115 | 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, // 0.5f, 0.0f, 0.5f, 1.0f, // FTR 116 | 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, // 0.5f, 0.0f, 0.5f, 1.0f, // FBR 117 | 1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 0.0f, // 0.5f, 0.0f, 0.5f, 1.0f, // RTR 118 | 1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, // 0.5f, 0.0f, 0.5f, 1.0f, // RBR 119 | }; 120 | 121 | unsigned int positions[] { 122 | 0, 1, 2, 1, 2, 3, // TOP 123 | 4, 5, 6, 5, 6, 7, // BOTTOM 124 | 8, 9, 10, 9, 10, 11, // FRONT 125 | 12, 13, 14, 13, 14, 15, // BACK 126 | 16, 17, 18, 17, 18, 19, // LEFT 127 | 20, 21, 22, 21, 22, 23, // RIGHT 128 | }; 129 | // @formatter:on 130 | 131 | // Vertex Array 132 | vao = Real::VertexArray::Make(); 133 | // Vertex Buffer 134 | Real::Reference vbo = Real::VertexBuffer::Make(vertices, 135 | sizeof(vertices)); 136 | vbo->Layout({ 137 | { Real::shader_data_t::vec3, "_pos", }, 138 | { Real::shader_data_t::vec3, "_normal", }, 139 | }); 140 | // Index Buffer 141 | Real::Reference ibo = Real::IndexBuffer::Make(positions, 142 | sizeof(positions) / sizeof(unsigned int)); 143 | 144 | vao->AddVertexBuffer(vbo); 145 | vao->AddIndexBuffer(ibo); 146 | } 147 | 148 | virtual void Update(Real::Timestep ts) override 149 | { 150 | // Light 151 | float lightAngleRads = glm::radians(lightAngle); 152 | float lx = glm::sin(lightAngleRads) * lightDistance; 153 | float lz = glm::cos(lightAngleRads) * lightDistance; 154 | light->Pos({ lx, lightYOffset, lz, }); 155 | 156 | // Camera 157 | camera->Position({ 0.0f, cameraYOffset, cameraDistance }); 158 | camera->LookAt({ 0.0, 0.0, 0.0 }); 159 | 160 | // Cube 161 | float deltaAngle = 162 | ts.milliseconds() * 0.1f * rotationSpeed; // TODO: float operators 163 | float deltaAngleRads = glm::radians(deltaAngle); 164 | transformMat = glm::rotate(transformMat, deltaAngleRads, 165 | glm::vec3(0.0f, 1.0f, 0.0f)); 166 | Real::Transform transform = transformMat; 167 | 168 | const auto& shader = shaderLib.Get("material"); 169 | shader->Bind(); 170 | material->Update(); 171 | // Light 172 | // TODO: abstract lighting 173 | shader->UniformFloat("u_Light.position", light->Pos()); 174 | shader->UniformFloat("u_Light.ambient", light->Ambient()); 175 | shader->UniformFloat("u_Light.diffuse", light->Diffuse()); 176 | shader->UniformFloat("u_Light.specular", light->Specular()); 177 | // Lighting 178 | 179 | // Scene 180 | Real::Renderer::StartScene(*camera); 181 | Real::Renderer::Submit(vao, material, transform); 182 | // Real::Renderer::Submit(light); 183 | Real::Renderer::EndScene(); 184 | 185 | Real::RenderCommand::DrawIndexed(vao); 186 | } 187 | }; 188 | 189 | class Application : public Real::Application 190 | { 191 | public: 192 | Application() 193 | :Real::Application() 194 | { 195 | PushLayer(new SandboxLayer()); 196 | } 197 | }; 198 | 199 | Real::Scope Real::Make() 200 | { 201 | return Real::MakeScope<::Application>(); 202 | } -------------------------------------------------------------------------------- /plan.md: -------------------------------------------------------------------------------- 1 | # Plans 2 | ### Global Engine plans 3 | ### TODOs -------------------------------------------------------------------------------- /rdoc/settings.cap: -------------------------------------------------------------------------------- 1 | { 2 | "rdocCaptureSettings": 1, 3 | "settings": { 4 | "autoStart": false, 5 | "commandLine": "", 6 | "environment": [ 7 | ], 8 | "executable": "@RDOC_TARGET_FILE@", 9 | "inject": false, 10 | "numQueuedFrames": 0, 11 | "options": { 12 | "allowFullscreen": true, 13 | "allowVSync": true, 14 | "apiValidation": false, 15 | "captureAllCmdLists": false, 16 | "captureCallstacks": true, 17 | "captureCallstacksOnlyDraws": false, 18 | "debugOutputMute": true, 19 | "delayForDebugger": 0, 20 | "hookIntoChildren": false, 21 | "refAllResources": false, 22 | "verifyBufferAccess": false 23 | }, 24 | "queuedFrameCap": 0, 25 | "workingDir": "@RDOC_WORKING_DIR@" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /vendor/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # spdlog 2 | set(SPDLOG_INSTALL OFF CACHE BOOL "" FORCE) 3 | set(SPDLOG_BUILD_BENCH OFF CACHE BOOL "" FORCE) 4 | set(SPDLOG_BUILD_EXAMPLE OFF CACHE BOOL "" FORCE) 5 | set(SPDLOG_BUILD_EXAMPLE_HO OFF CACHE BOOL "" FORCE) 6 | set(SPDLOG_BUILD_SHARED OFF CACHE BOOL "" FORCE) 7 | set(SPDLOG_BUILD_TESTS OFF CACHE BOOL "" FORCE) 8 | set(SPDLOG_BUILD_TESTS_HO OFF CACHE BOOL "" FORCE) 9 | add_subdirectory(spdlog) 10 | set_target_properties(spdlog PROPERTIES FOLDER vendor) 11 | 12 | # glfw 13 | set(GLFW_BUILD_DOCS OFF CACHE BOOL "" FORCE) 14 | set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE) 15 | set(GLFW_BUILD_TESTS OFF CACHE BOOL "" FORCE) 16 | set(GLFW_INSTALL OFF CACHE BOOL "" FORCE) 17 | add_subdirectory(glfw) 18 | set_target_properties(glfw PROPERTIES FOLDER vendor) 19 | 20 | # glad 21 | set(GLAD_INSTALL OFF CACHE BOOL "" FORCE) 22 | set(GLAD_PROFILE "core" CACHE STRING "" FORCE) 23 | set(GLAD_ALL_EXTENSIONS ON CACHE STRING "" FORCE) 24 | add_subdirectory(glad) 25 | set_target_properties(glad PROPERTIES FOLDER vendor) 26 | set_target_properties(glad-generate-files PROPERTIES FOLDER vendor) 27 | 28 | # imgui 29 | set(IMGUI_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE) 30 | add_subdirectory(imgui) 31 | set_target_properties(imgui PROPERTIES FOLDER vendor) 32 | 33 | # glm 34 | set(GLM_QUIET OFF CACHE BOOL "" FORCE) 35 | set(GLM_TEST_ENABLE OFF CACHE BOOL "" FORCE) 36 | add_subdirectory(glm) 37 | 38 | # stb 39 | add_subdirectory(stb) -------------------------------------------------------------------------------- /vendor/stb/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # TODO: improve this. 2 | add_library(stb INTERFACE) 3 | target_include_directories( 4 | stb INTERFACE 5 | "$" 6 | "$" 7 | ) --------------------------------------------------------------------------------