PixelBullet  0.0.1
A C++ game engine
Loading...
Searching...
No Matches
render_resource_resolver_internal.h
1#pragma once
2
3#include "pixelbullet/assets/material.h"
4#include "pixelbullet/filesystem/filesystem.h"
5#include "pixelbullet/filesystem/virtual_path_serialization.h"
6#include "pixelbullet/private/graphics/rendering/buffers/morph_mesh_resource.h"
7#include "pixelbullet/private/graphics/rendering/buffers/skinned_mesh_resource.h"
8#include "pixelbullet/private/graphics/rendering/buffers/skinned_morph_mesh_resource.h"
9#include "pixelbullet/private/graphics/rendering/buffers/static_mesh_resource.h"
10#include "pixelbullet/private/graphics/runtime_support/images/image_2d.h"
11#include "pixelbullet/scene/scene_environment_settings.h"
12#include "pixelbullet/serialization/node.h"
13
14#include <optional>
15#include <string>
16#include <vector>
17
18namespace pixelbullet::render_resource_resolver_internal
19{
20inline constexpr VkSamplerAddressMode k_cubemap_address_mode = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
21inline constexpr bool k_enable_anisotropic = true;
22inline constexpr bool k_enable_mipmap = true;
23inline constexpr std::string_view k_cubemap_file_suffix = ".png";
24inline constexpr std::string_view k_cubemap_authored_mip_directory = "mips";
25
27{
28 VkFilter mag_filter = VK_FILTER_LINEAR;
29 VkFilter min_filter = VK_FILTER_LINEAR;
30 VkSamplerMipmapMode mipmap_mode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
31 VkSamplerAddressMode address_mode_u = VK_SAMPLER_ADDRESS_MODE_REPEAT;
32 VkSamplerAddressMode address_mode_v = VK_SAMPLER_ADDRESS_MODE_REPEAT;
33 VkSamplerAddressMode address_mode_w = VK_SAMPLER_ADDRESS_MODE_REPEAT;
34 bool anisotropic = true;
35 bool mipmap = true;
36};
37
38inline std::string BuildLogicalPathKey(const VirtualPath& path)
39{
40 return std::string(path.LogicalPath());
41}
42
43inline std::string BuildTextureVariantKey(const VirtualPath& texture_path, const MaterialTextureSamplerSettings& sampler)
44{
45 std::string key = std::string(texture_path.LogicalPath());
46 key += "|";
47 key += ToString(sampler.wrap_u);
48 key += "|";
49 key += ToString(sampler.wrap_v);
50 key += "|";
51 key += ToString(sampler.mag_filter);
52 key += "|";
53 key += ToString(sampler.min_filter);
54 return key;
55}
56
57inline VkSamplerAddressMode ToVulkanAddressMode(const MaterialTextureWrapMode wrap_mode) noexcept
58{
59 switch (wrap_mode)
60 {
61 case MaterialTextureWrapMode::ClampToEdge:
62 return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
63 case MaterialTextureWrapMode::MirroredRepeat:
64 return VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT;
65 case MaterialTextureWrapMode::Repeat:
66 default:
67 return VK_SAMPLER_ADDRESS_MODE_REPEAT;
68 }
69}
70
71inline VkFilter ToVulkanMagFilter(const MaterialTextureMagFilter filter) noexcept
72{
73 return filter == MaterialTextureMagFilter::Nearest ? VK_FILTER_NEAREST : VK_FILTER_LINEAR;
74}
75
76inline TextureSamplingOptions BuildTextureSamplingOptions(const MaterialTextureSamplerSettings& sampler) noexcept
77{
79 options.mag_filter = ToVulkanMagFilter(sampler.mag_filter);
80 options.address_mode_u = ToVulkanAddressMode(sampler.wrap_u);
81 options.address_mode_v = ToVulkanAddressMode(sampler.wrap_v);
82 options.address_mode_w = options.address_mode_v;
83
84 switch (sampler.min_filter)
85 {
86 case MaterialTextureMinFilter::Nearest:
87 options.min_filter = VK_FILTER_NEAREST;
88 options.mipmap_mode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
89 options.mipmap = false;
90 break;
91 case MaterialTextureMinFilter::Linear:
92 options.min_filter = VK_FILTER_LINEAR;
93 options.mipmap_mode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
94 options.mipmap = false;
95 break;
96 case MaterialTextureMinFilter::NearestMipmapNearest:
97 options.min_filter = VK_FILTER_NEAREST;
98 options.mipmap_mode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
99 options.mipmap = true;
100 break;
101 case MaterialTextureMinFilter::LinearMipmapNearest:
102 options.min_filter = VK_FILTER_LINEAR;
103 options.mipmap_mode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
104 options.mipmap = true;
105 break;
106 case MaterialTextureMinFilter::NearestMipmapLinear:
107 options.min_filter = VK_FILTER_NEAREST;
108 options.mipmap_mode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
109 options.mipmap = true;
110 break;
111 case MaterialTextureMinFilter::LinearMipmapLinear:
112 default:
113 options.min_filter = VK_FILTER_LINEAR;
114 options.mipmap_mode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
115 options.mipmap = true;
116 break;
117 }
118
119 const bool fully_linear = options.mag_filter == VK_FILTER_LINEAR && options.min_filter == VK_FILTER_LINEAR &&
120 (!options.mipmap || options.mipmap_mode == VK_SAMPLER_MIPMAP_MODE_LINEAR);
121 options.anisotropic = fully_linear;
122 return options;
123}
124
125inline Node BuildTextureCacheKey(const VirtualPath& texture_path, const MaterialTextureSamplerSettings& sampler)
126{
127 const TextureSamplingOptions options = BuildTextureSamplingOptions(sampler);
128 return Image2D::BuildCacheKey(texture_path, options.mag_filter, options.min_filter, options.mipmap_mode, options.address_mode_u,
129 options.address_mode_v, options.address_mode_w, options.anisotropic, options.mipmap);
130}
131
132inline VirtualPath BuildCubemapMipFacePath(const VirtualPath& cubemap_root, const uint32_t mip_level, std::string_view face_name)
133{
134 return cubemap_root / std::string(k_cubemap_authored_mip_directory) / std::to_string(mip_level) /
135 (std::string(face_name) + std::string(k_cubemap_file_suffix));
136}
137
138inline std::optional<uint32_t> DetectAuthoredCubemapMipCount(const Filesystem& filesystem, const VirtualPath& cubemap_root)
139{
140 std::optional<uint32_t> mip_count;
141 for (uint32_t mip_level = 0u;; ++mip_level)
142 {
143 bool any_faces_found = false;
144 bool all_faces_found = true;
145 for (const std::string_view face_name : k_scene_environment_cubemap_faces)
146 {
147 const bool face_exists = filesystem.Exists(BuildCubemapMipFacePath(cubemap_root, mip_level, face_name));
148 any_faces_found = any_faces_found || face_exists;
149 all_faces_found = all_faces_found && face_exists;
150 }
151
152 if (!any_faces_found)
153 {
154 break;
155 }
156 if (!all_faces_found)
157 {
158 return std::nullopt;
159 }
160
161 mip_count = mip_level + 1u;
162 }
163
164 return mip_count;
165}
166
167inline Node BuildCubemapCacheKey(const VirtualPath& cubemap_root, const bool authored_mip_chain)
168{
169 Node node;
170 node["assetPath"] << cubemap_root;
171 node["fileSuffix"] << std::string(k_cubemap_file_suffix);
172
173 std::vector<std::string> file_sides;
174 file_sides.reserve(k_scene_environment_cubemap_faces.size());
175 for (const std::string_view face_name : k_scene_environment_cubemap_faces)
176 {
177 file_sides.emplace_back(face_name);
178 }
179 node["fileSides"] << file_sides;
180
181 node["filter"] << VK_FILTER_LINEAR;
182 node["addressMode"] << k_cubemap_address_mode;
183 node["anisotropic"] << k_enable_anisotropic;
184 node["mipmap"] << k_enable_mipmap;
185 node["authoredMipChain"] << authored_mip_chain;
186 return node;
187}
188
189inline Node BuildStaticMeshCacheKey(const VirtualPath& mesh_path)
190{
191 return StaticMeshResource::BuildCacheKey(mesh_path);
192}
193
194inline Node BuildMorphMeshCacheKey(const VirtualPath& mesh_path)
195{
196 return MorphMeshResource::BuildCacheKey(mesh_path);
197}
198
199inline Node BuildSkinnedMeshCacheKey(const VirtualPath& mesh_path)
200{
201 return SkinnedMeshResource::BuildCacheKey(mesh_path);
202}
203
204inline Node BuildSkinnedMorphMeshCacheKey(const VirtualPath& mesh_path)
205{
206 return SkinnedMorphMeshResource::BuildCacheKey(mesh_path);
207}
208
209inline bool HasCompleteCubemap(const Filesystem& filesystem, const VirtualPath& cubemap_root)
210{
211 const std::optional<uint32_t> authored_mip_count = DetectAuthoredCubemapMipCount(filesystem, cubemap_root);
212 if (authored_mip_count.has_value())
213 {
214 return *authored_mip_count > 0u;
215 }
216
217 for (const std::string_view face_name : k_scene_environment_cubemap_faces)
218 {
219 if (!filesystem.Exists(cubemap_root / (std::string(face_name) + std::string(k_cubemap_file_suffix))))
220 {
221 return false;
222 }
223 }
224 return true;
225}
226} // namespace pixelbullet::render_resource_resolver_internal
Definition virtual_path.h:10
Definition render_resource_resolver_internal.h:27