From 70b04c19b5c6da9d63a095fb7a2e17fd722c9cb1 Mon Sep 17 00:00:00 2001 From: SHsuperCM Date: Wed, 23 Feb 2022 11:13:12 +0200 Subject: Ported more of the enchantment type --- .../defaults/cit/types/TypeEnchantment.java | 244 ++++++++++++++++++--- .../defaults/config/CITResewnDefaultsConfig.java | 2 +- .../enchantment/BufferBuilderStorageAccessor.java | 15 ++ .../types/enchantment/RenderPhaseAccessor.java | 21 ++ 4 files changed, 245 insertions(+), 37 deletions(-) create mode 100644 defaults/src/main/java/shcm/shsupercm/fabric/citresewn/defaults/mixin/types/enchantment/BufferBuilderStorageAccessor.java create mode 100644 defaults/src/main/java/shcm/shsupercm/fabric/citresewn/defaults/mixin/types/enchantment/RenderPhaseAccessor.java (limited to 'defaults/src') diff --git a/defaults/src/main/java/shcm/shsupercm/fabric/citresewn/defaults/cit/types/TypeEnchantment.java b/defaults/src/main/java/shcm/shsupercm/fabric/citresewn/defaults/cit/types/TypeEnchantment.java index 760cc83..5fd6e3c 100644 --- a/defaults/src/main/java/shcm/shsupercm/fabric/citresewn/defaults/cit/types/TypeEnchantment.java +++ b/defaults/src/main/java/shcm/shsupercm/fabric/citresewn/defaults/cit/types/TypeEnchantment.java @@ -1,18 +1,28 @@ package shcm.shsupercm.fabric.citresewn.defaults.cit.types; +import com.mojang.blaze3d.systems.RenderSystem; import io.shcm.shsupercm.fabric.fletchingtable.api.Entrypoint; -import net.minecraft.client.render.RenderPhase; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.render.*; import net.minecraft.resource.ResourceManager; import net.minecraft.util.Identifier; +import net.minecraft.util.Util; +import net.minecraft.util.math.Matrix4f; +import net.minecraft.util.math.Vec3f; import org.lwjgl.opengl.GL11; import shcm.shsupercm.fabric.citresewn.api.CITTypeContainer; import shcm.shsupercm.fabric.citresewn.cit.*; +import shcm.shsupercm.fabric.citresewn.defaults.config.CITResewnDefaultsConfig; +import shcm.shsupercm.fabric.citresewn.defaults.mixin.types.enchantment.BufferBuilderStorageAccessor; +import shcm.shsupercm.fabric.citresewn.defaults.mixin.types.enchantment.RenderPhaseAccessor; import shcm.shsupercm.fabric.citresewn.ex.CITParsingException; import shcm.shsupercm.fabric.citresewn.pack.format.PropertyGroup; import shcm.shsupercm.fabric.citresewn.pack.format.PropertyKey; +import shcm.shsupercm.fabric.citresewn.pack.format.PropertyValue; import java.lang.ref.WeakReference; import java.util.*; +import java.util.function.Consumer; import static com.mojang.blaze3d.systems.RenderSystem.*; import static org.lwjgl.opengl.GL11.*; @@ -29,24 +39,68 @@ public class TypeEnchantment extends CITType { PropertyKey.of("speed"), PropertyKey.of("rotation"), PropertyKey.of("duration"), - PropertyKey.of("blend"), - PropertyKey.of("useGlint"), - PropertyKey.of("blur"), PropertyKey.of("r"), PropertyKey.of("g"), PropertyKey.of("b"), - PropertyKey.of("a")); + PropertyKey.of("a"), + PropertyKey.of("useGlint"), + PropertyKey.of("blur"), + PropertyKey.of("blend")); } public Identifier texture; - public float speed, rotation, duration, r, g, b, a; public int layer; + public float speed, rotation, duration, r, g, b, a; public boolean useGlint, blur; public Blend blend; + public final Map renderLayers = new EnumMap<>(GlintRenderLayer.class); + private final WrappedMethodIntensity methodIntensity = new WrappedMethodIntensity(); + @Override public void load(List conditions, PropertyGroup properties, ResourceManager resourceManager) throws CITParsingException { + PropertyValue textureProp = properties.getLastWithoutMetadata("citresewn", "texture"); + if (textureProp == null) + throw new CITParsingException("No texture specified", properties, -1); + this.texture = resolveAsset(properties.identifier, textureProp, "textures", ".png", resourceManager); + if (this.texture == null) + throw new CITParsingException("Could not resolve texture", properties, textureProp.position()); + + PropertyValue layerProp = properties.getLastWithoutMetadataOrDefault("0", "citresewn", "layer"); + try { + this.layer = Integer.parseInt(layerProp.value()); + } catch (Exception e) { + throw new CITParsingException("Could not parse integer", properties, layerProp.position(), e); + } + this.speed = parseFloatOrZero("speed", properties); + this.rotation = parseFloatOrZero("rotation", properties); + this.duration = parseFloatOrZero("duration", properties); + this.r = parseFloatOrZero("r", properties); + this.g = parseFloatOrZero("g", properties); + this.b = parseFloatOrZero("b", properties); + this.a = parseFloatOrZero("a", properties); + + this.useGlint = Boolean.parseBoolean(properties.getLastWithoutMetadataOrDefault("false", "citresewn", "useGlint").value()); + this.blur = Boolean.parseBoolean(properties.getLastWithoutMetadataOrDefault("true", "citresewn", "blur").value()); + + PropertyValue blendProp = properties.getLastWithoutMetadataOrDefault("add", "citresewn", "blend"); + try { + this.blend = Blend.getBlend(blendProp.value()); + } catch (Exception e) { + throw new CITParsingException("Could not parse blending method", properties, blendProp.position(), e); + } + } + + private float parseFloatOrZero(String propertyName, PropertyGroup properties) throws CITParsingException { + PropertyValue property = properties.getLastWithoutMetadata("citresewn", propertyName); + if (property == null) + return 0f; + try { + return Float.parseFloat(property.value()); + } catch (Exception e) { + throw new CITParsingException("Could not parse float", properties, property.position(), e); + } } public static class Container extends CITTypeContainer { @@ -57,6 +111,9 @@ public class TypeEnchantment extends CITType { public List> loaded = new ArrayList<>(); public List>> loadedLayered = new ArrayList<>(); + private List> appliedContext = null; + public boolean shouldApply = false; + @Override public void load(List> parsedCITs) { loaded.addAll(parsedCITs); @@ -68,23 +125,47 @@ public class TypeEnchantment extends CITType { layers.entrySet().stream() .sorted(Map.Entry.comparingByKey()) .forEachOrdered(layer -> loadedLayered.add(layer.getValue())); + + for (CIT cit : loaded) + for (GlintRenderLayer glintLayer : GlintRenderLayer.values()) { + RenderLayer renderLayer = glintLayer.build(cit.type, cit.propertiesIdentifier); + + cit.type.renderLayers.put(glintLayer, renderLayer); + ((BufferBuilderStorageAccessor) MinecraftClient.getInstance().getBufferBuilders()).getEntityBuilders().put(renderLayer, new BufferBuilder(renderLayer.getExpectedBufferSize())); + } } @Override public void dispose() { + appliedContext = null; + + for (CIT cit : loaded) + for (RenderLayer renderLayer : cit.type.renderLayers.values()) + ((BufferBuilderStorageAccessor) MinecraftClient.getInstance().getBufferBuilders()).getEntityBuilders().remove(renderLayer); + loaded.clear(); loadedLayered.clear(); } - public void apply(CITContext context) { + public void setContext(CITContext context) { if (context == null) { - //todo clear + appliedContext = null; return; } List>> cits = ((CITCacheEnchantment) (Object) context.stack).citresewn$getCacheTypeEnchantment().get(context); - //todo apply + appliedContext = new ArrayList<>(); + if (cits != null) + for (WeakReference> citRef : cits) + if (citRef != null) { + CIT cit = citRef.get(); + if (cit != null) + appliedContext.add(cit); + } + + if (appliedContext.isEmpty()) + appliedContext = null; } public List> getRealTimeCIT(CITContext context) { @@ -99,6 +180,107 @@ public class TypeEnchantment extends CITType { return cits; } } + + public enum GlintRenderLayer { + ARMOR_GLINT("armor_glint", 8f, layer -> layer + .shader(RenderPhaseAccessor.ARMOR_GLINT_SHADER()) + .writeMaskState(RenderPhaseAccessor.COLOR_MASK()) + .cull(RenderPhaseAccessor.DISABLE_CULLING()) + .depthTest(RenderPhaseAccessor.EQUAL_DEPTH_TEST()) + .layering(RenderPhaseAccessor.VIEW_OFFSET_Z_LAYERING())), + ARMOR_ENTITY_GLINT("armor_entity_glint", 0.16f, layer -> layer + .shader(RenderPhaseAccessor.ARMOR_ENTITY_GLINT_SHADER()) + .writeMaskState(RenderPhaseAccessor.COLOR_MASK()) + .cull(RenderPhaseAccessor.DISABLE_CULLING()) + .depthTest(RenderPhaseAccessor.EQUAL_DEPTH_TEST()) + .layering(RenderPhaseAccessor.VIEW_OFFSET_Z_LAYERING())), + GLINT_TRANSLUCENT("glint_translucent", 8f, layer -> layer + .shader(RenderPhaseAccessor.TRANSLUCENT_GLINT_SHADER()) + .writeMaskState(RenderPhaseAccessor.COLOR_MASK()) + .cull(RenderPhaseAccessor.DISABLE_CULLING()) + .depthTest(RenderPhaseAccessor.EQUAL_DEPTH_TEST()) + .target(RenderPhaseAccessor.ITEM_TARGET())), + GLINT("glint", 8f, layer -> layer + .shader(RenderPhaseAccessor.GLINT_SHADER()) + .writeMaskState(RenderPhaseAccessor.COLOR_MASK()) + .cull(RenderPhaseAccessor.DISABLE_CULLING()) + .depthTest(RenderPhaseAccessor.EQUAL_DEPTH_TEST())), + DIRECT_GLINT("glint_direct", 8f, layer -> layer + .shader(RenderPhaseAccessor.DIRECT_GLINT_SHADER()) + .writeMaskState(RenderPhaseAccessor.COLOR_MASK()) + .cull(RenderPhaseAccessor.DISABLE_CULLING()) + .depthTest(RenderPhaseAccessor.EQUAL_DEPTH_TEST())), + ENTITY_GLINT("entity_glint", 0.16f, layer -> layer + .shader(RenderPhaseAccessor.ENTITY_GLINT_SHADER()) + .writeMaskState(RenderPhaseAccessor.COLOR_MASK()) + .cull(RenderPhaseAccessor.DISABLE_CULLING()) + .depthTest(RenderPhaseAccessor.EQUAL_DEPTH_TEST()) + .target(RenderPhaseAccessor.ITEM_TARGET())), + DIRECT_ENTITY_GLINT("entity_glint_direct", 0.16f, layer -> layer + .shader(RenderPhaseAccessor.DIRECT_ENTITY_GLINT_SHADER()) + .writeMaskState(RenderPhaseAccessor.COLOR_MASK()) + .cull(RenderPhaseAccessor.DISABLE_CULLING()) + .depthTest(RenderPhaseAccessor.EQUAL_DEPTH_TEST())); + + public final String name; + private final Consumer setup; + private final float scale; + + GlintRenderLayer(String name, float scale, Consumer setup) { + this.name = name; + this.scale = scale; + this.setup = setup; + } + + public RenderLayer build(TypeEnchantment enchantment, Identifier propertiesIdentifier) { + final float speed = enchantment.speed, rotation = enchantment.rotation, r = enchantment.r, g = enchantment.g, b = enchantment.b, a = enchantment.a; + final WrappedMethodIntensity methodIntensity = enchantment.methodIntensity; + RenderLayer.MultiPhaseParameters.Builder layer = RenderLayer.MultiPhaseParameters.builder() + .texture(new RenderPhase.Texture(enchantment.texture, enchantment.blur, false)) + .texturing(new RenderPhase.Texturing("citresewn_glint_texturing", () -> { + float l = Util.getMeasuringTimeMs() * CITResewnDefaultsConfig.INSTANCE.type_enchantment_scroll_multiplier * speed; + float x = (l % 110000f) / 110000f; + float y = (l % 30000f) / 30000f; + Matrix4f matrix4f = Matrix4f.translate(-x, y, 0.0f); + matrix4f.multiply(Vec3f.POSITIVE_Z.getDegreesQuaternion(rotation + 10f)); + matrix4f.multiply(Matrix4f.scale(scale, scale, scale)); + setTextureMatrix(matrix4f); + + setShaderColor(r, g, b, a * methodIntensity.intensity); + }, () -> { + RenderSystem.resetTextureMatrix(); + + setShaderColor(1f, 1f, 1f, 1f); + })) + .transparency(enchantment.blend); + + this.setup.accept(layer); + + return RenderLayer.of("citresewn:enchantment_" + this.name + ":" + propertiesIdentifier.toString(), + VertexFormats.POSITION_TEXTURE, + VertexFormat.DrawMode.QUADS, + 256, + layer.build(false)); + } + + public VertexConsumer tryApply(VertexConsumer base, RenderLayer baseLayer, VertexConsumerProvider provider) { + if (!CONTAINER.shouldApply || CONTAINER.appliedContext == null || CONTAINER.appliedContext.size() == 0) + return null; + + VertexConsumer[] layers = new VertexConsumer[Math.min(CONTAINER.appliedContext.size(), Integer.MAX_VALUE /*todo cap global property*/)]; + + for (int i = 0; i < layers.length; i++) + layers[i] = provider.getBuffer(CONTAINER.appliedContext.get(i).type.renderLayers.get(GlintRenderLayer.this)); + + provider.getBuffer(baseLayer); // refresh base layer for armor consumer + + return base == null ? VertexConsumers.union(layers) : VertexConsumers.union(VertexConsumers.union(layers), base); + } + } + + private static class WrappedMethodIntensity { + public float intensity = 1f; + } public static class Blend extends RenderPhase.Transparency { private final int src, dst, srcAlpha, dstAlpha; @@ -127,30 +309,26 @@ public class TypeEnchantment extends CITType { disableBlend(); } - public static Blend getBlend(String blendString) throws BlendFormatException { + public static Blend getBlend(String blendString) throws Exception { try { //check named blending function return Named.valueOf(blendString.toUpperCase(Locale.ENGLISH)).blend; } catch (IllegalArgumentException ignored) { // create custom blending function - try { - String[] split = blendString.split(" "); - int src, dst, srcAlpha, dstAlpha; - if (split.length == 2) { - src = parseGLConstant(split[0]); - dst = parseGLConstant(split[1]); - srcAlpha = GL_ZERO; - dstAlpha = GL_ONE; - } else if (split.length == 4) { - src = parseGLConstant(split[0]); - dst = parseGLConstant(split[1]); - srcAlpha = parseGLConstant(split[2]); - dstAlpha = parseGLConstant(split[3]); - } else - throw new Exception(); - - return new Blend("custom_" + src + "_" + dst + "_" + srcAlpha + "_" + dstAlpha, src, dst, srcAlpha, dstAlpha); - } catch (Exception e) { - throw new BlendFormatException(); - } + String[] split = blendString.split("\\p{Zs}+"); + int src, dst, srcAlpha, dstAlpha; + if (split.length == 2) { + src = parseGLConstant(split[0]); + dst = parseGLConstant(split[1]); + srcAlpha = GL_ZERO; + dstAlpha = GL_ONE; + } else if (split.length == 4) { + src = parseGLConstant(split[0]); + dst = parseGLConstant(split[1]); + srcAlpha = parseGLConstant(split[2]); + dstAlpha = parseGLConstant(split[3]); + } else + throw new Exception(); + + return new Blend("custom_" + src + "_" + dst + "_" + srcAlpha + "_" + dstAlpha, src, dst, srcAlpha, dstAlpha); } } @@ -185,12 +363,6 @@ public class TypeEnchantment extends CITType { return s.startsWith("0x") ? Integer.parseInt(s.substring(2), 16) : Integer.parseInt(s); } - - public static class BlendFormatException extends Exception { - public BlendFormatException() { - super("Not a valid blending method"); - } - } } public interface CITCacheEnchantment { diff --git a/defaults/src/main/java/shcm/shsupercm/fabric/citresewn/defaults/config/CITResewnDefaultsConfig.java b/defaults/src/main/java/shcm/shsupercm/fabric/citresewn/defaults/config/CITResewnDefaultsConfig.java index 0787fba..791205b 100644 --- a/defaults/src/main/java/shcm/shsupercm/fabric/citresewn/defaults/config/CITResewnDefaultsConfig.java +++ b/defaults/src/main/java/shcm/shsupercm/fabric/citresewn/defaults/config/CITResewnDefaultsConfig.java @@ -8,7 +8,7 @@ import shcm.shsupercm.fabric.citresewn.CITResewn; import java.io.*; public class CITResewnDefaultsConfig { - + public float type_enchantment_scroll_multiplier = 1f; private static final File FILE = new File("config/citresewn-defaults.json"); diff --git a/defaults/src/main/java/shcm/shsupercm/fabric/citresewn/defaults/mixin/types/enchantment/BufferBuilderStorageAccessor.java b/defaults/src/main/java/shcm/shsupercm/fabric/citresewn/defaults/mixin/types/enchantment/BufferBuilderStorageAccessor.java new file mode 100644 index 0000000..e23e091 --- /dev/null +++ b/defaults/src/main/java/shcm/shsupercm/fabric/citresewn/defaults/mixin/types/enchantment/BufferBuilderStorageAccessor.java @@ -0,0 +1,15 @@ +package shcm.shsupercm.fabric.citresewn.defaults.mixin.types.enchantment; + +import net.minecraft.client.render.BufferBuilder; +import net.minecraft.client.render.BufferBuilderStorage; +import net.minecraft.client.render.RenderLayer; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +import java.util.SortedMap; + +@Mixin(BufferBuilderStorage.class) +public interface BufferBuilderStorageAccessor { + @Accessor + SortedMap getEntityBuilders(); +} diff --git a/defaults/src/main/java/shcm/shsupercm/fabric/citresewn/defaults/mixin/types/enchantment/RenderPhaseAccessor.java b/defaults/src/main/java/shcm/shsupercm/fabric/citresewn/defaults/mixin/types/enchantment/RenderPhaseAccessor.java new file mode 100644 index 0000000..b2a59b4 --- /dev/null +++ b/defaults/src/main/java/shcm/shsupercm/fabric/citresewn/defaults/mixin/types/enchantment/RenderPhaseAccessor.java @@ -0,0 +1,21 @@ +package shcm.shsupercm.fabric.citresewn.defaults.mixin.types.enchantment; + +import net.minecraft.client.render.RenderPhase; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +@Mixin(RenderPhase.class) +public interface RenderPhaseAccessor { + @Accessor("ARMOR_GLINT_SHADER") static RenderPhase.Shader ARMOR_GLINT_SHADER() { throw new RuntimeException(); } + @Accessor("ARMOR_ENTITY_GLINT_SHADER") static RenderPhase.Shader ARMOR_ENTITY_GLINT_SHADER() { throw new RuntimeException(); } + @Accessor("TRANSLUCENT_GLINT_SHADER") static RenderPhase.Shader TRANSLUCENT_GLINT_SHADER() { throw new RuntimeException(); } + @Accessor("GLINT_SHADER") static RenderPhase.Shader GLINT_SHADER() { throw new RuntimeException(); } + @Accessor("DIRECT_GLINT_SHADER") static RenderPhase.Shader DIRECT_GLINT_SHADER() { throw new RuntimeException(); } + @Accessor("ENTITY_GLINT_SHADER") static RenderPhase.Shader ENTITY_GLINT_SHADER() { throw new RuntimeException(); } + @Accessor("DIRECT_ENTITY_GLINT_SHADER") static RenderPhase.Shader DIRECT_ENTITY_GLINT_SHADER() { throw new RuntimeException(); } + @Accessor("DISABLE_CULLING") static RenderPhase.Cull DISABLE_CULLING() { throw new RuntimeException(); } + @Accessor("EQUAL_DEPTH_TEST") static RenderPhase.DepthTest EQUAL_DEPTH_TEST() { throw new RuntimeException(); } + @Accessor("COLOR_MASK") static RenderPhase.WriteMaskState COLOR_MASK() { throw new RuntimeException(); } + @Accessor("VIEW_OFFSET_Z_LAYERING") static RenderPhase.Layering VIEW_OFFSET_Z_LAYERING() { throw new RuntimeException(); } + @Accessor("ITEM_TARGET") static RenderPhase.Target ITEM_TARGET() { throw new RuntimeException(); } +} -- cgit