diff options
Diffstat (limited to 'backends/graphics/openglsdl/openglsdl-graphics.cpp')
-rw-r--r-- | backends/graphics/openglsdl/openglsdl-graphics.cpp | 206 |
1 files changed, 151 insertions, 55 deletions
diff --git a/backends/graphics/openglsdl/openglsdl-graphics.cpp b/backends/graphics/openglsdl/openglsdl-graphics.cpp index 0d140ee4d7..860173a3c6 100644 --- a/backends/graphics/openglsdl/openglsdl-graphics.cpp +++ b/backends/graphics/openglsdl/openglsdl-graphics.cpp @@ -45,6 +45,100 @@ OpenGLSdlGraphicsManager::OpenGLSdlGraphicsManager(uint desktopWidth, uint deskt SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); + // Setup proper SDL OpenGL context creation. +#if SDL_VERSION_ATLEAST(2, 0, 0) + OpenGL::ContextType glContextType; + + // Context version 1.4 is choosen arbitrarily based on what most shader + // extensions were written against. +#define DEFAULT_GL_MAJOR 1 +#define DEFAULT_GL_MINOR 4 + +#define DEFAULT_GLES_MAJOR 1 +#define DEFAULT_GLES_MINOR 1 + +#define DEFAULT_GLES2_MAJOR 2 +#define DEFAULT_GLES2_MINOR 0 + +#if USE_FORCED_GL + glContextType = OpenGL::kContextGL; + _glContextProfileMask = 0; + _glContextMajor = DEFAULT_GL_MAJOR; + _glContextMinor = DEFAULT_GL_MINOR; +#elif USE_FORCED_GLES + glContextType = OpenGL::kContextGLES; + _glContextProfileMask = SDL_GL_CONTEXT_PROFILE_ES; + _glContextMajor = DEFAULT_GLES_MAJOR; + _glContextMinor = DEFAULT_GLES_MINOR; +#elif USE_FORCED_GLES2 + glContextType = OpenGL::kContextGLES2; + _glContextProfileMask = SDL_GL_CONTEXT_PROFILE_ES; + _glContextMajor = DEFAULT_GLES2_MAJOR; + _glContextMinor = DEFAULT_GLES2_MINOR; +#else + bool noDefaults = false; + + // Obtain the default GL(ES) context SDL2 tries to setup. + // + // Please note this might not actually be SDL2's defaults when multiple + // instances of this object have been created. But that is no issue + // because then we already set up what we want to use. + // + // In case no defaults are given we prefer OpenGL over OpenGL ES. + if (SDL_GL_GetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, &_glContextProfileMask) != 0) { + _glContextProfileMask = 0; + noDefaults = true; + } + + if (SDL_GL_GetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, &_glContextMajor) != 0) { + noDefaults = true; + } + + if (SDL_GL_GetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, &_glContextMinor) != 0) { + noDefaults = true; + } + + if (noDefaults) { + if (_glContextProfileMask == SDL_GL_CONTEXT_PROFILE_ES) { + _glContextMajor = DEFAULT_GLES_MAJOR; + _glContextMinor = DEFAULT_GLES_MINOR; + } else { + _glContextProfileMask = 0; + _glContextMajor = DEFAULT_GL_MAJOR; + _glContextMinor = DEFAULT_GL_MINOR; + } + } + + if (_glContextProfileMask == SDL_GL_CONTEXT_PROFILE_ES) { + if (_glContextMajor >= 2) { + glContextType = OpenGL::kContextGLES2; + } else { + glContextType = OpenGL::kContextGLES; + } + } else if (_glContextProfileMask == SDL_GL_CONTEXT_PROFILE_CORE) { + glContextType = OpenGL::kContextGL; + + // Core profile does not allow legacy functionality, which we use. + // Thus we request a standard OpenGL context. + _glContextProfileMask = 0; + _glContextMajor = DEFAULT_GL_MAJOR; + _glContextMinor = DEFAULT_GL_MINOR; + } else { + glContextType = OpenGL::kContextGL; + } +#undef DEFAULT_GL_MAJOR +#undef DEFAULT_GL_MINOR +#undef DEFAULT_GLES_MAJOR +#undef DEFAULT_GLES_MINOR +#undef DEFAULT_GLES2_MAJOR +#undef DEFAULT_GLES2_MINOR +#endif + + setContextType(glContextType); +#else + setContextType(OpenGL::kContextGL); +#endif + // Retrieve a list of working fullscreen modes #if SDL_VERSION_ATLEAST(2, 0, 0) const int numModes = SDL_GetNumDisplayModes(0); @@ -100,6 +194,10 @@ OpenGLSdlGraphicsManager::OpenGLSdlGraphicsManager(uint desktopWidth, uint deskt } OpenGLSdlGraphicsManager::~OpenGLSdlGraphicsManager() { +#if SDL_VERSION_ATLEAST(2, 0, 0) + notifyContextDestroy(); + SDL_GL_DeleteContext(_glContext); +#endif } void OpenGLSdlGraphicsManager::activateManager() { @@ -210,20 +308,26 @@ Common::List<Graphics::PixelFormat> OpenGLSdlGraphicsManager::getSupportedFormat // RGBA4444 formats.push_back(Graphics::PixelFormat(2, 4, 4, 4, 4, 12, 8, 4, 0)); -#ifndef USE_GLES +#if !USE_FORCED_GLES && !USE_FORCED_GLES2 +#if !USE_FORCED_GL + if (!isGLESContext()) { +#endif #ifdef SCUMM_LITTLE_ENDIAN - // RGBA8888 - formats.push_back(Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0)); + // RGBA8888 + formats.push_back(Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0)); #else - // ABGR8888 - formats.push_back(Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24)); + // ABGR8888 + formats.push_back(Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24)); +#endif +#if !USE_FORCED_GL + } +#endif #endif - // ARGB8888, this should not be here, but Sword25 requires it. :-/ - formats.push_back(Graphics::PixelFormat(4, 8, 8, 8, 8, 16, 8, 0, 24)); // RGB555, this is used by SCUMM HE 16 bit games. + // This is not natively supported by OpenGL ES implementations, we convert + // the pixel format internally. formats.push_back(Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0)); -#endif formats.push_back(Graphics::PixelFormat::createFormatCLUT8()); @@ -244,8 +348,19 @@ void OpenGLSdlGraphicsManager::notifyVideoExpose() { void OpenGLSdlGraphicsManager::notifyResize(const uint width, const uint height) { #if SDL_VERSION_ATLEAST(2, 0, 0) + // We sometime get outdated resize events from SDL2. So check that the size we get + // is the actual current window size. If not ignore the resize. + // The issue for example occurs when switching from fullscreen to windowed mode or + // when switching between different fullscreen resolutions because SDL_DestroyWindow + // for a fullscreen window that doesn't have the SDL_WINDOW_FULLSCREEN_DESKTOP flag + // causes a SDL_WINDOWEVENT_RESIZED event with the old resolution to be sent, and this + // event is processed after recreating the window at the new resolution. + int currentWidth, currentHeight; + getWindowDimensions(¤tWidth, ¤tHeight); + if (width != (uint)currentWidth || height != (uint)currentHeight) + return; setActualScreenSize(width, height); - _eventSource->resetKeyboadEmulation(width - 1, height - 1); + _eventSource->resetKeyboardEmulation(width - 1, height - 1); #else if (!_ignoreResizeEvents && _hwScreen && !(_hwScreen->flags & SDL_FULLSCREEN)) { // We save that we handled a resize event here. We need to know this @@ -305,6 +420,10 @@ void OpenGLSdlGraphicsManager::refreshScreen() { #endif } +void *OpenGLSdlGraphicsManager::getProcAddress(const char *name) const { + return SDL_GL_GetProcAddress(name); +} + bool OpenGLSdlGraphicsManager::setupMode(uint width, uint height) { // In case we request a fullscreen mode we will use the mode the user // has chosen last time or the biggest mode available. @@ -378,6 +497,11 @@ bool OpenGLSdlGraphicsManager::setupMode(uint width, uint height) { flags |= SDL_WINDOW_RESIZABLE; } + // Request a OpenGL (ES) context we can use. + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, _glContextProfileMask); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, _glContextMajor); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, _glContextMinor); + if (!_window->createWindow(width, height, flags)) { // We treat fullscreen requests as a "hint" for now. This means in // case it is not available we simply ignore it. @@ -390,13 +514,6 @@ bool OpenGLSdlGraphicsManager::setupMode(uint width, uint height) { } } -#ifdef USE_GLES - // SDL2 will create a GLES2 context by default, so this is needed for GLES1-profile - // functions to work. - SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 1); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1); -#endif _glContext = SDL_GL_CreateContext(_window->getSDLWindow()); if (!_glContext) { return false; @@ -406,7 +523,7 @@ bool OpenGLSdlGraphicsManager::setupMode(uint width, uint height) { int actualWidth, actualHeight; getWindowDimensions(&actualWidth, &actualHeight); setActualScreenSize(actualWidth, actualHeight); - _eventSource->resetKeyboadEmulation(actualWidth - 1, actualHeight - 1); + _eventSource->resetKeyboardEmulation(actualWidth - 1, actualHeight - 1); return true; #else // WORKAROUND: Working around infamous SDL bugs when switching @@ -452,7 +569,7 @@ bool OpenGLSdlGraphicsManager::setupMode(uint width, uint height) { if (_hwScreen) { notifyContextCreate(rgba8888, rgba8888); setActualScreenSize(_hwScreen->w, _hwScreen->h); - _eventSource->resetKeyboadEmulation(_hwScreen->w - 1, _hwScreen->h - 1); + _eventSource->resetKeyboardEmulation(_hwScreen->w - 1, _hwScreen->h - 1); } // Ignore resize events (from SDL) for a few frames, if this isn't @@ -495,9 +612,9 @@ bool OpenGLSdlGraphicsManager::notifyEvent(const Common::Event &event) { #ifdef USE_OSD if (getFeatureState(OSystem::kFeatureFullscreenMode)) { - displayMessageOnOSD("Fullscreen mode"); + displayMessageOnOSD(_("Fullscreen mode")); } else { - displayMessageOnOSD("Windowed mode"); + displayMessageOnOSD(_("Windowed mode")); } #endif return true; @@ -590,7 +707,7 @@ bool OpenGLSdlGraphicsManager::notifyEvent(const Common::Event &event) { #ifdef USE_OSD int windowWidth = 0, windowHeight = 0; getWindowDimensions(&windowWidth, &windowHeight); - const Common::String osdMsg = Common::String::format("Resolution: %dx%d", windowWidth, windowHeight); + const Common::String osdMsg = Common::String::format(_("Resolution: %dx%d"), windowWidth, windowHeight); displayMessageOnOSD(osdMsg.c_str()); #endif @@ -610,45 +727,21 @@ bool OpenGLSdlGraphicsManager::notifyEvent(const Common::Event &event) { assert(!_ignoreLoadVideoMode); #ifdef USE_OSD - Common::String osdMsg = "Aspect ratio correction: "; - osdMsg += getFeatureState(OSystem::kFeatureAspectRatioCorrection) ? "enabled" : "disabled"; - displayMessageOnOSD(osdMsg.c_str()); + if (getFeatureState(OSystem::kFeatureAspectRatioCorrection)) + displayMessageOnOSD(_("Enabled aspect ratio correction")); + else + displayMessageOnOSD(_("Disabled aspect ratio correction")); #endif return true; } else if (event.kbd.keycode == Common::KEYCODE_f) { - // Ctrl+Alt+f toggles the graphics modes. - - // We are crazy we will allow the OpenGL base class to - // introduce new graphics modes like shaders for special - // filtering. If some other OpenGL subclass needs this, - // we can think of refactoring this. - int mode = getGraphicsMode(); - const OSystem::GraphicsMode *supportedModes = getSupportedGraphicsModes(); - const OSystem::GraphicsMode *modeDesc = nullptr; - - // Search the current mode. - for (; supportedModes->name; ++supportedModes) { - if (supportedModes->id == mode) { - modeDesc = supportedModes; - break; - } - } - assert(modeDesc); - - // Try to use the next mode in the list. - ++modeDesc; - if (!modeDesc->name) { - modeDesc = getSupportedGraphicsModes(); - } - - // Never ever try to resize the window when we simply want to - // switch the graphics mode. This assures that the window size - // does not change. + // Never ever try to resize the window when we simply want to enable or disable filtering. + // This assures that the window size does not change. _ignoreLoadVideoMode = true; + // Ctrl+Alt+f toggles filtering on/off beginGFXTransaction(); - setGraphicsMode(modeDesc->id); + setFeatureState(OSystem::kFeatureFilteringMode, !getFeatureState(OSystem::kFeatureFilteringMode)); endGFXTransaction(); // Make sure we do not ignore the next resize. This @@ -656,8 +749,11 @@ bool OpenGLSdlGraphicsManager::notifyEvent(const Common::Event &event) { assert(!_ignoreLoadVideoMode); #ifdef USE_OSD - const Common::String osdMsg = Common::String::format("Graphics mode: %s", _(modeDesc->description)); - displayMessageOnOSD(osdMsg.c_str()); + if (getFeatureState(OSystem::kFeatureFilteringMode)) { + displayMessageOnOSD(_("Filtering enabled")); + } else { + displayMessageOnOSD(_("Filtering disabled")); + } #endif return true; |