diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a6760f73b..f9807850a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -3,7 +3,7 @@ name: Build on: [ workflow_dispatch, pull_request, push ] env: - JAVA_VERSION: 21 + JAVA_VERSION: 25 jobs: build: @@ -31,7 +31,7 @@ jobs: - name: Build # Doesn't actually publish, as no secrets are passed in, just makes sure that publishing works # Also generate the mod jars for the test job - run: ./gradlew remapTestModJar publish --no-daemon + run: ./gradlew testModJar publish --no-daemon - name: Capture Build Artifacts uses: actions/upload-artifact@v4 @@ -74,7 +74,7 @@ jobs: # Lock to a specific commit, it would be bad if the tag is re-pushed with unwanted changes - name: Run the MC client - uses: 3arthqu4ke/mc-runtime-test@e72f8fe1134aabf6fc749a2a8c09bb56dd7d283e + uses: headlesshq/mc-runtime-test@9d9ea4af8ef6d82648051f750c49905f75d0c3bb with: mc: ${{ env.MINECRAFT_VERSION }} modloader: ${{ matrix.loader }} diff --git a/build.gradle.kts b/build.gradle.kts index 8704c07bc..3e2af5893 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,7 +1,8 @@ plugins { idea java - id("dev.architectury.loom") apply false + alias(libs.plugins.loom) apply false + alias(libs.plugins.mdg) apply false } println("Java: ${System.getProperty("java.version")}, JVM: ${System.getProperty("java.vm.version")} (${System.getProperty("java.vendor")}), Arch: ${System.getProperty("os.arch")}") diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index fc9aab75d..ab57371de 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -1,5 +1,3 @@ -import java.util.Properties - plugins { `kotlin-dsl` idea @@ -11,11 +9,9 @@ repositories { maven("https://maven.neoforged.net/releases/") { name = "NeoForged" } - maven("https://maven.architectury.dev/") { - name = "Architectury" + maven("https://maven.fabricmc.net/") { + name = "FabricMC" } - maven("https://repo.spongepowered.org/repository/maven-public") - maven("https://maven.parchmentmc.org") } idea.module { @@ -36,12 +32,7 @@ gradlePlugin { } } -val properties by lazy { - Properties().apply { - load(rootDir.parentFile.resolve("gradle.properties").inputStream()) - } -} - dependencies { - implementation("dev.architectury.loom:dev.architectury.loom.gradle.plugin:${properties["arch_loom_version"]}") + implementation(libs.fabric.loom) + implementation(libs.mdg) } diff --git a/buildSrc/settings.gradle.kts b/buildSrc/settings.gradle.kts new file mode 100644 index 000000000..57e9af307 --- /dev/null +++ b/buildSrc/settings.gradle.kts @@ -0,0 +1,8 @@ +// https://discuss.gradle.org/t/using-version-catalog-from-buildsrc-buildlogic-xyz-common-conventions-scripts/48534 +dependencyResolutionManagement { + versionCatalogs { + create("libs") { + from(files("../gradle/libs.versions.toml")) + } + } +} diff --git a/buildSrc/src/main/kotlin/dev/engine_room/gradle/jarset/JarSetExtension.kt b/buildSrc/src/main/kotlin/dev/engine_room/gradle/jarset/JarSetExtension.kt index 218984e20..e0b5e222c 100644 --- a/buildSrc/src/main/kotlin/dev/engine_room/gradle/jarset/JarSetExtension.kt +++ b/buildSrc/src/main/kotlin/dev/engine_room/gradle/jarset/JarSetExtension.kt @@ -1,7 +1,5 @@ package dev.engine_room.gradle.jarset -import net.fabricmc.loom.task.RemapJarTask -import net.fabricmc.loom.task.RemapSourcesJarTask import org.gradle.api.Project import org.gradle.api.tasks.SourceSet import org.gradle.jvm.tasks.Jar @@ -15,11 +13,9 @@ open class JarSetExtension(private val project: Project) { val mainSet: JarTaskSet by lazy { val jarTask = project.tasks.named("jar") - val remapJarTask = project.tasks.named("remapJar") val sourcesJarTask = project.tasks.named("sourcesJar") - val remapSourcesJarTask = project.tasks.named("remapSourcesJar") val javadocJarTask = project.tasks.named("javadocJar") - JarTaskSet(project, "main", jarTask, sourcesJarTask, javadocJarTask, remapJarTask, remapSourcesJarTask) + JarTaskSet(project, "main", jarTask, sourcesJarTask, javadocJarTask) } } diff --git a/buildSrc/src/main/kotlin/dev/engine_room/gradle/jarset/JarTaskSet.kt b/buildSrc/src/main/kotlin/dev/engine_room/gradle/jarset/JarTaskSet.kt index e4e1881f3..f8676a0bb 100644 --- a/buildSrc/src/main/kotlin/dev/engine_room/gradle/jarset/JarTaskSet.kt +++ b/buildSrc/src/main/kotlin/dev/engine_room/gradle/jarset/JarTaskSet.kt @@ -1,8 +1,5 @@ package dev.engine_room.gradle.jarset -import net.fabricmc.loom.task.AbstractRemapJarTask -import net.fabricmc.loom.task.RemapJarTask -import net.fabricmc.loom.task.RemapSourcesJarTask import org.gradle.api.Action import org.gradle.api.NamedDomainObjectProvider import org.gradle.api.Project @@ -27,24 +24,18 @@ class JarTaskSet( val jar: TaskProvider, val sources: TaskProvider, val javadocJar: TaskProvider, - val remapJar: TaskProvider, - val remapSources: TaskProvider ) { fun publishWithRawSources(action: Action): NamedDomainObjectProvider { return publish(sources, action) } - fun publishWithRemappedSources(action: Action): NamedDomainObjectProvider { - return publish(remapSources, action) - } - private fun publish( sourceJar: TaskProvider, action: Action ): NamedDomainObjectProvider { return project.the().publications.register("${name}RemapMaven") { - artifact(remapJar) + artifact(jar) artifact(sourceJar) artifact(javadocJar) action.execute(this) @@ -52,17 +43,7 @@ class JarTaskSet( } fun outgoing(name: String) { - outgoingRemapJar("${name}Remap") - outgoingJar("${name}Dev") - } - - fun outgoingRemapJar(name: String) { - val config = project.configurations.register(name) { - isCanBeConsumed = true - isCanBeResolved = false - } - - project.artifacts.add(config.name, remapJar) + outgoingJar(name) } fun outgoingJar(name: String) { @@ -75,22 +56,14 @@ class JarTaskSet( } /** - * Configure the assemble task to depend on the remap tasks and javadoc jar. + * Configure the assemble task to depend on the regular jar tasks and javadoc jar. */ fun addToAssemble() { project.tasks.named("assemble").configure { - dependsOn(remapJar, remapSources, javadocJar) + dependsOn(jar, sources, javadocJar) } } - /** - * Configure the remap tasks with the given action. - */ - fun configureRemap(action: Action) { - remapJar.configure(action) - remapSources.configure(action) - } - /** * Configure the jar tasks with the given action. */ @@ -99,16 +72,6 @@ class JarTaskSet( sources.configure(action) } - /** - * Create a new JarTaskSet with the same base jars but new tasks for remapping. - */ - fun forkRemap(newName: String): JarTaskSet { - val remapJarTask = createRemapJar(project, newName, jar) - val remapSourcesTask = createRemapSourcesJar(project, newName, sources) - - return JarTaskSet(project, newName, jar, sources, javadocJar, remapJarTask, remapSourcesTask) - } - companion object { private const val PACKAGE_INFOS_JAVA_PATTERN = "**/package-info.java" private const val BUILD_GROUP: String = "build" @@ -138,10 +101,7 @@ class JarTaskSet( val sourcesTask = createSourcesJar(project, name, sourceSetSet) val javadocJarTask = createJavadocJar(project, name, sourceSetSet) - val remapJarTask = createRemapJar(project, name, jarTask) - val remapSourcesTask = createRemapSourcesJar(project, name, sourcesTask) - - return JarTaskSet(project, name, jarTask, sourcesTask, javadocJarTask, remapJarTask, remapSourcesTask) + return JarTaskSet(project, name, jarTask, sourcesTask, javadocJarTask) } private fun createJar( @@ -206,34 +166,5 @@ class JarTaskSet( from(javadocTask.map { it.outputs }) } } - - private fun createRemapJar( - project: Project, - name: String, - jar: TaskProvider - ): TaskProvider { - return project.tasks.register("${name}RemapJar") { - dependsOn(jar) - group = LOOM_GROUP - destinationDirectory.set(project.layout.buildDirectory.dir("libs/${name}")) - - inputFile.set(jar.flatMap { it.archiveFile }) - } - } - - private fun createRemapSourcesJar( - project: Project, - name: String, - jar: TaskProvider - ): TaskProvider { - return project.tasks.register("${name}RemapSourcesJar") { - dependsOn(jar) - group = LOOM_GROUP - destinationDirectory.set(project.layout.buildDirectory.dir("libs/${name}")) - archiveClassifier.set(SOURCES_CLASSIFIER) - - inputFile.set(jar.flatMap { it.archiveFile }) - } - } } } diff --git a/buildSrc/src/main/kotlin/dev/engine_room/gradle/nullability/GeneratePackageInfosTask.kt b/buildSrc/src/main/kotlin/dev/engine_room/gradle/nullability/GeneratePackageInfosTask.kt index c8787fedd..62173f9e0 100644 --- a/buildSrc/src/main/kotlin/dev/engine_room/gradle/nullability/GeneratePackageInfosTask.kt +++ b/buildSrc/src/main/kotlin/dev/engine_room/gradle/nullability/GeneratePackageInfosTask.kt @@ -41,15 +41,8 @@ open class GeneratePackageInfosTask: DefaultTask() { NioExtensions.withWriter(target.resolve("package-info.java"), closureOf { val packageName = relativePath.toString().replace(File.separator, ".") - write(StringGroovyMethods.stripMargin("""@ParametersAreNonnullByDefault - |@FieldsAreNonnullByDefault - |@MethodsReturnNonnullByDefault + write(StringGroovyMethods.stripMargin("""@org.jspecify.annotations.NullMarked |package $packageName; - | - |import javax.annotation.ParametersAreNonnullByDefault; - | - |import net.minecraft.FieldsAreNonnullByDefault; - |import net.minecraft.MethodsReturnNonnullByDefault; |""")) }) } diff --git a/buildSrc/src/main/kotlin/dev/engine_room/gradle/nullability/PackageInfosExtension.kt b/buildSrc/src/main/kotlin/dev/engine_room/gradle/nullability/PackageInfosExtension.kt index f604e477c..2934ae9fc 100644 --- a/buildSrc/src/main/kotlin/dev/engine_room/gradle/nullability/PackageInfosExtension.kt +++ b/buildSrc/src/main/kotlin/dev/engine_room/gradle/nullability/PackageInfosExtension.kt @@ -28,7 +28,7 @@ open class PackageInfosExtension(private val project: Project) { } sourceSet.java.srcDir(task) - project.tasks.named("ideaSyncTask").configure { + project.tasks.matching { it.name == "ideaSyncTask" || it.name == "neoForgeIdeSync" }.configureEach { finalizedBy(task) } diff --git a/buildSrc/src/main/kotlin/dev/engine_room/gradle/platform/PlatformExtension.kt b/buildSrc/src/main/kotlin/dev/engine_room/gradle/platform/PlatformExtension.kt index 95ed30384..ab5ae4354 100644 --- a/buildSrc/src/main/kotlin/dev/engine_room/gradle/platform/PlatformExtension.kt +++ b/buildSrc/src/main/kotlin/dev/engine_room/gradle/platform/PlatformExtension.kt @@ -1,7 +1,10 @@ package dev.engine_room.gradle.platform import net.fabricmc.loom.api.LoomGradleExtensionAPI -import net.fabricmc.loom.task.RemapJarTask +import net.fabricmc.loom.task.RenderDocRunTask +import net.fabricmc.loom.task.RenderDocRunUITask +import net.neoforged.moddevgradle.dsl.ModDevExtension +import net.neoforged.moddevgradle.dsl.RunModel import org.gradle.api.Project import org.gradle.api.Task import org.gradle.api.tasks.SourceSet @@ -10,6 +13,7 @@ import org.gradle.kotlin.dsl.assign import org.gradle.kotlin.dsl.named import org.gradle.kotlin.dsl.register import org.gradle.kotlin.dsl.the +import org.gradle.kotlin.dsl.withType import java.io.File open class PlatformExtension(val project: Project) { @@ -19,11 +23,21 @@ open class PlatformExtension(val project: Project) { } } + fun setupMdgMod(vararg sourceSets: SourceSet) { + project.the().mods.maybeCreate("main").apply { + sourceSets.forEach(::sourceSet) + } + } + fun setupLoomRuns() { project.the().runs.apply { named("client") { isIdeConfigGenerated = true + // Better hotswap, only available with the JetBrains Runtime so we have to ignore invalid options aswell + jvmArguments.add("-XX:+IgnoreUnrecognizedVMOptions") + jvmArguments.add("-XX:+AllowEnhancedClassRedefinition") + // Turn on our own debug flags property("flw.dumpShaderSource", "true") property("flw.debugMemorySafety", "true") @@ -32,6 +46,8 @@ open class PlatformExtension(val project: Project) { property("mixin.debug.export", "true") property("mixin.debug.verbose", "true") + programArgs("--renderDebugLabels") + // 720p baby! programArgs("--width", "1280", "--height", "720") } @@ -42,27 +58,61 @@ open class PlatformExtension(val project: Project) { programArgs("--nogui") } } + + + if (System.getProperty("os.name") == "Linux") { + project.tasks.withType { + renderDocExecutable.set(File("/usr/bin/renderdoccmd")) + } + + project.tasks.withType { + renderDocExecutable.set(File("/usr/bin/qrenderdoc")) + } + } + } + + fun setupMdgRuns() { + project.the().runs.apply { + create("client") { + client() + + // Better hotswap, only available with the JetBrains Runtime so we have to ignore invalid options aswell + jvmArgument("-XX:+IgnoreUnrecognizedVMOptions") + jvmArgument("-XX:+AllowEnhancedClassRedefinition") + + // Turn on our own debug flags + systemProperty("flw.dumpShaderSource", "true") + systemProperty("flw.debugMemorySafety", "true") + + // Turn on mixin debug flags + systemProperty("mixin.debug.export", "true") + systemProperty("mixin.debug.verbose", "true") + + // 720p baby! + programArguments.addAll("--width", "1280", "--height", "720") + + // Helpful when debugging issues + programArguments.addAll("--renderDebugLabels", "--vulkanValidation") + } + + // We're a client mod, but we need to make sure we correctly render when playing on a server. + create("server") { + server() + + programArgument("--nogui") + } + } } fun setupTestMod(sourceSet: SourceSet) { project.tasks.apply { val testModJar = register("testModJar") { from(sourceSet.output) - val file = File(project.layout.buildDirectory.asFile.get(), "devlibs"); - destinationDirectory.set(file) - archiveClassifier = "testmod" - } - - val remapTestModJar = register("remapTestModJar") { - dependsOn(testModJar) - inputFile.set(testModJar.get().archiveFile) archiveClassifier = "testmod" - addNestedDependencies = false - classpath.from(sourceSet.compileClasspath) } named("build").configure { - dependsOn(remapTestModJar) + dependsOn(testModJar) } } } diff --git a/buildSrc/src/main/kotlin/dev/engine_room/gradle/subproject/SubprojectExtension.kt b/buildSrc/src/main/kotlin/dev/engine_room/gradle/subproject/SubprojectExtension.kt index d11d31f65..544f16cdb 100644 --- a/buildSrc/src/main/kotlin/dev/engine_room/gradle/subproject/SubprojectExtension.kt +++ b/buildSrc/src/main/kotlin/dev/engine_room/gradle/subproject/SubprojectExtension.kt @@ -1,6 +1,5 @@ package dev.engine_room.gradle.subproject -import net.fabricmc.loom.api.LoomGradleExtensionAPI import org.gradle.api.JavaVersion import org.gradle.api.Project import org.gradle.api.plugins.BasePluginExtension @@ -24,8 +23,6 @@ open class SubprojectExtension(val project: Project) { setBaseProperties(archiveBase, group, version) setupJava() addRepositories() - setupLoom() - setupDependencies() configureTasks() setupPublishing() } @@ -51,11 +48,6 @@ open class SubprojectExtension(val project: Project) { } } - private fun setupLoom() { - val loom = project.the() - loom.silentMojangMappingsLicense() - } - private fun setupJava() { val java_version: String by project @@ -86,6 +78,12 @@ open class SubprojectExtension(val project: Project) { includeGroup("curse.maven") } } + maven("https://maven.caffeinemc.net/releases") { + name = "CaffeineMC" + content { + includeGroup("net.caffeinemc") + } + } maven("https://api.modrinth.com/maven") { name = "Modrinth" content { @@ -95,25 +93,6 @@ open class SubprojectExtension(val project: Project) { } } - @Suppress("UnstableApiUsage") - private fun setupDependencies() { - project.dependencies.apply { - val minecraft_version: String by project - val parchment_minecraft_version: String by project - val parchment_version: String by project - val loom = project.the() - - add("minecraft", "com.mojang:minecraft:${minecraft_version}") - - add("mappings", loom.layered { - officialMojangMappings() - parchment("org.parchmentmc.data:parchment-${parchment_minecraft_version}:${parchment_version}@zip") - }) - - add("api", "com.google.code.findbugs:jsr305:3.0.2") - } - } - private fun configureTasks() { val java_version: String by project @@ -136,9 +115,10 @@ open class SubprojectExtension(val project: Project) { } withType().configureEach { - from("${project.rootDir}/LICENSE.md") { - into("META-INF") - } + // TODO +// from("${project.rootDir}/LICENSE.md") { +// into("META-INF") +// } } withType().configureEach { diff --git a/buildSrc/src/main/kotlin/dev/engine_room/gradle/transitive/TransitiveSourceSetsExtension.kt b/buildSrc/src/main/kotlin/dev/engine_room/gradle/transitive/TransitiveSourceSetsExtension.kt index 2fb1478e7..b04550de4 100644 --- a/buildSrc/src/main/kotlin/dev/engine_room/gradle/transitive/TransitiveSourceSetsExtension.kt +++ b/buildSrc/src/main/kotlin/dev/engine_room/gradle/transitive/TransitiveSourceSetsExtension.kt @@ -33,9 +33,9 @@ open class TransitiveSourceSetsExtension(val project: Project) { transitives.forEach { (sourceSet, configurator) -> project.configurations.named(sourceSet.compileOnlyConfigurationName).configure { - extendsFrom(configs[sourceSet]) + extendsFrom(configs[sourceSet]!!) configurator.compileSourceSets.forEach { - extendsFrom(configs[it]) + extendsFrom(configs[it]!!) } } } @@ -51,9 +51,9 @@ open class TransitiveSourceSetsExtension(val project: Project) { transitives.forEach { (sourceSet, configurator) -> project.configurations.named(sourceSet.runtimeOnlyConfigurationName).configure { - extendsFrom(configs[sourceSet]) + extendsFrom(configs[sourceSet]!!) configurator.runtimeSourceSets.forEach { - extendsFrom(configs[it]) + extendsFrom(configs[it]!!) } } } diff --git a/common/build.gradle.kts b/common/build.gradle.kts index 8f5e344dc..01fea2101 100644 --- a/common/build.gradle.kts +++ b/common/build.gradle.kts @@ -2,7 +2,7 @@ plugins { idea java `maven-publish` - id("dev.architectury.loom") + alias(libs.plugins.loom) id("flywheel.subproject") } @@ -15,6 +15,10 @@ val stubs = sourceSets.create("stubs") val main = sourceSets.getByName("main") val vanillin = sourceSets.create("vanillin") +loom { + accessWidenerPath = file("flywheel-common.accesswidener") +} + transitiveSourceSets { compileClasspath = main.compileClasspath @@ -58,72 +62,39 @@ jarSets { // For publishing. create("api", api, lib).apply { addToAssemble() - publishWithRemappedSources { - artifactId = "flywheel-common-intermediary-api-${property("artifact_minecraft_version")}" - } - configureJar { - manifest { - attributes("Fabric-Loom-Remap" to "true") - } - } - - // Don't publish the un-remapped jars because they don't have the correct manifest populated by Loom. - forkRemap("apiMojmap").apply { - addToAssemble() - configureRemap { - // "named" == mojmap - // We're probably remapping from named to named so Loom should noop this. - targetNamespace = "named" - } - - publishWithRawSources { - artifactId = "flywheel-common-mojmap-api-${property("artifact_minecraft_version")}" - } + publishWithRawSources { + artifactId = "flywheel-common-api-${property("artifact_minecraft_version")}" } } create("vanillin", vanillin).apply { addToAssemble() - publishWithRemappedSources { - artifactId = "vanillin-common-intermediary-${property("artifact_minecraft_version")}" + + publishWithRawSources { + artifactId = "vanillin-common-${property("artifact_minecraft_version")}" version = property("vanillin_version") as String groupId = property("vanillin_group") as String } - - configureJar { - manifest { - attributes("Fabric-Loom-Remap" to "true") - } - } - - // Don't publish the un-remapped jars because they don't have the correct manifest populated by Loom. - forkRemap("vanillinMojmap").apply { - addToAssemble() - configureRemap { - // "named" == mojmap - // We're probably remapping from named to named so Loom should noop this. - targetNamespace = "named" - } - - publishWithRawSources { - artifactId = "vanillin-common-mojmap-${property("artifact_minecraft_version")}" - version = property("vanillin_version") as String - groupId = property("vanillin_group") as String - } - } } } +repositories { + maven("https://maven.caffeinemc.net/releases/") +} + dependencies { - modCompileOnly("net.fabricmc:fabric-loader:${property("fabric_loader_version")}") + minecraft(libs.minecraft) + compileOnly(libs.bundles.mixin) - modCompileOnly("maven.modrinth:sodium:${property("sodium_version")}-fabric") - modCompileOnly("maven.modrinth:iris:${property("iris_version")}-fabric") + compileOnly(libs.sodium.fabric.api) + compileOnly("maven.modrinth:iris:${libs.versions.iris.get()}-fabric") compileOnly(annotationProcessor("io.github.llamalad7:mixinextras-common:0.4.1")!!) - testImplementation("org.junit.jupiter:junit-jupiter:5.8.1") + testImplementation(platform("org.junit:junit-bom:6.0.3")) + testImplementation("org.junit.jupiter:junit-jupiter") + testRuntimeOnly("org.junit.platform:junit-platform-launcher") } tasks.test { diff --git a/common/flywheel-common.accesswidener b/common/flywheel-common.accesswidener new file mode 100644 index 000000000..4e3281a69 --- /dev/null +++ b/common/flywheel-common.accesswidener @@ -0,0 +1,2 @@ +accessWidener v2 official +accessible class com/mojang/blaze3d/opengl/GlDevice diff --git a/common/src/api/java/dev/engine_room/flywheel/api/backend/Engine.java b/common/src/api/java/dev/engine_room/flywheel/api/backend/Engine.java index b44ee31ff..8356ec08f 100644 --- a/common/src/api/java/dev/engine_room/flywheel/api/backend/Engine.java +++ b/common/src/api/java/dev/engine_room/flywheel/api/backend/Engine.java @@ -9,7 +9,7 @@ import dev.engine_room.flywheel.api.task.Plan; import dev.engine_room.flywheel.api.visualization.VisualizationContext; import it.unimi.dsi.fastutil.longs.LongSet; -import net.minecraft.client.Camera; +import net.minecraft.client.renderer.state.level.CameraRenderState; import net.minecraft.core.BlockPos; import net.minecraft.core.SectionPos; import net.minecraft.core.Vec3i; @@ -43,7 +43,7 @@ public interface Engine { * * @return {@code true} if the render origin changed, {@code false} otherwise. */ - boolean updateRenderOrigin(Camera camera); + boolean updateRenderOrigin(CameraRenderState cameraRenderState); /** * Assign the set of sections that visuals have requested GPU light for. diff --git a/common/src/api/java/dev/engine_room/flywheel/api/backend/RenderContext.java b/common/src/api/java/dev/engine_room/flywheel/api/backend/RenderContext.java index e78df1aad..b52e32963 100644 --- a/common/src/api/java/dev/engine_room/flywheel/api/backend/RenderContext.java +++ b/common/src/api/java/dev/engine_room/flywheel/api/backend/RenderContext.java @@ -2,10 +2,11 @@ import org.joml.Matrix4fc; -import net.minecraft.client.Camera; import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.client.renderer.LevelRenderer; import net.minecraft.client.renderer.RenderBuffers; +import net.minecraft.client.renderer.state.level.CameraRenderState; +import net.minecraft.client.renderer.state.level.LevelRenderState; public interface RenderContext { LevelRenderer renderer(); @@ -20,7 +21,9 @@ public interface RenderContext { Matrix4fc viewProjection(); - Camera camera(); + CameraRenderState cameraRenderState(); + + LevelRenderState levelRenderState(); float partialTick(); } diff --git a/common/src/api/java/dev/engine_room/flywheel/api/instance/InstanceType.java b/common/src/api/java/dev/engine_room/flywheel/api/instance/InstanceType.java index fd5c726b1..5081c54e3 100644 --- a/common/src/api/java/dev/engine_room/flywheel/api/instance/InstanceType.java +++ b/common/src/api/java/dev/engine_room/flywheel/api/instance/InstanceType.java @@ -1,7 +1,7 @@ package dev.engine_room.flywheel.api.instance; import dev.engine_room.flywheel.api.layout.Layout; -import net.minecraft.resources.ResourceLocation; +import net.minecraft.resources.Identifier; /** * An InstanceType contains metadata for a specific instance that Flywheel can interface with. @@ -44,9 +44,9 @@ public interface InstanceType { * space to world space in whatever way the instance type requires. * * @return The vertex shader for this instance type. - * @apiNote {@code flywheel/} is implicitly prepended to the {@link ResourceLocation}'s path. + * @apiNote {@code flywheel/} is implicitly prepended to the {@link Identifier}'s path. */ - ResourceLocation vertexShader(); + Identifier vertexShader(); /** * The cull shader of this instance type. @@ -56,7 +56,7 @@ public interface InstanceType { * by the vertex shader would be contained by the output bounding sphere. * * @return The cull shader for this instance type. - * @apiNote {@code flywheel/} is implicitly prepended to the {@link ResourceLocation}'s path. + * @apiNote {@code flywheel/} is implicitly prepended to the {@link Identifier}'s path. */ - ResourceLocation cullShader(); + Identifier cullShader(); } diff --git a/common/src/api/java/dev/engine_room/flywheel/api/instance/Instancer.java b/common/src/api/java/dev/engine_room/flywheel/api/instance/Instancer.java index 704f0a9b4..d1de1a04c 100644 --- a/common/src/api/java/dev/engine_room/flywheel/api/instance/Instancer.java +++ b/common/src/api/java/dev/engine_room/flywheel/api/instance/Instancer.java @@ -1,6 +1,6 @@ package dev.engine_room.flywheel.api.instance; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import dev.engine_room.flywheel.api.backend.BackendImplemented; diff --git a/common/src/api/java/dev/engine_room/flywheel/api/internal/FlwApiLink.java b/common/src/api/java/dev/engine_room/flywheel/api/internal/FlwApiLink.java index 13e752154..7d4e10191 100644 --- a/common/src/api/java/dev/engine_room/flywheel/api/internal/FlwApiLink.java +++ b/common/src/api/java/dev/engine_room/flywheel/api/internal/FlwApiLink.java @@ -1,6 +1,6 @@ package dev.engine_room.flywheel.api.internal; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import dev.engine_room.flywheel.api.backend.Backend; import dev.engine_room.flywheel.api.layout.LayoutBuilder; diff --git a/common/src/api/java/dev/engine_room/flywheel/api/internal/package-info.java b/common/src/api/java/dev/engine_room/flywheel/api/internal/package-info.java index 9f47a63f6..3854580d0 100644 --- a/common/src/api/java/dev/engine_room/flywheel/api/internal/package-info.java +++ b/common/src/api/java/dev/engine_room/flywheel/api/internal/package-info.java @@ -1,12 +1,6 @@ @ApiStatus.Internal -@ParametersAreNonnullByDefault -@FieldsAreNonnullByDefault -@MethodsReturnNonnullByDefault +@NullMarked package dev.engine_room.flywheel.api.internal; -import javax.annotation.ParametersAreNonnullByDefault; - import org.jetbrains.annotations.ApiStatus; - -import net.minecraft.FieldsAreNonnullByDefault; -import net.minecraft.MethodsReturnNonnullByDefault; +import org.jspecify.annotations.NullMarked; diff --git a/common/src/api/java/dev/engine_room/flywheel/api/material/CutoutShader.java b/common/src/api/java/dev/engine_room/flywheel/api/material/CutoutShader.java index d98910cd5..f4252f0c1 100644 --- a/common/src/api/java/dev/engine_room/flywheel/api/material/CutoutShader.java +++ b/common/src/api/java/dev/engine_room/flywheel/api/material/CutoutShader.java @@ -1,13 +1,13 @@ package dev.engine_room.flywheel.api.material; -import net.minecraft.resources.ResourceLocation; +import net.minecraft.resources.Identifier; /** * A shader that decides what colors should be discarded in the fragment shader. */ public interface CutoutShader { /** - * @apiNote {@code flywheel/} is implicitly prepended to the {@link ResourceLocation}'s path. + * @apiNote {@code flywheel/} is implicitly prepended to the {@link Identifier}'s path. */ - ResourceLocation source(); + Identifier source(); } diff --git a/common/src/api/java/dev/engine_room/flywheel/api/material/FogShader.java b/common/src/api/java/dev/engine_room/flywheel/api/material/FogShader.java index 9a77a873a..88f2fcb85 100644 --- a/common/src/api/java/dev/engine_room/flywheel/api/material/FogShader.java +++ b/common/src/api/java/dev/engine_room/flywheel/api/material/FogShader.java @@ -1,13 +1,13 @@ package dev.engine_room.flywheel.api.material; -import net.minecraft.resources.ResourceLocation; +import net.minecraft.resources.Identifier; /** * A shader that controls the fog effect on a material. */ public interface FogShader { /** - * @apiNote {@code flywheel/} is implicitly prepended to the {@link ResourceLocation}'s path. + * @apiNote {@code flywheel/} is implicitly prepended to the {@link Identifier}'s path. */ - ResourceLocation source(); + Identifier source(); } diff --git a/common/src/api/java/dev/engine_room/flywheel/api/material/LightShader.java b/common/src/api/java/dev/engine_room/flywheel/api/material/LightShader.java index 977d16764..d59819a90 100644 --- a/common/src/api/java/dev/engine_room/flywheel/api/material/LightShader.java +++ b/common/src/api/java/dev/engine_room/flywheel/api/material/LightShader.java @@ -1,13 +1,13 @@ package dev.engine_room.flywheel.api.material; -import net.minecraft.resources.ResourceLocation; +import net.minecraft.resources.Identifier; /** * A shader that controls the GPU-based light on a material. */ public interface LightShader { /** - * @apiNote {@code flywheel/} is implicitly prepended to the {@link ResourceLocation}'s path. + * @apiNote {@code flywheel/} is implicitly prepended to the {@link Identifier}'s path. */ - ResourceLocation source(); + Identifier source(); } diff --git a/common/src/api/java/dev/engine_room/flywheel/api/material/Material.java b/common/src/api/java/dev/engine_room/flywheel/api/material/Material.java index 35d04b9b7..afe6b6b87 100644 --- a/common/src/api/java/dev/engine_room/flywheel/api/material/Material.java +++ b/common/src/api/java/dev/engine_room/flywheel/api/material/Material.java @@ -1,8 +1,8 @@ package dev.engine_room.flywheel.api.material; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; -import net.minecraft.resources.ResourceLocation; +import net.minecraft.resources.Identifier; public interface Material { MaterialShaders shaders(); @@ -13,7 +13,7 @@ public interface Material { LightShader light(); - ResourceLocation texture(); + Identifier texture(); /** * Should this material have linear filtering applied to the diffuse sampler? diff --git a/common/src/api/java/dev/engine_room/flywheel/api/material/MaterialShaders.java b/common/src/api/java/dev/engine_room/flywheel/api/material/MaterialShaders.java index bb8dc76ad..8797e1ff1 100644 --- a/common/src/api/java/dev/engine_room/flywheel/api/material/MaterialShaders.java +++ b/common/src/api/java/dev/engine_room/flywheel/api/material/MaterialShaders.java @@ -1,18 +1,18 @@ package dev.engine_room.flywheel.api.material; -import net.minecraft.resources.ResourceLocation; +import net.minecraft.resources.Identifier; /** * A vertex and fragment shader pair that can be attached to a material. */ public interface MaterialShaders { /** - * @apiNote {@code flywheel/} is implicitly prepended to the {@link ResourceLocation}'s path. + * @apiNote {@code flywheel/} is implicitly prepended to the {@link Identifier}'s path. */ - ResourceLocation vertexSource(); + Identifier vertexSource(); /** - * @apiNote {@code flywheel/} is implicitly prepended to the {@link ResourceLocation}'s path. + * @apiNote {@code flywheel/} is implicitly prepended to the {@link Identifier}'s path. */ - ResourceLocation fragmentSource(); + Identifier fragmentSource(); } diff --git a/common/src/api/java/dev/engine_room/flywheel/api/registry/IdRegistry.java b/common/src/api/java/dev/engine_room/flywheel/api/registry/IdRegistry.java index a2528ce03..9b615f347 100644 --- a/common/src/api/java/dev/engine_room/flywheel/api/registry/IdRegistry.java +++ b/common/src/api/java/dev/engine_room/flywheel/api/registry/IdRegistry.java @@ -4,29 +4,29 @@ import java.util.Set; import org.jetbrains.annotations.ApiStatus; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import org.jetbrains.annotations.UnmodifiableView; -import net.minecraft.resources.ResourceLocation; +import net.minecraft.resources.Identifier; @ApiStatus.NonExtendable public interface IdRegistry extends Iterable { - void register(ResourceLocation id, T object); + void register(Identifier id, T object); - S registerAndGet(ResourceLocation id, S object); + S registerAndGet(Identifier id, S object); @Nullable - T get(ResourceLocation id); + T get(Identifier id); @Nullable - ResourceLocation getId(T object); + Identifier getId(T object); - T getOrThrow(ResourceLocation id); + T getOrThrow(Identifier id); - ResourceLocation getIdOrThrow(T object); + Identifier getIdOrThrow(T object); @UnmodifiableView - Set getAllIds(); + Set getAllIds(); @UnmodifiableView Collection getAll(); diff --git a/common/src/api/java/dev/engine_room/flywheel/api/visual/BlockEntityVisual.java b/common/src/api/java/dev/engine_room/flywheel/api/visual/BlockEntityVisual.java index ea1950376..1d57dbf5a 100644 --- a/common/src/api/java/dev/engine_room/flywheel/api/visual/BlockEntityVisual.java +++ b/common/src/api/java/dev/engine_room/flywheel/api/visual/BlockEntityVisual.java @@ -2,7 +2,7 @@ import java.util.function.Consumer; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import dev.engine_room.flywheel.api.instance.Instance; import net.minecraft.world.level.block.entity.BlockEntity; diff --git a/common/src/api/java/dev/engine_room/flywheel/api/visual/DynamicVisual.java b/common/src/api/java/dev/engine_room/flywheel/api/visual/DynamicVisual.java index 6143f7836..769350066 100644 --- a/common/src/api/java/dev/engine_room/flywheel/api/visual/DynamicVisual.java +++ b/common/src/api/java/dev/engine_room/flywheel/api/visual/DynamicVisual.java @@ -6,7 +6,7 @@ import dev.engine_room.flywheel.api.instance.Instance; import dev.engine_room.flywheel.api.instance.Instancer; import dev.engine_room.flywheel.api.task.Plan; -import net.minecraft.client.Camera; +import net.minecraft.client.renderer.state.level.CameraRenderState; /** * An interface giving {@link Visual}s a hook to have a function called at @@ -32,7 +32,7 @@ public interface DynamicVisual extends Visual { */ @ApiStatus.NonExtendable interface Context { - Camera camera(); + CameraRenderState cameraRenderState(); FrustumIntersection frustum(); diff --git a/common/src/api/java/dev/engine_room/flywheel/api/visualization/VisualizationManager.java b/common/src/api/java/dev/engine_room/flywheel/api/visualization/VisualizationManager.java index 33437d798..c6d215169 100644 --- a/common/src/api/java/dev/engine_room/flywheel/api/visualization/VisualizationManager.java +++ b/common/src/api/java/dev/engine_room/flywheel/api/visualization/VisualizationManager.java @@ -3,7 +3,7 @@ import java.util.SortedSet; import org.jetbrains.annotations.ApiStatus; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import dev.engine_room.flywheel.api.backend.RenderContext; import dev.engine_room.flywheel.api.internal.FlwApiLink; @@ -57,6 +57,7 @@ interface RenderDispatcher { */ void onStartLevelRender(RenderContext ctx); + // TODO 1.21.11: update method name and doc /** * Render instances. * diff --git a/common/src/api/java/dev/engine_room/flywheel/api/visualization/VisualizerRegistry.java b/common/src/api/java/dev/engine_room/flywheel/api/visualization/VisualizerRegistry.java index eda95a7e7..e85a14dd2 100644 --- a/common/src/api/java/dev/engine_room/flywheel/api/visualization/VisualizerRegistry.java +++ b/common/src/api/java/dev/engine_room/flywheel/api/visualization/VisualizerRegistry.java @@ -1,6 +1,6 @@ package dev.engine_room.flywheel.api.visualization; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import dev.engine_room.flywheel.api.internal.FlwApiLink; import net.minecraft.world.entity.Entity; diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/Backends.java b/common/src/backend/java/dev/engine_room/flywheel/backend/Backends.java index d796248ae..da81c642f 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/Backends.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/Backends.java @@ -9,7 +9,7 @@ import dev.engine_room.flywheel.backend.gl.Driver; import dev.engine_room.flywheel.backend.gl.GlCompat; import dev.engine_room.flywheel.lib.backend.SimpleBackend; -import dev.engine_room.flywheel.lib.util.ResourceUtil; +import dev.engine_room.flywheel.lib.util.IdentifierUtil; import dev.engine_room.flywheel.lib.util.ShadersModHelper; public final class Backends { @@ -20,7 +20,7 @@ public final class Backends { .engineFactory(level -> new EngineImpl(level, new InstancedDrawManager(InstancingPrograms.get()), 256)) .priority(500) .supported(() -> GlCompat.SUPPORTS_INSTANCING && InstancingPrograms.allLoaded() && !ShadersModHelper.isShaderPackInUse()) - .register(ResourceUtil.rl("instancing")); + .register(IdentifierUtil.id("instancing")); /** * Use Compute shaders to cull instances. @@ -38,7 +38,7 @@ public final class Backends { } }) .supported(() -> GlCompat.SUPPORTS_INDIRECT && IndirectPrograms.allLoaded() && !ShadersModHelper.isShaderPackInUse()) - .register(ResourceUtil.rl("indirect")); + .register(IdentifierUtil.id("indirect")); private Backends() { } diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/InternalVertex.java b/common/src/backend/java/dev/engine_room/flywheel/backend/InternalVertex.java index beaab64ce..00d5496df 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/InternalVertex.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/InternalVertex.java @@ -6,10 +6,10 @@ import dev.engine_room.flywheel.api.layout.Layout; import dev.engine_room.flywheel.api.layout.LayoutBuilder; import dev.engine_room.flywheel.backend.gl.array.VertexAttribute; -import dev.engine_room.flywheel.lib.util.ResourceUtil; +import dev.engine_room.flywheel.lib.util.IdentifierUtil; import dev.engine_room.flywheel.lib.vertex.FullVertexView; import dev.engine_room.flywheel.lib.vertex.VertexView; -import net.minecraft.resources.ResourceLocation; +import net.minecraft.resources.Identifier; public final class InternalVertex { public static final Layout LAYOUT = LayoutBuilder.create() @@ -24,7 +24,7 @@ public final class InternalVertex { public static final List ATTRIBUTES = LayoutAttributes.attributes(LAYOUT); public static final int STRIDE = LAYOUT.byteSize(); - public static final ResourceLocation LAYOUT_SHADER = ResourceUtil.rl("internal/vertex_input.vert"); + public static final Identifier LAYOUT_SHADER = IdentifierUtil.id("internal/vertex_input.vert"); private InternalVertex() { } diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/LayoutAttributes.java b/common/src/backend/java/dev/engine_room/flywheel/backend/LayoutAttributes.java index 350d1acc6..ca0a71fc4 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/LayoutAttributes.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/LayoutAttributes.java @@ -3,6 +3,8 @@ import java.util.ArrayList; import java.util.List; +import com.mojang.blaze3d.vertex.VertexFormatElement; + import dev.engine_room.flywheel.api.layout.ArrayElementType; import dev.engine_room.flywheel.api.layout.ElementType; import dev.engine_room.flywheel.api.layout.FloatRepr; @@ -13,7 +15,6 @@ import dev.engine_room.flywheel.api.layout.UnsignedIntegerRepr; import dev.engine_room.flywheel.api.layout.ValueRepr; import dev.engine_room.flywheel.api.layout.VectorElementType; -import dev.engine_room.flywheel.backend.gl.GlNumericType; import dev.engine_room.flywheel.backend.gl.array.VertexAttribute; public class LayoutAttributes { @@ -79,31 +80,31 @@ private static void array(List out, ArrayElementType array) { } } - private static GlNumericType toGlType(IntegerRepr repr) { + private static VertexFormatElement.Type toGlType(IntegerRepr repr) { return switch (repr) { - case BYTE -> GlNumericType.BYTE; - case SHORT -> GlNumericType.SHORT; - case INT -> GlNumericType.INT; + case BYTE -> VertexFormatElement.Type.BYTE; + case SHORT -> VertexFormatElement.Type.SHORT; + case INT -> VertexFormatElement.Type.INT; }; } - private static GlNumericType toGlType(UnsignedIntegerRepr repr) { + private static VertexFormatElement.Type toGlType(UnsignedIntegerRepr repr) { return switch (repr) { - case UNSIGNED_BYTE -> GlNumericType.UBYTE; - case UNSIGNED_SHORT -> GlNumericType.USHORT; - case UNSIGNED_INT -> GlNumericType.UINT; + case UNSIGNED_BYTE -> VertexFormatElement.Type.UBYTE; + case UNSIGNED_SHORT -> VertexFormatElement.Type.USHORT; + case UNSIGNED_INT -> VertexFormatElement.Type.UINT; }; } - private static GlNumericType toGlType(FloatRepr repr) { + private static VertexFormatElement.Type toGlType(FloatRepr repr) { return switch (repr) { - case BYTE, NORMALIZED_BYTE -> GlNumericType.BYTE; - case UNSIGNED_BYTE, NORMALIZED_UNSIGNED_BYTE -> GlNumericType.UBYTE; - case SHORT, NORMALIZED_SHORT -> GlNumericType.SHORT; - case UNSIGNED_SHORT, NORMALIZED_UNSIGNED_SHORT -> GlNumericType.USHORT; - case INT, NORMALIZED_INT -> GlNumericType.INT; - case UNSIGNED_INT, NORMALIZED_UNSIGNED_INT -> GlNumericType.UINT; - case FLOAT -> GlNumericType.FLOAT; + case BYTE, NORMALIZED_BYTE -> VertexFormatElement.Type.BYTE; + case UNSIGNED_BYTE, NORMALIZED_UNSIGNED_BYTE -> VertexFormatElement.Type.UBYTE; + case SHORT, NORMALIZED_SHORT -> VertexFormatElement.Type.SHORT; + case UNSIGNED_SHORT, NORMALIZED_UNSIGNED_SHORT -> VertexFormatElement.Type.USHORT; + case INT, NORMALIZED_INT -> VertexFormatElement.Type.INT; + case UNSIGNED_INT, NORMALIZED_UNSIGNED_INT -> VertexFormatElement.Type.UINT; + case FLOAT -> VertexFormatElement.Type.FLOAT; }; } diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/MaterialShaderIndices.java b/common/src/backend/java/dev/engine_room/flywheel/backend/MaterialShaderIndices.java index 71fcbd112..cc9f12536 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/MaterialShaderIndices.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/MaterialShaderIndices.java @@ -11,7 +11,7 @@ import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; import it.unimi.dsi.fastutil.objects.ObjectArrayList; import it.unimi.dsi.fastutil.objects.ObjectList; -import net.minecraft.resources.ResourceLocation; +import net.minecraft.resources.Identifier; public final class MaterialShaderIndices { private static final Index fogSources = new Index(); @@ -37,8 +37,8 @@ public static int cutoutIndex(CutoutShader cutoutShader) { } public static class Index { - private final Object2IntMap sources2Index; - private final ObjectList sources; + private final Object2IntMap sources2Index; + private final ObjectList sources; private Index() { this.sources2Index = new Object2IntOpenHashMap<>(); @@ -46,11 +46,11 @@ private Index() { this.sources = new ObjectArrayList<>(); } - public ResourceLocation get(int index) { + public Identifier get(int index) { return sources.get(index); } - public int index(ResourceLocation source) { + public int index(Identifier source) { var out = sources2Index.getInt(source); if (out == -1) { @@ -63,11 +63,11 @@ public int index(ResourceLocation source) { } @Unmodifiable - public List all() { + public List all() { return sources; } - private void add(ResourceLocation source) { + private void add(Identifier source) { if (sources2Index.putIfAbsent(source, sources.size()) == -1) { sources.add(source); } diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/NoiseTextures.java b/common/src/backend/java/dev/engine_room/flywheel/backend/NoiseTextures.java index ba1d66186..0088c2a54 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/NoiseTextures.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/NoiseTextures.java @@ -3,19 +3,20 @@ import java.io.IOException; import org.jetbrains.annotations.UnknownNullability; -import org.lwjgl.opengl.GL32; +import com.mojang.blaze3d.opengl.GlConst; +import com.mojang.blaze3d.opengl.GlStateManager; +import com.mojang.blaze3d.opengl.GlTexture; import com.mojang.blaze3d.platform.NativeImage; -import com.mojang.blaze3d.systems.RenderSystem; import dev.engine_room.flywheel.backend.gl.GlTextureUnit; -import dev.engine_room.flywheel.lib.util.ResourceUtil; +import dev.engine_room.flywheel.lib.util.IdentifierUtil; import net.minecraft.client.renderer.texture.DynamicTexture; -import net.minecraft.resources.ResourceLocation; +import net.minecraft.resources.Identifier; import net.minecraft.server.packs.resources.ResourceManager; public class NoiseTextures { - public static final ResourceLocation NOISE_TEXTURE = ResourceUtil.rl("textures/flywheel/noise/blue.png"); + public static final Identifier NOISE_TEXTURE = IdentifierUtil.id("textures/flywheel/noise/blue.png"); @UnknownNullability public static DynamicTexture BLUE_NOISE; @@ -35,16 +36,18 @@ public static void reload(ResourceManager manager) { .open()) { var image = NativeImage.read(NativeImage.Format.LUMINANCE, is); - BLUE_NOISE = new DynamicTexture(image); + // TODO 1.21.11: maybe we should not use DynamicTexture here and do gen/upload manually + BLUE_NOISE = new DynamicTexture(() -> "Flywheel Blue Noise", image); GlTextureUnit.T0.makeActive(); - BLUE_NOISE.bind(); + GlStateManager._bindTexture(((GlTexture) BLUE_NOISE.getTexture()).glId()); - NoiseTextures.BLUE_NOISE.setFilter(true, false); - RenderSystem.texParameter(GL32.GL_TEXTURE_2D, GL32.GL_TEXTURE_WRAP_S, GL32.GL_REPEAT); - RenderSystem.texParameter(GL32.GL_TEXTURE_2D, GL32.GL_TEXTURE_WRAP_T, GL32.GL_REPEAT); + GlStateManager._texParameter(GlConst.GL_TEXTURE_2D, GlConst.GL_TEXTURE_MIN_FILTER, GlConst.GL_LINEAR); + GlStateManager._texParameter(GlConst.GL_TEXTURE_2D, GlConst.GL_TEXTURE_MAG_FILTER, GlConst.GL_LINEAR); + GlStateManager._texParameter(GlConst.GL_TEXTURE_2D, GlConst.GL_TEXTURE_WRAP_S, GlConst.GL_REPEAT); + GlStateManager._texParameter(GlConst.GL_TEXTURE_2D, GlConst.GL_TEXTURE_WRAP_T, GlConst.GL_REPEAT); - RenderSystem.bindTexture(0); + GlStateManager._bindTexture(0); } catch (IOException e) { } diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/compile/ContextShader.java b/common/src/backend/java/dev/engine_room/flywheel/backend/compile/ContextShader.java index 7c8aac5dd..51a559747 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/compile/ContextShader.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/compile/ContextShader.java @@ -3,7 +3,7 @@ import java.util.Locale; import java.util.function.Consumer; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import dev.engine_room.flywheel.backend.Samplers; import dev.engine_room.flywheel.backend.compile.core.Compilation; diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/compile/FlwPrograms.java b/common/src/backend/java/dev/engine_room/flywheel/backend/compile/FlwPrograms.java index 2dbc6cfb8..67def8bc2 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/compile/FlwPrograms.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/compile/FlwPrograms.java @@ -8,14 +8,14 @@ import dev.engine_room.flywheel.api.Flywheel; import dev.engine_room.flywheel.backend.glsl.ShaderSources; import dev.engine_room.flywheel.backend.glsl.SourceComponent; -import dev.engine_room.flywheel.lib.util.ResourceUtil; -import net.minecraft.resources.ResourceLocation; +import dev.engine_room.flywheel.lib.util.IdentifierUtil; +import net.minecraft.resources.Identifier; import net.minecraft.server.packs.resources.ResourceManager; public final class FlwPrograms { public static final Logger LOGGER = LoggerFactory.getLogger(Flywheel.ID + "/backend/shaders"); - private static final ResourceLocation COMPONENTS_HEADER_FRAG = ResourceUtil.rl("internal/components_header.frag"); + private static final Identifier COMPONENTS_HEADER_FRAG = IdentifierUtil.id("internal/components_header.frag"); public static ShaderSources SOURCES; diff --git a/neoforge/src/backend/java/dev/engine_room/flywheel/backend/compile/FlwProgramsReloader.java b/common/src/backend/java/dev/engine_room/flywheel/backend/compile/FlwProgramsReloader.java similarity index 77% rename from neoforge/src/backend/java/dev/engine_room/flywheel/backend/compile/FlwProgramsReloader.java rename to common/src/backend/java/dev/engine_room/flywheel/backend/compile/FlwProgramsReloader.java index e3350f108..23017874b 100644 --- a/neoforge/src/backend/java/dev/engine_room/flywheel/backend/compile/FlwProgramsReloader.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/compile/FlwProgramsReloader.java @@ -1,10 +1,14 @@ package dev.engine_room.flywheel.backend.compile; import dev.engine_room.flywheel.backend.NoiseTextures; +import dev.engine_room.flywheel.lib.util.IdentifierUtil; +import net.minecraft.resources.Identifier; import net.minecraft.server.packs.resources.ResourceManager; import net.minecraft.server.packs.resources.ResourceManagerReloadListener; public final class FlwProgramsReloader implements ResourceManagerReloadListener { + public static final Identifier ID = IdentifierUtil.id("programs"); + public static final FlwProgramsReloader INSTANCE = new FlwProgramsReloader(); private FlwProgramsReloader() { diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/compile/IndirectPrograms.java b/common/src/backend/java/dev/engine_room/flywheel/backend/compile/IndirectPrograms.java index d03980ed7..88a4ab763 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/compile/IndirectPrograms.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/compile/IndirectPrograms.java @@ -2,7 +2,7 @@ import java.util.List; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import com.google.common.collect.ImmutableList; @@ -20,19 +20,19 @@ import dev.engine_room.flywheel.backend.glsl.ShaderSources; import dev.engine_room.flywheel.backend.glsl.SourceComponent; import dev.engine_room.flywheel.backend.util.AtomicReferenceCounted; -import dev.engine_room.flywheel.lib.util.ResourceUtil; -import net.minecraft.resources.ResourceLocation; +import dev.engine_room.flywheel.lib.util.IdentifierUtil; +import net.minecraft.resources.Identifier; public class IndirectPrograms extends AtomicReferenceCounted { - private static final ResourceLocation CULL_SHADER_API_IMPL = ResourceUtil.rl("internal/indirect/cull_api_impl.glsl"); - private static final ResourceLocation CULL_SHADER_MAIN = ResourceUtil.rl("internal/indirect/cull.glsl"); - private static final ResourceLocation APPLY_SHADER_MAIN = ResourceUtil.rl("internal/indirect/apply.glsl"); - private static final ResourceLocation SCATTER_SHADER_MAIN = ResourceUtil.rl("internal/indirect/scatter.glsl"); - private static final ResourceLocation DOWNSAMPLE_FIRST = ResourceUtil.rl("internal/indirect/downsample_first.glsl"); - private static final ResourceLocation DOWNSAMPLE_SECOND = ResourceUtil.rl("internal/indirect/downsample_second.glsl"); + private static final Identifier CULL_SHADER_API_IMPL = IdentifierUtil.id("internal/indirect/cull_api_impl.glsl"); + private static final Identifier CULL_SHADER_MAIN = IdentifierUtil.id("internal/indirect/cull.glsl"); + private static final Identifier APPLY_SHADER_MAIN = IdentifierUtil.id("internal/indirect/apply.glsl"); + private static final Identifier SCATTER_SHADER_MAIN = IdentifierUtil.id("internal/indirect/scatter.glsl"); + private static final Identifier DOWNSAMPLE_FIRST = IdentifierUtil.id("internal/indirect/downsample_first.glsl"); + private static final Identifier DOWNSAMPLE_SECOND = IdentifierUtil.id("internal/indirect/downsample_second.glsl"); private static final Compile> CULL = new Compile<>(); - private static final Compile UTIL = new Compile<>(); + private static final Compile UTIL = new Compile<>(); private static final List EXTENSIONS = getExtensions(GlCompat.MAX_GLSL_VERSION); private static final List COMPUTE_EXTENSIONS = getComputeExtensions(GlCompat.MAX_GLSL_VERSION); @@ -42,10 +42,10 @@ public class IndirectPrograms extends AtomicReferenceCounted { private final PipelineCompiler pipeline; private final CompilationHarness> culling; - private final CompilationHarness utils; + private final CompilationHarness utils; private final OitPrograms oitPrograms; - private IndirectPrograms(PipelineCompiler pipeline, CompilationHarness> culling, CompilationHarness utils, OitPrograms oitPrograms) { + private IndirectPrograms(PipelineCompiler pipeline, CompilationHarness> culling, CompilationHarness utils, OitPrograms oitPrograms) { this.pipeline = pipeline; this.culling = culling; this.utils = utils; @@ -103,7 +103,7 @@ static void reload(ShaderSources sources, List vertexComponents private static CompilationHarness> createCullingCompiler(ShaderSources sources) { return CULL.program() .link(CULL.shader(GlCompat.MAX_GLSL_VERSION, ShaderType.COMPUTE) - .nameMapper(instanceType -> "culling/" + ResourceUtil.toDebugFileNameNoExtension(instanceType.cullShader())) + .nameMapper(instanceType -> "culling/" + IdentifierUtil.toDebugFileNameNoExtension(instanceType.cullShader())) .requireExtensions(COMPUTE_EXTENSIONS) .define("_FLW_SUBGROUP_SIZE", GlCompat.SUBGROUP_SIZE) .withResource(CULL_SHADER_API_IMPL) @@ -116,12 +116,12 @@ private static CompilationHarness> createCullingCompiler(ShaderS } /** - * A compiler for utility shaders, directly compiles the shader at the resource location specified by the parameter. + * A compiler for utility shaders, directly compiles the shader at the resource id specified by the parameter. */ - private static CompilationHarness createUtilCompiler(ShaderSources sources) { + private static CompilationHarness createUtilCompiler(ShaderSources sources) { return UTIL.program() .link(UTIL.shader(GlCompat.MAX_GLSL_VERSION, ShaderType.COMPUTE) - .nameMapper(resourceLocation -> "utilities/" + ResourceUtil.toDebugFileNameNoExtension(resourceLocation)) + .nameMapper(id -> "utilities/" + IdentifierUtil.toDebugFileNameNoExtension(id)) .requireExtensions(COMPUTE_EXTENSIONS) .define("_FLW_SUBGROUP_SIZE", GlCompat.SUBGROUP_SIZE) .withResource(s -> s)) diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/compile/InstancingPrograms.java b/common/src/backend/java/dev/engine_room/flywheel/backend/compile/InstancingPrograms.java index 96704fbbc..de4ec99d8 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/compile/InstancingPrograms.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/compile/InstancingPrograms.java @@ -2,7 +2,7 @@ import java.util.List; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import com.google.common.collect.ImmutableList; diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/compile/OitPrograms.java b/common/src/backend/java/dev/engine_room/flywheel/backend/compile/OitPrograms.java index 3b55448eb..5e13b4ac3 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/compile/OitPrograms.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/compile/OitPrograms.java @@ -10,19 +10,19 @@ import dev.engine_room.flywheel.backend.gl.shader.ShaderType; import dev.engine_room.flywheel.backend.glsl.GlslVersion; import dev.engine_room.flywheel.backend.glsl.ShaderSources; -import dev.engine_room.flywheel.lib.util.ResourceUtil; -import net.minecraft.resources.ResourceLocation; +import dev.engine_room.flywheel.lib.util.IdentifierUtil; +import net.minecraft.resources.Identifier; public class OitPrograms { - private static final ResourceLocation FULLSCREEN = ResourceUtil.rl("internal/fullscreen.vert"); - static final ResourceLocation OIT_COMPOSITE = ResourceUtil.rl("internal/oit_composite.frag"); - static final ResourceLocation OIT_DEPTH = ResourceUtil.rl("internal/oit_depth.frag"); + private static final Identifier FULLSCREEN = IdentifierUtil.id("internal/fullscreen.vert"); + static final Identifier OIT_COMPOSITE = IdentifierUtil.id("internal/oit_composite.frag"); + static final Identifier OIT_DEPTH = IdentifierUtil.id("internal/oit_depth.frag"); - private static final Compile COMPILE = new Compile<>(); + private static final Compile COMPILE = new Compile<>(); - private final CompilationHarness harness; + private final CompilationHarness harness; - public OitPrograms(CompilationHarness harness) { + public OitPrograms(CompilationHarness harness) { this.harness = harness; } @@ -32,8 +32,8 @@ public static OitPrograms createFullscreenCompiler(ShaderSources sources) { .nameMapper($ -> "fullscreen/fullscreen") .withResource(FULLSCREEN)) .link(COMPILE.shader(GlCompat.MAX_GLSL_VERSION, ShaderType.FRAGMENT) - .nameMapper(rl -> "fullscreen/" + ResourceUtil.toDebugFileNameNoExtension(rl)) - .onCompile((rl, compilation) -> { + .nameMapper(id -> "fullscreen/" + IdentifierUtil.toDebugFileNameNoExtension(id)) + .onCompile((id, compilation) -> { if (GlCompat.MAX_GLSL_VERSION.compareTo(GlslVersion.V400) < 0) { // Need to define FMA for the wavelet calculations compilation.define("fma(a, b, c) ((a) * (b) + (c))"); diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/compile/Pipeline.java b/common/src/backend/java/dev/engine_room/flywheel/backend/compile/Pipeline.java index 92a11c4b4..c26515b8a 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/compile/Pipeline.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/compile/Pipeline.java @@ -3,15 +3,15 @@ import java.util.Objects; import java.util.function.Consumer; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import dev.engine_room.flywheel.api.instance.Instance; import dev.engine_room.flywheel.api.instance.InstanceType; import dev.engine_room.flywheel.backend.gl.shader.GlProgram; import dev.engine_room.flywheel.backend.glsl.SourceComponent; -import net.minecraft.resources.ResourceLocation; +import net.minecraft.resources.Identifier; -public record Pipeline(ResourceLocation vertexMain, ResourceLocation fragmentMain, +public record Pipeline(Identifier vertexMain, Identifier fragmentMain, InstanceAssembler assembler, String compilerMarker, Consumer onLink) { @FunctionalInterface @@ -30,9 +30,9 @@ public static Builder builder() { public static class Builder { @Nullable - private ResourceLocation vertexMain; + private Identifier vertexMain; @Nullable - private ResourceLocation fragmentMain; + private Identifier fragmentMain; @Nullable private InstanceAssembler assembler; @Nullable @@ -40,12 +40,12 @@ public static class Builder { @Nullable private Consumer onLink; - public Builder vertexMain(ResourceLocation shader) { + public Builder vertexMain(Identifier shader) { this.vertexMain = shader; return this; } - public Builder fragmentMain(ResourceLocation shader) { + public Builder fragmentMain(Identifier shader) { this.fragmentMain = shader; return this; } diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/compile/PipelineCompiler.java b/common/src/backend/java/dev/engine_room/flywheel/backend/compile/PipelineCompiler.java index 7a73c4425..7900dffaf 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/compile/PipelineCompiler.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/compile/PipelineCompiler.java @@ -29,8 +29,8 @@ import dev.engine_room.flywheel.backend.glsl.generate.FnSignature; import dev.engine_room.flywheel.backend.glsl.generate.GlslExpr; import dev.engine_room.flywheel.lib.material.CutoutShaders; -import dev.engine_room.flywheel.lib.util.ResourceUtil; -import net.minecraft.resources.ResourceLocation; +import dev.engine_room.flywheel.lib.util.IdentifierUtil; +import net.minecraft.resources.Identifier; public final class PipelineCompiler { private static final Set ALL = Collections.newSetFromMap(new WeakHashMap<>()); @@ -40,8 +40,8 @@ public final class PipelineCompiler { private static UberShaderComponent FOG; private static UberShaderComponent CUTOUT; - private static final ResourceLocation API_IMPL_VERT = ResourceUtil.rl("internal/api_impl.vert"); - private static final ResourceLocation API_IMPL_FRAG = ResourceUtil.rl("internal/api_impl.frag"); + private static final Identifier API_IMPL_VERT = IdentifierUtil.id("internal/api_impl.vert"); + private static final Identifier API_IMPL_FRAG = IdentifierUtil.id("internal/api_impl.frag"); private final CompilationHarness harness; @@ -85,10 +85,10 @@ static PipelineCompiler create(ShaderSources sources, Pipeline pipeline, List { - var instance = ResourceUtil.toDebugFileNameNoExtension(key.instanceType() + var instance = IdentifierUtil.toDebugFileNameNoExtension(key.instanceType() .vertexShader()); - var material = ResourceUtil.toDebugFileNameNoExtension(key.materialShaders() + var material = IdentifierUtil.toDebugFileNameNoExtension(key.materialShaders() .vertexSource()); var context = key.contextShader() .nameLowerCase(); @@ -127,10 +127,10 @@ static PipelineCompiler create(ShaderSources sources, Pipeline pipeline, List { program.setSamplerBinding("_flw_instances", Samplers.INSTANCE_BUFFER); @@ -20,8 +20,8 @@ public final class Pipelines { public static final Pipeline INDIRECT = Pipeline.builder() .compilerMarker("indirect") - .vertexMain(ResourceUtil.rl("internal/indirect/main.vert")) - .fragmentMain(ResourceUtil.rl("internal/indirect/main.frag")) + .vertexMain(IdentifierUtil.id("internal/indirect/main.vert")) + .fragmentMain(IdentifierUtil.id("internal/indirect/main.frag")) .assembler(SsboInstanceComponent::new) .onLink($ -> { }) diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/compile/component/BufferTextureInstanceComponent.java b/common/src/backend/java/dev/engine_room/flywheel/backend/compile/component/BufferTextureInstanceComponent.java index aa421e13f..ac309eff6 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/compile/component/BufferTextureInstanceComponent.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/compile/component/BufferTextureInstanceComponent.java @@ -10,7 +10,7 @@ import dev.engine_room.flywheel.backend.glsl.generate.GlslExpr; import dev.engine_room.flywheel.backend.glsl.generate.GlslStmt; import dev.engine_room.flywheel.lib.math.MoreMath; -import dev.engine_room.flywheel.lib.util.ResourceUtil; +import dev.engine_room.flywheel.lib.util.IdentifierUtil; public class BufferTextureInstanceComponent extends InstanceAssemblerComponent { private static final String[] SWIZZLE_SELECTORS = { "x", "y", "z", "w" }; @@ -21,7 +21,7 @@ public BufferTextureInstanceComponent(InstanceType type) { @Override public String name() { - return ResourceUtil.rl("buffer_texture_instance_assembler").toString(); + return IdentifierUtil.id("buffer_texture_instance_assembler").toString(); } @Override diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/compile/component/InstanceStructComponent.java b/common/src/backend/java/dev/engine_room/flywheel/backend/compile/component/InstanceStructComponent.java index ac743e578..e3fb3083f 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/compile/component/InstanceStructComponent.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/compile/component/InstanceStructComponent.java @@ -8,7 +8,7 @@ import dev.engine_room.flywheel.backend.compile.LayoutInterpreter; import dev.engine_room.flywheel.backend.glsl.SourceComponent; import dev.engine_room.flywheel.backend.glsl.generate.GlslBuilder; -import dev.engine_room.flywheel.lib.util.ResourceUtil; +import dev.engine_room.flywheel.lib.util.IdentifierUtil; public class InstanceStructComponent implements SourceComponent { private static final String STRUCT_NAME = "FlwInstance"; @@ -21,7 +21,7 @@ public InstanceStructComponent(InstanceType type) { @Override public String name() { - return ResourceUtil.rl("instance_struct").toString(); + return IdentifierUtil.id("instance_struct").toString(); } @Override diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/compile/component/SsboInstanceComponent.java b/common/src/backend/java/dev/engine_room/flywheel/backend/compile/component/SsboInstanceComponent.java index 1151343db..b0492e17a 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/compile/component/SsboInstanceComponent.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/compile/component/SsboInstanceComponent.java @@ -11,7 +11,7 @@ import dev.engine_room.flywheel.backend.glsl.generate.GlslExpr; import dev.engine_room.flywheel.backend.glsl.generate.GlslStmt; import dev.engine_room.flywheel.lib.math.MoreMath; -import dev.engine_room.flywheel.lib.util.ResourceUtil; +import dev.engine_room.flywheel.lib.util.IdentifierUtil; public class SsboInstanceComponent extends InstanceAssemblerComponent { public SsboInstanceComponent(InstanceType type) { @@ -20,7 +20,7 @@ public SsboInstanceComponent(InstanceType type) { @Override public String name() { - return ResourceUtil.rl("ssbo_instance_assembler").toString(); + return IdentifierUtil.id("ssbo_instance_assembler").toString(); } @Override diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/compile/component/StringSubstitutionComponent.java b/common/src/backend/java/dev/engine_room/flywheel/backend/compile/component/StringSubstitutionComponent.java index 1960c283b..3e9b87d38 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/compile/component/StringSubstitutionComponent.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/compile/component/StringSubstitutionComponent.java @@ -4,7 +4,7 @@ import java.util.Map; import dev.engine_room.flywheel.backend.glsl.SourceComponent; -import dev.engine_room.flywheel.lib.util.ResourceUtil; +import dev.engine_room.flywheel.lib.util.IdentifierUtil; public final class StringSubstitutionComponent implements SourceComponent { private final SourceComponent source; @@ -42,7 +42,7 @@ public String source() { @Override public String name() { - return ResourceUtil.rl("string_substitution").toString() + " / " + source.name(); + return IdentifierUtil.id("string_substitution").toString() + " / " + source.name(); } @Override diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/compile/component/UberShaderComponent.java b/common/src/backend/java/dev/engine_room/flywheel/backend/compile/component/UberShaderComponent.java index f98aebd10..ce75cf45b 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/compile/component/UberShaderComponent.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/compile/component/UberShaderComponent.java @@ -5,7 +5,7 @@ import java.util.List; import java.util.function.UnaryOperator; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; @@ -18,29 +18,29 @@ import dev.engine_room.flywheel.backend.glsl.generate.GlslBuilder; import dev.engine_room.flywheel.backend.glsl.generate.GlslExpr; import dev.engine_room.flywheel.backend.glsl.generate.GlslSwitch; -import dev.engine_room.flywheel.lib.util.ResourceUtil; -import net.minecraft.resources.ResourceLocation; +import dev.engine_room.flywheel.lib.util.IdentifierUtil; +import net.minecraft.resources.Identifier; public class UberShaderComponent implements SourceComponent { - private final ResourceLocation name; + private final Identifier name; private final GlslExpr switchArg; private final List functionsToAdapt; private final List adaptedComponents; - private UberShaderComponent(ResourceLocation name, GlslExpr switchArg, List functionsToAdapt, List adaptedComponents) { + private UberShaderComponent(Identifier name, GlslExpr switchArg, List functionsToAdapt, List adaptedComponents) { this.name = name; this.switchArg = switchArg; this.functionsToAdapt = functionsToAdapt; this.adaptedComponents = adaptedComponents; } - public static Builder builder(ResourceLocation name) { + public static Builder builder(Identifier name) { return new Builder(name); } @Override public String name() { - return ResourceUtil.rl("uber_shader").toString() + " / " + name; + return IdentifierUtil.id("uber_shader").toString() + " / " + name; } @Override @@ -106,17 +106,17 @@ private record AdaptedFn(FnSignature signature, @Nullable GlslExpr defaultReturn } public static class Builder { - private final ResourceLocation name; - private final List materialSources = new ArrayList<>(); + private final Identifier name; + private final List materialSources = new ArrayList<>(); private final List adaptedFunctions = new ArrayList<>(); @Nullable private GlslExpr switchArg; - public Builder(ResourceLocation name) { + public Builder(Identifier name) { this.name = name; } - public Builder materialSources(List sources) { + public Builder materialSources(List sources) { this.materialSources.addAll(sources); return this; } diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/compile/core/Compilation.java b/common/src/backend/java/dev/engine_room/flywheel/backend/compile/core/Compilation.java index 9891a151b..0ff730fd3 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/compile/core/Compilation.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/compile/core/Compilation.java @@ -5,7 +5,8 @@ import java.util.ArrayList; import java.util.List; -import org.lwjgl.opengl.GL20; +import com.mojang.blaze3d.opengl.GlConst; +import com.mojang.blaze3d.opengl.GlStateManager; import dev.engine_room.flywheel.backend.compile.FlwPrograms; import dev.engine_room.flywheel.backend.gl.GlCompat; @@ -16,6 +17,7 @@ import dev.engine_room.flywheel.backend.glsl.SourceFile; import dev.engine_room.flywheel.lib.util.StringUtil; import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.ShaderManager; /** * Builder style class for compiling shaders. @@ -32,22 +34,22 @@ public class Compilation { private int generatedLines = 0; public ShaderResult compile(ShaderType shaderType, String name) { - int handle = GL20.glCreateShader(shaderType.glEnum); + int handle = GlStateManager.glCreateShader(shaderType.glEnum); var source = fullSource.toString(); GlCompat.safeShaderSource(handle, source); - GL20.glCompileShader(handle); + GlStateManager.glCompileShader(handle); var shaderName = name + "." + shaderType.extension; dumpSource(source, shaderName); - var infoLog = GL20.glGetShaderInfoLog(handle); + var infoLog = GlStateManager.glGetShaderInfoLog(handle, ShaderManager.MAX_LOG_LENGTH); if (compiledSuccessfully(handle)) { return ShaderResult.success(new GlShader(handle, shaderType, shaderName), infoLog); } - GL20.glDeleteShader(handle); + GlStateManager.glDeleteShader(handle); return ShaderResult.failure(new FailedCompilation(shaderName, files, generatedSource.toString(), source, infoLog)); } @@ -134,6 +136,6 @@ private static void dumpSource(String source, String fileName) { } public static boolean compiledSuccessfully(int handle) { - return GL20.glGetShaderi(handle, GL20.GL_COMPILE_STATUS) == GL20.GL_TRUE; + return GlStateManager.glGetShaderi(handle, GlConst.GL_COMPILE_STATUS) == GlConst.GL_TRUE; } } diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/compile/core/Compile.java b/common/src/backend/java/dev/engine_room/flywheel/backend/compile/core/Compile.java index 28ae49964..58d1e3345 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/compile/core/Compile.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/compile/core/Compile.java @@ -18,7 +18,7 @@ import dev.engine_room.flywheel.backend.glsl.ShaderSources; import dev.engine_room.flywheel.backend.glsl.SourceComponent; import dev.engine_room.flywheel.lib.util.StringUtil; -import net.minecraft.resources.ResourceLocation; +import net.minecraft.resources.Identifier; /** * A typed provider for shader compiler builders. @@ -75,12 +75,12 @@ public ShaderCompiler withComponent(Function sourceFetche return with((key, $) -> sourceFetcher.apply(key)); } - public ShaderCompiler withResource(Function sourceFetcher) { + public ShaderCompiler withResource(Function sourceFetcher) { return with((key, loader) -> loader.get(sourceFetcher.apply(key))); } - public ShaderCompiler withResource(ResourceLocation resourceLocation) { - return withResource($ -> resourceLocation); + public ShaderCompiler withResource(Identifier id) { + return withResource($ -> id); } public ShaderCompiler onCompile(BiConsumer cb) { diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/compile/core/FailedCompilation.java b/common/src/backend/java/dev/engine_room/flywheel/backend/compile/core/FailedCompilation.java index 20f3b3012..de5763bad 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/compile/core/FailedCompilation.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/compile/core/FailedCompilation.java @@ -8,7 +8,7 @@ import java.util.stream.Collectors; import java.util.stream.Stream; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import dev.engine_room.flywheel.backend.glsl.SourceFile; import dev.engine_room.flywheel.backend.glsl.SourceLines; @@ -16,12 +16,12 @@ import dev.engine_room.flywheel.backend.glsl.error.ErrorBuilder; import dev.engine_room.flywheel.backend.glsl.error.ErrorLevel; import dev.engine_room.flywheel.backend.glsl.span.Span; -import dev.engine_room.flywheel.lib.util.ResourceUtil; +import dev.engine_room.flywheel.lib.util.IdentifierUtil; import dev.engine_room.flywheel.lib.util.StringUtil; -import net.minecraft.resources.ResourceLocation; +import net.minecraft.resources.Identifier; public class FailedCompilation { - public static final ResourceLocation GENERATED_SOURCE_NAME = ResourceUtil.rl("generated_source"); + public static final Identifier GENERATED_SOURCE_NAME = IdentifierUtil.id("generated_source"); private static final Pattern PATTERN_ONE = Pattern.compile("(\\d+)\\((\\d+)\\) : (.*)"); private static final Pattern PATTERN_TWO = Pattern.compile("(\\w+): (\\d+):(\\d+):(?: '(.+?)' :)?(.*)"); private final List files; diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/compile/core/LinkResult.java b/common/src/backend/java/dev/engine_room/flywheel/backend/compile/core/LinkResult.java index cb28347c6..aa6541d34 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/compile/core/LinkResult.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/compile/core/LinkResult.java @@ -1,7 +1,5 @@ package dev.engine_room.flywheel.backend.compile.core; -import org.jetbrains.annotations.NotNull; - import dev.engine_room.flywheel.backend.gl.shader.GlProgram; public sealed interface LinkResult { @@ -9,7 +7,6 @@ public sealed interface LinkResult { record Success(GlProgram program, String log) implements LinkResult { @Override - @NotNull public GlProgram unwrap() { return program; } diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/compile/core/ProgramLinker.java b/common/src/backend/java/dev/engine_room/flywheel/backend/compile/core/ProgramLinker.java index 94ad675a6..6c334de9e 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/compile/core/ProgramLinker.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/compile/core/ProgramLinker.java @@ -1,18 +1,14 @@ package dev.engine_room.flywheel.backend.compile.core; -import static org.lwjgl.opengl.GL11.GL_TRUE; -import static org.lwjgl.opengl.GL20.GL_LINK_STATUS; -import static org.lwjgl.opengl.GL20.glAttachShader; -import static org.lwjgl.opengl.GL20.glCreateProgram; -import static org.lwjgl.opengl.GL20.glGetProgramInfoLog; -import static org.lwjgl.opengl.GL20.glGetProgrami; -import static org.lwjgl.opengl.GL20.glLinkProgram; - import java.util.List; import java.util.function.Consumer; +import com.mojang.blaze3d.opengl.GlConst; +import com.mojang.blaze3d.opengl.GlStateManager; + import dev.engine_room.flywheel.backend.gl.shader.GlProgram; import dev.engine_room.flywheel.backend.gl.shader.GlShader; +import net.minecraft.client.renderer.ShaderManager; public class ProgramLinker { @@ -25,17 +21,17 @@ public GlProgram link(List shaders, Consumer preLink) { } private LinkResult linkInternal(List shaders, Consumer preLink) { - int handle = glCreateProgram(); + int handle = GlStateManager.glCreateProgram(); var out = new GlProgram(handle); for (GlShader shader : shaders) { - glAttachShader(handle, shader.handle()); + GlStateManager.glAttachShader(handle, shader.handle()); } preLink.accept(out); - glLinkProgram(handle); - String log = glGetProgramInfoLog(handle); + GlStateManager.glLinkProgram(handle); + String log = GlStateManager.glGetProgramInfoLog(handle, ShaderManager.MAX_LOG_LENGTH); if (linkSuccessful(handle)) { return LinkResult.success(out, log); @@ -46,7 +42,7 @@ private LinkResult linkInternal(List shaders, Consumer preL } private static boolean linkSuccessful(int handle) { - return glGetProgrami(handle, GL_LINK_STATUS) == GL_TRUE; + return GlStateManager.glGetProgrami(handle, GlConst.GL_LINK_STATUS) == GlConst.GL_TRUE; } } diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/BaseInstancer.java b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/BaseInstancer.java index eae6d73cb..d7cd18295 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/BaseInstancer.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/BaseInstancer.java @@ -2,7 +2,7 @@ import java.util.ArrayList; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import dev.engine_room.flywheel.api.instance.Instance; import dev.engine_room.flywheel.backend.util.AtomicBitSet; diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/CommonCrumbling.java b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/CommonCrumbling.java index b636c8aa1..e64a7dddf 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/CommonCrumbling.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/CommonCrumbling.java @@ -16,7 +16,7 @@ public static void applyCrumblingProperties(SimpleMaterial.Builder crumblingMate .cutout(CutoutShaders.ONE_TENTH) .light(LightShaders.SMOOTH_WHEN_EMBEDDED) .polygonOffset(true) - .transparency(Transparency.CRUMBLING) + .transparency(Transparency.OPAQUE) .writeMask(WriteMask.COLOR) .useOverlay(false) .useLight(false) diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/DrawManager.java b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/DrawManager.java index 70dc64d2d..d652c882b 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/DrawManager.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/DrawManager.java @@ -9,7 +9,7 @@ import java.util.concurrent.ConcurrentLinkedQueue; import java.util.function.Function; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import com.mojang.datafixers.util.Pair; diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/EngineImpl.java b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/EngineImpl.java index b91212eff..28c9c95c1 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/EngineImpl.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/EngineImpl.java @@ -19,7 +19,7 @@ import dev.engine_room.flywheel.backend.engine.uniform.Uniforms; import dev.engine_room.flywheel.backend.gl.GlStateTracker; import it.unimi.dsi.fastutil.longs.LongSet; -import net.minecraft.client.Camera; +import net.minecraft.client.renderer.state.level.CameraRenderState; import net.minecraft.core.BlockPos; import net.minecraft.core.SectionPos; import net.minecraft.core.Vec3i; @@ -59,8 +59,8 @@ public Vec3i renderOrigin() { } @Override - public boolean updateRenderOrigin(Camera camera) { - Vec3 cameraPos = camera.getPosition(); + public boolean updateRenderOrigin(CameraRenderState cameraRenderState) { + Vec3 cameraPos = cameraRenderState.pos; double dx = renderOrigin.getX() - cameraPos.x; double dy = renderOrigin.getY() - cameraPos.y; double dz = renderOrigin.getZ() - cameraPos.z; diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/LightDataCollector.java b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/LightDataCollector.java index 1639ee7cc..d79c55a3e 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/LightDataCollector.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/LightDataCollector.java @@ -3,10 +3,10 @@ import java.util.BitSet; import java.util.Objects; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import org.lwjgl.system.MemoryUtil; -import dev.engine_room.flywheel.backend.SkyLightSectionStorageExtension; +import dev.engine_room.flywheel.backend.extension.SkyLightSectionStorageExtension; import dev.engine_room.flywheel.backend.mixin.light.LayerLightSectionStorageAccessor; import dev.engine_room.flywheel.backend.mixin.light.LightEngineAccessor; import it.unimi.dsi.fastutil.longs.Long2ObjectFunction; diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/LightLut.java b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/LightLut.java index 987ae674b..23a32c7ac 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/LightLut.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/LightLut.java @@ -3,7 +3,7 @@ import java.util.function.BiConsumer; import java.util.function.Supplier; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import it.unimi.dsi.fastutil.ints.IntArrayList; import net.minecraft.core.SectionPos; diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/LightStorage.java b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/LightStorage.java index 8462cdb9b..efb853bad 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/LightStorage.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/LightStorage.java @@ -2,7 +2,7 @@ import java.util.BitSet; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import org.lwjgl.system.MemoryUtil; import dev.engine_room.flywheel.api.task.Plan; @@ -25,9 +25,9 @@ import it.unimi.dsi.fastutil.longs.Long2IntOpenHashMap; import it.unimi.dsi.fastutil.longs.LongOpenHashSet; import it.unimi.dsi.fastutil.longs.LongSet; -import net.minecraft.client.renderer.LightTexture; import net.minecraft.core.SectionPos; import net.minecraft.core.Vec3i; +import net.minecraft.util.LightCoordsUtil; import net.minecraft.world.level.LevelAccessor; /** @@ -292,7 +292,7 @@ private void setupSectionBoxes() { .translate(x + 1, y + 1, z + 1) .scale(14) .color(255, 255, 0) - .light(LightTexture.FULL_BRIGHT) + .light(LightCoordsUtil.FULL_BRIGHT) .setChanged(); }); } @@ -357,7 +357,7 @@ private void setupLutRangeBoxes() { .translate(x2, y2, debug3) .scale(1, 1, size3 * 16) .color(0, 0, 255) - .light(LightTexture.FULL_BRIGHT) + .light(LightCoordsUtil.FULL_BRIGHT) .setChanged(); } } @@ -367,7 +367,7 @@ private void setupLutRangeBoxes() { .translate(debug2, y2, minLocal3 * 16 - renderOrigin.getZ()) .scale(size2 * 16, 1, (maxLocal3 - minLocal3) * 16) .color(255, 0, 0) - .light(LightTexture.FULL_BRIGHT) + .light(LightCoordsUtil.FULL_BRIGHT) .setChanged(); } @@ -376,7 +376,7 @@ private void setupLutRangeBoxes() { .translate(min2 * 16 - renderOrigin.getX(), debug1, min3 * 16 - renderOrigin.getZ()) .scale((max2 - min2) * 16, size1 * 16, (max3 - min3) * 16) .color(0, 255, 0) - .light(LightTexture.FULL_BRIGHT) + .light(LightCoordsUtil.FULL_BRIGHT) .setChanged(); } diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/MaterialRenderState.java b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/MaterialRenderState.java index 5d4eec2b2..c6556e7b9 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/MaterialRenderState.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/MaterialRenderState.java @@ -2,11 +2,17 @@ import java.util.Comparator; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import org.lwjgl.opengl.GL11; -import com.mojang.blaze3d.platform.GlStateManager; +import com.mojang.blaze3d.opengl.GlConst; +import com.mojang.blaze3d.opengl.GlSampler; +import com.mojang.blaze3d.opengl.GlStateManager; +import com.mojang.blaze3d.opengl.GlTextureView; +import com.mojang.blaze3d.pipeline.ColorTargetState; import com.mojang.blaze3d.systems.RenderSystem; +import com.mojang.blaze3d.textures.FilterMode; +import com.mojang.blaze3d.textures.GpuSampler; import dev.engine_room.flywheel.api.material.DepthTest; import dev.engine_room.flywheel.api.material.Material; @@ -39,74 +45,78 @@ public static void setupOit(Material material) { WriteMask mask = material.writeMask(); boolean writeColor = mask.color(); - RenderSystem.colorMask(writeColor, writeColor, writeColor, writeColor); + GlStateManager._colorMask(writeColor ? ColorTargetState.WRITE_ALL : ColorTargetState.WRITE_NONE); } private static void setupTexture(Material material) { - Samplers.DIFFUSE.makeActive(); AbstractTexture texture = Minecraft.getInstance() .getTextureManager() .getTexture(material.texture()); - texture.setFilter(material.blur(), material.mipmap()); - var textureId = texture.getId(); - RenderSystem.setShaderTexture(0, textureId); - RenderSystem.bindTexture(textureId); + + // TODO 1.21.11: give the Material more control, such as using default filter mode, address modes, AF, max LOD? + FilterMode filterMode = material.blur() ? FilterMode.LINEAR : FilterMode.NEAREST; + GpuSampler defaultSampler = texture.getSampler(); + GpuSampler sampler = RenderSystem.getSamplerCache() + .getSampler(defaultSampler.getAddressModeU(), defaultSampler.getAddressModeV(), filterMode, filterMode, material.mipmap()); + + /// TODO 1.21.11: should cubemap textures be allowed? + TextureBinder.bind(Samplers.DIFFUSE.number, texture.getTextureView(), sampler); } private static void setupBackfaceCulling(boolean backfaceCulling) { if (backfaceCulling) { - RenderSystem.enableCull(); + GlStateManager._enableCull(); } else { - RenderSystem.disableCull(); + GlStateManager._disableCull(); } } private static void setupPolygonOffset(boolean polygonOffset) { if (polygonOffset) { - RenderSystem.polygonOffset(-1.0F, -10.0F); - RenderSystem.enablePolygonOffset(); + GlStateManager._polygonOffset(-1.0F, -10.0F); + GlStateManager._enablePolygonOffset(); } else { - RenderSystem.polygonOffset(0.0F, 0.0F); - RenderSystem.disablePolygonOffset(); + GlStateManager._polygonOffset(0.0F, 0.0F); + GlStateManager._disablePolygonOffset(); } } private static void setupDepthTest(DepthTest depthTest) { switch (depthTest) { case OFF -> { - RenderSystem.disableDepthTest(); + GlStateManager._disableDepthTest(); } case NEVER -> { - RenderSystem.enableDepthTest(); - RenderSystem.depthFunc(GL11.GL_NEVER); + GlStateManager._enableDepthTest(); + GlStateManager._depthFunc(GL11.GL_NEVER); } case LESS -> { - RenderSystem.enableDepthTest(); - RenderSystem.depthFunc(GL11.GL_LESS); + GlStateManager._enableDepthTest(); + GlStateManager._depthFunc(GlConst.GL_LESS); } case EQUAL -> { - RenderSystem.enableDepthTest(); - RenderSystem.depthFunc(GL11.GL_EQUAL); + GlStateManager._enableDepthTest(); + GlStateManager._depthFunc(GlConst.GL_EQUAL); } case LEQUAL -> { - RenderSystem.enableDepthTest(); - RenderSystem.depthFunc(GL11.GL_LEQUAL); + GlStateManager._enableDepthTest(); + GlStateManager._depthFunc(GlConst.GL_LEQUAL); } case GREATER -> { - RenderSystem.enableDepthTest(); - RenderSystem.depthFunc(GL11.GL_GREATER); + GlStateManager._enableDepthTest(); + GlStateManager._depthFunc(GlConst.GL_GREATER); } case NOTEQUAL -> { - RenderSystem.enableDepthTest(); - RenderSystem.depthFunc(GL11.GL_NOTEQUAL); + GlStateManager._enableDepthTest(); + GlStateManager._depthFunc(GL11.GL_NOTEQUAL); } case GEQUAL -> { - RenderSystem.enableDepthTest(); - RenderSystem.depthFunc(GL11.GL_GEQUAL); + GlStateManager._enableDepthTest(); + GlStateManager._depthFunc(GlConst.GL_GEQUAL); } case ALWAYS -> { - RenderSystem.enableDepthTest(); - RenderSystem.depthFunc(GL11.GL_ALWAYS); + GlStateManager._enableDepthTest(); + GlStateManager._depthFunc(GlConst.GL_ALWAYS); } } } @@ -114,73 +124,35 @@ private static void setupDepthTest(DepthTest depthTest) { private static void setupTransparency(Transparency transparency) { switch (transparency) { case OPAQUE -> { - RenderSystem.disableBlend(); + GlStateManager._disableBlend(); } case ADDITIVE -> { - RenderSystem.enableBlend(); - RenderSystem.blendFunc(GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ONE); + GlStateManager._enableBlend(); + GlStateManager._blendFuncSeparate(GlConst.GL_ONE, GlConst.GL_ONE, GlConst.GL_ONE, GlConst.GL_ONE); } case LIGHTNING -> { - RenderSystem.enableBlend(); - RenderSystem.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE); + GlStateManager._enableBlend(); + GlStateManager._blendFuncSeparate(GlConst.GL_SRC_ALPHA, GlConst.GL_ONE, GlConst.GL_SRC_ALPHA, GlConst.GL_ONE); } case GLINT -> { - RenderSystem.enableBlend(); - RenderSystem.blendFuncSeparate(GlStateManager.SourceFactor.SRC_COLOR, GlStateManager.DestFactor.ONE, GlStateManager.SourceFactor.ZERO, GlStateManager.DestFactor.ONE); + GlStateManager._enableBlend(); + GlStateManager._blendFuncSeparate(GlConst.GL_SRC_COLOR, GlConst.GL_ONE, GlConst.GL_ZERO, GlConst.GL_ONE); } case CRUMBLING -> { - RenderSystem.enableBlend(); - RenderSystem.blendFuncSeparate(GlStateManager.SourceFactor.DST_COLOR, GlStateManager.DestFactor.SRC_COLOR, GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ZERO); + GlStateManager._enableBlend(); + GlStateManager._blendFuncSeparate(GlConst.GL_DST_COLOR, GlConst.GL_SRC_COLOR, GlConst.GL_ONE, GlConst.GL_ZERO); } case TRANSLUCENT -> { - RenderSystem.enableBlend(); - RenderSystem.blendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA); + GlStateManager._enableBlend(); + GlStateManager._blendFuncSeparate(GlConst.GL_SRC_ALPHA, GlConst.GL_ONE_MINUS_SRC_ALPHA, GlConst.GL_ONE, GlConst.GL_ONE_MINUS_SRC_ALPHA); } } } private static void setupWriteMask(WriteMask mask) { - RenderSystem.depthMask(mask.depth()); + GlStateManager._depthMask(mask.depth()); boolean writeColor = mask.color(); - RenderSystem.colorMask(writeColor, writeColor, writeColor, writeColor); - } - - public static void reset() { - resetTexture(); - resetBackfaceCulling(); - resetPolygonOffset(); - resetDepthTest(); - resetTransparency(); - resetWriteMask(); - } - - private static void resetTexture() { - Samplers.DIFFUSE.makeActive(); - RenderSystem.setShaderTexture(0, 0); - } - - private static void resetBackfaceCulling() { - RenderSystem.enableCull(); - } - - private static void resetPolygonOffset() { - RenderSystem.polygonOffset(0.0F, 0.0F); - RenderSystem.disablePolygonOffset(); - } - - private static void resetDepthTest() { - RenderSystem.disableDepthTest(); - RenderSystem.depthFunc(GL11.GL_LEQUAL); - } - - private static void resetTransparency() { - RenderSystem.disableBlend(); - RenderSystem.defaultBlendFunc(); - } - - private static void resetWriteMask() { - RenderSystem.depthMask(true); - RenderSystem.colorMask(true, true, true, true); + GlStateManager._colorMask(writeColor ? ColorTargetState.WRITE_ALL : ColorTargetState.WRITE_NONE); } public static boolean materialEquals(Material lhs, Material rhs) { diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/MeshPool.java b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/MeshPool.java index e1766d4e4..15a9bb7c7 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/MeshPool.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/MeshPool.java @@ -5,12 +5,14 @@ import java.util.List; import java.util.Map; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import org.lwjgl.opengl.GL32; +import com.mojang.blaze3d.opengl.GlConst; +import com.mojang.blaze3d.vertex.VertexFormat; + import dev.engine_room.flywheel.api.model.Mesh; import dev.engine_room.flywheel.backend.InternalVertex; -import dev.engine_room.flywheel.backend.gl.GlPrimitive; import dev.engine_room.flywheel.backend.gl.array.GlVertexArray; import dev.engine_room.flywheel.backend.gl.buffer.GlBuffer; import dev.engine_room.flywheel.backend.gl.buffer.GlBufferUsage; @@ -181,9 +183,10 @@ public boolean isInvalid() { public void draw(int instanceCount) { if (instanceCount > 1) { - GL32.glDrawElementsInstancedBaseVertex(GlPrimitive.TRIANGLES.glEnum, mesh.indexCount(), GL32.GL_UNSIGNED_INT, firstIndexByteOffset(), instanceCount, baseVertex); + + GL32.glDrawElementsInstancedBaseVertex(GlConst.toGl(VertexFormat.Mode.TRIANGLES), mesh.indexCount(), GlConst.GL_UNSIGNED_INT, firstIndexByteOffset(), instanceCount, baseVertex); } else { - GL32.glDrawElementsBaseVertex(GlPrimitive.TRIANGLES.glEnum, mesh.indexCount(), GL32.GL_UNSIGNED_INT, firstIndexByteOffset(), baseVertex); + GL32.glDrawElementsBaseVertex(GlConst.toGl(VertexFormat.Mode.TRIANGLES), mesh.indexCount(), GlConst.GL_UNSIGNED_INT, firstIndexByteOffset(), baseVertex); } } diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/TextureBinder.java b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/TextureBinder.java index 5d5f48da2..f42cbf0dd 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/TextureBinder.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/TextureBinder.java @@ -1,49 +1,70 @@ package dev.engine_room.flywheel.backend.engine; +import java.util.Collections; + +import org.jspecify.annotations.Nullable; +import org.lwjgl.opengl.GL33C; + +import com.mojang.blaze3d.opengl.GlConst; +import com.mojang.blaze3d.opengl.GlDevice; +import com.mojang.blaze3d.opengl.GlSampler; +import com.mojang.blaze3d.opengl.GlStateManager; +import com.mojang.blaze3d.opengl.GlTexture; +import com.mojang.blaze3d.pipeline.RenderTarget; import com.mojang.blaze3d.systems.RenderSystem; +import com.mojang.blaze3d.textures.FilterMode; +import com.mojang.blaze3d.textures.GpuSampler; +import com.mojang.blaze3d.textures.GpuTexture; +import com.mojang.blaze3d.textures.GpuTextureView; import dev.engine_room.flywheel.backend.Samplers; +import dev.engine_room.flywheel.backend.gl.GlUtil; import net.minecraft.client.Minecraft; -import net.minecraft.resources.ResourceLocation; +import net.minecraft.resources.Identifier; public class TextureBinder { - public static void bind(ResourceLocation resourceLocation) { - RenderSystem.bindTexture(byName(resourceLocation)); - } + public static void bind(int unit, Identifier textureId, @Nullable GpuSampler sampler) { + GpuTextureView texture = Minecraft.getInstance() + .getTextureManager() + .getTexture(textureId) + .getTextureView(); - public static void bindLightAndOverlay() { - var gameRenderer = Minecraft.getInstance().gameRenderer; + bind(unit, texture, sampler); + } - Samplers.OVERLAY.makeActive(); - gameRenderer.overlayTexture() - .setupOverlayColor(); - RenderSystem.bindTexture(RenderSystem.getShaderTexture(1)); + // Taken from GlCommandEncoder.trySetup + public static void bind(int unit, GpuTextureView textureView, @Nullable GpuSampler sampler) { + GlStateManager._activeTexture(GlConst.GL_TEXTURE0 + unit); + GlTexture texture = (GlTexture) textureView.texture(); + int i; + if ((texture.usage() & GpuTexture.USAGE_CUBEMAP_COMPATIBLE) != 0) { + i = GL33C.GL_TEXTURE_CUBE_MAP; + GL33C.glBindTexture(i, texture.glId()); + } else { + i = GlConst.GL_TEXTURE_2D; + GlStateManager._bindTexture(texture.glId()); + } - Samplers.LIGHT.makeActive(); - gameRenderer.lightTexture() - .turnOnLightLayer(); - RenderSystem.bindTexture(RenderSystem.getShaderTexture(2)); + if (sampler != null) { + GL33C.glBindSampler(unit, ((GlSampler) sampler).getId()); + GlStateManager._texParameter(i, GL33C.GL_TEXTURE_BASE_LEVEL, textureView.baseMipLevel()); + GlStateManager._texParameter(i, GL33C.GL_TEXTURE_MAX_LEVEL, textureView.baseMipLevel() + textureView.mipLevels() - 1); + } } - public static void resetLightAndOverlay() { + public static void bindLightAndOverlay() { var gameRenderer = Minecraft.getInstance().gameRenderer; - - gameRenderer.overlayTexture() - .teardownOverlayColor(); - gameRenderer.lightTexture() - .turnOffLightLayer(); + GpuSampler sampler = RenderSystem.getSamplerCache().getClampToEdge(FilterMode.LINEAR); + bind(Samplers.OVERLAY.number, gameRenderer.overlayTexture().getTextureView(), sampler); + bind(Samplers.LIGHT.number, gameRenderer.lightmap(), sampler); } - /** - * Get a built-in texture by its resource location. - * - * @param texture The texture's resource location. - * @return The texture. - */ - public static int byName(ResourceLocation texture) { - return Minecraft.getInstance() - .getTextureManager() - .getTexture(texture) - .getId(); + public static void bindRenderTarget(RenderTarget target) { + GlTexture colorTexture = (GlTexture) target.getColorTexture(); + int i = colorTexture.getFbo( + GlUtil.getGlDevice().directStateAccess(), + target.getDepthTexture() + ); + GlStateManager._glBindFramebuffer(GlConst.GL_FRAMEBUFFER, i); } } diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/embed/EmbeddedEnvironment.java b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/embed/EmbeddedEnvironment.java index e45dceec0..1e7c8afb6 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/embed/EmbeddedEnvironment.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/embed/EmbeddedEnvironment.java @@ -1,6 +1,6 @@ package dev.engine_room.flywheel.backend.engine.embed; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import org.joml.Matrix3f; import org.joml.Matrix3fc; import org.joml.Matrix4f; diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/indirect/DepthPyramid.java b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/indirect/DepthPyramid.java index 0f2f642b5..80bd9ab9a 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/indirect/DepthPyramid.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/indirect/DepthPyramid.java @@ -3,7 +3,10 @@ import org.lwjgl.opengl.GL32; import org.lwjgl.opengl.GL46; -import com.mojang.blaze3d.platform.GlStateManager; +import com.mojang.blaze3d.opengl.GlConst; +import com.mojang.blaze3d.opengl.GlStateManager; +import com.mojang.blaze3d.opengl.GlTexture; +import com.mojang.blaze3d.textures.GpuTexture; import dev.engine_room.flywheel.backend.compile.IndirectPrograms; import dev.engine_room.flywheel.backend.gl.GlTextureUnit; @@ -32,7 +35,8 @@ public void generate() { createPyramidMips(mipLevels, width, height); - int depthBufferId = mainRenderTarget.getDepthTextureId(); + GpuTexture depthTexture = mainRenderTarget.getDepthTexture(); + int depthBufferId = depthTexture != null ? ((GlTexture) depthTexture).glId() : 0; GL46.glMemoryBarrier(GL46.GL_FRAMEBUFFER_BARRIER_BIT); @@ -42,7 +46,7 @@ public void generate() { var downsampleFirstProgram = programs.getDownsampleFirstProgram(); downsampleFirstProgram.bind(); - GL46.glBindImageTexture(1, pyramidTextureId, 0, false, 0, GL32.GL_WRITE_ONLY, GL32.GL_R32F); + GL46.glBindImageTexture(1, pyramidTextureId, 0, false, 0, GlConst.GL_WRITE_ONLY, GL32.GL_R32F); GL46.glDispatchCompute(MoreMath.ceilingDiv(width << 1, 64), MoreMath.ceilingDiv(height << 1, 64), 1); var downsampleSecondProgram = programs.getDownsampleSecondProgram(); @@ -55,7 +59,7 @@ public void generate() { downsampleSecondProgram.setUInt("base_mip_level", baseMipLevel); for (int i = 0; i < Math.min(7, mipLevels - baseMipLevel); i++) { - GL46.glBindImageTexture(i, pyramidTextureId, baseMipLevel + i, false, 0, GL32.GL_WRITE_ONLY, GL32.GL_R32F); + GL46.glBindImageTexture(i, pyramidTextureId, baseMipLevel + i, false, 0, GlConst.GL_WRITE_ONLY, GL32.GL_R32F); } GL46.glDispatchCompute(MoreMath.ceilingDiv(width >> baseMipLevel, 64), MoreMath.ceilingDiv(height >> baseMipLevel, 64), 1); @@ -86,14 +90,14 @@ private void createPyramidMips(int mipLevels, int width, int height) { delete(); - pyramidTextureId = GL46.glCreateTextures(GL46.GL_TEXTURE_2D); + pyramidTextureId = GL46.glCreateTextures(GlConst.GL_TEXTURE_2D); GL46.glTextureStorage2D(pyramidTextureId, mipLevels, GL32.GL_R32F, width, height); - GL46.glTextureParameteri(pyramidTextureId, GL32.GL_TEXTURE_MIN_FILTER, GL32.GL_NEAREST); - GL46.glTextureParameteri(pyramidTextureId, GL32.GL_TEXTURE_MAG_FILTER, GL32.GL_NEAREST); - GL46.glTextureParameteri(pyramidTextureId, GL32.GL_TEXTURE_COMPARE_MODE, GL32.GL_NONE); - GL46.glTextureParameteri(pyramidTextureId, GL32.GL_TEXTURE_WRAP_S, GL32.GL_CLAMP_TO_EDGE); - GL46.glTextureParameteri(pyramidTextureId, GL32.GL_TEXTURE_WRAP_T, GL32.GL_CLAMP_TO_EDGE); + GL46.glTextureParameteri(pyramidTextureId, GlConst.GL_TEXTURE_MIN_FILTER, GlConst.GL_NEAREST); + GL46.glTextureParameteri(pyramidTextureId, GlConst.GL_TEXTURE_MAG_FILTER, GlConst.GL_NEAREST); + GL46.glTextureParameteri(pyramidTextureId, GlConst.GL_TEXTURE_COMPARE_MODE, GlConst.GL_NONE); + GL46.glTextureParameteri(pyramidTextureId, GlConst.GL_TEXTURE_WRAP_S, GlConst.GL_CLAMP_TO_EDGE); + GL46.glTextureParameteri(pyramidTextureId, GlConst.GL_TEXTURE_WRAP_T, GlConst.GL_CLAMP_TO_EDGE); } public static int mip0Size(int screenSize) { diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/indirect/IndirectBuffers.java b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/indirect/IndirectBuffers.java index 6280dfc6e..a7b56ff96 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/indirect/IndirectBuffers.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/indirect/IndirectBuffers.java @@ -1,8 +1,7 @@ package dev.engine_room.flywheel.backend.engine.indirect; -import static org.lwjgl.opengl.GL43.GL_SHADER_STORAGE_BUFFER; -import static org.lwjgl.opengl.GL44.nglBindBuffersRange; - +import org.lwjgl.opengl.GL43; +import org.lwjgl.opengl.GL44; import org.lwjgl.system.MemoryUtil; import org.lwjgl.system.Pointer; @@ -116,7 +115,7 @@ public void bindForCrumbling() { private void multiBind(int base, int count) { final long ptr = multiBindBlock.ptr(); - nglBindBuffersRange(GL_SHADER_STORAGE_BUFFER, base, count, ptr + base * INT_SIZE, ptr + OFFSET_OFFSET + base * PTR_SIZE, ptr + SIZE_OFFSET + base * PTR_SIZE); + GL44.nglBindBuffersRange(GL43.GL_SHADER_STORAGE_BUFFER, base, count, ptr + base * INT_SIZE, ptr + OFFSET_OFFSET + base * PTR_SIZE, ptr + SIZE_OFFSET + base * PTR_SIZE); } public void delete() { diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/indirect/IndirectCullingGroup.java b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/indirect/IndirectCullingGroup.java index 3bed52112..ee07ea95f 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/indirect/IndirectCullingGroup.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/indirect/IndirectCullingGroup.java @@ -1,15 +1,14 @@ package dev.engine_room.flywheel.backend.engine.indirect; -import static org.lwjgl.opengl.GL11.GL_TRIANGLES; -import static org.lwjgl.opengl.GL11.GL_UNSIGNED_INT; -import static org.lwjgl.opengl.GL42.GL_COMMAND_BARRIER_BIT; -import static org.lwjgl.opengl.GL42.glMemoryBarrier; -import static org.lwjgl.opengl.GL43.glDispatchCompute; - import java.util.ArrayList; import java.util.Comparator; import java.util.List; +import org.lwjgl.opengl.GL42; +import org.lwjgl.opengl.GL43; + +import com.mojang.blaze3d.opengl.GlConst; + import dev.engine_room.flywheel.api.instance.Instance; import dev.engine_room.flywheel.api.instance.InstanceType; import dev.engine_room.flywheel.api.material.Material; @@ -115,12 +114,12 @@ public void dispatchCull() { cullProgram.bind(); buffers.bindForCull(); - glDispatchCompute(buffers.objectStorage.capacity(), 1, 1); + GL43.glDispatchCompute(buffers.objectStorage.capacity(), 1, 1); } public void dispatchApply() { buffers.bindForApply(); - glDispatchCompute(GlCompat.getComputeGroupCount(indirectDraws.size()), 1, 1); + GL43.glDispatchCompute(GlCompat.getComputeGroupCount(indirectDraws.size()), 1, 1); } public boolean hasOitDraws() { @@ -243,7 +242,7 @@ private void drawBarrier() { if (needsDrawBarrier) { // In theory all command buffer writes will be protected by // the shader storage barrier bit, but better safe than sorry. - glMemoryBarrier(GL_COMMAND_BARRIER_BIT); + GL42.glMemoryBarrier(GL42.GL_COMMAND_BARRIER_BIT); needsDrawBarrier = false; } } @@ -288,7 +287,7 @@ public void delete() { private record MultiDraw(Material material, boolean embedded, int start, int end) { private void submit(GlProgram drawProgram) { - GlCompat.safeMultiDrawElementsIndirect(drawProgram, GL_TRIANGLES, GL_UNSIGNED_INT, this.start, this.end, IndirectBuffers.DRAW_COMMAND_STRIDE); + GlCompat.safeMultiDrawElementsIndirect(drawProgram, GlConst.GL_TRIANGLES, GlConst.GL_UNSIGNED_INT, this.start, this.end, IndirectBuffers.DRAW_COMMAND_STRIDE); } } } diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/indirect/IndirectDrawManager.java b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/indirect/IndirectDrawManager.java index 5211ba7a9..766e864fc 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/indirect/IndirectDrawManager.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/indirect/IndirectDrawManager.java @@ -1,17 +1,22 @@ package dev.engine_room.flywheel.backend.engine.indirect; -import static org.lwjgl.opengl.GL11.GL_TRIANGLES; -import static org.lwjgl.opengl.GL11.GL_UNSIGNED_INT; -import static org.lwjgl.opengl.GL30.glBindBufferRange; -import static org.lwjgl.opengl.GL40.glDrawElementsIndirect; -import static org.lwjgl.opengl.GL42.glMemoryBarrier; -import static org.lwjgl.opengl.GL43.GL_SHADER_STORAGE_BARRIER_BIT; -import static org.lwjgl.opengl.GL43.GL_SHADER_STORAGE_BUFFER; - import java.util.HashMap; import java.util.List; import java.util.Map; +import com.mojang.blaze3d.systems.RenderSystem; +import com.mojang.blaze3d.textures.FilterMode; +import com.mojang.blaze3d.textures.GpuSampler; + +import net.minecraft.resources.Identifier; + +import org.lwjgl.opengl.GL30; +import org.lwjgl.opengl.GL40; +import org.lwjgl.opengl.GL42; +import org.lwjgl.opengl.GL43; + +import com.mojang.blaze3d.opengl.GlConst; + import dev.engine_room.flywheel.api.backend.Engine; import dev.engine_room.flywheel.api.instance.Instance; import dev.engine_room.flywheel.api.instance.InstanceType; @@ -119,7 +124,7 @@ public void render(LightStorage lightStorage, EnvironmentStorage environmentStor // We could probably save some driver calls here when there are // actually zero instances, but that feels like a very rare case - glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT); + GL42.glMemoryBarrier(GL43.GL_SHADER_STORAGE_BARRIER_BIT); matrixBuffer.bind(); @@ -129,7 +134,7 @@ public void render(LightStorage lightStorage, EnvironmentStorage environmentStor group.dispatchCull(); } - glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT); + GL42.glMemoryBarrier(GL43.GL_SHADER_STORAGE_BARRIER_BIT); programs.getApplyProgram() .bind(); @@ -138,7 +143,7 @@ public void render(LightStorage lightStorage, EnvironmentStorage environmentStor group.dispatchApply(); } - glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT); + GL42.glMemoryBarrier(GL43.GL_SHADER_STORAGE_BARRIER_BIT); TextureBinder.bindLightAndOverlay(); @@ -146,6 +151,7 @@ public void render(LightStorage lightStorage, EnvironmentStorage environmentStor lightBuffers.bind(); matrixBuffer.bind(); Uniforms.bindAll(); + TextureBinder.bindRenderTarget(Minecraft.getInstance().getMainRenderTarget()); for (var group : cullingGroups.values()) { group.submitSolid(); @@ -188,9 +194,6 @@ public void render(LightStorage lightStorage, EnvironmentStorage environmentStor oitFramebuffer.composite(); } - - MaterialRenderState.reset(); - TextureBinder.resetLightAndOverlay(); } @Override @@ -237,7 +240,8 @@ public void renderCrumbling(List crumblingBlocks) { // Set up the crumbling program buffers. Nothing changes here between draws. GlBufferType.DRAW_INDIRECT_BUFFER.bind(crumblingDrawBuffer.handle()); - glBindBufferRange(GL_SHADER_STORAGE_BUFFER, BufferBindings.DRAW, crumblingDrawBuffer.handle(), 0, IndirectBuffers.DRAW_COMMAND_STRIDE); + GL30.glBindBufferRange(GL43.GL_SHADER_STORAGE_BUFFER, BufferBindings.DRAW, crumblingDrawBuffer.handle(), 0, IndirectBuffers.DRAW_COMMAND_STRIDE); + TextureBinder.bindRenderTarget(Minecraft.getInstance().getMainRenderTarget()); for (var groupEntry : byType.entrySet()) { var byProgress = groupEntry.getValue(); @@ -250,8 +254,9 @@ public void renderCrumbling(List crumblingBlocks) { } for (var progressEntry : byProgress.int2ObjectEntrySet()) { - Samplers.CRUMBLING.makeActive(); - TextureBinder.bind(ModelBakery.BREAKING_LOCATIONS.get(progressEntry.getIntKey())); + Identifier crumblingTextureId = ModelBakery.BREAKING_LOCATIONS.get(progressEntry.getIntKey()); + GpuSampler crumblingTextureSampler = RenderSystem.getSamplerCache().getRepeat(FilterMode.NEAREST); + TextureBinder.bind(Samplers.CRUMBLING.number, crumblingTextureId, crumblingTextureSampler); for (var instanceHandlePair : progressEntry.getValue()) { IndirectInstancer instancer = instanceHandlePair.getFirst(); @@ -270,16 +275,13 @@ public void renderCrumbling(List crumblingBlocks) { crumblingDrawBuffer.upload(block); // Submit! Everything is already bound by here. - glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, 0); + GL40.glDrawElementsIndirect(GlConst.GL_TRIANGLES, GlConst.GL_UNSIGNED_INT, 0); } } } } - MaterialRenderState.reset(); - TextureBinder.resetLightAndOverlay(); - block.free(); } diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/indirect/IndirectInstancer.java b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/indirect/IndirectInstancer.java index 8b432cd8a..b1ac7fa51 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/indirect/IndirectInstancer.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/indirect/IndirectInstancer.java @@ -5,7 +5,7 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReference; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import org.jetbrains.annotations.UnknownNullability; import org.joml.Vector4fc; import org.lwjgl.system.MemoryUtil; diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/indirect/OitFramebuffer.java b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/indirect/OitFramebuffer.java index 693fe9cef..1b95d9e99 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/indirect/OitFramebuffer.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/indirect/OitFramebuffer.java @@ -3,20 +3,23 @@ import org.lwjgl.opengl.GL32; import org.lwjgl.opengl.GL46; +import com.mojang.blaze3d.opengl.GlConst; +import com.mojang.blaze3d.opengl.GlStateManager; +import com.mojang.blaze3d.opengl.GlTexture; +import com.mojang.blaze3d.pipeline.ColorTargetState; import com.mojang.blaze3d.pipeline.RenderTarget; -import com.mojang.blaze3d.platform.GlStateManager; -import com.mojang.blaze3d.systems.RenderSystem; import dev.engine_room.flywheel.backend.NoiseTextures; import dev.engine_room.flywheel.backend.Samplers; import dev.engine_room.flywheel.backend.compile.OitPrograms; import dev.engine_room.flywheel.backend.gl.GlCompat; import dev.engine_room.flywheel.backend.gl.GlTextureUnit; +import dev.engine_room.flywheel.backend.gl.GlUtil; import net.minecraft.client.Minecraft; public class OitFramebuffer { public static final float[] CLEAR_TO_ZERO = {0, 0, 0, 0}; - public static final int[] DEPTH_RANGE_DRAW_BUFFERS = {GL46.GL_COLOR_ATTACHMENT0}; + public static final int[] DEPTH_RANGE_DRAW_BUFFERS = {GlConst.GL_COLOR_ATTACHMENT0}; public static final int[] RENDER_TRANSMITTANCE_DRAW_BUFFERS = {GL46.GL_COLOR_ATTACHMENT1, GL46.GL_COLOR_ATTACHMENT2, GL46.GL_COLOR_ATTACHMENT3, GL46.GL_COLOR_ATTACHMENT4}; public static final int[] ACCUMULATE_DRAW_BUFFERS = {GL46.GL_COLOR_ATTACHMENT5}; public static final int[] DEPTH_ONLY_DRAW_BUFFERS = {}; @@ -37,7 +40,7 @@ public OitFramebuffer(OitPrograms programs) { if (GlCompat.SUPPORTS_DSA) { vao = GL46.glCreateVertexArrays(); } else { - vao = GL32.glGenVertexArrays(); + vao = GlStateManager._glGenVertexArrays(); } } @@ -60,18 +63,19 @@ public void prepare() { maybeResizeFBO(renderTarget.width, renderTarget.height); Samplers.COEFFICIENTS.makeActive(); - // Bind zero to render system to make sure we clear their internal state - RenderSystem.bindTexture(0); + // Bind zero to state manager to make sure we clear its internal state + GlStateManager._bindTexture(0); GL32.glBindTexture(GL32.GL_TEXTURE_2D_ARRAY, coefficients); Samplers.DEPTH_RANGE.makeActive(); - RenderSystem.bindTexture(depthBounds); + GlStateManager._bindTexture(depthBounds); Samplers.NOISE.makeActive(); - NoiseTextures.BLUE_NOISE.bind(); + GlStateManager._bindTexture(((GlTexture) NoiseTextures.BLUE_NOISE.getTexture()).glId()); - GlStateManager._glBindFramebuffer(GL32.GL_FRAMEBUFFER, fbo); - GL32.glFramebufferTexture(GL32.GL_FRAMEBUFFER, GL32.GL_DEPTH_ATTACHMENT, renderTarget.getDepthTextureId(), 0); + GlStateManager._glBindFramebuffer(GlConst.GL_FRAMEBUFFER, fbo); + GlTexture depthTexture = (GlTexture) renderTarget.getDepthTexture(); + GL32.glFramebufferTexture(GlConst.GL_FRAMEBUFFER, GlConst.GL_DEPTH_ATTACHMENT, depthTexture != null ? depthTexture.glId() : 0, 0); } /** @@ -79,21 +83,21 @@ public void prepare() { */ public void depthRange() { // No depth writes, but we'll still use the depth test. - RenderSystem.depthMask(false); - RenderSystem.colorMask(true, true, true, true); - RenderSystem.enableBlend(); - RenderSystem.blendFunc(GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ONE); - RenderSystem.blendEquation(GL32.GL_MAX); + GlStateManager._depthMask(false); + GlStateManager._colorMask(ColorTargetState.WRITE_ALL); + GlStateManager._enableBlend(); + GlStateManager._blendFuncSeparate(GlConst.GL_ONE, GlConst.GL_ONE, GlConst.GL_ONE, GlConst.GL_ONE); + GL32.glBlendEquation(GlConst.GL_MAX); - var far = Minecraft.getInstance().gameRenderer.getDepthFar(); + float far = Minecraft.getInstance().gameRenderer.getGameRenderState().levelRenderState.cameraRenderState.depthFar; if (GlCompat.SUPPORTS_DSA) { GL46.glNamedFramebufferDrawBuffers(fbo, DEPTH_RANGE_DRAW_BUFFERS); GL46.glClearNamedFramebufferfv(fbo, GL46.GL_COLOR, 0, new float[]{-far, -far, 0, 0}); } else { GL32.glDrawBuffers(DEPTH_RANGE_DRAW_BUFFERS); - RenderSystem.clearColor(-far, -far, 0, 0); - RenderSystem.clear(GL32.GL_COLOR_BUFFER_BIT, false); + GL32.glClearColor(-far, -far, 0, 0); + GlStateManager._clear(GlConst.GL_COLOR_BUFFER_BIT); } } @@ -102,11 +106,11 @@ public void depthRange() { */ public void renderTransmittance() { // No depth writes, but we'll still use the depth test - RenderSystem.depthMask(false); - RenderSystem.colorMask(true, true, true, true); - RenderSystem.enableBlend(); - RenderSystem.blendFunc(GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ONE); - RenderSystem.blendEquation(GL32.GL_FUNC_ADD); + GlStateManager._depthMask(false); + GlStateManager._colorMask(ColorTargetState.WRITE_ALL); + GlStateManager._enableBlend(); + GlStateManager._blendFuncSeparate(GlConst.GL_ONE, GlConst.GL_ONE, GlConst.GL_ONE, GlConst.GL_ONE); + GL32.glBlendEquation(GlConst.GL_FUNC_ADD); if (GlCompat.SUPPORTS_DSA) { GL46.glNamedFramebufferDrawBuffers(fbo, RENDER_TRANSMITTANCE_DRAW_BUFFERS); @@ -117,8 +121,8 @@ public void renderTransmittance() { GL46.glClearNamedFramebufferfv(fbo, GL46.GL_COLOR, 3, CLEAR_TO_ZERO); } else { GL32.glDrawBuffers(RENDER_TRANSMITTANCE_DRAW_BUFFERS); - RenderSystem.clearColor(0, 0, 0, 0); - RenderSystem.clear(GL32.GL_COLOR_BUFFER_BIT, false); + GL32.glClearColor(0, 0, 0, 0); + GlStateManager._clear(GlConst.GL_COLOR_BUFFER_BIT); } } @@ -128,10 +132,10 @@ public void renderTransmittance() { */ public void renderDepthFromTransmittance() { // Only write to depth, not color. - RenderSystem.depthMask(true); - RenderSystem.colorMask(false, false, false, false); - RenderSystem.disableBlend(); - RenderSystem.depthFunc(GL32.GL_ALWAYS); + GlStateManager._depthMask(true); + GlStateManager._colorMask(ColorTargetState.WRITE_NONE); + GlStateManager._disableBlend(); + GlStateManager._depthFunc(GlConst.GL_ALWAYS); if (GlCompat.SUPPORTS_DSA) { GL46.glNamedFramebufferDrawBuffers(fbo, DEPTH_ONLY_DRAW_BUFFERS); @@ -150,11 +154,11 @@ public void renderDepthFromTransmittance() { */ public void accumulate() { // No depth writes, but we'll still use the depth test - RenderSystem.depthMask(false); - RenderSystem.colorMask(true, true, true, true); - RenderSystem.enableBlend(); - RenderSystem.blendFunc(GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ONE); - RenderSystem.blendEquation(GL32.GL_FUNC_ADD); + GlStateManager._depthMask(false); + GlStateManager._colorMask(ColorTargetState.WRITE_ALL); + GlStateManager._enableBlend(); + GlStateManager._blendFuncSeparate(GlConst.GL_ONE, GlConst.GL_ONE, GlConst.GL_ONE, GlConst.GL_ONE); + GL32.glBlendEquation(GlConst.GL_FUNC_ADD); if (GlCompat.SUPPORTS_DSA) { GL46.glNamedFramebufferDrawBuffers(fbo, ACCUMULATE_DRAW_BUFFERS); @@ -162,8 +166,8 @@ public void accumulate() { GL46.glClearNamedFramebufferfv(fbo, GL46.GL_COLOR, 0, CLEAR_TO_ZERO); } else { GL32.glDrawBuffers(ACCUMULATE_DRAW_BUFFERS); - RenderSystem.clearColor(0, 0, 0, 0); - RenderSystem.clear(GL32.GL_COLOR_BUFFER_BIT, false); + GL32.glClearColor(0, 0, 0, 0); + GlStateManager._clear(GlConst.GL_COLOR_BUFFER_BIT); } } @@ -172,21 +176,18 @@ public void accumulate() { */ public void composite() { if (Minecraft.useShaderTransparency()) { - Minecraft.getInstance().levelRenderer.getItemEntityTarget() - .bindWrite(false); + bindRenderTarget(Minecraft.getInstance().levelRenderer.getItemEntityTarget()); } else { - Minecraft.getInstance() - .getMainRenderTarget() - .bindWrite(false); + bindRenderTarget(Minecraft.getInstance().getMainRenderTarget()); } // The composite shader writes out the closest depth to gl_FragDepth. // depthMask = true: OIT stuff renders on top of other transparent stuff. // depthMask = false: other transparent stuff renders on top of OIT stuff. // If Neo gets wavelet OIT we can use their hooks to be correct with everything. - RenderSystem.depthMask(true); - RenderSystem.colorMask(true, true, true, true); - RenderSystem.enableBlend(); + GlStateManager._depthMask(true); + GlStateManager._colorMask(ColorTargetState.WRITE_ALL); + GlStateManager._enableBlend(); // We rely on the blend func to achieve: // final color = (1 - transmittance_total) * sum(color_f * alpha_f * transmittance_f) / sum(alpha_f * transmittance_f) @@ -194,21 +195,29 @@ public void composite() { // // Though note that the alpha value we emit in the fragment shader is actually (1. - transmittance_total). // The extra inversion step is so we can have a sane alpha value written out for the fabulous blit shader to consume. - RenderSystem.blendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA); - RenderSystem.blendEquation(GL32.GL_FUNC_ADD); - RenderSystem.depthFunc(GL32.GL_ALWAYS); + GlStateManager._blendFuncSeparate(GlConst.GL_SRC_ALPHA, GlConst.GL_ONE_MINUS_SRC_ALPHA, GlConst.GL_ONE, GlConst.GL_ONE_MINUS_SRC_ALPHA); + GL32.glBlendEquation(GlConst.GL_FUNC_ADD); + GlStateManager._depthFunc(GlConst.GL_ALWAYS); GlTextureUnit.T0.makeActive(); - RenderSystem.bindTexture(accumulate); + GlStateManager._bindTexture(accumulate); programs.getOitCompositeProgram() .bind(); drawFullscreenQuad(); - Minecraft.getInstance() - .getMainRenderTarget() - .bindWrite(false); + bindRenderTarget(Minecraft.getInstance().getMainRenderTarget()); + } + + private static void bindRenderTarget(RenderTarget target) { + GlTexture colorTexture = (GlTexture) target.getColorTexture(); + int i = colorTexture.getFbo( + GlUtil.getGlDevice().directStateAccess(), + target.getDepthTexture() + ); + GlStateManager._glBindFramebuffer(GlConst.GL_FRAMEBUFFER, i); + GlStateManager._viewport(0, 0, colorTexture.getWidth(0), colorTexture.getHeight(0)); } public void delete() { @@ -220,29 +229,29 @@ private void drawFullscreenQuad() { // Empty VAO, the actual full screen triangle is generated in the vertex shader GlStateManager._glBindVertexArray(vao); - GL32.glDrawArrays(GL32.GL_TRIANGLES, 0, 3); + GlStateManager._drawArrays(GlConst.GL_TRIANGLES, 0, 3); } private void deleteTextures() { if (depthBounds != -1) { - GL32.glDeleteTextures(depthBounds); + GlStateManager._deleteTexture(depthBounds); } if (coefficients != -1) { - GL32.glDeleteTextures(coefficients); + GlStateManager._deleteTexture(coefficients); } if (accumulate != -1) { - GL32.glDeleteTextures(accumulate); + GlStateManager._deleteTexture(accumulate); } if (fbo != -1) { - GL32.glDeleteFramebuffers(fbo); + GlStateManager._glDeleteFramebuffers(fbo); } // We sometimes get the same texture ID back when creating new textures, // so bind zero to clear the GlStateManager Samplers.COEFFICIENTS.makeActive(); - RenderSystem.bindTexture(0); + GlStateManager._bindTexture(0); Samplers.DEPTH_RANGE.makeActive(); - RenderSystem.bindTexture(0); + GlStateManager._bindTexture(0); } private void maybeResizeFBO(int width, int height) { @@ -266,7 +275,7 @@ private void maybeResizeFBO(int width, int height) { GL46.glTextureStorage3D(coefficients, 1, GL32.GL_RGBA16F, width, height, 4); GL46.glTextureStorage2D(accumulate, 1, GL32.GL_RGBA16F, width, height); - GL46.glNamedFramebufferTexture(fbo, GL32.GL_COLOR_ATTACHMENT0, depthBounds, 0); + GL46.glNamedFramebufferTexture(fbo, GlConst.GL_COLOR_ATTACHMENT0, depthBounds, 0); GL46.glNamedFramebufferTextureLayer(fbo, GL32.GL_COLOR_ATTACHMENT1, coefficients, 0, 0); GL46.glNamedFramebufferTextureLayer(fbo, GL32.GL_COLOR_ATTACHMENT2, coefficients, 0, 1); GL46.glNamedFramebufferTextureLayer(fbo, GL32.GL_COLOR_ATTACHMENT3, coefficients, 0, 2); @@ -275,45 +284,45 @@ private void maybeResizeFBO(int width, int height) { } else { fbo = GL46.glGenFramebuffers(); - depthBounds = GL32.glGenTextures(); - coefficients = GL32.glGenTextures(); - accumulate = GL32.glGenTextures(); + depthBounds = GlStateManager._genTexture(); + coefficients = GlStateManager._genTexture(); + accumulate = GlStateManager._genTexture(); GlTextureUnit.T0.makeActive(); - RenderSystem.bindTexture(0); + GlStateManager._bindTexture(0); - GL32.glBindTexture(GL32.GL_TEXTURE_2D, depthBounds); - GL32.glTexImage2D(GL32.GL_TEXTURE_2D, 0, GL32.GL_RG32F, width, height, 0, GL46.GL_RGBA, GL46.GL_BYTE, 0); + GlStateManager._bindTexture(depthBounds); + GL32.glTexImage2D(GlConst.GL_TEXTURE_2D, 0, GL32.GL_RG32F, width, height, 0, GL46.GL_RGBA, GL46.GL_BYTE, 0); - GL32.glTexParameteri(GL32.GL_TEXTURE_2D, GL32.GL_TEXTURE_MIN_FILTER, GL32.GL_NEAREST); - GL32.glTexParameteri(GL32.GL_TEXTURE_2D, GL32.GL_TEXTURE_MAG_FILTER, GL32.GL_NEAREST); - GL32.glTexParameteri(GL32.GL_TEXTURE_2D, GL32.GL_TEXTURE_WRAP_S, GL32.GL_CLAMP_TO_EDGE); - GL32.glTexParameteri(GL32.GL_TEXTURE_2D, GL32.GL_TEXTURE_WRAP_T, GL32.GL_CLAMP_TO_EDGE); + GlStateManager._texParameter(GlConst.GL_TEXTURE_2D, GlConst.GL_TEXTURE_MIN_FILTER, GlConst.GL_NEAREST); + GlStateManager._texParameter(GlConst.GL_TEXTURE_2D, GlConst.GL_TEXTURE_MAG_FILTER, GlConst.GL_NEAREST); + GlStateManager._texParameter(GlConst.GL_TEXTURE_2D, GlConst.GL_TEXTURE_WRAP_S, GlConst.GL_CLAMP_TO_EDGE); + GlStateManager._texParameter(GlConst.GL_TEXTURE_2D, GlConst.GL_TEXTURE_WRAP_T, GlConst.GL_CLAMP_TO_EDGE); GL32.glBindTexture(GL32.GL_TEXTURE_2D_ARRAY, coefficients); GL32.glTexImage3D(GL32.GL_TEXTURE_2D_ARRAY, 0, GL32.GL_RGBA16F, width, height, 4, 0, GL46.GL_RGBA, GL46.GL_BYTE, 0); - GL32.glTexParameteri(GL32.GL_TEXTURE_2D_ARRAY, GL32.GL_TEXTURE_MIN_FILTER, GL32.GL_NEAREST); - GL32.glTexParameteri(GL32.GL_TEXTURE_2D_ARRAY, GL32.GL_TEXTURE_MAG_FILTER, GL32.GL_NEAREST); - GL32.glTexParameteri(GL32.GL_TEXTURE_2D_ARRAY, GL32.GL_TEXTURE_WRAP_S, GL32.GL_CLAMP_TO_EDGE); - GL32.glTexParameteri(GL32.GL_TEXTURE_2D_ARRAY, GL32.GL_TEXTURE_WRAP_T, GL32.GL_CLAMP_TO_EDGE); + GlStateManager._texParameter(GL32.GL_TEXTURE_2D_ARRAY, GlConst.GL_TEXTURE_MIN_FILTER, GlConst.GL_NEAREST); + GlStateManager._texParameter(GL32.GL_TEXTURE_2D_ARRAY, GlConst.GL_TEXTURE_MAG_FILTER, GlConst.GL_NEAREST); + GlStateManager._texParameter(GL32.GL_TEXTURE_2D_ARRAY, GlConst.GL_TEXTURE_WRAP_S, GlConst.GL_CLAMP_TO_EDGE); + GlStateManager._texParameter(GL32.GL_TEXTURE_2D_ARRAY, GlConst.GL_TEXTURE_WRAP_T, GlConst.GL_CLAMP_TO_EDGE); - GL32.glBindTexture(GL32.GL_TEXTURE_2D, accumulate); - GL32.glTexImage2D(GL32.GL_TEXTURE_2D, 0, GL32.GL_RGBA16F, width, height, 0, GL46.GL_RGBA, GL46.GL_BYTE, 0); + GlStateManager._bindTexture(accumulate); + GL32.glTexImage2D(GlConst.GL_TEXTURE_2D, 0, GL32.GL_RGBA16F, width, height, 0, GL46.GL_RGBA, GL46.GL_BYTE, 0); - GL32.glTexParameteri(GL32.GL_TEXTURE_2D, GL32.GL_TEXTURE_MIN_FILTER, GL32.GL_NEAREST); - GL32.glTexParameteri(GL32.GL_TEXTURE_2D, GL32.GL_TEXTURE_MAG_FILTER, GL32.GL_NEAREST); - GL32.glTexParameteri(GL32.GL_TEXTURE_2D, GL32.GL_TEXTURE_WRAP_S, GL32.GL_CLAMP_TO_EDGE); - GL32.glTexParameteri(GL32.GL_TEXTURE_2D, GL32.GL_TEXTURE_WRAP_T, GL32.GL_CLAMP_TO_EDGE); + GlStateManager._texParameter(GlConst.GL_TEXTURE_2D, GlConst.GL_TEXTURE_MIN_FILTER, GlConst.GL_NEAREST); + GlStateManager._texParameter(GlConst.GL_TEXTURE_2D, GlConst.GL_TEXTURE_MAG_FILTER, GlConst.GL_NEAREST); + GlStateManager._texParameter(GlConst.GL_TEXTURE_2D, GlConst.GL_TEXTURE_WRAP_S, GlConst.GL_CLAMP_TO_EDGE); + GlStateManager._texParameter(GlConst.GL_TEXTURE_2D, GlConst.GL_TEXTURE_WRAP_T, GlConst.GL_CLAMP_TO_EDGE); - GlStateManager._glBindFramebuffer(GL32.GL_FRAMEBUFFER, fbo); + GlStateManager._glBindFramebuffer(GlConst.GL_FRAMEBUFFER, fbo); - GL46.glFramebufferTexture(GL32.GL_FRAMEBUFFER, GL32.GL_COLOR_ATTACHMENT0, depthBounds, 0); - GL46.glFramebufferTextureLayer(GL32.GL_FRAMEBUFFER, GL32.GL_COLOR_ATTACHMENT1, coefficients, 0, 0); - GL46.glFramebufferTextureLayer(GL32.GL_FRAMEBUFFER, GL32.GL_COLOR_ATTACHMENT2, coefficients, 0, 1); - GL46.glFramebufferTextureLayer(GL32.GL_FRAMEBUFFER, GL32.GL_COLOR_ATTACHMENT3, coefficients, 0, 2); - GL46.glFramebufferTextureLayer(GL32.GL_FRAMEBUFFER, GL32.GL_COLOR_ATTACHMENT4, coefficients, 0, 3); - GL46.glFramebufferTexture(GL32.GL_FRAMEBUFFER, GL32.GL_COLOR_ATTACHMENT5, accumulate, 0); + GL46.glFramebufferTexture(GlConst.GL_FRAMEBUFFER, GlConst.GL_COLOR_ATTACHMENT0, depthBounds, 0); + GL46.glFramebufferTextureLayer(GlConst.GL_FRAMEBUFFER, GL32.GL_COLOR_ATTACHMENT1, coefficients, 0, 0); + GL46.glFramebufferTextureLayer(GlConst.GL_FRAMEBUFFER, GL32.GL_COLOR_ATTACHMENT2, coefficients, 0, 1); + GL46.glFramebufferTextureLayer(GlConst.GL_FRAMEBUFFER, GL32.GL_COLOR_ATTACHMENT3, coefficients, 0, 2); + GL46.glFramebufferTextureLayer(GlConst.GL_FRAMEBUFFER, GL32.GL_COLOR_ATTACHMENT4, coefficients, 0, 3); + GL46.glFramebufferTexture(GlConst.GL_FRAMEBUFFER, GL32.GL_COLOR_ATTACHMENT5, accumulate, 0); } } } diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/indirect/ResizableStorageBuffer.java b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/indirect/ResizableStorageBuffer.java index 05aa0d722..c6f343555 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/indirect/ResizableStorageBuffer.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/indirect/ResizableStorageBuffer.java @@ -1,9 +1,8 @@ package dev.engine_room.flywheel.backend.engine.indirect; -import static org.lwjgl.opengl.GL15.glDeleteBuffers; -import static org.lwjgl.opengl.GL45.glCopyNamedBufferSubData; -import static org.lwjgl.opengl.GL45.glCreateBuffers; -import static org.lwjgl.opengl.GL45.glNamedBufferStorage; +import org.lwjgl.opengl.GL45; + +import com.mojang.blaze3d.opengl.GlStateManager; import dev.engine_room.flywheel.backend.gl.GlObject; import dev.engine_room.flywheel.lib.memory.FlwMemoryTracker; @@ -17,7 +16,7 @@ public class ResizableStorageBuffer extends GlObject { private long capacity = 0; public ResizableStorageBuffer() { - handle(glCreateBuffers()); + handle(GL45.glCreateBuffers()); } public long capacity() { @@ -29,17 +28,17 @@ public void ensureCapacity(long capacity) { if (this.capacity > 0) { int oldHandle = handle(); - int newHandle = glCreateBuffers(); + int newHandle = GL45.glCreateBuffers(); - glNamedBufferStorage(newHandle, capacity, 0); + GL45.glNamedBufferStorage(newHandle, capacity, 0); - glCopyNamedBufferSubData(oldHandle, newHandle, 0, 0, this.capacity); + GL45.glCopyNamedBufferSubData(oldHandle, newHandle, 0, 0, this.capacity); deleteInternal(oldHandle); handle(newHandle); } else { - glNamedBufferStorage(handle(), capacity, 0); + GL45.glNamedBufferStorage(handle(), capacity, 0); } this.capacity = capacity; FlwMemoryTracker._allocGpuMemory(this.capacity); @@ -47,7 +46,7 @@ public void ensureCapacity(long capacity) { @Override protected void deleteInternal(int handle) { - glDeleteBuffers(handle); + GlStateManager._glDeleteBuffers(handle); } @Override diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/indirect/StagingBuffer.java b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/indirect/StagingBuffer.java index efe107f92..a5e515432 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/indirect/StagingBuffer.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/indirect/StagingBuffer.java @@ -2,13 +2,15 @@ import java.util.function.LongConsumer; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import org.lwjgl.opengl.GL45; import org.lwjgl.opengl.GL45C; import org.lwjgl.system.MemoryUtil; +import com.mojang.blaze3d.buffers.GpuFence; +import com.mojang.blaze3d.opengl.GlFence; + import dev.engine_room.flywheel.backend.compile.IndirectPrograms; -import dev.engine_room.flywheel.backend.gl.GlFence; import dev.engine_room.flywheel.backend.gl.buffer.GlBuffer; import dev.engine_room.flywheel.backend.gl.buffer.GlBufferUsage; import dev.engine_room.flywheel.lib.memory.FlwMemoryTracker; @@ -195,13 +197,13 @@ public void flush() { public void reclaim() { while (!fencedRegions.isEmpty()) { var region = fencedRegions.first(); - if (!region.fence.isSignaled()) { - // We can't reclaim this region yet, and we know that all the regions after it are also not ready. - break; + try (GpuFence fence = region.fence) { + if (!fence.awaitCompletion(0L)) { + // We can't reclaim this region yet, and we know that all the regions after it are also not ready. + break; + } + fencedRegions.dequeue(); } - fencedRegions.dequeue(); - - region.fence.delete(); totalAvailable += region.capacity; } @@ -333,7 +335,7 @@ private void flushUsedRegion() { } } - private record FencedRegion(GlFence fence, long capacity) { + private record FencedRegion(GpuFence fence, long capacity) { } private static class OverflowStagingBuffer { diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/instancing/InstancedDrawManager.java b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/instancing/InstancedDrawManager.java index efe46c879..8450b2de1 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/instancing/InstancedDrawManager.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/instancing/InstancedDrawManager.java @@ -4,6 +4,10 @@ import java.util.Comparator; import java.util.List; +import com.mojang.blaze3d.systems.RenderSystem; +import com.mojang.blaze3d.textures.FilterMode; +import com.mojang.blaze3d.textures.GpuSampler; + import dev.engine_room.flywheel.api.backend.Engine; import dev.engine_room.flywheel.api.instance.Instance; import dev.engine_room.flywheel.api.material.Material; @@ -31,6 +35,7 @@ import dev.engine_room.flywheel.lib.material.SimpleMaterial; import net.minecraft.client.Minecraft; import net.minecraft.client.resources.model.ModelBakery; +import net.minecraft.resources.Identifier; public class InstancedDrawManager extends DrawManager> { private static final Comparator DRAW_COMPARATOR = Comparator.comparingInt(InstancedDraw::bias) @@ -118,6 +123,9 @@ public void render(LightStorage lightStorage, EnvironmentStorage environmentStor TextureBinder.bindLightAndOverlay(); light.bind(); + TextureBinder.bindRenderTarget(Minecraft.getInstance().getMainRenderTarget()); + + submitDraws(); if (!oitDraws.isEmpty()) { @@ -142,9 +150,6 @@ public void render(LightStorage lightStorage, EnvironmentStorage environmentStor oitFramebuffer.composite(); } - - MaterialRenderState.reset(); - TextureBinder.resetLightAndOverlay(); } private void submitDraws() { @@ -262,7 +267,9 @@ public void renderCrumbling(List crumblingBlocks) { Uniforms.bindAll(); vao.bindForDraw(); + TextureBinder.bindLightAndOverlay(); + TextureBinder.bindRenderTarget(Minecraft.getInstance().getMainRenderTarget()); for (var groupEntry : byType.entrySet()) { var byProgress = groupEntry.getValue(); @@ -270,8 +277,9 @@ public void renderCrumbling(List crumblingBlocks) { GroupKey shader = groupEntry.getKey(); for (var progressEntry : byProgress.int2ObjectEntrySet()) { - Samplers.CRUMBLING.makeActive(); - TextureBinder.bind(ModelBakery.BREAKING_LOCATIONS.get(progressEntry.getIntKey())); + Identifier crumblingTextureId = ModelBakery.BREAKING_LOCATIONS.get(progressEntry.getIntKey()); + GpuSampler crumblingTextureSampler = RenderSystem.getSamplerCache().getRepeat(FilterMode.NEAREST); + TextureBinder.bind(Samplers.CRUMBLING.number, crumblingTextureId, crumblingTextureSampler); for (var instanceHandlePair : progressEntry.getValue()) { InstancedInstancer instancer = instanceHandlePair.getFirst(); @@ -293,9 +301,6 @@ public void renderCrumbling(List crumblingBlocks) { } } } - - MaterialRenderState.reset(); - TextureBinder.resetLightAndOverlay(); } @Override diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/instancing/InstancedInstancer.java b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/instancing/InstancedInstancer.java index c56b281eb..ab31df3fc 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/instancing/InstancedInstancer.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/instancing/InstancedInstancer.java @@ -3,7 +3,7 @@ import java.util.ArrayList; import java.util.List; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import dev.engine_room.flywheel.api.instance.Instance; import dev.engine_room.flywheel.api.instance.InstanceWriter; diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/uniform/FogUniforms.java b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/uniform/FogUniforms.java index 976f4d5a3..fdeafd4de 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/uniform/FogUniforms.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/uniform/FogUniforms.java @@ -1,27 +1,20 @@ package dev.engine_room.flywheel.backend.engine.uniform; -import com.mojang.blaze3d.shaders.FogShape; -import com.mojang.blaze3d.systems.RenderSystem; +import org.joml.Vector4fc; public final class FogUniforms extends UniformWriter { - private static final int SIZE = 4 * 7; + private static final int SIZE = 4 * 10; static final UniformBuffer BUFFER = new UniformBuffer(Uniforms.FOG_INDEX, SIZE); - public static void update() { + public static void update(Vector4fc color, float environmentalStart, float environmentalEnd, + float renderDistanceStart, float renderDistanceEnd, float skyEnd, float cloudEnd) { long ptr = BUFFER.ptr(); - var color = RenderSystem.getShaderFogColor(); - - ptr = writeFloat(ptr, color[0]); - ptr = writeFloat(ptr, color[1]); - ptr = writeFloat(ptr, color[2]); - ptr = writeFloat(ptr, color[3]); - ptr = writeFloat(ptr, RenderSystem.getShaderFogStart()); - ptr = writeFloat(ptr, RenderSystem.getShaderFogEnd()); - - var fogShape = RenderSystem.getShaderFogShape(); - // Shouldn't ever be null, but we've seen crashes here. - ptr = writeInt(ptr, (fogShape == null ? FogShape.SPHERE : fogShape).getIndex()); + ptr = writeVec4(ptr, color); + ptr = writeVec2(ptr, environmentalStart, environmentalEnd); + ptr = writeVec2(ptr, renderDistanceStart, renderDistanceEnd); + ptr = writeFloat(ptr, skyEnd); + ptr = writeFloat(ptr, cloudEnd); BUFFER.markDirty(); } diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/uniform/FrameUniforms.java b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/uniform/FrameUniforms.java index 5a521b4c6..4ae1146c6 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/uniform/FrameUniforms.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/uniform/FrameUniforms.java @@ -9,13 +9,14 @@ import dev.engine_room.flywheel.api.backend.RenderContext; import dev.engine_room.flywheel.api.visualization.VisualizationManager; import dev.engine_room.flywheel.backend.engine.indirect.DepthPyramid; +import dev.engine_room.flywheel.backend.extension.CameraRenderStateExtension; import dev.engine_room.flywheel.backend.mixin.LevelRendererAccessor; -import net.minecraft.Util; import net.minecraft.client.Camera; import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.GameRenderer; +import net.minecraft.client.renderer.state.level.CameraRenderState; import net.minecraft.core.BlockPos; import net.minecraft.core.Vec3i; +import net.minecraft.util.Util; import net.minecraft.world.level.Level; import net.minecraft.world.phys.Vec3; @@ -68,8 +69,8 @@ public static void update(RenderContext context) { Vec3i renderOrigin = VisualizationManager.getOrThrow(context.level()) .renderOrigin(); - var camera = context.camera(); - Vec3 cameraPos = camera.getPosition(); + CameraRenderState cameraRenderState = context.cameraRenderState(); + Vec3 cameraPos = cameraRenderState.pos; var camX = (float) (cameraPos.x - renderOrigin.getX()); var camY = (float) (cameraPos.y - renderOrigin.getY()); var camZ = (float) (cameraPos.z - renderOrigin.getZ()); @@ -81,8 +82,8 @@ public static void update(RenderContext context) { VIEW_PROJECTION.translate(-camX, -camY, -camZ); CAMERA_POS.set(camX, camY, camZ); - CAMERA_LOOK.set(camera.getLookVector()); - CAMERA_ROT.set(camera.getXRot(), camera.getYRot()); + CAMERA_LOOK.set(((CameraRenderStateExtension) cameraRenderState).flywheel$getForwardVector()); + CAMERA_ROT.set(cameraRenderState.xRot, cameraRenderState.yRot); if (firstWrite) { setPrev(); @@ -95,7 +96,7 @@ public static void update(RenderContext context) { ptr += 96; - ptr = writeCullData(ptr); + ptr = writeCullData(ptr, cameraRenderState); ptr = writeMatrices(ptr); @@ -109,11 +110,11 @@ public static void update(RenderContext context) { ptr = writeFloat(ptr, (float) window.getWidth() / (float) window.getHeight()); // default line width: net.minecraft.client.renderer.RenderStateShard.LineStateShard ptr = writeFloat(ptr, Math.max(2.5F, (float) window.getWidth() / 1920.0F * 2.5F)); - ptr = writeFloat(ptr, Minecraft.getInstance().gameRenderer.getDepthFar()); + ptr = writeFloat(ptr, cameraRenderState.depthFar); ptr = writeTime(ptr, context); - ptr = writeCameraIn(ptr, camera); + ptr = writeCameraIn(ptr, cameraRenderState); ptr = writeInt(ptr, debugMode); @@ -178,20 +179,20 @@ private static long writeTime(long ptr, RenderContext context) { return ptr; } - private static long writeCameraIn(long ptr, Camera camera) { - if (!camera.isInitialized()) { + private static long writeCameraIn(long ptr, CameraRenderState cameraRenderState) { + if (!cameraRenderState.initialized) { ptr = writeInt(ptr, 0); ptr = writeInt(ptr, 0); return ptr; } - Level level = camera.getEntity().level(); - BlockPos blockPos = camera.getBlockPosition(); - Vec3 cameraPos = camera.getPosition(); + Level level = Minecraft.getInstance().level; + BlockPos blockPos = cameraRenderState.blockPos; + Vec3 cameraPos = cameraRenderState.pos; return writeInFluidAndBlock(ptr, level, blockPos, cameraPos); } - private static long writeCullData(long ptr) { + private static long writeCullData(long ptr, CameraRenderState cameraRenderState) { var mc = Minecraft.getInstance(); var mainRenderTarget = mc.getMainRenderTarget(); @@ -199,8 +200,8 @@ private static long writeCullData(long ptr) { int pyramidHeight = DepthPyramid.mip0Size(mainRenderTarget.height); int pyramidDepth = DepthPyramid.getImageMipLevels(pyramidWidth, pyramidHeight); - ptr = writeFloat(ptr, GameRenderer.PROJECTION_Z_NEAR); // zNear - ptr = writeFloat(ptr, mc.gameRenderer.getDepthFar()); // zFar + ptr = writeFloat(ptr, Camera.PROJECTION_Z_NEAR); // zNear + ptr = writeFloat(ptr, cameraRenderState.depthFar); // zFar ptr = writeFloat(ptr, PROJECTION.m00()); // P00 ptr = writeFloat(ptr, PROJECTION.m11()); // P11 ptr = writeFloat(ptr, pyramidWidth); // pyramidWidth diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/uniform/LevelUniforms.java b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/uniform/LevelUniforms.java index 126f08a2a..523b11d57 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/uniform/LevelUniforms.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/uniform/LevelUniforms.java @@ -4,12 +4,14 @@ import dev.engine_room.flywheel.api.backend.RenderContext; import net.minecraft.client.multiplayer.ClientLevel; +import net.minecraft.client.renderer.state.level.LevelRenderState; import net.minecraft.resources.ResourceKey; +import net.minecraft.util.ARGB; import net.minecraft.world.level.Level; -import net.minecraft.world.phys.Vec3; +import net.minecraft.world.level.dimension.DimensionType; public final class LevelUniforms extends UniformWriter { - private static final int SIZE = 16 * 4 + 4 * 12; + private static final int SIZE = 16 * 4 + 4 * 15; static final UniformBuffer BUFFER = new UniformBuffer(Uniforms.LEVEL_INDEX, SIZE); public static final Vector3f LIGHT0_DIRECTION = new Vector3f(); @@ -23,16 +25,17 @@ public static void update(RenderContext context) { ClientLevel level = context.level(); float partialTick = context.partialTick(); + LevelRenderState levelRenderState = context.levelRenderState(); - Vec3 skyColor = level.getSkyColor(context.camera().getPosition(), partialTick); - Vec3 cloudColor = level.getCloudColor(partialTick); - ptr = writeVec4(ptr, (float) skyColor.x, (float) skyColor.y, (float) skyColor.z, 1f); - ptr = writeVec4(ptr, (float) cloudColor.x, (float) cloudColor.y, (float) cloudColor.z, 1f); + int skyColor = levelRenderState.skyRenderState.skyColor; + int cloudColor = levelRenderState.cloudColor; + ptr = writeVec4(ptr, ARGB.redFloat(skyColor), ARGB.greenFloat(skyColor), ARGB.blueFloat(skyColor), 1f); + ptr = writeVec4(ptr, ARGB.redFloat(cloudColor), ARGB.greenFloat(cloudColor), ARGB.blueFloat(cloudColor), 1f); ptr = writeVec3(ptr, LIGHT0_DIRECTION); ptr = writeVec3(ptr, LIGHT1_DIRECTION); - long dayTime = level.getDayTime(); + long dayTime = level.getOverworldClockTime(); long levelDay = dayTime / 24000L; float timeOfDay = (float) (dayTime - levelDay * 24000L) / 24000f; ptr = writeInt(ptr, (int) (levelDay % 0x7FFFFFFFL)); @@ -40,19 +43,27 @@ public static void update(RenderContext context) { ptr = writeInt(ptr, level.dimensionType().hasSkyLight() ? 1 : 0); - ptr = writeFloat(ptr, level.getSunAngle(partialTick)); + float sunAngle = levelRenderState.skyRenderState.sunAngle; + ptr = writeFloat(ptr, sunAngle); + float moonAngle = levelRenderState.skyRenderState.moonAngle; + ptr = writeFloat(ptr, moonAngle); + float starAngle = levelRenderState.skyRenderState.starAngle; + ptr = writeFloat(ptr, starAngle); - ptr = writeFloat(ptr, level.getMoonBrightness()); - ptr = writeInt(ptr, level.getMoonPhase()); + int moonPhase = levelRenderState.skyRenderState.moonPhase.index(); + ptr = writeFloat(ptr, DimensionType.MOON_BRIGHTNESS_PER_PHASE[moonPhase]); + ptr = writeInt(ptr, moonPhase); + float starBrightness = levelRenderState.skyRenderState.starBrightness; + ptr = writeFloat(ptr, starBrightness); ptr = writeInt(ptr, level.isRaining() ? 1 : 0); ptr = writeFloat(ptr, level.getRainLevel(partialTick)); ptr = writeInt(ptr, level.isThundering() ? 1 : 0); ptr = writeFloat(ptr, level.getThunderLevel(partialTick)); - ptr = writeFloat(ptr, level.getSkyDarken(partialTick)); + ptr = writeFloat(ptr, level.getSkyDarken()); - ptr = writeInt(ptr, level.effects().constantAmbientLight() ? 1 : 0); + ptr = writeInt(ptr, level.dimensionType().cardinalLightType().ordinal()); // TODO: use defines for custom dimension ids int dimensionId; diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/uniform/PlayerUniforms.java b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/uniform/PlayerUniforms.java index 1c2bc6b34..c76dc1934 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/uniform/PlayerUniforms.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/uniform/PlayerUniforms.java @@ -1,21 +1,22 @@ package dev.engine_room.flywheel.backend.engine.uniform; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import dev.engine_room.flywheel.api.backend.RenderContext; import dev.engine_room.flywheel.backend.FlwBackendXplat; import dev.engine_room.flywheel.backend.mixin.AbstractClientPlayerAccessor; import net.minecraft.client.Minecraft; -import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.client.multiplayer.PlayerInfo; import net.minecraft.client.player.LocalPlayer; import net.minecraft.core.BlockPos; -import net.minecraft.util.FastColor; +import net.minecraft.util.ARGB; import net.minecraft.world.InteractionHand; import net.minecraft.world.item.BlockItem; import net.minecraft.world.item.Item; +import net.minecraft.world.level.Level; import net.minecraft.world.level.LightLayer; import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.lighting.LightEngine; import net.minecraft.world.phys.Vec3; import net.minecraft.world.scores.PlayerTeam; @@ -65,9 +66,9 @@ private static long writeTeamColor(long ptr, @Nullable PlayerTeam team) { Integer color = team.getColor().getColor(); if (color != null) { - int red = FastColor.ARGB32.red(color); - int green = FastColor.ARGB32.green(color); - int blue = FastColor.ARGB32.blue(color); + int red = ARGB.red(color); + int green = ARGB.green(color); + int blue = ARGB.blue(color); return writeVec4(ptr, red / 255f, green / 255f, blue / 255f, 1f); } else { return writeVec4(ptr, 1f, 1f, 1f, 1f); @@ -78,10 +79,10 @@ private static long writeTeamColor(long ptr, @Nullable PlayerTeam team) { } private static long writeEyeBrightness(long ptr, LocalPlayer player) { - ClientLevel level = player.clientLevel; + Level level = player.level(); int blockBrightness = level.getBrightness(LightLayer.BLOCK, player.blockPosition()); int skyBrightness = level.getBrightness(LightLayer.SKY, player.blockPosition()); - int maxBrightness = level.getMaxLightLevel(); + int maxBrightness = LightEngine.MAX_LEVEL; return writeVec2(ptr, (float) blockBrightness / (float) maxBrightness, (float) skyBrightness / (float) maxBrightness); @@ -95,7 +96,7 @@ private static long writeHeldLight(long ptr, LocalPlayer player) { if (handItem instanceof BlockItem blockItem) { Block block = blockItem.getBlock(); int blockLight = FlwBackendXplat.INSTANCE - .getLightEmission(block.defaultBlockState(), player.clientLevel, player.blockPosition()); + .getLightEmission(block.defaultBlockState(), player.level(), player.blockPosition()); if (heldLight < blockLight) { heldLight = blockLight; } @@ -106,7 +107,7 @@ private static long writeHeldLight(long ptr, LocalPlayer player) { } private static long writeEyeIn(long ptr, LocalPlayer player) { - ClientLevel level = player.clientLevel; + Level level = player.level(); Vec3 eyePos = player.getEyePosition(); BlockPos blockPos = BlockPos.containing(eyePos); return writeInFluidAndBlock(ptr, level, blockPos, eyePos); diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/uniform/UniformBuffer.java b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/uniform/UniformBuffer.java index 4dacf1cc0..ab4d89698 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/uniform/UniformBuffer.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/uniform/UniformBuffer.java @@ -1,6 +1,6 @@ package dev.engine_room.flywheel.backend.engine.uniform; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import org.lwjgl.opengl.GL32; import dev.engine_room.flywheel.backend.gl.buffer.GlBuffer; @@ -8,7 +8,7 @@ import dev.engine_room.flywheel.lib.math.MoreMath; import dev.engine_room.flywheel.lib.memory.MemoryBlock; -public class UniformBuffer { + public class UniformBuffer { private final int index; private final MemoryBlock clientBuffer; @Nullable diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/uniform/UniformWriter.java b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/uniform/UniformWriter.java index 81b2ba6b1..b099c17c6 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/uniform/UniformWriter.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/uniform/UniformWriter.java @@ -2,6 +2,7 @@ import org.joml.Matrix4f; import org.joml.Vector3fc; +import org.joml.Vector4fc; import org.lwjgl.system.MemoryUtil; import dev.engine_room.flywheel.lib.util.ExtraMemoryOps; @@ -50,6 +51,10 @@ static long writeVec4(long ptr, float x, float y, float z, float w) { return ptr + 16; } + static long writeVec4(long ptr, Vector4fc vec) { + return writeVec4(ptr, vec.x(), vec.y(), vec.z(), vec.w()); + } + static long writeIVec2(long ptr, int x, int y) { MemoryUtil.memPutInt(ptr, x); MemoryUtil.memPutInt(ptr + 4, y); diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/extension/CameraRenderStateExtension.java b/common/src/backend/java/dev/engine_room/flywheel/backend/extension/CameraRenderStateExtension.java new file mode 100644 index 000000000..791c471da --- /dev/null +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/extension/CameraRenderStateExtension.java @@ -0,0 +1,7 @@ +package dev.engine_room.flywheel.backend.extension; + +import org.joml.Vector3f; + +public interface CameraRenderStateExtension { + Vector3f flywheel$getForwardVector(); +} diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/SkyLightSectionStorageExtension.java b/common/src/backend/java/dev/engine_room/flywheel/backend/extension/SkyLightSectionStorageExtension.java similarity index 63% rename from common/src/backend/java/dev/engine_room/flywheel/backend/SkyLightSectionStorageExtension.java rename to common/src/backend/java/dev/engine_room/flywheel/backend/extension/SkyLightSectionStorageExtension.java index fe3596c1e..055484ede 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/SkyLightSectionStorageExtension.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/extension/SkyLightSectionStorageExtension.java @@ -1,6 +1,6 @@ -package dev.engine_room.flywheel.backend; +package dev.engine_room.flywheel.backend.extension; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import net.minecraft.world.level.chunk.DataLayer; diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/gl/GlCompat.java b/common/src/backend/java/dev/engine_room/flywheel/backend/gl/GlCompat.java index 897af67fd..42a362ea4 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/gl/GlCompat.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/gl/GlCompat.java @@ -3,9 +3,7 @@ import org.jetbrains.annotations.UnknownNullability; import org.lwjgl.PointerBuffer; import org.lwjgl.opengl.GL; -import org.lwjgl.opengl.GL20; import org.lwjgl.opengl.GL20C; -import org.lwjgl.opengl.GL31C; import org.lwjgl.opengl.GL40; import org.lwjgl.opengl.GL43; import org.lwjgl.opengl.GLCapabilities; @@ -13,6 +11,9 @@ import org.lwjgl.system.MemoryStack; import org.lwjgl.system.MemoryUtil; +import com.mojang.blaze3d.opengl.GlConst; +import com.mojang.blaze3d.opengl.GlStateManager; + import dev.engine_room.flywheel.backend.FlwBackend; import dev.engine_room.flywheel.backend.compile.core.Compilation; import dev.engine_room.flywheel.backend.gl.shader.GlProgram; @@ -127,7 +128,7 @@ private static int subgroupSize() { return 32; } if (CAPABILITIES.GL_KHR_shader_subgroup) { - return GL31C.glGetInteger(KHRShaderSubgroup.GL_SUBGROUP_SIZE_KHR); + return GlStateManager._getInteger(KHRShaderSubgroup.GL_SUBGROUP_SIZE_KHR); } // Try to guess. @@ -197,7 +198,7 @@ private static GlslVersion maxGlslVersion() { } private static boolean canCompileVersion(GlslVersion version) { - int handle = GL20.glCreateShader(GL20.GL_VERTEX_SHADER); + int handle = GlStateManager.glCreateShader(GlConst.GL_VERTEX_SHADER); // Compile the simplest possible shader. var source = """ @@ -206,11 +207,11 @@ void main() {} """.formatted(version.version); safeShaderSource(handle, source); - GL20.glCompileShader(handle); + GlStateManager.glCompileShader(handle); boolean success = Compilation.compiledSuccessfully(handle); - GL20.glDeleteShader(handle); + GlStateManager.glDeleteShader(handle); return success; } @@ -222,7 +223,7 @@ private static String safeGetString(int name) { if (CAPABILITIES == null) { return "invalid"; } - String str = GL20C.glGetString(name); + String str = GlStateManager._getString(name); return str == null ? "null" : str; } } diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/gl/GlFence.java b/common/src/backend/java/dev/engine_room/flywheel/backend/gl/GlFence.java deleted file mode 100644 index 63da9617d..000000000 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/gl/GlFence.java +++ /dev/null @@ -1,34 +0,0 @@ -package dev.engine_room.flywheel.backend.gl; - -import static org.lwjgl.opengl.GL32.GL_SIGNALED; -import static org.lwjgl.opengl.GL32.GL_SYNC_GPU_COMMANDS_COMPLETE; -import static org.lwjgl.opengl.GL32.GL_SYNC_STATUS; -import static org.lwjgl.opengl.GL32.glDeleteSync; -import static org.lwjgl.opengl.GL32.glFenceSync; -import static org.lwjgl.opengl.GL32.nglGetSynciv; - -import org.lwjgl.system.MemoryStack; -import org.lwjgl.system.MemoryUtil; - -public class GlFence { - private final long fence; - - public GlFence() { - fence = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); - } - - public boolean isSignaled() { - int result; - try (var memoryStack = MemoryStack.stackPush()) { - long checkPtr = memoryStack.ncalloc(Integer.BYTES, 0, Integer.BYTES); - nglGetSynciv(fence, GL_SYNC_STATUS, 1, MemoryUtil.NULL, checkPtr); - - result = MemoryUtil.memGetInt(checkPtr); - } - return result == GL_SIGNALED; - } - - public void delete() { - glDeleteSync(fence); - } -} diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/gl/GlNumericType.java b/common/src/backend/java/dev/engine_room/flywheel/backend/gl/GlNumericType.java deleted file mode 100644 index 1a42b8485..000000000 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/gl/GlNumericType.java +++ /dev/null @@ -1,42 +0,0 @@ -package dev.engine_room.flywheel.backend.gl; - -import org.lwjgl.opengl.GL11; - -public enum GlNumericType { - FLOAT(4, "float", GL11.GL_FLOAT), - UBYTE(1, "ubyte", GL11.GL_UNSIGNED_BYTE), - BYTE(1, "byte", GL11.GL_BYTE), - USHORT(2, "ushort", GL11.GL_UNSIGNED_SHORT), - SHORT(2, "short", GL11.GL_SHORT), - UINT(4, "uint", GL11.GL_UNSIGNED_INT), - INT(4, "int", GL11.GL_INT), - DOUBLE(8, "double", GL11.GL_DOUBLE), - ; - - public final int byteWidth; - public final String typeName; - public final int glEnum; - - GlNumericType(int bytes, String name, int glEnum) { - this.byteWidth = bytes; - this.typeName = name; - this.glEnum = glEnum; - } - - public int byteWidth() { - return byteWidth; - } - - public String typeName() { - return typeName; - } - - public int glEnum() { - return glEnum; - } - - @Override - public String toString() { - return typeName; - } -} diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/gl/GlPrimitive.java b/common/src/backend/java/dev/engine_room/flywheel/backend/gl/GlPrimitive.java deleted file mode 100644 index 60cc5bccc..000000000 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/gl/GlPrimitive.java +++ /dev/null @@ -1,23 +0,0 @@ -package dev.engine_room.flywheel.backend.gl; - -import org.lwjgl.opengl.GL11; - -public enum GlPrimitive { - POINTS(GL11.GL_POINTS), - LINES(GL11.GL_LINES), - LINE_LOOP(GL11.GL_LINE_LOOP), - LINE_STRIP(GL11.GL_LINE_STRIP), - TRIANGLES(GL11.GL_TRIANGLES), - TRIANGLE_STRIP(GL11.GL_TRIANGLE_STRIP), - TRIANGLE_FAN(GL11.GL_TRIANGLE_FAN), - QUADS(GL11.GL_QUADS), - QUAD_STRIP(GL11.GL_QUAD_STRIP), - POLYGON(GL11.GL_POLYGON), - ; - - public final int glEnum; - - GlPrimitive(int glEnum) { - this.glEnum = glEnum; - } -} diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/gl/GlStateTracker.java b/common/src/backend/java/dev/engine_room/flywheel/backend/gl/GlStateTracker.java index 93c40c9c0..dfe5fd69b 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/gl/GlStateTracker.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/gl/GlStateTracker.java @@ -1,8 +1,10 @@ package dev.engine_room.flywheel.backend.gl; -import com.mojang.blaze3d.platform.GlStateManager; +import com.mojang.blaze3d.opengl.GlConst; +import com.mojang.blaze3d.opengl.GlStateManager; import dev.engine_room.flywheel.backend.gl.buffer.GlBufferType; +import dev.engine_room.flywheel.backend.mixin.GlStateManagerAccessor; /** * Tracks bound buffers/vbos because GlStateManager doesn't do that for us. @@ -37,7 +39,7 @@ public static void _setProgram(int id) { } public static State getRestoreState() { - return new State(BUFFERS.clone(), vao, program, GlStateManager._getActiveTexture()); + return new State(BUFFERS.clone(), vao, program, GlStateManagerAccessor.flywheel$getActiveTexture() + GlConst.GL_TEXTURE0); } public static void bindVao(int vao) { diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/gl/GlTexture.java b/common/src/backend/java/dev/engine_room/flywheel/backend/gl/GlTexture.java deleted file mode 100644 index 958763d53..000000000 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/gl/GlTexture.java +++ /dev/null @@ -1,26 +0,0 @@ -package dev.engine_room.flywheel.backend.gl; - -import org.lwjgl.opengl.GL20; - -public class GlTexture extends GlObject { - private final int textureType; - - public GlTexture(int textureType) { - this.textureType = textureType; - handle(GL20.glGenTextures()); - } - - @Override - protected void deleteInternal(int handle) { - GL20.glDeleteTextures(handle); - } - - public void bind() { - GL20.glBindTexture(textureType, handle()); - } - - public void unbind() { - GL20.glBindTexture(textureType, 0); - } - -} diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/gl/GlTextureUnit.java b/common/src/backend/java/dev/engine_room/flywheel/backend/gl/GlTextureUnit.java index 75797f2ec..67932362c 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/gl/GlTextureUnit.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/gl/GlTextureUnit.java @@ -1,8 +1,9 @@ package dev.engine_room.flywheel.backend.gl; -import static org.lwjgl.opengl.GL13.GL_TEXTURE0; +import com.mojang.blaze3d.opengl.GlConst; +import com.mojang.blaze3d.opengl.GlStateManager; -import com.mojang.blaze3d.platform.GlStateManager; +import dev.engine_room.flywheel.backend.mixin.GlStateManagerAccessor; public enum GlTextureUnit { T0(0), @@ -40,12 +41,14 @@ public enum GlTextureUnit { ; + private static final GlTextureUnit[] VALUES = values(); + public final int number; public final int glEnum; GlTextureUnit(int unit) { this.number = unit; - this.glEnum = GL_TEXTURE0 + unit; + this.glEnum = GlConst.GL_TEXTURE0 + unit; } public void makeActive() { @@ -53,10 +56,14 @@ public void makeActive() { } public static GlTextureUnit getActive() { - return fromGlEnum(GlStateManager._getActiveTexture()); + return fromIndex(GlStateManagerAccessor.flywheel$getActiveTexture()); } public static GlTextureUnit fromGlEnum(int glEnum) { - return GlTextureUnit.values()[glEnum - GL_TEXTURE0]; + return VALUES[glEnum - GlConst.GL_TEXTURE0]; + } + + public static GlTextureUnit fromIndex(int index) { + return VALUES[index]; } } diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/gl/GlUtil.java b/common/src/backend/java/dev/engine_room/flywheel/backend/gl/GlUtil.java new file mode 100644 index 000000000..55cfc42a8 --- /dev/null +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/gl/GlUtil.java @@ -0,0 +1,16 @@ +package dev.engine_room.flywheel.backend.gl; + +import com.mojang.blaze3d.opengl.GlDevice; +import com.mojang.blaze3d.systems.GpuDeviceBackend; +import com.mojang.blaze3d.systems.RenderSystem; + +import dev.engine_room.flywheel.backend.mixin.GpuDeviceAccessor; + +public class GlUtil { + // TODO: This is bad, really bad for when vulkan comes around + @Deprecated(forRemoval = true) + public static GlDevice getGlDevice() { + GpuDeviceBackend backend = ((GpuDeviceAccessor) RenderSystem.getDevice()).flywheel$getBackend(); + return (GlDevice) backend; + } +} diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/gl/TextureBuffer.java b/common/src/backend/java/dev/engine_room/flywheel/backend/gl/TextureBuffer.java index d7bbc9cfc..b27157822 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/gl/TextureBuffer.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/gl/TextureBuffer.java @@ -2,8 +2,10 @@ import org.lwjgl.opengl.GL32; +import com.mojang.blaze3d.opengl.GlStateManager; + public class TextureBuffer extends GlObject { - public static final int MAX_TEXELS = GL32.glGetInteger(GL32.GL_MAX_TEXTURE_BUFFER_SIZE); + public static final int MAX_TEXELS = GlStateManager._getInteger(GL32.GL_MAX_TEXTURE_BUFFER_SIZE); public static final int MAX_BYTES = MAX_TEXELS * 16; // 4 channels * 4 bytes private final int format; diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/gl/array/GlVertexArray.java b/common/src/backend/java/dev/engine_room/flywheel/backend/gl/array/GlVertexArray.java index 28da1390a..46b555b06 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/gl/array/GlVertexArray.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/gl/array/GlVertexArray.java @@ -3,14 +3,15 @@ import java.util.List; import org.lwjgl.opengl.GL32; +import org.lwjgl.opengl.GL33C; -import com.mojang.blaze3d.platform.GlStateManager; +import com.mojang.blaze3d.opengl.GlStateManager; import dev.engine_room.flywheel.backend.gl.GlObject; import dev.engine_room.flywheel.backend.gl.GlStateTracker; public abstract class GlVertexArray extends GlObject { - protected static final int MAX_ATTRIBS = GL32.glGetInteger(GL32.GL_MAX_VERTEX_ATTRIBS); + protected static final int MAX_ATTRIBS = GlStateManager._getInteger(GL32.GL_MAX_VERTEX_ATTRIBS); protected static final int MAX_ATTRIB_BINDINGS = 16; public static GlVertexArray create() { @@ -41,6 +42,6 @@ public void bindForDraw() { @Override protected void deleteInternal(int handle) { - GlStateManager._glDeleteVertexArrays(handle); + GL33C.glDeleteVertexArrays(handle); } } diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/gl/array/GlVertexArrayDSA.java b/common/src/backend/java/dev/engine_room/flywheel/backend/gl/array/GlVertexArrayDSA.java index a3c67b0d2..196ecdb1d 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/gl/array/GlVertexArrayDSA.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/gl/array/GlVertexArrayDSA.java @@ -7,8 +7,10 @@ import org.lwjgl.opengl.GL45C; import org.lwjgl.system.Checks; +import com.mojang.blaze3d.opengl.GlConst; + import dev.engine_room.flywheel.backend.gl.GlCompat; -import net.minecraft.Util; +import net.minecraft.util.Util; public class GlVertexArrayDSA extends GlVertexArray { public static final boolean SUPPORTED = isSupported(); @@ -58,9 +60,9 @@ public void bindAttributes(final int bindingIndex, final int startAttribIndex, L if (!attribute.equals(attributes[attribIndex])) { if (attribute instanceof VertexAttribute.Float f) { - GL45C.glVertexArrayAttribFormat(handle, attribIndex, f.size(), f.type().glEnum, f.normalized(), offset); + GL45C.glVertexArrayAttribFormat(handle, attribIndex, f.size(), GlConst.toGl(f.type()), f.normalized(), offset); } else if (attribute instanceof VertexAttribute.Int vi) { - GL45C.glVertexArrayAttribIFormat(handle, attribIndex, vi.size(), vi.type().glEnum, offset); + GL45C.glVertexArrayAttribIFormat(handle, attribIndex, vi.size(), GlConst.toGl(vi.type()), offset); } attributes[attribIndex] = attribute; } diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/gl/array/GlVertexArrayGL3.java b/common/src/backend/java/dev/engine_room/flywheel/backend/gl/array/GlVertexArrayGL3.java index 785b17fca..5c9d92215 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/gl/array/GlVertexArrayGL3.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/gl/array/GlVertexArrayGL3.java @@ -5,15 +5,15 @@ import java.util.List; import org.lwjgl.opengl.ARBInstancedArrays; -import org.lwjgl.opengl.GL20C; -import org.lwjgl.opengl.GL30; -import org.lwjgl.opengl.GL32; import org.lwjgl.opengl.GL33C; import org.lwjgl.system.Checks; +import com.mojang.blaze3d.opengl.GlConst; +import com.mojang.blaze3d.opengl.GlStateManager; + import dev.engine_room.flywheel.backend.gl.GlCompat; import dev.engine_room.flywheel.backend.gl.buffer.GlBufferType; -import net.minecraft.Util; +import net.minecraft.util.Util; public abstract class GlVertexArrayGL3 extends GlVertexArray { private final BitSet attributeDirty = new BitSet(MAX_ATTRIBS); @@ -28,7 +28,7 @@ public abstract class GlVertexArrayGL3 extends GlVertexArray { private int boundElementBuffer = 0; public GlVertexArrayGL3() { - handle(GL30.glGenVertexArrays()); + handle(GlStateManager._glGenVertexArrays()); } @Override @@ -106,17 +106,15 @@ private void updateAttribute(int attribIndex) { } GlBufferType.ARRAY_BUFFER.bind(bindingBuffers[bindingIndex]); - GL20C.glEnableVertexAttribArray(attribIndex); + GlStateManager._enableVertexAttribArray(attribIndex); long offset = bindingOffsets[bindingIndex] + attributeOffsets[attribIndex]; int stride = bindingStrides[bindingIndex]; if (attribute instanceof VertexAttribute.Float f) { - GL32.glVertexAttribPointer(attribIndex, f.size(), f.type() - .glEnum(), f.normalized(), stride, offset); + GlStateManager._vertexAttribPointer(attribIndex, f.size(), GlConst.toGl(f.type()), f.normalized(), stride, offset); } else if (attribute instanceof VertexAttribute.Int vi) { - GL32.glVertexAttribIPointer(attribIndex, vi.size(), vi.type() - .glEnum(), stride, offset); + GlStateManager._vertexAttribIPointer(attribIndex, vi.size(), GlConst.toGl(vi.type()), stride, offset); } int divisor = bindingDivisors[bindingIndex]; diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/gl/array/GlVertexArraySeparateAttributes.java b/common/src/backend/java/dev/engine_room/flywheel/backend/gl/array/GlVertexArraySeparateAttributes.java index 6488ea03d..9813a7173 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/gl/array/GlVertexArraySeparateAttributes.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/gl/array/GlVertexArraySeparateAttributes.java @@ -7,10 +7,13 @@ import org.lwjgl.opengl.GL43C; import org.lwjgl.system.Checks; +import com.mojang.blaze3d.opengl.GlConst; +import com.mojang.blaze3d.opengl.GlStateManager; + import dev.engine_room.flywheel.backend.gl.GlCompat; import dev.engine_room.flywheel.backend.gl.GlStateTracker; import dev.engine_room.flywheel.backend.gl.buffer.GlBufferType; -import net.minecraft.Util; +import net.minecraft.util.Util; public class GlVertexArraySeparateAttributes extends GlVertexArray { public static final boolean SUPPORTED = isSupported(); @@ -25,7 +28,7 @@ public class GlVertexArraySeparateAttributes extends GlVertexArray { private int elementBufferBinding = 0; public GlVertexArraySeparateAttributes() { - handle(GL43C.glGenVertexArrays()); + handle(GlStateManager._glGenVertexArrays()); } @Override @@ -55,15 +58,15 @@ public void bindAttributes(final int bindingIndex, final int startAttribIndex, L for (var attribute : vertexAttributes) { if (!attributeEnabled.get(attribIndex)) { - GL43C.glEnableVertexAttribArray(attribIndex); + GlStateManager._enableVertexAttribArray(attribIndex); attributeEnabled.set(attribIndex); } if (!attribute.equals(attributes[attribIndex])) { if (attribute instanceof VertexAttribute.Float f) { - GL43C.glVertexAttribFormat(attribIndex, f.size(), f.type().glEnum, f.normalized(), offset); + GL43C.glVertexAttribFormat(attribIndex, f.size(), GlConst.toGl(f.type()), f.normalized(), offset); } else if (attribute instanceof VertexAttribute.Int vi) { - GL43C.glVertexAttribIFormat(attribIndex, vi.size(), vi.type().glEnum, offset); + GL43C.glVertexAttribIFormat(attribIndex, vi.size(), GlConst.toGl(vi.type()), offset); } attributes[attribIndex] = attribute; } diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/gl/array/VertexAttribute.java b/common/src/backend/java/dev/engine_room/flywheel/backend/gl/array/VertexAttribute.java index c01911dea..abb4b3172 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/gl/array/VertexAttribute.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/gl/array/VertexAttribute.java @@ -1,6 +1,6 @@ package dev.engine_room.flywheel.backend.gl.array; -import dev.engine_room.flywheel.backend.gl.GlNumericType; +import com.mojang.blaze3d.vertex.VertexFormatElement; public sealed interface VertexAttribute { int byteWidth(); @@ -12,10 +12,10 @@ public sealed interface VertexAttribute { * @param size The number of components in the attribute, e.g. 3 for a vec3. * @param normalized Whether the data is normalized. */ - record Float(GlNumericType type, int size, boolean normalized) implements VertexAttribute { + record Float(VertexFormatElement.Type type, int size, boolean normalized) implements VertexAttribute { @Override public int byteWidth() { - return size * type.byteWidth(); + return size * type.size(); } } @@ -25,10 +25,10 @@ public int byteWidth() { * @param type The type of the attribute, e.g. GL_INT. * @param size The number of components in the attribute, e.g. 3 for a vec3. */ - record Int(GlNumericType type, int size) implements VertexAttribute { + record Int(VertexFormatElement.Type type, int size) implements VertexAttribute { @Override public int byteWidth() { - return size * type.byteWidth(); + return size * type.size(); } } } diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/gl/buffer/Buffer.java b/common/src/backend/java/dev/engine_room/flywheel/backend/gl/buffer/Buffer.java index 2e73a8fe6..43a0057e7 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/gl/buffer/Buffer.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/gl/buffer/Buffer.java @@ -4,6 +4,8 @@ import org.lwjgl.opengl.GL45C; import org.lwjgl.system.Checks; +import com.mojang.blaze3d.opengl.GlStateManager; + import dev.engine_room.flywheel.backend.gl.GlCompat; public interface Buffer { @@ -47,7 +49,7 @@ private static boolean dsaMethodsAvailable() { class Core implements Buffer { @Override public int create() { - return GL15.glGenBuffers(); + return GlStateManager._glGenBuffers(); } @Override diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/gl/buffer/GlBuffer.java b/common/src/backend/java/dev/engine_room/flywheel/backend/gl/buffer/GlBuffer.java index 881c24239..11c932f49 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/gl/buffer/GlBuffer.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/gl/buffer/GlBuffer.java @@ -1,11 +1,12 @@ package dev.engine_room.flywheel.backend.gl.buffer; -import com.mojang.blaze3d.platform.GlStateManager; +import com.mojang.blaze3d.opengl.GlStateManager; import dev.engine_room.flywheel.backend.gl.GlObject; import dev.engine_room.flywheel.lib.memory.FlwMemoryTracker; import dev.engine_room.flywheel.lib.memory.MemoryBlock; +@Deprecated(forRemoval = true) public class GlBuffer extends GlObject { protected final GlBufferUsage usage; /** diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/gl/buffer/GlBufferType.java b/common/src/backend/java/dev/engine_room/flywheel/backend/gl/buffer/GlBufferType.java index 933976157..56d02ce32 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/gl/buffer/GlBufferType.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/gl/buffer/GlBufferType.java @@ -8,18 +8,20 @@ import org.lwjgl.opengl.GL42; import org.lwjgl.opengl.GL43; +import com.mojang.blaze3d.opengl.GlConst; + import dev.engine_room.flywheel.backend.gl.GlStateTracker; public enum GlBufferType { - ARRAY_BUFFER(GL15C.GL_ARRAY_BUFFER, GL15C.GL_ARRAY_BUFFER_BINDING), - ELEMENT_ARRAY_BUFFER(GL15C.GL_ELEMENT_ARRAY_BUFFER, GL15C.GL_ELEMENT_ARRAY_BUFFER_BINDING), - PIXEL_PACK_BUFFER(GL21.GL_PIXEL_PACK_BUFFER, GL21.GL_PIXEL_PACK_BUFFER_BINDING), - PIXEL_UNPACK_BUFFER(GL21.GL_PIXEL_UNPACK_BUFFER, GL21.GL_PIXEL_UNPACK_BUFFER_BINDING), + ARRAY_BUFFER(GlConst.GL_ARRAY_BUFFER, GL15C.GL_ARRAY_BUFFER_BINDING), + ELEMENT_ARRAY_BUFFER(GlConst.GL_ELEMENT_ARRAY_BUFFER, GL15C.GL_ELEMENT_ARRAY_BUFFER_BINDING), + PIXEL_PACK_BUFFER(GlConst.GL_PIXEL_PACK_BUFFER, GL21.GL_PIXEL_PACK_BUFFER_BINDING), + PIXEL_UNPACK_BUFFER(GlConst.GL_PIXEL_UNPACK_BUFFER, GL21.GL_PIXEL_UNPACK_BUFFER_BINDING), TRANSFORM_FEEDBACK_BUFFER(GL30.GL_TRANSFORM_FEEDBACK_BUFFER, GL30.GL_TRANSFORM_FEEDBACK_BUFFER_BINDING), - UNIFORM_BUFFER(GL31.GL_UNIFORM_BUFFER, GL31.GL_UNIFORM_BUFFER_BINDING), + UNIFORM_BUFFER(GlConst.GL_UNIFORM_BUFFER, GL31.GL_UNIFORM_BUFFER_BINDING), TEXTURE_BUFFER(GL31.GL_TEXTURE_BUFFER, GL31.GL_TEXTURE_BUFFER), - COPY_READ_BUFFER(GL31.GL_COPY_READ_BUFFER, GL31.GL_COPY_READ_BUFFER), - COPY_WRITE_BUFFER(GL31.GL_COPY_WRITE_BUFFER, GL31.GL_COPY_WRITE_BUFFER), + COPY_READ_BUFFER(GlConst.GL_COPY_READ_BUFFER, GlConst.GL_COPY_READ_BUFFER), + COPY_WRITE_BUFFER(GlConst.GL_COPY_WRITE_BUFFER, GlConst.GL_COPY_WRITE_BUFFER), DRAW_INDIRECT_BUFFER(GL40.GL_DRAW_INDIRECT_BUFFER, GL40.GL_DRAW_INDIRECT_BUFFER_BINDING), ATOMIC_COUNTER_BUFFER(GL42.GL_ATOMIC_COUNTER_BUFFER, GL42.GL_ATOMIC_COUNTER_BUFFER_BINDING), DISPATCH_INDIRECT_BUFFER(GL43.GL_DISPATCH_INDIRECT_BUFFER, GL43.GL_DISPATCH_INDIRECT_BUFFER_BINDING), @@ -36,15 +38,15 @@ public enum GlBufferType { public static GlBufferType fromTarget(int pTarget) { return switch (pTarget) { - case GL15C.GL_ARRAY_BUFFER -> ARRAY_BUFFER; - case GL15C.GL_ELEMENT_ARRAY_BUFFER -> ELEMENT_ARRAY_BUFFER; - case GL21.GL_PIXEL_PACK_BUFFER -> PIXEL_PACK_BUFFER; - case GL21.GL_PIXEL_UNPACK_BUFFER -> PIXEL_UNPACK_BUFFER; + case GlConst.GL_ARRAY_BUFFER -> ARRAY_BUFFER; + case GlConst.GL_ELEMENT_ARRAY_BUFFER -> ELEMENT_ARRAY_BUFFER; + case GlConst.GL_PIXEL_PACK_BUFFER -> PIXEL_PACK_BUFFER; + case GlConst.GL_PIXEL_UNPACK_BUFFER -> PIXEL_UNPACK_BUFFER; case GL30.GL_TRANSFORM_FEEDBACK_BUFFER -> TRANSFORM_FEEDBACK_BUFFER; - case GL31.GL_UNIFORM_BUFFER -> UNIFORM_BUFFER; + case GlConst.GL_UNIFORM_BUFFER -> UNIFORM_BUFFER; case GL31.GL_TEXTURE_BUFFER -> TEXTURE_BUFFER; - case GL31.GL_COPY_READ_BUFFER -> COPY_READ_BUFFER; - case GL31.GL_COPY_WRITE_BUFFER -> COPY_WRITE_BUFFER; + case GlConst.GL_COPY_READ_BUFFER -> COPY_READ_BUFFER; + case GlConst.GL_COPY_WRITE_BUFFER -> COPY_WRITE_BUFFER; case GL40.GL_DRAW_INDIRECT_BUFFER -> DRAW_INDIRECT_BUFFER; case GL42.GL_ATOMIC_COUNTER_BUFFER -> ATOMIC_COUNTER_BUFFER; case GL43.GL_DISPATCH_INDIRECT_BUFFER -> DISPATCH_INDIRECT_BUFFER; diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/gl/buffer/GlBufferUsage.java b/common/src/backend/java/dev/engine_room/flywheel/backend/gl/buffer/GlBufferUsage.java index 905a979e1..dbeb51cfa 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/gl/buffer/GlBufferUsage.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/gl/buffer/GlBufferUsage.java @@ -1,21 +1,22 @@ package dev.engine_room.flywheel.backend.gl.buffer; -import org.lwjgl.opengl.GL15; +import com.mojang.blaze3d.opengl.GlConst; /** * Gives a hint to the driver about how you intend to use a buffer. For a detailed explanation, see * this article. */ +@Deprecated(forRemoval = true) public enum GlBufferUsage { - STREAM_DRAW(GL15.GL_STREAM_DRAW), - STREAM_READ(GL15.GL_STREAM_READ), - STREAM_COPY(GL15.GL_STREAM_COPY), - STATIC_DRAW(GL15.GL_STATIC_DRAW), - STATIC_READ(GL15.GL_STATIC_READ), - STATIC_COPY(GL15.GL_STATIC_COPY), - DYNAMIC_DRAW(GL15.GL_DYNAMIC_DRAW), - DYNAMIC_READ(GL15.GL_DYNAMIC_READ), - DYNAMIC_COPY(GL15.GL_DYNAMIC_COPY), + STREAM_DRAW(GlConst.GL_STREAM_DRAW), + STREAM_READ(GlConst.GL_STREAM_READ), + STREAM_COPY(GlConst.GL_STREAM_COPY), + STATIC_DRAW(GlConst.GL_STATIC_DRAW), + STATIC_READ(GlConst.GL_STATIC_READ), + STATIC_COPY(GlConst.GL_STATIC_COPY), + DYNAMIC_DRAW(GlConst.GL_DYNAMIC_DRAW), + DYNAMIC_READ(GlConst.GL_DYNAMIC_READ), + DYNAMIC_COPY(GlConst.GL_DYNAMIC_COPY), ; public final int glEnum; diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/gl/error/GlError.java b/common/src/backend/java/dev/engine_room/flywheel/backend/gl/error/GlError.java deleted file mode 100644 index 4780a0922..000000000 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/gl/error/GlError.java +++ /dev/null @@ -1,48 +0,0 @@ -package dev.engine_room.flywheel.backend.gl.error; - -import java.util.function.Supplier; - -import org.lwjgl.opengl.GL20; -import org.lwjgl.opengl.GL30; - -import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap; -import it.unimi.dsi.fastutil.ints.Int2ObjectMap; - -public enum GlError { - INVALID_ENUM(GL20.GL_INVALID_ENUM), - INVALID_VALUE(GL20.GL_INVALID_VALUE), - INVALID_OPERATION(GL20.GL_INVALID_OPERATION), - INVALID_FRAMEBUFFER_OPERATION(GL30.GL_INVALID_FRAMEBUFFER_OPERATION), - OUT_OF_MEMORY(GL20.GL_OUT_OF_MEMORY), - STACK_UNDERFLOW(GL20.GL_STACK_UNDERFLOW), - STACK_OVERFLOW(GL20.GL_STACK_OVERFLOW), - ; - - private static final Int2ObjectMap errorLookup = new Int2ObjectArrayMap<>(); - - static { - errorLookup.defaultReturnValue(null); - for (GlError value : values()) { - errorLookup.put(value.glEnum, value); - } - } - - final int glEnum; - - GlError(int glEnum) { - this.glEnum = glEnum; - } - - // Great for use in your debugger's expression evaluator - public static GlError poll() { - return errorLookup.get(GL20.glGetError()); - } - - public static void pollAndThrow(Supplier context) { -// This was a bad idea. -// GlError err = GlError.poll(); -// if (err != null) { -// Flywheel.LOGGER.error("{}: {}", err.name(), context.get()); -// } - } -} diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/gl/error/GlException.java b/common/src/backend/java/dev/engine_room/flywheel/backend/gl/error/GlException.java deleted file mode 100644 index 05b405258..000000000 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/gl/error/GlException.java +++ /dev/null @@ -1,15 +0,0 @@ -package dev.engine_room.flywheel.backend.gl.error; - -public class GlException extends RuntimeException { - - final GlError errorCode; - - public GlException(GlError errorCode, String message) { - super(updateMessage(errorCode, message)); - this.errorCode = errorCode; - } - - private static String updateMessage(GlError error, String message) { - return String.format("%s: %s", error, message); - } -} diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/gl/shader/GlProgram.java b/common/src/backend/java/dev/engine_room/flywheel/backend/gl/shader/GlProgram.java index 9438ef355..c3f1518fa 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/gl/shader/GlProgram.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/gl/shader/GlProgram.java @@ -1,26 +1,13 @@ package dev.engine_room.flywheel.backend.gl.shader; -import static org.lwjgl.opengl.GL20.glBindAttribLocation; -import static org.lwjgl.opengl.GL20.glDeleteProgram; -import static org.lwjgl.opengl.GL20.glGetUniformLocation; -import static org.lwjgl.opengl.GL20.glUniform1f; -import static org.lwjgl.opengl.GL20.glUniform1i; -import static org.lwjgl.opengl.GL20.glUniform2f; -import static org.lwjgl.opengl.GL20.glUniform3f; -import static org.lwjgl.opengl.GL20.glUniform4f; -import static org.lwjgl.opengl.GL20.glUniformMatrix3fv; -import static org.lwjgl.opengl.GL20.glUniformMatrix4fv; -import static org.lwjgl.opengl.GL30.glUniform1ui; -import static org.lwjgl.opengl.GL30.glUniform2ui; -import static org.lwjgl.opengl.GL31.GL_INVALID_INDEX; -import static org.lwjgl.opengl.GL31.glGetUniformBlockIndex; -import static org.lwjgl.opengl.GL31.glUniformBlockBinding; - import org.joml.Matrix3fc; import org.joml.Matrix4fc; +import org.lwjgl.opengl.GL20; +import org.lwjgl.opengl.GL30; +import org.lwjgl.opengl.GL31; import org.slf4j.Logger; -import com.mojang.blaze3d.shaders.ProgramManager; +import com.mojang.blaze3d.opengl.GlStateManager; import com.mojang.logging.LogUtils; import dev.engine_room.flywheel.backend.gl.GlObject; @@ -28,6 +15,7 @@ import it.unimi.dsi.fastutil.objects.Object2IntMap; import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; +@Deprecated(forRemoval = true) public class GlProgram extends GlObject { private static final Logger LOGGER = LogUtils.getLogger(); @@ -38,11 +26,11 @@ public GlProgram(int handle) { } public void bind() { - ProgramManager.glUseProgram(handle()); + GlStateManager._glUseProgram(handle()); } public static void unbind() { - ProgramManager.glUseProgram(0); + GlStateManager._glUseProgram(0); } public void setFloat(String glslName, float value) { @@ -52,7 +40,7 @@ public void setFloat(String glslName, float value) { return; } - glUniform1f(uniform, value); + GL20.glUniform1f(uniform, value); } public void setVec2(String glslName, float x, float y) { @@ -62,7 +50,7 @@ public void setVec2(String glslName, float x, float y) { return; } - glUniform2f(uniform, x, y); + GL20.glUniform2f(uniform, x, y); } public void setVec3(String glslName, float x, float y, float z) { @@ -72,7 +60,7 @@ public void setVec3(String glslName, float x, float y, float z) { return; } - glUniform3f(uniform, x, y, z); + GL20.glUniform3f(uniform, x, y, z); } public void setVec4(String glslName, float x, float y, float z, float w) { @@ -82,7 +70,7 @@ public void setVec4(String glslName, float x, float y, float z, float w) { return; } - glUniform4f(uniform, x, y, z, w); + GL20.glUniform4f(uniform, x, y, z, w); } public void setMat4(String glslName, Matrix4fc matrix) { @@ -92,7 +80,7 @@ public void setMat4(String glslName, Matrix4fc matrix) { return; } - glUniformMatrix4fv(uniform, false, matrix.get(new float[16])); + GL20.glUniformMatrix4fv(uniform, false, matrix.get(new float[16])); } public void setMat3(String glslName, Matrix3fc matrix) { @@ -102,7 +90,7 @@ public void setMat3(String glslName, Matrix3fc matrix) { return; } - glUniformMatrix3fv(uniform, false, matrix.get(new float[9])); + GL20.glUniformMatrix3fv(uniform, false, matrix.get(new float[9])); } public void setBool(String glslName, boolean bool) { @@ -116,7 +104,7 @@ public void setUInt(String glslName, int value) { return; } - glUniform1ui(uniform, value); + GL30.glUniform1ui(uniform, value); } public void setUVec2(String name, int x, int y) { @@ -126,7 +114,7 @@ public void setUVec2(String name, int x, int y) { return; } - glUniform2ui(uniform, x, y); + GL30.glUniform2ui(uniform, x, y); } public void setInt(String glslName, int value) { @@ -136,7 +124,7 @@ public void setInt(String glslName, int value) { return; } - glUniform1i(uniform, value); + GL20.glUniform1i(uniform, value); } /** @@ -147,7 +135,7 @@ public void setInt(String glslName, int value) { */ public int getUniformLocation(String uniform) { return uniformLocationCache.computeIfAbsent(uniform, s -> { - int index = glGetUniformLocation(this.handle(), uniform); + int index = GlStateManager._glGetUniformLocation(this.handle(), uniform); if (index < 0) { LOGGER.debug("No active uniform '{}' exists. Could be unused.", uniform); @@ -170,27 +158,27 @@ public void setSamplerBinding(String name, int binding) { int samplerUniform = getUniformLocation(name); if (samplerUniform >= 0) { - glUniform1i(samplerUniform, binding); + GL20.glUniform1i(samplerUniform, binding); } } public void setUniformBlockBinding(String name, int binding) { - int index = glGetUniformBlockIndex(handle(), name); + int index = GL31.glGetUniformBlockIndex(handle(), name); - if (index == GL_INVALID_INDEX) { + if (index == GL31.GL_INVALID_INDEX) { LOGGER.debug("No active uniform block '{}' exists. Could be unused.", name); return; } - glUniformBlockBinding(handle(), index, binding); + GL31.glUniformBlockBinding(handle(), index, binding); } public void bindAttribLocation(String attribute, int binding) { - glBindAttribLocation(handle(), binding, attribute); + GlStateManager._glBindAttribLocation(handle(), binding, attribute); } @Override protected void deleteInternal(int handle) { - glDeleteProgram(handle); + GlStateManager.glDeleteProgram(handle); } } diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/gl/shader/GlShader.java b/common/src/backend/java/dev/engine_room/flywheel/backend/gl/shader/GlShader.java index 3481b33a3..ff85c8ca2 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/gl/shader/GlShader.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/gl/shader/GlShader.java @@ -1,9 +1,11 @@ package dev.engine_room.flywheel.backend.gl.shader; -import org.lwjgl.opengl.GL20; +import com.mojang.blaze3d.opengl.GlStateManager; import dev.engine_room.flywheel.backend.gl.GlObject; +// TODO: Waiting for mojang to impl compute shaders, once that is done this can be replaced with GlShaderModule +@Deprecated(forRemoval = true) public class GlShader extends GlObject { public final ShaderType type; @@ -18,7 +20,7 @@ public GlShader(int handle, ShaderType type, String name) { @Override protected void deleteInternal(int handle) { - GL20.glDeleteShader(handle); + GlStateManager.glDeleteShader(handle); } @Override diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/gl/shader/ShaderType.java b/common/src/backend/java/dev/engine_room/flywheel/backend/gl/shader/ShaderType.java index da323ff10..957752568 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/gl/shader/ShaderType.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/gl/shader/ShaderType.java @@ -1,11 +1,14 @@ package dev.engine_room.flywheel.backend.gl.shader; -import org.lwjgl.opengl.GL20; import org.lwjgl.opengl.GL43; +import com.mojang.blaze3d.opengl.GlConst; + +// TODO: Waiting for mojang to impl compute shaders +@Deprecated(forRemoval = true) public enum ShaderType { - VERTEX("vertex", "VERTEX_SHADER", "vert", GL20.GL_VERTEX_SHADER), - FRAGMENT("fragment", "FRAGMENT_SHADER", "frag", GL20.GL_FRAGMENT_SHADER), + VERTEX("vertex", "VERTEX_SHADER", "vert", GlConst.GL_VERTEX_SHADER), + FRAGMENT("fragment", "FRAGMENT_SHADER", "frag", GlConst.GL_FRAGMENT_SHADER), COMPUTE("compute", "COMPUTE_SHADER", "glsl", GL43.GL_COMPUTE_SHADER), ; diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/glsl/LoadError.java b/common/src/backend/java/dev/engine_room/flywheel/backend/glsl/LoadError.java index 5d4347ad4..c56189ed3 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/glsl/LoadError.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/glsl/LoadError.java @@ -9,17 +9,17 @@ import dev.engine_room.flywheel.backend.glsl.error.ErrorBuilder; import dev.engine_room.flywheel.backend.glsl.span.Span; -import net.minecraft.ResourceLocationException; -import net.minecraft.resources.ResourceLocation; +import net.minecraft.IdentifierException; +import net.minecraft.resources.Identifier; sealed public interface LoadError { ErrorBuilder generateMessage(); - record CircularDependency(ResourceLocation offender, List stack) implements LoadError { + record CircularDependency(Identifier offender, List stack) implements LoadError { public String format() { return stack.stream() - .dropWhile(l -> !l.equals(offender)) - .map(ResourceLocation::toString) + .dropWhile(id -> !id.equals(offender)) + .map(Identifier::toString) .collect(Collectors.joining(" -> ")); } @@ -31,12 +31,12 @@ public ErrorBuilder generateMessage() { } } - record IncludeError(ResourceLocation location, List> innerErrors) implements LoadError { + record IncludeError(Identifier id, List> innerErrors) implements LoadError { @Override public ErrorBuilder generateMessage() { var out = ErrorBuilder.create() - .error("could not load \"" + location + "\"") - .pointAtFile(location); + .error("could not load \"" + id + "\"") + .pointAtFile(id); for (var innerError : innerErrors) { var err = innerError.getSecond() @@ -49,29 +49,29 @@ public ErrorBuilder generateMessage() { } } - record IOError(ResourceLocation location, IOException exception) implements LoadError { + record IOError(Identifier id, IOException exception) implements LoadError { @Override public ErrorBuilder generateMessage() { if (exception instanceof FileNotFoundException) { return ErrorBuilder.create() - .error("\"" + location + "\" was not found"); + .error("\"" + id + "\" was not found"); } else { return ErrorBuilder.create() - .error("could not load \"" + location + "\" due to an IO error") + .error("could not load \"" + id + "\" due to an IO error") .note(exception.toString()); } } } - record ResourceError(ResourceLocation location) implements LoadError { + record ResourceError(Identifier id) implements LoadError { @Override public ErrorBuilder generateMessage() { return ErrorBuilder.create() - .error("\"" + location + "\" was not found"); + .error("\"" + id + "\" was not found"); } } - record MalformedInclude(ResourceLocationException exception) implements LoadError { + record MalformedInclude(IdentifierException exception) implements LoadError { @Override public ErrorBuilder generateMessage() { return ErrorBuilder.create() diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/glsl/ShaderSources.java b/common/src/backend/java/dev/engine_room/flywheel/backend/glsl/ShaderSources.java index 3a7274cfa..8c7bf7fbe 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/glsl/ShaderSources.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/glsl/ShaderSources.java @@ -13,7 +13,7 @@ import dev.engine_room.flywheel.backend.compile.FlwPrograms; import dev.engine_room.flywheel.lib.util.StringUtil; -import net.minecraft.resources.ResourceLocation; +import net.minecraft.resources.Identifier; import net.minecraft.server.packs.resources.Resource; import net.minecraft.server.packs.resources.ResourceManager; @@ -24,7 +24,7 @@ public class ShaderSources { public static final String SHADER_DIR = "flywheel/"; @VisibleForTesting - protected final Map cache; + protected final Map cache; public ShaderSources(ResourceManager manager) { var sourceFinder = new SourceFinder(manager); @@ -40,82 +40,82 @@ public ShaderSources(ResourceManager manager) { this.cache = sourceFinder.results; } - private static ResourceLocation locationWithoutFlywheelPrefix(ResourceLocation loc) { - return ResourceLocation.fromNamespaceAndPath(loc.getNamespace(), loc.getPath() + private static Identifier locationWithoutFlywheelPrefix(Identifier id) { + return Identifier.fromNamespaceAndPath(id.getNamespace(), id.getPath() .substring(SHADER_DIR.length())); } - public LoadResult find(ResourceLocation location) { - return cache.computeIfAbsent(location, loc -> new LoadResult.Failure(new LoadError.ResourceError(loc))); + public LoadResult find(Identifier id) { + return cache.computeIfAbsent(id, loc -> new LoadResult.Failure(new LoadError.ResourceError(loc))); } - public SourceFile get(ResourceLocation location) { - return find(location).unwrap(); + public SourceFile get(Identifier id) { + return find(id).unwrap(); } - private static boolean isShader(ResourceLocation loc) { - var path = loc.getPath(); + private static boolean isShader(Identifier id) { + var path = id.getPath(); return path.endsWith(".glsl") || path.endsWith(".vert") || path.endsWith(".frag") || path.endsWith(".comp"); } private static class SourceFinder { - private final Deque findStack = new ArrayDeque<>(); - private final Map results = new HashMap<>(); + private final Deque findStack = new ArrayDeque<>(); + private final Map results = new HashMap<>(); private final ResourceManager manager; public SourceFinder(ResourceManager manager) { this.manager = manager; } - public void rootLoad(ResourceLocation loc, Resource resource) { - var strippedLoc = locationWithoutFlywheelPrefix(loc); + public void rootLoad(Identifier id, Resource resource) { + var strippedId = locationWithoutFlywheelPrefix(id); - if (results.containsKey(strippedLoc)) { + if (results.containsKey(strippedId)) { // Some other source already #included this one. return; } - this.results.put(strippedLoc, readResource(strippedLoc, resource)); + this.results.put(strippedId, readResource(strippedId, resource)); } - public LoadResult recursiveLoad(ResourceLocation location) { - if (findStack.contains(location)) { - // Make a copy of the find stack with the offending location added on top to show the full path. - findStack.addLast(location); + public LoadResult recursiveLoad(Identifier id) { + if (findStack.contains(id)) { + // Make a copy of the find stack with the offending id added on top to show the full path. + findStack.addLast(id); var copy = List.copyOf(findStack); findStack.removeLast(); - return new LoadResult.Failure(new LoadError.CircularDependency(location, copy)); + return new LoadResult.Failure(new LoadError.CircularDependency(id, copy)); } - findStack.addLast(location); + findStack.addLast(id); - LoadResult out = _find(location); + LoadResult out = _find(id); findStack.removeLast(); return out; } - private LoadResult _find(ResourceLocation location) { + private LoadResult _find(Identifier id) { // Can't use computeIfAbsent because mutual recursion causes ConcurrentModificationExceptions - var out = results.get(location); + var out = results.get(id); if (out == null) { - out = load(location); - results.put(location, out); + out = load(id); + results.put(id, out); } return out; } - private LoadResult load(ResourceLocation loc) { - return manager.getResource(loc.withPrefix(SHADER_DIR)) - .map(resource -> readResource(loc, resource)) - .orElseGet(() -> new LoadResult.Failure(new LoadError.ResourceError(loc))); + private LoadResult load(Identifier id) { + return manager.getResource(id.withPrefix(SHADER_DIR)) + .map(resource -> readResource(id, resource)) + .orElseGet(() -> new LoadResult.Failure(new LoadError.ResourceError(id))); } - private LoadResult readResource(ResourceLocation loc, Resource resource) { + private LoadResult readResource(Identifier id, Resource resource) { try (InputStream stream = resource.open()) { String sourceString = new String(stream.readAllBytes(), StandardCharsets.UTF_8); - return SourceFile.parse(this::recursiveLoad, loc, sourceString); + return SourceFile.parse(this::recursiveLoad, id, sourceString); } catch (IOException e) { - return new LoadResult.Failure(new LoadError.IOError(loc, e)); + return new LoadResult.Failure(new LoadError.IOError(id, e)); } } } diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/glsl/SourceFile.java b/common/src/backend/java/dev/engine_room/flywheel/backend/glsl/SourceFile.java index 8a2241d76..8d3c1e7a4 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/glsl/SourceFile.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/glsl/SourceFile.java @@ -7,16 +7,16 @@ import java.util.Set; import java.util.function.Function; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import com.google.common.collect.ImmutableList; import com.mojang.datafixers.util.Pair; import dev.engine_room.flywheel.backend.glsl.span.Span; import dev.engine_room.flywheel.backend.glsl.span.StringSpan; -import dev.engine_room.flywheel.lib.util.ResourceUtil; -import net.minecraft.ResourceLocationException; -import net.minecraft.resources.ResourceLocation; +import dev.engine_room.flywheel.lib.util.IdentifierUtil; +import net.minecraft.IdentifierException; +import net.minecraft.resources.Identifier; /** * Immutable class representing a shader file. @@ -26,7 +26,7 @@ *

*/ public class SourceFile implements SourceComponent { - public final ResourceLocation name; + public final Identifier name; public final SourceLines source; @@ -39,7 +39,7 @@ public class SourceFile implements SourceComponent { public final String finalSource; - private SourceFile(ResourceLocation name, SourceLines source, ImmutableList imports, List included, String finalSource) { + private SourceFile(Identifier name, SourceLines source, ImmutableList imports, List included, String finalSource) { this.name = name; this.source = source; this.imports = imports; @@ -47,11 +47,11 @@ private SourceFile(ResourceLocation name, SourceLines source, ImmutableList sourceFinder, ResourceLocation name, String stringSource) { + public static LoadResult parse(Function sourceFinder, Identifier name, String stringSource) { var source = new SourceLines(name, stringSource); var imports = Import.parseImports(source); @@ -67,15 +67,15 @@ public static LoadResult parse(Function sourceFind continue; } - ResourceLocation location; + Identifier id; try { - location = ResourceUtil.parseFlywheelDefault(string); - } catch (ResourceLocationException e) { + id = IdentifierUtil.parseFlywheelDefault(string); + } catch (IdentifierException e) { failures.add(Pair.of(fileSpan, new LoadError.MalformedInclude(e))); continue; } - var result = sourceFinder.apply(location); + var result = sourceFinder.apply(id); if (result instanceof LoadResult.Success s) { included.add(s.unwrap()); diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/glsl/SourceLines.java b/common/src/backend/java/dev/engine_room/flywheel/backend/glsl/SourceLines.java index 934c40865..21993cb88 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/glsl/SourceLines.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/glsl/SourceLines.java @@ -9,12 +9,12 @@ import it.unimi.dsi.fastutil.ints.IntArrayList; import it.unimi.dsi.fastutil.ints.IntList; import it.unimi.dsi.fastutil.ints.IntLists; -import net.minecraft.resources.ResourceLocation; +import net.minecraft.resources.Identifier; public class SourceLines implements CharSequence { private static final Pattern NEW_LINE = Pattern.compile("(\\r\\n|\\r|\\n)"); - public final ResourceLocation name; + public final Identifier name; /** * 0-indexed line to char pos mapping. */ @@ -26,7 +26,7 @@ public class SourceLines implements CharSequence { private final ImmutableList lines; public final String raw; - public SourceLines(ResourceLocation name, String raw) { + public SourceLines(Identifier name, String raw) { this.name = name; this.raw = raw; this.lineStarts = createLineLookup(raw); diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/glsl/error/ErrorBuilder.java b/common/src/backend/java/dev/engine_room/flywheel/backend/glsl/error/ErrorBuilder.java index b23a05954..07bc535e1 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/glsl/error/ErrorBuilder.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/glsl/error/ErrorBuilder.java @@ -5,7 +5,7 @@ import java.util.stream.Collectors; import java.util.stream.Stream; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import org.jetbrains.annotations.VisibleForTesting; import dev.engine_room.flywheel.backend.glsl.SourceFile; @@ -19,7 +19,7 @@ import dev.engine_room.flywheel.backend.glsl.error.lines.TextLine; import dev.engine_room.flywheel.backend.glsl.span.Span; import dev.engine_room.flywheel.lib.util.StringUtil; -import net.minecraft.resources.ResourceLocation; +import net.minecraft.resources.Identifier; public class ErrorBuilder { // set to false for testing @@ -69,7 +69,7 @@ public ErrorBuilder pointAtFile(SourceLines source) { return pointAtFile(source.name); } - public ErrorBuilder pointAtFile(ResourceLocation file) { + public ErrorBuilder pointAtFile(Identifier file) { return pointAtFile(file.toString()); } diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/glsl/generate/FnSignature.java b/common/src/backend/java/dev/engine_room/flywheel/backend/glsl/generate/FnSignature.java index 6dd81ff65..1bf03bc24 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/glsl/generate/FnSignature.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/glsl/generate/FnSignature.java @@ -3,7 +3,7 @@ import java.util.Collection; import java.util.stream.Collectors; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import com.google.common.collect.ImmutableList; import com.mojang.datafixers.util.Pair; diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/glsl/generate/GlslSwitch.java b/common/src/backend/java/dev/engine_room/flywheel/backend/glsl/generate/GlslSwitch.java index 5112165cb..e1588512f 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/glsl/generate/GlslSwitch.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/glsl/generate/GlslSwitch.java @@ -4,7 +4,7 @@ import java.util.List; import java.util.stream.Collectors; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import com.mojang.datafixers.util.Pair; diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/mixin/AbstractClientPlayerAccessor.java b/common/src/backend/java/dev/engine_room/flywheel/backend/mixin/AbstractClientPlayerAccessor.java index 284653596..2be77ad8d 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/mixin/AbstractClientPlayerAccessor.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/mixin/AbstractClientPlayerAccessor.java @@ -1,6 +1,6 @@ package dev.engine_room.flywheel.backend.mixin; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.gen.Invoker; diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/mixin/CameraAccessor.java b/common/src/backend/java/dev/engine_room/flywheel/backend/mixin/CameraAccessor.java new file mode 100644 index 000000000..b62b50e71 --- /dev/null +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/mixin/CameraAccessor.java @@ -0,0 +1,12 @@ +package dev.engine_room.flywheel.backend.mixin; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +import net.minecraft.client.Camera; + +@Mixin(Camera.class) +public interface CameraAccessor { + @Accessor("depthFar") + float flywheel$getDepthFar(); +} diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/mixin/CameraMixin.java b/common/src/backend/java/dev/engine_room/flywheel/backend/mixin/CameraMixin.java new file mode 100644 index 000000000..b4a1ebcbe --- /dev/null +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/mixin/CameraMixin.java @@ -0,0 +1,23 @@ +package dev.engine_room.flywheel.backend.mixin; + +import org.joml.Vector3fc; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import dev.engine_room.flywheel.backend.extension.CameraRenderStateExtension; +import net.minecraft.client.Camera; +import net.minecraft.client.renderer.state.level.CameraRenderState; + +@Mixin(Camera.class) +public abstract class CameraMixin { + @Shadow + public abstract Vector3fc forwardVector(); + + @Inject(method = "extractRenderState", at = @At("TAIL")) + private void flywheel$extendRenderState(CameraRenderState cameraState, float cameraEntityPartialTicks, CallbackInfo ci) { + ((CameraRenderStateExtension) cameraState).flywheel$getForwardVector().set(forwardVector()); + } +} diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/mixin/CameraRenderStateMixin.java b/common/src/backend/java/dev/engine_room/flywheel/backend/mixin/CameraRenderStateMixin.java new file mode 100644 index 000000000..65f3391c3 --- /dev/null +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/mixin/CameraRenderStateMixin.java @@ -0,0 +1,19 @@ +package dev.engine_room.flywheel.backend.mixin; + +import org.joml.Vector3f; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; + +import dev.engine_room.flywheel.backend.extension.CameraRenderStateExtension; +import net.minecraft.client.renderer.state.level.CameraRenderState; + +@Mixin(CameraRenderState.class) +public class CameraRenderStateMixin implements CameraRenderStateExtension { + @Unique + private final Vector3f flywheel$forwardVector = new Vector3f(); + + @Override + public Vector3f flywheel$getForwardVector() { + return flywheel$forwardVector; + } +} diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/mixin/FogRendererMixin.java b/common/src/backend/java/dev/engine_room/flywheel/backend/mixin/FogRendererMixin.java new file mode 100644 index 000000000..b2b9b2440 --- /dev/null +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/mixin/FogRendererMixin.java @@ -0,0 +1,18 @@ +package dev.engine_room.flywheel.backend.mixin; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import dev.engine_room.flywheel.backend.engine.uniform.FogUniforms; +import net.minecraft.client.renderer.fog.FogData; +import net.minecraft.client.renderer.fog.FogRenderer; + +@Mixin(FogRenderer.class) +abstract class FogRendererMixin { + @Inject(method = "updateBuffer(Lnet/minecraft/client/renderer/fog/FogData;)V", at = @At("HEAD")) + private static void flywheel$onReturnSetupFog(FogData fog, CallbackInfo ci) { + FogUniforms.update(fog.color, fog.environmentalStart, fog.environmentalEnd, fog.renderDistanceStart, fog.renderDistanceEnd, fog.skyEnd, fog.cloudEnd); + } +} diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/mixin/GlStateManagerAccessor.java b/common/src/backend/java/dev/engine_room/flywheel/backend/mixin/GlStateManagerAccessor.java new file mode 100644 index 000000000..a4ce5d7db --- /dev/null +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/mixin/GlStateManagerAccessor.java @@ -0,0 +1,14 @@ +package dev.engine_room.flywheel.backend.mixin; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +import com.mojang.blaze3d.opengl.GlStateManager; + +@Mixin(GlStateManager.class) +public interface GlStateManagerAccessor { + @Accessor("activeTexture") + static int flywheel$getActiveTexture() { + throw new AssertionError(); + } +} diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/mixin/GlStateManagerMixin.java b/common/src/backend/java/dev/engine_room/flywheel/backend/mixin/GlStateManagerMixin.java index d1369f934..4fee1ac28 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/mixin/GlStateManagerMixin.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/mixin/GlStateManagerMixin.java @@ -1,19 +1,16 @@ package dev.engine_room.flywheel.backend.mixin; -import org.joml.Matrix4f; -import org.joml.Vector3f; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import com.mojang.blaze3d.platform.GlStateManager; +import com.mojang.blaze3d.opengl.GlStateManager; -import dev.engine_room.flywheel.backend.engine.uniform.LevelUniforms; import dev.engine_room.flywheel.backend.gl.GlStateTracker; import dev.engine_room.flywheel.backend.gl.buffer.GlBufferType; -@Mixin(value = GlStateManager.class, remap = false) +@Mixin(GlStateManager.class) abstract class GlStateManagerMixin { @Inject(method = "_glBindBuffer(II)V", at = @At("RETURN")) private static void flywheel$onBindBuffer(int target, int buffer, CallbackInfo ci) { @@ -29,12 +26,4 @@ abstract class GlStateManagerMixin { private static void flywheel$onUseProgram(int program, CallbackInfo ci) { GlStateTracker._setProgram(program); } - - @Inject(method = "setupLevelDiffuseLighting", at = @At("HEAD")) - private static void flywheel$onSetupLevelDiffuseLighting(Vector3f vector3f, Vector3f vector3f2, Matrix4f matrix4f, CallbackInfo ci) { - // Capture the light directions before they're transformed into screen space - // Basically all usages of assigning light direction go through here so I think this is safe - LevelUniforms.LIGHT0_DIRECTION.set(vector3f); - LevelUniforms.LIGHT1_DIRECTION.set(vector3f2); - } } diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/mixin/GpuDeviceAccessor.java b/common/src/backend/java/dev/engine_room/flywheel/backend/mixin/GpuDeviceAccessor.java new file mode 100644 index 000000000..a907105cd --- /dev/null +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/mixin/GpuDeviceAccessor.java @@ -0,0 +1,13 @@ +package dev.engine_room.flywheel.backend.mixin; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +import com.mojang.blaze3d.systems.GpuDevice; +import com.mojang.blaze3d.systems.GpuDeviceBackend; + +@Mixin(GpuDevice.class) +public interface GpuDeviceAccessor { + @Accessor("backend") + GpuDeviceBackend flywheel$getBackend(); +} diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/mixin/LightingMixin.java b/common/src/backend/java/dev/engine_room/flywheel/backend/mixin/LightingMixin.java new file mode 100644 index 000000000..3919ac6af --- /dev/null +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/mixin/LightingMixin.java @@ -0,0 +1,23 @@ +package dev.engine_room.flywheel.backend.mixin; + +import org.joml.Vector3f; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import com.mojang.blaze3d.platform.Lighting; +import com.mojang.blaze3d.platform.Lighting.Entry; + +import dev.engine_room.flywheel.backend.engine.uniform.LevelUniforms; + +@Mixin(Lighting.class) +abstract class LightingMixin { + @Inject(method = "updateBuffer(Lcom/mojang/blaze3d/platform/Lighting$Entry;Lorg/joml/Vector3f;Lorg/joml/Vector3f;)V", at = @At("HEAD")) + private static void flywheel$onHeadUpdateBuffer(Entry entry, Vector3f light0, Vector3f light1, CallbackInfo ci) { + if (entry == Entry.LEVEL) { + LevelUniforms.LIGHT0_DIRECTION.set(light0); + LevelUniforms.LIGHT1_DIRECTION.set(light1); + } + } +} diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/mixin/RenderSystemMixin.java b/common/src/backend/java/dev/engine_room/flywheel/backend/mixin/RenderSystemMixin.java index b08444dc7..9df88f3b2 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/mixin/RenderSystemMixin.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/mixin/RenderSystemMixin.java @@ -7,36 +7,12 @@ import com.mojang.blaze3d.systems.RenderSystem; -import dev.engine_room.flywheel.backend.engine.uniform.FogUniforms; import dev.engine_room.flywheel.backend.gl.GlCompat; -@Mixin(value = RenderSystem.class, remap = false) +@Mixin(RenderSystem.class) abstract class RenderSystemMixin { - @Inject(method = "initRenderer(IZ)V", at = @At("RETURN")) + @Inject(method = "initRenderer", at = @At("RETURN")) private static void flywheel$onInitRenderer(CallbackInfo ci) { GlCompat.init(); } - - @Inject(method = "setShaderFogStart(F)V", at = @At("RETURN")) - private static void flywheel$onSetFogStart(CallbackInfo ci) { - FogUniforms.update(); - } - - @Inject(method = "setShaderFogEnd(F)V", at = @At("RETURN")) - private static void flywheel$onSetFogEnd(CallbackInfo ci) { - FogUniforms.update(); - } - - // Fabric fails to resolve the mixin in prod when the full signature is specified. - // I suspect it's because this method references a class name in its signature, - // and that needs to be remapped while the function names in RenderSystem are marked with @DontObfuscate. - @Inject(method = "setShaderFogShape", at = @At("RETURN")) - private static void flywheel$onSetFogShape(CallbackInfo ci) { - FogUniforms.update(); - } - - @Inject(method = "setShaderFogColor(FFFF)V", at = @At("RETURN")) - private static void flywheel$onSetFogColor(CallbackInfo ci) { - FogUniforms.update(); - } } diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/mixin/light/LayerLightSectionStorageAccessor.java b/common/src/backend/java/dev/engine_room/flywheel/backend/mixin/light/LayerLightSectionStorageAccessor.java index 562ac36db..f7cb652ce 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/mixin/light/LayerLightSectionStorageAccessor.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/mixin/light/LayerLightSectionStorageAccessor.java @@ -1,7 +1,6 @@ package dev.engine_room.flywheel.backend.mixin.light; -import javax.annotation.Nullable; - +import org.jspecify.annotations.Nullable; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.gen.Invoker; diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/mixin/light/SkyLightSectionStorageMixin.java b/common/src/backend/java/dev/engine_room/flywheel/backend/mixin/light/SkyLightSectionStorageMixin.java index 8e178e127..09e357efe 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/mixin/light/SkyLightSectionStorageMixin.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/mixin/light/SkyLightSectionStorageMixin.java @@ -1,9 +1,9 @@ package dev.engine_room.flywheel.backend.mixin.light; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import org.spongepowered.asm.mixin.Mixin; -import dev.engine_room.flywheel.backend.SkyLightSectionStorageExtension; +import dev.engine_room.flywheel.backend.extension.SkyLightSectionStorageExtension; import net.minecraft.core.Direction; import net.minecraft.core.SectionPos; import net.minecraft.world.level.chunk.DataLayer; diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/util/AtomicBitSet.java b/common/src/backend/java/dev/engine_room/flywheel/backend/util/AtomicBitSet.java index 23a43eab3..a6fa378d2 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/util/AtomicBitSet.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/util/AtomicBitSet.java @@ -6,7 +6,7 @@ import java.util.BitSet; import java.util.concurrent.atomic.AtomicReference; -import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.NonNull; // https://github.com/Netflix/hollow/blob/master/hollow/src/main/java/com/netflix/hollow/core/memory/ThreadSafeBitSet.java // Refactored to remove unused methods, deduplicate some code segments, and add extra functionality with #forEachSetSpan @@ -481,8 +481,7 @@ private long[] segmentForPosition(int segmentIndex) { return expandToFit(segmentIndex).getSegment(segmentIndex); } - @NotNull - private AtomicBitSet.AtomicBitSetSegments expandToFit(int segmentIndex) { + private AtomicBitSet.@NonNull AtomicBitSetSegments expandToFit(int segmentIndex) { AtomicBitSetSegments visibleSegments = segments.get(); while (visibleSegments.numSegments() <= segmentIndex) { diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/util/MemoryBuffer.java b/common/src/backend/java/dev/engine_room/flywheel/backend/util/MemoryBuffer.java index f87914414..71a5b130d 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/util/MemoryBuffer.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/util/MemoryBuffer.java @@ -1,6 +1,6 @@ package dev.engine_room.flywheel.backend.util; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import dev.engine_room.flywheel.lib.memory.MemoryBlock; diff --git a/common/src/backend/resources/assets/flywheel/flywheel/internal/api_impl.frag b/common/src/backend/resources/assets/flywheel/flywheel/internal/api_impl.frag index af16b80e2..120d69fb0 100644 --- a/common/src/backend/resources/assets/flywheel/flywheel/internal/api_impl.frag +++ b/common/src/backend/resources/assets/flywheel/flywheel/internal/api_impl.frag @@ -9,7 +9,8 @@ flat in ivec2 flw_vertexOverlay; in vec2 flw_vertexLight; in vec3 flw_vertexNormal; -in float flw_distance; +in float flw_sphericalDistance; +in float flw_cylindricalDistance; vec4 flw_sampleColor; diff --git a/common/src/backend/resources/assets/flywheel/flywheel/internal/api_impl.vert b/common/src/backend/resources/assets/flywheel/flywheel/internal/api_impl.vert index 266f4e436..05ae813e4 100644 --- a/common/src/backend/resources/assets/flywheel/flywheel/internal/api_impl.vert +++ b/common/src/backend/resources/assets/flywheel/flywheel/internal/api_impl.vert @@ -9,7 +9,8 @@ flat out ivec2 flw_vertexOverlay; out vec2 flw_vertexLight; out vec3 flw_vertexNormal; -out float flw_distance; +out float flw_sphericalDistance; +out float flw_cylindricalDistance; FlwMaterial flw_material; diff --git a/common/src/backend/resources/assets/flywheel/flywheel/internal/common.frag b/common/src/backend/resources/assets/flywheel/flywheel/internal/common.frag index f6652b8b2..e2736fa5b 100644 --- a/common/src/backend/resources/assets/flywheel/flywheel/internal/common.frag +++ b/common/src/backend/resources/assets/flywheel/flywheel/internal/common.frag @@ -74,7 +74,7 @@ float _flw_diffuseFactor() { if (flw_material.cardinalLightingMode == 2u) { return diffuseFromLightDirections(flw_vertexNormal); } else if (flw_material.cardinalLightingMode == 1u) { - if (flw_constantAmbientLight == 1u) { + if (flw_cardinalLightType == 1u) { return diffuseNether(flw_vertexNormal); } else { return diffuse(flw_vertexNormal); diff --git a/common/src/backend/resources/assets/flywheel/flywheel/internal/common.vert b/common/src/backend/resources/assets/flywheel/flywheel/internal/common.vert index 3c2ffecdc..2ea08f3ea 100644 --- a/common/src/backend/resources/assets/flywheel/flywheel/internal/common.vert +++ b/common/src/backend/resources/assets/flywheel/flywheel/internal/common.vert @@ -93,7 +93,8 @@ void _flw_main(in FlwInstance instance, in uint stableInstanceID, in uint baseVe flw_vertexNormal = normalize(flw_vertexNormal); - flw_distance = fogDistance(flw_vertexPos.xyz, flw_cameraPos, flw_fogShape); + flw_sphericalDistance = sphericalDistance(flw_vertexPos.xyz, flw_cameraPos); + flw_cylindricalDistance = cylindricalDistance(flw_vertexPos.xyz, flw_cameraPos); gl_Position = flw_viewProjection * flw_vertexPos; diff --git a/common/src/backend/resources/assets/flywheel/flywheel/internal/fog_distance.glsl b/common/src/backend/resources/assets/flywheel/flywheel/internal/fog_distance.glsl index 7cedf058d..28bb896c2 100644 --- a/common/src/backend/resources/assets/flywheel/flywheel/internal/fog_distance.glsl +++ b/common/src/backend/resources/assets/flywheel/flywheel/internal/fog_distance.glsl @@ -1,21 +1,10 @@ -float sphericalDistance(vec3 relativePos) { - return length(relativePos); +float sphericalDistance(vec3 worldPos, vec3 cameraPos) { + return length(worldPos - cameraPos); } -float cylindricalDistance(vec3 relativePos) { +float cylindricalDistance(vec3 worldPos, vec3 cameraPos) { + vec3 relativePos = worldPos - cameraPos; float distXZ = length(relativePos.xz); float distY = abs(relativePos.y); return max(distXZ, distY); } - -float fogDistance(vec3 relativePos, int fogShape) { - if (fogShape == 0) { - return sphericalDistance(relativePos); - } else { - return cylindricalDistance(relativePos); - } -} - -float fogDistance(vec3 worldPos, vec3 cameraPos, int fogShape) { - return fogDistance(worldPos - cameraPos, fogShape); -} diff --git a/common/src/backend/resources/assets/flywheel/flywheel/internal/uniforms/fog.glsl b/common/src/backend/resources/assets/flywheel/flywheel/internal/uniforms/fog.glsl index 877c1aa16..875b65ceb 100644 --- a/common/src/backend/resources/assets/flywheel/flywheel/internal/uniforms/fog.glsl +++ b/common/src/backend/resources/assets/flywheel/flywheel/internal/uniforms/fog.glsl @@ -1,5 +1,9 @@ layout(std140) uniform _FlwFogUniforms { vec4 flw_fogColor; - vec2 flw_fogRange; - int flw_fogShape; + float flw_fogEnvironmentalStart; + float flw_fogEnvironmentalEnd; + float flw_fogRenderDistanceStart; + float flw_fogRenderDistanceEnd; + float flw_fogSkyEnd; + float flw_fogCloudEnd; }; diff --git a/common/src/backend/resources/assets/flywheel/flywheel/internal/uniforms/level.glsl b/common/src/backend/resources/assets/flywheel/flywheel/internal/uniforms/level.glsl index 231196aac..1e41e7c1e 100644 --- a/common/src/backend/resources/assets/flywheel/flywheel/internal/uniforms/level.glsl +++ b/common/src/backend/resources/assets/flywheel/flywheel/internal/uniforms/level.glsl @@ -13,10 +13,13 @@ layout(std140) uniform _FlwLevelUniforms { uint flw_levelHasSkyLight; float flw_sunAngle; + float flw_moonAngle; + float flw_starAngle; float flw_moonBrightness; /** There are normally only 8 moon phases. */ uint flw_moonPhase; + float flw_starBrightness; uint flw_isRaining; float flw_rainLevel; @@ -25,7 +28,7 @@ layout(std140) uniform _FlwLevelUniforms { float flw_skyDarken; - uint flw_constantAmbientLight; + uint flw_cardinalLightType; /** Use FLW_DIMENSION_* ids to determine the dimension. May eventually be implemented for custom dimensions. */ uint flw_dimension; diff --git a/common/src/backend/resources/flywheel.backend.mixins.json b/common/src/backend/resources/flywheel.backend.mixins.json index dea705b60..58a84bf35 100644 --- a/common/src/backend/resources/flywheel.backend.mixins.json +++ b/common/src/backend/resources/flywheel.backend.mixins.json @@ -1,13 +1,19 @@ { - "required": true, - "minVersion": "0.8", - "package": "dev.engine_room.flywheel.backend.mixin", - "compatibilityLevel": "JAVA_21", - "refmap": "backend-flywheel.refmap.json", - "client": [ + "required" : true, + "minVersion" : "0.8", + "package" : "dev.engine_room.flywheel.backend.mixin", + "compatibilityLevel" : "JAVA_25", + "client" : [ "AbstractClientPlayerAccessor", + "CameraAccessor", + "CameraMixin", + "CameraRenderStateMixin", + "FogRendererMixin", + "GlStateManagerAccessor", "GlStateManagerMixin", + "GpuDeviceAccessor", "LevelRendererAccessor", + "LightingMixin", "OptionsMixin", "RenderSystemMixin", "light.LayerLightSectionStorageAccessor", @@ -15,7 +21,7 @@ "light.SkyDataLayerStorageMapAccessor", "light.SkyLightSectionStorageMixin" ], - "injectors": { - "defaultRequire": 1 + "injectors" : { + "defaultRequire" : 1 } } diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/backend/SimpleBackend.java b/common/src/lib/java/dev/engine_room/flywheel/lib/backend/SimpleBackend.java index f7da878c7..79838edee 100644 --- a/common/src/lib/java/dev/engine_room/flywheel/lib/backend/SimpleBackend.java +++ b/common/src/lib/java/dev/engine_room/flywheel/lib/backend/SimpleBackend.java @@ -5,11 +5,11 @@ import java.util.function.Function; import java.util.function.IntSupplier; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import dev.engine_room.flywheel.api.backend.Backend; import dev.engine_room.flywheel.api.backend.Engine; -import net.minecraft.resources.ResourceLocation; +import net.minecraft.resources.Identifier; import net.minecraft.world.level.LevelAccessor; public final class SimpleBackend implements Backend { @@ -68,7 +68,7 @@ public Builder supported(BooleanSupplier isSupported) { return this; } - public Backend register(ResourceLocation id) { + public Backend register(Identifier id) { Objects.requireNonNull(engineFactory); Objects.requireNonNull(isSupported); diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/instance/ColoredLitInstance.java b/common/src/lib/java/dev/engine_room/flywheel/lib/instance/ColoredLitInstance.java index e8f95baf5..7fd7eec44 100644 --- a/common/src/lib/java/dev/engine_room/flywheel/lib/instance/ColoredLitInstance.java +++ b/common/src/lib/java/dev/engine_room/flywheel/lib/instance/ColoredLitInstance.java @@ -2,7 +2,7 @@ import dev.engine_room.flywheel.api.instance.InstanceHandle; import dev.engine_room.flywheel.api.instance.InstanceType; -import net.minecraft.util.FastColor; +import net.minecraft.util.ARGB; public abstract class ColoredLitInstance extends AbstractInstance implements FlatLit { public byte red = (byte) 0xFF; @@ -17,11 +17,11 @@ public ColoredLitInstance(InstanceType type, Insta } public ColoredLitInstance colorArgb(int argb) { - return color(FastColor.ARGB32.red(argb), FastColor.ARGB32.green(argb), FastColor.ARGB32.blue(argb), FastColor.ARGB32.alpha(argb)); + return color(ARGB.red(argb), ARGB.green(argb), ARGB.blue(argb), ARGB.alpha(argb)); } public ColoredLitInstance colorRgb(int rgb) { - return color(FastColor.ARGB32.red(rgb), FastColor.ARGB32.green(rgb), FastColor.ARGB32.blue(rgb)); + return color(ARGB.red(rgb), ARGB.green(rgb), ARGB.blue(rgb)); } public ColoredLitInstance color(int red, int green, int blue, int alpha) { diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/instance/FlatLit.java b/common/src/lib/java/dev/engine_room/flywheel/lib/instance/FlatLit.java index 7cd26dab5..3109c90fa 100644 --- a/common/src/lib/java/dev/engine_room/flywheel/lib/instance/FlatLit.java +++ b/common/src/lib/java/dev/engine_room/flywheel/lib/instance/FlatLit.java @@ -3,12 +3,12 @@ import java.util.Iterator; import java.util.stream.Stream; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import dev.engine_room.flywheel.api.instance.Instance; import dev.engine_room.flywheel.lib.visual.AbstractBlockEntityVisual; import dev.engine_room.flywheel.lib.visual.AbstractEntityVisual; -import net.minecraft.client.renderer.LightTexture; +import net.minecraft.util.LightCoordsUtil; /** * An interface that implementors of {@link Instance} should also implement if they wish to make use of @@ -17,7 +17,7 @@ public interface FlatLit extends Instance { /** * Set the packed light value for this instance. - * @param packedLight the packed light per {@link LightTexture#pack(int, int)} + * @param packedLight the packed light per {@link LightCoordsUtil#pack(int, int)} * @return {@code this} for chaining */ FlatLit light(int packedLight); @@ -29,7 +29,7 @@ public interface FlatLit extends Instance { * @return {@code this} for chaining */ default FlatLit light(int blockLight, int skyLight) { - return light(LightTexture.pack(blockLight, skyLight)); + return light(LightCoordsUtil.pack(blockLight, skyLight)); } static void relight(int packedLight, @Nullable FlatLit... instances) { diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/instance/InstanceTypes.java b/common/src/lib/java/dev/engine_room/flywheel/lib/instance/InstanceTypes.java index 9e9152e1a..e93c0ccf6 100644 --- a/common/src/lib/java/dev/engine_room/flywheel/lib/instance/InstanceTypes.java +++ b/common/src/lib/java/dev/engine_room/flywheel/lib/instance/InstanceTypes.java @@ -1,5 +1,7 @@ package dev.engine_room.flywheel.lib.instance; +import dev.engine_room.flywheel.lib.util.IdentifierUtil; + import org.lwjgl.system.MemoryUtil; import dev.engine_room.flywheel.api.instance.InstanceType; @@ -7,7 +9,6 @@ import dev.engine_room.flywheel.api.layout.IntegerRepr; import dev.engine_room.flywheel.api.layout.LayoutBuilder; import dev.engine_room.flywheel.lib.util.ExtraMemoryOps; -import dev.engine_room.flywheel.lib.util.ResourceUtil; public final class InstanceTypes { public static final InstanceType TRANSFORMED = SimpleInstanceType.builder(TransformedInstance::new) @@ -26,8 +27,8 @@ public final class InstanceTypes { ExtraMemoryOps.put2x16(ptr + 8, instance.light); ExtraMemoryOps.putMatrix4f(ptr + 12, instance.pose); }) - .vertexShader(ResourceUtil.rl("instance/transformed.vert")) - .cullShader(ResourceUtil.rl("instance/cull/transformed.glsl")) + .vertexShader(IdentifierUtil.id("instance/transformed.vert")) + .cullShader(IdentifierUtil.id("instance/cull/transformed.glsl")) .build(); public static final InstanceType POSED = SimpleInstanceType.builder(PosedInstance::new) @@ -48,8 +49,8 @@ public final class InstanceTypes { ExtraMemoryOps.putMatrix4f(ptr + 12, instance.pose); ExtraMemoryOps.putMatrix3f(ptr + 76, instance.normal); }) - .vertexShader(ResourceUtil.rl("instance/posed.vert")) - .cullShader(ResourceUtil.rl("instance/cull/posed.glsl")) + .vertexShader(IdentifierUtil.id("instance/posed.vert")) + .cullShader(IdentifierUtil.id("instance/cull/posed.glsl")) .build(); public static final InstanceType ORIENTED = SimpleInstanceType.builder(OrientedInstance::new) @@ -76,8 +77,8 @@ public final class InstanceTypes { MemoryUtil.memPutFloat(ptr + 32, instance.pivotZ); ExtraMemoryOps.putQuaternionf(ptr + 36, instance.rotation); }) - .vertexShader(ResourceUtil.rl("instance/oriented.vert")) - .cullShader(ResourceUtil.rl("instance/cull/oriented.glsl")) + .vertexShader(IdentifierUtil.id("instance/oriented.vert")) + .cullShader(IdentifierUtil.id("instance/cull/oriented.glsl")) .build(); public static final InstanceType SHADOW = SimpleInstanceType.builder(ShadowInstance::new) @@ -99,8 +100,8 @@ public final class InstanceTypes { MemoryUtil.memPutFloat(ptr + 28, instance.alpha); MemoryUtil.memPutFloat(ptr + 32, instance.radius); }) - .vertexShader(ResourceUtil.rl("instance/shadow.vert")) - .cullShader(ResourceUtil.rl("instance/cull/shadow.glsl")) + .vertexShader(IdentifierUtil.id("instance/shadow.vert")) + .cullShader(IdentifierUtil.id("instance/cull/shadow.glsl")) .build(); private InstanceTypes() { diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/instance/SimpleInstanceType.java b/common/src/lib/java/dev/engine_room/flywheel/lib/instance/SimpleInstanceType.java index 81b14082e..57000303c 100644 --- a/common/src/lib/java/dev/engine_room/flywheel/lib/instance/SimpleInstanceType.java +++ b/common/src/lib/java/dev/engine_room/flywheel/lib/instance/SimpleInstanceType.java @@ -7,16 +7,16 @@ import dev.engine_room.flywheel.api.instance.InstanceType; import dev.engine_room.flywheel.api.instance.InstanceWriter; import dev.engine_room.flywheel.api.layout.Layout; -import net.minecraft.resources.ResourceLocation; +import net.minecraft.resources.Identifier; public final class SimpleInstanceType implements InstanceType { private final Factory factory; private final Layout layout; private final InstanceWriter writer; - private final ResourceLocation vertexShader; - private final ResourceLocation cullShader; + private final Identifier vertexShader; + private final Identifier cullShader; - public SimpleInstanceType(Factory factory, Layout layout, InstanceWriter writer, ResourceLocation vertexShader, ResourceLocation cullShader) { + public SimpleInstanceType(Factory factory, Layout layout, InstanceWriter writer, Identifier vertexShader, Identifier cullShader) { this.factory = factory; this.layout = layout; this.writer = writer; @@ -44,12 +44,12 @@ public InstanceWriter writer() { } @Override - public ResourceLocation vertexShader() { + public Identifier vertexShader() { return vertexShader; } @Override - public ResourceLocation cullShader() { + public Identifier cullShader() { return cullShader; } @@ -62,8 +62,8 @@ public static final class Builder { private final Factory factory; private Layout layout; private InstanceWriter writer; - private ResourceLocation vertexShader; - private ResourceLocation cullShader; + private Identifier vertexShader; + private Identifier cullShader; public Builder(Factory factory) { this.factory = factory; @@ -79,12 +79,12 @@ public Builder writer(InstanceWriter writer) { return this; } - public Builder vertexShader(ResourceLocation vertexShader) { + public Builder vertexShader(Identifier vertexShader) { this.vertexShader = vertexShader; return this; } - public Builder cullShader(ResourceLocation cullShader) { + public Builder cullShader(Identifier cullShader) { this.cullShader = cullShader; return this; } diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/internal/FlwLibLink.java b/common/src/lib/java/dev/engine_room/flywheel/lib/internal/FlwLibLink.java index 203cca392..a6877dbb5 100644 --- a/common/src/lib/java/dev/engine_room/flywheel/lib/internal/FlwLibLink.java +++ b/common/src/lib/java/dev/engine_room/flywheel/lib/internal/FlwLibLink.java @@ -1,6 +1,5 @@ package dev.engine_room.flywheel.lib.internal; -import java.util.Deque; import java.util.Map; import org.slf4j.Logger; @@ -11,6 +10,8 @@ import dev.engine_room.flywheel.api.internal.DependencyInjection; import dev.engine_room.flywheel.lib.transform.PoseTransformStack; import net.minecraft.client.model.geom.ModelPart; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.phys.AABB; public interface FlwLibLink { FlwLibLink INSTANCE = DependencyInjection.load(FlwLibLink.class, "dev.engine_room.flywheel.impl.FlwLibLinkImpl"); @@ -23,7 +24,9 @@ public interface FlwLibLink { void compileModelPart(ModelPart part, PoseStack.Pose pose, VertexConsumer consumer, int light, int overlay, int color); - Deque getPoseStack(PoseStack stack); + boolean affectedByCulling(T entity); + + AABB getBoundingBoxForCulling(T entity); boolean isIrisLoaded(); diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/internal/FlwLibXplat.java b/common/src/lib/java/dev/engine_room/flywheel/lib/internal/FlwLibXplat.java index bcc74eef9..caa75a6ef 100644 --- a/common/src/lib/java/dev/engine_room/flywheel/lib/internal/FlwLibXplat.java +++ b/common/src/lib/java/dev/engine_room/flywheel/lib/internal/FlwLibXplat.java @@ -1,22 +1,18 @@ package dev.engine_room.flywheel.lib.internal; -import org.jetbrains.annotations.UnknownNullability; - import dev.engine_room.flywheel.api.internal.DependencyInjection; import dev.engine_room.flywheel.lib.model.SimpleModel; -import dev.engine_room.flywheel.lib.model.baked.BakedModelBuilder; import dev.engine_room.flywheel.lib.model.baked.BlockModelBuilder; -import net.minecraft.client.resources.model.BakedModel; -import net.minecraft.client.resources.model.ModelManager; -import net.minecraft.resources.ResourceLocation; +import dev.engine_room.flywheel.lib.model.baked.LevelModelBuilder; +import dev.engine_room.flywheel.lib.model.baked.PartialModel; +import net.minecraft.resources.Identifier; public interface FlwLibXplat { FlwLibXplat INSTANCE = DependencyInjection.load(FlwLibXplat.class, "dev.engine_room.flywheel.impl.FlwLibXplatImpl"); - @UnknownNullability - BakedModel getBakedModel(ModelManager modelManager, ResourceLocation location); - - SimpleModel buildBakedModelBuilder(BakedModelBuilder builder); + PartialModel createPartialModel(Identifier modelId); SimpleModel buildBlockModelBuilder(BlockModelBuilder builder); + + SimpleModel buildLevelModelBuilder(LevelModelBuilder builder); } diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/internal/package-info.java b/common/src/lib/java/dev/engine_room/flywheel/lib/internal/package-info.java index 6b8384594..2533461ff 100644 --- a/common/src/lib/java/dev/engine_room/flywheel/lib/internal/package-info.java +++ b/common/src/lib/java/dev/engine_room/flywheel/lib/internal/package-info.java @@ -1,12 +1,6 @@ @ApiStatus.Internal -@ParametersAreNonnullByDefault -@FieldsAreNonnullByDefault -@MethodsReturnNonnullByDefault +@NullMarked package dev.engine_room.flywheel.lib.internal; -import javax.annotation.ParametersAreNonnullByDefault; - import org.jetbrains.annotations.ApiStatus; - -import net.minecraft.FieldsAreNonnullByDefault; -import net.minecraft.MethodsReturnNonnullByDefault; +import org.jspecify.annotations.NullMarked; diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/material/CutoutShaders.java b/common/src/lib/java/dev/engine_room/flywheel/lib/material/CutoutShaders.java index 0b107c39c..b7213ceff 100644 --- a/common/src/lib/java/dev/engine_room/flywheel/lib/material/CutoutShaders.java +++ b/common/src/lib/java/dev/engine_room/flywheel/lib/material/CutoutShaders.java @@ -1,25 +1,25 @@ package dev.engine_room.flywheel.lib.material; import dev.engine_room.flywheel.api.material.CutoutShader; -import dev.engine_room.flywheel.lib.util.ResourceUtil; +import dev.engine_room.flywheel.lib.util.IdentifierUtil; public final class CutoutShaders { /** * Do not discard any fragments based on alpha. */ - public static final CutoutShader OFF = new SimpleCutoutShader(ResourceUtil.rl("cutout/off.glsl")); + public static final CutoutShader OFF = new SimpleCutoutShader(IdentifierUtil.id("cutout/off.glsl")); /** * Discard fragments with alpha close to or equal to zero. */ - public static final CutoutShader EPSILON = new SimpleCutoutShader(ResourceUtil.rl("cutout/epsilon.glsl")); + public static final CutoutShader EPSILON = new SimpleCutoutShader(IdentifierUtil.id("cutout/epsilon.glsl")); /** * Discard fragments with alpha less than to 0.1. */ - public static final CutoutShader ONE_TENTH = new SimpleCutoutShader(ResourceUtil.rl("cutout/one_tenth.glsl")); + public static final CutoutShader ONE_TENTH = new SimpleCutoutShader(IdentifierUtil.id("cutout/one_tenth.glsl")); /** * Discard fragments with alpha less than to 0.5. */ - public static final CutoutShader HALF = new SimpleCutoutShader(ResourceUtil.rl("cutout/half.glsl")); + public static final CutoutShader HALF = new SimpleCutoutShader(IdentifierUtil.id("cutout/half.glsl")); private CutoutShaders() { } diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/material/FogShaders.java b/common/src/lib/java/dev/engine_room/flywheel/lib/material/FogShaders.java index 39f903c47..62bb37776 100644 --- a/common/src/lib/java/dev/engine_room/flywheel/lib/material/FogShaders.java +++ b/common/src/lib/java/dev/engine_room/flywheel/lib/material/FogShaders.java @@ -1,12 +1,12 @@ package dev.engine_room.flywheel.lib.material; import dev.engine_room.flywheel.api.material.FogShader; -import dev.engine_room.flywheel.lib.util.ResourceUtil; +import dev.engine_room.flywheel.lib.util.IdentifierUtil; public final class FogShaders { - public static final FogShader NONE = new SimpleFogShader(ResourceUtil.rl("fog/none.glsl")); - public static final FogShader LINEAR = new SimpleFogShader(ResourceUtil.rl("fog/linear.glsl")); - public static final FogShader LINEAR_FADE = new SimpleFogShader(ResourceUtil.rl("fog/linear_fade.glsl")); + public static final FogShader NONE = new SimpleFogShader(IdentifierUtil.id("fog/none.glsl")); + public static final FogShader LINEAR = new SimpleFogShader(IdentifierUtil.id("fog/linear.glsl")); + public static final FogShader LINEAR_FADE = new SimpleFogShader(IdentifierUtil.id("fog/linear_fade.glsl")); private FogShaders() { } diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/material/LightShaders.java b/common/src/lib/java/dev/engine_room/flywheel/lib/material/LightShaders.java index f9f373d64..b6b315559 100644 --- a/common/src/lib/java/dev/engine_room/flywheel/lib/material/LightShaders.java +++ b/common/src/lib/java/dev/engine_room/flywheel/lib/material/LightShaders.java @@ -1,12 +1,12 @@ package dev.engine_room.flywheel.lib.material; import dev.engine_room.flywheel.api.material.LightShader; -import dev.engine_room.flywheel.lib.util.ResourceUtil; +import dev.engine_room.flywheel.lib.util.IdentifierUtil; public final class LightShaders { - public static final LightShader SMOOTH_WHEN_EMBEDDED = new SimpleLightShader(ResourceUtil.rl("light/smooth_when_embedded.glsl")); - public static final LightShader SMOOTH = new SimpleLightShader(ResourceUtil.rl("light/smooth.glsl")); - public static final LightShader FLAT = new SimpleLightShader(ResourceUtil.rl("light/flat.glsl")); + public static final LightShader SMOOTH_WHEN_EMBEDDED = new SimpleLightShader(IdentifierUtil.id("light/smooth_when_embedded.glsl")); + public static final LightShader SMOOTH = new SimpleLightShader(IdentifierUtil.id("light/smooth.glsl")); + public static final LightShader FLAT = new SimpleLightShader(IdentifierUtil.id("light/flat.glsl")); private LightShaders() { } diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/material/Materials.java b/common/src/lib/java/dev/engine_room/flywheel/lib/material/Materials.java index 932191dd4..2c94ed015 100644 --- a/common/src/lib/java/dev/engine_room/flywheel/lib/material/Materials.java +++ b/common/src/lib/java/dev/engine_room/flywheel/lib/material/Materials.java @@ -5,8 +5,10 @@ import dev.engine_room.flywheel.api.material.Material; import dev.engine_room.flywheel.api.material.Transparency; import dev.engine_room.flywheel.api.material.WriteMask; -import net.minecraft.client.renderer.entity.ItemRenderer; +import net.minecraft.client.renderer.feature.ItemFeatureRenderer; +import net.minecraft.client.renderer.texture.TextureAtlas; +// FIXME 1.21.11: use default blur/mipmap from AbstractTexture for all materials here, and by default public final class Materials { public static final Material SOLID_BLOCK = SimpleMaterial.builder() .build(); @@ -14,22 +16,15 @@ public final class Materials { .cardinalLightingMode(CardinalLightingMode.OFF) .build(); - public static final Material CUTOUT_MIPPED_BLOCK = SimpleMaterial.builder() - .cutout(CutoutShaders.HALF) - .build(); - public static final Material CUTOUT_MIPPED_UNSHADED_BLOCK = SimpleMaterial.builderOf(CUTOUT_MIPPED_BLOCK) - .cardinalLightingMode(CardinalLightingMode.OFF) - .build(); - public static final Material CUTOUT_BLOCK = SimpleMaterial.builder() - .cutout(CutoutShaders.ONE_TENTH) - .mipmap(false) + .cutout(CutoutShaders.HALF) .build(); public static final Material CUTOUT_UNSHADED_BLOCK = SimpleMaterial.builderOf(CUTOUT_BLOCK) .cardinalLightingMode(CardinalLightingMode.OFF) .build(); public static final Material TRANSLUCENT_BLOCK = SimpleMaterial.builder() + .cutout(CutoutShaders.EPSILON) .transparency(Transparency.ORDER_INDEPENDENT) .build(); public static final Material TRANSLUCENT_UNSHADED_BLOCK = SimpleMaterial.builderOf(TRANSLUCENT_BLOCK) @@ -45,24 +40,25 @@ public final class Materials { .build(); public static final Material GLINT = SimpleMaterial.builder() - .texture(ItemRenderer.ENCHANTED_GLINT_ITEM) + .texture(ItemFeatureRenderer.ENCHANTED_GLINT_ITEM) .shaders(StandardMaterialShaders.GLINT) .transparency(Transparency.GLINT) .writeMask(WriteMask.COLOR) .depthTest(DepthTest.EQUAL) .backfaceCulling(false) - .blur(true) - .mipmap(false) .build(); + // FIXME 1.21.11: missing TextureTransform.ENTITY_GLINT_TEXTURING public static final Material GLINT_ENTITY = SimpleMaterial.builderOf(GLINT) - .texture(ItemRenderer.ENCHANTED_GLINT_ENTITY) .build(); - public static final Material TRANSLUCENT_ENTITY = SimpleMaterial.builder() + public static final Material TRANSLUCENT_ITEM_ENTITY_BLOCK = SimpleMaterial.builder() + .transparency(Transparency.TRANSLUCENT) + .build(); + + public static final Material TRANSLUCENT_ITEM_ENTITY_ITEM = SimpleMaterial.builder() + .texture(TextureAtlas.LOCATION_ITEMS) .transparency(Transparency.TRANSLUCENT) - .cutout(CutoutShaders.ONE_TENTH) - .mipmap(false) .build(); private Materials() { diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/material/SimpleCutoutShader.java b/common/src/lib/java/dev/engine_room/flywheel/lib/material/SimpleCutoutShader.java index 0756761da..55f6f44ad 100644 --- a/common/src/lib/java/dev/engine_room/flywheel/lib/material/SimpleCutoutShader.java +++ b/common/src/lib/java/dev/engine_room/flywheel/lib/material/SimpleCutoutShader.java @@ -1,7 +1,7 @@ package dev.engine_room.flywheel.lib.material; import dev.engine_room.flywheel.api.material.CutoutShader; -import net.minecraft.resources.ResourceLocation; +import net.minecraft.resources.Identifier; -public record SimpleCutoutShader(@Override ResourceLocation source) implements CutoutShader { +public record SimpleCutoutShader(@Override Identifier source) implements CutoutShader { } diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/material/SimpleFogShader.java b/common/src/lib/java/dev/engine_room/flywheel/lib/material/SimpleFogShader.java index cc67a8f69..6a38239da 100644 --- a/common/src/lib/java/dev/engine_room/flywheel/lib/material/SimpleFogShader.java +++ b/common/src/lib/java/dev/engine_room/flywheel/lib/material/SimpleFogShader.java @@ -1,7 +1,7 @@ package dev.engine_room.flywheel.lib.material; import dev.engine_room.flywheel.api.material.FogShader; -import net.minecraft.resources.ResourceLocation; +import net.minecraft.resources.Identifier; -public record SimpleFogShader(@Override ResourceLocation source) implements FogShader { +public record SimpleFogShader(@Override Identifier source) implements FogShader { } diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/material/SimpleLightShader.java b/common/src/lib/java/dev/engine_room/flywheel/lib/material/SimpleLightShader.java index 08158e741..b5d002237 100644 --- a/common/src/lib/java/dev/engine_room/flywheel/lib/material/SimpleLightShader.java +++ b/common/src/lib/java/dev/engine_room/flywheel/lib/material/SimpleLightShader.java @@ -1,7 +1,7 @@ package dev.engine_room.flywheel.lib.material; import dev.engine_room.flywheel.api.material.LightShader; -import net.minecraft.resources.ResourceLocation; +import net.minecraft.resources.Identifier; -public record SimpleLightShader(@Override ResourceLocation source) implements LightShader { +public record SimpleLightShader(@Override Identifier source) implements LightShader { } diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/material/SimpleMaterial.java b/common/src/lib/java/dev/engine_room/flywheel/lib/material/SimpleMaterial.java index 46aab259b..f7edd55aa 100644 --- a/common/src/lib/java/dev/engine_room/flywheel/lib/material/SimpleMaterial.java +++ b/common/src/lib/java/dev/engine_room/flywheel/lib/material/SimpleMaterial.java @@ -9,8 +9,8 @@ import dev.engine_room.flywheel.api.material.MaterialShaders; import dev.engine_room.flywheel.api.material.Transparency; import dev.engine_room.flywheel.api.material.WriteMask; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.inventory.InventoryMenu; +import net.minecraft.client.renderer.texture.TextureAtlas; +import net.minecraft.resources.Identifier; public class SimpleMaterial implements Material { protected final MaterialShaders shaders; @@ -18,7 +18,7 @@ public class SimpleMaterial implements Material { protected final CutoutShader cutout; protected final LightShader light; - protected final ResourceLocation texture; + protected final Identifier texture; protected final boolean blur; protected final boolean mipmap; @@ -82,7 +82,7 @@ public LightShader light() { } @Override - public ResourceLocation texture() { + public Identifier texture() { return texture; } @@ -147,7 +147,7 @@ public static class Builder implements Material { protected CutoutShader cutout; protected LightShader light; - protected ResourceLocation texture; + protected Identifier texture; protected boolean blur; protected boolean mipmap; @@ -168,7 +168,7 @@ public Builder() { fog = FogShaders.LINEAR; cutout = CutoutShaders.OFF; light = LightShaders.SMOOTH_WHEN_EMBEDDED; - texture = InventoryMenu.BLOCK_ATLAS; + texture = TextureAtlas.LOCATION_BLOCKS; blur = false; mipmap = true; backfaceCulling = true; @@ -226,7 +226,7 @@ public Builder light(LightShader value) { return this; } - public Builder texture(ResourceLocation value) { + public Builder texture(Identifier value) { this.texture = value; return this; } @@ -315,7 +315,7 @@ public LightShader light() { } @Override - public ResourceLocation texture() { + public Identifier texture() { return texture; } diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/material/SimpleMaterialShaders.java b/common/src/lib/java/dev/engine_room/flywheel/lib/material/SimpleMaterialShaders.java index f39c1f4ea..892dfa132 100644 --- a/common/src/lib/java/dev/engine_room/flywheel/lib/material/SimpleMaterialShaders.java +++ b/common/src/lib/java/dev/engine_room/flywheel/lib/material/SimpleMaterialShaders.java @@ -1,7 +1,7 @@ package dev.engine_room.flywheel.lib.material; import dev.engine_room.flywheel.api.material.MaterialShaders; -import net.minecraft.resources.ResourceLocation; +import net.minecraft.resources.Identifier; -public record SimpleMaterialShaders(ResourceLocation vertexSource, ResourceLocation fragmentSource) implements MaterialShaders { +public record SimpleMaterialShaders(Identifier vertexSource, Identifier fragmentSource) implements MaterialShaders { } diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/material/StandardMaterialShaders.java b/common/src/lib/java/dev/engine_room/flywheel/lib/material/StandardMaterialShaders.java index 6892adb00..b192b0e87 100644 --- a/common/src/lib/java/dev/engine_room/flywheel/lib/material/StandardMaterialShaders.java +++ b/common/src/lib/java/dev/engine_room/flywheel/lib/material/StandardMaterialShaders.java @@ -1,17 +1,17 @@ package dev.engine_room.flywheel.lib.material; import dev.engine_room.flywheel.api.material.MaterialShaders; -import dev.engine_room.flywheel.lib.util.ResourceUtil; +import dev.engine_room.flywheel.lib.util.IdentifierUtil; public final class StandardMaterialShaders { public static final MaterialShaders DEFAULT = new SimpleMaterialShaders( - ResourceUtil.rl("material/default.vert"), ResourceUtil.rl("material/default.frag")); + IdentifierUtil.id("material/default.vert"), IdentifierUtil.id("material/default.frag")); - public static final MaterialShaders WIREFRAME = new SimpleMaterialShaders(ResourceUtil.rl("material/wireframe.vert"), ResourceUtil.rl("material/wireframe.frag")); + public static final MaterialShaders WIREFRAME = new SimpleMaterialShaders(IdentifierUtil.id("material/wireframe.vert"), IdentifierUtil.id("material/wireframe.frag")); - public static final MaterialShaders LINE = new SimpleMaterialShaders(ResourceUtil.rl("material/lines.vert"), ResourceUtil.rl("material/lines.frag")); + public static final MaterialShaders LINE = new SimpleMaterialShaders(IdentifierUtil.id("material/lines.vert"), IdentifierUtil.id("material/lines.frag")); - public static final MaterialShaders GLINT = new SimpleMaterialShaders(ResourceUtil.rl("material/glint.vert"), ResourceUtil.rl("material/default.frag")); + public static final MaterialShaders GLINT = new SimpleMaterialShaders(IdentifierUtil.id("material/glint.vert"), IdentifierUtil.id("material/default.frag")); private StandardMaterialShaders() { } diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/model/LineModelBuilder.java b/common/src/lib/java/dev/engine_room/flywheel/lib/model/LineModelBuilder.java index 1012ae04f..17eac0047 100644 --- a/common/src/lib/java/dev/engine_room/flywheel/lib/model/LineModelBuilder.java +++ b/common/src/lib/java/dev/engine_room/flywheel/lib/model/LineModelBuilder.java @@ -16,8 +16,8 @@ import dev.engine_room.flywheel.lib.memory.MemoryBlock; import dev.engine_room.flywheel.lib.vertex.FullVertexView; import dev.engine_room.flywheel.lib.vertex.VertexView; -import net.minecraft.client.renderer.LightTexture; import net.minecraft.client.renderer.texture.OverlayTexture; +import net.minecraft.util.LightCoordsUtil; public final class LineModelBuilder { private static final Material MATERIAL = SimpleMaterial.builder() @@ -91,7 +91,7 @@ public LineModelBuilder line(float x1, float y1, float z1, float x2, float y2, f vertexView.u(vertexCount + i, 0); vertexView.v(vertexCount + i, 0); vertexView.overlay(vertexCount + i, OverlayTexture.NO_OVERLAY); - vertexView.light(vertexCount + i, LightTexture.FULL_BRIGHT); + vertexView.light(vertexCount + i, LightCoordsUtil.FULL_BRIGHT); vertexView.normalX(vertexCount + i, normalX); vertexView.normalY(vertexCount + i, normalY); vertexView.normalZ(vertexCount + i, normalZ); diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/model/ModelUtil.java b/common/src/lib/java/dev/engine_room/flywheel/lib/model/ModelUtil.java index 0c8d54e72..7260cad9f 100644 --- a/common/src/lib/java/dev/engine_room/flywheel/lib/model/ModelUtil.java +++ b/common/src/lib/java/dev/engine_room/flywheel/lib/model/ModelUtil.java @@ -2,9 +2,9 @@ import java.util.Collection; -import org.jetbrains.annotations.Nullable; import org.joml.Vector3f; import org.joml.Vector4f; +import org.jspecify.annotations.Nullable; import dev.engine_room.flywheel.api.material.CardinalLightingMode; import dev.engine_room.flywheel.api.material.Material; @@ -15,20 +15,22 @@ import dev.engine_room.flywheel.lib.material.SimpleMaterial; import dev.engine_room.flywheel.lib.memory.MemoryBlock; import dev.engine_room.flywheel.lib.vertex.PosVertexView; -import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.Sheets; +import net.minecraft.client.renderer.chunk.ChunkSectionLayer; +import net.minecraft.client.renderer.rendertype.RenderType; +import net.minecraft.client.renderer.rendertype.RenderTypes; public final class ModelUtil { private static final float BOUNDING_SPHERE_EPSILON = 1e-4f; - private static final RenderType[] CHUNK_LAYERS = new RenderType[]{RenderType.solid(), RenderType.cutoutMipped(), RenderType.cutout(), RenderType.translucent(), RenderType.tripwire()}; + private static final ChunkSectionLayer[] CHUNK_LAYERS = ChunkSectionLayer.values(); // Array of chunk materials to make lookups easier. // Index by (renderTypeIdx * 4 + shaded * 2 + ambientOcclusion). - private static final Material[] CHUNK_MATERIALS = new Material[20]; + private static final Material[] CHUNK_MATERIALS = new Material[16]; static { - Material[] baseChunkMaterials = new Material[]{Materials.SOLID_BLOCK, Materials.CUTOUT_MIPPED_BLOCK, Materials.CUTOUT_BLOCK, Materials.TRANSLUCENT_BLOCK, Materials.TRIPWIRE_BLOCK,}; + Material[] baseChunkMaterials = new Material[]{Materials.SOLID_BLOCK, Materials.CUTOUT_BLOCK, Materials.TRANSLUCENT_BLOCK, Materials.TRIPWIRE_BLOCK,}; for (int chunkLayerIdx = 0; chunkLayerIdx < CHUNK_LAYERS.length; chunkLayerIdx++) { int baseMaterialIdx = chunkLayerIdx * 4; Material baseChunkMaterial = baseChunkMaterials[chunkLayerIdx]; @@ -55,14 +57,14 @@ private ModelUtil() { } @Nullable - public static Material getMaterial(RenderType chunkRenderType, boolean shaded) { - return getMaterial(chunkRenderType, shaded, true); + public static Material getMaterial(ChunkSectionLayer chunkSectionLayer, boolean shaded) { + return getMaterial(chunkSectionLayer, shaded, true); } @Nullable - public static Material getMaterial(RenderType chunkRenderType, boolean shaded, boolean ambientOcclusion) { + public static Material getMaterial(ChunkSectionLayer chunkSectionLayer, boolean shaded, boolean ambientOcclusion) { for (int chunkLayerIdx = 0; chunkLayerIdx < CHUNK_LAYERS.length; ++chunkLayerIdx) { - if (chunkRenderType == CHUNK_LAYERS[chunkLayerIdx]) { + if (chunkSectionLayer == CHUNK_LAYERS[chunkLayerIdx]) { int shadedIdx = shaded ? 1 : 0; int ambientOcclusionIdx = ambientOcclusion ? 1 : 0; @@ -76,28 +78,22 @@ public static Material getMaterial(RenderType chunkRenderType, boolean shaded, b @Nullable public static Material getItemMaterial(RenderType renderType) { - var chunkMaterial = getMaterial(renderType, true, false); - - if (chunkMaterial != null) { - return chunkMaterial; - } - if (renderType == Sheets.cutoutBlockSheet()) { return Materials.CUTOUT_BLOCK; } - if (renderType == Sheets.solidBlockSheet()) { - return Materials.SOLID_BLOCK; + if (renderType == Sheets.translucentBlockItemSheet()) { + return Materials.TRANSLUCENT_ITEM_ENTITY_BLOCK; } - if (renderType == Sheets.translucentCullBlockSheet() || renderType == Sheets.translucentItemSheet()) { - return Materials.TRANSLUCENT_ENTITY; + if (renderType == Sheets.translucentItemSheet()) { + return Materials.TRANSLUCENT_ITEM_ENTITY_ITEM; } - if (renderType == RenderType.glint() || renderType == RenderType.glintTranslucent()) { + if (renderType == RenderTypes.glint() || renderType == RenderTypes.glintTranslucent()) { return Materials.GLINT; } - if (renderType == RenderType.entityGlint() || renderType == RenderType.entityGlintDirect()) { + if (renderType == RenderTypes.entityGlint()) { return Materials.GLINT_ENTITY; } return null; diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/model/Models.java b/common/src/lib/java/dev/engine_room/flywheel/lib/model/Models.java index 80948eaef..b6f8d6b7d 100644 --- a/common/src/lib/java/dev/engine_room/flywheel/lib/model/Models.java +++ b/common/src/lib/java/dev/engine_room/flywheel/lib/model/Models.java @@ -6,8 +6,8 @@ import com.mojang.blaze3d.vertex.PoseStack; import dev.engine_room.flywheel.api.model.Model; -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.LevelModelBuilder; import dev.engine_room.flywheel.lib.model.baked.PartialModel; import dev.engine_room.flywheel.lib.model.baked.SinglePosVirtualBlockGetter; import dev.engine_room.flywheel.lib.transform.TransformStack; @@ -23,10 +23,10 @@ * method with the same parameters will return the same object. */ public final class Models { - private static final RendererReloadCache BLOCK_STATE = new RendererReloadCache<>(it -> new BlockModelBuilder(SinglePosVirtualBlockGetter.createFullDark() + private static final RendererReloadCache BLOCK_STATE = new RendererReloadCache<>(it -> new LevelModelBuilder(SinglePosVirtualBlockGetter.createFullDark() .blockState(it), List.of(BlockPos.ZERO)) .build()); - private static final RendererReloadCache PARTIAL = new RendererReloadCache<>(it -> new BakedModelBuilder(it.get()) + private static final RendererReloadCache PARTIAL = new RendererReloadCache<>(it -> new BlockModelBuilder(it.get()) .build()); private static final RendererReloadCache, Model> TRANSFORMED_PARTIAL = new RendererReloadCache<>(TransformedPartial::create); @@ -92,7 +92,7 @@ private record TransformedPartial(PartialModel partial, T key, BiConsumer materialFunc) { - if (materialFunc != null) { - this.materialFunc = (chunkRenderType, shaded, ambientOcclusion) -> materialFunc.apply(chunkRenderType, shaded); - } else { - this.materialFunc = null; - } - return this; - } - - public BakedModelBuilder materialFunc(@Nullable BlockMaterialFunction materialFunc) { - this.materialFunc = materialFunc; - return this; - } - - public SimpleModel build() { - if (level == null) { - level = EmptyVirtualBlockGetter.FULL_DARK; - } - if (pos == null) { - pos = BlockPos.ZERO; - } - if (materialFunc == null) { - materialFunc = ModelUtil::getMaterial; - } - - return FlwLibXplat.INSTANCE.buildBakedModelBuilder(this); - } -} diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/model/baked/BlockMaterialFunction.java b/common/src/lib/java/dev/engine_room/flywheel/lib/model/baked/BlockMaterialFunction.java index c8b177ec8..a99c3dec7 100644 --- a/common/src/lib/java/dev/engine_room/flywheel/lib/model/baked/BlockMaterialFunction.java +++ b/common/src/lib/java/dev/engine_room/flywheel/lib/model/baked/BlockMaterialFunction.java @@ -1,11 +1,11 @@ package dev.engine_room.flywheel.lib.model.baked; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import dev.engine_room.flywheel.api.material.Material; -import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.chunk.ChunkSectionLayer; public interface BlockMaterialFunction { @Nullable - Material apply(RenderType chunkRenderType, boolean shaded, boolean ambientOcclusion); + Material apply(ChunkSectionLayer chunkSectionLayer, boolean shaded, boolean ambientOcclusion); } diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/model/baked/BlockModelBuilder.java b/common/src/lib/java/dev/engine_room/flywheel/lib/model/baked/BlockModelBuilder.java index a1cb7450a..8532fa0fb 100644 --- a/common/src/lib/java/dev/engine_room/flywheel/lib/model/baked/BlockModelBuilder.java +++ b/common/src/lib/java/dev/engine_room/flywheel/lib/model/baked/BlockModelBuilder.java @@ -2,7 +2,7 @@ import java.util.function.BiFunction; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import com.mojang.blaze3d.vertex.PoseStack; @@ -10,38 +10,45 @@ import dev.engine_room.flywheel.lib.internal.FlwLibXplat; import dev.engine_room.flywheel.lib.model.ModelUtil; import dev.engine_room.flywheel.lib.model.SimpleModel; -import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.block.BlockAndTintGetter; +import net.minecraft.client.renderer.block.dispatch.BlockStateModel; +import net.minecraft.client.renderer.chunk.ChunkSectionLayer; import net.minecraft.core.BlockPos; -import net.minecraft.world.level.BlockAndTintGetter; public final class BlockModelBuilder { - final BlockAndTintGetter level; - final Iterable positions; + final BlockStateModel blockModel; + @Nullable + BlockAndTintGetter level; + @Nullable + BlockPos pos; @Nullable PoseStack poseStack; - boolean renderFluids = false; @Nullable BlockMaterialFunction materialFunc; - public BlockModelBuilder(BlockAndTintGetter level, Iterable positions) { + public BlockModelBuilder(BlockStateModel blockModel) { + this.blockModel = blockModel; + } + + public BlockModelBuilder level(@Nullable BlockAndTintGetter level) { this.level = level; - this.positions = positions; + return this; } - public BlockModelBuilder poseStack(@Nullable PoseStack poseStack) { - this.poseStack = poseStack; + public BlockModelBuilder pos(@Nullable BlockPos pos) { + this.pos = pos; return this; } - public BlockModelBuilder renderFluids(boolean renderFluids) { - this.renderFluids = renderFluids; + public BlockModelBuilder poseStack(@Nullable PoseStack poseStack) { + this.poseStack = poseStack; return this; } @Deprecated(forRemoval = true) - public BlockModelBuilder materialFunc(@Nullable BiFunction materialFunc) { + public BlockModelBuilder materialFunc(@Nullable BiFunction materialFunc) { if (materialFunc != null) { - this.materialFunc = (chunkRenderType, shaded, ambientOcclusion) -> materialFunc.apply(chunkRenderType, shaded); + this.materialFunc = (chunkSectionLayer, shaded, ambientOcclusion) -> materialFunc.apply(chunkSectionLayer, shaded); } else { this.materialFunc = null; } @@ -54,6 +61,12 @@ public BlockModelBuilder materialFunc(@Nullable BlockMaterialFunction materialFu } public SimpleModel build() { + if (level == null) { + level = EmptyVirtualBlockGetter.FULL_DARK; + } + if (pos == null) { + pos = BlockPos.ZERO; + } if (materialFunc == null) { materialFunc = ModelUtil::getMaterial; } diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/model/baked/EmptyVertexConsumer.java b/common/src/lib/java/dev/engine_room/flywheel/lib/model/baked/EmptyVertexConsumer.java new file mode 100644 index 000000000..1901069f8 --- /dev/null +++ b/common/src/lib/java/dev/engine_room/flywheel/lib/model/baked/EmptyVertexConsumer.java @@ -0,0 +1,49 @@ +package dev.engine_room.flywheel.lib.model.baked; + +import com.mojang.blaze3d.vertex.VertexConsumer; + +public class EmptyVertexConsumer implements VertexConsumer { + public static final EmptyVertexConsumer INSTANCE = new EmptyVertexConsumer(); + + private EmptyVertexConsumer() {} + + @Override + public VertexConsumer addVertex(float x, float y, float z) { + return this; + } + + @Override + public VertexConsumer setColor(int r, int g, int b, int a) { + return this; + } + + @Override + public VertexConsumer setColor(int color) { + return this; + } + + @Override + public VertexConsumer setUv(float u, float v) { + return this; + } + + @Override + public VertexConsumer setUv1(int u, int v) { + return this; + } + + @Override + public VertexConsumer setUv2(int u, int v) { + return this; + } + + @Override + public VertexConsumer setNormal(float x, float y, float z) { + return this; + } + + @Override + public VertexConsumer setLineWidth(float width) { + return this; + } +} diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/model/baked/EmptyVirtualBlockGetter.java b/common/src/lib/java/dev/engine_room/flywheel/lib/model/baked/EmptyVirtualBlockGetter.java index a5439444d..1bd6829c4 100644 --- a/common/src/lib/java/dev/engine_room/flywheel/lib/model/baked/EmptyVirtualBlockGetter.java +++ b/common/src/lib/java/dev/engine_room/flywheel/lib/model/baked/EmptyVirtualBlockGetter.java @@ -2,7 +2,7 @@ import java.util.function.ToIntFunction; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import net.minecraft.core.BlockPos; import net.minecraft.world.level.block.Blocks; @@ -41,7 +41,7 @@ public final int getHeight() { } @Override - public final int getMinBuildHeight() { + public final int getMinY() { return 0; } } diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/model/baked/LevelModelBuilder.java b/common/src/lib/java/dev/engine_room/flywheel/lib/model/baked/LevelModelBuilder.java new file mode 100644 index 000000000..1aa716adc --- /dev/null +++ b/common/src/lib/java/dev/engine_room/flywheel/lib/model/baked/LevelModelBuilder.java @@ -0,0 +1,63 @@ +package dev.engine_room.flywheel.lib.model.baked; + +import java.util.function.BiFunction; + +import org.jspecify.annotations.Nullable; + +import com.mojang.blaze3d.vertex.PoseStack; + +import dev.engine_room.flywheel.api.material.Material; +import dev.engine_room.flywheel.lib.internal.FlwLibXplat; +import dev.engine_room.flywheel.lib.model.ModelUtil; +import dev.engine_room.flywheel.lib.model.SimpleModel; +import net.minecraft.client.renderer.block.BlockAndTintGetter; +import net.minecraft.client.renderer.chunk.ChunkSectionLayer; +import net.minecraft.core.BlockPos; + +public final class LevelModelBuilder { + final BlockAndTintGetter level; + final Iterable positions; + @Nullable + PoseStack poseStack; + boolean renderFluids = false; + @Nullable + BlockMaterialFunction materialFunc; + + public LevelModelBuilder(BlockAndTintGetter level, Iterable positions) { + this.level = level; + this.positions = positions; + } + + public LevelModelBuilder poseStack(@Nullable PoseStack poseStack) { + this.poseStack = poseStack; + return this; + } + + public LevelModelBuilder renderFluids(boolean renderFluids) { + this.renderFluids = renderFluids; + return this; + } + + @Deprecated(forRemoval = true) + public LevelModelBuilder materialFunc(@Nullable BiFunction materialFunc) { + if (materialFunc != null) { + this.materialFunc = (chunkSectionLayer, shaded, ambientOcclusion) -> materialFunc.apply(chunkSectionLayer, shaded); + } else { + this.materialFunc = null; + } + return this; + } + + public LevelModelBuilder materialFunc(@Nullable BlockMaterialFunction materialFunc) { + this.materialFunc = materialFunc; + return this; + } + + public SimpleModel build() { + if (materialFunc == null) { + materialFunc = ModelUtil::getMaterial; + } + + return FlwLibXplat.INSTANCE.buildLevelModelBuilder(this); + } +} diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/model/baked/MeshEmitter.java b/common/src/lib/java/dev/engine_room/flywheel/lib/model/baked/MeshEmitter.java index dc74794fa..00334e84e 100644 --- a/common/src/lib/java/dev/engine_room/flywheel/lib/model/baked/MeshEmitter.java +++ b/common/src/lib/java/dev/engine_room/flywheel/lib/model/baked/MeshEmitter.java @@ -2,22 +2,28 @@ import java.util.Arrays; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.UnknownNullability; +import org.jspecify.annotations.Nullable; import com.google.common.collect.ImmutableList; import com.mojang.blaze3d.vertex.BufferBuilder; import com.mojang.blaze3d.vertex.ByteBufferBuilder; +import com.mojang.blaze3d.vertex.VertexConsumer; +import com.mojang.blaze3d.vertex.VertexFormat.Mode; import dev.engine_room.flywheel.api.material.Material; import dev.engine_room.flywheel.api.model.Mesh; import dev.engine_room.flywheel.api.model.Model; -import net.minecraft.client.renderer.RenderType; +import dev.engine_room.flywheel.lib.vertex.FlywheelVertexFormats; +import net.minecraft.client.renderer.chunk.ChunkSectionLayer; -class MeshEmitter { +@ApiStatus.Internal +public abstract class MeshEmitter implements VertexConsumer { private static final int INITIAL_CAPACITY = 1; private final ByteBufferBuilderStack byteBufferBuilderStack; - private final RenderType renderType; + private final ChunkSectionLayer chunkSectionLayer; private Material @UnknownNullability [] materials = new Material[INITIAL_CAPACITY]; private BufferBuilder @UnknownNullability [] bufferBuilders = new BufferBuilder[INITIAL_CAPACITY]; @@ -30,9 +36,9 @@ class MeshEmitter { private int currentIndex = 0; - MeshEmitter(ByteBufferBuilderStack byteBufferBuilderStack, RenderType renderType) { + MeshEmitter(ByteBufferBuilderStack byteBufferBuilderStack, ChunkSectionLayer chunkSectionLayer) { this.byteBufferBuilderStack = byteBufferBuilderStack; - this.renderType = renderType; + this.chunkSectionLayer = chunkSectionLayer; } public void prepare(BlockMaterialFunction blockMaterialFunction) { @@ -88,9 +94,7 @@ public BufferBuilder getBuffer(Material material) { } ByteBufferBuilder byteBufferBuilder = byteBufferBuilderStack.nextOrCreate(); - - // Trust that the RenderType mode/format don't change out from underneath us. - BufferBuilder bufferBuilder = new BufferBuilder(byteBufferBuilder, renderType.mode(), renderType.format()); + BufferBuilder bufferBuilder = new BufferBuilder(byteBufferBuilder, Mode.QUADS, FlywheelVertexFormats.BLOCK_VERTEX_FORMAT); // currentIndex == numBufferBuildersPopulated here. materials[currentIndex] = material; @@ -103,6 +107,17 @@ public BufferBuilder getBuffer(Material material) { return bufferBuilder; } + // TODO 1.21.11: cache the last used buffer? + @Nullable + public BufferBuilder getBuffer(boolean shade, boolean ao) { + Material key = blockMaterialFunction.apply(chunkSectionLayer, shade, ao); + if (key != null) { + return getBuffer(key); + } else { + return null; + } + } + private void resize(int capacity) { BufferBuilder[] newBufferBuilders = new BufferBuilder[capacity]; Material[] newMaterials = new Material[capacity]; diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/model/baked/MeshEmitterManager.java b/common/src/lib/java/dev/engine_room/flywheel/lib/model/baked/MeshEmitterManager.java index 032497cd9..3dcb8d95e 100644 --- a/common/src/lib/java/dev/engine_room/flywheel/lib/model/baked/MeshEmitterManager.java +++ b/common/src/lib/java/dev/engine_room/flywheel/lib/model/baked/MeshEmitterManager.java @@ -2,40 +2,34 @@ import java.util.function.BiFunction; -import org.jetbrains.annotations.Nullable; -import org.jetbrains.annotations.UnknownNullability; - import com.google.common.collect.ImmutableList; -import com.mojang.blaze3d.vertex.BufferBuilder; -import dev.engine_room.flywheel.api.material.Material; import dev.engine_room.flywheel.api.model.Model; import dev.engine_room.flywheel.lib.model.SimpleModel; import it.unimi.dsi.fastutil.objects.Reference2ReferenceArrayMap; import it.unimi.dsi.fastutil.objects.Reference2ReferenceMap; -import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.chunk.ChunkSectionLayer; -class MeshEmitterManager { - private static final RenderType[] CHUNK_LAYERS = RenderType.chunkBufferLayers().toArray(RenderType[]::new); +import org.jetbrains.annotations.ApiStatus; - private final Reference2ReferenceMap emitterMap = new Reference2ReferenceArrayMap<>(); - private final ByteBufferBuilderStack byteBufferBuilderStack = new ByteBufferBuilderStack(); +@ApiStatus.Internal +public class MeshEmitterManager { + private static final ChunkSectionLayer[] CHUNK_LAYERS = ChunkSectionLayer.values(); - @UnknownNullability - private BlockMaterialFunction blockMaterialFunction; + final Reference2ReferenceMap emitterMap = new Reference2ReferenceArrayMap<>(); + private final ByteBufferBuilderStack byteBufferBuilderStack = new ByteBufferBuilderStack(); - MeshEmitterManager(BiFunction meshEmitterFactory) { - for (RenderType renderType : CHUNK_LAYERS) { - emitterMap.put(renderType, meshEmitterFactory.apply(byteBufferBuilderStack, renderType)); + MeshEmitterManager(BiFunction meshEmitterFactory) { + for (ChunkSectionLayer chunkSectionLayer : CHUNK_LAYERS) { + emitterMap.put(chunkSectionLayer, meshEmitterFactory.apply(byteBufferBuilderStack, chunkSectionLayer)); } } - public T getEmitter(RenderType renderType) { - return emitterMap.get(renderType); + public T getEmitter(ChunkSectionLayer chunkSectionLayer) { + return emitterMap.get(chunkSectionLayer); } public void prepare(BlockMaterialFunction blockMaterialFunction) { - this.blockMaterialFunction = blockMaterialFunction; byteBufferBuilderStack.reset(); for (MeshEmitter emitter : emitterMap.values()) { @@ -50,8 +44,6 @@ public void prepareForBlock() { } public SimpleModel end() { - blockMaterialFunction = null; - ImmutableList.Builder meshes = ImmutableList.builder(); for (MeshEmitter emitter : emitterMap.values()) { @@ -60,14 +52,4 @@ public SimpleModel end() { return new SimpleModel(meshes.build()); } - - @Nullable - public BufferBuilder getBuffer(RenderType renderType, boolean shade, boolean ao) { - Material key = blockMaterialFunction.apply(renderType, shade, ao); - if (key != null) { - return emitterMap.get(renderType).getBuffer(key); - } else { - return null; - } - } } diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/model/baked/MeshHelper.java b/common/src/lib/java/dev/engine_room/flywheel/lib/model/baked/MeshHelper.java index c0191fc4c..093fdd332 100644 --- a/common/src/lib/java/dev/engine_room/flywheel/lib/model/baked/MeshHelper.java +++ b/common/src/lib/java/dev/engine_room/flywheel/lib/model/baked/MeshHelper.java @@ -2,7 +2,7 @@ import java.nio.ByteBuffer; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import org.lwjgl.system.MemoryUtil; import com.mojang.blaze3d.vertex.MeshData; diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/model/baked/PartialModel.java b/common/src/lib/java/dev/engine_room/flywheel/lib/model/baked/PartialModel.java index 0b80329e9..68c30a8d6 100644 --- a/common/src/lib/java/dev/engine_room/flywheel/lib/model/baked/PartialModel.java +++ b/common/src/lib/java/dev/engine_room/flywheel/lib/model/baked/PartialModel.java @@ -1,49 +1,42 @@ package dev.engine_room.flywheel.lib.model.baked; -import java.util.concurrent.ConcurrentMap; - +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.UnknownNullability; -import com.google.common.collect.MapMaker; - import dev.engine_room.flywheel.lib.internal.FlwLibXplat; -import net.minecraft.client.Minecraft; -import net.minecraft.client.resources.model.BakedModel; -import net.minecraft.resources.ResourceLocation; +import net.minecraft.client.renderer.block.dispatch.BlockStateModel; +import net.minecraft.client.resources.model.SimpleModelWrapper; +import net.minecraft.resources.Identifier; /** * A helper class for loading and accessing JSON models not directly used by any blocks or items. - *
- * Creating a PartialModel will make Minecraft automatically load the associated modelLocation. - *
- * Once Minecraft has finished baking all models, all PartialModels will have their bakedModel fields populated. + * + *

Creating a PartialModel will make Minecraft automatically load the associated modelId and bake the model as a + * {@link SimpleModelWrapper}. + * + *

Once Minecraft has finished baking all models, all PartialModels will have their blockStateModel fields populated. + * Newly created PartialModels will contain a null model until the next resource reload is finished. */ -public final class PartialModel { - static final ConcurrentMap ALL = new MapMaker().weakValues().makeMap(); - static boolean populateOnInit = false; - - private final ResourceLocation modelLocation; +@ApiStatus.NonExtendable +public class PartialModel { + final Identifier modelId; @UnknownNullability - BakedModel bakedModel; - - private PartialModel(ResourceLocation modelLocation) { - this.modelLocation = modelLocation; + BlockStateModel blockStateModel; - if (populateOnInit) { - bakedModel = FlwLibXplat.INSTANCE.getBakedModel(Minecraft.getInstance().getModelManager(), modelLocation); - } + PartialModel(Identifier modelId) { + this.modelId = modelId; } - public static PartialModel of(ResourceLocation modelLocation) { - return ALL.computeIfAbsent(modelLocation, PartialModel::new); + public static PartialModel of(Identifier modelId) { + return FlwLibXplat.INSTANCE.createPartialModel(modelId); } @UnknownNullability - public BakedModel get() { - return bakedModel; + public BlockStateModel get() { + return blockStateModel; } - public ResourceLocation modelLocation() { - return modelLocation; + public Identifier modelId() { + return modelId; } } diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/model/baked/SinglePosVirtualBlockGetter.java b/common/src/lib/java/dev/engine_room/flywheel/lib/model/baked/SinglePosVirtualBlockGetter.java index 21d248724..729ad5565 100644 --- a/common/src/lib/java/dev/engine_room/flywheel/lib/model/baked/SinglePosVirtualBlockGetter.java +++ b/common/src/lib/java/dev/engine_room/flywheel/lib/model/baked/SinglePosVirtualBlockGetter.java @@ -2,7 +2,7 @@ import java.util.function.ToIntFunction; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import net.minecraft.core.BlockPos; import net.minecraft.world.level.block.Blocks; @@ -67,7 +67,7 @@ public int getHeight() { } @Override - public int getMinBuildHeight() { + public int getMinY() { return pos.getY(); } } diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/model/baked/TransformingVertexConsumer.java b/common/src/lib/java/dev/engine_room/flywheel/lib/model/baked/TransformingVertexConsumer.java index 0e8b91380..d8af3dea1 100644 --- a/common/src/lib/java/dev/engine_room/flywheel/lib/model/baked/TransformingVertexConsumer.java +++ b/common/src/lib/java/dev/engine_room/flywheel/lib/model/baked/TransformingVertexConsumer.java @@ -41,6 +41,12 @@ public VertexConsumer setColor(int red, int green, int blue, int alpha) { return this; } + @Override + public VertexConsumer setColor(int color) { + delegate.setColor(color); + return this; + } + @Override public VertexConsumer setUv(float u, float v) { delegate.setUv(u, v); @@ -68,4 +74,10 @@ public VertexConsumer setNormal(float x, float y, float z) { MatrixMath.transformNormalZ(matrix, x, y, z)); return this; } + + @Override + public VertexConsumer setLineWidth(float width) { + delegate.setLineWidth(width); + return this; + } } diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/model/baked/VirtualBlockGetter.java b/common/src/lib/java/dev/engine_room/flywheel/lib/model/baked/VirtualBlockGetter.java index 1b5782d43..42077bb04 100644 --- a/common/src/lib/java/dev/engine_room/flywheel/lib/model/baked/VirtualBlockGetter.java +++ b/common/src/lib/java/dev/engine_room/flywheel/lib/model/baked/VirtualBlockGetter.java @@ -3,10 +3,10 @@ import java.util.function.ToIntFunction; import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.block.BlockAndTintGetter; import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; import net.minecraft.core.registries.Registries; -import net.minecraft.world.level.BlockAndTintGetter; +import net.minecraft.world.level.CardinalLighting; import net.minecraft.world.level.ColorResolver; import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.biome.Biomes; @@ -26,8 +26,8 @@ public FluidState getFluidState(BlockPos pos) { } @Override - public float getShade(Direction direction, boolean shaded) { - return 1f; + public CardinalLighting cardinalLighting() { + return CardinalLighting.DEFAULT; } @Override @@ -37,7 +37,7 @@ public LevelLightEngine getLightEngine() { @Override public int getBlockTint(BlockPos pos, ColorResolver resolver) { - Biome plainsBiome = Minecraft.getInstance().getConnection().registryAccess().registryOrThrow(Registries.BIOME).getOrThrow(Biomes.PLAINS); + Biome plainsBiome = Minecraft.getInstance().getConnection().registryAccess().lookupOrThrow(Registries.BIOME).getValueOrThrow(Biomes.PLAINS); return resolver.getColor(plainsBiome, pos.getX(), pos.getZ()); } } diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/model/baked/VirtualLightEngine.java b/common/src/lib/java/dev/engine_room/flywheel/lib/model/baked/VirtualLightEngine.java index e8b072384..cbb50b53d 100644 --- a/common/src/lib/java/dev/engine_room/flywheel/lib/model/baked/VirtualLightEngine.java +++ b/common/src/lib/java/dev/engine_room/flywheel/lib/model/baked/VirtualLightEngine.java @@ -2,7 +2,7 @@ import java.util.function.ToIntFunction; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import net.minecraft.core.BlockPos; import net.minecraft.core.SectionPos; diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/model/part/InstanceTree.java b/common/src/lib/java/dev/engine_room/flywheel/lib/model/part/InstanceTree.java index 87776ec0b..09d73b94f 100644 --- a/common/src/lib/java/dev/engine_room/flywheel/lib/model/part/InstanceTree.java +++ b/common/src/lib/java/dev/engine_room/flywheel/lib/model/part/InstanceTree.java @@ -5,7 +5,7 @@ import java.util.function.ObjIntConsumer; import org.jetbrains.annotations.ApiStatus; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import org.joml.Matrix4f; import org.joml.Matrix4fc; import org.joml.Quaternionf; @@ -460,12 +460,12 @@ public PartPose storePose() { } public void loadPose(PartPose pose) { - x = pose.x; - y = pose.y; - z = pose.z; - xRot = pose.xRot; - yRot = pose.yRot; - zRot = pose.zRot; + x = pose.x(); + y = pose.y(); + z = pose.z(); + xRot = pose.xRot(); + yRot = pose.yRot(); + zRot = pose.zRot(); xScale = ModelPart.DEFAULT_SCALE; yScale = ModelPart.DEFAULT_SCALE; zScale = ModelPart.DEFAULT_SCALE; diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/model/part/MeshTree.java b/common/src/lib/java/dev/engine_room/flywheel/lib/model/part/MeshTree.java index 3575a4386..e60cc942f 100644 --- a/common/src/lib/java/dev/engine_room/flywheel/lib/model/part/MeshTree.java +++ b/common/src/lib/java/dev/engine_room/flywheel/lib/model/part/MeshTree.java @@ -3,7 +3,7 @@ import java.util.Arrays; import java.util.NoSuchElementException; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import com.mojang.blaze3d.vertex.PoseStack; @@ -19,8 +19,8 @@ import net.minecraft.client.model.geom.ModelLayerLocation; import net.minecraft.client.model.geom.ModelPart; import net.minecraft.client.model.geom.PartPose; -import net.minecraft.client.renderer.LightTexture; import net.minecraft.client.renderer.texture.OverlayTexture; +import net.minecraft.util.LightCoordsUtil; public final class MeshTree { private static final ThreadLocal THREAD_LOCAL_OBJECTS = ThreadLocal.withInitial(ThreadLocalObjects::new); @@ -74,7 +74,7 @@ private static Mesh compile(ModelPart modelPart, ThreadLocalObjects objects) { } VertexWriter vertexWriter = objects.vertexWriter; - FlwLibLink.INSTANCE.compileModelPart(modelPart, IDENTITY_POSE, vertexWriter, LightTexture.FULL_BRIGHT, OverlayTexture.NO_OVERLAY, 0xFFFFFFFF); + FlwLibLink.INSTANCE.compileModelPart(modelPart, IDENTITY_POSE, vertexWriter, LightCoordsUtil.FULL_BRIGHT, OverlayTexture.NO_OVERLAY, 0xFFFFFFFF); MemoryBlock data = vertexWriter.copyDataAndReset(); VertexView vertexView = new PosTexNormalVertexView(); diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/model/part/ModelTree.java b/common/src/lib/java/dev/engine_room/flywheel/lib/model/part/ModelTree.java index 5774ebf44..57c3cd652 100644 --- a/common/src/lib/java/dev/engine_room/flywheel/lib/model/part/ModelTree.java +++ b/common/src/lib/java/dev/engine_room/flywheel/lib/model/part/ModelTree.java @@ -4,7 +4,7 @@ import java.util.Map; import java.util.NoSuchElementException; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import dev.engine_room.flywheel.api.model.Model; import net.minecraft.client.model.geom.PartPose; diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/model/part/ModelTrees.java b/common/src/lib/java/dev/engine_room/flywheel/lib/model/part/ModelTrees.java index 1f26053f4..6f9d126ef 100644 --- a/common/src/lib/java/dev/engine_room/flywheel/lib/model/part/ModelTrees.java +++ b/common/src/lib/java/dev/engine_room/flywheel/lib/model/part/ModelTrees.java @@ -5,7 +5,7 @@ import java.util.Map; import java.util.Set; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import dev.engine_room.flywheel.api.material.Material; import dev.engine_room.flywheel.api.model.Mesh; @@ -13,12 +13,16 @@ import dev.engine_room.flywheel.lib.model.RetexturedMesh; import dev.engine_room.flywheel.lib.model.SingleMeshModel; import dev.engine_room.flywheel.lib.util.RendererReloadCache; +import net.minecraft.client.Minecraft; import net.minecraft.client.model.geom.ModelLayerLocation; import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.client.resources.model.sprite.AtlasManager; +import net.minecraft.client.resources.model.sprite.SpriteId; public final class ModelTrees { private static final RendererReloadCache CACHE = new RendererReloadCache<>(k -> { - ModelTree tree = convert("", MeshTree.of(k.layer), k.pathsToPrune, k.texture != null ? k.texture.sprite() : null, k.material); + AtlasManager atlas = Minecraft.getInstance().getAtlasManager(); + ModelTree tree = convert("", MeshTree.of(k.layer), k.pathsToPrune, k.texture != null ? atlas.get(k.texture) : null, k.material); if (tree == null) { throw new IllegalArgumentException("Cannot prune root node!"); @@ -34,7 +38,7 @@ public static ModelTree of(ModelLayerLocation layer, Material material) { return CACHE.get(new ModelTreeKey(layer, Collections.emptySet(), null, material)); } - public static ModelTree of(ModelLayerLocation layer, net.minecraft.client.resources.model.Material texture, Material material) { + public static ModelTree of(ModelLayerLocation layer, SpriteId texture, Material material) { return CACHE.get(new ModelTreeKey(layer, Collections.emptySet(), texture, material)); } @@ -42,7 +46,7 @@ public static ModelTree of(ModelLayerLocation layer, Set pathsToPrune, M return CACHE.get(new ModelTreeKey(layer, Set.copyOf(pathsToPrune), null, material)); } - public static ModelTree of(ModelLayerLocation layer, Set pathsToPrune, net.minecraft.client.resources.model.Material texture, Material material) { + public static ModelTree of(ModelLayerLocation layer, Set pathsToPrune, SpriteId texture, Material material) { return CACHE.get(new ModelTreeKey(layer, Set.copyOf(pathsToPrune), texture, material)); } @@ -78,6 +82,6 @@ private static ModelTree convert(String path, MeshTree meshTree, Set pat return new ModelTree(model, meshTree.initialPose(), children); } - private record ModelTreeKey(ModelLayerLocation layer, Set pathsToPrune, @Nullable net.minecraft.client.resources.model.Material texture, Material material) { + private record ModelTreeKey(ModelLayerLocation layer, Set pathsToPrune, @Nullable SpriteId texture, Material material) { } } diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/model/part/VertexWriter.java b/common/src/lib/java/dev/engine_room/flywheel/lib/model/part/VertexWriter.java index 00d808ee3..cb526fbc1 100644 --- a/common/src/lib/java/dev/engine_room/flywheel/lib/model/part/VertexWriter.java +++ b/common/src/lib/java/dev/engine_room/flywheel/lib/model/part/VertexWriter.java @@ -48,6 +48,12 @@ public VertexConsumer setColor(int red, int green, int blue, int alpha) { return this; } + @Override + public VertexConsumer setColor(int color) { + // ignore color + return this; + } + @Override public VertexConsumer setUv(float u, float v) { if (!filledTexture) { @@ -83,6 +89,12 @@ public VertexConsumer setNormal(float x, float y, float z) { return this; } + @Override + public VertexConsumer setLineWidth(float width) { + // ignore line width + return this; + } + private long vertexPtr() { return data.ptr() + (vertexCount - 1) * STRIDE; } diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/task/functional/package-info.java b/common/src/lib/java/dev/engine_room/flywheel/lib/task/functional/package-info.java index 54e74141a..32bf7cee2 100644 --- a/common/src/lib/java/dev/engine_room/flywheel/lib/task/functional/package-info.java +++ b/common/src/lib/java/dev/engine_room/flywheel/lib/task/functional/package-info.java @@ -5,12 +5,7 @@ * interface, but do not need to create additional closure objects to translate when the consumer wishes to ignore * the context object. */ -@ParametersAreNonnullByDefault -@FieldsAreNonnullByDefault -@MethodsReturnNonnullByDefault +@NullMarked package dev.engine_room.flywheel.lib.task.functional; -import javax.annotation.ParametersAreNonnullByDefault; - -import net.minecraft.FieldsAreNonnullByDefault; -import net.minecraft.MethodsReturnNonnullByDefault; +import org.jspecify.annotations.NullMarked; diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/util/IdentifierUtil.java b/common/src/lib/java/dev/engine_room/flywheel/lib/util/IdentifierUtil.java new file mode 100644 index 000000000..3a9d0f983 --- /dev/null +++ b/common/src/lib/java/dev/engine_room/flywheel/lib/util/IdentifierUtil.java @@ -0,0 +1,63 @@ +package dev.engine_room.flywheel.lib.util; + +import com.mojang.brigadier.StringReader; +import com.mojang.brigadier.exceptions.CommandSyntaxException; + +import dev.engine_room.flywheel.api.Flywheel; +import net.minecraft.IdentifierException; +import net.minecraft.resources.Identifier; + +public final class IdentifierUtil { + private IdentifierUtil() { + } + + public static Identifier id(String path) { + return Identifier.fromNamespaceAndPath(Flywheel.ID, path); + } + + /** + * Same as {@link Identifier#parse(String)}, but defaults to Flywheel namespace. + */ + public static Identifier parseFlywheelDefault(String id) { + String namespace = Flywheel.ID; + String path = id; + + int i = id.indexOf(Identifier.NAMESPACE_SEPARATOR); + if (i >= 0) { + path = id.substring(i + 1); + if (i >= 1) { + namespace = id.substring(0, i); + } + } + + return Identifier.fromNamespaceAndPath(namespace, path); + } + + /** + * Same as {@link Identifier#read(StringReader)}, but defaults to Flywheel namespace. + */ + public static Identifier readFlywheelDefault(StringReader reader) throws CommandSyntaxException { + int i = reader.getCursor(); + + while (reader.canRead() && Identifier.isAllowedInIdentifier(reader.peek())) { + reader.skip(); + } + + String s = reader.getString().substring(i, reader.getCursor()); + + try { + return parseFlywheelDefault(s); + } catch (IdentifierException e) { + reader.setCursor(i); + throw Identifier.ERROR_INVALID.createWithContext(reader); + } + } + + /** + * Same as {@link Identifier#toDebugFileName()}, but also removes the file extension. + */ + public static String toDebugFileNameNoExtension(Identifier id) { + var stringLoc = id.toDebugFileName(); + return stringLoc.substring(0, stringLoc.lastIndexOf('.')); + } +} diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/util/RecyclingPoseStack.java b/common/src/lib/java/dev/engine_room/flywheel/lib/util/RecyclingPoseStack.java deleted file mode 100644 index fb73e087a..000000000 --- a/common/src/lib/java/dev/engine_room/flywheel/lib/util/RecyclingPoseStack.java +++ /dev/null @@ -1,42 +0,0 @@ -package dev.engine_room.flywheel.lib.util; - -import java.util.ArrayDeque; -import java.util.Deque; - -import com.mojang.blaze3d.vertex.PoseStack; - -import dev.engine_room.flywheel.lib.internal.FlwLibLink; - -/** - * A {@link PoseStack} that recycles {@link PoseStack.Pose} objects. - * - *

Vanilla's {@link PoseStack} can get quite expensive to use when each game object needs to - * maintain their own stack. This class helps alleviate memory pressure by making Pose objects - * long-lived. Note that this means that you CANNOT safely store a Pose object outside - * the RecyclingPoseStack that created it. - */ -public class RecyclingPoseStack extends PoseStack { - private final Deque recycleBin = new ArrayDeque<>(); - - @Override - public void pushPose() { - if (recycleBin.isEmpty()) { - super.pushPose(); - } else { - var last = last(); - var recycle = recycleBin.removeLast(); - recycle.pose() - .set(last.pose()); - recycle.normal() - .set(last.normal()); - FlwLibLink.INSTANCE.getPoseStack(this) - .addLast(recycle); - } - } - - @Override - public void popPose() { - recycleBin.addLast(FlwLibLink.INSTANCE.getPoseStack(this) - .removeLast()); - } -} diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/util/ResourceReloadHolder.java b/common/src/lib/java/dev/engine_room/flywheel/lib/util/ResourceReloadHolder.java index 9ff36d40c..1dc6c6003 100644 --- a/common/src/lib/java/dev/engine_room/flywheel/lib/util/ResourceReloadHolder.java +++ b/common/src/lib/java/dev/engine_room/flywheel/lib/util/ResourceReloadHolder.java @@ -6,7 +6,7 @@ import java.util.function.Supplier; import org.jetbrains.annotations.ApiStatus; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; public final class ResourceReloadHolder implements Supplier { private static final Set> ALL = Collections.newSetFromMap(new WeakHashMap<>()); diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/util/ResourceUtil.java b/common/src/lib/java/dev/engine_room/flywheel/lib/util/ResourceUtil.java deleted file mode 100644 index b61d9292a..000000000 --- a/common/src/lib/java/dev/engine_room/flywheel/lib/util/ResourceUtil.java +++ /dev/null @@ -1,67 +0,0 @@ -package dev.engine_room.flywheel.lib.util; - -import com.mojang.brigadier.StringReader; -import com.mojang.brigadier.exceptions.CommandSyntaxException; -import com.mojang.brigadier.exceptions.SimpleCommandExceptionType; - -import dev.engine_room.flywheel.api.Flywheel; -import net.minecraft.ResourceLocationException; -import net.minecraft.network.chat.Component; -import net.minecraft.resources.ResourceLocation; - -public final class ResourceUtil { - private static final SimpleCommandExceptionType ERROR_INVALID = new SimpleCommandExceptionType(Component.translatable("argument.id.invalid")); - - private ResourceUtil() { - } - - public static ResourceLocation rl(String path) { - return ResourceLocation.fromNamespaceAndPath(Flywheel.ID, path); - } - - /** - * Same as {@link ResourceLocation#parse(String)}, but defaults to Flywheel namespace. - */ - public static ResourceLocation parseFlywheelDefault(String location) { - String namespace = Flywheel.ID; - String path = location; - - int i = location.indexOf(ResourceLocation.NAMESPACE_SEPARATOR); - if (i >= 0) { - path = location.substring(i + 1); - if (i >= 1) { - namespace = location.substring(0, i); - } - } - - return ResourceLocation.fromNamespaceAndPath(namespace, path); - } - - /** - * Same as {@link ResourceLocation#read(StringReader)}, but defaults to Flywheel namespace. - */ - public static ResourceLocation readFlywheelDefault(StringReader reader) throws CommandSyntaxException { - int i = reader.getCursor(); - - while (reader.canRead() && ResourceLocation.isAllowedInResourceLocation(reader.peek())) { - reader.skip(); - } - - String s = reader.getString().substring(i, reader.getCursor()); - - try { - return parseFlywheelDefault(s); - } catch (ResourceLocationException resourcelocationexception) { - reader.setCursor(i); - throw ERROR_INVALID.createWithContext(reader); - } - } - - /** - * Same as {@link ResourceLocation#toDebugFileName()}, but also removes the file extension. - */ - public static String toDebugFileNameNoExtension(ResourceLocation resourceLocation) { - var stringLoc = resourceLocation.toDebugFileName(); - return stringLoc.substring(0, stringLoc.lastIndexOf('.')); - } -} diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/vertex/AbstractVertexView.java b/common/src/lib/java/dev/engine_room/flywheel/lib/vertex/AbstractVertexView.java index 7a7b506f3..2a18b0333 100644 --- a/common/src/lib/java/dev/engine_room/flywheel/lib/vertex/AbstractVertexView.java +++ b/common/src/lib/java/dev/engine_room/flywheel/lib/vertex/AbstractVertexView.java @@ -1,6 +1,6 @@ package dev.engine_room.flywheel.lib.vertex; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; public abstract class AbstractVertexView implements VertexView { protected long ptr; diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/vertex/FlywheelVertexFormats.java b/common/src/lib/java/dev/engine_room/flywheel/lib/vertex/FlywheelVertexFormats.java new file mode 100644 index 000000000..6459664e4 --- /dev/null +++ b/common/src/lib/java/dev/engine_room/flywheel/lib/vertex/FlywheelVertexFormats.java @@ -0,0 +1,17 @@ +package dev.engine_room.flywheel.lib.vertex; + +import com.mojang.blaze3d.vertex.DefaultVertexFormat; +import com.mojang.blaze3d.vertex.VertexFormat; +import com.mojang.blaze3d.vertex.VertexFormatElement; + +public class FlywheelVertexFormats { + /// Basically the same as {@link DefaultVertexFormat#BLOCK} but with the normals included + public static final VertexFormat BLOCK_VERTEX_FORMAT = VertexFormat.builder() + .add("Position", VertexFormatElement.POSITION) + .add("Color",VertexFormatElement.COLOR) + .add("UV0",VertexFormatElement.UV0) + .add("UV2",VertexFormatElement.UV2) + .add("Normal", VertexFormatElement.NORMAL) + .padding(1) + .build(); +} diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/vertex/VertexView.java b/common/src/lib/java/dev/engine_room/flywheel/lib/vertex/VertexView.java index 4c60462a2..a220d6a9c 100644 --- a/common/src/lib/java/dev/engine_room/flywheel/lib/vertex/VertexView.java +++ b/common/src/lib/java/dev/engine_room/flywheel/lib/vertex/VertexView.java @@ -1,6 +1,6 @@ package dev.engine_room.flywheel.lib.vertex; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import org.lwjgl.system.MemoryUtil; import dev.engine_room.flywheel.api.vertex.MutableVertexList; diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/visual/AbstractBlockEntityVisual.java b/common/src/lib/java/dev/engine_room/flywheel/lib/visual/AbstractBlockEntityVisual.java index 25d05d481..1bd92114a 100644 --- a/common/src/lib/java/dev/engine_room/flywheel/lib/visual/AbstractBlockEntityVisual.java +++ b/common/src/lib/java/dev/engine_room/flywheel/lib/visual/AbstractBlockEntityVisual.java @@ -2,7 +2,7 @@ import java.util.Iterator; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import org.jetbrains.annotations.UnknownNullability; import org.joml.FrustumIntersection; @@ -96,15 +96,15 @@ public boolean isVisible(FrustumIntersection frustum) { */ public boolean doDistanceLimitThisFrame(DynamicVisual.Context context) { return !context.limiter() - .shouldUpdate(pos.distToCenterSqr(context.camera().getPosition())); + .shouldUpdate(pos.distToCenterSqr(context.cameraRenderState().pos)); } protected int computePackedLight() { - return LevelRenderer.getLightColor(level, pos); + return LevelRenderer.getLightCoords(level, pos); } protected void relight(BlockPos pos, @Nullable FlatLit... instances) { - FlatLit.relight(LevelRenderer.getLightColor(level, pos), instances); + FlatLit.relight(LevelRenderer.getLightCoords(level, pos), instances); } protected void relight(@Nullable FlatLit... instances) { @@ -112,7 +112,7 @@ protected void relight(@Nullable FlatLit... instances) { } protected void relight(BlockPos pos, Iterator<@Nullable FlatLit> instances) { - FlatLit.relight(LevelRenderer.getLightColor(level, pos), instances); + FlatLit.relight(LevelRenderer.getLightCoords(level, pos), instances); } protected void relight(Iterator<@Nullable FlatLit> instances) { @@ -120,7 +120,7 @@ protected void relight(Iterator<@Nullable FlatLit> instances) { } protected void relight(BlockPos pos, Iterable<@Nullable FlatLit> instances) { - FlatLit.relight(LevelRenderer.getLightColor(level, pos), instances); + FlatLit.relight(LevelRenderer.getLightCoords(level, pos), instances); } protected void relight(Iterable<@Nullable FlatLit> instances) { diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/visual/AbstractEntityVisual.java b/common/src/lib/java/dev/engine_room/flywheel/lib/visual/AbstractEntityVisual.java index 80ffa73a0..3061b2d14 100644 --- a/common/src/lib/java/dev/engine_room/flywheel/lib/visual/AbstractEntityVisual.java +++ b/common/src/lib/java/dev/engine_room/flywheel/lib/visual/AbstractEntityVisual.java @@ -1,8 +1,8 @@ package dev.engine_room.flywheel.lib.visual; -import org.jetbrains.annotations.Nullable; import org.joml.FrustumIntersection; import org.joml.Vector3f; +import org.jspecify.annotations.Nullable; import dev.engine_room.flywheel.api.visual.DynamicVisual; import dev.engine_room.flywheel.api.visual.EntityVisual; @@ -12,8 +12,9 @@ import dev.engine_room.flywheel.api.visualization.VisualizationContext; import dev.engine_room.flywheel.api.visualization.VisualizationManager; import dev.engine_room.flywheel.lib.instance.FlatLit; -import net.minecraft.client.renderer.LightTexture; +import dev.engine_room.flywheel.lib.internal.FlwLibLink; import net.minecraft.core.BlockPos; +import net.minecraft.util.LightCoordsUtil; import net.minecraft.util.Mth; import net.minecraft.world.entity.Entity; import net.minecraft.world.level.LightLayer; @@ -89,14 +90,14 @@ public Vector3f getVisualPosition(float partialTick) { } public boolean isVisible(FrustumIntersection frustum) { - return entity.noCulling || visibilityTester.check(frustum); + return !FlwLibLink.INSTANCE.affectedByCulling(entity) || visibilityTester.check(frustum); } protected int computePackedLight(float partialTick) { BlockPos pos = BlockPos.containing(entity.getLightProbePosition(partialTick)); int blockLight = entity.isOnFire() ? 15 : level.getBrightness(LightLayer.BLOCK, pos); int skyLight = level.getBrightness(LightLayer.SKY, pos); - return LightTexture.pack(blockLight, skyLight); + return LightCoordsUtil.pack(blockLight, skyLight); } protected void relight(float partialTick, @Nullable FlatLit... instances) { diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/visual/EntityVisibilityTester.java b/common/src/lib/java/dev/engine_room/flywheel/lib/visual/EntityVisibilityTester.java index 90e2e977e..095b98e24 100644 --- a/common/src/lib/java/dev/engine_room/flywheel/lib/visual/EntityVisibilityTester.java +++ b/common/src/lib/java/dev/engine_room/flywheel/lib/visual/EntityVisibilityTester.java @@ -1,8 +1,9 @@ package dev.engine_room.flywheel.lib.visual; -import org.jetbrains.annotations.Nullable; import org.joml.FrustumIntersection; +import org.jspecify.annotations.Nullable; +import dev.engine_room.flywheel.lib.internal.FlwLibLink; import dev.engine_room.flywheel.lib.math.MoreMath; import net.minecraft.core.Vec3i; import net.minecraft.util.Mth; @@ -42,7 +43,7 @@ public EntityVisibilityTester(Entity entity, Vec3i renderOrigin, float scale) { * @return {@code true} if the Entity is visible, {@code false} otherwise. */ public boolean check(FrustumIntersection frustum) { - AABB aabb = entity.getBoundingBoxForCulling(); + AABB aabb = FlwLibLink.INSTANCE.getBoundingBoxForCulling(entity); // If we've never seen the entity before assume its visible. // Fixes entities freezing when they first spawn. diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/visual/component/FireComponent.java b/common/src/lib/java/dev/engine_room/flywheel/lib/visual/component/FireComponent.java index deb180e8a..9be814e00 100644 --- a/common/src/lib/java/dev/engine_room/flywheel/lib/visual/component/FireComponent.java +++ b/common/src/lib/java/dev/engine_room/flywheel/lib/visual/component/FireComponent.java @@ -19,9 +19,11 @@ import dev.engine_room.flywheel.lib.model.SingleMeshModel; import dev.engine_room.flywheel.lib.util.RendererReloadCache; import dev.engine_room.flywheel.lib.visual.util.SmartRecycler; -import net.minecraft.client.renderer.LightTexture; +import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.resources.model.ModelBakery; +import net.minecraft.client.resources.model.sprite.SpriteId; +import net.minecraft.util.LightCoordsUtil; import net.minecraft.util.Mth; import net.minecraft.world.entity.Entity; @@ -33,11 +35,9 @@ public final class FireComponent implements EntityComponent { .backfaceCulling(false) // Disable backface because we want to be able to flip the model. .build(); - // Parameterize by the material instead of the sprite - // because Material#sprite is a surprisingly heavy operation - // and because sprites are invalidated after a resource reload. - private static final RendererReloadCache FIRE_MODELS = new RendererReloadCache<>(texture -> { - return new SingleMeshModel(new FireMesh(texture.sprite()), FIRE_MATERIAL); + private static final RendererReloadCache FIRE_MODELS = new RendererReloadCache<>(texture -> { + TextureAtlasSprite sprite = Minecraft.getInstance().getAtlasManager().get(texture); + return new SingleMeshModel(new FireMesh(sprite), FIRE_MATERIAL); }); private final VisualizationContext context; @@ -57,7 +57,7 @@ private TransformedInstance createInstance(Model model) { TransformedInstance instance = context.instancerProvider() .instancer(InstanceTypes.TRANSFORMED, model) .createInstance(); - instance.light(LightTexture.FULL_BLOCK); + instance.light(LightCoordsUtil.pack(15, 0)); instance.setChanged(); return instance; } @@ -94,8 +94,7 @@ private void setupInstances(DynamicVisual.Context context) { stack.setIdentity(); stack.translate(entityX - renderOrigin.getX(), entityY - renderOrigin.getY(), entityZ - renderOrigin.getZ()); stack.scale(scale, scale, scale); - stack.mulPose(Axis.YP.rotationDegrees(-context.camera() - .getYRot())); + stack.mulPose(Axis.YP.rotationDegrees(-context.cameraRenderState().yRot)); stack.translate(0.0F, 0.0F, -0.3F + (float) ((int) maxHeight) * 0.02F); for (int i = 0; y < maxHeight; ++i) { @@ -155,7 +154,7 @@ private static void writeVertex(MutableVertexList vertexList, int i, float x, fl vertexList.b(i, 1); vertexList.u(i, u); vertexList.v(i, v); - vertexList.light(i, LightTexture.FULL_BLOCK); + vertexList.light(i, LightCoordsUtil.pack(15, 0)); vertexList.normalX(i, 0); vertexList.normalY(i, 1); vertexList.normalZ(i, 0); diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/visual/component/HitboxComponent.java b/common/src/lib/java/dev/engine_room/flywheel/lib/visual/component/HitboxComponent.java index d4d7ce8eb..87e4ccb83 100644 --- a/common/src/lib/java/dev/engine_room/flywheel/lib/visual/component/HitboxComponent.java +++ b/common/src/lib/java/dev/engine_room/flywheel/lib/visual/component/HitboxComponent.java @@ -10,11 +10,13 @@ import dev.engine_room.flywheel.lib.model.LineModelBuilder; import dev.engine_room.flywheel.lib.visual.util.SmartRecycler; import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.LightTexture; +import net.minecraft.client.gui.components.debug.DebugScreenEntries; +import net.minecraft.util.LightCoordsUtil; import net.minecraft.util.Mth; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.LivingEntity; +// TODO 1.21.11: vanilla changed hitbox rendering and moved it to the debug renderer system (EntityHitboxDebugRenderer) public final class HitboxComponent implements EntityComponent { // 010------110 // /| /| @@ -67,7 +69,7 @@ private TransformedInstance createInstance(Model model) { TransformedInstance instance = context.instancerProvider() .instancer(InstanceTypes.TRANSFORMED, model) .createInstance(); - instance.light(LightTexture.FULL_BLOCK); + instance.light(LightCoordsUtil.pack(15, 0)); instance.setChanged(); return instance; } @@ -86,8 +88,8 @@ public void beginFrame(DynamicVisual.Context context) { recycler.resetCount(); var shouldRenderHitBoxes = Minecraft.getInstance() - .getEntityRenderDispatcher() - .shouldRenderHitBoxes(); + .debugEntries + .isCurrentlyEnabled(DebugScreenEntries.ENTITY_HITBOXES); if (shouldRenderHitBoxes && !entity.isInvisible() && !Minecraft.getInstance() .showOnlyReducedInfo()) { float partialTick = context.partialTick(); diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/visual/component/ShadowComponent.java b/common/src/lib/java/dev/engine_room/flywheel/lib/visual/component/ShadowComponent.java index 2af41581f..2a86de5ec 100644 --- a/common/src/lib/java/dev/engine_room/flywheel/lib/visual/component/ShadowComponent.java +++ b/common/src/lib/java/dev/engine_room/flywheel/lib/visual/component/ShadowComponent.java @@ -1,8 +1,8 @@ package dev.engine_room.flywheel.lib.visual.component; -import org.jetbrains.annotations.Nullable; import org.joml.Vector4f; import org.joml.Vector4fc; +import org.jspecify.annotations.Nullable; import dev.engine_room.flywheel.api.material.Material; import dev.engine_room.flywheel.api.material.Transparency; @@ -18,12 +18,13 @@ import dev.engine_room.flywheel.lib.model.SingleMeshModel; import dev.engine_room.flywheel.lib.visual.util.InstanceRecycler; import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.LightTexture; +import net.minecraft.client.renderer.Lightmap; import net.minecraft.client.renderer.texture.OverlayTexture; import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos.MutableBlockPos; import net.minecraft.core.Direction.Axis; -import net.minecraft.resources.ResourceLocation; +import net.minecraft.resources.Identifier; +import net.minecraft.util.LightCoordsUtil; import net.minecraft.util.Mth; import net.minecraft.world.entity.Entity; import net.minecraft.world.level.Level; @@ -42,7 +43,7 @@ * The shadow will be cast on blocks at most {@code min(radius, 2 * strength)} blocks below the entity.

*/ public final class ShadowComponent implements EntityComponent { - private static final ResourceLocation SHADOW_TEXTURE = ResourceLocation.withDefaultNamespace("textures/misc/shadow.png"); + private static final Identifier SHADOW_TEXTURE = Identifier.withDefaultNamespace("textures/misc/shadow.png"); private static final Material SHADOW_MATERIAL = SimpleMaterial.builder() .texture(SHADOW_TEXTURE) .mipmap(false) @@ -157,7 +158,7 @@ private void setupInstance(ChunkAccess chunk, MutableBlockPos pos, float entityX // Too dark to render. return; } - float blockBrightness = LightTexture.getBrightness(level.dimensionType(), maxLocalRawBrightness); + float blockBrightness = Lightmap.getBrightness(level.dimensionType(), maxLocalRawBrightness); float alpha = strength * 0.5F * blockBrightness; if (alpha < 0.0F) { // Too far away/too weak to render. @@ -256,7 +257,7 @@ private static void writeVertex(MutableVertexList vertexList, int i, float x, fl vertexList.b(i, 1); vertexList.u(i, 0); vertexList.v(i, 0); - vertexList.light(i, LightTexture.FULL_BRIGHT); + vertexList.light(i, LightCoordsUtil.FULL_BRIGHT); vertexList.overlay(i, OverlayTexture.NO_OVERLAY); vertexList.normalX(i, 0); vertexList.normalY(i, 1); diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/visualization/SimpleBlockEntityVisualizer.java b/common/src/lib/java/dev/engine_room/flywheel/lib/visualization/SimpleBlockEntityVisualizer.java index 6a82041aa..e4d393025 100644 --- a/common/src/lib/java/dev/engine_room/flywheel/lib/visualization/SimpleBlockEntityVisualizer.java +++ b/common/src/lib/java/dev/engine_room/flywheel/lib/visualization/SimpleBlockEntityVisualizer.java @@ -3,7 +3,7 @@ import java.util.Objects; import java.util.function.Predicate; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import dev.engine_room.flywheel.api.visual.BlockEntityVisual; import dev.engine_room.flywheel.api.visualization.BlockEntityVisualizer; diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/visualization/SimpleEntityVisualizer.java b/common/src/lib/java/dev/engine_room/flywheel/lib/visualization/SimpleEntityVisualizer.java index 86e1832ea..c817c4a62 100644 --- a/common/src/lib/java/dev/engine_room/flywheel/lib/visualization/SimpleEntityVisualizer.java +++ b/common/src/lib/java/dev/engine_room/flywheel/lib/visualization/SimpleEntityVisualizer.java @@ -3,7 +3,7 @@ import java.util.Objects; import java.util.function.Predicate; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import dev.engine_room.flywheel.api.visual.EntityVisual; import dev.engine_room.flywheel.api.visualization.EntityVisualizer; diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/visualization/VisualizationHelper.java b/common/src/lib/java/dev/engine_room/flywheel/lib/visualization/VisualizationHelper.java index 8b8f79860..da7796960 100644 --- a/common/src/lib/java/dev/engine_room/flywheel/lib/visualization/VisualizationHelper.java +++ b/common/src/lib/java/dev/engine_room/flywheel/lib/visualization/VisualizationHelper.java @@ -1,6 +1,6 @@ package dev.engine_room.flywheel.lib.visualization; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import dev.engine_room.flywheel.api.visual.Effect; import dev.engine_room.flywheel.api.visual.Visual; diff --git a/common/src/lib/resources/assets/flywheel/flywheel/fog/linear.glsl b/common/src/lib/resources/assets/flywheel/flywheel/fog/linear.glsl index 9c03c6791..6411e5953 100644 --- a/common/src/lib/resources/assets/flywheel/flywheel/fog/linear.glsl +++ b/common/src/lib/resources/assets/flywheel/flywheel/fog/linear.glsl @@ -1,12 +1,22 @@ -vec4 linearFog(vec4 color, float distance, float fogStart, float fogEnd, vec4 fogColor) { - if (distance <= fogStart) { - return color; +float linearFogValue(float vertexDistance, float fogStart, float fogEnd) { + if (vertexDistance <= fogStart) { + return 0.0; + } else if (vertexDistance >= fogEnd) { + return 1.0; } - float fogValue = distance < fogEnd ? smoothstep(fogStart, fogEnd, distance) : 1.0; + return (vertexDistance - fogStart) / (fogEnd - fogStart); +} + +float totalFogValue(float sphericalVertexDistance, float cylindricalVertexDistance, float environmentalStart, float environmantalEnd, float renderDistanceStart, float renderDistanceEnd) { + return max(linearFogValue(sphericalVertexDistance, environmentalStart, environmantalEnd), linearFogValue(cylindricalVertexDistance, renderDistanceStart, renderDistanceEnd)); +} + +vec4 linearFog(vec4 color, float sphericalVertexDistance, float cylindricalVertexDistance, float environmentalStart, float environmantalEnd, float renderDistanceStart, float renderDistanceEnd, vec4 fogColor) { + float fogValue = totalFogValue(sphericalVertexDistance, cylindricalVertexDistance, environmentalStart, environmantalEnd, renderDistanceStart, renderDistanceEnd); return vec4(mix(color.rgb, fogColor.rgb, fogValue * fogColor.a), color.a); } vec4 flw_fogFilter(vec4 color) { - return linearFog(color, flw_distance, flw_fogRange.x, flw_fogRange.y, flw_fogColor); + return linearFog(color, flw_sphericalDistance, flw_cylindricalDistance, flw_fogEnvironmentalStart, flw_fogEnvironmentalEnd, flw_fogRenderDistanceStart, flw_fogRenderDistanceEnd, flw_fogColor); } diff --git a/common/src/main/java/dev/engine_room/flywheel/impl/BackendArgument.java b/common/src/main/java/dev/engine_room/flywheel/impl/BackendArgument.java index 1ef3235fc..53efd9370 100644 --- a/common/src/main/java/dev/engine_room/flywheel/impl/BackendArgument.java +++ b/common/src/main/java/dev/engine_room/flywheel/impl/BackendArgument.java @@ -14,11 +14,11 @@ import com.mojang.brigadier.suggestion.SuggestionsBuilder; import dev.engine_room.flywheel.api.backend.Backend; -import dev.engine_room.flywheel.lib.util.ResourceUtil; +import dev.engine_room.flywheel.lib.util.IdentifierUtil; import net.minecraft.commands.SharedSuggestionProvider; import net.minecraft.commands.synchronization.SingletonArgumentInfo; import net.minecraft.network.chat.Component; -import net.minecraft.resources.ResourceLocation; +import net.minecraft.resources.Identifier; public class BackendArgument implements ArgumentType { private static final List EXAMPLES = List.of("off", "flywheel:off", "instancing"); @@ -32,7 +32,7 @@ public class BackendArgument implements ArgumentType { @Override public Backend parse(StringReader reader) throws CommandSyntaxException { - ResourceLocation id = ResourceUtil.readFlywheelDefault(reader); + Identifier id = IdentifierUtil.readFlywheelDefault(reader); Backend backend = Backend.REGISTRY.get(id); if (backend == null) { @@ -45,7 +45,7 @@ public Backend parse(StringReader reader) throws CommandSyntaxException { @Override public CompletableFuture listSuggestions(CommandContext context, SuggestionsBuilder builder) { String input = builder.getRemaining().toLowerCase(Locale.ROOT); - for (ResourceLocation id : Backend.REGISTRY.getAllIds()) { + for (Identifier id : Backend.REGISTRY.getAllIds()) { String idStr = id.toString(); if (SharedSuggestionProvider.matchesSubStr(input, idStr) || SharedSuggestionProvider.matchesSubStr(input, id.getPath())) { builder.suggest(idStr); diff --git a/common/src/main/java/dev/engine_room/flywheel/impl/BackendManagerImpl.java b/common/src/main/java/dev/engine_room/flywheel/impl/BackendManagerImpl.java index df4262e5a..1f968c689 100644 --- a/common/src/main/java/dev/engine_room/flywheel/impl/BackendManagerImpl.java +++ b/common/src/main/java/dev/engine_room/flywheel/impl/BackendManagerImpl.java @@ -5,9 +5,9 @@ import dev.engine_room.flywheel.api.backend.Backend; import dev.engine_room.flywheel.impl.visualization.VisualizationManagerImpl; import dev.engine_room.flywheel.lib.backend.SimpleBackend; -import dev.engine_room.flywheel.lib.util.ResourceUtil; +import dev.engine_room.flywheel.lib.util.IdentifierUtil; import net.minecraft.client.multiplayer.ClientLevel; -import net.minecraft.resources.ResourceLocation; +import net.minecraft.resources.Identifier; public final class BackendManagerImpl { public static final Backend OFF_BACKEND = SimpleBackend.builder() @@ -15,7 +15,7 @@ public final class BackendManagerImpl { throw new UnsupportedOperationException("Cannot create engine when backend is off."); }) .supported(() -> true) - .register(ResourceUtil.rl("off")); + .register(IdentifierUtil.id("off")); private static Backend backend = OFF_BACKEND; @@ -75,7 +75,7 @@ private static void chooseBackend() { } public static String getBackendString() { - ResourceLocation backendId = Backend.REGISTRY.getId(backend); + Identifier backendId = Backend.REGISTRY.getId(backend); if (backendId == null) { return "[unregistered]"; } diff --git a/common/src/main/java/dev/engine_room/flywheel/impl/FlwApiLinkImpl.java b/common/src/main/java/dev/engine_room/flywheel/impl/FlwApiLinkImpl.java index 6f03a7dab..8b5902314 100644 --- a/common/src/main/java/dev/engine_room/flywheel/impl/FlwApiLinkImpl.java +++ b/common/src/main/java/dev/engine_room/flywheel/impl/FlwApiLinkImpl.java @@ -1,6 +1,6 @@ package dev.engine_room.flywheel.impl; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import dev.engine_room.flywheel.api.backend.Backend; import dev.engine_room.flywheel.api.internal.FlwApiLink; diff --git a/common/src/main/java/dev/engine_room/flywheel/impl/FlwDebugInfo.java b/common/src/main/java/dev/engine_room/flywheel/impl/FlwDebugInfo.java index 438a42038..ba19e0ac9 100644 --- a/common/src/main/java/dev/engine_room/flywheel/impl/FlwDebugInfo.java +++ b/common/src/main/java/dev/engine_room/flywheel/impl/FlwDebugInfo.java @@ -1,8 +1,9 @@ package dev.engine_room.flywheel.impl; -import java.util.List; +import java.net.URI; +import java.util.Locale; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import dev.engine_room.flywheel.api.visualization.VisualizationManager; import dev.engine_room.flywheel.backend.engine.AbstractInstancer; @@ -10,17 +11,24 @@ import dev.engine_room.flywheel.backend.gl.GlCompat; import dev.engine_room.flywheel.impl.visualization.VisualizationManagerImpl; import dev.engine_room.flywheel.lib.memory.FlwMemoryTracker; +import dev.engine_room.flywheel.lib.util.IdentifierUtil; import dev.engine_room.flywheel.lib.util.StringUtil; import it.unimi.dsi.fastutil.ints.IntArrayList; import it.unimi.dsi.fastutil.ints.IntComparators; import it.unimi.dsi.fastutil.ints.IntList; import net.minecraft.ChatFormatting; import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.components.debug.DebugScreenDisplayer; +import net.minecraft.client.gui.components.debug.DebugScreenEntry; import net.minecraft.core.Vec3i; -import net.minecraft.network.chat.ClickEvent; +import net.minecraft.network.chat.ClickEvent.CopyToClipboard; +import net.minecraft.network.chat.ClickEvent.OpenUrl; import net.minecraft.network.chat.Component; -import net.minecraft.network.chat.HoverEvent; +import net.minecraft.network.chat.HoverEvent.ShowText; import net.minecraft.network.chat.Style; +import net.minecraft.resources.Identifier; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.chunk.LevelChunk; public final class FlwDebugInfo { @@ -66,13 +74,13 @@ public static Component getDebugCommandInfo() { return Component.literal(debugInfoString) .append(Component.literal("\n\nClick to copy debug info to clipboard") .withStyle(Style.EMPTY.withUnderlined(true) - .withClickEvent(new ClickEvent(ClickEvent.Action.COPY_TO_CLIPBOARD, debugInfoString)) - .withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, Component.literal(debugInfoString))))) + .withClickEvent(new CopyToClipboard(debugInfoString)) + .withHoverEvent(new ShowText(Component.literal(debugInfoString))))) .append(Component.literal("\n\nClick to open an issue on GitHub") .withStyle(Style.EMPTY.withUnderlined(true) .withColor(ChatFormatting.BLUE) - .withClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, "https://github.com/Engine-Room/Flywheel/issues")) - .withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, Component.literal("Opens URL:\nhttps://github.com/Engine-Room/Flywheel/issues"))))); + .withClickEvent(new OpenUrl(URI.create("https://github.com/Engine-Room/Flywheel/issues"))) + .withHoverEvent(new ShowText(Component.literal("Opens URL:\nhttps://github.com/Engine-Room/Flywheel/issues"))))); } @@ -247,25 +255,47 @@ private static void addOpenGLDebugInfo(StringBuilder out) { appendLine(out, "Shading Language Version: ").append(GlCompat.GL_SHADING_LANGUAGE_VERSION_STRING); } - public static void addDebugInfo(Minecraft minecraft, List systemInfo) { - if (minecraft.showOnlyReducedInfo()) { - return; + public static class FlwDebugEntry implements DebugScreenEntry { + public static final Identifier ID = IdentifierUtil.id("flw_debug_info"); + private static final Identifier GROUP = IdentifierUtil.id("flywheel"); + + @Override + public void display(DebugScreenDisplayer displayer, @Nullable Level serverOrClientLevel, @Nullable LevelChunk clientChunk, @Nullable LevelChunk serverChunk) { + add(displayer, "Flywheel: %s", FlwImplXplat.INSTANCE.getVersionStr()); + add(displayer, "Backend: %s", BackendManagerImpl.getBackendString()); + add(displayer, "Update limiting: %s", FlwConfig.INSTANCE.limitUpdates() ? "on" : "off"); + + Level clientLevel = clientChunk != null ? clientChunk.getLevel() : null; + VisualizationManager manager = VisualizationManager.get(clientLevel); + if (manager != null) { + add(displayer, "B: %s, E: %s, F: %s", + manager.blockEntities().visualCount(), + manager.entities().visualCount(), + manager.effects().visualCount() + ); + + Vec3i renderOrigin = manager.renderOrigin(); + add(displayer, "Origin: %s, %s, %s", + renderOrigin.getX(), + renderOrigin.getY(), + renderOrigin.getZ() + ); + } + + // TODO b3d-ification: This is not really correct anymore, it no longer tracks the buffers flw creates, it should probably be removed + add(displayer, "Memory Usage: CPU: %s, GPU: %s", + StringUtil.formatBytes(FlwMemoryTracker.getCpuMemory()), + StringUtil.formatBytes(FlwMemoryTracker.getGpuMemory()) + ); } - systemInfo.add(""); - systemInfo.add("Flywheel: " + FlwImplXplat.INSTANCE.getVersionStr()); - systemInfo.add("Backend: " + BackendManagerImpl.getBackendString()); - systemInfo.add("Update limiting: " + (FlwConfig.INSTANCE.limitUpdates() ? "on" : "off")); - - VisualizationManager manager = VisualizationManager.get(minecraft.level); - if (manager != null) { - systemInfo.add("B: " + manager.blockEntities().visualCount() - + ", E: " + manager.entities().visualCount() - + ", F: " + manager.effects().visualCount()); - Vec3i renderOrigin = manager.renderOrigin(); - systemInfo.add("Origin: " + renderOrigin.getX() + ", " + renderOrigin.getY() + ", " + renderOrigin.getZ()); + @Override + public boolean isAllowed(boolean reducedDebugInfo) { + return true; } - systemInfo.add("Memory Usage: CPU: " + StringUtil.formatBytes(FlwMemoryTracker.getCpuMemory()) + ", GPU: " + StringUtil.formatBytes(FlwMemoryTracker.getGpuMemory())); + private static void add(DebugScreenDisplayer displayer, String input, Object... args) { + displayer.addToGroup(GROUP, String.format(Locale.ROOT, input, args)); + } } } diff --git a/common/src/main/java/dev/engine_room/flywheel/impl/FlwLibLinkImpl.java b/common/src/main/java/dev/engine_room/flywheel/impl/FlwLibLinkImpl.java index 10244b19c..f392720d5 100644 --- a/common/src/main/java/dev/engine_room/flywheel/impl/FlwLibLinkImpl.java +++ b/common/src/main/java/dev/engine_room/flywheel/impl/FlwLibLinkImpl.java @@ -1,6 +1,5 @@ package dev.engine_room.flywheel.impl; -import java.util.Deque; import java.util.Map; import org.slf4j.Logger; @@ -11,11 +10,15 @@ 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.mixin.EntityRendererAccessor; import dev.engine_room.flywheel.impl.mixin.ModelPartAccessor; -import dev.engine_room.flywheel.impl.mixin.PoseStackAccessor; import dev.engine_room.flywheel.lib.internal.FlwLibLink; import dev.engine_room.flywheel.lib.transform.PoseTransformStack; +import net.minecraft.client.Minecraft; import net.minecraft.client.model.geom.ModelPart; +import net.minecraft.client.renderer.entity.EntityRenderer; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.phys.AABB; public class FlwLibLinkImpl implements FlwLibLink { @Override @@ -39,8 +42,19 @@ public void compileModelPart(ModelPart part, PoseStack.Pose pose, VertexConsumer } @Override - public Deque getPoseStack(PoseStack stack) { - return ((PoseStackAccessor) stack).flywheel$getPoseStack(); + public boolean affectedByCulling(T entity) { + EntityRenderer renderer = Minecraft.getInstance() + .getEntityRenderDispatcher() + .getRenderer(entity); + return ((EntityRendererAccessor) renderer).flywheel$affectedByCulling(entity); + } + + @Override + public AABB getBoundingBoxForCulling(T entity) { + EntityRenderer renderer = Minecraft.getInstance() + .getEntityRenderDispatcher() + .getRenderer(entity); + return ((EntityRendererAccessor) renderer).flywheel$getBoundingBoxForCulling(entity); } @Override diff --git a/common/src/main/java/dev/engine_room/flywheel/impl/compat/CompatMod.java b/common/src/main/java/dev/engine_room/flywheel/impl/compat/CompatMod.java index 8217cb963..c53fa9ecd 100644 --- a/common/src/main/java/dev/engine_room/flywheel/impl/compat/CompatMod.java +++ b/common/src/main/java/dev/engine_room/flywheel/impl/compat/CompatMod.java @@ -3,7 +3,6 @@ import dev.engine_room.flywheel.impl.FlwImplXplat; public enum CompatMod { - EMBEDDIUM("embeddium"), IRIS("iris"), SODIUM("sodium"); diff --git a/common/src/main/java/dev/engine_room/flywheel/impl/compat/OptifineCompat.java b/common/src/main/java/dev/engine_room/flywheel/impl/compat/OptifineCompat.java index 42dfe4687..4d14fd4ab 100644 --- a/common/src/main/java/dev/engine_room/flywheel/impl/compat/OptifineCompat.java +++ b/common/src/main/java/dev/engine_room/flywheel/impl/compat/OptifineCompat.java @@ -2,7 +2,7 @@ import java.lang.reflect.Field; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import dev.engine_room.flywheel.impl.FlwImpl; diff --git a/common/src/main/java/dev/engine_room/flywheel/impl/compat/SodiumCompat.java b/common/src/main/java/dev/engine_room/flywheel/impl/compat/SodiumCompat.java index 130272c43..32cccd7f9 100644 --- a/common/src/main/java/dev/engine_room/flywheel/impl/compat/SodiumCompat.java +++ b/common/src/main/java/dev/engine_room/flywheel/impl/compat/SodiumCompat.java @@ -1,6 +1,6 @@ package dev.engine_room.flywheel.impl.compat; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import dev.engine_room.flywheel.api.visualization.BlockEntityVisualizer; import dev.engine_room.flywheel.impl.FlwImpl; diff --git a/common/src/main/java/dev/engine_room/flywheel/impl/event/RenderContextImpl.java b/common/src/main/java/dev/engine_room/flywheel/impl/event/RenderContextImpl.java index 5b52009d5..c2748a363 100644 --- a/common/src/main/java/dev/engine_room/flywheel/impl/event/RenderContextImpl.java +++ b/common/src/main/java/dev/engine_room/flywheel/impl/event/RenderContextImpl.java @@ -4,18 +4,21 @@ import org.joml.Matrix4fc; import dev.engine_room.flywheel.api.backend.RenderContext; -import net.minecraft.client.Camera; import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.client.renderer.LevelRenderer; import net.minecraft.client.renderer.RenderBuffers; +import net.minecraft.client.renderer.state.level.CameraRenderState; +import net.minecraft.client.renderer.state.level.LevelRenderState; public record RenderContextImpl(LevelRenderer renderer, ClientLevel level, RenderBuffers buffers, Matrix4fc modelView, - Matrix4fc projection, Matrix4fc viewProjection, Camera camera, - float partialTick) implements RenderContext { - public static RenderContextImpl create(LevelRenderer renderer, ClientLevel level, RenderBuffers buffers, Matrix4fc modelView, Matrix4f projection, Camera camera, float partialTick) { + Matrix4fc projection, Matrix4fc viewProjection, CameraRenderState cameraRenderState, + LevelRenderState levelRenderState, float partialTick) implements RenderContext { + public static ScopedValue PROJECTION_MATRIX_NO_BOB = ScopedValue.newInstance(); + + public static RenderContextImpl create(LevelRenderer renderer, ClientLevel level, RenderBuffers buffers, Matrix4fc modelView, Matrix4f projection, CameraRenderState cameraRenderState, LevelRenderState levelRenderState, float partialTick) { Matrix4f viewProjection = new Matrix4f(projection); viewProjection.mul(modelView); - return new RenderContextImpl(renderer, level, buffers, modelView, projection, viewProjection, camera, partialTick); + return new RenderContextImpl(renderer, level, buffers, modelView, projection, viewProjection, cameraRenderState, levelRenderState, partialTick); } } diff --git a/common/src/main/java/dev/engine_room/flywheel/impl/extension/BlockEntityTypeExtension.java b/common/src/main/java/dev/engine_room/flywheel/impl/extension/BlockEntityTypeExtension.java index b15f29c7a..93541d0c6 100644 --- a/common/src/main/java/dev/engine_room/flywheel/impl/extension/BlockEntityTypeExtension.java +++ b/common/src/main/java/dev/engine_room/flywheel/impl/extension/BlockEntityTypeExtension.java @@ -1,6 +1,6 @@ package dev.engine_room.flywheel.impl.extension; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import dev.engine_room.flywheel.api.visualization.BlockEntityVisualizer; import net.minecraft.world.level.block.entity.BlockEntity; diff --git a/common/src/main/java/dev/engine_room/flywheel/impl/extension/EntityTypeExtension.java b/common/src/main/java/dev/engine_room/flywheel/impl/extension/EntityTypeExtension.java index 2b0f8927f..5aa6cc4da 100644 --- a/common/src/main/java/dev/engine_room/flywheel/impl/extension/EntityTypeExtension.java +++ b/common/src/main/java/dev/engine_room/flywheel/impl/extension/EntityTypeExtension.java @@ -1,6 +1,6 @@ package dev.engine_room.flywheel.impl.extension; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import dev.engine_room.flywheel.api.visualization.EntityVisualizer; import net.minecraft.world.entity.Entity; diff --git a/common/src/main/java/dev/engine_room/flywheel/impl/layout/LayoutBuilderImpl.java b/common/src/main/java/dev/engine_room/flywheel/impl/layout/LayoutBuilderImpl.java index fbd2f8178..4472fee51 100644 --- a/common/src/main/java/dev/engine_room/flywheel/impl/layout/LayoutBuilderImpl.java +++ b/common/src/main/java/dev/engine_room/flywheel/impl/layout/LayoutBuilderImpl.java @@ -5,7 +5,7 @@ import java.util.Locale; import java.util.Set; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import org.jetbrains.annotations.Range; import dev.engine_room.flywheel.api.layout.ElementType; diff --git a/common/src/main/java/dev/engine_room/flywheel/impl/mixin/BlockEntityTypeMixin.java b/common/src/main/java/dev/engine_room/flywheel/impl/mixin/BlockEntityTypeMixin.java index c429dae95..90c879844 100644 --- a/common/src/main/java/dev/engine_room/flywheel/impl/mixin/BlockEntityTypeMixin.java +++ b/common/src/main/java/dev/engine_room/flywheel/impl/mixin/BlockEntityTypeMixin.java @@ -1,6 +1,6 @@ package dev.engine_room.flywheel.impl.mixin; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Unique; diff --git a/common/src/main/java/dev/engine_room/flywheel/impl/mixin/EntityRendererAccessor.java b/common/src/main/java/dev/engine_room/flywheel/impl/mixin/EntityRendererAccessor.java new file mode 100644 index 000000000..2c4ad5a05 --- /dev/null +++ b/common/src/main/java/dev/engine_room/flywheel/impl/mixin/EntityRendererAccessor.java @@ -0,0 +1,17 @@ +package dev.engine_room.flywheel.impl.mixin; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Invoker; + +import net.minecraft.client.renderer.entity.EntityRenderer; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.phys.AABB; + +@Mixin(EntityRenderer.class) +public interface EntityRendererAccessor { + @Invoker("affectedByCulling") + boolean flywheel$affectedByCulling(T entity); + + @Invoker("getBoundingBoxForCulling") + AABB flywheel$getBoundingBoxForCulling(T entity); +} diff --git a/common/src/main/java/dev/engine_room/flywheel/impl/mixin/EntityTypeMixin.java b/common/src/main/java/dev/engine_room/flywheel/impl/mixin/EntityTypeMixin.java index 91676872f..5d220ee7e 100644 --- a/common/src/main/java/dev/engine_room/flywheel/impl/mixin/EntityTypeMixin.java +++ b/common/src/main/java/dev/engine_room/flywheel/impl/mixin/EntityTypeMixin.java @@ -1,6 +1,6 @@ package dev.engine_room.flywheel.impl.mixin; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Unique; diff --git a/common/src/main/java/dev/engine_room/flywheel/impl/mixin/GameRendererMixin.java b/common/src/main/java/dev/engine_room/flywheel/impl/mixin/GameRendererMixin.java new file mode 100644 index 000000000..675a5aedd --- /dev/null +++ b/common/src/main/java/dev/engine_room/flywheel/impl/mixin/GameRendererMixin.java @@ -0,0 +1,29 @@ +package dev.engine_room.flywheel.impl.mixin; + +import org.joml.Matrix4f; +import org.joml.Matrix4fc; +import org.joml.Vector4f; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; + +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; +import com.llamalad7.mixinextras.sugar.Local; +import com.mojang.blaze3d.buffers.GpuBufferSlice; +import com.mojang.blaze3d.resource.GraphicsResourceAllocator; + +import dev.engine_room.flywheel.impl.event.RenderContextImpl; +import net.minecraft.client.DeltaTracker; +import net.minecraft.client.renderer.GameRenderer; +import net.minecraft.client.renderer.LevelRenderer; +import net.minecraft.client.renderer.chunk.ChunkSectionsToRender; +import net.minecraft.client.renderer.state.level.CameraRenderState; + +@Mixin(GameRenderer.class) +public class GameRendererMixin { + @WrapOperation(method = "renderLevel", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/LevelRenderer;renderLevel(Lcom/mojang/blaze3d/resource/GraphicsResourceAllocator;Lnet/minecraft/client/DeltaTracker;ZLnet/minecraft/client/renderer/state/level/CameraRenderState;Lorg/joml/Matrix4fc;Lcom/mojang/blaze3d/buffers/GpuBufferSlice;Lorg/joml/Vector4f;ZLnet/minecraft/client/renderer/chunk/ChunkSectionsToRender;)V")) + private void extractProjectionMatrixNoBob(LevelRenderer instance, GraphicsResourceAllocator resourceAllocator, DeltaTracker deltaTracker, boolean renderOutline, CameraRenderState cameraState, Matrix4fc modelViewMatrix, GpuBufferSlice terrainFog, Vector4f fogColor, boolean shouldRenderSky, ChunkSectionsToRender chunkSectionsToRender, Operation original, @Local(name = "projectionMatrix") Matrix4f projectionMatrix) { + ScopedValue.where(RenderContextImpl.PROJECTION_MATRIX_NO_BOB, projectionMatrix) + .run(() -> original.call(instance, resourceAllocator, deltaTracker, renderOutline, cameraState, modelViewMatrix, terrainFog, fogColor, shouldRenderSky, chunkSectionsToRender)); + } +} diff --git a/common/src/main/java/dev/engine_room/flywheel/impl/mixin/LevelRendererMixin.java b/common/src/main/java/dev/engine_room/flywheel/impl/mixin/LevelRendererMixin.java index 8fcccfdf6..c9440d6b4 100644 --- a/common/src/main/java/dev/engine_room/flywheel/impl/mixin/LevelRendererMixin.java +++ b/common/src/main/java/dev/engine_room/flywheel/impl/mixin/LevelRendererMixin.java @@ -1,9 +1,12 @@ package dev.engine_room.flywheel.impl.mixin; +import java.util.Iterator; import java.util.SortedSet; -import org.jetbrains.annotations.Nullable; import org.joml.Matrix4f; +import org.joml.Matrix4fc; +import org.joml.Vector4f; +import org.jspecify.annotations.Nullable; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; @@ -12,21 +15,23 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import com.mojang.blaze3d.vertex.PoseStack; +import com.google.common.collect.Iterators; +import com.llamalad7.mixinextras.injector.ModifyExpressionValue; +import com.mojang.blaze3d.buffers.GpuBufferSlice; +import com.mojang.blaze3d.resource.GraphicsResourceAllocator; import dev.engine_room.flywheel.api.visualization.VisualizationManager; import dev.engine_room.flywheel.impl.FlwImplXplat; import dev.engine_room.flywheel.impl.event.RenderContextImpl; import dev.engine_room.flywheel.lib.visualization.VisualizationHelper; import it.unimi.dsi.fastutil.longs.Long2ObjectMap; -import net.minecraft.client.Camera; import net.minecraft.client.DeltaTracker; import net.minecraft.client.multiplayer.ClientLevel; -import net.minecraft.client.renderer.GameRenderer; import net.minecraft.client.renderer.LevelRenderer; -import net.minecraft.client.renderer.LightTexture; -import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.RenderBuffers; +import net.minecraft.client.renderer.chunk.ChunkSectionsToRender; +import net.minecraft.client.renderer.state.level.CameraRenderState; +import net.minecraft.client.renderer.state.level.LevelRenderState; import net.minecraft.server.level.BlockDestructionProgress; import net.minecraft.world.entity.Entity; @@ -44,14 +49,18 @@ abstract class LevelRendererMixin { @Final private Long2ObjectMap> destructionProgress; + @Shadow + @Final + private LevelRenderState levelRenderState; + @Unique @Nullable private RenderContextImpl flywheel$renderContext; - // @Inject(method = "renderLevel", at = @At("HEAD")) - @Inject(method = "renderLevel", at = @At(value = "INVOKE_ASSIGN", target = "Lnet/minecraft/world/level/lighting/LevelLightEngine;runLightUpdates()I")) - private void flywheel$beginRender(DeltaTracker deltaTracker, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, LightTexture lightTexture, Matrix4f modelMatrix, Matrix4f projectionMatrix, CallbackInfo ci) { - flywheel$renderContext = RenderContextImpl.create((LevelRenderer) (Object) this, level, renderBuffers, modelMatrix, projectionMatrix, camera, deltaTracker.getGameTimeDeltaPartialTick(false)); + @Inject(method = "renderLevel", at = @At("HEAD")) + private void flywheel$beginRender(GraphicsResourceAllocator resourceAllocator, DeltaTracker deltaTracker, boolean renderOutline, CameraRenderState cameraState, Matrix4fc modelViewMatrix, GpuBufferSlice terrainFog, Vector4f fogColor, boolean shouldRenderSky, ChunkSectionsToRender chunkSectionsToRender, CallbackInfo ci) { + Matrix4f projectionMatrix = RenderContextImpl.PROJECTION_MATRIX_NO_BOB.get(); + flywheel$renderContext = RenderContextImpl.create((LevelRenderer) (Object) this, level, renderBuffers, modelViewMatrix, projectionMatrix, cameraState, levelRenderState, deltaTracker.getGameTimeDeltaPartialTick(false)); VisualizationManager manager = VisualizationManager.get(level); if (manager != null) { @@ -71,7 +80,7 @@ abstract class LevelRendererMixin { } } - @Inject(method = "renderLevel", at = @At(value = "INVOKE_STRING", target = "Lnet/minecraft/util/profiling/ProfilerFiller;popPush(Ljava/lang/String;)V", args = "ldc=blockentities")) + @Inject(method = "lambda$addMainPass$0", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/LevelRenderer;submitBlockEntities(Lcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/state/level/LevelRenderState;Lnet/minecraft/client/renderer/SubmitNodeStorage;)V")) private void flywheel$beforeBlockEntities(CallbackInfo ci) { if (flywheel$renderContext != null) { VisualizationManager manager = VisualizationManager.get(level); @@ -81,7 +90,7 @@ abstract class LevelRendererMixin { } } - @Inject(method = "renderLevel", at = @At(value = "INVOKE_STRING", target = "Lnet/minecraft/util/profiling/ProfilerFiller;popPush(Ljava/lang/String;)V", args = "ldc=destroyProgress")) + @Inject(method = "lambda$addMainPass$0", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/LevelRenderer;submitBlockDestroyAnimation(Lcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/SubmitNodeCollector;Lnet/minecraft/client/renderer/state/level/LevelRenderState;)V")) private void flywheel$beforeRenderCrumbling(CallbackInfo ci) { if (flywheel$renderContext != null) { VisualizationManager manager = VisualizationManager.get(level); @@ -91,10 +100,9 @@ abstract class LevelRendererMixin { } } - @Inject(method = "renderEntity", at = @At("HEAD"), cancellable = true) - private void flywheel$decideNotToRenderEntity(Entity entity, double camX, double camY, double camZ, float partialTick, PoseStack poseStack, MultiBufferSource bufferSource, CallbackInfo ci) { - if (VisualizationManager.supportsVisualization(entity.level()) && VisualizationHelper.skipVanillaRender(entity)) { - ci.cancel(); - } + @ModifyExpressionValue(method = "extractVisibleEntities", at = @At(value = "INVOKE", target = "Ljava/lang/Iterable;iterator()Ljava/util/Iterator;")) + private Iterator flywheel$decideNotToRenderEntity(Iterator original) { + return Iterators.filter(original, entity -> !(VisualizationManager.supportsVisualization(entity.level()) && + VisualizationHelper.skipVanillaRender(entity))); } } diff --git a/common/src/main/java/dev/engine_room/flywheel/impl/mixin/PoseStackAccessor.java b/common/src/main/java/dev/engine_room/flywheel/impl/mixin/PoseStackAccessor.java deleted file mode 100644 index 22478d2a3..000000000 --- a/common/src/main/java/dev/engine_room/flywheel/impl/mixin/PoseStackAccessor.java +++ /dev/null @@ -1,14 +0,0 @@ -package dev.engine_room.flywheel.impl.mixin; - -import java.util.Deque; - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Accessor; - -import com.mojang.blaze3d.vertex.PoseStack; - -@Mixin(PoseStack.class) -public interface PoseStackAccessor { - @Accessor("poseStack") - Deque flywheel$getPoseStack(); -} diff --git a/common/src/main/java/dev/engine_room/flywheel/impl/mixin/fix/FixFabulousDepthMixin.java b/common/src/main/java/dev/engine_room/flywheel/impl/mixin/fix/FixFabulousDepthMixin.java index e8c79651d..69cc330de 100644 --- a/common/src/main/java/dev/engine_room/flywheel/impl/mixin/fix/FixFabulousDepthMixin.java +++ b/common/src/main/java/dev/engine_room/flywheel/impl/mixin/fix/FixFabulousDepthMixin.java @@ -1,18 +1,14 @@ package dev.engine_room.flywheel.impl.mixin.fix; import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -import com.mojang.blaze3d.platform.GlStateManager; import net.minecraft.client.renderer.LevelRenderer; @Mixin(LevelRenderer.class) abstract class FixFabulousDepthMixin { - @Inject(method = "renderLevel", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/PostChain;process(F)V", ordinal = 1)) - private void flywheel$disableTransparencyShaderDepth(CallbackInfo ci) { - GlStateManager._depthMask(false); - } + // TODO 1.21.11: Is this still needed? +// @Inject(method = "renderLevel", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/PostChain;process(F)V", ordinal = 1)) +// private void flywheel$disableTransparencyShaderDepth(CallbackInfo ci) { +// GlStateManager._depthMask(false); +// } } diff --git a/common/src/main/java/dev/engine_room/flywheel/impl/mixin/visualmanage/BlockEntityMixin.java b/common/src/main/java/dev/engine_room/flywheel/impl/mixin/visualmanage/BlockEntityMixin.java index 5d6ae99ef..86cb2104a 100644 --- a/common/src/main/java/dev/engine_room/flywheel/impl/mixin/visualmanage/BlockEntityMixin.java +++ b/common/src/main/java/dev/engine_room/flywheel/impl/mixin/visualmanage/BlockEntityMixin.java @@ -1,6 +1,6 @@ package dev.engine_room.flywheel.impl.mixin.visualmanage; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; diff --git a/common/src/main/java/dev/engine_room/flywheel/impl/registry/IdRegistryImpl.java b/common/src/main/java/dev/engine_room/flywheel/impl/registry/IdRegistryImpl.java index 3ea57ea30..b2df5eeeb 100644 --- a/common/src/main/java/dev/engine_room/flywheel/impl/registry/IdRegistryImpl.java +++ b/common/src/main/java/dev/engine_room/flywheel/impl/registry/IdRegistryImpl.java @@ -4,7 +4,7 @@ import java.util.Iterator; import java.util.Set; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import org.jetbrains.annotations.UnmodifiableView; import dev.engine_room.flywheel.api.registry.IdRegistry; @@ -20,14 +20,14 @@ import it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap; import it.unimi.dsi.fastutil.objects.ReferenceCollection; import it.unimi.dsi.fastutil.objects.ReferenceCollections; -import net.minecraft.resources.ResourceLocation; +import net.minecraft.resources.Identifier; public class IdRegistryImpl implements IdRegistry { private static final ObjectList> ALL = new ObjectArrayList<>(); - private final Object2ReferenceMap map = Object2ReferenceMaps.synchronize(new Object2ReferenceOpenHashMap<>()); - private final Reference2ObjectMap reverseMap = Reference2ObjectMaps.synchronize(new Reference2ObjectOpenHashMap<>()); - private final ObjectSet keysView = ObjectSets.unmodifiable(map.keySet()); + private final Object2ReferenceMap map = Object2ReferenceMaps.synchronize(new Object2ReferenceOpenHashMap<>()); + private final Reference2ObjectMap reverseMap = Reference2ObjectMaps.synchronize(new Reference2ObjectOpenHashMap<>()); + private final ObjectSet keysView = ObjectSets.unmodifiable(map.keySet()); private final ReferenceCollection valuesView = ReferenceCollections.unmodifiable(map.values()); private boolean frozen; @@ -36,7 +36,7 @@ public IdRegistryImpl() { } @Override - public void register(ResourceLocation id, T object) { + public void register(Identifier id, T object) { if (frozen) { throw new IllegalStateException("Cannot register to frozen registry!"); } @@ -44,32 +44,32 @@ public void register(ResourceLocation id, T object) { if (oldValue != null) { throw new IllegalArgumentException("Cannot override registration for ID '" + id + "'!"); } - ResourceLocation oldId = reverseMap.put(object, id); + Identifier oldId = reverseMap.put(object, id); if (oldId != null) { throw new IllegalArgumentException("Cannot override ID '" + id + "' with registration for ID '" + oldId + "'!"); } } @Override - public S registerAndGet(ResourceLocation id, S object) { + public S registerAndGet(Identifier id, S object) { register(id, object); return object; } @Override @Nullable - public T get(ResourceLocation id) { + public T get(Identifier id) { return map.get(id); } @Override @Nullable - public ResourceLocation getId(T object) { + public Identifier getId(T object) { return reverseMap.get(object); } @Override - public T getOrThrow(ResourceLocation id) { + public T getOrThrow(Identifier id) { T object = get(id); if (object == null) { throw new IllegalArgumentException("Could not find object for ID '" + id + "'!"); @@ -78,8 +78,8 @@ public T getOrThrow(ResourceLocation id) { } @Override - public ResourceLocation getIdOrThrow(T object) { - ResourceLocation id = getId(object); + public Identifier getIdOrThrow(T object) { + Identifier id = getId(object); if (id == null) { throw new IllegalArgumentException("Could not find ID for object!"); } @@ -88,7 +88,7 @@ public ResourceLocation getIdOrThrow(T object) { @Override @UnmodifiableView - public Set getAllIds() { + public Set getAllIds() { return keysView; } diff --git a/common/src/main/java/dev/engine_room/flywheel/impl/task/Flag.java b/common/src/main/java/dev/engine_room/flywheel/impl/task/Flag.java index e726f84c9..4807e2455 100644 --- a/common/src/main/java/dev/engine_room/flywheel/impl/task/Flag.java +++ b/common/src/main/java/dev/engine_room/flywheel/impl/task/Flag.java @@ -2,7 +2,7 @@ import java.util.concurrent.atomic.AtomicBoolean; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; /** * A flag that can be raised and lowered in a thread-safe fashion. diff --git a/common/src/main/java/dev/engine_room/flywheel/impl/task/ParallelTaskExecutor.java b/common/src/main/java/dev/engine_room/flywheel/impl/task/ParallelTaskExecutor.java index 066d2ba82..e52b710b1 100644 --- a/common/src/main/java/dev/engine_room/flywheel/impl/task/ParallelTaskExecutor.java +++ b/common/src/main/java/dev/engine_room/flywheel/impl/task/ParallelTaskExecutor.java @@ -84,8 +84,7 @@ public void stopWorkers() { for (Thread thread : threads) { try { thread.join(); - } catch (InterruptedException e) { - // + } catch (InterruptedException _) { } } @@ -188,6 +187,11 @@ private void processTask(Runnable task) { } } + @Override + public void shutdown() { + stopWorkers(); + } + private class WorkerThread extends Thread { private int errorLogLatch = MAX_ERRORS_LOGGED_PER_THREAD; diff --git a/common/src/main/java/dev/engine_room/flywheel/impl/task/SerialTaskExecutor.java b/common/src/main/java/dev/engine_room/flywheel/impl/task/SerialTaskExecutor.java index 1eaffdff3..6470ba985 100644 --- a/common/src/main/java/dev/engine_room/flywheel/impl/task/SerialTaskExecutor.java +++ b/common/src/main/java/dev/engine_room/flywheel/impl/task/SerialTaskExecutor.java @@ -31,4 +31,8 @@ public boolean syncWhile(BooleanSupplier cond) { @Override public void syncPoint() { } + + @Override + public void shutdown() { + } } diff --git a/common/src/main/java/dev/engine_room/flywheel/impl/task/TaskExecutorImpl.java b/common/src/main/java/dev/engine_room/flywheel/impl/task/TaskExecutorImpl.java index 99eda8aa4..fcf07ec42 100644 --- a/common/src/main/java/dev/engine_room/flywheel/impl/task/TaskExecutorImpl.java +++ b/common/src/main/java/dev/engine_room/flywheel/impl/task/TaskExecutorImpl.java @@ -38,4 +38,12 @@ public interface TaskExecutorImpl extends TaskExecutor { * try to use {@link #syncUntil(BooleanSupplier) syncUntil}. */ void syncPoint(); + + /** + * Start shutting down this task executor. + *
+ * Any attempts to use the current executor after calling this will result in + * an exception being thrown unless the executor has been started again. + */ + void shutdown(); } diff --git a/common/src/main/java/dev/engine_room/flywheel/impl/visual/DynamicVisualContextImpl.java b/common/src/main/java/dev/engine_room/flywheel/impl/visual/DynamicVisualContextImpl.java index 09803bdae..fe9f13162 100644 --- a/common/src/main/java/dev/engine_room/flywheel/impl/visual/DynamicVisualContextImpl.java +++ b/common/src/main/java/dev/engine_room/flywheel/impl/visual/DynamicVisualContextImpl.java @@ -4,8 +4,8 @@ import dev.engine_room.flywheel.api.visual.DistanceUpdateLimiter; import dev.engine_room.flywheel.api.visual.DynamicVisual; -import net.minecraft.client.Camera; +import net.minecraft.client.renderer.state.level.CameraRenderState; -public record DynamicVisualContextImpl(Camera camera, FrustumIntersection frustum, float partialTick, - DistanceUpdateLimiter limiter) implements DynamicVisual.Context { +public record DynamicVisualContextImpl(CameraRenderState cameraRenderState, FrustumIntersection frustum, float partialTick, + DistanceUpdateLimiter limiter) implements DynamicVisual.Context { } diff --git a/common/src/main/java/dev/engine_room/flywheel/impl/visualization/VisualizationManagerImpl.java b/common/src/main/java/dev/engine_room/flywheel/impl/visualization/VisualizationManagerImpl.java index 9ad215370..f89230fd5 100644 --- a/common/src/main/java/dev/engine_room/flywheel/impl/visualization/VisualizationManagerImpl.java +++ b/common/src/main/java/dev/engine_room/flywheel/impl/visualization/VisualizationManagerImpl.java @@ -5,9 +5,9 @@ import java.util.SortedSet; import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.Nullable; import org.joml.FrustumIntersection; import org.joml.Matrix4f; +import org.jspecify.annotations.Nullable; import dev.engine_room.flywheel.api.backend.BackendManager; import dev.engine_room.flywheel.api.backend.Engine; @@ -112,7 +112,7 @@ private LateInit(LevelAccessor level) { var update = MapContextPlan.map(this::createVisualFrameContext) .to(NestedPlan.of(blockEntities.framePlan(visualizationContext), entities.framePlan(visualizationContext), effects.framePlan(visualizationContext))); - framePlan = IfElsePlan.on((RenderContext ctx) -> engine.updateRenderOrigin(ctx.camera())) + framePlan = IfElsePlan.on((RenderContext ctx) -> engine.updateRenderOrigin(ctx.cameraRenderState())) .ifTrue(recreate) .ifFalse(update) .plan() @@ -134,14 +134,13 @@ private LateInit(LevelAccessor level) { private DynamicVisual.Context createVisualFrameContext(RenderContext ctx) { Vec3i renderOrigin = engine.renderOrigin(); - var cameraPos = ctx.camera() - .getPosition(); + var cameraPos = ctx.cameraRenderState().pos; Matrix4f viewProjection = new Matrix4f(ctx.viewProjection()); viewProjection.translate((float) (renderOrigin.getX() - cameraPos.x), (float) (renderOrigin.getY() - cameraPos.y), (float) (renderOrigin.getZ() - cameraPos.z)); FrustumIntersection frustum = new FrustumIntersection(viewProjection); - return new DynamicVisualContextImpl(ctx.camera(), frustum, ctx.partialTick(), frameLimiter); + return new DynamicVisualContextImpl(ctx.cameraRenderState(), frustum, ctx.partialTick(), frameLimiter); } } diff --git a/common/src/main/java/dev/engine_room/flywheel/impl/visualization/VisualizerRegistryImpl.java b/common/src/main/java/dev/engine_room/flywheel/impl/visualization/VisualizerRegistryImpl.java index 43d605ed0..30fc255c6 100644 --- a/common/src/main/java/dev/engine_room/flywheel/impl/visualization/VisualizerRegistryImpl.java +++ b/common/src/main/java/dev/engine_room/flywheel/impl/visualization/VisualizerRegistryImpl.java @@ -1,6 +1,6 @@ package dev.engine_room.flywheel.impl.visualization; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import dev.engine_room.flywheel.api.visualization.BlockEntityVisualizer; import dev.engine_room.flywheel.api.visualization.EntityVisualizer; diff --git a/common/src/main/java/dev/engine_room/flywheel/impl/visualization/storage/BlockEntityStorage.java b/common/src/main/java/dev/engine_room/flywheel/impl/visualization/storage/BlockEntityStorage.java index 86af9070b..b56518480 100644 --- a/common/src/main/java/dev/engine_room/flywheel/impl/visualization/storage/BlockEntityStorage.java +++ b/common/src/main/java/dev/engine_room/flywheel/impl/visualization/storage/BlockEntityStorage.java @@ -1,6 +1,6 @@ package dev.engine_room.flywheel.impl.visualization.storage; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import dev.engine_room.flywheel.api.visual.BlockEntityVisual; import dev.engine_room.flywheel.api.visualization.VisualizationContext; diff --git a/common/src/main/java/dev/engine_room/flywheel/impl/visualization/storage/Storage.java b/common/src/main/java/dev/engine_room/flywheel/impl/visualization/storage/Storage.java index 8bc84204b..05190c541 100644 --- a/common/src/main/java/dev/engine_room/flywheel/impl/visualization/storage/Storage.java +++ b/common/src/main/java/dev/engine_room/flywheel/impl/visualization/storage/Storage.java @@ -5,7 +5,7 @@ import java.util.List; import java.util.Map; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import dev.engine_room.flywheel.api.task.Plan; import dev.engine_room.flywheel.api.visual.DynamicVisual; diff --git a/common/src/main/resources/flywheel.impl.mixins.json b/common/src/main/resources/flywheel.impl.mixins.json index 9b576d52d..ed625203b 100644 --- a/common/src/main/resources/flywheel.impl.mixins.json +++ b/common/src/main/resources/flywheel.impl.mixins.json @@ -2,17 +2,17 @@ "required": true, "minVersion": "0.8", "package": "dev.engine_room.flywheel.impl.mixin", - "compatibilityLevel": "JAVA_21", - "refmap": "flywheel.refmap.json", + "compatibilityLevel": "JAVA_25", "client": [ "BlockEntityTypeMixin", "ClientChunkCacheMixin", + "EntityRendererAccessor", "EntityTypeMixin", + "GameRendererMixin", "LevelMixin", "LevelRendererMixin", "MinecraftMixin", "ModelPartAccessor", - "PoseStackAccessor", "PoseStackMixin", "fix.FixFabulousDepthMixin", "visualmanage.BlockEntityMixin", diff --git a/common/src/test/java/dev/engine_room/flywheel/backend/glsl/MockShaderSources.java b/common/src/test/java/dev/engine_room/flywheel/backend/glsl/MockShaderSources.java index 4403088a5..d2a4d4bd6 100644 --- a/common/src/test/java/dev/engine_room/flywheel/backend/glsl/MockShaderSources.java +++ b/common/src/test/java/dev/engine_room/flywheel/backend/glsl/MockShaderSources.java @@ -7,56 +7,56 @@ import java.util.List; import java.util.Map; -import net.minecraft.resources.ResourceLocation; +import net.minecraft.resources.Identifier; public class MockShaderSources { - private final Map sources = new HashMap<>(); - private final Map cache = new HashMap<>(); - private final Deque findStack = new ArrayDeque<>(); + private final Map sources = new HashMap<>(); + private final Map cache = new HashMap<>(); + private final Deque findStack = new ArrayDeque<>(); public MockShaderSources() { } - public void add(ResourceLocation loc, String source) { + public void add(Identifier loc, String source) { sources.put(loc, source); } - public LoadResult find(ResourceLocation location) { - if (findStack.contains(location)) { - // Make a copy of the find stack with the offending location added on top to show the full path. - findStack.addLast(location); + public LoadResult find(Identifier id) { + if (findStack.contains(id)) { + // Make a copy of the find stack with the offending id added on top to show the full path. + findStack.addLast(id); var copy = List.copyOf(findStack); findStack.removeLast(); - return new LoadResult.Failure(new LoadError.CircularDependency(location, copy)); + return new LoadResult.Failure(new LoadError.CircularDependency(id, copy)); } - findStack.addLast(location); + findStack.addLast(id); - LoadResult out = load(location); + LoadResult out = load(id); findStack.removeLast(); return out; } - private LoadResult load(ResourceLocation loc) { - var out = cache.get(loc); + private LoadResult load(Identifier id) { + var out = cache.get(id); if (out != null) { return out; } - var loadResult = _load(loc); + var loadResult = _load(id); - cache.put(loc, loadResult); + cache.put(id, loadResult); return loadResult; } - private LoadResult _load(ResourceLocation loc) { - var maybeFound = sources.get(loc); + private LoadResult _load(Identifier id) { + var maybeFound = sources.get(id); if (maybeFound == null) { - return new LoadResult.Failure(new LoadError.IOError(loc, new FileNotFoundException(loc.toString()))); + return new LoadResult.Failure(new LoadError.IOError(id, new FileNotFoundException(id.toString()))); } - return SourceFile.parse(this::find, loc, maybeFound); + return SourceFile.parse(this::find, id, maybeFound); } } diff --git a/common/src/test/java/dev/engine_room/flywheel/backend/glsl/TestBase.java b/common/src/test/java/dev/engine_room/flywheel/backend/glsl/TestBase.java index 1e2860eb1..33dc85c7b 100644 --- a/common/src/test/java/dev/engine_room/flywheel/backend/glsl/TestBase.java +++ b/common/src/test/java/dev/engine_room/flywheel/backend/glsl/TestBase.java @@ -6,20 +6,20 @@ import java.util.List; -import dev.engine_room.flywheel.lib.util.ResourceUtil; -import net.minecraft.resources.ResourceLocation; +import dev.engine_room.flywheel.lib.util.IdentifierUtil; +import net.minecraft.resources.Identifier; public class TestBase { - public static final ResourceLocation FLW_A = ResourceUtil.rl("a.glsl"); - public static final ResourceLocation FLW_B = ResourceUtil.rl("b.glsl"); - public static final ResourceLocation FLW_C = ResourceUtil.rl("c.glsl"); + public static final Identifier FLW_A = IdentifierUtil.id("a.glsl"); + public static final Identifier FLW_B = IdentifierUtil.id("b.glsl"); + public static final Identifier FLW_C = IdentifierUtil.id("c.glsl"); public static T assertSingletonList(List list) { assertEquals(1, list.size()); return list.get(0); } - public static E findAndAssertError(Class clazz, MockShaderSources sources, ResourceLocation loc) { + public static E findAndAssertError(Class clazz, MockShaderSources sources, Identifier loc) { var result = sources.find(loc); var failure = assertInstanceOf(LoadResult.Failure.class, result); return assertInstanceOf(clazz, failure.error()); @@ -36,12 +36,12 @@ static E assertSimpleNestedErrorsToDepth(Class finalErr return assertInstanceOf(finalErrType, pair.getSecond()); } - public static SourceFile findAndAssertSuccess(MockShaderSources sources, ResourceLocation loc) { - var result = sources.find(loc); - return assertSuccessAndUnwrap(loc, result); + public static SourceFile findAndAssertSuccess(MockShaderSources sources, Identifier id) { + var result = sources.find(id); + return assertSuccessAndUnwrap(id, result); } - public static SourceFile assertSuccessAndUnwrap(ResourceLocation expectedName, LoadResult result) { + public static SourceFile assertSuccessAndUnwrap(Identifier expectedName, LoadResult result) { assertInstanceOf(LoadResult.Success.class, result); var file = result.unwrap(); diff --git a/common/src/test/java/dev/engine_room/flywheel/backend/glsl/TestErrorMessages.java b/common/src/test/java/dev/engine_room/flywheel/backend/glsl/TestErrorMessages.java index f1eff161d..26c06f476 100644 --- a/common/src/test/java/dev/engine_room/flywheel/backend/glsl/TestErrorMessages.java +++ b/common/src/test/java/dev/engine_room/flywheel/backend/glsl/TestErrorMessages.java @@ -7,7 +7,7 @@ import org.junit.jupiter.api.Test; import dev.engine_room.flywheel.backend.glsl.error.ErrorBuilder; -import net.minecraft.resources.ResourceLocation; +import net.minecraft.resources.Identifier; public class TestErrorMessages extends TestBase { @BeforeAll @@ -54,14 +54,14 @@ void testNestedIncludeMsg() { """, sources, FLW_A); } - public static void assertErrorMatches(String expected, MockShaderSources sources, ResourceLocation loc) { - var message = assertErrorAndGetMessage(sources, loc).build(); + public static void assertErrorMatches(String expected, MockShaderSources sources, Identifier id) { + var message = assertErrorAndGetMessage(sources, id).build(); assertEquals(expected.trim(), message.trim()); } - public static ErrorBuilder assertErrorAndGetMessage(MockShaderSources sources, ResourceLocation loc) { - var result = sources.find(loc); + public static ErrorBuilder assertErrorAndGetMessage(MockShaderSources sources, Identifier id) { + var result = sources.find(id); var failure = assertInstanceOf(LoadResult.Failure.class, result); return failure.error() .generateMessage(); diff --git a/common/src/test/java/dev/engine_room/flywheel/backend/glsl/TestShaderSourceLoading.java b/common/src/test/java/dev/engine_room/flywheel/backend/glsl/TestShaderSourceLoading.java index 57c635756..afbcb842a 100644 --- a/common/src/test/java/dev/engine_room/flywheel/backend/glsl/TestShaderSourceLoading.java +++ b/common/src/test/java/dev/engine_room/flywheel/backend/glsl/TestShaderSourceLoading.java @@ -48,7 +48,7 @@ void testMissingInclude() { var aErr = findAndAssertError(LoadError.IncludeError.class, sources, FLW_A); var ioErr = assertSimpleNestedErrorsToDepth(LoadError.IOError.class, aErr, 1); - assertEquals(FLW_B, ioErr.location()); + assertEquals(FLW_B, ioErr.id()); } @Test diff --git a/common/src/vanillin/java/dev/engine_room/vanillin/VanillaVisuals.java b/common/src/vanillin/java/dev/engine_room/vanillin/VanillaVisuals.java index db36bc8a1..c116f86ae 100644 --- a/common/src/vanillin/java/dev/engine_room/vanillin/VanillaVisuals.java +++ b/common/src/vanillin/java/dev/engine_room/vanillin/VanillaVisuals.java @@ -4,7 +4,7 @@ import java.util.List; import java.util.function.Consumer; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import dev.engine_room.vanillin.compose.ComposableEntityVisual; import dev.engine_room.vanillin.compose.ConfiguredElement; @@ -18,17 +18,13 @@ import dev.engine_room.vanillin.visuals.BellVisual; import dev.engine_room.vanillin.visuals.BlockDisplayVisual; import dev.engine_room.vanillin.visuals.ChestVisual; -import dev.engine_room.vanillin.visuals.ItemDisplayVisual; -import dev.engine_room.vanillin.visuals.ItemFrameVisual; -import dev.engine_room.vanillin.visuals.ItemVisual; import dev.engine_room.vanillin.visuals.MinecartVisual; import dev.engine_room.vanillin.visuals.ShulkerBoxVisual; import net.minecraft.client.model.geom.ModelLayerLocation; import net.minecraft.client.model.geom.ModelLayers; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EntityType; -import net.minecraft.world.entity.decoration.ItemFrame; -import net.minecraft.world.entity.vehicle.AbstractMinecart; +import net.minecraft.world.entity.vehicle.minecart.AbstractMinecart; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntityType; @@ -62,11 +58,12 @@ public static void init() { builder(EntityType.BLOCK_DISPLAY).factory(BlockDisplayVisual::new) .apply(STABLE); - composable(EntityType.ITEM_DISPLAY).with(element(VisualElements.ITEM_DISPLAY).build()) - .shouldVisualize((ctx, e) -> ItemDisplayVisual.shouldVisualize(e)) - .build() - .skipVanillaRender(ItemDisplayVisual::shouldVisualize) - .apply(EXPERIMENTAL); + // FIXME 1.21.11: port +// composable(EntityType.ITEM_DISPLAY).with(element(VisualElements.ITEM_DISPLAY).build()) +// .shouldVisualize((ctx, e) -> ItemDisplayVisual.shouldVisualize(e)) +// .build() +// .skipVanillaRender(ItemDisplayVisual::shouldVisualize) +// .apply(EXPERIMENTAL); minecart(EntityType.CHEST_MINECART, ModelLayers.CHEST_MINECART) .apply(STABLE); @@ -90,18 +87,20 @@ public static void init() { .skipVanillaRender(MinecartVisual::shouldSkipRender) .apply(STABLE); - itemFrame(EntityType.ITEM_FRAME).apply(EXPERIMENTAL); - itemFrame(EntityType.GLOW_ITEM_FRAME).apply(EXPERIMENTAL); - - composable(EntityType.ITEM).apply(VanillaVisuals::commonElements) - .with(element(VisualElements.FIRE).build()) - .with(element(VisualElements.SHADOW).configure(new ShadowElement.Config(0.15f, 0.75f)) - .build()) - .with(element(VisualElements.ITEM_ENTITY).build()) - .shouldVisualize(((ctx, entity) -> ItemVisual.isSupported(entity))) - .build() - .skipVanillaRender(ItemVisual::isSupported) - .apply(EXPERIMENTAL); + // FIXME 1.21.11: port +// itemFrame(EntityType.ITEM_FRAME).apply(EXPERIMENTAL); +// itemFrame(EntityType.GLOW_ITEM_FRAME).apply(EXPERIMENTAL); + + // FIXME 1.21.11: port +// composable(EntityType.ITEM).apply(VanillaVisuals::commonElements) +// .with(element(VisualElements.FIRE).build()) +// .with(element(VisualElements.SHADOW).configure(new ShadowElement.Config(0.15f, 0.75f)) +// .build()) +// .with(element(VisualElements.ITEM_ENTITY).build()) +// .shouldVisualize(((ctx, entity) -> ItemVisual.isSupported(entity))) +// .build() +// .skipVanillaRender(ItemVisual::isSupported) +// .apply(EXPERIMENTAL); } @@ -110,13 +109,14 @@ public static void commonElements(EntityBuilder builder) { .build()); } - public static EntityVisualizerBuilder itemFrame(EntityType type) { - return composable(type).apply(VanillaVisuals::commonElements) - .with(element(VisualElements.ITEM_FRAME).build()) - .shouldVisualize((ctx, entity) -> ItemFrameVisual.shouldVisualize(entity)) - .build() - .skipVanillaRender(ItemFrameVisual::shouldVisualize); - } + // FIXME 1.21.11: port +// public static EntityVisualizerBuilder itemFrame(EntityType type) { +// return composable(type).apply(VanillaVisuals::commonElements) +// .with(element(VisualElements.ITEM_FRAME).build()) +// .shouldVisualize((ctx, entity) -> ItemFrameVisual.shouldVisualize(entity)) +// .build() +// .skipVanillaRender(ItemFrameVisual::shouldVisualize); +// } public static EntityVisualizerBuilder minecart(EntityType type, ModelLayerLocation variant) { return composable(type).apply(VanillaVisuals::commonElements) diff --git a/common/src/vanillin/java/dev/engine_room/vanillin/Vanillin.java b/common/src/vanillin/java/dev/engine_room/vanillin/Vanillin.java index b6685402c..5c4d8c3d6 100644 --- a/common/src/vanillin/java/dev/engine_room/vanillin/Vanillin.java +++ b/common/src/vanillin/java/dev/engine_room/vanillin/Vanillin.java @@ -3,7 +3,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import net.minecraft.resources.ResourceLocation; +import net.minecraft.resources.Identifier; public class Vanillin { public static final String ID = "vanillin"; @@ -11,7 +11,7 @@ public class Vanillin { public static final Logger LOGGER = LoggerFactory.getLogger(ID); public static final Logger CONFIG_LOGGER = LoggerFactory.getLogger(ID + "/config"); - public static ResourceLocation rl(String path) { - return ResourceLocation.fromNamespaceAndPath(ID, path); + public static Identifier id(String path) { + return Identifier.fromNamespaceAndPath(ID, path); } } diff --git a/common/src/vanillin/java/dev/engine_room/vanillin/VanillinXplat.java b/common/src/vanillin/java/dev/engine_room/vanillin/VanillinXplat.java index 5234e9128..ff1305a3a 100644 --- a/common/src/vanillin/java/dev/engine_room/vanillin/VanillinXplat.java +++ b/common/src/vanillin/java/dev/engine_room/vanillin/VanillinXplat.java @@ -1,17 +1,11 @@ package dev.engine_room.vanillin; -import org.jetbrains.annotations.Nullable; - import dev.engine_room.flywheel.api.internal.DependencyInjection; -import net.minecraft.client.color.item.ItemColor; -import net.minecraft.world.item.Item; public interface VanillinXplat { VanillinXplat INSTANCE = DependencyInjection.load(VanillinXplat.class, "dev.engine_room.vanillin.VanillinXplatImpl"); boolean isDevelopmentEnvironment(); - @Nullable ItemColor itemColors(Item item); - boolean isModLoaded(String modId); } diff --git a/common/src/vanillin/java/dev/engine_room/vanillin/VisualElements.java b/common/src/vanillin/java/dev/engine_room/vanillin/VisualElements.java index 07ce6c628..2982e213c 100644 --- a/common/src/vanillin/java/dev/engine_room/vanillin/VisualElements.java +++ b/common/src/vanillin/java/dev/engine_room/vanillin/VisualElements.java @@ -5,18 +5,13 @@ import dev.engine_room.vanillin.elements.HitboxElement; import dev.engine_room.vanillin.elements.ShadowElement; import dev.engine_room.vanillin.visuals.BlockDisplayVisual; -import dev.engine_room.vanillin.visuals.ItemDisplayVisual; -import dev.engine_room.vanillin.visuals.ItemFrameVisual; -import dev.engine_room.vanillin.visuals.ItemVisual; import dev.engine_room.vanillin.visuals.MinecartVisual; import dev.engine_room.vanillin.visuals.TntMinecartVisual; import net.minecraft.client.model.geom.ModelLayerLocation; import net.minecraft.world.entity.Display; import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.decoration.ItemFrame; -import net.minecraft.world.entity.item.ItemEntity; -import net.minecraft.world.entity.vehicle.AbstractMinecart; -import net.minecraft.world.entity.vehicle.MinecartTNT; +import net.minecraft.world.entity.vehicle.minecart.AbstractMinecart; +import net.minecraft.world.entity.vehicle.minecart.MinecartTNT; // TODO: A way to get other elements in a visual, likely using these as keys. public class VisualElements { @@ -24,10 +19,12 @@ public class VisualElements { public static final VisualElement SHADOW = ShadowElement::new; public static final VisualElement.Unit FIRE = FireElement::new; - public static final VisualElement.Unit ITEM_ENTITY = ItemVisual::new; - public static final VisualElement.Unit ITEM_DISPLAY = ItemDisplayVisual::new; + // FIXME 1.21.11: port +// public static final VisualElement.Unit ITEM_ENTITY = ItemVisual::new; +// public static final VisualElement.Unit ITEM_DISPLAY = ItemDisplayVisual::new; public static final VisualElement.Unit BLOCK_DISPLAY = BlockDisplayVisual::new; - public static final VisualElement.Unit ITEM_FRAME = ItemFrameVisual::new; + // FIXME 1.21.11: port +// public static final VisualElement.Unit ITEM_FRAME = ItemFrameVisual::new; public static final VisualElement MINECART = MinecartVisual::new; public static final VisualElement.Unit TNT_MINECART = TntMinecartVisual::new; diff --git a/common/src/vanillin/java/dev/engine_room/vanillin/compose/ComposableEntityVisual.java b/common/src/vanillin/java/dev/engine_room/vanillin/compose/ComposableEntityVisual.java index 3f46ad8d1..8323cba84 100644 --- a/common/src/vanillin/java/dev/engine_room/vanillin/compose/ComposableEntityVisual.java +++ b/common/src/vanillin/java/dev/engine_room/vanillin/compose/ComposableEntityVisual.java @@ -1,6 +1,6 @@ package dev.engine_room.vanillin.compose; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import dev.engine_room.flywheel.api.visual.DynamicVisual; import dev.engine_room.flywheel.api.visual.EntityVisual; diff --git a/common/src/vanillin/java/dev/engine_room/vanillin/compose/ConfiguredElementImpl.java b/common/src/vanillin/java/dev/engine_room/vanillin/compose/ConfiguredElementImpl.java index e91b4fb20..d926ae51b 100644 --- a/common/src/vanillin/java/dev/engine_room/vanillin/compose/ConfiguredElementImpl.java +++ b/common/src/vanillin/java/dev/engine_room/vanillin/compose/ConfiguredElementImpl.java @@ -2,7 +2,7 @@ import java.util.Objects; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import dev.engine_room.flywheel.api.visual.Visual; import dev.engine_room.flywheel.api.visualization.VisualizationContext; diff --git a/common/src/vanillin/java/dev/engine_room/vanillin/config/BlockEntityVisualizerBuilder.java b/common/src/vanillin/java/dev/engine_room/vanillin/config/BlockEntityVisualizerBuilder.java index 8c8070999..f2ea30d43 100644 --- a/common/src/vanillin/java/dev/engine_room/vanillin/config/BlockEntityVisualizerBuilder.java +++ b/common/src/vanillin/java/dev/engine_room/vanillin/config/BlockEntityVisualizerBuilder.java @@ -3,7 +3,7 @@ import java.util.Objects; import java.util.function.Predicate; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import dev.engine_room.flywheel.lib.visualization.SimpleBlockEntityVisualizer; import net.minecraft.client.renderer.blockentity.BlockEntityRenderer; @@ -13,8 +13,7 @@ public class BlockEntityVisualizerBuilder { private final Configurator configurator; private final BlockEntityType type; - @Nullable - private SimpleBlockEntityVisualizer.Factory visualFactory; + private SimpleBlockEntityVisualizer.@Nullable Factory visualFactory; @Nullable private Predicate skipVanillaRender; diff --git a/common/src/vanillin/java/dev/engine_room/vanillin/config/Configurator.java b/common/src/vanillin/java/dev/engine_room/vanillin/config/Configurator.java index 28e97af02..56dbf61c6 100644 --- a/common/src/vanillin/java/dev/engine_room/vanillin/config/Configurator.java +++ b/common/src/vanillin/java/dev/engine_room/vanillin/config/Configurator.java @@ -5,7 +5,7 @@ import java.util.List; import java.util.Map; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import dev.engine_room.flywheel.api.visualization.BlockEntityVisualizer; import dev.engine_room.flywheel.api.visualization.EntityVisualizer; diff --git a/common/src/vanillin/java/dev/engine_room/vanillin/config/EntityVisualizerBuilder.java b/common/src/vanillin/java/dev/engine_room/vanillin/config/EntityVisualizerBuilder.java index 6e9a8aa54..0b1cd7dc3 100644 --- a/common/src/vanillin/java/dev/engine_room/vanillin/config/EntityVisualizerBuilder.java +++ b/common/src/vanillin/java/dev/engine_room/vanillin/config/EntityVisualizerBuilder.java @@ -3,7 +3,7 @@ import java.util.Objects; import java.util.function.Predicate; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import dev.engine_room.flywheel.lib.visualization.SimpleEntityVisualizer; import net.minecraft.client.renderer.entity.EntityRenderer; @@ -18,8 +18,7 @@ public final class EntityVisualizerBuilder { private final Configurator configurator; private final EntityType type; - @Nullable - private SimpleEntityVisualizer.Factory visualFactory; + private SimpleEntityVisualizer.@Nullable Factory visualFactory; @Nullable private Predicate skipVanillaRender; diff --git a/common/src/vanillin/java/dev/engine_room/vanillin/config/VisualOverrideValue.java b/common/src/vanillin/java/dev/engine_room/vanillin/config/VisualOverrideValue.java index 333e060d7..6bb0b0024 100644 --- a/common/src/vanillin/java/dev/engine_room/vanillin/config/VisualOverrideValue.java +++ b/common/src/vanillin/java/dev/engine_room/vanillin/config/VisualOverrideValue.java @@ -1,6 +1,6 @@ package dev.engine_room.vanillin.config; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; public enum VisualOverrideValue { DEFAULT, diff --git a/common/src/vanillin/java/dev/engine_room/vanillin/elements/FireElement.java b/common/src/vanillin/java/dev/engine_room/vanillin/elements/FireElement.java index 2a4c44e22..cff79913a 100644 --- a/common/src/vanillin/java/dev/engine_room/vanillin/elements/FireElement.java +++ b/common/src/vanillin/java/dev/engine_room/vanillin/elements/FireElement.java @@ -21,9 +21,11 @@ import dev.engine_room.flywheel.lib.visual.AbstractVisual; import dev.engine_room.flywheel.lib.visual.SimpleDynamicVisual; import dev.engine_room.flywheel.lib.visual.util.SmartRecycler; -import net.minecraft.client.renderer.LightTexture; +import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.resources.model.ModelBakery; +import net.minecraft.client.resources.model.sprite.SpriteId; +import net.minecraft.util.LightCoordsUtil; import net.minecraft.util.Mth; import net.minecraft.world.entity.Entity; @@ -35,11 +37,9 @@ public final class FireElement extends AbstractVisual implements SimpleDynamicVi .backfaceCulling(false) // Disable backface because we want to be able to flip the model. .build(); - // Parameterize by the material instead of the sprite - // because Material#sprite is a surprisingly heavy operation - // and because sprites are invalidated after a resource reload. - private static final RendererReloadCache FIRE_MODELS = new RendererReloadCache<>(texture -> { - return new SingleMeshModel(new FireMesh(texture.sprite()), FIRE_MATERIAL); + private static final RendererReloadCache FIRE_MODELS = new RendererReloadCache<>(texture -> { + TextureAtlasSprite sprite = Minecraft.getInstance().getAtlasManager().get(texture); + return new SingleMeshModel(new FireMesh(sprite), FIRE_MATERIAL); }); private final Entity entity; @@ -59,7 +59,7 @@ private TransformedInstance createInstance(Model model) { TransformedInstance instance = visualizationContext.instancerProvider() .instancer(InstanceTypes.TRANSFORMED, model) .createInstance(); - instance.light(LightTexture.FULL_BLOCK); + instance.light(LightCoordsUtil.pack(15, 0)); instance.setChanged(); return instance; } @@ -96,8 +96,7 @@ private void setupInstances(DynamicVisual.Context context) { stack.setIdentity(); stack.translate(entityX - renderOrigin.getX(), entityY - renderOrigin.getY(), entityZ - renderOrigin.getZ()); stack.scale(scale, scale, scale); - stack.mulPose(Axis.YP.rotationDegrees(-context.camera() - .getYRot())); + stack.mulPose(Axis.YP.rotationDegrees(-context.cameraRenderState().yRot)); stack.translate(0.0F, 0.0F, -0.3F + (float) ((int) maxHeight) * 0.02F); for (int i = 0; y < maxHeight; ++i) { @@ -157,7 +156,7 @@ private static void writeVertex(MutableVertexList vertexList, int i, float x, fl vertexList.b(i, 1); vertexList.u(i, u); vertexList.v(i, v); - vertexList.light(i, LightTexture.FULL_BLOCK); + vertexList.light(i, LightCoordsUtil.pack(15, 0)); vertexList.normalX(i, 0); vertexList.normalY(i, 1); vertexList.normalZ(i, 0); diff --git a/common/src/vanillin/java/dev/engine_room/vanillin/elements/HitboxElement.java b/common/src/vanillin/java/dev/engine_room/vanillin/elements/HitboxElement.java index 41dd4b245..c83addedd 100644 --- a/common/src/vanillin/java/dev/engine_room/vanillin/elements/HitboxElement.java +++ b/common/src/vanillin/java/dev/engine_room/vanillin/elements/HitboxElement.java @@ -12,11 +12,13 @@ import dev.engine_room.flywheel.lib.visual.SimpleDynamicVisual; import dev.engine_room.flywheel.lib.visual.util.SmartRecycler; import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.LightTexture; +import net.minecraft.client.gui.components.debug.DebugScreenEntries; +import net.minecraft.util.LightCoordsUtil; import net.minecraft.util.Mth; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.LivingEntity; +// TODO 1.21.11: vanilla changed hitbox rendering and moved it to the debug renderer system (EntityHitboxDebugRenderer) public final class HitboxElement implements Visual, SimpleDynamicVisual { // 010------110 // /| /| @@ -75,7 +77,7 @@ private TransformedInstance createInstance(Model model) { TransformedInstance instance = context.instancerProvider() .instancer(InstanceTypes.TRANSFORMED, model) .createInstance(); - instance.light(LightTexture.FULL_BLOCK); + instance.light(LightCoordsUtil.pack(15, 0)); instance.setChanged(); return instance; } @@ -108,8 +110,8 @@ public void animate(float partialTick) { recycler.resetCount(); var shouldRenderHitBoxes = Minecraft.getInstance() - .getEntityRenderDispatcher() - .shouldRenderHitBoxes(); + .debugEntries + .isCurrentlyEnabled(DebugScreenEntries.ENTITY_HITBOXES); if (shouldRenderHitBoxes && !entity.isInvisible() && !Minecraft.getInstance() .showOnlyReducedInfo()) { double entityX = Mth.lerp(partialTick, entity.xOld, entity.getX()); diff --git a/common/src/vanillin/java/dev/engine_room/vanillin/elements/ShadowElement.java b/common/src/vanillin/java/dev/engine_room/vanillin/elements/ShadowElement.java index 8b08b99ab..9bf9fafbb 100644 --- a/common/src/vanillin/java/dev/engine_room/vanillin/elements/ShadowElement.java +++ b/common/src/vanillin/java/dev/engine_room/vanillin/elements/ShadowElement.java @@ -1,8 +1,8 @@ package dev.engine_room.vanillin.elements; -import org.jetbrains.annotations.Nullable; import org.joml.Vector4f; import org.joml.Vector4fc; +import org.jspecify.annotations.Nullable; import dev.engine_room.flywheel.api.material.Material; import dev.engine_room.flywheel.api.material.Transparency; @@ -20,12 +20,13 @@ import dev.engine_room.flywheel.lib.visual.SimpleDynamicVisual; import dev.engine_room.flywheel.lib.visual.util.InstanceRecycler; import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.LightTexture; +import net.minecraft.client.renderer.Lightmap; import net.minecraft.client.renderer.texture.OverlayTexture; import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos.MutableBlockPos; import net.minecraft.core.Direction.Axis; -import net.minecraft.resources.ResourceLocation; +import net.minecraft.resources.Identifier; +import net.minecraft.util.LightCoordsUtil; import net.minecraft.util.Mth; import net.minecraft.world.entity.Entity; import net.minecraft.world.level.block.RenderShape; @@ -43,7 +44,7 @@ * The shadow will be cast on blocks at most {@code min(radius, 2 * strength)} blocks below the entity.

*/ public final class ShadowElement extends AbstractVisual implements SimpleDynamicVisual { - private static final ResourceLocation SHADOW_TEXTURE = ResourceLocation.withDefaultNamespace("textures/misc/shadow.png"); + private static final Identifier SHADOW_TEXTURE = Identifier.withDefaultNamespace("textures/misc/shadow.png"); private static final Material SHADOW_MATERIAL = SimpleMaterial.builder() .texture(SHADOW_TEXTURE) .mipmap(false) @@ -157,7 +158,7 @@ private void setupInstance(ChunkAccess chunk, MutableBlockPos pos, double entity // Too dark to render. return; } - float blockBrightness = LightTexture.getBrightness(level.dimensionType(), maxLocalRawBrightness); + float blockBrightness = Lightmap.getBrightness(level.dimensionType(), maxLocalRawBrightness); float alpha = strength * 0.5F * blockBrightness; if (alpha < 0.0F) { // Too far away/too weak to render. @@ -261,7 +262,7 @@ private static void writeVertex(MutableVertexList vertexList, int i, float x, fl vertexList.b(i, 1); vertexList.u(i, 0); vertexList.v(i, 0); - vertexList.light(i, LightTexture.FULL_BRIGHT); + vertexList.light(i, LightCoordsUtil.FULL_BRIGHT); vertexList.overlay(i, OverlayTexture.NO_OVERLAY); vertexList.normalX(i, 0); vertexList.normalY(i, 1); diff --git a/common/src/vanillin/java/dev/engine_room/vanillin/item/ItemModels.java b/common/src/vanillin/java/dev/engine_room/vanillin/item/ItemModels.java index 4b9119e77..cf122ba00 100644 --- a/common/src/vanillin/java/dev/engine_room/vanillin/item/ItemModels.java +++ b/common/src/vanillin/java/dev/engine_room/vanillin/item/ItemModels.java @@ -1,299 +1,301 @@ -package dev.engine_room.vanillin.item; - -import java.nio.ByteBuffer; -import java.nio.IntBuffer; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import org.jetbrains.annotations.Nullable; -import org.joml.Matrix3f; -import org.joml.Matrix4f; -import org.joml.Vector3f; -import org.joml.Vector4f; -import org.lwjgl.system.MemoryStack; - -import com.mojang.blaze3d.vertex.DefaultVertexFormat; -import com.mojang.blaze3d.vertex.PoseStack; - -import dev.engine_room.flywheel.api.material.Material; -import dev.engine_room.flywheel.api.material.Transparency; -import dev.engine_room.flywheel.api.model.Mesh; -import dev.engine_room.flywheel.api.model.Model; -import dev.engine_room.flywheel.lib.material.Materials; -import dev.engine_room.flywheel.lib.material.SimpleMaterial; -import dev.engine_room.flywheel.lib.memory.MemoryBlock; -import dev.engine_room.flywheel.lib.model.ModelUtil; -import dev.engine_room.flywheel.lib.model.SimpleModel; -import dev.engine_room.flywheel.lib.model.SimpleQuadMesh; -import dev.engine_room.flywheel.lib.model.SingleMeshModel; -import dev.engine_room.flywheel.lib.util.RendererReloadCache; -import dev.engine_room.flywheel.lib.vertex.FullVertexView; -import dev.engine_room.vanillin.Vanillin; -import dev.engine_room.vanillin.VanillinXplat; -import dev.engine_room.vanillin.mixin.item.ItemOverridesAccessor; -import net.minecraft.client.Minecraft; -import net.minecraft.client.multiplayer.ClientLevel; -import net.minecraft.client.renderer.ItemBlockRenderTypes; -import net.minecraft.client.renderer.block.model.BakedQuad; -import net.minecraft.client.renderer.block.model.ItemOverrides; -import net.minecraft.client.renderer.texture.OverlayTexture; -import net.minecraft.client.resources.model.BakedModel; -import net.minecraft.client.resources.model.ModelResourceLocation; -import net.minecraft.client.resources.model.MultiPartBakedModel; -import net.minecraft.client.resources.model.SimpleBakedModel; -import net.minecraft.client.resources.model.WeightedBakedModel; -import net.minecraft.core.Direction; -import net.minecraft.core.registries.Registries; -import net.minecraft.data.models.ItemModelGenerators; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.tags.TagKey; -import net.minecraft.util.RandomSource; -import net.minecraft.world.item.BlockItem; -import net.minecraft.world.item.Item; -import net.minecraft.world.item.ItemDisplayContext; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.Items; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.HalfTransparentBlock; -import net.minecraft.world.level.block.StainedGlassPaneBlock; - -public class ItemModels { - public static final TagKey NO_INSTANCING = TagKey.create(Registries.ITEM, Vanillin.rl("no_instancing")); - - private static final Model EMPTY_MODEL = new SimpleModel(List.of()); - private static final RendererReloadCache MESH_CACHE = new RendererReloadCache<>(key -> bakeMesh(key.model(), key.displayContext())); - private static final RendererReloadCache MODEL_CACHE = new RendererReloadCache<>(key -> bakeModel(key.model(), key.displayContext(), key.material(), key.foil())); - - private static final ModelResourceLocation TRIDENT_MODEL = ModelResourceLocation.vanilla("trident", "inventory"); - private static final ModelResourceLocation SPYGLASS_MODEL = ModelResourceLocation.vanilla("spyglass", "inventory"); - - private static final @Nullable Direction[] DIRECTIONS = new Direction[]{Direction.DOWN, Direction.UP, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST, null}; - - private static final Set ALLOWED_OVERRIDES = new HashSet<>(); - - static { - ALLOWED_OVERRIDES.add(ResourceLocation.withDefaultNamespace("lefthanded")); - ALLOWED_OVERRIDES.add(ResourceLocation.withDefaultNamespace("cooldown")); - ALLOWED_OVERRIDES.add(ItemModelGenerators.TRIM_TYPE_PREDICATE_ID); - ALLOWED_OVERRIDES.add(ResourceLocation.withDefaultNamespace("custom_model_data")); - ALLOWED_OVERRIDES.add(ResourceLocation.withDefaultNamespace("pull")); - ALLOWED_OVERRIDES.add(ResourceLocation.withDefaultNamespace("brushing")); - ALLOWED_OVERRIDES.add(ResourceLocation.withDefaultNamespace("pulling")); - ALLOWED_OVERRIDES.add(ResourceLocation.withDefaultNamespace("filled")); - ALLOWED_OVERRIDES.add(ResourceLocation.withDefaultNamespace("charged")); - ALLOWED_OVERRIDES.add(ResourceLocation.withDefaultNamespace("firework")); - ALLOWED_OVERRIDES.add(ResourceLocation.withDefaultNamespace("broken")); - ALLOWED_OVERRIDES.add(ResourceLocation.withDefaultNamespace("cast")); - ALLOWED_OVERRIDES.add(ResourceLocation.withDefaultNamespace("blocking")); - ALLOWED_OVERRIDES.add(ResourceLocation.withDefaultNamespace("throwing")); - ALLOWED_OVERRIDES.add(ResourceLocation.withDefaultNamespace("level")); - ALLOWED_OVERRIDES.add(ResourceLocation.withDefaultNamespace("tooting")); - } - - public static boolean isSupported(ItemStack stack) { - return !stack.is(NO_INSTANCING) && doesNotHaveItemColors(stack.getItem()) && isSupported(getModel(stack)); - } - - private static boolean doesNotHaveItemColors(Item item) { - return VanillinXplat.INSTANCE.itemColors(item) == null; - } - - public static BakedModel getModel(ItemStack stack) { - return Minecraft.getInstance() - .getItemRenderer() - .getItemModelShaper() - .getItemModel(stack); - } - - @Nullable - public static BakedModel getActualBakedModel(@Nullable ClientLevel clientLevel, ItemStack itemStack, ItemDisplayContext displayContext) { - if (itemStack.isEmpty()) { - return null; - } - - var baseModel = getModel(itemStack); - var overrides = baseModel.getOverrides(); - var model = overrides.resolve(baseModel, itemStack, clientLevel, null, 0); - - if (model == null) { - model = baseModel; - } - - boolean notEquipped = displayContext == ItemDisplayContext.GUI || displayContext == ItemDisplayContext.GROUND || displayContext == ItemDisplayContext.FIXED; - if (model.isCustomRenderer() || itemStack.is(Items.TRIDENT) && !notEquipped) { - return null; - } - - if (notEquipped) { - if (itemStack.is(Items.TRIDENT)) { - model = Minecraft.getInstance() - .getItemRenderer() - .getItemModelShaper() - .getModelManager() - .getModel(TRIDENT_MODEL); - } else if (itemStack.is(Items.SPYGLASS)) { - model = Minecraft.getInstance() - .getItemRenderer() - .getItemModelShaper() - .getModelManager() - .getModel(SPYGLASS_MODEL); - } - } - - return model; - } - - public static boolean isSupported(BakedModel model) { - if (model.isCustomRenderer()) { - return false; - } - - var overrides = model.getOverrides(); - if (overrides != ItemOverrides.EMPTY) { - var properties = ((ItemOverridesAccessor) overrides).vanillin$properties(); - - for (var property : properties) { - if (!ALLOWED_OVERRIDES.contains(property)) { - return false; - } - } - } - - // Check for class equality rather than instanceof to ensure subclasses are *not* handled by vanillin. - Class c = model.getClass(); - if (!(c == SimpleBakedModel.class || c == MultiPartBakedModel.class || c == WeightedBakedModel.class)) { - return false; - } - - return true; - } - - public static Model get(Level level, ItemStack itemStack, ItemDisplayContext displayContext) { - boolean cull = displayContext == ItemDisplayContext.GUI || displayContext.firstPerson() || !(itemStack.getItem() instanceof BlockItem block) || !(block.getBlock() instanceof HalfTransparentBlock) && !(block.getBlock() instanceof StainedGlassPaneBlock); - var material = ModelUtil.getItemMaterial(ItemBlockRenderTypes.getRenderType(itemStack, cull)); - - if (material == null) { - material = Materials.TRANSLUCENT_ENTITY; - } - - if (itemStack.getItem() instanceof BlockItem && material.transparency() == Transparency.TRANSLUCENT) { - material = SimpleMaterial.builderOf(material) - .transparency(Transparency.ORDER_INDEPENDENT) - .build(); - } - - // Visuals all hold references to Level so use that as the parameter type for convenience and cast here. - ClientLevel clientLevel = (level instanceof ClientLevel) ? (ClientLevel) level : null; - - BakedModel model = getActualBakedModel(clientLevel, itemStack, displayContext); - - if (model == null) { - return EMPTY_MODEL; - } - - return MODEL_CACHE.get(new BakedModelKey(model, displayContext, material, itemStack.hasFoil())); - } - - public static Model bakeModel(BakedModel model, ItemDisplayContext displayContext, Material material, boolean foil) { - var mesh = MESH_CACHE.get(new BakedMeshKey(model, displayContext)); - - if (foil) { - return new SimpleModel(List.of(new Model.ConfiguredMesh(material, mesh), new Model.ConfiguredMesh(Materials.GLINT, mesh))); - } else { - return new SingleMeshModel(mesh, material); - } - } - - public static Mesh bakeMesh(BakedModel model, ItemDisplayContext displayContext) { - boolean leftHand = displayContext == ItemDisplayContext.FIRST_PERSON_LEFT_HAND || displayContext == ItemDisplayContext.THIRD_PERSON_LEFT_HAND; - - var poseStack = new PoseStack(); - - model.getTransforms() - .getTransform(displayContext) - .apply(leftHand, poseStack); - poseStack.translate(-0.5f, -0.5f, -0.5f); - - RandomSource randomSource = RandomSource.create(); - - // Write all BakedQuads into a list first to get a count so we can allocate memory ahead of time. - List allQuads = new ArrayList<>(); - for (Direction value : DIRECTIONS) { - randomSource.setSeed(42L); - allQuads.addAll(model.getQuads(null, value, randomSource)); - } - - int vertexCount = allQuads.size() * 4; - var memoryBlock = MemoryBlock.mallocTracked(vertexCount * FullVertexView.STRIDE); - var meshVertices = new FullVertexView(); - - meshVertices.nativeMemoryOwner(memoryBlock); - meshVertices.ptr(memoryBlock.ptr()); - meshVertices.vertexCount(vertexCount); - - Vector4f position = new Vector4f(); - Vector3f normal = new Vector3f(); - - Matrix4f poseMatrix = poseStack.last() - .pose(); - Matrix3f normalMatrix = poseStack.last() - .normal(); - - try (MemoryStack memoryStack = MemoryStack.stackPush();) { - ByteBuffer byteBuffer = memoryStack.malloc(DefaultVertexFormat.BLOCK.getVertexSize()); - IntBuffer intBuffer = byteBuffer.asIntBuffer(); - - int vertex = 0; - - for (BakedQuad quad : allQuads) { - SodiumAnimatedTextureCompat.add(quad.getSprite()); - - int[] js = quad.getVertices(); - var direction = quad.getDirection(); - - normal.set(direction.getStepX(), direction.getStepY(), direction.getStepZ()); - normal.mul(normalMatrix); - - int j = js.length / 8; - - for (int k = 0; k < j; ++k) { - intBuffer.clear(); - intBuffer.put(js, k * 8, 8); - - position.set(byteBuffer.getFloat(0), byteBuffer.getFloat(4), byteBuffer.getFloat(8), 1.0f); - position.mul(poseMatrix); - - // We could probably handle item colors here. - meshVertices.x(vertex, position.x()); - meshVertices.y(vertex, position.y()); - meshVertices.z(vertex, position.z()); - meshVertices.r(vertex, 1.0f); - meshVertices.g(vertex, 1.0f); - meshVertices.b(vertex, 1.0f); - meshVertices.a(vertex, 1.0f); - meshVertices.u(vertex, byteBuffer.getFloat(16)); - meshVertices.v(vertex, byteBuffer.getFloat(20)); - meshVertices.overlay(vertex, OverlayTexture.NO_OVERLAY); - meshVertices.light(vertex, 0); - meshVertices.normalX(vertex, normal.x()); - meshVertices.normalY(vertex, normal.y()); - meshVertices.normalZ(vertex, normal.z()); - - vertex++; - } - } - } - - return new SimpleQuadMesh(meshVertices); - } - - public record BakedModelKey(BakedModel model, ItemDisplayContext displayContext, Material material, boolean foil) { - - } - - public record BakedMeshKey(BakedModel model, ItemDisplayContext displayContext) { - - } -} +// FIXME 1.21.11: port +//package dev.engine_room.vanillin.item; +// +//import java.nio.ByteBuffer; +//import java.nio.IntBuffer; +//import java.util.ArrayList; +//import java.util.HashSet; +//import java.util.List; +//import java.util.Set; +// +//import org.joml.Matrix3f; +//import org.joml.Matrix4f; +//import org.joml.Vector3f; +//import org.joml.Vector4f; +//import org.jspecify.annotations.Nullable; +//import org.lwjgl.system.MemoryStack; +// +//import com.mojang.blaze3d.vertex.DefaultVertexFormat; +//import com.mojang.blaze3d.vertex.PoseStack; +// +//import dev.engine_room.flywheel.api.material.Material; +//import dev.engine_room.flywheel.api.material.Transparency; +//import dev.engine_room.flywheel.api.model.Mesh; +//import dev.engine_room.flywheel.api.model.Model; +//import dev.engine_room.flywheel.lib.material.Materials; +//import dev.engine_room.flywheel.lib.material.SimpleMaterial; +//import dev.engine_room.flywheel.lib.memory.MemoryBlock; +//import dev.engine_room.flywheel.lib.model.ModelUtil; +//import dev.engine_room.flywheel.lib.model.SimpleModel; +//import dev.engine_room.flywheel.lib.model.SimpleQuadMesh; +//import dev.engine_room.flywheel.lib.model.SingleMeshModel; +//import dev.engine_room.flywheel.lib.util.RendererReloadCache; +//import dev.engine_room.flywheel.lib.vertex.FullVertexView; +//import dev.engine_room.vanillin.Vanillin; +//import dev.engine_room.vanillin.VanillinXplat; +//import dev.engine_room.vanillin.mixin.item.ItemOverridesAccessor; +//import net.minecraft.client.Minecraft; +//import net.minecraft.client.multiplayer.ClientLevel; +//import net.minecraft.client.renderer.ItemBlockRenderTypes; +//import net.minecraft.client.renderer.block.model.BakedQuad; +//import net.minecraft.client.renderer.block.model.ItemOverrides; +//import net.minecraft.client.renderer.item.ItemModel; +//import net.minecraft.client.renderer.texture.OverlayTexture; +//import net.minecraft.client.resources.model.BakedModel; +//import net.minecraft.client.resources.model.ModelResourceLocation; +//import net.minecraft.client.resources.model.MultiPartBakedModel; +//import net.minecraft.client.resources.model.SimpleBakedModel; +//import net.minecraft.client.resources.model.WeightedBakedModel; +//import net.minecraft.core.Direction; +//import net.minecraft.core.component.DataComponents; +//import net.minecraft.core.registries.Registries; +//import net.minecraft.data.models.ItemModelGenerators; +//import net.minecraft.resources.ResourceLocation; +//import net.minecraft.tags.TagKey; +//import net.minecraft.util.RandomSource; +//import net.minecraft.world.item.BlockItem; +//import net.minecraft.world.item.Item; +//import net.minecraft.world.item.ItemDisplayContext; +//import net.minecraft.world.item.ItemStack; +//import net.minecraft.world.item.Items; +//import net.minecraft.world.level.Level; +//import net.minecraft.world.level.block.HalfTransparentBlock; +//import net.minecraft.world.level.block.StainedGlassPaneBlock; +// +//public class ItemModels { +// public static final TagKey NO_INSTANCING = TagKey.create(Registries.ITEM, Vanillin.id("no_instancing")); +// +// private static final Model EMPTY_MODEL = new SimpleModel(List.of()); +// private static final RendererReloadCache MESH_CACHE = new RendererReloadCache<>(key -> bakeMesh(key.model(), key.displayContext())); +// private static final RendererReloadCache MODEL_CACHE = new RendererReloadCache<>(key -> bakeModel(key.model(), key.displayContext(), key.material(), key.foil())); +// +// private static final ModelResourceLocation TRIDENT_MODEL = ModelResourceLocation.vanilla("trident", "inventory"); +// private static final ModelResourceLocation SPYGLASS_MODEL = ModelResourceLocation.vanilla("spyglass", "inventory"); +// +// private static final @Nullable Direction[] DIRECTIONS = new Direction[]{Direction.DOWN, Direction.UP, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST, null}; +// +// private static final Set ALLOWED_OVERRIDES = new HashSet<>(); +// +// static { +// ALLOWED_OVERRIDES.add(ResourceLocation.withDefaultNamespace("lefthanded")); +// ALLOWED_OVERRIDES.add(ResourceLocation.withDefaultNamespace("cooldown")); +// ALLOWED_OVERRIDES.add(ItemModelGenerators.TRIM_TYPE_PREDICATE_ID); +// ALLOWED_OVERRIDES.add(ResourceLocation.withDefaultNamespace("custom_model_data")); +// ALLOWED_OVERRIDES.add(ResourceLocation.withDefaultNamespace("pull")); +// ALLOWED_OVERRIDES.add(ResourceLocation.withDefaultNamespace("brushing")); +// ALLOWED_OVERRIDES.add(ResourceLocation.withDefaultNamespace("pulling")); +// ALLOWED_OVERRIDES.add(ResourceLocation.withDefaultNamespace("filled")); +// ALLOWED_OVERRIDES.add(ResourceLocation.withDefaultNamespace("charged")); +// ALLOWED_OVERRIDES.add(ResourceLocation.withDefaultNamespace("firework")); +// ALLOWED_OVERRIDES.add(ResourceLocation.withDefaultNamespace("broken")); +// ALLOWED_OVERRIDES.add(ResourceLocation.withDefaultNamespace("cast")); +// ALLOWED_OVERRIDES.add(ResourceLocation.withDefaultNamespace("blocking")); +// ALLOWED_OVERRIDES.add(ResourceLocation.withDefaultNamespace("throwing")); +// ALLOWED_OVERRIDES.add(ResourceLocation.withDefaultNamespace("level")); +// ALLOWED_OVERRIDES.add(ResourceLocation.withDefaultNamespace("tooting")); +// } +// +// public static boolean isSupported(ItemStack stack) { +// return !stack.is(NO_INSTANCING) && doesNotHaveItemColors(stack.getItem()) && isSupported(getModel(stack)); +// } +// +// private static boolean doesNotHaveItemColors(Item item) { +// return VanillinXplat.INSTANCE.itemColors(item) == null; +// } +// +// public static ItemModel getModel(ItemStack stack) { +// return Minecraft.getInstance() +// .getModelManager() +// .getItemModel(stack.get(DataComponents.ITEM_MODEL)); +// } +// +// @Nullable +// public static BakedModel getActualBakedModel(@Nullable ClientLevel clientLevel, ItemStack itemStack, ItemDisplayContext displayContext) { +// if (itemStack.isEmpty()) { +// return null; +// } +// +// var baseModel = getModel(itemStack); +// var overrides = baseModel.getOverrides(); +// var model = overrides.resolve(baseModel, itemStack, clientLevel, null, 0); +// +// if (model == null) { +// model = baseModel; +// } +// +// boolean notEquipped = displayContext == ItemDisplayContext.GUI || displayContext == ItemDisplayContext.GROUND || displayContext == ItemDisplayContext.FIXED; +// if (model.isCustomRenderer() || itemStack.is(Items.TRIDENT) && !notEquipped) { +// return null; +// } +// +// if (notEquipped) { +// if (itemStack.is(Items.TRIDENT)) { +// model = Minecraft.getInstance() +// .getItemRenderer() +// .getItemModelShaper() +// .getModelManager() +// .getModel(TRIDENT_MODEL); +// } else if (itemStack.is(Items.SPYGLASS)) { +// model = Minecraft.getInstance() +// .getItemRenderer() +// .getItemModelShaper() +// .getModelManager() +// .getModel(SPYGLASS_MODEL); +// } +// } +// +// return model; +// } +// +// public static boolean isSupported(BakedModel model) { +// if (model.isCustomRenderer()) { +// return false; +// } +// +// var overrides = model.getOverrides(); +// if (overrides != ItemOverrides.EMPTY) { +// var properties = ((ItemOverridesAccessor) overrides).vanillin$properties(); +// +// for (var property : properties) { +// if (!ALLOWED_OVERRIDES.contains(property)) { +// return false; +// } +// } +// } +// +// // Check for class equality rather than instanceof to ensure subclasses are *not* handled by vanillin. +// Class c = model.getClass(); +// if (!(c == SimpleBakedModel.class || c == MultiPartBakedModel.class || c == WeightedBakedModel.class)) { +// return false; +// } +// +// return true; +// } +// +// public static Model get(Level level, ItemStack itemStack, ItemDisplayContext displayContext) { +// boolean cull = displayContext == ItemDisplayContext.GUI || displayContext.firstPerson() || !(itemStack.getItem() instanceof BlockItem block) || !(block.getBlock() instanceof HalfTransparentBlock) && !(block.getBlock() instanceof StainedGlassPaneBlock); +// var material = ModelUtil.getItemMaterial(ItemBlockRenderTypes.getRenderType(itemStack, cull)); +// +// if (material == null) { +// material = Materials.TRANSLUCENT_ENTITY; +// } +// +// if (itemStack.getItem() instanceof BlockItem && material.transparency() == Transparency.TRANSLUCENT) { +// material = SimpleMaterial.builderOf(material) +// .transparency(Transparency.ORDER_INDEPENDENT) +// .build(); +// } +// +// // Visuals all hold references to Level so use that as the parameter type for convenience and cast here. +// ClientLevel clientLevel = (level instanceof ClientLevel) ? (ClientLevel) level : null; +// +// BakedModel model = getActualBakedModel(clientLevel, itemStack, displayContext); +// +// if (model == null) { +// return EMPTY_MODEL; +// } +// +// return MODEL_CACHE.get(new BakedModelKey(model, displayContext, material, itemStack.hasFoil())); +// } +// +// public static Model bakeModel(BakedModel model, ItemDisplayContext displayContext, Material material, boolean foil) { +// var mesh = MESH_CACHE.get(new BakedMeshKey(model, displayContext)); +// +// if (foil) { +// return new SimpleModel(List.of(new Model.ConfiguredMesh(material, mesh), new Model.ConfiguredMesh(Materials.GLINT, mesh))); +// } else { +// return new SingleMeshModel(mesh, material); +// } +// } +// +// public static Mesh bakeMesh(BakedModel model, ItemDisplayContext displayContext) { +// boolean leftHand = displayContext == ItemDisplayContext.FIRST_PERSON_LEFT_HAND || displayContext == ItemDisplayContext.THIRD_PERSON_LEFT_HAND; +// +// var poseStack = new PoseStack(); +// +// model.getTransforms() +// .getTransform(displayContext) +// .apply(leftHand, poseStack); +// poseStack.translate(-0.5f, -0.5f, -0.5f); +// +// RandomSource randomSource = RandomSource.create(); +// +// // Write all BakedQuads into a list first to get a count so we can allocate memory ahead of time. +// List allQuads = new ArrayList<>(); +// for (Direction value : DIRECTIONS) { +// randomSource.setSeed(42L); +// allQuads.addAll(model.getQuads(null, value, randomSource)); +// } +// +// int vertexCount = allQuads.size() * 4; +// var memoryBlock = MemoryBlock.mallocTracked(vertexCount * FullVertexView.STRIDE); +// var meshVertices = new FullVertexView(); +// +// meshVertices.nativeMemoryOwner(memoryBlock); +// meshVertices.ptr(memoryBlock.ptr()); +// meshVertices.vertexCount(vertexCount); +// +// Vector4f position = new Vector4f(); +// Vector3f normal = new Vector3f(); +// +// Matrix4f poseMatrix = poseStack.last() +// .pose(); +// Matrix3f normalMatrix = poseStack.last() +// .normal(); +// +// try (MemoryStack memoryStack = MemoryStack.stackPush();) { +// ByteBuffer byteBuffer = memoryStack.malloc(DefaultVertexFormat.BLOCK.getVertexSize()); +// IntBuffer intBuffer = byteBuffer.asIntBuffer(); +// +// int vertex = 0; +// +// for (BakedQuad quad : allQuads) { +// SodiumAnimatedTextureCompat.add(quad.getSprite()); +// +// int[] js = quad.getVertices(); +// var direction = quad.getDirection(); +// +// normal.set(direction.getStepX(), direction.getStepY(), direction.getStepZ()); +// normal.mul(normalMatrix); +// +// int j = js.length / 8; +// +// for (int k = 0; k < j; ++k) { +// intBuffer.clear(); +// intBuffer.put(js, k * 8, 8); +// +// position.set(byteBuffer.getFloat(0), byteBuffer.getFloat(4), byteBuffer.getFloat(8), 1.0f); +// position.mul(poseMatrix); +// +// // We could probably handle item colors here. +// meshVertices.x(vertex, position.x()); +// meshVertices.y(vertex, position.y()); +// meshVertices.z(vertex, position.z()); +// meshVertices.r(vertex, 1.0f); +// meshVertices.g(vertex, 1.0f); +// meshVertices.b(vertex, 1.0f); +// meshVertices.a(vertex, 1.0f); +// meshVertices.u(vertex, byteBuffer.getFloat(16)); +// meshVertices.v(vertex, byteBuffer.getFloat(20)); +// meshVertices.overlay(vertex, OverlayTexture.NO_OVERLAY); +// meshVertices.light(vertex, 0); +// meshVertices.normalX(vertex, normal.x()); +// meshVertices.normalY(vertex, normal.y()); +// meshVertices.normalZ(vertex, normal.z()); +// +// vertex++; +// } +// } +// } +// +// return new SimpleQuadMesh(meshVertices); +// } +// +// public record BakedModelKey(BakedModel model, ItemDisplayContext displayContext, Material material, boolean foil) { +// +// } +// +// public record BakedMeshKey(BakedModel model, ItemDisplayContext displayContext) { +// +// } +//} diff --git a/common/src/vanillin/java/dev/engine_room/vanillin/item/SodiumAnimatedTextureCompat.java b/common/src/vanillin/java/dev/engine_room/vanillin/item/SodiumAnimatedTextureCompat.java index 031808fa7..51e1ee30a 100644 --- a/common/src/vanillin/java/dev/engine_room/vanillin/item/SodiumAnimatedTextureCompat.java +++ b/common/src/vanillin/java/dev/engine_room/vanillin/item/SodiumAnimatedTextureCompat.java @@ -4,7 +4,7 @@ import it.unimi.dsi.fastutil.objects.ReferenceArraySet; import it.unimi.dsi.fastutil.objects.ReferenceSet; import it.unimi.dsi.fastutil.objects.ReferenceSets; -import net.caffeinemc.mods.sodium.client.render.texture.SpriteUtil; +import net.caffeinemc.mods.sodium.api.texture.SpriteUtil; import net.minecraft.client.renderer.texture.TextureAtlasSprite; /** @@ -42,14 +42,14 @@ public static void onReloadRenderer() { private static final class Internals { private static void add(TextureAtlasSprite sprite) { - if (SpriteUtil.hasAnimation(sprite)) { + if (SpriteUtil.INSTANCE.hasAnimation(sprite)) { VISIBLE.add(sprite); } } private static void beginFrame() { for (var sprite : VISIBLE) { - SpriteUtil.markSpriteActive(sprite); + SpriteUtil.INSTANCE.markSpriteActive(sprite); } } } diff --git a/common/src/vanillin/java/dev/engine_room/vanillin/mixin/BlockModelSetAccessor.java b/common/src/vanillin/java/dev/engine_room/vanillin/mixin/BlockModelSetAccessor.java new file mode 100644 index 000000000..fc531a9de --- /dev/null +++ b/common/src/vanillin/java/dev/engine_room/vanillin/mixin/BlockModelSetAccessor.java @@ -0,0 +1,16 @@ +package dev.engine_room.vanillin.mixin; + +import java.util.Map; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +import net.minecraft.client.renderer.block.BlockModelSet; +import net.minecraft.client.renderer.block.model.BlockModel; +import net.minecraft.world.level.block.state.BlockState; + +@Mixin(BlockModelSet.class) +public interface BlockModelSetAccessor { + @Accessor("blockModelByStateCache") + Map flywheel$getBlockModelByStateCache(); +} diff --git a/common/src/vanillin/java/dev/engine_room/vanillin/mixin/ChestRendererAccessor.java b/common/src/vanillin/java/dev/engine_room/vanillin/mixin/ChestRendererAccessor.java new file mode 100644 index 000000000..754e65302 --- /dev/null +++ b/common/src/vanillin/java/dev/engine_room/vanillin/mixin/ChestRendererAccessor.java @@ -0,0 +1,16 @@ +package dev.engine_room.vanillin.mixin; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Invoker; + +import net.minecraft.client.renderer.blockentity.ChestRenderer; +import net.minecraft.client.renderer.blockentity.state.ChestRenderState; +import net.minecraft.world.level.block.entity.BlockEntity; + +@Mixin(ChestRenderer.class) +public interface ChestRendererAccessor { + @Invoker("getChestMaterial") + static ChestRenderState.ChestMaterialType flywheel$getChestMaterial(BlockEntity blockEntity, boolean xmasTextures) { + throw new AssertionError(); + } +} diff --git a/common/src/vanillin/java/dev/engine_room/vanillin/mixin/item/ItemOverridesAccessor.java b/common/src/vanillin/java/dev/engine_room/vanillin/mixin/item/ItemOverridesAccessor.java deleted file mode 100644 index e0b1fc167..000000000 --- a/common/src/vanillin/java/dev/engine_room/vanillin/mixin/item/ItemOverridesAccessor.java +++ /dev/null @@ -1,13 +0,0 @@ -package dev.engine_room.vanillin.mixin.item; - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Accessor; - -import net.minecraft.client.renderer.block.model.ItemOverrides; -import net.minecraft.resources.ResourceLocation; - -@Mixin(ItemOverrides.class) -public interface ItemOverridesAccessor { - @Accessor("properties") - ResourceLocation[] vanillin$properties(); -} diff --git a/common/src/vanillin/java/dev/engine_room/vanillin/visuals/BellVisual.java b/common/src/vanillin/java/dev/engine_room/vanillin/visuals/BellVisual.java index cd6788c67..7f52c22bf 100644 --- a/common/src/vanillin/java/dev/engine_room/vanillin/visuals/BellVisual.java +++ b/common/src/vanillin/java/dev/engine_room/vanillin/visuals/BellVisual.java @@ -34,7 +34,7 @@ public class BellVisual extends AbstractBlockEntityVisual imple public BellVisual(VisualizationContext ctx, BellBlockEntity blockEntity, float partialTick) { super(ctx, blockEntity, partialTick); - instances = InstanceTree.create(instancerProvider(), ModelTrees.of(ModelLayers.BELL, BellRenderer.BELL_RESOURCE_LOCATION, MATERIAL)); + instances = InstanceTree.create(instancerProvider(), ModelTrees.of(ModelLayers.BELL, BellRenderer.BELL_TEXTURE, MATERIAL)); bellBody = instances.childOrThrow("bell_body"); BlockPos visualPos = getVisualPosition(); diff --git a/common/src/vanillin/java/dev/engine_room/vanillin/visuals/BlockDisplayVisual.java b/common/src/vanillin/java/dev/engine_room/vanillin/visuals/BlockDisplayVisual.java index 212e8bb82..12d7b53bc 100644 --- a/common/src/vanillin/java/dev/engine_room/vanillin/visuals/BlockDisplayVisual.java +++ b/common/src/vanillin/java/dev/engine_room/vanillin/visuals/BlockDisplayVisual.java @@ -9,9 +9,10 @@ import dev.engine_room.flywheel.lib.visual.AbstractEntityVisual; import dev.engine_room.flywheel.lib.visual.SimpleDynamicVisual; import dev.engine_room.flywheel.lib.visual.component.ShadowComponent; -import net.minecraft.client.Camera; +import net.minecraft.client.renderer.state.level.CameraRenderState; import net.minecraft.util.Mth; import net.minecraft.world.entity.Display; +import net.minecraft.world.entity.Display.RenderState; import net.minecraft.world.entity.Entity; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.state.BlockState; @@ -41,7 +42,7 @@ public BlockDisplayVisual(VisualizationContext ctx, Display.BlockDisplay entity, @Override public void beginFrame(Context ctx) { - Display.RenderState renderState = entity.renderState(); + RenderState renderState = entity.renderState(); if (renderState == null) { instance.handle() .setVisible(false); @@ -84,19 +85,19 @@ public void beginFrame(Context ctx) { .translate((float) (pos.x - renderOrigin.getX()), (float) (pos.y - renderOrigin.getY()), (float) (pos.z - renderOrigin.getZ())); float partialTick = ctx.partialTick(); - Camera camera = ctx.camera(); + CameraRenderState cameraRenderState = ctx.cameraRenderState(); switch (renderState.billboardConstraints()) { case FIXED: instance.pose.rotateYXZ(-0.017453292F * entityYRot(entity, partialTick), ((float) Math.PI / 180F) * entityXRot(entity, partialTick), 0.0F); break; case HORIZONTAL: - instance.pose.rotateYXZ(-0.017453292F * entityYRot(entity, partialTick), ((float) Math.PI / 180F) * cameraXRot(camera), 0.0F); + instance.pose.rotateYXZ(-0.017453292F * entityYRot(entity, partialTick), ((float) Math.PI / 180F) * cameraXRot(cameraRenderState), 0.0F); break; case VERTICAL: - instance.pose.rotateYXZ(-0.017453292F * cameraYrot(camera), ((float) Math.PI / 180F) * entityXRot(entity, partialTick), 0.0F); + instance.pose.rotateYXZ(-0.017453292F * cameraYrot(cameraRenderState), ((float) Math.PI / 180F) * entityXRot(entity, partialTick), 0.0F); break; case CENTER: - instance.pose.rotateYXZ(-0.017453292F * cameraYrot(camera), ((float) Math.PI / 180F) * cameraXRot(camera), 0.0F); + instance.pose.rotateYXZ(-0.017453292F * cameraYrot(cameraRenderState), ((float) Math.PI / 180F) * cameraXRot(cameraRenderState), 0.0F); break; } @@ -106,12 +107,12 @@ public void beginFrame(Context ctx) { .setChanged(); } - private static float cameraYrot(Camera camera) { - return camera.getYRot() - 180.0F; + private static float cameraYrot(CameraRenderState cameraRenderState) { + return cameraRenderState.yRot - 180.0F; } - private static float cameraXRot(Camera camera) { - return -camera.getXRot(); + private static float cameraXRot(CameraRenderState cameraRenderState) { + return -cameraRenderState.xRot; } private static float entityYRot(Entity entity, float partialTick) { diff --git a/common/src/vanillin/java/dev/engine_room/vanillin/visuals/ChestVisual.java b/common/src/vanillin/java/dev/engine_room/vanillin/visuals/ChestVisual.java index fe4731189..0ac569f78 100644 --- a/common/src/vanillin/java/dev/engine_room/vanillin/visuals/ChestVisual.java +++ b/common/src/vanillin/java/dev/engine_room/vanillin/visuals/ChestVisual.java @@ -1,13 +1,12 @@ package dev.engine_room.vanillin.visuals; -import java.util.Calendar; import java.util.EnumMap; import java.util.Map; import java.util.function.Consumer; -import org.jetbrains.annotations.Nullable; import org.joml.Matrix4f; import org.joml.Matrix4fc; +import org.jspecify.annotations.Nullable; import dev.engine_room.flywheel.api.instance.Instance; import dev.engine_room.flywheel.api.material.Material; @@ -18,15 +17,18 @@ import dev.engine_room.flywheel.lib.model.part.ModelTrees; import dev.engine_room.flywheel.lib.visual.AbstractBlockEntityVisual; import dev.engine_room.flywheel.lib.visual.SimpleDynamicVisual; +import dev.engine_room.vanillin.mixin.ChestRendererAccessor; import it.unimi.dsi.fastutil.floats.Float2FloatFunction; import it.unimi.dsi.fastutil.longs.LongSet; import net.minecraft.client.model.geom.ModelLayerLocation; import net.minecraft.client.model.geom.ModelLayers; import net.minecraft.client.renderer.LevelRenderer; -import net.minecraft.client.renderer.LightTexture; import net.minecraft.client.renderer.Sheets; +import net.minecraft.client.renderer.blockentity.ChestRenderer; +import net.minecraft.client.resources.model.sprite.SpriteId; import net.minecraft.core.BlockPos; import net.minecraft.core.SectionPos; +import net.minecraft.util.LightCoordsUtil; import net.minecraft.util.Mth; import net.minecraft.world.level.block.AbstractChestBlock; import net.minecraft.world.level.block.Block; @@ -61,8 +63,7 @@ public class ChestVisual extends Abstrac @Nullable private final Matrix4fc initialPose; private final BrightnessCombiner brightnessCombiner = new BrightnessCombiner(); - @Nullable - private final DoubleBlockCombiner.NeighborCombineResult neighborCombineResult; + private final DoubleBlockCombiner.@Nullable NeighborCombineResult neighborCombineResult; @Nullable private final Float2FloatFunction lidProgress; @@ -74,7 +75,10 @@ public ChestVisual(VisualizationContext ctx, T blockEntity, float partialTick) { Block block = blockState.getBlock(); if (block instanceof AbstractChestBlock chestBlock) { ChestType chestType = blockState.hasProperty(ChestBlock.TYPE) ? blockState.getValue(ChestBlock.TYPE) : ChestType.SINGLE; - net.minecraft.client.resources.model.Material texture = Sheets.chooseMaterial(blockEntity, chestType, isChristmas()); + SpriteId texture = Sheets.chooseSprite( + ChestRendererAccessor.flywheel$getChestMaterial(blockEntity, ChestRenderer.xmasTextures()), + chestType + ); instances = InstanceTree.create(instancerProvider(), ModelTrees.of(LAYER_LOCATIONS.get(chestType), texture, MATERIAL)); lid = instances.childOrThrow("lid"); lock = instances.childOrThrow("lock"); @@ -95,11 +99,6 @@ public ChestVisual(VisualizationContext ctx, T blockEntity, float partialTick) { } } - private static boolean isChristmas() { - Calendar calendar = Calendar.getInstance(); - return calendar.get(Calendar.MONTH) + 1 == 12 && calendar.get(Calendar.DATE) >= 24 && calendar.get(Calendar.DATE) <= 26; - } - private Matrix4f createInitialPose() { BlockPos visualPos = getVisualPosition(); float horizontalAngle = blockState.getValue(ChestBlock.FACING).toYRot(); @@ -200,23 +199,23 @@ public LongSet acceptNone() { private class BrightnessCombiner implements DoubleBlockCombiner.Combiner { @Override public Integer acceptDouble(BlockEntity first, BlockEntity second) { - int firstLight = LevelRenderer.getLightColor(first.getLevel(), first.getBlockPos()); - int secondLight = LevelRenderer.getLightColor(second.getLevel(), second.getBlockPos()); - int firstBlockLight = LightTexture.block(firstLight); - int secondBlockLight = LightTexture.block(secondLight); - int firstSkyLight = LightTexture.sky(firstLight); - int secondSkyLight = LightTexture.sky(secondLight); - return LightTexture.pack(Math.max(firstBlockLight, secondBlockLight), Math.max(firstSkyLight, secondSkyLight)); + int firstLight = LevelRenderer.getLightCoords(first.getLevel(), first.getBlockPos()); + int secondLight = LevelRenderer.getLightCoords(second.getLevel(), second.getBlockPos()); + int firstBlockLight = LightCoordsUtil.block(firstLight); + int secondBlockLight = LightCoordsUtil.block(secondLight); + int firstSkyLight = LightCoordsUtil.sky(firstLight); + int secondSkyLight = LightCoordsUtil.sky(secondLight); + return LightCoordsUtil.pack(Math.max(firstBlockLight, secondBlockLight), Math.max(firstSkyLight, secondSkyLight)); } @Override public Integer acceptSingle(BlockEntity single) { - return LevelRenderer.getLightColor(single.getLevel(), single.getBlockPos()); + return LevelRenderer.getLightCoords(single.getLevel(), single.getBlockPos()); } @Override public Integer acceptNone() { - return LevelRenderer.getLightColor(level, pos); + return LevelRenderer.getLightCoords(level, pos); } } } diff --git a/common/src/vanillin/java/dev/engine_room/vanillin/visuals/ItemDisplayVisual.java b/common/src/vanillin/java/dev/engine_room/vanillin/visuals/ItemDisplayVisual.java index ce118e09f..20ddda5ab 100644 --- a/common/src/vanillin/java/dev/engine_room/vanillin/visuals/ItemDisplayVisual.java +++ b/common/src/vanillin/java/dev/engine_room/vanillin/visuals/ItemDisplayVisual.java @@ -1,144 +1,149 @@ -package dev.engine_room.vanillin.visuals; - -import com.mojang.math.Transformation; - -import dev.engine_room.flywheel.api.visualization.VisualizationContext; -import dev.engine_room.flywheel.lib.instance.InstanceTypes; -import dev.engine_room.flywheel.lib.instance.TransformedInstance; -import dev.engine_room.flywheel.lib.model.Models; -import dev.engine_room.flywheel.lib.visual.AbstractEntityVisual; -import dev.engine_room.flywheel.lib.visual.SimpleDynamicVisual; -import dev.engine_room.flywheel.lib.visual.component.ShadowComponent; -import dev.engine_room.vanillin.item.ItemModels; -import net.minecraft.client.Camera; -import net.minecraft.util.Mth; -import net.minecraft.world.entity.Display; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.phys.Vec3; - -public class ItemDisplayVisual extends AbstractEntityVisual implements SimpleDynamicVisual { - private final TransformedInstance instance; - - private ItemStack currentStack; - - private final ShadowComponent shadowComponent; - - public ItemDisplayVisual(VisualizationContext ctx, Display.ItemDisplay entity, float partialTick) { - super(ctx, entity, partialTick); - - var itemRenderState = entity.itemRenderState(); - - if (itemRenderState == null) { - currentStack = ItemStack.EMPTY; - instance = ctx.instancerProvider() - .instancer(InstanceTypes.TRANSFORMED, Models.block(Blocks.AIR.defaultBlockState())) - .createInstance(); - } else { - currentStack = itemRenderState.itemStack() - .copy(); - instance = ctx.instancerProvider() - .instancer(InstanceTypes.TRANSFORMED, ItemModels.get(level, currentStack, itemRenderState.itemTransform())) - .createInstance(); - } - - shadowComponent = new ShadowComponent(ctx, entity); - } - - @Override - public void beginFrame(Context ctx) { - Display.RenderState renderState = entity.renderState(); - if (renderState == null) { - instance.handle() - .setVisible(false); - return; - } - var object = entity.itemRenderState(); - if (object == null) { - instance.handle() - .setVisible(false); - return; - } - - instance.handle() - .setVisible(true); - - var itemStack = object.itemStack(); - - if (!ItemStack.matches(itemStack, currentStack)) { - currentStack = itemStack.copy(); - visualizationContext.instancerProvider() - .instancer(InstanceTypes.TRANSFORMED, ItemModels.get(level, currentStack, object.itemTransform())) - .stealInstance(instance); - } - - float f = entity.calculateInterpolationProgress(ctx.partialTick()); - - shadowComponent.radius(renderState.shadowRadius() - .get(f)); - shadowComponent.strength(renderState.shadowStrength() - .get(f)); - shadowComponent.beginFrame(ctx); - - int i = renderState.brightnessOverride(); - int j = i != -1 ? i : computePackedLight(ctx.partialTick()); - Transformation transformation = renderState.transformation() - .get(f); - - Vec3 pos = entity.position(); - var renderOrigin = renderOrigin(); - - instance.setIdentityTransform() - .translate((float) (pos.x - renderOrigin.getX()), (float) (pos.y - renderOrigin.getY()), (float) (pos.z - renderOrigin.getZ())); - - float partialTick = ctx.partialTick(); - Camera camera = ctx.camera(); - switch (renderState.billboardConstraints()) { - case FIXED: - instance.pose.rotateYXZ(-0.017453292F * entityYRot(entity, partialTick), ((float) Math.PI / 180F) * entityXRot(entity, partialTick), 0.0F); - break; - case HORIZONTAL: - instance.pose.rotateYXZ(-0.017453292F * entityYRot(entity, partialTick), ((float) Math.PI / 180F) * cameraXRot(camera), 0.0F); - break; - case VERTICAL: - instance.pose.rotateYXZ(-0.017453292F * cameraYrot(camera), ((float) Math.PI / 180F) * entityXRot(entity, partialTick), 0.0F); - break; - case CENTER: - instance.pose.rotateYXZ(-0.017453292F * cameraYrot(camera), ((float) Math.PI / 180F) * cameraXRot(camera), 0.0F); - break; - } - - // getMatrix does a copy which is not strictly necessary here but oh well. - instance.mul(transformation.getMatrix()) - .rotateY(Mth.PI) - .light(j) - .setChanged(); - } - - private static float cameraYrot(Camera camera) { - return camera.getYRot() - 180.0F; - } - - private static float cameraXRot(Camera camera) { - return -camera.getXRot(); - } - - private static float entityYRot(Entity entity, float partialTick) { - return Mth.rotLerp(partialTick, entity.yRotO, entity.getYRot()); - } - - private static float entityXRot(Entity entity, float partialTick) { - return Mth.lerp(partialTick, entity.xRotO, entity.getXRot()); - } - - @Override - protected void _delete() { - instance.delete(); - } - - public static boolean shouldVisualize(Display.ItemDisplay itemDisplay) { - var state = itemDisplay.itemRenderState(); - return state != null && ItemModels.isSupported(state.itemStack()); - } -} +// FIXME 1.21.11: port +//package dev.engine_room.vanillin.visuals; +// +//import java.util.Objects; +// +//import org.jspecify.annotations.Nullable; +// +//import com.mojang.math.Transformation; +// +//import dev.engine_room.flywheel.api.visualization.VisualizationContext; +//import dev.engine_room.flywheel.lib.instance.InstanceTypes; +//import dev.engine_room.flywheel.lib.instance.TransformedInstance; +//import dev.engine_room.flywheel.lib.model.Models; +//import dev.engine_room.flywheel.lib.visual.AbstractEntityVisual; +//import dev.engine_room.flywheel.lib.visual.SimpleDynamicVisual; +//import dev.engine_room.flywheel.lib.visual.component.ShadowComponent; +//import dev.engine_room.vanillin.item.ItemModels; +//import net.minecraft.client.Camera; +//import net.minecraft.util.Mth; +//import net.minecraft.world.entity.Display; +//import net.minecraft.world.entity.Entity; +//import net.minecraft.world.item.ItemStack; +//import net.minecraft.world.level.block.Blocks; +//import net.minecraft.world.phys.Vec3; +// +//public class ItemDisplayVisual extends AbstractEntityVisual implements SimpleDynamicVisual { +// private final TransformedInstance instance; +// +// private ItemStack currentStack; +// +// private final ShadowComponent shadowComponent; +// +// public ItemDisplayVisual(VisualizationContext ctx, Display.ItemDisplay entity, float partialTick) { +// super(ctx, entity, partialTick); +// +// var itemRenderState = entity.itemRenderState(); +// +// if (itemRenderState == null) { +// currentStack = ItemStack.EMPTY; +// instance = ctx.instancerProvider() +// .instancer(InstanceTypes.TRANSFORMED, Models.block(Blocks.AIR.defaultBlockState())) +// .createInstance(); +// } else { +// currentStack = itemRenderState.itemStack() +// .copy(); +// instance = ctx.instancerProvider() +// .instancer(InstanceTypes.TRANSFORMED, ItemModels.get(level, currentStack, itemRenderState.itemTransform())) +// .createInstance(); +// } +// +// shadowComponent = new ShadowComponent(ctx, entity); +// } +// +// @Override +// public void beginFrame(Context ctx) { +// Display.RenderState renderState = entity.renderState(); +// if (renderState == null) { +// instance.handle() +// .setVisible(false); +// return; +// } +// var object = entity.itemRenderState(); +// if (object == null) { +// instance.handle() +// .setVisible(false); +// return; +// } +// +// instance.handle() +// .setVisible(true); +// +// var itemStack = object.itemStack(); +// +// if (!ItemStack.matches(itemStack, currentStack)) { +// currentStack = itemStack.copy(); +// visualizationContext.instancerProvider() +// .instancer(InstanceTypes.TRANSFORMED, ItemModels.get(level, currentStack, object.itemTransform())) +// .stealInstance(instance); +// } +// +// float f = entity.calculateInterpolationProgress(ctx.partialTick()); +// +// shadowComponent.radius(renderState.shadowRadius() +// .get(f)); +// shadowComponent.strength(renderState.shadowStrength() +// .get(f)); +// shadowComponent.beginFrame(ctx); +// +// int i = renderState.brightnessOverride(); +// int j = i != -1 ? i : computePackedLight(ctx.partialTick()); +// Transformation transformation = renderState.transformation() +// .get(f); +// +// Vec3 pos = entity.position(); +// var renderOrigin = renderOrigin(); +// +// instance.setIdentityTransform() +// .translate((float) (pos.x - renderOrigin.getX()), (float) (pos.y - renderOrigin.getY()), (float) (pos.z - renderOrigin.getZ())); +// +// float partialTick = ctx.partialTick(); +// Camera cameraRenderState = ctx.cameraRenderState(); +// switch (renderState.billboardConstraints()) { +// case FIXED: +// instance.pose.rotateYXZ(-0.017453292F * entityYRot(entity, partialTick), ((float) Math.PI / 180F) * entityXRot(entity, partialTick), 0.0F); +// break; +// case HORIZONTAL: +// instance.pose.rotateYXZ(-0.017453292F * entityYRot(entity, partialTick), ((float) Math.PI / 180F) * cameraXRot(cameraRenderState), 0.0F); +// break; +// case VERTICAL: +// instance.pose.rotateYXZ(-0.017453292F * cameraYrot(cameraRenderState), ((float) Math.PI / 180F) * entityXRot(entity, partialTick), 0.0F); +// break; +// case CENTER: +// instance.pose.rotateYXZ(-0.017453292F * cameraYrot(cameraRenderState), ((float) Math.PI / 180F) * cameraXRot(cameraRenderState), 0.0F); +// break; +// } +// +// // getMatrix does a copy which is not strictly necessary here but oh well. +// instance.mul(transformation.getMatrix()) +// .rotateY(Mth.PI) +// .light(j) +// .setChanged(); +// } +// +// private static float cameraYrot(Camera cameraRenderState) { +// return cameraRenderState.yRot() - 180.0F; +// } +// +// private static float cameraXRot(Camera cameraRenderState) { +// return -cameraRenderState.xRot(); +// } +// +// private static float entityYRot(Entity entity, float partialTick) { +// return Mth.rotLerp(partialTick, entity.yRotO, entity.getYRot()); +// } +// +// private static float entityXRot(Entity entity, float partialTick) { +// return Mth.lerp(partialTick, entity.xRotO, entity.getXRot()); +// } +// +// @Override +// protected void _delete() { +// instance.delete(); +// } +// +// public static boolean shouldVisualize(Display.ItemDisplay itemDisplay) { +// var state = itemDisplay.itemRenderState(); +// return state != null && ItemModels.isSupported(state.itemStack()); +// } +//} diff --git a/common/src/vanillin/java/dev/engine_room/vanillin/visuals/ItemFrameVisual.java b/common/src/vanillin/java/dev/engine_room/vanillin/visuals/ItemFrameVisual.java index 7d6a44ce1..2bee5d1ce 100644 --- a/common/src/vanillin/java/dev/engine_room/vanillin/visuals/ItemFrameVisual.java +++ b/common/src/vanillin/java/dev/engine_room/vanillin/visuals/ItemFrameVisual.java @@ -1,182 +1,174 @@ -package dev.engine_room.vanillin.visuals; - -import org.joml.Matrix4f; - -import dev.engine_room.flywheel.api.model.Model; -import dev.engine_room.flywheel.api.visual.EntityVisual; -import dev.engine_room.flywheel.api.visualization.VisualizationContext; -import dev.engine_room.flywheel.lib.instance.InstanceTypes; -import dev.engine_room.flywheel.lib.instance.TransformedInstance; -import dev.engine_room.flywheel.lib.model.baked.BakedModelBuilder; -import dev.engine_room.flywheel.lib.util.RendererReloadCache; -import dev.engine_room.flywheel.lib.visual.AbstractVisual; -import dev.engine_room.flywheel.lib.visual.SimpleDynamicVisual; -import dev.engine_room.vanillin.item.ItemModels; -import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.LightTexture; -import net.minecraft.client.resources.model.ModelManager; -import net.minecraft.client.resources.model.ModelResourceLocation; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.util.Mth; -import net.minecraft.world.entity.EntityType; -import net.minecraft.world.entity.decoration.ItemFrame; -import net.minecraft.world.item.ItemDisplayContext; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.Items; -import net.minecraft.world.level.LightLayer; - -public class ItemFrameVisual extends AbstractVisual implements EntityVisual, SimpleDynamicVisual { - private static final ModelResourceLocation FRAME_LOCATION = ModelResourceLocation.vanilla("item_frame", "map=false"); - private static final ModelResourceLocation MAP_FRAME_LOCATION = ModelResourceLocation.vanilla("item_frame", "map=true"); - private static final ModelResourceLocation GLOW_FRAME_LOCATION = ModelResourceLocation.vanilla("glow_item_frame", "map=false"); - private static final ModelResourceLocation GLOW_MAP_FRAME_LOCATION = ModelResourceLocation.vanilla("glow_item_frame", "map=true"); - - public static final RendererReloadCache MODEL_RESOURCE_LOCATION = new RendererReloadCache<>(mrl -> { - ModelManager modelManager = Minecraft.getInstance() - .getModelManager() - .getBlockModelShaper() - .getModelManager(); - - return new BakedModelBuilder(modelManager.getModel(mrl)) - .build(); - }); - - private final Matrix4f baseTransform = new Matrix4f(); - - private final TransformedInstance frame; - private final TransformedInstance item; - private final ItemFrame entity; - private ModelResourceLocation lastFrameLocation; - private ItemStack lastItemStack; - - public ItemFrameVisual(VisualizationContext ctx, ItemFrame entity, float partialTick) { - super(ctx, entity.level(), partialTick); - - this.entity = entity; - - lastItemStack = entity.getItem() - .copy(); - - lastFrameLocation = getFrameModelResourceLoc(entity, lastItemStack); - var frameModel = MODEL_RESOURCE_LOCATION.get(lastFrameLocation); - - frame = ctx.instancerProvider() - .instancer(InstanceTypes.TRANSFORMED, frameModel) - .createInstance(); - - frame.setTransform(baseTransform); - - item = ctx.instancerProvider() - .instancer(InstanceTypes.TRANSFORMED, ItemModels.get(level, lastItemStack, ItemDisplayContext.FIXED)) - .createInstance(); - - animate(partialTick); - } - - public static boolean shouldVisualize(ItemFrame entity) { - // We don't support map rendering, and we can't support exotic item models. - return !entity.getItem() - .is(Items.FILLED_MAP) && ItemModels.isSupported(entity.getItem()); - } - - @Override - public void beginFrame(Context ctx) { - animate(ctx.partialTick()); - } - - public void animate(float partialTick) { - var light = LightTexture.pack(getBlockLightLevel(entity.getPos()), getSkyLightLevel(entity.getPos())); - - boolean invisible = entity.isInvisible(); - - Direction direction = entity.getDirection(); - var origin = visualizationContext.renderOrigin(); - - float d = 0.46875f; - - float x = (float) (entity.getX() - origin.getX() + direction.getStepX() * d); - float y = (float) (entity.getY() - origin.getY() + direction.getStepY() * d); - float z = (float) (entity.getZ() - origin.getZ() + direction.getStepZ() * d); - - baseTransform.translation(x, y, z); - baseTransform.rotateXYZ(Mth.DEG_TO_RAD * entity.getXRot(), Mth.DEG_TO_RAD * (180.0f - entity.getYRot()), 0.0f); - - var stack = entity.getItem(); - var frameLocation = getFrameModelResourceLoc(entity, stack); - - if (frameLocation != lastFrameLocation) { - visualizationContext.instancerProvider() - .instancer(InstanceTypes.TRANSFORMED, MODEL_RESOURCE_LOCATION.get(frameLocation)) - .stealInstance(frame); - lastFrameLocation = frameLocation; - } - - frame.setVisible(!invisible); - - frame.setTransform(baseTransform) - .translate(-0.5f, -0.5f, -0.5f) - .light(light) - .setChanged(); - - if (!ItemStack.matches(lastItemStack, stack)) { - lastItemStack = stack.copy(); - visualizationContext.instancerProvider() - .instancer(InstanceTypes.TRANSFORMED, ItemModels.get(level, lastItemStack, ItemDisplayContext.FIXED)) - .stealInstance(item); - } - - item.setTransform(baseTransform); - - if (invisible) { - item.translate(0.0F, 0.0F, 0.5F); - } else { - item.translate(0.0F, 0.0F, 0.4375F); - } - - int i = entity.hasFramedMap() ? entity.getRotation() % 4 * 2 : entity.getRotation(); - - item.rotateZDegrees(i * 360.0F / 8.0F); - - item.scale(0.5F, 0.5F, 0.5F); - - item.light(getLightVal(15728880, light)) - .setChanged(); - } - - @Override - public void update(float partialTick) { - - } - - @Override - protected void _delete() { - frame.delete(); - item.delete(); - } - - private int getLightVal(int glowLightVal, int regularLightVal) { - return entity.getType() == EntityType.GLOW_ITEM_FRAME ? glowLightVal : regularLightVal; - } - - protected int getSkyLightLevel(BlockPos pos) { - return level.getBrightness(LightLayer.SKY, pos); - } - - protected int getBlockLightLevelBase(BlockPos pos) { - return entity.isOnFire() ? 15 : level.getBrightness(LightLayer.BLOCK, pos); - } - - protected int getBlockLightLevel(BlockPos pos) { - return entity.getType() == EntityType.GLOW_ITEM_FRAME ? Math.max(5, getBlockLightLevelBase(pos)) : getBlockLightLevelBase(pos); - } - - public static ModelResourceLocation getFrameModelResourceLoc(ItemFrame entity, ItemStack item) { - boolean bl = entity.getType() == EntityType.GLOW_ITEM_FRAME; - if (item.is(Items.FILLED_MAP)) { - return bl ? GLOW_MAP_FRAME_LOCATION : MAP_FRAME_LOCATION; - } else { - return bl ? GLOW_FRAME_LOCATION : FRAME_LOCATION; - } - } -} +// FIXME 1.21.11: port +//package dev.engine_room.vanillin.visuals; +// +//import org.joml.Matrix4f; +// +//import dev.engine_room.flywheel.api.model.Model; +//import dev.engine_room.flywheel.api.visual.EntityVisual; +//import dev.engine_room.flywheel.api.visualization.VisualizationContext; +//import dev.engine_room.flywheel.lib.instance.InstanceTypes; +//import dev.engine_room.flywheel.lib.instance.TransformedInstance; +//import dev.engine_room.flywheel.lib.model.baked.BlockModelBuilder; +//import dev.engine_room.flywheel.lib.util.RendererReloadCache; +//import dev.engine_room.flywheel.lib.visual.AbstractVisual; +//import dev.engine_room.flywheel.lib.visual.SimpleDynamicVisual; +//import dev.engine_room.vanillin.item.ItemModels; +//import net.minecraft.client.Minecraft; +//import net.minecraft.client.renderer.block.BlockModelShaper; +//import net.minecraft.client.resources.model.BlockStateDefinitions; +//import net.minecraft.core.BlockPos; +//import net.minecraft.core.Direction; +//import net.minecraft.util.Mth; +//import net.minecraft.world.entity.EntityType; +//import net.minecraft.world.entity.decoration.ItemFrame; +//import net.minecraft.world.item.ItemDisplayContext; +//import net.minecraft.world.item.ItemStack; +//import net.minecraft.world.item.Items; +//import net.minecraft.world.level.LightLayer; +//import net.minecraft.world.level.block.state.BlockState; +// +//public class ItemFrameVisual extends AbstractVisual implements EntityVisual, SimpleDynamicVisual { +// public static final RendererReloadCache BLOCK_STATE = new RendererReloadCache<>(state -> { +// BlockModelShaper blockModelShaper = Minecraft.getInstance() +// .getModelManager() +// .getBlockModelShaper(); +// +// return new BlockModelBuilder(blockModelShaper.getBlockModel(state)) +// .build(); +// }); +// +// private final Matrix4f baseTransform = new Matrix4f(); +// +// private final TransformedInstance frame; +// private final TransformedInstance item; +// private final ItemFrame entity; +// private BlockState lastFrameBlockState; +// private ItemStack lastItemStack; +// +// public ItemFrameVisual(VisualizationContext ctx, ItemFrame entity, float partialTick) { +// super(ctx, entity.level(), partialTick); +// +// this.entity = entity; +// +// lastItemStack = entity.getItem() +// .copy(); +// +// lastFrameBlockState = getFrameBlockState(entity, lastItemStack); +// var frameModel = BLOCK_STATE.get(lastFrameBlockState); +// +// frame = ctx.instancerProvider() +// .instancer(InstanceTypes.TRANSFORMED, frameModel) +// .createInstance(); +// +// frame.setTransform(baseTransform); +// +// item = ctx.instancerProvider() +// .instancer(InstanceTypes.TRANSFORMED, ItemModels.get(level, lastItemStack, ItemDisplayContext.FIXED)) +// .createInstance(); +// +// animate(partialTick); +// } +// +// public static boolean shouldVisualize(ItemFrame entity) { +// // We don't support map rendering, and we can't support exotic item models. +// return !entity.getItem() +// .is(Items.FILLED_MAP) && ItemModels.isSupported(entity.getItem()); +// } +// +// @Override +// public void beginFrame(Context ctx) { +// animate(ctx.partialTick()); +// } +// +// public void animate(float partialTick) { +// var light = LightTexture.pack(getBlockLightLevel(entity.getPos()), getSkyLightLevel(entity.getPos())); +// +// boolean invisible = entity.isInvisible(); +// +// Direction direction = entity.getDirection(); +// var origin = visualizationContext.renderOrigin(); +// +// float d = 0.46875f; +// +// float x = (float) (entity.getX() - origin.getX() + direction.getStepX() * d); +// float y = (float) (entity.getY() - origin.getY() + direction.getStepY() * d); +// float z = (float) (entity.getZ() - origin.getZ() + direction.getStepZ() * d); +// +// baseTransform.translation(x, y, z); +// baseTransform.rotateXYZ(Mth.DEG_TO_RAD * entity.getXRot(), Mth.DEG_TO_RAD * (180.0f - entity.getYRot()), 0.0f); +// +// var stack = entity.getItem(); +// var frameBlockState = getFrameBlockState(entity, stack); +// +// if (frameBlockState != lastFrameBlockState) { +// visualizationContext.instancerProvider() +// .instancer(InstanceTypes.TRANSFORMED, BLOCK_STATE.get(frameBlockState)) +// .stealInstance(frame); +// lastFrameBlockState = frameBlockState; +// } +// +// frame.setVisible(!invisible); +// +// frame.setTransform(baseTransform) +// .translate(-0.5f, -0.5f, -0.5f) +// .light(light) +// .setChanged(); +// +// if (!ItemStack.matches(lastItemStack, stack)) { +// lastItemStack = stack.copy(); +// visualizationContext.instancerProvider() +// .instancer(InstanceTypes.TRANSFORMED, ItemModels.get(level, lastItemStack, ItemDisplayContext.FIXED)) +// .stealInstance(item); +// } +// +// item.setTransform(baseTransform); +// +// if (invisible) { +// item.translate(0.0F, 0.0F, 0.5F); +// } else { +// item.translate(0.0F, 0.0F, 0.4375F); +// } +// +// int i = entity.hasFramedMap() ? entity.getRotation() % 4 * 2 : entity.getRotation(); +// +// item.rotateZDegrees(i * 360.0F / 8.0F); +// +// item.scale(0.5F, 0.5F, 0.5F); +// +// item.light(getLightVal(15728880, light)) +// .setChanged(); +// } +// +// @Override +// public void update(float partialTick) { +// +// } +// +// @Override +// protected void _delete() { +// frame.delete(); +// item.delete(); +// } +// +// private int getLightVal(int glowLightVal, int regularLightVal) { +// return entity.getType() == EntityType.GLOW_ITEM_FRAME ? glowLightVal : regularLightVal; +// } +// +// protected int getSkyLightLevel(BlockPos pos) { +// return level.getBrightness(LightLayer.SKY, pos); +// } +// +// protected int getBlockLightLevelBase(BlockPos pos) { +// return entity.isOnFire() ? 15 : level.getBrightness(LightLayer.BLOCK, pos); +// } +// +// protected int getBlockLightLevel(BlockPos pos) { +// return entity.getType() == EntityType.GLOW_ITEM_FRAME ? Math.max(5, getBlockLightLevelBase(pos)) : getBlockLightLevelBase(pos); +// } +// +// public static BlockState getFrameBlockState(ItemFrame entity, ItemStack item) { +// boolean isGlowFrame = entity.getType() == EntityType.GLOW_ITEM_FRAME; +// boolean map = !item.isEmpty() && entity.getFramedMapId(item) != null; +// return BlockStateDefinitions.getItemFrameFakeState(isGlowFrame, map); +// } +//} diff --git a/common/src/vanillin/java/dev/engine_room/vanillin/visuals/ItemVisual.java b/common/src/vanillin/java/dev/engine_room/vanillin/visuals/ItemVisual.java index 5e3aadc64..273ee7f21 100644 --- a/common/src/vanillin/java/dev/engine_room/vanillin/visuals/ItemVisual.java +++ b/common/src/vanillin/java/dev/engine_room/vanillin/visuals/ItemVisual.java @@ -1,161 +1,162 @@ -package dev.engine_room.vanillin.visuals; - -import com.mojang.blaze3d.vertex.PoseStack; -import com.mojang.math.Axis; - -import dev.engine_room.flywheel.api.visualization.VisualizationContext; -import dev.engine_room.flywheel.lib.instance.InstanceTypes; -import dev.engine_room.flywheel.lib.instance.TransformedInstance; -import dev.engine_room.flywheel.lib.transform.TransformStack; -import dev.engine_room.flywheel.lib.visual.AbstractEntityVisual; -import dev.engine_room.flywheel.lib.visual.SimpleDynamicVisual; -import dev.engine_room.flywheel.lib.visual.util.InstanceRecycler; -import dev.engine_room.vanillin.item.ItemModels; -import net.minecraft.client.renderer.LightTexture; -import net.minecraft.client.resources.model.BakedModel; -import net.minecraft.util.Mth; -import net.minecraft.util.RandomSource; -import net.minecraft.world.entity.item.ItemEntity; -import net.minecraft.world.item.Item; -import net.minecraft.world.item.ItemDisplayContext; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.LightLayer; - -public class ItemVisual extends AbstractEntityVisual implements SimpleDynamicVisual { - - private static final ThreadLocal RANDOM = ThreadLocal.withInitial(RandomSource::createNewThreadLocalInstance); - - private final PoseStack pPoseStack = new PoseStack(); - private BakedModel bakedModel; - private ItemStack currentStack; - - private InstanceRecycler instances; - - public ItemVisual(VisualizationContext ctx, ItemEntity entity, float partialTick) { - super(ctx, entity, partialTick); - - currentStack = entity.getItem(); - bakedModel = ItemModels.getModel(currentStack); - var model = ItemModels.get(level, currentStack, ItemDisplayContext.GROUND); - instances = new InstanceRecycler<>(() -> ctx.instancerProvider() - .instancer(InstanceTypes.TRANSFORMED, model) - .createInstance()); - - animate(partialTick); - } - - public static boolean isSupported(ItemEntity entity) { - return ItemModels.isSupported(entity.getItem()); - } - - @Override - public void beginFrame(Context ctx) { - if (!isVisible(ctx.frustum())) { - return; - } - - animate(ctx.partialTick()); - } - - private void animate(float partialTick) { - pPoseStack.setIdentity(); - TransformStack.of(pPoseStack) - .translate(getVisualPosition(partialTick)); - - ItemStack itemstack = entity.getItem(); - if (!ItemStack.matches(itemstack, currentStack)) { - instances.delete(); - currentStack = itemstack.copy(); - bakedModel = ItemModels.getModel(currentStack); - var model = ItemModels.get(level, currentStack, ItemDisplayContext.GROUND); - instances = new InstanceRecycler<>(() -> visualizationContext.instancerProvider() - .instancer(InstanceTypes.TRANSFORMED, model) - .createInstance()); - } - instances.resetCount(); - - int i = itemstack.isEmpty() ? 187 : Item.getId(itemstack.getItem()) + itemstack.getDamageValue(); - var random = RANDOM.get(); - random.setSeed(i); - boolean flag = bakedModel.isGui3d(); - int j = this.getRenderAmount(itemstack); - float f = 0.25F; - float f1 = shouldBob() ? Mth.sin(((float) entity.getAge() + partialTick) / 10.0F + entity.bobOffs) * 0.1F + 0.1F : 0; - float groundScaleX = bakedModel.getTransforms().ground.scale.y(); - float groundScaleY = bakedModel.getTransforms().ground.scale.y(); - float groundScaleZ = bakedModel.getTransforms().ground.scale.y(); - pPoseStack.translate(0.0F, f1 + 0.25F * groundScaleZ, 0.0F); - float f3 = entity.getSpin(partialTick); - pPoseStack.mulPose(Axis.YP.rotation(f3)); - if (!flag) { - float f7 = -0.0F * (float) (j - 1) * 0.5F * groundScaleX; - float f8 = -0.0F * (float) (j - 1) * 0.5F * groundScaleY; - float f9 = -0.09375F * (float) (j - 1) * 0.5F * groundScaleZ; - pPoseStack.translate(f7, f8, f9); - } - - int light = LightTexture.pack(level.getBrightness(LightLayer.BLOCK, entity.blockPosition()), level.getBrightness(LightLayer.SKY, entity.blockPosition())); - - for (int k = 0; k < j; ++k) { - pPoseStack.pushPose(); - if (k > 0) { - if (flag) { - float f11 = (random.nextFloat() * 2.0F - 1.0F) * 0.15F; - float f13 = (random.nextFloat() * 2.0F - 1.0F) * 0.15F; - float f10 = (random.nextFloat() * 2.0F - 1.0F) * 0.15F; - pPoseStack.translate(shouldSpreadItems() ? f11 : 0, shouldSpreadItems() ? f13 : 0, shouldSpreadItems() ? f10 : 0); - } else { - float f12 = (random.nextFloat() * 2.0F - 1.0F) * 0.15F * 0.5F; - float f14 = (random.nextFloat() * 2.0F - 1.0F) * 0.15F * 0.5F; - pPoseStack.translate(shouldSpreadItems() ? f12 : 0, shouldSpreadItems() ? f14 : 0, 0.0D); - } - } - - instances.get() - .setTransform(pPoseStack.last()) - .light(light) - .setChanged(); - pPoseStack.popPose(); - if (!flag) { - pPoseStack.translate(0.0, 0.0, 0.09375F * groundScaleZ); - } - } - - instances.discardExtra(); - } - - protected int getRenderAmount(ItemStack pStack) { - int i = 1; - if (pStack.getCount() > 48) { - i = 5; - } else if (pStack.getCount() > 32) { - i = 4; - } else if (pStack.getCount() > 16) { - i = 3; - } else if (pStack.getCount() > 1) { - i = 2; - } - - return i; - } - - /** - * @return If items should spread out when rendered in 3D - */ - public boolean shouldSpreadItems() { - return true; - } - - /** - * @return If items should have a bob effect - */ - public boolean shouldBob() { - return true; - } - - @Override - protected void _delete() { - instances.delete(); - } - -} +// FIXME 1.21.11: port +//package dev.engine_room.vanillin.visuals; +// +//import com.mojang.blaze3d.vertex.PoseStack; +//import com.mojang.math.Axis; +// +//import dev.engine_room.flywheel.api.visualization.VisualizationContext; +//import dev.engine_room.flywheel.lib.instance.InstanceTypes; +//import dev.engine_room.flywheel.lib.instance.TransformedInstance; +//import dev.engine_room.flywheel.lib.transform.TransformStack; +//import dev.engine_room.flywheel.lib.visual.AbstractEntityVisual; +//import dev.engine_room.flywheel.lib.visual.SimpleDynamicVisual; +//import dev.engine_room.flywheel.lib.visual.util.InstanceRecycler; +//import dev.engine_room.vanillin.item.ItemModels; +//import net.minecraft.client.renderer.LightTexture; +//import net.minecraft.client.resources.model.BakedModel; +//import net.minecraft.util.Mth; +//import net.minecraft.util.RandomSource; +//import net.minecraft.world.entity.item.ItemEntity; +//import net.minecraft.world.item.Item; +//import net.minecraft.world.item.ItemDisplayContext; +//import net.minecraft.world.item.ItemStack; +//import net.minecraft.world.level.LightLayer; +// +//public class ItemVisual extends AbstractEntityVisual implements SimpleDynamicVisual { +// +// private static final ThreadLocal RANDOM = ThreadLocal.withInitial(RandomSource::createNewThreadLocalInstance); +// +// private final PoseStack pPoseStack = new PoseStack(); +// private BakedModel bakedModel; +// private ItemStack currentStack; +// +// private InstanceRecycler instances; +// +// public ItemVisual(VisualizationContext ctx, ItemEntity entity, float partialTick) { +// super(ctx, entity, partialTick); +// +// currentStack = entity.getItem(); +// bakedModel = ItemModels.getModel(currentStack); +// var model = ItemModels.get(level, currentStack, ItemDisplayContext.GROUND); +// instances = new InstanceRecycler<>(() -> ctx.instancerProvider() +// .instancer(InstanceTypes.TRANSFORMED, model) +// .createInstance()); +// +// animate(partialTick); +// } +// +// public static boolean isSupported(ItemEntity entity) { +// return ItemModels.isSupported(entity.getItem()); +// } +// +// @Override +// public void beginFrame(Context ctx) { +// if (!isVisible(ctx.frustum())) { +// return; +// } +// +// animate(ctx.partialTick()); +// } +// +// private void animate(float partialTick) { +// pPoseStack.setIdentity(); +// TransformStack.of(pPoseStack) +// .translate(getVisualPosition(partialTick)); +// +// ItemStack itemstack = entity.getItem(); +// if (!ItemStack.matches(itemstack, currentStack)) { +// instances.delete(); +// currentStack = itemstack.copy(); +// bakedModel = ItemModels.getModel(currentStack); +// var model = ItemModels.get(level, currentStack, ItemDisplayContext.GROUND); +// instances = new InstanceRecycler<>(() -> visualizationContext.instancerProvider() +// .instancer(InstanceTypes.TRANSFORMED, model) +// .createInstance()); +// } +// instances.resetCount(); +// +// int i = itemstack.isEmpty() ? 187 : Item.getId(itemstack.getItem()) + itemstack.getDamageValue(); +// var random = RANDOM.get(); +// random.setSeed(i); +// boolean flag = bakedModel.isGui3d(); +// int j = this.getRenderAmount(itemstack); +// float f = 0.25F; +// float f1 = shouldBob() ? Mth.sin(((float) entity.getAge() + partialTick) / 10.0F + entity.bobOffs) * 0.1F + 0.1F : 0; +// float groundScaleX = bakedModel.getTransforms().ground.scale.y(); +// float groundScaleY = bakedModel.getTransforms().ground.scale.y(); +// float groundScaleZ = bakedModel.getTransforms().ground.scale.y(); +// pPoseStack.translate(0.0F, f1 + 0.25F * groundScaleZ, 0.0F); +// float f3 = entity.getSpin(partialTick); +// pPoseStack.mulPose(Axis.YP.rotation(f3)); +// if (!flag) { +// float f7 = -0.0F * (float) (j - 1) * 0.5F * groundScaleX; +// float f8 = -0.0F * (float) (j - 1) * 0.5F * groundScaleY; +// float f9 = -0.09375F * (float) (j - 1) * 0.5F * groundScaleZ; +// pPoseStack.translate(f7, f8, f9); +// } +// +// int light = LightTexture.pack(level.getBrightness(LightLayer.BLOCK, entity.blockPosition()), level.getBrightness(LightLayer.SKY, entity.blockPosition())); +// +// for (int k = 0; k < j; ++k) { +// pPoseStack.pushPose(); +// if (k > 0) { +// if (flag) { +// float f11 = (random.nextFloat() * 2.0F - 1.0F) * 0.15F; +// float f13 = (random.nextFloat() * 2.0F - 1.0F) * 0.15F; +// float f10 = (random.nextFloat() * 2.0F - 1.0F) * 0.15F; +// pPoseStack.translate(shouldSpreadItems() ? f11 : 0, shouldSpreadItems() ? f13 : 0, shouldSpreadItems() ? f10 : 0); +// } else { +// float f12 = (random.nextFloat() * 2.0F - 1.0F) * 0.15F * 0.5F; +// float f14 = (random.nextFloat() * 2.0F - 1.0F) * 0.15F * 0.5F; +// pPoseStack.translate(shouldSpreadItems() ? f12 : 0, shouldSpreadItems() ? f14 : 0, 0.0D); +// } +// } +// +// instances.get() +// .setTransform(pPoseStack.last()) +// .light(light) +// .setChanged(); +// pPoseStack.popPose(); +// if (!flag) { +// pPoseStack.translate(0.0, 0.0, 0.09375F * groundScaleZ); +// } +// } +// +// instances.discardExtra(); +// } +// +// protected int getRenderAmount(ItemStack pStack) { +// int i = 1; +// if (pStack.getCount() > 48) { +// i = 5; +// } else if (pStack.getCount() > 32) { +// i = 4; +// } else if (pStack.getCount() > 16) { +// i = 3; +// } else if (pStack.getCount() > 1) { +// i = 2; +// } +// +// return i; +// } +// +// /** +// * @return If items should spread out when rendered in 3D +// */ +// public boolean shouldSpreadItems() { +// return true; +// } +// +// /** +// * @return If items should have a bob effect +// */ +// public boolean shouldBob() { +// return true; +// } +// +// @Override +// protected void _delete() { +// instances.delete(); +// } +// +//} diff --git a/common/src/vanillin/java/dev/engine_room/vanillin/visuals/MinecartVisual.java b/common/src/vanillin/java/dev/engine_room/vanillin/visuals/MinecartVisual.java index 1b495d6de..a1b833fd4 100644 --- a/common/src/vanillin/java/dev/engine_room/vanillin/visuals/MinecartVisual.java +++ b/common/src/vanillin/java/dev/engine_room/vanillin/visuals/MinecartVisual.java @@ -1,8 +1,8 @@ package dev.engine_room.vanillin.visuals; -import org.jetbrains.annotations.Nullable; import org.joml.Matrix4f; import org.joml.Matrix4fStack; +import org.jspecify.annotations.Nullable; import dev.engine_room.flywheel.api.material.Material; import dev.engine_room.flywheel.api.visual.DynamicVisual; @@ -18,16 +18,22 @@ import dev.engine_room.flywheel.lib.visual.AbstractEntityVisual; import dev.engine_room.flywheel.lib.visual.SimpleDynamicVisual; import dev.engine_room.flywheel.lib.visual.SimpleTickableVisual; +import dev.engine_room.vanillin.mixin.BlockModelSetAccessor; +import net.minecraft.client.Minecraft; import net.minecraft.client.model.geom.ModelLayerLocation; -import net.minecraft.resources.ResourceLocation; +import net.minecraft.client.renderer.block.BlockModelSet; +import net.minecraft.resources.Identifier; import net.minecraft.util.Mth; -import net.minecraft.world.entity.vehicle.AbstractMinecart; +import net.minecraft.world.entity.vehicle.minecart.AbstractMinecart; +import net.minecraft.world.entity.vehicle.minecart.MinecartBehavior; +import net.minecraft.world.entity.vehicle.minecart.NewMinecartBehavior; +import net.minecraft.world.entity.vehicle.minecart.OldMinecartBehavior; import net.minecraft.world.level.block.RenderShape; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.phys.Vec3; public class MinecartVisual extends AbstractEntityVisual implements SimpleTickableVisual, SimpleDynamicVisual { - private static final ResourceLocation TEXTURE = ResourceLocation.withDefaultNamespace("textures/entity/minecart.png"); + private static final Identifier TEXTURE = Identifier.withDefaultNamespace("textures/entity/minecart/minecart.png"); private static final Material MATERIAL = SimpleMaterial.builder() .texture(TEXTURE) .mipmap(false) @@ -56,12 +62,12 @@ public MinecartVisual(VisualizationContext ctx, T entity, float partialTick, Mod private TransformedInstance createContentsInstance() { RenderShape shape = blockState.getRenderShape(); - if (shape == RenderShape.ENTITYBLOCK_ANIMATED) { - instances.visible(false); + if (shape == RenderShape.INVISIBLE) { return null; } - if (shape == RenderShape.INVISIBLE) { + if (hasSpecialRenderer(blockState)) { + instances.visible(false); return null; } @@ -104,7 +110,6 @@ private void updateInstances(float partialTick) { var renderOrigin = renderOrigin(); stack.translate((float) (posX - renderOrigin.getX()), (float) (posY - renderOrigin.getY()), (float) (posZ - renderOrigin.getZ())); - float yaw = Mth.lerp(partialTick, entity.yRotO, entity.getYRot()); long randomBits = entity.getId() * 493286711L; randomBits = randomBits * randomBits * 4392167121L + randomBits * 98761L; @@ -113,33 +118,13 @@ private void updateInstances(float partialTick) { float nudgeZ = (((float) (randomBits >> 24 & 7L) + 0.5f) / 8.0f - 0.5F) * 0.004f; stack.translate(nudgeX, nudgeY, nudgeZ); - Vec3 pos = entity.getPos(posX, posY, posZ); - float pitch = Mth.lerp(partialTick, entity.xRotO, entity.getXRot()); - if (pos != null) { - Vec3 offset1 = entity.getPosOffs(posX, posY, posZ, 0.3F); - Vec3 offset2 = entity.getPosOffs(posX, posY, posZ, -0.3F); - - if (offset1 == null) { - offset1 = pos; - } - - if (offset2 == null) { - offset2 = pos; - } - - stack.translate((float) (pos.x - posX), (float) ((offset1.y + offset2.y) / 2.0D - posY), (float) (pos.z - posZ)); - Vec3 vec = offset2.add(-offset1.x, -offset1.y, -offset1.z); - if (vec.length() != 0.0D) { - vec = vec.normalize(); - yaw = (float) (Math.atan2(vec.z, vec.x) * 180.0D / Math.PI); - pitch = (float) (Math.atan(vec.y) * 73.0D); - } + MinecartBehavior behaviour = entity.getBehavior(); + if (behaviour instanceof NewMinecartBehavior nmb) { + newRender(partialTick, nmb); + } else if (behaviour instanceof OldMinecartBehavior omb) { + oldRender(partialTick, omb, posX, posY, posZ); } - stack.translate(0.0F, 0.375F, 0.0F); - stack.rotateY((180 - yaw) * Mth.DEG_TO_RAD); - stack.rotateZ(-pitch * Mth.DEG_TO_RAD); - float hurtTime = entity.getHurtTime() - partialTick; float damage = entity.getDamage() - partialTick; @@ -168,6 +153,36 @@ private void updateInstances(float partialTick) { updateLight(partialTick); } + private void newRender(float partialTick, NewMinecartBehavior behavior) { + stack.rotateY(behavior.getCartLerpYRot(partialTick) * Mth.DEG_TO_RAD); + stack.rotateZ(-behavior.getCartLerpXRot(partialTick) * Mth.DEG_TO_RAD); + stack.translate(0.0F, 0.375F, 0.0F); + } + + private void oldRender(float partialTick, OldMinecartBehavior behavior, double posX, double posY, double posZ) { + Vec3 pos = behavior.getPos(posX, posY, posZ); + float pitch = Mth.lerp(partialTick, entity.xRotO, entity.getXRot()); + float yaw = Mth.lerp(partialTick, entity.yRotO, entity.getYRot()); + if (pos != null) { + Vec3 frontPos = behavior.getPosOffs(posX, posY, posZ, 0.3F); + Vec3 backPos = behavior.getPosOffs(posX, posY, posZ, -0.3F); + + if (frontPos != null && backPos != null) { + stack.translate((float) (pos.x - posX), (float) ((frontPos.y + backPos.y) / 2.0D - posY), (float) (pos.z - posZ)); + Vec3 vec = backPos.add(-frontPos.x, -frontPos.y, -frontPos.z); + if (vec.length() != 0.0D) { + vec = vec.normalize(); + yaw = (float) (Math.atan2(vec.z, vec.x) * 180.0D / Math.PI); + pitch = (float) (Math.atan(vec.y) * 73.0D); + } + } + } + + stack.translate(0.0F, 0.375F, 0.0F); + stack.rotateY((180 - yaw) * Mth.DEG_TO_RAD); + stack.rotateZ(-pitch * Mth.DEG_TO_RAD); + } + protected void updateContents(TransformedInstance contents, Matrix4f pose, float partialTick) { contents.setTransform(pose) .setChanged(); @@ -191,6 +206,16 @@ protected void _delete() { } public static boolean shouldSkipRender(AbstractMinecart minecart) { - return minecart.getDisplayBlockState().getRenderShape() != RenderShape.ENTITYBLOCK_ANIMATED; + BlockState state = minecart.getDisplayBlockState(); + if (state.getRenderShape() == RenderShape.INVISIBLE) { + return true; + } else { + return !hasSpecialRenderer(state); + } + } + + private static boolean hasSpecialRenderer(BlockState state) { + BlockModelSet blockModelSet = Minecraft.getInstance().getModelManager().getBlockModelSet(); + return ((BlockModelSetAccessor) blockModelSet).flywheel$getBlockModelByStateCache().containsKey(state); } } diff --git a/common/src/vanillin/java/dev/engine_room/vanillin/visuals/ShulkerBoxVisual.java b/common/src/vanillin/java/dev/engine_room/vanillin/visuals/ShulkerBoxVisual.java index 0080041a1..a957982a3 100644 --- a/common/src/vanillin/java/dev/engine_room/vanillin/visuals/ShulkerBoxVisual.java +++ b/common/src/vanillin/java/dev/engine_room/vanillin/visuals/ShulkerBoxVisual.java @@ -16,6 +16,7 @@ import dev.engine_room.flywheel.lib.visual.SimpleDynamicVisual; import net.minecraft.client.model.geom.ModelLayers; import net.minecraft.client.renderer.Sheets; +import net.minecraft.client.resources.model.sprite.SpriteId; import net.minecraft.core.Direction; import net.minecraft.util.Mth; import net.minecraft.world.item.DyeColor; @@ -42,7 +43,7 @@ public ShulkerBoxVisual(VisualizationContext ctx, ShulkerBoxBlockEntity blockEnt super(ctx, blockEntity, partialTick); DyeColor color = blockEntity.getColor(); - net.minecraft.client.resources.model.Material texture; + SpriteId texture; if (color == null) { texture = Sheets.DEFAULT_SHULKER_TEXTURE_LOCATION; } else { diff --git a/common/src/vanillin/java/dev/engine_room/vanillin/visuals/TntMinecartVisual.java b/common/src/vanillin/java/dev/engine_room/vanillin/visuals/TntMinecartVisual.java index 7cf6d0736..b21f04caf 100644 --- a/common/src/vanillin/java/dev/engine_room/vanillin/visuals/TntMinecartVisual.java +++ b/common/src/vanillin/java/dev/engine_room/vanillin/visuals/TntMinecartVisual.java @@ -7,7 +7,7 @@ import net.minecraft.client.model.geom.ModelLayers; import net.minecraft.client.renderer.texture.OverlayTexture; import net.minecraft.util.Mth; -import net.minecraft.world.entity.vehicle.MinecartTNT; +import net.minecraft.world.entity.vehicle.minecart.MinecartTNT; public class TntMinecartVisual extends MinecartVisual { private static final int WHITE_OVERLAY = OverlayTexture.pack(OverlayTexture.u(1.0F), 10); diff --git a/common/src/vanillin/resources/vanillin.mixins.json b/common/src/vanillin/resources/vanillin.mixins.json index 0b196dae8..f98a953ba 100644 --- a/common/src/vanillin/resources/vanillin.mixins.json +++ b/common/src/vanillin/resources/vanillin.mixins.json @@ -1,13 +1,13 @@ { - "required" : true, - "minVersion" : "0.8", - "package" : "dev.engine_room.vanillin.mixin", - "compatibilityLevel" : "JAVA_21", - "refmap" : "vanillin.refmap.json", - "client" : [ - "item.ItemOverridesAccessor" + "required": true, + "minVersion": "0.8", + "package": "dev.engine_room.vanillin.mixin", + "compatibilityLevel": "JAVA_25", + "client": [ + "BlockModelSetAccessor", + "ChestRendererAccessor" ], - "injectors" : { - "defaultRequire" : 1 + "injectors": { + "defaultRequire": 1 } } diff --git a/docs/flywheel/api/stage/fragment.glsl b/docs/flywheel/api/stage/fragment.glsl index e13ec6588..ffa82b5a1 100644 --- a/docs/flywheel/api/stage/fragment.glsl +++ b/docs/flywheel/api/stage/fragment.glsl @@ -12,7 +12,8 @@ /*const*/ vec4 flw_sampleColor; -/*const*/ float flw_distance; +/*const*/ float flw_sphericalDistance; +/*const*/ float flw_cylindricalDistance; vec4 flw_fragColor; ivec2 flw_fragOverlay; diff --git a/docs/flywheel/api/uniforms/fog.glsl b/docs/flywheel/api/uniforms/fog.glsl index 73ce76546..e8965975d 100644 --- a/docs/flywheel/api/uniforms/fog.glsl +++ b/docs/flywheel/api/uniforms/fog.glsl @@ -1,3 +1,5 @@ vec4 flw_fogColor; -vec2 flw_fogRange; -int flw_fogShape; +vec2 flw_fogEnvironmentalRange; +vec2 flw_fogRenderDistanceRange; +float flw_fogSkyEnd; +float flw_fogCloudEnd; diff --git a/docs/flywheel/api/uniforms/level.glsl b/docs/flywheel/api/uniforms/level.glsl index ec8f29f66..c901a877c 100644 --- a/docs/flywheel/api/uniforms/level.glsl +++ b/docs/flywheel/api/uniforms/level.glsl @@ -12,10 +12,13 @@ float flw_timeOfDay; uint flw_levelHasSkyLight; float flw_sunAngle; +float flw_moonAngle; +float flw_starAngle; float flw_moonBrightness; /** There are normally only 8 moon phases. */ uint flw_moonPhase; +float flw_starBrightness; uint flw_isRaining; float flw_rainLevel; @@ -24,7 +27,7 @@ float flw_thunderLevel; float flw_skyDarken; -uint flw_constantAmbientLight; +uint flw_cardinalLightType; /** Use FLW_DIMENSION_* ids to determine the dimension. May eventually be implemented for custom dimensions. */ uint flw_dimension; diff --git a/fabric/build.gradle.kts b/fabric/build.gradle.kts index d0afd06e6..01e37f12f 100644 --- a/fabric/build.gradle.kts +++ b/fabric/build.gradle.kts @@ -2,7 +2,7 @@ plugins { idea java `maven-publish` - id("dev.architectury.loom") + alias(libs.plugins.loom) id("flywheel.subproject") id("flywheel.platform") } @@ -68,7 +68,7 @@ platform { setupTestMod(testMod) } -var flywheelVersion = "${property("flywheel_version")}+${property("minecraft_version")}" +var flywheelVersion = "${property("flywheel_version")}+${libs.versions.minecraft.get()}" if (subproject.buildNumber != null) { flywheelVersion += ".build.${subproject.buildNumber}" @@ -95,23 +95,21 @@ tasks.withType().configureEach { } } +loom { + accessWidenerPath = file("src/main/resources/flywheel.accesswidener") +} + jarSets { - mainSet.publishWithRemappedSources { + mainSet.publishWithRawSources { artifactId = "flywheel-fabric-${property("artifact_minecraft_version")}" } mainSet.outgoing("flywheel") create("api", api, lib).apply { addToAssemble() - publishWithRemappedSources { + publishWithRawSources { artifactId = "flywheel-fabric-api-${property("artifact_minecraft_version")}" } - - configureJar { - manifest { - attributes("Fabric-Loom-Remap" to "true") - } - } } } @@ -119,20 +117,13 @@ defaultPackageInfos { sources(api, lib, backend, main) } -loom { - mixin { - useLegacyMixinAp = true - add(main, "flywheel.refmap.json") - add(backend, "backend-flywheel.refmap.json") - } -} - dependencies { - modImplementation("net.fabricmc:fabric-loader:${property("fabric_loader_version")}") - modApi("net.fabricmc.fabric-api:fabric-api:${property("fabric_api_version")}") + minecraft(libs.minecraft) + implementation(libs.fabric.loader) + api(libs.fabric.api) - modCompileOnly("maven.modrinth:sodium:${property("sodium_version")}-fabric") - modCompileOnly("maven.modrinth:iris:${property("iris_version")}-fabric") + compileOnly(libs.sodium.fabric.api) + compileOnly("maven.modrinth:iris:${libs.versions.iris.get()}-fabric") "forApi"(project(path = common, configuration = "apiClasses")) "forLib"(project(path = common, configuration = "libClasses")) diff --git a/fabric/gradle.properties b/fabric/gradle.properties deleted file mode 100644 index 6c5947614..000000000 --- a/fabric/gradle.properties +++ /dev/null @@ -1 +0,0 @@ -loom.platform = fabric diff --git a/fabric/src/backend/java/dev/engine_room/flywheel/backend/compile/FlwProgramsReloader.java b/fabric/src/backend/java/dev/engine_room/flywheel/backend/compile/FlwProgramsReloader.java deleted file mode 100644 index 7782a5d7d..000000000 --- a/fabric/src/backend/java/dev/engine_room/flywheel/backend/compile/FlwProgramsReloader.java +++ /dev/null @@ -1,27 +0,0 @@ -package dev.engine_room.flywheel.backend.compile; - -import dev.engine_room.flywheel.backend.NoiseTextures; -import dev.engine_room.flywheel.lib.util.ResourceUtil; -import net.fabricmc.fabric.api.resource.SimpleSynchronousResourceReloadListener; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.server.packs.resources.ResourceManager; - -public final class FlwProgramsReloader implements SimpleSynchronousResourceReloadListener { - public static final FlwProgramsReloader INSTANCE = new FlwProgramsReloader(); - - public static final ResourceLocation ID = ResourceUtil.rl("programs"); - - private FlwProgramsReloader() { - } - - @Override - public void onResourceManagerReload(ResourceManager manager) { - FlwPrograms.reload(manager); - NoiseTextures.reload(manager); - } - - @Override - public ResourceLocation getFabricId() { - return ID; - } -} diff --git a/fabric/src/lib/java/dev/engine_room/flywheel/lib/model/baked/BakedModelBufferer.java b/fabric/src/lib/java/dev/engine_room/flywheel/lib/model/baked/BakedModelBufferer.java deleted file mode 100644 index 721c1bda9..000000000 --- a/fabric/src/lib/java/dev/engine_room/flywheel/lib/model/baked/BakedModelBufferer.java +++ /dev/null @@ -1,131 +0,0 @@ -package dev.engine_room.flywheel.lib.model.baked; - -import java.util.Iterator; - -import org.jetbrains.annotations.Nullable; - -import com.mojang.blaze3d.vertex.BufferBuilder; -import com.mojang.blaze3d.vertex.PoseStack; - -import dev.engine_room.flywheel.lib.model.SimpleModel; -import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.ItemBlockRenderTypes; -import net.minecraft.client.renderer.RenderType; -import net.minecraft.client.renderer.block.BlockRenderDispatcher; -import net.minecraft.client.renderer.block.ModelBlockRenderer; -import net.minecraft.client.renderer.texture.OverlayTexture; -import net.minecraft.client.resources.model.BakedModel; -import net.minecraft.core.BlockPos; -import net.minecraft.util.RandomSource; -import net.minecraft.world.level.BlockAndTintGetter; -import net.minecraft.world.level.block.RenderShape; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.material.FluidState; - -final class BakedModelBufferer { - private static final ThreadLocal THREAD_LOCAL_OBJECTS = ThreadLocal.withInitial(ThreadLocalObjects::new); - - private BakedModelBufferer() { - } - - public static SimpleModel bufferModel(BakedModel model, BlockPos pos, BlockAndTintGetter level, BlockState state, @Nullable PoseStack poseStack, BlockMaterialFunction blockMaterialFunction) { - ThreadLocalObjects objects = THREAD_LOCAL_OBJECTS.get(); - if (poseStack == null) { - poseStack = objects.identityPoseStack; - } - RandomSource random = objects.random; - FabricMeshEmitterManager emitters = objects.emitters; - - emitters.prepare(blockMaterialFunction); - - long seed = state.getSeed(pos); - - RenderType defaultLayer = ItemBlockRenderTypes.getChunkRenderType(state); - boolean useAo = Minecraft.useAmbientOcclusion(); - // See ModelBlockRenderer#tesselateBlock - boolean defaultAo = useAo && state.getLightEmission() == 0 && model.useAmbientOcclusion(); - model = emitters.prepareForModel(model, defaultLayer, useAo, defaultAo); - - poseStack.pushPose(); - Minecraft.getInstance() - .getBlockRenderer() - .getModelRenderer() - .tesselateBlock(level, model, state, pos, poseStack, emitters, false, random, seed, OverlayTexture.NO_OVERLAY); - poseStack.popPose(); - - return emitters.end(); - } - - public static SimpleModel bufferBlocks(Iterator posIterator, BlockAndTintGetter level, @Nullable PoseStack poseStack, boolean renderFluids, BlockMaterialFunction blockMaterialFunction) { - ThreadLocalObjects objects = THREAD_LOCAL_OBJECTS.get(); - if (poseStack == null) { - poseStack = objects.identityPoseStack; - } - RandomSource random = objects.random; - FabricMeshEmitterManager emitters = objects.emitters; - TransformingVertexConsumer transformingWrapper = objects.transformingWrapper; - - emitters.prepare(blockMaterialFunction); - - BlockRenderDispatcher renderDispatcher = Minecraft.getInstance() - .getBlockRenderer(); - ModelBlockRenderer blockRenderer = renderDispatcher.getModelRenderer(); - ModelBlockRenderer.enableCaching(); - - boolean useAo = Minecraft.useAmbientOcclusion(); - - while (posIterator.hasNext()) { - BlockPos pos = posIterator.next(); - BlockState state = level.getBlockState(pos); - - emitters.prepareForBlock(); - - if (renderFluids) { - FluidState fluidState = state.getFluidState(); - - if (!fluidState.isEmpty()) { - RenderType renderType = ItemBlockRenderTypes.getRenderLayer(fluidState); - - BufferBuilder bufferBuilder = emitters.getBuffer(renderType, true, false); - - if (bufferBuilder != null) { - transformingWrapper.prepare(bufferBuilder, poseStack); - - poseStack.pushPose(); - poseStack.translate(pos.getX() - (pos.getX() & 0xF), pos.getY() - (pos.getY() & 0xF), pos.getZ() - (pos.getZ() & 0xF)); - renderDispatcher.renderLiquid(pos, level, transformingWrapper, state, fluidState); - poseStack.popPose(); - } - } - } - - if (state.getRenderShape() == RenderShape.MODEL) { - long seed = state.getSeed(pos); - BakedModel model = renderDispatcher.getBlockModel(state); - - RenderType defaultLayer = ItemBlockRenderTypes.getChunkRenderType(state); - - // See ModelBlockRenderer#tesselateBlock - boolean defaultAo = useAo && state.getLightEmission() == 0 && model.useAmbientOcclusion(); - model = emitters.prepareForModel(model, defaultLayer, useAo, defaultAo); - - poseStack.pushPose(); - poseStack.translate(pos.getX(), pos.getY(), pos.getZ()); - blockRenderer.tesselateBlock(level, model, state, pos, poseStack, emitters, true, random, seed, OverlayTexture.NO_OVERLAY); - poseStack.popPose(); - } - } - - ModelBlockRenderer.clearCache(); - transformingWrapper.clear(); - return emitters.end(); - } - - private static class ThreadLocalObjects { - public final PoseStack identityPoseStack = new PoseStack(); - public final RandomSource random = RandomSource.createNewThreadLocalInstance(); - - public final FabricMeshEmitterManager emitters = new FabricMeshEmitterManager(); - public final TransformingVertexConsumer transformingWrapper = new TransformingVertexConsumer(); - } -} diff --git a/fabric/src/lib/java/dev/engine_room/flywheel/lib/model/baked/BlockStateModelBufferer.java b/fabric/src/lib/java/dev/engine_room/flywheel/lib/model/baked/BlockStateModelBufferer.java new file mode 100644 index 000000000..d05c9b551 --- /dev/null +++ b/fabric/src/lib/java/dev/engine_room/flywheel/lib/model/baked/BlockStateModelBufferer.java @@ -0,0 +1,154 @@ +package dev.engine_room.flywheel.lib.model.baked; + +import java.util.Iterator; + +import org.jetbrains.annotations.ApiStatus; +import org.jspecify.annotations.Nullable; + +import com.mojang.blaze3d.vertex.BufferBuilder; +import com.mojang.blaze3d.vertex.PoseStack; + +import dev.engine_room.flywheel.lib.model.SimpleModel; +import net.fabricmc.fabric.api.client.renderer.v1.Renderer; +import net.fabricmc.fabric.api.client.renderer.v1.mesh.QuadEmitter; +import net.fabricmc.fabric.api.client.renderer.v1.render.AltModelBlockRenderer; +import net.minecraft.client.Minecraft; +import net.minecraft.client.color.block.BlockColors; +import net.minecraft.client.renderer.block.BlockAndTintGetter; +import net.minecraft.client.renderer.block.BlockModelLighter; +import net.minecraft.client.renderer.block.FluidRenderer; +import net.minecraft.client.renderer.block.dispatch.BlockStateModel; +import net.minecraft.client.renderer.chunk.ChunkSectionLayer; +import net.minecraft.client.renderer.state.GameRenderState; +import net.minecraft.client.renderer.texture.OverlayTexture; +import net.minecraft.client.resources.model.ModelManager; +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.block.RenderShape; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.material.FluidState; + +@ApiStatus.Internal +public final class BlockStateModelBufferer { + private static final ThreadLocal THREAD_LOCAL_OBJECTS = ThreadLocal.withInitial(ThreadLocalObjects::new); + + private BlockStateModelBufferer() { + } + + public static SimpleModel bufferModel(BlockStateModel model, BlockPos pos, BlockAndTintGetter level, BlockState state, @Nullable PoseStack poseStack, BlockMaterialFunction blockMaterialFunction) { + ThreadLocalObjects objects = THREAD_LOCAL_OBJECTS.get(); + if (poseStack == null) { + poseStack = objects.identityPoseStack; + } + FabricMeshEmitterManager emitters = objects.emitters; + + emitters.prepare(blockMaterialFunction); + + long seed = state.getSeed(pos); + + Minecraft minecraft = Minecraft.getInstance(); + GameRenderState gameRenderState = minecraft.gameRenderer.getGameRenderState(); + BlockColors blockColors = minecraft.getBlockColors(); + + // See ModelBlockRenderer#tesselateBlock + boolean useAo = gameRenderState.optionsRenderState.ambientOcclusion; + boolean defaultAo = useAo && state.getLightEmission() == 0; + emitters.prepareForModel(useAo, defaultAo); + + AltModelBlockRenderer altModelBlockRenderer = Renderer.get().altModelBlockRenderer(useAo, true, blockColors); + + PoseStack finalPoseStack = poseStack; + QuadEmitter quadEmitter = Renderer.get().quadEmitter((quad) -> { + finalPoseStack.pushPose(); + ChunkSectionLayer layer = quad.chunkLayer(); + FabricMeshEmitter emitter = emitters.getEmitter(layer); + emitters.prepareForGeometry(quad); + quad.buffer(OverlayTexture.NO_OVERLAY, finalPoseStack.last(), emitter); + finalPoseStack.popPose(); + }); + + altModelBlockRenderer.tesselateBlock(quadEmitter, 0, 0, 0, level, pos, state, model, seed); + + return emitters.end(); + } + + public static SimpleModel bufferBlocks(Iterator posIterator, BlockAndTintGetter level, @Nullable PoseStack poseStack, boolean renderFluids, BlockMaterialFunction blockMaterialFunction) { + ThreadLocalObjects objects = THREAD_LOCAL_OBJECTS.get(); + if (poseStack == null) { + poseStack = objects.identityPoseStack; + } + FabricMeshEmitterManager emitters = objects.emitters; + TransformingVertexConsumer transformingWrapper = objects.transformingWrapper; + + emitters.prepare(blockMaterialFunction); + + BlockModelLighter.enableCaching(); + + Minecraft minecraft = Minecraft.getInstance(); + ModelManager modelManager = minecraft.getModelManager(); + GameRenderState gameRenderState = minecraft.gameRenderer.getGameRenderState(); + boolean useAo = gameRenderState.optionsRenderState.ambientOcclusion; + BlockColors blockColors = minecraft.getBlockColors(); + + AltModelBlockRenderer altModelBlockRenderer = Renderer.get().altModelBlockRenderer(useAo, true, blockColors); + FluidRenderer fluidRenderer = new FluidRenderer(modelManager.getFluidStateModelSet()); + + while (posIterator.hasNext()) { + BlockPos pos = posIterator.next(); + BlockState state = level.getBlockState(pos); + + emitters.prepareForBlock(); + + if (renderFluids) { + FluidState fluidState = state.getFluidState(); + + if (!fluidState.isEmpty()) { + poseStack.pushPose(); + poseStack.translate(pos.getX() - (pos.getX() & 0xF), pos.getY() - (pos.getY() & 0xF), pos.getZ() - (pos.getZ() & 0xF)); + PoseStack finalPoseStack = poseStack; + fluidRenderer.tesselate(level, pos, layer -> { + BufferBuilder bufferBuilder = emitters.getEmitter(layer).getBuffer(true, false); + + if (bufferBuilder != null) { + transformingWrapper.prepare(bufferBuilder, finalPoseStack); + return transformingWrapper; + } + + return EmptyVertexConsumer.INSTANCE; + }, state, fluidState); + poseStack.popPose(); + } + } + + if (state.getRenderShape() == RenderShape.MODEL) { + long seed = state.getSeed(pos); + BlockStateModel model = modelManager.getBlockStateModelSet().get(state); + + // See ModelBlockRenderer#tesselateBlock + boolean defaultAo = useAo && state.getLightEmission() == 0; + emitters.prepareForModel(useAo, defaultAo); + + PoseStack finalPoseStack = poseStack; + QuadEmitter quadEmitter = Renderer.get().quadEmitter((quad) -> { + finalPoseStack.pushPose(); + ChunkSectionLayer layer = quad.chunkLayer(); + FabricMeshEmitter emitter = emitters.getEmitter(layer); + emitters.prepareForGeometry(quad); + quad.buffer(OverlayTexture.NO_OVERLAY, finalPoseStack.last(), emitter); + finalPoseStack.popPose(); + }); + altModelBlockRenderer.tesselateBlock(quadEmitter, pos.getX(), pos.getY(), pos.getZ(), level, pos, state, model, seed); + } + } + + BlockModelLighter.clearCache(); + transformingWrapper.clear(); + return emitters.end(); + } + + private static class ThreadLocalObjects { + public final PoseStack identityPoseStack = new PoseStack(); + + public final FabricMeshEmitterManager emitters = new FabricMeshEmitterManager(); + public final TransformingVertexConsumer transformingWrapper = new TransformingVertexConsumer(); + } +} diff --git a/fabric/src/lib/java/dev/engine_room/flywheel/lib/model/baked/FabricMeshEmitter.java b/fabric/src/lib/java/dev/engine_room/flywheel/lib/model/baked/FabricMeshEmitter.java new file mode 100644 index 000000000..57a0473f6 --- /dev/null +++ b/fabric/src/lib/java/dev/engine_room/flywheel/lib/model/baked/FabricMeshEmitter.java @@ -0,0 +1,122 @@ +package dev.engine_room.flywheel.lib.model.baked; + +import com.mojang.blaze3d.vertex.BufferBuilder; +import com.mojang.blaze3d.vertex.PoseStack.Pose; +import com.mojang.blaze3d.vertex.QuadInstance; +import com.mojang.blaze3d.vertex.VertexConsumer; + +import net.minecraft.client.renderer.chunk.ChunkSectionLayer; +import net.minecraft.client.resources.model.geometry.BakedQuad; + +import org.jetbrains.annotations.ApiStatus; + +@ApiStatus.Internal +public class FabricMeshEmitter extends MeshEmitter { + private boolean shade; + private boolean ao; + + FabricMeshEmitter(ByteBufferBuilderStack byteBufferBuilderStack, ChunkSectionLayer chunkSectionLayer) { + super(byteBufferBuilderStack, chunkSectionLayer); + } + + public void prepareForGeometry(boolean shade, boolean ao) { + this.shade = shade; + this.ao = ao; + } + + @Override + public VertexConsumer addVertex(float x, float y, float z) { + BufferBuilder bufferBuilder = getBuffer(shade, ao); + if (bufferBuilder != null) { + bufferBuilder.addVertex(x, y, z); + } + return this; + } + + @Override + public VertexConsumer setColor(int red, int green, int blue, int alpha) { + BufferBuilder bufferBuilder = getBuffer(shade, ao); + if (bufferBuilder != null) { + bufferBuilder.setColor(red, green, blue, alpha); + } + return this; + } + + @Override + public VertexConsumer setColor(int color) { + BufferBuilder bufferBuilder = getBuffer(shade, ao); + if (bufferBuilder != null) { + bufferBuilder.setColor(color); + } + return this; + } + + @Override + public VertexConsumer setUv(float u, float v) { + BufferBuilder bufferBuilder = getBuffer(shade, ao); + if (bufferBuilder != null) { + bufferBuilder.setUv(u, v); + } + return this; + } + + @Override + public VertexConsumer setUv1(int u, int v) { + BufferBuilder bufferBuilder = getBuffer(shade, ao); + if (bufferBuilder != null) { + bufferBuilder.setUv1(u, v); + } + return this; + } + + @Override + public VertexConsumer setUv2(int u, int v) { + BufferBuilder bufferBuilder = getBuffer(shade, ao); + if (bufferBuilder != null) { + bufferBuilder.setUv2(u, v); + } + return this; + } + + @Override + public VertexConsumer setNormal(float x, float y, float z) { + BufferBuilder bufferBuilder = getBuffer(shade, ao); + if (bufferBuilder != null) { + bufferBuilder.setNormal(x, y, z); + } + return this; + } + + @Override + public VertexConsumer setLineWidth(float width) { + BufferBuilder bufferBuilder = getBuffer(shade, ao); + if (bufferBuilder != null) { + bufferBuilder.setLineWidth(width); + } + return this; + } + + @Override + public void addVertex(float x, float y, float z, int color, float u, float v, int packedOverlay, int packedLight, float normalX, float normalY, float normalZ) { + BufferBuilder bufferBuilder = getBuffer(shade, ao); + if (bufferBuilder != null) { + bufferBuilder.addVertex(x, y, z, color, u, v, packedOverlay, packedLight, normalX, normalY, normalZ); + } + } + + @Override + public void putBakedQuad(Pose pose, BakedQuad quad, QuadInstance instance) { + BufferBuilder bufferBuilder = getBuffer(shade, ao); + if (bufferBuilder != null) { + bufferBuilder.putBakedQuad(pose, quad, instance); + } + } + + @Override + public void putBlockBakedQuad(float x, float y, float z, BakedQuad quad, QuadInstance instance) { + BufferBuilder bufferBuilder = getBuffer(shade, ao); + if (bufferBuilder != null) { + bufferBuilder.putBlockBakedQuad(x, y, z, quad, instance); + } + } +} diff --git a/fabric/src/lib/java/dev/engine_room/flywheel/lib/model/baked/FabricMeshEmitterManager.java b/fabric/src/lib/java/dev/engine_room/flywheel/lib/model/baked/FabricMeshEmitterManager.java index 2f0a40f32..cfbaee447 100644 --- a/fabric/src/lib/java/dev/engine_room/flywheel/lib/model/baked/FabricMeshEmitterManager.java +++ b/fabric/src/lib/java/dev/engine_room/flywheel/lib/model/baked/FabricMeshEmitterManager.java @@ -1,154 +1,31 @@ package dev.engine_room.flywheel.lib.model.baked; -import java.util.function.Supplier; - -import org.jetbrains.annotations.Nullable; -import org.jetbrains.annotations.UnknownNullability; - -import com.mojang.blaze3d.vertex.BufferBuilder; -import com.mojang.blaze3d.vertex.PoseStack; -import com.mojang.blaze3d.vertex.VertexConsumer; - -import dev.engine_room.flywheel.lib.model.SimpleModel; -import net.fabricmc.fabric.api.renderer.v1.material.BlendMode; -import net.fabricmc.fabric.api.renderer.v1.material.RenderMaterial; -import net.fabricmc.fabric.api.renderer.v1.model.ForwardingBakedModel; -import net.fabricmc.fabric.api.renderer.v1.render.RenderContext; +import net.fabricmc.fabric.api.client.renderer.v1.mesh.QuadView; import net.fabricmc.fabric.api.util.TriState; -import net.minecraft.client.renderer.RenderType; -import net.minecraft.client.renderer.block.model.BakedQuad; -import net.minecraft.client.resources.model.BakedModel; -import net.minecraft.core.BlockPos; -import net.minecraft.util.RandomSource; -import net.minecraft.world.level.BlockAndTintGetter; -import net.minecraft.world.level.block.state.BlockState; -class FabricMeshEmitterManager extends MeshEmitterManager implements VertexConsumer { - private final WrapperModel wrapperModel = new WrapperModel(); +import org.jetbrains.annotations.ApiStatus; - @UnknownNullability - private RenderType defaultLayer; +@ApiStatus.Internal +public class FabricMeshEmitterManager extends MeshEmitterManager { private boolean useAo; private boolean defaultAo; - @Nullable - private BufferBuilder currentDelegate; FabricMeshEmitterManager() { - super(MeshEmitter::new); + super(FabricMeshEmitter::new); } - public BakedModel prepareForModel(BakedModel model, RenderType defaultLayer, boolean useAo, boolean defaultAo) { - this.defaultLayer = defaultLayer; + public void prepareForModel(boolean useAo, boolean defaultAo) { this.useAo = useAo; this.defaultAo = defaultAo; - wrapperModel.setWrapped(model); - return wrapperModel; - } - - @Override - public SimpleModel end() { - wrapperModel.setWrapped(null); - return super.end(); } - private void prepareForGeometry(RenderMaterial material) { - BlendMode blendMode = material.blendMode(); - RenderType layer = blendMode == BlendMode.DEFAULT ? defaultLayer : blendMode.blockRenderLayer; - boolean shade = !material.disableDiffuse(); - TriState aoMode = material.ambientOcclusion(); + public void prepareForGeometry(QuadView quad) { + boolean shade = quad.diffuseShade(); + TriState aoMode = quad.ambientOcclusion(); boolean ao = useAo && aoMode.orElse(defaultAo); - currentDelegate = getBuffer(layer, shade, ao); - } - - @Override - public VertexConsumer addVertex(float x, float y, float z) { - if (currentDelegate != null) { - currentDelegate.addVertex(x, y, z); - } - return this; - } - - @Override - public VertexConsumer setColor(int red, int green, int blue, int alpha) { - if (currentDelegate != null) { - currentDelegate.setColor(red, green, blue, alpha); - } - return this; - } - - @Override - public VertexConsumer setUv(float u, float v) { - if (currentDelegate != null) { - currentDelegate.setUv(u, v); - } - return this; - } - - @Override - public VertexConsumer setUv1(int u, int v) { - if (currentDelegate != null) { - currentDelegate.setUv1(u, v); - } - return this; - } - - @Override - public VertexConsumer setUv2(int u, int v) { - if (currentDelegate != null) { - currentDelegate.setUv2(u, v); - } - return this; - } - - @Override - public VertexConsumer setNormal(float x, float y, float z) { - if (currentDelegate != null) { - currentDelegate.setNormal(x, y, z); - } - return this; - } - - @Override - public void addVertex(float x, float y, float z, int color, float u, float v, int packedOverlay, int packedLight, float normalX, float normalY, float normalZ) { - if (currentDelegate != null) { - currentDelegate.addVertex(x, y, z, color, u, v, packedOverlay, packedLight, normalX, normalY, normalZ); - } - } - - @Override - public void putBulkData(PoseStack.Pose pose, BakedQuad quad, float red, float green, float blue, float alpha, int packedLight, int packedOverlay) { - if (currentDelegate != null) { - currentDelegate.putBulkData(pose, quad, red, green, blue, alpha, packedLight, packedOverlay); - } - } - - @Override - public void putBulkData(PoseStack.Pose pose, BakedQuad quad, float[] brightness, float red, float green, float blue, float alpha, int[] lightmap, int packedOverlay, boolean readAlpha) { - if (currentDelegate != null) { - currentDelegate.putBulkData(pose, quad, brightness, red, green, blue, alpha, lightmap, packedOverlay, readAlpha); - } - } - - private class WrapperModel extends ForwardingBakedModel { - private final RenderContext.QuadTransform quadTransform = quad -> { - FabricMeshEmitterManager.this.prepareForGeometry(quad.material()); - return true; - }; - - public void setWrapped(@Nullable BakedModel wrapped) { - this.wrapped = wrapped; - } - - @Override - public boolean isVanillaAdapter() { - return false; - } - @Override - public void emitBlockQuads(BlockAndTintGetter level, BlockState state, BlockPos pos, Supplier randomSupplier, RenderContext context) { - context.pushTransform(quadTransform); - super.emitBlockQuads(level, state, pos, randomSupplier, context); - context.popTransform(); + for (FabricMeshEmitter emitter : emitterMap.values()) { + emitter.prepareForGeometry(shade, ao); } } } diff --git a/fabric/src/lib/java/dev/engine_room/flywheel/lib/model/baked/FabricPartialModel.java b/fabric/src/lib/java/dev/engine_room/flywheel/lib/model/baked/FabricPartialModel.java new file mode 100644 index 000000000..c97c43a1d --- /dev/null +++ b/fabric/src/lib/java/dev/engine_room/flywheel/lib/model/baked/FabricPartialModel.java @@ -0,0 +1,74 @@ +package dev.engine_room.flywheel.lib.model.baked; + +import java.util.concurrent.ConcurrentMap; + +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; + +import com.google.common.collect.MapMaker; + +import dev.engine_room.flywheel.lib.util.IdentifierUtil; +import net.fabricmc.fabric.api.client.model.loading.v1.ExtraModelKey; +import net.fabricmc.fabric.api.client.model.loading.v1.ModelLoadingPlugin; +import net.fabricmc.fabric.api.client.model.loading.v1.UnbakedExtraModel; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.block.dispatch.BlockModelRotation; +import net.minecraft.client.renderer.block.dispatch.BlockStateModel; +import net.minecraft.client.renderer.block.dispatch.SingleVariant; +import net.minecraft.client.resources.model.ModelBaker; +import net.minecraft.client.resources.model.ModelManager; +import net.minecraft.client.resources.model.SimpleModelWrapper; +import net.minecraft.resources.Identifier; +import net.minecraft.server.packs.resources.ResourceManager; +import net.minecraft.server.packs.resources.ResourceManagerReloadListener; + +@ApiStatus.Internal +public class FabricPartialModel extends PartialModel { + private static final ConcurrentMap ALL = new MapMaker().weakValues().makeMap(); + + private final ExtraModelKey<@NotNull BlockStateModel> key; + + public FabricPartialModel(Identifier modelId) { + super(modelId); + key = ExtraModelKey.create(modelId::toString); + } + + public static FabricPartialModel of(Identifier modelId) { + return ALL.computeIfAbsent(modelId, FabricPartialModel::new); + } + + public static void registerAll(ModelLoadingPlugin.Context ctx) { + for (FabricPartialModel partial : ALL.values()) { + ctx.addModel(partial.key, partial.new Unbaked()); + } + } + + public static void refreshAll(ModelManager modelManager) { + for (FabricPartialModel partial : ALL.values()) { + partial.blockStateModel = modelManager.getModel(partial.key); + } + } + + private class Unbaked implements UnbakedExtraModel<@NotNull BlockStateModel> { + @Override + public BlockStateModel bake(ModelBaker baker) { + return new SingleVariant(SimpleModelWrapper.bake(baker, modelId, BlockModelRotation.IDENTITY)); + } + + @Override + public void resolveDependencies(Resolver resolver) { + resolver.markDependency(modelId); + } + } + + public static class ResourceReloadListener implements ResourceManagerReloadListener { + public static final Identifier ID = IdentifierUtil.id("partial_models"); + + public static final ResourceReloadListener INSTANCE = new ResourceReloadListener(); + + @Override + public void onResourceManagerReload(ResourceManager resourceManager) { + refreshAll(Minecraft.getInstance().getModelManager()); + } + } +} diff --git a/fabric/src/lib/java/dev/engine_room/flywheel/lib/model/baked/FabricSinglePosVirtualBlockGetter.java b/fabric/src/lib/java/dev/engine_room/flywheel/lib/model/baked/FabricSinglePosVirtualBlockGetter.java index 7a860daf3..462c4642e 100644 --- a/fabric/src/lib/java/dev/engine_room/flywheel/lib/model/baked/FabricSinglePosVirtualBlockGetter.java +++ b/fabric/src/lib/java/dev/engine_room/flywheel/lib/model/baked/FabricSinglePosVirtualBlockGetter.java @@ -2,7 +2,7 @@ import java.util.function.ToIntFunction; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import net.minecraft.core.BlockPos; import net.minecraft.world.level.block.entity.BlockEntity; diff --git a/fabric/src/lib/java/dev/engine_room/flywheel/lib/model/baked/ModelBuilderImpl.java b/fabric/src/lib/java/dev/engine_room/flywheel/lib/model/baked/ModelBuilderImpl.java index 4a0bcc4dd..741aa54c3 100644 --- a/fabric/src/lib/java/dev/engine_room/flywheel/lib/model/baked/ModelBuilderImpl.java +++ b/fabric/src/lib/java/dev/engine_room/flywheel/lib/model/baked/ModelBuilderImpl.java @@ -11,13 +11,13 @@ public final class ModelBuilderImpl { private ModelBuilderImpl() { } - public static SimpleModel buildBakedModelBuilder(BakedModelBuilder builder) { + public static SimpleModel buildBlockModelBuilder(BlockModelBuilder builder) { BlockState blockState = builder.level.getBlockState(builder.pos); - return BakedModelBufferer.bufferModel(builder.bakedModel, builder.pos, builder.level, blockState, builder.poseStack, builder.materialFunc); + return BlockStateModelBufferer.bufferModel(builder.blockModel, builder.pos, builder.level, blockState, builder.poseStack, builder.materialFunc); } - public static SimpleModel buildBlockModelBuilder(BlockModelBuilder builder) { - return BakedModelBufferer.bufferBlocks(builder.positions.iterator(), builder.level, builder.poseStack, builder.renderFluids, builder.materialFunc); + public static SimpleModel buildLevelModelBuilder(LevelModelBuilder builder) { + return BlockStateModelBufferer.bufferBlocks(builder.positions.iterator(), builder.level, builder.poseStack, builder.renderFluids, builder.materialFunc); } } diff --git a/fabric/src/lib/java/dev/engine_room/flywheel/lib/model/baked/PartialModelEventHandler.java b/fabric/src/lib/java/dev/engine_room/flywheel/lib/model/baked/PartialModelEventHandler.java deleted file mode 100644 index 62fb40ac3..000000000 --- a/fabric/src/lib/java/dev/engine_room/flywheel/lib/model/baked/PartialModelEventHandler.java +++ /dev/null @@ -1,56 +0,0 @@ -package dev.engine_room.flywheel.lib.model.baked; - -import java.util.List; - -import org.jetbrains.annotations.ApiStatus; - -import dev.engine_room.flywheel.lib.util.ResourceUtil; -import net.fabricmc.fabric.api.resource.ResourceReloadListenerKeys; -import net.fabricmc.fabric.api.resource.SimpleSynchronousResourceReloadListener; -import net.minecraft.client.Minecraft; -import net.minecraft.client.resources.model.ModelManager; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.server.packs.resources.ResourceManager; - -@ApiStatus.Internal -public final class PartialModelEventHandler { - private PartialModelEventHandler() { - } - - public static ResourceLocation[] onRegisterAdditional() { - return PartialModel.ALL.keySet().toArray(ResourceLocation[]::new); - } - - public static void onBakingCompleted(ModelManager manager) { - PartialModel.populateOnInit = true; - - for (PartialModel partial : PartialModel.ALL.values()) { - partial.bakedModel = manager.getModel(partial.modelLocation()); - } - } - - public static final class ReloadListener implements SimpleSynchronousResourceReloadListener { - public static final ReloadListener INSTANCE = new ReloadListener(); - - public static final ResourceLocation ID = ResourceUtil.rl("partial_models"); - public static final List DEPENDENCIES = List.of(ResourceReloadListenerKeys.MODELS); - - private ReloadListener() { - } - - @Override - public void onResourceManagerReload(ResourceManager resourceManager) { - onBakingCompleted(Minecraft.getInstance().getModelManager()); - } - - @Override - public ResourceLocation getFabricId() { - return ID; - } - - @Override - public List getFabricDependencies() { - return DEPENDENCIES; - } - } -} diff --git a/fabric/src/main/java/dev/engine_room/flywheel/impl/FabricFlwConfig.java b/fabric/src/main/java/dev/engine_room/flywheel/impl/FabricFlwConfig.java index 0e566a409..8f5769366 100644 --- a/fabric/src/main/java/dev/engine_room/flywheel/impl/FabricFlwConfig.java +++ b/fabric/src/main/java/dev/engine_room/flywheel/impl/FabricFlwConfig.java @@ -18,8 +18,8 @@ import dev.engine_room.flywheel.backend.FlwBackend; import dev.engine_room.flywheel.backend.compile.LightSmoothness; import net.fabricmc.loader.api.FabricLoader; -import net.minecraft.ResourceLocationException; -import net.minecraft.resources.ResourceLocation; +import net.minecraft.IdentifierException; +import net.minecraft.resources.Identifier; import net.minecraft.util.Mth; public class FabricFlwConfig implements FlwConfig { @@ -122,11 +122,11 @@ private void readBackend(JsonObject object) { } try { - this.backend = Backend.REGISTRY.getOrThrow(ResourceLocation.parse(value)); + this.backend = Backend.REGISTRY.getOrThrow(Identifier.parse(value)); useDefaultBackend = false; return; - } catch (ResourceLocationException e) { - msg = "'backend' value '" + value + "' is not a valid resource location"; + } catch (IdentifierException e) { + msg = "'backend' value '" + value + "' is not a valid resource id"; } catch (IllegalArgumentException e) { msg = "Backend with ID '" + value + "' is not registered"; } catch (Exception e) { diff --git a/fabric/src/main/java/dev/engine_room/flywheel/impl/FlwCommands.java b/fabric/src/main/java/dev/engine_room/flywheel/impl/FlwCommands.java index 7a0cee7b4..4c8587f51 100644 --- a/fabric/src/main/java/dev/engine_room/flywheel/impl/FlwCommands.java +++ b/fabric/src/main/java/dev/engine_room/flywheel/impl/FlwCommands.java @@ -13,10 +13,13 @@ import dev.engine_room.flywheel.backend.compile.PipelineCompiler; import dev.engine_room.flywheel.backend.engine.uniform.DebugMode; import dev.engine_room.flywheel.backend.engine.uniform.FrameUniforms; -import net.fabricmc.fabric.api.client.command.v2.ClientCommandManager; +import net.fabricmc.fabric.api.client.command.v2.ClientCommands; import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; import net.minecraft.client.Minecraft; +import net.minecraft.client.player.LocalPlayer; import net.minecraft.commands.CommandBuildContext; +import net.minecraft.commands.CommandSource; +import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.arguments.coordinates.BlockPosArgument; import net.minecraft.commands.arguments.coordinates.Coordinates; import net.minecraft.core.BlockPos; @@ -28,9 +31,9 @@ private FlwCommands() { } public static void registerClientCommands(CommandDispatcher dispatcher, CommandBuildContext buildContext) { - LiteralArgumentBuilder command = ClientCommandManager.literal("flywheel"); + LiteralArgumentBuilder command = ClientCommands.literal("flywheel"); - command.then(ClientCommandManager.literal("backend") + command.then(ClientCommands.literal("backend") .executes(context -> { Backend backend = BackendManager.currentBackend(); String idStr = Backend.REGISTRY.getIdOrThrow(backend) @@ -38,7 +41,7 @@ public static void registerClientCommands(CommandDispatcher { FabricFlwConfig.INSTANCE.backend = BackendManager.offBackend(); FabricFlwConfig.INSTANCE.useDefaultBackend = true; @@ -53,7 +56,7 @@ public static void registerClientCommands(CommandDispatcher { Backend requestedBackend = context.getArgument("id", Backend.class); FabricFlwConfig.INSTANCE.backend = requestedBackend; @@ -76,7 +79,7 @@ public static void registerClientCommands(CommandDispatcher { if (FabricFlwConfig.INSTANCE.limitUpdates) { context.getSource().sendFeedback(Component.translatable("command.flywheel.limit_updates.get.on")); @@ -85,7 +88,7 @@ public static void registerClientCommands(CommandDispatcher { FabricFlwConfig.INSTANCE.limitUpdates = true; FabricFlwConfig.INSTANCE.save(); @@ -93,7 +96,7 @@ public static void registerClientCommands(CommandDispatcher { FabricFlwConfig.INSTANCE.limitUpdates = false; FabricFlwConfig.INSTANCE.save(); @@ -102,8 +105,8 @@ public static void registerClientCommands(CommandDispatcher { var oldValue = FabricFlwConfig.INSTANCE.backendConfig.lightSmoothness; var newValue = context.getArgument("mode", LightSmoothness.class); @@ -122,11 +125,11 @@ public static void registerClientCommands(CommandDispatcher createDebugCommand() { - var debug = ClientCommandManager.literal("debug"); + var debug = ClientCommands.literal("debug"); - debug.then(ClientCommandManager.literal("crumbling") - .then(ClientCommandManager.argument("pos", BlockPosArgument.blockPos()) - .then(ClientCommandManager.argument("stage", IntegerArgumentType.integer(0, 9)) + debug.then(ClientCommands.literal("crumbling") + .then(ClientCommands.argument("pos", BlockPosArgument.blockPos()) + .then(ClientCommands.argument("stage", IntegerArgumentType.integer(0, 9)) .executes(context -> { Entity executor = context.getSource() .getEntity(); @@ -144,51 +147,51 @@ private static LiteralArgumentBuilder createDebugComm return Command.SINGLE_SUCCESS; })))); - debug.then(ClientCommandManager.literal("shader") - .then(ClientCommandManager.argument("mode", DebugModeArgument.INSTANCE) + debug.then(ClientCommands.literal("shader") + .then(ClientCommands.argument("mode", DebugModeArgument.INSTANCE) .executes(context -> { DebugMode mode = context.getArgument("mode", DebugMode.class); FrameUniforms.debugMode(mode); return Command.SINGLE_SUCCESS; }))); - debug.then(ClientCommandManager.literal("frustum") - .then(ClientCommandManager.literal("capture") + debug.then(ClientCommands.literal("frustum") + .then(ClientCommands.literal("capture") .executes(context -> { FrameUniforms.captureFrustum(); return Command.SINGLE_SUCCESS; })) - .then(ClientCommandManager.literal("unpause") + .then(ClientCommands.literal("unpause") .executes(context -> { FrameUniforms.unpauseFrustum(); return Command.SINGLE_SUCCESS; }))); - debug.then(ClientCommandManager.literal("lightSections") - .then(ClientCommandManager.literal("on") + debug.then(ClientCommands.literal("lightSections") + .then(ClientCommands.literal("on") .executes(context -> { BackendDebugFlags.LIGHT_STORAGE_VIEW = true; return Command.SINGLE_SUCCESS; })) - .then(ClientCommandManager.literal("off") + .then(ClientCommands.literal("off") .executes(context -> { BackendDebugFlags.LIGHT_STORAGE_VIEW = false; return Command.SINGLE_SUCCESS; }))); - debug.then(ClientCommandManager.literal("pauseUpdates") - .then(ClientCommandManager.literal("on") + debug.then(ClientCommands.literal("pauseUpdates") + .then(ClientCommands.literal("on") .executes(context -> { ImplDebugFlags.PAUSE_UPDATES = true; return Command.SINGLE_SUCCESS; })) - .then(ClientCommandManager.literal("off") + .then(ClientCommands.literal("off") .executes(context -> { ImplDebugFlags.PAUSE_UPDATES = false; return Command.SINGLE_SUCCESS; }))); - debug.then(ClientCommandManager.literal("info") + debug.then(ClientCommands.literal("info") .executes(context -> { context.getSource() .sendFeedback(FlwDebugInfo.getDebugCommandInfo()); @@ -200,6 +203,9 @@ private static LiteralArgumentBuilder createDebugComm // Client version of BlockPosArgument.getBlockPos private static BlockPos getBlockPos(CommandContext context, String name) { - return context.getArgument(name, Coordinates.class).getBlockPos(context.getSource().getPlayer().createCommandSourceStack()); + FabricClientCommandSource clientSource = context.getSource(); + LocalPlayer player = clientSource.getPlayer(); + CommandSourceStack commandSourceStack = new CommandSourceStack(CommandSource.NULL, clientSource.getPosition(), clientSource.getRotation(), null, clientSource.permissions(), player.getPlainTextName(), player.getDisplayName(), null, player); + return context.getArgument(name, Coordinates.class).getBlockPos(commandSourceStack); } } diff --git a/fabric/src/main/java/dev/engine_room/flywheel/impl/FlwLibXplatImpl.java b/fabric/src/main/java/dev/engine_room/flywheel/impl/FlwLibXplatImpl.java index 733d53425..0c977a490 100644 --- a/fabric/src/main/java/dev/engine_room/flywheel/impl/FlwLibXplatImpl.java +++ b/fabric/src/main/java/dev/engine_room/flywheel/impl/FlwLibXplatImpl.java @@ -1,30 +1,27 @@ package dev.engine_room.flywheel.impl; -import org.jetbrains.annotations.UnknownNullability; - import dev.engine_room.flywheel.lib.internal.FlwLibXplat; import dev.engine_room.flywheel.lib.model.SimpleModel; -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.FabricPartialModel; +import dev.engine_room.flywheel.lib.model.baked.LevelModelBuilder; import dev.engine_room.flywheel.lib.model.baked.ModelBuilderImpl; -import net.minecraft.client.resources.model.BakedModel; -import net.minecraft.client.resources.model.ModelManager; -import net.minecraft.resources.ResourceLocation; +import dev.engine_room.flywheel.lib.model.baked.PartialModel; +import net.minecraft.resources.Identifier; public class FlwLibXplatImpl implements FlwLibXplat { @Override - @UnknownNullability - public BakedModel getBakedModel(ModelManager modelManager, ResourceLocation location) { - return modelManager.getModel(location); + public PartialModel createPartialModel(Identifier modelId) { + return FabricPartialModel.of(modelId); } @Override - public SimpleModel buildBakedModelBuilder(BakedModelBuilder builder) { - return ModelBuilderImpl.buildBakedModelBuilder(builder); + public SimpleModel buildBlockModelBuilder(BlockModelBuilder builder) { + return ModelBuilderImpl.buildBlockModelBuilder(builder); } @Override - public SimpleModel buildBlockModelBuilder(BlockModelBuilder builder) { - return ModelBuilderImpl.buildBlockModelBuilder(builder); + public SimpleModel buildLevelModelBuilder(LevelModelBuilder builder) { + return ModelBuilderImpl.buildLevelModelBuilder(builder); } } diff --git a/fabric/src/main/java/dev/engine_room/flywheel/impl/FlywheelFabric.java b/fabric/src/main/java/dev/engine_room/flywheel/impl/FlywheelFabric.java index 3a4ce1c91..e4f0ad394 100644 --- a/fabric/src/main/java/dev/engine_room/flywheel/impl/FlywheelFabric.java +++ b/fabric/src/main/java/dev/engine_room/flywheel/impl/FlywheelFabric.java @@ -8,19 +8,24 @@ import dev.engine_room.flywheel.backend.compile.FlwProgramsReloader; import dev.engine_room.flywheel.backend.engine.uniform.Uniforms; import dev.engine_room.flywheel.impl.mixin.fabric.ArgumentTypeInfosAccessor; +import dev.engine_room.flywheel.impl.task.FlwTaskExecutor; import dev.engine_room.flywheel.impl.visualization.VisualizationEventHandler; -import dev.engine_room.flywheel.lib.model.baked.PartialModelEventHandler; +import dev.engine_room.flywheel.lib.model.baked.FabricPartialModel; +import dev.engine_room.flywheel.lib.util.IdentifierUtil; import dev.engine_room.flywheel.lib.util.RendererReloadCache; import dev.engine_room.flywheel.lib.util.ResourceReloadHolder; import net.fabricmc.api.ClientModInitializer; import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback; import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientEntityEvents; +import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents; import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; import net.fabricmc.fabric.api.client.model.loading.v1.ModelLoadingPlugin; -import net.fabricmc.fabric.api.resource.ResourceManagerHelper; +import net.fabricmc.fabric.api.resource.v1.ResourceLoader; +import net.fabricmc.fabric.api.resource.v1.reloader.ResourceReloaderKeys; import net.fabricmc.loader.api.FabricLoader; import net.fabricmc.loader.api.ModContainer; import net.fabricmc.loader.api.Version; +import net.minecraft.client.gui.components.debug.DebugScreenEntries; import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.server.packs.PackType; @@ -41,6 +46,8 @@ public void onInitializeClient() { } private static void setupImpl() { + ClientLifecycleEvents.CLIENT_STOPPING.register(_ -> FlwTaskExecutor.get().shutdown()); + ReloadLevelRendererCallback.EVENT.register(BackendManagerImpl::onReloadLevelRenderer); // This Fabric event runs slightly later than the Forge event Flywheel uses, but it shouldn't make a difference. @@ -57,6 +64,8 @@ private static void setupImpl() { ClientCommandRegistrationCallback.EVENT.register(FlwCommands::registerClientCommands); + DebugScreenEntries.register(FlwDebugInfo.FlwDebugEntry.ID, new FlwDebugInfo.FlwDebugEntry()); + EndClientResourceReloadCallback.EVENT.register((minecraft, resourceManager, initialReload, error) -> BackendManagerImpl.onEndClientResourceReload(error.isPresent())); @@ -72,16 +81,15 @@ private static void setupLib() { ReloadLevelRendererCallback.EVENT.register(level -> RendererReloadCache.onReloadLevelRenderer()); EndClientResourceReloadCallback.EVENT.register((minecraft, resourceManager, initialReload, error) -> ResourceReloadHolder.onEndClientResourceReload()); - ModelLoadingPlugin.register(ctx -> { - ctx.addModels(PartialModelEventHandler.onRegisterAdditional()); - }); - ResourceManagerHelper.get(PackType.CLIENT_RESOURCES).registerReloadListener(PartialModelEventHandler.ReloadListener.INSTANCE); + ModelLoadingPlugin.register(FabricPartialModel::registerAll); + ResourceLoader.get(PackType.CLIENT_RESOURCES).registerReloadListener(FabricPartialModel.ResourceReloadListener.ID, FabricPartialModel.ResourceReloadListener.INSTANCE); + ResourceLoader.get(PackType.CLIENT_RESOURCES).addListenerOrdering(ResourceReloaderKeys.Client.MODELS, FabricPartialModel.ResourceReloadListener.ID); } private static void setupBackend() { ReloadLevelRendererCallback.EVENT.register(level -> Uniforms.onReloadLevelRenderer()); - ResourceManagerHelper.get(PackType.CLIENT_RESOURCES).registerReloadListener(FlwProgramsReloader.INSTANCE); + ResourceLoader.get(PackType.CLIENT_RESOURCES).registerReloadListener(FlwProgramsReloader.ID, FlwProgramsReloader.INSTANCE); } public static Version version() { diff --git a/fabric/src/main/java/dev/engine_room/flywheel/impl/mixin/MinecraftMixin.java b/fabric/src/main/java/dev/engine_room/flywheel/impl/mixin/MinecraftMixin.java index dcab8eeec..ebef5304e 100644 --- a/fabric/src/main/java/dev/engine_room/flywheel/impl/mixin/MinecraftMixin.java +++ b/fabric/src/main/java/dev/engine_room/flywheel/impl/mixin/MinecraftMixin.java @@ -31,13 +31,13 @@ abstract class MinecraftMixin { FabricFlwConfig.INSTANCE.load(); } - @Inject(method = "method_53522", at = @At("HEAD")) + @Inject(method = "lambda$new$4", at = @At("HEAD")) private void flywheel$onEndInitialResourceReload(@Coerce Object gameLoadCookie, Optional error, CallbackInfo ci) { EndClientResourceReloadCallback.EVENT.invoker() .onEndClientResourceReload((Minecraft) (Object) this, resourceManager, true, error); } - @Inject(method = "method_24228", at = @At("HEAD")) + @Inject(method = "lambda$reloadResourcePacks$0", at = @At("HEAD")) private void flywheel$onEndManualResourceReload(boolean recovery, @Coerce Object gameLoadCookie, CompletableFuture future, Optional error, CallbackInfo ci) { EndClientResourceReloadCallback.EVENT.invoker() diff --git a/fabric/src/main/java/dev/engine_room/flywheel/impl/mixin/fabric/DebugScreenOverlayMixin.java b/fabric/src/main/java/dev/engine_room/flywheel/impl/mixin/fabric/DebugScreenOverlayMixin.java deleted file mode 100644 index c8201cfce..000000000 --- a/fabric/src/main/java/dev/engine_room/flywheel/impl/mixin/fabric/DebugScreenOverlayMixin.java +++ /dev/null @@ -1,26 +0,0 @@ -package dev.engine_room.flywheel.impl.mixin.fabric; - -import java.util.List; - -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -import dev.engine_room.flywheel.impl.FlwDebugInfo; -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.components.DebugScreenOverlay; - -@Mixin(DebugScreenOverlay.class) -abstract class DebugScreenOverlayMixin { - @Shadow - @Final - private Minecraft minecraft; - - @Inject(method = "getSystemInformation", at = @At("RETURN")) - private void flywheel$onGetSystemInformation(CallbackInfoReturnable> cir) { - FlwDebugInfo.addDebugInfo(minecraft, cir.getReturnValue()); - } -} diff --git a/fabric/src/main/java/dev/engine_room/flywheel/impl/mixin/fabric/MinecraftMixin.java b/fabric/src/main/java/dev/engine_room/flywheel/impl/mixin/fabric/MinecraftMixin.java index f87736ad1..9a4ecf2ad 100644 --- a/fabric/src/main/java/dev/engine_room/flywheel/impl/mixin/fabric/MinecraftMixin.java +++ b/fabric/src/main/java/dev/engine_room/flywheel/impl/mixin/fabric/MinecraftMixin.java @@ -15,17 +15,24 @@ abstract class MinecraftMixin { @Shadow public ClientLevel level; - @Inject(method = "setLevel(Lnet/minecraft/client/multiplayer/ClientLevel;Lnet/minecraft/client/gui/screens/ReceivingLevelScreen$Reason;)V", at = @At("HEAD")) + @Inject(method = "setLevel(Lnet/minecraft/client/multiplayer/ClientLevel;)V", at = @At("HEAD")) private void flywheel$onSetLevel(CallbackInfo ci) { if (level != null) { LevelAttached.invalidateLevel(level); } } - @Inject(method = "disconnect(Lnet/minecraft/client/gui/screens/Screen;)V", at = @At("HEAD")) + @Inject(method = "disconnect(Lnet/minecraft/client/gui/screens/Screen;ZZ)V", at = @At("HEAD")) private void flywheel$onDisconnect(CallbackInfo ci) { if (level != null) { LevelAttached.invalidateLevel(level); } } + + @Inject(method = "clearClientLevel", at = @At("HEAD")) + private void flywheel$onClearClientLevel(CallbackInfo ci) { + if (level != null) { + LevelAttached.invalidateLevel(level); + } + } } diff --git a/fabric/src/main/resources/fabric.mod.json b/fabric/src/main/resources/fabric.mod.json index 82729821e..b2c074806 100644 --- a/fabric/src/main/resources/fabric.mod.json +++ b/fabric/src/main/resources/fabric.mod.json @@ -33,5 +33,6 @@ }, "breaks": { "sodium": "<0.6.0-beta.2" - } + }, + "accessWidener": "flywheel.accesswidener" } diff --git a/fabric/src/main/resources/flywheel.accesswidener b/fabric/src/main/resources/flywheel.accesswidener new file mode 100644 index 000000000..4e3281a69 --- /dev/null +++ b/fabric/src/main/resources/flywheel.accesswidener @@ -0,0 +1,2 @@ +accessWidener v2 official +accessible class com/mojang/blaze3d/opengl/GlDevice diff --git a/fabric/src/main/resources/flywheel.impl.fabric.mixins.json b/fabric/src/main/resources/flywheel.impl.fabric.mixins.json index de280fb0c..d3e0ee36a 100644 --- a/fabric/src/main/resources/flywheel.impl.fabric.mixins.json +++ b/fabric/src/main/resources/flywheel.impl.fabric.mixins.json @@ -2,11 +2,9 @@ "required": true, "minVersion": "0.8", "package": "dev.engine_room.flywheel.impl.mixin.fabric", - "compatibilityLevel": "JAVA_21", - "refmap": "flywheel.refmap.json", + "compatibilityLevel": "JAVA_25", "client": [ "ArgumentTypeInfosAccessor", - "DebugScreenOverlayMixin", "MinecraftMixin", "SystemReportMixin" ], diff --git a/gradle.properties b/gradle.properties index 02295768e..956783476 100644 --- a/gradle.properties +++ b/gradle.properties @@ -20,31 +20,15 @@ flywheel_maven_version_range=[1.0.0,2.0) flywheel_semver_version_range=>=1.0.0 <2.0.0 # Mod dependency declarations -minecraft_semver_version_range = >=1.21.1 <1.21.2 -minecraft_maven_version_range = [1.21.1,1.21.2) -fabric_api_version_range = >=0.105.0 -neoforge_version_range = [21.1.66,) +minecraft_semver_version_range = >=26.1 <26.2 +minecraft_maven_version_range = [26.1,26.2) +fabric_api_version_range = >=0.144.4 +neoforge_version_range = [26.1.0.17-beta,) # General build dependency versions -java_version = 21 -arch_loom_version = 1.7.412 -cursegradle_version = 1.4.0 -parchment_minecraft_version = 1.21 -parchment_version = 2024.07.07 - -# Minecraft build dependency versions -minecraft_version = 1.21.1 -neoforge_version = 21.1.66 -fabric_loader_version = 0.16.5 -fabric_api_version = 0.105.0+1.21.1 - -# Build dependency mod versions -sodium_version = mc1.21.1-0.6.5 -iris_version = 1.8.0-beta.8+1.21.1 -# There is no oculus for 1.21.1 so we will only support iris -embeddium_version = 1.0.11+mc1.21.1 +java_version = 25 # Publication info flywheel_group=dev.engine-room.flywheel vanillin_group=dev.engine-room.vanillin -artifact_minecraft_version = 1.21.1 +artifact_minecraft_version = 26.1 diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml new file mode 100644 index 000000000..12f8af74e --- /dev/null +++ b/gradle/libs.versions.toml @@ -0,0 +1,42 @@ +[versions] +minecraft = "26.1.2" + +# https://neoforged.net/ +neoforge = "26.1.2.41-beta" +mdg = "2.0.+" + +# https://fabricmc.net/develop/ +loom = "1.16.+" +fabric-loader = "0.19.2" +fabric-api = "0.148.0+26.1.2" + +# we need to manually depend on mixin (+extras) in common +mixin = "0.16.5+mixin.0.8.7" +mixin-extras = "0.5.3" + +# https://maven.caffeinemc.net/#/releases/net/caffeinemc/sodium-fabric +sodium = "0.8.10+mc26.1.2" +# https://modrinth.com/mod/iris/versions +iris = "1.10.9+26.1" + +[libraries] +minecraft = { module = "com.mojang:minecraft", version.ref = "minecraft" } +fabric-loader = { module = "net.fabricmc:fabric-loader", version.ref = "fabric-loader" } +fabric-api = { module = "net.fabricmc.fabric-api:fabric-api", version.ref = "fabric-api" } +mixin = { module = "net.fabricmc:sponge-mixin", version.ref = "mixin" } +mixin-extras = { module = "io.github.llamalad7:mixinextras-common", version.ref = "mixin-extras" } + +mdg = { module = "net.neoforged:moddev-gradle", version.ref = "mdg" } +fabric-loom = { module = "net.fabricmc:fabric-loom", version.ref = "loom" } + +sodium-fabric = { module = "net.caffeinemc:sodium-fabric", version.ref = "sodium" } +sodium-fabric-api = { module = "net.caffeinemc:sodium-fabric-api", version.ref = "sodium" } +sodium-neoforge = { module = "net.caffeinemc:sodium-neoforge", version.ref = "sodium" } +sodium-neoforge-api = { module = "net.caffeinemc:sodium-neoforge-api", version.ref = "sodium" } + +[bundles] +mixin = [ "mixin", "mixin-extras" ] + +[plugins] +mdg = { id = "net.neoforged.moddev" } +loom = { id = "net.fabricmc.fabric-loom" } diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index a4b76b953..9bbc975c7 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index df97d72b8..dbc3ce4a0 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.4.0-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew index f5feea6d6..faf93008b 100755 --- a/gradlew +++ b/gradlew @@ -86,8 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s -' "$PWD" ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -206,7 +205,7 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. diff --git a/neoforge/build.gradle.kts b/neoforge/build.gradle.kts index 164c1c053..8565ecd7b 100644 --- a/neoforge/build.gradle.kts +++ b/neoforge/build.gradle.kts @@ -2,7 +2,7 @@ plugins { idea java `maven-publish` - id("dev.architectury.loom") + alias(libs.plugins.mdg) id("flywheel.subproject") id("flywheel.platform") } @@ -61,8 +61,8 @@ transitiveSourceSets { } platform { - setupLoomMod(api, lib, backend, main) - setupLoomRuns() + setupMdgMod(api, lib, backend, main) + setupMdgRuns() setupTestMod(testMod) } @@ -98,12 +98,6 @@ jarSets { publishWithRawSources { artifactId = "flywheel-neoforge-api-${property("artifact_minecraft_version")}" } - - configureJar { - manifest { - attributes("Fabric-Loom-Remap" to "true") - } - } } } @@ -111,32 +105,29 @@ defaultPackageInfos { sources(api, lib, backend, main) } -loom { - mixin { - useLegacyMixinAp = true - add(main, "flywheel.refmap.json") - add(backend, "backend-flywheel.refmap.json") - } +neoForge { + version = libs.versions.neoforge.get() runs { configureEach { - property("forge.logging.markers", "") - property("forge.logging.console.level", "debug") + systemProperty("forge.logging.markers", "") + systemProperty("forge.logging.console.level", "debug") } } -} -repositories { - maven("https://maven.neoforged.net/releases/") + mods { + create("flywheel") { + sourceSet(api) + sourceSet(lib) + sourceSet(backend) + sourceSet(main) + } + } } dependencies { - neoForge("net.neoforged:neoforge:${property("neoforge_version")}") - - modCompileOnly("maven.modrinth:sodium:${property("sodium_version")}-neoforge") - modCompileOnly("maven.modrinth:iris:${property("iris_version")}-neoforge") - - modCompileOnly("maven.modrinth:embeddium:${property("embeddium_version")}") + compileOnly(libs.sodium.neoforge.api) + compileOnly("maven.modrinth:iris:${libs.versions.iris.get()}-neoforge") "forApi"(project(path = common, configuration = "apiClasses")) "forLib"(project(path = common, configuration = "libClasses")) diff --git a/neoforge/gradle.properties b/neoforge/gradle.properties deleted file mode 100644 index 2e6ed7676..000000000 --- a/neoforge/gradle.properties +++ /dev/null @@ -1 +0,0 @@ -loom.platform = neoforge diff --git a/neoforge/src/lib/java/dev/engine_room/flywheel/lib/model/baked/BakedModelBufferer.java b/neoforge/src/lib/java/dev/engine_room/flywheel/lib/model/baked/BakedModelBufferer.java deleted file mode 100644 index 131c17f1f..000000000 --- a/neoforge/src/lib/java/dev/engine_room/flywheel/lib/model/baked/BakedModelBufferer.java +++ /dev/null @@ -1,154 +0,0 @@ -package dev.engine_room.flywheel.lib.model.baked; - -import java.util.Iterator; - -import org.jetbrains.annotations.Nullable; - -import com.mojang.blaze3d.vertex.BufferBuilder; -import com.mojang.blaze3d.vertex.PoseStack; - -import dev.engine_room.flywheel.lib.model.SimpleModel; -import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.ItemBlockRenderTypes; -import net.minecraft.client.renderer.RenderType; -import net.minecraft.client.renderer.block.BlockRenderDispatcher; -import net.minecraft.client.renderer.block.ModelBlockRenderer; -import net.minecraft.client.renderer.texture.OverlayTexture; -import net.minecraft.client.resources.model.BakedModel; -import net.minecraft.core.BlockPos; -import net.minecraft.util.RandomSource; -import net.minecraft.world.level.BlockAndTintGetter; -import net.minecraft.world.level.block.RenderShape; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.material.FluidState; -import net.neoforged.neoforge.client.ChunkRenderTypeSet; -import net.neoforged.neoforge.client.model.data.ModelData; -import net.neoforged.neoforge.common.util.TriState; - -final class BakedModelBufferer { - private static final ThreadLocal THREAD_LOCAL_OBJECTS = ThreadLocal.withInitial(ThreadLocalObjects::new); - - private BakedModelBufferer() { - } - - public static SimpleModel bufferModel(BakedModel model, BlockPos pos, BlockAndTintGetter level, BlockState state, @Nullable PoseStack poseStack, BlockMaterialFunction blockMaterialFunction) { - ThreadLocalObjects objects = THREAD_LOCAL_OBJECTS.get(); - if (poseStack == null) { - poseStack = objects.identityPoseStack; - } - RandomSource random = objects.random; - MeshEmitterManager emitters = objects.emitters; - - emitters.prepare(blockMaterialFunction); - - ModelBlockRenderer blockRenderer = Minecraft.getInstance() - .getBlockRenderer() - .getModelRenderer(); - - long seed = state.getSeed(pos); - ModelData modelData = model.getModelData(level, pos, state, level.getModelData(pos)); - random.setSeed(seed); - ChunkRenderTypeSet renderTypes = model.getRenderTypes(state, random, modelData); - - // See ModelBlockRenderer#tesselateBlock - boolean defaultAo = state.getLightEmission(level, pos) == 0; - boolean aoEnabled = Minecraft.useAmbientOcclusion(); - - for (RenderType renderType : renderTypes) { - TriState useAo = model.useAmbientOcclusion(state, modelData, renderType); - - boolean defaultAoLayer = aoEnabled && (useAo.isTrue() || (useAo.isDefault() && defaultAo)); - - NeoforgeMeshEmitter emitter = emitters.getEmitter(renderType); - emitter.prepareForModelLayer(defaultAoLayer); - - poseStack.pushPose(); - blockRenderer.tesselateBlock(level, model, state, pos, poseStack, emitter, false, random, seed, OverlayTexture.NO_OVERLAY, modelData, renderType); - poseStack.popPose(); - } - - return emitters.end(); - } - - public static SimpleModel bufferBlocks(Iterator posIterator, BlockAndTintGetter level, @Nullable PoseStack poseStack, boolean renderFluids, BlockMaterialFunction blockMaterialFunction) { - ThreadLocalObjects objects = THREAD_LOCAL_OBJECTS.get(); - if (poseStack == null) { - poseStack = objects.identityPoseStack; - } - RandomSource random = objects.random; - MeshEmitterManager emitters = objects.emitters; - TransformingVertexConsumer transformingWrapper = objects.transformingWrapper; - - emitters.prepare(blockMaterialFunction); - - BlockRenderDispatcher renderDispatcher = Minecraft.getInstance() - .getBlockRenderer(); - ModelBlockRenderer blockRenderer = renderDispatcher.getModelRenderer(); - ModelBlockRenderer.enableCaching(); - - boolean aoEnabled = Minecraft.useAmbientOcclusion(); - - while (posIterator.hasNext()) { - BlockPos pos = posIterator.next(); - BlockState state = level.getBlockState(pos); - - emitters.prepareForBlock(); - - if (renderFluids) { - FluidState fluidState = state.getFluidState(); - - if (!fluidState.isEmpty()) { - RenderType renderType = ItemBlockRenderTypes.getRenderLayer(fluidState); - - BufferBuilder bufferBuilder = emitters.getBuffer(renderType, true, false); - - if (bufferBuilder != null) { - transformingWrapper.prepare(bufferBuilder, poseStack); - - poseStack.pushPose(); - poseStack.translate(pos.getX() - (pos.getX() & 0xF), pos.getY() - (pos.getY() & 0xF), pos.getZ() - (pos.getZ() & 0xF)); - renderDispatcher.renderLiquid(pos, level, transformingWrapper, state, fluidState); - poseStack.popPose(); - } - } - } - - if (state.getRenderShape() == RenderShape.MODEL) { - long seed = state.getSeed(pos); - BakedModel model = renderDispatcher.getBlockModel(state); - ModelData modelData = model.getModelData(level, pos, state, level.getModelData(pos)); - random.setSeed(seed); - ChunkRenderTypeSet renderTypes = model.getRenderTypes(state, random, modelData); - - // See ModelBlockRenderer#tesselateBlock - boolean defaultAo = state.getLightEmission(level, pos) == 0; - - for (RenderType renderType : renderTypes) { - TriState useAo = model.useAmbientOcclusion(state, modelData, renderType); - - boolean defaultAoLayer = aoEnabled && (useAo.isTrue() || (useAo.isDefault() && defaultAo)); - - NeoforgeMeshEmitter emitter = emitters.getEmitter(renderType); - emitter.prepareForModelLayer(defaultAoLayer); - - poseStack.pushPose(); - poseStack.translate(pos.getX(), pos.getY(), pos.getZ()); - blockRenderer.tesselateBlock(level, model, state, pos, poseStack, emitter, true, random, seed, OverlayTexture.NO_OVERLAY, modelData, renderType); - poseStack.popPose(); - } - } - } - - ModelBlockRenderer.clearCache(); - transformingWrapper.clear(); - return emitters.end(); - } - - private static class ThreadLocalObjects { - public final PoseStack identityPoseStack = new PoseStack(); - public final RandomSource random = RandomSource.createNewThreadLocalInstance(); - - public final MeshEmitterManager emitters = new MeshEmitterManager<>(NeoforgeMeshEmitter::new); - public final TransformingVertexConsumer transformingWrapper = new TransformingVertexConsumer(); - } -} diff --git a/neoforge/src/lib/java/dev/engine_room/flywheel/lib/model/baked/BlockStateModelBufferer.java b/neoforge/src/lib/java/dev/engine_room/flywheel/lib/model/baked/BlockStateModelBufferer.java new file mode 100644 index 000000000..bbce84765 --- /dev/null +++ b/neoforge/src/lib/java/dev/engine_room/flywheel/lib/model/baked/BlockStateModelBufferer.java @@ -0,0 +1,178 @@ +package dev.engine_room.flywheel.lib.model.baked; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.jetbrains.annotations.ApiStatus.Internal; +import org.jspecify.annotations.Nullable; + +import com.mojang.blaze3d.vertex.BufferBuilder; +import com.mojang.blaze3d.vertex.PoseStack; + +import dev.engine_room.flywheel.lib.model.SimpleModel; +import net.minecraft.client.Minecraft; +import net.minecraft.client.color.block.BlockColors; +import net.minecraft.client.renderer.block.BlockAndTintGetter; +import net.minecraft.client.renderer.block.BlockModelLighter; +import net.minecraft.client.renderer.block.FluidRenderer; +import net.minecraft.client.renderer.block.ModelBlockRenderer; +import net.minecraft.client.renderer.block.dispatch.BlockStateModel; +import net.minecraft.client.renderer.block.dispatch.BlockStateModelPart; +import net.minecraft.client.renderer.chunk.ChunkSectionLayer; +import net.minecraft.client.renderer.state.GameRenderState; +import net.minecraft.client.resources.model.ModelManager; +import net.minecraft.core.BlockPos; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.block.RenderShape; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.material.FluidState; +import net.neoforged.neoforge.client.config.NeoForgeClientConfig; + +@Internal +public final class BlockStateModelBufferer { + private static final ThreadLocal THREAD_LOCAL_OBJECTS = ThreadLocal.withInitial(ThreadLocalObjects::new); + + public static final ScopedValue EMITTER_MANAGER = ScopedValue.newInstance(); + + private BlockStateModelBufferer() { + } + + public static SimpleModel bufferModel(BlockStateModel model, BlockPos pos, BlockAndTintGetter level, BlockState state, @Nullable PoseStack poseStack, BlockMaterialFunction blockMaterialFunction) { + ThreadLocalObjects objects = THREAD_LOCAL_OBJECTS.get(); + if (poseStack == null) { + poseStack = objects.identityPoseStack; + } + List parts = objects.parts; + RandomSource random = objects.random; + NeoForgeMeshEmitterManager emitters = objects.emitters; + + emitters.prepare(blockMaterialFunction); + + long seed = state.getSeed(pos); + random.setSeed(seed); + model.collectParts(level, pos, state, random, parts); + + Minecraft minecraft = Minecraft.getInstance(); + GameRenderState gameRenderState = minecraft.gameRenderer.getGameRenderState(); + BlockColors blockColors = minecraft.getBlockColors(); + + // See ModelBlockRenderer#tesselateBlock + boolean useAo = gameRenderState.optionsRenderState.ambientOcclusion; + boolean perPartAo = NeoForgeClientConfig.INSTANCE.handleAmbientOcclusionPerPart.getAsBoolean(); + boolean ao = useAo && (perPartAo || parts.isEmpty() || switch(parts.getFirst().ambientOcclusion()) { + case TRUE -> true; + case DEFAULT -> state.getLightEmission(level, pos) == 0; + case FALSE -> false; + }); + emitters.prepareForModel(ao); + + ModelBlockRenderer blockRenderer = new ModelBlockRenderer(useAo, true, blockColors); + + PoseStack finalPoseStack = poseStack; + ScopedValue.where(EMITTER_MANAGER, emitters).run(() -> + blockRenderer.tesselateBlock((_, _, _, quad, instance) -> { + finalPoseStack.pushPose(); + ChunkSectionLayer layer = quad.materialInfo().layer(); + emitters.getEmitter(layer).putBakedQuad(finalPoseStack.last(), quad, instance); + finalPoseStack.popPose(); + }, 0, 0, 0, level, pos, state, model, seed) + ); + + return emitters.end(); + } + + public static SimpleModel bufferBlocks(Iterator posIterator, BlockAndTintGetter level, @Nullable PoseStack poseStack, boolean renderFluids, BlockMaterialFunction blockMaterialFunction) { + ThreadLocalObjects objects = THREAD_LOCAL_OBJECTS.get(); + if (poseStack == null) { + poseStack = objects.identityPoseStack; + } + List parts = objects.parts; + RandomSource random = objects.random; + NeoForgeMeshEmitterManager emitters = objects.emitters; + TransformingVertexConsumer transformingWrapper = objects.transformingWrapper; + + emitters.prepare(blockMaterialFunction); + + BlockModelLighter.enableCaching(); + + Minecraft minecraft = Minecraft.getInstance(); + ModelManager modelManager = minecraft.getModelManager(); + GameRenderState gameRenderState = minecraft.gameRenderer.getGameRenderState(); + boolean useAo = gameRenderState.optionsRenderState.ambientOcclusion; + BlockColors blockColors = minecraft.getBlockColors(); + + ModelBlockRenderer blockRenderer = new ModelBlockRenderer(useAo, true, blockColors); + FluidRenderer fluidRenderer = new FluidRenderer(modelManager.getFluidStateModelSet()); + + boolean perPartAo = NeoForgeClientConfig.INSTANCE.handleAmbientOcclusionPerPart.getAsBoolean(); + + while (posIterator.hasNext()) { + BlockPos pos = posIterator.next(); + BlockState state = level.getBlockState(pos); + + emitters.prepareForBlock(); + + if (renderFluids) { + FluidState fluidState = state.getFluidState(); + + if (!fluidState.isEmpty()) { + poseStack.pushPose(); + poseStack.translate(pos.getX() - (pos.getX() & 0xF), pos.getY() - (pos.getY() & 0xF), pos.getZ() - (pos.getZ() & 0xF)); + PoseStack finalPoseStack = poseStack; + fluidRenderer.tesselate(level, pos, layer -> { + BufferBuilder bufferBuilder = emitters.getEmitter(layer).getBuffer(true, false); + + if (bufferBuilder != null) { + transformingWrapper.prepare(bufferBuilder, finalPoseStack); + return transformingWrapper; + } + + return EmptyVertexConsumer.INSTANCE; + }, state, fluidState); + poseStack.popPose(); + } + } + + if (state.getRenderShape() == RenderShape.MODEL) { + long seed = state.getSeed(pos); + random.setSeed(seed); + + BlockStateModel model = modelManager.getBlockStateModelSet().get(state); + model.collectParts(level, pos, state, random, parts); + + // See ModelBlockRenderer#tesselateBlock + boolean ao = useAo && (perPartAo || parts.isEmpty() || switch(parts.getFirst().ambientOcclusion()) { + case TRUE -> true; + case DEFAULT -> state.getLightEmission(level, pos) == 0; + case FALSE -> false; + }); + emitters.prepareForModel(ao); + + PoseStack finalPoseStack = poseStack; + ScopedValue.where(EMITTER_MANAGER, emitters).run(() -> + blockRenderer.tesselateBlock((x, y, z, quad, instance) -> { + finalPoseStack.pushPose(); + finalPoseStack.translate(x, y, z); + ChunkSectionLayer layer = quad.materialInfo().layer(); + emitters.getEmitter(layer).putBakedQuad(finalPoseStack.last(), quad, instance); + finalPoseStack.popPose(); + }, pos.getX(), pos.getY(), pos.getZ(), level, pos, state, model, seed) + ); + } + } + + BlockModelLighter.clearCache(); + transformingWrapper.clear(); + return emitters.end(); + } + + private static class ThreadLocalObjects { + public final PoseStack identityPoseStack = new PoseStack(); + public final List parts = new ArrayList<>(); + public final RandomSource random = RandomSource.createThreadLocalInstance(); + + public final NeoForgeMeshEmitterManager emitters = new NeoForgeMeshEmitterManager(); + public final TransformingVertexConsumer transformingWrapper = new TransformingVertexConsumer(); + } +} diff --git a/neoforge/src/lib/java/dev/engine_room/flywheel/lib/model/baked/ModelBuilderImpl.java b/neoforge/src/lib/java/dev/engine_room/flywheel/lib/model/baked/ModelBuilderImpl.java index 4a0bcc4dd..741aa54c3 100644 --- a/neoforge/src/lib/java/dev/engine_room/flywheel/lib/model/baked/ModelBuilderImpl.java +++ b/neoforge/src/lib/java/dev/engine_room/flywheel/lib/model/baked/ModelBuilderImpl.java @@ -11,13 +11,13 @@ public final class ModelBuilderImpl { private ModelBuilderImpl() { } - public static SimpleModel buildBakedModelBuilder(BakedModelBuilder builder) { + public static SimpleModel buildBlockModelBuilder(BlockModelBuilder builder) { BlockState blockState = builder.level.getBlockState(builder.pos); - return BakedModelBufferer.bufferModel(builder.bakedModel, builder.pos, builder.level, blockState, builder.poseStack, builder.materialFunc); + return BlockStateModelBufferer.bufferModel(builder.blockModel, builder.pos, builder.level, blockState, builder.poseStack, builder.materialFunc); } - public static SimpleModel buildBlockModelBuilder(BlockModelBuilder builder) { - return BakedModelBufferer.bufferBlocks(builder.positions.iterator(), builder.level, builder.poseStack, builder.renderFluids, builder.materialFunc); + public static SimpleModel buildLevelModelBuilder(LevelModelBuilder builder) { + return BlockStateModelBufferer.bufferBlocks(builder.positions.iterator(), builder.level, builder.poseStack, builder.renderFluids, builder.materialFunc); } } diff --git a/neoforge/src/lib/java/dev/engine_room/flywheel/lib/model/baked/NeoForgeMeshEmitter.java b/neoforge/src/lib/java/dev/engine_room/flywheel/lib/model/baked/NeoForgeMeshEmitter.java new file mode 100644 index 000000000..b9683edd5 --- /dev/null +++ b/neoforge/src/lib/java/dev/engine_room/flywheel/lib/model/baked/NeoForgeMeshEmitter.java @@ -0,0 +1,95 @@ +package dev.engine_room.flywheel.lib.model.baked; + +import org.jetbrains.annotations.ApiStatus; +import org.jspecify.annotations.Nullable; + +import com.mojang.blaze3d.vertex.BufferBuilder; +import com.mojang.blaze3d.vertex.PoseStack.Pose; +import com.mojang.blaze3d.vertex.QuadInstance; +import com.mojang.blaze3d.vertex.VertexConsumer; + +import net.minecraft.client.renderer.chunk.ChunkSectionLayer; +import net.minecraft.client.resources.model.geometry.BakedQuad; +import net.neoforged.neoforge.client.model.quad.MutableQuad; + +@ApiStatus.Internal +public class NeoForgeMeshEmitter extends MeshEmitter { + private boolean ao; + + NeoForgeMeshEmitter(ByteBufferBuilderStack byteBufferBuilderStack, ChunkSectionLayer chunkSectionLayer) { + super(byteBufferBuilderStack, chunkSectionLayer); + } + + // Called from ModelBlockRendererMixin if AO is on for the model before each part is buffered + public void prepareForPart(boolean ao) { + this.ao = ao; + } + + @Nullable + private BufferBuilder getBuffer(BakedQuad quad) { + boolean shade = quad.materialInfo().shade(); + boolean ao = quad.materialInfo().ambientOcclusion() && this.ao; + return getBuffer(shade, ao); + } + + @Override + public void putBakedQuad(Pose pose, BakedQuad quad, QuadInstance instance) { + BufferBuilder bufferBuilder = getBuffer(quad); + if (bufferBuilder != null) { + bufferBuilder.putBakedQuad(pose, quad, instance); + } + } + + @Override + public void putBlockBakedQuad(float x, float y, float z, BakedQuad quad, QuadInstance instance) { + BufferBuilder bufferBuilder = getBuffer(quad); + if (bufferBuilder != null) { + bufferBuilder.putBlockBakedQuad(x, y, z, quad, instance); + } + } + + @Override + public void putMutableQuad(Pose pose, MutableQuad quad, QuadInstance instance) { + throw new UnsupportedOperationException("NeoForgeMeshEmitter only supports putBakedQuad/putBlockBakedQuad!"); + } + + @Override + public VertexConsumer addVertex(float x, float y, float z) { + throw new UnsupportedOperationException("NeoForgeMeshEmitter only supports putBakedQuad/putBlockBakedQuad!"); + } + + @Override + public VertexConsumer setColor(int red, int green, int blue, int alpha) { + throw new UnsupportedOperationException("NeoForgeMeshEmitter only supports putBakedQuad/putBlockBakedQuad!"); + } + + @Override + public VertexConsumer setColor(int color) { + throw new UnsupportedOperationException("NeoForgeMeshEmitter only supports putBakedQuad/putBlockBakedQuad!"); + } + + @Override + public VertexConsumer setUv(float u, float v) { + throw new UnsupportedOperationException("NeoForgeMeshEmitter only supports putBakedQuad/putBlockBakedQuad!"); + } + + @Override + public VertexConsumer setUv1(int u, int v) { + throw new UnsupportedOperationException("NeoForgeMeshEmitter only supports putBakedQuad/putBlockBakedQuad!"); + } + + @Override + public VertexConsumer setUv2(int u, int v) { + throw new UnsupportedOperationException("NeoForgeMeshEmitter only supports putBakedQuad/putBlockBakedQuad!"); + } + + @Override + public VertexConsumer setNormal(float normalX, float normalY, float normalZ) { + throw new UnsupportedOperationException("NeoForgeMeshEmitter only supports putBakedQuad/putBlockBakedQuad!"); + } + + @Override + public VertexConsumer setLineWidth(float width) { + throw new UnsupportedOperationException("NeoForgeMeshEmitter only supports putBakedQuad/putBlockBakedQuad!"); + } +} diff --git a/neoforge/src/lib/java/dev/engine_room/flywheel/lib/model/baked/NeoForgeMeshEmitterManager.java b/neoforge/src/lib/java/dev/engine_room/flywheel/lib/model/baked/NeoForgeMeshEmitterManager.java new file mode 100644 index 000000000..3b9f07001 --- /dev/null +++ b/neoforge/src/lib/java/dev/engine_room/flywheel/lib/model/baked/NeoForgeMeshEmitterManager.java @@ -0,0 +1,27 @@ +package dev.engine_room.flywheel.lib.model.baked; + +import java.util.function.Function; + +import org.jetbrains.annotations.ApiStatus.Internal; + +import com.mojang.blaze3d.vertex.VertexConsumer; + +import net.minecraft.client.renderer.chunk.ChunkSectionLayer; + +@Internal +public class NeoForgeMeshEmitterManager extends MeshEmitterManager implements Function { + NeoForgeMeshEmitterManager() { + super(NeoForgeMeshEmitter::new); + } + + public void prepareForModel(boolean ao) { + for (NeoForgeMeshEmitter meshEmitter : emitterMap.values()) { + meshEmitter.prepareForPart(ao); + } + } + + @Override + public VertexConsumer apply(ChunkSectionLayer chunkSectionLayer) { + return getEmitter(chunkSectionLayer); + } +} diff --git a/neoforge/src/lib/java/dev/engine_room/flywheel/lib/model/baked/NeoForgePartialModel.java b/neoforge/src/lib/java/dev/engine_room/flywheel/lib/model/baked/NeoForgePartialModel.java new file mode 100644 index 000000000..6e512b27f --- /dev/null +++ b/neoforge/src/lib/java/dev/engine_room/flywheel/lib/model/baked/NeoForgePartialModel.java @@ -0,0 +1,63 @@ +package dev.engine_room.flywheel.lib.model.baked; + +import java.util.concurrent.ConcurrentMap; + +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; + +import com.google.common.collect.MapMaker; + +import net.minecraft.client.renderer.block.dispatch.BlockModelRotation; +import net.minecraft.client.renderer.block.dispatch.BlockStateModel; +import net.minecraft.client.renderer.block.dispatch.SingleVariant; +import net.minecraft.client.resources.model.ModelBaker; +import net.minecraft.client.resources.model.ModelDebugName; +import net.minecraft.client.resources.model.ModelManager; +import net.minecraft.client.resources.model.ResolvableModel; +import net.minecraft.client.resources.model.SimpleModelWrapper; +import net.minecraft.resources.Identifier; +import net.neoforged.neoforge.client.event.ModelEvent; +import net.neoforged.neoforge.client.model.standalone.StandaloneModelKey; +import net.neoforged.neoforge.client.model.standalone.UnbakedStandaloneModel; + +@ApiStatus.Internal +public class NeoForgePartialModel extends PartialModel { + private static final ConcurrentMap ALL = new MapMaker().weakValues().makeMap(); + + private final StandaloneModelKey<@NotNull BlockStateModel> key; + + public NeoForgePartialModel(Identifier modelId) { + super(modelId); + key = new StandaloneModelKey<>(modelId::toString); + } + + public static NeoForgePartialModel of(Identifier modelId) { + return ALL.computeIfAbsent(modelId, NeoForgePartialModel::new); + } + + public static void registerAll(ModelEvent.RegisterStandalone event) { + for (NeoForgePartialModel partial : ALL.values()) { + event.register(partial.key, partial.new Unbaked()); + } + } + + public static void refreshAll(ModelEvent.BakingCompleted event) { + ModelManager modelManager = event.getModelManager(); + + for (NeoForgePartialModel partial : ALL.values()) { + partial.blockStateModel = modelManager.getStandaloneModel(partial.key); + } + } + + private class Unbaked implements UnbakedStandaloneModel<@NotNull BlockStateModel> { + @Override + public @NotNull BlockStateModel bake(ModelBaker baker, ModelDebugName name) { + return new SingleVariant(SimpleModelWrapper.bake(baker, modelId, BlockModelRotation.IDENTITY)); + } + + @Override + public void resolveDependencies(ResolvableModel.Resolver resolver) { + resolver.markDependency(modelId); + } + } +} diff --git a/neoforge/src/lib/java/dev/engine_room/flywheel/lib/model/baked/NeoForgeSinglePosVirtualBlockGetter.java b/neoforge/src/lib/java/dev/engine_room/flywheel/lib/model/baked/NeoForgeSinglePosVirtualBlockGetter.java index 41291b65e..5eb2d475e 100644 --- a/neoforge/src/lib/java/dev/engine_room/flywheel/lib/model/baked/NeoForgeSinglePosVirtualBlockGetter.java +++ b/neoforge/src/lib/java/dev/engine_room/flywheel/lib/model/baked/NeoForgeSinglePosVirtualBlockGetter.java @@ -2,12 +2,12 @@ import java.util.function.ToIntFunction; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import net.minecraft.core.BlockPos; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; -import net.neoforged.neoforge.client.model.data.ModelData; +import net.neoforged.neoforge.model.data.ModelData; public class NeoForgeSinglePosVirtualBlockGetter extends SinglePosVirtualBlockGetter { @Nullable diff --git a/neoforge/src/lib/java/dev/engine_room/flywheel/lib/model/baked/NeoforgeMeshEmitter.java b/neoforge/src/lib/java/dev/engine_room/flywheel/lib/model/baked/NeoforgeMeshEmitter.java deleted file mode 100644 index ded11be75..000000000 --- a/neoforge/src/lib/java/dev/engine_room/flywheel/lib/model/baked/NeoforgeMeshEmitter.java +++ /dev/null @@ -1,99 +0,0 @@ -package dev.engine_room.flywheel.lib.model.baked; - -import org.jetbrains.annotations.ApiStatus; -import org.jetbrains.annotations.Nullable; - -import com.mojang.blaze3d.vertex.BufferBuilder; -import com.mojang.blaze3d.vertex.PoseStack; -import com.mojang.blaze3d.vertex.VertexConsumer; - -import dev.engine_room.flywheel.api.material.Material; -import net.minecraft.client.renderer.RenderType; -import net.minecraft.client.renderer.block.ModelBlockRenderer; -import net.minecraft.client.renderer.block.model.BakedQuad; - -@ApiStatus.Internal -public class NeoforgeMeshEmitter extends MeshEmitter implements VertexConsumer { - private final RenderType renderType; - - private boolean defaultAo; - - NeoforgeMeshEmitter(ByteBufferBuilderStack byteBufferBuilderStack, RenderType renderType) { - super(byteBufferBuilderStack, renderType); - this.renderType = renderType; - } - - /** - * Some mods, like FramedBlocks, have custom hooks to determine the default AO. This method is invoked a second time - * from within a mixin to {@link ModelBlockRenderer} after the accurate value is computed, so we don't need to - * support those custom hooks manually. It is possible that the mixin injector will never run (primarily due to - * implementations of Fabric Renderer API on Forge, like Indigo in Forgified Fabric API), so we always compute the - * value manually beforehand too. - */ - public void prepareForModelLayer(boolean defaultAo) { - this.defaultAo = defaultAo; - } - - @Nullable - private BufferBuilder getBuffer(boolean shade, boolean ao) { - Material key = blockMaterialFunction.apply(renderType, shade, ao); - if (key != null) { - return getBuffer(key); - } else { - return null; - } - } - - @Nullable - private BufferBuilder getBuffer(BakedQuad quad) { - boolean shade = quad.isShade(); - boolean ao = quad.hasAmbientOcclusion() && defaultAo; - return getBuffer(shade, ao); - } - - @Override - public void putBulkData(PoseStack.Pose pose, BakedQuad quad, float red, float green, float blue, float alpha, int packedLight, int packedOverlay) { - BufferBuilder bufferBuilder = getBuffer(quad); - if (bufferBuilder != null) { - bufferBuilder.putBulkData(pose, quad, red, green, blue, alpha, packedLight, packedOverlay); - } - } - - @Override - public void putBulkData(PoseStack.Pose pose, BakedQuad quad, float[] brightness, float red, float green, float blue, float alpha, int[] lightmap, int packedOverlay, boolean readAlpha) { - BufferBuilder bufferBuilder = getBuffer(quad); - if (bufferBuilder != null) { - bufferBuilder.putBulkData(pose, quad, brightness, red, green, blue, alpha, lightmap, packedOverlay, readAlpha); - } - } - - @Override - public VertexConsumer addVertex(float x, float y, float z) { - throw new UnsupportedOperationException("ForgeMeshEmitter only supports putBulkData!"); - } - - @Override - public VertexConsumer setColor(int red, int green, int blue, int alpha) { - throw new UnsupportedOperationException("ForgeMeshEmitter only supports putBulkData!"); - } - - @Override - public VertexConsumer setUv(float u, float v) { - throw new UnsupportedOperationException("ForgeMeshEmitter only supports putBulkData!"); - } - - @Override - public VertexConsumer setUv1(int u, int v) { - throw new UnsupportedOperationException("ForgeMeshEmitter only supports putBulkData!"); - } - - @Override - public VertexConsumer setUv2(int u, int v) { - throw new UnsupportedOperationException("ForgeMeshEmitter only supports putBulkData!"); - } - - @Override - public VertexConsumer setNormal(float normalX, float normalY, float normalZ) { - throw new UnsupportedOperationException("ForgeMeshEmitter only supports putBulkData!"); - } -} diff --git a/neoforge/src/lib/java/dev/engine_room/flywheel/lib/model/baked/PartialModelEventHandler.java b/neoforge/src/lib/java/dev/engine_room/flywheel/lib/model/baked/PartialModelEventHandler.java deleted file mode 100644 index d87eee208..000000000 --- a/neoforge/src/lib/java/dev/engine_room/flywheel/lib/model/baked/PartialModelEventHandler.java +++ /dev/null @@ -1,31 +0,0 @@ -package dev.engine_room.flywheel.lib.model.baked; - -import java.util.Map; - -import org.jetbrains.annotations.ApiStatus; - -import net.minecraft.client.resources.model.BakedModel; -import net.minecraft.client.resources.model.ModelResourceLocation; -import net.minecraft.resources.ResourceLocation; -import net.neoforged.neoforge.client.event.ModelEvent; - -@ApiStatus.Internal -public final class PartialModelEventHandler { - private PartialModelEventHandler() { - } - - public static void onRegisterAdditional(ModelEvent.RegisterAdditional event) { - for (ResourceLocation modelLocation : PartialModel.ALL.keySet()) { - event.register(ModelResourceLocation.standalone(modelLocation)); - } - } - - public static void onBakingCompleted(ModelEvent.BakingCompleted event) { - PartialModel.populateOnInit = true; - Map models = event.getModels(); - - for (PartialModel partial : PartialModel.ALL.values()) { - partial.bakedModel = models.get(ModelResourceLocation.standalone(partial.modelLocation())); - } - } -} diff --git a/neoforge/src/main/java/dev/engine_room/flywheel/impl/FlwImplXplatImpl.java b/neoforge/src/main/java/dev/engine_room/flywheel/impl/FlwImplXplatImpl.java index f754fc992..e4fbda838 100644 --- a/neoforge/src/main/java/dev/engine_room/flywheel/impl/FlwImplXplatImpl.java +++ b/neoforge/src/main/java/dev/engine_room/flywheel/impl/FlwImplXplatImpl.java @@ -2,13 +2,13 @@ import dev.engine_room.flywheel.api.event.ReloadLevelRendererEvent; import net.minecraft.client.multiplayer.ClientLevel; -import net.neoforged.fml.loading.LoadingModList; +import net.neoforged.fml.loading.FMLLoader; import net.neoforged.neoforge.common.NeoForge; public class FlwImplXplatImpl implements FlwImplXplat { @Override public boolean isModLoaded(String modId) { - return LoadingModList.get().getModFileById(modId) != null; + return FMLLoader.getCurrent().getLoadingModList().getModFileById(modId) != null; } @Override diff --git a/neoforge/src/main/java/dev/engine_room/flywheel/impl/FlwLibXplatImpl.java b/neoforge/src/main/java/dev/engine_room/flywheel/impl/FlwLibXplatImpl.java index c5ccd80f6..45d1ab393 100644 --- a/neoforge/src/main/java/dev/engine_room/flywheel/impl/FlwLibXplatImpl.java +++ b/neoforge/src/main/java/dev/engine_room/flywheel/impl/FlwLibXplatImpl.java @@ -1,31 +1,27 @@ package dev.engine_room.flywheel.impl; -import org.jetbrains.annotations.UnknownNullability; - import dev.engine_room.flywheel.lib.internal.FlwLibXplat; import dev.engine_room.flywheel.lib.model.SimpleModel; -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.LevelModelBuilder; import dev.engine_room.flywheel.lib.model.baked.ModelBuilderImpl; -import net.minecraft.client.resources.model.BakedModel; -import net.minecraft.client.resources.model.ModelManager; -import net.minecraft.client.resources.model.ModelResourceLocation; -import net.minecraft.resources.ResourceLocation; +import dev.engine_room.flywheel.lib.model.baked.NeoForgePartialModel; +import dev.engine_room.flywheel.lib.model.baked.PartialModel; +import net.minecraft.resources.Identifier; public class FlwLibXplatImpl implements FlwLibXplat { @Override - @UnknownNullability - public BakedModel getBakedModel(ModelManager modelManager, ResourceLocation location) { - return modelManager.getModel(ModelResourceLocation.standalone(location)); + public PartialModel createPartialModel(Identifier modelId) { + return NeoForgePartialModel.of(modelId); } @Override - public SimpleModel buildBakedModelBuilder(BakedModelBuilder builder) { - return ModelBuilderImpl.buildBakedModelBuilder(builder); + public SimpleModel buildBlockModelBuilder(BlockModelBuilder builder) { + return ModelBuilderImpl.buildBlockModelBuilder(builder); } @Override - public SimpleModel buildBlockModelBuilder(BlockModelBuilder builder) { - return ModelBuilderImpl.buildBlockModelBuilder(builder); + public SimpleModel buildLevelModelBuilder(LevelModelBuilder builder) { + return ModelBuilderImpl.buildLevelModelBuilder(builder); } } diff --git a/neoforge/src/main/java/dev/engine_room/flywheel/impl/FlywheelNeoForge.java b/neoforge/src/main/java/dev/engine_room/flywheel/impl/FlywheelNeoForge.java index ea451b17e..71b714ef9 100644 --- a/neoforge/src/main/java/dev/engine_room/flywheel/impl/FlywheelNeoForge.java +++ b/neoforge/src/main/java/dev/engine_room/flywheel/impl/FlywheelNeoForge.java @@ -8,9 +8,10 @@ import dev.engine_room.flywheel.api.event.ReloadLevelRendererEvent; import dev.engine_room.flywheel.backend.compile.FlwProgramsReloader; import dev.engine_room.flywheel.backend.engine.uniform.Uniforms; -import dev.engine_room.flywheel.impl.compat.EmbeddiumCompat; +import dev.engine_room.flywheel.impl.task.FlwTaskExecutor; import dev.engine_room.flywheel.impl.visualization.VisualizationEventHandler; -import dev.engine_room.flywheel.lib.model.baked.PartialModelEventHandler; +import dev.engine_room.flywheel.lib.model.baked.NeoForgePartialModel; +import dev.engine_room.flywheel.lib.util.IdentifierUtil; import dev.engine_room.flywheel.lib.util.LevelAttached; import dev.engine_room.flywheel.lib.util.RendererReloadCache; import dev.engine_room.flywheel.lib.util.ResourceReloadHolder; @@ -22,8 +23,9 @@ import net.neoforged.fml.ModContainer; import net.neoforged.fml.common.Mod; import net.neoforged.fml.event.lifecycle.FMLCommonSetupEvent; -import net.neoforged.neoforge.client.event.CustomizeGuiOverlayEvent; -import net.neoforged.neoforge.client.event.RegisterClientReloadListenersEvent; +import net.neoforged.neoforge.client.event.AddClientReloadListenersEvent; +import net.neoforged.neoforge.client.event.RegisterDebugEntriesEvent; +import net.neoforged.neoforge.client.event.lifecycle.ClientStoppingEvent; import net.neoforged.neoforge.common.NeoForge; import net.neoforged.neoforge.event.entity.EntityJoinLevelEvent; import net.neoforged.neoforge.event.entity.EntityLeaveLevelEvent; @@ -50,11 +52,11 @@ public FlywheelNeoForge(IEventBus modEventBus, ModContainer modContainer) { CrashReportCallables.registerCrashCallable("Flywheel Backend", BackendManagerImpl::getBackendString); FlwImpl.init(); - - EmbeddiumCompat.init(); } private static void registerImplEventListeners(IEventBus gameEventBus, IEventBus modEventBus) { + gameEventBus.addListener((ClientStoppingEvent e) -> FlwTaskExecutor.get().shutdown()); + gameEventBus.addListener((ReloadLevelRendererEvent e) -> BackendManagerImpl.onReloadLevelRenderer(e.level())); gameEventBus.addListener((LevelTickEvent.Post e) -> { @@ -68,15 +70,7 @@ private static void registerImplEventListeners(IEventBus gameEventBus, IEventBus gameEventBus.addListener(FlwCommands::registerClientCommands); - gameEventBus.addListener((CustomizeGuiOverlayEvent.DebugText e) -> { - Minecraft minecraft = Minecraft.getInstance(); - - if (!minecraft.getDebugOverlay().showDebugScreen()) { - return; - } - - FlwDebugInfo.addDebugInfo(minecraft, e.getRight()); - }); + modEventBus.addListener((RegisterDebugEntriesEvent e) -> e.register(FlwDebugInfo.FlwDebugEntry.ID, new FlwDebugInfo.FlwDebugEntry())); modEventBus.addListener((EndClientResourceReloadEvent e) -> BackendManagerImpl.onEndClientResourceReload(e.error().isPresent())); @@ -95,15 +89,15 @@ private static void registerLibEventListeners(IEventBus gameEventBus, IEventBus modEventBus.addListener((EndClientResourceReloadEvent e) -> RendererReloadCache.onReloadLevelRenderer()); modEventBus.addListener((EndClientResourceReloadEvent e) -> ResourceReloadHolder.onEndClientResourceReload()); - modEventBus.addListener(PartialModelEventHandler::onRegisterAdditional); - modEventBus.addListener(PartialModelEventHandler::onBakingCompleted); + modEventBus.addListener(NeoForgePartialModel::registerAll); + modEventBus.addListener(NeoForgePartialModel::refreshAll); } private static void registerBackendEventListeners(IEventBus gameEventBus, IEventBus modEventBus) { gameEventBus.addListener((ReloadLevelRendererEvent e) -> Uniforms.onReloadLevelRenderer()); - modEventBus.addListener((RegisterClientReloadListenersEvent e) -> { - e.registerReloadListener(FlwProgramsReloader.INSTANCE); + modEventBus.addListener((AddClientReloadListenersEvent e) -> { + e.addListener(FlwProgramsReloader.ID, FlwProgramsReloader.INSTANCE); }); } diff --git a/neoforge/src/main/java/dev/engine_room/flywheel/impl/NeoForgeFlwConfig.java b/neoforge/src/main/java/dev/engine_room/flywheel/impl/NeoForgeFlwConfig.java index d1445bc19..09d6e0b47 100644 --- a/neoforge/src/main/java/dev/engine_room/flywheel/impl/NeoForgeFlwConfig.java +++ b/neoforge/src/main/java/dev/engine_room/flywheel/impl/NeoForgeFlwConfig.java @@ -1,14 +1,14 @@ package dev.engine_room.flywheel.impl; import org.apache.commons.lang3.tuple.Pair; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import dev.engine_room.flywheel.api.backend.Backend; import dev.engine_room.flywheel.api.backend.BackendManager; import dev.engine_room.flywheel.backend.BackendConfig; import dev.engine_room.flywheel.backend.compile.LightSmoothness; -import net.minecraft.ResourceLocationException; -import net.minecraft.resources.ResourceLocation; +import net.minecraft.IdentifierException; +import net.minecraft.resources.Identifier; import net.neoforged.fml.ModContainer; import net.neoforged.fml.config.ModConfig; import net.neoforged.neoforge.common.ModConfigSpec; @@ -42,11 +42,11 @@ private static Backend parseBackend(String value) { return BackendManager.defaultBackend(); } - ResourceLocation backendId; + Identifier backendId; try { - backendId = ResourceLocation.parse(value); - } catch (ResourceLocationException e) { - FlwImpl.CONFIG_LOGGER.warn("'backend' value '{}' is not a valid resource location", value); + backendId = Identifier.parse(value); + } catch (IdentifierException e) { + FlwImpl.CONFIG_LOGGER.warn("'backend' value '{}' is not a valid resource id", value); return null; } diff --git a/neoforge/src/main/java/dev/engine_room/flywheel/impl/compat/EmbeddiumCompat.java b/neoforge/src/main/java/dev/engine_room/flywheel/impl/compat/EmbeddiumCompat.java deleted file mode 100644 index cd1e5e138..000000000 --- a/neoforge/src/main/java/dev/engine_room/flywheel/impl/compat/EmbeddiumCompat.java +++ /dev/null @@ -1,33 +0,0 @@ -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); - }); - } - } -} diff --git a/neoforge/src/main/java/dev/engine_room/flywheel/impl/mixin/MinecraftMixin.java b/neoforge/src/main/java/dev/engine_room/flywheel/impl/mixin/MinecraftMixin.java index 50950fbab..2c6f42597 100644 --- a/neoforge/src/main/java/dev/engine_room/flywheel/impl/mixin/MinecraftMixin.java +++ b/neoforge/src/main/java/dev/engine_room/flywheel/impl/mixin/MinecraftMixin.java @@ -28,12 +28,12 @@ abstract class MinecraftMixin { FlwImpl.freezeRegistries(); } - @Inject(method = "lambda$new$8", at = @At("HEAD"), remap = false) + @Inject(method = "lambda$new$4", at = @At("HEAD")) private void flywheel$onEndInitialResourceReload(@Coerce Object gameLoadCookie, Optional error, CallbackInfo ci) { ModLoader.postEvent(new EndClientResourceReloadEvent((Minecraft) (Object) this, resourceManager, true, error)); } - @Inject(method = "lambda$reloadResourcePacks$21", at = @At("HEAD"), remap = false) + @Inject(method = "lambda$reloadResourcePacks$0", at = @At("HEAD")) private void flywheel$onEndManualResourceReload(boolean recovery, @Coerce Object gameLoadCookie, CompletableFuture completablefuture, Optional error, CallbackInfo ci) { ModLoader.postEvent(new EndClientResourceReloadEvent((Minecraft) (Object) this, resourceManager, false, error)); } diff --git a/neoforge/src/main/java/dev/engine_room/flywheel/impl/mixin/neoforge/ModelBlockRendererMixin.java b/neoforge/src/main/java/dev/engine_room/flywheel/impl/mixin/neoforge/ModelBlockRendererMixin.java index dd5783e8a..e9c123f4d 100644 --- a/neoforge/src/main/java/dev/engine_room/flywheel/impl/mixin/neoforge/ModelBlockRendererMixin.java +++ b/neoforge/src/main/java/dev/engine_room/flywheel/impl/mixin/neoforge/ModelBlockRendererMixin.java @@ -2,29 +2,34 @@ import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.asm.mixin.injection.callback.LocalCapture; -import com.mojang.blaze3d.vertex.PoseStack; -import com.mojang.blaze3d.vertex.VertexConsumer; +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; +import com.llamalad7.mixinextras.sugar.Local; -import dev.engine_room.flywheel.lib.model.baked.NeoforgeMeshEmitter; -import net.minecraft.client.renderer.RenderType; +import dev.engine_room.flywheel.lib.model.baked.BlockStateModelBufferer; +import dev.engine_room.flywheel.lib.model.baked.NeoForgeMeshEmitter; +import dev.engine_room.flywheel.lib.model.baked.NeoForgeMeshEmitterManager; +import net.minecraft.client.renderer.block.BlockAndTintGetter; +import net.minecraft.client.renderer.block.BlockQuadOutput; import net.minecraft.client.renderer.block.ModelBlockRenderer; -import net.minecraft.client.resources.model.BakedModel; +import net.minecraft.client.renderer.chunk.ChunkSectionLayer; +import net.minecraft.client.resources.model.geometry.BakedQuad; import net.minecraft.core.BlockPos; -import net.minecraft.util.RandomSource; -import net.minecraft.world.level.BlockAndTintGetter; import net.minecraft.world.level.block.state.BlockState; -import net.neoforged.neoforge.client.model.data.ModelData; @Mixin(ModelBlockRenderer.class) abstract class ModelBlockRendererMixin { - @Inject(method = "tesselateBlock(Lnet/minecraft/world/level/BlockAndTintGetter;Lnet/minecraft/client/resources/model/BakedModel;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/core/BlockPos;Lcom/mojang/blaze3d/vertex/PoseStack;Lcom/mojang/blaze3d/vertex/VertexConsumer;ZLnet/minecraft/util/RandomSource;JILnet/neoforged/neoforge/client/model/data/ModelData;Lnet/minecraft/client/renderer/RenderType;)V", at = @At(value = "INVOKE", target = "net/minecraft/world/level/block/state/BlockState.getOffset(Lnet/minecraft/world/level/BlockGetter;Lnet/minecraft/core/BlockPos;)Lnet/minecraft/world/phys/Vec3;"), locals = LocalCapture.CAPTURE_FAILSOFT, require = 0) - private void onTesselateBlock(BlockAndTintGetter level, BakedModel model, BlockState state, BlockPos pos, PoseStack poseStack, VertexConsumer consumer, boolean checkSides, RandomSource random, long seed, int packedOverlay, ModelData modelData, RenderType renderType, CallbackInfo ci, boolean ao) { - if (consumer instanceof NeoforgeMeshEmitter meshEmitter) { - meshEmitter.prepareForModelLayer(ao); + @WrapOperation(method = "tesselateAmbientOcclusion", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/block/ModelBlockRenderer;putQuadWithTint(Lnet/minecraft/client/renderer/block/BlockQuadOutput;FFFLnet/minecraft/client/renderer/block/BlockAndTintGetter;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/core/BlockPos;Lnet/minecraft/client/resources/model/geometry/BakedQuad;)V")) + private void onTesselateWithAO(ModelBlockRenderer instance, BlockQuadOutput output, float x, float y, float z, BlockAndTintGetter level, BlockState state, BlockPos pos, BakedQuad quad, Operation original, @Local(name = "ao") boolean ao) { + ScopedValue value = BlockStateModelBufferer.EMITTER_MANAGER; + if (value.isBound()) { + ChunkSectionLayer layer = quad.materialInfo().layer(); + NeoForgeMeshEmitter meshEmitter = value.get().getEmitter(layer); + + meshEmitter.prepareForPart(ao); } + + original.call(instance, output, x, y, z, level, state, pos, quad); } } diff --git a/neoforge/src/main/resources/META-INF/accesstransformer.cfg b/neoforge/src/main/resources/META-INF/accesstransformer.cfg new file mode 100644 index 000000000..0ca9f7400 --- /dev/null +++ b/neoforge/src/main/resources/META-INF/accesstransformer.cfg @@ -0,0 +1 @@ +public com.mojang.blaze3d.opengl.GlDevice diff --git a/neoforge/src/main/resources/META-INF/neoforge.mods.toml b/neoforge/src/main/resources/META-INF/neoforge.mods.toml index 28a8cd00e..08df87d64 100644 --- a/neoforge/src/main/resources/META-INF/neoforge.mods.toml +++ b/neoforge/src/main/resources/META-INF/neoforge.mods.toml @@ -33,12 +33,6 @@ type = "required" versionRange = "${neoforge_version_range}" side = "CLIENT" -[[dependencies.${ flywheel_id }]] -modId = "embeddium" -type = "optional" -versionRange = "[0.3.25,)" -side = "CLIENT" - [[dependencies.${ flywheel_id }]] modId = "sodium" type = "optional" diff --git a/neoforge/src/main/resources/flywheel.impl.neoforge.mixins.json b/neoforge/src/main/resources/flywheel.impl.neoforge.mixins.json index a9dfae6cf..78ee994ce 100644 --- a/neoforge/src/main/resources/flywheel.impl.neoforge.mixins.json +++ b/neoforge/src/main/resources/flywheel.impl.neoforge.mixins.json @@ -2,8 +2,7 @@ "required": true, "minVersion": "0.8", "package" : "dev.engine_room.flywheel.impl.mixin.neoforge", - "compatibilityLevel": "JAVA_17", - "refmap": "flywheel.refmap.json", + "compatibilityLevel": "JAVA_25", "client": [ "ModelBlockRendererMixin" ], diff --git a/neoforge/src/testMod/java/dev/engine_room/flywheel/FlywheelTestModClient.java b/neoforge/src/testMod/java/dev/engine_room/flywheel/FlywheelTestModClient.java index 0ecd54a87..67219c3f0 100644 --- a/neoforge/src/testMod/java/dev/engine_room/flywheel/FlywheelTestModClient.java +++ b/neoforge/src/testMod/java/dev/engine_room/flywheel/FlywheelTestModClient.java @@ -16,7 +16,7 @@ public class FlywheelTestModClient { private static final Logger LOGGER = LoggerFactory.getLogger(NAME); public FlywheelTestModClient() { - LOGGER.info("Starting {} on Dist: {}", NAME, FMLLoader.getDist()); + LOGGER.info("Starting {} on Dist: {}", NAME, FMLLoader.getCurrent().getDist()); NeoForge.EVENT_BUS.addListener((ClientTickEvent.Post e) -> { LOGGER.info("Running mixin audit"); diff --git a/settings.gradle.kts b/settings.gradle.kts index 7e3b2f05f..45b5d2e80 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -5,16 +5,14 @@ pluginManagement { maven("https://maven.neoforged.net/releases/") { name = "NeoForged" } - maven("https://maven.architectury.dev/") { - name = "Architectury" + maven("https://maven.fabricmc.net") { + name = "FabricMC" } - maven("https://repo.spongepowered.org/repository/maven-public") - maven("https://maven.parchmentmc.org") } } plugins { - id("org.gradle.toolchains.foojay-resolver-convention") version("0.9.0") + id("org.gradle.toolchains.foojay-resolver-convention") version("1.0.0") } rootProject.name = "Flywheel" diff --git a/vanillinFabric/build.gradle.kts b/vanillinFabric/build.gradle.kts index 324865e0e..4cc585a4d 100644 --- a/vanillinFabric/build.gradle.kts +++ b/vanillinFabric/build.gradle.kts @@ -2,7 +2,7 @@ plugins { idea java `maven-publish` - id("dev.architectury.loom") + alias(libs.plugins.loom) id("flywheel.subproject") id("flywheel.platform") } @@ -26,7 +26,7 @@ transitiveSourceSets { } } -var vanillinVersion = "${property("vanillin_version")}+${property("minecraft_version")}" +var vanillinVersion = "${property("vanillin_version")}+${libs.versions.minecraft.get()}" if (subproject.buildNumber != null) { vanillinVersion += ".build.${subproject.buildNumber}" @@ -56,7 +56,7 @@ tasks.withType().configureEach { } jarSets { - mainSet.publishWithRemappedSources { + mainSet.publishWithRawSources { artifactId = "vanillin-fabric-${property("artifact_minecraft_version")}" } } @@ -65,25 +65,17 @@ defaultPackageInfos { sources(main) } -loom { - mixin { - useLegacyMixinAp = true - add(main, "vanillin.refmap.json") - } -} - dependencies { - modImplementation("net.fabricmc:fabric-loader:${property("fabric_loader_version")}") - modApi("net.fabricmc.fabric-api:fabric-api:${property("fabric_api_version")}") + minecraft(libs.minecraft) + implementation(libs.fabric.loader) + api(libs.fabric.api) - modCompileOnly("maven.modrinth:sodium:${property("sodium_version")}-fabric") + compileOnly(libs.sodium.fabric.api) compileOnly(project(path = common, configuration = "vanillinClasses")) compileOnly(project(path = common, configuration = "vanillinResources")) compileOnly(project(path = platform, configuration = "apiClasses")) - // JiJ flywheel proper - include(project(path = platform, configuration = "flywheelRemap")) - runtimeOnly(project(path = platform, configuration = "flywheelDev")) + include(runtimeOnly(project(path = platform, configuration = "flywheel"))!!) } diff --git a/vanillinFabric/gradle.properties b/vanillinFabric/gradle.properties deleted file mode 100644 index e846a8f57..000000000 --- a/vanillinFabric/gradle.properties +++ /dev/null @@ -1 +0,0 @@ -loom.platform=fabric diff --git a/vanillinFabric/src/main/java/dev/engine_room/vanillin/VanillinFabric.java b/vanillinFabric/src/main/java/dev/engine_room/vanillin/VanillinFabric.java index ca9ffca6d..339f04ced 100644 --- a/vanillinFabric/src/main/java/dev/engine_room/vanillin/VanillinFabric.java +++ b/vanillinFabric/src/main/java/dev/engine_room/vanillin/VanillinFabric.java @@ -3,7 +3,7 @@ import dev.engine_room.flywheel.api.event.ReloadLevelRendererCallback; import dev.engine_room.vanillin.item.SodiumAnimatedTextureCompat; import net.fabricmc.api.ClientModInitializer; -import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderEvents; +import net.fabricmc.fabric.api.client.rendering.v1.level.LevelRenderEvents; public class VanillinFabric implements ClientModInitializer { @Override @@ -14,6 +14,6 @@ public void onInitializeClient() { FabricVanillinConfig.INSTANCE.save(); ReloadLevelRendererCallback.EVENT.register(level -> SodiumAnimatedTextureCompat.onReloadRenderer()); - WorldRenderEvents.START.register(context -> SodiumAnimatedTextureCompat.beginFrame()); + LevelRenderEvents.START_MAIN.register(context -> SodiumAnimatedTextureCompat.beginFrame()); } } diff --git a/vanillinFabric/src/main/java/dev/engine_room/vanillin/VanillinXplatImpl.java b/vanillinFabric/src/main/java/dev/engine_room/vanillin/VanillinXplatImpl.java index df1cf7db7..c6608f247 100644 --- a/vanillinFabric/src/main/java/dev/engine_room/vanillin/VanillinXplatImpl.java +++ b/vanillinFabric/src/main/java/dev/engine_room/vanillin/VanillinXplatImpl.java @@ -1,14 +1,6 @@ package dev.engine_room.vanillin; -import org.jetbrains.annotations.Nullable; - -import dev.engine_room.vanillin.fabric.mixin.item.ItemColorsAccessor; -import dev.engine_room.vanillin.fabric.mixin.item.MinecraftAccessor; import net.fabricmc.loader.api.FabricLoader; -import net.minecraft.client.Minecraft; -import net.minecraft.client.color.item.ItemColor; -import net.minecraft.core.registries.BuiltInRegistries; -import net.minecraft.world.item.Item; public class VanillinXplatImpl implements VanillinXplat { @Override @@ -17,13 +9,6 @@ public boolean isDevelopmentEnvironment() { .isDevelopmentEnvironment(); } - @Override - @Nullable - public ItemColor itemColors(Item item) { - var itemColors = ((ItemColorsAccessor) ((MinecraftAccessor) Minecraft.getInstance()).vanillin$itemColors()).vanillin$itemColors(); - return itemColors.byId(BuiltInRegistries.ITEM.getId(item)); - } - @Override public boolean isModLoaded(String modId) { return FabricLoader.getInstance() diff --git a/vanillinFabric/src/main/java/dev/engine_room/vanillin/fabric/mixin/item/ItemColorsAccessor.java b/vanillinFabric/src/main/java/dev/engine_room/vanillin/fabric/mixin/item/ItemColorsAccessor.java deleted file mode 100644 index 78b2e5559..000000000 --- a/vanillinFabric/src/main/java/dev/engine_room/vanillin/fabric/mixin/item/ItemColorsAccessor.java +++ /dev/null @@ -1,14 +0,0 @@ -package dev.engine_room.vanillin.fabric.mixin.item; - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Accessor; - -import net.minecraft.client.color.item.ItemColor; -import net.minecraft.client.color.item.ItemColors; -import net.minecraft.core.IdMapper; - -@Mixin(ItemColors.class) -public interface ItemColorsAccessor { - @Accessor("itemColors") - IdMapper vanillin$itemColors(); -} diff --git a/vanillinFabric/src/main/java/dev/engine_room/vanillin/fabric/mixin/item/MinecraftAccessor.java b/vanillinFabric/src/main/java/dev/engine_room/vanillin/fabric/mixin/item/MinecraftAccessor.java deleted file mode 100644 index 3347ecb9e..000000000 --- a/vanillinFabric/src/main/java/dev/engine_room/vanillin/fabric/mixin/item/MinecraftAccessor.java +++ /dev/null @@ -1,13 +0,0 @@ -package dev.engine_room.vanillin.fabric.mixin.item; - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Accessor; - -import net.minecraft.client.Minecraft; -import net.minecraft.client.color.item.ItemColors; - -@Mixin(Minecraft.class) -public interface MinecraftAccessor { - @Accessor("itemColors") - ItemColors vanillin$itemColors(); -} diff --git a/vanillinFabric/src/main/resources/vanillin.fabric.mixins.json b/vanillinFabric/src/main/resources/vanillin.fabric.mixins.json index 88c9e26b6..2d485d46d 100644 --- a/vanillinFabric/src/main/resources/vanillin.fabric.mixins.json +++ b/vanillinFabric/src/main/resources/vanillin.fabric.mixins.json @@ -1,14 +1,11 @@ { - "required" : true, - "minVersion" : "0.8", - "package" : "dev.engine_room.vanillin.fabric.mixin", - "compatibilityLevel" : "JAVA_17", - "refmap" : "vanillin.refmap.json", - "client" : [ - "item.ItemColorsAccessor", - "item.MinecraftAccessor" + "required": true, + "minVersion": "0.8", + "package": "dev.engine_room.vanillin.fabric.mixin", + "compatibilityLevel": "JAVA_25", + "client": [ ], - "injectors" : { - "defaultRequire" : 1 + "injectors": { + "defaultRequire": 1 } } diff --git a/vanillinNeoForge/build.gradle.kts b/vanillinNeoForge/build.gradle.kts index 4ee406606..b966ca348 100644 --- a/vanillinNeoForge/build.gradle.kts +++ b/vanillinNeoForge/build.gradle.kts @@ -2,7 +2,7 @@ plugins { idea java `maven-publish` - id("dev.architectury.loom") + alias(libs.plugins.mdg) id("flywheel.subproject") id("flywheel.platform") } @@ -15,7 +15,7 @@ subproject.init("vanillin-neoforge", "vanillin_group", "vanillin_version") val main = sourceSets.getByName("main") platform { - setupLoomRuns() + setupMdgRuns() } transitiveSourceSets { @@ -59,31 +59,26 @@ defaultPackageInfos { sources(main) } -loom { - mixin { - useLegacyMixinAp = true - add(main, "vanillin.refmap.json") - } +neoForge { + version = libs.versions.neoforge.get() runs { configureEach { - property("forge.logging.markers", "") - property("forge.logging.console.level", "debug") + systemProperty("forge.logging.markers", "") + systemProperty("forge.logging.console.level", "debug") } } -} -repositories { - maven("https://maven.neoforged.net/releases/") + mods { + create("vanillin") { + sourceSet(main) + } + } } dependencies { - neoForge("net.neoforged:neoforge:${property("neoforge_version")}") - - modCompileOnly("maven.modrinth:sodium:${property("sodium_version")}-neoforge") - modCompileOnly("maven.modrinth:iris:${property("iris_version")}-neoforge") - - modCompileOnly("maven.modrinth:embeddium:${property("embeddium_version")}") + compileOnly(libs.sodium.neoforge.api) + compileOnly("maven.modrinth:iris:${libs.versions.iris.get()}-neoforge") compileOnly(project(path = common, configuration = "vanillinClasses")) compileOnly(project(path = common, configuration = "vanillinResources")) @@ -92,7 +87,5 @@ dependencies { compileOnly(annotationProcessor("io.github.llamalad7:mixinextras-common:0.4.1")!!) - // JiJ flywheel proper - include(project(path = platform, configuration = "flywheelRemap")) - runtimeOnly(project(path = platform, configuration = "flywheelDev")) + jarJar(runtimeOnly(project(path = platform, configuration = "flywheel"))!!) } diff --git a/vanillinNeoForge/gradle.properties b/vanillinNeoForge/gradle.properties deleted file mode 100644 index 2e6ed7676..000000000 --- a/vanillinNeoForge/gradle.properties +++ /dev/null @@ -1 +0,0 @@ -loom.platform = neoforge diff --git a/vanillinNeoForge/src/main/java/dev/engine_room/vanillin/VanillinXplatImpl.java b/vanillinNeoForge/src/main/java/dev/engine_room/vanillin/VanillinXplatImpl.java index 3ad095ebb..415bc64d6 100644 --- a/vanillinNeoForge/src/main/java/dev/engine_room/vanillin/VanillinXplatImpl.java +++ b/vanillinNeoForge/src/main/java/dev/engine_room/vanillin/VanillinXplatImpl.java @@ -1,28 +1,15 @@ package dev.engine_room.vanillin; -import dev.engine_room.vanillin.neoforge.mixin.item.ItemColorsAccessor; -import net.minecraft.client.Minecraft; -import net.minecraft.client.color.item.ItemColor; -import net.minecraft.world.item.Item; -import net.neoforged.fml.loading.FMLEnvironment; -import net.neoforged.fml.loading.LoadingModList; +import net.neoforged.fml.loading.FMLLoader; public class VanillinXplatImpl implements VanillinXplat { @Override public boolean isDevelopmentEnvironment() { - return !FMLEnvironment.production; - } - - @Override - public ItemColor itemColors(Item item) { - return ((ItemColorsAccessor) Minecraft.getInstance() - .getItemColors()).vanillin$itemColors() - .get(item); + return !FMLLoader.getCurrent().isProduction(); } @Override public boolean isModLoaded(String modId) { - return LoadingModList.get() - .getModFileById(modId) != null; + return FMLLoader.getCurrent().getLoadingModList().getModFileById(modId) != null; } } diff --git a/vanillinNeoForge/src/main/java/dev/engine_room/vanillin/neoforge/mixin/item/ItemColorsAccessor.java b/vanillinNeoForge/src/main/java/dev/engine_room/vanillin/neoforge/mixin/item/ItemColorsAccessor.java deleted file mode 100644 index 3f161386e..000000000 --- a/vanillinNeoForge/src/main/java/dev/engine_room/vanillin/neoforge/mixin/item/ItemColorsAccessor.java +++ /dev/null @@ -1,16 +0,0 @@ -package dev.engine_room.vanillin.neoforge.mixin.item; - -import java.util.Map; - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Accessor; - -import net.minecraft.client.color.item.ItemColor; -import net.minecraft.client.color.item.ItemColors; -import net.minecraft.world.item.Item; - -@Mixin(ItemColors.class) -public interface ItemColorsAccessor { - @Accessor("itemColors") - Map vanillin$itemColors(); -} diff --git a/vanillinNeoForge/src/main/resources/vanillin.neoforge.mixins.json b/vanillinNeoForge/src/main/resources/vanillin.neoforge.mixins.json index f4941242a..25cc5ec7b 100644 --- a/vanillinNeoForge/src/main/resources/vanillin.neoforge.mixins.json +++ b/vanillinNeoForge/src/main/resources/vanillin.neoforge.mixins.json @@ -1,13 +1,11 @@ { - "required" : true, - "minVersion" : "0.8", - "package" : "dev.engine_room.vanillin.neoforge.mixin", - "compatibilityLevel" : "JAVA_17", - "refmap" : "vanillin.refmap.json", - "client" : [ - "item.ItemColorsAccessor" + "required": true, + "minVersion": "0.8", + "package": "dev.engine_room.vanillin.neoforge.mixin", + "compatibilityLevel": "JAVA_25", + "client": [ ], - "injectors" : { - "defaultRequire" : 1 + "injectors": { + "defaultRequire": 1 } }