- moved viewport code to DFrameBuffer.

This commit is contained in:
Christoph Oelckers 2018-05-12 17:23:56 +02:00
parent f17f8c9359
commit c2a7a4bf30
16 changed files with 244 additions and 207 deletions

View file

@ -60,7 +60,7 @@ void FShadowMap::Update()
glViewport(0, 0, gl_shadowmap_quality, 1024);
GLRenderer->RenderScreenQuad();
const auto &viewport = GLRenderer->mScreenViewport;
const auto &viewport = screen->mScreenViewport;
glViewport(viewport.left, viewport.top, viewport.width, viewport.height);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, 0);

View file

@ -187,6 +187,9 @@ void FGLRenderer::AmbientOccludeScene()
float blurSharpness = 1.0f / blurAmount;
const auto &mSceneViewport = screen->mSceneViewport;
const auto &mScreenViewport = screen->mScreenViewport;
float sceneScaleX = mSceneViewport.width / (float)mScreenViewport.width;
float sceneScaleY = mSceneViewport.height / (float)mScreenViewport.height;
float sceneOffsetX = mSceneViewport.left / (float)mScreenViewport.width;
@ -254,7 +257,7 @@ void FGLRenderer::AmbientOccludeScene()
// Add SSAO back to scene texture:
mBuffers->BindSceneFB(false);
glViewport(mSceneViewport.left, mSceneViewport.top, mSceneViewport.width, mSceneViewport.height);
glViewport(screen->mSceneViewport.left, screen->mSceneViewport.top, screen->mSceneViewport.width, screen->mSceneViewport.height);
glEnable(GL_BLEND);
glBlendEquation(GL_FUNC_ADD);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
@ -292,6 +295,9 @@ void FGLRenderer::UpdateCameraExposure()
FGLPostProcessState savedState;
savedState.SaveTextureBindings(2);
const auto &mSceneViewport = screen->mSceneViewport;
const auto &mScreenViewport = screen->mScreenViewport;
// Extract light level from scene texture:
auto &level0 = mBuffers->ExposureLevels[0];
level0.Framebuffer.Bind();
@ -365,6 +371,9 @@ void FGLRenderer::BloomScene(int fixedcm)
auto &level0 = mBuffers->BloomLevels[0];
const auto &mSceneViewport = screen->mSceneViewport;
const auto &mScreenViewport = screen->mScreenViewport;
// Extract blooming pixels from scene texture:
level0.VFramebuffer.Bind();
glViewport(0, 0, level0.Width, level0.Height);
@ -450,7 +459,7 @@ void FGLRenderer::BlurScene(float gameinfobluramount)
int numLevels = 3; // Must be 4 or less (since FGLRenderBuffers::NumBloomLevels is 4 and we are using its buffers).
assert(numLevels <= FGLRenderBuffers::NumBloomLevels);
const auto &viewport = mScreenViewport; // The area we want to blur. Could also be mSceneViewport if only the scene area is to be blured
const auto &viewport = screen->mScreenViewport; // The area we want to blur. Could also be mSceneViewport if only the scene area is to be blured
const auto &level0 = mBuffers->BloomLevels[0];
@ -490,7 +499,7 @@ void FGLRenderer::BlurScene(float gameinfobluramount)
// Copy blur back to scene texture:
mBuffers->BlitLinear(level0.VFramebuffer, mBuffers->GetCurrentFB(), 0, 0, level0.Width, level0.Height, viewport.left, viewport.top, viewport.width, viewport.height);
glViewport(mScreenViewport.left, mScreenViewport.top, mScreenViewport.width, mScreenViewport.height);
glViewport(viewport.left, viewport.top, viewport.width, viewport.height);
FGLDebug::PopGroup();
}
@ -639,7 +648,7 @@ void FGLRenderer::LensDistortScene()
0.0f
};
float aspect = mSceneViewport.width / (float)mSceneViewport.height;
float aspect = screen->mSceneViewport.width / (float)screen->mSceneViewport.height;
// Scale factor to keep sampling within the input texture
float r2 = aspect * aspect * 0.25 + 0.25f;
@ -715,6 +724,8 @@ void FGLRenderer::ApplyFXAA()
void FGLRenderer::Flush()
{
const s3d::Stereo3DMode& stereo3dMode = s3d::Stereo3DMode::getCurrentMode();
const auto &mSceneViewport = screen->mSceneViewport;
const auto &mScreenViewport = screen->mScreenViewport;
if (stereo3dMode.IsMono() || !FGLRenderBuffers::IsEnabled())
{
@ -747,7 +758,7 @@ void FGLRenderer::Flush()
//
//-----------------------------------------------------------------------------
void FGLRenderer::CopyToBackbuffer(const GL_IRECT *bounds, bool applyGamma)
void FGLRenderer::CopyToBackbuffer(const IntRect *bounds, bool applyGamma)
{
screen->Draw2D(); // draw all pending 2D stuff before copying the buffer
screen->Clear2D();
@ -760,7 +771,7 @@ void FGLRenderer::CopyToBackbuffer(const GL_IRECT *bounds, bool applyGamma)
FGLPostProcessState savedState;
mBuffers->BindOutputFB();
GL_IRECT box;
IntRect box;
if (bounds)
{
box = *bounds;
@ -768,7 +779,7 @@ void FGLRenderer::CopyToBackbuffer(const GL_IRECT *bounds, bool applyGamma)
else
{
ClearBorders();
box = mOutputLetterbox;
box = screen->mOutputLetterbox;
}
mBuffers->BindCurrentTexture(0);
@ -782,7 +793,7 @@ void FGLRenderer::CopyToBackbuffer(const GL_IRECT *bounds, bool applyGamma)
FGLDebug::PopGroup();
}
void FGLRenderer::DrawPresentTexture(const GL_IRECT &box, bool applyGamma)
void FGLRenderer::DrawPresentTexture(const IntRect &box, bool applyGamma)
{
glViewport(box.left, box.top, box.width, box.height);
@ -815,7 +826,7 @@ void FGLRenderer::DrawPresentTexture(const GL_IRECT &box, bool applyGamma)
mPresentShader->Saturation.Set(clamp<float>(vid_saturation, -15.0f, 15.f));
mPresentShader->GrayFormula.Set(static_cast<int>(gl_satformula));
}
mPresentShader->Scale.Set(mScreenViewport.width / (float)mBuffers->GetWidth(), mScreenViewport.height / (float)mBuffers->GetHeight());
mPresentShader->Scale.Set(screen->mScreenViewport.width / (float)mBuffers->GetWidth(), screen->mScreenViewport.height / (float)mBuffers->GetHeight());
RenderScreenQuad();
}
@ -827,7 +838,7 @@ void FGLRenderer::DrawPresentTexture(const GL_IRECT &box, bool applyGamma)
void FGLRenderer::ClearBorders()
{
const auto &box = mOutputLetterbox;
const auto &box = screen->mOutputLetterbox;
int clientWidth = framebuffer->GetClientWidth();
int clientHeight = framebuffer->GetClientHeight();

View file

@ -67,7 +67,6 @@
EXTERN_CVAR(Int, screenblocks)
EXTERN_CVAR(Bool, cl_capfps)
CVAR(Bool, gl_scale_viewport, true, CVAR_ARCHIVE);
extern bool NoInterpolateView;
//===========================================================================
@ -225,117 +224,6 @@ FGLRenderer::~FGLRenderer()
delete mFXAALumaShader;
}
//==========================================================================
//
// Calculates the viewport values needed for 2D and 3D operations
//
//==========================================================================
void FGLRenderer::SetOutputViewport(GL_IRECT *bounds)
{
if (bounds)
{
mSceneViewport = *bounds;
mScreenViewport = *bounds;
mOutputLetterbox = *bounds;
return;
}
// Special handling so the view with a visible status bar displays properly
int height, width;
if (screenblocks >= 10)
{
height = framebuffer->GetHeight();
width = framebuffer->GetWidth();
}
else
{
height = (screenblocks*framebuffer->GetHeight() / 10) & ~7;
width = (screenblocks*framebuffer->GetWidth() / 10);
}
// Back buffer letterbox for the final output
int clientWidth = framebuffer->GetClientWidth();
int clientHeight = framebuffer->GetClientHeight();
if (clientWidth == 0 || clientHeight == 0)
{
// When window is minimized there may not be any client area.
// Pretend to the rest of the render code that we just have a very small window.
clientWidth = 160;
clientHeight = 120;
}
int screenWidth = framebuffer->GetWidth();
int screenHeight = framebuffer->GetHeight();
float scaleX, scaleY;
if (ViewportIsScaled43())
{
scaleX = MIN(clientWidth / (float)screenWidth, clientHeight / (screenHeight * 1.2f));
scaleY = scaleX * 1.2f;
}
else
{
scaleX = MIN(clientWidth / (float)screenWidth, clientHeight / (float)screenHeight);
scaleY = scaleX;
}
mOutputLetterbox.width = (int)round(screenWidth * scaleX);
mOutputLetterbox.height = (int)round(screenHeight * scaleY);
mOutputLetterbox.left = (clientWidth - mOutputLetterbox.width) / 2;
mOutputLetterbox.top = (clientHeight - mOutputLetterbox.height) / 2;
// The entire renderable area, including the 2D HUD
mScreenViewport.left = 0;
mScreenViewport.top = 0;
mScreenViewport.width = screenWidth;
mScreenViewport.height = screenHeight;
// Viewport for the 3D scene
mSceneViewport.left = viewwindowx;
mSceneViewport.top = screenHeight - (height + viewwindowy - ((height - viewheight) / 2));
mSceneViewport.width = viewwidth;
mSceneViewport.height = height;
// Scale viewports to fit letterbox
bool notScaled = ((mScreenViewport.width == ViewportScaledWidth(mScreenViewport.width, mScreenViewport.height)) &&
(mScreenViewport.width == ViewportScaledHeight(mScreenViewport.width, mScreenViewport.height)) &&
!ViewportIsScaled43());
if ((gl_scale_viewport && !framebuffer->IsFullscreen() && notScaled) || !FGLRenderBuffers::IsEnabled())
{
mScreenViewport.width = mOutputLetterbox.width;
mScreenViewport.height = mOutputLetterbox.height;
mSceneViewport.left = (int)round(mSceneViewport.left * scaleX);
mSceneViewport.top = (int)round(mSceneViewport.top * scaleY);
mSceneViewport.width = (int)round(mSceneViewport.width * scaleX);
mSceneViewport.height = (int)round(mSceneViewport.height * scaleY);
// Without render buffers we have to render directly to the letterbox
if (!FGLRenderBuffers::IsEnabled())
{
mScreenViewport.left += mOutputLetterbox.left;
mScreenViewport.top += mOutputLetterbox.top;
mSceneViewport.left += mOutputLetterbox.left;
mSceneViewport.top += mOutputLetterbox.top;
}
}
s3d::Stereo3DMode::getCurrentMode().AdjustViewports();
}
//===========================================================================
//
// Calculates the OpenGL window coordinates for a zdoom screen position
//
//===========================================================================
int FGLRenderer::ScreenToWindowX(int x)
{
return mScreenViewport.left + (int)round(x * mScreenViewport.width / (float)framebuffer->GetWidth());
}
int FGLRenderer::ScreenToWindowY(int y)
{
return mScreenViewport.top + mScreenViewport.height - (int)round(y * mScreenViewport.height / (float)framebuffer->GetHeight());
}
//===========================================================================
//
//
@ -482,7 +370,7 @@ void FGLRenderer::RenderTextureView(FCanvasTexture *tex, AActor *Viewpoint, doub
gltex->BindToFrameBuffer();
}
GL_IRECT bounds;
IntRect bounds;
bounds.left = bounds.top = 0;
bounds.width = FHardwareTexture::GetTexDimension(gltex->GetWidth());
bounds.height = FHardwareTexture::GetTexDimension(gltex->GetHeight());
@ -516,7 +404,7 @@ void FGLRenderer::WriteSavePic(player_t *player, FileWriter *file, int width, in
void FGLRenderer::BeginFrame()
{
buffersActive = GLRenderer->mBuffers->Setup(GLRenderer->mScreenViewport.width, GLRenderer->mScreenViewport.height, GLRenderer->mSceneViewport.width, GLRenderer->mSceneViewport.height);
buffersActive = GLRenderer->mBuffers->Setup(screen->mScreenViewport.width, screen->mScreenViewport.height, screen->mSceneViewport.width, screen->mSceneViewport.height);
}
//===========================================================================
@ -579,6 +467,7 @@ void FGLRenderer::Draw2D(F2DDrawer *drawer)
{
mBuffers->BindCurrentFB();
}
const auto &mScreenViewport = screen->mScreenViewport;
glViewport(mScreenViewport.left, mScreenViewport.top, mScreenViewport.width, mScreenViewport.height);
gl_RenderState.mViewMatrix.loadIdentity();
@ -641,10 +530,10 @@ void FGLRenderer::Draw2D(F2DDrawer *drawer)
glEnable(GL_SCISSOR_TEST);
// scissor test doesn't use the current viewport for the coordinates, so use real screen coordinates
// Note that the origin here is the lower left corner!
auto sciX = ScreenToWindowX(cmd.mScissor[0]);
auto sciY = ScreenToWindowY(cmd.mScissor[3]);
auto sciW = ScreenToWindowX(cmd.mScissor[2]) - sciX;
auto sciH = ScreenToWindowY(cmd.mScissor[1]) - sciY;
auto sciX = screen->ScreenToWindowX(cmd.mScissor[0]);
auto sciY = screen->ScreenToWindowY(cmd.mScissor[3]);
auto sciW = screen->ScreenToWindowX(cmd.mScissor[2]) - sciX;
auto sciH = screen->ScreenToWindowY(cmd.mScissor[1]) - sciY;
glScissor(sciX, sciY, sciW, sciH);
}
else glDisable(GL_SCISSOR_TEST);

View file

@ -51,19 +51,6 @@ class FCustomPostProcessShaders;
class GLSceneDrawer;
class SWSceneDrawer;
struct GL_IRECT
{
int left,top;
int width,height;
void Offset(int xofs,int yofs)
{
left+=xofs;
top+=yofs;
}
};
enum
{
DM_MAINVIEW,
@ -147,9 +134,6 @@ public:
SWSceneDrawer *swdrawer = nullptr;
LegacyShaderContainer *legacyShaders = nullptr;
GL_IRECT mScreenViewport;
GL_IRECT mSceneViewport;
GL_IRECT mOutputLetterbox;
bool mDrawingScene2D = false;
bool buffersActive = false;
@ -160,10 +144,6 @@ public:
FGLRenderer(OpenGLFrameBuffer *fb);
~FGLRenderer() ;
void SetOutputViewport(GL_IRECT *bounds);
int ScreenToWindowX(int x);
int ScreenToWindowY(int y);
void Initialize(int width, int height);
void ClearBorders();
@ -184,8 +164,8 @@ public:
void LensDistortScene();
void ApplyFXAA();
void BlurScene(float gameinfobluramount);
void CopyToBackbuffer(const GL_IRECT *bounds, bool applyGamma);
void DrawPresentTexture(const GL_IRECT &box, bool applyGamma);
void CopyToBackbuffer(const IntRect *bounds, bool applyGamma);
void DrawPresentTexture(const IntRect &box, bool applyGamma);
void Flush();
void Draw2D(F2DDrawer *data);
void RenderTextureView(FCanvasTexture *tex, AActor *Viewpoint, double FOV);

View file

@ -123,7 +123,7 @@ void GLSceneDrawer::SetViewArea()
void GLSceneDrawer::Reset3DViewport()
{
glViewport(GLRenderer->mScreenViewport.left, GLRenderer->mScreenViewport.top, GLRenderer->mScreenViewport.width, GLRenderer->mScreenViewport.height);
glViewport(screen->mScreenViewport.left, screen->mScreenViewport.top, screen->mScreenViewport.width, screen->mScreenViewport.height);
}
//-----------------------------------------------------------------------------
@ -150,7 +150,7 @@ void GLSceneDrawer::Set3DViewport(bool mainview)
glClearColor(GLRenderer->mSceneClearColor[0], GLRenderer->mSceneClearColor[1], GLRenderer->mSceneClearColor[2], 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
const auto &bounds = GLRenderer->mSceneViewport;
const auto &bounds = screen->mSceneViewport;
glViewport(bounds.left, bounds.top, bounds.width, bounds.height);
glScissor(bounds.left, bounds.top, bounds.width, bounds.height);
@ -637,7 +637,7 @@ void GLSceneDrawer::SetFixedColormap (player_t *player)
//
//-----------------------------------------------------------------------------
sector_t * GLSceneDrawer::RenderViewpoint (AActor * camera, GL_IRECT * bounds, float fov, float ratio, float fovratio, bool mainview, bool toscreen)
sector_t * GLSceneDrawer::RenderViewpoint (AActor * camera, IntRect * bounds, float fov, float ratio, float fovratio, bool mainview, bool toscreen)
{
sector_t * lviewsector;
GLRenderer->mSceneClearColor[0] = 0.0f;
@ -680,7 +680,7 @@ sector_t * GLSceneDrawer::RenderViewpoint (AActor * camera, GL_IRECT * bounds, f
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);
eye->SetUp();
GLRenderer->SetOutputViewport(bounds);
screen->SetOutputViewport(bounds);
Set3DViewport(mainview);
GLRenderer->mDrawingScene2D = true;
GLRenderer->mCurrentFoV = fov;
@ -704,12 +704,12 @@ sector_t * GLSceneDrawer::RenderViewpoint (AActor * camera, GL_IRECT * bounds, f
// This should be done after postprocessing, not before.
GLRenderer->mBuffers->BindCurrentFB();
glViewport(GLRenderer->mScreenViewport.left, GLRenderer->mScreenViewport.top, GLRenderer->mScreenViewport.width, GLRenderer->mScreenViewport.height);
glViewport(screen->mScreenViewport.left, screen->mScreenViewport.top, screen->mScreenViewport.width, screen->mScreenViewport.height);
if (!toscreen)
{
gl_RenderState.mViewMatrix.loadIdentity();
gl_RenderState.mProjectionMatrix.ortho(GLRenderer->mScreenViewport.left, GLRenderer->mScreenViewport.width, GLRenderer->mScreenViewport.height, GLRenderer->mScreenViewport.top, -1.0f, 1.0f);
gl_RenderState.mProjectionMatrix.ortho(screen->mScreenViewport.left, screen->mScreenViewport.width, screen->mScreenViewport.height, screen->mScreenViewport.top, -1.0f, 1.0f);
gl_RenderState.ApplyMatrices();
}
}
@ -733,7 +733,7 @@ sector_t * GLSceneDrawer::RenderViewpoint (AActor * camera, GL_IRECT * bounds, f
void GLSceneDrawer::WriteSavePic (player_t *player, FileWriter *file, int width, int height)
{
GL_IRECT bounds;
IntRect bounds;
P_FindParticleSubsectors(); // make sure that all recently spawned particles have a valid subsector.
bounds.left=0;

View file

@ -63,7 +63,7 @@ public:
void EndDrawScene(sector_t * viewsector);
void DrawEndScene2D(sector_t * viewsector);
sector_t *RenderViewpoint(AActor * camera, GL_IRECT * bounds, float fov, float ratio, float fovratio, bool mainview, bool toscreen);
sector_t *RenderViewpoint(AActor * camera, IntRect * bounds, float fov, float ratio, float fovratio, bool mainview, bool toscreen);
sector_t *RenderView(player_t *player);
void WriteSavePic(player_t *player, FileWriter *file, int width, int height);

View file

@ -45,12 +45,12 @@ void MaskAnaglyph::Present() const
gl_RenderState.SetColorMask(leftEye.GetColorMask().r, leftEye.GetColorMask().g, leftEye.GetColorMask().b, true);
gl_RenderState.ApplyColorMask();
GLRenderer->mBuffers->BindEyeTexture(0, 0);
GLRenderer->DrawPresentTexture(GLRenderer->mOutputLetterbox, true);
GLRenderer->DrawPresentTexture(screen->mOutputLetterbox, true);
gl_RenderState.SetColorMask(rightEye.GetColorMask().r, rightEye.GetColorMask().g, rightEye.GetColorMask().b, true);
gl_RenderState.ApplyColorMask();
GLRenderer->mBuffers->BindEyeTexture(1, 0);
GLRenderer->DrawPresentTexture(GLRenderer->mOutputLetterbox, true);
GLRenderer->DrawPresentTexture(screen->mOutputLetterbox, true);
gl_RenderState.ResetColorMask();
gl_RenderState.ApplyColorMask();

View file

@ -92,7 +92,7 @@ static void prepareInterleavedPresent(FPresentStereoShaderBase& shader)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
const GL_IRECT& box = GLRenderer->mOutputLetterbox;
const IntRect& box = screen->mOutputLetterbox;
glViewport(box.left, box.top, box.width, box.height);
shader.Bind();
@ -115,8 +115,8 @@ static void prepareInterleavedPresent(FPresentStereoShaderBase& shader)
shader.GrayFormula.Set(static_cast<int>(gl_satformula));
}
shader.Scale.Set(
GLRenderer->mScreenViewport.width / (float)GLRenderer->mBuffers->GetWidth(),
GLRenderer->mScreenViewport.height / (float)GLRenderer->mBuffers->GetHeight());
screen->mScreenViewport.width / (float)GLRenderer->mBuffers->GetWidth(),
screen->mScreenViewport.height / (float)GLRenderer->mBuffers->GetHeight());
}
// fixme: I don't know how to get absolute window position on Mac and Linux
@ -150,7 +150,7 @@ void CheckerInterleaved3D::Present() const
GLRenderer->mPresent3dCheckerShader->WindowPositionParity.Set(
(windowVOffset
+ windowHOffset
+ GLRenderer->mOutputLetterbox.height + 1 // +1 because of origin at bottom
+ screen->mOutputLetterbox.height + 1 // +1 because of origin at bottom
) % 2 // because we want the top pixel offset, but gl_FragCoord.y is the bottom pixel offset
);
@ -162,15 +162,15 @@ void s3d::CheckerInterleaved3D::AdjustViewports() const
// decrease the total pixel count by 2, but keep the same aspect ratio
const float sqrt2 = 1.41421356237f;
// Change size of renderbuffer, and align to screen
GLRenderer->mSceneViewport.height /= sqrt2;
GLRenderer->mSceneViewport.top /= sqrt2;
GLRenderer->mSceneViewport.width /= sqrt2;
GLRenderer->mSceneViewport.left /= sqrt2;
screen->mSceneViewport.height /= sqrt2;
screen->mSceneViewport.top /= sqrt2;
screen->mSceneViewport.width /= sqrt2;
screen->mSceneViewport.left /= sqrt2;
GLRenderer->mScreenViewport.height /= sqrt2;
GLRenderer->mScreenViewport.top /= sqrt2;
GLRenderer->mScreenViewport.width /= sqrt2;
GLRenderer->mScreenViewport.left /= sqrt2;
screen->mScreenViewport.height /= sqrt2;
screen->mScreenViewport.top /= sqrt2;
screen->mScreenViewport.width /= sqrt2;
screen->mScreenViewport.left /= sqrt2;
}
void ColumnInterleaved3D::Present() const
@ -214,7 +214,7 @@ void RowInterleaved3D::Present() const
GLRenderer->mPresent3dRowShader->WindowPositionParity.Set(
(windowVOffset
+ GLRenderer->mOutputLetterbox.height + 1 // +1 because of origin at bottom
+ screen->mOutputLetterbox.height + 1 // +1 because of origin at bottom
) % 2
);

View file

@ -80,12 +80,12 @@ void QuadStereo::Present() const
glDrawBuffer(GL_BACK_LEFT);
GLRenderer->ClearBorders();
GLRenderer->mBuffers->BindEyeTexture(0, 0);
GLRenderer->DrawPresentTexture(GLRenderer->mOutputLetterbox, true);
GLRenderer->DrawPresentTexture(screen->mOutputLetterbox, true);
glDrawBuffer(GL_BACK_RIGHT);
GLRenderer->ClearBorders();
GLRenderer->mBuffers->BindEyeTexture(1, 0);
GLRenderer->DrawPresentTexture(GLRenderer->mOutputLetterbox, true);
GLRenderer->DrawPresentTexture(screen->mOutputLetterbox, true);
glDrawBuffer(GL_BACK);
}
@ -94,7 +94,7 @@ void QuadStereo::Present() const
GLRenderer->mBuffers->BindOutputFB();
GLRenderer->ClearBorders();
GLRenderer->mBuffers->BindEyeTexture(0, 0);
GLRenderer->DrawPresentTexture(GLRenderer->mOutputLetterbox, true);
GLRenderer->DrawPresentTexture(screen->mOutputLetterbox, true);
}
}

View file

@ -44,11 +44,11 @@ void SideBySideBase::Present() const
GLRenderer->ClearBorders();
// Compute screen regions to use for left and right eye views
int leftWidth = GLRenderer->mOutputLetterbox.width / 2;
int rightWidth = GLRenderer->mOutputLetterbox.width - leftWidth;
GL_IRECT leftHalfScreen = GLRenderer->mOutputLetterbox;
int leftWidth = screen->mOutputLetterbox.width / 2;
int rightWidth = screen->mOutputLetterbox.width - leftWidth;
IntRect leftHalfScreen = screen->mOutputLetterbox;
leftHalfScreen.width = leftWidth;
GL_IRECT rightHalfScreen = GLRenderer->mOutputLetterbox;
IntRect rightHalfScreen = screen->mOutputLetterbox;
rightHalfScreen.width = rightWidth;
rightHalfScreen.left += leftWidth;
@ -63,10 +63,10 @@ void SideBySideBase::Present() const
void SideBySideBase::AdjustViewports() const
{
// Change size of renderbuffer, and align to screen
GLRenderer->mSceneViewport.width /= 2;
GLRenderer->mSceneViewport.left /= 2;
GLRenderer->mScreenViewport.width /= 2;
GLRenderer->mScreenViewport.left /= 2;
screen->mSceneViewport.width /= 2;
screen->mSceneViewport.left /= 2;
screen->mScreenViewport.width /= 2;
screen->mScreenViewport.left /= 2;
}
/* static */
@ -101,8 +101,8 @@ SideBySideFull::SideBySideFull(double ipdMeters)
void SideBySideFull::AdjustPlayerSprites() const /* override */
{
// Show weapon at double width, so it would appear normal width after rescaling
int w = GLRenderer->mScreenViewport.width;
int h = GLRenderer->mScreenViewport.height;
int w = screen->mScreenViewport.width;
int h = screen->mScreenViewport.height;
gl_RenderState.mProjectionMatrix.ortho(w/2, w + w/2, h, 0, -1.0f, 1.0f);
gl_RenderState.ApplyMatrices();
}
@ -120,12 +120,12 @@ void TopBottom3D::Present() const
GLRenderer->ClearBorders();
// Compute screen regions to use for left and right eye views
int topHeight = GLRenderer->mOutputLetterbox.height / 2;
int bottomHeight = GLRenderer->mOutputLetterbox.height - topHeight;
GL_IRECT topHalfScreen = GLRenderer->mOutputLetterbox;
int topHeight = screen->mOutputLetterbox.height / 2;
int bottomHeight = screen->mOutputLetterbox.height - topHeight;
IntRect topHalfScreen = screen->mOutputLetterbox;
topHalfScreen.height = topHeight;
topHalfScreen.top = topHeight;
GL_IRECT bottomHalfScreen = GLRenderer->mOutputLetterbox;
IntRect bottomHalfScreen = screen->mOutputLetterbox;
bottomHalfScreen.height = bottomHeight;
bottomHalfScreen.top = 0;
@ -140,10 +140,10 @@ void TopBottom3D::Present() const
void TopBottom3D::AdjustViewports() const
{
// Change size of renderbuffer, and align to screen
GLRenderer->mSceneViewport.height /= 2;
GLRenderer->mSceneViewport.top /= 2;
GLRenderer->mScreenViewport.height /= 2;
GLRenderer->mScreenViewport.top /= 2;
screen->mSceneViewport.height /= 2;
screen->mSceneViewport.top /= 2;
screen->mScreenViewport.height /= 2;
screen->mScreenViewport.top /= 2;
}
} /* namespace s3d */

View file

@ -93,7 +93,7 @@ void LeftEyeView::Present() const
GLRenderer->mBuffers->BindOutputFB();
GLRenderer->ClearBorders();
GLRenderer->mBuffers->BindEyeTexture(0, 0);
GLRenderer->DrawPresentTexture(GLRenderer->mOutputLetterbox, true);
GLRenderer->DrawPresentTexture(screen->mOutputLetterbox, true);
}
/* static */
@ -109,7 +109,7 @@ void RightEyeView::Present() const
GLRenderer->mBuffers->BindOutputFB();
GLRenderer->ClearBorders();
GLRenderer->mBuffers->BindEyeTexture(0, 0);
GLRenderer->DrawPresentTexture(GLRenderer->mOutputLetterbox, true);
GLRenderer->DrawPresentTexture(screen->mOutputLetterbox, true);
}

View file

@ -39,6 +39,7 @@
#include "hwrenderer/utility/hw_clock.h"
#include "gl/data/gl_vertexbuffer.h"
#include "gl/models/gl_models.h"
#include "gl/stereo3d/gl_stereo3d.h"
#include "gl_debug.h"
#include "r_videoscale.h"
@ -137,7 +138,7 @@ void OpenGLFrameBuffer::InitializeState()
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
GLRenderer->Initialize(GetWidth(), GetHeight());
GLRenderer->SetOutputViewport(nullptr);
SetOutputViewport(nullptr);
}
//==========================================================================
@ -167,7 +168,7 @@ void OpenGLFrameBuffer::Update()
GLRenderer->mVBO->OutputResized(Width, Height);
}
GLRenderer->SetOutputViewport(nullptr);
SetOutputViewport(nullptr);
}
//===========================================================================
@ -379,6 +380,17 @@ void OpenGLFrameBuffer::ResetFixedColormap()
}
}
bool OpenGLFrameBuffer::RenderBuffersEnabled()
{
return FGLRenderBuffers::IsEnabled();
}
void OpenGLFrameBuffer::SetOutputViewport(IntRect *bounds)
{
Super::SetOutputViewport(bounds);
s3d::Stereo3DMode::getCurrentMode().AdjustViewports();
}
void OpenGLFrameBuffer::UpdatePalette()
{
@ -446,7 +458,7 @@ void OpenGLFrameBuffer::BeginFrame()
void OpenGLFrameBuffer::GetScreenshotBuffer(const uint8_t *&buffer, int &pitch, ESSType &color_type, float &gamma)
{
const auto &viewport = GLRenderer->mOutputLetterbox;
const auto &viewport = mOutputLetterbox;
// Grab what is in the back buffer.
// We cannot rely on SCREENWIDTH/HEIGHT here because the output may have been scaled.
@ -513,10 +525,10 @@ void OpenGLFrameBuffer::GameRestart()
void OpenGLFrameBuffer::ScaleCoordsFromWindow(int16_t &x, int16_t &y)
{
int letterboxX = GLRenderer->mOutputLetterbox.left;
int letterboxY = GLRenderer->mOutputLetterbox.top;
int letterboxWidth = GLRenderer->mOutputLetterbox.width;
int letterboxHeight = GLRenderer->mOutputLetterbox.height;
int letterboxX = mOutputLetterbox.left;
int letterboxY = mOutputLetterbox.top;
int letterboxWidth = mOutputLetterbox.width;
int letterboxHeight = mOutputLetterbox.height;
// Subtract the LB video mode letterboxing
if (IsFullscreen())

View file

@ -46,6 +46,8 @@ public:
void TextureFilterChanged() override;
void ResetFixedColormap() override;
void BeginFrame() override;
bool RenderBuffersEnabled() override;
void SetOutputViewport(IntRect *bounds) override;
// Retrieves a buffer containing image data for a screenshot.
// Hint: Pitch can be negative for upside-down images, in which case buffer

View file

@ -115,7 +115,7 @@ bool OpenGLFrameBuffer::WipeStartScreen(int type)
return false;
}
const auto &viewport = GLRenderer->mScreenViewport;
const auto &viewport = screen->mScreenViewport;
wipestartscreen = new FHardwareTexture(true);
wipestartscreen->CreateTexture(NULL, viewport.width, viewport.height, 0, false, 0, "WipeStartScreen");
GLRenderer->mSamplerManager->Bind(0, CLAMP_NOFILTER, -1);
@ -163,7 +163,7 @@ bool OpenGLFrameBuffer::WipeStartScreen(int type)
void OpenGLFrameBuffer::WipeEndScreen()
{
GLRenderer->Flush();
const auto &viewport = GLRenderer->mScreenViewport;
const auto &viewport = screen->mScreenViewport;
wipeendscreen = new FHardwareTexture(true);
wipeendscreen->CreateTexture(NULL, viewport.width, viewport.height, 0, false, 0, "WipeEndScreen");
GLRenderer->mSamplerManager->Bind(0, CLAMP_NOFILTER, -1);
@ -206,7 +206,7 @@ bool OpenGLFrameBuffer::WipeDo(int ticks)
if (FGLRenderBuffers::IsEnabled())
{
GLRenderer->mBuffers->BindCurrentFB();
const auto &bounds = GLRenderer->mScreenViewport;
const auto &bounds = screen->mScreenViewport;
glViewport(bounds.left, bounds.top, bounds.width, bounds.height);
}

View file

@ -75,6 +75,8 @@
EXTERN_CVAR(Bool, cl_capfps)
EXTERN_CVAR(Float, vid_brightness)
EXTERN_CVAR(Float, vid_contrast)
CVAR(Bool, gl_scale_viewport, true, CVAR_ARCHIVE);
EXTERN_CVAR(Int, screenblocks)
CUSTOM_CVAR(Int, vid_maxfps, 200, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
{
@ -134,6 +136,8 @@ public:
bool SetFlash(PalEntry rgb, int amount) { DBGBREAK; return false; }
void GetFlash(PalEntry &rgb, int &amount) { DBGBREAK; }
bool IsFullscreen() { DBGBREAK; return 0; }
int GetClientWidth() { DBGBREAK; return 0; }
int GetClientHeight() { DBGBREAK; return 0; }
float Gamma;
};
@ -967,6 +971,117 @@ void DFrameBuffer::WriteSavePic(player_t *player, FileWriter *file, int width, i
}
//==========================================================================
//
// Calculates the viewport values needed for 2D and 3D operations
//
//==========================================================================
void DFrameBuffer::SetOutputViewport(IntRect *bounds)
{
if (bounds)
{
mSceneViewport = *bounds;
mScreenViewport = *bounds;
mOutputLetterbox = *bounds;
return;
}
// Special handling so the view with a visible status bar displays properly
int height, width;
if (screenblocks >= 10)
{
height = GetHeight();
width = GetWidth();
}
else
{
height = (screenblocks*GetHeight() / 10) & ~7;
width = (screenblocks*GetWidth() / 10);
}
// Back buffer letterbox for the final output
int clientWidth = GetClientWidth();
int clientHeight = GetClientHeight();
if (clientWidth == 0 || clientHeight == 0)
{
// When window is minimized there may not be any client area.
// Pretend to the rest of the render code that we just have a very small window.
clientWidth = 160;
clientHeight = 120;
}
int screenWidth = GetWidth();
int screenHeight = GetHeight();
float scaleX, scaleY;
if (ViewportIsScaled43())
{
scaleX = MIN(clientWidth / (float)screenWidth, clientHeight / (screenHeight * 1.2f));
scaleY = scaleX * 1.2f;
}
else
{
scaleX = MIN(clientWidth / (float)screenWidth, clientHeight / (float)screenHeight);
scaleY = scaleX;
}
mOutputLetterbox.width = (int)round(screenWidth * scaleX);
mOutputLetterbox.height = (int)round(screenHeight * scaleY);
mOutputLetterbox.left = (clientWidth - mOutputLetterbox.width) / 2;
mOutputLetterbox.top = (clientHeight - mOutputLetterbox.height) / 2;
// The entire renderable area, including the 2D HUD
mScreenViewport.left = 0;
mScreenViewport.top = 0;
mScreenViewport.width = screenWidth;
mScreenViewport.height = screenHeight;
// Viewport for the 3D scene
mSceneViewport.left = viewwindowx;
mSceneViewport.top = screenHeight - (height + viewwindowy - ((height - viewheight) / 2));
mSceneViewport.width = viewwidth;
mSceneViewport.height = height;
// Scale viewports to fit letterbox
bool notScaled = ((mScreenViewport.width == ViewportScaledWidth(mScreenViewport.width, mScreenViewport.height)) &&
(mScreenViewport.width == ViewportScaledHeight(mScreenViewport.width, mScreenViewport.height)) &&
!ViewportIsScaled43());
if ((gl_scale_viewport && !IsFullscreen() && notScaled) || !RenderBuffersEnabled())
{
mScreenViewport.width = mOutputLetterbox.width;
mScreenViewport.height = mOutputLetterbox.height;
mSceneViewport.left = (int)round(mSceneViewport.left * scaleX);
mSceneViewport.top = (int)round(mSceneViewport.top * scaleY);
mSceneViewport.width = (int)round(mSceneViewport.width * scaleX);
mSceneViewport.height = (int)round(mSceneViewport.height * scaleY);
// Without render buffers we have to render directly to the letterbox
if (!RenderBuffersEnabled())
{
mScreenViewport.left += mOutputLetterbox.left;
mScreenViewport.top += mOutputLetterbox.top;
mSceneViewport.left += mOutputLetterbox.left;
mSceneViewport.top += mOutputLetterbox.top;
}
}
}
//===========================================================================
//
// Calculates the OpenGL window coordinates for a zdoom screen position
//
//===========================================================================
int DFrameBuffer::ScreenToWindowX(int x)
{
return mScreenViewport.left + (int)round(x * mScreenViewport.width / (float)GetWidth());
}
int DFrameBuffer::ScreenToWindowY(int y)
{
return mScreenViewport.top + mScreenViewport.height - (int)round(y * mScreenViewport.height / (float)GetHeight());
}
CCMD(clean)
{
Printf ("CleanXfac: %d\nCleanYfac: %d\n", CleanXfac, CleanYfac);

View file

@ -63,6 +63,21 @@ enum EHWCaps
RFL_NO_SHADERS = 256
};
struct IntRect
{
int left, top;
int width, height;
void Offset(int xofs, int yofs)
{
left += xofs;
top += yofs;
}
};
extern int CleanWidth, CleanHeight, CleanXfac, CleanYfac;
@ -332,6 +347,10 @@ public:
int hwcaps = 0;
int instack[2] = { 0,0 }; // this is globally maintained state for portal recursion avoidance.
IntRect mScreenViewport;
IntRect mSceneViewport;
IntRect mOutputLetterbox;
public:
DFrameBuffer (int width, int height, bool bgra);
virtual ~DFrameBuffer() {}
@ -385,6 +404,11 @@ public:
virtual void ResetFixedColormap() {}
virtual void BeginFrame() {}
virtual int GetClientWidth() = 0;
virtual int GetClientHeight() = 0;
virtual bool RenderBuffersEnabled() { return false; };
// Begin 2D drawing operations.
// Returns true if hardware-accelerated 2D has been entered, false if not.
void Begin2D(bool copy3d) { isIn2D = true; }
@ -472,6 +496,10 @@ public:
// Calculate gamma table
void CalcGamma(float gamma, uint8_t gammalookup[256]);
virtual void SetOutputViewport(IntRect *bounds);
int ScreenToWindowX(int x);
int ScreenToWindowY(int y);
// Retrieves a buffer containing image data for a screenshot.
// Hint: Pitch can be negative for upside-down images, in which case buffer