diff options
author | Cameron Cawley | 2019-07-23 16:37:11 +0100 |
---|---|---|
committer | Thierry Crozat | 2019-08-04 18:46:30 +0100 |
commit | d765440c1ae138d2c92b89cd9313cac52cd2af4a (patch) | |
tree | 79f7f4ac95af3c5795448bc845bc5022b69f0831 /backends/graphics/opengl | |
parent | b242abd0295621d797f902bfaa6df9cc439657f2 (diff) | |
download | scummvm-rg350-d765440c1ae138d2c92b89cd9313cac52cd2af4a.tar.gz scummvm-rg350-d765440c1ae138d2c92b89cd9313cac52cd2af4a.tar.bz2 scummvm-rg350-d765440c1ae138d2c92b89cd9313cac52cd2af4a.zip |
OPENGL: Support RGBA8888 swapped textures when using OpenGL ES
Diffstat (limited to 'backends/graphics/opengl')
-rw-r--r-- | backends/graphics/opengl/opengl-graphics.cpp | 30 | ||||
-rw-r--r-- | backends/graphics/opengl/texture.cpp | 80 | ||||
-rw-r--r-- | backends/graphics/opengl/texture.h | 34 |
3 files changed, 106 insertions, 38 deletions
diff --git a/backends/graphics/opengl/opengl-graphics.cpp b/backends/graphics/opengl/opengl-graphics.cpp index 83d2c86058..3ee374eaab 100644 --- a/backends/graphics/opengl/opengl-graphics.cpp +++ b/backends/graphics/opengl/opengl-graphics.cpp @@ -208,25 +208,16 @@ Common::List<Graphics::PixelFormat> OpenGLGraphicsManager::getSupportedFormats() // RGBA4444 formats.push_back(Graphics::PixelFormat(2, 4, 4, 4, 4, 12, 8, 4, 0)); -#if !USE_FORCED_GLES && !USE_FORCED_GLES2 -#if !USE_FORCED_GL - if (!isGLESContext()) { -#endif + // These formats are not natively supported by OpenGL ES implementations, + // we convert the pixel format internally. #ifdef SCUMM_LITTLE_ENDIAN - // RGBA8888 - formats.push_back(Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0)); + // RGBA8888 + formats.push_back(Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0)); #else - // ABGR8888 - formats.push_back(Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24)); -#endif -#if !USE_FORCED_GL - } -#endif + // ABGR8888 + formats.push_back(Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24)); #endif - // RGB555, this is used by SCUMM HE 16 bit games. - // This is not natively supported by OpenGL ES implementations, we convert - // the pixel format internally. formats.push_back(Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0)); formats.push_back(Graphics::PixelFormat::createFormatCLUT8()); @@ -1109,9 +1100,14 @@ Surface *OpenGLGraphicsManager::createSurface(const Graphics::PixelFormat &forma // OpenGL ES does not support a texture format usable for RGB555. // Since SCUMM uses this pixel format for some games (and there is no // hope for this to change anytime soon) we use pixel format - // conversion to a supported texture format. However, this is a one - // time exception. + // conversion to a supported texture format. return new TextureRGB555(); +#ifdef SCUMM_LITTLE_ENDIAN + } else if (isGLESContext() && format == Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0)) { // RGBA8888 +#else + } else if (isGLESContext() && format == Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24)) { // ABGR8888 +#endif + return new TextureRGBA8888Swap(); #endif // !USE_FORCED_GL } else { const bool supported = getGLPixelFormat(format, glIntFormat, glFormat, glType); diff --git a/backends/graphics/opengl/texture.cpp b/backends/graphics/opengl/texture.cpp index 2a078534ab..93480f7360 100644 --- a/backends/graphics/opengl/texture.cpp +++ b/backends/graphics/opengl/texture.cpp @@ -26,6 +26,7 @@ #include "backends/graphics/opengl/pipelines/clut8.h" #include "backends/graphics/opengl/framebuffer.h" +#include "common/endian.h" #include "common/rect.h" #include "common/textconsole.h" @@ -423,7 +424,7 @@ void TextureCLUT8::updateGLTexture() { dirtyArea.width(), dirtyArea.height(), outSurf->pitch, _clut8Data.pitch, (const uint32 *)_palette); } else { - warning("TextureCLUT8::updateTexture: Unsupported pixel depth: %d", outSurf->format.bytesPerPixel); + warning("TextureCLUT8::updateGLTexture: Unsupported pixel depth: %d", outSurf->format.bytesPerPixel); } // Do generic handling of updating the texture. @@ -431,32 +432,37 @@ void TextureCLUT8::updateGLTexture() { } #if !USE_FORCED_GL -TextureRGB555::TextureRGB555() - : Texture(GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0)), - _rgb555Data() { +FakeTexture::FakeTexture(GLenum glIntFormat, GLenum glFormat, GLenum glType, const Graphics::PixelFormat &format) + : Texture(glIntFormat, glFormat, glType, format), + _rgbData() { } -TextureRGB555::~TextureRGB555() { - _rgb555Data.free(); +FakeTexture::~FakeTexture() { + _rgbData.free(); } -void TextureRGB555::allocate(uint width, uint height) { +void FakeTexture::allocate(uint width, uint height) { Texture::allocate(width, height); - // We only need to reinitialize our RGB555 surface when the output size + // We only need to reinitialize our surface when the output size // changed. - if (width == _rgb555Data.w && height == _rgb555Data.h) { + if (width == _rgbData.w && height == _rgbData.h) { return; } - _rgb555Data.create(width, height, Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0)); + warning("%s pixel format not supported by OpenGL ES, using %s instead", getFormat().toString().c_str(), _format.toString().c_str()); + _rgbData.create(width, height, getFormat()); +} + +TextureRGB555::TextureRGB555() + : FakeTexture(GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0)) { } Graphics::PixelFormat TextureRGB555::getFormat() const { return Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0); } -void TextureRGB555::updateTexture() { +void TextureRGB555::updateGLTexture() { if (!isDirty()) { return; } @@ -469,8 +475,8 @@ void TextureRGB555::updateTexture() { uint16 *dst = (uint16 *)outSurf->getBasePtr(dirtyArea.left, dirtyArea.top); const uint dstAdd = outSurf->pitch - 2 * dirtyArea.width(); - const uint16 *src = (const uint16 *)_rgb555Data.getBasePtr(dirtyArea.left, dirtyArea.top); - const uint srcAdd = _rgb555Data.pitch - 2 * dirtyArea.width(); + const uint16 *src = (const uint16 *)_rgbData.getBasePtr(dirtyArea.left, dirtyArea.top); + const uint srcAdd = _rgbData.pitch - 2 * dirtyArea.width(); for (int height = dirtyArea.height(); height > 0; --height) { for (int width = dirtyArea.width(); width > 0; --width) { @@ -488,6 +494,54 @@ void TextureRGB555::updateTexture() { // Do generic handling of updating the texture. Texture::updateGLTexture(); } + +TextureRGBA8888Swap::TextureRGBA8888Swap() +#ifdef SCUMM_LITTLE_ENDIAN + : FakeTexture(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24)) // ABGR8888 +#else + : FakeTexture(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0)) // RGBA8888 +#endif + { +} + +Graphics::PixelFormat TextureRGBA8888Swap::getFormat() const { +#ifdef SCUMM_LITTLE_ENDIAN + return Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0); // RGBA8888 +#else + return Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24); // ABGR8888 +#endif +} + +void TextureRGBA8888Swap::updateGLTexture() { + if (!isDirty()) { + return; + } + + // Convert color space. + Graphics::Surface *outSurf = Texture::getSurface(); + + const Common::Rect dirtyArea = getDirtyArea(); + + uint32 *dst = (uint32 *)outSurf->getBasePtr(dirtyArea.left, dirtyArea.top); + const uint dstAdd = outSurf->pitch - 4 * dirtyArea.width(); + + const uint32 *src = (const uint32 *)_rgbData.getBasePtr(dirtyArea.left, dirtyArea.top); + const uint srcAdd = _rgbData.pitch - 4 * dirtyArea.width(); + + for (int height = dirtyArea.height(); height > 0; --height) { + for (int width = dirtyArea.width(); width > 0; --width) { + const uint32 color = *src++; + + *dst++ = SWAP_BYTES_32(color); + } + + src = (const uint32 *)((const byte *)src + srcAdd); + dst = (uint32 *)((byte *)dst + dstAdd); + } + + // Do generic handling of updating the texture. + Texture::updateGLTexture(); +} #endif // !USE_FORCED_GL #if !USE_FORCED_GLES diff --git a/backends/graphics/opengl/texture.h b/backends/graphics/opengl/texture.h index 3be09cb9f9..81adc384b9 100644 --- a/backends/graphics/opengl/texture.h +++ b/backends/graphics/opengl/texture.h @@ -319,21 +319,39 @@ private: }; #if !USE_FORCED_GL -class TextureRGB555 : public Texture { +class FakeTexture : public Texture { public: - TextureRGB555(); - virtual ~TextureRGB555(); + FakeTexture(GLenum glIntFormat, GLenum glFormat, GLenum glType, const Graphics::PixelFormat &format); + virtual ~FakeTexture(); virtual void allocate(uint width, uint height); + virtual Graphics::PixelFormat getFormat() const = 0; + + virtual Graphics::Surface *getSurface() { return &_rgbData; } + virtual const Graphics::Surface *getSurface() const { return &_rgbData; } +protected: + Graphics::Surface _rgbData; +}; + +class TextureRGB555 : public FakeTexture { +public: + TextureRGB555(); + virtual ~TextureRGB555() {}; + virtual Graphics::PixelFormat getFormat() const; - virtual Graphics::Surface *getSurface() { return &_rgb555Data; } - virtual const Graphics::Surface *getSurface() const { return &_rgb555Data; } + virtual void updateGLTexture(); +}; - virtual void updateTexture(); -private: - Graphics::Surface _rgb555Data; +class TextureRGBA8888Swap : public FakeTexture { +public: + TextureRGBA8888Swap(); + virtual ~TextureRGBA8888Swap() {}; + + virtual Graphics::PixelFormat getFormat() const; + + virtual void updateGLTexture(); }; #endif // !USE_FORCED_GL |