From 3879d555172c0caa5bd2c0df250cdb63f0cb0b59 Mon Sep 17 00:00:00 2001 From: JozsefA Date: Thu, 22 Apr 2021 23:42:49 -0700 Subject: [PATCH] Better projector gui --- .../resources/assets/create/lang/en_us.json | 1 + .../com/simibubi/create/AllTileEntities.java | 29 ++--- .../projector/ChromaticProjectorBlock.java | 2 +- .../projector/ChromaticProjectorInstance.java | 28 +++++ .../projector/ChromaticProjectorScreen.java | 82 ++++++++++--- .../ChromaticProjectorTileEntity.java | 52 ++++++++- .../curiosities/projector/ColorEffects.java | 26 ++++- .../curiosities/projector/FilterStep.java | 33 +++++- .../render/backend/effects/ColorMatrices.java | 10 ++ .../backend/effects/EffectsHandler.java | 108 +++++------------- .../backend/effects/SphereFilterProgram.java | 46 ++++---- .../create/flywheel/shaders/area_effect.frag | 47 +++----- .../create/flywheel/shaders/area_effect.vert | 7 +- .../assets/create/textures/gui/projector.png | Bin 3095 -> 3086 bytes 14 files changed, 300 insertions(+), 171 deletions(-) create mode 100644 src/main/java/com/simibubi/create/content/curiosities/projector/ChromaticProjectorInstance.java diff --git a/src/generated/resources/assets/create/lang/en_us.json b/src/generated/resources/assets/create/lang/en_us.json index e5aa55e81..b266bf403 100644 --- a/src/generated/resources/assets/create/lang/en_us.json +++ b/src/generated/resources/assets/create/lang/en_us.json @@ -1153,6 +1153,7 @@ "create.gui.chromatic_projector.filter.grayscale": "Grayscale", "create.gui.chromatic_projector.filter.saturate": "Saturate", "create.gui.chromatic_projector.filter.hue_shift": "Hue shift", + "create.gui.chromatic_projector.filter.darken": "Darken", "create.gui.chromatic_projector.filter.end": "End", "create.gui.chromatic_projector.filter": "Filter", "_": "->------------------------] Subtitles [------------------------<-", diff --git a/src/main/java/com/simibubi/create/AllTileEntities.java b/src/main/java/com/simibubi/create/AllTileEntities.java index d654be591..9369fa6f1 100644 --- a/src/main/java/com/simibubi/create/AllTileEntities.java +++ b/src/main/java/com/simibubi/create/AllTileEntities.java @@ -116,6 +116,7 @@ import com.simibubi.create.content.contraptions.relays.gearbox.GearboxInstance; import com.simibubi.create.content.contraptions.relays.gearbox.GearboxRenderer; import com.simibubi.create.content.contraptions.relays.gearbox.GearboxTileEntity; import com.simibubi.create.content.contraptions.relays.gearbox.GearshiftTileEntity; +import com.simibubi.create.content.curiosities.projector.ChromaticProjectorInstance; import com.simibubi.create.content.curiosities.projector.ChromaticProjectorTileEntity; import com.simibubi.create.content.logistics.block.belts.tunnel.BeltTunnelInstance; import com.simibubi.create.content.logistics.block.belts.tunnel.BeltTunnelRenderer; @@ -646,21 +647,23 @@ public class AllTileEntities { .instance(() -> AdjustableRepeaterInstance::new) .validBlocks(AllBlocks.ADJUSTABLE_REPEATER) .renderer(() -> AdjustableRepeaterRenderer::new) - .register(); + .register(); public static final TileEntityEntry ADJUSTABLE_PULSE_REPEATER = - Create.registrate() - .tileEntity("adjustable_pulse_repeater", AdjustablePulseRepeaterTileEntity::new) - .instance(() -> AdjustableRepeaterInstance::new) - .validBlocks(AllBlocks.ADJUSTABLE_PULSE_REPEATER) - .renderer(() -> AdjustableRepeaterRenderer::new) - .register(); + Create.registrate() + .tileEntity("adjustable_pulse_repeater", AdjustablePulseRepeaterTileEntity::new) + .instance(() -> AdjustableRepeaterInstance::new) + .validBlocks(AllBlocks.ADJUSTABLE_PULSE_REPEATER) + .renderer(() -> AdjustableRepeaterRenderer::new) + .register(); - public static final TileEntityEntry TESTFX = - Create.registrate() - .tileEntity("chromatic_projector", ChromaticProjectorTileEntity::new) - .validBlocks(AllBlocks.CHROMATIC_PROJECTOR) - .register(); + public static final TileEntityEntry CHROMATIC_PROJECTOR = + Create.registrate() + .tileEntity("chromatic_projector", ChromaticProjectorTileEntity::new) + .instance(() -> ChromaticProjectorInstance::new) + .validBlocks(AllBlocks.CHROMATIC_PROJECTOR) + .register(); - public static void register() {} + public static void register() { + } } diff --git a/src/main/java/com/simibubi/create/content/curiosities/projector/ChromaticProjectorBlock.java b/src/main/java/com/simibubi/create/content/curiosities/projector/ChromaticProjectorBlock.java index 86b6ebeec..28d493cc5 100644 --- a/src/main/java/com/simibubi/create/content/curiosities/projector/ChromaticProjectorBlock.java +++ b/src/main/java/com/simibubi/create/content/curiosities/projector/ChromaticProjectorBlock.java @@ -54,7 +54,7 @@ public class ChromaticProjectorBlock extends Block implements ITE implements IDynamicInstance { + + public ChromaticProjectorInstance(InstancedTileRenderer renderer, ChromaticProjectorTileEntity tile) { + super(renderer, tile); + } + + @Override + public void beginFrame() { + Backend.effects.addSphere(tile.makeFilter()); + } + + @Override + public boolean decreaseFramerateWithDistance() { + return false; + } + + @Override + public void remove() { + + } +} diff --git a/src/main/java/com/simibubi/create/content/curiosities/projector/ChromaticProjectorScreen.java b/src/main/java/com/simibubi/create/content/curiosities/projector/ChromaticProjectorScreen.java index 1c74cf804..e7074cb6d 100644 --- a/src/main/java/com/simibubi/create/content/curiosities/projector/ChromaticProjectorScreen.java +++ b/src/main/java/com/simibubi/create/content/curiosities/projector/ChromaticProjectorScreen.java @@ -1,5 +1,6 @@ package com.simibubi.create.content.curiosities.projector; +import java.util.Collections; import java.util.Vector; import com.mojang.blaze3d.matrix.MatrixStack; @@ -11,6 +12,7 @@ import com.simibubi.create.foundation.gui.GuiGameElement; import com.simibubi.create.foundation.gui.widgets.IconButton; import com.simibubi.create.foundation.gui.widgets.ScrollInput; import com.simibubi.create.foundation.gui.widgets.SelectionScrollInput; +import com.simibubi.create.foundation.tileEntity.behaviour.scrollvalue.ScrollValueBehaviour; import com.simibubi.create.foundation.utility.Lang; import net.minecraft.client.Minecraft; @@ -35,12 +37,24 @@ public class ChromaticProjectorScreen extends AbstractSimiScreen { private Vector> inputs; + ChromaticProjectorTileEntity tile; + + private ScrollInput radius; + private ScrollInput density; + private ScrollInput feather; + private ScrollInput fade; + public ChromaticProjectorScreen(ChromaticProjectorTileEntity te) { + this.tile = te; this.stages = te.stages; this.pos = te.getPos(); //compareTag = Instruction.serializeAll(stages); } + private static Integer step(ScrollValueBehaviour.StepContext ctx, int base) { + return ctx.control ? 1 : base * (ctx.shift ? 5 : 1); + } + @Override protected void init() { setWindowSize(background.width + 50, background.height); @@ -57,6 +71,32 @@ public class ChromaticProjectorScreen extends AbstractSimiScreen { confirmButton = new IconButton(guiLeft + background.width - 33, guiTop + background.height - 24, AllIcons.I_CONFIRM); widgets.add(confirmButton); + radius = new ScrollInput(guiLeft + 46, guiTop + 117, 28, 18) + .titled(new StringTextComponent("Radius")) + .withStepFunction(ctx -> step(ctx, 2)) + .calling(tile::setRadius) + .withRange(0, 201) + .setState((int) (tile.radius * 2)); + feather = new ScrollInput(guiLeft + 46, guiTop + 139, 28, 18) + .titled(new StringTextComponent("Feather")) + .withStepFunction(ctx -> step(ctx, 5)) + .calling(tile::setFeather) + .withRange(0, 201) + .setState((int) (tile.feather * 4)); + fade = new ScrollInput(guiLeft + 117, guiTop + 139, 28, 18) + .titled(new StringTextComponent("Fade")) + .withStepFunction(ctx -> step(ctx, 1)) + .calling(tile::setFade) + .withRange(0, 51) + .setState((int) (tile.fade * 10)); + density = new ScrollInput(guiLeft + 117, guiTop + 117, 28, 18) + .titled(new StringTextComponent("Density")) + .withStepFunction(ctx -> step(ctx, 10)) + .calling(tile::setDensity) + .withRange(0, 401) + .setState((int) (tile.density * 100)); + + Collections.addAll(widgets, radius, density, feather, fade); } public void initInputsOfRow(int row) { @@ -73,10 +113,11 @@ public class ChromaticProjectorScreen extends AbstractSimiScreen { ScrollInput type = new SelectionScrollInput(x, y + rowHeight * row, 86, 18).forOptions(ColorEffects.getOptions()) .calling(state -> instructionUpdated(index, state)) - .setState(instruction.instruction.ordinal()) + .setState(instruction.filter.ordinal()) .titled(Lang.translate("gui.chromatic_projector.filter")); ScrollInput value = - new ScrollInput(x + 86 + 2, y + rowHeight * row, 28, 18).calling(state -> instruction.value = state); + new ScrollInput(x + 86 + 2, y + rowHeight * row, 28, 18) + .calling(state -> instruction.value = state); rowInputs.add(type); rowInputs.add(value); @@ -88,15 +129,15 @@ public class ChromaticProjectorScreen extends AbstractSimiScreen { public void updateParamsOfRow(int row) { FilterStep instruction = stages.get(row); Vector rowInputs = inputs.get(row); - ColorEffects def = instruction.instruction; + ColorEffects def = instruction.filter; boolean hasValue = def.hasParameter; ScrollInput value = rowInputs.get(1); value.active = value.visible = hasValue; if (hasValue) - value.withRange(0, 100) + value.withRange(def.minValue, def.maxValue + 1) //.titled(Lang.translate(def.parameterKey)) - //.withShiftStep(def.shiftStep) + .withShiftStep(5) .setState(instruction.value) .onChanged(); @@ -116,36 +157,47 @@ public class ChromaticProjectorScreen extends AbstractSimiScreen { continue; } - FilterStep instruction = stages.get(row); - ColorEffects def = instruction.instruction; + FilterStep step = stages.get(row); + ColorEffects def = step.filter; def.background.draw(matrixStack, guiLeft, guiTop + 14 + yOffset); - label(matrixStack, 36, yOffset - 3, Lang.translate(def.translationKey)); + if (def != ColorEffects.END) + label(matrixStack, 36, yOffset - 3, Lang.translate(def.translationKey)); if (def.hasParameter) { - String text = instruction.value + " %"; + String text = step.filter.formatValue(step.value); int stringWidth = textRenderer.getStringWidth(text); label(matrixStack, 118 + (12 - stringWidth / 2), yOffset - 3, new StringTextComponent(text)); } } + renderScroll(matrixStack, radius, 2f); + renderScroll(matrixStack, density, 100f); + renderScroll(matrixStack, feather, 4f); + renderScroll(matrixStack, fade, 10f); + textRenderer.drawWithShadow(matrixStack, title, guiLeft - 3 + (background.width - textRenderer.getWidth(title)) / 2, guiTop + 3, 0xffffff); GuiGameElement.of(renderedItem) - .at(guiLeft + background.width + 10, guiTop + 100, -150) + .at(guiLeft + background.width + 10, guiTop + 140, -150) .scale(5) .render(matrixStack); } + private void renderScroll(MatrixStack matrixStack, ScrollInput input, float divisor) { + + String text = String.valueOf(input.getState() / divisor); + + int stringWidth = textRenderer.getStringWidth(text); + textRenderer.drawWithShadow(matrixStack, text, input.x + (12 - stringWidth / 2), input.y + 5, 0xFFFFEE); + } + private void label(MatrixStack matrixStack, int x, int y, ITextComponent text) { textRenderer.drawWithShadow(matrixStack, text, guiLeft + x, guiTop + 26 + y, 0xFFFFEE); } public void sendPacket() { -// ListNBT serialized = Instruction.serializeAll(stages); -// if (serialized.equals(compareTag)) -// return; -// AllPackets.channel.sendToServer(new ConfigureSequencedGearshiftPacket(pos, serialized)); + } @Override @@ -155,7 +207,7 @@ public class ChromaticProjectorScreen extends AbstractSimiScreen { private void instructionUpdated(int index, int state) { ColorEffects newValue = ColorEffects.values()[state]; - stages.get(index).instruction = newValue; + stages.get(index).filter = newValue; stages.get(index).value = 100; updateParamsOfRow(index); if (newValue == ColorEffects.END) { diff --git a/src/main/java/com/simibubi/create/content/curiosities/projector/ChromaticProjectorTileEntity.java b/src/main/java/com/simibubi/create/content/curiosities/projector/ChromaticProjectorTileEntity.java index 79b20d45c..b6f9f4089 100644 --- a/src/main/java/com/simibubi/create/content/curiosities/projector/ChromaticProjectorTileEntity.java +++ b/src/main/java/com/simibubi/create/content/curiosities/projector/ChromaticProjectorTileEntity.java @@ -2,14 +2,64 @@ package com.simibubi.create.content.curiosities.projector; import java.util.Vector; +import com.simibubi.create.foundation.render.backend.effects.SphereFilterProgram; +import com.simibubi.create.foundation.render.backend.instancing.IInstanceRendered; + import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntityType; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.vector.Matrix4f; -public class ChromaticProjectorTileEntity extends TileEntity { +public class ChromaticProjectorTileEntity extends TileEntity implements IInstanceRendered { Vector stages = FilterStep.createDefault(); + float radius = 10f; + float density = 1f; + float feather = 3; + float fade = 1.3f; + boolean blend = true; + public ChromaticProjectorTileEntity(TileEntityType te) { super(te); } + + public SphereFilterProgram.FilterSphere makeFilter() { + Matrix4f filter = FilterStep.fold(stages); + + BlockPos pos = getPos(); + return new SphereFilterProgram.FilterSphere() + .setFilter(filter) + .setCenter(pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5) + .setRadius(radius) + .setDensity(density) + .setFeather(feather) + .setBlendOver(false) + .setFade(fade); + } + + public ChromaticProjectorTileEntity setRadius(int radius) { + this.radius = radius / 2f; + return this; + } + + public ChromaticProjectorTileEntity setDensity(int density) { + this.density = density / 100f; + return this; + } + + public ChromaticProjectorTileEntity setFeather(int feather) { + this.feather = feather / 4f; + return this; + } + + public ChromaticProjectorTileEntity setFade(int fade) { + this.fade = feather / 10f; + return this; + } + + public ChromaticProjectorTileEntity setBlend(boolean blend) { + this.blend = blend; + return this; + } } diff --git a/src/main/java/com/simibubi/create/content/curiosities/projector/ColorEffects.java b/src/main/java/com/simibubi/create/content/curiosities/projector/ColorEffects.java index abddf5773..964af44d0 100644 --- a/src/main/java/com/simibubi/create/content/curiosities/projector/ColorEffects.java +++ b/src/main/java/com/simibubi/create/content/curiosities/projector/ColorEffects.java @@ -15,8 +15,9 @@ public enum ColorEffects { INVERT(ColorMatrices::invert), SEPIA(ColorMatrices::sepia), GRAYSCALE(ColorMatrices::grayscale), - SATURATE(ColorMatrices::saturate), - HUE_SHIFT(ColorMatrices::hueShift), + DARKEN(ColorMatrices::darken), + SATURATE(ColorMatrices::saturate, 0, 200), + HUE_SHIFT(ColorMatrices::hueShift, 0, 360, 1f), END(ColorMatrices::identity, AllGuiTextures.PROJECTOR_END), ; @@ -26,6 +27,10 @@ public enum ColorEffects { String translationKey; AllGuiTextures background; + int minValue = 0; + int maxValue = 100; + float divisor = 100f; + ColorEffects(Supplier filter, AllGuiTextures background) { this($ -> filter.get(), false, background); } @@ -35,7 +40,18 @@ public enum ColorEffects { } ColorEffects(FilterFactory filter) { + this(filter, 0, 100); + } + + ColorEffects(FilterFactory filter, int minValue, int maxValue) { + this(filter, minValue, maxValue, 100f); + } + + ColorEffects(FilterFactory filter, int minValue, int maxValue, float divisor) { this(filter, true, AllGuiTextures.PROJECTOR_FILTER_STRENGTH); + this.minValue = minValue; + this.maxValue = maxValue; + this.divisor = divisor; } ColorEffects(FilterFactory filter, boolean hasParameter, AllGuiTextures background) { @@ -45,6 +61,12 @@ public enum ColorEffects { translationKey = "gui.chromatic_projector.filter." + Lang.asId(name()); } + String formatValue(int value) { + if (this == HUE_SHIFT) + return value + Lang.translate("generic.unit.degrees").getString(); + return "" + value; + } + static List getOptions() { List options = new ArrayList<>(); for (ColorEffects entry : values()) diff --git a/src/main/java/com/simibubi/create/content/curiosities/projector/FilterStep.java b/src/main/java/com/simibubi/create/content/curiosities/projector/FilterStep.java index 576df6c31..cb77ed07e 100644 --- a/src/main/java/com/simibubi/create/content/curiosities/projector/FilterStep.java +++ b/src/main/java/com/simibubi/create/content/curiosities/projector/FilterStep.java @@ -1,21 +1,44 @@ package com.simibubi.create.content.curiosities.projector; +import java.util.Iterator; import java.util.Vector; +import com.simibubi.create.foundation.render.backend.effects.ColorMatrices; + +import net.minecraft.util.math.vector.Matrix4f; + public class FilterStep { - ColorEffects instruction; + ColorEffects filter; int value; - public FilterStep(ColorEffects instruction) { - this.instruction = instruction; + public FilterStep(ColorEffects filter) { + this.filter = filter; } - public FilterStep(ColorEffects instruction, int value) { - this.instruction = instruction; + public FilterStep(ColorEffects filter, int value) { + this.filter = filter; this.value = value; } + public Matrix4f createFilter() { + return filter.filter.create(value / filter.divisor); + } + + public static Matrix4f fold(Vector filters) { + Iterator stepIterator = filters.stream().filter(it -> it != null && it.filter != ColorEffects.END).iterator(); + + if (stepIterator.hasNext()) { + Matrix4f accum = stepIterator.next().createFilter(); + + stepIterator.forEachRemaining(filterStep -> accum.multiply(filterStep.createFilter())); + + return accum; + } + + return ColorMatrices.identity(); + } + public static Vector createDefault() { Vector instructions = new Vector<>(ChromaticProjectorScreen.MAX_STEPS); instructions.add(new FilterStep(ColorEffects.SEPIA, 100)); diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/effects/ColorMatrices.java b/src/main/java/com/simibubi/create/foundation/render/backend/effects/ColorMatrices.java index 2bab3cfe0..99340ea31 100644 --- a/src/main/java/com/simibubi/create/foundation/render/backend/effects/ColorMatrices.java +++ b/src/main/java/com/simibubi/create/foundation/render/backend/effects/ColorMatrices.java @@ -92,6 +92,16 @@ public class ColorMatrices { return mat; } + public static Matrix4f darken(float amount) { + Matrix4f darken = new Matrix4f(); + darken.loadIdentity(); + darken.multiply(1f - amount); + darken.a03 = amount; + darken.a13 = amount; + darken.a23 = amount; + return darken; + } + public static Matrix4f identity() { Matrix4f mat = new Matrix4f(); mat.loadIdentity(); diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/effects/EffectsHandler.java b/src/main/java/com/simibubi/create/foundation/render/backend/effects/EffectsHandler.java index 0252924d1..f6368c9b5 100644 --- a/src/main/java/com/simibubi/create/foundation/render/backend/effects/EffectsHandler.java +++ b/src/main/java/com/simibubi/create/foundation/render/backend/effects/EffectsHandler.java @@ -1,5 +1,7 @@ package com.simibubi.create.foundation.render.backend.effects; +import java.util.ArrayList; + import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL15; import org.lwjgl.opengl.GL20; @@ -14,6 +16,7 @@ import com.simibubi.create.foundation.utility.AnimationTickHolder; import net.minecraft.client.MainWindow; import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.ActiveRenderInfo; import net.minecraft.client.renderer.GameRenderer; import net.minecraft.client.shader.Framebuffer; import net.minecraft.client.shader.FramebufferConstants; @@ -48,7 +51,11 @@ public class EffectsHandler { private final GlBuffer vbo = new GlBuffer(GL20.GL_ARRAY_BUFFER); + private final ArrayList spheres; + public EffectsHandler() { + spheres = new ArrayList<>(); + Framebuffer render = Minecraft.getInstance().getFramebuffer(); framebuffer = new Framebuffer(render.framebufferWidth, render.framebufferHeight, false, Minecraft.IS_RUNNING_ON_MAC); @@ -64,21 +71,17 @@ public class EffectsHandler { vao.unbind(); vbo.unbind(); + } - public void prepFramebufferSize() { - MainWindow window = Minecraft.getInstance().getWindow(); - if (framebuffer.framebufferWidth != window.getFramebufferWidth() - || framebuffer.framebufferHeight != window.getFramebufferHeight()) { - framebuffer.func_216491_a(window.getFramebufferWidth(), window.getFramebufferHeight(), - Minecraft.IS_RUNNING_ON_MAC); - } + public void addSphere(SphereFilterProgram.FilterSphere sphere) { + this.spheres.add(sphere); } public void render(Matrix4f view) { -// if (true) { -// return; -// } + if (spheres.size() == 0) { + return; + } GL20.glEnable(GL20.GL_DEPTH_TEST); @@ -98,7 +101,8 @@ public class EffectsHandler { program.bindDepthTexture(mainBuffer.getDepthAttachment()); GameRenderer gameRenderer = Minecraft.getInstance().gameRenderer; - Matrix4f projection = gameRenderer.getBasicProjectionMatrix(gameRenderer.getActiveRenderInfo(), AnimationTickHolder.getPartialTicks(), true); + ActiveRenderInfo activeRenderInfo = gameRenderer.getActiveRenderInfo(); + Matrix4f projection = gameRenderer.getBasicProjectionMatrix(activeRenderInfo, AnimationTickHolder.getPartialTicks(), true); projection.a33 = 1; projection.invert(); program.bindInverseProjection(projection); @@ -107,76 +111,17 @@ public class EffectsHandler { inverseView.invert(); program.bindInverseView(inverseView); - Vector3d cameraPos = gameRenderer.getActiveRenderInfo().getProjectedView(); + Vector3d cameraPos = activeRenderInfo.getProjectedView(); program.setCameraPos(cameraPos.inverse()); -// int n = 64; -// double rad = 15; -// for (int i = 0; i < n; i++) { -// double angle = ((double) i) / n * Math.PI * 2; -// program.addSphere(new SphereFilterProgram.FilterSphere() -// .setCenter(new Vector3d(852, 77, -204).subtract(cameraPos).add(Math.sin(angle) * rad, 0, Math.cos(angle) * rad)) -// .setRadius(15) -// .setFeather(3f) -// .setFade(1f) -// .setDensity(0.5f) -// .setFilter(ColorMatrices.hueShiftRGB((float) i / n * 360 + i / 2f))); -// } + for (SphereFilterProgram.FilterSphere sphere : spheres) { + sphere.center = sphere.center.subtract(cameraPos); + } - program.addSphere(new SphereFilterProgram.FilterSphere() - .setCenter(new Vector3d(865.5, 79, -240.5).subtract(cameraPos)) - .setRadius(10f) - .setFeather(3f) - .setFade(1.8f) - .setDensity(1.3f) - .setFilter(ColorMatrices.grayscale())); + spheres.sort((o1, o2) -> (int) Math.signum(o2.center.length() - o1.center.length())); - program.addSphere(new SphereFilterProgram.FilterSphere() - .setCenter(new Vector3d(852.5, 70, -203.5).subtract(cameraPos)) - .setRadius(20f) - .setFeather(3f) - .setFade(1f) - .setDensity(1.3f) - .setFilter(ColorMatrices.sepia(1f))); - -// Matrix4f test = ColorMatrices.sepia(1f); -// -// -// test.multiply(ColorMatrices.invert()); -// -// Matrix4f darken = new Matrix4f(); -// darken.loadIdentity(); -// darken.multiply(0.7f); -// darken.a03 = 0.7f; -// darken.a13 = 0.7f; -// darken.a23 = 0.7f; -// test.multiply(darken); - - Matrix4f test = ColorMatrices.saturate(2f); - - test.multiply(ColorMatrices.hueShift(120f)); - - program.addSphere(new SphereFilterProgram.FilterSphere() - .setCenter(new Vector3d(858.5, 88, -259.5).subtract(cameraPos)) - .setRadius(10f) - .setFeather(3f) - .setFade(1.8f) - .setDensity(0.5f) - .setStrength(1f) - .setFilter(test)); - - - program.addSphere(new SphereFilterProgram.FilterSphere() - .setCenter(new Vector3d(2310, 60, -954).subtract(cameraPos)) - .setRadius(8f) - .setFeather(3f) - .setFade(0.8f) - .setDensity(1.3f) - .setStrength(1f) - .setFilter(ColorMatrices.grayscale())); - - program.uploadFilters(); + program.uploadFilters(spheres); program.setFarPlane(getFarPlane()); program.setNearPlane(getNearPlane()); @@ -189,8 +134,8 @@ public class EffectsHandler { program.bindDepthTexture(0); GL20.glActiveTexture(GL20.GL_TEXTURE0); - program.clear(); program.unbind(); + spheres.clear(); Backend.compat.fbo.bindFramebuffer(GL30.GL_READ_FRAMEBUFFER, framebuffer.framebufferObject); Backend.compat.fbo.bindFramebuffer(GL30.GL_DRAW_FRAMEBUFFER, mainBuffer.framebufferObject); @@ -204,4 +149,13 @@ public class EffectsHandler { vao.delete(); vbo.delete(); } + + private void prepFramebufferSize() { + MainWindow window = Minecraft.getInstance().getWindow(); + if (framebuffer.framebufferWidth != window.getFramebufferWidth() + || framebuffer.framebufferHeight != window.getFramebufferHeight()) { + framebuffer.func_216491_a(window.getFramebufferWidth(), window.getFramebufferHeight(), + Minecraft.IS_RUNNING_ON_MAC); + } + } } diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/effects/SphereFilterProgram.java b/src/main/java/com/simibubi/create/foundation/render/backend/effects/SphereFilterProgram.java index 4616e8768..406059e74 100644 --- a/src/main/java/com/simibubi/create/foundation/render/backend/effects/SphereFilterProgram.java +++ b/src/main/java/com/simibubi/create/foundation/render/backend/effects/SphereFilterProgram.java @@ -1,6 +1,5 @@ package com.simibubi.create.foundation.render.backend.effects; -import java.nio.ByteBuffer; import java.nio.FloatBuffer; import java.util.ArrayList; @@ -29,8 +28,6 @@ public class SphereFilterProgram extends GlProgram { public final GlBuffer effectsUBO; - protected final ArrayList filters = new ArrayList<>(16); - protected final int uniformBlock; protected final int uDepth; @@ -82,17 +79,15 @@ public class SphereFilterProgram extends GlProgram { GL20.glUniform3f(uCameraPos, (float) pos.x, (float) pos.y, (float) pos.z); } - public void clear() { - filters.clear(); - } - - public void addSphere(FilterSphere filterSphere) { - filters.add(filterSphere); - } - - public void uploadFilters() { + public void uploadFilters(ArrayList filters) { effectsUBO.bind(GL20.GL_ARRAY_BUFFER); - effectsUBO.map(GL20.GL_ARRAY_BUFFER, 0, BUFFER_SIZE, this::uploadUBO); + effectsUBO.map(GL20.GL_ARRAY_BUFFER, 0, BUFFER_SIZE, buf -> { + buf.putInt(filters.size()); + buf.position(16); + FloatBuffer floatBuffer = buf.asFloatBuffer(); + + filters.forEach(it -> it.write(floatBuffer)); + }); effectsUBO.unbind(GL20.GL_ARRAY_BUFFER); } @@ -114,14 +109,6 @@ public class SphereFilterProgram extends GlProgram { GL20.glBindTexture(GL20.GL_TEXTURE_2D, textureObject); } - private void uploadUBO(ByteBuffer buf) { - buf.putInt(filters.size()); - buf.position(16); - FloatBuffer floatBuffer = buf.asFloatBuffer(); - - filters.forEach(it -> it.write(floatBuffer)); - } - public static class FilterSphere { public Vector3d center; public float radius; @@ -129,6 +116,7 @@ public class SphereFilterProgram extends GlProgram { public float fade; public float density = 2; public float strength = 1; + public boolean blendOver = false; public Matrix4f filter; @@ -137,6 +125,11 @@ public class SphereFilterProgram extends GlProgram { return this; } + public FilterSphere setCenter(double x, double y, double z) { + this.center = new Vector3d(x, y, z); + return this; + } + public FilterSphere setRadius(float radius) { this.radius = radius; return this; @@ -167,6 +160,11 @@ public class SphereFilterProgram extends GlProgram { return this; } + public FilterSphere setBlendOver(boolean blendOver) { + this.blendOver = blendOver; + return this; + } + public void write(FloatBuffer buf) { buf.put(new float[]{ (float) center.x, @@ -176,7 +174,11 @@ public class SphereFilterProgram extends GlProgram { feather, fade, density, - strength, + blendOver ? 1f : 0f, + 1f, + 1f, + 0f, + 0f, }); buf.put(RenderUtil.writeMatrix(filter)); diff --git a/src/main/resources/assets/create/flywheel/shaders/area_effect.frag b/src/main/resources/assets/create/flywheel/shaders/area_effect.frag index 00691aeb1..e36d9056d 100644 --- a/src/main/resources/assets/create/flywheel/shaders/area_effect.frag +++ b/src/main/resources/assets/create/flywheel/shaders/area_effect.frag @@ -16,34 +16,11 @@ uniform vec3 uCameraPos; struct SphereFilter { vec4 sphere;// - vec4 data;// + vec4 d1;// + vec4 d2;// mat4 colorOp; }; -vec3 getPosition(SphereFilter f) { - return f.sphere.xyz; -} - -float getRadius(SphereFilter f) { - return f.sphere.w; -} - -float getFeather(SphereFilter f) { - return f.data.x; -} - -float getFade(SphereFilter f) { - return f.data.y; -} - -float getDensity(SphereFilter f) { - return f.data.z; -} - -float getStrength(SphereFilter f) { - return f.data.w; -} - #define N 256 layout (std140) uniform Filters { int uCount; @@ -113,18 +90,22 @@ float bubbleFilterStrength(vec3 worldDir, float depth, vec4 sphere, float feathe return clamp(strength, 0., 1.);// * boo; } -float filterStrength(vec3 worldDir, float depth, vec4 sphere, vec4 data) { +float filterStrength(vec3 worldDir, float depth, inout SphereFilter f) { + vec4 sphere = f.sphere; + vec4 data = f.d1; float feather = data.x; float strength = 0.; // transition effect float transitionRadius = sphere.w + feather; strength += 1. - smoothstep(transitionRadius, transitionRadius + data.y, length(sphere.xyz)); - // surface effect - strength += surfaceFilterStrength(worldDir * depth, sphere, feather); // bubble effect strength += bubbleFilterStrength(worldDir, depth, sphere, feather, data.z); + strength *= f.d2.y; + // surface effect + strength += surfaceFilterStrength(worldDir * depth, sphere, feather) * f.d2.x; + return strength; } @@ -137,16 +118,16 @@ vec3 applyFilters(vec3 worldDir, float depth, vec3 diffuse) { for (int i = 0; i < uCount; i++) { SphereFilter s = uSpheres[i]; - float strength = filterStrength(worldDir, depth, s.sphere, s.data); + float strength = filterStrength(worldDir, depth, s); if (strength > 0) { const float fcon = 0.; - vec3 formatted = mix(diffuse, hsv, fcon); - vec3 filtered = filterColor(s.colorOp, formatted); - filtered = mix(filtered, hsv2rgbWrapped(filtered), fcon); + //vec3 formatted = mix(diffuse, hsv, fcon); + vec3 filtered = filterColor(s.colorOp, mix(diffuse, accum, s.d1.w)); + //filtered = mix(filtered, hsv2rgbWrapped(filtered), fcon); - float mixing = clamp(strength * s.data.w, 0., 1.); + float mixing = clamp(strength, 0., 1.); accum = mix(accum, filtered, mixing); } } diff --git a/src/main/resources/assets/create/flywheel/shaders/area_effect.vert b/src/main/resources/assets/create/flywheel/shaders/area_effect.vert index 6c1d35d5f..0a0d8443a 100644 --- a/src/main/resources/assets/create/flywheel/shaders/area_effect.vert +++ b/src/main/resources/assets/create/flywheel/shaders/area_effect.vert @@ -1,8 +1,11 @@ #version 140 // scaling constants -#define SXY 1.7282818// e - 0.99, this works too well -#define SZ 1.905// who knows, but it works +// e - 0.99, this works well, no idea why +#define SXY 1.7282818 +// 1.90 -> highp close, mediump far +// 1.91 -> mediump close, highp far +#define SZ 1.905 in vec4 aVertex;// diff --git a/src/main/resources/assets/create/textures/gui/projector.png b/src/main/resources/assets/create/textures/gui/projector.png index b2eaa0404874786d448563f2956a112ca51bc31d..165ac24d206aa6a5ded0317397fded44b7030006 100644 GIT binary patch literal 3086 zcmcImdpwlc8$a)B7(*&1mrBtjid@p#%E$~6BbSoaB{OX3HWhNqWX8A@ev-^=rHeNKn3< z7Mh_S_#1NvD)5|diMh7zj>K$%4<5-Qsu zv88)?aX27Ca{rIUyFGo~S6tCQkwGguDjd4ku;CcbyXd{Uvz@pzN08E zM;CuG3U}TPB3!@wYFq=wHXg&7or)eqfo*%bT3W2tRWkyjNf90``2^G0n&~KsD2HHz z;pe5u^F86!s@^_6Q*+yo`ky`P(jHqUrpHV-Zh<-rSm5el;jKMk4Wrnzat|jXCIdjY zhZE@gddzTYPgB=_biNp5HK}&PFaScBfgcpy;cu+9EsK;GE|FqO4E5uEKRUJBqT%^ zN&CoJKQ$)#aj*RF+-Fu%$;@ZEek`%7;RZ5_IG0(FznrzG3v~{jH4uLIaJ$1mA=VK@ zwmAV3%Q3r%rAHcJ*K@0lsZ^>@3swaObsoV(R~V?`^DJ*v_Twi{ip;rspsrqm^7Z@u z#?XoUDH<~Xaju|!xL41ch?|>4I4C@Cp__f%LgrYlp^Nho9e~SIQL9zez&-Z^09oF= z_IVZ3@2)x}_s{ zuWJ}CP~Xk6{8fEEzvZ$H!TOWC{c*Q=#6#$~rVh@xrvLUjG(A0?1TH_qn&Cu~5%ak< zZ;p-s!4T?@<2Ji%`{}Uz+Cn)ArF_+G`as82SYx?THY5(=)812gD~3N9$|-2K z2DNZf3W|AeSV>!!`j18-c8;L`aodgMwEdaR&rMP z(H4ziuCu$e5}C_=MCl6BsEw(G3sy$L`va}G;qv=QW2h^Rp)qu4hG%1(tocqR$iB6x z$J~7l;A~;yk={8-u)ciH%jwo|I3!wocw!+ZE_1ONhX4rXtxay~v!cimk6c&d56?ks zu1lA|u2r#{&}cL_&(kOa96VBp3JJe&>ZXy`6vdb@Ub{l!oj7u^NqnA%4WWk~wU&z9 zyix1ykclXL@*Ja(%C7`%%gZmqGGB{`4iBjiYvA2{53|73jWL_g7NarXNLw$ab97eE zrPaqEhYDry*yx93A;Y4GbcPxe|G`sIDSxYM&Dv{+>?>{2d!Z7fRyjsy7RgE*^ni@7 z@LKrdxKH;DL!6-qZ;6!Y#>b_6Zf*M$doI3AksNpE>MvCAvh40#ianQR%#_GTKh%R6 z?#H8N?~6vLG31SCOAjnjk!^6L^>MZNZ`eZhDM5x8HhUm8(J_r8$+Pj z8M+)6CkdQ(ZUL_A{JY=aq1Z6-xz&Vy?q@q*cbG&krKfM|mH%^;C`cxh{~S2Ui2yWb zf6eI)kVbC6rwN(A7rt#-&kLxeeK5rEw^m|^y~*Kqi z@|-nV3@$qxFrWJi&vL2^BHB>Guru3De6(=T4|o1@7?&Gv*${m(IHvWB6;AG6PS2M1}Qu)mDjA{+AB?CCU%X`1cO+R%AyRQffI$&ovL?oH! zZ$8O+)l~G)st1cnCe|jQ2fWBRmKo!Mdi|8uv|d6d>#c6 z$ci^y1!CHL+oUEsct3B5lo>#+_!;y6rH8tD3 zZ$!A(p1m8^?{d)H!OmQahSr$9*qf!P+GO4i65}M}43{$~+JrE!T}1ScjEWkZm=JU? zr{wGkrtMj&-<%tR1&@wF$Q4Omc0FPT!;5`2VME8c=}Sv=Zwe)H;-s082Jm>o;}Kdr zBx7UFWU#Qrb7IBp!uBf7#LEL4FEaW1D#Bt>ax!vmlURxNd^toK%_z@k+Y0EXmKc7C zE~nE1AmTx!#o`M-l{oDM1l4J2DqWqOTj>`ypjgB%HpCKws}uvh8*l<$4e*UVK{{F= zcFhm9k-*sg6HchD4A$)!9ngthT9}=eY=_4uztugx-esyE6=flHDD~r6Pt%2BN08~w z_^B>$v97L8#OveIk0w5YTpt0>lSPy%_g%}t(>QssGrHUE#8mfln3*+bV8!m!pr8`5 zCi+}OcHb^F5dVB&E*(MTKQ$_J03H=Qo+%!WPwOGD`%DoYD(dTIy literal 3095 zcmcgueLRzEAHVj34QWFqDbmn!gu;_EM@@%99ZE(MrsL$bLf(?tq)r^twB)5GPUNi& z8EM#3k(V>2v{-rRk(HSxAvQes@|;iS`RDoXdG3F%`}*GZ@8$Ylzu)(|Qun*;S)r`0 z3;)R%mwENoB<5!xVFA0w% zDsDG*Q#e+0@1DLVPW^W_;-7}5XK6>;i7}DH3%}c8KCd1}oHMwdnHTEz zXr1G_S`5$dx_+cyj^;IDfUx#u*Z8$r%2NH{${fyZAMtqevv{c>ce|^;e&2`ZB^KCr z7Y05n)zMJDFV`aQR&zGzqTu-8#Mst~M9wMc$PT*n=L!1J+(wb^Ymz#4ZnX1Se>Vby z&E&aKN)|L%ceqvb;^(``i}TKtWqz5qvWMCIu17X*dABr`JX@Qu2v!_Ka4F5tPiq59 z8lWodhJ)2wXmH362mF#UA)xNc4Uz+#S|@ANw3KXy$>v{59PCHf_0JD(84PumU{2Ii zq$Basx)o!yfwlt?Ib))}o*p+S+aiwzehBN<=t+K)ZoQP9Fwj;$A4!)8!_0gUw52u{ zSgfrvp?g$h9Y1lRBgoQtA=&BjlORicIrqoQxXkJ4==PfNN8RAezHs6DO@zE#HE~P1 zwcSl-VVs3o8&RwH+BPlKB7wN$PWJ@k6vcSD=(J?Y)k^xH1)sI#+Q-OR(_*%=H}QN% z8LWWEQy$K~5W?A|gr;iSLr^LqI>v*+c=N++y31jEwUwnAV{N)VnPRi%nStgx@ntZc zs}0T=P+boH8Xes$Qn~2E(M|@IKn62&4_6IRUXAqp%;b(4re`!Q?qW*hvWU@1w+Wyl- zFv|?ht#l5Aok)mrz5iz71>!}n>bZcRuW-i{_>@dw@F>j*To_mJvozs@&O}+Q+`=mm z_S?h4D7Md9wF^;;)F9Rt2<*3j8Qoa=Ak%}rdUxD#Xkwz0zebVb2x5BW;hpORS(ZQV zm5iiiXBYED!A&lfDM&w0G17bvwg0G*1A%!1w5L@XVAaeRl(!j>S?aH;{f>7O+j*g2~yEuA>90-nMEo zf8tPzrVafPPZDDD^g%fn`<)@sRr=_CTuJU&9|znY%fXmiw=}4oV#1y~ap1PHjv|X_iIftZ{|LyOMumWR=C&IU}(L^8+_>xEd(1Vbd$aEAM5F@q_>4@ zX7X7yM^IYs2G?qnCCSFJeb!#weHoW3n{;a6pifPHs*#B+c5X#Mg+eWF%vbOu4h3W` zvs84ClIH?U>k;c&l?sl}Kfgc56@=X&4)ihVIzlgQfT-xrM_X&DF2;W5wDLy1sJr*c zJ7IHLE)^@Mv{E7ENd&r}-Rrd}n!CY6A;U3o395t+D8zr^s8k2>u_;9ShdcH_@L;=~ z;?nC1n8|twdcx#=-%`%qyyu-3VNzH&<(VlVs|>}naUkA35PtuZupp6Ro4{g1`+gw= zjw+mbv_DP!p(4TOgc7s?*cZRV&xeq+A%4{fNY<ivpbevh%^+3c-~V$F*!*hOmmE8`-n@bXrs%?@ z5C|WT{TY`0Mb(Mrv;D;2=lQftTX}G~mj|S;9l2bbe|KM4vw@n{|Cf4dGj%CZ4t1O_ zUQP5XcZ32Z-~Qs~s~bMibvvgR6dFi}gn;WHu66M6^lY+pTb5G0s0lZz@FO==aEyH4 z8E)Qj3{HE9aJu~H@K3?9W97*=yXzuqb{4jbZv}(3HqlQQ?Qa(!<$OSzYhP@%x)M`T znFr3)U3_e(;*X6_BE2@3**Obj>`>xv~ihfy^cl;-KRi``r-l;g!>85$%5v5UG}rVX znh=RW71A%@Q8X~VEen!o?#xUb|F@or*F;6w;8$yJ_|wyEsKUq#{kbL+uIah?=qD`D z=2@vgApJ+OACO!YxT^v9@B-DlBG~IMzxIl-VPY4b;>yLhfxd#@kbc>H$ne==m4>Cy z#is*Rss||ZZWBAs6fXYg2!<`@0~v~qXjD9-IceM(`&lE_G|38 zE~Fq%0UE#pHfU?TO#^c@$5wIZT1<&rg9YjJ4J``>$U$4%z|5g9G~nDb@nU1FVVYFK z-w+ZNbDSY9{gGW` zY(8e51uT`4F!;FAWbls5CACgHc%Qtd~g24N~$*b zyqY@rc91NW?YB#Y2R`;XE;W7k&6~E<#6{oENkP<}t0 zZ<3nw>so)%!ez6`2Q`vnVq$9ZmEd=)t2bWK-8nO3Gdc7CVJ3J`d(dc5fpA+3x+Jv% zU{X~~m%wF%=T+8>CZ^xHvxP(=MSMJFZl(y_>sTx+e)p_&As4|7{}Su;T=!^88No~o zV9ts7%uXd;*?xO_=rAt|?$8^8wE;{zpUKH=Z>${--`s*@wQdD^o0(+Jj`=*hf;d$W z^t!)4@AjQLSsXL*$dsfDc?Q4-WCjOWp3<7A=C9-Iq&WKWyC(}389A(`GsJpua zb4CM=agm>`lBx067447HU3|xfD)CE?7&ft^iK;r6kkp2EHjN@4r@A`g^EBPa)jnt4 zkR}3zbjE&so0*8`tWX6xoe}F9yf7sM7`-a_7?pU~8ig|Qjyi+IbHZ={naq>uBEVUK zkpEy0aIayp3>FeO)omqH(#L@6?BU^Y=uad4Gf3!)i2zkxIdgS5{ZH?oZNg&XX2x^J x=yr!Heb~1aG@qI;T5sO