Rendering Engine 0.2.0
Modular Graphics Rendering Engine | v0.2.0
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 boost::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::sShadersRelativePathFolder = sContentRelativePathFolder / "Shaders";
13path const Utility:: sAppConfigFilePath = path{} / "Config" / "app_config.json";
14
18
20static bool sPackEntriesLoaded = false;
21path const Utility::sContentPackageFilePath = path{} / "Content" / "Pack.bin";
22path const Utility::sContentPackEntriesFilePath = path{} / "Content" / "Pack.json";
23
24void Utility::InitializePaths(int argc, char* argv[])
25{
26 sApplicationPath = boost::filesystem::path(argv[0]);
27
28 sBuildPath = FindPath( "Build" );
30}
31
33{
34 AppConfig cfg;
35
36 std::ifstream f(GetConfigFilePath().string());
37 if (!f.is_open())
38 {
39 return cfg;
40 }
41
42 try
43 {
44 nlohmann::json appConfigData = nlohmann::json::parse(f);
45
46 if (appConfigData.contains("appName"))
47 cfg.appName = appConfigData["appName"].get<std::string>();
48
49 if (appConfigData.contains("isFullScreen"))
50 cfg.isFullScreen = appConfigData["isFullScreen"].get<bool>();
51
52 if (appConfigData.contains("screenWidth"))
53 cfg.screenWidth = appConfigData["screenWidth"].get<float>();
54
55 if (appConfigData.contains("screenHeight"))
56 cfg.screenHeight = appConfigData["screenHeight"].get<float>();
57 }
58 catch (const std::exception& e)
59 {
60 return cfg;
61 }
62
63 return cfg;
64}
65
66std::vector<char> Utility::ReadShaderBinaryFile( std::string const & filename )
67{
68 std::ifstream file(filename, std::ios::ate | std::ios::binary);
69
70 if (!file.is_open())
71 {
72 throw std::runtime_error("failed to open shader binary file!");
73 }
74
75 size_t fileSize = (size_t) file.tellg();
76 std::vector<char> buffer(fileSize);
77
78 file.seekg(0);
79 file.read(buffer.data(), fileSize);
80
81 file.close();
82
83 return buffer;
84}
85
86std::vector<std::string> Utility::GetListOfFilesInDirectory( std::string directory )
87{
88 std::vector<std::string> shaderFileNames;
89
90 try
91 {
92 //check if parameter string is directory
93 if( boost::filesystem::exists( boost::filesystem::path( directory ) ) && boost::filesystem::is_directory( boost::filesystem::path( directory ) ) )
94 {
95 boost::filesystem::path pathToDirectory = boost::filesystem::path( directory );
96
97 if( boost::filesystem::is_directory( pathToDirectory ) )
98 {
99 for( boost::filesystem::directory_entry& x : boost::filesystem::directory_iterator( pathToDirectory ) )
100 {
101 size_t dot = x.path().string().find_last_of( "." );
102
103 if( std::string{ "spv" } == x.path().string().substr( dot + 1 ) )
104 {
105 std::cout << "Shader binary file: " << x.path().string() << "\n";
106 shaderFileNames.push_back( x.path().string() );
107 }
108 }
109 }
110 }
111 }
112 catch( const boost::filesystem::filesystem_error& ex )
113 {
114 std::cout << ex.what() << '\n';
115 }
116
117 return shaderFileNames;
118}
119
120boost::filesystem::path Utility::GetApplicationPath()
121{
122 return sApplicationPath;
123}
124
125boost::filesystem::path Utility::GetBuildPath()
126{
127 return sBuildPath;
128}
129
130boost::filesystem::path Utility::GetShadersBinaryPath()
131{
132 return sShadersBinaryPath;
133}
134
135
136boost::filesystem::path Utility::FindPath(std::string fileOrFolderName, std::string searchingFrom)
137{
138 boost::filesystem::path result;
139 for( boost::filesystem::directory_entry& x : boost::filesystem::directory_iterator(searchingFrom) )
140 {
141 if( x.path().filename().string() == fileOrFolderName )
142 {
143 result = x.path().generic_path();
144 }
145 }
146 return result;
147}
148
149std::vector<std::string> Utility::GetListOfFileNamesInDirectory(const char* directory, std::string extToSearch)
150{
151 std::vector<std::string> imageFileNames;
152
153 try
154 {
155 //check if parameter string is directory
156 if( boost::filesystem::exists(boost::filesystem::path(directory)) && boost::filesystem::is_directory(boost::filesystem::path(directory)) )
157 {
158 boost::filesystem::path pathToDirectory = boost::filesystem::path(directory);
159
160 if( boost::filesystem::is_directory(pathToDirectory) )
161 {
162 for( boost::filesystem::directory_entry& x : boost::filesystem::directory_iterator(pathToDirectory) )
163 {
164 size_t dot = x.path().string().find_last_of(".");
165
166 if( extToSearch == x.path().string().substr(dot + 1) )
167 {
168 imageFileNames.push_back(x.path().string());
169 }
170 }
171 }
172 }
173 }
174 catch( const boost::filesystem::filesystem_error& ex )
175 {
176 std::cout << ex.what() << '\n';
177 }
178
179 return imageFileNames;
180}
181
182boost::filesystem::path Utility::ResolveProjectRoot()
183{
184 auto exeDir = boost::filesystem::canonical(boost::filesystem::path(boost::filesystem::current_path())); // default
185 if (exeDir.filename() == "Debug" || exeDir.filename() == "Release")
186 exeDir = exeDir.parent_path(); // step out of Debug/Release
187 if (exeDir.filename() == "Binaries")
188 exeDir = exeDir.parent_path(); // step out of Binaries
189 return exeDir;
190}
191
192boost::filesystem::path Utility::GetTextureFolderPath()
193{
195}
196
197boost::filesystem::path Utility::GetModelsFolderPath()
198{
200}
201
202boost::filesystem::path Utility::GetShadersFolderPath()
203{
205}
206
207boost::filesystem::path Utility::GetConfigFilePath()
208{
210}
211
213{
214 const auto root = ResolveProjectRoot();
215 return boost::filesystem::exists(root / sContentPackageFilePath) &&
216 boost::filesystem::exists(root / sContentPackEntriesFilePath);
217}
218
220{
222 return sPackEntries;
223
224 sPackEntries.clear();
225
226 // Path to Pack.json
227 const boost::filesystem::path jsonPath = ResolveProjectRoot() / sContentPackEntriesFilePath;
228
229 if (!boost::filesystem::exists(jsonPath))
230 {
231 sPackEntriesLoaded = true;
232 return sPackEntries; // empty
233 }
234
235 // Load JSON
236 std::ifstream f(jsonPath.string());
237 if (!f.is_open())
238 {
239 std::cerr << "[ERROR] Failed to open Pack.json\n";
240 sPackEntriesLoaded = true;
241 return sPackEntries;
242 }
243
244 nlohmann::json j;
245 f >> j;
246
247 // Parse entries
248 for (auto it = j.begin(); it != j.end(); ++it)
249 {
250 PackEntry entry;
251 entry.offset = it.value().value("offset", 0);
252 entry.size = it.value().value("size", 0);
253 sPackEntries[it.key()] = entry;
254 }
255
256 sPackEntriesLoaded = true;
257 return sPackEntries;
258}
259
260std::vector<uint8_t> Utility::ReadPackedFile(const std::string& entryPath)
261{
262 std::vector<std::uint8_t> data;
263
264 if (!IsPackageProvided())
265 return data;
266
267 const path binPath = ResolveProjectRoot() / sContentPackageFilePath;
268 const path jsonPath = ResolveProjectRoot() / sContentPackEntriesFilePath;
269
270 if (!boost::filesystem::exists(binPath) ||
271 !boost::filesystem::exists(jsonPath))
272 {
273 std::cerr << "[Utility::ReadPackedFile] Missing Pack.bin or Pack.json\n";
274 return data;
275 }
276
278 // Check if this entry exists in Pack.json
279 auto it = sPackEntries.find(entryPath);
280 if (it == sPackEntries.end())
281 {
282 std::cerr << "[Utility::ReadPackedFile] No such packed entry: "
283 << entryPath << std::endl;
284 return data; // empty
285 }
286
287 const PackEntry& entry = it->second;
288
289 std::ifstream bin(binPath.string(), std::ios::binary);
290 if (!bin)
291 {
292 std::cerr << "[Utility::ReadPackedFile] Failed to open Pack.bin: "
293 << binPath.string() << std::endl;
294 return data;
295 }
296
297 // Read the memory region [offset, offset + size)
298
299 data.resize(entry.size);
300
301 bin.seekg(entry.offset, std::ios::beg);
302 if (!bin.good())
303 {
304 std::cerr << "[Utility::ReadPackedFile] Seek error for entry: "
305 << entryPath << std::endl;
306 return {};
307 }
308
309 bin.read(reinterpret_cast<char*>(data.data()), entry.size);
310 if (!bin.good())
311 {
312 std::cerr << "[Utility::ReadPackedFile] Read error for entry: "
313 << entryPath << std::endl;
314 return {};
315 }
316
317 return data;
318}
319
320}
static boost::filesystem::path GetConfigFilePath()
Returns absolute path to Config/app_config.json.
Definition utility.cpp:207
static boost::filesystem::path GetShadersFolderPath()
Returns absolute path to Content/Shaders.
Definition utility.cpp:202
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:149
static std::vector< char > ReadShaderBinaryFile(std::string const &filename)
Reads a binary shader file from disk.
Definition utility.cpp:66
static boost::filesystem::path GetApplicationPath()
Returns the absolute path of the running application.
Definition utility.cpp:120
static boost::filesystem::path GetShadersBinaryPath()
Returns the directory path containing compiled shader binaries.
Definition utility.cpp:130
static boost::filesystem::path sApplicationPath
Definition utility.hpp:156
static boost::filesystem::path sBuildPath
Definition utility.hpp:158
static boost::filesystem::path ResolveProjectRoot()
Resolves project root folder (handles Release/Debug/Binaries layouts).
Definition utility.cpp:182
static boost::filesystem::path GetBuildPath()
Returns the build output directory path.
Definition utility.cpp:125
static boost::filesystem::path const sContentRelativePathFolder
Definition utility.hpp:160
static boost::filesystem::path const sDefaultShadersBinaryRelativePath
Definition utility.hpp:157
static boost::filesystem::path const sAppConfigFilePath
Definition utility.hpp:166
static const PackEntries & GetPackEntries()
Returns the manifest of packed files.
Definition utility.cpp:219
static std::vector< std::string > GetListOfFilesInDirectory(std::string directory)
Returns a list of full file paths in the given directory.
Definition utility.cpp:86
static boost::filesystem::path const sContentPackageFilePath
Definition utility.hpp:161
static AppConfig ReadConfigFile()
Reads application settings from the JSON config file.
Definition utility.cpp:32
static boost::filesystem::path const sTextureRelativePathFolder
Definition utility.hpp:163
static boost::filesystem::path GetTextureFolderPath()
Returns absolute path to Content/Textures.
Definition utility.cpp:192
static boost::filesystem::path const sContentPackEntriesFilePath
Definition utility.hpp:162
static boost::filesystem::path const sShadersRelativePathFolder
Definition utility.hpp:165
static boost::filesystem::path const sModelsRelativePathFolder
Definition utility.hpp:164
static boost::filesystem::path sShadersBinaryPath
Definition utility.hpp:159
static std::vector< uint8_t > ReadPackedFile(const std::string &entryPath)
Reads raw bytes of a file stored inside Pack.bin.
Definition utility.cpp:260
static boost::filesystem::path GetModelsFolderPath()
Returns absolute path to Content/Models.
Definition utility.cpp:197
static bool IsPackageProvided()
Checks whether packed assets (Pack.bin / Pack.json) exist.
Definition utility.cpp:212
static void InitializePaths(int argc, char *argv[])
Initializes engine paths based on the executable location.
Definition utility.cpp:24
static PackEntries sPackEntries
Definition utility.cpp:19
std::unordered_map< std::string, PackEntry > PackEntries
Definition utility.hpp:48
static bool sPackEntriesLoaded
Definition utility.cpp:20
Basic application settings loaded from a configuration file.
Definition utility.hpp:27
float screenWidth
Desired window width in pixels (ignored in full-screen mode).
Definition utility.hpp:33
bool isFullScreen
Whether the application should start in full-screen mode.
Definition utility.hpp:31
std::string appName
Name of the application.
Definition utility.hpp:29
float screenHeight
Desired window height in pixels (ignored in full-screen mode).
Definition utility.hpp:35
Metadata describing one file stored inside a packed asset archive.
Definition utility.hpp:43
size_t offset
Definition utility.hpp:44
size_t size
Definition utility.hpp:45