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:
Jozufozu 2022-07-18 23:55:43 -07:00
commit 0b228b9db9
123 changed files with 551 additions and 378 deletions

View file

@ -60,6 +60,8 @@ body:
description: The version of the mod you were using when the bug occured
options:
- "0.7.0"
- "0.6.4"
- "0.6.3"
- "0.6.2"
- "0.6.1"
- "0.6.0"

View file

@ -11,10 +11,10 @@ buildscript {
classpath "org.parchmentmc:librarian:${librarian_version}"
}
}
plugins {
id 'com.matthewprenger.cursegradle' version "${cursegradle_version}"
}
apply plugin: 'net.minecraftforge.gradle'
apply plugin: 'org.parchmentmc.librarian.forgegradle'
apply plugin: 'eclipse'
@ -24,11 +24,10 @@ apply plugin: 'org.spongepowered.mixin'
boolean dev = System.getenv('RELEASE') == null || System.getenv('RELEASE').equalsIgnoreCase('false');
ext.buildNumber = System.getenv('BUILD_NUMBER')
if (buildNumber == null) buildNumber = 'custom'
version = "${mc_update_version}-${mod_version}" + (dev ? ".${buildNumber}" : '')
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)
@ -43,6 +42,8 @@ minecraft {
property 'forge.logging.markers', ''
property 'forge.logging.console.level', 'debug'
property 'mixin.debug.export', 'true'
property 'mixin.env.remapRefMap', 'true'
property 'mixin.env.refMapRemappingFile', "${projectDir}/build/createSrgToMcp/output.srg"
property 'flw.dumpShaderSource', 'true'
arg '-mixin.config=flywheel.mixins.json'
@ -87,10 +88,6 @@ minecraft {
}
}
mixin {
add sourceSets.main, 'flywheel.refmap.json'
}
repositories {
maven {
url 'https://www.cursemaven.com'
@ -102,12 +99,23 @@ repositories {
name 'tterrag maven'
url 'https://maven.tterrag.com/'
}
maven {
name = "Modrinth"
url = "https://api.modrinth.com/maven"
content {
includeGroup "maven.modrinth"
}
}
}
dependencies {
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
// 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..
jar {
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")
])
}
mixin {
add sourceSets.main, 'flywheel.refmap.json'
}
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 {
source = [sourceSets.main.allJava]
@ -141,29 +144,42 @@ javadoc {
options.addStringOption('Xdoclint:none', '-quiet')
}
task sourcesJar(type: Jar) {
from sourceSets.main.allSource
archiveBaseName.set(project.archivesBaseName)
archiveVersion.set("${project.version}")
archiveClassifier.set('sources')
jar {
manifest {
attributes([
'Specification-Title' : 'flywheel',
//'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) {
from javadoc.destinationDir
archiveClassifier.set('javadoc')
java {
withSourcesJar()
withJavadocJar()
}
artifacts {
archives jar, sourcesJar, javadocJar
void addLicense(jarTask) {
jarTask.from('LICENSE.md') {
rename '(.*)\\.(.*)', '$1_' + archivesBaseName + '.$2'
}
}
jar.finalizedBy('reobfJar')
addLicense(jar)
publishing {
tasks.publish.dependsOn 'build'
publications {
mavenJava(MavenPublication) {
artifact jar
artifact sourcesJar
artifact javadocJar
artifactId = archivesBaseName
from components.java
fg.component(it)
}
}

View file

@ -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:
Update to 1.18.2

View file

@ -3,9 +3,10 @@ org.gradle.daemon = false
# mod version info
mod_version = 0.7.0
mc_update_version = 1.18
artifact_minecraft_version = 1.18.2
minecraft_version = 1.18.2
forge_version = 40.1.0
forge_version = 40.1.68
# build dependency versions
forgegradle_version = 5.1.+
@ -13,7 +14,7 @@ mixingradle_version = 0.7-SNAPSHOT
mixin_version = 0.8.5
librarian_version = 1.+
cursegradle_version = 1.4.0
parchment_version = 2022.03.13
parchment_version = 2022.07.10
# curseforge info
projectId = 486392

Binary file not shown.

View file

@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
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
zipStorePath=wrapper/dists

10
gradlew vendored
View file

@ -1,7 +1,7 @@
#!/bin/sh
#
# Copyright © 2015-2021 the original authors.
# Copyright © 2015-2021 the original authors.
#
# Licensed under the Apache License, Version 2.0 (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
# requires all of these POSIX shell features:
# * functions;
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
# * compound commands having a testable exit status, especially «case»;
# * various built-in commands including «command», «set», and «ulimit».
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
# * compound commands having a testable exit status, especially «case»;
# * various built-in commands including «command», «set», and «ulimit».
#
# Important for patching:
#

View file

@ -4,7 +4,7 @@ import org.apache.maven.artifact.versioning.ArtifactVersion;
import org.slf4j.Logger;
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.instancing.InstancedRenderDispatcher;
import com.jozufozu.flywheel.backend.model.MeshPool;
@ -80,7 +80,7 @@ public class Flywheel {
private static void clientInit(IEventBus forgeEventBus, IEventBus modEventBus) {
CrashReportCallables.registerCrashCallable("Flywheel Backend", Backend::getBackendDescriptor);
OptifineHandler.init();
ShadersModHandler.init();
Backend.init();
forgeEventBus.addListener(FlwCommands::registerClientCommands);

View file

@ -90,7 +90,7 @@ public class Backend {
BackendType preferredChoice = FlwConfig.get()
.getBackendType();
boolean usingShaders = OptifineHandler.isUsingShaders();
boolean usingShaders = ShadersModHandler.isShaderPackInUse();
boolean canUseEngine = switch (preferredChoice) {
case OFF -> true;
case BATCHING -> !usingShaders;

View file

@ -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);
}
}

View file

@ -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);
}
}
}

View file

@ -10,8 +10,6 @@ import com.jozufozu.flywheel.api.instance.TickableInstance;
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstanceManager;
import com.jozufozu.flywheel.core.structs.FlatLit;
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 net.minecraft.core.BlockPos;
@ -26,6 +24,7 @@ public abstract class AbstractInstance implements Instance, LightListener {
protected final InstancerManager instancerManager;
public final Level level;
protected boolean removed = false;
public AbstractInstance(InstancerManager instancerManager, Level level) {
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.
*/
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.
@ -78,12 +86,12 @@ public abstract class AbstractInstance implements Instance, LightListener {
}
@Override
public ListenerStatus status() {
return ListenerStatus.OKAY;
public boolean isListenerInvalid() {
return removed;
}
@Override
public void onLightUpdate(LightProvider world, LightLayer type, ImmutableBox changed) {
public void onLightUpdate(LightLayer type, ImmutableBox changed) {
updateLight();
}
@ -103,4 +111,5 @@ public abstract class AbstractInstance implements Instance, LightListener {
models.forEach(model -> model.setBlockLight(block)
.setSkyLight(sky));
}
}

View file

@ -7,7 +7,7 @@ import java.util.Map;
import com.jozufozu.flywheel.api.InstancedPart;
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.core.RenderContext;
import com.jozufozu.flywheel.util.FlwUtil;
@ -55,7 +55,7 @@ public class BatchingEngine implements Engine {
var consumer = batchTracker.getDirectConsumer(renderType, vertices);
consumer.memSetZero();
var outputColorDiffuse = !consumer.hasOverlay() && !OptifineHandler.isUsingShaders();
var outputColorDiffuse = !consumer.hasOverlay() && !ShadersModHandler.isShaderPackInUse();
for (var transformSet : renderList) {
transformSet.setOutputColorDiffuse(outputColorDiffuse);

View file

@ -69,7 +69,7 @@ public class EffectInstanceManager extends InstanceManager<Effect> {
@Override
public void invalidate() {
instances.values().forEach(AbstractInstance::remove);
instances.values().forEach(AbstractInstance::removeAndMark);
instances.clear();
tickableInstances.clear();
dynamicInstances.clear();
@ -115,7 +115,7 @@ public class EffectInstanceManager extends InstanceManager<Effect> {
public void recreateAll() {
this.dynamicInstances.clear();
this.tickableInstances.clear();
this.instances.values().forEach(AbstractInstance::remove);
this.instances.values().forEach(AbstractInstance::removeAndMark);
var backup = new ArrayList<>(this.instances.keySet());
this.instances.clear();

View file

@ -6,8 +6,7 @@ import com.jozufozu.flywheel.api.instance.TickableInstance;
import com.jozufozu.flywheel.backend.instancing.AbstractInstance;
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstanceManager;
import com.jozufozu.flywheel.light.LightListener;
import com.jozufozu.flywheel.light.LightProvider;
import com.jozufozu.flywheel.light.MovingListener;
import com.jozufozu.flywheel.light.TickingLightListener;
import com.jozufozu.flywheel.util.box.GridAlignedBB;
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.
*/
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 GridAlignedBB bounds;
@ -51,7 +50,7 @@ public abstract class EntityInstance<E extends Entity> extends AbstractInstance
}
@Override
public boolean update(LightProvider provider) {
public boolean tickLightListener() {
AABB boundsNow = entity.getBoundingBox();
if (bounds.sameAs(boundsNow)) return false;

View file

@ -23,7 +23,6 @@ import net.minecraft.network.chat.TextComponent;
import net.minecraft.world.entity.Entity;
import net.minecraftforge.client.event.RegisterClientCommandsEvent;
import net.minecraftforge.common.ForgeConfigSpec.ConfigValue;
import net.minecraftforge.fml.ModList;
public class FlwCommands {
public static void registerClientCommands(RegisterClientCommandsEvent event) {
@ -141,17 +140,7 @@ public class FlwCommands {
return switch (type) {
case OFF -> new TextComponent("Disabled Flywheel").withStyle(ChatFormatting.RED);
case INSTANCING -> new TextComponent("Using Instancing Engine").withStyle(ChatFormatting.GREEN);
case BATCHING -> {
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;
}
case BATCHING -> new TextComponent("Using Batching Engine").withStyle(ChatFormatting.GREEN);
};
}

Some files were not shown because too many files have changed in this diff Show more