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  | 
