mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-11-14 22:11:50 +01:00
Better projector gui
This commit is contained in:
parent
fc919c4ac4
commit
3879d55517
14 changed files with 300 additions and 171 deletions
|
@ -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 [------------------------<-",
|
||||
|
|
|
@ -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<AdjustablePulseRepeaterTileEntity> 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<ChromaticProjectorTileEntity> TESTFX =
|
||||
Create.registrate()
|
||||
.tileEntity("chromatic_projector", ChromaticProjectorTileEntity::new)
|
||||
.validBlocks(AllBlocks.CHROMATIC_PROJECTOR)
|
||||
.register();
|
||||
public static final TileEntityEntry<ChromaticProjectorTileEntity> 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() {
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,7 +54,7 @@ public class ChromaticProjectorBlock extends Block implements ITE<ChromaticProje
|
|||
@Nullable
|
||||
@Override
|
||||
public TileEntity createTileEntity(BlockState state, IBlockReader world) {
|
||||
return AllTileEntities.TESTFX.create();
|
||||
return AllTileEntities.CHROMATIC_PROJECTOR.create();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
package com.simibubi.create.content.curiosities.projector;
|
||||
|
||||
import com.simibubi.create.foundation.render.backend.Backend;
|
||||
import com.simibubi.create.foundation.render.backend.instancing.IDynamicInstance;
|
||||
import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer;
|
||||
import com.simibubi.create.foundation.render.backend.instancing.TileEntityInstance;
|
||||
|
||||
public class ChromaticProjectorInstance extends TileEntityInstance<ChromaticProjectorTileEntity> 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() {
|
||||
|
||||
}
|
||||
}
|
|
@ -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<Vector<ScrollInput>> 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<ScrollInput> 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) {
|
||||
|
|
|
@ -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<FilterStep> 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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<Matrix4f> 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<ITextComponent> getOptions() {
|
||||
List<ITextComponent> options = new ArrayList<>();
|
||||
for (ColorEffects entry : values())
|
||||
|
|
|
@ -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<FilterStep> filters) {
|
||||
Iterator<FilterStep> 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<FilterStep> createDefault() {
|
||||
Vector<FilterStep> instructions = new Vector<>(ChromaticProjectorScreen.MAX_STEPS);
|
||||
instructions.add(new FilterStep(ColorEffects.SEPIA, 100));
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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<SphereFilterProgram.FilterSphere> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<FilterSphere> 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<FilterSphere> 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));
|
||||
|
|
|
@ -16,34 +16,11 @@ uniform vec3 uCameraPos;
|
|||
|
||||
struct SphereFilter {
|
||||
vec4 sphere;// <vec3 position, float radius>
|
||||
vec4 data;// <float feather, float fade, float density, float strength>
|
||||
vec4 d1;// <float feather, float fade, float density, float blend mode>
|
||||
vec4 d2;// <float surfaceStrength, float bubbleStrength>
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;// <vec2 position, vec2 texCoords>
|
||||
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 3 KiB After Width: | Height: | Size: 3 KiB |
Loading…
Reference in a new issue