aboutsummaryrefslogtreecommitdiff
path: root/backends/graphics/openglsdl/openglsdl-graphics.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'backends/graphics/openglsdl/openglsdl-graphics.cpp')
-rw-r--r--backends/graphics/openglsdl/openglsdl-graphics.cpp206
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(&currentWidth, &currentHeight);
+ 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;