Began work on biome colouring
This commit is contained in:
@@ -13,6 +13,9 @@ import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.render.Camera;
|
||||
import net.minecraft.client.render.Frustum;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.registry.RegistryKey;
|
||||
import net.minecraft.registry.RegistryKeys;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.chunk.WorldChunk;
|
||||
|
||||
@@ -72,6 +75,10 @@ public class VoxelCore {
|
||||
////Resave the db incase it failed a recovery
|
||||
//this.world.getMapper().forceResaveStates();
|
||||
|
||||
var biomeRegistry = MinecraftClient.getInstance().world.getRegistryManager().get(RegistryKeys.BIOME);
|
||||
for (var biome : this.world.getMapper().getBiomeEntries()) {
|
||||
this.renderer.getModelManager().addBiome(biome.id, biomeRegistry.get(new Identifier(biome.biome)));
|
||||
}
|
||||
|
||||
for (var state : this.world.getMapper().getStateEntries()) {
|
||||
this.renderer.getModelManager().addEntry(state.id, state.state);
|
||||
|
||||
@@ -16,6 +16,7 @@ import net.minecraft.client.render.RenderLayers;
|
||||
import net.minecraft.fluid.FluidState;
|
||||
import net.minecraft.registry.Registries;
|
||||
import net.minecraft.registry.RegistryKeys;
|
||||
import net.minecraft.util.Pair;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.world.BlockRenderView;
|
||||
@@ -40,6 +41,7 @@ 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.glGenerateTextureMipmap;
|
||||
import static org.lwjgl.opengl.GL45C.glTextureSubImage2D;
|
||||
|
||||
//Manages the storage and updating of model states, textures and colours
|
||||
@@ -53,6 +55,7 @@ public class ModelManager {
|
||||
public static final int MODEL_SIZE = 64;
|
||||
private final ModelTextureBakery bakery;
|
||||
private final GlBuffer modelBuffer;
|
||||
private final GlBuffer modelColourBuffer;
|
||||
private final GlTexture textures;
|
||||
private final int blockSampler = glGenSamplers();
|
||||
|
||||
@@ -91,12 +94,20 @@ public class ModelManager {
|
||||
private final int[] idMappings;
|
||||
private final Object2IntOpenHashMap<List<ColourDepthTextureData>> modelTexture2id = new Object2IntOpenHashMap<>();
|
||||
|
||||
|
||||
private final List<Biome> biomes = new ArrayList<>();
|
||||
private final List<Pair<Integer, BlockState>> modelsRequiringBiomeColours = new ArrayList<>();
|
||||
|
||||
|
||||
public ModelManager(int modelTextureSize) {
|
||||
this.modelTextureSize = modelTextureSize;
|
||||
this.bakery = new ModelTextureBakery(modelTextureSize, modelTextureSize);
|
||||
this.modelBuffer = new GlBuffer(MODEL_SIZE * (1<<16));
|
||||
|
||||
this.modelColourBuffer = new GlBuffer(4 * (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.textures = new GlTexture().store(GL_RGBA8, 4, modelTextureSize*3*256,modelTextureSize*2*256);
|
||||
this.metadataCache = new long[1<<16];
|
||||
this.idMappings = new int[1<<20];//Max of 1 million blockstates mapping to 65k model states
|
||||
Arrays.fill(this.idMappings, -1);
|
||||
@@ -263,11 +274,18 @@ public class ModelManager {
|
||||
//Temporary override to always be non biome specific
|
||||
if (colourProvider == null) {
|
||||
MemoryUtil.memPutInt(uploadPtr + 4, -1);//Set the default to nothing so that its faster on the gpu
|
||||
} else if ((!hasBiomeColourResolver) || true) {
|
||||
} else if (!hasBiomeColourResolver) {
|
||||
Biome defaultBiome = MinecraftClient.getInstance().world.getRegistryManager().get(RegistryKeys.BIOME).get(BiomeKeys.PLAINS);
|
||||
MemoryUtil.memPutInt(uploadPtr + 4, captureColourConstant(colourProvider, blockState, defaultBiome)|0xFF000000);
|
||||
} else {
|
||||
} else if (!this.biomes.isEmpty()) {
|
||||
//Populate the list of biomes for the model state
|
||||
int biomeIndex = this.modelsRequiringBiomeColours.size() * this.biomes.size();
|
||||
MemoryUtil.memPutInt(uploadPtr + 4, biomeIndex);
|
||||
this.modelsRequiringBiomeColours.add(new Pair<>(modelId, blockState));
|
||||
long clrUploadPtr = UploadStream.INSTANCE.upload(this.modelColourBuffer, biomeIndex * 4L, 4L * this.biomes.size());
|
||||
for (var biome : this.biomes) {
|
||||
MemoryUtil.memPutInt(clrUploadPtr, captureColourConstant(colourProvider, blockState, biome)|0xFF000000); clrUploadPtr += 4;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -277,9 +295,21 @@ public class ModelManager {
|
||||
|
||||
|
||||
this.putTextures(modelId, textureData);
|
||||
|
||||
glGenerateTextureMipmap(this.textures.id);
|
||||
return modelId;
|
||||
}
|
||||
|
||||
public void addBiome(int id, Biome biome) {
|
||||
this.biomes.add(biome);
|
||||
if (this.biomes.size()-1 != id) {
|
||||
throw new IllegalStateException("Biome ordering not consistent with biome id");
|
||||
}
|
||||
|
||||
//TODO: Need to invalidate teh entire colour buffer and reuploadd
|
||||
}
|
||||
|
||||
|
||||
//TODO: add a method to detect biome dependent colours (can do by detecting if getColor is ever called)
|
||||
// if it is, need to add it to a list and mark it as biome colour dependent or something then the shader
|
||||
// will either use the uint as an index or a direct colour multiplier
|
||||
@@ -388,6 +418,7 @@ public class ModelManager {
|
||||
|
||||
|
||||
|
||||
|
||||
public static boolean faceExists(long metadata, int face) {
|
||||
return ((metadata>>(8*face))&0xFF)!=0xFF;
|
||||
}
|
||||
@@ -510,9 +541,14 @@ public class ModelManager {
|
||||
return this.blockSampler;
|
||||
}
|
||||
|
||||
public int getColourBufferId() {
|
||||
return this.modelColourBuffer.id;
|
||||
}
|
||||
|
||||
public void free() {
|
||||
this.bakery.free();
|
||||
this.modelBuffer.free();
|
||||
this.modelColourBuffer.free();
|
||||
this.textures.free();
|
||||
glDeleteSamplers(this.blockSampler);
|
||||
}
|
||||
|
||||
@@ -81,7 +81,8 @@ public class Gl46FarWorldRenderer extends AbstractFarWorldRenderer {
|
||||
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
|
||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 7, this.models.getColourBufferId());
|
||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 8, this.lightDataBuffer.id);//Lighting LUT
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,8 @@ public class ActiveSectionTracker {
|
||||
|
||||
private final Long2ObjectOpenHashMap<VolatileHolder<WorldSection>>[] loadedSectionCache;
|
||||
private final SectionLoader loader;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public ActiveSectionTracker(int layers, SectionLoader loader) {
|
||||
this.loader = loader;
|
||||
this.loadedSectionCache = new Long2ObjectOpenHashMap[layers];
|
||||
|
||||
@@ -71,7 +71,11 @@ layout(binding = 6, std430) readonly restrict buffer ModelBuffer {
|
||||
BlockModel modelData[];
|
||||
};
|
||||
|
||||
layout(binding = 7, std430) readonly restrict buffer LightingBuffer {
|
||||
layout(binding = 7, std430) readonly restrict buffer ModelColourBuffer {
|
||||
uint colourData[];
|
||||
};
|
||||
|
||||
layout(binding = 8, std430) readonly restrict buffer LightingBuffer {
|
||||
uint lightData[];
|
||||
};
|
||||
|
||||
|
||||
@@ -14,4 +14,8 @@ uint faceHasAlphaCuttout(uint faceData) {
|
||||
|
||||
uint faceHasAlphaCuttoutOverride(uint faceData) {
|
||||
return (faceData>>23)&1;
|
||||
}
|
||||
|
||||
bool modelHasBiomeLUT(BlockModel model) {
|
||||
return ((model.flagsA)&2) != 0;
|
||||
}
|
||||
@@ -66,25 +66,25 @@ void main() {
|
||||
|
||||
vec3 offset = vec3(size, (float(face&1) + getDepthOffset(faceData, face)) * (1<<lodLevel));
|
||||
|
||||
if ((face>>1) == 0) {//Up/down
|
||||
if ((face>>1) == 0) { //Up/down
|
||||
offset = offset.xzy;
|
||||
}
|
||||
//Not needed, here for readability
|
||||
//if ((face>>1) == 1) {//north/south
|
||||
// offset = offset.xyz;
|
||||
//}
|
||||
if ((face>>1) == 2) {//west/east
|
||||
if ((face>>1) == 2) { //west/east
|
||||
offset = offset.zxy;
|
||||
}
|
||||
|
||||
gl_Position = MVP * vec4(corner + offset,1);
|
||||
gl_Position = MVP * vec4(corner + offset, 1);
|
||||
|
||||
|
||||
//Compute the uv coordinates
|
||||
vec2 modelUV = vec2(modelId&0xFF, (modelId>>8)&0xFF)*(1f/(256f));
|
||||
//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)));
|
||||
baseUV = modelUV + (vec2(face%3, face/3) * (1f/(vec2(3, 2)*256f)));
|
||||
uv = respectiveQuadSize + faceOffset;//Add in the face offset for 0,0 uv
|
||||
|
||||
discardAlpha = faceHasAlphaCuttout(faceData);
|
||||
@@ -96,7 +96,11 @@ void main() {
|
||||
colourTinting = getLighting(extractLightId(quad));
|
||||
|
||||
//Apply model colour tinting
|
||||
colourTinting *= uint2vec4RGBA(model.colourTint).yzwx;
|
||||
uint tintColour = model.colourTint;
|
||||
if (modelHasBiomeLUT(model)) {
|
||||
tintColour = colourData[tintColour + extractBiomeId(quad)];
|
||||
}
|
||||
colourTinting *= uint2vec4RGBA(tintColour).yzwx;
|
||||
|
||||
//Apply face tint
|
||||
if (face == 0) {
|
||||
|
||||
Reference in New Issue
Block a user