diff --git a/src/g_shared/sbarinfo_commands.cpp b/src/g_shared/sbarinfo_commands.cpp index 13c98d8339..d105ab8180 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/data/gl_matrix.cpp b/src/gl/data/gl_matrix.cpp index d8017ad404..1158828571 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 4e76b51cb3..d14599eb8c 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 596de35d9d..f777118fd4 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/dynlights/a_dynlight.cpp b/src/gl/dynlights/a_dynlight.cpp index 20d0d60782..0e52eedd8a 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.); } diff --git a/src/gl/models/gl_models.cpp b/src/gl/models/gl_models.cpp index 91bd9131e7..f3dfbd569d 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 6213eb0068..288b1a9db6 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_postprocess.cpp b/src/gl/renderer/gl_postprocess.cpp index d06b948503..fde8da3533 100644 --- a/src/gl/renderer/gl_postprocess.cpp +++ b/src/gl/renderer/gl_postprocess.cpp @@ -579,7 +579,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; diff --git a/src/gl/renderer/gl_renderer.cpp b/src/gl/renderer/gl_renderer.cpp index 5fa2de29d2..2895341cc8 100644 --- a/src/gl/renderer/gl_renderer.cpp +++ b/src/gl/renderer/gl_renderer.cpp @@ -117,12 +117,12 @@ FGLRenderer::FGLRenderer(OpenGLFrameBuffer *fb) mTonemapPalette = nullptr; mColormapShader = nullptr; mLensShader = nullptr; - mFXAAShader = nullptr; - mFXAALumaShader = nullptr; mLinearDepthShader = nullptr; mDepthBlurShader = nullptr; mSSAOShader = nullptr; mSSAOCombineShader = nullptr; + mFXAAShader = nullptr; + mFXAALumaShader = nullptr; } void gl_LoadModels(); @@ -201,11 +201,11 @@ FGLRenderer::~FGLRenderer() } if (mBuffers) delete mBuffers; if (mPresentShader) delete mPresentShader; - if (mPresent3dRowShader) delete mPresent3dRowShader; if (mLinearDepthShader) delete mLinearDepthShader; if (mDepthBlurShader) delete mDepthBlurShader; if (mSSAOShader) delete mSSAOShader; if (mSSAOCombineShader) delete mSSAOCombineShader; + if (mPresent3dRowShader) delete mPresent3dRowShader; if (mBloomExtractShader) delete mBloomExtractShader; if (mBloomCombineShader) delete mBloomCombineShader; if (mExposureExtractShader) delete mExposureExtractShader; diff --git a/src/gl/renderer/gl_renderstate.cpp b/src/gl/renderer/gl_renderstate.cpp index 2cfd739e90..cfaaea3cc0 100644 --- a/src/gl/renderer/gl_renderstate.cpp +++ b/src/gl/renderer/gl_renderstate.cpp @@ -142,6 +142,7 @@ bool FRenderState::ApplyShader() } glVertexAttrib4fv(VATTR_COLOR, mColor.vec); + glVertexAttrib4fv(VATTR_NORMAL, mNormal.vec); activeShader->muDesaturation.Set(mDesaturation / 255.f); activeShader->muFogEnabled.Set(fogset); @@ -271,12 +272,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 7bec51be04..3276502f12 100644 --- a/src/gl/renderer/gl_renderstate.h +++ b/src/gl/renderer/gl_renderstate.h @@ -97,6 +97,7 @@ class FRenderState float mShaderTimer; FVertexBuffer *mVertexBuffer, *mCurrentVertexBuffer; + FStateVec4 mNormal; FStateVec4 mColor; FStateVec4 mCameraPos; FStateVec4 mGlowTop, mGlowBottom; @@ -128,6 +129,8 @@ public: VSMatrix mViewMatrix; VSMatrix mModelMatrix; VSMatrix mTextureMatrix; + VSMatrix mNormalViewMatrix; + VSMatrix mNormalModelMatrix; FRenderState() { @@ -189,6 +192,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 90f3be66fc..394ca16265 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 f0c9677ba4..02fd9b452b 100644 --- a/src/gl/scene/gl_portal.cpp +++ b/src/gl/scene/gl_portal.cpp @@ -1219,7 +1219,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) @@ -1232,7 +1232,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 1653d2bb84..015b420163 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 19753f742e..ab88f2f9c7 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 32dc6ee5b1..143029ba74 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 3a7baec332..db16a941af 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 a7884b51a6..dbc43fd22b 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 26a449bf22..9368a268cb 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"); glBindFragDataLocation(hShader, 0, "FragColor"); glBindFragDataLocation(hShader, 1, "FragData"); @@ -245,6 +246,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)) @@ -333,14 +336,14 @@ FShader *FShaderCollection::Compile (const char *ShaderName, const char *ShaderP // //========================================================================== -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()); } - //========================================================================== // // @@ -602,23 +605,26 @@ EXTERN_CVAR(Int, gl_fuzztype) void FShaderCollection::ApplyMatrices(VSMatrix *proj, VSMatrix *view) { + 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); } } diff --git a/src/gl/shaders/gl_shader.h b/src/gl/shaders/gl_shader.h index 793fa63dd1..934674cbeb 100644 --- a/src/gl/shaders/gl_shader.h +++ b/src/gl/shaders/gl_shader.h @@ -287,7 +287,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; @@ -320,7 +322,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/src/gl/stereo3d/gl_interleaved3d.cpp b/src/gl/stereo3d/gl_interleaved3d.cpp index 329dec9530..036a84b0b8 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 diff --git a/src/vectors.h b/src/vectors.h index 00a65df507..1852609f2a 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 diff --git a/wadsrc/static/language.enu b/wadsrc/static/language.enu index f29c9301c7..89b38329cf 100644 --- a/wadsrc/static/language.enu +++ b/wadsrc/static/language.enu @@ -2638,9 +2638,9 @@ GLPREFMNU_MULTISAMPLE = "Multisample"; GLPREFMNU_TONEMAP = "Tonemap Mode"; GLPREFMNU_BLOOM = "Bloom effect"; GLPREFMNU_LENS = "Lens distortion effect"; -GLPREFMNU_FXAA = "FXAA Quality"; GLPREFMNU_SSAO = "Ambient occlusion quality"; GLPREFMNU_SSAO_PORTALS = "Portals with AO"; +GLPREFMNU_FXAA = "FXAA Quality"; // Option Values OPTVAL_SMART = "Smart"; diff --git a/wadsrc/static/menudef.zz b/wadsrc/static/menudef.zz index df01762691..6eb56be948 100644 --- a/wadsrc/static/menudef.zz +++ b/wadsrc/static/menudef.zz @@ -49,6 +49,14 @@ OptionValue "TonemapModes" 5, "$OPTVAL_PALETTE" } +OptionValue "SSAOModes" +{ + 0, "$OPTVAL_OFF" + 1, "$OPTVAL_LOW" + 2, "$OPTVAL_MEDIUM" + 3, "$OPTVAL_HIGH" +} + OptionValue "FXAAQuality" { 0, "$OPTVAL_OFF" @@ -58,14 +66,6 @@ OptionValue "FXAAQuality" 4, "$OPTVAL_EXTREME" } -OptionValue "SSAOModes" -{ - 0, "$OPTVAL_OFF" - 1, "$OPTVAL_LOW" - 2, "$OPTVAL_MEDIUM" - 3, "$OPTVAL_HIGH" -} - OptionValue "TextureFormats" { 0, "$OPTVAL_RGBA8" @@ -253,7 +253,7 @@ OptionMenu "GLPrefOptions" Option "$GLPREFMNU_TONEMAP", gl_tonemap, "TonemapModes" Option "$GLPREFMNU_BLOOM", gl_bloom, "OnOff" Option "$GLPREFMNU_LENS", gl_lens, "OnOff" - Option "$GLPREFMNU_FXAA", gl_fxaa, "FXAAQuality" Option "$GLPREFMNU_SSAO", gl_ssao, "SSAOModes" Slider "$GLPREFMNU_SSAO_PORTALS", gl_ssao_portals, 0.0, 4.0, 1.0, 0 + Option "$GLPREFMNU_FXAA", gl_fxaa, "FXAAQuality" } diff --git a/wadsrc/static/shaders/glsl/main.fp b/wadsrc/static/shaders/glsl/main.fp index cdd6ffe3f0..374edb59c0 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; @@ -206,6 +208,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 @@ -291,7 +324,7 @@ vec4 getLightColor(float fogdist, float fogfactor) { vec4 lightpos = lights[i]; vec4 lightcolor = lights[i+1]; - + lightcolor.rgb *= pointLightAttenuation(lightpos); dynlight.rgb -= lightcolor.rgb; } diff --git a/wadsrc/static/shaders/glsl/main.vp b/wadsrc/static/shaders/glsl/main.vp index 27faafb86e..0baca31f92 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 0f0545b2d9..81edd7b046 100644 --- a/wadsrc/static/shaders/glsl/shaderdefs.i +++ b/wadsrc/static/shaders/glsl/shaderdefs.i @@ -57,5 +57,7 @@ uniform int uQuadMode; uniform mat4 ProjectionMatrix; uniform mat4 ViewMatrix; uniform mat4 ModelMatrix; +uniform mat4 NormalViewMatrix; +uniform mat4 NormalModelMatrix; uniform mat4 TextureMatrix;