aboutsummaryrefslogtreecommitdiff
path: root/backends/graphics/opengl
diff options
context:
space:
mode:
authorJohannes Schickel2015-12-11 21:22:42 +0100
committerJohannes Schickel2015-12-12 22:40:20 +0100
commit693834e8c6e9bf01925dc1731dad44d15f880be9 (patch)
treec55939c1b761613da099be03ac52e0008b2fd747 /backends/graphics/opengl
parentf65a8b26898db3bd870010fc3a0b0b71e50e16b7 (diff)
downloadscummvm-rg350-693834e8c6e9bf01925dc1731dad44d15f880be9.tar.gz
scummvm-rg350-693834e8c6e9bf01925dc1731dad44d15f880be9.tar.bz2
scummvm-rg350-693834e8c6e9bf01925dc1731dad44d15f880be9.zip
OPENGL: Implement black borders using scissor test.
Diffstat (limited to 'backends/graphics/opengl')
-rw-r--r--backends/graphics/opengl/opengl-graphics.cpp90
-rw-r--r--backends/graphics/opengl/opengl-graphics.h4
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
//