mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2025-01-23 11:27:54 +01:00
Merge remote-tracking branch 'upstream/1.20/dev' into feat/multi-loader-1.21
# Conflicts: # common/src/lib/java/dev/engine_room/flywheel/lib/util/ShadersModHandler.java # common/src/main/java/dev/engine_room/flywheel/impl/FlwImplXplat.java # common/src/main/java/dev/engine_room/flywheel/impl/compat/SodiumCompat.java # common/src/main/java/dev/engine_room/flywheel/impl/mixin/BlockEntityTypeMixin.java # fabric/build.gradle.kts # fabric/src/main/java/dev/engine_room/flywheel/impl/FlwImplXplatImpl.java # fabric/src/main/java/dev/engine_room/flywheel/impl/FlwLibXplatImpl.java # fabric/src/main/java/dev/engine_room/flywheel/impl/mixin/sodium/ChunkBuilderMeshingTaskMixin.java # fabric/src/main/java/dev/engine_room/flywheel/impl/mixin/sodium/SodiumMixinPlugin.java # fabric/src/main/resources/fabric.mod.json # forge/build.gradle.kts # forge/src/main/java/dev/engine_room/flywheel/impl/FlwImplXplatImpl.java # forge/src/main/java/dev/engine_room/flywheel/impl/FlwLibXplatImpl.java # forge/src/main/java/dev/engine_room/flywheel/impl/FlywheelForge.java # forge/src/main/resources/META-INF/neoforge.mods.toml # gradle.properties # gradle/wrapper/gradle-wrapper.properties
This commit is contained in:
commit
07e66bb299
35 changed files with 591 additions and 196 deletions
|
@ -23,16 +23,11 @@ open class PlatformExtension(val project: Project) {
|
||||||
|
|
||||||
var apiArtifactId: String = "flywheel-${project.name}-api-${project.property("artifact_minecraft_version")}"
|
var apiArtifactId: String = "flywheel-${project.name}-api-${project.property("artifact_minecraft_version")}"
|
||||||
|
|
||||||
private val sources = mutableSetOf<SourceSet>()
|
|
||||||
private val commonSourceSets: SourceSetContainer by lazy { commonProject.the<SourceSetContainer>() }
|
private val commonSourceSets: SourceSetContainer by lazy { commonProject.the<SourceSetContainer>() }
|
||||||
|
|
||||||
fun sources(vararg sourceSets: SourceSet) {
|
fun setupLoomMod(vararg sourceSets: SourceSet) {
|
||||||
this.sources.addAll(sourceSets)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setupLoomMod() {
|
|
||||||
project.the<LoomGradleExtensionAPI>().mods.maybeCreate("main").apply {
|
project.the<LoomGradleExtensionAPI>().mods.maybeCreate("main").apply {
|
||||||
sources.forEach(::sourceSet)
|
sourceSets.forEach(::sourceSet)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,13 +56,13 @@ open class PlatformExtension(val project: Project) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun compileWithCommonSourceSets() {
|
fun compileWithCommonSourceSets(vararg sourceSets: SourceSet) {
|
||||||
project.tasks.apply {
|
project.tasks.apply {
|
||||||
withType<JavaCompile>().configureEach {
|
withType<JavaCompile>().configureEach {
|
||||||
JarTaskSet.excludeDuplicatePackageInfos(this)
|
JarTaskSet.excludeDuplicatePackageInfos(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
sources.forEach {
|
sourceSets.forEach {
|
||||||
val commonSourceSet = commonSourceSets.named(it.name).get()
|
val commonSourceSet = commonSourceSets.named(it.name).get()
|
||||||
|
|
||||||
named<JavaCompile>(it.compileJavaTaskName).configure {
|
named<JavaCompile>(it.compileJavaTaskName).configure {
|
||||||
|
@ -80,10 +75,10 @@ open class PlatformExtension(val project: Project) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setupFatJar() {
|
fun setupFatJar(vararg sourceSets: SourceSet) {
|
||||||
project.tasks.apply {
|
project.tasks.apply {
|
||||||
val extraSourceSets = sources.filter { it.name != "main" }.toList()
|
val extraSourceSets = sourceSets.filter { it.name != "main" }.toList()
|
||||||
val commonSources = sources.map { commonSourceSets.named(it.name).get() }
|
val commonSources = sourceSets.map { commonSourceSets.named(it.name).get() }
|
||||||
|
|
||||||
named<Jar>("jar").configure {
|
named<Jar>("jar").configure {
|
||||||
extraSourceSets.forEach { from(it.output) }
|
extraSourceSets.forEach { from(it.output) }
|
||||||
|
|
|
@ -25,7 +25,7 @@ open class TransitiveSourceSetsExtension(private val project: Project) {
|
||||||
|
|
||||||
fun createCompileConfigurations() {
|
fun createCompileConfigurations() {
|
||||||
val configs = transitives.mapValues { (sourceSet, _) ->
|
val configs = transitives.mapValues { (sourceSet, _) ->
|
||||||
project.configurations.create("for${sourceSet.name.capitalize()}") {
|
project.configurations.create("for${sourceSet.name.replaceFirstChar { it.uppercase() }}") {
|
||||||
isCanBeConsumed = true
|
isCanBeConsumed = true
|
||||||
isCanBeResolved = false
|
isCanBeResolved = false
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,7 @@ open class TransitiveSourceSetsExtension(private val project: Project) {
|
||||||
|
|
||||||
fun createRuntimeConfigurations() {
|
fun createRuntimeConfigurations() {
|
||||||
val configs = transitives.mapValues { (sourceSet, _) ->
|
val configs = transitives.mapValues { (sourceSet, _) ->
|
||||||
project.configurations.create("run${sourceSet.name.capitalize()}") {
|
project.configurations.create("run${sourceSet.name.replaceFirstChar { it.uppercase() }}") {
|
||||||
isCanBeConsumed = true
|
isCanBeConsumed = true
|
||||||
isCanBeResolved = false
|
isCanBeResolved = false
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ plugins {
|
||||||
val api = sourceSets.create("api")
|
val api = sourceSets.create("api")
|
||||||
val lib = sourceSets.create("lib")
|
val lib = sourceSets.create("lib")
|
||||||
val backend = sourceSets.create("backend")
|
val backend = sourceSets.create("backend")
|
||||||
|
val stubs = sourceSets.create("stubs")
|
||||||
val main = sourceSets.getByName("main")
|
val main = sourceSets.getByName("main")
|
||||||
|
|
||||||
transitiveSourceSets {
|
transitiveSourceSets {
|
||||||
|
@ -25,8 +26,11 @@ transitiveSourceSets {
|
||||||
rootCompile()
|
rootCompile()
|
||||||
compile(api, lib)
|
compile(api, lib)
|
||||||
}
|
}
|
||||||
|
sourceSet(stubs) {
|
||||||
|
rootCompile()
|
||||||
|
}
|
||||||
sourceSet(main) {
|
sourceSet(main) {
|
||||||
compile(api, lib, backend)
|
compile(api, lib, backend, stubs)
|
||||||
}
|
}
|
||||||
sourceSet(sourceSets.getByName("test")) {
|
sourceSet(sourceSets.getByName("test")) {
|
||||||
implementation(api, lib, backend)
|
implementation(api, lib, backend)
|
||||||
|
@ -42,6 +46,7 @@ jarSets {
|
||||||
outgoing("commonApiOnly", api)
|
outgoing("commonApiOnly", api)
|
||||||
outgoing("commonLib", lib)
|
outgoing("commonLib", lib)
|
||||||
outgoing("commonBackend", backend)
|
outgoing("commonBackend", backend)
|
||||||
|
outgoing("commonStubs", stubs)
|
||||||
outgoing("commonImpl", main)
|
outgoing("commonImpl", main)
|
||||||
|
|
||||||
// For publishing.
|
// For publishing.
|
||||||
|
|
|
@ -9,7 +9,7 @@ import dev.engine_room.flywheel.backend.engine.indirect.IndirectDrawManager;
|
||||||
import dev.engine_room.flywheel.backend.engine.instancing.InstancedDrawManager;
|
import dev.engine_room.flywheel.backend.engine.instancing.InstancedDrawManager;
|
||||||
import dev.engine_room.flywheel.backend.gl.GlCompat;
|
import dev.engine_room.flywheel.backend.gl.GlCompat;
|
||||||
import dev.engine_room.flywheel.lib.backend.SimpleBackend;
|
import dev.engine_room.flywheel.lib.backend.SimpleBackend;
|
||||||
import dev.engine_room.flywheel.lib.util.ShadersModHandler;
|
import dev.engine_room.flywheel.lib.util.ShadersModHelper;
|
||||||
|
|
||||||
public final class Backends {
|
public final class Backends {
|
||||||
/**
|
/**
|
||||||
|
@ -18,7 +18,7 @@ public final class Backends {
|
||||||
public static final Backend INSTANCING = SimpleBackend.builder()
|
public static final Backend INSTANCING = SimpleBackend.builder()
|
||||||
.engineFactory(level -> new EngineImpl(level, new InstancedDrawManager(InstancingPrograms.get()), 256))
|
.engineFactory(level -> new EngineImpl(level, new InstancedDrawManager(InstancingPrograms.get()), 256))
|
||||||
.priority(500)
|
.priority(500)
|
||||||
.supported(() -> GlCompat.SUPPORTS_INSTANCING && InstancingPrograms.allLoaded() && !ShadersModHandler.isShaderPackInUse())
|
.supported(() -> GlCompat.SUPPORTS_INSTANCING && InstancingPrograms.allLoaded() && !ShadersModHelper.isShaderPackInUse())
|
||||||
.register(Flywheel.rl("instancing"));
|
.register(Flywheel.rl("instancing"));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -27,7 +27,7 @@ public final class Backends {
|
||||||
public static final Backend INDIRECT = SimpleBackend.builder()
|
public static final Backend INDIRECT = SimpleBackend.builder()
|
||||||
.engineFactory(level -> new EngineImpl(level, new IndirectDrawManager(IndirectPrograms.get()), 256))
|
.engineFactory(level -> new EngineImpl(level, new IndirectDrawManager(IndirectPrograms.get()), 256))
|
||||||
.priority(1000)
|
.priority(1000)
|
||||||
.supported(() -> GlCompat.SUPPORTS_INDIRECT && IndirectPrograms.allLoaded() && !ShadersModHandler.isShaderPackInUse())
|
.supported(() -> GlCompat.SUPPORTS_INDIRECT && IndirectPrograms.allLoaded() && !ShadersModHelper.isShaderPackInUse())
|
||||||
.register(Flywheel.rl("indirect"));
|
.register(Flywheel.rl("indirect"));
|
||||||
|
|
||||||
private Backends() {
|
private Backends() {
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
package dev.engine_room.flywheel.backend.compile;
|
package dev.engine_room.flywheel.backend.compile;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.WeakHashMap;
|
||||||
|
|
||||||
import dev.engine_room.flywheel.api.Flywheel;
|
import dev.engine_room.flywheel.api.Flywheel;
|
||||||
import dev.engine_room.flywheel.api.instance.InstanceType;
|
import dev.engine_room.flywheel.api.instance.InstanceType;
|
||||||
|
@ -30,7 +33,7 @@ import dev.engine_room.flywheel.lib.util.ResourceUtil;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
|
||||||
public final class PipelineCompiler {
|
public final class PipelineCompiler {
|
||||||
private static final List<PipelineCompiler> ALL = List.of();
|
private static final Set<PipelineCompiler> ALL = Collections.newSetFromMap(new WeakHashMap<>());
|
||||||
|
|
||||||
private static final Compile<PipelineProgramKey> PIPELINE = new Compile<>();
|
private static final Compile<PipelineProgramKey> PIPELINE = new Compile<>();
|
||||||
|
|
||||||
|
@ -44,6 +47,7 @@ public final class PipelineCompiler {
|
||||||
|
|
||||||
public PipelineCompiler(CompilationHarness<PipelineProgramKey> harness) {
|
public PipelineCompiler(CompilationHarness<PipelineProgramKey> harness) {
|
||||||
this.harness = harness;
|
this.harness = harness;
|
||||||
|
ALL.add(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public GlProgram get(InstanceType<?> instanceType, ContextShader contextShader, Material material) {
|
public GlProgram get(InstanceType<?> instanceType, ContextShader contextShader, Material material) {
|
||||||
|
@ -57,15 +61,12 @@ public final class PipelineCompiler {
|
||||||
MaterialShaderIndices.fogSources()
|
MaterialShaderIndices.fogSources()
|
||||||
.index(fog.source());
|
.index(fog.source());
|
||||||
|
|
||||||
boolean useCutout = cutout != CutoutShaders.OFF;
|
// Same thing for cutout.
|
||||||
|
// Add OFF to the index here anyway to ensure MaterialEncoder doesn't deleteAll at an inappropriate time.
|
||||||
|
MaterialShaderIndices.cutoutSources()
|
||||||
|
.index(cutout.source());
|
||||||
|
|
||||||
if (useCutout) {
|
return harness.get(new PipelineProgramKey(instanceType, contextShader, light, shaders, cutout != CutoutShaders.OFF, FrameUniforms.debugOn()));
|
||||||
// Same thing for cutout.
|
|
||||||
MaterialShaderIndices.cutoutSources()
|
|
||||||
.index(cutout.source());
|
|
||||||
}
|
|
||||||
|
|
||||||
return harness.get(new PipelineProgramKey(instanceType, contextShader, light, shaders, useCutout, FrameUniforms.debugOn()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void delete() {
|
public void delete() {
|
||||||
|
|
|
@ -24,4 +24,12 @@ public interface FlwLibLink {
|
||||||
void compileModelPart(ModelPart part, PoseStack.Pose pose, VertexConsumer consumer, int light, int overlay, int color);
|
void compileModelPart(ModelPart part, PoseStack.Pose pose, VertexConsumer consumer, int light, int overlay, int color);
|
||||||
|
|
||||||
Deque<PoseStack.Pose> getPoseStack(PoseStack stack);
|
Deque<PoseStack.Pose> getPoseStack(PoseStack stack);
|
||||||
|
|
||||||
|
boolean isIrisLoaded();
|
||||||
|
|
||||||
|
boolean isOptifineInstalled();
|
||||||
|
|
||||||
|
boolean isShaderPackInUse();
|
||||||
|
|
||||||
|
boolean isRenderingShadowPass();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,11 @@
|
||||||
package dev.engine_room.flywheel.lib.internal;
|
package dev.engine_room.flywheel.lib.internal;
|
||||||
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
import org.jetbrains.annotations.UnknownNullability;
|
import org.jetbrains.annotations.UnknownNullability;
|
||||||
|
|
||||||
import dev.engine_room.flywheel.api.internal.DependencyInjection;
|
import dev.engine_room.flywheel.api.internal.DependencyInjection;
|
||||||
import dev.engine_room.flywheel.lib.model.baked.BakedModelBuilder;
|
import dev.engine_room.flywheel.lib.model.baked.BakedModelBuilder;
|
||||||
import dev.engine_room.flywheel.lib.model.baked.BlockModelBuilder;
|
import dev.engine_room.flywheel.lib.model.baked.BlockModelBuilder;
|
||||||
import dev.engine_room.flywheel.lib.model.baked.MultiBlockModelBuilder;
|
import dev.engine_room.flywheel.lib.model.baked.MultiBlockModelBuilder;
|
||||||
import dev.engine_room.flywheel.lib.util.ShadersModHandler;
|
|
||||||
import net.minecraft.client.renderer.block.BlockRenderDispatcher;
|
import net.minecraft.client.renderer.block.BlockRenderDispatcher;
|
||||||
import net.minecraft.client.resources.model.BakedModel;
|
import net.minecraft.client.resources.model.BakedModel;
|
||||||
import net.minecraft.client.resources.model.ModelManager;
|
import net.minecraft.client.resources.model.ModelManager;
|
||||||
|
@ -29,7 +27,4 @@ public interface FlwLibXplat {
|
||||||
BlockModelBuilder createBlockModelBuilder(BlockState state);
|
BlockModelBuilder createBlockModelBuilder(BlockState state);
|
||||||
|
|
||||||
MultiBlockModelBuilder createMultiBlockModelBuilder(BlockAndTintGetter level, Iterable<BlockPos> positions);
|
MultiBlockModelBuilder createMultiBlockModelBuilder(BlockAndTintGetter level, Iterable<BlockPos> positions);
|
||||||
|
|
||||||
@Nullable
|
|
||||||
ShadersModHandler.InternalHandler createIrisHandler();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ package dev.engine_room.flywheel.lib.material;
|
||||||
import dev.engine_room.flywheel.api.Flywheel;
|
import dev.engine_room.flywheel.api.Flywheel;
|
||||||
import dev.engine_room.flywheel.api.material.LightShader;
|
import dev.engine_room.flywheel.api.material.LightShader;
|
||||||
|
|
||||||
public class LightShaders {
|
public final class LightShaders {
|
||||||
public static final LightShader SMOOTH_WHEN_EMBEDDED = new SimpleLightShader(Flywheel.rl("light/smooth_when_embedded.glsl"));
|
public static final LightShader SMOOTH_WHEN_EMBEDDED = new SimpleLightShader(Flywheel.rl("light/smooth_when_embedded.glsl"));
|
||||||
public static final LightShader SMOOTH = new SimpleLightShader(Flywheel.rl("light/smooth.glsl"));
|
public static final LightShader SMOOTH = new SimpleLightShader(Flywheel.rl("light/smooth.glsl"));
|
||||||
public static final LightShader FLAT = new SimpleLightShader(Flywheel.rl("light/flat.glsl"));
|
public static final LightShader FLAT = new SimpleLightShader(Flywheel.rl("light/flat.glsl"));
|
||||||
|
|
|
@ -178,6 +178,7 @@ public class SimpleMaterial implements Material {
|
||||||
shaders = material.shaders();
|
shaders = material.shaders();
|
||||||
fog = material.fog();
|
fog = material.fog();
|
||||||
cutout = material.cutout();
|
cutout = material.cutout();
|
||||||
|
light = material.light();
|
||||||
texture = material.texture();
|
texture = material.texture();
|
||||||
blur = material.blur();
|
blur = material.blur();
|
||||||
mipmap = material.mipmap();
|
mipmap = material.mipmap();
|
||||||
|
|
|
@ -1,128 +0,0 @@
|
||||||
package dev.engine_room.flywheel.lib.util;
|
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.util.function.BooleanSupplier;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.ApiStatus;
|
|
||||||
|
|
||||||
import dev.engine_room.flywheel.lib.internal.FlwLibLink;
|
|
||||||
import dev.engine_room.flywheel.lib.internal.FlwLibXplat;
|
|
||||||
|
|
||||||
public final class ShadersModHandler {
|
|
||||||
private static final String OPTIFINE_ROOT_PACKAGE = "net.optifine";
|
|
||||||
|
|
||||||
private static final boolean IS_IRIS_LOADED;
|
|
||||||
private static final boolean IS_OPTIFINE_INSTALLED;
|
|
||||||
private static final InternalHandler INTERNAL_HANDLER;
|
|
||||||
|
|
||||||
static {
|
|
||||||
InternalHandler irisHandler = FlwLibXplat.INSTANCE
|
|
||||||
.createIrisHandler();
|
|
||||||
IS_IRIS_LOADED = irisHandler != null;
|
|
||||||
|
|
||||||
Package optifinePackage = Package.getPackage(OPTIFINE_ROOT_PACKAGE);
|
|
||||||
IS_OPTIFINE_INSTALLED = optifinePackage != null;
|
|
||||||
|
|
||||||
// OptiFine and Iris are assumed to be mutually exclusive
|
|
||||||
|
|
||||||
if (IS_IRIS_LOADED) {
|
|
||||||
FlwLibLink.INSTANCE.getLogger().debug("Iris detected.");
|
|
||||||
INTERNAL_HANDLER = irisHandler;
|
|
||||||
} else if (IS_OPTIFINE_INSTALLED) {
|
|
||||||
FlwLibLink.INSTANCE.getLogger().debug("OptiFine detected.");
|
|
||||||
INTERNAL_HANDLER = new OptifineHandler();
|
|
||||||
} else {
|
|
||||||
FlwLibLink.INSTANCE.getLogger().debug("No shaders mod detected.");
|
|
||||||
INTERNAL_HANDLER = new InternalHandler() {};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private ShadersModHandler() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isIrisLoaded() {
|
|
||||||
return IS_IRIS_LOADED;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isOptifineInstalled() {
|
|
||||||
return IS_OPTIFINE_INSTALLED;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isShaderPackInUse() {
|
|
||||||
return INTERNAL_HANDLER.isShaderPackInUse();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isRenderingShadowPass() {
|
|
||||||
return INTERNAL_HANDLER.isRenderingShadowPass();
|
|
||||||
}
|
|
||||||
|
|
||||||
@ApiStatus.Internal
|
|
||||||
public static void init() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@ApiStatus.Internal
|
|
||||||
public interface InternalHandler {
|
|
||||||
default boolean isShaderPackInUse() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
default boolean isRenderingShadowPass() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// evil reflection
|
|
||||||
private static class OptifineHandler implements InternalHandler {
|
|
||||||
private final BooleanSupplier shadersEnabledSupplier;
|
|
||||||
private final BooleanSupplier shadowPassSupplier;
|
|
||||||
|
|
||||||
private OptifineHandler() {
|
|
||||||
shadersEnabledSupplier = createShadersEnabledSupplier();
|
|
||||||
shadowPassSupplier = createShadowPassSupplier();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isShaderPackInUse() {
|
|
||||||
return shadersEnabledSupplier.getAsBoolean();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isRenderingShadowPass() {
|
|
||||||
return shadowPassSupplier.getAsBoolean();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static BooleanSupplier createShadersEnabledSupplier() {
|
|
||||||
try {
|
|
||||||
Class<?> ofShaders = Class.forName("net.optifine.shaders.Shaders");
|
|
||||||
Field field = ofShaders.getDeclaredField("shaderPackLoaded");
|
|
||||||
field.setAccessible(true);
|
|
||||||
return () -> {
|
|
||||||
try {
|
|
||||||
return field.getBoolean(null);
|
|
||||||
} catch (IllegalAccessException e) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
} catch (Exception e) {
|
|
||||||
return () -> false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static BooleanSupplier createShadowPassSupplier() {
|
|
||||||
try {
|
|
||||||
Class<?> ofShaders = Class.forName("net.optifine.shaders.Shaders");
|
|
||||||
Field field = ofShaders.getDeclaredField("isShadowPass");
|
|
||||||
field.setAccessible(true);
|
|
||||||
return () -> {
|
|
||||||
try {
|
|
||||||
return field.getBoolean(null);
|
|
||||||
} catch (IllegalAccessException e) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
} catch (Exception e) {
|
|
||||||
return () -> false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
package dev.engine_room.flywheel.lib.util;
|
||||||
|
|
||||||
|
import dev.engine_room.flywheel.lib.internal.FlwLibLink;
|
||||||
|
|
||||||
|
public final class ShadersModHelper {
|
||||||
|
public static final boolean IS_IRIS_LOADED = FlwLibLink.INSTANCE.isIrisLoaded();
|
||||||
|
public static final boolean IS_OPTIFINE_INSTALLED = FlwLibLink.INSTANCE.isOptifineInstalled();
|
||||||
|
|
||||||
|
private ShadersModHelper() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isShaderPackInUse() {
|
||||||
|
return FlwLibLink.INSTANCE.isShaderPackInUse();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isRenderingShadowPass() {
|
||||||
|
return FlwLibLink.INSTANCE.isRenderingShadowPass();
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,7 +6,6 @@ import org.slf4j.LoggerFactory;
|
||||||
import dev.engine_room.flywheel.api.Flywheel;
|
import dev.engine_room.flywheel.api.Flywheel;
|
||||||
import dev.engine_room.flywheel.backend.FlwBackend;
|
import dev.engine_room.flywheel.backend.FlwBackend;
|
||||||
import dev.engine_room.flywheel.impl.registry.IdRegistryImpl;
|
import dev.engine_room.flywheel.impl.registry.IdRegistryImpl;
|
||||||
import dev.engine_room.flywheel.lib.util.ShadersModHandler;
|
|
||||||
import dev.engine_room.flywheel.vanilla.VanillaVisuals;
|
import dev.engine_room.flywheel.vanilla.VanillaVisuals;
|
||||||
|
|
||||||
public final class FlwImpl {
|
public final class FlwImpl {
|
||||||
|
@ -21,7 +20,6 @@ public final class FlwImpl {
|
||||||
BackendManagerImpl.init();
|
BackendManagerImpl.init();
|
||||||
|
|
||||||
// lib
|
// lib
|
||||||
ShadersModHandler.init();
|
|
||||||
|
|
||||||
// backend
|
// backend
|
||||||
FlwBackend.init(FlwConfig.INSTANCE.backendConfig());
|
FlwBackend.init(FlwConfig.INSTANCE.backendConfig());
|
||||||
|
|
|
@ -6,11 +6,15 @@ import net.minecraft.client.multiplayer.ClientLevel;
|
||||||
public interface FlwImplXplat {
|
public interface FlwImplXplat {
|
||||||
FlwImplXplat INSTANCE = DependencyInjection.load(FlwImplXplat.class, "dev.engine_room.flywheel.impl.FlwImplXplatImpl");
|
FlwImplXplat INSTANCE = DependencyInjection.load(FlwImplXplat.class, "dev.engine_room.flywheel.impl.FlwImplXplatImpl");
|
||||||
|
|
||||||
boolean getModLoaded(String modId);
|
boolean isModLoaded(String modId);
|
||||||
|
|
||||||
void dispatchReloadLevelRendererEvent(ClientLevel level);
|
void dispatchReloadLevelRendererEvent(ClientLevel level);
|
||||||
|
|
||||||
String getVersionStr();
|
String getVersionStr();
|
||||||
|
|
||||||
FlwConfig getConfig();
|
FlwConfig getConfig();
|
||||||
|
|
||||||
|
boolean useSodium0_6Compat();
|
||||||
|
|
||||||
|
boolean useIrisCompat();
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,8 @@ import org.slf4j.Logger;
|
||||||
import com.mojang.blaze3d.vertex.PoseStack;
|
import com.mojang.blaze3d.vertex.PoseStack;
|
||||||
import com.mojang.blaze3d.vertex.VertexConsumer;
|
import com.mojang.blaze3d.vertex.VertexConsumer;
|
||||||
|
|
||||||
|
import dev.engine_room.flywheel.impl.compat.IrisCompat;
|
||||||
|
import dev.engine_room.flywheel.impl.compat.OptifineCompat;
|
||||||
import dev.engine_room.flywheel.impl.extension.PoseStackExtension;
|
import dev.engine_room.flywheel.impl.extension.PoseStackExtension;
|
||||||
import dev.engine_room.flywheel.impl.mixin.ModelPartAccessor;
|
import dev.engine_room.flywheel.impl.mixin.ModelPartAccessor;
|
||||||
import dev.engine_room.flywheel.impl.mixin.PoseStackAccessor;
|
import dev.engine_room.flywheel.impl.mixin.PoseStackAccessor;
|
||||||
|
@ -40,4 +42,36 @@ public class FlwLibLinkImpl implements FlwLibLink {
|
||||||
public Deque<PoseStack.Pose> getPoseStack(PoseStack stack) {
|
public Deque<PoseStack.Pose> getPoseStack(PoseStack stack) {
|
||||||
return ((PoseStackAccessor) stack).flywheel$getPoseStack();
|
return ((PoseStackAccessor) stack).flywheel$getPoseStack();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isIrisLoaded() {
|
||||||
|
return IrisCompat.ACTIVE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isOptifineInstalled() {
|
||||||
|
return OptifineCompat.IS_INSTALLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isShaderPackInUse() {
|
||||||
|
if (IrisCompat.ACTIVE) {
|
||||||
|
return IrisCompat.isShaderPackInUse();
|
||||||
|
} else if (OptifineCompat.IS_INSTALLED) {
|
||||||
|
return OptifineCompat.isShaderPackInUse();
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isRenderingShadowPass() {
|
||||||
|
if (IrisCompat.ACTIVE) {
|
||||||
|
return IrisCompat.isRenderingShadowPass();
|
||||||
|
} else if (OptifineCompat.IS_INSTALLED) {
|
||||||
|
return OptifineCompat.isRenderingShadowPass();
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
package dev.engine_room.flywheel.impl.compat;
|
||||||
|
|
||||||
|
import dev.engine_room.flywheel.impl.FlwImplXplat;
|
||||||
|
|
||||||
|
public enum CompatMod {
|
||||||
|
EMBEDDIUM("embeddium"),
|
||||||
|
IRIS("iris"),
|
||||||
|
OCULUS("oculus"),
|
||||||
|
SODIUM("sodium");
|
||||||
|
|
||||||
|
public final String id;
|
||||||
|
public final boolean isLoaded;
|
||||||
|
|
||||||
|
CompatMod(String modId) {
|
||||||
|
id = modId;
|
||||||
|
isLoaded = FlwImplXplat.INSTANCE.isModLoaded(modId);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
package dev.engine_room.flywheel.impl.compat;
|
||||||
|
|
||||||
|
import dev.engine_room.flywheel.impl.FlwImpl;
|
||||||
|
import dev.engine_room.flywheel.impl.FlwImplXplat;
|
||||||
|
import net.irisshaders.iris.api.v0.IrisApi;
|
||||||
|
|
||||||
|
public final class IrisCompat {
|
||||||
|
public static final boolean ACTIVE = FlwImplXplat.INSTANCE.useIrisCompat();
|
||||||
|
|
||||||
|
static {
|
||||||
|
if (ACTIVE) {
|
||||||
|
FlwImpl.LOGGER.debug("Detected Iris");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private IrisCompat() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isShaderPackInUse() {
|
||||||
|
if (!ACTIVE) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Internals.isShaderPackInUse();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isRenderingShadowPass() {
|
||||||
|
if (!ACTIVE) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Internals.isRenderingShadowPass();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final class Internals {
|
||||||
|
static boolean isShaderPackInUse() {
|
||||||
|
return IrisApi.getInstance()
|
||||||
|
.isShaderPackInUse();
|
||||||
|
}
|
||||||
|
|
||||||
|
static boolean isRenderingShadowPass() {
|
||||||
|
return IrisApi.getInstance()
|
||||||
|
.isRenderingShadowPass();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,73 @@
|
||||||
|
package dev.engine_room.flywheel.impl.compat;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import dev.engine_room.flywheel.impl.FlwImpl;
|
||||||
|
|
||||||
|
public final class OptifineCompat {
|
||||||
|
private static final String OPTIFINE_ROOT_PACKAGE = "net.optifine";
|
||||||
|
|
||||||
|
public static final boolean IS_INSTALLED;
|
||||||
|
@Nullable
|
||||||
|
private static final Field SHADER_PACK_LOADED_FIELD;
|
||||||
|
@Nullable
|
||||||
|
private static final Field IS_SHADOW_PASS_FIELD;
|
||||||
|
|
||||||
|
static {
|
||||||
|
Field shaderPackLoadedField = null;
|
||||||
|
Field isShadowPassField = null;
|
||||||
|
|
||||||
|
Package optifinePackage = Package.getPackage(OPTIFINE_ROOT_PACKAGE);
|
||||||
|
IS_INSTALLED = optifinePackage != null;
|
||||||
|
|
||||||
|
if (IS_INSTALLED) {
|
||||||
|
try {
|
||||||
|
Class<?> shadersClass = Class.forName("net.optifine.shaders.Shaders");
|
||||||
|
shaderPackLoadedField = shadersClass.getDeclaredField("shaderPackLoaded");
|
||||||
|
shaderPackLoadedField.setAccessible(true);
|
||||||
|
isShadowPassField = shadersClass.getDeclaredField("isShadowPass");
|
||||||
|
isShadowPassField.setAccessible(true);
|
||||||
|
} catch (Exception e) {
|
||||||
|
FlwImpl.LOGGER.debug("Failed to access OptiFine internals", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SHADER_PACK_LOADED_FIELD = shaderPackLoadedField;
|
||||||
|
IS_SHADOW_PASS_FIELD = isShadowPassField;
|
||||||
|
}
|
||||||
|
|
||||||
|
static {
|
||||||
|
if (IS_INSTALLED) {
|
||||||
|
FlwImpl.LOGGER.debug("Detected OptiFine");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private OptifineCompat() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isShaderPackInUse() {
|
||||||
|
if (SHADER_PACK_LOADED_FIELD == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return SHADER_PACK_LOADED_FIELD.getBoolean(null);
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isRenderingShadowPass() {
|
||||||
|
if (IS_SHADOW_PASS_FIELD == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return IS_SHADOW_PASS_FIELD.getBoolean(null);
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,20 +1,61 @@
|
||||||
package dev.engine_room.flywheel.impl.compat;
|
package dev.engine_room.flywheel.impl.compat;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import dev.engine_room.flywheel.api.visualization.BlockEntityVisualizer;
|
||||||
|
import dev.engine_room.flywheel.impl.FlwImpl;
|
||||||
|
import dev.engine_room.flywheel.impl.FlwImplXplat;
|
||||||
import dev.engine_room.flywheel.lib.visualization.VisualizationHelper;
|
import dev.engine_room.flywheel.lib.visualization.VisualizationHelper;
|
||||||
import net.caffeinemc.mods.sodium.api.blockentity.BlockEntityRenderHandler;
|
import net.caffeinemc.mods.sodium.api.blockentity.BlockEntityRenderHandler;
|
||||||
import net.caffeinemc.mods.sodium.api.blockentity.BlockEntityRenderPredicate;
|
import net.caffeinemc.mods.sodium.api.blockentity.BlockEntityRenderPredicate;
|
||||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||||
|
|
||||||
@SuppressWarnings({"unchecked", "UnstableApiUsage"})
|
public final class SodiumCompat {
|
||||||
public class SodiumCompat {
|
public static final boolean USE_0_6_COMPAT = FlwImplXplat.INSTANCE.useSodium0_6Compat();
|
||||||
public static <T extends BlockEntity> Object forBlockEntityType(BlockEntityType<T> type) {
|
|
||||||
BlockEntityRenderPredicate<T> predicate = (getter, pos, be) -> VisualizationHelper.tryAddBlockEntity(be);
|
static {
|
||||||
BlockEntityRenderHandler.instance().addRenderPredicate(type, predicate);
|
if (USE_0_6_COMPAT) {
|
||||||
|
FlwImpl.LOGGER.debug("Detected Sodium 0.6");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private SodiumCompat() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public static <T extends BlockEntity> Object onSetBlockEntityVisualizer(BlockEntityType<T> type, @Nullable BlockEntityVisualizer<? super T> oldVisualizer, @Nullable BlockEntityVisualizer<? super T> newVisualizer, @Nullable Object predicate) {
|
||||||
|
if (!USE_0_6_COMPAT) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (oldVisualizer == null && newVisualizer != null) {
|
||||||
|
if (predicate != null) {
|
||||||
|
throw new IllegalArgumentException("Sodium predicate must be null when old visualizer is null");
|
||||||
|
}
|
||||||
|
|
||||||
|
return Internals.addPredicate(type);
|
||||||
|
} else if (oldVisualizer != null && newVisualizer == null) {
|
||||||
|
if (predicate == null) {
|
||||||
|
throw new IllegalArgumentException("Sodium predicate must not be null when old visualizer is not null");
|
||||||
|
}
|
||||||
|
|
||||||
|
Internals.removePredicate(type, predicate);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return predicate;
|
return predicate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T extends BlockEntity> void removePredicate(BlockEntityType<T> type, Object predicate) {
|
private static final class Internals {
|
||||||
BlockEntityRenderHandler.instance().removeRenderPredicate(type, (BlockEntityRenderPredicate<T>) predicate);
|
static <T extends BlockEntity> Object addPredicate(BlockEntityType<T> type) {
|
||||||
|
BlockEntityRenderPredicate<T> predicate = (getter, pos, be) -> VisualizationHelper.tryAddBlockEntity(be);
|
||||||
|
BlockEntityRenderHandler.instance().addRenderPredicate(type, predicate);
|
||||||
|
return predicate;
|
||||||
|
}
|
||||||
|
|
||||||
|
static <T extends BlockEntity> void removePredicate(BlockEntityType<T> type, Object predicate) {
|
||||||
|
BlockEntityRenderHandler.instance().removeRenderPredicate(type, (BlockEntityRenderPredicate<T>) predicate);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,13 +29,10 @@ abstract class BlockEntityTypeMixin<T extends BlockEntity> implements BlockEntit
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void flywheel$setVisualizer(@Nullable BlockEntityVisualizer<? super T> visualizer) {
|
public void flywheel$setVisualizer(@Nullable BlockEntityVisualizer<? super T> visualizer) {
|
||||||
if (CompatMods.SODIUM.isLoaded) {
|
if (SodiumCompat.USE_0_6_COMPAT) {
|
||||||
if (flywheel$visualizer == null && visualizer != null) {
|
flywheel$sodiumPredicate = SodiumCompat.onSetBlockEntityVisualizer((BlockEntityType<T>) (Object) this, flywheel$visualizer, visualizer, flywheel$sodiumPredicate);
|
||||||
flywheel$sodiumPredicate = SodiumCompat.forBlockEntityType((BlockEntityType<?>) (Object) this);
|
|
||||||
} else if (flywheel$visualizer != null && visualizer == null && flywheel$sodiumPredicate != null) {
|
|
||||||
SodiumCompat.removePredicate((BlockEntityType<?>) (Object) this, flywheel$sodiumPredicate);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
this.flywheel$visualizer = visualizer;
|
|
||||||
|
flywheel$visualizer = visualizer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ import net.minecraft.world.entity.EntityType;
|
||||||
@Mixin(EntityType.class)
|
@Mixin(EntityType.class)
|
||||||
abstract class EntityTypeMixin<T extends Entity> implements EntityTypeExtension<T> {
|
abstract class EntityTypeMixin<T extends Entity> implements EntityTypeExtension<T> {
|
||||||
@Unique
|
@Unique
|
||||||
|
@Nullable
|
||||||
private EntityVisualizer<? super T> flywheel$visualizer;
|
private EntityVisualizer<? super T> flywheel$visualizer;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -22,6 +23,6 @@ abstract class EntityTypeMixin<T extends Entity> implements EntityTypeExtension<
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void flywheel$setVisualizer(@Nullable EntityVisualizer<? super T> visualizer) {
|
public void flywheel$setVisualizer(@Nullable EntityVisualizer<? super T> visualizer) {
|
||||||
this.flywheel$visualizer = visualizer;
|
flywheel$visualizer = visualizer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
// https://github.com/CaffeineMC/sodium-fabric/blob/e7643f4544f61180ed2f0ff4952d7daa2c1feaf4/common/src/api/java/net/caffeinemc/mods/sodium/api/blockentity/BlockEntityRenderHandler.java
|
||||||
|
// PolyForm Shield License 1.0.0
|
||||||
|
|
||||||
|
package net.caffeinemc.mods.sodium.api.blockentity;
|
||||||
|
|
||||||
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
|
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||||
|
import org.jetbrains.annotations.ApiStatus;
|
||||||
|
|
||||||
|
@ApiStatus.Experimental
|
||||||
|
@ApiStatus.AvailableSince("0.6.0")
|
||||||
|
public interface BlockEntityRenderHandler {
|
||||||
|
BlockEntityRenderHandler INSTANCE = null;
|
||||||
|
|
||||||
|
static BlockEntityRenderHandler instance() {
|
||||||
|
return INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a predicate to determine if a block entity should be rendered.
|
||||||
|
*
|
||||||
|
* <p>Upon chunk bake, block entities of the given type will have {@code shouldRender} evaluated.
|
||||||
|
* <br>If <b>all predicates</b> returns {@code true} (and the block entity has a renderer), the block entity will be
|
||||||
|
* added to the chunk for future rendering.</p>
|
||||||
|
* @param type The block entity type to associate the given predicate with.
|
||||||
|
* @param shouldRender The predicate for the block entity to evaluate.
|
||||||
|
*/
|
||||||
|
<T extends BlockEntity> void addRenderPredicate(BlockEntityType<T> type, BlockEntityRenderPredicate<T> shouldRender);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes a predicate added by {@code addRenderPredicate}. <b>It must be the same object that was added.</b>
|
||||||
|
*
|
||||||
|
* @param type The block entity type to associate the given predicate with.
|
||||||
|
* @param shouldRender The predicate to remove.
|
||||||
|
* @return If the predicate existed and was removed.
|
||||||
|
*/
|
||||||
|
<T extends BlockEntity> boolean removeRenderPredicate(BlockEntityType<T> type, BlockEntityRenderPredicate<T> shouldRender);
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
// https://github.com/CaffeineMC/sodium-fabric/blob/e7643f4544f61180ed2f0ff4952d7daa2c1feaf4/common/src/api/java/net/caffeinemc/mods/sodium/api/blockentity/BlockEntityRenderPredicate.java
|
||||||
|
// PolyForm Shield License 1.0.0
|
||||||
|
|
||||||
|
package net.caffeinemc.mods.sodium.api.blockentity;
|
||||||
|
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.world.level.BlockGetter;
|
||||||
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
|
import org.jetbrains.annotations.ApiStatus;
|
||||||
|
|
||||||
|
@ApiStatus.Experimental
|
||||||
|
@ApiStatus.AvailableSince("0.6.0")
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface BlockEntityRenderPredicate<T extends BlockEntity> {
|
||||||
|
boolean shouldRender(BlockGetter blockGetter, BlockPos blockPos, T entity);
|
||||||
|
}
|
114
common/src/stubs/java/net/irisshaders/iris/api/v0/IrisApi.java
Normal file
114
common/src/stubs/java/net/irisshaders/iris/api/v0/IrisApi.java
Normal file
|
@ -0,0 +1,114 @@
|
||||||
|
// https://github.com/IrisShaders/Iris/blob/20be7fc1ff8a48048cb4eb787e1299782bb1caa4/src/main/java/net/irisshaders/iris/api/v0/IrisApi.java
|
||||||
|
// GNU Lesser General Public License v3.0
|
||||||
|
|
||||||
|
package net.irisshaders.iris.api.v0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The entry point to the Iris API, major version 0. This is currently the latest
|
||||||
|
* version of the API.
|
||||||
|
*
|
||||||
|
* To access the API, use {@link #getInstance()}.
|
||||||
|
*/
|
||||||
|
public interface IrisApi {
|
||||||
|
/**
|
||||||
|
* @since API v0.0
|
||||||
|
*/
|
||||||
|
static IrisApi getInstance() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the minor revision of this API. This is incremented when
|
||||||
|
* new methods are added without breaking API. Mods can check this
|
||||||
|
* if they wish to check whether given API calls are available on
|
||||||
|
* the currently installed Iris version.
|
||||||
|
*
|
||||||
|
* @return The current minor revision. Currently, revision 2.
|
||||||
|
*/
|
||||||
|
int getMinorApiRevision();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether a shader pack is currently in use and being used
|
||||||
|
* for rendering. If there is no shader pack enabled or a shader
|
||||||
|
* pack failed to compile and is therefore not in use, this will
|
||||||
|
* return false.
|
||||||
|
*
|
||||||
|
* <p>Mods that need to enable custom workarounds for shaders
|
||||||
|
* should use this method.
|
||||||
|
*
|
||||||
|
* @return Whether shaders are being used for rendering.
|
||||||
|
* @since {@link #getMinorApiRevision() API v0.0}
|
||||||
|
*/
|
||||||
|
boolean isShaderPackInUse();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether the shadow pass is currently being rendered.
|
||||||
|
*
|
||||||
|
* <p>Generally, mods won't need to call this function for much.
|
||||||
|
* Mods should be fine with things being rendered multiple times
|
||||||
|
* each frame from different camera perspectives. Often, there's
|
||||||
|
* a better approach to fixing bugs than calling this function.
|
||||||
|
*
|
||||||
|
* <p>Pretty much the main legitimate use for this function that
|
||||||
|
* I've seen is in a mod like Immersive Portals, where it has
|
||||||
|
* very custom culling that doesn't work when the Iris shadow
|
||||||
|
* pass is active.
|
||||||
|
*
|
||||||
|
* <p>Naturally, this function can only return true if
|
||||||
|
* {@link #isShaderPackInUse()} returns true.
|
||||||
|
*
|
||||||
|
* @return Whether Iris is currently rendering the shadow pass.
|
||||||
|
* @since API v0.0
|
||||||
|
*/
|
||||||
|
boolean isRenderingShadowPass();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Opens the main Iris GUI screen. It's up to Iris to decide
|
||||||
|
* what this screen is, but generally this is the shader selection
|
||||||
|
* screen.
|
||||||
|
*
|
||||||
|
* This method takes and returns Objects instead of any concrete
|
||||||
|
* Minecraft screen class to avoid referencing Minecraft classes.
|
||||||
|
* Nevertheless, the passed parent must either be null, or an
|
||||||
|
* object that is a subclass of the appropriate {@code Screen}
|
||||||
|
* class for the given Minecraft version.
|
||||||
|
*
|
||||||
|
* @param parent The parent screen, an instance of the appropriate
|
||||||
|
* {@code Screen} class.
|
||||||
|
* @return A {@code Screen} class for the main Iris GUI screen.
|
||||||
|
* @since API v0.0
|
||||||
|
*/
|
||||||
|
Object openMainIrisScreenObj(Object parent);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the language key of the main screen. Currently, this
|
||||||
|
* is "options.iris.shaderPackSelection".
|
||||||
|
*
|
||||||
|
* @return the language key, for use with {@code TranslatableText}
|
||||||
|
* / {@code TranslatableComponent}
|
||||||
|
* @since API v0.0
|
||||||
|
*/
|
||||||
|
String getMainScreenLanguageKey();
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * Gets a config object that can edit the Iris configuration.
|
||||||
|
// * @since API v0.0
|
||||||
|
// */
|
||||||
|
// IrisApiConfig getConfig();
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * Gets a text vertex sink to render into.
|
||||||
|
// * @param maxQuadCount Maximum amount of quads that will be rendered with this sink
|
||||||
|
// * @param bufferProvider An IntFunction that can provide a {@code ByteBuffer} with at minimum the bytes provided by the input parameter
|
||||||
|
// * @since API 0.1
|
||||||
|
// */
|
||||||
|
// IrisTextVertexSink createTextVertexSink(int maxQuadCount, IntFunction<ByteBuffer> bufferProvider);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the sun path rotation used by the current shader pack.
|
||||||
|
*
|
||||||
|
* @return The sun path rotation as specified by the shader pack, or 0 if no shader pack is in use.
|
||||||
|
* @since API v0.2
|
||||||
|
*/
|
||||||
|
float getSunPathRotation();
|
||||||
|
}
|
|
@ -10,6 +10,7 @@ plugins {
|
||||||
val api = sourceSets.create("api")
|
val api = sourceSets.create("api")
|
||||||
val lib = sourceSets.create("lib")
|
val lib = sourceSets.create("lib")
|
||||||
val backend = sourceSets.create("backend")
|
val backend = sourceSets.create("backend")
|
||||||
|
val stubs = sourceSets.create("stubs")
|
||||||
val main = sourceSets.getByName("main")
|
val main = sourceSets.getByName("main")
|
||||||
|
|
||||||
transitiveSourceSets {
|
transitiveSourceSets {
|
||||||
|
@ -26,7 +27,12 @@ transitiveSourceSets {
|
||||||
rootCompile()
|
rootCompile()
|
||||||
compile(api, lib)
|
compile(api, lib)
|
||||||
}
|
}
|
||||||
|
sourceSet(stubs) {
|
||||||
|
rootCompile()
|
||||||
|
}
|
||||||
sourceSet(main) {
|
sourceSet(main) {
|
||||||
|
// Don't want stubs at runtime
|
||||||
|
compile(stubs)
|
||||||
implementation(api, lib, backend)
|
implementation(api, lib, backend)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,11 +41,10 @@ transitiveSourceSets {
|
||||||
|
|
||||||
platform {
|
platform {
|
||||||
commonProject = project(":common")
|
commonProject = project(":common")
|
||||||
sources(api, lib, backend, main)
|
compileWithCommonSourceSets(api, lib, backend, stubs, main)
|
||||||
compileWithCommonSourceSets()
|
setupLoomMod(api, lib, backend, main)
|
||||||
setupLoomMod()
|
|
||||||
setupLoomRuns()
|
setupLoomRuns()
|
||||||
setupFatJar()
|
setupFatJar(api, lib, backend, main)
|
||||||
}
|
}
|
||||||
|
|
||||||
jarSets {
|
jarSets {
|
||||||
|
@ -78,5 +83,6 @@ dependencies {
|
||||||
"forApi"(project(path = ":common", configuration = "commonApiOnly"))
|
"forApi"(project(path = ":common", configuration = "commonApiOnly"))
|
||||||
"forLib"(project(path = ":common", configuration = "commonLib"))
|
"forLib"(project(path = ":common", configuration = "commonLib"))
|
||||||
"forBackend"(project(path = ":common", configuration = "commonBackend"))
|
"forBackend"(project(path = ":common", configuration = "commonBackend"))
|
||||||
|
"forStubs"(project(path = ":common", configuration = "commonStubs"))
|
||||||
"forMain"(project(path = ":common", configuration = "commonImpl"))
|
"forMain"(project(path = ":common", configuration = "commonImpl"))
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ import net.minecraft.client.multiplayer.ClientLevel;
|
||||||
|
|
||||||
public class FlwImplXplatImpl implements FlwImplXplat {
|
public class FlwImplXplatImpl implements FlwImplXplat {
|
||||||
@Override
|
@Override
|
||||||
public boolean getModLoaded(String modId) {
|
public boolean isModLoaded(String modId) {
|
||||||
return FabricLoader.getInstance().isModLoaded(modId);
|
return FabricLoader.getInstance().isModLoaded(modId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,4 +24,14 @@ public class FlwImplXplatImpl implements FlwImplXplat {
|
||||||
public FlwConfig getConfig() {
|
public FlwConfig getConfig() {
|
||||||
return FabricFlwConfig.INSTANCE;
|
return FabricFlwConfig.INSTANCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean useSodium0_6Compat() {
|
||||||
|
return FabricSodiumCompat.USE_0_6_COMPAT;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean useIrisCompat() {
|
||||||
|
return CompatMod.IRIS.isLoaded;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package dev.engine_room.flywheel.impl;
|
package dev.engine_room.flywheel.impl;
|
||||||
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
import org.jetbrains.annotations.UnknownNullability;
|
import org.jetbrains.annotations.UnknownNullability;
|
||||||
|
|
||||||
import dev.engine_room.flywheel.impl.compat.CompatMods;
|
import dev.engine_room.flywheel.impl.compat.CompatMods;
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
package dev.engine_room.flywheel.impl.compat;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import dev.engine_room.flywheel.impl.FlwImpl;
|
||||||
|
import net.fabricmc.loader.api.FabricLoader;
|
||||||
|
import net.fabricmc.loader.api.ModContainer;
|
||||||
|
import net.fabricmc.loader.api.Version;
|
||||||
|
import net.fabricmc.loader.api.VersionParsingException;
|
||||||
|
import net.fabricmc.loader.api.metadata.version.VersionPredicate;
|
||||||
|
|
||||||
|
public final class FabricSodiumCompat {
|
||||||
|
public static final boolean USE_0_5_COMPAT;
|
||||||
|
public static final boolean USE_0_6_COMPAT;
|
||||||
|
|
||||||
|
static {
|
||||||
|
boolean use0_5Compat = false;
|
||||||
|
boolean use0_6Compat = false;
|
||||||
|
|
||||||
|
Optional<ModContainer> optionalModContainer = FabricLoader.getInstance().getModContainer(CompatMod.SODIUM.id);
|
||||||
|
|
||||||
|
if (optionalModContainer.isPresent()) {
|
||||||
|
ModContainer modContainer = optionalModContainer.get();
|
||||||
|
Version sodiumVersion = modContainer.getMetadata().getVersion();
|
||||||
|
|
||||||
|
try {
|
||||||
|
VersionPredicate predicate0_5 = VersionPredicate.parse("~0.5.0");
|
||||||
|
VersionPredicate predicate0_6 = VersionPredicate.parse(">=0.6.0-beta.2");
|
||||||
|
use0_5Compat = predicate0_5.test(sodiumVersion);
|
||||||
|
use0_6Compat = predicate0_6.test(sodiumVersion);
|
||||||
|
} catch (VersionParsingException e) {
|
||||||
|
FlwImpl.LOGGER.debug("Failed to parse Sodium version predicates", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
USE_0_5_COMPAT = use0_5Compat;
|
||||||
|
USE_0_6_COMPAT = use0_6Compat;
|
||||||
|
}
|
||||||
|
|
||||||
|
static {
|
||||||
|
if (USE_0_5_COMPAT) {
|
||||||
|
FlwImpl.LOGGER.debug("Detected Sodium 0.5");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private FabricSodiumCompat() {
|
||||||
|
}
|
||||||
|
}
|
|
@ -28,6 +28,7 @@
|
||||||
],
|
],
|
||||||
"depends": {
|
"depends": {
|
||||||
"minecraft": "${minecraft_semver_version_range}",
|
"minecraft": "${minecraft_semver_version_range}",
|
||||||
|
"fabricloader": ">=0.15.0",
|
||||||
"fabric-api": "${fabric_api_version_range}"
|
"fabric-api": "${fabric_api_version_range}"
|
||||||
},
|
},
|
||||||
"breaks": {
|
"breaks": {
|
||||||
|
|
|
@ -10,6 +10,7 @@ plugins {
|
||||||
val api = sourceSets.create("api")
|
val api = sourceSets.create("api")
|
||||||
val lib = sourceSets.create("lib")
|
val lib = sourceSets.create("lib")
|
||||||
val backend = sourceSets.create("backend")
|
val backend = sourceSets.create("backend")
|
||||||
|
val stubs = sourceSets.create("stubs")
|
||||||
val main = sourceSets.getByName("main")
|
val main = sourceSets.getByName("main")
|
||||||
|
|
||||||
transitiveSourceSets {
|
transitiveSourceSets {
|
||||||
|
@ -26,8 +27,11 @@ transitiveSourceSets {
|
||||||
rootCompile()
|
rootCompile()
|
||||||
compile(api, lib)
|
compile(api, lib)
|
||||||
}
|
}
|
||||||
|
sourceSet(stubs) {
|
||||||
|
rootCompile()
|
||||||
|
}
|
||||||
sourceSet(main) {
|
sourceSet(main) {
|
||||||
compile(api, lib, backend)
|
compile(api, lib, backend, stubs)
|
||||||
}
|
}
|
||||||
|
|
||||||
createCompileConfigurations()
|
createCompileConfigurations()
|
||||||
|
@ -35,11 +39,10 @@ transitiveSourceSets {
|
||||||
|
|
||||||
platform {
|
platform {
|
||||||
commonProject = project(":common")
|
commonProject = project(":common")
|
||||||
sources(api, lib, backend, main)
|
compileWithCommonSourceSets(api, lib, backend, stubs, main)
|
||||||
compileWithCommonSourceSets()
|
setupLoomMod(api, lib, backend, main)
|
||||||
setupLoomMod()
|
|
||||||
setupLoomRuns()
|
setupLoomRuns()
|
||||||
setupFatJar()
|
setupFatJar(api, lib, backend, main)
|
||||||
}
|
}
|
||||||
|
|
||||||
jarSets {
|
jarSets {
|
||||||
|
@ -88,5 +91,6 @@ dependencies {
|
||||||
"forApi"(project(path = ":common", configuration = "commonApiOnly"))
|
"forApi"(project(path = ":common", configuration = "commonApiOnly"))
|
||||||
"forLib"(project(path = ":common", configuration = "commonLib"))
|
"forLib"(project(path = ":common", configuration = "commonLib"))
|
||||||
"forBackend"(project(path = ":common", configuration = "commonBackend"))
|
"forBackend"(project(path = ":common", configuration = "commonBackend"))
|
||||||
|
"forStubs"(project(path = ":common", configuration = "commonStubs"))
|
||||||
"forMain"(project(path = ":common", configuration = "commonImpl"))
|
"forMain"(project(path = ":common", configuration = "commonImpl"))
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,15 @@
|
||||||
package dev.engine_room.flywheel.impl;
|
package dev.engine_room.flywheel.impl;
|
||||||
|
|
||||||
import dev.engine_room.flywheel.api.event.ReloadLevelRendererEvent;
|
import dev.engine_room.flywheel.api.event.ReloadLevelRendererEvent;
|
||||||
|
import dev.engine_room.flywheel.impl.compat.CompatMod;
|
||||||
import net.minecraft.client.multiplayer.ClientLevel;
|
import net.minecraft.client.multiplayer.ClientLevel;
|
||||||
import net.neoforged.fml.loading.LoadingModList;
|
import net.neoforged.fml.loading.LoadingModList;
|
||||||
import net.neoforged.neoforge.common.NeoForge;
|
import net.neoforged.neoforge.common.NeoForge;
|
||||||
|
import net.minecraftforge.fml.loading.LoadingModList;
|
||||||
|
|
||||||
public class FlwImplXplatImpl implements FlwImplXplat {
|
public class FlwImplXplatImpl implements FlwImplXplat {
|
||||||
@Override
|
@Override
|
||||||
public boolean getModLoaded(String modId) {
|
public boolean isModLoaded(String modId) {
|
||||||
return LoadingModList.get().getModFileById(modId) != null;
|
return LoadingModList.get().getModFileById(modId) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,4 +27,14 @@ public class FlwImplXplatImpl implements FlwImplXplat {
|
||||||
public FlwConfig getConfig() {
|
public FlwConfig getConfig() {
|
||||||
return NeoForgeFlwConfig.INSTANCE;
|
return NeoForgeFlwConfig.INSTANCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean useSodium0_6Compat() {
|
||||||
|
return CompatMod.SODIUM.isLoaded && !CompatMod.EMBEDDIUM.isLoaded;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean useIrisCompat() {
|
||||||
|
return CompatMod.IRIS.isLoaded || CompatMod.OCULUS.isLoaded;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@ package dev.engine_room.flywheel.impl;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
import org.jetbrains.annotations.UnknownNullability;
|
import org.jetbrains.annotations.UnknownNullability;
|
||||||
|
|
||||||
import dev.engine_room.flywheel.impl.compat.CompatMods;
|
import dev.engine_room.flywheel.impl.compat.CompatMods;
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
package dev.engine_room.flywheel.impl.compat;
|
||||||
|
|
||||||
|
import org.embeddedt.embeddium.api.ChunkDataBuiltEvent;
|
||||||
|
|
||||||
|
import dev.engine_room.flywheel.impl.FlwImpl;
|
||||||
|
import dev.engine_room.flywheel.lib.visualization.VisualizationHelper;
|
||||||
|
|
||||||
|
public final class EmbeddiumCompat {
|
||||||
|
public static final boolean ACTIVE = CompatMod.EMBEDDIUM.isLoaded;
|
||||||
|
|
||||||
|
static {
|
||||||
|
if (ACTIVE) {
|
||||||
|
FlwImpl.LOGGER.debug("Detected Embeddium");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private EmbeddiumCompat() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void init() {
|
||||||
|
if (ACTIVE) {
|
||||||
|
Internals.init();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final class Internals {
|
||||||
|
static void init() {
|
||||||
|
ChunkDataBuiltEvent.BUS.addListener(event -> {
|
||||||
|
event.getDataBuilder().removeBlockEntitiesIf(VisualizationHelper::tryAddBlockEntity);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -31,6 +31,13 @@ type = "required"
|
||||||
versionRange = "${neoforge_version_range}"
|
versionRange = "${neoforge_version_range}"
|
||||||
side = "CLIENT"
|
side = "CLIENT"
|
||||||
|
|
||||||
|
[[dependencies.${mod_id}]]
|
||||||
|
modId = "sodium"
|
||||||
|
mandatory = false
|
||||||
|
versionRange = "[0.6.0-beta.2,)"
|
||||||
|
side = "CLIENT"
|
||||||
|
|
||||||
|
# Simulates a breaks/incompatible dependency
|
||||||
[[dependencies.${mod_id}]]
|
[[dependencies.${mod_id}]]
|
||||||
modId = "embeddium"
|
modId = "embeddium"
|
||||||
type = "incompatible"
|
type = "incompatible"
|
||||||
|
|
|
@ -7,9 +7,9 @@ mod_name = Flywheel
|
||||||
mod_version = 1.0.0-beta
|
mod_version = 1.0.0-beta
|
||||||
mod_description = An overhauled entity and block entity rendering API.
|
mod_description = An overhauled entity and block entity rendering API.
|
||||||
mod_license = MIT
|
mod_license = MIT
|
||||||
mod_sources = https://github.com/Jozufozu/Flywheel
|
mod_sources = https://github.com/Engine-Room/Flywheel
|
||||||
mod_issues = https://github.com/Jozufozu/Flywheel/issues
|
mod_issues = https://github.com/Engine-Room/Flywheel/issues
|
||||||
mod_homepage = https://github.com/Jozufozu/Flywheel
|
mod_homepage = https://github.com/Engine-Room/Flywheel
|
||||||
|
|
||||||
# Mod dependency declarations
|
# Mod dependency declarations
|
||||||
minecraft_semver_version_range = >=1.21.1 <1.21.2
|
minecraft_semver_version_range = >=1.21.1 <1.21.2
|
||||||
|
|
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
|
@ -1,6 +1,6 @@
|
||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip
|
||||||
networkTimeout=10000
|
networkTimeout=10000
|
||||||
validateDistributionUrl=true
|
validateDistributionUrl=true
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
|
Loading…
Reference in a new issue