146 changes: 113 additions & 33 deletions src/gl/scene/gl_scene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
#include "gl/system/gl_cvars.h"
#include "gl/renderer/gl_lightdata.h"
#include "gl/renderer/gl_renderstate.h"
#include "gl/renderer/gl_renderbuffers.h"
#include "gl/data/gl_data.h"
#include "gl/data/gl_vertexbuffer.h"
#include "gl/dynlights/gl_dynlight.h"
Expand All @@ -71,6 +72,7 @@
#include "gl/scene/gl_drawinfo.h"
#include "gl/scene/gl_portal.h"
#include "gl/shaders/gl_shader.h"
#include "gl/shaders/gl_presentshader.h"
#include "gl/stereo3d/gl_stereo3d.h"
#include "gl/stereo3d/scoped_view_shifter.h"
#include "gl/textures/gl_translate.h"
Expand All @@ -91,9 +93,10 @@ CVAR(Float, gl_mask_threshold, 0.5f,CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
CVAR(Float, gl_mask_sprite_threshold, 0.5f,CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
CVAR(Bool, gl_sort_textures, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)

EXTERN_CVAR (Int, screenblocks)
EXTERN_CVAR (Bool, cl_capfps)
EXTERN_CVAR (Bool, r_deathcamera)
EXTERN_CVAR(Float, vid_brightness)
EXTERN_CVAR(Float, vid_contrast)


extern int viewpitch;
Expand Down Expand Up @@ -155,10 +158,12 @@ void FGLRenderer::SetViewArea()
//
//-----------------------------------------------------------------------------

void FGLRenderer::ResetViewport()
void FGLRenderer::Reset3DViewport()
{
int trueheight = static_cast<OpenGLFrameBuffer*>(screen)->GetTrueHeight(); // ugh...
glViewport(0, (trueheight-screen->GetHeight())/2, screen->GetWidth(), screen->GetHeight());
if (FGLRenderBuffers::IsSupported())
glViewport(0, 0, mOutputViewport.width, mOutputViewport.height);
else
glViewport(mOutputViewport.left, mOutputViewport.top, mOutputViewport.width, mOutputViewport.height);
}

//-----------------------------------------------------------------------------
Expand All @@ -167,38 +172,22 @@ void FGLRenderer::ResetViewport()
//
//-----------------------------------------------------------------------------

void FGLRenderer::SetViewport(GL_IRECT *bounds)
void FGLRenderer::Set3DViewport()
{
if (!bounds)
const auto &bounds = mOutputViewportLB;
if (FGLRenderBuffers::IsSupported())
{
int height, width;

// Special handling so the view with a visible status bar displays properly

if (screenblocks >= 10)
{
height = SCREENHEIGHT;
width = SCREENWIDTH;
}
else
{
height = (screenblocks*SCREENHEIGHT/10) & ~7;
width = (screenblocks*SCREENWIDTH/10);
}

int trueheight = static_cast<OpenGLFrameBuffer*>(screen)->GetTrueHeight(); // ugh...
int bars = (trueheight-screen->GetHeight())/2;

int vw = viewwidth;
int vh = viewheight;
glViewport(viewwindowx, trueheight-bars-(height+viewwindowy-((height-vh)/2)), vw, height);
glScissor(viewwindowx, trueheight-bars-(vh+viewwindowy), vw, vh);
mBuffers->Setup(mOutputViewport.width, mOutputViewport.height);
mBuffers->BindSceneFB();
glViewport(0, 0, bounds.width, bounds.height);
glScissor(0, 0, bounds.width, bounds.height);
}
else
{
glViewport(bounds->left, bounds->top, bounds->width, bounds->height);
glScissor(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);
}

glEnable(GL_SCISSOR_TEST);

#ifdef _DEBUG
Expand All @@ -215,6 +204,97 @@ void FGLRenderer::SetViewport(GL_IRECT *bounds)
glStencilOp(GL_KEEP,GL_KEEP,GL_REPLACE);
}

//-----------------------------------------------------------------------------
//
// Run post processing steps and copy to frame buffer
//
//-----------------------------------------------------------------------------

void FGLRenderer::Flush()
{
if (FGLRenderBuffers::IsSupported())
{
glDisable(GL_MULTISAMPLE);
glDisable(GL_DEPTH_TEST);
glDisable(GL_STENCIL_TEST);

mBuffers->BindOutputFB();

// Calculate letterbox
int clientWidth = framebuffer->GetClientWidth();
int clientHeight = framebuffer->GetClientHeight();
float scaleX = clientWidth / (float)mOutputViewport.width;
float scaleY = clientHeight / (float)mOutputViewport.height;
float scale = MIN(scaleX, scaleY);
int width = (int)round(mOutputViewport.width * scale);
int height = (int)round(mOutputViewport.height * scale);
int x = (clientWidth - width) / 2;
int y = (clientHeight - height) / 2;

// 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:
glViewport(x, y, width, height);

GLboolean blendEnabled;
GLint currentProgram;
glGetBooleanv(GL_BLEND, &blendEnabled);
glGetIntegerv(GL_CURRENT_PROGRAM, &currentProgram);
glDisable(GL_BLEND);

mPresentShader->Bind();
mPresentShader->InputTexture.Set(0);
if (framebuffer->IsHWGammaActive())
{
mPresentShader->Gamma.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->Contrast.Set(clamp<float>(vid_contrast, 0.1f, 3.f));
mPresentShader->Brightness.Set(clamp<float>(vid_brightness, -0.8f, 0.8f));
}
mBuffers->BindSceneTexture(0);

FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
ptr->Set(-1.0f, -1.0f, 0, 0.0f, 0.0f); ptr++;
ptr->Set(-1.0f, 1.0f, 0, 0.0f, 1.0f); ptr++;
ptr->Set(1.0f, -1.0f, 0, 1.0f, 0.0f); ptr++;
ptr->Set(1.0f, 1.0f, 0, 1.0f, 1.0f); ptr++;
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP);

if (blendEnabled)
glEnable(GL_BLEND);
glUseProgram(currentProgram);
}
}

//-----------------------------------------------------------------------------
//
// Setup the camera position
Expand Down Expand Up @@ -707,7 +787,7 @@ void FGLRenderer::EndDrawScene(sector_t * viewsector)

framebuffer->Begin2D(false);

ResetViewport();
Reset3DViewport();
// [BB] Only draw the sprites if we didn't render a HUD model before.
if ( renderHUDModel == false )
{
Expand Down Expand Up @@ -846,7 +926,8 @@ sector_t * FGLRenderer::RenderViewpoint (AActor * camera, GL_IRECT * bounds, flo
const s3d::EyePose * eye = stereo3dMode.getEyePose(eye_ix);
eye->SetUp();
// TODO: stereo specific viewport - needed when implementing side-by-side modes etc.
SetViewport(bounds);
SetOutputViewport(bounds);
Set3DViewport();
mCurrentFoV = fov;
// Stereo mode specific perspective projection
SetProjection( eye->GetProjection(fov, ratio, fovratio) );
Expand All @@ -873,7 +954,6 @@ sector_t * FGLRenderer::RenderViewpoint (AActor * camera, GL_IRECT * bounds, flo
return retval;
}


//-----------------------------------------------------------------------------
//
// renders the view
Expand Down
67 changes: 67 additions & 0 deletions src/gl/shaders/gl_presentshader.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
** gl_presentshader.cpp
** Copy rendered texture to back buffer, possibly with gamma correction
**
**---------------------------------------------------------------------------
** Copyright 2008 Christoph Oelckers
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions
** are met:
**
** 1. Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** 2. Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in the
** documentation and/or other materials provided with the distribution.
** 3. The name of the author may not be used to endorse or promote products
** derived from this software without specific prior written permission.
** 4. When not used as part of GZDoom or a GZDoom derivative, this code will be
** covered by the terms of the GNU Lesser General Public License as published
** by the Free Software Foundation; either version 2.1 of the License, or (at
** your option) any later version.
** 5. Full disclosure of the entire project's source code, except for third
** party libraries is mandatory. (NOTE: This clause is non-negotiable!)
**
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**---------------------------------------------------------------------------
**
*/

#include "gl/system/gl_system.h"
#include "files.h"
#include "m_swap.h"
#include "v_video.h"
#include "gl/gl_functions.h"
#include "vectors.h"
#include "gl/system/gl_interface.h"
#include "gl/system/gl_framebuffer.h"
#include "gl/system/gl_cvars.h"
#include "gl/shaders/gl_presentshader.h"

void FPresentShader::Bind()
{
if (!mShader)
{
mShader.Compile(FShaderProgram::Vertex, "shaders/glsl/present.vp");
mShader.Compile(FShaderProgram::Fragment, "shaders/glsl/present.fp");
mShader.SetFragDataLocation(0, "FragColor");
mShader.Link("shaders/glsl/present");
mShader.SetAttribLocation(0, "PositionInProjection");
InputTexture.Init(mShader, "InputTexture");
Gamma.Init(mShader, "Gamma");
Contrast.Init(mShader, "Contrast");
Brightness.Init(mShader, "Brightness");
}
mShader.Bind();
}
20 changes: 20 additions & 0 deletions src/gl/shaders/gl_presentshader.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#ifndef __GL_PRESENTSHADER_H
#define __GL_PRESENTSHADER_H

#include "gl_shaderprogram.h"

class FPresentShader
{
public:
void Bind();

FBufferedUniform1i InputTexture;
FBufferedUniform1f Gamma;
FBufferedUniform1f Contrast;
FBufferedUniform1f Brightness;

private:
FShaderProgram mShader;
};

#endif
205 changes: 205 additions & 0 deletions src/gl/shaders/gl_shaderprogram.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
/*
** gl_shaderprogram.cpp
** GLSL shader program compile and link
**
**---------------------------------------------------------------------------
** Copyright 2008 Christoph Oelckers
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions
** are met:
**
** 1. Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** 2. Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in the
** documentation and/or other materials provided with the distribution.
** 3. The name of the author may not be used to endorse or promote products
** derived from this software without specific prior written permission.
** 4. When not used as part of GZDoom or a GZDoom derivative, this code will be
** covered by the terms of the GNU Lesser General Public License as published
** by the Free Software Foundation; either version 2.1 of the License, or (at
** your option) any later version.
** 5. Full disclosure of the entire project's source code, except for third
** party libraries is mandatory. (NOTE: This clause is non-negotiable!)
**
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**---------------------------------------------------------------------------
**
*/

#include "gl/system/gl_system.h"
#include "files.h"
#include "m_swap.h"
#include "v_video.h"
#include "gl/gl_functions.h"
#include "vectors.h"
#include "gl/system/gl_interface.h"
#include "gl/system/gl_cvars.h"
#include "gl/shaders/gl_shaderprogram.h"
#include "w_wad.h"
#include "i_system.h"
#include "doomerrors.h"

//==========================================================================
//
// Free shader program resources
//
//==========================================================================

FShaderProgram::~FShaderProgram()
{
if (mProgram != 0)
glDeleteProgram(mProgram);

for (int i = 0; i < NumShaderTypes; i++)
{
if (mShaders[i] != 0)
glDeleteShader(mShaders[i]);
}
}

//==========================================================================
//
// Creates an OpenGL shader object for the specified type of shader
//
//==========================================================================

void FShaderProgram::CreateShader(ShaderType type)
{
GLenum gltype = 0;
switch (type)
{
default:
case Vertex: gltype = GL_VERTEX_SHADER; break;
case Fragment: gltype = GL_FRAGMENT_SHADER; break;
}
mShaders[type] = glCreateShader(gltype);
}

//==========================================================================
//
// Compiles a shader and attaches it the program object
//
//==========================================================================

void FShaderProgram::Compile(ShaderType type, const char *lumpName)
{
CreateShader(type);

const auto &handle = mShaders[type];

int lump = Wads.CheckNumForFullName(lumpName);
if (lump == -1) I_Error("Unable to load '%s'", lumpName);
FString code = Wads.ReadLump(lump).GetString().GetChars();

int lengths[1] = { (int)code.Len() };
const char *sources[1] = { code.GetChars() };
glShaderSource(handle, 1, sources, lengths);

glCompileShader(handle);

GLint status = 0;
glGetShaderiv(handle, GL_COMPILE_STATUS, &status);
if (status == GL_FALSE)
{
I_Error("Compile Shader '%s':\n%s\n", lumpName, GetShaderInfoLog(handle).GetChars());
}
else
{
if (mProgram == 0)
mProgram = glCreateProgram();
glAttachShader(mProgram, handle);
}
}

//==========================================================================
//
// Binds a fragment output variable to a frame buffer render target
//
//==========================================================================

void FShaderProgram::SetFragDataLocation(int index, const char *name)
{
glBindFragDataLocation(mProgram, index, name);
}

//==========================================================================
//
// Links a program with the compiled shaders
//
//==========================================================================

void FShaderProgram::Link(const char *name)
{
glLinkProgram(mProgram);

GLint status = 0;
glGetProgramiv(mProgram, GL_LINK_STATUS, &status);
if (status == GL_FALSE)
{
I_Error("Link Shader '%s':\n%s\n", name, GetProgramInfoLog(mProgram).GetChars());
}
}

//==========================================================================
//
// Set vertex attribute location
//
//==========================================================================

void FShaderProgram::SetAttribLocation(int index, const char *name)
{
glBindAttribLocation(mProgram, index, name);
}

//==========================================================================
//
// Makes the shader the active program
//
//==========================================================================

void FShaderProgram::Bind()
{
glUseProgram(mProgram);
}

//==========================================================================
//
// Returns the shader info log (warnings and compile errors)
//
//==========================================================================

FString FShaderProgram::GetShaderInfoLog(GLuint handle)
{
static char buffer[10000];
GLsizei length = 0;
buffer[0] = 0;
glGetShaderInfoLog(handle, 10000, &length, buffer);
return FString(buffer);
}

//==========================================================================
//
// Returns the program info log (warnings and compile errors)
//
//==========================================================================

FString FShaderProgram::GetProgramInfoLog(GLuint handle)
{
static char buffer[10000];
GLsizei length = 0;
buffer[0] = 0;
glGetProgramInfoLog(handle, 10000, &length, buffer);
return FString(buffer);
}
36 changes: 36 additions & 0 deletions src/gl/shaders/gl_shaderprogram.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#ifndef __GL_SHADERPROGRAM_H
#define __GL_SHADERPROGRAM_H

#include "gl_shader.h"

class FShaderProgram
{
public:
~FShaderProgram();

enum ShaderType
{
Vertex,
Fragment,
NumShaderTypes
};

void Compile(ShaderType type, const char *lumpName);
void SetFragDataLocation(int index, const char *name);
void Link(const char *name);
void SetAttribLocation(int index, const char *name);
void Bind();

operator GLuint() const { return mProgram; }
explicit operator bool() const { return mProgram != 0; }

private:
void CreateShader(ShaderType type);
FString GetShaderInfoLog(GLuint handle);
FString GetProgramInfoLog(GLuint handle);

GLuint mProgram = 0;
GLuint mShaders[NumShaderTypes];
};

#endif
29 changes: 22 additions & 7 deletions src/gl/system/gl_framebuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,12 @@ void gl_LoadExtensions();
void gl_PrintStartupLog();
void gl_SetupMenu();

CUSTOM_CVAR(Int, vid_hwgamma, 2, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL)
{
if (self < 0 || self > 2) self = 2;
if (GLRenderer != NULL && GLRenderer->framebuffer != NULL) GLRenderer->framebuffer->DoSetGamma();
}

//==========================================================================
//
//
Expand Down Expand Up @@ -150,12 +156,13 @@ 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());
//int trueH = GetTrueHeight();
//int h = GetHeight();
//glViewport(0, (trueH - h)/2, GetWidth(), GetHeight());

Begin2D(false);
GLRenderer->Initialize();
GLRenderer->SetOutputViewport(nullptr);
Begin2D(false);
}

//==========================================================================
Expand Down Expand Up @@ -230,10 +237,11 @@ void OpenGLFrameBuffer::Swap()

void OpenGLFrameBuffer::DoSetGamma()
{
WORD gammaTable[768];

if (m_supportsGamma)
bool useHWGamma = m_supportsGamma && ((vid_hwgamma == 0) || (vid_hwgamma == 2 && IsFullscreen()));
if (useHWGamma)
{
WORD gammaTable[768];

// This formula is taken from Doomsday
float gamma = clamp<float>(Gamma, 0.1f, 4.f);
float contrast = clamp<float>(vid_contrast, 0.1f, 3.f);
Expand All @@ -251,6 +259,13 @@ void OpenGLFrameBuffer::DoSetGamma()
gammaTable[i] = gammaTable[i + 256] = gammaTable[i + 512] = (WORD)clamp<double>(val*256, 0, 0xffff);
}
SetGammaTable(gammaTable);

HWGammaActive = true;
}
else if (HWGammaActive)
{
ResetGammaTable();
HWGammaActive = false;
}
}

Expand Down
4 changes: 3 additions & 1 deletion src/gl/system/gl_framebuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ class OpenGLFrameBuffer : public SDLGLFB
void WipeCleanup();
void Swap();
bool Is8BitMode() { return false; }

bool IsHWGammaActive() const { return HWGammaActive; }

private:
PalEntry Flash;
Expand Down Expand Up @@ -107,6 +107,8 @@ class OpenGLFrameBuffer : public SDLGLFB
FHardwareTexture *wipestartscreen;
FHardwareTexture *wipeendscreen;

bool HWGammaActive = false;

public:
AActor * LastCamera;
int palette_brightness;
Expand Down
32 changes: 27 additions & 5 deletions src/gl/system/gl_wipe.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,9 @@
#include "gl/system/gl_interface.h"
#include "gl/renderer/gl_renderer.h"
#include "gl/renderer/gl_renderstate.h"
#include "gl/renderer/gl_renderbuffers.h"
#include "gl/system/gl_framebuffer.h"
#include "gl/system/gl_cvars.h"
#include "gl/shaders/gl_shader.h"
#include "gl/textures/gl_translate.h"
#include "gl/textures/gl_material.h"
Expand Down Expand Up @@ -153,11 +155,21 @@ bool OpenGLFrameBuffer::WipeStartScreen(int type)
GLRenderer->mSamplerManager->Bind(1, CLAMP_NONE, -1);
glFinish();
wipestartscreen->Bind(0, false, false);
GLint readbuffer = 0;
glGetIntegerv(GL_READ_BUFFER, &readbuffer);
glReadBuffer(GL_FRONT);
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, Width, Height);
glReadBuffer(readbuffer);

if (FGLRenderBuffers::IsSupported())
{
GLRenderer->mBuffers->BindSceneFB();
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, Width, Height);
}
else
{
GLint readbuffer = 0;
glGetIntegerv(GL_READ_BUFFER, &readbuffer);
glReadBuffer(GL_FRONT);
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, Width, Height);
glReadBuffer(readbuffer);
}

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

Expand All @@ -179,6 +191,10 @@ void OpenGLFrameBuffer::WipeEndScreen()
GLRenderer->mSamplerManager->Bind(0, CLAMP_NOFILTER, -1);
glFinish();
wipeendscreen->Bind(0, false, false);

if (FGLRenderBuffers::IsSupported())
GLRenderer->mBuffers->BindSceneFB();

glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, Width, Height);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
Expand Down Expand Up @@ -214,6 +230,12 @@ bool OpenGLFrameBuffer::WipeDo(int ticks)
glDisable(GL_DEPTH_TEST);
glDepthMask(false);

if (FGLRenderBuffers::IsSupported())
{
GLRenderer->mBuffers->BindSceneFB();
glViewport(0, 0, GLRenderer->mOutputViewport.width, GLRenderer->mOutputViewport.height);
}

bool done = ScreenWipe->Run(ticks, this);
glDepthMask(true);
//DrawLetterbox();
Expand Down
14 changes: 14 additions & 0 deletions src/posix/cocoa/i_video.mm
Original file line number Diff line number Diff line change
Expand Up @@ -1239,6 +1239,20 @@ static bool HasModernFullscreenAPI()
{
}

void SDLGLFB::ResetGammaTable()
{
}

int SDLGLFB::GetClientWidth()
{
return GetWidth();
}

int SDLGLFB::GetClientHeight()
{
return GetHeight();
}


// ---------------------------------------------------------------------------

Expand Down
6 changes: 5 additions & 1 deletion src/posix/cocoa/sdlglvideo.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,16 @@ class SDLGLFB : public DFrameBuffer
virtual bool IsFullscreen();
virtual void SetVSync(bool vsync);

int GetClientWidth();
int GetClientHeight();

int GetTrueHeight() { return GetHeight(); }

protected:
int m_lock;
bool m_isUpdatePending;

static const bool m_supportsGamma = true;
static const bool m_supportsGamma = false;

SDLGLFB();

Expand All @@ -78,6 +81,7 @@ class SDLGLFB : public DFrameBuffer
void SwapBuffers();

void SetGammaTable(WORD* table);
void ResetGammaTable();
};

#endif // COCOA_SDLGLVIDEO_H_INCLUDED
31 changes: 26 additions & 5 deletions src/posix/sdl/sdlglvideo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -350,10 +350,7 @@ SDLGLFB::~SDLGLFB ()
{
if (Screen)
{
if (m_supportsGamma)
{
SDL_SetWindowGammaRamp(Screen, m_origGamma[0], m_origGamma[1], m_origGamma[2]);
}
ResetGammaTable();

if (GLContext)
{
Expand Down Expand Up @@ -387,7 +384,18 @@ bool SDLGLFB::CanUpdate ()

void SDLGLFB::SetGammaTable(WORD *tbl)
{
SDL_SetWindowGammaRamp(Screen, &tbl[0], &tbl[256], &tbl[512]);
if (m_supportsGamma)
{
SDL_SetWindowGammaRamp(Screen, &tbl[0], &tbl[256], &tbl[512]);
}
}

void SDLGLFB::ResetGammaTable()
{
if (m_supportsGamma)
{
SDL_SetWindowGammaRamp(Screen, m_origGamma[0], m_origGamma[1], m_origGamma[2]);
}
}

bool SDLGLFB::Lock(bool buffered)
Expand Down Expand Up @@ -447,3 +455,16 @@ void SDLGLFB::SwapBuffers()
SDL_GL_SwapWindow (Screen);
}

int SDLGLFB::GetClientWidth()
{
int width = 0;
SDL_GL_GetDrawableSize(Screen, &width, nullptr);
return width;
}

int SDLGLFB::GetClientHeight()
{
int height = 0;
SDL_GL_GetDrawableSize(Screen, nullptr, &height);
return width;
}
4 changes: 4 additions & 0 deletions src/posix/sdl/sdlglvideo.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,16 @@ class SDLGLFB : public DFrameBuffer

friend class SDLGLVideo;

int GetClientWidth();
int GetClientHeight();

//[C]
int GetTrueHeight() { return GetHeight();}

protected:
bool CanUpdate();
void SetGammaTable(WORD *tbl);
void ResetGammaTable();
void InitializeState();

SDLGLFB () {}
Expand Down
2 changes: 1 addition & 1 deletion src/win32/hardware.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,7 @@ void I_RestoreWindowedPos ()

extern int NewWidth, NewHeight, NewBits, DisplayBits;

CUSTOM_CVAR (Bool, fullscreen, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG|CVAR_NOINITCALL)
CUSTOM_CVAR (Bool, fullscreen, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG|CVAR_NOINITCALL)
{
NewWidth = screen->GetWidth();
NewHeight = screen->GetHeight();
Expand Down
49 changes: 38 additions & 11 deletions src/win32/win32gliface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -951,7 +951,7 @@ Win32GLFrameBuffer::Win32GLFrameBuffer(void *hMonitor, int width, int height, in
style |= WS_POPUP;
else
{
style |= WS_OVERLAPPEDWINDOW & ~WS_MAXIMIZEBOX;
style |= WS_OVERLAPPEDWINDOW;
exStyle |= WS_EX_WINDOWEDGE;
}

Expand All @@ -967,7 +967,13 @@ Win32GLFrameBuffer::Win32GLFrameBuffer(void *hMonitor, int width, int height, in
}
else
{
MoveWindow(Window, r.left, r.top, width + (GetSystemMetrics(SM_CXSIZEFRAME) * 2), height + (GetSystemMetrics(SM_CYSIZEFRAME) * 2) + GetSystemMetrics(SM_CYCAPTION), FALSE);
RECT windowRect;
windowRect.left = r.left;
windowRect.top = r.top;
windowRect.right = windowRect.left + width;
windowRect.bottom = windowRect.top + height;
AdjustWindowRectEx(&windowRect, style, FALSE, exStyle);
MoveWindow(Window, windowRect.left, windowRect.top, windowRect.right - windowRect.left, windowRect.bottom - windowRect.top, FALSE);

I_RestoreWindowedPos();
}
Expand All @@ -993,12 +999,7 @@ Win32GLFrameBuffer::Win32GLFrameBuffer(void *hMonitor, int width, int height, in

Win32GLFrameBuffer::~Win32GLFrameBuffer()
{
if (m_supportsGamma)
{
HDC hDC = GetDC(Window);
SetDeviceGammaRamp(hDC, (void *)m_origGamma);
ReleaseDC(Window, hDC);
}
ResetGammaTable();
I_SaveWindowedPos();

static_cast<Win32GLVideo *>(Video)->SetFullscreen(m_displayDeviceName, 0,0,0,0);
Expand Down Expand Up @@ -1041,11 +1042,24 @@ bool Win32GLFrameBuffer::CanUpdate()
//
//==========================================================================

void Win32GLFrameBuffer::ResetGammaTable()
{
if (m_supportsGamma)
{
HDC hDC = GetDC(Window);
SetDeviceGammaRamp(hDC, (void *)m_origGamma);
ReleaseDC(Window, hDC);
}
}

void Win32GLFrameBuffer::SetGammaTable(WORD *tbl)
{
HDC hDC = GetDC(Window);
SetDeviceGammaRamp(hDC, (void *)tbl);
ReleaseDC(Window, hDC);
if (m_supportsGamma)
{
HDC hDC = GetDC(Window);
SetDeviceGammaRamp(hDC, (void *)tbl);
ReleaseDC(Window, hDC);
}
}

//==========================================================================
Expand Down Expand Up @@ -1152,6 +1166,19 @@ void Win32GLFrameBuffer::NewRefreshRate ()
}
}

int Win32GLFrameBuffer::GetClientWidth()
{
RECT rect = { 0 };
GetClientRect(Window, &rect);
return rect.right - rect.left;
}

int Win32GLFrameBuffer::GetClientHeight()
{
RECT rect = { 0 };
GetClientRect(Window, &rect);
return rect.bottom - rect.top;
}

IVideo *gl_CreateVideo()
{
Expand Down
3 changes: 3 additions & 0 deletions src/win32/win32gliface.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,8 @@ class Win32GLFrameBuffer : public BaseWinFB
void SwapBuffers();
void NewRefreshRate ();

int GetClientWidth();
int GetClientHeight();

int GetTrueHeight() { return static_cast<Win32GLVideo *>(Video)->GetTrueHeight(); }

Expand All @@ -136,6 +138,7 @@ class Win32GLFrameBuffer : public BaseWinFB
protected:

bool CanUpdate();
void ResetGammaTable();
void SetGammaTable(WORD * tbl);

float m_Gamma, m_Brightness, m_Contrast;
Expand Down
2 changes: 2 additions & 0 deletions wadsrc/static/language.enu
Original file line number Diff line number Diff line change
Expand Up @@ -2281,6 +2281,7 @@ OPTVAL_SINC = "Sinc";
OPTVAL_NOTEONOFFONLY = "Note on/off only";
OPTVAL_FULLRAMPING = "Full ramping";
OPTVAL_ALLUNACKNOWLEDGED = "All unacknowledged";
OPTVAL_FULLSCREENONLY = "Fullscreen only";
// Colors
C_BRICK = "\cabrick";
C_TAN = "\cbtan";
Expand Down Expand Up @@ -2562,6 +2563,7 @@ MUSIC_DM2INT = "dm2int";
DSPLYMNU_GLOPT = "OpenGL Options";
DSPLYMNU_GAMMA = "Gamma correction";
DSPLYMNU_CONTRAST ="Contrast";
DSPLYMNU_HWGAMMA = "Hardware Gamma";

// OpenGL Options
GLMNU_TITLE = "OPENGL OPTIONS";
Expand Down
1 change: 1 addition & 0 deletions wadsrc/static/menudef.txt
Original file line number Diff line number Diff line change
Expand Up @@ -670,6 +670,7 @@ OptionMenu "VideoOptions"
Slider "$DSPLYMNU_GAMMA", "Gamma", 0.75, 3.0, 0.05, 2
Slider "$DSPLYMNU_BRIGHTNESS", "vid_brightness", -0.8,0.8, 0.05
Slider "$DSPLYMNU_CONTRAST", "vid_contrast", 0.1, 3.0, 0.1
Option "$DSPLYMNU_HWGAMMA", "vid_hwgamma", "HWGammaModes"

Option "$DSPLYMNU_VSYNC", "vid_vsync", "OnOff"
Option "$DSPLYMNU_CAPFPS", "cl_capfps", "OffOn"
Expand Down
7 changes: 7 additions & 0 deletions wadsrc/static/menudef.z
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,13 @@ OptionValue "FilterModes"
4, "$OPTVAL_TRILINEAR"
}

OptionValue "HWGammaModes"
{
0, "$OPTVAL_ON"
1, "$OPTVAL_OFF"
2, "$OPTVAL_FULLSCREENONLY"
}

OptionValue "TextureFormats"
{
0, "$OPTVAL_RGBA8"
Expand Down
23 changes: 23 additions & 0 deletions wadsrc/static/shaders/glsl/present.fp
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@

#version 330

in vec2 TexCoord;
out vec4 FragColor;

uniform sampler2D InputTexture;
uniform float Gamma;
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));
val += Brightness * 0.5;
return vec4(val, c.a);
}

void main()
{
FragColor = ApplyGamma(texture(InputTexture, TexCoord));
}
11 changes: 11 additions & 0 deletions wadsrc/static/shaders/glsl/present.vp
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@

#version 330

in vec4 PositionInProjection;
out vec2 TexCoord;

void main()
{
gl_Position = PositionInProjection;
TexCoord = PositionInProjection.xy * 0.5 + 0.5;
}