Fixed rendering of barrel fluid in transparent barrels

This commit is contained in:
thedarkcolour 2024-02-19 14:21:19 -08:00
parent 0f9c9ecd22
commit 6139163f36
5 changed files with 90 additions and 5 deletions

View File

@ -59,6 +59,7 @@ import org.jetbrains.annotations.NotNull;
import thedarkcolour.exdeorum.block.BarrelBlock;
import thedarkcolour.exdeorum.client.CompostColors;
import thedarkcolour.exdeorum.config.EConfig;
import thedarkcolour.exdeorum.material.BarrelMaterial;
import thedarkcolour.exdeorum.recipe.RecipeUtil;
import thedarkcolour.exdeorum.recipe.barrel.BarrelFluidMixingRecipe;
import thedarkcolour.exdeorum.registry.EBlockEntities;
@ -75,14 +76,17 @@ public class BarrelBlockEntity extends EBlockEntity {
public short r, g, b;
// Used to avoid triggering obsidian dupes in onContentsChanged, because Forge's FluidUtil actually modifies the tank for some reason
private boolean isBeingFilledByPlayer;
public BarrelBlockEntity(BlockPos pos, BlockState state) {
super(EBlockEntities.BARREL.get(), pos, state);
}
public final boolean transparent;
private final LazyOptional<IItemHandler> itemHandler = LazyOptional.of(() -> this.item);
private final LazyOptional<IFluidHandler> fluidHandler = LazyOptional.of(() -> this.tank);
public BarrelBlockEntity(BlockPos pos, BlockState state) {
super(EBlockEntities.BARREL.get(), pos, state);
this.transparent = BarrelMaterial.TRANSPARENT_BARRELS.contains(state.getBlock());
}
@Override
public <T> LazyOptional<T> getCapability(Capability<T> cap, Direction side) {
if (cap == ForgeCapabilities.FLUID_HANDLER) {

View File

@ -49,6 +49,7 @@ import net.minecraftforge.client.extensions.common.IClientFluidTypeExtensions;
import net.minecraftforge.client.model.CompositeModel;
import net.minecraftforge.client.model.data.ModelData;
import net.minecraftforge.registries.ForgeRegistries;
import org.joml.Matrix4f;
import org.joml.Vector3f;
import thedarkcolour.exdeorum.ExDeorum;
import thedarkcolour.exdeorum.client.ter.SieveRenderer;
@ -171,6 +172,70 @@ public class RenderUtil {
RenderUtil.renderFlatSprite(builder, stack, y, r, g, b, RenderUtil.blockAtlas.getSprite(extensions.getStillTexture(state, level, pos)), light, edge);
}
@SuppressWarnings("DuplicatedCode")
public static void renderFluidCube(MultiBufferSource buffers, PoseStack stack, Level level, BlockPos pos, float minY, float maxY, float edge, int light, int r, int g, int b, Fluid fluid) {
var extensions = IClientFluidTypeExtensions.of(fluid);
var state = fluid.defaultFluidState();
var builder = buffers.getBuffer(Sheets.translucentCullBlockSheet());
var pose = stack.last().pose();
var poseNormal = stack.last().normal();
Vector3f normal;
TextureAtlasSprite sprite = RenderUtil.blockAtlas.getSprite(extensions.getStillTexture(state, level, pos));
float uMin = sprite.getU0();
float uMax = sprite.getU1();
float vMin = sprite.getV0();
float vMax = sprite.getV1();
float edgeMin = edge / 16f;
float edgeMax = 1f - edge / 16f;
// Top face
normal = poseNormal.transform(new Vector3f(0, 1, 0));
builder.vertex(pose, edgeMin, maxY, edgeMin).color(r, g, b, 255).uv(uMin, vMin).overlayCoords(0, 10).uv2(light).normal(normal.x, normal.y, normal.z).endVertex();
builder.vertex(pose, edgeMin, maxY, edgeMax).color(r, g, b, 255).uv(uMin, vMax).overlayCoords(0, 10).uv2(light).normal(normal.x, normal.y, normal.z).endVertex();
builder.vertex(pose, edgeMax, maxY, edgeMax).color(r, g, b, 255).uv(uMax, vMax).overlayCoords(0, 10).uv2(light).normal(normal.x, normal.y, normal.z).endVertex();
builder.vertex(pose, edgeMax, maxY, edgeMin).color(r, g, b, 255).uv(uMax, vMin).overlayCoords(0, 10).uv2(light).normal(normal.x, normal.y, normal.z).endVertex();
// Bottom face
normal = poseNormal.transform(new Vector3f(0, -1, 0));
builder.vertex(pose, edgeMin, minY, edgeMin).color(r, g, b, 255).uv(uMin, vMin).overlayCoords(0, 10).uv2(light).normal(normal.x, normal.y, normal.z).endVertex();
builder.vertex(pose, edgeMax, minY, edgeMin).color(r, g, b, 255).uv(uMax, vMin).overlayCoords(0, 10).uv2(light).normal(normal.x, normal.y, normal.z).endVertex();
builder.vertex(pose, edgeMax, minY, edgeMax).color(r, g, b, 255).uv(uMax, vMax).overlayCoords(0, 10).uv2(light).normal(normal.x, normal.y, normal.z).endVertex();
builder.vertex(pose, edgeMin, minY, edgeMax).color(r, g, b, 255).uv(uMin, vMax).overlayCoords(0, 10).uv2(light).normal(normal.x, normal.y, normal.z).endVertex();
// Flowing texture coordinates
//sprite = RenderUtil.blockAtlas.getSprite(extensions.getFlowingTexture(state, level, pos));
//uMin = sprite.getU0();
//uMax = sprite.getU(8);
//vMin = sprite.getV0();
//vMax = sprite.getV(8);
// South face
normal = poseNormal.transform(new Vector3f(0, 0, 1));
builder.vertex(pose, edgeMax, maxY, edgeMax).color(r, g, b, 255).uv(uMax, vMin).overlayCoords(0, 10).uv2(light).normal(normal.x, normal.y, normal.z).endVertex();
builder.vertex(pose, edgeMin, maxY, edgeMax).color(r, g, b, 255).uv(uMin, vMin).overlayCoords(0, 10).uv2(light).normal(normal.x, normal.y, normal.z).endVertex();
builder.vertex(pose, edgeMin, minY, edgeMax).color(r, g, b, 255).uv(uMin, vMax).overlayCoords(0, 10).uv2(light).normal(normal.x, normal.y, normal.z).endVertex();
builder.vertex(pose, edgeMax, minY, edgeMax).color(r, g, b, 255).uv(uMax, vMax).overlayCoords(0, 10).uv2(light).normal(normal.x, normal.y, normal.z).endVertex();
// North face
normal = poseNormal.transform(new Vector3f(0, 0, -1));
builder.vertex(pose, edgeMin, maxY, edgeMin).color(r, g, b, 255).uv(uMin, vMin).overlayCoords(0, 10).uv2(light).normal(normal.x, normal.y, normal.z).endVertex();
builder.vertex(pose, edgeMax, maxY, edgeMin).color(r, g, b, 255).uv(uMax, vMin).overlayCoords(0, 10).uv2(light).normal(normal.x, normal.y, normal.z).endVertex();
builder.vertex(pose, edgeMax, minY, edgeMin).color(r, g, b, 255).uv(uMax, vMax).overlayCoords(0, 10).uv2(light).normal(normal.x, normal.y, normal.z).endVertex();
builder.vertex(pose, edgeMin, minY, edgeMin).color(r, g, b, 255).uv(uMin, vMax).overlayCoords(0, 10).uv2(light).normal(normal.x, normal.y, normal.z).endVertex();
// East face
normal = poseNormal.transform(new Vector3f(1, 0, 0));
builder.vertex(pose, edgeMax, maxY, edgeMin).color(r, g, b, 255).uv(uMin, vMin).overlayCoords(0, 10).uv2(light).normal(normal.x, normal.y, normal.z).endVertex();
builder.vertex(pose, edgeMax, maxY, edgeMax).color(r, g, b, 255).uv(uMax, vMin).overlayCoords(0, 10).uv2(light).normal(normal.x, normal.y, normal.z).endVertex();
builder.vertex(pose, edgeMax, minY, edgeMax).color(r, g, b, 255).uv(uMax, vMax).overlayCoords(0, 10).uv2(light).normal(normal.x, normal.y, normal.z).endVertex();
builder.vertex(pose, edgeMax, minY, edgeMin).color(r, g, b, 255).uv(uMin, vMax).overlayCoords(0, 10).uv2(light).normal(normal.x, normal.y, normal.z).endVertex();
// West face
normal = poseNormal.transform(new Vector3f(-1, 0, 0));
builder.vertex(pose, edgeMin, maxY, edgeMax).color(r, g, b, 255).uv(uMax, vMin).overlayCoords(0, 10).uv2(light).normal(normal.x, normal.y, normal.z).endVertex();
builder.vertex(pose, edgeMin, maxY, edgeMin).color(r, g, b, 255).uv(uMin, vMin).overlayCoords(0, 10).uv2(light).normal(normal.x, normal.y, normal.z).endVertex();
builder.vertex(pose, edgeMin, minY, edgeMin).color(r, g, b, 255).uv(uMin, vMax).overlayCoords(0, 10).uv2(light).normal(normal.x, normal.y, normal.z).endVertex();
builder.vertex(pose, edgeMin, minY, edgeMax).color(r, g, b, 255).uv(uMax, vMax).overlayCoords(0, 10).uv2(light).normal(normal.x, normal.y, normal.z).endVertex();
}
// Renders a sprite inside the barrel with the height determined by how full the barrel is.
public static void renderFlatSpriteLerp(VertexConsumer builder, PoseStack stack, float percentage, int r, int g, int b, TextureAtlasSprite sprite, int light, float edge, float yMin, float yMax) {
float y = Mth.lerp(percentage, yMin, yMax) / 16f;

View File

@ -97,7 +97,11 @@ public class BarrelRenderer implements BlockEntityRenderer<BarrelBlockEntity> {
b = (int) Mth.lerp(progress, b, 65);
}
RenderUtil.renderFlatFluidSprite(buffers, stack, level, pos, y, 2.0f, light, r, g, b, fluid);
if (barrel.transparent) {
RenderUtil.renderFluidCube(buffers, stack, level, pos, 1 / 16f, y, 2.0f, light, r, g, b, fluid);
} else {
RenderUtil.renderFlatFluidSprite(buffers, stack, level, pos, y, 2.0f, light, r, g, b, fluid);
}
}
});

View File

@ -62,6 +62,7 @@ import thedarkcolour.exdeorum.compat.ModIds;
import thedarkcolour.exdeorum.compat.top.ExDeorumTopCompat;
import thedarkcolour.exdeorum.config.EConfig;
import thedarkcolour.exdeorum.item.WateringCanItem;
import thedarkcolour.exdeorum.material.BarrelMaterial;
import thedarkcolour.exdeorum.network.NetworkHandler;
import thedarkcolour.exdeorum.network.VisualUpdateTracker;
import thedarkcolour.exdeorum.recipe.RecipeUtil;
@ -170,6 +171,7 @@ public final class EventHandler {
EFluids.WITCH_WATER_TYPE.get(),
fluidState -> fluidState.isSource() ? Blocks.OBSIDIAN.defaultBlockState() : (EConfig.SERVER.witchWaterNetherrackGenerator.get() ? Blocks.NETHERRACK.defaultBlockState() : Blocks.COBBLESTONE.defaultBlockState())
));
BarrelMaterial.loadTransparentBlocks();
});
}

View File

@ -44,10 +44,12 @@ import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public final class BarrelMaterial {
// Use a linked hash map to maintain insertion order
public static final List<BarrelMaterial> REGISTERED_MATERIALS = new ArrayList<>();
public static final Set<Block> TRANSPARENT_BARRELS = new HashSet<>();
private static final Path CUSTOM_BARREL_MATERIAL_CONFIGS = Paths.get("config/exdeorum/barrel_materials");
@ -226,6 +228,14 @@ public final class BarrelMaterial {
return new BlockEntityType<>(BarrelBlockEntity::new, validBlocks, null);
}
public static void loadTransparentBlocks() {
for (var material : REGISTERED_MATERIALS) {
if (material.transparent) {
TRANSPARENT_BARRELS.add(material.getBlock());
}
}
}
// Does not check if the mod is registered
public Item getItem() {
return this.item.get();