Compare commits
96 Commits
howToVulka
...
vkguide
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
597bd4c04e | ||
|
|
207cdbf2a3 | ||
|
|
f724ecc09d | ||
|
|
65a715bd12 | ||
|
|
d2cbc2e073 | ||
|
|
9b7b0af38d | ||
|
|
e2a2833aae | ||
|
|
4874a49aaa | ||
|
|
bbf7950bfa | ||
|
|
0313543c06 | ||
|
|
697d604d5a | ||
|
|
f12bcf9b7c | ||
|
|
b5bae50f55 | ||
|
|
089e7493b6 | ||
|
|
e6a2fb9c22 | ||
|
|
ffa06fb97f | ||
|
|
d0bb078f2f | ||
|
|
88dba64752 | ||
|
|
eb196fffd6 | ||
|
|
5626e6ead8 | ||
|
|
a78a17fdde | ||
|
|
9515c4293e | ||
|
|
f43f5ea101 | ||
|
|
0ff518ce9f | ||
|
|
610039cf16 | ||
|
|
f37b7676d3 | ||
|
|
fda45a1bfe | ||
|
|
052248a699 | ||
|
|
4468080472 | ||
|
|
df9aa831ac | ||
|
|
bc45fe99ab | ||
|
|
24e2090fb5 | ||
|
|
08958cb66f | ||
|
|
01a508edb2 | ||
|
|
1ccfae3d98 | ||
|
|
dcac87d621 | ||
|
|
424a454d1c | ||
|
|
c65ea58e84 | ||
|
|
aca3015e12 | ||
|
|
ddd7ee7a0d | ||
|
|
3ca60e61eb | ||
|
|
2774f27049 | ||
|
|
6feb6b98b5 | ||
|
|
05c9bf672b | ||
|
|
e6e7cf394f | ||
|
|
663d7ed70a | ||
| 6ebe7143a8 | |||
| 3c4be610c5 | |||
| 239b509ca8 | |||
| 620daad6b7 | |||
| be672eb3ce | |||
| a14a1f7b53 | |||
| 12667eb1f8 | |||
| 02b1a3a41a | |||
| 961c75ce94 | |||
| eda72b2125 | |||
| 9b2d49529e | |||
| 7962a5367a | |||
| cb1f648a31 | |||
| 235a6f1c4e | |||
|
|
4e92afd550 | ||
|
|
5ce6f70155 | ||
|
|
7e4aa7930c | ||
|
|
2f06209391 | ||
|
|
bb87c95da2 | ||
|
|
a09162d916 | ||
|
|
98c4594885 | ||
|
|
3a80180add | ||
|
|
8d83991d99 | ||
|
|
cfd92d7a87 | ||
|
|
ede2e3f1f9 | ||
|
|
c88340db29 | ||
|
|
6ab1795eeb | ||
|
|
69492d78ac | ||
|
|
4b33ed8732 | ||
|
|
e4b44af05c | ||
|
|
6df8188bb8 | ||
|
|
817a4de020 | ||
|
|
8f763d5e95 | ||
|
|
0dfbf9011a | ||
|
|
53a1a73bfc | ||
|
|
1ad367d650 | ||
|
|
f418ccabbc | ||
|
|
86257df3e8 | ||
|
|
cc53d411ef | ||
|
|
3844f654cb | ||
|
|
b01fab5b9c | ||
|
|
b25c3d8360 | ||
|
|
87e7db0c87 | ||
|
|
77ff2d7c0e | ||
|
|
f8b47fbdd4 | ||
|
|
9236ada59a | ||
|
|
2603d12394 | ||
|
|
46d150ac1d | ||
|
|
fe7f7521d8 | ||
|
|
c20c6928b1 |
1
.clangd
1
.clangd
@ -11,3 +11,4 @@ CompileFlags:
|
|||||||
- -DLOGGER_IMPL
|
- -DLOGGER_IMPL
|
||||||
- -DSERVER_INIT_IMPL
|
- -DSERVER_INIT_IMPL
|
||||||
- -DSERVER_IMPL
|
- -DSERVER_IMPL
|
||||||
|
- -DLOADER_IMPL
|
||||||
|
|||||||
4
.envrc
4
.envrc
@ -1,3 +1 @@
|
|||||||
FLAKEPATH="/home/alex/Developer/nix/NixOSDots/dev-flakes"
|
use flake
|
||||||
|
|
||||||
use flake ${FLAKEPATH}/vulkan
|
|
||||||
|
|||||||
54
.gitea/workflows/build.yaml
Normal file
54
.gitea/workflows/build.yaml
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
name: Build VulkanEngine
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- vkguide
|
||||||
|
pull_request:
|
||||||
|
workflow_dispatch:
|
||||||
|
schedule:
|
||||||
|
- cron: "@weekly"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-22.04
|
||||||
|
container: git.alexdelcamp.fr/alexandre_1a/flake-actions:latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout (avec submodules récursifs)
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
submodules: recursive
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: S'assurer que les flakes sont activés
|
||||||
|
run: |
|
||||||
|
mkdir -p ~/.config/nix
|
||||||
|
grep -q "experimental-features" ~/.config/nix/nix.conf 2>/dev/null || \
|
||||||
|
echo "experimental-features = nix-command flakes" >> ~/.config/nix/nix.conf
|
||||||
|
|
||||||
|
- name: Build using nix
|
||||||
|
run: |
|
||||||
|
nix build .#engine
|
||||||
|
|
||||||
|
- name: Bundle
|
||||||
|
run: |
|
||||||
|
nix bundle --bundler github:ralismark/nix-appimage .#engine --out-link ./engine-bundle
|
||||||
|
|
||||||
|
- name: Upload des artefacts
|
||||||
|
if: success()
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: vulkan-engine.zip
|
||||||
|
path: |
|
||||||
|
./engine-bundle
|
||||||
|
if-no-files-found: warn
|
||||||
|
archive: false
|
||||||
|
|
||||||
|
- name: Notify routine
|
||||||
|
if: always()
|
||||||
|
run: |
|
||||||
|
curl \
|
||||||
|
-H "Title: [Routine] VulkanEngine build" \
|
||||||
|
-d "Build finished (status: ${{ job.status }})" \
|
||||||
|
https://ntfy.alexdelcamp.fr/FlakeBuild
|
||||||
272
.gitea/workflows/build_linux.yaml
Normal file
272
.gitea/workflows/build_linux.yaml
Normal file
@ -0,0 +1,272 @@
|
|||||||
|
name: Build VulkanEngine
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- vkguide
|
||||||
|
pull_request:
|
||||||
|
workflow_dispatch:
|
||||||
|
schedule:
|
||||||
|
- cron: "0 3 * * 1"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# 1. Nix build: validates the flake build and produces the SPIR-V shaders
|
||||||
|
# (SPIR-V is OS independent, and slangc is not packaged in Debian).
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
nix:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
container: git.alexdelcamp.fr/alexandre_1a/flake-actions:latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
submodules: recursive
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: Configure
|
||||||
|
run: |
|
||||||
|
nix develop --command cmake -S . -B build \
|
||||||
|
-G Ninja \
|
||||||
|
-DCMAKE_BUILD_TYPE=Release
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: |
|
||||||
|
nix develop --command cmake --build build --parallel 2
|
||||||
|
|
||||||
|
- name: Upload shaders
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: shaders
|
||||||
|
path: build/engine/shaders
|
||||||
|
|
||||||
|
- name: Notify progress
|
||||||
|
if: always()
|
||||||
|
run: |
|
||||||
|
curl \
|
||||||
|
-H "Title: [Routine] Shaders" \
|
||||||
|
-d "Build finished" \
|
||||||
|
https://ntfy.alexdelcamp.fr/FlakeBuild
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# 2. Debian 12 builds: portable (static) and bundle (bin/ + lib/)
|
||||||
|
# Built on glibc 2.36 => runs on Debian 12 and anything newer.
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
debug:
|
||||||
|
needs: nix
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
container: debian:12
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
steps:
|
||||||
|
# git + nodejs must exist before checkout (JS actions run in the container)
|
||||||
|
- name: Dependencies
|
||||||
|
run: |
|
||||||
|
apt-get update
|
||||||
|
apt-get install -y --no-install-recommends \
|
||||||
|
git ca-certificates nodejs curl \
|
||||||
|
build-essential cmake ninja-build pkg-config \
|
||||||
|
libwayland-dev libwayland-bin wayland-protocols libxkbcommon-dev \
|
||||||
|
libx11-dev libxrandr-dev libxinerama-dev libxcursor-dev libxi-dev
|
||||||
|
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
submodules: recursive
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: Git safe directory
|
||||||
|
run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
|
||||||
|
|
||||||
|
- name: Download shaders
|
||||||
|
uses: actions/download-artifact@v4
|
||||||
|
with:
|
||||||
|
name: shaders
|
||||||
|
path: prebuilt-shaders
|
||||||
|
|
||||||
|
- name: Configure
|
||||||
|
run: |
|
||||||
|
cmake -S . -B build -G Ninja \
|
||||||
|
--preset debug \
|
||||||
|
-DVULKANENGINE_FETCH_DEPS=ON \
|
||||||
|
-DVULKANENGINE_PORTABLE=ON \
|
||||||
|
-DVULKANENGINE_PREBUILT_SHADERS="$PWD/prebuilt-shaders"
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: cmake --build build --parallel 2
|
||||||
|
|
||||||
|
- name: Install
|
||||||
|
run: cmake --install build --prefix dist --strip
|
||||||
|
|
||||||
|
- name: Check binaries
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
for b in dist/bin/engine dist/bin/server; do
|
||||||
|
echo "========== $b =========="
|
||||||
|
readelf -l "$b" | grep 'program interpreter'
|
||||||
|
readelf -d "$b" | grep -E 'RPATH|RUNPATH|NEEDED' || true
|
||||||
|
|
||||||
|
if strings "$b" | grep -q '/nix/store'; then
|
||||||
|
echo "ERROR: $b references /nix/store"; exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# The loader must come from volk (dlopen), never from NEEDED
|
||||||
|
if readelf -d "$b" | grep -q 'libvulkan'; then
|
||||||
|
echo "ERROR: $b links libvulkan directly"; exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "PORTABLE" = "PORTABLE" ]; then
|
||||||
|
if readelf -d "$b" | grep -Eq 'libstdc\+\+|libgcc_s'; then
|
||||||
|
echo "ERROR: $b is not static for libstdc++/libgcc"; exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
max=$(objdump -T "$b" | grep -o 'GLIBC_[0-9.]*' | sed 's/GLIBC_//' | sort -uV | tail -1 || true)
|
||||||
|
echo "Highest GLIBC symbol: ${max:-none}"
|
||||||
|
if [ -n "$max" ] && [ "$(printf '%s\n%s\n' "$max" 2.36 | sort -V | tail -1)" != "2.36" ]; then
|
||||||
|
echo "ERROR: needs glibc $max (> 2.36)"; exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ldd "$b" | grep 'not found'; then
|
||||||
|
echo "ERROR: unresolved libraries in $b"; exit 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# tar keeps permissions and symlinks; artifact zips do not
|
||||||
|
- name: Package
|
||||||
|
run: |
|
||||||
|
tar -C dist -czf VulkanEngine-DEBUG-linux-x86_64.tar.gz .
|
||||||
|
|
||||||
|
- name: Upload build
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: VulkanEngine-DEBUG-linux-x86_64
|
||||||
|
path: VulkanEngine-DEBUG-linux-x86_64.tar.gz
|
||||||
|
- name: Notify progress
|
||||||
|
if: failure()
|
||||||
|
run: |
|
||||||
|
curl \
|
||||||
|
-H "Title: [Routine] Engine-DEBUG build" \
|
||||||
|
-d "Build failed (nix: ${{ needs.nix.result }}, release: ${{ needs.debug.result }})" \
|
||||||
|
https://ntfy.alexdelcamp.fr/FlakeBuild
|
||||||
|
release:
|
||||||
|
needs: nix
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
container: debian:12
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
variant: [PORTABLE, BUNDLE]
|
||||||
|
|
||||||
|
steps:
|
||||||
|
# git + nodejs must exist before checkout (JS actions run in the container)
|
||||||
|
- name: Dependencies
|
||||||
|
run: |
|
||||||
|
apt-get update
|
||||||
|
apt-get install -y --no-install-recommends \
|
||||||
|
git ca-certificates nodejs curl \
|
||||||
|
build-essential cmake ninja-build pkg-config \
|
||||||
|
libwayland-dev libwayland-bin wayland-protocols libxkbcommon-dev \
|
||||||
|
libx11-dev libxrandr-dev libxinerama-dev libxcursor-dev libxi-dev
|
||||||
|
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
submodules: recursive
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: Git safe directory
|
||||||
|
run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
|
||||||
|
|
||||||
|
- name: Download shaders
|
||||||
|
uses: actions/download-artifact@v4
|
||||||
|
with:
|
||||||
|
name: shaders
|
||||||
|
path: prebuilt-shaders
|
||||||
|
|
||||||
|
- name: Configure
|
||||||
|
run: |
|
||||||
|
cmake -S . -B build -G Ninja \
|
||||||
|
-DCMAKE_BUILD_TYPE=Release \
|
||||||
|
-DVULKANENGINE_FETCH_DEPS=ON \
|
||||||
|
-DVULKANENGINE_${{ matrix.variant }}=ON \
|
||||||
|
-DVULKANENGINE_PREBUILT_SHADERS="$PWD/prebuilt-shaders"
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: cmake --build build --parallel 2
|
||||||
|
|
||||||
|
- name: Install
|
||||||
|
run: cmake --install build --prefix dist --strip
|
||||||
|
|
||||||
|
- name: Check binaries
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
for b in dist/bin/engine dist/bin/server; do
|
||||||
|
echo "========== $b =========="
|
||||||
|
readelf -l "$b" | grep 'program interpreter'
|
||||||
|
readelf -d "$b" | grep -E 'RPATH|RUNPATH|NEEDED' || true
|
||||||
|
|
||||||
|
if strings "$b" | grep -q '/nix/store'; then
|
||||||
|
echo "ERROR: $b references /nix/store"; exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# The loader must come from volk (dlopen), never from NEEDED
|
||||||
|
if readelf -d "$b" | grep -q 'libvulkan'; then
|
||||||
|
echo "ERROR: $b links libvulkan directly"; exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "${{ matrix.variant }}" = "PORTABLE" ]; then
|
||||||
|
if readelf -d "$b" | grep -Eq 'libstdc\+\+|libgcc_s'; then
|
||||||
|
echo "ERROR: $b is not static for libstdc++/libgcc"; exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
max=$(objdump -T "$b" | grep -o 'GLIBC_[0-9.]*' | sed 's/GLIBC_//' | sort -uV | tail -1 || true)
|
||||||
|
echo "Highest GLIBC symbol: ${max:-none}"
|
||||||
|
if [ -n "$max" ] && [ "$(printf '%s\n%s\n' "$max" 2.36 | sort -V | tail -1)" != "2.36" ]; then
|
||||||
|
echo "ERROR: needs glibc $max (> 2.36)"; exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ldd "$b" | grep 'not found'; then
|
||||||
|
echo "ERROR: unresolved libraries in $b"; exit 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ "${{ matrix.variant }}" = "BUNDLE" ]; then
|
||||||
|
echo "========== lib/ =========="
|
||||||
|
ls -la dist/lib
|
||||||
|
fi
|
||||||
|
|
||||||
|
# tar keeps permissions and symlinks; artifact zips do not
|
||||||
|
- name: Package
|
||||||
|
run: |
|
||||||
|
tar -C dist -czf VulkanEngine-${{ matrix.variant }}-linux-x86_64.tar.gz .
|
||||||
|
|
||||||
|
- name: Upload build
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: VulkanEngine-${{ matrix.variant }}-linux-x86_64
|
||||||
|
path: VulkanEngine-${{ matrix.variant }}-linux-x86_64.tar.gz
|
||||||
|
- name: Notify progress
|
||||||
|
if: failure()
|
||||||
|
run: |
|
||||||
|
curl \
|
||||||
|
-H "Title: [Routine] Engine-${{ matrix.variant }} build" \
|
||||||
|
-d "Build failed (nix: ${{ needs.nix.result }}, release: ${{ needs.release.result }})" \
|
||||||
|
https://ntfy.alexdelcamp.fr/FlakeBuild
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
notify:
|
||||||
|
needs: [nix, release]
|
||||||
|
if: always()
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Notify routine
|
||||||
|
run: |
|
||||||
|
curl \
|
||||||
|
-H "Title: [Routine] VulkanEngine build" \
|
||||||
|
-d "Build finished (nix: ${{ needs.nix.result }}, release: ${{ needs.release.result }})" \
|
||||||
|
https://ntfy.alexdelcamp.fr/FlakeBuild
|
||||||
5
.gitignore
vendored
5
.gitignore
vendored
@ -37,6 +37,11 @@ Thumbs.db
|
|||||||
# direnv
|
# direnv
|
||||||
.direnv/
|
.direnv/
|
||||||
|
|
||||||
|
# cache
|
||||||
|
.cache
|
||||||
|
.cache/*
|
||||||
|
|
||||||
# Nix flakes
|
# Nix flakes
|
||||||
result
|
result
|
||||||
result-*
|
result-*
|
||||||
|
.cache/*
|
||||||
|
|||||||
11
.gitmodules
vendored
11
.gitmodules
vendored
@ -1,3 +1,8 @@
|
|||||||
[submodule "src/imgui"]
|
[submodule "include/imgui"]
|
||||||
path = src/imgui
|
path = include/imgui
|
||||||
url = https://github.com/ocornut/imgui.git
|
url = https://git.alexdelcamp.fr/Alexandre_1a/imgui.git
|
||||||
|
branch = docking
|
||||||
|
|
||||||
|
[submodule "include/CLI11"]
|
||||||
|
path = include/CLI11
|
||||||
|
url = https://github.com/CLIUtils/CLI11.git
|
||||||
|
|||||||
316
CMakeLists.txt
316
CMakeLists.txt
@ -1,4 +1,4 @@
|
|||||||
cmake_minimum_required (VERSION 3.29)
|
cmake_minimum_required(VERSION 3.25) # Debian 12 ships 3.25
|
||||||
project(VulkanEngine)
|
project(VulkanEngine)
|
||||||
|
|
||||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/CMake")
|
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/CMake")
|
||||||
@ -9,10 +9,69 @@ include(FetchContent)
|
|||||||
include(CheckIPOSupported)
|
include(CheckIPOSupported)
|
||||||
check_ipo_supported(RESULT LTO_SUPPORTED OUTPUT LTO_ERROR)
|
check_ipo_supported(RESULT LTO_SUPPORTED OUTPUT LTO_ERROR)
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Build modes
|
||||||
|
# (default) Nix dev build, deps from the Nix shell
|
||||||
|
# FETCH_DEPS + PORTABLE Single directory, everything static except
|
||||||
|
# glibc (and the Vulkan loader, loaded via volk)
|
||||||
|
# FETCH_DEPS + BUNDLE bin/ + lib/, project libs shared in lib/,
|
||||||
|
# system libstdc++ / libc / loader are used
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
option(VULKANENGINE_PORTABLE
|
||||||
|
"Build a Linux binary without Nix-specific runtime paths (static libs)"
|
||||||
|
OFF
|
||||||
|
)
|
||||||
|
|
||||||
|
option(VULKANENGINE_BUNDLE
|
||||||
|
"Build a Linux bundle using libraries from the bundle directory"
|
||||||
|
OFF
|
||||||
|
)
|
||||||
|
|
||||||
|
option(VULKANENGINE_FETCH_DEPS
|
||||||
|
"Fetch dependencies with FetchContent instead of using system/Nix packages"
|
||||||
|
OFF
|
||||||
|
)
|
||||||
|
|
||||||
|
set(VULKANENGINE_PREBUILT_SHADERS "" CACHE PATH
|
||||||
|
"Directory containing precompiled .spv files (skips glslang/slangc)"
|
||||||
|
)
|
||||||
|
|
||||||
|
if(VULKANENGINE_PORTABLE AND VULKANENGINE_BUNDLE)
|
||||||
|
message(FATAL_ERROR "VULKANENGINE_PORTABLE and VULKANENGINE_BUNDLE are mutually exclusive")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if((VULKANENGINE_PORTABLE OR VULKANENGINE_BUNDLE) AND NOT VULKANENGINE_FETCH_DEPS)
|
||||||
|
message(FATAL_ERROR
|
||||||
|
"PORTABLE/BUNDLE builds need -DVULKANENGINE_FETCH_DEPS=ON "
|
||||||
|
"(Nix libraries must not leak into the result)")
|
||||||
|
endif()
|
||||||
|
|
||||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||||
|
|
||||||
|
# RPATH / runtime paths
|
||||||
|
if(VULKANENGINE_PORTABLE)
|
||||||
|
message(STATUS "VulkanEngine: PORTABLE build")
|
||||||
|
|
||||||
|
set(CMAKE_SKIP_RPATH TRUE)
|
||||||
|
|
||||||
|
elseif(VULKANENGINE_BUNDLE)
|
||||||
|
message(STATUS "VulkanEngine: BUNDLE build")
|
||||||
|
|
||||||
|
set(CMAKE_SKIP_BUILD_RPATH FALSE)
|
||||||
|
set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
|
||||||
|
|
||||||
|
# Executables are installed in bin/
|
||||||
|
# Libraries are installed in lib/
|
||||||
|
set(CMAKE_INSTALL_RPATH "$ORIGIN/../lib")
|
||||||
|
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH FALSE)
|
||||||
|
|
||||||
|
# Every shared lib we build ends up here, installed as-is into lib/
|
||||||
|
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib")
|
||||||
|
|
||||||
|
else()
|
||||||
|
message(STATUS "VulkanEngine: normal build")
|
||||||
|
endif()
|
||||||
|
|
||||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||||
find_program(GCC_AR NAMES gcc-ar REQUIRED)
|
find_program(GCC_AR NAMES gcc-ar REQUIRED)
|
||||||
find_program(GCC_RANLIB NAMES gcc-ranlib REQUIRED)
|
find_program(GCC_RANLIB NAMES gcc-ranlib REQUIRED)
|
||||||
@ -20,19 +79,103 @@ if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
|||||||
set(CMAKE_RANLIB "${GCC_RANLIB}")
|
set(CMAKE_RANLIB "${GCC_RANLIB}")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Find all package dependencies
|
# ---------------------------------------------------------------------------
|
||||||
|
# Dependencies
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Same in every mode: no link-time dependency on libvulkan, all Vulkan
|
||||||
|
# functions come from volk (otherwise vk*KHR aliases are undefined at link).
|
||||||
|
set(ENGINE_EXTRA_DEFINITIONS
|
||||||
|
GLFW_INCLUDE_NONE
|
||||||
|
VK_NO_PROTOTYPES
|
||||||
|
VMA_STATIC_VULKAN_FUNCTIONS=0
|
||||||
|
VMA_DYNAMIC_VULKAN_FUNCTIONS=1
|
||||||
|
)
|
||||||
|
|
||||||
|
if(VULKANENGINE_FETCH_DEPS)
|
||||||
|
# Portable = static libs, bundle = shared libs (in lib/)
|
||||||
|
if(VULKANENGINE_BUNDLE)
|
||||||
|
set(BUILD_SHARED_LIBS ON)
|
||||||
|
else()
|
||||||
|
set(BUILD_SHARED_LIBS OFF)
|
||||||
|
endif()
|
||||||
|
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||||
|
|
||||||
|
set(VULKAN_HEADERS_ENABLE_MODULE OFF CACHE BOOL "" FORCE)
|
||||||
|
set(VULKAN_HEADERS_ENABLE_TESTS OFF CACHE BOOL "" FORCE)
|
||||||
|
set(VULKAN_HEADERS_ENABLE_INSTALL OFF CACHE BOOL "" FORCE)
|
||||||
|
set(VOLK_PULL_IN_VULKAN OFF CACHE BOOL "" FORCE)
|
||||||
|
set(VOLK_INSTALL OFF CACHE BOOL "" FORCE)
|
||||||
|
set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
|
||||||
|
set(GLFW_BUILD_TESTS OFF CACHE BOOL "" FORCE)
|
||||||
|
set(GLFW_BUILD_DOCS OFF CACHE BOOL "" FORCE)
|
||||||
|
set(GLFW_INSTALL OFF CACHE BOOL "" FORCE)
|
||||||
|
set(FMT_INSTALL OFF CACHE BOOL "" FORCE)
|
||||||
|
set(FMT_TEST OFF CACHE BOOL "" FORCE)
|
||||||
|
set(SIMDJSON_DEVELOPER_MODE OFF CACHE BOOL "" FORCE)
|
||||||
|
set(CLI11_BUILD_TESTS OFF CACHE BOOL "" FORCE)
|
||||||
|
set(CLI11_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
|
||||||
|
set(GLM_BUILD_TESTS OFF CACHE BOOL "" FORCE)
|
||||||
|
set(GLM_BUILD_LIBRARY OFF CACHE BOOL "" FORCE)
|
||||||
|
|
||||||
|
# Keep these versions in sync with your nixpkgs (check the tags exist)
|
||||||
|
FetchContent_Declare(VulkanHeaders
|
||||||
|
GIT_REPOSITORY https://github.com/KhronosGroup/Vulkan-Headers.git
|
||||||
|
GIT_TAG v1.4.309)
|
||||||
|
# vulkan/vk_enum_string_helper.h lives here, not in Vulkan-Headers.
|
||||||
|
# SOURCE_SUBDIR points to a nonexistent dir so MakeAvailable only downloads
|
||||||
|
# (we use the checked-in header, no need to run its CMake).
|
||||||
|
FetchContent_Declare(VulkanUtilityLibraries
|
||||||
|
GIT_REPOSITORY https://github.com/KhronosGroup/Vulkan-Utility-Libraries.git
|
||||||
|
GIT_TAG v1.4.309
|
||||||
|
SOURCE_SUBDIR _no_cmake)
|
||||||
|
FetchContent_Declare(volk
|
||||||
|
GIT_REPOSITORY https://github.com/zeux/volk.git
|
||||||
|
GIT_TAG 1.4.304)
|
||||||
|
FetchContent_Declare(VMA
|
||||||
|
GIT_REPOSITORY https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator.git
|
||||||
|
GIT_TAG v3.2.1)
|
||||||
|
FetchContent_Declare(glfw
|
||||||
|
GIT_REPOSITORY https://github.com/glfw/glfw.git
|
||||||
|
GIT_TAG 3.4)
|
||||||
|
FetchContent_Declare(vk-bootstrap
|
||||||
|
GIT_REPOSITORY https://github.com/charles-lunarg/vk-bootstrap.git
|
||||||
|
GIT_TAG v1.4.365)
|
||||||
|
FetchContent_Declare(fmt
|
||||||
|
GIT_REPOSITORY https://github.com/fmtlib/fmt.git
|
||||||
|
GIT_TAG 11.0.2)
|
||||||
|
FetchContent_Declare(CLI11
|
||||||
|
GIT_REPOSITORY https://github.com/CLIUtils/CLI11.git
|
||||||
|
GIT_TAG v2.4.2)
|
||||||
|
FetchContent_Declare(glm
|
||||||
|
GIT_REPOSITORY https://github.com/g-truc/glm.git
|
||||||
|
GIT_TAG 1.0.1)
|
||||||
|
FetchContent_Declare(simdjson
|
||||||
|
GIT_REPOSITORY https://github.com/simdjson/simdjson.git
|
||||||
|
GIT_TAG v3.10.1)
|
||||||
|
|
||||||
|
# Vulkan headers first: vk-bootstrap and volk pick up Vulkan::Headers
|
||||||
|
FetchContent_MakeAvailable(VulkanHeaders VulkanUtilityLibraries)
|
||||||
|
FetchContent_MakeAvailable(volk VMA glfw vk-bootstrap fmt CLI11 glm simdjson)
|
||||||
|
|
||||||
|
target_link_libraries(volk PUBLIC Vulkan::Headers)
|
||||||
|
|
||||||
|
add_library(vk_utility_headers INTERFACE)
|
||||||
|
target_include_directories(vk_utility_headers SYSTEM INTERFACE
|
||||||
|
${vulkanutilitylibraries_SOURCE_DIR}/include)
|
||||||
|
target_link_libraries(vk_utility_headers INTERFACE Vulkan::Headers)
|
||||||
|
|
||||||
|
else()
|
||||||
|
# Nix path
|
||||||
|
find_package( volk CONFIG REQUIRED )
|
||||||
find_package( glfw3 REQUIRED )
|
find_package( glfw3 REQUIRED )
|
||||||
find_package( glm REQUIRED )
|
find_package( glm REQUIRED )
|
||||||
find_package( VulkanMemoryAllocator CONFIG REQUIRED )
|
find_package( VulkanMemoryAllocator CONFIG REQUIRED )
|
||||||
find_package( fmt REQUIRED )
|
find_package( CLI11 REQUIRED )
|
||||||
# Shader compilers
|
find_package( simdjson REQUIRED )
|
||||||
add_executable (glslang::validator IMPORTED)
|
endif()
|
||||||
find_program (GLSLANG_VALIDATOR "glslangValidator" HINTS $ENV{VULKAN_SDK}/bin REQUIRED)
|
|
||||||
set_property (TARGET glslang::validator PROPERTY IMPORTED_LOCATION "${GLSLANG_VALIDATOR}")
|
|
||||||
find_program(SLANGC_EXECUTABLE slangc HINTS $ENV{VULKAN_SDK}/bin REQUIRED)
|
|
||||||
|
|
||||||
# fastgltf because it's not in nixpkgs
|
|
||||||
|
|
||||||
|
# fastgltf because it's not in nixpkgs (declared after the switch above so it
|
||||||
|
# inherits BUILD_SHARED_LIBS)
|
||||||
FetchContent_Declare(
|
FetchContent_Declare(
|
||||||
fastgltf
|
fastgltf
|
||||||
GIT_REPOSITORY https://github.com/spnda/fastgltf.git
|
GIT_REPOSITORY https://github.com/spnda/fastgltf.git
|
||||||
@ -40,13 +183,26 @@ FetchContent_Declare(
|
|||||||
)
|
)
|
||||||
FetchContent_MakeAvailable(fastgltf)
|
FetchContent_MakeAvailable(fastgltf)
|
||||||
|
|
||||||
# vk-bootstrap because CMAKE can't find it on NixOS
|
# ---------------------------------------------------------------------------
|
||||||
FetchContent_Declare(
|
# Shader compilers (not needed when precompiled shaders are provided)
|
||||||
vk-bootstrap
|
# ---------------------------------------------------------------------------
|
||||||
GIT_REPOSITORY https://github.com/charles-lunarg/vk-bootstrap.git
|
if(NOT VULKANENGINE_PREBUILT_SHADERS)
|
||||||
GIT_TAG v1.3.295
|
add_executable (glslang::validator IMPORTED)
|
||||||
|
find_program (
|
||||||
|
GLSLANG_VALIDATOR
|
||||||
|
"glslangValidator"
|
||||||
|
HINTS $ENV{VULKAN_SDK}/bin
|
||||||
|
REQUIRED
|
||||||
)
|
)
|
||||||
FetchContent_MakeAvailable(vk-bootstrap)
|
|
||||||
|
set_property (
|
||||||
|
TARGET glslang::validator
|
||||||
|
PROPERTY IMPORTED_LOCATION "${GLSLANG_VALIDATOR}"
|
||||||
|
)
|
||||||
|
|
||||||
|
find_program(SLANGC_EXECUTABLE slangc HINTS $ENV{VULKAN_SDK}/bin REQUIRED)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
|
||||||
# Helper functions to build shaders
|
# Helper functions to build shaders
|
||||||
function(addGlslShader SOURCE OUTPUT_DIR)
|
function(addGlslShader SOURCE OUTPUT_DIR)
|
||||||
@ -91,21 +247,39 @@ endfunction()
|
|||||||
|
|
||||||
# A function to automate executables aditions
|
# A function to automate executables aditions
|
||||||
function ( addBinary BINARY_NAME )
|
function ( addBinary BINARY_NAME )
|
||||||
cmake_parse_arguments ( BINARY "IMGUI;LICENSE" "SOURCE" "SHADERS;SLANG_SHADERS;LIBS;TEXTURES;MODELS" ${ARGN} )
|
cmake_parse_arguments ( BINARY "IMGUI;LICENSE" "SOURCE" "SHADERS;SLANG_SHADERS;SLANG_ENTRIES;LIBS;TEXTURES;MODELS" ${ARGN} )
|
||||||
if (DEFINED BINARY_SOURCE)
|
if (DEFINED BINARY_SOURCE)
|
||||||
add_executable ( ${BINARY_NAME} src/${BINARY_SOURCE}.cpp )
|
add_executable ( ${BINARY_NAME} src/${BINARY_SOURCE}.cpp )
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
target_include_directories( ${BINARY_NAME} PRIVATE ${CMAKE_SOURCE_DIR}/src )
|
target_include_directories( ${BINARY_NAME} PRIVATE ${CMAKE_SOURCE_DIR}/src )
|
||||||
# Sets the output dir to have clear separation between binaries
|
# Sets the output dir to have clear separation between binaries
|
||||||
set_target_properties ( ${BINARY_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${BINARY_NAME} )
|
set_target_properties (
|
||||||
set_target_properties ( ${BINARY_NAME} PROPERTIES CXX_STANDARD 20 ) # Uses C++20
|
${BINARY_NAME}
|
||||||
|
PROPERTIES
|
||||||
|
RUNTIME_OUTPUT_DIRECTORY
|
||||||
|
${CMAKE_BINARY_DIR}/${BINARY_NAME}
|
||||||
|
CXX_STANDARD
|
||||||
|
20 # C++ 20
|
||||||
|
CXX_STANDARD_REQUIRED
|
||||||
|
ON
|
||||||
|
CXX_EXTENSIONS
|
||||||
|
OFF
|
||||||
|
CXX_SCAN_FOR_MODULES
|
||||||
|
OFF
|
||||||
|
)
|
||||||
# Sets per binary LTO
|
# Sets per binary LTO
|
||||||
if(LTO_SUPPORTED AND CMAKE_BUILD_TYPE STREQUAL "Release")
|
if(LTO_SUPPORTED AND CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||||
set_target_properties(${BINARY_NAME} PROPERTIES INTERPROCEDURAL_OPTIMIZATION TRUE)
|
set_target_properties(${BINARY_NAME} PROPERTIES INTERPROCEDURAL_OPTIMIZATION TRUE)
|
||||||
message("Enabled LTO")
|
message("Enabled LTO")
|
||||||
endif()
|
endif()
|
||||||
set_target_properties(${BINARY_NAME} PROPERTIES CXX_SCAN_FOR_MODULES OFF)
|
|
||||||
|
# Portable: libstdc++/libgcc statically linked so the binary does not depend
|
||||||
|
# on the host's version. NOT done for bundle: the shared libs in lib/ use the
|
||||||
|
# system libstdc++, and mixing two copies in one process is asking for trouble.
|
||||||
|
if(VULKANENGINE_PORTABLE)
|
||||||
|
target_link_options(${BINARY_NAME} PRIVATE -static-libstdc++ -static-libgcc)
|
||||||
|
endif()
|
||||||
|
|
||||||
# Define VULKAN_HPP_HANDLE_ERROR_OUT_OF_DATE_AS_SUCCESS to treat VK_ERROR_OUT_OF_DATE_KHR as a success code
|
# Define VULKAN_HPP_HANDLE_ERROR_OUT_OF_DATE_AS_SUCCESS to treat VK_ERROR_OUT_OF_DATE_KHR as a success code
|
||||||
target_compile_definitions (
|
target_compile_definitions (
|
||||||
@ -115,25 +289,33 @@ function ( addBinary BINARY_NAME )
|
|||||||
$<$<CONFIG:Debug>:DEBUG> # So CMAKE expose a #define DEBUG for debug builds
|
$<$<CONFIG:Debug>:DEBUG> # So CMAKE expose a #define DEBUG for debug builds
|
||||||
# Exposes versions
|
# Exposes versions
|
||||||
BUILD_ID="${ENGINE_VERSION}"
|
BUILD_ID="${ENGINE_VERSION}"
|
||||||
|
${ENGINE_EXTRA_DEFINITIONS}
|
||||||
)
|
)
|
||||||
|
|
||||||
if(BINARY_IMGUI)
|
if(BINARY_IMGUI)
|
||||||
target_include_directories(${BINARY_NAME} PRIVATE
|
target_include_directories(${BINARY_NAME} PRIVATE
|
||||||
${CMAKE_SOURCE_DIR}/src/imgui
|
${CMAKE_SOURCE_DIR}/include/imgui
|
||||||
${CMAKE_SOURCE_DIR}/src/imgui/backends
|
${CMAKE_SOURCE_DIR}/include/imgui/backends
|
||||||
)
|
)
|
||||||
|
|
||||||
target_sources(${BINARY_NAME} PRIVATE
|
target_sources(${BINARY_NAME} PRIVATE
|
||||||
${CMAKE_SOURCE_DIR}/src/imgui/imgui.cpp
|
${CMAKE_SOURCE_DIR}/include/imgui/imgui.cpp
|
||||||
|
|
||||||
${CMAKE_SOURCE_DIR}/src/imgui/imgui_draw.cpp
|
${CMAKE_SOURCE_DIR}/include/imgui/imgui_draw.cpp
|
||||||
${CMAKE_SOURCE_DIR}/src/imgui/imgui_tables.cpp
|
${CMAKE_SOURCE_DIR}/include/imgui/imgui_tables.cpp
|
||||||
${CMAKE_SOURCE_DIR}/src/imgui/imgui_widgets.cpp
|
${CMAKE_SOURCE_DIR}/include/imgui/imgui_widgets.cpp
|
||||||
${CMAKE_SOURCE_DIR}/src/imgui/imgui_demo.cpp
|
${CMAKE_SOURCE_DIR}/include/imgui/imgui_demo.cpp
|
||||||
|
#${CMAKE_SOURCE_DIR}/include/imgui/imgui_memory_editor.h
|
||||||
|
|
||||||
${CMAKE_SOURCE_DIR}/src/imgui/backends/imgui_impl_glfw.cpp
|
${CMAKE_SOURCE_DIR}/include/imgui/backends/imgui_impl_glfw.cpp
|
||||||
${CMAKE_SOURCE_DIR}/src/imgui/backends/imgui_impl_vulkan.cpp
|
${CMAKE_SOURCE_DIR}/include/imgui/backends/imgui_impl_vulkan.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# imgui's Vulkan backend must use volk since there is no linked loader
|
||||||
|
target_compile_definitions(${BINARY_NAME} PRIVATE IMGUI_IMPL_VULKAN_USE_VOLK)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
||||||
if(BINARY_LICENSE)
|
if(BINARY_LICENSE)
|
||||||
file(COPY ${CMAKE_SOURCE_DIR}/LICENSE DESTINATION ${CMAKE_BINARY_DIR}/${BINARY_NAME})
|
file(COPY ${CMAKE_SOURCE_DIR}/LICENSE DESTINATION ${CMAKE_BINARY_DIR}/${BINARY_NAME})
|
||||||
endif()
|
endif()
|
||||||
@ -141,6 +323,15 @@ function ( addBinary BINARY_NAME )
|
|||||||
|
|
||||||
if(DEFINED BINARY_SHADERS)
|
if(DEFINED BINARY_SHADERS)
|
||||||
set(SHADER_OUTPUT_DIR ${CMAKE_BINARY_DIR}/${BINARY_NAME}/shaders)
|
set(SHADER_OUTPUT_DIR ${CMAKE_BINARY_DIR}/${BINARY_NAME}/shaders)
|
||||||
|
|
||||||
|
if(VULKANENGINE_PREBUILT_SHADERS)
|
||||||
|
# Copy the .spv produced by the Nix job instead of compiling them
|
||||||
|
file(GLOB PREBUILT_SPV CONFIGURE_DEPENDS "${VULKANENGINE_PREBUILT_SHADERS}/*.spv")
|
||||||
|
if(NOT PREBUILT_SPV)
|
||||||
|
message(FATAL_ERROR "No .spv found in ${VULKANENGINE_PREBUILT_SHADERS}")
|
||||||
|
endif()
|
||||||
|
file(COPY ${PREBUILT_SPV} DESTINATION ${SHADER_OUTPUT_DIR})
|
||||||
|
else()
|
||||||
set(ALL_SPV_FILES "")
|
set(ALL_SPV_FILES "")
|
||||||
set(EXPANDED_SHADERS "")
|
set(EXPANDED_SHADERS "")
|
||||||
|
|
||||||
@ -170,9 +361,10 @@ function ( addBinary BINARY_NAME )
|
|||||||
add_custom_target(shaders_${BINARY_NAME} DEPENDS ${ALL_SPV_FILES})
|
add_custom_target(shaders_${BINARY_NAME} DEPENDS ${ALL_SPV_FILES})
|
||||||
add_dependencies(${BINARY_NAME} shaders_${BINARY_NAME})
|
add_dependencies(${BINARY_NAME} shaders_${BINARY_NAME})
|
||||||
endif()
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
if (DEFINED BINARY_LIBS)
|
if (DEFINED BINARY_LIBS)
|
||||||
target_link_libraries ( ${BINARY_NAME} ${BINARY_LIBS} )
|
target_link_libraries ( ${BINARY_NAME} PRIVATE ${BINARY_LIBS} )
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (DEFINED BINARY_MODELS) # Adds the 3D models in the binary folder
|
if (DEFINED BINARY_MODELS) # Adds the 3D models in the binary folder
|
||||||
@ -205,23 +397,73 @@ function ( addBinary BINARY_NAME )
|
|||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
|
|
||||||
# Scan the shader folder
|
# ---------------------------------------------------------------------------
|
||||||
file(GLOB SHADER_SOURCES CONFIGURE_DEPENDS "shaders/*")
|
# Binaries
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
list(
|
||||||
|
APPEND
|
||||||
|
lib_list
|
||||||
|
# Libs used
|
||||||
|
glfw
|
||||||
|
fmt
|
||||||
|
vk-bootstrap
|
||||||
|
CLI11::CLI11
|
||||||
|
fastgltf
|
||||||
|
)
|
||||||
|
|
||||||
# Adds the main binary
|
if(VULKANENGINE_FETCH_DEPS)
|
||||||
|
# No libvulkan at link time: volk loads libvulkan.so.1 at runtime.
|
||||||
|
# Remove what your code does not use (simdjson, glm...).
|
||||||
|
list(APPEND lib_list
|
||||||
|
volk
|
||||||
|
Vulkan::Headers
|
||||||
|
vk_utility_headers
|
||||||
|
GPUOpen::VulkanMemoryAllocator
|
||||||
|
glm::glm-header-only
|
||||||
|
simdjson::simdjson
|
||||||
|
)
|
||||||
|
else()
|
||||||
|
# Nix: volk comes from nixpkgs (vulkan-volk); libvulkan is NOT linked
|
||||||
|
list(APPEND lib_list volk::volk)
|
||||||
|
endif()
|
||||||
|
|
||||||
addBinary (
|
addBinary (
|
||||||
engine
|
engine
|
||||||
SOURCE Engine/main
|
SOURCE Engine/main
|
||||||
|
# Flags
|
||||||
SHADERS ${SHADER_SOURCES}
|
|
||||||
SHADERS
|
|
||||||
LIBS glfw fmt vk-bootstrap vulkan
|
|
||||||
IMGUI
|
IMGUI
|
||||||
LICENSE
|
LICENSE
|
||||||
|
|
||||||
|
SHADERS shaders/*
|
||||||
|
MODELS *
|
||||||
|
|
||||||
|
LIBS ${lib_list}
|
||||||
)
|
)
|
||||||
|
|
||||||
addBinary (
|
addBinary (
|
||||||
server
|
server
|
||||||
SOURCE Server/main
|
SOURCE Server/main
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Install (used for portable / bundle packaging)
|
||||||
|
# dist/bin/{engine,server,shaders,models,textures}
|
||||||
|
# dist/lib/*.so* (bundle only)
|
||||||
|
# dist/LICENSE
|
||||||
|
# Never bundled: libc, libstdc++, libvulkan, GL, X11, Wayland.
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
install(TARGETS engine server RUNTIME DESTINATION bin)
|
||||||
|
install(DIRECTORY ${CMAKE_BINARY_DIR}/engine/shaders DESTINATION bin OPTIONAL)
|
||||||
|
install(DIRECTORY ${CMAKE_BINARY_DIR}/engine/models DESTINATION bin OPTIONAL)
|
||||||
|
install(DIRECTORY ${CMAKE_BINARY_DIR}/engine/textures DESTINATION bin OPTIONAL)
|
||||||
|
install(FILES ${CMAKE_SOURCE_DIR}/LICENSE DESTINATION .)
|
||||||
|
|
||||||
|
if(VULKANENGINE_BUNDLE)
|
||||||
|
# Every shared lib built from fetched deps (glfw, fmt, fastgltf and its own
|
||||||
|
# simdjson, ...) with its symlinks. libstdc++ etc. are not built here.
|
||||||
|
install(DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/
|
||||||
|
DESTINATION lib
|
||||||
|
USE_SOURCE_PERMISSIONS
|
||||||
|
FILES_MATCHING PATTERN "*.so*"
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|||||||
17
README.md
17
README.md
@ -5,3 +5,20 @@ Might expending it later into a game or engine.
|
|||||||
|
|
||||||
Based from [vkguide](https://vkguide.dev/)
|
Based from [vkguide](https://vkguide.dev/)
|
||||||
This has a very different philosophy than the main [Khronos Vulkan Tutorial](https://docs.vulkan.org/tutorial/latest/00_Introduction.html)
|
This has a very different philosophy than the main [Khronos Vulkan Tutorial](https://docs.vulkan.org/tutorial/latest/00_Introduction.html)
|
||||||
|
|
||||||
|
## Install
|
||||||
|
|
||||||
|
You can build it yourself, using two methods:
|
||||||
|
1- Use a devenv, and cmake
|
||||||
|
2- Use nix build
|
||||||
|
|
||||||
|
Or you can grab an artefact from the actions tab (currently broken).
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
All runtime documentation is included in the program, just launch it witout any arguments, or with the `-h` flag to see how to use it.
|
||||||
|
|
||||||
|
## Known bugs
|
||||||
|
Currently, when opening a new build, the imgui layout is not done, you need to dock everything yourself, only at the first launch (after that, the layout is saved in `imgui.ini`)
|
||||||
|
You also need to launch the executable in the same folder as the assets (shaders, models, textures).
|
||||||
|
|
||||||
|
All of these "bugs" are planned to be fixed.
|
||||||
|
|||||||
11
ROADMAP.md
Normal file
11
ROADMAP.md
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
# Roadmap
|
||||||
|
|
||||||
|
Finish vkguide.dev
|
||||||
|
|
||||||
|
Rewrite some part, for structure purposes
|
||||||
|
|
||||||
|
Configure offscreen rendering for imgui (docked viewport)
|
||||||
|
|
||||||
|
Separate tooling and core, for shipping
|
||||||
|
- #ifdef DEBUG for tools
|
||||||
|
- #ifdef NDEBUG for release
|
||||||
BIN
assets/models/basicmesh.glb
Normal file
BIN
assets/models/basicmesh.glb
Normal file
Binary file not shown.
58
flake.lock
generated
Normal file
58
flake.lock
generated
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
{
|
||||||
|
"nodes": {
|
||||||
|
"flake-utils": {
|
||||||
|
"inputs": {
|
||||||
|
"systems": "systems"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1731533236,
|
||||||
|
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1791366222,
|
||||||
|
"narHash": "sha256-/4ezBOv6aldGab7qTb6ls3SDpgzG8kuuSqEAA9zEZ8E=",
|
||||||
|
"rev": "39ad350a0602fa0a58a544344e3e9187526ea45c",
|
||||||
|
"type": "tarball",
|
||||||
|
"url": "https://releases.nixos.org/nixpkgs/nixpkgs-26.11pre1087089.39ad350a0602/nixexprs.tar.zst"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"id": "nixpkgs",
|
||||||
|
"type": "indirect"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": {
|
||||||
|
"inputs": {
|
||||||
|
"flake-utils": "flake-utils",
|
||||||
|
"nixpkgs": "nixpkgs"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"systems": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1681028828,
|
||||||
|
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": "root",
|
||||||
|
"version": 7
|
||||||
|
}
|
||||||
114
flake.nix
Normal file
114
flake.nix
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
{
|
||||||
|
description = "VulkanEngine development environment";
|
||||||
|
|
||||||
|
inputs = {
|
||||||
|
nixpkgs.url = "nixpkgs";
|
||||||
|
flake-utils.url = "github:numtide/flake-utils";
|
||||||
|
};
|
||||||
|
|
||||||
|
outputs = { self, nixpkgs, flake-utils }:
|
||||||
|
flake-utils.lib.eachDefaultSystem (system:
|
||||||
|
let
|
||||||
|
pkgs = import nixpkgs {
|
||||||
|
inherit system;
|
||||||
|
config.allowUnfree = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
vulkanPackages = with pkgs; [
|
||||||
|
vulkan-headers
|
||||||
|
vulkan-loader
|
||||||
|
vulkan-validation-layers
|
||||||
|
vulkan-tools
|
||||||
|
vulkan-utility-libraries
|
||||||
|
vulkan-memory-allocator
|
||||||
|
vulkan-volk
|
||||||
|
vk-bootstrap
|
||||||
|
];
|
||||||
|
|
||||||
|
developmentPackages = with pkgs; [
|
||||||
|
# Shaders
|
||||||
|
shader-slang
|
||||||
|
glslang
|
||||||
|
|
||||||
|
# Vulkan
|
||||||
|
vulkan-headers
|
||||||
|
vulkan-loader
|
||||||
|
vulkan-validation-layers
|
||||||
|
vulkan-tools
|
||||||
|
vulkan-utility-libraries
|
||||||
|
vulkan-memory-allocator
|
||||||
|
vulkan-volk
|
||||||
|
vk-bootstrap
|
||||||
|
|
||||||
|
# Windowing
|
||||||
|
glfw3
|
||||||
|
wayland
|
||||||
|
wayland-protocols
|
||||||
|
wayland-scanner
|
||||||
|
libxkbcommon
|
||||||
|
|
||||||
|
# Audio
|
||||||
|
libpulseaudio
|
||||||
|
libpulseaudio.dev
|
||||||
|
|
||||||
|
# Libraries
|
||||||
|
fmt
|
||||||
|
cli11
|
||||||
|
simdjson
|
||||||
|
glm
|
||||||
|
nlohmann_json
|
||||||
|
tinyobjloader
|
||||||
|
tinygltf
|
||||||
|
stb
|
||||||
|
|
||||||
|
# Build
|
||||||
|
cmake
|
||||||
|
ninja
|
||||||
|
pkg-config
|
||||||
|
|
||||||
|
# Debug
|
||||||
|
gdb
|
||||||
|
renderdoc
|
||||||
|
];
|
||||||
|
|
||||||
|
in {
|
||||||
|
devShells.default = pkgs.mkShell {
|
||||||
|
name = "vulkan-engine";
|
||||||
|
|
||||||
|
hardeningDisable = [
|
||||||
|
"fortify"
|
||||||
|
];
|
||||||
|
|
||||||
|
packages = developmentPackages;
|
||||||
|
|
||||||
|
VK_LAYER_PATH =
|
||||||
|
"${pkgs.vulkan-validation-layers}/share/vulkan/explicit_layer.d";
|
||||||
|
|
||||||
|
VULKAN_SDK =
|
||||||
|
"${pkgs.vulkan-validation-layers}";
|
||||||
|
|
||||||
|
shellHook = ''
|
||||||
|
export LD_LIBRARY_PATH="${pkgs.lib.makeLibraryPath [
|
||||||
|
pkgs.vulkan-loader
|
||||||
|
pkgs.wayland
|
||||||
|
pkgs.libxkbcommon
|
||||||
|
]}"
|
||||||
|
echo "VulkanEngine development environment"
|
||||||
|
echo "CMake: $(cmake --version | head -n1)"
|
||||||
|
echo "Ninja: $(ninja --version)"
|
||||||
|
echo "GCC: $(g++ --version | head -n1)"
|
||||||
|
echo "GLSLang: $(glslangValidator --version | head -n1)"
|
||||||
|
echo "Slang: $(slangc -v | head -n1)"
|
||||||
|
|
||||||
|
unset SOURCE_DATE_EPOCH
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
packages.engine =
|
||||||
|
pkgs.callPackage ./package.nix {};
|
||||||
|
|
||||||
|
packages.default =
|
||||||
|
self.packages.${system}.engine;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
1
include/CLI11
Submodule
1
include/CLI11
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit c1cfe00d2f3d862aecfe6e69ec810414d5f4c906
|
||||||
1
include/imgui
Submodule
1
include/imgui
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit d7cce3ad5070bbdbbd7a39335c0c1e90071211d0
|
||||||
117
package.nix
Normal file
117
package.nix
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
{ lib
|
||||||
|
, stdenv
|
||||||
|
, fetchFromGitHub
|
||||||
|
, fetchgit
|
||||||
|
, cmake
|
||||||
|
, ninja
|
||||||
|
, pkg-config
|
||||||
|
, glfw3
|
||||||
|
, glm
|
||||||
|
, vulkan-headers
|
||||||
|
, vulkan-loader
|
||||||
|
, vulkan-volk
|
||||||
|
, vulkan-utility-libraries
|
||||||
|
, vulkan-memory-allocator
|
||||||
|
, vk-bootstrap
|
||||||
|
, fmt
|
||||||
|
, cli11
|
||||||
|
, glslang
|
||||||
|
, shader-slang
|
||||||
|
, simdjson
|
||||||
|
, patchelf
|
||||||
|
}:
|
||||||
|
|
||||||
|
let
|
||||||
|
fs = lib.fileset;
|
||||||
|
fastgltf = fetchFromGitHub {
|
||||||
|
owner = "spnda";
|
||||||
|
repo = "fastgltf";
|
||||||
|
rev = "v0.8.0";
|
||||||
|
hash = "sha256-nPkVMrve1+04XRpSswBqjlSurliCFBRxR8Zxy4xZ5pE=";
|
||||||
|
};
|
||||||
|
imgui = fetchgit {
|
||||||
|
url = "https://git.alexdelcamp.fr/Alexandre_1a/imgui.git";
|
||||||
|
rev = "d7cce3ad5070bbdbbd7a39335c0c1e90071211d0";
|
||||||
|
hash = "sha256-2v085YFc17aj96YlOc4Fp8sJUHUmjRU8X54FnuqKrgc=";
|
||||||
|
};
|
||||||
|
in
|
||||||
|
stdenv.mkDerivation {
|
||||||
|
pname = "vulkan-engine";
|
||||||
|
version = "1.1.0";
|
||||||
|
src = ./.;
|
||||||
|
|
||||||
|
postUnpack = ''
|
||||||
|
# include/ peut ne pas exister du tout dans la copie flake
|
||||||
|
# (cas de figure ici), donc on le crée.
|
||||||
|
mkdir -p $sourceRoot/include
|
||||||
|
|
||||||
|
# On remplace les dossiers vides (ou absents) par les vraies sources
|
||||||
|
rm -rf $sourceRoot/include/imgui $sourceRoot/include/CLI11
|
||||||
|
cp -r ${imgui} $sourceRoot/include/imgui
|
||||||
|
|
||||||
|
# Autorise le write sur l'arbre : CMake va générer des fichiers
|
||||||
|
chmod -R u+w $sourceRoot
|
||||||
|
'';
|
||||||
|
|
||||||
|
|
||||||
|
nativeBuildInputs = [
|
||||||
|
cmake
|
||||||
|
ninja
|
||||||
|
pkg-config
|
||||||
|
glslang
|
||||||
|
shader-slang
|
||||||
|
];
|
||||||
|
|
||||||
|
buildInputs = [
|
||||||
|
glfw3
|
||||||
|
glm
|
||||||
|
vulkan-headers
|
||||||
|
vulkan-volk
|
||||||
|
vulkan-loader
|
||||||
|
vulkan-utility-libraries
|
||||||
|
vk-bootstrap
|
||||||
|
vulkan-memory-allocator
|
||||||
|
fmt
|
||||||
|
cli11
|
||||||
|
simdjson
|
||||||
|
];
|
||||||
|
|
||||||
|
cmakeFlags = [
|
||||||
|
"-DCMAKE_BUILD_TYPE=Release"
|
||||||
|
"-DCMAKE_EXPORT_COMPILE_COMMANDS=ON"
|
||||||
|
"-DFETCHCONTENT_SOURCE_DIR_FASTGLTF=${fastgltf}"
|
||||||
|
"-DFETCHCONTENT_FULLY_DISCONNECTED=ON"
|
||||||
|
];
|
||||||
|
|
||||||
|
postFixup = ''
|
||||||
|
patchelf --add-rpath ${lib.makeLibraryPath [ vulkan-loader ]} $out/bin/engine
|
||||||
|
'';
|
||||||
|
|
||||||
|
installPhase = ''
|
||||||
|
runHook preInstall
|
||||||
|
mkdir -p $out/bin
|
||||||
|
|
||||||
|
cp engine/engine $out/bin/engine
|
||||||
|
cp server/server $out/bin/server
|
||||||
|
|
||||||
|
# Copier les shaders compilés où qu'ils soient
|
||||||
|
if [ -d engine/shaders ]; then
|
||||||
|
cp -r engine/shaders $out/bin/shaders
|
||||||
|
elif [ -d $sourceRoot/engine/shaders ]; then
|
||||||
|
# fallback : sources, à compiler ? normalement non
|
||||||
|
cp -r $sourceRoot/engine/shaders $out/bin/shaders
|
||||||
|
else
|
||||||
|
echo "ERREUR : aucun dossier shaders trouvé" >&2
|
||||||
|
find . -name "*.spv" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
[ -d engine/models ] && cp -r engine/models $out/bin/models
|
||||||
|
[ -d engine/textures ] && cp -r engine/textures $out/bin/textures
|
||||||
|
[ -f engine/LICENSE ] && cp engine/LICENSE $out/bin/LICENSE
|
||||||
|
|
||||||
|
runHook postInstall
|
||||||
|
'';
|
||||||
|
|
||||||
|
meta.mainProgram = "engine";
|
||||||
|
}
|
||||||
@ -1,30 +0,0 @@
|
|||||||
static float2 positions[3] = float2[](
|
|
||||||
float2(0.0, -0.5),
|
|
||||||
float2(0.5, 0.5),
|
|
||||||
float2(-0.5, 0.5)
|
|
||||||
);
|
|
||||||
|
|
||||||
static float3 colors[3] = float3[] (
|
|
||||||
float3(1.0, 0.0, 0.0),
|
|
||||||
float3(0.0, 1.0, 0.0),
|
|
||||||
float3(0.0, 0.0, 1.0)
|
|
||||||
);
|
|
||||||
|
|
||||||
struct VertexOutput {
|
|
||||||
float3 color;
|
|
||||||
float4 sv_position : SV_Position;
|
|
||||||
};
|
|
||||||
|
|
||||||
[shader("vertex")]
|
|
||||||
VertexOutput vertMain(uint vid : SV_VertexID) {
|
|
||||||
VertexOutput output;
|
|
||||||
output.sv_position = float4(positions[vid], 0.0, 1.0);
|
|
||||||
output.color = colors[vid];
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
|
|
||||||
[shader("fragment")]
|
|
||||||
float4 fragMain(VertexOutput inVert) : SV_Target {
|
|
||||||
float3 color = inVert.color;
|
|
||||||
return float4(color, 1.0);
|
|
||||||
}
|
|
||||||
13
shaders/colored_triangle_fragment.frag
Normal file
13
shaders/colored_triangle_fragment.frag
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#version 450
|
||||||
|
|
||||||
|
//shader input
|
||||||
|
layout(location = 0) in vec3 inColor;
|
||||||
|
|
||||||
|
//output write
|
||||||
|
layout(location = 0) out vec4 outFragColor;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
//return red
|
||||||
|
outFragColor = vec4(inColor, 1.0f);
|
||||||
|
}
|
||||||
36
shaders/colored_triangle_mesh.vert
Normal file
36
shaders/colored_triangle_mesh.vert
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
#version 450
|
||||||
|
#extension GL_EXT_buffer_reference : require
|
||||||
|
|
||||||
|
layout(location = 0) out vec3 outColor;
|
||||||
|
layout(location = 1) out vec2 outUV;
|
||||||
|
|
||||||
|
struct Vertex {
|
||||||
|
vec3 position;
|
||||||
|
float uv_x;
|
||||||
|
vec3 normal;
|
||||||
|
float uv_y;
|
||||||
|
vec4 color;
|
||||||
|
};
|
||||||
|
|
||||||
|
layout(buffer_reference, std430) readonly buffer VertexBuffer {
|
||||||
|
Vertex vertices[];
|
||||||
|
};
|
||||||
|
|
||||||
|
//push constants block
|
||||||
|
layout(push_constant) uniform constants
|
||||||
|
{
|
||||||
|
mat4 render_matrix;
|
||||||
|
VertexBuffer vertexBuffer;
|
||||||
|
} PushConstants;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
//load vertex data from device adress
|
||||||
|
Vertex v = PushConstants.vertexBuffer.vertices[gl_VertexIndex];
|
||||||
|
|
||||||
|
//output data
|
||||||
|
gl_Position = PushConstants.render_matrix * vec4(v.position, 1.0f);
|
||||||
|
outColor = v.color.xyz;
|
||||||
|
outUV.x = v.uv_x;
|
||||||
|
outUV.y = v.uv_y;
|
||||||
|
}
|
||||||
24
shaders/colored_triangle_vertices.vert
Normal file
24
shaders/colored_triangle_vertices.vert
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#version 450
|
||||||
|
|
||||||
|
layout (location = 0) out vec3 outColor;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
//const array of positions for the triangle
|
||||||
|
const vec3 positions[3] = vec3[3](
|
||||||
|
vec3(1.f,1.f, 0.0f),
|
||||||
|
vec3(-1.f,1.f, 0.0f),
|
||||||
|
vec3(0.f,-1.f, 0.0f)
|
||||||
|
);
|
||||||
|
|
||||||
|
//const array of colors for the triangle
|
||||||
|
const vec3 colors[3] = vec3[3](
|
||||||
|
vec3(1.0f, 0.0f, 0.0f), //red
|
||||||
|
vec3(0.0f, 1.0f, 0.0f), //green
|
||||||
|
vec3(00.f, 0.0f, 1.0f) //blue
|
||||||
|
);
|
||||||
|
|
||||||
|
//output the position of each vertex
|
||||||
|
gl_Position = vec4(positions[gl_VertexIndex], 1.0f);
|
||||||
|
outColor = colors[gl_VertexIndex];
|
||||||
|
}
|
||||||
@ -1,8 +1,31 @@
|
|||||||
|
/*
|
||||||
|
Todo:
|
||||||
|
The timestamp is not in localtime,
|
||||||
|
fix or disclaim
|
||||||
|
*/
|
||||||
#ifndef LOGGER_H
|
#ifndef LOGGER_H
|
||||||
#define LOGGER_H
|
#define LOGGER_H
|
||||||
|
|
||||||
// Custom includes
|
// Custom includes
|
||||||
|
|
||||||
|
|
||||||
|
// Enums
|
||||||
|
enum class LogModule {
|
||||||
|
ENGINE,
|
||||||
|
RENDERER,
|
||||||
|
GLFW,
|
||||||
|
CLEANUP
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class LogLevel {
|
||||||
|
EDEBUG,
|
||||||
|
EINIT, // Initialization related
|
||||||
|
EINFO, // General infos
|
||||||
|
EWARN,
|
||||||
|
EERROR,
|
||||||
|
EFATAL
|
||||||
|
};
|
||||||
|
|
||||||
class NetLogger {
|
class NetLogger {
|
||||||
public:
|
public:
|
||||||
struct Server{
|
struct Server{
|
||||||
@ -17,7 +40,79 @@ class NetLogger {
|
|||||||
void logNetAsync(); // Todo
|
void logNetAsync(); // Todo
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class Logger {
|
||||||
|
public:
|
||||||
|
// Members
|
||||||
|
std::string logBuffer; // Log is empty by default
|
||||||
|
std::vector<std::string_view> lines;
|
||||||
|
|
||||||
|
// Functions
|
||||||
|
template<typename... Args>
|
||||||
|
void logDisk(
|
||||||
|
LogModule module,
|
||||||
|
LogLevel level,
|
||||||
|
std::string_view message,
|
||||||
|
Args&&... args
|
||||||
|
); // Logs to a file on disk
|
||||||
|
// Overload
|
||||||
|
void logDisk(std::string_view message);
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
void logRAM(
|
||||||
|
LogModule module,
|
||||||
|
LogLevel level,
|
||||||
|
std::string_view message,
|
||||||
|
Args&&... args
|
||||||
|
); // Logs to ram (ImGUI)
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
void logConsole(
|
||||||
|
LogModule module,
|
||||||
|
LogLevel level,
|
||||||
|
std::string_view message,
|
||||||
|
Args&&... args
|
||||||
|
); // Logs to the console (crashes, etc...)
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
void logAll(
|
||||||
|
LogModule module,
|
||||||
|
LogLevel level,
|
||||||
|
std::string_view message,
|
||||||
|
Args&&... args
|
||||||
|
); // Logs using all of the above, RAM then console and finally disk, maybe multithread (?)
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
void logImportant(
|
||||||
|
LogModule module,
|
||||||
|
LogLevel level,
|
||||||
|
std::string_view message,
|
||||||
|
Args&&... args
|
||||||
|
); // Logs to console and file, in cases of crashes or errors
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
void logFatal(
|
||||||
|
LogModule module,
|
||||||
|
std::string_view message,
|
||||||
|
Args&&... args
|
||||||
|
); // Logs to console and file, then abort -> Core dump
|
||||||
|
|
||||||
|
|
||||||
|
// Utils functions
|
||||||
|
void merge(std::string_view source); // Merges a source dumped logs into this
|
||||||
|
|
||||||
|
void logSeparator();
|
||||||
|
|
||||||
|
void clear();
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Helper functions
|
||||||
|
static std::string_view moduleToString(LogModule m);
|
||||||
|
static std::string_view levelToString(LogLevel l);
|
||||||
|
inline std::string formatTimestamp(
|
||||||
|
std::chrono::system_clock::time_point tp
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // End of header
|
#endif // End of header
|
||||||
@ -29,12 +124,271 @@ class NetLogger {
|
|||||||
// Implementation
|
// Implementation
|
||||||
|
|
||||||
// Includes
|
// Includes
|
||||||
#include <httplib.h> // Todo : add it in the flake
|
//#include <httplib.h> // Todo : add it in the flake
|
||||||
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
#include <chrono>
|
||||||
|
|
||||||
|
/*
|
||||||
void NetLogger::initNetLogger(Server server) {
|
void NetLogger::initNetLogger(Server server) {
|
||||||
httplib::Client cli(server.url)
|
httplib::Client cli(server.url)
|
||||||
// Todo : add error handling
|
// Todo : add error handling
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
template<typename... Args>
|
||||||
|
void Logger::logRAM(
|
||||||
|
LogModule module,
|
||||||
|
LogLevel level,
|
||||||
|
std::string_view message,
|
||||||
|
Args&&... args
|
||||||
|
) {
|
||||||
|
auto now { std::chrono::system_clock::now() };
|
||||||
|
auto timestamp = formatTimestamp(now);
|
||||||
|
auto start = logBuffer.size();
|
||||||
|
|
||||||
|
fmt::format_to(
|
||||||
|
std::back_inserter(logBuffer),
|
||||||
|
"[{}] ",
|
||||||
|
timestamp
|
||||||
|
);
|
||||||
|
|
||||||
|
fmt::format_to(
|
||||||
|
std::back_inserter(logBuffer),
|
||||||
|
"[{}:{}] ",
|
||||||
|
moduleToString(module),
|
||||||
|
levelToString(level)
|
||||||
|
);
|
||||||
|
|
||||||
|
fmt::format_to(
|
||||||
|
std::back_inserter(logBuffer),
|
||||||
|
fmt::runtime(message),
|
||||||
|
std::forward<Args>(args)...
|
||||||
|
);
|
||||||
|
|
||||||
|
logBuffer.push_back('\n');
|
||||||
|
auto end = logBuffer.size();
|
||||||
|
lines.emplace_back(logBuffer.data() + start, end - start);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
void Logger::logConsole(
|
||||||
|
LogModule module,
|
||||||
|
LogLevel level,
|
||||||
|
std::string_view message,
|
||||||
|
Args&&... args
|
||||||
|
) {
|
||||||
|
std::string tempBuffer;
|
||||||
|
auto now = std::chrono::system_clock::now();
|
||||||
|
auto timestamp = formatTimestamp(now);
|
||||||
|
|
||||||
|
fmt::format_to(
|
||||||
|
std::back_inserter(tempBuffer),
|
||||||
|
"[{}] ",
|
||||||
|
timestamp
|
||||||
|
);
|
||||||
|
|
||||||
|
fmt::format_to(
|
||||||
|
std::back_inserter(tempBuffer),
|
||||||
|
"[{}:{}] ",
|
||||||
|
moduleToString(module),
|
||||||
|
levelToString(level)
|
||||||
|
);
|
||||||
|
|
||||||
|
fmt::format_to(
|
||||||
|
std::back_inserter(tempBuffer),
|
||||||
|
fmt::runtime(message),
|
||||||
|
std::forward<Args>(args)...
|
||||||
|
);
|
||||||
|
|
||||||
|
std::cout.write(tempBuffer.data(), tempBuffer.size());
|
||||||
|
std::cout.put('\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
void Logger::logDisk(
|
||||||
|
LogModule module,
|
||||||
|
LogLevel level,
|
||||||
|
std::string_view message,
|
||||||
|
Args&&... args
|
||||||
|
) {
|
||||||
|
// Open the logfile
|
||||||
|
std::ofstream logFile ("log.txt", std::ios::out | std::ios::app);
|
||||||
|
|
||||||
|
if (!logFile.good()) {
|
||||||
|
throw std::runtime_error("Failed to open logfile !");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a temporary buffer
|
||||||
|
std::string tempBuffer;
|
||||||
|
auto now = std::chrono::system_clock::now();
|
||||||
|
auto timestamp = formatTimestamp(now);
|
||||||
|
|
||||||
|
fmt::format_to(
|
||||||
|
std::back_inserter(tempBuffer),
|
||||||
|
"[{}] ",
|
||||||
|
timestamp
|
||||||
|
);
|
||||||
|
|
||||||
|
fmt::format_to(
|
||||||
|
std::back_inserter(tempBuffer),
|
||||||
|
"[{}:{}] ",
|
||||||
|
moduleToString(module),
|
||||||
|
levelToString(level)
|
||||||
|
);
|
||||||
|
|
||||||
|
fmt::format_to(
|
||||||
|
std::back_inserter(tempBuffer),
|
||||||
|
fmt::runtime(message),
|
||||||
|
std::forward<Args>(args)...
|
||||||
|
);
|
||||||
|
|
||||||
|
logFile << tempBuffer << '\n';
|
||||||
|
logFile.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Overload to inject a message
|
||||||
|
void Logger::logDisk(std::string_view message) {
|
||||||
|
std::ofstream logFile ("log.txt", std::ios::out | std::ios::app);
|
||||||
|
|
||||||
|
if (!logFile.good()) {
|
||||||
|
throw std::runtime_error("Failed to open logfile !");
|
||||||
|
}
|
||||||
|
|
||||||
|
logFile << message << '\n';
|
||||||
|
logFile.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
void Logger::logAll(
|
||||||
|
LogModule module,
|
||||||
|
LogLevel level,
|
||||||
|
std::string_view message,
|
||||||
|
Args&&... args
|
||||||
|
) {
|
||||||
|
// Logs to all targets !
|
||||||
|
logRAM(
|
||||||
|
module,
|
||||||
|
level,
|
||||||
|
message,
|
||||||
|
args...
|
||||||
|
);
|
||||||
|
|
||||||
|
logConsole(
|
||||||
|
module,
|
||||||
|
level,
|
||||||
|
message,
|
||||||
|
args...
|
||||||
|
);
|
||||||
|
|
||||||
|
logDisk(
|
||||||
|
module,
|
||||||
|
level,
|
||||||
|
message,
|
||||||
|
args...
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
void Logger::logImportant(
|
||||||
|
LogModule module,
|
||||||
|
LogLevel level,
|
||||||
|
std::string_view message,
|
||||||
|
Args&&... args
|
||||||
|
) {
|
||||||
|
logDisk(
|
||||||
|
module,
|
||||||
|
level,
|
||||||
|
message,
|
||||||
|
args...
|
||||||
|
);
|
||||||
|
|
||||||
|
logConsole(
|
||||||
|
module,
|
||||||
|
level,
|
||||||
|
message,
|
||||||
|
args...
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
void Logger::logFatal(
|
||||||
|
LogModule module,
|
||||||
|
std::string_view message,
|
||||||
|
Args&&... args
|
||||||
|
) {
|
||||||
|
// Separator
|
||||||
|
logDisk("================================== CRASH LOGS ==================================");
|
||||||
|
|
||||||
|
logDisk(
|
||||||
|
module,
|
||||||
|
LogLevel::EFATAL,
|
||||||
|
message,
|
||||||
|
args...
|
||||||
|
);
|
||||||
|
|
||||||
|
logConsole(
|
||||||
|
module,
|
||||||
|
LogLevel::EFATAL,
|
||||||
|
message,
|
||||||
|
args...
|
||||||
|
);
|
||||||
|
|
||||||
|
logSeparator();
|
||||||
|
|
||||||
|
std::abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Logger::merge(std::string_view source) {
|
||||||
|
/*
|
||||||
|
This merges a dumped logger into this one
|
||||||
|
Assumes the other logger is already formated.
|
||||||
|
This allows to add arbitrary strings into the logs
|
||||||
|
*/
|
||||||
|
logBuffer += source;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Logger::logSeparator() {
|
||||||
|
logDisk("================================================================================");
|
||||||
|
}
|
||||||
|
|
||||||
|
void Logger::clear() {
|
||||||
|
logBuffer.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string_view Logger::moduleToString(LogModule m) {
|
||||||
|
using enum LogModule;
|
||||||
|
switch (m) {
|
||||||
|
case ENGINE: return "Engine";
|
||||||
|
case RENDERER: return "Renderer";
|
||||||
|
case GLFW: return "GLFW";
|
||||||
|
case CLEANUP: return "CLEANUP";
|
||||||
|
default: return "Unkown";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string_view Logger::levelToString(LogLevel l) {
|
||||||
|
using enum LogLevel;
|
||||||
|
switch (l) {
|
||||||
|
case EDEBUG: return "Debug";
|
||||||
|
case EINFO: return "Info";
|
||||||
|
case EINIT: return "Init";
|
||||||
|
case EWARN: return "Warn";
|
||||||
|
case EERROR: return "Error";
|
||||||
|
case EFATAL: return "Fatal";
|
||||||
|
default: return "???";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Logger::formatTimestamp(
|
||||||
|
std::chrono::system_clock::time_point tp
|
||||||
|
) {
|
||||||
|
std::time_t t = std::chrono::system_clock::to_time_t(tp);
|
||||||
|
std::tm tm{};
|
||||||
|
localtime_r(&t, &tm);
|
||||||
|
return fmt::format("{:%Y-%m-%d %H:%M}", tm);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -12,19 +12,25 @@
|
|||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <fmt/base.h>
|
#include <fmt/base.h>
|
||||||
|
#include <fmt/format.h>
|
||||||
|
#include <fmt/chrono.h>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
#include <vulkan/vulkan.h>
|
#include <volk.h>
|
||||||
#include <vulkan/vulkan_core.h>
|
#include <vulkan/vulkan_core.h>
|
||||||
#include <vulkan/vk_enum_string_helper.h>
|
#include <vulkan/vk_enum_string_helper.h>
|
||||||
#include <vk_mem_alloc.h>
|
#include <vk_mem_alloc.h>
|
||||||
|
|
||||||
#define GLFW_INCLUDE_VULKAN
|
//#define GLFW_INCLUDE_NONE
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
|
#define GLM_ENABLE_EXPERIMENTAL
|
||||||
|
#define GLM_FORCE_DEPTH_ZERO_TO_ONE
|
||||||
|
#define GLM_FORCE_RADIANS
|
||||||
#include <glm/mat4x4.hpp>
|
#include <glm/mat4x4.hpp>
|
||||||
#include <glm/vec4.hpp>
|
#include <glm/vec4.hpp>
|
||||||
|
#include <glm/gtx/transform.hpp>
|
||||||
|
|
||||||
// Custom headers
|
// Custom headers
|
||||||
//#include "callbacks.h"
|
//#include "callbacks.h"
|
||||||
@ -41,9 +47,16 @@
|
|||||||
} \
|
} \
|
||||||
} while (0) \
|
} while (0) \
|
||||||
|
|
||||||
|
// Enums
|
||||||
|
enum class RenderRez {
|
||||||
|
FIT,
|
||||||
|
R800x800,
|
||||||
|
R720p,
|
||||||
|
R1080p,
|
||||||
|
R2k
|
||||||
|
};
|
||||||
|
|
||||||
// Custom types
|
// Custom types
|
||||||
|
|
||||||
struct DeletionQueue {
|
struct DeletionQueue {
|
||||||
std::deque<std::function<void()>> deletors;
|
std::deque<std::function<void()>> deletors;
|
||||||
|
|
||||||
@ -74,6 +87,42 @@ struct AllocatedImage {
|
|||||||
VkFormat imageFormat;
|
VkFormat imageFormat;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct AllocatedBuffer {
|
||||||
|
VkBuffer buffer;
|
||||||
|
VmaAllocation allocation;
|
||||||
|
VmaAllocationInfo info;
|
||||||
|
uint32_t size; // In bytes
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Vertex {
|
||||||
|
alignas(16) glm::vec3 position;
|
||||||
|
float uv_x;
|
||||||
|
alignas(16) glm::vec3 normal;
|
||||||
|
float uv_y;
|
||||||
|
glm::vec4 color;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Holds the ressouces required for a mesh
|
||||||
|
struct GPUMeshBuffers {
|
||||||
|
AllocatedBuffer indexBuffer;
|
||||||
|
AllocatedBuffer vertexBuffer;
|
||||||
|
VkDeviceAddress vertexBufferAddress;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GPUDrawPushConstants {
|
||||||
|
glm::mat4 worldMatrix;
|
||||||
|
VkDeviceAddress vertexBuffer;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Engine config
|
||||||
|
struct EngineConfig {
|
||||||
|
int gpuIndex {-1};
|
||||||
|
std::string modelPath;
|
||||||
|
};
|
||||||
|
|
||||||
|
// "Global" ? (I hope so) logger
|
||||||
|
Logger logger;
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@ -17,7 +17,7 @@ class Callback {
|
|||||||
|
|
||||||
void Callback::keyboardCallback(GLFWwindow* window, int key, int scancode, int action, int mods) {
|
void Callback::keyboardCallback(GLFWwindow* window, int key, int scancode, int action, int mods) {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fmt::println("[Engine:Info] Key pressed, key {}", key);
|
logger.logRAM(LogModule::GLFW, LogLevel::EINFO, "Key pressed, key {}", key);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -2,6 +2,7 @@
|
|||||||
#define INITIALIZERS_H
|
#define INITIALIZERS_H
|
||||||
// Normal header
|
// Normal header
|
||||||
#include "Common/Types.h"
|
#include "Common/Types.h"
|
||||||
|
#include "simdjson.h"
|
||||||
#include <vulkan/vulkan_core.h>
|
#include <vulkan/vulkan_core.h>
|
||||||
|
|
||||||
namespace vkinit {
|
namespace vkinit {
|
||||||
@ -64,12 +65,19 @@ namespace vkinit {
|
|||||||
VkImageLayout layout /*= VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL*/
|
VkImageLayout layout /*= VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL*/
|
||||||
);
|
);
|
||||||
|
|
||||||
|
VkRenderingAttachmentInfo depthAttachmentInfo(
|
||||||
|
VkImageView view,
|
||||||
|
VkImageLayout layout
|
||||||
|
);
|
||||||
|
|
||||||
VkRenderingInfo renderingInfo(
|
VkRenderingInfo renderingInfo(
|
||||||
VkExtent2D renderExtent,
|
VkExtent2D renderExtent,
|
||||||
VkRenderingAttachmentInfo* colorAttachment,
|
VkRenderingAttachmentInfo* colorAttachment,
|
||||||
VkRenderingAttachmentInfo* depthAttachment
|
VkRenderingAttachmentInfo* depthAttachment
|
||||||
);
|
);
|
||||||
|
|
||||||
|
VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo();
|
||||||
|
|
||||||
VkPipelineShaderStageCreateInfo pipelineShaderStageCreateInfo(
|
VkPipelineShaderStageCreateInfo pipelineShaderStageCreateInfo(
|
||||||
VkShaderStageFlagBits stage,
|
VkShaderStageFlagBits stage,
|
||||||
VkShaderModule shaderModule,
|
VkShaderModule shaderModule,
|
||||||
@ -287,6 +295,27 @@ namespace vkinit {
|
|||||||
return colorAttachment;
|
return colorAttachment;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VkRenderingAttachmentInfo depthAttachmentInfo(
|
||||||
|
VkImageView view,
|
||||||
|
VkImageLayout layout
|
||||||
|
) {
|
||||||
|
VkRenderingAttachmentInfo depthAttachment {
|
||||||
|
.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
|
||||||
|
.pNext = nullptr,
|
||||||
|
.imageView = view,
|
||||||
|
.imageLayout = layout,
|
||||||
|
.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR,
|
||||||
|
.storeOp = VK_ATTACHMENT_STORE_OP_STORE,
|
||||||
|
.clearValue = {
|
||||||
|
.depthStencil = {
|
||||||
|
.depth = 0.0f
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return depthAttachment;
|
||||||
|
}
|
||||||
|
|
||||||
VkRenderingInfo renderingInfo(
|
VkRenderingInfo renderingInfo(
|
||||||
VkExtent2D renderExtent,
|
VkExtent2D renderExtent,
|
||||||
VkRenderingAttachmentInfo* colorAttachment,
|
VkRenderingAttachmentInfo* colorAttachment,
|
||||||
@ -310,6 +339,21 @@ namespace vkinit {
|
|||||||
return renderInfo;
|
return renderInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo() {
|
||||||
|
VkPipelineLayoutCreateInfo info {
|
||||||
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
|
||||||
|
.pNext = nullptr,
|
||||||
|
// Empty defaults
|
||||||
|
.flags = 0,
|
||||||
|
.setLayoutCount = 0,
|
||||||
|
.pSetLayouts = nullptr,
|
||||||
|
.pushConstantRangeCount = 0,
|
||||||
|
.pPushConstantRanges = nullptr,
|
||||||
|
};
|
||||||
|
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
VkPipelineShaderStageCreateInfo pipelineShaderStageCreateInfo(
|
VkPipelineShaderStageCreateInfo pipelineShaderStageCreateInfo(
|
||||||
VkShaderStageFlagBits stage,
|
VkShaderStageFlagBits stage,
|
||||||
VkShaderModule shaderModule,
|
VkShaderModule shaderModule,
|
||||||
|
|||||||
197
src/Engine/engine/loader.h
Normal file
197
src/Engine/engine/loader.h
Normal file
@ -0,0 +1,197 @@
|
|||||||
|
#ifndef LOADER_H
|
||||||
|
#define LOADER_H
|
||||||
|
// Header
|
||||||
|
// Custom includes
|
||||||
|
#include "Common/Types.h"
|
||||||
|
// Other includes
|
||||||
|
#include <cstdint>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <filesystem>
|
||||||
|
|
||||||
|
// Stucts
|
||||||
|
struct GeoSurface {
|
||||||
|
uint32_t startIndex;
|
||||||
|
uint32_t count;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct MeshAsset {
|
||||||
|
std::string name;
|
||||||
|
|
||||||
|
std::vector<GeoSurface> surfaces;
|
||||||
|
GPUMeshBuffers meshBuffers;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Forward declaration
|
||||||
|
|
||||||
|
class Engine;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef LOADER_IMPL
|
||||||
|
#ifndef LOADER_IMPL_H
|
||||||
|
#define LOADER_IMPL_H
|
||||||
|
// Main code file
|
||||||
|
// Includes
|
||||||
|
#include <fastgltf/core.hpp>
|
||||||
|
#include <fastgltf/types.hpp>
|
||||||
|
#include <fastgltf/glm_element_traits.hpp>
|
||||||
|
#include <fastgltf/tools.hpp>
|
||||||
|
|
||||||
|
constexpr bool OverrideColors = true;
|
||||||
|
|
||||||
|
std::optional<std::vector<std::shared_ptr<MeshAsset>>> loadGltfMeshes(
|
||||||
|
Engine* engine,
|
||||||
|
std::filesystem::path filePath
|
||||||
|
) {
|
||||||
|
// Todo:
|
||||||
|
// Use util functions for attributes
|
||||||
|
auto& logger = engine->_logger; // Uses the main logger
|
||||||
|
logger.logAll(LogModule::ENGINE, LogLevel::EINFO, "Loading GLTF: {}", filePath.string());
|
||||||
|
|
||||||
|
fastgltf::Parser parser;
|
||||||
|
fastgltf::Asset gltf;
|
||||||
|
auto data = fastgltf::GltfDataBuffer::FromPath(filePath);
|
||||||
|
|
||||||
|
constexpr auto gltfOptions {
|
||||||
|
fastgltf::Options::LoadExternalBuffers
|
||||||
|
};
|
||||||
|
|
||||||
|
auto load = parser.loadGltf(
|
||||||
|
data.get(),
|
||||||
|
filePath.parent_path(),
|
||||||
|
gltfOptions
|
||||||
|
);
|
||||||
|
|
||||||
|
if(load) {
|
||||||
|
gltf = std::move(load.get());
|
||||||
|
} else {
|
||||||
|
logger.logFatal(LogModule::ENGINE, "Failed to load gltf: {}", fastgltf::to_underlying(load.error()));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::shared_ptr<MeshAsset>> meshes;
|
||||||
|
// Use the same vectors for all meshes
|
||||||
|
// so that the memory doesn't reallocate
|
||||||
|
// as often
|
||||||
|
|
||||||
|
std::vector<uint32_t> indices;
|
||||||
|
std::vector<Vertex> vertices;
|
||||||
|
|
||||||
|
// Now, some gltf gymnastics to get data into the correct buffers.
|
||||||
|
/*
|
||||||
|
====================================
|
||||||
|
The following comments are notes,
|
||||||
|
to help me build the loader,
|
||||||
|
based on the new fastgltf api
|
||||||
|
(the vkguide is using an older api)
|
||||||
|
====================================
|
||||||
|
By reading the vkguide, I can see that
|
||||||
|
he's iterating on "gltf" which is an Asset.
|
||||||
|
In the official docs, it is stated we can get direct
|
||||||
|
references to the Asset class, using pointers (->)
|
||||||
|
For exemple with buffers: asset->buffers
|
||||||
|
*/
|
||||||
|
for(fastgltf::Mesh& mesh : gltf.meshes) { // Perhaps error ?
|
||||||
|
MeshAsset newmesh;
|
||||||
|
|
||||||
|
newmesh.name = mesh.name;
|
||||||
|
|
||||||
|
// Clear the arrays for memory optimizations
|
||||||
|
indices.clear();
|
||||||
|
vertices.clear();
|
||||||
|
|
||||||
|
for(auto&& p : mesh.primitives) { // 100% Error, use pointers ig ?
|
||||||
|
GeoSurface newSurface;
|
||||||
|
newSurface.startIndex = (uint32_t)indices.size();
|
||||||
|
newSurface.count = (uint32_t)gltf.accessors[p.indicesAccessor.value()].count;
|
||||||
|
|
||||||
|
size_t initialVTX = vertices.size();
|
||||||
|
|
||||||
|
// -- Indices --
|
||||||
|
{
|
||||||
|
fastgltf::Accessor& indexAccessor = gltf.accessors[p.indicesAccessor.value()];
|
||||||
|
indices.reserve(indices.size() + indexAccessor.count); // Memory alloc ig ?
|
||||||
|
|
||||||
|
fastgltf::iterateAccessor<std::uint32_t>(gltf, indexAccessor,
|
||||||
|
[&](std::uint32_t idx) {
|
||||||
|
indices.push_back(idx + initialVTX);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- Vertex Positions --
|
||||||
|
{
|
||||||
|
auto posIt = p.findAttribute("POSITION");
|
||||||
|
if (posIt == p.attributes.end()) {
|
||||||
|
logger.logFatal(LogModule::ENGINE, "Primitive without POSITION attribute");
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
fastgltf::Accessor& posAccessor = gltf.accessors[posIt->accessorIndex];
|
||||||
|
vertices.resize(vertices.size() + posAccessor.count);
|
||||||
|
|
||||||
|
fastgltf::iterateAccessorWithIndex<glm::vec3>(gltf, posAccessor,
|
||||||
|
[&](glm::vec3 v, size_t index) {
|
||||||
|
Vertex newvtx;
|
||||||
|
newvtx.position = v;
|
||||||
|
newvtx.normal = { 1.0f, 0.0f, 0.0f };
|
||||||
|
newvtx.color = glm::vec4(1.0f);
|
||||||
|
newvtx.uv_x = 0.0f;
|
||||||
|
newvtx.uv_y = 0.0f;
|
||||||
|
vertices[initialVTX + index] = newvtx;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Normals ---
|
||||||
|
if (auto normals = p.findAttribute("NORMAL"); normals != p.attributes.end()) {
|
||||||
|
fastgltf::iterateAccessorWithIndex<glm::vec3>(gltf, gltf.accessors[normals->accessorIndex],
|
||||||
|
[&](glm::vec3 v, size_t index) {
|
||||||
|
vertices[initialVTX + index].normal = v;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- UVs ---
|
||||||
|
if (auto uv = p.findAttribute("TEXCOORD_0"); uv != p.attributes.end()) {
|
||||||
|
fastgltf::iterateAccessorWithIndex<glm::vec2>(gltf, gltf.accessors[uv->accessorIndex],
|
||||||
|
[&](glm::vec2 v, size_t index) {
|
||||||
|
vertices[initialVTX + index].uv_x = v.x;
|
||||||
|
vertices[initialVTX + index].uv_y = v.y;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Vertex Colors ---
|
||||||
|
if (auto colors = p.findAttribute("COLOR_0"); colors != p.attributes.end()) {
|
||||||
|
fastgltf::iterateAccessorWithIndex<glm::vec4>(gltf, gltf.accessors[colors->accessorIndex],
|
||||||
|
[&](glm::vec4 v, size_t index) {
|
||||||
|
vertices[initialVTX + index].color = v;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
newmesh.surfaces.push_back(newSurface);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Display vertex normals
|
||||||
|
if (OverrideColors) {
|
||||||
|
for (Vertex& vtx : vertices) {
|
||||||
|
vtx.color = glm::vec4(vtx.normal, 1.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
newmesh.meshBuffers = engine->uploadMesh(indices, vertices);
|
||||||
|
meshes.emplace_back(std::make_shared<MeshAsset>(std::move(newmesh)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Debug things
|
||||||
|
#ifdef DEBUG
|
||||||
|
if(fastgltf::validate(load.get()) != fastgltf::Error::None) {
|
||||||
|
logger.logFatal(LogModule::ENGINE, "gltf file is not up to spec !");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return meshes;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
@ -1,3 +1,8 @@
|
|||||||
|
/*
|
||||||
|
Todo:
|
||||||
|
Create a temporary struct, to have the correct structure
|
||||||
|
then copy it to the class member
|
||||||
|
*/
|
||||||
#ifndef PIPELINES_H
|
#ifndef PIPELINES_H
|
||||||
#define PIPELINES_H
|
#define PIPELINES_H
|
||||||
// Normal header
|
// Normal header
|
||||||
@ -28,6 +33,7 @@ class PipelineBuilder {
|
|||||||
VkPipelineLayout _pipelineLayout;
|
VkPipelineLayout _pipelineLayout;
|
||||||
VkPipelineDepthStencilStateCreateInfo _depthStencil;
|
VkPipelineDepthStencilStateCreateInfo _depthStencil;
|
||||||
VkPipelineRenderingCreateInfo _renderInfo;
|
VkPipelineRenderingCreateInfo _renderInfo;
|
||||||
|
VkFormat _colorAttachmentFormat;
|
||||||
|
|
||||||
PipelineBuilder() { clear(); }
|
PipelineBuilder() { clear(); }
|
||||||
|
|
||||||
@ -57,6 +63,8 @@ class PipelineBuilder {
|
|||||||
|
|
||||||
void setMultisamplingNone();
|
void setMultisamplingNone();
|
||||||
|
|
||||||
|
void enableBlendingAdditive();
|
||||||
|
void enableBlendingAlphaBlend();
|
||||||
void disableBlending();
|
void disableBlending();
|
||||||
|
|
||||||
void setColorAttachmentFormat(
|
void setColorAttachmentFormat(
|
||||||
@ -68,6 +76,10 @@ class PipelineBuilder {
|
|||||||
);
|
);
|
||||||
|
|
||||||
void disableDepthtest();
|
void disableDepthtest();
|
||||||
|
void enableDepthtest(
|
||||||
|
bool depthWriteEnable,
|
||||||
|
VkCompareOp op
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@ -323,6 +335,28 @@ void PipelineBuilder::setMultisamplingNone() {
|
|||||||
_multisampling.alphaToOneEnable = VK_FALSE;
|
_multisampling.alphaToOneEnable = VK_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PipelineBuilder::enableBlendingAdditive() {
|
||||||
|
_colorBlendAttachment.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
|
||||||
|
_colorBlendAttachment.blendEnable = VK_TRUE;
|
||||||
|
_colorBlendAttachment.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
|
||||||
|
_colorBlendAttachment.dstColorBlendFactor = VK_BLEND_FACTOR_ONE;
|
||||||
|
_colorBlendAttachment.colorBlendOp = VK_BLEND_OP_ADD;
|
||||||
|
_colorBlendAttachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
|
||||||
|
_colorBlendAttachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
|
||||||
|
_colorBlendAttachment.alphaBlendOp = VK_BLEND_OP_ADD;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PipelineBuilder::enableBlendingAlphaBlend() {
|
||||||
|
_colorBlendAttachment.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
|
||||||
|
_colorBlendAttachment.blendEnable = VK_TRUE;
|
||||||
|
_colorBlendAttachment.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
|
||||||
|
_colorBlendAttachment.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
|
||||||
|
_colorBlendAttachment.colorBlendOp = VK_BLEND_OP_ADD;
|
||||||
|
_colorBlendAttachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
|
||||||
|
_colorBlendAttachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
|
||||||
|
_colorBlendAttachment.alphaBlendOp = VK_BLEND_OP_ADD;
|
||||||
|
}
|
||||||
|
|
||||||
void PipelineBuilder::disableBlending() {
|
void PipelineBuilder::disableBlending() {
|
||||||
// Default write mask
|
// Default write mask
|
||||||
_colorBlendAttachment.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
|
_colorBlendAttachment.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
|
||||||
@ -330,6 +364,15 @@ void PipelineBuilder::disableBlending() {
|
|||||||
_colorBlendAttachment.blendEnable = VK_FALSE;
|
_colorBlendAttachment.blendEnable = VK_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PipelineBuilder::setColorAttachmentFormat(
|
||||||
|
VkFormat format
|
||||||
|
) {
|
||||||
|
_colorAttachmentFormat = format;
|
||||||
|
// connect the format to the renderInfo structure
|
||||||
|
_renderInfo.colorAttachmentCount = 1;
|
||||||
|
_renderInfo.pColorAttachmentFormats = &_colorAttachmentFormat;
|
||||||
|
}
|
||||||
|
|
||||||
void PipelineBuilder::setDepthFormat(
|
void PipelineBuilder::setDepthFormat(
|
||||||
VkFormat format
|
VkFormat format
|
||||||
) {
|
) {
|
||||||
@ -348,5 +391,20 @@ void PipelineBuilder::disableDepthtest() {
|
|||||||
_depthStencil.maxDepthBounds = 1.0f;
|
_depthStencil.maxDepthBounds = 1.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PipelineBuilder::enableDepthtest(
|
||||||
|
bool depthWriteEnable,
|
||||||
|
VkCompareOp op
|
||||||
|
) {
|
||||||
|
_depthStencil.depthTestEnable = VK_TRUE;
|
||||||
|
_depthStencil.depthWriteEnable = depthWriteEnable;
|
||||||
|
_depthStencil.depthCompareOp = op;
|
||||||
|
_depthStencil.depthBoundsTestEnable = VK_FALSE;
|
||||||
|
_depthStencil.stencilTestEnable = VK_FALSE;
|
||||||
|
_depthStencil.front = {};
|
||||||
|
_depthStencil.back = {};
|
||||||
|
_depthStencil.minDepthBounds = 0.0f;
|
||||||
|
_depthStencil.maxDepthBounds = 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -1,18 +1,99 @@
|
|||||||
|
/*
|
||||||
|
Copyright Alexandre Delcamp-Enache, 2026
|
||||||
|
Based on vkguide.dev
|
||||||
|
See engine.h for extensive documentation
|
||||||
|
Also, checkout the roadmap
|
||||||
|
*/
|
||||||
#define ENGINE_IMPL
|
#define ENGINE_IMPL
|
||||||
#include "engine/engine.h"
|
#include "engine/engine.h"
|
||||||
|
|
||||||
|
#include "CLI/CLI.hpp"
|
||||||
|
|
||||||
|
class ArgHandler {
|
||||||
|
public:
|
||||||
|
CLI::App* _run;
|
||||||
|
// All options
|
||||||
|
bool _listGPU {false};
|
||||||
|
EngineConfig config;
|
||||||
|
|
||||||
|
|
||||||
|
void buildArgs() {
|
||||||
|
// Setup
|
||||||
|
// Subcommands
|
||||||
|
_run = _app.add_subcommand("run");
|
||||||
|
|
||||||
|
// Main options/flags
|
||||||
|
_app.add_flag("--list-gpu, -l", _listGPU, "Lists available Graphics cards, useful for debugging");
|
||||||
|
_app.set_version_flag("--version, -v", BUILD_ID);
|
||||||
|
|
||||||
|
// Help
|
||||||
|
//_app.set_help_all_flag("--help-all", "Expand all help");
|
||||||
|
_app.set_help_flag();
|
||||||
|
_app.set_help_all_flag("--help, -h", "Print help for all subcommands");
|
||||||
|
|
||||||
|
// Subcommand options/flags
|
||||||
|
// Run
|
||||||
|
_run->add_option("--gpu, -g", config.gpuIndex, "Manually select a GPU");
|
||||||
|
_run->add_option("--model, -m", config.modelPath, "Overwrites the default model");
|
||||||
|
}
|
||||||
|
|
||||||
|
int dispatch(int argc, char* argv[]) {
|
||||||
|
CLI11_PARSE(_app, argc, argv);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void printHelp() {
|
||||||
|
fmt::println("{}", _app.help());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
CLI::App _app;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
int main(int argc, char* argv[]) {
|
||||||
|
// Classes we need
|
||||||
Engine engine;
|
Engine engine;
|
||||||
|
ArgHandler handler;
|
||||||
|
|
||||||
// Exemple of overwriting a class value
|
// Exemple of overwriting a class value
|
||||||
//engine._windowExtent = { 67, 67 };
|
//engine._windowExtent = { 67, 67 };
|
||||||
|
|
||||||
|
handler.buildArgs();
|
||||||
|
|
||||||
|
if (argc == 1) {
|
||||||
|
handler.printHelp();
|
||||||
|
fmt::println("Please use -h or --help to see all available options.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Checks for -h flag
|
||||||
|
int result = handler.dispatch(argc, argv);
|
||||||
|
if(result != 0) return result;
|
||||||
|
|
||||||
|
if (handler._run->parsed() &&
|
||||||
|
handler._run->get_help_ptr()->as<bool>()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(handler._listGPU) {
|
||||||
|
engine.getAvailableGPU();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(handler._run->parsed()){
|
||||||
|
engine.parseConfig(
|
||||||
|
handler.config
|
||||||
|
);
|
||||||
|
|
||||||
engine.init();
|
engine.init();
|
||||||
|
|
||||||
engine.run();
|
engine.run();
|
||||||
|
|
||||||
engine.cleanup();
|
engine.cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1 +0,0 @@
|
|||||||
Subproject commit 5220a3f48d39c000da8b46fb0fccf3dd62695c51
|
|
||||||
Loading…
x
Reference in New Issue
Block a user