Finished GeometryManager and added AABB raster support
This commit is contained in:
@@ -361,6 +361,6 @@ public class ModelManager {
|
||||
}
|
||||
|
||||
public void addDebugInfo(List<String> info) {
|
||||
|
||||
info.add("BlockModels registered: " + this.modelTexture2id.size() + "/" + (1<<16));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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()});
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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<<detail)-baseSectionPos)<<5);
|
||||
pos += aabbOffset;
|
||||
pos += (ivec3(gl_VertexID&1, (gl_VertexID>>2)&1, (gl_VertexID>>1)&1)*size)*(1<<detail);
|
||||
|
||||
vec3 cornerPos = vec3(((ipos<<detail)-baseSectionPos)<<5);
|
||||
gl_Position = MVP * vec4(cornerPos,1);
|
||||
gl_Position = MVP * vec4(vec3(pos),1);
|
||||
|
||||
//Write to this id
|
||||
id = sid;
|
||||
|
||||
@@ -16,6 +16,10 @@ uint extractQuadStart(SectionMeta meta) {
|
||||
return meta.ptr;
|
||||
}
|
||||
|
||||
uint extractQuadCount(SectionMeta meta) {
|
||||
return meta.cnt;
|
||||
ivec3 extractAABBOffset(SectionMeta meta) {
|
||||
return (ivec3(meta.AABB)>>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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user