OPENGL: Commenting.

svn-id: r51338
This commit is contained in:
Alejandro Marzini 2010-07-27 00:30:37 +00:00
parent 141e101841
commit f7220cfea7
3 changed files with 52 additions and 17 deletions

View file

@ -97,6 +97,9 @@ GLTexture::~GLTexture() {
} }
void GLTexture::refresh() { void GLTexture::refresh() {
// Delete previous texture
glDeleteTextures(1, &_textureName); CHECK_GL_ERROR();
// Generate the texture ID // Generate the texture ID
glGenTextures(1, &_textureName); CHECK_GL_ERROR(); glGenTextures(1, &_textureName); CHECK_GL_ERROR();
_refresh = true; _refresh = true;

View file

@ -355,6 +355,7 @@ void OpenGLGraphicsManager::copyRectToScreen(const byte *buf, int pitch, int x,
dst += _screenData.pitch; dst += _screenData.pitch;
} }
// Extend dirty area if not full screen redraw is flagged
if (!_screenNeedsRedraw) { if (!_screenNeedsRedraw) {
const Common::Rect dirtyRect(x, y, x + w, y + h); const Common::Rect dirtyRect(x, y, x + w, y + h);
_screenDirtyRect.extend(dirtyRect); _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) { if (!_overlayNeedsRedraw) {
const Common::Rect dirtyRect(x, y, x + w, y + h); const Common::Rect dirtyRect(x, y, x + w, y + h);
_overlayDirtyRect.extend(dirtyRect); _overlayDirtyRect.extend(dirtyRect);
@ -797,21 +799,27 @@ void OpenGLGraphicsManager::refreshCursor() {
} }
void OpenGLGraphicsManager::refreshCursorScale() { 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 scaleFactor = MIN((float)_videoMode.hardwareWidth / _videoMode.screenWidth,
(float)_videoMode.hardwareHeight / _videoMode.screenHeight); (float)_videoMode.hardwareHeight / _videoMode.screenHeight);
if (_cursorTargetScale >= scaleFactor && _videoMode.scaleFactor >= scaleFactor) { 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.rW = _cursorState.w;
_cursorState.rH = _cursorState.h; _cursorState.rH = _cursorState.h;
_cursorState.rHotX = _cursorState.hotX; _cursorState.rHotX = _cursorState.hotX;
_cursorState.rHotY = _cursorState.hotY; _cursorState.rHotY = _cursorState.hotY;
} else { } else {
// Otherwise, scale the cursor for the overlay
_cursorState.rW = _cursorState.w * scaleFactor; _cursorState.rW = _cursorState.w * scaleFactor;
_cursorState.rH = _cursorState.h * scaleFactor; _cursorState.rH = _cursorState.h * scaleFactor;
_cursorState.rHotX = _cursorState.hotX * scaleFactor; _cursorState.rHotX = _cursorState.hotX * scaleFactor;
_cursorState.rHotY = _cursorState.hotY * scaleFactor; _cursorState.rHotY = _cursorState.hotY * scaleFactor;
} }
// Always scale the cursor for the game
_cursorState.vW = _cursorState.w * scaleFactor; _cursorState.vW = _cursorState.w * scaleFactor;
_cursorState.vH = _cursorState.h * scaleFactor; _cursorState.vH = _cursorState.h * scaleFactor;
_cursorState.vHotX = _cursorState.hotX * scaleFactor; _cursorState.vHotX = _cursorState.hotX * scaleFactor;
@ -846,36 +854,36 @@ void OpenGLGraphicsManager::getGLPixelFormat(Graphics::PixelFormat pixelFormat,
glFormat = GL_RGB; glFormat = GL_RGB;
gltype = GL_UNSIGNED_BYTE; gltype = GL_UNSIGNED_BYTE;
} else { } else {
error("Pixel format not supported"); error("OpenGLGraphicsManager: Pixel format not supported");
} }
} }
void OpenGLGraphicsManager::internUpdateScreen() { void OpenGLGraphicsManager::internUpdateScreen() {
// Clear the screen // Clear the screen buffer
glClear(GL_COLOR_BUFFER_BIT); CHECK_GL_ERROR(); glClear(GL_COLOR_BUFFER_BIT); CHECK_GL_ERROR();
// Draw the game screen
if (_screenNeedsRedraw || !_screenDirtyRect.isEmpty()) if (_screenNeedsRedraw || !_screenDirtyRect.isEmpty())
// Refresh texture if dirty // Refresh texture if dirty
refreshGameScreen(); refreshGameScreen();
// Draw the game screen
_gameTexture->drawTexture(0, 0, _videoMode.hardwareWidth, _videoMode.hardwareHeight); _gameTexture->drawTexture(0, 0, _videoMode.hardwareWidth, _videoMode.hardwareHeight);
// Draw the overlay
if (_overlayVisible) { if (_overlayVisible) {
// Refresh texture if dirty
if (_overlayNeedsRedraw || !_overlayDirtyRect.isEmpty()) if (_overlayNeedsRedraw || !_overlayDirtyRect.isEmpty())
// Refresh texture if dirty
refreshOverlay(); refreshOverlay();
// Draw the overlay
_overlayTexture->drawTexture(0, 0, _videoMode.hardwareWidth, _videoMode.hardwareHeight); _overlayTexture->drawTexture(0, 0, _videoMode.hardwareWidth, _videoMode.hardwareHeight);
} }
// Draw the cursor
if (_cursorVisible) { if (_cursorVisible) {
// Refresh texture if dirty
if (_cursorNeedsRedraw) if (_cursorNeedsRedraw)
// Refresh texture if dirty
refreshCursor(); refreshCursor();
// Draw the cursor
if (_overlayVisible) if (_overlayVisible)
_cursorTexture->drawTexture(_cursorState.x - _cursorState.rHotX, _cursorTexture->drawTexture(_cursorState.x - _cursorState.rHotX,
_cursorState.y - _cursorState.rHotY, _cursorState.rW, _cursorState.rH); _cursorState.y - _cursorState.rHotY, _cursorState.rW, _cursorState.rH);
@ -886,7 +894,7 @@ void OpenGLGraphicsManager::internUpdateScreen() {
#ifdef USE_OSD #ifdef USE_OSD
if (_osdAlpha > 0) { if (_osdAlpha > 0) {
// Updated alpha value // Update alpha value
const int diff = g_system->getMillis() - _osdFadeStartTime; const int diff = g_system->getMillis() - _osdFadeStartTime;
if (diff > 0) { if (diff > 0) {
if (diff >= kOSDFadeOutDuration) { if (diff >= kOSDFadeOutDuration) {
@ -898,13 +906,13 @@ void OpenGLGraphicsManager::internUpdateScreen() {
} }
} }
// Set the osd transparency // 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 // Draw the osd texture
_osdTexture->drawTexture(0, 0, _videoMode.hardwareWidth, _videoMode.hardwareHeight); _osdTexture->drawTexture(0, 0, _videoMode.hardwareWidth, _videoMode.hardwareHeight);
// Reset color // Reset color
glColor4f(1.0f, 1.0f, 1.0f, 1.0f); glColor4f(1.0f, 1.0f, 1.0f, 1.0f); CHECK_GL_ERROR();
} }
#endif #endif
} }
@ -980,11 +988,14 @@ void OpenGLGraphicsManager::loadTextures() {
_cursorTexture->setFilter(filter); _cursorTexture->setFilter(filter);
if (_transactionDetails.newContext || _transactionDetails.filterChanged) { 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(); _gameTexture->refresh();
_overlayTexture->refresh(); _overlayTexture->refresh();
_cursorTexture->refresh(); _cursorTexture->refresh();
} }
// Allocate texture memory and finish refreshing
_gameTexture->allocBuffer(_videoMode.screenWidth, _videoMode.screenHeight); _gameTexture->allocBuffer(_videoMode.screenWidth, _videoMode.screenHeight);
_overlayTexture->allocBuffer(_videoMode.overlayWidth, _videoMode.overlayHeight); _overlayTexture->allocBuffer(_videoMode.overlayWidth, _videoMode.overlayHeight);
_cursorTexture->allocBuffer(_cursorState.w, _cursorState.h); _cursorTexture->allocBuffer(_cursorState.w, _cursorState.h);
@ -1113,10 +1124,11 @@ bool OpenGLGraphicsManager::saveScreenshot(const char *filename) {
uint8 *pixels = new uint8[width * height * 3]; uint8 *pixels = new uint8[width * height * 3];
// Get pixel data from opengl buffer // Get pixel data from opengl buffer
if (_formatBGR) if (_formatBGR) {
glReadPixels(0, 0, width, height, GL_BGR, GL_UNSIGNED_BYTE, pixels); glReadPixels(0, 0, width, height, GL_BGR, GL_UNSIGNED_BYTE, pixels); CHECK_GL_ERROR();
else } else {
glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, pixels); glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, pixels); CHECK_GL_ERROR();
}
// Open file // Open file
Common::DumpFile out; Common::DumpFile out;

View file

@ -118,7 +118,7 @@ Common::List<Graphics::PixelFormat> OpenGLSdlGraphicsManager::getSupportedFormat
if (RGBList[i] != format) if (RGBList[i] != format)
list.push_back(RGBList[i]); list.push_back(RGBList[i]);
} }
//list.push_back(Graphics::PixelFormat::createFormatCLUT8()); list.push_back(Graphics::PixelFormat::createFormatCLUT8());
return list; return list;
} }
@ -148,6 +148,8 @@ void OpenGLSdlGraphicsManager::warpMouse(int x, int y) {
bool OpenGLSdlGraphicsManager::loadGFXMode() { bool OpenGLSdlGraphicsManager::loadGFXMode() {
_videoMode.overlayWidth = _videoMode.screenWidth * _videoMode.scaleFactor; _videoMode.overlayWidth = _videoMode.screenWidth * _videoMode.scaleFactor;
_videoMode.overlayHeight = _videoMode.screenHeight * _videoMode.scaleFactor; _videoMode.overlayHeight = _videoMode.screenHeight * _videoMode.scaleFactor;
// If the screen was resized, do not change its size
if (!_screenResized) { if (!_screenResized) {
_videoMode.hardwareWidth = _videoMode.overlayWidth; _videoMode.hardwareWidth = _videoMode.overlayWidth;
_videoMode.hardwareHeight = _videoMode.overlayHeight; _videoMode.hardwareHeight = _videoMode.overlayHeight;
@ -161,10 +163,13 @@ bool OpenGLSdlGraphicsManager::loadGFXMode() {
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
// Find the best mode for fullscreen
if (_videoMode.fullscreen) { if (_videoMode.fullscreen) {
SDL_Rect const* const*availableModes = SDL_ListModes(NULL, SDL_FULLSCREEN | SDL_OPENGL); SDL_Rect const* const*availableModes = SDL_ListModes(NULL, SDL_FULLSCREEN | SDL_OPENGL);
const SDL_Rect *bestMode = NULL; const SDL_Rect *bestMode = NULL;
uint bestMetric = (uint)-1; uint bestMetric = (uint)-1;
// Iterate over all available fullscreen modes
while (const SDL_Rect *mode = *availableModes++) { while (const SDL_Rect *mode = *availableModes++) {
if (mode->w < _videoMode.hardwareWidth) if (mode->w < _videoMode.hardwareWidth)
continue; continue;
@ -180,18 +185,24 @@ bool OpenGLSdlGraphicsManager::loadGFXMode() {
} }
if (bestMode) { if (bestMode) {
// If there is a suiting mode, use it
_videoMode.hardwareWidth = bestMode->w; _videoMode.hardwareWidth = bestMode->w;
_videoMode.hardwareHeight = bestMode->h; _videoMode.hardwareHeight = bestMode->h;
} else { } else {
// If the last mode was in fullscreen, cancel GFX load
if (_oldVideoMode.fullscreen) if (_oldVideoMode.fullscreen)
return false; return false;
_videoMode.fullscreen = false; _videoMode.fullscreen = false;
} }
} }
// If changing to any fullscreen mode or from fullscreen,
// the OpenGL context is destroyed
if (_oldVideoMode.fullscreen || _videoMode.fullscreen) if (_oldVideoMode.fullscreen || _videoMode.fullscreen)
_transactionDetails.newContext = true; _transactionDetails.newContext = true;
// Create our window
_hwscreen = SDL_SetVideoMode(_videoMode.hardwareWidth, _videoMode.hardwareHeight, 32, _hwscreen = SDL_SetVideoMode(_videoMode.hardwareWidth, _videoMode.hardwareHeight, 32,
_videoMode.fullscreen ? (SDL_FULLSCREEN | SDL_OPENGL) : (SDL_OPENGL | SDL_RESIZABLE) _videoMode.fullscreen ? (SDL_FULLSCREEN | SDL_OPENGL) : (SDL_OPENGL | SDL_RESIZABLE)
); );
@ -202,13 +213,15 @@ bool OpenGLSdlGraphicsManager::loadGFXMode() {
if (!_oldVideoMode.setup) { if (!_oldVideoMode.setup) {
warning("SDL_SetVideoMode says we can't switch to that mode (%s)", SDL_GetError()); warning("SDL_SetVideoMode says we can't switch to that mode (%s)", SDL_GetError());
g_system->quit(); g_system->quit();
} else { } else
// Cancel GFX load, and go back to last mode
return false; return false;
}
} }
// Check if the screen is BGR format
_formatBGR = _hwscreen->format->Rshift != 0; _formatBGR = _hwscreen->format->Rshift != 0;
// Call and return parent implementation of this method
return OpenGLGraphicsManager::loadGFXMode(); return OpenGLGraphicsManager::loadGFXMode();
} }
@ -220,8 +233,10 @@ void OpenGLSdlGraphicsManager::unloadGFXMode() {
} }
void OpenGLSdlGraphicsManager::internUpdateScreen() { void OpenGLSdlGraphicsManager::internUpdateScreen() {
// Call to parent implementation of this method
OpenGLGraphicsManager::internUpdateScreen(); OpenGLGraphicsManager::internUpdateScreen();
// Swap OpenGL buffers
SDL_GL_SwapBuffers(); SDL_GL_SwapBuffers();
} }
@ -377,10 +392,15 @@ bool OpenGLSdlGraphicsManager::notifyEvent(const Common::Event &event) {
// HACK: Handle special SDL event // HACK: Handle special SDL event
case OSystem_SDL::kSdlEventResize: case OSystem_SDL::kSdlEventResize:
beginGFXTransaction(); 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.hardwareWidth = event.mouse.x;
_videoMode.hardwareHeight = event.mouse.y; _videoMode.hardwareHeight = event.mouse.y;
_screenResized = true; _screenResized = true;
_transactionDetails.sizeChanged = 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; _transactionDetails.newContext = true;
endGFXTransaction(); endGFXTransaction();
return true; return true;