Signs with custom Models

This commit is contained in:
Frank Bauer 2021-06-25 10:23:06 +02:00
parent 3143de77c3
commit a39989b331
2 changed files with 112 additions and 32 deletions

View file

@ -5,12 +5,7 @@ import java.util.Arrays;
import com.mojang.blaze3d.platform.GlStateManager;
import com.mojang.blaze3d.platform.Lighting;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.BufferBuilder;
import com.mojang.blaze3d.vertex.BufferUploader;
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.Tesselator;
import com.mojang.blaze3d.vertex.VertexConsumer;
import com.mojang.blaze3d.vertex.*;
import com.mojang.math.Matrix4f;
import net.fabricmc.api.EnvType;
@ -20,6 +15,7 @@ import net.minecraft.client.gui.GuiComponent;
import net.minecraft.client.gui.components.Button;
import net.minecraft.client.gui.font.TextFieldHelper;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.client.model.geom.PartNames;
import net.minecraft.client.multiplayer.ClientPacketListener;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.blockentity.SignRenderer.SignModel;
@ -51,7 +47,7 @@ public class BlockSignEditScreen extends Screen {
protected void init() {
minecraft.keyboardHandler.setSendRepeatsToGui(true);
this.addButton(new Button(this.width / 2 - 100, this.height / 4 + 120, 200, 20, CommonComponents.GUI_DONE,
this.addRenderableWidget(new Button(this.width / 2 - 100, this.height / 4 + 120, 200, 20, CommonComponents.GUI_DONE,
(buttonWidget) -> {
this.finishEditing();
}));
@ -80,7 +76,7 @@ public class BlockSignEditScreen extends Screen {
public void tick() {
++this.ticksSinceOpened;
if (!this.sign.getType().isValid(this.sign.getBlockState().getBlock())) {
if (!this.sign.getType().isValid(this.sign.getBlockState())) {
this.finishEditing();
}
}
@ -135,7 +131,7 @@ public class BlockSignEditScreen extends Screen {
matrices.scale(0.6666667F, -0.6666667F, -0.6666667F);
MultiBufferSource.BufferSource immediate = minecraft.renderBuffers().bufferSource();
VertexConsumer vertexConsumer = BaseSignBlockEntityRenderer.getConsumer(immediate, blockState.getBlock());
model.sign.render(matrices, vertexConsumer, 15728880, OverlayTexture.NO_OVERLAY);
model.root.getChild("sign").render(matrices, vertexConsumer, 15728880, OverlayTexture.NO_OVERLAY);
if (bl) {
model.stick.render(matrices, vertexConsumer, 15728880, OverlayTexture.NO_OVERLAY);
@ -206,7 +202,7 @@ public class BlockSignEditScreen extends Screen {
RenderSystem.disableTexture();
RenderSystem.enableColorLogicOp();
RenderSystem.logicOp(GlStateManager.LogicOp.OR_REVERSE);
bufferBuilder.begin(7, DefaultVertexFormat.POSITION_COLOR);
bufferBuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR);
float var32 = (float) x;
bufferBuilder.vertex(matrix4f, var32, (float) (l + 9), 0.0F).color(0, 0, 255, 255).endVertex();
var32 = (float) y;

View file

@ -1,68 +1,98 @@
package ru.bclib.client.render;
import java.util.HashMap;
import java.util.List;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import com.mojang.blaze3d.platform.NativeImage;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer;
import com.mojang.math.Vector3f;
import net.fabricmc.fabric.api.client.rendereregistry.v1.EntityModelLayerRegistry;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.Font;
import net.minecraft.client.model.geom.ModelLayerLocation;
import net.minecraft.client.model.geom.ModelLayers;
import net.minecraft.client.player.LocalPlayer;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.Sheets;
import net.minecraft.client.renderer.blockentity.BlockEntityRenderDispatcher;
import net.minecraft.client.renderer.blockentity.BlockEntityRenderer;
import net.minecraft.client.renderer.blockentity.SignRenderer;
import net.minecraft.client.renderer.blockentity.SignRenderer.SignModel;
import net.minecraft.client.renderer.entity.EntityRendererProvider;
import net.minecraft.client.resources.model.Material;
import net.minecraft.core.Registry;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.FormattedCharSequence;
import net.minecraft.util.Mth;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.item.DyeColor;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.SignBlock;
import net.minecraft.world.level.block.StandingSignBlock;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.properties.WoodType;
import net.minecraft.world.phys.Vec3;
import ru.bclib.blockentities.BaseSignBlockEntity;
import ru.bclib.blocks.BaseSignBlock;
import java.util.*;
public class BaseSignBlockEntityRenderer implements BlockEntityRenderer<BaseSignBlockEntity> {
private static final HashMap<Block, RenderType> LAYERS = Maps.newHashMap();
private static final Set<WoodType> TYPES = new HashSet<>();
private static final RenderType defaultLayer;
private final SignModel model = new SignRenderer.SignModel();
private final Font font;
private final Map<WoodType, SignModel> signModels;
private final SignModel defaultModel;
public BaseSignBlockEntityRenderer(BlockEntityRenderDispatcher dispatcher) {
super(dispatcher);
private static final int OUTLINE_RENDER_DISTANCE = Mth.square(16);
public BaseSignBlockEntityRenderer(EntityRendererProvider.Context ctx, ModelLayerLocation signLayerLocation) {
super();
//build a list of all new sign models.
this.signModels = (Map) TYPES.stream().collect(ImmutableMap.toImmutableMap((signType) -> {
return signType;
}, (signType) -> {
return new SignRenderer.SignModel(ctx.bakeLayer(ModelLayers.createSignModelName(signType)));
}));
//set up a default model
defaultModel = new SignRenderer.SignModel(ctx.bakeLayer(ModelLayers.createSignModelName(WoodType.OAK)));
this.font = ctx.getFont();
}
public void render(BaseSignBlockEntity signBlockEntity, float tickDelta, PoseStack matrixStack,
MultiBufferSource provider, int light, int overlay) {
BlockState state = signBlockEntity.getBlockState();
WoodType woodType = getSignType(state.getBlock());
SignRenderer.SignModel model = this.signModels.get(woodType);
matrixStack.pushPose();
matrixStack.translate(0.5D, 0.5D, 0.5D);
float angle = -((float) (state.getValue(StandingSignBlock.ROTATION) * 360) / 16.0F);
BlockState blockState = signBlockEntity.getBlockState();
if (blockState.getValue(BaseSignBlock.FLOOR)) {
matrixStack.mulPose(Vector3f.YP.rotationDegrees(angle));
this.model.stick.visible = true;
model.stick.visible = true;
} else {
matrixStack.mulPose(Vector3f.YP.rotationDegrees(angle + 180));
matrixStack.translate(0.0D, -0.3125D, -0.4375D);
this.model.stick.visible = false;
model.stick.visible = false;
}
matrixStack.pushPose();
matrixStack.scale(0.6666667F, -0.6666667F, -0.6666667F);
VertexConsumer vertexConsumer = getConsumer(provider, state.getBlock());
model.sign.render(matrixStack, vertexConsumer, light, overlay);
model.stick.render(matrixStack, vertexConsumer, light, overlay);
model.root.render(matrixStack, vertexConsumer, light, overlay);
//model.stick.render(matrixStack, vertexConsumer, light, overlay);
matrixStack.popPose();
Font textRenderer = renderer.getFont();
//Font textRenderer = renderer.getFont();
matrixStack.translate(0.0D, 0.3333333432674408D, 0.046666666865348816D);
matrixStack.scale(0.010416667F, -0.010416667F, 0.010416667F);
int m = signBlockEntity.getColor().getTextColor();
@ -71,21 +101,57 @@ public class BaseSignBlockEntityRenderer implements BlockEntityRenderer<BaseSign
int p = (int) (NativeImage.getB(m) * 0.4D);
int q = NativeImage.combine(0, p, o, n);
FormattedCharSequence[] formattedCharSequences = signBlockEntity
.getRenderMessages(Minecraft.getInstance().isTextFilteringEnabled(), (component) -> {
List<FormattedCharSequence> list = this.font.split(component, 90);
return list.isEmpty() ? FormattedCharSequence.EMPTY : (FormattedCharSequence) list.get(0);
});
int drawColor;
boolean drawOutlined;
int drawLight;
if (signBlockEntity.hasGlowingText()) {
drawColor = signBlockEntity.getColor().getTextColor();
drawOutlined = isOutlineVisible(signBlockEntity, drawColor);
drawLight = 15728880;
} else {
drawColor = m;
drawOutlined = false;
drawLight = light;
}
for (int s = 0; s < 4; ++s) {
FormattedCharSequence orderedText = signBlockEntity.getRenderMessage(s, (text) -> {
List<FormattedCharSequence> list = textRenderer.split(text, 90);
return list.isEmpty() ? FormattedCharSequence.EMPTY : list.get(0);
});
if (orderedText != null) {
float t = (float) (-textRenderer.width(orderedText) / 2);
textRenderer.drawInBatch(orderedText, t, (float) (s * 10 - 20), q, false, matrixStack.last().pose(), provider, false, 0, light);
FormattedCharSequence formattedCharSequence = formattedCharSequences[s];
float t = (float) (-this.font.width(formattedCharSequence) / 2);
if (drawOutlined) {
this.font.drawInBatch8xOutline(formattedCharSequence, t, (float) (s * 10 - 20), drawColor, m,
matrixStack.last().pose(), provider, drawLight);
} else {
this.font.drawInBatch((FormattedCharSequence) formattedCharSequence, t, (float) (s * 10 - 20), drawColor, false,
matrixStack.last().pose(), provider, false, 0, drawLight);
}
}
matrixStack.popPose();
}
public static Material getModelTexture(Block block) {
private static boolean isOutlineVisible(BaseSignBlockEntity signBlockEntity, int i) {
if (i == DyeColor.BLACK.getTextColor()) {
return true;
} else {
Minecraft minecraft = Minecraft.getInstance();
LocalPlayer localPlayer = minecraft.player;
if (localPlayer != null && minecraft.options.getCameraType().isFirstPerson() && localPlayer.isScoping()) {
return true;
} else {
Entity entity = minecraft.getCameraEntity();
return entity != null && entity.distanceToSqr(
Vec3.atCenterOf(signBlockEntity.getBlockPos())) < (double) OUTLINE_RENDER_DISTANCE;
}
}
}
public static WoodType getSignType(Block block) {
WoodType signType2;
if (block instanceof SignBlock) {
signType2 = ((SignBlock) block).type();
@ -93,13 +159,25 @@ public class BaseSignBlockEntityRenderer implements BlockEntityRenderer<BaseSign
signType2 = WoodType.OAK;
}
return Sheets.signTexture(signType2);
return signType2;
}
public static Material getModelTexture(Block block) {
return Sheets.getSignMaterial(getSignType(block));
}
public static VertexConsumer getConsumer(MultiBufferSource provider, Block block) {
return provider.getBuffer(LAYERS.getOrDefault(block, defaultLayer));
}
public static void registerCustomModel(Block block, EntityModelLayerRegistry.TexturedModelDataProvider provider) {
ResourceLocation blockId = Registry.BLOCK.getKey(block);
SignType type = new SignType(blockId.getPath());
TYPES.add(type);
EntityModelLayerRegistry.registerModelLayer(ModelLayers.createSignModelName(type), provider);
}
public static void registerRenderLayer(Block block) {
ResourceLocation blockId = Registry.BLOCK.getKey(block);
RenderType layer = RenderType.entitySolid(new ResourceLocation(blockId.getNamespace(),
@ -110,4 +188,10 @@ public class BaseSignBlockEntityRenderer implements BlockEntityRenderer<BaseSign
static {
defaultLayer = RenderType.entitySolid(new ResourceLocation("textures/entity/signs/oak.png"));
}
public static class SignType extends WoodType {
protected SignType(String string) {
super(string);
}
}
}