Lots of fixes

This commit is contained in:
mcrcortex
2024-01-29 11:18:16 +10:00
parent c4efd29206
commit 6302d3db1e
9 changed files with 308 additions and 35 deletions

View File

@@ -99,6 +99,7 @@ public class VoxelCore {
if (this.firstTime) {
this.distanceTracker.init(camera.getBlockPos().getX(), camera.getBlockPos().getZ());
this.firstTime = false;
//this.renderTracker.addLvl0(0,6,0);
}
this.distanceTracker.setCenter(camera.getBlockPos().getX(), camera.getBlockPos().getY(), camera.getBlockPos().getZ());
this.renderer.setupRender(frustum, camera);

View File

@@ -49,15 +49,7 @@ public class ModelTextureBakery {
.compile();
private static final List<MatrixStack> FACE_VIEWS = new ArrayList<>();
static {
addView(-90,0, 0);//Direction.DOWN
addView(90,0, 0);//Direction.UP
addView(0,180, 0);//Direction.NORTH
addView(0,0, 0);//Direction.SOUTH
//TODO: check these arnt the wrong way round
addView(0,90, 270);//Direction.EAST
addView(0,270, 270);//Direction.WEST
}
public ModelTextureBakery(int width, int height) {
this.width = width;
@@ -65,9 +57,23 @@ public class ModelTextureBakery {
this.colourTex = new GlTexture().store(GL_RGBA8, 1, width, height);
this.depthTex = new GlTexture().store(GL_DEPTH24_STENCIL8, 1, width, height);
this.framebuffer = new GlFramebuffer().bind(GL_COLOR_ATTACHMENT0, this.colourTex).bind(GL_DEPTH_STENCIL_ATTACHMENT, this.depthTex).verify();
//This is done to help make debugging easier
FACE_VIEWS.clear();
AddViews();
}
private static void addView(float pitch, float yaw, float rotation) {
private static void AddViews() {
addView(-90,0, 0, false);//Direction.DOWN
addView(90,0, 0, false);//Direction.UP
addView(0,180, 0, true);//Direction.NORTH
addView(0,0, 0, false);//Direction.SOUTH
//TODO: check these arnt the wrong way round
addView(0,90, 270, false);//Direction.EAST
addView(0,270, 270, false);//Direction.WEST
}
private static void addView(float pitch, float yaw, float rotation, boolean flipX) {
var stack = new MatrixStack();
stack.translate(0.5f,0.5f,0.5f);
stack.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(rotation));

View File

@@ -14,11 +14,14 @@ import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.util.math.Direction;
import org.joml.Matrix4f;
import org.joml.Vector3f;
import org.lwjgl.opengl.ARBIndirectParameters;
import org.lwjgl.opengl.GL11C;
import org.lwjgl.system.MemoryUtil;
import java.util.List;
import static org.lwjgl.opengl.ARBIndirectParameters.GL_PARAMETER_BUFFER_ARB;
import static org.lwjgl.opengl.ARBIndirectParameters.glMultiDrawElementsIndirectCountARB;
import static org.lwjgl.opengl.ARBMultiDrawIndirect.glMultiDrawElementsIndirect;
import static org.lwjgl.opengl.GL11.GL_TRIANGLES;
import static org.lwjgl.opengl.GL11.GL_UNSIGNED_SHORT;
@@ -51,11 +54,13 @@ public class Gl46FarWorldRenderer extends AbstractFarWorldRenderer {
.compile();
private final GlBuffer glCommandBuffer;
private final GlBuffer glCommandCountBuffer;
private final GlBuffer glVisibilityBuffer;
public Gl46FarWorldRenderer(int geometryBuffer, int maxSections) {
super(geometryBuffer, maxSections);
this.glCommandBuffer = new GlBuffer(maxSections*5L*4);
this.glCommandCountBuffer = new GlBuffer(4*2);
this.glVisibilityBuffer = new GlBuffer(maxSections*4L);
glClearNamedBufferData(this.glCommandBuffer.id, GL_R8UI, GL_RED_INTEGER, GL_UNSIGNED_BYTE, new int[1]);
glClearNamedBufferData(this.glVisibilityBuffer.id, GL_R8UI, GL_RED_INTEGER, GL_UNSIGNED_BYTE, new int[1]);
@@ -66,14 +71,16 @@ public class Gl46FarWorldRenderer extends AbstractFarWorldRenderer {
protected void setupVao() {
glBindVertexArray(this.vao);
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, this.glCommandBuffer.id);
glBindBuffer(GL_PARAMETER_BUFFER_ARB, this.glCommandCountBuffer.id);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, SharedIndexBuffer.INSTANCE.id());
glBindBufferBase(GL_UNIFORM_BUFFER, 0, this.uniformBuffer.id);
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.glVisibilityBuffer.id);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 5, this.models.getBufferId());
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 6, this.lightDataBuffer.id);//Lighting LUT
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, this.glCommandCountBuffer.id);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, this.geometry.metaId());
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 5, this.glVisibilityBuffer.id);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 6, this.models.getBufferId());
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 7, this.lightDataBuffer.id);//Lighting LUT
glBindVertexArray(0);
}
@@ -82,6 +89,8 @@ public class Gl46FarWorldRenderer extends AbstractFarWorldRenderer {
return;
}
//this.models.addEntry(0, Blocks.OAK_FENCE.getDefaultState());
RenderLayer.getCutoutMipped().startDrawing();
int oldActiveTexture = glGetInteger(GL_ACTIVE_TEXTURE);
@@ -101,16 +110,15 @@ public class Gl46FarWorldRenderer extends AbstractFarWorldRenderer {
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, this.models.getTextureId());
glClearNamedBufferData(this.glCommandCountBuffer.id, GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT, new int[1]);
this.commandGen.bind();
glDispatchCompute((this.geometry.getSectionCount() + 127) / 128, 1, 1);
glMemoryBarrier(GL_COMMAND_BARRIER_BIT | GL_SHADER_STORAGE_BARRIER_BIT | GL_UNIFORM_BARRIER_BIT);
this.lodShader.bind();
glDisable(GL_CULL_FACE);
glMultiDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT, 0, this.geometry.getSectionCount(), 0);
glMultiDrawElementsIndirectCountARB(GL_TRIANGLES, GL_UNSIGNED_SHORT, 0, 0, (int) (this.geometry.getSectionCount()*4.4), 0);
glEnable(GL_CULL_FACE);
//ARBIndirectParameters.glMultiDrawElementsIndirectCountARB(
glMemoryBarrier(GL_PIXEL_BUFFER_BARRIER_BIT | GL_FRAMEBUFFER_BARRIER_BIT);
@@ -164,6 +172,7 @@ public class Gl46FarWorldRenderer extends AbstractFarWorldRenderer {
this.cullShader.free();
this.glCommandBuffer.free();
this.glVisibilityBuffer.free();
this.glCommandCountBuffer.free();
}
@Override

View File

@@ -7,6 +7,7 @@ import me.cortex.zenith.common.util.MemoryBuffer;
import me.cortex.zenith.common.world.WorldEngine;
import me.cortex.zenith.common.world.WorldSection;
import me.cortex.zenith.common.world.other.Mapper;
import net.minecraft.block.Blocks;
import net.minecraft.client.MinecraftClient;
import org.lwjgl.system.MemoryUtil;
@@ -47,7 +48,6 @@ public class RenderDataFactory {
LongArrayList outData = new LongArrayList(1000);
//Up direction
for (int y = 0; y < 32; y++) {
mesher.reset();
for (int x = 0; x < 32; x++) {
@@ -91,7 +91,195 @@ public class RenderDataFactory {
int quad = array[i];
long data = mesher.getDataFromQuad(quad);
outData.add(Integer.toUnsignedLong(QuadEncoder.encodePosition(1, y, quad)) | ((data&0xFFFF)<<26) | (((data>>16)&0xFF)<<55) | (((data>>24)&0x1FF)<<46));
//outData.add(Integer.toUnsignedLong(QuadEncoder.encodePosition(1, y, quad)) | (1<<26));
}
}
//North direction
for (int z = 0; z < 32; z++) {
mesher.reset();
for (int x = 0; x < 32; x++) {
for (int y = 0; y < 32; y++) {
long self = this.sectionCache[WorldSection.getIndex(x, y, z)];
if (Mapper.isAir(self)) continue;
int selfBlockId = Mapper.getBlockId(self);
long metadata = this.modelMan.getModelMetadata(selfBlockId);
//If the model doesnt have a face, then just skip it
if (!ModelManager.faceExists(metadata, 2)) {
continue;
}
long facingState = Mapper.AIR;
//Need to access the other connecting section
if (z == 0) {
} else {
facingState = this.sectionCache[WorldSection.getIndex(x, y, z-1)];
}
long facingMetadata = this.modelMan.getModelMetadata(Mapper.getBlockId(facingState));
//If face can be occluded and is occluded from the facing block, then dont render the face
if (ModelManager.faceCanBeOccluded(metadata, 2) && ModelManager.faceOccludes(facingMetadata, 3)) {
continue;
}
int clientModelId = this.modelMan.getModelId(selfBlockId);
mesher.put(x, y, ((long)clientModelId) | (((long) Mapper.getLightId(facingState))<<16) | (((long) Mapper.getBiomeId(self))<<24));
}
}
//TODO: encode translucents and double sided quads to different global buffers
int count = mesher.process();
var array = mesher.getArray();
for (int i = 0; i < count; i++) {
int quad = array[i];
long data = mesher.getDataFromQuad(quad);
outData.add(Integer.toUnsignedLong(QuadEncoder.encodePosition(2, z, quad)) | ((data&0xFFFF)<<26) | (((data>>16)&0xFF)<<55) | (((data>>24)&0x1FF)<<46));
}
}
//South direction
for (int z = 0; z < 32; z++) {
mesher.reset();
for (int x = 0; x < 32; x++) {
for (int y = 0; y < 32; y++) {
long self = this.sectionCache[WorldSection.getIndex(x, y, z)];
if (Mapper.isAir(self)) continue;
int selfBlockId = Mapper.getBlockId(self);
long metadata = this.modelMan.getModelMetadata(selfBlockId);
//If the model doesnt have a face, then just skip it
if (!ModelManager.faceExists(metadata, 3)) {
continue;
}
long facingState = Mapper.AIR;
//Need to access the other connecting section
if (z == 31) {
} else {
facingState = this.sectionCache[WorldSection.getIndex(x, y, z+1)];
}
long facingMetadata = this.modelMan.getModelMetadata(Mapper.getBlockId(facingState));
//If face can be occluded and is occluded from the facing block, then dont render the face
if (ModelManager.faceCanBeOccluded(metadata, 3) && ModelManager.faceOccludes(facingMetadata, 2)) {
continue;
}
int clientModelId = this.modelMan.getModelId(selfBlockId);
mesher.put(x, y, ((long)clientModelId) | (((long) Mapper.getLightId(facingState))<<16) | (((long) Mapper.getBiomeId(self))<<24));
}
}
//TODO: encode translucents and double sided quads to different global buffers
int count = mesher.process();
var array = mesher.getArray();
for (int i = 0; i < count; i++) {
int quad = array[i];
long data = mesher.getDataFromQuad(quad);
outData.add(Integer.toUnsignedLong(QuadEncoder.encodePosition(3, z, quad)) | ((data&0xFFFF)<<26) | (((data>>16)&0xFF)<<55) | (((data>>24)&0x1FF)<<46));
}
}
//West direction
for (int x = 0; x < 32; x++) {
mesher.reset();
for (int y = 0; y < 32; y++) {
for (int z = 0; z < 32; z++) {
long self = this.sectionCache[WorldSection.getIndex(x, y, z)];
if (Mapper.isAir(self)) continue;
int selfBlockId = Mapper.getBlockId(self);
long metadata = this.modelMan.getModelMetadata(selfBlockId);
//If the model doesnt have a face, then just skip it
if (!ModelManager.faceExists(metadata, 2)) {
continue;
}
long facingState = Mapper.AIR;
//Need to access the other connecting section
if (x == 0) {
} else {
facingState = this.sectionCache[WorldSection.getIndex(x-1, y, z)];
}
long facingMetadata = this.modelMan.getModelMetadata(Mapper.getBlockId(facingState));
//If face can be occluded and is occluded from the facing block, then dont render the face
if (ModelManager.faceCanBeOccluded(metadata, 4) && ModelManager.faceOccludes(facingMetadata, 5)) {
continue;
}
int clientModelId = this.modelMan.getModelId(selfBlockId);
mesher.put(y, z, ((long)clientModelId) | (((long) Mapper.getLightId(facingState))<<16) | (((long) Mapper.getBiomeId(self))<<24));
}
}
//TODO: encode translucents and double sided quads to different global buffers
int count = mesher.process();
var array = mesher.getArray();
for (int i = 0; i < count; i++) {
int quad = array[i];
long data = mesher.getDataFromQuad(quad);
outData.add(Integer.toUnsignedLong(QuadEncoder.encodePosition(4, x, quad)) | ((data&0xFFFF)<<26) | (((data>>16)&0xFF)<<55) | (((data>>24)&0x1FF)<<46));
}
}
//East direction
for (int x = 0; x < 32; x++) {
mesher.reset();
for (int y = 0; y < 32; y++) {
for (int z = 0; z < 32; z++) {
long self = this.sectionCache[WorldSection.getIndex(x, y, z)];
if (Mapper.isAir(self)) continue;
int selfBlockId = Mapper.getBlockId(self);
long metadata = this.modelMan.getModelMetadata(selfBlockId);
//If the model doesnt have a face, then just skip it
if (!ModelManager.faceExists(metadata, 2)) {
continue;
}
long facingState = Mapper.AIR;
//Need to access the other connecting section
if (x == 31) {
} else {
facingState = this.sectionCache[WorldSection.getIndex(x+1, y, z)];
}
long facingMetadata = this.modelMan.getModelMetadata(Mapper.getBlockId(facingState));
//If face can be occluded and is occluded from the facing block, then dont render the face
if (ModelManager.faceCanBeOccluded(metadata, 5) && ModelManager.faceOccludes(facingMetadata, 4)) {
continue;
}
int clientModelId = this.modelMan.getModelId(selfBlockId);
mesher.put(y, z, ((long)clientModelId) | (((long) Mapper.getLightId(facingState))<<16) | (((long) Mapper.getBiomeId(self))<<24));
}
}
//TODO: encode translucents and double sided quads to different global buffers
int count = mesher.process();
var array = mesher.getArray();
for (int i = 0; i < count; i++) {
int quad = array[i];
long data = mesher.getDataFromQuad(quad);
outData.add(Integer.toUnsignedLong(QuadEncoder.encodePosition(5, x, quad)) | ((data&0xFFFF)<<26) | (((data>>16)&0xFF)<<55) | (((data>>24)&0x1FF)<<46));
}
}
@@ -111,8 +299,18 @@ public class RenderDataFactory {
if (outData.isEmpty()) {
return new BuiltSection(section.getKey(), null, null);
}
//outData.clear();
//int modelId = this.modelMan.getModelId(this.world.getMapper().getIdFromBlockState(Blocks.OAK_FENCE.getDefaultState()));
int modelId = this.modelMan.getModelId(this.world.getMapper().getIdFromBlockState(Blocks.OAK_FENCE.getDefaultState()));
//outData.add(encodeRaw(0, 0,0,0,0,0, modelId,0, 0));
//outData.add(encodeRaw(1, 0,0,0,0,0, modelId,0, 0));
//outData.add(encodeRaw(2, 0,0,0,0,0, modelId,0, 0));
//outData.add(encodeRaw(3, 0,0,0,0,0, modelId,0, 0));
//outData.add(encodeRaw(4, 0,0,0,0,0, modelId,0, 0));
//outData.add(encodeRaw(5, 0,0,0,0,0, modelId,0, 0));
//outData.add(encodeRaw(3, 0,1,0,0,0,159,0, 0));
var buff = new MemoryBuffer(outData.size()*8L);
long ptr = buff.address;
for (long data : outData) {
@@ -127,4 +325,56 @@ public class RenderDataFactory {
return ((long)face) | (((long) width)<<3) | (((long) height)<<7) | (((long) z)<<11) | (((long) y)<<16) | (((long) x)<<21) | (((long) blockId)<<26) | (((long) biomeId)<<46) | (((long) lightId)<<55);
}
/*
private void generateMeshForAxis() {
//Up direction
for (int y = 0; y < 32; y++) {
mesher.reset();
for (int x = 0; x < 32; x++) {
for (int z = 0; z < 32; z++) {
long self = this.sectionCache[WorldSection.getIndex(x, y, z)];
if (Mapper.isAir(self)) continue;
int selfBlockId = Mapper.getBlockId(self);
long metadata = this.modelMan.getModelMetadata(selfBlockId);
//If the model doesnt have a face, then just skip it
if (!ModelManager.faceExists(metadata, 1)) {
continue;
}
long facingState = Mapper.AIR;
//Need to access the other connecting section
if (y == 31) {
} else {
facingState = this.sectionCache[WorldSection.getIndex(x, y+1, z)];
}
long facingMetadata = this.modelMan.getModelMetadata(Mapper.getBlockId(facingState));
//If face can be occluded and is occluded from the facing block, then dont render the face
if (ModelManager.faceCanBeOccluded(metadata, 1) && ModelManager.faceOccludes(facingMetadata, 0)) {
continue;
}
int clientModelId = this.modelMan.getModelId(selfBlockId);
mesher.put(x, z, ((long)clientModelId) | (((long) Mapper.getLightId(facingState))<<16) | (((long) Mapper.getBiomeId(self))<<24));
}
}
//TODO: encode translucents and double sided quads to different global buffers
int count = mesher.process();
var array = mesher.getArray();
for (int i = 0; i < count; i++) {
int quad = array[i];
long data = mesher.getDataFromQuad(quad);
outData.add(Integer.toUnsignedLong(QuadEncoder.encodePosition(1, y, quad)) | ((data&0xFFFF)<<26) | (((data>>16)&0xFF)<<55) | (((data>>24)&0x1FF)<<46));
}
}
}*/
}

View File

@@ -185,6 +185,14 @@ public class Mapper {
return this.blockId2stateEntry.get(blockId).state;
}
public int getIdFromBlockState(BlockState state) {
var entry = this.block2stateEntry.get(state);
if (entry == null) {
return -1;
}
return entry.id;
}
//TODO: fixme: synchronize access to this.blockId2stateEntry
public StateEntry[] getStateEntries() {
var set = new ArrayList<>(this.blockId2stateEntry);

View File

@@ -49,22 +49,27 @@ layout(binding = 2, std430) writeonly restrict buffer DrawBuffer {
DrawCommand cmdBuffer[];
};
layout(binding = 3, std430) readonly restrict buffer SectionBuffer {
layout(binding = 3, std430) restrict buffer DrawCommandCountBuffer {
uint opaqueDrawCount;
uint translucentDrawCount;
};
layout(binding = 4, std430) readonly restrict buffer SectionBuffer {
SectionMeta sectionData[];
};
#ifndef VISIBILITY_ACCESS
#define VISIBILITY_ACCESS readonly
#endif
layout(binding = 4, std430) VISIBILITY_ACCESS restrict buffer VisibilityBuffer {
layout(binding = 5, std430) VISIBILITY_ACCESS restrict buffer VisibilityBuffer {
uint visibilityData[];
};
layout(binding = 5, std430) readonly restrict buffer ModelBuffer {
layout(binding = 6, std430) readonly restrict buffer ModelBuffer {
BlockModel modelData[];
};
layout(binding = 6, std430) readonly restrict buffer LightingBuffer {
layout(binding = 7, std430) readonly restrict buffer LightingBuffer {
uint lightData[];
};

View File

@@ -61,14 +61,6 @@ void main() {
cmd.firstIndex = 0;
cmd.baseVertex = int(extractQuadStart(meta))<<2;
cmd.baseInstance = encodeLocalLodPos(detail, ipos);
cmdBuffer[gl_GlobalInvocationID.x] = cmd;
} else {
DrawCommand cmd;
cmd.count = 0;
cmd.instanceCount = 0;
cmd.firstIndex = 0;
cmd.baseVertex = 0;
cmd.baseInstance = 0;
cmdBuffer[gl_GlobalInvocationID.x] = cmd;
cmdBuffer[atomicAdd(opaqueDrawCount, 1)] = cmd;
}
}

View File

@@ -14,4 +14,6 @@ void main() {
discard;
}
outColour = colour * colourTinting;
//outColour = vec4(uv + baseUV, 0, 1);
}

View File

@@ -83,9 +83,9 @@ void main() {
//TODO: make the face orientated by 2x3 so that division is not a integer div and modulo isnt needed
// as these are very slow ops
baseUV = modelUV + (vec2(face%3, face/3) * (1f/(vec2(3,2)*256f)));
uv = quadSize;// + faceOffset;//Add in the face offset for 0,0 uv
uv = quadSize + faceOffset;//Add in the face offset for 0,0 uv
discardAlpha = 1;
discardAlpha = 0;
//Compute lighting
colourTinting = getLighting(extractLightId(quad));