aboutsummaryrefslogtreecommitdiff
path: root/backends/graphics/opengl
diff options
context:
space:
mode:
authorAlejandro Marzini2010-07-31 22:54:10 +0000
committerAlejandro Marzini2010-07-31 22:54:10 +0000
commit7dbe257da8fcfd0996b21bdfe0d3851e3e2e1927 (patch)
tree00559cacc66487150ad9e124efa0ddbc689fec8d /backends/graphics/opengl
parentc93adcbd298b65fff72d3991d2690379c2ba8a88 (diff)
downloadscummvm-rg350-7dbe257da8fcfd0996b21bdfe0d3851e3e2e1927.tar.gz
scummvm-rg350-7dbe257da8fcfd0996b21bdfe0d3851e3e2e1927.tar.bz2
scummvm-rg350-7dbe257da8fcfd0996b21bdfe0d3851e3e2e1927.zip
OPENGL: Add support for BGR and rgb(a) reversed formats (Not available for GLES). General cleanup and commenting.
svn-id: r51559
Diffstat (limited to 'backends/graphics/opengl')
-rw-r--r--backends/graphics/opengl/gltexture.cpp7
-rw-r--r--backends/graphics/opengl/gltexture.h5
-rw-r--r--backends/graphics/opengl/opengl-graphics.cpp98
-rw-r--r--backends/graphics/opengl/opengl-graphics.h36
4 files changed, 114 insertions, 32 deletions
diff --git a/backends/graphics/opengl/gltexture.cpp b/backends/graphics/opengl/gltexture.cpp
index 79e7cd48f0..e43cbe2266 100644
--- a/backends/graphics/opengl/gltexture.cpp
+++ b/backends/graphics/opengl/gltexture.cpp
@@ -56,7 +56,7 @@ static GLuint nextHigher2(GLuint v) {
void GLTexture::initGLExtensions() {
static bool inited = false;
- // Return if extensions already checked
+ // Return if extensions were already checked
if (inited)
return;
@@ -75,9 +75,10 @@ void GLTexture::initGLExtensions() {
inited = true;
}
-GLTexture::GLTexture(byte bpp, GLenum format, GLenum type)
+GLTexture::GLTexture(byte bpp, GLenum internalFormat, GLenum format, GLenum type)
:
_bytesPerPixel(bpp),
+ _internalFormat(internalFormat),
_glFormat(format),
_glType(type),
_textureWidth(0),
@@ -131,7 +132,7 @@ void GLTexture::allocBuffer(GLuint w, GLuint h) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); CHECK_GL_ERROR();
// Allocate room for the texture
- glTexImage2D(GL_TEXTURE_2D, 0, _glFormat,
+ glTexImage2D(GL_TEXTURE_2D, 0, _internalFormat,
_textureWidth, _textureHeight, 0, _glFormat, _glType, NULL); CHECK_GL_ERROR();
_refresh = false;
diff --git a/backends/graphics/opengl/gltexture.h b/backends/graphics/opengl/gltexture.h
index 73771fda91..9864f6816c 100644
--- a/backends/graphics/opengl/gltexture.h
+++ b/backends/graphics/opengl/gltexture.h
@@ -58,7 +58,7 @@ public:
*/
static void initGLExtensions();
- GLTexture(byte bpp, GLenum format, GLenum type);
+ GLTexture(byte bpp, GLenum internalFormat, GLenum format, GLenum type);
virtual ~GLTexture();
/**
@@ -95,12 +95,13 @@ public:
/**
* Set the texture filter.
- * GL_NEAREST or GL_LINEAR should be passed.
+ * @filter the filter type, GL_NEAREST or GL_LINEAR
*/
void setFilter(GLint filter) { _filter = filter; }
protected:
const byte _bytesPerPixel;
+ const GLenum _internalFormat;
const GLenum _glFormat;
const GLenum _glType;
diff --git a/backends/graphics/opengl/opengl-graphics.cpp b/backends/graphics/opengl/opengl-graphics.cpp
index 3b04be600d..32dd14580e 100644
--- a/backends/graphics/opengl/opengl-graphics.cpp
+++ b/backends/graphics/opengl/opengl-graphics.cpp
@@ -188,7 +188,6 @@ void OpenGLGraphicsManager::initSize(uint width, uint height, const Graphics::Pi
assert(_transactionMode == kTransactionActive);
#ifdef USE_RGB_COLOR
- // Avoid redundant format changes
Graphics::PixelFormat newFormat;
if (!format)
newFormat = Graphics::PixelFormat::createFormatCLUT8();
@@ -197,6 +196,7 @@ void OpenGLGraphicsManager::initSize(uint width, uint height, const Graphics::Pi
assert(newFormat.bytesPerPixel > 0);
+ // Avoid redundant format changes
if (newFormat != _videoMode.format) {
_videoMode.format = newFormat;
_transactionDetails.formatChanged = true;
@@ -283,11 +283,7 @@ OSystem::TransactionError OpenGLGraphicsManager::endGFXTransaction() {
}
}
-#ifdef USE_RGB_COLOR
- if (_transactionDetails.sizeChanged || _transactionDetails.formatChanged || _transactionDetails.needHotswap) {
-#else
if (_transactionDetails.sizeChanged || _transactionDetails.needHotswap) {
-#endif
unloadGFXMode();
if (!loadGFXMode()) {
if (_oldVideoMode.setup) {
@@ -300,7 +296,11 @@ OSystem::TransactionError OpenGLGraphicsManager::endGFXTransaction() {
_videoMode.setup = true;
_screenChangeCount++;
}
+#ifdef USE_RGB_COLOR
+ } else if (_transactionDetails.filterChanged || _transactionDetails.formatChanged) {
+#else
} else if (_transactionDetails.filterChanged) {
+#endif
loadTextures();
internUpdateScreen();
} else if (_transactionDetails.needUpdatescreen) {
@@ -462,6 +462,7 @@ Graphics::PixelFormat OpenGLGraphicsManager::getOverlayFormat() const {
}
void OpenGLGraphicsManager::clearOverlay() {
+ // Set all pixels to 0
memset(_overlayData.pixels, 0, _overlayData.h * _overlayData.pitch);
_overlayNeedsRedraw = true;
}
@@ -470,6 +471,7 @@ void OpenGLGraphicsManager::grabOverlay(OverlayColor *buf, int pitch) {
assert(_overlayData.bytesPerPixel == sizeof(buf[0]));
const byte *src = (byte *)_overlayData.pixels;
for (int i = 0; i < _overlayData.h; i++) {
+ // Copy overlay data to buffer
memcpy(buf, src, _overlayData.pitch);
buf += pitch;
src += _overlayData.pitch;
@@ -565,12 +567,13 @@ void OpenGLGraphicsManager::warpMouse(int x, int y) {
void OpenGLGraphicsManager::setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format) {
#ifdef USE_RGB_COLOR
- if (!format)
- _cursorFormat = Graphics::PixelFormat::createFormatCLUT8();
- else
+ if (format)
_cursorFormat = *format;
+ else
+ _cursorFormat = Graphics::PixelFormat::createFormatCLUT8();
#else
assert(keycolor <= 255);
+ _cursorFormat = Graphics::PixelFormat::createFormatCLUT8();
#endif
// Allocate space for cursor data
@@ -845,42 +848,97 @@ void OpenGLGraphicsManager::refreshAspectRatio() {
float aspectRatio = (float)_videoMode.hardwareWidth / _videoMode.hardwareHeight;
float desiredAspectRatio = getAspectRatio();
+ // Adjust one screen dimension for mantaining the aspect ratio
if (aspectRatio < desiredAspectRatio)
_aspectHeight = (int)(_aspectWidth / desiredAspectRatio + 0.5f);
else if (aspectRatio > desiredAspectRatio)
_aspectWidth = (int)(_aspectHeight * desiredAspectRatio + 0.5f);
+ // Adjust x and y for centering the screen
_aspectX = (_videoMode.hardwareWidth - _aspectWidth) / 2;
_aspectY = (_videoMode.hardwareHeight - _aspectHeight) / 2;
}
-void OpenGLGraphicsManager::getGLPixelFormat(Graphics::PixelFormat pixelFormat, byte &bpp, GLenum &glFormat, GLenum &gltype) {
+void OpenGLGraphicsManager::getGLPixelFormat(Graphics::PixelFormat pixelFormat, byte &bpp, GLenum &intFormat, GLenum &glFormat, GLenum &gltype) {
if (pixelFormat == Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0)) { // RGBA8888
bpp = 4;
+ intFormat = GL_RGBA;
glFormat = GL_RGBA;
gltype = GL_UNSIGNED_BYTE;
} else if (pixelFormat == Graphics::PixelFormat(3, 8, 8, 8, 0, 16, 8, 0, 0)) { // RGB888
bpp = 3;
+ intFormat = GL_RGB;
glFormat = GL_RGB;
gltype = GL_UNSIGNED_BYTE;
} else if (pixelFormat == Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0)) { // RGB565
bpp = 2;
+ intFormat = GL_RGB;
glFormat = GL_RGB;
gltype = GL_UNSIGNED_SHORT_5_6_5;
} else if (pixelFormat == Graphics::PixelFormat(2, 5, 5, 5, 1, 11, 6, 1, 0)) { // RGB5551
bpp = 2;
+ intFormat = GL_RGBA;
glFormat = GL_RGBA;
gltype = GL_UNSIGNED_SHORT_5_5_5_1;
} else if (pixelFormat == Graphics::PixelFormat(2, 4, 4, 4, 4, 12, 8, 4, 0)) { // RGBA4444
bpp = 2;
+ intFormat = GL_RGBA;
glFormat = GL_RGBA;
gltype = GL_UNSIGNED_SHORT_4_4_4_4;
} else if (pixelFormat.bytesPerPixel == 1) { // CLUT8
// If uses a palette, create texture as RGB888. The pixel data will be converted
// later.
bpp = 3;
+ intFormat = GL_RGB;
glFormat = GL_RGB;
gltype = GL_UNSIGNED_BYTE;
+#ifndef USE_GLES
+ } else if (pixelFormat == Graphics::PixelFormat(4, 8, 8, 8, 8, 16, 8, 0, 24)) { // ARGB8888
+ bpp = 4;
+ intFormat = GL_RGBA;
+ glFormat = GL_BGRA;
+ gltype = GL_UNSIGNED_INT_8_8_8_8_REV;
+ } else if (pixelFormat == Graphics::PixelFormat(2, 4, 4, 4, 4, 8, 4, 0, 12)) { // ARGB4444
+ bpp = 2;
+ intFormat = GL_RGBA;
+ glFormat = GL_BGRA;
+ gltype = GL_UNSIGNED_SHORT_4_4_4_4_REV;
+ } else if (pixelFormat == Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24)) { // ABGR8888
+ bpp = 4;
+ intFormat = GL_RGBA;
+ glFormat = GL_RGBA;
+ gltype = GL_UNSIGNED_INT_8_8_8_8_REV;
+ } else if (pixelFormat == Graphics::PixelFormat(4, 8, 8, 8, 8, 8, 16, 24, 0)) { // BGRA8888
+ bpp = 4;
+ intFormat = GL_RGBA;
+ glFormat = GL_BGRA;
+ gltype = GL_UNSIGNED_BYTE;
+ } else if (pixelFormat == Graphics::PixelFormat(3, 8, 8, 8, 0, 0, 8, 16, 0)) { // BGR888
+ bpp = 3;
+ intFormat = GL_RGB;
+ glFormat = GL_BGR;
+ gltype = GL_UNSIGNED_BYTE;
+ } else if (pixelFormat == Graphics::PixelFormat(2, 5, 6, 5, 0, 0, 5, 11, 0)) { // BGR565
+ bpp = 2;
+ intFormat = GL_RGB;
+ glFormat = GL_BGR;
+ gltype = GL_UNSIGNED_SHORT_5_6_5;
+ } else if (pixelFormat == Graphics::PixelFormat(2, 5, 5, 5, 1, 1, 6, 11, 0)) { // BGRA5551
+ bpp = 2;
+ intFormat = GL_RGBA;
+ glFormat = GL_BGRA;
+ gltype = GL_UNSIGNED_SHORT_5_5_5_1;
+ } else if (pixelFormat == Graphics::PixelFormat(2, 4, 4, 4, 4, 0, 4, 8, 12)) { // ABGR4444
+ bpp = 2;
+ intFormat = GL_RGBA;
+ glFormat = GL_RGBA;
+ gltype = GL_UNSIGNED_SHORT_4_4_4_4_REV;
+ } else if (pixelFormat == Graphics::PixelFormat(2, 4, 4, 4, 4, 4, 8, 12, 0)) { // BGRA4444
+ bpp = 2;
+ intFormat = GL_RGBA;
+ glFormat = GL_BGRA;
+ gltype = GL_UNSIGNED_SHORT_4_4_4_4;
+#endif
} else {
error("OpenGLGraphicsManager: Pixel format not supported");
}
@@ -898,6 +956,7 @@ void OpenGLGraphicsManager::internUpdateScreen() {
glPushMatrix();
+ // Adjust game screen shake position
glTranslatef(0, _shakePos * scaleFactor, 0); CHECK_GL_ERROR();
// Draw the game screen
@@ -920,6 +979,8 @@ void OpenGLGraphicsManager::internUpdateScreen() {
refreshCursor();
glPushMatrix();
+
+ // Adjust mouse shake position, unless the overlay is visible
glTranslatef(0, _overlayVisible ? 0 : _shakePos * scaleFactor, 0); CHECK_GL_ERROR();
// Draw the cursor
@@ -1004,28 +1065,30 @@ void OpenGLGraphicsManager::loadTextures() {
if (!_gameTexture) {
byte bpp;
+ GLenum intformat;
GLenum format;
GLenum type;
#ifdef USE_RGB_COLOR
- getGLPixelFormat(_screenFormat, bpp, format, type);
+ getGLPixelFormat(_screenFormat, bpp, intformat, format, type);
#else
- getGLPixelFormat(Graphics::PixelFormat::createFormatCLUT8(), bpp, format, type);
+ getGLPixelFormat(Graphics::PixelFormat::createFormatCLUT8(), bpp, intformat, format, type);
#endif
- _gameTexture = new GLTexture(bpp, format, type);
+ _gameTexture = new GLTexture(bpp, intformat, format, type);
}
_overlayFormat = Graphics::PixelFormat(2, 5, 5, 5, 1, 11, 6, 1, 0);
if (!_overlayTexture) {
byte bpp;
+ GLenum intformat;
GLenum format;
GLenum type;
- getGLPixelFormat(_overlayFormat, bpp, format, type);
- _overlayTexture = new GLTexture(bpp, format, type);
+ getGLPixelFormat(_overlayFormat, bpp, intformat, format, type);
+ _overlayTexture = new GLTexture(bpp, intformat, format, type);
}
if (!_cursorTexture)
- _cursorTexture = new GLTexture(4, GL_RGBA, GL_UNSIGNED_BYTE);
+ _cursorTexture = new GLTexture(4, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE);
GLint filter = _videoMode.antialiasing ? GL_LINEAR : GL_NEAREST;
_gameTexture->setFilter(filter);
@@ -1062,7 +1125,7 @@ void OpenGLGraphicsManager::loadTextures() {
#ifdef USE_OSD
if (!_osdTexture)
- _osdTexture = new GLTexture(2, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1);
+ _osdTexture = new GLTexture(2, GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1);
if (_transactionDetails.newContext || _transactionDetails.filterChanged)
_osdTexture->refresh();
@@ -1115,6 +1178,7 @@ void OpenGLGraphicsManager::setAspectRatioCorrection(int ratio) {
if (_transactionMode == kTransactionActive) {
if (ratio == -1)
+ // If -1, switch to next mode
_videoMode.aspectRatioCorrection = (_videoMode.aspectRatioCorrection + 1) % 5;
else
_videoMode.aspectRatioCorrection = ratio;
@@ -1220,7 +1284,7 @@ bool OpenGLGraphicsManager::saveScreenshot(const char *filename) {
// Allocate space for screenshot
uint8 *pixels = new uint8[width * height * 3];
- // Get pixel data from opengl buffer
+ // Get pixel data from OpenGL buffer
#ifdef USE_GLES
glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, pixels); CHECK_GL_ERROR();
#else
diff --git a/backends/graphics/opengl/opengl-graphics.h b/backends/graphics/opengl/opengl-graphics.h
index 166009c04d..52262fe31f 100644
--- a/backends/graphics/opengl/opengl-graphics.h
+++ b/backends/graphics/opengl/opengl-graphics.h
@@ -34,7 +34,8 @@
#define USE_OSD 1
namespace OpenGL {
-
+// The OpenGL GFX modes. They have to be inside the OpenGL namespace so they
+// do not clash with the SDL GFX modes.
enum {
GFX_NORMAL = 0,
GFX_DOUBLESIZE = 1,
@@ -44,7 +45,11 @@ enum {
}
/**
- * Open GL graphics manager
+ * Open GL graphics manager. This is an abstract class, it does not do the
+ * window and OpenGL context initialization.
+ * Derived classes should at least override internUpdateScreen for doing
+ * the buffers swap, and implement loadGFXMode for handling the window/context if
+ * needed. If USE_RGB_COLOR is enabled, getSupportedFormats must be implemented.
*/
class OpenGLGraphicsManager : public GraphicsManager, public Common::EventObserver {
public:
@@ -105,8 +110,14 @@ public:
bool notifyEvent(const Common::Event &event);
protected:
-
+ /**
+ * Setup OpenGL settings
+ */
virtual void initGL();
+
+ /**
+ * Creates and refreshs OpenGL textures.
+ */
virtual void loadTextures();
//
@@ -159,7 +170,10 @@ protected:
};
VideoState _videoMode, _oldVideoMode;
- virtual void getGLPixelFormat(Graphics::PixelFormat pixelFormat, byte &bpp, GLenum &glFormat, GLenum &type);
+ /**
+ * Sets the OpenGL texture format for the given pixel format. If format is not support will raise an error.
+ */
+ virtual void getGLPixelFormat(Graphics::PixelFormat pixelFormat, byte &bpp, GLenum &intFormat, GLenum &glFormat, GLenum &type);
virtual void internUpdateScreen();
virtual bool loadGFXMode();
@@ -167,12 +181,18 @@ protected:
virtual void setScale(int newScale);
+ // Drawing coordinates for the current aspect ratio
int _aspectX;
int _aspectY;
int _aspectWidth;
int _aspectHeight;
+ /**
+ * Sets the aspect ratio mode.
+ * @mode the aspect ratio mode, if -1 it will switch to next mode.
+ */
virtual void setAspectRatioCorrection(int mode);
+
virtual void refreshAspectRatio();
virtual Common::String getAspectRatioName();
virtual float getAspectRatio();
@@ -222,13 +242,11 @@ protected:
int16 w, h;
int16 hotX, hotY;
- // The size and hotspot of the scaled cursor, in real
- // coordinates.
+ // The size and hotspot of the scaled cursor, in real coordinates.
int16 rW, rH;
int16 rHotX, rHotY;
- // The size and hotspot of the scaled cursor, in game
- // coordinates.
+ // The size and hotspot of the scaled cursor, in game coordinates.
int16 vW, vH;
int16 vHotX, vHotY;
@@ -239,9 +257,7 @@ protected:
GLTexture* _cursorTexture;
Graphics::Surface _cursorData;
-#ifdef USE_RGB_COLOR
Graphics::PixelFormat _cursorFormat;
-#endif
byte *_cursorPalette;
bool _cursorPaletteDisabled;
MousePos _cursorState;