]> git.localhorst.tv Git - blank.git/blob - src/app/init.cpp
some code reorganization
[blank.git] / src / app / 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(bool double_buffer, int sample_size) {
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 (double_buffer) {
61                 if (SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1) != 0) {
62                         sdl_error("SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1)");
63                 }
64         }
65
66         if (sample_size > 1) {
67                 if (SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1) != 0) {
68                         sdl_error("SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS)");
69                 }
70                 if (SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, sample_size) != 0) {
71                         sdl_error("SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES)");
72                 }
73         }
74 }
75
76
77 Window::Window()
78 : handle(SDL_CreateWindow(
79         "blank",
80         SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
81         960, 600,
82         SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE
83 )) {
84         if (!handle) {
85                 sdl_error("SDL_CreateWindow");
86         }
87 }
88
89 Window::~Window() {
90         SDL_DestroyWindow(handle);
91 }
92
93 void Window::GrabInput() {
94         SDL_SetWindowGrab(handle, SDL_TRUE);
95 }
96
97 void Window::ReleaseInput() {
98         SDL_SetWindowGrab(handle, SDL_FALSE);
99 }
100
101 void Window::GrabMouse() {
102         if (SDL_SetRelativeMouseMode(SDL_TRUE) != 0) {
103                 sdl_error("SDL_SetRelativeMouseMode");
104         }
105 }
106
107 void Window::ReleaseMouse() {
108         if (SDL_SetRelativeMouseMode(SDL_FALSE) != 0) {
109                 sdl_error("SDL_SetRelativeMouseMode");
110         }
111 }
112
113 GLContext Window::CreateContext() {
114         return GLContext(handle);
115 }
116
117 void Window::Flip() {
118         SDL_GL_SwapWindow(handle);
119 }
120
121
122 GLContext::GLContext(SDL_Window *win)
123 : handle(SDL_GL_CreateContext(win)) {
124         if (!handle) {
125                 sdl_error("SDL_GL_CreateContext");
126         }
127 }
128
129 GLContext::~GLContext() {
130         if (handle) {
131                 SDL_GL_DeleteContext(handle);
132         }
133 }
134
135
136 GLContext::GLContext(GLContext &&other)
137 : handle(other.handle) {
138         other.handle = nullptr;
139 }
140
141 GLContext &GLContext::operator =(GLContext &&other) {
142         std::swap(handle, other.handle);
143         return *this;
144 }
145
146 void GLContext::EnableVSync() {
147         if (SDL_GL_SetSwapInterval(1) != 0) {
148                 sdl_error("SDL_GL_SetSwapInterval");
149         }
150 }
151
152 void GLContext::EnableDepthTest() noexcept {
153         glEnable(GL_DEPTH_TEST);
154         glDepthFunc(GL_LESS);
155 }
156
157 void GLContext::EnableBackfaceCulling() noexcept {
158         glEnable(GL_CULL_FACE);
159 }
160
161 void GLContext::Clear() noexcept {
162         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
163 }
164
165 void GLContext::ClearDepthBuffer() noexcept {
166         glClear(GL_DEPTH_BUFFER_BIT);
167 }
168
169
170 InitGLEW::InitGLEW() {
171         glewExperimental = GL_TRUE;
172         GLenum glew_err = glewInit();
173         if (glew_err != GLEW_OK) {
174                 std::string msg("glewInit: ");
175                 const GLubyte *errBegin = glewGetErrorString(glew_err);
176                 const GLubyte *errEnd = errBegin;
177                 while (*errEnd != '\0') {
178                         ++errEnd;
179                 }
180                 msg.append(errBegin, errEnd);
181                 throw std::runtime_error(msg);
182         }
183 }
184
185 }