diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 13ef11ec3..d78903973 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1115,6 +1115,7 @@ set( FASTMATH_SOURCES gl/shaders/gl_bloomshader.cpp gl/shaders/gl_ambientshader.cpp gl/shaders/gl_blurshader.cpp + gl/shaders/gl_colormapshader.cpp gl/shaders/gl_tonemapshader.cpp gl/shaders/gl_lensshader.cpp gl/system/gl_interface.cpp diff --git a/src/gl/compatibility/gl_20.cpp b/src/gl/compatibility/gl_20.cpp index 8e6682f17..fdda99130 100644 --- a/src/gl/compatibility/gl_20.cpp +++ b/src/gl/compatibility/gl_20.cpp @@ -66,40 +66,39 @@ void gl_PatchMenu() { - if (gl.glslversion == 0) + // Radial fog and Doom lighting are not available without full shader support. + + FOptionValues **opt = OptionValues.CheckKey("LightingModes"); + if (opt != NULL) { - // Radial fog and Doom lighting are not available without full shader support. - - FOptionValues **opt = OptionValues.CheckKey("LightingModes"); - if (opt != NULL) + for(int i = (*opt)->mValues.Size()-1; i>=0; i--) { - for(int i = (*opt)->mValues.Size()-1; i>=0; i--) + // Delete 'Doom' lighting mode + if ((*opt)->mValues[i].Value == 2.0 || (*opt)->mValues[i].Value == 8.0) { - // Delete 'Doom' lighting mode - if ((*opt)->mValues[i].Value == 2.0 || (*opt)->mValues[i].Value == 8.0) - { - (*opt)->mValues.Delete(i); - } + (*opt)->mValues.Delete(i); } } - - opt = OptionValues.CheckKey("FogMode"); - if (opt != NULL) - { - for(int i = (*opt)->mValues.Size()-1; i>=0; i--) - { - // Delete 'Radial' fog mode - if ((*opt)->mValues[i].Value == 2.0) - { - (*opt)->mValues.Delete(i); - } - } - } - - // disable features that don't work without shaders. - if (gl_lightmode == 2 || gl_lightmode == 8) gl_lightmode = 3; - if (gl_fogmode == 2) gl_fogmode = 1; } + + opt = OptionValues.CheckKey("FogMode"); + if (opt != NULL) + { + for(int i = (*opt)->mValues.Size()-1; i>=0; i--) + { + // Delete 'Radial' fog mode + if ((*opt)->mValues[i].Value == 2.0) + { + (*opt)->mValues.Delete(i); + } + } + } + + // disable features that don't work without shaders. + if (gl_lightmode == 2 || gl_lightmode == 8) gl_lightmode = 3; + if (gl_fogmode == 2) gl_fogmode = 1; + + // todo: remove more unsupported stuff like postprocessing options. } @@ -378,7 +377,7 @@ void FRenderState::DrawColormapOverlay() //========================================================================== bool gl_SetupLight(int group, Plane & p, ADynamicLight * light, Vector & nearPt, Vector & up, Vector & right, - float & scale, int desaturation, bool checkside, bool additive) + float & scale, bool checkside, bool additive) { Vector fn, pos; @@ -434,14 +433,6 @@ bool gl_SetupLight(int group, Plane & p, ADynamicLight * light, Vector & nearPt, { gl_RenderState.BlendEquation(GL_FUNC_ADD); } - if (desaturation > 0 && gl.glslversion > 0) // no-shader excluded because no desaturated textures. - { - float gray = (r * 77 + g * 143 + b * 37) / 257; - - r = (r*(32 - desaturation) + gray*desaturation) / 32; - g = (g*(32 - desaturation) + gray*desaturation) / 32; - b = (b*(32 - desaturation) + gray*desaturation) / 32; - } gl_RenderState.SetColor(r, g, b); return true; } @@ -491,11 +482,6 @@ bool GLWall::PutWallCompat(int passflag) bool masked = passflag == 2 && gltexture->isMasked(); int list = list_indices[masked][foggy]; - if (list == GLLDL_WALLS_PLAIN) - { - if (gltexture->tex->gl_info.Brightmap && gl.glslversion >= 0.f) list = GLLDL_WALLS_BRIGHT; - //if (flags & GLWF_GLOW) list = GLLDL_WALLS_BRIGHT; - } gl_drawinfo->dldrawlists[list].AddWall(this); return true; @@ -520,10 +506,6 @@ bool GLFlat::PutFlatCompat(bool fog) int list = list_indices[masked][foggy]; - if (list == GLLDL_FLATS_PLAIN) - { - if (gltexture->tex->gl_info.Brightmap && gl.glslversion >= 0.f) list = GLLDL_FLATS_BRIGHT; - } gl_drawinfo->dldrawlists[list].AddFlat(this); return true; } @@ -612,7 +594,7 @@ void GLFlat::DrawSubsectorLights(subsector_t * sub, int pass) } p.Set(plane.plane); - if (!gl_SetupLight(sub->sector->PortalGroup, p, light, nearPt, up, right, scale, CM_DEFAULT, false, pass != GLPASS_LIGHTTEX)) + if (!gl_SetupLight(sub->sector->PortalGroup, p, light, nearPt, up, right, scale, false, pass != GLPASS_LIGHTTEX)) { node = node->nextLight; continue; @@ -692,7 +674,7 @@ bool GLWall::PrepareLight(ADynamicLight * light, int pass) return false; } - if (!gl_SetupLight(seg->frontsector->PortalGroup, p, light, nearPt, up, right, scale, CM_DEFAULT, true, pass != GLPASS_LIGHTTEX)) + if (!gl_SetupLight(seg->frontsector->PortalGroup, p, light, nearPt, up, right, scale, true, pass != GLPASS_LIGHTTEX)) { return false; } @@ -798,9 +780,7 @@ void FGLRenderer::RenderMultipassStuff() gl_RenderState.SetTextureMode(TM_MASK); gl_RenderState.EnableBrightmap(true); gl_RenderState.AlphaFunc(GL_GEQUAL, gl_mask_threshold); - gl_drawinfo->dldrawlists[GLLDL_WALLS_BRIGHT].DrawWalls(GLPASS_PLAIN); gl_drawinfo->dldrawlists[GLLDL_WALLS_MASKED].DrawWalls(GLPASS_PLAIN); - gl_drawinfo->dldrawlists[GLLDL_FLATS_BRIGHT].DrawFlats(GLPASS_PLAIN); gl_drawinfo->dldrawlists[GLLDL_FLATS_MASKED].DrawFlats(GLPASS_PLAIN); // Part 3: The base of fogged surfaces, including the texture @@ -823,10 +803,8 @@ void FGLRenderer::RenderMultipassStuff() glDepthFunc(GL_EQUAL); if (glset.lightmode == 8) gl_RenderState.SetSoftLightLevel(255); gl_drawinfo->dldrawlists[GLLDL_WALLS_PLAIN].DrawWalls(GLPASS_LIGHTTEX); - gl_drawinfo->dldrawlists[GLLDL_WALLS_BRIGHT].DrawWalls(GLPASS_LIGHTTEX); gl_drawinfo->dldrawlists[GLLDL_WALLS_MASKED].DrawWalls(GLPASS_LIGHTTEX); gl_drawinfo->dldrawlists[GLLDL_FLATS_PLAIN].DrawFlats(GLPASS_LIGHTTEX); - gl_drawinfo->dldrawlists[GLLDL_FLATS_BRIGHT].DrawFlats(GLPASS_LIGHTTEX); gl_drawinfo->dldrawlists[GLLDL_FLATS_MASKED].DrawFlats(GLPASS_LIGHTTEX); gl_RenderState.BlendEquation(GL_FUNC_ADD); } @@ -841,8 +819,6 @@ void FGLRenderer::RenderMultipassStuff() glDepthFunc(GL_LEQUAL); gl_drawinfo->dldrawlists[GLLDL_WALLS_PLAIN].DrawWalls(GLPASS_TEXONLY); gl_drawinfo->dldrawlists[GLLDL_FLATS_PLAIN].DrawFlats(GLPASS_TEXONLY); - gl_drawinfo->dldrawlists[GLLDL_WALLS_BRIGHT].DrawWalls(GLPASS_TEXONLY); - gl_drawinfo->dldrawlists[GLLDL_FLATS_BRIGHT].DrawFlats(GLPASS_TEXONLY); gl_RenderState.AlphaFunc(GL_GREATER, gl_mask_threshold); gl_drawinfo->dldrawlists[GLLDL_WALLS_MASKED].DrawWalls(GLPASS_TEXONLY); gl_drawinfo->dldrawlists[GLLDL_FLATS_MASKED].DrawFlats(GLPASS_TEXONLY); @@ -854,10 +830,8 @@ void FGLRenderer::RenderMultipassStuff() if (gl_SetupLightTexture()) { gl_drawinfo->dldrawlists[GLLDL_WALLS_PLAIN].DrawWalls(GLPASS_LIGHTTEX_ADDITIVE); - gl_drawinfo->dldrawlists[GLLDL_WALLS_BRIGHT].DrawWalls(GLPASS_LIGHTTEX_ADDITIVE); gl_drawinfo->dldrawlists[GLLDL_WALLS_MASKED].DrawWalls(GLPASS_LIGHTTEX_ADDITIVE); gl_drawinfo->dldrawlists[GLLDL_FLATS_PLAIN].DrawFlats(GLPASS_LIGHTTEX_ADDITIVE); - gl_drawinfo->dldrawlists[GLLDL_FLATS_BRIGHT].DrawFlats(GLPASS_LIGHTTEX_ADDITIVE); gl_drawinfo->dldrawlists[GLLDL_FLATS_MASKED].DrawFlats(GLPASS_LIGHTTEX_ADDITIVE); gl_drawinfo->dldrawlists[GLLDL_WALLS_FOG].DrawWalls(GLPASS_LIGHTTEX_FOGGY); gl_drawinfo->dldrawlists[GLLDL_WALLS_FOGMASKED].DrawWalls(GLPASS_LIGHTTEX_FOGGY); diff --git a/src/gl/data/gl_vertexbuffer.cpp b/src/gl/data/gl_vertexbuffer.cpp index 5833d3109..0309b2bcd 100644 --- a/src/gl/data/gl_vertexbuffer.cpp +++ b/src/gl/data/gl_vertexbuffer.cpp @@ -75,7 +75,7 @@ FVertexBuffer::~FVertexBuffer() void FSimpleVertexBuffer::BindVBO() { glBindBuffer(GL_ARRAY_BUFFER, vbo_id); - if (gl.glslversion > 0) + if (!gl.legacyMode) { glVertexAttribPointer(VATTR_VERTEX, 3, GL_FLOAT, false, sizeof(FSimpleVertex), &VSiO->x); glVertexAttribPointer(VATTR_TEXCOORD, 2, GL_FLOAT, false, sizeof(FSimpleVertex), &VSiO->u); @@ -100,7 +100,7 @@ void FSimpleVertexBuffer::EnableColorArray(bool on) { if (on) { - if (gl.glslversion > 0) + if (!gl.legacyMode) { glEnableVertexAttribArray(VATTR_COLOR); } @@ -111,7 +111,7 @@ void FSimpleVertexBuffer::EnableColorArray(bool on) } else { - if (gl.glslversion > 0) + if (!gl.legacyMode) { glDisableVertexAttribArray(VATTR_COLOR); } @@ -138,7 +138,7 @@ void FSimpleVertexBuffer::set(FSimpleVertex *verts, int count) //========================================================================== FFlatVertexBuffer::FFlatVertexBuffer(int width, int height) -: FVertexBuffer(gl.buffermethod != BM_CLIENTARRAY) +: FVertexBuffer(!gl.legacyMode) { switch (gl.buffermethod) { @@ -162,7 +162,7 @@ FFlatVertexBuffer::FFlatVertexBuffer(int width, int height) break; } - case BM_CLIENTARRAY: + default: { map = new FFlatVertex[BUFFER_SIZE]; DPrintf(DMSG_NOTIFY, "Using client array buffer\n"); @@ -219,7 +219,7 @@ FFlatVertexBuffer::~FFlatVertexBuffer() glUnmapBuffer(GL_ARRAY_BUFFER); glBindBuffer(GL_ARRAY_BUFFER, 0); } - if (gl.buffermethod == BM_CLIENTARRAY) + if (gl.legacyMode) { delete[] map; } @@ -230,19 +230,10 @@ FFlatVertexBuffer::~FFlatVertexBuffer() void FFlatVertexBuffer::BindVBO() { glBindBuffer(GL_ARRAY_BUFFER, vbo_id); - if (gl.glslversion > 0) + if (!gl.legacyMode) { - if (gl.buffermethod != BM_CLIENTARRAY) - { - glVertexAttribPointer(VATTR_VERTEX, 3, GL_FLOAT, false, sizeof(FFlatVertex), &VTO->x); - glVertexAttribPointer(VATTR_TEXCOORD, 2, GL_FLOAT, false, sizeof(FFlatVertex), &VTO->u); - } - else - { - // If we cannot use a hardware buffer, use an old-style client array. - glVertexAttribPointer(VATTR_VERTEX, 3, GL_FLOAT, false, sizeof(FFlatVertex), &map->x); - glVertexAttribPointer(VATTR_TEXCOORD, 2, GL_FLOAT, false, sizeof(FFlatVertex), &map->u); - } + glVertexAttribPointer(VATTR_VERTEX, 3, GL_FLOAT, false, sizeof(FFlatVertex), &VTO->x); + glVertexAttribPointer(VATTR_TEXCOORD, 2, GL_FLOAT, false, sizeof(FFlatVertex), &VTO->u); glEnableVertexAttribArray(VATTR_VERTEX); glEnableVertexAttribArray(VATTR_TEXCOORD); glDisableVertexAttribArray(VATTR_COLOR); diff --git a/src/gl/models/gl_models.cpp b/src/gl/models/gl_models.cpp index e686f2cea..22b61ace4 100644 --- a/src/gl/models/gl_models.cpp +++ b/src/gl/models/gl_models.cpp @@ -105,7 +105,7 @@ void gl_FlushModels() //=========================================================================== FModelVertexBuffer::FModelVertexBuffer(bool needindex, bool singleframe) - : FVertexBuffer(singleframe || gl.glslversion > 0) + : FVertexBuffer(singleframe || !gl.legacyMode) { vbo_ptr = nullptr; ibo_id = 0; @@ -125,7 +125,7 @@ void FModelVertexBuffer::BindVBO() { glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_id); glBindBuffer(GL_ARRAY_BUFFER, vbo_id); - if (gl.glslversion > 0) + if (!gl.legacyMode) { glEnableVertexAttribArray(VATTR_VERTEX); glEnableVertexAttribArray(VATTR_TEXCOORD); @@ -170,7 +170,7 @@ FModelVertex *FModelVertexBuffer::LockVertexBuffer(unsigned int size) { glBindBuffer(GL_ARRAY_BUFFER, vbo_id); glBufferData(GL_ARRAY_BUFFER, size * sizeof(FModelVertex), nullptr, GL_STATIC_DRAW); - if (gl.version >= 3.0) + if (!gl.legacyMode) return (FModelVertex*)glMapBufferRange(GL_ARRAY_BUFFER, 0, size * sizeof(FModelVertex), GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); else return (FModelVertex*)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); @@ -211,7 +211,7 @@ unsigned int *FModelVertexBuffer::LockIndexBuffer(unsigned int size) { glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_id); glBufferData(GL_ELEMENT_ARRAY_BUFFER, size * sizeof(unsigned int), NULL, GL_STATIC_DRAW); - if (gl.version >= 3.0) + if (!gl.legacyMode) return (unsigned int*)glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, 0, size * sizeof(unsigned int), GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); else return (unsigned int*)glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY); @@ -251,7 +251,7 @@ unsigned int FModelVertexBuffer::SetupFrame(unsigned int frame1, unsigned int fr glBindBuffer(GL_ARRAY_BUFFER, vbo_id); if (vbo_id > 0) { - if (gl.glslversion > 0) + if (!gl.legacyMode) { glVertexAttribPointer(VATTR_VERTEX, 3, GL_FLOAT, false, sizeof(FModelVertex), &VMO[frame1].x); glVertexAttribPointer(VATTR_TEXCOORD, 2, GL_FLOAT, false, sizeof(FModelVertex), &VMO[frame1].u); diff --git a/src/gl/renderer/gl_lightdata.cpp b/src/gl/renderer/gl_lightdata.cpp index 5d153894f..c2329879c 100644 --- a/src/gl/renderer/gl_lightdata.cpp +++ b/src/gl/renderer/gl_lightdata.cpp @@ -71,7 +71,7 @@ CUSTOM_CVAR(Bool, gl_enhanced_nightvision, true, CVAR_ARCHIVE|CVAR_NOINITCALL) { // The fixed colormap state needs to be reset because if this happens when // a shader is set to CM_LITE or CM_TORCH it won't register the change in behavior caused by this CVAR. - if (GLRenderer != NULL && GLRenderer->mShaderManager != NULL) + if (GLRenderer != nullptr && GLRenderer->mShaderManager != nullptr) { GLRenderer->mShaderManager->ResetFixedColormap(); } diff --git a/src/gl/renderer/gl_postprocess.cpp b/src/gl/renderer/gl_postprocess.cpp index 62815f718..684985074 100644 --- a/src/gl/renderer/gl_postprocess.cpp +++ b/src/gl/renderer/gl_postprocess.cpp @@ -72,6 +72,7 @@ #include "gl/shaders/gl_bloomshader.h" #include "gl/shaders/gl_blurshader.h" #include "gl/shaders/gl_tonemapshader.h" +#include "gl/shaders/gl_colormapshader.h" #include "gl/shaders/gl_lensshader.h" #include "gl/shaders/gl_presentshader.h" #include "gl/renderer/gl_2ddrawer.h" @@ -135,10 +136,11 @@ void FGLRenderer::RenderScreenQuad() void FGLRenderer::PostProcessScene() { - if (FGLRenderBuffers::IsEnabled()) mBuffers->BlitSceneToTexture(); + mBuffers->BlitSceneToTexture(); AmbientOccludeScene(); BloomScene(); TonemapScene(); + ColormapScene(); LensDistortScene(); } @@ -240,7 +242,7 @@ void FGLRenderer::AmbientOccludeScene() void FGLRenderer::BloomScene() { // Only bloom things if enabled and no special fixed light mode is active - if (!gl_bloom || !FGLRenderBuffers::IsEnabled() || gl_fixedcolormap != CM_DEFAULT || gl_ssao_debug) + if (!gl_bloom || gl_fixedcolormap != CM_DEFAULT || gl_ssao_debug) return; FGLDebug::PushGroup("BloomScene"); @@ -326,7 +328,7 @@ void FGLRenderer::BloomScene() void FGLRenderer::TonemapScene() { - if (gl_tonemap == 0 || !FGLRenderBuffers::IsEnabled()) + if (gl_tonemap == 0) return; FGLDebug::PushGroup("TonemapScene"); @@ -398,6 +400,38 @@ void FGLRenderer::ClearTonemapPalette() mTonemapPalette = nullptr; } +//----------------------------------------------------------------------------- +// +// Colormap scene texture and place the result in the HUD/2D texture +// +//----------------------------------------------------------------------------- + +void FGLRenderer::ColormapScene() +{ + if (gl_fixedcolormap < CM_FIRSTSPECIALCOLORMAP || gl_fixedcolormap >= CM_MAXCOLORMAP) + return; + + FGLDebug::PushGroup("ColormapScene"); + + FGLPostProcessState savedState; + + mBuffers->BindNextFB(); + mBuffers->BindCurrentTexture(0); + mColormapShader->Bind(); + + FSpecialColormap *scm = &SpecialColormaps[gl_fixedcolormap - CM_FIRSTSPECIALCOLORMAP]; + float m[] = { scm->ColorizeEnd[0] - scm->ColorizeStart[0], + scm->ColorizeEnd[1] - scm->ColorizeStart[1], scm->ColorizeEnd[2] - scm->ColorizeStart[2], 0.f }; + + mColormapShader->MapStart.Set(scm->ColorizeStart[0], scm->ColorizeStart[1], scm->ColorizeStart[2], 0.f); + mColormapShader->MapRange.Set(m); + + RenderScreenQuad(); + mBuffers->NextTexture(); + + FGLDebug::PopGroup(); +} + //----------------------------------------------------------------------------- // // Apply lens distortion and place the result in the HUD/2D texture @@ -406,7 +440,7 @@ void FGLRenderer::ClearTonemapPalette() void FGLRenderer::LensDistortScene() { - if (gl_lens == 0 || !FGLRenderBuffers::IsEnabled()) + if (gl_lens == 0) return; FGLDebug::PushGroup("LensDistortScene"); diff --git a/src/gl/renderer/gl_renderbuffers.cpp b/src/gl/renderer/gl_renderbuffers.cpp index 6da85bba7..93625722d 100644 --- a/src/gl/renderer/gl_renderbuffers.cpp +++ b/src/gl/renderer/gl_renderbuffers.cpp @@ -56,7 +56,14 @@ #include CVAR(Int, gl_multisample, 1, CVAR_ARCHIVE|CVAR_GLOBALCONFIG); -CVAR(Bool, gl_renderbuffers, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG); +CUSTOM_CVAR(Bool, gl_renderbuffers, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL) +{ + // this CVAR alters some fixed colormap related settings + if (GLRenderer != nullptr && GLRenderer->mShaderManager != nullptr) + { + //GLRenderer->mShaderManager->ResetFixedColormap(); + } +} //========================================================================== // @@ -95,7 +102,6 @@ void FGLRenderBuffers::ClearScene() DeleteFrameBuffer(mSceneFB); DeleteRenderBuffer(mSceneMSColor); DeleteRenderBuffer(mSceneMSDepthStencil); - DeleteRenderBuffer(mSceneMSDepth); DeleteRenderBuffer(mSceneMSStencil); } @@ -107,7 +113,6 @@ void FGLRenderBuffers::ClearPipeline() DeleteTexture(mPipelineTexture[i]); } DeleteTexture(mPipelineDepthStencil); - DeleteTexture(mPipelineDepth); DeleteTexture(mPipelineStencil); } @@ -233,25 +238,12 @@ void FGLRenderBuffers::CreateScene(int width, int height, int samples) if (samples > 1) { mSceneMSColor = CreateRenderBuffer("SceneMSColor", GetHdrFormat(), samples, width, height); - - if ((gl.flags & RFL_NO_DEPTHSTENCIL) != 0) - { - mSceneMSDepth = CreateRenderBuffer("SceneMSDepth", GL_DEPTH_COMPONENT24, samples, width, height); - mSceneMSStencil = CreateRenderBuffer("SceneMSStencil", GL_STENCIL_INDEX8, samples, width, height); - mSceneFB = CreateFrameBuffer("SceneFB", mSceneMSColor, mSceneMSDepth, mSceneMSStencil, true); - } - else - { - mSceneMSDepthStencil = CreateRenderBuffer("SceneMSDepthStencil", GL_DEPTH24_STENCIL8, samples, width, height); - mSceneFB = CreateFrameBuffer("SceneFB", mSceneMSColor, mSceneMSDepthStencil, true); - } + mSceneMSDepthStencil = CreateRenderBuffer("SceneMSDepthStencil", GL_DEPTH24_STENCIL8, samples, width, height); + mSceneFB = CreateFrameBuffer("SceneFB", mSceneMSColor, mSceneMSDepthStencil, true); } else { - if ((gl.flags & RFL_NO_DEPTHSTENCIL) != 0) - mSceneFB = CreateFrameBuffer("SceneFB", mPipelineTexture[0], mPipelineDepth, mPipelineStencil, false); - else - mSceneFB = CreateFrameBuffer("SceneFB", mPipelineTexture[0], mPipelineDepthStencil, false); + mSceneFB = CreateFrameBuffer("SceneFB", mPipelineTexture[0], mPipelineDepthStencil, false); } } @@ -265,23 +257,12 @@ void FGLRenderBuffers::CreatePipeline(int width, int height) { ClearPipeline(); - if ((gl.flags & RFL_NO_DEPTHSTENCIL) != 0) - { - mPipelineDepth = Create2DTexture("PipelineDepth", GL_DEPTH_COMPONENT24, width, height); - mPipelineStencil = Create2DTexture("PipelineStencil", GL_STENCIL_INDEX8, width, height); - } - else - { - mPipelineDepthStencil = Create2DTexture("PipelineDepthStencil", GL_DEPTH24_STENCIL8, width, height); - } + mPipelineDepthStencil = Create2DTexture("PipelineDepthStencil", GL_DEPTH24_STENCIL8, width, height); for (int i = 0; i < NumPipelineTextures; i++) { mPipelineTexture[i] = Create2DTexture("PipelineTexture", GetHdrFormat(), width, height); - if ((gl.flags & RFL_NO_DEPTHSTENCIL) != 0) - mPipelineFB[i] = CreateFrameBuffer("PipelineFB", mPipelineTexture[i], mPipelineDepth, mPipelineStencil, false); - else - mPipelineFB[i] = CreateFrameBuffer("PipelineFB", mPipelineTexture[i], mPipelineDepthStencil, false); + mPipelineFB[i] = CreateFrameBuffer("PipelineFB", mPipelineTexture[i], mPipelineDepthStencil, false); } } @@ -366,7 +347,7 @@ void FGLRenderBuffers::CreateAmbientOcclusion(int width, int height) GLuint FGLRenderBuffers::GetHdrFormat() { - return ((gl.flags & RFL_NO_RGBA16F) != 0) ? GL_RGBA8 : GL_RGBA16F; + return GL_RGBA16F; } //========================================================================== @@ -606,10 +587,7 @@ void FGLRenderBuffers::BindSceneFB() void FGLRenderBuffers::BindSceneDepthTexture(int index) { glActiveTexture(GL_TEXTURE0 + index); - if ((gl.flags & RFL_NO_DEPTHSTENCIL) != 0) - glBindTexture(GL_TEXTURE_2D, mPipelineDepth); - else - glBindTexture(GL_TEXTURE_2D, mPipelineDepthStencil); + glBindTexture(GL_TEXTURE_2D, mPipelineDepthStencil); } //========================================================================== @@ -677,7 +655,7 @@ void FGLRenderBuffers::BindOutputFB() bool FGLRenderBuffers::IsEnabled() { - return gl_renderbuffers && gl.glslversion != 0 && !FailedCreate; + return gl_renderbuffers && !gl.legacyMode && !FailedCreate; } bool FGLRenderBuffers::FailedCreate = false; diff --git a/src/gl/renderer/gl_renderbuffers.h b/src/gl/renderer/gl_renderbuffers.h index 5dc2e49bd..87e20117d 100644 --- a/src/gl/renderer/gl_renderbuffers.h +++ b/src/gl/renderer/gl_renderbuffers.h @@ -89,7 +89,6 @@ private: // Buffers for the scene GLuint mSceneMSColor = 0; GLuint mSceneMSDepthStencil = 0; - GLuint mSceneMSDepth = 0; GLuint mSceneMSStencil = 0; GLuint mSceneFB = 0; @@ -97,7 +96,6 @@ private: GLuint mPipelineTexture[NumPipelineTextures]; GLuint mPipelineFB[NumPipelineTextures]; GLuint mPipelineDepthStencil = 0; - GLuint mPipelineDepth = 0; GLuint mPipelineStencil = 0; // Back buffer frame buffer diff --git a/src/gl/renderer/gl_renderer.cpp b/src/gl/renderer/gl_renderer.cpp index 9e64c13b0..2d32f0d20 100644 --- a/src/gl/renderer/gl_renderer.cpp +++ b/src/gl/renderer/gl_renderer.cpp @@ -68,6 +68,7 @@ #include "gl/shaders/gl_bloomshader.h" #include "gl/shaders/gl_blurshader.h" #include "gl/shaders/gl_tonemapshader.h" +#include "gl/shaders/gl_colormapshader.h" #include "gl/shaders/gl_lensshader.h" #include "gl/shaders/gl_presentshader.h" #include "gl/textures/gl_texture.h" @@ -98,21 +99,30 @@ CVAR(Bool, gl_scale_viewport, true, 0); FGLRenderer::FGLRenderer(OpenGLFrameBuffer *fb) { framebuffer = fb; - mClipPortal = NULL; - mCurrentPortal = NULL; + mClipPortal = nullptr; + mCurrentPortal = nullptr; mMirrorCount = 0; mPlaneMirrorCount = 0; mLightCount = 0; mAngles = FRotator(0.f, 0.f, 0.f); mViewVector = FVector2(0,0); - mVBO = NULL; - mSkyVBO = NULL; + mVBO = nullptr; + mSkyVBO = nullptr; gl_spriteindex = 0; - mShaderManager = NULL; - gllight = glpart2 = glpart = mirrortexture = NULL; - mLights = NULL; + mShaderManager = nullptr; + gllight = glpart2 = glpart = mirrortexture = nullptr; + mLights = nullptr; m2DDrawer = nullptr; mTonemapPalette = nullptr; + mBuffers = nullptr; + mPresentShader = nullptr; + mBloomExtractShader = nullptr; + mBloomCombineShader = nullptr; + mBlurShader = nullptr; + mTonemapShader = nullptr; + mTonemapPalette = nullptr; + mColormapShader = nullptr; + mLensShader = nullptr; } void gl_LoadModels(); @@ -127,13 +137,14 @@ void FGLRenderer::Initialize(int width, int height) mBloomCombineShader = new FBloomCombineShader(); mBlurShader = new FBlurShader(); mTonemapShader = new FTonemapShader(); + mColormapShader = new FColormapShader(); mTonemapPalette = nullptr; mLensShader = new FLensShader(); mPresentShader = new FPresentShader(); m2DDrawer = new F2DDrawer; - // Only needed for the core profile, because someone decided it was a good idea to remove the default VAO. - if (gl.buffermethod != BM_CLIENTARRAY) + // needed for the core profile, because someone decided it was a good idea to remove the default VAO. + if (!gl.legacyMode) { glGenVertexArrays(1, &mVAOID); glBindVertexArray(mVAOID); @@ -148,7 +159,7 @@ void FGLRenderer::Initialize(int width, int height) mVBO = new FFlatVertexBuffer(width, height); mSkyVBO = new FSkyVertexBuffer; - if (gl.lightmethod != LM_SOFTWARE) mLights = new FLightBuffer(); + if (!gl.legacyMode) mLights = new FLightBuffer(); else mLights = NULL; gl_RenderState.SetVertexBuffer(mVBO); mFBID = 0; @@ -189,6 +200,7 @@ FGLRenderer::~FGLRenderer() if (mBlurShader) delete mBlurShader; if (mTonemapShader) delete mTonemapShader; if (mTonemapPalette) delete mTonemapPalette; + if (mColormapShader) delete mColormapShader; if (mLensShader) delete mLensShader; } diff --git a/src/gl/renderer/gl_renderer.h b/src/gl/renderer/gl_renderer.h index b07870738..c487c4a77 100644 --- a/src/gl/renderer/gl_renderer.h +++ b/src/gl/renderer/gl_renderer.h @@ -25,6 +25,7 @@ class FBloomExtractShader; class FBloomCombineShader; class FBlurShader; class FTonemapShader; +class FColormapShader; class FLensShader; class FPresentShader; class F2DDrawer; @@ -97,6 +98,7 @@ public: FBloomCombineShader *mBloomCombineShader; FBlurShader *mBlurShader; FTonemapShader *mTonemapShader; + FColormapShader *mColormapShader; FHardwareTexture *mTonemapPalette; FLensShader *mLensShader; FPresentShader *mPresentShader; @@ -172,6 +174,7 @@ public: void AmbientOccludeScene(); void BloomScene(); void TonemapScene(); + void ColormapScene(); void BindTonemapPalette(int texunit); void ClearTonemapPalette(); void LensDistortScene(); diff --git a/src/gl/renderer/gl_renderstate.cpp b/src/gl/renderer/gl_renderstate.cpp index aa7972f1a..aa41b556d 100644 --- a/src/gl/renderer/gl_renderstate.cpp +++ b/src/gl/renderer/gl_renderstate.cpp @@ -49,6 +49,7 @@ #include "gl/renderer/gl_renderstate.h" #include "gl/renderer/gl_colormap.h" #include "gl/dynlights//gl_lightbuffer.h" +#include "gl/renderer/gl_renderbuffers.h" void gl_SetTextureMode(int type); @@ -221,15 +222,24 @@ bool FRenderState::ApplyShader() { activeShader->muFixedColormap.Set(0); } - else if (mColormapState < CM_MAXCOLORMAP) + else if (mColormapState > CM_DEFAULT && mColormapState < CM_MAXCOLORMAP) { - FSpecialColormap *scm = &SpecialColormaps[gl_fixedcolormap - CM_FIRSTSPECIALCOLORMAP]; - float m[] = { scm->ColorizeEnd[0] - scm->ColorizeStart[0], - scm->ColorizeEnd[1] - scm->ColorizeStart[1], scm->ColorizeEnd[2] - scm->ColorizeStart[2], 0.f }; + if (FGLRenderBuffers::IsEnabled()) + { + // When using postprocessing to apply the colormap, we must render the image fullbright here. + activeShader->muFixedColormap.Set(2); + activeShader->muColormapStart.Set(1, 1, 1, 1.f); + } + else + { + FSpecialColormap *scm = &SpecialColormaps[gl_fixedcolormap - CM_FIRSTSPECIALCOLORMAP]; + float m[] = { scm->ColorizeEnd[0] - scm->ColorizeStart[0], + scm->ColorizeEnd[1] - scm->ColorizeStart[1], scm->ColorizeEnd[2] - scm->ColorizeStart[2], 0.f }; - activeShader->muFixedColormap.Set(1); - activeShader->muColormapStart.Set(scm->ColorizeStart[0], scm->ColorizeStart[1], scm->ColorizeStart[2], 0.f); - activeShader->muColormapRange.Set(m); + activeShader->muFixedColormap.Set(1); + activeShader->muColormapStart.Set(scm->ColorizeStart[0], scm->ColorizeStart[1], scm->ColorizeStart[2], 0.f); + activeShader->muColormapRange.Set(m); + } } else if (mColormapState == CM_FOGLAYER) { @@ -315,7 +325,7 @@ void FRenderState::Apply() else mVertexBuffer->BindVBO(); mCurrentVertexBuffer = mVertexBuffer; } - if (gl.glslversion > 0) + if (!gl.legacyMode) { ApplyShader(); } @@ -352,7 +362,7 @@ void FRenderState::ApplyMatrices() void FRenderState::ApplyLightIndex(int index) { - if (gl.lightmethod != LM_SOFTWARE) + if (!gl.legacyMode) { if (index > -1 && GLRenderer->mLights->GetBufferType() == GL_UNIFORM_BUFFER) { diff --git a/src/gl/renderer/gl_renderstate.h b/src/gl/renderer/gl_renderstate.h index 3e0729bbe..6acf44026 100644 --- a/src/gl/renderer/gl_renderstate.h +++ b/src/gl/renderer/gl_renderstate.h @@ -113,7 +113,7 @@ public: // Without shaders this translation must be applied to any texture. if (alphatexture) { - if (mat->tex->UseBasePalette() || gl.glslversion == 0) translation = TRANSLATION(TRANSLATION_Standard, 8); + if (mat->tex->UseBasePalette() || gl.legacyMode) translation = TRANSLATION(TRANSLATION_Standard, 8); } mEffectState = overrideshader >= 0? overrideshader : mat->mShaderIndex; mShaderTimer = mat->tex->gl_info.shaderspeed; diff --git a/src/gl/scene/gl_drawinfo.cpp b/src/gl/scene/gl_drawinfo.cpp index 842423094..c34d79816 100644 --- a/src/gl/scene/gl_drawinfo.cpp +++ b/src/gl/scene/gl_drawinfo.cpp @@ -322,7 +322,7 @@ void GLDrawList::SortWallIntoPlane(SortNode * head,SortNode * sort) AddWall(&w); // Splitting is done in the shader with clip planes, if available - if (gl.glslversion < 1.3f) + if (gl.flags & RFL_NO_CLIP_PLANES) { GLWall * ws1; ws->vertcount = 0; // invalidate current vertices. @@ -382,7 +382,7 @@ void GLDrawList::SortSpriteIntoPlane(SortNode * head,SortNode * sort) AddSprite(&s); // add a copy to avoid reallocation issues. // Splitting is done in the shader with clip planes, if available - if (gl.glslversion < 1.3f) + if (gl.flags & RFL_NO_CLIP_PLANES) { GLSprite * ss1; ss1=&sprites[sprites.Size()-1]; @@ -476,9 +476,15 @@ void GLDrawList::SortWallIntoWall(SortNode * head,SortNode * sort) ws1->glseg.x1=ws->glseg.x2=ix; ws1->glseg.y1=ws->glseg.y2=iy; + ws1->glseg.fracleft = ws->glseg.fracright = ws->glseg.fracleft + r*(ws->glseg.fracright - ws->glseg.fracleft); ws1->ztop[0]=ws->ztop[1]=izt; ws1->zbottom[0]=ws->zbottom[1]=izb; ws1->tcs[GLWall::LOLFT].u = ws1->tcs[GLWall::UPLFT].u = ws->tcs[GLWall::LORGT].u = ws->tcs[GLWall::UPRGT].u = iu; + if (gl.buffermethod == BM_DEFERRED) + { + ws->MakeVertices(false); + ws1->MakeVertices(false); + } SortNode * sort2=SortNodes.GetNew(); memset(sort2,0,sizeof(SortNode)); @@ -805,17 +811,19 @@ void GLDrawList::DrawSorted() if (!sorted) { + GLRenderer->mVBO->Map(); MakeSortList(); sorted=DoSort(SortNodes[SortNodeStart]); + GLRenderer->mVBO->Unmap(); } gl_RenderState.ClearClipSplit(); - if (gl.glslversion >= 1.3f) + if (!(gl.flags & RFL_NO_CLIP_PLANES)) { glEnable(GL_CLIP_DISTANCE1); glEnable(GL_CLIP_DISTANCE2); } DoDrawSorted(sorted); - if (gl.glslversion >= 1.3f) + if (!(gl.flags & RFL_NO_CLIP_PLANES)) { glDisable(GL_CLIP_DISTANCE1); glDisable(GL_CLIP_DISTANCE2); @@ -994,7 +1002,7 @@ static FDrawInfoList di_list; FDrawInfo::FDrawInfo() { next = NULL; - if (gl.lightmethod == LM_SOFTWARE) + if (gl.legacyMode) { dldrawlists = new GLDrawList[GLLDL_TYPES]; } diff --git a/src/gl/scene/gl_drawinfo.h b/src/gl/scene/gl_drawinfo.h index 124440eee..0e7296ee3 100644 --- a/src/gl/scene/gl_drawinfo.h +++ b/src/gl/scene/gl_drawinfo.h @@ -30,11 +30,9 @@ enum DLDrawListType { // These are organized so that the various multipass rendering modes have to be set as few times as possible GLLDL_WALLS_PLAIN, // dynamic lights on normal walls - GLLDL_WALLS_BRIGHT, // dynamic lights on brightmapped walls GLLDL_WALLS_MASKED, // dynamic lights on masked midtextures GLLDL_FLATS_PLAIN, // dynamic lights on normal flats - GLLDL_FLATS_BRIGHT, // dynamic lights on brightmapped flats GLLDL_FLATS_MASKED, // dynamic lights on masked flats GLLDL_WALLS_FOG, // lights on fogged walls diff --git a/src/gl/scene/gl_flats.cpp b/src/gl/scene/gl_flats.cpp index 8b665648e..1a3fe994b 100644 --- a/src/gl/scene/gl_flats.cpp +++ b/src/gl/scene/gl_flats.cpp @@ -430,7 +430,7 @@ void GLFlat::Draw(int pass, bool trans) // trans only has meaning for GLPASS_LIG { gl_RenderState.SetMaterial(gltexture, CLAMP_NONE, 0, -1, false); gl_SetPlaneTextureRotation(&plane, gltexture); - DrawSubsectors(pass, gl.lightmethod != LM_SOFTWARE, true); + DrawSubsectors(pass, !gl.legacyMode, true); gl_RenderState.EnableTextureMatrix(false); } if (renderstyle==STYLE_Add) gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); @@ -468,7 +468,7 @@ inline void GLFlat::PutFlat(bool fog) { Colormap.Clear(); } - if (gl.lightmethod == LM_SOFTWARE) + if (gl.legacyMode) { if (PutFlatCompat(fog)) return; } diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index 7537010b3..109b5fdbe 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -409,7 +409,7 @@ void FGLRenderer::RenderScene(int recursion) // this is the only geometry type on which decals can possibly appear gl_drawinfo->drawlists[GLDL_PLAINWALLS].DrawDecals(); - if (gl.lightmethod == LM_SOFTWARE) + if (gl.legacyMode) { // also process the render lists with walls and dynamic lights gl_drawinfo->dldrawlists[GLLDL_WALLS_PLAIN].DrawDecals(); @@ -480,7 +480,6 @@ void FGLRenderer::RenderTranslucent() // stencil, z-buffer and the projection matrix intact! // //----------------------------------------------------------------------------- -EXTERN_CVAR(Bool, gl_draw_sync) void FGLRenderer::DrawScene(int drawmode) { @@ -502,14 +501,6 @@ void FGLRenderer::DrawScene(int drawmode) } GLRenderer->mClipPortal = NULL; // this must be reset before any portal recursion takes place. - // Up to this point in the main draw call no rendering is performed so we can wait - // with swapping the render buffer until now. - if (!gl_draw_sync && drawmode == DM_MAINVIEW) - { - All.Unclock(); - static_cast(screen)->Swap(); - All.Clock(); - } RenderScene(recursion); // Handle all portals after rendering the opaque objects but before @@ -644,12 +635,14 @@ void FGLRenderer::DrawBlend(sector_t * viewsector) V_AddBlend (player->BlendR, player->BlendG, player->BlendB, player->BlendA, blend); } + gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); if (blend[3]>0.0f) { - gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); gl_RenderState.SetColor(blend[0], blend[1], blend[2], blend[3]); gl_FillScreen(); } + gl_RenderState.ResetColor(); + gl_RenderState.EnableTexture(true); } @@ -685,16 +678,19 @@ void FGLRenderer::EndDrawScene(sector_t * viewsector) { DrawPlayerSprites (viewsector, false); } - int cm = gl_RenderState.GetFixedColormap(); + if (gl.legacyMode) + { + int cm = gl_RenderState.GetFixedColormap(); + gl_RenderState.SetFixedColormap(cm); + gl_RenderState.DrawColormapOverlay(); + } + gl_RenderState.SetFixedColormap(CM_DEFAULT); gl_RenderState.SetSoftLightLevel(-1); DrawTargeterSprites(); - DrawBlend(viewsector); - if (gl.glslversion == 0.0) + if (FGLRenderBuffers::IsEnabled()) { - gl_RenderState.SetFixedColormap(cm); - gl_RenderState.DrawColormapOverlay(); - gl_RenderState.SetFixedColormap(CM_DEFAULT); + DrawBlend(viewsector); } // Restore standard rendering state @@ -855,7 +851,11 @@ sector_t * FGLRenderer::RenderViewpoint (AActor * camera, GL_IRECT * bounds, flo ProcessScene(toscreen); if (mainview && toscreen) EndDrawScene(retval); // do not call this for camera textures. - if (mainview) PostProcessScene(); + if (mainview && FGLRenderBuffers::IsEnabled()) + { + PostProcessScene(); + DrawBlend(viewsector); // This should be done after postprocessing, not before. + } mDrawingScene2D = false; eye->TearDown(); } @@ -899,7 +899,7 @@ void FGLRenderer::RenderView (player_t* player) P_FindParticleSubsectors (); - if (gl.lightmethod != LM_SOFTWARE) GLRenderer->mLights->Clear(); + if (!gl.legacyMode) GLRenderer->mLights->Clear(); // NoInterpolateView should have no bearing on camera textures, but needs to be preserved for the main view below. bool saved_niv = NoInterpolateView; @@ -954,7 +954,7 @@ void FGLRenderer::WriteSavePic (player_t *player, FILE *file, int width, int hei SetFixedColormap(player); gl_RenderState.SetVertexBuffer(mVBO); GLRenderer->mVBO->Reset(); - if (gl.lightmethod != LM_SOFTWARE) GLRenderer->mLights->Clear(); + if (!gl.legacyMode) GLRenderer->mLights->Clear(); // Check if there's some lights. If not some code can be skipped. TThinkerIterator it(STAT_DLIGHT); diff --git a/src/gl/scene/gl_skydome.cpp b/src/gl/scene/gl_skydome.cpp index 2b6843bdf..97c5cb458 100644 --- a/src/gl/scene/gl_skydome.cpp +++ b/src/gl/scene/gl_skydome.cpp @@ -87,7 +87,7 @@ FSkyVertexBuffer::~FSkyVertexBuffer() void FSkyVertexBuffer::BindVBO() { glBindBuffer(GL_ARRAY_BUFFER, vbo_id); - if (gl.glslversion > 0) + if (!gl.legacyMode) { glVertexAttribPointer(VATTR_VERTEX, 3, GL_FLOAT, false, sizeof(FSkyVertex), &VSO->x); glVertexAttribPointer(VATTR_TEXCOORD, 2, GL_FLOAT, false, sizeof(FSkyVertex), &VSO->u); @@ -321,7 +321,7 @@ void FSkyVertexBuffer::RenderDome(FMaterial *tex, int mode) RenderRow(GL_TRIANGLE_FAN, rc); gl_RenderState.EnableTexture(true); // The color array can only be activated now if this is drawn without shader - if (gl.glslversion == 0) + if (gl.legacyMode) { glEnableClientState(GL_COLOR_ARRAY); } diff --git a/src/gl/scene/gl_sprite.cpp b/src/gl/scene/gl_sprite.cpp index 0c5b2581a..8a8c89c80 100644 --- a/src/gl/scene/gl_sprite.cpp +++ b/src/gl/scene/gl_sprite.cpp @@ -870,7 +870,7 @@ void GLSprite::Process(AActor* thing, sector_t * sector, int thruportal) RenderStyle.CheckFuzz(); if (RenderStyle.BlendOp == STYLEOP_Fuzz) { - if (gl_fuzztype != 0 && gl.glslversion > 0) + if (gl_fuzztype != 0 && !gl.legacyMode) { // Todo: implement shader selection here RenderStyle = LegacyRenderStyles[STYLE_Translucent]; diff --git a/src/gl/scene/gl_walls.cpp b/src/gl/scene/gl_walls.cpp index 3afde063c..f8bb2a876 100644 --- a/src/gl/scene/gl_walls.cpp +++ b/src/gl/scene/gl_walls.cpp @@ -140,9 +140,8 @@ void GLWall::PutWall(bool translucent) } else { - if (gl.lightmethod == LM_SOFTWARE && !translucent) + if (gl.legacyMode && !translucent) { - // This is not yet ready. if (PutWallCompat(passflag[type])) return; } diff --git a/src/gl/scene/gl_walls_draw.cpp b/src/gl/scene/gl_walls_draw.cpp index 585ced1a8..40145abc4 100644 --- a/src/gl/scene/gl_walls_draw.cpp +++ b/src/gl/scene/gl_walls_draw.cpp @@ -216,9 +216,8 @@ void GLWall::RenderWall(int textured) } else if (vertcount == 0) { - // in case we get here without valid vertex data and no ability to create them now, - // use the quad drawer as fallback (without edge splitting.) - // This can only happen in one special situation, when a translucent line got split during sorting. + // This should never happen but in case it actually does, use the quad drawer as fallback (without edge splitting.) + // This way it at least gets drawn. FQuadDrawer qd; qd.Set(0, glseg.x1, zbottom[0], glseg.y1, tcs[LOLFT].u, tcs[LOLFT].v); qd.Set(1, glseg.x1, ztop[0], glseg.y1, tcs[UPLFT].u, tcs[UPLFT].v); @@ -242,7 +241,7 @@ void GLWall::RenderFogBoundary() { if (gl_fogmode && gl_fixedcolormap == 0) { - if (gl.glslversion > 0.f) + if (!gl.legacyMode) { int rel = rellight + getExtraLight(); gl_SetFog(lightlevel, rel, &Colormap, false); @@ -276,7 +275,7 @@ void GLWall::RenderMirrorSurface() Vector v(glseg.y2-glseg.y1, 0 ,-glseg.x2+glseg.x1); v.Normalize(); - if (gl.glslversion >= 0.f) + if (!gl.legacyMode) { // we use texture coordinates and texture matrix to pass the normal stuff to the shader so that the default vertex buffer format can be used as is. tcs[LOLFT].u = tcs[LORGT].u = tcs[UPLFT].u = tcs[UPRGT].u = v.X(); diff --git a/src/gl/shaders/gl_blurshader.cpp b/src/gl/shaders/gl_blurshader.cpp index 6154c17ce..bf2e29c7e 100644 --- a/src/gl/shaders/gl_blurshader.cpp +++ b/src/gl/shaders/gl_blurshader.cpp @@ -87,20 +87,6 @@ void FBlurShader::Blur(FGLRenderer *renderer, float blurAmount, int sampleCount, else setup->HorizontalShader->Bind(); - if (gl.glslversion < 1.3) - { - if (vertical) - { - setup->VerticalScaleX.Set(1.0f / width); - setup->VerticalScaleY.Set(1.0f / height); - } - else - { - setup->HorizontalScaleX.Set(1.0f / width); - setup->HorizontalScaleY.Set(1.0f / height); - } - } - glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, inputTexture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); @@ -156,14 +142,6 @@ FBlurShader::BlurSetup *FBlurShader::GetSetup(float blurAmount, int sampleCount) blurSetup.HorizontalShader->Bind(); glUniform1i(glGetUniformLocation(*blurSetup.HorizontalShader.get(), "SourceTexture"), 0); - if (gl.glslversion < 1.3) - { - blurSetup.VerticalScaleX.Init(*blurSetup.VerticalShader.get(), "ScaleX"); - blurSetup.VerticalScaleY.Init(*blurSetup.VerticalShader.get(), "ScaleY"); - blurSetup.HorizontalScaleX.Init(*blurSetup.HorizontalShader.get(), "ScaleX"); - blurSetup.HorizontalScaleY.Init(*blurSetup.HorizontalShader.get(), "ScaleY"); - } - mBlurSetups.Push(blurSetup); return &mBlurSetups[mBlurSetups.Size() - 1]; diff --git a/src/gl/shaders/gl_colormapshader.cpp b/src/gl/shaders/gl_colormapshader.cpp new file mode 100644 index 000000000..f28003150 --- /dev/null +++ b/src/gl/shaders/gl_colormapshader.cpp @@ -0,0 +1,67 @@ +/* +** gl_colormapshader.cpp +** Applies a fullscreen colormap to the scene +** +**--------------------------------------------------------------------------- +** Copyright 2016 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_colormapshader.h" + +void FColormapShader::Bind() +{ + auto &shader = mShader; + if (!shader) + { + shader.Compile(FShaderProgram::Vertex, "shaders/glsl/screenquad.vp", "", 330); + shader.Compile(FShaderProgram::Fragment, "shaders/glsl/colormap.fp", "", 330); + shader.SetFragDataLocation(0, "FragColor"); + shader.Link("shaders/glsl/colormap"); + shader.SetAttribLocation(0, "PositionInProjection"); + MapStart.Init(shader, "uFixedColormapStart"); + MapRange.Init(shader, "uFixedColormapRange"); + } + shader.Bind(); +} + diff --git a/src/gl/shaders/gl_colormapshader.h b/src/gl/shaders/gl_colormapshader.h new file mode 100644 index 000000000..b20c23a4c --- /dev/null +++ b/src/gl/shaders/gl_colormapshader.h @@ -0,0 +1,20 @@ +#ifndef __GL_COLORMAPSHADER_H +#define __GL_COLORMAPSHADER_H + +#include "gl_shaderprogram.h" + +class FColormapShader +{ +public: + void Bind(); + + FBufferedUniformSampler SceneTexture; + FUniform4f MapStart; + FUniform4f MapRange; + +private: + + FShaderProgram mShader; +}; + +#endif \ No newline at end of file diff --git a/src/gl/shaders/gl_shader.cpp b/src/gl/shaders/gl_shader.cpp index fa4c92933..ef8f19547 100644 --- a/src/gl/shaders/gl_shader.cpp +++ b/src/gl/shaders/gl_shader.cpp @@ -91,40 +91,27 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char * // FString vp_comb; - if (gl.lightmethod == LM_SOFTWARE) + assert(GLRenderer->mLights != NULL); + // On the shader side there is no difference between LM_DEFERRED and LM_DIRECT, it only decides how the buffer is initialized. + unsigned int lightbuffertype = GLRenderer->mLights->GetBufferType(); + unsigned int lightbuffersize = GLRenderer->mLights->GetBlockSize(); + if (lightbuffertype == GL_UNIFORM_BUFFER) { - if (gl.glslversion >= 1.3) + // This differentiation is for some Intel drivers which fail on #extension, so use of #version 140 is necessary + if (gl.glslversion < 1.4f) { - vp_comb = "#version 130\n"; + vp_comb.Format("#version 130\n#extension GL_ARB_uniform_buffer_object : require\n#define NUM_UBO_LIGHTS %d\n", lightbuffersize); } else { - vp_comb = "#define GLSL12_COMPATIBLE\n"; + vp_comb.Format("#version 140\n#define NUM_UBO_LIGHTS %d\n", lightbuffersize); } } else { - assert(GLRenderer->mLights != NULL); - // On the shader side there is no difference between LM_DEFERRED and LM_DIRECT, it only matters which buffer type is used by the light buffer. - unsigned int lightbuffertype = GLRenderer->mLights->GetBufferType(); - unsigned int lightbuffersize = GLRenderer->mLights->GetBlockSize(); - if (lightbuffertype == GL_UNIFORM_BUFFER) - { - // This differentiation is for some Intel drivers which fail on #extension, so use of #version 140 is necessary - if (gl.glslversion < 1.4f || gl.version < 3.1f) - { - vp_comb.Format("#version 130\n#extension GL_ARB_uniform_buffer_object : require\n#define NUM_UBO_LIGHTS %d\n", lightbuffersize); - } - else - { - vp_comb.Format("#version 140\n#define NUM_UBO_LIGHTS %d\n", lightbuffersize); - } - } - else - { - vp_comb = "#version 400 core\n#extension GL_ARB_shader_storage_buffer_object : require\n#define SHADER_STORAGE_LIGHTS\n"; - } + vp_comb = "#version 400 core\n#extension GL_ARB_shader_storage_buffer_object : require\n#define SHADER_STORAGE_LIGHTS\n"; } + if (gl.buffermethod == BM_DEFERRED) { vp_comb << "#define USE_QUAD_DRAWER\n"; @@ -169,12 +156,7 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char * } } - if (gl.glslversion < 1.3) - { - FShaderProgram::PatchVertShader(vp_comb); - FShaderProgram::PatchFragShader(fp_comb); - } - else if (gl.flags & RFL_NO_CLIP_PLANES) + if (gl.flags & RFL_NO_CLIP_PLANES) { // On ATI's GL3 drivers we have to disable gl_ClipDistance because it's hopelessly broken. // This will cause some glitches and regressions but is the only way to avoid total display garbage. @@ -274,7 +256,7 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char * texcoordmatrix_index = glGetUniformLocation(hShader, "uQuadTexCoords"); quadmode_index = glGetUniformLocation(hShader, "uQuadMode"); - if (LM_SOFTWARE != gl.lightmethod && !(gl.flags & RFL_SHADER_STORAGE_BUFFER)) + if (!gl.legacyMode && !(gl.flags & RFL_SHADER_STORAGE_BUFFER)) { int tempindex = glGetUniformBlockIndex(hShader, "LightBufferUBO"); if (tempindex != -1) glUniformBlockBinding(hShader, tempindex, LIGHTBUF_BINDINGPOINT); @@ -425,7 +407,7 @@ static const FEffectShader effectshaders[]= FShaderManager::FShaderManager() { - if (gl.glslversion > 0) CompileShaders(); + if (!gl.legacyMode) CompileShaders(); } //========================================================================== @@ -436,7 +418,7 @@ FShaderManager::FShaderManager() FShaderManager::~FShaderManager() { - if (gl.glslversion > 0) Clean(); + if (!gl.legacyMode) Clean(); } //========================================================================== @@ -578,7 +560,7 @@ EXTERN_CVAR(Int, gl_fuzztype) void FShaderManager::ApplyMatrices(VSMatrix *proj, VSMatrix *view) { - if (gl.glslversion == 0) + if (gl.legacyMode) { glMatrixMode(GL_PROJECTION); glLoadMatrixf(proj->get()); diff --git a/src/gl/shaders/gl_shaderprogram.cpp b/src/gl/shaders/gl_shaderprogram.cpp index 959315a9d..80a7ea99e 100644 --- a/src/gl/shaders/gl_shaderprogram.cpp +++ b/src/gl/shaders/gl_shaderprogram.cpp @@ -240,24 +240,13 @@ FString FShaderProgram::PatchShader(ShaderType type, const FString &code, const if (defines) patchedCode << defines; - if (gl.glslversion >= 1.3) - { - // these settings are actually pointless but there seem to be some old ATI drivers that fail to compile the shader without setting the precision here. - patchedCode << "precision highp int;\n"; - patchedCode << "precision highp float;\n"; - } + // these settings are actually pointless but there seem to be some old ATI drivers that fail to compile the shader without setting the precision here. + patchedCode << "precision highp int;\n"; + patchedCode << "precision highp float;\n"; patchedCode << "#line 1\n"; patchedCode << code; - if (gl.glslversion < 1.3) - { - if (type == Vertex) - PatchVertShader(patchedCode); - else if (type == Fragment) - PatchFragShader(patchedCode); - } - return patchedCode; } @@ -268,36 +257,3 @@ FString FShaderProgram::PatchShader(ShaderType type, const FString &code, const // //========================================================================== -void FShaderProgram::PatchCommon(FString &code) -{ - code.Substitute("precision highp int;", ""); - code.Substitute("precision highp float;", ""); -} - -void FShaderProgram::PatchVertShader(FString &code) -{ - PatchCommon(code); - code.Substitute("in vec", "attribute vec"); - code.Substitute("in float", "attribute float"); - code.Substitute("out vec", "varying vec"); - code.Substitute("out float", "varying float"); - code.Substitute("gl_ClipDistance", "//"); -} - -void FShaderProgram::PatchFragShader(FString &code) -{ - PatchCommon(code); - code.Substitute("out vec4 FragColor;", ""); - code.Substitute("FragColor", "gl_FragColor"); - code.Substitute("in vec", "varying vec"); - // this patches the switch statement to if's. - code.Substitute("break;", ""); - code.Substitute("switch (uFixedColormap)", "int i = uFixedColormap;"); - code.Substitute("case 0:", "if (i == 0)"); - code.Substitute("case 1:", "else if (i == 1)"); - code.Substitute("case 2:", "else if (i == 2)"); - code.Substitute("case 3:", "else if (i == 3)"); - code.Substitute("case 4:", "else if (i == 4)"); - code.Substitute("case 5:", "else if (i == 5)"); - code.Substitute("texture(", "texture2D("); -} diff --git a/src/gl/shaders/gl_shaderprogram.h b/src/gl/shaders/gl_shaderprogram.h index 64a36db49..aabfb1f6f 100644 --- a/src/gl/shaders/gl_shaderprogram.h +++ b/src/gl/shaders/gl_shaderprogram.h @@ -26,16 +26,11 @@ public: operator GLuint() const { return mProgram; } explicit operator bool() const { return mProgram != 0; } - // Needed by FShader - static void PatchVertShader(FString &code); - static void PatchFragShader(FString &code); - private: FShaderProgram(const FShaderProgram &) = delete; FShaderProgram &operator=(const FShaderProgram &) = delete; static FString PatchShader(ShaderType type, const FString &code, const char *defines, int maxGlslVersion); - static void PatchCommon(FString &code); void CreateShader(ShaderType type); FString GetShaderInfoLog(GLuint handle); diff --git a/src/gl/system/gl_framebuffer.cpp b/src/gl/system/gl_framebuffer.cpp index ae1fabaed..158d7f333 100644 --- a/src/gl/system/gl_framebuffer.cpp +++ b/src/gl/system/gl_framebuffer.cpp @@ -162,7 +162,7 @@ void OpenGLFrameBuffer::InitializeState() glEnable(GL_BLEND); glEnable(GL_DEPTH_CLAMP); glDisable(GL_DEPTH_TEST); - if (gl.glslversion == 0) glEnable(GL_TEXTURE_2D); + if (gl.legacyMode) glEnable(GL_TEXTURE_2D); glDisable(GL_LINE_SMOOTH); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); @@ -179,9 +179,6 @@ void OpenGLFrameBuffer::InitializeState() // //========================================================================== -// Testing only for now. -CVAR(Bool, gl_draw_sync, true, 0) //false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) - void OpenGLFrameBuffer::Update() { if (!CanUpdate()) @@ -197,10 +194,7 @@ void OpenGLFrameBuffer::Update() GLRenderer->SetOutputViewport(nullptr); - if (gl_draw_sync || !swapped) - { - Swap(); - } + Swap(); swapped = false; Unlock(); CheckBench(); diff --git a/src/gl/system/gl_interface.cpp b/src/gl/system/gl_interface.cpp index c54d96448..9185b63dc 100644 --- a/src/gl/system/gl_interface.cpp +++ b/src/gl/system/gl_interface.cpp @@ -154,10 +154,10 @@ void gl_LoadExtensions() else Printf("Emulating OpenGL v %s\n", version); } - gl.version = strtod(version, NULL) + 0.01f; + float gl_version = (float)strtod(version, NULL) + 0.01f; - // Don't even start if it's lower than 2.0 or no framebuffers are available - if ((gl.version < 2.0 || !CheckExtension("GL_EXT_framebuffer_object")) && gl.version < 3.0) + // Don't even start if it's lower than 2.0 or no framebuffers are available (The framebuffer extension is needed for glGenerateMipmapsEXT!) + if ((gl_version < 2.0f || !CheckExtension("GL_EXT_framebuffer_object")) && gl_version < 3.0f) { I_FatalError("Unsupported OpenGL version.\nAt least OpenGL 2.0 with framebuffer support is required to run " GAMENAME ".\n"); } @@ -166,105 +166,86 @@ void gl_LoadExtensions() gl.glslversion = strtod((char*)glGetString(GL_SHADING_LANGUAGE_VERSION), NULL) + 0.01f; gl.vendorstring = (char*)glGetString(GL_VENDOR); - gl.lightmethod = LM_SOFTWARE; - gl.buffermethod = BM_CLIENTARRAY; - if ((gl.version >= 3.3f || CheckExtension("GL_ARB_sampler_objects")) && !Args->CheckParm("-nosampler")) + // first test for optional features + if (CheckExtension("GL_ARB_texture_compression")) gl.flags |= RFL_TEXTURE_COMPRESSION; + if (CheckExtension("GL_EXT_texture_compression_s3tc")) gl.flags |= RFL_TEXTURE_COMPRESSION_S3TC; + + if ((gl_version >= 3.3f || CheckExtension("GL_ARB_sampler_objects")) && !Args->CheckParm("-nosampler")) { gl.flags |= RFL_SAMPLER_OBJECTS; } - // Buffer lighting is only feasible with GLSL 1.3 and higher, even if 1.2 supports the extension. - if (gl.version > 3.0f && (gl.version >= 3.3f || CheckExtension("GL_ARB_uniform_buffer_object"))) + // The minimum requirement for the modern render path are GL 3.0 + uniform buffers + if (gl_version < 3.0f || (gl_version < 3.1f && !CheckExtension("GL_ARB_uniform_buffer_object"))) { - gl.lightmethod = LM_DEFERRED; - gl.buffermethod = BM_DEFERRED; - } - - if (CheckExtension("GL_ARB_texture_compression")) gl.flags |= RFL_TEXTURE_COMPRESSION; - if (CheckExtension("GL_EXT_texture_compression_s3tc")) gl.flags |= RFL_TEXTURE_COMPRESSION_S3TC; - - if (Args->CheckParm("-noshader")/* || gl.glslversion < 1.2f*/) - { - gl.version = 2.11f; + gl.legacyMode = true; + gl.lightmethod = LM_LEGACY; + gl.buffermethod = BM_LEGACY; gl.glslversion = 0; - gl.lightmethod = LM_SOFTWARE; gl.flags |= RFL_NO_CLIP_PLANES; } - else if (gl.version < 3.0f) - { - if (CheckExtension("GL_NV_GPU_shader4") || CheckExtension("GL_EXT_GPU_shader4")) gl.glslversion = 1.21f; // for pre-3.0 drivers that support capable hardware. Needed for Apple. - else - { - gl.buffermethod = BM_CLIENTARRAY; - gl.glslversion = 0; - } - - if (!CheckExtension("GL_EXT_packed_float")) gl.flags |= RFL_NO_RGBA16F; - if (!CheckExtension("GL_EXT_packed_depth_stencil")) gl.flags |= RFL_NO_DEPTHSTENCIL; - gl.flags |= RFL_NO_CLIP_PLANES; - } - else if (gl.version < 4.f) - { -#ifdef _WIN32 - if (strstr(gl.vendorstring, "ATI Tech")) - { - gl.flags |= RFL_NO_CLIP_PLANES; // gl_ClipDistance is horribly broken on ATI GL3 drivers for Windows. - } -#endif - } - else if (gl.version < 4.5f) - { - // don't use GL 4.x features when running in GL 3 emulation mode. - if (CheckExtension("GL_ARB_buffer_storage")) - { - // work around a problem with older AMD drivers: Their implementation of shader storage buffer objects is piss-poor and does not match uniform buffers even closely. - // Recent drivers, GL 4.4 don't have this problem, these can easily be recognized by also supporting the GL_ARB_buffer_storage extension. - if (CheckExtension("GL_ARB_shader_storage_buffer_object")) - { - // Shader storage buffer objects are broken on current Intel drivers. - if (strstr(gl.vendorstring, "Intel") == NULL) - { - gl.flags |= RFL_SHADER_STORAGE_BUFFER; - } - } - gl.flags |= RFL_BUFFER_STORAGE; - gl.lightmethod = LM_DIRECT; - gl.buffermethod = BM_PERSISTENT; - } - else - { - gl.version = 3.3f; - } - } else { - // Assume that everything works without problems on GL 4.5 drivers where these things are core features. - gl.flags |= RFL_SHADER_STORAGE_BUFFER | RFL_BUFFER_STORAGE; - gl.lightmethod = LM_DIRECT; - gl.buffermethod = BM_PERSISTENT; - } + gl.legacyMode = false; + gl.lightmethod = LM_DEFERRED; + gl.buffermethod = BM_DEFERRED; + if (gl_version < 4.f) + { +#ifdef _WIN32 + if (strstr(gl.vendorstring, "ATI Tech")) + { + gl.flags |= RFL_NO_CLIP_PLANES; // gl_ClipDistance is horribly broken on ATI GL3 drivers for Windows. + } +#endif + } + else if (gl_version < 4.5f) + { + // don't use GL 4.x features when running a GL 3.x context. + if (CheckExtension("GL_ARB_buffer_storage")) + { + // work around a problem with older AMD drivers: Their implementation of shader storage buffer objects is piss-poor and does not match uniform buffers even closely. + // Recent drivers, GL 4.4 don't have this problem, these can easily be recognized by also supporting the GL_ARB_buffer_storage extension. + if (CheckExtension("GL_ARB_shader_storage_buffer_object")) + { + // Shader storage buffer objects are broken on current Intel drivers. + if (strstr(gl.vendorstring, "Intel") == NULL) + { + gl.flags |= RFL_SHADER_STORAGE_BUFFER; + } + } + gl.flags |= RFL_BUFFER_STORAGE; + gl.lightmethod = LM_DIRECT; + gl.buffermethod = BM_PERSISTENT; + } + } + else + { + // Assume that everything works without problems on GL 4.5 drivers where these things are core features. + gl.flags |= RFL_SHADER_STORAGE_BUFFER | RFL_BUFFER_STORAGE; + gl.lightmethod = LM_DIRECT; + gl.buffermethod = BM_PERSISTENT; + } - if (gl.version >= 4.3f || CheckExtension("GL_ARB_invalidate_subdata")) gl.flags |= RFL_INVALIDATE_BUFFER; - if (gl.version >= 4.3f || CheckExtension("GL_KHR_debug")) gl.flags |= RFL_DEBUG; + if (gl_version >= 4.3f || CheckExtension("GL_ARB_invalidate_subdata")) gl.flags |= RFL_INVALIDATE_BUFFER; + if (gl_version >= 4.3f || CheckExtension("GL_KHR_debug")) gl.flags |= RFL_DEBUG; - const char *lm = Args->CheckValue("-lightmethod"); - if (lm != NULL) - { - if (!stricmp(lm, "deferred") && gl.lightmethod == LM_DIRECT) gl.lightmethod = LM_DEFERRED; - if (!stricmp(lm, "textured")) gl.lightmethod = LM_SOFTWARE; - } + const char *lm = Args->CheckValue("-lightmethod"); + if (lm != NULL) + { + if (!stricmp(lm, "deferred") && gl.lightmethod == LM_DIRECT) gl.lightmethod = LM_DEFERRED; + } - lm = Args->CheckValue("-buffermethod"); - if (lm != NULL) - { - if (!stricmp(lm, "deferred") && gl.buffermethod == BM_PERSISTENT) gl.buffermethod = BM_DEFERRED; - if (!stricmp(lm, "clientarray")) gl.buffermethod = BM_CLIENTARRAY; + lm = Args->CheckValue("-buffermethod"); + if (lm != NULL) + { + if (!stricmp(lm, "deferred") && gl.buffermethod == BM_PERSISTENT) gl.buffermethod = BM_DEFERRED; + } } int v; - if (gl.lightmethod != LM_SOFTWARE && !(gl.flags & RFL_SHADER_STORAGE_BUFFER)) + if (!gl.legacyMode && !(gl.flags & RFL_SHADER_STORAGE_BUFFER)) { glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, &v); gl.maxuniforms = v; @@ -284,24 +265,27 @@ void gl_LoadExtensions() glGetIntegerv(GL_MAX_TEXTURE_SIZE, &gl.max_texturesize); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - // fudge a bit with the framebuffer stuff to avoid redundancies in the main code. Some of the older cards do not have the ARB stuff but the calls are nearly identical. - FUDGE_FUNC(glGenerateMipmap, EXT); - FUDGE_FUNC(glGenFramebuffers, EXT); - FUDGE_FUNC(glBindFramebuffer, EXT); - FUDGE_FUNC(glDeleteFramebuffers, EXT); - FUDGE_FUNC(glFramebufferTexture2D, EXT); - FUDGE_FUNC(glGenerateMipmap, EXT); - FUDGE_FUNC(glGenFramebuffers, EXT); - FUDGE_FUNC(glBindFramebuffer, EXT); - FUDGE_FUNC(glDeleteFramebuffers, EXT); - FUDGE_FUNC(glFramebufferTexture2D, EXT); - FUDGE_FUNC(glFramebufferRenderbuffer, EXT); - FUDGE_FUNC(glGenRenderbuffers, EXT); - FUDGE_FUNC(glDeleteRenderbuffers, EXT); - FUDGE_FUNC(glRenderbufferStorage, EXT); - FUDGE_FUNC(glBindRenderbuffer, EXT); - FUDGE_FUNC(glCheckFramebufferStatus, EXT); - gl_PatchMenu(); + if (gl.legacyMode) + { + // fudge a bit with the framebuffer stuff to avoid redundancies in the main code. Some of the older cards do not have the ARB stuff but the calls are nearly identical. + FUDGE_FUNC(glGenerateMipmap, EXT); + FUDGE_FUNC(glGenFramebuffers, EXT); + FUDGE_FUNC(glBindFramebuffer, EXT); + FUDGE_FUNC(glDeleteFramebuffers, EXT); + FUDGE_FUNC(glFramebufferTexture2D, EXT); + FUDGE_FUNC(glGenerateMipmap, EXT); + FUDGE_FUNC(glGenFramebuffers, EXT); + FUDGE_FUNC(glBindFramebuffer, EXT); + FUDGE_FUNC(glDeleteFramebuffers, EXT); + FUDGE_FUNC(glFramebufferTexture2D, EXT); + FUDGE_FUNC(glFramebufferRenderbuffer, EXT); + FUDGE_FUNC(glGenRenderbuffers, EXT); + FUDGE_FUNC(glDeleteRenderbuffers, EXT); + FUDGE_FUNC(glRenderbufferStorage, EXT); + FUDGE_FUNC(glBindRenderbuffer, EXT); + FUDGE_FUNC(glCheckFramebufferStatus, EXT); + gl_PatchMenu(); + } } //========================================================================== @@ -313,7 +297,7 @@ void gl_LoadExtensions() void gl_PrintStartupLog() { int v = 0; - if (gl.version >= 3.2) glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &v); + if (!gl.legacyMode) glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &v); Printf ("GL_VENDOR: %s\n", glGetString(GL_VENDOR)); Printf ("GL_RENDERER: %s\n", glGetString(GL_RENDERER)); @@ -332,7 +316,7 @@ void gl_PrintStartupLog() glGetIntegerv(GL_MAX_VARYING_FLOATS, &v); Printf ("Max. varying: %d\n", v); - if (gl.lightmethod != LM_SOFTWARE && !(gl.flags & RFL_SHADER_STORAGE_BUFFER)) + if (!gl.legacyMode && !(gl.flags & RFL_SHADER_STORAGE_BUFFER)) { glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &v); Printf ("Max. uniform block size: %d\n", v); @@ -349,7 +333,7 @@ void gl_PrintStartupLog() } // For shader-less, the special alphatexture translation must be changed to actually set the alpha, because it won't get translated by a shader. - if (gl.glslversion == 0) + if (gl.legacyMode) { FRemapTable *remap = translationtables[TRANSLATION_Standard][8]; for (int i = 0; i < 256; i++) diff --git a/src/gl/system/gl_interface.h b/src/gl/system/gl_interface.h index 8300b9973..edaec58c0 100644 --- a/src/gl/system/gl_interface.h +++ b/src/gl/system/gl_interface.h @@ -21,12 +21,10 @@ enum RenderFlags RFL_BUFFER_STORAGE = 8, RFL_SAMPLER_OBJECTS = 16, - RFL_NO_RGBA16F = 32, - RFL_NO_DEPTHSTENCIL = 64, - RFL_NO_CLIP_PLANES = 128, + RFL_NO_CLIP_PLANES = 32, - RFL_INVALIDATE_BUFFER = 256, - RFL_DEBUG = 512 + RFL_INVALIDATE_BUFFER = 64, + RFL_DEBUG = 128 }; enum TexMode @@ -43,15 +41,15 @@ enum TexMode enum ELightMethod { - LM_SOFTWARE = 0, // multi-pass texturing + LM_LEGACY = 0, // placeholder for legacy mode (textured lights), should not be checked anywhere in the code! LM_DEFERRED = 1, // calculate lights up front in a separate pass LM_DIRECT = 2, // calculate lights on the fly along with the render data }; enum EBufferMethod { - BM_CLIENTARRAY = 0, // use a client array instead of a hardware buffer - BM_DEFERRED = 1, // use a temporarily mapped buffer (only necessary on GL 3.x core profile, i.e. Apple) + BM_LEGACY = 0, // placeholder for legacy mode (client arrays), should not be checked anywhere in the code! + BM_DEFERRED = 1, // use a temporarily mapped buffer, for GL 3.x core profile BM_PERSISTENT = 2 // use a persistently mapped buffer }; @@ -64,10 +62,10 @@ struct RenderContext unsigned int uniformblockalignment; int lightmethod; int buffermethod; - float version; float glslversion; int max_texturesize; char * vendorstring; + bool legacyMode; int MaxLights() const { diff --git a/src/gl/textures/gl_hqresize.cpp b/src/gl/textures/gl_hqresize.cpp index 785f3c6e9..0af793e58 100644 --- a/src/gl/textures/gl_hqresize.cpp +++ b/src/gl/textures/gl_hqresize.cpp @@ -264,7 +264,7 @@ unsigned char *gl_CreateUpsampledTextureBuffer ( const FTexture *inputTexture, u return inputBuffer; // [BB] Don't upsample non-shader handled warped textures. Needs too much memory and time - if (gl.glslversion == 0 && inputTexture->bWarped) + if (gl.legacyMode && inputTexture->bWarped) return inputBuffer; // already scaled? diff --git a/src/gl/textures/gl_material.cpp b/src/gl/textures/gl_material.cpp index 6ba1fe4b0..bc9dc2f52 100644 --- a/src/gl/textures/gl_material.cpp +++ b/src/gl/textures/gl_material.cpp @@ -296,7 +296,7 @@ const FHardwareTexture *FGLTexture::Bind(int texunit, int clampmode, int transla if (translation <= 0) translation = -translation; else { - alphatrans = (gl.glslversion == 0 && translation == TRANSLATION(TRANSLATION_Standard, 8)); + alphatrans = (gl.legacyMode && translation == TRANSLATION(TRANSLATION_Standard, 8)); translation = GLTranslationPalette::GetInternalTranslation(translation); } @@ -307,7 +307,7 @@ const FHardwareTexture *FGLTexture::Bind(int texunit, int clampmode, int transla if (hwtex) { // Texture has become invalid - if ((!tex->bHasCanvas && (!tex->bWarped || gl.glslversion == 0)) && tex->CheckModified()) + if ((!tex->bHasCanvas && (!tex->bWarped || gl.legacyMode)) && tex->CheckModified()) { Clean(true); hwtex = CreateHwTexture(); @@ -325,7 +325,7 @@ const FHardwareTexture *FGLTexture::Bind(int texunit, int clampmode, int transla if (!tex->bHasCanvas) { buffer = CreateTexBuffer(translation, w, h, hirescheck, true, alphatrans); - if (tex->bWarped && gl.glslversion == 0 && w*h <= 256*256) // do not software-warp larger textures, especially on the old systems that still need this fallback. + if (tex->bWarped && gl.legacyMode && w*h <= 256*256) // do not software-warp larger textures, especially on the old systems that still need this fallback. { // need to do software warping FWarpTexture *wt = static_cast(tex); @@ -489,7 +489,7 @@ FMaterial::FMaterial(FTexture * tx, bool expanded) mSpriteU[0] = mSpriteV[0] = 0.f; mSpriteU[1] = mSpriteV[1] = 1.f; - FTexture *basetex = (tx->bWarped && gl.glslversion == 0)? tx : tx->GetRedirect(false); + FTexture *basetex = (tx->bWarped && gl.legacyMode)? tx : tx->GetRedirect(false); // allow the redirect only if the textute is not expanded or the scale matches. if (!expanded || (tx->Scale.X == basetex->Scale.X && tx->Scale.Y == basetex->Scale.Y)) { diff --git a/src/posix/cocoa/i_common.h b/src/posix/cocoa/i_common.h index 4a558cf24..9cedb0262 100644 --- a/src/posix/cocoa/i_common.h +++ b/src/posix/cocoa/i_common.h @@ -190,6 +190,9 @@ typedef NSInteger NSApplicationActivationPolicy; static const NSWindowCollectionBehavior NSWindowCollectionBehaviorFullScreenAuxiliary = NSWindowCollectionBehavior(1 << 8); +static const NSOpenGLPixelFormatAttribute NSOpenGLPFAOpenGLProfile(96); +static const NSOpenGLPixelFormatAttribute NSOpenGLProfileVersion3_2Core(0x3200); + #endif // prior to 10.7 #endif // COCOA_I_COMMON_INCLUDED diff --git a/src/posix/cocoa/i_video.mm b/src/posix/cocoa/i_video.mm index e2b59449d..f455a5f9f 100644 --- a/src/posix/cocoa/i_video.mm +++ b/src/posix/cocoa/i_video.mm @@ -233,7 +233,7 @@ namespace class CocoaVideo : public IVideo { public: - explicit CocoaVideo(int multisample); + CocoaVideo(); virtual EDisplayType GetDisplayType() { return DISPLAY_Both; } virtual void SetWindowedScale(float scale); @@ -465,7 +465,7 @@ CocoaWindow* CreateCocoaWindow(const NSUInteger styleMask) // --------------------------------------------------------------------------- -CocoaVideo::CocoaVideo(const int multisample) +CocoaVideo::CocoaVideo() : m_window(CreateCocoaWindow(STYLE_MASK_WINDOWED)) , m_width(-1) , m_height(-1) @@ -492,13 +492,10 @@ CocoaVideo::CocoaVideo(const int multisample) attributes[i++] = NSOpenGLPFAAllowOfflineRenderers; } - if (multisample) + if (NSAppKitVersionNumber >= AppKit10_7) { - attributes[i++] = NSOpenGLPFAMultisample; - attributes[i++] = NSOpenGLPFASampleBuffers; - attributes[i++] = NSOpenGLPixelFormatAttribute(1); - attributes[i++] = NSOpenGLPFASamples; - attributes[i++] = NSOpenGLPixelFormatAttribute(multisample); + attributes[i++] = NSOpenGLPFAOpenGLProfile; + attributes[i++] = NSOpenGLProfileVersion3_2Core; } attributes[i] = NSOpenGLPixelFormatAttribute(0); @@ -1254,7 +1251,7 @@ void I_InitGraphics() val.Bool = !!Args->CheckParm("-devparm"); ticker.SetGenericRepDefault(val, CVAR_Bool); - Video = new CocoaVideo(0); + Video = new CocoaVideo; atterm(I_ShutdownGraphics); } diff --git a/src/win32/win32gliface.cpp b/src/win32/win32gliface.cpp index 494d94233..7ca001e1e 100644 --- a/src/win32/win32gliface.cpp +++ b/src/win32/win32gliface.cpp @@ -748,11 +748,9 @@ bool Win32GLVideo::InitHardware (HWND Window, int multisample) } int prof = WGL_CONTEXT_CORE_PROFILE_BIT_ARB; - const char *lm = Args->CheckValue("-buffermethod"); - if (lm != NULL) - { - if (!stricmp(lm, "clientarray")) prof = WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; - } + const char *version = Args->CheckValue("-glversion"); + + if (version != nullptr && strcmp(version, "3.0") < 0) prof = WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; for (; prof <= WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; prof++) { diff --git a/wadsrc/static/shaders/glsl/colormap.fp b/wadsrc/static/shaders/glsl/colormap.fp new file mode 100644 index 000000000..e86429c37 --- /dev/null +++ b/wadsrc/static/shaders/glsl/colormap.fp @@ -0,0 +1,16 @@ + +in vec2 TexCoord; +out vec4 FragColor; + +uniform sampler2D tex; +uniform vec4 uFixedColormapStart; +uniform vec4 uFixedColormapRange; + +void main() +{ + vec4 frag = texture(tex, TexCoord); + float gray = (frag.r * 0.3 + frag.g * 0.56 + frag.b * 0.14); + vec4 cm = uFixedColormapStart + gray * uFixedColormapRange; + FragColor = vec4(clamp(cm.rgb, 0.0, 1.0), frag.a); +} + diff --git a/wadsrc/static/shaders/glsl/main.fp b/wadsrc/static/shaders/glsl/main.fp index 2a783e00c..84b7f5742 100644 --- a/wadsrc/static/shaders/glsl/main.fp +++ b/wadsrc/static/shaders/glsl/main.fp @@ -133,32 +133,6 @@ vec4 desaturate(vec4 texel) // //=========================================================================== -#ifdef GLSL12_COMPATIBLE -vec4 getTexel(vec2 st) -{ - vec4 texel = texture(tex, st); - - // - // Apply texture modes - // - if (uTextureMode != 0) - { - if (uTextureMode == 1) texel.rgb = vec3(1.0,1.0,1.0); - else if (uTextureMode == 2) texel.a = 1.0; - else if (uTextureMode == 3) texel = vec4(1.0-texel.r, 1.0-texel.b, 1.0-texel.g, texel.a); - else if (uTextureMode == 4) texel = vec4(1.0, 1.0, 1.0, texel.r*texel.a); - else if (uTextureMode == 5) - { - if (st.t < 0.0 || st.t > 1.0) - { - texel.a = 0.0; - } - } - } - texel *= uObjectColor; - return desaturate(texel); -} -#else vec4 getTexel(vec2 st) { vec4 texel = texture(tex, st); @@ -195,7 +169,6 @@ vec4 getTexel(vec2 st) return desaturate(texel); } -#endif //=========================================================================== // diff --git a/wadsrc/static/shaders/glsl/tonemap.fp b/wadsrc/static/shaders/glsl/tonemap.fp index 5a84ca5a4..c33349a38 100644 --- a/wadsrc/static/shaders/glsl/tonemap.fp +++ b/wadsrc/static/shaders/glsl/tonemap.fp @@ -70,17 +70,10 @@ uniform sampler2D PaletteLUT; vec3 Tonemap(vec3 color) { ivec3 c = ivec3(clamp(color.rgb, vec3(0.0), vec3(1.0)) * 255.0 + 0.5); -#if __VERSION__ < 130 - int index = (c.r / 4 * 64 + c.g / 4) * 64 + c.b / 4; - float tx = mod(index, 512) / 512.0; - float ty = float(index / 512) / 512.0; - return texture2D(PaletteLUT, vec2(tx, ty)).rgb; -#else int index = ((c.r >> 2) * 64 + (c.g >> 2)) * 64 + (c.b >> 2); int tx = index % 512; int ty = index / 512; return texelFetch(PaletteLUT, ivec2(tx, ty), 0).rgb; -#endif } #else