diff options
-rw-r--r-- | backends/graphics/opengl/gltexture.cpp | 3 | ||||
-rw-r--r-- | backends/graphics/opengl/opengl-graphics.cpp | 40 | ||||
-rw-r--r-- | backends/graphics/openglsdl/openglsdl-graphics.cpp | 26 |
3 files changed, 52 insertions, 17 deletions
diff --git a/backends/graphics/opengl/gltexture.cpp b/backends/graphics/opengl/gltexture.cpp index 679538585f..708788eeae 100644 --- a/backends/graphics/opengl/gltexture.cpp +++ b/backends/graphics/opengl/gltexture.cpp @@ -97,6 +97,9 @@ GLTexture::~GLTexture() { } void GLTexture::refresh() { + // Delete previous texture + glDeleteTextures(1, &_textureName); CHECK_GL_ERROR(); + // Generate the texture ID glGenTextures(1, &_textureName); CHECK_GL_ERROR(); _refresh = true; diff --git a/backends/graphics/opengl/opengl-graphics.cpp b/backends/graphics/opengl/opengl-graphics.cpp index 58ca7f09ce..a115878e53 100644 --- a/backends/graphics/opengl/opengl-graphics.cpp +++ b/backends/graphics/opengl/opengl-graphics.cpp @@ -355,6 +355,7 @@ void OpenGLGraphicsManager::copyRectToScreen(const byte *buf, int pitch, int x, dst += _screenData.pitch; } + // Extend dirty area if not full screen redraw is flagged if (!_screenNeedsRedraw) { const Common::Rect dirtyRect(x, y, x + w, y + h); _screenDirtyRect.extend(dirtyRect); @@ -514,6 +515,7 @@ void OpenGLGraphicsManager::copyRectToOverlay(const OverlayColor *buf, int pitch } } + // Extend dirty area if not full screen redraw is flagged if (!_overlayNeedsRedraw) { const Common::Rect dirtyRect(x, y, x + w, y + h); _overlayDirtyRect.extend(dirtyRect); @@ -797,21 +799,27 @@ void OpenGLGraphicsManager::refreshCursor() { } void OpenGLGraphicsManager::refreshCursorScale() { + // Get the window minimum scale factor. The cursor will mantain its original aspect + // ratio, and we do not want it to get too big if only one dimension is resized float scaleFactor = MIN((float)_videoMode.hardwareWidth / _videoMode.screenWidth, (float)_videoMode.hardwareHeight / _videoMode.screenHeight); if (_cursorTargetScale >= scaleFactor && _videoMode.scaleFactor >= scaleFactor) { + // If the cursor target scale and the video mode scale factor are bigger than + // the current window scale, do not scale the cursor for the overlay _cursorState.rW = _cursorState.w; _cursorState.rH = _cursorState.h; _cursorState.rHotX = _cursorState.hotX; _cursorState.rHotY = _cursorState.hotY; } else { + // Otherwise, scale the cursor for the overlay _cursorState.rW = _cursorState.w * scaleFactor; _cursorState.rH = _cursorState.h * scaleFactor; _cursorState.rHotX = _cursorState.hotX * scaleFactor; _cursorState.rHotY = _cursorState.hotY * scaleFactor; } + // Always scale the cursor for the game _cursorState.vW = _cursorState.w * scaleFactor; _cursorState.vH = _cursorState.h * scaleFactor; _cursorState.vHotX = _cursorState.hotX * scaleFactor; @@ -846,36 +854,36 @@ void OpenGLGraphicsManager::getGLPixelFormat(Graphics::PixelFormat pixelFormat, glFormat = GL_RGB; gltype = GL_UNSIGNED_BYTE; } else { - error("Pixel format not supported"); + error("OpenGLGraphicsManager: Pixel format not supported"); } } void OpenGLGraphicsManager::internUpdateScreen() { - // Clear the screen + // Clear the screen buffer glClear(GL_COLOR_BUFFER_BIT); CHECK_GL_ERROR(); - // Draw the game screen if (_screenNeedsRedraw || !_screenDirtyRect.isEmpty()) // Refresh texture if dirty refreshGameScreen(); + // Draw the game screen _gameTexture->drawTexture(0, 0, _videoMode.hardwareWidth, _videoMode.hardwareHeight); - // Draw the overlay if (_overlayVisible) { - // Refresh texture if dirty if (_overlayNeedsRedraw || !_overlayDirtyRect.isEmpty()) + // Refresh texture if dirty refreshOverlay(); + // Draw the overlay _overlayTexture->drawTexture(0, 0, _videoMode.hardwareWidth, _videoMode.hardwareHeight); } - // Draw the cursor if (_cursorVisible) { - // Refresh texture if dirty if (_cursorNeedsRedraw) + // Refresh texture if dirty refreshCursor(); + // Draw the cursor if (_overlayVisible) _cursorTexture->drawTexture(_cursorState.x - _cursorState.rHotX, _cursorState.y - _cursorState.rHotY, _cursorState.rW, _cursorState.rH); @@ -886,7 +894,7 @@ void OpenGLGraphicsManager::internUpdateScreen() { #ifdef USE_OSD if (_osdAlpha > 0) { - // Updated alpha value + // Update alpha value const int diff = g_system->getMillis() - _osdFadeStartTime; if (diff > 0) { if (diff >= kOSDFadeOutDuration) { @@ -898,13 +906,13 @@ void OpenGLGraphicsManager::internUpdateScreen() { } } // Set the osd transparency - glColor4f(1.0f, 1.0f, 1.0f, _osdAlpha / 100.0f); + glColor4f(1.0f, 1.0f, 1.0f, _osdAlpha / 100.0f); CHECK_GL_ERROR(); // Draw the osd texture _osdTexture->drawTexture(0, 0, _videoMode.hardwareWidth, _videoMode.hardwareHeight); // Reset color - glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); CHECK_GL_ERROR(); } #endif } @@ -980,11 +988,14 @@ void OpenGLGraphicsManager::loadTextures() { _cursorTexture->setFilter(filter); if (_transactionDetails.newContext || _transactionDetails.filterChanged) { + // If the context was destroyed or it is needed to change the texture filter + // we need to recreate the textures _gameTexture->refresh(); _overlayTexture->refresh(); _cursorTexture->refresh(); } + // Allocate texture memory and finish refreshing _gameTexture->allocBuffer(_videoMode.screenWidth, _videoMode.screenHeight); _overlayTexture->allocBuffer(_videoMode.overlayWidth, _videoMode.overlayHeight); _cursorTexture->allocBuffer(_cursorState.w, _cursorState.h); @@ -1113,10 +1124,11 @@ bool OpenGLGraphicsManager::saveScreenshot(const char *filename) { uint8 *pixels = new uint8[width * height * 3]; // Get pixel data from opengl buffer - if (_formatBGR) - glReadPixels(0, 0, width, height, GL_BGR, GL_UNSIGNED_BYTE, pixels); - else - glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, pixels); + if (_formatBGR) { + glReadPixels(0, 0, width, height, GL_BGR, GL_UNSIGNED_BYTE, pixels); CHECK_GL_ERROR(); + } else { + glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, pixels); CHECK_GL_ERROR(); + } // Open file Common::DumpFile out; diff --git a/backends/graphics/openglsdl/openglsdl-graphics.cpp b/backends/graphics/openglsdl/openglsdl-graphics.cpp index 880a38dbc2..ea01727238 100644 --- a/backends/graphics/openglsdl/openglsdl-graphics.cpp +++ b/backends/graphics/openglsdl/openglsdl-graphics.cpp @@ -118,7 +118,7 @@ Common::List<Graphics::PixelFormat> OpenGLSdlGraphicsManager::getSupportedFormat if (RGBList[i] != format) list.push_back(RGBList[i]); } - //list.push_back(Graphics::PixelFormat::createFormatCLUT8()); + list.push_back(Graphics::PixelFormat::createFormatCLUT8()); return list; } @@ -148,6 +148,8 @@ void OpenGLSdlGraphicsManager::warpMouse(int x, int y) { bool OpenGLSdlGraphicsManager::loadGFXMode() { _videoMode.overlayWidth = _videoMode.screenWidth * _videoMode.scaleFactor; _videoMode.overlayHeight = _videoMode.screenHeight * _videoMode.scaleFactor; + + // If the screen was resized, do not change its size if (!_screenResized) { _videoMode.hardwareWidth = _videoMode.overlayWidth; _videoMode.hardwareHeight = _videoMode.overlayHeight; @@ -161,10 +163,13 @@ bool OpenGLSdlGraphicsManager::loadGFXMode() { SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); + // Find the best mode for fullscreen if (_videoMode.fullscreen) { SDL_Rect const* const*availableModes = SDL_ListModes(NULL, SDL_FULLSCREEN | SDL_OPENGL); const SDL_Rect *bestMode = NULL; uint bestMetric = (uint)-1; + + // Iterate over all available fullscreen modes while (const SDL_Rect *mode = *availableModes++) { if (mode->w < _videoMode.hardwareWidth) continue; @@ -180,18 +185,24 @@ bool OpenGLSdlGraphicsManager::loadGFXMode() { } if (bestMode) { + // If there is a suiting mode, use it _videoMode.hardwareWidth = bestMode->w; _videoMode.hardwareHeight = bestMode->h; } else { + // If the last mode was in fullscreen, cancel GFX load if (_oldVideoMode.fullscreen) return false; + _videoMode.fullscreen = false; } } + // If changing to any fullscreen mode or from fullscreen, + // the OpenGL context is destroyed if (_oldVideoMode.fullscreen || _videoMode.fullscreen) _transactionDetails.newContext = true; + // Create our window _hwscreen = SDL_SetVideoMode(_videoMode.hardwareWidth, _videoMode.hardwareHeight, 32, _videoMode.fullscreen ? (SDL_FULLSCREEN | SDL_OPENGL) : (SDL_OPENGL | SDL_RESIZABLE) ); @@ -202,13 +213,15 @@ bool OpenGLSdlGraphicsManager::loadGFXMode() { if (!_oldVideoMode.setup) { warning("SDL_SetVideoMode says we can't switch to that mode (%s)", SDL_GetError()); g_system->quit(); - } else { + } else + // Cancel GFX load, and go back to last mode return false; - } } + // Check if the screen is BGR format _formatBGR = _hwscreen->format->Rshift != 0; + // Call and return parent implementation of this method return OpenGLGraphicsManager::loadGFXMode(); } @@ -220,8 +233,10 @@ void OpenGLSdlGraphicsManager::unloadGFXMode() { } void OpenGLSdlGraphicsManager::internUpdateScreen() { + // Call to parent implementation of this method OpenGLGraphicsManager::internUpdateScreen(); + // Swap OpenGL buffers SDL_GL_SwapBuffers(); } @@ -377,10 +392,15 @@ bool OpenGLSdlGraphicsManager::notifyEvent(const Common::Event &event) { // HACK: Handle special SDL event case OSystem_SDL::kSdlEventResize: beginGFXTransaction(); + // Set the new screen size. It is saved on the mouse event as part of HACK, + // there is no common resize event _videoMode.hardwareWidth = event.mouse.x; _videoMode.hardwareHeight = event.mouse.y; _screenResized = true; _transactionDetails.sizeChanged = true; + // The OpenGL context is not always destroyed during resizing, + // however it is better to waste some time recreating it than + // getting a blank screen _transactionDetails.newContext = true; endGFXTransaction(); return true; |