Compare commits
1 Commits
vkguide
...
howToVulka
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f1159d111b |
1
.clangd
1
.clangd
@ -11,4 +11,3 @@ CompileFlags:
|
|||||||
- -DLOGGER_IMPL
|
- -DLOGGER_IMPL
|
||||||
- -DSERVER_INIT_IMPL
|
- -DSERVER_INIT_IMPL
|
||||||
- -DSERVER_IMPL
|
- -DSERVER_IMPL
|
||||||
- -DLOADER_IMPL
|
|
||||||
|
|||||||
4
.envrc
4
.envrc
@ -1 +1,3 @@
|
|||||||
use flake
|
FLAKEPATH="/home/alex/Developer/nix/NixOSDots/dev-flakes"
|
||||||
|
|
||||||
|
use flake ${FLAKEPATH}/vulkan
|
||||||
|
|||||||
@ -1,54 +0,0 @@
|
|||||||
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
|
|
||||||
@ -1,272 +0,0 @@
|
|||||||
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,11 +37,6 @@ Thumbs.db
|
|||||||
# direnv
|
# direnv
|
||||||
.direnv/
|
.direnv/
|
||||||
|
|
||||||
# cache
|
|
||||||
.cache
|
|
||||||
.cache/*
|
|
||||||
|
|
||||||
# Nix flakes
|
# Nix flakes
|
||||||
result
|
result
|
||||||
result-*
|
result-*
|
||||||
.cache/*
|
|
||||||
|
|||||||
12
.gitmodules
vendored
12
.gitmodules
vendored
@ -1,8 +1,4 @@
|
|||||||
[submodule "include/imgui"]
|
[submodule "src/imgui"]
|
||||||
path = include/imgui
|
path = src/imgui
|
||||||
url = https://git.alexdelcamp.fr/Alexandre_1a/imgui.git
|
url = https://github.com/ocornut/imgui.git
|
||||||
branch = docking
|
branch = docking
|
||||||
|
|
||||||
[submodule "include/CLI11"]
|
|
||||||
path = include/CLI11
|
|
||||||
url = https://github.com/CLIUtils/CLI11.git
|
|
||||||
|
|||||||
372
CMakeLists.txt
372
CMakeLists.txt
@ -1,77 +1,18 @@
|
|||||||
cmake_minimum_required(VERSION 3.25) # Debian 12 ships 3.25
|
cmake_minimum_required (VERSION 3.29)
|
||||||
project(VulkanEngine)
|
project(VulkanEngine)
|
||||||
|
|
||||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/CMake")
|
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/CMake")
|
||||||
|
|
||||||
include(BuildInfo)
|
include(BuildInfo)
|
||||||
include(FetchContent)
|
include(FetchContent)
|
||||||
# LTO
|
#LTO
|
||||||
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)
|
||||||
@ -79,103 +20,19 @@ if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
|||||||
set(CMAKE_RANLIB "${GCC_RANLIB}")
|
set(CMAKE_RANLIB "${GCC_RANLIB}")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# Find all package dependencies
|
||||||
# Dependencies
|
find_package( glfw3 REQUIRED )
|
||||||
# ---------------------------------------------------------------------------
|
find_package( glm REQUIRED )
|
||||||
# Same in every mode: no link-time dependency on libvulkan, all Vulkan
|
find_package( VulkanMemoryAllocator CONFIG REQUIRED )
|
||||||
# functions come from volk (otherwise vk*KHR aliases are undefined at link).
|
find_package( fmt REQUIRED )
|
||||||
set(ENGINE_EXTRA_DEFINITIONS
|
# Shader compilers
|
||||||
GLFW_INCLUDE_NONE
|
add_executable (glslang::validator IMPORTED)
|
||||||
VK_NO_PROTOTYPES
|
find_program (GLSLANG_VALIDATOR "glslangValidator" HINTS $ENV{VULKAN_SDK}/bin REQUIRED)
|
||||||
VMA_STATIC_VULKAN_FUNCTIONS=0
|
set_property (TARGET glslang::validator PROPERTY IMPORTED_LOCATION "${GLSLANG_VALIDATOR}")
|
||||||
VMA_DYNAMIC_VULKAN_FUNCTIONS=1
|
find_program(SLANGC_EXECUTABLE slangc HINTS $ENV{VULKAN_SDK}/bin REQUIRED)
|
||||||
)
|
|
||||||
|
|
||||||
if(VULKANENGINE_FETCH_DEPS)
|
# fastgltf because it's not in nixpkgs
|
||||||
# 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( glm REQUIRED )
|
|
||||||
find_package( VulkanMemoryAllocator CONFIG REQUIRED )
|
|
||||||
find_package( CLI11 REQUIRED )
|
|
||||||
find_package( simdjson REQUIRED )
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# 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
|
||||||
@ -183,26 +40,13 @@ FetchContent_Declare(
|
|||||||
)
|
)
|
||||||
FetchContent_MakeAvailable(fastgltf)
|
FetchContent_MakeAvailable(fastgltf)
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# vk-bootstrap because CMAKE can't find it on NixOS
|
||||||
# Shader compilers (not needed when precompiled shaders are provided)
|
FetchContent_Declare(
|
||||||
# ---------------------------------------------------------------------------
|
vk-bootstrap
|
||||||
if(NOT VULKANENGINE_PREBUILT_SHADERS)
|
GIT_REPOSITORY https://github.com/charles-lunarg/vk-bootstrap.git
|
||||||
add_executable (glslang::validator IMPORTED)
|
GIT_TAG v1.3.295
|
||||||
find_program (
|
)
|
||||||
GLSLANG_VALIDATOR
|
FetchContent_MakeAvailable(vk-bootstrap)
|
||||||
"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)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
|
|
||||||
# Helper functions to build shaders
|
# Helper functions to build shaders
|
||||||
function(addGlslShader SOURCE OUTPUT_DIR)
|
function(addGlslShader SOURCE OUTPUT_DIR)
|
||||||
@ -247,39 +91,21 @@ 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;SLANG_ENTRIES;LIBS;TEXTURES;MODELS" ${ARGN} )
|
cmake_parse_arguments ( BINARY "IMGUI;LICENSE" "SOURCE" "SHADERS;SLANG_SHADERS;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 (
|
set_target_properties ( ${BINARY_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${BINARY_NAME} )
|
||||||
${BINARY_NAME}
|
set_target_properties ( ${BINARY_NAME} PROPERTIES CXX_STANDARD 20 ) # Uses C++20
|
||||||
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 (
|
||||||
@ -289,33 +115,25 @@ 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}/include/imgui
|
${CMAKE_SOURCE_DIR}/src/imgui
|
||||||
${CMAKE_SOURCE_DIR}/include/imgui/backends
|
${CMAKE_SOURCE_DIR}/src/imgui/backends
|
||||||
)
|
)
|
||||||
|
|
||||||
target_sources(${BINARY_NAME} PRIVATE
|
target_sources(${BINARY_NAME} PRIVATE
|
||||||
${CMAKE_SOURCE_DIR}/include/imgui/imgui.cpp
|
${CMAKE_SOURCE_DIR}/src/imgui/imgui.cpp
|
||||||
|
|
||||||
${CMAKE_SOURCE_DIR}/include/imgui/imgui_draw.cpp
|
${CMAKE_SOURCE_DIR}/src/imgui/imgui_draw.cpp
|
||||||
${CMAKE_SOURCE_DIR}/include/imgui/imgui_tables.cpp
|
${CMAKE_SOURCE_DIR}/src/imgui/imgui_tables.cpp
|
||||||
${CMAKE_SOURCE_DIR}/include/imgui/imgui_widgets.cpp
|
${CMAKE_SOURCE_DIR}/src/imgui/imgui_widgets.cpp
|
||||||
${CMAKE_SOURCE_DIR}/include/imgui/imgui_demo.cpp
|
${CMAKE_SOURCE_DIR}/src/imgui/imgui_demo.cpp
|
||||||
#${CMAKE_SOURCE_DIR}/include/imgui/imgui_memory_editor.h
|
|
||||||
|
|
||||||
${CMAKE_SOURCE_DIR}/include/imgui/backends/imgui_impl_glfw.cpp
|
${CMAKE_SOURCE_DIR}/src/imgui/backends/imgui_impl_glfw.cpp
|
||||||
${CMAKE_SOURCE_DIR}/include/imgui/backends/imgui_impl_vulkan.cpp
|
${CMAKE_SOURCE_DIR}/src/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()
|
||||||
@ -323,48 +141,38 @@ 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)
|
||||||
|
set(ALL_SPV_FILES "")
|
||||||
|
set(EXPANDED_SHADERS "")
|
||||||
|
|
||||||
if(VULKANENGINE_PREBUILT_SHADERS)
|
foreach(SHADER_PATTERN ${BINARY_SHADERS})
|
||||||
# Copy the .spv produced by the Nix job instead of compiling them
|
if(SHADER_PATTERN MATCHES "[*?]")
|
||||||
file(GLOB PREBUILT_SPV CONFIGURE_DEPENDS "${VULKANENGINE_PREBUILT_SHADERS}/*.spv")
|
file(GLOB SHADER_FILES CONFIGURE_DEPENDS ${SHADER_PATTERN})
|
||||||
if(NOT PREBUILT_SPV)
|
list(APPEND EXPANDED_SHADERS ${SHADER_FILES})
|
||||||
message(FATAL_ERROR "No .spv found in ${VULKANENGINE_PREBUILT_SHADERS}")
|
else()
|
||||||
|
list(APPEND EXPANDED_SHADERS ${SHADER_PATTERN})
|
||||||
endif()
|
endif()
|
||||||
file(COPY ${PREBUILT_SPV} DESTINATION ${SHADER_OUTPUT_DIR})
|
endforeach()
|
||||||
else()
|
|
||||||
set(ALL_SPV_FILES "")
|
|
||||||
set(EXPANDED_SHADERS "")
|
|
||||||
|
|
||||||
foreach(SHADER_PATTERN ${BINARY_SHADERS})
|
foreach(SHADER_SRC ${EXPANDED_SHADERS})
|
||||||
if(SHADER_PATTERN MATCHES "[*?]")
|
if(NOT IS_ABSOLUTE ${SHADER_SRC})
|
||||||
file(GLOB SHADER_FILES CONFIGURE_DEPENDS ${SHADER_PATTERN})
|
set(SHADER_SRC ${CMAKE_CURRENT_SOURCE_DIR}/${SHADER_SRC})
|
||||||
list(APPEND EXPANDED_SHADERS ${SHADER_FILES})
|
endif()
|
||||||
else()
|
get_filename_component(EXT ${SHADER_SRC} EXT)
|
||||||
list(APPEND EXPANDED_SHADERS ${SHADER_PATTERN})
|
if(EXT STREQUAL ".slang")
|
||||||
endif()
|
addSlangShader(${SHADER_SRC} "${BINARY_SLANG_ENTRIES}" ${SHADER_OUTPUT_DIR})
|
||||||
endforeach()
|
list(APPEND ALL_SPV_FILES ${SPV_FILE})
|
||||||
|
else()
|
||||||
|
addGlslShader(${SHADER_SRC} ${SHADER_OUTPUT_DIR})
|
||||||
|
list(APPEND ALL_SPV_FILES ${SPV_FILE})
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
|
||||||
foreach(SHADER_SRC ${EXPANDED_SHADERS})
|
add_custom_target(shaders_${BINARY_NAME} DEPENDS ${ALL_SPV_FILES})
|
||||||
if(NOT IS_ABSOLUTE ${SHADER_SRC})
|
add_dependencies(${BINARY_NAME} shaders_${BINARY_NAME})
|
||||||
set(SHADER_SRC ${CMAKE_CURRENT_SOURCE_DIR}/${SHADER_SRC})
|
|
||||||
endif()
|
|
||||||
get_filename_component(EXT ${SHADER_SRC} EXT)
|
|
||||||
if(EXT STREQUAL ".slang")
|
|
||||||
addSlangShader(${SHADER_SRC} "${BINARY_SLANG_ENTRIES}" ${SHADER_OUTPUT_DIR})
|
|
||||||
list(APPEND ALL_SPV_FILES ${SPV_FILE})
|
|
||||||
else()
|
|
||||||
addGlslShader(${SHADER_SRC} ${SHADER_OUTPUT_DIR})
|
|
||||||
list(APPEND ALL_SPV_FILES ${SPV_FILE})
|
|
||||||
endif()
|
|
||||||
endforeach()
|
|
||||||
|
|
||||||
add_custom_target(shaders_${BINARY_NAME} DEPENDS ${ALL_SPV_FILES})
|
|
||||||
add_dependencies(${BINARY_NAME} shaders_${BINARY_NAME})
|
|
||||||
endif()
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (DEFINED BINARY_LIBS)
|
if (DEFINED BINARY_LIBS)
|
||||||
target_link_libraries ( ${BINARY_NAME} PRIVATE ${BINARY_LIBS} )
|
target_link_libraries ( ${BINARY_NAME} ${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
|
||||||
@ -397,73 +205,23 @@ function ( addBinary BINARY_NAME )
|
|||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# Scan the shader folder
|
||||||
# Binaries
|
file(GLOB SHADER_SOURCES CONFIGURE_DEPENDS "shaders/*")
|
||||||
# ---------------------------------------------------------------------------
|
|
||||||
list(
|
|
||||||
APPEND
|
|
||||||
lib_list
|
|
||||||
# Libs used
|
|
||||||
glfw
|
|
||||||
fmt
|
|
||||||
vk-bootstrap
|
|
||||||
CLI11::CLI11
|
|
||||||
fastgltf
|
|
||||||
)
|
|
||||||
|
|
||||||
if(VULKANENGINE_FETCH_DEPS)
|
# Adds the main binary
|
||||||
# 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,20 +5,3 @@ 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
11
ROADMAP.md
@ -1,11 +0,0 @@
|
|||||||
# 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
|
|
||||||
Binary file not shown.
58
flake.lock
generated
58
flake.lock
generated
@ -1,58 +0,0 @@
|
|||||||
{
|
|
||||||
"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
114
flake.nix
@ -1,114 +0,0 @@
|
|||||||
{
|
|
||||||
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 +0,0 @@
|
|||||||
Subproject commit c1cfe00d2f3d862aecfe6e69ec810414d5f4c906
|
|
||||||
@ -1 +0,0 @@
|
|||||||
Subproject commit d7cce3ad5070bbdbbd7a39335c0c1e90071211d0
|
|
||||||
117
package.nix
117
package.nix
@ -1,117 +0,0 @@
|
|||||||
{ 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";
|
|
||||||
}
|
|
||||||
30
shaders/colored_triangle.slang
Normal file
30
shaders/colored_triangle.slang
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
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);
|
||||||
|
}
|
||||||
@ -1,13 +0,0 @@
|
|||||||
#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);
|
|
||||||
}
|
|
||||||
@ -1,36 +0,0 @@
|
|||||||
#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;
|
|
||||||
}
|
|
||||||
@ -1,24 +0,0 @@
|
|||||||
#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,31 +1,8 @@
|
|||||||
/*
|
|
||||||
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{
|
||||||
@ -40,79 +17,7 @@ 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
|
||||||
@ -124,271 +29,12 @@ class Logger {
|
|||||||
// 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,25 +12,19 @@
|
|||||||
#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 <volk.h>
|
#include <vulkan/vulkan.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_NONE
|
#define GLFW_INCLUDE_VULKAN
|
||||||
#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"
|
||||||
@ -47,16 +41,9 @@
|
|||||||
} \
|
} \
|
||||||
} 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;
|
||||||
|
|
||||||
@ -87,42 +74,6 @@ 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
|
||||||
logger.logRAM(LogModule::GLFW, LogLevel::EINFO, "Key pressed, key {}", key);
|
fmt::println("[Engine:Info] Key pressed, key {}", key);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -2,7 +2,6 @@
|
|||||||
#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 {
|
||||||
@ -65,19 +64,12 @@ 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,
|
||||||
@ -295,27 +287,6 @@ 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,
|
||||||
@ -339,21 +310,6 @@ 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,
|
||||||
|
|||||||
@ -1,197 +0,0 @@
|
|||||||
#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,8 +1,3 @@
|
|||||||
/*
|
|
||||||
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
|
||||||
@ -33,7 +28,6 @@ class PipelineBuilder {
|
|||||||
VkPipelineLayout _pipelineLayout;
|
VkPipelineLayout _pipelineLayout;
|
||||||
VkPipelineDepthStencilStateCreateInfo _depthStencil;
|
VkPipelineDepthStencilStateCreateInfo _depthStencil;
|
||||||
VkPipelineRenderingCreateInfo _renderInfo;
|
VkPipelineRenderingCreateInfo _renderInfo;
|
||||||
VkFormat _colorAttachmentFormat;
|
|
||||||
|
|
||||||
PipelineBuilder() { clear(); }
|
PipelineBuilder() { clear(); }
|
||||||
|
|
||||||
@ -63,9 +57,7 @@ class PipelineBuilder {
|
|||||||
|
|
||||||
void setMultisamplingNone();
|
void setMultisamplingNone();
|
||||||
|
|
||||||
void enableBlendingAdditive();
|
void disableBlending ();
|
||||||
void enableBlendingAlphaBlend();
|
|
||||||
void disableBlending();
|
|
||||||
|
|
||||||
void setColorAttachmentFormat(
|
void setColorAttachmentFormat(
|
||||||
VkFormat format
|
VkFormat format
|
||||||
@ -76,10 +68,6 @@ class PipelineBuilder {
|
|||||||
);
|
);
|
||||||
|
|
||||||
void disableDepthtest();
|
void disableDepthtest();
|
||||||
void enableDepthtest(
|
|
||||||
bool depthWriteEnable,
|
|
||||||
VkCompareOp op
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@ -335,28 +323,6 @@ 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;
|
||||||
@ -364,15 +330,6 @@ 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
|
||||||
) {
|
) {
|
||||||
@ -391,20 +348,5 @@ 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,99 +1,18 @@
|
|||||||
/*
|
|
||||||
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();
|
engine.init();
|
||||||
|
|
||||||
if (argc == 1) {
|
engine.run();
|
||||||
handler.printHelp();
|
|
||||||
fmt::println("Please use -h or --help to see all available options.");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Checks for -h flag
|
engine.cleanup();
|
||||||
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.run();
|
|
||||||
|
|
||||||
engine.cleanup();
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
1
src/imgui
Submodule
1
src/imgui
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit b48d1afbe8ee8b238e2961dc363a949dd7304e23
|
||||||
Loading…
x
Reference in New Issue
Block a user