Textures almost working, fixed up the mesher being a dumbass

This commit is contained in:
mcrcortex
2024-01-25 12:46:16 +10:00
parent c2f7712448
commit a391f34ab7
8 changed files with 121 additions and 58 deletions

View File

@@ -99,7 +99,7 @@ public class VoxelCore {
this.firstTime = false;
}
this.distanceTracker.setCenter(camera.getBlockPos().getX(), camera.getBlockPos().getY(), camera.getBlockPos().getZ());
//this.renderer.setupRender(frustum, camera);
this.renderer.setupRender(frustum, camera);
}
public void renderOpaque(MatrixStack matrices, double cameraX, double cameraY, double cameraZ) {
@@ -109,7 +109,7 @@ public class VoxelCore {
matrices.pop();
//this.renderer.getModelManager().updateEntry(0, Blocks.COMPARATOR.getDefaultState());
this.renderer.getModelManager().updateEntry(0, Blocks.OAK_LEAVES.getDefaultState());
//this.renderer.getModelManager().updateEntry(0, Blocks.OAK_LEAVES.getDefaultState());
//int boundFB = GlStateManager.getBoundFramebuffer();
//this.postProcessing.setSize(MinecraftClient.getInstance().getFramebuffer().textureWidth, MinecraftClient.getInstance().getFramebuffer().textureHeight);
@@ -123,8 +123,8 @@ public class VoxelCore {
//TODO: have the renderer also render a bounding full face just like black boarders around lvl 0
// this is cause the terrain might not exist and so all the caves are visible causing hell for the
// occlusion culler
if (false)
this.renderer.renderFarAwayOpaque(matrices, cameraX, cameraY, cameraZ);
this.renderer.renderFarAwayOpaque(matrices, cameraX, cameraY, cameraZ);
//glBindFramebuffer(GL_FRAMEBUFFER, boundFB);

View File

@@ -1,19 +1,40 @@
package me.cortex.zenith.client.core.model;
import com.mojang.blaze3d.platform.GlStateManager;
import me.cortex.zenith.client.core.gl.GlBuffer;
import me.cortex.zenith.client.core.gl.GlTexture;
import net.minecraft.block.BlockState;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.color.block.BlockColors;
import net.minecraft.registry.Registries;
import org.lwjgl.opengl.GL45C;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL11C.GL_NEAREST;
import static org.lwjgl.opengl.GL11C.GL_NEAREST_MIPMAP_LINEAR;
import static org.lwjgl.opengl.GL12C.GL_TEXTURE_MAX_LOD;
import static org.lwjgl.opengl.GL12C.GL_TEXTURE_MIN_LOD;
import static org.lwjgl.opengl.GL33.glDeleteSamplers;
import static org.lwjgl.opengl.GL33.glGenSamplers;
import static org.lwjgl.opengl.GL33C.glSamplerParameteri;
import static org.lwjgl.opengl.GL45C.glTextureSubImage2D;
//Manages the storage and updating of model states, textures and colours
//Also has a fast long[] based metadata lookup for when the terrain mesher needs to look up the face occlusion data
//TODO: support more than 65535 states, what should actually happen is a blockstate is registered, the model data is generated, then compared
// to all other models already loaded, if it is a duplicate, create a mapping from the id to the already loaded id, this will help with meshing aswell
// as leaves and such will be able to be merged
public class ModelManager {
public static final int MODEL_SIZE = 64;
private final ModelTextureBakery bakery = new ModelTextureBakery(16, 16);
private final ModelTextureBakery bakery;
private final GlBuffer modelBuffer;
private final GlTexture textures;
private final int blockSampler = glGenSamplers();
//Model data might also contain a constant colour if the colour resolver produces a constant colour, this saves space in the
// section buffer reverse indexing
//The Meta-cache contains critical information needed for meshing, colour provider bit, per-face = is empty, has alpha, is solid, full width, full height
// alpha means that some pixels have alpha values and belong in the translucent rendering layer,
@@ -38,9 +59,24 @@ public class ModelManager {
// this has an issue with scaffolding i believe tho, so maybe make it a probability to render??? idk
private final long[] metadataCache;
public ModelManager() {
//Provides a map from id -> model id as multiple ids might have the same internal model id
private final int[] idMappings;
private final int modelTextureSize;
public ModelManager(int modelTextureSize) {
this.modelTextureSize = modelTextureSize;
this.bakery = new ModelTextureBakery(modelTextureSize, modelTextureSize);
this.modelBuffer = new GlBuffer(MODEL_SIZE * (1<<16));
//TODO: figure out how to do mipping :blobfox_pineapple:
this.textures = new GlTexture().store(GL_RGBA8, 1, modelTextureSize*3*256,modelTextureSize*2*256);
this.metadataCache = new long[1<<16];
this.idMappings = new int[1<<16];
glSamplerParameteri(this.blockSampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
glSamplerParameteri(this.blockSampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glSamplerParameteri(this.blockSampler, GL_TEXTURE_MIN_LOD, 0);
glSamplerParameteri(this.blockSampler, GL_TEXTURE_MAX_LOD, 4);
}
public void updateEntry(int id, BlockState blockState) {
@@ -64,6 +100,16 @@ public class ModelManager {
}
private void putTextures(int id, ColourDepthTextureData[] textures) {
int X = (id&0xFF) * this.modelTextureSize*3;
int Y = ((id>>8)&0xFF) * this.modelTextureSize*2;
for (int subTex = 0; subTex < 6; subTex++) {
//glTextureSubImage2D(this.textures.id, 0, );
}
}
public long getModelMetadata(int id) {
return this.metadataCache[id];
}
@@ -72,8 +118,17 @@ public class ModelManager {
return this.modelBuffer.id;
}
public int getTextureId() {
return this.textures.id;
}
public int getSamplerId() {
return this.blockSampler;
}
public void free() {
this.bakery.free();
this.modelBuffer.free();
this.textures.free();
glDeleteSamplers(this.blockSampler);
}
}

View File

@@ -47,7 +47,7 @@ public abstract class AbstractFarWorldRenderer {
this.uniformBuffer = new GlBuffer(1024);
this.lightDataBuffer = new GlBuffer(256*4);//256 of uint
this.geometry = new GeometryManager(geometrySize*8L, maxSections);
this.models = new ModelManager();
this.models = new ModelManager(16);
}
protected abstract void setupVao();

View File

@@ -1,5 +1,6 @@
package me.cortex.zenith.client.core.rendering;
import com.mojang.blaze3d.platform.GlStateManager;
import com.mojang.blaze3d.systems.RenderSystem;
import me.cortex.zenith.client.core.gl.GlBuffer;
import me.cortex.zenith.client.core.gl.shader.Shader;
@@ -10,6 +11,8 @@ import net.minecraft.client.render.RenderLayer;
import net.minecraft.client.util.math.MatrixStack;
import org.joml.Matrix4f;
import org.joml.Vector3f;
import org.lwjgl.opengl.GL11C;
import org.lwjgl.opengl.GL45C;
import org.lwjgl.system.MemoryUtil;
import java.util.List;
@@ -17,6 +20,7 @@ import java.util.List;
import static org.lwjgl.opengl.ARBMultiDrawIndirect.glMultiDrawElementsIndirect;
import static org.lwjgl.opengl.GL11.GL_TRIANGLES;
import static org.lwjgl.opengl.GL11.GL_UNSIGNED_SHORT;
import static org.lwjgl.opengl.GL11.glGetInteger;
import static org.lwjgl.opengl.GL30.glBindVertexArray;
import static org.lwjgl.opengl.GL30C.GL_R8UI;
import static org.lwjgl.opengl.GL30C.GL_RED_INTEGER;
@@ -77,6 +81,8 @@ public class Gl46FarWorldRenderer extends AbstractFarWorldRenderer {
return;
}
RenderLayer.getCutoutMipped().startDrawing();
int oldActiveTexture = glGetInteger(GL_ACTIVE_TEXTURE);
int oldBoundTexture = glGetInteger(GL_TEXTURE_BINDING_2D);
//RenderSystem.enableBlend();
//RenderSystem.defaultBlendFunc();
@@ -85,32 +91,23 @@ public class Gl46FarWorldRenderer extends AbstractFarWorldRenderer {
UploadStream.INSTANCE.commit();
glBindVertexArray(this.vao);
//Bind the texture atlas
glBindSampler(0, this.models.getSamplerId());
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, this.models.getTextureId());
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();
if (false) {//Bloody intel gpus
glMultiDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT, 0, 1000, 0);
//int count = this.geometry.getSectionCount()/1000;
//for (int i = 0; i < 10; i++) {
// glMultiDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT, i*1000L*20, 1000, 0);
//}
//int rem = this.geometry.getSectionCount() - (count*1000);
//if (rem != 0) {
// glMultiDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT, count*1000L*20, rem, 0);
//}
} else {
//TODO: swap to a multidraw indirect counted
glMultiDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT, 0, this.geometry.getSectionCount(), 0);
}
glMultiDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT, 0, this.geometry.getSectionCount(), 0);
//ARBIndirectParameters.glMultiDrawElementsIndirectCountARB(
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);
@@ -124,8 +121,13 @@ public class Gl46FarWorldRenderer extends AbstractFarWorldRenderer {
glColorMask(true, true, true, true);
glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
glBindVertexArray(0);
//TODO: need to do temporal rasterization here
glBindVertexArray(0);
glBindSampler(0, 0);
GL11C.glBindTexture(GL_TEXTURE_2D, oldBoundTexture);
glActiveTexture(oldActiveTexture);
RenderLayer.getCutoutMipped().endDrawing();
}

View File

@@ -81,7 +81,7 @@ public class Mesher2D {
while (ex || ez) {
//Expand in the x direction
if (ex) {
if (endX + 1 > this.maxSize || endX+1 == (1 << this.size) - 1) {
if (endX - x >= this.maxSize || endX >= (1 << this.size) - 1) {
ex = false;
}
}
@@ -96,7 +96,7 @@ public class Mesher2D {
endX++;
}
if (ez) {
if (endZ + 1 > this.maxSize || endZ+1 == (1<<this.size)-1) {
if (endZ - z >= this.maxSize || endZ >= (1<<this.size)-1) {
ez = false;
}
}
@@ -143,7 +143,31 @@ public class Mesher2D {
return this.quadCache;
}
public void reset() {
this.setset.clear();
Arrays.fill(this.data, 0);
}
public long getDataFromQuad(int quad) {
return this.getData(getX(quad), getZ(quad));
}
public long getData(int x, int z) {
return this.data[this.getIdx(x, z)];
}
public static void main(String[] args) {
var mesh = new Mesher2D(5,15);
mesh.put(30,30, 123);
mesh.put(31,30, 123);
mesh.put(30,31, 123);
mesh.put(31,31, 123);
int count = mesh.process();
System.err.println(count);
}
public static void main2(String[] args) {
var r = new Random(123451);
int a = 0;
long total = 0;
@@ -161,18 +185,5 @@ public class Mesher2D {
System.out.println((double) (total/(1e+6))/200000);
//mesh.put(0,0,1);
}
public void reset() {
this.setset.clear();
Arrays.fill(this.data, 0);
}
public long getDataFromQuad(int quad) {
return this.getData(getX(quad), getZ(quad));
}
public long getData(int x, int z) {
return this.data[this.getIdx(x, z)];
}
}

View File

@@ -29,6 +29,8 @@ struct DrawCommand {
uint baseInstance;
};
layout(binding = 0) uniform sampler2D blockModelAtlas;
#ifndef Quad
#define Quad ivec2
#endif
@@ -65,3 +67,5 @@ vec4 getLighting(uint index) {
arr = arr & uvec4(0xFF);
return vec4(arr)*vec4(1.0f/255.0f);
}

View File

@@ -1,8 +1,9 @@
#version 460 core
layout(location = 0) in flat vec4 colour;
layout(binding = 0) uniform sampler2D blockModelAtlas;
layout(location = 0) in vec2 uv;
layout(location = 0) out vec4 outColour;
void main() {
//TODO: randomly discard the fragment with respect to the alpha value
vec2 uv = mod(uv, vec2(1));
outColour = colour;
outColour = texture(blockModelAtlas, uv);
}

View File

@@ -4,7 +4,7 @@
#import <zenith:lod/gl46/quad_format.glsl>
#import <zenith:lod/gl46/bindings.glsl>
layout(location = 0) out flat vec4 colour;
layout(location = 0) out vec2 uv;
uint extractLodLevel() {
return uint(gl_BaseInstance)>>29;
@@ -41,7 +41,8 @@ void main() {
cornerIdx ^= 1;
}
ivec2 size = extractSize(quad) * ivec2((cornerIdx>>1)&1, cornerIdx&1) * (1<<lodLevel);
ivec2 sizePreLod = extractSize(quad) * ivec2((cornerIdx>>1)&1, cornerIdx&1);
ivec2 size = sizePreLod * (1<<lodLevel);
vec3 pos = corner;
@@ -63,19 +64,8 @@ void main() {
uint stateId = extractStateId(quad);
uint biomeId = extractBiomeId(quad);
BlockModel stateInfo = modelData[stateId];
colour = uint2vec4RGBA(stateInfo.faceColours[face]);
colour *= getLighting(extractLightId(quad));
//Apply face tint
if (face == 0) {
colour.xyz *= vec3(0.75, 0.75, 0.75);
} else if (face != 1) {
colour.xyz *= vec3((float(face-2)/4)*0.6 + 0.4);
}
uv = vec2(sizePreLod);
}
//gl_Position = MVP * vec4(vec3(((cornerIdx)&1)+10,10,((cornerIdx>>1)&1)+10),1);
//uint i = uint(quad>>32);