It works EVEN BETTER

This commit is contained in:
mcrcortex
2024-09-23 01:10:43 +10:00
parent aafc475843
commit 87238bdb45
9 changed files with 65 additions and 20 deletions

View File

@@ -77,16 +77,16 @@ public class RenderService<T extends AbstractSectionRenderer<J, ?>, J extends Vi
world.getMapper().setBiomeCallback(this.modelService::addBiome);
//this.nodeManager.insertTopLevelNode(WorldEngine.getWorldSectionId(0, 0,0,0));
this.nodeManager.insertTopLevelNode(WorldEngine.getWorldSectionId(4, 0,0,0));
/*
final int H_WIDTH = 1;
//this.nodeManager.insertTopLevelNode(WorldEngine.getWorldSectionId(4, 0,0,0));
final int H_WIDTH = 10;
for (int x = -H_WIDTH; x <= H_WIDTH; x++) {
for (int y = -1; y <= 0; y++) {
for (int y = 0; y <= 0; y++) {
for (int z = -H_WIDTH; z <= H_WIDTH; z++) {
this.nodeManager.insertTopLevelNode(WorldEngine.getWorldSectionId(4, x, y, z));
}
}
}*/
}
}
public void setup(Camera camera) {
@@ -123,6 +123,8 @@ public class RenderService<T extends AbstractSectionRenderer<J, ?>, J extends Vi
if (this.nodeManager.writeChanges(this.traversal.getNodeBuffer())) {//TODO: maybe move the node buffer out of the traversal class
UploadStream.INSTANCE.commit();
}
//this needs to go after, due to geometry updates committed by the nodeManager
this.sectionRenderer.getGeometryManager().tick();
}
UploadStream.INSTANCE.tick();
@@ -142,6 +144,7 @@ public class RenderService<T extends AbstractSectionRenderer<J, ?>, J extends Vi
this.modelService.addDebugData(debug);
this.renderGen.addDebugData(debug);
this.sectionRenderer.addDebug(debug);
this.nodeManager.addDebug(debug);
}
public void shutdown() {

View File

@@ -115,7 +115,7 @@ public class HierarchicalOcclusionTraverser {
MemoryUtil.memPutInt(ptr, (int) (this.renderList.size()/4-1)); ptr += 4;//TODO maybe move this to a #define
//Screen space size for descending
MemoryUtil.memPutFloat(ptr, 64*64); ptr += 4;
MemoryUtil.memPutFloat(ptr, 128*128); ptr += 4;
}
private void bindings() {
@@ -143,7 +143,7 @@ public class HierarchicalOcclusionTraverser {
PrintfDebugUtil.bind();
this.traverseInternal(1);
this.traverseInternal(this.nodeManager.getTopLevelNodeIds().size());
this.downloadResetRequestQueue();
@@ -192,7 +192,7 @@ public class HierarchicalOcclusionTraverser {
ptr = UploadStream.INSTANCE.upload(this.scratchQueueA, 0, 4L*initialQueueSize);
for (int i = 0; i < initialQueueSize; i++) {
MemoryUtil.memPutInt(ptr + 4L*i, 0);
MemoryUtil.memPutInt(ptr + 4L*i, this.nodeManager.getTopLevelNodeIds().getInt(i));
}
UploadStream.INSTANCE.commit();

View File

@@ -1,5 +1,6 @@
package me.cortex.voxy.client.core.rendering.hierachical2;
import it.unimi.dsi.fastutil.ints.IntArrayList;
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
import it.unimi.dsi.fastutil.longs.Long2IntOpenHashMap;
import me.cortex.voxy.client.core.gl.GlBuffer;
@@ -12,6 +13,10 @@ import me.cortex.voxy.common.Logger;
import me.cortex.voxy.common.world.WorldEngine;
import me.jellysquid.mods.sodium.client.util.MathUtil;
import java.util.List;
public class NodeManager2 {
//Assumptions:
// all nodes have children (i.e. all nodes have at least one child existence bit set at all times)
@@ -22,6 +27,18 @@ public class NodeManager2 {
// For the queue processing, will need a redirect node-value type
// since for inner node child resize gpu could take N frames to update
//There is a very funny issue that has kinda, just resolved itself accidentally,
// however i wonder if i want a better solution for.
//That issue is, top level nodes that have no children
// the accidental solution, is that when the node is marked, it generates
// the child request,
// however, since there are no children in it, it sticks around, since there isnt anything to update it and invoke
// the finishRequest on it
// if the top level node ends up being updated with a child update, it should automatically solve itself
// as the new children are added to the already inprogress request!!!!
public static final int NULL_GEOMETRY_ID = -1;
public static final int EMPTY_GEOMETRY_ID = -2;
@@ -44,6 +61,7 @@ public class NodeManager2 {
private final Long2IntOpenHashMap activeSectionMap = new Long2IntOpenHashMap();
private final NodeStore nodeData;
public final int maxNodeCount;
private final IntArrayList topLevelNodeIds = new IntArrayList();
public NodeManager2(int maxNodeCount, AbstractSectionGeometryManager geometryManager, SectionUpdateRouter updateRouter) {
if (!MathUtil.isPowerOfTwo(maxNodeCount)) {
throw new IllegalArgumentException("Max node count must be a power of 2");
@@ -68,6 +86,8 @@ public class NodeManager2 {
int id = this.singleRequests.put(request);
this.updateRouter.watch(pos, WorldEngine.UPDATE_FLAGS);
this.activeSectionMap.put(pos, id|NODE_TYPE_REQUEST|REQUEST_TYPE_SINGLE);
}
public void removeTopLevelNode(long pos) {
@@ -77,6 +97,16 @@ public class NodeManager2 {
return;
}
//TODO: assert is top level node
//TODO:FIXME augment topLevelNodeIds with a hashmap from node id to array index
// OR!! just ensure the list is always ordered?? maybe? idk i think hashmap is best
// since the array list might get shuffled as nodes are removed
// since need to move the entry at the end of the array to fill a hole made
}
IntArrayList getTopLevelNodeIds() {
return this.topLevelNodeIds;
}
//==================================================================================================================
@@ -217,6 +247,11 @@ public class NodeManager2 {
//this.nodeData.setNodeType();
this.activeSectionMap.put(request.getPosition(), id|NODE_TYPE_LEAF);//Assume that the result of any single request type is a leaf node
this.nodeUpdates.add(id);
//Assume that this is always a top node
// FIXME: DONT DO THIS
this.topLevelNodeIds.add(id);
}
private void finishRequest(int requestId, NodeChildRequest request) {
@@ -367,4 +402,8 @@ public class NodeManager2 {
(WorldEngine.getY(basePos)<<1)|((addin>>2)&1),
(WorldEngine.getZ(basePos)<<1)|((addin>>1)&1));
}
public void addDebug(List<String> debug) {
debug.add("NC/IF: " + this.activeSectionMap.size() + "/" + (this.singleRequests.count() + this.childRequests.count()));
}
}

View File

@@ -235,6 +235,7 @@ public final class NodeStore {
int w = 0;
short flags = 0;
flags |= (short) (this.isNodeRequestInFlight(nodeId)?1:0);
flags |= (short) (this.getChildPtrCount(nodeId)<<2);
{

View File

@@ -21,7 +21,7 @@ public abstract class AbstractSectionGeometryManager {
public int uploadSection(BuiltSection section) {return this.uploadReplaceSection(-1, section);}
public abstract int uploadReplaceSection(int oldId, BuiltSection section);
public abstract void removeSection(int id);
void tick() {}
public void tick() {}
public void free() {}
}

View File

@@ -105,7 +105,7 @@ public class BasicSectionGeometryManager extends AbstractSectionGeometryManager
}
@Override
void tick() {
public void tick() {
//Upload all invalidated bits
if (!this.invalidatedSectionIds.isEmpty()) {
for (int id : this.invalidatedSectionIds) {

View File

@@ -34,6 +34,7 @@ import static org.lwjgl.opengl.GL45.glCopyNamedBufferSubData;
//Uses MDIC to render the sections
public class MDICSectionRenderer extends AbstractSectionRenderer<MDICViewport, BasicSectionGeometryManager> {
private final Shader terrainShader = Shader.make()
.defineIf("DEBUG_RENDER", false)
.add(ShaderType.VERTEX, "voxy:lod/gl46/quads2.vert")
.add(ShaderType.FRAGMENT, "voxy:lod/gl46/quads.frag")
.compile();
@@ -119,11 +120,6 @@ public class MDICSectionRenderer extends AbstractSectionRenderer<MDICViewport, B
public void renderOpaque(MDICViewport viewport) {
if (this.geometryManager.getSectionCount() == 0) return;
//Tick the geometry manager to upload all invalidated metadata changes to the gpu before invoking the command gen shader
this.geometryManager.tick();
this.uploadUniformBuffer(viewport);
//TODO compute the draw calls
@@ -193,7 +189,7 @@ public class MDICSectionRenderer extends AbstractSectionRenderer<MDICViewport, B
@Override
public void addDebug(List<String> lines) {
super.addDebug(lines);
lines.add("NC/GS: " + this.geometryManager.getSectionCount() + "/" + (this.geometryManager.getGeometryUsed()/(1024*1024)));//Node count/geometry size (MB)
lines.add("SC/GS: " + this.geometryManager.getSectionCount() + "/" + (this.geometryManager.getGeometryUsed()/(1024*1024)));//section count/geometry size (MB)
}
@Override

View File

@@ -42,4 +42,8 @@ public class ExpandingObjectAllocationList<T> {
}
return this.objects[index];
}
public int count() {
return this.bitSet.getCount();
}
}

View File

@@ -88,11 +88,13 @@ void traverse(in UnpackedNode node) {
addRequest(node);
//TODO: Decend into children? maybe add a bitflag saying is bad if the immediate children dont have meshes
if (node.lodLevel != 0) {
enqueueChildren(node);
}
}
}
}
}
void main() {
uint nodeId = getCurrentNode();