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.Camera;
|
||||||
import net.minecraft.client.render.Frustum;
|
import net.minecraft.client.render.Frustum;
|
||||||
import net.minecraft.client.util.math.MatrixStack;
|
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.World;
|
||||||
import net.minecraft.world.chunk.WorldChunk;
|
import net.minecraft.world.chunk.WorldChunk;
|
||||||
|
|
||||||
@@ -72,6 +75,10 @@ public class VoxelCore {
|
|||||||
////Resave the db incase it failed a recovery
|
////Resave the db incase it failed a recovery
|
||||||
//this.world.getMapper().forceResaveStates();
|
//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()) {
|
for (var state : this.world.getMapper().getStateEntries()) {
|
||||||
this.renderer.getModelManager().addEntry(state.id, state.state);
|
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.fluid.FluidState;
|
||||||
import net.minecraft.registry.Registries;
|
import net.minecraft.registry.Registries;
|
||||||
import net.minecraft.registry.RegistryKeys;
|
import net.minecraft.registry.RegistryKeys;
|
||||||
|
import net.minecraft.util.Pair;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.Direction;
|
import net.minecraft.util.math.Direction;
|
||||||
import net.minecraft.world.BlockRenderView;
|
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.glDeleteSamplers;
|
||||||
import static org.lwjgl.opengl.GL33.glGenSamplers;
|
import static org.lwjgl.opengl.GL33.glGenSamplers;
|
||||||
import static org.lwjgl.opengl.GL33C.glSamplerParameteri;
|
import static org.lwjgl.opengl.GL33C.glSamplerParameteri;
|
||||||
|
import static org.lwjgl.opengl.GL45C.glGenerateTextureMipmap;
|
||||||
import static org.lwjgl.opengl.GL45C.glTextureSubImage2D;
|
import static org.lwjgl.opengl.GL45C.glTextureSubImage2D;
|
||||||
|
|
||||||
//Manages the storage and updating of model states, textures and colours
|
//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;
|
public static final int MODEL_SIZE = 64;
|
||||||
private final ModelTextureBakery bakery;
|
private final ModelTextureBakery bakery;
|
||||||
private final GlBuffer modelBuffer;
|
private final GlBuffer modelBuffer;
|
||||||
|
private final GlBuffer modelColourBuffer;
|
||||||
private final GlTexture textures;
|
private final GlTexture textures;
|
||||||
private final int blockSampler = glGenSamplers();
|
private final int blockSampler = glGenSamplers();
|
||||||
|
|
||||||
@@ -91,12 +94,20 @@ public class ModelManager {
|
|||||||
private final int[] idMappings;
|
private final int[] idMappings;
|
||||||
private final Object2IntOpenHashMap<List<ColourDepthTextureData>> modelTexture2id = new Object2IntOpenHashMap<>();
|
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) {
|
public ModelManager(int modelTextureSize) {
|
||||||
this.modelTextureSize = modelTextureSize;
|
this.modelTextureSize = modelTextureSize;
|
||||||
this.bakery = new ModelTextureBakery(modelTextureSize, modelTextureSize);
|
this.bakery = new ModelTextureBakery(modelTextureSize, modelTextureSize);
|
||||||
this.modelBuffer = new GlBuffer(MODEL_SIZE * (1<<16));
|
this.modelBuffer = new GlBuffer(MODEL_SIZE * (1<<16));
|
||||||
|
|
||||||
|
this.modelColourBuffer = new GlBuffer(4 * (1<<16));
|
||||||
|
|
||||||
//TODO: figure out how to do mipping :blobfox_pineapple:
|
//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.metadataCache = new long[1<<16];
|
||||||
this.idMappings = new int[1<<20];//Max of 1 million blockstates mapping to 65k model states
|
this.idMappings = new int[1<<20];//Max of 1 million blockstates mapping to 65k model states
|
||||||
Arrays.fill(this.idMappings, -1);
|
Arrays.fill(this.idMappings, -1);
|
||||||
@@ -263,11 +274,18 @@ public class ModelManager {
|
|||||||
//Temporary override to always be non biome specific
|
//Temporary override to always be non biome specific
|
||||||
if (colourProvider == null) {
|
if (colourProvider == null) {
|
||||||
MemoryUtil.memPutInt(uploadPtr + 4, -1);//Set the default to nothing so that its faster on the gpu
|
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);
|
Biome defaultBiome = MinecraftClient.getInstance().world.getRegistryManager().get(RegistryKeys.BIOME).get(BiomeKeys.PLAINS);
|
||||||
MemoryUtil.memPutInt(uploadPtr + 4, captureColourConstant(colourProvider, blockState, defaultBiome)|0xFF000000);
|
MemoryUtil.memPutInt(uploadPtr + 4, captureColourConstant(colourProvider, blockState, defaultBiome)|0xFF000000);
|
||||||
} else {
|
} else if (!this.biomes.isEmpty()) {
|
||||||
//Populate the list of biomes for the model state
|
//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);
|
this.putTextures(modelId, textureData);
|
||||||
|
|
||||||
|
glGenerateTextureMipmap(this.textures.id);
|
||||||
return modelId;
|
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)
|
//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
|
// 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
|
// 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) {
|
public static boolean faceExists(long metadata, int face) {
|
||||||
return ((metadata>>(8*face))&0xFF)!=0xFF;
|
return ((metadata>>(8*face))&0xFF)!=0xFF;
|
||||||
}
|
}
|
||||||
@@ -510,9 +541,14 @@ public class ModelManager {
|
|||||||
return this.blockSampler;
|
return this.blockSampler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getColourBufferId() {
|
||||||
|
return this.modelColourBuffer.id;
|
||||||
|
}
|
||||||
|
|
||||||
public void free() {
|
public void free() {
|
||||||
this.bakery.free();
|
this.bakery.free();
|
||||||
this.modelBuffer.free();
|
this.modelBuffer.free();
|
||||||
|
this.modelColourBuffer.free();
|
||||||
this.textures.free();
|
this.textures.free();
|
||||||
glDeleteSamplers(this.blockSampler);
|
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, 4, this.geometry.metaId());
|
||||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 5, this.glVisibilityBuffer.id);
|
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 5, this.glVisibilityBuffer.id);
|
||||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 6, this.models.getBufferId());
|
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);
|
glBindVertexArray(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ public class ActiveSectionTracker {
|
|||||||
|
|
||||||
private final Long2ObjectOpenHashMap<VolatileHolder<WorldSection>>[] loadedSectionCache;
|
private final Long2ObjectOpenHashMap<VolatileHolder<WorldSection>>[] loadedSectionCache;
|
||||||
private final SectionLoader loader;
|
private final SectionLoader loader;
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
public ActiveSectionTracker(int layers, SectionLoader loader) {
|
public ActiveSectionTracker(int layers, SectionLoader loader) {
|
||||||
this.loader = loader;
|
this.loader = loader;
|
||||||
this.loadedSectionCache = new Long2ObjectOpenHashMap[layers];
|
this.loadedSectionCache = new Long2ObjectOpenHashMap[layers];
|
||||||
|
|||||||
@@ -71,7 +71,11 @@ layout(binding = 6, std430) readonly restrict buffer ModelBuffer {
|
|||||||
BlockModel modelData[];
|
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[];
|
uint lightData[];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -15,3 +15,7 @@ uint faceHasAlphaCuttout(uint faceData) {
|
|||||||
uint faceHasAlphaCuttoutOverride(uint faceData) {
|
uint faceHasAlphaCuttoutOverride(uint faceData) {
|
||||||
return (faceData>>23)&1;
|
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));
|
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;
|
offset = offset.xzy;
|
||||||
}
|
}
|
||||||
//Not needed, here for readability
|
//Not needed, here for readability
|
||||||
//if ((face>>1) == 1) {//north/south
|
//if ((face>>1) == 1) {//north/south
|
||||||
// offset = offset.xyz;
|
// offset = offset.xyz;
|
||||||
//}
|
//}
|
||||||
if ((face>>1) == 2) {//west/east
|
if ((face>>1) == 2) { //west/east
|
||||||
offset = offset.zxy;
|
offset = offset.zxy;
|
||||||
}
|
}
|
||||||
|
|
||||||
gl_Position = MVP * vec4(corner + offset,1);
|
gl_Position = MVP * vec4(corner + offset, 1);
|
||||||
|
|
||||||
|
|
||||||
//Compute the uv coordinates
|
//Compute the uv coordinates
|
||||||
vec2 modelUV = vec2(modelId&0xFF, (modelId>>8)&0xFF)*(1f/(256f));
|
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
|
//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
|
// 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
|
uv = respectiveQuadSize + faceOffset;//Add in the face offset for 0,0 uv
|
||||||
|
|
||||||
discardAlpha = faceHasAlphaCuttout(faceData);
|
discardAlpha = faceHasAlphaCuttout(faceData);
|
||||||
@@ -96,7 +96,11 @@ void main() {
|
|||||||
colourTinting = getLighting(extractLightId(quad));
|
colourTinting = getLighting(extractLightId(quad));
|
||||||
|
|
||||||
//Apply model colour tinting
|
//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
|
//Apply face tint
|
||||||
if (face == 0) {
|
if (face == 0) {
|
||||||
|
|||||||
Reference in New Issue
Block a user