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