mirror of
https://github.com/ZDoom/qzdoom-gpl.git
synced 2025-01-31 10:40:33 +00:00
Merge branch 'master' of https://github.com/coelckers/gzdoom
This commit is contained in:
commit
cf34e6f3e1
27 changed files with 312 additions and 225 deletions
|
@ -155,14 +155,10 @@ void F2DDrawer::AddTexture(FTexture *img, DrawParms &parms)
|
|||
color.a = (BYTE)(parms.Alpha * 255);
|
||||
|
||||
// scissor test doesn't use the current viewport for the coordinates, so use real screen coordinates
|
||||
int btm = (SCREENHEIGHT - screen->GetHeight()) / 2;
|
||||
btm = SCREENHEIGHT - btm;
|
||||
|
||||
int space = (static_cast<OpenGLFrameBuffer*>(screen)->GetTrueHeight() - screen->GetHeight()) / 2;
|
||||
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;
|
||||
dg.mScissor[0] = GLRenderer->ScreenToWindowX(parms.lclip);
|
||||
dg.mScissor[1] = GLRenderer->ScreenToWindowY(parms.dclip);
|
||||
dg.mScissor[2] = GLRenderer->ScreenToWindowX(parms.rclip) - dg.mScissor[0];
|
||||
dg.mScissor[3] = GLRenderer->ScreenToWindowY(parms.uclip) - dg.mScissor[1];
|
||||
|
||||
FSimpleVertex *ptr = &mVertices[dg.mVertIndex];
|
||||
ptr->Set(x, y, 0, u1, v1, color); ptr++;
|
||||
|
@ -399,6 +395,7 @@ void F2DDrawer::Flush()
|
|||
// DrawTypePoly may not use the color part of the vertex buffer because it needs to use gl_SetColor to produce proper output.
|
||||
if (lasttype == DrawTypePoly && dg->mType != DrawTypePoly)
|
||||
{
|
||||
gl_RenderState.ResetColor(); // this is needed to reset the desaturation.
|
||||
EnableColorArray(true);
|
||||
}
|
||||
else if (lasttype != DrawTypePoly && dg->mType == DrawTypePoly)
|
||||
|
@ -437,7 +434,8 @@ void F2DDrawer::Flush()
|
|||
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);
|
||||
gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
gl_RenderState.SetTextureMode(TM_MODULATE);
|
||||
|
|
|
@ -143,6 +143,8 @@ void FGLRenderer::BloomScene()
|
|||
mBloomExtractShader->Bind();
|
||||
mBloomExtractShader->SceneTexture.Set(0);
|
||||
mBloomExtractShader->Exposure.Set(mCameraExposure);
|
||||
mBloomExtractShader->Scale.Set(mSceneViewport.width / (float)mScreenViewport.width, mSceneViewport.height / (float)mScreenViewport.height);
|
||||
mBloomExtractShader->Offset.Set(mSceneViewport.left / (float)mScreenViewport.width, mSceneViewport.top / (float)mScreenViewport.height);
|
||||
RenderScreenQuad();
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
|
@ -152,8 +154,8 @@ void FGLRenderer::BloomScene()
|
|||
{
|
||||
const auto &level = mBuffers->BloomLevels[i];
|
||||
const auto &next = mBuffers->BloomLevels[i + 1];
|
||||
mBlurShader->BlurHorizontal(mVBO, blurAmount, sampleCount, level.VTexture, level.HFramebuffer, level.Width, level.Height);
|
||||
mBlurShader->BlurVertical(mVBO, blurAmount, sampleCount, level.HTexture, next.VFramebuffer, next.Width, next.Height);
|
||||
mBlurShader->BlurHorizontal(this, blurAmount, sampleCount, level.VTexture, level.HFramebuffer, level.Width, level.Height);
|
||||
mBlurShader->BlurVertical(this, blurAmount, sampleCount, level.HTexture, next.VFramebuffer, next.Width, next.Height);
|
||||
}
|
||||
|
||||
// Blur and upscale:
|
||||
|
@ -162,8 +164,8 @@ void FGLRenderer::BloomScene()
|
|||
const auto &level = mBuffers->BloomLevels[i];
|
||||
const auto &next = mBuffers->BloomLevels[i - 1];
|
||||
|
||||
mBlurShader->BlurHorizontal(mVBO, blurAmount, sampleCount, level.VTexture, level.HFramebuffer, level.Width, level.Height);
|
||||
mBlurShader->BlurVertical(mVBO, blurAmount, sampleCount, level.HTexture, level.VFramebuffer, level.Width, level.Height);
|
||||
mBlurShader->BlurHorizontal(this, blurAmount, sampleCount, level.VTexture, level.HFramebuffer, level.Width, level.Height);
|
||||
mBlurShader->BlurVertical(this, blurAmount, sampleCount, level.HTexture, level.VFramebuffer, level.Width, level.Height);
|
||||
|
||||
// Linear upscale:
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, next.VFramebuffer);
|
||||
|
@ -177,12 +179,12 @@ void FGLRenderer::BloomScene()
|
|||
RenderScreenQuad();
|
||||
}
|
||||
|
||||
mBlurShader->BlurHorizontal(mVBO, blurAmount, sampleCount, level0.VTexture, level0.HFramebuffer, level0.Width, level0.Height);
|
||||
mBlurShader->BlurVertical(mVBO, blurAmount, sampleCount, level0.HTexture, level0.VFramebuffer, level0.Width, level0.Height);
|
||||
mBlurShader->BlurHorizontal(this, blurAmount, sampleCount, level0.VTexture, level0.HFramebuffer, level0.Width, level0.Height);
|
||||
mBlurShader->BlurVertical(this, blurAmount, sampleCount, level0.HTexture, level0.VFramebuffer, level0.Width, level0.Height);
|
||||
|
||||
// Add bloom back to scene texture:
|
||||
mBuffers->BindCurrentFB();
|
||||
glViewport(mOutputViewport.left, mOutputViewport.top, mOutputViewport.width, mOutputViewport.height);
|
||||
glViewport(mSceneViewport.left, mSceneViewport.top, mSceneViewport.width, mSceneViewport.height);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendEquation(GL_FUNC_ADD);
|
||||
glBlendFunc(GL_ONE, GL_ONE);
|
||||
|
@ -193,6 +195,7 @@ void FGLRenderer::BloomScene()
|
|||
mBloomCombineShader->Bind();
|
||||
mBloomCombineShader->BloomTexture.Set(0);
|
||||
RenderScreenQuad();
|
||||
glViewport(mScreenViewport.left, mScreenViewport.top, mScreenViewport.width, mScreenViewport.height);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -243,7 +246,7 @@ void FGLRenderer::LensDistortScene()
|
|||
0.0f
|
||||
};
|
||||
|
||||
float aspect = mOutputViewport.width / mOutputViewport.height;
|
||||
float aspect = mSceneViewport.width / mSceneViewport.height;
|
||||
|
||||
// Scale factor to keep sampling within the input texture
|
||||
float r2 = aspect * aspect * 0.25 + 0.25f;
|
||||
|
@ -283,72 +286,33 @@ void FGLRenderer::CopyToBackbuffer(const GL_IRECT *bounds, bool applyGamma)
|
|||
if (FGLRenderBuffers::IsEnabled())
|
||||
{
|
||||
FGLPostProcessState savedState;
|
||||
|
||||
mBuffers->BindOutputFB();
|
||||
|
||||
int x, y, width, height;
|
||||
GL_IRECT box;
|
||||
if (bounds)
|
||||
{
|
||||
x = bounds->left;
|
||||
y = bounds->top;
|
||||
width = bounds->width;
|
||||
height = bounds->height;
|
||||
box = *bounds;
|
||||
}
|
||||
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);
|
||||
}
|
||||
ClearBorders();
|
||||
box = mOutputLetterbox;
|
||||
}
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
|
||||
// Present what was rendered:
|
||||
glViewport(x, y, width, height);
|
||||
glDisable(GL_BLEND);
|
||||
glViewport(box.left, box.top, box.width, box.height);
|
||||
|
||||
mPresentShader->Bind();
|
||||
mPresentShader->InputTexture.Set(0);
|
||||
if (!applyGamma || framebuffer->IsHWGammaActive())
|
||||
{
|
||||
mPresentShader->Gamma.Set(1.0f);
|
||||
mPresentShader->InvGamma.Set(1.0f);
|
||||
mPresentShader->Contrast.Set(1.0f);
|
||||
mPresentShader->Brightness.Set(0.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
mPresentShader->Gamma.Set(clamp<float>(Gamma, 0.1f, 4.f));
|
||||
mPresentShader->InvGamma.Set(1.0f / clamp<float>(Gamma, 0.1f, 4.f));
|
||||
mPresentShader->Contrast.Set(clamp<float>(vid_contrast, 0.1f, 3.f));
|
||||
mPresentShader->Brightness.Set(clamp<float>(vid_brightness, -0.8f, 0.8f));
|
||||
}
|
||||
|
@ -358,4 +322,48 @@ void FGLRenderer::CopyToBackbuffer(const GL_IRECT *bounds, bool applyGamma)
|
|||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -139,30 +139,46 @@ void FGLRenderBuffers::DeleteFrameBuffer(GLuint &handle)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void FGLRenderBuffers::Setup(int width, int height)
|
||||
void FGLRenderBuffers::Setup(int width, int height, int sceneWidth, int sceneHeight)
|
||||
{
|
||||
if (!IsEnabled())
|
||||
return;
|
||||
|
||||
if (width <= 0 || height <= 0)
|
||||
I_FatalError("Requested invalid render buffer sizes: screen = %dx%d", width, height);
|
||||
|
||||
int samples = GetCvarSamples();
|
||||
|
||||
GLint activeTex;
|
||||
GLint textureBinding;
|
||||
glGetIntegerv(GL_ACTIVE_TEXTURE, &activeTex);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glGetIntegerv(GL_TEXTURE_BINDING_2D, &textureBinding);
|
||||
|
||||
if (width == mWidth && height == mHeight && mSamples != samples)
|
||||
{
|
||||
CreateScene(mWidth, mHeight, samples);
|
||||
mSamples = samples;
|
||||
}
|
||||
else if (width > mWidth || height > mHeight)
|
||||
else if (width != mWidth || height != mHeight)
|
||||
{
|
||||
CreatePipeline(width, height);
|
||||
CreateScene(width, height, samples);
|
||||
CreateBloom(width, height);
|
||||
mWidth = width;
|
||||
mHeight = height;
|
||||
mSamples = samples;
|
||||
}
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
// Bloom bluring buffers need to match the scene to avoid bloom bleeding artifacts
|
||||
if (mBloomWidth != sceneWidth || mBloomHeight != sceneHeight)
|
||||
{
|
||||
CreateBloom(sceneWidth, sceneHeight);
|
||||
mBloomWidth = sceneWidth;
|
||||
mBloomHeight = sceneHeight;
|
||||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_BINDING_2D, textureBinding);
|
||||
glActiveTexture(activeTex);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, 0);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
@ -219,6 +235,10 @@ void FGLRenderBuffers::CreatePipeline(int width, int height)
|
|||
void FGLRenderBuffers::CreateBloom(int width, int height)
|
||||
{
|
||||
ClearBloom();
|
||||
|
||||
// No scene, no bloom!
|
||||
if (width <= 0 || height <= 0)
|
||||
return;
|
||||
|
||||
int bloomWidth = MAX(width / 2, 1);
|
||||
int bloomHeight = MAX(height / 2, 1);
|
||||
|
@ -246,7 +266,7 @@ void FGLRenderBuffers::CreateBloom(int width, int height)
|
|||
|
||||
GLuint FGLRenderBuffers::GetHdrFormat()
|
||||
{
|
||||
return ((gl.flags & RFL_NO_RGBA16F) != 0) ? GL_RGBA8 : GL_RGBA16F;
|
||||
return ((gl.flags & RFL_NO_RGBA16F) != 0) ? GL_RGBA8 : GL_RGBA16;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -276,10 +296,9 @@ int FGLRenderBuffers::GetCvarSamples()
|
|||
|
||||
GLuint FGLRenderBuffers::Create2DTexture(GLuint format, int width, int height)
|
||||
{
|
||||
GLuint type = (format == GL_RGBA16F) ? GL_FLOAT : GL_UNSIGNED_BYTE;
|
||||
GLuint type = (format == GL_RGBA16) ? GL_UNSIGNED_SHORT : GL_UNSIGNED_BYTE;
|
||||
GLuint handle = 0;
|
||||
glGenTextures(1, &handle);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, handle);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, GL_RGBA, type, nullptr);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
|
@ -329,6 +348,7 @@ GLuint FGLRenderBuffers::CreateFrameBuffer(GLuint colorbuffer)
|
|||
glBindFramebuffer(GL_FRAMEBUFFER, handle);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorbuffer, 0);
|
||||
CheckFrameBufferCompleteness();
|
||||
ClearFrameBuffer();
|
||||
return handle;
|
||||
}
|
||||
|
||||
|
@ -343,6 +363,7 @@ GLuint FGLRenderBuffers::CreateFrameBuffer(GLuint colorbuffer, GLuint depthstenc
|
|||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorbuffer, 0);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depthstencil);
|
||||
CheckFrameBufferCompleteness();
|
||||
ClearFrameBuffer();
|
||||
return handle;
|
||||
}
|
||||
|
||||
|
@ -358,6 +379,7 @@ GLuint FGLRenderBuffers::CreateFrameBuffer(GLuint colorbuffer, GLuint depth, GLu
|
|||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depth);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, stencil);
|
||||
CheckFrameBufferCompleteness();
|
||||
ClearFrameBuffer();
|
||||
return handle;
|
||||
}
|
||||
|
||||
|
@ -389,6 +411,31 @@ void FGLRenderBuffers::CheckFrameBufferCompleteness()
|
|||
I_FatalError(error);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Clear frame buffer to make sure it never contains uninitialized data
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FGLRenderBuffers::ClearFrameBuffer()
|
||||
{
|
||||
GLboolean scissorEnabled;
|
||||
GLint stencilValue;
|
||||
GLdouble depthValue;
|
||||
glGetBooleanv(GL_SCISSOR_TEST, &scissorEnabled);
|
||||
glGetIntegerv(GL_STENCIL_CLEAR_VALUE, &stencilValue);
|
||||
glGetDoublev(GL_DEPTH_CLEAR_VALUE, &depthValue);
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
glClearColor(0.0, 0.0, 0.0, 0.0);
|
||||
glClearDepth(0.0);
|
||||
glClearStencil(0);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||
glClearStencil(stencilValue);
|
||||
glClearDepth(depthValue);
|
||||
if (scissorEnabled)
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Resolves the multisample frame buffer by copying it to the scene texture
|
||||
|
|
|
@ -20,7 +20,7 @@ public:
|
|||
FGLRenderBuffers();
|
||||
~FGLRenderBuffers();
|
||||
|
||||
void Setup(int width, int height);
|
||||
void Setup(int width, int height, int sceneWidth, int sceneHeight);
|
||||
|
||||
void BindSceneFB();
|
||||
void BlitSceneToTexture();
|
||||
|
@ -54,6 +54,7 @@ private:
|
|||
GLuint CreateFrameBuffer(GLuint colorbuffer, GLuint depthstencil, bool colorIsARenderBuffer);
|
||||
GLuint CreateFrameBuffer(GLuint colorbuffer, GLuint depth, GLuint stencil, bool colorIsARenderBuffer);
|
||||
void CheckFrameBufferCompleteness();
|
||||
void ClearFrameBuffer();
|
||||
void DeleteTexture(GLuint &handle);
|
||||
void DeleteRenderBuffer(GLuint &handle);
|
||||
void DeleteFrameBuffer(GLuint &handle);
|
||||
|
@ -64,6 +65,8 @@ private:
|
|||
int mWidth = 0;
|
||||
int mHeight = 0;
|
||||
int mSamples = 0;
|
||||
int mBloomWidth = 0;
|
||||
int mBloomHeight = 0;
|
||||
|
||||
static const int NumPipelineTextures = 2;
|
||||
int mCurrentPipelineTexture = 0;
|
||||
|
|
|
@ -79,6 +79,8 @@
|
|||
|
||||
EXTERN_CVAR(Int, screenblocks)
|
||||
|
||||
CVAR(Bool, gl_scale_viewport, true, 0);
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Renderer interface
|
||||
|
@ -190,16 +192,14 @@ void FGLRenderer::SetOutputViewport(GL_IRECT *bounds)
|
|||
{
|
||||
if (bounds)
|
||||
{
|
||||
mOutputViewport = *bounds;
|
||||
mOutputViewportLB = *bounds;
|
||||
mSceneViewport = *bounds;
|
||||
mScreenViewport = *bounds;
|
||||
mOutputLetterbox = *bounds;
|
||||
return;
|
||||
}
|
||||
|
||||
int height, width;
|
||||
|
||||
// Special handling so the view with a visible status bar displays properly
|
||||
|
||||
int height, width;
|
||||
if (screenblocks >= 10)
|
||||
{
|
||||
height = framebuffer->GetHeight();
|
||||
|
@ -211,29 +211,64 @@ void FGLRenderer::SetOutputViewport(GL_IRECT *bounds)
|
|||
width = (screenblocks*framebuffer->GetWidth() / 10);
|
||||
}
|
||||
|
||||
int trueheight = framebuffer->GetTrueHeight(); // ugh...
|
||||
int bars = (trueheight - framebuffer->GetHeight()) / 2;
|
||||
|
||||
int vw = viewwidth;
|
||||
int vh = viewheight;
|
||||
// Back buffer letterbox for the final output
|
||||
int clientWidth = framebuffer->GetClientWidth();
|
||||
int clientHeight = framebuffer->GetClientHeight();
|
||||
int screenWidth = framebuffer->GetWidth();
|
||||
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
|
||||
mScreenViewport.left = 0;
|
||||
mScreenViewport.top = 0;
|
||||
mScreenViewport.width = framebuffer->GetWidth();
|
||||
mScreenViewport.height = framebuffer->GetHeight();
|
||||
mScreenViewport.width = screenWidth;
|
||||
mScreenViewport.height = screenHeight;
|
||||
|
||||
// Letterboxed viewport for the main scene
|
||||
mOutputViewportLB.left = viewwindowx;
|
||||
mOutputViewportLB.top = trueheight - bars - (height + viewwindowy - ((height - vh) / 2));
|
||||
mOutputViewportLB.width = vw;
|
||||
mOutputViewportLB.height = height;
|
||||
// Viewport for the 3D scene
|
||||
mSceneViewport.left = viewwindowx;
|
||||
mSceneViewport.top = screenHeight - (height + viewwindowy - ((height - viewheight) / 2));
|
||||
mSceneViewport.width = viewwidth;
|
||||
mSceneViewport.height = height;
|
||||
|
||||
// Entire canvas for player sprites
|
||||
mOutputViewport.left = 0;
|
||||
mOutputViewport.top = (trueheight - framebuffer->GetHeight()) / 2;
|
||||
mOutputViewport.width = framebuffer->GetWidth();
|
||||
mOutputViewport.height = framebuffer->GetHeight();
|
||||
// Scale viewports to fit letterbox
|
||||
if (gl_scale_viewport || !FGLRenderBuffers::IsEnabled())
|
||||
{
|
||||
mScreenViewport.width = mOutputLetterbox.width;
|
||||
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());
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
@ -251,16 +286,16 @@ void FGLRenderer::Begin2D()
|
|||
{
|
||||
if (FGLRenderBuffers::IsEnabled())
|
||||
{
|
||||
mBuffers->Setup(framebuffer->GetWidth(), framebuffer->GetHeight());
|
||||
mBuffers->Setup(mScreenViewport.width, mScreenViewport.height, mSceneViewport.width, mSceneViewport.height);
|
||||
if (mDrawingScene2D)
|
||||
mBuffers->BindSceneFB();
|
||||
else
|
||||
mBuffers->BindCurrentFB();
|
||||
}
|
||||
glViewport(mScreenViewport.left, mScreenViewport.top, mScreenViewport.width, mScreenViewport.height);
|
||||
glScissor(mScreenViewport.left, mScreenViewport.top, mScreenViewport.width, mScreenViewport.height);
|
||||
|
||||
gl_RenderState.EnableFog(false);
|
||||
gl_RenderState.Set2DMode(true);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
@ -363,32 +398,3 @@ unsigned char *FGLRenderer::GetTextureBuffer(FTexture *tex, int &w, int &h)
|
|||
}
|
||||
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;
|
||||
|
||||
GL_IRECT mScreenViewport;
|
||||
GL_IRECT mOutputViewportLB;
|
||||
GL_IRECT mOutputViewport;
|
||||
GL_IRECT mSceneViewport;
|
||||
GL_IRECT mOutputLetterbox;
|
||||
bool mDrawingScene2D = false;
|
||||
float mCameraExposure = 1.0f;
|
||||
|
||||
FGLRenderer(OpenGLFrameBuffer *fb);
|
||||
~FGLRenderer() ;
|
||||
|
||||
void SetOutputViewport(GL_IRECT *bounds);
|
||||
int ScreenToWindowX(int x);
|
||||
int ScreenToWindowY(int y);
|
||||
|
||||
angle_t FrustumAngle();
|
||||
void SetViewArea();
|
||||
void SetOutputViewport(GL_IRECT *bounds);
|
||||
void Set3DViewport(bool mainview);
|
||||
void Reset3DViewport();
|
||||
sector_t *RenderViewpoint (AActor * camera, GL_IRECT * bounds, float fov, float ratio, float fovratio, bool mainview, bool toscreen);
|
||||
|
|
|
@ -81,7 +81,6 @@ void FRenderState::Reset()
|
|||
mAlphaThreshold = 0.5f;
|
||||
mBlendEquation = GL_FUNC_ADD;
|
||||
mObjectColor = 0xffffffff;
|
||||
m2D = true;
|
||||
mVertexBuffer = mCurrentVertexBuffer = NULL;
|
||||
mColormapState = CM_DEFAULT;
|
||||
mLightParms[3] = -1.f;
|
||||
|
|
|
@ -60,13 +60,12 @@ class FRenderState
|
|||
int mSrcBlend, mDstBlend;
|
||||
float mAlphaThreshold;
|
||||
int mBlendEquation;
|
||||
bool m2D;
|
||||
bool mModelMatrixEnabled;
|
||||
bool mTextureMatrixEnabled;
|
||||
bool mLastDepthClamp;
|
||||
float mInterpolationFactor;
|
||||
float mClipHeight, mClipHeightDirection;
|
||||
float mShaderTimer;
|
||||
bool mLastDepthClamp;
|
||||
|
||||
FVertexBuffer *mVertexBuffer, *mCurrentVertexBuffer;
|
||||
FStateVec4 mColor;
|
||||
|
@ -428,11 +427,6 @@ public:
|
|||
return res;
|
||||
}
|
||||
|
||||
void Set2DMode(bool on)
|
||||
{
|
||||
m2D = on;
|
||||
}
|
||||
|
||||
void SetInterpolationFactor(float fac)
|
||||
{
|
||||
mInterpolationFactor = fac;
|
||||
|
|
|
@ -135,7 +135,6 @@ void GLPortal::ClearScreen()
|
|||
gl_MatrixStack.Pop(gl_RenderState.mViewMatrix);
|
||||
gl_RenderState.ApplyMatrices();
|
||||
if (multi) glEnable(GL_MULTISAMPLE);
|
||||
gl_RenderState.Set2DMode(false);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -157,7 +157,7 @@ void FGLRenderer::SetViewArea()
|
|||
|
||||
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())
|
||||
{
|
||||
mBuffers->Setup(mOutputViewport.width, mOutputViewport.height);
|
||||
mBuffers->Setup(mScreenViewport.width, mScreenViewport.height, mSceneViewport.width, mSceneViewport.height);
|
||||
mBuffers->BindSceneFB();
|
||||
}
|
||||
|
||||
const auto &bounds = mOutputViewportLB;
|
||||
const auto &bounds = mSceneViewport;
|
||||
glViewport(bounds.left, bounds.top, bounds.width, bounds.height);
|
||||
glScissor(bounds.left, bounds.top, bounds.width, bounds.height);
|
||||
|
||||
|
@ -223,7 +223,6 @@ void FGLRenderer::SetProjection(float fov, float ratio, float fovratio)
|
|||
|
||||
float fovy = 2 * RAD2DEG(atan(tan(DEG2RAD(fov) / 2) / fovratio));
|
||||
gl_RenderState.mProjectionMatrix.perspective(fovy, ratio, 5.f, 65536.f);
|
||||
gl_RenderState.Set2DMode(false);
|
||||
}
|
||||
|
||||
// raw matrix input from stereo 3d modes
|
||||
|
@ -231,7 +230,6 @@ void FGLRenderer::SetProjection(VSMatrix matrix)
|
|||
{
|
||||
gl_RenderState.mProjectionMatrix.loadIdentity();
|
||||
gl_RenderState.mProjectionMatrix.multMatrix(matrix);
|
||||
gl_RenderState.Set2DMode(false);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
|
@ -119,7 +119,7 @@ void FSkyVertexBuffer::SkyVertex(int r, int c, bool zflip)
|
|||
static const FAngle maxSideAngle = 60.f;
|
||||
static const float scale = 10000.;
|
||||
|
||||
FAngle topAngle= (c / (float)mColumns * 360.f);
|
||||
FAngle topAngle = (c / (float)mColumns * 360.f);
|
||||
FAngle sideAngle = maxSideAngle * (mRows - r) / mRows;
|
||||
float height = sideAngle.Sin();
|
||||
float realRadius = scale * sideAngle.Cos();
|
||||
|
@ -127,13 +127,13 @@ void FSkyVertexBuffer::SkyVertex(int r, int c, bool zflip)
|
|||
float z = (!zflip) ? scale * height : -scale * height;
|
||||
|
||||
FSkyVertex vert;
|
||||
|
||||
|
||||
vert.color = r == 0 ? 0xffffff : 0xffffffff;
|
||||
|
||||
|
||||
// And the texture coordinates.
|
||||
if(!zflip) // Flipped Y is for the lower hemisphere.
|
||||
if (!zflip) // Flipped Y is for the lower hemisphere.
|
||||
{
|
||||
vert.u = (-c / (float)mColumns) ;
|
||||
vert.u = (-c / (float)mColumns);
|
||||
vert.v = (r / (float)mRows);
|
||||
}
|
||||
else
|
||||
|
@ -142,7 +142,7 @@ void FSkyVertexBuffer::SkyVertex(int r, int c, bool zflip)
|
|||
vert.v = 1.0f + ((mRows - r) / (float)mRows);
|
||||
}
|
||||
|
||||
if (r != 4) z+=300;
|
||||
if (r != 4) z += 300;
|
||||
// And finally the vertex.
|
||||
vert.x = -pos.X; // Doom mirrors the sky vertically!
|
||||
vert.y = z - 1.f;
|
||||
|
@ -194,21 +194,21 @@ void FSkyVertexBuffer::CreateDome()
|
|||
// the first thing we put into the buffer is the fog layer object which is just 4 triangles around the viewpoint.
|
||||
|
||||
mVertices.Reserve(12);
|
||||
mVertices[0].Set( 1.0f, 1.0f, -1.0f);
|
||||
mVertices[1].Set( 1.0f, -1.0f, -1.0f);
|
||||
mVertices[2].Set(-1.0f, 0.0f, -1.0f);
|
||||
mVertices[0].Set(1.0f, 1.0f, -1.0f);
|
||||
mVertices[1].Set(1.0f, -1.0f, -1.0f);
|
||||
mVertices[2].Set(-1.0f, 0.0f, -1.0f);
|
||||
|
||||
mVertices[3].Set( 1.0f, 1.0f, -1.0f);
|
||||
mVertices[4].Set( 1.0f, -1.0f, -1.0f);
|
||||
mVertices[5].Set( 0.0f, 0.0f, 1.0f);
|
||||
mVertices[3].Set(1.0f, 1.0f, -1.0f);
|
||||
mVertices[4].Set(1.0f, -1.0f, -1.0f);
|
||||
mVertices[5].Set(0.0f, 0.0f, 1.0f);
|
||||
|
||||
mVertices[6].Set(-1.0f, 0.0f, -1.0f);
|
||||
mVertices[7].Set( 1.0f, 1.0f, -1.0f);
|
||||
mVertices[8].Set( 0.0f, 0.0f, 1.0f);
|
||||
mVertices[7].Set(1.0f, 1.0f, -1.0f);
|
||||
mVertices[8].Set(0.0f, 0.0f, 1.0f);
|
||||
|
||||
mVertices[9].Set(1.0f, -1.0f, -1.0f);
|
||||
mVertices[10].Set(-1.0f, 0.0f, -1.0f);
|
||||
mVertices[11].Set( 0.0f, 0.0f, 1.0f);
|
||||
mVertices[11].Set(0.0f, 0.0f, 1.0f);
|
||||
|
||||
mColumns = 128;
|
||||
mRows = 4;
|
||||
|
@ -358,7 +358,7 @@ void RenderDome(FMaterial * tex, float x_offset, float y_offset, bool mirror, in
|
|||
gl_RenderState.EnableModelMatrix(true);
|
||||
|
||||
gl_RenderState.mModelMatrix.loadIdentity();
|
||||
gl_RenderState.mModelMatrix.rotate(-180.0f+x_offset, 0.f, 1.f, 0.f);
|
||||
gl_RenderState.mModelMatrix.rotate(-180.0f + x_offset, 0.f, 1.f, 0.f);
|
||||
|
||||
float xscale = texw < 1024.f ? floor(1024.f / float(texw)) : 1.f;
|
||||
float yscale = 1.f;
|
||||
|
@ -366,18 +366,18 @@ void RenderDome(FMaterial * tex, float x_offset, float y_offset, bool mirror, in
|
|||
{
|
||||
// smaller sky textures must be tiled. We restrict it to 128 sky pixels, though
|
||||
gl_RenderState.mModelMatrix.translate(0.f, -1250.f, 0.f);
|
||||
gl_RenderState.mModelMatrix.scale(1.f, 128/230.f, 1.f);
|
||||
gl_RenderState.mModelMatrix.scale(1.f, 128 / 230.f, 1.f);
|
||||
yscale = 128 / texh; // intentionally left as integer.
|
||||
}
|
||||
else if (texh < 200)
|
||||
{
|
||||
gl_RenderState.mModelMatrix.translate(0.f, -1250.f, 0.f);
|
||||
gl_RenderState.mModelMatrix.scale(1.f, texh/230.f, 1.f);
|
||||
gl_RenderState.mModelMatrix.scale(1.f, texh / 230.f, 1.f);
|
||||
}
|
||||
else if (texh <= 240)
|
||||
{
|
||||
gl_RenderState.mModelMatrix.translate(0.f, (200 - texh + tex->tex->SkyOffset + skyoffset)*skyoffsetfactor, 0.f);
|
||||
gl_RenderState.mModelMatrix.scale(1.f, 1.f + ((texh-200.f)/200.f) * 1.17f, 1.f);
|
||||
gl_RenderState.mModelMatrix.scale(1.f, 1.f + ((texh - 200.f) / 200.f) * 1.17f, 1.f);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -387,12 +387,13 @@ void RenderDome(FMaterial * tex, float x_offset, float y_offset, bool mirror, in
|
|||
}
|
||||
gl_RenderState.EnableTextureMatrix(true);
|
||||
gl_RenderState.mTextureMatrix.loadIdentity();
|
||||
gl_RenderState.mTextureMatrix.scale(mirror? -xscale : xscale, yscale, 1.f);
|
||||
gl_RenderState.mTextureMatrix.scale(mirror ? -xscale : xscale, yscale, 1.f);
|
||||
gl_RenderState.mTextureMatrix.translate(1.f, y_offset / texh, 1.f);
|
||||
}
|
||||
|
||||
GLRenderer->mSkyVBO->RenderDome(tex, mode);
|
||||
gl_RenderState.EnableTextureMatrix(false);
|
||||
gl_RenderState.EnableModelMatrix(false);
|
||||
}
|
||||
|
||||
|
||||
|
@ -493,7 +494,7 @@ void GLSkyPortal::DrawContents()
|
|||
bool oldClamp = gl_RenderState.SetDepthClamp(true);
|
||||
|
||||
gl_MatrixStack.Push(gl_RenderState.mViewMatrix);
|
||||
GLRenderer->SetupView(0, 0, 0, ViewAngle, !!(MirrorFlag&1), !!(PlaneMirrorFlag&1));
|
||||
GLRenderer->SetupView(0, 0, 0, ViewAngle, !!(MirrorFlag & 1), !!(PlaneMirrorFlag & 1));
|
||||
|
||||
gl_RenderState.SetVertexBuffer(GLRenderer->mSkyVBO);
|
||||
if (origin->texture[0] && origin->texture[0]->tex->gl_info.bSkybox)
|
||||
|
@ -536,6 +537,5 @@ void GLSkyPortal::DrawContents()
|
|||
gl_RenderState.ApplyMatrices();
|
||||
glset.lightmode = oldlightmode;
|
||||
gl_RenderState.SetDepthClamp(oldClamp);
|
||||
gl_RenderState.EnableModelMatrix(false);
|
||||
}
|
||||
|
||||
|
|
|
@ -60,6 +60,8 @@ void FBloomExtractShader::Bind()
|
|||
mShader.SetAttribLocation(0, "PositionInProjection");
|
||||
SceneTexture.Init(mShader, "SceneTexture");
|
||||
Exposure.Init(mShader, "ExposureAdjustment");
|
||||
Scale.Init(mShader, "Scale");
|
||||
Offset.Init(mShader, "Offset");
|
||||
}
|
||||
mShader.Bind();
|
||||
}
|
||||
|
|
|
@ -10,6 +10,8 @@ public:
|
|||
|
||||
FBufferedUniform1i SceneTexture;
|
||||
FBufferedUniform1f Exposure;
|
||||
FBufferedUniform2f Scale;
|
||||
FBufferedUniform2f Offset;
|
||||
|
||||
private:
|
||||
FShaderProgram mShader;
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
#include "gl/system/gl_cvars.h"
|
||||
#include "gl/shaders/gl_blurshader.h"
|
||||
#include "gl/data/gl_vertexbuffer.h"
|
||||
#include "gl/renderer/gl_renderer.h"
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
|
@ -56,9 +57,9 @@
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void FBlurShader::BlurVertical(FFlatVertexBuffer *vbo, float blurAmount, int sampleCount, GLuint inputTexture, GLuint outputFrameBuffer, int width, int height)
|
||||
void FBlurShader::BlurVertical(FGLRenderer *renderer, float blurAmount, int sampleCount, GLuint inputTexture, GLuint outputFrameBuffer, int width, int height)
|
||||
{
|
||||
Blur(vbo, blurAmount, sampleCount, inputTexture, outputFrameBuffer, width, height, true);
|
||||
Blur(renderer, blurAmount, sampleCount, inputTexture, outputFrameBuffer, width, height, true);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -67,9 +68,9 @@ void FBlurShader::BlurVertical(FFlatVertexBuffer *vbo, float blurAmount, int sam
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void FBlurShader::BlurHorizontal(FFlatVertexBuffer *vbo, float blurAmount, int sampleCount, GLuint inputTexture, GLuint outputFrameBuffer, int width, int height)
|
||||
void FBlurShader::BlurHorizontal(FGLRenderer *renderer, float blurAmount, int sampleCount, GLuint inputTexture, GLuint outputFrameBuffer, int width, int height)
|
||||
{
|
||||
Blur(vbo, blurAmount, sampleCount, inputTexture, outputFrameBuffer, width, height, false);
|
||||
Blur(renderer, blurAmount, sampleCount, inputTexture, outputFrameBuffer, width, height, false);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -78,7 +79,7 @@ void FBlurShader::BlurHorizontal(FFlatVertexBuffer *vbo, float blurAmount, int s
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void FBlurShader::Blur(FFlatVertexBuffer *vbo, float blurAmount, int sampleCount, GLuint inputTexture, GLuint outputFrameBuffer, int width, int height, bool vertical)
|
||||
void FBlurShader::Blur(FGLRenderer *renderer, float blurAmount, int sampleCount, GLuint inputTexture, GLuint outputFrameBuffer, int width, int height, bool vertical)
|
||||
{
|
||||
BlurSetup *setup = GetSetup(blurAmount, sampleCount);
|
||||
if (vertical)
|
||||
|
@ -111,12 +112,7 @@ void FBlurShader::Blur(FFlatVertexBuffer *vbo, float blurAmount, int sampleCount
|
|||
glViewport(0, 0, width, height);
|
||||
glDisable(GL_BLEND);
|
||||
|
||||
FFlatVertex *ptr = vbo->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++;
|
||||
vbo->RenderCurrent(ptr, GL_TRIANGLE_STRIP);
|
||||
renderer->RenderScreenQuad();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
|
@ -4,16 +4,16 @@
|
|||
#include "gl_shaderprogram.h"
|
||||
#include <memory>
|
||||
|
||||
class FFlatVertexBuffer;
|
||||
class FGLRenderer;
|
||||
|
||||
class FBlurShader
|
||||
{
|
||||
public:
|
||||
void BlurVertical(FFlatVertexBuffer *vbo, float blurAmount, int sampleCount, GLuint inputTexture, GLuint outputFrameBuffer, int width, int height);
|
||||
void BlurHorizontal(FFlatVertexBuffer *vbo, float blurAmount, int sampleCount, GLuint inputTexture, GLuint outputFrameBuffer, int width, int height);
|
||||
void BlurVertical(FGLRenderer *renderer, float blurAmount, int sampleCount, GLuint inputTexture, GLuint outputFrameBuffer, int width, int height);
|
||||
void BlurHorizontal(FGLRenderer *renderer, float blurAmount, int sampleCount, GLuint inputTexture, GLuint outputFrameBuffer, int width, int height);
|
||||
|
||||
private:
|
||||
void Blur(FFlatVertexBuffer *vbo, float blurAmount, int sampleCount, GLuint inputTexture, GLuint outputFrameBuffer, int width, int height, bool vertical);
|
||||
void Blur(FGLRenderer *renderer, float blurAmount, int sampleCount, GLuint inputTexture, GLuint outputFrameBuffer, int width, int height, bool vertical);
|
||||
|
||||
struct BlurSetup
|
||||
{
|
||||
|
|
|
@ -60,7 +60,7 @@ void FPresentShader::Bind()
|
|||
mShader.SetAttribLocation(0, "PositionInProjection");
|
||||
mShader.SetAttribLocation(1, "UV");
|
||||
InputTexture.Init(mShader, "InputTexture");
|
||||
Gamma.Init(mShader, "Gamma");
|
||||
InvGamma.Init(mShader, "InvGamma");
|
||||
Contrast.Init(mShader, "Contrast");
|
||||
Brightness.Init(mShader, "Brightness");
|
||||
Scale.Init(mShader, "UVScale");
|
||||
|
|
|
@ -9,7 +9,7 @@ public:
|
|||
void Bind();
|
||||
|
||||
FBufferedUniform1i InputTexture;
|
||||
FBufferedUniform1f Gamma;
|
||||
FBufferedUniform1f InvGamma;
|
||||
FBufferedUniform1f Contrast;
|
||||
FBufferedUniform1f Brightness;
|
||||
FBufferedUniform2f Scale;
|
||||
|
|
|
@ -160,10 +160,6 @@ void OpenGLFrameBuffer::InitializeState()
|
|||
|
||||
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->SetOutputViewport(nullptr);
|
||||
Begin2D(false);
|
||||
|
@ -191,13 +187,8 @@ void OpenGLFrameBuffer::Update()
|
|||
DrawRateStuff();
|
||||
GLRenderer->Flush();
|
||||
|
||||
if (GetTrueHeight() != GetHeight())
|
||||
{
|
||||
if (GLRenderer != NULL)
|
||||
GLRenderer->ClearBorders();
|
||||
GLRenderer->SetOutputViewport(nullptr);
|
||||
|
||||
Begin2D(false);
|
||||
}
|
||||
if (gl_draw_sync || !swapped)
|
||||
{
|
||||
Swap();
|
||||
|
@ -484,15 +475,41 @@ void OpenGLFrameBuffer::FillSimplePoly(FTexture *texture, FVector2 *points, int
|
|||
|
||||
void OpenGLFrameBuffer::GetScreenshotBuffer(const BYTE *&buffer, int &pitch, ESSType &color_type)
|
||||
{
|
||||
const auto &viewport = GLRenderer->mOutputLetterbox;
|
||||
|
||||
// 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 * 3);
|
||||
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 h = SCREENHEIGHT;
|
||||
|
||||
ReleaseScreenshotBuffer();
|
||||
ScreenshotBuffer = new BYTE[w * h * 3];
|
||||
|
||||
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
||||
glReadPixels(0,(GetTrueHeight() - GetHeight()) / 2,w,h,GL_RGB,GL_UNSIGNED_BYTE,ScreenshotBuffer);
|
||||
glPixelStorei(GL_PACK_ALIGNMENT, 4);
|
||||
float rcpWidth = 1.0f / w;
|
||||
float rcpHeight = 1.0f / h;
|
||||
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 * viewport.width) * 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;
|
||||
color_type = SS_RGB;
|
||||
buffer = ScreenshotBuffer + w * 3 * (h - 1);
|
||||
|
|
|
@ -151,8 +151,9 @@ bool OpenGLFrameBuffer::WipeStartScreen(int type)
|
|||
return false;
|
||||
}
|
||||
|
||||
wipestartscreen = new FHardwareTexture(Width, Height, true);
|
||||
wipestartscreen->CreateTexture(NULL, Width, Height, 0, false, 0);
|
||||
const auto &viewport = GLRenderer->mScreenViewport;
|
||||
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(1, CLAMP_NONE, -1);
|
||||
glFinish();
|
||||
|
@ -161,14 +162,14 @@ bool OpenGLFrameBuffer::WipeStartScreen(int type)
|
|||
if (FGLRenderBuffers::IsEnabled())
|
||||
{
|
||||
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
|
||||
{
|
||||
GLint readbuffer = 0;
|
||||
glGetIntegerv(GL_READ_BUFFER, &readbuffer);
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -189,8 +190,10 @@ bool OpenGLFrameBuffer::WipeStartScreen(int type)
|
|||
void OpenGLFrameBuffer::WipeEndScreen()
|
||||
{
|
||||
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);
|
||||
glFinish();
|
||||
wipeendscreen->Bind(0, false, false);
|
||||
|
@ -198,7 +201,7 @@ void OpenGLFrameBuffer::WipeEndScreen()
|
|||
if (FGLRenderBuffers::IsEnabled())
|
||||
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_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
|
|
|
@ -148,8 +148,8 @@ static void RotationComp(const sector_t *sec, int which, double dx, double dy, d
|
|||
}
|
||||
else
|
||||
{
|
||||
double ca = an.Cos();
|
||||
double sa = an.Sin();
|
||||
double ca = -an.Cos();
|
||||
double sa = -an.Sin();
|
||||
tdx = dx*ca - dy*sa;
|
||||
tdy = dy*ca + dx*sa;
|
||||
}
|
||||
|
@ -350,8 +350,8 @@ DScroller::DScroller (double dx, double dy, const line_t *l,
|
|||
if (y > x) d = x, x = y, y = d;
|
||||
|
||||
d = x / g_sin(g_atan2(y, x) + M_PI / 2);
|
||||
x = (-dy * l->Delta().Y + dx * l->Delta().X) / d;
|
||||
y = (-dx * l->Delta().Y - dy * l->Delta().Y) / d;
|
||||
x = -(dy * l->Delta().Y + dx * l->Delta().X) / d;
|
||||
y = -(dx * l->Delta().Y - dy * l->Delta().X) / d;
|
||||
|
||||
m_Type = EScroll::sc_side;
|
||||
m_dx = x;
|
||||
|
|
|
@ -303,9 +303,13 @@ void FTraceInfo::Setup3DFloors()
|
|||
{
|
||||
if (Check3DFloorPlane(rover, false))
|
||||
{
|
||||
Results->Crossed3DWater = rover;
|
||||
Results->Crossed3DWaterPos = Results->HitPos;
|
||||
Results->Distance = 0;
|
||||
// only consider if the plane is above the actual floor.
|
||||
if (rover->top.plane->ZatPoint(Results->HitPos) > bf)
|
||||
{
|
||||
Results->Crossed3DWater = rover;
|
||||
Results->Crossed3DWaterPos = Results->HitPos;
|
||||
Results->Distance = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -766,9 +770,13 @@ bool FTraceInfo::TraceTraverse (int ptflags)
|
|||
{
|
||||
if (Check3DFloorPlane(rover, false))
|
||||
{
|
||||
Results->Crossed3DWater = rover;
|
||||
Results->Crossed3DWaterPos = Results->HitPos;
|
||||
Results->Distance = 0;
|
||||
// only consider if the plane is above the actual floor.
|
||||
if (rover->top.plane->ZatPoint(Results->HitPos) > CurSector->floorplane.ZatPoint(Results->HitPos))
|
||||
{
|
||||
Results->Crossed3DWater = rover;
|
||||
Results->Crossed3DWaterPos = Results->HitPos;
|
||||
Results->Distance = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -168,7 +168,7 @@ namespace
|
|||
const NSInteger LEVEL_WINDOWED = NSNormalWindowLevel;
|
||||
|
||||
const NSUInteger STYLE_MASK_FULLSCREEN = NSBorderlessWindowMask;
|
||||
const NSUInteger STYLE_MASK_WINDOWED = NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask;
|
||||
const NSUInteger STYLE_MASK_WINDOWED = NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSResizableWindowMask;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1206,12 +1206,18 @@ void SDLGLFB::ResetGammaTable()
|
|||
|
||||
int SDLGLFB::GetClientWidth()
|
||||
{
|
||||
return static_cast<int>(rbOpts.width + 2.0f * rbOpts.shiftX);
|
||||
NSView *view = [[NSOpenGLContext currentContext] view];
|
||||
NSRect backingBounds = [view convertRectToBacking: [view bounds]];
|
||||
int clientWidth = (int)backingBounds.size.width;
|
||||
return clientWidth > 0 ? clientWidth : Width;
|
||||
}
|
||||
|
||||
int SDLGLFB::GetClientHeight()
|
||||
{
|
||||
return static_cast<int>(rbOpts.height + 2.0f * rbOpts.shiftY);
|
||||
NSView *view = [[NSOpenGLContext currentContext] view];
|
||||
NSRect backingBounds = [view convertRectToBacking: [view bounds]];
|
||||
int clientHeight = (int)backingBounds.size.height;
|
||||
return clientHeight > 0 ? clientHeight : Height;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -65,8 +65,6 @@ public:
|
|||
int GetClientWidth();
|
||||
int GetClientHeight();
|
||||
|
||||
int GetTrueHeight() { return GetHeight(); }
|
||||
|
||||
protected:
|
||||
int m_lock;
|
||||
bool m_isUpdatePending;
|
||||
|
|
|
@ -61,9 +61,6 @@ public:
|
|||
int GetClientWidth();
|
||||
int GetClientHeight();
|
||||
|
||||
//[C]
|
||||
int GetTrueHeight() { return GetHeight();}
|
||||
|
||||
protected:
|
||||
bool CanUpdate();
|
||||
void SetGammaTable(WORD *tbl);
|
||||
|
|
|
@ -4,9 +4,11 @@ out vec4 FragColor;
|
|||
|
||||
uniform sampler2D SceneTexture;
|
||||
uniform float ExposureAdjustment;
|
||||
uniform vec2 Scale;
|
||||
uniform vec2 Offset;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 color = texture(SceneTexture, TexCoord);
|
||||
vec4 color = texture(SceneTexture, Offset + TexCoord * Scale);
|
||||
FragColor = max(vec4(color.rgb * ExposureAdjustment - 1, 1), vec4(0));
|
||||
}
|
||||
|
|
|
@ -3,14 +3,14 @@ in vec2 TexCoord;
|
|||
out vec4 FragColor;
|
||||
|
||||
uniform sampler2D InputTexture;
|
||||
uniform float Gamma;
|
||||
uniform float InvGamma;
|
||||
uniform float Contrast;
|
||||
uniform float Brightness;
|
||||
|
||||
vec4 ApplyGamma(vec4 c)
|
||||
{
|
||||
vec3 val = c.rgb * Contrast - (Contrast - 1.0) * 0.5;
|
||||
val = pow(val, vec3(1.0 / Gamma));
|
||||
vec3 val = max(c.rgb * Contrast - (Contrast - 1.0) * 0.5, vec3(0.0));
|
||||
val = pow(val, vec3(InvGamma));
|
||||
val += Brightness * 0.5;
|
||||
return vec4(val, c.a);
|
||||
}
|
||||
|
|
|
@ -7,12 +7,14 @@ uniform float ExposureAdjustment;
|
|||
|
||||
vec3 Linear(vec3 c)
|
||||
{
|
||||
//c = max(c, vec3(0.0));
|
||||
//return pow(c, 2.2);
|
||||
return c * c; // cheaper, but assuming gamma of 2.0 instead of 2.2
|
||||
}
|
||||
|
||||
vec3 sRGB(vec3 c)
|
||||
{
|
||||
c = max(c, vec3(0.0));
|
||||
//return pow(c, vec3(1.0 / 2.2));
|
||||
return sqrt(c); // cheaper, but assuming gamma of 2.0 instead of 2.2
|
||||
}
|
||||
|
@ -56,8 +58,7 @@ vec3 Uncharted2Tonemap(vec3 x)
|
|||
vec3 Tonemap(vec3 color)
|
||||
{
|
||||
float W = 11.2;
|
||||
float ExposureBias = 2.0;
|
||||
vec3 curr = Uncharted2Tonemap(ExposureBias * color);
|
||||
vec3 curr = Uncharted2Tonemap(color);
|
||||
vec3 whiteScale = vec3(1) / Uncharted2Tonemap(vec3(W));
|
||||
return sRGB(curr * whiteScale);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue