From 7536dd705d121ed3a49b7e4b05af88fd241d1674 Mon Sep 17 00:00:00 2001 From: vimene Date: Sun, 15 Feb 2026 15:11:49 +0100 Subject: more improvements in builds setup - moved slang shaders to spvshaders to separate software and hardware shaders - split Makefile.am into Makefile.am, src/Makefile.am and src/spvshaders/Makefile.am - build shaders as DATA primary, instead of both PROGRAMS and SCRIPTS, which greatly simplifies building. Before that, we had to first build them as PROGRAMS, and then copy them as SCRIPTS to remove executable extensions (i.e. ".exe" for Windows) - changed final executable dir from enginedir to bindir, which makes automake see it as an exec instead of data - compute relative paths from C++, which makes it possible to change dirs arbitrarily when running make while still having a relocatable executable - updated README.md to reflect changes in dirs - use AX_COMPARE_VERSION() to simplify checking if Vulkan headers version is correct - factored out most of paths computation in engine::path_utils::Paths --- .gitignore | 2 +- Makefile.am | 88 ++------------------------------------------- README.md | 22 ++++++------ common.am | 4 +++ configure.ac | 79 +++++++++++++++------------------------- src/Makefile.am | 61 +++++++++++++++++++++++++++++++ src/engine.cpp | 27 ++++++-------- src/path_utils.cpp | 14 ++++++++ src/path_utils.hpp | 20 +++++++++++ src/shaders/shader.slang | 48 ------------------------- src/spvshaders/Makefile.am | 9 +++++ src/spvshaders/shader.slang | 48 +++++++++++++++++++++++++ 12 files changed, 211 insertions(+), 211 deletions(-) create mode 100644 common.am create mode 100644 src/Makefile.am delete mode 100644 src/shaders/shader.slang create mode 100644 src/spvshaders/Makefile.am create mode 100644 src/spvshaders/shader.slang diff --git a/.gitignore b/.gitignore index 0e5e946..ec09064 100644 --- a/.gitignore +++ b/.gitignore @@ -14,7 +14,7 @@ Makefile Makefile.in /aclocal.m4 /build-aux/ -/m4/pkg.m4 +/m4/*.m4 /configure /configure~ /src/config.h diff --git a/Makefile.am b/Makefile.am index 1930529..6e7a500 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,27 +1,9 @@ +include common.am + +SUBDIRS = src src/spvshaders EXTRA_DIST = m4/NOTES ACLOCAL_AMFLAGS = -Im4 --install -# TODO: right now, the source tree and the install tree must share the same structure, which is very -# bad, because for example this causes "src" to be used as a final directory -# TODO: make variable for each subdirectory name, instead of copying it everywhere -# TODO: we shouldn't have everything in a single Makefile.am -if DEBUG -ASSETS_DIR_CPP = $(srcdir)/assets -ASSETS_OBJS_DIR_CPP = $(srcdir)/assets/objs -ASSETS_TEXTURES_DIR_CPP = $(srcdir)/assets/textures -SHADERS_DIR_CPP = $(builddir) -else -ASSETS_DIR_CPP = assets -ASSETS_OBJS_DIR_CPP = assets/objs -ASSETS_TEXTURES_DIR_CPP = assets/textures -SHADERS_DIR_CPP = shaders -endif - -enginedir = $(datarootdir)/engine -assetsdir = $(enginedir)/assets -assets_objsdir = $(assetsdir)/objs -assets_texturesdir = $(assetsdir)/textures -shadersdir = $(enginedir)/shaders assets_objs_DATA = \ assets/objs/suzanne.obj \ assets/objs/viking_room.obj @@ -41,67 +23,3 @@ EXTRA_DIST += $(assets_objs_DATA) $(assets_textures_DATA) # comes from here https://sketchfab.com/3d-models/viking-room-a49f1b8e4f5c4ecf9e1fe7d81915ad38, # modified by the author(s) of the vulkan tutorials (see # https://docs.vulkan.org/tutorial/latest/08_Loading_models.html#_sample_mesh) - -engine_PROGRAMS = engine -shaders_SCRIPTS = shader.spv -noinst_PROGRAMS = shader.spv.rmext -CLEANFILES = shader.spv shader.spv.rmext - -engine_SOURCES = \ - src/engine.cpp \ - src/renderer.hpp src/renderer.cpp \ - src/obj_parser.hpp src/obj_parser.cpp \ - src/vulkan_utils.hpp \ - src/path_utils.hpp src/path_utils.cpp \ - src/stb_image.h \ - src/stb_image.cpp \ - src/fb/fb.hpp \ - src/fb/chfb.hpp src/fb/chfb.cpp \ - src/fb/pixfb.hpp src/fb/pixfb.cpp \ - src/math/utils.hpp \ - src/math/vector.hpp \ - src/math/mat4.hpp \ - src/math/quat.hpp \ - src/math/tform.hpp \ - src/o3d/mesh.hpp src/o3d/mesh.cpp \ - src/o3d/obj3d.hpp \ - src/o3d/vertex.hpp \ - src/o3d/deriv_vertex.hpp \ - src/o3d/tri.hpp \ - src/o3d/tri_deriv.hpp \ - src/o3d/polygon.hpp \ - src/o3d/camera.hpp \ - src/o3d/scene.hpp \ - src/ctrl/keyboard.hpp \ - src/ctrl/mouse.hpp \ - src/shaders/shaders.hpp \ - src/shaders/simple_shaders.hpp src/shaders/simple_shaders.cpp - -shader_spv_rmext_SOURCES = src/shaders/shader.slang - -engine_CPPFLAGS = -std=gnu++23 -Wall -Wextra -I'$(srcdir)/src' \ - -DASSETS_DIR='"$(ASSETS_DIR_CPP)"' \ - -DASSETS_OBJS_DIR='"$(ASSETS_OBJS_DIR_CPP)"' \ - -DASSETS_TEXTURES_DIR='"$(ASSETS_TEXTURES_DIR_CPP)"' \ - -DSHADERS_DIR='"$(SHADERS_DIR_CPP)"' \ - $(GLFW3_CFLAGS) $(VULKAN_CFLAGS) -if !DEBUG -engine_CPPFLAGS += -DNDEBUG -endif -engine_LDFLAGS = -std=gnu++23 -Wall -Wextra -engine_LDADD = $(GLFW3_LIBS) $(VULKAN_LIBS) - -if HAVE_NCURSES -engine_CPPFLAGS += $(NCURSES_CFLAGS) -engine_LDADD += $(NCURSES_LIBS) -endif - -src/engine-stb_image.$(OBJEXT): CXXFLAGS += -Wno-unused-but-set-variable - -shader_spv_rmext_SLANGFLAGS = -target spirv -profile spirv_1_4 -emit-spirv-directly -fvk-use-entrypoint-name -entry vert_main -entry frag_main - -shader.spv.rmext$(EXEEXT): src/shaders/shader.slang - $(SLANGC) $(shader_spv_rmext_SLANGFLAGS) -o $@ $< - -shader.spv: shader.spv.rmext$(EXEEXT) - cp -f $< $@ diff --git a/README.md b/README.md index 9ce7885..2141e3f 100644 --- a/README.md +++ b/README.md @@ -55,7 +55,7 @@ While inside the directory containing all files: :::sh mkdir build cd build - ../configure --prefix="$(realpath .)" --with-ncurses + ../configure --prefix="$(realpath .)" --bindir="$(realpath share/engine)" --with-ncurses make make install @@ -70,7 +70,7 @@ than the ones given by `pkgconf`, you have to set both `GLFW3_CFLAGS` and `GLFW3 `configure` command line, like so: :::sh - ../configure --prefix="$(realpath .)" --with-ncurses \ + ../configure --prefix="$(realpath .)" --bindir="$(realpath share/engine)" --with-ncurses \ GLFW3_CFLAGS=-I/path/to/glfw/headers \ GLFW3_LIBS=-L/path/to/glfw/libs -lglfw3 @@ -79,7 +79,7 @@ LunarG's Vulkan SDK, you have to set both `VULKAN_CFLAGS` and `VULKAN_LIBS` in t command line, like so: :::sh - ../configure --prefix="$(realpath .)" --with-ncurses \ + ../configure --prefix="$(realpath .)" --bindir="$(realpath share/engine)" --with-ncurses \ VULKAN_CFLAGS=-I/path/to/vulkan/headers \ VULKAN_LIBS=-L/path/to/vulkan/libs -lvulkan @@ -87,7 +87,7 @@ If `slangc` cannot be found in path, or if you also want to use the one given by SDK, you have to set `SLANGC` to the path of the executable, like so: :::sh - ../configure --prefix="$(realpath .)" --with-ncurses \ + ../configure --prefix="$(realpath .)" --bindir="$(realpath share/engine)" --with-ncurses \ SLANGC=/path/to/slangc If ncurses headers or libncurses.so cannot be found, or if you want to use ones other than the ones @@ -95,14 +95,14 @@ given by `pkgconf`, you have to set both `NCURSES_CFLAGS` and `NCURSES_LIBS` in command line, like so: :::sh - ../configure --prefix="$(realpath .)" --with-ncurses \ + ../configure --prefix="$(realpath .)" --bindir="$(realpath share/engine)" --with-ncurses \ NCURSES_CFLAGS=-I/path/to/ncurses/headers \ NCURSES_LIBS=-L/path/to/ncurses/libs -lvulkan You can, of course, combine as many as you like: :::sh - ../configure --prefix="$(realpath .)" --with-ncurses \ + ../configure --prefix="$(realpath .)" --bindir="$(realpath share/engine)" --with-ncurses \ GLFW3_CFLAGS=-I/path/to/glfw/headers \ GLFW3_LIBS=-L/path/to/glfw/libs -lglfw3 \ VULKAN_CFLAGS=-I/path/to/vulkan/headers \ @@ -134,7 +134,7 @@ While inside the directory containing all files: :::sh mkdir build cd build - ../configure --prefix="$(realpath .)" \ + ../configure --prefix="$(realpath .)" --bindir="$(realpath share/engine)" \ --build x86_64-pc-linux-gnu \ --host x86_64-w64-mingw32 make @@ -153,7 +153,7 @@ than the ones given by `pkgconf`, you have to set both `GLFW3_CFLAGS` and `GLFW3 `configure` command line, like so: :::sh - ../configure --prefix="$(realpath .)" \ + ../configure --prefix="$(realpath .)" --bindir="$(realpath share/engine)" \ --build x86_64-pc-linux-gnu \ --host x86_64-w64-mingw32 \ GLFW3_CFLAGS=-I/path/to/glfw/headers \ @@ -164,7 +164,7 @@ LunarG's Vulkan SDK, you have to set both `VULKAN_CFLAGS` and `VULKAN_LIBS` in t command line, like so: :::sh - ../configure --prefix="$(realpath .)" \ + ../configure --prefix="$(realpath .)" --bindir="$(realpath share/engine)" \ --build x86_64-pc-linux-gnu \ --host x86_64-w64-mingw32 \ VULKAN_CFLAGS=-I/path/to/vulkan/headers \ @@ -174,7 +174,7 @@ If `slangc` cannot be found in path, or if you also want to use the one given by SDK, you have to set `SLANGC` to the path of the executable, like so: :::sh - ../configure --prefix="$(realpath .)" \ + ../configure --prefix="$(realpath .)" --bindir="$(realpath share/engine)" \ --build x86_64-pc-linux-gnu \ --host x86_64-w64-mingw32 \ SLANGC=/path/to/slangc @@ -182,7 +182,7 @@ SDK, you have to set `SLANGC` to the path of the executable, like so: You can, of course, combine as many as you like: :::sh - ../configure --prefix="$(realpath .)" \ + ../configure --prefix="$(realpath .)" --bindir="$(realpath share/engine)" \ --build x86_64-pc-linux-gnu \ --host x86_64-w64-mingw32 \ GLFW3_CFLAGS=-I/path/to/glfw/headers \ diff --git a/common.am b/common.am new file mode 100644 index 0000000..e54bb09 --- /dev/null +++ b/common.am @@ -0,0 +1,4 @@ +assetsdir = $(pkgdatadir)/assets +assets_objsdir = $(assetsdir)/objs +assets_texturesdir = $(assetsdir)/textures +spvshadersdir = $(pkgdatadir)/spvshaders diff --git a/configure.ac b/configure.ac index 744694d..959b07c 100644 --- a/configure.ac +++ b/configure.ac @@ -5,9 +5,14 @@ AC_CONFIG_HEADERS([src/config.h]) AC_CONFIG_AUX_DIR([build-aux]) AC_CONFIG_MACRO_DIR([m4]) AM_INIT_AUTOMAKE([foreign subdir-objects]) -AC_CONFIG_FILES([Makefile]) +AC_CONFIG_FILES([Makefile src/Makefile src/spvshaders/Makefile]) AC_REQUIRE_AUX_FILE([tap-driver.sh]) +CXXFLAGS_save="$CXXFLAGS" +LIBS_save="$LIBS" +CXXFLAGS= +LIBS= + AC_PROG_CXX AC_PROG_AWK AC_PROG_INSTALL @@ -43,59 +48,33 @@ PKG_CHECK_MODULES([GLFW3], [glfw3 >= 3.3.10]) PKG_CHECK_MODULES([VULKAN], [vulkan]) PKG_HAVE_DEFINE_WITH_MODULES([NCURSES], [ncurses >= 6.4.20230625]) -AC_LANG([C++]) -CXXFLAGS_save="$CXXFLAGS" -LIBS_save="$LIBS" - -# ENGINE_VULKAN_VER(VARIANT, MAJOR, MINOR, PATCH, [CMP]) -# ------------------------------------------------------ -m4_define([ENGINE_VULKAN_VER], [[variant ]$1[ version ]ifelse([$#], [5], [$5[ ]], [[]])$2[.]$3[.]$4]) +AC_LANG_PUSH([C++]) m4_define([vulkan_required_api_variant], [[0]]) -m4_define([vulkan_required_api_major], [[1]]) -m4_define([vulkan_required_api_minor], [[4]]) -m4_define([vulkan_required_api_patch], [[313]]) -m4_define([vulkan_required_api_str], - [ENGINE_VULKAN_VER( - [vulkan_required_api_variant], - [vulkan_required_api_major], - [vulkan_required_api_minor], - [vulkan_required_api_patch], - [[>=]])]) -AC_MSG_CHECKING([for Vulkan headers ]vulkan_required_api_str) +m4_define([vulkan_required_api], [[1.4.313]]) +AC_MSG_CHECKING( + [if Vulkan headers are variant ]vulkan_required_api_variant[ and version at least ]vulkan_required_api) CXXFLAGS="$VULKAN_CFLAGS" -AC_COMPUTE_INT([vulkan_api], [VK_HEADER_VERSION_COMPLETE], [ -#include -], [AC_MSG_ERROR([cannot check Vulkan headers version])]) -AS_VAR_ARITH([vulkan_api_variant], [$vulkan_api \>\> 29]) -AS_VAR_ARITH([vulkan_api_major], [\( $vulkan_api \>\> 22 \) \& 127]) -AS_VAR_ARITH([vulkan_api_minor], [\( $vulkan_api \>\> 12 \) \& 1023]) -AS_VAR_ARITH([vulkan_api_patch], [$vulkan_api \& 4095]) -vulkan_api_str="ENGINE_VULKAN_VER([[$vulkan_api_variant]], [[$vulkan_api_major]], [[$vulkan_api_minor]], [[$vulkan_api_patch]])" -vulkan_version_ok=no -AS_VAR_IF([vulkan_api_variant], vulkan_required_api_variant, [ - AS_VAR_ARITH([vulkan_version_cmp], [$vulkan_api_major \>= ]vulkan_required_api_major) - AS_VAR_IF([vulkan_version_cmp], [1], [ - AS_VAR_ARITH([vulkan_version_cmp], [$vulkan_api_major \> ]vulkan_required_api_major) - AS_VAR_IF([vulkan_version_cmp], [1], [vulkan_version_ok=yes], [ - AS_VAR_ARITH([vulkan_version_cmp], [$vulkan_api_minor \>= ]vulkan_required_api_minor) - AS_VAR_IF([vulkan_version_cmp], [1], [ - AS_VAR_ARITH([vulkan_version_cmp], [$vulkan_api_minor \> ]vulkan_required_api_minor) - AS_VAR_IF([vulkan_version_cmp], [1], [vulkan_version_ok=yes], [ - AS_VAR_ARITH([vulkan_version_cmp], [$vulkan_api_patch \>= ]vulkan_required_api_patch) - AS_VAR_IF([vulkan_version_cmp], [1], [vulkan_version_ok=yes]) - ]) - ]) - ]) - ]) +AC_COMPUTE_INT([vulkan_api_int], [VK_HEADER_VERSION_COMPLETE], + [#include ], + [AC_MSG_ERROR([cannot check Vulkan headers version])]) +AS_VAR_ARITH([vulkan_api_variant], [$][vulkan_api_int \>\> 29]) +AS_VAR_ARITH([vulkan_api_major], [\( ][$][vulkan_api_int \>\> 22 \) \& 127]) +AS_VAR_ARITH([vulkan_api_minor], [\( ][$][vulkan_api_int \>\> 12 \) \& 1023]) +AS_VAR_ARITH([vulkan_api_patch], [$][vulkan_api_int \& 4095]) +vulkan_api="[$]vulkan_api_major.[$]vulkan_api_minor.[$]vulkan_api_patch" +AS_VAR_IF([vulkan_api_variant], vulkan_required_api_variant,, [ + AC_MSG_RESULT([no]) + AC_MSG_ERROR( + [Vulkan headers are variant ][$][vulkan_api_variant, but variant ]vulkan_required_api_variant[ required]) ]) -AS_VAR_IF([vulkan_version_ok], [yes], - [AC_MSG_RESULT([yes])], - [ - AC_MSG_RESULT([no]) - AC_MSG_ERROR( - [Vulkan headers $vulkan_api_str found, but ]vulkan_required_api_str[ required]) - ]) +AX_COMPARE_VERSION([$][vulkan_api], [ge], vulkan_required_api, [AC_MSG_RESULT([yes])], [ + AC_MSG_RESULT([no]) + AC_MSG_ERROR( + [Vulkan headers are version ][$][vulkan_api, but version at least ]vulkan_required_api[ required]) +]) + +AC_LANG_POP([C++]) CXXFLAGS="$CXXFLAGS_save" LIBS="$LIBS_save" diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 0000000..00e76ac --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,61 @@ +include ../common.am + +bin_PROGRAMS = engine + +engine_SOURCES = \ + engine.cpp \ + renderer.hpp renderer.cpp \ + obj_parser.hpp obj_parser.cpp \ + vulkan_utils.hpp \ + path_utils.hpp path_utils.cpp \ + stb_image.h \ + stb_image.cpp \ + fb/fb.hpp \ + fb/chfb.hpp fb/chfb.cpp \ + fb/pixfb.hpp fb/pixfb.cpp \ + math/utils.hpp \ + math/vector.hpp \ + math/mat4.hpp \ + math/quat.hpp \ + math/tform.hpp \ + o3d/mesh.hpp o3d/mesh.cpp \ + o3d/obj3d.hpp \ + o3d/vertex.hpp \ + o3d/deriv_vertex.hpp \ + o3d/tri.hpp \ + o3d/tri_deriv.hpp \ + o3d/polygon.hpp \ + o3d/camera.hpp \ + o3d/scene.hpp \ + ctrl/keyboard.hpp \ + ctrl/mouse.hpp \ + shaders/shaders.hpp \ + shaders/simple_shaders.hpp shaders/simple_shaders.cpp + +if DEBUG +BINDIR_CXX = $(abs_builddir) +SPVSHADERSDIR_CXX = $(abs_builddir)/spvshaders +PKGDATADIR_CXX = $(abs_top_srcdir) +else +BINDIR_CXX = $(bindir) +SPVSHADERSDIR_CXX = $(spvshadersdir) +PKGDATADIR_CXX = $(pkgdatadir) +endif + +engine_CPPFLAGS = -std=gnu++23 -Wall -Wextra -I'$(srcdir)/src' \ + -DBINDIR='"$(BINDIR_CXX)"' \ + -DPKGDATADIR='"$(PKGDATADIR_CXX)"' \ + -DSPVSHADERSDIR='"$(SPVSHADERSDIR_CXX)"' \ + $(GLFW3_CFLAGS) $(VULKAN_CFLAGS) +if !DEBUG +engine_CPPFLAGS += -DNDEBUG +endif +engine_LDFLAGS = -std=gnu++23 -Wall -Wextra +engine_LDADD = $(GLFW3_LIBS) $(VULKAN_LIBS) + +if HAVE_NCURSES +engine_CPPFLAGS += $(NCURSES_CFLAGS) +engine_LDADD += $(NCURSES_LIBS) +endif + +engine-stb_image.$(OBJEXT): CXXFLAGS += -Wno-unused-but-set-variable diff --git a/src/engine.cpp b/src/engine.cpp index a9991c4..1f57bd7 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -194,7 +194,7 @@ static void render_software(Renderer& renderer, const Matr #ifdef HAVE_NCURSES #define MKEY_ESC 27 -static int main_term(const std::filesystem::path& files_root, Scene& scene) { +static int main_term(const engine::path_utils::Paths& paths, Scene& scene) { // init std::setlocale(LC_ALL, ""); initscr(); @@ -206,7 +206,7 @@ static int main_term(const std::filesystem::path& files_root, Scene& scene) { curs_set(0); int texture_w, texture_h, texture_channels; - const auto texture_path = std::filesystem::path(files_root).append(ASSETS_TEXTURES_DIR "/viking_room.png"); + const auto texture_path = paths.assets_textures() / "viking_room.png"; #ifdef _WIN32 const auto texture_path_wcstr = texture_path.c_str(); const auto texture_path_cstr_size = stbi_convert_wchar_to_utf8(nullptr, 0, texture_path_wcstr); @@ -907,7 +907,7 @@ static void generate_mipmaps(VkCommandBuffer cmd_buf, VkPhysicalDevice physical_ } } -static int main_graphical(const std::filesystem::path& files_root, Scene& scene) { +static int main_graphical(const engine::path_utils::Paths& paths, Scene& scene) { // init window glfwInit(); glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); @@ -1581,7 +1581,7 @@ static int main_graphical(const std::filesystem::path& files_root, Scene& scene) // reading shader file auto shader_module = [&] { auto shader_code = [&] { - const auto shader_path = std::filesystem::path(files_root).append(SHADERS_DIR "/shader.spv"); + const auto shader_path = paths.spvshaders() / "shader.spv"; const auto shader_file_name = shader_path.c_str(); std::ifstream shader_file(shader_file_name, std::ios::ate | std::ios::binary); if (!shader_file.is_open()) { @@ -1832,7 +1832,7 @@ static int main_graphical(const std::filesystem::path& files_root, Scene& scene) // create texture image auto [texture_img, texture_mip_lvls, texture_img_device_mem, texture_w, texture_h, texture_pixels] = [&] { int w, h, channels; - const auto texture_path = std::filesystem::path(files_root).append(ASSETS_TEXTURES_DIR "/viking_room.png"); + const auto texture_path = paths.assets_textures() / "viking_room.png"; #ifdef _WIN32 const auto texture_path_wcstr = texture_path.c_str(); const auto texture_path_cstr_size = stbi_convert_wchar_to_utf8(nullptr, 0, texture_path_wcstr); @@ -2892,12 +2892,7 @@ static void parse_args(const std::vector& args, Mode& mode) { } int main(int argc, char *argv[]) { - const auto exe_path_opt = engine::path_utils::exe_path(); - if (!exe_path_opt) { - std::cerr << "cannot find path of executable" << std::endl; - exit(1); - } - const auto files_root = (*exe_path_opt).parent_path(); + const auto paths = engine::path_utils::Paths(); Mode mode = Mode::graphical; parse_args(convert_args(argc, argv), mode); @@ -2920,7 +2915,7 @@ int main(int argc, char *argv[]) { case GameType::suzanne: return { { - engine::parse_object(std::filesystem::path(files_root).append(ASSETS_OBJS_DIR "/suzanne.obj")), + engine::parse_object(paths.assets_objs() / "suzanne.obj"), { Vector3(0.f, 0.f, 0.f), Quaternion::one(), @@ -2939,7 +2934,7 @@ int main(int argc, char *argv[]) { } }, { - engine::parse_object(std::filesystem::path(files_root).append(ASSETS_OBJS_DIR "/suzanne.obj")), + engine::parse_object(paths.assets_objs() / "suzanne.obj"), { Vector3(0.f, 1.f, 0.f), Quaternion::one(), @@ -2950,7 +2945,7 @@ int main(int argc, char *argv[]) { case GameType::test: return { { - engine::parse_object(std::filesystem::path(files_root).append(ASSETS_OBJS_DIR "/viking_room.obj")), + engine::parse_object(paths.assets_objs() / "viking_room.obj"), { Vector3(0.f, .5f, 0.f), Quaternion::look_towards({ -1.f, 0.f, 0.f }, { 0.f, 0.f, 1.f }).conjugate(), @@ -2969,13 +2964,13 @@ int main(int argc, char *argv[]) { return EXIT_SUCCESS; case Mode::term: #ifdef HAVE_NCURSES - return main_term(files_root, scene); + return main_term(paths, scene); #else std::cerr << "Error: ncurses was not enabled during compilation." << std::endl; return EXIT_FAILURE; #endif case Mode::graphical: - return main_graphical(files_root, scene); + return main_graphical(paths, scene); default: std::unreachable(); } diff --git a/src/path_utils.cpp b/src/path_utils.cpp index df35ef1..94bbba5 100644 --- a/src/path_utils.cpp +++ b/src/path_utils.cpp @@ -1,4 +1,5 @@ #include "path_utils.hpp" +#include #include #include #ifdef _WIN32 @@ -18,3 +19,16 @@ std::optional engine::path_utils::exe_path() noexcept { # error "operating system not supported" #endif } + +engine::path_utils::Paths::Paths() noexcept { + const auto exe_path_opt = engine::path_utils::exe_path(); + if (!exe_path_opt) { + std::cerr << "cannot find path of executable" << std::endl; + exit(1); + } + const auto files_root = (*exe_path_opt).parent_path(); + + m_assets_objs = files_root / std::filesystem::relative(PKGDATADIR "/assets/objs", BINDIR); + m_assets_textures = files_root / std::filesystem::relative(PKGDATADIR "/assets/textures", BINDIR); + m_spvshaders = files_root / std::filesystem::relative(SPVSHADERSDIR, BINDIR); +} diff --git a/src/path_utils.hpp b/src/path_utils.hpp index e87aad6..76567bc 100644 --- a/src/path_utils.hpp +++ b/src/path_utils.hpp @@ -8,6 +8,26 @@ namespace engine::path_utils { std::optional exe_path() noexcept; +class Paths { + public: + Paths() noexcept; + + const std::filesystem::path& assets_objs() const & noexcept { + return m_assets_objs; + } + + const std::filesystem::path& assets_textures() const & noexcept { + return m_assets_textures; + } + + const std::filesystem::path& spvshaders() const & noexcept { + return m_spvshaders; + } + + private: + std::filesystem::path m_assets_objs, m_assets_textures, m_spvshaders; +}; + } #endif // PATH_UTILS_HPP diff --git a/src/shaders/shader.slang b/src/shaders/shader.slang deleted file mode 100644 index 245df4b..0000000 --- a/src/shaders/shader.slang +++ /dev/null @@ -1,48 +0,0 @@ -struct VertexInput { - float3 pos; - float3 normal; - float2 uv; -}; - -struct UniformBuffer { - float4x4 model, view, proj, inv_view; -}; - -ConstantBuffer ubo; - -struct VertexOutput { - float4 pos : SV_Position; - float3 world_loc; - float3 normal; - float2 uv; -}; - -[shader("vertex")] -VertexOutput vert_main(VertexInput vi) { - VertexOutput vo; - float4 world_loc = mul(ubo.model, float4(vi.pos, 1.)); - vo.pos = mul(ubo.proj, mul(ubo.view, world_loc)); - vo.world_loc = world_loc.xyz; - vo.normal = mul(ubo.model, float4(vi.normal, 0.)).xyz; - vo.uv = vi.uv; - return vo; -} - -Sampler2D texture; - -[shader("fragment")] -float4 frag_main(VertexOutput vo) : SV_Target { - // float3 u = vo.world_loc - (ubo.inv_view * float4(0., 0., 0., 1.)).xyz; - // float u_len_sq = dot(u, u); - // u = normalize(u); - // float attenuation = dot(mul(ubo.inv_view, float4(0., 0., -1., 0.)).xyz, u); - // if (attenuation < .7) attenuation = 0.f; - // else if (attenuation > .8) attenuation = 1.; - // else attenuation = (attenuation - .7) / .1; - // float light = -dot(vo.normal, u) / u_len_sq; - // if (light < 0.) light = 0.; - // float final_light = .003 + light * attenuation * .8 * .997; - // if (final_light > 1.) final_light = 1.; - // return float4(final_light, final_light, final_light, 1.); - return float4(texture.Sample(vo.uv).rgb, 1.f); -} diff --git a/src/spvshaders/Makefile.am b/src/spvshaders/Makefile.am new file mode 100644 index 0000000..5a5a362 --- /dev/null +++ b/src/spvshaders/Makefile.am @@ -0,0 +1,9 @@ +include ../../common.am + +spvshaders_DATA = shader.spv +CLEANFILES = shader.spv + +shader_spv_SLANGFLAGS = -target spirv -profile spirv_1_4 -emit-spirv-directly -fvk-use-entrypoint-name -entry vert_main -entry frag_main + +shader.spv: $(srcdir)/shader.slang + $(SLANGC) $(shader_spv_SLANGFLAGS) -o $@ $< diff --git a/src/spvshaders/shader.slang b/src/spvshaders/shader.slang new file mode 100644 index 0000000..245df4b --- /dev/null +++ b/src/spvshaders/shader.slang @@ -0,0 +1,48 @@ +struct VertexInput { + float3 pos; + float3 normal; + float2 uv; +}; + +struct UniformBuffer { + float4x4 model, view, proj, inv_view; +}; + +ConstantBuffer ubo; + +struct VertexOutput { + float4 pos : SV_Position; + float3 world_loc; + float3 normal; + float2 uv; +}; + +[shader("vertex")] +VertexOutput vert_main(VertexInput vi) { + VertexOutput vo; + float4 world_loc = mul(ubo.model, float4(vi.pos, 1.)); + vo.pos = mul(ubo.proj, mul(ubo.view, world_loc)); + vo.world_loc = world_loc.xyz; + vo.normal = mul(ubo.model, float4(vi.normal, 0.)).xyz; + vo.uv = vi.uv; + return vo; +} + +Sampler2D texture; + +[shader("fragment")] +float4 frag_main(VertexOutput vo) : SV_Target { + // float3 u = vo.world_loc - (ubo.inv_view * float4(0., 0., 0., 1.)).xyz; + // float u_len_sq = dot(u, u); + // u = normalize(u); + // float attenuation = dot(mul(ubo.inv_view, float4(0., 0., -1., 0.)).xyz, u); + // if (attenuation < .7) attenuation = 0.f; + // else if (attenuation > .8) attenuation = 1.; + // else attenuation = (attenuation - .7) / .1; + // float light = -dot(vo.normal, u) / u_len_sq; + // if (light < 0.) light = 0.; + // float final_light = .003 + light * attenuation * .8 * .997; + // if (final_light > 1.) final_light = 1.; + // return float4(final_light, final_light, final_light, 1.); + return float4(texture.Sample(vo.uv).rgb, 1.f); +} -- cgit v1.2.3