cae  0.0.0
Cross-API graphics engine
Loading...
Searching...
No Matches
application.cpp
Go to the documentation of this file.
1#include "CAE/Application.hpp"
2#include "CAE/Common.hpp"
3
4#include "Utils/File.hpp"
5#include "Utils/Logger.hpp"
6#include "Utils/Path.hpp"
7
8static std::vector<std::shared_ptr<utl::IPlugin>> loadPlugins(const std::unique_ptr<utl::PluginLoader> &loader)
9{
10 std::vector<std::shared_ptr<utl::IPlugin>> loadedPlugins;
11 const std::filesystem::path pluginDir{PLUGINS_DIR};
12 if (!utl::Path::existsDir(pluginDir))
13 {
14 utl::Logger::log("Plugins directory does not exist: " + pluginDir.string(), utl::LogLevel::WARNING);
15 return loadedPlugins;
16 }
17
18 for (const auto &entry : std::filesystem::directory_iterator(pluginDir))
19 {
20 if (!entry.is_regular_file() || entry.path().extension() != PLUGINS_EXTENSION)
21 {
22 continue;
23 }
24 const std::string pluginPath = entry.path().string();
25 if (auto plugin = loader->loadPlugin<utl::IPlugin>(pluginPath, "cae-"); plugin != nullptr)
26 {
27 utl::Logger::log("Loaded plugin:\t " + plugin->getName() + " from " + pluginPath, utl::LogLevel::INFO);
28 loadedPlugins.push_back(plugin);
29 }
30 else
31 {
32 utl::Logger::log("Failed to load plugin: " + pluginPath, utl::LogLevel::WARNING);
33 }
34 }
35 if (loadedPlugins.empty())
36 {
37 utl::Logger::log("No plugins loaded from directory: " + pluginDir.string(), utl::LogLevel::WARNING);
38 }
39
40 return loadedPlugins;
41}
42
43cae::Application::Application(const ArgsConfig &argsConfig, const EnvConfig &envConfig)
44 : m_pluginLoader(std::make_unique<utl::PluginLoader>())
45{
46 utl::Logger::log("PROJECT INFO:\n" + std::string(MESSAGE::VERSION_MSG) + '\n', utl::LogLevel::INFO);
47
48 try
49 {
50 m_appConfig.envConfig = envConfig;
51
52 if (!argsConfig.config_path.empty())
53 {
55 }
58 }
59 catch (const std::exception &e)
60 {
61 utl::Logger::log(std::string("Application initialization failed: ") + e.what(), utl::LogLevel::WARNING);
62 }
63}
64
65void cae::Application::setupEngine(const std::string &rendererName, const std::string &windowName,
66 const std::string &shaderFrontendName, const std::string &shaderIRName)
67{
68 std::shared_ptr<IWindow> windowPlugin = nullptr;
69 std::shared_ptr<IRenderer> rendererPlugin = nullptr;
70 std::shared_ptr<IShaderIR> shaderIRPlugin = nullptr;
71 std::vector<std::function<std::shared_ptr<IShaderFrontend>()>> shaderFactories;
72
73 for (auto &plugin : loadPlugins(m_pluginLoader))
74 {
75 if (const auto renderer = std::dynamic_pointer_cast<IRenderer>(plugin))
76 {
77 if (renderer->getName() == rendererName)
78 {
79 rendererPlugin = renderer;
80 }
81 }
82 if (const auto window = std::dynamic_pointer_cast<IWindow>(plugin))
83 {
84 if (window->getName() == windowName)
85 {
86 windowPlugin = window;
87 }
88 }
89 if (const auto shader = std::dynamic_pointer_cast<IShaderFrontend>(plugin))
90 {
91 if (shader->getName() == shaderFrontendName)
92 {
93 shaderFactories.emplace_back([shader]() { return shader; });
94 }
95 }
96 if (const auto shaderIR = std::dynamic_pointer_cast<IShaderIR>(plugin))
97 {
98 if (shaderIR->getName() == shaderIRName)
99 {
100 shaderIRPlugin = shaderIR;
101 }
102 }
103 }
104 if (windowPlugin == nullptr)
105 {
106 utl::Logger::log("No window plugin found with name: " + windowName, utl::LogLevel::WARNING);
107 }
108 if (rendererPlugin == nullptr)
109 {
110 utl::Logger::log("No renderer plugin found with name: " + rendererName, utl::LogLevel::WARNING);
111 }
112 if (shaderFactories.empty())
113 {
114 utl::Logger::log("No shader plugin found with name: " + shaderFrontendName, utl::LogLevel::WARNING);
115 }
116 m_engine = std::make_unique<Engine>(
117 m_appConfig.engineConfig, []() { return nullptr; }, []() { return nullptr; },
118 [rendererPlugin]() { return rendererPlugin; }, [shaderIRPlugin]() { return shaderIRPlugin; }, shaderFactories,
119 [windowPlugin]() { return windowPlugin; });
120}
121
122static const std::vector<float> cubeVertices = {
123 // positions // colors
124 -0.5f, -0.5f, -0.5f, 1, 0, 0, 0.5f, -0.5f, -0.5f, 0, 1, 0, 0.5f, 0.5f, -0.5f, 0, 0, 1,
125 0.5f, 0.5f, -0.5f, 0, 0, 1, -0.5f, 0.5f, -0.5f, 1, 1, 0, -0.5f, -0.5f, -0.5f, 1, 0, 0,
126
127 -0.5f, -0.5f, 0.5f, 1, 0, 1, 0.5f, -0.5f, 0.5f, 0, 1, 1, 0.5f, 0.5f, 0.5f, 1, 1, 1,
128 0.5f, 0.5f, 0.5f, 1, 1, 1, -0.5f, 0.5f, 0.5f, 0, 0, 0, -0.5f, -0.5f, 0.5f, 1, 0, 1,
129
130 -0.5f, 0.5f, 0.5f, 1, 0, 0, -0.5f, 0.5f, -0.5f, 0, 1, 0, -0.5f, -0.5f, -0.5f, 0, 0, 1,
131 -0.5f, -0.5f, -0.5f, 0, 0, 1, -0.5f, -0.5f, 0.5f, 1, 1, 0, -0.5f, 0.5f, 0.5f, 1, 0, 0,
132
133 0.5f, 0.5f, 0.5f, 1, 0, 1, 0.5f, 0.5f, -0.5f, 0, 1, 1, 0.5f, -0.5f, -0.5f, 1, 1, 1,
134 0.5f, -0.5f, -0.5f, 1, 1, 1, 0.5f, -0.5f, 0.5f, 0, 0, 0, 0.5f, 0.5f, 0.5f, 1, 0, 1,
135
136 -0.5f, -0.5f, -0.5f, 1, 0, 0, 0.5f, -0.5f, -0.5f, 0, 1, 0, 0.5f, -0.5f, 0.5f, 0, 0, 1,
137 0.5f, -0.5f, 0.5f, 0, 0, 1, -0.5f, -0.5f, 0.5f, 1, 1, 0, -0.5f, -0.5f, -0.5f, 1, 0, 0,
138
139 -0.5f, 0.5f, -0.5f, 1, 0, 1, 0.5f, 0.5f, -0.5f, 0, 1, 1, 0.5f, 0.5f, 0.5f, 1, 1, 1,
140 0.5f, 0.5f, 0.5f, 1, 1, 1, -0.5f, 0.5f, 0.5f, 0, 0, 0, -0.5f, 0.5f, -0.5f, 1, 0, 1};
141
143{
144 static const std::vector<ShaderSourceDesc> shaderSources = {
145 {.id = "basic_vertex",
147 .source = utl::fileToString(utl::Path::resolveRelativeToExe("assets/shaders/glsl/texture.vert")),
148 .stage = ShaderStage::VERTEX},
149
150 {.id = "basic_fragment",
152 .source = utl::fileToString(utl::Path::resolveRelativeToExe("assets/shaders/glsl/texture.frag")),
153 .stage = ShaderStage::FRAGMENT},
154 };
155 m_engine->initializeRenderResources(shaderSources, cubeVertices);
156 mainLoop();
157}
158
160{
161 m_engine->stop();
162
163 m_pluginLoader = nullptr;
164 m_engine = nullptr;
165}
166
168{
169 std::array<float, 10> fpsBuffer{};
170 int fpsIndex = 0;
171 WindowEvent e{};
172
173 while (!m_engine->getWindow()->shouldClose())
174 {
175 m_engine->render();
176 glm::vec3 moveDir(0.0F);
177 glm::vec2 lookDir(0.0F);
178 m_engine->getWindow()->pollEvents();
179 while (m_engine->getWindow()->pollEvent(e))
180 {
181 if (e.type == WindowEventType::KeyDown)
182 {
183 m_keyState[e.key.key] = true;
184 }
185 else if (e.type == WindowEventType::KeyUp)
186 {
187 m_keyState[e.key.key] = false;
188 }
189 }
190
191 if (m_keyState[KeyCode::Up])
192 {
193 lookDir.y += 1.0F;
194 }
195 if (m_keyState[KeyCode::Down])
196 {
197 lookDir.y -= 1.0F;
198 }
199 if (m_keyState[KeyCode::Left])
200 {
201 lookDir.x -= 1.0F;
202 }
203 if (m_keyState[KeyCode::Right])
204 {
205 lookDir.x += 1.0F;
206 }
207
208 if (glm::length(lookDir) > 0.0F)
209 {
210 lookDir *= m_engine->getCamera()->getLookSpeed() * m_engine->getClock()->getDeltaSeconds();
211 m_engine->getCamera()->rotate(lookDir.x, lookDir.y, 1.0F);
212 }
213
214 glm::vec3 forward = glm::normalize(
215 glm::vec3(m_engine->getCamera()->getDirection().x, 0.0F, m_engine->getCamera()->getDirection().z));
216 glm::vec3 right = glm::normalize(glm::cross(forward, glm::vec3(0.0F, 1.0F, 0.0F)));
217
218 if (m_keyState[KeyCode::W])
219 {
220 moveDir += forward;
221 }
222 if (m_keyState[KeyCode::S])
223 {
224 moveDir -= forward;
225 }
226 if (m_keyState[KeyCode::A])
227 {
228 moveDir -= right;
229 }
230 if (m_keyState[KeyCode::D])
231 {
232 moveDir += right;
233 }
234
235 if (glm::length(moveDir) > 0.0F)
236 {
237 moveDir = glm::normalize(moveDir);
238 m_engine->getCamera()->move(moveDir, m_engine->getClock()->getDeltaSeconds());
239 }
240
241 if (m_keyState[KeyCode::LCtrl])
242 {
243 m_engine->getCamera()->move(glm::vec3(0.0F, -1.0F, 0.0F), m_engine->getClock()->getDeltaSeconds());
244 }
245 if (m_keyState[KeyCode::Space])
246 {
247 m_engine->getCamera()->move(glm::vec3(0.0F, 1.0F, 0.0F), m_engine->getClock()->getDeltaSeconds());
248 }
249
250 m_engine->update(fpsBuffer, fpsIndex);
251 }
252}
This file contains the Application class declaration.
This file contains file utility functions.
This file contains the Logger class.
This file contains Path resolution utilities.
static std::vector< std::shared_ptr< utl::IPlugin > > loadPlugins(const std::unique_ptr< utl::PluginLoader > &loader)
static const std::vector< float > cubeVertices
AppConfig m_appConfig
Application(const ArgsConfig &argsConfig, const EnvConfig &envConfig)
Construct the Application with given configurations.
void mainLoop()
main loop
static EngineConfig parseEngineConf(const std::string &path)
Parse the engine configuration file.
Definition conf.cpp:12
void setupEngine(const std::string &rendererName, const std::string &windowName, const std::string &shaderFrontendName, const std::string &shaderIRName)
Setup the engine with the given plugins.
void start()
Start the application.
void stop()
Stop the application.
Interface for plugins.
Definition IPlugin.hpp:46
static void log(const std::string &message, const LogLevel &logLevel)
Log a message with a specific log level.
Definition Logger.hpp:71
static fs::path resolveRelativeToExe(const fs::path &relativePath)
Resolve a relative path to the executable directory.
Definition Path.hpp:121
static bool existsDir(const fs::path &path)
Check if a directory exists.
Definition Path.hpp:68
This file contains the common definitions.
static constexpr std::string_view VERSION_MSG
Definition Common.hpp:22
constexpr auto GLFW
Definition Common.hpp:51
std::string fileToString(const std::filesystem::path &path)
Read a file and return its contents as a string.
Definition file.cpp:27
EnvConfig envConfig
EngineConfig engineConfig
Struct for command line arguments configuration.
std::string config_path
Struct for environment variables configuration.
Struct for window events.
Definition IWindow.hpp:63