diff options
author | Alejandro Marzini | 2010-07-20 04:32:31 +0000 |
---|---|---|
committer | Alejandro Marzini | 2010-07-20 04:32:31 +0000 |
commit | 302400a701187eba6d0dee2daa253da87b29d83f (patch) | |
tree | 14ef4ab769860d534fa56a40949eb4e31e355db9 /backends | |
parent | 014d7b791c03c0c754ebc2d4ef2f2a961420a63a (diff) | |
download | scummvm-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.cpp | 43 | ||||
-rw-r--r-- | backends/graphics/opengl/gltexture.h | 9 | ||||
-rw-r--r-- | backends/graphics/opengl/opengl-graphics.cpp | 39 | ||||
-rw-r--r-- | backends/graphics/opengl/opengl-graphics.h | 2 | ||||
-rw-r--r-- | backends/graphics/openglsdl/openglsdl-graphics.cpp | 39 | ||||
-rw-r--r-- | backends/graphics/openglsdl/openglsdl-graphics.h | 1 |
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); |