minecraft-src/net/minecraft/client/renderer/RenderStateShard.java
2025-07-04 03:45:38 +03:00

305 lines
12 KiB
Java

package net.minecraft.client.renderer;
import com.mojang.blaze3d.pipeline.RenderTarget;
import com.mojang.blaze3d.systems.RenderSystem;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.OptionalDouble;
import java.util.function.Supplier;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.Util;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.RenderStateShard.MultiTextureStateShard.Builder;
import net.minecraft.client.renderer.RenderStateShard.MultiTextureStateShard.Entry;
import net.minecraft.client.renderer.texture.AbstractTexture;
import net.minecraft.client.renderer.texture.TextureAtlas;
import net.minecraft.client.renderer.texture.TextureManager;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.TriState;
import org.joml.Matrix4f;
import org.joml.Matrix4fStack;
@Environment(EnvType.CLIENT)
public abstract class RenderStateShard {
public static final double MAX_ENCHANTMENT_GLINT_SPEED_MILLIS = 8.0;
protected final String name;
private final Runnable setupState;
private final Runnable clearState;
protected static final RenderStateShard.TextureStateShard BLOCK_SHEET_MIPPED = new RenderStateShard.TextureStateShard(
TextureAtlas.LOCATION_BLOCKS, TriState.FALSE, true
);
protected static final RenderStateShard.TextureStateShard BLOCK_SHEET = new RenderStateShard.TextureStateShard(
TextureAtlas.LOCATION_BLOCKS, TriState.FALSE, false
);
protected static final RenderStateShard.EmptyTextureStateShard NO_TEXTURE = new RenderStateShard.EmptyTextureStateShard();
protected static final RenderStateShard.TexturingStateShard DEFAULT_TEXTURING = new RenderStateShard.TexturingStateShard(
"default_texturing", () -> {}, () -> {}
);
protected static final RenderStateShard.TexturingStateShard GLINT_TEXTURING = new RenderStateShard.TexturingStateShard(
"glint_texturing", () -> setupGlintTexturing(8.0F), RenderSystem::resetTextureMatrix
);
protected static final RenderStateShard.TexturingStateShard ENTITY_GLINT_TEXTURING = new RenderStateShard.TexturingStateShard(
"entity_glint_texturing", () -> setupGlintTexturing(0.5F), RenderSystem::resetTextureMatrix
);
protected static final RenderStateShard.TexturingStateShard ARMOR_ENTITY_GLINT_TEXTURING = new RenderStateShard.TexturingStateShard(
"armor_entity_glint_texturing", () -> setupGlintTexturing(0.16F), RenderSystem::resetTextureMatrix
);
protected static final RenderStateShard.LightmapStateShard LIGHTMAP = new RenderStateShard.LightmapStateShard(true);
protected static final RenderStateShard.LightmapStateShard NO_LIGHTMAP = new RenderStateShard.LightmapStateShard(false);
protected static final RenderStateShard.OverlayStateShard OVERLAY = new RenderStateShard.OverlayStateShard(true);
protected static final RenderStateShard.OverlayStateShard NO_OVERLAY = new RenderStateShard.OverlayStateShard(false);
protected static final RenderStateShard.LayeringStateShard NO_LAYERING = new RenderStateShard.LayeringStateShard("no_layering", () -> {}, () -> {});
protected static final RenderStateShard.LayeringStateShard VIEW_OFFSET_Z_LAYERING = new RenderStateShard.LayeringStateShard("view_offset_z_layering", () -> {
Matrix4fStack matrix4fStack = RenderSystem.getModelViewStack();
matrix4fStack.pushMatrix();
RenderSystem.getProjectionType().applyLayeringTransform(matrix4fStack, 1.0F);
}, () -> {
Matrix4fStack matrix4fStack = RenderSystem.getModelViewStack();
matrix4fStack.popMatrix();
});
protected static final RenderStateShard.LayeringStateShard VIEW_OFFSET_Z_LAYERING_FORWARD = new RenderStateShard.LayeringStateShard(
"view_offset_z_layering_forward", () -> {
Matrix4fStack matrix4fStack = RenderSystem.getModelViewStack();
matrix4fStack.pushMatrix();
RenderSystem.getProjectionType().applyLayeringTransform(matrix4fStack, -1.0F);
}, () -> {
Matrix4fStack matrix4fStack = RenderSystem.getModelViewStack();
matrix4fStack.popMatrix();
}
);
protected static final RenderStateShard.OutputStateShard MAIN_TARGET = new RenderStateShard.OutputStateShard(
"main_target", () -> Minecraft.getInstance().getMainRenderTarget()
);
protected static final RenderStateShard.OutputStateShard OUTLINE_TARGET = new RenderStateShard.OutputStateShard("outline_target", () -> {
RenderTarget renderTarget = Minecraft.getInstance().levelRenderer.entityOutlineTarget();
return renderTarget != null ? renderTarget : Minecraft.getInstance().getMainRenderTarget();
});
protected static final RenderStateShard.OutputStateShard TRANSLUCENT_TARGET = new RenderStateShard.OutputStateShard("translucent_target", () -> {
RenderTarget renderTarget = Minecraft.getInstance().levelRenderer.getTranslucentTarget();
return renderTarget != null ? renderTarget : Minecraft.getInstance().getMainRenderTarget();
});
protected static final RenderStateShard.OutputStateShard PARTICLES_TARGET = new RenderStateShard.OutputStateShard("particles_target", () -> {
RenderTarget renderTarget = Minecraft.getInstance().levelRenderer.getParticlesTarget();
return renderTarget != null ? renderTarget : Minecraft.getInstance().getMainRenderTarget();
});
protected static final RenderStateShard.OutputStateShard WEATHER_TARGET = new RenderStateShard.OutputStateShard("weather_target", () -> {
RenderTarget renderTarget = Minecraft.getInstance().levelRenderer.getWeatherTarget();
return renderTarget != null ? renderTarget : Minecraft.getInstance().getMainRenderTarget();
});
protected static final RenderStateShard.OutputStateShard ITEM_ENTITY_TARGET = new RenderStateShard.OutputStateShard("item_entity_target", () -> {
RenderTarget renderTarget = Minecraft.getInstance().levelRenderer.getItemEntityTarget();
return renderTarget != null ? renderTarget : Minecraft.getInstance().getMainRenderTarget();
});
protected static final RenderStateShard.LineStateShard DEFAULT_LINE = new RenderStateShard.LineStateShard(OptionalDouble.of(1.0));
public RenderStateShard(String name, Runnable setupState, Runnable clearState) {
this.name = name;
this.setupState = setupState;
this.clearState = clearState;
}
public void setupRenderState() {
this.setupState.run();
}
public void clearRenderState() {
this.clearState.run();
}
public String toString() {
return this.name;
}
public String getName() {
return this.name;
}
private static void setupGlintTexturing(float scale) {
long l = (long)(Util.getMillis() * Minecraft.getInstance().options.glintSpeed().get() * 8.0);
float f = (float)(l % 110000L) / 110000.0F;
float g = (float)(l % 30000L) / 30000.0F;
Matrix4f matrix4f = new Matrix4f().translation(-f, g, 0.0F);
matrix4f.rotateZ((float) (Math.PI / 18)).scale(scale);
RenderSystem.setTextureMatrix(matrix4f);
}
@Environment(EnvType.CLIENT)
static class BooleanStateShard extends RenderStateShard {
private final boolean enabled;
public BooleanStateShard(String name, Runnable setupState, Runnable clearState, boolean enabled) {
super(name, setupState, clearState);
this.enabled = enabled;
}
@Override
public String toString() {
return this.name + "[" + this.enabled + "]";
}
}
@Environment(EnvType.CLIENT)
protected static class EmptyTextureStateShard extends RenderStateShard {
public EmptyTextureStateShard(Runnable setupState, Runnable clearState) {
super("texture", setupState, clearState);
}
EmptyTextureStateShard() {
super("texture", () -> {}, () -> {});
}
protected Optional<ResourceLocation> cutoutTexture() {
return Optional.empty();
}
}
@Environment(EnvType.CLIENT)
protected static class LayeringStateShard extends RenderStateShard {
public LayeringStateShard(String string, Runnable runnable, Runnable runnable2) {
super(string, runnable, runnable2);
}
}
@Environment(EnvType.CLIENT)
protected static class LightmapStateShard extends RenderStateShard.BooleanStateShard {
public LightmapStateShard(boolean useLightmap) {
super("lightmap", () -> {
if (useLightmap) {
Minecraft.getInstance().gameRenderer.lightTexture().turnOnLightLayer();
}
}, () -> {
if (useLightmap) {
Minecraft.getInstance().gameRenderer.lightTexture().turnOffLightLayer();
}
}, useLightmap);
}
}
@Environment(EnvType.CLIENT)
protected static class LineStateShard extends RenderStateShard {
private final OptionalDouble width;
public LineStateShard(OptionalDouble width) {
super("line_width", () -> {
if (!Objects.equals(width, OptionalDouble.of(1.0))) {
if (width.isPresent()) {
RenderSystem.lineWidth((float)width.getAsDouble());
} else {
RenderSystem.lineWidth(Math.max(2.5F, Minecraft.getInstance().getWindow().getWidth() / 1920.0F * 2.5F));
}
}
}, () -> {
if (!Objects.equals(width, OptionalDouble.of(1.0))) {
RenderSystem.lineWidth(1.0F);
}
});
this.width = width;
}
@Override
public String toString() {
return this.name + "[" + (this.width.isPresent() ? this.width.getAsDouble() : "window_scale") + "]";
}
}
@Environment(EnvType.CLIENT)
protected static class MultiTextureStateShard extends RenderStateShard.EmptyTextureStateShard {
private final Optional<ResourceLocation> cutoutTexture;
MultiTextureStateShard(List<Entry> entries) {
super(() -> {
for (int i = 0; i < entries.size(); i++) {
Entry entry = (Entry)entries.get(i);
TextureManager textureManager = Minecraft.getInstance().getTextureManager();
AbstractTexture abstractTexture = textureManager.getTexture(entry.id);
abstractTexture.setFilter(entry.blur, entry.mipmap);
RenderSystem.setShaderTexture(i, abstractTexture.getTexture());
}
}, () -> {});
this.cutoutTexture = entries.isEmpty() ? Optional.empty() : Optional.of(((Entry)entries.getFirst()).id);
}
@Override
protected Optional<ResourceLocation> cutoutTexture() {
return this.cutoutTexture;
}
public static Builder builder() {
return new Builder();
}
}
@Environment(EnvType.CLIENT)
protected static final class OffsetTexturingStateShard extends RenderStateShard.TexturingStateShard {
public OffsetTexturingStateShard(float u, float v) {
super("offset_texturing", () -> RenderSystem.setTextureMatrix(new Matrix4f().translation(u, v, 0.0F)), () -> RenderSystem.resetTextureMatrix());
}
}
@Environment(EnvType.CLIENT)
protected static class OutputStateShard extends RenderStateShard {
private final Supplier<RenderTarget> renderTargetSupplier;
public OutputStateShard(String name, Supplier<RenderTarget> renderTargetSupplier) {
super(name, () -> {}, () -> {});
this.renderTargetSupplier = renderTargetSupplier;
}
public RenderTarget getRenderTarget() {
return (RenderTarget)this.renderTargetSupplier.get();
}
}
@Environment(EnvType.CLIENT)
protected static class OverlayStateShard extends RenderStateShard.BooleanStateShard {
public OverlayStateShard(boolean useOverlay) {
super("overlay", () -> {
if (useOverlay) {
Minecraft.getInstance().gameRenderer.overlayTexture().setupOverlayColor();
}
}, () -> {
if (useOverlay) {
Minecraft.getInstance().gameRenderer.overlayTexture().teardownOverlayColor();
}
}, useOverlay);
}
}
@Environment(EnvType.CLIENT)
protected static class TextureStateShard extends RenderStateShard.EmptyTextureStateShard {
private final Optional<ResourceLocation> texture;
private final TriState blur;
private final boolean mipmap;
public TextureStateShard(ResourceLocation texture, TriState blur, boolean mipmap) {
super(() -> {
TextureManager textureManager = Minecraft.getInstance().getTextureManager();
AbstractTexture abstractTexture = textureManager.getTexture(texture);
abstractTexture.setFilter(blur, mipmap);
RenderSystem.setShaderTexture(0, abstractTexture.getTexture());
}, () -> {});
this.texture = Optional.of(texture);
this.blur = blur;
this.mipmap = mipmap;
}
@Override
public String toString() {
return this.name + "[" + this.texture + "(blur=" + this.blur + ", mipmap=" + this.mipmap + ")]";
}
@Override
protected Optional<ResourceLocation> cutoutTexture() {
return this.texture;
}
}
@Environment(EnvType.CLIENT)
protected static class TexturingStateShard extends RenderStateShard {
public TexturingStateShard(String string, Runnable runnable, Runnable runnable2) {
super(string, runnable, runnable2);
}
}
}