It all works, needs some cleanup

This commit is contained in:
JozsefA 2021-04-12 16:00:13 -07:00
parent 62eb16241b
commit db7913d91b
24 changed files with 611 additions and 219 deletions

View file

@ -2,7 +2,7 @@ package com.simibubi.create.content.contraptions.components.structureMovement.re
import org.lwjgl.opengl.GL20; import org.lwjgl.opengl.GL20;
import com.simibubi.create.foundation.render.backend.gl.BasicProgram; import com.simibubi.create.foundation.render.backend.core.BasicProgram;
import com.simibubi.create.foundation.render.backend.gl.shader.ProgramFogMode; import com.simibubi.create.foundation.render.backend.gl.shader.ProgramFogMode;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;

View file

@ -186,6 +186,8 @@ public class ClientEvents {
ms.pop(); ms.pop();
RenderWork.runAll(); RenderWork.runAll();
//Backend.effects.render();
} }
@SubscribeEvent @SubscribeEvent

View file

@ -46,9 +46,9 @@ public class RenderHooksMixin {
if (!Backend.available()) if (!Backend.available())
return; return;
Matrix4f viewProjection = stack.peek() Matrix4f view = stack.peek()
.getModel() .getModel();
.copy(); Matrix4f viewProjection = view.copy();
viewProjection.multiplyBackward(Backend.projectionMatrix); viewProjection.multiplyBackward(Backend.projectionMatrix);
FastRenderDispatcher.renderLayer(type, viewProjection, camX, camY, camZ); FastRenderDispatcher.renderLayer(type, viewProjection, camX, camY, camZ);
@ -56,6 +56,10 @@ public class RenderHooksMixin {
ContraptionRenderDispatcher.renderLayer(type, viewProjection, camX, camY, camZ); ContraptionRenderDispatcher.renderLayer(type, viewProjection, camX, camY, camZ);
GL20.glUseProgram(0); GL20.glUseProgram(0);
if (type == RenderType.getTranslucent()) {
Backend.effects.render(view);
}
} }
@Inject(at = @At(value = "INVOKE", target = "net.minecraft.client.renderer.WorldRenderer.updateChunks(J)V"), method = "render") @Inject(at = @At(value = "INVOKE", target = "net.minecraft.client.renderer.WorldRenderer.updateChunks(J)V"), method = "render")

View file

@ -1,19 +1,41 @@
package com.simibubi.create.foundation.mixin; package com.simibubi.create.foundation.mixin;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import com.mojang.blaze3d.matrix.MatrixStack; import com.mojang.blaze3d.matrix.MatrixStack;
import com.simibubi.create.foundation.render.backend.Backend; import com.simibubi.create.foundation.render.backend.Backend;
import com.simibubi.create.foundation.render.backend.effects.EffectsHandler;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.ActiveRenderInfo;
import net.minecraft.client.renderer.GameRenderer; import net.minecraft.client.renderer.GameRenderer;
import net.minecraft.util.math.vector.Matrix4f; import net.minecraft.util.math.vector.Matrix4f;
@Mixin(GameRenderer.class) @Mixin(GameRenderer.class)
public class StoreProjectionMatrixMixin { public abstract class StoreProjectionMatrixMixin {
@Shadow
private float cameraZoom;
@Shadow
private float zoomX;
@Shadow
private float zoomY;
@Shadow
public abstract double getFOVModifier(ActiveRenderInfo p_215311_1_, float p_215311_2_, boolean p_215311_3_);
@Shadow
@Final
private Minecraft mc;
@Shadow
private float farPlaneDistance;
@Unique @Unique
private boolean shouldCopy = false; private boolean shouldCopy = false;
@ -34,4 +56,19 @@ public class StoreProjectionMatrixMixin {
shouldCopy = false; shouldCopy = false;
} }
} }
@Inject(method = "getBasicProjectionMatrix",
at = @At("HEAD"),
cancellable = true)
private void overrideNearPlane(ActiveRenderInfo p_228382_1_, float p_228382_2_, boolean p_228382_3_, CallbackInfoReturnable<Matrix4f> cir) {
MatrixStack matrixstack = new MatrixStack();
matrixstack.peek().getModel().loadIdentity();
if (this.cameraZoom != 1.0F) {
matrixstack.translate((double) this.zoomX, (double) (-this.zoomY), 0.0D);
matrixstack.scale(this.cameraZoom, this.cameraZoom, 1.0F);
}
matrixstack.peek().getModel().multiply(Matrix4f.perspective(this.getFOVModifier(p_228382_1_, p_228382_2_, p_228382_3_), (float) this.mc.getWindow().getFramebufferWidth() / (float) this.mc.getWindow().getFramebufferHeight(), EffectsHandler.getNearPlane(), EffectsHandler.getFarPlane()));
cir.setReturnValue(matrixstack.peek().getModel());
}
} }

View file

@ -11,12 +11,15 @@ import com.simibubi.create.content.contraptions.components.structureMovement.ren
import com.simibubi.create.content.contraptions.relays.belt.BeltAttributes; import com.simibubi.create.content.contraptions.relays.belt.BeltAttributes;
import com.simibubi.create.content.logistics.block.FlapAttributes; import com.simibubi.create.content.logistics.block.FlapAttributes;
import com.simibubi.create.foundation.render.backend.core.BasicAttributes; import com.simibubi.create.foundation.render.backend.core.BasicAttributes;
import com.simibubi.create.foundation.render.backend.core.BasicProgram;
import com.simibubi.create.foundation.render.backend.core.ModelAttributes; import com.simibubi.create.foundation.render.backend.core.ModelAttributes;
import com.simibubi.create.foundation.render.backend.core.OrientedAttributes; import com.simibubi.create.foundation.render.backend.core.OrientedAttributes;
import com.simibubi.create.foundation.render.backend.core.TransformAttributes; import com.simibubi.create.foundation.render.backend.core.TransformAttributes;
import com.simibubi.create.foundation.render.backend.gl.BasicProgram; import com.simibubi.create.foundation.render.backend.effects.PostProcessingProgram;
import com.simibubi.create.foundation.render.backend.gl.shader.FogSensitiveProgram;
import com.simibubi.create.foundation.render.backend.gl.shader.ProgramSpec; import com.simibubi.create.foundation.render.backend.gl.shader.ProgramSpec;
import com.simibubi.create.foundation.render.backend.gl.shader.ShaderConstants; import com.simibubi.create.foundation.render.backend.gl.shader.ShaderConstants;
import com.simibubi.create.foundation.render.backend.gl.shader.SingleProgram;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
@ -25,7 +28,15 @@ public class AllProgramSpecs {
// noop, make sure the static field are loaded. // noop, make sure the static field are loaded.
} }
public static final ProgramSpec<BasicProgram> MODEL = register(ProgramSpec.builder("model", BasicProgram::new) public static final ProgramSpec<PostProcessingProgram> CHROMATIC = register(ProgramSpec.builder("chromatic", new SingleProgram.SpecLoader<>(PostProcessingProgram::new))
.addAttributes(ModelAttributes.class)
.addAttributes(BasicAttributes.class)
.addAttributes(TransformAttributes.class)
.setVert(Locations.SCREEN_QUAD)
.setFrag(Locations.CHROMATIC)
.createProgramSpec());
public static final ProgramSpec<BasicProgram> MODEL = register(ProgramSpec.builder("model", new FogSensitiveProgram.SpecLoader<>(BasicProgram::new))
.addAttributes(ModelAttributes.class) .addAttributes(ModelAttributes.class)
.addAttributes(BasicAttributes.class) .addAttributes(BasicAttributes.class)
.addAttributes(TransformAttributes.class) .addAttributes(TransformAttributes.class)
@ -33,7 +44,7 @@ public class AllProgramSpecs {
.setFrag(Locations.MODEL_FRAG) .setFrag(Locations.MODEL_FRAG)
.createProgramSpec()); .createProgramSpec());
public static final ProgramSpec<BasicProgram> ORIENTED = register(ProgramSpec.builder("oriented", BasicProgram::new) public static final ProgramSpec<BasicProgram> ORIENTED = register(ProgramSpec.builder("oriented", new FogSensitiveProgram.SpecLoader<>(BasicProgram::new))
.addAttributes(ModelAttributes.class) .addAttributes(ModelAttributes.class)
.addAttributes(BasicAttributes.class) .addAttributes(BasicAttributes.class)
.addAttributes(OrientedAttributes.class) .addAttributes(OrientedAttributes.class)
@ -41,7 +52,7 @@ public class AllProgramSpecs {
.setFrag(Locations.MODEL_FRAG) .setFrag(Locations.MODEL_FRAG)
.createProgramSpec()); .createProgramSpec());
public static final ProgramSpec<BasicProgram> ROTATING = register(ProgramSpec.builder("rotating", BasicProgram::new) public static final ProgramSpec<BasicProgram> ROTATING = register(ProgramSpec.builder("rotating", new FogSensitiveProgram.SpecLoader<>(BasicProgram::new))
.addAttributes(ModelAttributes.class) .addAttributes(ModelAttributes.class)
.addAttributes(BasicAttributes.class) .addAttributes(BasicAttributes.class)
.addAttributes(KineticAttributes.class) .addAttributes(KineticAttributes.class)
@ -50,7 +61,7 @@ public class AllProgramSpecs {
.setFrag(Locations.MODEL_FRAG) .setFrag(Locations.MODEL_FRAG)
.createProgramSpec()); .createProgramSpec());
public static final ProgramSpec<BasicProgram> BELT = register(ProgramSpec.builder("belt", BasicProgram::new) public static final ProgramSpec<BasicProgram> BELT = register(ProgramSpec.builder("belt", new FogSensitiveProgram.SpecLoader<>(BasicProgram::new))
.addAttributes(ModelAttributes.class) .addAttributes(ModelAttributes.class)
.addAttributes(BasicAttributes.class) .addAttributes(BasicAttributes.class)
.addAttributes(KineticAttributes.class) .addAttributes(KineticAttributes.class)
@ -59,18 +70,18 @@ public class AllProgramSpecs {
.setFrag(Locations.MODEL_FRAG) .setFrag(Locations.MODEL_FRAG)
.createProgramSpec()); .createProgramSpec());
public static final ProgramSpec<BasicProgram> FLAPS = register(ProgramSpec.builder("flap", BasicProgram::new) public static final ProgramSpec<BasicProgram> FLAPS = register(ProgramSpec.builder("flap", new FogSensitiveProgram.SpecLoader<>(BasicProgram::new))
.addAttributes(ModelAttributes.class) .addAttributes(ModelAttributes.class)
.addAttributes(FlapAttributes.class) .addAttributes(FlapAttributes.class)
.setVert(Locations.FLAP) .setVert(Locations.FLAP)
.setFrag(Locations.MODEL_FRAG) .setFrag(Locations.MODEL_FRAG)
.createProgramSpec()); .createProgramSpec());
public static final ProgramSpec<ContraptionProgram> C_STRUCTURE = register(ProgramSpec.builder("contraption_structure", ContraptionProgram::new) public static final ProgramSpec<ContraptionProgram> C_STRUCTURE = register(ProgramSpec.builder("contraption_structure", new FogSensitiveProgram.SpecLoader<>(ContraptionProgram::new))
.addAttributes(ContraptionAttributes.class) .addAttributes(ContraptionAttributes.class)
.setVert(Locations.CONTRAPTION_STRUCTURE) .setVert(Locations.CONTRAPTION_STRUCTURE)
.setFrag(Locations.CONTRAPTION) .setFrag(Locations.CONTRAPTION)
.createProgramSpec()); .createProgramSpec());
public static final ProgramSpec<ContraptionProgram> C_MODEL = register(ProgramSpec.builder("contraption_model", ContraptionProgram::new) public static final ProgramSpec<ContraptionProgram> C_MODEL = register(ProgramSpec.builder("contraption_model", new FogSensitiveProgram.SpecLoader<>(ContraptionProgram::new))
.addAttributes(ModelAttributes.class) .addAttributes(ModelAttributes.class)
.addAttributes(BasicAttributes.class) .addAttributes(BasicAttributes.class)
.addAttributes(TransformAttributes.class) .addAttributes(TransformAttributes.class)
@ -78,7 +89,7 @@ public class AllProgramSpecs {
.setFrag(Locations.CONTRAPTION) .setFrag(Locations.CONTRAPTION)
.setDefines(ShaderConstants.define("CONTRAPTION")) .setDefines(ShaderConstants.define("CONTRAPTION"))
.createProgramSpec()); .createProgramSpec());
public static final ProgramSpec<ContraptionProgram> C_ORIENTED = register(ProgramSpec.builder("contraption_oriented", ContraptionProgram::new) public static final ProgramSpec<ContraptionProgram> C_ORIENTED = register(ProgramSpec.builder("contraption_oriented", new FogSensitiveProgram.SpecLoader<>(ContraptionProgram::new))
.addAttributes(ModelAttributes.class) .addAttributes(ModelAttributes.class)
.addAttributes(BasicAttributes.class) .addAttributes(BasicAttributes.class)
.addAttributes(OrientedAttributes.class) .addAttributes(OrientedAttributes.class)
@ -86,7 +97,7 @@ public class AllProgramSpecs {
.setFrag(Locations.CONTRAPTION) .setFrag(Locations.CONTRAPTION)
.setDefines(ShaderConstants.define("CONTRAPTION")) .setDefines(ShaderConstants.define("CONTRAPTION"))
.createProgramSpec()); .createProgramSpec());
public static final ProgramSpec<ContraptionProgram> C_ROTATING = register(ProgramSpec.builder("contraption_rotating", ContraptionProgram::new) public static final ProgramSpec<ContraptionProgram> C_ROTATING = register(ProgramSpec.builder("contraption_rotating", new FogSensitiveProgram.SpecLoader<>(ContraptionProgram::new))
.addAttributes(ModelAttributes.class) .addAttributes(ModelAttributes.class)
.addAttributes(BasicAttributes.class) .addAttributes(BasicAttributes.class)
.addAttributes(KineticAttributes.class) .addAttributes(KineticAttributes.class)
@ -95,7 +106,7 @@ public class AllProgramSpecs {
.setFrag(Locations.CONTRAPTION) .setFrag(Locations.CONTRAPTION)
.setDefines(ShaderConstants.define("CONTRAPTION")) .setDefines(ShaderConstants.define("CONTRAPTION"))
.createProgramSpec()); .createProgramSpec());
public static final ProgramSpec<ContraptionProgram> C_BELT = register(ProgramSpec.builder("contraption_belt", ContraptionProgram::new) public static final ProgramSpec<ContraptionProgram> C_BELT = register(ProgramSpec.builder("contraption_belt", new FogSensitiveProgram.SpecLoader<>(ContraptionProgram::new))
.addAttributes(ModelAttributes.class) .addAttributes(ModelAttributes.class)
.addAttributes(BasicAttributes.class) .addAttributes(BasicAttributes.class)
.addAttributes(KineticAttributes.class) .addAttributes(KineticAttributes.class)
@ -104,14 +115,14 @@ public class AllProgramSpecs {
.setFrag(Locations.CONTRAPTION) .setFrag(Locations.CONTRAPTION)
.setDefines(ShaderConstants.define("CONTRAPTION")) .setDefines(ShaderConstants.define("CONTRAPTION"))
.createProgramSpec()); .createProgramSpec());
public static final ProgramSpec<ContraptionProgram> C_FLAPS = register(ProgramSpec.builder("contraption_flap", ContraptionProgram::new) public static final ProgramSpec<ContraptionProgram> C_FLAPS = register(ProgramSpec.builder("contraption_flap", new FogSensitiveProgram.SpecLoader<>(ContraptionProgram::new))
.addAttributes(ModelAttributes.class) .addAttributes(ModelAttributes.class)
.addAttributes(FlapAttributes.class) .addAttributes(FlapAttributes.class)
.setVert(Locations.FLAP) .setVert(Locations.FLAP)
.setFrag(Locations.CONTRAPTION) .setFrag(Locations.CONTRAPTION)
.setDefines(ShaderConstants.define("CONTRAPTION")) .setDefines(ShaderConstants.define("CONTRAPTION"))
.createProgramSpec()); .createProgramSpec());
public static final ProgramSpec<ContraptionProgram> C_ACTOR = register(ProgramSpec.builder("contraption_actor", ContraptionProgram::new) public static final ProgramSpec<ContraptionProgram> C_ACTOR = register(ProgramSpec.builder("contraption_actor", new FogSensitiveProgram.SpecLoader<>(ContraptionProgram::new))
.addAttributes(ModelAttributes.class) .addAttributes(ModelAttributes.class)
.addAttributes(ActorVertexAttributes.class) .addAttributes(ActorVertexAttributes.class)
.setVert(Locations.CONTRAPTION_ACTOR) .setVert(Locations.CONTRAPTION_ACTOR)
@ -120,6 +131,8 @@ public class AllProgramSpecs {
public static class Locations { public static class Locations {
public static final ResourceLocation SCREEN_QUAD = loc("screen_quad.vert");
public static final ResourceLocation CHROMATIC = loc("chromatic.frag");
public static final ResourceLocation MODEL_FRAG = loc("model.frag"); public static final ResourceLocation MODEL_FRAG = loc("model.frag");
public static final ResourceLocation MODEL_VERT = loc("model.vert"); public static final ResourceLocation MODEL_VERT = loc("model.vert");
public static final ResourceLocation ORIENTED = loc("oriented.vert"); public static final ResourceLocation ORIENTED = loc("oriented.vert");

View file

@ -7,9 +7,9 @@ import com.simibubi.create.content.contraptions.base.RotatingModel;
import com.simibubi.create.content.contraptions.relays.belt.BeltInstancedModel; import com.simibubi.create.content.contraptions.relays.belt.BeltInstancedModel;
import com.simibubi.create.content.logistics.block.FlapModel; import com.simibubi.create.content.logistics.block.FlapModel;
import com.simibubi.create.foundation.render.backend.MaterialTypes; import com.simibubi.create.foundation.render.backend.MaterialTypes;
import com.simibubi.create.foundation.render.backend.core.BasicProgram;
import com.simibubi.create.foundation.render.backend.core.OrientedModel; import com.simibubi.create.foundation.render.backend.core.OrientedModel;
import com.simibubi.create.foundation.render.backend.core.TransformedModel; import com.simibubi.create.foundation.render.backend.core.TransformedModel;
import com.simibubi.create.foundation.render.backend.gl.BasicProgram;
import com.simibubi.create.foundation.render.backend.gl.shader.ShaderCallback; import com.simibubi.create.foundation.render.backend.gl.shader.ShaderCallback;
import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer; import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer;
import com.simibubi.create.foundation.render.backend.instancing.RenderMaterial; import com.simibubi.create.foundation.render.backend.instancing.RenderMaterial;

View file

@ -9,7 +9,7 @@ import org.lwjgl.opengl.GL;
import org.lwjgl.opengl.GLCapabilities; import org.lwjgl.opengl.GLCapabilities;
import com.simibubi.create.foundation.config.AllConfigs; import com.simibubi.create.foundation.config.AllConfigs;
import com.simibubi.create.foundation.render.backend.gl.GlFog; import com.simibubi.create.foundation.render.backend.effects.EffectsHandler;
import com.simibubi.create.foundation.render.backend.gl.shader.GlProgram; import com.simibubi.create.foundation.render.backend.gl.shader.GlProgram;
import com.simibubi.create.foundation.render.backend.gl.shader.IMultiProgram; import com.simibubi.create.foundation.render.backend.gl.shader.IMultiProgram;
import com.simibubi.create.foundation.render.backend.gl.shader.ProgramSpec; import com.simibubi.create.foundation.render.backend.gl.shader.ProgramSpec;
@ -28,6 +28,7 @@ public class Backend {
public static final Logger log = LogManager.getLogger(Backend.class); public static final Logger log = LogManager.getLogger(Backend.class);
public static final ShaderLoader shaderLoader = new ShaderLoader(); public static final ShaderLoader shaderLoader = new ShaderLoader();
public static EffectsHandler effects;
public static Matrix4f projectionMatrix = new Matrix4f(); public static Matrix4f projectionMatrix = new Matrix4f();
@ -108,5 +109,10 @@ public class Backend {
compat.instancedArraysSupported(); compat.instancedArraysSupported();
enabled = AllConfigs.CLIENT.experimentalRendering.get() && !OptifineHandler.usingShaders(); enabled = AllConfigs.CLIENT.experimentalRendering.get() && !OptifineHandler.usingShaders();
if (enabled) {
if (effects != null) effects.delete();
effects = new EffectsHandler();
}
} }
} }

View file

@ -2,24 +2,17 @@ package com.simibubi.create.foundation.render.backend;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.simibubi.create.CreateClient; import com.simibubi.create.CreateClient;
import com.simibubi.create.content.contraptions.KineticDebugger; import com.simibubi.create.content.contraptions.KineticDebugger;
import com.simibubi.create.foundation.render.KineticRenderer; import com.simibubi.create.foundation.render.KineticRenderer;
import com.simibubi.create.foundation.utility.AnimationTickHolder;
import com.simibubi.create.foundation.utility.WorldAttached; import com.simibubi.create.foundation.utility.WorldAttached;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.player.ClientPlayerEntity;
import net.minecraft.client.renderer.GameRenderer;
import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.world.ClientWorld; import net.minecraft.client.world.ClientWorld;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.potion.Effects;
import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.vector.Matrix4f; import net.minecraft.util.math.vector.Matrix4f;
import net.minecraft.util.math.vector.Vector3f;
import net.minecraft.world.World; import net.minecraft.world.World;
public class FastRenderDispatcher { public class FastRenderDispatcher {

View file

@ -12,7 +12,6 @@ import java.nio.channels.FileChannel;
import java.nio.channels.ReadableByteChannel; import java.nio.channels.ReadableByteChannel;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.EnumMap;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Map; import java.util.Map;
@ -27,11 +26,9 @@ import org.lwjgl.system.MemoryUtil;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.systems.RenderSystem;
import com.simibubi.create.foundation.render.backend.gl.GlFogMode; import com.simibubi.create.foundation.render.backend.gl.attrib.IVertexAttrib;
import com.simibubi.create.foundation.render.backend.gl.shader.SingleProgram;
import com.simibubi.create.foundation.render.backend.gl.shader.GlProgram; import com.simibubi.create.foundation.render.backend.gl.shader.GlProgram;
import com.simibubi.create.foundation.render.backend.gl.shader.GlShader; import com.simibubi.create.foundation.render.backend.gl.shader.GlShader;
import com.simibubi.create.foundation.render.backend.gl.shader.FogSensitiveProgram;
import com.simibubi.create.foundation.render.backend.gl.shader.IMultiProgram; import com.simibubi.create.foundation.render.backend.gl.shader.IMultiProgram;
import com.simibubi.create.foundation.render.backend.gl.shader.ProgramSpec; import com.simibubi.create.foundation.render.backend.gl.shader.ProgramSpec;
import com.simibubi.create.foundation.render.backend.gl.shader.ShaderConstants; import com.simibubi.create.foundation.render.backend.gl.shader.ShaderConstants;
@ -96,43 +93,34 @@ public class ShaderLoader {
private <P extends GlProgram, S extends ProgramSpec<P>> void loadProgramFromSpec(S programSpec) { private <P extends GlProgram, S extends ProgramSpec<P>> void loadProgramFromSpec(S programSpec) {
if (programSpec.fogSensitive) { Backend.programs.put(programSpec, programSpec.finalizer.create(this, programSpec));
Map<GlFogMode, P> programGroup = new EnumMap<>(GlFogMode.class);
for (GlFogMode fogMode : GlFogMode.values()) {
programGroup.put(fogMode, loadProgram(programSpec, fogMode));
}
Backend.programs.put(programSpec, new FogSensitiveProgram<>(programGroup));
} else {
P program = loadProgram(programSpec, GlFogMode.NONE);
Backend.programs.put(programSpec, new SingleProgram<>(program));
}
Backend.log.debug("Loaded program {}", programSpec.name); Backend.log.debug("Loaded program {}", programSpec.name);
} }
private <P extends GlProgram, S extends ProgramSpec<P>> P loadProgram(S programSpec, GlFogMode fogMode) { public GlProgram.Builder loadProgram(ProgramSpec<?> programSpec) {
GlShader vert = null; return loadProgram(programSpec, programSpec.defines);
GlShader frag = null; }
public GlProgram.Builder loadProgram(ProgramSpec<?> programSpec, ShaderConstants defines) {
return loadProgram(programSpec.name, programSpec.vert, programSpec.frag, programSpec.attributes, defines);
}
public GlProgram.Builder loadProgram(ResourceLocation name, ResourceLocation vert, ResourceLocation frag, Collection<IVertexAttrib> attribs, ShaderConstants defines) {
GlShader vsh = null;
GlShader fsh = null;
try { try {
ShaderConstants defines = new ShaderConstants(programSpec.defines); vsh = loadShader(vert, ShaderType.VERTEX, defines);
fsh = loadShader(frag, ShaderType.FRAGMENT, defines);
defines.defineAll(fogMode.getDefines());
vert = loadShader(programSpec.getVert(), ShaderType.VERTEX, defines);
frag = loadShader(programSpec.getFrag(), ShaderType.FRAGMENT, defines);
GlProgram.Builder builder = GlProgram.builder(programSpec.name, fogMode).attachShader(vert).attachShader(frag);
programSpec.attributes.forEach(builder::addAttribute);
return builder.build(programSpec.factory);
return GlProgram.builder(name)
.attachShader(vsh)
.attachShader(fsh)
.addAttributes(attribs)
.link();
} finally { } finally {
if (vert != null) vert.delete(); if (vsh != null) vsh.delete();
if (frag != null) frag.delete(); if (fsh != null) fsh.delete();
} }
} }
@ -166,7 +154,7 @@ public class ShaderLoader {
}); });
} }
private GlShader loadShader(ResourceLocation name, ShaderType type, ShaderConstants defines) { public GlShader loadShader(ResourceLocation name, ShaderType type, ShaderConstants defines) {
String source = shaderSource.get(name); String source = shaderSource.get(name);
source = processIncludes(name, source); source = processIncludes(name, source);

View file

@ -1,8 +1,7 @@
package com.simibubi.create.foundation.render.backend.gl; package com.simibubi.create.foundation.render.backend.core;
import org.lwjgl.opengl.GL20; import org.lwjgl.opengl.GL20;
import com.simibubi.create.foundation.render.backend.RenderUtil;
import com.simibubi.create.foundation.render.backend.gl.shader.GlProgram; import com.simibubi.create.foundation.render.backend.gl.shader.GlProgram;
import com.simibubi.create.foundation.render.backend.gl.shader.ProgramFogMode; import com.simibubi.create.foundation.render.backend.gl.shader.ProgramFogMode;
import com.simibubi.create.foundation.utility.AnimationTickHolder; import com.simibubi.create.foundation.utility.AnimationTickHolder;
@ -51,8 +50,4 @@ public class BasicProgram extends GlProgram {
fogMode.bind(); fogMode.bind();
} }
protected static void uploadMatrixUniform(int uniform, Matrix4f mat) {
GL20.glUniformMatrix4fv(uniform, false, RenderUtil.writeMatrix(mat));
}
} }

View file

@ -1,24 +1,72 @@
package com.simibubi.create.foundation.render.backend.effects; package com.simibubi.create.foundation.render.backend.effects;
import org.lwjgl.opengl.GL15;
import org.lwjgl.opengl.GL20;
import org.lwjgl.opengl.GL30;
import com.simibubi.create.foundation.render.AllProgramSpecs;
import com.simibubi.create.foundation.render.backend.Backend;
import com.simibubi.create.foundation.render.backend.gl.GlBuffer;
import com.simibubi.create.foundation.render.backend.gl.GlPrimitiveType;
import com.simibubi.create.foundation.render.backend.gl.GlVertexArray;
import com.simibubi.create.foundation.utility.AnimationTickHolder;
import net.minecraft.client.MainWindow; import net.minecraft.client.MainWindow;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.GameRenderer;
import net.minecraft.client.shader.Framebuffer; import net.minecraft.client.shader.Framebuffer;
import net.minecraft.client.shader.FramebufferConstants;
import net.minecraft.util.math.vector.Matrix4f;
import net.minecraft.util.math.vector.Vector3d;
public class EffectsHandler { public class EffectsHandler {
final Minecraft mc; public static float getNearPlane() {
return 0.05f;
}
public static float getFarPlane() {
return Minecraft.getInstance().gameRenderer.getFarPlaneDistance();
}
public static final float[] vertices = {
// pos // tex
-1.0f, -1.0f, 0.0f, 0.0f,
1.0f, 1.0f, 1.0f, 1.0f,
-1.0f, 1.0f, 0.0f, 1.0f,
-1.0f, -1.0f, 0.0f, 0.0f,
1.0f, -1.0f, 1.0f, 0.0f,
1.0f, 1.0f, 1.0f, 1.0f
};
private static final int bufferSize = vertices.length * 4;
private final Framebuffer framebuffer; private final Framebuffer framebuffer;
private final GlVertexArray vao = new GlVertexArray();
public EffectsHandler(Minecraft minecraft) { private final GlBuffer vbo = new GlBuffer(GL20.GL_ARRAY_BUFFER);
this.mc = minecraft;
Framebuffer render = minecraft.getFramebuffer(); public EffectsHandler() {
Framebuffer render = Minecraft.getInstance().getFramebuffer();
framebuffer = new Framebuffer(render.framebufferWidth, render.framebufferHeight, false, Minecraft.IS_RUNNING_ON_MAC); framebuffer = new Framebuffer(render.framebufferWidth, render.framebufferHeight, false, Minecraft.IS_RUNNING_ON_MAC);
vbo.bind();
vbo.alloc(bufferSize, GL15.GL_STATIC_DRAW);
vbo.map(bufferSize, buf -> buf.asFloatBuffer().put(vertices));
vao.bind();
GL20.glEnableVertexAttribArray(0);
GL20.glVertexAttribPointer(0, 4, GlPrimitiveType.FLOAT.getGlConstant(), false, 4 * 4, 0);
vao.unbind();
vbo.unbind();
} }
public void prepFramebufferSize() { public void prepFramebufferSize() {
MainWindow window = mc.getWindow(); MainWindow window = Minecraft.getInstance().getWindow();
if (framebuffer.framebufferWidth != window.getFramebufferWidth() if (framebuffer.framebufferWidth != window.getFramebufferWidth()
|| framebuffer.framebufferHeight != window.getFramebufferHeight()) { || framebuffer.framebufferHeight != window.getFramebufferHeight()) {
framebuffer.func_216491_a(window.getFramebufferWidth(), window.getFramebufferHeight(), framebuffer.func_216491_a(window.getFramebufferWidth(), window.getFramebufferHeight(),
@ -26,5 +74,68 @@ public class EffectsHandler {
} }
} }
public void render(Matrix4f view) {
GL20.glEnable(GL20.GL_DEPTH_TEST);
GL20.glDepthRange(getNearPlane(), getFarPlane());
// float[] floats = new float[2];
// GL20.glGetFloatv(GL20.GL_DEPTH_RANGE, floats);
prepFramebufferSize();
Framebuffer mainBuffer = Minecraft.getInstance().getFramebuffer();
GL30.glBindFramebuffer(FramebufferConstants.FRAME_BUFFER, framebuffer.framebufferObject);
PostProcessingProgram program = Backend.getProgram(AllProgramSpecs.CHROMATIC);
program.bind();
program.bindColorTexture(mainBuffer.getColorAttachment());
program.bindDepthTexture(mainBuffer.getDepthAttachment());
GameRenderer gameRenderer = Minecraft.getInstance().gameRenderer;
Matrix4f projection = gameRenderer.getBasicProjectionMatrix(gameRenderer.getActiveRenderInfo(), AnimationTickHolder.getPartialTicks(), true);
//Matrix4f projection = Backend.projectionMatrix.copy();
//projection.a23 = projection.a32 = 0;
projection.a33 = 1;
projection.invert();
program.bindInverseProjection(projection);
Matrix4f inverseView = view.copy();
inverseView.invert();
// Matrix4f inverseView = new Matrix4f();
// inverseView.loadIdentity();
program.bindInverseView(inverseView);
Vector3d pos = new Vector3d(286, 73, -149);
Vector3d cameraPos = gameRenderer.getActiveRenderInfo().getProjectedView();
Vector3d shaderPos = pos.subtract(cameraPos).scale(1 / getFarPlane());
program.setSphere(shaderPos, 20f / getFarPlane(), 0.01f);
program.setFarPlane(getFarPlane());
program.setNearPlane(getNearPlane());
vao.bind();
GL20.glDrawArrays(GL20.GL_TRIANGLES, 0, 6);
vao.unbind();
program.bindColorTexture(0);
program.bindDepthTexture(0);
program.unbind();
GL30.glBindFramebuffer(GL30.GL_READ_FRAMEBUFFER, framebuffer.framebufferObject);
GL30.glBindFramebuffer(GL30.GL_DRAW_FRAMEBUFFER, mainBuffer.framebufferObject);
GL30.glBlitFramebuffer(0, 0, mainBuffer.framebufferWidth, mainBuffer.framebufferHeight, 0, 0, mainBuffer.framebufferWidth, mainBuffer.framebufferHeight, GL30.GL_COLOR_BUFFER_BIT, GL20.GL_LINEAR);
GL30.glBindFramebuffer(FramebufferConstants.FRAME_BUFFER, mainBuffer.framebufferObject);
}
public void delete() {
framebuffer.deleteFramebuffer();
vao.delete();
vbo.delete();
}
} }

View file

@ -0,0 +1,76 @@
package com.simibubi.create.foundation.render.backend.effects;
import org.lwjgl.opengl.GL20;
import com.simibubi.create.foundation.render.backend.gl.shader.GlProgram;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.vector.Matrix4f;
import net.minecraft.util.math.vector.Vector3d;
public class PostProcessingProgram extends GlProgram {
final int uDepth;
final int uColor;
final int uInverseProjection;
final int uInverseView;
final int uNearPlane;
final int uFarPlane;
final int uSphereCenter;
final int uSphereRadius;
final int uSphereFeather;
public PostProcessingProgram(ResourceLocation name, int handle) {
super(name, handle);
uInverseProjection = getUniformLocation("uInverseProjection");
uInverseView = getUniformLocation("uInverseView");
uNearPlane = getUniformLocation("uNearPlane");
uFarPlane = getUniformLocation("uFarPlane");
uSphereCenter = getUniformLocation("uSphereCenter");
uSphereRadius = getUniformLocation("uSphereRadius");
uSphereFeather = getUniformLocation("uSphereFeather");
bind();
uDepth = setSamplerBinding("uDepth", 8);
uColor = setSamplerBinding("uColor", 9);
unbind();
}
public void setNearPlane(float nearPlane) {
GL20.glUniform1f(uNearPlane, nearPlane);
}
public void setFarPlane(float farPlane) {
GL20.glUniform1f(uFarPlane, farPlane);
}
public void setSphere(Vector3d center, float radius, float feather) {
GL20.glUniform3f(uSphereCenter, (float) center.x, (float) center.y, (float) center.z);
GL20.glUniform1f(uSphereRadius, radius);
GL20.glUniform1f(uSphereFeather, feather);
}
public void bindInverseProjection(Matrix4f mat) {
uploadMatrixUniform(uInverseProjection, mat);
}
public void bindInverseView(Matrix4f mat) {
uploadMatrixUniform(uInverseView, mat);
}
public void bindDepthTexture(int textureObject) {
GL20.glActiveTexture(GL20.GL_TEXTURE8);
GL20.glBindTexture(GL20.GL_TEXTURE_2D, textureObject);
}
public void bindColorTexture(int textureObject) {
GL20.glActiveTexture(GL20.GL_TEXTURE9);
GL20.glBindTexture(GL20.GL_TEXTURE_2D, textureObject);
}
}

View file

@ -0,0 +1,38 @@
package com.simibubi.create.foundation.render.backend.effects;
import com.simibubi.create.foundation.render.backend.gl.attrib.CommonAttributes;
import com.simibubi.create.foundation.render.backend.gl.attrib.IAttribSpec;
import com.simibubi.create.foundation.render.backend.gl.attrib.IVertexAttrib;
public enum ScreenQuadAttributes implements IVertexAttrib {
INSTANCE_POS("aVertex", CommonAttributes.VEC4),
;
private final String name;
private final IAttribSpec spec;
ScreenQuadAttributes(String name, IAttribSpec spec) {
this.name = name;
this.spec = spec;
}
@Override
public String attribName() {
return name;
}
@Override
public IAttribSpec attribSpec() {
return spec;
}
@Override
public int getDivisor() {
return 0;
}
@Override
public int getBufferIndex() {
return 0;
}
}

View file

@ -3,6 +3,7 @@ package com.simibubi.create.foundation.render.backend.gl;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.util.function.Consumer; import java.util.function.Consumer;
import org.lwjgl.opengl.GL15;
import org.lwjgl.opengl.GL20; import org.lwjgl.opengl.GL20;
import com.simibubi.create.foundation.render.backend.Backend; import com.simibubi.create.foundation.render.backend.Backend;
@ -18,25 +19,29 @@ public class GlBuffer extends GlObject {
public int getBufferType() { public int getBufferType() {
return bufferType; return bufferType;
} }
public void bind() { public void bind() {
GL20.glBindBuffer(bufferType, handle()); GL20.glBindBuffer(bufferType, handle());
} }
public void unbind() { public void unbind() {
GL20.glBindBuffer(bufferType, 0); GL20.glBindBuffer(bufferType, 0);
} }
public void with(Consumer<GlBuffer> action) { public void alloc(int size, int usage) {
bind(); GL15.glBufferData(bufferType, size, usage);
action.accept(this); }
unbind();
}
public void map(int length, Consumer<ByteBuffer> upload) { public void with(Consumer<GlBuffer> action) {
Backend.compat.mapBuffer(bufferType, 0, length, upload); bind();
} action.accept(this);
unbind();
}
public void map(int length, Consumer<ByteBuffer> upload) {
Backend.compat.mapBuffer(bufferType, 0, length, upload);
}
public void map(int offset, int length, Consumer<ByteBuffer> upload) { public void map(int offset, int length, Consumer<ByteBuffer> upload) {
Backend.compat.mapBuffer(bufferType, offset, length, upload); Backend.compat.mapBuffer(bufferType, offset, length, upload);

View file

@ -1,26 +1,61 @@
package com.simibubi.create.foundation.render.backend.gl.shader; package com.simibubi.create.foundation.render.backend.gl.shader;
import java.util.EnumMap;
import java.util.Map; import java.util.Map;
import com.simibubi.create.foundation.render.backend.ShaderLoader;
import com.simibubi.create.foundation.render.backend.gl.GlFog; import com.simibubi.create.foundation.render.backend.gl.GlFog;
import com.simibubi.create.foundation.render.backend.gl.GlFogMode; import com.simibubi.create.foundation.render.backend.gl.GlFogMode;
import net.minecraft.util.ResourceLocation;
public class FogSensitiveProgram<P extends GlProgram> implements IMultiProgram<P> { public class FogSensitiveProgram<P extends GlProgram> implements IMultiProgram<P> {
private final Map<GlFogMode, P> programs; private final Map<GlFogMode, P> programs;
public FogSensitiveProgram(Map<GlFogMode, P> programs) { public FogSensitiveProgram(Map<GlFogMode, P> programs) {
this.programs = programs; this.programs = programs;
} }
@Override @Override
public P get() { public P get() {
return programs.get(GlFog.getFogMode()); return programs.get(GlFog.getFogMode());
} }
@Override @Override
public void delete() { public void delete() {
programs.values().forEach(GlProgram::delete); programs.values().forEach(GlProgram::delete);
} }
public static class SpecLoader<P extends GlProgram> implements ShaderSpecLoader<P> {
private final FogProgramLoader<P> fogProgramLoader;
public SpecLoader(FogProgramLoader<P> fogProgramLoader) {
this.fogProgramLoader = fogProgramLoader;
}
@Override
public IMultiProgram<P> create(ShaderLoader loader, ProgramSpec<P> spec) {
Map<GlFogMode, P> programs = new EnumMap<>(GlFogMode.class);
for (GlFogMode fogMode : GlFogMode.values()) {
ShaderConstants defines = new ShaderConstants(spec.defines);
defines.defineAll(fogMode.getDefines());
GlProgram.Builder builder = loader.loadProgram(spec, defines);
programs.put(fogMode, fogProgramLoader.create(builder.name, builder.program, fogMode.getFogFactory()));
}
return new FogSensitiveProgram<>(programs);
}
}
public interface FogProgramLoader<P extends GlProgram> {
P create(ResourceLocation name, int handle, ProgramFogMode.Factory fogFactory);
}
} }

View file

@ -1,34 +1,37 @@
package com.simibubi.create.foundation.render.backend.gl.shader; package com.simibubi.create.foundation.render.backend.gl.shader;
import java.util.Collection;
import org.lwjgl.opengl.GL20; import org.lwjgl.opengl.GL20;
import com.simibubi.create.foundation.render.backend.Backend; import com.simibubi.create.foundation.render.backend.Backend;
import com.simibubi.create.foundation.render.backend.gl.GlFogMode; import com.simibubi.create.foundation.render.backend.RenderUtil;
import com.simibubi.create.foundation.render.backend.gl.GlObject; import com.simibubi.create.foundation.render.backend.gl.GlObject;
import com.simibubi.create.foundation.render.backend.gl.attrib.IVertexAttrib; import com.simibubi.create.foundation.render.backend.gl.attrib.IVertexAttrib;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.vector.Matrix4f;
public abstract class GlProgram extends GlObject { public abstract class GlProgram extends GlObject {
public final ResourceLocation name; public final ResourceLocation name;
protected GlProgram(ResourceLocation name, int handle) { protected GlProgram(ResourceLocation name, int handle) {
setHandle(handle); setHandle(handle);
this.name = name; this.name = name;
} }
public static Builder builder(ResourceLocation name, GlFogMode fogMode) { public static Builder builder(ResourceLocation name) {
return new Builder(name, fogMode); return new Builder(name);
} }
public void bind() { public void bind() {
GL20.glUseProgram(handle()); GL20.glUseProgram(handle());
} }
public void unbind() { public void unbind() {
GL20.glUseProgram(0); GL20.glUseProgram(0);
} }
/** /**
* Retrieves the index of the uniform with the given name. * Retrieves the index of the uniform with the given name.
@ -52,76 +55,78 @@ public abstract class GlProgram extends GlObject {
* @return The sampler uniform's index. * @return The sampler uniform's index.
* @throws NullPointerException If no uniform exists with the given name. * @throws NullPointerException If no uniform exists with the given name.
*/ */
public int setSamplerBinding(String name, int binding) { public int setSamplerBinding(String name, int binding) {
int samplerUniform = getUniformLocation(name); int samplerUniform = getUniformLocation(name);
if (samplerUniform >= 0) { if (samplerUniform >= 0) {
GL20.glUniform1i(samplerUniform, binding); GL20.glUniform1i(samplerUniform, binding);
} }
return samplerUniform; return samplerUniform;
} }
@Override protected static void uploadMatrixUniform(int uniform, Matrix4f mat) {
protected void deleteInternal(int handle) { GL20.glUniformMatrix4fv(uniform, false, RenderUtil.writeMatrix(mat));
GL20.glDeleteProgram(handle); }
}
public static class Builder { @Override
private final ResourceLocation name; protected void deleteInternal(int handle) {
private final int program; GL20.glDeleteProgram(handle);
private final GlFogMode fogMode; }
private int attributeIndex; public static class Builder {
public final ResourceLocation name;
public final int program;
public Builder(ResourceLocation name, GlFogMode fogMode) { private int attributeIndex;
this.name = name;
this.program = GL20.glCreateProgram();
this.fogMode = fogMode;
}
public Builder attachShader(GlShader shader) { public Builder(ResourceLocation name) {
GL20.glAttachShader(this.program, shader.handle()); this.name = name;
this.program = GL20.glCreateProgram();
}
return this; public Builder attachShader(GlShader shader) {
} GL20.glAttachShader(this.program, shader.handle());
public <A extends IVertexAttrib> Builder addAttribute(A attrib) { return this;
GL20.glBindAttribLocation(this.program, attributeIndex, attrib.attribName()); }
attributeIndex += attrib.attribSpec().getAttributeCount();
return this;
}
/** public <A extends IVertexAttrib> Builder addAttributes(Collection<A> attributes) {
* Links the attached shaders to this program and returns a user-defined container which wraps the shader attributes.forEach(this::addAttribute);
* program. This container can, for example, provide methods for updating the specific uniforms of that shader return this;
* set. }
*
* @param factory The factory which will create the shader program's container
* @param <P> The type which should be instantiated with the new program's handle
* @return An instantiated shader container as provided by the factory
*/
public <P extends GlProgram> P build(ProgramFactory<P> factory) {
GL20.glLinkProgram(this.program);
String log = GL20.glGetProgramInfoLog(this.program); public <A extends IVertexAttrib> Builder addAttribute(A attrib) {
GL20.glBindAttribLocation(this.program, attributeIndex, attrib.attribName());
attributeIndex += attrib.attribSpec().getAttributeCount();
return this;
}
if (!log.isEmpty()) { /**
Backend.log.debug("Program link log for " + this.name + ": " + log); * Links the attached shaders to this program and returns a user-defined container which wraps the shader
} * program. This container can, for example, provide methods for updating the specific uniforms of that shader
* set.
*
* @param factory The factory which will create the shader program's container
* @param <P> The type which should be instantiated with the new program's handle
* @return An instantiated shader container as provided by the factory
*/
public Builder link() {
GL20.glLinkProgram(this.program);
int result = GL20.glGetProgrami(this.program, GL20.GL_LINK_STATUS); String log = GL20.glGetProgramInfoLog(this.program);
if (result != GL20.GL_TRUE) { if (!log.isEmpty()) {
throw new RuntimeException("Shader program linking failed, see log for details"); Backend.log.debug("Program link log for " + this.name + ": " + log);
} }
return factory.create(this.name, this.program, this.fogMode.getFogFactory()); int result = GL20.glGetProgrami(this.program, GL20.GL_LINK_STATUS);
}
}
@FunctionalInterface if (result != GL20.GL_TRUE) {
public interface ProgramFactory<P extends GlProgram> { throw new RuntimeException("Shader program linking failed, see log for details");
P create(ResourceLocation name, int handle, ProgramFogMode.Factory fogFactory); }
}
return this;
}
}
} }

View file

@ -16,54 +16,42 @@ public class ProgramSpec<P extends GlProgram> {
public final ShaderConstants defines; public final ShaderConstants defines;
public final GlProgram.ProgramFactory<P> factory;
public final ArrayList<IVertexAttrib> attributes; public final ArrayList<IVertexAttrib> attributes;
public final boolean fogSensitive; public final ShaderSpecLoader<P> finalizer;
public static <P extends GlProgram> Builder<P> builder(String name, GlProgram.ProgramFactory<P> factory) { public static <P extends GlProgram> Builder<P> builder(String name, ShaderSpecLoader<P> factory) {
return builder(new ResourceLocation(Create.ID, name), factory); return builder(new ResourceLocation(Create.ID, name), factory);
}
public static <P extends GlProgram> Builder<P> builder(ResourceLocation name, GlProgram.ProgramFactory<P> factory) {
return new Builder<>(name, factory);
}
public ProgramSpec(ResourceLocation name, ResourceLocation vert, ResourceLocation frag, GlProgram.ProgramFactory<P> factory, ShaderConstants defines, ArrayList<IVertexAttrib> attributes, boolean fogSensitive) {
this.name = name;
this.vert = vert;
this.frag = frag;
this.defines = defines;
this.factory = factory;
this.attributes = attributes;
this.fogSensitive = fogSensitive;
} }
public ResourceLocation getVert() { public static <P extends GlProgram> Builder<P> builder(ResourceLocation name, ShaderSpecLoader<P> factory) {
return vert; return new Builder<>(name, factory);
} }
public ResourceLocation getFrag() { public ProgramSpec(ResourceLocation name, ResourceLocation vert, ResourceLocation frag, ShaderConstants defines, ArrayList<IVertexAttrib> attributes, ShaderSpecLoader<P> finalizer) {
return frag; this.name = name;
} this.vert = vert;
this.frag = frag;
this.defines = defines;
this.attributes = attributes;
this.finalizer = finalizer;
}
public static class Builder<P extends GlProgram> { public static class Builder<P extends GlProgram> {
private ResourceLocation vert; private ResourceLocation vert;
private ResourceLocation frag; private ResourceLocation frag;
private ShaderConstants defines = ShaderConstants.EMPTY; private ShaderConstants defines = ShaderConstants.EMPTY;
private boolean fogSensitive = true; private final ShaderSpecLoader<P> loader;
private final ResourceLocation name; private final ResourceLocation name;
private final GlProgram.ProgramFactory<P> factory;
private final ArrayList<IVertexAttrib> attributes; private final ArrayList<IVertexAttrib> attributes;
public Builder(ResourceLocation name, GlProgram.ProgramFactory<P> factory) { public Builder(ResourceLocation name, ShaderSpecLoader<P> factory) {
this.name = name; this.name = name;
this.factory = factory; this.loader = factory;
attributes = new ArrayList<>(); attributes = new ArrayList<>();
} }
public Builder<P> setVert(ResourceLocation vert) { public Builder<P> setVert(ResourceLocation vert) {
this.vert = vert; this.vert = vert;
@ -80,18 +68,14 @@ public class ProgramSpec<P extends GlProgram> {
return this; return this;
} }
public Builder<P> setFogSensitive(boolean fogSensitive) {
this.fogSensitive = fogSensitive;
return this;
}
public <A extends Enum<A> & IVertexAttrib> Builder<P> addAttributes(Class<A> attributeEnum) { public <A extends Enum<A> & IVertexAttrib> Builder<P> addAttributes(Class<A> attributeEnum) {
attributes.addAll(Arrays.asList(attributeEnum.getEnumConstants())); attributes.addAll(Arrays.asList(attributeEnum.getEnumConstants()));
return this; return this;
} }
public ProgramSpec<P> createProgramSpec() { public ProgramSpec<P> createProgramSpec() {
return new ProgramSpec<>(name, vert, frag, factory, defines, attributes, fogSensitive); return new ProgramSpec<>(name, vert, frag, defines, attributes, loader);
} }
} }
} }

View file

@ -0,0 +1,7 @@
package com.simibubi.create.foundation.render.backend.gl.shader;
import com.simibubi.create.foundation.render.backend.ShaderLoader;
public interface ShaderSpecLoader<P extends GlProgram> {
IMultiProgram<P> create(ShaderLoader loader, ProgramSpec<P> spec);
}

View file

@ -1,5 +1,9 @@
package com.simibubi.create.foundation.render.backend.gl.shader; package com.simibubi.create.foundation.render.backend.gl.shader;
import com.simibubi.create.foundation.render.backend.ShaderLoader;
import net.minecraft.util.ResourceLocation;
public class SingleProgram<P extends GlProgram> implements IMultiProgram<P> { public class SingleProgram<P extends GlProgram> implements IMultiProgram<P> {
final P program; final P program;
@ -16,4 +20,24 @@ public class SingleProgram<P extends GlProgram> implements IMultiProgram<P> {
public void delete() { public void delete() {
program.delete(); program.delete();
} }
public static class SpecLoader<P extends GlProgram> implements ShaderSpecLoader<P> {
final ProgramFactory<P> factory;
public SpecLoader(ProgramFactory<P> factory) {
this.factory = factory;
}
@Override
public IMultiProgram<P> create(ShaderLoader loader, ProgramSpec<P> spec) {
GlProgram.Builder builder = loader.loadProgram(spec);
return new SingleProgram<>(factory.create(builder.name, builder.program));
}
}
@FunctionalInterface
public interface ProgramFactory<P extends GlProgram> {
P create(ResourceLocation name, int handle);
}
} }

View file

@ -182,7 +182,7 @@ public abstract class InstancedModel<D extends InstanceData> extends BufferedMod
int requiredSize = size * stride; int requiredSize = size * stride;
if (requiredSize > glBufferSize) { if (requiredSize > glBufferSize) {
glBufferSize = requiredSize + stride * 16; glBufferSize = requiredSize + stride * 16;
GL15.glBufferData(instanceVBO.getBufferType(), glBufferSize, GL15.GL_STATIC_DRAW); instanceVBO.alloc(glBufferSize, GL15.GL_STATIC_DRAW);
instanceVBO.map(glBufferSize, buffer -> { instanceVBO.map(glBufferSize, buffer -> {
for (D datum : data) { for (D datum : data) {

View file

@ -9,9 +9,9 @@ import javax.annotation.Nullable;
import com.simibubi.create.foundation.render.backend.Backend; import com.simibubi.create.foundation.render.backend.Backend;
import com.simibubi.create.foundation.render.backend.MaterialType; import com.simibubi.create.foundation.render.backend.MaterialType;
import com.simibubi.create.foundation.render.backend.MaterialTypes; import com.simibubi.create.foundation.render.backend.MaterialTypes;
import com.simibubi.create.foundation.render.backend.core.BasicProgram;
import com.simibubi.create.foundation.render.backend.core.ModelData; import com.simibubi.create.foundation.render.backend.core.ModelData;
import com.simibubi.create.foundation.render.backend.core.OrientedData; import com.simibubi.create.foundation.render.backend.core.OrientedData;
import com.simibubi.create.foundation.render.backend.gl.BasicProgram;
import com.simibubi.create.foundation.render.backend.gl.shader.ShaderCallback; import com.simibubi.create.foundation.render.backend.gl.shader.ShaderCallback;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;

View file

@ -19,7 +19,7 @@ import com.simibubi.create.foundation.render.Compartment;
import com.simibubi.create.foundation.render.SuperByteBufferCache; import com.simibubi.create.foundation.render.SuperByteBufferCache;
import com.simibubi.create.foundation.render.backend.Backend; import com.simibubi.create.foundation.render.backend.Backend;
import com.simibubi.create.foundation.render.backend.FastRenderDispatcher; import com.simibubi.create.foundation.render.backend.FastRenderDispatcher;
import com.simibubi.create.foundation.render.backend.gl.BasicProgram; import com.simibubi.create.foundation.render.backend.core.BasicProgram;
import com.simibubi.create.foundation.render.backend.gl.shader.ProgramSpec; import com.simibubi.create.foundation.render.backend.gl.shader.ProgramSpec;
import com.simibubi.create.foundation.render.backend.gl.shader.ShaderCallback; import com.simibubi.create.foundation.render.backend.gl.shader.ShaderCallback;

View file

@ -1,13 +1,62 @@
#version 120 #version 120
layout (std140) struct Sphere { varying vec4 Vertex;
vec4 positionRadius; varying vec3 CameraDir;
vec4 color;
} uSpheres; //layout (std140) struct Sphere {
// vec4 positionRadius;
// vec4 color;
//} uSphere;
uniform sampler2D uDepth; uniform sampler2D uDepth;
uniform sampler2D uColor; uniform sampler2D uColor;
uniform mat4 uInverseProjection;
uniform mat4 uInverseView;
uniform float uNearPlane = 0.15;
uniform float uFarPlane = 1;
uniform vec3 uSphereCenter = vec3(0, 0, 0);
uniform float uSphereRadius = 1;
uniform float uSphereFeather = 0.05;
float linearizeDepth(float d, float zNear, float zFar) {
float z_n = 2.0 * d - 1.0;
return 2.0 * zNear * zFar / (zFar + zNear - z_n * (zFar - zNear));
}
vec4 filterColor(vec4 frag) {
const vec3 lum = vec3(0.21, 0.71, 0.07);
float grey = dot(frag.rgb, lum.rgb);
return vec4(grey, grey, grey, frag.a);
}
vec3 getWorldPos(float depth) {
vec3 cameraPos = CameraDir * depth;
vec3 worldPos = (uInverseView * vec4(cameraPos, 1)).xyz;
return worldPos;
}
float getDepth() {
float depth = texture2D(uDepth, Vertex.zw).r;
depth = linearizeDepth(depth, uNearPlane, uFarPlane);
//depth = ( - uNearPlane) / (uFarPlane - uNearPlane);
depth = depth / uFarPlane;
return depth;
}
void main() { void main() {
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); float depth = getDepth();
vec3 worldPos = getWorldPos(depth);
float distance = distance(uSphereCenter, worldPos);
float strength = smoothstep(uSphereRadius - uSphereFeather, uSphereRadius + uSphereFeather, distance);
vec4 fragColor = texture2D(uColor, Vertex.zw);
gl_FragColor = mix(fragColor, filterColor(fragColor), strength);
//gl_FragColor = vec4(worldPos, 1);
} }

View file

@ -0,0 +1,20 @@
#version 120
attribute vec4 aVertex;// <vec2 position, vec2 texCoords>
varying vec4 Vertex;
varying vec3 CameraDir;
uniform mat4 uInverseProjection;
void main() {
gl_Position = vec4(aVertex.xy, 0.0f, 1.0f);
Vertex = aVertex;
vec4 clip = vec4(aVertex.xy, 0, 1);
clip *= uInverseProjection;
CameraDir = clip.xyz / clip.w;
//worldDirection = (uInverseProjection * vec4(aVertex.xy, 0, 1.)).xyz;
}