From 5e39890118c650fb2161b79f824890ac70402d5f Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 11 Aug 2018 18:25:15 +0200 Subject: [PATCH] - use a uniform buffer for per-scene data like rotation matrices. --- src/CMakeLists.txt | 1 + src/gl/data/gl_viewpointbuffer.cpp | 173 +++++++++++++++++++++++++++ src/gl/data/gl_viewpointbuffer.h | 35 ++++++ src/gl/renderer/gl_renderer.cpp | 35 ++---- src/gl/renderer/gl_renderer.h | 34 +++--- src/gl/scene/gl_drawinfo.cpp | 1 + src/gl/scene/gl_drawinfo.h | 1 + src/gl/scene/gl_portal.cpp | 8 +- src/gl/scene/gl_scene.cpp | 25 ++-- src/gl/scene/gl_skydome.cpp | 1 - src/gl/shaders/gl_shader.cpp | 109 ++++------------- src/gl/shaders/gl_shader.h | 15 --- src/hwrenderer/data/shaderuniforms.h | 3 +- wadsrc/static/shaders/glsl/main.vp | 4 + 14 files changed, 278 insertions(+), 167 deletions(-) create mode 100644 src/gl/data/gl_viewpointbuffer.cpp create mode 100644 src/gl/data/gl_viewpointbuffer.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 110c20fc3..30a98487b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1044,6 +1044,7 @@ set (PCH_SOURCES g_statusbar/shared_sbar.cpp gl/data/gl_vertexbuffer.cpp gl/data/gl_uniformbuffer.cpp + gl/data/gl_viewpointbuffer.cpp gl/dynlights/gl_lightbuffer.cpp gl/dynlights/gl_shadowmap.cpp gl/models/gl_models.cpp diff --git a/src/gl/data/gl_viewpointbuffer.cpp b/src/gl/data/gl_viewpointbuffer.cpp new file mode 100644 index 000000000..7b9039bf3 --- /dev/null +++ b/src/gl/data/gl_viewpointbuffer.cpp @@ -0,0 +1,173 @@ +// +//--------------------------------------------------------------------------- +// +// Copyright(C) 2018 Christoph Oelckers +// All rights reserved. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see http://www.gnu.org/licenses/ +// +//-------------------------------------------------------------------------- +// +/* +** gl_viewpointbuffer.cpp +** Buffer data maintenance for per viewpoint uniform data +** +**/ + +#include "gl_load/gl_system.h" +#include "gl_load/gl_interface.h" +#include "hwrenderer/data/shaderuniforms.h" +#include "hwrenderer/scene/hw_viewpointuniforms.h" +#include "gl_viewpointbuffer.h" + +static const int INITIAL_BUFFER_SIZE = 100; // 100 viewpoints per frame should nearly always be enough + +GLViewpointBuffer::GLViewpointBuffer() +{ + mBufferSize = INITIAL_BUFFER_SIZE; + mBlockAlign = ((sizeof(HWViewpointUniforms) / gl.uniformblockalignment) + 1) * gl.uniformblockalignment; + mByteSize = mBufferSize * mBlockAlign; + Allocate(); + Clear(); + mLastMappedIndex = UINT_MAX; +} + +GLViewpointBuffer::~GLViewpointBuffer() +{ + glBindBuffer(GL_UNIFORM_BUFFER, 0); + glDeleteBuffers(1, &mBufferId); +} + +void GLViewpointBuffer::Allocate() +{ + glGenBuffers(1, &mBufferId); + glBindBufferBase(GL_UNIFORM_BUFFER, VIEWPOINT_BINDINGPOINT, mBufferId); + glBindBuffer(GL_UNIFORM_BUFFER, mBufferId); // Note: Some older AMD drivers don't do that in glBindBufferBase, as they should. + if (gl.flags & RFL_BUFFER_STORAGE) + { + glBufferStorage(GL_UNIFORM_BUFFER, mByteSize, NULL, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT); + mBufferPointer = glMapBufferRange(GL_UNIFORM_BUFFER, 0, mByteSize, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT); + } + else + { + glBufferData(GL_UNIFORM_BUFFER, mByteSize, NULL, GL_STATIC_DRAW); + mBufferPointer = NULL; + } +} + +void GLViewpointBuffer::CheckSize() +{ + if (mUploadIndex >= mBufferSize) + { + // reallocate the buffer with twice the size + unsigned int oldbuffer = mBufferId; + + mBufferSize *= 2; + mByteSize *= 2; + + // first unmap the old buffer + glBindBuffer(GL_UNIFORM_BUFFER, mBufferId); + glUnmapBuffer(GL_UNIFORM_BUFFER); + + Allocate(); + glBindBuffer(GL_COPY_READ_BUFFER, oldbuffer); + + // copy contents and delete the old buffer. + glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_UNIFORM_BUFFER, 0, 0, mByteSize / 2); // old size is half of the current one. + glBindBuffer(GL_COPY_READ_BUFFER, 0); + glDeleteBuffers(1, &oldbuffer); + } +} + +void GLViewpointBuffer::Map() +{ + if (!(gl.flags & RFL_BUFFER_STORAGE)) + { + glBindBuffer(GL_UNIFORM_BUFFER, mBufferId); + mBufferPointer = (float*)glMapBufferRange(GL_UNIFORM_BUFFER, 0, mByteSize, GL_MAP_WRITE_BIT); + } +} + +void GLViewpointBuffer::Unmap() +{ + if (!(gl.flags & RFL_BUFFER_STORAGE)) + { + glBindBuffer(GL_UNIFORM_BUFFER, mBufferId); + glUnmapBuffer(GL_UNIFORM_BUFFER); + mBufferPointer = nullptr; + } + else + { + glMemoryBarrier(GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT); + } +} + +int GLViewpointBuffer::Bind(unsigned int index) +{ + if (index != mLastMappedIndex) + { + mLastMappedIndex = index; + glBindBufferRange(GL_UNIFORM_BUFFER, VIEWPOINT_BINDINGPOINT, mBufferId, index * mBlockAlign, mBlockAlign); + + // Update the viewpoint-related clip plane setting. + auto *vp = (HWViewpointUniforms*)(((char*)mBufferPointer) + mUploadIndex * mBlockAlign); + if (!(gl.flags & RFL_NO_CLIP_PLANES)) + { + if (index > 0 && (vp->mClipHeightDirection != 0.f || vp->mClipLine.X > -10000000.0f)) + { + glEnable(GL_CLIP_DISTANCE0); + } + else + { + glDisable(GL_CLIP_DISTANCE0); + } + } + } + return index; +} + +void GLViewpointBuffer::Set2D(int width, int height) +{ + if (width != m2DWidth || height != m2DHeight) + { + HWViewpointUniforms matrices; + matrices.SetDefaults(); + matrices.mProjectionMatrix.ortho(0, width, height, 0, -1.0f, 1.0f); + matrices.CalcDependencies(); + Map(); + memcpy(mBufferPointer, &matrices, sizeof(matrices)); + Unmap(); + m2DWidth = width; + m2DHeight = height; + mLastMappedIndex = -1; + } + Bind(0); +} + +int GLViewpointBuffer::SetViewpoint(HWViewpointUniforms *vp) +{ + CheckSize(); + Map(); + memcpy(((char*)mBufferPointer) + mUploadIndex * mBlockAlign, vp, sizeof(*vp)); + Unmap(); + + return Bind(mUploadIndex++); +} + +void GLViewpointBuffer::Clear() +{ + // Index 0 is reserved for the 2D projection. + mUploadIndex = 1; +} + diff --git a/src/gl/data/gl_viewpointbuffer.h b/src/gl/data/gl_viewpointbuffer.h new file mode 100644 index 000000000..208a42a5d --- /dev/null +++ b/src/gl/data/gl_viewpointbuffer.h @@ -0,0 +1,35 @@ + +#include "tarray.h" + +struct HWViewpointUniforms; + +class GLViewpointBuffer +{ + unsigned int mBufferId; + unsigned int mBufferSize; + unsigned int mBlockAlign; + unsigned int mUploadIndex; + unsigned int mLastMappedIndex; + unsigned int mByteSize; + void * mBufferPointer; + + unsigned int m2DWidth = ~0u, m2DHeight = ~0u; + + unsigned int mBlockSize; + + void CheckSize(); + void Allocate(); + +public: + + GLViewpointBuffer(); + ~GLViewpointBuffer(); + void Clear(); + void Map(); + void Unmap(); + int Bind(unsigned int index); + void Set2D(int width, int height); + int SetViewpoint(HWViewpointUniforms *vp); + unsigned int GetBlockSize() const { return mBlockSize; } +}; + diff --git a/src/gl/renderer/gl_renderer.cpp b/src/gl/renderer/gl_renderer.cpp index a27effd06..0bcdf7db6 100644 --- a/src/gl/renderer/gl_renderer.cpp +++ b/src/gl/renderer/gl_renderer.cpp @@ -57,6 +57,7 @@ #include "gl/shaders/gl_postprocessshaderinstance.h" #include "gl/textures/gl_samplers.h" #include "gl/dynlights/gl_lightbuffer.h" +#include "gl/data/gl_viewpointbuffer.h" #include "r_videoscale.h" EXTERN_CVAR(Int, screenblocks) @@ -79,21 +80,6 @@ extern bool NoInterpolateView; FGLRenderer::FGLRenderer(OpenGLFrameBuffer *fb) { framebuffer = fb; - mMirrorCount = 0; - mPlaneMirrorCount = 0; - mVBO = nullptr; - mSkyVBO = nullptr; - mShaderManager = nullptr; - mLights = nullptr; - mBuffers = nullptr; - mScreenBuffers = nullptr; - mSaveBuffers = nullptr; - mPresentShader = nullptr; - mPresent3dCheckerShader = nullptr; - mPresent3dColumnShader = nullptr; - mPresent3dRowShader = nullptr; - mShadowMapShader = nullptr; - mCustomPostProcessShaders = nullptr; } void FGLRenderer::Initialize(int width, int height) @@ -118,6 +104,7 @@ void FGLRenderer::Initialize(int width, int height) mVBO = new FFlatVertexBuffer(width, height); mSkyVBO = new FSkyVertexBuffer; mLights = new FLightBuffer(); + mViewpoints = new GLViewpointBuffer; gl_RenderState.SetVertexBuffer(mVBO); mFBID = 0; mOldFBID = 0; @@ -132,11 +119,12 @@ FGLRenderer::~FGLRenderer() FlushModels(); AActor::DeleteAllAttachedLights(); FMaterial::FlushAll(); - if (mShaderManager != NULL) delete mShaderManager; - if (mSamplerManager != NULL) delete mSamplerManager; - if (mVBO != NULL) delete mVBO; - if (mSkyVBO != NULL) delete mSkyVBO; - if (mLights != NULL) delete mLights; + if (mShaderManager != nullptr) delete mShaderManager; + if (mSamplerManager != nullptr) delete mSamplerManager; + if (mVBO != nullptr) delete mVBO; + if (mSkyVBO != nullptr) delete mSkyVBO; + if (mLights != nullptr) delete mLights; + if (mViewpoints != nullptr) delete mViewpoints; if (mFBID != 0) glDeleteFramebuffers(1, &mFBID); if (mVAOID != 0) { @@ -427,12 +415,7 @@ void FGLRenderer::Draw2D(F2DDrawer *drawer) mBuffers->BindCurrentFB(); const auto &mScreenViewport = screen->mScreenViewport; glViewport(mScreenViewport.left, mScreenViewport.top, mScreenViewport.width, mScreenViewport.height); - - HWViewpointUniforms matrices; - matrices.SetDefaults(); - matrices.mProjectionMatrix.ortho(0, screen->GetWidth(), screen->GetHeight(), 0, -1.0f, 1.0f); - matrices.CalcDependencies(); - GLRenderer->mShaderManager->ApplyMatrices(&matrices, NORMAL_PASS); + GLRenderer->mViewpoints->Set2D(screen->GetWidth(), screen->GetHeight()); glDisable(GL_DEPTH_TEST); diff --git a/src/gl/renderer/gl_renderer.h b/src/gl/renderer/gl_renderer.h index 7551d4428..3a48a9ccb 100644 --- a/src/gl/renderer/gl_renderer.h +++ b/src/gl/renderer/gl_renderer.h @@ -35,6 +35,7 @@ class FHardwareTexture; class FShadowMapShader; class FCustomPostProcessShaders; class SWSceneDrawer; +class GLViewpointBuffer; struct FRenderViewpoint; #define NOQUEUE nullptr // just some token to be used as a placeholder @@ -51,33 +52,34 @@ class FGLRenderer public: OpenGLFrameBuffer *framebuffer; - int mMirrorCount; - int mPlaneMirrorCount; - FShaderManager *mShaderManager; - FSamplerManager *mSamplerManager; + int mMirrorCount = 0; + int mPlaneMirrorCount = 0; + FShaderManager *mShaderManager = nullptr; + FSamplerManager *mSamplerManager = nullptr; unsigned int mFBID; unsigned int mVAOID; unsigned int PortalQueryObject; int mOldFBID; - FGLRenderBuffers *mBuffers; - FGLRenderBuffers *mScreenBuffers; - FGLRenderBuffers *mSaveBuffers; - FPresentShader *mPresentShader; - FPresent3DCheckerShader *mPresent3dCheckerShader; - FPresent3DColumnShader *mPresent3dColumnShader; - FPresent3DRowShader *mPresent3dRowShader; - FShadowMapShader *mShadowMapShader; - FCustomPostProcessShaders *mCustomPostProcessShaders; + FGLRenderBuffers *mBuffers = nullptr; + FGLRenderBuffers *mScreenBuffers = nullptr; + FGLRenderBuffers *mSaveBuffers = nullptr; + FPresentShader *mPresentShader = nullptr; + FPresent3DCheckerShader *mPresent3dCheckerShader = nullptr; + FPresent3DColumnShader *mPresent3dColumnShader = nullptr; + FPresent3DRowShader *mPresent3dRowShader = nullptr; + FShadowMapShader *mShadowMapShader = nullptr; + FCustomPostProcessShaders *mCustomPostProcessShaders = nullptr; FShadowMap mShadowMap; //FRotator mAngles; - FFlatVertexBuffer *mVBO; - FSkyVertexBuffer *mSkyVBO; - FLightBuffer *mLights; + FFlatVertexBuffer *mVBO = nullptr; + FSkyVertexBuffer *mSkyVBO = nullptr; + FLightBuffer *mLights = nullptr; + GLViewpointBuffer *mViewpoints = nullptr; SWSceneDrawer *swdrawer = nullptr; FPortalSceneState mPortalState; diff --git a/src/gl/scene/gl_drawinfo.cpp b/src/gl/scene/gl_drawinfo.cpp index fbc5aa60c..7cddfdec4 100644 --- a/src/gl/scene/gl_drawinfo.cpp +++ b/src/gl/scene/gl_drawinfo.cpp @@ -213,6 +213,7 @@ void FDrawInfo::StartScene() decals[0].Clear(); decals[1].Clear(); hudsprites.Clear(); + vpIndex = 0; // Fullbright information needs to be propagated from the main view. if (outer != nullptr) FullbrightFlags = outer->FullbrightFlags; diff --git a/src/gl/scene/gl_drawinfo.h b/src/gl/scene/gl_drawinfo.h index e41e718a2..702c3981c 100644 --- a/src/gl/scene/gl_drawinfo.h +++ b/src/gl/scene/gl_drawinfo.h @@ -38,6 +38,7 @@ struct FDrawInfo : public HWDrawInfo HWDrawList drawlists[GLDL_TYPES]; TArray hudsprites; // These may just be stored by value. TArray decals[2]; // the second slot is for mirrors which get rendered in a separate pass. + int vpIndex; void ApplyVPUniforms() override; diff --git a/src/gl/scene/gl_portal.cpp b/src/gl/scene/gl_portal.cpp index 6f721a7dc..3ef4e2e3e 100644 --- a/src/gl/scene/gl_portal.cpp +++ b/src/gl/scene/gl_portal.cpp @@ -42,6 +42,7 @@ #include "gl/data/gl_vertexbuffer.h" #include "hwrenderer/scene/hw_clipper.h" #include "gl/scene/gl_portal.h" +#include "gl/data/gl_viewpointbuffer.h" //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- @@ -66,9 +67,7 @@ void GLPortal::ClearScreen(HWDrawInfo *di) { bool multi = !!glIsEnabled(GL_MULTISAMPLE); - di->VPUniforms.mViewMatrix.loadIdentity(); - di->VPUniforms.mProjectionMatrix.ortho(0, SCREENWIDTH, SCREENHEIGHT, 0, -1.0f, 1.0f); - di->ApplyVPUniforms(); + GLRenderer->mViewpoints->Set2D(SCREENWIDTH, SCREENHEIGHT); gl_RenderState.SetColor(0, 0, 0); gl_RenderState.Apply(); @@ -236,7 +235,7 @@ void GLPortal::End(HWDrawInfo *di, bool usestencil) Clocker c(PortalAll); di = static_cast(di)->EndDrawInfo(); - di->ApplyVPUniforms(); + GLRenderer->mViewpoints->Bind(static_cast(di)->vpIndex); if (usestencil) { auto &vp = di->Viewpoint; @@ -295,7 +294,6 @@ void GLPortal::End(HWDrawInfo *di, bool usestencil) // Restore the old view if (vp.camera != nullptr) vp.camera->renderflags = (vp.camera->renderflags & ~RF_MAYBEINVISIBLE) | savedvisibility; - di->SetupView(vp.Pos.X, vp.Pos.Y, vp.Pos.Z, !!(mState->MirrorFlag & 1), !!(mState->PlaneMirrorFlag & 1)); // This draws a valid z-buffer into the stencil's contents to ensure it // doesn't get overwritten by the level's geometry. diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index 4e1aa844b..8c6b5ce39 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -50,6 +50,7 @@ #include "gl/renderer/gl_renderstate.h" #include "gl/renderer/gl_renderbuffers.h" #include "gl/data/gl_vertexbuffer.h" +#include "gl/data/gl_viewpointbuffer.h" #include "hwrenderer/scene/hw_clipper.h" #include "hwrenderer/scene/hw_portal.h" #include "gl/scene/gl_drawinfo.h" @@ -76,19 +77,7 @@ EXTERN_CVAR (Bool, r_drawvoxels) void FDrawInfo::ApplyVPUniforms() { VPUniforms.CalcDependencies(); - GLRenderer->mShaderManager->ApplyMatrices(&VPUniforms, gl_RenderState.GetPassType()); - - if (!(gl.flags & RFL_NO_CLIP_PLANES)) - { - if (VPUniforms.mClipHeightDirection != 0.f || VPUniforms.mClipLine.X > -10000000.0f) - { - glEnable(GL_CLIP_DISTANCE0); - } - else - { - glDisable(GL_CLIP_DISTANCE0); - } - } + vpIndex = GLRenderer->mViewpoints->SetViewpoint(&VPUniforms); } @@ -337,7 +326,7 @@ void FDrawInfo::DrawScene(int drawmode) GLRenderer->mBuffers->BindSceneFB(true); gl_RenderState.EnableDrawBuffers(gl_RenderState.GetPassDrawBufferCount()); gl_RenderState.Apply(); - ApplyVPUniforms(); + GLRenderer->mViewpoints->Bind(vpIndex); } // Handle all portals after rendering the opaque objects but before @@ -383,9 +372,10 @@ void FDrawInfo::DrawEndScene2D(sector_t * viewsector) const bool renderHUDModel = IsHUDModelForPlayerAvailable(players[consoleplayer].camera->player); auto vrmode = VRMode::GetVRMode(true); - VPUniforms.mViewMatrix.loadIdentity(); - VPUniforms.mProjectionMatrix = vrmode->GetHUDSpriteProjection(); - ApplyVPUniforms(); + HWViewpointUniforms vp = VPUniforms; + vp.mViewMatrix.loadIdentity(); + vp.mProjectionMatrix = vrmode->GetHUDSpriteProjection(); + GLRenderer->mViewpoints->SetViewpoint(&vp); glDisable(GL_DEPTH_TEST); glDisable(GL_MULTISAMPLE); @@ -459,6 +449,7 @@ sector_t * FGLRenderer::RenderViewpoint (FRenderViewpoint &mainvp, AActor * came // Render (potentially) multiple views for stereo 3d // Fixme. The view offsetting should be done with a static table and not require setup of the entire render state for the mode. auto vrmode = VRMode::GetVRMode(mainview && toscreen); + mViewpoints->Clear(); for (int eye_ix = 0; eye_ix < vrmode->mEyeCount; ++eye_ix) { const auto &eye = vrmode->mEyes[eye_ix]; diff --git a/src/gl/scene/gl_skydome.cpp b/src/gl/scene/gl_skydome.cpp index 9feaad5b0..afc4d16dd 100644 --- a/src/gl/scene/gl_skydome.cpp +++ b/src/gl/scene/gl_skydome.cpp @@ -269,7 +269,6 @@ void GLSkyPortal::DrawContents(HWDrawInfo *di) } } gl_RenderState.SetVertexBuffer(GLRenderer->mVBO); - di->ApplyVPUniforms(); ::level.lightmode = oldlightmode; gl_RenderState.SetDepthClamp(oldClamp); } diff --git a/src/gl/shaders/gl_shader.cpp b/src/gl/shaders/gl_shader.cpp index 5f3fae934..e0d656038 100644 --- a/src/gl/shaders/gl_shader.cpp +++ b/src/gl/shaders/gl_shader.cpp @@ -49,18 +49,30 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char * static char buffer[10000]; FString error; - FString i_data; - - // 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. - i_data += "precision highp int;\n"; - i_data += "precision highp float;\n"; + FString i_data = R"( + // 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. + precision highp int; + precision highp float; - i_data += "uniform vec4 uCameraPos;\n"; + // This must match the HWViewpointUniforms struct + layout(std140) uniform ViewpointUBO { + mat4 ProjectionMatrix; + mat4 ViewMatrix; + mat4 NormalViewMatrix; + + vec4 uCameraPos; + vec4 uClipLine; + + float uGlobVis; // uGlobVis = R_GetGlobVis(r_visibility) / 32.0 + int uPalLightLevels; + int uViewHeight; // Software fuzz scaling + float uClipHeight; + float uClipHeightDirection; + }; + )"; + i_data += "uniform int uTextureMode;\n"; - i_data += "uniform float uClipHeight;\n"; - i_data += "uniform float uClipHeightDirection;\n"; i_data += "uniform vec2 uClipSplit;\n"; - i_data += "uniform vec4 uClipLine;\n"; i_data += "uniform float uAlphaThreshold;\n"; // colors @@ -87,15 +99,10 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char * i_data += "#define uLightFactor uLightAttr.g\n"; i_data += "#define uLightDist uLightAttr.r\n"; i_data += "uniform int uFogEnabled;\n"; - i_data += "uniform int uPalLightLevels;\n"; - i_data += "uniform float uGlobVis;\n"; // uGlobVis = R_GetGlobVis(r_visibility) / 32.0 // dynamic lights i_data += "uniform int uLightIndex;\n"; - // Software fuzz scaling - i_data += "uniform int uViewHeight;\n"; - // Blinn glossiness and specular level i_data += "uniform vec2 uSpecularMaterial;\n"; @@ -107,10 +114,7 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char * i_data += "#endif\n"; // matrices - i_data += "uniform mat4 ProjectionMatrix;\n"; - i_data += "uniform mat4 ViewMatrix;\n"; i_data += "uniform mat4 ModelMatrix;\n"; - i_data += "uniform mat4 NormalViewMatrix;\n"; i_data += "uniform mat4 NormalModelMatrix;\n"; i_data += "uniform mat4 TextureMatrix;\n"; @@ -348,28 +352,20 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char * lights_index = glGetUniformLocation(hShader, "lights"); fakevb_index = glGetUniformLocation(hShader, "fakeVB"); - projectionmatrix_index = glGetUniformLocation(hShader, "ProjectionMatrix"); - viewmatrix_index = glGetUniformLocation(hShader, "ViewMatrix"); modelmatrix_index = glGetUniformLocation(hShader, "ModelMatrix"); texturematrix_index = glGetUniformLocation(hShader, "TextureMatrix"); vertexmatrix_index = glGetUniformLocation(hShader, "uQuadVertices"); texcoordmatrix_index = glGetUniformLocation(hShader, "uQuadTexCoords"); - normalviewmatrix_index = glGetUniformLocation(hShader, "NormalViewMatrix"); normalmodelmatrix_index = glGetUniformLocation(hShader, "NormalModelMatrix"); quadmode_index = glGetUniformLocation(hShader, "uQuadMode"); - viewheight_index = glGetUniformLocation(hShader, "uViewHeight"); - camerapos_index = glGetUniformLocation(hShader, "uCameraPos"); - pallightlevels_index = glGetUniformLocation(hShader, "uPalLightLevels"); - globvis_index = glGetUniformLocation(hShader, "uGlobVis"); - clipheight_index = glGetUniformLocation(hShader, "uClipHeight"); - clipheightdirection_index = glGetUniformLocation(hShader, "uClipHeightDirection"); - clipline_index = glGetUniformLocation(hShader, "uClipLine"); if (lightbuffertype == GL_UNIFORM_BUFFER) { int tempindex = glGetUniformBlockIndex(hShader, "LightBufferUBO"); if (tempindex != -1) glUniformBlockBinding(hShader, tempindex, LIGHTBUF_BINDINGPOINT); } + int tempindex = glGetUniformBlockIndex(hShader, "ViewpointUBO"); + if (tempindex != -1) glUniformBlockBinding(hShader, tempindex, VIEWPOINT_BINDINGPOINT); glUseProgram(hShader); if (quadmode_index > 0) glUniform1i(quadmode_index, 0); @@ -448,27 +444,6 @@ FShader *FShaderCollection::Compile (const char *ShaderName, const char *ShaderP return shader; } -//========================================================================== -// -// -// -//========================================================================== - -void FShader::ApplyMatrices(HWViewpointUniforms *u) -{ - Bind(); - glUniformMatrix4fv(projectionmatrix_index, 1, false, u->mProjectionMatrix.get()); - glUniformMatrix4fv(viewmatrix_index, 1, false, u->mViewMatrix.get()); - glUniformMatrix4fv(normalviewmatrix_index, 1, false, u->mNormalViewMatrix.get()); - - glUniform4fv(camerapos_index, 1, &u->mCameraPos[0]); - glUniform1i(viewheight_index, u->mViewHeight); - glUniform1i(pallightlevels_index, u->mPalLightLevels); - glUniform1f(globvis_index, u->mGlobVis); - glUniform1f(clipheight_index, u->mClipHeight); - glUniform1f(clipheightdirection_index, u->mClipHeightDirection); -} - //========================================================================== // // @@ -566,15 +541,6 @@ FShader *FShaderManager::Get(unsigned int eff, bool alphateston, EPassType passT return nullptr; } -void FShaderManager::ApplyMatrices(HWViewpointUniforms *u, EPassType passType) -{ - if (passType < mPassShaders.Size()) - mPassShaders[passType]->ApplyMatrices(u); - - if (mActiveShader) - mActiveShader->Bind(); -} - //========================================================================== // // @@ -706,35 +672,6 @@ FShader *FShaderCollection::BindEffect(int effect) } -//========================================================================== -// -// -// -//========================================================================== -EXTERN_CVAR(Int, gl_fuzztype) - -void FShaderCollection::ApplyMatrices(HWViewpointUniforms *u) -{ - for (int i = 0; i < SHADER_NoTexture; i++) - { - mMaterialShaders[i]->ApplyMatrices(u); - mMaterialShadersNAT[i]->ApplyMatrices(u); - } - mMaterialShaders[SHADER_NoTexture]->ApplyMatrices(u); - if (gl_fuzztype != 0) - { - mMaterialShaders[SHADER_NoTexture + gl_fuzztype]->ApplyMatrices(u); - } - for (unsigned i = FIRST_USER_SHADER; i < mMaterialShaders.Size(); i++) - { - mMaterialShaders[i]->ApplyMatrices(u); - } - for (int i = 0; i < MAX_EFFECTS; i++) - { - mEffectShaders[i]->ApplyMatrices(u); - } -} - //========================================================================== // // diff --git a/src/gl/shaders/gl_shader.h b/src/gl/shaders/gl_shader.h index cb63b502d..46ba3c793 100644 --- a/src/gl/shaders/gl_shader.h +++ b/src/gl/shaders/gl_shader.h @@ -267,16 +267,6 @@ class FShader int normalmodelmatrix_index; int texturematrix_index; - int projectionmatrix_index; - int viewmatrix_index; - int normalviewmatrix_index; - int viewheight_index; - int camerapos_index; - int pallightlevels_index; - int globvis_index; - int clipheight_index; - int clipheightdirection_index; - int clipline_index; public: int vertexmatrix_index; @@ -308,9 +298,6 @@ public: bool Bind(); unsigned int GetHandle() const { return hShader; } - - void ApplyMatrices(HWViewpointUniforms *u); - }; //========================================================================== @@ -329,7 +316,6 @@ public: FShader *BindEffect(int effect, EPassType passType); FShader *Get(unsigned int eff, bool alphateston, EPassType passType); - void ApplyMatrices(HWViewpointUniforms *u, EPassType passType); private: FShader *mActiveShader = nullptr; @@ -351,7 +337,6 @@ public: FShader *Compile(const char *ShaderName, const char *ShaderPath, const char *LightModePath, const char *shaderdefines, bool usediscard, EPassType passType); int Find(const char *mame); FShader *BindEffect(int effect); - void ApplyMatrices(HWViewpointUniforms *u); FShader *Get(unsigned int eff, bool alphateston) { diff --git a/src/hwrenderer/data/shaderuniforms.h b/src/hwrenderer/data/shaderuniforms.h index 9400fa0a5..4ec9c2393 100644 --- a/src/hwrenderer/data/shaderuniforms.h +++ b/src/hwrenderer/data/shaderuniforms.h @@ -7,7 +7,8 @@ enum { LIGHTBUF_BINDINGPOINT = 1, - POSTPROCESS_BINDINGPOINT = 2 + POSTPROCESS_BINDINGPOINT = 2, + VIEWPOINT_BINDINGPOINT = 3 }; enum class UniformType diff --git a/wadsrc/static/shaders/glsl/main.vp b/wadsrc/static/shaders/glsl/main.vp index 1089cadcb..e25438c02 100644 --- a/wadsrc/static/shaders/glsl/main.vp +++ b/wadsrc/static/shaders/glsl/main.vp @@ -87,6 +87,10 @@ void main() { gl_ClipDistance[0] = -( (worldcoord.z - uClipLine.y) * uClipLine.z + (uClipLine.x - worldcoord.x) * uClipLine.w ) + 1.0/32768.0; // allow a tiny bit of imprecisions for colinear linedefs. } + else + { + gl_ClipDistance[0] = 1; + } // clip planes used for translucency splitting gl_ClipDistance[1] = worldcoord.y - uClipSplit.x;