mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-10 23:02:08 +00:00
Remove GetTrueHeight from GL renderer and concentrate all viewport calculations in SetOutputViewport
This commit is contained in:
parent
353a464f5b
commit
c817979eae
9 changed files with 163 additions and 138 deletions
|
@ -155,14 +155,10 @@ void F2DDrawer::AddTexture(FTexture *img, DrawParms &parms)
|
||||||
color.a = (BYTE)(parms.Alpha * 255);
|
color.a = (BYTE)(parms.Alpha * 255);
|
||||||
|
|
||||||
// scissor test doesn't use the current viewport for the coordinates, so use real screen coordinates
|
// scissor test doesn't use the current viewport for the coordinates, so use real screen coordinates
|
||||||
int btm = (SCREENHEIGHT - screen->GetHeight()) / 2;
|
dg.mScissor[0] = GLRenderer->ScreenToWindowX(parms.lclip);
|
||||||
btm = SCREENHEIGHT - btm;
|
dg.mScissor[1] = GLRenderer->ScreenToWindowY(parms.dclip);
|
||||||
|
dg.mScissor[2] = GLRenderer->ScreenToWindowX(parms.rclip) - GLRenderer->ScreenToWindowX(parms.lclip);
|
||||||
int space = (static_cast<OpenGLFrameBuffer*>(screen)->GetTrueHeight() - screen->GetHeight()) / 2;
|
dg.mScissor[3] = GLRenderer->ScreenToWindowY(parms.dclip) - GLRenderer->ScreenToWindowY(parms.uclip);
|
||||||
dg.mScissor[0] = parms.lclip;
|
|
||||||
dg.mScissor[1] = btm - parms.dclip + space;
|
|
||||||
dg.mScissor[2] = parms.rclip - parms.lclip;
|
|
||||||
dg.mScissor[3] = parms.dclip - parms.uclip;
|
|
||||||
|
|
||||||
FSimpleVertex *ptr = &mVertices[dg.mVertIndex];
|
FSimpleVertex *ptr = &mVertices[dg.mVertIndex];
|
||||||
ptr->Set(x, y, 0, u1, v1, color); ptr++;
|
ptr->Set(x, y, 0, u1, v1, color); ptr++;
|
||||||
|
@ -438,7 +434,8 @@ void F2DDrawer::Flush()
|
||||||
glDrawArrays(GL_TRIANGLE_STRIP, dt->mVertIndex + 4, 4);
|
glDrawArrays(GL_TRIANGLE_STRIP, dt->mVertIndex + 4, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
glScissor(0, 0, screen->GetWidth(), screen->GetHeight());
|
const auto &viewport = GLRenderer->mScreenViewport;
|
||||||
|
glScissor(viewport.left, viewport.top, viewport.width, viewport.height);
|
||||||
glDisable(GL_SCISSOR_TEST);
|
glDisable(GL_SCISSOR_TEST);
|
||||||
gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
gl_RenderState.SetTextureMode(TM_MODULATE);
|
gl_RenderState.SetTextureMode(TM_MODULATE);
|
||||||
|
|
|
@ -182,7 +182,7 @@ void FGLRenderer::BloomScene()
|
||||||
|
|
||||||
// Add bloom back to scene texture:
|
// Add bloom back to scene texture:
|
||||||
mBuffers->BindCurrentFB();
|
mBuffers->BindCurrentFB();
|
||||||
glViewport(mOutputViewport.left, mOutputViewport.top, mOutputViewport.width, mOutputViewport.height);
|
glViewport(mScreenViewport.left, mScreenViewport.top, mScreenViewport.width, mScreenViewport.height);
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
glBlendEquation(GL_FUNC_ADD);
|
glBlendEquation(GL_FUNC_ADD);
|
||||||
glBlendFunc(GL_ONE, GL_ONE);
|
glBlendFunc(GL_ONE, GL_ONE);
|
||||||
|
@ -243,7 +243,7 @@ void FGLRenderer::LensDistortScene()
|
||||||
0.0f
|
0.0f
|
||||||
};
|
};
|
||||||
|
|
||||||
float aspect = mOutputViewport.width / mOutputViewport.height;
|
float aspect = mSceneViewport.width / mSceneViewport.height;
|
||||||
|
|
||||||
// Scale factor to keep sampling within the input texture
|
// Scale factor to keep sampling within the input texture
|
||||||
float r2 = aspect * aspect * 0.25 + 0.25f;
|
float r2 = aspect * aspect * 0.25 + 0.25f;
|
||||||
|
@ -283,60 +283,21 @@ void FGLRenderer::CopyToBackbuffer(const GL_IRECT *bounds, bool applyGamma)
|
||||||
if (FGLRenderBuffers::IsEnabled())
|
if (FGLRenderBuffers::IsEnabled())
|
||||||
{
|
{
|
||||||
FGLPostProcessState savedState;
|
FGLPostProcessState savedState;
|
||||||
|
|
||||||
mBuffers->BindOutputFB();
|
mBuffers->BindOutputFB();
|
||||||
|
|
||||||
int x, y, width, height;
|
GL_IRECT box;
|
||||||
if (bounds)
|
if (bounds)
|
||||||
{
|
{
|
||||||
x = bounds->left;
|
box = *bounds;
|
||||||
y = bounds->top;
|
|
||||||
width = bounds->width;
|
|
||||||
height = bounds->height;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Calculate letterbox
|
ClearBorders();
|
||||||
int clientWidth = framebuffer->GetClientWidth();
|
box = mOutputLetterbox;
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
glDisable(GL_SCISSOR_TEST);
|
|
||||||
|
|
||||||
// Present what was rendered:
|
// Present what was rendered:
|
||||||
glViewport(x, y, width, height);
|
glViewport(box.left, box.top, box.width, box.height);
|
||||||
glDisable(GL_BLEND);
|
|
||||||
|
|
||||||
mPresentShader->Bind();
|
mPresentShader->Bind();
|
||||||
mPresentShader->InputTexture.Set(0);
|
mPresentShader->InputTexture.Set(0);
|
||||||
|
@ -358,4 +319,48 @@ void FGLRenderer::CopyToBackbuffer(const GL_IRECT *bounds, bool applyGamma)
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
RenderScreenQuad();
|
RenderScreenQuad();
|
||||||
}
|
}
|
||||||
|
else if (!bounds)
|
||||||
|
{
|
||||||
|
FGLPostProcessState savedState;
|
||||||
|
ClearBorders();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Fills the black bars around the screen letterbox
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void FGLRenderer::ClearBorders()
|
||||||
|
{
|
||||||
|
const auto &box = mOutputLetterbox;
|
||||||
|
|
||||||
|
int clientWidth = framebuffer->GetClientWidth();
|
||||||
|
int clientHeight = framebuffer->GetClientHeight();
|
||||||
|
|
||||||
|
glViewport(0, 0, clientWidth, clientHeight);
|
||||||
|
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
|
glEnable(GL_SCISSOR_TEST);
|
||||||
|
if (box.top > 0)
|
||||||
|
{
|
||||||
|
glScissor(0, 0, clientWidth, box.top);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
}
|
||||||
|
if (clientHeight - box.top - box.height > 0)
|
||||||
|
{
|
||||||
|
glScissor(0, box.top + box.height, clientWidth, clientHeight - box.top - box.height);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
}
|
||||||
|
if (box.left > 0)
|
||||||
|
{
|
||||||
|
glScissor(0, box.top, box.left, box.height);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
}
|
||||||
|
if (clientWidth - box.left - box.width > 0)
|
||||||
|
{
|
||||||
|
glScissor(box.left + box.width, box.top, clientWidth - box.left - box.width, box.height);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
}
|
||||||
|
glDisable(GL_SCISSOR_TEST);
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,6 +79,8 @@
|
||||||
|
|
||||||
EXTERN_CVAR(Int, screenblocks)
|
EXTERN_CVAR(Int, screenblocks)
|
||||||
|
|
||||||
|
CVAR(Bool, gl_scale_viewport, true, 0);
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
//
|
//
|
||||||
// Renderer interface
|
// Renderer interface
|
||||||
|
@ -190,16 +192,14 @@ void FGLRenderer::SetOutputViewport(GL_IRECT *bounds)
|
||||||
{
|
{
|
||||||
if (bounds)
|
if (bounds)
|
||||||
{
|
{
|
||||||
mOutputViewport = *bounds;
|
mSceneViewport = *bounds;
|
||||||
mOutputViewportLB = *bounds;
|
|
||||||
mScreenViewport = *bounds;
|
mScreenViewport = *bounds;
|
||||||
|
mOutputLetterbox = *bounds;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int height, width;
|
|
||||||
|
|
||||||
// Special handling so the view with a visible status bar displays properly
|
// Special handling so the view with a visible status bar displays properly
|
||||||
|
int height, width;
|
||||||
if (screenblocks >= 10)
|
if (screenblocks >= 10)
|
||||||
{
|
{
|
||||||
height = framebuffer->GetHeight();
|
height = framebuffer->GetHeight();
|
||||||
|
@ -211,29 +211,64 @@ void FGLRenderer::SetOutputViewport(GL_IRECT *bounds)
|
||||||
width = (screenblocks*framebuffer->GetWidth() / 10);
|
width = (screenblocks*framebuffer->GetWidth() / 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
int trueheight = framebuffer->GetTrueHeight(); // ugh...
|
// Back buffer letterbox for the final output
|
||||||
int bars = (trueheight - framebuffer->GetHeight()) / 2;
|
int clientWidth = framebuffer->GetClientWidth();
|
||||||
|
int clientHeight = framebuffer->GetClientHeight();
|
||||||
int vw = viewwidth;
|
int screenWidth = framebuffer->GetWidth();
|
||||||
int vh = viewheight;
|
int screenHeight = framebuffer->GetHeight();
|
||||||
|
float scale = MIN(clientWidth / (float)screenWidth, clientHeight / (float)screenHeight);
|
||||||
|
mOutputLetterbox.width = (int)round(screenWidth * scale);
|
||||||
|
mOutputLetterbox.height = (int)round(screenHeight * scale);
|
||||||
|
mOutputLetterbox.left = (clientWidth - mOutputLetterbox.width) / 2;
|
||||||
|
mOutputLetterbox.top = (clientHeight - mOutputLetterbox.height) / 2;
|
||||||
|
|
||||||
// The entire renderable area, including the 2D HUD
|
// The entire renderable area, including the 2D HUD
|
||||||
mScreenViewport.left = 0;
|
mScreenViewport.left = 0;
|
||||||
mScreenViewport.top = 0;
|
mScreenViewport.top = 0;
|
||||||
mScreenViewport.width = framebuffer->GetWidth();
|
mScreenViewport.width = screenWidth;
|
||||||
mScreenViewport.height = framebuffer->GetHeight();
|
mScreenViewport.height = screenHeight;
|
||||||
|
|
||||||
// Letterboxed viewport for the main scene
|
// Viewport for the 3D scene
|
||||||
mOutputViewportLB.left = viewwindowx;
|
mSceneViewport.left = viewwindowx;
|
||||||
mOutputViewportLB.top = trueheight - bars - (height + viewwindowy - ((height - vh) / 2));
|
mSceneViewport.top = screenHeight - (height + viewwindowy - ((height - viewheight) / 2));
|
||||||
mOutputViewportLB.width = vw;
|
mSceneViewport.width = viewwidth;
|
||||||
mOutputViewportLB.height = height;
|
mSceneViewport.height = height;
|
||||||
|
|
||||||
// Entire canvas for player sprites
|
// Scale viewports to fit letterbox
|
||||||
mOutputViewport.left = 0;
|
if (gl_scale_viewport || !FGLRenderBuffers::IsEnabled())
|
||||||
mOutputViewport.top = (trueheight - framebuffer->GetHeight()) / 2;
|
{
|
||||||
mOutputViewport.width = framebuffer->GetWidth();
|
mScreenViewport.width = mOutputLetterbox.width;
|
||||||
mOutputViewport.height = framebuffer->GetHeight();
|
mScreenViewport.height = mOutputLetterbox.height;
|
||||||
|
mSceneViewport.left = (int)round(mSceneViewport.left * scale);
|
||||||
|
mSceneViewport.top = (int)round(mSceneViewport.top * scale);
|
||||||
|
mSceneViewport.width = (int)round(mSceneViewport.width * scale);
|
||||||
|
mSceneViewport.height = (int)round(mSceneViewport.height * scale);
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// 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());
|
||||||
}
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
@ -258,6 +293,7 @@ void FGLRenderer::Begin2D()
|
||||||
mBuffers->BindCurrentFB();
|
mBuffers->BindCurrentFB();
|
||||||
}
|
}
|
||||||
glViewport(mScreenViewport.left, mScreenViewport.top, mScreenViewport.width, mScreenViewport.height);
|
glViewport(mScreenViewport.left, mScreenViewport.top, mScreenViewport.width, mScreenViewport.height);
|
||||||
|
glScissor(mScreenViewport.left, mScreenViewport.top, mScreenViewport.width, mScreenViewport.height);
|
||||||
|
|
||||||
gl_RenderState.EnableFog(false);
|
gl_RenderState.EnableFog(false);
|
||||||
gl_RenderState.Set2DMode(true);
|
gl_RenderState.Set2DMode(true);
|
||||||
|
@ -363,32 +399,3 @@ unsigned char *FGLRenderer::GetTextureBuffer(FTexture *tex, int &w, int &h)
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//===========================================================================
|
|
||||||
|
|
||||||
void FGLRenderer::ClearBorders()
|
|
||||||
{
|
|
||||||
OpenGLFrameBuffer *glscreen = static_cast<OpenGLFrameBuffer*>(screen);
|
|
||||||
|
|
||||||
// Letterbox time! Draw black top and bottom borders.
|
|
||||||
int width = glscreen->GetWidth();
|
|
||||||
int height = glscreen->GetHeight();
|
|
||||||
int trueHeight = glscreen->GetTrueHeight();
|
|
||||||
|
|
||||||
int borderHeight = (trueHeight - height) / 2;
|
|
||||||
|
|
||||||
glViewport(0, 0, width, trueHeight);
|
|
||||||
glClearColor(0, 0, 0, 1);
|
|
||||||
glEnable(GL_SCISSOR_TEST);
|
|
||||||
glScissor(0, 0, width, borderHeight);
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
|
||||||
glScissor(0, trueHeight-borderHeight, width, borderHeight);
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
|
||||||
glDisable(GL_SCISSOR_TEST);
|
|
||||||
glViewport(0, (trueHeight - height) / 2, width, height);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -111,17 +111,20 @@ public:
|
||||||
F2DDrawer *m2DDrawer;
|
F2DDrawer *m2DDrawer;
|
||||||
|
|
||||||
GL_IRECT mScreenViewport;
|
GL_IRECT mScreenViewport;
|
||||||
GL_IRECT mOutputViewportLB;
|
GL_IRECT mSceneViewport;
|
||||||
GL_IRECT mOutputViewport;
|
GL_IRECT mOutputLetterbox;
|
||||||
bool mDrawingScene2D = false;
|
bool mDrawingScene2D = false;
|
||||||
float mCameraExposure = 1.0f;
|
float mCameraExposure = 1.0f;
|
||||||
|
|
||||||
FGLRenderer(OpenGLFrameBuffer *fb);
|
FGLRenderer(OpenGLFrameBuffer *fb);
|
||||||
~FGLRenderer() ;
|
~FGLRenderer() ;
|
||||||
|
|
||||||
|
void SetOutputViewport(GL_IRECT *bounds);
|
||||||
|
int ScreenToWindowX(int x);
|
||||||
|
int ScreenToWindowY(int y);
|
||||||
|
|
||||||
angle_t FrustumAngle();
|
angle_t FrustumAngle();
|
||||||
void SetViewArea();
|
void SetViewArea();
|
||||||
void SetOutputViewport(GL_IRECT *bounds);
|
|
||||||
void Set3DViewport(bool mainview);
|
void Set3DViewport(bool mainview);
|
||||||
void Reset3DViewport();
|
void Reset3DViewport();
|
||||||
sector_t *RenderViewpoint (AActor * camera, GL_IRECT * bounds, float fov, float ratio, float fovratio, bool mainview, bool toscreen);
|
sector_t *RenderViewpoint (AActor * camera, GL_IRECT * bounds, float fov, float ratio, float fovratio, bool mainview, bool toscreen);
|
||||||
|
|
|
@ -157,7 +157,7 @@ void FGLRenderer::SetViewArea()
|
||||||
|
|
||||||
void FGLRenderer::Reset3DViewport()
|
void FGLRenderer::Reset3DViewport()
|
||||||
{
|
{
|
||||||
glViewport(mOutputViewport.left, mOutputViewport.top, mOutputViewport.width, mOutputViewport.height);
|
glViewport(mScreenViewport.left, mScreenViewport.top, mScreenViewport.width, mScreenViewport.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -170,11 +170,11 @@ void FGLRenderer::Set3DViewport(bool mainview)
|
||||||
{
|
{
|
||||||
if (mainview && FGLRenderBuffers::IsEnabled())
|
if (mainview && FGLRenderBuffers::IsEnabled())
|
||||||
{
|
{
|
||||||
mBuffers->Setup(mOutputViewport.width, mOutputViewport.height);
|
mBuffers->Setup(mScreenViewport.width, mScreenViewport.height);
|
||||||
mBuffers->BindSceneFB();
|
mBuffers->BindSceneFB();
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto &bounds = mOutputViewportLB;
|
const auto &bounds = mSceneViewport;
|
||||||
glViewport(bounds.left, bounds.top, bounds.width, bounds.height);
|
glViewport(bounds.left, bounds.top, bounds.width, bounds.height);
|
||||||
glScissor(bounds.left, bounds.top, bounds.width, bounds.height);
|
glScissor(bounds.left, bounds.top, bounds.width, bounds.height);
|
||||||
|
|
||||||
|
|
|
@ -160,10 +160,6 @@ void OpenGLFrameBuffer::InitializeState()
|
||||||
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
//int trueH = GetTrueHeight();
|
|
||||||
//int h = GetHeight();
|
|
||||||
//glViewport(0, (trueH - h)/2, GetWidth(), GetHeight());
|
|
||||||
|
|
||||||
GLRenderer->Initialize(GetWidth(), GetHeight());
|
GLRenderer->Initialize(GetWidth(), GetHeight());
|
||||||
GLRenderer->SetOutputViewport(nullptr);
|
GLRenderer->SetOutputViewport(nullptr);
|
||||||
Begin2D(false);
|
Begin2D(false);
|
||||||
|
@ -191,13 +187,6 @@ void OpenGLFrameBuffer::Update()
|
||||||
DrawRateStuff();
|
DrawRateStuff();
|
||||||
GLRenderer->Flush();
|
GLRenderer->Flush();
|
||||||
|
|
||||||
if (GetTrueHeight() != GetHeight())
|
|
||||||
{
|
|
||||||
if (GLRenderer != NULL)
|
|
||||||
GLRenderer->ClearBorders();
|
|
||||||
|
|
||||||
Begin2D(false);
|
|
||||||
}
|
|
||||||
if (gl_draw_sync || !swapped)
|
if (gl_draw_sync || !swapped)
|
||||||
{
|
{
|
||||||
Swap();
|
Swap();
|
||||||
|
@ -484,15 +473,41 @@ void OpenGLFrameBuffer::FillSimplePoly(FTexture *texture, FVector2 *points, int
|
||||||
|
|
||||||
void OpenGLFrameBuffer::GetScreenshotBuffer(const BYTE *&buffer, int &pitch, ESSType &color_type)
|
void OpenGLFrameBuffer::GetScreenshotBuffer(const BYTE *&buffer, int &pitch, ESSType &color_type)
|
||||||
{
|
{
|
||||||
|
const auto &viewport = GLRenderer->mScreenViewport;
|
||||||
|
|
||||||
|
// Grab what is in the back buffer.
|
||||||
|
// We cannot rely on SCREENWIDTH/HEIGHT here because the output may have been scaled.
|
||||||
|
TArray<uint8_t> pixels;
|
||||||
|
pixels.Resize(viewport.width * viewport.height);
|
||||||
|
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
||||||
|
glReadPixels(viewport.left, viewport.top, viewport.width, viewport.height, GL_RGB, GL_UNSIGNED_BYTE, &pixels[0]);
|
||||||
|
glPixelStorei(GL_PACK_ALIGNMENT, 4);
|
||||||
|
|
||||||
|
// Copy to screenshot buffer:
|
||||||
int w = SCREENWIDTH;
|
int w = SCREENWIDTH;
|
||||||
int h = SCREENHEIGHT;
|
int h = SCREENHEIGHT;
|
||||||
|
|
||||||
ReleaseScreenshotBuffer();
|
ReleaseScreenshotBuffer();
|
||||||
ScreenshotBuffer = new BYTE[w * h * 3];
|
ScreenshotBuffer = new BYTE[w * h * 3];
|
||||||
|
|
||||||
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
float rcpWidth = 1.0f / viewport.width;
|
||||||
glReadPixels(0,(GetTrueHeight() - GetHeight()) / 2,w,h,GL_RGB,GL_UNSIGNED_BYTE,ScreenshotBuffer);
|
float rcpHeight = 1.0f / viewport.height;
|
||||||
glPixelStorei(GL_PACK_ALIGNMENT, 4);
|
for (int y = 0; y < h; y++)
|
||||||
|
{
|
||||||
|
for (int x = 0; x < w; x++)
|
||||||
|
{
|
||||||
|
float u = (x + 0.5f) * rcpWidth;
|
||||||
|
float v = (y + 0.5f) * rcpHeight;
|
||||||
|
int sx = u * viewport.width;
|
||||||
|
int sy = v * viewport.height;
|
||||||
|
int sindex = (sx + sy * w) * 3;
|
||||||
|
int dindex = (x + y * w) * 3;
|
||||||
|
ScreenshotBuffer[dindex] = pixels[sindex];
|
||||||
|
ScreenshotBuffer[dindex + 1] = pixels[sindex + 1];
|
||||||
|
ScreenshotBuffer[dindex + 2] = pixels[sindex + 2];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pitch = -w*3;
|
pitch = -w*3;
|
||||||
color_type = SS_RGB;
|
color_type = SS_RGB;
|
||||||
buffer = ScreenshotBuffer + w * 3 * (h - 1);
|
buffer = ScreenshotBuffer + w * 3 * (h - 1);
|
||||||
|
|
|
@ -151,8 +151,9 @@ bool OpenGLFrameBuffer::WipeStartScreen(int type)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
wipestartscreen = new FHardwareTexture(Width, Height, true);
|
const auto &viewport = GLRenderer->mScreenViewport;
|
||||||
wipestartscreen->CreateTexture(NULL, Width, Height, 0, false, 0);
|
wipestartscreen = new FHardwareTexture(viewport.width, viewport.height, true);
|
||||||
|
wipestartscreen->CreateTexture(NULL, viewport.width, viewport.height, 0, false, 0);
|
||||||
GLRenderer->mSamplerManager->Bind(0, CLAMP_NOFILTER, -1);
|
GLRenderer->mSamplerManager->Bind(0, CLAMP_NOFILTER, -1);
|
||||||
GLRenderer->mSamplerManager->Bind(1, CLAMP_NONE, -1);
|
GLRenderer->mSamplerManager->Bind(1, CLAMP_NONE, -1);
|
||||||
glFinish();
|
glFinish();
|
||||||
|
@ -161,14 +162,14 @@ bool OpenGLFrameBuffer::WipeStartScreen(int type)
|
||||||
if (FGLRenderBuffers::IsEnabled())
|
if (FGLRenderBuffers::IsEnabled())
|
||||||
{
|
{
|
||||||
GLRenderer->mBuffers->BindCurrentFB();
|
GLRenderer->mBuffers->BindCurrentFB();
|
||||||
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, Width, Height);
|
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, viewport.left, viewport.top, viewport.width, viewport.height);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
GLint readbuffer = 0;
|
GLint readbuffer = 0;
|
||||||
glGetIntegerv(GL_READ_BUFFER, &readbuffer);
|
glGetIntegerv(GL_READ_BUFFER, &readbuffer);
|
||||||
glReadBuffer(GL_FRONT);
|
glReadBuffer(GL_FRONT);
|
||||||
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, Width, Height);
|
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, viewport.left, viewport.top, viewport.width, viewport.height);
|
||||||
glReadBuffer(readbuffer);
|
glReadBuffer(readbuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -189,8 +190,10 @@ bool OpenGLFrameBuffer::WipeStartScreen(int type)
|
||||||
void OpenGLFrameBuffer::WipeEndScreen()
|
void OpenGLFrameBuffer::WipeEndScreen()
|
||||||
{
|
{
|
||||||
GLRenderer->m2DDrawer->Flush();
|
GLRenderer->m2DDrawer->Flush();
|
||||||
wipeendscreen = new FHardwareTexture(Width, Height, true);
|
|
||||||
wipeendscreen->CreateTexture(NULL, Width, Height, 0, false, 0);
|
const auto &viewport = GLRenderer->mScreenViewport;
|
||||||
|
wipeendscreen = new FHardwareTexture(viewport.width, viewport.height, true);
|
||||||
|
wipeendscreen->CreateTexture(NULL, viewport.width, viewport.height, 0, false, 0);
|
||||||
GLRenderer->mSamplerManager->Bind(0, CLAMP_NOFILTER, -1);
|
GLRenderer->mSamplerManager->Bind(0, CLAMP_NOFILTER, -1);
|
||||||
glFinish();
|
glFinish();
|
||||||
wipeendscreen->Bind(0, false, false);
|
wipeendscreen->Bind(0, false, false);
|
||||||
|
@ -198,7 +201,7 @@ void OpenGLFrameBuffer::WipeEndScreen()
|
||||||
if (FGLRenderBuffers::IsEnabled())
|
if (FGLRenderBuffers::IsEnabled())
|
||||||
GLRenderer->mBuffers->BindCurrentFB();
|
GLRenderer->mBuffers->BindCurrentFB();
|
||||||
|
|
||||||
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, Width, Height);
|
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, viewport.left, viewport.top, viewport.width, viewport.height);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||||
|
|
|
@ -65,8 +65,6 @@ public:
|
||||||
int GetClientWidth();
|
int GetClientWidth();
|
||||||
int GetClientHeight();
|
int GetClientHeight();
|
||||||
|
|
||||||
int GetTrueHeight() { return GetHeight(); }
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
int m_lock;
|
int m_lock;
|
||||||
bool m_isUpdatePending;
|
bool m_isUpdatePending;
|
||||||
|
|
|
@ -61,9 +61,6 @@ public:
|
||||||
int GetClientWidth();
|
int GetClientWidth();
|
||||||
int GetClientHeight();
|
int GetClientHeight();
|
||||||
|
|
||||||
//[C]
|
|
||||||
int GetTrueHeight() { return GetHeight();}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool CanUpdate();
|
bool CanUpdate();
|
||||||
void SetGammaTable(WORD *tbl);
|
void SetGammaTable(WORD *tbl);
|
||||||
|
|
Loading…
Reference in a new issue