diff --git a/src/main/java/com/simibubi/create/CreateClient.java b/src/main/java/com/simibubi/create/CreateClient.java index 515429057..ddab555eb 100644 --- a/src/main/java/com/simibubi/create/CreateClient.java +++ b/src/main/java/com/simibubi/create/CreateClient.java @@ -12,7 +12,7 @@ import com.simibubi.create.foundation.block.render.SpriteShifter; import com.simibubi.create.foundation.item.CustomItemModels; import com.simibubi.create.foundation.item.CustomRenderedItems; import com.simibubi.create.foundation.render.KineticRenderer; -import com.simibubi.create.foundation.render.OptifineHandler; +import com.simibubi.create.foundation.render.gl.backend.OptifineHandler; import com.simibubi.create.foundation.render.SuperByteBufferCache; import com.simibubi.create.foundation.render.contraption.ContraptionRenderDispatcher; import com.simibubi.create.foundation.render.gl.backend.Backend; diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/mixer/MechanicalMixerRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/components/mixer/MechanicalMixerRenderer.java index ca1b39d8b..9937e6cfa 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/mixer/MechanicalMixerRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/mixer/MechanicalMixerRenderer.java @@ -24,6 +24,11 @@ public class MechanicalMixerRenderer extends KineticTileEntityRenderer { super(dispatcher); } + @Override + public boolean isGlobalRenderer(KineticTileEntity te) { + return true; + } + @Override protected void renderSafe(KineticTileEntity te, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer, int light, int overlay) { diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/press/MechanicalPressRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/components/press/MechanicalPressRenderer.java index 58a7a6c83..18f2353a7 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/press/MechanicalPressRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/press/MechanicalPressRenderer.java @@ -19,6 +19,11 @@ public class MechanicalPressRenderer extends KineticTileEntityRenderer { super(dispatcher); } + @Override + public boolean isGlobalRenderer(KineticTileEntity te) { + return true; + } + @Override protected void renderSafe(KineticTileEntity te, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer, int light, int overlay) { diff --git a/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmRenderer.java b/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmRenderer.java index 73f747b57..3e38b8abb 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmRenderer.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmRenderer.java @@ -29,6 +29,11 @@ public class ArmRenderer extends KineticTileEntityRenderer { super(dispatcher); } + @Override + public boolean isGlobalRenderer(KineticTileEntity te) { + return true; + } + @Override protected void renderSafe(KineticTileEntity te, float pt, MatrixStack ms, IRenderTypeBuffer buffer, int light, int overlay) { diff --git a/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmTileEntity.java b/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmTileEntity.java index e088c50d0..c4370c2b4 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmTileEntity.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmTileEntity.java @@ -466,6 +466,11 @@ public class ArmTileEntity extends KineticTileEntity { return true; } + @Override + public boolean shouldRenderAsTE() { + return true; + } + private class SelectionModeValueBox extends CenteredSideValueBoxTransform { public SelectionModeValueBox() { diff --git a/src/main/java/com/simibubi/create/foundation/command/ConfigureConfigPacket.java b/src/main/java/com/simibubi/create/foundation/command/ConfigureConfigPacket.java index 2154690df..945166a97 100644 --- a/src/main/java/com/simibubi/create/foundation/command/ConfigureConfigPacket.java +++ b/src/main/java/com/simibubi/create/foundation/command/ConfigureConfigPacket.java @@ -5,7 +5,6 @@ import java.util.function.Supplier; import com.simibubi.create.foundation.render.FastRenderDispatcher; import com.simibubi.create.foundation.render.gl.backend.Backend; -import javafx.scene.layout.Background; import org.apache.logging.log4j.LogManager; import com.simibubi.create.content.contraptions.goggles.GoggleConfigScreen; @@ -88,11 +87,7 @@ public class ConfigureConfigPacket extends SimplePacketBase { private static void experimentalRendering(String value) { boolean last = AllConfigs.CLIENT.experimentalRendering.get(); AllConfigs.CLIENT.experimentalRendering.set(Boolean.parseBoolean(value)); - Backend.refreshAvailability(); - - if (last != AllConfigs.CLIENT.experimentalRendering.get()) { - FastRenderDispatcher.refresh(); - } + FastRenderDispatcher.refresh(); } @OnlyIn(Dist.CLIENT) diff --git a/src/main/java/com/simibubi/create/foundation/config/CClient.java b/src/main/java/com/simibubi/create/foundation/config/CClient.java index 25fcc3fea..a1f3fbc13 100644 --- a/src/main/java/com/simibubi/create/foundation/config/CClient.java +++ b/src/main/java/com/simibubi/create/foundation/config/CClient.java @@ -38,19 +38,7 @@ public class CClient extends ConfigBase { */ @Override public Boolean get() { - boolean enabled = super.get(); - - if (enabled) { - switch (Backend.getAvailability()) { - case FULL: - case PARTIAL: - return true; - default: - return false; - } - } else { - return false; - } + return super.get() && Backend.canUse(); } } diff --git a/src/main/java/com/simibubi/create/foundation/mixin/ShaderCloseMixin.java b/src/main/java/com/simibubi/create/foundation/mixin/ShaderCloseMixin.java new file mode 100644 index 000000000..e65a9774c --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/mixin/ShaderCloseMixin.java @@ -0,0 +1,29 @@ +package com.simibubi.create.foundation.mixin; + +import com.simibubi.create.foundation.render.gl.backend.OptifineHandler; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.gui.screen.VideoSettingsScreen; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import javax.annotation.Nullable; + +@Mixin(Minecraft.class) +public class ShaderCloseMixin { + + @Shadow @Nullable public Screen currentScreen; + + @Inject(at = @At("HEAD"), method = "displayGuiScreen") + private void whenScreenChanges(Screen screen, CallbackInfo info) { + if (OptifineHandler.optifineInstalled() && screen instanceof VideoSettingsScreen) { + Screen old = this.currentScreen; + if (old != null && old.getClass().getName().startsWith(OptifineHandler.SHADER_PACKAGE)) { + OptifineHandler.refresh(); + } + } + } +} diff --git a/src/main/java/com/simibubi/create/foundation/render/FastRenderDispatcher.java b/src/main/java/com/simibubi/create/foundation/render/FastRenderDispatcher.java index ad75f735b..208e1474b 100644 --- a/src/main/java/com/simibubi/create/foundation/render/FastRenderDispatcher.java +++ b/src/main/java/com/simibubi/create/foundation/render/FastRenderDispatcher.java @@ -5,6 +5,8 @@ import com.mojang.blaze3d.systems.RenderSystem; import com.simibubi.create.CreateClient; import com.simibubi.create.foundation.config.AllConfigs; import com.simibubi.create.foundation.render.contraption.ContraptionRenderDispatcher; +import com.simibubi.create.foundation.render.gl.backend.Backend; +import com.simibubi.create.foundation.render.gl.backend.OptifineHandler; import com.simibubi.create.foundation.render.light.ILightListener; import com.simibubi.create.foundation.utility.AnimationTickHolder; import com.simibubi.create.foundation.utility.WorldAttached; @@ -63,6 +65,7 @@ public class FastRenderDispatcher { public static void refresh() { RenderWork.enqueue(() -> { CreateClient.kineticRenderer.invalidate(); + OptifineHandler.refresh(); Minecraft.getInstance().worldRenderer.loadRenderers(); ClientWorld world = Minecraft.getInstance().world; if (world != null) world.loadedTileEntityList.forEach(CreateClient.kineticRenderer::add); diff --git a/src/main/java/com/simibubi/create/foundation/render/OptifineHandler.java b/src/main/java/com/simibubi/create/foundation/render/OptifineHandler.java deleted file mode 100644 index 55665fcee..000000000 --- a/src/main/java/com/simibubi/create/foundation/render/OptifineHandler.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.simibubi.create.foundation.render; - -import com.simibubi.create.foundation.render.gl.backend.Backend; -import net.minecraft.client.Minecraft; - -import java.io.*; -import java.util.Optional; - -public class OptifineHandler { - private static Package optifine; - private static OptifineHandler handler; - - public final boolean usingShaders; - - public OptifineHandler(boolean usingShaders) { - this.usingShaders = usingShaders; - } - - public static Optional get() { - return Optional.ofNullable(handler); - } - - public static void init() { - optifine = Package.getPackage("net.optifine"); - - if (optifine == null) { - Backend.log.info("Optifine not detected."); - } else { - Backend.log.info("Optifine detected."); - - refresh(); - } - } - - public static void refresh() { - if (optifine == null) return; - - File dir = Minecraft.getInstance().gameDir; - - File shaderOptions = new File(dir, "optionsshaders.txt"); - - boolean shadersOff = true; - try { - BufferedReader reader = new BufferedReader(new FileReader(shaderOptions)); - - shadersOff = reader.lines().anyMatch(it -> it.replaceAll("\\s", "").equals("shaderPack=OFF")); - } catch (FileNotFoundException e) { - Backend.log.info("No shader config found."); - } - - handler = new OptifineHandler(!shadersOff); - } - - public boolean isUsingShaders() { - return usingShaders; - } -} diff --git a/src/main/java/com/simibubi/create/foundation/render/gl/backend/Backend.java b/src/main/java/com/simibubi/create/foundation/render/gl/backend/Backend.java index 62c258479..96fff17a3 100644 --- a/src/main/java/com/simibubi/create/foundation/render/gl/backend/Backend.java +++ b/src/main/java/com/simibubi/create/foundation/render/gl/backend/Backend.java @@ -1,6 +1,5 @@ package com.simibubi.create.foundation.render.gl.backend; -import com.simibubi.create.foundation.render.OptifineHandler; import com.simibubi.create.foundation.render.gl.shader.*; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.texture.TextureUtil; @@ -33,19 +32,16 @@ public class Backend { public static final FloatBuffer VEC3_BUFFER = MemoryUtil.memAllocFloat(3); public static final FloatBuffer MATRIX_BUFFER = MemoryUtil.memAllocFloat(16); - private static final Backend instance = new Backend(); - public static Backend instance() { - return instance; - } - private static final Map> registry = new HashMap<>(); private static final Map, GlProgram> programs = new HashMap<>(); public static GLCapabilities capabilities; - private static RenderingAvailability availability; + private static SystemCapability capability; private static MapBuffer mapBuffer; - + public Backend() { + throw new IllegalStateException(); + } public static void mapBuffer(int target, int offset, int length, Consumer upload) { mapBuffer.mapBuffer(target, offset, length, upload); @@ -101,26 +97,37 @@ public class Backend { return Arrays.stream(constants).filter(it -> it.supported(caps)).findFirst().orElse(last); } - public static RenderingAvailability getAvailability() { - return availability; + public static boolean canUse() { + return isCapable() && !OptifineHandler.usingShaders(); + } + + public static SystemCapability getCapability() { + return capability; + } + + public static boolean isCapable() { + return capability.isCapable(); } public static void init() { // Can be null when running datagenerators due to the unfortunate time we call this Minecraft mc = Minecraft.getInstance(); - if (mc != null && mc.getResourceManager() instanceof IReloadableResourceManager) { + if (mc == null) return; + + IResourceManager manager = mc.getResourceManager(); + + if (manager instanceof IReloadableResourceManager) { ISelectiveResourceReloadListener listener = Backend::onResourceManagerReload; - ((IReloadableResourceManager) mc.getResourceManager()).addReloadListener(listener); + ((IReloadableResourceManager) manager).addReloadListener(listener); } } - public static void onResourceManagerReload(IResourceManager manager, Predicate predicate) { + private static void onResourceManagerReload(IResourceManager manager, Predicate predicate) { if (predicate.test(VanillaResourceType.SHADERS)) { capabilities = GL.createCapabilities(); mapBuffer = getLatest(MapBuffer.class); - OptifineHandler.refresh(); - refreshAvailability(); + refresh(); programs.values().forEach(GlProgram::delete); programs.clear(); @@ -130,6 +137,14 @@ public class Backend { } } + public static void refresh() { + if (capabilities.OpenGL33) { + capability = SystemCapability.CAPABLE; + } else { + capability = SystemCapability.INCAPABLE; + } + } + private static

> void loadProgram(IResourceManager manager, S programSpec) { GlShader vert = null; GlShader frag = null; @@ -164,16 +179,4 @@ public class Backend { } } } - - public static void refreshAvailability() { - if (capabilities.OpenGL33) { - availability = RenderingAvailability.FULL; - - OptifineHandler.get() - .filter(OptifineHandler::isUsingShaders) - .ifPresent(it -> availability = RenderingAvailability.OPTIFINE_SHADERS); - } else { - availability = RenderingAvailability.INCAPABLE; - } - } } diff --git a/src/main/java/com/simibubi/create/foundation/render/gl/backend/OptifineHandler.java b/src/main/java/com/simibubi/create/foundation/render/gl/backend/OptifineHandler.java new file mode 100644 index 000000000..5143ba134 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/render/gl/backend/OptifineHandler.java @@ -0,0 +1,82 @@ +package com.simibubi.create.foundation.render.gl.backend; + +import net.minecraft.client.Minecraft; + +import java.io.*; +import java.util.Optional; + +public class OptifineHandler { + public static final String OPTIFINE_ROOT_PACKAGE = "net.optifine"; + public static final String SHADER_PACKAGE = "net.optifine.shaders"; + + private static Package optifine; + private static OptifineHandler handler; + + public final boolean usingShaders; + + public OptifineHandler(boolean usingShaders) { + this.usingShaders = usingShaders; + } + + /** + * Get information about the current Optifine configuration. + * @return {@link Optional#empty()} if Optifine is not installed. + */ + public static Optional get() { + return Optional.ofNullable(handler); + } + + public static boolean optifineInstalled() { + return optifine != null; + } + + public static boolean usingShaders() { + return OptifineHandler.get() + .map(OptifineHandler::isUsingShaders) + .orElse(false); + } + + public static void init() { + optifine = Package.getPackage(OPTIFINE_ROOT_PACKAGE); + + if (optifine == null) { + Backend.log.info("Optifine not detected."); + } else { + Backend.log.info("Optifine detected."); + + refresh(); + } + } + + public static void refresh() { + if (optifine == null) return; + + File dir = Minecraft.getInstance().gameDir; + + File shaderOptions = new File(dir, "optionsshaders.txt"); + + boolean shadersOff = true; + try { + BufferedReader reader = new BufferedReader(new FileReader(shaderOptions)); + + shadersOff = reader.lines() + .anyMatch(it -> { + String line = it.replaceAll("\\s", ""); + if (line.startsWith("shaderPack=")) { + String setting = line.substring("shaderPack=".length()); + + return setting.equals("OFF") || setting.equals("(internal)"); + } + return false; + }); + } catch (FileNotFoundException e) { + Backend.log.info("No shader config found."); + } + + handler = new OptifineHandler(!shadersOff); + } + + public boolean isUsingShaders() { + return usingShaders; + } +} diff --git a/src/main/java/com/simibubi/create/foundation/render/gl/backend/RenderingAvailability.java b/src/main/java/com/simibubi/create/foundation/render/gl/backend/RenderingAvailability.java deleted file mode 100644 index 23841149b..000000000 --- a/src/main/java/com/simibubi/create/foundation/render/gl/backend/RenderingAvailability.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.simibubi.create.foundation.render.gl.backend; - -public enum RenderingAvailability { - /** - * The current system does not support enough - * OpenGL features to enable fast rendering. - */ - INCAPABLE, - - /** - * The current system supports OpenGL 3.3. - */ - FULL, - - /** - * The current system supports OpenGL 2.0, - * or some ARBs that make it equivalent. - */ - PARTIAL, - - /** - * It doesn't matter what the current system - * supports because Optifine is installed and - * a shaderpack is enabled. - */ - OPTIFINE_SHADERS, -} diff --git a/src/main/java/com/simibubi/create/foundation/render/gl/backend/SystemCapability.java b/src/main/java/com/simibubi/create/foundation/render/gl/backend/SystemCapability.java new file mode 100644 index 000000000..4dcb5d9a4 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/render/gl/backend/SystemCapability.java @@ -0,0 +1,19 @@ +package com.simibubi.create.foundation.render.gl.backend; + +public enum SystemCapability { + /** + * The current system does not support enough + * OpenGL features to enable fast rendering. + */ + INCAPABLE, + + /** + * The current system supports OpenGL 3.3. + */ + CAPABLE, + ; + + public boolean isCapable() { + return this == CAPABLE; + } +} diff --git a/src/main/resources/create.mixins.json b/src/main/resources/create.mixins.json index ae2f46a98..4f171a769 100644 --- a/src/main/resources/create.mixins.json +++ b/src/main/resources/create.mixins.json @@ -3,9 +3,9 @@ "package": "com.simibubi.create.foundation.mixin", "compatibilityLevel": "JAVA_8", "refmap": "create.refmap.json", - "client": ["CancelTileEntityRenderMixin", "LightUpdateMixin", "RenderInLayerMixin"], + "client": ["OnRemoveTileMixin", "ShaderCloseMixin", "CancelTileEntityRenderMixin", "LightUpdateMixin", "RenderInLayerMixin"], "injectors": { "defaultRequire": 1 }, - "minVersion": "0.8", "mixins": ["OnRemoveTileMixin"] + "minVersion": "0.8" } \ No newline at end of file