13 void sdl_error(std::string msg) {
14 const char *error = SDL_GetError();
20 throw std::runtime_error(msg);
28 if (SDL_Init(SDL_INIT_VIDEO) != 0) {
29 sdl_error("SDL_Init(SDL_INIT_VIDEO)");
39 if (IMG_Init(IMG_INIT_PNG) == 0) {
40 sdl_error("IMG_Init(IMG_INIT_PNG)");
50 if (SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3) != 0) {
51 sdl_error("SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3)");
53 if (SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3) != 0) {
54 sdl_error("SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3)");
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)");
60 if (SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1) != 0) {
61 sdl_error("SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1)");
67 : handle(SDL_CreateWindow(
69 SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
71 SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE
74 sdl_error("SDL_CreateWindow");
79 SDL_DestroyWindow(handle);
82 void Window::GrabInput() {
83 SDL_SetWindowGrab(handle, SDL_TRUE);
86 void Window::ReleaseInput() {
87 SDL_SetWindowGrab(handle, SDL_FALSE);
90 void Window::GrabMouse() {
91 if (SDL_SetRelativeMouseMode(SDL_TRUE) != 0) {
92 sdl_error("SDL_SetRelativeMouseMode");
96 void Window::ReleaseMouse() {
97 if (SDL_SetRelativeMouseMode(SDL_FALSE) != 0) {
98 sdl_error("SDL_SetRelativeMouseMode");
102 GLContext Window::CreateContext() {
103 return GLContext(handle);
106 void Window::Flip() {
107 SDL_GL_SwapWindow(handle);
111 GLContext::GLContext(SDL_Window *win)
112 : handle(SDL_GL_CreateContext(win)) {
114 sdl_error("SDL_GL_CreateContext");
118 GLContext::~GLContext() {
120 SDL_GL_DeleteContext(handle);
125 GLContext::GLContext(GLContext &&other)
126 : handle(other.handle) {
127 other.handle = nullptr;
130 GLContext &GLContext::operator =(GLContext &&other) {
131 std::swap(handle, other.handle);
135 void GLContext::EnableVSync() {
136 if (SDL_GL_SetSwapInterval(1) != 0) {
137 sdl_error("SDL_GL_SetSwapInterval");
141 void GLContext::EnableDepthTest() {
142 glEnable(GL_DEPTH_TEST);
143 glDepthFunc(GL_LESS);
146 void GLContext::EnableBackfaceCulling() {
147 glEnable(GL_CULL_FACE);
150 void GLContext::Clear() {
151 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
155 InitGLEW::InitGLEW() {
156 glewExperimental = GL_TRUE;
157 GLenum glew_err = glewInit();
158 if (glew_err != GLEW_OK) {
159 std::string msg("glewInit: ");
160 const GLubyte *errBegin = glewGetErrorString(glew_err);
161 const GLubyte *errEnd = errBegin;
162 while (*errEnd != '\0') {
165 msg.append(errBegin, errEnd);
166 throw std::runtime_error(msg);