mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-24 13:01:47 +00:00
- cleanup of savegame picture code.
* re-added screen blends for images from the hardware renderer. * moved all postprocessing of the image out of the renderers. * cleaned out a large piece of cruft for handling the palette in the frame buffer class. This was all a remnant of the old paletted backend that no longer exists. Nowadays the screen blend is just a postprocessing effect drawn over the 3D screen, there is no need to maintain any of it as global state anymore. * since the engine doesn't produce paletted screenshots anymore there is no need to have handling for it in the generation code. This depended on otherwise obsolete information so it got removed along with that information.
This commit is contained in:
parent
392ba7ed2e
commit
b7d09c95dd
14 changed files with 62 additions and 120 deletions
|
@ -1294,7 +1294,6 @@ void C_FullConsole ()
|
|||
primaryLevel->Music = "";
|
||||
S_Start ();
|
||||
P_FreeLevelData ();
|
||||
V_SetBlend (0,0,0,0);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -1247,7 +1247,6 @@ void D_DoAdvanceDemo (void)
|
|||
return;
|
||||
}
|
||||
|
||||
V_SetBlend (0,0,0,0);
|
||||
players[consoleplayer].playerstate = PST_LIVE; // not reborn
|
||||
usergame = false; // no save / end game here
|
||||
paused = 0;
|
||||
|
@ -2698,8 +2697,6 @@ void D_DoomMain (void)
|
|||
}
|
||||
else
|
||||
{
|
||||
// let the renderer reinitialize some stuff if needed
|
||||
screen->InitPalette();
|
||||
// These calls from inside V_Init2 are still necessary
|
||||
C_NewModeAdjust();
|
||||
D_StartTitle (); // start up intro loop
|
||||
|
|
|
@ -2100,6 +2100,56 @@ static void PutSaveComment (FSerializer &arc)
|
|||
arc.AddString("Comment", comment);
|
||||
}
|
||||
|
||||
void DoWriteSavePic(FileWriter *file, ESSType ssformat, uint8_t *scr, int width, int height, sector_t *viewsector, bool upsidedown)
|
||||
{
|
||||
PalEntry palette[256];
|
||||
PalEntry modulateColor;
|
||||
auto blend = screen->CalcBlend(viewsector, &modulateColor);
|
||||
int pixelsize = 1;
|
||||
// Apply the screen blend, because the renderer does not provide this.
|
||||
if (ssformat == SS_RGB)
|
||||
{
|
||||
int numbytes = width * height * 3;
|
||||
pixelsize = 3;
|
||||
if (modulateColor != 0xffffffff)
|
||||
{
|
||||
float r = modulateColor.r / 255.f;
|
||||
float g = modulateColor.g / 255.f;
|
||||
float b = modulateColor.b / 255.f;
|
||||
for (int i = 0; i < numbytes; i += 3)
|
||||
{
|
||||
scr[i] = uint8_t(scr[i] * r);
|
||||
scr[i + 1] = uint8_t(scr[i + 1] * g);
|
||||
scr[i + 2] = uint8_t(scr[i + 2] * b);
|
||||
}
|
||||
}
|
||||
float iblendfac = 1.f - blend.W;
|
||||
blend.X *= blend.W;
|
||||
blend.Y *= blend.W;
|
||||
blend.Z *= blend.W;
|
||||
for (int i = 0; i < numbytes; i += 3)
|
||||
{
|
||||
scr[i] = uint8_t(scr[i] * iblendfac + blend.X);
|
||||
scr[i + 1] = uint8_t(scr[i + 1] * iblendfac + blend.Y);
|
||||
scr[i + 2] = uint8_t(scr[i + 2] * iblendfac + blend.Z);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Apply the screen blend to the palette. The colormap related parts get skipped here because these are already part of the image.
|
||||
DoBlending(GPalette.BaseColors, palette, 256, uint8_t(blend.X), uint8_t(blend.Y), uint8_t(blend.Z), uint8_t(blend.W*255));
|
||||
}
|
||||
|
||||
int pitch = width * pixelsize;
|
||||
if (upsidedown)
|
||||
{
|
||||
scr += ((height - 1) * width * pixelsize);
|
||||
pitch *= -1;
|
||||
}
|
||||
|
||||
M_CreatePNG(file, scr, ssformat == SS_PAL? palette : nullptr, ssformat, width, height, pitch, Gamma);
|
||||
}
|
||||
|
||||
static void PutSavePic (FileWriter *file, int width, int height)
|
||||
{
|
||||
if (width <= 0 || height <= 0 || !storesavepic)
|
||||
|
|
|
@ -173,7 +173,7 @@ TArray<uint8_t> FImageSource::GetPalettedPixels(int conversion)
|
|||
int FImageSource::CopyPixels(FBitmap *bmp, int conversion)
|
||||
{
|
||||
if (conversion == luminance) conversion = normal; // luminance images have no use as an RGB source.
|
||||
PalEntry *palette = screen->GetPalette();
|
||||
PalEntry *palette = GPalette.BaseColors;
|
||||
for(int i=1;i<256;i++) palette[i].a = 255; // set proper alpha values
|
||||
auto ppix = CreatePalettedPixels(conversion);
|
||||
bmp->CopyPixelData(0, 0, ppix.Data(), Width, Height, Height, 1, 0, palette, nullptr);
|
||||
|
|
|
@ -211,7 +211,6 @@ int DIntermissionScreenFader::Responder (event_t *ev)
|
|||
{
|
||||
if (ev->type == EV_KeyDown)
|
||||
{
|
||||
V_SetBlend(0,0,0,0);
|
||||
return -1;
|
||||
}
|
||||
return Super::Responder(ev);
|
||||
|
@ -852,7 +851,6 @@ void F_StartIntermission(FIntermissionDescriptor *desc, bool deleteme, uint8_t s
|
|||
{
|
||||
DIntermissionController::CurrentIntermission->Destroy();
|
||||
}
|
||||
V_SetBlend (0,0,0,0);
|
||||
S_StopAllChannels ();
|
||||
gameaction = ga_nothing;
|
||||
gamestate = GS_FINALE;
|
||||
|
|
|
@ -612,12 +612,6 @@ void M_ScreenShot (const char *filename)
|
|||
auto buffer = screen->GetScreenshotBuffer(pitch, color_type, gamma);
|
||||
if (buffer.Size() > 0)
|
||||
{
|
||||
PalEntry palette[256];
|
||||
|
||||
if (color_type == SS_PAL)
|
||||
{
|
||||
screen->GetFlashedPalette(palette);
|
||||
}
|
||||
file = FileWriter::Open(autoname);
|
||||
if (file == NULL)
|
||||
{
|
||||
|
@ -626,12 +620,12 @@ void M_ScreenShot (const char *filename)
|
|||
}
|
||||
if (writepcx)
|
||||
{
|
||||
WritePCXfile(file, buffer.Data(), palette, color_type,
|
||||
WritePCXfile(file, buffer.Data(), nullptr, color_type,
|
||||
screen->GetWidth(), screen->GetHeight(), pitch);
|
||||
}
|
||||
else
|
||||
{
|
||||
WritePNGfile(file, buffer.Data(), palette, color_type,
|
||||
WritePNGfile(file, buffer.Data(), nullptr, color_type,
|
||||
screen->GetWidth(), screen->GetHeight(), pitch, gamma);
|
||||
}
|
||||
delete file;
|
||||
|
|
|
@ -67,6 +67,8 @@ EXTERN_CVAR(Bool, cl_capfps)
|
|||
|
||||
extern bool NoInterpolateView;
|
||||
|
||||
void DoWriteSavePic(FileWriter *file, ESSType ssformat, uint8_t *scr, int width, int height, sector_t *viewsector, bool upsidedown);
|
||||
|
||||
namespace OpenGLRenderer
|
||||
{
|
||||
|
||||
|
@ -370,9 +372,11 @@ void FGLRenderer::WriteSavePic (player_t *player, FileWriter *file, int width, i
|
|||
// strictly speaking not needed as the glReadPixels should block until the scene is rendered, but this is to safeguard against shitty drivers
|
||||
glFinish();
|
||||
|
||||
uint8_t * scr = (uint8_t *)M_Malloc(width * height * 3);
|
||||
int numpixels = width * height;
|
||||
uint8_t * scr = (uint8_t *)M_Malloc(numpixels * 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, Gamma);
|
||||
|
||||
DoWriteSavePic(file, SS_RGB, scr, width, height, viewsector, true);
|
||||
M_Free(scr);
|
||||
|
||||
// Switch back the screen render buffers
|
||||
|
|
|
@ -208,10 +208,11 @@ void FSoftwareRenderer::RenderView(player_t *player, DCanvas *target, void *vide
|
|||
});
|
||||
}
|
||||
|
||||
void DoWriteSavePic(FileWriter *file, ESSType ssformat, uint8_t *scr, int width, int height, sector_t *viewsector, bool upsidedown);
|
||||
|
||||
void FSoftwareRenderer::WriteSavePic (player_t *player, FileWriter *file, int width, int height)
|
||||
{
|
||||
DCanvas pic(width, height, false);
|
||||
PalEntry palette[256];
|
||||
|
||||
// Take a snapshot of the player's view
|
||||
if (V_IsPolyRenderer())
|
||||
|
@ -230,11 +231,7 @@ void FSoftwareRenderer::WriteSavePic (player_t *player, FileWriter *file, int wi
|
|||
r_viewpoint = mScene.MainThread()->Viewport->viewpoint;
|
||||
r_viewwindow = mScene.MainThread()->Viewport->viewwindow;
|
||||
}
|
||||
auto blend = screen->CalcBlend(r_viewpoint.sector, nullptr);
|
||||
const PalEntry bcolor(255, uint8_t(blend.X), uint8_t(blend.Y), uint8_t(blend.Z));
|
||||
screen->SetFlash(bcolor, int(blend.W * 256));
|
||||
screen->GetFlashedPalette (palette);
|
||||
M_CreatePNG (file, pic.GetPixels(), palette, SS_PAL, width, height, pic.GetPitch(), Gamma);
|
||||
DoWriteSavePic(file, SS_PAL, pic.GetPixels(), width, height, r_viewpoint.sector, false);
|
||||
}
|
||||
|
||||
void FSoftwareRenderer::DrawRemainingPlayerSprites()
|
||||
|
|
|
@ -202,11 +202,6 @@ void DFrameBuffer::DrawRateStuff ()
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void DFrameBuffer::GetFlashedPalette(PalEntry pal[256])
|
||||
{
|
||||
DoBlending(SourcePalette, pal, 256, Flash.r, Flash.g, Flash.b, Flash.a);
|
||||
}
|
||||
|
||||
void DFrameBuffer::Update()
|
||||
{
|
||||
CheckBench();
|
||||
|
@ -225,24 +220,6 @@ void DFrameBuffer::Update()
|
|||
}
|
||||
}
|
||||
|
||||
PalEntry *DFrameBuffer::GetPalette()
|
||||
{
|
||||
return SourcePalette;
|
||||
}
|
||||
|
||||
bool DFrameBuffer::SetFlash(PalEntry rgb, int amount)
|
||||
{
|
||||
Flash = PalEntry(amount, rgb.r, rgb.g, rgb.b);
|
||||
return true;
|
||||
}
|
||||
|
||||
void DFrameBuffer::GetFlash(PalEntry &rgb, int &amount)
|
||||
{
|
||||
rgb = Flash;
|
||||
rgb.a = 0;
|
||||
amount = Flash.a;
|
||||
}
|
||||
|
||||
void DFrameBuffer::SetClearColor(int color)
|
||||
{
|
||||
PalEntry pe = GPalette.BaseColors[color];
|
||||
|
@ -293,18 +270,6 @@ FTexture *DFrameBuffer::WipeEndScreen()
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// DFrameBuffer :: InitPalette
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void DFrameBuffer::InitPalette()
|
||||
{
|
||||
memcpy(SourcePalette, GPalette.BaseColors, sizeof(PalEntry) * 256);
|
||||
UpdatePalette();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// DFrameBuffer :: GetCaps
|
||||
|
|
|
@ -443,29 +443,6 @@ void DoBlending (const PalEntry *from, PalEntry *to, int count, int r, int g, in
|
|||
}
|
||||
}
|
||||
|
||||
void V_SetBlend (int blendr, int blendg, int blendb, int blenda)
|
||||
{
|
||||
// Don't do anything if the new blend is the same as the old
|
||||
if (((blenda|BlendA) == 0) ||
|
||||
(blendr == BlendR &&
|
||||
blendg == BlendG &&
|
||||
blendb == BlendB &&
|
||||
blenda == BlendA))
|
||||
return;
|
||||
|
||||
V_ForceBlend (blendr, blendg, blendb, blenda);
|
||||
}
|
||||
|
||||
void V_ForceBlend (int blendr, int blendg, int blendb, int blenda)
|
||||
{
|
||||
BlendR = blendr;
|
||||
BlendG = blendg;
|
||||
BlendB = blendb;
|
||||
BlendA = blenda;
|
||||
|
||||
screen->SetFlash (PalEntry (BlendR, BlendG, BlendB), BlendA);
|
||||
}
|
||||
|
||||
CCMD (testblend)
|
||||
{
|
||||
FString colorstring;
|
||||
|
|
|
@ -77,23 +77,6 @@ void DoBlending (const PalEntry *from, PalEntry *to, int count, int r, int g, in
|
|||
void ReadPalette(int lumpnum, uint8_t *buffer);
|
||||
void InitPalette ();
|
||||
|
||||
// V_SetBlend()
|
||||
// input: blendr: red component of blend
|
||||
// blendg: green component of blend
|
||||
// blendb: blue component of blend
|
||||
// blenda: alpha component of blend
|
||||
//
|
||||
// Applies the blend to all palettes with PALETTEF_BLEND flag
|
||||
void V_SetBlend (int blendr, int blendg, int blendb, int blenda);
|
||||
|
||||
// V_ForceBlend()
|
||||
//
|
||||
// Normally, V_SetBlend() does nothing if the new blend is the
|
||||
// same as the old. This function will perform the blending
|
||||
// even if the blend hasn't changed.
|
||||
void V_ForceBlend (int blendr, int blendg, int blendb, int blenda);
|
||||
|
||||
|
||||
EXTERN_CVAR (Int, paletteflash)
|
||||
enum PaletteFlashFlags
|
||||
{
|
||||
|
|
|
@ -696,9 +696,6 @@ void V_Init (bool restart)
|
|||
// Update screen palette when restarting
|
||||
else
|
||||
{
|
||||
PalEntry *palette = screen->GetPalette ();
|
||||
for (int i = 0; i < 256; ++i)
|
||||
*palette++ = GPalette.BaseColors[i];
|
||||
screen->UpdatePalette();
|
||||
}
|
||||
|
||||
|
|
|
@ -352,9 +352,6 @@ private:
|
|||
protected:
|
||||
int clipleft = 0, cliptop = 0, clipwidth = -1, clipheight = -1;
|
||||
|
||||
PalEntry Flash = 0; // Only needed to support some cruft in the interface that only makes sense for the software renderer
|
||||
PalEntry SourcePalette[256]; // This is where unpaletted textures get their palette from
|
||||
|
||||
public:
|
||||
// Hardware render state that needs to be exposed to the API independent part of the renderer. For ease of access this is stored in the base class.
|
||||
int hwcaps = 0; // Capability flags
|
||||
|
@ -404,26 +401,12 @@ public:
|
|||
// Make the surface visible.
|
||||
virtual void Update ();
|
||||
|
||||
// Return a pointer to 256 palette entries that can be written to.
|
||||
PalEntry *GetPalette ();
|
||||
|
||||
// Stores the palette with flash blended in into 256 dwords
|
||||
void GetFlashedPalette (PalEntry palette[256]);
|
||||
|
||||
// Mark the palette as changed. It will be updated on the next Update().
|
||||
virtual void UpdatePalette() {}
|
||||
|
||||
virtual void SetGamma() {}
|
||||
|
||||
// Sets a color flash. RGB is the color, and amount is 0-256, with 256
|
||||
// being all flash and 0 being no flash. Returns false if the hardware
|
||||
// does not support this. (Always true for now, since palettes can always
|
||||
// be flashed.)
|
||||
bool SetFlash (PalEntry rgb, int amount);
|
||||
|
||||
// Converse of SetFlash
|
||||
void GetFlash (PalEntry &rgb, int &amount);
|
||||
|
||||
// Returns true if running fullscreen.
|
||||
virtual bool IsFullscreen () = 0;
|
||||
virtual void ToggleFullscreen(bool yes) {}
|
||||
|
@ -475,7 +458,6 @@ public:
|
|||
}
|
||||
|
||||
// Report a game restart
|
||||
void InitPalette();
|
||||
void SetClearColor(int color);
|
||||
virtual uint32_t GetCaps();
|
||||
virtual void WriteSavePic(player_t *player, FileWriter *file, int width, int height);
|
||||
|
|
|
@ -761,7 +761,6 @@ void WI_Start(wbstartstruct_t *wbstartstruct)
|
|||
}
|
||||
}
|
||||
|
||||
V_SetBlend(0, 0, 0, 0);
|
||||
S_StopAllChannels();
|
||||
for (auto Level : AllLevels())
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue