diff --git a/src/main/java/me/cortex/voxelmon/core/DistanceTracker.java b/src/main/java/me/cortex/voxelmon/core/DistanceTracker.java index 3ce75b92..3a91968b 100644 --- a/src/main/java/me/cortex/voxelmon/core/DistanceTracker.java +++ b/src/main/java/me/cortex/voxelmon/core/DistanceTracker.java @@ -24,10 +24,13 @@ public class DistanceTracker { this.rings = new TransitionRing2D[rings+1]; this.tracker = tracker; - int DIST = 16; + //NOTE: This is in our render distance units, to convert to chunks at lvl 0 multiply by 2 + int DIST = 24; this.rings[0] = new TransitionRing2D(5, DIST, (x,z)->{ - if (true) return; + if (true) { + return; + } for (int y = -2; y < 10; y++) { this.tracker.remLvl0(x, y, z); } diff --git a/src/main/java/me/cortex/voxelmon/core/rendering/Gl46FarWorldRenderer.java b/src/main/java/me/cortex/voxelmon/core/rendering/Gl46FarWorldRenderer.java index aeeb8d4c..695613bb 100644 --- a/src/main/java/me/cortex/voxelmon/core/rendering/Gl46FarWorldRenderer.java +++ b/src/main/java/me/cortex/voxelmon/core/rendering/Gl46FarWorldRenderer.java @@ -48,6 +48,7 @@ public class Gl46FarWorldRenderer extends AbstractFarWorldRenderer { .compile(); private final GlBuffer glCommandBuffer = new GlBuffer(100_000*5*4, 0); + private final GlBuffer glVisibilityBuffer = new GlBuffer(100_000*4, 0); public Gl46FarWorldRenderer() { super(); @@ -63,9 +64,10 @@ public class Gl46FarWorldRenderer extends AbstractFarWorldRenderer { glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, this.geometry.geometryId()); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, this.glCommandBuffer.id); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, this.geometry.metaId()); - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, this.stateDataBuffer.id);//State LUT - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 5, this.biomeDataBuffer.id);//Biome LUT - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 6, 0);//Lighting LUT + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, this.glVisibilityBuffer.id); + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 5, this.stateDataBuffer.id);//State LUT + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 6, this.biomeDataBuffer.id);//Biome LUT + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 7, 0);//Lighting LUT glBindVertexArray(0); } @@ -91,11 +93,23 @@ public class Gl46FarWorldRenderer extends AbstractFarWorldRenderer { glMemoryBarrier(GL_PIXEL_BUFFER_BARRIER_BIT|GL_FRAMEBUFFER_BARRIER_BIT); //TODO: add gpu occlusion culling here (after the lod drawing) (maybe, finish the rest of the PoC first) + cullShader.bind(); + + glColorMask(false,false,false,false); + glDepthMask(false); + glDrawElementsInstanced(GL_TRIANGLES, 6*2*3, GL_UNSIGNED_BYTE, (1<<16)*6*2, this.geometry.getSectionCount()); + glDepthMask(true); + glColorMask(true,true,true,true); + + glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT); + glBindVertexArray(0); RenderLayer.getCutoutMipped().endDrawing(); } + //FIXME: dont do something like this as it breaks multiviewport mods + private int frameId = 0; private void updateUniformBuffer(MatrixStack stack, double cx, double cy, double cz) { long ptr = UploadStream.INSTANCE.upload(this.uniformBuffer, 0, this.uniformBuffer.size()); var mat = new Matrix4f(RenderSystem.getProjectionMatrix()).mul(stack.peek().getPositionMatrix()); @@ -111,6 +125,7 @@ public class Gl46FarWorldRenderer extends AbstractFarWorldRenderer { plane.getToAddress(ptr); ptr += 4*4; } innerTranslation.getToAddress(ptr); ptr += 4*3; + MemoryUtil.memPutInt(ptr, this.frameId++); ptr += 4; } @Override @@ -119,6 +134,8 @@ public class Gl46FarWorldRenderer extends AbstractFarWorldRenderer { this.commandGen.free(); this.lodShader.free(); this.cullShader.free(); + this.glCommandBuffer.free(); + this.glVisibilityBuffer.free(); } @Override diff --git a/src/main/java/me/cortex/voxelmon/core/rendering/RenderTracker.java b/src/main/java/me/cortex/voxelmon/core/rendering/RenderTracker.java index 345ef715..fee78ac1 100644 --- a/src/main/java/me/cortex/voxelmon/core/rendering/RenderTracker.java +++ b/src/main/java/me/cortex/voxelmon/core/rendering/RenderTracker.java @@ -167,19 +167,23 @@ public class RenderTracker { } public int getBuildFlagsOrAbort(WorldSection section) { + var cam = MinecraftClient.getInstance().cameraEntity; + if (cam == null) { + return 0; + } var holder = this.activeSections.get(section.getKey()); int buildMask = 0; if (holder != null) { - if (section.z< (((int)MinecraftClient.getInstance().cameraEntity.getPos().z)>>(5+section.lvl))+1) { + if (section.z<(((int)cam.getPos().z)>>(5+section.lvl))+1) { buildMask |= 1<< Direction.SOUTH.getId(); } - if (section.z>(((int)MinecraftClient.getInstance().cameraEntity.getPos().z)>>(5+section.lvl))-1) { + if (section.z>(((int)cam.getPos().z)>>(5+section.lvl))-1) { buildMask |= 1<>(5+section.lvl))+1) { + if (section.x<(((int)cam.getPos().x)>>(5+section.lvl))+1) { buildMask |= 1<(((int)MinecraftClient.getInstance().cameraEntity.getPos().x)>>(5+section.lvl))-1) { + if (section.x>(((int)cam.getPos().x)>>(5+section.lvl))-1) { buildMask |= 1<= 1L<<31) { - throw new IllegalStateException(); - } - this.commonIndexBufferOffset = (int) offset; - buffer.free(); - this.commonIndexQuadCount = newQuadCount; - } - return this.commonIndexBufferOffset * 6; + private static MemoryBuffer generateCubeIndexBuffer() { + var buffer = new MemoryBuffer(6*2*3); + long ptr = buffer.address; + MemoryUtil.memSet(ptr, 0, 6*2*3 ); + + //Bottom face + MemoryUtil.memPutByte(ptr++, (byte) 0); + MemoryUtil.memPutByte(ptr++, (byte) 1); + MemoryUtil.memPutByte(ptr++, (byte) 2); + MemoryUtil.memPutByte(ptr++, (byte) 3); + MemoryUtil.memPutByte(ptr++, (byte) 2); + MemoryUtil.memPutByte(ptr++, (byte) 1); + + //top face + MemoryUtil.memPutByte(ptr++, (byte) 6); + MemoryUtil.memPutByte(ptr++, (byte) 5); + MemoryUtil.memPutByte(ptr++, (byte) 4); + MemoryUtil.memPutByte(ptr++, (byte) 5); + MemoryUtil.memPutByte(ptr++, (byte) 6); + MemoryUtil.memPutByte(ptr++, (byte) 7); + + //north face + MemoryUtil.memPutByte(ptr++, (byte) 0); + MemoryUtil.memPutByte(ptr++, (byte) 4); + MemoryUtil.memPutByte(ptr++, (byte) 1); + MemoryUtil.memPutByte(ptr++, (byte) 5); + MemoryUtil.memPutByte(ptr++, (byte) 1); + MemoryUtil.memPutByte(ptr++, (byte) 4); + + //south face + MemoryUtil.memPutByte(ptr++, (byte) 3); + MemoryUtil.memPutByte(ptr++, (byte) 6); + MemoryUtil.memPutByte(ptr++, (byte) 2); + MemoryUtil.memPutByte(ptr++, (byte) 6); + MemoryUtil.memPutByte(ptr++, (byte) 3); + MemoryUtil.memPutByte(ptr++, (byte) 7); + + //west face + MemoryUtil.memPutByte(ptr++, (byte) 2); + MemoryUtil.memPutByte(ptr++, (byte) 4); + MemoryUtil.memPutByte(ptr++, (byte) 0); + MemoryUtil.memPutByte(ptr++, (byte) 4); + MemoryUtil.memPutByte(ptr++, (byte) 2); + MemoryUtil.memPutByte(ptr++, (byte) 6); + + //east face + MemoryUtil.memPutByte(ptr++, (byte) 1); + MemoryUtil.memPutByte(ptr++, (byte) 5); + MemoryUtil.memPutByte(ptr++, (byte) 3); + MemoryUtil.memPutByte(ptr++, (byte) 7); + MemoryUtil.memPutByte(ptr++, (byte) 3); + MemoryUtil.memPutByte(ptr++, (byte) 5); + + return buffer; } public int id() { - return this.indexBuffer.id(); + return this.indexBuffer.id; } } diff --git a/src/main/java/me/cortex/voxelmon/core/rendering/building/RenderGenerationService.java b/src/main/java/me/cortex/voxelmon/core/rendering/building/RenderGenerationService.java index 98548dbc..a8f98f90 100644 --- a/src/main/java/me/cortex/voxelmon/core/rendering/building/RenderGenerationService.java +++ b/src/main/java/me/cortex/voxelmon/core/rendering/building/RenderGenerationService.java @@ -115,19 +115,20 @@ public class RenderGenerationService { return; } - //Wait for the ingest to finish - while (this.taskCounter.availablePermits() != 0) { - Thread.onSpinWait(); - } - - //Shutdown + //Since this is just render data, dont care about any tasks needing to finish this.running = false; this.taskCounter.release(1000); + //Wait for thread to join try { for (var worker : this.workers) { worker.join(); } } catch (InterruptedException e) {throw new RuntimeException(e);} + + //Cleanup any remaining data + while (!this.taskQueue.isEmpty()) { + this.taskQueue.pop(); + } } } diff --git a/src/main/java/me/cortex/voxelmon/core/util/IndexUtil.java b/src/main/java/me/cortex/voxelmon/core/util/IndexUtil.java index e1f940fa..26b3e8d5 100644 --- a/src/main/java/me/cortex/voxelmon/core/util/IndexUtil.java +++ b/src/main/java/me/cortex/voxelmon/core/util/IndexUtil.java @@ -3,7 +3,7 @@ package me.cortex.voxelmon.core.util; import org.lwjgl.system.MemoryUtil; public class IndexUtil { - public static MemoryBuffer generateQuadIndices(int quadCount) { + public static MemoryBuffer generateQuadIndicesShort(int quadCount) { if ((quadCount*4) >= 1<<16) { throw new IllegalArgumentException("Quad count to large"); } @@ -22,4 +22,19 @@ public class IndexUtil { return buffer; } + + public static MemoryBuffer generateQuadIndicesInt(int quadCount) { + MemoryBuffer buffer = new MemoryBuffer(quadCount * 6L * 2); + long ptr = buffer.address; + for(int i = 0; i < quadCount*4; i += 4) { + MemoryUtil.memPutInt(ptr + (0*4), i); + MemoryUtil.memPutInt(ptr + (1*4), (i + 1)); + MemoryUtil.memPutInt(ptr + (2*4), (i + 2)); + MemoryUtil.memPutInt(ptr + (3*4), (i + 1)); + MemoryUtil.memPutInt(ptr + (4*4), (i + 3)); + MemoryUtil.memPutInt(ptr + (5*4), (i + 2)); + ptr += 6 * 4; + } + return buffer; + } } diff --git a/src/main/java/me/cortex/voxelmon/core/world/WorldEngine.java b/src/main/java/me/cortex/voxelmon/core/world/WorldEngine.java index 81bc4a4e..1fb7ae51 100644 --- a/src/main/java/me/cortex/voxelmon/core/world/WorldEngine.java +++ b/src/main/java/me/cortex/voxelmon/core/world/WorldEngine.java @@ -17,12 +17,11 @@ import java.util.concurrent.atomic.AtomicReference; //Use an LMDB backend to store the world, use a local inmemory cache for lod sections // automatically manages and invalidates sections of the world as needed public class WorldEngine { - private static final int ACTIVE_CACHE_SIZE = 10; public final StorageBackend storage; private final Mapper mapper; private final ActiveSectionTracker sectionTracker; - public final VoxelIngestService ingestService = new VoxelIngestService(this); + public final VoxelIngestService ingestService; public final SectionSavingService savingService; private RenderTracker renderTracker; @@ -42,6 +41,7 @@ public class WorldEngine { this.sectionTracker = new ActiveSectionTracker(maxMipLayers, this::unsafeLoadSection); this.savingService = new SectionSavingService(this, savingServiceWorkers); + this.ingestService = new VoxelIngestService(this); } private boolean unsafeLoadSection(WorldSection into) { @@ -69,7 +69,7 @@ public class WorldEngine { } //Marks a section as dirty, enqueuing it for saving and or render data rebuilding - private void markDirty(WorldSection section) { + public void markDirty(WorldSection section) { this.renderTracker.sectionUpdated(section); //TODO: add an option for having synced saving, that is when call enqueueSave, that will instead, instantly // save to the db, this can be useful for just reducing the amount of thread pools in total diff --git a/src/main/resources/assets/voxelmon/shaders/lod/gl46/bindings.glsl b/src/main/resources/assets/voxelmon/shaders/lod/gl46/bindings.glsl index 161692d4..cea12256 100644 --- a/src/main/resources/assets/voxelmon/shaders/lod/gl46/bindings.glsl +++ b/src/main/resources/assets/voxelmon/shaders/lod/gl46/bindings.glsl @@ -50,17 +50,21 @@ layout(binding = 3, std430) readonly restrict buffer SectionBuffer { SectionMeta sectionData[]; }; -layout(binding = 4, std430) readonly restrict buffer StateBuffer { - State stateData[]; -}; - -layout(binding = 5, std430) readonly restrict buffer BiomeBuffer { - Biome biomeData[]; -}; - #ifndef VISIBILITY_ACCESS #define VISIBILITY_ACCESS readonly #endif -layout(binding = 6, std430) VISIBILITY_ACCESS restrict buffer VisibilityBuffer { +layout(binding = 4, std430) VISIBILITY_ACCESS restrict buffer VisibilityBuffer { uint visibilityData[]; }; + +layout(binding = 5, std430) readonly restrict buffer StateBuffer { + State stateData[]; +}; + +layout(binding = 6, std430) readonly restrict buffer BiomeBuffer { + Biome biomeData[]; +}; + +layout(binding = 7, std430) readonly restrict buffer LightingBuffer { + vec4 lightData[]; +}; diff --git a/src/main/resources/assets/voxelmon/shaders/lod/gl46/cmdgen.comp b/src/main/resources/assets/voxelmon/shaders/lod/gl46/cmdgen.comp index 03e9ad44..013a7015 100644 --- a/src/main/resources/assets/voxelmon/shaders/lod/gl46/cmdgen.comp +++ b/src/main/resources/assets/voxelmon/shaders/lod/gl46/cmdgen.comp @@ -34,12 +34,20 @@ void main() { uint detail = extractDetail(meta); ivec3 ipos = extractPosition(meta); - //TODO: fixme; i dont think this is correct vec3 cornerPos = vec3(((ipos<>detail)))); diff --git a/src/main/resources/assets/voxelmon/shaders/lod/gl46/cull/raster.frag b/src/main/resources/assets/voxelmon/shaders/lod/gl46/cull/raster.frag index 6e5bc37c..2455f6c6 100644 --- a/src/main/resources/assets/voxelmon/shaders/lod/gl46/cull/raster.frag +++ b/src/main/resources/assets/voxelmon/shaders/lod/gl46/cull/raster.frag @@ -4,7 +4,9 @@ #import flat in uint id; flat in uint value; +//out vec4 colour; void main() { visibilityData[id] = value; + //colour = vec4(float(id&7)/7, float((id>>3)&7)/7, float((id>>6)&7)/7, 1); } \ No newline at end of file diff --git a/src/main/resources/assets/voxelmon/shaders/lod/gl46/cull/raster.vert b/src/main/resources/assets/voxelmon/shaders/lod/gl46/cull/raster.vert index 97841ad3..f6858676 100644 --- a/src/main/resources/assets/voxelmon/shaders/lod/gl46/cull/raster.vert +++ b/src/main/resources/assets/voxelmon/shaders/lod/gl46/cull/raster.vert @@ -8,18 +8,20 @@ flat out uint id; flat out uint value; void main() { - SectionMeta section = sectionData[gl_VertexID>>3]; + uint sid = gl_InstanceID; + + SectionMeta section = sectionData[sid]; uint detail = extractDetail(section); ivec3 ipos = extractPosition(section); //Transform ipos with respect to the vertex corner - ipos += ivec3(gl_VertexID&1, (gl_VertexID>>1)&1, (gl_VertexID>>2)&1); + ipos += ivec3(gl_VertexID&1, (gl_VertexID>>2)&1, (gl_VertexID>>1)&1); vec3 cornerPos = vec3(((ipos<>3; + id = sid; value = frameId; } \ No newline at end of file