]> git.localhorst.tv Git - blank.git/blob - src/init.cpp
9e73c2890226e11cd20a271cefae00c79c4f3e7c
[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 InitGL::~InitGL() {
66
67 }
68
69
70 Window::Window()
71 : handle(SDL_CreateWindow(
72         "blank",
73         SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
74         960, 600,
75         SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE
76 )) {
77         if (!handle) {
78                 sdl_error("SDL_CreateWindow");
79         }
80 }
81
82 Window::~Window() {
83         SDL_DestroyWindow(handle);
84 }
85
86 void Window::GrabInput() {
87         SDL_SetWindowGrab(handle, SDL_TRUE);
88 }
89
90 void Window::ReleaseInput() {
91         SDL_SetWindowGrab(handle, SDL_FALSE);
92 }
93
94 void Window::GrabMouse() {
95         if (SDL_SetRelativeMouseMode(SDL_TRUE) != 0) {
96                 sdl_error("SDL_SetRelativeMouseMode");
97         }
98 }
99
100 void Window::ReleaseMouse() {
101         if (SDL_SetRelativeMouseMode(SDL_FALSE) != 0) {
102                 sdl_error("SDL_SetRelativeMouseMode");
103         }
104 }
105
106 GLContext Window::CreateContext() {
107         return GLContext(handle);
108 }
109
110 void Window::Flip() {
111         SDL_GL_SwapWindow(handle);
112 }
113
114
115 GLContext::GLContext(SDL_Window *win)
116 : handle(SDL_GL_CreateContext(win)) {
117         if (!handle) {
118                 sdl_error("SDL_GL_CreateContext");
119         }
120 }
121
122 GLContext::~GLContext() {
123         if (handle) {
124                 SDL_GL_DeleteContext(handle);
125         }
126 }
127
128
129 GLContext::GLContext(GLContext &&other)
130 : handle(other.handle) {
131         other.handle = nullptr;
132 }
133
134 GLContext &GLContext::operator =(GLContext &&other) {
135         std::swap(handle, other.handle);
136         return *this;
137 }
138
139 void GLContext::EnableVSync() {
140         if (SDL_GL_SetSwapInterval(1) != 0) {
141                 sdl_error("SDL_GL_SetSwapInterval");
142         }
143 }
144
145 void GLContext::EnableDepthTest() {
146         glEnable(GL_DEPTH_TEST);
147         glDepthFunc(GL_LESS);
148 }
149
150 void GLContext::EnableBackfaceCulling() {
151         glEnable(GL_CULL_FACE);
152 }
153
154 void GLContext::Clear() {
155         glClear(GL_COLOR_BUFFER_BIT | 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 InitGLEW::~InitGLEW() {
175
176 }
177
178 }