Fixed overbright screenshots with hardware gamma off

When render buffers are used to apply gamma/brightness/contrast screenshots should not use PNG gamma correction
This commit is contained in:
alexey.lysiuk 2017-12-06 10:59:20 +02:00
parent 505c99b0a8
commit 5162e7162e
13 changed files with 29 additions and 21 deletions

View file

@ -969,7 +969,7 @@ void GLSceneDrawer::WriteSavePic (player_t *player, FileWriter *file, int width,
uint8_t * scr = (uint8_t *)M_Malloc(width * height * 3);
glReadPixels(0,0,width, height,GL_RGB,GL_UNSIGNED_BYTE,scr);
M_CreatePNG (file, scr + ((height-1) * width * 3), NULL, SS_RGB, width, height, -width*3);
M_CreatePNG (file, scr + ((height-1) * width * 3), NULL, SS_RGB, width, height, -width * 3, Gamma);
M_Free(scr);
}

View file

@ -487,7 +487,7 @@ void OpenGLFrameBuffer::FillSimplePoly(FTexture *texture, FVector2 *points, int
//
//===========================================================================
void OpenGLFrameBuffer::GetScreenshotBuffer(const uint8_t *&buffer, int &pitch, ESSType &color_type)
void OpenGLFrameBuffer::GetScreenshotBuffer(const uint8_t *&buffer, int &pitch, ESSType &color_type, float &gamma)
{
const auto &viewport = GLRenderer->mOutputLetterbox;
@ -527,6 +527,10 @@ void OpenGLFrameBuffer::GetScreenshotBuffer(const uint8_t *&buffer, int &pitch,
pitch = -w*3;
color_type = SS_RGB;
buffer = ScreenshotBuffer + w * 3 * (h - 1);
// Screenshot should not use gamma correction if it was already applied to rendered image
EXTERN_CVAR(Bool, fullscreen);
gamma = 1 == vid_hwgamma || (2 == vid_hwgamma && !fullscreen) ? 1.0f : Gamma;
}
//===========================================================================

View file

@ -51,7 +51,7 @@ public:
// Retrieves a buffer containing image data for a screenshot.
// Hint: Pitch can be negative for upside-down images, in which case buffer
// points to the last row in the buffer, which will be the first row output.
virtual void GetScreenshotBuffer(const uint8_t *&buffer, int &pitch, ESSType &color_type);
virtual void GetScreenshotBuffer(const uint8_t *&buffer, int &pitch, ESSType &color_type, float &gamma) override;
// Releases the screenshot buffer.
virtual void ReleaseScreenshotBuffer();

View file

@ -1671,15 +1671,15 @@ void OpenGLSWFrameBuffer::SetBlendingRect(int x1, int y1, int x2, int y2)
//
//==========================================================================
void OpenGLSWFrameBuffer::GetScreenshotBuffer(const uint8_t *&buffer, int &pitch, ESSType &color_type)
void OpenGLSWFrameBuffer::GetScreenshotBuffer(const uint8_t *&buffer, int &pitch, ESSType &color_type, float &gamma)
{
Super::GetScreenshotBuffer(buffer, pitch, color_type);
Super::GetScreenshotBuffer(buffer, pitch, color_type, gamma);
/*
LockedRect lrect;
if (!Accel2D)
{
Super::GetScreenshotBuffer(buffer, pitch, color_type);
Super::GetScreenshotBuffer(buffer, pitch, color_type, gamma);
return;
}
buffer = nullptr;
@ -1702,6 +1702,7 @@ void OpenGLSWFrameBuffer::GetScreenshotBuffer(const uint8_t *&buffer, int &pitch
buffer = (const uint8_t *)lrect.pBits;
pitch = lrect.Pitch;
color_type = SS_BGRA;
gamma = Gamma;
}
}
*/

View file

@ -44,7 +44,7 @@ public:
int GetPageCount() override;
void SetVSync(bool vsync) override;
void NewRefreshRate() override;
void GetScreenshotBuffer(const uint8_t *&buffer, int &pitch, ESSType &color_type) override;
void GetScreenshotBuffer(const uint8_t *&buffer, int &pitch, ESSType &color_type, float &gamma) override;
void ReleaseScreenshotBuffer() override;
void SetBlendingRect(int x1, int y1, int x2, int y2) override;
bool Begin2D(bool copy3d) override;

View file

@ -521,11 +521,11 @@ void WritePCXfile (FileWriter *file, const uint8_t *buffer, const PalEntry *pale
// WritePNGfile
//
void WritePNGfile (FileWriter *file, const uint8_t *buffer, const PalEntry *palette,
ESSType color_type, int width, int height, int pitch)
ESSType color_type, int width, int height, int pitch, float gamma)
{
char software[100];
mysnprintf(software, countof(software), GAMENAME " %s", GetVersionString());
if (!M_CreatePNG (file, buffer, palette, color_type, width, height, pitch) ||
if (!M_CreatePNG (file, buffer, palette, color_type, width, height, pitch, gamma) ||
!M_AppendPNGText (file, "Software", software) ||
!M_FinishPNG (file))
{
@ -626,8 +626,9 @@ void M_ScreenShot (const char *filename)
const uint8_t *buffer;
int pitch;
ESSType color_type;
float gamma;
screen->GetScreenshotBuffer(buffer, pitch, color_type);
screen->GetScreenshotBuffer(buffer, pitch, color_type, gamma);
if (buffer != NULL)
{
PalEntry palette[256];
@ -651,7 +652,7 @@ void M_ScreenShot (const char *filename)
else
{
WritePNGfile(file, buffer, palette, color_type,
screen->GetWidth(), screen->GetHeight(), pitch);
screen->GetWidth(), screen->GetHeight(), pitch, gamma);
}
delete file;
screen->ReleaseScreenshotBuffer();

View file

@ -132,7 +132,7 @@ CVAR(Float, png_gamma, 0.f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
//==========================================================================
bool M_CreatePNG (FileWriter *file, const uint8_t *buffer, const PalEntry *palette,
ESSType color_type, int width, int height, int pitch)
ESSType color_type, int width, int height, int pitch, float gamma)
{
uint8_t work[8 + // signature
12+2*4+5 + // IHDR
@ -157,7 +157,7 @@ bool M_CreatePNG (FileWriter *file, const uint8_t *buffer, const PalEntry *palet
MakeChunk (ihdr, MAKE_ID('I','H','D','R'), 2*4+5);
// Assume a display exponent of 2.2 (100000/2.2 ~= 45454.5)
*gama = BigLong (int (45454.5f * (png_gamma == 0.f ? Gamma : png_gamma)));
*gama = BigLong (int (45454.5f * (png_gamma == 0.f ? gamma : png_gamma)));
MakeChunk (gama, MAKE_ID('g','A','M','A'), 4);
if (color_type == SS_PAL)

View file

@ -46,7 +46,7 @@ class FileWriter;
// This function writes the PNG signature and the IHDR, gAMA, PLTE, and IDAT
// chunks.
bool M_CreatePNG (FileWriter *file, const uint8_t *buffer, const PalEntry *pal,
ESSType color_type, int width, int height, int pitch);
ESSType color_type, int width, int height, int pitch, float gamma);
// Creates a grayscale 1x1 PNG file. Used for savegames without savepics.
bool M_CreateDummyPNG (FileWriter *file);

View file

@ -225,7 +225,7 @@ void FSoftwareRenderer::WriteSavePic (player_t *player, FileWriter *file, int wi
r_viewwindow = mScene.MainThread()->Viewport->viewwindow;
}
screen->GetFlashedPalette (palette);
M_CreatePNG (file, pic->GetBuffer(), palette, SS_PAL, width, height, pic->GetPitch());
M_CreatePNG (file, pic->GetBuffer(), palette, SS_PAL, width, height, pic->GetPitch(), Gamma);
pic->Unlock ();
delete pic;
}
@ -399,4 +399,4 @@ uint32_t FSoftwareRenderer::GetCaps()
FlagSet |= RFF_COLORMAP;
return (uint32_t)FlagSet;
}
}

View file

@ -329,12 +329,13 @@ void DCanvas::Dim (PalEntry color)
//
//==========================================================================
void DCanvas::GetScreenshotBuffer(const uint8_t *&buffer, int &pitch, ESSType &color_type)
void DCanvas::GetScreenshotBuffer(const uint8_t *&buffer, int &pitch, ESSType &color_type, float &gamma)
{
Lock(true);
buffer = GetBuffer();
pitch = IsBgra() ? GetPitch() * 4 : GetPitch();
color_type = IsBgra() ? SS_BGRA : SS_PAL;
gamma = Gamma;
}
//==========================================================================

View file

@ -256,7 +256,7 @@ public:
// Retrieves a buffer containing image data for a screenshot.
// Hint: Pitch can be negative for upside-down images, in which case buffer
// points to the last row in the buffer, which will be the first row output.
virtual void GetScreenshotBuffer(const uint8_t *&buffer, int &pitch, ESSType &color_type);
virtual void GetScreenshotBuffer(const uint8_t *&buffer, int &pitch, ESSType &color_type, float &gamma);
// Releases the screenshot buffer.
virtual void ReleaseScreenshotBuffer();

View file

@ -1755,13 +1755,13 @@ void D3DFB::SetBlendingRect(int x1, int y1, int x2, int y2)
//
//==========================================================================
void D3DFB::GetScreenshotBuffer(const uint8_t *&buffer, int &pitch, ESSType &color_type)
void D3DFB::GetScreenshotBuffer(const uint8_t *&buffer, int &pitch, ESSType &color_type, float &gamma)
{
D3DLOCKED_RECT lrect;
if (!Accel2D)
{
Super::GetScreenshotBuffer(buffer, pitch, color_type);
Super::GetScreenshotBuffer(buffer, pitch, color_type, gamma);
return;
}
buffer = NULL;
@ -1784,6 +1784,7 @@ void D3DFB::GetScreenshotBuffer(const uint8_t *&buffer, int &pitch, ESSType &col
buffer = (const uint8_t *)lrect.pBits;
pitch = lrect.Pitch;
color_type = SS_BGRA;
gamma = Gamma;
}
}
}

View file

@ -124,7 +124,7 @@ public:
bool PaintToWindow ();
void SetVSync (bool vsync);
void NewRefreshRate();
void GetScreenshotBuffer(const uint8_t *&buffer, int &pitch, ESSType &color_type);
void GetScreenshotBuffer(const uint8_t *&buffer, int &pitch, ESSType &color_type, float &gamma) override;
void ReleaseScreenshotBuffer();
void SetBlendingRect (int x1, int y1, int x2, int y2);
bool Begin2D (bool copy3d);