From 7c4780638201122f6ad8024c5edcce26b6759767 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Mon, 3 Oct 2016 09:18:47 +0200 Subject: [PATCH 1/5] Fix aspect ratio bug in LensDistortScene --- src/gl/renderer/gl_postprocess.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gl/renderer/gl_postprocess.cpp b/src/gl/renderer/gl_postprocess.cpp index 6c18edd1e..ff65fee6d 100644 --- a/src/gl/renderer/gl_postprocess.cpp +++ b/src/gl/renderer/gl_postprocess.cpp @@ -569,7 +569,7 @@ void FGLRenderer::LensDistortScene() 0.0f }; - float aspect = mSceneViewport.width / mSceneViewport.height; + float aspect = mSceneViewport.width / (float)mSceneViewport.height; // Scale factor to keep sampling within the input texture float r2 = aspect * aspect * 0.25 + 0.25f; From 41ab08ee4716b5e2e7da10bf52b4ce5c3ed49321 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 3 Oct 2016 11:00:26 +0200 Subject: [PATCH 2/5] - fixed: TVector::Resized needs to consider that the input vector has a length of 0. In this case just performing the normal calculations results in an invalid vector. --- src/vectors.h | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/vectors.h b/src/vectors.h index 00a65df50..1852609f2 100644 --- a/src/vectors.h +++ b/src/vectors.h @@ -556,17 +556,29 @@ struct TVector3 // Resizes this vector to be the specified length (if it is not 0) TVector3 &MakeResize(double len) { - double scale = len / Length(); - X = vec_t(X * scale); - Y = vec_t(Y * scale); - Z = vec_t(Z * scale); + double vlen = Length(); + if (vlen != 0.) + { + double scale = len / vlen; + X = vec_t(X * scale); + Y = vec_t(Y * scale); + Z = vec_t(Z * scale); + } return *this; } TVector3 Resized(double len) { - double scale = len / Length(); - return{ vec_t(X * scale), vec_t(Y * scale), vec_t(Z * scale) }; + double vlen = Length(); + if (vlen != 0.) + { + double scale = len / vlen; + return{ vec_t(X * scale), vec_t(Y * scale), vec_t(Z * scale) }; + } + else + { + return *this; + } } // Dot product From 4eb5f10b02cc2b1844f0a6894f3a7005049d767a Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 3 Oct 2016 16:09:32 +0200 Subject: [PATCH 3/5] - use normals to have proper light attenuation. So far only implemented for walls and flats. Models are planned but need some thinking about how to efficiently collect all required lights for an object. --- src/gl/data/gl_matrix.cpp | 2 +- src/gl/data/gl_vertexbuffer.cpp | 2 ++ src/gl/data/gl_vertexbuffer.h | 9 +++++- src/gl/models/gl_models.cpp | 2 ++ src/gl/models/gl_voxels.cpp | 2 ++ src/gl/renderer/gl_renderstate.cpp | 5 ++++ src/gl/renderer/gl_renderstate.h | 13 +++++++++ src/gl/scene/gl_flats.cpp | 10 +++++-- src/gl/scene/gl_portal.cpp | 4 +-- src/gl/scene/gl_skydome.cpp | 1 + src/gl/scene/gl_sprite.cpp | 1 + src/gl/scene/gl_wall.h | 9 ++++++ src/gl/scene/gl_walls.cpp | 4 +-- src/gl/scene/gl_walls_draw.cpp | 8 ++--- src/gl/shaders/gl_shader.cpp | 22 +++++++++----- src/gl/shaders/gl_shader.h | 4 ++- wadsrc/static/shaders/glsl/main.fp | 39 +++++++++++++++++++++++-- wadsrc/static/shaders/glsl/main.vp | 7 +++++ wadsrc/static/shaders/glsl/shaderdefs.i | 2 ++ 19 files changed, 122 insertions(+), 24 deletions(-) diff --git a/src/gl/data/gl_matrix.cpp b/src/gl/data/gl_matrix.cpp index d8017ad40..115882857 100644 --- a/src/gl/data/gl_matrix.cpp +++ b/src/gl/data/gl_matrix.cpp @@ -442,7 +442,7 @@ VSMatrix::computeNormalMatrix(const FLOATTYPE *aMatrix) mMat3x3[1] * (mMat3x3[5] * mMat3x3[6] - mMat3x3[8] * mMat3x3[3]) + mMat3x3[2] * (mMat3x3[3] * mMat3x3[7] - mMat3x3[4] * mMat3x3[6]); - invDet = 1.0f/det; + invDet = 1.0/det; mMatrix[0] = (mMat3x3[4] * mMat3x3[8] - mMat3x3[5] * mMat3x3[7]) * invDet; mMatrix[1] = (mMat3x3[5] * mMat3x3[6] - mMat3x3[8] * mMat3x3[3]) * invDet; diff --git a/src/gl/data/gl_vertexbuffer.cpp b/src/gl/data/gl_vertexbuffer.cpp index 4e76b51cb..d14599eb8 100644 --- a/src/gl/data/gl_vertexbuffer.cpp +++ b/src/gl/data/gl_vertexbuffer.cpp @@ -71,6 +71,7 @@ void FSimpleVertexBuffer::BindVBO() glEnableVertexAttribArray(VATTR_TEXCOORD); glEnableVertexAttribArray(VATTR_COLOR); glDisableVertexAttribArray(VATTR_VERTEX2); + glDisableVertexAttribArray(VATTR_NORMAL); } else { @@ -236,6 +237,7 @@ void FFlatVertexBuffer::BindVBO() glEnableVertexAttribArray(VATTR_TEXCOORD); glDisableVertexAttribArray(VATTR_COLOR); glDisableVertexAttribArray(VATTR_VERTEX2); + glDisableVertexAttribArray(VATTR_NORMAL); } else { diff --git a/src/gl/data/gl_vertexbuffer.h b/src/gl/data/gl_vertexbuffer.h index 596de35d9..f777118fd 100644 --- a/src/gl/data/gl_vertexbuffer.h +++ b/src/gl/data/gl_vertexbuffer.h @@ -271,6 +271,7 @@ struct FModelVertex { float x, y, z; // world position float u, v; // texture coordinates + unsigned packedNormal; // normal vector as GL_INT_2_10_10_10_REV. void Set(float xx, float yy, float zz, float uu, float vv) { @@ -283,7 +284,13 @@ struct FModelVertex void SetNormal(float nx, float ny, float nz) { - // GZDoom currently doesn't use normals. This function is so that the high level code can pretend it does. + /* + int inx = int(nx * 512); + int iny = int(ny * 512); + int inz = int(nz * 512); + packedNormal = 0x40000000 | ((inx & 1023) << 20) | ((iny & 1023) << 10) | (inz & 1023); + */ + packedNormal = 0; // Per-pixel lighting for models isn't implemented yet so leave this at 0 for now. } }; diff --git a/src/gl/models/gl_models.cpp b/src/gl/models/gl_models.cpp index 91bd9131e..f3dfbd569 100644 --- a/src/gl/models/gl_models.cpp +++ b/src/gl/models/gl_models.cpp @@ -119,6 +119,7 @@ void FModelVertexBuffer::BindVBO() glEnableVertexAttribArray(VATTR_VERTEX); glEnableVertexAttribArray(VATTR_TEXCOORD); glEnableVertexAttribArray(VATTR_VERTEX2); + glEnableVertexAttribArray(VATTR_NORMAL); glDisableVertexAttribArray(VATTR_COLOR); } else @@ -245,6 +246,7 @@ unsigned int FModelVertexBuffer::SetupFrame(unsigned int frame1, unsigned int fr glVertexAttribPointer(VATTR_VERTEX, 3, GL_FLOAT, false, sizeof(FModelVertex), &VMO[frame1].x); glVertexAttribPointer(VATTR_TEXCOORD, 2, GL_FLOAT, false, sizeof(FModelVertex), &VMO[frame1].u); glVertexAttribPointer(VATTR_VERTEX2, 3, GL_FLOAT, false, sizeof(FModelVertex), &VMO[frame2].x); + glVertexAttribPointer(VATTR_NORMAL, 4, GL_UNSIGNED_INT_2_10_10_10_REV, false, sizeof(FModelVertex), &VMO[frame2].packedNormal); } else { diff --git a/src/gl/models/gl_voxels.cpp b/src/gl/models/gl_voxels.cpp index 6213eb006..288b1a9db 100644 --- a/src/gl/models/gl_voxels.cpp +++ b/src/gl/models/gl_voxels.cpp @@ -248,6 +248,7 @@ void FVoxelModel::AddFace(int x1, int y1, int z1, int x2, int y2, int z2, int x3 FModelVertex vert; unsigned int indx[4]; + vert.packedNormal = 0; // currently this is not being used for voxels. vert.u = (((col & 15) * 255 / 16) + 7) / 255.f; vert.v = (((col / 16) * 255 / 16) + 7) / 255.f; @@ -271,6 +272,7 @@ void FVoxelModel::AddFace(int x1, int y1, int z1, int x2, int y2, int z2, int x3 vert.y = -z3 + PivotZ; indx[3] = AddVertex(vert, check); + mIndices.Push(indx[0]); mIndices.Push(indx[1]); mIndices.Push(indx[3]); diff --git a/src/gl/renderer/gl_renderstate.cpp b/src/gl/renderer/gl_renderstate.cpp index 967296cb8..a8c9c5da2 100644 --- a/src/gl/renderer/gl_renderstate.cpp +++ b/src/gl/renderer/gl_renderstate.cpp @@ -141,6 +141,7 @@ bool FRenderState::ApplyShader() } glVertexAttrib4fv(VATTR_COLOR, mColor.vec); + glVertexAttrib4fv(VATTR_NORMAL, mNormal.vec); activeShader->muDesaturation.Set(mDesaturation / 255.f); activeShader->muFogEnabled.Set(fogset); @@ -269,12 +270,16 @@ bool FRenderState::ApplyShader() if (mModelMatrixEnabled) { mModelMatrix.matrixToGL(activeShader->modelmatrix_index); + VSMatrix norm; + norm.computeNormalMatrix(mModelMatrix); + mNormalModelMatrix.matrixToGL(activeShader->normalmodelmatrix_index); activeShader->currentModelMatrixState = true; } else if (activeShader->currentModelMatrixState) { activeShader->currentModelMatrixState = false; identityMatrix.matrixToGL(activeShader->modelmatrix_index); + identityMatrix.matrixToGL(activeShader->normalmodelmatrix_index); } return true; } diff --git a/src/gl/renderer/gl_renderstate.h b/src/gl/renderer/gl_renderstate.h index 1c0a20348..6a1856910 100644 --- a/src/gl/renderer/gl_renderstate.h +++ b/src/gl/renderer/gl_renderstate.h @@ -90,6 +90,7 @@ class FRenderState float mShaderTimer; FVertexBuffer *mVertexBuffer, *mCurrentVertexBuffer; + FStateVec4 mNormal; FStateVec4 mColor; FStateVec4 mCameraPos; FStateVec4 mGlowTop, mGlowBottom; @@ -119,6 +120,8 @@ public: VSMatrix mViewMatrix; VSMatrix mModelMatrix; VSMatrix mTextureMatrix; + VSMatrix mNormalViewMatrix; + VSMatrix mNormalModelMatrix; FRenderState() { @@ -180,6 +183,16 @@ public: void SetClipHeight(float height, float direction); + void SetNormal(FVector3 norm) + { + mNormal.Set(norm.X, norm.Y, norm.Z, 0.f); + } + + void SetNormal(float x, float y, float z) + { + mNormal.Set(x, y, z, 0.f); + } + void SetColor(float r, float g, float b, float a = 1.f, int desat = 0) { mColor.Set(r, g, b, a); diff --git a/src/gl/scene/gl_flats.cpp b/src/gl/scene/gl_flats.cpp index 90f3be66f..394ca1626 100644 --- a/src/gl/scene/gl_flats.cpp +++ b/src/gl/scene/gl_flats.cpp @@ -374,6 +374,7 @@ void GLFlat::Draw(int pass, bool trans) // trans only has meaning for GLPASS_LIG } #endif + gl_RenderState.SetNormal(plane.plane.Normal().X, plane.plane.Normal().Z, plane.plane.Normal().Y); switch (pass) { @@ -502,6 +503,11 @@ inline void GLFlat::PutFlat(bool fog) void GLFlat::Process(sector_t * model, int whichplane, bool fog) { plane.GetFromSector(model, whichplane); + if (whichplane != int(ceiling)) + { + // Flip the normal if the source plane has a different orientation than what we are about to render. + plane.plane.FlipVert(); + } if (!fog) { @@ -641,7 +647,7 @@ void GLFlat::ProcessSector(sector_t * frontsector) Colormap.CopyFrom3DLight(light); } renderstyle = STYLE_Translucent; - Process(frontsector, false, false); + Process(frontsector, sector_t::floor, false); } } @@ -700,7 +706,7 @@ void GLFlat::ProcessSector(sector_t * frontsector) Colormap.CopyFrom3DLight(light); } renderstyle = STYLE_Translucent; - Process(frontsector, true, false); + Process(frontsector, sector_t::ceiling, false); } } diff --git a/src/gl/scene/gl_portal.cpp b/src/gl/scene/gl_portal.cpp index 4a7fa9d7a..50693d75c 100644 --- a/src/gl/scene/gl_portal.cpp +++ b/src/gl/scene/gl_portal.cpp @@ -1217,7 +1217,7 @@ void GLEEHorizonPortal::DrawContents() if (sector->GetTexture(sector_t::ceiling) != skyflatnum) { GLHorizonInfo horz; - horz.plane.GetFromSector(sector, true); + horz.plane.GetFromSector(sector, sector_t::ceiling); horz.lightlevel = gl_ClampLight(sector->GetCeilingLight()); horz.colormap = sector->ColorMap; if (portal->mType == PORTS_PLANE) @@ -1230,7 +1230,7 @@ void GLEEHorizonPortal::DrawContents() if (sector->GetTexture(sector_t::floor) != skyflatnum) { GLHorizonInfo horz; - horz.plane.GetFromSector(sector, false); + horz.plane.GetFromSector(sector, sector_t::floor); horz.lightlevel = gl_ClampLight(sector->GetFloorLight()); horz.colormap = sector->ColorMap; if (portal->mType == PORTS_PLANE) diff --git a/src/gl/scene/gl_skydome.cpp b/src/gl/scene/gl_skydome.cpp index 1653d2bb8..015b42016 100644 --- a/src/gl/scene/gl_skydome.cpp +++ b/src/gl/scene/gl_skydome.cpp @@ -114,6 +114,7 @@ void FSkyVertexBuffer::BindVBO() glEnableVertexAttribArray(VATTR_TEXCOORD); glEnableVertexAttribArray(VATTR_COLOR); glDisableVertexAttribArray(VATTR_VERTEX2); + glDisableVertexAttribArray(VATTR_NORMAL); } else { diff --git a/src/gl/scene/gl_sprite.cpp b/src/gl/scene/gl_sprite.cpp index 19753f742..ab88f2f9c 100644 --- a/src/gl/scene/gl_sprite.cpp +++ b/src/gl/scene/gl_sprite.cpp @@ -406,6 +406,7 @@ void GLSprite::Draw(int pass) gl_RenderState.Apply(); FVector3 v[4]; + gl_RenderState.SetNormal(0, 0, 0); CalculateVertices(v); FQuadDrawer qd; diff --git a/src/gl/scene/gl_wall.h b/src/gl/scene/gl_wall.h index 32dc6ee5b..143029ba7 100644 --- a/src/gl/scene/gl_wall.h +++ b/src/gl/scene/gl_wall.h @@ -60,6 +60,15 @@ struct GLSeg float x1,x2; float y1,y2; float fracleft, fracright; // fractional offset of the 2 vertices on the linedef + + FVector3 Normal() const + { + // we do not use the vector math inlines here because they are not optimized for speed but accuracy in the playsim + float x = y2 - y1; + float y = x1 - x2; + float length = sqrt(x*x + y*y); + return FVector3(x / length, 0, y / length); + } }; struct texcoord diff --git a/src/gl/scene/gl_walls.cpp b/src/gl/scene/gl_walls.cpp index 3a7baec33..db16a941a 100644 --- a/src/gl/scene/gl_walls.cpp +++ b/src/gl/scene/gl_walls.cpp @@ -470,7 +470,7 @@ bool GLWall::DoHorizon(seg_t * seg,sector_t * fs, vertex_t * v1,vertex_t * v2) } else { - hi.plane.GetFromSector(fs, true); + hi.plane.GetFromSector(fs, sector_t::ceiling); hi.lightlevel = gl_ClampLight(fs->GetCeilingLight()); hi.colormap = fs->ColorMap; @@ -498,7 +498,7 @@ bool GLWall::DoHorizon(seg_t * seg,sector_t * fs, vertex_t * v1,vertex_t * v2) } else { - hi.plane.GetFromSector(fs, false); + hi.plane.GetFromSector(fs, sector_t::floor); hi.lightlevel = gl_ClampLight(fs->GetFloorLight()); hi.colormap = fs->ColorMap; diff --git a/src/gl/scene/gl_walls_draw.cpp b/src/gl/scene/gl_walls_draw.cpp index a7884b51a..dbc43fd22 100644 --- a/src/gl/scene/gl_walls_draw.cpp +++ b/src/gl/scene/gl_walls_draw.cpp @@ -254,14 +254,13 @@ void GLWall::RenderMirrorSurface() if (GLRenderer->mirrortexture == NULL) return; // For the sphere map effect we need a normal of the mirror surface, - Vector v(glseg.y2-glseg.y1, 0 ,-glseg.x2+glseg.x1); - v.Normalize(); + FVector3 v = glseg.Normal(); 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(); - tcs[LOLFT].v = tcs[LORGT].v = tcs[UPLFT].v = tcs[UPRGT].v = v.Z(); + tcs[LOLFT].u = tcs[LORGT].u = tcs[UPLFT].u = tcs[UPRGT].u = v.X; + tcs[LOLFT].v = tcs[LORGT].v = tcs[UPLFT].v = tcs[UPRGT].v = v.Z; gl_RenderState.EnableTextureMatrix(true); gl_RenderState.mTextureMatrix.computeNormalMatrix(gl_RenderState.mViewMatrix); @@ -414,6 +413,7 @@ void GLWall::RenderTranslucentWall() //========================================================================== void GLWall::Draw(int pass) { + gl_RenderState.SetNormal(glseg.Normal()); switch (pass) { case GLPASS_LIGHTSONLY: diff --git a/src/gl/shaders/gl_shader.cpp b/src/gl/shaders/gl_shader.cpp index d4e05dfa8..8f78e22e4 100644 --- a/src/gl/shaders/gl_shader.cpp +++ b/src/gl/shaders/gl_shader.cpp @@ -179,6 +179,7 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char * glBindAttribLocation(hShader, VATTR_TEXCOORD, "aTexCoord"); glBindAttribLocation(hShader, VATTR_COLOR, "aColor"); glBindAttribLocation(hShader, VATTR_VERTEX2, "aVertex2"); + glBindAttribLocation(hShader, VATTR_NORMAL, "aNormal"); glLinkProgram(hShader); @@ -241,6 +242,8 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char * 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"); if (!gl.legacyMode && !(gl.flags & RFL_SHADER_STORAGE_BUFFER)) @@ -328,14 +331,14 @@ FShader *FShaderManager::Compile (const char *ShaderName, const char *ShaderPath // //========================================================================== -void FShader::ApplyMatrices(VSMatrix *proj, VSMatrix *view) +void FShader::ApplyMatrices(VSMatrix *proj, VSMatrix *view, VSMatrix *norm) { Bind(); glUniformMatrix4fv(projectionmatrix_index, 1, false, proj->get()); glUniformMatrix4fv(viewmatrix_index, 1, false, view->get()); + glUniformMatrix4fv(normalviewmatrix_index, 1, false, norm->get()); } - //========================================================================== // // @@ -556,23 +559,26 @@ void FShaderManager::ApplyMatrices(VSMatrix *proj, VSMatrix *view) } else { + VSMatrix norm; + norm.computeNormalMatrix(*view); + for (int i = 0; i < 4; i++) { - mTextureEffects[i]->ApplyMatrices(proj, view); - mTextureEffectsNAT[i]->ApplyMatrices(proj, view); + mTextureEffects[i]->ApplyMatrices(proj, view, &norm); + mTextureEffectsNAT[i]->ApplyMatrices(proj, view, &norm); } - mTextureEffects[4]->ApplyMatrices(proj, view); + mTextureEffects[4]->ApplyMatrices(proj, view, &norm); if (gl_fuzztype != 0) { - mTextureEffects[4 + gl_fuzztype]->ApplyMatrices(proj, view); + mTextureEffects[4 + gl_fuzztype]->ApplyMatrices(proj, view, &norm); } for (unsigned i = 12; i < mTextureEffects.Size(); i++) { - mTextureEffects[i]->ApplyMatrices(proj, view); + mTextureEffects[i]->ApplyMatrices(proj, view, &norm); } for (int i = 0; i < MAX_EFFECTS; i++) { - mEffectShaders[i]->ApplyMatrices(proj, view); + mEffectShaders[i]->ApplyMatrices(proj, view, &norm); } if (mActiveShader != NULL) mActiveShader->Bind(); } diff --git a/src/gl/shaders/gl_shader.h b/src/gl/shaders/gl_shader.h index 343942321..679ae1172 100644 --- a/src/gl/shaders/gl_shader.h +++ b/src/gl/shaders/gl_shader.h @@ -285,7 +285,9 @@ class FShader int lights_index; int projectionmatrix_index; int viewmatrix_index; + int normalviewmatrix_index; int modelmatrix_index; + int normalmodelmatrix_index; int texturematrix_index; public: int vertexmatrix_index; @@ -318,7 +320,7 @@ public: bool Bind(); unsigned int GetHandle() const { return hShader; } - void ApplyMatrices(VSMatrix *proj, VSMatrix *view); + void ApplyMatrices(VSMatrix *proj, VSMatrix *view, VSMatrix *norm); }; diff --git a/wadsrc/static/shaders/glsl/main.fp b/wadsrc/static/shaders/glsl/main.fp index 95ac874b7..fb1983fc7 100644 --- a/wadsrc/static/shaders/glsl/main.fp +++ b/wadsrc/static/shaders/glsl/main.fp @@ -1,6 +1,8 @@ in vec4 pixelpos; in vec2 glowdist; +in vec4 vWorldNormal; +in vec4 vEyeNormal; in vec4 vTexCoord; in vec4 vColor; @@ -121,6 +123,37 @@ float R_DoomLightingEquation(float light) return lightscale; } +//=========================================================================== +// +// Standard lambertian diffuse light calculation +// +//=========================================================================== + +float diffuseContribution(vec3 lightDirection, vec3 normal) +{ + return max(dot(normal, lightDirection), 0.0f); +} + +//=========================================================================== +// +// Calculates the brightness of a dynamic point light +// Todo: Find a better way to define which lighting model to use. +// (Specular mode has been removed for now.) +// +//=========================================================================== + +float pointLightAttenuation(vec4 lightpos) +{ + float attenuation = max(lightpos.w - distance(pixelpos.xyz, lightpos.xyz),0.0) / lightpos.w; + #if 0 + return attenuation; + #else + vec3 lightDirection = normalize(lightpos.xyz - pixelpos.xyz); + float diffuseAmount = diffuseContribution(lightDirection, normalize(vWorldNormal.xyz)); + return attenuation * diffuseAmount; + #endif +} + //=========================================================================== // // Calculate light @@ -196,7 +229,7 @@ vec4 getLightColor(float fogdist, float fogfactor) vec4 lightpos = lights[i]; vec4 lightcolor = lights[i+1]; - lightcolor.rgb *= max(lightpos.w - distance(pixelpos.xyz, lightpos.xyz),0.0) / lightpos.w; + lightcolor.rgb *= pointLightAttenuation(lightpos); dynlight.rgb += lightcolor.rgb; } // @@ -207,7 +240,7 @@ vec4 getLightColor(float fogdist, float fogfactor) vec4 lightpos = lights[i]; vec4 lightcolor = lights[i+1]; - lightcolor.rgb *= max(lightpos.w - distance(pixelpos.xyz, lightpos.xyz),0.0) / lightpos.w; + lightcolor.rgb *= pointLightAttenuation(lightpos); dynlight.rgb -= lightcolor.rgb; } } @@ -289,7 +322,7 @@ void main() vec4 lightpos = lights[i]; vec4 lightcolor = lights[i+1]; - lightcolor.rgb *= max(lightpos.w - distance(pixelpos.xyz, lightpos.xyz),0.0) / lightpos.w; + lightcolor.rgb *= pointLightAttenuation(lightpos); addlight.rgb += lightcolor.rgb; } frag.rgb = clamp(frag.rgb + desaturate(addlight).rgb, 0.0, 1.0); diff --git a/wadsrc/static/shaders/glsl/main.vp b/wadsrc/static/shaders/glsl/main.vp index a2c1bac5b..1de8854c0 100644 --- a/wadsrc/static/shaders/glsl/main.vp +++ b/wadsrc/static/shaders/glsl/main.vp @@ -4,8 +4,12 @@ in vec2 aTexCoord; in vec4 aColor; #ifndef SIMPLE // we do not need these for simple shaders in vec4 aVertex2; +in vec4 aNormal; out vec4 pixelpos; out vec2 glowdist; + +out vec4 vWorldNormal; +out vec4 vEyeNormal; #endif out vec4 vTexCoord; @@ -54,6 +58,9 @@ void main() gl_ClipDistance[3] = -((uSplitTopPlane.w + uSplitTopPlane.x * worldcoord.x + uSplitTopPlane.y * worldcoord.z) * uSplitTopPlane.z) - worldcoord.y; gl_ClipDistance[4] = worldcoord.y + ((uSplitBottomPlane.w + uSplitBottomPlane.x * worldcoord.x + uSplitBottomPlane.y * worldcoord.z) * uSplitBottomPlane.z); } + + vWorldNormal = NormalModelMatrix * aNormal; + vEyeNormal = NormalViewMatrix * vWorldNormal; #endif #ifdef SPHEREMAP diff --git a/wadsrc/static/shaders/glsl/shaderdefs.i b/wadsrc/static/shaders/glsl/shaderdefs.i index 3701694bc..8c5697a66 100644 --- a/wadsrc/static/shaders/glsl/shaderdefs.i +++ b/wadsrc/static/shaders/glsl/shaderdefs.i @@ -56,5 +56,7 @@ uniform int uQuadMode; uniform mat4 ProjectionMatrix; uniform mat4 ViewMatrix; uniform mat4 ModelMatrix; +uniform mat4 NormalViewMatrix; +uniform mat4 NormalModelMatrix; uniform mat4 TextureMatrix; From 7ab7fc9a57f8d329f53e9643586eb1ed958afb51 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 3 Oct 2016 16:21:50 +0200 Subject: [PATCH 4/5] - seems I missed this part... --- src/gl/dynlights/a_dynlight.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/gl/dynlights/a_dynlight.cpp b/src/gl/dynlights/a_dynlight.cpp index 20d0d6078..0e52eedd8 100644 --- a/src/gl/dynlights/a_dynlight.cpp +++ b/src/gl/dynlights/a_dynlight.cpp @@ -391,6 +391,16 @@ void ADynamicLight::UpdateLocation() Prev = target->Pos(); subsector = R_PointInSubsector(Prev); Sector = subsector->sector; + + // Some z-coordinate fudging to prevent the light from getting too close to the floor or ceiling planes. With proper attenuation this would render them invisible. + // A distance of 5 is needed so that the light's effect doesn't become too small. + if (Z() < target->floorz + 5.) SetZ(target->floorz + 5.); + else if (Z() > target->ceilingz - 5.) SetZ(target->ceilingz - 5.); + } + else + { + if (Z() < floorz + 5.) SetZ(floorz + 5.); + else if (Z() > ceilingz - 5.) SetZ(ceilingz - 5.); } From 5d99e7dafe28fbc92978c5b30ebcfed8013a4ff6 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Mon, 3 Oct 2016 22:13:33 +0300 Subject: [PATCH 5/5] Fixed compilation on platforms other than Windows --- src/g_shared/sbarinfo_commands.cpp | 4 ++-- src/gl/stereo3d/gl_interleaved3d.cpp | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/g_shared/sbarinfo_commands.cpp b/src/g_shared/sbarinfo_commands.cpp index 13c98d833..d105ab818 100644 --- a/src/g_shared/sbarinfo_commands.cpp +++ b/src/g_shared/sbarinfo_commands.cpp @@ -1187,12 +1187,12 @@ class CommandDrawNumber : public CommandDrawString if (!(cvartype == CVAR_Bool || cvartype == CVAR_Int)) { - sc.ScriptMessage("CVar '%s' is not an int or bool", cvarName); + sc.ScriptMessage("CVar '%s' is not an int or bool", cvarName.GetChars()); } } else { - sc.ScriptMessage("CVar '%s' does not exist", cvarName); + sc.ScriptMessage("CVar '%s' does not exist", cvarName.GetChars()); } if (parenthesized) sc.MustGetToken(')'); diff --git a/src/gl/stereo3d/gl_interleaved3d.cpp b/src/gl/stereo3d/gl_interleaved3d.cpp index 329dec953..036a84b0b 100644 --- a/src/gl/stereo3d/gl_interleaved3d.cpp +++ b/src/gl/stereo3d/gl_interleaved3d.cpp @@ -104,10 +104,13 @@ void RowInterleaved3D::Present() const // Compute absolute offset from top of screen to top of current display window // because we need screen-relative, not window-relative, scan line parity int windowVOffset = 0; + +#ifdef _WIN32 if (! fullscreen) { I_SaveWindowedPos(); // update win_y CVAR windowVOffset = win_y; } +#endif // _WIN32 GLRenderer->mPresent3dRowShader->VerticalPixelOffset.Set( windowVOffset // fixme: vary with window location