]> git.localhorst.tv Git - blank.git/blob - src/init.cpp
split entity from controller
[blank.git] / src / init.cpp
1 #include "init.hpp"
2
3 #include <algorithm>
4 #include <SDL.h>
5 #include <SDL_image.h>
6 #include <stdexcept>
7 #include <string>
8 #include <GL/glew.h>
9
10
11 namespace {
12
13 void sdl_error(std::string msg) {
14         const char *error = SDL_GetError();
15         if (*error != '\0') {
16                 msg += ": ";
17                 msg += error;
18                 SDL_ClearError();
19         }
20         throw std::runtime_error(msg);
21 }
22
23 }
24
25 namespace blank {
26
27 InitSDL::InitSDL() {
28         if (SDL_Init(SDL_INIT_VIDEO) != 0) {
29                 sdl_error("SDL_Init(SDL_INIT_VIDEO)");
30         }
31 }
32
33 InitSDL::~InitSDL() {
34         SDL_Quit();
35 }
36
37
38 InitIMG::InitIMG() {
39         if (IMG_Init(IMG_INIT_PNG) == 0) {
40                 sdl_error("IMG_Init(IMG_INIT_PNG)");
41         }
42 }
43
44 InitIMG::~InitIMG() {
45         IMG_Quit();
46 }
47
48
49 InitGL::InitGL() {
50         if (SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3) != 0) {
51                 sdl_error("SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3)");
52         }
53         if (SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3) != 0) {
54                 sdl_error("SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3)");
55         }
56         if (SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE) != 0) {
57                 sdl_error("SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE)");
58         }
59
60         if (SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1) != 0) {
61                 sdl_error("SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1)");
62         }
63 }
64
65
66 Window::Window()
67 : handle(SDL_CreateWindow(
68         "blank",
69         SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
70         960, 600,
71         SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE
72 )) {
73         if (!handle) {
74                 sdl_error("SDL_CreateWindow");
75         }
76 }
77
78 Window::~Window() {
79         SDL_DestroyWindow(handle);
80 }
81
82 void Window::GrabInput() {
83         SDL_SetWindowGrab(handle, SDL_TRUE);
84 }
85
86 void Window::ReleaseInput() {
87         SDL_SetWindowGrab(handle, SDL_FALSE);
88 }
89
90 void Window::GrabMouse() {
91         if (SDL_SetRelativeMouseMode(SDL_TRUE) != 0) {
92                 sdl_error("SDL_SetRelativeMouseMode");
93         }
94 }
95
96 void Window::ReleaseMouse() {
97         if (SDL_SetRelativeMouseMode(SDL_FALSE) != 0) {
98                 sdl_error("SDL_SetRelativeMouseMode");
99         }
100 }
101
102 GLContext Window::CreateContext() {
103         return GLContext(handle);
104 }
105
106 void Window::Flip() {
107         SDL_GL_SwapWindow(handle);
108 }
109
110
111 GLContext::GLContext(SDL_Window *win)
112 : handle(SDL_GL_CreateContext(win)) {
113         if (!handle) {
114                 sdl_error("SDL_GL_CreateContext");
115         }
116 }
117
118 GLContext::~GLContext() {
119         if (handle) {
120                 SDL_GL_DeleteContext(handle);
121         }
122 }
123
124
125 GLContext::GLContext(GLContext &&other)
126 : handle(other.handle) {
127         other.handle = nullptr;
128 }
129
130 GLContext &GLContext::operator =(GLContext &&other) {
131         std::swap(handle, other.handle);
132         return *this;
133 }
134
135 void GLContext::EnableVSync() {
136         if (SDL_GL_SetSwapInterval(1) != 0) {
137                 sdl_error("SDL_GL_SetSwapInterval");
138         }
139 }
140
141 void GLContext::EnableDepthTest() {
142         glEnable(GL_DEPTH_TEST);
143         glDepthFunc(GL_LESS);
144 }
145
146 void GLContext::EnableBackfaceCulling() {
147         glEnable(GL_CULL_FACE);
148 }
149
150 void GLContext::Clear() {
151         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
152 }
153
154 void GLContext::ClearDepthBuffer() {
155         glClear(GL_DEPTH_BUFFER_BIT);
156 }
157
158
159 InitGLEW::InitGLEW() {
160         glewExperimental = GL_TRUE;
161         GLenum glew_err = glewInit();
162         if (glew_err != GLEW_OK) {
163                 std::string msg("glewInit: ");
164                 const GLubyte *errBegin = glewGetErrorString(glew_err);
165                 const GLubyte *errEnd = errBegin;
166                 while (*errEnd != '\0') {
167                         ++errEnd;
168                 }
169                 msg.append(errBegin, errEnd);
170                 throw std::runtime_error(msg);
171         }
172 }
173
174 }