OPENGL: Commenting.
svn-id: r51338
This commit is contained in:
parent
141e101841
commit
f7220cfea7
3 changed files with 52 additions and 17 deletions
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue