Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
f63a0c3
test 2d texture array
nstlaurent Sep 9, 2026
8a432e8
working test with flats
nstlaurent Sep 9, 2026
f34a2be
testing with walls
nstlaurent Sep 9, 2026
35ce80b
start using texture index in shader to merge texture array vbos
nstlaurent Sep 10, 2026
50951da
remove test code
nstlaurent Sep 10, 2026
2f05f47
move array texture lookup to gl texture manager
nstlaurent Sep 10, 2026
4df742c
support in flood fill
nstlaurent Sep 10, 2026
a2fe7c3
support texture arrays for dynamic rendering
nstlaurent Sep 10, 2026
4e554f4
fix lookup
nstlaurent Sep 10, 2026
0e7266e
move to GLTextureArrayBuilder and clear texture arrays on map change
nstlaurent Sep 10, 2026
3bdcf33
removing using
nstlaurent Sep 10, 2026
6b188de
move texture index to pack in surface options
nstlaurent Sep 11, 2026
814e5f4
correct separation for clamped array textures
nstlaurent Sep 11, 2026
f522747
make free geometry manager aware of array textures
nstlaurent Sep 11, 2026
5d7b02f
add missing calls to disable dynamic buffering
nstlaurent Sep 11, 2026
c3cce72
remove todo
nstlaurent Sep 11, 2026
bdc5501
also load switch textures
nstlaurent Sep 11, 2026
737f3fe
fix reupload, cleanup
nstlaurent Sep 11, 2026
f8f8884
Merge branch 'dev' into 2d-texture-array
nstlaurent Sep 11, 2026
7476cbe
add draw counters to profiler
nstlaurent Sep 11, 2026
4955255
move log to debug
nstlaurent Sep 11, 2026
321fe86
ensure store is set in rotation
nstlaurent Sep 11, 2026
5b0e629
fix remaining boundTextureIndex variables
nstlaurent Sep 11, 2026
f928660
corect samplers for brightmap
nstlaurent Sep 12, 2026
ea7f5fe
exclude brightmaps from array textures
nstlaurent Sep 12, 2026
38739bd
add boundTextureIndex as constants since they aren't used in entity/h…
nstlaurent Sep 12, 2026
5c10805
add hud elements draw tracking and drawcounts command
nstlaurent Sep 12, 2026
08cf14f
add count functions
nstlaurent Sep 12, 2026
9153913
correct brightmap clear texture binds
nstlaurent Sep 12, 2026
33833e3
refactor so array textures have context for future use and use ArrayT…
nstlaurent Sep 12, 2026
35d4700
flag if cached
nstlaurent Sep 12, 2026
2ead519
pass through context
nstlaurent Sep 13, 2026
c2e0ded
refactor to use texture directly
nstlaurent Sep 13, 2026
7967fcf
start work for sprites
nstlaurent Sep 13, 2026
b7cb3cd
fix lookup and refactor to use based off flags
nstlaurent Sep 13, 2026
030c27a
add bucket code
nstlaurent Sep 13, 2026
ebb8729
pad images
nstlaurent Sep 13, 2026
64f10d2
it works
nstlaurent Sep 14, 2026
e29f8a7
fix z offset
nstlaurent Sep 14, 2026
1ce507b
start with 32 bucket
nstlaurent Sep 14, 2026
0c94efe
store max index in bucket, refactor to ui
nstlaurent Sep 14, 2026
2e9cef0
use single fit image, move brightmap sprites to overflow bucket
nstlaurent Sep 14, 2026
38ccd34
fix flag
nstlaurent Sep 14, 2026
59d5c7d
fix for non bucketed textures
nstlaurent Sep 14, 2026
3a5819e
pack array index / texture dim index to single float
nstlaurent Sep 14, 2026
dbce4bf
remove using
nstlaurent Sep 14, 2026
bd1af95
correct healthbars
nstlaurent Sep 14, 2026
2b18d5e
refactor to pack dimensions with array index into single float proper…
nstlaurent Sep 14, 2026
682acc4
limit bucket sizes to MaxArrayLayers
nstlaurent Sep 14, 2026
57eb79b
update release notes
nstlaurent Sep 15, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions Client/Client.Commands.cs
Original file line number Diff line number Diff line change
Expand Up @@ -657,6 +657,21 @@ private void Use(ConsoleCommandEventArgs args) =>
private static void GarbageCollect(ConsoleCommandEventArgs args) =>
GCUtil.ForceGarbageCollection();

[ConsoleCommand("drawcounts", "Logs the draw counts of the renderer.")]
private void DrawCounts(ConsoleCommandEventArgs args)
{
ref var counts = ref m_window.Renderer.LastDrawCounts;
HelionLog.Info($"GeometryStatic: {counts.GeometryStatic}");
HelionLog.Info($"GeometryDynamic: {counts.GeometryDynamic}");
HelionLog.Info($"FloodFillStatic: {counts.FloodFillStatic}");
HelionLog.Info($"FloodFillDynamic: {counts.FloodFillDynamic}");
HelionLog.Info($"Skies: {counts.Skies}");
HelionLog.Info($"Sprites: {counts.Sprites}");
HelionLog.Info($"HudElements: {counts.HudElements}");
HelionLog.Info($"Level Total: {counts.LevelTotal()}");
HelionLog.Info($"Total: {counts.Total()}");
}

private void DoUseCommand(ConsoleCommandEventArgs args)
{
if (m_layerManager.WorldLayer == null || args.Args.Count == 0)
Expand Down
1 change: 0 additions & 1 deletion Client/Client.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using static Helion.Util.Assertion.Assert;

Expand Down
21 changes: 20 additions & 1 deletion Core/Graphics/Image.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using Helion.Geometry.Vectors;
using Helion.Graphics.Palettes;
using Helion.Resources;
using Helion.Util.Assertion;
using Helion.Util.Extensions;
using SixLabors.ImageSharp.PixelFormats;
using System;
Expand Down Expand Up @@ -30,7 +31,7 @@ public class Image
public Dimension Dimension;
public ImageType ImageType;
public ImageType UploadType;
public readonly Vec2I Offset;
public Vec2I Offset;
public readonly ResourceNamespace Namespace;
public uint[] m_pixels; // Stored as argb with a = high byte, b = low byte
public readonly byte[] m_indices;
Expand Down Expand Up @@ -407,6 +408,24 @@ public void SetPixel(int x, int y, Color color, Palette palette)
}
}

public void CopyPixelsFrom(Image image)
{
Precondition(!(image.Indices.Length > 0 && Indices.Length == 0), "Image type mismatch");

var width = Math.Min(image.Dimension.Width, Dimension.Width);
var height = Math.Min(image.Dimension.Height, Dimension.Height);

for (int x = 0; x < width; x++)
{
for (int y = 0; y < height; y++)
{
SetPixel(x, y, image.GetPixel(x, y));
if (image.ImageType == ImageType.PaletteWithArgb)
SetIndex(x, y, image.GetIndex(x, y));
}
}
}

public void ConvertToGrayscale(bool normalize)
{
if (ImageType == ImageType.Palette)
Expand Down
7 changes: 7 additions & 0 deletions Core/Render/OpenGL/Context/GLInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,18 @@ public static class GLInfo
public static bool MapPersistentBitSupported = true;
public static bool MemoryBarrierSupported = true;
public static bool DebugLabel;
public static int MaxArrayLayers;

static GLInfo()
{
Renderer = GL.GetString(StringName.Renderer);
ShadingVersion = GL.GetString(StringName.ShadingLanguageVersion);
Vendor = GL.GetString(StringName.Vendor);
MaxArrayLayers = GetMaxArrayLayers();
}
public static int GetMaxArrayLayers()
{
GL.GetInteger(GetPName.MaxArrayTextureLayers, out var maxLayers);
return maxLayers;
}
}
8 changes: 6 additions & 2 deletions Core/Render/OpenGL/Renderers/Legacy/Hud/LegacyHudRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
using Helion.Resources.Definitions.Zdoom;
using Helion.Util;
using Helion.Util.Configs;
using Helion.Util.Profiling.Timers;
using OpenTK.Graphics.OpenGL;
using static Helion.Util.Assertion.Assert;

Expand All @@ -25,12 +26,14 @@ public class LegacyHudRenderer : HudRenderer
private readonly LegacyHudShader m_program;
private readonly HudDrawBuffer m_drawBuffer;
private readonly IConfig m_config;
private readonly RenderProfiler m_renderProfiler;
private float DrawDepth = 1.0f;

public LegacyHudRenderer(IConfig config, LegacyGLTextureManager textureManager, DataCache dataCache)
public LegacyHudRenderer(IConfig config, LegacyGLTextureManager textureManager, DataCache dataCache, RenderProfiler renderProfiler)
{
m_config = config;
m_textureManager = textureManager;
m_renderProfiler = renderProfiler;
m_program = new();
m_pipeline = new(m_program, new StreamVertexBuffer<HudVertex>("Hud"), "Hud");
m_drawBuffer = new(dataCache);
Expand Down Expand Up @@ -175,9 +178,10 @@ public override void Render(Rectangle viewport, Dimension windowDimension, Dimen
if (data.BrightmapTexture != null)
data.BrightmapTexture.Bind();
else
GL.BindTexture(TextureTarget.Texture2D, 0);
GL.BindTexture(data.Texture.Target, 0);
m_pipeline.DrawArrays();
data.Texture.Unbind();
m_renderProfiler.DrawCounts.HudElements++;
}

m_pipeline.Unbind();
Expand Down
10 changes: 6 additions & 4 deletions Core/Render/OpenGL/Renderers/Legacy/Hud/LegacyHudShader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ private static string GetBrightmapColorBlend()

return @"
if (useBrightmaps == 1)
fragColor.rgb *= mix(vec3(1.0), min(vec3(1.0), texture(brightmapTexture, uvFrag.st).rgb + rgbMultiplierFrag.rgb), rgbMultiplierFrag.w);
fragColor.rgb *= mix(vec3(1.0), min(vec3(1.0), texture(brightmapTexture, vec3(uvFrag.st, 0)).rgb + rgbMultiplierFrag.rgb), rgbMultiplierFrag.w);
else
fragColor.xyz *= mix(vec3(1.0), rgbMultiplierFrag.xyz, rgbMultiplierFrag.w);";
}
Expand All @@ -129,9 +129,9 @@ private static string GetBrightmapColorBlend()

out vec4 fragColor;

uniform sampler2D boundTexture;
uniform sampler2DArray boundTexture;
uniform sampler2D opaqueTexture;
uniform sampler2D brightmapTexture;
uniform sampler2DArray brightmapTexture;
uniform samplerBuffer colormapTexture;
uniform float fuzzFrac;
uniform float fuzzDiv;
Expand All @@ -145,10 +145,12 @@ private static string GetBrightmapColorBlend()
uniform vec2 fuzzSampleOffset;
uniform int fuzzRefraction;

const int boundTextureIndex = 0;

${FuzzFunction}

void main() {
fragColor = texture(boundTexture, uvFrag.st);
fragColor = texture(boundTexture, vec3(uvFrag.st, 0));
${ColorMapFetch}
${AlphaFlag}
fragColor.w *= alphaFrag;
Expand Down
7 changes: 4 additions & 3 deletions Core/Render/OpenGL/Renderers/Legacy/World/Data/RenderData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,24 +45,25 @@ public void Clear()
Pipeline.Clear();
}

public void Draw()
public bool Draw()
{
if (Pipeline.Empty)
return;
return false;

GL.ActiveTexture(BindTextures.BoundTexture);
Texture.Bind();
GL.ActiveTexture(BindTextures.BrightmapTexture);
if (BrightMapTexture != null)
BrightMapTexture.Bind();
else
GL.BindTexture(TextureTarget.Texture2D, 0);
GL.BindTexture(Texture.Target, 0);

Pipeline.Bind(true);
Pipeline.Vbo.Upload();
Pipeline.Vbo.DrawArraysInstanced(PrimitiveType.TriangleStrip, 0, 4);

Texture.Unbind();
return true;
}

protected virtual void Dispose(bool disposing)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,15 @@ public class RenderDataCollection<[DynamicallyAccessedMembers(DynamicallyAccesse
private readonly DynamicArray<RenderData<TVertex>> m_dataToRender = new(2048);
private readonly RenderProgram m_program;
private readonly RenderDataPool<TVertex> m_renderDataPool;
private readonly Action? m_onDraw;
private int m_renderCount;
private bool m_disposed;

public RenderDataCollection(RenderProgram program, RenderDataPool<TVertex> renderDataPool)
public RenderDataCollection(RenderProgram program, RenderDataPool<TVertex> renderDataPool, Action? onDraw = null)
{
m_program = program;
m_renderDataPool = renderDataPool;
m_onDraw = onDraw;
}

~RenderDataCollection()
Expand Down Expand Up @@ -72,7 +74,10 @@ public void Render()
return;

for (int i = 0; i < m_dataToRender.Length; i++)
m_dataToRender[i].Draw();
{
if (m_dataToRender[i].Draw())
m_onDraw?.Invoke();
}
}

protected virtual void Dispose(bool disposing)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,18 @@ public class RenderDataManager<[DynamicallyAccessedMembers(DynamicallyAccessedMe

private readonly RenderDataCollection<TVertex>[] m_renderDataStyles;
private readonly RenderData<TVertex> m_healthBarData;
private readonly Action? m_onDraw;
private bool m_disposed;

public RenderDataManager(RenderProgram program, GLLegacyTexture healthBarTexture, RenderDataPool<TVertex> renderDataPool)
public RenderDataManager(RenderProgram program, GLLegacyTexture healthBarTexture, RenderDataPool<TVertex> renderDataPool, Action? onDraw = null)
{
Assert.Precondition(RenderStyleLookup.Length == (int)RenderStyle.Count, "Render style lookup size mismatch");
m_renderDataStyles = new RenderDataCollection<TVertex>[(int)RenderDataStyle.Count];
for (int i = 0; i < m_renderDataStyles.Length; i++)
m_renderDataStyles[i] = new(program, renderDataPool);
m_renderDataStyles[i] = new(program, renderDataPool, onDraw);

m_healthBarData = new(program, healthBarTexture);
m_onDraw = onDraw;
}

~RenderDataManager()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,10 @@ public void Clear()
Pipeline.Clear();
}

public void Draw()
public bool Draw()
{
if (Pipeline.Empty)
return;
return false;

// We are doing binding manually since apparently these are all
// coming up in the memory profiler as a bunch of new 'actions'.
Expand All @@ -57,13 +57,14 @@ public void Draw()
if (BrightmapTexture != null)
BrightmapTexture.Bind();
else
GL.BindTexture(TextureTarget.Texture2D, 0);
GL.BindTexture(Texture.Target, 0);

Pipeline.Bind(true);
Pipeline.Vbo.Upload();
Pipeline.DrawArrays();
Pipeline.Unbind();
Texture.Unbind();
return true;
}

public void Dispose()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
using Helion.Render.OpenGL.Shader;
using Helion.Render.OpenGL.Texture.Legacy;
using Helion.Render.OpenGL.Texture.Legacy;
using Helion.Util.Container;
using System;
using System.Collections.Generic;

namespace Helion.Render.OpenGL.Renderers.Legacy.World.Data;

public class RenderWorldDataList(RenderWorldDataPool pool)
public class RenderWorldDataList(RenderWorldDataPool pool, Action? onDraw)
{
public List<RenderWorldData> RenderData = [];
private RenderWorldData?[] m_allRenderData = new RenderWorldData?[1024];
private readonly DynamicArray<RenderWorldData> m_dataToRender = new(1024);
private readonly RenderWorldDataPool m_pool = pool;
private readonly Action? m_onDraw = onDraw;
private int m_renderCount;

public void Reset()
Expand Down Expand Up @@ -60,7 +60,10 @@ public RenderWorldData Add(GLLegacyTexture texture, GLLegacyTexture? brightmapTe
public void Draw()
{
for (int i = 0; i < m_dataToRender.Length; i++)
m_dataToRender[i].Draw();
{
if (m_dataToRender[i].Draw())
m_onDraw?.Invoke();
}
}

public void Clear()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,21 @@ public sealed class RenderWorldDataManager : StyleRendererBase, IDisposable
{
private readonly RenderWorldDataPool m_pool;
private readonly GeometryTypeLookup<RenderWorldDataList> m_lookup;
private readonly Action? m_onDraw;
private RenderWorldData? m_coverWalls;

public bool BufferCoverWalls = true;

public RenderWorldDataManager(RenderProgram program)
public RenderWorldDataManager(RenderProgram program, Action? onDraw)
{
m_pool = new(program, 1024);
m_onDraw = onDraw;
m_lookup = new(AllocateDataList);
}

private RenderWorldDataList AllocateDataList()
{
return new RenderWorldDataList(m_pool);
return new RenderWorldDataList(m_pool, m_onDraw);
}

public void Reset()
Expand Down
Loading
Loading