Apply gamma when using true color output on Linux and Mac

This commit is contained in:
Magnus Norddahl 2016-06-11 18:41:56 +02:00
parent 5ae8e9e8c2
commit 40b76dc9b0
4 changed files with 68 additions and 17 deletions

View file

@ -869,10 +869,7 @@ void CocoaFrameBuffer::Update()
if (IsBgra())
{
for (int y = 0; y < Height; y++)
{
memcpy((uint32_t*)m_pixelBuffer + y * Width, (uint32_t*)MemBuffer + y * Pitch, Width * BYTES_PER_PIXEL);
}
CopyWithGammaBgra(m_pixelBuffer, Width * BYTES_PER_PIXEL, m_gammaTable[0], m_gammaTable[1], m_gammaTable[2], m_flashColor, m_flashAmount);
}
else
{

View file

@ -497,17 +497,7 @@ void SDLFB::Update ()
if (Bgra)
{
if (pitch == Pitch * 4)
{
memcpy(pixels, MemBuffer, Width*Height*4);
}
else
{
for (int y = 0; y < Height; ++y)
{
memcpy((BYTE *)pixels + y*pitch, MemBuffer + y*Pitch*4, Width*4);
}
}
CopyWithGammaBgra(pixels, pitch, GammaTable[0], GammaTable[1], GammaTable[2], Flash, FlashAmount);
}
else if (NotPaletted)
{

View file

@ -742,13 +742,12 @@ void DCanvas::CalcGamma (float gamma, BYTE gammalookup[256])
// I found this formula on the web at
// <http://panda.mostang.com/sane/sane-gamma.html>,
// but that page no longer exits.
double invgamma = 1.f / gamma;
int i;
for (i = 0; i < 256; i++)
{
gammalookup[i] = (BYTE)(255.0 * pow (i / 255.0, invgamma));
gammalookup[i] = (BYTE)(255.0 * pow (i / 255.0, invgamma) + 0.5);
}
}
@ -876,6 +875,70 @@ DFrameBuffer::DFrameBuffer (int width, int height, bool bgra)
Accel2D = false;
}
//==========================================================================
//
// DFrameBuffer :: PostprocessBgra
//
// Copies data to destination buffer while performing gamma and flash.
// This is only needed if a target cannot do this with shaders.
//
//==========================================================================
void DFrameBuffer::CopyWithGammaBgra(void *output, int pitch, const BYTE *gammared, const BYTE *gammagreen, const BYTE *gammablue, PalEntry flash, int flash_amount)
{
const BYTE *gammatables[3] = { gammared, gammagreen, gammablue };
if (flash_amount > 0)
{
uint16_t inv_flash_amount = 256 - flash_amount;
uint16_t flash_red = flash.r * flash_amount;
uint16_t flash_green = flash.g * flash_amount;
uint16_t flash_blue = flash.b * flash_amount;
for (int y = 0; y < Height; y++)
{
BYTE *dest = (BYTE*)output + y * pitch;
BYTE *src = MemBuffer + y * Pitch * 4;
for (int x = 0; x < Width; x++)
{
uint16_t fg_red = src[2];
uint16_t fg_green = src[1];
uint16_t fg_blue = src[0];
uint16_t red = (fg_red * inv_flash_amount + flash_red) >> 8;
uint16_t green = (fg_green * inv_flash_amount + flash_green) >> 8;
uint16_t blue = (fg_blue * inv_flash_amount + flash_blue) >> 8;
dest[0] = gammatables[2][blue];
dest[1] = gammatables[1][green];
dest[2] = gammatables[0][red];
dest[3] = 0xff;
dest += 4;
src += 4;
}
}
}
else
{
for (int y = 0; y < Height; y++)
{
BYTE *dest = (BYTE*)output + y * pitch;
BYTE *src = MemBuffer + y * Pitch * 4;
for (int x = 0; x < Width; x++)
{
dest[0] = gammatables[2][src[0]];
dest[1] = gammatables[1][src[1]];
dest[2] = gammatables[0][src[2]];
dest[3] = 0xff;
dest += 4;
src += 4;
}
}
}
}
//==========================================================================
//
// DFrameBuffer :: DrawRateStuff

View file

@ -420,6 +420,7 @@ public:
protected:
void DrawRateStuff ();
void CopyFromBuff (BYTE *src, int srcPitch, int width, int height, BYTE *dest);
void CopyWithGammaBgra(void *output, int pitch, const BYTE *gammared, const BYTE *gammagreen, const BYTE *gammablue, PalEntry flash, int flash_amount);
DFrameBuffer () {}