16#ifndef ACMXVK_BUILD_RESOURCE_DIRECTORY
17#define ACMXVK_BUILD_RESOURCE_DIRECTORY "."
20#ifndef ACMXVK_INSTALL_RESOURCE_DIRECTORY
21#define ACMXVK_INSTALL_RESOURCE_DIRECTORY "."
24#ifndef ACMXVK_BUILD_SPRITE_VERTEX_SHADER
25#define ACMXVK_BUILD_SPRITE_VERTEX_SHADER "sprite.vert.spv"
28#ifndef ACMXVK_INSTALL_SPRITE_VERTEX_SHADER
29#define ACMXVK_INSTALL_SPRITE_VERTEX_SHADER "sprite.vert.spv"
32#ifndef ACMXVK_BUILD_ECHO_CACHE_SHADER
33#define ACMXVK_BUILD_ECHO_CACHE_SHADER "echo_cache.frag.spv"
36#ifndef ACMXVK_INSTALL_ECHO_CACHE_SHADER
37#define ACMXVK_INSTALL_ECHO_CACHE_SHADER "echo_cache.frag.spv"
40#ifndef ACMXVK_BUILD_FLIP_SHADER
41#define ACMXVK_BUILD_FLIP_SHADER "flip.frag.spv"
44#ifndef ACMXVK_INSTALL_FLIP_SHADER
45#define ACMXVK_INSTALL_FLIP_SHADER "flip.frag.spv"
48#ifndef ACMXVK_BUILD_PASSTHROUGH_SHADER
49#define ACMXVK_BUILD_PASSTHROUGH_SHADER "passthrough.frag.spv"
52#ifndef ACMXVK_INSTALL_PASSTHROUGH_SHADER
53#define ACMXVK_INSTALL_PASSTHROUGH_SHADER "passthrough.frag.spv"
56#ifndef ACMXVK_BUILD_HDR_TRANSFER_DIRECTORY
57#define ACMXVK_BUILD_HDR_TRANSFER_DIRECTORY "."
60#ifndef ACMXVK_INSTALL_HDR_TRANSFER_DIRECTORY
61#define ACMXVK_INSTALL_HDR_TRANSFER_DIRECTORY "."
64#ifndef ACMXVK_BUILD_HUMAN_COMPOSITE_SHADER
65#define ACMXVK_BUILD_HUMAN_COMPOSITE_SHADER "human_composite.frag.spv"
68#ifndef ACMXVK_INSTALL_HUMAN_COMPOSITE_SHADER
69#define ACMXVK_INSTALL_HUMAN_COMPOSITE_SHADER "human_composite.frag.spv"
72#ifndef ACMXVK_BUILD_MODEL_VERTEX_SHADER
73#define ACMXVK_BUILD_MODEL_VERTEX_SHADER "model.vert.spv"
76#ifndef ACMXVK_INSTALL_MODEL_VERTEX_SHADER
77#define ACMXVK_INSTALL_MODEL_VERTEX_SHADER "model.vert.spv"
80#ifndef ACMXVK_BUILD_MODEL_FRAGMENT_SHADER
81#define ACMXVK_BUILD_MODEL_FRAGMENT_SHADER "model.frag.spv"
84#ifndef ACMXVK_INSTALL_MODEL_FRAGMENT_SHADER
85#define ACMXVK_INSTALL_MODEL_FRAGMENT_SHADER "model.frag.spv"
88#ifndef ACMXVK_BUILD_DEFAULT_MODEL
89#define ACMXVK_BUILD_DEFAULT_MODEL "cube.obj"
92#ifndef ACMXVK_INSTALL_DEFAULT_MODEL
93#define ACMXVK_INSTALL_DEFAULT_MODEL "cube.obj"
96#ifndef ACMXVK_BUILD_OVERLAY_FONT
97#define ACMXVK_BUILD_OVERLAY_FONT "font.ttf"
100#ifndef ACMXVK_INSTALL_OVERLAY_FONT
101#define ACMXVK_INSTALL_OVERLAY_FONT "font.ttf"
104#ifndef ACMXVK_BUILD_CROSSFADE_DIRECTORY
105#define ACMXVK_BUILD_CROSSFADE_DIRECTORY "shaders/xfade"
108#ifndef ACMXVK_INSTALL_CROSSFADE_DIRECTORY
109#define ACMXVK_INSTALL_CROSSFADE_DIRECTORY "shaders/xfade"
115 [[nodiscard]] fs::path executable_resource_directory() {
116 std::vector<wchar_t> buffer(MAX_PATH);
118 const DWORD
length = GetModuleFileNameW(
119 nullptr, buffer.data(),
120 static_cast<DWORD
>(buffer.size()));
124 if (
length < buffer.size() - 1U) {
125 const std::wstring executable_name(buffer.data(),
length);
126 const fs::path executable(executable_name);
127 return executable.parent_path().parent_path() /
"share" /
130 if (buffer.size() >= 32768U) {
133 buffer.resize(buffer.size() * 2U);
138 [[nodiscard]] fs::path
140 const fs::path &installed_path,
141 const fs::path &built_path) {
142 const fs::path resource =
find_resource(options, relative_path);
143 if (!resource.empty()) {
146 if (fs::is_regular_file(installed_path)) {
147 return installed_path;
154 std::vector<fs::path> directories;
155 const auto append = [&](
const fs::path &directory) {
156 if (directory.empty()) {
159 const fs::path normalized =
160 fs::absolute(directory).lexically_normal();
161 if (std::find(directories.begin(), directories.end(), normalized) ==
163 directories.push_back(normalized);
170 append(executable_resource_directory());
172 append(fs::current_path());
177 const fs::path &relative_path) {
178 if (relative_path.empty() || relative_path.is_absolute()) {
181 const fs::path normalized_relative = relative_path.lexically_normal();
182 const std::string relative_text = normalized_relative.generic_string();
183 if (relative_text ==
".." || relative_text.starts_with(
"../") ||
184 relative_text.find(
"/../") != std::string::npos) {
188 const fs::path candidate =
189 (directory / normalized_relative).lexically_normal();
190 if (fs::is_regular_file(candidate)) {
198 return resolve_resource(options,
"shaders/sprite.vert.spv",
204 return resolve_resource(options,
"shaders/echo_cache.frag.spv",
210 return resolve_resource(options,
"shaders/flip.frag.spv",
216 return resolve_resource(options,
"shaders/passthrough.frag.spv",
223 const std::string filename =
224 std::string(
"hdr_") + (hlg ?
"hlg_" :
"pq_") +
225 (encode ?
"encode.frag.spv" :
"decode.frag.spv");
226 return resolve_resource(
227 options, fs::path(
"shaders") / filename,
233 const std::string filename =
234 std::string(
"hdr_preview_") + (hlg ?
"hlg" :
"pq") +
236 return resolve_resource(
237 options, fs::path(
"shaders") / filename,
243 return resolve_resource(options,
"shaders/human_composite.frag.spv",
249 std::size_t shader_index) {
251 throw std::out_of_range(
"crossfade shader index is out of range");
253 const std::string filename =
255 const fs::path resource =
256 find_resource(options, fs::path(
"shaders/xfade") / filename);
257 if (!resource.empty()) {
260 const fs::path installed =
262 if (fs::is_regular_file(installed)) {
265 const fs::path built =
267 if (fs::is_regular_file(built)) {
270 throw std::runtime_error(
"crossfade shader was not found: " +
275 return resolve_resource(options,
"shaders/model.vert.spv",
281 return resolve_resource(options,
"shaders/model.frag.spv",
287 return resolve_resource(options,
"models/cube.obj",
293 return resolve_resource(options,
"data/font.ttf",
fs::path resolve_resource(const Options &options, const fs::path &relative_path, const fs::path &installed_path, const fs::path &built_path)
fs::path default_model_path(const Options &options)
fs::path echo_cache_shader_path(const Options &options)
fs::path human_composite_shader_path(const Options &options)
std::vector< fs::path > resource_directories(const Options &options)
fs::path model_fragment_shader_path(const Options &options)
fs::path model_vertex_shader_path(const Options &options)
fs::path passthrough_shader_path(const Options &options)
fs::path hdr_preview_shader_path(const Options &options, bool hlg)
fs::path crossfade_shader_path(const Options &options, std::size_t shader_index)
fs::path sprite_vertex_shader_path(const Options &options)
fs::path hdr_transfer_shader_path(const Options &options, bool hlg, bool encode)
constexpr std::array< std::string_view, 35 > CROSSFADE_NAMES
fs::path overlay_font_path(const Options &options)
fs::path flip_shader_path(const Options &options)
fs::path find_resource(const Options &options, const fs::path &relative_path)
#define ACMXVK_BUILD_MODEL_VERTEX_SHADER
#define ACMXVK_INSTALL_HDR_TRANSFER_DIRECTORY
#define ACMXVK_INSTALL_PASSTHROUGH_SHADER
#define ACMXVK_INSTALL_OVERLAY_FONT
#define ACMXVK_BUILD_HUMAN_COMPOSITE_SHADER
#define ACMXVK_BUILD_CROSSFADE_DIRECTORY
#define ACMXVK_BUILD_PASSTHROUGH_SHADER
#define ACMXVK_BUILD_ECHO_CACHE_SHADER
#define ACMXVK_BUILD_RESOURCE_DIRECTORY
#define ACMXVK_INSTALL_MODEL_VERTEX_SHADER
#define ACMXVK_INSTALL_RESOURCE_DIRECTORY
#define ACMXVK_INSTALL_SPRITE_VERTEX_SHADER
#define ACMXVK_BUILD_DEFAULT_MODEL
#define ACMXVK_INSTALL_HUMAN_COMPOSITE_SHADER
#define ACMXVK_INSTALL_MODEL_FRAGMENT_SHADER
#define ACMXVK_BUILD_FLIP_SHADER
#define ACMXVK_INSTALL_ECHO_CACHE_SHADER
#define ACMXVK_BUILD_SPRITE_VERTEX_SHADER
#define ACMXVK_INSTALL_FLIP_SHADER
#define ACMXVK_BUILD_OVERLAY_FONT
#define ACMXVK_INSTALL_CROSSFADE_DIRECTORY
#define ACMXVK_BUILD_MODEL_FRAGMENT_SHADER
#define ACMXVK_INSTALL_DEFAULT_MODEL
#define ACMXVK_BUILD_HDR_TRANSFER_DIRECTORY
std::string resource_directory