From 787dc88c43728ddd9e93bd1bbc37cde70eeded33 Mon Sep 17 00:00:00 2001 From: mcrcortex <18544518+MCRcortex@users.noreply.github.com> Date: Mon, 29 Jan 2024 12:35:09 +1000 Subject: [PATCH] Finished GeometryManager and added AABB raster support --- .../client/core/model/ModelManager.java | 2 +- .../rendering/AbstractFarWorldRenderer.java | 1 - .../core/rendering/GeometryManager.java | 30 ++++++---------- .../client/core/rendering/RenderTracker.java | 21 ++++++----- .../core/rendering/building/BuiltSection.java | 36 +++++++++++++------ .../building/BuiltSectionGeometry.java | 21 ----------- .../rendering/building/RenderDataFactory.java | 4 +-- .../zenith/shaders/lod/gl46/bindings.glsl | 8 ++--- .../zenith/shaders/lod/gl46/cmdgen.comp | 6 ++-- .../zenith/shaders/lod/gl46/cull/raster.vert | 9 +++-- .../zenith/shaders/lod/gl46/section.glsl | 8 +++-- 11 files changed, 69 insertions(+), 77 deletions(-) delete mode 100644 src/main/java/me/cortex/zenith/client/core/rendering/building/BuiltSectionGeometry.java diff --git a/src/main/java/me/cortex/zenith/client/core/model/ModelManager.java b/src/main/java/me/cortex/zenith/client/core/model/ModelManager.java index d6fa3119..86fb24a5 100644 --- a/src/main/java/me/cortex/zenith/client/core/model/ModelManager.java +++ b/src/main/java/me/cortex/zenith/client/core/model/ModelManager.java @@ -361,6 +361,6 @@ public class ModelManager { } public void addDebugInfo(List info) { - + info.add("BlockModels registered: " + this.modelTexture2id.size() + "/" + (1<<16)); } } diff --git a/src/main/java/me/cortex/zenith/client/core/rendering/AbstractFarWorldRenderer.java b/src/main/java/me/cortex/zenith/client/core/rendering/AbstractFarWorldRenderer.java index 9c634147..fba5ec49 100644 --- a/src/main/java/me/cortex/zenith/client/core/rendering/AbstractFarWorldRenderer.java +++ b/src/main/java/me/cortex/zenith/client/core/rendering/AbstractFarWorldRenderer.java @@ -6,7 +6,6 @@ package me.cortex.zenith.client.core.rendering; import me.cortex.zenith.client.core.gl.GlBuffer; import me.cortex.zenith.client.core.model.ModelManager; import me.cortex.zenith.client.core.rendering.building.BuiltSection; -import me.cortex.zenith.client.core.rendering.building.BuiltSectionGeometry; import me.cortex.zenith.client.core.rendering.util.UploadStream; import net.minecraft.client.MinecraftClient; import net.minecraft.client.render.Camera; diff --git a/src/main/java/me/cortex/zenith/client/core/rendering/GeometryManager.java b/src/main/java/me/cortex/zenith/client/core/rendering/GeometryManager.java index cd7307e4..956296b6 100644 --- a/src/main/java/me/cortex/zenith/client/core/rendering/GeometryManager.java +++ b/src/main/java/me/cortex/zenith/client/core/rendering/GeometryManager.java @@ -5,7 +5,6 @@ import it.unimi.dsi.fastutil.longs.LongArrayList; import it.unimi.dsi.fastutil.objects.ObjectArrayList; import me.cortex.zenith.client.core.gl.GlBuffer; import me.cortex.zenith.client.core.rendering.building.BuiltSection; -import me.cortex.zenith.client.core.rendering.building.BuiltSectionGeometry; import me.cortex.zenith.client.core.rendering.util.BufferArena; import me.cortex.zenith.client.core.rendering.util.UploadStream; import org.lwjgl.system.MemoryUtil; @@ -33,7 +32,7 @@ public class GeometryManager { void uploadResults() { while (!this.buildResults.isEmpty()) { var result = this.buildResults.pop(); - boolean isDelete = result.opaque == null && result.translucent == null; + boolean isDelete = result.geometryBuffer == null; if (isDelete) { int id = -1; if ((id = this.pos2id.remove(result.position)) != -1) { @@ -142,36 +141,29 @@ public class GeometryManager { //TODO: pack the offsets of each axis so that implicit face culling can work //Note! the opaquePreDataCount and translucentPreDataCount are never writen to the meta buffer, as they are indexed in reverse relative to the base opaque and translucent geometry - private record SectionMeta(long position, int aabb, int opaqueGeometryPtr, int count, int translucentGeometryPtr) { + private record SectionMeta(long position, int aabb, int geometryPtr, int size, int[] offsets) { public void writeMetadata(long ptr) { //THIS IS DUE TO ENDIANNESS and that we are splitting a long into 2 ints MemoryUtil.memPutInt(ptr, (int) (this.position>>32)); ptr += 4; MemoryUtil.memPutInt(ptr, (int) this.position); ptr += 4; MemoryUtil.memPutInt(ptr, (int) this.aabb); ptr += 4; - ptr += 4; + MemoryUtil.memPutInt(ptr, this.geometryPtr + this.offsets[0]); ptr += 4; - MemoryUtil.memPutInt(ptr, this.opaqueGeometryPtr); ptr += 4; - MemoryUtil.memPutInt(ptr, this.count); ptr += 4; - - //MemoryUtil.memPutInt(ptr, (int) this.translucentGeometryPtr + this.translucentPreDataCount); ptr += 4; - //MemoryUtil.memPutInt(ptr, this.translucentQuadCount); ptr += 4; + MemoryUtil.memPutInt(ptr, (this.offsets[1]-this.offsets[0])|((this.offsets[2]-this.offsets[1])<<16)); ptr += 4; + MemoryUtil.memPutInt(ptr, (this.offsets[3]-this.offsets[2])|((this.offsets[4]-this.offsets[3])<<16)); ptr += 4; + MemoryUtil.memPutInt(ptr, (this.offsets[5]-this.offsets[4])|((this.offsets[6]-this.offsets[5])<<16)); ptr += 4; + MemoryUtil.memPutInt(ptr, (this.offsets[7]-this.offsets[6])|((this.size -this.offsets[7])<<16)); ptr += 4; } } private SectionMeta createMeta(BuiltSection geometry) { - int geometryPtr = (int) this.geometryBuffer.upload(geometry.opaque.buffer()); - - //TODO: support translucent geometry - //return new SectionMeta(geometry.position, 0, geometryPtr, (int) (geometry.opaque.buffer().size/8), 0, -1,0, 0); - return new SectionMeta(geometry.position, 0, geometryPtr, (int) (geometry.opaque.buffer().size/8), -1); + int geometryPtr = (int) this.geometryBuffer.upload(geometry.geometryBuffer); + return new SectionMeta(geometry.position, geometry.aabb, geometryPtr, (int) (geometry.geometryBuffer.size/8), geometry.offsets); } private void freeMeta(SectionMeta meta) { - if (meta.opaqueGeometryPtr != -1) { - this.geometryBuffer.free(meta.opaqueGeometryPtr); - } - if (meta.translucentGeometryPtr != -1) { - this.geometryBuffer.free(meta.translucentGeometryPtr); + if (meta.geometryPtr != -1) { + this.geometryBuffer.free(meta.geometryPtr); } } diff --git a/src/main/java/me/cortex/zenith/client/core/rendering/RenderTracker.java b/src/main/java/me/cortex/zenith/client/core/rendering/RenderTracker.java index 71606601..fa7fbb76 100644 --- a/src/main/java/me/cortex/zenith/client/core/rendering/RenderTracker.java +++ b/src/main/java/me/cortex/zenith/client/core/rendering/RenderTracker.java @@ -1,7 +1,6 @@ package me.cortex.zenith.client.core.rendering; import me.cortex.zenith.client.core.rendering.building.BuiltSection; -import me.cortex.zenith.client.core.rendering.building.BuiltSectionGeometry; import me.cortex.zenith.client.core.rendering.building.RenderGenerationService; import me.cortex.zenith.common.world.WorldEngine; import me.cortex.zenith.common.world.WorldSection; @@ -42,7 +41,7 @@ public class RenderTracker { //Removes a lvl 0 section from the world renderer public void remLvl0(int x, int y, int z) { this.activeSections.remove(WorldEngine.getWorldSectionId(0, x, y, z)); - this.renderer.enqueueResult(new BuiltSection(WorldEngine.getWorldSectionId(0, x, y, z), null, null)); + this.renderer.enqueueResult(new BuiltSection(WorldEngine.getWorldSectionId(0, x, y, z))); this.renderGen.removeTask(0, x, y, z); } @@ -64,14 +63,14 @@ public class RenderTracker { this.renderGen.enqueueTask(lvl, x, y, z, this::shouldStillBuild, this::getBuildFlagsOrAbort); - this.renderer.enqueueResult(new BuiltSection(WorldEngine.getWorldSectionId(lvl-1, (x<<1), (y<<1), (z<<1)), null, null)); - this.renderer.enqueueResult(new BuiltSection(WorldEngine.getWorldSectionId(lvl-1, (x<<1), (y<<1), (z<<1)+1), null, null)); - this.renderer.enqueueResult(new BuiltSection(WorldEngine.getWorldSectionId(lvl-1, (x<<1), (y<<1)+1, (z<<1)), null, null)); - this.renderer.enqueueResult(new BuiltSection(WorldEngine.getWorldSectionId(lvl-1, (x<<1), (y<<1)+1, (z<<1)+1), null, null)); - this.renderer.enqueueResult(new BuiltSection(WorldEngine.getWorldSectionId(lvl-1, (x<<1)+1, (y<<1), (z<<1)), null, null)); - this.renderer.enqueueResult(new BuiltSection(WorldEngine.getWorldSectionId(lvl-1, (x<<1)+1, (y<<1), (z<<1)+1), null, null)); - this.renderer.enqueueResult(new BuiltSection(WorldEngine.getWorldSectionId(lvl-1, (x<<1)+1, (y<<1)+1, (z<<1)), null, null)); - this.renderer.enqueueResult(new BuiltSection(WorldEngine.getWorldSectionId(lvl-1, (x<<1)+1, (y<<1)+1, (z<<1)+1), null, null)); + this.renderer.enqueueResult(new BuiltSection(WorldEngine.getWorldSectionId(lvl-1, (x<<1), (y<<1), (z<<1)))); + this.renderer.enqueueResult(new BuiltSection(WorldEngine.getWorldSectionId(lvl-1, (x<<1), (y<<1), (z<<1)+1))); + this.renderer.enqueueResult(new BuiltSection(WorldEngine.getWorldSectionId(lvl-1, (x<<1), (y<<1)+1, (z<<1)))); + this.renderer.enqueueResult(new BuiltSection(WorldEngine.getWorldSectionId(lvl-1, (x<<1), (y<<1)+1, (z<<1)+1))); + this.renderer.enqueueResult(new BuiltSection(WorldEngine.getWorldSectionId(lvl-1, (x<<1)+1, (y<<1), (z<<1)))); + this.renderer.enqueueResult(new BuiltSection(WorldEngine.getWorldSectionId(lvl-1, (x<<1)+1, (y<<1), (z<<1)+1))); + this.renderer.enqueueResult(new BuiltSection(WorldEngine.getWorldSectionId(lvl-1, (x<<1)+1, (y<<1)+1, (z<<1)))); + this.renderer.enqueueResult(new BuiltSection(WorldEngine.getWorldSectionId(lvl-1, (x<<1)+1, (y<<1)+1, (z<<1)+1))); this.renderGen.removeTask(lvl-1, (x<<1), (y<<1), (z<<1)); @@ -96,7 +95,7 @@ public class RenderTracker { this.activeSections.put(WorldEngine.getWorldSectionId(lvl-1, (x<<1)+1, (y<<1)+1, (z<<1)+1), O); this.activeSections.remove(WorldEngine.getWorldSectionId(lvl, x, y, z)); - this.renderer.enqueueResult(new BuiltSection(WorldEngine.getWorldSectionId(lvl, x, y, z), null, null)); + this.renderer.enqueueResult(new BuiltSection(WorldEngine.getWorldSectionId(lvl, x, y, z))); this.renderGen.removeTask(lvl, x, y, z); this.renderGen.enqueueTask(lvl - 1, (x<<1), (y<<1), (z<<1), this::shouldStillBuild, this::getBuildFlagsOrAbort); diff --git a/src/main/java/me/cortex/zenith/client/core/rendering/building/BuiltSection.java b/src/main/java/me/cortex/zenith/client/core/rendering/building/BuiltSection.java index 92c95990..03c01a59 100644 --- a/src/main/java/me/cortex/zenith/client/core/rendering/building/BuiltSection.java +++ b/src/main/java/me/cortex/zenith/client/core/rendering/building/BuiltSection.java @@ -1,29 +1,43 @@ package me.cortex.zenith.client.core.rendering.building; +import me.cortex.zenith.common.util.MemoryBuffer; + +import java.util.Arrays; import java.util.Objects; //TODO: also have an AABB size stored public final class BuiltSection { public final long position; - public final BuiltSectionGeometry opaque; - public final BuiltSectionGeometry translucent; + public final int aabb; + public final MemoryBuffer geometryBuffer; + public final int[] offsets; - public BuiltSection(long position, BuiltSectionGeometry opaque, BuiltSectionGeometry translucent) { + public BuiltSection(long position) { + this(position, -1, null, null); + } + + public BuiltSection(long position, int aabb, MemoryBuffer geometryBuffer, int[] offsets) { this.position = position; - this.opaque = opaque; - this.translucent = translucent; + this.aabb = aabb; + this.geometryBuffer = geometryBuffer; + this.offsets = offsets; + if (offsets != null) { + for (int i = 0; i < offsets.length-1; i++) { + int delta = offsets[i+1] - offsets[i]; + if (delta<0||delta>=(1<<16)) { + throw new IllegalArgumentException("Offsets out of range"); + } + } + } } public BuiltSection clone() { - return new BuiltSection(this.position, this.opaque != null ? this.opaque.clone() : null, this.translucent != null ? this.translucent.clone() : null); + return new BuiltSection(this.position, this.aabb, this.geometryBuffer!=null?this.geometryBuffer.copy():null, this.offsets!=null?Arrays.copyOf(this.offsets, this.offsets.length):null); } public void free() { - if (this.opaque != null) { - this.opaque.free(); - } - if (this.translucent != null) { - this.translucent.free(); + if (this.geometryBuffer != null) { + this.geometryBuffer.free(); } } } diff --git a/src/main/java/me/cortex/zenith/client/core/rendering/building/BuiltSectionGeometry.java b/src/main/java/me/cortex/zenith/client/core/rendering/building/BuiltSectionGeometry.java deleted file mode 100644 index e9165c4d..00000000 --- a/src/main/java/me/cortex/zenith/client/core/rendering/building/BuiltSectionGeometry.java +++ /dev/null @@ -1,21 +0,0 @@ -package me.cortex.zenith.client.core.rendering.building; - -import me.cortex.zenith.common.util.MemoryBuffer; - -import java.util.Arrays; - -/** - * @param startOffsets Will be converted to ending offsets when doing data computation - */ -public record BuiltSectionGeometry(MemoryBuffer buffer, short[] startOffsets) { - - public BuiltSectionGeometry clone() { - return new BuiltSectionGeometry(this.buffer != null ? this.buffer.copy() : null, Arrays.copyOf(this.startOffsets, this.startOffsets.length)); - } - - public void free() { - if (this.buffer != null) { - this.buffer.free(); - } - } -} diff --git a/src/main/java/me/cortex/zenith/client/core/rendering/building/RenderDataFactory.java b/src/main/java/me/cortex/zenith/client/core/rendering/building/RenderDataFactory.java index cc8181fe..80a34718 100644 --- a/src/main/java/me/cortex/zenith/client/core/rendering/building/RenderDataFactory.java +++ b/src/main/java/me/cortex/zenith/client/core/rendering/building/RenderDataFactory.java @@ -297,7 +297,7 @@ public class RenderDataFactory { //MemoryUtil.memPutLong(buff.address+48, encodeRaw(2, 0,1,0,0,2,159,0, 0));//92 515 //MemoryUtil.memPutLong(buff.address+56, encodeRaw(3, 0,1,0,0,2,159,0, 0));//92 515 if (outData.isEmpty()) { - return new BuiltSection(section.getKey(), null, null); + return new BuiltSection(section.getKey()); } //outData.clear(); @@ -317,7 +317,7 @@ public class RenderDataFactory { MemoryUtil.memPutLong(ptr, data); ptr+=8; } - return new BuiltSection(section.getKey(), new BuiltSectionGeometry(buff, new short[0]), null); + return new BuiltSection(section.getKey(), (31<<15)|(31<<20)|(31<<25), buff, new int[]{0, outData.size(), outData.size(), outData.size(), outData.size(), outData.size(), outData.size(), outData.size()}); } diff --git a/src/main/resources/assets/zenith/shaders/lod/gl46/bindings.glsl b/src/main/resources/assets/zenith/shaders/lod/gl46/bindings.glsl index 97cafa50..37a2d72b 100644 --- a/src/main/resources/assets/zenith/shaders/lod/gl46/bindings.glsl +++ b/src/main/resources/assets/zenith/shaders/lod/gl46/bindings.glsl @@ -21,11 +21,11 @@ struct SectionMeta { uint posA; uint posB; uint AABB; - uint _padA; uint ptr; - uint cnt; - uint _padB; - uint _padC; + uint cntA; + uint cntB; + uint cntC; + uint cntD; }; //TODO: see if making the stride 2*4*4 bytes or something cause you get that 16 byte write diff --git a/src/main/resources/assets/zenith/shaders/lod/gl46/cmdgen.comp b/src/main/resources/assets/zenith/shaders/lod/gl46/cmdgen.comp index 4d0dfc55..3ddb5f6a 100644 --- a/src/main/resources/assets/zenith/shaders/lod/gl46/cmdgen.comp +++ b/src/main/resources/assets/zenith/shaders/lod/gl46/cmdgen.comp @@ -55,11 +55,13 @@ void main() { } if (shouldRender) { + uint basePtr = extractQuadStart(meta); + DrawCommand cmd; - cmd.count = extractQuadCount(meta) * 6; + cmd.count = (meta.cntA&0xFFFF) * 6; cmd.instanceCount = 1; cmd.firstIndex = 0; - cmd.baseVertex = int(extractQuadStart(meta))<<2; + cmd.baseVertex = int(basePtr)<<2; cmd.baseInstance = encodeLocalLodPos(detail, ipos); cmdBuffer[atomicAdd(opaqueDrawCount, 1)] = cmd; } diff --git a/src/main/resources/assets/zenith/shaders/lod/gl46/cull/raster.vert b/src/main/resources/assets/zenith/shaders/lod/gl46/cull/raster.vert index 4ac89195..0d0980de 100644 --- a/src/main/resources/assets/zenith/shaders/lod/gl46/cull/raster.vert +++ b/src/main/resources/assets/zenith/shaders/lod/gl46/cull/raster.vert @@ -14,12 +14,15 @@ void main() { uint detail = extractDetail(section); ivec3 ipos = extractPosition(section); + ivec3 aabbOffset = extractAABBOffset(section); + ivec3 size = extractAABBSize(section); //Transform ipos with respect to the vertex corner - ipos += ivec3(gl_VertexID&1, (gl_VertexID>>2)&1, (gl_VertexID>>1)&1); + ivec3 pos = (((ipos<>2)&1, (gl_VertexID>>1)&1)*size)*(1<>ivec3(0,5,10))&31; +} + +ivec3 extractAABBSize(SectionMeta meta) { + return ((ivec3(meta.AABB)>>ivec3(15,20,25))&31)+1;//The size is + 1 cause its always at least 1x1x1 }