OPENGL: Limit mouse cursor drawing to inside game screen when no overlay is visible.

This commit is contained in:
Johannes Schickel 2015-01-07 20:02:10 +01:00
parent 4c64f7e194
commit f879f8af04
2 changed files with 90 additions and 7 deletions

View file

@ -49,9 +49,9 @@ OpenGLGraphicsManager::OpenGLGraphicsManager()
_displayWidth(0), _displayHeight(0), _defaultFormat(), _defaultFormatAlpha(), _displayWidth(0), _displayHeight(0), _defaultFormat(), _defaultFormatAlpha(),
_gameScreen(nullptr), _gameScreenShakeOffset(0), _overlay(nullptr), _gameScreen(nullptr), _gameScreenShakeOffset(0), _overlay(nullptr),
_overlayVisible(false), _cursor(nullptr), _overlayVisible(false), _cursor(nullptr),
_cursorX(0), _cursorY(0), _cursorHotspotX(0), _cursorHotspotY(0), _cursorHotspotXScaled(0), _cursorX(0), _cursorY(0), _cursorDisplayX(0),_cursorDisplayY(0), _cursorHotspotX(0), _cursorHotspotY(0),
_cursorHotspotYScaled(0), _cursorWidthScaled(0), _cursorHeightScaled(0), _cursorKeyColor(0), _cursorHotspotXScaled(0), _cursorHotspotYScaled(0), _cursorWidthScaled(0), _cursorHeightScaled(0),
_cursorVisible(false), _cursorDontScale(false), _cursorPaletteEnabled(false) _cursorKeyColor(0), _cursorVisible(false), _cursorDontScale(false), _cursorPaletteEnabled(false)
#ifdef USE_OSD #ifdef USE_OSD
, _osdAlpha(0), _osdFadeStartTime(0), _osd(nullptr) , _osdAlpha(0), _osdFadeStartTime(0), _osd(nullptr)
#endif #endif
@ -351,7 +351,7 @@ void OpenGLGraphicsManager::updateScreen() {
return; return;
} }
// Clear the screen buffer // Clear the screen buffer.
GLCALL(glClear(GL_COLOR_BUFFER_BIT)); GLCALL(glClear(GL_COLOR_BUFFER_BIT));
const GLfloat shakeOffset = _gameScreenShakeOffset * (GLfloat)_displayHeight / _gameScreen->getHeight(); const GLfloat shakeOffset = _gameScreenShakeOffset * (GLfloat)_displayHeight / _gameScreen->getHeight();
@ -370,12 +370,42 @@ void OpenGLGraphicsManager::updateScreen() {
// visible. // visible.
const GLfloat cursorOffset = _overlayVisible ? 0 : shakeOffset; const GLfloat cursorOffset = _overlayVisible ? 0 : shakeOffset;
_cursor->draw(_cursorX - _cursorHotspotXScaled, _cursorY - _cursorHotspotYScaled + cursorOffset, _cursor->draw(_cursorDisplayX - _cursorHotspotXScaled,
_cursorDisplayY - _cursorHotspotYScaled + cursorOffset,
_cursorWidthScaled, _cursorHeightScaled); _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 #ifdef USE_OSD
// Fourth step: Draw the OSD. // Fifth step: Draw the OSD.
if (_osdAlpha > 0) { if (_osdAlpha > 0) {
Common::StackLock lock(_osdMutex); Common::StackLock lock(_osdMutex);
@ -435,10 +465,16 @@ int16 OpenGLGraphicsManager::getOverlayHeight() {
void OpenGLGraphicsManager::showOverlay() { void OpenGLGraphicsManager::showOverlay() {
_overlayVisible = true; _overlayVisible = true;
// Update cursor position.
setMousePosition(_cursorX, _cursorY);
} }
void OpenGLGraphicsManager::hideOverlay() { void OpenGLGraphicsManager::hideOverlay() {
_overlayVisible = false; _overlayVisible = false;
// Update cursor position.
setMousePosition(_cursorX, _cursorY);
} }
Graphics::PixelFormat OpenGLGraphicsManager::getOverlayFormat() const { Graphics::PixelFormat OpenGLGraphicsManager::getOverlayFormat() const {
@ -901,6 +937,19 @@ void OpenGLGraphicsManager::adjustMousePosition(int16 &x, int16 &y) {
} }
} }
void OpenGLGraphicsManager::setMousePosition(int x, int y) {
_cursorX = x;
_cursorY = y;
if (_overlayVisible) {
_cursorDisplayX = x;
_cursorDisplayY = y;
} else {
_cursorDisplayX = CLIP<int>(x, _displayX, _displayX + _displayWidth - 1);
_cursorDisplayY = CLIP<int>(y, _displayY, _displayY + _displayHeight - 1);
}
}
Texture *OpenGLGraphicsManager::createTexture(const Graphics::PixelFormat &format, bool wantAlpha) { Texture *OpenGLGraphicsManager::createTexture(const Graphics::PixelFormat &format, bool wantAlpha) {
GLenum glIntFormat, glFormat, glType; GLenum glIntFormat, glFormat, glType;
if (format.bytesPerPixel == 1) { if (format.bytesPerPixel == 1) {
@ -1046,6 +1095,9 @@ void OpenGLGraphicsManager::recalculateDisplayArea() {
// We center the screen in the middle for now. // We center the screen in the middle for now.
_displayX = (_outputScreenWidth - _displayWidth ) / 2; _displayX = (_outputScreenWidth - _displayWidth ) / 2;
_displayY = (_outputScreenHeight - _displayHeight) / 2; _displayY = (_outputScreenHeight - _displayHeight) / 2;
// Update the cursor position to adjust for new display area.
setMousePosition(_cursorX, _cursorY);
} }
void OpenGLGraphicsManager::updateCursorPalette() { void OpenGLGraphicsManager::updateCursorPalette() {
@ -1163,4 +1215,20 @@ void OpenGLGraphicsManager::saveScreenshot(const Common::String &filename) const
delete[] pixels; 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 } // End of namespace OpenGL

View file

@ -155,7 +155,7 @@ protected:
* @param x X coordinate in physical coordinates. * @param x X coordinate in physical coordinates.
* @param y Y coordinate in physical coordinates. * @param y Y coordinate in physical coordinates.
*/ */
void setMousePosition(int x, int y) { _cursorX = x; _cursorY = y; } void setMousePosition(int x, int y);
/** /**
* Query the mouse position in physical coordinates. * Query the mouse position in physical coordinates.
@ -393,6 +393,16 @@ private:
*/ */
int _cursorY; int _cursorY;
/**
* X coordinate used for drawing the cursor.
*/
int _cursorDisplayX;
/**
* Y coordinate used for drawing the cursor.
*/
int _cursorDisplayY;
/** /**
* The X offset for the cursor hotspot in unscaled coordinates. * The X offset for the cursor hotspot in unscaled coordinates.
*/ */
@ -454,6 +464,11 @@ private:
*/ */
byte _cursorPalette[3 * 256]; byte _cursorPalette[3 * 256];
/**
* Draws a rectangle
*/
void drawRect(GLfloat x, GLfloat y, GLfloat w, GLfloat h);
#ifdef USE_OSD #ifdef USE_OSD
// //
// OSD // OSD