diff --git a/src/main/java/com/jozufozu/flywheel/backend/Backend.java b/src/main/java/com/jozufozu/flywheel/backend/Backend.java index fc0b3ac8a..73fb81cad 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/Backend.java +++ b/src/main/java/com/jozufozu/flywheel/backend/Backend.java @@ -21,8 +21,8 @@ import org.lwjgl.opengl.GL; import org.lwjgl.opengl.GLCapabilities; import com.jozufozu.flywheel.backend.core.CrumblingRenderer; -import com.jozufozu.flywheel.backend.core.WorldContext; import com.jozufozu.flywheel.backend.core.WorldTileRenderer; +import com.jozufozu.flywheel.backend.core.context.WorldContext; import com.jozufozu.flywheel.backend.core.shader.WorldProgram; import com.jozufozu.flywheel.backend.core.shader.spec.ProgramSpec; import com.jozufozu.flywheel.backend.gl.shader.GlProgram; diff --git a/src/main/java/com/jozufozu/flywheel/backend/core/CrumblingRenderer.java b/src/main/java/com/jozufozu/flywheel/backend/core/CrumblingRenderer.java index f1be59600..002540e27 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/core/CrumblingRenderer.java +++ b/src/main/java/com/jozufozu/flywheel/backend/core/CrumblingRenderer.java @@ -1,5 +1,7 @@ package com.jozufozu.flywheel.backend.core; +import com.jozufozu.flywheel.backend.core.context.WorldContext; + import net.minecraft.util.math.BlockPos; public class CrumblingRenderer extends WorldTileRenderer { diff --git a/src/main/java/com/jozufozu/flywheel/backend/core/FullscreenQuad.java b/src/main/java/com/jozufozu/flywheel/backend/core/FullscreenQuad.java new file mode 100644 index 000000000..d290e7e58 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/backend/core/FullscreenQuad.java @@ -0,0 +1,61 @@ +package com.jozufozu.flywheel.backend.core; + +import org.lwjgl.opengl.GL20; + +import com.jozufozu.flywheel.backend.gl.GlPrimitiveType; +import com.jozufozu.flywheel.backend.gl.GlVertexArray; +import com.jozufozu.flywheel.backend.gl.buffer.GlBuffer; +import com.jozufozu.flywheel.backend.gl.buffer.GlBufferType; + +import net.minecraftforge.common.util.Lazy; + +public class FullscreenQuad { + + public static final Lazy INSTANCE = Lazy.of(FullscreenQuad::new); + + private 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 GlVertexArray vao; + private final GlBuffer vbo; + + private FullscreenQuad() { + vbo = new GlBuffer(GlBufferType.ARRAY_BUFFER); + vbo.bind(); + vbo.alloc(bufferSize); + vbo.getBuffer(0, bufferSize) + .putFloatArray(vertices) + .flush(); + + vao = new GlVertexArray(); + vao.bind(); + + GL20.glEnableVertexAttribArray(0); + + GL20.glVertexAttribPointer(0, 4, GlPrimitiveType.FLOAT.getGlConstant(), false, 4 * 4, 0); + + vao.unbind(); + vbo.unbind(); + } + + public void draw() { + vao.bind(); + GL20.glDrawArrays(GL20.GL_TRIANGLES, 0, 6); + vao.unbind(); + } + + public void delete() { + vao.delete(); + vbo.delete(); + } +} diff --git a/src/main/java/com/jozufozu/flywheel/backend/core/WorldTileRenderer.java b/src/main/java/com/jozufozu/flywheel/backend/core/WorldTileRenderer.java index 5401bd444..c473905db 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/core/WorldTileRenderer.java +++ b/src/main/java/com/jozufozu/flywheel/backend/core/WorldTileRenderer.java @@ -2,6 +2,7 @@ package com.jozufozu.flywheel.backend.core; import java.util.ArrayList; +import com.jozufozu.flywheel.backend.core.context.WorldContext; import com.jozufozu.flywheel.backend.core.shader.ShaderCallback; import com.jozufozu.flywheel.backend.core.shader.WorldProgram; import com.jozufozu.flywheel.backend.instancing.InstancedTileRenderer; diff --git a/src/main/java/com/jozufozu/flywheel/backend/core/WorldContext.java b/src/main/java/com/jozufozu/flywheel/backend/core/context/WorldContext.java similarity index 97% rename from src/main/java/com/jozufozu/flywheel/backend/core/WorldContext.java rename to src/main/java/com/jozufozu/flywheel/backend/core/context/WorldContext.java index 008e5c7a9..c3197dbd5 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/core/WorldContext.java +++ b/src/main/java/com/jozufozu/flywheel/backend/core/context/WorldContext.java @@ -1,4 +1,4 @@ -package com.jozufozu.flywheel.backend.core; +package com.jozufozu.flywheel.backend.core.context; import java.util.EnumMap; import java.util.Map; @@ -12,6 +12,7 @@ import com.jozufozu.flywheel.backend.Backend; import com.jozufozu.flywheel.backend.ResourceUtil; import com.jozufozu.flywheel.backend.ShaderContext; import com.jozufozu.flywheel.backend.ShaderLoader; +import com.jozufozu.flywheel.backend.core.CrumblingProgram; import com.jozufozu.flywheel.backend.core.shader.ExtensibleGlProgram; import com.jozufozu.flywheel.backend.core.shader.IMultiProgram; import com.jozufozu.flywheel.backend.core.shader.StateSensitiveMultiProgram; diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/InstancedTileRenderer.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/InstancedTileRenderer.java index 8d7c2fe11..8101d291a 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/InstancedTileRenderer.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/InstancedTileRenderer.java @@ -8,7 +8,7 @@ import java.util.concurrent.ConcurrentHashMap; import javax.annotation.Nullable; import com.jozufozu.flywheel.backend.Backend; -import com.jozufozu.flywheel.backend.core.WorldContext; +import com.jozufozu.flywheel.backend.core.context.WorldContext; import com.jozufozu.flywheel.backend.core.materials.ModelData; import com.jozufozu.flywheel.backend.core.materials.OrientedData; import com.jozufozu.flywheel.backend.core.shader.ShaderCallback; diff --git a/src/main/java/com/simibubi/create/CreateClient.java b/src/main/java/com/simibubi/create/CreateClient.java index cd804a361..6feabe8a7 100644 --- a/src/main/java/com/simibubi/create/CreateClient.java +++ b/src/main/java/com/simibubi/create/CreateClient.java @@ -112,7 +112,6 @@ public class CreateClient { PonderIndex.registerTags(); UIRenderHelper.init(); - UIRenderHelper.enableStencil(); IResourceManager resourceManager = Minecraft.getInstance() .getResourceManager(); @@ -120,7 +119,7 @@ public class CreateClient { ((IReloadableResourceManager) resourceManager).addReloadListener(new ResourceReloadHandler()); AllBlockPartials.clientInit(); - + event.enqueueWork(() -> { CopperBacktankArmorLayer.register(); }); diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionRenderDispatcher.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionRenderDispatcher.java index 5d537347d..1e9992cbc 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionRenderDispatcher.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionRenderDispatcher.java @@ -15,7 +15,7 @@ import java.util.stream.Stream; import org.apache.commons.lang3.tuple.Pair; import com.jozufozu.flywheel.backend.Backend; -import com.jozufozu.flywheel.backend.core.WorldContext; +import com.jozufozu.flywheel.backend.core.context.WorldContext; import com.jozufozu.flywheel.backend.loading.ModelTemplate; import com.mojang.blaze3d.matrix.MatrixStack; import com.simibubi.create.AllMovementBehaviours; diff --git a/src/main/java/com/simibubi/create/foundation/config/ui/ConfigScreen.java b/src/main/java/com/simibubi/create/foundation/config/ui/ConfigScreen.java index 98086a786..24a2d4da6 100644 --- a/src/main/java/com/simibubi/create/foundation/config/ui/ConfigScreen.java +++ b/src/main/java/com/simibubi/create/foundation/config/ui/ConfigScreen.java @@ -8,18 +8,26 @@ import java.util.stream.Collectors; import javax.annotation.Nonnull; import org.apache.commons.lang3.StringUtils; +import org.lwjgl.opengl.GL11; +import org.lwjgl.opengl.GL20; +import org.lwjgl.opengl.GL30; +import com.jozufozu.flywheel.backend.Backend; import com.mojang.blaze3d.matrix.MatrixStack; import com.simibubi.create.AllBlocks; import com.simibubi.create.content.contraptions.relays.elementary.CogWheelBlock; import com.simibubi.create.foundation.gui.AbstractSimiScreen; import com.simibubi.create.foundation.gui.GuiGameElement; import com.simibubi.create.foundation.gui.StencilElement; +import com.simibubi.create.foundation.gui.UIRenderHelper; import com.simibubi.create.foundation.utility.animation.Force; import com.simibubi.create.foundation.utility.animation.PhysicalFloat; import net.minecraft.block.BlockState; +import net.minecraft.client.Minecraft; import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.shader.Framebuffer; +import net.minecraft.client.shader.FramebufferConstants; import net.minecraft.util.Direction; public abstract class ConfigScreen extends AbstractSimiScreen { @@ -83,7 +91,35 @@ public abstract class ConfigScreen extends AbstractSimiScreen { } @Override - protected void renderWindow(MatrixStack ms, int mouseX, int mouseY, float partialTicks) {} + protected void prepareFrame() { + Framebuffer thisBuffer = UIRenderHelper.framebuffer; + Framebuffer mainBuffer = Minecraft.getInstance().getFramebuffer(); + + Backend.compat.fbo.bindFramebuffer(GL30.GL_READ_FRAMEBUFFER, mainBuffer.framebufferObject); + Backend.compat.fbo.bindFramebuffer(GL30.GL_DRAW_FRAMEBUFFER, thisBuffer.framebufferObject); + Backend.compat.blit.blitFramebuffer(0, 0, mainBuffer.framebufferWidth, mainBuffer.framebufferHeight, 0, 0, mainBuffer.framebufferWidth, mainBuffer.framebufferHeight, GL30.GL_COLOR_BUFFER_BIT, GL20.GL_LINEAR); + + Backend.compat.fbo.bindFramebuffer(FramebufferConstants.FRAME_BUFFER, thisBuffer.framebufferObject); + GL11.glClear(GL30.GL_STENCIL_BUFFER_BIT | GL30.GL_DEPTH_BUFFER_BIT); + + } + + @Override + protected void endFrame() { + + Framebuffer thisBuffer = UIRenderHelper.framebuffer; + Framebuffer mainBuffer = Minecraft.getInstance().getFramebuffer(); + + Backend.compat.fbo.bindFramebuffer(GL30.GL_READ_FRAMEBUFFER, thisBuffer.framebufferObject); + Backend.compat.fbo.bindFramebuffer(GL30.GL_DRAW_FRAMEBUFFER, mainBuffer.framebufferObject); + Backend.compat.blit.blitFramebuffer(0, 0, mainBuffer.framebufferWidth, mainBuffer.framebufferHeight, 0, 0, mainBuffer.framebufferWidth, mainBuffer.framebufferHeight, GL30.GL_COLOR_BUFFER_BIT, GL20.GL_LINEAR); + + Backend.compat.fbo.bindFramebuffer(FramebufferConstants.FRAME_BUFFER, mainBuffer.framebufferObject); + } + + @Override + protected void renderWindow(MatrixStack ms, int mouseX, int mouseY, float partialTicks) { + } @Override public boolean mouseScrolled(double mouseX, double mouseY, double delta) { diff --git a/src/main/java/com/simibubi/create/foundation/gui/AbstractSimiScreen.java b/src/main/java/com/simibubi/create/foundation/gui/AbstractSimiScreen.java index b064ccbfa..4a78dc36e 100644 --- a/src/main/java/com/simibubi/create/foundation/gui/AbstractSimiScreen.java +++ b/src/main/java/com/simibubi/create/foundation/gui/AbstractSimiScreen.java @@ -43,20 +43,30 @@ public abstract class AbstractSimiScreen extends Screen { @Override public void render(MatrixStack ms, int mouseX, int mouseY, float partialTicks) { partialTicks = partialTicks == 10 ? 0 - : Minecraft.getInstance() + : Minecraft.getInstance() .getRenderPartialTicks(); ms.push(); + prepareFrame(); + renderWindowBackground(ms, mouseX, mouseY, partialTicks); renderWindow(ms, mouseX, mouseY, partialTicks); for (Widget widget : widgets) widget.render(ms, mouseX, mouseY, partialTicks); renderWindowForeground(ms, mouseX, mouseY, partialTicks); + endFrame(); + ms.pop(); } + protected void prepareFrame() { + } + + protected void endFrame() { + } + protected void renderWindowBackground(MatrixStack ms, int mouseX, int mouseY, float partialTicks) { renderBackground(ms); } diff --git a/src/main/java/com/simibubi/create/foundation/gui/StencilElement.java b/src/main/java/com/simibubi/create/foundation/gui/StencilElement.java index 26677e053..22c70b75f 100644 --- a/src/main/java/com/simibubi/create/foundation/gui/StencilElement.java +++ b/src/main/java/com/simibubi/create/foundation/gui/StencilElement.java @@ -47,5 +47,6 @@ public abstract class StencilElement extends RenderElement { protected void cleanUp(MatrixStack ms) { GL11.glDisable(GL11.GL_STENCIL_TEST); + } } diff --git a/src/main/java/com/simibubi/create/foundation/gui/UIRenderHelper.java b/src/main/java/com/simibubi/create/foundation/gui/UIRenderHelper.java index fee8e48c6..23adb2cc2 100644 --- a/src/main/java/com/simibubi/create/foundation/gui/UIRenderHelper.java +++ b/src/main/java/com/simibubi/create/foundation/gui/UIRenderHelper.java @@ -1,6 +1,6 @@ package com.simibubi.create.foundation.gui; -import java.awt.Color; +import java.awt.*; import javax.annotation.Nonnull; @@ -25,23 +25,33 @@ import net.minecraftforge.fml.client.gui.GuiUtils; public class UIRenderHelper { - public static void enableStencil() { - RenderSystem.recordRenderCall(() -> Minecraft.getInstance().getFramebuffer().enableStencil()); - } - + /** + * An FBO that has a stencil buffer for use wherever stencil are necessary. Forcing the main FBO to have a stencil + * buffer will cause GL error spam when using fabulous graphics. + */ public static Framebuffer framebuffer; + public static void updateWindowSize(MainWindow mainWindow) { + if (framebuffer != null) + framebuffer.func_216491_a(mainWindow.getFramebufferWidth(), mainWindow.getFramebufferHeight(), Minecraft.IS_RUNNING_ON_MAC); + } + public static void init() { RenderSystem.recordRenderCall(() -> { MainWindow mainWindow = Minecraft.getInstance() .getWindow(); - framebuffer = new Framebuffer(mainWindow.getFramebufferWidth(), mainWindow.getFramebufferHeight(), true, - Minecraft.IS_RUNNING_ON_MAC); - framebuffer.setFramebufferColor(0, 0, 0, 0); - framebuffer.enableStencil(); + framebuffer = createFramebuffer(mainWindow); }); } + private static Framebuffer createFramebuffer(MainWindow mainWindow) { + Framebuffer framebuffer = new Framebuffer(mainWindow.getFramebufferWidth(), mainWindow.getFramebufferHeight(), true, + Minecraft.IS_RUNNING_ON_MAC); + framebuffer.setFramebufferColor(0, 0, 0, 0); + framebuffer.enableStencil(); + return framebuffer; + } + public static void drawFramebuffer(float alpha) { MainWindow window = Minecraft.getInstance() .getWindow(); @@ -70,10 +80,10 @@ public class UIRenderHelper { } public static void streak(MatrixStack ms, float angle, int x, int y, int breadth, int length) {streak(ms, angle, x, y, breadth, length, Theme.i(Theme.Key.STREAK));} - // angle in degrees; 0° -> fading to the right // x and y specify the middle point of the starting edge // breadth is the total width of the streak + public static void streak(MatrixStack ms, float angle, int x, int y, int breadth, int length, int color) { int a1 = 0xa0 << 24; int a2 = 0x80 << 24; diff --git a/src/main/java/com/simibubi/create/foundation/mixin/WindowResizeMixin.java b/src/main/java/com/simibubi/create/foundation/mixin/WindowResizeMixin.java index 5008129b3..21ed291ff 100644 --- a/src/main/java/com/simibubi/create/foundation/mixin/WindowResizeMixin.java +++ b/src/main/java/com/simibubi/create/foundation/mixin/WindowResizeMixin.java @@ -22,8 +22,7 @@ public class WindowResizeMixin { @Inject(at = @At("TAIL"), method = "updateWindowSize") private void updateWindowSize(CallbackInfo ci) { - if (UIRenderHelper.framebuffer != null) - UIRenderHelper.framebuffer.func_216491_a(mainWindow.getFramebufferWidth(), mainWindow.getFramebufferHeight(), Minecraft.IS_RUNNING_ON_MAC); + UIRenderHelper.updateWindowSize(mainWindow); } } diff --git a/src/main/java/com/simibubi/create/foundation/render/effects/EffectsHandler.java b/src/main/java/com/simibubi/create/foundation/render/effects/EffectsHandler.java index eae45b987..2e3e71301 100644 --- a/src/main/java/com/simibubi/create/foundation/render/effects/EffectsHandler.java +++ b/src/main/java/com/simibubi/create/foundation/render/effects/EffectsHandler.java @@ -9,10 +9,7 @@ import org.lwjgl.opengl.GL20; import org.lwjgl.opengl.GL30; import com.jozufozu.flywheel.backend.Backend; -import com.jozufozu.flywheel.backend.gl.GlPrimitiveType; -import com.jozufozu.flywheel.backend.gl.GlVertexArray; -import com.jozufozu.flywheel.backend.gl.buffer.GlBuffer; -import com.jozufozu.flywheel.backend.gl.buffer.GlBufferType; +import com.jozufozu.flywheel.backend.core.FullscreenQuad; import com.jozufozu.flywheel.util.RenderUtil; import com.simibubi.create.foundation.render.AllProgramSpecs; import com.simibubi.create.foundation.utility.AnimationTickHolder; @@ -52,23 +49,8 @@ public class EffectsHandler { return Minecraft.getInstance().gameRenderer.getFarPlaneDistance() * 4; } - 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; - - private final GlBuffer vbo; private final ArrayList spheres; @@ -78,23 +60,6 @@ public class EffectsHandler { Framebuffer render = Minecraft.getInstance().getFramebuffer(); framebuffer = new Framebuffer(render.framebufferWidth, render.framebufferHeight, false, Minecraft.IS_RUNNING_ON_MAC); - vbo = new GlBuffer(GlBufferType.ARRAY_BUFFER); - vbo.bind(); - vbo.alloc(bufferSize); - vbo.getBuffer(0, bufferSize) - .putFloatArray(vertices) - .flush(); - - vao = new GlVertexArray(); - vao.bind(); - - GL20.glEnableVertexAttribArray(0); - - GL20.glVertexAttribPointer(0, 4, GlPrimitiveType.FLOAT.getGlConstant(), false, 4 * 4, 0); - - vao.unbind(); - vbo.unbind(); - } public void addSphere(FilterSphere sphere) { @@ -155,9 +120,7 @@ public class EffectsHandler { program.setFarPlane(getFarPlane()); program.setNearPlane(getNearPlane()); - vao.bind(); - GL20.glDrawArrays(GL20.GL_TRIANGLES, 0, 6); - vao.unbind(); + FullscreenQuad.INSTANCE.get().draw(); program.bindColorTexture(0); program.bindDepthTexture(0); @@ -174,9 +137,6 @@ public class EffectsHandler { public void delete() { framebuffer.deleteFramebuffer(); - - vao.delete(); - vbo.delete(); } private void prepFramebufferSize() {