Skip to content

Commit

Permalink
Use custom color resolver if requested
Browse files Browse the repository at this point in the history
- Implement BlockColorRegistry for fast look up
- Refactor
  • Loading branch information
xCollateral committed Oct 21, 2024
1 parent 5c8bbfe commit b56a22d
Show file tree
Hide file tree
Showing 6 changed files with 141 additions and 47 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package net.vulkanmod.interfaces.color;

import net.minecraft.client.color.block.BlockColors;
import net.vulkanmod.render.chunk.build.color.BlockColorRegistry;

public interface BlockColorsExtended {

static BlockColorsExtended from(BlockColors blockColors) {
return (BlockColorsExtended) blockColors;
}

BlockColorRegistry getColorResolverMap();
}
29 changes: 29 additions & 0 deletions src/main/java/net/vulkanmod/mixin/render/color/BlockColorsM.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package net.vulkanmod.mixin.render.color;

import net.minecraft.client.color.block.BlockColor;
import net.minecraft.client.color.block.BlockColors;
import net.minecraft.world.level.block.Block;
import net.vulkanmod.interfaces.color.BlockColorsExtended;
import net.vulkanmod.render.chunk.build.color.BlockColorRegistry;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

@Mixin(BlockColors.class)
public class BlockColorsM implements BlockColorsExtended {

@Unique
private BlockColorRegistry colorResolvers = new BlockColorRegistry();

@Inject(method = "register", at = @At("RETURN"))
private void onRegister(BlockColor blockColor, Block[] blocks, CallbackInfo ci) {
this.colorResolvers.register(blockColor, blocks);
}

@Override
public BlockColorRegistry getColorResolverMap() {
return this.colorResolvers;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package net.vulkanmod.render.chunk.build.color;

import it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap;
import net.minecraft.client.color.block.BlockColor;
import net.minecraft.world.level.block.Block;

public class BlockColorRegistry {

private final Reference2ReferenceOpenHashMap<Block, BlockColor> map = new Reference2ReferenceOpenHashMap<>();

public void register(BlockColor blockColor, Block... blocks) {
for (Block block : blocks) {
this.map.put(block, blockColor);
}
}

public BlockColor getBlockColor(Block block) {
return this.map.get(block);
}

}
111 changes: 67 additions & 44 deletions src/main/java/net/vulkanmod/render/chunk/build/color/TintCache.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package net.vulkanmod.render.chunk.build.color;

import it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.BiomeColors;
import net.minecraft.core.BlockPos;
Expand All @@ -13,7 +14,7 @@
public class TintCache {
private static final int SECTION_WIDTH = 16;

private final Layer[] layers = new Layer[SECTION_WIDTH];
private final Reference2ReferenceOpenHashMap<ColorResolver, Layer[]> layers;

private int blendRadius, totalWidth;
private int secX, secY, secZ;
Expand All @@ -24,7 +25,12 @@ public class TintCache {
private int[] temp;

public TintCache() {
Arrays.fill(layers, new Layer());
this.layers = new Reference2ReferenceOpenHashMap<>();

// Default resolvers
this.layers.put(BiomeColors.FOLIAGE_COLOR_RESOLVER, allocateLayers());
this.layers.put(BiomeColors.GRASS_COLOR_RESOLVER, allocateLayers());
this.layers.put(BiomeColors.WATER_COLOR_RESOLVER, allocateLayers());
}

public void init(int blendRadius, int secX, int secY, int secZ) {
Expand All @@ -35,62 +41,91 @@ public void init(int blendRadius, int secX, int secY, int secZ) {
this.secY = secY;
this.secZ = secZ;

minX = (secX << 4) - blendRadius;
minZ = (secZ << 4) - blendRadius;
maxX = (secX << 4) + 16 + blendRadius;
maxZ = (secZ << 4) + 16 + blendRadius;
this.minX = (secX << 4) - blendRadius;
this.minZ = (secZ << 4) - blendRadius;
this.maxX = (secX << 4) + 16 + blendRadius;
this.maxZ = (secZ << 4) + 16 + blendRadius;

int size = totalWidth * totalWidth;

if(size != dataSize) {
if (size != this.dataSize) {
this.dataSize = size;
for (Layer layer : layers) {
layer.allocate(size);

for (Layer[] layers : layers.values()) {
for (Layer layer : layers) {
layer.allocate(size);
}
}
temp = new int[size];
} else {
for (Layer layer : layers) {
layer.invalidate();

this.temp = new int[size];
}
else {
for (Layer[] layers : layers.values()) {
for (Layer layer : layers) {
layer.invalidate();
}
}
}
}

public int getColor(BlockPos blockPos, ColorResolver colorResolver) {
int relY = blockPos.getY() & 15;
Layer layer = layers[relY];
if(layer.invalidated)
calculateLayer(relY);

int[] values = layer.getValues(colorResolver);
if (!this.layers.containsKey(colorResolver)) {
addResolver(colorResolver);
}

Layer layer = this.layers.get(colorResolver)[relY];

if (layer.invalidated) {
calculateLayer(layer, colorResolver, relY);
}

int[] values = layer.getValues();

int relX = blockPos.getX() & 15;
int relZ = blockPos.getZ() & 15;
int idx = totalWidth * (relZ + blendRadius) + (relX + blendRadius);
int idx = this.totalWidth * (relZ + this.blendRadius) + (relX + this.blendRadius);
return values[idx];
}

public void calculateLayer(int y) {
private void addResolver(ColorResolver colorResolver) {
Layer[] layers1 = allocateLayers();

for (Layer layer : layers1) {
layer.allocate(this.dataSize);
}

this.layers.put(colorResolver, layers1);
}

private Layer[] allocateLayers() {
Layer[] layers = new Layer[SECTION_WIDTH];

Arrays.fill(layers, new Layer());
return layers;
}

private void calculateLayer(Layer layer, ColorResolver colorResolver, int y) {
Level level = WorldRenderer.getLevel();
Layer layer = layers[y];

BlockPos.MutableBlockPos blockPos = new BlockPos.MutableBlockPos();
int absY = (secY << 4) + y;

for (int absZ = minZ; absZ < maxZ ; absZ++) {
for (int absX = minX; absX < maxX ; absX++) {
int[] values = layer.values;

for (int absZ = minZ; absZ < maxZ; absZ++) {
for (int absX = minX; absX < maxX; absX++) {
blockPos.set(absX, absY, absZ);
Biome biome = level.getBiome(blockPos).value();

final int idx = (absX - minX) + (absZ - minZ) * totalWidth;
layer.grass[idx] = biome.getGrassColor(absX, absZ);
layer.foliage[idx] = biome.getFoliageColor();
layer.water[idx] = biome.getWaterColor();
values[idx] = colorResolver.getColor(biome, absX, absZ);
}
}

if (blendRadius > 0) {
this.applyBlur(layer.grass);
this.applyBlur(layer.foliage);
this.applyBlur(layer.water);
this.applyBlur(values);
}

layer.invalidated = false;
Expand All @@ -112,31 +147,19 @@ private void applyBlur(int[] buffer) {

static class Layer {
private boolean invalidated = true;

private int[] grass;
private int[] foliage;
private int[] water;
private int[] values;

void allocate(int size) {
grass = new int[size];
foliage = new int[size];
water = new int[size];
this.values = new int[size];
invalidate();
}

void invalidate() {
this.invalidated = true;
}

public int[] getValues(ColorResolver colorResolver) {
if (colorResolver == BiomeColors.GRASS_COLOR_RESOLVER)
return grass;
else if (colorResolver == BiomeColors.FOLIAGE_COLOR_RESOLVER)
return foliage;
else if (colorResolver == BiomeColors.WATER_COLOR_RESOLVER)
return water;

throw new IllegalArgumentException("Unexpected resolver: " + colorResolver.toString());
public int[] getValues() {
return this.values;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import net.fabricmc.fabric.api.renderer.v1.model.ModelHelper;
import net.fabricmc.fabric.api.renderer.v1.render.RenderContext;
import net.minecraft.client.Minecraft;
import net.minecraft.client.color.block.BlockColor;
import net.minecraft.client.color.block.BlockColors;
import net.minecraft.client.renderer.block.model.BakedQuad;
import net.minecraft.util.RandomSource;
Expand All @@ -15,6 +16,8 @@
import net.minecraft.world.phys.shapes.BooleanOp;
import net.minecraft.world.phys.shapes.Shapes;
import net.minecraft.world.phys.shapes.VoxelShape;
import net.vulkanmod.interfaces.color.BlockColorsExtended;
import net.vulkanmod.render.chunk.build.color.BlockColorRegistry;
import net.vulkanmod.render.chunk.build.light.LightPipeline;
import net.vulkanmod.render.chunk.build.light.data.QuadLightData;
import org.jetbrains.annotations.Nullable;
Expand All @@ -40,7 +43,7 @@ public abstract class AbstractBlockRenderContext extends AbstractRenderContext {
protected static final RenderMaterial STANDARD_MATERIAL = RENDERER.materialFinder().shadeMode(ShadeMode.VANILLA).find();
protected static final RenderMaterial NO_AO_MATERIAL = RENDERER.materialFinder().shadeMode(ShadeMode.VANILLA).ambientOcclusion(TriState.FALSE).find();

protected final BlockColors blockColors;
protected final BlockColorRegistry blockColorRegistry;

private final MutableQuadViewImpl editorQuad = new MutableQuadViewImpl() {
{
Expand Down Expand Up @@ -88,7 +91,8 @@ protected void rehash(int i) {
protected AbstractBlockRenderContext() {
this.occlusionCache.defaultReturnValue((byte) 127);

this.blockColors = Minecraft.getInstance().getBlockColors();
BlockColors blockColors = Minecraft.getInstance().getBlockColors();
this.blockColorRegistry = BlockColorsExtended.from(blockColors).getColorResolverMap();
}

protected void setupLightPipelines(LightPipeline flatLightPipeline, LightPipeline smoothLightPipeline) {
Expand Down Expand Up @@ -226,7 +230,10 @@ protected void colorizeQuad(MutableQuadViewImpl quad, int colorIndex) {
}

private int getBlockColor(BlockAndTintGetter region, int colorIndex) {
return 0xFF000000 | blockColors.getColor(blockState, region, blockPos, colorIndex);
BlockColor blockColor = this.blockColorRegistry.getBlockColor(this.blockState.getBlock());

int color = blockColor != null ? blockColor.getColor(blockState, region, blockPos, colorIndex) : -1;
return 0xFF000000 | color;
}

protected void shadeQuad(MutableQuadViewImpl quad, LightPipeline lightPipeline, boolean emissive, boolean vanillaShade) {
Expand Down
1 change: 1 addition & 0 deletions src/main/resources/vulkanmod.mixins.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
"render.ShaderInstanceM",
"render.block.BakedQuadM",
"render.clouds.LevelRendererM",
"render.color.BlockColorsM",
"render.entity.EntityRendererM",
"render.entity.LevelRendererM",
"render.entity.model.ModelPartCubeM",
Expand Down

0 comments on commit b56a22d

Please sign in to comment.