From 7d4895d9df907ac83803c85762f8b97beb44eb7f Mon Sep 17 00:00:00 2001 From: Kevin Caccamo Date: Sat, 22 Sep 2018 10:24:01 -0400 Subject: [PATCH 1/9] Calculate normals for OBJ models with smooth groups Add smoothGroup member to OBJFace struct, and assign the current smooth group number to it Move face normal calculation code to CalculateNormalFlat Add AddVertFaces method, which initializes and populates the vertFaces array of arrays, which holds references to triangle references per vertex Only initialize and populate vertFaces if the model has missing normals and smooth groups Assign smooth groups to triangle data Add CalculateNormalSmooth method, which calculates the normals for each face the vertex is attached to, depending on whether or not the faces are part of the given smooth group, and averages them out Add OBJTriRef struct, which holds references to triangles on OBJ surfaces Make {agg,cur}SurfFaceCount unsigned ints Change nvec to a value instead of a pointer --- src/r_data/models/models_obj.cpp | 153 ++++++++++++++++++++++++++----- src/r_data/models/models_obj.h | 21 ++++- 2 files changed, 150 insertions(+), 24 deletions(-) diff --git a/src/r_data/models/models_obj.cpp b/src/r_data/models/models_obj.cpp index 4cc5ffa17..d56d994a0 100644 --- a/src/r_data/models/models_obj.cpp +++ b/src/r_data/models/models_obj.cpp @@ -101,8 +101,9 @@ bool FOBJModel::Load(const char* fn, int lumpnum, const char* buffer, int length FTextureID curMtl = FNullTextureID(); OBJSurface *curSurface = nullptr; - int aggSurfFaceCount = 0; - int curSurfFaceCount = 0; + unsigned int aggSurfFaceCount = 0; + unsigned int curSurfFaceCount = 0; + unsigned int curSmoothGroup = 0; while(sc.GetString()) { @@ -186,9 +187,25 @@ bool FOBJModel::Load(const char* fn, int lumpnum, const char* buffer, int length sc.UnGet(); // No 4th side, move back } } + face.smoothGroup = curSmoothGroup; faces.Push(face); curSurfFaceCount += 1; } + else if (sc.Compare("s")) + { + sc.MustGetString(); + if (sc.Compare("off")) + { + curSmoothGroup = 0; + } + else + { + sc.UnGet(); + sc.MustGetNumber(); + curSmoothGroup = sc.Number; + hasSmoothGroups = hasSmoothGroups || curSmoothGroup > 0; + } + } } sc.Close(); @@ -277,11 +294,13 @@ bool FOBJModel::ParseFaceSide(const FString &sideStr, OBJFace &face, int sidx) else { side.normref = -1; + hasMissingNormals = true; } } else { side.normref = -1; + hasMissingNormals = true; } } else @@ -289,6 +308,7 @@ bool FOBJModel::ParseFaceSide(const FString &sideStr, OBJFace &face, int sidx) origIdx = atoi(sideStr.GetChars()); side.vertref = ResolveIndex(origIdx, FaceElement::VertexIndex); side.normref = -1; + hasMissingNormals = true; side.uvref = -1; } face.sides[sidx] = side; @@ -348,6 +368,11 @@ void FOBJModel::BuildVertexBuffer(FModelRenderer *renderer) surfaces[i].vbStart = vbufsize; vbufsize += surfaces[i].numTris * 3; } + // Initialize/populate vertFaces + if (hasMissingNormals && hasSmoothGroups) + { + AddVertFaces(); + } auto vbuf = renderer->CreateVertexBuffer(false,true); SetVertexBuffer(renderer, vbuf); @@ -372,39 +397,40 @@ void FOBJModel::BuildVertexBuffer(FModelRenderer *renderer) FVector3 curVvec = RealignVector(verts[vidx]); FVector2 curUvec = FixUV(uvs[uvidx]); - FVector3 *nvec = nullptr; + FVector3 nvec; mdv->Set(curVvec.X, curVvec.Y, curVvec.Z, curUvec.X, curUvec.Y); if (nidx >= 0 && (unsigned int)nidx < norms.Size()) { - nvec = new FVector3(RealignVector(norms[nidx])); + nvec = RealignVector(norms[nidx]); } else { - // https://www.khronos.org/opengl/wiki/Calculating_a_Surface_Normal - // Find other sides of triangle - auto nextSidx = side + 2; - if (nextSidx >= 3) nextSidx -= 3; - - auto lastSidx = side + 1; - if (lastSidx >= 3) lastSidx -= 3; - - OBJFaceSide &nextSide = surfaces[i].tris[j].sides[nextSidx]; - OBJFaceSide &lastSide = surfaces[i].tris[j].sides[lastSidx]; - - // Cross-multiply the U-vector and V-vector - FVector3 uvec = RealignVector(verts[nextSide.vertref]) - curVvec; - FVector3 vvec = RealignVector(verts[lastSide.vertref]) - curVvec; - - nvec = new FVector3(uvec ^ vvec); + if (surfaces[i].tris[j].smoothGroup == 0) + { + nvec = CalculateNormalFlat(i, j); + } + else + { + nvec = CalculateNormalSmooth(vidx, surfaces[i].tris[j].smoothGroup); + } } - mdv->SetNormal(nvec->X, nvec->Y, nvec->Z); - delete nvec; + mdv->SetNormal(nvec.X, nvec.Y, nvec.Z); } } delete[] surfaces[i].tris; } + + // Destroy vertFaces + if (hasMissingNormals && hasSmoothGroups) + { + for (size_t i = 0; i < verts.Size(); i++) + { + vertFaces[i].Clear(); + } + delete[] vertFaces; + } vbuf->UnlockVertexBuffer(); } @@ -432,6 +458,7 @@ void FOBJModel::ConstructSurfaceTris(OBJSurface &surf) surf.tris[triIdx].sideCount = 3; if (faces[i].sideCount == 3) { + surf.tris[triIdx].smoothGroup = faces[i].smoothGroup; memcpy(surf.tris[triIdx].sides, faces[i].sides, sizeof(OBJFaceSide) * 3); } else if (faces[i].sideCount == 4) // Triangulate face @@ -443,6 +470,7 @@ void FOBJModel::ConstructSurfaceTris(OBJSurface &surf) delete[] triangulated; triIdx += 1; // Filling out two faces } + DPrintf(DMSG_SPAMMY, "Smooth group: %d\n", surf.tris[triIdx].smoothGroup); } } @@ -455,7 +483,9 @@ void FOBJModel::ConstructSurfaceTris(OBJSurface &surf) void FOBJModel::TriangulateQuad(const OBJFace &quad, OBJFace *tris) { tris[0].sideCount = 3; + tris[0].smoothGroup = quad.smoothGroup; tris[1].sideCount = 3; + tris[1].smoothGroup = quad.smoothGroup; int tsidx[2][3] = {{0, 1, 3}, {1, 2, 3}}; @@ -470,6 +500,26 @@ void FOBJModel::TriangulateQuad(const OBJFace &quad, OBJFace *tris) } } +/** + * Add the vertices of all surfaces' triangles to the array of vertex->triangle references + */ +void FOBJModel::AddVertFaces() { + // Initialize and populate vertFaces - this array stores references to triangles per vertex + vertFaces = new TArray[verts.Size()]; + for (size_t i = 0; i < surfaces.Size(); i++) + { + for (size_t j = 0; j < surfaces[i].numTris; j++) + { + OBJTriRef otr = OBJTriRef(i, j); + for (size_t k = 0; k < surfaces[i].tris[j].sideCount; k++) + { + int vidx = surfaces[i].tris[j].sides[k].vertref; + vertFaces[vidx].Push(otr); + } + } + } +} + /** * Re-align a vector to match MD3 alignment * @@ -494,6 +544,65 @@ inline FVector2 FOBJModel::FixUV(FVector2 vecToRealign) return vecToRealign; } +/** + * Calculate the surface normal for a triangle + * + * @param surfIdx The surface index + * @param triIdx The triangle Index + * @return The surface normal vector + */ +FVector3 FOBJModel::CalculateNormalFlat(unsigned int surfIdx, unsigned int triIdx) +{ + // https://www.khronos.org/opengl/wiki/Calculating_a_Surface_Normal + int curVert = surfaces[surfIdx].tris[triIdx].sides[0].vertref; + int nextVert = surfaces[surfIdx].tris[triIdx].sides[2].vertref; + int lastVert = surfaces[surfIdx].tris[triIdx].sides[1].vertref; + + // Cross-multiply the U-vector and V-vector + FVector3 curVvec = RealignVector(verts[curVert]); + FVector3 uvec = RealignVector(verts[nextVert]) - curVvec; + FVector3 vvec = RealignVector(verts[lastVert]) - curVvec; + + return uvec ^ vvec; +} + +/** + * Calculate the surface normal for a triangle + * + * @param otr A reference to the surface, and a triangle within that surface, as an OBJTriRef + * @return The surface normal vector + */ +FVector3 FOBJModel::CalculateNormalFlat(OBJTriRef otr) +{ + return CalculateNormalFlat(otr.surf, otr.tri); +} + +/** + * Calculate the normal of a vertex in a specific smooth group + * + * @param vidx The index of the vertex in the array of vertices + * @param smoothGroup The smooth group number + */ +FVector3 FOBJModel::CalculateNormalSmooth(unsigned int vidx, unsigned int smoothGroup) +{ + unsigned int connectedFaces = 0; + TArray& vTris = vertFaces[vidx]; + + FVector3 vNormal(0,0,0); + for (size_t face = 0; face < vTris.Size(); face++) + { + OBJFace& tri = surfaces[vTris[face].surf].tris[vTris[face].tri]; + if (tri.smoothGroup == smoothGroup) + { + FVector3 fNormal = CalculateNormalFlat(vTris[face]); + connectedFaces += 1; + vNormal += fNormal; + } + } + vNormal /= connectedFaces; + return vNormal; +} + /** * Find the index of the frame with the given name * diff --git a/src/r_data/models/models_obj.h b/src/r_data/models/models_obj.h index d6d68a58e..01a6e03cf 100644 --- a/src/r_data/models/models_obj.h +++ b/src/r_data/models/models_obj.h @@ -30,6 +30,8 @@ class FOBJModel : public FModel { private: const char *newSideSep = "$"; // OBJ side separator is /, which is parsed as a line comment by FScanner if two of them are next to each other. + bool hasMissingNormals; + bool hasSmoothGroups; enum class FaceElement { @@ -38,6 +40,14 @@ private: VNormalIndex }; + struct OBJTriRef + { + unsigned int surf; + unsigned int tri; + OBJTriRef(): surf(0), tri(0) {} + OBJTriRef(unsigned int surf, unsigned int tri): surf(surf), tri(tri) {} + bool operator== (OBJTriRef other) { return surf == other.surf && tri == other.tri; } + }; struct OBJFaceSide { int vertref; @@ -47,7 +57,9 @@ private: struct OBJFace { unsigned int sideCount; + unsigned int smoothGroup; OBJFaceSide sides[4]; + OBJFace(): sideCount(0), smoothGroup(0) {} }; struct OBJSurface // 1 surface per 'usemtl' { @@ -66,16 +78,21 @@ private: TArray faces; TArray surfaces; FScanner sc; + TArray* vertFaces; + int ResolveIndex(int origIndex, FaceElement el); template void ParseVector(TArray &array); bool ParseFaceSide(const FString &side, OBJFace &face, int sidx); void ConstructSurfaceTris(OBJSurface &surf); - int ResolveIndex(int origIndex, FaceElement el); + void AddVertFaces(); void TriangulateQuad(const OBJFace &quad, OBJFace *tris); FVector3 RealignVector(FVector3 vecToRealign); FVector2 FixUV(FVector2 vecToRealign); + FVector3 CalculateNormalFlat(unsigned int surfIdx, unsigned int triIdx); + FVector3 CalculateNormalFlat(OBJTriRef otr); + FVector3 CalculateNormalSmooth(unsigned int vidx, unsigned int smoothGroup); public: - FOBJModel() {} + FOBJModel(): hasMissingNormals(false), hasSmoothGroups(false), vertFaces(nullptr) {} ~FOBJModel(); bool Load(const char* fn, int lumpnum, const char* buffer, int length) override; int FindFrame(const char* name) override; From 525ab8eda385380dab712443ac1b9944fabaa586 Mon Sep 17 00:00:00 2001 From: Kevin Caccamo Date: Sat, 22 Sep 2018 12:49:54 -0400 Subject: [PATCH 2/9] Attempt to fix warnings from VS2017 Win64 compiler --- src/r_data/models/models_obj.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/r_data/models/models_obj.cpp b/src/r_data/models/models_obj.cpp index d56d994a0..035efd4d4 100644 --- a/src/r_data/models/models_obj.cpp +++ b/src/r_data/models/models_obj.cpp @@ -379,9 +379,9 @@ void FOBJModel::BuildVertexBuffer(FModelRenderer *renderer) FModelVertex *vertptr = vbuf->LockVertexBuffer(vbufsize); - for (size_t i = 0; i < surfaces.Size(); i++) + for (unsigned int i = 0; i < surfaces.Size(); i++) { - for (size_t j = 0; j < surfaces[i].numTris; j++) + for (unsigned int j = 0; j < surfaces[i].numTris; j++) { for (size_t side = 0; side < 3; side++) { @@ -506,9 +506,9 @@ void FOBJModel::TriangulateQuad(const OBJFace &quad, OBJFace *tris) void FOBJModel::AddVertFaces() { // Initialize and populate vertFaces - this array stores references to triangles per vertex vertFaces = new TArray[verts.Size()]; - for (size_t i = 0; i < surfaces.Size(); i++) + for (unsigned int i = 0; i < surfaces.Size(); i++) { - for (size_t j = 0; j < surfaces[i].numTris; j++) + for (unsigned int j = 0; j < surfaces[i].numTris; j++) { OBJTriRef otr = OBJTriRef(i, j); for (size_t k = 0; k < surfaces[i].tris[j].sideCount; k++) @@ -599,7 +599,7 @@ FVector3 FOBJModel::CalculateNormalSmooth(unsigned int vidx, unsigned int smooth vNormal += fNormal; } } - vNormal /= connectedFaces; + vNormal /= (float)connectedFaces; return vNormal; } From 6135e867a99e2d9e90815067ce9aee7d702bdcb8 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Fri, 5 Oct 2018 04:36:11 +0200 Subject: [PATCH 3/9] - remove shadow acne from PCF shadowmap filter and add three quality levels --- wadsrc/static/language.enu | 4 +- wadsrc/static/language.fr | 4 +- wadsrc/static/menudef.txt | 4 +- wadsrc/static/shaders/glsl/main.fp | 128 ++++++++++++++--------------- 4 files changed, 72 insertions(+), 68 deletions(-) diff --git a/wadsrc/static/language.enu b/wadsrc/static/language.enu index 4f5e1dd13..ab957c322 100644 --- a/wadsrc/static/language.enu +++ b/wadsrc/static/language.enu @@ -2442,7 +2442,9 @@ OPTVAL_FOO_DUMB = "foo_dumb"; OPTVAL_ALIASING = "Aliasing"; OPTVAL_LINEAR = "Linear"; OPTVAL_NEAREST = "Nearest"; -OPTVAL_PCF = "PCF"; +OPTVAL_PCF_LOW = "PCF (Low)"; +OPTVAL_PCF_MEDIUM = "PCF (Medium)"; +OPTVAL_PCF_HIGH = "PCF (High)"; OPTVAL_CUBIC = "Cubic"; OPTVAL_BLEP = "Band-limited step"; OPTVAL_LINEARSLOW = "Linear (Slower)"; diff --git a/wadsrc/static/language.fr b/wadsrc/static/language.fr index c43a3c222..22cd852d8 100644 --- a/wadsrc/static/language.fr +++ b/wadsrc/static/language.fr @@ -2419,7 +2419,9 @@ OPTVAL_DEFAULT = "Défaut"; OPTVAL_SOUNDSYSTEM = "Système Sonore"; OPTVAL_LINEAR = "Linéaire"; OPTVAL_NEAREST = "Nearest"; -OPTVAL_PCF = "PCF"; +OPTVAL_PCF_LOW = "PCF (Low)"; +OPTVAL_PCF_MEDIUM = "PCF (Medium)"; +OPTVAL_PCF_HIGH = "PCF (High)"; OPTVAL_CUBIC = "Cubique"; OPTVAL_BLEP = "Step limité sur bande"; OPTVAL_LINEARSLOW = "Linéaire (Lent)"; diff --git a/wadsrc/static/menudef.txt b/wadsrc/static/menudef.txt index a40c8b2df..c2e084c3d 100644 --- a/wadsrc/static/menudef.txt +++ b/wadsrc/static/menudef.txt @@ -2259,7 +2259,9 @@ OptionValue ShadowMapQuality OptionValue ShadowMapFilter { 0, "$OPTVAL_NEAREST" - 1, "$OPTVAL_PCF" + 1, "$OPTVAL_PCF_LOW" + 2, "$OPTVAL_PCF_MEDIUM" + 3, "$OPTVAL_PCF_HIGH" } diff --git a/wadsrc/static/shaders/glsl/main.fp b/wadsrc/static/shaders/glsl/main.fp index c8ad439cb..6bc34d275 100644 --- a/wadsrc/static/shaders/glsl/main.fp +++ b/wadsrc/static/shaders/glsl/main.fp @@ -178,47 +178,26 @@ float shadowDirToU(vec2 dir) } } -float sampleShadowmap(vec2 dir, float v) +vec2 shadowUToDir(float u) { - float u = shadowDirToU(dir); - float dist2 = dot(dir, dir); - return step(dist2, texture(ShadowMap, vec2(u, v)).x); + u *= 4.0; + vec2 raydir; + switch (int(u)) + { + case 0: raydir = vec2(u * 2.0 - 1.0, 1.0); break; + case 1: raydir = vec2(1.0, 1.0 - (u - 1.0) * 2.0); break; + case 2: raydir = vec2(1.0 - (u - 2.0) * 2.0, -1.0); break; + case 3: raydir = vec2(-1.0, (u - 3.0) * 2.0 - 1.0); break; + } + return raydir; } -float sampleShadowmapLinear(vec2 dir, float v) +float sampleShadowmap(vec3 planePoint, float v) { - float u = shadowDirToU(dir); - float dist2 = dot(dir, dir); + float bias = 1.0; + float negD = dot(vWorldNormal.xyz, planePoint); - vec2 isize = textureSize(ShadowMap, 0); - vec2 size = vec2(isize); - - vec2 fetchPos = vec2(u, v) * size - vec2(0.5, 0.0); - if (fetchPos.x < 0.0) - fetchPos.x += size.x; - - ivec2 ifetchPos = ivec2(fetchPos); - int y = ifetchPos.y; - - float t = fract(fetchPos.x); - int x0 = ifetchPos.x; - int x1 = ifetchPos.x + 1; - if (x1 == isize.x) - x1 = 0; - - float depth0 = texelFetch(ShadowMap, ivec2(x0, y), 0).x; - float depth1 = texelFetch(ShadowMap, ivec2(x1, y), 0).x; - return mix(step(dist2, depth0), step(dist2, depth1), t); -} - -vec2 shadowmapAdjustedRay(vec4 lightpos) -{ - vec3 planePoint = pixelpos.xyz - lightpos.xyz; - - if (dot(planePoint.xz, planePoint.xz) < 1.0) - return planePoint.xz * 0.5; - - vec3 ray = normalize(planePoint); + vec3 ray = planePoint; vec2 isize = textureSize(ShadowMap, 0); float scale = float(isize.x) * 0.25; @@ -239,51 +218,70 @@ vec2 shadowmapAdjustedRay(vec4 lightpos) ray.x = sign(ray.x); } - float bias = 1.0; - float negD = dot(vWorldNormal.xyz, planePoint); float t = negD / dot(vWorldNormal.xyz, ray) - bias; - return ray.xz * t; + vec2 dir = ray.xz * t; + + float u = shadowDirToU(dir); + float dist2 = dot(dir, dir); + return step(dist2, texture(ShadowMap, vec2(u, v)).x); } -//=========================================================================== -// -// Check if light is in shadow using Percentage Closer Filtering (PCF) -// -//=========================================================================== +float sampleShadowmapPCF(vec3 planePoint, float v) +{ + float bias = 1.0; + float negD = dot(vWorldNormal.xyz, planePoint); + + vec3 ray = planePoint; + + if (abs(ray.z) > abs(ray.x)) + ray.y = ray.y / abs(ray.z); + else + ray.y = ray.y / abs(ray.x); + + vec2 isize = textureSize(ShadowMap, 0); + float scale = float(isize.x); + float texelPos = floor(shadowDirToU(ray.xz) * scale); + + float sum = 0.0; + float step_count = uShadowmapFilter; + + texelPos -= step_count + 0.5; + for (float x = -step_count; x <= step_count; x++) + { + float u = texelPos / scale; + vec2 dir = shadowUToDir(u); + + ray.x = dir.x; + ray.z = dir.y; + float t = negD / dot(vWorldNormal.xyz, ray) - bias; + dir = ray.xz * t; + + float dist2 = dot(dir, dir); + sum += step(dist2, texture(ShadowMap, vec2(u, v)).x); + texelPos++; + } + return sum / (uShadowmapFilter * 2.0 + 1.0); +} float shadowmapAttenuation(vec4 lightpos, float shadowIndex) { if (shadowIndex >= 1024.0) return 1.0; // No shadowmap available for this light - float v = (shadowIndex + 0.5) / 1024.0; + vec3 planePoint = pixelpos.xyz - lightpos.xyz; - vec2 ray = shadowmapAdjustedRay(lightpos); + if (dot(planePoint.xz, planePoint.xz) < 1.0) + return 1.0; // Light is too close + + float v = (shadowIndex + 0.5) / 1024.0; if (uShadowmapFilter <= 0) { - return sampleShadowmap(ray, v); - //return sampleShadowmapLinear(ray, v); + return sampleShadowmap(planePoint, v); } else { - float length = length(ray); - if (length < 3.0) - return 1.0; - - vec2 dir = ray / length * min(length / 50.0, 1.0); // avoid sampling behind light - - vec2 normal = vec2(-dir.y, dir.x); - vec2 bias = dir * 10.0; - - float sum = 0.0; - float step_count = ((uShadowmapFilter - 1) / 2.); - - for (float x = -step_count; x <= step_count; x++) - { - sum += sampleShadowmap(ray + normal * x /*- bias * abs(x)*/, v); - } - return sum / uShadowmapFilter; + return sampleShadowmapPCF(planePoint, v); } } From 9cffc291349a927f4d54ecf6aaaac7937d6f499b Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Fri, 5 Oct 2018 15:22:21 +0300 Subject: [PATCH 4/9] - fixed stuck memory usage warning in options menu https://forum.zdoom.org/viewtopic.php?t=62186 --- wadsrc/static/zscript/menu/optionmenu.txt | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/wadsrc/static/zscript/menu/optionmenu.txt b/wadsrc/static/zscript/menu/optionmenu.txt index 3e1853735..f73035ab0 100644 --- a/wadsrc/static/zscript/menu/optionmenu.txt +++ b/wadsrc/static/zscript/menu/optionmenu.txt @@ -540,14 +540,19 @@ class CompatibilityMenu : OptionMenu class GLTextureGLOptions : OptionMenu { private int mWarningIndex; + private string mWarningLabel; override void Init(Menu parent, OptionMenuDescriptor desc) { super.Init(parent, desc); + // Find index of warning item placeholder + mWarningIndex = -1; + mWarningLabel = "!HQRESIZE_WARNING!"; + for (int i=0; i < mDesc.mItems.Size(); ++i) { - if (mDesc.mItems[i].mLabel == "!HQRESIZE_WARNING!") + if (mDesc.mItems[i].mLabel == mWarningLabel) { mWarningIndex = i; break; @@ -555,11 +560,22 @@ class GLTextureGLOptions : OptionMenu } } + override void OnDestroy() + { + // Restore warning item placeholder + if (mWarningIndex >= 0) + { + mDesc.mItems[mWarningIndex].mLabel = mWarningLabel; + } + + Super.OnDestroy(); + } + override void Ticker() { Super.Ticker(); - if (mWarningIndex > 0) + if (mWarningIndex >= 0) { string message; From 8ea74770fde01ed6d8d7dd50160b213a54e5f043 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Fri, 5 Oct 2018 21:30:16 +0200 Subject: [PATCH 5/9] - fix artifact in PCF filter when the texture coordinate wraps --- wadsrc/static/shaders/glsl/main.fp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wadsrc/static/shaders/glsl/main.fp b/wadsrc/static/shaders/glsl/main.fp index 6bc34d275..228d7b02d 100644 --- a/wadsrc/static/shaders/glsl/main.fp +++ b/wadsrc/static/shaders/glsl/main.fp @@ -248,7 +248,7 @@ float sampleShadowmapPCF(vec3 planePoint, float v) texelPos -= step_count + 0.5; for (float x = -step_count; x <= step_count; x++) { - float u = texelPos / scale; + float u = fract(texelPos / scale); vec2 dir = shadowUToDir(u); ray.x = dir.x; From 605d9ecdabbb89ad14a3e92c07147777cf67e683 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 6 Oct 2018 23:50:12 +0200 Subject: [PATCH 6/9] - removed dynamic lights from Hexen's Mana pickups. They barely glow, yet were casting relatively strong lights. --- wadsrc_lights/static/filter/hexen/gldefs.txt | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/wadsrc_lights/static/filter/hexen/gldefs.txt b/wadsrc_lights/static/filter/hexen/gldefs.txt index cc9513d97..fb6cb49c3 100644 --- a/wadsrc_lights/static/filter/hexen/gldefs.txt +++ b/wadsrc_lights/static/filter/hexen/gldefs.txt @@ -1545,11 +1545,6 @@ pointlight MANA1 offset 0 36 0 } -object Mana1 -{ - frame MAN1 { light MANA1 } -} - // Green mana pointlight MANA2 { @@ -1559,11 +1554,6 @@ pointlight MANA2 offset 0 36 0 } -object Mana2 -{ - frame MAN2 { light MANA2 } -} - // Combined mana pointlight MANA3 { From 2a6892619283cf480ddab17a57ab5f1582ffa9f3 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sun, 7 Oct 2018 11:08:10 +0300 Subject: [PATCH 7/9] - use Xcode 10 for Travis builds --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 956ed21cf..6962cbaff 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,7 +16,7 @@ matrix: - CMAKE_OPTIONS="-DCMAKE_BUILD_TYPE=Debug -DCMAKE_OSX_DEPLOYMENT_TARGET=10.9" - os: osx - osx_image: xcode9.4 + osx_image: xcode10 env: - CMAKE_OPTIONS="-DCMAKE_BUILD_TYPE=Release -DCMAKE_OSX_DEPLOYMENT_TARGET=10.9" From 4d14642cadad984cd101e1a5b9654598d75d6682 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sun, 7 Oct 2018 11:10:29 +0300 Subject: [PATCH 8/9] - enabled macOS dark mode support with pre-10.14 SDKs https://developer.apple.com/documentation/appkit/nsappearancecustomization/choosing_a_specific_appearance_for_your_app --- src/posix/osx/zdoom-info.plist | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/posix/osx/zdoom-info.plist b/src/posix/osx/zdoom-info.plist index f0bbbf3d9..341a061d7 100644 --- a/src/posix/osx/zdoom-info.plist +++ b/src/posix/osx/zdoom-info.plist @@ -48,5 +48,7 @@ NSApplication NSSupportsAutomaticGraphicsSwitching + NSRequiresAquaSystemAppearance + From 2c9a82e084c23a36f0c7c86bd6367077801219a6 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 7 Oct 2018 19:59:51 +0200 Subject: [PATCH 9/9] - fixed potential null pointer access in Hexen's spike code. --- wadsrc/static/zscript/hexen/spike.txt | 37 +++++++++++++++------------ 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/wadsrc/static/zscript/hexen/spike.txt b/wadsrc/static/zscript/hexen/spike.txt index cb8df17e2..a411dbf3f 100644 --- a/wadsrc/static/zscript/hexen/spike.txt +++ b/wadsrc/static/zscript/hexen/spike.txt @@ -179,26 +179,29 @@ class ThrustFloor : Actor while (it.Next()) { let targ = it.thing; - double blockdist = radius + it.thing.radius; - if (abs(targ.pos.x - it.Position.X) >= blockdist || abs(targ.pos.y - it.Position.Y) >= blockdist) - continue; - - // Q: Make this z-aware for everything? It never was before. - if (targ.pos.z + targ.height < pos.z || targ.pos.z > pos.z + height) + if (targ != null) { - if (CurSector.PortalGroup != targ.CurSector.PortalGroup) + double blockdist = radius + targ.radius; + if (abs(targ.pos.x - it.Position.X) >= blockdist || abs(targ.pos.y - it.Position.Y) >= blockdist) continue; + + // Q: Make this z-aware for everything? It never was before. + if (targ.pos.z + targ.height < pos.z || targ.pos.z > pos.z + height) + { + if (CurSector.PortalGroup != targ.CurSector.PortalGroup) + continue; + } + + if (!targ.bShootable) + continue; + + if (targ == self) + continue; // don't clip against self + + int newdam = targ.DamageMobj (self, self, 10001, 'Crush'); + targ.TraceBleed (newdam > 0 ? newdam : 10001, null); + args[1] = 1; // Mark thrust thing as bloody } - - if (!targ.bShootable) - continue; - - if (targ == self) - continue; // don't clip against self - - int newdam = targ.DamageMobj (self, self, 10001, 'Crush'); - targ.TraceBleed (newdam > 0 ? newdam : 10001, null); - args[1] = 1; // Mark thrust thing as bloody } } }