-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathWindow.cpp
107 lines (94 loc) · 2.71 KB
/
Window.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
module;
#include <glad/glad.h>
#include <GLFW/glfw3.h>
export module graphics:Window;
import :Framebuffer;
import <string>;
import <stdexcept>;
export namespace graphics
{
constexpr int openGLMajorVersion = 2;
constexpr int openGLMinorVersion = 1;
// A window overtakes the entire process it's spawned in. Only a single Window instance is
// therefore allowed to be constructed per process.
class Window
{
double prev;
protected:
Framebuffer framebuffer;
GLFWwindow* window;
virtual void update(const double now, const double delta) {}
virtual void draw() {}
virtual void windowSizeCallback(GLFWwindow* window, int width, int height)
{
glViewport(0, 0, width, height);
framebuffer = graphics::Framebuffer(width, height);
}
virtual void keyCallback(GLFWwindow* window, int key, int scancode, int action,
int mods) {}
virtual void mouseButtonCallback(GLFWwindow* window, int button, int action, int mods) {}
public:
Window(const int width, const int height, const std::string& name) :
framebuffer(width, height)
{
if (glfwInit() == GLFW_FALSE)
{
throw std::runtime_error("Failed to initialize GLFW!");
}
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, openGLMajorVersion);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, openGLMinorVersion);
window = glfwCreateWindow(width, height, name.c_str(), NULL, NULL);
if (!window)
{
glfwTerminate();
throw std::runtime_error("Failed to create a GLFW window!");
}
glfwMakeContextCurrent(window);
if (!gladLoadGLLoader(reinterpret_cast<GLADloadproc>(glfwGetProcAddress)))
{
glfwTerminate();
throw std::runtime_error("Failed to initialize GLAD!");
}
prev = glfwGetTime();
glfwSetWindowUserPointer(window, this);
glfwSetWindowSizeCallback(window, [](GLFWwindow* window, int width, int height)
{
reinterpret_cast<decltype(this)>(glfwGetWindowUserPointer(window))->
windowSizeCallback(window, width, height);
}
);
glfwSetKeyCallback(window, [](GLFWwindow* window, int key, int scancode, int action,
int mods)
{
reinterpret_cast<decltype(this)>(glfwGetWindowUserPointer(window))->
keyCallback(window, key, scancode, action, mods);
}
);
glfwSetMouseButtonCallback(window, [](GLFWwindow* window, int button, int action,
int mods)
{
reinterpret_cast<decltype(this)>(glfwGetWindowUserPointer(window))->
mouseButtonCallback(window, button, action, mods);
}
);
}
~Window()
{
glfwTerminate();
}
void loop()
{
double now;
while (!glfwWindowShouldClose(window))
{
now = glfwGetTime();
update(now, now - prev);
prev = now;
draw();
framebuffer.blit();
glfwSwapBuffers(window);
glfwPollEvents();
}
}
};
}