diff --git a/Core/Render/OpenGL/Renderers/Legacy/World/DynamicVertex.cs b/Core/Render/OpenGL/Renderers/Legacy/World/DynamicVertex.cs index a3806cf3d..7c82ef8b0 100644 --- a/Core/Render/OpenGL/Renderers/Legacy/World/DynamicVertex.cs +++ b/Core/Render/OpenGL/Renderers/Legacy/World/DynamicVertex.cs @@ -16,7 +16,7 @@ public struct DynamicVertex public float V; [VertexAttribute] - public float Options; + public float SurfaceOptions; [VertexAttribute] public float LightLevelAdd; @@ -30,6 +30,6 @@ public struct DynamicVertex public float PrevU; public float PrevV; - [VertexAttribute(required: false)] - public float ColorMapIndex; + [VertexAttribute] + public float RenderOptions; } diff --git a/Core/Render/OpenGL/Renderers/Legacy/World/Entities/EntityProgram.cs b/Core/Render/OpenGL/Renderers/Legacy/World/Entities/EntityProgram.cs index 70dfa864d..ca4b33d64 100644 --- a/Core/Render/OpenGL/Renderers/Legacy/World/Entities/EntityProgram.cs +++ b/Core/Render/OpenGL/Renderers/Legacy/World/Entities/EntityProgram.cs @@ -145,10 +145,10 @@ protected override string VertexShader() => @" #version 330 layout(location = 0) in vec3 pos; - layout(location = 1) in float options; + layout(location = 1) in float surfaceOptions; layout(location = 2) in vec3 prevPos; layout(location = 3) in float offsetXYZ; - layout(location = 4) in float colorMapAndRenderIndex; + layout(location = 4) in float renderOptions; flat out float lightLevelOut; flat out float alphaOut; @@ -168,15 +168,15 @@ protected override string VertexShader() => @" void main() { - int intOptions = floatBitsToInt(options); + int intOptions = floatBitsToInt(surfaceOptions); alphaOut = (intOptions & 0xFF) / 255.0; fuzzOut = (intOptions >> 8) & 1; flipUOut = (intOptions >> 9) & 1; lightLevelOut = (intOptions >> 10) & 0xFF; colorMapTranslationOut = (intOptions >> 18); - intOptions = floatBitsToInt(colorMapAndRenderIndex); - int sectorIndexInt = intOptions >> 16; + intOptions = floatBitsToInt(renderOptions); + int lightIndexInt = intOptions >> 16; int renderIndex = intOptions & 0xFFFF; intOptions = floatBitsToInt(offsetXYZ); @@ -188,8 +188,8 @@ void main() offsetZOut = mix(offsetZOut, -offsetZOut, offsetZSign); renderIndexOut = renderIndex; - sectorColorMapIndexOut = texelFetch(sectorColormapTexture, sectorIndexInt).rgb; - sectorFogOut = texelFetch(sectorFogTexture, sectorIndexInt).rgba; + sectorColorMapIndexOut = texelFetch(sectorColormapTexture, lightIndexInt).rgb; + sectorFogOut = texelFetch(sectorFogTexture, lightIndexInt).rgba; gl_Position = vec4(mix(prevPos, pos, timeFrac), 1.0); positionZOut = gl_Position.z; } diff --git a/Core/Render/OpenGL/Renderers/Legacy/World/Entities/EntityRenderer.cs b/Core/Render/OpenGL/Renderers/Legacy/World/Entities/EntityRenderer.cs index 30be16a8f..1dd3054bd 100644 --- a/Core/Render/OpenGL/Renderers/Legacy/World/Entities/EntityRenderer.cs +++ b/Core/Render/OpenGL/Renderers/Legacy/World/Entities/EntityRenderer.cs @@ -284,9 +284,9 @@ public void RenderEntity(Entity entity, in Vec2D position, int renderIndex) vertex.PrevPos.X = (float)(entity.PrevPosition.X - nudgeAmount.X); vertex.PrevPos.Y = (float)(entity.PrevPosition.Y - nudgeAmount.Y); vertex.PrevPos.Z = (float)entity.PrevPosition.Z; - vertex.Options = VertexOptions.Entity(alpha, fuzz, flipU, colorMapIndex, lightLevel); - vertex.ColorMapAndRenderIndex = VertexOptions.EntityColorMapAndRenderIndex( - Renderer.GetColorMapBufferIndex(sector, WorldStatic.Sector3D && sector.Sectors3D.Length > 0 ? LightBufferType.Wall : LightBufferType.Floor), renderIndex); + vertex.SurfaceOptions = VertexOptions.EntityPackSurface(alpha, fuzz, flipU, colorMapIndex, lightLevel); + vertex.RenderOptions = VertexOptions.EntityPackRender( + Renderer.GetLightBufferIndex(sector, WorldStatic.Sector3D && sector.Sectors3D.Length > 0 ? LightBufferType.Wall : LightBufferType.Floor), renderIndex); if (entity.Definition.Flags.SpawnCeiling() && m_vanillaRender) { @@ -298,7 +298,7 @@ public void RenderEntity(Entity entity, in Vec2D position, int renderIndex) vertex.PrevPos.Z = entity.PrevPosition.Z != entity.Position.Z ? (float)entity.Sector.Ceiling.PrevZ : ceilingZ; } - vertex.OffsetXYZ = VertexOptions.EntityXYZ(offsetX, offsetZ); + vertex.OffsetXYZ = VertexOptions.EntityPackXYZ(offsetX, offsetZ); arrayData.Length = length + 1; if (m_healthBars && entity.Flags.Shootable() && (m_healthBarLimit <= 0 || m_healthBarLimit <= entity.Properties.Health)) @@ -326,10 +326,10 @@ private void RenderHealthBar(Entity entity, GLLegacyTexture texture, float offse float min = 1f / (entity.Properties.HealthBarWidth + MinBarWidth - 5); // Normalized health percent (0-255) int health = (int)(Math.Max(min, entity.Health / (float)entity.Properties.Health) * 255f); - vertex.Options = VertexOptions.Entity(1, attackFlash ? 1 : 0, 0, entity.Properties.HealthBarWidth, health); + vertex.SurfaceOptions = VertexOptions.EntityPackSurface(1, attackFlash ? 1 : 0, 0, entity.Properties.HealthBarWidth, health); vertex.Pos = entityVertex.Pos; vertex.PrevPos = entityVertex.PrevPos; - vertex.OffsetXYZ = VertexOptions.EntityXYZ(0, offset); + vertex.OffsetXYZ = VertexOptions.EntityPackXYZ(0, offset); array.SetLength(array.Length + 1); } diff --git a/Core/Render/OpenGL/Renderers/Legacy/World/Entities/EntityVertex.cs b/Core/Render/OpenGL/Renderers/Legacy/World/Entities/EntityVertex.cs index 7882a0d57..5083bef85 100644 --- a/Core/Render/OpenGL/Renderers/Legacy/World/Entities/EntityVertex.cs +++ b/Core/Render/OpenGL/Renderers/Legacy/World/Entities/EntityVertex.cs @@ -11,8 +11,8 @@ public struct EntityVertex public Vec3F Pos; [VertexAttribute] - // X offset written to colormap option portion when in health bar mode - public float Options; + // X offset written to surface option portions when in health bar mode + public float SurfaceOptions; [VertexAttribute] public Vec3F PrevPos; @@ -20,6 +20,6 @@ public struct EntityVertex [VertexAttribute] public float OffsetXYZ; - [VertexAttribute(required: false)] - public float ColorMapAndRenderIndex; + [VertexAttribute] + public float RenderOptions; } diff --git a/Core/Render/OpenGL/Renderers/Legacy/World/Geometry/CoverWallUtil.cs b/Core/Render/OpenGL/Renderers/Legacy/World/Geometry/CoverWallUtil.cs index ed7e0455c..2a17b870b 100644 --- a/Core/Render/OpenGL/Renderers/Legacy/World/Geometry/CoverWallUtil.cs +++ b/Core/Render/OpenGL/Renderers/Legacy/World/Geometry/CoverWallUtil.cs @@ -48,22 +48,22 @@ public static unsafe void CopyCoverWallVertices(Side side, StaticVertex[] static { DynamicVertex* v = startVertex; staticVertices[index++] = new StaticVertex(v->X, v->Y, v->Z + heights.AddTop, v->U, v->V, - v->Options, v->LightLevelAdd, 0); + v->SurfaceOptions, v->LightLevelAdd, 0); v++; staticVertices[index++] = new StaticVertex(v->X, v->Y, v->Z - heights.SubBottom, v->U, v->V, - v->Options, v->LightLevelAdd, 0); + v->SurfaceOptions, v->LightLevelAdd, 0); v++; staticVertices[index++] = new StaticVertex(v->X, v->Y, v->Z + heights.AddTop, v->U, v->V, - v->Options, v->LightLevelAdd, 0); + v->SurfaceOptions, v->LightLevelAdd, 0); v++; staticVertices[index++] = new StaticVertex(v->X, v->Y, v->Z - heights.SubBottom, v->U, v->V, - v->Options, v->LightLevelAdd, 0); + v->SurfaceOptions, v->LightLevelAdd, 0); v++; staticVertices[index++] = new StaticVertex(v->X, v->Y, v->Z + heights.AddTop, v->U, v->V, - v->Options, v->LightLevelAdd, 0); + v->SurfaceOptions, v->LightLevelAdd, 0); v++; staticVertices[index++] = new StaticVertex(v->X, v->Y, v->Z - heights.SubBottom, v->U, v->V, - v->Options, v->LightLevelAdd, 0); + v->SurfaceOptions, v->LightLevelAdd, 0); } } diff --git a/Core/Render/OpenGL/Renderers/Legacy/World/Geometry/GeometryRenderer.cs b/Core/Render/OpenGL/Renderers/Legacy/World/Geometry/GeometryRenderer.cs index ae0889a24..a8f58f866 100644 --- a/Core/Render/OpenGL/Renderers/Legacy/World/Geometry/GeometryRenderer.cs +++ b/Core/Render/OpenGL/Renderers/Legacy/World/Geometry/GeometryRenderer.cs @@ -144,9 +144,9 @@ public GeometryRenderer(IConfig config, ArchiveCollection archiveCollection, Leg m_renderTwoSidedMiddleSliceFunc = RenderTwoSidedMiddleSlice; m_renderSectorSliceFunc3D = RenderSectorSlice3D; - var options = VertexOptions.World(1, 1, 0, 0, 0, 0); + var options = VertexOptions.PackSurface(1, 1, 0, 0, 0, 0); for (int i = 0; i < m_wallVertices.Length; i++) - m_wallVertices[i].Options = options; + m_wallVertices[i].SurfaceOptions = options; m_world = null!; } @@ -771,14 +771,13 @@ public void RenderOneSided(Side side, bool isFront, out DynamicVertex[]? vertice if (side.OffsetChanged || m_sectorChangedLine || data == null) { - int colorMapIndex = Renderer.GetColorMapBufferIndex(lightLevelSector, LightBufferType.Wall); - int lightIndex = Renderer.GetLightBufferIndex(side, side.Middle, lightLevelSector); + int lightIndex = Renderer.GetLightBufferIndex(side, side.Middle, lightLevelSector, out var overrideLightIndex); int addAlpha = allowAlpha ? 0 : 1; WorldTriangulator.HandleOneSided(side, offsetSide ?? side, floor, ceiling, texture.UVInverse, ref wall, isFront: isFront); if (data == null) - data = GetWallVertices(wall, GetLightLevelAdd(side), lightIndex, colorMapIndex, GetWallLightLevel(side, side.Middle), side.Line.Id, WallLocation.Middle, addAlpha: addAlpha, alpha: side.Alpha); + data = GetWallVertices(wall, GetLightLevelAdd(side), lightIndex, overrideLightIndex, GetWallLightLevel(side, side.Middle), side.Line.Id, WallLocation.Middle, addAlpha: addAlpha, alpha: side.Alpha); else - SetWallVertices(data, wall, GetLightLevelAdd(side), lightIndex, colorMapIndex, GetWallLightLevel(side, side.Middle), side.Line.Id, WallLocation.Middle, addAlpha: addAlpha, alpha: side.Alpha); + SetWallVertices(data, wall, GetLightLevelAdd(side), lightIndex, overrideLightIndex, GetWallLightLevel(side, side.Middle), side.Line.Id, WallLocation.Middle, addAlpha: addAlpha, alpha: side.Alpha); SetCachedSide(m_vertexLookup, side, data); } @@ -1132,17 +1131,16 @@ public void RenderTwoSidedLower(Side facingSide, Side otherSide, Sector facingSe if (facingSide.OffsetChanged || m_sectorChangedLine || data == null) { - int colorMapIndex = Renderer.GetColorMapBufferIndex(lightLevelSector, LightBufferType.Wall); - int lightIndex = Renderer.GetLightBufferIndex(facingSide, facingSide.Lower, lightLevelSector); + int lightIndex = Renderer.GetLightBufferIndex(facingSide, facingSide.Lower, lightLevelSector, out var overrideLightIndex); // This lower would clip into the upper texture. Pick the upper as the priority and stop at the ceiling. if (top.Z > otherSector.Ceiling.Z && !TextureManager.IsSkyTexture(otherSector.Ceiling.TextureHandle)) top = otherSector.Ceiling; WorldTriangulator.HandleTwoSidedLower(facingSide, top, bottom, texture.UVInverse, isFrontSide, ref wall); if (data == null) - data = GetWallVertices(wall, GetLightLevelAdd(facingSide), lightIndex, colorMapIndex, GetWallLightLevel(facingSide, facingSide.Lower), facingSide.Line.Id, WallLocation.Lower); + data = GetWallVertices(wall, GetLightLevelAdd(facingSide), lightIndex, overrideLightIndex, GetWallLightLevel(facingSide, facingSide.Lower), facingSide.Line.Id, WallLocation.Lower); else - SetWallVertices(data, wall, GetLightLevelAdd(facingSide), lightIndex, colorMapIndex, GetWallLightLevel(facingSide, facingSide.Lower), facingSide.Line.Id, WallLocation.Lower); + SetWallVertices(data, wall, GetLightLevelAdd(facingSide), lightIndex, overrideLightIndex, GetWallLightLevel(facingSide, facingSide.Lower), facingSide.Line.Id, WallLocation.Lower); SetCachedSide(m_vertexLookup, facingSide, data); } @@ -1255,13 +1253,12 @@ public void RenderTwoSidedUpper(Side facingSide, Side otherSide, Sector facingSe if (facingSide.OffsetChanged || m_sectorChangedLine || data == null) { - int colorMapIndex = Renderer.GetColorMapBufferIndex(lightLevelSector, LightBufferType.Wall); - int lightIndex = Renderer.GetLightBufferIndex(facingSide, facingSide.Upper, lightLevelSector); + int lightIndex = Renderer.GetLightBufferIndex(facingSide, facingSide.Upper, lightLevelSector, out var overrideLightIndex); WorldTriangulator.HandleTwoSidedUpper(facingSide, top, bottom, texture.UVInverse, isFrontSide, ref wall); if (data == null) - data = GetWallVertices(wall, GetLightLevelAdd(facingSide), lightIndex, colorMapIndex, GetWallLightLevel(facingSide, facingSide.Upper), facingSide.Line.Id, WallLocation.Upper); + data = GetWallVertices(wall, GetLightLevelAdd(facingSide), lightIndex, overrideLightIndex, GetWallLightLevel(facingSide, facingSide.Upper), facingSide.Line.Id, WallLocation.Upper); else - SetWallVertices(data, wall, GetLightLevelAdd(facingSide), lightIndex, colorMapIndex, GetWallLightLevel(facingSide, facingSide.Upper), facingSide.Line.Id, WallLocation.Upper); + SetWallVertices(data, wall, GetLightLevelAdd(facingSide), lightIndex, overrideLightIndex, GetWallLightLevel(facingSide, facingSide.Upper), facingSide.Line.Id, WallLocation.Upper); SetCachedSide(m_vertexUpperLookup, facingSide, data); } @@ -1309,13 +1306,12 @@ public DynamicVertex[] RenderTwoSidedUpperOrLowerRaw(WallLocation location, Side WallVertices wall = default; GLLegacyTexture texture = m_glTextureManager.GetTexture(lowerWall.TextureHandle); - int colorMapIndex = Renderer.GetColorMapBufferIndex(facingSector, LightBufferType.Wall); int lightIndex = Renderer.GetLightBufferIndex(facingSector, LightBufferType.Wall); if (location == WallLocation.Upper) WorldTriangulator.HandleTwoSidedUpper(facingSide, facingSector.Ceiling, otherSector.Ceiling, texture.UVInverse, isFrontSide, ref wall); else WorldTriangulator.HandleTwoSidedLower(facingSide, otherSector.Floor, facingSector.Floor, texture.UVInverse, isFrontSide, ref wall); - SetWallVertices(m_wallVertices, wall, GetLightLevelAdd(facingSide), lightIndex, colorMapIndex, 0, facingSide.Line.Id, location); + SetWallVertices(m_wallVertices, wall, GetLightLevelAdd(facingSide), lightIndex, lightIndex, 0, facingSide.Line.Id, location); return m_wallVertices; } @@ -1436,8 +1432,7 @@ public void RenderTwoSidedMiddle(Side facingSide, Side otherSide, Sector facingS prevOffset = GetTransferHeightHackOffset(TextureManager, facingSide, otherSide, opening.BottomZ, opening.TopZ, previous: true); } - int colorMapIndex = Renderer.GetColorMapBufferIndex(lightLevelSector, LightBufferType.Wall); - int lightIndex = Renderer.GetLightBufferIndex(facingSide, facingSide.Middle, lightLevelSector); + int lightIndex = Renderer.GetLightBufferIndex(facingSide, facingSide.Middle, lightLevelSector, out var overrideLightIndex); WallVertices wall = default; WorldTriangulator.HandleTwoSidedMiddle(facingSide, @@ -1445,9 +1440,9 @@ public void RenderTwoSidedMiddle(Side facingSide, Side otherSide, Sector facingS clipPlanes: GetTwoSidedMiddleClipPlanes(facingSide, otherSide, facingSector, otherSector), restrictSpan: restrictSpan); if (data == null) - data = GetWallVertices(wall, GetLightLevelAdd(facingSide), lightIndex, colorMapIndex, GetWallLightLevel(facingSide, facingSide.Middle), line.Id, WallLocation.None, alpha, addAlpha: 0); + data = GetWallVertices(wall, GetLightLevelAdd(facingSide), lightIndex, overrideLightIndex, GetWallLightLevel(facingSide, facingSide.Middle), line.Id, WallLocation.None, alpha, addAlpha: 0); else - SetWallVertices(data, wall, GetLightLevelAdd(facingSide), lightIndex, colorMapIndex, GetWallLightLevel(facingSide, facingSide.Middle), line.Id, WallLocation.None, alpha, addAlpha: 0); + SetWallVertices(data, wall, GetLightLevelAdd(facingSide), lightIndex, overrideLightIndex, GetWallLightLevel(facingSide, facingSide.Middle), line.Id, WallLocation.None, alpha, addAlpha: 0); SetCachedSide(m_vertexLookup, facingSide, data); line.RenderSegStart = saveStart; @@ -1669,23 +1664,22 @@ private void RenderFlat(DynamicArray subsectors, SectorPlane renderPl var lookupData = generateSector3D ? GetSectorVertices3D(subsectors, geometryPlane, out var generate) : GetSectorVertices(subsectors, floor, id, out generate); if (generate || flatChanged) { - int colorMapIndex, lightIndex; + int lightIndex; + int overrideLightIndex; SectorPlane lightPlane; if (floor) { - lightIndex = Renderer.GetLightBufferIndex(lightLevelSector, SectorPlaneFace.Floor, LightBufferType.Floor); - colorMapIndex = Renderer.GetColorMapBufferIndex(lightLevelSector, LightBufferType.Floor); + lightIndex = Renderer.GetLightBufferIndex(lightLevelSector, SectorPlaneFace.Floor, LightBufferType.Floor, out overrideLightIndex); lightPlane = sector.TransferFloorLightSector.Floor; } else { - lightIndex = Renderer.GetLightBufferIndex(lightLevelSector, SectorPlaneFace.Floor, LightBufferType.Ceiling); - colorMapIndex = Renderer.GetColorMapBufferIndex(lightLevelSector, LightBufferType.Ceiling); + lightIndex = Renderer.GetLightBufferIndex(lightLevelSector, SectorPlaneFace.Ceiling, LightBufferType.Ceiling, out overrideLightIndex); lightPlane = sector.TransferCeilingLightSector.Ceiling; } - var flatLightLevel = (byte)Math.Clamp(lightPlane.LightLevelAbsolute ? lightPlane.LightLevel : (short)0, (short)0, (short)255); + var flatLightLevel = (byte)Math.Clamp(lightPlane.LightLevelAdd, (short)0, (short)255); int upper = floor ? 0 : 1; int lower = 1 - upper; int addAlpha = allowAlpha ? 0 : 1; @@ -1703,7 +1697,7 @@ private void RenderFlat(DynamicArray subsectors, SectorPlane renderPl { ref var second = ref m_subsectorVertices.Data[i]; ref var third = ref m_subsectorVertices.Data[i + 1]; - GetFlatVertices(lookupData, indexStart, ref root, ref second, ref third, lightIndex, colorMapIndex, flatLightLevel, upper, lower, addAlpha, alpha); + GetFlatVertices(lookupData, indexStart, ref root, ref second, ref third, lightIndex, overrideLightIndex, flatLightLevel, upper, lower, addAlpha, alpha); indexStart += 3; } } @@ -1903,7 +1897,7 @@ private static unsafe void CreateSkyFlatVertices(SkyGeometryVertex[] vertices, i } } - private static unsafe void SetWallVertices(DynamicVertex[] data, in WallVertices wv, int lightLevelAdd, int lightBufferIndex, int colorMapIndex, byte wallLightLevel, + private static unsafe void SetWallVertices(DynamicVertex[] data, in WallVertices wv, int lightLevelAdd, int lightIndex, int overrideLightIndex, byte wallLightLevel, int mapId, WallLocation location, float alpha = 1.0f, int addAlpha = 1) { var uvFlags = UvFlags.Normal; @@ -1911,7 +1905,7 @@ private static unsafe void SetWallVertices(DynamicVertex[] data, in WallVertices uvFlags |= UvFlags.MirrorX; if (wv.TopLeft.V > wv.BottomRight.V) uvFlags |= UvFlags.MirrorY; - var colorMapAndLightLevel = VertexOptions.ColorMapIndex(colorMapIndex, wallLightLevel, uvFlags); + var renderOptions = VertexOptions.PackRender(lightIndex, wallLightLevel, uvFlags); var lightLevelAddAndMapId = VertexOptions.LightLevelAdd(mapId, lightLevelAdd); var lower = location == WallLocation.Lower ? 1 : 0; var upper = location == WallLocation.Upper ? 1 : 0; @@ -1928,9 +1922,9 @@ private static unsafe void SetWallVertices(DynamicVertex[] data, in WallVertices vertex->V = wv.TopLeft.V; vertex->PrevU = wv.TopLeft.PrevU; vertex->PrevV = wv.TopLeft.PrevV; - vertex->Options = VertexOptions.World(1, alpha, addAlpha, upper, lower, lightBufferIndex); + vertex->SurfaceOptions = VertexOptions.PackSurface(1, alpha, addAlpha, upper, lower, overrideLightIndex); vertex->LightLevelAdd = lightLevelAddAndMapId; - vertex->ColorMapIndex = colorMapAndLightLevel; + vertex->RenderOptions = renderOptions; vertex++; vertex->X = wv.TopLeft.X; @@ -1943,9 +1937,9 @@ private static unsafe void SetWallVertices(DynamicVertex[] data, in WallVertices vertex->V = wv.BottomRight.V; vertex->PrevU = wv.TopLeft.PrevU; vertex->PrevV = wv.BottomRight.PrevV; - vertex->Options = VertexOptions.World(1, alpha, addAlpha, upper, lower, lightBufferIndex); + vertex->SurfaceOptions = VertexOptions.PackSurface(1, alpha, addAlpha, upper, lower, overrideLightIndex); vertex->LightLevelAdd = lightLevelAddAndMapId; - vertex->ColorMapIndex = colorMapAndLightLevel; + vertex->RenderOptions = renderOptions; vertex++; vertex->X = wv.BottomRight.X; @@ -1958,9 +1952,9 @@ private static unsafe void SetWallVertices(DynamicVertex[] data, in WallVertices vertex->V = wv.TopLeft.V; vertex->PrevU = wv.BottomRight.PrevU; vertex->PrevV = wv.TopLeft.PrevV; - vertex->Options = VertexOptions.World(1, alpha, addAlpha, upper, lower, lightBufferIndex); + vertex->SurfaceOptions = VertexOptions.PackSurface(1, alpha, addAlpha, upper, lower, overrideLightIndex); vertex->LightLevelAdd = lightLevelAddAndMapId; - vertex->ColorMapIndex = colorMapAndLightLevel; + vertex->RenderOptions = renderOptions; vertex++; vertex->X = wv.BottomRight.X; @@ -1973,9 +1967,9 @@ private static unsafe void SetWallVertices(DynamicVertex[] data, in WallVertices vertex->V = wv.BottomRight.V; vertex->PrevU = wv.BottomRight.PrevU; vertex->PrevV = wv.BottomRight.PrevV; - vertex->Options = VertexOptions.World(0, alpha, addAlpha, upper, lower, lightBufferIndex); + vertex->SurfaceOptions = VertexOptions.PackSurface(0, alpha, addAlpha, upper, lower, overrideLightIndex); vertex->LightLevelAdd = lightLevelAddAndMapId; - vertex->ColorMapIndex = colorMapAndLightLevel; + vertex->RenderOptions = renderOptions; vertex++; vertex->X = wv.BottomRight.X; @@ -1988,9 +1982,9 @@ private static unsafe void SetWallVertices(DynamicVertex[] data, in WallVertices vertex->V = wv.TopLeft.V; vertex->PrevU = wv.BottomRight.PrevU; vertex->PrevV = wv.TopLeft.PrevV; - vertex->Options = VertexOptions.World(0, alpha, addAlpha, upper, lower, lightBufferIndex); + vertex->SurfaceOptions = VertexOptions.PackSurface(0, alpha, addAlpha, upper, lower, overrideLightIndex); vertex->LightLevelAdd = lightLevelAddAndMapId; - vertex->ColorMapIndex = colorMapAndLightLevel; + vertex->RenderOptions = renderOptions; vertex++; vertex->X = wv.TopLeft.X; @@ -2003,13 +1997,13 @@ private static unsafe void SetWallVertices(DynamicVertex[] data, in WallVertices vertex->V = wv.BottomRight.V; vertex->PrevU = wv.TopLeft.PrevU; vertex->PrevV = wv.BottomRight.PrevV; - vertex->Options = VertexOptions.World(0, alpha, addAlpha, upper, lower, lightBufferIndex); + vertex->SurfaceOptions = VertexOptions.PackSurface(0, alpha, addAlpha, upper, lower, overrideLightIndex); vertex->LightLevelAdd = lightLevelAddAndMapId; - vertex->ColorMapIndex = colorMapAndLightLevel; + vertex->RenderOptions = renderOptions; } } - private static unsafe DynamicVertex[] GetWallVertices(in WallVertices wv, int lightLevelAdd, int lightBufferIndex, int colorMapIndex, byte wallLightLevel, + private static unsafe DynamicVertex[] GetWallVertices(in WallVertices wv, int lightLevelAdd, int lightIndex, int overrideLightIndex, byte wallLightLevel, int mapId, WallLocation location, float alpha = 1.0f, int addAlpha = 1) { var uvFlags = UvFlags.Normal; @@ -2017,7 +2011,7 @@ private static unsafe DynamicVertex[] GetWallVertices(in WallVertices wv, int li uvFlags |= UvFlags.MirrorX; if (wv.TopLeft.V > wv.BottomRight.V) uvFlags |= UvFlags.MirrorY; - var colorMapAndLightLevel = VertexOptions.ColorMapIndex(colorMapIndex, wallLightLevel, uvFlags); + var renderOptions = VertexOptions.PackRender(lightIndex, wallLightLevel, uvFlags); var lightLevelAddAndMapId = VertexOptions.LightLevelAdd(mapId, lightLevelAdd); var lower = location == WallLocation.Lower ? 1 : 0; var upper = location == WallLocation.Upper ? 1 : 0; @@ -2044,9 +2038,9 @@ private static unsafe DynamicVertex[] GetWallVertices(in WallVertices wv, int li vertex->V = wv.TopLeft.V; vertex->PrevU = wv.TopLeft.PrevU; vertex->PrevV = wv.TopLeft.PrevV; - vertex->Options = VertexOptions.World(1, alpha, addAlpha, upper, lower, lightBufferIndex); + vertex->SurfaceOptions = VertexOptions.PackSurface(1, alpha, addAlpha, upper, lower, overrideLightIndex); vertex->LightLevelAdd = lightLevelAddAndMapId; - vertex->ColorMapIndex = colorMapAndLightLevel; + vertex->RenderOptions = renderOptions; // 1 vertex++; @@ -2060,9 +2054,9 @@ private static unsafe DynamicVertex[] GetWallVertices(in WallVertices wv, int li vertex->V = wv.BottomRight.V; vertex->PrevU = wv.TopLeft.PrevU; vertex->PrevV = wv.BottomRight.PrevV; - vertex->Options = VertexOptions.World(1, alpha, addAlpha, upper, lower, lightBufferIndex); + vertex->SurfaceOptions = VertexOptions.PackSurface(1, alpha, addAlpha, upper, lower, overrideLightIndex); vertex->LightLevelAdd = lightLevelAddAndMapId; - vertex->ColorMapIndex = colorMapAndLightLevel; + vertex->RenderOptions = renderOptions; // 2 vertex++; @@ -2076,9 +2070,9 @@ private static unsafe DynamicVertex[] GetWallVertices(in WallVertices wv, int li vertex->V = wv.TopLeft.V; vertex->PrevU = wv.BottomRight.PrevU; vertex->PrevV = wv.TopLeft.PrevV; - vertex->Options = VertexOptions.World(1, alpha, addAlpha, upper, lower, lightBufferIndex); + vertex->SurfaceOptions = VertexOptions.PackSurface(1, alpha, addAlpha, upper, lower, overrideLightIndex); vertex->LightLevelAdd = lightLevelAddAndMapId; - vertex->ColorMapIndex = colorMapAndLightLevel; + vertex->RenderOptions = renderOptions; // 3 vertex++; @@ -2092,9 +2086,9 @@ private static unsafe DynamicVertex[] GetWallVertices(in WallVertices wv, int li vertex->V = wv.BottomRight.V; vertex->PrevU = wv.BottomRight.PrevU; vertex->PrevV = wv.BottomRight.PrevV; - vertex->Options = VertexOptions.World(0, alpha, addAlpha, upper, lower, lightBufferIndex); + vertex->SurfaceOptions = VertexOptions.PackSurface(0, alpha, addAlpha, upper, lower, overrideLightIndex); vertex->LightLevelAdd = lightLevelAddAndMapId; - vertex->ColorMapIndex = colorMapAndLightLevel; + vertex->RenderOptions = renderOptions; // 4 vertex++; @@ -2108,9 +2102,9 @@ private static unsafe DynamicVertex[] GetWallVertices(in WallVertices wv, int li vertex->V = wv.TopLeft.V; vertex->PrevU = wv.BottomRight.PrevU; vertex->PrevV = wv.TopLeft.PrevV; - vertex->Options = VertexOptions.World(0, alpha, addAlpha, upper, lower, lightBufferIndex); + vertex->SurfaceOptions = VertexOptions.PackSurface(0, alpha, addAlpha, upper, lower, overrideLightIndex); vertex->LightLevelAdd = lightLevelAddAndMapId; - vertex->ColorMapIndex = colorMapAndLightLevel; + vertex->RenderOptions = renderOptions; // 5 vertex++; @@ -2124,19 +2118,19 @@ private static unsafe DynamicVertex[] GetWallVertices(in WallVertices wv, int li vertex->V = wv.BottomRight.V; vertex->PrevU = wv.TopLeft.PrevU; vertex->PrevV = wv.BottomRight.PrevV; - vertex->Options = VertexOptions.World(0, alpha, addAlpha, upper, lower, lightBufferIndex); + vertex->SurfaceOptions = VertexOptions.PackSurface(0, alpha, addAlpha, upper, lower, overrideLightIndex); vertex->LightLevelAdd = lightLevelAddAndMapId; - vertex->ColorMapIndex = colorMapAndLightLevel; + vertex->RenderOptions = renderOptions; } return data; } private static unsafe void GetFlatVertices(DynamicVertex[] vertices, int startIndex, ref TriangulatedWorldVertex root, ref TriangulatedWorldVertex second, ref TriangulatedWorldVertex third, - int lightLevelBufferIndex, int colorMapIndex, int flatLightLevel, int upper, int lower, int addAlpha, float alpha) + int lightIndex, int overrideLightIndex, int flatLightLevel, int upper, int lower, int addAlpha, float alpha) { - var options = VertexOptions.World(0, alpha, addAlpha, upper, lower, lightLevelBufferIndex); - float colorMapAndLightLevel = VertexOptions.ColorMapIndex(colorMapIndex, flatLightLevel); + var surfaceOptions = VertexOptions.PackSurface(0, alpha, addAlpha, upper, lower, overrideLightIndex); + var renderOptions = VertexOptions.PackRender(lightIndex, flatLightLevel); fixed (DynamicVertex* startVertex = &vertices[startIndex]) { DynamicVertex* vertex = startVertex; @@ -2150,8 +2144,8 @@ private static unsafe void GetFlatVertices(DynamicVertex[] vertices, int startIn vertex->V = root.V; vertex->PrevU = root.PrevU; vertex->PrevV = root.PrevV; - vertex->Options = options; - vertex->ColorMapIndex = colorMapAndLightLevel; + vertex->SurfaceOptions = surfaceOptions; + vertex->RenderOptions = renderOptions; vertex++; vertex->X = second.X; @@ -2164,8 +2158,8 @@ private static unsafe void GetFlatVertices(DynamicVertex[] vertices, int startIn vertex->V = second.V; vertex->PrevU = second.PrevU; vertex->PrevV = second.PrevV; - vertex->Options = options; - vertex->ColorMapIndex = colorMapAndLightLevel; + vertex->SurfaceOptions = surfaceOptions; + vertex->RenderOptions = renderOptions; vertex++; vertex->X = third.X; @@ -2178,8 +2172,8 @@ private static unsafe void GetFlatVertices(DynamicVertex[] vertices, int startIn vertex->V = third.V; vertex->PrevU = third.PrevU; vertex->PrevV = third.PrevV; - vertex->Options = options; - vertex->ColorMapIndex = colorMapAndLightLevel; + vertex->SurfaceOptions = surfaceOptions; + vertex->RenderOptions = renderOptions; } } diff --git a/Core/Render/OpenGL/Renderers/Legacy/World/Geometry/Portals/FloodFill/FloodFillProgram.cs b/Core/Render/OpenGL/Renderers/Legacy/World/Geometry/Portals/FloodFill/FloodFillProgram.cs index 0d4ed4e42..f6b638a87 100644 --- a/Core/Render/OpenGL/Renderers/Legacy/World/Geometry/Portals/FloodFill/FloodFillProgram.cs +++ b/Core/Render/OpenGL/Renderers/Legacy/World/Geometry/Portals/FloodFill/FloodFillProgram.cs @@ -85,8 +85,8 @@ protected override string VertexShader() => @" layout(location = 3) in float maxViewZ; layout(location = 4) in float prevZ; layout(location = 5) in float prevPlaneZ; - layout(location = 6) in float options; - layout(location = 7) in float colorMapIndex; + layout(location = 6) in float surfaceOptions; + layout(location = 7) in float renderOptions; layout(location = 8) in float mapId; flat out float planeZFrag; @@ -117,11 +117,10 @@ void main() vertexPosFrag = mix(prevPos, pos, timeFrac); mapIdFrag = mapId; - ${ColorMapAndLightLevelSet} - float alphaFrag; float addAlphaFrag; ${VertexOptionsSet} + ${ColorMapAndLightLevelSet} ${SectorColorMapVertexFunction} ${VertexLightBuffer} diff --git a/Core/Render/OpenGL/Renderers/Legacy/World/Geometry/Portals/FloodFill/FloodFillRenderer.cs b/Core/Render/OpenGL/Renderers/Legacy/World/Geometry/Portals/FloodFill/FloodFillRenderer.cs index 9b33dfb8d..69b8f39cc 100644 --- a/Core/Render/OpenGL/Renderers/Legacy/World/Geometry/Portals/FloodFill/FloodFillRenderer.cs +++ b/Core/Render/OpenGL/Renderers/Legacy/World/Geometry/Portals/FloodFill/FloodFillRenderer.cs @@ -111,16 +111,16 @@ public void UpdateStaticWall(int floodKey, SectorPlane floodPlane, WallVertices var upper = sideTexture == SideTexture.Upper ? 1 : 0; var lower = sideTexture == SideTexture.Lower ? 1 : 0; - var options = VertexOptions.World(0, 0, 0, upper, lower, data.LightIndex); + var options = VertexOptions.PackSurface(0, 0, 0, upper, lower, data.OverrideLightIndex); FloodFillVertex topLeft = new((vertices.TopLeft.X, vertices.TopLeft.Y, topZ), - prevTopZ, planeZ, prevPlaneZ, minZ, maxZ, options, data.ColorMapAndLightLevel, mapId); + prevTopZ, planeZ, prevPlaneZ, minZ, maxZ, options, data.RenderOptions, mapId); FloodFillVertex topRight = new((vertices.BottomRight.X, vertices.BottomRight.Y, topZ), - prevTopZ, planeZ, prevPlaneZ, minZ, maxZ, options, data.ColorMapAndLightLevel, mapId); + prevTopZ, planeZ, prevPlaneZ, minZ, maxZ, options, data.RenderOptions, mapId); FloodFillVertex bottomLeft = new((vertices.TopLeft.X, vertices.TopLeft.Y, bottomZ), - prevBottomZ, planeZ, prevPlaneZ, minZ, maxZ, options, data.ColorMapAndLightLevel, mapId); + prevBottomZ, planeZ, prevPlaneZ, minZ, maxZ, options, data.RenderOptions, mapId); FloodFillVertex bottomRight = new((vertices.BottomRight.X, vertices.BottomRight.Y, bottomZ), - prevBottomZ, planeZ, prevPlaneZ, minZ, maxZ, options, data.ColorMapAndLightLevel, mapId); + prevBottomZ, planeZ, prevPlaneZ, minZ, maxZ, options, data.RenderOptions, mapId); var vbo = floodInfo.Vertices.Vbo; vbo.Data[data.VboOffset] = topLeft; @@ -131,14 +131,14 @@ public void UpdateStaticWall(int floodKey, SectorPlane floodPlane, WallVertices vbo.Data[data.VboOffset + 5] = bottomRight; if (isFloodFillPlane) - ProjectFloodPlane(vbo, data.VboOffset + VerticesPerWall, vertices, minZ, maxZ, planeZ, prevPlaneZ, data.LightIndex, - maxPlaneZ > Constants.MaxTextureHeight ? -Constants.MaxTextureHeight : Constants.MaxTextureHeight, false, data.ColorMapAndLightLevel, mapId); + ProjectFloodPlane(vbo, data.VboOffset + VerticesPerWall, vertices, minZ, maxZ, planeZ, prevPlaneZ, data.OverrideLightIndex, + maxPlaneZ > Constants.MaxTextureHeight ? -Constants.MaxTextureHeight : Constants.MaxTextureHeight, false, data.RenderOptions, mapId); vbo.Bind(); vbo.UploadSubData(data.VboOffset, data.Vertices); } - public int AddStaticWall(SectorPlane sectorPlane, WallVertices vertices, double minPlaneZ, double maxPlaneZ, + public int AddStaticWall(SectorPlane sectorPlane, in WallVertices vertices, double minPlaneZ, double maxPlaneZ, SideTexture sideTexture, int mapId, bool isFloodFillPlane = false) { if (m_textureManager != null && m_textureManager.IsSkyTexture(sectorPlane.TextureHandle)) @@ -151,20 +151,15 @@ public int AddStaticWall(SectorPlane sectorPlane, WallVertices vertices, double float prevPlaneZ = (float)sectorPlane.PrevZ; FloodFillInfo floodFillInfo = GetOrCreateFloodFillInfo(sectorPlane); - int lightIndex, colorMapIndex; + int lightIndex; + int overrideLightIndex; if (sectorPlane.Facing == SectorPlaneFace.Floor) - { - lightIndex = Renderer.GetLightBufferIndex(sectorPlane.Sector, SectorPlaneFace.Floor, LightBufferType.Floor); - colorMapIndex = Renderer.GetColorMapBufferIndex(sectorPlane.Sector, LightBufferType.Floor); - } + lightIndex = Renderer.GetLightBufferIndex(sectorPlane.Sector, SectorPlaneFace.Floor, LightBufferType.Floor, out overrideLightIndex); else - { - lightIndex = Renderer.GetLightBufferIndex(sectorPlane.Sector, SectorPlaneFace.Ceiling, LightBufferType.Ceiling); - colorMapIndex = Renderer.GetColorMapBufferIndex(sectorPlane.Sector, LightBufferType.Ceiling); - } + lightIndex = Renderer.GetLightBufferIndex(sectorPlane.Sector, SectorPlaneFace.Ceiling, LightBufferType.Ceiling, out overrideLightIndex); - var flatLightLevel = (byte)Math.Clamp(sectorPlane.LightLevelAbsolute ? sectorPlane.LightLevel : (short)0, (short)0, (short)255); - var colorMapAndLightLevel = VertexOptions.ColorMapIndex(colorMapIndex, flatLightLevel); + var flatLightLevel = (byte)Math.Clamp(sectorPlane.LightLevelAdd, (short)0, (short)255); + var lightBufferIndex = VertexOptions.PackRender(lightIndex, flatLightLevel); for (var node = m_freeData.First; node != null; node = node.Next) { @@ -175,7 +170,7 @@ public int AddStaticWall(SectorPlane sectorPlane, WallVertices vertices, double m_freeData.Remove(node); m_freeNodes.Add(node); - m_floodGeometry[data.Key - 1] = new(data.Key, data.TextureHandle, lightIndex, colorMapAndLightLevel, data.VboOffset, data.Vertices); + m_floodGeometry[data.Key - 1] = new(data.Key, data.TextureHandle, overrideLightIndex, lightBufferIndex, data.VboOffset, data.Vertices); UpdateStaticWall(data.Key, sectorPlane, vertices, minPlaneZ, maxPlaneZ, sideTexture, mapId); return data.Key; } @@ -184,20 +179,20 @@ public int AddStaticWall(SectorPlane sectorPlane, WallVertices vertices, double int newKey = m_floodGeometry.Length + 1; var vbo = floodFillInfo.Vertices.Vbo; - m_floodGeometry.Add(new FloodGeometry(newKey, floodFillInfo.TextureHandle, lightIndex, colorMapAndLightLevel, vbo.Count, vertexCount)); + m_floodGeometry.Add(new FloodGeometry(newKey, floodFillInfo.TextureHandle, overrideLightIndex, lightBufferIndex, vbo.Count, vertexCount)); var upper = sideTexture == SideTexture.Upper ? 1 : 0; var lower = sideTexture == SideTexture.Lower ? 1 : 0; - var options = VertexOptions.World(0, 0, 0, upper, lower, lightIndex); + var options = VertexOptions.PackSurface(0, 0, 0, upper, lower, overrideLightIndex); FloodFillVertex topLeft = new((vertices.TopLeft.X, vertices.TopLeft.Y, vertices.TopLeft.Z), - vertices.TopLeft.Z, planeZ, prevPlaneZ, minZ, maxZ, options, colorMapAndLightLevel, mapId); + vertices.TopLeft.Z, planeZ, prevPlaneZ, minZ, maxZ, options, lightBufferIndex, mapId); FloodFillVertex topRight = new((vertices.BottomRight.X, vertices.BottomRight.Y, vertices.TopLeft.Z), - vertices.TopLeft.Z, planeZ, prevPlaneZ, minZ, maxZ, options, colorMapAndLightLevel, mapId); + vertices.TopLeft.Z, planeZ, prevPlaneZ, minZ, maxZ, options, lightBufferIndex, mapId); FloodFillVertex bottomLeft = new((vertices.TopLeft.X, vertices.TopLeft.Y, vertices.BottomRight.Z), - vertices.BottomRight.Z, planeZ, prevPlaneZ, minZ, maxZ, options, colorMapAndLightLevel, mapId); + vertices.BottomRight.Z, planeZ, prevPlaneZ, minZ, maxZ, options, lightBufferIndex, mapId); FloodFillVertex bottomRight = new((vertices.BottomRight.X, vertices.BottomRight.Y, vertices.BottomRight.Z), - vertices.BottomRight.Z, planeZ, prevPlaneZ, minZ, maxZ, options, colorMapAndLightLevel, mapId); + vertices.BottomRight.Z, planeZ, prevPlaneZ, minZ, maxZ, options, lightBufferIndex, mapId); int offset = vbo.Data.Length; int newLength = vbo.Data.Length + VerticesPerWall; @@ -213,7 +208,7 @@ public int AddStaticWall(SectorPlane sectorPlane, WallVertices vertices, double if (isFloodFillPlane) ProjectFloodPlane(vbo, vbo.Data.Length, vertices, minZ, maxZ, planeZ, prevPlaneZ, lightIndex, - maxPlaneZ > Constants.MaxTextureHeight ? -Constants.MaxTextureHeight : Constants.MaxTextureHeight, true, colorMapIndex, mapId); + maxPlaneZ > Constants.MaxTextureHeight ? -Constants.MaxTextureHeight : Constants.MaxTextureHeight, true, lightIndex, mapId); if (m_renderMode == FloodFillRenderMode.Dynamic) return 0; @@ -221,8 +216,8 @@ public int AddStaticWall(SectorPlane sectorPlane, WallVertices vertices, double return newKey; } - private static unsafe void ProjectFloodPlane(VertexBufferObject vbo, int startIndex, - WallVertices vertices, float minZ, float maxZ, float planeZ, float prevPlaneZ, int lightIndex, int addHeight, bool add, float colorMapAndLightLevel, int mapId) + private static void ProjectFloodPlane(VertexBufferObject vbo, int startIndex, + WallVertices vertices, float minZ, float maxZ, float planeZ, float prevPlaneZ, int overrideLightIndex, int addHeight, bool add, float renderOptions, int mapId) { int newLength = startIndex + FloodPlaneAddCount * VerticesPerWall; vbo.Data.EnsureCapacity(newLength); @@ -236,15 +231,15 @@ private static unsafe void ProjectFloodPlane(VertexBufferObject float prevTopZ = vertices.PrevTopZ + currentAddHeight; float prevBottomZ = vertices.PrevBottomZ + currentAddHeight; - var options = VertexOptions.World(0, 0, 0, 0, 0, lightIndex); + var surfaceOptions = VertexOptions.PackSurface(0, 0, 0, 0, 0, overrideLightIndex); FloodFillVertex topLeft = new((vertices.TopLeft.X, vertices.TopLeft.Y, topLeftZ), - prevTopZ, planeZ, prevPlaneZ, minZ, maxZ, options, colorMapAndLightLevel, mapId); + prevTopZ, planeZ, prevPlaneZ, minZ, maxZ, surfaceOptions, renderOptions, mapId); FloodFillVertex topRight = new((vertices.BottomRight.X, vertices.BottomRight.Y, topLeftZ), - prevTopZ, planeZ, prevPlaneZ, minZ, maxZ, options, colorMapAndLightLevel, mapId); + prevTopZ, planeZ, prevPlaneZ, minZ, maxZ, surfaceOptions, renderOptions, mapId); FloodFillVertex bottomLeft = new((vertices.TopLeft.X, vertices.TopLeft.Y, bottomRightZ), - prevBottomZ, planeZ, prevPlaneZ, minZ, maxZ, lightIndex, colorMapAndLightLevel, mapId); + prevBottomZ, planeZ, prevPlaneZ, minZ, maxZ, surfaceOptions, renderOptions, mapId); FloodFillVertex bottomRight = new((vertices.BottomRight.X, vertices.BottomRight.Y, bottomRightZ), - prevBottomZ, planeZ, prevPlaneZ, minZ, maxZ, options, colorMapAndLightLevel, mapId); + prevBottomZ, planeZ, prevPlaneZ, minZ, maxZ, surfaceOptions, renderOptions, mapId); buffer[startIndex++] = topLeft; buffer[startIndex++] = bottomLeft; diff --git a/Core/Render/OpenGL/Renderers/Legacy/World/Geometry/Portals/FloodFill/FloodFillVertex.cs b/Core/Render/OpenGL/Renderers/Legacy/World/Geometry/Portals/FloodFill/FloodFillVertex.cs index c6511fd84..8c88f24a0 100644 --- a/Core/Render/OpenGL/Renderers/Legacy/World/Geometry/Portals/FloodFill/FloodFillVertex.cs +++ b/Core/Render/OpenGL/Renderers/Legacy/World/Geometry/Portals/FloodFill/FloodFillVertex.cs @@ -5,7 +5,7 @@ namespace Helion.Render.OpenGL.Renderers.Legacy.World.Geometry.Portals.FloodFill; [StructLayout(LayoutKind.Sequential, Pack = 1)] -public struct FloodFillVertex(Vec3F pos, float prevZ, float planeZ, float prevPlaneZ, float minPlaneZ, float maxPlaneZ, float options, float colorMapAndLightLevel, int mapId) +public struct FloodFillVertex(Vec3F pos, float prevZ, float planeZ, float prevPlaneZ, float minPlaneZ, float maxPlaneZ, float surfaceOptions, float renderOptions, int mapId) { [VertexAttribute("pos", size: 3)] public Vec3F Pos = pos; @@ -25,11 +25,11 @@ public struct FloodFillVertex(Vec3F pos, float prevZ, float planeZ, float prevPl [VertexAttribute("prevPlaneZ", size: 1)] public float PrevPlaneZ = prevPlaneZ; - [VertexAttribute("options", size: 1)] - public float Options = options; + [VertexAttribute("surfaceOptions", size: 1)] + public float SurfaceOptions = surfaceOptions; - [VertexAttribute("colorMapIndex", size: 1, required: false)] - public float ColorMapIndex = colorMapAndLightLevel; + [VertexAttribute("renderOptions", size: 1)] + public float RenderOptions = renderOptions; [VertexAttribute("mapId", size: 1, required: false)] public float MapId = mapId; diff --git a/Core/Render/OpenGL/Renderers/Legacy/World/Geometry/Portals/FloodFill/FloodGeometry.cs b/Core/Render/OpenGL/Renderers/Legacy/World/Geometry/Portals/FloodFill/FloodGeometry.cs index b568a9486..defc773d4 100644 --- a/Core/Render/OpenGL/Renderers/Legacy/World/Geometry/Portals/FloodFill/FloodGeometry.cs +++ b/Core/Render/OpenGL/Renderers/Legacy/World/Geometry/Portals/FloodFill/FloodGeometry.cs @@ -1,11 +1,11 @@ namespace Helion.Render.OpenGL.Renderers.Legacy.World.Geometry.Portals.FloodFill; -public readonly struct FloodGeometry(int key, int textureHandle, int lightIndex, float colorMapAndLightLevel, int vboOffset, int vertices) +public readonly struct FloodGeometry(int key, int textureHandle, int overrideLightIndex, float renderOptions, int vboOffset, int vertices) { public readonly int Key = key; public readonly int TextureHandle = textureHandle; - public readonly int LightIndex = lightIndex; - public readonly float ColorMapAndLightLevel = colorMapAndLightLevel; + public readonly int OverrideLightIndex = overrideLightIndex; + public readonly float RenderOptions = renderOptions; public readonly int VboOffset = vboOffset; public readonly int Vertices = vertices; } diff --git a/Core/Render/OpenGL/Renderers/Legacy/World/Geometry/Static/StaticCacheGeometryRenderer.cs b/Core/Render/OpenGL/Renderers/Legacy/World/Geometry/Static/StaticCacheGeometryRenderer.cs index f701bef09..a10eda005 100644 --- a/Core/Render/OpenGL/Renderers/Legacy/World/Geometry/Static/StaticCacheGeometryRenderer.cs +++ b/Core/Render/OpenGL/Renderers/Legacy/World/Geometry/Static/StaticCacheGeometryRenderer.cs @@ -626,7 +626,7 @@ private static unsafe void AddVertices(DynamicArray staticVertices { DynamicVertex* v = startVertex + i; staticVertices.Data[staticStartIndex + i] = new StaticVertex(v->X, v->Y, v->Z, v->U, v->V, - v->Options, v->LightLevelAdd, v->ColorMapIndex); + v->SurfaceOptions, v->LightLevelAdd, v->RenderOptions); } staticVertices.SetLength(staticVertices.Length + vertices.Length); @@ -641,7 +641,7 @@ private static unsafe void CopyVertices(StaticVertex[] staticVertices, SpanX, v->Y, v->Z, v->U, v->V, - v->Options, v->LightLevelAdd, v->ColorMapIndex); + v->SurfaceOptions, v->LightLevelAdd, v->RenderOptions); } } } diff --git a/Core/Render/OpenGL/Renderers/Legacy/World/InterpolationShader.cs b/Core/Render/OpenGL/Renderers/Legacy/World/InterpolationShader.cs index 76dc067db..1c7ae047a 100644 --- a/Core/Render/OpenGL/Renderers/Legacy/World/InterpolationShader.cs +++ b/Core/Render/OpenGL/Renderers/Legacy/World/InterpolationShader.cs @@ -105,11 +105,11 @@ protected override string VertexShader() => @" layout(location = 0) in vec3 pos; layout(location = 1) in vec2 uv; - layout(location = 2) in float options; + layout(location = 2) in float surfaceOptions; layout(location = 3) in float lightLevelAdd; layout(location = 4) in vec3 prevPos; layout(location = 5) in vec2 prevUV; - layout(location = 6) in float colorMapIndex; + layout(location = 6) in float renderOptions; out vec2 uvFrag; flat out float alphaFrag; diff --git a/Core/Render/OpenGL/Renderers/Legacy/World/Shader/VertexFunction.cs b/Core/Render/OpenGL/Renderers/Legacy/World/Shader/VertexFunction.cs index e87a2e02f..82bc90753 100644 --- a/Core/Render/OpenGL/Renderers/Legacy/World/Shader/VertexFunction.cs +++ b/Core/Render/OpenGL/Renderers/Legacy/World/Shader/VertexFunction.cs @@ -35,20 +35,22 @@ public static class VertexFunction public static string VertexOptionsSet => @" - int intOptions = floatBitsToInt(options); + int intOptions = floatBitsToInt(surfaceOptions); alphaFrag = (intOptions & 0xFF) / 255.0; float topLeft = float((intOptions >> 8) & 1); addAlphaFrag = float((intOptions >> 9) & 1); upperFrag = float((intOptions >> 10) & 1); lowerFrag = float((intOptions >> 11) & 1); - float lightLevelBufferIndex = float(intOptions >> 12);"; + float overrideLightIndex = float(float(intOptions >> 12));"; public static string ColorMapAndLightLevelSet => @" - int colorMapAndLightLevel = floatBitsToInt(colorMapIndex); - vertexLightLevelFrag = float(colorMapAndLightLevel & 0xFF); - colorMapIndexFrag = float((colorMapAndLightLevel >> 10) & 0x3FFFFF); - uvFlags = float((colorMapAndLightLevel >> 8) & 0x3);"; + int lightLevelIndexAndLightLevel = floatBitsToInt(renderOptions); + vertexLightLevelFrag = float(lightLevelIndexAndLightLevel & 0xFF); + float lightLevelBufferIndex = float((lightLevelIndexAndLightLevel >> 10) & 0x3FFFFF); + colorMapIndexFrag = lightLevelBufferIndex; + lightLevelBufferIndex = mix(lightLevelBufferIndex, overrideLightIndex - 1, float(overrideLightIndex > 0)); + uvFlags = float((lightLevelIndexAndLightLevel >> 8) & 0x3);"; public static string LightLevelAddAndMapIdSet => @" diff --git a/Core/Render/OpenGL/Renderers/Legacy/World/StaticShader.cs b/Core/Render/OpenGL/Renderers/Legacy/World/StaticShader.cs index 05bad158a..2451b6658 100644 --- a/Core/Render/OpenGL/Renderers/Legacy/World/StaticShader.cs +++ b/Core/Render/OpenGL/Renderers/Legacy/World/StaticShader.cs @@ -103,8 +103,8 @@ protected override string VertexShader() => @" layout(location = 0) in vec3 pos; layout(location = 1) in vec2 uv; layout(location = 2) in float lightLevelAdd; - layout(location = 3) in float options; - layout(location = 4) in float colorMapIndex; + layout(location = 3) in float surfaceOptions; + layout(location = 4) in float renderOptions; out vec2 uvFrag; flat out float alphaFrag; diff --git a/Core/Render/OpenGL/Renderers/Legacy/World/StaticVertex.cs b/Core/Render/OpenGL/Renderers/Legacy/World/StaticVertex.cs index 69da0f795..4bd5a67cb 100644 --- a/Core/Render/OpenGL/Renderers/Legacy/World/StaticVertex.cs +++ b/Core/Render/OpenGL/Renderers/Legacy/World/StaticVertex.cs @@ -4,7 +4,7 @@ namespace Helion.Render.OpenGL.Renderers.Legacy.World; [StructLayout(LayoutKind.Sequential, Pack = 1)] -public struct StaticVertex(float x, float y, float z, float u, float v, float options, float lightLevelAdd, float colorMapIndex) +public struct StaticVertex(float x, float y, float z, float u, float v, float surfaceOptions, float lightLevelAdd, float renderOptions) { [VertexAttribute("pos", size: 3)] public float X = x; @@ -19,8 +19,8 @@ public struct StaticVertex(float x, float y, float z, float u, float v, float op public float LightLevelAdd = lightLevelAdd; [VertexAttribute] - public float Options = options; + public float SurfaceOptions = surfaceOptions; - [VertexAttribute(required: false)] - public float ColorMapIndex = colorMapIndex; + [VertexAttribute] + public float RenderOptions = renderOptions; } diff --git a/Core/Render/OpenGL/Renderers/Legacy/World/VertexOptions.cs b/Core/Render/OpenGL/Renderers/Legacy/World/VertexOptions.cs index 8e99a495c..be35d9d19 100644 --- a/Core/Render/OpenGL/Renderers/Legacy/World/VertexOptions.cs +++ b/Core/Render/OpenGL/Renderers/Legacy/World/VertexOptions.cs @@ -5,19 +5,21 @@ namespace Helion.Render.OpenGL.Renderers.Legacy.World; public static class VertexOptions { + // When overrideLightIndex is non-zero then lighting uses index overrideLightIndex - 1 [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static unsafe float World(int topLeft, float alpha, int addAlpha, int upper, int lower, int lightLevelBufferIndex) + public static unsafe float PackSurface(int topLeft, float alpha, int addAlpha, int upper, int lower, int overrideLightIndex) { int alphaByte = (int)(alpha * 255.0f); - int packed = (alphaByte & 0xFF) | (topLeft << 8) | (addAlpha << 9) | (upper << 10) | (lower << 11) | (lightLevelBufferIndex << 12); + int packed = (alphaByte & 0xFF) | (topLeft << 8) | (addAlpha << 9) | (upper << 10) | (lower << 11) | (overrideLightIndex << 12); return *(float*)&packed; } - + + [MethodImpl(MethodImplOptions.AggressiveInlining)] // UvFlags only required for walls - public static unsafe float ColorMapIndex(int colorMapIndex, int vertexLightLevel, UvFlags uvFlags = UvFlags.Normal) + public static unsafe float PackRender(int lightIndex, int vertexLightLevel, UvFlags uvFlags = UvFlags.Normal) { - // colorMapIndex 22 bits, uvFlags 2 bits, vertexLightLevel 8 bits - int packed = ((colorMapIndex & 0x3FFFFF) << 10) | (((int)uvFlags & 0x3) << 8) | (vertexLightLevel & 0xFF); + // lightIndex 22 bits, uvFlags 2 bits, vertexLightLevel 8 bits + int packed = ((lightIndex & 0x3FFFFF) << 10) | (((int)uvFlags & 0x3) << 8) | (vertexLightLevel & 0xFF); return *(float*)&packed; } @@ -33,7 +35,7 @@ public static unsafe float LightLevelAdd(int mapId, int lightLevelAdd) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static unsafe float Entity(float alpha, int fuzz, int flipU, int colormap, int lightLevel) + public static unsafe float EntityPackSurface(float alpha, int fuzz, int flipU, int colormap, int lightLevel) { int alphaByte = (int)(alpha * 255.0f); int packed = (alphaByte & 0xFF) | (fuzz << 8) | (flipU << 9) | (Math.Clamp(lightLevel, 0, 255) << 10) | (colormap << 18); @@ -41,14 +43,14 @@ public static unsafe float Entity(float alpha, int fuzz, int flipU, int colormap } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static unsafe float EntityColorMapAndRenderIndex(int colorMapIndex, int renderIndex) + public static unsafe float EntityPackRender(int colorMapIndex, int renderIndex) { int packed = colorMapIndex << 16 | renderIndex; return *(float*)&packed; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static unsafe float EntityXYZ(int offsetXY, int offsetZ) + public static unsafe float EntityPackXYZ(int offsetXY, int offsetZ) { // Shift negative bit for mask to get absolute value and sign bit to remove branches int maskXY = offsetXY >> 31; diff --git a/Core/Render/Renderer.World.cs b/Core/Render/Renderer.World.cs index bfbf04d0b..bcfbdc821 100644 --- a/Core/Render/Renderer.World.cs +++ b/Core/Render/Renderer.World.cs @@ -25,40 +25,33 @@ enum BlockSide Both = 3 } + private unsafe delegate void SetLightBufferPtrAction(IWorld world, T* data); + private readonly SectorUpdates m_updateLightSectors = new(); private readonly SectorUpdates m_updateColorMapSectors = new(); private readonly SectorUpdates m_updateFogColorSectors = new(); private readonly SectorUpdates m_updateLineHeights = new(); - private GLBufferTextureStorage? m_lightBufferStorage; + private GLBufferTextureStorage? m_sectorLightsBuffer; private GLBufferTextureStorage? m_sectorColorMapsBuffer; private GLBufferTextureStorage? m_sectorFogBuffer; private GLBufferTextureStorage? m_colorMapBuffer; private GLBufferTextureStorage? m_mapDataBuffer; private GLBufferTextureStorage? m_lineHeightsBuffer; - private byte[] m_lightBufferData = []; - private float[] m_mapBufferData = []; - private float[] m_lineHeightsBufferData = []; - - public static int GetLightBufferIndex(Side side, Wall wall, Sector sector) + public static int GetLightBufferIndex(Side side, Wall wall, Sector sector, out int overrideLightIndex) { // The shader will add the light level at this index plus the vertex light level. // Return LightBuffer.DarkIndex (lightlevel=0) to not add the sectors light level if absolute. - if (side.Flags.LightLevelAbsolute || wall.LightLevelAbsolute) - return LightBuffer.DarkIndex; - + overrideLightIndex = side.Flags.LightLevelAbsolute || wall.LightLevelAbsolute ? LightBuffer.DarkIndex + 1 : 0; return GetLightBufferIndex(sector, LightBufferType.Wall); } - public static int GetLightBufferIndex(Sector sector, SectorPlaneFace planeType, LightBufferType type) + public static int GetLightBufferIndex(Sector sector, SectorPlaneFace planeType, LightBufferType type, out int overrideLightIndex) { var transferLightSector = planeType == SectorPlaneFace.Floor ? sector.TransferFloorLightSector : sector.TransferCeilingLightSector; var plane = transferLightSector.GetSectorPlane(planeType); - - if (plane.LightLevelAbsolute) - return LightBuffer.DarkIndex; - + overrideLightIndex = plane.LightLevelAbsolute ? LightBuffer.DarkIndex + 1 : 0; return GetLightBufferIndex(sector, type); } @@ -73,18 +66,7 @@ public static int GetLightBufferIndex(Sector sector, LightBufferType type) }; } - public static int GetColorMapBufferIndex(Sector sector, LightBufferType type) - { - return type switch - { - LightBufferType.Floor => (sector.TransferFloorLightSector.Id + 1) * LightBuffer.BufferSize + LightBuffer.FloorOffset, - LightBufferType.Ceiling => (sector.TransferCeilingLightSector.Id + 1) * LightBuffer.BufferSize + LightBuffer.CeilingOffset, - LightBufferType.Wall => (sector.Id + 1) * LightBuffer.BufferSize + LightBuffer.WallOffset, - _ => sector.Id + 1, - }; - } - - public void UpdateToNewWorld(IWorld world) + public unsafe void UpdateToNewWorld(IWorld world) { m_lastDrawWorldCmd = default; m_updateLightSectors.ClearAndReset(); @@ -119,59 +101,16 @@ public void UpdateToNewWorld(IWorld world) var alloc = !m_world.SameAsPreviousMap; SetMapDataBuffer(world, alloc); - SetLightDataBuffer(world, alloc); - SetSectorColorMapsBuffer(world, alloc); - SetSectorFogBuffer(world, alloc); + m_sectorLightsBuffer = InitLightBuffer(world, alloc, m_sectorLightsBuffer, InitLightBuffer, "Sector light levels", SizedInternalFormat.R8ui); + m_sectorColorMapsBuffer = InitLightBuffer(world, alloc, m_sectorColorMapsBuffer, InitSectorColorMap, "Sector colormaps", SizedInternalFormat.Rgba32f); + m_sectorFogBuffer = InitLightBuffer(world, alloc, m_sectorFogBuffer, InitSectorFogBuffer, "Sector fog", SizedInternalFormat.Rgba32f); SetLineHeights(world, alloc); } - private unsafe void SetLightDataBuffer(IWorld world, bool alloc) - { - if (alloc || m_lightBufferStorage == null) - { - m_lightBufferStorage?.Dispose(); - m_lightBufferData = new byte[world.Sectors.Count * LightBuffer.BufferSize + LightBuffer.SectorIndexStart]; - m_lightBufferStorage = new("Sector lights texture buffer", m_lightBufferData, SizedInternalFormat.R8ui, GLInfo.MapPersistentBitSupported); - - m_lightBufferStorage.Map(data => - { - var lightBuffer = (byte*)data.ToPointer(); - SetLightBuffer(world, lightBuffer); - }); - } - else - { - var lightBuffer = m_lightBufferStorage.GetMappedBufferAndBind(); - SetLightBuffer(world, lightBuffer.MappedMemoryPtr); - m_lightBufferStorage.Unbind(); - } - } - - private unsafe void SetLightBuffer(IWorld world, byte* lightBuffer) - { - lightBuffer[LightBuffer.DarkIndex] = 0; - lightBuffer[LightBuffer.FullBrightIndex] = 255; - - for (int i = 0; i < LightBuffer.ColorMapCount; i++) - lightBuffer[LightBuffer.ColorMapStartIndex + i] = - (byte)(256 - ((LightBuffer.ColorMapCount - i) * 256 / LightBuffer.ColorMapCount)); - - for (int i = 0; i < world.Sectors.Count; i++) - { - Sector sector = world.Sectors[i]; - var lightLevel = (byte)Math.Clamp(sector.LightLevel, (short)0, (short)255); - int index = sector.Id * LightBuffer.BufferSize + LightBuffer.SectorIndexStart; - lightBuffer[index + LightBuffer.FloorOffset] = lightLevel; - lightBuffer[index + LightBuffer.CeilingOffset] = lightLevel; - lightBuffer[index + LightBuffer.WallOffset] = lightLevel; - } - } - private unsafe void SetLineHeights(IWorld world, bool alloc) { if (!world.Config.Render.VanillaRender) { - m_lineHeightsBufferData = []; m_lineHeightsBuffer?.Dispose(); m_lineHeightsBuffer = null; return; @@ -180,8 +119,7 @@ private unsafe void SetLineHeights(IWorld world, bool alloc) if (alloc || m_lineHeightsBuffer == null) { m_lineHeightsBuffer?.Dispose(); - m_lineHeightsBufferData = new float[world.Lines.Count * GLBufferTextureStorage.FourComponentLength]; - m_lineHeightsBuffer = new("Line heights data buffer", m_lineHeightsBufferData, SizedInternalFormat.Rgba32f, GLInfo.MapPersistentBitSupported); + m_lineHeightsBuffer = new("Line heights data buffer", new float[world.Lines.Count * GLBufferTextureStorage.FourComponentLength], SizedInternalFormat.Rgba32f, GLInfo.MapPersistentBitSupported); m_lineHeightsBuffer.Map(data => { @@ -207,65 +145,50 @@ private unsafe void SetLineHeights(IWorld world, bool alloc) } } - private unsafe void SetSectorColorMapsBuffer(IWorld world, bool alloc) + private static unsafe GLBufferTextureStorage InitLightBuffer(IWorld world, bool alloc, GLBufferTextureStorage? bufferStorage, + SetLightBufferPtrAction setAction, string name, SizedInternalFormat format) where T : struct { - if (alloc || m_sectorColorMapsBuffer == null) + if (alloc || bufferStorage == null) { - // First index will always map to default colormap - int sectorBufferCount = (world.Sectors.Count + 1) * LightBuffer.BufferSize; - // PaletteColorMode is index to colormap, true color will be RGB mix - int size = 4; - var sectorBuffer = new float[sectorBufferCount * size]; - - m_sectorColorMapsBuffer?.Dispose(); - m_sectorColorMapsBuffer = new("Sector colormaps", sectorBuffer, SizedInternalFormat.Rgba32f, GLInfo.MapPersistentBitSupported); - } + bufferStorage?.Dispose(); + bufferStorage = new(name, AllocLightSectorArray(world), format, GLInfo.MapPersistentBitSupported); - if (alloc) - { - m_sectorColorMapsBuffer.Map(data => + bufferStorage.Map(data => { - float* colorMapBuffer = (float*)data.ToPointer(); - InitSectorColorMap(world, colorMapBuffer); + var lightBuffer = (T*)data.ToPointer(); + setAction(world, lightBuffer); }); } else { - var mappedBuffer = m_sectorColorMapsBuffer.GetMappedBufferAndBind(); - float* colorMapBuffer = mappedBuffer.MappedMemoryPtr; - InitSectorColorMap(world, colorMapBuffer); - m_sectorColorMapsBuffer.Unbind(); + var lightBuffer = bufferStorage.GetMappedBufferAndBind(); + setAction(world, lightBuffer.MappedMemoryPtr); + bufferStorage.Unbind(); } + + return bufferStorage; } - private unsafe void SetSectorFogBuffer(IWorld world, bool alloc) + private static T[] AllocLightSectorArray(IWorld world) where T : struct { - if (alloc || m_sectorFogBuffer == null) - { - // First index will always map to default colormap - int sectorBufferCount = (world.Sectors.Count + 1) * LightBuffer.BufferSize; - // PaletteColorMode is index to colormap, true color will be RGB mix - int size = 4; - var sectorBuffer = new float[sectorBufferCount * size]; - - m_sectorFogBuffer?.Dispose(); - m_sectorFogBuffer = new("Sector fog", sectorBuffer, SizedInternalFormat.Rgba32f, GLInfo.MapPersistentBitSupported); - } + var sectorBufferCount = world.Sectors.Count * LightBuffer.BufferSize + LightBuffer.SectorIndexStart; + return new T[sectorBufferCount * GLBufferTextureStorage.FourComponentLength]; + } - if (alloc) - { - m_sectorFogBuffer.Map(data => - { - float* fogBuffer = (float*)data.ToPointer(); - InitSectorFogBuffer(world, fogBuffer); - }); - } - else + private unsafe void InitLightBuffer(IWorld world, byte* lightBuffer) + { + lightBuffer[LightBuffer.DarkIndex] = 0; + lightBuffer[LightBuffer.FullBrightIndex] = 255; + + for (int i = 0; i < LightBuffer.ColorMapCount; i++) + lightBuffer[LightBuffer.ColorMapStartIndex + i] = + (byte)(256 - ((LightBuffer.ColorMapCount - i) * 256 / LightBuffer.ColorMapCount)); + + for (int i = 0; i < world.Sectors.Count; i++) { - var mappedBuffer = m_sectorFogBuffer.GetMappedBufferAndBind(); - float* fadeBuffer = mappedBuffer.MappedMemoryPtr; - InitSectorFogBuffer(world, fadeBuffer); - m_sectorFogBuffer.Unbind(); + var sector = world.Sectors[i]; + var lightLevel = sector.GetByteLightLevel(); + SetSectorLight(lightBuffer, sector, lightLevel); } } @@ -293,13 +216,22 @@ private static unsafe void InitSectorFogBuffer(IWorld world, float* fadeBuffer) private static unsafe void SetSectorFog(float* fadeBuffer, int sectorId, Color fadeColor, short lightLevel, float fogDensity) { - int index = (sectorId + 1) * LightBuffer.BufferSize; - const int VectorSize = 4; - + var index = sectorId * LightBuffer.BufferSize + LightBuffer.SectorIndexStart; var fade = GetSectorFogDensity(fadeColor, lightLevel, fogDensity); - *(Vec4F*)&fadeBuffer[(index + LightBuffer.FloorOffset) * VectorSize] = fade; - *(Vec4F*)&fadeBuffer[(index + LightBuffer.CeilingOffset) * VectorSize] = fade; - *(Vec4F*)&fadeBuffer[(index + LightBuffer.WallOffset) * VectorSize] = fade; + + *(Vec4F*)&fadeBuffer[(index + LightBuffer.FloorOffset) * GLBufferTextureStorage.FourComponentLength] = fade; + *(Vec4F*)&fadeBuffer[(index + LightBuffer.CeilingOffset) * GLBufferTextureStorage.FourComponentLength] = fade; + *(Vec4F*)&fadeBuffer[(index + LightBuffer.WallOffset) * GLBufferTextureStorage.FourComponentLength] = fade; + } + + private static unsafe void SetSectorColorMap(float* colorMapBuffer, Sector sector, Colormap? colormap) + { + var index = sector.Id * LightBuffer.BufferSize + LightBuffer.SectorIndexStart; + var setColor = GetSectorSetColor(colormap); + + *(Vec3F*)&colorMapBuffer[(index + LightBuffer.FloorOffset) * GLBufferTextureStorage.FourComponentLength] = setColor; + *(Vec3F*)&colorMapBuffer[(index + LightBuffer.CeilingOffset) * GLBufferTextureStorage.FourComponentLength] = setColor; + *(Vec3F*)&colorMapBuffer[(index + LightBuffer.WallOffset) * GLBufferTextureStorage.FourComponentLength] = setColor; } private static Vec4F GetSectorFogDensity(Color fadeColor, short lightLevel, float fogDensity) @@ -316,18 +248,6 @@ private static Vec4F GetSectorFogDensity(Color fadeColor, short lightLevel, floa return new(fadeColor.R / 255f, fadeColor.G / 255f, fadeColor.B / 255f, fogDensity); } - private static unsafe void SetSectorColorMap(float* colorMapBuffer, Sector sector, Colormap? colormap) - { - int index = (sector.Id + 1) * LightBuffer.BufferSize; - - const int VectorSize = 4; - var setColor = GetSectorSetColor(colormap); - - *(Vec3F*)&colorMapBuffer[(index + LightBuffer.FloorOffset) * VectorSize] = setColor; - *(Vec3F*)&colorMapBuffer[(index + LightBuffer.CeilingOffset) * VectorSize] = setColor; - *(Vec3F*)&colorMapBuffer[(index + LightBuffer.WallOffset) * VectorSize] = setColor; - } - private static Vec3F GetSectorSetColor(Colormap? colormap) { // True color always uses rgb color mix. @@ -347,7 +267,6 @@ public unsafe void SetMapDataBuffer(IWorld world, bool alloc) { if (!world.Config.Render.VanillaRender) { - m_mapBufferData = []; m_mapDataBuffer?.Dispose(); m_mapDataBuffer = null; return; @@ -357,8 +276,7 @@ public unsafe void SetMapDataBuffer(IWorld world, bool alloc) return; m_mapDataBuffer?.Dispose(); - m_mapBufferData = new float[world.Lines.Count * 6]; - m_mapDataBuffer = new("Map data buffer", m_mapBufferData, SizedInternalFormat.Rgba32f, false); + m_mapDataBuffer = new("Map data buffer", new float[world.Lines.Count * 6], SizedInternalFormat.Rgba32f, false); m_mapDataBuffer.Map(data => { @@ -452,10 +370,10 @@ private void UpdateBuffers() private unsafe void UpdateLights() { - if (m_updateLightSectors.UpdateSectors.Length == 0 || m_lightBufferStorage == null || m_sectorFogBuffer == null) + if (m_updateLightSectors.UpdateSectors.Length == 0 || m_sectorLightsBuffer == null || m_sectorFogBuffer == null) return; - var lightBuffer = m_lightBufferStorage.GetMappedBufferAndBind(); + var lightBuffer = m_sectorLightsBuffer.GetMappedBufferAndBind(); var lightData = lightBuffer.MappedMemoryPtr; var fogBuffer = m_sectorFogBuffer.GetMappedBufferAndBind(); @@ -464,15 +382,21 @@ private unsafe void UpdateLights() for (int i = 0; i < m_updateLightSectors.UpdateSectors.Length; i++) { var sector = m_updateLightSectors.UpdateSectors[i]; - var level = (byte)Math.Clamp(sector.LightLevel, (short)0, (short)255); - var index = sector.Id * LightBuffer.BufferSize + LightBuffer.SectorIndexStart; - lightData[index + LightBuffer.FloorOffset] = level; - lightData[index + LightBuffer.CeilingOffset] = level; - lightData[index + LightBuffer.WallOffset] = level; - SetSectorFog(fogData, sector.Id, sector.FogColor, level, sector.FogDensity); + var lightLevel = sector.GetByteLightLevel(); + SetSectorLight(lightData, sector, lightLevel); + SetSectorFog(fogData, sector.Id, sector.FogColor, lightLevel, sector.FogDensity); } - m_lightBufferStorage.Unbind(); + m_sectorLightsBuffer.Unbind(); + m_sectorFogBuffer.Unbind(); + } + + private unsafe void SetSectorLight(byte* lightData, Sector sector, byte lightLevel) + { + var index = sector.Id * LightBuffer.BufferSize + LightBuffer.SectorIndexStart; + lightData[index + LightBuffer.FloorOffset] = lightLevel; + lightData[index + LightBuffer.CeilingOffset] = lightLevel; + lightData[index + LightBuffer.WallOffset] = lightLevel; } private unsafe void UpdateColorMaps() diff --git a/Core/Render/Renderer.cs b/Core/Render/Renderer.cs index da8c8b84d..72eb2ce03 100644 --- a/Core/Render/Renderer.cs +++ b/Core/Render/Renderer.cs @@ -633,7 +633,7 @@ private void BindSectorFogBuffer() private void BindLightBuffer() { - m_lightBufferStorage?.BindTexture(BindTextures.SectorLight); + m_sectorLightsBuffer?.BindTexture(BindTextures.SectorLight); } private void BindMapDataBuffer() @@ -981,7 +981,7 @@ protected virtual void Dispose(bool disposing) m_worldRenderer.Dispose(); m_framebufferRenderer.Dispose(); m_automapRenderer.Dispose(); - m_lightBufferStorage?.Dispose(); + m_sectorLightsBuffer?.Dispose(); m_sectorColorMapsBuffer?.Dispose(); m_sectorFogBuffer?.Dispose(); m_transitionRenderer?.Dispose(); diff --git a/Core/World/Geometry/Builder/UdmfGeometryBuilder.cs b/Core/World/Geometry/Builder/UdmfGeometryBuilder.cs index ba41cfb48..ded95e6ef 100644 --- a/Core/World/Geometry/Builder/UdmfGeometryBuilder.cs +++ b/Core/World/Geometry/Builder/UdmfGeometryBuilder.cs @@ -48,7 +48,7 @@ private static void PopulateSectorData(UdmfMap map, GeometryBuilder builder, Tex offsets.Scale.Y = mapSector.ScaleFloorY; var floorPlane = CreateSectorPlane(mapSector, SectorPlaneFace.Floor, textureManager, offsets); - floorPlane.LightLevel = mapSector.LightFloor; + floorPlane.LightLevelAdd = mapSector.LightFloor; floorPlane.LightLevelAbsolute = mapSector.LightFloorAbsolute; offsets = default; @@ -61,7 +61,7 @@ private static void PopulateSectorData(UdmfMap map, GeometryBuilder builder, Tex offsets.Scale.Y = mapSector.ScaleCeilingY; var ceilingPlane = CreateSectorPlane(mapSector, SectorPlaneFace.Ceiling, textureManager, offsets); - ceilingPlane.LightLevel = mapSector.LightCeiling; + ceilingPlane.LightLevelAdd = mapSector.LightCeiling; ceilingPlane.LightLevelAbsolute = mapSector.LightCeilingAbsolute; GetSectorSpecial(mapSector, needsTranslation, out var sectorSpecial, out var sectorData); diff --git a/Core/World/Geometry/Sectors/Sector.cs b/Core/World/Geometry/Sectors/Sector.cs index c48a61b82..01cd8623d 100644 --- a/Core/World/Geometry/Sectors/Sector.cs +++ b/Core/World/Geometry/Sectors/Sector.cs @@ -17,8 +17,10 @@ using Helion.World.Special; using Helion.World.Special.Specials; using Helion.World.Static; +using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; +using System.Runtime.CompilerServices; using static Helion.World.Entities.EntityManager; using Vector2D = Helion.Models.Vector2D; @@ -236,6 +238,9 @@ public bool CheckRenderingChanged(int gametick, bool checkTransferHeights = true public short FloorRenderLightLevel => TransferFloorLightSector.Floor.LightLevel; public short CeilingRenderLightLevel => TransferCeilingLightSector.Ceiling.LightLevel; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public byte GetByteLightLevel() => (byte)Math.Clamp(LightLevel, (short)0, (short)255); + public void SetFriction(double friction) { DataChanges |= SectorDataTypes.Friction; diff --git a/Core/World/Geometry/Sectors/SectorPlane.cs b/Core/World/Geometry/Sectors/SectorPlane.cs index c64199dcd..c4eeec069 100644 --- a/Core/World/Geometry/Sectors/SectorPlane.cs +++ b/Core/World/Geometry/Sectors/SectorPlane.cs @@ -23,6 +23,7 @@ public sealed class SectorPlane : ISoundSource public double PrevZ; public int TextureHandle; public short LightLevel; + public short LightLevelAdd; public int LastRenderChangeGametick; public int LastRenderGametick; public int Id; diff --git a/Tests/Unit/GameAction/Udmf/UdmfMap.cs b/Tests/Unit/GameAction/Udmf/UdmfMap.cs index 4d58927e8..071ae76bc 100644 --- a/Tests/Unit/GameAction/Udmf/UdmfMap.cs +++ b/Tests/Unit/GameAction/Udmf/UdmfMap.cs @@ -228,7 +228,8 @@ public void SectorProperties() sector.Ceiling.RenderOffsets.Offset.Y.Should().Be(48); sector.Ceiling.RenderOffsets.Scale.X.Should().Be(3); sector.Ceiling.RenderOffsets.Scale.Y.Should().Be(2); - sector.Ceiling.LightLevel.Should().Be(64); + sector.Ceiling.LightLevel.Should().Be(96); + sector.Ceiling.LightLevelAdd.Should().Be(64); sector.Ceiling.LightLevelAbsolute.Should().BeFalse(); sector.Ceiling.RenderOffsets.Rotate.Should().Be(MathHelper.ToRadians(160)); @@ -236,7 +237,8 @@ public void SectorProperties() sector.Floor.RenderOffsets.Offset.Y.Should().Be(24); sector.Floor.RenderOffsets.Scale.X.Should().Be(0.5); sector.Floor.RenderOffsets.Scale.Y.Should().Be(0.6); - sector.Floor.LightLevel.Should().Be(128); + sector.Floor.LightLevel.Should().Be(96); + sector.Floor.LightLevelAdd.Should().Be(128); sector.Floor.LightLevelAbsolute.Should().BeTrue(); sector.Floor.RenderOffsets.Rotate.Should().Be(MathHelper.ToRadians(45));