From 7709db4bb08a68073939d21fb904d7e99ad1c398 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Sun, 31 Jul 2016 16:23:21 +0200 Subject: [PATCH] Fix broken viewport/backbuffer location for WriteSavePic --- src/gl/data/gl_vertexbuffer.h | 10 +++ src/gl/renderer/gl_postprocess.cpp | 122 +++++++++++--------------- src/gl/renderer/gl_renderbuffers.h | 3 + src/gl/renderer/gl_renderer.h | 5 +- src/gl/scene/gl_scene.cpp | 9 +- src/gl/shaders/gl_presentshader.cpp | 1 + wadsrc/static/shaders/glsl/present.vp | 3 +- 7 files changed, 74 insertions(+), 79 deletions(-) diff --git a/src/gl/data/gl_vertexbuffer.h b/src/gl/data/gl_vertexbuffer.h index b88cc6ca1..eeb3ace48 100644 --- a/src/gl/data/gl_vertexbuffer.h +++ b/src/gl/data/gl_vertexbuffer.h @@ -105,6 +105,16 @@ public: if (pcount) *pcount = count; } + void RenderScreenQuad(float maxU = 1.0f, float maxV = 1.0f) + { + FFlatVertex *ptr = GetBuffer(); + ptr->Set(-1.0f, -1.0f, 0, 0.0f, 0.0f); ptr++; + ptr->Set(-1.0f, 1.0f, 0, 0.0f, maxV); ptr++; + ptr->Set(1.0f, -1.0f, 0, maxU, 0.0f); ptr++; + ptr->Set(1.0f, 1.0f, 0, maxU, maxV); ptr++; + RenderCurrent(ptr, GL_TRIANGLE_STRIP); + } + #endif void Reset() { diff --git a/src/gl/renderer/gl_postprocess.cpp b/src/gl/renderer/gl_postprocess.cpp index e13acda4a..1f937be55 100644 --- a/src/gl/renderer/gl_postprocess.cpp +++ b/src/gl/renderer/gl_postprocess.cpp @@ -145,14 +145,7 @@ void FGLRenderer::BloomScene() mBloomExtractShader->Bind(); mBloomExtractShader->SceneTexture.Set(0); mBloomExtractShader->Exposure.Set(mCameraExposure); - { - FFlatVertex *ptr = mVBO->GetBuffer(); - ptr->Set(-1.0f, -1.0f, 0, 0.0f, 0.0f); ptr++; - ptr->Set(-1.0f, 1.0f, 0, 0.0f, 1.0f); ptr++; - ptr->Set(1.0f, -1.0f, 0, 1.0f, 0.0f); ptr++; - ptr->Set(1.0f, 1.0f, 0, 1.0f, 1.0f); ptr++; - mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP); - } + mVBO->RenderScreenQuad(); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); @@ -183,14 +176,7 @@ void FGLRenderer::BloomScene() glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); mBloomCombineShader->Bind(); mBloomCombineShader->BloomTexture.Set(0); - { - FFlatVertex *ptr = mVBO->GetBuffer(); - ptr->Set(-1.0f, -1.0f, 0, 0.0f, 0.0f); ptr++; - ptr->Set(-1.0f, 1.0f, 0, 0.0f, 1.0f); ptr++; - ptr->Set(1.0f, -1.0f, 0, 1.0f, 0.0f); ptr++; - ptr->Set(1.0f, 1.0f, 0, 1.0f, 1.0f); ptr++; - mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP); - } + mVBO->RenderScreenQuad(); } mBlurShader->BlurHorizontal(mVBO, blurAmount, sampleCount, level0.VTexture, level0.HFramebuffer, level0.Width, level0.Height); @@ -208,14 +194,7 @@ void FGLRenderer::BloomScene() glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); mBloomCombineShader->Bind(); mBloomCombineShader->BloomTexture.Set(0); - { - FFlatVertex *ptr = mVBO->GetBuffer(); - ptr->Set(-1.0f, -1.0f, 0, 0.0f, 0.0f); ptr++; - ptr->Set(-1.0f, 1.0f, 0, 0.0f, 1.0f); ptr++; - ptr->Set(1.0f, -1.0f, 0, 1.0f, 0.0f); ptr++; - ptr->Set(1.0f, 1.0f, 0, 1.0f, 1.0f); ptr++; - mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP); - } + mVBO->RenderScreenQuad(); if (blendEnabled) glEnable(GL_BLEND); @@ -263,13 +242,7 @@ void FGLRenderer::TonemapScene() mTonemapShader->Bind(); mTonemapShader->SceneTexture.Set(0); mTonemapShader->Exposure.Set(mCameraExposure); - - FFlatVertex *ptr = mVBO->GetBuffer(); - ptr->Set(-1.0f, -1.0f, 0, 0.0f, 0.0f); ptr++; - ptr->Set(-1.0f, 1.0f, 0, 0.0f, 1.0f); ptr++; - ptr->Set(1.0f, -1.0f, 0, 1.0f, 0.0f); ptr++; - ptr->Set(1.0f, 1.0f, 0, 1.0f, 1.0f); ptr++; - mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP); + mVBO->RenderScreenQuad(); if (blendEnabled) glEnable(GL_BLEND); @@ -287,7 +260,7 @@ void FGLRenderer::TonemapScene() // //----------------------------------------------------------------------------- -void FGLRenderer::Flush() +void FGLRenderer::CopyToBackbuffer(const GL_IRECT *bounds) { if (FGLRenderBuffers::IsEnabled()) { @@ -311,40 +284,51 @@ void FGLRenderer::Flush() mBuffers->BindOutputFB(); - // Calculate letterbox - int clientWidth = framebuffer->GetClientWidth(); - int clientHeight = framebuffer->GetClientHeight(); - float scaleX = clientWidth / (float)mOutputViewport.width; - float scaleY = clientHeight / (float)mOutputViewport.height; - float scale = MIN(scaleX, scaleY); - int width = (int)round(mOutputViewport.width * scale); - int height = (int)round(mOutputViewport.height * scale); - int x = (clientWidth - width) / 2; - int y = (clientHeight - height) / 2; + int x, y, width, height; + if (bounds) + { + x = bounds->left; + y = bounds->top; + width = bounds->width; + height = bounds->height; + } + else + { + // Calculate letterbox + int clientWidth = framebuffer->GetClientWidth(); + int clientHeight = framebuffer->GetClientHeight(); + float scaleX = clientWidth / (float)mScreenViewport.width; + float scaleY = clientHeight / (float)mScreenViewport.height; + float scale = MIN(scaleX, scaleY); + width = (int)round(mScreenViewport.width * scale); + height = (int)round(mScreenViewport.height * scale); + x = (clientWidth - width) / 2; + y = (clientHeight - height) / 2; - // Black bars around the box: - glViewport(0, 0, clientWidth, clientHeight); - glClearColor(0.0f, 0.0f, 0.0f, 1.0f); - glEnable(GL_SCISSOR_TEST); - if (y > 0) - { - glScissor(0, 0, clientWidth, y); - glClear(GL_COLOR_BUFFER_BIT); - } - if (clientHeight - y - height > 0) - { - glScissor(0, y + height, clientWidth, clientHeight - y - height); - glClear(GL_COLOR_BUFFER_BIT); - } - if (x > 0) - { - glScissor(0, y, x, height); - glClear(GL_COLOR_BUFFER_BIT); - } - if (clientWidth - x - width > 0) - { - glScissor(x + width, y, clientWidth - x - width, height); - glClear(GL_COLOR_BUFFER_BIT); + // Black bars around the box: + glViewport(0, 0, clientWidth, clientHeight); + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); + glEnable(GL_SCISSOR_TEST); + if (y > 0) + { + glScissor(0, 0, clientWidth, y); + glClear(GL_COLOR_BUFFER_BIT); + } + if (clientHeight - y - height > 0) + { + glScissor(0, y + height, clientWidth, clientHeight - y - height); + glClear(GL_COLOR_BUFFER_BIT); + } + if (x > 0) + { + glScissor(0, y, x, height); + glClear(GL_COLOR_BUFFER_BIT); + } + if (clientWidth - x - width > 0) + { + glScissor(x + width, y, clientWidth - x - width, height); + glClear(GL_COLOR_BUFFER_BIT); + } } glDisable(GL_SCISSOR_TEST); @@ -367,13 +351,7 @@ void FGLRenderer::Flush() mPresentShader->Brightness.Set(clamp(vid_brightness, -0.8f, 0.8f)); } mBuffers->BindHudTexture(0); - - FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer(); - ptr->Set(-1.0f, -1.0f, 0, 0.0f, 0.0f); ptr++; - ptr->Set(-1.0f, 1.0f, 0, 0.0f, 1.0f); ptr++; - ptr->Set(1.0f, -1.0f, 0, 1.0f, 0.0f); ptr++; - ptr->Set(1.0f, 1.0f, 0, 1.0f, 1.0f); ptr++; - GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP); + mVBO->RenderScreenQuad(width / (float)mBuffers->GetWidth(), height / (float)mBuffers->GetHeight()); if (blendEnabled) glEnable(GL_BLEND); diff --git a/src/gl/renderer/gl_renderbuffers.h b/src/gl/renderer/gl_renderbuffers.h index b4765b544..37bbdc2e5 100644 --- a/src/gl/renderer/gl_renderbuffers.h +++ b/src/gl/renderer/gl_renderbuffers.h @@ -34,6 +34,9 @@ public: static bool IsEnabled(); + int GetWidth() const { return mWidth; } + int GetHeight() const { return mHeight; } + private: void ClearScene(); void ClearHud(); diff --git a/src/gl/renderer/gl_renderer.h b/src/gl/renderer/gl_renderer.h index 150d23f6a..3fd2afa86 100644 --- a/src/gl/renderer/gl_renderer.h +++ b/src/gl/renderer/gl_renderer.h @@ -118,7 +118,7 @@ public: angle_t FrustumAngle(); void SetViewArea(); void SetOutputViewport(GL_IRECT *bounds); - void Set3DViewport(bool toscreen); + void Set3DViewport(bool mainview); void Reset3DViewport(); sector_t *RenderViewpoint (AActor * camera, GL_IRECT * bounds, float fov, float ratio, float fovratio, bool mainview, bool toscreen); void RenderView(player_t *player); @@ -160,7 +160,8 @@ public: void EndDrawScene(sector_t * viewsector); void BloomScene(); void TonemapScene(); - void Flush(); + void CopyToBackbuffer(const GL_IRECT *bounds); + void Flush() { CopyToBackbuffer(nullptr); } void SetProjection(float fov, float ratio, float fovratio); void SetProjection(VSMatrix matrix); // raw matrix input from stereo 3d modes diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index d0a9e23b9..734257c8c 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -166,9 +166,9 @@ void FGLRenderer::Reset3DViewport() // //----------------------------------------------------------------------------- -void FGLRenderer::Set3DViewport(bool toscreen) +void FGLRenderer::Set3DViewport(bool mainview) { - if (toscreen && FGLRenderBuffers::IsEnabled()) + if (mainview && FGLRenderBuffers::IsEnabled()) { mBuffers->Setup(mOutputViewport.width, mOutputViewport.height); mBuffers->BindSceneFB(); @@ -840,7 +840,7 @@ sector_t * FGLRenderer::RenderViewpoint (AActor * camera, GL_IRECT * bounds, flo eye->SetUp(); // TODO: stereo specific viewport - needed when implementing side-by-side modes etc. SetOutputViewport(bounds); - Set3DViewport(toscreen); + Set3DViewport(mainview); mDrawingScene2D = true; mCurrentFoV = fov; // Stereo mode specific perspective projection @@ -859,7 +859,7 @@ sector_t * FGLRenderer::RenderViewpoint (AActor * camera, GL_IRECT * bounds, flo ProcessScene(toscreen); if (mainview) EndDrawScene(retval); // do not call this for camera textures. - if (toscreen) + if (mainview) { if (FGLRenderBuffers::IsEnabled()) mBuffers->BlitSceneToTexture(); BloomScene(); @@ -976,6 +976,7 @@ void FGLRenderer::WriteSavePic (player_t *player, FILE *file, int width, int hei gl_RenderState.SetSoftLightLevel(-1); screen->Begin2D(false); DrawBlend(viewsector); + CopyToBackbuffer(&bounds); glFlush(); byte * scr = (byte *)M_Malloc(width * height * 3); diff --git a/src/gl/shaders/gl_presentshader.cpp b/src/gl/shaders/gl_presentshader.cpp index 0ebfc9945..2f9642458 100644 --- a/src/gl/shaders/gl_presentshader.cpp +++ b/src/gl/shaders/gl_presentshader.cpp @@ -58,6 +58,7 @@ void FPresentShader::Bind() mShader.SetFragDataLocation(0, "FragColor"); mShader.Link("shaders/glsl/present"); mShader.SetAttribLocation(0, "PositionInProjection"); + mShader.SetAttribLocation(1, "UV"); InputTexture.Init(mShader, "InputTexture"); Gamma.Init(mShader, "Gamma"); Contrast.Init(mShader, "Contrast"); diff --git a/wadsrc/static/shaders/glsl/present.vp b/wadsrc/static/shaders/glsl/present.vp index 5990669a5..fea7e25ad 100644 --- a/wadsrc/static/shaders/glsl/present.vp +++ b/wadsrc/static/shaders/glsl/present.vp @@ -1,9 +1,10 @@ in vec4 PositionInProjection; +in vec2 UV; out vec2 TexCoord; void main() { gl_Position = PositionInProjection; - TexCoord = PositionInProjection.xy * 0.5 + 0.5; + TexCoord = UV; }