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