From 469c9241eb9bf67b999835c090ef34bf14f7620d Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 20 Jun 2018 12:29:52 +0200 Subject: [PATCH] Moved WriteSavePic implementation to FGLRenderer --- src/gl/renderer/gl_renderer.cpp | 54 +++++++++++++++++++++++++++--- src/gl/scene/gl_scene.cpp | 44 ------------------------ src/hwrenderer/scene/hw_fakeflat.h | 2 +- 3 files changed, 50 insertions(+), 50 deletions(-) diff --git a/src/gl/renderer/gl_renderer.cpp b/src/gl/renderer/gl_renderer.cpp index c438f0934..c8c0fd271 100644 --- a/src/gl/renderer/gl_renderer.cpp +++ b/src/gl/renderer/gl_renderer.cpp @@ -361,14 +361,58 @@ void FGLRenderer::RenderTextureView(FCanvasTexture *tex, AActor *Viewpoint, doub tex->SetUpdated(); } -void FGLRenderer::WriteSavePic(player_t *player, FileWriter *file, int width, int height) +//=========================================================================== +// +// Render the view to a savegame picture +// +//=========================================================================== + +void FGLRenderer::WriteSavePic (player_t *player, FileWriter *file, int width, int height) { - // Todo: This needs to call the software renderer and process the returned image, if so desired. - // This also needs to take out parts of the scene drawer so they can be shared between renderers. - GLSceneDrawer drawer; - drawer.WriteSavePic(player, file, width, height); + IntRect bounds; + bounds.left = 0; + bounds.top = 0; + bounds.width = width; + bounds.height = height; + + // 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 + mBuffers = mSaveBuffers; + + P_FindParticleSubsectors(); // make sure that all recently spawned particles have a valid subsector. + gl_RenderState.SetVertexBuffer(mVBO); + mVBO->Reset(); + mLights->Clear(); + + // This shouldn't overwrite the global viewpoint even for a short time. + GLSceneDrawer drawer; + FRenderViewpoint savevp; + sector_t *viewsector = drawer.RenderViewpoint(savevp, players[consoleplayer].camera, &bounds, r_viewpoint.FieldOfView.Degrees, 1.6f, 1.6f, true, false); + glDisable(GL_STENCIL_TEST); + gl_RenderState.SetSoftLightLevel(-1); + 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 + glFinish(); + + 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, Gamma); + M_Free(scr); + + // Switch back the screen render buffers + screen->SetViewportRects(nullptr); + mBuffers = mScreenBuffers; } +//=========================================================================== +// +// +// +//=========================================================================== + void FGLRenderer::BeginFrame() { buffersActive = GLRenderer->mScreenBuffers->Setup(screen->mScreenViewport.width, screen->mScreenViewport.height, screen->mSceneViewport.width, screen->mSceneViewport.height); diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index b46aad6bd..9d758b43f 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -545,47 +545,3 @@ sector_t * GLSceneDrawer::RenderViewpoint (FRenderViewpoint &mainvp, AActor * ca return mainvp.sector; } -//=========================================================================== -// -// Render the view to a savegame picture -// -//=========================================================================== - -void GLSceneDrawer::WriteSavePic (player_t *player, FileWriter *file, int width, int height) -{ - IntRect bounds; - bounds.left = 0; - bounds.top = 0; - bounds.width = width; - bounds.height = height; - - // 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. - gl_RenderState.SetVertexBuffer(GLRenderer->mVBO); - GLRenderer->mVBO->Reset(); - GLRenderer->mLights->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.SetSoftLightLevel(-1); - 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 - glFinish(); - - 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, Gamma); - M_Free(scr); - - // Switch back the screen render buffers - screen->SetViewportRects(nullptr); - GLRenderer->mBuffers = GLRenderer->mScreenBuffers; -} diff --git a/src/hwrenderer/scene/hw_fakeflat.h b/src/hwrenderer/scene/hw_fakeflat.h index 8e5b9dfec..c56f3798d 100644 --- a/src/hwrenderer/scene/hw_fakeflat.h +++ b/src/hwrenderer/scene/hw_fakeflat.h @@ -9,7 +9,7 @@ enum area_t : int }; -// Global functions. Make them members of GLRenderer later? +// Global functions. bool hw_CheckClip(side_t * sidedef, sector_t * frontsector, sector_t * backsector); sector_t * hw_FakeFlat(sector_t * sec, sector_t * dest, area_t in_area, bool back); area_t hw_CheckViewArea(vertex_t *v1, vertex_t *v2, sector_t *frontsector, sector_t *backsector);