mirror of
https://github.com/ZDoom/gzdoom.git
synced 2025-02-21 11:31:41 +00:00
- consolidated the savegame picture code.
This commit is contained in:
parent
6177ed153d
commit
44d39ef63e
11 changed files with 158 additions and 177 deletions
|
@ -82,6 +82,7 @@
|
||||||
#include "events.h"
|
#include "events.h"
|
||||||
#include "c_buttons.h"
|
#include "c_buttons.h"
|
||||||
#include "d_buttons.h"
|
#include "d_buttons.h"
|
||||||
|
#include "hwrenderer/scene/hw_drawinfo.h"
|
||||||
|
|
||||||
|
|
||||||
static FRandom pr_dmspawn ("DMSpawn");
|
static FRandom pr_dmspawn ("DMSpawn");
|
||||||
|
@ -2252,56 +2253,6 @@ static void PutSaveComment (FSerializer &arc)
|
||||||
arc.AddString("Comment", comment);
|
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 = V_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)
|
static void PutSavePic (FileWriter *file, int width, int height)
|
||||||
{
|
{
|
||||||
if (width <= 0 || height <= 0 || !storesavepic)
|
if (width <= 0 || height <= 0 || !storesavepic)
|
||||||
|
@ -2312,7 +2263,7 @@ static void PutSavePic (FileWriter *file, int width, int height)
|
||||||
{
|
{
|
||||||
D_Render([&]()
|
D_Render([&]()
|
||||||
{
|
{
|
||||||
screen->WriteSavePic(&players[consoleplayer], file, width, height);
|
WriteSavePic(&players[consoleplayer], file, width, height);
|
||||||
}, false);
|
}, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#include "r_data/r_interpolate.h"
|
#include "r_data/r_interpolate.h"
|
||||||
#include "r_utility.h"
|
#include "r_utility.h"
|
||||||
#include "d_player.h"
|
#include "d_player.h"
|
||||||
|
#include "swrenderer/r_renderer.h"
|
||||||
#include "hwrenderer/dynlights/hw_dynlightdata.h"
|
#include "hwrenderer/dynlights/hw_dynlightdata.h"
|
||||||
#include "hwrenderer/utility/hw_clock.h"
|
#include "hwrenderer/utility/hw_clock.h"
|
||||||
#include "hwrenderer/data/flatvertices.h"
|
#include "hwrenderer/data/flatvertices.h"
|
||||||
|
@ -39,6 +40,7 @@
|
||||||
#include "hwrenderer/dynlights/hw_lightbuffer.h"
|
#include "hwrenderer/dynlights/hw_lightbuffer.h"
|
||||||
#include "hwrenderer/utility/hw_cvars.h"
|
#include "hwrenderer/utility/hw_cvars.h"
|
||||||
#include "hwrenderer/data/hw_viewpointbuffer.h"
|
#include "hwrenderer/data/hw_viewpointbuffer.h"
|
||||||
|
#include "hwrenderer/scene/hw_fakeflat.h"
|
||||||
#include "hwrenderer/scene/hw_clipper.h"
|
#include "hwrenderer/scene/hw_clipper.h"
|
||||||
#include "hwrenderer/scene/hw_portal.h"
|
#include "hwrenderer/scene/hw_portal.h"
|
||||||
#include "hwrenderer/utility/hw_vrmodes.h"
|
#include "hwrenderer/utility/hw_vrmodes.h"
|
||||||
|
@ -118,3 +120,107 @@ sector_t* RenderViewpoint(FRenderViewpoint& mainvp, AActor* camera, IntRect* bou
|
||||||
|
|
||||||
return mainvp.sector;
|
return mainvp.sector;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 = V_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);
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// Render the view to a savegame picture
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
void WriteSavePic(player_t* player, FileWriter* file, int width, int height)
|
||||||
|
{
|
||||||
|
if (!V_IsHardwareRenderer())
|
||||||
|
{
|
||||||
|
SWRenderer->WriteSavePic(player, file, width, height);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
IntRect bounds;
|
||||||
|
bounds.left = 0;
|
||||||
|
bounds.top = 0;
|
||||||
|
bounds.width = width;
|
||||||
|
bounds.height = height;
|
||||||
|
auto& RenderState = *screen->RenderState();
|
||||||
|
|
||||||
|
// we must be sure the GPU finished reading from the buffer before we fill it with new data.
|
||||||
|
screen->WaitForCommands(false);
|
||||||
|
|
||||||
|
// Switch to render buffers dimensioned for the savepic
|
||||||
|
screen->SetSaveBuffers(true);
|
||||||
|
screen->ImageTransitionScene(true);
|
||||||
|
|
||||||
|
hw_ClearFakeFlat();
|
||||||
|
RenderState.SetVertexBuffer(screen->mVertexData);
|
||||||
|
screen->mVertexData->Reset();
|
||||||
|
screen->mLights->Clear();
|
||||||
|
screen->mViewpoints->Clear();
|
||||||
|
|
||||||
|
// This shouldn't overwrite the global viewpoint even for a short time.
|
||||||
|
FRenderViewpoint savevp;
|
||||||
|
sector_t* viewsector = RenderViewpoint(savevp, players[consoleplayer].camera, &bounds, r_viewpoint.FieldOfView.Degrees, 1.6f, 1.6f, true, false);
|
||||||
|
RenderState.EnableStencil(false);
|
||||||
|
RenderState.SetNoSoftLightLevel();
|
||||||
|
|
||||||
|
int numpixels = width * height;
|
||||||
|
uint8_t* scr = (uint8_t*)M_Malloc(numpixels * 3);
|
||||||
|
screen->CopyScreenToBuffer(width, height, scr);
|
||||||
|
|
||||||
|
DoWriteSavePic(file, SS_RGB, scr, width, height, viewsector, screen->FlipSavePic());
|
||||||
|
M_Free(scr);
|
||||||
|
|
||||||
|
// Switch back the screen render buffers
|
||||||
|
screen->SetViewportRects(nullptr);
|
||||||
|
screen->SetSaveBuffers(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -57,8 +57,6 @@ EXTERN_CVAR(Bool, r_drawvoxels)
|
||||||
EXTERN_CVAR(Int, gl_tonemap)
|
EXTERN_CVAR(Int, gl_tonemap)
|
||||||
EXTERN_CVAR(Bool, cl_capfps)
|
EXTERN_CVAR(Bool, cl_capfps)
|
||||||
|
|
||||||
void DoWriteSavePic(FileWriter* file, ESSType ssformat, uint8_t* scr, int width, int height, sector_t* viewsector, bool upsidedown);
|
|
||||||
|
|
||||||
extern bool NoInterpolateView;
|
extern bool NoInterpolateView;
|
||||||
|
|
||||||
void gl_LoadExtensions();
|
void gl_LoadExtensions();
|
||||||
|
@ -192,59 +190,18 @@ void OpenGLFrameBuffer::Update()
|
||||||
Super::Update();
|
Super::Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
//===========================================================================
|
void OpenGLFrameBuffer::CopyScreenToBuffer(int width, int height, uint8_t* scr)
|
||||||
//
|
|
||||||
// Render the view to a savegame picture
|
|
||||||
//
|
|
||||||
//===========================================================================
|
|
||||||
|
|
||||||
void OpenGLFrameBuffer::WriteSavePic(player_t *player, FileWriter *file, int width, int height)
|
|
||||||
{
|
{
|
||||||
if (!V_IsHardwareRenderer())
|
|
||||||
{
|
|
||||||
Super::WriteSavePic(player, file, width, height);
|
|
||||||
}
|
|
||||||
else if (GLRenderer != nullptr)
|
|
||||||
{
|
|
||||||
IntRect bounds;
|
IntRect bounds;
|
||||||
bounds.left = 0;
|
bounds.left = 0;
|
||||||
bounds.top = 0;
|
bounds.top = 0;
|
||||||
bounds.width = width;
|
bounds.width = width;
|
||||||
bounds.height = height;
|
bounds.height = height;
|
||||||
|
|
||||||
// we must be sure the GPU finished reading from the buffer before we fill it with new data.
|
|
||||||
glFinish();
|
|
||||||
|
|
||||||
// Switch to render buffers dimensioned for the savepic
|
|
||||||
GLRenderer->mBuffers = GLRenderer->mSaveBuffers;
|
|
||||||
|
|
||||||
hw_ClearFakeFlat();
|
|
||||||
gl_RenderState.SetVertexBuffer(screen->mVertexData);
|
|
||||||
screen->mVertexData->Reset();
|
|
||||||
screen->mLights->Clear();
|
|
||||||
screen->mViewpoints->Clear();
|
|
||||||
|
|
||||||
// This shouldn't overwrite the global viewpoint even for a short time.
|
|
||||||
FRenderViewpoint savevp;
|
|
||||||
sector_t* viewsector = RenderViewpoint(savevp, players[consoleplayer].camera, &bounds, r_viewpoint.FieldOfView.Degrees, 1.6f, 1.6f, true, false);
|
|
||||||
glDisable(GL_STENCIL_TEST);
|
|
||||||
gl_RenderState.SetNoSoftLightLevel();
|
|
||||||
GLRenderer->CopyToBackbuffer(&bounds, false);
|
GLRenderer->CopyToBackbuffer(&bounds, false);
|
||||||
|
|
||||||
// strictly speaking not needed as the glReadPixels should block until the scene is rendered, but this is to safeguard against shitty drivers
|
// strictly speaking not needed as the glReadPixels should block until the scene is rendered, but this is to safeguard against shitty drivers
|
||||||
glFinish();
|
glFinish();
|
||||||
|
|
||||||
int numpixels = width * height;
|
|
||||||
uint8_t* scr = (uint8_t*)M_Malloc(numpixels * 3);
|
|
||||||
glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, scr);
|
glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, scr);
|
||||||
|
|
||||||
DoWriteSavePic(file, SS_RGB, scr, width, height, viewsector, true);
|
|
||||||
M_Free(scr);
|
|
||||||
|
|
||||||
// Switch back the screen render buffers
|
|
||||||
screen->SetViewportRects(nullptr);
|
|
||||||
GLRenderer->mBuffers = GLRenderer->mScreenBuffers;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
@ -549,6 +506,18 @@ void OpenGLFrameBuffer::UpdateShadowMap()
|
||||||
GLRenderer->UpdateShadowMap();
|
GLRenderer->UpdateShadowMap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OpenGLFrameBuffer::WaitForCommands(bool finish)
|
||||||
|
{
|
||||||
|
glFinish();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenGLFrameBuffer::SetSaveBuffers(bool yes)
|
||||||
|
{
|
||||||
|
if (!GLRenderer) return;
|
||||||
|
if (yes) GLRenderer->mBuffers = GLRenderer->mSaveBuffers;
|
||||||
|
else GLRenderer->mBuffers = GLRenderer->mScreenBuffers;
|
||||||
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
|
|
|
@ -32,13 +32,16 @@ public:
|
||||||
void NextEye(int eyecount) override;
|
void NextEye(int eyecount) override;
|
||||||
void SetSceneRenderTarget(bool useSSAO) override;
|
void SetSceneRenderTarget(bool useSSAO) override;
|
||||||
void UpdateShadowMap() override;
|
void UpdateShadowMap() override;
|
||||||
|
void WaitForCommands(bool finish) override;
|
||||||
|
void SetSaveBuffers(bool yes) override;
|
||||||
|
void CopyScreenToBuffer(int width, int height, uint8_t* buffer) override;
|
||||||
|
bool FlipSavePic() const override { return true; }
|
||||||
|
|
||||||
FRenderState* RenderState() override;
|
FRenderState* RenderState() override;
|
||||||
void CleanForRestart() override;
|
void CleanForRestart() override;
|
||||||
void UpdatePalette() override;
|
void UpdatePalette() override;
|
||||||
uint32_t GetCaps() override;
|
uint32_t GetCaps() override;
|
||||||
const char* DeviceName() const override;
|
const char* DeviceName() const override;
|
||||||
void WriteSavePic(player_t *player, FileWriter *file, int width, int height) override;
|
|
||||||
sector_t *RenderView(player_t *player) override;
|
sector_t *RenderView(player_t *player) override;
|
||||||
void SetTextureFilterMode() override;
|
void SetTextureFilterMode() override;
|
||||||
IHardwareTexture *CreateHardwareTexture() override;
|
IHardwareTexture *CreateHardwareTexture() override;
|
||||||
|
|
|
@ -330,3 +330,4 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
sector_t* RenderViewpoint(FRenderViewpoint& mainvp, AActor* camera, IntRect* bounds, float fov, float ratio, float fovratio, bool mainview, bool toscreen);
|
sector_t* RenderViewpoint(FRenderViewpoint& mainvp, AActor* camera, IntRect* bounds, float fov, float ratio, float fovratio, bool mainview, bool toscreen);
|
||||||
|
void WriteSavePic(player_t* player, FileWriter* file, int width, int height);
|
||||||
|
|
|
@ -53,7 +53,6 @@
|
||||||
#include "engineerrors.h"
|
#include "engineerrors.h"
|
||||||
|
|
||||||
void Draw2D(F2DDrawer *drawer, FRenderState &state);
|
void Draw2D(F2DDrawer *drawer, FRenderState &state);
|
||||||
void DoWriteSavePic(FileWriter *file, ESSType ssformat, uint8_t *scr, int width, int height, sector_t *viewsector, bool upsidedown);
|
|
||||||
|
|
||||||
EXTERN_CVAR(Bool, r_drawvoxels)
|
EXTERN_CVAR(Bool, r_drawvoxels)
|
||||||
EXTERN_CVAR(Int, gl_tonemap)
|
EXTERN_CVAR(Int, gl_tonemap)
|
||||||
|
@ -218,17 +217,6 @@ void PolyFrameBuffer::Update()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PolyFrameBuffer::WriteSavePic(player_t *player, FileWriter *file, int width, int height)
|
|
||||||
{
|
|
||||||
if (!V_IsHardwareRenderer())
|
|
||||||
{
|
|
||||||
Super::WriteSavePic(player, file, width, height);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sector_t *PolyFrameBuffer::RenderView(player_t *player)
|
sector_t *PolyFrameBuffer::RenderView(player_t *player)
|
||||||
{
|
{
|
||||||
// To do: this is virtually identical to FGLRenderer::RenderView and should be merged.
|
// To do: this is virtually identical to FGLRenderer::RenderView and should be merged.
|
||||||
|
|
|
@ -40,7 +40,6 @@ public:
|
||||||
void PrecacheMaterial(FMaterial *mat, int translation) override;
|
void PrecacheMaterial(FMaterial *mat, int translation) override;
|
||||||
void UpdatePalette() override;
|
void UpdatePalette() override;
|
||||||
uint32_t GetCaps() override;
|
uint32_t GetCaps() override;
|
||||||
void WriteSavePic(player_t *player, FileWriter *file, int width, int height) override;
|
|
||||||
sector_t *RenderView(player_t *player) override;
|
sector_t *RenderView(player_t *player) override;
|
||||||
void SetTextureFilterMode() override;
|
void SetTextureFilterMode() override;
|
||||||
void TextureFilterChanged() override;
|
void TextureFilterChanged() override;
|
||||||
|
|
|
@ -312,12 +312,6 @@ uint32_t DFrameBuffer::GetCaps()
|
||||||
return (uint32_t)FlagSet;
|
return (uint32_t)FlagSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DFrameBuffer::WriteSavePic(player_t *player, FileWriter *file, int width, int height)
|
|
||||||
{
|
|
||||||
SWRenderer->WriteSavePic(player, file, width, height);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// Calculates the viewport values needed for 2D and 3D operations
|
// Calculates the viewport values needed for 2D and 3D operations
|
||||||
|
|
|
@ -309,13 +309,18 @@ public:
|
||||||
virtual uint32_t GetCaps();
|
virtual uint32_t GetCaps();
|
||||||
virtual int Backend() { return 0; }
|
virtual int Backend() { return 0; }
|
||||||
virtual const char* DeviceName() const { return "Unknown"; }
|
virtual const char* DeviceName() const { return "Unknown"; }
|
||||||
virtual void WriteSavePic(player_t *player, FileWriter *file, int width, int height);
|
|
||||||
virtual sector_t *RenderView(player_t *player) { return nullptr; }
|
virtual sector_t *RenderView(player_t *player) { return nullptr; }
|
||||||
virtual void AmbientOccludeScene(float m5) {}
|
virtual void AmbientOccludeScene(float m5) {}
|
||||||
virtual void FirstEye() {}
|
virtual void FirstEye() {}
|
||||||
virtual void NextEye(int eyecount) {}
|
virtual void NextEye(int eyecount) {}
|
||||||
virtual void SetSceneRenderTarget(bool useSSAO) {}
|
virtual void SetSceneRenderTarget(bool useSSAO) {}
|
||||||
virtual void UpdateShadowMap() {}
|
virtual void UpdateShadowMap() {}
|
||||||
|
virtual void WaitForCommands(bool finish) {}
|
||||||
|
virtual void SetSaveBuffers(bool yes) {}
|
||||||
|
virtual void ImageTransitionScene(bool unknown) {}
|
||||||
|
virtual void CopyScreenToBuffer(int width, int height, uint8_t* buffer) { memset(buffer, 0, width* height); }
|
||||||
|
virtual bool FlipSavePic() const { return false; }
|
||||||
|
|
||||||
|
|
||||||
// Screen wiping
|
// Screen wiping
|
||||||
virtual FTexture *WipeStartScreen();
|
virtual FTexture *WipeStartScreen();
|
||||||
|
|
|
@ -61,7 +61,6 @@
|
||||||
#include "engineerrors.h"
|
#include "engineerrors.h"
|
||||||
|
|
||||||
void Draw2D(F2DDrawer *drawer, FRenderState &state);
|
void Draw2D(F2DDrawer *drawer, FRenderState &state);
|
||||||
void DoWriteSavePic(FileWriter *file, ESSType ssformat, uint8_t *scr, int width, int height, sector_t *viewsector, bool upsidedown);
|
|
||||||
|
|
||||||
EXTERN_CVAR(Bool, r_drawvoxels)
|
EXTERN_CVAR(Bool, r_drawvoxels)
|
||||||
EXTERN_CVAR(Int, gl_tonemap)
|
EXTERN_CVAR(Int, gl_tonemap)
|
||||||
|
@ -318,53 +317,6 @@ void VulkanFrameBuffer::WaitForCommands(bool finish)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VulkanFrameBuffer::WriteSavePic(player_t *player, FileWriter *file, int width, int height)
|
|
||||||
{
|
|
||||||
if (!V_IsHardwareRenderer())
|
|
||||||
{
|
|
||||||
Super::WriteSavePic(player, file, width, height);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
IntRect bounds;
|
|
||||||
bounds.left = 0;
|
|
||||||
bounds.top = 0;
|
|
||||||
bounds.width = width;
|
|
||||||
bounds.height = height;
|
|
||||||
|
|
||||||
// we must be sure the GPU finished reading from the buffer before we fill it with new data.
|
|
||||||
WaitForCommands(false);
|
|
||||||
|
|
||||||
// Switch to render buffers dimensioned for the savepic
|
|
||||||
mActiveRenderBuffers = mSaveBuffers.get();
|
|
||||||
|
|
||||||
mPostprocess->ImageTransitionScene(true);
|
|
||||||
|
|
||||||
hw_ClearFakeFlat();
|
|
||||||
GetRenderState()->SetVertexBuffer(screen->mVertexData);
|
|
||||||
screen->mVertexData->Reset();
|
|
||||||
screen->mLights->Clear();
|
|
||||||
screen->mViewpoints->Clear();
|
|
||||||
|
|
||||||
// This shouldn't overwrite the global viewpoint even for a short time.
|
|
||||||
FRenderViewpoint savevp;
|
|
||||||
sector_t *viewsector = RenderViewpoint(savevp, players[consoleplayer].camera, &bounds, r_viewpoint.FieldOfView.Degrees, 1.6f, 1.6f, true, false);
|
|
||||||
GetRenderState()->EnableStencil(false);
|
|
||||||
GetRenderState()->SetNoSoftLightLevel();
|
|
||||||
|
|
||||||
int numpixels = width * height;
|
|
||||||
uint8_t * scr = (uint8_t *)M_Malloc(numpixels * 3);
|
|
||||||
CopyScreenToBuffer(width, height, scr);
|
|
||||||
|
|
||||||
DoWriteSavePic(file, SS_RGB, scr, width, height, viewsector, false);
|
|
||||||
M_Free(scr);
|
|
||||||
|
|
||||||
// Switch back the screen render buffers
|
|
||||||
screen->SetViewportRects(nullptr);
|
|
||||||
mActiveRenderBuffers = mScreenBuffers.get();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sector_t *VulkanFrameBuffer::RenderView(player_t *player)
|
sector_t *VulkanFrameBuffer::RenderView(player_t *player)
|
||||||
{
|
{
|
||||||
// To do: this is virtually identical to FGLRenderer::RenderView and should be merged.
|
// To do: this is virtually identical to FGLRenderer::RenderView and should be merged.
|
||||||
|
@ -634,7 +586,7 @@ FTexture *VulkanFrameBuffer::WipeEndScreen()
|
||||||
return tex;
|
return tex;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VulkanFrameBuffer::CopyScreenToBuffer(int w, int h, void *data)
|
void VulkanFrameBuffer::CopyScreenToBuffer(int w, int h, uint8_t *data)
|
||||||
{
|
{
|
||||||
VkTextureImage image;
|
VkTextureImage image;
|
||||||
|
|
||||||
|
@ -866,6 +818,18 @@ void VulkanFrameBuffer::UpdateShadowMap()
|
||||||
mPostprocess->UpdateShadowMap();
|
mPostprocess->UpdateShadowMap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VulkanFrameBuffer::SetSaveBuffers(bool yes)
|
||||||
|
{
|
||||||
|
if (yes) mActiveRenderBuffers = mSaveBuffers.get();
|
||||||
|
else mActiveRenderBuffers = mScreenBuffers.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
void VulkanFrameBuffer::ImageTransitionScene(bool unknown)
|
||||||
|
{
|
||||||
|
mPostprocess->ImageTransitionScene(unknown);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
FRenderState* VulkanFrameBuffer::RenderState()
|
FRenderState* VulkanFrameBuffer::RenderState()
|
||||||
{
|
{
|
||||||
return mRenderState.get();
|
return mRenderState.get();
|
||||||
|
|
|
@ -80,7 +80,6 @@ public:
|
||||||
uint32_t GetCaps() override;
|
uint32_t GetCaps() override;
|
||||||
const char* DeviceName() const override;
|
const char* DeviceName() const override;
|
||||||
int Backend() override { return 1; }
|
int Backend() override { return 1; }
|
||||||
void WriteSavePic(player_t *player, FileWriter *file, int width, int height) override;
|
|
||||||
sector_t *RenderView(player_t *player) override;
|
sector_t *RenderView(player_t *player) override;
|
||||||
void SetTextureFilterMode() override;
|
void SetTextureFilterMode() override;
|
||||||
void TextureFilterChanged() override;
|
void TextureFilterChanged() override;
|
||||||
|
@ -91,6 +90,8 @@ public:
|
||||||
void AmbientOccludeScene(float m5) override;
|
void AmbientOccludeScene(float m5) override;
|
||||||
void SetSceneRenderTarget(bool useSSAO) override;
|
void SetSceneRenderTarget(bool useSSAO) override;
|
||||||
void UpdateShadowMap() override;
|
void UpdateShadowMap() override;
|
||||||
|
void SetSaveBuffers(bool yes) override;
|
||||||
|
void ImageTransitionScene(bool unknown) override;
|
||||||
|
|
||||||
IHardwareTexture *CreateHardwareTexture() override;
|
IHardwareTexture *CreateHardwareTexture() override;
|
||||||
FMaterial* CreateMaterial(FGameTexture* tex, int scaleflags) override;
|
FMaterial* CreateMaterial(FGameTexture* tex, int scaleflags) override;
|
||||||
|
@ -108,7 +109,7 @@ public:
|
||||||
|
|
||||||
void Draw2D() override;
|
void Draw2D() override;
|
||||||
|
|
||||||
void WaitForCommands(bool finish);
|
void WaitForCommands(bool finish) override;
|
||||||
|
|
||||||
void PushGroup(const FString &name);
|
void PushGroup(const FString &name);
|
||||||
void PopGroup();
|
void PopGroup();
|
||||||
|
@ -118,7 +119,7 @@ private:
|
||||||
void RenderTextureView(FCanvasTexture *tex, AActor *Viewpoint, double FOV);
|
void RenderTextureView(FCanvasTexture *tex, AActor *Viewpoint, double FOV);
|
||||||
void PrintStartupLog();
|
void PrintStartupLog();
|
||||||
void CreateFanToTrisIndexBuffer();
|
void CreateFanToTrisIndexBuffer();
|
||||||
void CopyScreenToBuffer(int w, int h, void *data);
|
void CopyScreenToBuffer(int w, int h, uint8_t *data) override;
|
||||||
void DeleteFrameObjects();
|
void DeleteFrameObjects();
|
||||||
void FlushCommands(VulkanCommandBuffer **commands, size_t count, bool finish, bool lastsubmit);
|
void FlushCommands(VulkanCommandBuffer **commands, size_t count, bool finish, bool lastsubmit);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue