-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMain.cpp
231 lines (207 loc) · 8.75 KB
/
Main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
#include "Main.h"
#include "Rendering/RenderingProvider.h"
#include "CoreModule/Input.h"
#include "CoreModule/SceneManager.h"
#include "CoreModule/Manager/RendererManager.h"
#include "CoreModule/Settings.h"
#include "Editor/ImguiManager.h"
#include "CoreModule/Manager/ResourceManager.h"
#include "CoreModule/Manager/PhysicsManager.h"
#include "Editor/EditorApplication.h"
#include "Rendering/VulkanRendering.h"
using namespace KritiaEngine;
using namespace KritiaEngine::SceneManagement;
using namespace KritiaEngine::Manager;
using namespace KritiaEngine::Rendering;
using namespace KritiaEngine::Editor::GUI;
using namespace KritiaEngine::Editor;
constexpr const char* title = "Kritia Engine";
int main()
{
Settings::Deserialize();
if (Settings::renderingBackend == RenderingProvider::RenderingBackend::Software) {
std::cout << "UseOpenGL is set to false, please set it to true or change the property of visual studio project to call WinMain() to use the Software Rendering backend." << std::endl;
} else {
if (!InitializeWindow()) {
return -1;
}
InitializeCoreModules();
InitializeGUI();
// 游戏循环, Tick
while (!glfwWindowShouldClose(window)) {
Time::UpdateDeltaTime(glfwGetTime());
//执行一些特殊的输入控制
ProcessInput();
//执行所有Update函数,处理逻辑
Update();
//渲染
Render();
ResourceManager::CollectGarbage();
}
PhysicsManager::Clear();
Settings::Serialize();
RenderingProvider::Cleanup();
glfwDestroyWindow(window);
glfwTerminate();
}
return 0;
}
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) {
Settings::Deserialize();
if (Settings::renderingBackend == RenderingProvider::RenderingBackend::OpenGL) {
return main();
} else {
MSG msg;
WNDCLASS wndclass;
//对窗口类的各属性进行初始化
wndclass.style = CS_HREDRAW | CS_VREDRAW; /*窗口类的风格,CS前缀,C表示Class,S表示
Style,这里使用了水平和垂直风格*/
wndclass.lpfnWndProc = WndProc; /*这里将回到函数的名字赋值用以windows后面回调*/
wndclass.cbClsExtra = 0; //附加参数,通常情况下为0
wndclass.cbWndExtra = 0; //附加参数,通常情况下为0
wndclass.hInstance = hInstance; //窗口句柄,这里将WinMain中的hInstance句柄赋值就可
wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); /*窗口图标,LoadIcon()是加载图标,这里是加载一个系统资源图标,LoadIcon()的原型是HICON LoadIcon(HINSTANCE, LPCSTR);*/
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); /*加载鼠标,同上相似*/
wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); /*窗口画刷,这里是使用的白色画刷,所以创建出来的窗口的背景颜色则是白色的*/
wndclass.lpszMenuName = NULL; //窗口菜单名称,这里没有菜单,设为NULL
wndclass.lpszClassName = TEXT("KritiaEngineWindow"); //窗口类名称,这个窗口类名称可作为这个窗口的唯一标识
if (!RegisterClass(&wndclass)) {
return 0;
}
hwnd = CreateWindow(TEXT("KritiaEngineWindow"), TEXT("KritiaEngine"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, Settings::ScreenWidth, Settings::ScreenHeight, NULL, NULL, hInstance, NULL);
ShowWindow(hwnd, iCmdShow);
UpdateWindow(hwnd);
InitializeCoreModules();
//InitializeGUI();
startTime = SYSTEMTIME();
GetLocalTime(&startTime);
while (GetMessage(&msg, hwnd, NULL, 0)) {
SYSTEMTIME time = SYSTEMTIME();
GetLocalTime(&time);
Time::UpdateDeltaTime(time.wMilliseconds - startTime.wMilliseconds);
//执行一些特殊的输入控制
//ProcessInput();
//翻译消息
TranslateMessage(&msg);
//派发消息
DispatchMessage(&msg);
//执行所有Update函数,处理逻辑
Update();
//渲染
Render();
ResourceManager::CollectGarbage();
}
PhysicsManager::Clear();
return msg.wParam;
}
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
//处理消息
switch (message) {
case WM_CREATE:
/*窗口在创建时,会接收到该消息,通常在这里进行初始化操作*/
return 0;
case WM_SIZE:
/*窗口被改变大小时,会接收到该消息,在窗口被创建时也会收到一次*/
return 0;
case WM_PAINT:
/*窗口有绘图操作更新时,会收到这个消息*/
return 0;
case WM_DESTROY:
/*关不窗口时,会收到该消息,PostQuitMessage()像系统表明终止当前线程,没有这个函数的话,窗口不会关闭*/
PostQuitMessage(0);
return 0;
}
//将不需要处理的消息传递给系统作默认处理
return DefWindowProc(hwnd, message, wParam, lParam);
}
//渲染循环
void Render() {
RenderingProvider::SetupRenderingFrame();
RendererManager::Render();
if (Settings::renderingBackend == RenderingProvider::RenderingBackend::OpenGL) {
ImguiManager::RenderGUI();
}
RenderingProvider::EndRenderingFrame(window);
}
void Update() {
if (editor) {
Camera::editorCamera->EditorCameraUpdate();
}
BehaviourManager::ComponentUpdate();
if (EditorApplication::isPlaying) {
BehaviourManager::BehaviourUpdate();
PhysicsManager::PhysicsUpdate();
}
}
void FramebufferSizeCallback(GLFWwindow* window, int width, int height) {
glViewport(0, 0, width, height);
}
bool InitializeWindow()
{
//初始化窗口
if (Settings::renderingBackend == RenderingProvider::RenderingBackend::OpenGL || Settings::renderingBackend == RenderingProvider::RenderingBackend::Vulkan) {
glfwInit();
if (Settings::renderingBackend == RenderingProvider::RenderingBackend::OpenGL) {
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
if (RenderingProvider::msaaEnabled) {
glfwWindowHint(GLFW_SAMPLES, 4);
}
window = glfwCreateWindow(Settings::ScreenWidth, Settings::ScreenHeight, title, NULL, NULL);
if (window == NULL) {
std::cout << "Failed to create GLFW window" << std::endl;
glfwTerminate();
return false;
}
glfwMakeContextCurrent(window);
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
std::cout << "Failed to initialize GLAD" << std::endl;
return false;
}
glfwSetFramebufferSizeCallback(window, FramebufferSizeCallback);
} else {
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);
window = glfwCreateWindow(Settings::ScreenWidth, Settings::ScreenHeight, title, nullptr, nullptr);
glfwSetWindowSizeCallback(window, VulkanRendering::OnWindowResized);
if (window == NULL) {
std::cout << "Failed to create GLFW window" << std::endl;
glfwTerminate();
return false;
}
}
glfwSetCursorPosCallback(window, Input::MouseCursorPosCallback);
glfwSetScrollCallback(window, Input::MouseScrollCallback);
glfwSwapInterval(1);
if (Settings::renderingBackend == RenderingProvider::RenderingBackend::Vulkan) {
uint32_t extensionCount = 0;
vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, nullptr);
std::cout << extensionCount << " vulkan extensions supported" << std::endl;
}
return true;
}
return false;
}
void InitializeGUI() {
ImguiManager::Initialize(window, editor);
}
void ProcessInput() {
if (Settings::renderingBackend == RenderingProvider::RenderingBackend::OpenGL || Settings::renderingBackend == RenderingProvider::RenderingBackend::Vulkan) {
if (Input::GetKeyDown(GLFW_KEY_ESCAPE)) {
glfwSetWindowShouldClose(window, true);
}
//重置鼠标偏移
Input::ResetMouseOffset();
//检查事件,交换缓冲
glfwPollEvents();
}
}
// 初始化所有核心模块
void InitializeCoreModules() {
PhysicsManager::Initialize();
Input::Initialize(window);
RenderingProvider::Initialize(hwnd, window);
SceneManager::Initialize(editor);
}