diff --git a/src/render/SubChunkRenderer.cs b/src/render/SubChunkRenderer.cs
index bf3cd03..5736be9 100644
--- a/src/render/SubChunkRenderer.cs
+++ b/src/render/SubChunkRenderer.cs
@@ -153,7 +153,7 @@ public void Dispose() {
/// TODO store the number of blocks in the chunksection and only allocate the vertex list up to that length
///
public void meshChunk() {
- sw.Restart();
+ //sw.Restart();
if (subChunk.world.renderer.fastChunkSwitch) {
vao?.Dispose();
vao = new ExtremelySharedBlockVAO(subChunk.world.renderer.chunkVAO);
@@ -207,7 +207,7 @@ public void meshChunk() {
var finalVertices = CollectionsMarshal.AsSpan(chunkVertices);
var finalIndices = CollectionsMarshal.AsSpan(chunkIndices);
vao.upload(finalVertices, finalIndices);
- Console.Out.WriteLine($"PartMeshing1.2: {sw.Elapsed.TotalMicroseconds}us {chunkIndices.Count}");
+ //Console.Out.WriteLine($"PartMeshing1.2: {sw.Elapsed.TotalMicroseconds}us {chunkIndices.Count}");
}
else {
hasRenderOpaque = false;
@@ -238,11 +238,11 @@ public void meshChunk() {
}
}
//}
- Console.Out.WriteLine($"Meshing: {sw.Elapsed.TotalMicroseconds}us {chunkIndices.Count}");
+ //Console.Out.WriteLine($"Meshing: {sw.Elapsed.TotalMicroseconds}us {chunkIndices.Count}");
//if (!subChunk.isEmpty && !hasRenderOpaque && !hasRenderTranslucent) {
// Console.Out.WriteLine($"CHUNKDATA: {subChunk.blocks.blockCount} {subChunk.blocks.isFull()}");
//}
- sw.Stop();
+ //sw.Stop();
}
@@ -629,10 +629,10 @@ static byte getLightFromCacheUnsafe(ref byte arrayBase, int x, int y, int z) {
// only apply AO if enabled
if ((settings & SETTING_AO) != 0 && !facesRef.noAO) {
- ao.First = (byte)(o.First == 3 ? 3 : byte.PopCount((byte)(o.First & 7)));
- ao.Second = (byte)((o.Second & 3) == 3 ? 3 : byte.PopCount((byte)(o.Second & 7)));
- ao.Third = (byte)((o.Third & 3) == 3 ? 3 : byte.PopCount((byte)(o.Third & 7)));
- ao.Fourth = (byte)((o.Fourth & 3) == 3 ? 3 : byte.PopCount((byte)(o.Fourth & 7)));
+ ao.First = (byte)(o.First == 3 ? 3 : byte.PopCount(o.First));
+ ao.Second = (byte)((o.Second & 3) == 3 ? 3 : byte.PopCount(o.Second));
+ ao.Third = (byte)((o.Third & 3) == 3 ? 3 : byte.PopCount(o.Third));
+ ao.Fourth = (byte)((o.Fourth & 3) == 3 ? 3 : byte.PopCount(o.Fourth));
}
// if face is noAO, don't average....
@@ -643,30 +643,10 @@ static byte getLightFromCacheUnsafe(ref byte arrayBase, int x, int y, int z) {
var n = l.AsUInt32();
// split light and reassemble it again
- light.First = (byte)(
- average((n[0] >> 4) & 0x0F0F0F0F,
- (byte)(o.First & 7))
- << 4 |
- average(n[0] & 0x0F0F0F0F,
- (byte)(o.First & 7)));
- light.Second = (byte)(
- average((n[1] >> 4) & 0x0F0F0F0F,
- (byte)(o.Second & 7))
- << 4 |
- average(n[1] & 0x0F0F0F0F,
- (byte)(o.Second & 7)));
- light.Third = (byte)(
- average((n[2] >> 4) & 0x0F0F0F0F,
- (byte)(o.Third & 7))
- << 4 |
- average(n[2] & 0x0F0F0F0F,
- (byte)(o.Third & 7)));
- light.Fourth = (byte)(
- average((n[3] >> 4) & 0x0F0F0F0F,
- (byte)(o.Fourth & 7))
- << 4 |
- average(n[3] & 0x0F0F0F0F,
- (byte)(o.Fourth & 7)));
+ light.First = average2(n[0], o.First);
+ light.Second = average2(n[1], o.Second);
+ light.Third = average2(n[2], o.Third);
+ light.Fourth = average2(n[3], o.Fourth);
}
//}
}
@@ -809,6 +789,34 @@ public static byte average(uint lightNibble, byte oFlags) {
/ (BitOperations.PopCount((byte)(inv & 0x7)) + 1));
}
+ ///
+ /// average but does blocklight and skylight at once
+ ///
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static byte average2(uint lightNibble, byte oFlags) {
+ if (oFlags < 3) {
+ // set the 4 bit of oFlags to 0 because it is visible then
+ oFlags &= 3;
+ }
+
+ // (byte.PopCount((byte)(~oFlags & 0x7)) is "inverse popcount" - count the number of 0s in the byte
+ // (~oFlags & 1) is 1 if the first bit is 0, 0 otherwise
+ var inv = ~oFlags;
+ var popcnt = BitOperations.PopCount((byte)(inv & 0x7)) + 1;
+ var sky = (byte)(((lightNibble & 0xF) * (inv & 1) +
+ (lightNibble >> 8 & 0xF) * ((inv & 2) >> 1) +
+ (lightNibble >> 16 & 0xF) * ((inv & 4) >> 2) +
+ (lightNibble >> 24 & 0xF))
+ / popcnt);
+
+ var block = (byte)(((lightNibble >> 4 & 0xF) * (inv & 1) +
+ (lightNibble >> 12 & 0xF) * ((inv & 2) >> 1) +
+ (lightNibble >> 20 & 0xF) * ((inv & 4) >> 2) +
+ (lightNibble >> 28 & 0xF))
+ / popcnt);
+ return (byte)(sky | block << 4);
+ }
+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void addAO(int x, int y, int z, int x1, int y1, int z1, out int x2, out int y2, out int z2) {
x2 = x + x1;
diff --git a/src/ui/GUI.cs b/src/ui/GUI.cs
index cf4d766..96efe06 100644
--- a/src/ui/GUI.cs
+++ b/src/ui/GUI.cs
@@ -231,6 +231,7 @@ public void drawString3D(ReadOnlySpan text, Vector3 position, Vector3 rota
var mat = flip * rot * Matrix4x4.CreateScale(1 / 256f * scale) * Matrix4x4.CreateTranslation(position);
Game.fontLoader.renderer3D.setMatrix(ref mat);
guiFontThin.DrawText(Game.fontLoader.renderer3D, text, new Vector2(0, 0), colour == default ? FSColor.White : colour.toFS());
+ Game.fontLoader.renderer3D.flush();
}
public void drawStringOnBlock(ReadOnlySpan text, Vector3D pos, RawDirection face, float scale, Color4b colour = default) {
diff --git a/src/util/font/TextRenderer3D.cs b/src/util/font/TextRenderer3D.cs
index 02331a2..2b7dcfa 100644
--- a/src/util/font/TextRenderer3D.cs
+++ b/src/util/font/TextRenderer3D.cs
@@ -38,13 +38,21 @@ public void renderTick(double interp) {
}
public void begin() {
- tb.Begin(BatcherBeginMode.Immediate);
+ tb.Begin();
}
public void end() {
tb.End();
}
+ ///
+ /// Finish drawing text.
+ ///
+ public void flush() {
+ tb.End();
+ tb.Begin();
+ }
+
public void Draw(object texture, Vector2 pos, Rectangle? src, FSColor color, float rotation, Vector2 scale, float depth) {
var tex = (Texture2D)texture;
var intPos = new Vector2((int)pos.X, (int)pos.Y);