mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2024-12-26 06:57:02 +01:00
Merge branch '1.18/dev' into 1.18/next
# Conflicts: # .github/ISSUE_TEMPLATE/bug_report.yml # build.gradle # gradle.properties # src/main/java/com/jozufozu/flywheel/Flywheel.java # src/main/java/com/jozufozu/flywheel/backend/Backend.java # src/main/java/com/jozufozu/flywheel/backend/Loader.java # src/main/java/com/jozufozu/flywheel/backend/OptifineHandler.java # src/main/java/com/jozufozu/flywheel/backend/instancing/AbstractInstance.java # src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceManager.java # src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchedMaterialGroup.java # src/main/java/com/jozufozu/flywheel/core/model/BakedModelBuilder.java # src/main/java/com/jozufozu/flywheel/core/model/Bufferable.java # src/main/java/com/jozufozu/flywheel/core/model/ModelUtil.java # src/main/java/com/jozufozu/flywheel/core/model/WorldModel.java # src/main/java/com/jozufozu/flywheel/core/model/WorldModelBuilder.java # src/main/java/com/jozufozu/flywheel/core/vertex/BlockVertexList.java # src/main/java/com/jozufozu/flywheel/core/vertex/BlockVertexListUnsafe.java # src/main/java/com/jozufozu/flywheel/core/vertex/PosTexNormalVertexListUnsafe.java # src/main/java/com/jozufozu/flywheel/mixin/FrustumMixin.java
This commit is contained in:
commit
0b228b9db9
123 changed files with 551 additions and 378 deletions
2
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
2
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
|
@ -60,6 +60,8 @@ body:
|
||||||
description: The version of the mod you were using when the bug occured
|
description: The version of the mod you were using when the bug occured
|
||||||
options:
|
options:
|
||||||
- "0.7.0"
|
- "0.7.0"
|
||||||
|
- "0.6.4"
|
||||||
|
- "0.6.3"
|
||||||
- "0.6.2"
|
- "0.6.2"
|
||||||
- "0.6.1"
|
- "0.6.1"
|
||||||
- "0.6.0"
|
- "0.6.0"
|
||||||
|
|
92
build.gradle
92
build.gradle
|
@ -11,10 +11,10 @@ buildscript {
|
||||||
classpath "org.parchmentmc:librarian:${librarian_version}"
|
classpath "org.parchmentmc:librarian:${librarian_version}"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id 'com.matthewprenger.cursegradle' version "${cursegradle_version}"
|
id 'com.matthewprenger.cursegradle' version "${cursegradle_version}"
|
||||||
}
|
}
|
||||||
|
|
||||||
apply plugin: 'net.minecraftforge.gradle'
|
apply plugin: 'net.minecraftforge.gradle'
|
||||||
apply plugin: 'org.parchmentmc.librarian.forgegradle'
|
apply plugin: 'org.parchmentmc.librarian.forgegradle'
|
||||||
apply plugin: 'eclipse'
|
apply plugin: 'eclipse'
|
||||||
|
@ -24,11 +24,10 @@ apply plugin: 'org.spongepowered.mixin'
|
||||||
boolean dev = System.getenv('RELEASE') == null || System.getenv('RELEASE').equalsIgnoreCase('false');
|
boolean dev = System.getenv('RELEASE') == null || System.getenv('RELEASE').equalsIgnoreCase('false');
|
||||||
|
|
||||||
ext.buildNumber = System.getenv('BUILD_NUMBER')
|
ext.buildNumber = System.getenv('BUILD_NUMBER')
|
||||||
if (buildNumber == null) buildNumber = 'custom'
|
|
||||||
|
|
||||||
version = "${mc_update_version}-${mod_version}" + (dev ? ".${buildNumber}" : '')
|
|
||||||
group = 'com.jozufozu.flywheel'
|
group = 'com.jozufozu.flywheel'
|
||||||
archivesBaseName = 'flywheel-forge'
|
archivesBaseName = "flywheel-forge-${artifact_minecraft_version}"
|
||||||
|
version = mod_version + (dev && buildNumber != null ? "-${buildNumber}" : '')
|
||||||
|
|
||||||
java.toolchain.languageVersion = JavaLanguageVersion.of(17)
|
java.toolchain.languageVersion = JavaLanguageVersion.of(17)
|
||||||
|
|
||||||
|
@ -43,6 +42,8 @@ minecraft {
|
||||||
property 'forge.logging.markers', ''
|
property 'forge.logging.markers', ''
|
||||||
property 'forge.logging.console.level', 'debug'
|
property 'forge.logging.console.level', 'debug'
|
||||||
property 'mixin.debug.export', 'true'
|
property 'mixin.debug.export', 'true'
|
||||||
|
property 'mixin.env.remapRefMap', 'true'
|
||||||
|
property 'mixin.env.refMapRemappingFile', "${projectDir}/build/createSrgToMcp/output.srg"
|
||||||
property 'flw.dumpShaderSource', 'true'
|
property 'flw.dumpShaderSource', 'true'
|
||||||
|
|
||||||
arg '-mixin.config=flywheel.mixins.json'
|
arg '-mixin.config=flywheel.mixins.json'
|
||||||
|
@ -87,10 +88,6 @@ minecraft {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mixin {
|
|
||||||
add sourceSets.main, 'flywheel.refmap.json'
|
|
||||||
}
|
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
maven {
|
maven {
|
||||||
url 'https://www.cursemaven.com'
|
url 'https://www.cursemaven.com'
|
||||||
|
@ -102,12 +99,23 @@ repositories {
|
||||||
name 'tterrag maven'
|
name 'tterrag maven'
|
||||||
url 'https://maven.tterrag.com/'
|
url 'https://maven.tterrag.com/'
|
||||||
}
|
}
|
||||||
|
maven {
|
||||||
|
name = "Modrinth"
|
||||||
|
url = "https://api.modrinth.com/maven"
|
||||||
|
content {
|
||||||
|
includeGroup "maven.modrinth"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
minecraft "net.minecraftforge:forge:${minecraft_version}-${forge_version}"
|
minecraft "net.minecraftforge:forge:${minecraft_version}-${forge_version}"
|
||||||
|
|
||||||
compileOnly fg.deobf("curse.maven:starlight-526854:3706539")
|
// switch to implementation for debugging
|
||||||
|
compileOnly fg.deobf("maven.modrinth:starlight-forge:1.0.2+1.18.2")
|
||||||
|
|
||||||
|
compileOnly fg.deobf("maven.modrinth:rubidium:0.5.2a")
|
||||||
|
compileOnly fg.deobf("curse.maven:oculus-581495:3821406")
|
||||||
|
|
||||||
// https://discord.com/channels/313125603924639766/725850371834118214/910619168821354497
|
// https://discord.com/channels/313125603924639766/725850371834118214/910619168821354497
|
||||||
// Prevent Mixin annotation processor from getting into IntelliJ's annotation processor settings
|
// Prevent Mixin annotation processor from getting into IntelliJ's annotation processor settings
|
||||||
|
@ -117,23 +125,18 @@ dependencies {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Example for how to get properties into the manifest for reading by the runtime..
|
mixin {
|
||||||
jar {
|
add sourceSets.main, 'flywheel.refmap.json'
|
||||||
manifest {
|
|
||||||
attributes([
|
|
||||||
'Specification-Title' : 'flywheel',
|
|
||||||
//'Specification-Vendor': 'flywheel authors',
|
|
||||||
'Specification-Version' : '1', // We are version 1 of ourselves
|
|
||||||
'Implementation-Title' : project.name,
|
|
||||||
'Implementation-Version' : project.version,
|
|
||||||
//'Implementation-Vendor': 'flywheel authors',
|
|
||||||
'MixinConfigs' : 'flywheel.mixins.json',
|
|
||||||
'Implementation-Timestamp': new Date().format("yyyy-MM-dd'T'HH:mm:ssZ")
|
|
||||||
])
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
jar.finalizedBy('reobfJar')
|
// Workaround for SpongePowered/MixinGradle#38
|
||||||
|
afterEvaluate {
|
||||||
|
tasks.configureReobfTaskForReobfJar.mustRunAfter(tasks.compileJava)
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.withType(JavaCompile).configureEach {
|
||||||
|
options.encoding = 'UTF-8' // Use the UTF-8 charset for Java compilation
|
||||||
|
}
|
||||||
|
|
||||||
javadoc {
|
javadoc {
|
||||||
source = [sourceSets.main.allJava]
|
source = [sourceSets.main.allJava]
|
||||||
|
@ -141,29 +144,42 @@ javadoc {
|
||||||
options.addStringOption('Xdoclint:none', '-quiet')
|
options.addStringOption('Xdoclint:none', '-quiet')
|
||||||
}
|
}
|
||||||
|
|
||||||
task sourcesJar(type: Jar) {
|
jar {
|
||||||
from sourceSets.main.allSource
|
manifest {
|
||||||
archiveBaseName.set(project.archivesBaseName)
|
attributes([
|
||||||
archiveVersion.set("${project.version}")
|
'Specification-Title' : 'flywheel',
|
||||||
archiveClassifier.set('sources')
|
//'Specification-Vendor': 'flywheel authors',
|
||||||
|
'Specification-Version' : '1', // We are version 1 of ourselves
|
||||||
|
'Implementation-Title' : project.jar.baseName,
|
||||||
|
'Implementation-Version' : project.jar.archiveVersion,
|
||||||
|
//'Implementation-Vendor': 'flywheel authors',
|
||||||
|
'Implementation-Timestamp': new Date().format("yyyy-MM-dd'T'HH:mm:ssZ"),
|
||||||
|
'MixinConfigs' : 'flywheel.mixins.json'
|
||||||
|
])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
task javadocJar(type: Jar, dependsOn: javadoc) {
|
java {
|
||||||
from javadoc.destinationDir
|
withSourcesJar()
|
||||||
archiveClassifier.set('javadoc')
|
withJavadocJar()
|
||||||
}
|
}
|
||||||
|
|
||||||
artifacts {
|
void addLicense(jarTask) {
|
||||||
archives jar, sourcesJar, javadocJar
|
jarTask.from('LICENSE.md') {
|
||||||
|
rename '(.*)\\.(.*)', '$1_' + archivesBaseName + '.$2'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
jar.finalizedBy('reobfJar')
|
||||||
|
addLicense(jar)
|
||||||
|
|
||||||
publishing {
|
publishing {
|
||||||
tasks.publish.dependsOn 'build'
|
|
||||||
publications {
|
publications {
|
||||||
mavenJava(MavenPublication) {
|
mavenJava(MavenPublication) {
|
||||||
artifact jar
|
artifactId = archivesBaseName
|
||||||
artifact sourcesJar
|
|
||||||
artifact javadocJar
|
from components.java
|
||||||
|
fg.component(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,16 @@
|
||||||
|
0.6.4:
|
||||||
|
Fixes
|
||||||
|
- Fix shader detection with oculus
|
||||||
|
Technical/API
|
||||||
|
- LightUpdater is simplified to increase reliability and reflect how it is actually used
|
||||||
|
- ModelUtil is superseded by model builders, to be improved more in 0.7.0
|
||||||
|
- VertexLists now copy input buffers to reduce memory usage
|
||||||
|
|
||||||
|
0.6.3:
|
||||||
|
Technical/API
|
||||||
|
- Light updates are now processed in parallel.
|
||||||
|
- The light updater is now more selective of the levels it processes, fixing a memory leak.
|
||||||
|
|
||||||
0.6.2:
|
0.6.2:
|
||||||
Update to 1.18.2
|
Update to 1.18.2
|
||||||
|
|
||||||
|
|
|
@ -3,9 +3,10 @@ org.gradle.daemon = false
|
||||||
|
|
||||||
# mod version info
|
# mod version info
|
||||||
mod_version = 0.7.0
|
mod_version = 0.7.0
|
||||||
mc_update_version = 1.18
|
artifact_minecraft_version = 1.18.2
|
||||||
|
|
||||||
minecraft_version = 1.18.2
|
minecraft_version = 1.18.2
|
||||||
forge_version = 40.1.0
|
forge_version = 40.1.68
|
||||||
|
|
||||||
# build dependency versions
|
# build dependency versions
|
||||||
forgegradle_version = 5.1.+
|
forgegradle_version = 5.1.+
|
||||||
|
@ -13,7 +14,7 @@ mixingradle_version = 0.7-SNAPSHOT
|
||||||
mixin_version = 0.8.5
|
mixin_version = 0.8.5
|
||||||
librarian_version = 1.+
|
librarian_version = 1.+
|
||||||
cursegradle_version = 1.4.0
|
cursegradle_version = 1.4.0
|
||||||
parchment_version = 2022.03.13
|
parchment_version = 2022.07.10
|
||||||
|
|
||||||
# curseforge info
|
# curseforge info
|
||||||
projectId = 486392
|
projectId = 486392
|
||||||
|
|
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
|
@ -1,5 +1,5 @@
|
||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.1-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
|
|
10
gradlew
vendored
10
gradlew
vendored
|
@ -1,7 +1,7 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright © 2015-2021 the original authors.
|
# Copyright © 2015-2021 the original authors.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# you may not use this file except in compliance with the License.
|
# you may not use this file except in compliance with the License.
|
||||||
|
@ -32,10 +32,10 @@
|
||||||
# Busybox and similar reduced shells will NOT work, because this script
|
# Busybox and similar reduced shells will NOT work, because this script
|
||||||
# requires all of these POSIX shell features:
|
# requires all of these POSIX shell features:
|
||||||
# * functions;
|
# * functions;
|
||||||
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
|
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
|
||||||
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
|
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
|
||||||
# * compound commands having a testable exit status, especially «case»;
|
# * compound commands having a testable exit status, especially «case»;
|
||||||
# * various built-in commands including «command», «set», and «ulimit».
|
# * various built-in commands including «command», «set», and «ulimit».
|
||||||
#
|
#
|
||||||
# Important for patching:
|
# Important for patching:
|
||||||
#
|
#
|
||||||
|
|
|
@ -4,7 +4,7 @@ import org.apache.maven.artifact.versioning.ArtifactVersion;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.Backend;
|
import com.jozufozu.flywheel.backend.Backend;
|
||||||
import com.jozufozu.flywheel.backend.OptifineHandler;
|
import com.jozufozu.flywheel.backend.ShadersModHandler;
|
||||||
import com.jozufozu.flywheel.backend.RenderWork;
|
import com.jozufozu.flywheel.backend.RenderWork;
|
||||||
import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher;
|
import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher;
|
||||||
import com.jozufozu.flywheel.backend.model.MeshPool;
|
import com.jozufozu.flywheel.backend.model.MeshPool;
|
||||||
|
@ -80,7 +80,7 @@ public class Flywheel {
|
||||||
private static void clientInit(IEventBus forgeEventBus, IEventBus modEventBus) {
|
private static void clientInit(IEventBus forgeEventBus, IEventBus modEventBus) {
|
||||||
CrashReportCallables.registerCrashCallable("Flywheel Backend", Backend::getBackendDescriptor);
|
CrashReportCallables.registerCrashCallable("Flywheel Backend", Backend::getBackendDescriptor);
|
||||||
|
|
||||||
OptifineHandler.init();
|
ShadersModHandler.init();
|
||||||
Backend.init();
|
Backend.init();
|
||||||
|
|
||||||
forgeEventBus.addListener(FlwCommands::registerClientCommands);
|
forgeEventBus.addListener(FlwCommands::registerClientCommands);
|
||||||
|
|
|
@ -90,7 +90,7 @@ public class Backend {
|
||||||
BackendType preferredChoice = FlwConfig.get()
|
BackendType preferredChoice = FlwConfig.get()
|
||||||
.getBackendType();
|
.getBackendType();
|
||||||
|
|
||||||
boolean usingShaders = OptifineHandler.isUsingShaders();
|
boolean usingShaders = ShadersModHandler.isShaderPackInUse();
|
||||||
boolean canUseEngine = switch (preferredChoice) {
|
boolean canUseEngine = switch (preferredChoice) {
|
||||||
case OFF -> true;
|
case OFF -> true;
|
||||||
case BATCHING -> !usingShaders;
|
case BATCHING -> !usingShaders;
|
||||||
|
|
|
@ -1,117 +0,0 @@
|
||||||
package com.jozufozu.flywheel.backend;
|
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.util.function.BooleanSupplier;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import net.minecraft.client.Camera;
|
|
||||||
import net.minecraft.client.renderer.culling.Frustum;
|
|
||||||
|
|
||||||
public final class OptifineHandler {
|
|
||||||
public static final String OPTIFINE_ROOT_PACKAGE = "net.optifine";
|
|
||||||
public static final String SHADER_PACKAGE = "net.optifine.shaders";
|
|
||||||
|
|
||||||
private static boolean isOptifineInstalled;
|
|
||||||
private static BooleanSupplier shadersEnabledSupplier;
|
|
||||||
private static BooleanSupplier shadowPassSupplier;
|
|
||||||
private static FrustumConstructor shadowFrustumConstructor;
|
|
||||||
|
|
||||||
private OptifineHandler() {
|
|
||||||
}
|
|
||||||
|
|
||||||
private static FrustumConstructor createShadowFrustumConstructor() {
|
|
||||||
try {
|
|
||||||
Class<?> ofShaders = Class.forName("net.optifine.shaders.ShadersRender");
|
|
||||||
Method method = ofShaders.getDeclaredMethod("makeShadowFrustum", Camera.class, Float.TYPE);
|
|
||||||
method.setAccessible(true);
|
|
||||||
return (cam, pt) -> {
|
|
||||||
try {
|
|
||||||
return (Frustum) method.invoke(null, cam, pt);
|
|
||||||
} catch (Exception ignored) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
} catch (Exception ignored) {
|
|
||||||
return ($, $$) -> null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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 ignored) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
} catch (Exception ignored) {
|
|
||||||
return () -> false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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 ignored) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
} catch (Exception ignored) {
|
|
||||||
return () -> false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void init() {
|
|
||||||
Package optifinePackage = Package.getPackage(OPTIFINE_ROOT_PACKAGE);
|
|
||||||
isOptifineInstalled = optifinePackage != null;
|
|
||||||
|
|
||||||
if (isOptifineInstalled) {
|
|
||||||
Backend.LOGGER.info("Optifine detected.");
|
|
||||||
} else {
|
|
||||||
Backend.LOGGER.info("Optifine not detected.");
|
|
||||||
}
|
|
||||||
|
|
||||||
shadersEnabledSupplier = createShadersEnabledSupplier();
|
|
||||||
shadowPassSupplier = createShadowPassSupplier();
|
|
||||||
shadowFrustumConstructor = createShadowFrustumConstructor();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isOptifineInstalled() {
|
|
||||||
return isOptifineInstalled;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isUsingShaders() {
|
|
||||||
return shadersEnabledSupplier.getAsBoolean();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isShadowPass() {
|
|
||||||
return shadowPassSupplier.getAsBoolean();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public static Frustum createShadowFrustum(Camera camera, float partialTicks) {
|
|
||||||
var frustum = shadowFrustumConstructor.create(camera, partialTicks);
|
|
||||||
if (frustum != null) {
|
|
||||||
var position = camera.getPosition();
|
|
||||||
frustum.prepare(position.x, position.y, position.z);
|
|
||||||
}
|
|
||||||
return frustum;
|
|
||||||
}
|
|
||||||
|
|
||||||
@FunctionalInterface
|
|
||||||
public interface FrustumConstructor {
|
|
||||||
@Nullable
|
|
||||||
Frustum create(Camera camera, float partialTicks);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,179 @@
|
||||||
|
package com.jozufozu.flywheel.backend;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.function.BooleanSupplier;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
import net.irisshaders.iris.api.v0.IrisApi;
|
||||||
|
import net.minecraft.client.Camera;
|
||||||
|
import net.minecraft.client.renderer.culling.Frustum;
|
||||||
|
import net.minecraftforge.fml.ModList;
|
||||||
|
|
||||||
|
public final class ShadersModHandler {
|
||||||
|
public static final String OPTIFINE_ROOT_PACKAGE = "net.optifine";
|
||||||
|
public static final String SHADER_PACKAGE = "net.optifine.shaders";
|
||||||
|
|
||||||
|
private static final boolean isOculusLoaded;
|
||||||
|
private static final boolean isOptifineInstalled;
|
||||||
|
private static final InternalHandler internalHandler;
|
||||||
|
|
||||||
|
static {
|
||||||
|
Package optifinePackage = Package.getPackage(OPTIFINE_ROOT_PACKAGE);
|
||||||
|
isOptifineInstalled = optifinePackage != null;
|
||||||
|
isOculusLoaded = ModList.get()
|
||||||
|
.isLoaded("oculus");
|
||||||
|
|
||||||
|
// optfine and oculus are assumed to be mutually exclusive
|
||||||
|
|
||||||
|
if (isOptifineInstalled) {
|
||||||
|
Backend.LOGGER.info("Optifine detected.");
|
||||||
|
internalHandler = new Optifine();
|
||||||
|
} else if (isOculusLoaded) {
|
||||||
|
Backend.LOGGER.info("Oculus detected.");
|
||||||
|
internalHandler = new Oculus();
|
||||||
|
} else {
|
||||||
|
Backend.LOGGER.info("No shaders mod detected.");
|
||||||
|
internalHandler = new InternalHandler() {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private ShadersModHandler() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void init() {
|
||||||
|
// noop, load statics
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isOptifineInstalled() {
|
||||||
|
return isOptifineInstalled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isOculusLoaded() {
|
||||||
|
return isOculusLoaded;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isShaderPackInUse() {
|
||||||
|
return internalHandler.isShaderPackInUse();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isRenderingShadowPass() {
|
||||||
|
return internalHandler.isRenderingShadowPass();
|
||||||
|
}
|
||||||
|
|
||||||
|
private interface InternalHandler {
|
||||||
|
default boolean isShaderPackInUse() {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
default boolean isRenderingShadowPass() {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// simple, lovely api calls
|
||||||
|
private static class Oculus implements InternalHandler {
|
||||||
|
@Override
|
||||||
|
public boolean isShaderPackInUse() {
|
||||||
|
return IrisApi.getInstance()
|
||||||
|
.isShaderPackInUse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isRenderingShadowPass() {
|
||||||
|
return IrisApi.getInstance()
|
||||||
|
.isRenderingShadowPass();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// evil reflection
|
||||||
|
private static class Optifine implements InternalHandler {
|
||||||
|
private final BooleanSupplier shadersEnabledSupplier;
|
||||||
|
private final BooleanSupplier shadowPassSupplier;
|
||||||
|
private final FrustumConstructor shadowFrustumConstructor;
|
||||||
|
|
||||||
|
Optifine() {
|
||||||
|
shadersEnabledSupplier = createShadersEnabledSupplier();
|
||||||
|
shadowPassSupplier = createShadowPassSupplier();
|
||||||
|
shadowFrustumConstructor = createShadowFrustumConstructor();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isShaderPackInUse() {
|
||||||
|
return shadersEnabledSupplier.getAsBoolean();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isRenderingShadowPass() {
|
||||||
|
return shadowPassSupplier.getAsBoolean();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public Frustum createShadowFrustum(Camera camera, float partialTicks) {
|
||||||
|
var frustum = shadowFrustumConstructor.create(camera, partialTicks);
|
||||||
|
if (frustum != null) {
|
||||||
|
var position = camera.getPosition();
|
||||||
|
frustum.prepare(position.x, position.y, position.z);
|
||||||
|
}
|
||||||
|
return frustum;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static FrustumConstructor createShadowFrustumConstructor() {
|
||||||
|
try {
|
||||||
|
Class<?> ofShaders = Class.forName("net.optifine.shaders.ShadersRender");
|
||||||
|
Method method = ofShaders.getDeclaredMethod("makeShadowFrustum", Camera.class, Float.TYPE);
|
||||||
|
method.setAccessible(true);
|
||||||
|
return (cam, pt) -> {
|
||||||
|
try {
|
||||||
|
return (Frustum) method.invoke(null, cam, pt);
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
return ($, $$) -> null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 ignored) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
return () -> false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 ignored) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
return () -> false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface FrustumConstructor {
|
||||||
|
@Nullable
|
||||||
|
Frustum create(Camera camera, float partialTicks);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,8 +10,6 @@ import com.jozufozu.flywheel.api.instance.TickableInstance;
|
||||||
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstanceManager;
|
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstanceManager;
|
||||||
import com.jozufozu.flywheel.core.structs.FlatLit;
|
import com.jozufozu.flywheel.core.structs.FlatLit;
|
||||||
import com.jozufozu.flywheel.light.LightListener;
|
import com.jozufozu.flywheel.light.LightListener;
|
||||||
import com.jozufozu.flywheel.light.LightProvider;
|
|
||||||
import com.jozufozu.flywheel.light.ListenerStatus;
|
|
||||||
import com.jozufozu.flywheel.util.box.ImmutableBox;
|
import com.jozufozu.flywheel.util.box.ImmutableBox;
|
||||||
|
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
|
@ -26,6 +24,7 @@ public abstract class AbstractInstance implements Instance, LightListener {
|
||||||
|
|
||||||
protected final InstancerManager instancerManager;
|
protected final InstancerManager instancerManager;
|
||||||
public final Level level;
|
public final Level level;
|
||||||
|
protected boolean removed = false;
|
||||||
|
|
||||||
public AbstractInstance(InstancerManager instancerManager, Level level) {
|
public AbstractInstance(InstancerManager instancerManager, Level level) {
|
||||||
this.instancerManager = instancerManager;
|
this.instancerManager = instancerManager;
|
||||||
|
@ -39,10 +38,19 @@ public abstract class AbstractInstance implements Instance, LightListener {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final void removeAndMark() {
|
||||||
|
if (removed) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
remove();
|
||||||
|
removed = true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Free any acquired resources.
|
* Free any acquired resources.
|
||||||
*/
|
*/
|
||||||
public abstract void remove();
|
protected abstract void remove();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update instance data here. Good for when data doesn't change very often and when animations are GPU based.
|
* Update instance data here. Good for when data doesn't change very often and when animations are GPU based.
|
||||||
|
@ -78,12 +86,12 @@ public abstract class AbstractInstance implements Instance, LightListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ListenerStatus status() {
|
public boolean isListenerInvalid() {
|
||||||
return ListenerStatus.OKAY;
|
return removed;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLightUpdate(LightProvider world, LightLayer type, ImmutableBox changed) {
|
public void onLightUpdate(LightLayer type, ImmutableBox changed) {
|
||||||
updateLight();
|
updateLight();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,4 +111,5 @@ public abstract class AbstractInstance implements Instance, LightListener {
|
||||||
models.forEach(model -> model.setBlockLight(block)
|
models.forEach(model -> model.setBlockLight(block)
|
||||||
.setSkyLight(sky));
|
.setSkyLight(sky));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ import java.util.Map;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.InstancedPart;
|
import com.jozufozu.flywheel.api.InstancedPart;
|
||||||
import com.jozufozu.flywheel.api.struct.StructType;
|
import com.jozufozu.flywheel.api.struct.StructType;
|
||||||
import com.jozufozu.flywheel.backend.OptifineHandler;
|
import com.jozufozu.flywheel.backend.ShadersModHandler;
|
||||||
import com.jozufozu.flywheel.backend.instancing.*;
|
import com.jozufozu.flywheel.backend.instancing.*;
|
||||||
import com.jozufozu.flywheel.core.RenderContext;
|
import com.jozufozu.flywheel.core.RenderContext;
|
||||||
import com.jozufozu.flywheel.util.FlwUtil;
|
import com.jozufozu.flywheel.util.FlwUtil;
|
||||||
|
@ -55,7 +55,7 @@ public class BatchingEngine implements Engine {
|
||||||
var consumer = batchTracker.getDirectConsumer(renderType, vertices);
|
var consumer = batchTracker.getDirectConsumer(renderType, vertices);
|
||||||
consumer.memSetZero();
|
consumer.memSetZero();
|
||||||
|
|
||||||
var outputColorDiffuse = !consumer.hasOverlay() && !OptifineHandler.isUsingShaders();
|
var outputColorDiffuse = !consumer.hasOverlay() && !ShadersModHandler.isShaderPackInUse();
|
||||||
|
|
||||||
for (var transformSet : renderList) {
|
for (var transformSet : renderList) {
|
||||||
transformSet.setOutputColorDiffuse(outputColorDiffuse);
|
transformSet.setOutputColorDiffuse(outputColorDiffuse);
|
||||||
|
|
|
@ -69,7 +69,7 @@ public class EffectInstanceManager extends InstanceManager<Effect> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void invalidate() {
|
public void invalidate() {
|
||||||
instances.values().forEach(AbstractInstance::remove);
|
instances.values().forEach(AbstractInstance::removeAndMark);
|
||||||
instances.clear();
|
instances.clear();
|
||||||
tickableInstances.clear();
|
tickableInstances.clear();
|
||||||
dynamicInstances.clear();
|
dynamicInstances.clear();
|
||||||
|
@ -115,7 +115,7 @@ public class EffectInstanceManager extends InstanceManager<Effect> {
|
||||||
public void recreateAll() {
|
public void recreateAll() {
|
||||||
this.dynamicInstances.clear();
|
this.dynamicInstances.clear();
|
||||||
this.tickableInstances.clear();
|
this.tickableInstances.clear();
|
||||||
this.instances.values().forEach(AbstractInstance::remove);
|
this.instances.values().forEach(AbstractInstance::removeAndMark);
|
||||||
|
|
||||||
var backup = new ArrayList<>(this.instances.keySet());
|
var backup = new ArrayList<>(this.instances.keySet());
|
||||||
this.instances.clear();
|
this.instances.clear();
|
||||||
|
|
|
@ -6,8 +6,7 @@ import com.jozufozu.flywheel.api.instance.TickableInstance;
|
||||||
import com.jozufozu.flywheel.backend.instancing.AbstractInstance;
|
import com.jozufozu.flywheel.backend.instancing.AbstractInstance;
|
||||||
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstanceManager;
|
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstanceManager;
|
||||||
import com.jozufozu.flywheel.light.LightListener;
|
import com.jozufozu.flywheel.light.LightListener;
|
||||||
import com.jozufozu.flywheel.light.LightProvider;
|
import com.jozufozu.flywheel.light.TickingLightListener;
|
||||||
import com.jozufozu.flywheel.light.MovingListener;
|
|
||||||
import com.jozufozu.flywheel.util.box.GridAlignedBB;
|
import com.jozufozu.flywheel.util.box.GridAlignedBB;
|
||||||
import com.mojang.math.Vector3f;
|
import com.mojang.math.Vector3f;
|
||||||
|
|
||||||
|
@ -34,7 +33,7 @@ import net.minecraft.world.phys.Vec3;
|
||||||
*
|
*
|
||||||
* @param <E> The type of {@link Entity} your class is an instance of.
|
* @param <E> The type of {@link Entity} your class is an instance of.
|
||||||
*/
|
*/
|
||||||
public abstract class EntityInstance<E extends Entity> extends AbstractInstance implements LightListener, MovingListener {
|
public abstract class EntityInstance<E extends Entity> extends AbstractInstance implements LightListener, TickingLightListener {
|
||||||
|
|
||||||
protected final E entity;
|
protected final E entity;
|
||||||
protected final GridAlignedBB bounds;
|
protected final GridAlignedBB bounds;
|
||||||
|
@ -51,7 +50,7 @@ public abstract class EntityInstance<E extends Entity> extends AbstractInstance
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean update(LightProvider provider) {
|
public boolean tickLightListener() {
|
||||||
AABB boundsNow = entity.getBoundingBox();
|
AABB boundsNow = entity.getBoundingBox();
|
||||||
|
|
||||||
if (bounds.sameAs(boundsNow)) return false;
|
if (bounds.sameAs(boundsNow)) return false;
|
||||||
|
|
|
@ -23,7 +23,6 @@ import net.minecraft.network.chat.TextComponent;
|
||||||
import net.minecraft.world.entity.Entity;
|
import net.minecraft.world.entity.Entity;
|
||||||
import net.minecraftforge.client.event.RegisterClientCommandsEvent;
|
import net.minecraftforge.client.event.RegisterClientCommandsEvent;
|
||||||
import net.minecraftforge.common.ForgeConfigSpec.ConfigValue;
|
import net.minecraftforge.common.ForgeConfigSpec.ConfigValue;
|
||||||
import net.minecraftforge.fml.ModList;
|
|
||||||
|
|
||||||
public class FlwCommands {
|
public class FlwCommands {
|
||||||
public static void registerClientCommands(RegisterClientCommandsEvent event) {
|
public static void registerClientCommands(RegisterClientCommandsEvent event) {
|
||||||
|
@ -141,17 +140,7 @@ public class FlwCommands {
|
||||||
return switch (type) {
|
return switch (type) {
|
||||||
case OFF -> new TextComponent("Disabled Flywheel").withStyle(ChatFormatting.RED);
|
case OFF -> new TextComponent("Disabled Flywheel").withStyle(ChatFormatting.RED);
|
||||||
case INSTANCING -> new TextComponent("Using Instancing Engine").withStyle(ChatFormatting.GREEN);
|
case INSTANCING -> new TextComponent("Using Instancing Engine").withStyle(ChatFormatting.GREEN);
|
||||||
case BATCHING -> {
|
case BATCHING -> new TextComponent("Using Batching Engine").withStyle(ChatFormatting.GREEN);
|
||||||
MutableComponent msg = new TextComponent("Using Batching Engine").withStyle(ChatFormatting.GREEN);
|
|
||||||
|
|
||||||
if (ModList.get()
|
|
||||||
.isLoaded("create")) {
|
|
||||||
// FIXME: batching engine contraption lighting issues
|
|
||||||
msg.append(new TextComponent("\nWARNING: May cause issues with Create Contraptions").withStyle(ChatFormatting.RED));
|
|
||||||
}
|
|
||||||
|
|
||||||
yield msg;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue