OPENGL: Support RGBA8888 swapped textures when using OpenGL ES
This commit is contained in:
parent
b242abd029
commit
d765440c1a
3 changed files with 106 additions and 38 deletions
|
@ -208,25 +208,16 @@ Common::List<Graphics::PixelFormat> OpenGLGraphicsManager::getSupportedFormats()
|
||||||
// RGBA4444
|
// RGBA4444
|
||||||
formats.push_back(Graphics::PixelFormat(2, 4, 4, 4, 4, 12, 8, 4, 0));
|
formats.push_back(Graphics::PixelFormat(2, 4, 4, 4, 4, 12, 8, 4, 0));
|
||||||
|
|
||||||
#if !USE_FORCED_GLES && !USE_FORCED_GLES2
|
// These formats are not natively supported by OpenGL ES implementations,
|
||||||
#if !USE_FORCED_GL
|
// we convert the pixel format internally.
|
||||||
if (!isGLESContext()) {
|
|
||||||
#endif
|
|
||||||
#ifdef SCUMM_LITTLE_ENDIAN
|
#ifdef SCUMM_LITTLE_ENDIAN
|
||||||
// RGBA8888
|
// RGBA8888
|
||||||
formats.push_back(Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0));
|
formats.push_back(Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0));
|
||||||
#else
|
#else
|
||||||
// ABGR8888
|
// ABGR8888
|
||||||
formats.push_back(Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24));
|
formats.push_back(Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24));
|
||||||
#endif
|
#endif
|
||||||
#if !USE_FORCED_GL
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// RGB555, this is used by SCUMM HE 16 bit games.
|
// 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(2, 5, 5, 5, 0, 10, 5, 0, 0));
|
||||||
|
|
||||||
formats.push_back(Graphics::PixelFormat::createFormatCLUT8());
|
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.
|
// OpenGL ES does not support a texture format usable for RGB555.
|
||||||
// Since SCUMM uses this pixel format for some games (and there is no
|
// Since SCUMM uses this pixel format for some games (and there is no
|
||||||
// hope for this to change anytime soon) we use pixel format
|
// hope for this to change anytime soon) we use pixel format
|
||||||
// conversion to a supported texture format. However, this is a one
|
// conversion to a supported texture format.
|
||||||
// time exception.
|
|
||||||
return new TextureRGB555();
|
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
|
#endif // !USE_FORCED_GL
|
||||||
} else {
|
} else {
|
||||||
const bool supported = getGLPixelFormat(format, glIntFormat, glFormat, glType);
|
const bool supported = getGLPixelFormat(format, glIntFormat, glFormat, glType);
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include "backends/graphics/opengl/pipelines/clut8.h"
|
#include "backends/graphics/opengl/pipelines/clut8.h"
|
||||||
#include "backends/graphics/opengl/framebuffer.h"
|
#include "backends/graphics/opengl/framebuffer.h"
|
||||||
|
|
||||||
|
#include "common/endian.h"
|
||||||
#include "common/rect.h"
|
#include "common/rect.h"
|
||||||
#include "common/textconsole.h"
|
#include "common/textconsole.h"
|
||||||
|
|
||||||
|
@ -423,7 +424,7 @@ void TextureCLUT8::updateGLTexture() {
|
||||||
dirtyArea.width(), dirtyArea.height(),
|
dirtyArea.width(), dirtyArea.height(),
|
||||||
outSurf->pitch, _clut8Data.pitch, (const uint32 *)_palette);
|
outSurf->pitch, _clut8Data.pitch, (const uint32 *)_palette);
|
||||||
} else {
|
} 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.
|
// Do generic handling of updating the texture.
|
||||||
|
@ -431,32 +432,37 @@ void TextureCLUT8::updateGLTexture() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !USE_FORCED_GL
|
#if !USE_FORCED_GL
|
||||||
TextureRGB555::TextureRGB555()
|
FakeTexture::FakeTexture(GLenum glIntFormat, GLenum glFormat, GLenum glType, const Graphics::PixelFormat &format)
|
||||||
: Texture(GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0)),
|
: Texture(glIntFormat, glFormat, glType, format),
|
||||||
_rgb555Data() {
|
_rgbData() {
|
||||||
}
|
}
|
||||||
|
|
||||||
TextureRGB555::~TextureRGB555() {
|
FakeTexture::~FakeTexture() {
|
||||||
_rgb555Data.free();
|
_rgbData.free();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureRGB555::allocate(uint width, uint height) {
|
void FakeTexture::allocate(uint width, uint height) {
|
||||||
Texture::allocate(width, 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.
|
// changed.
|
||||||
if (width == _rgb555Data.w && height == _rgb555Data.h) {
|
if (width == _rgbData.w && height == _rgbData.h) {
|
||||||
return;
|
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 {
|
Graphics::PixelFormat TextureRGB555::getFormat() const {
|
||||||
return Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0);
|
return Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureRGB555::updateTexture() {
|
void TextureRGB555::updateGLTexture() {
|
||||||
if (!isDirty()) {
|
if (!isDirty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -469,8 +475,8 @@ void TextureRGB555::updateTexture() {
|
||||||
uint16 *dst = (uint16 *)outSurf->getBasePtr(dirtyArea.left, dirtyArea.top);
|
uint16 *dst = (uint16 *)outSurf->getBasePtr(dirtyArea.left, dirtyArea.top);
|
||||||
const uint dstAdd = outSurf->pitch - 2 * dirtyArea.width();
|
const uint dstAdd = outSurf->pitch - 2 * dirtyArea.width();
|
||||||
|
|
||||||
const uint16 *src = (const uint16 *)_rgb555Data.getBasePtr(dirtyArea.left, dirtyArea.top);
|
const uint16 *src = (const uint16 *)_rgbData.getBasePtr(dirtyArea.left, dirtyArea.top);
|
||||||
const uint srcAdd = _rgb555Data.pitch - 2 * dirtyArea.width();
|
const uint srcAdd = _rgbData.pitch - 2 * dirtyArea.width();
|
||||||
|
|
||||||
for (int height = dirtyArea.height(); height > 0; --height) {
|
for (int height = dirtyArea.height(); height > 0; --height) {
|
||||||
for (int width = dirtyArea.width(); width > 0; --width) {
|
for (int width = dirtyArea.width(); width > 0; --width) {
|
||||||
|
@ -488,6 +494,54 @@ void TextureRGB555::updateTexture() {
|
||||||
// Do generic handling of updating the texture.
|
// Do generic handling of updating the texture.
|
||||||
Texture::updateGLTexture();
|
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
|
#endif // !USE_FORCED_GL
|
||||||
|
|
||||||
#if !USE_FORCED_GLES
|
#if !USE_FORCED_GLES
|
||||||
|
|
|
@ -319,21 +319,39 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
#if !USE_FORCED_GL
|
#if !USE_FORCED_GL
|
||||||
class TextureRGB555 : public Texture {
|
class FakeTexture : public Texture {
|
||||||
public:
|
public:
|
||||||
TextureRGB555();
|
FakeTexture(GLenum glIntFormat, GLenum glFormat, GLenum glType, const Graphics::PixelFormat &format);
|
||||||
virtual ~TextureRGB555();
|
virtual ~FakeTexture();
|
||||||
|
|
||||||
virtual void allocate(uint width, uint height);
|
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::PixelFormat getFormat() const;
|
||||||
|
|
||||||
virtual Graphics::Surface *getSurface() { return &_rgb555Data; }
|
virtual void updateGLTexture();
|
||||||
virtual const Graphics::Surface *getSurface() const { return &_rgb555Data; }
|
};
|
||||||
|
|
||||||
virtual void updateTexture();
|
class TextureRGBA8888Swap : public FakeTexture {
|
||||||
private:
|
public:
|
||||||
Graphics::Surface _rgb555Data;
|
TextureRGBA8888Swap();
|
||||||
|
virtual ~TextureRGBA8888Swap() {};
|
||||||
|
|
||||||
|
virtual Graphics::PixelFormat getFormat() const;
|
||||||
|
|
||||||
|
virtual void updateGLTexture();
|
||||||
};
|
};
|
||||||
#endif // !USE_FORCED_GL
|
#endif // !USE_FORCED_GL
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue