From b7d09c95ddb84f5c1aaf84877d7a059bfa607ca9 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 9 Mar 2019 14:48:14 +0100 Subject: [PATCH] - 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. --- src/c_console.cpp | 1 - src/d_main.cpp | 3 -- src/g_game.cpp | 50 +++++++++++++++++++++++ src/gamedata/textures/image.cpp | 2 +- src/intermission/intermission.cpp | 2 - src/m_misc.cpp | 10 +---- src/rendering/gl/renderer/gl_renderer.cpp | 8 +++- src/rendering/swrenderer/r_swrenderer.cpp | 9 ++-- src/v_framebuffer.cpp | 35 ---------------- src/v_palette.cpp | 23 ----------- src/v_palette.h | 17 -------- src/v_video.cpp | 3 -- src/v_video.h | 18 -------- src/wi_stuff.cpp | 1 - 14 files changed, 62 insertions(+), 120 deletions(-) diff --git a/src/c_console.cpp b/src/c_console.cpp index 12d76adba..8da82d852 100644 --- a/src/c_console.cpp +++ b/src/c_console.cpp @@ -1294,7 +1294,6 @@ void C_FullConsole () primaryLevel->Music = ""; S_Start (); P_FreeLevelData (); - V_SetBlend (0,0,0,0); } else { diff --git a/src/d_main.cpp b/src/d_main.cpp index 365b54938..ebb17e3d6 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -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 diff --git a/src/g_game.cpp b/src/g_game.cpp index dd5e73e75..a3375b5ca 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -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) diff --git a/src/gamedata/textures/image.cpp b/src/gamedata/textures/image.cpp index f047b8137..bbc621627 100644 --- a/src/gamedata/textures/image.cpp +++ b/src/gamedata/textures/image.cpp @@ -173,7 +173,7 @@ TArray 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); diff --git a/src/intermission/intermission.cpp b/src/intermission/intermission.cpp index 9affb04ad..f1dd8b9a0 100644 --- a/src/intermission/intermission.cpp +++ b/src/intermission/intermission.cpp @@ -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; diff --git a/src/m_misc.cpp b/src/m_misc.cpp index 2bf798b13..4b3438bc4 100644 --- a/src/m_misc.cpp +++ b/src/m_misc.cpp @@ -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; diff --git a/src/rendering/gl/renderer/gl_renderer.cpp b/src/rendering/gl/renderer/gl_renderer.cpp index 38a0ad604..662365724 100644 --- a/src/rendering/gl/renderer/gl_renderer.cpp +++ b/src/rendering/gl/renderer/gl_renderer.cpp @@ -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 diff --git a/src/rendering/swrenderer/r_swrenderer.cpp b/src/rendering/swrenderer/r_swrenderer.cpp index a2863ec71..cf153551f 100644 --- a/src/rendering/swrenderer/r_swrenderer.cpp +++ b/src/rendering/swrenderer/r_swrenderer.cpp @@ -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() diff --git a/src/v_framebuffer.cpp b/src/v_framebuffer.cpp index 26a86623a..c026133c0 100644 --- a/src/v_framebuffer.cpp +++ b/src/v_framebuffer.cpp @@ -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 diff --git a/src/v_palette.cpp b/src/v_palette.cpp index e598fa290..0c3427cd3 100644 --- a/src/v_palette.cpp +++ b/src/v_palette.cpp @@ -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; diff --git a/src/v_palette.h b/src/v_palette.h index a9a7e476b..703891656 100644 --- a/src/v_palette.h +++ b/src/v_palette.h @@ -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 { diff --git a/src/v_video.cpp b/src/v_video.cpp index d82d18eb9..9d091a51e 100644 --- a/src/v_video.cpp +++ b/src/v_video.cpp @@ -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(); } diff --git a/src/v_video.h b/src/v_video.h index d4fedf17c..826532853 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -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); diff --git a/src/wi_stuff.cpp b/src/wi_stuff.cpp index 1849d471c..dedda4602 100644 --- a/src/wi_stuff.cpp +++ b/src/wi_stuff.cpp @@ -761,7 +761,6 @@ void WI_Start(wbstartstruct_t *wbstartstruct) } } - V_SetBlend(0, 0, 0, 0); S_StopAllChannels(); for (auto Level : AllLevels()) {