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 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 net.minecraft.util.ResourceLocation;

View file

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

View file

@ -46,9 +46,9 @@ public class RenderHooksMixin {
if (!Backend.available())
return;
Matrix4f viewProjection = stack.peek()
.getModel()
.copy();
Matrix4f view = stack.peek()
.getModel();
Matrix4f viewProjection = view.copy();
viewProjection.multiplyBackward(Backend.projectionMatrix);
FastRenderDispatcher.renderLayer(type, viewProjection, camX, camY, camZ);
@ -56,6 +56,10 @@ public class RenderHooksMixin {
ContraptionRenderDispatcher.renderLayer(type, viewProjection, camX, camY, camZ);
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")

View file

@ -1,19 +1,41 @@
package com.simibubi.create.foundation.mixin;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import com.mojang.blaze3d.matrix.MatrixStack;
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.util.math.vector.Matrix4f;
@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
private boolean shouldCopy = false;
@ -34,4 +56,19 @@ public class StoreProjectionMatrixMixin {
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.logistics.block.FlapAttributes;
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.OrientedAttributes;
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.ShaderConstants;
import com.simibubi.create.foundation.render.backend.gl.shader.SingleProgram;
import net.minecraft.util.ResourceLocation;
@ -25,7 +28,15 @@ public class AllProgramSpecs {
// 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(BasicAttributes.class)
.addAttributes(TransformAttributes.class)
@ -33,7 +44,7 @@ public class AllProgramSpecs {
.setFrag(Locations.MODEL_FRAG)
.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(BasicAttributes.class)
.addAttributes(OrientedAttributes.class)
@ -41,7 +52,7 @@ public class AllProgramSpecs {
.setFrag(Locations.MODEL_FRAG)
.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(BasicAttributes.class)
.addAttributes(KineticAttributes.class)
@ -50,7 +61,7 @@ public class AllProgramSpecs {
.setFrag(Locations.MODEL_FRAG)
.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(BasicAttributes.class)
.addAttributes(KineticAttributes.class)
@ -59,18 +70,18 @@ public class AllProgramSpecs {
.setFrag(Locations.MODEL_FRAG)
.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(FlapAttributes.class)
.setVert(Locations.FLAP)
.setFrag(Locations.MODEL_FRAG)
.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)
.setVert(Locations.CONTRAPTION_STRUCTURE)
.setFrag(Locations.CONTRAPTION)
.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(BasicAttributes.class)
.addAttributes(TransformAttributes.class)
@ -78,7 +89,7 @@ public class AllProgramSpecs {
.setFrag(Locations.CONTRAPTION)
.setDefines(ShaderConstants.define("CONTRAPTION"))
.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(BasicAttributes.class)
.addAttributes(OrientedAttributes.class)
@ -86,7 +97,7 @@ public class AllProgramSpecs {
.setFrag(Locations.CONTRAPTION)
.setDefines(ShaderConstants.define("CONTRAPTION"))
.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(BasicAttributes.class)
.addAttributes(KineticAttributes.class)
@ -95,7 +106,7 @@ public class AllProgramSpecs {
.setFrag(Locations.CONTRAPTION)
.setDefines(ShaderConstants.define("CONTRAPTION"))
.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(BasicAttributes.class)
.addAttributes(KineticAttributes.class)
@ -104,14 +115,14 @@ public class AllProgramSpecs {
.setFrag(Locations.CONTRAPTION)
.setDefines(ShaderConstants.define("CONTRAPTION"))
.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(FlapAttributes.class)
.setVert(Locations.FLAP)
.setFrag(Locations.CONTRAPTION)
.setDefines(ShaderConstants.define("CONTRAPTION"))
.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(ActorVertexAttributes.class)
.setVert(Locations.CONTRAPTION_ACTOR)
@ -120,6 +131,8 @@ public class AllProgramSpecs {
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_VERT = loc("model.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.logistics.block.FlapModel;
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.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.instancing.InstancedTileRenderer;
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 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.IMultiProgram;
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 ShaderLoader shaderLoader = new ShaderLoader();
public static EffectsHandler effects;
public static Matrix4f projectionMatrix = new Matrix4f();
@ -108,5 +109,10 @@ public class Backend {
compat.instancedArraysSupported();
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 com.mojang.blaze3d.matrix.MatrixStack;
import com.simibubi.create.CreateClient;
import com.simibubi.create.content.contraptions.KineticDebugger;
import com.simibubi.create.foundation.render.KineticRenderer;
import com.simibubi.create.foundation.utility.AnimationTickHolder;
import com.simibubi.create.foundation.utility.WorldAttached;
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.world.ClientWorld;
import net.minecraft.entity.Entity;
import net.minecraft.potion.Effects;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.vector.Matrix4f;
import net.minecraft.util.math.vector.Vector3f;
import net.minecraft.world.World;
public class FastRenderDispatcher {

View file

@ -12,7 +12,6 @@ import java.nio.channels.FileChannel;
import java.nio.channels.ReadableByteChannel;
import java.util.ArrayList;
import java.util.Collection;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
@ -27,11 +26,9 @@ import org.lwjgl.system.MemoryUtil;
import com.google.common.collect.Lists;
import com.mojang.blaze3d.systems.RenderSystem;
import com.simibubi.create.foundation.render.backend.gl.GlFogMode;
import com.simibubi.create.foundation.render.backend.gl.shader.SingleProgram;
import com.simibubi.create.foundation.render.backend.gl.attrib.IVertexAttrib;
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.FogSensitiveProgram;
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.ShaderConstants;
@ -96,43 +93,34 @@ public class ShaderLoader {
private <P extends GlProgram, S extends ProgramSpec<P>> void loadProgramFromSpec(S programSpec) {
if (programSpec.fogSensitive) {
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.programs.put(programSpec, programSpec.finalizer.create(this, programSpec));
Backend.log.debug("Loaded program {}", programSpec.name);
}
private <P extends GlProgram, S extends ProgramSpec<P>> P loadProgram(S programSpec, GlFogMode fogMode) {
GlShader vert = null;
GlShader frag = null;
public GlProgram.Builder loadProgram(ProgramSpec<?> programSpec) {
return loadProgram(programSpec, programSpec.defines);
}
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 {
ShaderConstants defines = new ShaderConstants(programSpec.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);
vsh = loadShader(vert, ShaderType.VERTEX, defines);
fsh = loadShader(frag, ShaderType.FRAGMENT, defines);
return GlProgram.builder(name)
.attachShader(vsh)
.attachShader(fsh)
.addAttributes(attribs)
.link();
} finally {
if (vert != null) vert.delete();
if (frag != null) frag.delete();
if (vsh != null) vsh.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);
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 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.ProgramFogMode;
import com.simibubi.create.foundation.utility.AnimationTickHolder;
@ -51,8 +50,4 @@ public class BasicProgram extends GlProgram {
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;
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.Minecraft;
import net.minecraft.client.renderer.GameRenderer;
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 {
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 GlVertexArray vao = new GlVertexArray();
public EffectsHandler(Minecraft minecraft) {
this.mc = minecraft;
private final GlBuffer vbo = new GlBuffer(GL20.GL_ARRAY_BUFFER);
Framebuffer render = minecraft.getFramebuffer();
public EffectsHandler() {
Framebuffer render = Minecraft.getInstance().getFramebuffer();
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() {
MainWindow window = mc.getWindow();
MainWindow window = Minecraft.getInstance().getWindow();
if (framebuffer.framebufferWidth != window.getFramebufferWidth()
|| framebuffer.framebufferHeight != 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.util.function.Consumer;
import org.lwjgl.opengl.GL15;
import org.lwjgl.opengl.GL20;
import com.simibubi.create.foundation.render.backend.Backend;
@ -18,25 +19,29 @@ public class GlBuffer extends GlObject {
public int getBufferType() {
return bufferType;
}
}
public void bind() {
GL20.glBindBuffer(bufferType, handle());
}
public void bind() {
GL20.glBindBuffer(bufferType, handle());
}
public void unbind() {
GL20.glBindBuffer(bufferType, 0);
}
public void unbind() {
GL20.glBindBuffer(bufferType, 0);
}
public void with(Consumer<GlBuffer> action) {
bind();
action.accept(this);
unbind();
}
public void alloc(int size, int usage) {
GL15.glBufferData(bufferType, size, usage);
}
public void map(int length, Consumer<ByteBuffer> upload) {
Backend.compat.mapBuffer(bufferType, 0, length, upload);
}
public void with(Consumer<GlBuffer> action) {
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) {
Backend.compat.mapBuffer(bufferType, offset, length, upload);

View file

@ -1,26 +1,61 @@
package com.simibubi.create.foundation.render.backend.gl.shader;
import java.util.EnumMap;
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.GlFogMode;
import net.minecraft.util.ResourceLocation;
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) {
this.programs = programs;
}
public FogSensitiveProgram(Map<GlFogMode, P> programs) {
this.programs = programs;
}
@Override
public P get() {
return programs.get(GlFog.getFogMode());
}
@Override
public P get() {
return programs.get(GlFog.getFogMode());
}
@Override
public void delete() {
programs.values().forEach(GlProgram::delete);
}
@Override
public void 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;
import java.util.Collection;
import org.lwjgl.opengl.GL20;
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.attrib.IVertexAttrib;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.vector.Matrix4f;
public abstract class GlProgram extends GlObject {
public final ResourceLocation name;
public final ResourceLocation name;
protected GlProgram(ResourceLocation name, int handle) {
setHandle(handle);
this.name = name;
}
protected GlProgram(ResourceLocation name, int handle) {
setHandle(handle);
this.name = name;
}
public static Builder builder(ResourceLocation name, GlFogMode fogMode) {
return new Builder(name, fogMode);
}
public static Builder builder(ResourceLocation name) {
return new Builder(name);
}
public void bind() {
GL20.glUseProgram(handle());
}
public void bind() {
GL20.glUseProgram(handle());
}
public void unbind() {
GL20.glUseProgram(0);
}
public void unbind() {
GL20.glUseProgram(0);
}
/**
* 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.
* @throws NullPointerException If no uniform exists with the given name.
*/
public int setSamplerBinding(String name, int binding) {
int samplerUniform = getUniformLocation(name);
public int setSamplerBinding(String name, int binding) {
int samplerUniform = getUniformLocation(name);
if (samplerUniform >= 0) {
GL20.glUniform1i(samplerUniform, binding);
}
if (samplerUniform >= 0) {
GL20.glUniform1i(samplerUniform, binding);
}
return samplerUniform;
}
return samplerUniform;
}
@Override
protected void deleteInternal(int handle) {
GL20.glDeleteProgram(handle);
}
protected static void uploadMatrixUniform(int uniform, Matrix4f mat) {
GL20.glUniformMatrix4fv(uniform, false, RenderUtil.writeMatrix(mat));
}
public static class Builder {
private final ResourceLocation name;
private final int program;
private final GlFogMode fogMode;
@Override
protected void deleteInternal(int handle) {
GL20.glDeleteProgram(handle);
}
private int attributeIndex;
public static class Builder {
public final ResourceLocation name;
public final int program;
public Builder(ResourceLocation name, GlFogMode fogMode) {
this.name = name;
this.program = GL20.glCreateProgram();
this.fogMode = fogMode;
}
private int attributeIndex;
public Builder attachShader(GlShader shader) {
GL20.glAttachShader(this.program, shader.handle());
public Builder(ResourceLocation name) {
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) {
GL20.glBindAttribLocation(this.program, attributeIndex, attrib.attribName());
attributeIndex += attrib.attribSpec().getAttributeCount();
return this;
}
return this;
}
/**
* 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 <P extends GlProgram> P build(ProgramFactory<P> factory) {
GL20.glLinkProgram(this.program);
public <A extends IVertexAttrib> Builder addAttributes(Collection<A> attributes) {
attributes.forEach(this::addAttribute);
return this;
}
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) {
throw new RuntimeException("Shader program linking failed, see log for details");
}
if (!log.isEmpty()) {
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
public interface ProgramFactory<P extends GlProgram> {
P create(ResourceLocation name, int handle, ProgramFogMode.Factory fogFactory);
}
if (result != GL20.GL_TRUE) {
throw new RuntimeException("Shader program linking failed, see log for details");
}
return this;
}
}
}

View file

@ -16,54 +16,42 @@ public class ProgramSpec<P extends GlProgram> {
public final ShaderConstants defines;
public final GlProgram.ProgramFactory<P> factory;
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) {
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 static <P extends GlProgram> Builder<P> builder(String name, ShaderSpecLoader<P> factory) {
return builder(new ResourceLocation(Create.ID, name), factory);
}
public ResourceLocation getVert() {
return vert;
}
public static <P extends GlProgram> Builder<P> builder(ResourceLocation name, ShaderSpecLoader<P> factory) {
return new Builder<>(name, factory);
}
public ResourceLocation getFrag() {
return frag;
}
public ProgramSpec(ResourceLocation name, ResourceLocation vert, ResourceLocation frag, ShaderConstants defines, ArrayList<IVertexAttrib> attributes, ShaderSpecLoader<P> finalizer) {
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> {
private ResourceLocation vert;
private ResourceLocation frag;
private ShaderConstants defines = ShaderConstants.EMPTY;
private boolean fogSensitive = true;
private ShaderConstants defines = ShaderConstants.EMPTY;
private final ShaderSpecLoader<P> loader;
private final ResourceLocation name;
private final GlProgram.ProgramFactory<P> factory;
private final ArrayList<IVertexAttrib> attributes;
public Builder(ResourceLocation name, GlProgram.ProgramFactory<P> factory) {
this.name = name;
this.factory = factory;
attributes = new ArrayList<>();
}
public Builder(ResourceLocation name, ShaderSpecLoader<P> factory) {
this.name = name;
this.loader = factory;
attributes = new ArrayList<>();
}
public Builder<P> setVert(ResourceLocation vert) {
this.vert = vert;
@ -80,18 +68,14 @@ public class ProgramSpec<P extends GlProgram> {
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) {
attributes.addAll(Arrays.asList(attributeEnum.getEnumConstants()));
return this;
}
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;
import com.simibubi.create.foundation.render.backend.ShaderLoader;
import net.minecraft.util.ResourceLocation;
public class SingleProgram<P extends GlProgram> implements IMultiProgram<P> {
final P program;
@ -16,4 +20,24 @@ public class SingleProgram<P extends GlProgram> implements IMultiProgram<P> {
public void 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;
if (requiredSize > glBufferSize) {
glBufferSize = requiredSize + stride * 16;
GL15.glBufferData(instanceVBO.getBufferType(), glBufferSize, GL15.GL_STATIC_DRAW);
instanceVBO.alloc(glBufferSize, GL15.GL_STATIC_DRAW);
instanceVBO.map(glBufferSize, buffer -> {
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.MaterialType;
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.OrientedData;
import com.simibubi.create.foundation.render.backend.gl.BasicProgram;
import com.simibubi.create.foundation.render.backend.gl.shader.ShaderCallback;
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.backend.Backend;
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.ShaderCallback;

View file

@ -1,13 +1,62 @@
#version 120
layout (std140) struct Sphere {
vec4 positionRadius;
vec4 color;
} uSpheres;
varying vec4 Vertex;
varying vec3 CameraDir;
//layout (std140) struct Sphere {
// vec4 positionRadius;
// vec4 color;
//} uSphere;
uniform sampler2D uDepth;
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() {
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;
}