aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--backends/graphics/opengl/opengl-graphics.cpp60
-rw-r--r--backends/graphics/opengl/texture.cpp7
-rw-r--r--backends/graphics/opengl/texture.h12
3 files changed, 64 insertions, 15 deletions
diff --git a/backends/graphics/opengl/opengl-graphics.cpp b/backends/graphics/opengl/opengl-graphics.cpp
index 3223075fbd..e3c56dccca 100644
--- a/backends/graphics/opengl/opengl-graphics.cpp
+++ b/backends/graphics/opengl/opengl-graphics.cpp
@@ -145,19 +145,10 @@ bool OpenGLGraphicsManager::setGraphicsMode(int mode) {
_gameScreen->enableLinearFiltering(mode == GFX_LINEAR);
}
- if (_overlay) {
- _overlay->enableLinearFiltering(mode == GFX_LINEAR);
- }
-
if (_cursor) {
_cursor->enableLinearFiltering(mode == GFX_LINEAR);
}
-#ifdef USE_OSD
- if (_osd) {
- _osd->enableLinearFiltering(mode == GFX_LINEAR);
- }
-#endif
return true;
default:
@@ -221,7 +212,13 @@ OSystem::TransactionError OpenGLGraphicsManager::endGFXTransaction() {
#else
Graphics::PixelFormat::createFormatCLUT8()
#endif
- )) {
+ )
+ // HACK: This is really nasty but we don't have any guarantees of
+ // a context existing before, which means we don't know the maximum
+ // supported texture size before this. Thus, we check whether the
+ // requested game resolution is supported over here.
+ || ( _currentState.gameWidth > (uint)Texture::getMaximumTextureSize()
+ || _currentState.gameHeight > (uint)Texture::getMaximumTextureSize())) {
if (_transactionMode == kTransactionActive) {
// Try to setup the old state in case its valid and is
// actually different from the new one.
@@ -754,12 +751,34 @@ void OpenGLGraphicsManager::setActualScreenSize(uint width, uint height) {
GLCALL(glMatrixMode(GL_MODELVIEW));
GLCALL(glLoadIdentity());
+ uint overlayWidth = width;
+ uint overlayHeight = height;
+
+ // WORKAROUND: We can only support surfaces up to the maximum supported
+ // texture size. Thus, in case we encounter a physical size bigger than
+ // this maximum texture size we will simply use an overlay as big as
+ // possible and then scale it to the physical display size. This sounds
+ // bad but actually all recent chips should support full HD resolution
+ // anyway. Thus, it should not be a real issue for modern hardware.
+ if ( overlayWidth > (uint)Texture::getMaximumTextureSize()
+ || overlayHeight > (uint)Texture::getMaximumTextureSize()) {
+ const frac_t outputAspect = intToFrac(_outputScreenWidth) / _outputScreenHeight;
+
+ if (outputAspect > (frac_t)FRAC_ONE) {
+ overlayWidth = Texture::getMaximumTextureSize();
+ overlayHeight = intToFrac(overlayWidth) / outputAspect;
+ } else {
+ overlayHeight = Texture::getMaximumTextureSize();
+ overlayWidth = fracToInt(overlayHeight * outputAspect);
+ }
+ }
+
// HACK: We limit the minimal overlay size to 256x200, which is the
// minimum of the dimensions of the two resolutions 256x240 (NES) and
// 320x200 (many DOS games use this). This hopefully assure that our
// GUI has working layouts.
- const uint overlayWidth = MAX<uint>(width, 256);
- const uint overlayHeight = MAX<uint>(height, 200);
+ overlayWidth = MAX<uint>(overlayWidth, 256);
+ overlayHeight = MAX<uint>(overlayHeight, 200);
if (!_overlay || _overlay->getFormat() != _defaultFormatAlpha) {
delete _overlay;
@@ -769,7 +788,10 @@ void OpenGLGraphicsManager::setActualScreenSize(uint width, uint height) {
const bool supported = getGLPixelFormat(_defaultFormatAlpha, glIntFormat, glFormat, glType);
assert(supported);
_overlay = new Texture(glIntFormat, glFormat, glType, _defaultFormatAlpha);
- _overlay->enableLinearFiltering(_currentState.graphicsMode == GFX_LINEAR);
+ // We always filter the overlay with GL_LINEAR. This assures it's
+ // readable in case it needs to be scaled and does not affect it
+ // otherwise.
+ _overlay->enableLinearFiltering(true);
}
_overlay->allocate(overlayWidth, overlayHeight);
_overlay->fill(0);
@@ -783,9 +805,12 @@ void OpenGLGraphicsManager::setActualScreenSize(uint width, uint height) {
const bool supported = getGLPixelFormat(_defaultFormatAlpha, glIntFormat, glFormat, glType);
assert(supported);
_osd = new Texture(glIntFormat, glFormat, glType, _defaultFormatAlpha);
- _osd->enableLinearFiltering(_currentState.graphicsMode == GFX_LINEAR);
+ // We always filter the osd with GL_LINEAR. This assures it's
+ // readable in case it needs to be scaled and does not affect it
+ // otherwise.
+ _osd->enableLinearFiltering(true);
}
- _osd->allocate(_outputScreenWidth, _outputScreenHeight);
+ _osd->allocate(_overlay->getWidth(), _overlay->getHeight());
_osd->fill(0);
#endif
@@ -824,6 +849,9 @@ void OpenGLGraphicsManager::notifyContextChange(const Graphics::PixelFormat &def
GLCALL(glEnable(GL_TEXTURE_2D));
+ // Query information needed by textures.
+ Texture::queryTextureInformation();
+
// Refresh the output screen dimensions if some are set up.
if (_outputScreenWidth != 0 && _outputScreenHeight != 0) {
setActualScreenSize(_outputScreenWidth, _outputScreenHeight);
@@ -860,6 +888,8 @@ void OpenGLGraphicsManager::adjustMousePosition(int16 &x, int16 &y) {
// here when the overlay is visible. This is because for very small
// resolutions we have a minimal overlay size and have to adjust
// for that.
+ // This can also happen when the overlay is smaller than the actual
+ // display size because of texture size limitations.
if (_overlay) {
x = (x * _overlay->getWidth()) / _outputScreenWidth;
y = (y * _overlay->getHeight()) / _outputScreenHeight;
diff --git a/backends/graphics/opengl/texture.cpp b/backends/graphics/opengl/texture.cpp
index d89bd00ac4..917bf70534 100644
--- a/backends/graphics/opengl/texture.cpp
+++ b/backends/graphics/opengl/texture.cpp
@@ -41,6 +41,13 @@ static GLuint nextHigher2(GLuint v) {
return ++v;
}
+GLint Texture::_maxTextureSize = 0;
+
+void Texture::queryTextureInformation() {
+ glGetIntegerv(GL_MAX_TEXTURE_SIZE, &_maxTextureSize);
+ debug(5, "OpenGL maximum texture size: %d", _maxTextureSize);
+}
+
Texture::Texture(GLenum glIntFormat, GLenum glFormat, GLenum glType, const Graphics::PixelFormat &format)
: _glIntFormat(glIntFormat), _glFormat(glFormat), _glType(glType), _format(format), _glFilter(GL_NEAREST),
_glTexture(0), _textureData(), _userPixelData(), _allDirty(false) {
diff --git a/backends/graphics/opengl/texture.h b/backends/graphics/opengl/texture.h
index 273e7b7319..e28d980de4 100644
--- a/backends/graphics/opengl/texture.h
+++ b/backends/graphics/opengl/texture.h
@@ -110,6 +110,16 @@ public:
virtual void *getPalette() { return 0; }
virtual const void *getPalette() const { return 0; }
+ /**
+ * Query texture related OpenGL information from the context. This only
+ * queries the maximum texture size for now.
+ */
+ static void queryTextureInformation();
+
+ /**
+ * @return Return the maximum texture dimensions supported.
+ */
+ static GLint getMaximumTextureSize() { return _maxTextureSize; }
protected:
virtual void updateTexture();
@@ -129,6 +139,8 @@ private:
bool _allDirty;
Common::Rect _dirtyArea;
void clearDirty() { _allDirty = false; _dirtyArea = Common::Rect(); }
+
+ static GLint _maxTextureSize;
};
class TextureCLUT8 : public Texture {