Skip to content

Commit

Permalink
Optimize hatch preview rendering (#994)
Browse files Browse the repository at this point in the history
  • Loading branch information
Technici4n authored Jan 2, 2025
1 parent 7a6636d commit 959ef3f
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 37 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ private static void init(FMLConstructModEvent ignored) {
(mc, parentScreen) -> AutoConfig.getConfigScreen(MIConfig.class, parentScreen).get());

modBus.addListener(RegisterRenderBuffersEvent.class, event -> {
event.registerRenderBuffer(MIRenderTypes.solidHighlight());
event.registerRenderBuffer(MIRenderTypes.cutoutHighlight());
});

// Warn if neither JEI nor REI is present!
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,11 @@
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
import com.mojang.blaze3d.vertex.VertexFormat;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.texture.TextureAtlas;

public class MIRenderTypes {
private static RenderType MACHINE_WRENCH_OVERLAY;
private static RenderType SOLID_HIGHLIGHT; // used by hatch preview and wrong block highlight
private static RenderType CUTOUT_HIGHLIGHT; // used by hatch preview and wrong block highlight

public static RenderType machineOverlay() {
if (MACHINE_WRENCH_OVERLAY == null) {
Expand All @@ -38,11 +39,11 @@ public static RenderType machineOverlay() {
return MACHINE_WRENCH_OVERLAY;
}

public static RenderType solidHighlight() {
if (SOLID_HIGHLIGHT == null) {
SOLID_HIGHLIGHT = Factory.makeSolidHighlight();
public static RenderType cutoutHighlight() {
if (CUTOUT_HIGHLIGHT == null) {
CUTOUT_HIGHLIGHT = Factory.makeCutoutHighlight();
}
return SOLID_HIGHLIGHT;
return CUTOUT_HIGHLIGHT;
}

// This is a subclass to get access to a bunch of fields and classes.
Expand All @@ -63,14 +64,14 @@ private static RenderType makeMachineOverlay() {
.createCompositeState(false));
}

private static RenderType makeSolidHighlight() {
private static RenderType makeCutoutHighlight() {
// Use block vertex format to use the fast path in BufferBuilder, even if the shader doesn't use the extra vertex attributes.
return create("solid_highlight", DefaultVertexFormat.BLOCK, VertexFormat.Mode.QUADS, 65536, false, false,
return create("cutout_highlight", DefaultVertexFormat.BLOCK, VertexFormat.Mode.QUADS, 65536, false, false,
CompositeState.builder()
.setTransparencyState(NO_TRANSPARENCY)
.setTextureState(NO_TEXTURE)
.setLightmapState(NO_LIGHTMAP)
.setShaderState(POSITION_COLOR_SHADER)
.setTextureState(new TextureStateShard(TextureAtlas.LOCATION_BLOCKS, false, false))
.setLightmapState(LIGHTMAP)
.setShaderState(POSITION_COLOR_TEX_LIGHTMAP_SHADER)
.createCompositeState(false));
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ public void render(MultiblockMachineBlockEntity be, float tickDelta, PoseStack m
// Highlight placeable hatches in green
matrices.translate(-0.005, -0.005, -0.005);
matrices.scale(1.01f, 1.01f, 1.01f);
RenderHelper.drawOverlay(matrices, vcp, 111f / 256, 1, 111f / 256, 15728880, overlay);
RenderHelper.drawOverlay(matrices, vcp, overlay);
}
}
if (drawHighlights) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
import net.minecraft.client.renderer.BlockEntityWithoutLevelRenderer;
import net.minecraft.client.renderer.GameRenderer;
import net.minecraft.client.renderer.LevelRenderer;
import net.minecraft.client.renderer.LightTexture;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.Sheets;
import net.minecraft.client.renderer.block.model.BakedQuad;
Expand All @@ -76,40 +77,40 @@
import org.joml.Matrix4f;

public class RenderHelper {
private static final Supplier<BakedQuad[]> OVERLAY_QUADS;
private static final float W = 0.05f;
private static final ResourceLocation LOCKED_TEXTURE_LOCATION = MI.id("block/locked");
private static final ResourceLocation HATCH_PLACEMENT_OVERLAY_LOCATION = MI.id("block/hatch_placement_overlay");
@Nullable
private static OverlayQuads overlayQuads;

private record OverlayQuads(BakedQuad[] quads, TextureAtlasSprite sprite) {
}

public static void drawOverlay(PoseStack ms, MultiBufferSource vcp, float r, float g, float b, int light, int overlay) {
VertexConsumer vc = vcp.getBuffer(MIRenderTypes.solidHighlight());
for (BakedQuad overlayQuad : OVERLAY_QUADS.get()) {
vc.putBulkData(ms.last(), overlayQuad, r, g, b, 1.0f, light, overlay);
public static void drawOverlay(PoseStack ms, MultiBufferSource vcp, int overlay) {
var sprite = Minecraft.getInstance().getTextureAtlas(InventoryMenu.BLOCK_ATLAS).apply(HATCH_PLACEMENT_OVERLAY_LOCATION);
if (overlayQuads == null || overlayQuads.sprite() != sprite) {
overlayQuads = new OverlayQuads(buildOverlayQuads(sprite), sprite);
}
VertexConsumer vc = vcp.getBuffer(MIRenderTypes.cutoutHighlight());
for (BakedQuad overlayQuad : overlayQuads.quads) {
vc.putBulkData(ms.last(), overlayQuad, 1.0f, 1.0f, 1.0f, 1.0f, LightTexture.FULL_BRIGHT, /* not used by shader */ overlay);
}
}

static {
OVERLAY_QUADS = Suppliers.memoize(() -> {
var overlayQuads = new BakedQuad[24];
QuadEmitter emitter = new QuadBuffer();
for (Direction direction : Direction.values()) {
emitter.emit();
emitter.square(direction, 0, 0, 1, W, 0);
overlayQuads[direction.get3DDataValue() * 4] = emitter.toBakedQuad(null);
emitter.square(direction, 0, 1 - W, 1, 1, 0);
overlayQuads[direction.get3DDataValue() * 4 + 1] = emitter.toBakedQuad(null);
emitter.square(direction, 0, W, W, 1 - W, 0);
overlayQuads[direction.get3DDataValue() * 4 + 2] = emitter.toBakedQuad(null);
emitter.square(direction, 1 - W, W, 1, 1 - W, 0);
overlayQuads[direction.get3DDataValue() * 4 + 3] = emitter.toBakedQuad(null);
}
return overlayQuads;
});
private static BakedQuad[] buildOverlayQuads(TextureAtlasSprite sprite) {
var overlayQuads = new BakedQuad[6];
QuadEmitter emitter = new QuadBuffer();
for (Direction direction : Direction.values()) {
emitter.emit();
emitter.square(direction, 0, 0, 1, 1, 0);
emitter.spriteBake(sprite, MutableQuadView.BAKE_LOCK_UV);
overlayQuads[direction.get3DDataValue()] = emitter.toBakedQuad(sprite);
}
return overlayQuads;
}

private static final Supplier<BakedQuad[]> CUBE_QUADS;

public static void drawCube(PoseStack ms, MultiBufferSource vcp, float r, float g, float b, int light, int overlay) {
VertexConsumer vc = vcp.getBuffer(MIRenderTypes.solidHighlight());
VertexConsumer vc = vcp.getBuffer(MIRenderTypes.cutoutHighlight());
for (BakedQuad cubeQuad : CUBE_QUADS.get()) {
vc.putBulkData(ms.last(), cubeQuad, r, g, b, 1.0f, light, overlay);
}
Expand Down Expand Up @@ -226,6 +227,8 @@ public static void quadWithAlpha(VertexConsumer consumer, PoseStack.Pose matrixE
consumer.putBulkData(matrixEntry, quad, red, green, blue, alpha, light, overlay);
}

private static final ResourceLocation LOCKED_TEXTURE_LOCATION = MI.id("block/locked");

public static void drawLockedTexture(BlockEntity entity, PoseStack matrices, MultiBufferSource vertexConsumers, int colorRgb) {
VertexConsumer vc = vertexConsumers.getBuffer(Sheets.cutoutBlockSheet());
var sprite = Minecraft.getInstance().getTextureAtlas(InventoryMenu.BLOCK_ATLAS).apply(LOCKED_TEXTURE_LOCATION);
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 959ef3f

Please sign in to comment.