Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ dependencies {

// Compat fixes
modCompileOnly(fabricApi.module("fabric-renderer-indigo", fapiVersion))
modCompileOnly(fabricApi.module("fabric-rendering-fluids-v1", fapiVersion))
modCompileOnly(libs.sodium) { isTransitive = false }
modCompileOnly(libs.lithium) { isTransitive = false }
modCompileOnly(libs.iris) { isTransitive = false }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -249,17 +249,17 @@ private void keybindW(WTable table, KeybindSetting setting) {
private void blockW(WTable table, BlockSetting setting) {
WHorizontalList list = table.add(theme.horizontalList()).expandX().widget();

WItem item = list.add(theme.item(setting.get().asItem().getDefaultStack())).widget();
WBlock block = list.add(theme.block(setting.get().getDefaultState())).widget();

WButton select = list.add(theme.button("Select")).widget();
select.action = () -> {
BlockSettingScreen screen = new BlockSettingScreen(theme, setting);
screen.onClosed(() -> item.set(setting.get().asItem().getDefaultStack()));
screen.onClosed(() -> block.setState(setting.get().getDefaultState()));

mc.setScreen(screen);
};

reset(table, setting, () -> item.set(setting.get().asItem().getDefaultStack()));
reset(table, setting, () -> block.setState(setting.get().getDefaultState()));
}

private void blockPosW(WTable table, BlockPosSetting setting) {
Expand Down
11 changes: 11 additions & 0 deletions src/main/java/meteordevelopment/meteorclient/gui/GuiTheme.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import meteordevelopment.meteorclient.utils.misc.Keybind;
import meteordevelopment.meteorclient.utils.misc.Names;
import meteordevelopment.meteorclient.utils.render.color.Color;
import net.minecraft.block.BlockState;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NbtCompound;
Expand Down Expand Up @@ -176,6 +177,16 @@ public WItemWithLabel itemWithLabel(ItemStack stack) {
return itemWithLabel(stack, Names.get(stack.getItem()));
}

public WBlock block(BlockState state) {
return w(new WBlock(state));
}
public WBlockWithLabel blockWithLabel(BlockState state, String name) {
return w(new WBlockWithLabel(state, name));
}
public WBlockWithLabel blockWithLabel(BlockState state) {
return blockWithLabel(state, Names.get(state.getBlock()));
}

public WTexture texture(double width, double height, double rotation, Texture texture) {
return w(new WTexture(width, height, rotation, texture));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import net.minecraft.util.math.MathHelper;

import java.util.List;
import java.util.Optional;

import static meteordevelopment.meteorclient.MeteorClient.mc;
import static meteordevelopment.meteorclient.utils.Utils.getWindowHeight;
Expand Down Expand Up @@ -173,6 +174,10 @@ public void scissorEnd() {
scissorPool.free(scissor);
}

public Optional<Scissor> getScissor() {
return scissorStack.isEmpty() ? Optional.empty() : Optional.of(scissorStack.top());
}

public boolean renderTooltip(DrawContext drawContext, double mouseX, double mouseY, double delta) {
tooltipAnimProgress += (tooltip != null ? 1 : -1) * delta * 14;
tooltipAnimProgress = MathHelper.clamp(tooltipAnimProgress, 0, 1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ protected boolean includeValue(Block value) {

@Override
protected WWidget getValueWidget(Block block) {
return theme.itemWithLabel(block.asItem().getDefaultStack(), Names.get(block));
return theme.blockWithLabel(block.getDefaultState());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
import net.minecraft.block.Block;
import net.minecraft.block.Blocks;
import net.minecraft.registry.Registries;
import net.minecraft.util.Identifier;

import java.util.function.Predicate;

Expand All @@ -24,19 +23,15 @@ public BlockListSettingScreen(GuiTheme theme, BlockListSetting setting) {

@Override
protected boolean includeValue(Block value) {
if (Registries.BLOCK.getId(value).getPath().endsWith("_wall_banner")) {
return false;
}

Predicate<Block> filter = ((BlockListSetting) setting).filter;

if (filter == null) return value != Blocks.AIR;
return filter.test(value);
}

@Override
protected WWidget getValueWidget(Block value) {
return theme.itemWithLabel(value.asItem().getDefaultStack(), Names.get(value));
protected WWidget getValueWidget(Block block) {
return theme.blockWithLabel(block.getDefaultState());
}

@Override
Expand All @@ -46,12 +41,4 @@ protected String[] getValueNames(Block value) {
Registries.BLOCK.getId(value).toString()
};
}

@Override
protected Block getAdditionalValue(Block value) {
String path = Registries.BLOCK.getId(value).getPath();
if (!path.endsWith("_banner")) return null;

return Registries.BLOCK.get(Identifier.ofVanilla(path.substring(0, path.length() - 6) + "wall_banner"));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,11 @@

import meteordevelopment.meteorclient.gui.GuiTheme;
import meteordevelopment.meteorclient.gui.WindowScreen;
import meteordevelopment.meteorclient.gui.widgets.WItemWithLabel;
import meteordevelopment.meteorclient.gui.widgets.WBlockWithLabel;
import meteordevelopment.meteorclient.gui.widgets.containers.WTable;
import meteordevelopment.meteorclient.gui.widgets.input.WTextBox;
import meteordevelopment.meteorclient.gui.widgets.pressable.WButton;
import meteordevelopment.meteorclient.settings.BlockSetting;
import meteordevelopment.meteorclient.utils.misc.Names;
import net.minecraft.block.Block;
import net.minecraft.block.Blocks;
import net.minecraft.registry.Registries;
Expand Down Expand Up @@ -53,7 +52,7 @@ private void initTable() {
if (setting.filter != null && !setting.filter.test(block)) continue;
if (skipValue(block)) continue;

WItemWithLabel item = theme.itemWithLabel(block.asItem().getDefaultStack(), Names.get(block));
WBlockWithLabel item = theme.blockWithLabel(block.getDefaultState());
if (!filterText.isEmpty() && !Strings.CI.contains(item.getLabelText(), filterText)) continue;
table.add(item);

Expand Down
172 changes: 172 additions & 0 deletions src/main/java/meteordevelopment/meteorclient/gui/widgets/WBlock.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
/*
* This file is part of the Meteor Client distribution (https://github.com/MeteorDevelopment/meteor-client).
* Copyright (c) Meteor Development.
*/

package meteordevelopment.meteorclient.gui.widgets;

import com.mojang.blaze3d.systems.ProjectionType;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.textures.FilterMode;
import com.mojang.blaze3d.textures.TextureFormat;
import it.unimi.dsi.fastutil.objects.Reference2ObjectMap;
import it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap;
import meteordevelopment.meteorclient.gui.renderer.GuiRenderer;
import meteordevelopment.meteorclient.gui.renderer.Scissor;
import meteordevelopment.meteorclient.renderer.Texture;
import meteordevelopment.meteorclient.utils.render.SimpleBlockRenderer;
import net.minecraft.block.BlockState;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.render.ProjectionMatrix2;
import net.minecraft.client.render.VertexConsumerProvider;
import net.minecraft.client.util.BufferAllocator;
import net.minecraft.client.util.Window;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.item.ItemStack;
import net.minecraft.util.math.BlockPos;

import java.util.Optional;

public class WBlock extends WWidget {
private static final int TEXTURE_SIZE = 64;

private static VertexConsumerProvider.Immediate IMMEDIATE;
private static Texture DEPTH;
private static ProjectionMatrix2 PROJECTION_TEXTURE;
private static ProjectionMatrix2 PROJECTION_SCREEN;

private static final Reference2ObjectMap<BlockState, Texture> TEXTURES = new Reference2ObjectOpenHashMap<>();

protected BlockState state;
protected boolean initialized;
protected boolean chached;

public WBlock(BlockState state) {
this.state = state;
}

@Override
protected void onCalculateSize() {
double s = theme.scale(32);

width = s;
height = s;
}

@Override
protected void onRender(GuiRenderer renderer, double mouseX, double mouseY, double delta) {
if (state.isAir()) return;

// Render as an item model
ItemStack stack = state.getBlock().asItem().getDefaultStack();

if (!stack.isEmpty()) {
renderer.post(() -> {
double s = theme.scale(2);
renderer.item(stack, (int) x, (int) y, (float) s, true);
});

return;
}

// Render block
if (!initialized) {
chached = !SimpleBlockRenderer.hasAnimatedTextures(state);
}

if (IMMEDIATE == null) {
IMMEDIATE = VertexConsumerProvider.immediate(new BufferAllocator(1536));
DEPTH = new Texture(TEXTURE_SIZE, TEXTURE_SIZE, TextureFormat.DEPTH32, FilterMode.NEAREST, FilterMode.NEAREST);
PROJECTION_TEXTURE = new ProjectionMatrix2("Block widget texture projection", -100, 100, true);
PROJECTION_SCREEN = new ProjectionMatrix2("Block widget screen projection", -100, 100, false);
}

if (chached) {
Texture texture = TEXTURES.computeIfAbsent(state, WBlock::renderToTexture);
renderer.texture(x, y, width, height, 0, texture);
} else {
Optional<Scissor> scissorOpt = renderer.getScissor();
renderer.post(() -> renderDirectly(scissorOpt, state, (float) x, (float) y, (float) width, (float) height, (float) theme.scale(0.5d)));
}
}

private static Texture renderToTexture(BlockState state) {
Texture color = new Texture(TEXTURE_SIZE, TEXTURE_SIZE, TextureFormat.RGBA8, FilterMode.NEAREST, FilterMode.NEAREST);

var commands = RenderSystem.getDevice().createCommandEncoder();
commands.clearDepthTexture(DEPTH.getGlTexture(), 1);
commands.clearColorTexture(color.getGlTexture(), 0);

RenderSystem.outputColorTextureOverride = color.getGlTextureView();
RenderSystem.outputDepthTextureOverride = DEPTH.getGlTextureView();
RenderSystem.backupProjectionMatrix();
RenderSystem.setProjectionMatrix(PROJECTION_TEXTURE.set(TEXTURE_SIZE, TEXTURE_SIZE), ProjectionType.PERSPECTIVE);

var view = RenderSystem.getModelViewStack();
view.pushMatrix().identity();
view.scale(TEXTURE_SIZE);

view.rotateXYZ(30 * (float) (Math.PI / 180.0), 45 * (float) (Math.PI / 180.0), 0);
view.scale(0.625f, 0.625f, -0.625f);
view.translate(0.55f, 0, -0.5f);

SimpleBlockRenderer.renderFull(null, BlockPos.ORIGIN, state, null, new MatrixStack(), MinecraftClient.getInstance().getRenderTickCounter().getDynamicDeltaTicks(), IMMEDIATE);
IMMEDIATE.draw();

view.popMatrix();

RenderSystem.restoreProjectionMatrix();
RenderSystem.outputDepthTextureOverride = null;
RenderSystem.outputColorTextureOverride = null;

return color;
}

private static void renderDirectly(Optional<Scissor> scissorOpt, BlockState state, float x, float y, float width, float height, float scale) {
Window window = MinecraftClient.getInstance().getWindow();

int framebufferHeight = window.getFramebufferHeight();
float canonicalY = framebufferHeight - y - height;

if (scissorOpt.isPresent()) {
Scissor scissor = scissorOpt.get();
int canonicalScissorY = framebufferHeight - scissor.y - scissor.height;

int x1 = Math.max((int) x, scissor.x);
int y1 = Math.max((int) canonicalY, canonicalScissorY);
int x2 = Math.min((int) (x + width), scissor.x + scissor.width);
int y2 = Math.min((int) (canonicalY + height), canonicalScissorY + scissor.height);
int w = x2 - x1;
int h = y2 - y1;

RenderSystem.enableScissorForRenderTypeDraws(x1, y1, w, h);
} else {
RenderSystem.enableScissorForRenderTypeDraws((int) x, (int) (canonicalY), (int) width, (int) height);
}

RenderSystem.backupProjectionMatrix();
RenderSystem.setProjectionMatrix(PROJECTION_SCREEN.set(window.getFramebufferWidth(), window.getFramebufferHeight()), ProjectionType.PERSPECTIVE);

var view = RenderSystem.getModelViewStack();
view.pushMatrix().identity();
view.translate(x, canonicalY, 0);
view.scale(TEXTURE_SIZE * scale);

view.rotateXYZ(30 * (float) (Math.PI / 180.0), 45 * (float) (Math.PI / 180.0), 0);
view.scale(0.625f, 0.625f, -0.625f);
view.translate(0.55f, 0, -0.5f);

SimpleBlockRenderer.renderFull(null, BlockPos.ORIGIN, state, null, new MatrixStack(), MinecraftClient.getInstance().getRenderTickCounter().getDynamicDeltaTicks(), IMMEDIATE);
IMMEDIATE.draw();

view.popMatrix();

RenderSystem.restoreProjectionMatrix();
RenderSystem.disableScissorForRenderTypeDraws();
}

public void setState(BlockState state) {
this.state = state;
this.initialized = false;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* This file is part of the Meteor Client distribution (https://github.com/MeteorDevelopment/meteor-client).
* Copyright (c) Meteor Development.
*/

package meteordevelopment.meteorclient.gui.widgets;

import meteordevelopment.meteorclient.gui.widgets.containers.WHorizontalList;
import meteordevelopment.meteorclient.utils.misc.Names;
import net.minecraft.block.BlockState;

public class WBlockWithLabel extends WHorizontalList {
private BlockState state;
private String name;

private WBlock block;
private WLabel label;

public WBlockWithLabel(BlockState state, String name) {
this.state = state;
this.name = name;
}

@Override
public void init() {
block = add(theme.block(state)).widget();
label = add(theme.label(name)).widget();
}

public void set(BlockState state) {
this.state = state;
block.state = state;

name = Names.get(state.getBlock());
label.set(name);
}

public String getLabelText() {
return label == null ? name : label.get();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import net.minecraft.block.ChestBlock;
import net.minecraft.block.entity.*;
import net.minecraft.block.enums.ChestType;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;

Expand Down Expand Up @@ -341,7 +342,7 @@ private void renderBox(Render3DEvent event, BlockEntity blockEntity) {

private void renderShader(Render3DEvent event, BlockEntity blockEntity) {
vertexConsumerProvider.setColor(lineColor);
SimpleBlockRenderer.renderWithBlockEntity(blockEntity, event.tickDelta, vertexConsumerProvider);
SimpleBlockRenderer.renderFlat(mc.world, blockEntity.getPos(), blockEntity.getCachedState(), blockEntity, new MatrixStack(), event.tickDelta, vertexConsumerProvider);
}

@Override
Expand Down
Loading