Removed caching rings, tinkered with model bakery, tweeked upload counts, moved inital ring fill offthread
This commit is contained in:
@@ -8,7 +8,7 @@ yarn_mappings=1.20.4+build.1
|
|||||||
loader_version=0.15.0
|
loader_version=0.15.0
|
||||||
|
|
||||||
# Mod Properties
|
# Mod Properties
|
||||||
mod_version = 0.0.7-alpha
|
mod_version = 0.0.8-alpha
|
||||||
maven_group = me.cortex
|
maven_group = me.cortex
|
||||||
archives_base_name = voxy
|
archives_base_name = voxy
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ import me.cortex.voxy.client.core.rendering.RenderTracker;
|
|||||||
import me.cortex.voxy.client.core.util.RingUtil;
|
import me.cortex.voxy.client.core.util.RingUtil;
|
||||||
import net.minecraft.client.MinecraftClient;
|
import net.minecraft.client.MinecraftClient;
|
||||||
|
|
||||||
|
import java.util.stream.IntStream;
|
||||||
|
|
||||||
//Can use ring logic
|
//Can use ring logic
|
||||||
// i.e. when a player moves the rings of each lod change (how it was doing in the original attempt)
|
// i.e. when a player moves the rings of each lod change (how it was doing in the original attempt)
|
||||||
// also have it do directional quad culling and rebuild the chunk if needed (this shouldent happen very often) (the reason is to significantly reduce draw calls)
|
// also have it do directional quad culling and rebuild the chunk if needed (this shouldent happen very often) (the reason is to significantly reduce draw calls)
|
||||||
@@ -26,8 +28,8 @@ public class DistanceTracker {
|
|||||||
this.cacheLoadRings = new TransitionRing2D[lodRingScales.length];
|
this.cacheLoadRings = new TransitionRing2D[lodRingScales.length];
|
||||||
this.cacheUnloadRings = new TransitionRing2D[lodRingScales.length];
|
this.cacheUnloadRings = new TransitionRing2D[lodRingScales.length];
|
||||||
this.tracker = tracker;
|
this.tracker = tracker;
|
||||||
this.minYSection = MinecraftClient.getInstance().world.getBottomSectionCoord()/2;
|
this.minYSection = MinecraftClient.getInstance().world.getBottomSectionCoord()/2;//-128;
|
||||||
this.maxYSection = MinecraftClient.getInstance().world.getTopSectionCoord()/2;
|
this.maxYSection = MinecraftClient.getInstance().world.getTopSectionCoord()/2;//128;
|
||||||
|
|
||||||
|
|
||||||
//The rings 0+ start at 64 vanilla rd, no matter what the game is set at, that is if the game is set to 32 rd
|
//The rings 0+ start at 64 vanilla rd, no matter what the game is set at, that is if the game is set to 32 rd
|
||||||
@@ -40,18 +42,20 @@ public class DistanceTracker {
|
|||||||
|
|
||||||
//TODO:FIXME i think the radius is wrong and (lodRingScales[i]) needs to be (lodRingScales[i]<<1) since the transition ring (the thing above)
|
//TODO:FIXME i think the radius is wrong and (lodRingScales[i]) needs to be (lodRingScales[i]<<1) since the transition ring (the thing above)
|
||||||
// acts on LoD level + 1
|
// acts on LoD level + 1
|
||||||
this.cacheLoadRings[i] = new TransitionRing2D(5+i, (lodRingScales[i]<<1) + cacheLoadDistance, (x, z) -> {
|
|
||||||
//When entering a cache ring, trigger a mesh op and inject into cache
|
//TODO: check this is actually working lmao and make it generate parent level lods on the exit instead of entry so it looks correct when flying backwards
|
||||||
for (int y = this.minYSection>>capRing; y <= this.maxYSection>>capRing; y++) {
|
//this.cacheLoadRings[i] = new TransitionRing2D(5+i, (lodRingScales[i]<<1) + cacheLoadDistance, (x, z) -> {
|
||||||
this.tracker.addCache(capRing, x, y, z);
|
// //When entering a cache ring, trigger a mesh op and inject into cache
|
||||||
}
|
// for (int y = this.minYSection>>capRing; y <= this.maxYSection>>capRing; y++) {
|
||||||
}, (x, z) -> {});
|
// this.tracker.addCache(capRing, x, y, z);
|
||||||
this.cacheUnloadRings[i] = new TransitionRing2D(5+i, (lodRingScales[i]<<1) + cacheUnloadDistance, (x, z) -> {}, (x, z) -> {
|
// }
|
||||||
//When exiting the cache unload ring, tell the cache to dump whatever mesh it has cached and not add any mesh from that position
|
//}, (x, z) -> {});
|
||||||
for (int y = this.minYSection>>capRing; y <= this.maxYSection>>capRing; y++) {
|
//this.cacheUnloadRings[i] = new TransitionRing2D(5+i, (lodRingScales[i]<<1) + cacheUnloadDistance, (x, z) -> {}, (x, z) -> {
|
||||||
this.tracker.removeCache(capRing, x, y, z);
|
// //When exiting the cache unload ring, tell the cache to dump whatever mesh it has cached and not add any mesh from that position
|
||||||
}
|
// for (int y = this.minYSection>>capRing; y <= this.maxYSection>>capRing; y++) {
|
||||||
});
|
// this.tracker.removeCache(capRing, x, y, z);
|
||||||
|
// }
|
||||||
|
//});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,36 +79,64 @@ public class DistanceTracker {
|
|||||||
// the lod sections
|
// the lod sections
|
||||||
public void setCenter(int x, int y, int z) {
|
public void setCenter(int x, int y, int z) {
|
||||||
for (var ring : this.cacheLoadRings) {
|
for (var ring : this.cacheLoadRings) {
|
||||||
ring.update(x, z);
|
if (ring!=null)
|
||||||
|
ring.update(x, z);
|
||||||
}
|
}
|
||||||
for (var ring : this.loDRings) {
|
for (var ring : this.loDRings) {
|
||||||
ring.update(x, z);
|
ring.update(x, z);
|
||||||
}
|
}
|
||||||
for (var ring : this.cacheUnloadRings) {
|
for (var ring : this.cacheUnloadRings) {
|
||||||
ring.update(x, z);
|
if (ring!=null)
|
||||||
|
ring.update(x, z);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void init(int x, int z) {
|
public void init(int x, int z) {
|
||||||
//Radius of chunks to enqueue
|
|
||||||
int SIZE = 128;
|
|
||||||
//Insert highest LOD level
|
|
||||||
for (int ox = -SIZE; ox <= SIZE; ox++) {
|
|
||||||
for (int oz = -SIZE; oz <= SIZE; oz++) {
|
|
||||||
this.inc(4, (x>>(5+this.loDRings.length)) + ox, (z>>(5+this.loDRings.length)) + oz);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
for (var ring : this.cacheLoadRings) {
|
for (var ring : this.cacheLoadRings) {
|
||||||
ring.fill(x, z);
|
if (ring != null)
|
||||||
|
ring.setCenter(x, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = this.loDRings.length-1; 0 <= i; i--) {
|
for (var ring : this.cacheUnloadRings) {
|
||||||
if (this.loDRings[i] != null) {
|
if (ring != null)
|
||||||
this.loDRings[i].fill(x, z);
|
ring.setCenter(x, z);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (var ring : this.loDRings) {
|
||||||
|
if (ring != null)
|
||||||
|
ring.setCenter(x, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
var thread = new Thread(()-> {
|
||||||
|
//Radius of chunks to enqueue
|
||||||
|
int SIZE = 128;
|
||||||
|
//Insert highest LOD level
|
||||||
|
for (int ox = -SIZE; ox <= SIZE; ox++) {
|
||||||
|
for (int oz = -SIZE; oz <= SIZE; oz++) {
|
||||||
|
this.inc(4, (x >> (5 + this.loDRings.length)) + ox, (z >> (5 + this.loDRings.length)) + oz);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
for (var ring : this.cacheLoadRings) {
|
||||||
|
if (ring != null)
|
||||||
|
ring.fill(x, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var ring : this.cacheUnloadRings) {
|
||||||
|
if (ring != null)
|
||||||
|
ring.fill(x, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = this.loDRings.length - 1; 0 <= i; i--) {
|
||||||
|
if (this.loDRings[i] != null) {
|
||||||
|
this.loDRings[i].fill(x, z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
thread.setName("LoD Ring Initializer");
|
||||||
|
thread.start();
|
||||||
|
//TODO: FIXME: need to destory on shutdown
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -248,6 +280,7 @@ public class DistanceTracker {
|
|||||||
|
|
||||||
int r2 = this.radius*this.radius;
|
int r2 = this.radius*this.radius;
|
||||||
for (int a = -this.radius; a <= this.radius; a++) {
|
for (int a = -this.radius; a <= this.radius; a++) {
|
||||||
|
//IntStream.range(-this.radius, this.radius+1).parallel().forEach(a->{
|
||||||
int b = (int) Math.floor(Math.sqrt(r2-(a*a)));
|
int b = (int) Math.floor(Math.sqrt(r2-(a*a)));
|
||||||
for (int c = -b; c <= b; c++) {
|
for (int c = -b; c <= b; c++) {
|
||||||
this.enter.callback(a + cx, c + cz);
|
this.enter.callback(a + cx, c + cz);
|
||||||
@@ -261,8 +294,12 @@ public class DistanceTracker {
|
|||||||
outsideCallback.callback(a + cx, c + cz);
|
outsideCallback.callback(a + cx, c + cz);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}//);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCenter(int x, int z) {
|
||||||
|
int cx = x>>this.shiftSize;
|
||||||
|
int cz = z>>this.shiftSize;
|
||||||
this.currentX = cx;
|
this.currentX = cx;
|
||||||
this.currentZ = cz;
|
this.currentZ = cz;
|
||||||
this.lastUpdateX = x + (((int)(Math.random()*4))<<(this.shiftSize-4));
|
this.lastUpdateX = x + (((int)(Math.random()*4))<<(this.shiftSize-4));
|
||||||
|
|||||||
@@ -347,7 +347,7 @@ public class ModelManager {
|
|||||||
public void addBiome(int id, Biome biome) {
|
public void addBiome(int id, Biome biome) {
|
||||||
this.biomes.add(biome);
|
this.biomes.add(biome);
|
||||||
if (this.biomes.size()-1 != id) {
|
if (this.biomes.size()-1 != id) {
|
||||||
throw new IllegalStateException("Biome ordering not consistent with biome id");
|
throw new IllegalStateException("Biome ordering not consistent with biome id for biome " + biome + " expected id: " + (this.biomes.size()-1) + " got id: " + id);
|
||||||
}
|
}
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|||||||
@@ -164,7 +164,8 @@ public class ModelTextureBakery {
|
|||||||
|
|
||||||
this.rasterShader.bind();
|
this.rasterShader.bind();
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
glBindTexture(GL_TEXTURE_2D, MinecraftClient.getInstance().getTextureManager().getTexture(new Identifier("minecraft", "textures/atlas/blocks.png")).getGlId());
|
int texId = MinecraftClient.getInstance().getTextureManager().getTexture(new Identifier("minecraft", "textures/atlas/blocks.png")).getGlId();
|
||||||
|
glBindTexture(GL_TEXTURE_2D, texId);
|
||||||
GlUniform.uniform1(0, 0);
|
GlUniform.uniform1(0, 0);
|
||||||
|
|
||||||
var faces = new ColourDepthTextureData[FACE_VIEWS.size()];
|
var faces = new ColourDepthTextureData[FACE_VIEWS.size()];
|
||||||
@@ -192,6 +193,23 @@ public class ModelTextureBakery {
|
|||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||||
vc.begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_COLOR_TEXTURE);
|
vc.begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_COLOR_TEXTURE);
|
||||||
|
|
||||||
|
|
||||||
|
//if (state.hasBlockEntity() && state.getBlock() == Blocks.CHEST) {
|
||||||
|
// //TODO: finish BlockEntity raster
|
||||||
|
// var entity = ((BlockEntityProvider)state.getBlock()).createBlockEntity(BlockPos.ORIGIN, state);
|
||||||
|
// var renderer = MinecraftClient.getInstance().getBlockEntityRenderDispatcher().get(entity);
|
||||||
|
// if (renderer != null) {
|
||||||
|
// entity.setWorld(MinecraftClient.getInstance().world);
|
||||||
|
// renderer.render(entity, 0.0f, new MatrixStack(), (layer) -> {
|
||||||
|
// //glBindTexture(GL_TEXTURE_2D);
|
||||||
|
// return vc;
|
||||||
|
// }, 0, 0);
|
||||||
|
// }
|
||||||
|
// entity.markRemoved();
|
||||||
|
//}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (!renderFluid) {
|
if (!renderFluid) {
|
||||||
renderQuads(vc, state, model, new MatrixStack(), randomValue);
|
renderQuads(vc, state, model, new MatrixStack(), randomValue);
|
||||||
} else {
|
} else {
|
||||||
@@ -260,15 +278,6 @@ public class ModelTextureBakery {
|
|||||||
BufferRenderer.draw(vc.end());
|
BufferRenderer.draw(vc.end());
|
||||||
|
|
||||||
|
|
||||||
if (state.hasBlockEntity()) {
|
|
||||||
//TODO: finish BlockEntity raster
|
|
||||||
//var entity = ((BlockEntityProvider)state).createBlockEntity(BlockPos.ORIGIN, state);
|
|
||||||
//var renderer = MinecraftClient.getInstance().getBlockEntityRenderDispatcher().get(entity);
|
|
||||||
//renderer.render();
|
|
||||||
//entity.markRemoved();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT);
|
glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT);
|
||||||
int[] colourData = new int[this.width*this.height];
|
int[] colourData = new int[this.width*this.height];
|
||||||
int[] depthData = new int[this.width*this.height];
|
int[] depthData = new int[this.width*this.height];
|
||||||
|
|||||||
@@ -95,7 +95,8 @@ public class TextureUtils {
|
|||||||
// due to this and the unsigned bullshit, i believe the depth value needs to get multiplied by 2
|
// due to this and the unsigned bullshit, i believe the depth value needs to get multiplied by 2
|
||||||
depthF *= 2;
|
depthF *= 2;
|
||||||
if (depthF > 1.00001f) {
|
if (depthF > 1.00001f) {
|
||||||
throw new IllegalArgumentException("Depth greater than 1");
|
System.err.println("Warning: Depth greater than 1");
|
||||||
|
depthF = 1.0f;
|
||||||
}
|
}
|
||||||
return depthF;
|
return depthF;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ public abstract class AbstractFarWorldRenderer {
|
|||||||
UploadStream.INSTANCE.commit();
|
UploadStream.INSTANCE.commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
int maxUpdatesPerFrame = 30;
|
int maxUpdatesPerFrame = 10;
|
||||||
|
|
||||||
//Do any BlockChanges
|
//Do any BlockChanges
|
||||||
while ((!this.blockStateUpdates.isEmpty()) && (maxUpdatesPerFrame-- > 0)) {
|
while ((!this.blockStateUpdates.isEmpty()) && (maxUpdatesPerFrame-- > 0)) {
|
||||||
|
|||||||
@@ -141,8 +141,8 @@ public class RenderTracker {
|
|||||||
|
|
||||||
//Enqueues a renderTask for a section to cache the result
|
//Enqueues a renderTask for a section to cache the result
|
||||||
public void addCache(int lvl, int x, int y, int z) {
|
public void addCache(int lvl, int x, int y, int z) {
|
||||||
//this.renderGen.markCache(lvl, x, y, z);
|
this.renderGen.markCache(lvl, x, y, z);
|
||||||
//this.renderGen.enqueueTask(lvl, x, y, z, ((lvl1, x1, y1, z1) -> true));//TODO: replace the true identity lambda with a callback check to the render cache
|
this.renderGen.enqueueTask(lvl, x, y, z, ((lvl1, x1, y1, z1) -> true));//TODO: replace the true identity lambda with a callback check to the render cache
|
||||||
}
|
}
|
||||||
|
|
||||||
//Removes the position from the cache
|
//Removes the position from the cache
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ package me.cortex.voxy.client.core.rendering.building;
|
|||||||
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
//TODO: Have a second level disk cache
|
||||||
|
|
||||||
//TODO: instead of storing duplicate render geometry between here and gpu memory
|
//TODO: instead of storing duplicate render geometry between here and gpu memory
|
||||||
// when a section is unloaded from the gpu, put it into a download stream and recover the BuiltSection
|
// when a section is unloaded from the gpu, put it into a download stream and recover the BuiltSection
|
||||||
// and put that into the cache, then remove the uploaded mesh from the cache
|
// and put that into the cache, then remove the uploaded mesh from the cache
|
||||||
@@ -24,7 +26,9 @@ public class BuiltSectionMeshCache {
|
|||||||
//Returns true if the mesh was used, (this is so the parent method can free mesh object)
|
//Returns true if the mesh was used, (this is so the parent method can free mesh object)
|
||||||
public boolean putMesh(BuiltSection mesh) {
|
public boolean putMesh(BuiltSection mesh) {
|
||||||
var mesh2 = this.renderCache.computeIfPresent(mesh.position, (id, value) -> {
|
var mesh2 = this.renderCache.computeIfPresent(mesh.position, (id, value) -> {
|
||||||
value.free();
|
if (value != HOLDER) {
|
||||||
|
value.free();
|
||||||
|
}
|
||||||
return mesh;
|
return mesh;
|
||||||
});
|
});
|
||||||
return mesh2 == mesh;
|
return mesh2 == mesh;
|
||||||
|
|||||||
@@ -61,6 +61,11 @@ public class RenderGenerationService {
|
|||||||
try {
|
try {
|
||||||
mesh = factory.generateMesh(section);
|
mesh = factory.generateMesh(section);
|
||||||
} catch (IdNotYetComputedException e) {
|
} catch (IdNotYetComputedException e) {
|
||||||
|
try {
|
||||||
|
Thread.sleep(100);
|
||||||
|
} catch (InterruptedException ex) {
|
||||||
|
throw new RuntimeException(ex);
|
||||||
|
}
|
||||||
//We need to reinsert the build task into the queue
|
//We need to reinsert the build task into the queue
|
||||||
//System.err.println("Render task failed to complete due to un-computed client id");
|
//System.err.println("Render task failed to complete due to un-computed client id");
|
||||||
synchronized (this.taskQueue) {
|
synchronized (this.taskQueue) {
|
||||||
|
|||||||
Reference in New Issue
Block a user