diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000000000000000000000000000000000000..b83e93bd44cd5f80dcf8cdb2bd96edc8e6a767e3 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,16 @@ +*.hpp linguist-language=c++ +*.hxx linguist-language=c++ +*.cpp linguist-language=c++ +*.cxx linguist-language=c++ +*.inl linguist-language=c++ +*.h linguist-language=c +*.c linguist-language=c +dependencies/assimp/*.h linguist-language=c++ +dependencies/asyncplusplus/*.h linguist-language=c++ +dependencies/doctest/*.h linguist-language=c++ +dependencies/moodycamel/*.h linguist-language=c++ +dependencies/plog/*.h linguist-language=c++ +dependencies/robin-map/*.h linguist-language=c++ + +*.mmf filter=lfs diff=lfs merge=lfs -text +*.ktx filter=lfs diff=lfs merge=lfs -text diff --git a/.gitignore b/.gitignore index d9ea94d0a027d7761c84a7fcbfaf8979f5f835db..8342e342f92717d76068ace53fceab90c4095baf 100644 --- a/.gitignore +++ b/.gitignore @@ -37,8 +37,6 @@ CMakeLists.txt.user assets/*.log -assets/assets_ext -assets/extensions assets/ImageTool.jar diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index f9cf9f4842bacb7dce03def2fba568711abecf06..7d67ae74cc167e3097414f659c0fc3ee5e196f79 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -5,57 +5,66 @@ stages: variables: GIT_SUBMODULE_STRATEGY: recursive - -build_gcc: - stage: build - script: - - export CC=gcc - - export CXX=g++ - - mkdir -p build - - cd build - - mkdir -p bin - - rm -rf src - - cmake -G Ninja -DCMAKE_INSTALL_PREFIX:PATH=../bin -DCMAKE_BUILD_TYPE=Release -DMIRRAGE_EXPORT_EXECUTABLE=ON .. - - cmake --build . --target src/install - - cmake --build . --target test + +.cache-paths-spec: &cache-paths + - build + +.linux-cache-spec: &linux-cache-spec + cache: + key: ${CI_COMMIT_REF_SLUG}-${CI_JOB_NAME} + paths: *cache-paths + +.windows-cache-spec: &windows-cache-spec + cache: + paths: *cache-paths + key: "%CI_COMMIT_REF_SLUG%-%CI_JOB_NAME%-%CI_RUNNER_ID%" + +.windows-task: &windows-task + tags: + - windows + only: + variables: + - $WINDOWS_CI + +.artifact-spec: &artifact-spec artifacts: + name: "mirrage" paths: - - build/bin + - mirrage expire_in: 1 day - cache: - key: "gcc_${CI_COMMIT_REF_SLUG}" - paths: - - build -build_clang: +.build-ninja-linux: &build-ninja-linux stage: build script: - - export CC=clang - - export CXX=clang++ - - mkdir -p build + - cmake -E make_directory build - cd build - - mkdir -p bin - - rm -rf src - - cmake -G Ninja -DCMAKE_INSTALL_PREFIX:PATH=../bin -DCMAKE_BUILD_TYPE=Release -DMIRRAGE_EXPORT_EXECUTABLE=ON .. + - cmake -E remove_directory src + - cmake -G Ninja -DCMAKE_INSTALL_PREFIX:PATH=../../mirrage -DCMAKE_BUILD_TYPE=Release -DMIRRAGE_EXPORT_EXECUTABLE=ON .. + - cmake --build . - cmake --build . --target src/install - cmake --build . --target test - - wget https://github.com/lowkey42/mirrage/releases/download/v0.2/model_data_lbs.tar.xz || true - - cd bin/bin - - tar xf ../../model_data_lbs.tar.xz - artifacts: - paths: - - build/bin - expire_in: 1 week - cache: - key: "clang_${CI_COMMIT_REF_SLUG}" - paths: - - build + <<: *linux-cache-spec + <<: *artifact-spec + +build-gcc: + variables: + CC: "gcc" + CXX: "g++" + <<: *build-ninja-linux + +build-clang: + variables: + CC: "clang" + CXX: "clang++" + <<: *build-ninja-linux -build_scanbuild: +build-scanbuild: stage: build script: - export CC=clang - export CXX=clang++ + - export CMAKE_BUILD_PARALLEL_LEVEL=$(nproc --all) + - echo "Build parallelism:" ${CMAKE_BUILD_PARALLEL_LEVEL} - mkdir -p build - cd build - scan-build --use-c++=clang++ --use-cc=clang cmake -DMIRRAGE_FORCE_LIBCPP=ON -DMIRRAGE_ENABLE_COTIRE=OFF -G "Unix Makefiles" .. @@ -66,4 +75,33 @@ build_scanbuild: expire_in: 1 week when: always +build-mingw: + stage: build + script: + - cmake -E make_directory build + - cd build + - cmake -E remove_directory src + - cmake -G Ninja -DCMAKE_INSTALL_PREFIX:PATH=../../mirrage -DCMAKE_BUILD_TYPE=Release -DMIRRAGE_ENABLE_COTIRE=OFF -DMIRRAGE_EXPORT_EXECUTABLE=ON .. + - cmake --build . + - cmake --build . --target src/install + - cmake --build . --target test + variables: + CC: "gcc" + CXX: "g++" + <<: *windows-task + <<: *windows-cache-spec + <<: *artifact-spec +build-msvc: + stage: build + script: + - cmake -E make_directory build + - cd build + - cmake -E remove_directory src + - cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_INSTALL_PREFIX:PATH=../../mirrage -DMIRRAGE_EXPORT_EXECUTABLE=ON -DMIRRAGE_ENABLE_BACKWARD=OFF .. + - cmake --build . --config Release -- /m + - cmake --build . --config Release --target src/install + - cmake --build . --config Release --target RUN_TESTS + <<: *windows-task + <<: *windows-cache-spec + <<: *artifact-spec diff --git a/.gitmodules b/.gitmodules index 7f5d6632c695fdebf05aedf30b40562bc66ea252..561674c0e91f5d944a5f3fb4396482811dfcedf2 100644 --- a/.gitmodules +++ b/.gitmodules @@ -3,7 +3,7 @@ url = https://github.com/bombela/backward-cpp.git [submodule "dependencies/plog"] path = dependencies/plog - url = https://github.com/SergiusTheBest/plog.git + url = https://github.com/lowkey42/plog.git [submodule "dependencies/assimp"] path = dependencies/assimp url = https://github.com/assimp/assimp.git @@ -19,9 +19,6 @@ [submodule "dependencies/magic_get"] path = dependencies/magic_get url = https://github.com/apolukhin/magic_get.git -[submodule "dependencies/nuklear"] - path = dependencies/nuklear - url = https://github.com/vurtun/nuklear.git [submodule "dependencies/physfs"] path = dependencies/physfs url = https://github.com/lowkey42/physfs.git @@ -37,3 +34,12 @@ [submodule "dependencies/doctest"] path = dependencies/doctest url = https://github.com/onqtam/doctest.git +[submodule "dependencies/SDL"] + path = dependencies/SDL + url = https://github.com/SDL-mirror/SDL.git +[submodule "dependencies/crunch"] + path = dependencies/crunch + url = https://github.com/lowkey42/crunch.git +[submodule "dependencies/imgui"] + path = dependencies/imgui + url = https://github.com/ocornut/imgui.git diff --git a/CMakeLists.txt b/CMakeLists.txt index fb4cbab8bfc4d450c71c978f57ba46dfe848dd49..41149b3930cdb1cfa86c280cd696ee29b06555a3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.2 FATAL_ERROR) +cmake_minimum_required(VERSION 3.8 FATAL_ERROR) project(mirrage LANGUAGES C CXX) @@ -25,3 +25,6 @@ endif() add_subdirectory(dependencies) add_subdirectory(src) +if(MSVC_IDE AND MIRRAGE_BUILD_DEMO) + set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT demo) +endif() diff --git a/README.md b/README.md index b2083c74633809bb8501337975e4b02c1f915654..fe9666570fb20c29e335b7f33f5a69ffc2c396d9 100644 --- a/README.md +++ b/README.md @@ -5,8 +5,11 @@ ## Mirrage -Mirrage (Mirrage Indirect Radiance Renderer And Game Engine) is a Vulkan based deferred renderer with bits and pieces of a simple game engine, that has been developed as part of my CS Bachelor thesis about screen-space global illumination. As such it is (at least in its current state) mostly just a fancy renderer with a simple demo application and just enough engine stuff (ECS, input, ui, glue-code) to keep that running. But in the future I will hopefully get it to an actually usefull state and use it as a basis for my future projects. +Mirrage (Mirrage Indirect Radiance Renderer And Game Engine) is a Vulkan based deferred renderer with bits and pieces of a simple game engine, that has been developed as part of my CS Bachelor thesis about screen-space global illumination. As such it is (at least in its current state) mostly just a fancy renderer with a simple demo application and just enough engine stuff (ECS, input, ui, glue-code) to keep that running. But in the future I will hopefully get it to an actually useful state and use it as a basis for my future projects. +The repository at GitHub is a read-only mirror and the main repository is located on Gitlab.com. + +WIP API documentation/examples: ### Demo Demo Video @@ -18,44 +21,56 @@ Mirrage (Mirrage Indirect Radiance Renderer And Game Engine) is a Vulkan based d | ![](screenshots/front.jpeg) | ![](screenshots/light_cube.jpeg) | + ### Dependencies + Required: -- CMake >= 3.8 -- SDL2 >= 2.0.8 +- CMake >= 3.9 - Vulkan + Vulkan-HPP >= 1.1.80 -- GLSLC (if MIRRAGE_COMPILE_SHADERS is ON) +- GLSLC Included in this repository: - Assimp 3.3.1 (only for mesh-converter) +- crunch (only for mesh-converter): "Crunch Library Copyright (c) 2010-2016 Richard Geldreich, Jr., Tenacious Software, and Binomial LLC" - glm - gsl - moodycamel - nuklear - physicsFS +- SDL2 - SF2 - stb_image (only for mesh-converter) + ### Supported Compilers -- GCC >= 7 -- Clang >= 5 + +- GCC >= 8 +- Clang >= 7 +- MSVC 19.14 (Visual Studio 2017 15.7) + ### Build from Source -- git clone https://github.com/lowkey42/mirrage.git + +- git lfs install +- git clone --recurse-submodules https://gitlab.com/lowkey42/mirrage.git - mkdir mirrage_build - cd mirrage_build - cmake ../mirrage - cmake --build . -In order to execute the compiled demo application, the src/demo/demo binary has be be executed from the working directory assets (the folder containing the archives.lst) and this folder has to contain the required models (Sponza and Conrnell-Box) in its extensions sub-directory. This assets can be downloaded from the latetest release. + The project can be further configured by setting the following CMake-Properties (-DPROP=ON/OFF): +- MIRRAGE_BUILD_DEMO: Build the demo application (Default: ON when building the engine directly, OFF when including it from another CMake-Project) - MIRRAGE_BUILD_MESH_CONVERTER: Also build the mesh converter that can be used to converter models into the engine specific data format (Default: OFF) -- MIRRAGE_COMPILE_SHADERS: Also compile the glsl shaders into SPIR-V (requires GLSLC) +- MIRRAGE_ENABLE_BACKWARD: Enable stacktraces (Default: ON on Linux, OFF on Windows because the underlying library backward-cpp doesn't currently support Windows) - MIRRAGE_ENABLE_CLANG_FORMAT: Includes an additional clangformat target, that can be used to automatically format all source files in the project - MIRRAGE_ENABLE_LTO: Activates link time optimizations on gcc/clang (Default: OFF) - MIRRAGE_SAN: Build with clang sanatizers (address, integer, undefined and address-use-after-scope) (Default: OFF) +- MIRRAGE_ENABLE_COTIRE: Enables automatic precompiled headers through cotire - MIRRAGE_USE_LIBCPP: Uses libc++ instead of libstdc++ when compiling with clang (Default: ON) +- MIRRAGE_OPTIMIZE_NATIVE: Compile with -march=native (Default: OFF) diff --git a/assets/archives.lst b/assets/archives.lst index 7157fabd5641b671f578a37fac36e34fa24cdca4..94d4c0b933127c9936ba261b2deffcdbbdca8c70 100644 --- a/assets/archives.lst +++ b/assets/archives.lst @@ -1,3 +1,2 @@ -core_assets demo_assets extensions/* diff --git a/assets/core_assets/assets_core_config.map b/assets/core_assets/assets_core_config.map deleted file mode 100644 index bb021d6eefffdd72cb3dd550d191d76ed9f358f3..0000000000000000000000000000000000000000 --- a/assets/core_assets/assets_core_config.map +++ /dev/null @@ -1,10 +0,0 @@ -cfg:input_mapping = settings/input_mapping.json -cfg:graphics = graphics-cfg.json -cfg:renderer = renderer-cfg.json -cfg:sounds = sounds-cfg.json -cfg:language = language-cfg.json -cfg:languages_info = settings/languages.json -cfg:gui = settings/gui.json - -loc: = loc/ -pl_cache: = pipeline_caches diff --git a/assets/core_assets/assets_core_fonts.map b/assets/core_assets/assets_core_fonts.map deleted file mode 100644 index 829c0583e39538ed6759b5e2fa5d66f5aa17e191..0000000000000000000000000000000000000000 --- a/assets/core_assets/assets_core_fonts.map +++ /dev/null @@ -1,2 +0,0 @@ -font: = fonts/ -font:test_font = fonts/droid_sans.ttf diff --git a/assets/core_assets/assets_core_shader.map b/assets/core_assets/assets_core_shader.map deleted file mode 100644 index d38858bb1f1cc2a53b89964de0c66d05b4301828..0000000000000000000000000000000000000000 --- a/assets/core_assets/assets_core_shader.map +++ /dev/null @@ -1,96 +0,0 @@ -shader: = shader/ - -vert_shader:blit = shader/bin/fullscreen.vert.spv -frag_shader:blit = shader/bin/blit.frag.spv - -vert_shader:debug_draw = shader/bin/debug_draw.vert.spv -frag_shader:debug_draw = shader/bin/debug_draw.frag.spv - - -vert_shader:light_directional = shader/bin/fullscreen.vert.spv -frag_shader:light_directional = shader/bin/light_directional.frag.spv - -vert_shader:light_point = shader/bin/light_point.vert.spv -frag_shader:light_point = shader/bin/light_point.frag.spv - -vert_shader:shadow_model = shader/bin/shadow_model.vert.spv -vert_shader:shadow_model_animated = shader/bin/shadow_model_animated.vert.spv -vert_shader:shadow_model_animated_dqs = shader/bin/shadow_model_animated_dqs.vert.spv -frag_shader:shadow_model = shader/bin/shadow_model.frag.spv - -vert_shader:model = shader/bin/model.vert.spv -vert_shader:model_animated = shader/bin/model_animated.vert.spv -vert_shader:model_animated_dqs = shader/bin/model_animated_dqs.vert.spv -frag_shader:model = shader/bin/model.frag.spv -frag_shader:model_emissive = shader/bin/model_emissive.frag.spv -frag_shader:model_alphatest = shader/bin/model_alphatest.frag.spv - -vert_shader:ui = shader/bin/ui.vert.spv -frag_shader:ui = shader/bin/ui.frag.spv - -vert_shader:taa = shader/bin/fullscreen.vert.spv -frag_shader:taa = shader/bin/taa.frag.spv - -vert_shader:ssao_blur = shader/bin/ssao_blur.vert.spv -frag_shader:ssao_blur = shader/bin/ssao_blur.frag.spv - -vert_shader:ssao = shader/bin/fullscreen.vert.spv -frag_shader:ssao = shader/bin/ssao.frag.spv - - -vert_shader:gi_blend = shader/bin/fullscreen.vert.spv -frag_shader:gi_blend = shader/bin/gi_blend.frag.spv - -vert_shader:gi_diffuse_reproject = shader/bin/fullscreen.vert.spv -frag_shader:gi_diffuse_reproject = shader/bin/gi_diffuse_reproject.frag.spv - -vert_shader:gi_integrate_brdf = shader/bin/gi_integrate_brdf.vert.spv -frag_shader:gi_integrate_brdf = shader/bin/gi_integrate_brdf.frag.spv - -vert_shader:gi_mipgen = shader/bin/fullscreen.vert.spv -frag_shader:gi_mipgen = shader/bin/gi_mipgen.frag.spv - -vert_shader:gi_sample = shader/bin/fullscreen.vert.spv -frag_shader:gi_sample = shader/bin/gi_sample.frag.spv - -vert_shader:gi_sample_upsample = shader/bin/fullscreen.vert.spv -frag_shader:gi_sample_upsample = shader/bin/gi_sample_upsample.frag.spv - -vert_shader:gi_sample_blend = shader/bin/fullscreen.vert.spv -frag_shader:gi_sample_blend = shader/bin/gi_sample_blend.frag.spv - -vert_shader:gi_sample_spec = shader/bin/fullscreen.vert.spv -frag_shader:gi_sample_spec = shader/bin/gi_sample_spec.frag.spv - -vert_shader:gi_spec_blur = shader/bin/gi_spec_blur.vert.spv -frag_shader:gi_spec_blur = shader/bin/gi_spec_blur.frag.spv - -vert_shader:gi_reproject = shader/bin/fullscreen.vert.spv -frag_shader:gi_reproject = shader/bin/gi_reproject.frag.spv - -vert_shader:gi_reprojection_weights = shader/bin/fullscreen.vert.spv -frag_shader:gi_reprojection_weights = shader/bin/gi_reprojection_weights.frag.spv - -vert_shader:gi_weight_mipgen = shader/bin/fullscreen.vert.spv -frag_shader:gi_weight_mipgen = shader/bin/gi_weight_mipgen.frag.spv - -vert_shader:median_filter = shader/bin/fullscreen.vert.spv -frag_shader:median_filter = shader/bin/median_filter.frag.spv - -vert_shader:luminance = shader/bin/fullscreen.vert.spv -frag_shader:luminance = shader/bin/luminance.frag.spv - -vert_shader:luminance_adapt = shader/bin/fullscreen.vert.spv -frag_shader:luminance_adapt = shader/bin/luminance_adapt.frag.spv - -vert_shader:bloom_apply = shader/bin/fullscreen.vert.spv -frag_shader:bloom_apply = shader/bin/bloom_apply.frag.spv - -vert_shader:bloom_blur = shader/bin/bloom_blur.vert.spv -frag_shader:bloom_blur = shader/bin/bloom_blur.frag.spv - -comp_shader:tone_mapping_adjust = shader/bin/tone_mapping_adjust.comp.spv -comp_shader:tone_mapping_histogram = shader/bin/tone_mapping_histogram.comp.spv - -vert_shader:tone_mapping_apply = shader/bin/fullscreen.vert.spv -frag_shader:tone_mapping_apply = shader/bin/tone_mapping_apply.frag.spv diff --git a/assets/core_assets/fonts/droid_sans.ttf b/assets/core_assets/fonts/droid_sans.ttf deleted file mode 100644 index 767c63ad000e3eea20f3cb7a43ba9f4154ed7a5d..0000000000000000000000000000000000000000 Binary files a/assets/core_assets/fonts/droid_sans.ttf and /dev/null differ diff --git a/assets/core_assets/fonts/immortal.ttf b/assets/core_assets/fonts/immortal.ttf deleted file mode 100644 index 146ad3c0b5c78e563b160cdad758c6c321fb9244..0000000000000000000000000000000000000000 Binary files a/assets/core_assets/fonts/immortal.ttf and /dev/null differ diff --git a/assets/core_assets/settings/gui.json b/assets/core_assets/settings/gui.json deleted file mode 100644 index c05e4705b82b0afe8f814391711adeabd9401b69..0000000000000000000000000000000000000000 --- a/assets/core_assets/settings/gui.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "fonts": [ - {"aid":"font:test_font", "size":12, "default_font":true} - ] -} diff --git a/assets/core_assets/settings/languages.json b/assets/core_assets/settings/languages.json deleted file mode 100644 index 5468c194da2ff1c603314d5bcded3cd880341425..0000000000000000000000000000000000000000 --- a/assets/core_assets/settings/languages.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "default_language": "en", - "supported_languages": ["en"] -} diff --git a/assets/core_assets/shader/bin/blit.frag.spv b/assets/core_assets/shader/bin/blit.frag.spv deleted file mode 100644 index e5d14c35be8724d1339556c3453fbc0208e6fbbd..0000000000000000000000000000000000000000 Binary files a/assets/core_assets/shader/bin/blit.frag.spv and /dev/null differ diff --git a/assets/core_assets/shader/bin/bloom_apply.frag.spv b/assets/core_assets/shader/bin/bloom_apply.frag.spv deleted file mode 100644 index b6750038968e5bdb329c69b267741d9d9ead938d..0000000000000000000000000000000000000000 Binary files a/assets/core_assets/shader/bin/bloom_apply.frag.spv and /dev/null differ diff --git a/assets/core_assets/shader/bin/bloom_blur.frag.spv b/assets/core_assets/shader/bin/bloom_blur.frag.spv deleted file mode 100644 index 5fece56e262252d4eac5d82c5fb95577961b35c4..0000000000000000000000000000000000000000 Binary files a/assets/core_assets/shader/bin/bloom_blur.frag.spv and /dev/null differ diff --git a/assets/core_assets/shader/bin/bloom_blur.vert.spv b/assets/core_assets/shader/bin/bloom_blur.vert.spv deleted file mode 100644 index b673973c9408b6ae3a6a8aab66adbafffc6520ee..0000000000000000000000000000000000000000 Binary files a/assets/core_assets/shader/bin/bloom_blur.vert.spv and /dev/null differ diff --git a/assets/core_assets/shader/bin/debug_draw.frag.spv b/assets/core_assets/shader/bin/debug_draw.frag.spv deleted file mode 100644 index 4391bf2ad91de036d81e633cd523ac1d4fde7a35..0000000000000000000000000000000000000000 Binary files a/assets/core_assets/shader/bin/debug_draw.frag.spv and /dev/null differ diff --git a/assets/core_assets/shader/bin/debug_draw.vert.spv b/assets/core_assets/shader/bin/debug_draw.vert.spv deleted file mode 100644 index 6812cb11a7eac2ddd9f4e7d71d154b4363963032..0000000000000000000000000000000000000000 Binary files a/assets/core_assets/shader/bin/debug_draw.vert.spv and /dev/null differ diff --git a/assets/core_assets/shader/bin/fullscreen.vert.spv b/assets/core_assets/shader/bin/fullscreen.vert.spv deleted file mode 100644 index f83bf62e19e626d359612477fd493930c1b8f23e..0000000000000000000000000000000000000000 Binary files a/assets/core_assets/shader/bin/fullscreen.vert.spv and /dev/null differ diff --git a/assets/core_assets/shader/bin/gi_blend.frag.spv b/assets/core_assets/shader/bin/gi_blend.frag.spv deleted file mode 100644 index 0c670efd0810f63b19cc5c8a101af2fc222ae412..0000000000000000000000000000000000000000 Binary files a/assets/core_assets/shader/bin/gi_blend.frag.spv and /dev/null differ diff --git a/assets/core_assets/shader/bin/gi_diffuse_reproject.frag.spv b/assets/core_assets/shader/bin/gi_diffuse_reproject.frag.spv deleted file mode 100644 index e35d3c4bd1add66b1f9ab8e5a5bf78bce77f0c78..0000000000000000000000000000000000000000 Binary files a/assets/core_assets/shader/bin/gi_diffuse_reproject.frag.spv and /dev/null differ diff --git a/assets/core_assets/shader/bin/gi_integrate_brdf.frag.spv b/assets/core_assets/shader/bin/gi_integrate_brdf.frag.spv deleted file mode 100644 index c96ed1a60429a87e4a4dbedc26f10ca37c27cf52..0000000000000000000000000000000000000000 Binary files a/assets/core_assets/shader/bin/gi_integrate_brdf.frag.spv and /dev/null differ diff --git a/assets/core_assets/shader/bin/gi_integrate_brdf.vert.spv b/assets/core_assets/shader/bin/gi_integrate_brdf.vert.spv deleted file mode 100644 index f83bf62e19e626d359612477fd493930c1b8f23e..0000000000000000000000000000000000000000 Binary files a/assets/core_assets/shader/bin/gi_integrate_brdf.vert.spv and /dev/null differ diff --git a/assets/core_assets/shader/bin/gi_mipgen.frag.spv b/assets/core_assets/shader/bin/gi_mipgen.frag.spv deleted file mode 100644 index 2610a473034a518b9bfb5ad0e4ecfd8d87a9ba76..0000000000000000000000000000000000000000 Binary files a/assets/core_assets/shader/bin/gi_mipgen.frag.spv and /dev/null differ diff --git a/assets/core_assets/shader/bin/gi_reproject.frag.spv b/assets/core_assets/shader/bin/gi_reproject.frag.spv deleted file mode 100644 index c433cb9fea41972eaf447041187838f239a51805..0000000000000000000000000000000000000000 Binary files a/assets/core_assets/shader/bin/gi_reproject.frag.spv and /dev/null differ diff --git a/assets/core_assets/shader/bin/gi_reprojection_weights.frag.spv b/assets/core_assets/shader/bin/gi_reprojection_weights.frag.spv deleted file mode 100644 index f66256dbe80b10e78054ea90772ec9876e0bd564..0000000000000000000000000000000000000000 Binary files a/assets/core_assets/shader/bin/gi_reprojection_weights.frag.spv and /dev/null differ diff --git a/assets/core_assets/shader/bin/gi_sample.frag.spv b/assets/core_assets/shader/bin/gi_sample.frag.spv deleted file mode 100644 index a1c12b04e3e9c1a74bb0d6d47e99ca78d00694eb..0000000000000000000000000000000000000000 Binary files a/assets/core_assets/shader/bin/gi_sample.frag.spv and /dev/null differ diff --git a/assets/core_assets/shader/bin/gi_sample_blend.frag.spv b/assets/core_assets/shader/bin/gi_sample_blend.frag.spv deleted file mode 100644 index 8e62f73bdddffd16d65656f5b19261911ba4bb01..0000000000000000000000000000000000000000 Binary files a/assets/core_assets/shader/bin/gi_sample_blend.frag.spv and /dev/null differ diff --git a/assets/core_assets/shader/bin/gi_sample_spec.frag.spv b/assets/core_assets/shader/bin/gi_sample_spec.frag.spv deleted file mode 100644 index 61972ac947ab41574bda440432259bb3c5b6fc0f..0000000000000000000000000000000000000000 Binary files a/assets/core_assets/shader/bin/gi_sample_spec.frag.spv and /dev/null differ diff --git a/assets/core_assets/shader/bin/gi_sample_upsample.frag.spv b/assets/core_assets/shader/bin/gi_sample_upsample.frag.spv deleted file mode 100644 index eb3c24b6e398cb96a637d56f22cafc7c6f33a84b..0000000000000000000000000000000000000000 Binary files a/assets/core_assets/shader/bin/gi_sample_upsample.frag.spv and /dev/null differ diff --git a/assets/core_assets/shader/bin/gi_spec_blur.frag.spv b/assets/core_assets/shader/bin/gi_spec_blur.frag.spv deleted file mode 100644 index 2a9d4ecb0fc245943f8352327af29cc0722b550b..0000000000000000000000000000000000000000 Binary files a/assets/core_assets/shader/bin/gi_spec_blur.frag.spv and /dev/null differ diff --git a/assets/core_assets/shader/bin/gi_spec_blur.vert.spv b/assets/core_assets/shader/bin/gi_spec_blur.vert.spv deleted file mode 100644 index 4f88b747efdd562669ea958f6b736a54215d22a6..0000000000000000000000000000000000000000 Binary files a/assets/core_assets/shader/bin/gi_spec_blur.vert.spv and /dev/null differ diff --git a/assets/core_assets/shader/bin/gi_weight_mipgen.frag.spv b/assets/core_assets/shader/bin/gi_weight_mipgen.frag.spv deleted file mode 100644 index bec60a5fa9d3fc0d8211a53089aad3d49e576510..0000000000000000000000000000000000000000 Binary files a/assets/core_assets/shader/bin/gi_weight_mipgen.frag.spv and /dev/null differ diff --git a/assets/core_assets/shader/bin/light_directional.frag.spv b/assets/core_assets/shader/bin/light_directional.frag.spv deleted file mode 100644 index 243f1c8c5ec6439202dc55206754b9be5946076b..0000000000000000000000000000000000000000 Binary files a/assets/core_assets/shader/bin/light_directional.frag.spv and /dev/null differ diff --git a/assets/core_assets/shader/bin/light_point.frag.spv b/assets/core_assets/shader/bin/light_point.frag.spv deleted file mode 100644 index cc6d236b816f554a5801f1c8619c90b7ef20de38..0000000000000000000000000000000000000000 Binary files a/assets/core_assets/shader/bin/light_point.frag.spv and /dev/null differ diff --git a/assets/core_assets/shader/bin/light_point.vert.spv b/assets/core_assets/shader/bin/light_point.vert.spv deleted file mode 100644 index 16dce111a5325e185390136bad5ff9d673acc6cf..0000000000000000000000000000000000000000 Binary files a/assets/core_assets/shader/bin/light_point.vert.spv and /dev/null differ diff --git a/assets/core_assets/shader/bin/luminance.frag.spv b/assets/core_assets/shader/bin/luminance.frag.spv deleted file mode 100644 index 5b54bc9bdfc517f8ecada9054101d8e9e5bb1c8d..0000000000000000000000000000000000000000 Binary files a/assets/core_assets/shader/bin/luminance.frag.spv and /dev/null differ diff --git a/assets/core_assets/shader/bin/luminance_adapt.frag.spv b/assets/core_assets/shader/bin/luminance_adapt.frag.spv deleted file mode 100644 index 372ef6a345af3316046acd0263ba6f71615db100..0000000000000000000000000000000000000000 Binary files a/assets/core_assets/shader/bin/luminance_adapt.frag.spv and /dev/null differ diff --git a/assets/core_assets/shader/bin/median_filter.frag.spv b/assets/core_assets/shader/bin/median_filter.frag.spv deleted file mode 100644 index c493073870257f19a8dd4be0e71e60af765fc521..0000000000000000000000000000000000000000 Binary files a/assets/core_assets/shader/bin/median_filter.frag.spv and /dev/null differ diff --git a/assets/core_assets/shader/bin/model.frag.spv b/assets/core_assets/shader/bin/model.frag.spv deleted file mode 100644 index 80de975f8301f64ad3931e81694a99bcba0e6528..0000000000000000000000000000000000000000 Binary files a/assets/core_assets/shader/bin/model.frag.spv and /dev/null differ diff --git a/assets/core_assets/shader/bin/model.vert.spv b/assets/core_assets/shader/bin/model.vert.spv deleted file mode 100644 index e8bc2f0429c90d5b2ad0123e365cef508ba3e993..0000000000000000000000000000000000000000 Binary files a/assets/core_assets/shader/bin/model.vert.spv and /dev/null differ diff --git a/assets/core_assets/shader/bin/model_alphatest.frag.spv b/assets/core_assets/shader/bin/model_alphatest.frag.spv deleted file mode 100644 index d1df2efceb84899f5d3a894479fa90fcdf1e9a9b..0000000000000000000000000000000000000000 Binary files a/assets/core_assets/shader/bin/model_alphatest.frag.spv and /dev/null differ diff --git a/assets/core_assets/shader/bin/model_animated.vert.spv b/assets/core_assets/shader/bin/model_animated.vert.spv deleted file mode 100644 index 3627aabf87ce121b13515c7b87ab260514d27a03..0000000000000000000000000000000000000000 Binary files a/assets/core_assets/shader/bin/model_animated.vert.spv and /dev/null differ diff --git a/assets/core_assets/shader/bin/model_animated_dqs.vert.spv b/assets/core_assets/shader/bin/model_animated_dqs.vert.spv deleted file mode 100644 index 7302d0e9943ddf5061f716c18c9c5be740461253..0000000000000000000000000000000000000000 Binary files a/assets/core_assets/shader/bin/model_animated_dqs.vert.spv and /dev/null differ diff --git a/assets/core_assets/shader/bin/model_emissive.frag.spv b/assets/core_assets/shader/bin/model_emissive.frag.spv deleted file mode 100644 index 89e3dc61ef35a6d89f9eb9ccf00b8ba8a21c3671..0000000000000000000000000000000000000000 Binary files a/assets/core_assets/shader/bin/model_emissive.frag.spv and /dev/null differ diff --git a/assets/core_assets/shader/bin/shadow_model.frag.spv b/assets/core_assets/shader/bin/shadow_model.frag.spv deleted file mode 100644 index fb22bd0b06863905699c00c5c9932dd31d4deca0..0000000000000000000000000000000000000000 Binary files a/assets/core_assets/shader/bin/shadow_model.frag.spv and /dev/null differ diff --git a/assets/core_assets/shader/bin/shadow_model.vert.spv b/assets/core_assets/shader/bin/shadow_model.vert.spv deleted file mode 100644 index c8096e10e990bce899cc5317f6d6936ba0943f3c..0000000000000000000000000000000000000000 Binary files a/assets/core_assets/shader/bin/shadow_model.vert.spv and /dev/null differ diff --git a/assets/core_assets/shader/bin/shadow_model_animated.vert.spv b/assets/core_assets/shader/bin/shadow_model_animated.vert.spv deleted file mode 100644 index 94028ed6dd711902575aeb1deaa09a84549dbe16..0000000000000000000000000000000000000000 Binary files a/assets/core_assets/shader/bin/shadow_model_animated.vert.spv and /dev/null differ diff --git a/assets/core_assets/shader/bin/shadow_model_animated_dqs.vert.spv b/assets/core_assets/shader/bin/shadow_model_animated_dqs.vert.spv deleted file mode 100644 index 25552e85469b2bcc02443c5e3f73abf689200101..0000000000000000000000000000000000000000 Binary files a/assets/core_assets/shader/bin/shadow_model_animated_dqs.vert.spv and /dev/null differ diff --git a/assets/core_assets/shader/bin/ssao.frag.spv b/assets/core_assets/shader/bin/ssao.frag.spv deleted file mode 100644 index 444009b9ac26ec74b7cf3f691276d86081c804fc..0000000000000000000000000000000000000000 Binary files a/assets/core_assets/shader/bin/ssao.frag.spv and /dev/null differ diff --git a/assets/core_assets/shader/bin/ssao_blur.frag.spv b/assets/core_assets/shader/bin/ssao_blur.frag.spv deleted file mode 100644 index 9bf4e2eca956c8e1cc6ce1ec61904309e200d2e7..0000000000000000000000000000000000000000 Binary files a/assets/core_assets/shader/bin/ssao_blur.frag.spv and /dev/null differ diff --git a/assets/core_assets/shader/bin/ssao_blur.vert.spv b/assets/core_assets/shader/bin/ssao_blur.vert.spv deleted file mode 100644 index bb65988e648a68beac9e9178395414ccf7186c8b..0000000000000000000000000000000000000000 Binary files a/assets/core_assets/shader/bin/ssao_blur.vert.spv and /dev/null differ diff --git a/assets/core_assets/shader/bin/taa.frag.spv b/assets/core_assets/shader/bin/taa.frag.spv deleted file mode 100644 index 4a6002d6b56bb8fb03540758c7273e9dec2831f1..0000000000000000000000000000000000000000 Binary files a/assets/core_assets/shader/bin/taa.frag.spv and /dev/null differ diff --git a/assets/core_assets/shader/bin/tone_mapping_adjust.comp.spv b/assets/core_assets/shader/bin/tone_mapping_adjust.comp.spv deleted file mode 100644 index 85ea6a8bab5bd89ea044336a4120bf5d51783dfa..0000000000000000000000000000000000000000 Binary files a/assets/core_assets/shader/bin/tone_mapping_adjust.comp.spv and /dev/null differ diff --git a/assets/core_assets/shader/bin/tone_mapping_apply.frag.spv b/assets/core_assets/shader/bin/tone_mapping_apply.frag.spv deleted file mode 100644 index d2bf5ba2cd8439be304865daea749af3ed46eb7e..0000000000000000000000000000000000000000 Binary files a/assets/core_assets/shader/bin/tone_mapping_apply.frag.spv and /dev/null differ diff --git a/assets/core_assets/shader/bin/tone_mapping_histogram.comp.spv b/assets/core_assets/shader/bin/tone_mapping_histogram.comp.spv deleted file mode 100644 index ddd63f03e08babc3af00f05cd5050ee2172605e4..0000000000000000000000000000000000000000 Binary files a/assets/core_assets/shader/bin/tone_mapping_histogram.comp.spv and /dev/null differ diff --git a/assets/core_assets/shader/bin/ui.frag.spv b/assets/core_assets/shader/bin/ui.frag.spv deleted file mode 100644 index dcaac90105c6b1be93cc05aeee92f3feb77791c6..0000000000000000000000000000000000000000 Binary files a/assets/core_assets/shader/bin/ui.frag.spv and /dev/null differ diff --git a/assets/core_assets/shader/bin/ui.vert.spv b/assets/core_assets/shader/bin/ui.vert.spv deleted file mode 100644 index f008a4eb7699c069bec0de58eed13f6b46b435e4..0000000000000000000000000000000000000000 Binary files a/assets/core_assets/shader/bin/ui.vert.spv and /dev/null differ diff --git a/assets/core_assets/shader/median_filter.frag b/assets/core_assets/shader/median_filter.frag deleted file mode 100644 index 2d08803d1670863ed6e4a2c323448e0cee8b7bb8..0000000000000000000000000000000000000000 --- a/assets/core_assets/shader/median_filter.frag +++ /dev/null @@ -1,60 +0,0 @@ -#version 450 -#extension GL_ARB_separate_shader_objects : enable -#extension GL_ARB_shading_language_420pack : enable - - -layout(location = 0) in Vertex_data { - vec2 tex_coords; -} vertex_out; - -layout(location = 0) out vec4 out_color; - -layout(set=1, binding = 0) uniform sampler2D color_sampler; - -// A Fast, Small-Radius GPU Median Filter by Morgan McGuire: http://casual-effects.com/research/McGuire2008Median/index.html -#define s2(a, b) temp = a; a = min(a, b); b = max(temp, b); -#define mn3(a, b, c) s2(a, b); s2(a, c); -#define mx3(a, b, c) s2(b, c); s2(a, c); - -#define mnmx3(a, b, c) mx3(a, b, c); s2(a, b); // 3 exchanges -#define mnmx4(a, b, c, d) s2(a, b); s2(c, d); s2(a, c); s2(b, d); // 4 exchanges -#define mnmx5(a, b, c, d, e) s2(a, b); s2(c, d); mn3(a, c, e); mx3(b, d, e); // 6 exchanges -#define mnmx6(a, b, c, d, e, f) s2(a, d); s2(b, e); s2(c, f); mn3(a, b, c); mx3(d, e, f); // 7 exchanges - -void main() { - ivec2 result_sampler_size = textureSize(color_sampler, 0).xy; - ivec2 uv = ivec2(textureSize(color_sampler, 0).xy * vertex_out.tex_coords); - vec3 colors[9]; - for(int x=-1; x<=1; x++) { - for(int y=-1; y<=1; y++) { - ivec2 c_uv = uv+ivec2(x,y); - c_uv = clamp(c_uv, ivec2(0,0), result_sampler_size-ivec2(1,1)); - colors[(x+1)*3+(y+1)] = texelFetch(color_sampler, c_uv, 0).rgb; - } - } - - float min_c = dot(colors[0], colors[0]); - float max_c = min_c; - - for(int i=1; i<9; i++) { - float intensity = dot(colors[i], colors[i]); - min_c = min(min_c, intensity); - max_c = max(max_c, intensity); - } - - vec3 org = colors[4]; - float org_intensity = dot(org, org); - if(min_corg_intensity) { - out_color = vec4(org, 1.0); - - } else { - // Starting with a subset of size 6, remove the min and max each time - vec3 temp; - mnmx6(colors[0], colors[1], colors[2], colors[3], colors[4], colors[5]); - mnmx5(colors[1], colors[2], colors[3], colors[4], colors[6]); - mnmx4(colors[2], colors[3], colors[4], colors[7]); - mnmx3(colors[3], colors[4], colors[8]); - out_color = vec4(colors[4], 1.0); - } - //out_color = vec4(org, 1.0); -} diff --git a/assets/core_assets/textures/blue_noise.ktx b/assets/core_assets/textures/blue_noise.ktx deleted file mode 100644 index debd72ce42703028d22954402cd1329b8d9b0a9c..0000000000000000000000000000000000000000 Binary files a/assets/core_assets/textures/blue_noise.ktx and /dev/null differ diff --git a/assets/core_assets/textures/default_black.png b/assets/core_assets/textures/default_black.png deleted file mode 100644 index bba5c08abd7297b58f5ed7ee7c5e3eabc1a2c1ee..0000000000000000000000000000000000000000 Binary files a/assets/core_assets/textures/default_black.png and /dev/null differ diff --git a/assets/core_assets/textures/default_normal.png b/assets/core_assets/textures/default_normal.png deleted file mode 100644 index cdaf0a41b55de317a21b00fa201ed77cfebd7054..0000000000000000000000000000000000000000 Binary files a/assets/core_assets/textures/default_normal.png and /dev/null differ diff --git a/assets/core_assets/textures/default_placeholder.ktx b/assets/core_assets/textures/default_placeholder.ktx deleted file mode 100644 index c63c95b3c5ee651750c3c006e9d4bcdcebfff12e..0000000000000000000000000000000000000000 Binary files a/assets/core_assets/textures/default_placeholder.ktx and /dev/null differ diff --git a/assets/core_assets/textures/default_placeholder.png b/assets/core_assets/textures/default_placeholder.png deleted file mode 100644 index 91802e1c089f2a0802943cccaf56edb71c8c2598..0000000000000000000000000000000000000000 Binary files a/assets/core_assets/textures/default_placeholder.png and /dev/null differ diff --git a/assets/core_assets/textures/default_white.ktx b/assets/core_assets/textures/default_white.ktx deleted file mode 100644 index 171d8d97109b08bd92322d08aff4094ff7e2c7ec..0000000000000000000000000000000000000000 Binary files a/assets/core_assets/textures/default_white.ktx and /dev/null differ diff --git a/assets/core_assets/textures/default_white.png b/assets/core_assets/textures/default_white.png deleted file mode 100644 index 2a2f75c8b6300d174a4d8dc72455c3e06c60eaf8..0000000000000000000000000000000000000000 Binary files a/assets/core_assets/textures/default_white.png and /dev/null differ diff --git a/assets/demo_assets/assets_blueprints.map b/assets/demo_assets/assets_blueprints.map index a116788d94991ca188c05074c02bca9adfbdf35a..60a17a3d33bf16c97b9ac67eb31b75c9fc82e22d 100644 --- a/assets/demo_assets/assets_blueprints.map +++ b/assets/demo_assets/assets_blueprints.map @@ -1,6 +1 @@ -blueprint:camera = blueprints/camera.json -blueprint:sponza = blueprints/sponza.json -blueprint:cornell = blueprints/cornell.json -blueprint:sun = blueprints/sun.json -blueprint:cube = blueprints/cube.json - +blueprint: = blueprints/*.json diff --git a/assets/demo_assets/assets_model.map b/assets/demo_assets/assets_model.map index a01887e28cbcd3501266596030206e527e5be7cc..c4155c08c6826be9c84ac2ac170b44694d4cb7f8 100644 --- a/assets/demo_assets/assets_model.map +++ b/assets/demo_assets/assets_model.map @@ -1,5 +1,2 @@ -model: = models/ -mat: = materials/ - -model:cube = models/cube.mmf - +model: = models/*.mmf +mat: = materials/*.msf diff --git a/assets/demo_assets/assets_particles.map b/assets/demo_assets/assets_particles.map new file mode 100644 index 0000000000000000000000000000000000000000..12b099cc95d62793b977fb73a4aa75f1d7c08bea --- /dev/null +++ b/assets/demo_assets/assets_particles.map @@ -0,0 +1,8 @@ +particle: = particles/ + +particle_def:test_particles = particles/test_particles.json +particle_sys:test_particles = particles/test_particle_system.json + +particle_def:test_smoke_particles = particles/test_smoke_particles.json +particle_sys:test_smoke_particles = particles/test_smoke_system.json + diff --git a/assets/demo_assets/blueprints/billboard.json b/assets/demo_assets/blueprints/billboard.json new file mode 100644 index 0000000000000000000000000000000000000000..33e210c2dd1d47d302a848f241b02fc462d8ef2a --- /dev/null +++ b/assets/demo_assets/blueprints/billboard.json @@ -0,0 +1,14 @@ +{ + "Transform":{ + }, + "Billboard": { + "billboards": [ + { + "size": {"w":1, "h":1}, + "material_aid": "mat:billboard_material.msf", + "clip_rect": {"x":0, "y":0, "z":1, "w":1}, + "dynamic_lighting": true + } + ] + } +} diff --git a/assets/demo_assets/blueprints/decal.json b/assets/demo_assets/blueprints/decal.json new file mode 100644 index 0000000000000000000000000000000000000000..295bf3080b1e72cb035a5c5d3255ab4bd96c317b --- /dev/null +++ b/assets/demo_assets/blueprints/decal.json @@ -0,0 +1,15 @@ +{ + "Transform":{ + }, + "Decal": { + "decals": [ + { + "size": {"w":1, "h":1}, + "material_aid": "mat:decal_material.msf", + "clip_rect": {"x":0, "y":0, "z":1, "w":1}, + "thickness": 0.2, + "color": {"a":0.25} + } + ] + } +} diff --git a/assets/demo_assets/blueprints/sun.json b/assets/demo_assets/blueprints/sun.json index 8431ca9e010ff1c33805ef7053ec79c739c2b3ab..9cba8b67b55cea5adb82d24d016f77b7c4dec2be 100644 --- a/assets/demo_assets/blueprints/sun.json +++ b/assets/demo_assets/blueprints/sun.json @@ -3,12 +3,15 @@ }, "Directional_light": { "source_radius": 0.8, - "intensity": 140000.0, + "intensity": 130000.0, "temperature": 4500, + "shadow_intensity": 2.0, + "shadow_temperature": 4000, "shadow_size": 24, "near_plane": 1.0, "far_plane": 80, - "update_frequency": 1 + "update_frequency": 1, + "light_particles": true }, "Shadowcaster": { }, diff --git a/assets/demo_assets/blueprints/test_particle_emitter.json b/assets/demo_assets/blueprints/test_particle_emitter.json new file mode 100644 index 0000000000000000000000000000000000000000..a6b452f56fe0efeae0a25afc09d9fe39b2b5dcc6 --- /dev/null +++ b/assets/demo_assets/blueprints/test_particle_emitter.json @@ -0,0 +1,11 @@ +{ + "Transform":{ + "scale": {"x": 0.1, "y": 0.1, "z": 0.1} + }, + "Model": { + "aid": "model:cube" + }, + "Particle_system": { + "cfg": "particle_sys:test_particles" + } +} diff --git a/assets/demo_assets/blueprints/test_smoke_emitter.json b/assets/demo_assets/blueprints/test_smoke_emitter.json new file mode 100644 index 0000000000000000000000000000000000000000..6f978e034e062fcf821576e4c1e246402c7a6f23 --- /dev/null +++ b/assets/demo_assets/blueprints/test_smoke_emitter.json @@ -0,0 +1,11 @@ +{ + "Transform":{ + "scale": {"x": 0.1, "y": 0.1, "z": 0.1} + }, + "Model": { + "aid": "model:cube" + }, + "Particle_system": { + "cfg": "particle_sys:test_smoke_particles" + } +} diff --git a/assets/demo_assets/materials/billboard_material.msf b/assets/demo_assets/materials/billboard_material.msf new file mode 100644 index 0000000000000000000000000000000000000000..f27950ba42134e921b89021d125c1b353701f503 --- /dev/null +++ b/assets/demo_assets/materials/billboard_material.msf @@ -0,0 +1,4 @@ +{ + "albedo_aid": "billboard.ktx", + "emission_aid": "white" +} diff --git a/assets/demo_assets/materials/cube_Material.msf b/assets/demo_assets/materials/cube_Material.msf index 9504a0a2a86797715850125d40c1a0f50eeca966..a0dd972a92aaf5af13926b295219b2bb6c02a002 100644 --- a/assets/demo_assets/materials/cube_Material.msf +++ b/assets/demo_assets/materials/cube_Material.msf @@ -1,4 +1,5 @@ { - "substance_id": "emissive", - "albedo_aid": "cube_light.ktx" + "substance_id": "default", + "albedo_aid": "cube_light.ktx", + "emission_aid": "default_white.ktx" } diff --git a/assets/demo_assets/materials/decal_material.msf b/assets/demo_assets/materials/decal_material.msf new file mode 100644 index 0000000000000000000000000000000000000000..34402e2aaa6a1bd3f5e11a61df78a8477d2c086e --- /dev/null +++ b/assets/demo_assets/materials/decal_material.msf @@ -0,0 +1,4 @@ +{ + "albedo_aid": "billboard.ktx", + "normal_aid": "sponza_bricks_normal.ktx" +} diff --git a/assets/demo_assets/models/cube.mmf b/assets/demo_assets/models/cube.mmf index 672ea6a41b0b992676fb844d85e319c8fe74e597..cf28fcde7a5269c15e62bf0e1c244a50ebb11429 100644 Binary files a/assets/demo_assets/models/cube.mmf and b/assets/demo_assets/models/cube.mmf differ diff --git a/assets/demo_assets/particles/test_particle_system.json b/assets/demo_assets/particles/test_particle_system.json new file mode 100644 index 0000000000000000000000000000000000000000..fd8e1fcc3dcd858da0d44c144738e853a7b6a784 --- /dev/null +++ b/assets/demo_assets/particles/test_particle_system.json @@ -0,0 +1,29 @@ +{ + "emitters": [{ + "spawn": [ + {"particles_per_second": 20000, "stddev":0, "time": 1}, + {"particles_per_second": 0, "stddev":0, "time": 20} + ], + "spawn_loop": true, + + "size": {"x":0, "y":0}, + "direction": {"mean":{"elevation":0.85, "azimuth":-0.25}, "stddev":{"elevation":0.1, "azimuth":0.1}}, + + "ttl": {"mean": 4, "stddev": 0.5}, + + "velocity": {"mean": 32, "stddev": 8.0}, + + "emit_script_id": "comp_shader:particle_spawn_sphere", + + "type_id": "particle_def:test_particles" + }], + + "effectors": [ + { + "force": 10, + "force_dir": {"y":-1}, + "distance_decay": 0, + "scale_with_mass": false + } + ] +} diff --git a/assets/demo_assets/particles/test_particles.json b/assets/demo_assets/particles/test_particles.json new file mode 100644 index 0000000000000000000000000000000000000000..07a7a15e7ee3c19e6a0e983fd7ed5542a9bbdc0a --- /dev/null +++ b/assets/demo_assets/particles/test_particles.json @@ -0,0 +1,30 @@ +{ + "keyframes": [ + { + "time": 0, + "color": {"mean":{"hue":0, "saturation":1}, "stddev":{"hue":0.5}}, + "size": {"mean": {"x": 0.05, "y":0.15, "z":0.04}, "stddev":{"x": 0.04, "y":0.02, "z":0.02}}, + "rotation": {"mean":{"angle":0}, "stddev":{"elevation":1, "azimuth":1, "angle": 1}}, + "drag": 0.1 + }, + { + "time": 4, + "color": {"mean":{"hue":0, "saturation":1}, "stddev":{"hue":1}}, + "size": {"mean": {"x": 0.01, "y":0.1, "z":0.01}}, + "rotation": {"mean":{"angle":1}, "stddev":{"elevation":1, "azimuth":1, "angle": 1}}, + "drag": 1.0 + } + ], + + "symmetric_scaling": true, + "rotate_with_velocity": false, + "blend": "solid", +/* + "geometry": "billboard", + "material_id": "mat:billboard_material.msf", +*/ + "geometry": "mesh", + "model_id": "model:cube", + + "update_script_id": "comp_shader:particle_update_simple" +} diff --git a/assets/demo_assets/particles/test_smoke_particles.json b/assets/demo_assets/particles/test_smoke_particles.json new file mode 100644 index 0000000000000000000000000000000000000000..c324d1e36c0edbc98fe9f8079d0dce542abd2e73 --- /dev/null +++ b/assets/demo_assets/particles/test_smoke_particles.json @@ -0,0 +1,135 @@ +{ + "keyframes": [ + { + "time": 0.1, + "color": {"mean":{"value":0.8, "alpha":0.5}, "stddev":{"value":0.2}}, + "size": {"mean": {"x": 0.5}, "stddev":{"x": 0.1}}, + "rotation": {"mean":{"angle":0}, "stddev":{"angle": 1}}, + "clip_rect": {"x":0, "y":0, "z":0.2, "w":0.333}, + "drag": 0.1 + }, + { + "time": 0.2, + "color": {"mean":{"value":0.8, "alpha":0.5}, "stddev":{"value":0.2}}, + "size": {"mean": {"x": 0.5}, "stddev":{"x": 0.1}}, + "rotation": {"mean":{"angle":0}, "stddev":{"angle": 1}}, + "clip_rect": {"x":0.2, "y":0, "z":0.2, "w":0.333}, + "drag": 0.1 + }, + { + "time": 0.3, + "color": {"mean":{"value":0.8, "alpha":0.5}, "stddev":{"value":0.2}}, + "size": {"mean": {"x": 0.5}, "stddev":{"x": 0.1}}, + "rotation": {"mean":{"angle":0}, "stddev":{"angle": 1}}, + "clip_rect": {"x":0.4, "y":0, "z":0.2, "w":0.333}, + "drag": 0.1 + }, + { + "time": 0.4, + "color": {"mean":{"value":0.8, "alpha":0.5}, "stddev":{"value":0.2}}, + "size": {"mean": {"x": 0.5}, "stddev":{"x": 0.1}}, + "rotation": {"mean":{"angle":0}, "stddev":{"angle": 1}}, + "clip_rect": {"x":0.6, "y":0, "z":0.2, "w":0.333}, + "drag": 0.1 + }, + { + "time": 0.5, + "color": {"mean":{"value":0.8, "alpha":0.5}, "stddev":{"value":0.2}}, + "size": {"mean": {"x": 0.5}, "stddev":{"x": 0.1}}, + "rotation": {"mean":{"angle":0}, "stddev":{"angle": 1}}, + "clip_rect": {"x":0.8, "y":0, "z":0.2, "w":0.333}, + "drag": 0.1 + }, + { + "time": 0.6, + "color": {"mean":{"value":0.8, "alpha":0.5}, "stddev":{"value":0.2}}, + "size": {"mean": {"x": 0.5}, "stddev":{"x": 0.1}}, + "rotation": {"mean":{"angle":0}, "stddev":{"angle": 1}}, + "clip_rect": {"x":0, "y":0.333, "z":0.2, "w":0.333}, + "drag": 0.1 + }, + { + "time": 0.7, + "color": {"mean":{"value":0.8, "alpha":0.5}, "stddev":{"value":0.2}}, + "size": {"mean": {"x": 0.5}, "stddev":{"x": 0.1}}, + "rotation": {"mean":{"angle":0}, "stddev":{"angle": 1}}, + "clip_rect": {"x":0.2, "y":0.333, "z":0.2, "w":0.333}, + "drag": 0.1 + }, + { + "time": 0.8, + "color": {"mean":{"value":0.8, "alpha":0.5}, "stddev":{"value":0.2}}, + "size": {"mean": {"x": 0.5}, "stddev":{"x": 0.1}}, + "rotation": {"mean":{"angle":0}, "stddev":{"angle": 1}}, + "clip_rect": {"x":0.4, "y":0.333, "z":0.2, "w":0.333}, + "drag": 0.1 + }, + { + "time": 0.9, + "color": {"mean":{"value":0.8, "alpha":0.5}, "stddev":{"value":0.2}}, + "size": {"mean": {"x": 0.5}, "stddev":{"x": 0.1}}, + "rotation": {"mean":{"angle":0}, "stddev":{"angle": 1}}, + "clip_rect": {"x":0.6, "y":0.333, "z":0.2, "w":0.333}, + "drag": 0.1 + }, + { + "time": 1, + "color": {"mean":{"value":0.8, "alpha":0.5}, "stddev":{"value":0.2}}, + "size": {"mean": {"x": 0.5}, "stddev":{"x": 0.1}}, + "rotation": {"mean":{"angle":0}, "stddev":{"angle": 1}}, + "clip_rect": {"x":0.8, "y":0.333, "z":0.2, "w":0.333}, + "drag": 0.1 + }, + { + "time": 1.1, + "color": {"mean":{"value":0.8, "alpha":0.5}, "stddev":{"value":0.2}}, + "size": {"mean": {"x": 0.5}, "stddev":{"x": 0.1}}, + "rotation": {"mean":{"angle":0}, "stddev":{"angle": 1}}, + "clip_rect": {"x":0, "y":0.666, "z":0.2, "w":0.333}, + "drag": 0.1 + }, + { + "time": 1.2, + "color": {"mean":{"value":0.8, "alpha":0.5}, "stddev":{"value":0.2}}, + "size": {"mean": {"x": 0.5}, "stddev":{"x": 0.1}}, + "rotation": {"mean":{"angle":0}, "stddev":{"angle": 1}}, + "clip_rect": {"x":0.2, "y":0.666, "z":0.2, "w":0.333}, + "drag": 0.1 + }, + { + "time": 1.3, + "color": {"mean":{"value":0.8, "alpha":0.5}, "stddev":{"value":0.2}}, + "size": {"mean": {"x": 0.5}, "stddev":{"x": 0.1}}, + "rotation": {"mean":{"angle":0}, "stddev":{"angle": 1}}, + "clip_rect": {"x":0.4, "y":0.666, "z":0.2, "w":0.333}, + "drag": 0.1 + }, + { + "time": 1.4, + "color": {"mean":{"value":0.8, "alpha":0.5}, "stddev":{"value":0.2}}, + "size": {"mean": {"x": 0.5}, "stddev":{"x": 0.1}}, + "rotation": {"mean":{"angle":0}, "stddev":{"angle": 1}}, + "clip_rect": {"x":0.6, "y":0.666, "z":0.2, "w":0.333}, + "drag": 0.1 + }, + { + "time": 1.5, + "color": {"mean":{"value":0.8, "alpha":0.5}, "stddev":{"value":0.2}}, + "size": {"mean": {"x": 0.5}, "stddev":{"x": 0.1}}, + "rotation": {"mean":{"angle":0}, "stddev":{"angle": 1}}, + "clip_rect": {"x":0.8, "y":0.666, "z":0.2, "w":0.333}, + "drag": 0.1 + } + ], + + "loop_keyframe_time": 1.5, + + "symmetric_scaling": true, + "rotate_with_velocity": false, + "blend": "transparent", + + "geometry": "billboard", + "material_id": "tex:smoke_particle.ktx", + + "update_script_id": "comp_shader:particle_update_simple" +} diff --git a/assets/demo_assets/particles/test_smoke_system.json b/assets/demo_assets/particles/test_smoke_system.json new file mode 100644 index 0000000000000000000000000000000000000000..67ee433132b1b829cb82aae7fd26209c48f98283 --- /dev/null +++ b/assets/demo_assets/particles/test_smoke_system.json @@ -0,0 +1,19 @@ +{ + "emitters": [{ + "spawn": [ + {"particles_per_second": 200, "stddev":5, "time": 1} + ], + "spawn_loop": true, + + "size": {"x":0, "y":0}, + "direction": {"mean":{"elevation":-1, "azimuth":0}, "stddev":{"elevation":0.4, "azimuth":0.4}}, + + "ttl": {"mean": 30, "stddev": 0}, + + "velocity": {"mean": 0.01, "stddev": 0.008}, + + "emit_script_id": "comp_shader:particle_spawn_sphere", + + "type_id": "particle_def:test_smoke_particles" + }] +} diff --git a/assets/demo_assets/settings/input_mapping.json b/assets/demo_assets/settings/input_mapping.json index 7a3cd8c80edc5d2553684ba565557ac840dd6bf5..3ade562b4e16e3a02bb7b2f7ad3cb02692d36b10 100644 --- a/assets/demo_assets/settings/input_mapping.json +++ b/assets/demo_assets/settings/input_mapping.json @@ -32,7 +32,9 @@ "F3": {"type":"once", "action":"playback"}, "Space": {"type":"once", "action":"pause"}, - "F11": {"type":"once", "action":"toggle_ui"} + "F11": {"type":"once", "action":"toggle_ui"}, + + "Caret": {"type":"once", "action":"console"} }, "pad_sticks": { diff --git a/assets/demo_assets/textures/billboard.ktx b/assets/demo_assets/textures/billboard.ktx new file mode 100644 index 0000000000000000000000000000000000000000..e0a3f20c35376511768a9c2fd198cb7874356f00 --- /dev/null +++ b/assets/demo_assets/textures/billboard.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:10073647350e106a963edb860925fb1e6f8a3cf94592454dbf376044ac88181a +size 349616 diff --git a/assets/demo_assets/textures/cube_light.ktx b/assets/demo_assets/textures/cube_light.ktx index 42f590502fa8115fda9ba2edd44d69d5e2471def..2af99ae57bdb2a49211970e8981544e650a28c1a 100644 Binary files a/assets/demo_assets/textures/cube_light.ktx and b/assets/demo_assets/textures/cube_light.ktx differ diff --git a/assets/demo_assets/textures/smoke_particle.ktx b/assets/demo_assets/textures/smoke_particle.ktx new file mode 100644 index 0000000000000000000000000000000000000000..d2dd86dede9a3506d45622ea3bf22074c96c182c --- /dev/null +++ b/assets/demo_assets/textures/smoke_particle.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6465cf49910624c557674465baa2f4360af9537142de46705e378302eca48356 +size 1310832 diff --git a/assets/extensions/cornell/materials/cornell_floor.msf b/assets/extensions/cornell/materials/cornell_floor.msf new file mode 100644 index 0000000000000000000000000000000000000000..782a09bd846d39a25710fe4386b4454a894f251d --- /dev/null +++ b/assets/extensions/cornell/materials/cornell_floor.msf @@ -0,0 +1,7 @@ +{ + "substance_id": "default", + "albedo_aid": "cornell_floor_albedo.ktx", + "normal_aid": "cornell_floor_normal.ktx", + "brdf_aid": "cornell_floor_brdf.ktx", + "emission_aid": "" +} diff --git a/assets/extensions/cornell/materials/cornell_leftwall.msf b/assets/extensions/cornell/materials/cornell_leftwall.msf new file mode 100644 index 0000000000000000000000000000000000000000..a19e317d1ace56050a543d41a4761ea90aa3d674 --- /dev/null +++ b/assets/extensions/cornell/materials/cornell_leftwall.msf @@ -0,0 +1,7 @@ +{ + "substance_id": "default", + "albedo_aid": "cornell_leftwall_albedo.ktx", + "normal_aid": "cornell_leftwall_normal.ktx", + "brdf_aid": "cornell_leftwall_brdf.ktx", + "emission_aid": "" +} diff --git a/assets/extensions/cornell/materials/cornell_light.msf b/assets/extensions/cornell/materials/cornell_light.msf new file mode 100644 index 0000000000000000000000000000000000000000..19b947a6cad80e1eb7a5e3c7129bac1643e8950a --- /dev/null +++ b/assets/extensions/cornell/materials/cornell_light.msf @@ -0,0 +1,7 @@ +{ + "substance_id": "alphatest", + "albedo_aid": "cornell_light_albedo.ktx", + "normal_aid": "cornell_light_normal.ktx", + "brdf_aid": "cornell_light_brdf.ktx", + "emission_aid": "cornell_light_emission.ktx" +} diff --git a/assets/extensions/cornell/materials/cornell_rightwall.msf b/assets/extensions/cornell/materials/cornell_rightwall.msf new file mode 100644 index 0000000000000000000000000000000000000000..cc7298daf923ac4bc630d450bc2304a061ef9f0b --- /dev/null +++ b/assets/extensions/cornell/materials/cornell_rightwall.msf @@ -0,0 +1,7 @@ +{ + "substance_id": "default", + "albedo_aid": "cornell_rightwall_albedo.ktx", + "normal_aid": "cornell_rightwall_normal.ktx", + "brdf_aid": "cornell_rightwall_brdf.ktx", + "emission_aid": "" +} diff --git a/assets/extensions/cornell/materials/cornell_shortbox.msf b/assets/extensions/cornell/materials/cornell_shortbox.msf new file mode 100644 index 0000000000000000000000000000000000000000..557cce11713f8e04de0c5beb93cf1b2380cc6a93 --- /dev/null +++ b/assets/extensions/cornell/materials/cornell_shortbox.msf @@ -0,0 +1,7 @@ +{ + "substance_id": "default", + "albedo_aid": "cornell_shortbox_albedo.ktx", + "normal_aid": "cornell_shortbox_normal.ktx", + "brdf_aid": "cornell_shortbox_brdf.ktx", + "emission_aid": "" +} diff --git a/assets/extensions/cornell/materials/cornell_sphere.msf b/assets/extensions/cornell/materials/cornell_sphere.msf new file mode 100644 index 0000000000000000000000000000000000000000..21683b47428ed820dbfd02667fec9449d036bc3e --- /dev/null +++ b/assets/extensions/cornell/materials/cornell_sphere.msf @@ -0,0 +1,7 @@ +{ + "substance_id": "default", + "albedo_aid": "cornell_sphere_albedo.ktx", + "normal_aid": "cornell_sphere_normal.ktx", + "brdf_aid": "cornell_sphere_brdf.ktx", + "emission_aid": "" +} diff --git a/assets/extensions/cornell/models/cornell.mmf b/assets/extensions/cornell/models/cornell.mmf new file mode 100644 index 0000000000000000000000000000000000000000..018cb9c28107b638c936c939cbc2b5a16e8ce912 --- /dev/null +++ b/assets/extensions/cornell/models/cornell.mmf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ca4162a178d93c7b9d52bdbc701ccad9d3ee5cd72966d518227e04d7bada45ed +size 35297 diff --git a/assets/extensions/cornell/textures/cornell_floor_albedo.ktx b/assets/extensions/cornell/textures/cornell_floor_albedo.ktx new file mode 100644 index 0000000000000000000000000000000000000000..5c4da75e58b931afa4ba2642c51f0d2fe376fec8 --- /dev/null +++ b/assets/extensions/cornell/textures/cornell_floor_albedo.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:24f971711f127f6507f4000779f4b1d9a11851ad26dc4af49a10229fbf96efd7 +size 5592512 diff --git a/assets/extensions/cornell/textures/cornell_floor_brdf.ktx b/assets/extensions/cornell/textures/cornell_floor_brdf.ktx new file mode 100644 index 0000000000000000000000000000000000000000..369d0f9875bfcdc95d9a1a7d05902c636b615249 --- /dev/null +++ b/assets/extensions/cornell/textures/cornell_floor_brdf.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8e881b227e190bfa3db97fb9d65f85641992309ef7ec762a43f6968852e28769 +size 2796312 diff --git a/assets/extensions/cornell/textures/cornell_floor_normal.ktx b/assets/extensions/cornell/textures/cornell_floor_normal.ktx new file mode 100644 index 0000000000000000000000000000000000000000..b140be1972d6ceb8787864b9e8cda528b82af308 --- /dev/null +++ b/assets/extensions/cornell/textures/cornell_floor_normal.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:91527266078d432988ab9a9d63cb2542e3560b8f2c71f39105c7c48eb802a572 +size 2796312 diff --git a/assets/extensions/cornell/textures/cornell_leftwall_albedo.ktx b/assets/extensions/cornell/textures/cornell_leftwall_albedo.ktx new file mode 100644 index 0000000000000000000000000000000000000000..7a48cb7ec09190bc3d31f9191d6ecedd56920c00 --- /dev/null +++ b/assets/extensions/cornell/textures/cornell_leftwall_albedo.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:da3c54f19ca4cca2910cf2beb68c43289bc519d4d4458612280bc4c612c508de +size 5592512 diff --git a/assets/extensions/cornell/textures/cornell_leftwall_brdf.ktx b/assets/extensions/cornell/textures/cornell_leftwall_brdf.ktx new file mode 100644 index 0000000000000000000000000000000000000000..369d0f9875bfcdc95d9a1a7d05902c636b615249 --- /dev/null +++ b/assets/extensions/cornell/textures/cornell_leftwall_brdf.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8e881b227e190bfa3db97fb9d65f85641992309ef7ec762a43f6968852e28769 +size 2796312 diff --git a/assets/extensions/cornell/textures/cornell_leftwall_normal.ktx b/assets/extensions/cornell/textures/cornell_leftwall_normal.ktx new file mode 100644 index 0000000000000000000000000000000000000000..b140be1972d6ceb8787864b9e8cda528b82af308 --- /dev/null +++ b/assets/extensions/cornell/textures/cornell_leftwall_normal.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:91527266078d432988ab9a9d63cb2542e3560b8f2c71f39105c7c48eb802a572 +size 2796312 diff --git a/assets/extensions/cornell/textures/cornell_light_albedo.ktx b/assets/extensions/cornell/textures/cornell_light_albedo.ktx new file mode 100644 index 0000000000000000000000000000000000000000..5043db09f618b5b1301b960b41297f2215c3f588 --- /dev/null +++ b/assets/extensions/cornell/textures/cornell_light_albedo.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dcd9685cf2b5b527ad49a654f3922a53a44124dc4cf34b75e926b6e1abb42ce0 +size 5592512 diff --git a/assets/extensions/cornell/textures/cornell_light_brdf.ktx b/assets/extensions/cornell/textures/cornell_light_brdf.ktx new file mode 100644 index 0000000000000000000000000000000000000000..369d0f9875bfcdc95d9a1a7d05902c636b615249 --- /dev/null +++ b/assets/extensions/cornell/textures/cornell_light_brdf.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8e881b227e190bfa3db97fb9d65f85641992309ef7ec762a43f6968852e28769 +size 2796312 diff --git a/assets/extensions/cornell/textures/cornell_light_emission.ktx b/assets/extensions/cornell/textures/cornell_light_emission.ktx new file mode 100644 index 0000000000000000000000000000000000000000..cbe50f7cebf1ae93cc65b6c2a169d243fb0cede6 --- /dev/null +++ b/assets/extensions/cornell/textures/cornell_light_emission.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9fb46dc75c85e13e5846d3fc10a3edf9af169c41c13d13de078ba9a077ccd8fb +size 4164 diff --git a/assets/extensions/cornell/textures/cornell_light_normal.ktx b/assets/extensions/cornell/textures/cornell_light_normal.ktx new file mode 100644 index 0000000000000000000000000000000000000000..b140be1972d6ceb8787864b9e8cda528b82af308 --- /dev/null +++ b/assets/extensions/cornell/textures/cornell_light_normal.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:91527266078d432988ab9a9d63cb2542e3560b8f2c71f39105c7c48eb802a572 +size 2796312 diff --git a/assets/extensions/cornell/textures/cornell_rightwall_albedo.ktx b/assets/extensions/cornell/textures/cornell_rightwall_albedo.ktx new file mode 100644 index 0000000000000000000000000000000000000000..9196bc6360e83d130e20b6cfe7b04a60c1706a41 --- /dev/null +++ b/assets/extensions/cornell/textures/cornell_rightwall_albedo.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:37cb5b0d108576b2d9262d20c16d3d4f9a172d0d56438f913146453d9cb8ea44 +size 5592512 diff --git a/assets/extensions/cornell/textures/cornell_rightwall_brdf.ktx b/assets/extensions/cornell/textures/cornell_rightwall_brdf.ktx new file mode 100644 index 0000000000000000000000000000000000000000..369d0f9875bfcdc95d9a1a7d05902c636b615249 --- /dev/null +++ b/assets/extensions/cornell/textures/cornell_rightwall_brdf.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8e881b227e190bfa3db97fb9d65f85641992309ef7ec762a43f6968852e28769 +size 2796312 diff --git a/assets/extensions/cornell/textures/cornell_rightwall_normal.ktx b/assets/extensions/cornell/textures/cornell_rightwall_normal.ktx new file mode 100644 index 0000000000000000000000000000000000000000..b140be1972d6ceb8787864b9e8cda528b82af308 --- /dev/null +++ b/assets/extensions/cornell/textures/cornell_rightwall_normal.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:91527266078d432988ab9a9d63cb2542e3560b8f2c71f39105c7c48eb802a572 +size 2796312 diff --git a/assets/extensions/cornell/textures/cornell_shortbox_albedo.ktx b/assets/extensions/cornell/textures/cornell_shortbox_albedo.ktx new file mode 100644 index 0000000000000000000000000000000000000000..5c4da75e58b931afa4ba2642c51f0d2fe376fec8 --- /dev/null +++ b/assets/extensions/cornell/textures/cornell_shortbox_albedo.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:24f971711f127f6507f4000779f4b1d9a11851ad26dc4af49a10229fbf96efd7 +size 5592512 diff --git a/assets/extensions/cornell/textures/cornell_shortbox_brdf.ktx b/assets/extensions/cornell/textures/cornell_shortbox_brdf.ktx new file mode 100644 index 0000000000000000000000000000000000000000..369d0f9875bfcdc95d9a1a7d05902c636b615249 --- /dev/null +++ b/assets/extensions/cornell/textures/cornell_shortbox_brdf.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8e881b227e190bfa3db97fb9d65f85641992309ef7ec762a43f6968852e28769 +size 2796312 diff --git a/assets/extensions/cornell/textures/cornell_shortbox_normal.ktx b/assets/extensions/cornell/textures/cornell_shortbox_normal.ktx new file mode 100644 index 0000000000000000000000000000000000000000..b140be1972d6ceb8787864b9e8cda528b82af308 --- /dev/null +++ b/assets/extensions/cornell/textures/cornell_shortbox_normal.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:91527266078d432988ab9a9d63cb2542e3560b8f2c71f39105c7c48eb802a572 +size 2796312 diff --git a/assets/extensions/cornell/textures/cornell_sphere_albedo.ktx b/assets/extensions/cornell/textures/cornell_sphere_albedo.ktx new file mode 100644 index 0000000000000000000000000000000000000000..6986b2695e216e828168f0df0ffd1343333377de --- /dev/null +++ b/assets/extensions/cornell/textures/cornell_sphere_albedo.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a40b51716098ae5ef7e2780394c82c421fd9d724fdb8a0863cba1a984cda9777 +size 5592512 diff --git a/assets/extensions/cornell/textures/cornell_sphere_brdf.ktx b/assets/extensions/cornell/textures/cornell_sphere_brdf.ktx new file mode 100644 index 0000000000000000000000000000000000000000..5938d8a9c6852321e376b8b2d37f32df59bab343 --- /dev/null +++ b/assets/extensions/cornell/textures/cornell_sphere_brdf.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:40b38cd42bb613ed6690f07d378e02d35969725ba205795e632ed4fb9dd684e2 +size 2796312 diff --git a/assets/extensions/cornell/textures/cornell_sphere_normal.ktx b/assets/extensions/cornell/textures/cornell_sphere_normal.ktx new file mode 100644 index 0000000000000000000000000000000000000000..b140be1972d6ceb8787864b9e8cda528b82af308 --- /dev/null +++ b/assets/extensions/cornell/textures/cornell_sphere_normal.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:91527266078d432988ab9a9d63cb2542e3560b8f2c71f39105c7c48eb802a572 +size 2796312 diff --git a/assets/extensions/monk/animations/attack.maf b/assets/extensions/monk/animations/attack.maf new file mode 100644 index 0000000000000000000000000000000000000000..d2ab3cabc0c63bb1e1ae8407e8f2f6a878c38853 Binary files /dev/null and b/assets/extensions/monk/animations/attack.maf differ diff --git a/assets/extensions/monk/animations/dance.maf b/assets/extensions/monk/animations/dance.maf new file mode 100644 index 0000000000000000000000000000000000000000..bb74c289e307c838d853810e331b4f9d46e195c2 Binary files /dev/null and b/assets/extensions/monk/animations/dance.maf differ diff --git a/assets/extensions/monk/animations/die.maf b/assets/extensions/monk/animations/die.maf new file mode 100644 index 0000000000000000000000000000000000000000..b3a4ee33d1439b5b9596e4a970c18ac647bb8bc8 Binary files /dev/null and b/assets/extensions/monk/animations/die.maf differ diff --git a/assets/extensions/monk/animations/flee.maf b/assets/extensions/monk/animations/flee.maf new file mode 100644 index 0000000000000000000000000000000000000000..07abac030d6f2270cc228e3f7c309b40eacb12a0 Binary files /dev/null and b/assets/extensions/monk/animations/flee.maf differ diff --git a/assets/extensions/monk/animations/idle.maf b/assets/extensions/monk/animations/idle.maf new file mode 100644 index 0000000000000000000000000000000000000000..7fbc3f912061770702c55e40aa4deade1a2a4553 Binary files /dev/null and b/assets/extensions/monk/animations/idle.maf differ diff --git a/assets/extensions/monk/animations/sad.maf b/assets/extensions/monk/animations/sad.maf new file mode 100644 index 0000000000000000000000000000000000000000..f9d43a2a6300c20c0d13646b35a259ac0ca7635b Binary files /dev/null and b/assets/extensions/monk/animations/sad.maf differ diff --git a/assets/extensions/monk/animations/sleep.maf b/assets/extensions/monk/animations/sleep.maf new file mode 100644 index 0000000000000000000000000000000000000000..ec9e974a5c344fb701dc9bebfd79e1621f54f231 Binary files /dev/null and b/assets/extensions/monk/animations/sleep.maf differ diff --git a/assets/extensions/monk/animations/torturefire.maf b/assets/extensions/monk/animations/torturefire.maf new file mode 100644 index 0000000000000000000000000000000000000000..477f339405ea325e95171757d1cfddc13aff95bb Binary files /dev/null and b/assets/extensions/monk/animations/torturefire.maf differ diff --git a/assets/extensions/monk/animations/walk.maf b/assets/extensions/monk/animations/walk.maf new file mode 100644 index 0000000000000000000000000000000000000000..c2abf9ffa2079c85ee3333934ee3dcb463163c93 Binary files /dev/null and b/assets/extensions/monk/animations/walk.maf differ diff --git a/assets/extensions/monk/assets_monk.map b/assets/extensions/monk/assets_monk.map new file mode 100644 index 0000000000000000000000000000000000000000..286586b2b0038ba85e78e002bbb37c114fa7daa3 --- /dev/null +++ b/assets/extensions/monk/assets_monk.map @@ -0,0 +1,14 @@ +blueprint:monk = blueprints/monk.json +skel:monk = models/monk.mbf + +blueprint:monk_lbs = blueprints/monk_lbs.json +skel:monk_lbs = models/monk_lbs.mbf + +anim:monk_attack = animations/attack.maf +anim:monk_dance = animations/dance.maf +anim:monk_die = animations/die.maf +anim:monk_flee = animations/flee.maf +anim:monk_idle = animations/idle.maf +anim:monk_sad = animations/sad.maf +anim:monk_sleep = animations/sleep.maf +anim:monk_walk = animations/walk.maf diff --git a/assets/extensions/monk/blueprints/monk.json b/assets/extensions/monk/blueprints/monk.json new file mode 100644 index 0000000000000000000000000000000000000000..cdde2ced96e61085385d1af2c7cb08ef67c0953a --- /dev/null +++ b/assets/extensions/monk/blueprints/monk.json @@ -0,0 +1,26 @@ +{ + "Transform":{ + "scale": {"x": 0.018, "y": 0.018, "z": 0.018} + }, + "Model": { + "aid": "model:monk.mmf" + }, + "Pose": {"skeleton": "skel:monk"}, + "Animation": {}, + "Simple_animation_controller": { + "animations": { + "attack": "anim:monk_attack", + "dance": "anim:monk_dance", + "die": "anim:monk_die", + "flee": "anim:monk_flee", + "idle": "anim:monk_idle", + "sad": "anim:monk_sad", + "sleep": "anim:monk_sleep", + "walk": "anim:monk_walk" + }, + "current_animation": { + "id": "dance" + } + }, + "Shadowcaster": {} +} diff --git a/assets/extensions/monk/blueprints/monk_lbs.json b/assets/extensions/monk/blueprints/monk_lbs.json new file mode 100644 index 0000000000000000000000000000000000000000..cf21ae5b9e3d079ed498e423b5ce1835a2cfb212 --- /dev/null +++ b/assets/extensions/monk/blueprints/monk_lbs.json @@ -0,0 +1,26 @@ +{ + "Transform":{ + "scale": {"x": 0.018, "y": 0.018, "z": 0.018} + }, + "Model": { + "aid": "model:monk.mmf" + }, + "Pose": {"skeleton": "skel:monk_lbs"}, + "Animation": {}, + "Simple_animation_controller": { + "animations": { + "attack": "anim:monk_attack", + "dance": "anim:monk_dance", + "die": "anim:monk_die", + "flee": "anim:monk_flee", + "idle": "anim:monk_idle", + "sad": "anim:monk_sad", + "sleep": "anim:monk_sleep", + "walk": "anim:monk_walk" + }, + "current_animation": { + "id": "dance" + } + }, + "Shadowcaster": {} +} diff --git a/assets/extensions/monk/materials/monk_monkbody.msf b/assets/extensions/monk/materials/monk_monkbody.msf new file mode 100644 index 0000000000000000000000000000000000000000..b3be9c26f0107633b11e49e2e733b85c74f10464 --- /dev/null +++ b/assets/extensions/monk/materials/monk_monkbody.msf @@ -0,0 +1,7 @@ +{ + "substance_id": "alphatest", + "albedo_aid": "monk_monkbody_albedo.ktx", + "normal_aid": "monk_monkbody_normal.ktx", + "brdf_aid": "monk_monkbody_brdf.ktx", + "emission_aid": "" +} diff --git a/assets/extensions/monk/materials/monk_monkhair.msf b/assets/extensions/monk/materials/monk_monkhair.msf new file mode 100644 index 0000000000000000000000000000000000000000..5d365167240d3c12ebc5bef1499c290271801b1a --- /dev/null +++ b/assets/extensions/monk/materials/monk_monkhair.msf @@ -0,0 +1,7 @@ +{ + "substance_id": "alphatest", + "albedo_aid": "monk_monkhair_albedo.ktx", + "normal_aid": "monk_monkhair_normal.ktx", + "brdf_aid": "monk_monkhair_brdf.ktx", + "emission_aid": "" +} diff --git a/assets/extensions/monk/materials/monk_monkhead.msf b/assets/extensions/monk/materials/monk_monkhead.msf new file mode 100644 index 0000000000000000000000000000000000000000..a11aa25c9c23b2038336e9b104abbfbb59d55d79 --- /dev/null +++ b/assets/extensions/monk/materials/monk_monkhead.msf @@ -0,0 +1,7 @@ +{ + "substance_id": "default", + "albedo_aid": "monk_monkhead_albedo.ktx", + "normal_aid": "monk_monkhead_normal.ktx", + "brdf_aid": "monk_monkhead_brdf.ktx", + "emission_aid": "" +} diff --git a/assets/extensions/monk/models/monk.mbf b/assets/extensions/monk/models/monk.mbf new file mode 100644 index 0000000000000000000000000000000000000000..900d1c9550634f0ba9efe6ff39bf8deaeff17c88 Binary files /dev/null and b/assets/extensions/monk/models/monk.mbf differ diff --git a/assets/extensions/monk/models/monk.mmf b/assets/extensions/monk/models/monk.mmf new file mode 100644 index 0000000000000000000000000000000000000000..bf6ad780694b9cf4f40acb20a671ef97ea8ccedd --- /dev/null +++ b/assets/extensions/monk/models/monk.mmf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:af3df7070ab6ef7d8635a5cd9c99c112d18856858d37871383c67e5071ac91b3 +size 208763 diff --git a/assets/extensions/monk/models/monk_lbs.mbf b/assets/extensions/monk/models/monk_lbs.mbf new file mode 100644 index 0000000000000000000000000000000000000000..2607f1d2178be114291a6e6438275c0354122895 Binary files /dev/null and b/assets/extensions/monk/models/monk_lbs.mbf differ diff --git a/assets/extensions/monk/textures/monk_monkbody_albedo.ktx b/assets/extensions/monk/textures/monk_monkbody_albedo.ktx new file mode 100644 index 0000000000000000000000000000000000000000..ec7d68b3827982747cca9733c2cb6e8db059b23a --- /dev/null +++ b/assets/extensions/monk/textures/monk_monkbody_albedo.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:16bd81aa40853d09d643502a6943b9417a0c0811d18cc218c53bc78da3f2303e +size 1398196 diff --git a/assets/extensions/monk/textures/monk_monkbody_brdf.ktx b/assets/extensions/monk/textures/monk_monkbody_brdf.ktx new file mode 100644 index 0000000000000000000000000000000000000000..5d3e40c20835afd973caacee0dd65af2f6f8fca7 --- /dev/null +++ b/assets/extensions/monk/textures/monk_monkbody_brdf.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3372ae0de96408d7c29303eb91efb4e16cc9106692dc64d1bc77f06c1ac258cd +size 349616 diff --git a/assets/extensions/monk/textures/monk_monkbody_normal.ktx b/assets/extensions/monk/textures/monk_monkbody_normal.ktx new file mode 100644 index 0000000000000000000000000000000000000000..2b7cfb1324c2be00400957253b32147b963bce35 --- /dev/null +++ b/assets/extensions/monk/textures/monk_monkbody_normal.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0e07ac6f7d35bb36d65d404cd33deae5a978b3696e5ae8c0c44b6da7eab78898 +size 349616 diff --git a/assets/extensions/monk/textures/monk_monkhair_albedo.ktx b/assets/extensions/monk/textures/monk_monkhair_albedo.ktx new file mode 100644 index 0000000000000000000000000000000000000000..d4ca532dd0692f7d8727375630ade8af9b2158c3 --- /dev/null +++ b/assets/extensions/monk/textures/monk_monkhair_albedo.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dee1de2ea58a8eff907234ec330ca76c440706d9e16c2c3d028c54887cab2846 +size 349616 diff --git a/assets/extensions/monk/textures/monk_monkhair_brdf.ktx b/assets/extensions/monk/textures/monk_monkhair_brdf.ktx new file mode 100644 index 0000000000000000000000000000000000000000..166f0497d95b972d9fcba9ab99ff506599136d5c --- /dev/null +++ b/assets/extensions/monk/textures/monk_monkhair_brdf.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6d7a3f89bdf3f17ad5f820e506d3f7022642a0f4bf4e3944eaf4a75de71a3eaa +size 349616 diff --git a/assets/extensions/monk/textures/monk_monkhair_normal.ktx b/assets/extensions/monk/textures/monk_monkhair_normal.ktx new file mode 100644 index 0000000000000000000000000000000000000000..019c632ec5dfeea4ea43a4124fa8b6bd7657c5cb --- /dev/null +++ b/assets/extensions/monk/textures/monk_monkhair_normal.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5fd8297a123bbf6e1317eaa7e1769ec3afd5467d36cac2c6546309df86ead7a7 +size 349616 diff --git a/assets/extensions/monk/textures/monk_monkhead_albedo.ktx b/assets/extensions/monk/textures/monk_monkhead_albedo.ktx new file mode 100644 index 0000000000000000000000000000000000000000..7fd4aca719db5b0b0317e4c32d03a18718b24f77 --- /dev/null +++ b/assets/extensions/monk/textures/monk_monkhead_albedo.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:39ab61334e33af13053dd3cf9a61ba8577d336541e6729e0a95f4079e6d6042b +size 1398196 diff --git a/assets/extensions/monk/textures/monk_monkhead_brdf.ktx b/assets/extensions/monk/textures/monk_monkhead_brdf.ktx new file mode 100644 index 0000000000000000000000000000000000000000..6ffff0d50468df07535657da6e67a79bd1933d82 --- /dev/null +++ b/assets/extensions/monk/textures/monk_monkhead_brdf.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ba3e977e61f605381651b9c8a5ef147ea7c8b3156b8d90dce08575e53db35541 +size 349616 diff --git a/assets/extensions/monk/textures/monk_monkhead_normal.ktx b/assets/extensions/monk/textures/monk_monkhead_normal.ktx new file mode 100644 index 0000000000000000000000000000000000000000..f44ebd69f4342997f49ff5bbdef99df6c994c712 --- /dev/null +++ b/assets/extensions/monk/textures/monk_monkhead_normal.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9a60057dc21507966e8ea89a0263e60179f71517e0ded183be0b5d55eaf22c35 +size 349616 diff --git a/assets/extensions/rotation_test/animations/armaturearmatureaction.maf b/assets/extensions/rotation_test/animations/armaturearmatureaction.maf new file mode 100644 index 0000000000000000000000000000000000000000..28ba675da1575dcba6cead5a232bcea7af9165bc Binary files /dev/null and b/assets/extensions/rotation_test/animations/armaturearmatureaction.maf differ diff --git a/assets/extensions/rotation_test/animations/armaturecylinderaction.maf b/assets/extensions/rotation_test/animations/armaturecylinderaction.maf new file mode 100644 index 0000000000000000000000000000000000000000..1e9fabb6f8cc80ecfda96715283c1bd1b2ce8029 Binary files /dev/null and b/assets/extensions/rotation_test/animations/armaturecylinderaction.maf differ diff --git a/assets/extensions/rotation_test/assets_rotation_test.map b/assets/extensions/rotation_test/assets_rotation_test.map new file mode 100644 index 0000000000000000000000000000000000000000..b122d772fbc9dae90f7259afc7f9864aff04c90f --- /dev/null +++ b/assets/extensions/rotation_test/assets_rotation_test.map @@ -0,0 +1,8 @@ +blueprint:rotation_test = blueprints/rotation_test.json +skel:rotation_test = models/rotation.mbf + +blueprint:rotation_test_lbs = blueprints/rotation_test_lbs.json +skel:rotation_test_lbs = models/rotation_lbs.mbf + +anim:rotation_test = animations/armaturearmatureaction.maf + diff --git a/assets/extensions/rotation_test/blueprints/rotation_test.json b/assets/extensions/rotation_test/blueprints/rotation_test.json new file mode 100644 index 0000000000000000000000000000000000000000..142f9ab0e458aa16e60741f6294338c3a072b3d1 --- /dev/null +++ b/assets/extensions/rotation_test/blueprints/rotation_test.json @@ -0,0 +1,21 @@ +{ + "Transform":{ + "scale": {"x": 0.003, "y": 0.003, "z": 0.003} + }, + "Model": { + "aid": "model:rotation.mmf" + }, + "Pose": {"skeleton": "skel:rotation_test"}, + + "Animation": {}, + "Simple_animation_controller": { + "animations": { + "test": "anim:rotation_test" + }, + "current_animation": { + "id": "test", + "speed": 0.2 + } + }, + "Shadowcaster": {} +} diff --git a/assets/extensions/rotation_test/blueprints/rotation_test_lbs.json b/assets/extensions/rotation_test/blueprints/rotation_test_lbs.json new file mode 100644 index 0000000000000000000000000000000000000000..4e94fde02efc153150bc0bd29d9283f68f39c264 --- /dev/null +++ b/assets/extensions/rotation_test/blueprints/rotation_test_lbs.json @@ -0,0 +1,22 @@ +{ + "Transform":{ + "scale": {"x": 0.003, "y": 0.003, "z": 0.003} + }, + "Model": { + "aid": "model:rotation.mmf" + }, + "Pose": {"skeleton": "skel:rotation_test_lbs"}, + + "Animation": {}, + "Simple_animation_controller": { + "animations": { + "test": "anim:rotation_test" + }, + "current_animation": { + "id": "test", + "speed": 0.2 + } + }, + "Shadowcaster": {}, + "Point_light": {"source_radius":1.0, "intensity":620, "temperature":1900} +} diff --git a/assets/extensions/rotation_test/materials/rotation_material.003.msf b/assets/extensions/rotation_test/materials/rotation_material.003.msf new file mode 100644 index 0000000000000000000000000000000000000000..44940d6e99d3e2b702ecf6066d954f21aa639a11 --- /dev/null +++ b/assets/extensions/rotation_test/materials/rotation_material.003.msf @@ -0,0 +1,7 @@ +{ + "substance_id": "default", + "albedo_aid": "rotation_material.003_albedo.ktx", + "normal_aid": "rotation_material.003_normal.ktx", + "brdf_aid": "rotation_material.003_brdf.ktx", + "emission_aid": "" +} diff --git a/assets/extensions/rotation_test/models/rotation.mbf b/assets/extensions/rotation_test/models/rotation.mbf new file mode 100644 index 0000000000000000000000000000000000000000..48d08d203fd35e497c87e8a862377ed73609381c Binary files /dev/null and b/assets/extensions/rotation_test/models/rotation.mbf differ diff --git a/assets/extensions/rotation_test/models/rotation.mmf b/assets/extensions/rotation_test/models/rotation.mmf new file mode 100644 index 0000000000000000000000000000000000000000..fe1149e6cf74d36b0c879775decd70f02470c82a --- /dev/null +++ b/assets/extensions/rotation_test/models/rotation.mmf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d06711b1985c183d20ad2c7f3e00f0d7db7a17bc91ada0231e640873932256c2 +size 91697 diff --git a/assets/extensions/rotation_test/models/rotation_lbs.mbf b/assets/extensions/rotation_test/models/rotation_lbs.mbf new file mode 100644 index 0000000000000000000000000000000000000000..40cc3aec602c653afe4200483440258dfafdf609 Binary files /dev/null and b/assets/extensions/rotation_test/models/rotation_lbs.mbf differ diff --git a/assets/extensions/rotation_test/textures/rotation_material.003_albedo.ktx b/assets/extensions/rotation_test/textures/rotation_material.003_albedo.ktx new file mode 100644 index 0000000000000000000000000000000000000000..13ddb4f84162f55bb15994800cb69db613875628 --- /dev/null +++ b/assets/extensions/rotation_test/textures/rotation_material.003_albedo.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f2d31719f597eb5452a6f666ca1506de4179d59e19341c22863b532834bd07ab +size 5592512 diff --git a/assets/extensions/rotation_test/textures/rotation_material.003_brdf.ktx b/assets/extensions/rotation_test/textures/rotation_material.003_brdf.ktx new file mode 100644 index 0000000000000000000000000000000000000000..de501cc2436e2683f64e5abf48864979cdb2ee04 --- /dev/null +++ b/assets/extensions/rotation_test/textures/rotation_material.003_brdf.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7d59823be8e3f0eb31d64b310cb1f4fc7d3080b2b5f4805579285eae4d225456 +size 699156 diff --git a/assets/extensions/rotation_test/textures/rotation_material.003_normal.ktx b/assets/extensions/rotation_test/textures/rotation_material.003_normal.ktx new file mode 100644 index 0000000000000000000000000000000000000000..dd141369e9b12f5ce06bdc8a136e06266bd45745 --- /dev/null +++ b/assets/extensions/rotation_test/textures/rotation_material.003_normal.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:470b69a039ffa03ec17c3b20a4e2e65239bb582742f5c7698db0c383d4d41c98 +size 699156 diff --git a/assets/extensions/sponza/materials/sponza_16___default.msf b/assets/extensions/sponza/materials/sponza_16___default.msf new file mode 100644 index 0000000000000000000000000000000000000000..ed2e852f632cb58bba534787e147a686d4621f72 --- /dev/null +++ b/assets/extensions/sponza/materials/sponza_16___default.msf @@ -0,0 +1,7 @@ +{ + "substance_id": "default", + "albedo_aid": "sponza_16___default_albedo.ktx", + "normal_aid": "sponza_16___default_normal.ktx", + "brdf_aid": "sponza_16___default_brdf.ktx", + "emission_aid": "" +} diff --git a/assets/extensions/sponza/materials/sponza_arch.msf b/assets/extensions/sponza/materials/sponza_arch.msf new file mode 100644 index 0000000000000000000000000000000000000000..e646a42ebcc0207ea2a5bc867d112c915c691101 --- /dev/null +++ b/assets/extensions/sponza/materials/sponza_arch.msf @@ -0,0 +1,7 @@ +{ + "substance_id": "default", + "albedo_aid": "sponza_arch_albedo.ktx", + "normal_aid": "sponza_arch_normal.ktx", + "brdf_aid": "sponza_arch_brdf.ktx", + "emission_aid": "" +} diff --git a/assets/extensions/sponza/materials/sponza_bricks.msf b/assets/extensions/sponza/materials/sponza_bricks.msf new file mode 100644 index 0000000000000000000000000000000000000000..d3bbd3b9647c9071617ef679b93e54b9a48b18ef --- /dev/null +++ b/assets/extensions/sponza/materials/sponza_bricks.msf @@ -0,0 +1,7 @@ +{ + "substance_id": "default", + "albedo_aid": "sponza_bricks_albedo.ktx", + "normal_aid": "sponza_bricks_normal.ktx", + "brdf_aid": "sponza_bricks_brdf.ktx", + "emission_aid": "" +} diff --git a/assets/extensions/sponza/materials/sponza_ceiling.msf b/assets/extensions/sponza/materials/sponza_ceiling.msf new file mode 100644 index 0000000000000000000000000000000000000000..addd148c0b1a2a65a8dcf25a669334294e0af5af --- /dev/null +++ b/assets/extensions/sponza/materials/sponza_ceiling.msf @@ -0,0 +1,7 @@ +{ + "substance_id": "default", + "albedo_aid": "sponza_ceiling_albedo.ktx", + "normal_aid": "sponza_ceiling_normal.ktx", + "brdf_aid": "sponza_ceiling_brdf.ktx", + "emission_aid": "" +} diff --git a/assets/extensions/sponza/materials/sponza_chain.msf b/assets/extensions/sponza/materials/sponza_chain.msf new file mode 100644 index 0000000000000000000000000000000000000000..53c7e7e6eef88042d365e0d2757260bd6fe7584b --- /dev/null +++ b/assets/extensions/sponza/materials/sponza_chain.msf @@ -0,0 +1,7 @@ +{ + "substance_id": "alphatest", + "albedo_aid": "sponza_chain_albedo.ktx", + "normal_aid": "sponza_chain_normal.ktx", + "brdf_aid": "sponza_chain_brdf.ktx", + "emission_aid": "" +} diff --git a/assets/extensions/sponza/materials/sponza_column_a.msf b/assets/extensions/sponza/materials/sponza_column_a.msf new file mode 100644 index 0000000000000000000000000000000000000000..cf6e94061ce3cce397611c9816e3873a59bc4526 --- /dev/null +++ b/assets/extensions/sponza/materials/sponza_column_a.msf @@ -0,0 +1,7 @@ +{ + "substance_id": "default", + "albedo_aid": "sponza_column_a_albedo.ktx", + "normal_aid": "sponza_column_a_normal.ktx", + "brdf_aid": "sponza_column_a_brdf.ktx", + "emission_aid": "" +} diff --git a/assets/extensions/sponza/materials/sponza_column_b.msf b/assets/extensions/sponza/materials/sponza_column_b.msf new file mode 100644 index 0000000000000000000000000000000000000000..b1349dfc285af10e0bf5064eb2f8eb8fd51bec4d --- /dev/null +++ b/assets/extensions/sponza/materials/sponza_column_b.msf @@ -0,0 +1,7 @@ +{ + "substance_id": "default", + "albedo_aid": "sponza_column_b_albedo.ktx", + "normal_aid": "sponza_column_b_normal.ktx", + "brdf_aid": "sponza_column_b_brdf.ktx", + "emission_aid": "" +} diff --git a/assets/extensions/sponza/materials/sponza_column_c.msf b/assets/extensions/sponza/materials/sponza_column_c.msf new file mode 100644 index 0000000000000000000000000000000000000000..3d4331daecebb93df3acf72c737f272f40a02c04 --- /dev/null +++ b/assets/extensions/sponza/materials/sponza_column_c.msf @@ -0,0 +1,7 @@ +{ + "substance_id": "default", + "albedo_aid": "sponza_column_c_albedo.ktx", + "normal_aid": "sponza_column_c_normal.ktx", + "brdf_aid": "sponza_column_c_brdf.ktx", + "emission_aid": "" +} diff --git a/assets/extensions/sponza/materials/sponza_details.msf b/assets/extensions/sponza/materials/sponza_details.msf new file mode 100644 index 0000000000000000000000000000000000000000..d9a709e4643f111420edc0990a8df57033ee4951 --- /dev/null +++ b/assets/extensions/sponza/materials/sponza_details.msf @@ -0,0 +1,7 @@ +{ + "substance_id": "default", + "albedo_aid": "sponza_details_albedo.ktx", + "normal_aid": "sponza_details_normal.ktx", + "brdf_aid": "sponza_details_brdf.ktx", + "emission_aid": "" +} diff --git a/assets/extensions/sponza/materials/sponza_fabric_c.msf b/assets/extensions/sponza/materials/sponza_fabric_c.msf new file mode 100644 index 0000000000000000000000000000000000000000..b7da8b3734dad5e4490d6b9aa2caf30e486bbe91 --- /dev/null +++ b/assets/extensions/sponza/materials/sponza_fabric_c.msf @@ -0,0 +1,7 @@ +{ + "substance_id": "default", + "albedo_aid": "sponza_fabric_c_albedo.ktx", + "normal_aid": "sponza_fabric_c_normal.ktx", + "brdf_aid": "sponza_fabric_c_brdf.ktx", + "emission_aid": "" +} diff --git a/assets/extensions/sponza/materials/sponza_fabric_d.msf b/assets/extensions/sponza/materials/sponza_fabric_d.msf new file mode 100644 index 0000000000000000000000000000000000000000..8e5e8420a2ae4053fb3132c82c8b38d82f523c06 --- /dev/null +++ b/assets/extensions/sponza/materials/sponza_fabric_d.msf @@ -0,0 +1,7 @@ +{ + "substance_id": "default", + "albedo_aid": "sponza_fabric_d_albedo.ktx", + "normal_aid": "sponza_fabric_d_normal.ktx", + "brdf_aid": "sponza_fabric_d_brdf.ktx", + "emission_aid": "" +} diff --git a/assets/extensions/sponza/materials/sponza_fabric_e.msf b/assets/extensions/sponza/materials/sponza_fabric_e.msf new file mode 100644 index 0000000000000000000000000000000000000000..423b746af4cc03fe8993dbcd86c9e97841d77ecb --- /dev/null +++ b/assets/extensions/sponza/materials/sponza_fabric_e.msf @@ -0,0 +1,7 @@ +{ + "substance_id": "default", + "albedo_aid": "sponza_fabric_e_albedo.ktx", + "normal_aid": "sponza_fabric_e_normal.ktx", + "brdf_aid": "sponza_fabric_e_brdf.ktx", + "emission_aid": "" +} diff --git a/assets/extensions/sponza/materials/sponza_fabric_f.msf b/assets/extensions/sponza/materials/sponza_fabric_f.msf new file mode 100644 index 0000000000000000000000000000000000000000..2f8ff4dd15d148395c15f95d79e5dad574a55fa1 --- /dev/null +++ b/assets/extensions/sponza/materials/sponza_fabric_f.msf @@ -0,0 +1,7 @@ +{ + "substance_id": "default", + "albedo_aid": "sponza_fabric_f_albedo.ktx", + "normal_aid": "sponza_fabric_f_normal.ktx", + "brdf_aid": "sponza_fabric_f_brdf.ktx", + "emission_aid": "" +} diff --git a/assets/extensions/sponza/materials/sponza_fabric_g.msf b/assets/extensions/sponza/materials/sponza_fabric_g.msf new file mode 100644 index 0000000000000000000000000000000000000000..bff06f0e669e876b1ef2ba871cb528685dc68c40 --- /dev/null +++ b/assets/extensions/sponza/materials/sponza_fabric_g.msf @@ -0,0 +1,7 @@ +{ + "substance_id": "default", + "albedo_aid": "sponza_fabric_g_albedo.ktx", + "normal_aid": "sponza_fabric_g_normal.ktx", + "brdf_aid": "sponza_fabric_g_brdf.ktx", + "emission_aid": "" +} diff --git a/assets/extensions/sponza/materials/sponza_flagpole.msf b/assets/extensions/sponza/materials/sponza_flagpole.msf new file mode 100644 index 0000000000000000000000000000000000000000..6cbbc3d7d5cbd58e91207a803a90c805331fab0b --- /dev/null +++ b/assets/extensions/sponza/materials/sponza_flagpole.msf @@ -0,0 +1,7 @@ +{ + "substance_id": "default", + "albedo_aid": "sponza_flagpole_albedo.ktx", + "normal_aid": "sponza_flagpole_normal.ktx", + "brdf_aid": "sponza_flagpole_brdf.ktx", + "emission_aid": "" +} diff --git a/assets/extensions/sponza/materials/sponza_floor.msf b/assets/extensions/sponza/materials/sponza_floor.msf new file mode 100644 index 0000000000000000000000000000000000000000..9517f48e47df693a932450fe8308ddf4cbd6ffa6 --- /dev/null +++ b/assets/extensions/sponza/materials/sponza_floor.msf @@ -0,0 +1,7 @@ +{ + "substance_id": "default", + "albedo_aid": "sponza_floor_albedo.ktx", + "normal_aid": "sponza_floor_normal.ktx", + "brdf_aid": "sponza_floor_brdf.ktx", + "emission_aid": "" +} diff --git a/assets/extensions/sponza/materials/sponza_leaf.msf b/assets/extensions/sponza/materials/sponza_leaf.msf new file mode 100644 index 0000000000000000000000000000000000000000..1cc177df0f08a3acbc2b91e27f3e5038a77c481b --- /dev/null +++ b/assets/extensions/sponza/materials/sponza_leaf.msf @@ -0,0 +1,7 @@ +{ + "substance_id": "alphatest", + "albedo_aid": "sponza_leaf_albedo.ktx", + "normal_aid": "sponza_leaf_normal.ktx", + "brdf_aid": "sponza_leaf_brdf.ktx", + "emission_aid": "" +} diff --git a/assets/extensions/sponza/materials/sponza_material__25.msf b/assets/extensions/sponza/materials/sponza_material__25.msf new file mode 100644 index 0000000000000000000000000000000000000000..4e97573143c546ae033f664184dc8c5c945df7d2 --- /dev/null +++ b/assets/extensions/sponza/materials/sponza_material__25.msf @@ -0,0 +1,7 @@ +{ + "substance_id": "default", + "albedo_aid": "sponza_material__25_albedo.ktx", + "normal_aid": "sponza_material__25_normal.ktx", + "brdf_aid": "sponza_material__25_brdf.ktx", + "emission_aid": "" +} diff --git a/assets/extensions/sponza/materials/sponza_material__298.msf b/assets/extensions/sponza/materials/sponza_material__298.msf new file mode 100644 index 0000000000000000000000000000000000000000..a0e95c7e75c2049a59798d5cad9d07fe0f9b9436 --- /dev/null +++ b/assets/extensions/sponza/materials/sponza_material__298.msf @@ -0,0 +1,7 @@ +{ + "substance_id": "default", + "albedo_aid": "sponza_material__298_albedo.ktx", + "normal_aid": "sponza_material__298_normal.ktx", + "brdf_aid": "sponza_material__298_brdf.ktx", + "emission_aid": "" +} diff --git a/assets/extensions/sponza/materials/sponza_material__47.msf b/assets/extensions/sponza/materials/sponza_material__47.msf new file mode 100644 index 0000000000000000000000000000000000000000..3b74c1fa72f8f69b91250b45175241ab6c4efa43 --- /dev/null +++ b/assets/extensions/sponza/materials/sponza_material__47.msf @@ -0,0 +1,7 @@ +{ + "substance_id": "default", + "albedo_aid": "sponza_material__47_albedo.ktx", + "normal_aid": "sponza_material__47_normal.ktx", + "brdf_aid": "sponza_material__47_brdf.ktx", + "emission_aid": "" +} diff --git a/assets/extensions/sponza/materials/sponza_material__57.msf b/assets/extensions/sponza/materials/sponza_material__57.msf new file mode 100644 index 0000000000000000000000000000000000000000..f19277b094fe92e7beaaca6dff22f5d1ebb8cedc --- /dev/null +++ b/assets/extensions/sponza/materials/sponza_material__57.msf @@ -0,0 +1,7 @@ +{ + "substance_id": "alphatest", + "albedo_aid": "sponza_material__57_albedo.ktx", + "normal_aid": "sponza_material__57_normal.ktx", + "brdf_aid": "sponza_material__57_brdf.ktx", + "emission_aid": "" +} diff --git a/assets/extensions/sponza/materials/sponza_roof.msf b/assets/extensions/sponza/materials/sponza_roof.msf new file mode 100644 index 0000000000000000000000000000000000000000..6258f02196b185fde3237b58cf3a101025ffc1bd --- /dev/null +++ b/assets/extensions/sponza/materials/sponza_roof.msf @@ -0,0 +1,7 @@ +{ + "substance_id": "default", + "albedo_aid": "sponza_roof_albedo.ktx", + "normal_aid": "sponza_roof_normal.ktx", + "brdf_aid": "sponza_roof_brdf.ktx", + "emission_aid": "" +} diff --git a/assets/extensions/sponza/materials/sponza_vase.msf b/assets/extensions/sponza/materials/sponza_vase.msf new file mode 100644 index 0000000000000000000000000000000000000000..c44e56499c6d753ab7848f254ab1f0518cac1980 --- /dev/null +++ b/assets/extensions/sponza/materials/sponza_vase.msf @@ -0,0 +1,7 @@ +{ + "substance_id": "default", + "albedo_aid": "sponza_vase_albedo.ktx", + "normal_aid": "sponza_vase_normal.ktx", + "brdf_aid": "sponza_vase_brdf.ktx", + "emission_aid": "" +} diff --git a/assets/extensions/sponza/materials/sponza_vase_hanging.msf b/assets/extensions/sponza/materials/sponza_vase_hanging.msf new file mode 100644 index 0000000000000000000000000000000000000000..f56fb68dbf05ae9c61af95c00573c36624ad53fd --- /dev/null +++ b/assets/extensions/sponza/materials/sponza_vase_hanging.msf @@ -0,0 +1,7 @@ +{ + "substance_id": "default", + "albedo_aid": "sponza_vase_hanging_albedo.ktx", + "normal_aid": "sponza_vase_hanging_normal.ktx", + "brdf_aid": "sponza_vase_hanging_brdf.ktx", + "emission_aid": "" +} diff --git a/assets/extensions/sponza/materials/sponza_vase_round.msf b/assets/extensions/sponza/materials/sponza_vase_round.msf new file mode 100644 index 0000000000000000000000000000000000000000..80e507b44e1782ca6a82d64880c664fb3bd25731 --- /dev/null +++ b/assets/extensions/sponza/materials/sponza_vase_round.msf @@ -0,0 +1,7 @@ +{ + "substance_id": "default", + "albedo_aid": "sponza_vase_round_albedo.ktx", + "normal_aid": "sponza_vase_round_normal.ktx", + "brdf_aid": "sponza_vase_round_brdf.ktx", + "emission_aid": "" +} diff --git a/assets/extensions/sponza/models/sponza.mmf b/assets/extensions/sponza/models/sponza.mmf new file mode 100644 index 0000000000000000000000000000000000000000..9899a415f8645362efd3b451dbdc70455370b160 --- /dev/null +++ b/assets/extensions/sponza/models/sponza.mmf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5c87d9119872f529b454416ffb95cc0474f55eebdf5bdc21106947a1170c4c75 +size 9539076 diff --git a/assets/extensions/sponza/textures/sponza_16___default_albedo.ktx b/assets/extensions/sponza/textures/sponza_16___default_albedo.ktx new file mode 100644 index 0000000000000000000000000000000000000000..a37d47e4b44cdc3bb64acd31a93e1d7ddde98431 --- /dev/null +++ b/assets/extensions/sponza/textures/sponza_16___default_albedo.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fb9420efd5e0a18b09dfb5762e849e6ab8ab28c85f54e528f0ab1f3aa67c7946 +size 1398196 diff --git a/assets/extensions/sponza/textures/sponza_16___default_brdf.ktx b/assets/extensions/sponza/textures/sponza_16___default_brdf.ktx new file mode 100644 index 0000000000000000000000000000000000000000..947a378ed83ad2cb96168515344985ffa746cfff --- /dev/null +++ b/assets/extensions/sponza/textures/sponza_16___default_brdf.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1bbd6227ad160aa52de52130ed5373e1db756e0a7753999f04f12d69846ee703 +size 1398196 diff --git a/assets/extensions/sponza/textures/sponza_16___default_normal.ktx b/assets/extensions/sponza/textures/sponza_16___default_normal.ktx new file mode 100644 index 0000000000000000000000000000000000000000..edaccff1722d2d7f7aeb08b841b82b1f994fcd78 --- /dev/null +++ b/assets/extensions/sponza/textures/sponza_16___default_normal.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2edc6fbef2cee30f862c59c2f57955595fc617e327ee5115a3a19f1768f2ac8e +size 1398196 diff --git a/assets/extensions/sponza/textures/sponza_arch_albedo.ktx b/assets/extensions/sponza/textures/sponza_arch_albedo.ktx new file mode 100644 index 0000000000000000000000000000000000000000..4690eb7e7c75fe36228cec814db21158dda59a90 --- /dev/null +++ b/assets/extensions/sponza/textures/sponza_arch_albedo.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:85aae7ac331b404fc7c6293cb65d84986b3ca16a5a882ca60a62d891860fff8a +size 1398196 diff --git a/assets/extensions/sponza/textures/sponza_arch_brdf.ktx b/assets/extensions/sponza/textures/sponza_arch_brdf.ktx new file mode 100644 index 0000000000000000000000000000000000000000..7b8b565a57b9531d545c140bcdca84e64e230ffc --- /dev/null +++ b/assets/extensions/sponza/textures/sponza_arch_brdf.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:82f3ba291fda67f48edbccdd67777a0c183575b7b60e845dd3323dcbd4797dfe +size 1398196 diff --git a/assets/extensions/sponza/textures/sponza_arch_normal.ktx b/assets/extensions/sponza/textures/sponza_arch_normal.ktx new file mode 100644 index 0000000000000000000000000000000000000000..4a5a0631f0db2ade80d5c02092490785f9ac456d --- /dev/null +++ b/assets/extensions/sponza/textures/sponza_arch_normal.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bef3a6773d2983785384d699d06f8e99eb130c4e70ea17382855339b4c6b782b +size 1398196 diff --git a/assets/extensions/sponza/textures/sponza_bricks_albedo.ktx b/assets/extensions/sponza/textures/sponza_bricks_albedo.ktx new file mode 100644 index 0000000000000000000000000000000000000000..84ca6b921fcae39ac50f372a41827d472d860ed9 --- /dev/null +++ b/assets/extensions/sponza/textures/sponza_bricks_albedo.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6fb8e16c12ae05e1e58f32d59dc81916004b4c53fd45fec0b07a01489d245756 +size 1398196 diff --git a/assets/extensions/sponza/textures/sponza_bricks_brdf.ktx b/assets/extensions/sponza/textures/sponza_bricks_brdf.ktx new file mode 100644 index 0000000000000000000000000000000000000000..5c02de0440c9c5ab9a95408cb336a1bfeca3bd66 --- /dev/null +++ b/assets/extensions/sponza/textures/sponza_bricks_brdf.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6b8d1dc0b027c63d3381d5c90321f215072662201688b71eaa56aacb3cc670a3 +size 1398196 diff --git a/assets/extensions/sponza/textures/sponza_bricks_normal.ktx b/assets/extensions/sponza/textures/sponza_bricks_normal.ktx new file mode 100644 index 0000000000000000000000000000000000000000..09f85527f083f9bc98643e81aed2a261c84c1318 --- /dev/null +++ b/assets/extensions/sponza/textures/sponza_bricks_normal.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:874361242e4d2a0ca6cb89996bdbe129606ccbb36306055b448ca3b66af22b37 +size 1398196 diff --git a/assets/extensions/sponza/textures/sponza_ceiling_albedo.ktx b/assets/extensions/sponza/textures/sponza_ceiling_albedo.ktx new file mode 100644 index 0000000000000000000000000000000000000000..efcfcb4beb623dd6a8741462e24d620e1113d8fb --- /dev/null +++ b/assets/extensions/sponza/textures/sponza_ceiling_albedo.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4ce717672711222c7a4b0f5130b0bf27b8622ea61f01ede8c99dd35dab09abd6 +size 1398196 diff --git a/assets/extensions/sponza/textures/sponza_ceiling_brdf.ktx b/assets/extensions/sponza/textures/sponza_ceiling_brdf.ktx new file mode 100644 index 0000000000000000000000000000000000000000..a56a3f3e0442c72c626d13d0dbba7efeaac9822c --- /dev/null +++ b/assets/extensions/sponza/textures/sponza_ceiling_brdf.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6553ff559f2304775b1c2cccab9972aa22637676370caaf89adf5be9e4dbfbe8 +size 1398196 diff --git a/assets/extensions/sponza/textures/sponza_ceiling_normal.ktx b/assets/extensions/sponza/textures/sponza_ceiling_normal.ktx new file mode 100644 index 0000000000000000000000000000000000000000..8183a48139a1572a7f44cfb026a50b24e5c6cdb2 --- /dev/null +++ b/assets/extensions/sponza/textures/sponza_ceiling_normal.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1cf54ee821c42f9dd6f48977d1f16a4782b0b3f01dd754507b99e9f082e05e0c +size 1398196 diff --git a/assets/extensions/sponza/textures/sponza_chain_albedo.ktx b/assets/extensions/sponza/textures/sponza_chain_albedo.ktx new file mode 100644 index 0000000000000000000000000000000000000000..548d6a867a14e4b3c1b7cfb1f0adbab05f6682db --- /dev/null +++ b/assets/extensions/sponza/textures/sponza_chain_albedo.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5aa8a655902063ed1c8b52b7765d9cc3165d88ded08693b6840241e7477b0eff +size 1398196 diff --git a/assets/extensions/sponza/textures/sponza_chain_brdf.ktx b/assets/extensions/sponza/textures/sponza_chain_brdf.ktx new file mode 100644 index 0000000000000000000000000000000000000000..2ba7b48dc5b3122fe12f33892e42145a66dda326 --- /dev/null +++ b/assets/extensions/sponza/textures/sponza_chain_brdf.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:272bf43c27dfecdfb0284608c49757dc4e3d87f2cb994504fa606735feb738c6 +size 1398196 diff --git a/assets/extensions/sponza/textures/sponza_chain_normal.ktx b/assets/extensions/sponza/textures/sponza_chain_normal.ktx new file mode 100644 index 0000000000000000000000000000000000000000..4250e1d63dcfdf170a00c6bb3babf4cb0682c129 --- /dev/null +++ b/assets/extensions/sponza/textures/sponza_chain_normal.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:08cc92c73dce36ed2466edbca88da6c18aa0337382155fe52c821bf1952253d6 +size 1398196 diff --git a/assets/extensions/sponza/textures/sponza_column_a_albedo.ktx b/assets/extensions/sponza/textures/sponza_column_a_albedo.ktx new file mode 100644 index 0000000000000000000000000000000000000000..da54c49a579c43b7694c81f68af48284e1c2bd96 --- /dev/null +++ b/assets/extensions/sponza/textures/sponza_column_a_albedo.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c372220ce7707defd5eff652d216bfc23be7ef7c68b35a8912d6df3c23da5528 +size 1398196 diff --git a/assets/extensions/sponza/textures/sponza_column_a_brdf.ktx b/assets/extensions/sponza/textures/sponza_column_a_brdf.ktx new file mode 100644 index 0000000000000000000000000000000000000000..6241359107ab3c1f33fccda24606e2396840f200 --- /dev/null +++ b/assets/extensions/sponza/textures/sponza_column_a_brdf.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f382ced121b215716de65f521be6ec4e3483fc40d32af2da073eb71fa566789a +size 1398196 diff --git a/assets/extensions/sponza/textures/sponza_column_a_normal.ktx b/assets/extensions/sponza/textures/sponza_column_a_normal.ktx new file mode 100644 index 0000000000000000000000000000000000000000..efe1ee159b503cd4f2892d694e7bae1dfac3dbd5 --- /dev/null +++ b/assets/extensions/sponza/textures/sponza_column_a_normal.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f157ef0b60b832fd8ee4608a22687df7a32a3072f917ec7aaf7609d21a2a8461 +size 1398196 diff --git a/assets/extensions/sponza/textures/sponza_column_b_albedo.ktx b/assets/extensions/sponza/textures/sponza_column_b_albedo.ktx new file mode 100644 index 0000000000000000000000000000000000000000..db2af2d63fd2dd2e9fed428e94a89f75eb3f8bb2 --- /dev/null +++ b/assets/extensions/sponza/textures/sponza_column_b_albedo.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:131d968a2bf96ca0c43ec0c300f54bf6be801f43f394900d43d1f80183c632a7 +size 1398196 diff --git a/assets/extensions/sponza/textures/sponza_column_b_brdf.ktx b/assets/extensions/sponza/textures/sponza_column_b_brdf.ktx new file mode 100644 index 0000000000000000000000000000000000000000..091c4f4ccf24f2d5478b56b342ec7d555e9a0856 --- /dev/null +++ b/assets/extensions/sponza/textures/sponza_column_b_brdf.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:75ff1d51c9f1d7a9fd930a55f8efae78a95a40d0fda2f6ad3e186de2b9ef919e +size 1398196 diff --git a/assets/extensions/sponza/textures/sponza_column_b_normal.ktx b/assets/extensions/sponza/textures/sponza_column_b_normal.ktx new file mode 100644 index 0000000000000000000000000000000000000000..412d8d814e4da520b4a403bf01c25a22af22f951 --- /dev/null +++ b/assets/extensions/sponza/textures/sponza_column_b_normal.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4ba7cb912331bfc76c91be2099fb5ae9fa3b23c862aa5511c1a4f82fbcf681f8 +size 1398196 diff --git a/assets/extensions/sponza/textures/sponza_column_c_albedo.ktx b/assets/extensions/sponza/textures/sponza_column_c_albedo.ktx new file mode 100644 index 0000000000000000000000000000000000000000..0f4242282ea8ffd6e7e7f6db3487660b1821208c --- /dev/null +++ b/assets/extensions/sponza/textures/sponza_column_c_albedo.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4ad1e50ec408ef6f71e8c77dc750d4a5a7f9b55fbf14c71c885f9989d23ef599 +size 1398196 diff --git a/assets/extensions/sponza/textures/sponza_column_c_brdf.ktx b/assets/extensions/sponza/textures/sponza_column_c_brdf.ktx new file mode 100644 index 0000000000000000000000000000000000000000..4bd2c80480c3561e285f05327741c7f4344983bc --- /dev/null +++ b/assets/extensions/sponza/textures/sponza_column_c_brdf.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:560919384791bb622982d1b6f0c6e881d9d5962d3f4dcd8801d5cc451c1cb72b +size 1398196 diff --git a/assets/extensions/sponza/textures/sponza_column_c_normal.ktx b/assets/extensions/sponza/textures/sponza_column_c_normal.ktx new file mode 100644 index 0000000000000000000000000000000000000000..c95329e6aafa2971d79943662ce701a629f252bf --- /dev/null +++ b/assets/extensions/sponza/textures/sponza_column_c_normal.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c319e89fde4c7e200041e982cd2f5164a2f9467b15d8953e4e7e2cc8d1bfa3f9 +size 1398196 diff --git a/assets/extensions/sponza/textures/sponza_details_albedo.ktx b/assets/extensions/sponza/textures/sponza_details_albedo.ktx new file mode 100644 index 0000000000000000000000000000000000000000..be545bbfb8978a7419355fad68285cc3858a410b --- /dev/null +++ b/assets/extensions/sponza/textures/sponza_details_albedo.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ce61e4039477154bf6a1c2199fe42eeb6ed87821182226bf4cec9e83f550ca2a +size 1398196 diff --git a/assets/extensions/sponza/textures/sponza_details_brdf.ktx b/assets/extensions/sponza/textures/sponza_details_brdf.ktx new file mode 100644 index 0000000000000000000000000000000000000000..72b6ec889c657b45247829edbf2806bc59dd5af0 --- /dev/null +++ b/assets/extensions/sponza/textures/sponza_details_brdf.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a9071e744605dfd04c12732730abb41cc160f8ba9a1dea7dd6b8dd2a9359e52f +size 1398196 diff --git a/assets/extensions/sponza/textures/sponza_details_normal.ktx b/assets/extensions/sponza/textures/sponza_details_normal.ktx new file mode 100644 index 0000000000000000000000000000000000000000..a24574ec93d29d048b8f27380d2e33209701a6e6 --- /dev/null +++ b/assets/extensions/sponza/textures/sponza_details_normal.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ce87b7b4118879b6fb6e056fda069978b17d64d62971935e8cf9fbc9f0c46292 +size 1398196 diff --git a/assets/extensions/sponza/textures/sponza_fabric_c_albedo.ktx b/assets/extensions/sponza/textures/sponza_fabric_c_albedo.ktx new file mode 100644 index 0000000000000000000000000000000000000000..5c91cab828e01aa356898b17475a486f2f91c74e --- /dev/null +++ b/assets/extensions/sponza/textures/sponza_fabric_c_albedo.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9f93996446257cdf5db43bd9e99445221a64ba65cdd308e999241a83c117909e +size 1398196 diff --git a/assets/extensions/sponza/textures/sponza_fabric_c_brdf.ktx b/assets/extensions/sponza/textures/sponza_fabric_c_brdf.ktx new file mode 100644 index 0000000000000000000000000000000000000000..41c18ce73ce85016b02cb48046df4cc9776f3527 --- /dev/null +++ b/assets/extensions/sponza/textures/sponza_fabric_c_brdf.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:55d81c3007a8577234aac95fb947ce6a509b40fc0988262af74f1536700dcf80 +size 1398196 diff --git a/assets/extensions/sponza/textures/sponza_fabric_c_normal.ktx b/assets/extensions/sponza/textures/sponza_fabric_c_normal.ktx new file mode 100644 index 0000000000000000000000000000000000000000..5be2878749f0e4ab9c5fc0db79f6f5d5afcaca6a --- /dev/null +++ b/assets/extensions/sponza/textures/sponza_fabric_c_normal.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:74cb3cb214e283e1051532d3b5a2c94f4506dd229314e61abac76655fc59264c +size 1398196 diff --git a/assets/extensions/sponza/textures/sponza_fabric_d_albedo.ktx b/assets/extensions/sponza/textures/sponza_fabric_d_albedo.ktx new file mode 100644 index 0000000000000000000000000000000000000000..5cc38126155df5d9a988239d3dfb3f3462153f24 --- /dev/null +++ b/assets/extensions/sponza/textures/sponza_fabric_d_albedo.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:525e69ec0e93fc075456cb67b963d97101cbf428604ae5d45bb01c2522220490 +size 1398196 diff --git a/assets/extensions/sponza/textures/sponza_fabric_d_brdf.ktx b/assets/extensions/sponza/textures/sponza_fabric_d_brdf.ktx new file mode 100644 index 0000000000000000000000000000000000000000..947a378ed83ad2cb96168515344985ffa746cfff --- /dev/null +++ b/assets/extensions/sponza/textures/sponza_fabric_d_brdf.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1bbd6227ad160aa52de52130ed5373e1db756e0a7753999f04f12d69846ee703 +size 1398196 diff --git a/assets/extensions/sponza/textures/sponza_fabric_d_normal.ktx b/assets/extensions/sponza/textures/sponza_fabric_d_normal.ktx new file mode 100644 index 0000000000000000000000000000000000000000..edaccff1722d2d7f7aeb08b841b82b1f994fcd78 --- /dev/null +++ b/assets/extensions/sponza/textures/sponza_fabric_d_normal.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2edc6fbef2cee30f862c59c2f57955595fc617e327ee5115a3a19f1768f2ac8e +size 1398196 diff --git a/assets/extensions/sponza/textures/sponza_fabric_e_albedo.ktx b/assets/extensions/sponza/textures/sponza_fabric_e_albedo.ktx new file mode 100644 index 0000000000000000000000000000000000000000..3f1b38ec6997bb80f1c094286c399c0e61b42e95 --- /dev/null +++ b/assets/extensions/sponza/textures/sponza_fabric_e_albedo.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c6152050ed59a026225a7059d960749585dbfefdacacf062b379c90b27310e04 +size 1398196 diff --git a/assets/extensions/sponza/textures/sponza_fabric_e_brdf.ktx b/assets/extensions/sponza/textures/sponza_fabric_e_brdf.ktx new file mode 100644 index 0000000000000000000000000000000000000000..947a378ed83ad2cb96168515344985ffa746cfff --- /dev/null +++ b/assets/extensions/sponza/textures/sponza_fabric_e_brdf.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1bbd6227ad160aa52de52130ed5373e1db756e0a7753999f04f12d69846ee703 +size 1398196 diff --git a/assets/extensions/sponza/textures/sponza_fabric_e_normal.ktx b/assets/extensions/sponza/textures/sponza_fabric_e_normal.ktx new file mode 100644 index 0000000000000000000000000000000000000000..edaccff1722d2d7f7aeb08b841b82b1f994fcd78 --- /dev/null +++ b/assets/extensions/sponza/textures/sponza_fabric_e_normal.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2edc6fbef2cee30f862c59c2f57955595fc617e327ee5115a3a19f1768f2ac8e +size 1398196 diff --git a/assets/extensions/sponza/textures/sponza_fabric_f_albedo.ktx b/assets/extensions/sponza/textures/sponza_fabric_f_albedo.ktx new file mode 100644 index 0000000000000000000000000000000000000000..1df7b0ac290b5e345948c722d913852343c60780 --- /dev/null +++ b/assets/extensions/sponza/textures/sponza_fabric_f_albedo.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fd3b438dc8eacf1785fd545af42203559f31082525cbcaaa0fbe1534fb9cf1df +size 1398196 diff --git a/assets/extensions/sponza/textures/sponza_fabric_f_brdf.ktx b/assets/extensions/sponza/textures/sponza_fabric_f_brdf.ktx new file mode 100644 index 0000000000000000000000000000000000000000..41c18ce73ce85016b02cb48046df4cc9776f3527 --- /dev/null +++ b/assets/extensions/sponza/textures/sponza_fabric_f_brdf.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:55d81c3007a8577234aac95fb947ce6a509b40fc0988262af74f1536700dcf80 +size 1398196 diff --git a/assets/extensions/sponza/textures/sponza_fabric_f_normal.ktx b/assets/extensions/sponza/textures/sponza_fabric_f_normal.ktx new file mode 100644 index 0000000000000000000000000000000000000000..5be2878749f0e4ab9c5fc0db79f6f5d5afcaca6a --- /dev/null +++ b/assets/extensions/sponza/textures/sponza_fabric_f_normal.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:74cb3cb214e283e1051532d3b5a2c94f4506dd229314e61abac76655fc59264c +size 1398196 diff --git a/assets/extensions/sponza/textures/sponza_fabric_g_albedo.ktx b/assets/extensions/sponza/textures/sponza_fabric_g_albedo.ktx new file mode 100644 index 0000000000000000000000000000000000000000..25fb82b01d62b1f9b972f792862e23e58b229ccd --- /dev/null +++ b/assets/extensions/sponza/textures/sponza_fabric_g_albedo.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:78a365286b628eee852aba91913bc3a836c2d1ee7fab55f91665c76f41eebcfd +size 1398196 diff --git a/assets/extensions/sponza/textures/sponza_fabric_g_brdf.ktx b/assets/extensions/sponza/textures/sponza_fabric_g_brdf.ktx new file mode 100644 index 0000000000000000000000000000000000000000..41c18ce73ce85016b02cb48046df4cc9776f3527 --- /dev/null +++ b/assets/extensions/sponza/textures/sponza_fabric_g_brdf.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:55d81c3007a8577234aac95fb947ce6a509b40fc0988262af74f1536700dcf80 +size 1398196 diff --git a/assets/extensions/sponza/textures/sponza_fabric_g_normal.ktx b/assets/extensions/sponza/textures/sponza_fabric_g_normal.ktx new file mode 100644 index 0000000000000000000000000000000000000000..5be2878749f0e4ab9c5fc0db79f6f5d5afcaca6a --- /dev/null +++ b/assets/extensions/sponza/textures/sponza_fabric_g_normal.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:74cb3cb214e283e1051532d3b5a2c94f4506dd229314e61abac76655fc59264c +size 1398196 diff --git a/assets/extensions/sponza/textures/sponza_flagpole_albedo.ktx b/assets/extensions/sponza/textures/sponza_flagpole_albedo.ktx new file mode 100644 index 0000000000000000000000000000000000000000..4ac25f41eb2d907a75a6e50f687fa917fca053a9 --- /dev/null +++ b/assets/extensions/sponza/textures/sponza_flagpole_albedo.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:655174aa4961a1a20dfb54f603f83453d77f00dc3d50b33655b120345f1184d4 +size 1398196 diff --git a/assets/extensions/sponza/textures/sponza_flagpole_brdf.ktx b/assets/extensions/sponza/textures/sponza_flagpole_brdf.ktx new file mode 100644 index 0000000000000000000000000000000000000000..e62cbbc3ba03ff40eb936ce1041a7b2b65a5c041 --- /dev/null +++ b/assets/extensions/sponza/textures/sponza_flagpole_brdf.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:db1e64c061ed1378ef2df0cb69dc0c8da1a6c644e552cded8e9415f7ee0bfb06 +size 1398196 diff --git a/assets/extensions/sponza/textures/sponza_flagpole_normal.ktx b/assets/extensions/sponza/textures/sponza_flagpole_normal.ktx new file mode 100644 index 0000000000000000000000000000000000000000..6ac2cf1891922d88bd016b8f1f140c70d6ad39a3 --- /dev/null +++ b/assets/extensions/sponza/textures/sponza_flagpole_normal.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7a15bbc9cbf0b7e51039eb8643dd1717ea6cb3bc1bf316ec5d25bec66ff5779b +size 1398196 diff --git a/assets/extensions/sponza/textures/sponza_floor_albedo.ktx b/assets/extensions/sponza/textures/sponza_floor_albedo.ktx new file mode 100644 index 0000000000000000000000000000000000000000..241726940318101edc69c5b7d1a6c81f54f8071d --- /dev/null +++ b/assets/extensions/sponza/textures/sponza_floor_albedo.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4260ebda6cf61556ef8c8793398da312c89f45dc235a95f8bfbbef94f9125e9c +size 5592504 diff --git a/assets/extensions/sponza/textures/sponza_floor_brdf.ktx b/assets/extensions/sponza/textures/sponza_floor_brdf.ktx new file mode 100644 index 0000000000000000000000000000000000000000..074a5928e405d7728a6c788b6227b4d48563e470 --- /dev/null +++ b/assets/extensions/sponza/textures/sponza_floor_brdf.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:44ef13238c11dd18e1d969dbf0a2dbc4a1e85068f28846ee640e386635adf500 +size 5592504 diff --git a/assets/extensions/sponza/textures/sponza_floor_normal.ktx b/assets/extensions/sponza/textures/sponza_floor_normal.ktx new file mode 100644 index 0000000000000000000000000000000000000000..6712da91a3f29c67b58955f70fdad29654514fd8 --- /dev/null +++ b/assets/extensions/sponza/textures/sponza_floor_normal.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8b685f702654e0a312f7f666beade3277b5eeb5f6a3c41036c7701927d8e032e +size 5592504 diff --git a/assets/extensions/sponza/textures/sponza_leaf_albedo.ktx b/assets/extensions/sponza/textures/sponza_leaf_albedo.ktx new file mode 100644 index 0000000000000000000000000000000000000000..85de3b94c5eb719f032f93957188bd8709c431be --- /dev/null +++ b/assets/extensions/sponza/textures/sponza_leaf_albedo.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:282d799d74c1c568e95ff1b4fcbb2968b15503a1b68bcdfd8b8a8f6e81f05756 +size 1398196 diff --git a/assets/extensions/sponza/textures/sponza_leaf_brdf.ktx b/assets/extensions/sponza/textures/sponza_leaf_brdf.ktx new file mode 100644 index 0000000000000000000000000000000000000000..0ce772af7c34083c065b0120317487ea02091826 --- /dev/null +++ b/assets/extensions/sponza/textures/sponza_leaf_brdf.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:999c84e5ad0f2dd923e1662b53725c2be8815aeed74ce6f104baa546fce3dd42 +size 1398196 diff --git a/assets/extensions/sponza/textures/sponza_leaf_normal.ktx b/assets/extensions/sponza/textures/sponza_leaf_normal.ktx new file mode 100644 index 0000000000000000000000000000000000000000..c74abcb51d38e29ff11ac95f04e138ddca9db4cb --- /dev/null +++ b/assets/extensions/sponza/textures/sponza_leaf_normal.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:534b0f658d65db5eb390ddb8eb5e9ba2bb52bb32b1c0c8c2a08898845b36f9fb +size 1398196 diff --git a/assets/extensions/sponza/textures/sponza_material__25_albedo.ktx b/assets/extensions/sponza/textures/sponza_material__25_albedo.ktx new file mode 100644 index 0000000000000000000000000000000000000000..9640d5fe9731384d5a9170ff1f408a75969a2161 --- /dev/null +++ b/assets/extensions/sponza/textures/sponza_material__25_albedo.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f0482e168fb3f902ba99f0200ee76a593e07369b5d06fa920abd5310c4943e2c +size 1398196 diff --git a/assets/extensions/sponza/textures/sponza_material__25_brdf.ktx b/assets/extensions/sponza/textures/sponza_material__25_brdf.ktx new file mode 100644 index 0000000000000000000000000000000000000000..09b7d4e89ad5b28ebdc891cee3bc9da3878f571f --- /dev/null +++ b/assets/extensions/sponza/textures/sponza_material__25_brdf.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2f1fabe9a48eee5c0c71437a6edad053622af15345c436fce8281244d4a5c3f8 +size 1398196 diff --git a/assets/extensions/sponza/textures/sponza_material__25_normal.ktx b/assets/extensions/sponza/textures/sponza_material__25_normal.ktx new file mode 100644 index 0000000000000000000000000000000000000000..30af18f5a244cbccadacbb0db0a940d800e616b6 --- /dev/null +++ b/assets/extensions/sponza/textures/sponza_material__25_normal.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:83872e72c9fc53534b7782ef94e0fa9c67d057415207b200f0b622a7a60ccfdd +size 1398196 diff --git a/assets/extensions/sponza/textures/sponza_material__298_albedo.ktx b/assets/extensions/sponza/textures/sponza_material__298_albedo.ktx new file mode 100644 index 0000000000000000000000000000000000000000..92d0463b93aa0e254ab53748611801fe627d74b2 --- /dev/null +++ b/assets/extensions/sponza/textures/sponza_material__298_albedo.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:300c99cc290f7e2f74b9bafd88da2665190399386e85225e854c561035e02670 +size 1398196 diff --git a/assets/extensions/sponza/textures/sponza_material__298_brdf.ktx b/assets/extensions/sponza/textures/sponza_material__298_brdf.ktx new file mode 100644 index 0000000000000000000000000000000000000000..09b7d4e89ad5b28ebdc891cee3bc9da3878f571f --- /dev/null +++ b/assets/extensions/sponza/textures/sponza_material__298_brdf.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2f1fabe9a48eee5c0c71437a6edad053622af15345c436fce8281244d4a5c3f8 +size 1398196 diff --git a/assets/extensions/sponza/textures/sponza_material__298_normal.ktx b/assets/extensions/sponza/textures/sponza_material__298_normal.ktx new file mode 100644 index 0000000000000000000000000000000000000000..c20abeb9fd2b5193f5361bd2f176724356e23f8b --- /dev/null +++ b/assets/extensions/sponza/textures/sponza_material__298_normal.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e39560b6438f4475a6ae290f33fbb6cc459cfd9f7669ae926c6a86fa92f9d84e +size 1398196 diff --git a/assets/extensions/sponza/textures/sponza_material__47_albedo.ktx b/assets/extensions/sponza/textures/sponza_material__47_albedo.ktx new file mode 100644 index 0000000000000000000000000000000000000000..71e86bb633d45fdf3b4de4df0df551127aeff4b4 --- /dev/null +++ b/assets/extensions/sponza/textures/sponza_material__47_albedo.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:258295ec7dfec951defcf1a1e39a96f1fae87fafcb40002486c35b892ffae8a6 +size 1440 diff --git a/assets/extensions/sponza/textures/sponza_material__47_brdf.ktx b/assets/extensions/sponza/textures/sponza_material__47_brdf.ktx new file mode 100644 index 0000000000000000000000000000000000000000..ef1d9446fe45adf6796bed796c9c7ffe4dbe2cdb --- /dev/null +++ b/assets/extensions/sponza/textures/sponza_material__47_brdf.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6ee4817d7ba8c78aea221901ace7db587bc61eb9634e3061472e304bf1963557 +size 349616 diff --git a/assets/extensions/sponza/textures/sponza_material__47_normal.ktx b/assets/extensions/sponza/textures/sponza_material__47_normal.ktx new file mode 100644 index 0000000000000000000000000000000000000000..019c632ec5dfeea4ea43a4124fa8b6bd7657c5cb --- /dev/null +++ b/assets/extensions/sponza/textures/sponza_material__47_normal.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5fd8297a123bbf6e1317eaa7e1769ec3afd5467d36cac2c6546309df86ead7a7 +size 349616 diff --git a/assets/extensions/sponza/textures/sponza_material__57_albedo.ktx b/assets/extensions/sponza/textures/sponza_material__57_albedo.ktx new file mode 100644 index 0000000000000000000000000000000000000000..7fcb5ebde9549d500ef62fcde67decec72f5069b --- /dev/null +++ b/assets/extensions/sponza/textures/sponza_material__57_albedo.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3e4dbdfe09bdd1a76f82fa0a7c84772e50a0ea03e61a46aba1c49162edf04ddc +size 1398196 diff --git a/assets/extensions/sponza/textures/sponza_material__57_brdf.ktx b/assets/extensions/sponza/textures/sponza_material__57_brdf.ktx new file mode 100644 index 0000000000000000000000000000000000000000..a8ca59a374e27aeb2c8d66265a47437c256ffdeb --- /dev/null +++ b/assets/extensions/sponza/textures/sponza_material__57_brdf.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6110cfa34cc2521376cfe06d6eee5e78cf8b71cc422eab4b447b097c745d836c +size 1398196 diff --git a/assets/extensions/sponza/textures/sponza_material__57_normal.ktx b/assets/extensions/sponza/textures/sponza_material__57_normal.ktx new file mode 100644 index 0000000000000000000000000000000000000000..cfafae694b96e4158ab87bd7e1182a6a7cd45b11 --- /dev/null +++ b/assets/extensions/sponza/textures/sponza_material__57_normal.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6df881e1e347128baff1e07ccdce66d72270168a30144fed86316b52e5fac233 +size 1398196 diff --git a/assets/extensions/sponza/textures/sponza_roof_albedo.ktx b/assets/extensions/sponza/textures/sponza_roof_albedo.ktx new file mode 100644 index 0000000000000000000000000000000000000000..948000115ee6f0e9d486c22b42a9e1b5131457ee --- /dev/null +++ b/assets/extensions/sponza/textures/sponza_roof_albedo.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a8c7340f5b37c67048db4c8cb9a64629f4cb19934de5bd20ac3bb99e65edc0fb +size 1398196 diff --git a/assets/extensions/sponza/textures/sponza_roof_brdf.ktx b/assets/extensions/sponza/textures/sponza_roof_brdf.ktx new file mode 100644 index 0000000000000000000000000000000000000000..d43339366f653e06f10162776ad93bc2a713f2de --- /dev/null +++ b/assets/extensions/sponza/textures/sponza_roof_brdf.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:170e221ab3144369b7f1b7f27e3667ec8d6c4a43c3b6cb6ffd396fcbb5d82148 +size 1398196 diff --git a/assets/extensions/sponza/textures/sponza_roof_normal.ktx b/assets/extensions/sponza/textures/sponza_roof_normal.ktx new file mode 100644 index 0000000000000000000000000000000000000000..e2635838d376dbdceb4753d1cdb91be8eba67149 --- /dev/null +++ b/assets/extensions/sponza/textures/sponza_roof_normal.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:04cc6619968018421bd45e099ddf4300b9b045a67a509f722be1a24f77a4dba8 +size 1398196 diff --git a/assets/extensions/sponza/textures/sponza_vase_albedo.ktx b/assets/extensions/sponza/textures/sponza_vase_albedo.ktx new file mode 100644 index 0000000000000000000000000000000000000000..85139951e3faaf19135419e27e408a063d77a3bd --- /dev/null +++ b/assets/extensions/sponza/textures/sponza_vase_albedo.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:28b6231a99b3e7a2c492de35262a8d040cff0bca7f4daa27713258b299372f5b +size 1398196 diff --git a/assets/extensions/sponza/textures/sponza_vase_brdf.ktx b/assets/extensions/sponza/textures/sponza_vase_brdf.ktx new file mode 100644 index 0000000000000000000000000000000000000000..e2a5ed274fb13727c50e6f4166562dfe728adab0 --- /dev/null +++ b/assets/extensions/sponza/textures/sponza_vase_brdf.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8783cda81301b0978c1d6feefc27a347e0fbd8ba598bf433bf245db97f97a716 +size 1398196 diff --git a/assets/extensions/sponza/textures/sponza_vase_hanging_albedo.ktx b/assets/extensions/sponza/textures/sponza_vase_hanging_albedo.ktx new file mode 100644 index 0000000000000000000000000000000000000000..29ec9268ad32063989b9638cc25868bc98608735 --- /dev/null +++ b/assets/extensions/sponza/textures/sponza_vase_hanging_albedo.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fbacd57921c0efd8218dbd92bf3ea709b4a0c949597db97d2bd9d251b39efa8e +size 1398196 diff --git a/assets/extensions/sponza/textures/sponza_vase_hanging_brdf.ktx b/assets/extensions/sponza/textures/sponza_vase_hanging_brdf.ktx new file mode 100644 index 0000000000000000000000000000000000000000..a8bcb5c617dfd242c755f2e228d30770aa4117d0 --- /dev/null +++ b/assets/extensions/sponza/textures/sponza_vase_hanging_brdf.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6e630186097c231adb94b5868701a5edddfbf420d480a38dfe7a4604693b890a +size 1398196 diff --git a/assets/extensions/sponza/textures/sponza_vase_hanging_normal.ktx b/assets/extensions/sponza/textures/sponza_vase_hanging_normal.ktx new file mode 100644 index 0000000000000000000000000000000000000000..4bde866e4f90eaec7f442d6b50bb5309fd268596 --- /dev/null +++ b/assets/extensions/sponza/textures/sponza_vase_hanging_normal.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:09db7278ccb4ac31576880a8d32970f97f243576ce0cdd95b9e2ea3c40c39e37 +size 1398196 diff --git a/assets/extensions/sponza/textures/sponza_vase_normal.ktx b/assets/extensions/sponza/textures/sponza_vase_normal.ktx new file mode 100644 index 0000000000000000000000000000000000000000..27090e83ebe98cbde1e518972b14b5f7c3260eef --- /dev/null +++ b/assets/extensions/sponza/textures/sponza_vase_normal.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fd742086cad72e09461b30afec04fdf47b1a39324bb47ec6540a8c492a1bb061 +size 1398196 diff --git a/assets/extensions/sponza/textures/sponza_vase_round_albedo.ktx b/assets/extensions/sponza/textures/sponza_vase_round_albedo.ktx new file mode 100644 index 0000000000000000000000000000000000000000..310a6441698dbec52d8e5b6d5d3867da0796b38e --- /dev/null +++ b/assets/extensions/sponza/textures/sponza_vase_round_albedo.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b3cf02152b2fdf525e79aa01e65c8cfd5ee8668af8d5cd1a8dcabc028d40d6fe +size 1398196 diff --git a/assets/extensions/sponza/textures/sponza_vase_round_brdf.ktx b/assets/extensions/sponza/textures/sponza_vase_round_brdf.ktx new file mode 100644 index 0000000000000000000000000000000000000000..bbe74ac133d58997d5513b220882c7b1ab394337 --- /dev/null +++ b/assets/extensions/sponza/textures/sponza_vase_round_brdf.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5828a4b3c4cec99dcd7c957997324885287599d3f57098947515a5141b2a77ea +size 1398196 diff --git a/assets/extensions/sponza/textures/sponza_vase_round_normal.ktx b/assets/extensions/sponza/textures/sponza_vase_round_normal.ktx new file mode 100644 index 0000000000000000000000000000000000000000..9eb256d43bbc0534081a36cbad51314ef1ae7f8d --- /dev/null +++ b/assets/extensions/sponza/textures/sponza_vase_round_normal.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dcd6675cd8aa82852f44c1712b9ea37e6dedaebb89649708c2105e5f36e32413 +size 1398196 diff --git a/clang-format.cmake b/clang-format.cmake index 30b02f0ce3982cd0c59ec50953f313f13ceb5df9..e5b78033a735e1c8838c5f24e822c5b7d09476de 100644 --- a/clang-format.cmake +++ b/clang-format.cmake @@ -1,7 +1,7 @@ # additional target to perform clang-format run, requires clang-format # get all project files -file(GLOB_RECURSE ALL_SOURCE_FILES *.cpp *.h*) +file(GLOB_RECURSE ALL_SOURCE_FILES "${MIRRAGE_ROOT_DIR}/src/*.cpp" "${MIRRAGE_ROOT_DIR}/src/*.h*") add_custom_target( clangformat diff --git a/dependencies/CMakeLists.txt b/dependencies/CMakeLists.txt index f1e7b60c9af42364cb98c341d9b1422dfe5f856b..073ac42abbb2b375ae6c695fda844fe5ef4ce083 100644 --- a/dependencies/CMakeLists.txt +++ b/dependencies/CMakeLists.txt @@ -1,15 +1,21 @@ -cmake_minimum_required(VERSION 3.2 FATAL_ERROR) +cmake_minimum_required(VERSION 3.11 FATAL_ERROR) SET(BUILD_SHARED_LIBS FALSE CACHE BOOL "" FORCE) add_subdirectory(asyncplusplus) -add_subdirectory(backward-cpp) + +if(${MIRRAGE_ENABLE_BACKWARD}) + add_subdirectory(backward-cpp) +endif() + add_subdirectory(enet) include(glm_interface.cmake) include(gsl_interface.cmake) include(moodycamel_interface.cmake) -include(nuklear_interface.cmake) +include(imgui_interface.cmake) -include(magic_get_interface.cmake) +if(NOT TARGET boost::pfr) + include(magic_get_interface.cmake) +endif() SET(PHYSFS_ARCHIVE_7Z FALSE CACHE BOOL "" FORCE) SET(PHYSFS_BUILD_SHARED FALSE CACHE BOOL "" FORCE) @@ -20,6 +26,50 @@ include(plog_interface.cmake) include(robin-map_interface.cmake) include(doctest_interface.cmake) +if (WIN32) + option(MIRRAGE_PREFER_SYSTEM_SDL "Try to find an already installed SDL2 on the system before building our own" OFF) +else() + option(MIRRAGE_PREFER_SYSTEM_SDL "Try to find an already installed SDL2 on the system before building our own" ON) +endif() +if(MIRRAGE_PREFER_SYSTEM_SDL) + find_package(SDL2) + if(SDL2_FOUND) + if(TARGET SDL2::SDL2) + set_target_properties(SDL2::SDL2 PROPERTIES IMPORTED_GLOBAL TRUE) + set_target_properties(SDL2::SDL2main PROPERTIES IMPORTED_GLOBAL TRUE) + add_library(mirrage::deps::SDL2 ALIAS SDL2::SDL2) + add_library(mirrage::deps::SDL2main ALIAS SDL2::SDL2main) + else() + if(NOT EXISTS ${SDL2_INCLUDE_DIR}/SDL.h) + if(EXISTS ${SDL2_INCLUDE_DIR}/SDL2/SDL.h) + set(SDL2_INCLUDE_DIR "${SDL2_INCLUDE_DIR}/SDL2") + else() + find_path(SDL2_INCLUDE_DIR NAMES SDL_vulkan.h PATH_SUFFIXES SDL2) + message("Found SDL2 include directory: ${SDL2_INCLUDE_DIR}") + endif() + endif() + + if(EXISTS ${SDL2_INCLUDE_DIR}/SDL.h) + add_library(mirrage::deps::SDL2 INTERFACE IMPORTED GLOBAL) + set_property(TARGET mirrage::deps::SDL2 PROPERTY INTERFACE_LINK_LIBRARIES ${SDL2_LIBRARIES}) + set_property(TARGET mirrage::deps::SDL2 PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${SDL2_INCLUDE_DIR}) + message("Generated SDL2 target: ${SDL2_LIBRARIES}; ${SDL2_INCLUDE_DIR}") + endif() + endif() + endif() +endif() + +if(NOT TARGET mirrage::deps::SDL2) + message("Building SDL2 from source") + add_subdirectory(SDL) + if(MSVC) + target_compile_options(SDL2 PRIVATE /wd4267 /wd4018) + target_compile_options(SDL2-static PRIVATE /wd4267 /wd4018) + endif() + add_library(mirrage::deps::SDL2 ALIAS SDL2-static) + add_library(mirrage::deps::SDL2main ALIAS SDL2main) +endif() + add_subdirectory(sf2) @@ -31,4 +81,5 @@ if(MIRRAGE_BUILD_MESH_CONVERTER) endif() add_subdirectory(stb_image) + include(crunch_interface.cmake) endif() diff --git a/dependencies/SDL b/dependencies/SDL new file mode 160000 index 0000000000000000000000000000000000000000..279eb4402b59c15eee566d98bbe4d2b9c22604cd --- /dev/null +++ b/dependencies/SDL @@ -0,0 +1 @@ +Subproject commit 279eb4402b59c15eee566d98bbe4d2b9c22604cd diff --git a/dependencies/asyncplusplus b/dependencies/asyncplusplus index df0df2d889a78cc594aad8bbbdeb6240e7605b88..a22315d5bda54f802a0c94ecd71e4b33fbfa2796 160000 --- a/dependencies/asyncplusplus +++ b/dependencies/asyncplusplus @@ -1 +1 @@ -Subproject commit df0df2d889a78cc594aad8bbbdeb6240e7605b88 +Subproject commit a22315d5bda54f802a0c94ecd71e4b33fbfa2796 diff --git a/dependencies/crunch b/dependencies/crunch new file mode 160000 index 0000000000000000000000000000000000000000..b9b8066a84a2c19769a8200cd114b8e3f00b540a --- /dev/null +++ b/dependencies/crunch @@ -0,0 +1 @@ +Subproject commit b9b8066a84a2c19769a8200cd114b8e3f00b540a diff --git a/dependencies/crunch_interface.cmake b/dependencies/crunch_interface.cmake new file mode 100644 index 0000000000000000000000000000000000000000..a54b827265b50508c478d505ec821a3bbc033dc6 --- /dev/null +++ b/dependencies/crunch_interface.cmake @@ -0,0 +1,117 @@ +cmake_minimum_required(VERSION 3.2 FATAL_ERROR) + +project(crunch) + +if(MSVC) + set(CRUNCH_PLATFORM_SOURCES crunch/crnlib/crn_threading_win32.cpp) +else() + set(CRUNCH_PLATFORM_SOURCES crunch/crnlib/crn_threading_pthreads.cpp) +endif() + + +file(GLOB_RECURSE CRUNCH_SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/crunch/crnlib/*.h + ${CMAKE_CURRENT_SOURCE_DIR}/crunch/crunch/*.h + ${CMAKE_CURRENT_SOURCE_DIR}/crunch/inc/*.h +) +add_library(crunch STATIC ${CRUNCH_SOURCES} ${CRUNCH_PLATFORM_SOURCES} + crunch/crnlib/crn_arealist.cpp + crunch/crnlib/crn_assert.cpp + crunch/crnlib/crn_checksum.cpp + crunch/crnlib/crn_colorized_console.cpp + crunch/crnlib/crn_command_line_params.cpp + crunch/crnlib/crn_comp.cpp + crunch/crnlib/crn_console.cpp + crunch/crnlib/crn_core.cpp + crunch/crnlib/crn_data_stream.cpp + crunch/crnlib/crn_dds_comp.cpp + crunch/crnlib/crn_decomp.cpp + crunch/crnlib/crn_dxt1.cpp + crunch/crnlib/crn_dxt5a.cpp + crunch/crnlib/crn_dxt.cpp + crunch/crnlib/crn_dxt_endpoint_refiner.cpp + crunch/crnlib/crn_dxt_fast.cpp + crunch/crnlib/crn_dxt_hc_common.cpp + crunch/crnlib/crn_dxt_hc.cpp + crunch/crnlib/crn_dxt_image.cpp + crunch/crnlib/crn_dynamic_string.cpp + crunch/crnlib/crn_etc.cpp + crunch/crnlib/crn_file_utils.cpp + crunch/crnlib/crn_find_files.cpp + crunch/crnlib/crn_hash.cpp + crunch/crnlib/crn_hash_map.cpp + crunch/crnlib/crn_huffman_codes.cpp + crunch/crnlib/crn_image_utils.cpp + crunch/crnlib/crn_jpgd.cpp + crunch/crnlib/crn_jpge.cpp + crunch/crnlib/crn_ktx_texture.cpp + crunch/crnlib/crnlib.cpp + crunch/crnlib/crn_lzma_codec.cpp + crunch/crnlib/crn_math.cpp + crunch/crnlib/crn_mem.cpp + crunch/crnlib/crn_miniz.cpp + crunch/crnlib/crn_mipmapped_texture.cpp + crunch/crnlib/crn_pixel_format.cpp + crunch/crnlib/crn_platform.cpp + crunch/crnlib/crn_prefix_coding.cpp + crunch/crnlib/crn_qdxt1.cpp + crunch/crnlib/crn_qdxt5.cpp + crunch/crnlib/crn_rand.cpp + crunch/crnlib/crn_resample_filters.cpp + crunch/crnlib/crn_resampler.cpp + crunch/crnlib/crn_rg_etc1.cpp + crunch/crnlib/crn_ryg_dxt.cpp + crunch/crnlib/crn_sparse_bit_array.cpp + crunch/crnlib/crn_stb_image.cpp + crunch/crnlib/crn_strutils.cpp + crunch/crnlib/crn_symbol_codec.cpp + crunch/crnlib/crn_texture_comp.cpp + crunch/crnlib/crn_texture_conversion.cpp + crunch/crnlib/crn_texture_file_types.cpp + crunch/crnlib/crn_threaded_resampler.cpp + crunch/crnlib/crn_timer.cpp + crunch/crnlib/crn_utils.cpp + crunch/crnlib/crn_value.cpp + crunch/crnlib/crn_vector.cpp + crunch/crnlib/crn_zeng.cpp + crunch/crnlib/lzma_7zBuf2.cpp + crunch/crnlib/lzma_7zBuf.cpp + crunch/crnlib/lzma_7zCrc.cpp + crunch/crnlib/lzma_7zFile.cpp + crunch/crnlib/lzma_7zStream.cpp + crunch/crnlib/lzma_Alloc.cpp + crunch/crnlib/lzma_Bcj2.cpp + crunch/crnlib/lzma_Bra86.cpp + crunch/crnlib/lzma_Bra.cpp + crunch/crnlib/lzma_BraIA64.cpp + crunch/crnlib/lzma_LzFind.cpp + crunch/crnlib/lzma_LzmaDec.cpp + crunch/crnlib/lzma_LzmaEnc.cpp + crunch/crnlib/lzma_LzmaLib.cpp +) +add_library(crunch::crunch ALIAS crunch) + +if(NOT MSVC) + target_compile_options(crunch PRIVATE -fno-strict-aliasing -lpthread -w) +endif() + +target_include_directories(crunch PUBLIC + $ + $) + +install(TARGETS crunch EXPORT crunchTargets + INCLUDES DESTINATION include + ARCHIVE DESTINATION lib + LIBRARY DESTINATION lib +) +install(DIRECTORY crunch/inc/ DESTINATION include) + +export( + EXPORT crunchTargets + FILE "${CMAKE_CURRENT_BINARY_DIR}/crunchTargets.cmake" +) + +install( + EXPORT crunchTargets FILE crunchTargets.cmake + DESTINATION lib/cmake +) diff --git a/dependencies/enet/CMakeLists.txt b/dependencies/enet/CMakeLists.txt index 27f932183227a624d74e1ae9b977fee0fa9ba8d4..30a6bf8746e5d48f1abfa2d3a981ec064512f301 100644 --- a/dependencies/enet/CMakeLists.txt +++ b/dependencies/enet/CMakeLists.txt @@ -71,8 +71,12 @@ target_include_directories(enet PUBLIC $ $) -if (MINGW) - target_link_libraries(enet winmm ws2_32) +if(WIN32) + target_link_libraries(enet PUBLIC winmm ws2_32) +endif() + +if(MSVC) + target_compile_definitions(enet PRIVATE _WINSOCK_DEPRECATED_NO_WARNINGS) endif() install(TARGETS enet EXPORT enetTargets diff --git a/dependencies/imgui b/dependencies/imgui new file mode 160000 index 0000000000000000000000000000000000000000..a53c57152b83491a4bcd7fceca9d6cbc887c0c54 --- /dev/null +++ b/dependencies/imgui @@ -0,0 +1 @@ +Subproject commit a53c57152b83491a4bcd7fceca9d6cbc887c0c54 diff --git a/dependencies/imgui_interface.cmake b/dependencies/imgui_interface.cmake new file mode 100644 index 0000000000000000000000000000000000000000..b99e5247476485d94fee10d68fa2b98905680562 --- /dev/null +++ b/dependencies/imgui_interface.cmake @@ -0,0 +1,36 @@ +cmake_minimum_required(VERSION 3.2 FATAL_ERROR) + +project(imgui) + +add_library(imgui STATIC + imgui/imgui.cpp + imgui/imgui.h + imgui/imgui_demo.cpp + imgui/imgui_draw.cpp + imgui/imgui_internal.h + imgui/imgui_widgets.cpp + imgui/imstb_rectpack.h + imgui/imstb_textedit.h + imgui/imstb_truetype.h +) +add_library(imgui::imgui ALIAS imgui) +target_include_directories(imgui SYSTEM INTERFACE + $ + $ +) +install(TARGETS imgui EXPORT imguiTargets + INCLUDES DESTINATION include + ARCHIVE DESTINATION lib + LIBRARY DESTINATION lib +) + +export( + EXPORT imguiTargets + FILE "${CMAKE_CURRENT_BINARY_DIR}/imguiTargets.cmake" +) + +install( + EXPORT imguiTargets FILE imguiTargets.cmake + NAMESPACE imgui:: + DESTINATION lib/cmake +) diff --git a/dependencies/magic_get_interface.cmake b/dependencies/magic_get_interface.cmake index cb58d2288368cb8b43140205fa85e82c7b6e0551..e19539e44d0828a739610e43080a34ce40d7fb1d 100644 --- a/dependencies/magic_get_interface.cmake +++ b/dependencies/magic_get_interface.cmake @@ -1,21 +1,14 @@ cmake_minimum_required(VERSION 3.2 FATAL_ERROR) -project(magic_get) +include_guard() -add_library(magic_get INTERFACE) -add_library(boost::magic_get ALIAS magic_get) -target_include_directories(magic_get INTERFACE +add_library(pfr INTERFACE) +add_library(boost::pfr ALIAS pfr) +target_include_directories(pfr INTERFACE $ $) -if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") - # GCC broke their structured binding implementation in 7.2.0. - # See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81888 - # TODO: Remove when fixed. - target_compile_options(magic_get INTERFACE -DBOOST_PFR_USE_CPP17=0) -endif() - -install(TARGETS magic_get EXPORT magic_get_targets INCLUDES DESTINATION include) +install(TARGETS pfr EXPORT magic_get_targets INCLUDES DESTINATION include) install( DIRECTORY ${CMAKE_SOURCE_DIR}/magic_get/include/ DESTINATION include diff --git a/dependencies/nuklear b/dependencies/nuklear deleted file mode 160000 index aeb18269131ab2c8d579aab935e15a8f4b040e38..0000000000000000000000000000000000000000 --- a/dependencies/nuklear +++ /dev/null @@ -1 +0,0 @@ -Subproject commit aeb18269131ab2c8d579aab935e15a8f4b040e38 diff --git a/dependencies/physfs b/dependencies/physfs index 7c693a1ce4d2b82ebcb62674365863224543f5bd..53684f1d003058836f67e4f28e5d22e7d7fde597 160000 --- a/dependencies/physfs +++ b/dependencies/physfs @@ -1 +1 @@ -Subproject commit 7c693a1ce4d2b82ebcb62674365863224543f5bd +Subproject commit 53684f1d003058836f67e4f28e5d22e7d7fde597 diff --git a/dependencies/plog b/dependencies/plog index b56969ec12dacc40b08daa211e336feead538e94..7c54ae4110f2d4e37f083eb76ed069aa87d6697c 160000 --- a/dependencies/plog +++ b/dependencies/plog @@ -1 +1 @@ -Subproject commit b56969ec12dacc40b08daa211e336feead538e94 +Subproject commit 7c54ae4110f2d4e37f083eb76ed069aa87d6697c diff --git a/dependencies/sf2 b/dependencies/sf2 index 26cc9aa8881064c6f43caac653d809d8717f4c4e..8a8c6a170fc05fbea5a75aeea8da20307ff26b08 160000 --- a/dependencies/sf2 +++ b/dependencies/sf2 @@ -1 +1 @@ -Subproject commit 26cc9aa8881064c6f43caac653d809d8717f4c4e +Subproject commit 8a8c6a170fc05fbea5a75aeea8da20307ff26b08 diff --git a/embed_assets.cmake b/embed_assets.cmake new file mode 100644 index 0000000000000000000000000000000000000000..5b104f2685d84c4a02921d9610cadfa173aa38e4 --- /dev/null +++ b/embed_assets.cmake @@ -0,0 +1,94 @@ +cmake_minimum_required(VERSION 3.2 FATAL_ERROR) + +macro(mirrage_embed_asset) + set(options) + set(oneValueArgs TARGET EXPORT) + set(multiValueArgs SOURCES DEPENDS) + cmake_parse_arguments(EMBED_ASSET "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + set(target ${EMBED_ASSET_TARGET}) + + string (REPLACE ";" "$" src_files_str "${EMBED_ASSET_SOURCES}") + + set(ID "mirrage_embedded_asset_${target}") + if(MSVC) + set(EMBED_SRC_FILE "${CMAKE_CURRENT_BINARY_DIR}/embedded_assets_${target}.rc") + set(EMBED_MODE "MSVC") + elseif(APPLE) + set(EMBED_SRC_FILE "${CMAKE_CURRENT_BINARY_DIR}/embedded_assets.s") + set(EMBED_MODE "APPLE") + else() + set(EMBED_SRC_FILE "${CMAKE_CURRENT_BINARY_DIR}/embedded_assets.s") + set(EMBED_MODE "ASM") + endif() + + add_custom_command(OUTPUT ${EMBED_SRC_FILE} + COMMAND ${CMAKE_COMMAND} -DMIRRAGE_ROOT_DIR=${MIRRAGE_ROOT_DIR} -DEMBED_MODE=${EMBED_MODE} -DID=${ID} -DSRC_FILES=${src_files_str} -DDST_DIR=${CMAKE_CURRENT_BINARY_DIR} -DEMBED_SRC_FILE=${EMBED_SRC_FILE} -P ${MIRRAGE_ROOT_DIR}/embed_recursive_into_asm.cmake + DEPENDS ${EMBED_ASSET_DEPENDS} + VERBATIM + ) + + set(PLATFORM_EMBED_SRC "") + + if(MSVC) + string(TOUPPER "${ID}" RES_ID) + set(PLATFORM_EMBED_SRC +"#include +#include + +static auto create_asset() -> mirrage::asset::Embedded_asset { + auto handle = GetModuleHandle(NULL); + auto res = FindResource(handle, \"${RES_ID}\", RT_RCDATA); + + if(!res){ + throw std::runtime_error(\"Couldn't find ressource ${RES_ID}.\"); + } + + return mirrage::asset::Embedded_asset(\"${target}\", + gsl::span{reinterpret_cast(LockResource(LoadResource(handle, res))), + static_cast(SizeofResource(handle, res))}); +} + +static auto mirrage_asset_reg = create_asset(); +") + + else() + set(PLATFORM_EMBED_SRC +"extern \"C\" const char ${ID}[]; +extern \"C\" const int ${ID}_size; + +static auto mirrage_asset_reg = mirrage::asset::Embedded_asset(\"${target}\", + gsl::span{reinterpret_cast(&*${ID}), ${ID}_size}); +") + endif() + + file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/embedded_assets.cpp" CONTENT +"#include + +${PLATFORM_EMBED_SRC} + +void ref_embedded_assets_${target}() { + volatile mirrage::asset::Embedded_asset* x = &mirrage_asset_reg; +#ifndef _MSC_VER + asm volatile(\"\" : \"+r\" (x)); +#endif +} +") + + if(NOT MSVC) + target_sources(${target} PRIVATE ${EMBED_SRC_FILE}) + endif() + target_sources(${target} PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/embedded_assets.cpp") + add_custom_target(mirrage_embedded_assets_${target} DEPENDS ${EMBED_SRC_FILE}) + add_dependencies(${target} mirrage_embedded_assets_${target}) + if(MSVC) + add_library(mirrage_embedded_assets_obj_${target} OBJECT "${EMBED_SRC_FILE}") + target_link_libraries(${target} INTERFACE $) + add_dependencies(mirrage_embedded_assets_obj_${target} mirrage_embedded_assets_${target}) + if(EMBED_ASSET_EXPORT) + install(TARGETS mirrage_embedded_assets_obj_${target} + EXPORT ${EMBED_ASSET_EXPORT} + OBJECTS DESTINATION lib) + endif() + endif() +endmacro() + diff --git a/embed_recursive_into_asm.cmake b/embed_recursive_into_asm.cmake new file mode 100644 index 0000000000000000000000000000000000000000..d999e6dd90e2fa533ec6fb4b2532c6bc02dc27db --- /dev/null +++ b/embed_recursive_into_asm.cmake @@ -0,0 +1,46 @@ +cmake_minimum_required(VERSION 3.2 FATAL_ERROR) + +function(mirrage_copy_recursive src dst) + foreach(path ${src}) + get_filename_component(file ${path} NAME) + if(IS_DIRECTORY ${path}) + set(files "") + file(GLOB files ${path}/*) + mirrage_copy_recursive("${files}" "${dst}/${file}") + set(local_copied_files ${local_copied_files} ${copied_files}) + else() + execute_process( + COMMAND ${CMAKE_COMMAND} -E make_directory "${dst}" + OUTPUT_QUIET + ) + execute_process( + COMMAND ${CMAKE_COMMAND} -E copy_if_different "${path}" "${dst}/" + OUTPUT_QUIET + ) + list(APPEND local_copied_files "${dst}/${file}") + endif() + endforeach(path) + + set(copied_files "${local_copied_files}" PARENT_SCOPE) +endfunction() + +mirrage_copy_recursive("${SRC_FILES}" "${DST_DIR}/embed") + +execute_process(COMMAND ${CMAKE_COMMAND} -E tar "cfv" "${DST_DIR}/embedded_assets.zip" --format=zip ${copied_files} + WORKING_DIRECTORY "${DST_DIR}/embed" + OUTPUT_QUIET +) + +if("${EMBED_MODE} " STREQUAL "MSVC ") + string(TOUPPER "${ID}" RES_ID) + configure_file(${MIRRAGE_ROOT_DIR}/embedded_assets.rc.in "${EMBED_SRC_FILE}") + execute_process(COMMAND ${CMAKE_COMMAND} -E touch "${EMBED_SRC_FILE}" OUTPUT_QUIET) +else() + if("${EMBED_MODE} " STREQUAL "APPLE ") + set(SECTION ".const_data, no_dead_strip") + else() + set(SECTION ".section .rodata") + endif() + configure_file(${MIRRAGE_ROOT_DIR}/embedded_assets.s.in "${CMAKE_CURRENT_BINARY_DIR}/embedded_assets.s") + execute_process(COMMAND ${CMAKE_COMMAND} -E touch "${CMAKE_CURRENT_BINARY_DIR}/embedded_assets.s" OUTPUT_QUIET) +endif() diff --git a/embedded_assets.rc.in b/embedded_assets.rc.in new file mode 100644 index 0000000000000000000000000000000000000000..fc61522bea5d43486062122ab5bde2154ddb5360 --- /dev/null +++ b/embedded_assets.rc.in @@ -0,0 +1 @@ +${RES_ID} RCDATA "${DST_DIR}/embedded_assets.zip" diff --git a/embedded_assets.s.in b/embedded_assets.s.in new file mode 100644 index 0000000000000000000000000000000000000000..1f908f5b15afb3f0dcffba20e2880db8723149b1 --- /dev/null +++ b/embedded_assets.s.in @@ -0,0 +1,9 @@ + ${SECTION} + .global ${ID} + .global ${ID}_size +${ID}: + .incbin "${DST_DIR}/embedded_assets.zip" +1: +${ID}_size: + .int 1b - ${ID} + diff --git a/globals.cmake b/globals.cmake index f3af22636cdf410ac36ddec66b24373a39606e62..c6d3eae619d5eab54f92faa32c22fd53cecea21d 100644 --- a/globals.cmake +++ b/globals.cmake @@ -1,3 +1,4 @@ +cmake_minimum_required(VERSION 3.2 FATAL_ERROR) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) @@ -5,11 +6,19 @@ set(CMAKE_CXX_EXTENSIONS OFF) # required at top-level set(MIRRAGE_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}) +set(MIRRAGE_ROOT_PROJECT_DIR ${CMAKE_CURRENT_SOURCE_DIR}) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${MIRRAGE_ROOT_DIR}/modules") -# add_definitions(-DHPC_HISTOGRAM_DEBUG_VIEW) +enable_language(C CXX ASM) + add_definitions(-DGSL_TERMINATE_ON_CONTRACT_VIOLATION) +if (WIN32) + option(MIRRAGE_ENABLE_BACKWARD "Enable stacktraces through backward-cpp" OFF) +else() + option(MIRRAGE_ENABLE_BACKWARD "Enable stacktraces through backward-cpp" ON) +endif() + # LTO if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ftemplate-depth=1024 -fno-strict-aliasing") @@ -39,7 +48,7 @@ endif() if (CMAKE_CXX_COMPILER_ID MATCHES "Clang") set(MIRRAGE_DEFAULT_COMPILER_ARGS -Wextra -Wall -pedantic -Wextra-semi -Wzero-as-null-pointer-constant -Wold-style-cast -Werror - -Wno-unused-parameter -Wno-unused-private-field -Wno-missing-braces) + -Wno-unused-parameter -Wno-unused-private-field -Wno-missing-braces -Wno-error-unused-command-line-argument) elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") set(MIRRAGE_DEFAULT_COMPILER_ARGS -Wextra -Wall -pedantic @@ -47,7 +56,9 @@ elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") -Wno-missing-braces) elseif(MSVC) - set(MIRRAGE_DEFAULT_COMPILER_ARGS /Za) + set(MIRRAGE_DEFAULT_COMPILER_ARGS /DWIN32_LEAN_AND_MEAN /DNOMINMAX /MP /W3 /WX) + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /ignore:4221") + set(CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} /ignore:4221") endif() # Select optimal linker @@ -80,13 +91,20 @@ if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" OR MIRRAGE_FORCE_LIBCPP) endif() endif() +option(MIRRAGE_OPTIMIZE_NATIVE "Enable -march=native" OFF) +if(${MIRRAGE_OPTIMIZE_NATIVE}) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=native") +endif() + option(MIRRAGE_ENABLE_COTIRE "Enable cotire" ON) if(MIRRAGE_ENABLE_COTIRE) include(cotire OPTIONAL) if(COMMAND cotire) add_definitions(-DGLM_FORCE_RADIANS -DGLM_FORCE_DEPTH_ZERO_TO_ON -DGLM_ENABLE_EXPERIMENTAL -DGLM_FORCE_CXX14) - add_compile_options(-pthread) + if(NOT MSVC) + add_compile_options(-pthread) + endif() set_property(GLOBAL PROPERTY COTIRE_PREFIX_HEADER_INCLUDE_PATH "${MIRRAGE_ROOT_DIR}/dependencies") set_property(GLOBAL PROPERTY COTIRE_PREFIX_HEADER_IGNORE_PATH "${MIRRAGE_ROOT_DIR}/dependencies/nuklear;${MIRRAGE_ROOT_DIR}/src;${MIRRAGE_ROOT_DIR}/dependencies/moodycamel/concurrentqueue.h") set_property(GLOBAL PROPERTY COTIRE_ADD_UNITY_BUILD FALSE) @@ -101,6 +119,8 @@ endif() option(MIRRAGE_ENABLE_CLANG_FORMAT "Includes a clangformat target, that automatically formats the source files." OFF) if(MIRRAGE_ENABLE_CLANG_FORMAT) - include(clang-format.cmake) + include(${MIRRAGE_ROOT_DIR}/clang-format.cmake) endif() +include(${MIRRAGE_ROOT_DIR}/embed_assets.cmake) + diff --git a/modules/FindSDL2.cmake b/modules/FindSDL2.cmake deleted file mode 100644 index f24af555a2529dde1cd4450b04eee6e03fe8779e..0000000000000000000000000000000000000000 --- a/modules/FindSDL2.cmake +++ /dev/null @@ -1,249 +0,0 @@ -# Locate SDL2 library -# This module defines -# SDL2_LIBRARY, the name of the library to link against -# SDL2_FOUND, if false, do not try to link to SDL2 -# SDL2_INCLUDE_DIR, where to find SDL.h -# -# This module responds to the the flag: -# SDL2_BUILDING_LIBRARY -# If this is defined, then no SDL2_main will be linked in because -# only applications need main(). -# Otherwise, it is assumed you are building an application and this -# module will attempt to locate and set the the proper link flags -# as part of the returned SDL2_LIBRARY variable. -# -# Don't forget to include SDL2main.h and SDL2main.m your project for the -# OS X framework based version. (Other versions link to -lSDL2main which -# this module will try to find on your behalf.) Also for OS X, this -# module will automatically add the -framework Cocoa on your behalf. -# -# -# Additional Note: If you see an empty SDL2_LIBRARY_TEMP in your configuration -# and no SDL2_LIBRARY, it means CMake did not find your SDL2 library -# (SDL2.dll, libsdl2.so, SDL2.framework, etc). -# Set SDL2_LIBRARY_TEMP to point to your SDL2 library, and configure again. -# Similarly, if you see an empty SDL2MAIN_LIBRARY, you should set this value -# as appropriate. These values are used to generate the final SDL2_LIBRARY -# variable, but when these values are unset, SDL2_LIBRARY does not get created. -# -# -# $SDL2 is an environment variable that would -# correspond to the ./configure --prefix=$SDL2 -# used in building SDL2. -# l.e.galup 9-20-02 -# -# Modified by Eric Wing. -# Added code to assist with automated building by using environmental variables -# and providing a more controlled/consistent search behavior. -# Added new modifications to recognize OS X frameworks and -# additional Unix paths (FreeBSD, etc). -# Also corrected the header search path to follow "proper" SDL2 guidelines. -# Added a search for SDL2main which is needed by some platforms. -# Added a search for threads which is needed by some platforms. -# Added needed compile switches for MinGW. -# -# On OSX, this will prefer the Framework version (if found) over others. -# People will have to manually change the cache values of -# SDL2_LIBRARY to override this selection or set the CMake environment -# CMAKE_INCLUDE_PATH to modify the search paths. -# -# Note that the header path has changed from SDL2/SDL.h to just SDL.h -# This needed to change because "proper" SDL2 convention -# is #include "SDL.h", not . This is done for portability -# reasons because not all systems place things in SDL2/ (see FreeBSD). -# -# Ported by Johnny Patterson. This is a literal port for SDL2 of the FindSDL.cmake -# module with the minor edit of changing "SDL" to "SDL2" where necessary. This -# was not created for redistribution, and exists temporarily pending official -# SDL2 CMake modules. -# -# Note that on windows this will only search for the 32bit libraries, to search -# for 64bit change x86/i686-w64 to x64/x86_64-w64 - -#============================================================================= -# Copyright 2003-2009 Kitware, Inc. -# -# CMake - Cross Platform Makefile Generator -# Copyright 2000-2014 Kitware, Inc. -# Copyright 2000-2011 Insight Software Consortium -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# -# * Neither the names of Kitware, Inc., the Insight Software Consortium, -# nor the names of their contributors may be used to endorse or promote -# products derived from this software without specific prior written -# permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -# This software is distributed WITHOUT ANY WARRANTY; without even the -# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the License for more information. -#============================================================================= -# (To distribute this file outside of CMake, substitute the full -# License text for the above reference.) - -FIND_PATH(SDL2_INCLUDE_DIR SDL.h - HINTS - $ENV{SDL2} - PATH_SUFFIXES include/SDL2 include SDL2 - i686-w64-mingw32/include/SDL2 - x86_64-w64-mingw32/include/SDL2 - PATHS - ~/Library/Frameworks - /Library/Frameworks - /usr/local/include/SDL2 - /usr/include/SDL2 - /sw # Fink - /opt/local # DarwinPorts - /opt/csw # Blastwave - /opt -) - -# Lookup the 64 bit libs on x64 -IF(CMAKE_SIZEOF_VOID_P EQUAL 8) - FIND_LIBRARY(SDL2_LIBRARY_TEMP SDL2 - HINTS - $ENV{SDL2} - PATH_SUFFIXES lib64 lib - lib/x64 - x86_64-w64-mingw32/lib - PATHS - /sw - /opt/local - /opt/csw - /opt - ) -# On 32bit build find the 32bit libs -ELSE(CMAKE_SIZEOF_VOID_P EQUAL 8) - FIND_LIBRARY(SDL2_LIBRARY_TEMP SDL2 - HINTS - $ENV{SDL2} - PATH_SUFFIXES lib - lib/x86 - i686-w64-mingw32/lib - PATHS - /sw - /opt/local - /opt/csw - /opt - ) -ENDIF(CMAKE_SIZEOF_VOID_P EQUAL 8) - -IF(NOT SDL2_BUILDING_LIBRARY) - IF(NOT ${SDL2_INCLUDE_DIR} MATCHES ".framework") - # Non-OS X framework versions expect you to also dynamically link to - # SDL2main. This is mainly for Windows and OS X. Other (Unix) platforms - # seem to provide SDL2main for compatibility even though they don't - # necessarily need it. - # Lookup the 64 bit libs on x64 - IF(CMAKE_SIZEOF_VOID_P EQUAL 8) - FIND_LIBRARY(SDL2MAIN_LIBRARY - NAMES SDL2main - HINTS - $ENV{SDL2} - PATH_SUFFIXES lib64 lib - lib/x64 - x86_64-w64-mingw32/lib - PATHS - /sw - /opt/local - /opt/csw - /opt - ) - # On 32bit build find the 32bit libs - ELSE(CMAKE_SIZEOF_VOID_P EQUAL 8) - FIND_LIBRARY(SDL2MAIN_LIBRARY - NAMES SDL2main - HINTS - $ENV{SDL2} - PATH_SUFFIXES lib - lib/x86 - i686-w64-mingw32/lib - PATHS - /sw - /opt/local - /opt/csw - /opt - ) - ENDIF(CMAKE_SIZEOF_VOID_P EQUAL 8) - ENDIF(NOT ${SDL2_INCLUDE_DIR} MATCHES ".framework") -ENDIF(NOT SDL2_BUILDING_LIBRARY) - -# SDL2 may require threads on your system. -# The Apple build may not need an explicit flag because one of the -# frameworks may already provide it. -# But for non-OSX systems, I will use the CMake Threads package. -IF(NOT APPLE) - FIND_PACKAGE(Threads) -ENDIF(NOT APPLE) - -# MinGW needs an additional library, mwindows -# It's total link flags should look like -lmingw32 -lSDL2main -lSDL2 -lmwindows -# (Actually on second look, I think it only needs one of the m* libraries.) -IF(MINGW) - SET(MINGW32_LIBRARY mingw32 CACHE STRING "mwindows for MinGW") -ENDIF(MINGW) - -SET(SDL2_FOUND "NO") - IF(SDL2_LIBRARY_TEMP) - # For SDL2main - IF(NOT SDL2_BUILDING_LIBRARY) - IF(SDL2MAIN_LIBRARY) - SET(SDL2_LIBRARY_TEMP ${SDL2MAIN_LIBRARY} ${SDL2_LIBRARY_TEMP}) - ENDIF(SDL2MAIN_LIBRARY) - ENDIF(NOT SDL2_BUILDING_LIBRARY) - - # For OS X, SDL2 uses Cocoa as a backend so it must link to Cocoa. - # CMake doesn't display the -framework Cocoa string in the UI even - # though it actually is there if I modify a pre-used variable. - # I think it has something to do with the CACHE STRING. - # So I use a temporary variable until the end so I can set the - # "real" variable in one-shot. - IF(APPLE) - SET(SDL2_LIBRARY_TEMP ${SDL2_LIBRARY_TEMP} "-framework Cocoa") - ENDIF(APPLE) - - # For threads, as mentioned Apple doesn't need this. - # In fact, there seems to be a problem if I used the Threads package - # and try using this line, so I'm just skipping it entirely for OS X. - IF(NOT APPLE) - SET(SDL2_LIBRARY_TEMP ${SDL2_LIBRARY_TEMP} ${CMAKE_THREAD_LIBS_INIT}) - ENDIF(NOT APPLE) - - # For MinGW library - IF(MINGW) - SET(SDL2_LIBRARY_TEMP ${MINGW32_LIBRARY} ${SDL2_LIBRARY_TEMP}) - ENDIF(MINGW) - - # Set the final string here so the GUI reflects the final state. - SET(SDL2_LIBRARY ${SDL2_LIBRARY_TEMP} CACHE STRING "Where the SDL2 Library can be found") - # Set the temp variable to INTERNAL so it is not seen in the CMake GUI - SET(SDL2_LIBRARY_TEMP "${SDL2_LIBRARY_TEMP}" CACHE INTERNAL "") - - SET(SDL2_FOUND "YES") -ENDIF(SDL2_LIBRARY_TEMP) - -INCLUDE(FindPackageHandleStandardArgs) - -FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL2 REQUIRED_VARS SDL2_LIBRARY SDL2_INCLUDE_DIR) diff --git a/modules/android_toolchain.cmake b/modules/android_toolchain.cmake deleted file mode 100644 index d97d625b127f1b4028a98652b66e1f35f2470dc4..0000000000000000000000000000000000000000 --- a/modules/android_toolchain.cmake +++ /dev/null @@ -1,1709 +0,0 @@ -# Copyright (c) 2010-2011, Ethan Rublee -# Copyright (c) 2011-2014, Andrey Kamaev -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# -# 1. Redistributions of source code must retain the above copyright notice, -# this list of conditions and the following disclaimer. -# -# 2. Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# -# 3. Neither the name of the copyright holder nor the names of its -# contributors may be used to endorse or promote products derived from this -# software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. - -# ------------------------------------------------------------------------------ -# Android CMake toolchain file, for use with the Android NDK r5-r10d -# Requires cmake 2.6.3 or newer (2.8.9 or newer is recommended). -# See home page: https://github.com/taka-no-me/android-cmake -# -# Usage Linux: -# $ export ANDROID_NDK=/absolute/path/to/the/android-ndk -# $ mkdir build && cd build -# $ cmake -DCMAKE_TOOLCHAIN_FILE=path/to/the/android.toolchain.cmake .. -# $ make -j8 -# -# Usage Windows: -# You need native port of make to build your project. -# Android NDK r7 (and newer) already has make.exe on board. -# For older NDK you have to install it separately. -# For example, this one: http://gnuwin32.sourceforge.net/packages/make.htm -# -# $ SET ANDROID_NDK=C:\absolute\path\to\the\android-ndk -# $ mkdir build && cd build -# $ cmake.exe -G"MinGW Makefiles" -# -DCMAKE_TOOLCHAIN_FILE=path\to\the\android.toolchain.cmake -# -DCMAKE_MAKE_PROGRAM="%ANDROID_NDK%\prebuilt\windows\bin\make.exe" .. -# $ cmake.exe --build . -# -# -# Options (can be set as cmake parameters: -D=): -# ANDROID_NDK=/opt/android-ndk - path to the NDK root. -# Can be set as environment variable. Can be set only at first cmake run. -# -# ANDROID_ABI=armeabi-v7a - specifies the target Application Binary -# Interface (ABI). This option nearly matches to the APP_ABI variable -# used by ndk-build tool from Android NDK. -# -# Possible targets are: -# "armeabi" - ARMv5TE based CPU with software floating point operations -# "armeabi-v7a" - ARMv7 based devices with hardware FPU instructions -# this ABI target is used by default -# "armeabi-v7a with NEON" - same as armeabi-v7a, but -# sets NEON as floating-point unit -# "armeabi-v7a with VFPV3" - same as armeabi-v7a, but -# sets VFPV3 as floating-point unit (has 32 registers instead of 16) -# "armeabi-v6 with VFP" - tuned for ARMv6 processors having VFP -# "x86" - IA-32 instruction set -# "mips" - MIPS32 instruction set -# -# 64-bit ABIs for NDK r10 and newer: -# "arm64-v8a" - ARMv8 AArch64 instruction set -# "x86_64" - Intel64 instruction set (r1) -# "mips64" - MIPS64 instruction set (r6) -# -# ANDROID_NATIVE_API_LEVEL=android-8 - level of Android API compile for. -# Option is read-only when standalone toolchain is used. -# Note: building for "android-L" requires explicit configuration. -# -# ANDROID_TOOLCHAIN_NAME=arm-linux-androideabi-4.9 - the name of compiler -# toolchain to be used. The list of possible values depends on the NDK -# version. For NDK r10c the possible values are: -# -# * aarch64-linux-android-4.9 -# * aarch64-linux-android-clang3.4 -# * aarch64-linux-android-clang3.5 -# * arm-linux-androideabi-4.6 -# * arm-linux-androideabi-4.8 -# * arm-linux-androideabi-4.9 (default) -# * arm-linux-androideabi-clang3.4 -# * arm-linux-androideabi-clang3.5 -# * mips64el-linux-android-4.9 -# * mips64el-linux-android-clang3.4 -# * mips64el-linux-android-clang3.5 -# * mipsel-linux-android-4.6 -# * mipsel-linux-android-4.8 -# * mipsel-linux-android-4.9 -# * mipsel-linux-android-clang3.4 -# * mipsel-linux-android-clang3.5 -# * x86-4.6 -# * x86-4.8 -# * x86-4.9 -# * x86-clang3.4 -# * x86-clang3.5 -# * x86_64-4.9 -# * x86_64-clang3.4 -# * x86_64-clang3.5 -# -# ANDROID_FORCE_ARM_BUILD=OFF - set ON to generate 32-bit ARM instructions -# instead of Thumb. Is not available for "armeabi-v6 with VFP" -# (is forced to be ON) ABI. -# -# ANDROID_NO_UNDEFINED=ON - set ON to show all undefined symbols as linker -# errors even if they are not used. -# -# ANDROID_SO_UNDEFINED=OFF - set ON to allow undefined symbols in shared -# libraries. Automatically turned for NDK r5x and r6x due to GLESv2 -# problems. -# -# ANDROID_STL=gnustl_static - specify the runtime to use. -# -# Possible values are: -# none -> Do not configure the runtime. -# system -> Use the default minimal system C++ runtime library. -# Implies -fno-rtti -fno-exceptions. -# Is not available for standalone toolchain. -# system_re -> Use the default minimal system C++ runtime library. -# Implies -frtti -fexceptions. -# Is not available for standalone toolchain. -# gabi++_static -> Use the GAbi++ runtime as a static library. -# Implies -frtti -fno-exceptions. -# Available for NDK r7 and newer. -# Is not available for standalone toolchain. -# gabi++_shared -> Use the GAbi++ runtime as a shared library. -# Implies -frtti -fno-exceptions. -# Available for NDK r7 and newer. -# Is not available for standalone toolchain. -# stlport_static -> Use the STLport runtime as a static library. -# Implies -fno-rtti -fno-exceptions for NDK before r7. -# Implies -frtti -fno-exceptions for NDK r7 and newer. -# Is not available for standalone toolchain. -# stlport_shared -> Use the STLport runtime as a shared library. -# Implies -fno-rtti -fno-exceptions for NDK before r7. -# Implies -frtti -fno-exceptions for NDK r7 and newer. -# Is not available for standalone toolchain. -# gnustl_static -> Use the GNU STL as a static library. -# Implies -frtti -fexceptions. -# gnustl_shared -> Use the GNU STL as a shared library. -# Implies -frtti -fno-exceptions. -# Available for NDK r7b and newer. -# Silently degrades to gnustl_static if not available. -# -# ANDROID_STL_FORCE_FEATURES=ON - turn rtti and exceptions support based on -# chosen runtime. If disabled, then the user is responsible for settings -# these options. -# -# What?: -# android-cmake toolchain searches for NDK/toolchain in the following order: -# ANDROID_NDK - cmake parameter -# ANDROID_NDK - environment variable -# ANDROID_STANDALONE_TOOLCHAIN - cmake parameter -# ANDROID_STANDALONE_TOOLCHAIN - environment variable -# ANDROID_NDK - default locations -# ANDROID_STANDALONE_TOOLCHAIN - default locations -# -# Make sure to do the following in your scripts: -# SET( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${my_cxx_flags}" ) -# SET( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${my_cxx_flags}" ) -# The flags will be prepopulated with critical flags, so don't loose them. -# Also be aware that toolchain also sets configuration-specific compiler -# flags and linker flags. -# -# ANDROID and BUILD_ANDROID will be set to true, you may test any of these -# variables to make necessary Android-specific configuration changes. -# -# Also ARMEABI or ARMEABI_V7A or X86 or MIPS or ARM64_V8A or X86_64 or MIPS64 -# will be set true, mutually exclusive. NEON option will be set true -# if VFP is set to NEON. -# -# ------------------------------------------------------------------------------ - -cmake_minimum_required( VERSION 2.6.3 ) - -if( DEFINED CMAKE_CROSSCOMPILING ) - # subsequent toolchain loading is not really needed - return() -endif() - -if( CMAKE_TOOLCHAIN_FILE ) - # touch toolchain variable to suppress "unused variable" warning -endif() - -# inherit settings in recursive loads -get_property( _CMAKE_IN_TRY_COMPILE GLOBAL PROPERTY IN_TRY_COMPILE ) -if( _CMAKE_IN_TRY_COMPILE ) - include( "${CMAKE_CURRENT_SOURCE_DIR}/../android.toolchain.config.cmake" OPTIONAL ) -endif() - -# this one is important -if( CMAKE_VERSION VERSION_GREATER "3.0.99" ) - set( CMAKE_SYSTEM_NAME Android ) -else() - set( CMAKE_SYSTEM_NAME Linux ) -endif() - -# this one not so much -set( CMAKE_SYSTEM_VERSION 1 ) - -# rpath makes low sense for Android -set( CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG "" ) -set( CMAKE_SKIP_RPATH TRUE CACHE BOOL "If set, runtime paths are not added when using shared libraries." ) - -# NDK search paths -set( ANDROID_SUPPORTED_NDK_VERSIONS ${ANDROID_EXTRA_NDK_VERSIONS} -r10d -r10c -r10b -r10 -r9d -r9c -r9b -r9 -r8e -r8d -r8c -r8b -r8 -r7c -r7b -r7 -r6b -r6 -r5c -r5b -r5 "" ) -if( NOT DEFINED ANDROID_NDK_SEARCH_PATHS ) - if( CMAKE_HOST_WIN32 ) - file( TO_CMAKE_PATH "$ENV{PROGRAMFILES}" ANDROID_NDK_SEARCH_PATHS ) - set( ANDROID_NDK_SEARCH_PATHS "${ANDROID_NDK_SEARCH_PATHS}" "$ENV{SystemDrive}/NVPACK" ) - else() - file( TO_CMAKE_PATH "$ENV{HOME}" ANDROID_NDK_SEARCH_PATHS ) - set( ANDROID_NDK_SEARCH_PATHS /opt "${ANDROID_NDK_SEARCH_PATHS}/NVPACK" ) - endif() -endif() -if( NOT DEFINED ANDROID_STANDALONE_TOOLCHAIN_SEARCH_PATH ) - set( ANDROID_STANDALONE_TOOLCHAIN_SEARCH_PATH /opt/android-toolchain ) -endif() - -# known ABIs -set( ANDROID_SUPPORTED_ABIS_arm "armeabi-v7a;armeabi;armeabi-v7a with NEON;armeabi-v7a with VFPV3;armeabi-v6 with VFP" ) -set( ANDROID_SUPPORTED_ABIS_arm64 "arm64-v8a" ) -set( ANDROID_SUPPORTED_ABIS_x86 "x86" ) -set( ANDROID_SUPPORTED_ABIS_x86_64 "x86_64" ) -set( ANDROID_SUPPORTED_ABIS_mips "mips" ) -set( ANDROID_SUPPORTED_ABIS_mips64 "mips64" ) - -# API level defaults -set( ANDROID_DEFAULT_NDK_API_LEVEL 8 ) -set( ANDROID_DEFAULT_NDK_API_LEVEL_arm64 21 ) -set( ANDROID_DEFAULT_NDK_API_LEVEL_x86 9 ) -set( ANDROID_DEFAULT_NDK_API_LEVEL_x86_64 21 ) -set( ANDROID_DEFAULT_NDK_API_LEVEL_mips 9 ) -set( ANDROID_DEFAULT_NDK_API_LEVEL_mips64 21 ) - - -macro( __LIST_FILTER listvar regex ) - if( ${listvar} ) - foreach( __val ${${listvar}} ) - if( __val MATCHES "${regex}" ) - list( REMOVE_ITEM ${listvar} "${__val}" ) - endif() - endforeach() - endif() -endmacro() - -macro( __INIT_VARIABLE var_name ) - set( __test_path 0 ) - foreach( __var ${ARGN} ) - if( __var STREQUAL "PATH" ) - set( __test_path 1 ) - break() - endif() - endforeach() - - if( __test_path AND NOT EXISTS "${${var_name}}" ) - unset( ${var_name} CACHE ) - endif() - - if( " ${${var_name}}" STREQUAL " " ) - set( __values 0 ) - foreach( __var ${ARGN} ) - if( __var STREQUAL "VALUES" ) - set( __values 1 ) - elseif( NOT __var STREQUAL "PATH" ) - if( __var MATCHES "^ENV_.*$" ) - string( REPLACE "ENV_" "" __var "${__var}" ) - set( __value "$ENV{${__var}}" ) - elseif( DEFINED ${__var} ) - set( __value "${${__var}}" ) - elseif( __values ) - set( __value "${__var}" ) - else() - set( __value "" ) - endif() - - if( NOT " ${__value}" STREQUAL " " AND (NOT __test_path OR EXISTS "${__value}") ) - set( ${var_name} "${__value}" ) - break() - endif() - endif() - endforeach() - unset( __value ) - unset( __values ) - endif() - - if( __test_path ) - file( TO_CMAKE_PATH "${${var_name}}" ${var_name} ) - endif() - unset( __test_path ) -endmacro() - -macro( __DETECT_NATIVE_API_LEVEL _var _path ) - set( __ndkApiLevelRegex "^[\t ]*#define[\t ]+__ANDROID_API__[\t ]+([0-9]+)[\t ]*.*$" ) - file( STRINGS ${_path} __apiFileContent REGEX "${__ndkApiLevelRegex}" ) - if( NOT __apiFileContent ) - message( SEND_ERROR "Could not get Android native API level. Probably you have specified invalid level value, or your copy of NDK/toolchain is broken." ) - endif() - string( REGEX REPLACE "${__ndkApiLevelRegex}" "\\1" ${_var} "${__apiFileContent}" ) - unset( __apiFileContent ) - unset( __ndkApiLevelRegex ) -endmacro() - -macro( __DETECT_TOOLCHAIN_MACHINE_NAME _var _root ) - if( EXISTS "${_root}" ) - file( GLOB __gccExePath RELATIVE "${_root}/bin/" "${_root}/bin/*-gcc${TOOL_OS_SUFFIX}" ) - __LIST_FILTER( __gccExePath "^[.].*" ) - list( LENGTH __gccExePath __gccExePathsCount ) - if( NOT __gccExePathsCount EQUAL 1 AND NOT _CMAKE_IN_TRY_COMPILE ) - message( WARNING "Could not determine machine name for compiler from ${_root}" ) - set( ${_var} "" ) - else() - get_filename_component( __gccExeName "${__gccExePath}" NAME_WE ) - string( REPLACE "-gcc" "" ${_var} "${__gccExeName}" ) - endif() - unset( __gccExePath ) - unset( __gccExePathsCount ) - unset( __gccExeName ) - else() - set( ${_var} "" ) - endif() -endmacro() - - -# fight against cygwin -set( ANDROID_FORBID_SYGWIN TRUE CACHE BOOL "Prevent cmake from working under cygwin and using cygwin tools") -mark_as_advanced( ANDROID_FORBID_SYGWIN ) -if( ANDROID_FORBID_SYGWIN ) - if( CYGWIN ) - message( FATAL_ERROR "Android NDK and android-cmake toolchain are not welcome Cygwin. It is unlikely that this cmake toolchain will work under cygwin. But if you want to try then you can set cmake variable ANDROID_FORBID_SYGWIN to FALSE and rerun cmake." ) - endif() - - if( CMAKE_HOST_WIN32 ) - # remove cygwin from PATH - set( __new_path "$ENV{PATH}") - __LIST_FILTER( __new_path "cygwin" ) - set(ENV{PATH} "${__new_path}") - unset(__new_path) - endif() -endif() - - -# detect current host platform -if( NOT DEFINED ANDROID_NDK_HOST_X64 AND (CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "amd64|x86_64|AMD64" OR CMAKE_HOST_APPLE) ) - set( ANDROID_NDK_HOST_X64 1 CACHE BOOL "Try to use 64-bit compiler toolchain" ) - mark_as_advanced( ANDROID_NDK_HOST_X64 ) -endif() - -set( TOOL_OS_SUFFIX "" ) -if( CMAKE_HOST_APPLE ) - set( ANDROID_NDK_HOST_SYSTEM_NAME "darwin-x86_64" ) - set( ANDROID_NDK_HOST_SYSTEM_NAME2 "darwin-x86" ) -elseif( CMAKE_HOST_WIN32 ) - set( ANDROID_NDK_HOST_SYSTEM_NAME "windows-x86_64" ) - set( ANDROID_NDK_HOST_SYSTEM_NAME2 "windows" ) - set( TOOL_OS_SUFFIX ".exe" ) -elseif( CMAKE_HOST_UNIX ) - set( ANDROID_NDK_HOST_SYSTEM_NAME "linux-x86_64" ) - set( ANDROID_NDK_HOST_SYSTEM_NAME2 "linux-x86" ) -else() - message( FATAL_ERROR "Cross-compilation on your platform is not supported by this cmake toolchain" ) -endif() - -if( NOT ANDROID_NDK_HOST_X64 ) - set( ANDROID_NDK_HOST_SYSTEM_NAME ${ANDROID_NDK_HOST_SYSTEM_NAME2} ) -endif() - -# see if we have path to Android NDK -if( NOT ANDROID_NDK AND NOT ANDROID_STANDALONE_TOOLCHAIN ) - __INIT_VARIABLE( ANDROID_NDK PATH ENV_ANDROID_NDK ) -endif() -if( NOT ANDROID_NDK ) - # see if we have path to Android standalone toolchain - __INIT_VARIABLE( ANDROID_STANDALONE_TOOLCHAIN PATH ENV_ANDROID_STANDALONE_TOOLCHAIN ) - - if( NOT ANDROID_STANDALONE_TOOLCHAIN ) - #try to find Android NDK in one of the the default locations - set( __ndkSearchPaths ) - foreach( __ndkSearchPath ${ANDROID_NDK_SEARCH_PATHS} ) - foreach( suffix ${ANDROID_SUPPORTED_NDK_VERSIONS} ) - list( APPEND __ndkSearchPaths "${__ndkSearchPath}/android-ndk${suffix}" ) - endforeach() - endforeach() - __INIT_VARIABLE( ANDROID_NDK PATH VALUES ${__ndkSearchPaths} ) - unset( __ndkSearchPaths ) - - if( ANDROID_NDK ) - message( STATUS "Using default path for Android NDK: ${ANDROID_NDK}" ) - message( STATUS " If you prefer to use a different location, please define a cmake or environment variable: ANDROID_NDK" ) - else() - #try to find Android standalone toolchain in one of the the default locations - __INIT_VARIABLE( ANDROID_STANDALONE_TOOLCHAIN PATH ANDROID_STANDALONE_TOOLCHAIN_SEARCH_PATH ) - - if( ANDROID_STANDALONE_TOOLCHAIN ) - message( STATUS "Using default path for standalone toolchain ${ANDROID_STANDALONE_TOOLCHAIN}" ) - message( STATUS " If you prefer to use a different location, please define the variable: ANDROID_STANDALONE_TOOLCHAIN" ) - endif( ANDROID_STANDALONE_TOOLCHAIN ) - endif( ANDROID_NDK ) - endif( NOT ANDROID_STANDALONE_TOOLCHAIN ) -endif( NOT ANDROID_NDK ) - -# remember found paths -if( ANDROID_NDK ) - get_filename_component( ANDROID_NDK "${ANDROID_NDK}" ABSOLUTE ) - set( ANDROID_NDK "${ANDROID_NDK}" CACHE INTERNAL "Path of the Android NDK" FORCE ) - set( BUILD_WITH_ANDROID_NDK True ) - if( EXISTS "${ANDROID_NDK}/RELEASE.TXT" ) - file( STRINGS "${ANDROID_NDK}/RELEASE.TXT" ANDROID_NDK_RELEASE_FULL LIMIT_COUNT 1 REGEX "r[0-9]+[a-z]?" ) - string( REGEX MATCH "r([0-9]+)([a-z]?)" ANDROID_NDK_RELEASE "${ANDROID_NDK_RELEASE_FULL}" ) - else() - set( ANDROID_NDK_RELEASE "r1x" ) - set( ANDROID_NDK_RELEASE_FULL "unreleased" ) - endif() - string( REGEX REPLACE "r([0-9]+)([a-z]?)" "\\1*1000" ANDROID_NDK_RELEASE_NUM "${ANDROID_NDK_RELEASE}" ) - string( FIND " abcdefghijklmnopqastuvwxyz" "${CMAKE_MATCH_2}" __ndkReleaseLetterNum ) - math( EXPR ANDROID_NDK_RELEASE_NUM "${ANDROID_NDK_RELEASE_NUM}+${__ndkReleaseLetterNum}" ) -elseif( ANDROID_STANDALONE_TOOLCHAIN ) - get_filename_component( ANDROID_STANDALONE_TOOLCHAIN "${ANDROID_STANDALONE_TOOLCHAIN}" ABSOLUTE ) - # try to detect change - if( CMAKE_AR ) - string( LENGTH "${ANDROID_STANDALONE_TOOLCHAIN}" __length ) - string( SUBSTRING "${CMAKE_AR}" 0 ${__length} __androidStandaloneToolchainPreviousPath ) - if( NOT __androidStandaloneToolchainPreviousPath STREQUAL ANDROID_STANDALONE_TOOLCHAIN ) - message( FATAL_ERROR "It is not possible to change path to the Android standalone toolchain on subsequent run." ) - endif() - unset( __androidStandaloneToolchainPreviousPath ) - unset( __length ) - endif() - set( ANDROID_STANDALONE_TOOLCHAIN "${ANDROID_STANDALONE_TOOLCHAIN}" CACHE INTERNAL "Path of the Android standalone toolchain" FORCE ) - set( BUILD_WITH_STANDALONE_TOOLCHAIN True ) -else() - list(GET ANDROID_NDK_SEARCH_PATHS 0 ANDROID_NDK_SEARCH_PATH) - message( FATAL_ERROR "Could not find neither Android NDK nor Android standalone toolchain. - You should either set an environment variable: - export ANDROID_NDK=~/my-android-ndk - or - export ANDROID_STANDALONE_TOOLCHAIN=~/my-android-toolchain - or put the toolchain or NDK in the default path: - sudo ln -s ~/my-android-ndk ${ANDROID_NDK_SEARCH_PATH}/android-ndk - sudo ln -s ~/my-android-toolchain ${ANDROID_STANDALONE_TOOLCHAIN_SEARCH_PATH}" ) -endif() - -# android NDK layout -if( BUILD_WITH_ANDROID_NDK ) - if( NOT DEFINED ANDROID_NDK_LAYOUT ) - # try to automatically detect the layout - if( EXISTS "${ANDROID_NDK}/RELEASE.TXT") - set( ANDROID_NDK_LAYOUT "RELEASE" ) - elseif( EXISTS "${ANDROID_NDK}/../../linux-x86/toolchain/" ) - set( ANDROID_NDK_LAYOUT "LINARO" ) - elseif( EXISTS "${ANDROID_NDK}/../../gcc/" ) - set( ANDROID_NDK_LAYOUT "ANDROID" ) - endif() - endif() - set( ANDROID_NDK_LAYOUT "${ANDROID_NDK_LAYOUT}" CACHE STRING "The inner layout of NDK" ) - mark_as_advanced( ANDROID_NDK_LAYOUT ) - if( ANDROID_NDK_LAYOUT STREQUAL "LINARO" ) - set( ANDROID_NDK_HOST_SYSTEM_NAME ${ANDROID_NDK_HOST_SYSTEM_NAME2} ) # only 32-bit at the moment - set( ANDROID_NDK_TOOLCHAINS_PATH "${ANDROID_NDK}/../../${ANDROID_NDK_HOST_SYSTEM_NAME}/toolchain" ) - set( ANDROID_NDK_TOOLCHAINS_SUBPATH "" ) - set( ANDROID_NDK_TOOLCHAINS_SUBPATH2 "" ) - elseif( ANDROID_NDK_LAYOUT STREQUAL "ANDROID" ) - set( ANDROID_NDK_HOST_SYSTEM_NAME ${ANDROID_NDK_HOST_SYSTEM_NAME2} ) # only 32-bit at the moment - set( ANDROID_NDK_TOOLCHAINS_PATH "${ANDROID_NDK}/../../gcc/${ANDROID_NDK_HOST_SYSTEM_NAME}/arm" ) - set( ANDROID_NDK_TOOLCHAINS_SUBPATH "" ) - set( ANDROID_NDK_TOOLCHAINS_SUBPATH2 "" ) - else() # ANDROID_NDK_LAYOUT STREQUAL "RELEASE" - set( ANDROID_NDK_TOOLCHAINS_PATH "${ANDROID_NDK}/toolchains" ) - set( ANDROID_NDK_TOOLCHAINS_SUBPATH "/prebuilt/${ANDROID_NDK_HOST_SYSTEM_NAME}" ) - set( ANDROID_NDK_TOOLCHAINS_SUBPATH2 "/prebuilt/${ANDROID_NDK_HOST_SYSTEM_NAME2}" ) - endif() - get_filename_component( ANDROID_NDK_TOOLCHAINS_PATH "${ANDROID_NDK_TOOLCHAINS_PATH}" ABSOLUTE ) - - # try to detect change of NDK - if( CMAKE_AR ) - string( LENGTH "${ANDROID_NDK_TOOLCHAINS_PATH}" __length ) - string( SUBSTRING "${CMAKE_AR}" 0 ${__length} __androidNdkPreviousPath ) - if( NOT __androidNdkPreviousPath STREQUAL ANDROID_NDK_TOOLCHAINS_PATH ) - message( FATAL_ERROR "It is not possible to change the path to the NDK on subsequent CMake run. You must remove all generated files from your build folder first. - " ) - endif() - unset( __androidNdkPreviousPath ) - unset( __length ) - endif() -endif() - - -# get all the details about standalone toolchain -if( BUILD_WITH_STANDALONE_TOOLCHAIN ) - __DETECT_NATIVE_API_LEVEL( ANDROID_SUPPORTED_NATIVE_API_LEVELS "${ANDROID_STANDALONE_TOOLCHAIN}/sysroot/usr/include/android/api-level.h" ) - set( ANDROID_STANDALONE_TOOLCHAIN_API_LEVEL ${ANDROID_SUPPORTED_NATIVE_API_LEVELS} ) - set( __availableToolchains "standalone" ) - __DETECT_TOOLCHAIN_MACHINE_NAME( __availableToolchainMachines "${ANDROID_STANDALONE_TOOLCHAIN}" ) - if( NOT __availableToolchainMachines ) - message( FATAL_ERROR "Could not determine machine name of your toolchain. Probably your Android standalone toolchain is broken." ) - endif() - if( __availableToolchainMachines MATCHES x86_64 ) - set( __availableToolchainArchs "x86_64" ) - elseif( __availableToolchainMachines MATCHES i686 ) - set( __availableToolchainArchs "x86" ) - elseif( __availableToolchainMachines MATCHES aarch64 ) - set( __availableToolchainArchs "arm64" ) - elseif( __availableToolchainMachines MATCHES arm ) - set( __availableToolchainArchs "arm" ) - elseif( __availableToolchainMachines MATCHES mips64el ) - set( __availableToolchainArchs "mips64" ) - elseif( __availableToolchainMachines MATCHES mipsel ) - set( __availableToolchainArchs "mips" ) - endif() - execute_process( COMMAND "${ANDROID_STANDALONE_TOOLCHAIN}/bin/${__availableToolchainMachines}-gcc${TOOL_OS_SUFFIX}" -dumpversion - OUTPUT_VARIABLE __availableToolchainCompilerVersions OUTPUT_STRIP_TRAILING_WHITESPACE ) - string( REGEX MATCH "[0-9]+[.][0-9]+([.][0-9]+)?" __availableToolchainCompilerVersions "${__availableToolchainCompilerVersions}" ) - if( EXISTS "${ANDROID_STANDALONE_TOOLCHAIN}/bin/clang${TOOL_OS_SUFFIX}" ) - list( APPEND __availableToolchains "standalone-clang" ) - list( APPEND __availableToolchainMachines ${__availableToolchainMachines} ) - list( APPEND __availableToolchainArchs ${__availableToolchainArchs} ) - list( APPEND __availableToolchainCompilerVersions ${__availableToolchainCompilerVersions} ) - endif() -endif() - -macro( __GLOB_NDK_TOOLCHAINS __availableToolchainsVar __availableToolchainsLst __toolchain_subpath ) - foreach( __toolchain ${${__availableToolchainsLst}} ) - if( "${__toolchain}" MATCHES "-clang3[.][0-9]$" AND NOT EXISTS "${ANDROID_NDK_TOOLCHAINS_PATH}/${__toolchain}${__toolchain_subpath}" ) - SET( __toolchainVersionRegex "^TOOLCHAIN_VERSION[\t ]+:=[\t ]+(.*)$" ) - FILE( STRINGS "${ANDROID_NDK_TOOLCHAINS_PATH}/${__toolchain}/setup.mk" __toolchainVersionStr REGEX "${__toolchainVersionRegex}" ) - if( __toolchainVersionStr ) - string( REGEX REPLACE "${__toolchainVersionRegex}" "\\1" __toolchainVersionStr "${__toolchainVersionStr}" ) - string( REGEX REPLACE "-clang3[.][0-9]$" "-${__toolchainVersionStr}" __gcc_toolchain "${__toolchain}" ) - else() - string( REGEX REPLACE "-clang3[.][0-9]$" "-4.6" __gcc_toolchain "${__toolchain}" ) - endif() - unset( __toolchainVersionStr ) - unset( __toolchainVersionRegex ) - else() - set( __gcc_toolchain "${__toolchain}" ) - endif() - __DETECT_TOOLCHAIN_MACHINE_NAME( __machine "${ANDROID_NDK_TOOLCHAINS_PATH}/${__gcc_toolchain}${__toolchain_subpath}" ) - if( __machine ) - string( REGEX MATCH "[0-9]+[.][0-9]+([.][0-9x]+)?$" __version "${__gcc_toolchain}" ) - if( __machine MATCHES x86_64 ) - set( __arch "x86_64" ) - elseif( __machine MATCHES i686 ) - set( __arch "x86" ) - elseif( __machine MATCHES aarch64 ) - set( __arch "arm64" ) - elseif( __machine MATCHES arm ) - set( __arch "arm" ) - elseif( __machine MATCHES mips64el ) - set( __arch "mips64" ) - elseif( __machine MATCHES mipsel ) - set( __arch "mips" ) - else() - set( __arch "" ) - endif() - #message("machine: !${__machine}!\narch: !${__arch}!\nversion: !${__version}!\ntoolchain: !${__toolchain}!\n") - if (__arch) - list( APPEND __availableToolchainMachines "${__machine}" ) - list( APPEND __availableToolchainArchs "${__arch}" ) - list( APPEND __availableToolchainCompilerVersions "${__version}" ) - list( APPEND ${__availableToolchainsVar} "${__toolchain}" ) - endif() - endif() - unset( __gcc_toolchain ) - endforeach() -endmacro() - -# get all the details about NDK -if( BUILD_WITH_ANDROID_NDK ) - file( GLOB ANDROID_SUPPORTED_NATIVE_API_LEVELS RELATIVE "${ANDROID_NDK}/platforms" "${ANDROID_NDK}/platforms/android-*" ) - string( REPLACE "android-" "" ANDROID_SUPPORTED_NATIVE_API_LEVELS "${ANDROID_SUPPORTED_NATIVE_API_LEVELS}" ) - set( __availableToolchains "" ) - set( __availableToolchainMachines "" ) - set( __availableToolchainArchs "" ) - set( __availableToolchainCompilerVersions "" ) - if( ANDROID_TOOLCHAIN_NAME AND EXISTS "${ANDROID_NDK_TOOLCHAINS_PATH}/${ANDROID_TOOLCHAIN_NAME}/" ) - # do not go through all toolchains if we know the name - set( __availableToolchainsLst "${ANDROID_TOOLCHAIN_NAME}" ) - __GLOB_NDK_TOOLCHAINS( __availableToolchains __availableToolchainsLst "${ANDROID_NDK_TOOLCHAINS_SUBPATH}" ) - if( NOT __availableToolchains AND NOT ANDROID_NDK_TOOLCHAINS_SUBPATH STREQUAL ANDROID_NDK_TOOLCHAINS_SUBPATH2 ) - __GLOB_NDK_TOOLCHAINS( __availableToolchains __availableToolchainsLst "${ANDROID_NDK_TOOLCHAINS_SUBPATH2}" ) - if( __availableToolchains ) - set( ANDROID_NDK_TOOLCHAINS_SUBPATH ${ANDROID_NDK_TOOLCHAINS_SUBPATH2} ) - endif() - endif() - endif() - if( NOT __availableToolchains ) - file( GLOB __availableToolchainsLst RELATIVE "${ANDROID_NDK_TOOLCHAINS_PATH}" "${ANDROID_NDK_TOOLCHAINS_PATH}/*" ) - if( __availableToolchainsLst ) - list(SORT __availableToolchainsLst) # we need clang to go after gcc - endif() - __LIST_FILTER( __availableToolchainsLst "^[.]" ) - __LIST_FILTER( __availableToolchainsLst "llvm" ) - __LIST_FILTER( __availableToolchainsLst "renderscript" ) - __GLOB_NDK_TOOLCHAINS( __availableToolchains __availableToolchainsLst "${ANDROID_NDK_TOOLCHAINS_SUBPATH}" ) - if( NOT __availableToolchains AND NOT ANDROID_NDK_TOOLCHAINS_SUBPATH STREQUAL ANDROID_NDK_TOOLCHAINS_SUBPATH2 ) - __GLOB_NDK_TOOLCHAINS( __availableToolchains __availableToolchainsLst "${ANDROID_NDK_TOOLCHAINS_SUBPATH2}" ) - if( __availableToolchains ) - set( ANDROID_NDK_TOOLCHAINS_SUBPATH ${ANDROID_NDK_TOOLCHAINS_SUBPATH2} ) - endif() - endif() - endif() - if( NOT __availableToolchains ) - message( FATAL_ERROR "Could not find any working toolchain in the NDK. Probably your Android NDK is broken." ) - endif() -endif() - -# build list of available ABIs -set( ANDROID_SUPPORTED_ABIS "" ) -set( __uniqToolchainArchNames ${__availableToolchainArchs} ) -list( REMOVE_DUPLICATES __uniqToolchainArchNames ) -list( SORT __uniqToolchainArchNames ) -foreach( __arch ${__uniqToolchainArchNames} ) - list( APPEND ANDROID_SUPPORTED_ABIS ${ANDROID_SUPPORTED_ABIS_${__arch}} ) -endforeach() -unset( __uniqToolchainArchNames ) -if( NOT ANDROID_SUPPORTED_ABIS ) - message( FATAL_ERROR "No one of known Android ABIs is supported by this cmake toolchain." ) -endif() - -# choose target ABI -__INIT_VARIABLE( ANDROID_ABI VALUES ${ANDROID_SUPPORTED_ABIS} ) -# verify that target ABI is supported -list( FIND ANDROID_SUPPORTED_ABIS "${ANDROID_ABI}" __androidAbiIdx ) -if( __androidAbiIdx EQUAL -1 ) - string( REPLACE ";" "\", \"" PRINTABLE_ANDROID_SUPPORTED_ABIS "${ANDROID_SUPPORTED_ABIS}" ) - message( FATAL_ERROR "Specified ANDROID_ABI = \"${ANDROID_ABI}\" is not supported by this cmake toolchain or your NDK/toolchain. - Supported values are: \"${PRINTABLE_ANDROID_SUPPORTED_ABIS}\" - " ) -endif() -unset( __androidAbiIdx ) - -# set target ABI options -if( ANDROID_ABI STREQUAL "x86" ) - set( X86 true ) - set( ANDROID_NDK_ABI_NAME "x86" ) - set( ANDROID_ARCH_NAME "x86" ) - set( ANDROID_LLVM_TRIPLE "i686-none-linux-android" ) - set( CMAKE_SYSTEM_PROCESSOR "i686" ) -elseif( ANDROID_ABI STREQUAL "x86_64" ) - set( X86 true ) - set( X86_64 true ) - set( ANDROID_NDK_ABI_NAME "x86_64" ) - set( ANDROID_ARCH_NAME "x86_64" ) - set( CMAKE_SYSTEM_PROCESSOR "x86_64" ) - set( ANDROID_LLVM_TRIPLE "x86_64-none-linux-android" ) -elseif( ANDROID_ABI STREQUAL "mips64" ) - set( MIPS64 true ) - set( ANDROID_NDK_ABI_NAME "mips64" ) - set( ANDROID_ARCH_NAME "mips64" ) - set( ANDROID_LLVM_TRIPLE "mips64el-none-linux-android" ) - set( CMAKE_SYSTEM_PROCESSOR "mips64" ) -elseif( ANDROID_ABI STREQUAL "mips" ) - set( MIPS true ) - set( ANDROID_NDK_ABI_NAME "mips" ) - set( ANDROID_ARCH_NAME "mips" ) - set( ANDROID_LLVM_TRIPLE "mipsel-none-linux-android" ) - set( CMAKE_SYSTEM_PROCESSOR "mips" ) -elseif( ANDROID_ABI STREQUAL "arm64-v8a" ) - set( ARM64_V8A true ) - set( ANDROID_NDK_ABI_NAME "arm64-v8a" ) - set( ANDROID_ARCH_NAME "arm64" ) - set( ANDROID_LLVM_TRIPLE "aarch64-none-linux-android" ) - set( CMAKE_SYSTEM_PROCESSOR "aarch64" ) - set( VFPV3 true ) - set( NEON true ) -elseif( ANDROID_ABI STREQUAL "armeabi" ) - set( ARMEABI true ) - set( ANDROID_NDK_ABI_NAME "armeabi" ) - set( ANDROID_ARCH_NAME "arm" ) - set( ANDROID_LLVM_TRIPLE "armv5te-none-linux-androideabi" ) - set( CMAKE_SYSTEM_PROCESSOR "armv5te" ) -elseif( ANDROID_ABI STREQUAL "armeabi-v6 with VFP" ) - set( ARMEABI_V6 true ) - set( ANDROID_NDK_ABI_NAME "armeabi" ) - set( ANDROID_ARCH_NAME "arm" ) - set( ANDROID_LLVM_TRIPLE "armv5te-none-linux-androideabi" ) - set( CMAKE_SYSTEM_PROCESSOR "armv6" ) - # need always fallback to older platform - set( ARMEABI true ) -elseif( ANDROID_ABI STREQUAL "armeabi-v7a") - set( ARMEABI_V7A true ) - set( ANDROID_NDK_ABI_NAME "armeabi-v7a" ) - set( ANDROID_ARCH_NAME "arm" ) - set( ANDROID_LLVM_TRIPLE "armv7-none-linux-androideabi" ) - set( CMAKE_SYSTEM_PROCESSOR "armv7-a" ) -elseif( ANDROID_ABI STREQUAL "armeabi-v7a with VFPV3" ) - set( ARMEABI_V7A true ) - set( ANDROID_NDK_ABI_NAME "armeabi-v7a" ) - set( ANDROID_ARCH_NAME "arm" ) - set( ANDROID_LLVM_TRIPLE "armv7-none-linux-androideabi" ) - set( CMAKE_SYSTEM_PROCESSOR "armv7-a" ) - set( VFPV3 true ) -elseif( ANDROID_ABI STREQUAL "armeabi-v7a with NEON" ) - set( ARMEABI_V7A true ) - set( ANDROID_NDK_ABI_NAME "armeabi-v7a" ) - set( ANDROID_ARCH_NAME "arm" ) - set( ANDROID_LLVM_TRIPLE "armv7-none-linux-androideabi" ) - set( CMAKE_SYSTEM_PROCESSOR "armv7-a" ) - set( VFPV3 true ) - set( NEON true ) -else() - message( SEND_ERROR "Unknown ANDROID_ABI=\"${ANDROID_ABI}\" is specified." ) -endif() - -if( CMAKE_BINARY_DIR AND EXISTS "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeSystem.cmake" ) - # really dirty hack - # it is not possible to change CMAKE_SYSTEM_PROCESSOR after the first run... - file( APPEND "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeSystem.cmake" "SET(CMAKE_SYSTEM_PROCESSOR \"${CMAKE_SYSTEM_PROCESSOR}\")\n" ) -endif() - -if( ANDROID_ARCH_NAME STREQUAL "arm" AND NOT ARMEABI_V6 ) - __INIT_VARIABLE( ANDROID_FORCE_ARM_BUILD VALUES OFF ) - set( ANDROID_FORCE_ARM_BUILD ${ANDROID_FORCE_ARM_BUILD} CACHE BOOL "Use 32-bit ARM instructions instead of Thumb-1" FORCE ) - mark_as_advanced( ANDROID_FORCE_ARM_BUILD ) -else() - unset( ANDROID_FORCE_ARM_BUILD CACHE ) -endif() - -# choose toolchain -if( ANDROID_TOOLCHAIN_NAME ) - list( FIND __availableToolchains "${ANDROID_TOOLCHAIN_NAME}" __toolchainIdx ) - if( __toolchainIdx EQUAL -1 ) - list( SORT __availableToolchains ) - string( REPLACE ";" "\n * " toolchains_list "${__availableToolchains}" ) - set( toolchains_list " * ${toolchains_list}") - message( FATAL_ERROR "Specified toolchain \"${ANDROID_TOOLCHAIN_NAME}\" is missing in your NDK or broken. Please verify that your NDK is working or select another compiler toolchain. -To configure the toolchain set CMake variable ANDROID_TOOLCHAIN_NAME to one of the following values:\n${toolchains_list}\n" ) - endif() - list( GET __availableToolchainArchs ${__toolchainIdx} __toolchainArch ) - if( NOT __toolchainArch STREQUAL ANDROID_ARCH_NAME ) - message( SEND_ERROR "Selected toolchain \"${ANDROID_TOOLCHAIN_NAME}\" is not able to compile binaries for the \"${ANDROID_ARCH_NAME}\" platform." ) - endif() -else() - set( __toolchainIdx -1 ) - set( __applicableToolchains "" ) - set( __toolchainMaxVersion "0.0.0" ) - list( LENGTH __availableToolchains __availableToolchainsCount ) - math( EXPR __availableToolchainsCount "${__availableToolchainsCount}-1" ) - foreach( __idx RANGE ${__availableToolchainsCount} ) - list( GET __availableToolchainArchs ${__idx} __toolchainArch ) - if( __toolchainArch STREQUAL ANDROID_ARCH_NAME ) - list( GET __availableToolchainCompilerVersions ${__idx} __toolchainVersion ) - string( REPLACE "x" "99" __toolchainVersion "${__toolchainVersion}") - if( __toolchainVersion VERSION_GREATER __toolchainMaxVersion ) - set( __toolchainMaxVersion "${__toolchainVersion}" ) - set( __toolchainIdx ${__idx} ) - endif() - endif() - endforeach() - unset( __availableToolchainsCount ) - unset( __toolchainMaxVersion ) - unset( __toolchainVersion ) -endif() -unset( __toolchainArch ) -if( __toolchainIdx EQUAL -1 ) - message( FATAL_ERROR "No one of available compiler toolchains is able to compile for ${ANDROID_ARCH_NAME} platform." ) -endif() -list( GET __availableToolchains ${__toolchainIdx} ANDROID_TOOLCHAIN_NAME ) -list( GET __availableToolchainMachines ${__toolchainIdx} ANDROID_TOOLCHAIN_MACHINE_NAME ) -list( GET __availableToolchainCompilerVersions ${__toolchainIdx} ANDROID_COMPILER_VERSION ) - -unset( __toolchainIdx ) -unset( __availableToolchains ) -unset( __availableToolchainMachines ) -unset( __availableToolchainArchs ) -unset( __availableToolchainCompilerVersions ) - -# choose native API level -__INIT_VARIABLE( ANDROID_NATIVE_API_LEVEL ENV_ANDROID_NATIVE_API_LEVEL ANDROID_API_LEVEL ENV_ANDROID_API_LEVEL ANDROID_STANDALONE_TOOLCHAIN_API_LEVEL ANDROID_DEFAULT_NDK_API_LEVEL_${ANDROID_ARCH_NAME} ANDROID_DEFAULT_NDK_API_LEVEL ) -string( REPLACE "android-" "" ANDROID_NATIVE_API_LEVEL "${ANDROID_NATIVE_API_LEVEL}" ) -string( STRIP "${ANDROID_NATIVE_API_LEVEL}" ANDROID_NATIVE_API_LEVEL ) -# adjust API level -set( __real_api_level ${ANDROID_DEFAULT_NDK_API_LEVEL_${ANDROID_ARCH_NAME}} ) -foreach( __level ${ANDROID_SUPPORTED_NATIVE_API_LEVELS} ) - if( (__level LESS ANDROID_NATIVE_API_LEVEL OR __level STREQUAL ANDROID_NATIVE_API_LEVEL) AND NOT __level LESS __real_api_level ) - set( __real_api_level ${__level} ) - endif() -endforeach() -if( __real_api_level AND NOT ANDROID_NATIVE_API_LEVEL STREQUAL __real_api_level ) - message( STATUS "Adjusting Android API level 'android-${ANDROID_NATIVE_API_LEVEL}' to 'android-${__real_api_level}'") - set( ANDROID_NATIVE_API_LEVEL ${__real_api_level} ) -endif() -unset(__real_api_level) -# validate -list( FIND ANDROID_SUPPORTED_NATIVE_API_LEVELS "${ANDROID_NATIVE_API_LEVEL}" __levelIdx ) -if( __levelIdx EQUAL -1 ) - message( SEND_ERROR "Specified Android native API level 'android-${ANDROID_NATIVE_API_LEVEL}' is not supported by your NDK/toolchain." ) -else() - if( BUILD_WITH_ANDROID_NDK ) - __DETECT_NATIVE_API_LEVEL( __realApiLevel "${ANDROID_NDK}/platforms/android-${ANDROID_NATIVE_API_LEVEL}/arch-${ANDROID_ARCH_NAME}/usr/include/android/api-level.h" ) - if( NOT __realApiLevel EQUAL ANDROID_NATIVE_API_LEVEL AND NOT __realApiLevel GREATER 9000 ) - message( SEND_ERROR "Specified Android API level (${ANDROID_NATIVE_API_LEVEL}) does not match to the level found (${__realApiLevel}). Probably your copy of NDK is broken." ) - endif() - unset( __realApiLevel ) - endif() - set( ANDROID_NATIVE_API_LEVEL "${ANDROID_NATIVE_API_LEVEL}" CACHE STRING "Android API level for native code" FORCE ) - set( CMAKE_ANDROID_API ${ANDROID_NATIVE_API_LEVEL} ) - if( CMAKE_VERSION VERSION_GREATER "2.8" ) - list( SORT ANDROID_SUPPORTED_NATIVE_API_LEVELS ) - set_property( CACHE ANDROID_NATIVE_API_LEVEL PROPERTY STRINGS ${ANDROID_SUPPORTED_NATIVE_API_LEVELS} ) - endif() -endif() -unset( __levelIdx ) - - -# remember target ABI -set( ANDROID_ABI "${ANDROID_ABI}" CACHE STRING "The target ABI for Android. If arm, then armeabi-v7a is recommended for hardware floating point." FORCE ) -if( CMAKE_VERSION VERSION_GREATER "2.8" ) - list( SORT ANDROID_SUPPORTED_ABIS_${ANDROID_ARCH_NAME} ) - set_property( CACHE ANDROID_ABI PROPERTY STRINGS ${ANDROID_SUPPORTED_ABIS_${ANDROID_ARCH_NAME}} ) -endif() - - -# runtime choice (STL, rtti, exceptions) -if( NOT ANDROID_STL ) - set( ANDROID_STL gnustl_static ) -endif() -set( ANDROID_STL "${ANDROID_STL}" CACHE STRING "C++ runtime" ) -set( ANDROID_STL_FORCE_FEATURES ON CACHE BOOL "automatically configure rtti and exceptions support based on C++ runtime" ) -mark_as_advanced( ANDROID_STL ANDROID_STL_FORCE_FEATURES ) - -if( BUILD_WITH_ANDROID_NDK ) - if( NOT "${ANDROID_STL}" MATCHES "^(none|system|system_re|(gabi\\+\\+|stlport|gnustl|libc\\+\\+)_(static|shared))$") - message( FATAL_ERROR "ANDROID_STL is set to invalid value \"${ANDROID_STL}\". -The possible values are: - none -> Do not configure the runtime. - system -> Use the default minimal system C++ runtime library. - system_re -> Same as system but with rtti and exceptions. - gabi++_static -> Use the GAbi++ runtime as a static library. - gabi++_shared -> Use the GAbi++ runtime as a shared library. - stlport_static -> Use the STLport runtime as a static library. - stlport_shared -> Use the STLport runtime as a shared library. - gnustl_static -> (default) Use the GNU STL as a static library. - gnustl_shared -> Use the GNU STL as a shared library. - libc++_static -> Use the LLVM C++ Standard Library as a static library. - libc++_shared -> Use the LLVM C++ Standard Library as a shared library. -" ) - endif() -elseif( BUILD_WITH_STANDALONE_TOOLCHAIN ) - if( NOT "${ANDROID_STL}" MATCHES "^(none|gnustl_static|gnustl_shared)$") - message( FATAL_ERROR "ANDROID_STL is set to invalid value \"${ANDROID_STL}\". -The possible values are: - none -> Do not configure the runtime. - gnustl_static -> (default) Use the GNU STL as a static library. - gnustl_shared -> Use the GNU STL as a shared library. -" ) - endif() -endif() - -unset( ANDROID_RTTI ) -unset( ANDROID_EXCEPTIONS ) -unset( ANDROID_STL_INCLUDE_DIRS ) -unset( __libstl ) -unset( __libsupcxx ) - -if( NOT _CMAKE_IN_TRY_COMPILE AND ANDROID_NDK_RELEASE STREQUAL "r7b" AND ARMEABI_V7A AND NOT VFPV3 AND ANDROID_STL MATCHES "gnustl" ) - message( WARNING "The GNU STL armeabi-v7a binaries from NDK r7b can crash non-NEON devices. The files provided with NDK r7b were not configured properly, resulting in crashes on Tegra2-based devices and others when trying to use certain floating-point functions (e.g., cosf, sinf, expf). -You are strongly recommended to switch to another NDK release. -" ) -endif() - -if( NOT _CMAKE_IN_TRY_COMPILE AND X86 AND ANDROID_STL MATCHES "gnustl" AND ANDROID_NDK_RELEASE STREQUAL "r6" ) - message( WARNING "The x86 system header file from NDK r6 has incorrect definition for ptrdiff_t. You are recommended to upgrade to a newer NDK release or manually patch the header: -See https://android.googlesource.com/platform/development.git f907f4f9d4e56ccc8093df6fee54454b8bcab6c2 - diff --git a/ndk/platforms/android-9/arch-x86/include/machine/_types.h b/ndk/platforms/android-9/arch-x86/include/machine/_types.h - index 5e28c64..65892a1 100644 - --- a/ndk/platforms/android-9/arch-x86/include/machine/_types.h - +++ b/ndk/platforms/android-9/arch-x86/include/machine/_types.h - @@ -51,7 +51,11 @@ typedef long int ssize_t; - #endif - #ifndef _PTRDIFF_T - #define _PTRDIFF_T - -typedef long ptrdiff_t; - +# ifdef __ANDROID__ - + typedef int ptrdiff_t; - +# else - + typedef long ptrdiff_t; - +# endif - #endif -" ) -endif() - - -# setup paths and STL for standalone toolchain -if( BUILD_WITH_STANDALONE_TOOLCHAIN ) - set( ANDROID_TOOLCHAIN_ROOT "${ANDROID_STANDALONE_TOOLCHAIN}" ) - set( ANDROID_CLANG_TOOLCHAIN_ROOT "${ANDROID_STANDALONE_TOOLCHAIN}" ) - set( ANDROID_SYSROOT "${ANDROID_STANDALONE_TOOLCHAIN}/sysroot" ) - - if( NOT ANDROID_STL STREQUAL "none" ) - set( ANDROID_STL_INCLUDE_DIRS "${ANDROID_STANDALONE_TOOLCHAIN}/include/c++/${ANDROID_COMPILER_VERSION}" ) - if( NOT EXISTS "${ANDROID_STL_INCLUDE_DIRS}" ) - # old location ( pre r8c ) - set( ANDROID_STL_INCLUDE_DIRS "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/include/c++/${ANDROID_COMPILER_VERSION}" ) - endif() - if( ARMEABI_V7A AND EXISTS "${ANDROID_STL_INCLUDE_DIRS}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/${CMAKE_SYSTEM_PROCESSOR}/bits" ) - list( APPEND ANDROID_STL_INCLUDE_DIRS "${ANDROID_STL_INCLUDE_DIRS}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/${CMAKE_SYSTEM_PROCESSOR}" ) - elseif( ARMEABI AND NOT ANDROID_FORCE_ARM_BUILD AND EXISTS "${ANDROID_STL_INCLUDE_DIRS}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/thumb/bits" ) - list( APPEND ANDROID_STL_INCLUDE_DIRS "${ANDROID_STL_INCLUDE_DIRS}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/thumb" ) - else() - list( APPEND ANDROID_STL_INCLUDE_DIRS "${ANDROID_STL_INCLUDE_DIRS}/${ANDROID_TOOLCHAIN_MACHINE_NAME}" ) - endif() - # always search static GNU STL to get the location of libsupc++.a - if( ARMEABI_V7A AND NOT ANDROID_FORCE_ARM_BUILD AND EXISTS "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/${CMAKE_SYSTEM_PROCESSOR}/thumb/libstdc++.a" ) - set( __libstl "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/${CMAKE_SYSTEM_PROCESSOR}/thumb" ) - elseif( ARMEABI_V7A AND EXISTS "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/${CMAKE_SYSTEM_PROCESSOR}/libstdc++.a" ) - set( __libstl "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/${CMAKE_SYSTEM_PROCESSOR}" ) - elseif( ARMEABI AND NOT ANDROID_FORCE_ARM_BUILD AND EXISTS "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/thumb/libstdc++.a" ) - set( __libstl "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/thumb" ) - elseif( EXISTS "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/libstdc++.a" ) - set( __libstl "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib" ) - endif() - if( __libstl ) - set( __libsupcxx "${__libstl}/libsupc++.a" ) - set( __libstl "${__libstl}/libstdc++.a" ) - endif() - if( NOT EXISTS "${__libsupcxx}" ) - message( FATAL_ERROR "The required libstdsupc++.a is missing in your standalone toolchain. - Usually it happens because of bug in make-standalone-toolchain.sh script from NDK r7, r7b and r7c. - You need to either upgrade to newer NDK or manually copy - $ANDROID_NDK/sources/cxx-stl/gnu-libstdc++/libs/${ANDROID_NDK_ABI_NAME}/libsupc++.a - to - ${__libsupcxx} - " ) - endif() - if( ANDROID_STL STREQUAL "gnustl_shared" ) - if( ARMEABI_V7A AND EXISTS "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/${CMAKE_SYSTEM_PROCESSOR}/libgnustl_shared.so" ) - set( __libstl "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/${CMAKE_SYSTEM_PROCESSOR}/libgnustl_shared.so" ) - elseif( ARMEABI AND NOT ANDROID_FORCE_ARM_BUILD AND EXISTS "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/thumb/libgnustl_shared.so" ) - set( __libstl "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/thumb/libgnustl_shared.so" ) - elseif( EXISTS "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/libgnustl_shared.so" ) - set( __libstl "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/libgnustl_shared.so" ) - endif() - endif() - if( ANDROID_STL STREQUAL "c++_shared" ) - if( ARMEABI_V7A AND EXISTS "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/${CMAKE_SYSTEM_PROCESSOR}/libc++_shared.so" ) - set( __libstl "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/${CMAKE_SYSTEM_PROCESSOR}/libc++_shared.so" ) - elseif( ARMEABI AND NOT ANDROID_FORCE_ARM_BUILD AND EXISTS "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/thumb/libc++_shared.so" ) - set( __libstl "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/thumb/libc++_shared.so" ) - elseif( EXISTS "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/libc++_shared.so" ) - set( __libstl "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/libc++_shared.so" ) - endif() - endif() - endif() -endif() - -# clang -if( "${ANDROID_TOOLCHAIN_NAME}" STREQUAL "standalone-clang" ) - set( ANDROID_COMPILER_IS_CLANG 1 ) - execute_process( COMMAND "${ANDROID_CLANG_TOOLCHAIN_ROOT}/bin/clang${TOOL_OS_SUFFIX}" --version OUTPUT_VARIABLE ANDROID_CLANG_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE ) - string( REGEX MATCH "[0-9]+[.][0-9]+" ANDROID_CLANG_VERSION "${ANDROID_CLANG_VERSION}") -elseif( "${ANDROID_TOOLCHAIN_NAME}" MATCHES "-clang3[.][0-9]?$" ) - string( REGEX MATCH "3[.][0-9]$" ANDROID_CLANG_VERSION "${ANDROID_TOOLCHAIN_NAME}") - string( REGEX REPLACE "-clang${ANDROID_CLANG_VERSION}$" "-${ANDROID_COMPILER_VERSION}" ANDROID_GCC_TOOLCHAIN_NAME "${ANDROID_TOOLCHAIN_NAME}" ) - if( NOT EXISTS "${ANDROID_NDK_TOOLCHAINS_PATH}/llvm-${ANDROID_CLANG_VERSION}${ANDROID_NDK_TOOLCHAINS_SUBPATH}/bin/clang${TOOL_OS_SUFFIX}" ) - message( FATAL_ERROR "Could not find the Clang compiler driver" ) - endif() - set( ANDROID_COMPILER_IS_CLANG 1 ) - set( ANDROID_CLANG_TOOLCHAIN_ROOT "${ANDROID_NDK_TOOLCHAINS_PATH}/llvm-${ANDROID_CLANG_VERSION}${ANDROID_NDK_TOOLCHAINS_SUBPATH}" ) -else() - set( ANDROID_GCC_TOOLCHAIN_NAME "${ANDROID_TOOLCHAIN_NAME}" ) - unset( ANDROID_COMPILER_IS_CLANG CACHE ) -endif() - -string( REPLACE "." "" _clang_name "clang${ANDROID_CLANG_VERSION}" ) -if( NOT EXISTS "${ANDROID_CLANG_TOOLCHAIN_ROOT}/bin/${_clang_name}${TOOL_OS_SUFFIX}" ) - set( _clang_name "clang" ) -endif() - - -# setup paths and STL for NDK -if( BUILD_WITH_ANDROID_NDK ) - set( ANDROID_TOOLCHAIN_ROOT "${ANDROID_NDK_TOOLCHAINS_PATH}/${ANDROID_GCC_TOOLCHAIN_NAME}${ANDROID_NDK_TOOLCHAINS_SUBPATH}" ) - set( ANDROID_SYSROOT "${ANDROID_NDK}/platforms/android-${ANDROID_NATIVE_API_LEVEL}/arch-${ANDROID_ARCH_NAME}" ) - - if( ANDROID_STL STREQUAL "none" ) - # do nothing - elseif( ANDROID_STL STREQUAL "system" ) - set( ANDROID_RTTI OFF ) - set( ANDROID_EXCEPTIONS OFF ) - set( ANDROID_STL_INCLUDE_DIRS "${ANDROID_NDK}/sources/cxx-stl/system/include" ) - elseif( ANDROID_STL STREQUAL "system_re" ) - set( ANDROID_RTTI ON ) - set( ANDROID_EXCEPTIONS ON ) - set( ANDROID_STL_INCLUDE_DIRS "${ANDROID_NDK}/sources/cxx-stl/system/include" ) - elseif( ANDROID_STL MATCHES "gabi" ) - if( ANDROID_NDK_RELEASE_NUM LESS 7000 ) # before r7 - message( FATAL_ERROR "gabi++ is not available in your NDK. You have to upgrade to NDK r7 or newer to use gabi++.") - endif() - set( ANDROID_RTTI ON ) - set( ANDROID_EXCEPTIONS OFF ) - set( ANDROID_STL_INCLUDE_DIRS "${ANDROID_NDK}/sources/cxx-stl/gabi++/include" ) - set( __libstl "${ANDROID_NDK}/sources/cxx-stl/gabi++/libs/${ANDROID_NDK_ABI_NAME}/libgabi++_static.a" ) - elseif( ANDROID_STL MATCHES "stlport" ) - if( NOT ANDROID_NDK_RELEASE_NUM LESS 8004 ) # before r8d - set( ANDROID_EXCEPTIONS ON ) - else() - set( ANDROID_EXCEPTIONS OFF ) - endif() - if( ANDROID_NDK_RELEASE_NUM LESS 7000 ) # before r7 - set( ANDROID_RTTI OFF ) - else() - set( ANDROID_RTTI ON ) - endif() - set( ANDROID_STL_INCLUDE_DIRS "${ANDROID_NDK}/sources/cxx-stl/stlport/stlport" ) - set( __libstl "${ANDROID_NDK}/sources/cxx-stl/stlport/libs/${ANDROID_NDK_ABI_NAME}/libstlport_static.a" ) - elseif( ANDROID_STL MATCHES "gnustl" ) - set( ANDROID_EXCEPTIONS ON ) - set( ANDROID_RTTI ON ) - if( EXISTS "${ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++/${ANDROID_COMPILER_VERSION}" ) - if( ARMEABI_V7A AND ANDROID_COMPILER_VERSION VERSION_EQUAL "4.7" AND ANDROID_NDK_RELEASE STREQUAL "r8d" ) - # gnustl binary for 4.7 compiler is buggy :( - # TODO: look for right fix - set( __libstl "${ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++/4.6" ) - else() - set( __libstl "${ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++/${ANDROID_COMPILER_VERSION}" ) - endif() - else() - set( __libstl "${ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++" ) - endif() - set( ANDROID_STL_INCLUDE_DIRS "${__libstl}/include" "${__libstl}/libs/${ANDROID_NDK_ABI_NAME}/include" "${__libstl}/include/backward" ) - if( EXISTS "${__libstl}/libs/${ANDROID_NDK_ABI_NAME}/libgnustl_static.a" ) - set( __libstl "${__libstl}/libs/${ANDROID_NDK_ABI_NAME}/libgnustl_static.a" ) - else() - set( __libstl "${__libstl}/libs/${ANDROID_NDK_ABI_NAME}/libstdc++.a" ) - endif() - elseif( ANDROID_STL MATCHES "libc\\+\\+" ) - set( ANDROID_EXCEPTIONS ON ) - set( ANDROID_RTTI ON ) - set( __libstl "${ANDROID_NDK}/sources/cxx-stl/llvm-libc++/libs/${ANDROID_NDK_ABI_NAME}/libc++_static.a" ) - set( ANDROID_STL_INCLUDE_DIRS "${ANDROID_NDK}/sources/cxx-stl/llvm-libc++/libcxx/include/" "${ANDROID_NDK}/sources/cxx-stl/llvm-libc++abi/libcxxabi/include" ) - else() - message( FATAL_ERROR "Unknown runtime: ${ANDROID_STL}" ) - endif() - # find libsupc++.a - rtti & exceptions - if( ANDROID_STL STREQUAL "system_re" OR ANDROID_STL MATCHES "gnustl" ) - set( __libsupcxx "${ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++/${ANDROID_COMPILER_VERSION}/libs/${ANDROID_NDK_ABI_NAME}/libsupc++.a" ) # r8b or newer - if( NOT EXISTS "${__libsupcxx}" ) - set( __libsupcxx "${ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++/libs/${ANDROID_NDK_ABI_NAME}/libsupc++.a" ) # r7-r8 - endif() - if( NOT EXISTS "${__libsupcxx}" ) # before r7 - if( ARMEABI_V7A ) - if( ANDROID_FORCE_ARM_BUILD ) - set( __libsupcxx "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/${CMAKE_SYSTEM_PROCESSOR}/libsupc++.a" ) - else() - set( __libsupcxx "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/${CMAKE_SYSTEM_PROCESSOR}/thumb/libsupc++.a" ) - endif() - elseif( ARMEABI AND NOT ANDROID_FORCE_ARM_BUILD ) - set( __libsupcxx "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/thumb/libsupc++.a" ) - else() - set( __libsupcxx "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/libsupc++.a" ) - endif() - endif() - if( NOT EXISTS "${__libsupcxx}") - message( ERROR "Could not find libsupc++.a for a chosen platform. Either your NDK is not supported or is broken.") - endif() - endif() -endif() - - -# case of shared STL linkage -if( ANDROID_STL MATCHES "shared" AND DEFINED __libstl ) - string( REPLACE "_static.a" "_shared.so" __libstl "${__libstl}" ) - # TODO: check if .so file exists before the renaming -endif() - - -# ccache support -__INIT_VARIABLE( _ndk_ccache NDK_CCACHE ENV_NDK_CCACHE ) -if( _ndk_ccache ) - if( DEFINED NDK_CCACHE AND NOT EXISTS NDK_CCACHE ) - unset( NDK_CCACHE CACHE ) - endif() - find_program( NDK_CCACHE "${_ndk_ccache}" DOC "The path to ccache binary") -else() - unset( NDK_CCACHE CACHE ) -endif() -unset( _ndk_ccache ) - - -# setup the cross-compiler -if( NOT CMAKE_C_COMPILER ) - if( NDK_CCACHE AND NOT ANDROID_SYSROOT MATCHES "[ ;\"]" ) - set( CMAKE_C_COMPILER "${NDK_CCACHE}" CACHE PATH "ccache as C compiler" ) - set( CMAKE_CXX_COMPILER "${NDK_CCACHE}" CACHE PATH "ccache as C++ compiler" ) - if( ANDROID_COMPILER_IS_CLANG ) - set( CMAKE_C_COMPILER_ARG1 "${ANDROID_CLANG_TOOLCHAIN_ROOT}/bin/${_clang_name}${TOOL_OS_SUFFIX}" CACHE PATH "C compiler") - set( CMAKE_CXX_COMPILER_ARG1 "${ANDROID_CLANG_TOOLCHAIN_ROOT}/bin/${_clang_name}++${TOOL_OS_SUFFIX}" CACHE PATH "C++ compiler") - else() - set( CMAKE_C_COMPILER_ARG1 "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-gcc${TOOL_OS_SUFFIX}" CACHE PATH "C compiler") - set( CMAKE_CXX_COMPILER_ARG1 "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-g++${TOOL_OS_SUFFIX}" CACHE PATH "C++ compiler") - endif() - else() - if( ANDROID_COMPILER_IS_CLANG ) - set( CMAKE_C_COMPILER "${ANDROID_CLANG_TOOLCHAIN_ROOT}/bin/${_clang_name}${TOOL_OS_SUFFIX}" CACHE PATH "C compiler") - set( CMAKE_CXX_COMPILER "${ANDROID_CLANG_TOOLCHAIN_ROOT}/bin/${_clang_name}++${TOOL_OS_SUFFIX}" CACHE PATH "C++ compiler") - else() - set( CMAKE_C_COMPILER "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-gcc${TOOL_OS_SUFFIX}" CACHE PATH "C compiler" ) - set( CMAKE_CXX_COMPILER "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-g++${TOOL_OS_SUFFIX}" CACHE PATH "C++ compiler" ) - endif() - endif() - set( CMAKE_ASM_COMPILER "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-gcc${TOOL_OS_SUFFIX}" CACHE PATH "assembler" ) - set( CMAKE_STRIP "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-strip${TOOL_OS_SUFFIX}" CACHE PATH "strip" ) - if( EXISTS "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-gcc-ar${TOOL_OS_SUFFIX}" ) - # Use gcc-ar if we have it for better LTO support. - set( CMAKE_AR "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-gcc-ar${TOOL_OS_SUFFIX}" CACHE PATH "archive" ) - else() - set( CMAKE_AR "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-ar${TOOL_OS_SUFFIX}" CACHE PATH "archive" ) - endif() - set( CMAKE_LINKER "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-ld${TOOL_OS_SUFFIX}" CACHE PATH "linker" ) - set( CMAKE_NM "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-nm${TOOL_OS_SUFFIX}" CACHE PATH "nm" ) - set( CMAKE_OBJCOPY "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-objcopy${TOOL_OS_SUFFIX}" CACHE PATH "objcopy" ) - set( CMAKE_OBJDUMP "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-objdump${TOOL_OS_SUFFIX}" CACHE PATH "objdump" ) - set( CMAKE_RANLIB "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-ranlib${TOOL_OS_SUFFIX}" CACHE PATH "ranlib" ) -endif() - -set( _CMAKE_TOOLCHAIN_PREFIX "${ANDROID_TOOLCHAIN_MACHINE_NAME}-" ) -if( CMAKE_VERSION VERSION_LESS 2.8.5 ) - set( CMAKE_ASM_COMPILER_ARG1 "-c" ) -endif() -if( APPLE ) - find_program( CMAKE_INSTALL_NAME_TOOL NAMES install_name_tool ) - if( NOT CMAKE_INSTALL_NAME_TOOL ) - message( FATAL_ERROR "Could not find install_name_tool, please check your installation." ) - endif() - mark_as_advanced( CMAKE_INSTALL_NAME_TOOL ) -endif() - -# Force set compilers because standard identification works badly for us -include( CMakeForceCompiler ) -CMAKE_FORCE_C_COMPILER( "${CMAKE_C_COMPILER}" GNU ) -if( ANDROID_COMPILER_IS_CLANG ) - set( CMAKE_C_COMPILER_ID Clang ) -endif() -set( CMAKE_C_PLATFORM_ID Linux ) -if( X86_64 OR MIPS64 OR ARM64_V8A ) - set( CMAKE_C_SIZEOF_DATA_PTR 8 ) -else() - set( CMAKE_C_SIZEOF_DATA_PTR 4 ) -endif() -set( CMAKE_C_HAS_ISYSROOT 1 ) -set( CMAKE_C_COMPILER_ABI ELF ) -CMAKE_FORCE_CXX_COMPILER( "${CMAKE_CXX_COMPILER}" GNU ) -if( ANDROID_COMPILER_IS_CLANG ) - set( CMAKE_CXX_COMPILER_ID Clang) -endif() -set( CMAKE_CXX_PLATFORM_ID Linux ) -set( CMAKE_CXX_SIZEOF_DATA_PTR ${CMAKE_C_SIZEOF_DATA_PTR} ) -set( CMAKE_CXX_HAS_ISYSROOT 1 ) -set( CMAKE_CXX_COMPILER_ABI ELF ) -set( CMAKE_CXX_SOURCE_FILE_EXTENSIONS cc cp cxx cpp CPP c++ C ) -# force ASM compiler (required for CMake < 2.8.5) -set( CMAKE_ASM_COMPILER_ID_RUN TRUE ) -set( CMAKE_ASM_COMPILER_ID GNU ) -set( CMAKE_ASM_COMPILER_WORKS TRUE ) -set( CMAKE_ASM_COMPILER_FORCED TRUE ) -set( CMAKE_COMPILER_IS_GNUASM 1) -set( CMAKE_ASM_SOURCE_FILE_EXTENSIONS s S asm ) - -foreach( lang C CXX ASM ) - if( ANDROID_COMPILER_IS_CLANG ) - set( CMAKE_${lang}_COMPILER_VERSION ${ANDROID_CLANG_VERSION} ) - else() - set( CMAKE_${lang}_COMPILER_VERSION ${ANDROID_COMPILER_VERSION} ) - endif() -endforeach() - -# flags and definitions -remove_definitions( -DANDROID ) -add_definitions( -DANDROID ) - -if( ANDROID_SYSROOT MATCHES "[ ;\"]" ) - if( CMAKE_HOST_WIN32 ) - # try to convert path to 8.3 form - file( WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/cvt83.cmd" "@echo %~s1" ) - execute_process( COMMAND "$ENV{ComSpec}" /c "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/cvt83.cmd" "${ANDROID_SYSROOT}" - OUTPUT_VARIABLE __path OUTPUT_STRIP_TRAILING_WHITESPACE - RESULT_VARIABLE __result ERROR_QUIET ) - if( __result EQUAL 0 ) - file( TO_CMAKE_PATH "${__path}" ANDROID_SYSROOT ) - set( ANDROID_CXX_FLAGS "--sysroot=${ANDROID_SYSROOT}" ) - else() - set( ANDROID_CXX_FLAGS "--sysroot=\"${ANDROID_SYSROOT}\"" ) - endif() - else() - set( ANDROID_CXX_FLAGS "'--sysroot=${ANDROID_SYSROOT}'" ) - endif() - if( NOT _CMAKE_IN_TRY_COMPILE ) - # quotes can break try_compile and compiler identification - message(WARNING "Path to your Android NDK (or toolchain) has non-alphanumeric symbols.\nThe build might be broken.\n") - endif() -else() - set( ANDROID_CXX_FLAGS "--sysroot=${ANDROID_SYSROOT}" ) -endif() - -# NDK flags -if (ARM64_V8A ) - set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -funwind-tables" ) - set( ANDROID_CXX_FLAGS_RELEASE "-fomit-frame-pointer -fstrict-aliasing" ) - set( ANDROID_CXX_FLAGS_DEBUG "-fno-omit-frame-pointer -fno-strict-aliasing" ) - if( NOT ANDROID_COMPILER_IS_CLANG ) - set( ANDROID_CXX_FLAGS_RELEASE "${ANDROID_CXX_FLAGS_RELEASE} -funswitch-loops -finline-limit=300" ) - endif() -elseif( ARMEABI OR ARMEABI_V7A) - set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -funwind-tables" ) - if( NOT ANDROID_FORCE_ARM_BUILD AND NOT ARMEABI_V6 ) - set( ANDROID_CXX_FLAGS_RELEASE "-mthumb -fomit-frame-pointer -fno-strict-aliasing" ) - set( ANDROID_CXX_FLAGS_DEBUG "-marm -fno-omit-frame-pointer -fno-strict-aliasing" ) - if( NOT ANDROID_COMPILER_IS_CLANG ) - set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -finline-limit=64" ) - endif() - else() - # always compile ARMEABI_V6 in arm mode; otherwise there is no difference from ARMEABI - set( ANDROID_CXX_FLAGS_RELEASE "-marm -fomit-frame-pointer -fstrict-aliasing" ) - set( ANDROID_CXX_FLAGS_DEBUG "-marm -fno-omit-frame-pointer -fno-strict-aliasing" ) - if( NOT ANDROID_COMPILER_IS_CLANG ) - set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -funswitch-loops -finline-limit=300" ) - endif() - endif() -elseif( X86 OR X86_64 ) - set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -funwind-tables" ) - if( NOT ANDROID_COMPILER_IS_CLANG ) - set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -funswitch-loops -finline-limit=300" ) - endif() - set( ANDROID_CXX_FLAGS_RELEASE "-fomit-frame-pointer -fstrict-aliasing" ) - set( ANDROID_CXX_FLAGS_DEBUG "-fno-omit-frame-pointer -fno-strict-aliasing" ) -elseif( MIPS OR MIPS64 ) - set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -fno-strict-aliasing -finline-functions -funwind-tables -fmessage-length=0" ) - set( ANDROID_CXX_FLAGS_RELEASE "-fomit-frame-pointer" ) - set( ANDROID_CXX_FLAGS_DEBUG "-fno-omit-frame-pointer" ) - if( NOT ANDROID_COMPILER_IS_CLANG ) - set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -fno-inline-functions-called-once -fgcse-after-reload -frerun-cse-after-loop -frename-registers" ) - set( ANDROID_CXX_FLAGS_RELEASE "${ANDROID_CXX_FLAGS_RELEASE} -funswitch-loops -finline-limit=300" ) - endif() -elseif() - set( ANDROID_CXX_FLAGS_RELEASE "" ) - set( ANDROID_CXX_FLAGS_DEBUG "" ) -endif() - -set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -fsigned-char" ) # good/necessary when porting desktop libraries - -if( NOT X86 AND NOT ANDROID_COMPILER_IS_CLANG ) - set( ANDROID_CXX_FLAGS "-Wno-psabi ${ANDROID_CXX_FLAGS}" ) -endif() - -if( NOT ANDROID_COMPILER_VERSION VERSION_LESS "4.6" ) - set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -no-canonical-prefixes" ) # see https://android-review.googlesource.com/#/c/47564/ -endif() - -# ABI-specific flags -if( ARMEABI_V7A ) - set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -march=armv7-a -mfloat-abi=softfp" ) - if( NEON ) - set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -mfpu=neon" ) - elseif( VFPV3 ) - set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -mfpu=vfpv3" ) - else() - set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -mfpu=vfpv3-d16" ) - endif() -elseif( ARMEABI_V6 ) - set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -march=armv6 -mfloat-abi=softfp -mfpu=vfp" ) # vfp == vfpv2 -elseif( ARMEABI ) - set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -march=armv5te -mtune=xscale -msoft-float" ) -endif() - -if( ANDROID_STL MATCHES "gnustl" AND (EXISTS "${__libstl}" OR EXISTS "${__libsupcxx}") ) - set( CMAKE_CXX_CREATE_SHARED_LIBRARY " -o " ) - set( CMAKE_CXX_CREATE_SHARED_MODULE " -o " ) - set( CMAKE_CXX_LINK_EXECUTABLE " -o " ) -else() - set( CMAKE_CXX_CREATE_SHARED_LIBRARY " -o " ) - set( CMAKE_CXX_CREATE_SHARED_MODULE " -o " ) - set( CMAKE_CXX_LINK_EXECUTABLE " -o " ) -endif() - -# STL -if( EXISTS "${__libstl}" OR EXISTS "${__libsupcxx}" ) - if( EXISTS "${__libstl}" ) - set( CMAKE_CXX_CREATE_SHARED_LIBRARY "${CMAKE_CXX_CREATE_SHARED_LIBRARY} \"${__libstl}\"" ) - set( CMAKE_CXX_CREATE_SHARED_MODULE "${CMAKE_CXX_CREATE_SHARED_MODULE} \"${__libstl}\"" ) - set( CMAKE_CXX_LINK_EXECUTABLE "${CMAKE_CXX_LINK_EXECUTABLE} \"${__libstl}\"" ) - endif() - if( EXISTS "${__libsupcxx}" ) - set( CMAKE_CXX_CREATE_SHARED_LIBRARY "${CMAKE_CXX_CREATE_SHARED_LIBRARY} \"${__libsupcxx}\"" ) - set( CMAKE_CXX_CREATE_SHARED_MODULE "${CMAKE_CXX_CREATE_SHARED_MODULE} \"${__libsupcxx}\"" ) - set( CMAKE_CXX_LINK_EXECUTABLE "${CMAKE_CXX_LINK_EXECUTABLE} \"${__libsupcxx}\"" ) - # C objects: - set( CMAKE_C_CREATE_SHARED_LIBRARY " -o " ) - set( CMAKE_C_CREATE_SHARED_MODULE " -o " ) - set( CMAKE_C_LINK_EXECUTABLE " -o " ) - set( CMAKE_C_CREATE_SHARED_LIBRARY "${CMAKE_C_CREATE_SHARED_LIBRARY} \"${__libsupcxx}\"" ) - set( CMAKE_C_CREATE_SHARED_MODULE "${CMAKE_C_CREATE_SHARED_MODULE} \"${__libsupcxx}\"" ) - set( CMAKE_C_LINK_EXECUTABLE "${CMAKE_C_LINK_EXECUTABLE} \"${__libsupcxx}\"" ) - endif() - if( ANDROID_STL MATCHES "gnustl" ) - if( NOT EXISTS "${ANDROID_LIBM_PATH}" ) - set( ANDROID_LIBM_PATH -lm ) - endif() - set( CMAKE_CXX_CREATE_SHARED_LIBRARY "${CMAKE_CXX_CREATE_SHARED_LIBRARY} ${ANDROID_LIBM_PATH}" ) - set( CMAKE_CXX_CREATE_SHARED_MODULE "${CMAKE_CXX_CREATE_SHARED_MODULE} ${ANDROID_LIBM_PATH}" ) - set( CMAKE_CXX_LINK_EXECUTABLE "${CMAKE_CXX_LINK_EXECUTABLE} ${ANDROID_LIBM_PATH}" ) - endif() -endif() - -# variables controlling optional build flags -if( ANDROID_NDK_RELEASE_NUM LESS 7000 ) # before r7 - # libGLESv2.so in NDK's prior to r7 refers to missing external symbols. - # So this flag option is required for all projects using OpenGL from native. - __INIT_VARIABLE( ANDROID_SO_UNDEFINED VALUES ON ) -else() - __INIT_VARIABLE( ANDROID_SO_UNDEFINED VALUES OFF ) -endif() -__INIT_VARIABLE( ANDROID_NO_UNDEFINED VALUES ON ) -__INIT_VARIABLE( ANDROID_FUNCTION_LEVEL_LINKING VALUES ON ) -__INIT_VARIABLE( ANDROID_GOLD_LINKER VALUES ON ) -__INIT_VARIABLE( ANDROID_NOEXECSTACK VALUES ON ) -__INIT_VARIABLE( ANDROID_RELRO VALUES ON ) - -set( ANDROID_NO_UNDEFINED ${ANDROID_NO_UNDEFINED} CACHE BOOL "Show all undefined symbols as linker errors" ) -set( ANDROID_SO_UNDEFINED ${ANDROID_SO_UNDEFINED} CACHE BOOL "Allows or disallows undefined symbols in shared libraries" ) -set( ANDROID_FUNCTION_LEVEL_LINKING ${ANDROID_FUNCTION_LEVEL_LINKING} CACHE BOOL "Put each function in separate section and enable garbage collection of unused input sections at link time" ) -set( ANDROID_GOLD_LINKER ${ANDROID_GOLD_LINKER} CACHE BOOL "Enables gold linker" ) -set( ANDROID_NOEXECSTACK ${ANDROID_NOEXECSTACK} CACHE BOOL "Allows or disallows undefined symbols in shared libraries" ) -set( ANDROID_RELRO ${ANDROID_RELRO} CACHE BOOL "Enables RELRO - a memory corruption mitigation technique" ) -mark_as_advanced( ANDROID_NO_UNDEFINED ANDROID_SO_UNDEFINED ANDROID_FUNCTION_LEVEL_LINKING ANDROID_GOLD_LINKER ANDROID_NOEXECSTACK ANDROID_RELRO ) - -# linker flags -set( ANDROID_LINKER_FLAGS "" ) - -if( ARMEABI_V7A ) - # this is *required* to use the following linker flags that routes around - # a CPU bug in some Cortex-A8 implementations: - set( ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} -Wl,--fix-cortex-a8" ) -endif() - -if( ANDROID_NO_UNDEFINED ) - if( MIPS ) - # there is some sysroot-related problem in mips linker... - if( NOT ANDROID_SYSROOT MATCHES "[ ;\"]" ) - set( ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} -Wl,--no-undefined -Wl,-rpath-link,${ANDROID_SYSROOT}/usr/lib" ) - endif() - else() - set( ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} -Wl,--no-undefined" ) - endif() -endif() - -if( ANDROID_SO_UNDEFINED ) - set( ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} -Wl,-allow-shlib-undefined" ) -endif() - -if( ANDROID_FUNCTION_LEVEL_LINKING ) - set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -fdata-sections -ffunction-sections" ) - set( ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} -Wl,--gc-sections" ) -endif() - -if( ANDROID_COMPILER_VERSION VERSION_EQUAL "4.6" ) - if( ANDROID_GOLD_LINKER AND (CMAKE_HOST_UNIX OR ANDROID_NDK_RELEASE_NUM GREATER 8002) AND (ARMEABI OR ARMEABI_V7A OR X86) ) - set( ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} -fuse-ld=gold" ) - elseif( ANDROID_NDK_RELEASE_NUM GREATER 8002 ) # after r8b - set( ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} -fuse-ld=bfd" ) - elseif( ANDROID_NDK_RELEASE STREQUAL "r8b" AND ARMEABI AND NOT _CMAKE_IN_TRY_COMPILE ) - message( WARNING "The default bfd linker from arm GCC 4.6 toolchain can fail with 'unresolvable R_ARM_THM_CALL relocation' error message. See https://code.google.com/p/android/issues/detail?id=35342 - On Linux and OS X host platform you can workaround this problem using gold linker (default). - Rerun cmake with -DANDROID_GOLD_LINKER=ON option in case of problems. -" ) - endif() -endif() # version 4.6 - -if( ANDROID_NOEXECSTACK ) - if( ANDROID_COMPILER_IS_CLANG ) - set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -Xclang -mnoexecstack" ) - else() - set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -Wa,--noexecstack" ) - endif() - set( ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} -Wl,-z,noexecstack" ) -endif() - -if( ANDROID_RELRO ) - set( ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} -Wl,-z,relro -Wl,-z,now" ) -endif() - -if( ANDROID_COMPILER_IS_CLANG ) - set( ANDROID_CXX_FLAGS "-target ${ANDROID_LLVM_TRIPLE} -Qunused-arguments ${ANDROID_CXX_FLAGS}" ) - if( BUILD_WITH_ANDROID_NDK ) - set( ANDROID_CXX_FLAGS "-gcc-toolchain ${ANDROID_TOOLCHAIN_ROOT} ${ANDROID_CXX_FLAGS}" ) - endif() -endif() - -# cache flags -set( CMAKE_CXX_FLAGS "" CACHE STRING "c++ flags" ) -set( CMAKE_C_FLAGS "" CACHE STRING "c flags" ) -set( CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG" CACHE STRING "c++ Release flags" ) -set( CMAKE_C_FLAGS_RELEASE "-O3 -DNDEBUG" CACHE STRING "c Release flags" ) -set( CMAKE_CXX_FLAGS_DEBUG "-O0 -g -DDEBUG -D_DEBUG" CACHE STRING "c++ Debug flags" ) -set( CMAKE_C_FLAGS_DEBUG "-O0 -g -DDEBUG -D_DEBUG" CACHE STRING "c Debug flags" ) -set( CMAKE_SHARED_LINKER_FLAGS "" CACHE STRING "shared linker flags" ) -set( CMAKE_MODULE_LINKER_FLAGS "" CACHE STRING "module linker flags" ) -set( CMAKE_EXE_LINKER_FLAGS "-Wl,-z,nocopyreloc" CACHE STRING "executable linker flags" ) - -# put flags to cache (for debug purpose only) -set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS}" CACHE INTERNAL "Android specific c/c++ flags" ) -set( ANDROID_CXX_FLAGS_RELEASE "${ANDROID_CXX_FLAGS_RELEASE}" CACHE INTERNAL "Android specific c/c++ Release flags" ) -set( ANDROID_CXX_FLAGS_DEBUG "${ANDROID_CXX_FLAGS_DEBUG}" CACHE INTERNAL "Android specific c/c++ Debug flags" ) -set( ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS}" CACHE INTERNAL "Android specific c/c++ linker flags" ) - -# finish flags -set( CMAKE_CXX_FLAGS "${ANDROID_CXX_FLAGS} ${CMAKE_CXX_FLAGS}" ) -set( CMAKE_C_FLAGS "${ANDROID_CXX_FLAGS} ${CMAKE_C_FLAGS}" ) -set( CMAKE_CXX_FLAGS_RELEASE "${ANDROID_CXX_FLAGS_RELEASE} ${CMAKE_CXX_FLAGS_RELEASE}" ) -set( CMAKE_C_FLAGS_RELEASE "${ANDROID_CXX_FLAGS_RELEASE} ${CMAKE_C_FLAGS_RELEASE}" ) -set( CMAKE_CXX_FLAGS_DEBUG "${ANDROID_CXX_FLAGS_DEBUG} ${CMAKE_CXX_FLAGS_DEBUG}" ) -set( CMAKE_C_FLAGS_DEBUG "${ANDROID_CXX_FLAGS_DEBUG} ${CMAKE_C_FLAGS_DEBUG}" ) -set( CMAKE_SHARED_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} ${CMAKE_SHARED_LINKER_FLAGS}" ) -set( CMAKE_MODULE_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} ${CMAKE_MODULE_LINKER_FLAGS}" ) -set( CMAKE_EXE_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} ${CMAKE_EXE_LINKER_FLAGS}" ) - -if( MIPS AND BUILD_WITH_ANDROID_NDK AND ANDROID_NDK_RELEASE STREQUAL "r8" ) - set( CMAKE_SHARED_LINKER_FLAGS "-Wl,-T,${ANDROID_NDK_TOOLCHAINS_PATH}/${ANDROID_GCC_TOOLCHAIN_NAME}/mipself.xsc ${CMAKE_SHARED_LINKER_FLAGS}" ) - set( CMAKE_MODULE_LINKER_FLAGS "-Wl,-T,${ANDROID_NDK_TOOLCHAINS_PATH}/${ANDROID_GCC_TOOLCHAIN_NAME}/mipself.xsc ${CMAKE_MODULE_LINKER_FLAGS}" ) - set( CMAKE_EXE_LINKER_FLAGS "-Wl,-T,${ANDROID_NDK_TOOLCHAINS_PATH}/${ANDROID_GCC_TOOLCHAIN_NAME}/mipself.x ${CMAKE_EXE_LINKER_FLAGS}" ) -endif() - -# pie/pic -if( NOT (ANDROID_NATIVE_API_LEVEL LESS 16) AND (NOT DEFINED ANDROID_APP_PIE OR ANDROID_APP_PIE) AND (CMAKE_VERSION VERSION_GREATER 2.8.8) ) - set( CMAKE_POSITION_INDEPENDENT_CODE TRUE ) - set( CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fPIE -pie") -else() - set( CMAKE_POSITION_INDEPENDENT_CODE FALSE ) - set( CMAKE_CXX_FLAGS "-fpic ${CMAKE_CXX_FLAGS}" ) - set( CMAKE_C_FLAGS "-fpic ${CMAKE_C_FLAGS}" ) -endif() - -# configure rtti -if( DEFINED ANDROID_RTTI AND ANDROID_STL_FORCE_FEATURES ) - if( ANDROID_RTTI ) - set( CMAKE_CXX_FLAGS "-frtti ${CMAKE_CXX_FLAGS}" ) - else() - set( CMAKE_CXX_FLAGS "-fno-rtti ${CMAKE_CXX_FLAGS}" ) - endif() -endif() - -# configure exceptios -if( DEFINED ANDROID_EXCEPTIONS AND ANDROID_STL_FORCE_FEATURES ) - if( ANDROID_EXCEPTIONS ) - set( CMAKE_CXX_FLAGS "-fexceptions ${CMAKE_CXX_FLAGS}" ) - set( CMAKE_C_FLAGS "-fexceptions ${CMAKE_C_FLAGS}" ) - else() - set( CMAKE_CXX_FLAGS "-fno-exceptions ${CMAKE_CXX_FLAGS}" ) - set( CMAKE_C_FLAGS "-fno-exceptions ${CMAKE_C_FLAGS}" ) - endif() -endif() - -# global includes and link directories -include_directories( SYSTEM "${ANDROID_SYSROOT}/usr/include" ${ANDROID_STL_INCLUDE_DIRS} ) -get_filename_component(__android_install_path "${CMAKE_INSTALL_PREFIX}/libs/${ANDROID_NDK_ABI_NAME}" ABSOLUTE) # avoid CMP0015 policy warning -link_directories( "${__android_install_path}" ) - -# detect if need link crtbegin_so.o explicitly -if( NOT DEFINED ANDROID_EXPLICIT_CRT_LINK ) - set( __cmd "${CMAKE_CXX_CREATE_SHARED_LIBRARY}" ) - string( REPLACE "" "${CMAKE_CXX_COMPILER} ${CMAKE_CXX_COMPILER_ARG1}" __cmd "${__cmd}" ) - string( REPLACE "" "${CMAKE_C_COMPILER} ${CMAKE_C_COMPILER_ARG1}" __cmd "${__cmd}" ) - string( REPLACE "" "${CMAKE_CXX_FLAGS}" __cmd "${__cmd}" ) - string( REPLACE "" "" __cmd "${__cmd}" ) - string( REPLACE "" "${CMAKE_SHARED_LINKER_FLAGS}" __cmd "${__cmd}" ) - string( REPLACE "" "-shared" __cmd "${__cmd}" ) - string( REPLACE "" "" __cmd "${__cmd}" ) - string( REPLACE "" "" __cmd "${__cmd}" ) - string( REPLACE "" "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/toolchain_crtlink_test.so" __cmd "${__cmd}" ) - string( REPLACE "" "\"${ANDROID_SYSROOT}/usr/lib/crtbegin_so.o\"" __cmd "${__cmd}" ) - string( REPLACE "" "" __cmd "${__cmd}" ) - separate_arguments( __cmd ) - foreach( __var ANDROID_NDK ANDROID_NDK_TOOLCHAINS_PATH ANDROID_STANDALONE_TOOLCHAIN ) - if( ${__var} ) - set( __tmp "${${__var}}" ) - separate_arguments( __tmp ) - string( REPLACE "${__tmp}" "${${__var}}" __cmd "${__cmd}") - endif() - endforeach() - string( REPLACE "'" "" __cmd "${__cmd}" ) - string( REPLACE "\"" "" __cmd "${__cmd}" ) - execute_process( COMMAND ${__cmd} RESULT_VARIABLE __cmd_result OUTPUT_QUIET ERROR_QUIET ) - if( __cmd_result EQUAL 0 ) - set( ANDROID_EXPLICIT_CRT_LINK ON ) - else() - set( ANDROID_EXPLICIT_CRT_LINK OFF ) - endif() -endif() - -if( ANDROID_EXPLICIT_CRT_LINK ) - set( CMAKE_CXX_CREATE_SHARED_LIBRARY "${CMAKE_CXX_CREATE_SHARED_LIBRARY} \"${ANDROID_SYSROOT}/usr/lib/crtbegin_so.o\"" ) - set( CMAKE_CXX_CREATE_SHARED_MODULE "${CMAKE_CXX_CREATE_SHARED_MODULE} \"${ANDROID_SYSROOT}/usr/lib/crtbegin_so.o\"" ) -endif() - -# setup output directories -set( CMAKE_INSTALL_PREFIX "${ANDROID_TOOLCHAIN_ROOT}/user" CACHE STRING "path for installing" ) - -if( DEFINED LIBRARY_OUTPUT_PATH_ROOT - OR EXISTS "${CMAKE_SOURCE_DIR}/AndroidManifest.xml" - OR (EXISTS "${CMAKE_SOURCE_DIR}/../AndroidManifest.xml" AND EXISTS "${CMAKE_SOURCE_DIR}/../jni/") ) - set( LIBRARY_OUTPUT_PATH_ROOT ${CMAKE_SOURCE_DIR} CACHE PATH "Root for binaries output, set this to change where Android libs are installed to" ) - if( NOT _CMAKE_IN_TRY_COMPILE ) - if( EXISTS "${CMAKE_SOURCE_DIR}/jni/CMakeLists.txt" ) - set( EXECUTABLE_OUTPUT_PATH "${LIBRARY_OUTPUT_PATH_ROOT}/bin/${ANDROID_NDK_ABI_NAME}" CACHE PATH "Output directory for applications" ) - else() - set( EXECUTABLE_OUTPUT_PATH "${LIBRARY_OUTPUT_PATH_ROOT}/bin" CACHE PATH "Output directory for applications" ) - endif() - set( LIBRARY_OUTPUT_PATH "${LIBRARY_OUTPUT_PATH_ROOT}/libs/${ANDROID_NDK_ABI_NAME}" CACHE PATH "Output directory for Android libs" ) - endif() -endif() - -# copy shaed stl library to build directory -if( NOT _CMAKE_IN_TRY_COMPILE AND __libstl MATCHES "[.]so$" AND DEFINED LIBRARY_OUTPUT_PATH ) - get_filename_component( __libstlname "${__libstl}" NAME ) - execute_process( COMMAND "${CMAKE_COMMAND}" -E copy_if_different "${__libstl}" "${LIBRARY_OUTPUT_PATH}/${__libstlname}" RESULT_VARIABLE __fileCopyProcess ) - if( NOT __fileCopyProcess EQUAL 0 OR NOT EXISTS "${LIBRARY_OUTPUT_PATH}/${__libstlname}") - message( SEND_ERROR "Failed copying of ${__libstl} to the ${LIBRARY_OUTPUT_PATH}/${__libstlname}" ) - endif() - unset( __fileCopyProcess ) - unset( __libstlname ) -endif() - - -# set these global flags for cmake client scripts to change behavior -set( ANDROID True ) -set( BUILD_ANDROID True ) - -# where is the target environment -set( CMAKE_FIND_ROOT_PATH "${ANDROID_TOOLCHAIN_ROOT}/bin" "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_MACHINE_NAME}" "${ANDROID_SYSROOT}" "${CMAKE_INSTALL_PREFIX}" "${CMAKE_INSTALL_PREFIX}/share" ) - -# only search for libraries and includes in the ndk toolchain -set( CMAKE_FIND_ROOT_PATH_MODE_PROGRAM ONLY ) -set( CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY ) -set( CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY ) - - -# macro to find packages on the host OS -macro( find_host_package ) - set( CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER ) - set( CMAKE_FIND_ROOT_PATH_MODE_LIBRARY NEVER ) - set( CMAKE_FIND_ROOT_PATH_MODE_INCLUDE NEVER ) - if( CMAKE_HOST_WIN32 ) - SET( WIN32 1 ) - SET( UNIX ) - elseif( CMAKE_HOST_APPLE ) - SET( APPLE 1 ) - SET( UNIX ) - endif() - find_package( ${ARGN} ) - SET( WIN32 ) - SET( APPLE ) - SET( UNIX 1 ) - set( CMAKE_FIND_ROOT_PATH_MODE_PROGRAM ONLY ) - set( CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY ) - set( CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY ) -endmacro() - - -# macro to find programs on the host OS -macro( find_host_program ) - set( CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER ) - set( CMAKE_FIND_ROOT_PATH_MODE_LIBRARY NEVER ) - set( CMAKE_FIND_ROOT_PATH_MODE_INCLUDE NEVER ) - if( CMAKE_HOST_WIN32 ) - SET( WIN32 1 ) - SET( UNIX ) - elseif( CMAKE_HOST_APPLE ) - SET( APPLE 1 ) - SET( UNIX ) - endif() - find_program( ${ARGN} ) - SET( WIN32 ) - SET( APPLE ) - SET( UNIX 1 ) - set( CMAKE_FIND_ROOT_PATH_MODE_PROGRAM ONLY ) - set( CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY ) - set( CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY ) -endmacro() - - -# export toolchain settings for the try_compile() command -if( NOT _CMAKE_IN_TRY_COMPILE ) - set( __toolchain_config "") - foreach( __var NDK_CCACHE LIBRARY_OUTPUT_PATH_ROOT ANDROID_FORBID_SYGWIN - ANDROID_NDK_HOST_X64 - ANDROID_NDK - ANDROID_NDK_LAYOUT - ANDROID_STANDALONE_TOOLCHAIN - ANDROID_TOOLCHAIN_NAME - ANDROID_ABI - ANDROID_NATIVE_API_LEVEL - ANDROID_STL - ANDROID_STL_FORCE_FEATURES - ANDROID_FORCE_ARM_BUILD - ANDROID_NO_UNDEFINED - ANDROID_SO_UNDEFINED - ANDROID_FUNCTION_LEVEL_LINKING - ANDROID_GOLD_LINKER - ANDROID_NOEXECSTACK - ANDROID_RELRO - ANDROID_LIBM_PATH - ANDROID_EXPLICIT_CRT_LINK - ANDROID_APP_PIE - ) - if( DEFINED ${__var} ) - if( ${__var} MATCHES " ") - set( __toolchain_config "${__toolchain_config}set( ${__var} \"${${__var}}\" CACHE INTERNAL \"\" )\n" ) - else() - set( __toolchain_config "${__toolchain_config}set( ${__var} ${${__var}} CACHE INTERNAL \"\" )\n" ) - endif() - endif() - endforeach() - file( WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/android.toolchain.config.cmake" "${__toolchain_config}" ) - unset( __toolchain_config ) -endif() - - -# force cmake to produce / instead of \ in build commands for Ninja generator -if( CMAKE_GENERATOR MATCHES "Ninja" AND CMAKE_HOST_WIN32 ) - # it is a bad hack after all - # CMake generates Ninja makefiles with UNIX paths only if it thinks that we are going to build with MinGW - set( CMAKE_COMPILER_IS_MINGW TRUE ) # tell CMake that we are MinGW - set( CMAKE_CROSSCOMPILING TRUE ) # stop recursion - enable_language( C ) - enable_language( CXX ) - # unset( CMAKE_COMPILER_IS_MINGW ) # can't unset because CMake does not convert back-slashes in response files without it - unset( MINGW ) -endif() - - -# Variables controlling behavior or set by cmake toolchain: -# ANDROID_ABI : "armeabi-v7a" (default), "armeabi", "armeabi-v7a with NEON", "armeabi-v7a with VFPV3", "armeabi-v6 with VFP", "x86", "mips", "arm64-v8a", "x86_64", "mips64" -# ANDROID_NATIVE_API_LEVEL : 3,4,5,8,9,14,15,16,17,18,19,21 (depends on NDK version) -# ANDROID_STL : gnustl_static/gnustl_shared/stlport_static/stlport_shared/gabi++_static/gabi++_shared/system_re/system/none -# ANDROID_FORBID_SYGWIN : ON/OFF -# ANDROID_NO_UNDEFINED : ON/OFF -# ANDROID_SO_UNDEFINED : OFF/ON (default depends on NDK version) -# ANDROID_FUNCTION_LEVEL_LINKING : ON/OFF -# ANDROID_GOLD_LINKER : ON/OFF -# ANDROID_NOEXECSTACK : ON/OFF -# ANDROID_RELRO : ON/OFF -# ANDROID_FORCE_ARM_BUILD : ON/OFF -# ANDROID_STL_FORCE_FEATURES : ON/OFF -# ANDROID_LIBM_PATH : path to libm.so (set to something like $(TOP)/out/target/product//obj/lib/libm.so) to workaround unresolved `sincos` -# Can be set only at the first run: -# ANDROID_NDK : path to your NDK install -# NDK_CCACHE : path to your ccache executable -# ANDROID_TOOLCHAIN_NAME : the NDK name of compiler toolchain -# ANDROID_NDK_HOST_X64 : try to use x86_64 toolchain (default for x64 host systems) -# ANDROID_NDK_LAYOUT : the inner NDK structure (RELEASE, LINARO, ANDROID) -# LIBRARY_OUTPUT_PATH_ROOT : -# ANDROID_STANDALONE_TOOLCHAIN -# -# Primary read-only variables: -# ANDROID : always TRUE -# ARMEABI : TRUE for arm v6 and older devices -# ARMEABI_V6 : TRUE for arm v6 -# ARMEABI_V7A : TRUE for arm v7a -# ARM64_V8A : TRUE for arm64-v8a -# NEON : TRUE if NEON unit is enabled -# VFPV3 : TRUE if VFP version 3 is enabled -# X86 : TRUE if configured for x86 -# X86_64 : TRUE if configured for x86_64 -# MIPS : TRUE if configured for mips -# MIPS64 : TRUE if configured for mips64 -# BUILD_WITH_ANDROID_NDK : TRUE if NDK is used -# BUILD_WITH_STANDALONE_TOOLCHAIN : TRUE if standalone toolchain is used -# ANDROID_NDK_HOST_SYSTEM_NAME : "windows", "linux-x86" or "darwin-x86" depending on host platform -# ANDROID_NDK_ABI_NAME : "armeabi", "armeabi-v7a", "x86", "mips", "arm64-v8a", "x86_64", "mips64" depending on ANDROID_ABI -# ANDROID_NDK_RELEASE : from r5 to r10d; set only for NDK -# ANDROID_NDK_RELEASE_NUM : numeric ANDROID_NDK_RELEASE version (1000*major+minor) -# ANDROID_ARCH_NAME : "arm", "x86", "mips", "arm64", "x86_64", "mips64" depending on ANDROID_ABI -# ANDROID_SYSROOT : path to the compiler sysroot -# TOOL_OS_SUFFIX : "" or ".exe" depending on host platform -# ANDROID_COMPILER_IS_CLANG : TRUE if clang compiler is used -# -# Secondary (less stable) read-only variables: -# ANDROID_COMPILER_VERSION : GCC version used (not Clang version) -# ANDROID_CLANG_VERSION : version of clang compiler if clang is used -# ANDROID_CXX_FLAGS : C/C++ compiler flags required by Android platform -# ANDROID_SUPPORTED_ABIS : list of currently allowed values for ANDROID_ABI -# ANDROID_TOOLCHAIN_MACHINE_NAME : "arm-linux-androideabi", "arm-eabi" or "i686-android-linux" -# ANDROID_TOOLCHAIN_ROOT : path to the top level of toolchain (standalone or placed inside NDK) -# ANDROID_CLANG_TOOLCHAIN_ROOT : path to clang tools -# ANDROID_SUPPORTED_NATIVE_API_LEVELS : list of native API levels found inside NDK -# ANDROID_STL_INCLUDE_DIRS : stl include paths -# ANDROID_RTTI : if rtti is enabled by the runtime -# ANDROID_EXCEPTIONS : if exceptions are enabled by the runtime -# ANDROID_GCC_TOOLCHAIN_NAME : read-only, differs from ANDROID_TOOLCHAIN_NAME only if clang is used -# -# Defaults: -# ANDROID_DEFAULT_NDK_API_LEVEL -# ANDROID_DEFAULT_NDK_API_LEVEL_${ARCH} -# ANDROID_NDK_SEARCH_PATHS -# ANDROID_SUPPORTED_ABIS_${ARCH} -# ANDROID_SUPPORTED_NDK_VERSIONS diff --git a/modules/cotire.cmake b/modules/cotire.cmake index ced265c105940123785990c9259fc87b5d62cbd1..371ab8bc4fcfa2b38f30218fc5274a2f2cfb46fd 100644 --- a/modules/cotire.cmake +++ b/modules/cotire.cmake @@ -43,7 +43,7 @@ if (NOT CMAKE_SCRIPT_MODE_FILE) endif() set (COTIRE_CMAKE_MODULE_FILE "${CMAKE_CURRENT_LIST_FILE}") -set (COTIRE_CMAKE_MODULE_VERSION "1.8.0") +set (COTIRE_CMAKE_MODULE_VERSION "1.8.1") # activate select policies if (POLICY CMP0025) @@ -931,9 +931,9 @@ function (cotire_add_includes_to_cmd _cmdVar _language _includesVar _systemInclu list (FIND ${_systemIncludesVar} "${_include}" _index) endif() if (_index GREATER -1) + # Pass -isystem as a separated flag, not as "-isystem ". string(STRIP "${CMAKE_INCLUDE_SYSTEM_FLAG_${_language}}" _include_system_flag) list (APPEND ${_cmdVar} "${_include_system_flag}" "${_include}") - else() list (APPEND ${_cmdVar} "${CMAKE_INCLUDE_FLAG_${_language}}${CMAKE_INCLUDE_FLAG_SEP_${_language}}${_include}") endif() @@ -1070,10 +1070,10 @@ macro (cotire_check_ignore_header_file_path _headerFile _headerIsIgnoredVar) set (${_headerIsIgnoredVar} TRUE) elseif (IS_DIRECTORY "${_headerFile}") set (${_headerIsIgnoredVar} TRUE) - elseif ("${_headerFile}" MATCHES "\\.\\.|[_-]fixed" AND "${_headerFile}" MATCHES "\\.h$") - # heuristic: ignore C headers with embedded parent directory references or "-fixed" or "_fixed" in path + elseif ("${_headerFile}" MATCHES "\\.\\.|[_-]fixed") + # heuristic: ignore headers with embedded parent directory references or "-fixed" or "_fixed" in path # these often stem from using GCC #include_next tricks, which may break the precompiled header compilation - # with the error message "error: no include path in which to search for header.h" + # with the error message "error: no include path in which to search for header" set (${_headerIsIgnoredVar} TRUE) else() set (${_headerIsIgnoredVar} FALSE) @@ -1632,7 +1632,6 @@ function (cotire_add_pch_compilation_flags _language _compilerID _compilerVersio file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileNative) file (TO_NATIVE_PATH "${_pchFile}" _pchFileNative) file (TO_NATIVE_PATH "${_hostFile}" _hostFileNative) - string (REGEX REPLACE "\\.[^.]*$" ".obj" _objFileNative "${_hostFileNative}") # cl.exe options used # /Yc creates a precompiled header file # /Fp specifies precompiled header binary file name @@ -1640,16 +1639,13 @@ function (cotire_add_pch_compilation_flags _language _compilerID _compilerVersio # /TC treat all files named on the command line as C source files # /TP treat all files named on the command line as C++ source files # /Zs syntax check only - # /c stop compilation after creating an object file - # /Fo specifies object file name # /Zm precompiled header memory allocation scaling factor set (_sourceFileTypeC "/TC") set (_sourceFileTypeCXX "/TP") if (_flags) # append to list list (APPEND _flags /nologo "${_sourceFileType${_language}}" - "/Yc${_prefixFileNative}" "/Fp${_pchFileNative}" "/FI${_prefixFileNative}" /c "/Fo${_objFileNative}" - "${_hostFileNative}") + "/Yc${_prefixFileNative}" "/Fp${_pchFileNative}" "/FI${_prefixFileNative}" /Zs "${_hostFileNative}") if (COTIRE_PCH_MEMORY_SCALING_FACTOR) list (APPEND _flags "/Zm${COTIRE_PCH_MEMORY_SCALING_FACTOR}") endif() @@ -2387,8 +2383,8 @@ endfunction() function (cotire_setup_pch_file_compilation _language _target _targetScript _prefixFile _pchFile _hostFile) set (_sourceFiles ${ARGN}) - if ((CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel" OR - (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "Clang")) AND NOT "${CMAKE_GENERATOR}" MATCHES "Make|Ninja") + if (CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel" OR + (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "Clang")) # for MSVC, Intel and Clang-cl, we attach the precompiled header compilation to the host file # the remaining files include the precompiled header, see cotire_setup_pch_file_inclusion if (_sourceFiles) @@ -2420,16 +2416,9 @@ function (cotire_setup_pch_file_compilation _language _target _targetScript _pre if (COTIRE_DEBUG) message (STATUS "add_custom_command: OUTPUT ${_pchFile} ${_cmds} DEPENDS ${_prefixFile} ${_realCompilerExe} IMPLICIT_DEPENDS ${_language} ${_prefixFile}") endif() - set (_outputFiles "") - list (APPEND _outputFiles "${_pchFile}") set_property (SOURCE "${_pchFile}" PROPERTY GENERATED TRUE) - if (CMAKE_${_language}_COMPILER_ID MATCHES "MSVC") - string (REGEX REPLACE "\\.[^.]*$" ".obj" _hostObjFile "${_hostFile}") - list (APPEND _outputFiles "${_hostObjFile}") - set_property (SOURCE "${_hostObjFile}" PROPERTY GENERATED TRUE) - endif() add_custom_command( - OUTPUT ${_outputFiles} + OUTPUT "${_pchFile}" COMMAND ${_cmds} DEPENDS "${_prefixFile}" "${_realCompilerExe}" IMPLICIT_DEPENDS ${_language} "${_prefixFile}" @@ -2441,8 +2430,8 @@ function (cotire_setup_pch_file_compilation _language _target _targetScript _pre endfunction() function (cotire_setup_pch_file_inclusion _language _target _wholeTarget _prefixFile _pchFile _hostFile) - if ((CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel" OR - (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "Clang")) AND NOT "${CMAKE_GENERATOR}" MATCHES "Make|Ninja") + if (CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel" OR + (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "Clang")) # for MSVC, Intel and clang-cl, we include the precompiled header in all but the host file # the host file does the precompiled header compilation, see cotire_setup_pch_file_compilation set (_sourceFiles ${ARGN}) @@ -2589,9 +2578,9 @@ function (cotire_setup_target_pch_usage _languages _target _wholeTarget) # if this is a single-language target without any excluded files if (_wholeTarget) set (_language "${_languages}") - # for Intel and clang-cl, precompiled header inclusion is always done on the source file level + # for MSVC, Intel and clang-cl, precompiled header inclusion is always done on the source file level # see cotire_setup_pch_file_inclusion - if (NOT CMAKE_${_language}_COMPILER_ID MATCHES "Intel" AND NOT + if (NOT CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel" AND NOT (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "Clang")) get_property(_prefixFile TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER) if (_prefixFile) @@ -3041,16 +3030,6 @@ function (cotire_process_target_language _language _configurations _target _whol if (_targetUsePCH) cotire_make_pch_file_path(${_language} ${_target} _pchFile) if (_pchFile) - if (CMAKE_${_language}_COMPILER_ID MATCHES "MSVC" AND "${CMAKE_GENERATOR}" MATCHES "Make|Ninja") - # use stub file to link in precompiled header - string (REGEX REPLACE "\\.[^.]*$" "_stub.cxx" _stubFile "${_prefixFile}") - file (WRITE "${_stubFile}" "#include \"${_prefixFile}\"") - list (INSERT _sourceFiles 0 "${_stubFile}") - string (REGEX REPLACE "\\.[^.]*$" ".obj" _stubObjFile "${_stubFile}") - set_property (SOURCE "${_stubObjFile}" PROPERTY GENERATED TRUE) - target_sources (${_target} PRIVATE "${_stubObjFile}") - set_property(TARGET ${_target} PROPERTY COTIRE_${_language}_STUB_OBJECT "${_stubObjFile}") - endif() # first file in _sourceFiles is passed as the host file cotire_setup_pch_file_compilation( ${_language} ${_target} "${_targetConfigScript}" "${_prefixFile}" "${_pchFile}" ${_sourceFiles}) @@ -3140,11 +3119,6 @@ function (cotire_collect_unity_target_sources _target _languages _unityTargetSou if (_sourceFiles OR _cotiredSources) list (REMOVE_ITEM _unityTargetSources ${_sourceFiles} ${_cotiredSources}) endif() - if (CMAKE_${_language}_COMPILER_ID MATCHES "MSVC" AND "${CMAKE_GENERATOR}" MATCHES "Make|Ninja") - # remove pch stub object file - get_property(_stubObjFile TARGET ${_target} PROPERTY COTIRE_${_language}_STUB_OBJECT) - list (REMOVE_ITEM _unityTargetSources "${_stubObjFile}") - endif() # add unity source files instead list (APPEND _unityTargetSources ${_unityFiles}) endif() diff --git a/screenshots/cornell.jpeg b/screenshots/cornell.jpeg index 8eaead5adea63aabd208072902d4d48e8c2cf486..30b6a61d5b0448819c3fc4b953d5271bd4f967a2 100644 Binary files a/screenshots/cornell.jpeg and b/screenshots/cornell.jpeg differ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index cb812173dc53a4903548e23db28fdc559b0c3459..7da0eac09213d6f44dcb14d43fbe20ba226c7586 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,5 +1,7 @@ cmake_minimum_required(VERSION 3.2 FATAL_ERROR) +add_subdirectory(mirrage) + if(MIRRAGE_BUILD_DEMO) add_subdirectory(demo) endif() @@ -8,5 +10,3 @@ if(MIRRAGE_BUILD_MESH_CONVERTER) add_subdirectory(mesh_converter) endif() -add_subdirectory(mirrage) - diff --git a/src/demo/CMakeLists.txt b/src/demo/CMakeLists.txt index 5fd3264bbcb28c2dca49a4cf4587394825a5ad3e..d6b6342f42c5668bf979373d7baa674a44bb0ede 100644 --- a/src/demo/CMakeLists.txt +++ b/src/demo/CMakeLists.txt @@ -1,6 +1,6 @@ -cmake_minimum_required(VERSION 3.2 FATAL_ERROR) +cmake_minimum_required(VERSION 3.9 FATAL_ERROR) -project(mirrage_demo LANGUAGES CXX) +project(mirrage_demo LANGUAGES CXX ASM) file(GLOB_RECURSE HEADER_FILES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} @@ -13,9 +13,13 @@ add_executable(demo ${HEADER_FILES} src/main.cpp src/meta_system.cpp src/test_screen.cpp + src/test_animation_screen.cpp ${BACKWARD_ENABLE} ) -add_backward(demo) +if(${MIRRAGE_ENABLE_BACKWARD}) + add_backward(demo) +endif() +target_compile_features(demo PUBLIC cxx_std_17) set(MIRRAGE_DEFAULT_COMPILER_ARGS ${MIRRAGE_DEFAULT_COMPILER_ARGS}) target_compile_options(demo PRIVATE ${MIRRAGE_DEFAULT_COMPILER_ARGS}) @@ -29,6 +33,18 @@ target_link_libraries(demo sf2 doctest ) +if (WIN32) + if(MINGW) + target_link_libraries(demo + PRIVATE + mingw32 + ) + endif() + target_link_libraries(demo + PRIVATE + mirrage::deps::SDL2main + ) +endif() option(MIRRAGE_EXPORT_EXECUTABLE "Export executable" OFF) if(MIRRAGE_EXPORT_EXECUTABLE) @@ -39,3 +55,7 @@ endif() if(COMMAND cotire) cotire(demo) endif() + +if(MSVC_IDE) + set_property(TARGET demo PROPERTY VS_DEBUGGER_WORKING_DIRECTORY "${MIRRAGE_ROOT_DIR}/assets") +endif() diff --git a/src/demo/src/game_engine.cpp b/src/demo/src/game_engine.cpp index 5281c1dbed1e2f495b9f54fadc5d123b2db2bb42..d3300e5e8a7cfed99d37adaad14c80fbcb053aaa 100644 --- a/src/demo/src/game_engine.cpp +++ b/src/demo/src/game_engine.cpp @@ -2,48 +2,61 @@ #include #include +#include #include #include #include #include +#include #include #include #include #include +#include #include #include #include #include +#include namespace mirrage { - Game_engine::Game_engine(const std::string& org, - const std::string& title, - std::uint32_t version_major, - std::uint32_t version_minor, - bool debug, - int argc, - char** argv, - char** env) - : Engine(org, title, version_major, version_minor, debug, false, argc, argv, env) + Game_engine::Game_engine(const std::string& org, + const std::string& title, + util::maybe base_dir, + std::uint32_t version_major, + std::uint32_t version_minor, + bool debug, + int argc, + char** argv, + char** env) + : Engine(org, title, std::move(base_dir), version_major, version_minor, debug, false, argc, argv, env) + , _debug_ui(assets(), gui(), bus()) , _renderer_factory(std::make_unique( *this, window(), util::make_vector(renderer::make_pass_factory(), + renderer::make_pass_factory(), renderer::make_pass_factory(), renderer::make_pass_factory(), renderer::make_pass_factory(), renderer::make_pass_factory(), renderer::make_pass_factory(), renderer::make_pass_factory(), + renderer::make_pass_factory(), renderer::make_pass_factory(), + renderer::make_pass_factory(), renderer::make_pass_factory(), renderer::make_pass_factory(), + renderer::make_pass_factory(), renderer::make_pass_factory(), renderer::make_pass_factory(), renderer::make_pass_factory()))) + , _global_render(_renderer_factory->create_renderer()) + , _render_pass_mask(_renderer_factory->all_passes_mask()) { + util::erase_fast(_render_pass_mask, renderer::render_pass_id_of()); } Game_engine::~Game_engine() @@ -51,6 +64,13 @@ namespace mirrage { screens().clear(); // destroy all screens before the engine } - void Game_engine::_on_post_frame(util::Time) { _renderer_factory->finish_frame(); } + void Game_engine::_on_post_frame(util::Time dt) + { + _debug_ui.draw(); + + _global_render->update(dt); + _global_render->draw(); + _renderer_factory->finish_frame(); + } } // namespace mirrage diff --git a/src/demo/src/game_engine.hpp b/src/demo/src/game_engine.hpp index c5d5a39b2ab42deac486d4532030aae92dae7d8a..0e7b0e08fccebf5a52be5736e369a626fa490dd9 100644 --- a/src/demo/src/game_engine.hpp +++ b/src/demo/src/game_engine.hpp @@ -11,6 +11,7 @@ #include #include +#include #include @@ -21,22 +22,28 @@ namespace mirrage { class Game_engine : public Engine { public: - Game_engine(const std::string& org, - const std::string& title, - std::uint32_t version_major, - std::uint32_t version_minor, - bool debug, - int argc, - char** argv, - char** env); - ~Game_engine(); + Game_engine(const std::string& org, + const std::string& title, + util::maybe base_dir, + std::uint32_t version_major, + std::uint32_t version_minor, + bool debug, + int argc, + char** argv, + char** env); + ~Game_engine() override; auto renderer_factory() noexcept -> auto& { return *_renderer_factory; } + auto global_render() noexcept -> auto& { return *_global_render; } + auto render_pass_mask() noexcept -> auto& { return _render_pass_mask; } protected: void _on_post_frame(util::Time) override; private: + gui::Debug_ui _debug_ui; std::unique_ptr _renderer_factory; + std::unique_ptr _global_render; + renderer::Render_pass_mask _render_pass_mask; }; } // namespace mirrage diff --git a/src/demo/src/main.cpp b/src/demo/src/main.cpp index aca1fba2d28df1f1db84f89587dcf4e56dd5f7d5..69b8eff7ef37f474b5c8190705d7efae19571463 100644 --- a/src/demo/src/main.cpp +++ b/src/demo/src/main.cpp @@ -8,13 +8,16 @@ #define DOCTEST_CONFIG_IMPLEMENT #include "game_engine.hpp" +#include "test_animation_screen.hpp" #include "test_screen.hpp" #include #include +#include +#include -#include +#include #include #include #include @@ -28,7 +31,8 @@ using namespace std::string_literals; namespace { - std::unique_ptr engine; + std::unique_ptr engine; + std::unique_ptr global_commands; void init_env(int argc, char** argv, char** env); void init_engine(); @@ -69,19 +73,30 @@ int main(int argc, char** argv, char** env) namespace { constexpr auto org_name = "secondsystem"; constexpr auto app_name = "Mirrage"; - int argc; - char** argv; - char** env; + auto base_dir() -> util::maybe + { +#ifndef NDEBUG + return mirrage::version_info::engine_root + "/assets"; +#else + return util::nothing; +#endif + } + + int argc; + char** argv; + char** env; void init_env(int argc, char** argv, char** env) { - auto write_dir = asset::write_dir(argv[0], org_name, app_name); + auto write_dir = asset::write_dir(argv[0], org_name, app_name, base_dir()); static auto fileAppender = plog::RollingFileAppender( (write_dir + "/mirrage.log").c_str(), 1024L * 1024L, 4); static auto consoleAppender = plog::ColorConsoleAppender(); - plog::init(plog::debug, &fileAppender).addAppender(&consoleAppender); + plog::init(plog::debug, &fileAppender) + .addAppender(&consoleAppender) + .addAppender(&gui::debug_console_appender()); ::argc = argc; @@ -89,6 +104,7 @@ namespace { ::env = env; LOG(plog::debug) << "Game started from: " << argv[0] << "\n" + << "Base dir: " << base_dir().get_ref_or("") << "\n" << "Working dir: " << asset::pwd() << "\n" << "Write dir: " << write_dir << "\n" << "Version: " << version_info::name << "\n" @@ -114,15 +130,37 @@ namespace { } - engine = std::make_unique(org_name, app_name, 0, 1, debug, argc, argv, env); + engine = std::make_unique(org_name, app_name, base_dir(), 0, 1, debug, argc, argv, env); + + global_commands = std::make_unique(); + global_commands->add("screen.leave | Pops the top screens", + [&](std::uint8_t depth) { engine->screens().leave(depth); }); + global_commands->add( + "screen.print | Prints the currently open screens (=> update+draw next, D> only draw, S> " + "don't update+draw)", + [&]() { + auto screen_list = engine->screens().print_stack(); + LOG(plog::info) << "Open Screens: " << screen_list; + }); + + global_commands->add("screen.enter.test | Enters the test screen", + [&]() { engine->screens().enter(); }); + global_commands->add("screen.enter.animation_test | Enters the animation test screen", + [&]() { engine->screens().enter(); }); if(argc > 1 && argv[1] == "test"s) engine->screens().enter(); + else if(argc > 1 && argv[1] == "animation_test"s) + engine->screens().enter(); else engine->screens().enter(); } void onFrame() { engine->on_frame(); } - void shutdown() { engine.reset(); } + void shutdown() + { + global_commands.reset(); + engine.reset(); + } } // namespace diff --git a/src/demo/src/meta_system.cpp b/src/demo/src/meta_system.cpp index f6b8278827236750ed8718b51aef89c5ec75cca2..5889d925dd0a0c461435c3d6923e5998318d772e 100644 --- a/src/demo/src/meta_system.cpp +++ b/src/demo/src/meta_system.cpp @@ -8,14 +8,37 @@ namespace mirrage { + using namespace ecs::components; Meta_system::Meta_system(Game_engine& engine) : _entities(engine.assets(), this) - , _renderer(engine.renderer_factory().create_renderer(_entities)) + , _renderer(engine.renderer_factory().create_renderer(_entities, engine.render_pass_mask())) , _model_loading(std::make_unique(_entities, engine.assets())) , _nims(std::make_unique(_entities)) { _entities.register_component_type(); + + _commands.add("reload | Reloads most assets", [&] { engine.assets().reload(); }); + + _commands.add("ecs.emplace | Creates a new entity in front of the current camera", + [&](std::string blueprint) { + auto pos = glm::vec3(0, 0, 0); + float prio = -1.f; + for(auto&& [transform, cam] : + _entities.list()) { + if(cam.priority() > prio) { + prio = cam.priority(); + pos = transform.position + transform.direction() * 2.f; + } + } + _entities.entity_builder(blueprint).position(pos).create(); + }); + + _commands.add("mem.renderer | Prints memory usage of renderer", [&] { + auto msg = std::stringstream(); + _renderer->device().print_memory_usage(msg); + LOG(plog::info) << "Renderer Memory usage: " << msg.str(); + }); } Meta_system::~Meta_system() diff --git a/src/demo/src/meta_system.hpp b/src/demo/src/meta_system.hpp index 698197c692da4e4e93f2b4825194602d0decb75b..8671299f15136ef33f9c4b93dc328b04166020bc 100644 --- a/src/demo/src/meta_system.hpp +++ b/src/demo/src/meta_system.hpp @@ -3,6 +3,7 @@ #include "game_engine.hpp" #include +#include namespace mirrage { @@ -36,5 +37,6 @@ namespace mirrage { std::unique_ptr _renderer; std::unique_ptr _model_loading; std::unique_ptr _nims; + util::Console_command_container _commands; }; } // namespace mirrage diff --git a/src/demo/src/systems/nim_system.cpp b/src/demo/src/systems/nim_system.cpp index ee32af163befb4efed3fa1c4a405fdbbde4435a3..9bb8ec2b50aa9bcaa3c7c544373c4f665c2f6d95 100644 --- a/src/demo/src/systems/nim_system.cpp +++ b/src/demo/src/systems/nim_system.cpp @@ -80,9 +80,9 @@ namespace mirrage::systems { state.orientations.emplace_back(iter->second.orientation); state.light_colors.emplace_back(iter->second.light_color); } else if(state.positions.empty()) { - state.positions.emplace_back(0, 0, 0); - state.orientations.emplace_back(1, 0, 0, 0); - state.light_colors.emplace_back(1, 0.938374f, 0.88349f, 100.f); + state.positions.emplace_back(0.0f, 0.0f, 0.0f); + state.orientations.emplace_back(1.0f, 0.0f, 0.0f, 0.0f); + state.light_colors.emplace_back(1.0f, 0.938374f, 0.88349f, 100.f); } else { state.positions.emplace_back(glm::vec3(state.positions.back())); state.orientations.emplace_back(glm::quat(state.orientations.back())); diff --git a/src/demo/src/test_animation_screen.cpp b/src/demo/src/test_animation_screen.cpp new file mode 100644 index 0000000000000000000000000000000000000000..106629546e57f0e9af42081b456e3bd4236a0397 --- /dev/null +++ b/src/demo/src/test_animation_screen.cpp @@ -0,0 +1,160 @@ +#include "test_animation_screen.hpp" + +#include +#include + + +namespace mirrage { + using namespace ecs::components; + using namespace util::unit_literals; + using namespace graphic; + + Test_animation_screen::Test_animation_screen(Engine& engine) : Test_screen(engine) + { + _animation_test_dqs = _meta_system.entities() + .entity_builder("monk") + .position({-8, 0, -0.5f - 1.f}) + .direction(glm::vec3{-1, 0, 0}) + .create(); + + _animation_test_lbs = _meta_system.entities() + .entity_builder("monk_lbs") + .position({-8, 0, -0.5f + 1.f}) + .direction(glm::vec3{-1, 0, 0}) + .create(); + + + _animation_test2_dqs = _meta_system.entities() + .entity_builder("rotation_test") + .position({-4, 0, -0.5f - 1.f}) + .create(); + + _animation_test2_lbs = _meta_system.entities() + .entity_builder("rotation_test_lbs") + .position({-4, 0, -0.5f + 1.f}) + .create(); + } + + void Test_animation_screen::_draw() + { + auto anim_mb = _animation_test_dqs.get(); + auto anim_lbs_mb = _animation_test_lbs.get(); + if(anim_mb.is_nothing()) + return; + + auto& anim = anim_mb.get_or_throw(); + + ImGui::PositionNextWindow( + {300, 500}, ImGui::WindowPosition_X::right, ImGui::WindowPosition_Y::center); + if(ImGui::Begin("Animation")) { + ImGui::TextUnformatted("Animation"); + + auto animations_strs = std::array{ + {"[None]", "Attack", "Dance", "Die", "Flee", "Idle", "Sad", "Sleep", "Walk"}}; + auto animations_ids = std::array{{""_strid, + "attack"_strid, + "dance"_strid, + "die"_strid, + "flee"_strid, + "idle"_strid, + "sad"_strid, + "sleep"_strid, + "walk"_strid}}; + (void) animations_ids; + + auto curr_animation_id = anim.animation_id().get_or(""_strid); + auto curr_idx = int(std::distance( + animations_ids.begin(), + std::find(animations_ids.begin(), animations_ids.end(), curr_animation_id))); + + if(ImGui::Combo("Animation", &curr_idx, animations_strs.data(), int(animations_strs.size()))) { + anim.play(animations_ids.at(std::size_t(curr_idx))); + anim_lbs_mb.process([&](auto& anim) { anim.play(animations_ids.at(std::size_t(curr_idx))); }); + } + + anim.animation().process([&](auto& curr_animation) { + auto& dqs_anim = _animation_test_dqs.get().get_or_throw(); + auto& dqs_states = dqs_anim.states(); + auto& lbs_anim = _animation_test_lbs.get().get_or_throw(); + auto& lbs_states = lbs_anim.states(); + + auto time = 0.f; + auto curr_dqs_state = std::find_if(dqs_states.begin(), dqs_states.end(), [&](auto& s) { + return &*s.animation == &*curr_animation; + }); + auto curr_lbs_state = std::find_if(lbs_states.begin(), lbs_states.end(), [&](auto& s) { + return &*s.animation == &*curr_animation; + }); + + if(curr_dqs_state != dqs_states.end()) { + time = curr_dqs_state->time; + } else if(curr_lbs_state != lbs_states.end()) { + time = curr_dqs_state->time; + } + + auto duration = curr_animation->duration(); + + auto new_time = ImGui::ValueSliderFloat("Time", time, 0.f, duration); + if(std::abs(new_time - time) > 0.00001f) { + dqs_anim.mark_dirty(); + lbs_anim.mark_dirty(); + + if(curr_dqs_state != dqs_states.end()) + curr_dqs_state->time = new_time; + + if(curr_lbs_state != lbs_states.end()) + curr_lbs_state->time = new_time; + } + + ImGui::TextUnformatted( + (util::to_string(new_time) + " / " + util::to_string(duration)).c_str()); + + anim.speed(ImGui::ValueSliderFloat("Speed", anim.speed(), 0.f, 5.f)); + + + if(anim.paused()) + anim.pause(!ImGui::Button("Continue")); + else + anim.pause(ImGui::Button("Pause")); + + ImGui::SameLine(); + + if(anim.reversed()) + anim.reverse(!ImGui::Button("Reverse (->)")); + else + anim.reverse(ImGui::Button("Reverse (<-)")); + + ImGui::SameLine(); + + if(anim.looped()) + anim.loop(!ImGui::Button("Once")); + else + anim.loop(ImGui::Button("Repeat")); + + + anim_lbs_mb.process([&](auto& anim_lbs) { + anim_lbs.speed(anim.speed()); + anim_lbs.pause(anim.paused()); + anim_lbs.reverse(anim.reversed()); + anim_lbs.loop(anim.looped()); + }); + }); + } + + ImGui::TextUnformatted("Rotation Test"); + _animation_test2_dqs.get().process([&](auto& anim) { + if(anim.paused()) + anim.pause(!ImGui::Button("Continue")); + else + anim.pause(ImGui::Button("Pause")); + + _animation_test2_lbs.get().process( + [&](auto& anim_lbs) { anim_lbs.pause(anim.paused()); }); + }); + + ImGui::End(); + + Test_screen::_draw(); + } + +} // namespace mirrage diff --git a/src/demo/src/test_animation_screen.hpp b/src/demo/src/test_animation_screen.hpp new file mode 100644 index 0000000000000000000000000000000000000000..ce132119a0101c1f3b57d996396fc27b6acbbb44 --- /dev/null +++ b/src/demo/src/test_animation_screen.hpp @@ -0,0 +1,40 @@ +/** The main menu ************************************************************ + * * + * Copyright (c) 2016 Florian Oetke * + * This file is distributed under the MIT License * + * See LICENSE file for details. * +\*****************************************************************************/ + +#pragma once + +#include "test_screen.hpp" + +#include +#include +#include +#include + + +namespace mirrage { + + class Test_animation_screen : public Test_screen { + public: + Test_animation_screen(Engine& engine); + + auto name() const -> std::string override { return "Test_animation"; } + + protected: + void _draw() override; + + auto _prev_screen_policy() const noexcept -> Prev_screen_policy override + { + return Prev_screen_policy::discard; + } + + private: + ecs::Entity_facet _animation_test_dqs; + ecs::Entity_facet _animation_test_lbs; + ecs::Entity_facet _animation_test2_dqs; + ecs::Entity_facet _animation_test2_lbs; + }; +} // namespace mirrage diff --git a/src/demo/src/test_screen.cpp b/src/demo/src/test_screen.cpp index e7ea2144f655936404edf1d0165ff448393b0d75..79ce146427a7bef972cf703c6e8b5fcfc75bffcb 100644 --- a/src/demo/src/test_screen.cpp +++ b/src/demo/src/test_screen.cpp @@ -9,10 +9,6 @@ #include #include -#ifdef HPC_HISTOGRAM_DEBUG_VIEW -#include -#endif - #include #include #include @@ -30,20 +26,6 @@ #include - -template -void quick_exit(int) noexcept -{ - std::abort(); -} -void mirrage_quick_exit() noexcept -{ - using namespace std; - // calls std::quick_exit if it exists or the template-fallback defined above, if not - // needs to be at global scope for this workaround to work correctly - quick_exit(0); -} - namespace mirrage { using namespace ecs::components; using namespace util::unit_literals; @@ -82,46 +64,39 @@ namespace mirrage { , _meta_system(static_cast(engine)) , _gui(engine.gui()) , _performance_log(util::nothing) - , _window_width(engine.window().width()) - , _window_height(engine.window().height()) - , _window_fullscreen(engine.window().fullscreen() != graphic::Fullscreen::no) { + _meta_system.entities().entity_builder("cornell").position({1000, 0, 0}).create(); - _animation_test_dqs = _meta_system.entities().emplace("monk"); - _animation_test_dqs.get().process([](auto& transform) { - transform.position = {-8, 0, -0.5f - 1.f}; - transform.orientation = glm::quatLookAt(glm::vec3{-1, 0, 0}, glm::vec3{0, 1, 0}); - }); - - _animation_test_lbs = _meta_system.entities().emplace("monk_lbs"); - _animation_test_lbs.get().process([](auto& transform) { - transform.position = {-8, 0, -0.5f + 1.f}; - transform.orientation = glm::quatLookAt(glm::vec3{-1, 0, 0}, glm::vec3{0, 1, 0}); - }); + _cmd_commands.add_property("pos", + [&](glm::vec3 position) { + _camera.get().process( + [&](auto& transform) { transform.position = position; }); + }, + [&]() { + return _camera.get().process( + glm::vec3(0, 0, 0), + [&](auto& transform) { return transform.position; }); + }); + _meta_system.entities().entity_builder("sponza").create(); - _animation_test2_dqs = _meta_system.entities().emplace("rotation_test"); - _animation_test2_dqs.get().process([](auto& transform) { - transform.position = {-4, 0, -0.5f - 1.f}; - }); + _meta_system.entities().entity_builder("test_particle_emitter").position({-6, 2, 1}).create(); + _meta_system.entities().entity_builder("test_smoke_emitter").position({-6, 1, -1}).create(); - _animation_test2_lbs = _meta_system.entities().emplace("rotation_test_lbs"); - _animation_test2_lbs.get().process([](auto& transform) { - transform.position = {-4, 0, -0.5f + 1.f}; - }); + _meta_system.entities() + .entity_builder("billboard") + .position({-8, 1, 0.5f}) + .direction({-1, 0, 0}) + .create(); + _meta_system.entities().entity_builder("decal").position({-8, 0, -0.5f}).create(); + _sun = _meta_system.entities().entity_builder("sun").create(); - _camera = _meta_system.entities().emplace("camera"); - - auto cornell = _meta_system.entities().emplace("cornell"); - cornell.get().process([&](auto& transform) { transform.position = {1000, 0, 0}; }); - - _meta_system.entities().emplace("sponza"); - - _sun = _meta_system.entities().emplace("sun"); - - _set_preset(1); + _camera = _meta_system.entities() + .entity_builder("camera") + .post_create([&](auto&&) { _set_preset(1); }) + .create(); _mailbox.subscribe_to([&](input::Once_action& e) { switch(e.id) { @@ -133,20 +108,15 @@ namespace mirrage { _engine.screens().leave(); } break; - case "fast_quit"_strid: - _meta_system.renderer().device().wait_idle(); - std::this_thread::sleep_for(std::chrono::milliseconds(250)); - mirrage_quick_exit(); - break; - - case "create"_strid: - _meta_system.entities().emplace("cube").get().process( - [&](auto& transform) { - auto& cam = _camera.get().get_or_throw(); - transform.position = cam.position + cam.direction(); - }); + case "create"_strid: { + auto& cam = _camera.get().get_or_throw(); + _meta_system.entities() + .entity_builder("cube") + .position(cam.position + cam.direction()) + .create(); break; + } case "print"_strid: { auto cam = _camera.get().get_or_throw().position; @@ -182,6 +152,7 @@ namespace mirrage { case "pause"_strid: LOG(plog::debug) << "Pause/Unpause playback"; _meta_system.nims().toggle_pause(); + _paused = !_paused; break; case "toggle_ui"_strid: _show_ui = !_show_ui; break; @@ -304,7 +275,7 @@ namespace mirrage { }); _look = {0.f, 0.f}; - _meta_system.update(dt); + _meta_system.update(_paused ? util::Time(0.001f) : dt); _performance_log.process([&](auto& log) { _performance_log_delay_left -= dt; @@ -348,15 +319,6 @@ namespace mirrage { { if(_show_ui) { _draw_settings_window(); - _draw_histogram_window(); - _draw_animation_window(); - - if(_show_profiler) { - _meta_system.renderer().profiler().enable(); - _draw_profiler_window(); - } else { - _meta_system.renderer().profiler().disable(); - } } _meta_system.renderer().debug_draw({renderer::Debug_geometry{{0, 1, 0}, {0, 5, 0}, {1, 0, 0}}, @@ -366,16 +328,10 @@ namespace mirrage { } void Test_screen::_draw_settings_window() { - auto ctx = _gui.ctx(); - if(nk_begin_titled(ctx, - "debug_controls", - "Debug Controls", - _gui.centered_left(250, 720), - NK_WINDOW_BORDER | NK_WINDOW_MOVABLE | NK_WINDOW_TITLE | NK_WINDOW_MINIMIZABLE)) { + ImGui::PositionNextWindow({250, 400}, ImGui::WindowPosition_X::left, ImGui::WindowPosition_Y::center); + if(ImGui::Begin("Debug Controls")) { - nk_layout_row_dynamic(ctx, 20, 2); - - nk_label(ctx, "Preset", NK_TEXT_LEFT); + ImGui::TextUnformatted("Preset"); auto preset_options = std::array{{"Free Motion", "Center", "Top-Down", @@ -383,34 +339,26 @@ namespace mirrage { "Hallway", "Hallway2", "Cornell Box"}}; - _set_preset(nk_combo(ctx, - preset_options.data(), - preset_options.size(), - _selected_preset, - 14, - nk_vec2(100.f, 200))); - - - nk_layout_row_dynamic(ctx, 20, 1); - auto show_profiler = _show_profiler ? 1 : 0; - if(nk_checkbox_label(ctx, "Show Profiler", &show_profiler)) { - _show_profiler = show_profiler == 1; - } + ImGui::Combo("preset", &_selected_preset, preset_options.data(), int(preset_options.size())); - if(!_meta_system.nims().is_playing()) { - nk_layout_row_dynamic(ctx, 20, 1); - nk_label(ctx, "Directional Light", NK_TEXT_LEFT); - nk_layout_row_dynamic(ctx, 14, 1); + _camera.process([&](auto& cam) { + cam.dof_focus(ImGui::ValueSliderFloat("Focus Plane", cam.dof_focus(), 0.1f, 100.f)); + cam.dof_range(ImGui::ValueSliderFloat("Focus Range", cam.dof_range(), 0.1f, 10.f)); + cam.dof_power(ImGui::ValueSliderFloat("DOF Power", cam.dof_power(), 0.01f, 1.f)); + }); + + if(!_meta_system.nims().is_playing()) { + ImGui::TextUnformatted("Directional Light"); - auto elevation = nk_propertyf(ctx, "Elevation", 0.f, _sun_elevation, 1.f, 0.05f, 0.001f); + auto elevation = ImGui::ValueSliderFloat("Elevation", _sun_elevation, 0.f, 1.f); if(std::abs(elevation - _sun_elevation) > 0.000001f) { _sun_elevation = elevation; _set_preset(0); } - auto azimuth = nk_propertyf(ctx, "Azimuth", -2.f, _sun_azimuth, 2.f, 0.05f, 0.001f); + auto azimuth = ImGui::ValueSliderFloat("Azimuth", _sun_azimuth, -2.f, 2.f); if(std::abs(azimuth - _sun_azimuth) > 0.000001f) { _sun_azimuth = azimuth; _set_preset(0); @@ -420,445 +368,30 @@ namespace mirrage { _sun.get().process( [&](renderer::Directional_light_comp& light) { - auto new_size = nk_propertyf( - ctx, "Size", 0.5f, light.source_radius() / 1_m, 20.f, 0.1f, 0.01f); + auto new_size = + ImGui::ValueSliderFloat("Size", light.source_radius() / 1_m, 0.5f, 20.f); light.source_radius(new_size * 1_m); - auto new_temp = nk_propertyf( - ctx, "Color", 500.f, _sun_color_temperature, 20000.f, 500.f, 50.f); + auto new_temp = + ImGui::ValueSliderFloat("Color", _sun_color_temperature, 500.f, 20000.f); if(std::abs(new_temp - _sun_color_temperature) > 0.000001f) { light.temperature(_sun_color_temperature = new_temp); _set_preset(0); } - auto color = util::Rgba{light.color(), light.intensity() / 50'000.f}; - if(gui::color_picker(ctx, color, 210.f)) { + ImGui::Spacing(); + ImGui::TextUnformatted("Color"); + auto color = util::Rgba{light.color(), light.intensity() / 50000.f}; + if(ImGui::ColorPicker4("Color", &color.r)) { light.color({color.r, color.g, color.b}); - light.intensity(color.a * 50'000.f); + light.intensity(color.a * 50000.f); _set_preset(0); } }); } - - nk_layout_row_dynamic(ctx, 10, 1); - nk_label(ctx, "", NK_TEXT_LEFT); - - nk_layout_row_dynamic(ctx, 20, 1); - nk_label(ctx, "Graphic Settings", NK_TEXT_LEFT); - auto renderer_settings = _meta_system.renderer().settings(); - auto bool_nk_wrapper = 0; - - nk_property_int(ctx, "Window Width", 640, &_window_width, 7680, 1, 1); - nk_property_int(ctx, "Window Height", 360, &_window_height, 4320, 1, 1); - - bool_nk_wrapper = _window_fullscreen ? 1 : 0; - nk_checkbox_label(ctx, "Fullscreen", &bool_nk_wrapper); - _window_fullscreen = bool_nk_wrapper == 1; - - if(nk_button_label(ctx, "Apply")) { - if(_window_width != _engine.window().width() || _window_height != _engine.window().height() - || _window_fullscreen != (_engine.window().fullscreen() != graphic::Fullscreen::no)) { - _engine.window().dimensions(_window_width, - _window_height, - _window_fullscreen ? graphic::Fullscreen::yes_borderless - : graphic::Fullscreen::no); - } - } - - nk_layout_row_dynamic(ctx, 10, 1); - nk_label(ctx, "", NK_TEXT_LEFT); - nk_layout_row_dynamic(ctx, 20, 1); - - nk_label(ctx, "Renderer Settings", NK_TEXT_LEFT); - - nk_layout_row_dynamic(ctx, 20, 1); - nk_property_int(ctx, "Debug Layer", -1, &renderer_settings.debug_gi_layer, 5, 1, 1); - - bool_nk_wrapper = renderer_settings.gi ? 1 : 0; - nk_checkbox_label(ctx, "Indirect Illumination", &bool_nk_wrapper); - renderer_settings.gi = bool_nk_wrapper == 1; - - bool_nk_wrapper = renderer_settings.gi_shadows ? 1 : 0; - nk_checkbox_label(ctx, "Indirect Shadows", &bool_nk_wrapper); - renderer_settings.gi_shadows = bool_nk_wrapper == 1; - - bool_nk_wrapper = renderer_settings.gi_highres ? 1 : 0; - nk_checkbox_label(ctx, "High-Resolution GI", &bool_nk_wrapper); - renderer_settings.gi_highres = bool_nk_wrapper == 1; - - nk_property_int(ctx, "Minimum GI MIP", 0, &renderer_settings.gi_min_mip_level, 4, 1, 1); - - nk_property_int(ctx, "Diffuse GI MIP", 0, &renderer_settings.gi_diffuse_mip_level, 4, 1, 1); - - nk_property_int(ctx, "Low-Res Sample Count", 8, &renderer_settings.gi_lowres_samples, 1024, 1, 1); - - nk_property_int(ctx, "Sample Count", 8, &renderer_settings.gi_samples, 1024, 1, 1); - - nk_property_float( - ctx, "Exposure", 0.f, &renderer_settings.exposure_override, 50.f, 0.001f, 0.01f); - - nk_property_float( - ctx, "Background Brightness", 0.f, &renderer_settings.background_intensity, 10.f, 1, 0.1f); - - bool_nk_wrapper = renderer_settings.ssao ? 1 : 0; - nk_checkbox_label(ctx, "Ambient Occlusion", &bool_nk_wrapper); - renderer_settings.ssao = bool_nk_wrapper == 1; - - bool_nk_wrapper = renderer_settings.bloom ? 1 : 0; - nk_checkbox_label(ctx, "Bloom", &bool_nk_wrapper); - renderer_settings.bloom = bool_nk_wrapper == 1; - - bool_nk_wrapper = renderer_settings.tonemapping ? 1 : 0; - nk_checkbox_label(ctx, "Tonemapping", &bool_nk_wrapper); - renderer_settings.tonemapping = bool_nk_wrapper == 1; - - - nk_layout_row_dynamic(ctx, 20, 2); - - if(nk_button_label(ctx, "Apply")) { - if(_window_width != _engine.window().width() || _window_height != _engine.window().height() - || _window_fullscreen != (_engine.window().fullscreen() != graphic::Fullscreen::no)) { - _engine.window().dimensions(_window_width, - _window_height, - _window_fullscreen ? graphic::Fullscreen::yes_borderless - : graphic::Fullscreen::no); - } - _meta_system.renderer().settings(renderer_settings, true); - } else { - _meta_system.renderer().settings(renderer_settings, false); - } - - if(nk_button_label(ctx, "Reset")) { - _meta_system.renderer().settings(renderer::Renderer_settings{}, true); - } - } - nk_end(ctx); - } - - namespace { - template - auto to_fixed_str(T num, int digits) - { - auto ss = std::stringstream{}; - ss << std::fixed << std::setprecision(digits) << num; - return ss.str(); - } - - auto pad_left(const std::string& str, int padding) - { - return std::string(std::size_t(padding), ' ') + str; - } - - template - auto top_n(const Container& container, Comp&& less) - { - auto max_elements = std::array(); - max_elements.fill(container.end()); - - for(auto iter = container.begin(); iter != container.end(); iter++) { - // compare with each of the top elements - for(auto i = std::size_t(0); i < N; i++) { - if(max_elements[i] == container.end() || less(*max_elements[i], *iter)) { - // move top elements to make room - for(auto j = i + 1; j < N; j++) { - max_elements[j] = max_elements[j - 1]; - } - max_elements[i] = iter; - break; - } - } - } - - return max_elements; - } - - template - auto index_of(const Container& container, const T& element) -> int - { - auto top_entry = std::find(container.begin(), container.end(), element); - if(top_entry == container.end()) - return -1; - - return gsl::narrow(std::distance(container.begin(), top_entry)); - } - } // namespace - void Test_screen::_draw_profiler_window() - { - auto ctx = _gui.ctx(); - if(nk_begin_titled(ctx, - "profiler", - "Profiler", - _gui.centered_right(330, 380), - NK_WINDOW_BORDER | NK_WINDOW_MOVABLE | NK_WINDOW_TITLE | NK_WINDOW_MINIMIZABLE)) { - - nk_layout_row_dynamic(ctx, 20, 1); - if(nk_button_label(ctx, "Reset")) { - _meta_system.renderer().profiler().reset(); - } - -#if 0 - if(_performance_log.is_nothing() && nk_button_label(ctx, "Record")) { - _performance_log = _engine.assets().save_raw("log:perf.log"_aid); - } -#endif - - constexpr auto rows = std::array{{0.4f, 0.15f, 0.15f, 0.15f, 0.15f}}; - nk_layout_row(ctx, NK_DYNAMIC, 25, rows.size(), rows.data()); - nk_label(ctx, "RenderPass", NK_TEXT_CENTERED); - nk_label(ctx, "Curr (ms)", NK_TEXT_CENTERED); - nk_label(ctx, "Min (ms)", NK_TEXT_CENTERED); - nk_label(ctx, "Avg (ms)", NK_TEXT_CENTERED); - nk_label(ctx, "Max (ms)", NK_TEXT_CENTERED); - - nk_layout_row(ctx, NK_DYNAMIC, 10, rows.size(), rows.data()); - - - auto print_entry = - [&](auto&& printer, const Profiler_result& result, int depth = 0, int rank = -1) -> void { - auto color = [&] { - switch(rank) { - case 0: return nk_rgb(255, 0, 0); - case 1: return nk_rgb(255, 220, 128); - default: return nk_rgb(255, 255, 255); - } - }(); - - nk_label_colored(ctx, pad_left(result.name(), depth * 4).c_str(), NK_TEXT_LEFT, color); - nk_label_colored(ctx, to_fixed_str(result.time_ms(), 2).c_str(), NK_TEXT_RIGHT, color); - nk_label_colored(ctx, to_fixed_str(result.time_min_ms(), 2).c_str(), NK_TEXT_RIGHT, color); - nk_label_colored(ctx, to_fixed_str(result.time_avg_ms(), 2).c_str(), NK_TEXT_RIGHT, color); - nk_label_colored(ctx, to_fixed_str(result.time_max_ms(), 2).c_str(), NK_TEXT_RIGHT, color); - - - auto worst_timings = top_n<2>( - result, [](auto&& lhs, auto&& rhs) { return lhs.time_avg_ms() < rhs.time_avg_ms(); }); - - for(auto iter = result.begin(); iter != result.end(); iter++) { - auto rank = index_of(worst_timings, iter); - printer(printer, *iter, depth + 1, rank); - } - }; - - auto& result = _meta_system.renderer().profiler().results(); - print_entry(print_entry, result); - } - - nk_end(ctx); - } - - void Test_screen::_draw_histogram_window() - { -#ifdef HPC_HISTOGRAM_DEBUG_VIEW - - auto tone_mapping_pass = _meta_system.renderer().find_pass(); - if(tone_mapping_pass) { - auto&& histogram = tone_mapping_pass->last_histogram(); - auto histogram_sum = std::accumulate(begin(histogram), end(histogram) - 2, 0.0); - auto max_histogram = std::max_element(begin(histogram), end(histogram) - 2); - - auto ctx = _gui.ctx(); - if(nk_begin_titled( - ctx, - "Histogram", - "Histogram", - _gui.centered_right(400, 600), - NK_WINDOW_BORDER | NK_WINDOW_MOVABLE | NK_WINDOW_TITLE | NK_WINDOW_MINIMIZABLE)) { - - nk_layout_row_dynamic(ctx, 400, 1); - nk_chart_begin( - ctx, NK_CHART_COLUMN, static_cast(histogram.size() - 2), 0, *max_histogram); - for(auto i : util::range(histogram.size() - 1)) { - auto state = nk_chart_push(ctx, histogram[i]); - if(state & NK_CHART_HOVERING) { - _last_selected_histogram = i; - } - } - nk_chart_end(ctx); - - nk_layout_row_dynamic(ctx, 25, 2); - nk_label(ctx, "Luminance", NK_TEXT_CENTERED); - auto log_lum_range = std::log(_meta_system.renderer().gbuffer().max_luminance) - - std::log(_meta_system.renderer().gbuffer().min_luminance); - auto log_lum = float(_last_selected_histogram) / float(histogram.size() - 1) * log_lum_range - + std::log(_meta_system.renderer().gbuffer().min_luminance); - auto lum = std::exp(log_lum); - nk_label(ctx, to_fixed_str(lum, 5).c_str(), NK_TEXT_CENTERED); - - auto percentage = static_cast(histogram[_last_selected_histogram]) - / std::max(1.0, histogram_sum); - nk_label(ctx, "Percentage", NK_TEXT_CENTERED); - nk_label(ctx, (to_fixed_str(percentage * 100, 4) + " %").c_str(), NK_TEXT_CENTERED); - - nk_label(ctx, "La", NK_TEXT_CENTERED); - nk_label(ctx, (to_fixed_str(histogram[histogram.size() - 2], 4)).c_str(), NK_TEXT_CENTERED); - nk_label(ctx, "p(La)", NK_TEXT_CENTERED); - nk_label(ctx, - (to_fixed_str(1.f - histogram[histogram.size() - 1], 4)).c_str(), - NK_TEXT_CENTERED); - - nk_label(ctx, "Trimmings", NK_TEXT_CENTERED); - nk_label(ctx, - std::to_string( - static_cast(tone_mapping_pass->max_histogram_size() - histogram_sum)) - .c_str(), - NK_TEXT_CENTERED); - - auto renderer_settings = _meta_system.renderer().settings(); - - nk_property_float(ctx, - "Min Display Lum.", - 1.f / 255.f / 4.f, - &renderer_settings.min_display_luminance, - 500.f, - 0.001f, - 0.01f); - nk_property_float(ctx, - "Max Display Lum.", - 1.f / 255.f / 4.f, - &renderer_settings.max_display_luminance, - 500.f, - 0.001f, - 0.01f); - - _meta_system.renderer().settings(renderer_settings, false); - } - - nk_end(ctx); } -#endif - } - - void Test_screen::_draw_animation_window() - { - auto anim_mb = _animation_test_dqs.get(); - auto anim_lbs_mb = _animation_test_lbs.get(); - if(anim_mb.is_nothing()) - return; - - auto& anim = anim_mb.get_or_throw(); - - auto ctx = _gui.ctx(); - if(nk_begin_titled(ctx, - "Animation", - "Animation", - _gui.centered_right(300, 500), - NK_WINDOW_BORDER | NK_WINDOW_MOVABLE | NK_WINDOW_TITLE | NK_WINDOW_MINIMIZABLE)) { - - nk_layout_row_dynamic(ctx, 20, 1); - - nk_label(ctx, "Animation", NK_TEXT_LEFT); - auto animations_strs = std::array{ - {"[None]", "Attack", "Dance", "Die", "Flee", "Idle", "Sad", "Sleep", "Walk"}}; - auto animations_ids = std::array{{""_strid, - "attack"_strid, - "dance"_strid, - "die"_strid, - "flee"_strid, - "idle"_strid, - "sad"_strid, - "sleep"_strid, - "walk"_strid}}; - (void) animations_ids; - - auto curr_animation_id = anim.animation_id().get_or(""_strid); - auto curr_idx = - std::distance(animations_ids.begin(), - std::find(animations_ids.begin(), animations_ids.end(), curr_animation_id)); - - auto new_idx = nk_combo(ctx, - animations_strs.data(), - animations_strs.size(), - int(curr_idx), - 14, - nk_vec2(100.f, 200)); - - if(new_idx != curr_idx) { - anim.play(animations_ids.at(std::size_t(new_idx))); - anim_lbs_mb.process([&](auto& anim) { anim.play(animations_ids.at(std::size_t(new_idx))); }); - } - - anim.animation().process([&](auto& curr_animation) { - auto& dqs_anim = _animation_test_dqs.get().get_or_throw(); - auto& dqs_states = dqs_anim.states(); - auto& lbs_anim = _animation_test_lbs.get().get_or_throw(); - auto& lbs_states = lbs_anim.states(); - - auto time = 0.f; - auto curr_dqs_state = std::find_if(dqs_states.begin(), dqs_states.end(), [&](auto& s) { - return &*s.animation == &*curr_animation; - }); - auto curr_lbs_state = std::find_if(lbs_states.begin(), lbs_states.end(), [&](auto& s) { - return &*s.animation == &*curr_animation; - }); - - if(curr_dqs_state != dqs_states.end()) { - time = curr_dqs_state->time; - } else if(curr_lbs_state != lbs_states.end()) { - time = curr_dqs_state->time; - } - - auto duration = curr_animation->duration(); - - nk_label(ctx, "Time", NK_TEXT_LEFT); - auto new_time = nk_slide_float(ctx, 0.f, time, duration, 0.01f); - if(std::abs(new_time - time) > 0.00001f) { - dqs_anim.mark_dirty(); - lbs_anim.mark_dirty(); - - if(curr_dqs_state != dqs_states.end()) - curr_dqs_state->time = new_time; - - if(curr_lbs_state != lbs_states.end()) - curr_lbs_state->time = new_time; - } - - nk_label(ctx, - (util::to_string(new_time) + " / " + util::to_string(duration)).c_str(), - NK_TEXT_LEFT); - - auto speed = anim.speed(); - nk_property_float(ctx, "Speed", 0.f, &speed, 5.f, 0.1f, 0.05f); - anim.speed(speed); - - - if(anim.paused()) - anim.pause(!nk_button_label(ctx, "Continue")); - else - anim.pause(nk_button_label(ctx, "Pause")); - - if(anim.reversed()) - anim.reverse(!nk_button_label(ctx, "Reverse (->)")); - else - anim.reverse(nk_button_label(ctx, "Reverse (<-)")); - - if(anim.looped()) - anim.loop(!nk_button_label(ctx, "Once")); - else - anim.loop(nk_button_label(ctx, "Repeat")); - - - anim_lbs_mb.process([&](auto& anim_lbs) { - anim_lbs.speed(anim.speed()); - anim_lbs.pause(anim.paused()); - anim_lbs.reverse(anim.reversed()); - anim_lbs.loop(anim.looped()); - }); - }); - } - - nk_label(ctx, "Rotation Test", NK_TEXT_LEFT); - _animation_test2_dqs.get().process([&](auto& anim) { - if(anim.paused()) - anim.pause(!nk_button_label(ctx, "Continue")); - else - anim.pause(nk_button_label(ctx, "Pause")); - - _animation_test2_lbs.get().process( - [&](auto& anim_lbs) { anim_lbs.pause(anim.paused()); }); - }); - - nk_end(ctx); + ImGui::End(); } void Test_screen::_update_sun_position() diff --git a/src/demo/src/test_screen.hpp b/src/demo/src/test_screen.hpp index 9a29c9f07edac3a36da90ec37e64586014be561b..9d22051b21ea4cec775d4ba758e76ff934434464 100644 --- a/src/demo/src/test_screen.hpp +++ b/src/demo/src/test_screen.hpp @@ -13,6 +13,7 @@ #include #include #include +#include #include @@ -23,6 +24,8 @@ namespace mirrage { Test_screen(Engine& engine); ~Test_screen() noexcept; + auto name() const -> std::string override { return "Test"; } + protected: void _update(util::Time delta_time) override; void _draw() override; @@ -35,7 +38,7 @@ namespace mirrage { return Prev_screen_policy::discard; } - private: + protected: util::Mailbox_collection _mailbox; Meta_system _meta_system; @@ -44,10 +47,6 @@ namespace mirrage { ecs::Entity_facet _camera; ecs::Entity_facet _sun; - ecs::Entity_facet _animation_test_dqs; - ecs::Entity_facet _animation_test_lbs; - ecs::Entity_facet _animation_test2_dqs; - ecs::Entity_facet _animation_test2_lbs; float _sun_elevation = 0.92f; float _sun_azimuth = 1.22f; @@ -57,6 +56,8 @@ namespace mirrage { glm::vec3 _move{}; bool _mouse_look = false; + bool _paused = false; + float _cam_yaw = 0; float _cam_pitch = 0; @@ -66,23 +67,17 @@ namespace mirrage { util::Time _record_timer{0}; bool _show_ui = true; - bool _show_profiler = false; std::size_t _last_selected_histogram = 0; util::maybe _performance_log; util::Time _performance_log_delay_left{1}; bool _preformance_log_first_row = true; - int _window_width; - int _window_height; - bool _window_fullscreen; + util::Console_command_container _cmd_commands; void _set_preset(int); void _update_sun_position(); void _draw_settings_window(); - void _draw_profiler_window(); - void _draw_histogram_window(); - void _draw_animation_window(); }; } // namespace mirrage diff --git a/src/mesh_converter/CMakeLists.txt b/src/mesh_converter/CMakeLists.txt index 3f3aa111526cd79aed64c58b18e0542c56d328b8..82680c481294824520231d0634e447c7599d8904 100644 --- a/src/mesh_converter/CMakeLists.txt +++ b/src/mesh_converter/CMakeLists.txt @@ -1,11 +1,11 @@ -cmake_minimum_required(VERSION 3.2 FATAL_ERROR) +cmake_minimum_required(VERSION 3.9 FATAL_ERROR) project(mirrage_mesh_converter LANGUAGES CXX) - add_executable(mesh_converter animation_parser.cpp animation_parser.hpp + common.cpp common.hpp filesystem.cpp filesystem.hpp @@ -18,8 +18,10 @@ add_executable(mesh_converter skeleton_parser.hpp ${BACKWARD_ENABLE} ) - -add_backward(mesh_converter) +if(${MIRRAGE_ENABLE_BACKWARD}) + add_backward(mesh_converter) +endif() +target_compile_features(mesh_converter PUBLIC cxx_std_17) target_link_libraries(mesh_converter PRIVATE @@ -30,5 +32,6 @@ target_link_libraries(mesh_converter sf2 stb_image doctest + crunch::crunch + Async++ ) - diff --git a/src/mesh_converter/common.cpp b/src/mesh_converter/common.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3514bda97cf8f218ce9241b202ed064b15e206c9 --- /dev/null +++ b/src/mesh_converter/common.cpp @@ -0,0 +1,6 @@ +#include "common.hpp" + +namespace mirrage { + std::atomic parallel_tasks_started = 0; + std::atomic parallel_tasks_done = 0; +} // namespace mirrage diff --git a/src/mesh_converter/common.hpp b/src/mesh_converter/common.hpp index d5fd2f37b00b6c34f5178cf630d2de36510e7bde..9ad80e4b6b0077cea74b9e447129f0ed377f2abc 100644 --- a/src/mesh_converter/common.hpp +++ b/src/mesh_converter/common.hpp @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -17,6 +18,9 @@ namespace mirrage { + extern std::atomic parallel_tasks_started; + extern std::atomic parallel_tasks_done; + sf2_enum(Texture_type, albedo, metalness, roughness, normal, emission); using Texture_mapping = std::unordered_map>; diff --git a/src/mesh_converter/main.cpp b/src/mesh_converter/main.cpp index aa46fe68276c1d093aa49ee0669ad71c93572065..a06b6985f9a3cda4fa33bd548e36b1444e4dd483 100644 --- a/src/mesh_converter/main.cpp +++ b/src/mesh_converter/main.cpp @@ -15,45 +15,54 @@ #include #include +#ifndef __clang_analyzer__ +#include +#endif + +#include #include +#include #include + using namespace mirrage; -auto extract_arg(std::vector& args, const std::string& key) -> util::maybe; +auto extract_arg(std::vector& args, const std::string& key, bool flag = false) + -> util::maybe; auto load_config(const util::maybe& config_arg, const util::maybe& out_arg, const std::string& working_dir, const std::vector& inputs) -> Mesh_converted_config; +constexpr static auto usage_str = "Usage ./mesh_converter [--output=DIR] [--cfg=CFG_FILE] INPUT..."; + // ./mesh_converter sponza.obj // ./mesh_converter --output=/foo/bar sponza.obj int main(int argc, char** argv) { - doctest::Context context; - context.setOption("no-run", true); - context.applyCommandLine(argc, argv); - auto res = context.run(); - if(context.shouldExit()) - return res; - static auto fileAppender = plog::RollingFileAppender("mesh_converter.log", 4L * 1024L, 4); static auto consoleAppender = plog::ColorConsoleAppender(); plog::init(plog::debug, &fileAppender).addAppender(&consoleAppender); - if(argc < 1) { - LOG(plog::error) << "Too few arguments!\n" - << "Usage ./mesh_converter [--output=DIR] INPUT [...]"; + if(argc <= 1) { + LOG(plog::error) << "Too few arguments!\n" << usage_str; return 1; } auto args = std::vector{const_cast(argv + 1), const_cast(argv + argc)}; + if(args[0] == "--help" || args[0] == "-h") { + LOG(plog::info) << usage_str; + return 0; + } + auto output_arg = extract_arg(args, "--output"); auto config_arg = extract_arg(args, "--cfg"); auto config = load_config(extract_arg(args, "--cfg"), output_arg, argv[0], args); + auto normal = extract_arg(args, "--normal", true).is_some(); + auto srgb = !extract_arg(args, "--rg", true).is_some(); auto output = output_arg.get_or(config.default_output_directory); @@ -64,15 +73,27 @@ int main(int argc, char** argv) for(auto&& input : args) { if(util::ends_with(input, ".png")) - convert_texture(input, output); + convert_texture(input, output, normal, srgb); else convert_model(input, output, config); } - return res; + using namespace std::chrono_literals; + + auto last_parallel_tasks_done = std::size_t(0); + while(parallel_tasks_started.load() > parallel_tasks_done.load()) { + if(last_parallel_tasks_done != parallel_tasks_done.load()) { + last_parallel_tasks_done = parallel_tasks_done.load(); + + LOG(plog::info) << "Waiting for background tasks: " << last_parallel_tasks_done << "/" + << parallel_tasks_started.load(); + } + std::this_thread::sleep_for(1s); + } } -auto extract_arg(std::vector& args, const std::string& key) -> util::maybe +auto extract_arg(std::vector& args, const std::string& key, bool flag) + -> util::maybe { auto found = std::find_if(args.begin(), args.end(), [&](auto& str) { return util::starts_with(str, key); }); @@ -80,6 +101,11 @@ auto extract_arg(std::vector& args, const std::string& key) -> util if(found == args.end()) return mirrage::util::nothing; + if(flag) { + args.erase(found); + return util::just(std::string()); + } + // found contains the key and the value if(util::contains(*found, '=') && found->back() != '=') { auto ret = *found; diff --git a/src/mesh_converter/material_parser.cpp b/src/mesh_converter/material_parser.cpp index 97b73763cf09333b4aebdedf805071bbe0679447..84f2c579cd8a090f956d06e8e2cf5b5c1f1f181d 100644 --- a/src/mesh_converter/material_parser.cpp +++ b/src/mesh_converter/material_parser.cpp @@ -9,9 +9,14 @@ #include #include +#include #include #include +#ifndef __clang_analyzer__ +#include +#endif + #include #include #include @@ -22,8 +27,9 @@ using namespace std::string_literals; namespace mirrage { namespace { - constexpr unsigned char type_tag[] = { - 0xAB, 0x4B, 0x54, 0x58, 0x20, 0x31, 0x31, 0xBB, 0x0D, 0x0A, 0x1A, 0x0A}; + constexpr char padding_data[] = {0x0, 0x0, 0x0, 0x0}; + constexpr unsigned char type_tag[] = { + 0xAB, 0x4B, 0x54, 0x58, 0x20, 0x31, 0x31, 0xBB, 0x0D, 0x0A, 0x1A, 0x0A}; struct ktx_header10 { std::uint32_t Endianness; @@ -41,71 +47,43 @@ namespace mirrage { std::uint32_t BytesOfKeyValueData; }; + using rg8 = glm::vec<2, std::uint8_t, glm::highp>; + using rgba8 = glm::vec<4, std::uint8_t, glm::highp>; + using rgba32 = glm::vec<4, float, glm::highp>; template - struct Pixel { - T r; - T g; - T b; - T a; - }; - - template - auto operator+(const Pixel& lhs, const Pixel& rhs) - { - return Pixel{lhs.r + rhs.r, lhs.g + rhs.g, lhs.b + rhs.b, lhs.a + rhs.a}; - } - - template - auto operator*(const Pixel& lhs, T rhs) - { - return Pixel{lhs.r * rhs, lhs.g * rhs, lhs.b * rhs, lhs.a * rhs}; - } - - template - auto operator*(T lhs, const Pixel& rhs) - { - return Pixel{lhs * rhs.r, lhs * rhs.g, lhs * rhs.b, lhs * rhs.a}; - } - - template - auto operator/(const Pixel& lhs, T rhs) - { - return Pixel{lhs.r / rhs, lhs.g / rhs, lhs.b / rhs, lhs.a / rhs}; - } - - - template struct Image_data { - using Pixels = std::vector>; + using Pixels = std::vector; - std::uint32_t width; - std::uint32_t height; + std::int_fast32_t width; + std::int_fast32_t height; std::vector mip_levels; Image_data() = default; - Image_data(std::uint32_t width, std::uint32_t height) - : width(width), height(height), mip_levels(std::floor(std::log2(std::min(width, height))) + 1) + Image_data(std::int_fast32_t width, std::int_fast32_t height) + : width(width) + , height(height) + , mip_levels(std::size_t(util::max(1, std::floor(std::log2(std::min(width, height))) - 1))) { for(auto i = 0u; i < mip_levels.size(); i++) { - auto width = std::max(1u, this->width >> i); - auto height = std::max(1u, this->height >> i); + auto width = std::max(std::int_fast32_t(1), this->width >> i); + auto height = std::max(std::int_fast32_t(1), this->height >> i); - mip_levels[i].resize(width * height); + mip_levels[i].resize(std::size_t(width * height)); } } - auto& pixel(std::uint32_t level, std::uint32_t x, std::uint32_t y) + auto& pixel(std::int_fast32_t level, std::int_fast32_t x, std::int_fast32_t y) { - return mip_levels.at(level).at(y * (width >> level) + x); + return mip_levels.at(std::size_t(level)).at(std::size_t(y * (width >> level) + x)); } template void foreach(F&& f) { for(std::uint32_t i = 0u; i < mip_levels.size(); i++) { - auto width = std::max(1u, this->width >> i); - auto height = std::max(1u, this->height >> i); + auto width = std::max(std::int_fast32_t(1), this->width >> i); + auto height = std::max(std::int_fast32_t(1), this->height >> i); for(std::uint32_t y = 0; y < height; y++) { for(std::uint32_t x = 0; x < width; x++) { f(pixel(i, x, y), i, x, y); @@ -127,7 +105,7 @@ namespace mirrage { return std::string(str.C_Str()); } - auto load_texture2d(const std::string path, bool srgb = true) -> Image_data + auto load_texture2d(const std::string path, bool srgb = true) -> Image_data { int width = 0; int height = 0; @@ -136,15 +114,14 @@ namespace mirrage { ON_EXIT { stbi_image_free(data); }; - auto image = Image_data(width, height); + auto image = Image_data(width, height); for(std::uint32_t y = 0; y < image.height; y++) { for(std::uint32_t x = 0; x < image.width; x++) { - auto pixel = - Pixel{static_cast(data[(y * image.width + x) * 4 + 0]) / 255.f, - static_cast(data[(y * image.width + x) * 4 + 1]) / 255.f, - static_cast(data[(y * image.width + x) * 4 + 2]) / 255.f, - static_cast(data[(y * image.width + x) * 4 + 3]) / 255.f}; + auto pixel = rgba32{static_cast(data[(y * image.width + x) * 4 + 0]) / 255.f, + static_cast(data[(y * image.width + x) * 4 + 1]) / 255.f, + static_cast(data[(y * image.width + x) * 4 + 2]) / 255.f, + static_cast(data[(y * image.width + x) * 4 + 3]) / 255.f}; if(srgb) { pixel.r = std::pow(pixel.r, 1.f / 2.2f); @@ -164,8 +141,8 @@ namespace mirrage { void generate_mip_maps(Image_data& image, F&& f) { for(std::uint32_t i = 1u; i < image.mip_levels.size(); i++) { - auto width = std::max(1u, image.width >> i); - auto height = std::max(1u, image.height >> i); + auto width = util::max(1, image.width >> i); + auto height = util::max(1, image.height >> i); for(std::uint32_t y = 0; y < height; y++) { for(std::uint32_t x = 0; x < width; x++) { image.pixel(i, x, y) = f(image.pixel(i - 1, x * 2, y * 2), @@ -177,9 +154,18 @@ namespace mirrage { } } - void store_texture(Image_data& image, const std::string& ouput, bool srgb = true) + auto to_8bit(float v) -> std::uint8_t + { + return static_cast(glm::clamp(v * 255.f, 0.f, 255.f)); + } + + enum class Texture_format { s_rgba, rg }; + + void store_texture(Image_data image, std::string ouput, Texture_format format) { - if(srgb) { + static constexpr auto cDXTBlockSize = std::int32_t(4); + + if(format == Texture_format::s_rgba) { for(auto& level_data : image.mip_levels) { for(auto& pixel : level_data) { pixel.r = std::pow(pixel.r, 2.2f); @@ -190,59 +176,98 @@ namespace mirrage { } } - auto rgb8_image = Image_data(image.width, image.height); - - for(std::uint32_t i = 0u; i < image.mip_levels.size(); i++) { - auto width = std::max(1u, image.width >> i); - auto height = std::max(1u, image.height >> i); - for(std::uint32_t y = 0; y < height; y++) { - for(std::uint32_t x = 0; x < width; x++) { - auto src = image.pixel(i, x, y); - auto& dst = rgb8_image.pixel(i, x, y); - dst.r = static_cast(glm::clamp(src.r * 255.f, 0.f, 255.f)); - dst.g = static_cast(glm::clamp(src.g * 255.f, 0.f, 255.f)); - dst.b = static_cast(glm::clamp(src.b * 255.f, 0.f, 255.f)); - dst.a = static_cast(glm::clamp(src.a * 255.f, 0.f, 255.f)); - } - } - } - - - // TODO: compression (DXTx/BCx/...). No support in gli and a sparse library support in general - auto out = std::ofstream(ouput, std::ofstream::binary); + const auto crn_format = format == Texture_format::rg ? cCRNFmtDXN_XY : cCRNFmtDXT5; + auto comp_params = crn_comp_params{}; + comp_params.m_format = crn_format; + comp_params.m_dxt_quality = cCRNDXTQualityUber; + comp_params.m_num_helper_threads = 4; + comp_params.set_flag(cCRNCompFlagPerceptual, format == Texture_format::s_rgba); + comp_params.set_flag(cCRNCompFlagDXT1AForTransparency, format == Texture_format::s_rgba); + auto pContext = crn_create_block_compressor(comp_params); + out.write(reinterpret_cast(&type_tag), sizeof(type_tag)); auto header = ktx_header10{}; header.Endianness = 0x04030201; - header.GLType = 0x1401; - header.GLTypeSize = 4; - header.GLFormat = 0x1908; - header.GLInternalFormat = srgb ? 0x8C43 : 0x8058; - header.GLBaseInternalFormat = 0x1908; - header.PixelWidth = image.width; - header.PixelHeight = image.height; + header.GLType = 0; + header.GLTypeSize = 1; + header.GLFormat = 0; + header.GLInternalFormat = 0x8C4F; // GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT + header.GLBaseInternalFormat = 0x1908; // GL_RGBA + header.PixelWidth = std::uint32_t(image.width); + header.PixelHeight = std::uint32_t(image.height); header.PixelDepth = 0; header.NumberOfArrayElements = 0; header.NumberOfFaces = 1; - header.NumberOfMipmapLevels = image.mip_levels.size(); + header.NumberOfMipmapLevels = std::uint32_t(image.mip_levels.size()); header.BytesOfKeyValueData = 0; + if(format == Texture_format::rg) { + header.GLInternalFormat = 0x8DBD; // GL_COMPRESSED_RG_RGTC2 + header.GLBaseInternalFormat = 0x8227; // GL_RG + } + out.write(reinterpret_cast(&header), sizeof(header)); - for(std::uint32_t i = 0; i < rgb8_image.mip_levels.size(); i++) { - auto size = std::uint32_t((image.width >> i) * (image.height >> i) * 4); - auto size_padded = glm::ceilMultiple(size, std::uint32_t(4)); + char block_data[cDXTBlockSize * cDXTBlockSize * 4]; + crn_uint32 pixels[cDXTBlockSize * cDXTBlockSize]; + + for(std::uint32_t i = 0; i < image.mip_levels.size(); i++) { + // calc and write size + auto width = util::max(1, image.width >> i); + auto height = util::max(1, image.height >> i); + + auto num_blocks_x = std::int32_t((width + cDXTBlockSize - 1) / cDXTBlockSize); + auto num_blocks_y = std::int32_t((height + cDXTBlockSize - 1) / cDXTBlockSize); + auto bytes_per_block = crn_get_bytes_per_dxt_block(crn_format); + auto total_compressed_size = std::uint32_t(num_blocks_x * num_blocks_y) * bytes_per_block; + + auto size_padded = glm::ceilMultiple(total_compressed_size, std::uint32_t(4)); out.write(reinterpret_cast(&size_padded), sizeof(std::uint32_t)); - out.write(reinterpret_cast(rgb8_image.mip_levels[i].data()), size); + // write pixel data + for(std::int32_t block_y = 0; block_y < num_blocks_y; block_y++) { + for(std::int32_t block_x = 0; block_x < num_blocks_x; block_x++) { + // read block from source + crn_uint32* pDst_pixels = pixels; + for(int y = 0; y < cDXTBlockSize; y++) { + auto y_clipped = util::min(height - 1U, (block_y * cDXTBlockSize) + y); + for(int x = 0; x < cDXTBlockSize; x++) { + auto x_clipped = util::min(width - 1U, (block_x * cDXTBlockSize) + x); + auto src = image.pixel(i, x_clipped, y_clipped); + *pDst_pixels++ = crn_uint32(to_8bit(src.r)) << 8 * 0 + | crn_uint32(to_8bit(src.g)) << 8 * 1 + | crn_uint32(to_8bit(src.b)) << 8 * 2 + | crn_uint32(to_8bit(src.a)) << 8 * 3; + } + } + + crn_compress_block(pContext, pixels, block_data); + + out.write(block_data, std::streamsize(bytes_per_block)); + } + } + + if(size_padded > total_compressed_size) { + // padding + out.write(padding_data, std::streamsize(size_padded - total_compressed_size)); + } } } + void store_texture_async(Image_data image, std::string output, Texture_format format) + { + parallel_tasks_started++; + async::spawn([image = std::move(image), output = std::move(output), format]() mutable { + store_texture(std::move(image), std::move(output), format); + parallel_tasks_done++; + }); + } - auto find_texture(const std::string& mat_name, - const aiMaterial& material, - const Mesh_converted_config& cfg, - Texture_type type) -> std::string + auto try_find_texture(const std::string& mat_name, + const aiMaterial& material, + const Mesh_converted_config& cfg, + Texture_type type) -> util::maybe { auto override = util::find_maybe(cfg.material_texture_override, mat_name) .process([&](auto& override) { return util::find_maybe(override, type); }) @@ -260,6 +285,17 @@ namespace mirrage { } } + return util::nothing; + } + auto find_texture(const std::string& mat_name, + const aiMaterial& material, + const Mesh_converted_config& cfg, + Texture_type type) -> std::string + { + auto tex = try_find_texture(mat_name, material, cfg, type); + if(tex.is_some()) + return tex.get_or_throw(); + auto name = sf2::get_enum_info().name_of(type).str(); auto texture_name = "default_"s + name + ".png"; @@ -315,77 +351,91 @@ namespace mirrage { auto texture_dir = output + "/textures/"; - auto substance_id = util::Str_id("default"); // TODO: decide alpha-test / alpha-blend / emissive? + auto material_file = renderer::Material_data{}; + material_file.substance_id = util::Str_id("default"); // TODO: decide alpha-test / alpha-blend - // load and combine textures + // convert albedo auto albedo_name = resolve_path(name, base_dir, find_texture(name, material, cfg, Texture_type::albedo)); auto albedo = load_texture2d(albedo_name); generate_mip_maps(albedo, [](auto a, auto b, auto c, auto d) { return (a + b + c + d) / 4.f; }); - albedo_name = name + "_albedo.ktx"; - store_texture(albedo, texture_dir + albedo_name); - - auto material_file = renderer::Material_data{}; - material_file.substance_id = substance_id; - material_file.albedo_aid = albedo_name; - - switch(substance_id) { - case "emissive"_strid: { - auto emission_texture_name = find_texture(name, material, cfg, Texture_type::emission); - auto emission = load_texture2d(resolve_path(name, base_dir, emission_texture_name), false); - generate_mip_maps(emission, - [](auto a, auto b, auto c, auto d) { return (a + b + c + d) / 4.f; }); - - material_file.mat_data2_aid = name + "_mat_data2.ktx"; - store_texture(emission, texture_dir + material_file.mat_data2_aid, false); + material_file.albedo_aid = name + "_albedo.ktx"; + store_texture_async(albedo, texture_dir + material_file.albedo_aid, Texture_format::s_rgba); + + // convert normal + auto normal_name = find_texture(name, material, cfg, Texture_type::normal); + auto normal = load_texture2d(resolve_path(name, base_dir, normal_name), false); + normal.foreach([&](auto& pixel, auto level, auto x, auto y) { + // generate mip levels + if(level > 0) { + auto n_00 = normal.pixel(level - 1, x * 2, y * 2); + auto n_10 = normal.pixel(level - 1, x * 2 + 1, y * 2); + auto n_11 = normal.pixel(level - 1, x * 2 + 1, y * 2 + 1); + auto n_01 = normal.pixel(level - 1, x * 2, y * 2 + 1); + + auto n = glm::normalize(glm::vec3(n_00.r * 2 - 1, n_00.g * 2 - 1, n_00.b * 2 - 1)) + + glm::normalize(glm::vec3(n_10.r * 2 - 1, n_10.g * 2 - 1, n_10.b * 2 - 1)) + + glm::normalize(glm::vec3(n_11.r * 2 - 1, n_11.g * 2 - 1, n_11.b * 2 - 1)) + + glm::normalize(glm::vec3(n_01.r * 2 - 1, n_01.g * 2 - 1, n_01.b * 2 - 1)); + + n = glm::normalize(n / 4.f); + pixel.r = n.x * 0.5f + 0.5f; + pixel.g = n.y * 0.5f + 0.5f; + pixel.b = n.z * 0.5f + 0.5f; + pixel.a = 1; } - [[fallthrough]]; - - case "default"_strid: - default: - auto metallic_texture_name = find_texture(name, material, cfg, Texture_type::metalness); - auto roughness_texture_name = find_texture(name, material, cfg, Texture_type::roughness); - auto normal_texture_name = find_texture(name, material, cfg, Texture_type::normal); - - auto metallic = load_texture2d(resolve_path(name, base_dir, metallic_texture_name), false); - auto roughness = load_texture2d(resolve_path(name, base_dir, roughness_texture_name), false); - auto normal = load_texture2d(resolve_path(name, base_dir, normal_texture_name), false); - - generate_mip_maps(metallic, - [](auto a, auto b, auto c, auto d) { return (a + b + c + d) / 4.f; }); - generate_mip_maps(roughness, - [](auto a, auto b, auto c, auto d) { return (a + b + c + d) / 4.f; }); - - normal.foreach([&](auto& pixel, auto level, auto x, auto y) { - if(level > 0) { - auto n_00 = normal.pixel(level - 1, x * 2, y * 2); - auto n_10 = normal.pixel(level - 1, x * 2 + 1, y * 2); - auto n_11 = normal.pixel(level - 1, x * 2 + 1, y * 2 + 1); - auto n_01 = normal.pixel(level - 1, x * 2, y * 2 + 1); - - auto n = glm::normalize(glm::vec3(n_00.r * 2 - 1, n_00.g * 2 - 1, n_00.b * 2 - 1)) - + glm::normalize(glm::vec3(n_10.r * 2 - 1, n_10.g * 2 - 1, n_10.b * 2 - 1)) - + glm::normalize(glm::vec3(n_11.r * 2 - 1, n_11.g * 2 - 1, n_11.b * 2 - 1)) - + glm::normalize(glm::vec3(n_01.r * 2 - 1, n_01.g * 2 - 1, n_01.b * 2 - 1)); - - n = glm::normalize(n / 4.f); - pixel.r = n.x * 0.5f + 0.5f; - pixel.g = n.y * 0.5f + 0.5f; - pixel.b = n.z * 0.5f + 0.5f; - pixel.a = 1; - } - }); - - normal.foreach([&](auto& pixel, auto level, auto x, auto y) { - pixel.b = roughness.pixel(level, x, y).r; - pixel.a = metallic.pixel(level, x, y).r; - }); - - material_file.mat_data_aid = name + "_mat_data.ktx"; - store_texture(normal, texture_dir + material_file.mat_data_aid, false); - break; + }); + material_file.normal_aid = name + "_normal.ktx"; + store_texture_async(normal, texture_dir + material_file.normal_aid, Texture_format::rg); + + // convert brdf + auto metallic_name = find_texture(name, material, cfg, Texture_type::metalness); + auto roughness_name = find_texture(name, material, cfg, Texture_type::roughness); + auto metallic = load_texture2d(resolve_path(name, base_dir, metallic_name), false); + auto roughness = load_texture2d(resolve_path(name, base_dir, roughness_name), false); + generate_mip_maps(metallic, [](auto a, auto b, auto c, auto d) { return (a + b + c + d) / 4.f; }); + generate_mip_maps(roughness, [](auto a, auto b, auto c, auto d) { return (a + b + c + d) / 4.f; }); + if(roughness.width == metallic.width && roughness.height == metallic.height) + roughness.foreach([&](auto& pixel, auto level, auto x, auto y) { + pixel.g = metallic.pixel(level, x, y).r; + }); + else { + auto width_scale = float(metallic.width) / float(roughness.width); + auto height_scale = float(metallic.height) / float(roughness.height); + roughness.foreach([&](auto& pixel, auto level, auto x, auto y) { + pixel.g = + metallic.pixel(level, std::int32_t(x * width_scale), std::int32_t(y * height_scale)).r; + }); } + material_file.brdf_aid = name + "_brdf.ktx"; + store_texture_async(roughness, texture_dir + material_file.brdf_aid, Texture_format::rg); + + // convert emissive + try_find_texture(name, material, cfg, Texture_type::emission).process([&](auto& emission_name) { + auto emission = load_texture2d(resolve_path(name, base_dir, emission_name), false); + generate_mip_maps(emission, [](auto a, auto b, auto c, auto d) { return (a + b + c + d) / 4.f; }); + + material_file.emission_aid = name + "_emission.ktx"; + store_texture_async(emission, texture_dir + material_file.emission_aid, Texture_format::rg); + }); + + // determine substance type + auto uses_alpha_mask = std::int_fast32_t(0); + auto uses_alpha_blend = std::int_fast32_t(0); + albedo.foreach([&](auto& pixel, auto level, auto, auto) { + if(level == 0) { + auto mask = pixel.a < 254.f / 255.f; + uses_alpha_mask += mask ? 1 : 0; + uses_alpha_blend += mask && pixel.a > 2.f / 255.f ? 1 : 0; + } + }); + auto alpha_cutoff = std::clamp((albedo.width * albedo.height) / 100, 10, 200); + if(uses_alpha_blend > alpha_cutoff) + material_file.substance_id = util::Str_id("alphatest"); // TODO: alphablend + else if(uses_alpha_mask > alpha_cutoff) + material_file.substance_id = util::Str_id("alphatest"); + // store results auto filename = output + "/materials/" + name + ".msf"; @@ -396,15 +446,45 @@ namespace mirrage { return true; } - void convert_texture(const std::string& input, const std::string& output_dir) + void convert_texture(const std::string& input, + const std::string& output_dir, + bool normal_texture, + bool srgb) { - auto data = load_texture2d(input, true); - generate_mip_maps(data, [](auto a, auto b, auto c, auto d) { return (a + b + c + d) / 4.f; }); + auto data = load_texture2d(input, srgb); + if(normal_texture) { + data.foreach([&](auto& pixel, auto level, auto x, auto y) { + // generate mip levels + if(level > 0) { + auto n_00 = data.pixel(level - 1, x * 2, y * 2); + auto n_10 = data.pixel(level - 1, x * 2 + 1, y * 2); + auto n_11 = data.pixel(level - 1, x * 2 + 1, y * 2 + 1); + auto n_01 = data.pixel(level - 1, x * 2, y * 2 + 1); + + auto n = glm::normalize(glm::vec3(n_00.r * 2 - 1, n_00.g * 2 - 1, n_00.b * 2 - 1)) + + glm::normalize(glm::vec3(n_10.r * 2 - 1, n_10.g * 2 - 1, n_10.b * 2 - 1)) + + glm::normalize(glm::vec3(n_11.r * 2 - 1, n_11.g * 2 - 1, n_11.b * 2 - 1)) + + glm::normalize(glm::vec3(n_01.r * 2 - 1, n_01.g * 2 - 1, n_01.b * 2 - 1)); + + n = glm::normalize(n / 4.f); + pixel.r = n.x * 0.5f + 0.5f; + pixel.g = n.y * 0.5f + 0.5f; + pixel.b = n.z * 0.5f + 0.5f; + pixel.a = 1; + } + }); + + } else { + generate_mip_maps(data, [](auto a, auto b, auto c, auto d) { return (a + b + c + d) / 4.f; }); + } + auto input_path = util::split_on_last(input, "/"); auto input_name = input_path.second.empty() ? input_path.first : input_path.second; input_name = util::split_on_last(input_name, ".").first; - store_texture(data, output_dir + "/" + input_name + ".ktx", false); + store_texture(data, + output_dir + "/" + input_name + ".ktx", + srgb ? Texture_format::s_rgba : Texture_format::rg); } } // namespace mirrage diff --git a/src/mesh_converter/material_parser.hpp b/src/mesh_converter/material_parser.hpp index 8f0656451bb05e72ceaeb6c43e5e9e312b5f9802..7434ba1f923f40da13233d99a26d93c33b0928e0 100644 --- a/src/mesh_converter/material_parser.hpp +++ b/src/mesh_converter/material_parser.hpp @@ -14,6 +14,9 @@ namespace mirrage { const std::string& output, const Mesh_converted_config& cfg); - extern void convert_texture(const std::string& input, const std::string& output_dir); + extern void convert_texture(const std::string& input, + const std::string& output_dir, + bool normal_texture, + bool srgb); } // namespace mirrage diff --git a/src/mirrage/CMakeLists.txt b/src/mirrage/CMakeLists.txt index f13d61fd3996bff2e90326c18dbbcb7fecb62879..ff466f63609e4d1d7e554f07761665ea90bd1f8f 100644 --- a/src/mirrage/CMakeLists.txt +++ b/src/mirrage/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.2 FATAL_ERROR) -project(mirrage LANGUAGES CXX) +project(mirrage) add_subdirectory(utils) add_subdirectory(error) diff --git a/src/mirrage/asset/CMakeLists.txt b/src/mirrage/asset/CMakeLists.txt index 2983566ae22ef52bd088187cf9527df26065fead..dcf8f839c7eb6d8c2d926523baed8d54e483dde7 100644 --- a/src/mirrage/asset/CMakeLists.txt +++ b/src/mirrage/asset/CMakeLists.txt @@ -1,6 +1,6 @@ -cmake_minimum_required(VERSION 3.2 FATAL_ERROR) +cmake_minimum_required(VERSION 3.9 FATAL_ERROR) -project(mirrage_asset LANGUAGES CXX) +project(mirrage_asset) # need to be specified with the sources for correct syntax highlighting in some IDEs file(GLOB_RECURSE HEADER_FILES @@ -11,11 +11,13 @@ file(GLOB_RECURSE HEADER_FILES add_library(mirrage_asset STATIC src/aid.cpp src/asset_manager.cpp + src/embedded_asset.cpp src/error.cpp src/stream.cpp ${HEADER_FILES} ) add_library(mirrage::asset ALIAS mirrage_asset) +target_compile_features(mirrage_asset PUBLIC cxx_std_17) set(MIRRAGE_DEFAULT_COMPILER_ARGS ${MIRRAGE_DEFAULT_COMPILER_ARGS}) target_compile_options(mirrage_asset PRIVATE ${MIRRAGE_DEFAULT_COMPILER_ARGS}) diff --git a/src/mirrage/asset/include/mirrage/asset/asset_manager.hpp b/src/mirrage/asset/include/mirrage/asset/asset_manager.hpp index 05375a56310794852dd147b35f204b3d82e9f910..e69190805b573fbf253062a6a00244b6c11db03f 100644 --- a/src/mirrage/asset/include/mirrage/asset/asset_manager.hpp +++ b/src/mirrage/asset/include/mirrage/asset/asset_manager.hpp @@ -44,9 +44,10 @@ namespace mirrage::asset { } extern std::string pwd(); - extern std::string write_dir(const std::string& exe_name, - const std::string& org_name, - const std::string& app_name); + extern std::string write_dir(const std::string& exe_name, + const std::string& org_name, + const std::string& app_name, + util::maybe additional_search_path); template @@ -134,7 +135,10 @@ namespace mirrage::asset { class Asset_manager { public: - Asset_manager(const std::string& exe_name, const std::string& org_name, const std::string& app_name); + Asset_manager(const std::string& exe_name, + const std::string& org_name, + const std::string& app_name, + util::maybe additional_search_path); ~Asset_manager(); void reload(); @@ -172,6 +176,9 @@ namespace mirrage::asset { template void remove_stateful_loader(); + template + auto load_stream(asset::istream) -> Ptr; + private: friend class ostream; @@ -179,16 +186,22 @@ namespace mirrage::asset { friend class detail::Asset_container; private: + struct General_Disptacher { + std::string base_dir; + std::string default_extension; + }; + mutable std::mutex _containers_mutex; mutable std::shared_mutex _dispatchers_mutex; detail::Map> _containers; detail::Map _dispatchers; + detail::Map _general_dispatchers; void _post_write(); - auto _base_dir(Asset_type type) const -> util::maybe; + auto _resolve_unkown(const AID& id, bool only_preexisting) const -> util::maybe; void _reload_dispatchers(); diff --git a/src/mirrage/asset/include/mirrage/asset/asset_manager.hxx b/src/mirrage/asset/include/mirrage/asset/asset_manager.hxx index 6eb3d273d362eb6c3f12fffc213965970cf1fad4..2d55882209e0f8ec3e53416f25617dfe7b3fdacd 100644 --- a/src/mirrage/asset/include/mirrage/asset/asset_manager.hxx +++ b/src/mirrage/asset/include/mirrage/asset/asset_manager.hxx @@ -25,7 +25,7 @@ namespace mirrage::asset { if(_cached_result) return util::justPtr(_cached_result); - return ready() ? util::nothing : get_blocking(); + return ready() ? util::nothing : util::maybe(get_blocking()); } template @@ -156,11 +156,15 @@ namespace mirrage::asset { template auto Asset_manager::load(const AID& id, bool cache) -> Ptr { - auto a = load_maybe(id, cache); - if(a.is_nothing()) + auto path = resolve(id); + if(path.is_nothing()) throw std::system_error(Asset_error::resolve_failed, id.str()); - return a.get_or_throw(); + auto&& container = _find_container(); + if(container.is_nothing()) + throw std::system_error(Asset_error::stateful_loader_not_initialized, util::type_name()); + + return container.get_or_throw().load(id, path.get_or_throw(), cache); } template @@ -217,6 +221,24 @@ namespace mirrage::asset { _containers.erase(util::type_uid_of()); } + template + auto Asset_manager::load_stream(asset::istream stream) -> Ptr + { + auto container = _find_container(); + if(container.is_nothing()) + throw std::system_error(Asset_error::stateful_loader_not_initialized, util::type_name()); + + + auto new_value = container.get_or_throw().load(std::move(stream)); + + if constexpr(std::is_same_v>) + return Ptr(stream.aid(), new_value.share()); + else if constexpr(std::is_same_v>) + return Ptr(stream.aid(), std::move(new_value)); + else + return Ptr(stream.aid(), async::make_task(std::move(new_value)).share()); + } + template auto Asset_manager::_find_container() -> util::maybe&> { diff --git a/src/mirrage/asset/include/mirrage/asset/embedded_asset.hpp b/src/mirrage/asset/include/mirrage/asset/embedded_asset.hpp new file mode 100644 index 0000000000000000000000000000000000000000..e5911a2b264cd77f7e7e2b3f56c9dbace7b63abc --- /dev/null +++ b/src/mirrage/asset/include/mirrage/asset/embedded_asset.hpp @@ -0,0 +1,32 @@ +/** interface to register embedded asset archives **************************** + * * + * Copyright (c) 2018 Florian Oetke * + * This file is distributed under the MIT License * + * See LICENSE file for details. * +\*****************************************************************************/ + +#pragma once + +#include +#include +#include + +namespace mirrage::asset { + + class Embedded_asset { + public: + Embedded_asset(std::string name, gsl::span data); + + auto name() const noexcept -> auto& { return _name; } + auto data() const noexcept { return _data; } + + static auto instances() noexcept -> gsl::span { return _instances(); } + + private: + const std::string _name; + gsl::span _data; + + static auto _instances() noexcept -> std::vector&; + }; + +} // namespace mirrage::asset diff --git a/src/mirrage/asset/src/asset_manager.cpp b/src/mirrage/asset/src/asset_manager.cpp index 1f3e5b3df25a8e4566511d8a5b6d88e03d521c91..abffb4db88cdb9b94ca153157875ea84e9ef8824 100644 --- a/src/mirrage/asset/src/asset_manager.cpp +++ b/src/mirrage/asset/src/asset_manager.cpp @@ -1,8 +1,10 @@ #include +#include #include #include +#include #include #include @@ -136,7 +138,7 @@ namespace { } } - void init_physicsfs(const std::string& exe_name) + void init_physicsfs(const std::string& exe_name, mirrage::util::maybe additional_search_path) { if(PHYSFS_isInit()) return; @@ -151,6 +153,8 @@ namespace { || !PHYSFS_mount(mirrage::asset::pwd().c_str(), nullptr, 1)) throw std::system_error(static_cast(PHYSFS_getLastErrorCode()), "Unable to setup default search path."); + + additional_search_path.process([&](auto& dir) { PHYSFS_mount(dir.c_str(), nullptr, 1); }); } constexpr auto default_source = {std::make_tuple("assets", false), std::make_tuple("assets.zip", true)}; @@ -162,7 +166,7 @@ namespace mirrage::asset { { char cCurrentPath[FILENAME_MAX]; -#ifdef WINDOWS +#ifdef _WIN32 _getcwd(cCurrentPath, sizeof(cCurrentPath)); #else if(getcwd(cCurrentPath, sizeof(cCurrentPath)) == nullptr) { @@ -172,11 +176,12 @@ namespace mirrage::asset { return cCurrentPath; } - std::string write_dir(const std::string& exe_name, - const std::string& org_name, - const std::string& app_name) + std::string write_dir(const std::string& exe_name, + const std::string& org_name, + const std::string& app_name, + util::maybe additional_search_path) { - init_physicsfs(exe_name); + init_physicsfs(exe_name, additional_search_path); if(exists_dir("write_dir")) { return std::string(PHYSFS_getRealDir("write_dir")) + "/write_dir"; @@ -185,14 +190,14 @@ namespace mirrage::asset { return PHYSFS_getPrefDir(org_name.c_str(), app_name.c_str()); } - - Asset_manager::Asset_manager(const std::string& exe_name, - const std::string& org_name, - const std::string& app_name) + Asset_manager::Asset_manager(const std::string& exe_name, + const std::string& org_name, + const std::string& app_name, + util::maybe additional_search_path) { - init_physicsfs(exe_name); + init_physicsfs(exe_name, additional_search_path); - auto write_dir = ::mirrage::asset::write_dir(exe_name, org_name, app_name); + auto write_dir = ::mirrage::asset::write_dir(exe_name, org_name, app_name, additional_search_path); create_dir(write_dir); LOG(plog::debug) << "Write dir: " << write_dir; @@ -204,10 +209,14 @@ namespace mirrage::asset { throw std::system_error(static_cast(PHYSFS_getLastErrorCode()), "Unable to set write-dir: "s + write_dir); + auto add_source = [](std::string path) { + auto apath = PHYSFS_getRealDir(path.c_str()); + if(apath) { + path = std::string(apath) + "/" + path; + } - auto add_source = [](const char* path) { LOG(plog::info) << "Added FS directory: " << path; - if(!PHYSFS_mount(path, nullptr, 1)) + if(!PHYSFS_mount(path.c_str(), nullptr, 1)) throw std::system_error(static_cast(PHYSFS_getLastErrorCode()), "Error adding custom archive: "s + path); }; @@ -250,6 +259,29 @@ namespace mirrage::asset { } } + for(auto ea : Embedded_asset::instances()) { + LOG(plog::info) << "Include embedded asset \"" << ea->name() << "\": " << ea->data().size() + << " bytes MD5: " + << util::md5(std::string(reinterpret_cast(ea->data().data()), + std::size_t(ea->data().size_bytes()))); + auto name = "embedded_" + ea->name() + ".zip"; + if(!PHYSFS_mountMemory(ea->data().data(), + static_cast(ea->data().size_bytes()), + nullptr, + name.c_str(), + nullptr, + 1)) { + throw std::system_error(static_cast(PHYSFS_getLastErrorCode()), + "Unable to add embedded archive: "s + ea->name()); + } + } + + // unmount default search-path + PHYSFS_unmount(PHYSFS_getBaseDir()); + PHYSFS_unmount(append_file(PHYSFS_getBaseDir(), "..").c_str()); + PHYSFS_unmount(mirrage::asset::pwd().c_str()); + additional_search_path.process([&](auto& dir) { PHYSFS_unmount(dir.c_str()); }); + _reload_dispatchers(); } @@ -312,7 +344,7 @@ namespace mirrage::asset { } auto Asset_manager::open_rw(const AID& id) -> ostream { - auto path = resolve(id); + auto path = resolve(id, false); if(path.is_nothing()) { path = resolve(AID{id.type(), ""}).process(id.str(), [&](auto&& prefix) { return append_file(prefix, id.str()); @@ -336,8 +368,8 @@ namespace mirrage::asset { res.emplace_back(d.first); } - _base_dir(type).process([&](const std::string& dir) { - for(auto&& f : list_files(dir, "", "")) + util::find_maybe(_general_dispatchers, type).process([&](auto& entry) { + for(auto&& f : list_files(entry.base_dir, "", "")) res.emplace_back(type, f); }); @@ -367,23 +399,42 @@ namespace mirrage::asset { return id.name(); - auto baseDir = _base_dir(id.type()); - - if(baseDir.is_some()) { - auto path = append_file(baseDir.get_or_throw(), id.name()); - if(exists_file(path)) - return std::move(path); - - else if(!only_preexisting) { - PHYSFS_mkdir(baseDir.get_or_throw().c_str()); - return std::move(path); - } + if(auto try2 = _resolve_unkown(id, only_preexisting); try2.is_some()) { + return std::move(try2.get_or_throw()); } if(!only_preexisting) { return id.name(); } + LOG(plog::warning) << "Couldn't resove AID '" << id.str() + << "'. Dispatcher: " << (res != _dispatchers.end() ? res->second : "!NO-MATCH"); + + return util::nothing; + } + auto Asset_manager::_resolve_unkown(const AID& id, bool only_preexisting) const + -> util::maybe + { + auto lock = std::shared_lock{_dispatchers_mutex}; + + auto dir = _general_dispatchers.find(id.type()); + + if(dir == _general_dispatchers.end()) + return util::nothing; + + auto path = append_file(dir->second.base_dir, id.name()); + if(exists_file(path)) + return std::move(path); + + path = path + dir->second.default_extension; + if(exists_file(path)) + return std::move(path); + + if(!only_preexisting) { + PHYSFS_mkdir(dir->second.base_dir.c_str()); + return std::move(path); + } + return util::nothing; } auto Asset_manager::resolve_reverse(std::string_view path) -> util::maybe @@ -400,19 +451,6 @@ namespace mirrage::asset { void Asset_manager::_post_write() {} - auto Asset_manager::_base_dir(Asset_type type) const -> util::maybe - { - auto lock = std::shared_lock{_dispatchers_mutex}; - - auto dir = _dispatchers.find(AID{type, ""}); // search for prefix-entry - - if(dir == _dispatchers.end()) - return util::nothing; - - std::string bdir = dir->second; - return bdir; - } - void Asset_manager::_reload_dispatchers() { auto lock = std::unique_lock{_dispatchers_mutex}; @@ -426,7 +464,14 @@ namespace mirrage::asset { auto kvp = util::split(l, "="); std::string path = util::trim_copy(kvp.second); if(!path.empty()) { - _dispatchers.emplace(AID{kvp.first}, std::move(path)); + auto aid = AID{kvp.first}; + LOG(plog::debug) << " " << AID{kvp.first}.str() << " = " << path; + + if(aid.name().empty()) { + auto [dir, ext] = util::split_on_last(path, "*"); + _general_dispatchers.emplace(aid.type(), General_Disptacher{dir, ext}); + } else + _dispatchers.emplace(std::move(aid), std::move(path)); } } } diff --git a/src/mirrage/asset/src/embedded_asset.cpp b/src/mirrage/asset/src/embedded_asset.cpp new file mode 100644 index 0000000000000000000000000000000000000000..41a27d3f76fc064b9f68932687359fabf4a4dc46 --- /dev/null +++ b/src/mirrage/asset/src/embedded_asset.cpp @@ -0,0 +1,19 @@ +#include + +#include + +namespace mirrage::asset { + + auto Embedded_asset::_instances() noexcept -> std::vector& + { + static std::vector list; + return list; + } + + Embedded_asset::Embedded_asset(std::string name, gsl::span data) + : _name(std::move(name)), _data(std::move(data)) + { + _instances().emplace_back(this); + } + +} // namespace mirrage::asset diff --git a/src/mirrage/core/CMakeLists.txt b/src/mirrage/core/CMakeLists.txt index b3fe3b204251061ebc213077beea19ea605a0324..44473ee2145fed0cd1aea1f20cf65c421d2f62d0 100644 --- a/src/mirrage/core/CMakeLists.txt +++ b/src/mirrage/core/CMakeLists.txt @@ -1,15 +1,9 @@ -cmake_minimum_required(VERSION 3.2 FATAL_ERROR) +cmake_minimum_required(VERSION 3.9 FATAL_ERROR) -project(mirrage LANGUAGES CXX) +project(mirrage) include(version_info.cmake) -find_package(SDL2 REQUIRED) -add_library(sdl2::sdl2 INTERFACE IMPORTED) -set_property(TARGET sdl2::sdl2 PROPERTY INTERFACE_LINK_LIBRARIES ${SDL2_LIBRARY}) -set_property(TARGET sdl2::sdl2 PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${SDL2_INCLUDE_DIR}) - - # need to be specified with the sources for correct syntax highlighting in some IDEs file(GLOB_RECURSE HEADER_FILES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} @@ -24,6 +18,24 @@ add_library(mirrage STATIC ${HEADER_FILES} ) add_library(mirrage::mirrage ALIAS mirrage) +target_compile_features(mirrage PUBLIC cxx_std_17) + +file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/assets_mirrage_core.map" CONTENT +"cfg:input_mapping = settings/input_mapping.json +cfg:graphics = graphics-cfg.json +cfg:renderer = renderer-cfg.json +cfg:sounds = sounds-cfg.json +cfg:language = language-cfg.json +cfg:languages_info = settings/languages.json +cfg:gui = settings/gui.json + +loc: = loc/ +pl_cache: = pipeline_caches +") +mirrage_embed_asset(TARGET mirrage + EXPORT mirrage_targets + SOURCES "${CMAKE_CURRENT_BINARY_DIR}/assets_mirrage_core.map" + DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/assets_mirrage_core.map") set(MIRRAGE_DEFAULT_COMPILER_ARGS ${MIRRAGE_DEFAULT_COMPILER_ARGS}) target_compile_options(mirrage PRIVATE ${MIRRAGE_DEFAULT_COMPILER_ARGS}) @@ -36,7 +48,7 @@ target_include_directories(mirrage PUBLIC target_link_libraries(mirrage PUBLIC mirrage::utils - sdl2::sdl2 + mirrage::deps::SDL2 mirrage::asset mirrage::ecs mirrage::graphic diff --git a/src/mirrage/core/include/mirrage/engine.hpp b/src/mirrage/core/include/mirrage/engine.hpp index 43118e51ab2b36111113d020c3f0b6e57e89e626..00f2a2dccb069024bb2c9b03b0e18268cb790c6a 100644 --- a/src/mirrage/core/include/mirrage/engine.hpp +++ b/src/mirrage/core/include/mirrage/engine.hpp @@ -46,15 +46,16 @@ namespace mirrage { class Engine { public: - Engine(const std::string& org, - const std::string& title, - std::uint32_t version_major, - std::uint32_t version_minor, - bool debug, - bool headless, - int argc, - char** argv, - char** env); + Engine(const std::string& org, + const std::string& title, + util::maybe base_dir, + std::uint32_t version_major, + std::uint32_t version_minor, + bool debug, + bool headless, + int argc, + char** argv, + char** env); virtual ~Engine() noexcept; bool running() const noexcept { return !_quit; } diff --git a/src/mirrage/core/include/mirrage/info.hpp b/src/mirrage/core/include/mirrage/info.hpp index 07e6532d4d436addde396b0ff412657112b099e4..c853b049d88d8090dfe489e48e990451d1a089c7 100644 --- a/src/mirrage/core/include/mirrage/info.hpp +++ b/src/mirrage/core/include/mirrage/info.hpp @@ -15,4 +15,6 @@ namespace mirrage::version_info { extern const std::string hash; extern const std::string date; extern const std::string subject; + extern const std::string project_root; + extern const std::string engine_root; } // namespace mirrage::version_info diff --git a/src/mirrage/core/include/mirrage/screen.hpp b/src/mirrage/core/include/mirrage/screen.hpp index c81b20283b65b8fc071bcb736b1bbd3e20c0dcdf..311e9fc24ee5fb9177014dfe683499cdd0d8bb1a 100644 --- a/src/mirrage/core/include/mirrage/screen.hpp +++ b/src/mirrage/core/include/mirrage/screen.hpp @@ -7,7 +7,11 @@ #pragma once +#include + +#include #include +#include #include #include @@ -19,13 +23,17 @@ namespace mirrage { enum class Prev_screen_policy { discard, stack, draw, update }; - class Screen { + class Screen : private util::Deferred_action_container { public: Screen(Engine& engine) : _engine(engine) {} Screen(const Screen&) = delete; Screen& operator=(const Screen&) = delete; - virtual ~Screen() noexcept = default; + virtual ~Screen() noexcept; + + using Deferred_action_container::defer; + + virtual auto name() const -> std::string = 0; protected: friend class Screen_manager; @@ -37,6 +45,9 @@ namespace mirrage { virtual auto _prev_screen_policy() const noexcept -> Prev_screen_policy = 0; Engine& _engine; + + private: + void _actual_update(util::Time delta_time); }; class Screen_manager { @@ -60,10 +71,26 @@ namespace mirrage { void do_queued_actions(); void clear(); + auto print_stack() const -> std::string + { + auto out = std::stringstream(); + for(auto& screen : util::range_reverse(_screen_stack)) { + out << screen->name(); + switch(screen->_prev_screen_policy()) { + case Prev_screen_policy::discard: out << " |"; break; + case Prev_screen_policy::stack: out << " S> "; break; + case Prev_screen_policy::draw: out << " D> "; break; + case Prev_screen_policy::update: out << " U> "; break; + } + } + + return out.str(); + } + protected: Engine& _engine; std::vector> _screen_stack; - int32_t _leave = 0; + int32_t _leave_count = 0; std::vector> _next_screens; }; } // namespace mirrage diff --git a/src/mirrage/core/info.cpp.in b/src/mirrage/core/info.cpp.in index aa3b318ffd4cb2eb87527bae63e6315ce251afdc..a236e6730774beab4dd592d14b3656701176de55 100644 --- a/src/mirrage/core/info.cpp.in +++ b/src/mirrage/core/info.cpp.in @@ -8,6 +8,8 @@ namespace mirrage { const std::string hash = "@GIT_HASH@"; const std::string date = "@GIT_DATE@"; const std::string subject = "@GIT_SUBJECT@"; + const std::string project_root = "@MIRRAGE_ROOT_PROJECT_DIR@"; + const std::string engine_root = "@MIRRAGE_ROOT_DIR@"; } diff --git a/src/mirrage/core/src/engine.cpp b/src/mirrage/core/src/engine.cpp index a00e3af59b41bc1e3a830fbe412abcd7a195bb67..d492af5583652434d1aae195bdfdf3b2b923e604 100644 --- a/src/mirrage/core/src/engine.cpp +++ b/src/mirrage/core/src/engine.cpp @@ -20,6 +20,7 @@ #include #endif +extern void ref_embedded_assets_mirrage(); namespace mirrage { namespace { @@ -83,17 +84,18 @@ namespace mirrage { Engine::Sdl_wrapper::~Sdl_wrapper() { SDL_Quit(); } - Engine::Engine(const std::string& org, - const std::string& title, - std::uint32_t version_major, - std::uint32_t version_minor, - bool debug, - bool headless, - int argc, - char** argv, + Engine::Engine(const std::string& org, + const std::string& title, + util::maybe base_dir, + std::uint32_t version_major, + std::uint32_t version_minor, + bool debug, + bool headless, + int argc, + char** argv, char**) : _screens(*this) - , _asset_manager(std::make_unique(argc > 0 ? argv[0] : "", org, title)) + , _asset_manager(std::make_unique(argc > 0 ? argv[0] : "", org, title, base_dir)) , _translator(std::make_unique(*_asset_manager)) , _sdl(headless) , _graphics_context(headless ? std::unique_ptr() @@ -113,6 +115,7 @@ namespace mirrage { , _current_time(SDL_GetTicks() / 1000.0) , _headless(headless) { + ref_embedded_assets_mirrage(); _graphics_main_window.process([&](auto& window) { _input_manager->viewport({0, 0, window.width(), window.height()}); @@ -124,7 +127,7 @@ namespace mirrage { if(headless) { #ifdef _WIN32 // TODO - (void) sigIntHandler; + (void) (&sigIntHandler); #else struct sigaction action; action.sa_handler = sigIntHandler; diff --git a/src/mirrage/core/src/screen.cpp b/src/mirrage/core/src/screen.cpp index 11ff0981646709773bed61f10e2f57aa7879d27b..1a98476d87bbbb61be8ea15ff8768cd409dde31b 100644 --- a/src/mirrage/core/src/screen.cpp +++ b/src/mirrage/core/src/screen.cpp @@ -5,6 +5,15 @@ namespace mirrage { + Screen::~Screen() noexcept = default; + + void Screen::_actual_update(util::Time delta_time) + { + Deferred_action_container::update(delta_time); + _update(delta_time); + } + + Screen_manager::Screen_manager(Engine& engine) : _engine(engine) {} Screen_manager::~Screen_manager() noexcept { clear(); } @@ -25,11 +34,11 @@ namespace mirrage { if(depth <= 0) return; - if(_leave > 0) { + if(_leave_count > 0) { LOG(plog::warning) << "multiple screen leaves per frame."; } - _leave += depth; + _leave_count += depth; } auto Screen_manager::current() -> Screen& { return *_screen_stack.back(); } @@ -45,7 +54,7 @@ namespace mirrage { for(; screen_index >= 0; screen_index--) { auto& s = screen_stack.at(size_t(screen_index)); - s->_update(delta_time); + s->_actual_update(delta_time); if(s->_prev_screen_policy() != Prev_screen_policy::update) break; @@ -66,13 +75,13 @@ namespace mirrage { void Screen_manager::do_queued_actions() { // leave screen if requested - if(_leave > 0) { + if(_leave_count > 0) { auto last = std::shared_ptr{}; if(!_screen_stack.empty()) { last = std::move(_screen_stack.back()); } - for(int32_t i = std::min(_leave, int32_t(_screen_stack.size())); i > 0; i--) { + for(int32_t i = std::min(_leave_count, int32_t(_screen_stack.size())); i > 0; i--) { _screen_stack.pop_back(); } @@ -87,7 +96,7 @@ namespace mirrage { _screen_stack.back()->_on_enter(util::nothing); } - _leave = 0; + _leave_count = 0; } // enter new screen if requested @@ -113,4 +122,5 @@ namespace mirrage { _screen_stack.clear(); } + } // namespace mirrage diff --git a/src/mirrage/core/src/translation.cpp b/src/mirrage/core/src/translation.cpp index 5cb453a9abe941bf507e328777f7d730f84c9779..ee4b26226ceaf4099a04d2a009321672c4aaa3cd 100644 --- a/src/mirrage/core/src/translation.cpp +++ b/src/mirrage/core/src/translation.cpp @@ -76,18 +76,22 @@ namespace mirrage { auto Translator::supported_languages() const -> std::vector { - return _assets.load("cfg:language_info"_aid)->supported_languages; + return _assets.load_maybe("cfg:language_info"_aid) + .process(std::vector{}, + [&](auto& lang_info) { return lang_info->supported_languages; }); } void Translator::_reload() { _print_missing(); - auto info = _assets.load("cfg:languages_info"_aid); + auto info = _assets.load_maybe("cfg:languages_info"_aid); + if(info.is_nothing()) + return; - if(!contains(info->supported_languages, _language)) { + if(!contains(info.get_or_throw()->supported_languages, _language)) { LOG(plog::info) << "Unsupported language: " << _language; - _language = Language_id{info->default_language}; + _language = Language_id{info.get_or_throw()->default_language}; } LOG(plog::info) << "Using text language: " << _language; diff --git a/src/mirrage/ecs/CMakeLists.txt b/src/mirrage/ecs/CMakeLists.txt index 8807427e1d574afbaa8dffc8f421c0785f8cb9aa..93daed45ec859328dde7eb3ec9458df5d96f0e5b 100644 --- a/src/mirrage/ecs/CMakeLists.txt +++ b/src/mirrage/ecs/CMakeLists.txt @@ -1,6 +1,6 @@ -cmake_minimum_required(VERSION 3.2 FATAL_ERROR) +cmake_minimum_required(VERSION 3.9 FATAL_ERROR) -project(mirrage_ecs LANGUAGES CXX) +project(mirrage_ecs) # need to be specified with the sources for correct syntax highlighting in some IDEs file(GLOB_RECURSE HEADER_FILES @@ -18,6 +18,7 @@ add_library(mirrage_ecs STATIC ${HEADER_FILES} ) add_library(mirrage::ecs ALIAS mirrage_ecs) +target_compile_features(mirrage_ecs PUBLIC cxx_std_17) set(MIRRAGE_DEFAULT_COMPILER_ARGS ${MIRRAGE_DEFAULT_COMPILER_ARGS}) target_compile_options(mirrage_ecs PRIVATE ${MIRRAGE_DEFAULT_COMPILER_ARGS}) diff --git a/src/mirrage/ecs/include/mirrage/ecs/component.hpp b/src/mirrage/ecs/include/mirrage/ecs/component.hpp index 6293aff91ae26f027f827afcfee2b9e19ca36d29..32a4fd5ddcc7191bae7a29bb67c3d921079f71dc 100644 --- a/src/mirrage/ecs/include/mirrage/ecs/component.hpp +++ b/src/mirrage/ecs/include/mirrage/ecs/component.hpp @@ -163,8 +163,8 @@ namespace mirrage::ecs { class Component : public Tiny_component, public detail::Owned_component_base { public: - using component_base_t = Component; - static constexpr auto sort_key = &Component::_owner; + using component_base_t = Component; + static constexpr auto sort_key() { return &Component::_owner; } static constexpr auto sort_key_index = 0; Component() = default; diff --git a/src/mirrage/ecs/include/mirrage/ecs/component.hxx b/src/mirrage/ecs/include/mirrage/ecs/component.hxx index 4da5a964c5b4ed7807c086416a26cd21c81cea5b..dbe8627f78ef431662daa1c78723cfbfc5ebf0d2 100644 --- a/src/mirrage/ecs/include/mirrage/ecs/component.hxx +++ b/src/mirrage/ecs/include/mirrage/ecs/component.hxx @@ -215,7 +215,7 @@ namespace mirrage::ecs { template struct Pool_storage_policy_sort> { static constexpr bool sorted = true; - static constexpr auto sort_key = T::sort_key; + static constexpr auto sort_key = T::sort_key(); static constexpr auto sort_key_constructor_idx = T::sort_key_index; }; @@ -267,7 +267,7 @@ namespace mirrage::ecs { auto empty() const -> bool { return _pool.empty(); } template ().*T::sort_key)>>> + class = std::enable_if_t().*T::sort_key())>>> auto find(const Key& key) { return _pool.find(key); @@ -601,7 +601,7 @@ namespace mirrage::ecs { { if constexpr(pool_based) { auto& component = *_iterator; - _last_value = value_type{(component.*T::sort_key).id(), &component}; + _last_value = value_type{(component.*T::sort_key()).id(), &component}; } else { auto&& [entity, idx] = *_iterator; _last_value = value_type{entity, &_container->_storage.get(idx)}; diff --git a/src/mirrage/ecs/include/mirrage/ecs/entity_handle.hpp b/src/mirrage/ecs/include/mirrage/ecs/entity_handle.hpp index 31e56dbf35e9b2b7b3a622333dbf2b4cdb22fdd0..e88451c530c466d4aa793dc2b66fdb7ae5b5a9e7 100644 --- a/src/mirrage/ecs/include/mirrage/ecs/entity_handle.hpp +++ b/src/mirrage/ecs/include/mirrage/ecs/entity_handle.hpp @@ -100,7 +100,7 @@ namespace mirrage::ecs { h.revision(static_cast(rev & ~Entity_handle::free_rev)); // mark as used auto success = true; - auto cas = expected_rev; + auto cas = uint8_t(0); do { cas = expected_rev; success = rev.compare_exchange_strong(cas, h.revision()); diff --git a/src/mirrage/ecs/include/mirrage/ecs/entity_manager.hpp b/src/mirrage/ecs/include/mirrage/ecs/entity_manager.hpp index 4e4e43c00e7922f08fc2128d8f7afe9ec38c02e6..7879c29c482aef543acf1c035fc131c6fba5295e 100644 --- a/src/mirrage/ecs/include/mirrage/ecs/entity_manager.hpp +++ b/src/mirrage/ecs/include/mirrage/ecs/entity_manager.hpp @@ -18,10 +18,13 @@ #include #include +#include +#include #include #include #include +#include #include @@ -36,6 +39,70 @@ namespace mirrage::ecs { /// entity transfer object using ETO = std::string; + class Entity_builder { + public: + Entity_builder() = default; + + auto blueprint(std::string v) -> Entity_builder& + { + _blueprint = std::move(v); + return *this; + } + + auto position(glm::vec3 v) -> Entity_builder& + { + _position = v; + return *this; + } + auto direction(glm::vec3 v) -> Entity_builder& + { + _rotation = v; + _look_at = false; + return *this; + } + auto look_at(glm::vec3 v) -> Entity_builder& + { + _rotation = v; + _look_at = true; + return *this; + } + auto rotation(glm::quat v) -> Entity_builder& + { + _rotation = v; + return *this; + } + + auto post_create(std::function v) -> Entity_builder& + { + _post_create = v; + return *this; + } + + auto create() -> Entity_facet; + + private: + friend class Entity_manager; + + using Listener = std::function; + using Rotation = std::variant; + + Entity_builder(Entity_manager& m, std::string blueprint = {}) + : _manager(&m), _blueprint(std::move(blueprint)) + { + } + + void apply(); + + Entity_manager* _manager = nullptr; + Entity_facet _facet; + Listener _post_create; + std::string _blueprint; + Rotation _rotation; + util::maybe _position; + bool _look_at = false; + }; + + /** * The main functionality is thread-safe but the other methods require a lock to prevent * concurrent read access during their execution @@ -46,11 +113,16 @@ namespace mirrage::ecs { ~Entity_manager(); // user interface; thread-safe - auto emplace() noexcept -> Entity_facet; - auto emplace(const std::string& blueprint) -> Entity_facet; // TODO/FIXME: currently NOT thread-safe + auto entity_builder(std::string blueprint = {}) -> Entity_builder + { + return {*this, std::move(blueprint)}; + } + auto emplace_empty() -> Entity_facet; auto get(Entity_handle entity) -> util::maybe; auto get_handle(Entity_id id) const -> Entity_handle { return _handles.get(id); } auto validate(Entity_handle entity) -> bool { return _handles.valid(entity); } + template + void process(Entity_handle entity, F&& callback); // deferred to next call to process_queued_actions void erase(Entity_handle entity); @@ -84,10 +156,12 @@ namespace mirrage::ecs { auto component_type_by_name(const std::string& name) -> util::maybe; private: + friend class Entity_builder; friend class Entity_facet; friend class Entity_collection_facet; - using Erase_queue = moodycamel::ConcurrentQueue; + using Erase_queue = moodycamel::ConcurrentQueue; + using Emplace_queue = moodycamel::ConcurrentQueue; asset::Asset_manager& _assets; util::any_ptr _userdata; @@ -95,6 +169,7 @@ namespace mirrage::ecs { Entity_handle_generator _handles; Erase_queue _queue_erase; std::vector _local_queue_erase; + Emplace_queue _queued_emplace; std::vector> _components; std::unordered_map _components_by_name; diff --git a/src/mirrage/ecs/include/mirrage/ecs/entity_manager.hxx b/src/mirrage/ecs/include/mirrage/ecs/entity_manager.hxx index 39af99bcbbdbbc0846db48bcea780626db61106e..2fa9fb109acbe102a1de53ac9ad1ed435048393d 100644 --- a/src/mirrage/ecs/include/mirrage/ecs/entity_manager.hxx +++ b/src/mirrage/ecs/include/mirrage/ecs/entity_manager.hxx @@ -30,6 +30,13 @@ namespace mirrage::ecs { return it != _components_by_name.end() ? util::just(it->second) : util::nothing; } + template + void Entity_manager::process(Entity_handle entity, F&& callback) + { + if(auto f = get(entity); f.is_some()) + f.get_or_throw().process(std::forward(callback)); + } + template auto Entity_manager::list() -> Component_container& { @@ -68,6 +75,32 @@ namespace mirrage::ecs { return _manager->list().find(_owner); } + namespace detail { + template + void infer_process_args(Entity_facet& facet, F&& function, std::index_sequence) + { + facet.process>...>(std::forward(function)); + } + } // namespace detail + + template + void Entity_facet::process(F&& function) + { + if constexpr(sizeof...(Ts) == 0) { + detail::infer_process_args(*this, + std::forward(function), + std::make_index_sequence::argument_count>()); + + } else { + MIRRAGE_INVARIANT(_manager && _manager->validate(_owner), + "Access to invalid Entity_facet for " << entity_name(_owner)); + auto r = std::make_tuple(_manager->list().find(_owner)...); + if(std::apply([](auto&&... c) { return (... && c.is_some()); }, r)) { + std::apply([&](auto&... c) { function(c.get_or_throw()...); }, r); + } + } + } + template bool Entity_facet::has() { @@ -77,7 +110,8 @@ namespace mirrage::ecs { template void Entity_facet::emplace(Args&&... args) { - emplace_init(+[](const T&) {}, std::forward(args)...); + emplace_init( + +[](const T&) {}, std::forward(args)...); } template diff --git a/src/mirrage/ecs/include/mirrage/ecs/entity_set_view.hpp b/src/mirrage/ecs/include/mirrage/ecs/entity_set_view.hpp index 83790be45dd9c15de42bf9f5d29274416df9d949..3015e8d904d233c1926c7965d9ffd989adf6d1fc 100644 --- a/src/mirrage/ecs/include/mirrage/ecs/entity_set_view.hpp +++ b/src/mirrage/ecs/include/mirrage/ecs/entity_set_view.hpp @@ -92,7 +92,10 @@ namespace mirrage::ecs { auto operator*() noexcept -> value_type& { return get(); } auto operator-> () noexcept -> value_type* { return &get(); } + auto operator*() const noexcept -> const value_type& { return get(); } + auto operator-> () const noexcept -> const value_type* { return &get(); } auto get() noexcept -> value_type&; + auto get() const noexcept -> const value_type&; auto operator++() -> Entity_set_iterator&; auto operator++(int) -> Entity_set_iterator { @@ -118,9 +121,9 @@ namespace mirrage::ecs { SortedPools& _sorted_pools; UnsortedPools& _unsorted_pools; - util::maybe _last_value; - Entity_id _entity; - Values _values; + mutable util::maybe _last_value; + Entity_id _entity; + Values _values; void _find_next_valid(); }; diff --git a/src/mirrage/ecs/include/mirrage/ecs/entity_set_view.hxx b/src/mirrage/ecs/include/mirrage/ecs/entity_set_view.hxx index b2c78902f8d72a1953e973bdb65b2b27c1dea3a9..872f3a09e466dfe1493cd6a61103a65e95fc2425 100644 --- a/src/mirrage/ecs/include/mirrage/ecs/entity_set_view.hxx +++ b/src/mirrage/ecs/include/mirrage/ecs/entity_set_view.hxx @@ -32,6 +32,14 @@ namespace mirrage::ecs { get_value(_entities, _entity, _values)...); return _last_value.get_or_throw(); } + template + auto Entity_set_iterator::get() const noexcept + -> const value_type& + { + _last_value.emplace(get_value(_entities, _entity, _values), + get_value(_entities, _entity, _values)...); + return _last_value.get_or_throw(); + } template auto build_pool_mask(std::tuple& sorted_pools, diff --git a/src/mirrage/ecs/include/mirrage/ecs/types.hpp b/src/mirrage/ecs/include/mirrage/ecs/types.hpp index eee96ded5ad4caefa46d5152a293b80f8a4fe668..3c0fb43c918e84398d724ebde2082418083bb1ce 100644 --- a/src/mirrage/ecs/include/mirrage/ecs/types.hpp +++ b/src/mirrage/ecs/include/mirrage/ecs/types.hpp @@ -61,6 +61,9 @@ namespace mirrage::ecs { template util::maybe get(); + template + void process(F&&); + template bool has(); diff --git a/src/mirrage/ecs/src/entity_manager.cpp b/src/mirrage/ecs/src/entity_manager.cpp index 18132692f9a9a895c3a722f9206cf9c205602845..25814c4e3161f8c33da6a906ecbe43280102489b 100644 --- a/src/mirrage/ecs/src/entity_manager.cpp +++ b/src/mirrage/ecs/src/entity_manager.cpp @@ -3,6 +3,8 @@ #include #include +#include + #include #include @@ -23,16 +25,51 @@ namespace mirrage::ecs { } Entity_manager::~Entity_manager() { deinit_serializer(*this); } - Entity_facet Entity_manager::emplace() noexcept { return {*this, _handles.get_new()}; } - Entity_facet Entity_manager::emplace(const std::string& blueprint) + auto Entity_builder::create() -> Entity_facet { - auto e = emplace(); + MIRRAGE_INVARIANT(_manager, "Called Entity_builder::create() on uninitialized/moved-from object."); + + _facet = _manager->emplace_empty(); - apply_blueprint(_assets, e, blueprint); + if(!_blueprint.empty()) { + _manager->_queued_emplace.enqueue(*this); + } else { + apply(); + } - return {*this, e.handle()}; + return _facet; } + void Entity_builder::apply() + { + MIRRAGE_INVARIANT(_facet, "Called Entity_builder::apply() without facet"); + + if(!_blueprint.empty()) + apply_blueprint(_manager->_assets, _facet, _blueprint); + + else if(_position.is_some() || std::holds_alternative(_rotation)) + _facet.emplace(); + + _facet.process([&](auto& transform) { + if(_position.is_some()) + transform.position = _position.get_or_throw(); + + if(auto r = std::get_if(&_rotation)) { + if(_look_at) + transform.look_at(*r); + else + transform.direction(*r); + } else if(auto r = std::get_if(&_rotation)) { + transform.orientation = *r; + } + }); + + if(_post_create) + _post_create(_facet); + } + + auto Entity_manager::emplace_empty() -> Entity_facet { return {*this, _handles.get_new()}; } + auto Entity_manager::get(Entity_handle entity) -> util::maybe { if(validate(entity)) @@ -55,27 +92,45 @@ namespace mirrage::ecs { MIRRAGE_INVARIANT(_local_queue_erase.empty(), "Someone's been sleeping in my bed! (_local_queue_erase is dirty)"); - std::array erase_buffer; - do { - std::size_t count = _queue_erase.try_dequeue_bulk(erase_buffer.data(), erase_buffer.size()); + { + std::array emplace_buffer; + do { + std::size_t count = + _queued_emplace.try_dequeue_bulk(emplace_buffer.data(), emplace_buffer.size()); + if(count > 0) { + for(std::size_t i = 0; i < count; i++) { + emplace_buffer[i].apply(); + } + + } else { + break; + } + } while(true); + } + + { + std::array erase_buffer; + do { + std::size_t count = _queue_erase.try_dequeue_bulk(erase_buffer.data(), erase_buffer.size()); - if(count > 0) { - for(std::size_t i = 0; i < count; i++) { - const auto h = erase_buffer[i]; - if(!validate(h)) - continue; + if(count > 0) { + for(std::size_t i = 0; i < count; i++) { + const auto h = erase_buffer[i]; + if(!validate(h)) + continue; - _local_queue_erase.emplace_back(h); + _local_queue_erase.emplace_back(h); - for(auto& component : _components) { - if(component) - component->erase(h); + for(auto& component : _components) { + if(component) + component->erase(h); + } } + } else { + break; } - } else { - break; - } - } while(true); + } while(true); + } for(auto& component : _components) { if(component) @@ -95,7 +150,8 @@ namespace mirrage::ecs { component->clear(); _handles.clear(); - _queue_erase = Erase_queue{}; + _queue_erase = Erase_queue{}; + _queued_emplace = Emplace_queue{}; } @@ -111,7 +167,7 @@ namespace mirrage::ecs { auto Entity_manager::read_one(ETO data, Entity_handle target) -> Entity_facet { if(!validate(target)) { - target = emplace(); + target = emplace_empty(); } std::istringstream stream{data}; diff --git a/src/mirrage/ecs/src/serializer.cpp b/src/mirrage/ecs/src/serializer.cpp index 1c97c381042360a88b4c9922daea4823d93a0b1f..f2fe4c2c68e86ccf3c2019863f775ec423f6aa23 100644 --- a/src/mirrage/ecs/src/serializer.cpp +++ b/src/mirrage/ecs/src/serializer.cpp @@ -253,7 +253,7 @@ namespace mirrage::ecs { auto& ecs_deserializer = static_cast(s); if(!ecs_deserializer.manager.validate(e)) { - auto e_facet = ecs_deserializer.manager.emplace(); + auto e_facet = ecs_deserializer.manager.emplace_empty(); e = e_facet.handle(); } diff --git a/src/mirrage/error/CMakeLists.txt b/src/mirrage/error/CMakeLists.txt index 85d98d04e4200378377ed37984a34b689cc616c8..123a30890677e282ea8a7e64885c32246cb40d58 100644 --- a/src/mirrage/error/CMakeLists.txt +++ b/src/mirrage/error/CMakeLists.txt @@ -1,6 +1,6 @@ -cmake_minimum_required(VERSION 3.2 FATAL_ERROR) +cmake_minimum_required(VERSION 3.9 FATAL_ERROR) -project(mirrage_error LANGUAGES CXX) +project(mirrage_error) # need to be specified with the sources for correct syntax highlighting in some IDEs file(GLOB_RECURSE HEADER_FILES @@ -13,6 +13,7 @@ add_library(mirrage_error STATIC ${HEADER_FILES} ) add_library(mirrage::error ALIAS mirrage_error) +target_compile_features(mirrage_error PUBLIC cxx_std_17) set(MIRRAGE_DEFAULT_COMPILER_ARGS ${MIRRAGE_DEFAULT_COMPILER_ARGS}) target_compile_options(mirrage_error PRIVATE ${MIRRAGE_DEFAULT_COMPILER_ARGS}) diff --git a/src/mirrage/graphic/CMakeLists.txt b/src/mirrage/graphic/CMakeLists.txt index 4d1e8b8ed8504c7cabe685521e743e8cd697684d..8b1e200d86c6079e4ecd5af1fbe6233a0ff842e5 100644 --- a/src/mirrage/graphic/CMakeLists.txt +++ b/src/mirrage/graphic/CMakeLists.txt @@ -1,15 +1,9 @@ -cmake_minimum_required(VERSION 3.2 FATAL_ERROR) +cmake_minimum_required(VERSION 3.9 FATAL_ERROR) -project(mirrage_graphic LANGUAGES CXX) +project(mirrage_graphic) find_package(Vulkan REQUIRED) -find_package(SDL2 REQUIRED) -add_library(sdl2::sdl2 INTERFACE IMPORTED) -set_property(TARGET sdl2::sdl2 PROPERTY INTERFACE_LINK_LIBRARIES ${SDL2_LIBRARY}) -set_property(TARGET sdl2::sdl2 PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${SDL2_INCLUDE_DIR}) - - # need to be specified with the sources for correct syntax highlighting in some IDEs file(GLOB_RECURSE HEADER_FILES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} @@ -36,6 +30,12 @@ add_library(mirrage_graphic STATIC ${HEADER_FILES} ) add_library(mirrage::graphic ALIAS mirrage_graphic) +target_compile_features(mirrage_graphic PUBLIC cxx_std_17) + +option(MIRRAGE_VULKAN_USE_LABELS "Use labels if VK_EXT_DEBUG_UTILS_EXTENSION_NAME is available" ON) +if(NOT MIRRAGE_VULKAN_USE_LABELS) + target_compile_definitions(mirrage_graphic PRIVATE MIRRAGE_IGNORE_VULKAN_LABELS) +endif() set(MIRRAGE_DEFAULT_COMPILER_ARGS ${MIRRAGE_DEFAULT_COMPILER_ARGS}) target_compile_options(mirrage_graphic PRIVATE ${MIRRAGE_DEFAULT_COMPILER_ARGS}) @@ -52,7 +52,7 @@ target_link_libraries(mirrage_graphic gsl mirrage::asset sf2 - sdl2::sdl2 + mirrage::deps::SDL2 Vulkan::Vulkan ) diff --git a/src/mirrage/graphic/include/mirrage/graphic/context.hpp b/src/mirrage/graphic/include/mirrage/graphic/context.hpp index e716eca3d843648e0d66cc32e1d38b5dc59f7f62..d4923b8fc4e63fae6a369e4ac5b08d4fe39d894e 100644 --- a/src/mirrage/graphic/include/mirrage/graphic/context.hpp +++ b/src/mirrage/graphic/include/mirrage/graphic/context.hpp @@ -67,6 +67,10 @@ namespace mirrage { auto asset_manager() -> auto& { return _assets; } + void vkCmdBeginDebugUtilsLabelEXT(VkCommandBuffer commandBuffer, + const VkDebugUtilsLabelEXT* pLabelInfo); + void vkCmdEndDebugUtilsLabelEXT(VkCommandBuffer commandBuffer); + private: asset::Asset_manager& _assets; std::string _name; @@ -74,11 +78,25 @@ namespace mirrage { std::vector _enabled_layers; vk::UniqueInstance _instance; - vk::UniqueDebugReportCallbackEXT _debug_callback; + vk::UniqueDebugUtilsMessengerEXT _debug_callback; std::unordered_map _windows; + PFN_vkCmdBeginDebugUtilsLabelEXT _vkCmdBeginDebugUtilsLabelEXT = nullptr; + PFN_vkCmdEndDebugUtilsLabelEXT _vkCmdEndDebugUtilsLabelEXT = nullptr; + auto _find_window_settings(const std::string& name, int width, int height) -> Window_settings; }; + + class Queue_debug_label { + public: + Queue_debug_label(Context&, vk::CommandBuffer, const char* name); + ~Queue_debug_label(); + + private: + Context* _ctx; + vk::CommandBuffer _cmds; + }; + } // namespace graphic } // namespace mirrage diff --git a/src/mirrage/graphic/include/mirrage/graphic/descriptor_sets.hpp b/src/mirrage/graphic/include/mirrage/graphic/descriptor_sets.hpp index 4aa35db1e215a73f01a34bbb48474b363484b596..5995863eb7c30132b34c0ed086d6a2833dec38b5 100644 --- a/src/mirrage/graphic/include/mirrage/graphic/descriptor_sets.hpp +++ b/src/mirrage/graphic/include/mirrage/graphic/descriptor_sets.hpp @@ -48,6 +48,10 @@ namespace mirrage::graphic { class Descriptor_pool { public: + Descriptor_pool(vk::Device device, + std::int32_t chunk_size, + std::initializer_list types); + // Allocates a descriptor from the pool // \param bindings: The estimated number of bindings required by the layout auto create_descriptor(vk::DescriptorSetLayout, std::int32_t bindings) -> DescriptorSet; @@ -63,10 +67,6 @@ namespace mirrage::graphic { std::vector _chunks_free_count; mutable std::mutex _mutex; - Descriptor_pool(vk::Device device, - std::int32_t chunk_size, - std::initializer_list types); - Descriptor_pool(const Descriptor_pool&) = delete; Descriptor_pool(Descriptor_pool&&) = delete; Descriptor_pool& operator=(const Descriptor_pool&) = delete; diff --git a/src/mirrage/graphic/include/mirrage/graphic/device.hpp b/src/mirrage/graphic/include/mirrage/graphic/device.hpp index 164d213e39b590f68264c351b3e929558f67bbe0..cbfb5f5051586064fc39c9d4adaba7b3fdf36428 100644 --- a/src/mirrage/graphic/include/mirrage/graphic/device.hpp +++ b/src/mirrage/graphic/include/mirrage/graphic/device.hpp @@ -35,7 +35,8 @@ namespace mirrage::graphic { Queue_tag default_draw_queue, Queue_family_mapping queue_mapping, Swapchain_create_infos, - bool dedicated_alloc_supported); + bool dedicated_alloc_supported, + const vk::PhysicalDeviceFeatures& features); ~Device(); auto get_queue(Queue_tag) -> vk::Queue; @@ -111,6 +112,7 @@ namespace mirrage::graphic { auto physical_device() const noexcept { return _gpu; } auto physical_device_properties() const noexcept { return _gpu_properties; } + auto physical_device_features() const noexcept { return _features; } auto transfer() -> auto& { return _transfer_manager; } @@ -134,10 +136,11 @@ namespace mirrage::graphic { auto context() -> auto& { return util::Registered::parent(); } - void wait_idle() + void wait_idle(bool clear_delete_queue = false) { _device->waitIdle(); - _delete_queue.clear(); + if(clear_delete_queue) + _delete_queue.clear(); } auto is_unified_memory_architecture() const noexcept @@ -145,7 +148,7 @@ namespace mirrage::graphic { return _memory_allocator.is_unified_memory_architecture(); } - auto max_frames_in_flight() const noexcept { return _delete_queue.capacity() + 2; } + auto max_frames_in_flight() const noexcept { return _delete_queue.capacity() + 1; } auto vk_device() const noexcept { return &*_device; } auto pipeline_cache() const noexcept { return **_pipeline_cache; } @@ -155,6 +158,7 @@ namespace mirrage::graphic { vk::UniqueDevice _device; vk::PhysicalDevice _gpu; + vk::PhysicalDeviceFeatures _features; asset::Asset_manager& _assets; vk::PhysicalDeviceProperties _gpu_properties; std::unordered_map _swapchains; diff --git a/src/mirrage/graphic/include/mirrage/graphic/device_memory.hpp b/src/mirrage/graphic/include/mirrage/graphic/device_memory.hpp index b1e89b11d6ddab7c9cbc0be3dea5db72f4f27b9a..d64cadaca166dc847a7fee76d3e6eaf8e5bd1727 100644 --- a/src/mirrage/graphic/include/mirrage/graphic/device_memory.hpp +++ b/src/mirrage/graphic/include/mirrage/graphic/device_memory.hpp @@ -129,6 +129,11 @@ namespace mirrage::graphic { auto memory() -> auto& { return _memory; } + operator bool() const noexcept { return valid(); } + + auto valid() const noexcept { return _instance.operator bool(); } + + private: UniqueHandleType _instance; Device_memory _memory; diff --git a/src/mirrage/graphic/include/mirrage/graphic/render_pass.hpp b/src/mirrage/graphic/include/mirrage/graphic/render_pass.hpp index 48b214e3203da7949d006f90ee10d0b716a65743..b3cce828702afec474b785ce532fcd8b170fbb80 100644 --- a/src/mirrage/graphic/include/mirrage/graphic/render_pass.hpp +++ b/src/mirrage/graphic/include/mirrage/graphic/render_pass.hpp @@ -76,7 +76,7 @@ namespace mirrage::graphic { binding = gsl::narrow(vertex_bindings.size()); vertex_bindings.emplace_back(binding, - sizeof(T), + gsl::narrow(sizeof(T)), per_instance_data ? vk::VertexInputRate::eInstance : vk::VertexInputRate::eVertex); @@ -231,7 +231,7 @@ namespace mirrage::graphic { std::size_t _pipeline_index; std::vector _color_attachments; std::vector _input_attachments; - std::vector _preserve_attachments; + std::vector _preserve_attachments; util::maybe _depth_stencil_attachment; std::unordered_map> _stages; @@ -384,91 +384,104 @@ namespace mirrage::graphic { int location, std::size_t offset) { - vertex_attributes.emplace_back(location, binding, vk::Format::eR32Sfloat, offset); + vertex_attributes.emplace_back( + location, binding, vk::Format::eR32Sfloat, gsl::narrow(offset)); } template <> inline void Pipeline_description::add_vertex_attributes(int binding, int location, std::size_t offset) { - vertex_attributes.emplace_back(location, binding, vk::Format::eR32Sint, offset); + vertex_attributes.emplace_back( + location, binding, vk::Format::eR32Sint, gsl::narrow(offset)); } template <> inline void Pipeline_description::add_vertex_attributes(int binding, int location, std::size_t offset) { - vertex_attributes.emplace_back(location, binding, vk::Format::eR32Uint, offset); + vertex_attributes.emplace_back( + location, binding, vk::Format::eR32Uint, gsl::narrow(offset)); } template <> inline void Pipeline_description::add_vertex_attributes(int binding, int location, std::size_t offset) { - vertex_attributes.emplace_back(location, binding, vk::Format::eR32G32Sfloat, offset); + vertex_attributes.emplace_back( + location, binding, vk::Format::eR32G32Sfloat, gsl::narrow(offset)); } template <> inline void Pipeline_description::add_vertex_attributes(int binding, int location, std::size_t offset) { - vertex_attributes.emplace_back(location, binding, vk::Format::eR32G32Sint, offset); + vertex_attributes.emplace_back( + location, binding, vk::Format::eR32G32Sint, gsl::narrow(offset)); } template <> inline void Pipeline_description::add_vertex_attributes(int binding, int location, std::size_t offset) { - vertex_attributes.emplace_back(location, binding, vk::Format::eR32G32Uint, offset); + vertex_attributes.emplace_back( + location, binding, vk::Format::eR32G32Uint, gsl::narrow(offset)); } template <> inline void Pipeline_description::add_vertex_attributes(int binding, int location, std::size_t offset) { - vertex_attributes.emplace_back(location, binding, vk::Format::eR32G32B32Sfloat, offset); + vertex_attributes.emplace_back( + location, binding, vk::Format::eR32G32B32Sfloat, gsl::narrow(offset)); } template <> inline void Pipeline_description::add_vertex_attributes(int binding, int location, std::size_t offset) { - vertex_attributes.emplace_back(location, binding, vk::Format::eR32G32B32Sint, offset); + vertex_attributes.emplace_back( + location, binding, vk::Format::eR32G32B32Sint, gsl::narrow(offset)); } template <> inline void Pipeline_description::add_vertex_attributes(int binding, int location, std::size_t offset) { - vertex_attributes.emplace_back(location, binding, vk::Format::eR32G32B32Uint, offset); + vertex_attributes.emplace_back( + location, binding, vk::Format::eR32G32B32Uint, gsl::narrow(offset)); } template <> inline void Pipeline_description::add_vertex_attributes(int binding, int location, std::size_t offset) { - vertex_attributes.emplace_back(location, binding, vk::Format::eR32G32B32A32Sfloat, offset); + vertex_attributes.emplace_back( + location, binding, vk::Format::eR32G32B32A32Sfloat, gsl::narrow(offset)); } template <> inline void Pipeline_description::add_vertex_attributes(int binding, int location, std::size_t offset) { - vertex_attributes.emplace_back(location, binding, vk::Format::eR32G32B32A32Sint, offset); + vertex_attributes.emplace_back( + location, binding, vk::Format::eR32G32B32A32Sint, gsl::narrow(offset)); } template <> inline void Pipeline_description::add_vertex_attributes(int binding, int location, std::size_t offset) { - vertex_attributes.emplace_back(location, binding, vk::Format::eR32G32B32A32Uint, offset); + vertex_attributes.emplace_back( + location, binding, vk::Format::eR32G32B32A32Uint, gsl::narrow(offset)); } template <> inline void Pipeline_description::add_vertex_attributes(int binding, int location, std::size_t offset) { - vertex_attributes.emplace_back(location, binding, vk::Format::eR8G8B8A8Unorm, offset); + vertex_attributes.emplace_back( + location, binding, vk::Format::eR8G8B8A8Unorm, gsl::narrow(offset)); } } // namespace mirrage::graphic diff --git a/src/mirrage/graphic/include/mirrage/graphic/streamed_buffer.hpp b/src/mirrage/graphic/include/mirrage/graphic/streamed_buffer.hpp index 44ee97ab8f002c7beb7a39c1dbe2891d9d112ff5..6dc93a291eebc89ea78e01bcbb30f703c4bdea90 100644 --- a/src/mirrage/graphic/include/mirrage/graphic/streamed_buffer.hpp +++ b/src/mirrage/graphic/include/mirrage/graphic/streamed_buffer.hpp @@ -25,12 +25,17 @@ namespace mirrage::graphic { auto update(std::int32_t dest_offset, gsl::span data) -> bool; template - auto update_objs(std::int32_t dest_offset, gsl::span obj) -> bool + auto update_objs(std::int32_t dest_offset, gsl::span obj) -> bool { static_assert(std::is_standard_layout::value, ""); return update(dest_offset, gsl::span(reinterpret_cast(obj.data()), obj.size_bytes())); } + template + auto update_objs(std::int32_t dest_offset, const std::initializer_list& obj) -> bool + { + return update_objs(dest_offset, gsl::span(obj)); + } template auto update_objects(std::int32_t dest_offset, F&& f) -> bool diff --git a/src/mirrage/graphic/include/mirrage/graphic/swapchain.hpp b/src/mirrage/graphic/include/mirrage/graphic/swapchain.hpp index e5102c4b8275177a98a2871947e3973866186b08..d8596f970109b4a2ff4242bfc275597b32ce9b97 100644 --- a/src/mirrage/graphic/include/mirrage/graphic/swapchain.hpp +++ b/src/mirrage/graphic/include/mirrage/graphic/swapchain.hpp @@ -11,7 +11,6 @@ namespace mirrage::graphic { class Swapchain : public Window_modification_handler { public: - Swapchain() = default; Swapchain(const vk::Device& dev, vk::PhysicalDevice, Window&, vk::SwapchainCreateInfoKHR); Swapchain(Swapchain&&) = default; Swapchain& operator=(Swapchain&&) = default; @@ -32,9 +31,9 @@ namespace mirrage::graphic { auto image_format() const noexcept { return _image_format; } private: - const vk::Device& _device; + const vk::Device* _device; vk::PhysicalDevice _gpu; - Window& _window; + Window* _window; vk::SwapchainCreateInfoKHR _info; vk::UniqueSwapchainKHR _swapchain; std::vector _images; diff --git a/src/mirrage/graphic/include/mirrage/graphic/texture.hpp b/src/mirrage/graphic/include/mirrage/graphic/texture.hpp index 3bc5a3e99d4ef6a5018689fdb4a60aece17284ce..aba6d45853d491f50f7736459e27469e8b1acdb2 100644 --- a/src/mirrage/graphic/include/mirrage/graphic/texture.hpp +++ b/src/mirrage/graphic/include/mirrage/graphic/texture.hpp @@ -80,6 +80,19 @@ namespace mirrage::graphic { template class Texture : public detail::Base_texture { + protected: + Texture(Device& device, + Image_type type, + Image_dimensions sim, + std::int32_t mip_levels, + vk::Format format, + vk::ImageUsageFlags usage, + vk::ImageAspectFlags aspect, + bool dedicated) + : Base_texture(device, type, sim, mip_levels, format, usage, aspect, dedicated) + { + } + public: Texture(Device& device, Static_image image, vk::Format format) : Base_texture(device, std::move(image), format) @@ -101,18 +114,15 @@ namespace mirrage::graphic { bool srgb, gsl::span data, std::uint32_t owner_qfamily) - : Texture(device, - Type, - dim, - generate_mipmaps, - detail::format_from_channels(device, channels, srgb), - data, - owner_qfamily) + : Base_texture(device, + Type, + dim, + generate_mipmaps, + detail::format_from_channels(device, channels, srgb), + data, + owner_qfamily) { } - - protected: - using detail::Base_texture::Base_texture; }; template class Render_target : public Texture { diff --git a/src/mirrage/graphic/include/mirrage/graphic/transfer_manager.hpp b/src/mirrage/graphic/include/mirrage/graphic/transfer_manager.hpp index 143b1934b3705acb519e20cd4e71b548a7165862..be2a1a1e14d5b96850d07866e920e5a5dbb96c42 100644 --- a/src/mirrage/graphic/include/mirrage/graphic/transfer_manager.hpp +++ b/src/mirrage/graphic/include/mirrage/graphic/transfer_manager.hpp @@ -183,10 +183,10 @@ namespace mirrage::graphic { std::uint32_t owner, const Image_dimensions&, vk::Format, - std::int32_t mip_levels, - std::int32_t size, - std::function write_data, - bool dedicated = false) -> Static_image; + std::int32_t mip_levels, + std::int32_t size, + std::function write_data, + bool dedicated = false) -> Static_image; auto upload_buffer(vk::BufferUsageFlags usage, std::uint32_t owner, diff --git a/src/mirrage/graphic/include/mirrage/graphic/vk_wrapper.hpp b/src/mirrage/graphic/include/mirrage/graphic/vk_wrapper.hpp index 27361848434dd4b4d514cbd65006c270e5a9cdc7..b1b22c516b8c72b9fd7ba35fa2aca598fa7cda28 100644 --- a/src/mirrage/graphic/include/mirrage/graphic/vk_wrapper.hpp +++ b/src/mirrage/graphic/include/mirrage/graphic/vk_wrapper.hpp @@ -56,7 +56,10 @@ namespace mirrage::graphic { }; struct Image_dimensions { - Image_dimensions(std::int32_t width, std::int32_t height, std::int32_t depth, std::int32_t layers) + Image_dimensions(std::int32_t width = 1, + std::int32_t height = 1, + std::int32_t depth = 1, + std::int32_t layers = 1) : width(width), height(height), depth(depth), layers(layers) { } @@ -71,22 +74,28 @@ namespace mirrage::graphic { template <> struct Image_dimensions_t : Image_dimensions { - Image_dimensions_t(std::int32_t width) : Image_dimensions(width, 1, 1, 1) {} + Image_dimensions_t(std::int32_t width = 1) : Image_dimensions(width, 1, 1, 1) {} }; template <> struct Image_dimensions_t : Image_dimensions { - Image_dimensions_t(std::int32_t width, std::int32_t height) : Image_dimensions(width, height, 1, 1) {} + Image_dimensions_t(std::int32_t width = 1, std::int32_t height = 1) + : Image_dimensions(width, height, 1, 1) + { + } }; template <> struct Image_dimensions_t : Image_dimensions { - Image_dimensions_t(std::int32_t width, std::int32_t height, std::int32_t layers) + Image_dimensions_t(std::int32_t width = 1, std::int32_t height = 1, std::int32_t layers = 1) : Image_dimensions(width, height, 1, layers) { } }; template <> struct Image_dimensions_t : Image_dimensions { - Image_dimensions_t(std::int32_t width, std::int32_t height) : Image_dimensions(width, height, 1, 6) {} + Image_dimensions_t(std::int32_t width = 1, std::int32_t height = 1) + : Image_dimensions(width, height, 1, 6) + { + } }; @@ -102,7 +111,7 @@ namespace mirrage::graphic { private: friend class Device; - const vk::Device& _device; + const vk::Device* _device; vk::UniqueCommandPool _pool; Command_buffer_pool(const vk::Device& device, vk::UniqueCommandPool pool); @@ -123,7 +132,7 @@ namespace mirrage::graphic { private: friend class Device; - const vk::Device& _device; + const vk::Device* _device; vk::UniqueFence _fence; Fence(const vk::Device& device, bool signaled); @@ -170,6 +179,7 @@ namespace mirrage::graphic { _callback(e.data); return true; }); + _callback(current()); } auto start_new_frame() -> vk::Fence diff --git a/src/mirrage/graphic/src/context.cpp b/src/mirrage/graphic/src/context.cpp index d89b1cbe04faf1b1be841d30801bdbc833340170..4043395ee105fdf7c7d2ceebd34ada6dcf0f98ea 100644 --- a/src/mirrage/graphic/src/context.cpp +++ b/src/mirrage/graphic/src/context.cpp @@ -1,5 +1,5 @@ -#include -#include +#include +#include #include // has to be first so he sf2_struct define is set @@ -20,28 +20,28 @@ extern "C" { -VkResult vkCreateDebugReportCallbackEXT(VkInstance instance, - const VkDebugReportCallbackCreateInfoEXT* pCreateInfo, +VkResult vkCreateDebugUtilsMessengerEXT(VkInstance instance, + const VkDebugUtilsMessengerCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, - VkDebugReportCallbackEXT* pCallback) + VkDebugUtilsMessengerEXT* pMessenger) { - auto func = reinterpret_cast( - vkGetInstanceProcAddr(instance, "vkCreateDebugReportCallbackEXT")); + auto func = reinterpret_cast( + vkGetInstanceProcAddr(instance, "vkCreateDebugUtilsMessengerEXT")); if(func != nullptr) { - return func(instance, pCreateInfo, pAllocator, pCallback); + return func(instance, pCreateInfo, pAllocator, pMessenger); } else { return VK_ERROR_EXTENSION_NOT_PRESENT; } } -void vkDestroyDebugReportCallbackEXT(VkInstance instance, - VkDebugReportCallbackEXT callback, +void vkDestroyDebugUtilsMessengerEXT(VkInstance instance, + VkDebugUtilsMessengerEXT messenger, const VkAllocationCallbacks* pAllocator) { - auto func = reinterpret_cast( - vkGetInstanceProcAddr(instance, "vkDestroyDebugReportCallbackEXT")); + auto func = reinterpret_cast( + vkGetInstanceProcAddr(instance, "vkDestroyDebugUtilsMessengerEXT")); if(func != nullptr) { - func(instance, callback, pAllocator); + func(instance, messenger, pAllocator); } } } @@ -181,35 +181,47 @@ namespace mirrage::graphic { return validation_layers; } - VKAPI_ATTR VkBool32 VKAPI_CALL debugCallback(VkDebugReportFlagsEXT flags, - VkDebugReportObjectTypeEXT objType, - uint64_t obj, - size_t location, - int32_t code, - const char* layerPrefix, - const char* msg, - void* userData) + VKAPI_ATTR VkBool32 VKAPI_CALL debugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, + VkDebugUtilsMessageTypeFlagsEXT messageType, + const VkDebugUtilsMessengerCallbackDataEXT* data, + void*) { - (void) obj; - (void) location; - (void) code; - (void) userData; - - // silences: DescriptorSet 0x3f previously bound as set #1 is incompatible with set - // 0x1cc99c0 newly bound as set #1 so set #2 and any subsequent sets were - // disturbed by newly bound pipelineLayout (0x4f) - if(objType == VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT) - return VK_FALSE; - - - if(flags & VK_DEBUG_REPORT_ERROR_BIT_EXT) { - LOG(plog::error) << "[VK | " << layerPrefix << "] " << msg; - } else if(flags & VK_DEBUG_REPORT_WARNING_BIT_EXT - || flags & VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT) { - LOG(plog::warning) << "[VK | " << layerPrefix << "] " << msg; - } else { - LOG(plog::info) << "[VK | " << layerPrefix << "] " << msg; + auto level = [&] { + if(messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT) { + return plog::verbose; + } else if(messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT) { + return plog::info; + } else if(messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT) { + return plog::warning; + } else { + return plog::error; + } + }(); + + auto type = [&] { + if(messageType & VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT) { + return " GENERAL"; + } else if(messageType & VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT) { + return " SPEC"; + } else if(messageType & VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT) { + return " PERF"; + } else { + return ""; + } + }(); + + auto details = std::stringstream(); + if(data->objectCount > 0) { + // TODO } + if(data->cmdBufLabelCount > 0) { + // TODO + } + + auto stacktrace = level == plog::error ? "\nAt:\n" + util::print_stacktrace() : ""; + + LOG(level) << "[VK" << type << "|" << data->pMessageIdName << "] " << data->pMessage + << details.str() << stacktrace; return VK_FALSE; } @@ -258,14 +270,15 @@ namespace mirrage::graphic { add_present_extensions(required_extensions, _windows); auto optional_extensions = std::vector{}; + required_extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME); if(debug) { - _enabled_layers = check_layers({"VK_LAYER_LUNARG_standard_validation", + _enabled_layers = check_layers({"VK_LAYER_LUNARG_image", "VK_LAYER_LUNARG_parameter_validation", "VK_LAYER_LUNARG_core_validation", + "VK_LAYER_LUNARG_swapchain", + "VK_LAYER_GOOGLE_unique_objects", "VK_LAYER_GOOGLE_threading"}); - - required_extensions.push_back(VK_EXT_DEBUG_REPORT_EXTENSION_NAME); } sort_and_unique(required_extensions); @@ -296,12 +309,31 @@ namespace mirrage::graphic { _instance = vk::createInstanceUnique(instanceCreateInfo); if(debug) { - _debug_callback = _instance->createDebugReportCallbackEXTUnique( - {/* vk::DebugReportFlagBitsEXT::eDebug | vk::DebugReportFlagBitsEXT::eInformation | */ - vk::DebugReportFlagBitsEXT::eError | vk::DebugReportFlagBitsEXT::ePerformanceWarning - | vk::DebugReportFlagBitsEXT::eWarning, - debugCallback}); + auto create_info = vk::DebugUtilsMessengerCreateInfoEXT{ + vk::DebugUtilsMessengerCreateFlagsEXT{}, + vk::DebugUtilsMessageSeverityFlagBitsEXT::eInfo + | vk::DebugUtilsMessageSeverityFlagBitsEXT::eWarning + | vk::DebugUtilsMessageSeverityFlagBitsEXT::eError, + vk::DebugUtilsMessageTypeFlagBitsEXT::eGeneral + | vk::DebugUtilsMessageTypeFlagBitsEXT::eValidation + | vk::DebugUtilsMessageTypeFlagBitsEXT::ePerformance, + &debugCallback}; + _debug_callback = _instance->createDebugUtilsMessengerEXTUnique(create_info); + } + +#ifndef MIRRAGE_IGNORE_VULKAN_LABELS + _vkCmdBeginDebugUtilsLabelEXT = reinterpret_cast( + vkGetInstanceProcAddr(*_instance, "vkCmdBeginDebugUtilsLabelEXT")); + _vkCmdEndDebugUtilsLabelEXT = reinterpret_cast( + vkGetInstanceProcAddr(*_instance, "vkCmdEndDebugUtilsLabelEXT")); + + if(!_vkCmdBeginDebugUtilsLabelEXT || !_vkCmdEndDebugUtilsLabelEXT) { + _vkCmdBeginDebugUtilsLabelEXT = nullptr; + _vkCmdEndDebugUtilsLabelEXT = nullptr; + LOG(plog::warning) << "vkCmdBeginDebugUtilsLabelEXT/vkCmdEndDebugUtilsLabelEXT extension " + "function not found."; } +#endif for(auto&& [_, window] : _windows) { (void) _; @@ -632,7 +664,8 @@ namespace mirrage::graphic { << ". Collapsed with previous queue!"; } - queue_mapping.emplace(tag, std::make_tuple(family, std::get<1>(entry).size() - 1)); + queue_mapping.emplace( + tag, std::make_tuple(family, gsl::narrow(std::get<1>(entry).size() - 1))); } auto used_queues = std::vector{}; @@ -660,6 +693,29 @@ namespace mirrage::graphic { draw_queue_tag.get_or_throw("No draw or compute queue! That doesn't seem right."), std::move(queue_mapping), std::move(swapchains), - dedicated_alloc_supported); + dedicated_alloc_supported, + create_info.features); + } + + void Context::vkCmdBeginDebugUtilsLabelEXT(VkCommandBuffer commandBuffer, + const VkDebugUtilsLabelEXT* pLabelInfo) + { + if(_vkCmdBeginDebugUtilsLabelEXT) + _vkCmdBeginDebugUtilsLabelEXT(commandBuffer, pLabelInfo); } + void Context::vkCmdEndDebugUtilsLabelEXT(VkCommandBuffer commandBuffer) + { + if(_vkCmdEndDebugUtilsLabelEXT) + _vkCmdEndDebugUtilsLabelEXT(commandBuffer); + } + + Queue_debug_label::Queue_debug_label(Context& ctx, vk::CommandBuffer cmds, const char* name) + : _ctx(&ctx), _cmds(cmds) + { + auto label = VkDebugUtilsLabelEXT{ + VkStructureType::VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT, nullptr, name, {0, 0, 0, 0}}; + _ctx->vkCmdBeginDebugUtilsLabelEXT(cmds, &label); + } + Queue_debug_label::~Queue_debug_label() { _ctx->vkCmdEndDebugUtilsLabelEXT(_cmds); } + } // namespace mirrage::graphic diff --git a/src/mirrage/graphic/src/descriptor_sets.cpp b/src/mirrage/graphic/src/descriptor_sets.cpp index 678e16ad7b57bd00f59e9c5cd0d09b59959fd297..952f0a9fd8d7fda878371afe5517685cba4cbdc4 100644 --- a/src/mirrage/graphic/src/descriptor_sets.cpp +++ b/src/mirrage/graphic/src/descriptor_sets.cpp @@ -81,7 +81,7 @@ namespace mirrage::graphic { auto ret = vkAllocateDescriptorSets(_device, &c_alloc_info, &desc_set); if(ret == VK_SUCCESS) { - return DescriptorSet(this, pool_idx, desc_set, bindings); + return DescriptorSet(this, gsl::narrow(pool_idx), desc_set, bindings); } else { LOG(plog::warning) << "Allocated a new descriptorSetPool (shouldn't happen too often!)."; *free_iter = 0; @@ -188,7 +188,7 @@ namespace mirrage::graphic { desc_writes.reserve(images.size()); for(auto& desc_image : desc_images) { desc_writes.emplace_back(set, - desc_writes.size(), + gsl::narrow(desc_writes.size()), 0, 1, vk::DescriptorType::eCombinedImageSampler, diff --git a/src/mirrage/graphic/src/device.cpp b/src/mirrage/graphic/src/device.cpp index 04a317486e301a76366bbc2dcc9d361f4bdf10ae..d21522f6ef90bfb2b16490b4f0c5ea5979475fb2 100644 --- a/src/mirrage/graphic/src/device.cpp +++ b/src/mirrage/graphic/src/device.cpp @@ -46,18 +46,28 @@ namespace mirrage::graphic { } }; - Device::Device(Context& context, - asset::Asset_manager& assets, - vk::UniqueDevice device, - vk::PhysicalDevice gpu, - Queue_tag transfer_queue, - Queue_tag default_draw_queue, - Queue_family_mapping queue_mapping, - Swapchain_create_infos swapchains, - bool dedicated_alloc_supported) + namespace { + const auto default_image_usage = + vk::FormatFeatureFlagBits::eBlitDst | vk::FormatFeatureFlagBits::eBlitSrc + | vk::FormatFeatureFlagBits::eSampledImageFilterLinear + | vk::FormatFeatureFlagBits::eColorAttachmentBlend + | vk::FormatFeatureFlagBits::eColorAttachment | vk::FormatFeatureFlagBits::eTransferSrc + | vk::FormatFeatureFlagBits::eTransferDst | vk::FormatFeatureFlagBits::eSampledImage; + } + Device::Device(Context& context, + asset::Asset_manager& assets, + vk::UniqueDevice device, + vk::PhysicalDevice gpu, + Queue_tag transfer_queue, + Queue_tag default_draw_queue, + Queue_family_mapping queue_mapping, + Swapchain_create_infos swapchains, + bool dedicated_alloc_supported, + const vk::PhysicalDeviceFeatures& features) : util::Registered(context) , _device(std::move(device)) , _gpu(gpu) + , _features(features) , _assets(assets) , _gpu_properties(gpu.getProperties()) , _pipeline_cache(load_main_pipeline_cache(*this, assets)) @@ -82,47 +92,23 @@ namespace mirrage::graphic { .get_or_throw("No depth-stencil format " "supported by device")) - , _r_format(get_supported_format({vk::Format::eR8Unorm}, - vk::FormatFeatureFlagBits::eBlitDst - | vk::FormatFeatureFlagBits::eBlitSrc - | vk::FormatFeatureFlagBits::eSampledImageFilterLinear, - Format_usage::image_optimal)) - , _rg_format(get_supported_format({vk::Format::eR8G8Unorm}, - vk::FormatFeatureFlagBits::eBlitDst - | vk::FormatFeatureFlagBits::eBlitSrc - | vk::FormatFeatureFlagBits::eSampledImageFilterLinear, - Format_usage::image_optimal)) - , _rgb_format(get_supported_format({vk::Format::eR8G8B8Unorm}, - vk::FormatFeatureFlagBits::eBlitDst - | vk::FormatFeatureFlagBits::eBlitSrc - | vk::FormatFeatureFlagBits::eSampledImageFilterLinear, - Format_usage::image_optimal)) - , _rgba_format(get_supported_format({vk::Format::eR8G8B8A8Unorm}, - vk::FormatFeatureFlagBits::eBlitDst - | vk::FormatFeatureFlagBits::eBlitSrc - | vk::FormatFeatureFlagBits::eSampledImageFilterLinear, - Format_usage::image_optimal)) - - , _sr_format(get_supported_format({vk::Format::eR8Srgb}, - vk::FormatFeatureFlagBits::eBlitDst - | vk::FormatFeatureFlagBits::eBlitSrc - | vk::FormatFeatureFlagBits::eSampledImageFilterLinear, - Format_usage::image_optimal)) - , _srg_format(get_supported_format({vk::Format::eR8G8Srgb}, - vk::FormatFeatureFlagBits::eBlitDst - | vk::FormatFeatureFlagBits::eBlitSrc - | vk::FormatFeatureFlagBits::eSampledImageFilterLinear, - Format_usage::image_optimal)) - , _srgb_format(get_supported_format({vk::Format::eR8G8B8Srgb}, - vk::FormatFeatureFlagBits::eBlitDst - | vk::FormatFeatureFlagBits::eBlitSrc - | vk::FormatFeatureFlagBits::eSampledImageFilterLinear, - Format_usage::image_optimal)) - , _srgba_format(get_supported_format({vk::Format::eR8G8B8A8Srgb}, - vk::FormatFeatureFlagBits::eBlitDst - | vk::FormatFeatureFlagBits::eBlitSrc - | vk::FormatFeatureFlagBits::eSampledImageFilterLinear, - Format_usage::image_optimal)) + , _r_format(get_supported_format( + {vk::Format::eR8Unorm}, default_image_usage, Format_usage::image_optimal)) + , _rg_format(get_supported_format( + {vk::Format::eR8G8Unorm}, default_image_usage, Format_usage::image_optimal)) + , _rgb_format(get_supported_format( + {vk::Format::eR8G8B8Unorm}, default_image_usage, Format_usage::image_optimal)) + , _rgba_format(get_supported_format( + {vk::Format::eR8G8B8A8Unorm}, default_image_usage, Format_usage::image_optimal)) + + , _sr_format( + get_supported_format({vk::Format::eR8Srgb}, default_image_usage, Format_usage::image_optimal)) + , _srg_format(get_supported_format( + {vk::Format::eR8G8Srgb}, default_image_usage, Format_usage::image_optimal)) + , _srgb_format(get_supported_format( + {vk::Format::eR8G8B8Srgb}, default_image_usage, Format_usage::image_optimal)) + , _srgba_format(get_supported_format( + {vk::Format::eR8G8B8A8Srgb}, default_image_usage, Format_usage::image_optimal)) , _device_specific_asset_loaders(std::make_unique(assets, *this, default_draw_queue)) { @@ -135,15 +121,15 @@ namespace mirrage::graphic { Device::~Device() { - wait_idle(); backup_caches(); - print_memory_usage(std::cerr); + _device_specific_asset_loaders.reset(); - _delete_queue.clear(); - _memory_allocator.shrink_to_fit(); + wait_idle(true); print_memory_usage(std::cerr); + _memory_allocator.shrink_to_fit(); + print_memory_usage(std::cerr); } void Device::print_memory_usage(std::ostream& log) const { @@ -173,7 +159,11 @@ namespace mirrage::graphic { void Device::backup_caches() { if(_pipeline_cache.ready()) { - _assets.save(_pipeline_cache); + try { + _assets.save(_pipeline_cache); + } catch(std::system_error& error) { + LOG(plog::error) << "Unable to save pipeline cache: " << error.what(); + } } } diff --git a/src/mirrage/graphic/src/render_pass.cpp b/src/mirrage/graphic/src/render_pass.cpp index 0b234c51e35457a44b495ec2c550e06de85f4fc6..6356572310e3c5588ba73382f9f99c61155da22b 100644 --- a/src/mirrage/graphic/src/render_pass.cpp +++ b/src/mirrage/graphic/src/render_pass.cpp @@ -129,10 +129,10 @@ namespace mirrage::graphic { const auto default_viewport = vk::Viewport{}; const auto default_viewport_state = vk::PipelineViewportStateCreateInfo{ vk::PipelineViewportStateCreateFlags{}, 1, nullptr, 1, nullptr}; - const vk::DynamicState default_dynamic_states[]{vk::DynamicState::eScissor, - vk::DynamicState::eViewport}; - const auto default_dynamic_state = vk::PipelineDynamicStateCreateInfo{ - vk::PipelineDynamicStateCreateFlags{}, 2, default_dynamic_states}; + const vk::DynamicState default_dynamic_states[]{ + vk::DynamicState::eScissor, vk::DynamicState::eViewport, vk::DynamicState::eBlendConstants}; + const auto default_dynamic_state = vk::PipelineDynamicStateCreateInfo{ + vk::PipelineDynamicStateCreateFlags{}, 3, default_dynamic_states}; } // namespace void Pipeline_description::build_create_info(const vk::Device& device, vk::GraphicsPipelineCreateInfo& cinfo, @@ -324,21 +324,23 @@ namespace mirrage::graphic { vk::AttachmentReference{attachment_idx, vk::ImageLayout::eDepthStencilAttachmentOptimal}; return *this; } - auto Subpass_builder::preserve_attachment(Attachment_ref) -> Subpass_builder& + auto Subpass_builder::preserve_attachment(Attachment_ref attachment) -> Subpass_builder& { - // TODO - MIRRAGE_FAIL("TODO"); + auto attachment_idx = gsl::narrow_cast(reinterpret_cast(attachment)); + _preserve_attachments.emplace_back(attachment_idx); + return *this; } auto Subpass_builder::build_description() -> vk::SubpassDescription { - auto desc = vk::SubpassDescription{}; - desc.colorAttachmentCount = gsl::narrow(_color_attachments.size()); - desc.pColorAttachments = _color_attachments.data(); - desc.inputAttachmentCount = gsl::narrow(_input_attachments.size()); - desc.pInputAttachments = _input_attachments.data(); - // TODO: preserve attachments + auto desc = vk::SubpassDescription{}; + desc.colorAttachmentCount = gsl::narrow(_color_attachments.size()); + desc.pColorAttachments = _color_attachments.data(); + desc.inputAttachmentCount = gsl::narrow(_input_attachments.size()); + desc.pInputAttachments = _input_attachments.data(); + desc.preserveAttachmentCount = gsl::narrow(_preserve_attachments.size()); + desc.pPreserveAttachments = _preserve_attachments.data(); _depth_stencil_attachment.process([&](auto& a) { desc.pDepthStencilAttachment = &a; }); return desc; @@ -392,8 +394,10 @@ namespace mirrage::graphic { vk::DependencyFlags flags) -> Render_pass_builder& { - auto src_id = src.process(VK_SUBPASS_EXTERNAL, [](auto& s) { return s._index; }); - auto dst_id = dst.process(VK_SUBPASS_EXTERNAL, [](auto& s) { return s._index; }); + auto src_id = + src.process(VK_SUBPASS_EXTERNAL, [](auto& s) { return gsl::narrow(s._index); }); + auto dst_id = + dst.process(VK_SUBPASS_EXTERNAL, [](auto& s) { return gsl::narrow(s._index); }); _dependencies.emplace_back( src_id, dst_id, srcStageMask, dstStageMask, srcAccessMask, dstAccessMask, flags); diff --git a/src/mirrage/graphic/src/swapchain.cpp b/src/mirrage/graphic/src/swapchain.cpp index 8f060ca5dbb8ddd3ca56e4d99d82c1bb4dcbd8d8..6670b9f603c34259a7859d81f484a3a2e1ec9a3c 100644 --- a/src/mirrage/graphic/src/swapchain.cpp +++ b/src/mirrage/graphic/src/swapchain.cpp @@ -10,9 +10,9 @@ namespace mirrage::graphic { Window& window, vk::SwapchainCreateInfoKHR info) : Window_modification_handler(window) - , _device(dev) + , _device(&dev) , _gpu(gpu) - , _window(window) + , _window(&window) , _info(info) , _swapchain(dev.createSwapchainKHRUnique(info)) , _images(dev.getSwapchainImagesKHR(*_swapchain)) @@ -37,13 +37,14 @@ namespace mirrage::graphic { ivc.setViewType(vk::ImageViewType::e2D); ivc.setFormat(_info.imageFormat); ivc.setSubresourceRange(vk::ImageSubresourceRange{vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1}); - _image_views.emplace_back(_device.createImageViewUnique(ivc)); + _image_views.emplace_back(_device->createImageViewUnique(ivc)); } } auto Swapchain::acquireNextImage(vk::Semaphore s, vk::Fence f) const -> std::size_t { - return _device.acquireNextImageKHR(*_swapchain, std::numeric_limits::max(), s, f).value; + return _device->acquireNextImageKHR(*_swapchain, std::numeric_limits::max(), s, f) + .value; } bool Swapchain::present(vk::Queue& q, std::size_t img_index, vk::Semaphore s) @@ -53,25 +54,25 @@ namespace mirrage::graphic { auto info = vk::PresentInfoKHR{s ? 1u : 0u, &s, 1, &*_swapchain, &img_index_vk}; auto result = vkQueuePresentKHR(VkQueue(q), reinterpret_cast(&info)); - _window.on_present(); + _window->on_present(); if(result != VK_SUCCESS || _recreate_pending) { _recreate_pending = false; - _device.waitIdle(); + _device->waitIdle(); - auto capabilities = _gpu.getSurfaceCapabilitiesKHR(_window.surface()); + auto capabilities = _gpu.getSurfaceCapabilitiesKHR(_window->surface()); LOG(plog::debug) << "Extends: " << capabilities.currentExtent.width << ", " << capabilities.currentExtent.height; - _image_width = _window.width(); - _image_height = _window.height(); + _image_width = _window->width(); + _image_height = _window->height(); _info.oldSwapchain = *_swapchain; _info.imageExtent.width = gsl::narrow(_image_width); _info.imageExtent.height = gsl::narrow(_image_height); - _swapchain = _device.createSwapchainKHRUnique(_info); - _images = _device.getSwapchainImagesKHR(*_swapchain); + _swapchain = _device->createSwapchainKHRUnique(_info); + _images = _device->getSwapchainImagesKHR(*_swapchain); _create_image_views(); diff --git a/src/mirrage/graphic/src/texture.cpp b/src/mirrage/graphic/src/texture.cpp index 64e7962fc3510775d1174f6210a4d81fa82bb82e..02a1e9e5ab290cc9740a44396983677796b449aa 100644 --- a/src/mirrage/graphic/src/texture.cpp +++ b/src/mirrage/graphic/src/texture.cpp @@ -39,7 +39,7 @@ namespace mirrage::graphic::detail { mipmaps = 9999; mipmaps = glm::clamp( - mipmaps, 1.f, static_cast(std::floor(std::log2(std::min(width, height)))) + 1); + mipmaps, 1, static_cast(std::floor(std::log2(std::min(width, height)))) + 1); return mipmaps; } @@ -113,10 +113,17 @@ namespace mirrage::graphic::detail { format, generate_mipmaps ? 0 : 1, gsl::narrow(data.size_bytes() + 4), - [&](char* dest) { - new(dest) std::uint32_t(gsl::narrow(data.size_bytes())); - dest += 4; - std::memcpy(dest, data.data(), gsl::narrow(data.size_bytes())); + [&, idx = std::uint32_t(0)](char* dest, std::uint32_t size) mutable { + if(idx == 0) { + MIRRAGE_INVARIANT(size >= 4, "unexpected read of less than 4 byte"); + new(dest) std::uint32_t(gsl::narrow(data.size_bytes())); + dest += 4; + idx += 4; + size -= 4; + } + if(size >= 4) { + std::memcpy(dest, data.data() + (idx - 4), size); + } })) , _image_view(device.create_image_view( image(), format, 0, gsl::narrow(_image.mip_level_count()))) @@ -155,13 +162,14 @@ namespace mirrage::graphic::detail { gsl::narrow(header.depth), gsl::narrow(header.layers)); - auto image = device.transfer().upload_image(vk_type(header.type), - owner_qfamily, - dimensions, - header.format, - gsl::narrow(header.mip_levels), - gsl::narrow(header.size), - [&](char* dest) { in.read_direct(dest, header.size); }); + auto image = device.transfer().upload_image( + vk_type(header.type), + owner_qfamily, + dimensions, + header.format, + gsl::narrow(header.mip_levels), + gsl::narrow(header.size), + [&](char* dest, std::uint32_t size) { in.read_direct(dest, size); }); return {std::move(image), header.format, header.type}; } diff --git a/src/mirrage/graphic/src/transfer_manager.cpp b/src/mirrage/graphic/src/transfer_manager.cpp index 3eedf68031cfce32231d561dc6447a5fe3276126..e2c0b4d399ca25cf8394db9b3c49a81cf842ac79 100644 --- a/src/mirrage/graphic/src/transfer_manager.cpp +++ b/src/mirrage/graphic/src/transfer_manager.cpp @@ -135,13 +135,13 @@ namespace mirrage::graphic { Transfer_manager::~Transfer_manager() {} auto Transfer_manager::upload_image(vk::ImageType, - std::uint32_t owner, - const Image_dimensions& dimensions, - vk::Format format, - std::int32_t mip_levels, - std::int32_t size, - std::function write_data, - bool dedicated) -> Static_image + std::uint32_t owner, + const Image_dimensions& dimensions, + vk::Format format, + std::int32_t mip_levels, + std::int32_t size, + std::function write_data, + bool dedicated) -> Static_image { auto stored_mip_levels = std::max(1, mip_levels); @@ -161,8 +161,6 @@ namespace mirrage::graphic { auto ptr = staging_buffer.memory().mapped_addr().get_or_throw("Staging GPU memory is not mapped!"); auto begin_ptr = ptr; - write_data(ptr); - // extract sizes of mip levels auto mip_image_sizes = std::vector(); mip_image_sizes.reserve(gsl::narrow(stored_mip_levels)); @@ -171,10 +169,10 @@ namespace mirrage::graphic { MIRRAGE_INVARIANT(ptr - begin_ptr < size, "buffer overflow"); - auto mip_size = *reinterpret_cast(ptr); - mip_size += 3 - ((mip_size + 3) % 4); // mipPadding - ptr += sizeof(std::uint32_t); // imageSize - ptr += mip_size; // data + auto mip_size = std::uint32_t(0); + write_data(reinterpret_cast(&mip_size), sizeof(mip_size)); + write_data(ptr, mip_size); + ptr += mip_size; mip_image_sizes.emplace_back(mip_size); } @@ -477,7 +475,6 @@ namespace mirrage::graphic { for(auto i : util::range(t.mip_count_loaded)) { auto size = t.mip_image_sizes[std::size_t(i)]; - offset += std::uint32_t((sizeof(std::uint32_t))); // imageSize MIRRAGE_INVARIANT(offset + size <= t.size, "Overflow in _transfer_image"); diff --git a/src/mirrage/graphic/src/vk_wrapper.cpp b/src/mirrage/graphic/src/vk_wrapper.cpp index 5dec2f8d90522117d4e7aba61991c906c7aefe77..e39702bad598eb23d9fcfe3473a23677e46de750 100644 --- a/src/mirrage/graphic/src/vk_wrapper.cpp +++ b/src/mirrage/graphic/src/vk_wrapper.cpp @@ -9,31 +9,35 @@ namespace mirrage::graphic { Command_buffer_pool::Command_buffer_pool(const vk::Device& device, vk::UniqueCommandPool pool) - : _device(device), _pool(std::move(pool)) + : _device(&device), _pool(std::move(pool)) { } - Command_buffer_pool::~Command_buffer_pool() { _device.waitIdle(); } + Command_buffer_pool::~Command_buffer_pool() + { + if(_device) + _device->waitIdle(); + } auto Command_buffer_pool::create_primary(std::int32_t count) -> std::vector { - return _device.allocateCommandBuffersUnique(vk::CommandBufferAllocateInfo( + return _device->allocateCommandBuffersUnique(vk::CommandBufferAllocateInfo( *_pool, vk::CommandBufferLevel::ePrimary, gsl::narrow(count))); } auto Command_buffer_pool::create_secondary(std::int32_t count) -> std::vector { - return _device.allocateCommandBuffersUnique(vk::CommandBufferAllocateInfo( + return _device->allocateCommandBuffersUnique(vk::CommandBufferAllocateInfo( *_pool, vk::CommandBufferLevel::eSecondary, gsl::narrow(count))); } - Fence::operator bool() const { return _device.getFenceStatus(*_fence) == vk::Result::eSuccess; } - void Fence::reset() { _device.resetFences({*_fence}); } - void Fence::wait() { _device.waitForFences({*_fence}, true, std::numeric_limits::max()); } + Fence::operator bool() const { return _device->getFenceStatus(*_fence) == vk::Result::eSuccess; } + void Fence::reset() { _device->resetFences({*_fence}); } + void Fence::wait() { _device->waitForFences({*_fence}, true, std::numeric_limits::max()); } Fence::Fence(const vk::Device& device, bool signaled) - : _device(device) - , _fence(_device.createFenceUnique({signaled ? vk::FenceCreateFlags{vk::FenceCreateFlagBits::eSignaled} - : vk::FenceCreateFlags{}})) + : _device(&device) + , _fence(_device->createFenceUnique({signaled ? vk::FenceCreateFlags{vk::FenceCreateFlagBits::eSignaled} + : vk::FenceCreateFlags{}})) { } diff --git a/src/mirrage/graphic/src/window.cpp b/src/mirrage/graphic/src/window.cpp index b3ec86e79c20a78c06283953bd025c45e7d06a58..debeedbbfe2d0017c0ec370ba67fee9214ba2161 100644 --- a/src/mirrage/graphic/src/window.cpp +++ b/src/mirrage/graphic/src/window.cpp @@ -8,8 +8,8 @@ #include #include -#include -#include +#include +#include #include #include diff --git a/src/mirrage/gui/CMakeLists.txt b/src/mirrage/gui/CMakeLists.txt index 641f92858a5e24e12afb2239118999f7dd9b8126..006e565b7156e3b05b2507b38b0bea8c16167839 100644 --- a/src/mirrage/gui/CMakeLists.txt +++ b/src/mirrage/gui/CMakeLists.txt @@ -1,6 +1,6 @@ -cmake_minimum_required(VERSION 3.2 FATAL_ERROR) +cmake_minimum_required(VERSION 3.9 FATAL_ERROR) -project(mirrage_gui LANGUAGES CXX) +project(mirrage_gui) # need to be specified with the sources for correct syntax highlighting in some IDEs file(GLOB_RECURSE HEADER_FILES @@ -9,13 +9,26 @@ file(GLOB_RECURSE HEADER_FILES ) add_library(mirrage_gui STATIC - src/color_picker.cpp + src/debug_ui.cpp src/gui.cpp - src/menu.cpp - src/text_edit.cpp ${HEADER_FILES} ) add_library(mirrage::gui ALIAS mirrage_gui) +target_compile_features(mirrage_gui PUBLIC cxx_std_17) + +file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/assets_mirrage_gui.map" CONTENT +"cfg:gui = settings/gui.json +cfg:console_history = console_history.txt +font: = fonts/*.ttf +font:default_font = fonts/default_font.ttf +") +mirrage_embed_asset(TARGET mirrage_gui + EXPORT mirrage_gui_targets + SOURCES + "${CMAKE_CURRENT_BINARY_DIR}/assets_mirrage_gui.map" + "${CMAKE_CURRENT_SOURCE_DIR}/assets/fonts" + DEPENDS + "${CMAKE_CURRENT_BINARY_DIR}/assets_mirrage_gui.map") set(MIRRAGE_DEFAULT_COMPILER_ARGS ${MIRRAGE_DEFAULT_COMPILER_ARGS}) target_compile_options(mirrage_gui PRIVATE ${MIRRAGE_DEFAULT_COMPILER_ARGS}) @@ -30,7 +43,7 @@ target_link_libraries(mirrage_gui mirrage::utils gsl glm::glm - nuklear + imgui::imgui mirrage::asset mirrage::input sf2 diff --git a/src/mirrage/gui/assets/fonts/default_font.ttf b/src/mirrage/gui/assets/fonts/default_font.ttf new file mode 100644 index 0000000000000000000000000000000000000000..592ccd20073f76a663c56fe0176397149782565c Binary files /dev/null and b/src/mirrage/gui/assets/fonts/default_font.ttf differ diff --git a/src/mirrage/gui/include/mirrage/gui/debug_ui.hpp b/src/mirrage/gui/include/mirrage/gui/debug_ui.hpp new file mode 100644 index 0000000000000000000000000000000000000000..3c3d837ae2db8e9e3e9f2a5f840670d882269cfa --- /dev/null +++ b/src/mirrage/gui/include/mirrage/gui/debug_ui.hpp @@ -0,0 +1,98 @@ +/** Console and UI elements for debugging ************************************ + * * + * Copyright (c) 2018 Florian Oetke * + * This file is distributed under the MIT License * + * See LICENSE file for details. * +\*****************************************************************************/ + +#pragma once + +#include +#include +#include + +#include + +#include +#include + + +namespace mirrage::gui { + + class Gui; + class Debug_ui; + + class Debug_console_appender : public plog::IAppender { + public: + void write(const plog::Record& record) override; + + private: + friend class Debug_ui; + struct Msg { + plog::Severity severity; + std::string msg; + Msg(plog::Severity s, std::string msg) : severity(s), msg(std::move(msg)) {} + }; + + std::vector _messages; + }; + inline auto& debug_console_appender() + { + static auto inst = Debug_console_appender(); + return inst; + } + + class Debug_ui { + public: + Debug_ui(asset::Asset_manager&, Gui&, util::Message_bus&); + + void draw(); + + private: + Gui& _gui; + util::Mailbox_collection _mailbox; + asset::Asset_manager& _assets; + ImGuiTextFilter _text_filter; + + bool _show_console = false; + bool _scroll_to_bottom = true; + bool _focus_prompt = true; + std::string _command; + + util::Console_command_container _commands; + std::unordered_set _shown_debug_menus; + std::vector _history; + int _current_history_entry = -1; + + void _save_history(); + }; + + + class Debug_menu { + public: + Debug_menu(std::string name); + virtual ~Debug_menu(); + + virtual void draw(Gui&) = 0; + virtual void on_show() {} + virtual void on_hide() {} + + auto name() const noexcept -> auto& { return _name; } + + static void draw_all(const std::string& name, Gui& gui); + static auto is_debug_menu(const std::string& name) -> bool; + static auto print_names() -> std::string; + static auto all_debug_menus() -> const std::vector& { return instances(); } + + private: + friend class Debug_ui; + static auto instances() -> std::vector& + { + static auto list = std::vector(); + return list; + } + + std::string _name; + }; + +} // namespace mirrage::gui diff --git a/src/mirrage/gui/include/mirrage/gui/gui.hpp b/src/mirrage/gui/include/mirrage/gui/gui.hpp index 418631345e98fcb5375d1c43a29cc49f821fa55f..5f757ad07dffee6ac2fb0e6c93fb2330ed0afd2b 100644 --- a/src/mirrage/gui/include/mirrage/gui/gui.hpp +++ b/src/mirrage/gui/include/mirrage/gui/gui.hpp @@ -7,35 +7,89 @@ #pragma once -#include - -#define NK_INCLUDE_FIXED_TYPES -#define NK_INCLUDE_STANDARD_IO -#define NK_INCLUDE_DEFAULT_ALLOCATOR -#define NK_INCLUDE_VERTEX_BUFFER_OUTPUT -#define NK_INCLUDE_FONT_BAKING -#define NK_INCLUDE_DEFAULT_FONT -#include - #include -#include +#include #include #include -#include +#include + +#define IM_VEC2_CLASS_EXTRA \ + ImVec2(const glm::vec2& f) : x(f.x), y(f.y) {} \ + operator glm::vec2() const { return glm::vec2(x, y); } +#define IM_VEC4_CLASS_EXTRA \ + ImVec4(const glm::vec4& f) : x(f.x), y(f.y), z(f.z), w(f.w) {} \ + operator glm::vec4() const { return glm::vec4(x, y, z, w); } + +#include + +#include #include -extern nk_size nk_do_progress(nk_flags* state, - struct nk_command_buffer* out, - struct nk_rect bounds, - nk_size value, - nk_size max, - int modifiable, - const struct nk_style_progress* style, - struct nk_input* in); -struct nk_context; +namespace mirrage::gui::literals { + inline ImColor operator"" _imcolor(const char* str, std::size_t len) + { + auto c = mirrage::util::hex_to_color(str, len); + return {std::pow(c.r, 2.2f), std::pow(c.g, 2.2f), std::pow(c.b, 2.2f), c.a}; + } +} // namespace mirrage::gui::literals + +namespace ImGui { + inline constexpr float SIZE_AUTO = 0.0f; + + enum class WindowPosition_X { center = 0, left = 1, right = 2 }; + enum class WindowPosition_Y { center = 0, top = 1, bottom = 2 }; + + extern void PositionNextWindow(glm::vec2 size, + WindowPosition_X x, + WindowPosition_Y y, + glm::vec2 offset = {}); + + struct Column { + const char* header = ""; + float size = -1.f; + + Column() = default; + /*implicit*/ Column(const char* header, float size = -1) : header(header), size(size) {} + }; + + extern void BeginTable(const char* id, + std::initializer_list, + bool first_call, + bool border = true, + bool separator = true); + + extern float ValueSliderFloat(const char* label, + float v, + float v_min, + float v_max, + const char* format = "%.3f", + float power = 1.0f); + + // ImGui::InputText() with std::string + // Because text input needs dynamic resizing, we need to setup a callback to grow the capacity + IMGUI_API bool InputText(const char* label, + std::string* str, + ImGuiInputTextFlags flags = 0, + ImGuiInputTextCallback callback = nullptr, + void* user_data = nullptr); + IMGUI_API bool InputTextMultiline(const char* label, + std::string* str, + const ImVec2& size = ImVec2(0, 0), + ImGuiInputTextFlags flags = 0, + ImGuiInputTextCallback callback = nullptr, + void* user_data = nullptr); + IMGUI_API bool InputTextWithHint(const char* label, + const char* hint, + std::string* str, + ImGuiInputTextFlags flags = 0, + ImGuiInputTextCallback callback = nullptr, + void* user_data = nullptr); +} // namespace ImGui + +struct ImFont; namespace mirrage { class Engine; @@ -59,9 +113,9 @@ namespace mirrage::gui { } struct Gui_vertex { - glm::vec2 position; - glm::vec2 uv; - nk_byte color[4]; + glm::vec2 position; + glm::vec2 uv; + std::uint8_t color[4]; }; class Gui_renderer_interface { @@ -72,22 +126,26 @@ namespace mirrage::gui { void draw_gui(); virtual auto load_texture(int width, int height, int channels, const std::uint8_t* data) - -> std::shared_ptr = 0; + -> std::shared_ptr = 0; - virtual auto load_texture(const asset::AID&) -> std::shared_ptr = 0; + virtual auto load_texture(const asset::AID&) -> std::shared_ptr = 0; protected: friend class Gui; friend struct detail::Nk_renderer; - virtual void prepare_draw(gsl::span indices, - gsl::span vertices, - glm::mat4 view_proj) = 0; - virtual void draw_elements(int texture_handle, + using Prepare_data_src = std::function; + + virtual void prepare_draw(std::size_t index_count, + std::size_t vertex_count, + glm::mat4 view_proj, + Prepare_data_src write_data) = 0; + virtual void draw_elements(void* texture_handle, glm::vec4 clip_rect, std::uint32_t offset, - std::uint32_t count) = 0; - virtual void finalize_draw() = 0; + std::uint32_t count, + std::uint32_t vertex_offset) = 0; + virtual void finalize_draw() = 0; private: template @@ -96,10 +154,7 @@ namespace mirrage::gui { Gui* _gui; }; - // TODO: gamepad input: https://gist.github.com/vurtun/519801825b4ccfad6767 - // https://github.com/vurtun/nuklear/issues/50 - // TODO: theme support: https://github.com/vurtun/nuklear/blob/master/demo/style.c - // https://github.com/vurtun/nuklear/blob/master/example/skinning.c + class Gui { public: Gui(glm::vec4 viewport, asset::Asset_manager& assets, input::Input_manager& input); @@ -108,20 +163,14 @@ namespace mirrage::gui { void draw(); void start_frame(); - auto ctx() -> nk_context*; + auto find_font(util::Str_id) const -> util::maybe; auto viewport() const noexcept { return _viewport; } - auto virtual_viewport() const noexcept -> glm::vec4; - void viewport(glm::vec4 new_viewport); - auto centered(int width, int height) -> struct nk_rect; - auto centered_left(int width, int height) -> struct nk_rect; - auto centered_right(int width, int height) -> struct nk_rect; - auto ready() const noexcept { return bool(_impl); } - auto load_texture(const asset::AID&) -> std::shared_ptr; + auto load_texture(const asset::AID&) -> std::shared_ptr; private: template @@ -157,32 +206,4 @@ namespace mirrage::gui { } }; - - // widgets - extern bool color_picker(nk_context*, util::Rgb& color, float width, float factor = 1.f); - extern bool color_picker(nk_context*, util::Rgba& color, float width, float factor = 1.f); - - extern void begin_menu(nk_context*, int& active); - extern bool menu_button(nk_context*, const char* text, bool enabled = true); - extern void end_menu(nk_context*); - - class Text_edit { - public: - Text_edit(); - Text_edit(Text_edit&&) = default; - Text_edit& operator=(Text_edit&&) = default; - ~Text_edit(); - - void reset(const std::string&); - void get(std::string&) const; - - auto active() const noexcept { return _active; } - - void update_and_draw(nk_context*, nk_flags type); - void update_and_draw(nk_context*, nk_flags type, std::string&); - - private: - util::maybe _data; - bool _active = false; - }; } // namespace mirrage::gui diff --git a/src/mirrage/gui/src/color_picker.cpp b/src/mirrage/gui/src/color_picker.cpp deleted file mode 100644 index 0da7d9ed6f9ca512415c6573abb97ae59b9f0c44..0000000000000000000000000000000000000000 --- a/src/mirrage/gui/src/color_picker.cpp +++ /dev/null @@ -1,64 +0,0 @@ -#include - -#include - - -namespace mirrage::gui { - - namespace { - bool color_picker(nk_context* ctx, nk_colorf& cf, float width, bool hasAlpha) - { - auto c = nk_color{static_cast(cf.r * 255), - static_cast(cf.g * 255), - static_cast(cf.b * 255), - static_cast(cf.a * 255)}; - if(nk_combo_begin_color(ctx, c, nk_vec2(width, width))) { - nk_layout_row_dynamic(ctx, 120, 1); - cf = nk_color_picker(ctx, cf, hasAlpha ? NK_RGBA : NK_RGB); - - nk_layout_row_dynamic(ctx, 14, 1); - cf.r = nk_propertyf(ctx, "#R:", 0, cf.r, 1, 0.1f, 0.01f); - cf.g = nk_propertyf(ctx, "#G:", 0, cf.g, 1, 0.1f, 0.01f); - cf.b = nk_propertyf(ctx, "#B:", 0, cf.b, 1, 0.1f, 0.01f); - if(hasAlpha) { - cf.a = nk_propertyf(ctx, "#A:", 0, cf.a, 1, 0.1f, 0.01f); - } - - nk_combo_end(ctx); - - return true; - } - return false; - } - } // namespace - - bool color_picker(nk_context* ctx, util::Rgb& color, float width, float factor) - { - nk_colorf c = nk_colorf{color.r / factor, color.g / factor, color.b / factor, 1.f}; - - if(color_picker(ctx, c, width, false)) { - auto newColor = util::Rgb{c.r * factor, c.g * factor, c.b * factor}; - - if(glm::length2(newColor - color) > 0.0001f) { - color = newColor; - return true; - } - } - return false; - } - - bool color_picker(nk_context* ctx, util::Rgba& color, float width, float factor) - { - nk_colorf c = nk_colorf{color.r / factor, color.g / factor, color.b / factor, color.a / factor}; - - if(color_picker(ctx, c, width, true)) { - auto newColor = util::Rgba{c.r * factor, c.g * factor, c.b * factor, c.a * factor}; - - if(glm::length2(newColor - color) > 0.0001f) { - color = newColor; - return true; - } - } - return false; - } -} // namespace mirrage::gui diff --git a/src/mirrage/gui/src/debug_ui.cpp b/src/mirrage/gui/src/debug_ui.cpp new file mode 100644 index 0000000000000000000000000000000000000000..05e37236218eeefa864f77ac67e22e89f6a3b3af --- /dev/null +++ b/src/mirrage/gui/src/debug_ui.cpp @@ -0,0 +1,329 @@ +#include + +#include + +#include +#include +#include + +#include + + +template +void quick_exit(int) noexcept +{ + std::abort(); +} +void mirrage_quick_exit() noexcept +{ + using namespace std; + // calls std::quick_exit if it exists or the template-fallback defined above, if not + // needs to be at global scope for this workaround to work correctly + quick_exit(0); +} + +namespace mirrage::gui { + + namespace { + const auto msg_color = std::array{{ + ImVec4{255, 255, 255, 255}, // none = 0, + ImVec4{255, 0, 0, 255}, // fatal = 1, + ImVec4{255, 128, 0, 255}, // error = 2, + ImVec4{255, 200, 80, 255}, // warning = 3, + ImVec4{255, 255, 255, 255}, // info = 4, + ImVec4{140, 140, 140, 255}, // debug = 5, + ImVec4{140, 140, 140, 255} // verbose = 6 + }}; + + const auto history_aid = "cfg:console_history"_aid; + } // namespace + + void Debug_console_appender::write(const plog::Record& record) + { + auto msg = +#ifdef _WIN32 + plog::util::toNarrow(plog::TxtFormatter::format(record), 0); +#else + plog::TxtFormatter::format(record); +#endif + auto prev_pos = std::string::size_type(0); + auto pos = std::string::size_type(0); + while((pos = msg.find("\n", prev_pos)) != std::string::npos) { + auto len = pos - prev_pos + 1; + if(len > 0) + _messages.emplace_back(record.getSeverity(), + prev_pos == 0 ? msg.substr(prev_pos, pos - prev_pos) + : " " + msg.substr(prev_pos, pos - prev_pos)); + + prev_pos = pos + 1; + } + } + + + Debug_ui::Debug_ui(asset::Asset_manager& assets, Gui& gui, util::Message_bus& bus) + : _gui(gui), _mailbox(bus), _assets(assets) + { + assets.open(history_aid).process([&](auto& is) { _history = is.lines(); }); + + _commands.add("help | Prints all available commands", [&]() { + auto stream = std::stringstream{}; + auto max_width = 0; + for(auto& c : util::Console_command_container::list_all_commands()) { + auto sep = c.second->api().find("|"); + max_width = std::max(max_width, int(sep != std::string::npos ? sep : c.second->api().size())); + } + + for(auto& c : util::Console_command_container::list_all_commands()) { + auto sep = c.second->api().find("|"); + + stream << c.second->api().substr(0, sep); + for(int i = int(sep != std::string::npos ? sep : c.second->api().size()); i < max_width + 10; + i++) + stream << ' '; + + if(sep != std::string::npos) + stream << c.second->api().substr(sep + 1); + + stream << "\n"; + } + + LOG(plog::info) << "Available commands:\n" << stream.str(); + }); + + _commands.add("history | Prints all previous commands", [&]() { + IF_LOG_(PLOG_DEFAULT_INSTANCE, plog::info) + { + auto record = + plog::Record(plog::info, PLOG_GET_FUNC(), __LINE__, PLOG_GET_FILE(), PLOG_GET_THIS()); + + record << "History:\n"; + for(auto& h : _history) { + record << h << "\n"; + } + + (*plog::get()) += std::move(record); + } + }); + _commands.add("history.clear | Clears the history", [&]() { + _history.clear(); + _save_history(); + }); + + _commands.add("show | Enables a specific debug UI element (see list_uis for possible options)", + [&](std::string ui) { + if(Debug_menu::is_debug_menu(ui)) { + _shown_debug_menus.insert(std::move(ui)); + _show_console = false; + } else + LOG(plog::error) << "Unknown ui menu " << ui + << " expected one of: " << Debug_menu::print_names(); + }); + _commands.add("show.all | Enables all debug UI elements", [&] { + for(auto& m : Debug_menu::all_debug_menus()) { + _shown_debug_menus.insert(m->name()); + _show_console = false; + } + }); + _commands.add("hide | Disables a specific debug UI element (see list_uis for possible options)", + [&](std::string ui) { + if(Debug_menu::is_debug_menu(ui)) + _shown_debug_menus.erase(ui); + else + LOG(plog::error) << "Unknown ui menu " << ui + << " expected one of: " << Debug_menu::print_names(); + }); + _commands.add("hide.all | Disables all debug UI elements", [&] { _shown_debug_menus.clear(); }); + + _commands.add("list_uis | Lists all available debug UI elements", + [&]() { LOG(plog::info) << "UI menus: " << Debug_menu::print_names(); }); + + _mailbox.subscribe_to([&](input::Once_action& e) { + switch(e.id) { + case "fast_quit"_strid: mirrage_quick_exit(); break; + case "console"_strid: + _show_console = !_show_console; + _focus_prompt = true; + break; + } + }); + } + + void Debug_ui::draw() + { + _mailbox.update_subscriptions(); + + for(auto& dm : _shown_debug_menus) { + Debug_menu::draw_all(dm, _gui); + } + + if(!_show_console) + return; + + auto viewport = _gui.viewport(); + auto width = viewport.z; + auto height = 300.f; + + ImGui::PositionNextWindow( + {width, height}, ImGui::WindowPosition_X::center, ImGui::WindowPosition_Y::top); + if(ImGui::Begin("debug_console", + nullptr, + {width, height}, + ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove + | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse)) { + + _text_filter.Draw("Filter (\"incl,-excl\") (\"error\")"); + ImGui::Separator(); + + auto footer_height_to_reserve = + ImGui::GetStyle().ItemSpacing.y + ImGui::GetFrameHeightWithSpacing(); + if(ImGui::BeginChild("ScrollingRegion", + ImVec2(0, -footer_height_to_reserve), + false, + ImGuiWindowFlags_HorizontalScrollbar)) { + + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(4, 1)); + for(const auto& msg : debug_console_appender()._messages) { + if(!_text_filter.PassFilter(msg.msg.c_str())) + continue; + + ImGui::PushStyleColor(ImGuiCol_Text, msg_color[std::size_t(msg.severity)]); + ImGui::TextUnformatted(msg.msg.c_str()); + ImGui::PopStyleColor(); + } + + if(_scroll_to_bottom) { + ImGui::SetScrollHereY(1.0f); + _scroll_to_bottom = false; + } + ImGui::PopStyleVar(); + } + ImGui::EndChild(); + ImGui::Separator(); + + + // command prompt + bool reclaim_focus = false; + + auto input_callback = +[](ImGuiInputTextCallbackData* data) -> int { + auto self = reinterpret_cast(data->UserData); + switch(data->EventFlag) { + case ImGuiInputTextFlags_CallbackCompletion: { + auto cmd = std::string(data->Buf, data->Buf + data->CursorPos); + auto suggestions = util::Console_command_container::complete(cmd); + + if(suggestions.empty()) { + debug_console_appender()._messages.emplace_back(plog::Severity::verbose, + "Unknown command: " + cmd); + + } else if(suggestions.size() == 1) { + data->DeleteChars(0, int(cmd.size())); + data->InsertChars(0, suggestions.front()->name().c_str()); + data->CursorPos = int(suggestions.front()->name().size()); + debug_console_appender()._messages.emplace_back(plog::Severity::verbose, + suggestions.front()->api()); + } else { + // TODO: move to popup + debug_console_appender()._messages.emplace_back(plog::Severity::verbose, + "Command Suggestions:"); + for(auto& s : suggestions) { + debug_console_appender()._messages.emplace_back(plog::Severity::verbose, + s->api()); + } + } + self->_scroll_to_bottom = true; + + break; + } + + case ImGuiInputTextFlags_CallbackHistory: { + auto prev = self->_current_history_entry; + if(data->EventKey == ImGuiKey_UpArrow) { + if(self->_current_history_entry == -1) + self->_current_history_entry = int(self->_history.size()) - 1; + else if(self->_current_history_entry > 0) + self->_current_history_entry--; + } else if(data->EventKey == ImGuiKey_DownArrow) { + if(self->_current_history_entry != -1) + if(++self->_current_history_entry >= int(self->_history.size())) + self->_current_history_entry = -1; + } + + // A better implementation would preserve the data on the current input line along with cursor position. + if(prev != self->_current_history_entry) { + const char* history_str = + (self->_current_history_entry >= 0) + ? self->_history[std::size_t(self->_current_history_entry)].c_str() + : ""; + data->DeleteChars(0, data->BufTextLen); + data->InsertChars(0, history_str); + } + break; + } + } + return 0; + }; + + if(ImGui::InputText("", + &_command, + ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_CallbackCompletion + | ImGuiInputTextFlags_CallbackHistory, + input_callback, + this)) { + if(util::Console_command_container::call(_command)) { + _history.emplace_back(_command); + _save_history(); + _command.clear(); + } + reclaim_focus = true; + } + + // Auto-focus on window apparition + ImGui::SetItemDefaultFocus(); + if(reclaim_focus) + ImGui::SetKeyboardFocusHere(-1); // Auto focus previous widget + } + ImGui::End(); + } + + void Debug_ui::_save_history() + { + auto os = _assets.open_rw(history_aid); + for(auto& h : _history) + os << h << "\n"; + os.close(); + } + + + Debug_menu::Debug_menu(std::string name) : _name(std::move(name)) { instances().emplace_back(this); } + Debug_menu::~Debug_menu() { util::erase_fast(instances(), this); } + + void Debug_menu::draw_all(const std::string& name, Gui& gui) + { + for(auto dm : instances()) + if(dm->_name == name) + dm->draw(gui); + } + auto Debug_menu::is_debug_menu(const std::string& name) -> bool + { + for(auto dm : instances()) + if(dm->_name == name) + return true; + + return false; + } + auto Debug_menu::print_names() -> std::string + { + auto stream = std::stringstream{}; + auto first = true; + for(auto dm : instances()) { + if(first) + first = false; + else + stream << ", "; + + stream << dm->_name; + } + return stream.str(); + } + +} // namespace mirrage::gui diff --git a/src/mirrage/gui/src/gui.cpp b/src/mirrage/gui/src/gui.cpp index 7ca9adafccee469d5482c12eb74d02a2bdab078d..85c17b847385544d4ba921c66443aefdad054f60 100644 --- a/src/mirrage/gui/src/gui.cpp +++ b/src/mirrage/gui/src/gui.cpp @@ -1,195 +1,400 @@ -#define NK_IMPLEMENTATION -#define NK_LIB +#include #include #include #include #include +#include -#include +#include +#include #include #include -#include #include #include +#ifdef _WIN32 +#include "SDL_syswm.h" +#endif -namespace mirrage::gui { - namespace { - struct Nk_renderer; +extern void ref_embedded_assets_mirrage_gui(); - struct Font_desc { - std::string aid; - float size; - bool default_font = false; - }; - - struct Gui_cfg { - std::vector fonts; - }; - sf2_structDef(Font_desc, aid, size, default_font); - sf2_structDef(Gui_cfg, fonts); +namespace ImGui { - void nk_sdl_clipbard_paste(nk_handle, struct nk_text_edit* edit) - { - auto text = SDL_GetClipboardText(); - if(text) { - nk_textedit_paste(edit, text, nk_strlen(text)); - } - } + void PositionNextWindow(glm::vec2 size, WindowPosition_X x, WindowPosition_Y y, glm::vec2 offset) + { + auto sw = GetIO().DisplaySize.x; + auto sh = GetIO().DisplaySize.y; - void nk_sdl_clipbard_copy(nk_handle, const char* text, int len) - { - if(len <= 0) - return; + SetNextWindowSize(ImVec2(size.x, size.y), ImGuiCond_Once); - auto str = std::string(text, static_cast(len)); - SDL_SetClipboardText(str.c_str()); + auto position = ImVec2(offset.x, offset.y); + switch(x) { + case WindowPosition_X::left: position.x += 0.f; break; + case WindowPosition_X::right: position.x += sw - size.x; break; + case WindowPosition_X::center: position.x += sw / 2.f - size.x / 2.f; break; } - auto sdl_to_nk_mb(Uint8 button) -> util::maybe - { - switch(button) { - case SDL_BUTTON_LEFT: return NK_BUTTON_LEFT; - case SDL_BUTTON_MIDDLE: return NK_BUTTON_MIDDLE; - case SDL_BUTTON_RIGHT: return NK_BUTTON_RIGHT; - default: return util::nothing; - } + switch(y) { + case WindowPosition_Y::top: position.y += 0.f; break; + case WindowPosition_Y::bottom: position.y += sh - size.y; break; + case WindowPosition_Y::center: position.y += sh / 2.f - size.y / 2.f; break; } - class Gui_event_filter : public input::Sdl_event_filter { - public: - Gui_event_filter(input::Input_manager& input_mgr, - nk_context* ctx, - const glm::vec4& viewport, - const glm::mat4& ui_matrix) - : Sdl_event_filter(input_mgr) - , _input_mgr(input_mgr) - , _ctx(ctx) - , _viewport(viewport) - , _ui_matrix(ui_matrix) - { - } + SetNextWindowPos(position, ImGuiCond_Once); + } - void pre_input_events() override - { - _grab_clicks = nk_window_is_any_hovered(_ctx); - _grab_inputs = nk_item_is_any_active(_ctx); + void BeginTable(const char* id, + std::initializer_list columns, + bool first_call, + bool border, + bool separator) + { + ImGui::Columns(int(columns.size()), id, border); - nk_input_begin(_ctx); - } - void post_input_events() override { nk_input_end(_ctx); } + if(separator) + ImGui::Separator(); - bool handle_key(bool down, SDL_Keycode key) - { - const auto state = SDL_GetKeyboardState(nullptr); - const auto ctrl = state[SDL_SCANCODE_LCTRL] || state[SDL_SCANCODE_RCTRL]; + float offset = 0.0f; + ImGuiStyle& style = ImGui::GetStyle(); - switch(key) { - case SDLK_RSHIFT: - case SDLK_LSHIFT: nk_input_key(_ctx, NK_KEY_SHIFT, down); return false; + for(auto& column : columns) { + if(first_call) { + auto width = column.size >= 0 ? column.size + : (ImGui::CalcTextSize(column.header, nullptr, true).x + + 2 * style.ItemSpacing.x); - case SDLK_DELETE: nk_input_key(_ctx, NK_KEY_DEL, down); return false; + ImGui::SetColumnOffset(-1, offset); + ImGui::SetColumnWidth(-1, width); - case SDLK_RETURN: nk_input_key(_ctx, NK_KEY_ENTER, down); return false; + offset += width; + } + ImGui::Text("%s", column.header); + ImGui::NextColumn(); + } - case SDLK_TAB: nk_input_key(_ctx, NK_KEY_TAB, down); return false; + if(separator) + ImGui::Separator(); + } - case SDLK_BACKSPACE: nk_input_key(_ctx, NK_KEY_BACKSPACE, down); return false; + float ValueSliderFloat( + const char* label, float v, float v_min, float v_max, const char* format, float power) + { + SliderFloat(label, &v, v_min, v_max, format, power); + return v; + } +} // namespace ImGui + + +// copied from imgui_stdlib.cpp +struct InputTextCallback_UserData { + std::string* Str; + ImGuiInputTextCallback ChainCallback; + void* ChainCallbackUserData; +}; + +static int InputTextCallback(ImGuiInputTextCallbackData* data) +{ + InputTextCallback_UserData* user_data = static_cast(data->UserData); + if(data->EventFlag == ImGuiInputTextFlags_CallbackResize) { + // Resize string callback + // If for some reason we refuse the new length (BufTextLen) and/or capacity (BufSize) we need to set them back to what we want. + std::string* str = user_data->Str; + IM_ASSERT(data->Buf == str->c_str()); + str->resize(std::size_t(data->BufTextLen)); + data->Buf = const_cast(str->c_str()); + } else if(user_data->ChainCallback) { + // Forward to user callback, if any + data->UserData = user_data->ChainCallbackUserData; + return user_data->ChainCallback(data); + } + return 0; +} + +bool ImGui::InputText(const char* label, + std::string* str, + ImGuiInputTextFlags flags, + ImGuiInputTextCallback callback, + void* user_data) +{ + IM_ASSERT((flags & ImGuiInputTextFlags_CallbackResize) == 0); + flags |= ImGuiInputTextFlags_CallbackResize; + + InputTextCallback_UserData cb_user_data; + cb_user_data.Str = str; + cb_user_data.ChainCallback = callback; + cb_user_data.ChainCallbackUserData = user_data; + return InputText(label, + const_cast(str->c_str()), + str->capacity() + 1, + flags, + InputTextCallback, + &cb_user_data); +} + +bool ImGui::InputTextMultiline(const char* label, + std::string* str, + const ImVec2& size, + ImGuiInputTextFlags flags, + ImGuiInputTextCallback callback, + void* user_data) +{ + IM_ASSERT((flags & ImGuiInputTextFlags_CallbackResize) == 0); + flags |= ImGuiInputTextFlags_CallbackResize; + + InputTextCallback_UserData cb_user_data; + cb_user_data.Str = str; + cb_user_data.ChainCallback = callback; + cb_user_data.ChainCallbackUserData = user_data; + return InputTextMultiline(label, + const_cast(str->c_str()), + str->capacity() + 1, + size, + flags, + InputTextCallback, + &cb_user_data); +} + +bool ImGui::InputTextWithHint(const char* label, + const char* hint, + std::string* str, + ImGuiInputTextFlags flags, + ImGuiInputTextCallback callback, + void* user_data) +{ + IM_ASSERT((flags & ImGuiInputTextFlags_CallbackResize) == 0); + flags |= ImGuiInputTextFlags_CallbackResize; + + InputTextCallback_UserData cb_user_data; + cb_user_data.Str = str; + cb_user_data.ChainCallback = callback; + cb_user_data.ChainCallbackUserData = user_data; + return InputTextWithHint(label, + hint, + const_cast(str->c_str()), + str->capacity() + 1, + flags, + InputTextCallback, + &cb_user_data); +} - case SDLK_HOME: - nk_input_key(_ctx, NK_KEY_TEXT_START, down); - nk_input_key(_ctx, NK_KEY_SCROLL_START, down); - return false; - case SDLK_END: - nk_input_key(_ctx, NK_KEY_TEXT_END, down); - nk_input_key(_ctx, NK_KEY_SCROLL_END, down); - return false; - case SDLK_PAGEDOWN: nk_input_key(_ctx, NK_KEY_SCROLL_DOWN, down); return false; - case SDLK_PAGEUP: nk_input_key(_ctx, NK_KEY_SCROLL_UP, down); return false; +namespace mirrage::gui { - case SDLK_z: nk_input_key(_ctx, NK_KEY_TEXT_UNDO, down && ctrl); return false; - case SDLK_y: nk_input_key(_ctx, NK_KEY_TEXT_REDO, down && ctrl); return false; + namespace { + struct Font_desc { + util::Str_id id; + std::string aid; + float size; + }; - case SDLK_c: nk_input_key(_ctx, NK_KEY_COPY, down && ctrl); return false; - case SDLK_x: nk_input_key(_ctx, NK_KEY_CUT, down && ctrl); return false; - case SDLK_v: nk_input_key(_ctx, NK_KEY_PASTE, down && ctrl); return false; + struct Gui_cfg { + std::vector fonts; + }; + sf2_structDef(Font_desc, id, aid, size); + sf2_structDef(Gui_cfg, fonts); + + void set_clipboard(void*, const char* text) { SDL_SetClipboardText(text); } + + class Gui_event_filter : public input::Sdl_event_filter { + public: + Gui_event_filter(input::Input_manager& input_mgr) + : Sdl_event_filter(input_mgr), _input_mgr(input_mgr) + { + _cursors[ImGuiMouseCursor_Arrow] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW); + _cursors[ImGuiMouseCursor_TextInput] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_IBEAM); + _cursors[ImGuiMouseCursor_ResizeAll] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEALL); + _cursors[ImGuiMouseCursor_ResizeNS] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENS); + _cursors[ImGuiMouseCursor_ResizeEW] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEWE); + _cursors[ImGuiMouseCursor_ResizeNESW] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENESW); + _cursors[ImGuiMouseCursor_ResizeNWSE] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENWSE); + _cursors[ImGuiMouseCursor_Hand] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_HAND); + + ImGuiIO& io = ImGui::GetIO(); + io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; + io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; + io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; + io.IniFilename = nullptr; + + // Keyboard mapping. ImGui will use those indices to peek into the io.KeysDown[] array. + io.KeyMap[ImGuiKey_Tab] = SDL_SCANCODE_TAB; + io.KeyMap[ImGuiKey_LeftArrow] = SDL_SCANCODE_LEFT; + io.KeyMap[ImGuiKey_RightArrow] = SDL_SCANCODE_RIGHT; + io.KeyMap[ImGuiKey_UpArrow] = SDL_SCANCODE_UP; + io.KeyMap[ImGuiKey_DownArrow] = SDL_SCANCODE_DOWN; + io.KeyMap[ImGuiKey_PageUp] = SDL_SCANCODE_PAGEUP; + io.KeyMap[ImGuiKey_PageDown] = SDL_SCANCODE_PAGEDOWN; + io.KeyMap[ImGuiKey_Home] = SDL_SCANCODE_HOME; + io.KeyMap[ImGuiKey_End] = SDL_SCANCODE_END; + io.KeyMap[ImGuiKey_Insert] = SDL_SCANCODE_INSERT; + io.KeyMap[ImGuiKey_Delete] = SDL_SCANCODE_DELETE; + io.KeyMap[ImGuiKey_Backspace] = SDL_SCANCODE_BACKSPACE; + io.KeyMap[ImGuiKey_Space] = SDL_SCANCODE_SPACE; + io.KeyMap[ImGuiKey_Enter] = SDL_SCANCODE_RETURN; + io.KeyMap[ImGuiKey_Escape] = SDL_SCANCODE_ESCAPE; + io.KeyMap[ImGuiKey_A] = SDL_SCANCODE_A; + io.KeyMap[ImGuiKey_C] = SDL_SCANCODE_C; + io.KeyMap[ImGuiKey_V] = SDL_SCANCODE_V; + io.KeyMap[ImGuiKey_X] = SDL_SCANCODE_X; + io.KeyMap[ImGuiKey_Y] = SDL_SCANCODE_Y; + io.KeyMap[ImGuiKey_Z] = SDL_SCANCODE_Z; + + io.ClipboardUserData = this; + io.SetClipboardTextFn = set_clipboard; + io.GetClipboardTextFn = +[](void* userdata) -> const char* { + return reinterpret_cast(userdata)->get_clipboard(); + }; + +#ifdef _WIN32 + SDL_SysWMinfo wmInfo; + SDL_VERSION(&wmInfo.version); + SDL_GetWindowWMInfo(_input_mgr.window(), &wmInfo); + io.ImeWindowHandle = wmInfo.info.win.window; +#endif + } - case SDLK_b: nk_input_key(_ctx, NK_KEY_TEXT_LINE_START, down && ctrl); return false; - case SDLK_e: nk_input_key(_ctx, NK_KEY_TEXT_LINE_END, down && ctrl); return false; + auto get_clipboard() -> char* + { + _clipboard_data = {SDL_GetClipboardText(), SDL_free}; + return reinterpret_cast(_clipboard_data.get()); + } - case SDLK_LEFT: - nk_input_key(_ctx, NK_KEY_TEXT_WORD_LEFT, down && ctrl); - nk_input_key(_ctx, NK_KEY_LEFT, down && !ctrl); - return false; + void notify_frame_rendered() { _last_frame_rendered = true; } - case SDLK_RIGHT: - nk_input_key(_ctx, NK_KEY_TEXT_WORD_RIGHT, down && ctrl); - nk_input_key(_ctx, NK_KEY_RIGHT, down && !ctrl); - return false; + void pre_input_events() override + { + if(!_last_frame_rendered) + ImGui::EndFrame(); + } - default: return true; + void post_input_events() override + { + ImGuiIO& io = ImGui::GetIO(); + auto window = _input_mgr.window(); + + int w, h; + int display_w, display_h; + SDL_GetWindowSize(window, &w, &h); + SDL_GL_GetDrawableSize(window, &display_w, &display_h); + io.DisplaySize = ImVec2(static_cast(w), static_cast(h)); + if(w > 0 && h > 0) + io.DisplayFramebufferScale = + ImVec2(static_cast(display_w) / w, static_cast(display_h) / h); + + // Setup time step (we don't use SDL_GetTicks() because it is using millisecond resolution) + static const auto frequency = SDL_GetPerformanceFrequency(); + auto current_time = SDL_GetPerformanceCounter(); + io.DeltaTime = + _time > 0 ? static_cast(static_cast(current_time - _time) / frequency) + : (1.0f / 60.0f); + _time = current_time; + + + if(io.WantSetMousePos) + SDL_WarpMouseInWindow( + window, static_cast(io.MousePos.x), static_cast(io.MousePos.y)); + else + io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX); + + int mx, my; + Uint32 mouse_buttons = SDL_GetMouseState(&mx, &my); + io.MouseDown[0] = + _mouse_pressed[0] + || (mouse_buttons & SDL_BUTTON(SDL_BUTTON_LEFT)) + != 0; // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame. + io.MouseDown[1] = _mouse_pressed[1] || (mouse_buttons & SDL_BUTTON(SDL_BUTTON_RIGHT)) != 0; + io.MouseDown[2] = _mouse_pressed[2] || (mouse_buttons & SDL_BUTTON(SDL_BUTTON_MIDDLE)) != 0; + _mouse_pressed[0] = _mouse_pressed[1] = _mouse_pressed[2] = false; + +#if !defined(__EMSCRIPTEN__) && !defined(__ANDROID__) && !(defined(__APPLE__) && TARGET_OS_IOS) + SDL_Window* focused_window = SDL_GetKeyboardFocus(); + if(_input_mgr.window() == focused_window) { + // SDL_GetMouseState() gives mouse position seemingly based on the last window entered/focused(?) + // The creation of a new windows at runtime and SDL_CaptureMouse both seems to severely mess up with that, so we retrieve that position globally. + int wx, wy; + SDL_GetWindowPosition(focused_window, &wx, &wy); + SDL_GetGlobalMouseState(&mx, &my); + mx -= wx; + my -= wy; + io.MousePos = ImVec2(static_cast(mx), static_cast(my)); } + + // SDL_CaptureMouse() let the OS know e.g. that our imgui drag outside the SDL window boundaries shouldn't e.g. trigger the OS window resize cursor. + // The function is only supported from SDL 2.0.4 (released Jan 2016) + bool any_mouse_button_down = ImGui::IsAnyMouseDown(); + SDL_CaptureMouse(any_mouse_button_down ? SDL_TRUE : SDL_FALSE); +#else + if(SDL_GetWindowFlags(window) & SDL_WINDOW_INPUT_FOCUS) + io.MousePos = ImVec2(static_cast(mx), static_cast(my)); +#endif + + // update cursor icon + if(!(io.ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange)) { + auto imgui_cursor = ImGui::GetMouseCursor(); + + if(io.MouseDrawCursor || imgui_cursor == ImGuiMouseCursor_None) { + // Hide OS mouse cursor if imgui is drawing it or if it wants no cursor + SDL_ShowCursor(SDL_FALSE); + } else { + // Show OS mouse cursor + auto idx = std::size_t(imgui_cursor); + SDL_SetCursor(_cursors[idx].data + ? _cursors[idx].data + : _cursors[std::size_t(ImGuiMouseCursor_Arrow)].data); + SDL_ShowCursor(SDL_TRUE); + } + } + + ImGui::NewFrame(); + _last_frame_rendered = false; + } + + void handle_key(bool down, SDL_Scancode key) + { + ImGuiIO& io = ImGui::GetIO(); + + IM_ASSERT(key >= 0 && key < static_cast(sizeof(io.KeysDown) / sizeof(*io.KeysDown))); + io.KeysDown[key] = down; + io.KeyShift = ((SDL_GetModState() & KMOD_SHIFT) != 0); + io.KeyCtrl = ((SDL_GetModState() & KMOD_CTRL) != 0); + io.KeyAlt = ((SDL_GetModState() & KMOD_ALT) != 0); + io.KeySuper = ((SDL_GetModState() & KMOD_GUI) != 0); } bool propagate(SDL_Event& evt) override { + ImGuiIO& io = ImGui::GetIO(); + switch(evt.type) { case SDL_KEYUP: case SDL_KEYDOWN: - if(!_grab_inputs) - return true; - - handle_key(evt.type == SDL_KEYDOWN, evt.key.keysym.sym); - return evt.key.keysym.sym == SDLK_ESCAPE; + handle_key(evt.type == SDL_KEYDOWN, evt.key.keysym.scancode); + return evt.key.keysym.sym == SDLK_ESCAPE || !io.WantCaptureKeyboard; + case SDL_MOUSEBUTTONUP: return !io.WantCaptureMouse; case SDL_MOUSEBUTTONDOWN: - case SDL_MOUSEBUTTONUP: - sdl_to_nk_mb(evt.button.button).process([&](auto button) { - auto p = glm::unProject(glm::vec3{evt.button.x, evt.button.y, 0.99f}, - glm::mat4(1), - _ui_matrix, - _viewport); - nk_input_button(_ctx, - button, - static_cast(p.x), - static_cast(p.y), - evt.type == SDL_MOUSEBUTTONDOWN); - }); - return !_grab_clicks; - - case SDL_MOUSEMOTION: { - if(!_input_mgr.capture_mouse()) { - auto p = glm::unProject(glm::vec3{evt.motion.x, evt.motion.y, 0.99f}, - glm::mat4(1), - _ui_matrix, - _viewport); - nk_input_motion(_ctx, static_cast(p.x), static_cast(p.y)); + if(evt.button.button > 0 && evt.button.button < 4) { + _mouse_pressed[evt.button.button - 1] = true; } - return true; //< never swallow mouse-move - } + return !io.WantCaptureMouse; case SDL_MOUSEWHEEL: - if(!_grab_clicks) - return true; - - nk_input_scroll( - _ctx, - nk_vec2(static_cast(evt.wheel.x), static_cast(evt.wheel.y))); - return false; + if(evt.wheel.x > 0) + io.MouseWheelH += 1; + if(evt.wheel.x < 0) + io.MouseWheelH -= 1; + if(evt.wheel.y > 0) + io.MouseWheel += 1; + if(evt.wheel.y < 0) + io.MouseWheel -= 1; + return !io.WantCaptureMouse; case SDL_TEXTINPUT: { - if(!_grab_inputs) - return true; - - nk_glyph glyph; - memcpy(glyph, evt.text.text, NK_UTF_SIZE); - nk_input_glyph(_ctx, glyph); - return false; + io.AddInputCharactersUTF8(evt.text.text); + return !io.WantCaptureKeyboard; } default: return true; @@ -197,251 +402,193 @@ namespace mirrage::gui { } private: - input::Input_manager& _input_mgr; - nk_context* _ctx; - const glm::vec4& _viewport; - const glm::mat4& _ui_matrix; - bool _grab_clicks = false; - bool _grab_inputs = false; - }; - - struct Wnk_Context { - nk_context ctx; + struct Cursor { + SDL_Cursor* data = nullptr; + + Cursor(SDL_Cursor* data = nullptr) : data(data) {} + Cursor(const Cursor& c) = delete; + ~Cursor() { SDL_FreeCursor(data); } + + Cursor& operator=(Cursor&& c) + { + SDL_FreeCursor(data); + data = c.data; + c.data = nullptr; + return *this; + } + Cursor& operator=(const Cursor& c) = delete; + }; - Wnk_Context() - { - nk_init_default(&ctx, nullptr); - ctx.clip.copy = nk_sdl_clipbard_copy; - ctx.clip.paste = nk_sdl_clipbard_paste; - ctx.clip.userdata = nk_handle_ptr(nullptr); - } - ~Wnk_Context() { nk_free(&ctx); } - }; - struct Wnk_Buffer { - nk_buffer buffer; + input::Input_manager& _input_mgr; + std::array _mouse_pressed = {false, false, false}; + std::uint64_t _time = 0; + bool _last_frame_rendered = true; - Wnk_Buffer() { nk_buffer_init_default(&buffer); } - ~Wnk_Buffer() { nk_buffer_free(&buffer); } + std::array _cursors; + std::unique_ptr _clipboard_data{nullptr, &SDL_free}; }; - - template - auto get_buffer_data_ref(nk_buffer& src) -> gsl::span - { - nk_memory_status info; - nk_buffer_info(&info, &src); - - static_assert(sizeof(T) < 4 || sizeof(T) % 4 == 0, "T is not 4 bytes alligned"); - - auto size = info.allocated; - if(size % 4 != 0) { - auto align_diff = (4 - size % 4); - MIRRAGE_INVARIANT(align_diff + info.allocated <= info.size, - "Can't align buffer: " << info.allocated << " / " << info.size); - - size += align_diff; - } - - return gsl::span(reinterpret_cast(nk_buffer_memory_const(&src)), - size / sizeof(T)); - } } // namespace namespace detail { struct Nk_renderer { Gui_renderer_interface& renderer; - Wnk_Buffer commands; - nk_draw_null_texture null_tex; - Wnk_Buffer vbo; - Wnk_Buffer ibo; - - Nk_renderer(Gui_renderer_interface& renderer) : renderer(renderer) {} - void draw(nk_context& ctx, glm::vec4 viewport, glm::vec2 screen_size, const glm::mat4& ui_matrix) + void draw() { - - glm::vec2 scale = glm::vec2(viewport.z - viewport.x, viewport.w - viewport.y) / screen_size; - - // flush nk stuff to buffers - nk_convert_config config; - memset(&config, 0, sizeof(config)); - config.global_alpha = 1.0f; - config.shape_AA = NK_ANTI_ALIASING_ON; - config.line_AA = NK_ANTI_ALIASING_ON; - config.circle_segment_count = 22; - config.curve_segment_count = 22; - config.arc_segment_count = 22; - config.null = null_tex; - - constexpr struct nk_draw_vertex_layout_element vertex_layout[] = { - {NK_VERTEX_POSITION, NK_FORMAT_FLOAT, offsetof(Gui_vertex, position)}, - {NK_VERTEX_TEXCOORD, NK_FORMAT_FLOAT, offsetof(Gui_vertex, uv)}, - {NK_VERTEX_COLOR, NK_FORMAT_R8G8B8A8, offsetof(Gui_vertex, color)}, - {NK_VERTEX_LAYOUT_END}}; - config.vertex_layout = vertex_layout; - config.vertex_size = sizeof(struct Gui_vertex); - config.vertex_alignment = NK_ALIGNOF(struct Gui_vertex); - - nk_buffer_clear(&vbo.buffer); - nk_buffer_clear(&ibo.buffer); - nk_buffer_clear(&commands.buffer); - nk_convert(&ctx, &commands.buffer, &vbo.buffer, &ibo.buffer, &config); - - auto indices = get_buffer_data_ref(ibo.buffer); - auto vertices = get_buffer_data_ref(vbo.buffer); - - if(!vertices.empty() && !indices.empty()) { - renderer.prepare_draw(indices, vertices, ui_matrix); - - ON_EXIT { renderer.finalize_draw(); }; - - // draw stuff - - auto cmd = static_cast(nullptr); - auto offset = std::uint32_t(0); - for(cmd = nk__draw_begin(&ctx, &commands.buffer); cmd; - cmd = nk__draw_next(cmd, &commands.buffer, &ctx)) { - - if(cmd->elem_count == 0) - continue; - - auto clip = glm::vec4{glm::clamp(cmd->clip_rect.x * scale.x, viewport.x, viewport.z), - glm::clamp(cmd->clip_rect.y * scale.y, viewport.y, viewport.w), - glm::clamp(cmd->clip_rect.w * scale.x, viewport.x, viewport.z), - glm::clamp(cmd->clip_rect.h * scale.y, viewport.y, viewport.w)}; - - renderer.draw_elements(cmd->texture.id, clip, offset, cmd->elem_count); - - offset += cmd->elem_count; + ImGui::Render(); + auto draw_data = ImGui::GetDrawData(); + + // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) + auto fb_width = static_cast(draw_data->DisplaySize.x * draw_data->FramebufferScale.x); + auto fb_height = static_cast(draw_data->DisplaySize.y * draw_data->FramebufferScale.y); + if(fb_width <= 0 || fb_height <= 0 || draw_data->TotalVtxCount == 0) + return; + + auto vertex_size = static_cast(draw_data->TotalVtxCount) * sizeof(ImDrawVert); + auto index_size = static_cast(draw_data->TotalIdxCount) * sizeof(ImDrawIdx); + if(vertex_size <= 0 || index_size <= 0) + return; + + auto write_data = [&](std::uint16_t* indices, Gui_vertex* vertices) { + for(auto&& cmd_list : + util::range(draw_data->CmdLists, draw_data->CmdLists + draw_data->CmdListsCount)) { + memcpy(vertices, + cmd_list->VtxBuffer.Data, + static_cast(cmd_list->VtxBuffer.Size) * sizeof(ImDrawVert)); + memcpy(indices, + cmd_list->IdxBuffer.Data, + static_cast(cmd_list->IdxBuffer.Size) * sizeof(ImDrawIdx)); + + vertices += cmd_list->VtxBuffer.Size; + indices += cmd_list->IdxBuffer.Size; } + }; + + + auto size = glm::vec2(draw_data->DisplaySize.x, draw_data->DisplaySize.y); + auto offset = glm::vec2(draw_data->DisplayPos.x, draw_data->DisplayPos.y); + + auto projection = + glm::ortho(-size.x / 2.f, size.x / 2.f, size.y / 2.f, -size.y / 2.f, -1.f, 1.f); + projection[1][1] *= -1.f; + projection = projection + * glm::translate(glm::mat4(1.f), + glm::vec3(-size.x / 2 - offset.x, -size.y / 2 - offset.y, 0)); + + renderer.prepare_draw(index_size, vertex_size, projection, write_data); + ON_EXIT { renderer.finalize_draw(); }; + + // draw stuff + // Will project scissor/clipping rectangles into framebuffer space + ImVec2 clip_off = draw_data->DisplayPos; // (0,0) unless using multi-viewports + ImVec2 clip_scale = + draw_data->FramebufferScale; // (1,1) unless using retina display which are often (2,2) + + // Render command lists + auto idx_offset = std::uint32_t(0); + auto vert_offset = std::uint32_t(0); + for(int n = 0; n < draw_data->CmdListsCount; n++) { + const ImDrawList* cmd_list = draw_data->CmdLists[n]; + for(int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) { + const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; + if(pcmd->UserCallback) { + pcmd->UserCallback(cmd_list, pcmd); + } else { + // Project scissor/clipping rectangles into framebuffer space + glm::vec4 clip_rect; + clip_rect.x = (pcmd->ClipRect.x - clip_off.x) * clip_scale.x; + clip_rect.y = (pcmd->ClipRect.y - clip_off.y) * clip_scale.y; + clip_rect.z = (pcmd->ClipRect.z - clip_off.x) * clip_scale.x; + clip_rect.w = (pcmd->ClipRect.w - clip_off.y) * clip_scale.y; + + if(clip_rect.x < fb_width && clip_rect.y < fb_height && clip_rect.z >= 0.0f + && clip_rect.w >= 0.0f) { + renderer.draw_elements( + pcmd->TextureId, clip_rect, idx_offset, pcmd->ElemCount, vert_offset); + } + } + idx_offset += pcmd->ElemCount; + } + vert_offset += std::uint32_t(cmd_list->VtxBuffer.Size); } - - //nk_clear(&ctx); } }; } // namespace detail namespace { struct Wnk_font_atlas { - nk_font_atlas atlas; - const uint8_t* data; - int width; - int height; + std::unordered_map fonts; + std::shared_ptr texture; - Wnk_font_atlas(asset::Asset_manager& assets) + Wnk_font_atlas(asset::Asset_manager& assets, Gui_renderer_interface& renderer) { - nk_font_atlas_init_default(&atlas); - nk_font_atlas_begin(&atlas); + ImGuiIO& io = ImGui::GetIO(); + io.Fonts->AddFontDefault(); + + auto fonts = std::vector>(); + + auto cfg = ImFontConfig{}; + cfg.FontDataOwnedByAtlas = false; + + auto load_font = [&](const Font_desc& font) { + assets.load_maybe(font.aid, false).process([&](auto&& data) { + auto f = io.Fonts->AddFontFromMemoryTTF(const_cast(data->data()), + static_cast(data->size()), + font.size, + &cfg); + this->fonts.emplace(font.id, f); + LOG(plog::debug) << "Loaded font \"" << font.aid << "\" in fontsize " << font.size; + fonts.emplace_back(std::move(data)); + }); + }; assets.load_maybe("cfg:gui"_aid, false).process([&](auto& cfg) { for(auto& font : cfg->fonts) { - assets.load_maybe(font.aid, false).process([&](auto&& data) { - auto f = nk_font_atlas_add_from_memory( - &atlas, const_cast(data->data()), data->size(), font.size, nullptr); - if(font.default_font) { - atlas.default_font = f; - } - LOG(plog::debug) - << "Loaded font \"" << font.aid << "\" in fontsize " << font.size; - }); + load_font(font); } }); - data = static_cast( - nk_font_atlas_bake(&atlas, &width, &height, NK_FONT_ATLAS_RGBA32)); - } - void post_init(nk_context& ctx, nk_draw_null_texture& null_tex, struct nk_image tex) - { - data = nullptr; - width = 0; - height = 0; - - nk_font_atlas_end(&atlas, tex.handle, &null_tex); // frees data - if(atlas.default_font) - nk_style_set_font(&ctx, &atlas.default_font->handle); + // bake + unsigned char* pixels; + int width, height; + // TODO: alpha8 would be more compact/faster + io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); + texture = renderer.load_texture(width, height, 4, pixels); + io.Fonts->TexID = texture.get(); } - - ~Wnk_font_atlas() { nk_font_atlas_clear(&atlas); } }; - glm::vec2 normalize_screen_size(int window_width, int window_height, int target_height) - { - auto width = static_cast(window_width); - auto height = static_cast(window_height); - - if(width / height <= 5 / 3.f) { // special case for weird resolutions - target_height = int(float(target_height) * 1.25f); - } - - if(width < height) { // special case for portrait-mode - float vheight = std::round(height * (static_cast(target_height)) / width); - return {target_height, vheight}; - } else { - float vwidth = std::round(width * (static_cast(target_height)) / height); - return {vwidth, target_height}; + struct Imgui_context { + Imgui_context() + { + ImGui::CreateContext(); + ImGui::GetIO(); + ImGui::StyleColorsDark(); } - } - - auto build_ui_mat(glm::vec2 size) - { - auto m = glm::ortho(-size.x / 2.f, size.x / 2.f, size.y / 2.f, -size.y / 2.f, -1.f, 1.f); - m[1][1] *= -1.f; - - return m * glm::translate(glm::mat4(1.f), glm::vec3(-size.x / 2, -size.y / 2, 0)); - } + ~Imgui_context() { ImGui::DestroyContext(); } + }; } // namespace struct Gui::PImpl { - glm::vec4 viewport; - glm::vec2 screen_size; - glm::mat4 ui_matrix; - Wnk_Context ctx; - Wnk_Buffer buffer; - detail::Nk_renderer renderer; - Wnk_font_atlas atlas; - std::shared_ptr atlas_tex; - Gui_event_filter input_filter; - - PImpl(glm::vec4 viewport, - asset::Asset_manager& assets, - input::Input_manager& input, - Gui_renderer_interface& renderer) - : ctx() - , renderer(renderer) - , atlas(assets) - , atlas_tex(renderer.load_texture(atlas.width, atlas.height, 4, atlas.data)) - , input_filter(input, &ctx.ctx, this->viewport, ui_matrix) - { - - change_viewport(viewport); - - atlas.post_init(ctx.ctx, this->renderer.null_tex, *atlas_tex); - - ctx.ctx.style.window.background = nk_rgba(0, 0, 0, 240); - ctx.ctx.style.window.fixed_background = nk_style_item_color(nk_rgba(0, 0, 0, 240)); - ctx.ctx.style.window.header.normal = nk_style_item_color(nk_rgba(5, 5, 5, 255)); - ctx.ctx.style.window.header.hover = nk_style_item_color(nk_rgba(5, 5, 5, 255)); - ctx.ctx.style.window.header.active = nk_style_item_color(nk_rgba(5, 5, 5, 255)); - ctx.ctx.style.window.border_color = nk_rgb(0, 0, 0); - ctx.ctx.style.window.menu_border_color = nk_rgb(0, 0, 0); - } - ~PImpl() {} + Imgui_context ctx; + Wnk_font_atlas atlas; + detail::Nk_renderer renderer; + Gui_event_filter input_filter; - void change_viewport(glm::vec4 new_viewport) + PImpl(asset::Asset_manager& assets, input::Input_manager& input, Gui_renderer_interface& renderer) + : atlas(assets, renderer), renderer(renderer), input_filter(input) { - viewport = new_viewport; - screen_size = normalize_screen_size(static_cast(viewport.z - viewport.x), - static_cast(viewport.w - viewport.y), - 720); - ui_matrix = build_ui_mat(screen_size); } + ~PImpl() {} }; Gui::Gui(glm::vec4 viewport, asset::Asset_manager& assets, input::Input_manager& input) : _viewport(viewport), _assets(assets), _input(input) { + ref_embedded_assets_mirrage_gui(); } Gui::~Gui() { MIRRAGE_INVARIANT(_renderer == nullptr, "GUI still has a renderer registered (leak?)"); } @@ -453,7 +600,7 @@ namespace mirrage::gui { if(renderer) { MIRRAGE_INVARIANT(_renderer == nullptr, "Gui already has a different renderer: " << _renderer << "!=" << renderer); - _impl = std::make_unique(_viewport, _assets, _input, *renderer); + _impl = std::make_unique(_assets, _input, *renderer); } else { _impl.reset(); } @@ -461,21 +608,20 @@ namespace mirrage::gui { _renderer = renderer; } - auto Gui::virtual_viewport() const noexcept -> glm::vec4 - { - if(_impl) - return {0.f, 0.f, _impl->screen_size.x, _impl->screen_size.y}; - else - return _viewport; - } - - void Gui::viewport(glm::vec4 new_viewport) + auto Gui::find_font(util::Str_id id) const -> util::maybe { - _viewport = new_viewport; - if(ready()) { - _impl->change_viewport(new_viewport); + if(!ready()) { + LOG(plog::error) << "No gui renderer instantiated when Gui::draw was called!"; + return util::nothing; } + + auto iter = _impl->atlas.fonts.find(id); + if(iter == _impl->atlas.fonts.end()) + return util::nothing; + else + return util::justCopy(iter->second); } + void Gui::viewport(glm::vec4 new_viewport) { _viewport = new_viewport; } void Gui_renderer_interface::draw_gui() { @@ -492,39 +638,15 @@ namespace mirrage::gui { } viewport(_input.viewport()); - - _impl->renderer.draw(_impl->ctx.ctx, _impl->viewport, _impl->screen_size, _impl->ui_matrix); - } - void Gui::start_frame() - { - if(_renderer) - nk_clear(&_impl->ctx.ctx); - } - - auto Gui::ctx() -> nk_context* - { - MIRRAGE_INVARIANT(ready(), "No gui renderer instantiated when nk_context was requested!"); - - return &_impl->ctx.ctx; + _impl->renderer.draw(); + _impl->input_filter.notify_frame_rendered(); } + void Gui::start_frame() {} - auto Gui::load_texture(const asset::AID& aid) -> std::shared_ptr + auto Gui::load_texture(const asset::AID& aid) -> std::shared_ptr { MIRRAGE_INVARIANT(_renderer, "No gui renderer instantiated when load_texture was called!"); return _renderer->load_texture(aid); } - auto Gui::centered(int width, int height) -> struct nk_rect { - return nk_rect(_impl->screen_size.x / 2.f - float(width) / 2.f, - _impl->screen_size.y / 2.f - float(height) / 2.f, - float(width), - float(height)); - } auto Gui::centered_left(int width, int height) -> struct nk_rect { - return nk_rect(0, _impl->screen_size.y / 2.f - float(height) / 2.f, float(width), float(height)); - } auto Gui::centered_right(int width, int height) -> struct nk_rect { - return nk_rect(_impl->screen_size.x - float(width), - _impl->screen_size.y / 2.f - float(height) / 2.f, - float(width), - float(height)); - } } // namespace mirrage::gui diff --git a/src/mirrage/gui/src/menu.cpp b/src/mirrage/gui/src/menu.cpp deleted file mode 100644 index b32a5b625113b5689487421b43b91c982b846cdc..0000000000000000000000000000000000000000 --- a/src/mirrage/gui/src/menu.cpp +++ /dev/null @@ -1,26 +0,0 @@ -#include - -#include - - -namespace mirrage::gui { - - void begin_menu(nk_context*, int& active) - { - // TODO - } - - bool menu_button(nk_context* ctx, const char* text, bool enabled) - { - if(!enabled) - return false; - - nk_layout_row_dynamic(ctx, 80, 1); - return nk_button_label(ctx, text); - } - - void end_menu(nk_context*) - { - // TODO - } -} // namespace mirrage::gui diff --git a/src/mirrage/gui/src/text_edit.cpp b/src/mirrage/gui/src/text_edit.cpp deleted file mode 100644 index 1399c5b582dbc251013648a3cebc0a27fe97565a..0000000000000000000000000000000000000000 --- a/src/mirrage/gui/src/text_edit.cpp +++ /dev/null @@ -1,47 +0,0 @@ -#include - - -namespace mirrage::gui { - - Text_edit::Text_edit() : _data(nk_text_edit{}) { nk_textedit_init_default(&_data.get_or_throw()); } - Text_edit::~Text_edit() - { - if(_data.is_some()) { - nk_textedit_free(&_data.get_or_throw()); - } - } - - void Text_edit::reset(const std::string& str) - { - MIRRAGE_INVARIANT(_data.is_some(), "Text_edit is in moved-from state!"); - - nk_textedit_free(&_data.get_or_throw()); - nk_textedit_init_default(&_data.get_or_throw()); - nk_str_append_text_char(&_data.get_or_throw().string, str.data(), static_cast(str.length())); - } - - void Text_edit::get(std::string& str) const - { - MIRRAGE_INVARIANT(_data.is_some(), "Text_edit is in moved-from state!"); - - auto& cstr = _data.get_or_throw().string; - - str.assign(reinterpret_cast(nk_str_get_const(&cstr)), - static_cast(cstr.buffer.allocated)); - } - - void Text_edit::update_and_draw(nk_context* ctx, nk_flags type, std::string& str) - { - update_and_draw(ctx, type); - get(str); - } - - void Text_edit::update_and_draw(nk_context* ctx, nk_flags type) - { - MIRRAGE_INVARIANT(_data.is_some(), "Text_edit is in moved-from state!"); - - auto ev = nk_edit_buffer(ctx, type, &_data.get_or_throw(), nk_filter_default); - - _active = (ev & NK_EDIT_INACTIVE) != NK_EDIT_INACTIVE; - } -} // namespace mirrage::gui diff --git a/src/mirrage/input/CMakeLists.txt b/src/mirrage/input/CMakeLists.txt index f892fc8af0ad720cfe90aca1e05b9c09c0b0a9bf..45123fc913eddf27edb816d209d8c6e21bc150ac 100644 --- a/src/mirrage/input/CMakeLists.txt +++ b/src/mirrage/input/CMakeLists.txt @@ -1,12 +1,6 @@ -cmake_minimum_required(VERSION 3.2 FATAL_ERROR) - -project(mirrage_input LANGUAGES CXX) - -find_package(SDL2 REQUIRED) -add_library(sdl2::sdl2 INTERFACE IMPORTED) -set_property(TARGET sdl2::sdl2 PROPERTY INTERFACE_LINK_LIBRARIES ${SDL2_LIBRARY}) -set_property(TARGET sdl2::sdl2 PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${SDL2_INCLUDE_DIR}) +cmake_minimum_required(VERSION 3.9 FATAL_ERROR) +project(mirrage_input) # need to be specified with the sources for correct syntax highlighting in some IDEs file(GLOB_RECURSE HEADER_FILES @@ -20,6 +14,7 @@ add_library(mirrage_input STATIC ${HEADER_FILES} ) add_library(mirrage::input ALIAS mirrage_input) +target_compile_features(mirrage_input PUBLIC cxx_std_17) set(MIRRAGE_DEFAULT_COMPILER_ARGS ${MIRRAGE_DEFAULT_COMPILER_ARGS}) target_compile_options(mirrage_input PRIVATE ${MIRRAGE_DEFAULT_COMPILER_ARGS}) @@ -35,7 +30,7 @@ target_link_libraries(mirrage_input gsl glm::glm mirrage::asset - sdl2::sdl2 + mirrage::deps::SDL2 sf2 ) diff --git a/src/mirrage/input/include/mirrage/input/input_manager.hpp b/src/mirrage/input/include/mirrage/input/input_manager.hpp index 1d00e8ba15c868686a3794d9f0ee4693448a2de4..a0a0c71635798ad335232022576a27ba4b005e95 100644 --- a/src/mirrage/input/include/mirrage/input/input_manager.hpp +++ b/src/mirrage/input/include/mirrage/input/input_manager.hpp @@ -14,7 +14,7 @@ #include #include -#include +#include #include #include #include @@ -66,6 +66,7 @@ namespace mirrage::input { auto viewport() const noexcept { return _viewport; } void viewport(glm::vec4 v) { _viewport = v; } void window(SDL_Window* w) { _sdl_window = w; } + auto window() { return _sdl_window; } auto last_pointer_world_position(int idx = 0) const noexcept { @@ -101,7 +102,7 @@ namespace mirrage::input { void _on_mouse_motion(const SDL_MouseMotionEvent& motion); void _poll_events(); - void _handle_event(SDL_Event& event); + void _handle_event(SDL_Event& event, bool filtered); private: class Gamepad; diff --git a/src/mirrage/input/include/mirrage/input/input_mapping.hpp b/src/mirrage/input/include/mirrage/input/input_mapping.hpp index 9f744b2df49e3f7098084a08c554370477548333..121474fa1e47606320042ac4482cad98f938e84a 100644 --- a/src/mirrage/input/include/mirrage/input/input_mapping.hpp +++ b/src/mirrage/input/include/mirrage/input/input_mapping.hpp @@ -14,10 +14,11 @@ #include #include -#include +#include #include #include #include +#include namespace mirrage::asset { @@ -51,7 +52,7 @@ namespace mirrage::input { void enable_context(Context_id id); void on_key_pressed(Key); - void on_key_released(Key); + void on_key_released(Key, bool filtered); void on_mouse_pos_change(glm::vec2 rel, glm::vec2 abs); @@ -62,7 +63,7 @@ namespace mirrage::input { void on_pad_button_released(Input_source src, Pad_button); void on_mouse_button_pressed(Mouse_button, float pressure = 1.f); - void on_mouse_button_released(Mouse_button, int8_t clicks); + void on_mouse_button_released(Mouse_button, int8_t clicks, bool filtered); void on_pad_stick_change(Input_source src, Pad_stick, glm::vec2 rel, glm::vec2 abs); @@ -74,6 +75,9 @@ namespace mirrage::input { Context_id _active_context_id; Context* _active_context; + std::unordered_set _cont_pressed_keys; + std::unordered_set _cont_pressed_mouse; + bool _primary_mouse_button_down = false; bool _is_mouse_drag = false; }; diff --git a/src/mirrage/input/include/mirrage/input/types.hpp b/src/mirrage/input/include/mirrage/input/types.hpp index 61d8a8fa17102d3e686b4ef991498205467e5fe8..229387373eb5110d17348c8609356a37e96bab6f 100644 --- a/src/mirrage/input/include/mirrage/input/types.hpp +++ b/src/mirrage/input/include/mirrage/input/types.hpp @@ -9,7 +9,7 @@ #include -#include +#include #include #include diff --git a/src/mirrage/input/src/input_manager.cpp b/src/mirrage/input/src/input_manager.cpp index 8f1e00dbbe7f16641dece997d91ff6097134b6e8..51771c9d2ee464f9a62fa1484871717625fa59dc 100644 --- a/src/mirrage/input/src/input_manager.cpp +++ b/src/mirrage/input/src/input_manager.cpp @@ -8,7 +8,7 @@ #include #include -#include +#include #ifdef EMSCRIPTEN #include @@ -181,7 +181,7 @@ namespace mirrage::input { _pointer_world_pos[i] = _screen_to_world_coords(_pointer_screen_pos[i]); for(auto& gp : _gamepads) - if(gp){ + if(gp) { gp->update(dt); } @@ -201,9 +201,7 @@ namespace mirrage::input { [&](auto f) { return !f->propagate(event); }) != _event_filter.end(); - if(!filtered) { - _handle_event(event); - } + _handle_event(event, filtered); } for(auto& f : _event_filter) { @@ -212,8 +210,12 @@ namespace mirrage::input { } - void Input_manager::_handle_event(SDL_Event& event) + void Input_manager::_handle_event(SDL_Event& event, bool filtered) { + if(filtered && event.type != SDL_KEYUP && event.type != SDL_MOUSEBUTTONUP) { + return; + } + switch(event.type) { case SDL_TEXTINPUT: _mailbox.send(event.text.text); break; @@ -223,8 +225,9 @@ namespace mirrage::input { break; case SDL_KEYUP: - if(event.key.repeat == 0) - _mapper->on_key_released(from_sdl_keycode(event.key.keysym.sym)); + if(event.key.repeat == 0) { + _mapper->on_key_released(from_sdl_keycode(event.key.keysym.sym), filtered); + } break; case SDL_MOUSEMOTION: _on_mouse_motion(event.motion); break; @@ -235,8 +238,8 @@ namespace mirrage::input { break; case SDL_MOUSEBUTTONUP: - _mapper->on_mouse_button_released(event.button.button, - static_cast(event.button.clicks)); + _mapper->on_mouse_button_released( + event.button.button, static_cast(event.button.clicks), filtered); _pointer_active[0] = false; break; @@ -281,7 +284,7 @@ namespace mirrage::input { if(event.tfinger.type == SDL_FINGERDOWN) _mapper->on_mouse_button_pressed(1, event.tfinger.pressure); else if(event.tfinger.type == SDL_FINGERUP) - _mapper->on_mouse_button_released(1, 1); + _mapper->on_mouse_button_released(1, 1, filtered); } } break; @@ -339,7 +342,8 @@ namespace mirrage::input { if(SDL_IsGameController(joystick_id)) { SDL_GameController* controller = SDL_GameControllerOpen(joystick_id); if(controller) { - _gamepads.emplace_back(std::make_unique(_gamepads.size() + 1, controller, *_mapper)); + _gamepads.emplace_back(std::make_unique( + gsl::narrow(_gamepads.size() + 1), controller, *_mapper)); _mailbox.send(Input_source(_gamepads.size())); } else { std::cerr << "Could not open gamecontroller " << joystick_id << ": " << SDL_GetError() diff --git a/src/mirrage/input/src/input_mapping.cpp b/src/mirrage/input/src/input_mapping.cpp index bfb1e63c71834379996b640447210afa0e263558..3bbf08fea634293099fed5de1d251649a9cb6716 100644 --- a/src/mirrage/input/src/input_mapping.cpp +++ b/src/mirrage/input/src/input_mapping.cpp @@ -153,12 +153,21 @@ namespace mirrage::input { void Input_mapper::on_key_pressed(Key k) { + _cont_pressed_keys.emplace(k); find_maybe(_active_context->keys, k).process([&](auto& action) { process_pressed(_bus, action); }); } - void Input_mapper::on_key_released(Key k) + void Input_mapper::on_key_released(Key k, bool filtered) { - find_maybe(_active_context->keys, k).process([&](auto& action) { process_release(_bus, action); }); + auto pressed = _cont_pressed_keys.count(k); + _cont_pressed_keys.erase(k); + + find_maybe(_active_context->keys, k).process([&](auto& action) { + if(!filtered || action.type == Reaction_type::continuous) { + if(pressed || action.type != Reaction_type::continuous) + process_release(_bus, action); + } + }); } void Input_mapper::on_mouse_pos_change(glm::vec2 rel, glm::vec2 abs) @@ -213,6 +222,8 @@ namespace mirrage::input { void Input_mapper::on_mouse_button_pressed(Mouse_button b, float pressure) { + _cont_pressed_mouse.emplace(b); + find_maybe(_active_context->mouse_buttons, {b, 0}).process([&](auto& action) { process_pressed(_bus, action, Input_source{0}, pressure); }); @@ -221,9 +232,9 @@ namespace mirrage::input { _primary_mouse_button_down = true; } - void Input_mapper::on_mouse_button_released(Mouse_button b, int8_t clicks) + void Input_mapper::on_mouse_button_released(Mouse_button b, int8_t clicks, bool filtered) { - if(b != 1 || !_is_mouse_drag) { + if((b != 1 || !_is_mouse_drag) && !filtered) { find_maybe(_active_context->mouse_buttons, {b, clicks}).process([&](auto& action) { process_release(_bus, action); }); @@ -236,13 +247,16 @@ namespace mirrage::input { // call end listerners for continue_click_handlers (clicks==0) find_maybe(_active_context->mouse_buttons, {b, 0}).process([&](auto& action) { - process_release(_bus, action); + if(!filtered || (action.type == Reaction_type::continuous && _cont_pressed_mouse.count(b) > 0)) + process_release(_bus, action); }); if(b == 1) { _primary_mouse_button_down = false; _is_mouse_drag = false; } + + _cont_pressed_mouse.erase(b); } void Input_mapper::on_pad_stick_change(Input_source src, Pad_stick s, glm::vec2 rel, glm::vec2 abs) diff --git a/src/mirrage/net/CMakeLists.txt b/src/mirrage/net/CMakeLists.txt index ee8683f5014830f4199d649eecf2d806b5df02f5..26ed9c9347f94f3cf819af4487b5e1921f254524 100644 --- a/src/mirrage/net/CMakeLists.txt +++ b/src/mirrage/net/CMakeLists.txt @@ -1,6 +1,6 @@ -cmake_minimum_required(VERSION 3.2 FATAL_ERROR) +cmake_minimum_required(VERSION 3.9 FATAL_ERROR) -project(mirrage_net LANGUAGES CXX) +project(mirrage_net) # need to be specified with the sources for correct syntax highlighting in some IDEs file(GLOB_RECURSE HEADER_FILES @@ -19,6 +19,7 @@ add_library(mirrage_net STATIC ${HEADER_FILES} ) add_library(mirrage::net ALIAS mirrage_net) +target_compile_features(mirrage_net PUBLIC cxx_std_17) set(MIRRAGE_DEFAULT_COMPILER_ARGS ${MIRRAGE_DEFAULT_COMPILER_ARGS}) target_compile_options(mirrage_net PRIVATE ${MIRRAGE_DEFAULT_COMPILER_ARGS}) @@ -34,7 +35,7 @@ target_link_libraries(mirrage_net glm::glm mirrage::error enet - boost::magic_get + boost::pfr ) diff --git a/src/mirrage/renderer/CMakeLists.txt b/src/mirrage/renderer/CMakeLists.txt index 8a9c8eae3df8ca136ccd19ae3393cfc5c32429c7..d3e73a94cbdd98fc714536dc9658394ce974b217 100644 --- a/src/mirrage/renderer/CMakeLists.txt +++ b/src/mirrage/renderer/CMakeLists.txt @@ -1,6 +1,39 @@ -cmake_minimum_required(VERSION 3.2 FATAL_ERROR) +cmake_minimum_required(VERSION 3.9 FATAL_ERROR) + +project(mirrage_renderer) + +#shaders +file(GLOB_RECURSE GLSL_SOURCE_FILES + shader/*.frag + shader/*.vert + shader/*.comp +) + +file(GLOB_RECURSE ALL_SHADERS + RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} + shader/*.frag + shader/*.vert + shader/*.comp + shader/*.glsl + assets/assets_mirrage_renderer_shader.map) + +add_custom_target(mirrage_renderer_shaders SOURCES ${ALL_SHADERS}) + +set(MIRRAGE_GLSL_COMPILER "glslc" CACHE STRING "Path to glslc compiler") + +foreach(GLSL ${GLSL_SOURCE_FILES}) + get_filename_component(FILE_DIR ${GLSL} DIRECTORY) + string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" FILE_DIR ${FILE_DIR}) + get_filename_component(FILE_NAME ${GLSL} NAME) + set(SPIRV "${CMAKE_CURRENT_BINARY_DIR}/${FILE_DIR}/${FILE_NAME}.spv") + add_custom_command( + OUTPUT ${SPIRV} + COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_CURRENT_BINARY_DIR}/${FILE_DIR}/" + COMMAND ${MIRRAGE_GLSL_COMPILER} -o ${SPIRV} -c ${GLSL} + DEPENDS ${ALL_SHADERS}) + list(APPEND SPIRV_BINARY_FILES ${SPIRV}) +endforeach(GLSL) -project(mirrage_renderer LANGUAGES CXX) # need to be specified with the sources for correct syntax highlighting in some IDEs file(GLOB_RECURSE HEADER_FILES @@ -10,24 +43,32 @@ file(GLOB_RECURSE HEADER_FILES add_library(mirrage_renderer STATIC src/pass/animation_pass.cpp + src/pass/billboard_pass.cpp src/pass/blit_pass.cpp src/pass/bloom_pass.cpp + src/pass/clear_pass.cpp src/pass/debug_draw_pass.cpp src/pass/deferred_geometry_subpass.cpp src/pass/deferred_lighting_subpass.cpp src/pass/deferred_pass.cpp + src/pass/depth_of_field_pass.cpp src/pass/frustum_culling_pass.cpp src/pass/gen_mipmap_pass.cpp src/pass/gi_pass.cpp src/pass/gui_pass.cpp + src/pass/particle_pass.cpp src/pass/shadowmapping_pass.cpp src/pass/ssao_pass.cpp src/pass/taa_pass.cpp src/pass/tone_mapping_pass.cpp + src/pass/transparent_pass.cpp src/animation.cpp src/animation_comp.cpp + src/billboard.cpp src/camera_comp.cpp + src/debug_ui.hpp + src/decal.cpp src/deferred_renderer.cpp src/gbuffer.cpp src/light_comp.cpp @@ -40,16 +81,29 @@ add_library(mirrage_renderer STATIC ${HEADER_FILES} ) add_library(mirrage::renderer ALIAS mirrage_renderer) +target_compile_features(mirrage_renderer PUBLIC cxx_std_17) -set(MIRRAGE_DEFAULT_COMPILER_ARGS ${MIRRAGE_DEFAULT_COMPILER_ARGS}) -target_compile_options(mirrage_renderer PRIVATE ${MIRRAGE_DEFAULT_COMPILER_ARGS}) +mirrage_embed_asset(TARGET mirrage_renderer + EXPORT mirrage_renderer_targets + SOURCES + "${CMAKE_CURRENT_BINARY_DIR}/shader" + "${CMAKE_CURRENT_SOURCE_DIR}/assets/textures" + "${CMAKE_CURRENT_SOURCE_DIR}/assets/assets_mirrage_renderer_shader.map" + "${CMAKE_CURRENT_SOURCE_DIR}/assets/assets_mirrage_renderer_textures.map" + DEPENDS + ${SPIRV_BINARY_FILES} + "${CMAKE_CURRENT_SOURCE_DIR}/assets/assets_mirrage_renderer_shader.map" + "${CMAKE_CURRENT_SOURCE_DIR}/assets/assets_mirrage_renderer_textures.map") -option(MIRRAGE_COMPILE_SHADERS "Compile demo shaders" OFF) -if(MIRRAGE_COMPILE_SHADERS) - include(shaders.cmake) - add_dependencies(mirrage_renderer demo_shaders) +option(MIRRAGE_HISTOGRAM_DEBUG_VIEW "Enable debug view for tone mapping pass" OFF) +if(MIRRAGE_HISTOGRAM_DEBUG_VIEW) + target_compile_definitions(mirrage_renderer PUBLIC MIRRAGE_HISTOGRAM_DEBUG_VIEW) endif() + +set(MIRRAGE_DEFAULT_COMPILER_ARGS ${MIRRAGE_DEFAULT_COMPILER_ARGS}) +target_compile_options(mirrage_renderer PRIVATE ${MIRRAGE_DEFAULT_COMPILER_ARGS}) + target_include_directories(mirrage_renderer PUBLIC $ $) @@ -68,7 +122,6 @@ target_link_libraries(mirrage_renderer robin-map ) - install(TARGETS mirrage_renderer EXPORT mirrage_renderer_targets INCLUDES DESTINATION include ARCHIVE DESTINATION lib diff --git a/src/mirrage/renderer/assets/assets_mirrage_renderer_shader.map b/src/mirrage/renderer/assets/assets_mirrage_renderer_shader.map new file mode 100644 index 0000000000000000000000000000000000000000..0904882256fd21cb60374e0ff891b0995b383478 --- /dev/null +++ b/src/mirrage/renderer/assets/assets_mirrage_renderer_shader.map @@ -0,0 +1,120 @@ +shader: = shader/ + +comp_shader:particle_spawn_sphere = shader/particle/spawn_sphere.comp.spv +comp_shader:particle_update_simple = shader/particle/update_simple.comp.spv + +vert_shader:billboard = shader/billboard.vert.spv +frag_shader:billboard_lit = shader/billboard.frag.spv +frag_shader:billboard_unlit = shader/billboard_unlit.frag.spv + +vert_shader:blit = shader/fullscreen.vert.spv +frag_shader:blit = shader/blit.frag.spv + +vert_shader:debug_draw = shader/debug_draw.vert.spv +frag_shader:debug_draw = shader/debug_draw.frag.spv + +vert_shader:decal = shader/decal.vert.spv +frag_shader:decal = shader/decal.frag.spv + +vert_shader:depth_of_field = shader/fullscreen.vert.spv +frag_shader:depth_of_field_apply = shader/depth_of_field_apply.frag.spv +frag_shader:depth_of_field_coc = shader/depth_of_field_coc.frag.spv +frag_shader:depth_of_field_calc = shader/depth_of_field_calc.frag.spv + +vert_shader:light_directional = shader/fullscreen.vert.spv +frag_shader:light_directional = shader/light_directional.frag.spv + +vert_shader:light_point = shader/light_point.vert.spv +frag_shader:light_point = shader/light_point.frag.spv + +vert_shader:shadow_model = shader/shadow_model.vert.spv +vert_shader:shadow_model_animated = shader/shadow_model_animated.vert.spv +vert_shader:shadow_model_animated_dqs = shader/shadow_model_animated_dqs.vert.spv +frag_shader:shadow_model = shader/shadow_model.frag.spv + +vert_shader:model = shader/model.vert.spv +vert_shader:model_animated = shader/model_animated.vert.spv +vert_shader:model_animated_dqs = shader/model_animated_dqs.vert.spv +frag_shader:model = shader/model.frag.spv +frag_shader:model_emissive = shader/model_emissive.frag.spv +frag_shader:model_alphatest = shader/model_alphatest.frag.spv + +vert_shader:particle = shader/particle.vert.spv +frag_shader:particle_solid = shader/particle_solid.frag.spv +vert_shader:particle_transparent = shader/particle_transparent.vert.spv +vert_shader:particle_transparent_lit = shader/particle_transparent_lit.vert.spv +frag_shader:particle_transparent_lit = shader/particle_transparent_lit.frag.spv +frag_shader:particle_transparent_unlit = shader/particle_transparent_unlit.frag.spv + +vert_shader:transparent_compose = shader/fullscreen.vert.spv +frag_shader:transparent_compose = shader/transparent_compose.frag.spv + +vert_shader:ui = shader/ui.vert.spv +frag_shader:ui = shader/ui.frag.spv + +vert_shader:taa = shader/fullscreen.vert.spv +frag_shader:taa = shader/taa.frag.spv + +vert_shader:ssao_blur = shader/ssao_blur.vert.spv +frag_shader:ssao_blur = shader/ssao_blur.frag.spv + +vert_shader:ssao = shader/fullscreen.vert.spv +frag_shader:ssao = shader/ssao.frag.spv + + +vert_shader:gi_blend = shader/fullscreen.vert.spv +frag_shader:gi_blend = shader/gi_blend.frag.spv + +vert_shader:gi_diffuse_reproject = shader/fullscreen.vert.spv +frag_shader:gi_diffuse_reproject = shader/gi_diffuse_reproject.frag.spv + +vert_shader:gi_integrate_brdf = shader/gi_integrate_brdf.vert.spv +frag_shader:gi_integrate_brdf = shader/gi_integrate_brdf.frag.spv + +vert_shader:gi_mipgen = shader/fullscreen.vert.spv +frag_shader:gi_mipgen = shader/gi_mipgen.frag.spv + +vert_shader:gi_sample = shader/fullscreen.vert.spv +frag_shader:gi_sample = shader/gi_sample.frag.spv + +vert_shader:gi_sample_upsample = shader/fullscreen.vert.spv +frag_shader:gi_sample_upsample = shader/gi_sample_upsample.frag.spv + +vert_shader:gi_sample_blend = shader/fullscreen.vert.spv +frag_shader:gi_sample_blend = shader/gi_sample_blend.frag.spv + +vert_shader:gi_sample_spec = shader/fullscreen.vert.spv +frag_shader:gi_sample_spec = shader/gi_sample_spec.frag.spv + +vert_shader:gi_spec_blur = shader/gi_spec_blur.vert.spv +frag_shader:gi_spec_blur = shader/gi_spec_blur.frag.spv + +vert_shader:gi_reproject = shader/fullscreen.vert.spv +frag_shader:gi_reproject = shader/gi_reproject.frag.spv + +vert_shader:gi_reprojection_weights = shader/fullscreen.vert.spv +frag_shader:gi_reprojection_weights = shader/gi_reprojection_weights.frag.spv + +vert_shader:gi_weight_mipgen = shader/fullscreen.vert.spv +frag_shader:gi_weight_mipgen = shader/gi_weight_mipgen.frag.spv + +vert_shader:median_filter = shader/fullscreen.vert.spv +frag_shader:median_filter = shader/median_filter.frag.spv + +vert_shader:luminance = shader/fullscreen.vert.spv +frag_shader:luminance = shader/luminance.frag.spv + +vert_shader:luminance_adapt = shader/fullscreen.vert.spv +frag_shader:luminance_adapt = shader/luminance_adapt.frag.spv + +vert_shader:bloom_apply = shader/fullscreen.vert.spv +frag_shader:bloom_apply = shader/bloom_apply.frag.spv + +vert_shader:bloom_blur = shader/bloom_blur.vert.spv +frag_shader:bloom_blur = shader/bloom_blur.frag.spv + +comp_shader:tone_mapping_adjust = shader/tone_mapping_adjust.comp.spv +comp_shader:tone_mapping_histogram = shader/tone_mapping_histogram.comp.spv + +vert_shader:tone_mapping_apply = shader/fullscreen.vert.spv +frag_shader:tone_mapping_apply = shader/tone_mapping_apply.frag.spv diff --git a/assets/core_assets/assets_core_tex.map b/src/mirrage/renderer/assets/assets_mirrage_renderer_textures.map similarity index 72% rename from assets/core_assets/assets_core_tex.map rename to src/mirrage/renderer/assets/assets_mirrage_renderer_textures.map index a9dccdf4c07824a25ab60cf4f309820bce774398..8c29f20d07d584aa9db023c19aa248c1c4a91114 100644 --- a/assets/core_assets/assets_core_tex.map +++ b/src/mirrage/renderer/assets/assets_mirrage_renderer_textures.map @@ -1,8 +1,8 @@ tex: = textures/ -tex:black = textures/default_black.png tex:white = textures/default_white.ktx -tex:normal = textures/default_normal.png +tex:default_normal = textures/default_normal.ktx +tex:default_brdf = textures/default_brdf.ktx tex:placeholder = textures/default_placeholder.ktx tex:blue_noise = textures/blue_noise.ktx diff --git a/src/mirrage/renderer/assets/textures/blue_noise.ktx b/src/mirrage/renderer/assets/textures/blue_noise.ktx new file mode 100644 index 0000000000000000000000000000000000000000..280b60f6114d9771c3662bcdccdccdc98d7df90f --- /dev/null +++ b/src/mirrage/renderer/assets/textures/blue_noise.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3e4e457a31721b752b7850ab2103fc3cbec099fcdbe3b6c92d1bffed70577236 +size 87476 diff --git a/src/mirrage/renderer/assets/textures/default_brdf.ktx b/src/mirrage/renderer/assets/textures/default_brdf.ktx new file mode 100644 index 0000000000000000000000000000000000000000..0a2bb63e051ad2d0884c4f7d299831fee6aaeff8 --- /dev/null +++ b/src/mirrage/renderer/assets/textures/default_brdf.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:56aadc27f71b9e7f28ca8772fc17ad3075a358c8b8c3b9a24e4cede913f9b6a8 +size 84 diff --git a/src/mirrage/renderer/assets/textures/default_normal.ktx b/src/mirrage/renderer/assets/textures/default_normal.ktx new file mode 100644 index 0000000000000000000000000000000000000000..d4ce16e18d92347f6c02741100d855e74b77e83b --- /dev/null +++ b/src/mirrage/renderer/assets/textures/default_normal.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:73a65e3c250e991e119be02dc1d3298ec73846bb205aacd97ec104f4454936fa +size 84 diff --git a/src/mirrage/renderer/assets/textures/default_placeholder.ktx b/src/mirrage/renderer/assets/textures/default_placeholder.ktx new file mode 100644 index 0000000000000000000000000000000000000000..4c24d6d3bacae68ccb36690868855209c6ced89f --- /dev/null +++ b/src/mirrage/renderer/assets/textures/default_placeholder.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9b2e5ea0ce4c4b7f23827260ddf0c2bfb830c58babecbb42c5c31bcedc7b71d8 +size 4164 diff --git a/src/mirrage/renderer/assets/textures/default_white.ktx b/src/mirrage/renderer/assets/textures/default_white.ktx new file mode 100644 index 0000000000000000000000000000000000000000..cbe50f7cebf1ae93cc65b6c2a169d243fb0cede6 --- /dev/null +++ b/src/mirrage/renderer/assets/textures/default_white.ktx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9fb46dc75c85e13e5846d3fc10a3edf9af169c41c13d13de078ba9a077ccd8fb +size 4164 diff --git a/assets/core_assets/textures/satisfy_regular_20.tga b/src/mirrage/renderer/assets/textures/satisfy_regular_20.tga similarity index 100% rename from assets/core_assets/textures/satisfy_regular_20.tga rename to src/mirrage/renderer/assets/textures/satisfy_regular_20.tga diff --git a/assets/core_assets/textures/x.template_regular_48.tga b/src/mirrage/renderer/assets/textures/x.template_regular_48.tga similarity index 100% rename from assets/core_assets/textures/x.template_regular_48.tga rename to src/mirrage/renderer/assets/textures/x.template_regular_48.tga diff --git a/src/mirrage/renderer/include/mirrage/renderer/animation_comp.hpp b/src/mirrage/renderer/include/mirrage/renderer/animation_comp.hpp index b1fe88e2218201da11c390918560e375aabb1f5b..be1c8158758f443b47d8bd0c961124ade467707c 100644 --- a/src/mirrage/renderer/include/mirrage/renderer/animation_comp.hpp +++ b/src/mirrage/renderer/include/mirrage/renderer/animation_comp.hpp @@ -101,6 +101,27 @@ namespace mirrage::renderer { : Component(owner, em) { } + Simple_animation_controller_comp(Simple_animation_controller_comp&& rhs) noexcept + : Component(static_cast(rhs)) + , _animations(std::move(rhs._animations)) + , _current_animation(std::move(rhs._current_animation)) + , _prev_animation(std::move(rhs._prev_animation)) + , _next_animation(std::move(rhs._next_animation)) + , _fade_time(std::move(rhs._fade_time)) + , _fade_time_left(std::move(rhs._fade_time_left)) + { + } + auto operator=(Simple_animation_controller_comp&& rhs) noexcept -> Simple_animation_controller_comp& + { + Component::operator=(static_cast(rhs)); + _animations = std::move(rhs._animations); + _current_animation = std::move(rhs._current_animation); + _prev_animation = std::move(rhs._prev_animation); + _next_animation = std::move(rhs._next_animation); + _fade_time = std::move(rhs._fade_time); + _fade_time_left = std::move(rhs._fade_time_left); + return *this; + } void play(util::Str_id animation, bool preserve_state = true); void play(util::Str_id animation, float speed, bool reversed, bool paused, bool looped); diff --git a/src/mirrage/renderer/include/mirrage/renderer/billboard.hpp b/src/mirrage/renderer/include/mirrage/renderer/billboard.hpp new file mode 100644 index 0000000000000000000000000000000000000000..f598c6bc057e89169de81717f453ee1662f56565 --- /dev/null +++ b/src/mirrage/renderer/include/mirrage/renderer/billboard.hpp @@ -0,0 +1,87 @@ +#pragma once + +#include + +#include +#include +#include + + +namespace mirrage::renderer { + + struct Billboard_data { + glm::vec3 offset{0, 0, 0}; + glm::vec2 size{1, 1}; + glm::vec4 clip_rect{0, 0, 1, 1}; // x,y,w,h + util::Rgba color{1, 1, 1, 1}; + util::Rgba emissive_color{1, 1, 1, 1000}; + + bool active = true; + bool dynamic_lighting = true; + bool absolute_screen_space = false; + bool fixed_screen_size = false; + bool vertical_rotation = false; + + std::string material_aid; + }; +#ifdef sf2_structDef + sf2_structDef(Billboard_data, + offset, + size, + clip_rect, + color, + emissive_color, + dynamic_lighting, + absolute_screen_space, + fixed_screen_size, + vertical_rotation, + material_aid); +#endif + + struct Billboard : Billboard_data { + Material_ptr material; + + Billboard() = default; + Billboard(Billboard_data&& data, Material_ptr m) + : Billboard_data(std::move(data)), material(std::move(m)) + { + } + }; + + class Billboard_comp : public ecs::Component { + public: + static constexpr const char* name() { return "Billboard"; } + friend void load_component(ecs::Deserializer& state, Billboard_comp&); + friend void save_component(ecs::Serializer& state, const Billboard_comp&); + + using Component::Component; + + util::small_vector billboards; + }; + + struct Billboard_push_constants { + glm::vec4 position; + glm::vec4 size; // xy, z=screen_space, w=fixed_screen_size + glm::vec4 clip_rect; + glm::vec4 color; + glm::vec4 emissive_color; + glm::vec4 placeholder[3]; + }; + extern auto construct_push_constants(const Billboard&, const glm::mat4& view, const glm::vec4& viewport) + -> Billboard_push_constants; + +} // namespace mirrage::renderer + +namespace mirrage::asset { + + template <> + struct Loader { + public: + static auto load(istream in) -> async::task; + void save(ostream, const renderer::Billboard&) + { + MIRRAGE_FAIL("Save of billboards is not supported!"); + } + }; + +} // namespace mirrage::asset diff --git a/src/mirrage/renderer/include/mirrage/renderer/camera_comp.hpp b/src/mirrage/renderer/include/mirrage/renderer/camera_comp.hpp index 8953de746e9ea9743d87b57066066b1535ece619..934820f6c29eb1613138a3ba534811306230438a 100644 --- a/src/mirrage/renderer/include/mirrage/renderer/camera_comp.hpp +++ b/src/mirrage/renderer/include/mirrage/renderer/camera_comp.hpp @@ -25,15 +25,27 @@ namespace mirrage::renderer { auto far_plane() const noexcept { return _far; } auto fov() const noexcept { return _fov; } + void dof_focus(float v) noexcept { _dof_focus = v; } + auto dof_focus() const noexcept { return _dof_focus; } + void dof_range(float v) noexcept { _dof_range = v; } + auto dof_range() const noexcept { return _dof_range; } + void dof_power(float v) noexcept { _dof_power = v; } + auto dof_power() const noexcept { return _dof_power; } + private: util::Angle _fov; float _near = 0.2f; float _far = 1000.f; float _priority = 0.f; + + float _dof_focus = 0.f; + float _dof_range = 1.f; + float _dof_power = 0.f; }; struct Camera_state { public: + Camera_state(glm::vec4 viewport); Camera_state(const Camera_comp&, const ecs::components::Transform_comp&, glm::vec4 viewport); Camera_state(const Camera_comp&, glm::vec3 position, glm::quat orientation, glm::vec4 viewport); @@ -53,5 +65,9 @@ namespace mirrage::renderer { float aspect_ratio; util::Angle fov_vertical; util::Angle fov_horizontal; + + float dof_focus = 0.f; + float dof_range = 1.f; + float dof_power = 0.f; }; } // namespace mirrage::renderer diff --git a/src/mirrage/renderer/include/mirrage/renderer/decal.hpp b/src/mirrage/renderer/include/mirrage/renderer/decal.hpp new file mode 100644 index 0000000000000000000000000000000000000000..3c1cfdf352aeec9d4d43a5513d83c9e8fdc4113a --- /dev/null +++ b/src/mirrage/renderer/include/mirrage/renderer/decal.hpp @@ -0,0 +1,80 @@ +#pragma once + +#include + +#include +#include +#include + + +namespace mirrage::renderer { + + struct Decal_data { + glm::vec3 offset{0, 0, 0}; + glm::quat rotation{0.707f, -0.707f, 0.f, 0.f}; + glm::vec2 size{1, 1}; + glm::vec4 clip_rect{0, 0, 1, 1}; // x,y,w,h + util::Rgba color{1, 1, 1, 1}; + util::Rgba emissive_color{1, 1, 1, 1000}; + + float normal_alpha = 1.f; + float roughness_alpha = 1.f; + float metallic_alpha = 1.f; + + float thickness = 0.1f; + bool active = true; + + std::string material_aid; + }; +#ifdef sf2_structDef + sf2_structDef(Decal_data, + offset, + rotation, + size, + clip_rect, + color, + emissive_color, + normal_alpha, + roughness_alpha, + metallic_alpha, + thickness, + active, + material_aid); +#endif + + struct Decal : Decal_data { + Material_ptr material; + + Decal() = default; + Decal(Decal_data&& data, Material_ptr m) : Decal_data(std::move(data)), material(std::move(m)) {} + }; + + class Decal_comp : public ecs::Component { + public: + static constexpr const char* name() { return "Decal"; } + friend void load_component(ecs::Deserializer& state, Decal_comp&); + friend void save_component(ecs::Serializer& state, const Decal_comp&); + + using Component::Component; + + util::small_vector decals; + }; + + struct Decal_push_constants { + glm::mat4 model_view; // + packed clip_rect (vec4) and color (vec4) + glm::mat4 model_view_inv; // + emissive_color + }; + extern auto construct_push_constants(const Decal&, const glm::mat4& model) -> Decal_push_constants; + +} // namespace mirrage::renderer + +namespace mirrage::asset { + + template <> + struct Loader { + public: + static auto load(istream in) -> async::task; + void save(ostream, const renderer::Decal&) { MIRRAGE_FAIL("Save of decals is not supported!"); } + }; + +} // namespace mirrage::asset diff --git a/src/mirrage/renderer/include/mirrage/renderer/deferred_renderer.hpp b/src/mirrage/renderer/include/mirrage/renderer/deferred_renderer.hpp index 1fe0b52b0a20a3d95b2155c97137fcb70023017e..7e49ed425ee8b520455776c198bb95519c9b2774 100644 --- a/src/mirrage/renderer/include/mirrage/renderer/deferred_renderer.hpp +++ b/src/mirrage/renderer/include/mirrage/renderer/deferred_renderer.hpp @@ -10,6 +10,7 @@ #include #include +#include #include #include @@ -38,7 +39,7 @@ namespace mirrage::renderer { bool gi_shadows = false; int gi_diffuse_mip_level = 1; int gi_min_mip_level = 0; - int gi_samples = 32; + int gi_samples = 64; int gi_lowres_samples = 128; int gi_low_quality_mip_levels = 0; @@ -47,12 +48,19 @@ namespace mirrage::renderer { float scene_luminance_override = -1.f; float exposure_luminance_override = -1.f; float scotopic_sim_weight = 1.f; - float min_display_luminance = 2.f; - float max_display_luminance = 150.0f; + float min_display_luminance = 40.f; + float max_display_luminance = 200.0f; + float amient_light_intensity = 0.1f; - bool taa = true; - bool ssao = true; - bool bloom = true; + int transparent_particle_mip_level = 0; + bool particle_fragment_shadows = true; + + bool taa = true; + bool ssao = true; + bool bloom = true; + bool depth_of_field = true; + bool particles = true; + std::int32_t max_particles = 1'000'000; float background_intensity = 0.f; @@ -73,9 +81,15 @@ namespace mirrage::renderer { gi_low_quality_mip_levels, min_display_luminance, max_display_luminance, + amient_light_intensity, + transparent_particle_mip_level, + particle_fragment_shadows, taa, ssao, bloom, + depth_of_field, + particles, + max_particles, shadows, dynamic_lighting, debug_geometry); @@ -100,6 +114,7 @@ namespace mirrage::renderer { return std::unique_ptr(new T(std::forward(args)...)); } + using Render_pass_mask = std::vector; // util::small_vector; // shared among all Deferred_renderers in all screens class Deferred_renderer_factory { @@ -109,7 +124,17 @@ namespace mirrage::renderer { std::vector>); ~Deferred_renderer_factory(); - auto create_renderer(ecs::Entity_manager&) -> std::unique_ptr; + auto create_renderer(util::maybe = util::nothing, + Render_pass_mask = Render_pass_mask{}) -> std::unique_ptr; + + template + auto create_renderer(util::maybe ecs = util::nothing) + -> std::unique_ptr + { + return create_renderer(ecs, Render_pass_mask{render_pass_id_of()...}); + } + + auto all_passes_mask() const noexcept -> auto& { return _all_passes_mask; } void queue_commands(vk::CommandBuffer); auto queue_temporary_command_buffer() -> vk::CommandBuffer; @@ -127,6 +152,11 @@ namespace mirrage::renderer { void settings(const Renderer_settings& s, bool apply = true); void save_settings(); + auto global_uniforms_layout() const noexcept { return *_global_uniform_descriptor_set_layout; } + auto compute_storage_buffer_layout() const { return *_compute_storage_buffer_layout; } + auto compute_uniform_buffer_layout() const { return *_compute_uniform_buffer_layout; } + + private: friend class Deferred_renderer; struct Asset_loaders; @@ -154,7 +184,16 @@ namespace mirrage::renderer { bool _recreation_pending = false; vk::UniqueSampler _model_material_sampler; vk::UniqueDescriptorSetLayout _model_desc_set_layout; + vk::UniqueDescriptorSetLayout _global_uniform_descriptor_set_layout; + vk::UniqueDescriptorSetLayout _compute_storage_buffer_layout; + vk::UniqueDescriptorSetLayout _compute_uniform_buffer_layout; std::unique_ptr _asset_loaders; + Render_pass_mask _all_passes_mask; + + class Profiler_menu; + class Settings_menu; + std::unique_ptr _profiler_menu; + std::unique_ptr _settings_menu; void _present(); auto _rank_device(vk::PhysicalDevice, util::maybe gqueue) -> int; @@ -168,8 +207,8 @@ namespace mirrage::renderer { class Deferred_renderer { public: Deferred_renderer(Deferred_renderer_factory&, - std::vector>&, - ecs::Entity_manager&, + std::vector, + util::maybe, Engine&); Deferred_renderer(const Deferred_renderer&) = delete; auto operator=(const Deferred_renderer&) -> Deferred_renderer& = delete; @@ -185,7 +224,6 @@ namespace mirrage::renderer { auto gbuffer() noexcept -> auto& { return *_gbuffer; } auto gbuffer() const noexcept -> auto& { return *_gbuffer; } auto global_uniforms() const noexcept -> auto& { return _global_uniforms; } - auto global_uniforms_layout() const noexcept { return *_global_uniform_descriptor_set_layout; } auto asset_manager() noexcept -> auto& { return _factory->_assets; } auto device() noexcept -> auto& { return *_factory->_device; } @@ -203,9 +241,15 @@ namespace mirrage::renderer { auto noise_descriptor_set_layout() const noexcept { return *_noise_descriptor_set_layout; } auto noise_descriptor_set() const noexcept { return *_noise_descriptor_set; } + auto billboard_model() const noexcept -> auto& { return _billboard_model; } + auto model_material_sampler() const noexcept { return _factory->model_material_sampler(); } auto model_descriptor_set_layout() const noexcept { return _factory->model_descriptor_set_layout(); } + auto global_uniforms_layout() const noexcept { return _factory->global_uniforms_layout(); } + auto compute_storage_buffer_layout() const { return _factory->compute_storage_buffer_layout(); } + auto compute_uniform_buffer_layout() const { return _factory->compute_uniform_buffer_layout(); } + auto active_camera() noexcept -> util::maybe; auto settings() const -> auto& { return _factory->settings(); } @@ -225,6 +269,7 @@ namespace mirrage::renderer { _frame_data.debug_geometry_queue.emplace_back(line); } } + void debug_draw_sphere(const glm::vec3& center, float radius, const util::Rgb&); auto low_level_draw_queue() -> auto& { return _frame_data.geometry_queue; } @@ -234,10 +279,10 @@ namespace mirrage::renderer { private: friend class Deferred_renderer_factory; - Engine* _engine; - Deferred_renderer_factory* _factory; - ecs::Entity_manager* _entity_manager; - graphic::Descriptor_pool _descriptor_set_pool; + Engine* _engine; + Deferred_renderer_factory* _factory; + util::maybe _entity_manager; + graphic::Descriptor_pool _descriptor_set_pool; std::unique_ptr _gbuffer; Global_uniforms _global_uniforms; @@ -246,20 +291,22 @@ namespace mirrage::renderer { float _delta_time = 0.f; std::uint32_t _frame_counter = 0; - vk::UniqueDescriptorSetLayout _global_uniform_descriptor_set_layout; - graphic::DescriptorSet _global_uniform_descriptor_set; - graphic::Dynamic_buffer _global_uniform_buffer; + graphic::DescriptorSet _global_uniform_descriptor_set; + graphic::Dynamic_buffer _global_uniform_buffer; graphic::Texture_ptr _blue_noise; vk::UniqueSampler _noise_sampler; graphic::Image_descriptor_set_layout _noise_descriptor_set_layout; graphic::DescriptorSet _noise_descriptor_set; + Model _billboard_model; + + std::vector _pass_factories; std::vector> _passes; - Camera_comp::Pool* _cameras; - util::maybe _active_camera; - Frame_data _frame_data; + util::maybe _cameras; + util::maybe _active_camera; + Frame_data _frame_data; void _write_global_uniform_descriptor_set(); void _update_global_uniforms(vk::CommandBuffer, const Camera_state& camera); diff --git a/src/mirrage/renderer/include/mirrage/renderer/light_comp.hpp b/src/mirrage/renderer/include/mirrage/renderer/light_comp.hpp index 8a2552b5b6beb3c696d1a6fd106e0c8a4c6c2223..d2c63f4d038d6041d4196852fcfca037a7c27488 100644 --- a/src/mirrage/renderer/include/mirrage/renderer/light_comp.hpp +++ b/src/mirrage/renderer/include/mirrage/renderer/light_comp.hpp @@ -16,10 +16,13 @@ namespace mirrage::renderer { using Component::Component; void temperature(float kelvin); + void shadow_temperature(float kelvin); auto shadowcaster(bool b) noexcept { _shadowcaster = b; } void source_radius(util::Distance v) noexcept { _source_radius = v; } void intensity(float v) noexcept { _intensity = v; } + void shadow_intensity(float v) noexcept { _shadow_intensity = v; } void color(util::Rgb v) noexcept { _color = v; } + void shadow_color(util::Rgb v) noexcept { _shadow_color = v; } void shadowmap_id(int id) noexcept { _shadowmap_id = id; } void shadow_size(float v) noexcept { _shadow_size = v; } void shadow_near_plane(float v) noexcept { _shadow_near_plane = v; } @@ -28,9 +31,14 @@ namespace mirrage::renderer { auto shadowcaster() const noexcept { return _shadowcaster; } auto source_radius() const noexcept { return _source_radius; } auto intensity() const noexcept { return _intensity; } + auto shadow_intensity() const noexcept { return _shadow_intensity; } auto color() const noexcept { return _color; } + auto shadow_color() const noexcept { return _shadow_color; } auto shadowmap_id() const noexcept { return _shadowmap_id; } + void light_particles(bool b) noexcept { _light_particles = b; } + auto light_particles() const noexcept { return _light_particles; } + auto calc_shadowmap_view_proj(ecs::components::Transform_comp& transform) const -> glm::mat4; auto needs_update() { return _shadow_last_update >= _shadow_update_frequency; } @@ -49,6 +57,9 @@ namespace mirrage::renderer { util::Distance _source_radius; float _intensity; // in lux util::Rgb _color; + bool _light_particles = false; + float _shadow_intensity = 0; // in lux + util::Rgb _shadow_color = {0, 0, 0}; bool _shadowcaster = true; int _shadowmap_id = -1; float _shadow_size = 128; diff --git a/src/mirrage/renderer/include/mirrage/renderer/model.hpp b/src/mirrage/renderer/include/mirrage/renderer/model.hpp index cceb08571b372aa0222518373c657ba553cb8824..39d74cde30cd6da6978aaeb2338a36c814c780c4 100644 --- a/src/mirrage/renderer/include/mirrage/renderer/model.hpp +++ b/src/mirrage/renderer/include/mirrage/renderer/model.hpp @@ -21,12 +21,13 @@ namespace mirrage::renderer { struct Material_data { util::Str_id substance_id = "default"_strid; std::string albedo_aid; - std::string mat_data_aid; // RG: normal, B:roughness, A:metallic - std::string mat_data2_aid; // R:emissive intensity + std::string normal_aid; // RG: normal + std::string brdf_aid; // R:roughness, G:metallic + std::string emission_aid; // R:emissive intensity }; #ifdef sf2_structDef - sf2_structDef(Material_data, substance_id, albedo_aid, mat_data_aid, mat_data2_aid); + sf2_structDef(Material_data, substance_id, albedo_aid, normal_aid, brdf_aid, emission_aid); #endif @@ -37,30 +38,47 @@ namespace mirrage::renderer { graphic::DescriptorSet, vk::Sampler, graphic::Texture_ptr albedo, - graphic::Texture_ptr mat_data, - graphic::Texture_ptr mat_data2, + graphic::Texture_ptr normal, + graphic::Texture_ptr brdf, + graphic::Texture_ptr emission, + bool has_albedo, + bool has_normal, + bool has_brdf, + bool has_emission, util::Str_id substance_id); - void bind(graphic::Render_pass& pass) const; + void bind(graphic::Render_pass& pass, int bind_point = 1) const; auto substance_id() const noexcept { return _substance_id; } + auto has_albedo() const noexcept { return _has_albedo; } + auto has_normal() const noexcept { return _has_normal; } + auto has_brdf() const noexcept { return _has_brdf; } + auto has_emission() const noexcept { return _has_emission; } private: graphic::DescriptorSet _descriptor_set; graphic::Texture_ptr _albedo; - graphic::Texture_ptr _mat_data; - graphic::Texture_ptr _mat_data2; + graphic::Texture_ptr _normal; + graphic::Texture_ptr _brdf; + graphic::Texture_ptr _emission; util::Str_id _substance_id; + bool _has_albedo; + bool _has_normal; + bool _has_brdf; + bool _has_emission; }; using Material_ptr = asset::Ptr; - struct Model_vertex { glm::vec3 position; glm::vec3 normal; glm::vec2 tex_coords; Model_vertex() = default; + Model_vertex(glm::vec3 position, glm::vec3 normal, glm::vec2 tex_coords) + : position(position), normal(normal), tex_coords(tex_coords) + { + } Model_vertex(float px, float py, float pz, float nx, float ny, float nz, float u, float v) : position(px, py, pz), normal(nx, ny, nz), tex_coords(u, v) { @@ -219,6 +237,8 @@ namespace mirrage::renderer { auto rigged() const noexcept { return _rigged; } auto bone_count() const noexcept { return _bone_count; } + auto ready() const { return _mesh.ready(); } + private: graphic::Mesh _mesh; std::vector _sub_meshes; diff --git a/src/mirrage/renderer/include/mirrage/renderer/particle_system.hpp b/src/mirrage/renderer/include/mirrage/renderer/particle_system.hpp index 7ee006c692fc6c435f3f767fbb00c4832d20a1b7..deb41efd8d49d243ec362e0311022ad9fc57b184 100644 --- a/src/mirrage/renderer/include/mirrage/renderer/particle_system.hpp +++ b/src/mirrage/renderer/include/mirrage/renderer/particle_system.hpp @@ -1,153 +1,463 @@ #pragma once +#include + #include #include #include +#include #include +#include #include #include #include -#include +#include #include namespace mirrage::renderer { - enum class Particle_blend_mode { unlit }; - sf2_enumDef(Particle_blend_mode, unlit); + struct Particle { + glm::vec4 position; // xyz + ttl_left + glm::vec4 velocity; // xyz + ttl_initial + glm::uvec4 + data; // last_feedback_buffer_index, seed, keyframe, floatBitsToUint(keyframe_interpolation_factor) + }; + + class Particle_script { + public: + explicit Particle_script(vk::UniquePipeline pipeline) : _pipeline(std::move(pipeline)) {} + + void bind(vk::CommandBuffer) const; + + private: + vk::UniquePipeline _pipeline; + }; + + enum class Particle_blend_mode { solid, transparent, transparent_unlit }; + sf2_enumDef(Particle_blend_mode, solid, transparent, transparent_unlit); - enum class Particle_emitter_shape { sphere }; - sf2_enumDef(Particle_emitter_shape, sphere); + enum class Particle_geometry { billboard, mesh }; + sf2_enumDef(Particle_geometry, billboard, mesh); - template struct Particle_color { - T hue; - T saturation; - T value; - T alpha; + float hue = 0.f; + float saturation = 0.f; + float value = 0.f; + float alpha = 0.f; }; - sf2_structDef(Particle_color, hue, saturation, value, alpha); - sf2_structDef(Particle_color, hue, saturation, value, alpha); + sf2_structDef(Particle_color, hue, saturation, value, alpha); + + /// angle + axis rotation with the axis expressed in spherical coordinates + /// elevation=0 and azimuth=0 is (0,0,1) and the base-plane is XZ + struct Particle_rotation { + float elevation = 0.f; //< 0=0°, 1= 90° + float azimuth = 0.f; //< 0=0°, 1=360° + float angle = 0.f; //< 0=0°, 1=360° + float padding; + }; + sf2_structDef(Particle_rotation, elevation, azimuth, angle); - struct Particle_emitter_config { - float time = 0; + struct Particle_direction { + float elevation = 1.f; + float azimuth = 0.f; + float velocity_elevation = 1.f; + float velocity_azimuth = 0.f; + }; + sf2_structDef(Particle_direction, elevation, azimuth, velocity_elevation, velocity_azimuth); - float spawn_rate_mean = 10.f; - float spawn_rate_variance = 1.f; + template + struct Random_value { + T mean{}; + T stddev{}; + }; + sf2_structDef(Random_value, mean, stddev); + sf2_structDef(Random_value, mean, stddev); + sf2_structDef(Random_value, mean, stddev); + sf2_structDef(Random_value, mean, stddev); + sf2_structDef(Random_value, mean, stddev); + + + /// modify velocities of living particles + /// e.g. + /// gravity: {..., force=10, dir={0,-1,0}, decay=0} + /// point: {position=? dir={0,0,0}, decay=2} + /// flow: {position=? dir={1,0,0}, decay=2} + struct Particle_effector_config { + glm::quat rotation{1, 0, 0, 0}; + glm::vec3 position{0, 0, 0}; + bool absolute = false; + + float force = 0.f; + glm::vec3 force_dir{0, 0, 0}; + float distance_decay = 2.f; + + bool scale_with_mass = true; + float negative_mass_scale = 0.f; //< 0: clamp mass to >=0; >0: inverte direction; 0.5: force/2 + }; + sf2_structDef(Particle_effector_config, + position, + rotation, + absolute, + force, + force_dir, + distance_decay, + scale_with_mass, + negative_mass_scale); + + struct Particle_keyframe { + Random_value color = {{1, 0, 1, 1}}; + Random_value rotation = {}; + Random_value size = {{1.f, 1.f, 1.f, 0.f}}; + glm::vec4 clip_rect = {0, 0, 1, 1}; + + float time = 0; + float base_mass = 1; + float density = 0; + float drag = 0.f; + }; + sf2_structDef(Particle_keyframe, color, rotation, size, clip_rect, time, base_mass, density, drag); + static_assert(sizeof(Particle_keyframe) == sizeof(float) * (4 * 3 * 2 + 4 + 4), + "Particle_keyframe contains padding"); + + /// describes how living particles are updated and drawn + struct Particle_type_config { + util::small_vector keyframes; + + bool color_normal_distribution_h = false; + bool color_normal_distribution_s = false; + bool color_normal_distribution_v = false; + bool color_normal_distribution_a = false; + bool rotation_normal_distribution_x = false; + bool rotation_normal_distribution_y = false; + bool rotation_normal_distribution_z = false; + bool size_normal_distribution_x = false; + bool size_normal_distribution_y = false; + bool size_normal_distribution_z = false; + + bool rotate_with_velocity = false; + bool symmetric_scaling = false; //< also use x size for y and z + float loop_keyframe_time = 0.f; + + Particle_blend_mode blend = Particle_blend_mode::transparent; + Particle_geometry geometry = Particle_geometry::billboard; + + float update_range = -1.f; + float draw_range = -1.f; + bool shadowcaster = false; + + std::string material_id; + renderer::Material_ptr material; + + std::string model_id; + asset::Ptr model; + + std::string update_script_id; + asset::Ptr update_script; + }; + sf2_structDef(Particle_type_config, + keyframes, + color_normal_distribution_h, + color_normal_distribution_s, + color_normal_distribution_v, + color_normal_distribution_a, + rotation_normal_distribution_x, + rotation_normal_distribution_y, + rotation_normal_distribution_z, + size_normal_distribution_x, + size_normal_distribution_y, + size_normal_distribution_z, + rotate_with_velocity, + symmetric_scaling, + loop_keyframe_time, + blend, + geometry, + update_range, + draw_range, + shadowcaster, + material_id, + model_id, + update_script_id); + + + struct Particle_emitter_spawn { + float particles_per_second = 10.f; + float stddev = 0.f; + float time = -1.f; + }; + sf2_structDef(Particle_emitter_spawn, particles_per_second, stddev, time); - Particle_color color_mean = {1, 1, 1, 1}; - Particle_color color_variance = {0, 0, 0, 0}; - Particle_color color_change_mean = {0, 0, 0, 0}; - Particle_color color_change_variance = {0, 0, 0, 0}; + // describes how new particles are created + struct Particle_emitter_config { + Random_value ttl = {1.f}; + + Random_value velocity = {1.f}; - float size_mean = 0.1f; - float size_variance = 0.f; - float size_change_mean = 0.f; - float size_change_variance = 0.f; + glm::vec4 size = {0.f, 1.f, 0.f, 0.f}; // min_radius, max_radius, , - float rotation_mean = 0.1f; - float rotation_variance = 0.1f; - float rotation_change_mean = 0.f; - float rotation_change_variance = 0.f; + bool independent_direction = false; // initial velocity direction is independent of spawn position + Random_value direction = {Particle_direction{}, + Particle_direction{1.f, 0.5f, 1.f, 0.5f}}; + bool direction_normal_distribution = false; - float ttl_mean = 1.f; - float ttl_variance = 0.f; + float parent_velocity = 0.f; - float velocity_mean = 1.f; - float velocity_variance = 0.f; + glm::vec3 offset{0, 0, 0}; + glm::quat rotation{1, 0, 0, 0}; - Particle_blend_mode blend = Particle_blend_mode::unlit; - Particle_emitter_shape shape = Particle_emitter_shape::sphere; - glm::vec3 shape_size = glm::vec3(1, 1, 1); + util::small_vector spawn; + bool spawn_loop = true; - float drag = 0.f; + std::string emit_script_id; + asset::Ptr emit_script; - // returns offset and direction - auto calc_offset(std::mt19937&) -> std::tuple; + std::string type_id; + asset::Ptr type; }; sf2_structDef(Particle_emitter_config, - time, - spawn_rate_mean, - spawn_rate_variance, - color_mean, - color_variance, - color_change_mean, - color_change_variance, - size_mean, - size_variance, - size_change_mean, - size_change_variance, - rotation_mean, - rotation_variance, - rotation_change_mean, - rotation_change_variance, - ttl_mean, - ttl_variance, - velocity_mean, - velocity_variance, - blend, - shape, - shape_size, - drag); + spawn, + spawn_loop, + ttl, + velocity, + size, + independent_direction, + direction, + direction_normal_distribution, + parent_velocity, + offset, + rotation, + emit_script_id, + type_id); + + struct Particle_system_config { + util::small_vector emitters; + std::vector effectors; + }; + sf2_structDef(Particle_system_config, emitters, effectors); + class Particle_emitter_gpu_data { + public: + auto valid() const noexcept { return _live_rev && *_live_rev == _rev; } + void set(const std::uint64_t* rev, + vk::Buffer, + vk::DescriptorSet, + std::int32_t offset, + std::int32_t count, + std::uint32_t feedback_idx); + + void next_uniforms(vk::DescriptorSet s) { _next_uniforms = s; } + auto next_uniforms() const noexcept { return _next_uniforms; } + + auto batch_able() const noexcept { return _batch_able; } + void batch_able(bool b) noexcept { _batch_able = b; } + + private: + vk::Buffer _buffer; + vk::DescriptorSet _uniforms; + vk::DescriptorSet _next_uniforms; + const std::uint64_t* _live_rev = nullptr; + std::uint64_t _rev = 0; + std::int32_t _offset = 0; + std::int32_t _count = 0; + std::uint32_t _feedback_idx = 0; + bool _batch_able = true; + + friend class Particle_emitter; + }; + class Particle_emitter { public: - Particle_emitter(graphic::Texture_ptr texture, - std::vector keyframes, - std::size_t capacity, - util::maybe follow_entity = {}); + explicit Particle_emitter(const Particle_emitter_config& cfg) : _cfg(&cfg) {} + + void active(bool b) noexcept { _active = b; } + auto active() const noexcept { return _active; } + + void position(glm::vec3 p) noexcept { _position = p; } + auto position() const noexcept { return _position; } + + void rotation(glm::quat r) noexcept { _rotation = r; } + auto rotation() const noexcept { return _rotation; } + + void absolute(bool b) noexcept { _absolute = b; } + auto absolute() const noexcept { return _absolute; } - void position(glm::vec3 p) + void incr_time(float dt); + auto spawn(util::default_rand&) -> std::int32_t; + void override_spawn(std::int32_t spawn) { _particles_to_spawn = spawn; } + + auto drawable() const noexcept { return _gpu_data && _gpu_data->valid(); } + auto particle_offset() const noexcept { return drawable() ? _gpu_data->_offset : 0; } + auto particle_count() const noexcept { return drawable() ? _gpu_data->_count : 0; } + auto particle_feedback_idx() const noexcept + { + return drawable() ? util::just(_gpu_data->_feedback_idx) : util::nothing; + } + auto particle_buffer() const noexcept { return drawable() ? _gpu_data->_buffer : vk::Buffer{}; } + auto particle_uniforms() const noexcept { - _center_position = p; - _follow_entity = {}; + return drawable() ? _gpu_data->_uniforms : vk::DescriptorSet{}; } - void follow(ecs::Entity_facet f) { _follow_entity = f; } + auto particles_to_spawn() const noexcept { return _particles_to_spawn; } + auto last_timestep() const noexcept { return _last_timestep; } - void update(util::Time dt, bool emit_new, std::mt19937&); - auto dead() const -> bool { return _positions.empty(); } + auto gpu_data() -> std::shared_ptr; - auto active() const noexcept { return _active; } - void enable() { _active = true; } - void disable() { _active = false; } + auto cfg() const noexcept -> auto& { return *_cfg; } private: - graphic::Texture_ptr _texture; - std::vector _config_keyframes; + const Particle_emitter_config* _cfg; - std::vector _positions; - std::vector _seeds; - std::vector _creation_times; - std::vector _ttls; - std::vector _velocities; + // TODO: userdata? + bool _active = true; + glm::vec3 _position{0, 0, 0}; + glm::quat _rotation{1, 0, 0, 0}; + bool _absolute = false; - std::vector _dead_indices; + float _time_accumulator = 0.f; + std::size_t _spawn_idx = 0; + float _spawn_entry_timer = 0; - util::Time _time = util::Time{0.f}; - float _to_spawn = 0.f; - bool _active = true; + std::int32_t _particles_to_spawn = 0; + float _last_timestep = 0; - glm::vec3 _center_position = {0, 0, 0}; - util::maybe _follow_entity; + // shared_ptr because its update after the async compute tasks finished + std::shared_ptr _gpu_data; }; - class Particle_system { + class Particle_system : private std::enable_shared_from_this { public: - Particle_system(asset::Asset_manager& assets); + using Emitter_list = util::small_vector; + using Effector_list = std::vector; + + Particle_system() = default; + Particle_system(asset::Ptr cfg, + glm::vec3 position = {0, 0, 0}, + glm::quat rotation = {1, 0, 0, 0}); + + auto cfg() const noexcept { return _cfg; } + auto cfg_aid() const { return _cfg ? util::just(_cfg.aid()) : util::nothing; } - void add_emitter(std::shared_ptr); - auto add_emitter(asset::AID descriptor) -> std::shared_ptr; + auto emitters() noexcept -> auto& + { + _check_reload(); + return _emitters; + } + + auto effectors() noexcept -> auto& + { + _check_reload(); + return _effectors; + } - void update(util::Time); + void position(glm::vec3 p) noexcept { _position = p; } + auto position() const noexcept { return _position; } + + void rotation(glm::quat r) noexcept { _rotation = r; } + auto rotation() const noexcept { return _rotation; } + + auto emitter_position(const Particle_emitter& e) const noexcept + { + return e.absolute() ? e.position() : _position + e.position(); + } + + auto emitter_rotation(const Particle_emitter& e) const noexcept + { + return e.absolute() ? e.rotation() : glm::normalize(_rotation * e.rotation()); + } private: - asset::Asset_manager& _assets; - std::mt19937 _random_gen; + friend class Particle_pass; + + asset::Ptr _cfg; + bool _loaded = false; + Emitter_list _emitters; + Effector_list _effectors; + + glm::vec3 _position{0, 0, 0}; + glm::vec3 _last_position{0, 0, 0}; + glm::quat _rotation{1, 0, 0, 0}; + + void _check_reload(); + }; - std::vector> _emmitter; - // TODO + + class Particle_system_comp : public ecs::Component { + public: + static constexpr const char* name() { return "Particle_system"; } + friend void load_component(ecs::Deserializer& state, Particle_system_comp&); + friend void save_component(ecs::Serializer& state, const Particle_system_comp&); + + Particle_system_comp() = default; + Particle_system_comp(ecs::Entity_handle owner, ecs::Entity_manager& em) : Component(owner, em) {} + + Particle_system particle_system; }; + + class Particle_effector_comp : public ecs::Component { + public: + static constexpr const char* name() { return "Particle_effector"; } + friend void load_component(ecs::Deserializer& state, Particle_effector_comp&); + friend void save_component(ecs::Serializer& state, const Particle_effector_comp&); + + Particle_effector_comp() = default; + Particle_effector_comp(ecs::Entity_handle owner, ecs::Entity_manager& em) : Component(owner, em) {} + + Particle_effector_config effector; + }; + + + extern auto create_particle_shared_desc_set_layout(graphic::Device&) -> vk::UniqueDescriptorSetLayout; + + extern auto create_particle_script_pipeline_layout(graphic::Device& device, + vk::DescriptorSetLayout shared_desc_set, + vk::DescriptorSetLayout storage_buffer, + vk::DescriptorSetLayout uniform_buffer) + -> vk::UniquePipelineLayout; + } // namespace mirrage::renderer + +namespace mirrage::asset { + + template <> + struct Loader { + public: + Loader(graphic::Device& device, + vk::DescriptorSetLayout storage_buffer, + vk::DescriptorSetLayout uniform_buffer); + + auto load(istream in) -> renderer::Particle_script; + [[noreturn]] void save(ostream, const renderer::Particle_script&) + { + MIRRAGE_FAIL("Save of Particle_script is not supported!"); + } + + private: + graphic::Device& _device; + vk::UniqueDescriptorSetLayout _shared_desc_set; + vk::UniquePipelineLayout _layout; + }; + + template <> + struct Loader { + public: + auto load(istream in) -> async::task; + [[noreturn]] void save(ostream, const renderer::Particle_system_config&) + { + MIRRAGE_FAIL("Save of Particle_system_config is not supported!"); + } + }; + + template <> + struct Loader { + public: + auto load(istream in) -> async::task; + [[noreturn]] void save(ostream, const renderer::Particle_type_config&) + { + MIRRAGE_FAIL("Save of Particle_type_config is not supported!"); + } + }; + +} // namespace mirrage::asset diff --git a/src/mirrage/renderer/include/mirrage/renderer/pass/animation_pass.hpp b/src/mirrage/renderer/include/mirrage/renderer/pass/animation_pass.hpp index 58e6e2c90119dfd69ffa45849c85b96c2969cff6..e8d546b97813ed91e8a097ca85bbfb7d17f7cc49 100644 --- a/src/mirrage/renderer/include/mirrage/renderer/pass/animation_pass.hpp +++ b/src/mirrage/renderer/include/mirrage/renderer/pass/animation_pass.hpp @@ -39,8 +39,12 @@ namespace std { namespace mirrage::renderer { + class Animation_pass_factory; + class Animation_pass : public Render_pass { public: + using Factory = Animation_pass_factory; + Animation_pass(Deferred_renderer&, ecs::Entity_manager&); void update(util::Time dt) override; @@ -84,8 +88,16 @@ namespace mirrage::renderer { class Animation_pass_factory : public Render_pass_factory { public: - auto create_pass(Deferred_renderer&, ecs::Entity_manager&, Engine&, bool&) - -> std::unique_ptr override; + auto id() const noexcept -> Render_pass_id override + { + return render_pass_id_of(); + } + + auto create_pass(Deferred_renderer&, + std::shared_ptr, + util::maybe, + Engine&, + bool&) -> std::unique_ptr override; auto rank_device(vk::PhysicalDevice, util::maybe, int) -> int override; diff --git a/src/mirrage/renderer/include/mirrage/renderer/pass/billboard_pass.hpp b/src/mirrage/renderer/include/mirrage/renderer/pass/billboard_pass.hpp new file mode 100644 index 0000000000000000000000000000000000000000..b2e421f60db519b53d97d499d4df040de923977e --- /dev/null +++ b/src/mirrage/renderer/include/mirrage/renderer/pass/billboard_pass.hpp @@ -0,0 +1,50 @@ +#pragma once + +#include + +#include + + +namespace mirrage::renderer { + + class Billboard_pass_factory; + + class Billboard_pass : public Render_pass { + public: + using Factory = Billboard_pass_factory; + + Billboard_pass(Deferred_renderer&, ecs::Entity_manager&, graphic::Render_target_2D& target); + + void update(util::Time dt) override; + void draw(Frame_data&) override; + + auto name() const noexcept -> const char* override { return "Billboard"; } + + private: + Deferred_renderer& _renderer; + ecs::Entity_manager& _entities; + graphic::Framebuffer _framebuffer; + graphic::Render_pass _render_pass; + }; + + class Billboard_pass_factory : public Render_pass_factory { + public: + auto id() const noexcept -> Render_pass_id override + { + return render_pass_id_of(); + } + + auto create_pass(Deferred_renderer&, + std::shared_ptr, + util::maybe, + Engine&, + bool& write_first_pp_buffer) -> std::unique_ptr override; + + auto rank_device(vk::PhysicalDevice, util::maybe graphics_queue, int current_score) + -> int override; + + void configure_device(vk::PhysicalDevice, + util::maybe graphics_queue, + graphic::Device_create_info&) override; + }; +} // namespace mirrage::renderer diff --git a/src/mirrage/renderer/include/mirrage/renderer/pass/blit_pass.hpp b/src/mirrage/renderer/include/mirrage/renderer/pass/blit_pass.hpp index 219af6cb8068b2bb9787a1d5810ac1c69f23dd48..ea66dd58b334902df6e04d03cbe97e6a8769bdc5 100644 --- a/src/mirrage/renderer/include/mirrage/renderer/pass/blit_pass.hpp +++ b/src/mirrage/renderer/include/mirrage/renderer/pass/blit_pass.hpp @@ -7,9 +7,13 @@ namespace mirrage::renderer { + class Blit_pass_factory; + class Blit_pass : public Render_pass { public: - Blit_pass(Deferred_renderer&, graphic::Texture_2D& src); + using Factory = Blit_pass_factory; + + Blit_pass(Deferred_renderer&, graphic::Render_target_2D& src); void update(util::Time dt) override; void draw(Frame_data&) override; @@ -28,8 +32,13 @@ namespace mirrage::renderer { class Blit_pass_factory : public Render_pass_factory { public: - auto create_pass(Deferred_renderer&, ecs::Entity_manager&, Engine&, bool& write_first_pp_buffer) - -> std::unique_ptr override; + auto id() const noexcept -> Render_pass_id override { return render_pass_id_of(); } + + auto create_pass(Deferred_renderer&, + std::shared_ptr, + util::maybe, + Engine&, + bool& write_first_pp_buffer) -> std::unique_ptr override; auto rank_device(vk::PhysicalDevice, util::maybe graphics_queue, int current_score) -> int override; diff --git a/src/mirrage/renderer/include/mirrage/renderer/pass/bloom_pass.hpp b/src/mirrage/renderer/include/mirrage/renderer/pass/bloom_pass.hpp index 23ae3598d45bda277929925675272081e527f0b1..3f88a91178eff2aa97639a3533f6d01b1595cac9 100644 --- a/src/mirrage/renderer/include/mirrage/renderer/pass/bloom_pass.hpp +++ b/src/mirrage/renderer/include/mirrage/renderer/pass/bloom_pass.hpp @@ -7,8 +7,12 @@ namespace mirrage::renderer { + class Bloom_pass_factory; + class Bloom_pass : public Render_pass { public: + using Factory = Bloom_pass_factory; + Bloom_pass(Deferred_renderer&, graphic::Render_target_2D& src); @@ -46,8 +50,16 @@ namespace mirrage::renderer { class Bloom_pass_factory : public Render_pass_factory { public: - auto create_pass(Deferred_renderer&, ecs::Entity_manager&, Engine&, bool& write_first_pp_buffer) - -> std::unique_ptr override; + auto id() const noexcept -> Render_pass_id override + { + return render_pass_id_of(); + } + + auto create_pass(Deferred_renderer&, + std::shared_ptr, + util::maybe, + Engine&, + bool&) -> std::unique_ptr override; auto rank_device(vk::PhysicalDevice, util::maybe graphics_queue, int current_score) -> int override; diff --git a/src/mirrage/renderer/include/mirrage/renderer/pass/clear_pass.hpp b/src/mirrage/renderer/include/mirrage/renderer/pass/clear_pass.hpp new file mode 100644 index 0000000000000000000000000000000000000000..2d78b005825b8025db2c2f4eb875627a1a557605 --- /dev/null +++ b/src/mirrage/renderer/include/mirrage/renderer/pass/clear_pass.hpp @@ -0,0 +1,47 @@ +#pragma once + +#include + +#include + + +namespace mirrage::renderer { + + class Clear_pass_factory; + + class Clear_pass : public Render_pass { + public: + using Factory = Clear_pass_factory; + + Clear_pass(Deferred_renderer&); + + void update(util::Time dt) override; + void draw(Frame_data&) override; + + auto name() const noexcept -> const char* override { return "Clear"; } + + private: + Deferred_renderer& _renderer; + }; + + class Clear_pass_factory : public Render_pass_factory { + public: + auto id() const noexcept -> Render_pass_id override + { + return render_pass_id_of(); + } + + auto create_pass(Deferred_renderer&, + std::shared_ptr, + util::maybe, + Engine&, + bool& write_first_pp_buffer) -> std::unique_ptr override; + + auto rank_device(vk::PhysicalDevice, util::maybe graphics_queue, int current_score) + -> int override; + + void configure_device(vk::PhysicalDevice, + util::maybe graphics_queue, + graphic::Device_create_info&) override; + }; +} // namespace mirrage::renderer diff --git a/src/mirrage/renderer/include/mirrage/renderer/pass/debug_draw_pass.hpp b/src/mirrage/renderer/include/mirrage/renderer/pass/debug_draw_pass.hpp index 362bb87180a86d650c442806d29a099cf5e63c3b..1393c0758f5afc2b77c564dc09672f1e2726f916 100644 --- a/src/mirrage/renderer/include/mirrage/renderer/pass/debug_draw_pass.hpp +++ b/src/mirrage/renderer/include/mirrage/renderer/pass/debug_draw_pass.hpp @@ -8,8 +8,12 @@ namespace mirrage::renderer { + class Debug_draw_pass_factory; + class Debug_draw_pass : public Render_pass { public: + using Factory = Debug_draw_pass_factory; + Debug_draw_pass(Deferred_renderer&, graphic::Render_target_2D& src); void update(util::Time dt) override; @@ -26,8 +30,16 @@ namespace mirrage::renderer { class Debug_draw_pass_factory : public Render_pass_factory { public: - auto create_pass(Deferred_renderer&, ecs::Entity_manager&, Engine&, bool& write_first_pp_buffer) - -> std::unique_ptr override; + auto id() const noexcept -> Render_pass_id override + { + return render_pass_id_of(); + } + + auto create_pass(Deferred_renderer&, + std::shared_ptr, + util::maybe, + Engine&, + bool&) -> std::unique_ptr override; auto rank_device(vk::PhysicalDevice, util::maybe graphics_queue, int current_score) -> int override; diff --git a/src/mirrage/renderer/include/mirrage/renderer/pass/deferred_geometry_subpass.hpp b/src/mirrage/renderer/include/mirrage/renderer/pass/deferred_geometry_subpass.hpp index 13220f760dc09d5ecee598abfa1154535c693a4f..a8e0ce16e3c48f57ddabdd8ab51b81335d06c3f6 100644 --- a/src/mirrage/renderer/include/mirrage/renderer/pass/deferred_geometry_subpass.hpp +++ b/src/mirrage/renderer/include/mirrage/renderer/pass/deferred_geometry_subpass.hpp @@ -23,9 +23,20 @@ namespace mirrage::renderer { void configure_pipeline(Deferred_renderer&, graphic::Pipeline_description&); void configure_subpass(Deferred_renderer&, graphic::Subpass_builder&); + void configure_emissive_subpass(Deferred_renderer&, graphic::Subpass_builder&); void configure_animation_pipeline(Deferred_renderer&, graphic::Pipeline_description&); void configure_animation_subpass(Deferred_renderer&, graphic::Subpass_builder&); + void configure_animation_emissive_subpass(Deferred_renderer&, graphic::Subpass_builder&); + + void configure_billboard_pipeline(Deferred_renderer&, graphic::Pipeline_description&); + void configure_billboard_subpass(Deferred_renderer&, graphic::Subpass_builder&); + + void configure_decal_pipeline(Deferred_renderer&, graphic::Pipeline_description&); + void configure_decal_subpass(Deferred_renderer&, graphic::Subpass_builder&); + + void configure_particle_pipeline(Deferred_renderer&, graphic::Pipeline_description&); + void configure_particle_subpass(Deferred_renderer&, graphic::Subpass_builder&); void update(util::Time dt); void pre_draw(Frame_data&); @@ -37,5 +48,8 @@ namespace mirrage::renderer { util::iter_range::iterator> _geometry_range; util::iter_range::iterator> _rigged_geometry_range; + + vk::UniqueDescriptorSetLayout _decal_input_attachment_descriptor_set_layout; + graphic::DescriptorSet _decal_input_attachment_descriptor_set; }; } // namespace mirrage::renderer diff --git a/src/mirrage/renderer/include/mirrage/renderer/pass/deferred_pass.hpp b/src/mirrage/renderer/include/mirrage/renderer/pass/deferred_pass.hpp index 38736d1a5ba64a4ccba5e2a70ab40e8a5519ead6..adbbb5ea248b0cb316bec9baf85adacdb7745170 100644 --- a/src/mirrage/renderer/include/mirrage/renderer/pass/deferred_pass.hpp +++ b/src/mirrage/renderer/include/mirrage/renderer/pass/deferred_pass.hpp @@ -15,13 +15,18 @@ namespace mirrage::renderer { glm::vec4 light_color; //< for light-subpass; A=intensity glm::vec4 light_data; //< for light-subpass; R=src_radius, GBA=direction glm::vec4 light_data2; //< for light-subpass; R=shadowmapID + glm::vec4 shadow_color; }; static_assert(sizeof(Deferred_push_constants) <= 4096, "Too large for push constants!"); + class Deferred_pass_factory; + // populates linear-depth, albedo/matId, matData, writes the direct lighting results // to the target color-Buffer and just the diffuse lighting to the other color-Buffer class Deferred_pass : public Render_pass { public: + using Factory = Deferred_pass_factory; + Deferred_pass(Deferred_renderer&, ecs::Entity_manager&, graphic::Render_target_2D& color_target, @@ -47,8 +52,16 @@ namespace mirrage::renderer { class Deferred_pass_factory : public Render_pass_factory { public: - auto create_pass(Deferred_renderer&, ecs::Entity_manager&, Engine&, bool&) - -> std::unique_ptr override; + auto id() const noexcept -> Render_pass_id override + { + return render_pass_id_of(); + } + + auto create_pass(Deferred_renderer&, + std::shared_ptr, + util::maybe, + Engine&, + bool&) -> std::unique_ptr override; auto rank_device(vk::PhysicalDevice, util::maybe, int) -> int override; diff --git a/src/mirrage/renderer/include/mirrage/renderer/pass/depth_of_field_pass.hpp b/src/mirrage/renderer/include/mirrage/renderer/pass/depth_of_field_pass.hpp new file mode 100644 index 0000000000000000000000000000000000000000..5b82908ca5259aa44e1952fb0f8266d6d61bd1f7 --- /dev/null +++ b/src/mirrage/renderer/include/mirrage/renderer/pass/depth_of_field_pass.hpp @@ -0,0 +1,68 @@ +#pragma once + +#include + +#include + + +namespace mirrage::renderer { + + class Depth_of_field_pass_factory; + + /** + * @brief Depth of field effect based on + * http://tuxedolabs.blogspot.com/2018/05/bokeh-depth-of-field-in-single-pass.html + */ + class Depth_of_field_pass : public Render_pass { + public: + using Factory = Depth_of_field_pass_factory; + + Depth_of_field_pass(Deferred_renderer&, + graphic::Render_target_2D& src, + graphic::Render_target_2D& target); + + void update(util::Time dt) override; + void draw(Frame_data&) override; + + auto name() const noexcept -> const char* override { return "Depth of Fields"; } + + private: + Deferred_renderer& _renderer; + graphic::Render_target_2D& _src; + graphic::Render_target_2D& _target; + vk::UniqueSampler _gbuffer_sampler; + graphic::Image_descriptor_set_layout _descriptor_set_layout; + + graphic::DescriptorSet _coc_descriptor_set; + graphic::Framebuffer _coc_framebuffer; + graphic::Render_pass _coc_renderpass; + + graphic::DescriptorSet _dof_descriptor_set; + graphic::Framebuffer _dof_framebuffer; + graphic::Render_pass _dof_renderpass; + + graphic::DescriptorSet _apply_descriptor_set; + graphic::Framebuffer _apply_framebuffer; + graphic::Render_pass _apply_renderpass; + }; + + class Depth_of_field_pass_factory : public Render_pass_factory { + public: + auto id() const noexcept -> Render_pass_id override + { + return render_pass_id_of(); + } + + auto create_pass(Deferred_renderer&, + std::shared_ptr, + util::maybe, + Engine&, + bool&) -> std::unique_ptr override; + + auto rank_device(vk::PhysicalDevice, util::maybe, int) -> int override; + + void configure_device(vk::PhysicalDevice, + util::maybe, + graphic::Device_create_info&) override; + }; +} // namespace mirrage::renderer diff --git a/src/mirrage/renderer/include/mirrage/renderer/pass/frustum_culling_pass.hpp b/src/mirrage/renderer/include/mirrage/renderer/pass/frustum_culling_pass.hpp index 3617e69915149e045bc79c70530e7d0b06a69fd8..91fd33e4ec2826cc8d8e74ca6bdd6aa070c239ef 100644 --- a/src/mirrage/renderer/include/mirrage/renderer/pass/frustum_culling_pass.hpp +++ b/src/mirrage/renderer/include/mirrage/renderer/pass/frustum_culling_pass.hpp @@ -4,8 +4,12 @@ namespace mirrage::renderer { + class Frustum_culling_pass_factory; + class Frustum_culling_pass : public Render_pass { public: + using Factory = Frustum_culling_pass_factory; + Frustum_culling_pass(Deferred_renderer&, ecs::Entity_manager&); @@ -21,8 +25,16 @@ namespace mirrage::renderer { class Frustum_culling_pass_factory : public Render_pass_factory { public: - auto create_pass(Deferred_renderer&, ecs::Entity_manager&, Engine&, bool&) - -> std::unique_ptr override; + auto id() const noexcept -> Render_pass_id override + { + return render_pass_id_of(); + } + + auto create_pass(Deferred_renderer&, + std::shared_ptr, + util::maybe, + Engine&, + bool&) -> std::unique_ptr override; auto rank_device(vk::PhysicalDevice, util::maybe, int) -> int override; diff --git a/src/mirrage/renderer/include/mirrage/renderer/pass/gen_mipmap_pass.hpp b/src/mirrage/renderer/include/mirrage/renderer/pass/gen_mipmap_pass.hpp index 61742dab6caa457e9a7ab5dfd1eb679cf4b0da64..1ff5c31c13a170f228f9619104f8ed5f7c0a80ca 100644 --- a/src/mirrage/renderer/include/mirrage/renderer/pass/gen_mipmap_pass.hpp +++ b/src/mirrage/renderer/include/mirrage/renderer/pass/gen_mipmap_pass.hpp @@ -7,11 +7,15 @@ namespace mirrage::renderer { + class Gen_mipmap_pass_factory; + /** * @brief Generates mipmaps for depth and normal (mat_data) buffer */ class Gen_mipmap_pass : public Render_pass { public: + using Factory = Gen_mipmap_pass_factory; + Gen_mipmap_pass(Deferred_renderer&); @@ -34,8 +38,16 @@ namespace mirrage::renderer { class Gen_mipmap_pass_factory : public Render_pass_factory { public: - auto create_pass(Deferred_renderer&, ecs::Entity_manager&, Engine&, bool&) - -> std::unique_ptr override; + auto id() const noexcept -> Render_pass_id override + { + return render_pass_id_of(); + } + + auto create_pass(Deferred_renderer&, + std::shared_ptr, + util::maybe, + Engine&, + bool&) -> std::unique_ptr override; auto rank_device(vk::PhysicalDevice, util::maybe, int) -> int override; diff --git a/src/mirrage/renderer/include/mirrage/renderer/pass/gi_pass.hpp b/src/mirrage/renderer/include/mirrage/renderer/pass/gi_pass.hpp index 4acbb0db7f388e0216d530cbf53f351836bb2138..4f65c083808f77a7058de3d3e77ea79245fa16bf 100644 --- a/src/mirrage/renderer/include/mirrage/renderer/pass/gi_pass.hpp +++ b/src/mirrage/renderer/include/mirrage/renderer/pass/gi_pass.hpp @@ -7,8 +7,12 @@ namespace mirrage::renderer { + class Gi_pass_factory; + class Gi_pass : public Render_pass { public: + using Factory = Gi_pass_factory; + Gi_pass(Deferred_renderer&, graphic::Render_target_2D& in_out, graphic::Render_target_2D& diffuse_in); @@ -130,8 +134,13 @@ namespace mirrage::renderer { class Gi_pass_factory : public Render_pass_factory { public: - auto create_pass(Deferred_renderer&, ecs::Entity_manager&, Engine&, bool&) - -> std::unique_ptr override; + auto id() const noexcept -> Render_pass_id override { return render_pass_id_of(); } + + auto create_pass(Deferred_renderer&, + std::shared_ptr, + util::maybe, + Engine&, + bool&) -> std::unique_ptr override; auto rank_device(vk::PhysicalDevice, util::maybe, int) -> int override; diff --git a/src/mirrage/renderer/include/mirrage/renderer/pass/gui_pass.hpp b/src/mirrage/renderer/include/mirrage/renderer/pass/gui_pass.hpp index 222fe8e1250717e1a07500dbc0928365480408bb..7a0d3b652ec1b6cfbab72ea7940eb87d48923b1e 100644 --- a/src/mirrage/renderer/include/mirrage/renderer/pass/gui_pass.hpp +++ b/src/mirrage/renderer/include/mirrage/renderer/pass/gui_pass.hpp @@ -12,39 +12,47 @@ namespace mirrage::renderer { + class Gui_pass_factory; + class Gui_pass : public Render_pass, public gui::Gui_renderer_interface { public: - Gui_pass(Deferred_renderer&, Engine&); + using Factory = Gui_pass_factory; + + Gui_pass(Deferred_renderer&, Engine&, std::shared_ptr last_state); void update(util::Time dt) override; void draw(Frame_data&) override; auto load_texture(int width, int height, int channels, const std::uint8_t* data) - -> std::shared_ptr override; + -> std::shared_ptr override; - auto load_texture(const asset::AID&) -> std::shared_ptr override; + auto load_texture(const asset::AID&) -> std::shared_ptr override; auto name() const noexcept -> const char* override { return "GUI"; } + auto extract_persistent_state() -> std::shared_ptr override; + protected: - void prepare_draw(gsl::span indices, - gsl::span vertices, - glm::mat4 view_proj) override; - void draw_elements(int texture_handle, + void prepare_draw(std::size_t index_count, + std::size_t vertex_count, + glm::mat4 view_proj, + Prepare_data_src write_data) override; + void draw_elements(void* texture_handle, glm::vec4 clip_rect, std::uint32_t offset, - std::uint32_t count) override; + std::uint32_t count, + std::uint32_t vertex_offset) override; void finalize_draw() override; private: struct Loaded_texture { public: - struct nk_image handle; + void* handle; auto get_if_ready() -> util::maybe; - Loaded_texture(int handle, + Loaded_texture(std::uintptr_t handle, graphic::Texture_ptr texture, vk::Sampler, Deferred_renderer&, @@ -59,22 +67,36 @@ namespace mirrage::renderer { bool initialized = false; }; + struct Texture_cache { + Deferred_renderer& _renderer; + vk::UniqueSampler _sampler; + vk::UniqueDescriptorSetLayout _descriptor_set_layout; + std::uintptr_t _next_texture_handle = 0; + std::vector> _loaded_textures; + std::unordered_map> _loaded_textures_by_aid; + std::unordered_map> _loaded_textures_by_handle; + + Texture_cache(Deferred_renderer&); + + void shrink(); + + auto load_texture(int width, int height, int channels, const std::uint8_t* data) + -> std::shared_ptr; + + auto load_texture(const asset::AID&) -> std::shared_ptr; + }; + Deferred_renderer& _renderer; - std::vector _framebuffers; vk::UniqueSampler _sampler; vk::UniqueDescriptorSetLayout _descriptor_set_layout; + std::shared_ptr _texture_cache; + std::vector _framebuffers; graphic::Render_pass _render_pass; graphic::DescriptorSet _descriptor_set; graphic::Streamed_buffer _mesh_buffer; - // texture cache/store - int _next_texture_handle = 0; - std::vector> _loaded_textures; - std::unordered_map> _loaded_textures_by_aid; - std::unordered_map> _loaded_textures_by_handle; - // temporary values used during draw - int _bound_texture_handle = -1; + util::maybe _bound_texture_handle = util::nothing; util::maybe _current_command_buffer; util::maybe _current_framebuffer; }; @@ -82,8 +104,15 @@ namespace mirrage::renderer { class Gui_pass_factory : public Render_pass_factory { public: - auto create_pass(Deferred_renderer&, ecs::Entity_manager&, Engine&, bool&) - -> std::unique_ptr override; + auto id() const noexcept -> Render_pass_id override { return render_pass_id_of(); } + + auto requires_gbuffer() const noexcept -> bool override { return false; } + + auto create_pass(Deferred_renderer&, + std::shared_ptr last_state, + util::maybe, + Engine&, + bool&) -> std::unique_ptr override; auto rank_device(vk::PhysicalDevice, util::maybe, int) -> int override; diff --git a/src/mirrage/renderer/include/mirrage/renderer/pass/particle_pass.hpp b/src/mirrage/renderer/include/mirrage/renderer/pass/particle_pass.hpp new file mode 100644 index 0000000000000000000000000000000000000000..d6489a9174c530973a6c36a6b54c98391ec30e16 --- /dev/null +++ b/src/mirrage/renderer/include/mirrage/renderer/pass/particle_pass.hpp @@ -0,0 +1,111 @@ +#pragma once + +#include + +#include +#include + + +namespace mirrage::renderer { + + class Particle_pass_factory; + + /** + * @brief Updates particle systems and submits them for drawing + * Should be after animation but before other render_passes + */ + class Particle_pass : public Render_pass { + public: + using Factory = Particle_pass_factory; + + Particle_pass(Deferred_renderer&, ecs::Entity_manager&); + + + void update(util::Time dt) override; + void draw(Frame_data&) override; + + auto name() const noexcept -> const char* override { return "Particle"; } + + private: + struct Update_uniform_buffer { + graphic::Backed_buffer buffer; + graphic::DescriptorSet desc_set; + std::int32_t capacity = -1; + + void reserve(Deferred_renderer& renderer, std::int32_t new_capacity); + }; + struct Per_frame_data { + vk::UniqueCommandBuffer commands; + graphic::Backed_buffer particles; + graphic::Backed_buffer shared_uniforms; + graphic::DescriptorSet descriptor_set; + std::int32_t capacity = -1; + std::int32_t effector_capacity = -1; + std::vector particle_type_data; + std::int32_t next_free_particle_type_data = 0; + + void reserve(Deferred_renderer& renderer, + std::int32_t particle_count, + std::int32_t particle_type_count, + std::int32_t global_effector_count); + + auto next_particle_type_data() -> Update_uniform_buffer&; + }; + + struct Emitter_range { + std::int32_t offset; + std::int32_t count; + }; + + using Emitter_gpu_data = std::vector>; + + Deferred_renderer& _renderer; + ecs::Entity_manager& _ecs; + util::default_rand _rand; + vk::DeviceSize _storage_buffer_offset_alignment; + vk::UniqueDescriptorSetLayout _descriptor_set_layout; + vk::UniquePipelineLayout _pipeline_layout; + std::uint64_t _rev = 0; //< used to invalidate data of old particle emitters + + float _dt = 0.f; + + bool _update_submitted = false; + graphic::Fence _update_fence; + graphic::Backed_buffer _feedback_buffer; + graphic::Backed_buffer _feedback_buffer_host; + std::size_t _feedback_buffer_size = 0; + Emitter_gpu_data _emitter_gpu_data; + + std::vector _per_frame_data; + std::int32_t _current_frame = 0; + bool _first_frame = true; + + void _submit_update(Frame_data&); + auto _alloc_feedback_buffer(Frame_data&) + -> std::tuple, gsl::span>; + void _update_descriptor_set(Per_frame_data&, util::maybe); + void _update_type_uniforms(Frame_data&, Per_frame_data&); + void _dispatch_emits(Frame_data&, vk::CommandBuffer); + void _dispatch_updates(Frame_data&, vk::CommandBuffer); + }; + + class Particle_pass_factory : public Render_pass_factory { + public: + auto id() const noexcept -> Render_pass_id override + { + return render_pass_id_of(); + } + + auto create_pass(Deferred_renderer&, + std::shared_ptr, + util::maybe, + Engine&, + bool&) -> std::unique_ptr override; + + auto rank_device(vk::PhysicalDevice, util::maybe, int) -> int override; + + void configure_device(vk::PhysicalDevice, + util::maybe, + graphic::Device_create_info&) override; + }; +} // namespace mirrage::renderer diff --git a/src/mirrage/renderer/include/mirrage/renderer/pass/shadowmapping_pass.hpp b/src/mirrage/renderer/include/mirrage/renderer/pass/shadowmapping_pass.hpp index 60c8d866096c99be17129ca7cbbba43715f55d53..897e92e1dfb7d17f82b04657e59af958daa99c40 100644 --- a/src/mirrage/renderer/include/mirrage/renderer/pass/shadowmapping_pass.hpp +++ b/src/mirrage/renderer/include/mirrage/renderer/pass/shadowmapping_pass.hpp @@ -26,8 +26,12 @@ namespace mirrage::renderer { Shadowmap(Shadowmap&& rhs) noexcept; }; + class Shadowmapping_pass_factory; + class Shadowmapping_pass : public Render_pass { public: + using Factory = Shadowmapping_pass_factory; + Shadowmapping_pass(Deferred_renderer&, ecs::Entity_manager&); void update(util::Time dt) override; @@ -51,8 +55,16 @@ namespace mirrage::renderer { class Shadowmapping_pass_factory : public Render_pass_factory { public: - auto create_pass(Deferred_renderer&, ecs::Entity_manager&, Engine&, bool&) - -> std::unique_ptr override; + auto id() const noexcept -> Render_pass_id override + { + return render_pass_id_of(); + } + + auto create_pass(Deferred_renderer&, + std::shared_ptr, + util::maybe, + Engine&, + bool&) -> std::unique_ptr override; auto rank_device(vk::PhysicalDevice, util::maybe, int) -> int override; diff --git a/src/mirrage/renderer/include/mirrage/renderer/pass/ssao_pass.hpp b/src/mirrage/renderer/include/mirrage/renderer/pass/ssao_pass.hpp index c428a2afc98343526e5cc70fffaeea3634fed5e0..008b6037b037f6055189e31bfef30cb17361594d 100644 --- a/src/mirrage/renderer/include/mirrage/renderer/pass/ssao_pass.hpp +++ b/src/mirrage/renderer/include/mirrage/renderer/pass/ssao_pass.hpp @@ -7,8 +7,12 @@ namespace mirrage::renderer { + class Ssao_pass_factory; + class Ssao_pass : public Render_pass { public: + using Factory = Ssao_pass_factory; + Ssao_pass(Deferred_renderer&); void update(util::Time dt) override; @@ -38,8 +42,13 @@ namespace mirrage::renderer { class Ssao_pass_factory : public Render_pass_factory { public: - auto create_pass(Deferred_renderer&, ecs::Entity_manager&, Engine&, bool&) - -> std::unique_ptr override; + auto id() const noexcept -> Render_pass_id override { return render_pass_id_of(); } + + auto create_pass(Deferred_renderer&, + std::shared_ptr, + util::maybe, + Engine&, + bool&) -> std::unique_ptr override; auto rank_device(vk::PhysicalDevice, util::maybe, int) -> int override; diff --git a/src/mirrage/renderer/include/mirrage/renderer/pass/taa_pass.hpp b/src/mirrage/renderer/include/mirrage/renderer/pass/taa_pass.hpp index e2d75a7694903148be7b85f42b1acb4b7a802852..4817fe15294fa3feadfc11e5b3631cd506b95017 100644 --- a/src/mirrage/renderer/include/mirrage/renderer/pass/taa_pass.hpp +++ b/src/mirrage/renderer/include/mirrage/renderer/pass/taa_pass.hpp @@ -12,8 +12,12 @@ namespace mirrage::renderer { glm::mat4 fov_reprojection{}; // fov_reprojection[3].xy = offset }; + class Taa_pass_factory; + class Taa_pass : public Render_pass { public: + using Factory = Taa_pass_factory; + Taa_pass(Deferred_renderer&, graphic::Render_target_2D& write, graphic::Texture_2D& read); @@ -47,8 +51,13 @@ namespace mirrage::renderer { class Taa_pass_factory : public Render_pass_factory { public: - auto create_pass(Deferred_renderer&, ecs::Entity_manager&, Engine&, bool&) - -> std::unique_ptr override; + auto id() const noexcept -> Render_pass_id override { return render_pass_id_of(); } + + auto create_pass(Deferred_renderer&, + std::shared_ptr, + util::maybe, + Engine&, + bool&) -> std::unique_ptr override; auto rank_device(vk::PhysicalDevice, util::maybe, int) -> int override; diff --git a/src/mirrage/renderer/include/mirrage/renderer/pass/tone_mapping_pass.hpp b/src/mirrage/renderer/include/mirrage/renderer/pass/tone_mapping_pass.hpp index 18bcf7a6edaca462d06bbff3f0827048c2d6372c..c676b6e0b1a482d50b6e4779fb56f0f8aea84314 100644 --- a/src/mirrage/renderer/include/mirrage/renderer/pass/tone_mapping_pass.hpp +++ b/src/mirrage/renderer/include/mirrage/renderer/pass/tone_mapping_pass.hpp @@ -7,8 +7,12 @@ namespace mirrage::renderer { + class Tone_mapping_pass_factory; + class Tone_mapping_pass : public Render_pass { public: + using Factory = Tone_mapping_pass_factory; + Tone_mapping_pass(Deferred_renderer&, graphic::Render_target_2D& src, graphic::Render_target_2D& target); @@ -63,8 +67,16 @@ namespace mirrage::renderer { class Tone_mapping_pass_factory : public Render_pass_factory { public: - auto create_pass(Deferred_renderer&, ecs::Entity_manager&, Engine&, bool&) - -> std::unique_ptr override; + auto id() const noexcept -> Render_pass_id override + { + return render_pass_id_of(); + } + + auto create_pass(Deferred_renderer&, + std::shared_ptr, + util::maybe, + Engine&, + bool&) -> std::unique_ptr override; auto rank_device(vk::PhysicalDevice, util::maybe, int) -> int override; diff --git a/src/mirrage/renderer/include/mirrage/renderer/pass/transparent_pass.hpp b/src/mirrage/renderer/include/mirrage/renderer/pass/transparent_pass.hpp new file mode 100644 index 0000000000000000000000000000000000000000..de02330a45920ddb756c6ea0bbbea6baf2c9225a --- /dev/null +++ b/src/mirrage/renderer/include/mirrage/renderer/pass/transparent_pass.hpp @@ -0,0 +1,65 @@ +#pragma once + +#include + +#include +#include + + +namespace mirrage::renderer { + + class Transparent_pass_factory; + + class Transparent_pass : public Render_pass { + public: + using Factory = Transparent_pass_factory; + + Transparent_pass(Deferred_renderer&, ecs::Entity_manager& ecs, graphic::Render_target_2D& target); + + void update(util::Time dt) override; + void draw(Frame_data&) override; + + auto name() const noexcept -> const char* override { return "Transparent"; } + + private: + Deferred_renderer& _renderer; + ecs::Entity_manager& _ecs; + vk::Format _revealage_format; + graphic::Render_target_2D _accum; + graphic::Render_target_2D _revealage; + + vk::UniqueSampler _sampler; + vk::UniqueDescriptorSetLayout _desc_set_layout; + graphic::DescriptorSet _accum_descriptor_set; + std::vector _compose_descriptor_sets; + + std::vector _accum_framebuffers; + graphic::Render_pass _accum_render_pass; + + graphic::Framebuffer _compose_framebuffer; + graphic::Render_pass _compose_render_pass; + + graphic::Dynamic_buffer _light_uniforms; + std::vector _light_uniforms_tmp; + }; + + class Transparent_pass_factory : public Render_pass_factory { + public: + auto id() const noexcept -> Render_pass_id override + { + return render_pass_id_of(); + } + + auto create_pass(Deferred_renderer&, + std::shared_ptr, + util::maybe, + Engine&, + bool&) -> std::unique_ptr override; + + auto rank_device(vk::PhysicalDevice, util::maybe, int) -> int override; + + void configure_device(vk::PhysicalDevice, + util::maybe, + graphic::Device_create_info&) override; + }; +} // namespace mirrage::renderer diff --git a/src/mirrage/renderer/include/mirrage/renderer/render_pass.hpp b/src/mirrage/renderer/include/mirrage/renderer/render_pass.hpp index 956020213b9f27c0d41c133fff923a8a9ee2b80b..3ccf26e44ccb76fe02cabb2893d004a1328dc4e3 100644 --- a/src/mirrage/renderer/include/mirrage/renderer/render_pass.hpp +++ b/src/mirrage/renderer/include/mirrage/renderer/render_pass.hpp @@ -1,8 +1,13 @@ #pragma once +#include +#include +#include + #include #include #include +#include #include #include @@ -11,6 +16,7 @@ #include #include +#include #include @@ -99,6 +105,36 @@ namespace mirrage::renderer { glm::vec3 start; glm::vec3 end; util::Rgb color; + + Debug_geometry() = default; + Debug_geometry(const glm::vec3& start, const glm::vec3& end, const util::Rgb& color) + : start(start), end(end), color(color) + { + } + }; + + struct Particle_draw { + ecs::Entity_handle entity; + Particle_emitter* emitter; + Particle_system* system; + const Particle_type_config* type_cfg; + gsl::span effectors; + std::uint32_t culling_mask; + + Particle_draw() = default; + Particle_draw(ecs::Entity_handle entity, + Particle_emitter& emitter, + Particle_system& system, + gsl::span effectors, + std::uint32_t culling_mask) + : entity(entity) + , emitter(&emitter) + , system(&system) + , type_cfg(&*emitter.cfg().type) + , effectors(effectors) + , culling_mask(culling_mask) + { + } }; class Frame_data { @@ -107,11 +143,23 @@ namespace mirrage::renderer { vk::DescriptorSet global_uniform_set; std::size_t swapchain_image; - std::vector geometry_queue; - std::vector light_queue; - std::vector debug_geometry_queue; + std::vector geometry_queue; + std::vector light_queue; + std::vector debug_geometry_queue; + std::vector billboard_queue; + std::vector> decal_queue; + std::vector particle_queue; auto partition_geometry(std::uint32_t mask) -> util::vector_range; + void clear_queues() + { + geometry_queue.clear(); + light_queue.clear(); + debug_geometry_queue.clear(); + billboard_queue.clear(); + decal_queue.clear(); + particle_queue.clear(); + } }; class Render_pass { @@ -124,17 +172,29 @@ namespace mirrage::renderer { virtual void process_camera(Camera_state&) {} //< allows passes to modify the current camera virtual auto name() const noexcept -> const char* = 0; + + /// API to allow render passes to save some of their state (e.g. loaded textures/data) + /// across pipeline/renderer recreation + virtual auto extract_persistent_state() -> std::shared_ptr { return {}; } }; + using Render_pass_id = util::type_uid_t; + class Render_pass_factory { public: + Render_pass_factory(); virtual ~Render_pass_factory() = default; + virtual auto id() const noexcept -> Render_pass_id = 0; + virtual auto create_pass(Deferred_renderer&, - ecs::Entity_manager&, + std::shared_ptr last_state, + util::maybe, Engine&, bool& write_first_pp_buffer) -> std::unique_ptr = 0; + virtual auto requires_gbuffer() const noexcept -> bool { return true; } + virtual auto rank_device(vk::PhysicalDevice, util::maybe graphics_queue, int current_score) -> int @@ -151,4 +211,16 @@ namespace mirrage::renderer { } }; + template + auto render_pass_id_of() + { + if constexpr(std::is_base_of::value) + return util::type_uid_of(); + else { + static_assert(std::is_base_of::value, + "T is not a renderpass, nor its factory."); + return util::type_uid_of(); + } + } + } // namespace mirrage::renderer diff --git a/assets/core_assets/shader/model_emissive.frag b/src/mirrage/renderer/shader/billboard.frag similarity index 57% rename from assets/core_assets/shader/model_emissive.frag rename to src/mirrage/renderer/shader/billboard.frag index 45e3f555dfecb802abc7e4f47c130c3ad1018944..8f13d1a1a1777ac19c150704fdd23a6fdd807327 100644 --- a/assets/core_assets/shader/model_emissive.frag +++ b/src/mirrage/renderer/shader/billboard.frag @@ -6,24 +6,26 @@ #include "normal_encoding.glsl" layout(location = 0) in vec3 view_pos; -layout(location = 1) in vec3 normal; -layout(location = 2) in vec2 tex_coords; +layout(location = 1) in vec2 tex_coords; layout(location = 0) out vec4 depth_out; -layout(location = 1) out vec4 albedo_mat_id; +layout(location = 1) out vec4 albedo_mat_id_out; layout(location = 2) out vec4 mat_data_out; layout(location = 3) out vec4 color_out; layout(location = 4) out vec4 color_diffuse_out; layout(set=1, binding = 0) uniform sampler2D albedo_sampler; -layout(set=1, binding = 1) uniform sampler2D mat_data_sampler; -layout(set=1, binding = 2) uniform sampler2D mat_data2_sampler; +layout(set=1, binding = 1) uniform sampler2D normal_sampler; +layout(set=1, binding = 2) uniform sampler2D brdf_sampler; +layout(set=1, binding = 3) uniform sampler2D emission_sampler; layout(push_constant) uniform Per_model_uniforms { - mat4 model; - vec4 light_color; - vec4 material_properties; + vec4 position; + vec4 size; // xy, z=screen_space, w=fixed_screen_size + vec4 clip_rect; + vec4 color; + vec4 emissive_color; } model_uniforms; const float PI = 3.14159265359; @@ -34,33 +36,28 @@ vec3 tangent_space_to_world(vec3 N); void main() { vec4 albedo = texture(albedo_sampler, tex_coords); + albedo *= model_uniforms.color; - if(albedo.a < 0.1) + if(albedo.a<0.05) discard; - vec4 mat_data = texture(mat_data_sampler, tex_coords); - - vec3 N = tangent_space_to_world(decode_tangent_normal(mat_data.rg)); - N = normalize(normal); - - float roughness = mat_data.b; - float metallic = mat_data.a; + vec3 N = tangent_space_to_world(decode_tangent_normal(texture(normal_sampler, tex_coords).rg)); + vec4 brdf = texture(brdf_sampler, tex_coords); + float roughness = brdf.r; + float metallic = brdf.g; roughness = mix(0.01, 0.99, roughness*roughness); - float emissive_power = texture(mat_data2_sampler, tex_coords).r; - float emissive_only = step(0.1, emissive_power); + float emissive_power = texture(emission_sampler, tex_coords).r; - albedo.rgb *= mix(vec3(1), model_uniforms.material_properties.rgb, emissive_only); - - depth_out = vec4(-view_pos.z / global_uniforms.proj_planes.y, 0,0,1); - albedo_mat_id = vec4(albedo.rgb, 1.0); - mat_data_out = vec4(encode_normal(N), mix(roughness, 1, emissive_only), metallic); - color_out = vec4(albedo.rgb * emissive_power * model_uniforms.material_properties.a, 1.0); + depth_out = vec4(-view_pos.z / global_uniforms.proj_planes.y, 0,0,1); + albedo_mat_id_out = vec4(albedo.rgb, 0.0); + mat_data_out = vec4(encode_normal(N), roughness, metallic); + color_out = vec4(albedo.rgb * model_uniforms.emissive_color.rgb + * emissive_power * model_uniforms.emissive_color.a * albedo.a, 1.0); color_diffuse_out = color_out; } - vec3 decode_tangent_normal(vec2 tn) { if(dot(tn,tn)<0.00001) return vec3(0,0,1); @@ -71,7 +68,7 @@ vec3 decode_tangent_normal(vec2 tn) { } vec3 tangent_space_to_world(vec3 N) { - vec3 VN = normalize(normal); + vec3 VN = vec3(0,0,1); // calculate tangent vec3 p_dx = dFdx(view_pos); diff --git a/src/mirrage/renderer/shader/billboard.vert b/src/mirrage/renderer/shader/billboard.vert new file mode 100644 index 0000000000000000000000000000000000000000..5d2a198cb3e407522299f21f602c35b5e0d8a7f9 --- /dev/null +++ b/src/mirrage/renderer/shader/billboard.vert @@ -0,0 +1,54 @@ +#version 450 +#extension GL_ARB_separate_shader_objects : enable +#extension GL_ARB_shading_language_420pack : enable + +#include "global_uniforms.glsl" + + +layout(location = 0) out vec3 out_view_pos; +layout(location = 1) out vec2 out_tex_coords; + +layout(push_constant) uniform Per_model_uniforms { + vec4 position; + vec4 size; // xy, z=screen_space, w=fixed_screen_size + vec4 clip_rect; + vec4 color; + vec4 emissive_color; +} model_uniforms; + +out gl_PerVertex { + vec4 gl_Position; +}; + +const vec2 vertex_positions[4] = vec2[]( + vec2(0, 0), + vec2(1, 0), + vec2(0, 1), + vec2(1, 1) +); + +void main() { + + vec2 p = vertex_positions[gl_VertexIndex]; + vec2 offset = (p-0.5)*model_uniforms.size.xy; + + if(model_uniforms.position.w>0.5) + offset = vec2(offset.x, 0) + offset.y*vec2(global_uniforms.view_mat[1][0], global_uniforms.view_mat[1][1]); + + vec4 view_pos = vec4(model_uniforms.position.xyz, 1.0); + if(model_uniforms.size.w<0.5) + view_pos.xy += offset; + + vec4 ndc_pos = global_uniforms.proj_mat * view_pos; + if(model_uniforms.size.z>=0.5) + ndc_pos = view_pos; + + if(model_uniforms.size.w>=0.5) { + ndc_pos.xy += vec2(offset.x, -offset.y)*ndc_pos.w; + } + + gl_Position = ndc_pos; + out_view_pos = view_pos.xyz; + out_tex_coords = model_uniforms.clip_rect.xy + p * model_uniforms.clip_rect.zw; + out_tex_coords.y = 1-out_tex_coords.y; +} diff --git a/src/mirrage/renderer/shader/billboard_unlit.frag b/src/mirrage/renderer/shader/billboard_unlit.frag new file mode 100644 index 0000000000000000000000000000000000000000..4e1c902f35378e2676817ece98c1ba662b62ffaf --- /dev/null +++ b/src/mirrage/renderer/shader/billboard_unlit.frag @@ -0,0 +1,35 @@ +#version 450 +#extension GL_ARB_separate_shader_objects : enable +#extension GL_ARB_shading_language_420pack : enable + +#include "global_uniforms.glsl" +#include "normal_encoding.glsl" + +layout(location = 0) in vec3 view_pos; +layout(location = 1) in vec2 tex_coords; + +layout(location = 0) out vec4 color_out; + +layout(set=1, binding = 0) uniform sampler2D albedo_sampler; +layout(set=1, binding = 1) uniform sampler2D normal_sampler; +layout(set=1, binding = 2) uniform sampler2D brdf_sampler; +layout(set=1, binding = 3) uniform sampler2D emission_sampler; + +layout(push_constant) uniform Per_model_uniforms { + vec4 position; + vec4 size; // xy, z=screen_space, w=fixed_screen_size + vec4 clip_rect; + vec4 color; + vec4 emissive_color; +} model_uniforms; + + +void main() { + vec4 albedo = texture(albedo_sampler, tex_coords); + albedo *= model_uniforms.color; + + if(albedo.a<0.05) + discard; + + color_out = vec4(albedo.rgb * albedo.a, 0.0); +} diff --git a/assets/core_assets/shader/blit.frag b/src/mirrage/renderer/shader/blit.frag similarity index 96% rename from assets/core_assets/shader/blit.frag rename to src/mirrage/renderer/shader/blit.frag index 2625652d80fe7feb7128cbf8e501cd57acfb3e09..b4f7f0e4102552a8e4362f6ba6e097456caf51e9 100644 --- a/assets/core_assets/shader/blit.frag +++ b/src/mirrage/renderer/shader/blit.frag @@ -3,7 +3,7 @@ #extension GL_ARB_shading_language_420pack : enable #include "normal_encoding.glsl" -#include "color_conversion.glsl" +#include "color_conversion.glsl" #include "random.glsl" #include "global_uniforms.glsl" @@ -145,12 +145,12 @@ vec3 highlow_mix(vec3 color, float cutoff, vec3 low, vec3 high) { vec3 dither(vec3 color) { vec3 color_srgb = highlow_mix(color, 0.0031308, 12.92*color, 1.055*pow(color, vec3(1.0/2.4))-0.055); - vec3 rand = texture(blue_noise, vertex_out.tex_coords*vec2(1920,1080)/128.0).rgb; + vec3 rand = texelFetch(blue_noise, ivec2(mod(vertex_out.tex_coords*textureSize(color_sampler,0), textureSize(blue_noise,0))), 0).rgb; vec3 rand_tri = rand*2.0-1.0; rand_tri = sign(rand_tri) * (1.0-sqrt(1.0-abs(rand_tri))); - color_srgb += rand / 253.0; + color_srgb += rand / 250.0; return highlow_mix(color_srgb, 0.04045, color_srgb/12.92, pow(color_srgb/1.055 + 0.055/1.055, vec3(2.4))); } diff --git a/assets/core_assets/shader/bloom_apply.frag b/src/mirrage/renderer/shader/bloom_apply.frag similarity index 100% rename from assets/core_assets/shader/bloom_apply.frag rename to src/mirrage/renderer/shader/bloom_apply.frag diff --git a/assets/core_assets/shader/bloom_blur.frag b/src/mirrage/renderer/shader/bloom_blur.frag similarity index 100% rename from assets/core_assets/shader/bloom_blur.frag rename to src/mirrage/renderer/shader/bloom_blur.frag diff --git a/assets/core_assets/shader/bloom_blur.vert b/src/mirrage/renderer/shader/bloom_blur.vert similarity index 100% rename from assets/core_assets/shader/bloom_blur.vert rename to src/mirrage/renderer/shader/bloom_blur.vert diff --git a/assets/core_assets/shader/brdf.glsl b/src/mirrage/renderer/shader/brdf.glsl similarity index 82% rename from assets/core_assets/shader/brdf.glsl rename to src/mirrage/renderer/shader/brdf.glsl index bd28f04f0d7f669a26ea6cbdcdac8a1c690c61d0..189ef0a31411193a74a16988cf811de5f2c6f386 100644 --- a/assets/core_assets/shader/brdf.glsl +++ b/src/mirrage/renderer/shader/brdf.glsl @@ -37,7 +37,7 @@ vec3 fresnelSchlick(float cosTheta, vec3 F0) { return F0 + (1.0 - F0) * pow(1.0 - cosTheta, 5.0); } -vec3 brdf(vec3 albedo, vec3 F0, float roughness, vec3 N, vec3 V, vec3 L, vec3 radiance, out vec3 diffuse) { +vec3 brdf_without_NdotL(vec3 albedo, vec3 F0, float roughness, vec3 N, vec3 V, vec3 L, vec3 radiance, out vec3 diffuse) { const float PI = 3.14159265359; vec3 H = normalize(V+L); @@ -53,9 +53,12 @@ vec3 brdf(vec3 albedo, vec3 F0, float roughness, vec3 N, vec3 V, vec3 L, vec3 ra float denominator = 4 * max(dot(N, V), 0.0) * max(dot(N, L), 0.0) + 0.001; vec3 brdf = nominator / denominator; - // add to outgoing radiance Lo - float NdotL = max(dot(N, L), 0.0); + diffuse = kD * albedo / PI * radiance; + return (kD * albedo / PI + brdf) * radiance; +} - diffuse = kD * albedo / PI * radiance * NdotL; - return (kD * albedo / PI + brdf) * radiance * NdotL; +vec3 brdf(vec3 albedo, vec3 F0, float roughness, vec3 N, vec3 V, vec3 L, vec3 radiance, out vec3 diffuse) { + float NdotL = max(dot(N, L), 0.0); + radiance *= NdotL; + return brdf_without_NdotL(albedo, F0, roughness, N, V, L, radiance, diffuse); } diff --git a/assets/core_assets/shader/color_conversion.glsl b/src/mirrage/renderer/shader/color_conversion.glsl similarity index 100% rename from assets/core_assets/shader/color_conversion.glsl rename to src/mirrage/renderer/shader/color_conversion.glsl diff --git a/assets/core_assets/shader/debug_draw.frag b/src/mirrage/renderer/shader/debug_draw.frag similarity index 100% rename from assets/core_assets/shader/debug_draw.frag rename to src/mirrage/renderer/shader/debug_draw.frag diff --git a/assets/core_assets/shader/debug_draw.vert b/src/mirrage/renderer/shader/debug_draw.vert similarity index 100% rename from assets/core_assets/shader/debug_draw.vert rename to src/mirrage/renderer/shader/debug_draw.vert diff --git a/src/mirrage/renderer/shader/decal.frag b/src/mirrage/renderer/shader/decal.frag new file mode 100644 index 0000000000000000000000000000000000000000..6aa02b2c194313ba5cc767ff8bbf921fdd112da4 --- /dev/null +++ b/src/mirrage/renderer/shader/decal.frag @@ -0,0 +1,116 @@ +#version 450 +#extension GL_ARB_separate_shader_objects : enable +#extension GL_ARB_shading_language_420pack : enable + +#include "global_uniforms.glsl" +#include "normal_encoding.glsl" + +layout(location = 0) in vec3 view_pos; +layout(location = 1) in vec4 ndc_pos; + + +layout(location = 0) out vec4 albedo_mat_id_out; +layout(location = 1) out vec4 mat_data_out; +layout(location = 2) out vec4 color_out; +layout(location = 3) out vec4 color_diffuse_out; + +layout(set=1, binding = 0) uniform sampler2D albedo_sampler; +layout(set=1, binding = 1) uniform sampler2D normal_sampler; +layout(set=1, binding = 2) uniform sampler2D brdf_sampler; +layout(set=1, binding = 3) uniform sampler2D emission_sampler; + +layout(input_attachment_index = 0, set=2, binding = 0) uniform subpassInput depth_sampler; + + +layout(push_constant) uniform Per_model_uniforms { + mat4 model_to_view; + mat4 view_to_model; +} model_uniforms; + +const float PI = 3.14159265359; + + +vec3 decode_tangent_normal(vec2 tn); +vec3 tangent_space_to_world(vec3 N, vec3 p_dx, vec3 p_dy, vec2 tc_dx, vec2 tc_dy); + +void main() { + vec2 screen_tex_coords = ndc_pos.xy/ndc_pos.w /2.0 +0.5; + + vec4 clip_rect = vec4(unpackSnorm2x16(floatBitsToUint(model_uniforms.model_to_view[0][3])), + unpackSnorm2x16(floatBitsToUint(model_uniforms.model_to_view[1][3])))*10.0; + vec4 color = vec4(unpackUnorm2x16(floatBitsToUint(model_uniforms.model_to_view[2][3])), + unpackUnorm2x16(floatBitsToUint(model_uniforms.model_to_view[3][3]))); + + vec4 emissive_color = vec4(model_uniforms.view_to_model[0][3], model_uniforms.view_to_model[1][3], + model_uniforms.view_to_model[2][3], model_uniforms.view_to_model[3][3]); + + mat4 view_to_model = model_uniforms.view_to_model; + view_to_model[0][3] = 0; + view_to_model[1][3] = 0; + view_to_model[2][3] = 0; + view_to_model[3][3] = 1; + + float depth = subpassLoad(depth_sampler).r; + vec3 position = position_from_ldepth(screen_tex_coords, depth); + vec4 decal_pos = view_to_model * vec4(position, 1.0); + decal_pos /= decal_pos.w; + decal_pos.xyz += 0.5; + + vec2 tex_coords = clip_rect.xy + decal_pos.xy*clip_rect.zw; + tex_coords.y = 1.0-tex_coords.y; + + vec3 p_dx = dFdx(position); + vec3 p_dy = dFdy(position); + + vec2 tc_dx = dFdx(tex_coords); + vec2 tc_dy = dFdy(tex_coords); + + if(decal_pos.x<0 || decal_pos.y<0 || decal_pos.z<0 || decal_pos.x>1 || decal_pos.y>1 || decal_pos.z>1) { + discard; + } + + vec4 albedo = texture(albedo_sampler, tex_coords); + if(albedo.a<0.05) + discard; + + albedo *= color; + albedo.rgb *= albedo.a; + + vec3 N = tangent_space_to_world(decode_tangent_normal(texture(normal_sampler, tex_coords).rg), p_dx, p_dy, tc_dx, tc_dy); + vec4 brdf = texture(brdf_sampler, tex_coords); + float roughness = brdf.r; + float metallic = brdf.g; + roughness = mix(0.01, 0.99, roughness*roughness); + + float emissive_power = texture(emission_sampler, tex_coords).r; + + albedo_mat_id_out = albedo; + mat_data_out = vec4(encode_normal(N), roughness, metallic); + color_out = vec4(albedo.rgb * emissive_color.rgb + * emissive_power * emissive_color.a * albedo.a, albedo.a); + color_diffuse_out = color_out; +} + +vec3 decode_tangent_normal(vec2 tn) { + if(dot(tn,tn)<0.00001) + return vec3(0,0,1); + + vec3 N = vec3(tn*2-1, 0); + N.z = sqrt(1 - dot(N.xy, N.xy)); + return N; +} + +vec3 tangent_space_to_world(vec3 N, vec3 p_dx, vec3 p_dy, vec2 tc_dx, vec2 tc_dy) { + // calculate tangent + vec3 VN = -normalize(cross(p_dx, p_dy)); + + vec3 p_dy_N = cross(p_dy, VN); + vec3 p_dx_N = cross(VN, p_dx); + + vec3 T = p_dy_N * tc_dx.x + p_dx_N * tc_dy.x; + vec3 B = p_dy_N * tc_dx.y + p_dx_N * tc_dy.y; + + float inv_max = inversesqrt(max(dot(T,T), dot(B,B))); + mat3 TBN = mat3(T*inv_max, B*inv_max, VN); + return normalize(TBN * N); +} diff --git a/src/mirrage/renderer/shader/decal.vert b/src/mirrage/renderer/shader/decal.vert new file mode 100644 index 0000000000000000000000000000000000000000..1be9266e2970af12960da77a47709489326a11d8 --- /dev/null +++ b/src/mirrage/renderer/shader/decal.vert @@ -0,0 +1,52 @@ +#version 450 +#extension GL_ARB_separate_shader_objects : enable +#extension GL_ARB_shading_language_420pack : enable + +#include "global_uniforms.glsl" + + +layout(location = 0) out vec3 out_view_pos; +layout(location = 1) out vec4 out_ndc_pos; + +layout(push_constant) uniform Per_model_uniforms { + mat4 model_to_view; + mat4 view_to_model; +} model_uniforms; + +out gl_PerVertex { + vec4 gl_Position; +}; + +const vec3 vertex_positions[14] = vec3[]( + vec3(-1.f, 1.f, 1.f), + vec3(1.f, 1.f, 1.f), + vec3(-1.f, -1.f, 1.f), + vec3(1.f, -1.f, 1.f), + vec3(1.f, -1.f, -1.f), + vec3(1.f, 1.f, 1.f), + vec3(1.f, 1.f, -1.f), + vec3(-1.f, 1.f, 1.f), + vec3(-1.f, 1.f, -1.f), + vec3(-1.f, -1.f, 1.f), + vec3(-1.f, -1.f, -1.f), + vec3(1.f, -1.f, -1.f), + vec3(-1.f, 1.f, -1.f), + vec3(1.f, 1.f, -1.f) +); + +void main() { + vec3 p = vertex_positions[gl_VertexIndex]; + + mat4 model_to_view = model_uniforms.model_to_view; + model_to_view[0][3] = 0; + model_to_view[1][3] = 0; + model_to_view[2][3] = 0; + model_to_view[3][3] = 1; + + vec4 view_pos = model_to_view * vec4(p*0.5, 1.0); + + out_view_pos = view_pos.xyz / view_pos.w; + vec4 ndc_pos = global_uniforms.proj_mat * view_pos; + gl_Position = ndc_pos; + out_ndc_pos = ndc_pos; +} diff --git a/src/mirrage/renderer/shader/depth_of_field_apply.frag b/src/mirrage/renderer/shader/depth_of_field_apply.frag new file mode 100644 index 0000000000000000000000000000000000000000..36f23f5ed99d566a6ab0576731103c9a4bb9cc5c --- /dev/null +++ b/src/mirrage/renderer/shader/depth_of_field_apply.frag @@ -0,0 +1,20 @@ +#version 450 +#extension GL_ARB_separate_shader_objects : enable +#extension GL_ARB_shading_language_420pack : enable + +#include "global_uniforms.glsl" + +layout(location = 0) in Vertex_data { + vec2 tex_coords; +} vertex_out; + +layout(location = 0) out vec4 out_color; + +layout(set=1, binding = 0) uniform sampler2D color_sampler; +layout(set=1, binding = 1) uniform sampler2D dof_sampler; + +void main() { + vec4 dof = textureLod(dof_sampler, vertex_out.tex_coords, 0); + vec3 color = textureLod(color_sampler, vertex_out.tex_coords, 0).rgb; + out_color = vec4(mix(color, dof.rgb, smoothstep(0.1, 2.0, dof.a)), 1.0); +} diff --git a/src/mirrage/renderer/shader/depth_of_field_calc.frag b/src/mirrage/renderer/shader/depth_of_field_calc.frag new file mode 100644 index 0000000000000000000000000000000000000000..4341fcf9ef631965f27cf4f562178827a3606713 --- /dev/null +++ b/src/mirrage/renderer/shader/depth_of_field_calc.frag @@ -0,0 +1,55 @@ +#version 450 +#extension GL_ARB_separate_shader_objects : enable +#extension GL_ARB_shading_language_420pack : enable + +#include "global_uniforms.glsl" +#include "random.glsl" + + +layout(location = 0) in Vertex_data { + vec2 tex_coords; +} vertex_out; + +layout(location = 0) out vec4 out_color; + +layout(set=1, binding = 0) uniform sampler2D color_sampler; + +layout (constant_id = 0) const float MAX_RADIUS = 15; +layout (constant_id = 1) const float RAD_SCALE = 0.7; + +layout(push_constant) uniform Push_constants { + // focus_distance, range, radius + vec4 parameters; +} pcs; + + +void main() { + vec4 center = textureLod(color_sampler, vertex_out.tex_coords, 0); + float center_coc = center.a; + float center_coc2 = abs(2.0 * center.a); + vec3 color = center.rgb; + float weight_sum = 1.0; + float coc_sum = abs(center_coc); + + vec2 texel_size = 1.0 / textureSize(color_sampler, 0); + + float radius = RAD_SCALE; + for (float ang = 0; radius center_coc) + sample_data.a = min(coc, center_coc2); + + float m = smoothstep(radius-0.5, radius+0.5, coc); + color += mix(color/weight_sum, sample_data.rgb, m); + coc_sum += mix(coc_sum/weight_sum, coc, m); + weight_sum += 1.0; + radius += RAD_SCALE/radius; + } + + + out_color = vec4(color/weight_sum, coc_sum/weight_sum); +} diff --git a/src/mirrage/renderer/shader/depth_of_field_coc.frag b/src/mirrage/renderer/shader/depth_of_field_coc.frag new file mode 100644 index 0000000000000000000000000000000000000000..e22615dd78a381da6df7639a7af2173bca671a22 --- /dev/null +++ b/src/mirrage/renderer/shader/depth_of_field_coc.frag @@ -0,0 +1,58 @@ +#version 450 +#extension GL_ARB_separate_shader_objects : enable +#extension GL_ARB_shading_language_420pack : enable + +#include "global_uniforms.glsl" + +layout(location = 0) in Vertex_data { + vec2 tex_coords; +} vertex_out; + +layout(location = 0) out vec4 out_color; + +layout(set=1, binding = 0) uniform sampler2D color_sampler; +layout(set=1, binding = 1) uniform sampler2D depth_sampler; + +layout (constant_id = 0) const float MAX_RADIUS = 15; +layout (constant_id = 1) const float RAD_SCALE = 0.5; + +layout(push_constant) uniform Push_constants { + // focus_distance, range, radius + vec4 parameters; + mat4 depth_reprojection; +} pcs; + + +float calc_coc(float dist) { + const float focus_distance = pcs.parameters[0]; + const float range = pcs.parameters[1]; + const float radius = pcs.parameters[2]; + + float coc = (dist - focus_distance) / dist / range; + if(coc<0) + coc *= 2.0; + + return MAX_RADIUS * radius * clamp(coc, -1.0, 1.0); +} + +void main() { + vec4 red = textureGather(color_sampler, vertex_out.tex_coords, 0); + vec4 green = textureGather(color_sampler, vertex_out.tex_coords, 1); + vec4 blue = textureGather(color_sampler, vertex_out.tex_coords, 2); + + vec3 color = vec3( + max(red[0], max(red[1], max(red[2], red[3]))), + max(green[0], max(green[1], max(green[2], green[3]))), + max(blue[0], max(blue[1], max(blue[2], blue[3]))) + ); + + vec4 depth_uv = pcs.depth_reprojection * vec4(vertex_out.tex_coords*2-1, 0.5, 1); + depth_uv.xy = (depth_uv.xy/depth_uv.w)*0.5+0.5; + + vec4 depth = textureGather(depth_sampler, depth_uv.xy, 0); + vec4 dist = depth * global_uniforms.proj_planes[1]; + + float coc = calc_coc(dot(vec4(1.0), dist)/4.0); + + out_color = vec4(color, coc); +} diff --git a/assets/core_assets/shader/fullscreen.vert b/src/mirrage/renderer/shader/fullscreen.vert similarity index 100% rename from assets/core_assets/shader/fullscreen.vert rename to src/mirrage/renderer/shader/fullscreen.vert diff --git a/assets/core_assets/shader/gi_blend.frag b/src/mirrage/renderer/shader/gi_blend.frag similarity index 85% rename from assets/core_assets/shader/gi_blend.frag rename to src/mirrage/renderer/shader/gi_blend.frag index d8aeeb17f190a97715da95b6ac5812e16be39a7b..c2fc726d4237381d99b0c3e87c5eab72b3695b6b 100644 --- a/assets/core_assets/shader/gi_blend.frag +++ b/src/mirrage/renderer/shader/gi_blend.frag @@ -41,8 +41,16 @@ void main() { out_color.rgb = texture(result_spec_sampler, vertex_out.tex_coords).rgb; out_color.a = 1; - } else if(pcs.prev_projection[2][3]>=1) { - out_color.rgb = textureLod(result_diff_sampler, vertex_out.tex_coords, pcs.prev_projection[2][3]-1).rgb; + } else if(pcs.prev_projection[2][3]==1) { + out_color.rgb = specular; + out_color.a = 1; + + } else if(pcs.prev_projection[2][3]==2) { + out_color.rgb = radiance; + out_color.a = 1; + + } else if(pcs.prev_projection[2][3]>=3) { + out_color.rgb = textureLod(result_diff_sampler, vertex_out.tex_coords, pcs.prev_projection[2][3]-3).rgb; out_color.a = 1; } diff --git a/assets/core_assets/shader/gi_blend_common.glsl b/src/mirrage/renderer/shader/gi_blend_common.glsl similarity index 100% rename from assets/core_assets/shader/gi_blend_common.glsl rename to src/mirrage/renderer/shader/gi_blend_common.glsl diff --git a/assets/core_assets/shader/gi_diffuse_reproject.frag b/src/mirrage/renderer/shader/gi_diffuse_reproject.frag similarity index 100% rename from assets/core_assets/shader/gi_diffuse_reproject.frag rename to src/mirrage/renderer/shader/gi_diffuse_reproject.frag diff --git a/assets/core_assets/shader/gi_integrate_brdf.frag b/src/mirrage/renderer/shader/gi_integrate_brdf.frag similarity index 100% rename from assets/core_assets/shader/gi_integrate_brdf.frag rename to src/mirrage/renderer/shader/gi_integrate_brdf.frag diff --git a/assets/core_assets/shader/gi_integrate_brdf.vert b/src/mirrage/renderer/shader/gi_integrate_brdf.vert similarity index 100% rename from assets/core_assets/shader/gi_integrate_brdf.vert rename to src/mirrage/renderer/shader/gi_integrate_brdf.vert diff --git a/assets/core_assets/shader/gi_mipgen.frag b/src/mirrage/renderer/shader/gi_mipgen.frag similarity index 100% rename from assets/core_assets/shader/gi_mipgen.frag rename to src/mirrage/renderer/shader/gi_mipgen.frag diff --git a/assets/core_assets/shader/gi_reproject.frag b/src/mirrage/renderer/shader/gi_reproject.frag similarity index 100% rename from assets/core_assets/shader/gi_reproject.frag rename to src/mirrage/renderer/shader/gi_reproject.frag diff --git a/assets/core_assets/shader/gi_reprojection_weights.frag b/src/mirrage/renderer/shader/gi_reprojection_weights.frag similarity index 100% rename from assets/core_assets/shader/gi_reprojection_weights.frag rename to src/mirrage/renderer/shader/gi_reprojection_weights.frag diff --git a/assets/core_assets/shader/gi_sample.frag b/src/mirrage/renderer/shader/gi_sample.frag similarity index 93% rename from assets/core_assets/shader/gi_sample.frag rename to src/mirrage/renderer/shader/gi_sample.frag index b5b90a03534652cf5f2549eb601204d9cce05fae..90eeda740250f494cd09a31464eb59a40f5d05e5 100644 --- a/assets/core_assets/shader/gi_sample.frag +++ b/src/mirrage/renderer/shader/gi_sample.frag @@ -87,8 +87,8 @@ vec3 gi_sample(int lod, int base_mip) { ivec2 uv = ivec2(vertex_out.tex_coords * texture_size); // clamp area to reduce artefacts around borders - if(uv.x<=0 || uv.y<=0 || uv.y >= texture_size.y-1 || uv.x >= texture_size.x-1) - return vec3(0, 0, 0); +// if(uv.x<=0 || uv.y<=0 || uv.y >= texture_size.y-1 || uv.x >= texture_size.x-1) +// return vec3(0, 0, 0); // fetch the depth/normal of the target pixel and reconstruct its view-space position float depth = texelFetch(depth_sampler, uv, 0).r; @@ -99,9 +99,11 @@ vec3 gi_sample(int lod, int base_mip) { // fetch SAMPLES samples in a spiral pattern and combine their GI contribution vec3 c = vec3(0,0,0); - float angle = random(vec4(vertex_out.tex_coords, lod, global_uniforms.time.w)).r * 2*PI; + float angle = texelFetch(noise_sampler, ivec2(mod(vertex_out.tex_coords*textureSize(color_sampler,0),textureSize(noise_sampler,0))), 0).r; + angle = mod(angle+2.6180339887*int(global_uniforms.time.w), 1.0); + angle *= 2*PI; - float outer_radius = R+2.0; + float outer_radius = R+1.0; float inner_radius = LAST_SAMPLE==0 ? outer_radius / 2.0 : 2.0; float angle_step = 2.39996;// PI * 2.0 / pow((sqrt(5.0) + 1.0) / 2.0, 2.0); @@ -114,8 +116,8 @@ vec3 gi_sample(int lod, int base_mip) { for(int i=0; i noise + // read diffuse color, modulate with median if equal to min/max of neighborhood => noise ivec2 result_sampler_size = textureSize(result_sampler, 0).xy; ivec2 uv = ivec2(result_sampler_size * vertex_out.tex_coords); @@ -95,26 +95,12 @@ void main() { texelFetchOffset(result_sampler, uv, 0, ivec2( 1, 1)).rgb ); - float min_c = pixel_intensity(colors[0]); - float max_c = min_c; - - for(int i=1; i<9; i++) { - float intensity = pixel_intensity(colors[i]); - min_c = min(min_c, intensity); - max_c = max(max_c, intensity); - } - - vec3 org = colors[4]; - float org_intensity = dot(org, org); - if(max_c>org_intensity) - out_color = vec4(org, 1.0); - else { - out_color = vec4(median_vec3(colors), 1.0); - } + out_color = vec4(median_vec3(colors), 1.0); // modulate diffuse GI by ambient occlusion if(INCLUDE_AO==1) { float ao = texture(ao_sampler, vertex_out.tex_coords).r * 0.75 + 0.25; + ao = mix(1.0, ao, pcs.projection[3][3]); out_color.rgb *= ao; for(int i=0; i<9; i++) colors[i] *= ao; diff --git a/assets/core_assets/shader/gi_sample_spec.frag b/src/mirrage/renderer/shader/gi_sample_spec.frag similarity index 92% rename from assets/core_assets/shader/gi_sample_spec.frag rename to src/mirrage/renderer/shader/gi_sample_spec.frag index 1db9597456f5cd4144c973459b4c6fc14a0e0a46..ececb280510c3e6cc5988fd2e1d8c4a57cbdad77 100644 --- a/assets/core_assets/shader/gi_sample_spec.frag +++ b/src/mirrage/renderer/shader/gi_sample_spec.frag @@ -80,6 +80,27 @@ vec3 sample_color_lod(float roughness, vec2 hit_uv, vec3 L, float coneTheta) { } void main() { + vec3 diffuse = textureLod(diffuse_sampler, vertex_out.tex_coords, pcs.prev_projection[0][3]).rgb/ (PI*PI*2); + + float history_weight = texelFetch(history_weight_sampler, + ivec2(vertex_out.tex_coords * textureSize(history_weight_sampler, 0)), + 0).r; + if(history_weight<=0) + history_weight = 0.0; + else if(history_weight>100) + history_weight = 1.0; + else + history_weight = 1.0-1.0/(1+history_weight); + + // blend to diffuse if history_weight is too high to avoid flicker + float diffuse_weight = smoothstep(0.9, 1.0, history_weight); + if(diffuse_weight>=1.0) { + out_color = vec4(diffuse,1); + return; + } + out_color.rgb = mix(diffuse, out_color.rgb, diffuse_weight); + + float startLod = pcs.prev_projection[0][3]; vec2 depthSize = textureSize(depth_sampler, int(startLod + 0.5)); @@ -134,21 +155,10 @@ void main() { out_color.rgb = max(color * factor_distance * factor_normal, vec3(0)); } else { - out_color.rgb = textureLod(diffuse_sampler, vertex_out.tex_coords, pcs.prev_projection[0][3]).rgb / (PI*PI*2); + out_color.rgb = diffuse; } - float history_weight = texelFetch(history_weight_sampler, - ivec2(vertex_out.tex_coords * textureSize(history_weight_sampler, 0)), - 0).r; - if(history_weight<=0) - history_weight = 0.0; - else if(history_weight>100) - history_weight = 1.0; - else - history_weight = 1.0-1.0/(1+history_weight); - out_color *= 1.0 - min(history_weight, 0.94); - out_color = max(out_color, vec4(0)); } diff --git a/assets/core_assets/shader/gi_sample_upsample.frag b/src/mirrage/renderer/shader/gi_sample_upsample.frag similarity index 100% rename from assets/core_assets/shader/gi_sample_upsample.frag rename to src/mirrage/renderer/shader/gi_sample_upsample.frag diff --git a/assets/core_assets/shader/gi_spec_blur.frag b/src/mirrage/renderer/shader/gi_spec_blur.frag similarity index 96% rename from assets/core_assets/shader/gi_spec_blur.frag rename to src/mirrage/renderer/shader/gi_spec_blur.frag index abd9b4c9aad72cf08e6b12ef0a5dbce9227c78e2..56f2ab68b036da3a03c110e60e92337f9646bbd4 100644 --- a/assets/core_assets/shader/gi_spec_blur.frag +++ b/src/mirrage/renderer/shader/gi_spec_blur.frag @@ -39,5 +39,5 @@ void main() { color_out = vec4(result / weight_sum, 1.0); - color_out.rgb = mix(color_out.rgb, center, 0.7); + color_out.rgb = mix(color_out.rgb, center, 0.6); } diff --git a/assets/core_assets/shader/gi_spec_blur.vert b/src/mirrage/renderer/shader/gi_spec_blur.vert similarity index 100% rename from assets/core_assets/shader/gi_spec_blur.vert rename to src/mirrage/renderer/shader/gi_spec_blur.vert diff --git a/assets/core_assets/shader/gi_weight_mipgen.frag b/src/mirrage/renderer/shader/gi_weight_mipgen.frag similarity index 100% rename from assets/core_assets/shader/gi_weight_mipgen.frag rename to src/mirrage/renderer/shader/gi_weight_mipgen.frag diff --git a/assets/core_assets/shader/global_uniforms.glsl b/src/mirrage/renderer/shader/global_uniforms.glsl similarity index 78% rename from assets/core_assets/shader/global_uniforms.glsl rename to src/mirrage/renderer/shader/global_uniforms.glsl index 58bd077525eb8ae30d82a79cefda5aa07de3d3b6..062fbf3fe1425398d65f7a34193f8a6e642d5a99 100644 --- a/assets/core_assets/shader/global_uniforms.glsl +++ b/src/mirrage/renderer/shader/global_uniforms.glsl @@ -1,7 +1,7 @@ #ifndef GLOBAL_UNIFORMS_INCLUDED #define GLOBAL_UNIFORMS_INCLUDED -layout(set=0, binding = 0) uniform Global_uniforms { +layout(std140, set=0, binding = 0) uniform Global_uniforms { mat4 view_proj_mat; mat4 view_mat; mat4 proj_mat; @@ -9,7 +9,7 @@ layout(set=0, binding = 0) uniform Global_uniforms { mat4 inv_proj_mat; vec4 eye_pos; vec4 proj_planes; //< near, far, fov horizontal, fov vertical - vec4 time; //< time, sin(time), delta_time, frame-number % 100.000 + vec4 time; //< time, sin(time), delta_time, frame-number % 20 vec4 proj_info; } global_uniforms; diff --git a/assets/core_assets/shader/light_directional.frag b/src/mirrage/renderer/shader/light_directional.frag similarity index 91% rename from assets/core_assets/shader/light_directional.frag rename to src/mirrage/renderer/shader/light_directional.frag index a94e050133aa1184a22e60abd0c72c5045f0a9df..5ba565e4ab3cb33a466a917f695ae72b9da56984 100644 --- a/assets/core_assets/shader/light_directional.frag +++ b/src/mirrage/renderer/shader/light_directional.frag @@ -32,6 +32,7 @@ layout(push_constant) uniform Per_model_uniforms { vec4 light_color; vec4 light_data; // R=src_radius, GBA=direction vec4 light_data2; // R=shadowmapID + vec4 shadow_color; } model_uniforms; @@ -47,6 +48,7 @@ void main() { vec3 position = position_from_ldepth(vertex_out.tex_coords, depth); vec3 V = -normalize(position); + vec3 L = model_uniforms.light_data.gba; vec3 albedo = albedo_mat_id.rgb; int material = int(albedo_mat_id.a*255); @@ -56,21 +58,26 @@ void main() { vec3 F0 = mix(vec3(0.04), albedo.rgb, metallic); albedo.rgb *= 1.0 - metallic; - vec3 radiance = model_uniforms.light_color.rgb * model_uniforms.light_color.a; + vec3 radiance = model_uniforms.light_color.rgb * model_uniforms.light_color.a; float shadow = sample_shadowmap(position + N*0.06); + float NdotL = max(dot(N, L), 0.0); + vec3 shadow_radiance = model_uniforms.shadow_color.rgb * model_uniforms.shadow_color.a; - out_color = vec4(0,0,0,0); - out_color_diff = vec4(0,0,0,0); + out_color = vec4(0,0,0,1.0); + out_color_diff = vec4(0,0,0,1.0); - if(shadow>0.0) { - vec3 L = model_uniforms.light_data.gba; + shadow *= NdotL; + if(shadow>0.0) { vec3 diffuse; - out_color = vec4(brdf(albedo, F0, roughness, N, V, L, radiance, diffuse) * shadow, 1.0); + out_color = vec4(brdf_without_NdotL(albedo, F0, roughness, N, V, L, radiance, diffuse) * shadow, 1.0); out_color_diff = vec4(diffuse * shadow, 1.0); } + + out_color.rgb += shadow_radiance * albedo / PI * (1.0 - shadow); + out_color_diff.rgb += shadow_radiance * albedo / PI * (1.0 - shadow); } diff --git a/assets/core_assets/shader/light_point.frag b/src/mirrage/renderer/shader/light_point.frag similarity index 100% rename from assets/core_assets/shader/light_point.frag rename to src/mirrage/renderer/shader/light_point.frag diff --git a/assets/core_assets/shader/light_point.vert b/src/mirrage/renderer/shader/light_point.vert similarity index 100% rename from assets/core_assets/shader/light_point.vert rename to src/mirrage/renderer/shader/light_point.vert diff --git a/assets/core_assets/shader/luminance.frag b/src/mirrage/renderer/shader/luminance.frag similarity index 100% rename from assets/core_assets/shader/luminance.frag rename to src/mirrage/renderer/shader/luminance.frag diff --git a/assets/core_assets/shader/luminance_adapt.frag b/src/mirrage/renderer/shader/luminance_adapt.frag similarity index 100% rename from assets/core_assets/shader/luminance_adapt.frag rename to src/mirrage/renderer/shader/luminance_adapt.frag diff --git a/assets/core_assets/shader/median.glsl b/src/mirrage/renderer/shader/median.glsl similarity index 100% rename from assets/core_assets/shader/median.glsl rename to src/mirrage/renderer/shader/median.glsl diff --git a/src/mirrage/renderer/shader/median_filter.frag b/src/mirrage/renderer/shader/median_filter.frag new file mode 100644 index 0000000000000000000000000000000000000000..5f3f2aa3fde4c112e28e58c8d79372d24e9b07f1 --- /dev/null +++ b/src/mirrage/renderer/shader/median_filter.frag @@ -0,0 +1,38 @@ +#version 450 +#extension GL_ARB_separate_shader_objects : enable +#extension GL_ARB_shading_language_420pack : enable + +#include "median.glsl" + +layout(location = 0) in Vertex_data { + vec2 tex_coords; +} vertex_out; + +layout(location = 0) out vec4 out_color; + +layout(set=1, binding = 0) uniform sampler2D color_sampler; + +void main() { + ivec2 color_sampler_size = textureSize(color_sampler, 0).xy; + ivec2 uv = ivec2(color_sampler_size * vertex_out.tex_coords); + + if(uv.x<=1 || uv.y<=1 || uv.x>=color_sampler_size.x-2 || uv.y>=color_sampler_size.y-2) { + out_color = vec4(texelFetch(color_sampler, uv, 0).rgb, 1); + return; + } + + vec3 colors[9] = vec3[]( + texelFetchOffset(color_sampler, uv, 0, ivec2(-1,-1)).rgb, + texelFetchOffset(color_sampler, uv, 0, ivec2(-1, 0)).rgb, + texelFetchOffset(color_sampler, uv, 0, ivec2( 0,-1)).rgb, + texelFetchOffset(color_sampler, uv, 0, ivec2( 0, 1)).rgb, + texelFetchOffset(color_sampler, uv, 0, ivec2( 0, 0)).rgb, + texelFetchOffset(color_sampler, uv, 0, ivec2( 1,-1)).rgb, + texelFetchOffset(color_sampler, uv, 0, ivec2(-1, 1)).rgb, + texelFetchOffset(color_sampler, uv, 0, ivec2( 1, 0)).rgb, + texelFetchOffset(color_sampler, uv, 0, ivec2( 1, 1)).rgb + ); + + vec3 org_c = colors[4]; + out_color = vec4(mix(org_c, median_vec3(colors), 0.9), 1.0); +} diff --git a/assets/core_assets/shader/model.frag b/src/mirrage/renderer/shader/model.frag similarity index 81% rename from assets/core_assets/shader/model.frag rename to src/mirrage/renderer/shader/model.frag index 0b8f61d739cafdb98e1881b8a61cb0ef4b0d684a..0708af543e7b3ed6b81622b8059a78b6fe4eb095 100644 --- a/assets/core_assets/shader/model.frag +++ b/src/mirrage/renderer/shader/model.frag @@ -15,11 +15,11 @@ layout(location = 2) in vec2 tex_coords; layout(location = 0) out vec4 depth_out; layout(location = 1) out vec4 albedo_mat_id_out; layout(location = 2) out vec4 mat_data_out; -layout(location = 3) out vec4 color_out; -layout(location = 4) out vec4 color_diffuse_out; layout(set=1, binding = 0) uniform sampler2D albedo_sampler; -layout(set=1, binding = 1) uniform sampler2D mat_data_sampler; +layout(set=1, binding = 1) uniform sampler2D normal_sampler; +layout(set=1, binding = 2) uniform sampler2D brdf_sampler; +layout(set=1, binding = 3) uniform sampler2D emission_sampler; layout(push_constant) uniform Per_model_uniforms { mat4 model; @@ -36,19 +36,16 @@ vec3 tangent_space_to_world(vec3 N); void main() { vec4 albedo = texture(albedo_sampler, tex_coords); - vec4 mat_data = texture(mat_data_sampler, tex_coords); - - vec3 N = tangent_space_to_world(decode_tangent_normal(mat_data.rg)); - - float roughness = mat_data.b; - float metallic = mat_data.a; + vec3 N = tangent_space_to_world(decode_tangent_normal(texture(normal_sampler, tex_coords).rg)); + vec4 brdf = texture(brdf_sampler, tex_coords); + float roughness = brdf.r; + float metallic = brdf.g; roughness = mix(0.01, 0.99, roughness*roughness); depth_out = vec4(-view_pos.z / global_uniforms.proj_planes.y, 0,0,1); albedo_mat_id_out = vec4(albedo.rgb, 0.0); mat_data_out = vec4(encode_normal(N), roughness, metallic); - color_diffuse_out = color_out = vec4(0,0,0,1); } vec3 decode_tangent_normal(vec2 tn) { diff --git a/assets/core_assets/shader/model.vert b/src/mirrage/renderer/shader/model.vert similarity index 100% rename from assets/core_assets/shader/model.vert rename to src/mirrage/renderer/shader/model.vert diff --git a/assets/core_assets/shader/model_alphatest.frag b/src/mirrage/renderer/shader/model_alphatest.frag similarity index 81% rename from assets/core_assets/shader/model_alphatest.frag rename to src/mirrage/renderer/shader/model_alphatest.frag index 08431333bcb5a61e3de30810e2b052fac546a181..c6d68ada21eb8ef4c02069c75ad740a0973a9eee 100644 --- a/assets/core_assets/shader/model_alphatest.frag +++ b/src/mirrage/renderer/shader/model_alphatest.frag @@ -13,11 +13,11 @@ layout(location = 2) in vec2 tex_coords; layout(location = 0) out vec4 depth_out; layout(location = 1) out vec4 albedo_mat_id_out; layout(location = 2) out vec4 mat_data_out; -layout(location = 3) out vec4 color_out; -layout(location = 4) out vec4 color_diffuse_out; layout(set=1, binding = 0) uniform sampler2D albedo_sampler; -layout(set=1, binding = 1) uniform sampler2D mat_data_sampler; +layout(set=1, binding = 1) uniform sampler2D normal_sampler; +layout(set=1, binding = 2) uniform sampler2D brdf_sampler; +layout(set=1, binding = 3) uniform sampler2D emission_sampler; layout(push_constant) uniform Per_model_uniforms { mat4 model; @@ -37,19 +37,16 @@ void main() { if(albedo.a < 0.1) discard; - vec4 mat_data = texture(mat_data_sampler, tex_coords); - - vec3 normal = tangent_space_to_world(decode_tangent_normal(mat_data.rg)); - - float roughness = mat_data.b; - float metallic = mat_data.a; + vec3 N = tangent_space_to_world(decode_tangent_normal(texture(normal_sampler, tex_coords).rg)); + vec4 brdf = texture(brdf_sampler, tex_coords); + float roughness = brdf.r; + float metallic = brdf.g; roughness = mix(0.01, 0.99, roughness*roughness); depth_out = vec4(-view_pos.z / global_uniforms.proj_planes.y, 0,0,1); albedo_mat_id_out = vec4(albedo.rgb, 0.0); mat_data_out = vec4(encode_normal(normal), roughness, metallic); - color_diffuse_out = color_out = vec4(0,0,0,1); } vec3 decode_tangent_normal(vec2 tn) { diff --git a/assets/core_assets/shader/model_animated.vert b/src/mirrage/renderer/shader/model_animated.vert similarity index 100% rename from assets/core_assets/shader/model_animated.vert rename to src/mirrage/renderer/shader/model_animated.vert diff --git a/assets/core_assets/shader/model_animated_dqs.vert b/src/mirrage/renderer/shader/model_animated_dqs.vert similarity index 100% rename from assets/core_assets/shader/model_animated_dqs.vert rename to src/mirrage/renderer/shader/model_animated_dqs.vert diff --git a/src/mirrage/renderer/shader/model_emissive.frag b/src/mirrage/renderer/shader/model_emissive.frag new file mode 100644 index 0000000000000000000000000000000000000000..62db7c30875b0ffacd2550f86ffd06fcea7519e4 --- /dev/null +++ b/src/mirrage/renderer/shader/model_emissive.frag @@ -0,0 +1,80 @@ +#version 450 +#extension GL_ARB_separate_shader_objects : enable +#extension GL_ARB_shading_language_420pack : enable + +#include "global_uniforms.glsl" +#include "normal_encoding.glsl" + +layout(early_fragment_tests) in; + +layout(location = 0) in vec3 view_pos; +layout(location = 1) in vec3 normal; +layout(location = 2) in vec2 tex_coords; + + +layout(location = 0) out vec4 color_out; +layout(location = 1) out vec4 color_diffuse_out; + +layout(set=1, binding = 0) uniform sampler2D albedo_sampler; +layout(set=1, binding = 1) uniform sampler2D normal_sampler; +layout(set=1, binding = 2) uniform sampler2D brdf_sampler; +layout(set=1, binding = 3) uniform sampler2D emission_sampler; + +layout(push_constant) uniform Per_model_uniforms { + mat4 model; + vec4 light_color; + vec4 material_properties; +} model_uniforms; + +const float PI = 3.14159265359; + + +vec3 decode_tangent_normal(vec2 tn); +vec3 tangent_space_to_world(vec3 N); + +void main() { + vec4 albedo = texture(albedo_sampler, tex_coords); + vec3 N = tangent_space_to_world(decode_tangent_normal(texture(normal_sampler, tex_coords).rg)); + + vec4 brdf = texture(brdf_sampler, tex_coords); + float roughness = brdf.r; + float metallic = brdf.g; + roughness = mix(0.01, 0.99, roughness*roughness); + + float emissive_power = texture(emission_sampler, tex_coords).r; + + color_out = vec4(albedo.rgb * model_uniforms.material_properties.rgb * emissive_power * model_uniforms.material_properties.a * albedo.a, 0.0); + color_diffuse_out = color_out; +} + + +vec3 decode_tangent_normal(vec2 tn) { + if(dot(tn,tn)<0.00001) + return vec3(0,0,1); + + vec3 N = vec3(tn*2-1, 0); + N.z = sqrt(1 - dot(N.xy, N.xy)); + return N; +} + +vec3 tangent_space_to_world(vec3 N) { + vec3 VN = normalize(normal); + + // calculate tangent + vec3 p_dx = dFdx(view_pos); + vec3 p_dy = dFdy(view_pos); + + vec2 tc_dx = dFdx(tex_coords); + vec2 tc_dy = dFdy(tex_coords); + + vec3 p_dy_N = cross(p_dy, VN); + vec3 p_dx_N = cross(VN, p_dx); + + vec3 T = p_dy_N * tc_dx.x + p_dx_N * tc_dy.x; + vec3 B = p_dy_N * tc_dx.y + p_dx_N * tc_dy.y; + + float inv_max = inversesqrt(max(dot(T,T), dot(B,B))); + mat3 TBN = mat3(T*inv_max, B*inv_max, VN); + return normalize(TBN * N); +} + diff --git a/assets/core_assets/shader/normal_encoding.glsl b/src/mirrage/renderer/shader/normal_encoding.glsl similarity index 100% rename from assets/core_assets/shader/normal_encoding.glsl rename to src/mirrage/renderer/shader/normal_encoding.glsl diff --git a/src/mirrage/renderer/shader/particle.vert b/src/mirrage/renderer/shader/particle.vert new file mode 100644 index 0000000000000000000000000000000000000000..aaecfb822b00c6f55de698be30d8a21ed7921258 --- /dev/null +++ b/src/mirrage/renderer/shader/particle.vert @@ -0,0 +1,39 @@ +#version 450 +#extension GL_ARB_separate_shader_objects : enable +#extension GL_ARB_shading_language_420pack : enable + +#include "particle/data_structures.glsl" + +layout(location = 0) in vec3 position; +layout(location = 1) in vec3 normal; +layout(location = 2) in vec2 tex_coords; + +layout(location = 3) in vec4 particle_position; +layout(location = 4) in vec4 particle_velocity; +layout(location = 5) in uvec4 particle_data; + +layout(location = 0) out vec4 out_view_pos; +layout(location = 1) out vec3 out_normal; +layout(location = 2) out vec2 out_tex_coords; +layout(location = 3) out vec4 out_particle_color; +layout(location = 4) out vec4 out_screen_pos; + +layout(std140, set=2, binding = 0) readonly buffer Particle_type_config { + PARTICLE_TYPE_CONFIG +} particle_config; + +layout(push_constant) uniform Per_model_uniforms { + mat4 model_to_view; + vec4 light_color; + vec4 options; +} model_uniforms; + +out gl_PerVertex { + vec4 gl_Position; +}; + +#include "particle.vert_base.glsl" + +void main() { + base_main(); +} diff --git a/src/mirrage/renderer/shader/particle.vert_base.glsl b/src/mirrage/renderer/shader/particle.vert_base.glsl new file mode 100644 index 0000000000000000000000000000000000000000..ae9f4670eaff782f1148ce94aa99fc6952d7e41b --- /dev/null +++ b/src/mirrage/renderer/shader/particle.vert_base.glsl @@ -0,0 +1,137 @@ + +#include "global_uniforms.glsl" +#include "color_conversion.glsl" + +vec3 calc_size(uint keyframe_a, uint keyframe_b, float t, vec3 rand) { + return mix(rand_xyz(particle_config.keyframes[keyframe_a].size, rand), + rand_xyz(particle_config.keyframes[keyframe_b].size, rand), + t); +} +vec4 calc_rotation(uint keyframe_a, uint keyframe_b, float t, vec3 rand) { + return normalize(mix(rand_quat(particle_config.keyframes[keyframe_a].rotation, rand), + rand_quat(particle_config.keyframes[keyframe_b].rotation, rand), + t)); +} +vec4 calc_color(uint keyframe_a, uint keyframe_b, float t, vec4 rand) { + return mix(rand_vec4(particle_config.keyframes[keyframe_a].color, rand), + rand_vec4(particle_config.keyframes[keyframe_b].color, rand), + t); +} + +void calc_random(uint seed, out vec3 rotation, out vec3 size, out vec4 color) { + vec2 uniform_rotation = uniform_rand(seed, 20, 21); + vec2 uniform_shared = uniform_rand(seed, 22, 23); + vec2 uniform_size = uniform_rand(seed, 24, 25); + vec4 uniform_color = vec4(uniform_rand(seed, 10, 11), uniform_rand(seed, 12, 13)); + + vec2 normal_rotation = uniform_to_normal_rand(uniform_rotation); + vec2 normal_shared = uniform_to_normal_rand(uniform_shared); + vec2 normal_size = uniform_to_normal_rand(uniform_size); + vec4 normal_color = vec4(uniform_to_normal_rand(uniform_color.xy), uniform_to_normal_rand(uniform_color.zw)); + + + color.x = (particle_config.normal_distribution_flags & 1)!=0 ? normal_color.x + : uniform_color.x*2-1; + color.y = (particle_config.normal_distribution_flags & 2)!=0 ? normal_color.y + : uniform_color.y*2-1; + color.z = (particle_config.normal_distribution_flags & 4)!=0 ? normal_color.z + : uniform_color.z*2-1; + color.w = (particle_config.normal_distribution_flags & 8)!=0 ? normal_color.w + : uniform_color.w*2-1; + + size.x = (particle_config.normal_distribution_flags & 16)!=0 ? normal_shared.y + : uniform_shared.y*2-1; + size.y = (particle_config.normal_distribution_flags & 32)!=0 ? normal_size.x + : uniform_size.x*2-1; + size.z = (particle_config.normal_distribution_flags & 64)!=0 ? normal_size.x + : uniform_size.x*2-1; + + rotation.x = (particle_config.normal_distribution_flags & 128)!=0 ? normal_rotation.x + : uniform_rotation.x*2-1; + rotation.y = (particle_config.normal_distribution_flags & 256)!=0 ? normal_rotation.y + : uniform_rotation.y*2-1; + rotation.z = (particle_config.normal_distribution_flags & 512)!=0 ? normal_shared.x + : uniform_shared.x*2-1; +} + +void base_main() { + uint seed = particle_data.y; + + vec3 rand_rotation; + vec3 rand_size; + vec4 rand_color; + calc_random(seed, rand_rotation, rand_size, rand_color); + + + uint keyframe_a = particle_data.z; + uint keyframe_b = min(keyframe_a+1, particle_config.keyframe_count-1); + float keyframe_t = uintBitsToFloat(particle_data.w); + + vec3 size = max(vec3(0,0,0), calc_size(keyframe_a, keyframe_b, keyframe_t, rand_size)); + if((particle_config.flags&4)!=0) + size.y = size.z = size.x; + + vec4 p = vec4(position * size, 1.0); + vec4 n = vec4(normal, 0.0); + + vec4 rotation = calc_rotation(keyframe_a, keyframe_b, keyframe_t, rand_rotation); + p.xyz = quaternion_rotate(p.xyz, rotation); + n.xyz = quaternion_rotate(n.xyz, rotation); + + uint rotate_with_velocity = particle_config.flags & 3; + + if(rotate_with_velocity==2) { + vec4 view_vel = (global_uniforms.view_mat * vec4(particle_velocity.xyz, 0.0)); + + float len_2d = length(view_vel.xy); + + if(len_2d >= 0.001) { + view_vel.xy = view_vel.xy / len_2d; + float angle = (view_vel.y<0? -1.0 : 1.0) * acos(view_vel.x); + angle -= 3.1415926*0.5; + + float sa = sin(angle); + float ca = cos(angle); + p.xy = vec2(p.x*ca - p.y*sa, p.x*sa + p.y*ca); + n.xy = vec2(n.x*ca - n.y*sa, n.x*sa + n.y*ca); + } + + } else if(rotate_with_velocity==1) { + vec3 dir = particle_velocity.xyz; + float dir_len = length(dir); + if(dir_len > 0) { + dir /= dir_len; + if(dir.y <= -1.0) { + p.xyz = vec3(-p.x, -p.y, p.z); + n.xyz = vec3(-n.x, -n.y, n.z); + } else if(dir.y < 1.0) { + vec3 my = normalize(dir); + vec3 mz = normalize(cross(my, vec3(0,1,0))); + vec3 mx = normalize(cross(my, mz)); + p.xyz = mat3(mx,my,mz) * p.xyz; + n.xyz = mat3(mx,my,mz) * n.xyz; + } + } + } + + + p = model_uniforms.model_to_view * p; + n = model_uniforms.model_to_view * n; + + vec4 view_pos = global_uniforms.view_mat * vec4(p.xyz + particle_position.xyz, 1.0); + + out_view_pos = view_pos; + out_normal = (global_uniforms.view_mat * n).xyz; + out_tex_coords = tex_coords; + vec4 clip_rect = particle_config.keyframes[keyframe_t<0.5 ? keyframe_a : keyframe_b].clip_rect; + out_tex_coords.y = 1-out_tex_coords.y; + out_tex_coords = clip_rect.xy + out_tex_coords * clip_rect.zw; + out_tex_coords.y = 1-out_tex_coords.y; + + vec4 color = calc_color(keyframe_a, keyframe_b, keyframe_t, rand_color);; + out_particle_color = vec4(hsv2rgb(color.xyz), color.a); + + vec4 screen_pos = global_uniforms.proj_mat * view_pos; + out_screen_pos = screen_pos; + gl_Position = screen_pos; +} diff --git a/src/mirrage/renderer/shader/particle/base_particle_script.glsl b/src/mirrage/renderer/shader/particle/base_particle_script.glsl new file mode 100644 index 0000000000000000000000000000000000000000..aaa52c18953c4ea2717a04cc4b6ee52de211badf --- /dev/null +++ b/src/mirrage/renderer/shader/particle/base_particle_script.glsl @@ -0,0 +1,29 @@ +#include "data_structures.glsl" + +layout(std140, set=0, binding = 0) readonly buffer Shared_uniforms { + int effector_count; + int global_effector_count; + + int padding2; + int padding3; + + Effector effectors[]; +} shared_uniforms; + +layout(std430, set=0, binding = 1) readonly buffer Particles_old { + Particle particles[]; +} pin; + +layout(std430, set=0, binding = 2) writeonly buffer Particles_new { + Particle particles[]; +} pout; + +layout(std430, set=0, binding = 3) buffer Feedback_buffer { + Emitter_particle_range ranges[]; +} feedback; + +layout(std430, set=0, binding = 4) buffer Feedback_mapping { + uint new_feedback_index[]; +} feedback_mapping; + +//layout(set=5, binding = 0) uniform sampler2D color_sampler; diff --git a/src/mirrage/renderer/shader/particle/data_structures.glsl b/src/mirrage/renderer/shader/particle/data_structures.glsl new file mode 100644 index 0000000000000000000000000000000000000000..a5e2e120c9eea778c571f85aa2e21310387cc146 --- /dev/null +++ b/src/mirrage/renderer/shader/particle/data_structures.glsl @@ -0,0 +1,143 @@ +#include "../random.glsl" + +vec3 quaternion_rotate(vec3 v, vec4 q) { + return v + 2.0 * cross(cross(v, q.xyz ) + q.w*v, q.xyz); +} + +struct Random_vec4 { + vec4 mean; + vec4 stddev; +}; +struct Random_float { + float mean; + float stddev; + // padded to vec4 if used as std140 +}; + +vec2 uniform_to_normal_rand(vec2 rand) { + float x = 6.28318530718 * rand[1]; + return sqrt(-2.0*log(rand[0])) * vec2(cos(x),sin(x)); +} +// 0-1 +float uniform_rand(uint seed, uint i) { + return floatConstruct(hash(uvec2(seed, i))); +} +vec2 uniform_rand(uint seed, uint i, uint j) { + return vec2(uniform_rand(seed, i), uniform_rand(seed, j)); +} + +vec2 normal_rand(uint seed, uint i, uint j) { + return uniform_to_normal_rand(uniform_rand(seed, i, j)); +} + +float rand_float(Random_float range, float rand) { + return range.mean + range.stddev*rand; +} +vec4 rand_vec4(Random_vec4 range, vec4 rand) { + return range.mean + range.stddev*rand; +} +vec3 rand_xyz(Random_vec4 range, vec3 rand) { + return range.mean.xyz + range.stddev.xyz*rand; +} +vec4 rand_quat(Random_vec4 range, vec3 rand) { + range.mean *= vec4(0.5, 1, 1, 1) * 2 * 3.14159265359; + range.stddev *= vec4(0.5, 1, 1, 1) * 2 * 3.14159265359; + + vec2 angles = range.mean.xy + range.stddev.xy * rand.xy; + angles.y += 3.14159265359 * 0.5; + vec3 axis = vec3(cos(angles.x)*cos(angles.y), + cos(angles.x)*sin(angles.y), + sin(angles.x)).xzy; + + float angle = range.mean.z + range.stddev.z * rand.z; + float half_angle = angle/2.0; + float sha = sin(half_angle); + + return vec4(axis * sha, cos(half_angle)); +} +vec3 rand_dir(vec2 mean_angles, vec2 stddev_angles, vec2 rand) { + vec2 rot = stddev_angles * rand*3.14159265359; + vec3 rand_dir = vec3(cos(rot.x)*cos(rot.y), + cos(rot.x)*sin(rot.y), + sin(rot.x)).xzy; + + vec3 base_dir = vec3(cos(mean_angles.x)*cos(mean_angles.y), + cos(mean_angles.x)*sin(mean_angles.y), + sin(mean_angles.x)).xzy; + + if(base_dir.x <= -1.0) { + rand_dir = vec3(-1, -1, 1) * rand_dir; + + } else if(base_dir.x < 1.0) { + vec3 mx = normalize(base_dir); + vec3 mz = normalize(cross(mx, vec3(1,0,0))); + vec3 my = normalize(cross(mx, mz)); + rand_dir = mat3(mx,my,mz) * rand_dir; + } + + return rand_dir; +} + + +struct Effector { + vec4 force_dir; // w=padding + vec4 position; // w=padding + + float force; + float distance_decay; + float mass_scale; // used as a=mix(F/m, F, mass_scale) + float negative_mass_scale; +}; + +struct Particle { + vec4 position; // xyz + ttl_left + vec4 velocity; // xyz + ttl_initial + uvec4 data; // last_feedback_buffer_index, seed, keyframe, floatBitsToUint(keyframe_interpolation_factor) + // seed: 0=ttl, 1=velocity, 2+3=direction, 4+5=vel_direction, 6...=position + // 10-13=color + // 20-22=rotation, 23-25=size +}; + +struct Emitter_particle_range { + int offset; + int count; +}; + +struct Particle_keyframe { + Random_vec4 color; // hsv + alpha + Random_vec4 rotation; // elevation, azimuth, angle + Random_vec4 size; // xyz + + vec4 clip_rect; + + float time; + float base_mass; + float density; + float drag; +}; + + +/* + normal_distribution_flags: + 1 << 0 = 1 : color[0] normal/uniform + 1 << 1 = 2 : color[1] normal/uniform + 1 << 2 = 4 : color[2] normal/uniform + 1 << 3 = 8 : color[3] normal/uniform + 1 << 4 = 16 : rotation[0] normal/uniform + 1 << 5 = 32 : rotation[1] normal/uniform + 1 << 6 = 64 : rotation[2] normal/uniform + 1 << 7 = 128 : size[0] normal/uniform + 1 << 8 = 256 : size[1] normal/uniform + 1 << 9 = 512 : size[2] normal/uniform + + flags: + 0b011: rotate_with_velocity + 0b100: symmetric_scaling +*/ +#define PARTICLE_TYPE_CONFIG \ + uint normal_distribution_flags;\ + uint flags; \ + float loop_keyframe_time; \ + uint keyframe_count; \ + Particle_keyframe[] keyframes; + diff --git a/src/mirrage/renderer/shader/particle/spawn_sphere.comp b/src/mirrage/renderer/shader/particle/spawn_sphere.comp new file mode 100644 index 0000000000000000000000000000000000000000..62bb4dba70da87b6a152848a5e1e176bd3b8c8ca --- /dev/null +++ b/src/mirrage/renderer/shader/particle/spawn_sphere.comp @@ -0,0 +1,74 @@ +#version 450 +#extension GL_ARB_separate_shader_objects : enable + +#include "base_particle_script.glsl" + +layout (local_size_x = 32, local_size_y = 1, local_size_z = 1 ) in; + +layout(push_constant) uniform Push_constants { + vec4 parent_velocity; + vec4 position; + vec4 rotation_quat; + Random_vec4 direction; + + vec2 size; + + Random_float ttl; + Random_float velocity; + + uint direction_flags; // 0x1 : independent; 0x2 : normal distribution + + uint offset; + uint to_spawn; + uint base_seed; + uint feedback_buffer_id; + float timestep; +} emitter_cfg; + +void main() { + uint invId = gl_GlobalInvocationID.x; + + if(invId < emitter_cfg.to_spawn) { + uint index = emitter_cfg.offset + invId; + + uint seed = hash(uvec2(emitter_cfg.base_seed, index)); + vec2 r01 = normal_rand(seed, 0, 1); + + float rand_ttl = rand_float(emitter_cfg.ttl, r01[0]); + float rand_vel = rand_float(emitter_cfg.velocity, r01[1])*0.5 + 0.5; + + pout.particles[index].position.w = rand_ttl; + pout.particles[index].velocity.w = rand_ttl; + pout.particles[index].data = uvec4(emitter_cfg.feedback_buffer_id, seed, 0, floatBitsToUint(0)); + + vec2 dir_mean_factor = vec2(0.5*3.14159265359, 2.0*3.14159265359); + + bool dir_normal_distr = (emitter_cfg.direction_flags & 2) != 0; + vec2 r23 = dir_normal_distr ? normal_rand(seed, 2, 3) : uniform_rand(seed, 2,3)*2-1; + vec3 dir = quaternion_rotate(rand_dir(emitter_cfg.direction.mean.xy*dir_mean_factor, + emitter_cfg.direction.stddev.xy, + r23), + emitter_cfg.rotation_quat); + + vec3 vel_dir = dir; + if((emitter_cfg.direction_flags & 1) != 0) { + vec2 r45 = dir_normal_distr ? normal_rand(seed, 4, 5) : uniform_rand(seed, 4, 5)*2-1; + vel_dir = quaternion_rotate(rand_dir(emitter_cfg.direction.mean.zw*dir_mean_factor, + emitter_cfg.direction.stddev.zw, + r45), + emitter_cfg.rotation_quat); + } + + float r = mix(emitter_cfg.size[0], emitter_cfg.size[1], uniform_rand(seed, 6)); + vec3 pos = emitter_cfg.position.xyz + dir*r; + vec3 velocity = vel_dir*rand_vel + emitter_cfg.parent_velocity.xyz; + + // single euler step to distribute particles more evenly with bigger delta-times + pos += velocity * emitter_cfg.timestep*(float(invId)/float(emitter_cfg.to_spawn)); + + pout.particles[index].position.xyz = pos; + pout.particles[index].velocity.xyz = velocity; + + + } +} diff --git a/src/mirrage/renderer/shader/particle/update_simple.comp b/src/mirrage/renderer/shader/particle/update_simple.comp new file mode 100644 index 0000000000000000000000000000000000000000..48965bda638060604c352bf16ddac666b6f91b0a --- /dev/null +++ b/src/mirrage/renderer/shader/particle/update_simple.comp @@ -0,0 +1,152 @@ +#version 450 +#extension GL_ARB_separate_shader_objects : enable + +#include "base_particle_script.glsl" + +layout (local_size_x = 32, local_size_y = 1, local_size_z = 1) in; + +layout(std140, set=1, binding = 0) readonly buffer Particle_type_config { + PARTICLE_TYPE_CONFIG +} particle_config; + + +layout(push_constant) uniform Push_constants { + float timestep; + uint particle_read_offset; + uint particle_read_count; + + uint effector_count; + uint effector_offset; +} update_cfg; + + +vec3 calc_size(uint keyframe_a, uint keyframe_b, float t, vec3 rand) { + return mix(rand_xyz(particle_config.keyframes[keyframe_a].size, rand), + rand_xyz(particle_config.keyframes[keyframe_b].size, rand), + t); +} + +vec3 calc_effector_force(uint effector_idx, vec3 p, float inv_mass, float mass_sign) { + vec3 p_diff = shared_uniforms.effectors[effector_idx].position.xyz - p; + float dist = length(p_diff); + + vec3 dir = shared_uniforms.effectors[effector_idx].force_dir.xyz; + if(dot(dir,dir) < 0.000001 && dist>0.000001) { + dir = p_diff / dist; + } else { + dir = normalize(dir); + } + + float force = shared_uniforms.effectors[effector_idx].force; + + // distance decay + if(shared_uniforms.effectors[effector_idx].distance_decay > 0) + force /= pow(dist, shared_uniforms.effectors[effector_idx].distance_decay); + + float accel = mix(force, force*inv_mass, shared_uniforms.effectors[effector_idx].mass_scale); + if(mass_sign<0) { + accel *= mass_sign * shared_uniforms.effectors[effector_idx].negative_mass_scale; + } + + return clamp(accel, -30, 30) * dir; +} + +void main() { + uint offset = gl_GlobalInvocationID.x; + + if(offset < update_cfg.particle_read_count) { + uint index = offset + update_cfg.particle_read_offset; + + vec2 ttl = vec2(pin.particles[index].position.w, pin.particles[index].velocity.w); + ttl[0] -= update_cfg.timestep; + + if(ttl[0] <= 0) { + // dead => drop data + } else { + const float dt = update_cfg.timestep; + + uint seed = pin.particles[index].data.y; + + // incr count and get output index + uint old_feedback_index = pin.particles[index].data.x; + uint feedback_index = feedback_mapping.new_feedback_index[old_feedback_index]; + uint out_offset = atomicAdd(feedback.ranges[feedback_index].count, 1); + uint out_index = out_offset + feedback.ranges[feedback_index].offset; + + // update keyframe + float age = ttl[1] - ttl[0]; + uint keyframe = pin.particles[index].data.z; + if(particle_config.loop_keyframe_time>0) { + keyframe = 0; + age = mod(age, particle_config.loop_keyframe_time); + } + + for(uint i=keyframe+1; i age) { + keyframe = i - 1; + break; + } + } + + uint keyframe_b = min(keyframe+1, particle_config.keyframe_count-1); + + float time_a = particle_config.keyframes[keyframe].time; + float time_b = particle_config.keyframes[keyframe_b].time; + + float time_diff = time_b - time_a; + float keyframe_t = time_diff>0.0 ? clamp((age - time_a) / time_diff, 0.0, 1.0) : 0.0; + + // update position / velocity + vec3 position = pin.particles[index].position.xyz; + vec3 velocity = pin.particles[index].velocity.xyz; + velocity *= (1.0 - dt*mix(particle_config.keyframes[keyframe].drag, + particle_config.keyframes[keyframe_b].drag, + keyframe_t)); + + // apply effectors + vec2 uniform_shared = uniform_rand(seed, 22, 23); + vec2 uniform_size = uniform_rand(seed, 24, 25); + vec2 normal_shared = uniform_to_normal_rand(uniform_shared); + vec2 normal_size = uniform_to_normal_rand(uniform_size); + + vec3 size_rand; + size_rand.x = (particle_config.normal_distribution_flags & 16)!=0 ? normal_shared.y + : uniform_shared.y*2-1; + size_rand.y = (particle_config.normal_distribution_flags & 32)!=0 ? normal_size.x + : uniform_size.x*2-1; + size_rand.z = (particle_config.normal_distribution_flags & 64)!=0 ? normal_size.x + : uniform_size.x*2-1; + + vec3 size = calc_size(keyframe, keyframe_b, keyframe_t, size_rand); + if((particle_config.flags&4)!=0) + size.y = size.z = size.x; + float volumn = size.x * size.y * size.z; + + float mass = mix(particle_config.keyframes[keyframe].base_mass, + particle_config.keyframes[keyframe_b].base_mass, + keyframe_t); + + mass += volumn * mix(particle_config.keyframes[keyframe].density, + particle_config.keyframes[keyframe_b].density, + keyframe_t); + + float inv_mass = mass>0.0000001 ? abs(1.0/mass) : 0.0; + float mass_sign = mass<0 ? -1.0 : 1.0; + + for(uint i=0; i=1 || lightspace_pos.y>=1) + return 1.0; + else { + return texture(sampler2DShadow(shadowmaps[shadowmap], shadowmap_shadow_sampler), + lightspace_pos.xyz); + } +} + +vec3 calc_lighting(vec3 albedo, vec3 radiance, vec3 shadow_radiance, vec3 position, vec3 N, vec3 L, + float roughness, float metallic, int shadowmap) { + + const float PI = 3.14159265359; + + vec3 V = -normalize(position); + + vec3 F0 = mix(vec3(0.04), albedo.rgb, metallic); + albedo.rgb *= 1.0 - metallic; + + float shadow = 1; + if(FRAGMENT_SHADOWS==1) { + if(shadowmap>=0) { + mat4 ls = lights.dir_lights[shadowmap].light_space; + shadow = sample_shadow(ls, shadowmap, position); + } + } else { + shadow = in_shadows[shadowmap]; + } + + float NdotL = max(dot(N, L), 0.0); + + shadow *= NdotL; + + vec3 out_color = vec3(0,0,0); + + if(shadow>0.0) { + vec3 diffuse; + out_color = brdf_without_NdotL(albedo, F0, roughness, N, V, L, radiance, diffuse) * shadow; + } + + return out_color + shadow_radiance * albedo / PI * (1.0 - shadow); +} + +vec4 calc_color(int mip) { + vec4 albedo = texture(albedo_sampler, tex_coords); + albedo *= out_particle_color; + + vec2 screen_uv = out_screen_pos.xy/out_screen_pos.w*0.5+0.5; + float background_depth = textureLod(depth_sampler, screen_uv, mip).r * -global_uniforms.proj_planes.y; + albedo.a *= smoothstep(0, 0.2, abs(background_depth-view_pos.z/view_pos.w)); + + if(albedo.a<0.001) { + discard; + } + + vec2 N_tangent = texture(normal_sampler, tex_coords).rg*2-1; + vec3 N = normalize(normal); + if(dot(N_tangent,N_tangent) < 0.0001) + N = tangent_space_to_world(N, decode_tangent_normal(N_tangent)); + + vec4 brdf = texture(brdf_sampler, tex_coords); + float roughness = brdf.r; + float metallic = brdf.g; + roughness = mix(0.01, 0.99, roughness*roughness); + + float emissive_power = texture(emission_sampler, tex_coords).r; + + vec4 result_color = vec4(0,0,0,albedo.a); + + result_color.rgb += albedo.rgb * model_uniforms.light_data.rgb * emissive_power + * model_uniforms.light_data.a * albedo.a; + + if(lights.count==0) { + result_color.rgb += albedo.rgb * albedo.a; + + } else { + for(int i=0; i=1 || lightspace_pos.y>=1) + return 1.0; + else { + return texture(sampler2DShadow(shadowmaps[shadowmap], shadowmap_shadow_sampler), + lightspace_pos.xyz); + } +} + +void main() { + base_main(); + + if(FRAGMENT_SHADOWS==0) { + vec3 p = out_view_pos.xyz / out_view_pos.w; + + for(int i=0; i + + +namespace mirrage::renderer { + + void load_component(ecs::Deserializer& state, Billboard_comp& comp) + { + state.read_virtual(sf2::vmember("billboards", comp.billboards)); + + for(auto& b : comp.billboards) { + if(!b.material || b.material.aid() != b.material_aid) { + b.material = state.assets.load(b.material_aid); + } + b.material_aid = {}; // reset aid to safe memory + } + } + void save_component(ecs::Serializer& state, const Billboard_comp& comp) + { + auto billboards = comp.billboards; + for(auto& b : billboards) + b.material_aid = b.material.aid().str(); + + state.write_virtual(sf2::vmember("billboards", billboards)); + } + + auto construct_push_constants(const Billboard& bb, const glm::mat4& view, const glm::vec4& viewport) + -> Billboard_push_constants + { + auto pcs = Billboard_push_constants{}; + pcs.position = glm::vec4(bb.offset, 1.f); + if(!bb.absolute_screen_space) { + pcs.position = view * pcs.position; + pcs.position /= pcs.position.w; + } else { + pcs.position.x = pcs.position.x / (viewport.z / 2) - 1.f; + pcs.position.y = -(pcs.position.y / (viewport.w / 2) - 1.f); + } + pcs.position.w = bb.vertical_rotation ? 1.f : 0.f; + pcs.size = glm::vec4(bb.size, + bb.absolute_screen_space ? 1.f : 0.f, + bb.fixed_screen_size || bb.absolute_screen_space ? 1.f : 0.f); + if(bb.absolute_screen_space || bb.fixed_screen_size) { + pcs.size.x /= viewport.z / 2.f; + pcs.size.y /= viewport.w / 2.f; + } + pcs.clip_rect = bb.clip_rect; + pcs.color = bb.color; + pcs.emissive_color = bb.emissive_color; + pcs.emissive_color.a /= 10000.0f; + + return pcs; + } + +} // namespace mirrage::renderer + +namespace mirrage::asset { + auto Loader::load(istream in) -> async::task + { + auto& assets = in.manager(); + auto data = Loader::load(std::move(in)); + + auto mat = assets.load(data.material_aid); + return mat.internal_task().then([data = std::move(data), mat = std::move(mat)](auto&) mutable { + return renderer::Billboard{std::move(data), std::move(mat)}; + }); + } + +} // namespace mirrage::asset diff --git a/src/mirrage/renderer/src/camera_comp.cpp b/src/mirrage/renderer/src/camera_comp.cpp index d3a109667fa7199a7e5f0d826601fcff28749a92..547dcba0f3aa79f93a194f9bd126efb55deffefa 100644 --- a/src/mirrage/renderer/src/camera_comp.cpp +++ b/src/mirrage/renderer/src/camera_comp.cpp @@ -18,8 +18,12 @@ namespace mirrage::renderer { { auto fov = comp._fov / 1_deg; - state.read_virtual( - sf2::vmember("fov", fov), sf2::vmember("near", comp._near), sf2::vmember("far", comp._far)); + state.read_virtual(sf2::vmember("fov", fov), + sf2::vmember("near", comp._near), + sf2::vmember("far", comp._far), + sf2::vmember("dof_focus", comp._dof_focus), + sf2::vmember("dof_range", comp._dof_range), + sf2::vmember("dof_power", comp._dof_power)); comp._fov = fov * 1_deg; } @@ -27,8 +31,12 @@ namespace mirrage::renderer { { auto fov = comp._fov / 1_deg; - state.write_virtual( - sf2::vmember("fov", fov), sf2::vmember("near", comp._near), sf2::vmember("far", comp._far)); + state.write_virtual(sf2::vmember("fov", fov), + sf2::vmember("near", comp._near), + sf2::vmember("far", comp._far), + sf2::vmember("dof_focus", comp._dof_focus), + sf2::vmember("dof_range", comp._dof_range), + sf2::vmember("dof_power", comp._dof_power)); } auto Camera_comp::calc_projection(glm::vec4 viewport) const -> glm::mat4 @@ -45,8 +53,31 @@ namespace mirrage::renderer { model[3] = glm::vec4(position, 1.f); return model; } + auto def_projection(glm::vec4 viewport) -> glm::mat4 + { + auto m = glm::perspective(glm::radians(50.f), aspect_radio(viewport), 0.1f, 100.f); + m[1][1] *= -1; + return m; + } } // namespace + + Camera_state::Camera_state(glm::vec4 viewport) + : eye_position(0, 0, 0) + , viewport(viewport) + , inv_view(1.f) + , view(glm::inverse(inv_view)) + , projection(def_projection(viewport)) + , pure_projection(projection) + , view_projection(projection * view) + , near_plane(0.1f) + , far_plane(100.f) + , aspect_ratio((viewport.z - viewport.x) / (viewport.w - viewport.y)) + , fov_vertical(glm::radians(50.f)) + , fov_horizontal(2.f * std::atan(std::tan(fov_vertical / 2.f) * aspect_ratio)) + { + } + Camera_state::Camera_state(const Camera_comp& cam, const ecs::components::Transform_comp& transform, glm::vec4 viewport) @@ -69,6 +100,9 @@ namespace mirrage::renderer { , aspect_ratio((viewport.z - viewport.x) / (viewport.w - viewport.y)) , fov_vertical(cam.fov()) , fov_horizontal(2.f * std::atan(std::tan(fov_vertical / 2.f) * aspect_ratio)) + , dof_focus(cam.dof_focus()) + , dof_range(cam.dof_range()) + , dof_power(cam.dof_power()) { } diff --git a/src/mirrage/renderer/src/debug_ui.hpp b/src/mirrage/renderer/src/debug_ui.hpp new file mode 100644 index 0000000000000000000000000000000000000000..5004d6204f57eec541ae55d6b1c1f467d760045e --- /dev/null +++ b/src/mirrage/renderer/src/debug_ui.hpp @@ -0,0 +1,252 @@ +#pragma once + +#include + +#include +#include + +#include + + +namespace mirrage::renderer { + + namespace detail { + template + auto to_fixed_str(T num, int digits) + { + auto ss = std::stringstream{}; + ss << std::fixed << std::setprecision(digits) << num; + return ss.str(); + } + + auto pad_left(const std::string& str, int padding) + { + return std::string(std::size_t(padding), ' ') + str; + } + + template + auto top_n(const Container& container, Comp&& less) + { + auto max_elements = std::array(); + max_elements.fill(container.end()); + + for(auto iter = container.begin(); iter != container.end(); iter++) { + // compare with each of the top elements + for(auto i = std::size_t(0); i < N; i++) { + if(max_elements[i] == container.end() || less(*max_elements[i], *iter)) { + // move top elements to make room + for(auto j = i + 1; j < N; j++) { + max_elements[j] = max_elements[j - 1]; + } + max_elements[i] = iter; + break; + } + } + } + + return max_elements; + } + + template + auto index_of(const Container& container, const T& element) -> int + { + auto top_entry = std::find(container.begin(), container.end(), element); + if(top_entry == container.end()) + return -1; + + return gsl::narrow(std::distance(container.begin(), top_entry)); + } + } // namespace detail + + + class Deferred_renderer_factory::Profiler_menu : public gui::Debug_menu { + public: + Profiler_menu(std::vector& renderer_instances) + : Debug_menu("profiler"), _renderer_instances(renderer_instances) + { + } + + void on_show() override + { + for(auto& r : _renderer_instances) + r->profiler().enable(); + } + void on_hide() override + { + for(auto& r : _renderer_instances) + r->profiler().disable(); + } + + void draw(gui::Gui&) override + { + for(auto& r : _renderer_instances) + r->profiler().enable(); + + ImGui::PositionNextWindow( + {330, 380}, ImGui::WindowPosition_X::right, ImGui::WindowPosition_Y::center); + if(ImGui::Begin("Renderer Profiler")) { + if(ImGui::Button("Reset")) { + for(auto& r : _renderer_instances) + r->profiler().reset(); + } + +#if 0 + if(_performance_log.is_nothing() && nk_button_label(ctx, "Record")) { + _performance_log = _engine.assets().save_raw("log:perf.log"_aid); + } +#endif + + ImGui::BeginTable("perf", + {"RenderPass", "Curr (ms)", "Min (ms)", "Avg (ms)", "Max (ms)"}, + _first_frame); + + auto print_entry = [&](auto&& printer, + const graphic::Profiler_result& result, + int depth = 0, + int rank = -1) -> void { + auto color = [&] { + switch(rank) { + case 0: return ImColor(255, 0, 0); + case 1: return ImColor(255, 220, 128); + default: return ImColor(255, 255, 255); + } + }(); + + ImGui::TextColored(color, "%s", detail::pad_left(result.name(), depth * 4).c_str()); + ImGui::NextColumn(); + ImGui::TextColored(color, "%s", detail::to_fixed_str(result.time_ms(), 2).c_str()); + ImGui::NextColumn(); + ImGui::TextColored(color, "%s", detail::to_fixed_str(result.time_min_ms(), 2).c_str()); + ImGui::NextColumn(); + ImGui::TextColored(color, "%s", detail::to_fixed_str(result.time_avg_ms(), 2).c_str()); + ImGui::NextColumn(); + ImGui::TextColored(color, "%s", detail::to_fixed_str(result.time_max_ms(), 2).c_str()); + ImGui::NextColumn(); + + auto worst_timings = detail::top_n<2>(result, [](auto&& lhs, auto&& rhs) { + return lhs.time_avg_ms() < rhs.time_avg_ms(); + }); + + for(auto iter = result.begin(); iter != result.end(); iter++) { + auto rank = detail::index_of(worst_timings, iter); + printer(printer, *iter, depth + 1, rank); + } + }; + + + for(auto& r : _renderer_instances) + print_entry(print_entry, r->profiler().results()); + } + + ImGui::End(); + _first_frame = false; + } + + private: + std::vector& _renderer_instances; + bool _first_frame = true; + }; + + + class Deferred_renderer_factory::Settings_menu : public gui::Debug_menu { + public: + Settings_menu(Deferred_renderer_factory& factory, graphic::Window& window) + : Debug_menu("renderer_settings") + , _factory(factory) + , _window(window) + , _window_width(_window.width()) + , _window_height(_window.height()) + , _window_fullscreen(_window.fullscreen() != graphic::Fullscreen::no) + { + } + + void draw(gui::Gui&) override + { + ImGui::PositionNextWindow( + {250, 600}, ImGui::WindowPosition_X::left, ImGui::WindowPosition_Y::center); + if(ImGui::Begin("Renderer Setting")) { + + auto renderer_settings = _factory.settings(); + + ImGui::SliderInt("Window Width", &_window_width, 640, 7680); + ImGui::SliderInt("Window Height", &_window_height, 360, 4320); + + ImGui::Checkbox("Fullscreen", &_window_fullscreen); + + if(ImGui::Button("Apply")) { + apply_window_changed(); + } + + ImGui::Spacing(); + + ImGui::TextUnformatted("Renderer Settings"); + + ImGui::Checkbox("Particle Frag. Shadows", &renderer_settings.particle_fragment_shadows); + + ImGui::SliderInt("Debug Layer", &renderer_settings.debug_gi_layer, -1, 10); + + ImGui::Checkbox("Indirect Illumination", &renderer_settings.gi); + + ImGui::Checkbox("Indirect Shadows", &renderer_settings.gi_shadows); + + ImGui::Checkbox("High-Resolution GI", &renderer_settings.gi_highres); + + ImGui::SliderInt("Minimum GI MIP", &renderer_settings.gi_min_mip_level, 0, 4); + + ImGui::SliderInt("Diffuse GI MIP", &renderer_settings.gi_diffuse_mip_level, 0, 4); + + ImGui::SliderInt("Low-Res Sample Count", &renderer_settings.gi_lowres_samples, 8, 1024); + ImGui::SliderInt("Sample Count", &renderer_settings.gi_samples, 8, 1024); + + ImGui::SliderFloat("Exposure", &renderer_settings.exposure_override, 0.f, 50.f); + + ImGui::SliderFloat("Min Disp. Lum.", &renderer_settings.min_display_luminance, 1.f, 100.f); + ImGui::SliderFloat("Max Disp. Lum.", &renderer_settings.max_display_luminance, 1.f, 1000.f); + + ImGui::SliderFloat( + "Background Brightness", &renderer_settings.background_intensity, 0.f, 10.f); + + ImGui::Checkbox("Ambient Occlusion", &renderer_settings.ssao); + + ImGui::Checkbox("Bloom", &renderer_settings.bloom); + + ImGui::Checkbox("Tonemapping", &renderer_settings.tonemapping); + + ImGui::Checkbox("Depth of Field", &renderer_settings.depth_of_field); + + + if(ImGui::Button("Apply")) { + apply_window_changed(); + _factory.settings(renderer_settings, true); + } else { + _factory.settings(renderer_settings, false); + } + + if(ImGui::Button("Reset")) { + _factory.settings(renderer::Renderer_settings{}, true); + } + } + ImGui::End(); + } + + void apply_window_changed() + { + if(_window_width != _window.width() || _window_height != _window.height() + || _window_fullscreen != (_window.fullscreen() != graphic::Fullscreen::no)) { + _window.dimensions(_window_width, + _window_height, + _window_fullscreen ? graphic::Fullscreen::yes_borderless + : graphic::Fullscreen::no); + } + } + + private: + Deferred_renderer_factory& _factory; + graphic::Window& _window; + + int _window_width; + int _window_height; + bool _window_fullscreen; + }; + +} // namespace mirrage::renderer diff --git a/src/mirrage/renderer/src/decal.cpp b/src/mirrage/renderer/src/decal.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a8c54663b9c63d91fcda8d9d8869fd5d8cb866a0 --- /dev/null +++ b/src/mirrage/renderer/src/decal.cpp @@ -0,0 +1,89 @@ +#include + +#include + + +namespace mirrage::renderer { + + void load_component(ecs::Deserializer& state, Decal_comp& comp) + { + state.read_virtual(sf2::vmember("decals", comp.decals)); + + for(auto& b : comp.decals) { + if(!b.material || b.material.aid() != b.material_aid) { + b.material = state.assets.load(b.material_aid); + } + b.material_aid = {}; // reset aid to safe memory + } + } + void save_component(ecs::Serializer& state, const Decal_comp& comp) + { + auto decals = comp.decals; + for(auto& b : decals) + b.material_aid = b.material.aid().str(); + + state.write_virtual(sf2::vmember("decals", decals)); + } + + namespace { + auto near_zero(float v) { return std::abs(v) < 0.0000001f; } + } // namespace + auto construct_push_constants(const Decal& bb, const glm::mat4& model) -> Decal_push_constants + { + auto pcs = Decal_push_constants{}; + pcs.model_view = model * glm::translate(glm::mat4(1), bb.offset) * glm::toMat4(bb.rotation) + * glm::scale(glm::mat4(1), glm::vec3(bb.size.x, bb.size.y, bb.thickness)); + pcs.model_view_inv = glm::inverse(pcs.model_view); + + MIRRAGE_INVARIANT(near_zero(pcs.model_view[0][3]) && near_zero(pcs.model_view[1][3]) + && near_zero(pcs.model_view[2][3]) && near_zero(pcs.model_view[3][3] - 1.f), + "Invalid matrix."); + + MIRRAGE_INVARIANT(near_zero(pcs.model_view_inv[0][3]) && near_zero(pcs.model_view_inv[1][3]) + && near_zero(pcs.model_view_inv[2][3]) + && near_zero(pcs.model_view_inv[3][3] - 1.f), + "Invalid matrix."); + + auto emissive_color = bb.emissive_color; + emissive_color.a /= 10000.0f; + if(!bb.material->has_emission()) + emissive_color = util::Rgba{0, 0, 0, 0}; + + pcs.model_view_inv[0][3] = emissive_color.r; + pcs.model_view_inv[1][3] = emissive_color.g; + pcs.model_view_inv[2][3] = emissive_color.b; + pcs.model_view_inv[3][3] = emissive_color.a; + + auto tmp = glm::uint(); + + tmp = glm::packSnorm2x16(glm::vec2{bb.clip_rect.r, bb.clip_rect.g} / 10.f); + std::memcpy(&pcs.model_view[0][3], &tmp, sizeof(tmp)); + + tmp = glm::packSnorm2x16(glm::vec2{bb.clip_rect.b, bb.clip_rect.a} / 10.f); + std::memcpy(&pcs.model_view[1][3], &tmp, sizeof(tmp)); + + auto color = bb.material->has_albedo() ? bb.color : util::Rgba{0, 0, 0, 0}; + tmp = glm::packUnorm2x16(glm::vec2{color.r, color.g}); + std::memcpy(&pcs.model_view[2][3], &tmp, sizeof(tmp)); + + tmp = glm::packUnorm2x16(glm::vec2{color.b, color.a}); + std::memcpy(&pcs.model_view[3][3], &tmp, sizeof(tmp)); + + return pcs; + } + +} // namespace mirrage::renderer + +namespace mirrage::asset { + auto Loader::load(istream in) -> async::task + { + auto& assets = in.manager(); + auto data = Loader::load(std::move(in)); + + auto mat = assets.load(data.material_aid); + return mat.internal_task().then([data = std::move(data), mat = std::move(mat)](auto&) mutable { + return renderer::Decal{std::move(data), std::move(mat)}; + }); + } + +} // namespace mirrage::asset diff --git a/src/mirrage/renderer/src/deferred_renderer.cpp b/src/mirrage/renderer/src/deferred_renderer.cpp index da18e5422b2c8d6ba743d650330670fc9d61b32d..94dc301130a4bf80dfa710a84912f453300bcc62 100644 --- a/src/mirrage/renderer/src/deferred_renderer.cpp +++ b/src/mirrage/renderer/src/deferred_renderer.cpp @@ -1,5 +1,8 @@ #include +#include "debug_ui.hpp" + +#include #include #include @@ -8,44 +11,78 @@ #include #include #include +#include +#include #include #include using namespace mirrage::graphic; +extern void ref_embedded_assets_mirrage_renderer(); + namespace mirrage::renderer { - Deferred_renderer::Deferred_renderer(Deferred_renderer_factory& factory, - std::vector>& passes, - ecs::Entity_manager& ecs, - Engine& engine) + namespace { + auto gbuffer_required(const std::vector& passes) + { + return std::any_of(passes.begin(), passes.end(), [&](auto& p) { return p->requires_gbuffer(); }); + } + + auto create_billboard_model(Deferred_renderer& r) + { + const auto vertices = + std::array{Model_vertex{glm::vec3(-0.5f, -0.5f, 0), + glm::normalize(glm::vec3(-0.8f, -0.8f, 0.131f)), + glm::vec2(0, 1)}, + Model_vertex{glm::vec3(0.5f, -0.5f, 0), + glm::normalize(glm::vec3(0.8f, -0.8f, 0.131f)), + glm::vec2(1, 1)}, + Model_vertex{glm::vec3(-0.5f, 0.5f, 0), + glm::normalize(glm::vec3(-0.8f, 0.8f, 0.131f)), + glm::vec2(0, 0)}, + Model_vertex{glm::vec3(0.5f, 0.5f, 0), + glm::normalize(glm::vec3(0.8f, 0.8f, 0.131f)), + glm::vec2(1, 0)}}; + const auto indices = std::array{0, 1, 2, 2, 1, 3}; + + return Model{graphic::Mesh{r.device(), r.queue_family(), vertices, indices}, + {Sub_mesh{{}, 0u, 6u, glm::vec3(0, 0, 0), 1.f}}, + 1.f, + glm::vec3(0, 0, 0), + false, + 0}; + } + } // namespace + + + Deferred_renderer::Deferred_renderer(Deferred_renderer_factory& factory, + std::vector passes, + util::maybe ecs, + Engine& engine) : _engine(&engine) , _factory(&factory) - , _entity_manager(&ecs) - , _descriptor_set_pool(device().create_descriptor_pool(128, - {vk::DescriptorType::eUniformBuffer, - vk::DescriptorType::eUniformBufferDynamic, - vk::DescriptorType::eCombinedImageSampler, - vk::DescriptorType::eInputAttachment, - vk::DescriptorType::eStorageBuffer, - vk::DescriptorType::eStorageTexelBuffer, - vk::DescriptorType::eStorageImage, - vk::DescriptorType::eSampledImage, - vk::DescriptorType::eSampler})) - , _gbuffer(std::make_unique( - device(), _descriptor_set_pool, factory._window.width(), factory._window.height())) - , _profiler(device(), 64) + , _entity_manager(ecs) + , _descriptor_set_pool(*device().vk_device(), + 128, + {vk::DescriptorType::eUniformBuffer, + vk::DescriptorType::eUniformBufferDynamic, + vk::DescriptorType::eCombinedImageSampler, + vk::DescriptorType::eInputAttachment, + vk::DescriptorType::eStorageBuffer, + vk::DescriptorType::eStorageTexelBuffer, + vk::DescriptorType::eStorageImage, + vk::DescriptorType::eSampledImage, + vk::DescriptorType::eSampler}) + , _gbuffer(gbuffer_required(passes) ? std::make_unique(device(), + _descriptor_set_pool, + factory._window.width(), + factory._window.height()) + : std::unique_ptr()) + , _profiler(device(), 128) - , _global_uniform_descriptor_set_layout( - device().create_descriptor_set_layout(vk::DescriptorSetLayoutBinding{ - 0, - vk::DescriptorType::eUniformBuffer, - 1, - vk::ShaderStageFlagBits::eVertex | vk::ShaderStageFlagBits::eFragment - | vk::ShaderStageFlagBits::eCompute})) , _global_uniform_descriptor_set( - _descriptor_set_pool.create_descriptor(*_global_uniform_descriptor_set_layout, 1)) + _descriptor_set_pool.create_descriptor(*factory._global_uniform_descriptor_set_layout, 1)) , _global_uniform_buffer( device().transfer().create_dynamic_buffer(sizeof(Global_uniforms), vk::BufferUsageFlagBits::eUniformBuffer, @@ -60,13 +97,19 @@ namespace mirrage::renderer { vk::Filter::eNearest, vk::SamplerMipmapMode::eNearest)) , _noise_descriptor_set_layout(device(), *_noise_sampler, 1, vk::ShaderStageFlagBits::eFragment) - , _passes(util::map(passes, + , _billboard_model(create_billboard_model(*this)) + , _pass_factories(std::move(passes)) + , _passes(util::map(_pass_factories, [&, write_first_pp_buffer = true](auto& factory) mutable { - return factory->create_pass(*this, ecs, engine, write_first_pp_buffer); + return factory->create_pass( + *this, std::shared_ptr{}, ecs, engine, write_first_pp_buffer); })) - , _cameras(&ecs.list()) + , _cameras(ecs.is_some() ? util::justPtr(&ecs.get_or_throw().list()) : util::nothing) { - ecs.register_component_type(); + if(ecs.is_some()) + ecs.get_or_throw().register_component_type(); + + ref_embedded_assets_mirrage_renderer(); _write_global_uniform_descriptor_set(); @@ -80,6 +123,7 @@ namespace mirrage::renderer { device().wait_idle(); std::this_thread::sleep_for(std::chrono::milliseconds(250)); _passes.clear(); + device().wait_idle(true); } void Deferred_renderer::recreate() @@ -87,24 +131,32 @@ namespace mirrage::renderer { LOG(plog::warning) << "--recreate"; device().wait_idle(); + auto persisted_pass_states = std::vector>(); + for(auto& pass : _passes) { - if(pass) + if(pass) { + persisted_pass_states.emplace_back(pass->extract_persistent_state()); pass.reset(); + } else { + persisted_pass_states.emplace_back(); + } } - _gbuffer.reset(); + if(gbuffer_required(_pass_factories)) { + _gbuffer.reset(); - // recreate gbuffer and renderpasses - _gbuffer = std::make_unique( - device(), _descriptor_set_pool, _factory->_window.width(), _factory->_window.height()); + // recreate gbuffer and renderpasses + _gbuffer = std::make_unique( + device(), _descriptor_set_pool, _factory->_window.width(), _factory->_window.height()); + } auto write_first_pp_buffer = true; for(auto i = std::size_t(0); i < _passes.size(); i++) { - _passes[i] = _factory->_pass_factories.at(i)->create_pass( - *this, *_entity_manager, *_engine, write_first_pp_buffer); + _passes[i] = _pass_factories.at(i)->create_pass( + *this, persisted_pass_states.at(i), _entity_manager, *_engine, write_first_pp_buffer); } - _profiler = graphic::Profiler(device(), 64); + _profiler = graphic::Profiler(device(), 128); device().wait_idle(); } @@ -123,14 +175,15 @@ namespace mirrage::renderer { nullptr, &buffer_info}; - device().vk_device()->updateDescriptorSets(desc_writes.size(), desc_writes.data(), 0, nullptr); + device().vk_device()->updateDescriptorSets( + gsl::narrow(desc_writes.size()), desc_writes.data(), 0, nullptr); } void Deferred_renderer::update(util::Time dt) { _time_acc += dt.value(); _delta_time = dt.value(); - _frame_counter = (_frame_counter + 1) % 1000000; + _frame_counter = (_frame_counter + 1) % 10; for(auto& pass : _passes) { if(pass) @@ -171,14 +224,13 @@ namespace mirrage::renderer { // draw subpasses for(auto& pass : _passes) { if(pass) { + auto q = graphic::Queue_debug_label(device().context(), main_command_buffer, pass->name()); auto _ = _profiler.push(pass->name()); pass->draw(_frame_data); } } - _frame_data.geometry_queue.clear(); - _frame_data.light_queue.clear(); - _frame_data.debug_geometry_queue.clear(); + _frame_data.clear_queues(); // reset cached camera state _active_camera = util::nothing; @@ -215,33 +267,39 @@ namespace mirrage::renderer { if(_active_camera.is_some()) return _active_camera.get_or_throw(); - auto max_prio = std::numeric_limits::lowest(); - auto active = static_cast(nullptr); + if(_cameras.is_some()) { + auto max_prio = std::numeric_limits::lowest(); + auto active = static_cast(nullptr); - for(auto& camera : *_cameras) { - if(camera.priority() > max_prio && camera.owner(*_entity_manager).is_some()) { - max_prio = camera.priority(); - active = &camera; + for(auto& camera : _cameras.get_or_throw()) { + if(camera.priority() > max_prio && camera.owner(_entity_manager.get_or_throw()).is_some()) { + max_prio = camera.priority(); + active = &camera; + } } - } - if(active) { - const auto& viewport = _factory->_window.viewport(); - auto& transform = active->owner(*_entity_manager) - .get_or_throw() - .get() - .get_or_throw("Camera without transform component!"); - _active_camera = Camera_state(*active, transform, viewport); - - for(auto& p : _passes) { - if(p) - p->process_camera(_active_camera.get_or_throw()); + if(active) { + const auto& viewport = _factory->_window.viewport(); + auto& transform = active->owner(_entity_manager.get_or_throw()) + .get_or_throw() + .get() + .get_or_throw("Camera without transform component!"); + _active_camera = Camera_state(*active, transform, viewport); + + for(auto& p : _passes) { + if(p) + p->process_camera(_active_camera.get_or_throw()); + } + + return util::justPtr(&_active_camera.get_or_throw()); + } else { + _active_camera = util::nothing; + return util::maybe(); } - return _active_camera.get_or_throw(); } else { - _active_camera = util::nothing; - return util::nothing; + _active_camera.emplace(_factory->_window.viewport()); + return util::justPtr(&_active_camera.get_or_throw()); } } @@ -251,6 +309,160 @@ namespace mirrage::renderer { return _descriptor_set_pool.create_descriptor(layout, bindings); } + void Deferred_renderer::debug_draw_sphere(const glm::vec3& center, float radius, const util::Rgb& color) + { + constexpr auto vertices = std::array{ + glm::vec3(0.000000, -1.000000, 0.000000), glm::vec3(0.723607, -0.447220, 0.525725), + glm::vec3(-0.276388, -0.447220, 0.850649), glm::vec3(-0.894426, -0.447216, 0.000000), + glm::vec3(-0.276388, -0.447220, -0.850649), glm::vec3(0.723607, -0.447220, -0.525725), + glm::vec3(0.276388, 0.447220, 0.850649), glm::vec3(-0.723607, 0.447220, 0.525725), + glm::vec3(-0.723607, 0.447220, -0.525725), glm::vec3(0.276388, 0.447220, -0.850649), + glm::vec3(0.894426, 0.447216, 0.000000), glm::vec3(0.000000, 1.000000, 0.000000), + glm::vec3(-0.162456, -0.850654, 0.499995), glm::vec3(0.425323, -0.850654, 0.309011), + glm::vec3(0.262869, -0.525738, 0.809012), glm::vec3(0.850648, -0.525736, 0.000000), + glm::vec3(0.425323, -0.850654, -0.309011), glm::vec3(-0.525730, -0.850652, 0.000000), + glm::vec3(-0.688189, -0.525736, 0.499997), glm::vec3(-0.162456, -0.850654, -0.499995), + glm::vec3(-0.688189, -0.525736, -0.499997), glm::vec3(0.262869, -0.525738, -0.809012), + glm::vec3(0.951058, 0.000000, 0.309013), glm::vec3(0.951058, 0.000000, -0.309013), + glm::vec3(0.000000, 0.000000, 1.000000), glm::vec3(0.587786, 0.000000, 0.809017), + glm::vec3(-0.951058, 0.000000, 0.309013), glm::vec3(-0.587786, 0.000000, 0.809017), + glm::vec3(-0.587786, 0.000000, -0.809017), glm::vec3(-0.951058, 0.000000, -0.309013), + glm::vec3(0.587786, 0.000000, -0.809017), glm::vec3(0.000000, 0.000000, -1.000000), + glm::vec3(0.688189, 0.525736, 0.499997), glm::vec3(-0.262869, 0.525738, 0.809012), + glm::vec3(-0.850648, 0.525736, 0.000000), glm::vec3(-0.262869, 0.525738, -0.809012), + glm::vec3(0.688189, 0.525736, -0.499997), glm::vec3(0.162456, 0.850654, 0.499995), + glm::vec3(0.525730, 0.850652, 0.000000), glm::vec3(-0.425323, 0.850654, 0.309011), + glm::vec3(-0.425323, 0.850654, -0.309011), glm::vec3(0.162456, 0.850654, -0.499995)}; + + if(_factory->settings().debug_geometry) { + const auto line = [&](auto b, auto e) { + _frame_data.debug_geometry_queue.emplace_back(vertices[std::size_t(b - 1)] * radius + center, + vertices[std::size_t(e - 1)] * radius + center, + color); + }; + + line(1, 13); + line(1, 14); + line(1, 17); + line(1, 18); + line(1, 20); + line(2, 14); + line(2, 15); + line(2, 16); + line(2, 23); + line(2, 26); + line(3, 13); + line(3, 15); + line(3, 19); + line(3, 25); + line(3, 28); + line(4, 18); + line(4, 19); + line(4, 21); + line(4, 27); + line(4, 30); + line(5, 20); + line(5, 21); + line(5, 22); + line(5, 29); + line(5, 32); + line(6, 16); + line(6, 17); + line(6, 22); + line(6, 24); + line(6, 31); + line(7, 25); + line(7, 26); + line(7, 33); + line(7, 34); + line(7, 38); + line(8, 27); + line(8, 28); + line(8, 34); + line(8, 35); + line(8, 40); + line(9, 29); + line(9, 30); + line(9, 35); + line(9, 36); + line(9, 41); + line(10, 31); + line(10, 32); + line(10, 36); + line(10, 37); + line(10, 42); + line(11, 23); + line(11, 24); + line(11, 33); + line(11, 37); + line(11, 39); + line(12, 38); + line(12, 39); + line(12, 40); + line(12, 41); + line(12, 42); + line(13, 14); + line(13, 15); + line(13, 18); + line(13, 19); + line(14, 15); + line(14, 16); + line(14, 17); + line(15, 25); + line(15, 26); + line(16, 17); + line(16, 23); + line(16, 24); + line(17, 20); + line(17, 22); + line(18, 19); + line(18, 20); + line(18, 21); + line(19, 27); + line(19, 28); + line(20, 21); + line(20, 22); + line(21, 29); + line(21, 30); + line(22, 31); + line(22, 32); + line(23, 24); + line(23, 26); + line(23, 33); + line(24, 31); + line(24, 37); + line(25, 26); + line(25, 28); + line(25, 34); + line(27, 28); + line(27, 30); + line(27, 35); + line(28, 34); + line(29, 30); + line(29, 32); + line(29, 36); + line(30, 35); + line(31, 32); + line(31, 37); + line(32, 36); + line(33, 38); + line(33, 39); + line(34, 38); + line(34, 40); + line(35, 40); + line(35, 41); + line(36, 41); + line(36, 42); + line(37, 39); + line(37, 42); + line(38, 39); + line(38, 40); + line(39, 42); + line(40, 41); + line(41, 42); + } + } + struct Deferred_renderer_factory::Asset_loaders { asset::Asset_manager& assets; @@ -259,15 +471,22 @@ namespace mirrage::renderer { graphic::Device& device, vk::Sampler material_sampler, vk::DescriptorSetLayout material_layout, - std::uint32_t draw_queue) + std::uint32_t draw_queue, + vk::DescriptorSetLayout storage_buffer, + vk::DescriptorSetLayout uniform_buffer) : assets(assets) { - assets.create_stateful_loader(device, assets, material_sampler, material_layout); assets.create_stateful_loader(device, assets, draw_queue); + assets.create_stateful_loader(device, storage_buffer, uniform_buffer); + assets.create_stateful_loader(); + assets.create_stateful_loader(); } ~Asset_loaders() { + assets.remove_stateful_loader(); + assets.remove_stateful_loader(); + assets.remove_stateful_loader(); assets.remove_stateful_loader(); assets.remove_stateful_loader(); } @@ -292,10 +511,37 @@ namespace mirrage::renderer { , _compute_command_buffer_pool(_device->create_command_buffer_pool("compute"_strid, true, true)) , _model_material_sampler(_device->create_sampler(12)) , _model_desc_set_layout(create_material_descriptor_set_layout(*_device, *_model_material_sampler)) - , _asset_loaders(std::make_unique( - _assets, *_device, *_model_material_sampler, *_model_desc_set_layout, _draw_queue_family)) - { + , _global_uniform_descriptor_set_layout( + _device->create_descriptor_set_layout(vk::DescriptorSetLayoutBinding{ + 0, + vk::DescriptorType::eUniformBuffer, + 1, + vk::ShaderStageFlagBits::eVertex | vk::ShaderStageFlagBits::eFragment + | vk::ShaderStageFlagBits::eCompute})) + , _compute_storage_buffer_layout(_device->create_descriptor_set_layout(vk::DescriptorSetLayoutBinding{ + 0, + vk::DescriptorType::eStorageBuffer, + 1, + vk::ShaderStageFlagBits::eCompute | vk::ShaderStageFlagBits::eVertex + | vk::ShaderStageFlagBits::eFragment})) + , _compute_uniform_buffer_layout(_device->create_descriptor_set_layout(vk::DescriptorSetLayoutBinding{ + 0, + vk::DescriptorType::eUniformBuffer, + 1, + vk::ShaderStageFlagBits::eCompute | vk::ShaderStageFlagBits::eVertex + | vk::ShaderStageFlagBits::eFragment})) + , _asset_loaders(std::make_unique(_assets, + *_device, + *_model_material_sampler, + *_model_desc_set_layout, + _draw_queue_family, + compute_storage_buffer_layout(), + compute_uniform_buffer_layout())) + , _all_passes_mask(util::map(_pass_factories, [&](auto& f) { return f->id(); })) + , _profiler_menu(std::make_unique(_renderer_instances)) + , _settings_menu(std::make_unique(*this, _window)) + { auto maybe_settings = _assets.load_maybe("cfg:renderer"_aid); if(maybe_settings.is_nothing()) { _settings = asset::make_ready_asset("cfg:renderer"_aid, Renderer_settings{}); @@ -318,10 +564,19 @@ namespace mirrage::renderer { _settings = _assets.load("cfg:renderer"_aid); } - auto Deferred_renderer_factory::create_renderer(ecs::Entity_manager& ecs) + auto Deferred_renderer_factory::create_renderer(util::maybe ecs, + Render_pass_mask passes) -> std::unique_ptr { - return std::make_unique(*this, _pass_factories, ecs, _engine); + auto pass_factories = std::vector(); + pass_factories.reserve(_pass_factories.size()); + for(auto& p : _pass_factories) { + if(passes.empty() || std::find(passes.begin(), passes.end(), p->id()) != passes.end()) { + pass_factories.emplace_back(p.get()); + } + } + + return std::make_unique(*this, pass_factories, ecs, _engine); } void Deferred_renderer_factory::finish_frame() @@ -466,6 +721,10 @@ namespace mirrage::renderer { "Anisotropic filtering is not supported by device!"); ret_val.features.samplerAnisotropy = true; + MIRRAGE_INVARIANT(supported_features.textureCompressionBC, + "BC texture compression is not supported by device!"); + ret_val.features.textureCompressionBC = true; + for(auto& pass : _pass_factories) { pass->configure_device(gpu, gqueue, ret_val); } diff --git a/src/mirrage/renderer/src/gbuffer.cpp b/src/mirrage/renderer/src/gbuffer.cpp index d0fb85f89710d4c3ff2befd607c5bc8b8dbac3bb..9bf2b4987a3cb62e5152f338814430c4427ee746 100644 --- a/src/mirrage/renderer/src/gbuffer.cpp +++ b/src/mirrage/renderer/src/gbuffer.cpp @@ -26,7 +26,7 @@ namespace mirrage::renderer { auto get_depth_format(graphic::Device& device) { auto format = device.get_supported_format( - {vk::Format::eR16Unorm, vk::Format::eR16Sfloat, vk::Format::eR32Sfloat}, + {vk::Format::eR32Sfloat}, vk::FormatFeatureFlagBits::eColorAttachment | vk::FormatFeatureFlagBits::eSampledImageFilterLinear); @@ -58,16 +58,18 @@ namespace mirrage::renderer { {width, height}, 1,