void Win32Window::setWindowSize(Vec2i size) { SetWindowLong(m_hWnd, GWL_STYLE, WS_OVERLAPPEDWINDOW); depth_ = 0; DWORD windowStyle = WS_OVERLAPPEDWINDOW; DWORD windowExtendedStyle = WS_EX_APPWINDOW; RECT rcWnd; SetRect(&rcWnd, 0, 0, size.x, size.y); AdjustWindowRectEx(&rcWnd, windowStyle, GetMenu(m_hWnd) != NULL, windowExtendedStyle); int dx = rcWnd.right - rcWnd.left - size.x; int dy = rcWnd.bottom - rcWnd.top - size.y; SetWindowPos(m_hWnd, HWND_NOTOPMOST, 0, 0, size.x + dx, size.y + dy, SWP_SHOWWINDOW); if(isFullscreen_) { isFullscreen_ = false; onToggleFullscreen(); } onResize(size.x, size.y); }
void SDL2Window::changeMode(DisplayMode mode, bool makeFullscreen) { if(!m_window) { m_size = mode.resolution; m_fullscreen = makeFullscreen; return; } if(m_fullscreen == makeFullscreen && m_size == mode.resolution) { return; } bool wasFullscreen = m_fullscreen; m_renderer->beforeResize(wasFullscreen || makeFullscreen); if(makeFullscreen) { if(mode.resolution != Vec2i_ZERO) { SDL_DisplayMode sdlmode; SDL_DisplayMode requested; requested.driverdata = NULL; requested.format = 0; requested.refresh_rate = 0; requested.w = mode.resolution.x; requested.h = mode.resolution.y; int display = SDL_GetWindowDisplayIndex(m_window); if(!SDL_GetClosestDisplayMode(display, &requested, &sdlmode)) { if(SDL_GetDesktopDisplayMode(display, &sdlmode)) { return; } } if(SDL_SetWindowDisplayMode(m_window, &sdlmode) < 0) { return; } } } Uint32 flags = getSDLFlagsForMode(mode.resolution, makeFullscreen); if(SDL_SetWindowFullscreen(m_window, flags) < 0) { return; } if(!makeFullscreen) { SDL_SetWindowSize(m_window, mode.resolution.x, mode.resolution.y); } if(wasFullscreen != makeFullscreen) { onToggleFullscreen(makeFullscreen); } if(makeFullscreen) { // SDL regrettably sends resize events when a fullscreen window is minimized. // Because of that we ignore all size change events when fullscreen. // Instead, handle the size change here. updateSize(); } tick(); }
void Win32Window::setFullscreenMode(Vec2i resolution, unsigned _depth) { SetWindowLong(m_hWnd, GWL_STYLE, WS_POPUP | WS_VISIBLE); depth_ = _depth; SetWindowPos(m_hWnd, HWND_TOP, 0, 0, resolution.x, resolution.y, SWP_SHOWWINDOW); if(!isFullscreen_) { isFullscreen_ = true; onToggleFullscreen(); } onResize(resolution.x, resolution.y); }
void SDLWindow::setWindowSize(Vec2i size) { if(!isFullscreen_ && size == getSize()) { return; } if(!setMode(DisplayMode(size, 0), false)) { return; } if(isFullscreen_) { isFullscreen_ = false; updateSize(true); onToggleFullscreen(); } }
void SDLWindow::setFullscreenMode(Vec2i resolution, unsigned _depth) { if(isFullscreen_ && size_ == resolution && depth_ == _depth) { return; } if(!setMode(DisplayMode(resolution, depth_), true)) { return; } if(!isFullscreen_) { isFullscreen_ = true; updateSize(true); onToggleFullscreen(); } else { updateSize(true); } }
bool SDL2Window::initialize() { arx_assert(!m_displayModes.empty()); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); #if ARX_PLATFORM == ARX_PLATFORM_WIN32 // Used on Windows to prevent software opengl fallback. // The linux situation: // Causes SDL to require visuals without caveats. // On linux some drivers only supply multisample capable GLX Visuals // with a GLX_NON_CONFORMANT_VISUAL_EXT caveat. // see: https://www.opengl.org/registry/specs/EXT/visual_rating.txt SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1); #endif // TODO EGL and core profile are not supported yet SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY); if(gldebug::isEnabled()) { SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG); } int x = SDL_WINDOWPOS_UNDEFINED, y = SDL_WINDOWPOS_UNDEFINED; Uint32 windowFlags = getSDLFlagsForMode(m_size, m_fullscreen); windowFlags |= SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIDDEN; for(int msaa = m_maxMSAALevel; msaa > 0; msaa--) { bool lastTry = (msaa == 1); // Cleanup context and window from previous tries if(m_glcontext) { SDL_GL_DeleteContext(m_glcontext); m_glcontext = NULL; } if(m_window) { SDL_DestroyWindow(m_window); m_window = NULL; } SDL_ClearError(); SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, msaa > 1 ? 1 : 0); SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, msaa > 1 ? msaa : 0); m_window = SDL_CreateWindow(m_title.c_str(), x, y, m_size.x, m_size.y, windowFlags); if(!m_window) { if(lastTry) { LogError << "Could not create window: " << SDL_GetError(); return false; } continue; } m_glcontext = SDL_GL_CreateContext(m_window); if(!m_glcontext) { if(lastTry) { LogError << "Could not create GL context: " << SDL_GetError(); return false; } continue; } // Verify that the MSAA setting matches what was requested int msaaEnabled, msaaValue; SDL_GL_GetAttribute(SDL_GL_MULTISAMPLEBUFFERS, &msaaEnabled); SDL_GL_GetAttribute(SDL_GL_MULTISAMPLESAMPLES, &msaaValue); if(!lastTry) { if(!msaaEnabled || msaaValue < msaa) { continue; } } if(msaaEnabled) { m_MSAALevel = msaaValue; } else { m_MSAALevel = 0; } // Verify that we actually got an accelerated context (void)glGetError(); // clear error flags GLint texunits = 0; glGetIntegerv(GL_MAX_TEXTURE_UNITS, &texunits); if(glGetError() != GL_NO_ERROR || texunits < GLint(m_minTextureUnits)) { if(lastTry) { LogError << "Not enough GL texture units available: have " << texunits << ", need at least " << m_minTextureUnits; return false; } continue; } // All good const char * system = "(unknown)"; { ARX_SDL_SysWMinfo info; info.version.major = 2; info.version.minor = 0; info.version.patch = 4; if(SDL_GetWindowWMInfo(m_window, reinterpret_cast<SDL_SysWMinfo *>(&info))) { switch(info.subsystem) { case ARX_SDL_SYSWM_UNKNOWN: break; case ARX_SDL_SYSWM_WINDOWS: system = "Windows"; break; case ARX_SDL_SYSWM_X11: system = "X11"; break; #if SDL_VERSION_ATLEAST(2, 0, 3) case ARX_SDL_SYSWM_WINRT: system = "WinRT"; break; #endif case ARX_SDL_SYSWM_DIRECTFB: system = "DirectFB"; break; case ARX_SDL_SYSWM_COCOA: system = "Cocoa"; break; case ARX_SDL_SYSWM_UIKIT: system = "UIKit"; break; #if SDL_VERSION_ATLEAST(2, 0, 2) case ARX_SDL_SYSWM_WAYLAND: system = "Wayland"; break; case ARX_SDL_SYSWM_MIR: system = "Mir"; break; #endif #if SDL_VERSION_ATLEAST(2, 0, 4) case ARX_SDL_SYSWM_ANDROID: system = "Android"; break; #endif } } } int red = 0, green = 0, blue = 0, alpha = 0, depth = 0, doublebuffer = 0; SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &red); SDL_GL_GetAttribute(SDL_GL_GREEN_SIZE, &green); SDL_GL_GetAttribute(SDL_GL_BLUE_SIZE, &blue); SDL_GL_GetAttribute(SDL_GL_ALPHA_SIZE, &alpha); SDL_GL_GetAttribute(SDL_GL_DEPTH_SIZE, &depth); SDL_GL_GetAttribute(SDL_GL_DOUBLEBUFFER, &doublebuffer); LogInfo << "Window: " << system << " r:" << red << " g:" << green << " b:" << blue << " a:" << alpha << " depth:" << depth << " aa:" << msaa << "x" << " doublebuffer:" << doublebuffer; break; } // Use the executable icon for the window #if ARX_PLATFORM == ARX_PLATFORM_WIN32 { SDL_SysWMinfo info; SDL_VERSION(&info.version); if(SDL_GetWindowWMInfo(m_window, &info) && info.subsystem == SDL_SYSWM_WINDOWS) { platform::WideString filename; filename.allocate(filename.capacity()); while(true) { DWORD size = GetModuleFileNameW(NULL, filename.data(), filename.size()); if(size < filename.size()) { filename.resize(size); break; } filename.allocate(filename.size() * 2); } HICON largeIcon = 0; HICON smallIcon = 0; ExtractIconExW(filename, 0, &largeIcon, &smallIcon, 1); if(smallIcon) { SendMessage(info.info.win.window, WM_SETICON, ICON_SMALL, LPARAM(smallIcon)); } if(largeIcon) { SendMessage(info.info.win.window, WM_SETICON, ICON_BIG, LPARAM(largeIcon)); } } } #endif setVSync(m_vsync); SDL_ShowWindow(m_window); SDL_ShowCursor(SDL_DISABLE); m_renderer->initialize(); onCreate(); onToggleFullscreen(m_fullscreen); updateSize(true); onShow(true); onFocus(true); return true; }
bool SDL2Window::initialize() { arx_assert(!m_displayModes.empty()); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); // We need an accelerated OpenGL context or we'll likely fail later SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1); // TODO EGL and core profile are not supported yet SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY); SDL_GL_SetAttribute(SDL_GL_CONTEXT_EGL, 0); if(gldebug::isEnabled()) { SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG); } int x = SDL_WINDOWPOS_UNDEFINED, y = SDL_WINDOWPOS_UNDEFINED; Uint32 windowFlags = getSDLFlagsForMode(m_size, m_fullscreen); windowFlags |= SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIDDEN; for(int msaa = m_maxMSAALevel; msaa > 0; msaa--) { bool lastTry = (msaa == 1); // Cleanup context and window from previous tries if(m_glcontext) { SDL_GL_DeleteContext(m_glcontext); m_glcontext = NULL; } if(m_window) { SDL_DestroyWindow(m_window); m_window = NULL; } SDL_ClearError(); SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, msaa > 1 ? 1 : 0); SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, msaa > 1 ? msaa : 0); m_window = SDL_CreateWindow(m_title.c_str(), x, y, m_size.x, m_size.y, windowFlags); if(!m_window) { if(lastTry) { LogError << "Could not create window: " << SDL_GetError(); return false; } continue; } m_glcontext = SDL_GL_CreateContext(m_window); if(!m_glcontext) { if(lastTry) { LogError << "Could not create GL context: " << SDL_GetError(); return false; } continue; } // Verify that the MSAA setting matches what was requested int msaaEnabled, msaaValue; SDL_GL_GetAttribute(SDL_GL_MULTISAMPLEBUFFERS, &msaaEnabled); SDL_GL_GetAttribute(SDL_GL_MULTISAMPLESAMPLES, &msaaValue); if(!lastTry) { if(!msaaEnabled || msaaValue < msaa) { continue; } } if(msaaEnabled) { m_MSAALevel = msaaValue; } else { m_MSAALevel = 0; } // Verify that we actually got an accelerated context (void)glGetError(); // clear error flags GLint texunits = 0; glGetIntegerv(GL_MAX_TEXTURE_UNITS, &texunits); if(glGetError() != GL_NO_ERROR || texunits < GLint(m_minTextureUnits)) { if(lastTry) { LogError << "Not enough GL texture units available: have " << texunits << ", need at least " << m_minTextureUnits; return false; } continue; } // All good int red = 0, green = 0, blue = 0, alpha = 0, depth = 0, doublebuffer = 0; SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &red); SDL_GL_GetAttribute(SDL_GL_GREEN_SIZE, &green); SDL_GL_GetAttribute(SDL_GL_BLUE_SIZE, &blue); SDL_GL_GetAttribute(SDL_GL_ALPHA_SIZE, &alpha); SDL_GL_GetAttribute(SDL_GL_DEPTH_SIZE, &depth); SDL_GL_GetAttribute(SDL_GL_DOUBLEBUFFER, &doublebuffer); LogInfo << "Window: r:" << red << " g:" << green << " b:" << blue << " a:" << alpha << " depth:" << depth << " aa:" << msaa << "x doublebuffer:" << doublebuffer; break; } setVSync(m_vsync); SDL_ShowWindow(m_window); SDL_ShowCursor(SDL_DISABLE); m_renderer->initialize(); onCreate(); onToggleFullscreen(m_fullscreen); updateSize(true); onShow(true); onFocus(true); return true; }