Compare commits
79 commits
Author | SHA1 | Date | |
---|---|---|---|
avery | 9b468e5c8a | ||
Mars | 450c92ec55 | ||
Mars | 0f7c86bd4b | ||
Mars | 2fa8e016da | ||
Mars | 5b7f400b7b | ||
Mars | 31f772eb2d | ||
Mars | f99ff172db | ||
Mars | 40af687b7f | ||
Mars | e2eec3fbeb | ||
Mars | 0caa990a93 | ||
Mars | edbcf2406b | ||
Mars | 4a4939e65b | ||
Mars | 52123f27ac | ||
Mars | 059dc159bd | ||
Mars | 3fdca6c6db | ||
Mars | ed9141ae8f | ||
Mars | fa2d41ac81 | ||
Mars | e06d360e28 | ||
Mars | b2779c119a | ||
Mars | 154a81721d | ||
Mars | 7632347218 | ||
Mars | bac5d088f8 | ||
Mars | 780a7301f5 | ||
Mars | 545975d6bb | ||
Mars | 96a92ec0e2 | ||
Mars | fdc9507670 | ||
Mars | 7dafdfffa6 | ||
Mars | 8bb2fafe01 | ||
Mars | 8285b60211 | ||
Mars | 02cd99a73a | ||
Mars | f541f6ec8c | ||
Mars | bdc1ebc047 | ||
Mars | b97a9e2b7b | ||
Mars | f4fcfd3fda | ||
Mars | ae7de1f8ee | ||
Mars | f0e85c0d88 | ||
Mars | 1732d56e22 | ||
Mars | 7cc871fb48 | ||
Mars | c2ee7e8677 | ||
Mars | 31b93deecb | ||
Mars | 1eade711ba | ||
Mars | 79fdc8c38a | ||
Mars | 61a2e9367b | ||
Mars | f4f4b7898b | ||
Mars | 6711f4b6e0 | ||
Mars | e3cc2bd8f3 | ||
Mars | 0d77992e67 | ||
Mars | df0e12a783 | ||
Mars | ecc11a2751 | ||
Mars | daad4cc907 | ||
Mars | 83631f940e | ||
Mars | 14ca81b3cb | ||
Mars | 23bb6b871f | ||
Mars | 76fa86d622 | ||
Mars | 7fd7beea60 | ||
Mars | 7648a55f8d | ||
Mars | e0b7e93bd8 | ||
Mars | 98bd5f7bc2 | ||
Mars | ba46d3d834 | ||
Mars | 9ae5a4675a | ||
Mars | 623c51d335 | ||
Mars | 87c6018de1 | ||
Mars | aadf46f066 | ||
Mars | 10af83237f | ||
Mars | 6395c6b95c | ||
Mars | 9b221b81b4 | ||
Mars | 658595e0c5 | ||
Mars | 134b43c1d4 | ||
Mars | 2735eb5807 | ||
Mars | ffd3f44464 | ||
Mars | ee96290c80 | ||
Mars | 329eeb76c7 | ||
Mars | a4c78acebf | ||
Mars | d489322ab2 | ||
Mars | df6ec77374 | ||
Mars | 01cdd533c5 | ||
Mars | 651f339537 | ||
Mars | d6c93896d1 | ||
Mars | 12c4d95aff |
|
@ -20,6 +20,7 @@ IndentWidth: 2
|
||||||
NamespaceIndentation: All
|
NamespaceIndentation: All
|
||||||
SpaceBeforeCpp11BracedList: true
|
SpaceBeforeCpp11BracedList: true
|
||||||
SpacesBeforeTrailingComments: 1
|
SpacesBeforeTrailingComments: 1
|
||||||
|
Standard: Latest
|
||||||
|
|
||||||
IncludeBlocks: Regroup
|
IncludeBlocks: Regroup
|
||||||
IncludeCategories:
|
IncludeCategories:
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
# noinspection SpellCheckingInspection
|
|
||||||
Checks: >
|
Checks: >
|
||||||
*,
|
*,
|
||||||
-ctad-maybe-unsupported,
|
-ctad-maybe-unsupported,
|
||||||
|
@ -8,6 +7,7 @@ Checks: >
|
||||||
-bugprone-implicit-widening-of-multiplication-result,
|
-bugprone-implicit-widening-of-multiplication-result,
|
||||||
-cert-env33-c,
|
-cert-env33-c,
|
||||||
-concurrency-mt-unsafe,
|
-concurrency-mt-unsafe,
|
||||||
|
-cppcoreguidelines-avoid-const-or-ref-data-members,
|
||||||
-cppcoreguidelines-avoid-magic-numbers,
|
-cppcoreguidelines-avoid-magic-numbers,
|
||||||
-cppcoreguidelines-owning-memory,
|
-cppcoreguidelines-owning-memory,
|
||||||
-cppcoreguidelines-pro-type-member-init,
|
-cppcoreguidelines-pro-type-member-init,
|
||||||
|
|
4
.clangd
4
.clangd
|
@ -1,4 +0,0 @@
|
||||||
Diagnostics:
|
|
||||||
Suppress: >
|
|
||||||
-Wmissing-template-arg-list-after-template-kw,
|
|
||||||
-Wctad-maybe-unsupported
|
|
3
.envrc
3
.envrc
|
@ -1,2 +1 @@
|
||||||
export NIXPKGS_ALLOW_UNSUPPORTED_SYSTEM=1
|
use_flake
|
||||||
use_flake . --impure
|
|
||||||
|
|
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -2,3 +2,4 @@
|
||||||
.direnv/
|
.direnv/
|
||||||
.vscode/
|
.vscode/
|
||||||
build/
|
build/
|
||||||
|
imgui.ini
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
# This file was generated by nvfetcher, please do not modify it manually.
|
# This file was generated by nvfetcher, please do not modify it manually.
|
||||||
{ fetchgit, fetchurl, fetchFromGitHub, dockerTools }:
|
|
||||||
{
|
{
|
||||||
|
fetchgit,
|
||||||
|
fetchurl,
|
||||||
|
fetchFromGitHub,
|
||||||
|
dockerTools,
|
||||||
|
}: {
|
||||||
fmt = {
|
fmt = {
|
||||||
pname = "fmt";
|
pname = "fmt";
|
||||||
version = "11.0.2";
|
version = "11.0.2";
|
||||||
|
|
92
flake.lock
92
flake.lock
|
@ -1,12 +1,63 @@
|
||||||
{
|
{
|
||||||
"nodes": {
|
"nodes": {
|
||||||
|
"flake-compat": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1688025799,
|
||||||
|
"narHash": "sha256-ktpB4dRtnksm9F5WawoIkEneh1nrEvuxb5lJFt1iOyw=",
|
||||||
|
"owner": "nix-community",
|
||||||
|
"repo": "flake-compat",
|
||||||
|
"rev": "8bf105319d44f6b9f0d764efa4fdef9f1cc9ba1c",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-community",
|
||||||
|
"repo": "flake-compat",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixos-asahi": {
|
||||||
|
"inputs": {
|
||||||
|
"flake-compat": "flake-compat",
|
||||||
|
"nixpkgs": "nixpkgs",
|
||||||
|
"rust-overlay": "rust-overlay"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1729779640,
|
||||||
|
"narHash": "sha256-M9t4Ta9d76aVqd1mkLBl8zFSWYc8pv6AZTy1SU5bVp0=",
|
||||||
|
"owner": "zzywysm",
|
||||||
|
"repo": "nixos-asahi",
|
||||||
|
"rev": "5f8823f3543cbf9566d5af49b3a3c18539681eac",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "zzywysm",
|
||||||
|
"repo": "nixos-asahi",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1727065772,
|
"lastModified": 1725103162,
|
||||||
"narHash": "sha256-U9baiEXL2YsS67QKlBAPIUq+OB+eUPKv8n1vGNdhiec=",
|
"narHash": "sha256-Ym04C5+qovuQDYL/rKWSR+WESseQBbNAe5DsXNx5trY=",
|
||||||
|
"owner": "nixos",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "12228ff1752d7b7624a54e9c1af4b222b3c1073b",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nixos",
|
||||||
|
"ref": "nixos-unstable",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs_2": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1730853263,
|
||||||
|
"narHash": "sha256-Cnp2zjzaA4bYUOhM/xo9GxhgOgTHn+qNbSGu4su8RaQ=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "989dc4cbf6a95f2e5fefc8cd61d2198a8fb6834a",
|
"rev": "5d4d64e923ce570996c089d768710f61bde0b9d3",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -15,13 +66,13 @@
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nixpkgs_2": {
|
"nixpkgs_3": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1726481836,
|
"lastModified": 1726871744,
|
||||||
"narHash": "sha256-MWTBH4dd5zIz2iatDb8IkqSjIeFum9jAqkFxgHLdzO4=",
|
"narHash": "sha256-V5LpfdHyQkUF7RfOaDPrZDP+oqz88lTJrMT1+stXNwo=",
|
||||||
"owner": "nixos",
|
"owner": "nixos",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "20f9370d5f588fb8c72e844c54511cab054b5f40",
|
"rev": "a1d92660c6b3b7c26fb883500a80ea9d33321be2",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -33,11 +84,28 @@
|
||||||
},
|
},
|
||||||
"root": {
|
"root": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"nixpkgs": "nixpkgs",
|
"nixos-asahi": "nixos-asahi",
|
||||||
|
"nixpkgs": "nixpkgs_2",
|
||||||
"treefmt-nix": "treefmt-nix",
|
"treefmt-nix": "treefmt-nix",
|
||||||
"utils": "utils"
|
"utils": "utils"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"rust-overlay": {
|
||||||
|
"flake": false,
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1686795910,
|
||||||
|
"narHash": "sha256-jDa40qRZ0GRQtP9EMZdf+uCbvzuLnJglTUI2JoHfWDc=",
|
||||||
|
"owner": "oxalica",
|
||||||
|
"repo": "rust-overlay",
|
||||||
|
"rev": "5c2b97c0a9bc5217fc3dfb1555aae0fb756d99f9",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "oxalica",
|
||||||
|
"repo": "rust-overlay",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"systems": {
|
"systems": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1681028828,
|
"lastModified": 1681028828,
|
||||||
|
@ -55,14 +123,14 @@
|
||||||
},
|
},
|
||||||
"treefmt-nix": {
|
"treefmt-nix": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"nixpkgs": "nixpkgs_2"
|
"nixpkgs": "nixpkgs_3"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1726734507,
|
"lastModified": 1730321837,
|
||||||
"narHash": "sha256-VUH5O5AcOSxb0uL/m34dDkxFKP6WLQ6y4I1B4+N3L2w=",
|
"narHash": "sha256-vK+a09qq19QNu2MlLcvN4qcRctJbqWkX7ahgPZ/+maI=",
|
||||||
"owner": "numtide",
|
"owner": "numtide",
|
||||||
"repo": "treefmt-nix",
|
"repo": "treefmt-nix",
|
||||||
"rev": "ee41a466c2255a3abe6bc50fc6be927cdee57a9f",
|
"rev": "746901bb8dba96d154b66492a29f5db0693dbfcc",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
40
flake.nix
40
flake.nix
|
@ -2,6 +2,7 @@
|
||||||
description = "C/C++ environment";
|
description = "C/C++ environment";
|
||||||
|
|
||||||
inputs = {
|
inputs = {
|
||||||
|
nixos-asahi.url = "github:zzywysm/nixos-asahi";
|
||||||
nixpkgs.url = "github:NixOS/nixpkgs";
|
nixpkgs.url = "github:NixOS/nixpkgs";
|
||||||
treefmt-nix.url = "github:numtide/treefmt-nix";
|
treefmt-nix.url = "github:numtide/treefmt-nix";
|
||||||
utils.url = "github:numtide/flake-utils";
|
utils.url = "github:numtide/flake-utils";
|
||||||
|
@ -10,13 +11,20 @@
|
||||||
outputs = {
|
outputs = {
|
||||||
self,
|
self,
|
||||||
nixpkgs,
|
nixpkgs,
|
||||||
|
nixos-asahi,
|
||||||
treefmt-nix,
|
treefmt-nix,
|
||||||
utils,
|
utils,
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
utils.lib.eachDefaultSystem (
|
utils.lib.eachDefaultSystem (
|
||||||
system: let
|
system: let
|
||||||
pkgs = import nixpkgs {inherit system;};
|
pkgs = import nixpkgs {
|
||||||
|
inherit system;
|
||||||
|
config = {
|
||||||
|
allowUnfree = true;
|
||||||
|
allowUnsupportedSystem = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
stdenv =
|
stdenv =
|
||||||
if pkgs.hostPlatform.isLinux
|
if pkgs.hostPlatform.isLinux
|
||||||
|
@ -34,14 +42,21 @@
|
||||||
|
|
||||||
fmt = mkPkg "fmt";
|
fmt = mkPkg "fmt";
|
||||||
|
|
||||||
|
imgui = pkgs.imgui.override {
|
||||||
|
IMGUI_BUILD_GLFW_BINDING = true;
|
||||||
|
IMGUI_BUILD_VULKAN_BINDING = true;
|
||||||
|
};
|
||||||
|
|
||||||
deps = with pkgs; [
|
deps = with pkgs; [
|
||||||
fmt
|
fmt
|
||||||
glfw
|
glfw
|
||||||
glm
|
glm
|
||||||
|
imgui
|
||||||
|
shaderc.dev
|
||||||
|
shaderc.lib
|
||||||
vulkan-extension-layer
|
vulkan-extension-layer
|
||||||
vulkan-memory-allocator
|
vulkan-memory-allocator
|
||||||
vulkan-utility-libraries
|
vulkan-utility-libraries
|
||||||
vulkan-headers
|
|
||||||
vulkan-loader
|
vulkan-loader
|
||||||
vulkan-tools
|
vulkan-tools
|
||||||
];
|
];
|
||||||
|
@ -82,7 +97,6 @@
|
||||||
projectRootFile = "flake.nix";
|
projectRootFile = "flake.nix";
|
||||||
programs = {
|
programs = {
|
||||||
alejandra.enable = true;
|
alejandra.enable = true;
|
||||||
deadnix.enable = true;
|
|
||||||
|
|
||||||
clang-format = {
|
clang-format = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
@ -92,15 +106,17 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
devShell = mkShell.override {inherit stdenv;} {
|
devShell = mkShell.override {inherit stdenv;} {
|
||||||
packages =
|
buildInputs =
|
||||||
[
|
[
|
||||||
alejandra
|
alejandra
|
||||||
bear
|
bear
|
||||||
|
cmake
|
||||||
(llvmPackages_18.clang-tools.override {enableLibcxx = true;})
|
(llvmPackages_18.clang-tools.override {enableLibcxx = true;})
|
||||||
lldb
|
lldb
|
||||||
meson
|
meson
|
||||||
|
nil
|
||||||
ninja
|
ninja
|
||||||
nvfetcher
|
#nvfetcher
|
||||||
pkg-config
|
pkg-config
|
||||||
unzip
|
unzip
|
||||||
|
|
||||||
|
@ -113,6 +129,20 @@
|
||||||
|
|
||||||
VULKAN_SDK = "${vulkan-headers}";
|
VULKAN_SDK = "${vulkan-headers}";
|
||||||
VK_LAYER_PATH = "${vulkan-validation-layers}/share/vulkan/explicit_layer.d";
|
VK_LAYER_PATH = "${vulkan-validation-layers}/share/vulkan/explicit_layer.d";
|
||||||
|
VK_ICD_FILENAMES =
|
||||||
|
if stdenv.isDarwin
|
||||||
|
then "${darwin.moltenvk}/share/vulkan/icd.d/MoltenVK_icd.json"
|
||||||
|
else let
|
||||||
|
vulkanDir =
|
||||||
|
if stdenv.hostPlatform.isx86_64
|
||||||
|
then "${mesa.drivers}/share/vulkan/icd.d"
|
||||||
|
else "${nixos-asahi.packages.aarch64-linux.mesa-asahi-edge.drivers}/share/vulkan/icd.d";
|
||||||
|
vulkanFiles = builtins.filter (file: builtins.match ".*\\.json$" file != null) (builtins.attrNames (builtins.readDir vulkanDir));
|
||||||
|
vulkanPaths = lib.concatStringsSep ":" (map (file: "${vulkanDir}/${file}") vulkanFiles);
|
||||||
|
in
|
||||||
|
if stdenv.hostPlatform.isx86_64
|
||||||
|
then "${linuxPackages_latest.nvidia_x11_beta}/share/vulkan/icd.d/nvidia_icd.x86_64.json:${vulkanPaths}"
|
||||||
|
else vulkanPaths;
|
||||||
|
|
||||||
shellHook = ''
|
shellHook = ''
|
||||||
export PATH="${llvmPackages_18.clang-tools.override {enableLibcxx = true;}}/bin:$PATH"
|
export PATH="${llvmPackages_18.clang-tools.override {enableLibcxx = true;}}/bin:$PATH"
|
||||||
|
|
8617
include/stb_image.h
Normal file
8617
include/stb_image.h
Normal file
File diff suppressed because it is too large
Load diff
3542
include/tiny_obj_loader.h
Normal file
3542
include/tiny_obj_loader.h
Normal file
File diff suppressed because it is too large
Load diff
5015
include/vkfw.hpp
Normal file
5015
include/vkfw.hpp
Normal file
File diff suppressed because it is too large
Load diff
41
meson.build
41
meson.build
|
@ -2,7 +2,7 @@ project(
|
||||||
'graphics-test',
|
'graphics-test',
|
||||||
'cpp',
|
'cpp',
|
||||||
version: '0.1.0',
|
version: '0.1.0',
|
||||||
default_options: ['cpp_std=c++20', 'warning_level=everything', 'buildtype=debugoptimized'],
|
default_options: ['cpp_std=c++26', 'warning_level=everything', 'buildtype=debugoptimized'],
|
||||||
)
|
)
|
||||||
|
|
||||||
cpp = meson.get_compiler('cpp')
|
cpp = meson.get_compiler('cpp')
|
||||||
|
@ -12,37 +12,32 @@ common_cpp_args = [
|
||||||
'-Wno-c++20-extensions',
|
'-Wno-c++20-extensions',
|
||||||
'-Wno-c++98-compat',
|
'-Wno-c++98-compat',
|
||||||
'-Wno-c++98-compat-pedantic',
|
'-Wno-c++98-compat-pedantic',
|
||||||
'-Wno-disabled-macro-expansion',
|
|
||||||
'-Wno-missing-prototypes',
|
|
||||||
'-Wno-padded',
|
|
||||||
'-Wno-pre-c++20-compat-pedantic',
|
'-Wno-pre-c++20-compat-pedantic',
|
||||||
'-Wno-switch-default',
|
'-Wno-padded',
|
||||||
'-Wno-unsafe-buffer-usage',
|
'-mavx2'
|
||||||
'-Wunused-function',
|
|
||||||
'-fvisibility=hidden',
|
|
||||||
]
|
]
|
||||||
|
|
||||||
add_project_arguments(cpp.get_supported_arguments(common_cpp_args), language: 'cpp')
|
add_project_arguments(cpp.get_supported_arguments(common_cpp_args), language: 'cpp')
|
||||||
|
|
||||||
source_file_names = [
|
|
||||||
'src/main.cpp',
|
|
||||||
]
|
|
||||||
|
|
||||||
sources = []
|
|
||||||
|
|
||||||
foreach file : source_file_names
|
|
||||||
sources += files(file)
|
|
||||||
endforeach
|
|
||||||
|
|
||||||
deps = [
|
deps = [
|
||||||
dependency('fmt', static: true),
|
dependency('fmt', include_type: 'system'),
|
||||||
dependency('glfw3'),
|
dependency('glfw3', include_type: 'system'),
|
||||||
dependency('glm'),
|
dependency('glm', include_type: 'system'),
|
||||||
dependency('vulkan'),
|
dependency('vulkan', include_type: 'system'),
|
||||||
|
dependency('shaderc', include_type: 'system'),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
imgui_dep = dependency('imgui', required: false, include_type: 'system')
|
||||||
|
|
||||||
|
if not imgui_dep.found()
|
||||||
|
imgui_dep = cpp.find_library('imgui', required: true)
|
||||||
|
endif
|
||||||
|
|
||||||
|
deps += imgui_dep
|
||||||
|
|
||||||
executable(
|
executable(
|
||||||
'graphics-test',
|
'graphics-test',
|
||||||
sources,
|
sources: files('src/main.cpp'),
|
||||||
|
include_directories: include_directories('include', is_system: true),
|
||||||
dependencies: deps,
|
dependencies: deps,
|
||||||
)
|
)
|
||||||
|
|
16053
models/viking_room.obj
Normal file
16053
models/viking_room.obj
Normal file
File diff suppressed because it is too large
Load diff
2752
src/main.cpp
2752
src/main.cpp
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
166
src/util/shaders.hpp
Normal file
166
src/util/shaders.hpp
Normal file
|
@ -0,0 +1,166 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <filesystem>
|
||||||
|
#include <fmt/format.h>
|
||||||
|
#include <fstream>
|
||||||
|
#include <shaderc/shaderc.hpp>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "types.hpp"
|
||||||
|
|
||||||
|
class ShaderCompiler {
|
||||||
|
public:
|
||||||
|
ShaderCompiler() = default;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Compiles or loads a cached SPIR-V shader from a file.
|
||||||
|
*
|
||||||
|
* @param shaderSource The source code of the shader.
|
||||||
|
* @param kind The type of shader being compiled (vertex, fragment, etc.).
|
||||||
|
* @param shaderName The name used for caching the compiled shader.
|
||||||
|
* @return std::vector<u32> A vector containing the compiled SPIR-V code.
|
||||||
|
* @throws std::runtime_error if shader compilation fails.
|
||||||
|
*
|
||||||
|
* This function attempts to load a shader from the cache. If the shader
|
||||||
|
* is not found in the cache, it compiles the shader from the source code
|
||||||
|
* and saves the result to the cache for future use.
|
||||||
|
*/
|
||||||
|
static fn getCompiledShader(
|
||||||
|
const char* shaderSource,
|
||||||
|
const shaderc_shader_kind& kind,
|
||||||
|
const string& shaderName
|
||||||
|
) -> std::vector<u32> {
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
const filesystem::path cacheFile = getCacheFilePath(shaderName);
|
||||||
|
|
||||||
|
// Try loading from cache first
|
||||||
|
vector<u32> spirvCode = loadCachedShader(cacheFile);
|
||||||
|
|
||||||
|
if (!spirvCode.empty()) {
|
||||||
|
fmt::println("Loaded shader from cache: {}", cacheFile.string());
|
||||||
|
return spirvCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cache miss, compile the shader
|
||||||
|
spirvCode = compileShader(shaderSource, kind);
|
||||||
|
|
||||||
|
if (spirvCode.empty())
|
||||||
|
throw runtime_error("Shader compilation failed for: " + shaderName);
|
||||||
|
|
||||||
|
// Cache the compiled SPIR-V binary
|
||||||
|
saveCompiledShader(spirvCode, cacheFile.string());
|
||||||
|
return spirvCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* @brief Generates the cache file path based on the operating system.
|
||||||
|
*
|
||||||
|
* @param shaderName The name used for the shader file.
|
||||||
|
* @return string The full path to the cache file.
|
||||||
|
*
|
||||||
|
* This function determines the appropriate directory for caching shaders
|
||||||
|
* based on the operating system and returns the full path for the specified shader name.
|
||||||
|
*/
|
||||||
|
static fn getCacheFilePath(const string& shaderName) -> std::filesystem::path {
|
||||||
|
using namespace std::filesystem;
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
path cacheDir = path(getenv("LOCALAPPDATA")) / "VulkanApp" / "Shaders";
|
||||||
|
#elif defined(__APPLE__)
|
||||||
|
path cacheDir = path(getenv("HOME")) / "Library" / "Application Support" / "VulkanApp" / "Shaders";
|
||||||
|
#else // Assume Linux or other UNIX-like systems
|
||||||
|
path cacheDir = path(getenv("HOME")) / ".local" / "share" / "VulkanApp" / "Shaders";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!exists(cacheDir))
|
||||||
|
create_directories(cacheDir); // Create the directory if it doesn't exist
|
||||||
|
|
||||||
|
return cacheDir / (shaderName + ".spv");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Compiles GLSL code to SPIR-V.
|
||||||
|
*
|
||||||
|
* @param source The GLSL source code to compile.
|
||||||
|
* @param kind The type of shader being compiled.
|
||||||
|
* @return std::vector<u32> A vector containing the compiled SPIR-V code.
|
||||||
|
*
|
||||||
|
* This function uses the shaderc library to compile GLSL source code into
|
||||||
|
* SPIR-V binary format. If the compilation fails, an empty vector is returned.
|
||||||
|
*/
|
||||||
|
static fn compileShader(const char* source, const shaderc_shader_kind& kind) -> std::vector<u32> {
|
||||||
|
using namespace shaderc;
|
||||||
|
|
||||||
|
Compiler compiler;
|
||||||
|
CompileOptions options;
|
||||||
|
|
||||||
|
SpvCompilationResult result = compiler.CompileGlslToSpv(source, kind, "shader.glsl", "main", options);
|
||||||
|
|
||||||
|
if (result.GetCompilationStatus() != shaderc_compilation_status_success) {
|
||||||
|
fmt::println(stderr, "Shader compilation failed: {}", result.GetErrorMessage());
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
return { result.cbegin(), result.cend() };
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Loads compiled SPIR-V shader code from a cache file.
|
||||||
|
*
|
||||||
|
* @param cacheFile The path to the cached SPIR-V file.
|
||||||
|
* @return std::vector<u32> A vector containing the loaded SPIR-V code.
|
||||||
|
* @throws std::runtime_error if the file cannot be read.
|
||||||
|
*
|
||||||
|
* This function checks if the specified cache file exists and reads its
|
||||||
|
* contents into a vector. If the file cannot be opened, an exception is thrown.
|
||||||
|
*/
|
||||||
|
static fn loadCachedShader(const std::filesystem::path& cacheFile) -> std::vector<u32> {
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
if (!filesystem::exists(cacheFile))
|
||||||
|
return {}; // No cached file
|
||||||
|
|
||||||
|
ifstream file(cacheFile, ios::binary);
|
||||||
|
|
||||||
|
// Check if the file was successfully opened
|
||||||
|
if (!file)
|
||||||
|
throw runtime_error("Failed to open cached shader file: " + cacheFile.string());
|
||||||
|
|
||||||
|
usize fileSize = filesystem::file_size(cacheFile);
|
||||||
|
vector<u32> spirvCode(fileSize / sizeof(u32));
|
||||||
|
|
||||||
|
// Read entire file content into the vector
|
||||||
|
if (!file.read(bit_cast<char*>(spirvCode.data()), static_cast<streamsize>(fileSize)))
|
||||||
|
throw runtime_error("Failed to read cached shader file: " + cacheFile.string());
|
||||||
|
|
||||||
|
return spirvCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Saves compiled SPIR-V binary to a cache file.
|
||||||
|
*
|
||||||
|
* @param spirvCode The SPIR-V code to save.
|
||||||
|
* @param cacheFile The path to the file where the SPIR-V code will be saved.
|
||||||
|
* @throws std::runtime_error if the file cannot be written.
|
||||||
|
*
|
||||||
|
* This function writes the compiled SPIR-V binary to the specified file.
|
||||||
|
* If the file cannot be opened or written, an exception is thrown.
|
||||||
|
*/
|
||||||
|
static fn saveCompiledShader(const std::vector<u32>& spirvCode, const string& cacheFile) -> void {
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
ofstream file(cacheFile, ios::binary);
|
||||||
|
|
||||||
|
// Check if the file was successfully opened
|
||||||
|
if (!file)
|
||||||
|
throw runtime_error("Failed to open file for saving shader: " + cacheFile);
|
||||||
|
|
||||||
|
if (!file.write(
|
||||||
|
bit_cast<const char*>(spirvCode.data()), static_cast<streamsize>(spirvCode.size() * sizeof(u32))
|
||||||
|
))
|
||||||
|
throw runtime_error("Failed to save shader to cache: " + cacheFile);
|
||||||
|
}
|
||||||
|
};
|
121
src/util/unique_image.hpp
Normal file
121
src/util/unique_image.hpp
Normal file
|
@ -0,0 +1,121 @@
|
||||||
|
#include <filesystem>
|
||||||
|
|
||||||
|
#define STB_IMAGE_IMPLEMENTATION
|
||||||
|
#include <stb_image.h>
|
||||||
|
|
||||||
|
#include "types.hpp"
|
||||||
|
|
||||||
|
namespace stb {
|
||||||
|
/**
|
||||||
|
* @brief A class that handles loading and managing image data.
|
||||||
|
*
|
||||||
|
* This class uses the stb_image library to load images from the filesystem
|
||||||
|
* and provides access to the image data, dimensions, and channel count.
|
||||||
|
*/
|
||||||
|
class UniqueImage {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @brief Constructs a UniqueImage object and loads an image from the specified path.
|
||||||
|
*
|
||||||
|
* @param path The filesystem path to the image file to load.
|
||||||
|
*/
|
||||||
|
UniqueImage(const std::filesystem::path& path) { load(path.string().c_str()); }
|
||||||
|
|
||||||
|
// Deleted copy constructor to prevent copying.
|
||||||
|
UniqueImage(const UniqueImage&) = delete;
|
||||||
|
|
||||||
|
// Deleted copy assignment operator to prevent copying.
|
||||||
|
fn operator=(const UniqueImage&)->UniqueImage& = delete;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Move constructor for UniqueImage.
|
||||||
|
*
|
||||||
|
* @param other The UniqueImage object from which to move resources.
|
||||||
|
*
|
||||||
|
* Transfers ownership of resources from another UniqueImage object.
|
||||||
|
*/
|
||||||
|
UniqueImage(UniqueImage&& other) noexcept
|
||||||
|
: mData(other.mData), mWidth(other.mWidth), mHeight(other.mHeight), mChannels(other.mChannels) {
|
||||||
|
other.mData = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Move assignment operator for UniqueImage.
|
||||||
|
*
|
||||||
|
* @param other The UniqueImage object from which to move resources.
|
||||||
|
* @return Reference to this object.
|
||||||
|
*
|
||||||
|
* Transfers ownership of resources from another UniqueImage object.
|
||||||
|
*/
|
||||||
|
fn operator=(UniqueImage&& other) noexcept -> UniqueImage& {
|
||||||
|
if (this != &other) {
|
||||||
|
if (mData)
|
||||||
|
stbi_image_free(mData);
|
||||||
|
|
||||||
|
mData = other.mData;
|
||||||
|
mWidth = other.mWidth;
|
||||||
|
mHeight = other.mHeight;
|
||||||
|
mChannels = other.mChannels;
|
||||||
|
other.mData = nullptr;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Destructor for UniqueImage.
|
||||||
|
*
|
||||||
|
* Frees the image data if it is allocated.
|
||||||
|
*/
|
||||||
|
~UniqueImage() {
|
||||||
|
if (mData)
|
||||||
|
stbi_image_free(mData);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Retrieves the image data.
|
||||||
|
*
|
||||||
|
* @return Pointer to the image data in memory.
|
||||||
|
*/
|
||||||
|
[[nodiscard]] fn getData() const -> u8* { return mData; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Retrieves the width of the image.
|
||||||
|
*
|
||||||
|
* @return The width of the image in pixels.
|
||||||
|
*/
|
||||||
|
[[nodiscard]] fn getWidth() const -> i32 { return mWidth; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Retrieves the height of the image.
|
||||||
|
*
|
||||||
|
* @return The height of the image in pixels.
|
||||||
|
*/
|
||||||
|
[[nodiscard]] fn getHeight() const -> i32 { return mHeight; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Retrieves the number of channels in the image.
|
||||||
|
*
|
||||||
|
* @return The number of channels in the image (e.g., 3 for RGB, 4 for RGBA).
|
||||||
|
*/
|
||||||
|
[[nodiscard]] fn getChannels() const -> i32 { return mChannels; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
u8* mData = nullptr; ///< Pointer to the image data.
|
||||||
|
i32 mWidth = 0; ///< Width of the image in pixels.
|
||||||
|
i32 mHeight = 0; ///< Height of the image in pixels.
|
||||||
|
i32 mChannels = 0; ///< Number of channels in the image.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Loads an image from a file.
|
||||||
|
*
|
||||||
|
* @param filename The name of the file from which to load the image.
|
||||||
|
* @throws std::runtime_error If the image fails to load.
|
||||||
|
*/
|
||||||
|
fn load(const char* filename) -> void {
|
||||||
|
mData = stbi_load(filename, &mWidth, &mHeight, &mChannels, STBI_rgb_alpha);
|
||||||
|
|
||||||
|
if (!mData)
|
||||||
|
throw std::runtime_error("Failed to load image: " + string(stbi_failure_reason()));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
52
src/util/vertex.hpp
Normal file
52
src/util/vertex.hpp
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
#define GLM_FORCE_DEPTH_ZERO_TO_ONE
|
||||||
|
#define GLM_ENABLE_EXPERIMENTAL
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
#include <glm/gtx/hash.hpp>
|
||||||
|
|
||||||
|
#define VULKAN_HPP_NO_CONSTRUCTORS
|
||||||
|
#include <vulkan/vulkan.hpp>
|
||||||
|
|
||||||
|
#include "types.hpp"
|
||||||
|
|
||||||
|
// Vertex data for the model
|
||||||
|
struct Vertex {
|
||||||
|
// Position of the vertex
|
||||||
|
glm::vec3 pos;
|
||||||
|
// Color of the vertex (in RGB)
|
||||||
|
glm::vec3 color;
|
||||||
|
// Texture coordinates of the vertex
|
||||||
|
glm::vec2 tex_coord;
|
||||||
|
|
||||||
|
// Returns the binding description for the vertex
|
||||||
|
static fn getBindingDescription() -> vk::VertexInputBindingDescription {
|
||||||
|
return { .binding = 0, .stride = sizeof(Vertex), .inputRate = vk::VertexInputRate::eVertex };
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns the attribute descriptions for the vertex
|
||||||
|
static fn getAttributeDescriptions() -> std::array<vk::VertexInputAttributeDescription, 3> {
|
||||||
|
return {
|
||||||
|
// Position attribute
|
||||||
|
vk::VertexInputAttributeDescription { 0, 0, vk::Format::eR32G32B32Sfloat, offsetof(Vertex, pos) },
|
||||||
|
// Color attribute
|
||||||
|
vk::VertexInputAttributeDescription { 1, 0, vk::Format::eR32G32B32Sfloat, offsetof(Vertex, color) },
|
||||||
|
// Texture coordinate attribute
|
||||||
|
vk::VertexInputAttributeDescription { 2, 0, vk::Format::eR32G32Sfloat, offsetof(Vertex, tex_coord) }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Overload the equality operator for the vertex
|
||||||
|
fn operator==(const Vertex& other) const->bool {
|
||||||
|
return pos == other.pos && color == other.color && tex_coord == other.tex_coord;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Hash function for the vertex
|
||||||
|
namespace std {
|
||||||
|
template <>
|
||||||
|
struct hash<Vertex> {
|
||||||
|
fn operator()(Vertex const& vertex) const->size_t {
|
||||||
|
return ((hash<glm::vec3>()(vertex.pos) ^ (hash<glm::vec3>()(vertex.color) << 1)) >> 1) ^
|
||||||
|
(hash<glm::vec2>()(vertex.tex_coord) << 1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
BIN
textures/viking_room.png
Normal file
BIN
textures/viking_room.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 940 KiB |
Loading…
Reference in a new issue