diff options
author | Johannes Schickel | 2015-12-11 21:22:42 +0100 |
---|---|---|
committer | Johannes Schickel | 2015-12-12 22:40:20 +0100 |
commit | 693834e8c6e9bf01925dc1731dad44d15f880be9 (patch) | |
tree | c55939c1b761613da099be03ac52e0008b2fd747 | |
parent | f65a8b26898db3bd870010fc3a0b0b71e50e16b7 (diff) | |
download | scummvm-rg350-693834e8c6e9bf01925dc1731dad44d15f880be9.tar.gz scummvm-rg350-693834e8c6e9bf01925dc1731dad44d15f880be9.tar.bz2 scummvm-rg350-693834e8c6e9bf01925dc1731dad44d15f880be9.zip |
OPENGL: Implement black borders using scissor test.
-rw-r--r-- | backends/graphics/opengl/opengl-graphics.cpp | 90 | ||||
-rw-r--r-- | backends/graphics/opengl/opengl-graphics.h | 4 |
2 files changed, 44 insertions, 50 deletions
diff --git a/backends/graphics/opengl/opengl-graphics.cpp b/backends/graphics/opengl/opengl-graphics.cpp index 05e24675fd..df74e110bb 100644 --- a/backends/graphics/opengl/opengl-graphics.cpp +++ b/backends/graphics/opengl/opengl-graphics.cpp @@ -52,7 +52,7 @@ OpenGLGraphicsManager::OpenGLGraphicsManager() _cursorX(0), _cursorY(0), _cursorDisplayX(0),_cursorDisplayY(0), _cursorHotspotX(0), _cursorHotspotY(0), _cursorHotspotXScaled(0), _cursorHotspotYScaled(0), _cursorWidthScaled(0), _cursorHeightScaled(0), _cursorKeyColor(0), _cursorVisible(false), _cursorDontScale(false), _cursorPaletteEnabled(false), - _forceRedraw(false) + _forceRedraw(false), _scissorOverride(3) #ifdef USE_OSD , _osdAlpha(0), _osdFadeStartTime(0), _osd(nullptr) #endif @@ -366,7 +366,19 @@ void OpenGLGraphicsManager::updateScreen() { _forceRedraw = false; // Clear the screen buffer. - GLCALL(glClear(GL_COLOR_BUFFER_BIT)); + if (_scissorOverride) { + // In certain cases we need to assure that the whole screen area is + // cleared. For example, when switching from overlay visible to + // invisible, we need to assure that all contents are cleared to + // properly remove all overlay contents. + GLCALL(glDisable(GL_SCISSOR_TEST)); + GLCALL(glClear(GL_COLOR_BUFFER_BIT)); + GLCALL(glEnable(GL_SCISSOR_TEST)); + + --_scissorOverride; + } else { + GLCALL(glClear(GL_COLOR_BUFFER_BIT)); + } const GLfloat shakeOffset = _gameScreenShakeOffset * (GLfloat)_displayHeight / _gameScreen->getHeight(); @@ -389,37 +401,8 @@ void OpenGLGraphicsManager::updateScreen() { _cursorWidthScaled, _cursorHeightScaled); } - // Fourth step: Draw black borders around the game screen when no overlay - // is visible. This makes sure that the mouse cursor etc. is only drawn - // in the actual game screen area in this case. - if (!_overlayVisible) { - GLCALL(glColor4f(0.0f, 0.0f, 0.0f, 1.0f)); - - GLCALL(glDisable(GL_TEXTURE_2D)); - GLCALL(glDisableClientState(GL_TEXTURE_COORD_ARRAY)); - - // Top border. - drawRect(0, 0, _outputScreenWidth, _displayY); - - // Left border. - drawRect(0, 0, _displayX, _outputScreenHeight); - - // Bottom border. - const int y = _displayY + _displayHeight; - drawRect(0, y, _outputScreenWidth, _outputScreenHeight - y); - - // Right border. - const int x = _displayX + _displayWidth; - drawRect(x, 0, _outputScreenWidth - x, _outputScreenHeight); - - GLCALL(glEnableClientState(GL_TEXTURE_COORD_ARRAY)); - GLCALL(glEnable(GL_TEXTURE_2D)); - - GLCALL(glColor4f(1.0f, 1.0f, 1.0f, 1.0f)); - } - #ifdef USE_OSD - // Fifth step: Draw the OSD. + // Fourth step: Draw the OSD. if (_osdAlpha > 0) { Common::StackLock lock(_osdMutex); @@ -483,6 +466,9 @@ void OpenGLGraphicsManager::showOverlay() { _overlayVisible = true; _forceRedraw = true; + // Allow drawing inside full screen area. + GLCALL(glDisable(GL_SCISSOR_TEST)); + // Update cursor position. setMousePosition(_cursorX, _cursorY); } @@ -491,6 +477,10 @@ void OpenGLGraphicsManager::hideOverlay() { _overlayVisible = false; _forceRedraw = true; + // Limit drawing to screen area. + GLCALL(glEnable(GL_SCISSOR_TEST)); + _scissorOverride = 3; + // Update cursor position. setMousePosition(_cursorX, _cursorY); } @@ -875,6 +865,16 @@ void OpenGLGraphicsManager::notifyContextCreate(const Graphics::PixelFormat &def GLCALL(glEnable(GL_TEXTURE_2D)); + // Setup scissor state accordingly. + if (_overlayVisible) { + GLCALL(glDisable(GL_SCISSOR_TEST)); + } else { + GLCALL(glEnable(GL_SCISSOR_TEST)); + } + // Clear the whole screen for the first three frames to assure any + // leftovers are cleared. + _scissorOverride = 3; + // We use a "pack" alignment (when reading from textures) to 4 here, // since the only place where we really use it is the BMP screenshot // code and that requires the same alignment too. @@ -1126,6 +1126,16 @@ void OpenGLGraphicsManager::recalculateDisplayArea() { _displayX = (_outputScreenWidth - _displayWidth ) / 2; _displayY = (_outputScreenHeight - _displayHeight) / 2; + // Setup drawing limitation for game graphics. + // This invovles some trickery because OpenGL's viewport coordinate system + // is upside down compared to ours. + GLCALL(glScissor(_displayX, + _outputScreenHeight - _displayHeight - _displayY, + _displayWidth, + _displayHeight)); + // Clear the whole screen for the first three frames to remove leftovers. + _scissorOverride = 3; + // Update the cursor position to adjust for new display area. setMousePosition(_cursorX, _cursorY); @@ -1248,20 +1258,4 @@ void OpenGLGraphicsManager::saveScreenshot(const Common::String &filename) const delete[] pixels; } -void OpenGLGraphicsManager::drawRect(GLfloat x, GLfloat y, GLfloat w, GLfloat h) { - if (w < 0 || h < 0) { - return; - } - - const GLfloat vertices[4*2] = { - x, y, - x + w, y, - x, y + h, - x + w, y + h - }; - GLCALL(glVertexPointer(2, GL_FLOAT, 0, vertices)); - - GLCALL(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4)); -} - } // End of namespace OpenGL diff --git a/backends/graphics/opengl/opengl-graphics.h b/backends/graphics/opengl/opengl-graphics.h index e88c3ae243..9578839383 100644 --- a/backends/graphics/opengl/opengl-graphics.h +++ b/backends/graphics/opengl/opengl-graphics.h @@ -479,9 +479,9 @@ private: bool _forceRedraw; /** - * Draws a rectangle + * Number of frames glClear shall ignore scissor testing. */ - void drawRect(GLfloat x, GLfloat y, GLfloat w, GLfloat h); + uint _scissorOverride; #ifdef USE_OSD // |