- fix gamepic render buffer issues

This commit is contained in:
Magnus Norddahl 2018-06-03 13:59:40 +02:00
parent dea1d0259d
commit f03c02df43
9 changed files with 40 additions and 25 deletions

View file

@ -82,9 +82,6 @@
static FRandom pr_dmspawn ("DMSpawn"); static FRandom pr_dmspawn ("DMSpawn");
static FRandom pr_pspawn ("PlayerSpawn"); static FRandom pr_pspawn ("PlayerSpawn");
const int SAVEPICWIDTH = 216;
const int SAVEPICHEIGHT = 162;
bool G_CheckDemoStatus (void); bool G_CheckDemoStatus (void);
void G_ReadDemoTiccmd (ticcmd_t *cmd, int player); void G_ReadDemoTiccmd (ticcmd_t *cmd, int player);
void G_WriteDemoTiccmd (ticcmd_t *cmd, int player, int buf); void G_WriteDemoTiccmd (ticcmd_t *cmd, int player, int buf);

View file

@ -102,5 +102,7 @@ class AInventory;
extern const AInventory *SendItemUse, *SendItemDrop; extern const AInventory *SendItemUse, *SendItemDrop;
extern int SendItemDropAmount; extern int SendItemDropAmount;
const int SAVEPICWIDTH = 216;
const int SAVEPICHEIGHT = 162;
#endif #endif

View file

@ -35,6 +35,7 @@
#include "p_effect.h" #include "p_effect.h"
#include "d_player.h" #include "d_player.h"
#include "a_dynlight.h" #include "a_dynlight.h"
#include "g_game.h"
#include "swrenderer/r_swscene.h" #include "swrenderer/r_swscene.h"
#include "hwrenderer/utility/hw_clock.h" #include "hwrenderer/utility/hw_clock.h"
@ -96,6 +97,8 @@ FGLRenderer::FGLRenderer(OpenGLFrameBuffer *fb)
mLights = nullptr; mLights = nullptr;
mTonemapPalette = nullptr; mTonemapPalette = nullptr;
mBuffers = nullptr; mBuffers = nullptr;
mScreenBuffers = nullptr;
mSaveBuffers = nullptr;
mPresentShader = nullptr; mPresentShader = nullptr;
mPresent3dCheckerShader = nullptr; mPresent3dCheckerShader = nullptr;
mPresent3dColumnShader = nullptr; mPresent3dColumnShader = nullptr;
@ -122,7 +125,9 @@ FGLRenderer::FGLRenderer(OpenGLFrameBuffer *fb)
void FGLRenderer::Initialize(int width, int height) void FGLRenderer::Initialize(int width, int height)
{ {
mBuffers = new FGLRenderBuffers(); mScreenBuffers = new FGLRenderBuffers();
mSaveBuffers = new FGLRenderBuffers();
mBuffers = mScreenBuffers;
mLinearDepthShader = new FLinearDepthShader(); mLinearDepthShader = new FLinearDepthShader();
mDepthBlurShader = new FDepthBlurShader(); mDepthBlurShader = new FDepthBlurShader();
mSSAOShader = new FSSAOShader(); mSSAOShader = new FSSAOShader();
@ -400,7 +405,9 @@ void FGLRenderer::WriteSavePic(player_t *player, FileWriter *file, int width, in
void FGLRenderer::BeginFrame() void FGLRenderer::BeginFrame()
{ {
buffersActive = GLRenderer->mBuffers->Setup(screen->mScreenViewport.width, screen->mScreenViewport.height, screen->mSceneViewport.width, screen->mSceneViewport.height); buffersActive = GLRenderer->mScreenBuffers->Setup(screen->mScreenViewport.width, screen->mScreenViewport.height, screen->mSceneViewport.width, screen->mSceneViewport.height);
if (buffersActive)
buffersActive = GLRenderer->mSaveBuffers->Setup(SAVEPICWIDTH, SAVEPICHEIGHT, SAVEPICWIDTH, SAVEPICHEIGHT);
} }
//=========================================================================== //===========================================================================

View file

@ -100,6 +100,8 @@ public:
int mOldFBID; int mOldFBID;
FGLRenderBuffers *mBuffers; FGLRenderBuffers *mBuffers;
FGLRenderBuffers *mScreenBuffers;
FGLRenderBuffers *mSaveBuffers;
FLinearDepthShader *mLinearDepthShader; FLinearDepthShader *mLinearDepthShader;
FSSAOShader *mSSAOShader; FSSAOShader *mSSAOShader;
FDepthBlurShader *mDepthBlurShader; FDepthBlurShader *mDepthBlurShader;

View file

@ -656,7 +656,7 @@ sector_t * GLSceneDrawer::RenderViewpoint (AActor * camera, IntRect * bounds, fl
SetFixedColormap(camera->player); // reiterate color map for each eye, so night vision goggles work in both eyes SetFixedColormap(camera->player); // reiterate color map for each eye, so night vision goggles work in both eyes
const s3d::EyePose * eye = stereo3dMode.getEyePose(eye_ix); const s3d::EyePose * eye = stereo3dMode.getEyePose(eye_ix);
eye->SetUp(); eye->SetUp();
screen->SetOutputViewport(bounds); screen->SetViewportRects(bounds);
Set3DViewport(mainview); Set3DViewport(mainview);
GLRenderer->mDrawingScene2D = true; GLRenderer->mDrawingScene2D = true;
GLRenderer->mCurrentFoV = fov; GLRenderer->mCurrentFoV = fov;
@ -713,20 +713,24 @@ sector_t * GLSceneDrawer::RenderViewpoint (AActor * camera, IntRect * bounds, fl
void GLSceneDrawer::WriteSavePic (player_t *player, FileWriter *file, int width, int height) void GLSceneDrawer::WriteSavePic (player_t *player, FileWriter *file, int width, int height)
{ {
IntRect bounds; IntRect bounds;
P_FindParticleSubsectors(); // make sure that all recently spawned particles have a valid subsector.
bounds.left = 0; bounds.left = 0;
bounds.top = 0; bounds.top = 0;
bounds.width = width; bounds.width = width;
bounds.height = height; bounds.height = height;
glFlush();
// if GLRenderer->mVBO is persistently mapped we must be sure the GPU finished reading from it before we fill it with new data.
glFinish();
// Switch to render buffers dimensioned for the savepic
GLRenderer->mBuffers = GLRenderer->mSaveBuffers;
P_FindParticleSubsectors(); // make sure that all recently spawned particles have a valid subsector.
SetFixedColormap(player); SetFixedColormap(player);
gl_RenderState.SetVertexBuffer(GLRenderer->mVBO); gl_RenderState.SetVertexBuffer(GLRenderer->mVBO);
GLRenderer->mVBO->Reset(); GLRenderer->mVBO->Reset();
if (!gl.legacyMode) GLRenderer->mLights->Clear(); if (!gl.legacyMode) GLRenderer->mLights->Clear();
sector_t *viewsector = RenderViewpoint(players[consoleplayer].camera, &bounds, sector_t *viewsector = RenderViewpoint(players[consoleplayer].camera, &bounds, r_viewpoint.FieldOfView.Degrees, 1.6f, 1.6f, true, false);
r_viewpoint.FieldOfView.Degrees, 1.6f, 1.6f, true, false);
glDisable(GL_STENCIL_TEST); glDisable(GL_STENCIL_TEST);
gl_RenderState.SetFixedColormap(CM_DEFAULT); gl_RenderState.SetFixedColormap(CM_DEFAULT);
gl_RenderState.SetSoftLightLevel(-1); gl_RenderState.SetSoftLightLevel(-1);
@ -737,12 +741,16 @@ void GLSceneDrawer::WriteSavePic (player_t *player, FileWriter *file, int width,
screen->Draw2D(); screen->Draw2D();
} }
GLRenderer->CopyToBackbuffer(&bounds, false); GLRenderer->CopyToBackbuffer(&bounds, false);
glFlush();
screen->SetOutputViewport(nullptr); // 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); uint8_t * scr = (uint8_t *)M_Malloc(width * height * 3);
glReadPixels(0,0,width, height,GL_RGB,GL_UNSIGNED_BYTE,scr); 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); M_CreatePNG (file, scr + ((height-1) * width * 3), NULL, SS_RGB, width, height, -width * 3, Gamma);
M_Free(scr); M_Free(scr);
// Switch back the screen render buffers
screen->SetViewportRects(nullptr);
GLRenderer->mBuffers = GLRenderer->mScreenBuffers;
} }

View file

@ -136,7 +136,7 @@ void OpenGLFrameBuffer::InitializeState()
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
GLRenderer->Initialize(GetWidth(), GetHeight()); GLRenderer->Initialize(GetWidth(), GetHeight());
SetOutputViewport(nullptr); SetViewportRects(nullptr);
} }
//========================================================================== //==========================================================================
@ -164,14 +164,11 @@ void OpenGLFrameBuffer::Update()
int clientHeight = ViewportScaledHeight(initialWidth, initialHeight); int clientHeight = ViewportScaledHeight(initialWidth, initialHeight);
if (clientWidth > 0 && clientHeight > 0 && (Width != clientWidth || Height != clientHeight)) if (clientWidth > 0 && clientHeight > 0 && (Width != clientWidth || Height != clientHeight))
{ {
// Do not call Resize here because it's only for software canvases
Width = clientWidth; Width = clientWidth;
Height = clientHeight; Height = clientHeight;
V_OutputResized(Width, Height); V_OutputResized(Width, Height);
GLRenderer->mVBO->OutputResized(Width, Height); GLRenderer->mVBO->OutputResized(Width, Height);
} }
SetOutputViewport(nullptr);
} }
//=========================================================================== //===========================================================================
@ -392,9 +389,10 @@ bool OpenGLFrameBuffer::RenderBuffersEnabled()
return FGLRenderBuffers::IsEnabled(); return FGLRenderBuffers::IsEnabled();
} }
void OpenGLFrameBuffer::SetOutputViewport(IntRect *bounds) void OpenGLFrameBuffer::SetViewportRects(IntRect *bounds)
{ {
Super::SetOutputViewport(bounds); Super::SetViewportRects(bounds);
if (!bounds)
s3d::Stereo3DMode::getCurrentMode().AdjustViewports(); s3d::Stereo3DMode::getCurrentMode().AdjustViewports();
} }
@ -431,6 +429,7 @@ void OpenGLFrameBuffer::SetClearColor(int color)
void OpenGLFrameBuffer::BeginFrame() void OpenGLFrameBuffer::BeginFrame()
{ {
SetViewportRects(nullptr);
if (GLRenderer != nullptr) if (GLRenderer != nullptr)
GLRenderer->BeginFrame(); GLRenderer->BeginFrame();
} }

View file

@ -42,7 +42,7 @@ public:
void ResetFixedColormap() override; void ResetFixedColormap() override;
void BeginFrame() override; void BeginFrame() override;
bool RenderBuffersEnabled() override; bool RenderBuffersEnabled() override;
void SetOutputViewport(IntRect *bounds) override; void SetViewportRects(IntRect *bounds) override;
void BlurScene(float amount) override; void BlurScene(float amount) override;
// Retrieves a buffer containing image data for a screenshot. // Retrieves a buffer containing image data for a screenshot.

View file

@ -1005,7 +1005,7 @@ void DFrameBuffer::WriteSavePic(player_t *player, FileWriter *file, int width, i
// //
//========================================================================== //==========================================================================
void DFrameBuffer::SetOutputViewport(IntRect *bounds) void DFrameBuffer::SetViewportRects(IntRect *bounds)
{ {
if (bounds) if (bounds)
{ {

View file

@ -501,7 +501,7 @@ public:
// Calculate gamma table // Calculate gamma table
void CalcGamma(float gamma, uint8_t gammalookup[256]); void CalcGamma(float gamma, uint8_t gammalookup[256]);
virtual void SetOutputViewport(IntRect *bounds); virtual void SetViewportRects(IntRect *bounds);
int ScreenToWindowX(int x); int ScreenToWindowX(int x);
int ScreenToWindowY(int y); int ScreenToWindowY(int y);