Rendering Engine 0.2.14
Modular Graphics Rendering Engine | v0.2.14
Loading...
Searching...
No Matches
utility.cpp
Go to the documentation of this file.
1#include "utility.hpp"
2#include <nlohmann/json.hpp>
3
4namespace rendering_engine
5{
6using namespace std::filesystem;
7
8path const Utility::sDefaultShadersBinaryRelativePath = {"/Content/Shaders/"};
9path const Utility::sContentRelativePathFolder = path{} / "Content";
10path const Utility::sTextureRelativePathFolder = sContentRelativePathFolder / "Textures";
11path const Utility::sModelsRelativePathFolder = sContentRelativePathFolder / "Models";
12path const Utility::sFontsRelativePathFolder = sContentRelativePathFolder / "Fonts";
13path const Utility::sShadersRelativePathFolder = sContentRelativePathFolder / "Shaders";
14path const Utility:: sAppConfigFilePath = path{} / "Config" / "app_config.json";
15path const Utility::sLogFolderPath = path{} / "Logs";
16
20
22static bool sPackEntriesLoaded = false;
23path const Utility::sContentPackageFilePath = path{} / "Content" / "Pack.bin";
24path const Utility::sContentPackEntriesFilePath = path{} / "Content" / "Pack.json";
25
26void Utility::InitializePaths(int argc, char* argv[])
27{
28 sApplicationPath = std::filesystem::path(argv[0]);
29
30 sBuildPath = FindPath( "Build" );
32}
33
35{
36 AppConfig cfg;
37
38 std::ifstream f(GetConfigFilePath().string());
39 if (!f.is_open())
40 {
41 return cfg;
42 }
43
44 try
45 {
46 nlohmann::json appConfigData = nlohmann::json::parse(f);
47
48 if (appConfigData.contains("appName"))
49 cfg.appName = appConfigData["appName"].get<std::string>();
50
51 if (appConfigData.contains("isFullScreen"))
52 cfg.isFullScreen = appConfigData["isFullScreen"].get<bool>();
53
54 if (appConfigData.contains("screenWidth"))
55 cfg.screenWidth = appConfigData["screenWidth"].get<float>();
56
57 if (appConfigData.contains("screenHeight"))
58 cfg.screenHeight = appConfigData["screenHeight"].get<float>();
59
60 if (appConfigData.contains("text"))
61 {
62 const auto& textNode = appConfigData["text"];
63
64 if (textNode.contains("scripts") && textNode["scripts"].is_array())
65 {
66 for (const auto& script : textNode["scripts"])
67 {
68 if (script.is_string())
69 {
70 auto found = std::find(cfg.textScripts.begin(), cfg.textScripts.end(), script);
71 if(found == cfg.textScripts.end())
72 {
73 cfg.textScripts.push_back(script.get<std::string>());
74 }
75 }
76 }
77 }
78
79 if (textNode.contains("fontSizePreload") && textNode["fontSizePreload"].is_array())
80 {
81 for (const auto& fontSize : textNode["fontSizePreload"])
82 {
83 auto found = std::find(cfg.fontSizePreload.begin(), cfg.fontSizePreload.end(), fontSize);
84 if (found == cfg.fontSizePreload.end())
85 {
86 cfg.fontSizePreload.push_back(fontSize.get<int>());
87 }
88 }
89 }
90 }
91
92 if (appConfigData.contains("logLevel"))
93 cfg.logLevel = appConfigData["logLevel"].get<std::string>();
94
95 if (appConfigData.contains("useSmoothedFPS"))
96 cfg.useSmoothedFPS = appConfigData["useSmoothedFPS"].get<bool>();
97
98 if (appConfigData.contains("targetFPS"))
99 cfg.targetFPS = appConfigData["targetFPS"].get<float>();
100
101 if (appConfigData.contains("showStatsOverlay"))
102 cfg.showStatsOverlay = appConfigData["showStatsOverlay"].get<bool>();
103
104 }
105 catch (const std::exception& e)
106 {
107 return cfg;
108 }
109
110 return cfg;
111}
112
113std::vector<char> Utility::ReadShaderBinaryFile( std::string const & filename )
114{
115 std::ifstream file(filename, std::ios::ate | std::ios::binary);
116
117 if (!file.is_open())
118 {
119 throw std::runtime_error("failed to open shader binary file!");
120 }
121
122 size_t fileSize = (size_t) file.tellg();
123 std::vector<char> buffer(fileSize);
124
125 file.seekg(0);
126 file.read(buffer.data(), fileSize);
127
128 file.close();
129
130 return buffer;
131}
132
133std::vector<std::string> Utility::GetListOfFilesInDirectory( std::string directory )
134{
135 std::vector<std::string> shaderFileNames;
136
137 try
138 {
139 //check if parameter string is directory
140 if( std::filesystem::exists( std::filesystem::path( directory ) ) && std::filesystem::is_directory(std::filesystem::path( directory ) ) )
141 {
142 std::filesystem::path pathToDirectory = std::filesystem::path( directory );
143
144 if(std::filesystem::is_directory( pathToDirectory ) )
145 {
146 for(const std::filesystem::directory_entry& x : std::filesystem::directory_iterator( pathToDirectory ) )
147 {
148 size_t dot = x.path().string().find_last_of( "." );
149
150 if( std::string{ "spv" } == x.path().string().substr( dot + 1 ) )
151 {
152 std::cout << "Shader binary file: " << x.path().string() << "\n";
153 shaderFileNames.push_back( x.path().string() );
154 }
155 }
156 }
157 }
158 }
159 catch( const std::filesystem::filesystem_error& ex )
160 {
161 std::cout << ex.what() << '\n';
162 }
163
164 return shaderFileNames;
165}
166
167std::filesystem::path Utility::GetApplicationPath()
168{
169 return sApplicationPath;
170}
171
172std::filesystem::path Utility::GetBuildPath()
173{
174 return sBuildPath;
175}
176
177std::filesystem::path Utility::GetShadersBinaryPath()
178{
179 return sShadersBinaryPath;
180}
181
182
183std::filesystem::path Utility::FindPath(std::string fileOrFolderName, std::string searchingFrom)
184{
185 std::filesystem::path result;
186 for(const std::filesystem::directory_entry& entry : std::filesystem::directory_iterator(searchingFrom) )
187 {
188 if( entry.path().filename().string() == fileOrFolderName )
189 {
190 result = entry.path();
191 break;
192 }
193 }
194 return result;
195}
196
197std::vector<std::string> Utility::GetListOfFileNamesInDirectory(const char* directory, std::string extToSearch)
198{
199 std::vector<std::string> imageFileNames;
200
201 try
202 {
203 //check if parameter string is directory
204 if(std::filesystem::exists(std::filesystem::path(directory)) && std::filesystem::is_directory(std::filesystem::path(directory)) )
205 {
206 std::filesystem::path pathToDirectory = std::filesystem::path(directory);
207
208 if(std::filesystem::is_directory(pathToDirectory) )
209 {
210 for(const std::filesystem::directory_entry& x : std::filesystem::directory_iterator(pathToDirectory) )
211 {
212 size_t dot = x.path().string().find_last_of(".");
213
214 if( extToSearch == x.path().string().substr(dot + 1) )
215 {
216 imageFileNames.push_back(x.path().string());
217 }
218 }
219 }
220 }
221 }
222 catch( const std::filesystem::filesystem_error& ex )
223 {
224 std::cout << ex.what() << '\n';
225 }
226
227 return imageFileNames;
228}
229
230std::filesystem::path Utility::ResolveProjectRoot()
231{
232 auto exeDir = std::filesystem::canonical(std::filesystem::path(std::filesystem::current_path())); // default
233 if (exeDir.filename() == "Debug" || exeDir.filename() == "Release")
234 exeDir = exeDir.parent_path(); // step out of Debug/Release
235 if (exeDir.filename() == "Binaries")
236 exeDir = exeDir.parent_path(); // step out of Binaries
237 return exeDir;
238}
239
240std::filesystem::path Utility::GetContentFolderPath()
241{
243}
244
245std::filesystem::path Utility::GetTextureFolderPath()
246{
248}
249
250std::filesystem::path Utility::GetModelsFolderPath()
251{
253}
254
255std::filesystem::path Utility::GetFontsFolderPath()
256{
258}
259
260std::filesystem::path Utility::GetShadersFolderPath()
261{
263}
264
265std::filesystem::path Utility::GetConfigFilePath()
266{
268}
269
270std::filesystem::path Utility::GetLogsFolderPath()
271{
273}
274
276{
277 const auto root = ResolveProjectRoot();
278 return std::filesystem::exists(root / sContentPackageFilePath) &&
279 std::filesystem::exists(root / sContentPackEntriesFilePath);
280}
281
283{
285 return sPackEntries;
286
287 sPackEntries.clear();
288
289 // Path to Pack.json
290 const std::filesystem::path jsonPath = ResolveProjectRoot() / sContentPackEntriesFilePath;
291
292 if (!std::filesystem::exists(jsonPath))
293 {
294 sPackEntriesLoaded = true;
295 return sPackEntries; // empty
296 }
297
298 // Load JSON
299 std::ifstream f(jsonPath.string());
300 if (!f.is_open())
301 {
302 std::cerr << "[ERROR] Failed to open Pack.json\n";
303 sPackEntriesLoaded = true;
304 return sPackEntries;
305 }
306
307 nlohmann::json j;
308 f >> j;
309
310 // Parse entries
311 for (auto it = j.begin(); it != j.end(); ++it)
312 {
313 PackEntry entry;
314 entry.offset = it.value().value("offset", 0);
315 entry.size = it.value().value("size", 0);
316 sPackEntries[it.key()] = entry;
317 }
318
319 sPackEntriesLoaded = true;
320 return sPackEntries;
321}
322
323std::vector<uint8_t> Utility::ReadPackedFile(const std::string& entryPath)
324{
325 std::vector<std::uint8_t> data;
326
327 if (!IsPackageProvided())
328 return data;
329
330 const path binPath = ResolveProjectRoot() / sContentPackageFilePath;
331 const path jsonPath = ResolveProjectRoot() / sContentPackEntriesFilePath;
332
333 if (!std::filesystem::exists(binPath) ||
334 !std::filesystem::exists(jsonPath))
335 {
336 std::cerr << "[Utility::ReadPackedFile] Missing Pack.bin or Pack.json\n";
337 return data;
338 }
339
341 // Check if this entry exists in Pack.json
342 auto it = sPackEntries.find(entryPath);
343 if (it == sPackEntries.end())
344 {
345 std::cerr << "[Utility::ReadPackedFile] No such packed entry: "
346 << entryPath << std::endl;
347 return data; // empty
348 }
349
350 const PackEntry& entry = it->second;
351
352 std::ifstream bin(binPath.string(), std::ios::binary);
353 if (!bin)
354 {
355 std::cerr << "[Utility::ReadPackedFile] Failed to open Pack.bin: "
356 << binPath.string() << std::endl;
357 return data;
358 }
359
360 // Read the memory region [offset, offset + size)
361
362 data.resize(entry.size);
363
364 bin.seekg(entry.offset, std::ios::beg);
365 if (!bin.good())
366 {
367 std::cerr << "[Utility::ReadPackedFile] Seek error for entry: "
368 << entryPath << std::endl;
369 return {};
370 }
371
372 bin.read(reinterpret_cast<char*>(data.data()), entry.size);
373 if (!bin.good())
374 {
375 std::cerr << "[Utility::ReadPackedFile] Read error for entry: "
376 << entryPath << std::endl;
377 return {};
378 }
379
380 return data;
381}
382
383
384}
static std::vector< std::string > GetListOfFileNamesInDirectory(const char *directory, std::string extToSearch)
Returns a list of file names in a directory matching the specified extension.
Definition utility.cpp:197
static std::vector< char > ReadShaderBinaryFile(std::string const &filename)
Reads a binary shader file from disk.
Definition utility.cpp:113
static std::filesystem::path GetShadersBinaryPath()
Returns the directory path containing compiled shader binaries.
Definition utility.cpp:177
static std::filesystem::path sApplicationPath
Definition utility.hpp:178
static std::filesystem::path sBuildPath
Definition utility.hpp:180
static std::filesystem::path GetConfigFilePath()
Returns absolute path to Config/app_config.json.
Definition utility.cpp:265
static std::filesystem::path GetTextureFolderPath()
Returns absolute path to Content/Textures.
Definition utility.cpp:245
static std::filesystem::path GetFontsFolderPath()
Returns absolute path to Content/Fonts.
Definition utility.cpp:255
static std::filesystem::path ResolveProjectRoot()
Resolves project root folder (handles Release/Debug/Binaries layouts).
Definition utility.cpp:230
static std::filesystem::path const sContentRelativePathFolder
Definition utility.hpp:182
static std::filesystem::path GetLogsFolderPath()
Returns absolute path to Logs folder.
Definition utility.cpp:270
static std::filesystem::path const sDefaultShadersBinaryRelativePath
Definition utility.hpp:179
static std::filesystem::path const sAppConfigFilePath
Definition utility.hpp:189
static const PackEntries & GetPackEntries()
Returns the manifest of packed files.
Definition utility.cpp:282
static std::vector< std::string > GetListOfFilesInDirectory(std::string directory)
Returns a list of full file paths in the given directory.
Definition utility.cpp:133
static std::filesystem::path GetApplicationPath()
Returns the absolute path of the running application.
Definition utility.cpp:167
static std::filesystem::path const sContentPackageFilePath
Definition utility.hpp:183
static std::filesystem::path const sLogFolderPath
Definition utility.hpp:190
static std::filesystem::path GetContentFolderPath()
Returns absolute path to Content.
Definition utility.cpp:240
static AppConfig ReadConfigFile()
Reads application settings from the JSON config file.
Definition utility.cpp:34
static std::filesystem::path const sTextureRelativePathFolder
Definition utility.hpp:185
static std::filesystem::path const sContentPackEntriesFilePath
Definition utility.hpp:184
static std::filesystem::path const sShadersRelativePathFolder
Definition utility.hpp:188
static std::filesystem::path const sFontsRelativePathFolder
Definition utility.hpp:187
static std::filesystem::path const sModelsRelativePathFolder
Definition utility.hpp:186
static std::filesystem::path GetModelsFolderPath()
Returns absolute path to Content/Models.
Definition utility.cpp:250
static std::filesystem::path GetBuildPath()
Returns the build output directory path.
Definition utility.cpp:172
static std::filesystem::path sShadersBinaryPath
Definition utility.hpp:181
static std::vector< uint8_t > ReadPackedFile(const std::string &entryPath)
Reads raw bytes of a file stored inside Pack.bin.
Definition utility.cpp:323
static bool IsPackageProvided()
Checks whether packed assets (Pack.bin / Pack.json) exist.
Definition utility.cpp:275
static void InitializePaths(int argc, char *argv[])
Initializes engine paths based on the executable location.
Definition utility.cpp:26
static std::filesystem::path GetShadersFolderPath()
Returns absolute path to Content/Shaders.
Definition utility.cpp:260
static PackEntries sPackEntries
Definition utility.cpp:21
std::unordered_map< std::string, PackEntry > PackEntries
Definition utility.hpp:61
static bool sPackEntriesLoaded
Definition utility.cpp:22
Basic application settings loaded from a configuration file.
Definition utility.hpp:28
float targetFPS
Target frame rate (0 = uncapped).
Definition utility.hpp:46
float screenWidth
Desired window width in pixels (ignored in full-screen mode).
Definition utility.hpp:34
bool isFullScreen
Whether the application should start in full-screen mode.
Definition utility.hpp:32
std::string appName
Name of the application.
Definition utility.hpp:30
bool useSmoothedFPS
Enable FPS smoothing and frame pacing behavior.
Definition utility.hpp:44
bool showStatsOverlay
Enable on-screen statistics overlay.
Definition utility.hpp:48
float screenHeight
Desired window height in pixels (ignored in full-screen mode).
Definition utility.hpp:36
std::vector< std::string > textScripts
Unicode scripts to preload for text rendering.
Definition utility.hpp:38
std::string logLevel
Logging verbosity level ("Error", "Warning", "Info", "Debug").
Definition utility.hpp:42
std::vector< int > fontSizePreload
Font sizes to preload at startup.
Definition utility.hpp:40
Metadata describing one file stored inside a packed asset archive.
Definition utility.hpp:56