STARK: Optionally do alpha pre-multiplication when loading PNGs

This commit is contained in:
Bastien Bouclet 2019-01-17 20:57:25 +01:00
parent b9a1b8eefd
commit 281ecbdc86
4 changed files with 53 additions and 1 deletions

View File

@ -56,6 +56,7 @@ Settings::Settings(Audio::Mixer *mixer, const ADGameDescription *gd) :
ConfMan.registerDefault(_boolKey[kHighFMV], true);
ConfMan.registerDefault(_boolKey[kTimeSkip], false);
ConfMan.registerDefault(_intKey[kSaveLoadPage], 0);
ConfMan.registerDefault("replacement_png_premultiply_alpha", false);
// Use the FunCom logo video to check low-resolution fmv
Common::SeekableReadStream *lowResFMV = StarkArchiveLoader->getExternalFile("1402_lo_res.bbb", "Global/");
@ -88,6 +89,10 @@ bool Settings::isAssetsModEnabled() const {
return ConfMan.getBool("enable_assets_mod");
}
bool Settings::shouldPreMultiplyReplacementPNGs() const {
return ConfMan.getBool("replacement_png_premultiply_alpha");
}
Gfx::Texture::SamplingFilter Settings::getImageSamplingFilter() const {
return ConfMan.getBool("use_linear_filtering") ? Gfx::Texture::kLinear : Gfx::Texture::kNearest;
}

View File

@ -98,6 +98,17 @@ public:
/** Should the game try to load external replacement assets? */
bool isAssetsModEnabled() const;
/**
* Should the engine apply alpha pre-multiplication when loading replacement PNGs
*
* When rendering, textures are expected to be in pre-multiplied alpha format.
* It's best to have the PNGs in that format on file to speed up loading by removing
* the need to convert them. However this option enables the conversion when loading
* the files to they can be stored with regular alpha transparency for convenience
* when testing.
*/
bool shouldPreMultiplyReplacementPNGs() const;
/** Should linear filtering be used when sampling the background image textures? */
Gfx::Texture::SamplingFilter getImageSamplingFilter() const;

View File

@ -82,13 +82,47 @@ bool VisualImageXMG::loadPNG(Common::SeekableReadStream *stream) {
return false;
}
_surface = pngDecoder.getSurface()->convertTo(Gfx::Driver::getRGBAPixelFormat());
if (StarkSettings->shouldPreMultiplyReplacementPNGs()) {
// We can do alpha pre-multiplication when loading for
// convenience when testing modded graphics.
_surface = multiplyColorWithAlpha(pngDecoder.getSurface());
} else {
_surface = pngDecoder.getSurface()->convertTo(Gfx::Driver::getRGBAPixelFormat());
}
_texture = _gfx->createTexture(_surface);
_texture->setSamplingFilter(StarkSettings->getImageSamplingFilter());
return true;
}
Graphics::Surface *VisualImageXMG::multiplyColorWithAlpha(const Graphics::Surface *source) {
assert(source->format.bytesPerPixel == 4);
Graphics::Surface *dest = new Graphics::Surface();
dest->create(source->w, source->h, Gfx::Driver::getRGBAPixelFormat());
for (uint y = 0; y < source->h; y++) {
const uint32 *srcPixel = (const uint32 *) source->getBasePtr(0, y);
uint32 *dstPixel = (uint32 *) dest->getBasePtr(0, y);
for (uint x = 0; x < source->w; x++) {
byte a, r, g, b;
source->format.colorToARGB(*srcPixel++, a, r, g, b);
if (a != 0xFF) {
r = (int) r * a / 255;
g = (int) g * a / 255;
b = (int) b * a / 255;
}
*dstPixel++ = dest->format.ARGBToColor(a, r, g, b);
}
}
return dest;
}
void VisualImageXMG::render(const Common::Point &position, bool useOffset) {
render(position, useOffset, true);
}

View File

@ -92,6 +92,8 @@ public:
const Graphics::Surface *getSurface() const;
private:
Graphics::Surface *multiplyColorWithAlpha(const Graphics::Surface *source);
Gfx::Driver *_gfx;
Gfx::SurfaceRenderer *_surfaceRenderer;
Gfx::Texture *_texture;