#include #include #include namespace psemek::sdl2 { window::window(psemek::app::application::options const & options) : sdl_init_(init(SDL_INIT_EVENTS | SDL_INIT_VIDEO)) { SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, gl::sys::major_version()); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, gl::sys::minor_version()); SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); if (options.multisampling == 0) { SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0); } else { SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1); SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, options.multisampling); } std::uint32_t flags = SDL_WINDOW_OPENGL | SDL_WINDOW_HIDDEN | SDL_WINDOW_RESIZABLE; if (options.highdpi) flags |= SDL_WINDOW_ALLOW_HIGHDPI; SDL_DisplayMode display_mode; SDL_GetCurrentDisplayMode(0, &display_mode); window_ = SDL_CreateWindow(options.name.data(), SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, display_mode.w, display_mode.h, flags); if (!window_) sdl2::fail("Failed to create window: "); gl_context_ = SDL_GL_CreateContext(window_); if (!gl_context_) sdl2::fail("Failed to create OpenGL context: "); SDL_GL_MakeCurrent(window_, gl_context_); } geom::vector window::size() const { geom::vector result; SDL_GL_GetDrawableSize(window_, &result[0], &result[1]); return result; } void window::show() { SDL_ShowWindow(window_); } void window::swap() { SDL_GL_SwapWindow(window_); } void window::show_cursor(bool show) { SDL_ShowCursor(show ? SDL_TRUE : SDL_FALSE); SDL_SetRelativeMouseMode(show ? SDL_FALSE : SDL_TRUE); } void window::vsync(bool on) { if (on) { // try adaptive vsync if (SDL_GL_SetSwapInterval(-1) != 0) { // failed, try usual vsync then SDL_GL_SetSwapInterval(1); } } else { SDL_GL_SetSwapInterval(0); } } void window::windowed(bool on) { SDL_DisplayMode display_mode; SDL_GetCurrentDisplayMode(0, &display_mode); SDL_Rect display_usable_bounds; SDL_GetDisplayUsableBounds(0, &display_usable_bounds); SDL_SetWindowFullscreen(window_, on ? 0 : SDL_WINDOW_FULLSCREEN_DESKTOP); SDL_SetWindowBordered(window_, on ? SDL_TRUE : SDL_FALSE); SDL_RestoreWindow(window_); if (on) { int top_border, left_border, bottom_border, right_border; SDL_GetWindowBordersSize(window_, &top_border, &left_border, &bottom_border, &right_border); SDL_SetWindowSize(window_, display_usable_bounds.w - left_border - right_border, display_usable_bounds.h - top_border - bottom_border); SDL_SetWindowPosition(window_, left_border, top_border); } } window::~window() { if (gl_context_) SDL_GL_DeleteContext(gl_context_); if (window_) SDL_DestroyWindow(window_); } }