-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathIEngine.cpp
136 lines (110 loc) · 3.77 KB
/
IEngine.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
#include "IEngine.h"
#include "GL/glew.h"
#include <GLFW/glfw3.h>
#include "IScreen.h"
#include "Window.h"
void IEngine::Run()
{
// Calling initialization methods
this->OnPreInit();
this->_Init();
this->OnPostInit();
// Starting engine loop
this->_isRunning = true;
double timeInit = glfwGetTime();
while (this->_isRunning && !this->window.ShouldClose())
{
double timeFinal = glfwGetTime();
// Capping game loop speed
if ((timeFinal - timeInit) >= this->_desiredFrameTime)
{
// Setting current frametime as the average of FRAMETIME_INTERVAL
this->_frameTimes.push_back(timeFinal - timeInit);
if (this->_frameTimes.size() > FRAMETIME_INTERVAL)
this->_frameTimes.erase(this->_frameTimes.begin());
double avg = 0;
std::vector<double>::iterator iter;
for (iter = this->_frameTimes.begin(); iter != this->_frameTimes.end(); iter++)
avg += *iter;
avg /= this->_frameTimes.size();
this->_frameTime = avg;
// Resetting timer
timeInit = glfwGetTime();
// Polling inputs
glfwPollEvents();
// Calling engine and screen update methods
this->OnUpdate();
if (this->_currentScreen)
this->_currentScreen->OnUpdate();
// Calling separate update steps for step consistency
double timeLeft = this->_frameTime;
int iterations = 0;
while (timeLeft >= this->_desiredFrameTime && iterations <= MAX_UPDATE_STEPS)
{
this->OnUpdateStep();
if (this->_currentScreen)
this->_currentScreen->OnUpdateStep();
timeLeft -= this->_desiredFrameTime;
iterations++;
}
// Rendering by calling draw methods
if (this->_currentScreen)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
this->_currentScreen->OnDraw();
this->window.SwapBuffers();
}
}
}
this->Destroy();
}
void IEngine::Destroy()
{
this->_isRunning = false;
// Calling destruction methods
this->OnPreDestroy();
this->_currentScreen->OnExit();
std::map<const char*, IScreen*>::iterator iter;
for (iter = this->_screenMap.begin(); iter != this->_screenMap.end(); iter++)
iter->second->OnDestroy();
// Garbage-collecting window
this->window.Destroy();
// Terminating GLFW
glfwTerminate();
// Calling post-destruction methods
this->OnPostDestroy();
}
void IEngine::ChangeScreen(const std::string& name)
{
// Exiting current screen if valid
if (this->_currentScreen)
this->_currentScreen->OnExit();
// Switching screen and calling entry method
this->_currentScreen = this->_screenMap.at(name.c_str());
this->_currentScreen->OnEntry();
}
void IEngine::AddScreen(const std::string& name, IScreen* screen)
{
// Adding screen to the screen map and initializing
this->_screenMap[name.c_str()] = screen;
screen->SetParentEngine(this);
screen->OnInit();
}
void IEngine::_Init()
{
// Initializing GLFW and error checking
if (!glfwInit())
std::fprintf(stderr, "Failed to initialize GLFW\n");
// Initializing window
this->window.Init(name, width, height, flags);
// Initializing GLEW and error checking
glewExperimental = GL_TRUE;
GLenum err = glewInit();
if (err != GLEW_OK)
std::fprintf(stderr, "Error: %s\n", glewGetErrorString(err));
std::printf("%s\n", glGetString(GL_VERSION));
// Enable depth testing
glEnable(GL_DEPTH_TEST);
// Enable face culling
glEnable(GL_CULL_FACE);
}