mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2025-07-28 23:02:53 +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 org.jetbrains.annotations.ApiStatus;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.ServiceLoader;
|
import java.util.ServiceLoader;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@ -32,17 +30,15 @@ public final class Services {
|
|||||||
* @throws IllegalStateException When the service cannot be loaded.
|
* @throws IllegalStateException When the service cannot be loaded.
|
||||||
*/
|
*/
|
||||||
public static <T> T load(Class<T> klass) {
|
public static <T> T load(Class<T> klass) {
|
||||||
List<T> services = new ArrayList<>(1);
|
var services = ServiceLoader.load(klass).stream().toList();
|
||||||
for (var provider : ServiceLoader.load(klass)) services.add(provider);
|
return switch (services.size()) {
|
||||||
switch (services.size()) {
|
case 1 -> services.get(0).get();
|
||||||
case 1:
|
case 0 -> throw new IllegalStateException("Cannot find service for " + klass.getName());
|
||||||
return services.get(0);
|
default -> {
|
||||||
case 0:
|
var serviceTypes = services.stream().map(x -> x.type().getName()).collect(Collectors.joining(", "));
|
||||||
throw new IllegalStateException("Cannot find service for " + klass.getName());
|
|
||||||
default:
|
|
||||||
var serviceTypes = services.stream().map(x -> x.getClass().getName()).collect(Collectors.joining(", "));
|
|
||||||
throw new IllegalStateException("Multiple services for " + klass.getName() + ": " + serviceTypes);
|
throw new IllegalStateException("Multiple services for " + klass.getName() + ": " + serviceTypes);
|
||||||
}
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -3,8 +3,9 @@
|
|||||||
* Copyright Daniel Ratcliffe, 2011-2022. Do not distribute without permission.
|
* Copyright Daniel Ratcliffe, 2011-2022. Do not distribute without permission.
|
||||||
* Send enquiries to dratcliffe@gmail.com
|
* 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 com.mojang.blaze3d.vertex.VertexFormat;
|
||||||
import dan200.computercraft.client.render.RenderTypes;
|
import dan200.computercraft.client.render.RenderTypes;
|
||||||
import dan200.computercraft.client.render.text.DirectFixedWidthFontRenderer;
|
import dan200.computercraft.client.render.text.DirectFixedWidthFontRenderer;
|
||||||
@ -13,28 +14,20 @@ import net.irisshaders.iris.api.v0.IrisTextVertexSink;
|
|||||||
import net.minecraftforge.fml.ModList;
|
import net.minecraftforge.fml.ModList;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.function.IntFunction;
|
import java.util.function.IntFunction;
|
||||||
|
|
||||||
public class ShaderMod {
|
/**
|
||||||
public static final ShaderMod INSTANCE
|
* A {@link ShaderMod} for Oculus (the Forge Iris port).
|
||||||
= ModList.get().isLoaded("oculus") ? new IrisImpl()
|
*/
|
||||||
: new ShaderMod();
|
@AutoService(ShaderMod.Provider.class)
|
||||||
|
public class IrisShaderMod implements ShaderMod.Provider {
|
||||||
public boolean isShaderMod() {
|
@Override
|
||||||
return Optifine.isLoaded();
|
public Optional<ShaderMod> get() {
|
||||||
|
return ModList.get().isLoaded("oculus") ? Optional.of(new Impl()) : Optional.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isRenderingShadowPass() {
|
private static final class Impl extends ShaderMod {
|
||||||
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 {
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isRenderingShadowPass() {
|
public boolean isRenderingShadowPass() {
|
||||||
return IrisApi.getInstance().isRenderingShadowPass();
|
return IrisApi.getInstance().isRenderingShadowPass();
|
@ -3,7 +3,7 @@
|
|||||||
* Copyright Daniel Ratcliffe, 2011-2022. Do not distribute without permission.
|
* Copyright Daniel Ratcliffe, 2011-2022. Do not distribute without permission.
|
||||||
* Send enquiries to dratcliffe@gmail.com
|
* Send enquiries to dratcliffe@gmail.com
|
||||||
*/
|
*/
|
||||||
package dan200.computercraft.shared.integration;
|
package dan200.computercraft.client.integration;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Detect whether Optifine is installed.
|
* 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.Matrix4f;
|
||||||
import com.mojang.math.Vector3f;
|
import com.mojang.math.Vector3f;
|
||||||
import dan200.computercraft.client.FrameInfo;
|
import dan200.computercraft.client.FrameInfo;
|
||||||
|
import dan200.computercraft.client.integration.ShaderMod;
|
||||||
import dan200.computercraft.client.render.monitor.MonitorRenderState;
|
import dan200.computercraft.client.render.monitor.MonitorRenderState;
|
||||||
import dan200.computercraft.client.render.text.DirectFixedWidthFontRenderer;
|
import dan200.computercraft.client.render.text.DirectFixedWidthFontRenderer;
|
||||||
import dan200.computercraft.client.render.text.FixedWidthFontRenderer;
|
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.client.util.DirectVertexBuffer;
|
||||||
import dan200.computercraft.core.terminal.Terminal;
|
import dan200.computercraft.core.terminal.Terminal;
|
||||||
import dan200.computercraft.shared.config.Config;
|
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.ClientMonitor;
|
||||||
import dan200.computercraft.shared.peripheral.monitor.MonitorRenderer;
|
import dan200.computercraft.shared.peripheral.monitor.MonitorRenderer;
|
||||||
import dan200.computercraft.shared.peripheral.monitor.TileMonitor;
|
import dan200.computercraft.shared.peripheral.monitor.TileMonitor;
|
||||||
@ -112,7 +112,7 @@ public class TileEntityMonitorRenderer implements BlockEntityRenderer<TileMonito
|
|||||||
|
|
||||||
// Draw the contents
|
// Draw the contents
|
||||||
var terminal = originTerminal.getTerminal();
|
var terminal = originTerminal.getTerminal();
|
||||||
if (terminal != null && !ShaderMod.INSTANCE.isRenderingShadowPass()) {
|
if (terminal != null && !ShaderMod.get().isRenderingShadowPass()) {
|
||||||
// Draw a terminal
|
// Draw a terminal
|
||||||
int width = terminal.getWidth(), height = terminal.getHeight();
|
int width = terminal.getWidth(), height = terminal.getHeight();
|
||||||
int pixelWidth = width * FONT_WIDTH, pixelHeight = height * FONT_HEIGHT;
|
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) {
|
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();
|
var buffer = sink.buffer();
|
||||||
|
|
||||||
draw.accept(sink);
|
draw.accept(sink);
|
||||||
@ -279,8 +279,8 @@ public class TileEntityMonitorRenderer implements BlockEntityRenderer<TileMonito
|
|||||||
return MonitorRenderer.VBO;
|
return MonitorRenderer.VBO;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ShaderMod.INSTANCE.isShaderMod()) {
|
if (ShaderMod.get().isShaderMod()) {
|
||||||
LOG.warn("Optifine is loaded, assuming shaders are being used. Falling back to VBO monitor renderer.");
|
LOG.warn("A shader mod is loaded, assuming shaders are being used. Falling back to VBO monitor renderer.");
|
||||||
return MonitorRenderer.VBO;
|
return MonitorRenderer.VBO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -519,6 +519,7 @@ public class TileMonitor extends TileGeneric {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public IPeripheral peripheral() {
|
public IPeripheral peripheral() {
|
||||||
|
createServerMonitor();
|
||||||
if (peripheral != null) return peripheral;
|
if (peripheral != null) return peripheral;
|
||||||
return peripheral = new MonitorPeripheral(this);
|
return peripheral = new MonitorPeripheral(this);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user