This commit is contained in:
nashmuhandes 2016-08-18 03:40:30 +08:00
commit cf34e6f3e1
27 changed files with 312 additions and 225 deletions

View file

@ -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);

View file

@ -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);
}

View file

@ -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

View file

@ -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;

View file

@ -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);
}

View file

@ -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);

View file

@ -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;

View file

@ -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;

View file

@ -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);
}

View file

@ -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);
}
//-----------------------------------------------------------------------------

View file

@ -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);
}

View file

@ -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();
}

View file

@ -10,6 +10,8 @@ public:
FBufferedUniform1i SceneTexture;
FBufferedUniform1f Exposure;
FBufferedUniform2f Scale;
FBufferedUniform2f Offset;
private:
FShaderProgram mShader;

View file

@ -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();
}
//==========================================================================

View file

@ -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
{

View file

@ -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");

View file

@ -9,7 +9,7 @@ public:
void Bind();
FBufferedUniform1i InputTexture;
FBufferedUniform1f Gamma;
FBufferedUniform1f InvGamma;
FBufferedUniform1f Contrast;
FBufferedUniform1f Brightness;
FBufferedUniform2f Scale;

View file

@ -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);

View file

@ -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);

View file

@ -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;

View file

@ -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;
}
}
}
}

View file

@ -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;
}

View file

@ -65,8 +65,6 @@ public:
int GetClientWidth();
int GetClientHeight();
int GetTrueHeight() { return GetHeight(); }
protected:
int m_lock;
bool m_isUpdatePending;

View file

@ -61,9 +61,6 @@ public:
int GetClientWidth();
int GetClientHeight();
//[C]
int GetTrueHeight() { return GetHeight();}
protected:
bool CanUpdate();
void SetGammaTable(WORD *tbl);

View file

@ -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));
}

View file

@ -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);
}

View file

@ -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);
}