Rendering Engine 0.2.9
Modular Graphics Rendering Engine | v0.2.9
core_application.cpp
Go to the documentation of this file.
3#include "vulkan_renderer.hpp"
4#include "app_clock.hpp"
5#include "app_time.hpp"
6#include "scene_manager.hpp"
7#include "utility.hpp"
8#include "logger.hpp"
9
10#include <exception>
11#include <thread>
12
13namespace rendering_engine
14{
16 :
17 mAppTime(std::make_shared<AppTime>()),
18 mWindowSystem{ nullptr },
19 mRenderer{ nullptr }
20{
22
23 mAppName = mAppConfig.appName.c_str();
25 mWidth = static_cast<unsigned int>(mAppConfig.screenWidth);
26 mHeight = static_cast<unsigned int>(mAppConfig.screenHeight);
27}
29 :
30 bIsFullScreen{true},
31 mAppName(appName),
32 mAppTime(std::make_shared<AppTime>()),
33 mWindowSystem{nullptr},
34 mRenderer{nullptr}
35{
37}
38
39CoreApplication::CoreApplication(unsigned int width, unsigned int height, char const* appName)
40 :
41 bIsFullScreen{false},
42 mWidth{width},
43 mHeight{height},
44 mAppName(appName),
45 mAppTime(std::make_shared<AppTime>()),
46 mWindowSystem{ nullptr },
47 mRenderer{ nullptr }
48{
50}
51
53 unsigned int height,
54 char const* appName,
55 std::shared_ptr<IWindowSystem> windowSystem,
56 std::shared_ptr<IRenderer> renderer)
57 :
58 bIsFullScreen{ false },
59 mWidth{ width },
60 mHeight{ height },
61 mAppName(appName),
62 mAppTime(std::make_shared<AppTime>()),
63 mWindowSystem{ windowSystem },
64 mRenderer{ renderer }
65{
67}
68
70 std::shared_ptr<IWindowSystem> windowSystem,
71 std::shared_ptr<IRenderer> renderer)
72 :
73 bIsFullScreen{ true },
74 mWidth{ 0 },
75 mHeight{ 0 },
76 mAppName(appName),
77 mAppTime(std::make_shared<AppTime>()),
78 mWindowSystem{ windowSystem },
79 mRenderer{ renderer }
80{
82}
83
85
87{
89
90 LOG_INFO("Initializing CoreApplication...");
91 LOG_INFO(std::string("Application name: ") + mAppName);
92
93 auto startTime = std::chrono::steady_clock::now();
94
95 if (!mWindowSystem)
96 {
97 LOG_DEBUG("Creating StandaloneDesktopWindow...");
98 mWindowSystem = std::make_shared<StandaloneDesktopWindow>(*this);
99 }
100 if (!mRenderer)
101 {
102 LOG_DEBUG("Creating VulkanRenderer...");
103 mRenderer = std::make_shared<VulkanRenderer>(*mWindowSystem.get());
104 }
105
106 LOG_INFO("Creating application window...");
107 mWindowSystem->CreateAppWindow(mWidth, mHeight, mAppName);
108 if (bIsFullScreen)
109 {
110 mWidth = mWindowSystem->GetFullScreenResolution().width;
111 mHeight = mWindowSystem->GetFullScreenResolution().height;
112
113 LOG_INFO("Fullscreen mode enabled. Resolution set to: "
114 + std::to_string(mWidth) + "x" + std::to_string(mHeight));
115 }
116 LOG_INFO("Initializing renderer...");
117 mRenderer->InitializeRenderer();
118
119 LOG_INFO("Initializing SceneManager...");
120 mSceneManager = std::make_shared<SceneManager>(mRenderer.get(), this);
121 mSceneManager->Initialize();
122
123 auto endTime = std::chrono::steady_clock::now();
124 auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(endTime - startTime).count();
125
126 LOG_INFO("CoreApplication initialized in " + std::to_string(duration) + " ms.");
127}
128
130{
131 LOG_INFO("Entering main loop.");
132
133 AppClock appClock;
134 appClock.Reset();
135
136 const float targetFrameTimeMs =
137 (mAppConfig.targetFPS > 0) ? (1000.0f / static_cast<float>(mAppConfig.targetFPS)) : 0.0f;
138
139 while (!mWindowSystem->ShouldClose())
140 {
141 const auto frameStart = std::chrono::steady_clock::now();
142
143 appClock.UpdateAppTime(*mAppTime);
144 mWindowSystem->PollEvents();
145
146 const auto updateStart = std::chrono::steady_clock::now();
147 Update(mAppTime->ElapsedAppTimeSeconds());
148 const auto updateEnd = std::chrono::steady_clock::now();
149
150 const auto drawStart = std::chrono::steady_clock::now();
151 Draw();
152 const auto drawEnd = std::chrono::steady_clock::now();
153
154 const auto frameEnd = std::chrono::steady_clock::now();
155
157 std::chrono::duration<float, std::milli>(updateEnd - updateStart).count();
159 std::chrono::duration<float, std::milli>(drawEnd - drawStart).count();
161 std::chrono::duration<float, std::milli>(frameEnd - frameStart).count();
162
163
164 // Frame pacing (sleep)
165 if (mAppConfig.targetFPS > 0)
166 {
167 const auto afterMetrics = std::chrono::steady_clock::now();
168
169 const float actualFrameTimeMs =
170 std::chrono::duration<float, std::milli>(afterMetrics - frameStart).count();
171
172 if (actualFrameTimeMs < targetFrameTimeMs)
173 {
174 const auto sleepDuration =
175 std::chrono::duration<float, std::milli>(
176 targetFrameTimeMs - actualFrameTimeMs);
177
178 std::this_thread::sleep_for(sleepDuration);
179 }
180 }
181
182 const auto frameEndTotal = std::chrono::steady_clock::now();
183 const auto frameLengthTotal = std::chrono::duration<float, std::milli>(frameEndTotal - frameStart).count();
184
186 {
187 mFrameMetrics.fpsRaw = 1000.0f / frameLengthTotal;
188
189 const float alpha = 0.1f;
190
191 if (mFrameMetrics.fpsSmoothed == 0.0f)
192 {
194 }
195 else
196 {
198 alpha * mFrameMetrics.fpsRaw +
199 (1.0f - alpha) * mFrameMetrics.fpsSmoothed;
200 }
201 }
202 }
203
204 LOG_INFO("Main loop exited.");
205
206 Shutdown();
207}
208
209void CoreApplication::Update(float deltaTime)
210{
211 if (mSceneManager)
212 {
213 mSceneManager->Update(deltaTime);
214 }
215}
216
218{
219 if (mRenderer->BeginFrame())
220 {
221 mRenderer->BeginRenderPass();
222 mSceneManager->Draw();
223 mRenderer->EndRenderPass();
224 mRenderer->EndFrame();
225 }
226}
227
229{
230 LOG_INFO("Shutting down CoreApplication...");
231 mRenderer->WaitIdle();
232 LOG_DEBUG("Shutting down SceneManager...");
233 mSceneManager->Shutdown();
234 LOG_DEBUG("Shutting down Renderer...");
235 mRenderer->ShutdownRenderer();
236 LOG_DEBUG("Shutting down WindowSystem...");
237 mWindowSystem->Shutdown();
238 LOG_INFO("CoreApplication shutdown complete.");
240}
241
243{
245 ss.name = mAppName;
247 ss.height = mHeight;
248 ss.width = mWidth;
249
250 return ss;
251}
252
254{
255 return mFrameMetrics;
256}
257
258} // rendering_engine
High-resolution clock for updating application time.
Provides time tracking for the application runtime.
Provides high-resolution timing for frame updates.
Definition: app_clock.hpp:50
void Reset()
Resets the clock to the current system time.
Definition: app_clock.cpp:31
void UpdateAppTime(AppTime &appTime)
Updates the given AppTime instance with elapsed and total durations.
Definition: app_clock.cpp:38
Manages current, total, and elapsed time for the application.
Definition: app_time.hpp:36
std::shared_ptr< SceneManager > mSceneManager
CoreApplication()
Constructs a CoreApplication using settings from the config file.
FrameMetrics GetFrameMetrics() const override
Returns performance metrics of the last processed frame.
ScreenSettings GetScreenSettings() const override
Retrieves the current screen or window settings.
std::shared_ptr< IWindowSystem > mWindowSystem
void Draw() override
Executes the rendering logic for the current frame.
void Shutdown() override
Performs cleanup and shuts down the application.
std::shared_ptr< AppTime > mAppTime
void Run() override
Runs the main application loop.
void Update(float deltaTime) override
Updates the application state.
std::shared_ptr< IRenderer > mRenderer
void Initialize() override
Initializes the application and its subsystems.
void Shutdown()
Finalizes logging system and closes the log file.
Definition: logger.cpp:82
void Initialize(const std::string &appName)
Initializes logging system and creates a new log file.
Definition: logger.cpp:39
static Logger & Get()
Returns singleton logger instance.
Definition: logger.cpp:33
static AppConfig ReadConfigFile()
Reads application settings from the JSON config file.
Definition: utility.cpp:34
Engine-wide logging system for runtime diagnostics and performance tracking.
#define LOG_DEBUG(msg)
Definition: logger.hpp:38
#define LOG_INFO(msg)
Definition: logger.hpp:39
float targetFPS
Target frame rate (0 = uncapped).
Definition: utility.hpp:45
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
Stores CPU timing statistics for a rendered frame.
Describes window and display configuration for the application.
std::string name
The window or application name.
unsigned int width
Screen or window width in pixels.
unsigned int height
Screen or window height in pixels.
bool isFullScreen
Whether the application runs in fullscreen mode.