mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2024-12-14 20:20:30 +00:00
Make the shader mod system a little more flexible
Mostly for multi-loader support, but also /technically/ makes it easier to support multiple loaders in the future.
This commit is contained in:
parent
8a7156785d
commit
0c4fd2b29e
@ -8,8 +8,6 @@ package dan200.computercraft.impl;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.ServiceLoader;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@ -32,17 +30,15 @@ public final class Services {
|
||||
* @throws IllegalStateException When the service cannot be loaded.
|
||||
*/
|
||||
public static <T> T load(Class<T> klass) {
|
||||
List<T> services = new ArrayList<>(1);
|
||||
for (var provider : ServiceLoader.load(klass)) services.add(provider);
|
||||
switch (services.size()) {
|
||||
case 1:
|
||||
return services.get(0);
|
||||
case 0:
|
||||
throw new IllegalStateException("Cannot find service for " + klass.getName());
|
||||
default:
|
||||
var serviceTypes = services.stream().map(x -> x.getClass().getName()).collect(Collectors.joining(", "));
|
||||
var services = ServiceLoader.load(klass).stream().toList();
|
||||
return switch (services.size()) {
|
||||
case 1 -> services.get(0).get();
|
||||
case 0 -> throw new IllegalStateException("Cannot find service for " + klass.getName());
|
||||
default -> {
|
||||
var serviceTypes = services.stream().map(x -> x.type().getName()).collect(Collectors.joining(", "));
|
||||
throw new IllegalStateException("Multiple services for " + klass.getName() + ": " + serviceTypes);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -3,8 +3,9 @@
|
||||
* Copyright Daniel Ratcliffe, 2011-2022. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
package dan200.computercraft.shared.integration;
|
||||
package dan200.computercraft.client.integration;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import com.mojang.blaze3d.vertex.VertexFormat;
|
||||
import dan200.computercraft.client.render.RenderTypes;
|
||||
import dan200.computercraft.client.render.text.DirectFixedWidthFontRenderer;
|
||||
@ -13,28 +14,20 @@ import net.irisshaders.iris.api.v0.IrisTextVertexSink;
|
||||
import net.minecraftforge.fml.ModList;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Optional;
|
||||
import java.util.function.IntFunction;
|
||||
|
||||
public class ShaderMod {
|
||||
public static final ShaderMod INSTANCE
|
||||
= ModList.get().isLoaded("oculus") ? new IrisImpl()
|
||||
: new ShaderMod();
|
||||
|
||||
public boolean isShaderMod() {
|
||||
return Optifine.isLoaded();
|
||||
/**
|
||||
* A {@link ShaderMod} for Oculus (the Forge Iris port).
|
||||
*/
|
||||
@AutoService(ShaderMod.Provider.class)
|
||||
public class IrisShaderMod implements ShaderMod.Provider {
|
||||
@Override
|
||||
public Optional<ShaderMod> get() {
|
||||
return ModList.get().isLoaded("oculus") ? Optional.of(new Impl()) : Optional.empty();
|
||||
}
|
||||
|
||||
public boolean isRenderingShadowPass() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public DirectFixedWidthFontRenderer.QuadEmitter getQuadEmitter(int vertexCount, IntFunction<ByteBuffer> makeBuffer) {
|
||||
return new DirectFixedWidthFontRenderer.ByteBufferEmitter(
|
||||
makeBuffer.apply(RenderTypes.TERMINAL.format().getVertexSize() * vertexCount * 4)
|
||||
);
|
||||
}
|
||||
|
||||
private static final class IrisImpl extends ShaderMod {
|
||||
private static final class Impl extends ShaderMod {
|
||||
@Override
|
||||
public boolean isRenderingShadowPass() {
|
||||
return IrisApi.getInstance().isRenderingShadowPass();
|
@ -3,7 +3,7 @@
|
||||
* Copyright Daniel Ratcliffe, 2011-2022. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
package dan200.computercraft.shared.integration;
|
||||
package dan200.computercraft.client.integration;
|
||||
|
||||
/**
|
||||
* Detect whether Optifine is installed.
|
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2022. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
package dan200.computercraft.client.integration;
|
||||
|
||||
import dan200.computercraft.client.render.RenderTypes;
|
||||
import dan200.computercraft.client.render.text.DirectFixedWidthFontRenderer;
|
||||
import dan200.computercraft.client.util.DirectVertexBuffer;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Optional;
|
||||
import java.util.ServiceLoader;
|
||||
import java.util.function.IntFunction;
|
||||
|
||||
/**
|
||||
* Find the currently loaded shader mod (if present) and provides utilities for interacting with it.
|
||||
*/
|
||||
public class ShaderMod {
|
||||
public static ShaderMod get() {
|
||||
return Storage.INSTANCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if shaders may be used in the current session.
|
||||
*
|
||||
* @return Whether a shader mod is loaded.
|
||||
*/
|
||||
public boolean isShaderMod() {
|
||||
return Optifine.isLoaded();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether we're currently rendering shadows. Rendering may fall back to a faster but less detailed pass.
|
||||
*
|
||||
* @return Whether we're rendering shadows.
|
||||
*/
|
||||
public boolean isRenderingShadowPass() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an appropriate quad emitter for use with {@link DirectVertexBuffer} and {@link DirectFixedWidthFontRenderer} .
|
||||
*
|
||||
* @param vertexCount The number of vertices.
|
||||
* @param makeBuffer A function to allocate a temporary buffer.
|
||||
* @return The quad emitter.
|
||||
*/
|
||||
public DirectFixedWidthFontRenderer.QuadEmitter getQuadEmitter(int vertexCount, IntFunction<ByteBuffer> makeBuffer) {
|
||||
return new DirectFixedWidthFontRenderer.ByteBufferEmitter(
|
||||
makeBuffer.apply(RenderTypes.TERMINAL.format().getVertexSize() * vertexCount * 4)
|
||||
);
|
||||
}
|
||||
|
||||
public interface Provider {
|
||||
Optional<ShaderMod> get();
|
||||
}
|
||||
|
||||
private static class Storage {
|
||||
static final ShaderMod INSTANCE = ServiceLoader.load(Provider.class)
|
||||
.stream()
|
||||
.flatMap(x -> x.get().get().stream())
|
||||
.findFirst()
|
||||
.orElseGet(ShaderMod::new);
|
||||
}
|
||||
}
|
@ -16,6 +16,7 @@ import com.mojang.math.Matrix3f;
|
||||
import com.mojang.math.Matrix4f;
|
||||
import com.mojang.math.Vector3f;
|
||||
import dan200.computercraft.client.FrameInfo;
|
||||
import dan200.computercraft.client.integration.ShaderMod;
|
||||
import dan200.computercraft.client.render.monitor.MonitorRenderState;
|
||||
import dan200.computercraft.client.render.text.DirectFixedWidthFontRenderer;
|
||||
import dan200.computercraft.client.render.text.FixedWidthFontRenderer;
|
||||
@ -23,7 +24,6 @@ import dan200.computercraft.client.util.DirectBuffers;
|
||||
import dan200.computercraft.client.util.DirectVertexBuffer;
|
||||
import dan200.computercraft.core.terminal.Terminal;
|
||||
import dan200.computercraft.shared.config.Config;
|
||||
import dan200.computercraft.shared.integration.ShaderMod;
|
||||
import dan200.computercraft.shared.peripheral.monitor.ClientMonitor;
|
||||
import dan200.computercraft.shared.peripheral.monitor.MonitorRenderer;
|
||||
import dan200.computercraft.shared.peripheral.monitor.TileMonitor;
|
||||
@ -112,7 +112,7 @@ public class TileEntityMonitorRenderer implements BlockEntityRenderer<TileMonito
|
||||
|
||||
// Draw the contents
|
||||
var terminal = originTerminal.getTerminal();
|
||||
if (terminal != null && !ShaderMod.INSTANCE.isRenderingShadowPass()) {
|
||||
if (terminal != null && !ShaderMod.get().isRenderingShadowPass()) {
|
||||
// Draw a terminal
|
||||
int width = terminal.getWidth(), height = terminal.getHeight();
|
||||
int pixelWidth = width * FONT_WIDTH, pixelHeight = height * FONT_HEIGHT;
|
||||
@ -233,7 +233,7 @@ public class TileEntityMonitorRenderer implements BlockEntityRenderer<TileMonito
|
||||
}
|
||||
|
||||
private static void renderToBuffer(DirectVertexBuffer vbo, int size, Consumer<DirectFixedWidthFontRenderer.QuadEmitter> draw) {
|
||||
var sink = ShaderMod.INSTANCE.getQuadEmitter(size, TileEntityMonitorRenderer::getBuffer);
|
||||
var sink = ShaderMod.get().getQuadEmitter(size, TileEntityMonitorRenderer::getBuffer);
|
||||
var buffer = sink.buffer();
|
||||
|
||||
draw.accept(sink);
|
||||
@ -279,8 +279,8 @@ public class TileEntityMonitorRenderer implements BlockEntityRenderer<TileMonito
|
||||
return MonitorRenderer.VBO;
|
||||
}
|
||||
|
||||
if (ShaderMod.INSTANCE.isShaderMod()) {
|
||||
LOG.warn("Optifine is loaded, assuming shaders are being used. Falling back to VBO monitor renderer.");
|
||||
if (ShaderMod.get().isShaderMod()) {
|
||||
LOG.warn("A shader mod is loaded, assuming shaders are being used. Falling back to VBO monitor renderer.");
|
||||
return MonitorRenderer.VBO;
|
||||
}
|
||||
|
||||
|
@ -519,6 +519,7 @@ public class TileMonitor extends TileGeneric {
|
||||
}
|
||||
|
||||
public IPeripheral peripheral() {
|
||||
createServerMonitor();
|
||||
if (peripheral != null) return peripheral;
|
||||
return peripheral = new MonitorPeripheral(this);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user