aboutsummaryrefslogtreecommitdiff
path: root/backends
diff options
context:
space:
mode:
authorAlejandro Marzini2010-07-20 04:32:31 +0000
committerAlejandro Marzini2010-07-20 04:32:31 +0000
commit302400a701187eba6d0dee2daa253da87b29d83f (patch)
tree14ef4ab769860d534fa56a40949eb4e31e355db9 /backends
parent014d7b791c03c0c754ebc2d4ef2f2a961420a63a (diff)
downloadscummvm-rg350-302400a701187eba6d0dee2daa253da87b29d83f.tar.gz
scummvm-rg350-302400a701187eba6d0dee2daa253da87b29d83f.tar.bz2
scummvm-rg350-302400a701187eba6d0dee2daa253da87b29d83f.zip
OPENGL: Implement fullscreen mode.
svn-id: r51049
Diffstat (limited to 'backends')
-rw-r--r--backends/graphics/opengl/gltexture.cpp43
-rw-r--r--backends/graphics/opengl/gltexture.h9
-rw-r--r--backends/graphics/opengl/opengl-graphics.cpp39
-rw-r--r--backends/graphics/opengl/opengl-graphics.h2
-rw-r--r--backends/graphics/openglsdl/openglsdl-graphics.cpp39
-rw-r--r--backends/graphics/openglsdl/openglsdl-graphics.h1
6 files changed, 75 insertions, 58 deletions
diff --git a/backends/graphics/opengl/gltexture.cpp b/backends/graphics/opengl/gltexture.cpp
index e1fb5ba00d..e3760ee2d8 100644
--- a/backends/graphics/opengl/gltexture.cpp
+++ b/backends/graphics/opengl/gltexture.cpp
@@ -77,7 +77,10 @@ GLTexture::GLTexture(byte bpp, GLenum format, GLenum type)
_glFormat(format),
_glType(type),
_textureWidth(0),
- _textureHeight(0) {
+ _textureHeight(0),
+ _realWidth(0),
+ _realHeight(0),
+ _refresh(false) {
// Generates the texture ID for GL
CHECK_GL_ERROR( glGenTextures(1, &_textureName) );
@@ -91,22 +94,20 @@ GLTexture::GLTexture(byte bpp, GLenum format, GLenum type)
}
GLTexture::~GLTexture() {
- debug("Destroying texture %u", _textureName);
CHECK_GL_ERROR( glDeleteTextures(1, &_textureName) );
}
void GLTexture::refresh() {
// Generates the texture ID for GL
- //CHECK_GL_ERROR( glGenTextures(1, &_textureName) );
- //updateBuffer(_surface.pixels, _surface.bytesPerPixel, 0, 0, _surface.w, _surface.h);
+ CHECK_GL_ERROR( glGenTextures(1, &_textureName) );
+ _refresh = true;
}
void GLTexture::allocBuffer(GLuint w, GLuint h) {
- _surface.w = w;
- _surface.h = h;
- _surface.bytesPerPixel = _bytesPerPixel;
-
- if (w <= _textureWidth && h <= _textureHeight)
+ _realWidth = w;
+ _realHeight = h;
+
+ if (w <= _textureWidth && h <= _textureHeight && !_refresh)
// Already allocated a sufficiently large buffer
return;
@@ -117,9 +118,6 @@ void GLTexture::allocBuffer(GLuint w, GLuint h) {
_textureWidth = nextHigher2(w);
_textureHeight = nextHigher2(h);
}
- _surface.pitch = _textureWidth * _bytesPerPixel;
-
- //_surface.create(w, h, _bytesPerPixel);
// Allocate room for the texture now, but pixel data gets uploaded
// later (perhaps with multiple TexSubImage2D operations).
@@ -130,6 +128,11 @@ void GLTexture::allocBuffer(GLuint w, GLuint h) {
CHECK_GL_ERROR( glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE) );
CHECK_GL_ERROR( glTexImage2D(GL_TEXTURE_2D, 0, _glFormat,
_textureWidth, _textureHeight, 0, _glFormat, _glType, NULL) );
+
+ if (_surface.w != _textureWidth || _surface.h != _textureHeight)
+ _surface.create(_textureWidth, _textureHeight, _bytesPerPixel);
+
+ _refresh = false;
}
void GLTexture::updateBuffer(const void *buf, int pitch, GLuint x, GLuint y, GLuint w, GLuint h) {
@@ -138,15 +141,13 @@ void GLTexture::updateBuffer(const void *buf, int pitch, GLuint x, GLuint y, GLu
if (static_cast<int>(w) * _bytesPerPixel == pitch) {
CHECK_GL_ERROR( glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h,
_glFormat, _glType, buf) );
- //memcpy(_surface.pixels, buf, w * pitch);
+ memcpy(_surface.getBasePtr(x, y), buf, h * pitch);
} else {
- // GLES removed the ability to specify pitch, so we
- // have to do this row by row.
const byte* src = static_cast<const byte*>(buf);
do {
CHECK_GL_ERROR( glTexSubImage2D(GL_TEXTURE_2D, 0, x, y,
w, 1, _glFormat, _glType, src) );
- //memcpy(_surface.pixels, src, pitch);
+ memcpy(_surface.getBasePtr(x, y), src, w * _bytesPerPixel);
++y;
src += pitch;
} while (--h);
@@ -154,19 +155,17 @@ void GLTexture::updateBuffer(const void *buf, int pitch, GLuint x, GLuint y, GLu
}
void GLTexture::fillBuffer(byte x) {
- byte* tmpbuf = new byte[_surface.h * _surface.w * _bytesPerPixel];
- memset(tmpbuf, x, _surface.h * _surface.w * _bytesPerPixel);
+ memset(_surface.pixels, x, _surface.h * _surface.pitch);
CHECK_GL_ERROR( glBindTexture(GL_TEXTURE_2D, _textureName) );
CHECK_GL_ERROR( glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, _surface.w, _surface.h,
- _glFormat, _glType, tmpbuf) );
- delete[] tmpbuf;
+ _glFormat, _glType, _surface.pixels) );
}
void GLTexture::drawTexture(GLshort x, GLshort y, GLshort w, GLshort h) {
CHECK_GL_ERROR( glBindTexture(GL_TEXTURE_2D, _textureName) );
- const GLfloat texWidth = (GLfloat)_surface.w / _textureWidth;//xdiv(_surface.w, _textureWidth);
- const GLfloat texHeight = (GLfloat)_surface.h / _textureHeight;//xdiv(_surface.h, _textureHeight);
+ const GLfloat texWidth = (GLfloat)_realWidth / _textureWidth;//xdiv(_surface.w, _textureWidth);
+ const GLfloat texHeight = (GLfloat)_realHeight / _textureHeight;//xdiv(_surface.h, _textureHeight);
const GLfloat texcoords[] = {
0, 0,
texWidth, 0,
diff --git a/backends/graphics/opengl/gltexture.h b/backends/graphics/opengl/gltexture.h
index 88a2b59962..d689e02951 100644
--- a/backends/graphics/opengl/gltexture.h
+++ b/backends/graphics/opengl/gltexture.h
@@ -65,13 +65,13 @@ public:
virtual void updateBuffer(const void *buf, int pitch, GLuint x, GLuint y,
GLuint w, GLuint h);
- virtual void drawTexture() { drawTexture(0, 0, _surface.w, _surface.h); }
+ virtual void drawTexture() { drawTexture(0, 0, _realWidth, _realHeight); }
virtual void drawTexture(GLshort x, GLshort y, GLshort w, GLshort h);
Graphics::Surface *getSurface() { return &_surface; }
- GLuint getWidth() const { return _surface.w; }
- GLuint getHeight() const { return _surface.h; }
+ GLuint getWidth() const { return _realWidth; }
+ GLuint getHeight() const { return _realHeight; }
GLuint getTextureName() const { return _textureName; }
protected:
@@ -80,7 +80,10 @@ protected:
const GLenum _glType;
Graphics::Surface _surface;
+ GLuint _realWidth;
+ GLuint _realHeight;
GLuint _textureName;
GLuint _textureWidth;
GLuint _textureHeight;
+ bool _refresh;
};
diff --git a/backends/graphics/opengl/opengl-graphics.cpp b/backends/graphics/opengl/opengl-graphics.cpp
index 413f4221f1..540e1ada0e 100644
--- a/backends/graphics/opengl/opengl-graphics.cpp
+++ b/backends/graphics/opengl/opengl-graphics.cpp
@@ -226,9 +226,9 @@ OSystem::TransactionError OpenGLGraphicsManager::endGFXTransaction() {
}
#ifdef USE_RGB_COLOR
- if (_transactionDetails.sizeChanged || _transactionDetails.formatChanged) {
+ if (_transactionDetails.sizeChanged || _transactionDetails.formatChanged || _transactionDetails.needHotswap) {
#else
- if (_transactionDetails.sizeChanged) {
+ if (_transactionDetails.sizeChanged || _transactionDetails.needHotswap) {
#endif
unloadGFXMode();
if (!loadGFXMode()) {
@@ -243,20 +243,6 @@ OSystem::TransactionError OpenGLGraphicsManager::endGFXTransaction() {
_videoMode.setup = true;
_screenChangeCount++;
}
- } else if (_transactionDetails.needHotswap) {
- //setGraphicsModeIntern();
- if (!hotswapGFXMode()) {
- if (_oldVideoMode.setup) {
- _transactionMode = kTransactionRollback;
- errors |= endGFXTransaction();
- }
- } else {
- _videoMode.setup = true;
- _screenChangeCount++;
-
- if (_transactionDetails.needUpdatescreen)
- internUpdateScreen();
- }
} else if (_transactionDetails.needUpdatescreen) {
//setGraphicsModeIntern();
internUpdateScreen();
@@ -365,13 +351,16 @@ void OpenGLGraphicsManager::clearOverlay() {
}
void OpenGLGraphicsManager::grabOverlay(OverlayColor *buf, int pitch) {
- const Graphics::Surface* surface = _overlayTexture->getSurface();
+ const Graphics::Surface *surface = _overlayTexture->getSurface();
assert(surface->bytesPerPixel == sizeof(buf[0]));
- int h = surface->h;
+ uint w = _overlayTexture->getWidth();
+ uint h = _overlayTexture->getHeight();
+ const byte *src = (byte *)surface->pixels;
do {
- //memcpy(buf, surface->pixels, surface->w * sizeof(buf[0]));
- memset(buf, 0, surface->w * sizeof(buf[0]));
+ //memset(buf, 0, w * sizeof(buf[0]));
+ memcpy(buf, src, w * sizeof(buf[0]));
buf += pitch;
+ src += surface->pitch;
} while (--h);
}
@@ -600,19 +589,19 @@ bool OpenGLGraphicsManager::loadGFXMode() {
GLenum type;
getGLPixelFormat(_screenFormat, bpp, format, type);
_gameTexture = new GLTexture(bpp, format, type);
- } else
+ } else if (_transactionDetails.newContext)
_gameTexture->refresh();
_overlayFormat = Graphics::PixelFormat(2, 4, 4, 4, 4, 12, 8, 4, 0);
if (!_overlayTexture)
_overlayTexture = new GLTexture(2, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4);
- else
+ else if (_transactionDetails.newContext)
_overlayTexture->refresh();
if (!_cursorTexture)
_cursorTexture = new GLTexture(4, GL_RGBA, GL_UNSIGNED_BYTE);
- else
+ else if (_transactionDetails.newContext)
_cursorTexture->refresh();
_gameTexture->allocBuffer(_videoMode.screenWidth, _videoMode.screenHeight);
@@ -628,10 +617,6 @@ void OpenGLGraphicsManager::unloadGFXMode() {
}
-bool OpenGLGraphicsManager::hotswapGFXMode() {
- return false;
-}
-
void OpenGLGraphicsManager::setScale(int newScale) {
if (newScale == _videoMode.scaleFactor)
return;
diff --git a/backends/graphics/opengl/opengl-graphics.h b/backends/graphics/opengl/opengl-graphics.h
index d76e328d07..038f658bb9 100644
--- a/backends/graphics/opengl/opengl-graphics.h
+++ b/backends/graphics/opengl/opengl-graphics.h
@@ -116,6 +116,7 @@ protected:
bool sizeChanged;
bool needHotswap;
bool needUpdatescreen;
+ bool newContext;
#ifdef USE_RGB_COLOR
bool formatChanged;
#endif
@@ -147,7 +148,6 @@ protected:
virtual void internUpdateScreen();
virtual bool loadGFXMode();
virtual void unloadGFXMode();
- virtual bool hotswapGFXMode();
virtual void setScale(int newScale);
diff --git a/backends/graphics/openglsdl/openglsdl-graphics.cpp b/backends/graphics/openglsdl/openglsdl-graphics.cpp
index 1eae7dd9c7..fe3662a520 100644
--- a/backends/graphics/openglsdl/openglsdl-graphics.cpp
+++ b/backends/graphics/openglsdl/openglsdl-graphics.cpp
@@ -139,6 +139,35 @@ bool OpenGLSdlGraphicsManager::loadGFXMode() {
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
+ if (_videoMode.fullscreen) {
+ SDL_Rect const* const*availableModes = SDL_ListModes(NULL, SDL_FULLSCREEN | SDL_OPENGL);
+ const SDL_Rect *bestMode = NULL;
+ uint bestMetric = (uint)-1;
+ while (const SDL_Rect *mode = *availableModes++) {
+ if (mode->w < _videoMode.hardwareWidth)
+ continue;
+ if (mode->h < _videoMode.hardwareHeight)
+ continue;
+
+ uint metric = mode->w * mode->h - _videoMode.hardwareWidth * _videoMode.hardwareHeight;
+ if (metric > bestMetric)
+ continue;
+
+ bestMode = mode;
+ bestMetric = metric;
+ }
+
+ if (bestMode) {
+ _videoMode.hardwareWidth = bestMode->w;
+ _videoMode.hardwareHeight = bestMode->h;
+ } else {
+ _videoMode.fullscreen = false;
+ }
+ }
+
+ if (_oldVideoMode.fullscreen != _videoMode.fullscreen)
+ _transactionDetails.newContext = true;
+
_hwscreen = SDL_SetVideoMode(_videoMode.hardwareWidth, _videoMode.hardwareHeight, 32,
_videoMode.fullscreen ? (SDL_FULLSCREEN | SDL_OPENGL) : (SDL_OPENGL | SDL_RESIZABLE)
);
@@ -164,10 +193,6 @@ void OpenGLSdlGraphicsManager::unloadGFXMode() {
}
}
-bool OpenGLSdlGraphicsManager::hotswapGFXMode() {
- return false;
-}
-
void OpenGLSdlGraphicsManager::internUpdateScreen() {
OpenGLGraphicsManager::internUpdateScreen();
@@ -216,7 +241,13 @@ bool OpenGLSdlGraphicsManager::handleScalerHotkeys(Common::KeyCode key) {
}
void OpenGLSdlGraphicsManager::setFullscreenMode(bool enable) {
+ if (_oldVideoMode.setup && _oldVideoMode.fullscreen == enable)
+ return;
+ if (_transactionMode == kTransactionActive) {
+ _videoMode.fullscreen = enable;
+ _transactionDetails.needHotswap = true;
+ }
}
bool OpenGLSdlGraphicsManager::isScalerHotkey(const Common::Event &event) {
diff --git a/backends/graphics/openglsdl/openglsdl-graphics.h b/backends/graphics/openglsdl/openglsdl-graphics.h
index a9ee200ece..b0bf12cd4d 100644
--- a/backends/graphics/openglsdl/openglsdl-graphics.h
+++ b/backends/graphics/openglsdl/openglsdl-graphics.h
@@ -55,7 +55,6 @@ protected:
virtual bool loadGFXMode();
virtual void unloadGFXMode();
- virtual bool hotswapGFXMode();
virtual void setFullscreenMode(bool enable);