Compare commits

..

82 Commits

Author SHA1 Message Date
James Seibel 3f16d67746 fix blaze3d rendering 2026-04-08 07:39:36 -05:00
James Seibel 3a34dc8626 Create RenderPipelineBuilderWrapper and update test renderer 2026-04-05 18:42:02 -05:00
James Seibel c1766fb439 lightmap update 2026-04-05 17:30:09 -05:00
James Seibel cfd47adfda update fabric/neo api methods 2026-04-05 17:23:48 -05:00
James Seibel 9b9e6b9179 fix world gen 2026-04-05 17:23:14 -05:00
James Seibel 49d1587a71 re-add debug screen 2026-04-05 17:22:12 -05:00
James Seibel b0f5e55744 extend Iris incompat blaze3D message 2026-04-05 17:21:31 -05:00
James Seibel d9191534d5 add mod accessors 2026-04-05 17:21:14 -05:00
James Seibel ff459621e6 remove unused getFov() 2026-04-05 17:20:18 -05:00
James Seibel 64fb45d74d Fix access wideners 2026-04-05 17:18:32 -05:00
James Seibel 1590abb489 up CI java version 21 -> 25
will probably break old MC versions, the CI script will probably need some tweaking.
2026-04-03 22:38:23 -05:00
James Seibel a3c9b0654a Add MC 26 to the auto build script 2026-04-03 21:15:43 -05:00
James Seibel a9388321d9 Fix MC 1.21.11 compiling? 2026-04-03 20:46:50 -05:00
James Seibel 877c824e58 continue porting to MC 26 (2) 2026-04-03 20:02:32 -05:00
James Seibel 80f30dfd74 Continue porting to MC 26 2026-04-03 07:51:53 -05:00
Ran-Mewo 9a087025fe update stuffs 2026-03-31 12:21:11 +11:00
Ran-Mewo 21dc0f13c9 JVM Args & Don't use mappings on 26.1+ 2026-03-31 00:22:13 +11:00
James Seibel 7794958804 Start MC 26 porting 2026-03-30 07:49:36 -05:00
Ran-Mewo c245ed6598 improve filtering logic 2026-03-30 17:45:31 +11:00
Ran-Mewo 6270b03005 update unimined to support 26.1 2026-03-30 17:17:45 +11:00
Ran-Mewo 2674b945bb fix neoforg 2026-03-30 17:06:51 +11:00
James Seibel 0647bdbab3 update manifold 25.1.31 -> 26.1.6 2026-03-29 21:17:44 -05:00
Ran-Mewo 528a12ac83 fix javadocs 2026-03-30 02:20:00 +11:00
Ran-Mewo 4ac9de05df wao! 2026-03-30 02:07:40 +11:00
Ran-Mewo a0f1b72089 fix merged jars for CI 2026-03-30 01:13:28 +11:00
Ran-Mewo 85c07b11c6 meows 2026-03-30 00:51:58 +11:00
Ran-Mewo 215e1d46d0 wao 2026-03-29 19:29:11 +11:00
James Seibel 5f228f0567 Merge branch 'chunk-save-mixin-proto' into 'main'
On Chunk save ignore ProtoChunks

See merge request distant-horizons-team/distant-horizons!90
2026-03-27 19:24:42 +00:00
James Seibel f597958e1e disable thread pausing when render tasks exist 2026-03-27 07:01:12 -05:00
James Seibel 95921358f8 Merge branch 'main' of gitlab.com:distant-horizons-team/distant-horizons 2026-03-27 07:00:58 -05:00
James Seibel a22d494797 Merge branch 'internal-server-inverted-logic' into 'main'
Fix inverted chunk ignoring logic for generation mode "Save Chunks"

See merge request distant-horizons-team/distant-horizons!89
2026-03-26 21:32:36 +00:00
Fabian Maurer 666e917b8f Ignore ProtoChunks 2026-03-26 21:34:36 +01:00
Fabian Maurer a26a97e7fb Fix inverted chunk update ignoring logic 2026-03-26 21:32:15 +01:00
James Seibel cdbb9de933 remove instanced rendering config option 2026-03-24 19:38:03 -05:00
James Seibel feccf12580 Fix Iris using the wrong far clip plane
https://github.com/IrisShaders/Iris/issues/2534
2026-03-24 07:16:45 -05:00
James Seibel d371d93c9d add tracy to neo/fabric launch args 2026-03-22 21:26:58 -05:00
James Seibel 5f3e8d76b2 only set IS_RUNNING_IN_IDE for dev builds 2026-03-21 17:17:41 -05:00
James Seibel a7bd72e35b Minor speed improvement for GLBuffer upload 2026-03-21 17:09:26 -05:00
James Seibel 0a5326d2b1 fix phantom log when there is sufficient memory 2026-03-21 16:57:43 -05:00
James Seibel dad2014c46 fix cross level generic GL rendering 2026-03-21 16:35:50 -05:00
James Seibel 70dd0bda72 fix blaze3D memory leak 2026-03-21 16:13:30 -05:00
James Seibel 8213901229 remove unhelpful buffer delete mac test 2026-03-21 16:03:29 -05:00
James Seibel 668ba491e8 stage VBO/IBO upload and allow global IBO 2026-03-21 16:03:18 -05:00
James Seibel d85589c41a minor comment changes 2026-03-21 15:22:04 -05:00
James Seibel 7f5316108d Fix GL buffers not being deleted 2026-03-21 08:17:06 -05:00
James Seibel 9c1abbac2b ignore deprecation warning in TexturedButton 2026-03-21 07:32:56 -05:00
coolGi 1bb957a866 Add mailmap 2026-03-20 22:19:28 +13:00
James Seibel 6ccba17baf Fix render thread startup crash on Neoforge with GL 2026-03-19 07:29:46 -05:00
James Seibel e4c5d8adab Fix neoforge texture validation issue 2026-03-19 07:00:49 -05:00
James Seibel 823f204424 Fix texture using buffer flags 2026-03-19 07:00:35 -05:00
James Seibel 505e9a77fd Fix compiling for MC 1.20.4 and older 2026-03-18 07:49:09 -05:00
James Seibel 4c580fe4ff Add render task profiling 2026-03-18 07:45:50 -05:00
James Seibel efc1865f87 Add the ability to cull lilly pads, seaGrass, etc. 2026-03-15 20:53:29 -05:00
James Seibel ae08ad56c4 Fix MC complaining about GL shader file names 2026-03-15 16:52:17 -05:00
James Seibel 633544e0b0 remove unneeded chunk update warnings 2026-03-15 16:46:51 -05:00
James Seibel 2432028aa0 javadoc cleanup 2026-03-15 16:30:48 -05:00
James Seibel eb6aa13815 Disable generic rendering on Mac 2026-03-15 16:29:48 -05:00
James Seibel 55155103ec revert to AUTO rendering A if an invalid API is selected 2026-03-15 16:24:03 -05:00
James Seibel 667dd85aef Fix LOD rendering on Mac 2026-03-15 15:57:57 -05:00
James Seibel 9bd946a41c fix blaze wireframe renderer not appearing outside LODs 2026-03-14 15:55:57 -05:00
James Seibel 241baef7af Improve warning logs for chunkUpdateManager 2026-03-14 15:55:47 -05:00
James Seibel b5890a4783 clean up todo comments 2026-03-14 15:33:35 -05:00
James Seibel e3b67ef500 fix generic objects not uploading on first add
also clean up some comments
2026-03-14 15:27:16 -05:00
James Seibel 5905fe3df2 fix some generic objects not rendering 2026-03-14 14:33:55 -05:00
James Seibel 9d35a70437 fix shift-click not working on config min option 2026-03-14 14:33:39 -05:00
James Seibel f121860563 Fixes beacons not always showing/hiding correctly 2026-03-14 14:33:13 -05:00
James Seibel 9715db3ac6 fix generic rendering not uploading in some cases 2026-03-14 14:31:25 -05:00
James Seibel 03a29fbacb fix compiler warnings 2026-03-14 10:19:03 -05:00
James Seibel e91888934b Try fix concurrency issue with render closing 2026-03-14 10:18:50 -05:00
James Seibel 030f814398 Fix 1.21.11 compiling 2026-03-14 09:32:35 -05:00
James Seibel 90ef8fd64d Fix GL buffer upload corrupting the GL state 2026-03-14 09:20:36 -05:00
James Seibel 0ffefaa8c1 Fix a few Legacy GL issues 2026-03-13 07:42:41 -05:00
James Seibel 99703d65df Fix fade renderer using the wrong frame buffer 2026-03-13 07:42:09 -05:00
s809 bd2f5a7836 Stop pregen on server shutdown 2026-03-13 00:48:05 +05:00
s809 a44556f86a Replace fix with debug wireframe stub 2026-03-12 22:38:38 +05:00
s809 4597b7f647 Fix server not loading levels 2026-03-12 19:20:47 +05:00
James Seibel 0de80cfaa7 Fix AUTO rendering API crashing 2026-03-12 06:49:02 -05:00
James Seibel 034aaddca3 Allow translucent generic objects 2026-03-10 19:26:28 -05:00
James Seibel a1d493f25d fix refactor rename 2026-03-10 19:18:03 -05:00
James Seibel 4b5a4dda79 Up API version 5.1.0 -> 6.0.0 2026-03-10 19:08:01 -05:00
James Seibel ce528f3fd5 up DH version 2.4.6 -> 3.0.0 2026-03-10 19:07:50 -05:00
James Seibel e4c769e95e merge blaze renderer changes 2026-03-10 19:07:07 -05:00
116 changed files with 3021 additions and 2098 deletions
+3 -3
View File
@@ -1,6 +1,6 @@
# use Eclipse's JDK
# The ci should always use a unix(-like) OS to work
image: eclipse-temurin:21
image: eclipse-temurin:25
# all stages need to be defined here
stages:
@@ -35,6 +35,7 @@ build:
parallel:
matrix:
- MC_VER: [
"1.26.1",
"1.21.11", "1.21.10", "1.21.9", "1.21.8", "1.21.6", "1.21.5", "1.21.4", "1.21.3", "1.21.1",
"1.20.6", "1.20.4", "1.20.2", "1.20.1",
"1.19.4", "1.19.2",
@@ -46,8 +47,7 @@ build:
# this both runs the unit tests and assembles the code
- ./gradlew clean -PmcVer="${MC_VER}" -PinfoGitCommit="${CI_COMMIT_SHA}" -PinfoGitBranch="${CI_COMMIT_BRANCH}" -PinfoBuildSource="GitLab CI (${CI_PIPELINE_ID})" --gradle-user-home cache/;
- ./gradlew build -PmcVer="${MC_VER}" -PinfoGitCommit="${CI_COMMIT_SHA}" -PinfoGitBranch="${CI_COMMIT_BRANCH}" -PinfoBuildSource="GitLab CI (${CI_PIPELINE_ID})" --gradle-user-home cache/;
- ./gradlew mergeJars -PmcVer="${MC_VER}" -PinfoGitCommit="${CI_COMMIT_SHA}" -PinfoGitBranch="${CI_COMMIT_BRANCH}" -PinfoBuildSource="GitLab CI (${CI_PIPELINE_ID})" --gradle-user-home cache/;
- cp ./fabric/build/libs/* ./forge/build/libs/* ./neoforge/build/libs/* ./build/merged/* . || true
- cp ./fabric/build/libs/* ./forge/build/libs/* ./neoforge/build/libs/* ./build/forgix/* . || true
artifacts:
name: "NightlyBuild_${MC_VER}-${CI_COMMIT_SHORT_SHA}-${CI_COMMIT_TIMESTAMP}"
paths:
+16
View File
@@ -0,0 +1,16 @@
# See mailmap docs: https://git-scm.com/docs/gitmailmap
# Test with git shortlog --summary --email
# Keep sorted for easier editing and smaller diffs
Ada Aster <an.ada.poirier@gmail.com>
CodeF53 <fseusb@gmail.com> <37855219+CodeF53@users.noreply.github.com>
coolGi <me@coolgi.dev> <sasanaps@hotmail.com>
James Seibel <jeseibel@gondtc.com> <jseibel@vertsys.com>
Morippi <leoleo97@libero.it> <leoloe97@libero.it>
Morippi <leoleo97@libero.it> <Morippi>
Ran <43445785+Ran-Mewo@users.noreply.github.com> <10044908-_Ran@users.noreply.gitlab.com>
Ran <43445785+Ran-Mewo@users.noreply.github.com> <43445785+Ran-Mewo@users.noreply.github.com>
Ran <43445785+Ran-Mewo@users.noreply.github.com> <43445785+RanCraftPlayz@users.noreply.github.com>
TomTheFurry <tomlee92502@yahoo.com>
TomTheFurry <tomlee92502@yahoo.com> <46843632+TomTheFurry@users.noreply.github.com>
Yeshi <yeshi@newengine.org>
+1 -1
View File
@@ -1,4 +1,4 @@
FROM eclipse-temurin:17-jdk
FROM eclipse-temurin:25-jdk
WORKDIR /home/build/
COPY ./gradlew .
+4 -680
View File
@@ -1,684 +1,8 @@
import com.github.jengelman.gradle.plugins.shadow.transformers.Transformer
import com.github.jengelman.gradle.plugins.shadow.transformers.TransformerContext
import org.apache.tools.zip.ZipEntry
import javax.annotation.Nonnull
import org.apache.tools.zip.ZipOutputStream
import java.util.function.Function
import java.util.function.Predicate
plugins {
id "java"
// Plugin to put dependencies inside our final jar
id "com.github.johnrengelman.shadow" version '8.1.1' apply false
// Plugin to create merged jars
id "io.github.pacifistmc.forgix" version "1.3.4"
// Manifold preprocessor
id "systems.manifold.manifold-gradle-plugin" version "0.0.2-alpha"
// Architectury is used here only as a replacement for forge's own loom
id "dev.architectury.loom" version "1.13-SNAPSHOT" apply false
id 'root'
id 'io.github.pacifistmc.forgix' version '2.+'
}
/**
* Creates the list of preprocessors to use.
*
* @param mcVers array of all MC versions
* @param mcIndex array index of the currently active MC version
*/
def writeBuildGradlePredefine(List<String> mcVers, int mcIndex)
{
// Build the list of preprocessors to use
StringBuilder sb = new StringBuilder();
sb.append("# DON'T TOUCH THIS FILE, This is handled by the build script\n");
for (int i = 0; i < mcVers.size(); i++)
{
String verStr = mcVers[i].replace(".", "_");
sb.append("MC_" + verStr + "=" + i.toString() + "\n");
if (mcIndex == i)
{
sb.append("MC_VER=" + i.toString() + "\n");
}
}
// Check if this is a development build
if (mod_version.toLowerCase().contains("dev"))
{
// WARNING: only use this for logging, we don't want to have confusion
// when a method doesn't work correctly in the release build.
sb.append("DEV_BUILD=\n");
}
new File(projectDir, "build.properties").text = sb.toString()
}
// Transfers the values set in settings.gradle to the rest of the project
project.gradle.ext.getProperties().each { prop ->
rootProject.ext.set(prop.key, prop.value)
//println "Added prop [key:" + prop.key + ", value:" + prop.value + "]"
}
// Sets up manifold stuff
writeBuildGradlePredefine(rootProject.mcVers, rootProject.mcIndex)
// Sets up the version string (the name we use for our jar)
rootProject.versionStr = rootProject.mod_version + "-" + rootProject.minecraft_version // + "-" + new Date().format("yyyy_MM_dd_HH_mm")
class NativeTransformer implements Transformer {
private Predicate<String> fileMatcher
private Function<String, String> filePathMapper
private final HashMap<String, String> replacements = new HashMap()
private final HashMap<String, byte[]> rewrittenFiles = new HashMap()
private var nativeRelocator
public File rootDir
void matchFiles(Predicate<String> matcher) {
fileMatcher = matcher
}
void mapPaths(Function<String, String> mapper) {
filePathMapper = mapper
}
void relocateNative(String target, String replacement) {
if (replacement.length() > target.length()) {
throw new GradleException("Length of value \"${replacement}\" exceeds the length of \"${target}\": ${replacement.length()} > ${target.length()}")
}
replacements.put(target, replacement)
}
@Override
boolean canTransformResource(@Nonnull FileTreeElement element) {
return fileMatcher.test(element.name)
}
@Override
void transform(@Nonnull TransformerContext context) {
byte[] content = context.is.readAllBytes()
if (nativeRelocator == null) {
nativeRelocator = new NativeRelocator(rootDir.toPath().resolve("relocate_natives"))
}
try {
String path = filePathMapper != null
? filePathMapper.apply(context.path)
: context.path
content = nativeRelocator.processBinary(path, content, replacements)
rewrittenFiles.put(path, content)
}
catch (Throwable e) {
throw new GradleException("Failed to relocate", e)
}
}
@Override
boolean hasTransformedResource() { return !rewrittenFiles.isEmpty() }
@Override
void modifyOutputStream(@Nonnull ZipOutputStream os, boolean preserveFileTimestamps) {
for (Map.Entry<String, byte[]> rewrittenFile : rewrittenFiles.entrySet()) {
os.putNextEntry(new ZipEntry(rewrittenFile.key))
os.write(rewrittenFile.value)
}
}
}
subprojects { p ->
// Does the same as "p == project(":common") || p == project(":fabric") || p == project(":quilt") || p == project(":forge") || p == project("WhateverWeAddLaterOn")"
// Useful later on so we dont have duplicated code
def isMinecraftSubProject = p != project(":core") && p != project(":api")
// Apply plugins
apply plugin: "java"
apply plugin: "com.github.johnrengelman.shadow"
if (isMinecraftSubProject)
apply plugin: "systems.manifold.manifold-gradle-plugin"
// Apply forge's loom
if ((findProject(":forge") && p == project(":forge")) ||
(findProject(":neoforge") && p == project(":neoforge"))
)
{
apply plugin: "dev.architectury.loom"
}
// Set the manifold version (may not be required tough)
manifold {
manifoldVersion = rootProject.manifold_version
}
// set up custom configurations (configurations are a way to handle dependencies)
configurations {
// extends the shadowJar configuration
shadowMe
// have implemented dependencies automatically embedded in the final jar
implementation.extendsFrom(shadowMe)
// Configuration fpr core & api
coreProjects
shadowMe.extendsFrom(coreProjects)
// FIXME this additional configuration is necessary because forge
// needs forgeRuntimeLibrary, although adding it to shadowMe
// causes runtime issues where the libraries aren't properly added
forgeShadowMe
// this should match shadowMe pretty closely
implementation.extendsFrom(forgeShadowMe)
shadowMe.extendsFrom(forgeShadowMe)
forgeRuntimeLibrary.extendsFrom(forgeShadowMe)
if (isMinecraftSubProject && p != project(":common")) {
// Shadow common
common
shadowCommon // Don't use shadow from the shadow plugin because we don't want IDEA to index this.
compileClasspath.extendsFrom common
runtimeClasspath.extendsFrom common
if (findProject(":forge"))
developmentForge.extendsFrom common
if (findProject(":neoforge"))
developmentNeoForge.extendsFrom common
compileClasspath.extendsFrom coreProjects
runtimeClasspath.extendsFrom coreProjects
if (findProject(":forge"))
developmentForge.extendsFrom coreProjects
if (findProject(":neoforge"))
developmentNeoForge.extendsFrom coreProjects
}
}
dependencies {
//=====================//
// shared dependencies //
//=====================//
// Manifold
if (isMinecraftSubProject) {
annotationProcessor("systems.manifold:manifold-preprocessor:${rootProject.manifold_version}")
}
// Log4j
if (p == project(":core"))
{
// the standalone core jar needs logging shaded otherwise it won't run
forgeShadowMe("org.apache.logging.log4j:log4j-api:${rootProject.log4j_version}")
forgeShadowMe("org.apache.logging.log4j:log4j-core:${rootProject.log4j_version}")
}
else
{
// When running in MC, MC already includes logging
implementation("org.apache.logging.log4j:log4j-api:${rootProject.log4j_version}")
implementation("org.apache.logging.log4j:log4j-core:${rootProject.log4j_version}")
}
// JOML
if (project.hasProperty("embed_joml") && embed_joml == "true")
forgeShadowMe("org.joml:joml:${rootProject.joml_version}")
else
implementation("org.joml:joml:${rootProject.joml_version}")
// JUnit tests
implementation("org.junit.jupiter:junit-jupiter:5.8.2")
implementation("org.junit.jupiter:junit-jupiter-engine:5.8.2")
implementation("junit:junit:4.13")
// FastUtil
// Note: MC 1.16 uses 8.2.1, and versions after use 8.5.12
// We cannot relocate this library since we call some MC classes that reference it
implementation("it.unimi.dsi:fastutil:${rootProject.fastutil_version}")
forgeShadowMe("com.github.luben:zstd-jni:${rootProject.zstd_version}")
// Compression
forgeShadowMe("org.lz4:lz4-java:${rootProject.lz4_version}") // LZ4
forgeShadowMe("org.tukaani:xz:${rootProject.xz_version}") // LZMA
// Sqlite Database
forgeShadowMe("org.xerial:sqlite-jdbc:${rootProject.sqlite_jdbc_version}")
// NightConfig (includes Toml & Json)
forgeShadowMe("com.electronwill.night-config:toml:${rootProject.nightconfig_version}")
forgeShadowMe("com.electronwill.night-config:json:${rootProject.nightconfig_version}")
// SVG (not needed atm)
// forgeShadowMe("com.formdev:svgSalamander:${rootProject.svgSalamander_version}")
// Netty
implementation("io.netty:netty-buffer:${rootProject.netty_version}")
//==========================//
// conditional dependencies //
//==========================//
// Add core
if (isMinecraftSubProject) {
coreProjects(project(":core")) {
// Remove Junit test libraries
exclude group: "org.junit.jupiter", module: "junit-jupiter"
exclude group: "org.junit.jupiter", module: "junit-jupiter-engine"
exclude group: "junit", module: "junit"
// Removed dependencies
transitive false
}
}
// Add the api
if (p != project(":api")) {
coreProjects(project(":api")) {
// Remove Junit test libraries
exclude group: "org.junit.jupiter", module: "junit-jupiter"
exclude group: "org.junit.jupiter", module: "junit-jupiter-engine"
exclude group: "junit", module: "junit"
// Removed dependencies
transitive false
}
}
// Add common
if (isMinecraftSubProject && p != project(":common")) {
// Common
common(project(":common")) { transitive false }
shadowCommon(project(":common")) { transitive false }
}
}
shadowJar {
configurations = [project.configurations.shadowMe]
if (isMinecraftSubProject && p != project(":common")) {
configurations.push(project.configurations.shadowCommon) // Shadow the common subproject
relocate "com.seibel.distanthorizons.common", "loaderCommon.${p.name}.com.seibel.distanthorizons.common" // Move the loader files to a different location
}
def librariesLocation = "DistantHorizons.libraries"
// Compression (LZ4)
relocate "net.jpountz", "${librariesLocation}.jpountz"
// Logging
relocate "org.slf4j", "${librariesLocation}.slf4j"
// Sqlite Database
// librariesLocation isn't used because it's too long for replacing paths in native libraries
// Allowing strings larger than the original string would require shifting the entire binary's contents
relocate "org.sqlite", "dh_sqlite", {
exclude "org/sqlite/native/**"
}
relocate "jdbc:sqlite", "jdbc:dh_sqlite"
transform(NativeTransformer) {
rootDir = project.rootDir
matchFiles { it.startsWith("org/sqlite") }
mapPaths { it.replace("org/sqlite", "dh_sqlite") }
relocateNative "org/sqlite", "dh_sqlite"
relocateNative "org_sqlite", "dh_1sqlite"
}
// ZStd
// librariesLocation isn't used because it's too long for replacing paths in native libraries
// Allowing strings larger than the original string would require shifting the entire binary's contents
relocate "com.github.luben", "dhcomgithubluben"
relocate "libzstd-jni", "libzstd-jni_dh"
relocate "zstd-jni", "zstd-jni_dh"
transform(NativeTransformer) {
rootDir = project.rootDir
matchFiles { it.contains("libzstd-jni") && !it.contains("aix/ppc64") }
mapPaths { it.replace("libzstd-jni", "libzstd-jni_dh") }
relocateNative "com/github/luben", "dhcomgithubluben"
relocateNative "com_github_luben", "dhcomgithubluben"
}
// JOML
if (project.hasProperty("embed_joml") && embed_joml == "true")
relocate "org.joml", "${librariesLocation}.joml"
// NightConfig (includes Toml & Json)
relocate "com.electronwill.nightconfig", "${librariesLocation}.electronwill.nightconfig"
// Netty
// Don't relocate, it causes problems with using MC's FriendlyByteBufs
// relocate "io.netty", "${librariesLocation}.netty"
mergeServiceFiles()
}
// Using jar.finalizedBy(shadowJar) causes issues so we do this scuffed bypass
jar.dependsOn(shadowJar)
// Put stuff from gradle.properties into the mod info
// Note: these resources are only included in the mod jars, the core and API jars don't include these files
processResources {
def resourceTargets = [ // Location of where to inject the properties
// Holds info like git commit
"build_info.json",
// Properties for each of the loaders
"fabric.mod.json",
"quilt.mod.json",
"META-INF/mods.toml",
"META-INF/neoforge.mods.toml",
// The mixins for each of the loaders
//"DistantHorizons."+ p.name +".fabricLike.mixins.json"
]
def intoTargets = ["$buildDir/resources/main/"] // Location of the built resources folder
// Fix forge version numbering system as it is weird
// For whatever reason forge uses [1.18, 1.18.1, 1.18.2) instead of the standard ["1.18", "1.18.1", "1.18.2"]
def compatible_forgemc_versions = "${compatible_minecraft_versions}".replaceAll("\"", "").replaceAll("]", ",)")
// println compatible_forgemc_versions
// Quilt's custom contributors system
// This has to be like
// "Person": "Developer", "Another person": "Developer"
def quilt_contributors = []
def mod_author_list = mod_authors.replaceAll("\"", "").replace("[", "").replace("]", "").split(",")
for (dev in mod_author_list) {
quilt_contributors.push("\"${dev.strip()}\": \"Developer\"")
}
quilt_contributors.reverse()
//println quilt_contributors.join(", ")
// These "hasProperty"'s are so that they can be passed through the cli (ie in the CI)
try {
if (infoGitCommit == "null")
infoGitCommit = 'git rev-parse --verify HEAD'.execute().text.trim()
if (infoGitBranch == "null")
infoGitBranch = 'git symbolic-ref --short HEAD'.execute().text.trim()
} catch (Exception e) {
infoGitCommit = infoGitBranch = "Git not found"
println "Git or Git project not found"
}
// The left side is what gets replaced in the mod info and the right side is where to get it from in the gradle.properties
def replaceProperties = [
version : mod_version,
mod_name : mod_readable_name,
group : maven_group,
authors : mod_authors,
description : mod_description,
homepage : mod_homepage,
source : mod_source,
issues : mod_issues,
discord : mod_discord,
minecraft_version : minecraft_version,
compatible_minecraft_versions: compatible_minecraft_versions,
compatible_forgemc_versions : compatible_forgemc_versions,
java_version : java_version,
quilt_contributors : "{"+quilt_contributors.join(", ")+"}",
info_git_commit : infoGitBranch,
info_git_branch : infoGitCommit,
info_build_source : infoBuildSource,
fabric_incompatibility_list : fabric_incompatibility_list,
fabric_recommend_list : fabric_recommend_list,
neoforge_version_range : neoforge_version_range,
]
// replace any properties in the sub-projects with the values defined here
inputs.properties replaceProperties
replaceProperties.put "project", project
filesMatching(resourceTargets) {
expand replaceProperties
}
intoTargets.each { target ->
if (file(target).exists()) {
copy {
from(sourceSets.main.resources) {
include resourceTargets
expand replaceProperties
}
into target
}
}
}
// ==================== Delete un-needed files ====================
// Jank solution to remove all unused accesswideners
// (neo)forge (well, mainly architectury) requires the original accesswidener file, meaning we require this jank solution to keep it
exclude { file ->
if (file.name.contains(".distanthorizons.accesswidener") && file.name != "${accessWidenerVersion}.distanthorizons.accesswidener") {
return true
}
return false
}
}
// Adds the standalone jar's entrypoint
jar {
from "LICENSE.txt"
manifest {
attributes(
'Implementation-Title': rootProject.mod_name,
'Implementation-Version': rootProject.mod_version,
'Multi-Release': true, // needed for logging in the standalone core jar
'Main-Class': 'com.seibel.distanthorizons.core.jar.JarMain', // When changing the main of the jar change this line
)
}
}
// this can be un-commented if we ever wanted to make DH modular (AKA use a module-info.java file) again
/*
// Tells gradle where to look for other modules
// Why isn't the classpath added to the modules path by default?
if (p == project(":core")) {
compileJava {
inputs.property('moduleName', 'dhApi')
doFirst {
options.compilerArgs = [
'--module-path', classpath.asPath
]
classpath = files()
}
}
}
*/
}
allprojects { p ->
// Does the same as "p == project(":common") || p == project(":fabric") || p == project(":quilt") || p == project(":forge") || p == project("WhateverWeAddLaterOn")"
// Useful later on so we dont have duplicated code
def isMinecraftSubProject = p != project(":core") && p != project(":api")
apply plugin: "java"
apply plugin: "maven-publish"
// Sets the name of the jar, the version will contain the name of the project if it isn't the root project
archivesBaseName = rootProject.mod_name
version = (project == rootProject ? "" : project.name + "-") + rootProject.versionStr
group = rootProject.maven_group
// this is the text that appears at the top of the overview (home) page
// and is used when bookmarking a page
javadoc.title = rootProject.mod_name + "-" + project.name
// Some annotations arent "technically" part of the official java standard,
// so we define it ourself here
javadoc {
configure( options ) {
tags(
'todo:X"',
'apiNote:a:API Note:',
'implSpec:a:Implementation Requirements:',
'implNote:a:Implementation Note:'
)
}
}
repositories {
// Mojang overrides (added to fix downloading the wrong LWJGL libs on M1 Mac's and potentially other arm64 based machines)
maven { url "https://libraries.minecraft.net/" }
// The central repo
mavenCentral()
// Used for Google's Collect library
maven { url "https://repo.enonic.com/public/" }
// For parchment mappings
// versions can be found here: https://ldtteam.jfrog.io/ui/native/parchmentmc-public/org/parchmentmc/data/
maven { url "https://maven.parchmentmc.org" }
// For Architectury API
maven { url "https://maven.architectury.dev" }
// For Git repositories
maven { url "https://jitpack.io" }
// For Manifold Preprocessor
maven { url "https://oss.sonatype.org/content/repositories/snapshots/" }
// Required for importing Modrinth mods
maven {
name = "Modrinth"
url = "https://api.modrinth.com/maven"
content {
includeGroup "maven.modrinth"
}
}
// Required for importing CursedForge mods
maven {
url "https://www.cursemaven.com"
content {
includeGroup "curse.maven"
}
}
// VanillaGradle and Mixins in common
maven { url "https://repo.spongepowered.org/maven/" }
// Canvas mod
maven { url "https://maven.vram.io/" }
// ModMenu mod
maven { url "https://maven.terraformersmc.com/" }
// neoforge
maven { url "https://maven.neoforged.net/releases/" }
// These 3 are for importing mods that arnt on CursedForge, Modrinth, GitHub, GitLab or anywhere opensource
flatDir {
dirs "${rootDir}/mods/fabric"
content {
includeGroup "fabric-mod"
}
}
flatDir {
dirs "${rootDir}/mods/quilt"
content {
includeGroup "quilt-mod"
}
}
flatDir {
dirs "${rootDir}/mods/forge"
content {
includeGroup "forge-mod"
}
}
}
// Adds some dependencies that are in vanilla but not in core
if (p == project(":core")) {
OperatingSystem os = org.gradle.nativeplatform.platform.internal.DefaultNativePlatform.currentOperatingSystem;
// Set the OS lwjgl is using to the current os
project.ext.lwjglNatives = "natives-" + os.toFamilyName()
dependencies {
// All of these dependencies are in Vanilla Minecraft, but we need to depend on them as we arent importing Minecraft in the core
// Imports most of lwjgl's libraries
implementation platform("org.lwjgl:lwjgl-bom:${rootProject.lwjgl_version}")
// REMEMBER: Don't shadow stuff here, these are just the libs that are included in Minecraft so that the core can use them
implementation "org.lwjgl:lwjgl"
implementation "org.lwjgl:lwjgl-assimp"
implementation "org.lwjgl:lwjgl-glfw"
// OpenGL is removed since DH now handles rendering in the "Common" project
// so we can use OpenGL for old MC versions and Blaze3D (IE Vulkan) for newer ones
// implementation "org.lwjgl:lwjgl-openal"
// implementation "org.lwjgl:lwjgl-opengl"
implementation "org.lwjgl:lwjgl-stb"
implementation "org.lwjgl:lwjgl-tinyfd"
runtimeOnly "org.lwjgl:lwjgl::$lwjglNatives"
runtimeOnly "org.lwjgl:lwjgl-assimp::$lwjglNatives"
runtimeOnly "org.lwjgl:lwjgl-glfw::$lwjglNatives"
// runtimeOnly "org.lwjgl:lwjgl-openal::$lwjglNatives"
// runtimeOnly "org.lwjgl:lwjgl-opengl::$lwjglNatives"
runtimeOnly "org.lwjgl:lwjgl-stb::$lwjglNatives"
runtimeOnly "org.lwjgl:lwjgl-tinyfd::$lwjglNatives"
implementation "org.joml:joml:${rootProject.joml_version}"
// Some other dependencies
implementation("org.jetbrains:annotations:16.0.2")
implementation("com.google.code.findbugs:jsr305:3.0.2")
implementation("com.google.common:google-collect:0.5")
implementation("com.google.guava:guava:31.1-jre")
}
}
task copyCommonLoaderResources(type: Copy) {
from project(":common").file("src/main/resources/${accessWidenerVersion}.distanthorizons.accesswidener")
into(file(p.file("build/resources/main")))
rename "${accessWidenerVersion}.distanthorizons.accesswidener", "distanthorizons.accesswidener"
}
task copyCoreResources(type: Copy) {
from fileTree(project(":core").file("src/main/resources"))
into p.file("build/resources/main")
}
tasks.withType(JavaCompile) {
if (isMinecraftSubProject) {
options.release = rootProject.java_version as Integer
} else {
options.release = 8; // Core & Api should use Java 8 no matter what
}
options.encoding = "UTF-8"
}
java {
withSourcesJar()
}
forgix {
autoRun = true
}
+24
View File
@@ -0,0 +1,24 @@
plugins {
id 'groovy-gradle-plugin'
}
repositories {
gradlePluginPortal()
mavenCentral()
maven { url = 'https://maven.wagyourtail.xyz/releases' } // Jvmdowngrader & unimined libs
maven { url = 'https://maven.outlands.top/releases' } // Hosts the kappa fork of unimined
maven { url = 'https://maven.wagyourtail.xyz/snapshots' } // The manifold gradle plugin we use
maven { url = 'https://maven.architectury.dev/' } // Minecraft mod libs
maven { url = 'https://maven.fabricmc.net/' } // Fabric
maven { url = 'https://maven.neoforged.net/releases/' } // NeoForge
maven { url = 'https://maven.minecraftforge.net/' } // Forge
maven { url = 'https://repo.spongepowered.org/repository/maven-public/' } // Hosts minecraft libs
maven { url = 'https://oss.sonatype.org/content/repositories/snapshots/' } // Hosts a few dependencies we use
}
dependencies {
implementation 'com.gradleup.shadow:shadow-gradle-plugin:9.0.0'
implementation 'xyz.wagyourtail.unimined:xyz.wagyourtail.unimined.gradle.plugin:1.4.17-kappa'
implementation 'xyz.wagyourtail:manifold-gradle:1.0.0-SNAPSHOT'
implementation 'xyz.wagyourtail.jvmdowngrader:xyz.wagyourtail.jvmdowngrader.gradle.plugin:1.3.4'
}
+467
View File
@@ -0,0 +1,467 @@
import com.github.jengelman.gradle.plugins.shadow.transformers.ResourceTransformer
import com.github.jengelman.gradle.plugins.shadow.transformers.TransformerContext
import org.apache.tools.zip.ZipEntry
import org.apache.tools.zip.ZipOutputStream
import javax.annotation.Nonnull
import java.util.function.Function
import java.util.function.Predicate
// Convention plugin for all MC-facing subprojects (common + loaders).
// Common uses this directly; loaders use it via unimined-fabric/forge/neoforge.
// IMPORTANT: unimined MUST be applied before shadow/jvmdowngrader
// so its afterEvaluate runs first and can modify configs.
plugins {
id 'java'
id 'maven-publish'
id 'xyz.wagyourtail.unimined'
id 'com.gradleup.shadow'
id 'xyz.wagyourtail.manifold'
id 'xyz.wagyourtail.jvmdowngrader'
}
def isNotCommonProject = project.name != "common"
// ==================== Version Properties ====================
project.gradle.ext.getProperties().each { prop ->
rootProject.ext.set(prop.key, prop.value)
}
manifold {
version = rootProject.manifold_version
}
// ==================== Repositories ====================
repositories {
maven { url "https://libraries.minecraft.net/" }
mavenCentral()
maven { url "https://repo.enonic.com/public/" }
maven { url "https://maven.parchmentmc.org" }
maven { url "https://maven.architectury.dev" }
maven { url "https://jitpack.io" }
maven { url "https://oss.sonatype.org/content/repositories/snapshots/" }
maven {
name = "Modrinth"
url = "https://api.modrinth.com/maven"
content { includeGroup "maven.modrinth" }
}
maven {
url "https://www.cursemaven.com"
content { includeGroup "curse.maven" }
}
maven { url "https://repo.spongepowered.org/maven/" }
maven { url "https://maven.terraformersmc.com/" }
maven { url "https://maven.neoforged.net/releases/" }
flatDir {
dirs "${rootDir}/mods/fabric"
content { includeGroup "fabric-mod" }
}
flatDir {
dirs "${rootDir}/mods/quilt"
content { includeGroup "quilt-mod" }
}
flatDir {
dirs "${rootDir}/mods/forge"
content { includeGroup "forge-mod" }
}
}
// ==================== Java Config ====================
tasks.withType(JavaCompile).configureEach {
options.release = rootProject.java_version as Integer
options.encoding = "UTF-8"
}
java {
sourceCompatibility = JavaVersion.toVersion(gradle.ext.java_version as Integer)
targetCompatibility = JavaVersion.toVersion(gradle.ext.java_version as Integer)
withSourcesJar()
}
// ==================== Loader-Only Config ====================
if (isNotCommonProject) {
base { archivesName = rootProject.mod_name }
rootProject.ext.versionStr = rootProject.mod_version + "-" + rootProject.minecraft_version
version = project.name + "-" + rootProject.versionStr
group = rootProject.maven_group
javadoc.title = rootProject.mod_name + "-" + project.name
tasks.withType(GenerateModuleMetadata).configureEach {
enabled = false
}
tasks.withType(Test).configureEach {
enabled = false
}
compileTestJava.enabled = false
tasks.withType(Sign).configureEach {
enabled = false
}
jar {
from "LICENSE.txt"
manifest {
attributes(
'Implementation-Title': rootProject.mod_name,
'Implementation-Version': rootProject.mod_version,
'Multi-Release': true,
'Main-Class': 'com.seibel.distanthorizons.core.jar.JarMain',
)
}
}
}
// ==================== Unimined Minecraft Config ====================
unimined.minecraft(sourceSets.main, true) {
version gradle.ext.minecraft_version
if (gradle.ext.minecraft_version.startsWith("1.")) { // 26.1+ doesn't use obfuscation
mappings {
mojmap()
devNamespace "mojmap"
}
}
}
if (isNotCommonProject) {
// Mixin remapping and common project wiring
unimined.minecraft(sourceSets.main, true) {
mods.modImplementation {
mixinRemap {
reset()
enableBaseMixin()
enableMixinExtra()
}
// Some Fabric API modules ship AW in 'named' namespace instead of 'intermediary'
catchAWNamespaceAssertion()
}
}
dependencies {
implementation(project(":common"))
}
processResources {
from project(":common").sourceSets.main.resources
}
tasks.withType(JavaCompile).configureEach {
source(project(":common").sourceSets.main.allSource)
}
} else {
// Common: fabric for compilation + access widener, no jar remapping or runs
unimined.minecraft {
fabric {
loader gradle.ext.fabric_loader_version
accessWidener project.file("src/main/resources/${gradle.ext.accessWidenerVersion}.distanthorizons.accesswidener")
}
defaultRemapJar = false
runs.off = true
}
}
// ==================== Configurations ====================
evaluationDependsOn(":core")
configurations {
shadowMe
coreProjects
shadowMe.extendsFrom(coreProjects)
implementation.extendsFrom(shadowMe)
common
implementation.extendsFrom(common)
}
// ==================== Dependencies ====================
// Copy core's compileOnly deps so MC-provided deps are visible without redeclaring them.
project(":core").configurations.compileOnly.allDependencies.each { dep ->
if (!(dep instanceof ProjectDependency))
dependencies.add("compileOnly", dep)
}
dependencies {
// Manifold preprocessor & strings
annotationProcessor(manifold.module("preprocessor"))
// NightConfig: implementation in core (bundled) but Unimined strips it from compile classpath
compileOnly("com.electronwill.night-config:toml:${rootProject.nightconfig_version}")
// Core & API projects — bundled into shadow jar
coreProjects(project(":core"))
coreProjects(project(":api"))
// JOML: shadow for old MC versions that don't bundle it (core has it compileOnly already)
if (project.hasProperty("embed_joml") && embed_joml == "true")
shadowMe("org.joml:joml:${rootProject.joml_version}")
// Common project dependency
if (isNotCommonProject)
common(project(":common")) { transitive false }
}
// ==================== NativeTransformer ====================
class NativeTransformer implements ResourceTransformer {
private Predicate<String> fileMatcher
private Function<String, String> filePathMapper
private final HashMap<String, String> replacements = new HashMap()
private final HashMap<String, byte[]> rewrittenFiles = new HashMap()
private nativeRelocator
public File rootDir
void matchFiles(Predicate<String> matcher) {
fileMatcher = matcher
}
void mapPaths(Function<String, String> mapper) {
filePathMapper = mapper
}
void relocateNative(String target, String replacement) {
if (replacement.length() > target.length()) {
throw new GradleException("Length of value \"${replacement}\" exceeds the length of \"${target}\": ${replacement.length()} > ${target.length()}")
}
replacements.put(target, replacement)
}
@Override
boolean canTransformResource(@Nonnull FileTreeElement element) {
return fileMatcher != null && fileMatcher.test(element.relativePath.pathString)
}
@Override
void transform(@Nonnull TransformerContext context) {
byte[] content = context.inputStream.readAllBytes()
if (nativeRelocator == null) {
nativeRelocator = new NativeRelocator(rootDir.toPath().resolve("relocate_natives"))
}
try {
String path = filePathMapper != null
? filePathMapper.apply(context.path)
: context.path
content = nativeRelocator.processBinary(path, content, replacements)
rewrittenFiles.put(path, content)
}
catch (Throwable e) {
throw new GradleException("Failed to relocate", e)
}
}
@Override
boolean hasTransformedResource() { return !rewrittenFiles.isEmpty() }
@Override
void modifyOutputStream(@Nonnull ZipOutputStream os, boolean preserveFileTimestamps) {
for (Map.Entry<String, byte[]> rewrittenFile : rewrittenFiles.entrySet()) {
os.putNextEntry(new ZipEntry(rewrittenFile.key))
os.write(rewrittenFile.value)
}
}
}
// ==================== Shadow JAR (loaders only) ====================
if (isNotCommonProject) {
shadowJar {
configurations = [project.configurations.shadowMe]
relocate "com.seibel.distanthorizons.common", "loaderCommon.${project.name}.com.seibel.distanthorizons.common"
def librariesLocation = "DistantHorizons.libraries"
// LZ4
relocate "net.jpountz", "${librariesLocation}.jpountz"
// SLF4J
relocate "org.slf4j", "${librariesLocation}.slf4j"
// SQLite
relocate "org.sqlite", "dh_sqlite", { exclude "org/sqlite/native/**" }
relocate "jdbc:sqlite", "jdbc:dh_sqlite"
transform(NativeTransformer) {
rootDir = project.rootDir
matchFiles { it.startsWith("org/sqlite") }
mapPaths { it.replace("org/sqlite", "dh_sqlite") }
relocateNative "org/sqlite", "dh_sqlite"
relocateNative "org_sqlite", "dh_1sqlite"
}
// ZStd
relocate "com.github.luben", "dhcomgithubluben"
relocate "libzstd-jni", "libzstd-jni_dh"
relocate "zstd-jni", "zstd-jni_dh"
transform(NativeTransformer) {
rootDir = project.rootDir
matchFiles { it.contains("libzstd-jni") && !it.contains("aix/ppc64") }
mapPaths { it.replace("libzstd-jni", "libzstd-jni_dh") }
relocateNative "com/github/luben", "dhcomgithubluben"
relocateNative "com_github_luben", "dhcomgithubluben"
}
// JOML (conditional)
if (project.hasProperty("embed_joml") && embed_joml == "true")
relocate "org.joml", "${librariesLocation}.joml"
// NightConfig
relocate "com.electronwill.nightconfig", "${librariesLocation}.electronwill.nightconfig"
mergeServiceFiles()
}
afterEvaluate {
tasks.named("remapJar").configure {
dependsOn(shadowJar)
inputFile.set(shadowJar.archiveFile)
}
// Make run tasks use the shadow jar so relocated deps work in dev.
// Filter out jars bundled in the shadow jar, but keep jars that the loader also
// needs (e.g. NightConfig — DH relocates it, but NeoForge needs the original).
def shadowedPaths = configurations.shadowMe.resolve().collect { it.path }.toSet()
def loaderPaths = configurations.minecraftLibraries.resolve().collect { it.path }.toSet()
tasks.withType(JavaExec).configureEach { runTask ->
dependsOn(shadowJar)
classpath = files(shadowJar.archiveFile) + classpath.filter { file ->
!file.path.contains(project.buildDir.path) &&
!file.path.contains("core${File.separator}build") &&
!file.path.contains("api${File.separator}build") &&
!file.path.contains("common${File.separator}build") &&
!(shadowedPaths.contains(file.path) && !loaderPaths.contains(file.path))
}
// Shared run directory so all loaders use the same worlds
def isClient = runTask.name.toLowerCase().contains("client")
runTask.workingDir = rootProject.file("run/${isClient ? 'client' : 'server'}")
// JVM args
runTask.jvmArgs(
"-Dio.netty.leakDetection.level=advanced",
//"-XX:+UseZGC",
//"-XX:+ZGenerational",
)
if (isClient) {
runTask.jvmArgs(
"-Dminecraft.api.auth.host=https://nope.invalid",
"-Dminecraft.api.account.host=https://nope.invalid",
"-Dminecraft.api.session.host=https://nope.invalid",
"-Dminecraft.api.services.host=https://nope.invalid",
)
runTask.args("--username", "Dev", "--renderDebugLabels", "--tracy")
}
}
}
}
// ==================== Process Resources (loaders only) ====================
if (isNotCommonProject) {
processResources {
def resourceTargets = [
"build_info.json",
"fabric.mod.json",
"quilt.mod.json",
"META-INF/mods.toml",
"META-INF/neoforge.mods.toml",
]
def compatible_forgemc_versions = "${rootProject.compatible_minecraft_versions}".replaceAll("\"", "").replaceAll("]", ",)")
// Quilt contributors
def quilt_contributors = []
def mod_author_list = rootProject.mod_authors.replaceAll("\"", "").replace("[", "").replace("]", "").split(",")
for (dev in mod_author_list) {
quilt_contributors.push("\"${dev.strip()}\": \"Developer\"")
}
quilt_contributors.reverse()
try {
if (rootProject.infoGitCommit == "null")
rootProject.ext.infoGitCommit = 'git rev-parse --verify HEAD'.execute().text.trim()
if (rootProject.infoGitBranch == "null")
rootProject.ext.infoGitBranch = 'git symbolic-ref --short HEAD'.execute().text.trim()
} catch (Exception e) {
rootProject.ext.infoGitCommit = "Git not found"
rootProject.ext.infoGitBranch = "Git not found"
}
def replaceProperties = [
version : rootProject.mod_version,
mod_name : rootProject.mod_readable_name,
group : rootProject.maven_group,
authors : rootProject.mod_authors,
description : rootProject.mod_description,
homepage : rootProject.mod_homepage,
source : rootProject.mod_source,
issues : rootProject.mod_issues,
discord : rootProject.mod_discord,
minecraft_version : rootProject.minecraft_version,
compatible_minecraft_versions: rootProject.compatible_minecraft_versions,
compatible_forgemc_versions : compatible_forgemc_versions,
java_version : rootProject.java_version,
quilt_contributors : "{" + quilt_contributors.join(", ") + "}",
info_git_commit : rootProject.infoGitBranch,
info_git_branch : rootProject.infoGitCommit,
info_build_source : rootProject.infoBuildSource,
fabric_incompatibility_list : rootProject.fabric_incompatibility_list,
fabric_recommend_list : rootProject.fabric_recommend_list,
neoforge_version_range : rootProject.neoforge_version_range,
]
inputs.properties replaceProperties
replaceProperties.put "project", project
filesMatching(resourceTargets) {
expand replaceProperties
}
// Remove unused access wideners
exclude { file ->
if (file.name.contains(".distanthorizons.accesswidener") && file.name != "${rootProject.accessWidenerVersion}.distanthorizons.accesswidener") {
return true
}
return false
}
}
// ==================== Resource Copy Tasks ====================
task copyCommonLoaderResources(type: Copy) {
from project(":common").file("src/main/resources/${rootProject.accessWidenerVersion}.distanthorizons.accesswidener")
into(file(project.file("build/resources/main")))
rename "${rootProject.accessWidenerVersion}.distanthorizons.accesswidener", "distanthorizons.accesswidener"
}
task copyCoreResources(type: Copy) {
from fileTree(project(":core").file("src/main/resources"))
into project.file("build/resources/main")
}
// ==================== JVMDowngrader ====================
jvmdg.downgradeTo = JavaVersion.toVersion(rootProject.java_version)
downgradeJar.archiveClassifier.set(null)
shadeDowngradedApi.archiveClassifier.set(null)
}
+56
View File
@@ -0,0 +1,56 @@
plugins {
id 'java'
}
// Transfer version properties from settings.gradle to project
project.gradle.ext.getProperties().each { prop ->
rootProject.ext.set(prop.key, prop.value)
}
// Version string for archives
rootProject.ext.versionStr = rootProject.mod_version + "-" + rootProject.minecraft_version
rootProject.allprojects {
version = (it == rootProject ? "" : it.name + "-") + rootProject.versionStr
group = rootProject.maven_group
// Custom javadoc tags for all subprojects
plugins.withType(JavaPlugin) {
javadoc {
options.tags(
'todo:X"',
'apiNote:a:API Note:',
'implSpec:a:Implementation Requirements:',
'implNote:a:Implementation Note:'
)
}
}
}
// Create build.properties with preprocessor definitions
def writePreprocessorDefinitions() {
StringBuilder sb = new StringBuilder()
sb.append("# DON'T TOUCH THIS FILE, This is handled by the build script\n")
gradle.ext.mcVers.eachWithIndex { ver, idx ->
sb.append("MC_${ver.replace('.', '_')}=${idx}\n")
if (gradle.ext.mcIndex == idx)
sb.append("MC_VER=${idx}\n")
}
if (rootProject.mod_version.toLowerCase().contains("dev")) {
sb.append("DEV_BUILD=\n")
}
new File(rootDir, "build.properties").text = sb.toString()
}
writePreprocessorDefinitions()
// Wire JVMDowngrader to process remapped jars
gradle.projectsEvaluated {
rootProject.subprojects.each {
if (it.tasks.findByName('remapJar') == null) return
it.tasks.downgradeJar.inputFile = it.tasks.remapJar.archiveFile
it.tasks.jar.finalizedBy(it.tasks.remapJar)
it.tasks.remapJar.finalizedBy(it.tasks.shadeDowngradedApi)
}
}
@@ -0,0 +1,13 @@
plugins {
id 'dh-loader'
}
unimined.minecraft {
fabric {
loader gradle.ext.fabric_loader_version
accessWidener project(":common").file("src/main/resources/${gradle.ext.accessWidenerVersion}.distanthorizons.accesswidener")
}
}
runClient.javaLauncher = null
runServer.javaLauncher = null
@@ -0,0 +1,17 @@
plugins {
id 'dh-loader'
}
def awFile = project(":common").file("src/main/resources/${gradle.ext.accessWidenerVersion}.distanthorizons.accesswidener")
unimined.minecraft {
forge {
loader gradle.ext.forge_version
useToolchains = false
mixinConfig("DistantHorizons.forge.mixins.json")
accessTransformer aw2at(awFile)
}
}
runClient.javaLauncher = null
runServer.javaLauncher = null
@@ -0,0 +1,16 @@
plugins {
id 'dh-loader'
}
def awFile = project(":common").file("src/main/resources/${gradle.ext.accessWidenerVersion}.distanthorizons.accesswidener")
unimined.minecraft {
neoForged {
loader gradle.ext.neoforge_version
useToolchains = false
accessTransformer aw2at(awFile)
}
}
runClient.javaLauncher = null
runServer.javaLauncher = null
+1 -39
View File
@@ -1,41 +1,3 @@
// temporary fix for broken spongepowered version
buildscript {
configurations.configureEach {
resolutionStrategy {
force 'org.spongepowered:vanillagradle:0.2.1-20240507.024226-82'
// newer versions can be found by going to the link:
// https://repo.spongepowered.org/#browse/browse:maven-public:org%2Fspongepowered%2Fvanillagradle%2F0.2.1-SNAPSHOT
}
}
}
plugins {
id "org.spongepowered.gradle.vanilla" version "0.2.1-SNAPSHOT"
id 'dh-loader'
}
minecraft {
accessWideners(project(":common").file("src/main/resources/${accessWidenerVersion}.distanthorizons.accesswidener"))
version(rootProject.minecraft_version)
}
dependencies {
// So mixins can be written in common
compileOnly group:'org.spongepowered', name:'mixin', version:'0.8.5'
}
publishing {
publications {
mavenCommon(MavenPublication) {
artifactId = rootProject.mod_readable_name
from components.java
}
}
// See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing.
repositories {
// Add repositories to publish to here.
}
}
@@ -19,7 +19,12 @@ import com.seibel.distanthorizons.core.enums.MinecraftTextFormat;
import com.seibel.distanthorizons.core.jar.ModJarInfo;
import com.seibel.distanthorizons.core.jar.updater.SelfUpdater;
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import com.seibel.distanthorizons.core.render.renderer.AbstractDebugWireframeRenderer;
import com.seibel.distanthorizons.core.render.renderer.StubDebugWireframeRenderer;
import com.seibel.distanthorizons.core.util.NativeDialogUtil;
import com.seibel.distanthorizons.core.util.ThreadUtil;
import com.seibel.distanthorizons.core.util.threading.DhThreadFactory;
import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil;
import com.seibel.distanthorizons.core.wrapperInterfaces.IVersionConstants;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IIrisAccessor;
@@ -32,6 +37,7 @@ import net.minecraft.server.MinecraftServer;
import net.minecraft.server.dedicated.DedicatedServer;
import com.seibel.distanthorizons.core.logging.DhLogger;
import java.util.concurrent.CompletableFuture;
import java.util.function.Consumer;
import java.util.function.Supplier;
@@ -134,6 +140,7 @@ public abstract class AbstractModInitializer
this.initConfig();
this.postInit();
this.postServerInit();
this.commandInitializer.onServerReady();
this.checkForUpdates();
@@ -222,7 +229,35 @@ public abstract class AbstractModInitializer
ApiEventInjector.INSTANCE.fireAllEvents(DhApiAfterDhInitEvent.class, null);
}
private void postClientInit() { DependencySetup.setRenderingApiBindings(); }
private void postClientInit()
{
CompletableFuture<Void> future = new CompletableFuture<>();
// This method may be called from either the render thread,
// or some other random setup thread depending on the mod loader.
// In order to avoid confusion/inconsistent problems, we're always going
// to run setup on our own thread.
Thread dhSetupThread = new Thread(() ->
{
try
{
DependencySetup.setRenderingApiBindings();
}
catch (Exception e)
{
future.completeExceptionally(e);
}
finally
{
future.complete(null);
}
});
dhSetupThread.setName(ThreadUtil.THREAD_NAME_PREFIX + "PostClientInit Thread");
dhSetupThread.start();
future.join();
}
private void postServerInit() { SingletonInjector.INSTANCE.bind(AbstractDebugWireframeRenderer.class, new StubDebugWireframeRenderer()); }
//endregion
@@ -343,7 +378,7 @@ public abstract class AbstractModInitializer
// Iris only supports nataive OpenGL
if (renderApi != EDhApiRenderApi.OPEN_GL)
{
String irisUnsupportedMessage = "Iris doesn't support DH when using the ["+EDhApiRenderApi.BLAZE_3D+"] rendering API, please change it to ["+EDhApiRenderApi.OPEN_GL+"] in DH's config file.";
String irisUnsupportedMessage = "Iris doesn't support DH when using the ["+EDhApiRenderApi.BLAZE_3D+"] rendering API, this will need to be fixed on Iris' end. As a temporary fix please change the rendering API to ["+EDhApiRenderApi.OPEN_GL+"] in DH's config file.";
LOGGER.fatal(irisUnsupportedMessage);
NativeDialogUtil.showDialog(ModInfo.READABLE_NAME, irisUnsupportedMessage, "ok", "error");
@@ -4,14 +4,17 @@ import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.seibel.distanthorizons.common.wrappers.world.ServerLevelWrapper;
import com.seibel.distanthorizons.core.api.internal.SharedApi;
import com.seibel.distanthorizons.core.generation.PregenManager;
import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos2D;
import com.seibel.distanthorizons.core.world.DhServerWorld;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.arguments.DimensionArgument;
import net.minecraft.commands.arguments.coordinates.ColumnPosArgument;
import net.minecraft.server.level.ColumnPos;
import net.minecraft.server.level.ServerLevel;
import java.util.Objects;
import java.util.concurrent.CancellationException;
import java.util.concurrent.CompletableFuture;
@@ -22,7 +25,11 @@ import static net.minecraft.commands.Commands.literal;
public class PregenCommand extends AbstractCommand
{
private final PregenManager pregenManager = new PregenManager();
private PregenManager getPregenManager()
{
DhServerWorld world = (DhServerWorld) Objects.requireNonNull(SharedApi.getAbstractDhWorld());
return world.getPregenManager();
}
@Override
public LiteralArgumentBuilder<CommandSourceStack> buildCommand()
@@ -48,7 +55,7 @@ public class PregenCommand extends AbstractCommand
private int pregenStatus(CommandContext<CommandSourceStack> c)
{
String statusString = this.pregenManager.getStatusString();
String statusString = this.getPregenManager().getStatusString();
//noinspection ReplaceNullCheck
if (statusString != null)
{
@@ -68,7 +75,7 @@ public class PregenCommand extends AbstractCommand
ColumnPos origin = ColumnPosArgument.getColumnPos(c, "origin");
int chunkRadius = getInteger(c, "chunkRadius");
CompletableFuture<Void> future = this.pregenManager.startPregen(
CompletableFuture<Void> future = this.getPregenManager().startPregen(
ServerLevelWrapper.getWrapper(level),
new DhBlockPos2D(#if MC_VER >= MC_1_19_2 origin.x(), origin.z() #else origin.x, origin.z #endif),
chunkRadius
@@ -94,7 +101,7 @@ public class PregenCommand extends AbstractCommand
private int pregenStop(CommandContext<CommandSourceStack> c)
{
CompletableFuture<Void> runningPregen = this.pregenManager.getRunningPregen();
CompletableFuture<Void> runningPregen = this.getPregenManager().getRunningPregen();
if (runningPregen == null)
{
return this.sendFailureResponse(c, "Pregen is not running");
@@ -4,9 +4,11 @@ import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
import com.seibel.distanthorizons.common.wrappers.world.ServerLevelWrapper;
import com.seibel.distanthorizons.core.api.internal.ServerApi;
import com.seibel.distanthorizons.core.api.internal.SharedApi;
import com.seibel.distanthorizons.core.pos.DhChunkPos;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IServerLevelWrapper;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.chunk.ChunkAccess;
import net.minecraft.world.level.chunk.ProtoChunk;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
public class MixinChunkMapCommon
@@ -16,8 +18,18 @@ public class MixinChunkMapCommon
{
IServerLevelWrapper levelWrapper = ServerLevelWrapper.getWrapper(level);
int chunkPosX;
int chunkPosZ;
#if MC_VER <= MC_1_21_11
chunkPosX = chunk.getPos().x;
chunkPosZ = chunk.getPos().z;
#else
chunkPosX = chunk.getPos().x();
chunkPosZ = chunk.getPos().z();
#endif
// is this position already being updated?
if (SharedApi.isChunkAtChunkPosAlreadyUpdating(levelWrapper, chunk.getPos().x, chunk.getPos().z))
if (SharedApi.isChunkAtChunkPosAlreadyUpdating(levelWrapper, chunkPosX, chunkPosZ))
{
return;
}
@@ -38,13 +50,13 @@ public class MixinChunkMapCommon
// MC has a tendency to try saving incomplete or corrupted chunks (which show up as empty or black chunks)
// this logic should prevent that from happening
#if MC_VER == MC_1_16_5 || MC_VER == MC_1_17_1
#if MC_VER <= MC_1_17_1
if (chunk.isUnsaved() || chunk.getUpgradeData() != null || !chunk.isLightCorrect())
{
return;
}
#else
if (chunk.isUnsaved() || chunk.isUpgrading() || !chunk.isLightCorrect())
if (chunk.isUnsaved() || chunk.isUpgrading() || !chunk.isLightCorrect() || chunk instanceof ProtoChunk)
{
return;
}
@@ -55,7 +67,7 @@ public class MixinChunkMapCommon
// biome validation //
// some chunks may be missing their biomes, which cause issues when attempting to save them
#if MC_VER == MC_1_16_5 || MC_VER == MC_1_17_1
#if MC_VER <= MC_1_17_1
if (chunk.getBiomes() == null)
{
return;
@@ -29,7 +29,6 @@ import com.mojang.blaze3d.buffers.GpuBufferSlice;
import com.mojang.blaze3d.buffers.Std140Builder;
import com.mojang.blaze3d.buffers.Std140SizeCalculator;
import com.mojang.blaze3d.pipeline.RenderPipeline;
import com.mojang.blaze3d.platform.DepthTestFunction;
import com.mojang.blaze3d.platform.PolygonMode;
import com.mojang.blaze3d.shaders.UniformType;
import com.mojang.blaze3d.systems.CommandEncoder;
@@ -39,6 +38,7 @@ import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.VertexFormat;
import com.seibel.distanthorizons.common.render.blaze.util.BlazeUniformUtil;
import com.seibel.distanthorizons.common.render.blaze.util.BlazeDhVertexFormatUtil;
import com.seibel.distanthorizons.common.render.blaze.wrappers.RenderPipelineBuilderWrapper;
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
import com.seibel.distanthorizons.core.logging.DhLogger;
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
@@ -139,26 +139,27 @@ public class BlazeDebugWireframeRenderer extends AbstractDebugWireframeRenderer
}
private void createPipelines()
{
VertexFormat vertexFormat = VertexFormat.builder()
.add("vPosition", BlazeDhVertexFormatUtil.FLOAT_XYZ_POS)
.build();
RenderPipeline.Builder pipelineBuilder = RenderPipeline.builder();
RenderPipelineBuilderWrapper pipelineBuilder = new RenderPipelineBuilderWrapper();
{
pipelineBuilder.withCull(false);
pipelineBuilder.withDepthWrite(false);
pipelineBuilder.withDepthTestFunction(DepthTestFunction.LESS_DEPTH_TEST);
pipelineBuilder.withFaceCulling(false);
pipelineBuilder.withDepthWrite(true);
pipelineBuilder.withDepthTest(RenderPipelineBuilderWrapper.EDhDepthTest.LESS);
pipelineBuilder.withColorWrite(true);
pipelineBuilder.withoutBlend();
pipelineBuilder.withPolygonMode(PolygonMode.WIREFRAME);
pipelineBuilder.withLocation(Identifier.parse("distanthorizons:debug_wireframe_renderer"));
pipelineBuilder.withPolygonMode(RenderPipelineBuilderWrapper.EDhPolygonMode.WIREFRAME);
pipelineBuilder.withName("debug_wireframe_renderer");
pipelineBuilder.withVertexShader(Identifier.fromNamespaceAndPath("distanthorizons", "debug/blaze/vert"));
pipelineBuilder.withFragmentShader(Identifier.fromNamespaceAndPath("distanthorizons", "debug/blaze/frag"));
pipelineBuilder.withVertexShader("debug/blaze/vert");
pipelineBuilder.withFragmentShader("debug/blaze/frag");
pipelineBuilder.withUniform("uniformBlock", UniformType.UNIFORM_BUFFER);
pipelineBuilder.withUniformBuffer("uniformBlock");
pipelineBuilder.withVertexFormat(vertexFormat, VertexFormat.Mode.DEBUG_LINES);
VertexFormat vertexFormat = VertexFormat.builder()
.add("vPosition", BlazeDhVertexFormatUtil.FLOAT_XYZ_POS)
.build();
pipelineBuilder.withVertexFormat(vertexFormat);
pipelineBuilder.withVertexMode(RenderPipelineBuilderWrapper.EDhVertexMode.LINES);
}
this.pipeline = pipelineBuilder.build();
@@ -225,15 +226,15 @@ public class BlazeDebugWireframeRenderer extends AbstractDebugWireframeRenderer
//region
@Override
public void render(Box box)
public void renderBox(Box box)
{
this.init();
if (BlazeDhMetaRenderer.INSTANCE.dhColorTextureWrapper.isEmpty()
|| BlazeDhMetaRenderer.INSTANCE.dhDepthTextureWrapper.isEmpty())
{
return;
}
//if (BlazeDhMetaRenderer.INSTANCE.dhColorTextureWrapper.isEmpty()
// || BlazeDhMetaRenderer.INSTANCE.dhDepthTextureWrapper.isEmpty())
//{
// return;
//}
// shouldn't happen, but just in case
if (box == null)
@@ -298,27 +299,27 @@ public class BlazeDebugWireframeRenderer extends AbstractDebugWireframeRenderer
// render //
try (RenderPass renderPass = commandEncoder.createRenderPass(
this::getRenderPassName,
BlazeDhMetaRenderer.INSTANCE.dhColorTextureWrapper.textureView,
/*optionalClearColorAsInt*/ OptionalInt.empty(),
BlazeDhMetaRenderer.INSTANCE.dhDepthTextureWrapper.textureView,
/*optionalDepthValueAsDouble*/ OptionalDouble.empty()))
{
// Bind instance data //
renderPass.setUniform("uniformBlock", this.uniformBuffer);
renderPass.setPipeline(this.pipeline);
renderPass.setIndexBuffer(this.boxIndexBuffer, VertexFormat.IndexType.INT);
renderPass.setVertexBuffer(0, this.boxVertexBuffer);
renderPass.drawIndexed(
/*indexStart*/ 0,
/*firstIndex*/0,
/*indexCount*/BOX_OUTLINE_INDICES.length,
/*instanceCount*/1);
}
//try (RenderPass renderPass = commandEncoder.createRenderPass(
// this::getRenderPassName,
// BlazeDhMetaRenderer.INSTANCE.dhColorTextureWrapper.textureView,
// /*optionalClearColorAsInt*/ OptionalInt.empty(),
// BlazeDhMetaRenderer.INSTANCE.dhDepthTextureWrapper.textureView,
// /*optionalDepthValueAsDouble*/ OptionalDouble.empty()))
//{
// // Bind instance data //
// renderPass.setUniform("uniformBlock", this.uniformBuffer);
//
// renderPass.setPipeline(this.pipeline);
// renderPass.setIndexBuffer(this.boxIndexBuffer, VertexFormat.IndexType.INT);
//
// renderPass.setVertexBuffer(0, this.boxVertexBuffer);
//
// renderPass.drawIndexed(
// /*indexStart*/ 0,
// /*firstIndex*/0,
// /*indexCount*/BOX_OUTLINE_INDICES.length,
// /*instanceCount*/1);
//}
}
private String getRenderPassName() { return "distantHorizons:McDebugRenderer"; }
@@ -30,7 +30,6 @@ import com.mojang.blaze3d.buffers.Std140Builder;
import com.mojang.blaze3d.buffers.Std140SizeCalculator;
import com.mojang.blaze3d.pipeline.BlendFunction;
import com.mojang.blaze3d.pipeline.RenderPipeline;
import com.mojang.blaze3d.platform.DepthTestFunction;
import com.mojang.blaze3d.platform.PolygonMode;
import com.mojang.blaze3d.shaders.UniformType;
import com.mojang.blaze3d.systems.CommandEncoder;
@@ -49,6 +48,7 @@ import com.seibel.distanthorizons.api.objects.render.DhApiRenderableBox;
import com.seibel.distanthorizons.api.objects.render.DhApiRenderableBoxGroupShading;
import com.seibel.distanthorizons.common.render.blaze.objects.BlazeGenericObjectVertexContainer;
import com.seibel.distanthorizons.common.render.blaze.util.BlazeDhVertexFormatUtil;
import com.seibel.distanthorizons.common.render.blaze.wrappers.RenderPipelineBuilderWrapper;
import com.seibel.distanthorizons.common.render.blaze.wrappers.texture.BlazeTextureViewWrapper;
import com.seibel.distanthorizons.common.render.blaze.util.BlazeUniformUtil;
import com.seibel.distanthorizons.common.wrappers.misc.LightMapWrapper;
@@ -108,10 +108,7 @@ public class BlazeDhGenericObjectRenderer implements IDhGenericRenderer
// rendering setup
private boolean init = false;
private VertexFormat vertexFormat;
private RenderPipeline opaquePipeline;
private RenderPipeline transparentPipeline;
private RenderPipeline pipeline;
private GpuBuffer vertUniformBuffer;
@@ -132,12 +129,6 @@ public class BlazeDhGenericObjectRenderer implements IDhGenericRenderer
}
this.init = true;
this.vertexFormat = VertexFormat.builder()
.add("vPosition", BlazeDhVertexFormatUtil.FLOAT_XYZ_POS)
.add("aColor", BlazeDhVertexFormatUtil.RGBA_UBYTE_COLOR)
.add("aMaterial", BlazeDhVertexFormatUtil.IRIS_MATERIAL)
.build();
this.createPipelines();
if (RENDER_DEBUG_OBJECTS)
@@ -147,37 +138,36 @@ public class BlazeDhGenericObjectRenderer implements IDhGenericRenderer
}
private void createPipelines()
{
RenderPipeline.Builder pipelineBuilder = RenderPipeline.builder();
RenderPipelineBuilderWrapper pipelineBuilder = new RenderPipelineBuilderWrapper();
{
pipelineBuilder.withCull(true);
pipelineBuilder.withFaceCulling(true);
pipelineBuilder.withDepthWrite(true);
pipelineBuilder.withDepthTestFunction(DepthTestFunction.LESS_DEPTH_TEST);
pipelineBuilder.withDepthTest(RenderPipelineBuilderWrapper.EDhDepthTest.LESS);
pipelineBuilder.withBlend(BlendFunction.TRANSLUCENT); // TRANSLUCENT = new BlendFunction(SourceFactor.SRC_ALPHA, DestFactor.ONE_MINUS_SRC_ALPHA, SourceFactor.ONE, DestFactor.ONE_MINUS_SRC_ALPHA);
pipelineBuilder.withColorWrite(true);
pipelineBuilder.withPolygonMode(PolygonMode.FILL);
pipelineBuilder.withLocation(Identifier.parse("distanthorizons:generic"));
pipelineBuilder.withPolygonMode(RenderPipelineBuilderWrapper.EDhPolygonMode.FILL);
pipelineBuilder.withName("generic_objects");
pipelineBuilder.withVertexShader(Identifier.fromNamespaceAndPath("distanthorizons", "generic/blaze/vert"));
pipelineBuilder.withFragmentShader(Identifier.fromNamespaceAndPath("distanthorizons", "generic/blaze/frag"));
pipelineBuilder.withVertexShader("generic/blaze/vert");
pipelineBuilder.withFragmentShader("generic/blaze/frag");
pipelineBuilder.withSampler("uLightMap");
pipelineBuilder.withUniform("vertUniformBlock", UniformType.UNIFORM_BUFFER);
pipelineBuilder.withUniformBuffer("vertUniformBlock");
pipelineBuilder.withVertexFormat(this.vertexFormat, VertexFormat.Mode.TRIANGLES);
VertexFormat vertexFormat = VertexFormat.builder()
.add("vPosition", BlazeDhVertexFormatUtil.FLOAT_XYZ_POS)
.add("aColor", BlazeDhVertexFormatUtil.RGBA_UBYTE_COLOR)
.add("aMaterial", BlazeDhVertexFormatUtil.IRIS_MATERIAL)
.add("paddingOne", BlazeDhVertexFormatUtil.BYTE_PAD)
.add("paddingTwo", BlazeDhVertexFormatUtil.BYTE_PAD)
.add("paddingThree", BlazeDhVertexFormatUtil.BYTE_PAD)
.build();
pipelineBuilder.withVertexFormat(vertexFormat);
pipelineBuilder.withVertexMode(RenderPipelineBuilderWrapper.EDhVertexMode.TRIANGLES);
}
// opaque
{
pipelineBuilder.withoutBlend();
this.opaquePipeline = pipelineBuilder.build();
}
// transparent
{
pipelineBuilder.withBlend(BlendFunction.TRANSLUCENT);
this.transparentPipeline = pipelineBuilder.build();
}
this.pipeline = pipelineBuilder.build();
}
private void addGenericDebugObjects()
{
@@ -303,7 +293,11 @@ public class BlazeDhGenericObjectRenderer implements IDhGenericRenderer
throw new IllegalArgumentException("Box group must be of type ["+ RenderableBoxGroup.class.getSimpleName()+"], type received: ["+(iBoxGroup != null ? iBoxGroup.getClass() : "NULL")+"].");
}
RenderableBoxGroup boxGroup = (RenderableBoxGroup) iBoxGroup;
if (boxGroup.size() != 0)
{
// trigger a box change to make sure the initial data is uploaded
boxGroup.triggerBoxChange();
}
long id = boxGroup.getId();
if (this.boxGroupById.containsKey(id))
@@ -500,15 +494,7 @@ public class BlazeDhGenericObjectRenderer implements IDhGenericRenderer
profiler.push(boxGroup.getResourceLocationNamespace());
profiler.push(boxGroup.getResourceLocationPath());
try (RenderPass renderPass = COMMAND_ENCODER.createRenderPass(
this::getRenderPassName,
BlazeDhMetaRenderer.INSTANCE.dhColorTextureWrapper.textureView,
/*optionalClearColorAsInt*/ OptionalInt.empty(),
BlazeDhMetaRenderer.INSTANCE.dhDepthTextureWrapper.textureView,
/*optionalDepthValueAsDouble*/ OptionalDouble.empty()))
{
this.renderBoxGroupInstanced(renderPass, renderEventParam, boxGroup, camPos, profiler);
}
this.renderBoxGroupInstanced(renderEventParam, boxGroup, profiler);
profiler.pop(); // resource path
profiler.pop(); // resource namespace
@@ -545,46 +531,54 @@ public class BlazeDhGenericObjectRenderer implements IDhGenericRenderer
//region
private void renderBoxGroupInstanced(
RenderPass renderPass, RenderParams renderEventParam,
RenderableBoxGroup boxGroup, Vec3d camPos,
RenderParams renderEventParam,
RenderableBoxGroup boxGroup,
IProfilerWrapper profiler)
{
// update instance data //
profiler.push("vertex setup");
BlazeGenericObjectVertexContainer container = (BlazeGenericObjectVertexContainer) boxGroup.vertexBufferContainer;
LightMapWrapper lightMapWrapper = (LightMapWrapper) renderEventParam.lightmap;
BlazeTextureViewWrapper lightmapTextureViewWrapper = lightMapWrapper.getTextureViewWrapper();
renderPass.bindTexture("uLightMap", lightmapTextureViewWrapper.textureView, lightmapTextureViewWrapper.textureSampler);
// Bind instance data //
profiler.popPush("binding");
renderPass.setUniform("vertUniformBlock", this.vertUniformBuffer);
// set pipeline
renderPass.setPipeline(this.opaquePipeline); // TODO
renderPass.setIndexBuffer(container.indexGpuBuffer, VertexFormat.IndexType.INT);
renderPass.setVertexBuffer(0, container.vboGpuBuffer);
// Draw instanced
profiler.popPush("render");
if (container.uploadedBoxCount > 0)
try (RenderPass renderPass = COMMAND_ENCODER.createRenderPass(
this::getRenderPassName,
BlazeDhMetaRenderer.INSTANCE.dhColorTextureWrapper.textureView,
/*optionalClearColorAsInt*/ OptionalInt.empty(),
BlazeDhMetaRenderer.INSTANCE.dhDepthTextureWrapper.textureView,
/*optionalDepthValueAsDouble*/ OptionalDouble.empty()))
{
renderPass.drawIndexed(
/*indexStart*/ 0,
/*firstIndex*/0,
/*indexCount*/container.uploadedBoxCount * 24, // TODO?
/*instanceCount*/1);
// update instance data //
profiler.push("vertex setup");
BlazeGenericObjectVertexContainer container = (BlazeGenericObjectVertexContainer) boxGroup.vertexBufferContainer;
LightMapWrapper lightMapWrapper = (LightMapWrapper) renderEventParam.lightmap;
BlazeTextureViewWrapper lightmapTextureViewWrapper = lightMapWrapper.getTextureViewWrapper();
renderPass.bindTexture("uLightMap", lightmapTextureViewWrapper.textureView, lightmapTextureViewWrapper.textureSampler);
// Bind instance data //
profiler.popPush("binding");
renderPass.setUniform("vertUniformBlock", this.vertUniformBuffer);
// set pipeline
renderPass.setPipeline(this.pipeline);
renderPass.setIndexBuffer(container.indexGpuBuffer, VertexFormat.IndexType.INT);
renderPass.setVertexBuffer(0, container.vboGpuBuffer);
// Draw instanced
profiler.popPush("render");
if (container.uploadedBoxCount > 0)
{
renderPass.drawIndexed(
/*indexStart*/ 0,
/*firstIndex*/0,
/*indexCount*/container.uploadedBoxCount * 36, // 36 = 6 faces * 6 verticies per face
/*instanceCount*/1);
}
}
profiler.pop();
}
@@ -8,16 +8,21 @@ public class BlazeDhMetaRenderer {}
import com.mojang.blaze3d.textures.GpuTexture;
import com.seibel.distanthorizons.common.render.blaze.apply.BlazeDhApplyRenderer;
import com.seibel.distanthorizons.common.render.blaze.wrappers.texture.BlazeTextureWrapper;
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
import com.seibel.distanthorizons.core.render.RenderParams;
import com.seibel.distanthorizons.core.util.ColorUtil;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass.IDhMetaRenderer;
import net.minecraft.client.Minecraft;
import java.awt.*;
public class BlazeDhMetaRenderer implements IDhMetaRenderer
{
public static final BlazeDhMetaRenderer INSTANCE = new BlazeDhMetaRenderer();
private static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class);
private BlazeDhApplyRenderer applyRenderer;
@@ -79,12 +84,10 @@ public class BlazeDhMetaRenderer implements IDhMetaRenderer
@Override
public void clearDhDepthAndColorTextures(RenderParams renderParams)
{
// TODO use for clear color
//IMinecraftRenderWrapper r;
//r.getSkyColor()
this.dhDepthTextureWrapper.clearDepth(1.0f);
this.dhColorTextureWrapper.clearColor(ColorUtil.argbToInt(1, 1, 1, 1));
Color color = MC_RENDER.getSkyColor();
this.dhColorTextureWrapper.clearColor(ColorUtil.toColorInt(color));
}
//endregion
@@ -11,7 +11,6 @@ import com.mojang.blaze3d.buffers.Std140Builder;
import com.mojang.blaze3d.buffers.Std140SizeCalculator;
import com.mojang.blaze3d.pipeline.BlendFunction;
import com.mojang.blaze3d.pipeline.RenderPipeline;
import com.mojang.blaze3d.platform.DepthTestFunction;
import com.mojang.blaze3d.platform.PolygonMode;
import com.mojang.blaze3d.shaders.UniformType;
import com.mojang.blaze3d.systems.CommandEncoder;
@@ -22,18 +21,16 @@ import com.mojang.blaze3d.vertex.VertexFormat;
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiBeforeBufferRenderEvent;
import com.seibel.distanthorizons.common.render.blaze.util.BlazeDhVertexFormatUtil;
import com.seibel.distanthorizons.common.render.blaze.util.BlazeUniformUtil;
import com.seibel.distanthorizons.common.render.blaze.wrappers.RenderPipelineBuilderWrapper;
import com.seibel.distanthorizons.common.render.blaze.wrappers.texture.BlazeTextureViewWrapper;
import com.seibel.distanthorizons.common.render.blaze.wrappers.uniform.BlazeLodUniformBufferWrapper;
import com.seibel.distanthorizons.common.render.blaze.wrappers.buffer.BlazeVertexBufferWrapper;
import com.seibel.distanthorizons.common.wrappers.misc.LightMapWrapper;
import com.seibel.distanthorizons.core.config.Config;
import com.seibel.distanthorizons.core.dataObjects.render.bufferBuilding.LodBufferContainer;
import com.seibel.distanthorizons.core.dataObjects.render.bufferBuilding.LodQuadBuilder;
import com.seibel.distanthorizons.core.logging.DhLogger;
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import com.seibel.distanthorizons.core.pos.DhSectionPos;
import com.seibel.distanthorizons.common.render.openGl.glObject.enums.GLEnums;
import com.seibel.distanthorizons.common.render.openGl.glObject.buffer.GlQuadElementBuffer;
import com.seibel.distanthorizons.core.render.RenderParams;
import com.seibel.distanthorizons.core.util.RenderUtil;
import com.seibel.distanthorizons.core.util.math.Mat4f;
@@ -45,7 +42,6 @@ import com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass.IDhTe
import com.seibel.distanthorizons.core.wrapperInterfaces.render.objects.IVertexBufferWrapper;
import com.seibel.distanthorizons.coreapi.DependencyInjection.ApiEventInjector;
import net.minecraft.resources.Identifier;
import org.lwjgl.opengl.GL32;
import org.lwjgl.system.MemoryUtil;
import java.nio.ByteBuffer;
@@ -68,8 +64,6 @@ public class BlazeDhTerrainRenderer implements IDhTerrainRenderer
private RenderPipeline transparentPipeline;
private boolean init = false;
private GpuBuffer indexBuffer;
private GpuBuffer fragUniformBuffer;
private GpuBuffer vertSharedUniformBuffer;
@@ -88,38 +82,39 @@ public class BlazeDhTerrainRenderer implements IDhTerrainRenderer
{
return;
}
this.init = true; // todo only set when succeeded (in case of exception)
VertexFormat vertexFormat = VertexFormat.builder()
.add("vPosition", BlazeDhVertexFormatUtil.SHORT_XYZ_POS)
.add("meta", BlazeDhVertexFormatUtil.META)
.add("vColor", BlazeDhVertexFormatUtil.RGBA_UBYTE_COLOR)
.add("irisMaterial", BlazeDhVertexFormatUtil.IRIS_MATERIAL)
.add("irisNormal", BlazeDhVertexFormatUtil.IRIS_NORMAL)
.add("paddingTwo", BlazeDhVertexFormatUtil.BYTE_PAD)
.add("paddingThree", BlazeDhVertexFormatUtil.BYTE_PAD) // padding is to make sure the format is a multiple of 4
.build();
RenderPipeline.Builder pipelineBuilder = RenderPipeline.builder();
RenderPipelineBuilderWrapper pipelineBuilder = new RenderPipelineBuilderWrapper();
{
pipelineBuilder.withCull(true);
pipelineBuilder.withFaceCulling(true);
pipelineBuilder.withDepthWrite(true);
pipelineBuilder.withDepthTestFunction(DepthTestFunction.LESS_DEPTH_TEST);
pipelineBuilder.withDepthTest(RenderPipelineBuilderWrapper.EDhDepthTest.LESS);
pipelineBuilder.withColorWrite(true);
pipelineBuilder.withPolygonMode(PolygonMode.FILL);
pipelineBuilder.withLocation(Identifier.parse("distanthorizons:lod_render"));
pipelineBuilder.withVertexShader(Identifier.fromNamespaceAndPath("distanthorizons", "lod/blaze/vert"));
pipelineBuilder.withFragmentShader(Identifier.fromNamespaceAndPath("distanthorizons", "lod/blaze/frag"));
pipelineBuilder.withPolygonMode(RenderPipelineBuilderWrapper.EDhPolygonMode.FILL);
pipelineBuilder.withName("terrain");
pipelineBuilder.withSampler("uLightMap");
pipelineBuilder.withUniform("vertUniqueUniformBlock", UniformType.UNIFORM_BUFFER);
pipelineBuilder.withUniform("vertSharedUniformBlock", UniformType.UNIFORM_BUFFER);
pipelineBuilder.withUniform("fragUniformBlock", UniformType.UNIFORM_BUFFER);
pipelineBuilder.withVertexShader("lod/blaze/vert");
pipelineBuilder.withFragmentShader("lod/blaze/frag");
pipelineBuilder.withVertexFormat(vertexFormat, VertexFormat.Mode.TRIANGLES);
pipelineBuilder.withUniformBuffer("vertUniqueUniformBlock");
pipelineBuilder.withUniformBuffer("vertSharedUniformBlock");
pipelineBuilder.withUniformBuffer("fragUniformBlock");
VertexFormat vertexFormat = VertexFormat.builder()
.add("vPosition", BlazeDhVertexFormatUtil.SHORT_XYZ_POS)
.add("meta", BlazeDhVertexFormatUtil.META)
.add("vColor", BlazeDhVertexFormatUtil.RGBA_UBYTE_COLOR)
.add("irisMaterial", BlazeDhVertexFormatUtil.IRIS_MATERIAL)
.add("irisNormal", BlazeDhVertexFormatUtil.IRIS_NORMAL)
.add("paddingTwo", BlazeDhVertexFormatUtil.BYTE_PAD)
.add("paddingThree", BlazeDhVertexFormatUtil.BYTE_PAD) // padding is to make sure the format is a multiple of 4
.build();
pipelineBuilder.withVertexFormat(vertexFormat);
pipelineBuilder.withVertexMode(RenderPipelineBuilderWrapper.EDhVertexMode.TRIANGLES);
}
// opaque
@@ -130,9 +125,12 @@ public class BlazeDhTerrainRenderer implements IDhTerrainRenderer
// transparent
{
// TRANSLUCENT = new BlendFunction(SourceFactor.SRC_ALPHA, DestFactor.ONE_MINUS_SRC_ALPHA, SourceFactor.ONE, DestFactor.ONE_MINUS_SRC_ALPHA);
pipelineBuilder.withBlend(BlendFunction.TRANSLUCENT);
this.transparentPipeline = pipelineBuilder.build();
}
this.init = true;
}
//endregion
@@ -195,7 +193,7 @@ public class BlazeDhTerrainRenderer implements IDhTerrainRenderer
.putMat4f() // uCombinedMatrix
.get();
ByteBuffer buffer = ByteBuffer.allocateDirect(uniformBufferSize);
ByteBuffer buffer = MemoryUtil.memAlloc(uniformBufferSize);
buffer.order(ByteOrder.nativeOrder());
Std140Builder.intoBuffer(buffer)
.putInt(0) // uIsWhiteWorld
@@ -215,6 +213,8 @@ public class BlazeDhTerrainRenderer implements IDhTerrainRenderer
GpuBufferSlice bufferSlice = new GpuBufferSlice(this.vertSharedUniformBuffer, 0, uniformBufferSize);
COMMAND_ENCODER.writeToBuffer(bufferSlice, buffer);
MemoryUtil.memFree(buffer);
}
profiler.popPush("set frag uniforms");
@@ -241,7 +241,7 @@ public class BlazeDhTerrainRenderer implements IDhTerrainRenderer
// upload data //
ByteBuffer buffer = ByteBuffer.allocateDirect(uniformBufferSize);
ByteBuffer buffer = MemoryUtil.memAlloc(uniformBufferSize);
buffer.order(ByteOrder.nativeOrder());
buffer = Std140Builder.intoBuffer(buffer)
.putFloat(dhNearClipDistance) // uClipDistance
@@ -257,30 +257,7 @@ public class BlazeDhTerrainRenderer implements IDhTerrainRenderer
GpuBufferSlice bufferSlice = new GpuBufferSlice(this.fragUniformBuffer, 0, uniformBufferSize);
COMMAND_ENCODER.writeToBuffer(bufferSlice, buffer);
}
// create index buffer
{
if (this.indexBuffer == null)
{
ByteBuffer buffer = MemoryUtil.memAlloc(LodQuadBuilder.getMaxBufferByteSize() * GLEnums.getTypeSize(GL32.GL_UNSIGNED_INT) * 6);
GlQuadElementBuffer.buildBuffer(LodQuadBuilder.getMaxBufferByteSize(), buffer, GL32.GL_UNSIGNED_INT);
// create buffer if needed
if (this.indexBuffer == null
|| this.indexBuffer.size() < buffer.capacity())
{
int usage = GpuBuffer.USAGE_COPY_DST
| GpuBuffer.USAGE_VERTEX
| GpuBuffer.USAGE_INDEX
| GpuBuffer.USAGE_UNIFORM;
this.indexBuffer = GPU_DEVICE.createBuffer(this::getIndexBufferName, usage, buffer.capacity());
}
GpuBufferSlice bufferSlice = new GpuBufferSlice(this.indexBuffer, /*offset*/ 0, buffer.capacity());
COMMAND_ENCODER.writeToBuffer(bufferSlice, buffer);
}
MemoryUtil.memFree(buffer);
}
@@ -290,25 +267,20 @@ public class BlazeDhTerrainRenderer implements IDhTerrainRenderer
profiler.popPush("setup");
// create a render pass
OptionalInt optionalClearColorAsInt = OptionalInt.empty();
OptionalDouble optionalDepthValueAsDouble = OptionalDouble.empty();
try(RenderPass renderPass = COMMAND_ENCODER.createRenderPass(
this::getRenderPassName,
BlazeDhMetaRenderer.INSTANCE.dhColorTextureWrapper.textureView,
optionalClearColorAsInt,
BlazeDhMetaRenderer.INSTANCE.dhDepthTextureWrapper.textureView, optionalDepthValueAsDouble)
/*optionalClearColorAsInt*/ OptionalInt.empty(),
BlazeDhMetaRenderer.INSTANCE.dhDepthTextureWrapper.textureView,
/*optionalDepthValueAsDouble*/ OptionalDouble.empty())
)
{
// bind MC Lightmap
//renderPass.bindTexture("uLightMap", this.mcLightTextureViewWrapper.textureView, this.mcLightTextureViewWrapper.textureSampler);
LightMapWrapper lightMapWrapper = (LightMapWrapper) renderEventParam.lightmap;
BlazeTextureViewWrapper lightmapTextureViewWrapper = lightMapWrapper.getTextureViewWrapper();
renderPass.bindTexture("uLightMap", lightmapTextureViewWrapper.textureView, lightmapTextureViewWrapper.textureSampler);
// set pipeline
renderPass.setPipeline(opaquePass ? this.opaquePipeline : this.transparentPipeline);
renderPass.setIndexBuffer(this.indexBuffer, VertexFormat.IndexType.INT);
// shared uniforms
renderPass.setUniform("fragUniformBlock", this.fragUniformBuffer);
@@ -345,7 +317,7 @@ public class BlazeDhTerrainRenderer implements IDhTerrainRenderer
profiler.popPush("rendering");
// render each buffer
IVertexBufferWrapper[] bufferWrapperList = opaquePass ? bufferContainer.vbos : bufferContainer.vbosTransparent;
IVertexBufferWrapper[] bufferWrapperList = opaquePass ? bufferContainer.vboOpaqueWrappers : bufferContainer.vboTransparentWrappers;
for (int i = 0; i < bufferWrapperList.length; i++)
{
BlazeVertexBufferWrapper bufferWrapper = (BlazeVertexBufferWrapper) bufferWrapperList[i];
@@ -365,9 +337,10 @@ public class BlazeDhTerrainRenderer implements IDhTerrainRenderer
ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeBufferRenderEvent.class, new DhApiBeforeBufferRenderEvent.EventParam(renderEventParam, modelPos));
}
renderPass.setVertexBuffer(0, bufferWrapper.vboGpuBuffer); // vertex buffer can only be "0" lol
renderPass.setIndexBuffer(bufferWrapper.getIndexGpuBuffer(), VertexFormat.IndexType.INT);
renderPass.setVertexBuffer(0, bufferWrapper.vertexGpuBuffer); // vertex buffer can only be "0" lol
if (!bufferWrapper.vboGpuBuffer.isClosed())
if (!bufferWrapper.vertexGpuBuffer.isClosed())
{
renderPass.drawIndexed(
/*indexStart*/ 0,
@@ -27,9 +27,6 @@ public class BlazeDhApplyRenderer {}
import com.mojang.blaze3d.buffers.GpuBuffer;
import com.mojang.blaze3d.pipeline.BlendFunction;
import com.mojang.blaze3d.pipeline.RenderPipeline;
import com.mojang.blaze3d.platform.DepthTestFunction;
import com.mojang.blaze3d.platform.PolygonMode;
import com.mojang.blaze3d.shaders.UniformType;
import com.mojang.blaze3d.systems.CommandEncoder;
import com.mojang.blaze3d.systems.GpuDevice;
import com.mojang.blaze3d.systems.RenderPass;
@@ -37,12 +34,13 @@ import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.textures.*;
import com.mojang.blaze3d.vertex.VertexFormat;
import com.seibel.distanthorizons.common.render.blaze.util.BlazeDhVertexFormatUtil;
import com.seibel.distanthorizons.common.render.blaze.wrappers.RenderPipelineBuilderWrapper;
import com.seibel.distanthorizons.common.render.blaze.wrappers.texture.BlazeTextureViewWrapper;
import com.seibel.distanthorizons.common.render.blaze.util.BlazePostProcessUtil;
import com.seibel.distanthorizons.common.render.blaze.wrappers.texture.BlazeTextureWrapper;
import com.seibel.distanthorizons.core.logging.DhLogger;
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import com.seibel.distanthorizons.coreapi.ModInfo;
import net.minecraft.resources.Identifier;
import org.jetbrains.annotations.Nullable;
import java.util.Arrays;
@@ -81,6 +79,10 @@ public class BlazeDhApplyRenderer
private final BlazeTextureViewWrapper sourceDepthTextureViewWrapper = new BlazeTextureViewWrapper();
private final BlazeTextureViewWrapper destinationColorTextureViewWrapper = new BlazeTextureViewWrapper();
/** We don't want to actually write any depth data, but blaze3D complains if we don't bind a depth texture. */
private final BlazeTextureWrapper dummyDepthTextureWrapper = BlazeTextureWrapper.createDepth("apply_dummy_depth");
/**
* Can be set for special application shaders that need
@@ -134,8 +136,12 @@ public class BlazeDhApplyRenderer
GpuTexture sourceDepthTexture,
GpuTexture destinationColorTexture)
{
this.createPipeline();
this.vboGpuBuffer = BlazePostProcessUtil.createAndUploadScreenVertexData(this.name);
// one-time setup
if (this.pipeline == null)
{
this.createPipeline();
this.vboGpuBuffer = BlazePostProcessUtil.createAndUploadScreenVertexData(this.name);
}
this.sourceColorTextureViewWrapper.tryWrap(sourceColorTexture);
this.sourceDepthTextureViewWrapper.tryWrap(sourceDepthTexture);
@@ -145,20 +151,11 @@ public class BlazeDhApplyRenderer
}
private void createPipeline()
{
if (this.pipeline != null)
RenderPipelineBuilderWrapper pipelineBuilder = new RenderPipelineBuilderWrapper();
{
return;
}
VertexFormat vertexFormat = VertexFormat.builder()
.add("vPosition", BlazeDhVertexFormatUtil.SCREEN_POS)
.build();
RenderPipeline.Builder pipelineBuilder = RenderPipeline.builder();
{
pipelineBuilder.withCull(false);
pipelineBuilder.withFaceCulling(false);
pipelineBuilder.withDepthWrite(false);
pipelineBuilder.withDepthTestFunction(DepthTestFunction.NO_DEPTH_TEST);
pipelineBuilder.withDepthTest(RenderPipelineBuilderWrapper.EDhDepthTest.NONE);
pipelineBuilder.withColorWrite(true);
if (this.blendFunction != null)
@@ -170,23 +167,26 @@ public class BlazeDhApplyRenderer
pipelineBuilder.withoutBlend();
}
pipelineBuilder.withPolygonMode(PolygonMode.FILL);
pipelineBuilder.withLocation(Identifier.parse(this.identifierName)); // TODO will complain if capital letters are included
pipelineBuilder.withPolygonMode(RenderPipelineBuilderWrapper.EDhPolygonMode.FILL);
pipelineBuilder.withName(this.name);
// TODO manually validate paths to confirm they exist and end with ".fsh" or ".vsh", MC silently fails if the files are missing/improperly named
pipelineBuilder.withVertexShader(Identifier.fromNamespaceAndPath("distanthorizons", this.vertexShaderPath));
pipelineBuilder.withFragmentShader(Identifier.fromNamespaceAndPath("distanthorizons", this.fragmentShaderPath));
pipelineBuilder.withVertexShader(this.vertexShaderPath);
pipelineBuilder.withFragmentShader(this.fragmentShaderPath);
for (int i = 0; i < this.uniformNames.length; i++)
{
String uniformName = this.uniformNames[i];
pipelineBuilder.withUniform(uniformName, UniformType.UNIFORM_BUFFER);
pipelineBuilder.withUniformBuffer(uniformName);
}
pipelineBuilder.withSampler("uSourceColorTexture");
pipelineBuilder.withSampler("uSourceDepthTexture");
pipelineBuilder.withVertexFormat(vertexFormat, VertexFormat.Mode.TRIANGLE_FAN);
VertexFormat vertexFormat = VertexFormat.builder()
.add("vPosition", BlazeDhVertexFormatUtil.SCREEN_POS)
.build();
pipelineBuilder.withVertexFormat(vertexFormat);
pipelineBuilder.withVertexMode(RenderPipelineBuilderWrapper.EDhVertexMode.TRIANGLE_FAN);
}
this.pipeline = pipelineBuilder.build();
}
@@ -223,11 +223,13 @@ public class BlazeDhApplyRenderer
{
this.tryInit(sourceColorTexture, sourceDepthTexture, destinationColorTexture);
this.dummyDepthTextureWrapper.tryCreateOrResize();
try (RenderPass renderPass = COMMAND_ENCODER.createRenderPass(
this::getIdentifierName,
this.destinationColorTextureViewWrapper.textureView,
/*optionalClearColorAsInt*/ OptionalInt.empty(),
/*depthTexture*/ null,
this.dummyDepthTextureWrapper.textureView,
/*optionalDepthValueAsDouble*/ OptionalDouble.empty()))
{
renderPass.bindTexture("uSourceColorTexture", this.sourceColorTextureViewWrapper.textureView, this.sourceColorTextureViewWrapper.textureSampler);
@@ -26,20 +26,17 @@ public class BlazeDhCopyRenderer {}
import com.mojang.blaze3d.buffers.GpuBuffer;
import com.mojang.blaze3d.pipeline.RenderPipeline;
import com.mojang.blaze3d.platform.DepthTestFunction;
import com.mojang.blaze3d.platform.PolygonMode;
import com.mojang.blaze3d.systems.CommandEncoder;
import com.mojang.blaze3d.systems.GpuDevice;
import com.mojang.blaze3d.systems.RenderPass;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.textures.*;
import com.mojang.blaze3d.vertex.VertexFormat;
import com.seibel.distanthorizons.common.render.blaze.wrappers.RenderPipelineBuilderWrapper;
import com.seibel.distanthorizons.common.render.blaze.wrappers.texture.BlazeTextureViewWrapper;
import com.seibel.distanthorizons.common.render.blaze.wrappers.texture.BlazeTextureWrapper;
import com.seibel.distanthorizons.common.render.blaze.util.BlazePostProcessUtil;
import com.seibel.distanthorizons.core.logging.DhLogger;
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import net.minecraft.resources.Identifier;
import java.util.OptionalDouble;
import java.util.OptionalInt;
@@ -63,6 +60,8 @@ public class BlazeDhCopyRenderer
private GpuBuffer vboGpuBuffer;
private BlazeTextureWrapper dummyDepthTextureWrapper;
//=============//
@@ -81,23 +80,25 @@ public class BlazeDhCopyRenderer
this.init = true;
this.dummyDepthTextureWrapper = BlazeTextureWrapper.createDepth("dh_copy_depth_texture");
RenderPipeline.Builder pipelineBuilder = RenderPipeline.builder();
RenderPipelineBuilderWrapper pipelineBuilder = new RenderPipelineBuilderWrapper();
{
pipelineBuilder.withCull(false);
pipelineBuilder.withFaceCulling(false);
pipelineBuilder.withDepthWrite(false);
pipelineBuilder.withDepthTestFunction(DepthTestFunction.NO_DEPTH_TEST);
pipelineBuilder.withDepthTest(RenderPipelineBuilderWrapper.EDhDepthTest.NONE);
pipelineBuilder.withColorWrite(true);
pipelineBuilder.withoutBlend();
pipelineBuilder.withPolygonMode(PolygonMode.FILL);
pipelineBuilder.withLocation(Identifier.parse("distanthorizons:copy_render"));
pipelineBuilder.withPolygonMode(RenderPipelineBuilderWrapper.EDhPolygonMode.FILL);
pipelineBuilder.withName("copy");
pipelineBuilder.withVertexShader(Identifier.fromNamespaceAndPath("distanthorizons", "copy/blaze/vert"));
pipelineBuilder.withFragmentShader(Identifier.fromNamespaceAndPath("distanthorizons", "copy/blaze/frag"));
pipelineBuilder.withVertexShader("copy/blaze/vert");
pipelineBuilder.withFragmentShader("copy/blaze/frag");
pipelineBuilder.withSampler("uCopyTexture");
pipelineBuilder.withVertexFormat(BlazePostProcessUtil.createVertexFormat(), VertexFormat.Mode.TRIANGLE_FAN);
pipelineBuilder.withVertexFormat(BlazePostProcessUtil.createVertexFormat());
pipelineBuilder.withVertexMode(RenderPipelineBuilderWrapper.EDhVertexMode.TRIANGLE_FAN);
}
this.pipeline = pipelineBuilder.build();
@@ -139,11 +140,13 @@ public class BlazeDhCopyRenderer
{
this.tryInit();
this.dummyDepthTextureWrapper.tryCreateOrResize();
try (RenderPass renderPass = COMMAND_ENCODER.createRenderPass(
this::getRenderPassName,
destinationTextureView,
/*optionalClearColorAsInt*/ OptionalInt.empty(),
/*depthTexture*/ null,
this.dummyDepthTextureWrapper.textureView,
/*optionalDepthValueAsDouble*/ OptionalDouble.empty()))
{
renderPass.bindTexture("uCopyTexture", sourceTextureView, sourceTextureSampler);
@@ -84,14 +84,10 @@ public class BlazeGenericObjectVertexContainer implements IDhGenericObjectVertex
//===========================//
//region
@Override
public void updateVertexData(List<DhApiRenderableBox> uploadBoxList)
{
int boxCount = uploadBoxList.size();
if (boxCount == 0)
{
return; // TODO done just to fix a buffer empty crash
}
// recreate the data arrays if their size is different
if (this.uploadedBoxCount != boxCount)
@@ -183,20 +179,24 @@ public class BlazeGenericObjectVertexContainer implements IDhGenericObjectVertex
this.vertexBuffer.put(a);
this.vertexBuffer.put(box.material);
// TODO make sure this all is a multiple of 4 like LodQuadBuilder (might cause issues with AMD/Mac otherwise)
// padding so the vertex format's byte count is a multiple of 4
this.vertexBuffer.put((byte)0);
this.vertexBuffer.put((byte)0);
this.vertexBuffer.put((byte)0);
}
}
this.vertexBuffer.flip();
this.indexBuffer.flip();
this.state = BlazeGenericObjectVertexContainer.EState.READY_TO_UPLOAD;
}
private int vertexBufferSize()
{
int faceCount = this.uploadedBoxCount * 6;
int vertexCount = faceCount * 6;
// minimum of 1 box to prevent trying to create a buffer of size 0
int boxCount = Math.max(this.uploadedBoxCount, 1);
int faceCount = boxCount * 6; // 6 faces on a cube
int vertexCount = faceCount * 6; // 6 vertices per cube
int byteSize = vertexCount * 3 * Float.BYTES; // x,y,z
byteSize += vertexCount * 4; // r,g,b,a
@@ -205,19 +205,30 @@ public class BlazeGenericObjectVertexContainer implements IDhGenericObjectVertex
}
private int indexBufferSize()
{
int quadCount = this.uploadedBoxCount * 36;
int byteSize = quadCount * GLEnums.getTypeSize(GL32.GL_UNSIGNED_INT) * 6;
// minimum of 1 box to prevent trying to create a buffer of size 0
int boxCount = Math.max(this.uploadedBoxCount, 1);
int quadCount = boxCount * 6 * 6; // 6 faces with 6 vertices each
int byteSize = quadCount * GLEnums.getTypeSize(GL32.GL_UNSIGNED_INT);
return byteSize;
}
@Override
public void uploadDataToGpu()
{
// vertex
{
int totalVertexByteSize = this.vertexBufferSize();
if (this.vboGpuBuffer == null
|| this.vboGpuBuffer.size() < totalVertexByteSize)
// recreating if the size changes is always necessary (even if we only need a smaller amount)
// due to a bug on Mac where it will attempt to render anything allocated in the buffer
|| this.vboGpuBuffer.size() != totalVertexByteSize)
{
if (this.vboGpuBuffer != null)
{
this.vboGpuBuffer.close();
}
int usage = GpuBuffer.USAGE_COPY_DST
| GpuBuffer.USAGE_VERTEX;
this.vboGpuBuffer = GPU_DEVICE.createBuffer(this::getVertexBufferName, usage, totalVertexByteSize);
@@ -231,12 +242,17 @@ public class BlazeGenericObjectVertexContainer implements IDhGenericObjectVertex
{
int totalVertexByteSize = this.indexBufferSize();
if (this.indexGpuBuffer == null
|| this.indexGpuBuffer.size() < totalVertexByteSize)
// recreating if the size changes is always necessary (even if we only need a smaller amount)
// due to a bug on Mac where it will attempt to render anything allocated in the buffer
|| this.indexGpuBuffer.size() != totalVertexByteSize)
{
if (this.indexGpuBuffer != null)
{
this.indexGpuBuffer.close();
}
int usage = GpuBuffer.USAGE_COPY_DST
| GpuBuffer.USAGE_VERTEX
| GpuBuffer.USAGE_INDEX
| GpuBuffer.USAGE_UNIFORM;
| GpuBuffer.USAGE_INDEX;
this.indexGpuBuffer = GPU_DEVICE.createBuffer(this::getIndexBufferName, usage, totalVertexByteSize);
}
@@ -245,8 +261,6 @@ public class BlazeGenericObjectVertexContainer implements IDhGenericObjectVertex
COMMAND_ENCODER.writeToBuffer(bufferSlice, this.indexBuffer);
}
this.state = EState.RENDER;
}
private String getVertexBufferName() { return "distantHorizons:GenericVertexBuffer"; }
private String getIndexBufferName() { return "distantHorizons:GenericIndexBuffer"; }
@@ -263,7 +277,7 @@ public class BlazeGenericObjectVertexContainer implements IDhGenericObjectVertex
@Override
public void close()
{
RenderThreadTaskHandler.INSTANCE.queueRunningOnRenderThread(() ->
RenderThreadTaskHandler.INSTANCE.queueRunningOnRenderThread("BlazeGenericObjectVertexContainer close", () ->
{
if (this.vboGpuBuffer != null)
{
@@ -29,18 +29,15 @@ import com.mojang.blaze3d.buffers.GpuBufferSlice;
import com.mojang.blaze3d.buffers.Std140Builder;
import com.mojang.blaze3d.buffers.Std140SizeCalculator;
import com.mojang.blaze3d.pipeline.RenderPipeline;
import com.mojang.blaze3d.platform.DepthTestFunction;
import com.mojang.blaze3d.platform.PolygonMode;
import com.mojang.blaze3d.shaders.UniformType;
import com.mojang.blaze3d.systems.CommandEncoder;
import com.mojang.blaze3d.systems.GpuDevice;
import com.mojang.blaze3d.systems.RenderPass;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.VertexFormat;
import com.seibel.distanthorizons.common.render.blaze.BlazeDhMetaRenderer;
import com.seibel.distanthorizons.common.render.blaze.apply.BlazeDhCopyRenderer;
import com.seibel.distanthorizons.common.render.blaze.util.BlazePostProcessUtil;
import com.seibel.distanthorizons.common.render.blaze.util.BlazeUniformUtil;
import com.seibel.distanthorizons.common.render.blaze.wrappers.RenderPipelineBuilderWrapper;
import com.seibel.distanthorizons.common.render.blaze.wrappers.texture.BlazeTextureViewWrapper;
import com.seibel.distanthorizons.common.render.blaze.wrappers.texture.BlazeTextureWrapper;
import com.seibel.distanthorizons.core.logging.DhLogger;
@@ -50,7 +47,6 @@ import com.seibel.distanthorizons.core.util.RenderUtil;
import com.seibel.distanthorizons.core.util.math.Mat4f;
import com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass.IDhFarFadeRenderer;
import net.minecraft.client.Minecraft;
import net.minecraft.resources.Identifier;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
@@ -76,8 +72,11 @@ public class BlazeDhFarFadeRenderer implements IDhFarFadeRenderer
private GpuBuffer vboGpuBuffer;
public final BlazeTextureWrapper dhFadeColorTextureWrapper = BlazeTextureWrapper.createColor("DhFadeColorTexture");
public final BlazeTextureViewWrapper mcColorTextureViewWrapper = new BlazeTextureViewWrapper();
private final BlazeTextureWrapper dhFadeColorTextureWrapper = BlazeTextureWrapper.createColor("dh_far_fade_color_texture");
/** We don't want to actually write any depth data, but blaze3D complains if we don't bind a depth texture. */
private final BlazeTextureWrapper dhFadeDepthTextureWrapper = BlazeTextureWrapper.createDepth("dh_far_fade_depth_texture");
private final BlazeTextureViewWrapper mcColorTextureViewWrapper = new BlazeTextureViewWrapper();
@@ -98,27 +97,28 @@ public class BlazeDhFarFadeRenderer implements IDhFarFadeRenderer
RenderPipeline.Builder pipelineBuilder = RenderPipeline.builder();
RenderPipelineBuilderWrapper pipelineBuilder = new RenderPipelineBuilderWrapper();
{
pipelineBuilder.withCull(false);
pipelineBuilder.withFaceCulling(false);
pipelineBuilder.withDepthWrite(false);
pipelineBuilder.withDepthTestFunction(DepthTestFunction.NO_DEPTH_TEST);
pipelineBuilder.withDepthTest(RenderPipelineBuilderWrapper.EDhDepthTest.NONE);
pipelineBuilder.withColorWrite(true);
pipelineBuilder.withoutBlend();
pipelineBuilder.withPolygonMode(PolygonMode.FILL);
pipelineBuilder.withLocation(Identifier.parse("distanthorizons:far_fade"));
pipelineBuilder.withPolygonMode(RenderPipelineBuilderWrapper.EDhPolygonMode.FILL);
pipelineBuilder.withName("far_fade");
pipelineBuilder.withVertexShader(Identifier.fromNamespaceAndPath("distanthorizons", "fade/blaze/vert"));
pipelineBuilder.withFragmentShader(Identifier.fromNamespaceAndPath("distanthorizons", "fade/blaze/dh_fade"));
pipelineBuilder.withVertexShader("fade/blaze/vert");
pipelineBuilder.withFragmentShader("fade/blaze/dh_fade");
pipelineBuilder.withSampler("uMcColorTexture");
pipelineBuilder.withSampler("uDhDepthTexture");
pipelineBuilder.withSampler("uDhColorTexture");
pipelineBuilder.withUniform("fragUniformBlock", UniformType.UNIFORM_BUFFER);
pipelineBuilder.withUniformBuffer("fragUniformBlock");
pipelineBuilder.withVertexFormat(BlazePostProcessUtil.createVertexFormat(), VertexFormat.Mode.TRIANGLE_FAN);
pipelineBuilder.withVertexFormat(BlazePostProcessUtil.createVertexFormat());
pipelineBuilder.withVertexMode(RenderPipelineBuilderWrapper.EDhVertexMode.TRIANGLE_FAN);
}
this.pipeline = pipelineBuilder.build();
@@ -153,6 +153,8 @@ public class BlazeDhFarFadeRenderer implements IDhFarFadeRenderer
this.dhFadeColorTextureWrapper.tryCreateOrResize();
this.mcColorTextureViewWrapper.tryWrap(Minecraft.getInstance().getMainRenderTarget().getColorTexture());
this.dhFadeDepthTextureWrapper.tryCreateOrResize();
{
int uniformBufferSize = new Std140SizeCalculator()
.putFloat() // uStartFadeBlockDistance
@@ -206,7 +208,7 @@ public class BlazeDhFarFadeRenderer implements IDhFarFadeRenderer
this::getRenderPassName,
this.dhFadeColorTextureWrapper.textureView,
/*optionalClearColorAsInt*/ OptionalInt.empty(),
/*depthTexture*/ null,
this.dhFadeDepthTextureWrapper.textureView,
/*optionalDepthValueAsDouble*/ OptionalDouble.empty()))
{
// MC texture
@@ -30,21 +30,18 @@ import com.mojang.blaze3d.buffers.Std140Builder;
import com.mojang.blaze3d.buffers.Std140SizeCalculator;
import com.mojang.blaze3d.pipeline.BlendFunction;
import com.mojang.blaze3d.pipeline.RenderPipeline;
import com.mojang.blaze3d.platform.DepthTestFunction;
import com.mojang.blaze3d.platform.DestFactor;
import com.mojang.blaze3d.platform.PolygonMode;
import com.mojang.blaze3d.platform.SourceFactor;
import com.mojang.blaze3d.shaders.UniformType;
import com.mojang.blaze3d.systems.CommandEncoder;
import com.mojang.blaze3d.systems.GpuDevice;
import com.mojang.blaze3d.systems.RenderPass;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.VertexFormat;
import com.seibel.distanthorizons.api.enums.rendering.EDhApiFogColorMode;
import com.seibel.distanthorizons.api.enums.rendering.EDhApiHeightFogDirection;
import com.seibel.distanthorizons.api.enums.rendering.EDhApiHeightFogMixMode;
import com.seibel.distanthorizons.common.render.blaze.BlazeDhMetaRenderer;
import com.seibel.distanthorizons.common.render.blaze.apply.BlazeDhApplyRenderer;
import com.seibel.distanthorizons.common.render.blaze.wrappers.RenderPipelineBuilderWrapper;
import com.seibel.distanthorizons.common.render.blaze.wrappers.texture.BlazeTextureWrapper;
import com.seibel.distanthorizons.common.render.blaze.util.BlazePostProcessUtil;
import com.seibel.distanthorizons.common.render.blaze.util.BlazeUniformUtil;
@@ -58,7 +55,6 @@ import com.seibel.distanthorizons.core.util.math.Mat4f;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass.IDhFogRenderer;
import net.minecraft.resources.Identifier;
import java.awt.*;
import java.nio.ByteBuffer;
@@ -91,7 +87,9 @@ public class BlazeDhFogRenderer implements IDhFogRenderer
private GpuBuffer vboGpuBuffer;
public BlazeTextureWrapper fogColorTextureWrapper = BlazeTextureWrapper.createColor("DhFogColorTexture");
private final BlazeTextureWrapper fogColorTextureWrapper = BlazeTextureWrapper.createColor("dh_fog_color_texture");
/** We don't want to actually write any depth data, but blaze3D complains if we don't bind a depth texture. */
private final BlazeTextureWrapper fogDepthTextureWrapper = BlazeTextureWrapper.createDepth("dh_fog_depth_texture");
@@ -119,24 +117,25 @@ public class BlazeDhFogRenderer implements IDhFogRenderer
"apply/blaze/vert", "apply/blaze/frag"
);
RenderPipeline.Builder pipelineBuilder = RenderPipeline.builder();
RenderPipelineBuilderWrapper pipelineBuilder = new RenderPipelineBuilderWrapper();
{
pipelineBuilder.withCull(false);
pipelineBuilder.withFaceCulling(false);
pipelineBuilder.withDepthWrite(false);
pipelineBuilder.withDepthTestFunction(DepthTestFunction.NO_DEPTH_TEST);
pipelineBuilder.withDepthTest(RenderPipelineBuilderWrapper.EDhDepthTest.NONE);
pipelineBuilder.withColorWrite(true);
pipelineBuilder.withoutBlend();
pipelineBuilder.withPolygonMode(PolygonMode.FILL);
pipelineBuilder.withLocation(Identifier.parse("distanthorizons:fog_render"));
pipelineBuilder.withPolygonMode(RenderPipelineBuilderWrapper.EDhPolygonMode.FILL);
pipelineBuilder.withName("fog_render");
pipelineBuilder.withVertexShader(Identifier.fromNamespaceAndPath("distanthorizons", "fog/blaze/vert"));
pipelineBuilder.withFragmentShader(Identifier.fromNamespaceAndPath("distanthorizons", "fog/blaze/frag"));
pipelineBuilder.withVertexShader("fog/blaze/vert");
pipelineBuilder.withFragmentShader("fog/blaze/frag");
pipelineBuilder.withSampler("uDhDepthTexture");
pipelineBuilder.withUniform("fragUniformBlock", UniformType.UNIFORM_BUFFER);
pipelineBuilder.withUniformBuffer("fragUniformBlock");
pipelineBuilder.withVertexFormat(BlazePostProcessUtil.createVertexFormat(), VertexFormat.Mode.TRIANGLE_FAN);
pipelineBuilder.withVertexFormat(BlazePostProcessUtil.createVertexFormat());
pipelineBuilder.withVertexMode(RenderPipelineBuilderWrapper.EDhVertexMode.TRIANGLE_FAN);
}
this.pipeline = pipelineBuilder.build();
@@ -168,7 +167,7 @@ public class BlazeDhFogRenderer implements IDhFogRenderer
this.fogColorTextureWrapper.tryCreateOrResize();
this.fogDepthTextureWrapper.tryCreateOrResize();
{
int uniformBufferSize = new Std140SizeCalculator()
@@ -339,7 +338,7 @@ public class BlazeDhFogRenderer implements IDhFogRenderer
this::getRenderPassName,
this.fogColorTextureWrapper.textureView,
/*optionalClearColorAsInt*/ OptionalInt.empty(),
/*depthTexture*/ null,
this.fogDepthTextureWrapper.textureView,
/*optionalDepthValueAsDouble*/ OptionalDouble.empty()))
{
renderPass.bindTexture("uDhDepthTexture", BlazeDhMetaRenderer.INSTANCE.dhDepthTextureWrapper.textureView, BlazeDhMetaRenderer.INSTANCE.dhDepthTextureWrapper.textureSampler);
@@ -30,18 +30,15 @@ import com.mojang.blaze3d.buffers.Std140Builder;
import com.mojang.blaze3d.buffers.Std140SizeCalculator;
import com.mojang.blaze3d.pipeline.BlendFunction;
import com.mojang.blaze3d.pipeline.RenderPipeline;
import com.mojang.blaze3d.platform.DepthTestFunction;
import com.mojang.blaze3d.platform.DestFactor;
import com.mojang.blaze3d.platform.PolygonMode;
import com.mojang.blaze3d.platform.SourceFactor;
import com.mojang.blaze3d.shaders.UniformType;
import com.mojang.blaze3d.systems.CommandEncoder;
import com.mojang.blaze3d.systems.GpuDevice;
import com.mojang.blaze3d.systems.RenderPass;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.VertexFormat;
import com.seibel.distanthorizons.common.render.blaze.BlazeDhMetaRenderer;
import com.seibel.distanthorizons.common.render.blaze.apply.BlazeDhApplyRenderer;
import com.seibel.distanthorizons.common.render.blaze.wrappers.RenderPipelineBuilderWrapper;
import com.seibel.distanthorizons.common.render.blaze.wrappers.texture.BlazeTextureWrapper;
import com.seibel.distanthorizons.common.render.blaze.util.BlazePostProcessUtil;
import com.seibel.distanthorizons.common.render.blaze.util.BlazeUniformUtil;
@@ -53,7 +50,6 @@ import com.seibel.distanthorizons.core.util.RenderUtil;
import com.seibel.distanthorizons.core.util.math.Mat4f;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass.IDhSsaoRenderer;
import net.minecraft.resources.Identifier;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
@@ -83,7 +79,9 @@ public class BlazeDhSsaoRenderer implements IDhSsaoRenderer
private GpuBuffer vboGpuBuffer;
public BlazeTextureWrapper ssaoColorTextureWrapper = BlazeTextureWrapper.createColor("DhSsaoTexture");
private final BlazeTextureWrapper ssaoColorTextureWrapper = BlazeTextureWrapper.createColor("dh_ssao_color_texture");
/** We don't want to actually write any depth data, but blaze3D complains if we don't bind a depth texture. */
private final BlazeTextureWrapper ssaoDepthTextureWrapper = BlazeTextureWrapper.createDepth("dh_ssao_depth_texture");
@@ -110,24 +108,25 @@ public class BlazeDhSsaoRenderer implements IDhSsaoRenderer
/*uniforms*/ new String[] { "applyFragUniformBlock" }
);
RenderPipeline.Builder pipelineBuilder = RenderPipeline.builder();
RenderPipelineBuilderWrapper pipelineBuilder = new RenderPipelineBuilderWrapper();
{
pipelineBuilder.withCull(false);
pipelineBuilder.withFaceCulling(false);
pipelineBuilder.withDepthWrite(false);
pipelineBuilder.withDepthTestFunction(DepthTestFunction.NO_DEPTH_TEST);
pipelineBuilder.withDepthTest(RenderPipelineBuilderWrapper.EDhDepthTest.NONE);
pipelineBuilder.withColorWrite(true);
pipelineBuilder.withoutBlend();
pipelineBuilder.withPolygonMode(PolygonMode.FILL);
pipelineBuilder.withLocation(Identifier.parse("distanthorizons:ssao_render"));
pipelineBuilder.withPolygonMode(RenderPipelineBuilderWrapper.EDhPolygonMode.FILL);
pipelineBuilder.withName("ssao_render");
pipelineBuilder.withVertexShader(Identifier.fromNamespaceAndPath("distanthorizons", "ssao/blaze/vert"));
pipelineBuilder.withFragmentShader(Identifier.fromNamespaceAndPath("distanthorizons", "ssao/blaze/frag"));
pipelineBuilder.withVertexShader("ssao/blaze/vert");
pipelineBuilder.withFragmentShader("ssao/blaze/frag");
pipelineBuilder.withSampler("uDhDepthTexture");
pipelineBuilder.withUniform("fragUniformBlock", UniformType.UNIFORM_BUFFER);
pipelineBuilder.withUniformBuffer("fragUniformBlock");
pipelineBuilder.withVertexFormat(BlazePostProcessUtil.createVertexFormat(), VertexFormat.Mode.TRIANGLE_FAN);
pipelineBuilder.withVertexFormat(BlazePostProcessUtil.createVertexFormat());
pipelineBuilder.withVertexMode(RenderPipelineBuilderWrapper.EDhVertexMode.TRIANGLE_FAN);
}
this.pipeline = pipelineBuilder.build();
@@ -160,6 +159,7 @@ public class BlazeDhSsaoRenderer implements IDhSsaoRenderer
// textures
this.ssaoColorTextureWrapper.tryCreateOrResize();
this.ssaoDepthTextureWrapper.tryCreateOrResize();
// frag uniforms
{
@@ -259,7 +259,7 @@ public class BlazeDhSsaoRenderer implements IDhSsaoRenderer
this::getRenderPassName,
this.ssaoColorTextureWrapper.textureView,
/*optionalClearColorAsInt*/ OptionalInt.empty(),
/*depthTexture*/ null,
this.ssaoDepthTextureWrapper.textureView,
/*optionalDepthValueAsDouble*/ OptionalDouble.empty()))
{
renderPass.bindTexture("uDhDepthTexture", BlazeDhMetaRenderer.INSTANCE.dhDepthTextureWrapper.textureView, BlazeDhMetaRenderer.INSTANCE.dhDepthTextureWrapper.textureSampler);
@@ -29,7 +29,6 @@ import com.mojang.blaze3d.buffers.GpuBufferSlice;
import com.mojang.blaze3d.buffers.Std140Builder;
import com.mojang.blaze3d.buffers.Std140SizeCalculator;
import com.mojang.blaze3d.pipeline.RenderPipeline;
import com.mojang.blaze3d.platform.DepthTestFunction;
import com.mojang.blaze3d.platform.PolygonMode;
import com.mojang.blaze3d.shaders.UniformType;
import com.mojang.blaze3d.systems.CommandEncoder;
@@ -41,6 +40,7 @@ import com.seibel.distanthorizons.common.render.blaze.BlazeDhMetaRenderer;
import com.seibel.distanthorizons.common.render.blaze.apply.BlazeDhCopyRenderer;
import com.seibel.distanthorizons.common.render.blaze.util.BlazePostProcessUtil;
import com.seibel.distanthorizons.common.render.blaze.util.BlazeUniformUtil;
import com.seibel.distanthorizons.common.render.blaze.wrappers.RenderPipelineBuilderWrapper;
import com.seibel.distanthorizons.common.render.blaze.wrappers.texture.BlazeTextureViewWrapper;
import com.seibel.distanthorizons.common.render.blaze.wrappers.texture.BlazeTextureWrapper;
import com.seibel.distanthorizons.core.config.Config;
@@ -82,7 +82,10 @@ public class BlazeVanillaFadeRenderer implements IDhVanillaFadeRenderer
private GpuBuffer vboGpuBuffer;
public final BlazeTextureWrapper fadeColorTextureWrapper = BlazeTextureWrapper.createColor("DhVanillaFadeTexture");
public final BlazeTextureWrapper fadeColorTextureWrapper = BlazeTextureWrapper.createColor("DhVanillaFadeColorTexture");
/** We don't want to actually write any depth data, but blaze3D complains if we don't bind a depth texture. */
private final BlazeTextureWrapper fadeDepthTextureWrapper = BlazeTextureWrapper.createDepth("DhVanillaFadeDepthTexture");
public final BlazeTextureViewWrapper mcDepthTextureWrapper = new BlazeTextureViewWrapper();
public final BlazeTextureViewWrapper mcColorTextureWrapper = new BlazeTextureViewWrapper();
@@ -106,18 +109,18 @@ public class BlazeVanillaFadeRenderer implements IDhVanillaFadeRenderer
RenderPipeline.Builder pipelineBuilder = RenderPipeline.builder();
RenderPipelineBuilderWrapper pipelineBuilder = new RenderPipelineBuilderWrapper();
{
pipelineBuilder.withCull(false);
pipelineBuilder.withFaceCulling(false);
pipelineBuilder.withDepthWrite(false);
pipelineBuilder.withDepthTestFunction(DepthTestFunction.NO_DEPTH_TEST);
pipelineBuilder.withDepthTest(RenderPipelineBuilderWrapper.EDhDepthTest.NONE);
pipelineBuilder.withColorWrite(true);
pipelineBuilder.withoutBlend();
pipelineBuilder.withPolygonMode(PolygonMode.FILL);
pipelineBuilder.withLocation(Identifier.parse("distanthorizons:mc_vanilla_fade_render"));
pipelineBuilder.withPolygonMode(RenderPipelineBuilderWrapper.EDhPolygonMode.FILL);
pipelineBuilder.withName("vanilla_fade");
pipelineBuilder.withVertexShader(Identifier.fromNamespaceAndPath("distanthorizons", "fade/blaze/vert"));
pipelineBuilder.withFragmentShader(Identifier.fromNamespaceAndPath("distanthorizons", "fade/blaze/vanilla_fade"));
pipelineBuilder.withVertexShader("fade/blaze/vert");
pipelineBuilder.withFragmentShader("fade/blaze/vanilla_fade");
pipelineBuilder.withSampler("uMcDepthTexture");
pipelineBuilder.withSampler("uCombinedMcDhColorTexture");
@@ -125,9 +128,10 @@ public class BlazeVanillaFadeRenderer implements IDhVanillaFadeRenderer
pipelineBuilder.withSampler("uDhDepthTexture");
pipelineBuilder.withSampler("uDhColorTexture");
pipelineBuilder.withUniform("fragUniformBlock", UniformType.UNIFORM_BUFFER);
pipelineBuilder.withUniformBuffer("fragUniformBlock");
pipelineBuilder.withVertexFormat(BlazePostProcessUtil.createVertexFormat(), VertexFormat.Mode.TRIANGLE_FAN);
pipelineBuilder.withVertexFormat(BlazePostProcessUtil.createVertexFormat());
pipelineBuilder.withVertexMode(RenderPipelineBuilderWrapper.EDhVertexMode.TRIANGLE_FAN);
}
this.pipeline = pipelineBuilder.build();
@@ -158,6 +162,7 @@ public class BlazeVanillaFadeRenderer implements IDhVanillaFadeRenderer
// textures
this.fadeColorTextureWrapper.tryCreateOrResize();
this.fadeDepthTextureWrapper.tryCreateOrResize();
this.mcDepthTextureWrapper.tryWrap(Minecraft.getInstance().getMainRenderTarget().getDepthTexture());
this.mcColorTextureWrapper.tryWrap(Minecraft.getInstance().getMainRenderTarget().getColorTexture());
@@ -235,7 +240,7 @@ public class BlazeVanillaFadeRenderer implements IDhVanillaFadeRenderer
this::getRenderPassName,
this.fadeColorTextureWrapper.textureView,
/*optionalClearColorAsInt*/ OptionalInt.empty(),
/*depthTexture*/ null,
this.fadeDepthTextureWrapper.textureView,
/*optionalDepthValueAsDouble*/ OptionalDouble.empty()))
{
renderPass.bindTexture("uMcDepthTexture", this.mcDepthTextureWrapper.textureView, this.mcDepthTextureWrapper.textureSampler);
@@ -27,7 +27,6 @@ public class BlazeDhTestTriangleRenderer {}
import com.mojang.blaze3d.buffers.GpuBuffer;
import com.mojang.blaze3d.buffers.GpuBufferSlice;
import com.mojang.blaze3d.pipeline.RenderPipeline;
import com.mojang.blaze3d.platform.DepthTestFunction;
import com.mojang.blaze3d.platform.PolygonMode;
import com.mojang.blaze3d.systems.CommandEncoder;
import com.mojang.blaze3d.systems.GpuDevice;
@@ -36,6 +35,8 @@ import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.textures.*;
import com.mojang.blaze3d.vertex.VertexFormat;
import com.seibel.distanthorizons.common.render.blaze.util.BlazeDhVertexFormatUtil;
import com.seibel.distanthorizons.common.render.blaze.wrappers.RenderPipelineBuilderWrapper;
import com.seibel.distanthorizons.common.render.blaze.wrappers.texture.BlazeTextureViewWrapper;
import com.seibel.distanthorizons.core.logging.DhLogger;
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import com.seibel.distanthorizons.core.render.RenderParams;
@@ -48,6 +49,12 @@ import java.nio.ByteOrder;
import java.util.OptionalDouble;
import java.util.OptionalInt;
#if MC_VER <= MC_1_21_11
#else
import com.mojang.blaze3d.pipeline.DepthStencilState;
import com.mojang.blaze3d.platform.CompareOp;
#endif
/**
* Renders the OpenGL/Vulkan triangle
* to the center of the screen to confirm DH's
@@ -65,7 +72,8 @@ public class BlazeDhTestTriangleRenderer implements IDhTestTriangleRenderer
private RenderPipeline pipeline;
private boolean init = false;
private GpuTextureView mcColorTextureView;
public final BlazeTextureViewWrapper mcColorTextureViewWrapper = new BlazeTextureViewWrapper();
public final BlazeTextureViewWrapper mcDepthTextureViewWrapper = new BlazeTextureViewWrapper();
private GpuBuffer vboGpuBuffer;
@@ -86,42 +94,28 @@ public class BlazeDhTestTriangleRenderer implements IDhTestTriangleRenderer
}
this.init = true;
VertexFormat vertexFormat = VertexFormat.builder()
.add("vPosition", BlazeDhVertexFormatUtil.SCREEN_POS)
.add("vColor", BlazeDhVertexFormatUtil.RGBA_FLOAT_COLOR)
.build();
//int breakpointOne = 0;
// needs to manually be set if the VertexFormatElement isn't registered
//this.vertexFormat.getOffsetsByElement()[this.posForm.id()] = 0;
//this.vertexFormat.getOffsetsByElement()[this.colForm.id()] = Float.BYTES * 2;
//
//int breakpointTwo = 0;
RenderPipeline.Builder pipelineBuilder = RenderPipeline.builder();
RenderPipelineBuilderWrapper pipelineBuilder = new RenderPipelineBuilderWrapper();
{
pipelineBuilder.withCull(false);
pipelineBuilder.withFaceCulling(false);
pipelineBuilder.withDepthWrite(false);
pipelineBuilder.withDepthTestFunction(DepthTestFunction.NO_DEPTH_TEST);
pipelineBuilder.withDepthTest(RenderPipelineBuilderWrapper.EDhDepthTest.NONE);
pipelineBuilder.withColorWrite(true);
pipelineBuilder.withoutBlend();
pipelineBuilder.withPolygonMode(PolygonMode.FILL);
pipelineBuilder.withLocation(Identifier.parse("distanthorizons:test_render"));
pipelineBuilder.withName("triangle_test");
pipelineBuilder.withVertexShader(Identifier.fromNamespaceAndPath("distanthorizons", "test/blaze/vert"));
pipelineBuilder.withFragmentShader(Identifier.fromNamespaceAndPath("distanthorizons", "test/blaze/frag"));
pipelineBuilder.withVertexShader("test/blaze/vert");
pipelineBuilder.withFragmentShader("test/blaze/frag");
pipelineBuilder.withVertexFormat(vertexFormat, VertexFormat.Mode.TRIANGLES);
VertexFormat vertexFormat = VertexFormat.builder()
.add("vPosition", BlazeDhVertexFormatUtil.SCREEN_POS)
.add("vColor", BlazeDhVertexFormatUtil.RGBA_FLOAT_COLOR)
.build();
pipelineBuilder.withVertexFormat(vertexFormat);
pipelineBuilder.withVertexMode(RenderPipelineBuilderWrapper.EDhVertexMode.TRIANGLES);
}
this.pipeline = pipelineBuilder.build();
this.mcColorTextureView = GPU_DEVICE.createTextureView(Minecraft.getInstance().getMainRenderTarget().getColorTexture());
this.uploadVertexData();
}
private void uploadVertexData()
@@ -170,11 +164,14 @@ public class BlazeDhTestTriangleRenderer implements IDhTestTriangleRenderer
{
this.tryInit();
this.mcColorTextureViewWrapper.tryWrap(Minecraft.getInstance().getMainRenderTarget().getColorTexture());
this.mcDepthTextureViewWrapper.tryWrap(Minecraft.getInstance().getMainRenderTarget().getDepthTexture());
try (RenderPass renderPass = COMMAND_ENCODER.createRenderPass(
this::getRenderPassName,
this.mcColorTextureView,
this.mcColorTextureViewWrapper.textureView,
/*optionalClearColorAsInt*/ OptionalInt.empty(),
/*mcDepthTextureView*/ null,
this.mcDepthTextureViewWrapper.textureView,
/*optionalDepthValueAsDouble*/ OptionalDouble.empty()))
{
renderPass.setVertexBuffer(0, this.vboGpuBuffer);
@@ -14,28 +14,29 @@ import com.seibel.distanthorizons.core.logging.DhLogger;
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import com.seibel.distanthorizons.core.wrapperInterfaces.IVersionConstants;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
import org.jetbrains.annotations.NotNull;
/**
* @see LodQuadBuilder
*/
@SuppressWarnings("DataFlowIssue") // ignore null setter warnings in the static constructor (those will only be null if the render API is GL and in that case we should never use these objects)
public class BlazeDhVertexFormatUtil
{
private static final DhLogger LOGGER = new DhLoggerBuilder().build();
@NotNull public static final VertexFormatElement SCREEN_POS;
@NotNull public static final VertexFormatElement RGBA_FLOAT_COLOR;
public static final VertexFormatElement SCREEN_POS;
public static final VertexFormatElement RGBA_FLOAT_COLOR;
public static final VertexFormatElement SHORT_XYZ_POS;
public static final VertexFormatElement BYTE_PAD;
@NotNull public static final VertexFormatElement SHORT_XYZ_POS;
@NotNull public static final VertexFormatElement BYTE_PAD;
/** contains light and micro-offset */
public static final VertexFormatElement META;
public static final VertexFormatElement RGBA_UBYTE_COLOR;
public static final VertexFormatElement IRIS_MATERIAL;
public static final VertexFormatElement IRIS_NORMAL;
@NotNull public static final VertexFormatElement META;
@NotNull public static final VertexFormatElement RGBA_UBYTE_COLOR;
@NotNull public static final VertexFormatElement IRIS_MATERIAL;
@NotNull public static final VertexFormatElement IRIS_NORMAL;
public static final VertexFormatElement FLOAT_XYZ_POS;
@NotNull public static final VertexFormatElement FLOAT_XYZ_POS;
@@ -56,6 +57,7 @@ public class BlazeDhVertexFormatUtil
try
{
#if MC_VER <= MC_1_21_11
SCREEN_POS = VertexFormatElement.register(/*id*/22, /*index*/0, VertexFormatElement.Type.FLOAT, VertexFormatElement.Usage.POSITION, /*count*/ 2);
RGBA_FLOAT_COLOR = VertexFormatElement.register(/*id*/23, /*index*/0, VertexFormatElement.Type.FLOAT, VertexFormatElement.Usage.COLOR, /*count*/ 4);
@@ -68,6 +70,20 @@ public class BlazeDhVertexFormatUtil
IRIS_NORMAL = VertexFormatElement.register(/*id*/29, /*index*/0, VertexFormatElement.Type.BYTE, VertexFormatElement.Usage.GENERIC, /*count*/ 1);
FLOAT_XYZ_POS = VertexFormatElement.register(/*id*/30, /*index*/0, VertexFormatElement.Type.FLOAT, VertexFormatElement.Usage.POSITION, /*count*/ 3);
#else
SCREEN_POS = VertexFormatElement.register(/*id*/22, /*index*/0, VertexFormatElement.Type.FLOAT, false, /*count*/ 2);
RGBA_FLOAT_COLOR = VertexFormatElement.register(/*id*/23, /*index*/0, VertexFormatElement.Type.FLOAT, false, /*count*/ 4);
SHORT_XYZ_POS = VertexFormatElement.register(/*id*/24, /*index*/0, VertexFormatElement.Type.USHORT, false, /*count*/ 3);
BYTE_PAD = VertexFormatElement.register(/*id*/25, /*index*/0, VertexFormatElement.Type.BYTE, false, /*count*/ 1);
META = VertexFormatElement.register(/*id*/26, /*index*/0, VertexFormatElement.Type.USHORT, false, /*count*/ 1);
RGBA_UBYTE_COLOR = VertexFormatElement.register(/*id*/27, /*index*/0, VertexFormatElement.Type.UBYTE, true, /*count*/ 4);
IRIS_MATERIAL = VertexFormatElement.register(/*id*/28, /*index*/0, VertexFormatElement.Type.BYTE, false, /*count*/ 1);
IRIS_NORMAL = VertexFormatElement.register(/*id*/29, /*index*/0, VertexFormatElement.Type.BYTE, false, /*count*/ 1);
FLOAT_XYZ_POS = VertexFormatElement.register(/*id*/30, /*index*/0, VertexFormatElement.Type.FLOAT, false, /*count*/ 3);
#endif
}
catch (Exception e)
{
@@ -84,6 +100,7 @@ public class BlazeDhVertexFormatUtil
}
else
{
// set to null so we can fail fast with a null pointer if we ever attempt to incorrectly use these
SCREEN_POS = null;
RGBA_FLOAT_COLOR = null;
@@ -9,9 +9,13 @@ import com.mojang.blaze3d.buffers.GpuBuffer;
import com.mojang.blaze3d.systems.CommandEncoder;
import com.mojang.blaze3d.systems.GpuDevice;
import com.mojang.blaze3d.systems.RenderSystem;
import com.seibel.distanthorizons.core.logging.DhLogger;
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
public class BlazeUniformUtil
{
private static final DhLogger LOGGER = new DhLoggerBuilder().build();
private static final GpuDevice GPU_DEVICE = RenderSystem.getDevice();
private static final CommandEncoder COMMAND_ENCODER = GPU_DEVICE.createCommandEncoder();
@@ -22,7 +26,11 @@ public class BlazeUniformUtil
if (vboGpuBuffer == null
|| vboGpuBuffer.size() < size)
{
// GpuBuffer.USAGE_UNIFORM = 128
if (vboGpuBuffer != null)
{
vboGpuBuffer.close();
}
int usage = GpuBuffer.USAGE_COPY_DST
| GpuBuffer.USAGE_VERTEX
| GpuBuffer.USAGE_UNIFORM;
@@ -0,0 +1,351 @@
package com.seibel.distanthorizons.common.render.blaze.wrappers;
import com.mojang.blaze3d.pipeline.BlendFunction;
import com.mojang.blaze3d.pipeline.ColorTargetState;
import com.mojang.blaze3d.pipeline.DepthStencilState;
import com.mojang.blaze3d.pipeline.RenderPipeline;
import com.mojang.blaze3d.platform.CompareOp;
import com.mojang.blaze3d.platform.PolygonMode;
import com.mojang.blaze3d.shaders.UniformType;
import com.mojang.blaze3d.vertex.VertexFormat;
import net.minecraft.resources.Identifier;
import java.io.IOException;
import java.io.InputStream;
import java.util.Optional;
public class RenderPipelineBuilderWrapper
{
public static final String NAME_PREFIX = "distanthorizons:";
private static final String SHADER_RESOURCE_FOLDER = "assets/distanthorizons/shaders/";
private static final ClassLoader CLASS_LOADER = RenderPipelineBuilderWrapper.class.getClassLoader();
private final RenderPipeline.Builder blazePipelineBuilder;
// variables for specific builder options should be put next to their builder methods for simpler organization
//=============//
// constructor //
//=============//
//region
public RenderPipelineBuilderWrapper()
{
this.blazePipelineBuilder = RenderPipeline.builder();
}
//endregion
//==========//
// building //
//==========//
//region
private boolean writeDepth = false;
public RenderPipelineBuilderWrapper withDepthWrite(boolean write)
{
this.writeDepth = write;
return this;
}
private boolean writeColor = false;
public RenderPipelineBuilderWrapper withColorWrite(boolean write)
{
this.writeColor = write;
return this;
}
private BlendFunction blendFunction = null;
public RenderPipelineBuilderWrapper withBlend(BlendFunction blendFunction)
{
this.blendFunction = blendFunction;
return this;
}
public RenderPipelineBuilderWrapper withoutBlend()
{
this.blendFunction = null;
return this;
}
private EDhDepthTest depthTest;
public RenderPipelineBuilderWrapper withDepthTest(EDhDepthTest depthTest)
{
this.depthTest = depthTest;
return this;
}
public RenderPipelineBuilderWrapper withFaceCulling(boolean culling)
{
this.blazePipelineBuilder.withCull(culling);
return this;
}
public RenderPipelineBuilderWrapper withPolygonMode(EDhPolygonMode dhMode)
{
PolygonMode blazeMode;
switch (dhMode)
{
case FILL:
blazeMode = PolygonMode.FILL;
break;
case WIREFRAME:
blazeMode = PolygonMode.WIREFRAME;
break;
default:
throw new UnsupportedOperationException("No polygonMode defined for type ["+dhMode+"].");
}
this.blazePipelineBuilder.withPolygonMode(blazeMode);
return this;
}
public RenderPipelineBuilderWrapper withName(String name) throws IllegalArgumentException
{
// Identifiers must be of a specific format
if (!isValidIdentifier(name))
{
throw new IllegalArgumentException("Non [a-z0-9/._-] character in name: ["+name+"].");
}
this.blazePipelineBuilder.withLocation(Identifier.parse(NAME_PREFIX + name));
return this;
}
public RenderPipelineBuilderWrapper withSampler(String name) throws IllegalArgumentException
{
this.blazePipelineBuilder.withSampler(name);
return this;
}
public RenderPipelineBuilderWrapper withUniformBuffer(String name) throws IllegalArgumentException
{
this.blazePipelineBuilder.withUniform(name, UniformType.UNIFORM_BUFFER);
return this;
}
private VertexFormat vertexFormat = null;
public RenderPipelineBuilderWrapper withVertexFormat(VertexFormat vertexFormat)
{
this.vertexFormat = vertexFormat;
return this;
}
private EDhVertexMode vertexMode = null;
public RenderPipelineBuilderWrapper withVertexMode(EDhVertexMode vertexMode)
{
this.vertexMode = vertexMode;
return this;
}
public RenderPipelineBuilderWrapper withVertexShader(String scriptResourcePath) { return this.withShader(EDhShaderType.VERTEX, scriptResourcePath); }
public RenderPipelineBuilderWrapper withFragmentShader(String scriptResourcePath) { return this.withShader(EDhShaderType.FRAGMENT, scriptResourcePath); }
private RenderPipelineBuilderWrapper withShader(EDhShaderType shaderType, String scriptResourcePath)
{
String fullShaderResourcePath = SHADER_RESOURCE_FOLDER + scriptResourcePath + shaderType.fileExtension;
// confirm the shader file exists
try (InputStream scriptListInputStream = CLASS_LOADER.getResourceAsStream(fullShaderResourcePath))
{
if (scriptListInputStream == null)
{
throw new NullPointerException("Failed to find the SQL Script list file [" + fullShaderResourcePath + "], no auto update scripts can be run.");
}
}
catch (IOException e)
{
// shouldn't happen, but just in case
throw new RuntimeException("Unexpected issue closing resource stream for shader type: ["+shaderType+"] at: ["+fullShaderResourcePath+"], error: ["+e.getMessage()+"].", e);
}
if (shaderType == EDhShaderType.VERTEX)
{
this.blazePipelineBuilder.withVertexShader(Identifier.parse(NAME_PREFIX + scriptResourcePath));
}
else
{
this.blazePipelineBuilder.withFragmentShader(Identifier.parse(NAME_PREFIX + scriptResourcePath));
}
return this;
}
//endregion
//=====//
// end //
//=====//
//region
public RenderPipeline build() throws UnsupportedOperationException
{
// depth/color
{
#if MC_VER <= MC_1_21_11
this.blazePipelineBuilder.withDepthWrite(this.writeDepth);
this.blazePipelineBuilder.withColorWrite(this.writeColor);
if (this.blendFunction != null)
{
this.blazePipelineBuilder.withBlend(this.blendFunction);
}
else
{
this.blazePipelineBuilder.withoutBlend();
}
switch (this.depthTest)
{
case NONE:
break;
case LESS:
break;
}
this.blazepipelineBuilder.withDepthTest(RenderPipelineBuilderWrapper.EDhDepthTest.NONE);
#else
CompareOp compareOp;
switch (this.depthTest)
{
case NONE:
compareOp = CompareOp.ALWAYS_PASS;
break;
case LESS:
compareOp = CompareOp.LESS_THAN;
break;
default:
throw new UnsupportedOperationException("No depth test defined for type ["+this.depthTest+"].");
}
this.blazePipelineBuilder.withDepthStencilState(new DepthStencilState(compareOp, this.writeDepth));
this.blazePipelineBuilder.withColorTargetState(
new ColorTargetState(
Optional.ofNullable(this.blendFunction),
this.writeColor ? ColorTargetState.WRITE_ALL : ColorTargetState.WRITE_NONE
)
);
#endif
}
// vertex format
{
VertexFormat.Mode blazeVertexMode;
switch (this.vertexMode)
{
case TRIANGLES:
blazeVertexMode = VertexFormat.Mode.TRIANGLES;
break;
case TRIANGLE_FAN:
blazeVertexMode = VertexFormat.Mode.TRIANGLE_FAN;
break;
case LINES:
blazeVertexMode = VertexFormat.Mode.DEBUG_LINES;
break;
default:
throw new UnsupportedOperationException("No vertex mode defined for type ["+this.vertexMode+"].");
}
this.blazePipelineBuilder.withVertexFormat(vertexFormat, blazeVertexMode);
}
return this.blazePipelineBuilder.build();
}
//endregion
//================//
// helper methods //
//================//
//region
private static boolean isValidIdentifier(String identifier)
{
for (int i = 0; i < identifier.length(); i++)
{
char ch = identifier.charAt(i);
if (!isValidNamespaceChar(ch))
{
return false;
}
}
return true;
}
private static boolean isValidNamespaceChar(final char ch)
{
return ch == '_'
|| ch == '-'
// only lower case characters
|| (ch >= 'a' && ch <= 'z')
|| (ch >= '0' && ch <= '9')
|| ch == '.';
}
//endregion
//================//
// helper classes //
//================//
//region
public enum EDhPolygonMode
{
FILL,
WIREFRAME;
}
public enum EDhVertexMode
{
TRIANGLES,
TRIANGLE_FAN,
LINES;
}
public enum EDhDepthTest
{
NONE,
LESS;
}
private enum EDhShaderType
{
FRAGMENT(".fsh"),
VERTEX(".vsh");
public final String fileExtension;
EDhShaderType(String fileExtension)
{
this.fileExtension = fileExtension;
}
}
//endregion
}
@@ -10,31 +10,86 @@ import com.mojang.blaze3d.buffers.GpuBufferSlice;
import com.mojang.blaze3d.systems.CommandEncoder;
import com.mojang.blaze3d.systems.GpuDevice;
import com.mojang.blaze3d.systems.RenderSystem;
import com.seibel.distanthorizons.core.dataObjects.render.bufferBuilding.IndexBufferBuilder;
import com.seibel.distanthorizons.core.dataObjects.render.bufferBuilding.LodQuadBuilder;
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
import com.seibel.distanthorizons.core.logging.DhLogger;
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import com.seibel.distanthorizons.core.render.RenderThreadTaskHandler;
import com.seibel.distanthorizons.core.wrapperInterfaces.render.AbstractDhRenderApiDefinition;
import com.seibel.distanthorizons.core.wrapperInterfaces.render.objects.IVertexBufferWrapper;
import org.lwjgl.system.MemoryUtil;
import java.nio.ByteBuffer;
import java.util.concurrent.atomic.AtomicInteger;
public class BlazeVertexBufferWrapper implements IVertexBufferWrapper
{
private static final DhLogger LOGGER = new DhLoggerBuilder().build();
private static final AbstractDhRenderApiDefinition RENDER_DEF = SingletonInjector.INSTANCE.get(AbstractDhRenderApiDefinition.class);
private static final GpuDevice GPU_DEVICE = RenderSystem.getDevice();
private static final CommandEncoder COMMAND_ENCODER = GPU_DEVICE.createCommandEncoder();
private static final AtomicInteger BUFFER_COUNT_REF = new AtomicInteger(0);
public final String name;
public String getName() { return this.name; }
public GpuBuffer vboGpuBuffer = null;
public GpuBuffer vertexGpuBuffer = null;
public int vertexCount = -1;
public int indexCount = -1;
public boolean uploaded = false;
private GpuBuffer indexGpuBuffer = null;
private static GpuBuffer GLOBAL_INDEX_GPU_BUFFER = null;
public GpuBuffer getIndexGpuBuffer()
{
if (RENDER_DEF.useSingleIbo())
{
return GLOBAL_INDEX_GPU_BUFFER;
}
else
{
return this.indexGpuBuffer;
}
}
//=============//
// constructor //
//=============//
//region
static
{
if (RENDER_DEF.useSingleIbo())
{
RenderThreadTaskHandler.INSTANCE.queueRunningOnRenderThread("Global IBO Creation", () ->
{
int maxSize = LodQuadBuilder.getMaxBufferByteSize();
int maxVertexCount = maxSize / LodQuadBuilder.BYTES_PER_VERTEX;
int maxQuadCount = (maxVertexCount / 4);
ByteBuffer indexBuffer = IndexBufferBuilder.createBuffer(maxQuadCount);
int usage = GpuBuffer.USAGE_COPY_DST
| GpuBuffer.USAGE_INDEX;
GLOBAL_INDEX_GPU_BUFFER = GPU_DEVICE.createBuffer(BlazeVertexBufferWrapper::getIndexBufferName, usage, indexBuffer.capacity());
GpuBufferSlice bufferSlice = new GpuBufferSlice(GLOBAL_INDEX_GPU_BUFFER, /*offset*/ 0, indexBuffer.capacity());
COMMAND_ENCODER.writeToBuffer(bufferSlice, indexBuffer);
MemoryUtil.memFree(indexBuffer);
});
}
}
public BlazeVertexBufferWrapper(String name) { this.name = name; }
//endregion
@@ -47,23 +102,88 @@ public class BlazeVertexBufferWrapper implements IVertexBufferWrapper
//region
@Override
public void upload(ByteBuffer buffer, int vertexCount)
public void uploadVertexBuffer(ByteBuffer vertexBuffer, int vertexCount)
{
int oldVertexCount = this.vertexCount;
this.vertexCount = vertexCount;
// 4 vertices per face, but 6 indices (IE 2 triangles) per face, aka need to multiply by 1.5
this.indexCount = (int)(vertexCount * 1.5);
this.uploaded = true;
int usage = GpuBuffer.USAGE_COPY_DST
| GpuBuffer.USAGE_VERTEX;
int byteSize = (buffer.limit() - buffer.position());
this.vboGpuBuffer = GPU_DEVICE.createBuffer(this::getName, usage, byteSize);
GpuBufferSlice bufferSlice = new GpuBufferSlice(this.vboGpuBuffer, /*offset*/0, byteSize);
COMMAND_ENCODER.writeToBuffer(bufferSlice, buffer);
if (this.vertexGpuBuffer == null
// recreating if the size changes is always necessary (even if we only need a smaller amount)
// due to a bug on Mac where it will attempt to render anything allocated in the buffer
|| oldVertexCount != vertexCount)
{
if (this.vertexGpuBuffer == null)
{
BUFFER_COUNT_REF.incrementAndGet();
//LOGGER.info("Create, count: ["+BUFFER_COUNT_REF.get()+"]");
}
if (this.vertexGpuBuffer != null)
{
this.vertexGpuBuffer.close();
}
int usage = GpuBuffer.USAGE_COPY_DST
| GpuBuffer.USAGE_VERTEX;
int byteSize = (vertexBuffer.limit() - vertexBuffer.position());
this.vertexGpuBuffer = GPU_DEVICE.createBuffer(this::getName, usage, byteSize);
GpuBufferSlice bufferSlice = new GpuBufferSlice(this.vertexGpuBuffer, /*offset*/0, byteSize);
COMMAND_ENCODER.writeToBuffer(bufferSlice, vertexBuffer);
}
}
@Override
public void uploadIndexBuffer(ByteBuffer buffer, int vertexCount)
{
int oldIndexCount = this.indexCount;
// 4 vertices per face, but 6 indices (IE 2 triangles) per face, aka need to multiply by 1.5
this.indexCount = (int)(vertexCount * 1.5);
if (RENDER_DEF.useSingleIbo())
{
// ignore index uploading when running a single IBO
return;
}
// recreating if the size changes is always necessary (even if we only need a smaller amount)
// due to a bug on Mac where it will attempt to render anything allocated in the buffer
if (this.indexGpuBuffer == null
|| oldIndexCount != this.indexCount)
{
if (this.indexGpuBuffer == null)
{
BUFFER_COUNT_REF.incrementAndGet();
}
if (this.indexGpuBuffer != null)
{
this.indexGpuBuffer.close();
}
ByteBuffer indexBuffer = IndexBufferBuilder.createBuffer(this.vertexCount);
int usage = GpuBuffer.USAGE_COPY_DST
| GpuBuffer.USAGE_INDEX;
this.indexGpuBuffer = GPU_DEVICE.createBuffer(BlazeVertexBufferWrapper::getIndexBufferName, usage, indexBuffer.capacity());
GpuBufferSlice bufferSlice = new GpuBufferSlice(this.indexGpuBuffer, /*offset*/ 0, indexBuffer.capacity());
COMMAND_ENCODER.writeToBuffer(bufferSlice, indexBuffer);
MemoryUtil.memFree(indexBuffer);
}
}
private static String getIndexBufferName() { return "distantHorizons:LodIndexBuffer"; }
//endregion
@@ -76,10 +196,19 @@ public class BlazeVertexBufferWrapper implements IVertexBufferWrapper
@Override
public void close()
{
if (this.vboGpuBuffer != null)
if (this.vertexGpuBuffer != null)
{
this.vboGpuBuffer.close();
BUFFER_COUNT_REF.decrementAndGet();
this.vertexGpuBuffer.close();
}
if (this.indexGpuBuffer != null)
{
BUFFER_COUNT_REF.decrementAndGet();
this.indexGpuBuffer.close();
}
//LOGGER.info("Close, count: ["+BUFFER_COUNT_REF.get()+"]");
}
//endregion
@@ -103,10 +103,10 @@ public class BlazeTextureWrapper
this.width = viewWidth;
this.height = viewHeight;
int usage = GpuBuffer.USAGE_HINT_CLIENT_STORAGE
| GpuBuffer.USAGE_COPY_DST
| GpuBuffer.USAGE_VERTEX
| GpuBuffer.USAGE_UNIFORM;
int usage = GpuTexture.USAGE_COPY_DST
| GpuTexture.USAGE_TEXTURE_BINDING
| GpuTexture.USAGE_COPY_SRC
| GpuTexture.USAGE_RENDER_ATTACHMENT;
this.texture = GPU_DEVICE.createTexture(this.name,
usage,
this.textureFormat,
@@ -32,7 +32,7 @@ public class BlazeLodUniformBufferWrapper extends BlazeUniformBufferWrapper impl
//========//
// ??? //
// upload //
//========//
//region
@@ -72,5 +72,7 @@ public class BlazeLodUniformBufferWrapper extends BlazeUniformBufferWrapper impl
//endregion
}
#endif
@@ -20,7 +20,7 @@
package com.seibel.distanthorizons.common.render.openGl;
import com.seibel.distanthorizons.api.enums.config.EDhApiGpuUploadMethod;
import com.seibel.distanthorizons.common.render.openGl.glObject.buffer.GLElementBuffer;
import com.seibel.distanthorizons.common.render.openGl.glObject.buffer.GLIndexBuffer;
import com.seibel.distanthorizons.common.render.openGl.glObject.buffer.GLVertexBuffer;
import com.seibel.distanthorizons.common.render.openGl.glObject.shader.GlShaderProgram;
import com.seibel.distanthorizons.common.render.openGl.glObject.vertexAttribute.GlAbstractVertexAttribute;
@@ -53,7 +53,7 @@ public class GlDhDebugWireframeRenderer extends AbstractDebugWireframeRenderer
// rendering setup
private GlShaderProgram basicShader;
private GLVertexBuffer vertexBuffer;
private GLElementBuffer indexBuffer;
private GLIndexBuffer indexBuffer;
private GlAbstractVertexAttribute va;
private boolean init = false;
@@ -140,7 +140,7 @@ public class GlDhDebugWireframeRenderer extends AbstractDebugWireframeRenderer
boxOutlineBuffer.order(ByteOrder.nativeOrder());
boxOutlineBuffer.asIntBuffer().put(BOX_OUTLINE_INDICES);
boxOutlineBuffer.rewind();
this.indexBuffer = new GLElementBuffer(false);
this.indexBuffer = new GLIndexBuffer(false);
this.indexBuffer.uploadBuffer(boxOutlineBuffer, EDhApiGpuUploadMethod.DATA, BOX_OUTLINE_INDICES.length * Integer.BYTES, GL32.GL_STATIC_DRAW);
}
@@ -8,13 +8,12 @@ import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhAp
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiTextureCreatedParam;
import com.seibel.distanthorizons.common.render.openGl.glObject.GLProxy;
import com.seibel.distanthorizons.common.render.openGl.glObject.GlDhFramebuffer;
import com.seibel.distanthorizons.common.render.openGl.glObject.buffer.GlQuadElementBuffer;
import com.seibel.distanthorizons.common.render.openGl.glObject.texture.*;
import com.seibel.distanthorizons.common.render.openGl.postProcessing.apply.GlDhApplyShader;
import com.seibel.distanthorizons.common.render.openGl.terrain.GlDhTerrainShaderProgram;
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftGLWrapper;
import com.seibel.distanthorizons.common.wrappers.misc.LightMapWrapper;
import com.seibel.distanthorizons.core.config.Config;
import com.seibel.distanthorizons.core.dataObjects.render.bufferBuilding.LodQuadBuilder;
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
import com.seibel.distanthorizons.core.logging.DhLogger;
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
@@ -96,7 +95,7 @@ public class GlDhMetaRenderer implements IDhMetaRenderer
this.renderObjectsCreated = true;
}
this.shaderProgramForThisFrame = GlDhTerrainShaderProgram.INSTANCE;
this.shaderProgramForThisFrame = GlDhTerrainRenderer.INSTANCE.getTerrainShaderProgram();
IDhApiShaderProgram lodShaderProgramOverride = OverrideInjector.INSTANCE.get(IDhApiShaderProgram.class);
if (lodShaderProgramOverride != null && this.shaderProgramForThisFrame.overrideThisFrame())
{
@@ -106,7 +105,6 @@ public class GlDhMetaRenderer implements IDhMetaRenderer
this.setGLState(renderParams, firstPass);
GlDhTerrainShaderProgram.INSTANCE.quadIBO.bind();
this.bindLightmap(renderParams.lightmap);
}
private void setGLState(
@@ -242,9 +240,6 @@ public class GlDhMetaRenderer implements IDhMetaRenderer
LOGGER.info("Setting up renderer");
GlDhTerrainShaderProgram.INSTANCE.quadIBO = new GlQuadElementBuffer();
GlDhTerrainShaderProgram.INSTANCE.quadIBO.reserve(LodQuadBuilder.getMaxBufferByteSize());
// create or get the frame buffer
if (AbstractOptifineAccessor.optifinePresent())
@@ -362,7 +357,6 @@ public class GlDhMetaRenderer implements IDhMetaRenderer
this.unbindLightmap();
GlDhTerrainShaderProgram.INSTANCE.quadIBO.unbind();
this.shaderProgramForThisFrame.unbind();
}
@@ -8,6 +8,7 @@ import com.seibel.distanthorizons.common.render.openGl.postProcessing.fade.GlDhF
import com.seibel.distanthorizons.common.render.openGl.postProcessing.fade.GlVanillaFadeRenderer;
import com.seibel.distanthorizons.common.render.openGl.postProcessing.fog.GlDhFogRenderer;
import com.seibel.distanthorizons.common.render.openGl.postProcessing.ssao.GlDhSSAORenderer;
import com.seibel.distanthorizons.common.render.openGl.terrain.GlDhTerrainShaderProgram;
import com.seibel.distanthorizons.common.render.openGl.test.GlTestTriangleRenderer;
import com.seibel.distanthorizons.core.render.renderer.AbstractDebugWireframeRenderer;
import com.seibel.distanthorizons.core.wrapperInterfaces.render.AbstractDhRenderApiDefinition;
@@ -35,7 +36,7 @@ public class GlDhRenderApiDefinition extends AbstractDhRenderApiDefinition
//region
@Override public IDhMetaRenderer getMetaRenderer() { return GlDhMetaRenderer.INSTANCE; }
@Override public IDhTerrainRenderer getTerrainRenderer() { return GlDhTerrainShaderProgram.INSTANCE; }
@Override public IDhTerrainRenderer getTerrainRenderer() { return GlDhTerrainRenderer.INSTANCE; }
@Override public IDhSsaoRenderer getSsaoRenderer() { return GlDhSSAORenderer.INSTANCE; }
@Override public IDhFogRenderer getFogRenderer() { return GlDhFogRenderer.INSTANCE; }
@Override public IDhFarFadeRenderer getFarFadeRenderer() { return GlDhFarFadeRenderer.INSTANCE; }
@@ -53,7 +54,7 @@ public class GlDhRenderApiDefinition extends AbstractDhRenderApiDefinition
//===========//
//region
@Override public IDhGenericRenderer createGenericRenderer() { return GlGenericObjectRenderer.INSTANCE; }
@Override public IDhGenericRenderer createGenericRenderer() { return new GlGenericObjectRenderer(); }
@Override public IVertexBufferWrapper createVboWrapper(String name) { return new GLVertexBuffer(); }
@Override public ILodContainerUniformBufferWrapper createLodContainerUniformWrapper() { return new GlDummyUniformData(); }
@@ -0,0 +1,67 @@
package com.seibel.distanthorizons.common.render.openGl;
import com.seibel.distanthorizons.common.render.openGl.terrain.GlDhTerrainShaderProgram;
import com.seibel.distanthorizons.core.dataObjects.render.bufferBuilding.LodBufferContainer;
import com.seibel.distanthorizons.core.render.RenderParams;
import com.seibel.distanthorizons.core.util.objects.SortedArraySet;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IProfilerWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass.IDhTerrainRenderer;
public class GlDhTerrainRenderer implements IDhTerrainRenderer
{
public static final GlDhTerrainRenderer INSTANCE = new GlDhTerrainRenderer();
private GlDhTerrainShaderProgram terrainShaderProgram = null;
//=============//
// constructor //
//=============//
//region
private GlDhTerrainRenderer() {}
//endregion
//=========//
// getters //
//=========//
//region
/** must be called on the render thread the first time so GL can run it's setup */
public GlDhTerrainShaderProgram getTerrainShaderProgram()
{
if (this.terrainShaderProgram == null)
{
this.terrainShaderProgram = new GlDhTerrainShaderProgram();
}
return this.terrainShaderProgram;
}
//endregion
//========//
// render //
//========//
//region
@Override
public void render(RenderParams renderEventParam, boolean opaquePass, SortedArraySet<LodBufferContainer> bufferContainers, IProfilerWrapper profiler)
{
this.getTerrainShaderProgram();
this.terrainShaderProgram.tryInit();
this.terrainShaderProgram.render(renderEventParam, opaquePass, bufferContainers, profiler);
}
//endregion
}
@@ -30,7 +30,7 @@ import com.seibel.distanthorizons.api.objects.math.DhApiVec3d;
import com.seibel.distanthorizons.api.objects.render.DhApiRenderableBox;
import com.seibel.distanthorizons.api.objects.render.DhApiRenderableBoxGroupShading;
import com.seibel.distanthorizons.common.render.openGl.glObject.GLProxy;
import com.seibel.distanthorizons.common.render.openGl.glObject.buffer.GLElementBuffer;
import com.seibel.distanthorizons.common.render.openGl.glObject.buffer.GLIndexBuffer;
import com.seibel.distanthorizons.common.render.openGl.glObject.buffer.GLVertexBuffer;
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftGLWrapper;
import com.seibel.distanthorizons.core.config.Config;
@@ -76,8 +76,6 @@ public class GlGenericObjectRenderer implements IDhGenericRenderer
private static final DhApiRenderableBoxGroupShading DEFAULT_SHADING = DhApiRenderableBoxGroupShading.getUnshaded();
public static final GlGenericObjectRenderer INSTANCE = new GlGenericObjectRenderer();
/**
* Can be used to troubleshoot the renderer.
* If enabled several debug objects will render around (0,150,0).
@@ -91,7 +89,7 @@ public class GlGenericObjectRenderer implements IDhGenericRenderer
private IDhApiGenericObjectShaderProgram instancedShaderProgram;
private IDhApiGenericObjectShaderProgram directShaderProgram;
private GLVertexBuffer boxVertexBuffer;
private GLElementBuffer boxIndexBuffer;
private GLIndexBuffer boxIndexBuffer;
private boolean instancedRenderingAvailable;
private boolean vertexAttribDivisorSupported;
@@ -176,7 +174,7 @@ public class GlGenericObjectRenderer implements IDhGenericRenderer
//=============//
//region
private GlGenericObjectRenderer() { }
public GlGenericObjectRenderer() { }
public void init()
{
@@ -195,6 +193,13 @@ public class GlGenericObjectRenderer implements IDhGenericRenderer
this.vertexAttribDivisorSupported = GLProxy.getInstance().vertexAttribDivisorSupported;
this.instancedArraysSupported = GLProxy.getInstance().instancedArraysSupported;
boolean isMac = (EPlatform.get() == EPlatform.MACOS);
if (isMac)
{
LOGGER.warn("Generic rendering not supported by Mac. Clouds, beacons, and some other effects will be disabled.");
Config.Client.Advanced.Graphics.GenericRendering.enableGenericRendering.setApiValue(false);
return;
}
this.instancedRenderingAvailable = (this.vertexAttribDivisorSupported || this.instancedArraysSupported) && !isMac;
if (!this.instancedRenderingAvailable)
{
@@ -232,7 +237,7 @@ public class GlGenericObjectRenderer implements IDhGenericRenderer
ByteBuffer solidIndexBuffer = MemoryUtil.memAlloc(BOX_INDICES.length * Integer.BYTES);
solidIndexBuffer.asIntBuffer().put(BOX_INDICES);
solidIndexBuffer.rewind();
this.boxIndexBuffer = new GLElementBuffer(false);
this.boxIndexBuffer = new GLIndexBuffer(false);
this.boxIndexBuffer.uploadBuffer(solidIndexBuffer, EDhApiGpuUploadMethod.DATA, BOX_INDICES.length * Integer.BYTES, GL32.GL_STATIC_DRAW);
this.boxIndexBuffer.bind();
MemoryUtil.memFree(solidIndexBuffer);
@@ -361,6 +366,11 @@ public class GlGenericObjectRenderer implements IDhGenericRenderer
throw new IllegalArgumentException("Box group must be of type ["+ RenderableBoxGroup.class.getSimpleName()+"], type received: ["+(iBoxGroup != null ? iBoxGroup.getClass() : "NULL")+"].");
}
RenderableBoxGroup boxGroup = (RenderableBoxGroup) iBoxGroup;
if (boxGroup.size() != 0)
{
// trigger a box change to make sure the initial data is uploaded
boxGroup.triggerBoxChange();
}
long id = boxGroup.getId();
@@ -394,14 +404,19 @@ public class GlGenericObjectRenderer implements IDhGenericRenderer
@Override
public void render(RenderParams renderEventParam, IProfilerWrapper profiler, boolean renderingWithSsao)
{
// generic rendering (both instanced and direct) is extremely unstable on Mac, so don't render anything
if (EPlatform.get() == EPlatform.MACOS)
{
return;
}
// render setup //
profiler.push("setup");
this.init();
boolean useInstancedRendering = this.instancedRenderingAvailable
&& Config.Client.Advanced.Graphics.GenericRendering.enableInstancedRendering.get();
ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeGenericRenderSetupEvent.class, renderEventParam);
@@ -421,7 +436,7 @@ public class GlGenericObjectRenderer implements IDhGenericRenderer
GL32.glBlendEquation(GL32.GL_FUNC_ADD);
GLMC.glBlendFuncSeparate(GL32.GL_SRC_ALPHA, GL32.GL_ONE_MINUS_SRC_ALPHA, GL32.GL_ONE, GL32.GL_ONE_MINUS_SRC_ALPHA);
IDhApiGenericObjectShaderProgram shaderProgram = useInstancedRendering ? this.instancedShaderProgram : this.directShaderProgram;
IDhApiGenericObjectShaderProgram shaderProgram = this.instancedRenderingAvailable ? this.instancedShaderProgram : this.directShaderProgram;
IDhApiGenericObjectShaderProgram shaderProgramOverride = OverrideInjector.INSTANCE.get(IDhApiGenericObjectShaderProgram.class);
if (shaderProgramOverride != null && shaderProgram.overrideThisFrame())
{
@@ -473,7 +488,7 @@ public class GlGenericObjectRenderer implements IDhGenericRenderer
}
// update instanced data if needed
if (useInstancedRendering)
if (this.instancedRenderingAvailable)
{
boxGroup.tryUpdateInstancedDataAsync();
@@ -491,7 +506,7 @@ public class GlGenericObjectRenderer implements IDhGenericRenderer
profiler.popPush("rendering");
profiler.push(boxGroup.getResourceLocationNamespace());
profiler.push(boxGroup.getResourceLocationPath());
if (useInstancedRendering)
if (this.instancedRenderingAvailable)
{
this.renderBoxGroupInstanced(shaderProgram, renderEventParam, boxGroup, camPos, profiler);
}
@@ -506,6 +521,7 @@ public class GlGenericObjectRenderer implements IDhGenericRenderer
}
//==========//
// clean up //
//==========//
@@ -105,10 +105,9 @@ public class GlGenericObjectVertexContainer implements IDhGenericObjectVertexBuf
this.materialData[i] = box.material;
}
this.state = GlGenericObjectVertexContainer.EState.READY_TO_UPLOAD;
}
@Override
public void uploadDataToGpu()
{
this.tryCreateBuffers();
@@ -128,8 +127,6 @@ public class GlGenericObjectVertexContainer implements IDhGenericObjectVertexBuf
// Upload materials
GL32.glBindBuffer(GL32.GL_ARRAY_BUFFER, this.material);
GL32.glBufferData(GL32.GL_ARRAY_BUFFER, this.materialData, GL32.GL_DYNAMIC_DRAW);
this.state = EState.RENDER;
}
/** needs to be done on the render thread */
private void tryCreateBuffers()
@@ -220,16 +220,7 @@ public class GLProxy
return instance;
}
public EDhApiGpuUploadMethod getGpuUploadMethod()
{
EDhApiGpuUploadMethod uploadOverride = Config.Client.Advanced.Debugging.OpenGl.glUploadMode.get();
if (uploadOverride == EDhApiGpuUploadMethod.AUTO)
{
return this.preferredUploadMethod;
}
return uploadOverride;
}
public EDhApiGpuUploadMethod getGpuUploadMethod() { return this.preferredUploadMethod; }
public static boolean runningOnRenderThread()
{
@@ -21,6 +21,7 @@ package com.seibel.distanthorizons.common.render.openGl.glObject.buffer;
import com.seibel.distanthorizons.api.enums.config.EDhApiGpuUploadMethod;
import com.seibel.distanthorizons.common.render.openGl.glObject.GLProxy;
import com.seibel.distanthorizons.common.render.openGl.glObject.GLState;
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftGLWrapper;
import com.seibel.distanthorizons.core.config.Config;
import com.seibel.distanthorizons.core.logging.DhLogger;
@@ -78,7 +79,7 @@ public class GLBuffer implements AutoCloseable
static { CLEANUP_THREAD.execute(() -> runPhantomReferenceCleanupLoop()); }
public GLBuffer(boolean isBufferStorage) { this.create(isBufferStorage); }
public GLBuffer(boolean isBufferStorage) { this.destroyOldAndCreate(isBufferStorage); }
//endregion
@@ -104,7 +105,7 @@ public class GLBuffer implements AutoCloseable
//====================//
//region
protected void create(boolean asBufferStorage)
protected void destroyOldAndCreate(boolean asBufferStorage)
{
if (!GLProxy.runningOnRenderThread())
{
@@ -112,10 +113,9 @@ public class GLBuffer implements AutoCloseable
}
// destroy the old buffer if one is present
// (as of 2024-12-31 James didn't see this happen, but just in case)
if (this.id != 0)
{
destroyBufferIdAsync(this.id);
destroyBufferIdNow(this.id);
}
this.id = GLMC.glGenBuffers();
@@ -136,13 +136,21 @@ public class GLBuffer implements AutoCloseable
return;
}
destroyBufferIdAsync(this.id);
final int idToDelete = this.id; // saving the ID to a separate variable is necessary so it can be captured by the lambda
RenderThreadTaskHandler.INSTANCE.queueRunningOnRenderThread("GLBuffer destroyAsync", () -> { destroyBufferIdNow(idToDelete); });
this.id = 0;
this.size = 0;
}
private static void destroyBufferIdAsync(int id)
private static void destroyBufferIdNow(int id)
{
// only delete valid buffers
if (id == 0)
{
LOGGER.warn("Attempted to destroy a buffer with ID 0, VRAM memory leaks may occur.");
return;
}
// remove and clear the phantom reference if present
if (BUFFER_ID_TO_PHANTOM.containsKey(id))
{
@@ -157,21 +165,19 @@ public class GLBuffer implements AutoCloseable
BUFFER_ID_TO_PHANTOM.remove(id);
}
RenderThreadTaskHandler.INSTANCE.queueRunningOnRenderThread(() ->
bufferCount.decrementAndGet();
// destroy the buffer if it exists,
// the buffer may not exist if the destroy method is called twice
if (GL32.glIsBuffer(id))
{
// destroy the buffer if it exists,
// the buffer may not exist if the destroy method is called twice
if (GL32.glIsBuffer(id))
GLMC.glDeleteBuffers(id);
if (Config.Client.Advanced.Debugging.logBufferGarbageCollection.get())
{
GLMC.glDeleteBuffers(id);
bufferCount.decrementAndGet();
if (Config.Client.Advanced.Debugging.logBufferGarbageCollection.get())
{
LOGGER.info("destroyed buffer [" + id + "], remaining: [" + BUFFER_ID_TO_PHANTOM.size() + "]");
}
LOGGER.info("destroyed buffer [" + id + "], remaining: [" + BUFFER_ID_TO_PHANTOM.size() + "]");
}
});
}
}
//endregion
@@ -202,36 +208,46 @@ public class GLBuffer implements AutoCloseable
return;
}
// make sure the buffer is ready for uploading
this.createOrChangeBufferTypeForUpload(uploadMethod);
switch (uploadMethod)
// re-binding the old VBO is necessary for old MC versions (IE 1.16.5 and older)
// otherwise the screen may be black when on the home menu
int previousBoundVbo = GL32.glGetInteger(GL32.GL_ARRAY_BUFFER_BINDING);
try
{
//case NONE:
// return;
case AUTO:
LodUtil.assertNotReach("GpuUploadMethod AUTO must be resolved before call to uploadBuffer()!");
case BUFFER_STORAGE:
this.uploadBufferStorage(bb, bufferHint);
break;
case DATA:
this.uploadBufferData(bb, bufferHint);
break;
case SUB_DATA:
this.uploadSubData(bb, maxExpansionSize, bufferHint);
break;
default:
LodUtil.assertNotReach("Unknown GpuUploadMethod!");
// make sure the buffer is ready for uploading
this.createOrChangeBufferTypeForUpload(uploadMethod);
switch (uploadMethod)
{
case AUTO:
LodUtil.assertNotReach("GpuUploadMethod AUTO must be resolved before call to uploadBuffer()!");
case BUFFER_STORAGE:
this.uploadBufferStorage(bb);
break;
case DATA:
this.uploadBufferData(bb, bufferHint);
break;
case SUB_DATA:
this.uploadSubData(bb, maxExpansionSize, bufferHint);
break;
default:
LodUtil.assertNotReach("Unknown GpuUploadMethod!");
}
}
finally
{
GL32.glBindBuffer(GL32.GL_ARRAY_BUFFER, GL32.glIsBuffer(previousBoundVbo) ? previousBoundVbo : 0);
}
}
/** Requires the buffer to be bound */
protected void uploadBufferStorage(ByteBuffer bb, int bufferStorageHint)
protected void uploadBufferStorage(ByteBuffer bb)
{
LodUtil.assertTrue(this.bufferStorage, "Buffer is not bufferStorage but its trying to use bufferStorage upload method!");
int bbSize = bb.limit() - bb.position();
this.destroyAsync();
this.create(true);
this.destroyOldAndCreate(true);
this.bind();
GL44.glBufferStorage(this.getBufferBindingTarget(), bb, 0);
this.size = bbSize;
@@ -300,8 +316,8 @@ public class GLBuffer implements AutoCloseable
{
// recreate if the buffer storage type changed
this.bind();
this.destroyAsync();
this.create(uploadMethod.useBufferStorage);
destroyBufferIdNow(this.id);
this.destroyOldAndCreate(uploadMethod.useBufferStorage);
this.bind();
}
else
@@ -310,7 +326,7 @@ public class GLBuffer implements AutoCloseable
// This can happen if the buffer was deleted previously.
if (this.id == 0)
{
this.create(this.bufferStorage);
this.destroyOldAndCreate(this.bufferStorage);
}
this.bind();
@@ -346,7 +362,7 @@ public class GLBuffer implements AutoCloseable
if (PHANTOM_TO_BUFFER_ID.containsKey(phantomRef))
{
int id = PHANTOM_TO_BUFFER_ID.get(phantomRef);
destroyBufferIdAsync(id);
RenderThreadTaskHandler.INSTANCE.queueRunningOnRenderThread("GLBuffer phantom destroy", () -> { destroyBufferIdNow(id); });
//LOGGER.warn("Buffer Phantom collected, ID: ["+id+"]");
}
@@ -22,24 +22,22 @@ package com.seibel.distanthorizons.common.render.openGl.glObject.buffer;
import org.lwjgl.opengl.GL32;
/**
* This is a container for a OpenGL
* VBO (Vertex Buffer Object).
* AKA the GLElementBuffer
*
* @author James Seibel
* @version 11-20-2021
*/
public class GLElementBuffer extends GLBuffer
public class GLIndexBuffer extends GLBuffer
{
/**
* When uploading to a buffer that is too small, recreate it this many times
* bigger than the upload payload
*/
protected int indicesCount = 0;
public int getIndicesCount() { return this.indicesCount; }
protected int type = GL32.GL_UNSIGNED_INT;
public int getType() { return type; }
protected int glType = GL32.GL_UNSIGNED_INT;
public int getGlType() { return this.glType; }
public GLElementBuffer(boolean isBufferStorage)
public GLIndexBuffer(boolean isBufferStorage)
{
super(isBufferStorage);
}
@@ -52,9 +50,6 @@ public class GLElementBuffer extends GLBuffer
}
@Override
public int getBufferBindingTarget()
{
return GL32.GL_ELEMENT_ARRAY_BUFFER;
}
public int getBufferBindingTarget() { return GL32.GL_ELEMENT_ARRAY_BUFFER; }
}
@@ -23,6 +23,10 @@ import java.nio.ByteBuffer;
import com.seibel.distanthorizons.common.render.openGl.glObject.GLProxy;
import com.seibel.distanthorizons.core.dataObjects.render.bufferBuilding.LodQuadBuilder;
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
import com.seibel.distanthorizons.core.jar.EPlatform;
import com.seibel.distanthorizons.core.render.RenderThreadTaskHandler;
import com.seibel.distanthorizons.core.wrapperInterfaces.render.AbstractDhRenderApiDefinition;
import com.seibel.distanthorizons.core.wrapperInterfaces.render.objects.IVertexBufferWrapper;
import org.lwjgl.opengl.GL32;
@@ -37,6 +41,8 @@ import com.seibel.distanthorizons.api.enums.config.EDhApiGpuUploadMethod;
*/
public class GLVertexBuffer extends GLBuffer implements IVertexBufferWrapper
{
private static final AbstractDhRenderApiDefinition RENDER_DEF = SingletonInjector.INSTANCE.get(AbstractDhRenderApiDefinition.class);
/**
* When uploading to a buffer that is too small, recreate it this many times
* bigger than the upload payload
@@ -45,12 +51,43 @@ public class GLVertexBuffer extends GLBuffer implements IVertexBufferWrapper
public int getVertexCount() { return this.vertexCount; }
private GlQuadIndexBuffer quadIBO = null;
private static GlQuadIndexBuffer GLOBAL_QUAD_IBO = null;
public GlQuadIndexBuffer getQuadIBO()
{
if (RENDER_DEF.useSingleIbo())
{
return GLOBAL_QUAD_IBO;
}
else
{
return this.quadIBO;
}
}
//=============//
// constructor //
//=============//
//region
static
{
if (RENDER_DEF.useSingleIbo())
{
RenderThreadTaskHandler.INSTANCE.queueRunningOnRenderThread("Global IBO Creation", () ->
{
GLOBAL_QUAD_IBO = new GlQuadIndexBuffer();
int maxSize = LodQuadBuilder.getMaxBufferByteSize();
int maxVertexCount = maxSize / LodQuadBuilder.BYTES_PER_VERTEX;
int maxQuadCount = (maxVertexCount / 4);
GLOBAL_QUAD_IBO.upload(maxQuadCount);
});
}
}
public GLVertexBuffer() { this(GLProxy.getInstance().getGpuUploadMethod() == EDhApiGpuUploadMethod.BUFFER_STORAGE); }
public GLVertexBuffer(boolean isBufferStorage) { super(isBufferStorage); }
@@ -67,7 +104,7 @@ public class GLVertexBuffer extends GLBuffer implements IVertexBufferWrapper
public int getBufferBindingTarget() { return GL32.GL_ARRAY_BUFFER; }
@Override
public void upload(ByteBuffer buffer, int vertexCount)
public void uploadVertexBuffer(ByteBuffer buffer, int vertexCount)
{
EDhApiGpuUploadMethod uploadMethod = GLProxy.getInstance().getGpuUploadMethod();
int maxBufferSize = LodQuadBuilder.getMaxBufferByteSize();
@@ -89,19 +126,60 @@ public class GLVertexBuffer extends GLBuffer implements IVertexBufferWrapper
// If size is zero, just ignore it.
if (byteBuffer.limit() - byteBuffer.position() != 0)
{
boolean useBuffStorage = uploadMethod.useBufferStorage;
super.uploadBuffer(byteBuffer, uploadMethod, maxExpansionSize, useBuffStorage ? 0 : GL32.GL_STATIC_DRAW);
super.uploadBuffer(byteBuffer, uploadMethod, maxExpansionSize, uploadMethod.useBufferStorage ? 0 : GL32.GL_STATIC_DRAW);
}
this.vertexCount = vertexCount;
}
@Override
public void uploadIndexBuffer(ByteBuffer buffer, int vertexCount)
{
if (RENDER_DEF.useSingleIbo())
{
// ignore index uploading when running a single IBO
return;
}
// If size is zero, just ignore it.
if (vertexCount == 0)
{
return;
}
if (this.quadIBO != null)
{
this.quadIBO.close();
}
this.quadIBO = new GlQuadIndexBuffer();
int quadCount = (vertexCount / 4);
this.quadIBO.upload(quadCount);
}
//endregion
//================//
// base overrides //
//================//
//region
@Override
public void close() { this.destroyAsync(); }
@Override
public void destroyAsync()
{
super.destroyAsync();
if (this.quadIBO != null)
{
this.quadIBO.destroyAsync();
}
this.vertexCount = 0;
}
@@ -1,192 +0,0 @@
/*
* This file is part of the Distant Horizons mod
* licensed under the GNU LGPL v3 License.
*
* Copyright (C) 2020 James Seibel
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.seibel.distanthorizons.common.render.openGl.glObject.buffer;
import com.seibel.distanthorizons.api.enums.config.EDhApiGpuUploadMethod;
import com.seibel.distanthorizons.common.render.openGl.glObject.enums.GLEnums;
import com.seibel.distanthorizons.core.logging.DhLogger;
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import org.lwjgl.opengl.GL32;
import org.lwjgl.system.MemoryUtil;
import java.nio.ByteBuffer;
/** AKA Index Buffer TODO RENAME */
public class GlQuadElementBuffer extends GLElementBuffer
{
private static final DhLogger LOGGER = new DhLoggerBuilder().build();
//=============//
// constructor //
//=============//
//region
public GlQuadElementBuffer() { super(false); }
public void reserve(int quadCount)
{
if (quadCount < 0)
{
throw new IllegalArgumentException("quadCount must be greater than 0");
}
if (quadCount == 0)
{
// shouldn't happen, but just in case
return;
}
this.indicesCount = quadCount * 6; // 2 triangles per quad
if (this.indicesCount >= this.getCapacity()
&& this.indicesCount < this.getCapacity() * BUFFER_SHRINK_TRIGGER)
{
return;
}
int vertexCount = quadCount * 4; // 4 vertices per quad
if (vertexCount < 255)
{
// Reserve 1 for the reset index
this.type = GL32.GL_UNSIGNED_BYTE;
}
else if (vertexCount < 65535)
{
// Reserve 1 for the reset index
this.type = GL32.GL_UNSIGNED_SHORT;
}
else
{
this.type = GL32.GL_UNSIGNED_INT;
}
ByteBuffer buffer = MemoryUtil.memAlloc(this.indicesCount * GLEnums.getTypeSize(this.type));
buildBuffer(quadCount, buffer, this.type);
this.bind();
super.uploadBuffer(buffer, EDhApiGpuUploadMethod.DATA,
this.indicesCount * GLEnums.getTypeSize(this.type), GL32.GL_STATIC_DRAW);
MemoryUtil.memFree(buffer);
}
//endregion
//=========//
// getters //
//=========//
//region
public int getCapacity() { return super.getSize() / GLEnums.getTypeSize(this.getType()); }
//endregion
//==========//
// building //
//==========//
//region
public static void buildBuffer(int quadCount, ByteBuffer buffer, int type)
{
switch (type)
{
case GL32.GL_UNSIGNED_BYTE:
buildBufferByte(quadCount, buffer);
break;
case GL32.GL_UNSIGNED_SHORT:
buildBufferShort(quadCount, buffer);
break;
case GL32.GL_UNSIGNED_INT:
buildBufferInt(quadCount, buffer);
break;
default:
throw new IllegalStateException("Unknown buffer type: [" + type + "].");
}
}
private static void buildBufferByte(int quadCount, ByteBuffer buffer)
{
for (int i = 0; i < quadCount; i++)
{
int vIndex = i * 4;
// First triangle
buffer.put((byte) (vIndex));
buffer.put((byte) (vIndex + 1));
buffer.put((byte) (vIndex + 2));
// Second triangle
buffer.put((byte) (vIndex + 2));
buffer.put((byte) (vIndex + 3));
buffer.put((byte) (vIndex));
}
if (buffer.hasRemaining())
{
throw new IllegalStateException("QuadElementBuffer is not full somehow after building");
}
buffer.rewind();
}
private static void buildBufferShort(int quadCount, ByteBuffer buffer)
{
for (int i = 0; i < quadCount; i++)
{
int vIndex = i * 4;
// First triangle
buffer.putShort((short) (vIndex));
buffer.putShort((short) (vIndex + 1));
buffer.putShort((short) (vIndex + 2));
// Second triangle
buffer.putShort((short) (vIndex + 2));
buffer.putShort((short) (vIndex + 3));
buffer.putShort((short) (vIndex));
}
if (buffer.hasRemaining())
{
throw new IllegalStateException("QuadElementBuffer is not full somehow after building");
}
buffer.rewind();
}
private static void buildBufferInt(int quadCount, ByteBuffer buffer)
{
for (int i = 0; i < quadCount; i++)
{
int vIndex = i * 4;
// First triangle
buffer.putInt(vIndex);
buffer.putInt(vIndex + 1);
buffer.putInt(vIndex + 2);
// Second triangle
buffer.putInt(vIndex + 2);
buffer.putInt(vIndex + 3);
buffer.putInt(vIndex);
}
if (buffer.hasRemaining())
{
throw new IllegalStateException("QuadElementBuffer is not full somehow after building");
}
buffer.rewind();
}
//endregion
}
@@ -0,0 +1,89 @@
/*
* This file is part of the Distant Horizons mod
* licensed under the GNU LGPL v3 License.
*
* Copyright (C) 2020 James Seibel
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.seibel.distanthorizons.common.render.openGl.glObject.buffer;
import com.seibel.distanthorizons.api.enums.config.EDhApiGpuUploadMethod;
import com.seibel.distanthorizons.common.render.openGl.glObject.enums.GLEnums;
import com.seibel.distanthorizons.core.dataObjects.render.bufferBuilding.IndexBufferBuilder;
import com.seibel.distanthorizons.core.logging.DhLogger;
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import org.lwjgl.opengl.GL32;
import org.lwjgl.system.MemoryUtil;
import java.nio.ByteBuffer;
/** aka GlQuadElementBuffer */
public class GlQuadIndexBuffer extends GLIndexBuffer
{
private static final DhLogger LOGGER = new DhLoggerBuilder().build();
//=============//
// constructor //
//=============//
//region
public GlQuadIndexBuffer() { super(false); }
public void upload(int quadCount)
{
if (quadCount < 0)
{
throw new IllegalArgumentException("quadCount must be greater than 0");
}
if (quadCount == 0)
{
// shouldn't happen, but just in case
return;
}
this.indicesCount = quadCount * 6; // 2 triangles per quad
if (this.indicesCount >= this.getCapacity()
&& this.indicesCount < this.getCapacity() * BUFFER_SHRINK_TRIGGER)
{
return;
}
this.glType = GL32.GL_UNSIGNED_INT;
ByteBuffer buffer = IndexBufferBuilder.createBuffer(quadCount);
this.bind();
super.uploadBuffer(buffer, EDhApiGpuUploadMethod.DATA,
this.indicesCount * GLEnums.getTypeSize(this.glType), GL32.GL_STATIC_DRAW);
MemoryUtil.memFree(buffer);
}
//endregion
//=========//
// getters //
//=========//
//region
public int getCapacity() { return super.getSize() / GLEnums.getTypeSize(this.getGlType()); }
//endregion
}
@@ -57,7 +57,7 @@ public class GlDhApplyShader extends GlAbstractShaderRenderer
public void onInit()
{
this.shader = new GlShaderProgram(
"assets/distanthorizons/shaders/shared/gl/quadApply.vert",
"assets/distanthorizons/shaders/shared/gl/quad_apply.vert",
"assets/distanthorizons/shaders/shared/gl/apply.frag",
"vPosition"
);
@@ -59,7 +59,7 @@ public class GlDhFarFadeApplyShader extends GlAbstractShaderRenderer
public void onInit()
{
this.shader = new GlShaderProgram(
"assets/distanthorizons/shaders/shared/gl/quadApply.vert",
"assets/distanthorizons/shaders/shared/gl/quad_apply.vert",
"assets/distanthorizons/shaders/fade/gl/apply.frag",
"vPosition"
);
@@ -69,8 +69,8 @@ public class GlDhFarFadeShader extends GlAbstractShaderRenderer
public void onInit()
{
this.shader = new GlShaderProgram(
"assets/distanthorizons/shaders/shared/gl/quadApply.vert",
"assets/distanthorizons/shaders/fade/gl/dhFade.frag",
"assets/distanthorizons/shaders/shared/gl/quad_apply.vert",
"assets/distanthorizons/shaders/fade/gl/dh_fade.frag",
"vPosition"
);
@@ -77,8 +77,8 @@ public class GlDhVanillaFadeShader extends GlAbstractShaderRenderer
public void onInit()
{
this.shader = new GlShaderProgram(
"assets/distanthorizons/shaders/shared/gl/quadApply.vert",
"assets/distanthorizons/shaders/fade/gl/vanillaFade.frag",
"assets/distanthorizons/shaders/shared/gl/quad_apply.vert",
"assets/distanthorizons/shaders/fade/gl/vanilla_fade.frag",
"vPosition"
);
@@ -168,7 +168,7 @@ public class GlVanillaFadeRenderer implements IDhVanillaFadeRenderer
profiler.popPush("Vanilla Fade Apply");
GlDhFarFadeApplyShader.INSTANCE.fadeTexture = this.fadeTexture;
GlDhFarFadeApplyShader.INSTANCE.readFramebuffer = GlDhFarFadeShader.INSTANCE.frameBuffer;
GlDhFarFadeApplyShader.INSTANCE.readFramebuffer = GlDhVanillaFadeShader.INSTANCE.frameBuffer;
GlDhFarFadeApplyShader.INSTANCE.drawFramebuffer = MC_RENDER.getTargetFramebuffer();
GlDhFarFadeApplyShader.INSTANCE.render(renderParams);
}
@@ -57,7 +57,7 @@ public class GlDhFogApplyShader extends GlAbstractShaderRenderer
public void onInit()
{
this.shader = new GlShaderProgram(
"assets/distanthorizons/shaders/shared/gl/quadApply.vert",
"assets/distanthorizons/shaders/shared/gl/quad_apply.vert",
"assets/distanthorizons/shaders/fog/gl/apply.frag",
"vPosition"
);
@@ -109,7 +109,7 @@ public class GlDhFogShader extends GlAbstractShaderRenderer
public void onInit()
{
this.shader = new GlShaderProgram(
"assets/distanthorizons/shaders/shared/gl/quadApply.vert",
"assets/distanthorizons/shaders/shared/gl/quad_apply.vert",
"assets/distanthorizons/shaders/fog/gl/fog.frag",
"vPosition"
);
@@ -62,7 +62,7 @@ public class GlDhSSAOApplyShader extends GlAbstractShaderRenderer
public void onInit()
{
this.shader = new GlShaderProgram(
"assets/distanthorizons/shaders/shared/gl/quadApply.vert",
"assets/distanthorizons/shaders/shared/gl/quad_apply.vert",
"assets/distanthorizons/shaders/ssao/gl/apply.frag",
"vPosition"
);
@@ -70,7 +70,7 @@ public class GlDhSSAOShader extends GlAbstractShaderRenderer
public void onInit()
{
this.shader = new GlShaderProgram(
"assets/distanthorizons/shaders/shared/gl/quadApply.vert",
"assets/distanthorizons/shaders/shared/gl/quad_apply.vert",
"assets/distanthorizons/shaders/ssao/gl/ao.frag",
"vPosition"
);
@@ -1,31 +1,12 @@
/*
* This file is part of the Distant Horizons mod
* licensed under the GNU LGPL v3 License.
*
* Copyright (C) 2020 James Seibel
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.seibel.distanthorizons.common.render.openGl;
package com.seibel.distanthorizons.common.render.openGl.terrain;
import com.seibel.distanthorizons.api.interfaces.override.rendering.IDhApiShaderProgram;
import com.seibel.distanthorizons.api.methods.events.abstractEvents.*;
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiRenderParam;
import com.seibel.distanthorizons.api.objects.math.DhApiVec3f;
import com.seibel.distanthorizons.common.render.openGl.GlDhMetaRenderer;
import com.seibel.distanthorizons.common.render.openGl.glObject.GLProxy;
import com.seibel.distanthorizons.common.render.openGl.glObject.buffer.GLVertexBuffer;
import com.seibel.distanthorizons.common.render.openGl.glObject.buffer.GlQuadElementBuffer;
import com.seibel.distanthorizons.common.render.openGl.glObject.shader.GlShaderProgram;
import com.seibel.distanthorizons.common.render.openGl.glObject.vertexAttribute.GlAbstractVertexAttribute;
import com.seibel.distanthorizons.common.render.openGl.glObject.vertexAttribute.GlVertexAttributePostGL43;
@@ -49,29 +30,26 @@ import com.seibel.distanthorizons.core.util.objects.SortedArraySet;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IProfilerWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IIrisAccessor;
import com.seibel.distanthorizons.core.wrapperInterfaces.render.objects.IVertexBufferWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass.IDhTerrainRenderer;
import com.seibel.distanthorizons.coreapi.DependencyInjection.ApiEventInjector;
import org.lwjgl.opengl.GL32;
/**
* Handles rendering the normal LOD terrain.
* @see LodQuadBuilder
* @see LodQuadBuilder
*/
public class GlDhTerrainShaderProgram extends GlShaderProgram implements IDhApiShaderProgram, IDhTerrainRenderer
public class GlDhTerrainShaderProgram extends GlShaderProgram implements IDhApiShaderProgram
{
public static final DhLogger LOGGER = new DhLoggerBuilder()
.fileLevelConfig(Config.Common.Logging.logRendererEventToFile)
.build();
public static final GlDhTerrainShaderProgram INSTANCE = new GlDhTerrainShaderProgram();
private static final MinecraftGLWrapper GLMC = MinecraftGLWrapper.INSTANCE;
private static final IIrisAccessor IRIS_ACCESSOR = ModAccessorInjector.INSTANCE.get(IIrisAccessor.class);
private boolean init = false;
public GlQuadElementBuffer quadIBO = null;
public final GlAbstractVertexAttribute vao;
public GlAbstractVertexAttribute vao;
// uniforms //
//region
@@ -106,13 +84,22 @@ public class GlDhTerrainShaderProgram extends GlShaderProgram implements IDhApiS
//=============//
//region
private GlDhTerrainShaderProgram()
public GlDhTerrainShaderProgram()
{
super(
"assets/distanthorizons/shaders/shared/gl/standard.vert",
"assets/distanthorizons/shaders/shared/gl/flat_shaded.frag",
new String[]{"vPosition", "color"}
);
}
public void tryInit()
{
if (this.init)
{
return;
}
this.uCombinedMatrix = this.getUniformLocation("uCombinedMatrix");
this.uModelOffset = this.getUniformLocation("uModelOffset");
@@ -165,6 +152,10 @@ public class GlDhTerrainShaderProgram extends GlShaderProgram implements IDhApiS
throw e;
}
// unbinding here is necessary to fix an issue when running on Legacy GL
this.vao.unbind();
this.init = true;
}
//endregion
@@ -179,6 +170,7 @@ public class GlDhTerrainShaderProgram extends GlShaderProgram implements IDhApiS
@Override
public void bind()
{
this.tryInit();
super.bind();
this.vao.bind();
}
@@ -206,7 +198,7 @@ public class GlDhTerrainShaderProgram extends GlShaderProgram implements IDhApiS
combinedMatrix.multiply(renderParameters.dhModelViewMatrix);
super.bind();
// uniforms
this.setUniform(this.uCombinedMatrix, combinedMatrix);
this.setUniform(this.uMircoOffset, 0.01f); // 0.01 block offset
@@ -267,7 +259,6 @@ public class GlDhTerrainShaderProgram extends GlShaderProgram implements IDhApiS
//===========//
//region
@Override
public void render(RenderParams renderEventParam, boolean opaquePass, SortedArraySet<LodBufferContainer> bufferContainers, IProfilerWrapper profiler)
{
//=======================//
@@ -337,7 +328,7 @@ public class GlDhTerrainShaderProgram extends GlShaderProgram implements IDhApiS
ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeBufferRenderEvent.class, new DhApiBeforeBufferRenderEvent.EventParam(renderEventParam, modelPos));
}
IVertexBufferWrapper[] vertexBuffers = (opaquePass ? bufferContainer.vbos : bufferContainer.vbosTransparent);
IVertexBufferWrapper[] vertexBuffers = (opaquePass ? bufferContainer.vboOpaqueWrappers : bufferContainer.vboTransparentWrappers);
for (int vboIndex = 0; vboIndex < vertexBuffers.length; vboIndex++)
{
GLVertexBuffer vbo = (GLVertexBuffer) vertexBuffers[vboIndex];
@@ -355,12 +346,16 @@ public class GlDhTerrainShaderProgram extends GlShaderProgram implements IDhApiS
int indexCount = (int)(vbo.getVertexCount() * 1.5);
vbo.bind();
vbo.getQuadIBO().bind();
GlDhMetaRenderer.INSTANCE.shaderProgramForThisFrame.bindVertexBuffer(vbo.getId());
GL32.glDrawElements(
GL32.GL_TRIANGLES,
indexCount,
this.quadIBO.getType(), 0);
vbo.getQuadIBO().getGlType(), 0);
vbo.unbind();
vbo.getQuadIBO().unbind();
}
}
}
@@ -384,4 +379,4 @@ public class GlDhTerrainShaderProgram extends GlShaderProgram implements IDhApiS
}
}
@@ -80,37 +80,55 @@ public class DependencySetup
SingletonInjector.INSTANCE.bind(IConfigGui.class, ClassicConfigGUI.CONFIG_CORE_INTERFACE);
}
/** will be called from a DH thread, not the render thread */
public static void setRenderingApiBindings()
{
EDhApiRenderApi renderingApiEnum = Config.Client.Advanced.Graphics.Experimental.renderingApi.get();
if (renderingApiEnum == EDhApiRenderApi.AUTO)
{
#if MC_VER < MC_1_21_11
renderingApiEnum = EDhApiRenderApi.OPEN_GL;
#else
renderingApiEnum = EDhApiRenderApi.BLAZE_3D;
#endif
IVersionConstants versionConstants = SingletonInjector.INSTANCE.get(IVersionConstants.class);
renderingApiEnum = versionConstants.getDefaultRenderingApi();
}
LOGGER.info("Setting DH Rendering API to: ["+renderingApiEnum+"].");
boolean validApi;
AbstractDhRenderApiDefinition renderDefinition;
if (renderingApiEnum == EDhApiRenderApi.OPEN_GL)
{
validApi = true;
renderDefinition = new GlDhRenderApiDefinition();
}
else if (renderingApiEnum == EDhApiRenderApi.BLAZE_3D)
{
#if MC_VER <= MC_1_21_10
throw new IllegalStateException("["+renderingApiEnum+"] is not supported on this version of Minecraft.");
validApi = false;
renderDefinition = null;
#else
validApi = true;
renderDefinition = new BlazeDhRenderApiDefinition();
#endif
}
else
{
throw new IllegalStateException("No ["+ AbstractDhRenderApiDefinition.class.getSimpleName()+"] concrete implementation found for the value: ["+renderingApiEnum+"].");
String message = "No ["+ AbstractDhRenderApiDefinition.class.getSimpleName()+"] concrete implementation found for the value: ["+renderingApiEnum+"].";
LOGGER.fatal(message);
throw new IllegalStateException(message);
}
// crash if an invalid API is set
if (!validApi)
{
String message = "["+renderingApiEnum+"] is not supported on this version of Minecraft, reverting to ["+EDhApiRenderApi.AUTO+"].";
LOGGER.fatal(message);
Config.Client.Advanced.Graphics.Experimental.renderingApi.set(EDhApiRenderApi.AUTO);
throw new IllegalStateException(message);
}
renderDefinition.bindRenderers();
}
@@ -139,7 +139,16 @@ public class McObjectConverter
}
public static BlockPos Convert(DhBlockPos wrappedPos) { return new BlockPos(wrappedPos.getX(), wrappedPos.getY(), wrappedPos.getZ()); }
public static ChunkPos Convert(DhChunkPos wrappedPos) { return new ChunkPos(wrappedPos.getX(), wrappedPos.getZ()); }
public static DhChunkPos Convert(ChunkPos mcPos)
{
#if MC_VER <= MC_1_21_11
return new DhChunkPos(mcPos.x, mcPos.z);
#else
return new DhChunkPos(mcPos.x(), mcPos.z());
#endif
}
public static Direction Convert(EDhDirection lodDirection) { return directions[lodDirection.ordinal()]; }
public static EDhDirection Convert(Direction direction) { return lodDirections[direction.ordinal()]; }
@@ -93,6 +93,8 @@ public class VersionConstants implements IVersionConstants
return "1.21.10";
#elif MC_VER == MC_1_21_11
return "1.21.11";
#elif MC_VER == MC_1_26_1
return "21.6";
#else
ERROR MC version constant missing
#endif
@@ -102,7 +104,7 @@ public class VersionConstants implements IVersionConstants
@Override
public EDhApiRenderApi getDefaultRenderingApi()
{
#if MC_VER <= MC_1_21_11
#if MC_VER <= MC_1_26_1
return EDhApiRenderApi.OPEN_GL;
#else
ERROR MC version constant missing
@@ -147,16 +147,19 @@ public class WrapperFactory implements IWrapperFactory
public IBlockStateWrapper deserializeBlockStateWrapper(String str, ILevelWrapper levelWrapper) throws IOException { return BlockStateWrapper.deserialize(str, levelWrapper); }
@Override
public IBlockStateWrapper getAirBlockStateWrapper() { return BlockStateWrapper.AIR; }
@Override
public IBlockStateWrapper getWaterBlockStateWrapper(ILevelWrapper levelWrapper) { return BlockStateWrapper.getWaterBlockStateWrapper(levelWrapper); }
@Override
public ObjectOpenHashSet<IBlockStateWrapper> getRendererIgnoredBlocks(ILevelWrapper levelWrapper) { return BlockStateWrapper.getRendererIgnoredBlocks(levelWrapper); }
@Override
public ObjectOpenHashSet<IBlockStateWrapper> getRendererIgnoredCaveBlocks(ILevelWrapper levelWrapper) { return BlockStateWrapper.getRendererIgnoredCaveBlocks(levelWrapper); }
@Override
public ObjectOpenHashSet<IBlockStateWrapper> getWaterSubsurfaceReplacementBlocks(ILevelWrapper levelWrapper) { return BlockStateWrapper.getWaterSubsurfaceReplacementBlocks(levelWrapper); }
@Override
public ObjectOpenHashSet<IBlockStateWrapper> getWaterSurfaceReplacementBlocks(ILevelWrapper levelWrapper) { return BlockStateWrapper.getWaterSurfaceReplacementBlocks(levelWrapper); }
@Override
public void resetRendererIgnoredCaveBlocks() { BlockStateWrapper.clearRendererIgnoredCaveBlocks(); }
@Override
public void resetRendererIgnoredBlocksSet() { BlockStateWrapper.clearRendererIgnoredBlocks(); }
public void resetCachedIgnoredBlocksSets() { BlockStateWrapper.clearCachedIgnoreBlocks(); }
/**
@@ -10,11 +10,9 @@ import com.seibel.distanthorizons.core.util.ColorUtil;
import com.seibel.distanthorizons.core.util.FullDataPointUtil;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
import it.unimi.dsi.fastutil.longs.LongArrayList;
import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.BlockAndTintGetter;
import net.minecraft.world.level.ColorResolver;
import net.minecraft.world.level.biome.Biome;
@@ -30,6 +28,11 @@ import org.jetbrains.annotations.Nullable;
import net.minecraft.core.Holder;
#endif
#if MC_VER <= MC_1_21_11
import net.minecraft.world.level.BlockAndTintGetter;
#else
import net.minecraft.client.renderer.block.BlockAndTintGetter;
#endif
public abstract class AbstractDhTintGetter implements BlockAndTintGetter
{
@@ -49,6 +49,7 @@ import net.minecraft.core.registries.Registries;
import net.minecraft.resources.ResourceLocation;
#else
import net.minecraft.resources.Identifier;
import net.minecraft.core.component.DataComponentMap;
#endif
import net.minecraft.world.level.biome.Biome;
@@ -221,17 +222,17 @@ public class BiomeWrapper implements IBiomeWrapper
Level level = (Level)levelWrapper.getWrappedMcObject();
net.minecraft.core.RegistryAccess registryAccess = level.registryAccess();
#if MC_VER < MC_1_21_11
#if MC_VER <= MC_1_21_10
ResourceLocation resourceLocation;
#else
Identifier resourceLocation;
#endif
#if MC_VER == MC_1_16_5 || MC_VER == MC_1_17_1
#if MC_VER <= MC_1_17_1
resourceLocation = registryAccess.registryOrThrow(Registry.BIOME_REGISTRY).getKey(this.biome);
#elif MC_VER == MC_1_18_2 || MC_VER == MC_1_19_2
#elif MC_VER <= MC_1_19_2
resourceLocation = registryAccess.registryOrThrow(Registry.BIOME_REGISTRY).getKey(this.biome.value());
#elif MC_VER < MC_1_21_3
#elif MC_VER <= MC_1_21_4
resourceLocation = registryAccess.registryOrThrow(Registries.BIOME).getKey(this.biome.value());
#else
resourceLocation = registryAccess.lookupOrThrow(Registries.BIOME).getKey(this.biome.value());
@@ -240,7 +241,7 @@ public class BiomeWrapper implements IBiomeWrapper
if (resourceLocation == null)
{
String biomeName;
#if MC_VER == MC_1_16_5 || MC_VER == MC_1_17_1
#if MC_VER <= MC_1_17_1
biomeName = this.biome.toString();
#else
biomeName = this.biome.value().toString();
@@ -354,18 +355,18 @@ public class BiomeWrapper implements IBiomeWrapper
boolean success;
#if MC_VER == MC_1_16_5 || MC_VER == MC_1_17_1
#if MC_VER <= MC_1_17_1
Biome biome = registryAccess.registryOrThrow(Registry.BIOME_REGISTRY).get(resourceLocation);
success = (biome != null);
#elif MC_VER == MC_1_18_2 || MC_VER == MC_1_19_2
#elif MC_VER <= MC_1_19_2
Biome unwrappedBiome = registryAccess.registryOrThrow(Registry.BIOME_REGISTRY).get(resourceLocation);
success = (unwrappedBiome != null);
Holder<Biome> biome = new Holder.Direct<>(unwrappedBiome);
#elif MC_VER < MC_1_21_3
#elif MC_VER <= MC_1_21_4
Biome unwrappedBiome = registryAccess.registryOrThrow(Registries.BIOME).get(resourceLocation);
success = (unwrappedBiome != null);
Holder<Biome> biome = new Holder.Direct<>(unwrappedBiome);
#else
#elif MC_VER <= MC_1_21_11
Holder<Biome> biome;
Optional<Holder.Reference<Biome>> optionalBiomeHolder = registryAccess.lookupOrThrow(Registries.BIOME).get(resourceLocation);
if (optionalBiomeHolder.isPresent())
@@ -379,6 +380,20 @@ public class BiomeWrapper implements IBiomeWrapper
success = false;
biome = null;
}
#else
Holder<Biome> biome;
Optional<Holder.Reference<Biome>> optionalBiomeHolder = registryAccess.lookupOrThrow(Registries.BIOME).get(resourceLocation);
if (optionalBiomeHolder.isPresent())
{
Biome unwrappedBiome = optionalBiomeHolder.get().value();
success = (unwrappedBiome != null);
biome = new Holder.Direct<>(unwrappedBiome, DataComponentMap.EMPTY);
}
else
{
success = false;
biome = null;
}
#endif
return new BiomeDeserializeResult(success, biome);
@@ -20,6 +20,7 @@
package com.seibel.distanthorizons.common.wrappers.block;
import com.seibel.distanthorizons.api.enums.rendering.EDhApiBlockMaterial;
import com.seibel.distanthorizons.common.wrappers.WrapperFactory;
import com.seibel.distanthorizons.core.config.Config;
import com.seibel.distanthorizons.core.config.types.ConfigEntry;
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
@@ -44,7 +45,6 @@ import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Stream;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
#if MC_VER == MC_1_16_5 || MC_VER == MC_1_17_1
@@ -95,6 +95,9 @@ public class BlockStateWrapper implements IBlockStateWrapper
public static ObjectOpenHashSet<IBlockStateWrapper> rendererIgnoredBlocks = null;
public static ObjectOpenHashSet<IBlockStateWrapper> rendererIgnoredCaveBlocks = null;
public static ObjectOpenHashSet<IBlockStateWrapper> waterSubsurfaceReplacementBlocks = null;
public static ObjectOpenHashSet<IBlockStateWrapper> waterSurfaceReplacementBlocks = null;
public static IBlockStateWrapper waterBlock = null;
/** keep track of broken blocks so we don't log every time */
#if MC_VER <= MC_1_21_10
@@ -211,7 +214,14 @@ public class BlockStateWrapper implements IBlockStateWrapper
if (blockState != null)
{
// check if this block has any tags
Stream<TagKey<Block>> tags = blockState.getTags();
Stream<TagKey<Block>> tags;
#if MC_VER <= MC_1_21_11
tags = blockState.getTags();
#else
tags = blockState.tags();
#endif
this.isBeaconBaseBlock = tags.anyMatch((TagKey<Block> tag) -> tag.location().getPath().toLowerCase().contains("beacon_base_blocks"));
}
else
@@ -312,10 +322,12 @@ public class BlockStateWrapper implements IBlockStateWrapper
//====================//
//region
/**
* Requires a {@link ILevelWrapper} since {@link BlockStateWrapper#deserialize(String,ILevelWrapper)} also requires one.
/**
* Each of the following methods require
* a {@link ILevelWrapper} since {@link BlockStateWrapper#deserialize(String,ILevelWrapper)} also requires one.
* This way the method won't accidentally be called before the deserialization can be completed.
*/
public static ObjectOpenHashSet<IBlockStateWrapper> getRendererIgnoredBlocks(ILevelWrapper levelWrapper)
{
// use the cached version if possible
@@ -329,10 +341,6 @@ public class BlockStateWrapper implements IBlockStateWrapper
rendererIgnoredBlocks = getAllBlockWrappers(Config.Client.Advanced.Graphics.Culling.ignoredRenderBlockCsv, baseIgnoredBlock, levelWrapper);
return rendererIgnoredBlocks;
}
/**
* Requires a {@link ILevelWrapper} since {@link BlockStateWrapper#deserialize(String,ILevelWrapper)} also requires one.
* This way the method won't accidentally be called before the deserialization can be completed.
*/
public static ObjectOpenHashSet<IBlockStateWrapper> getRendererIgnoredCaveBlocks(ILevelWrapper levelWrapper)
{
// use the cached version if possible
@@ -346,9 +354,50 @@ public class BlockStateWrapper implements IBlockStateWrapper
rendererIgnoredCaveBlocks = getAllBlockWrappers(Config.Client.Advanced.Graphics.Culling.ignoredRenderCaveBlockCsv, baseIgnoredBlock, levelWrapper);
return rendererIgnoredCaveBlocks;
}
public static ObjectOpenHashSet<IBlockStateWrapper> getWaterSurfaceReplacementBlocks(ILevelWrapper levelWrapper)
{
// use the cached version if possible
if (waterSurfaceReplacementBlocks != null)
{
return waterSurfaceReplacementBlocks;
}
ObjectOpenHashSet<String> baseIgnoredBlock = new ObjectOpenHashSet<>();
waterSurfaceReplacementBlocks = getAllBlockWrappers(Config.Client.Advanced.Graphics.Culling.waterSurfaceBlockReplacementCsv, baseIgnoredBlock, levelWrapper);
return waterSurfaceReplacementBlocks;
}
public static ObjectOpenHashSet<IBlockStateWrapper> getWaterSubsurfaceReplacementBlocks(ILevelWrapper levelWrapper)
{
// use the cached version if possible
if (waterSubsurfaceReplacementBlocks != null)
{
return waterSubsurfaceReplacementBlocks;
}
ObjectOpenHashSet<String> baseIgnoredBlock = new ObjectOpenHashSet<>();
waterSubsurfaceReplacementBlocks = getAllBlockWrappers(Config.Client.Advanced.Graphics.Culling.waterSubSurfaceBlockReplacementCsv, baseIgnoredBlock, levelWrapper);
return waterSubsurfaceReplacementBlocks;
}
public static IBlockStateWrapper getWaterBlockStateWrapper(ILevelWrapper levelWrapper)
{
// use the cached version if possible
if (waterBlock != null)
{
return waterBlock;
}
waterBlock = WrapperFactory.INSTANCE.deserializeBlockStateWrapperOrGetDefault("minecraft:water", levelWrapper);
return waterBlock;
}
public static void clearRendererIgnoredBlocks() { rendererIgnoredBlocks = null; }
public static void clearRendererIgnoredCaveBlocks() { rendererIgnoredCaveBlocks = null; }
public static void clearCachedIgnoreBlocks()
{
rendererIgnoredBlocks = null;
rendererIgnoredCaveBlocks = null;
waterSurfaceReplacementBlocks = null;
waterSubsurfaceReplacementBlocks = null;
waterBlock = null;
}
//endregion
@@ -625,22 +674,23 @@ public class BlockStateWrapper implements IBlockStateWrapper
// older versions of MC have a static registry
#if MC_VER > MC_1_17_1
#if MC_VER <= MC_1_16_5
#else
Level level = (Level)levelWrapper.getWrappedMcObject();
net.minecraft.core.RegistryAccess registryAccess = level.registryAccess();
#endif
#if MC_VER < MC_1_21_11
#if MC_VER <= MC_1_21_10
ResourceLocation resourceLocation;
#else
Identifier resourceLocation;
#endif
#if MC_VER == MC_1_16_5 || MC_VER == MC_1_17_1
#if MC_VER <= MC_1_17_1
resourceLocation = Registry.BLOCK.getKey(this.blockState.getBlock());
#elif MC_VER == MC_1_18_2 || MC_VER == MC_1_19_2
#elif MC_VER <= MC_1_19_2
resourceLocation = registryAccess.registryOrThrow(Registry.BLOCK_REGISTRY).getKey(this.blockState.getBlock());
#elif MC_VER < MC_1_21_3
#elif MC_VER <= MC_1_21_4
resourceLocation = registryAccess.registryOrThrow(Registries.BLOCK).getKey(this.blockState.getBlock());
#else
resourceLocation = registryAccess.lookupOrThrow(Registries.BLOCK).getKey(this.blockState.getBlock());
@@ -729,18 +779,19 @@ public class BlockStateWrapper implements IBlockStateWrapper
try
{
#if MC_VER > MC_1_17_1
#if MC_VER <= MC_1_16_5
#else
LodUtil.assertTrue(levelWrapper != null && levelWrapper.getWrappedMcObject() != null);
Level level = (Level)levelWrapper.getWrappedMcObject();
#endif
Block block;
#if MC_VER == MC_1_16_5 || MC_VER == MC_1_17_1
#if MC_VER <= MC_1_17_1
block = Registry.BLOCK.get(resourceLocation);
#elif MC_VER == MC_1_18_2 || MC_VER == MC_1_19_2
#elif MC_VER <= MC_1_19_2
net.minecraft.core.RegistryAccess registryAccess = level.registryAccess();
block = registryAccess.registryOrThrow(Registry.BLOCK_REGISTRY).get(resourceLocation);
#elif MC_VER < MC_1_21_3
#elif MC_VER <= MC_1_21_4
net.minecraft.core.RegistryAccess registryAccess = level.registryAccess();
block = registryAccess.registryOrThrow(Registries.BLOCK).get(resourceLocation);
#else
@@ -27,7 +27,6 @@ import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPosMutable;
import com.seibel.distanthorizons.core.util.ColorUtil;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.block.model.BakedQuad;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.core.Direction;
import net.minecraft.world.level.block.*;
@@ -47,8 +46,13 @@ import java.util.List;
import java.util.concurrent.locks.ReentrantLock;
#if MC_VER < MC_1_21_5
#else
import net.minecraft.client.renderer.block.model.BakedQuad;
#elif MC_VER <= MC_1_21_11
import net.minecraft.client.renderer.block.model.BlockModelPart;
import net.minecraft.client.renderer.block.model.BakedQuad;
#else
import net.minecraft.client.renderer.block.dispatch.BlockStateModelPart;
import net.minecraft.client.resources.model.geometry.BakedQuad;
#endif
/**
@@ -123,6 +127,7 @@ public class ClientBlockStateColorCache
private static final int[] linearToSrgbTable = new int[]
{
//region
0x0073000d, 0x007a000d, 0x0080000d, 0x0087000d, 0x008d000d, 0x0094000d, 0x009a000d, 0x00a1000d,
0x00a7001a, 0x00b4001a, 0x00c1001a, 0x00ce001a, 0x00da001a, 0x00e7001a, 0x00f4001a, 0x0101001a,
0x010e0033, 0x01280033, 0x01410033, 0x015b0033, 0x01750033, 0x018f0033, 0x01a80033, 0x01c20033,
@@ -136,9 +141,11 @@ public class ClientBlockStateColorCache
0x31d105b0, 0x34a80555, 0x37520507, 0x39d504c5, 0x3c37048b, 0x3e7c0458, 0x40a8042a, 0x42bd0401,
0x44c20798, 0x488e071e, 0x4c1c06b6, 0x4f76065d, 0x52a50610, 0x55ac05cc, 0x5892058f, 0x5b590559,
0x5e0c0a23, 0x631c0980, 0x67db08f6, 0x6c55087f, 0x70940818, 0x74a007bd, 0x787d076c, 0x7c330723,
//endregion
};
private static final float[] srgbToLinearTable = new float[]
//region
{
0.0f, 0.000303527f, 0.000607054f, 0.00091058103f, 0.001214108f, 0.001517635f, 0.0018211621f, 0.002124689f,
0.002428216f, 0.002731743f, 0.00303527f, 0.0033465356f, 0.003676507f, 0.004024717f, 0.004391442f,
@@ -172,6 +179,7 @@ public class ClientBlockStateColorCache
0.78353804f, 0.79129815f, 0.79910296f, 0.8069525f, 0.8148468f, 0.822786f, 0.8307701f, 0.83879924f, 0.84687346f,
0.8549928f, 0.8631574f, 0.87136734f, 0.8796226f, 0.8879232f, 0.89626956f, 0.90466136f, 0.913099f, 0.92158204f,
0.93011117f, 0.9386859f, 0.9473069f, 0.9559735f, 0.9646866f, 0.9734455f, 0.98225087f, 0.9911022f, 1.0f
//endregion
};
private static final ThreadLocal<TintWithoutLevelOverrider> TintWithoutLevelOverrideGetter = ThreadLocal.withInitial(() -> new TintWithoutLevelOverrider());
@@ -239,11 +247,18 @@ public class ClientBlockStateColorCache
{
BakedQuad firstQuad = quads.get(0);
#if MC_VER <= MC_1_21_11
this.needPostTinting = firstQuad.isTinted();
#else
this.needPostTinting = firstQuad.materialInfo().isTinted();
#endif
#if MC_VER <= MC_1_21_4
this.tintIndex = firstQuad.getTintIndex();
#else
#elif MC_VER <= MC_1_21_11
this.tintIndex = firstQuad.tintIndex();
#else
this.tintIndex = firstQuad.materialInfo().tintIndex();
#endif
#if MC_VER < MC_1_17_1
@@ -254,10 +269,14 @@ public class ClientBlockStateColorCache
this.baseColor = calculateColorFromTexture(
firstQuad.getSprite(),
EColorMode.getColorMode(this.blockState.getBlock()));
#else
#elif MC_VER <= MC_1_21_11
this.baseColor = calculateColorFromTexture(
firstQuad.sprite(),
EColorMode.getColorMode(this.blockState.getBlock()));
#else
this.baseColor = calculateColorFromTexture(
firstQuad.materialInfo().sprite(),
EColorMode.getColorMode(this.blockState.getBlock()));
#endif
}
else
@@ -304,7 +323,7 @@ public class ClientBlockStateColorCache
#if MC_VER < MC_1_21_5
quads = MC.getModelManager().getBlockModelShaper().
getBlockModel(effectiveBlockState).getQuads(effectiveBlockState, direction, RANDOM);
#else
#elif MC_VER <= MC_1_21_11
List<BlockModelPart> blockModelPartList = MC.getModelManager().getBlockModelShaper().
getBlockModel(effectiveBlockState).collectParts(RANDOM);
@@ -317,6 +336,17 @@ public class ClientBlockStateColorCache
quads.addAll(blockModelPartList.get(i).getQuads(direction));
}
}
#else
List<BlockStateModelPart> blockModelPartList = new ArrayList<>();
MC.getModelManager().getBlockStateModelSet()
.get(effectiveBlockState).collectParts(RANDOM, blockModelPartList);
quads = new ArrayList<>();
for (int i = 0; i < blockModelPartList.size(); i++)
{
// if direction is null this will return the unculled quads
quads.addAll(blockModelPartList.get(i).getQuads(direction));
}
#endif
return quads;
@@ -457,7 +487,11 @@ public class ClientBlockStateColorCache
private int getParticleIconColor()
{
return calculateColorFromTexture(
Minecraft.getInstance().getModelManager().getBlockModelShaper().getParticleIcon(this.blockState),
#if MC_VER <= MC_1_21_11
Minecraft.getInstance().getModelManager().getBlockModelShaper().getParticleIcon(this.blockState),
#else
Minecraft.getInstance().getModelManager().getBlockStateModelSet().get(this.blockState).particleMaterial().sprite(),
#endif
EColorMode.getColorMode(this.blockState.getBlock()));
}
@@ -500,12 +534,20 @@ public class ClientBlockStateColorCache
{
// one or more tint values weren't calculated,
// we need MC's color resolver
#if MC_VER <= MC_1_21_11
tintColor = Minecraft.getInstance()
.getBlockColors()
.getColor(this.blockState,
tintOverride,
McObjectConverter.Convert(blockPos),
this.tintIndex);
#else
tintColor = Minecraft.getInstance()
.getBlockColors()
.getTintSources(this.blockState)
.get(this.tintIndex)
.color(this.blockState);
#endif
}
}
catch (UnsupportedOperationException e)
@@ -528,12 +570,20 @@ public class ClientBlockStateColorCache
tintColor = tintOverride.tryGetBlockTint(new DhBlockPosMutable(blockPos));
if (tintColor == AbstractDhTintGetter.INVALID_COLOR)
{
#if MC_VER <= MC_1_21_11
tintColor = Minecraft.getInstance()
.getBlockColors()
.getColor(this.blockState,
tintOverride,
McObjectConverter.Convert(blockPos),
this.tintIndex);
#else
tintColor = Minecraft.getInstance()
.getBlockColors()
.getTintSources(this.blockState)
.get(this.tintIndex)
.color(this.blockState);
#endif
}
}
}
@@ -19,6 +19,7 @@
package com.seibel.distanthorizons.common.wrappers.block;
import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
#if MC_VER < MC_1_17_1
@@ -63,8 +63,10 @@ public class TintGetterOverride extends AbstractDhTintGetter
// methods //
//=========//
#if MC_VER <= MC_1_21_11
@Override
public float getShade(Direction direction, boolean bl) { return this.parent.getShade(direction, bl); }
#endif
@Override
public LevelLightEngine getLightEngine() { return this.parent.getLightEngine(); }
@@ -175,6 +177,13 @@ public class TintGetterOverride extends AbstractDhTintGetter
@Override
public int getSectionYFromSectionIndex(int i) { return this.parent.getSectionYFromSectionIndex(i); }
#endif
#if MC_VER <= MC_1_21_11
#else
@Override
public CardinalLighting cardinalLighting() { return CardinalLighting.DEFAULT; }
#endif
@@ -19,8 +19,6 @@
package com.seibel.distanthorizons.common.wrappers.block;
import com.seibel.distanthorizons.core.dataObjects.fullData.sources.FullDataSourceV2;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.world.level.LevelReader;
@@ -30,6 +28,12 @@ import net.minecraft.world.level.lighting.LevelLightEngine;
import net.minecraft.world.level.material.FluidState;
import org.jetbrains.annotations.Nullable;
#if MC_VER <= MC_1_21_11
#else
import net.minecraft.world.level.CardinalLighting;
#endif
public class TintWithoutLevelOverrider extends AbstractDhTintGetter
{
@@ -46,9 +50,12 @@ public class TintWithoutLevelOverrider extends AbstractDhTintGetter
// methods //
//=========//
#if MC_VER <= MC_1_21_11
@Override
public float getShade(Direction direction, boolean shade)
{ throw new UnsupportedOperationException("ERROR: getShade() called on TintWithoutLevelOverrider. Object is for tinting only."); }
#endif
@Override
public LevelLightEngine getLightEngine()
{ throw new UnsupportedOperationException("ERROR: getLightEngine() called on TintWithoutLevelOverrider. Object is for tinting only."); }
@@ -87,4 +94,18 @@ public class TintWithoutLevelOverrider extends AbstractDhTintGetter
#endif
//=================//
// post MC 1.21.11 //
//=================//
#if MC_VER <= MC_1_21_11
#else
@Override
public CardinalLighting cardinalLighting()
{ throw new UnsupportedOperationException("ERROR: cardinalLighting() called on TintWithoutLevelOverrider. Object is for tinting only."); }
#endif
}
@@ -122,7 +122,12 @@ public class ChunkWrapper implements IChunkWrapper
{
this.chunk = chunk;
this.wrappedLevel = wrappedLevel;
#if MC_VER <= MC_1_21_11
this.chunkPos = new DhChunkPos(chunk.getPos().x, chunk.getPos().z);
#else
this.chunkPos = new DhChunkPos(chunk.getPos().x(), chunk.getPos().z());
#endif
}
@Override
@@ -46,8 +46,10 @@ import org.jetbrains.annotations.Nullable;
#if MC_VER < MC_1_20_1
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.gui.GuiComponent;
#else
#elif MC_VER <= MC_1_21_11
import net.minecraft.client.gui.GuiGraphics;
#else
import net.minecraft.client.gui.GuiGraphicsExtractor;
#endif
#if MC_VER >= MC_1_17_1
@@ -71,8 +73,6 @@ import static com.seibel.distanthorizons.common.wrappers.gui.GuiHelper.Translata
* Based upon TinyConfig but is highly modified
* https://github.com/Minenash/TinyConfig
*
* Note: floats don't work with this system, use doubles.
*
* @author coolGi
* @author Motschen
* @author James Seibel
@@ -445,7 +445,11 @@ public class ClassicConfigGUI
// move forward or backwards depending on if the shift key is pressed
int index = shiftPressed ? startingIndex-1 : startingIndex+1;
index = (index >= enumList.size()) ? 0 : index;
// wrap around to the other side of the array when necessary
if (index >= enumList.size()) { index = 0; }
else if (index < 0) { index = enumList.size() - 1; }
// walk through the enums to find the next selectable one
while (index != startingIndex)
@@ -462,14 +466,8 @@ public class ClassicConfigGUI
index = shiftPressed ? index-1 : index+1;
// wrap around to the other side of the array when necessary
if (index >= enumList.size())
{
index = 0;
}
else if (index < 0)
{
index = enumList.size() - 1;
}
if (index >= enumList.size()) { index = 0; }
else if (index < 0) { index = enumList.size() - 1; }
}
@@ -585,7 +583,7 @@ public class ClassicConfigGUI
widget.insertText(String.valueOf(configEntry.get()));
Predicate<String> processor = configGuiInfo.tooltipFunction.apply(widget, this.doneButton);
widget.setFilter(processor);
//widget.setFilter(processor);
this.configListWidget.addButton(this, configEntry, widget, resetButton, null, textComponent);
@@ -702,17 +700,26 @@ public class ClassicConfigGUI
@Override
#if MC_VER < MC_1_20_1
public void render(PoseStack matrices, int mouseX, int mouseY, float delta)
#else
#elif MC_VER <= MC_1_21_11
public void render(GuiGraphics matrices, int mouseX, int mouseY, float delta)
#else
public void extractRenderState(GuiGraphicsExtractor matrices, int mouseX, int mouseY, float delta)
#endif
{
#if MC_VER < MC_1_20_2 // 1.20.2 now enables this by default in the `this.list.render` function
this.renderBackground(matrices); // Renders background
#else
this.renderBackground(matrices);
#elif MC_VER <= MC_1_21_11
super.render(matrices, mouseX, mouseY, delta);
#else
super.extractRenderState(matrices, mouseX, mouseY, delta);
#endif
this.configListWidget.render(matrices, mouseX, mouseY, delta); // Render buttons
// Render buttons
#if MC_VER <= MC_1_21_11
this.configListWidget.render(matrices, mouseX, mouseY, delta);
#else
this.configListWidget.extractRenderState(matrices, mouseX, mouseY, delta);
#endif
// Render config title
@@ -754,8 +761,10 @@ public class ClassicConfigGUI
#if MC_VER < MC_1_20_1
private void renderTooltip(PoseStack matrices, int mouseX, int mouseY, float delta)
#else
#elif MC_VER <= MC_1_21_11
private void renderTooltip(GuiGraphics matrices, int mouseX, int mouseY, float delta)
#else
private void renderTooltip(GuiGraphicsExtractor matrices, int mouseX, int mouseY, float delta)
#endif
{
AbstractWidget hoveredWidget = this.configListWidget.getHoveredButton(mouseX, mouseY);
@@ -957,8 +966,10 @@ public class ClassicConfigGUI
public void render(PoseStack matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta)
#elif MC_VER < MC_1_21_9
public void render(GuiGraphics matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta)
#else
#elif MC_VER <= MC_1_21_11
public void renderContent(GuiGraphics matrices, int mouseX, int mouseY, boolean hovered, float tickDelta)
#else
public void extractContent(GuiGraphicsExtractor matrices, int mouseX, int mouseY, boolean hovered, float tickDelta)
#endif
{
try
@@ -977,19 +988,31 @@ public class ClassicConfigGUI
if (this.button != null)
{
SetY(this.button, y);
#if MC_VER <= MC_1_21_11
this.button.render(matrices, mouseX, mouseY, tickDelta);
#else
this.button.extractRenderState(matrices, mouseX, mouseY, tickDelta);
#endif
}
if (this.resetButton != null)
{
SetY(this.resetButton, y);
#if MC_VER <= MC_1_21_11
this.resetButton.render(matrices, mouseX, mouseY, tickDelta);
#else
this.resetButton.extractRenderState(matrices, mouseX, mouseY, tickDelta);
#endif
}
if (this.indexButton != null)
{
SetY(this.indexButton, y);
#if MC_VER <= MC_1_21_11
this.indexButton.render(matrices, mouseX, mouseY, tickDelta);
#else
this.indexButton.extractRenderState(matrices, mouseX, mouseY, tickDelta);
#endif
}
if (this.text != null)
@@ -1038,11 +1061,16 @@ public class ClassicConfigGUI
this.text,
textXPos, y + 5,
0xFFFFFF);
#else
#elif MC_VER <= MC_1_21_11
matrices.drawString(textRenderer,
this.text,
textXPos, y + 5,
0xFFFFFFFF);
#else
matrices.text(textRenderer,
this.text,
textXPos, y + 5,
0xFFFFFFFF);
#endif
}
}
@@ -3,6 +3,7 @@ package com.seibel.distanthorizons.common.wrappers.gui;
#if MC_VER < MC_1_21_9
// not supported for older MC versions
#else
import com.seibel.distanthorizons.core.logging.f3.F3Screen;
import com.seibel.distanthorizons.coreapi.ModInfo;
@@ -19,6 +20,8 @@ import net.minecraft.world.level.chunk.LevelChunk;
#if MC_VER <= MC_1_21_10
import net.minecraft.resources.ResourceLocation;
#else
import net.minecraft.resources.Identifier;
#endif
#endif
@@ -32,6 +35,7 @@ public class DhDebugScreenEntry implements net.minecraft.client.gui.components.d
{
public static void register()
{
#if MC_VER <= MC_1_21_11
// This method is private, so its access will need to be widened
DebugScreenEntries.register(
// The id, this will be displayed on the options screen
@@ -44,6 +48,23 @@ public class DhDebugScreenEntry implements net.minecraft.client.gui.components.d
// The screen entry
new DhDebugScreenEntry()
);
#elif MC_VER <= MC_1_21_11
DebugScreenEntries.allEntries().put(
// The id, this will be displayed on the options screen
Identifier.fromNamespaceAndPath(ModInfo.RESOURCE_NAMESPACE, "distant_horizons"),
// The screen entry
new DhDebugScreenEntry()
);
#else
DebugScreenEntries.register(
// The id, this will be displayed on the options screen
ModInfo.RESOURCE_NAMESPACE,
// The screen entry
new DhDebugScreenEntry()
);
#endif
}
@@ -58,6 +79,8 @@ public class DhDebugScreenEntry implements net.minecraft.client.gui.components.d
displayer.addLine(message);
}
//region
//// The following will display like so if it is the only entry on the screen:
//// First left! First Right!
////
@@ -86,6 +109,8 @@ public class DhDebugScreenEntry implements net.minecraft.client.gui.components.d
//
//displayer.addToGroup(GROUP_TWO, "I am another group!");
//displayer.addToGroup(GROUP_TWO, "This will appear after with no line breaks!");
//endregion
}
@Override
@@ -94,5 +119,8 @@ public class DhDebugScreenEntry implements net.minecraft.client.gui.components.d
// Always show regardless of accessibility option
return true;
}
}
#endif
@@ -1,15 +1,19 @@
package com.seibel.distanthorizons.common.wrappers.gui;
import net.minecraft.client.gui.Font;
#if MC_VER < MC_1_20_1
import com.mojang.blaze3d.vertex.PoseStack;
#else
import net.minecraft.client.gui.GuiGraphics;
#endif
import net.minecraft.client.gui.components.Button;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.network.chat.Component;
#if MC_VER < MC_1_20_1
import com.mojang.blaze3d.vertex.PoseStack;
#elif MC_VER <= MC_1_21_11
import net.minecraft.client.gui.GuiGraphics;
#else
import net.minecraft.client.gui.GuiGraphicsExtractor;
#endif
import java.util.List;
public class DhScreen extends Screen
@@ -73,7 +77,7 @@ public class DhScreen extends Screen
{
guiStack.renderTooltip(font, text, x, y);
}
#else
#elif MC_VER <= MC_1_21_11
protected void DhDrawCenteredString(GuiGraphics guiStack, Font font, Component text, int x, int y, int color)
{
guiStack.drawCenteredString(font, text, x, y, color);
@@ -82,10 +86,6 @@ public class DhScreen extends Screen
{
guiStack.drawString(font, text, x, y, color);
}
//protected void DhRenderTooltip(GuiGraphics guiStack, Font font, List<? extends net.minecraft.util.FormattedCharSequence> text, int x, int y)
//{
// //guiStack.renderTooltip(font, text, x, y);
//}
protected void DhRenderComponentTooltip(GuiGraphics guiStack, Font font, List<Component> comp, int x, int y)
{
guiStack.setComponentTooltipForNextFrame(font, comp, x, y);
@@ -94,6 +94,23 @@ public class DhScreen extends Screen
{
guiStack.setTooltipForNextFrame(font, text, x, y);
}
#else
protected void DhDrawCenteredString(GuiGraphicsExtractor guiStack, Font font, Component text, int x, int y, int color)
{
guiStack.centeredText(font, text, x, y, color);
}
protected void DhDrawString(GuiGraphicsExtractor guiStack, Font font, Component text, int x, int y, int color)
{
guiStack.text(font, text, x, y, color);
}
protected void DhRenderComponentTooltip(GuiGraphicsExtractor guiStack, Font font, List<Component> comp, int x, int y)
{
guiStack.setComponentTooltipForNextFrame(font, comp, x, y);
}
protected void DhRenderTooltip(GuiGraphicsExtractor guiStack, Font font, Component text, int x, int y)
{
guiStack.setTooltipForNextFrame(font, text, x, y);
}
#endif
@@ -1,16 +1,24 @@
package com.seibel.distanthorizons.common.wrappers.gui;
import com.mojang.blaze3d.platform.Window;
import com.mojang.blaze3d.vertex.PoseStack;
import com.seibel.distanthorizons.core.config.gui.AbstractScreen;
import net.minecraft.client.Minecraft;
#if MC_VER >= MC_1_20_1
import net.minecraft.client.gui.GuiGraphics;
#endif
import net.minecraft.client.gui.components.ContainerObjectSelectionList;
import net.minecraft.client.gui.screens.Screen;
import org.jetbrains.annotations.NotNull;
#if MC_VER < MC_1_20_1
import com.mojang.blaze3d.vertex.PoseStack;
#elif MC_VER <= MC_1_21_11
import net.minecraft.client.gui.GuiGraphics;
#else
import net.minecraft.client.gui.GuiGraphicsExtractor;
#endif
import java.nio.file.Path;
import java.util.*;
@@ -74,8 +82,10 @@ public class MinecraftScreen
@Override
#if MC_VER < MC_1_20_1
public void render(PoseStack matrices, int mouseX, int mouseY, float delta)
#else
#elif MC_VER <= MC_1_21_11
public void render(GuiGraphics matrices, int mouseX, int mouseY, float delta)
#else
public void extractRenderState(GuiGraphicsExtractor matrices, int mouseX, int mouseY, float delta)
#endif
{
#if MC_VER < MC_1_20_2
@@ -86,13 +96,21 @@ public class MinecraftScreen
// background blur is already being rendered, rendering again causes the game to crash
#endif
#if MC_VER <= MC_1_21_11
this.configListWidget.render(matrices, mouseX, mouseY, delta); // Renders the items in the render list (currently only used to tint background darker)
#else
this.configListWidget.extractRenderState(matrices, mouseX, mouseY, delta); // Renders the items in the render list (currently only used to tint background darker)
#endif
this.screen.mouseX = mouseX;
this.screen.mouseY = mouseY;
this.screen.render(delta); // Render everything on the main screen
#if MC_VER <= MC_1_21_11
super.render(matrices, mouseX, mouseY, delta); // Render the vanilla stuff (currently only used for the background and tint)
#else
super.extractRenderState(matrices, mouseX, mouseY, delta); // Renders the items in the render list (currently only used to tint background darker)
#endif
}
#if MC_VER <= MC_1_21_10
@@ -45,9 +45,12 @@ import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.RenderPipelines;
#else
#elif MC_VER <= MC_1_21_11
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.renderer.RenderPipelines;
#else
import net.minecraft.client.gui.GuiGraphicsExtractor;
import net.minecraft.client.renderer.RenderPipelines;
#endif
#if MC_VER <= MC_1_21_10
@@ -63,8 +66,10 @@ import net.minecraft.resources.Identifier;
* @version 2023-10-03
*/
#if MC_VER < MC_1_20_2
@SuppressWarnings("deprecation") // we use a few deprecated Mojang functions (as expected when running on old MC versions)
public class TexturedButtonWidget extends ImageButton
#else
@SuppressWarnings("deprecation") // we use a few deprecated Mojang functions (as expected when running on old MC versions)
public class TexturedButtonWidget extends Button
#endif
{
@@ -194,9 +199,12 @@ public class TexturedButtonWidget extends Button
#if MC_VER < MC_1_21_11
@Override
public void renderWidget(GuiGraphics matrices, int mouseX, int mouseY, float delta)
#else
#elif MC_VER <= MC_1_21_11
@Override
protected void renderContents(GuiGraphics matrices, int mouseX, int mouseY, float delta)
#else
@Override
protected void extractContents(GuiGraphicsExtractor matrices, int mouseX, int mouseY, float delta)
#endif
{
if (this.renderBackground)
@@ -210,11 +218,11 @@ public class TexturedButtonWidget extends Button
this.getX(), this.getY(),
this.getWidth(), this.getHeight());
#else
matrices.blitSprite(
RenderPipelines.GUI_TEXTURED,
SPRITES.get(this.active, this.isHoveredOrFocused()),
this.getX(), this.getY(),
this.getWidth(), this.getHeight());
//matrices.blitSprite(
// RenderPipelines.GUI_TEXTURED,
// SPRITES.get(this.active, this.isHoveredOrFocused()),
// this.getX(), this.getY(),
// this.getWidth(), this.getHeight());
#endif
}
@@ -23,8 +23,10 @@ import net.minecraft.client.gui.narration.NarratableEntry;
#if MC_VER < MC_1_20_1
import net.minecraft.client.gui.GuiComponent;
import com.mojang.blaze3d.vertex.PoseStack;
#else
#elif MC_VER <= MC_1_21_11
import net.minecraft.client.gui.GuiGraphics;
#else
import net.minecraft.client.gui.GuiGraphicsExtractor;
#endif
@@ -168,8 +170,10 @@ public class ChangelogScreen extends DhScreen
@Override
#if MC_VER < MC_1_20_1
public void render(PoseStack matrices, int mouseX, int mouseY, float delta)
#else
#elif MC_VER <= MC_1_21_11
public void render(GuiGraphics matrices, int mouseX, int mouseY, float delta)
#else
public void extractRenderState(GuiGraphicsExtractor matrices, int mouseX, int mouseY, float delta)
#endif
{
#if MC_VER < MC_1_20_2
@@ -206,8 +210,14 @@ public class ChangelogScreen extends DhScreen
// render order matters, otherwise on 1.20.6+ the blurred background will render on top of the text
#if MC_VER <= MC_1_21_11
super.render(matrices, mouseX, mouseY, delta); // Render the buttons
this.changelogArea.render(matrices, mouseX, mouseY, delta); // Render the changelog
#else
super.extractRenderState(matrices, mouseX, mouseY, delta); // Render the buttons
this.changelogArea.extractRenderState(matrices, mouseX, mouseY, delta); // Render the changelog
#endif
this.DhDrawCenteredString(matrices, this.font, this.title, this.width / 2, 15, 0xFFFFFF); // Render title
}
@@ -264,10 +274,14 @@ public class ChangelogScreen extends DhScreen
@Override
public void render(GuiGraphics matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta)
{ matrices.drawString(textRenderer, this.text, 12, y + 5, 0xFFFFFF); }
#else
#elif MC_VER <= MC_1_21_11
@Override
public void renderContent(GuiGraphics matrices, int y, int x, boolean hovered, float tickDelta)
{ matrices.drawString(textRenderer, this.text, 12, y + 5, 0xFFFFFF); }
#else
@Override
public void extractContent(GuiGraphicsExtractor matrices, int y, int x, boolean hovered, float tickDelta)
{ matrices.text(textRenderer, this.text, 12, y + 5, 0xFFFFFF); }
#endif
@Override
@@ -13,10 +13,12 @@ import com.seibel.distanthorizons.core.logging.DhLogger;
import net.minecraft.client.gui.screens.Screen;
#if MC_VER >= MC_1_20_1
#if MC_VER < MC_1_20_1
import com.mojang.blaze3d.vertex.PoseStack;
#elif MC_VER <= MC_1_21_11
import net.minecraft.client.gui.GuiGraphics;
#else
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.gui.GuiGraphicsExtractor;
#endif
#if MC_VER <= MC_1_21_10
@@ -172,8 +174,10 @@ public class UpdateModScreen extends DhScreen
@Override
#if MC_VER < MC_1_20_1
public void render(PoseStack matrices, int mouseX, int mouseY, float delta)
#else
#elif MC_VER <= MC_1_21_11
public void render(GuiGraphics matrices, int mouseX, int mouseY, float delta)
#else
public void extractRenderState(GuiGraphicsExtractor matrices, int mouseX, int mouseY, float delta)
#endif
{
#if MC_VER < MC_1_20_2
@@ -184,8 +188,12 @@ public class UpdateModScreen extends DhScreen
// background blur is already being rendered, rendering again causes the game to crash
#endif
#if MC_VER <= MC_1_21_11
super.render(matrices, mouseX, mouseY, delta); // Render the buttons
#else
super.extractRenderState(matrices, mouseX, mouseY, delta);
#endif
// Render the text's
this.DhDrawCenteredString(matrices, this.font,
Translatable(ModInfo.ID + ".updater.text1"),
@@ -172,7 +172,12 @@ public class MinecraftClientWrapper implements IMinecraftClientWrapper, IMinecra
#else
ChunkPos playerPos = player.chunkPosition();
#endif
#if MC_VER <= MC_1_21_11
return new DhChunkPos(playerPos.x, playerPos.z);
#else
return new DhChunkPos(playerPos.x(), playerPos.z());
#endif
}
//endregion
@@ -225,9 +230,13 @@ public class MinecraftClientWrapper implements IMinecraftClientWrapper, IMinecra
player.displayClientMessage(net.minecraft.network.chat.Component.translatable(string), /*isOverlay*/false);
#else
RenderThreadTaskHandler.INSTANCE.queueRunningOnRenderThread(() ->
RenderThreadTaskHandler.INSTANCE.queueRunningOnRenderThread("MinecraftClientWrapper sendChatMessage", () ->
{
#if MC_VER <= MC_1_21_11
player.displayClientMessage(net.minecraft.network.chat.Component.translatable(string), /*isOverlay*/false);
#else
player.sendSystemMessage(net.minecraft.network.chat.Component.translatable(string));
#endif
});
#endif
}
@@ -243,8 +252,10 @@ public class MinecraftClientWrapper implements IMinecraftClientWrapper, IMinecra
#if MC_VER < MC_1_19_2
player.displayClientMessage(new TextComponent(string), /*isOverlay*/true);
#else
#elif MC_VER <= MC_1_21_11
player.displayClientMessage(net.minecraft.network.chat.Component.translatable(string), /*isOverlay*/true);
#else
player.sendOverlayMessage(net.minecraft.network.chat.Component.translatable(string));
#endif
}
@@ -176,21 +176,6 @@ public class MinecraftGLWrapper
{
GL32.glDeleteBuffers(buffer);
// attempt to fix a bug with Mac where de-allocated buffers
// are still being used, causing a SIGSEGV native crash
// and/or corrupting native memory
if (EPlatform.get() == EPlatform.MACOS)
{
// force the delete buffer (and any other in-flight) GL
// commands to finish before continuing
GL32.glFinish();
// James hates this idea.
// He kinda hopes it doesn't help,
// but maybe metal's API just doesn't finish correctly so we need to wait a moment longer before continuing.
try { Thread.sleep(1); } catch (InterruptedException ignore) { }
}
// MC's implementation has a bug where it will throw:
// GL_INVALID_OPERATION in glBufferData(immutable)
// when attempting to delete Storage Buffers
@@ -40,6 +40,7 @@ import com.seibel.distanthorizons.core.wrapperInterfaces.misc.ILightMapWrapper;
import net.minecraft.client.renderer.FogRenderer;
import com.mojang.blaze3d.systems.RenderSystem;
#else
import net.minecraft.client.renderer.fog.FogData;
import net.minecraft.client.renderer.fog.FogRenderer;
#endif
@@ -182,8 +183,10 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
return MC.getFrameTime();
#elif MC_VER < MC_1_21_3
return MC.getTimer().getRealtimeDeltaTicks();
#else
#elif MC_VER <= MC_1_21_11
return MC.deltaTracker.getRealtimeDeltaTicks();
#else
return MC.getDeltaTracker().getRealtimeDeltaTicks();
#endif
}
@@ -253,12 +256,30 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
return Color.white;
}
float darkenAmount;
#if MC_VER <= MC_1_21_11
darkenAmount = MC.gameRenderer.getDarkenWorldAmount(MC.deltaTracker.getGameTimeDeltaPartialTick(true));
#else
darkenAmount = MC.gameRenderer.getBossOverlayWorldDarkening(MC.deltaTracker.getGameTimeDeltaPartialTick(true));
#endif
#if MC_VER <= MC_1_21_11
Vector4f colorValues = mcFogRenderer.setupFog(
MC.gameRenderer.getMainCamera(),
MC.options.getEffectiveRenderDistance(),
MC.deltaTracker,
MC.gameRenderer.getDarkenWorldAmount(MC.deltaTracker.getGameTimeDeltaPartialTick(true)),
darkenAmount,
MC.level);
#else
FogData fogData = mcFogRenderer.setupFog(
MC.gameRenderer.getMainCamera(),
MC.options.getEffectiveRenderDistance(),
MC.deltaTracker,
darkenAmount,
MC.level);
Vector4f colorValues = fogData.color;
#endif
return new Color(
Math.max(0f, Math.min(colorValues.x, 1f)), // r
Math.max(0f, Math.min(colorValues.y, 1f)), // g
@@ -296,9 +317,6 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
}
}
@Override
public double getFov(float partialTicks) { return MC.gameRenderer.getFov(MC.gameRenderer.getMainCamera(), partialTicks, true); }
/** Measured in chunks */
@Override
public int getRenderDistance()
@@ -513,7 +531,11 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
if (MC.level != null)
{
Direction mcDir = McObjectConverter.Convert(lodDirection);
#if MC_VER <= MC_1_21_11
return MC.level.getShade(mcDir, true);
#else
return MC.level.cardinalLighting().byFace(mcDir);
#endif
}
else
{
@@ -24,6 +24,7 @@ import com.google.common.collect.ImmutableMap;
import com.seibel.distanthorizons.api.DhApi;
import com.seibel.distanthorizons.api.enums.worldGeneration.EDhApiDistantGeneratorMode;
import com.seibel.distanthorizons.api.enums.worldGeneration.EDhApiWorldGenerationStep;
import com.seibel.distanthorizons.common.wrappers.McObjectConverter;
import com.seibel.distanthorizons.common.wrappers.world.ServerLevelWrapper;
import com.seibel.distanthorizons.common.wrappers.worldGeneration.chunkFileHandling.ChunkFileReader;
import com.seibel.distanthorizons.common.wrappers.worldGeneration.mimicObject.*;
@@ -54,6 +55,7 @@ import java.util.function.Consumer;
import com.seibel.distanthorizons.coreapi.ModInfo;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import com.seibel.distanthorizons.common.wrappers.worldGeneration.step.StepBiomes;
import com.seibel.distanthorizons.common.wrappers.worldGeneration.step.StepFeatures;
@@ -116,6 +118,8 @@ public final class BatchGenerationEnvironment implements IBatchGeneratorEnvironm
private final IDhServerLevel dhServerLevel;
@Nullable
private final ChunkUpdateQueueManager updateManager;
public final InternalServerGenerator internalServerGenerator;
public final ChunkFileReader chunkFileReader;
@@ -184,6 +188,7 @@ public final class BatchGenerationEnvironment implements IBatchGeneratorEnvironm
public BatchGenerationEnvironment(IDhServerLevel dhServerLevel)
{
this.dhServerLevel = dhServerLevel;
this.updateManager = WorldChunkUpdateManager.INSTANCE.getByLevelWrapper(this.dhServerLevel.getServerLevelWrapper());
this.globalParams = new GlobalWorldGenParams(dhServerLevel);
this.internalServerGenerator = new InternalServerGenerator(this.globalParams, this.dhServerLevel);
this.chunkFileReader = new ChunkFileReader(this.globalParams);
@@ -349,12 +354,12 @@ public final class BatchGenerationEnvironment implements IBatchGeneratorEnvironm
while (existingChunkPosIterator.hasNext())
{
ChunkPos chunkPos = existingChunkPosIterator.next();
DhChunkPos dhChunkPos = new DhChunkPos(chunkPos.x, chunkPos.z);
DhChunkPos dhChunkPos = McObjectConverter.Convert(chunkPos);
CompletableFuture<ChunkWrapper> getExistingChunkFuture
// running async allows file IO to run in parallel when C2ME is present
= this.chunkFileReader.createEmptyOrPreExistingChunkWrapperAsync(
chunkPos.x, chunkPos.z,
dhChunkPos.getX(), dhChunkPos.getZ(),
chunkSkyLightingByDhPos, chunkBlockLightingByDhPos, chunkWrappersByDhPos);
readFutureByDhChunkPos.put(dhChunkPos, getExistingChunkFuture);
@@ -381,7 +386,7 @@ public final class BatchGenerationEnvironment implements IBatchGeneratorEnvironm
while (emptyChunkPosIterator.hasNext())
{
ChunkPos chunkPos = emptyChunkPosIterator.next();
DhChunkPos dhChunkPos = new DhChunkPos(chunkPos.x, chunkPos.z);
DhChunkPos dhChunkPos = McObjectConverter.Convert(chunkPos);
// create empty chunks outside the generation radius
if (!readFutureByDhChunkPos.containsKey(dhChunkPos))
@@ -432,7 +437,11 @@ public final class BatchGenerationEnvironment implements IBatchGeneratorEnvironm
relZ + refPosZ + zOffsetFinal));
ChunkAccess centerChunk = regionChunks.stream()
#if MC_VER <= MC_1_21_11
.filter((chunk) -> chunk.getPos().x == centerX && chunk.getPos().z == centerZ)
#else
.filter((chunk) -> chunk.getPos().x() == centerX && chunk.getPos().z() == centerZ)
#endif
.findFirst()
.orElseGet(() -> regionChunks.getFirst());
@@ -530,9 +539,9 @@ public final class BatchGenerationEnvironment implements IBatchGeneratorEnvironm
Iterator<ChunkPos> iterator = ChunkPosGenStream.getIterator(genEvent.minPos.getX(), genEvent.minPos.getZ(), genEvent.widthInChunks, 0);
while (iterator.hasNext())
{
ChunkPos pos = iterator.next();
DhChunkPos dhPos = new DhChunkPos(pos.x, pos.z);
ChunkWrapper wrappedChunk = chunkWrappersByDhPos.get(dhPos);
ChunkPos chunkPos = iterator.next();
DhChunkPos dhChunkPos = McObjectConverter.Convert(chunkPos);
ChunkWrapper wrappedChunk = chunkWrappersByDhPos.get(dhChunkPos);
// only pass along chunks that have been generated up to BIOMES
// this is to prevent issues with generating existing
@@ -546,7 +555,7 @@ public final class BatchGenerationEnvironment implements IBatchGeneratorEnvironm
if (!this.generatedChunkWithoutBiomeWarningLogged)
{
this.generatedChunkWithoutBiomeWarningLogged = true;
LOGGER.warn("Chunk [" + dhPos + "] wasn't generated up to BIOMES, world gen may appear empty.");
LOGGER.warn("Chunk [" + dhChunkPos + "] wasn't generated up to BIOMES, world gen may appear empty.");
}
}
}
@@ -592,10 +601,9 @@ public final class BatchGenerationEnvironment implements IBatchGeneratorEnvironm
// usually ignoring the chunk's position is unnecessary,
// but this improves performance if a chunk update event does sneak through
ChunkUpdateQueueManager updateManager = WorldChunkUpdateManager.INSTANCE.getByLevelWrapper(this.dhServerLevel.getServerLevelWrapper());
if (updateManager != null)
if (this.updateManager != null)
{
updateManager.addPosToIgnore(chunkWrapper.getChunkPos());
this.updateManager.addPosToIgnore(chunkWrapper.getChunkPos());
}
});
@@ -724,15 +732,9 @@ public final class BatchGenerationEnvironment implements IBatchGeneratorEnvironm
@Override
public void run()
{
ChunkUpdateQueueManager updateManager = WorldChunkUpdateManager.INSTANCE.getByLevelWrapper(BatchGenerationEnvironment.this.dhServerLevel.getServerLevelWrapper());
if (updateManager != null)
if (BatchGenerationEnvironment.this.updateManager != null)
{
updateManager.addPosToIgnore(chunkWrapper.getChunkPos());
}
else
{
// shouldn't happen, but just in case
LOGGER.warn("Unable to find chunk update manager for server level ["+BatchGenerationEnvironment.this.dhServerLevel+"], chunk updates may fail.");
BatchGenerationEnvironment.this.updateManager.removePosToIgnore(chunkWrapper.getChunkPos());
}
}
}, MS_TO_IGNORE_CHUNK_AFTER_COMPLETION);
@@ -1,6 +1,7 @@
package com.seibel.distanthorizons.common.wrappers.worldGeneration;
import com.seibel.distanthorizons.api.DhApi;
import com.seibel.distanthorizons.common.wrappers.McObjectConverter;
import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
import com.seibel.distanthorizons.common.wrappers.worldGeneration.params.GlobalWorldGenParams;
import com.seibel.distanthorizons.core.api.internal.ClientApi;
@@ -22,6 +23,9 @@ import com.seibel.distanthorizons.core.util.TimerUtil;
import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IC2meAccessor;
import com.seibel.distanthorizons.coreapi.ModInfo;
import org.jetbrains.annotations.Nullable;
import net.minecraft.server.level.ChunkHolder;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.TicketType;
@@ -75,6 +79,8 @@ public class InternalServerGenerator
private final GlobalWorldGenParams params;
private final IDhServerLevel dhServerLevel;
@Nullable
private final ChunkUpdateQueueManager updateManager;
private final Timer chunkSaveIgnoreTimer = TimerUtil.CreateTimer("ChunkSaveIgnoreTimer");
@@ -87,6 +93,7 @@ public class InternalServerGenerator
{
this.params = params;
this.dhServerLevel = dhServerLevel;
this.updateManager = WorldChunkUpdateManager.INSTANCE.getByLevelWrapper(this.dhServerLevel.getServerLevelWrapper());
}
@@ -237,10 +244,9 @@ public class InternalServerGenerator
ServerLevel level = this.params.mcServerLevel;
// ignore chunk update events for this position
ChunkUpdateQueueManager updateManager = WorldChunkUpdateManager.INSTANCE.getByLevelWrapper(this.params.dhServerLevel.getServerLevelWrapper());
if (updateManager != null)
if (this.updateManager != null)
{
updateManager.addPosToIgnore(new DhChunkPos(chunkPos.x, chunkPos.z));
this.updateManager.addPosToIgnore(McObjectConverter.Convert(chunkPos));
}
#if MC_VER < MC_1_21_5
@@ -253,7 +259,10 @@ public class InternalServerGenerator
// probably not the most optimal to run updates here, but fast enough
level.getChunkSource().distanceManager.runAllUpdates(level.getChunkSource().chunkMap);
ChunkHolder chunkHolder = level.getChunkSource().chunkMap.getUpdatingChunkIfPresent(chunkPos.toLong());
ChunkHolder chunkHolder = level.getChunkSource().chunkMap
.getUpdatingChunkIfPresent(
#if MC_VER <= MC_1_21_11 chunkPos.toLong() #else chunkPos.pack() #endif
);
if (chunkHolder == null)
{
throw new IllegalStateException("No chunk chunkHolder for pos ["+chunkPos+"] after ticket has been added.");
@@ -304,15 +313,9 @@ public class InternalServerGenerator
@Override
public void run()
{
ChunkUpdateQueueManager updateManager = WorldChunkUpdateManager.INSTANCE.getByLevelWrapper(dhLevel.getServerLevelWrapper());
if (updateManager != null)
if (InternalServerGenerator.this.updateManager != null)
{
updateManager.addPosToIgnore(new DhChunkPos(chunkPos.x, chunkPos.z));
}
else
{
// shouldn't happen, but just in case
LOGGER.warn("Unable to find chunk update manager for server level ["+dhLevel+"], chunk updates may fail.");
InternalServerGenerator.this.updateManager.removePosToIgnore(McObjectConverter.Convert(chunkPos));
}
}
}, MS_TO_IGNORE_CHUNK_AFTER_COMPLETION);
@@ -20,12 +20,14 @@
package com.seibel.distanthorizons.common.wrappers.worldGeneration.chunkFileHandling;
import com.mojang.serialization.Codec;
import com.seibel.distanthorizons.common.wrappers.McObjectConverter;
import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
import com.seibel.distanthorizons.core.config.Config;
import com.seibel.distanthorizons.core.level.IDhServerLevel;
import com.seibel.distanthorizons.core.logging.DhLogger;
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import com.seibel.distanthorizons.core.pos.DhChunkPos;
import com.seibel.distanthorizons.core.util.LodUtil;
import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.ChunkLightStorage;
@@ -673,7 +675,9 @@ public class ChunkCompoundTagParser
{
LOGGED_ERROR_MESSAGE_MAP.computeIfAbsent(message, (newMessage) ->
{
LOGGER.warn("Unable to deserialize blocks for chunk section [" + chunkPos.x + ", " + sectionYIndex + ", " + chunkPos.z + "], error: ["+newMessage+"]. " +
DhChunkPos dhChunkPos = McObjectConverter.Convert(chunkPos);
LOGGER.warn("Unable to deserialize blocks for chunk section [" + dhChunkPos.getX() + ", " + sectionYIndex + ", " + dhChunkPos.getZ() + "], error: ["+newMessage+"]. " +
"This can probably be ignored, although if your world looks wrong, optimizing it via the single player menu then deleting your DH database(s) should fix the problem.");
return newMessage;
@@ -683,7 +687,9 @@ public class ChunkCompoundTagParser
{
LOGGED_ERROR_MESSAGE_MAP.computeIfAbsent(message, (newMessage) ->
{
LOGGER.warn("Unable to deserialize biomes for chunk section [" + chunkPos.x + ", " + sectionYIndex + ", " + chunkPos.z + "], error: ["+newMessage+"]. " +
DhChunkPos dhChunkPos = McObjectConverter.Convert(chunkPos);
LOGGER.warn("Unable to deserialize biomes for chunk section [" + dhChunkPos.getX() + ", " + sectionYIndex + ", " + dhChunkPos.getZ() + "], error: ["+newMessage+"]. " +
"This can probably be ignored, although if your world looks wrong, optimizing it via the single player menu then deleting your DH database(s) should fix the problem.");
return newMessage;
@@ -22,9 +22,12 @@ package com.seibel.distanthorizons.common.wrappers.worldGeneration.mimicObject;
import java.lang.invoke.MethodHandles;
import java.util.List;
import java.util.concurrent.locks.ReentrantLock;
import com.seibel.distanthorizons.common.wrappers.McObjectConverter;
import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
import com.seibel.distanthorizons.common.wrappers.worldGeneration.BatchGenerationEnvironment;
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import com.seibel.distanthorizons.core.pos.DhChunkPos;
import com.seibel.distanthorizons.core.util.LodUtil;
import net.minecraft.world.level.block.EntityBlock;
import net.minecraft.world.level.block.SpawnerBlock;
@@ -89,7 +92,7 @@ public class DhLitWorldGenRegion extends WorldGenRegion
public final int writeRadius;
public final int size;
private final ChunkPos firstPos;
private final DhChunkPos firstPos;
private final List<ChunkAccess> cache;
private final Long2ObjectOpenHashMap<ChunkAccess> chunkMap = new Long2ObjectOpenHashMap<ChunkAccess>();
@@ -149,7 +152,7 @@ public class DhLitWorldGenRegion extends WorldGenRegion
centerChunk);
#endif
this.firstPos = chunkList.get(0).getPos();
this.firstPos = McObjectConverter.Convert(chunkList.get(0).getPos());
this.serverLevel = serverLevel;
this.generator = generator;
this.lightEngine = lightEngine;
@@ -165,17 +168,22 @@ public class DhLitWorldGenRegion extends WorldGenRegion
@Override
public boolean ensureCanWrite(BlockPos blockPos)
{
int i = SectionPos.blockToSectionCoord(blockPos.getX());
int j = SectionPos.blockToSectionCoord(blockPos.getZ());
ChunkPos chunkPos = this.getCenter();
ChunkAccess center = this.getChunk(chunkPos.x, chunkPos.z);
int k = Math.abs(chunkPos.x - i);
int l = Math.abs(chunkPos.z - j);
if (k > this.writeRadius || l > this.writeRadius)
DhChunkPos chunkPos = McObjectConverter.Convert(this.getCenter());
int sectionCoordX = SectionPos.blockToSectionCoord(blockPos.getX());
int sectionCoordZ = SectionPos.blockToSectionCoord(blockPos.getZ());
// TODO what do these "abs" positions mean?
int absX = Math.abs(chunkPos.getX() - sectionCoordX);
int absZ = Math.abs(chunkPos.getZ() - sectionCoordZ);
if (absX > this.writeRadius
|| absZ > this.writeRadius)
{
return false;
}
#if MC_VER >= MC_1_18_2
ChunkAccess center = this.getChunk(chunkPos.getX(), chunkPos.getZ());
if (center.isUpgrading())
{
LevelHeightAccessor levelHeightAccessor = center.getHeightAccessorForGeneration();
@@ -196,6 +204,7 @@ public class DhLitWorldGenRegion extends WorldGenRegion
}
}
#endif
return true;
}
#endif
@@ -372,7 +381,15 @@ public class DhLitWorldGenRegion extends WorldGenRegion
if (chunk == null)
{
// check memory
chunk = this.chunkMap.get(ChunkPos.asLong(chunkX, chunkZ));
long chunkPosAsLong;
#if MC_VER <= MC_1_21_11
chunkPosAsLong = ChunkPos.asLong(chunkX, chunkZ);
#else
chunkPosAsLong = ChunkPos.pack(chunkX, chunkZ);
#endif
chunk = this.chunkMap.get(chunkPosAsLong);
if (chunk == null)
{
// chunk isn't in memory, generate a new one
@@ -381,7 +398,7 @@ public class DhLitWorldGenRegion extends WorldGenRegion
{
throw new NullPointerException("The provided generator should not return null!");
}
this.chunkMap.put(ChunkPos.asLong(chunkX, chunkZ), chunk);
this.chunkMap.put(chunkPosAsLong, chunk);
}
}
@@ -401,17 +418,18 @@ public class DhLitWorldGenRegion extends WorldGenRegion
/** Use this instead of super.hasChunk() to bypass C2ME concurrency checks */
public boolean superHasChunk(int x, int z)
{
int k = x - this.firstPos.x;
int l = z - this.firstPos.z;
return l >= 0 && l < this.size && k >= 0 && k < this.size;
int xOffset = x - this.firstPos.getX();
int zOffset = z - this.firstPos.getZ();
return zOffset >= 0 && zOffset < this.size
&& xOffset >= 0 && xOffset < this.size;
}
/** Use this instead of super.getChunk() to bypass C2ME concurrency checks */
private ChunkAccess superGetChunk(int x, int z)
{
int k = x - this.firstPos.x;
int l = z - this.firstPos.z;
return this.cache.get(k + l * this.size);
int xOffset = x - this.firstPos.getX();
int zOffset = z - this.firstPos.getZ();
return this.cache.get(xOffset + zOffset * this.size);
}
@@ -69,8 +69,13 @@ public class RegionFileStorageExternalCache implements AutoCloseable
}
long chunkPosLong;
#if MC_VER <= MC_1_21_11
chunkPosLong = ChunkPos.asLong(chunkPos.getRegionX(), chunkPos.getRegionZ());
#else
chunkPosLong = ChunkPos.pack(chunkPos.getRegionX(), chunkPos.getRegionZ());
#endif
long chunkPosLong = ChunkPos.asLong(chunkPos.getRegionX(), chunkPos.getRegionZ());
RegionFile regionFile = null;
// Check vanilla cache
@@ -84,7 +89,7 @@ public class RegionFileStorageExternalCache implements AutoCloseable
{
this.getRegionFileLock.lock();
#if MC_VER == MC_1_16_5 || MC_VER == MC_1_17_1
#if MC_VER <= MC_1_17_1
regionFile = this.storage.getRegionFile(chunkPos);
// keeping the region cache size low helps prevent concurrency issues
@@ -104,7 +109,7 @@ public class RegionFileStorageExternalCache implements AutoCloseable
}
catch (ArrayIndexOutOfBoundsException e)
{
#if MC_VER == MC_1_16_5 || MC_VER == MC_1_17_1
#if MC_VER <= MC_1_17_1
// the file just wasn't cached
break;
#else
@@ -179,7 +184,7 @@ public class RegionFileStorageExternalCache implements AutoCloseable
regionFile = new RegionFile(new RegionStorageInfo("level", null, "level type"), regionFilePath, storageFolderPath, false);
#endif
this.regionFileCache.add(new RegionFileCache(ChunkPos.asLong(chunkPos.getRegionX(), chunkPos.getRegionZ()), regionFile));
this.regionFileCache.add(new RegionFileCache(chunkPosLong, regionFile));
while (this.regionFileCache.size() > MAX_CACHE_SIZE)
{
this.regionFileCache.poll().file.close();
@@ -28,6 +28,8 @@ import java.util.stream.Stream;
import com.google.common.collect.ImmutableList;
import com.seibel.distanthorizons.common.wrappers.McObjectConverter;
import com.seibel.distanthorizons.core.pos.DhChunkPos;
import it.unimi.dsi.fastutil.longs.LongSet;
import net.minecraft.core.BlockPos;
import net.minecraft.core.SectionPos;
@@ -222,9 +224,10 @@ public class WorldGenStructFeatManager extends #if MC_VER < MC_1_19_2 StructureF
}
#else
@Override
public List<StructureStart> startsForStructure(ChunkPos sectionPos, Predicate<Structure> predicate)
public List<StructureStart> startsForStructure(ChunkPos chunkPos, Predicate<Structure> predicate)
{
ChunkAccess chunk = _getChunk(sectionPos.x, sectionPos.z, ChunkStatus.STRUCTURE_REFERENCES);
DhChunkPos dhChunkPos = McObjectConverter.Convert(chunkPos);
ChunkAccess chunk = _getChunk(dhChunkPos.getX(), dhChunkPos.getZ(), ChunkStatus.STRUCTURE_REFERENCES);
if (chunk == null) return List.of();
// Copied from StructureFeatureManager::startsForFeature(...)
@@ -113,10 +113,14 @@ public final class GlobalWorldGenParams
this.worldOptions = worldData.worldGenOptions();
this.biomes = registry.registryOrThrow(Registries.BIOME);
this.worldSeed = worldOptions.seed();
#else
#elif MC_VER <= MC_1_21_11
this.worldOptions = worldData.worldGenOptions();
this.biomes = this.registry.lookupOrThrow(Registries.BIOME);
this.worldSeed = this.worldOptions.seed();
#else
this.worldOptions = server.getWorldGenSettings().options();
this.biomes = this.registry.lookupOrThrow(Registries.BIOME);
this.worldSeed = this.worldOptions.seed();
#endif
#if MC_VER >= MC_1_18_2
@@ -0,0 +1,56 @@
accessWidener v1 official
# used when determining where to save files to
accessible field net/minecraft/world/level/storage/SavedDataStorage dataFolder Ljava/nio/file/Path;
# used to help determine what folder a clientLevel is
accessible field net/minecraft/world/level/biome/BiomeManager biomeZoomSeed J
# used when rendering
accessible method net/minecraft/client/renderer/GameRenderer getFov (Lnet/minecraft/client/Camera;FZ)F
accessible field net/minecraft/client/Minecraft deltaTracker Lnet/minecraft/client/DeltaTracker$Timer;
accessible field net/minecraft/client/renderer/LevelRenderer level Lnet/minecraft/client/multiplayer/ClientLevel;
# used for grabbing vanilla rendered chunks
accessible field net/minecraft/client/renderer/LevelRenderer visibleSections Lit/unimi/dsi/fastutil/objects/ObjectArrayList;
# world generation
accessible field net/minecraft/world/level/chunk/LevelChunk loaded Z
accessible field net/minecraft/world/level/lighting/LightEngine storage Lnet/minecraft/world/level/lighting/LayerLightSectionStorage;
accessible method net/minecraft/world/level/lighting/LayerLightSectionStorage lightOnInSection (J)Z
accessible field net/minecraft/server/level/ServerChunkCache distanceManager Lnet/minecraft/server/level/DistanceManager;
accessible method net/minecraft/server/level/ChunkMap getUpdatingChunkIfPresent (J)Lnet/minecraft/server/level/ChunkHolder;
accessible method net/minecraft/server/level/ChunkMap tick (Ljava/util/function/BooleanSupplier;)V
accessible field net/minecraft/server/level/ServerLevel entityManager Lnet/minecraft/world/level/entity/PersistentEntitySectionManager;
accessible field net/minecraft/server/level/ChunkMap mainThreadExecutor Lnet/minecraft/util/thread/BlockableEventLoop;
# getting existing chunks outside the main thread
accessible method net/minecraft/server/level/ChunkMap getVisibleChunkIfPresent (J)Lnet/minecraft/server/level/ChunkHolder;
# lod generation from save file
accessible field net/minecraft/world/level/chunk/storage/SimpleRegionStorage worker Lnet/minecraft/world/level/chunk/storage/IOWorker;
accessible field net/minecraft/world/level/chunk/storage/IOWorker storage Lnet/minecraft/world/level/chunk/storage/RegionFileStorage;
accessible field net/minecraft/world/level/chunk/storage/RegionFileStorage regionCache Lit/unimi/dsi/fastutil/longs/Long2ObjectLinkedOpenHashMap;
accessible field net/minecraft/world/level/chunk/storage/RegionFileStorage folder Ljava/nio/file/Path;
# grabbing textures
accessible class net/minecraft/client/renderer/texture/SpriteContents$AnimatedTexture
accessible method net/minecraft/client/renderer/texture/SpriteContents$AnimatedTexture getFrameX (I)I
accessible method net/minecraft/client/renderer/texture/SpriteContents$AnimatedTexture getFrameY (I)I
accessible field net/minecraft/client/renderer/texture/SpriteContents animatedTexture Lnet/minecraft/client/renderer/texture/SpriteContents$AnimatedTexture;
accessible field net/minecraft/client/renderer/texture/SpriteContents originalImage Lcom/mojang/blaze3d/platform/NativeImage;
# UI stuff
accessible field net/minecraft/client/gui/components/AbstractButton SPRITES Lnet/minecraft/client/gui/components/WidgetSprites;
# Handles inserting the config button
accessible field net/minecraft/client/gui/layouts/HeaderAndFooterLayout headerFrame Lnet/minecraft/client/gui/layouts/FrameLayout;
accessible field net/minecraft/client/gui/layouts/FrameLayout children Ljava/util/List;
accessible class net/minecraft/client/gui/layouts/FrameLayout$ChildContainer
accessible field net/minecraft/client/gui/layouts/LinearLayout wrapped Lnet/minecraft/client/gui/layouts/GridLayout;
accessible method net/minecraft/client/gui/components/debug/DebugScreenEntries register (Ljava/lang/String;Lnet/minecraft/client/gui/components/debug/DebugScreenEntry;)Lnet/minecraft/resources/Identifier;
# hacky stuff
accessible field net/minecraft/util/ThreadingDetector lock Ljava/util/concurrent/Semaphore;
mutable field net/minecraft/util/ThreadingDetector lock Ljava/util/concurrent/Semaphore;
+14 -135
View File
@@ -1,106 +1,24 @@
plugins {
id "fabric-loom" version "1.10-SNAPSHOT"
}
loom {
accessWidenerPath = project(":common").file("src/main/resources/${accessWidenerVersion}.distanthorizons.accesswidener")
// "runs" isn't required, but when we do need it then it can be useful
runs {
client {
client()
setConfigName("Fabric Client")
ideConfigGenerated(true) // When true a run configuration file will be generated for IDE's. By default only set to true for the root project.
runDir("../run/client")
vmArgs(
// https://github.com/FabricMC/fabric-loom/issues/915#issuecomment-1609154390
"-Dminecraft.api.auth.host=https://nope.invalid",
"-Dminecraft.api.account.host=https://nope.invalid",
"-Dminecraft.api.session.host=https://nope.invalid",
"-Dminecraft.api.services.host=https://nope.invalid",
// https://netty.io/wiki/reference-counted-objects.html#leak-detection-levels
"-Dio.netty.leakDetection.level=advanced",
"-XX:+UseZGC",
"-XX:+ZGenerational"
)
// "--renderDebugLabels" is a Mojang command to show render names in RenderDoc
programArgs("--username", "Dev", "--renderDebugLabels")
}
server {
server()
setConfigName("Fabric Server")
ideConfigGenerated(true)
runDir("../run/server")
vmArgs("-Dio.netty.leakDetection.level=advanced")
}
}
}
remapJar {
inputFile = shadowJar.archiveFile
dependsOn shadowJar
id 'unimined-fabric'
}
configurations {
// The addModJar basically embeds the mod to the built jar
addModJar
include.extendsFrom addModJar
modImplementation.extendsFrom addModJar
}
// ==================== Dependencies ====================
def addMod(path, enabled) {
if (enabled == "2")
dependencies { modImplementation(path) }
else if (enabled == "1")
dependencies { modCompileOnly(path) }
dependencies { compileOnly(path) }
}
dependencies {
minecraft "com.mojang:minecraft:${rootProject.minecraft_version}"
mappings loom.layered() {
// Mojmap mappings
officialMojangMappings()
// Parchment mappings (it adds parameter mappings & javadoc)
parchment("org.parchmentmc.data:parchment-${rootProject.parchment_version}@zip")
}
// Fabric loader
modImplementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}"
// annotationProcessor "javax.annotation:javax.annotation-api:1.3.2"
// implementation("javax.annotation:javax.annotation-api:1.3.2")
// runtimeOnly "javax.annotation:javax.annotation-api:1.3.2"
// compileOnly "javax.annotation:javax.annotation-api:1.3.2"
// modImplementation "javax.annotation:javax.annotation-api:1.3.2"
// Fabric API
addModJar(fabricApi.module("fabric-api-base", rootProject.fabric_api_version))
addModJar(fabricApi.module("fabric-lifecycle-events-v1", rootProject.fabric_api_version))
if (buildVersionBefore(minecraft_version, "1.21.9"))
{
addModJar(fabricApi.module("fabric-resource-loader-v0", rootProject.fabric_api_version))
}
else // > 1.21.9
{
addModJar(fabricApi.module("fabric-resource-loader-v0", rootProject.fabric_api_version))
addModJar(fabricApi.module("fabric-resource-loader-v1", rootProject.fabric_api_version))
}
addModJar(fabricApi.module("fabric-events-interaction-v0", rootProject.fabric_api_version))
addModJar(fabricApi.module("fabric-rendering-v1", rootProject.fabric_api_version))
addModJar(fabricApi.module("fabric-networking-api-v1", rootProject.fabric_api_version))
addModJar(fabricApi.module("fabric-entity-events-v1", rootProject.fabric_api_version))
if (buildVersionBefore(minecraft_version, "1.19.2"))
addModJar(fabricApi.module("fabric-command-api-v1", rootProject.fabric_api_version))
else
addModJar(fabricApi.module("fabric-command-api-v2", rootProject.fabric_api_version))
// used by mod menu in MC 1.20.6+
addModJar(fabricApi.module("fabric-screen-api-v1", rootProject.fabric_api_version))
addModJar(fabricApi.module("fabric-key-binding-api-v1", rootProject.fabric_api_version))
// Fabric API (bundled as jar-in-jar so users don't need to install it separately)
modImplementation "net.fabricmc.fabric-api:fabric-api:${rootProject.fabric_api_version}"
include "net.fabricmc.fabric-api:fabric-api:${rootProject.fabric_api_version}"
// Mod Menu
addMod("com.terraformersmc:modmenu:${rootProject.modmenu_version}", rootProject.enable_mod_menu)
@@ -113,11 +31,7 @@ dependencies {
// Sodium
addMod("maven.modrinth:sodium:${rootProject.sodium_version}", rootProject.enable_sodium)
if (rootProject.enable_sodium == "2") {
implementation "org.joml:joml:1.10.2"
modImplementation(fabricApi.module("fabric-rendering-data-attachment-v1", rootProject.fabric_api_version))
modImplementation(fabricApi.module("fabric-rendering-fluids-v1", rootProject.fabric_api_version))
}
if (rootProject.enable_sodium == "2") implementation "org.joml:joml:1.10.2"
// Lithium
addMod("maven.modrinth:lithium:${rootProject.lithium_version}", rootProject.enable_lithium)
@@ -129,65 +43,32 @@ dependencies {
addMod("com.github.quiqueck:BCLib:${rootProject.bclib_version}", rootProject.enable_bclib)
// Canvas
addMod("io.vram:canvas-fabric-${project.canvas_version}", rootProject.enable_canvas)
addMod("io.vram:canvas-fabric-${rootProject.canvas_version}", rootProject.enable_canvas)
// Immersive Portals
if (rootProject.enable_immersive_portals == "1") {
modCompileOnly("com.github.iPortalTeam.ImmersivePortalsMod:imm_ptl_core:${project.immersive_portals_version}")
modCompileOnly("com.github.iPortalTeam.ImmersivePortalsMod:imm_ptl_core:${rootProject.immersive_portals_version}")
}
else if (rootProject.enable_immersive_portals == "2") {
modImplementation ("com.github.iPortalTeam.ImmersivePortalsMod:imm_ptl_core:${project.immersive_portals_version}") {
modImplementation ("com.github.iPortalTeam.ImmersivePortalsMod:imm_ptl_core:${rootProject.immersive_portals_version}") {
exclude(group: "net.fabricmc.fabric-api")
transitive(false)
}
modImplementation ("com.github.iPortalTeam.ImmersivePortalsMod:q_misc_util:${project.immersive_portals_version}") {
modImplementation("com.github.iPortalTeam.ImmersivePortalsMod:q_misc_util:${rootProject.immersive_portals_version}") {
exclude(group: "net.fabricmc.fabric-api")
transitive(false)
}
modImplementation ("com.github.iPortalTeam.ImmersivePortalsMod:build:${project.immersive_portals_version}") {
modImplementation("com.github.iPortalTeam.ImmersivePortalsMod:build:${rootProject.immersive_portals_version}") {
exclude(group: "net.fabricmc.fabric-api")
transitive(false)
}
modImplementation("net.fabricmc.fabric-api:fabric-api:${rootProject.fabric_api_version}")
api("com.github.LlamaLad7:MixinExtras:0.2.0-beta.4")
annotationProcessor("com.github.LlamaLad7:MixinExtras:0.2.0-beta.4")
}
}
private static boolean buildVersionBefore(String minecraft_version, String compareVersion)
{
int sortValue = sortSemanticVersionOldestToNewest(minecraft_version, compareVersion);
return sortValue == -1;
}
/**
* input format: "major.minor.patch"
* needed so we can sort versions with different length strings
* IE: 1.21.1 should come before 1.21.10
*/
private static int sortSemanticVersionOldestToNewest(String version1, String version2)
{
String[] parts1 = version1.split("\\.");
String[] parts2 = version2.split("\\.");
int major1 = Integer.parseInt(parts1[0]);
int major2 = Integer.parseInt(parts2[0]);
if (major1 != major2)
{
return Integer.compare(major1, major2);
}
int minor1 = Integer.parseInt(parts1[1]);
int minor2 = Integer.parseInt(parts2[1]);
if (minor1 != minor2)
{
return Integer.compare(minor1, minor2);
}
int patch1 = Integer.parseInt(parts1[2]);
int patch2 = Integer.parseInt(parts2[2]);
return Integer.compare(patch1, patch2);
}
// ==================== Tasks ====================
task deleteResources(type: Delete) {
delete file("build/resources/main")
@@ -198,14 +79,12 @@ processResources {
dependsOn(copyCommonLoaderResources)
}
runClient {
tasks.named('runClient') {
dependsOn(copyCoreResources)
dependsOn(copyCommonLoaderResources)
// jvmArgs([ "-XX:-OmitStackTraceInFastThrow", minecraftMemoryJavaArg ])
finalizedBy(deleteResources)
}
sourcesJar {
def commonSources = project(":common").sourcesJar
dependsOn commonSources
@@ -315,7 +315,16 @@ public class FabricClientProxy implements AbstractModInitializer.IEventProxy
// networking event //
//==================//
#if MC_VER >= MC_1_20_6
#if MC_VER < MC_1_20_6
ClientPlayNetworking.registerGlobalReceiver(AbstractPluginPacketSender.WRAPPER_PACKET_RESOURCE, (client, handler, buffer, packetSender) ->
{
AbstractNetworkMessage message = PACKET_SENDER.decodeMessage(buffer);
if (message != null)
{
ClientApi.INSTANCE.pluginMessageReceived(message);
}
});
#elif MC_VER <= MC_1_21_11
PayloadTypeRegistry.playS2C().register(CommonPacketPayload.TYPE, new CommonPacketPayload.Codec());
ClientPlayNetworking.registerGlobalReceiver(CommonPacketPayload.TYPE, (payload, context) ->
{
@@ -326,13 +335,14 @@ public class FabricClientProxy implements AbstractModInitializer.IEventProxy
ClientApi.INSTANCE.pluginMessageReceived(payload.message());
});
#else
ClientPlayNetworking.registerGlobalReceiver(AbstractPluginPacketSender.WRAPPER_PACKET_RESOURCE, (client, handler, buffer, packetSender) ->
PayloadTypeRegistry.clientboundPlay().register(CommonPacketPayload.TYPE, new CommonPacketPayload.Codec());
ClientPlayNetworking.registerGlobalReceiver(CommonPacketPayload.TYPE, (payload, context) ->
{
AbstractNetworkMessage message = PACKET_SENDER.decodeMessage(buffer);
if (message != null)
if (payload.message() == null)
{
ClientApi.INSTANCE.pluginMessageReceived(message);
return;
}
ClientApi.INSTANCE.pluginMessageReceived(payload.message());
});
#endif
}
@@ -18,11 +18,9 @@ import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapp
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
import com.seibel.distanthorizons.fabric.testing.TestChunkInputReplacerEvent;
import com.seibel.distanthorizons.fabric.testing.TestWorldGenBindingEvent;
import net.fabricmc.fabric.api.entity.event.v1.ServerEntityWorldChangeEvents;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerChunkEvents;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerWorldEvents;
import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents;
import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking;
import net.minecraft.client.Minecraft;
@@ -39,6 +37,14 @@ import net.fabricmc.fabric.api.networking.v1.PayloadTypeRegistry;
import com.seibel.distanthorizons.core.network.messages.AbstractNetworkMessage;
#endif
#if MC_VER <= MC_1_21_11
import net.fabricmc.fabric.api.entity.event.v1.ServerEntityWorldChangeEvents;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerWorldEvents;
#else
import net.fabricmc.fabric.api.entity.event.v1.ServerEntityLevelChangeEvents;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLevelEvents;
#endif
/**
* This handles all events sent to the server,
* and is the starting point for most of the mod.
@@ -101,18 +107,31 @@ public class FabricServerProxy implements AbstractModInitializer.IEventProxy
});
// ServerLevelLoadEvent
#if MC_VER <= MC_1_21_11
ServerWorldEvents.LOAD.register((server, level) ->
#else
ServerLevelEvents.LOAD.register((server, level) ->
#endif
{
ServerApi.INSTANCE.serverLevelLoadEvent(this.getServerLevelWrapper(level));
});
// ServerLevelUnloadEvent
#if MC_VER <= MC_1_21_11
ServerWorldEvents.UNLOAD.register((server, level) ->
#else
ServerLevelEvents.UNLOAD.register((server, level) ->
#endif
{
ServerApi.INSTANCE.serverLevelUnloadEvent(this.getServerLevelWrapper(level));
});
// ServerChunkLoadEvent
#if MC_VER <= MC_1_21_11
ServerChunkEvents.CHUNK_LOAD.register((server, chunk) ->
#else
ServerChunkEvents.CHUNK_LOAD.register((server, chunk, generated) ->
#endif
{
ILevelWrapper level = this.getServerLevelWrapper((ServerLevel) chunk.getLevel());
ServerApi.INSTANCE.serverChunkLoadEvent(
@@ -129,7 +148,12 @@ public class FabricServerProxy implements AbstractModInitializer.IEventProxy
{
ServerApi.INSTANCE.serverPlayerDisconnectEvent(this.getServerPlayerWrapper(handler.player));
});
#if MC_VER <= MC_1_21_11
ServerEntityWorldChangeEvents.AFTER_PLAYER_CHANGE_WORLD.register((player, originLevel, destinationLevel) ->
#else
ServerEntityLevelChangeEvents.AFTER_PLAYER_CHANGE_LEVEL.register((player, originLevel, destinationLevel) ->
#endif
{
ServerApi.INSTANCE.serverPlayerLevelChangeEvent(
this.getServerPlayerWrapper(player),
@@ -138,7 +162,16 @@ public class FabricServerProxy implements AbstractModInitializer.IEventProxy
);
});
#if MC_VER >= MC_1_20_6
#if MC_VER < MC_1_20_6
ServerPlayNetworking.registerGlobalReceiver(AbstractPluginPacketSender.WRAPPER_PACKET_RESOURCE, (server, serverPlayer, handler, buffer, packetSender) ->
{
AbstractNetworkMessage message = PACKET_SENDER.decodeMessage(buffer);
if (message != null)
{
ServerApi.INSTANCE.pluginMessageReceived(ServerPlayerWrapper.getWrapper(serverPlayer), message);
}
});
#elif MC_VER <= MC_1_21_11
PayloadTypeRegistry.playC2S().register(CommonPacketPayload.TYPE, new CommonPacketPayload.Codec());
if (this.isDedicatedServer)
{
@@ -154,13 +187,19 @@ public class FabricServerProxy implements AbstractModInitializer.IEventProxy
ServerApi.INSTANCE.pluginMessageReceived(ServerPlayerWrapper.getWrapper(context.player()), payload.message());
});
#else
ServerPlayNetworking.registerGlobalReceiver(AbstractPluginPacketSender.WRAPPER_PACKET_RESOURCE, (server, serverPlayer, handler, buffer, packetSender) ->
PayloadTypeRegistry.serverboundPlay().register(CommonPacketPayload.TYPE, new CommonPacketPayload.Codec());
if (this.isDedicatedServer)
{
AbstractNetworkMessage message = PACKET_SENDER.decodeMessage(buffer);
if (message != null)
PayloadTypeRegistry.clientboundPlay().register(CommonPacketPayload.TYPE, new CommonPacketPayload.Codec());
}
ServerPlayNetworking.registerGlobalReceiver(CommonPacketPayload.TYPE, (payload, context) ->
{
if (payload.message() == null)
{
ServerApi.INSTANCE.pluginMessageReceived(ServerPlayerWrapper.getWrapper(serverPlayer), message);
return;
}
ServerApi.INSTANCE.pluginMessageReceived(ServerPlayerWrapper.getWrapper(context.player()), payload.message());
});
#endif
}
@@ -47,6 +47,11 @@ import com.mojang.blaze3d.textures.GpuSampler;
public class MixinChunkSectionsToRender
{
//===========//
// Pre MC 26 //
//===========//
//regino
#if MC_VER <= MC_1_21_11
#if MC_VER <= MC_1_21_10
// needs to fire at HEAD with a lower than normal order (less than 1000)
@@ -74,6 +79,51 @@ public class MixinChunkSectionsToRender
}
}
//endregion
#else
//============//
// post MC 26 //
//============//
//region
// needs to fire at HEAD with a lower than normal order (less than 1000)
// otherwise it will be canceled by Sodium
@Inject(at = @At("HEAD"), method = "renderGroup", order = 800)
private void renderDeferredLayerHead(ChunkSectionLayerGroup chunkSectionLayerGroup, GpuSampler gpuSampler, CallbackInfo ci)
{
ClientApi.RENDER_STATE.clientLevelWrapper = ClientLevelWrapper.getWrapperIfDifferent(ClientApi.RENDER_STATE.clientLevelWrapper, Minecraft.getInstance().levelRenderer.level);
ClientApi.RENDER_STATE.canRenderOrThrow();
if (chunkSectionLayerGroup == ChunkSectionLayerGroup.TRANSLUCENT)
{
ClientApi.INSTANCE.renderDeferredLodsForShaders();
}
else if (chunkSectionLayerGroup == ChunkSectionLayerGroup.OPAQUE)
{
ClientApi.INSTANCE.renderFadeTransparent();
ClientApi.INSTANCE.renderLods();
}
}
@Inject(at = @At("RETURN"), method = "renderGroup", order = 800)
private void renderDeferredLayerReturn(ChunkSectionLayerGroup chunkSectionLayerGroup, GpuSampler gpuSampler, CallbackInfo ci)
{
ClientApi.RENDER_STATE.canRenderOrThrow();
if (chunkSectionLayerGroup == ChunkSectionLayerGroup.TRANSLUCENT)
{
ClientApi.INSTANCE.renderFadeOpaque();
}
}
//endregion
#endif
}
@@ -47,30 +47,39 @@ import org.joml.Matrix4fc;
import org.joml.Vector4f;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
#else
#elif MC_VER <= MC_1_21_11
import com.mojang.blaze3d.buffers.GpuBufferSlice;
import com.mojang.blaze3d.resource.GraphicsResourceAllocator;
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftRenderWrapper;
import net.minecraft.client.Camera;
import net.minecraft.client.DeltaTracker;
import net.minecraft.client.renderer.chunk.ChunkSectionsToRender;
import org.joml.Matrix4f;
import org.joml.Matrix4fc;
import org.joml.Vector4f;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
#else
import com.mojang.blaze3d.buffers.GpuBufferSlice;
import com.mojang.blaze3d.resource.GraphicsResourceAllocator;
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftRenderWrapper;
import net.minecraft.client.DeltaTracker;
import net.minecraft.client.renderer.chunk.ChunkSectionsToRender;
import org.joml.Matrix4fc;
import org.joml.Vector4f;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import net.minecraft.client.renderer.state.level.CameraRenderState;
#endif
import com.seibel.distanthorizons.common.wrappers.McObjectConverter;
import com.seibel.distanthorizons.common.wrappers.world.ClientLevelWrapper;
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftRenderWrapper;
import com.seibel.distanthorizons.core.api.internal.ClientApi;
import com.seibel.distanthorizons.coreapi.ModInfo;
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.client.renderer.LevelRenderer;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
@@ -91,6 +100,13 @@ public class MixinLevelRenderer
private static final DhLogger LOGGER = new DhLoggerBuilder().build();
//===========//
// Pre MC 26 //
//===========//
//region
#if MC_VER <= MC_1_21_11
#if MC_VER < MC_1_17_1
@Inject(at = @At("HEAD"),
method = "renderChunkLayer(Lnet/minecraft/client/renderer/RenderType;Lcom/mojang/blaze3d/vertex/PoseStack;DDD)V",
@@ -128,7 +144,7 @@ public class MixinLevelRenderer
Vector4f skyColor, boolean thinFog, CallbackInfo callback)
#endif
{
#if MC_VER == MC_1_16_5
#if MC_VER <= MC_1_16_5
// get the matrices from the OpenGL fixed pipeline
float[] mcProjMatrixRaw = new float[16];
GL32.glGetFloatv(GL32.GL_PROJECTION_MATRIX, mcProjMatrixRaw);
@@ -190,6 +206,64 @@ public class MixinLevelRenderer
}
#endif
#endif
//endregion
//============//
// post MC 26 //
//============//
//region
#if MC_VER <= MC_1_21_11
#else
@Inject(at = @At("HEAD"), method = "prepareChunkRenders")
private void prepareChunkRenders(final Matrix4fc modelViewMatrix, CallbackInfoReturnable<ChunkSectionsToRender> callback)
{
ClientApi.RENDER_STATE.clientLevelWrapper = ClientLevelWrapper.getWrapperIfDifferent(ClientApi.RENDER_STATE.clientLevelWrapper, this.level);
}
@Inject(at = @At("HEAD"), method = "renderLevel")
public void renderLevel(
final GraphicsResourceAllocator resourceAllocator, final DeltaTracker deltaTracker,
final boolean renderBlockOutline, final CameraRenderState camera,
final Matrix4fc modelViewMatrix, final GpuBufferSlice terrainFog,
final Vector4f fogColor, final boolean shouldRenderSky,
final ChunkSectionsToRender chunkSectionsToRender,
CallbackInfo callback)
{
ClientApi.RENDER_STATE.mcModelViewMatrix = McObjectConverter.Convert(modelViewMatrix);
ClientApi.RENDER_STATE.mcProjectionMatrix = McObjectConverter.Convert(camera.projectionMatrix);
ClientApi.RENDER_STATE.partialTickTime = MinecraftRenderWrapper.INSTANCE.getPartialTickTime();
}
@Inject(
method = "addMainPass(Lcom/mojang/blaze3d/framegraph/FrameGraphBuilder;Lnet/minecraft/client/renderer/culling/Frustum;Lorg/joml/Matrix4fc;Lcom/mojang/blaze3d/buffers/GpuBufferSlice;ZLnet/minecraft/client/renderer/state/level/LevelRenderState;Lnet/minecraft/client/DeltaTracker;Lnet/minecraft/util/profiling/ProfilerFiller;Lnet/minecraft/client/renderer/chunk/ChunkSectionsToRender;)V",
at = @At(
value = "RETURN",
target = "Lcom/mojang/blaze3d/framegraph/FramePass;executes(Ljava/lang/Runnable;)V",
remap = false
)
)
public void addMainPass(
CallbackInfo ci)
{
// only crash during development
if (ModInfo.IS_DEV_BUILD)
{
ClientApi.RENDER_STATE.canRenderOrThrow();
}
ClientApi.INSTANCE.renderLods();
}
#endif
//endregion
@@ -24,7 +24,6 @@ import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
import net.minecraft.client.renderer.LightTexture;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
@@ -43,8 +42,19 @@ import com.mojang.blaze3d.opengl.GlTexture;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.textures.GpuTexture;
#endif
#if MC_VER <= MC_1_21_11
import net.minecraft.client.renderer.LightTexture;
#else
import net.minecraft.client.renderer.state.LightmapRenderState;
import net.minecraft.client.renderer.Lightmap;
#endif
#if MC_VER <= MC_1_21_11
@Mixin(LightTexture.class)
#else
@Mixin(Lightmap.class)
#endif
public class MixinLightTexture
{
@@ -67,8 +77,13 @@ public class MixinLightTexture
#if MC_VER <= MC_1_21_11
@Inject(method = "updateLightTexture(F)V", at = @At("RETURN"))
public void updateLightTexture(float partialTicks, CallbackInfo ci)
#else
@Inject(method = "render(Lnet/minecraft/client/renderer/state/LightmapRenderState;)V", at = @At("RETURN"))
public void render(LightmapRenderState renderState, CallbackInfo ci)
#endif
{
IMinecraftClientWrapper mc = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class);
if (mc == null)
@@ -1,25 +1,12 @@
package com.seibel.distanthorizons.fabric.mixins.client;
import com.seibel.distanthorizons.common.commonMixins.DhUpdateScreenBase;
import com.seibel.distanthorizons.common.wrappers.world.ClientLevelWrapper;
import com.seibel.distanthorizons.core.api.internal.ClientApi;
import com.seibel.distanthorizons.core.jar.updater.SelfUpdater;
import com.seibel.distanthorizons.core.logging.DhLogger;
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import com.seibel.distanthorizons.coreapi.ModInfo;
import net.minecraft.SharedConstants;
import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.ClientLevel;
import org.spongepowered.asm.mixin.*;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
/**
* At the moment this is only used for the auto updater
*
* @author coolGi
*/
@Mixin(SharedConstants.class)
public abstract class MixinSharedConstants
{
@@ -29,7 +16,8 @@ public abstract class MixinSharedConstants
@Inject(method = "<clinit>", at = @At("TAIL"))
private static void setIsRunningInIde(CallbackInfo ci)
{
IS_RUNNING_IN_IDE = true;
// run extra validation for dev builds
IS_RUNNING_IN_IDE = ModInfo.IS_DEV_BUILD;
}
}
+17 -87
View File
@@ -1,107 +1,38 @@
plugins {
// Note: This is only needed for multi-loader projects
// The main architectury loom version is set at the start of the root build.gradle
id "architectury-plugin" version "3.4-SNAPSHOT"
id 'unimined-forge'
}
sourceCompatibility = targetCompatibility = JavaVersion.VERSION_21
architectury {
platformSetupLoomIde()
forge()
}
//loom {
// forge {
// convertAccessWideners.set(true)
// extraAccessWideners.add("lod.accesswidener")
// mixinConfigs("DistantHorizons.mixins.json")
// }
//}
loom {
silentMojangMappingsLicense() // Shut the licencing warning
accessWidenerPath = project(":common").file("src/main/resources/${accessWidenerVersion}.distanthorizons.accesswidener")
forge {
convertAccessWideners = true
extraAccessWideners.add loom.accessWidenerPath.get().asFile.name
mixinConfigs = [
"DistantHorizons.forge.mixins.json"
]
}
// "runs" isn't required, but when we do need it then it can be useful
runs {
client {
client()
setConfigName("Forge Client")
ideConfigGenerated(false) // When true a run configuration file will be generated for IDE's. By default only set to true for the root project.
runDir("../run/client")
vmArgs(
// https://github.com/FabricMC/fabric-loom/issues/915#issuecomment-1609154390
"-Dminecraft.api.auth.host=https://nope.invalid",
"-Dminecraft.api.account.host=https://nope.invalid",
"-Dminecraft.api.session.host=https://nope.invalid",
"-Dminecraft.api.services.host=https://nope.invalid",
// https://netty.io/wiki/reference-counted-objects.html#leak-detection-levels
"-Dio.netty.leakDetection.level=advanced"
)
programArgs("--username", "Dev")
}
server {
server()
setConfigName("Forge Server")
ideConfigGenerated(false)
runDir("../run/server")
vmArgs("-Dio.netty.leakDetection.level=advanced")
}
}
}
remapJar {
inputFile = shadowJar.archiveFile
dependsOn shadowJar
}
// ==================== Mod Dependency Helper ====================
def addMod(path, enabled) {
if (enabled == "2")
dependencies { implementation(path) }
dependencies { modImplementation(path) }
else if (enabled == "1")
dependencies { modCompileOnly(path) }
dependencies { compileOnly(path) }
}
// ==================== Dependencies ====================
dependencies {
minecraft "com.mojang:minecraft:${rootProject.minecraft_version}"
mappings loom.layered() {
// Mojmap mappings
officialMojangMappings()
// Parchment mappings (it adds parameter mappings & javadoc)
parchment("org.parchmentmc.data:parchment-${rootProject.parchment_version}@zip")
}
// Forge
forge "net.minecraftforge:forge:${rootProject.minecraft_version}-${rootProject.forge_version}"
// TerraForged
addMod("curse.maven:TerraForged-363820:${rootProject.terraforged_version}", rootProject.enable_terraforged)
// TerraFirmaCraft
addMod("curse.maven:TerraFirmaCraft-302973:4616004", rootProject.enable_terrafirmacraft)
if ( // Only run on MC 1.20.6 or later
// FIXME: Add an environment variable for the Major, Minor, and Patch version number of Minecraft
minecraft_version.split("\\.")[1].toInteger() >= 20 &&
(
minecraft_version.split("\\.").length > 1 && // Incase there isn't a minor version
minecraft_version.split("\\.")[2].toInteger() >= 6
)
) {
// (potential) hack fix, force jopt-simple to be exactly 5.0.4 because Mojang ships that version, but some transitive dependencies request 6.0+
implementation('net.sf.jopt-simple:jopt-simple:5.0.4') //{ version { strictly '5.0.4' } }
// TODO: Check if this is still needed and if so ensure this code works for MC 26.1+
// (potential) hack fix for MC 1.20.6 and later, force jopt-simple to be exactly 5.0.4 because Mojang ships that version, but some transitive dependencies request 6.0+
def mcParts = rootProject.minecraft_version.split("\\.")
if (mcParts[1].toInteger() >= 20 && (mcParts.length > 2 && mcParts[2].toInteger() >= 6)) {
implementation('net.sf.jopt-simple:jopt-simple:5.0.4')
}
}
// ==================== Tasks ====================
task deleteResources(type: Delete) {
delete file("build/resources/main")
}
@@ -119,4 +50,3 @@ tasks.named('runClient') {
dependsOn(tasks.named('copyAllResources'))
finalizedBy(deleteResources)
}
-1
View File
@@ -1 +0,0 @@
loom.platform=forge
+5 -10
View File
@@ -5,8 +5,8 @@ org.gradle.caching=true
# Mod Info
mod_name=DistantHorizons
mod_version=2.4.6-b-dev
api_version=5.1.0
mod_version=3.0.0-b-dev
api_version=6.0.0
maven_group=com.seibel.distanthorizons
mod_readable_name=Distant Horizons
mod_description=This mod generates and renders simplified terrain beyond the normal view distance at a low performance cost. Allowing you to see much farther without turning your game into a slideshow.
@@ -18,9 +18,9 @@ mod_issues=https://gitlab.com/jeseibel/distant-horizons/-/issues
mod_discord=https://discord.gg/xAB8G4cENx
# Global Plugin Versions
manifold_version=2025.1.31
manifold_version=2026.1.6
# 2023.1.17 can be used if there are mystery Java compiler issues
nightconfig_version=3.6.6
nightconfig_version=3.8.3
lz4_version=1.8.0
xz_version=1.9
zstd_version=1.5.7-6
@@ -34,11 +34,6 @@ fastutil_version=8.2.1
log4j_version=2.23.1
joml_version=1.10.2
# Architectury config
# this is necessary for MC 1.21.3 because including Sodium and Iris throws "Mod was built with a newer version of Loom (1.8.9), you are using Loom (1.7.415)"
loom.ignoreDependencyLoomVersionValidation=true
# These are here so they can be changed with cmd arguments
# If they are null, they would be automatically set
# (This is mainly used for the CI)
@@ -51,7 +46,7 @@ versionStr=
# This defines what MC version Intellij will use for the preprocessor
# and what version is used automatically by build and run commands
mcVer=1.21.11
mcVer=1.26.1
# Defines the maximum amount of memory Minecraft is allowed when run in a development environment
#minecraftMemoryJavaArg="-Xmx4G"
+1 -1
View File
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-9.4.1-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
+12 -73
View File
@@ -1,104 +1,43 @@
plugins {
// Note: This is only needed for multi-loader projects
// The main architectury loom version is set at the start of the root build.gradle
id "architectury-plugin" version "3.4-SNAPSHOT"
}
sourceCompatibility = targetCompatibility = JavaVersion.VERSION_17
architectury {
platformSetupLoomIde()
neoForge()
}
loom {
silentMojangMappingsLicense() // Shut the licencing warning
accessWidenerPath = project(":common").file("src/main/resources/${accessWidenerVersion}.distanthorizons.accesswidener")
neoForge {
// Access wideners are defined in the `remapJar.atAccessWideners`
// Mixins are defined in the `mods.toml`
}
mixin {
// Mixins are defined in the `mods.toml`
}
// "runs" isn't required, but when we do need it then it can be useful
runs {
client {
client()
setConfigName("NeoForge Client")
ideConfigGenerated(false) // When true a run configuration file will be generated for IDE's. By default only set to true for the root project.
runDir("../run/client")
vmArgs("-Dio.netty.leakDetection.level=advanced") // https://netty.io/wiki/reference-counted-objects.html#leak-detection-levels
// "--renderDebugLabels" is a Mojang command to show render names in RenderDoc
programArgs("--username", "Dev", "--renderDebugLabels")
}
server {
server()
setConfigName("NeoForge Server")
ideConfigGenerated(false)
runDir("../run/server")
vmArgs("-Dio.netty.leakDetection.level=advanced")
}
}
id 'unimined-neoforge'
}
// ==================== Mod Dependency Helper ====================
def addMod(path, enabled) {
if (enabled == "2")
dependencies { implementation(path) }
dependencies { modImplementation(path) }
else if (enabled == "1")
dependencies { modCompileOnly(path) }
dependencies { compileOnly(path) }
}
dependencies {
minecraft "com.mojang:minecraft:${rootProject.minecraft_version}"
mappings loom.layered()
{
// Mojmap mappings
officialMojangMappings()
// Parchment mappings (it adds parameter mappings & javadoc)
parchment("org.parchmentmc.data:parchment-${rootProject.parchment_version}@zip")
}
// Neoforge
neoForge "net.neoforged:neoforge:${rootProject.neoforge_version}"
// ==================== Dependencies ====================
dependencies {
// Iris
addMod("maven.modrinth:iris:${rootProject.neo_iris_version}", rootProject.neo_enable_iris)
}
// ==================== Tasks ====================
task deleteResources(type: Delete) {
delete file("build/resources/main")
}
tasks.register('copyAllResources') {
processResources {
dependsOn(copyCoreResources)
dependsOn(copyCommonLoaderResources)
}
processResources {
dependsOn(tasks.named('copyAllResources'))
}
tasks.named('runClient') {
dependsOn(tasks.named('copyAllResources'))
dependsOn(copyCoreResources)
dependsOn(copyCommonLoaderResources)
finalizedBy(deleteResources)
}
remapJar {
inputFile = shadowJar.archiveFile
dependsOn shadowJar
atAccessWideners.add("distanthorizons.accesswidener")
}
sourcesJar {
def commonSources = project(":common").sourcesJar
dependsOn commonSources
-1
View File
@@ -1 +0,0 @@
loom.platform=neoForge
@@ -218,8 +218,13 @@ public class NeoforgeClientProxy implements AbstractModInitializer.IEventProxy
#else
#if MC_VER <= MC_1_21_11
@SubscribeEvent
public void afterLevelEntityRenderEvent(RenderLevelStageEvent.AfterEntities event)
#else
@SubscribeEvent
public void afterLevelEntityRenderEvent(RenderLevelStageEvent.AfterOpaqueFeatures event)
#endif
{
#if MC_VER < MC_1_21_9
ClientApi.RENDER_STATE.clientLevelWrapper = ClientLevelWrapper.getWrapperIfDifferent(ClientApi.RENDER_STATE.clientLevelWrapper, (ClientLevel)event.getLevel());
@@ -35,6 +35,7 @@ import net.minecraft.client.DeltaTracker;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.client.renderer.LevelRenderer;
import net.minecraft.client.renderer.state.level.CameraRenderState;
import org.joml.Matrix4f;
import org.joml.Matrix4fc;
import org.joml.Vector4f;
@@ -77,6 +78,12 @@ public class MixinLevelRenderer
//===========//
// Pre MC 26 //
//===========//
//region
#if MC_VER <= MC_1_21_11
#if MC_VER < MC_1_21_6
@Inject(at = @At("HEAD"), method = "renderSectionLayer")
private void renderChunkLayer(RenderType renderType, double x, double y, double z, Matrix4f modelViewMatrix, Matrix4f projectionMatrix, CallbackInfo callback)
@@ -165,6 +172,71 @@ public class MixinLevelRenderer
}
#endif
#endif
//endregion
//============//
// post MC 26 //
//============//
//region
#if MC_VER <= MC_1_21_11
#else
@Inject(at = @At("HEAD"), method = "prepareChunkRenders")
private void prepareChunkRenders(final Matrix4fc modelViewMatrix, CallbackInfoReturnable<ChunkSectionsToRender> callback)
{
ClientApi.RENDER_STATE.clientLevelWrapper = ClientLevelWrapper.getWrapperIfDifferent(ClientApi.RENDER_STATE.clientLevelWrapper, this.level);
}
@Inject(at = @At("HEAD"), method = "renderLevel")
public void renderLevel(
final GraphicsResourceAllocator resourceAllocator, final DeltaTracker deltaTracker,
final boolean renderBlockOutline, final CameraRenderState camera,
final Matrix4fc modelViewMatrix, final GpuBufferSlice terrainFog,
final Vector4f fogColor, final boolean shouldRenderSky,
final ChunkSectionsToRender chunkSectionsToRender,
CallbackInfo callback)
{
ClientApi.RENDER_STATE.mcModelViewMatrix = McObjectConverter.Convert(modelViewMatrix);
ClientApi.RENDER_STATE.mcProjectionMatrix = McObjectConverter.Convert(camera.projectionMatrix);
ClientApi.RENDER_STATE.partialTickTime = MinecraftRenderWrapper.INSTANCE.getPartialTickTime();
}
@Inject(
method = "addMainPass(Lcom/mojang/blaze3d/framegraph/FrameGraphBuilder;Lnet/minecraft/client/renderer/culling/Frustum;Lorg/joml/Matrix4fc;Lcom/mojang/blaze3d/buffers/GpuBufferSlice;ZLnet/minecraft/client/renderer/state/level/LevelRenderState;Lnet/minecraft/client/DeltaTracker;Lnet/minecraft/util/profiling/ProfilerFiller;Lnet/minecraft/client/renderer/chunk/ChunkSectionsToRender;)V",
at = @At(
value = "RETURN",
target = "Lcom/mojang/blaze3d/framegraph/FramePass;executes(Ljava/lang/Runnable;)V",
remap = false
)
)
public void addMainPass(
CallbackInfo ci)
{
// only crash during development
if (ModInfo.IS_DEV_BUILD)
{
try
{
ClientApi.RENDER_STATE.canRenderOrThrow();
}
catch (IllegalStateException e)
{
return;
}
}
ClientApi.INSTANCE.renderLods();
}
#endif
//endregion

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