Compare commits
32 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| fc516a20d5 | |||
| 791c2c3426 | |||
| b00079897a | |||
| 37b73e1d5c | |||
| 4bd1136713 | |||
| ef98dbd5fd | |||
| 5df0a60b06 | |||
| 9feb20eff8 | |||
| c9267d61a8 | |||
| a29e225a80 | |||
| ae0f3c2b3b | |||
| 852ea75449 | |||
| ab6a5dad2b | |||
| 1a1eaca280 | |||
| 0272f8c57f | |||
| cf09358710 | |||
| b5d833fa3d | |||
| 329dbe9585 | |||
| c7ae7f155e | |||
| 5f7dbb8662 | |||
| ee21548151 | |||
| ca00125960 | |||
| 4067264e72 | |||
| 9c2d243ad4 | |||
| de9d8b0d2e | |||
| 67f4615b34 | |||
| cd7a130ee4 | |||
| 4d17f7aecf | |||
| a59e7500ab | |||
| 40040294e7 | |||
| 783e61ec3d | |||
| e09db5d7df |
@@ -1,19 +0,0 @@
|
|||||||
**/.git
|
|
||||||
**/.gitlab
|
|
||||||
**/.cache
|
|
||||||
|
|
||||||
buildAllJars
|
|
||||||
|
|
||||||
**/_Misc Files
|
|
||||||
*.bat
|
|
||||||
*.md
|
|
||||||
*.sh
|
|
||||||
*.txt
|
|
||||||
|
|
||||||
coreSubProjects/*.md
|
|
||||||
coreSubProjects/*.txt
|
|
||||||
|
|
||||||
**/.gitignore
|
|
||||||
**/.gitattributes
|
|
||||||
**/.gitlab-cy.yml
|
|
||||||
**/.gitmodules
|
|
||||||
-12
@@ -1,12 +0,0 @@
|
|||||||
FROM eclipse-temurin:25-jdk
|
|
||||||
|
|
||||||
WORKDIR /home/build/
|
|
||||||
COPY ./gradlew .
|
|
||||||
RUN chmod +x ./gradlew
|
|
||||||
CMD echo "\r========== [CLEAN: $MC_VER] ==========" && \
|
|
||||||
./gradlew clean -PmcVer="$MC_VER" --gradle-user-home .gradle-cache/ && \
|
|
||||||
echo "\r========== [BUILD: $MC_VER] ==========" && \
|
|
||||||
./gradlew build -PmcVer="$MC_VER" --gradle-user-home .gradle-cache/ && \
|
|
||||||
echo "\r========== [MERGE: $MC_VER] ==========" && \
|
|
||||||
./gradlew mergeJars -PmcVer="$MC_VER" --gradle-user-home .gradle-cache/ && \
|
|
||||||
echo "\r========== [DONE: $MC_VER] =========="
|
|
||||||
@@ -14,89 +14,11 @@ Below is a video demonstrating the system:
|
|||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
## Minecraft and Library Versions
|
|
||||||
|
|
||||||
### This branch supports the following versions of Minecraft:
|
|
||||||
|
|
||||||
#### 1.20.4, 1.20.3 (Default)
|
|
||||||
Fabric: 0.15.1\
|
|
||||||
Fabric API: 0.91.2+1.20.4\
|
|
||||||
Forge: 49.0.30\
|
|
||||||
NeoForge: 118-beta\
|
|
||||||
Parchment: 1.20.2:2023.12.10\
|
|
||||||
Modmenu: 9.0.0-pre.1
|
|
||||||
|
|
||||||
#### 1.20.2
|
|
||||||
Fabric: 0.14.24\
|
|
||||||
Fabric API: 0.90.4+1.20.2\
|
|
||||||
Forge: 48.0.13\
|
|
||||||
Parchment: 1.20.1:2023.09.03\
|
|
||||||
Modmenu: 8.0.0
|
|
||||||
|
|
||||||
#### 1.20.1, 1.20
|
|
||||||
Fabric: 0.14.24\
|
|
||||||
Fabric API: 0.90.4+1.20.1\
|
|
||||||
Forge: 47.2.1\
|
|
||||||
Parchment: 1.20.1:2023.09.03\
|
|
||||||
Modmenu: 7.2.2
|
|
||||||
|
|
||||||
#### 1.19.4
|
|
||||||
Fabric: 0.14.24\
|
|
||||||
Fabric API: 0.87.1+1.19.4\
|
|
||||||
Forge: 45.2.4\
|
|
||||||
Parchment: 1.19.4:2023.06.26\
|
|
||||||
Modmenu: 6.3.1
|
|
||||||
|
|
||||||
#### 1.19.2
|
|
||||||
Fabric: 0.14.24\
|
|
||||||
Fabric API: 0.76.1+1.19.2\
|
|
||||||
Forge: 43.3.2\
|
|
||||||
Parchment: 1.19.2:2022.11.27\
|
|
||||||
Modmenu: 4.2.0-beta.2
|
|
||||||
|
|
||||||
#### 1.18.2
|
|
||||||
Fabric: 0.14.24\
|
|
||||||
Fabric API: 0.76.0+1.18.2\
|
|
||||||
Forge: 40.2.10\
|
|
||||||
Parchment: 1.18.2:2022.11.06\
|
|
||||||
Modmenu: 3.2.5
|
|
||||||
|
|
||||||
#### 1.17.1, 1.17
|
|
||||||
Fabric: 0.14.24\
|
|
||||||
Fabric API: 0.46.1+1.17\
|
|
||||||
Forge: 37.1.1\
|
|
||||||
Parchment: 1.17.1:2021.12.12\
|
|
||||||
Modmenu: 2.0.14
|
|
||||||
|
|
||||||
#### 1.16.5, 1.16.4
|
|
||||||
Fabric: 0.14.24\
|
|
||||||
Fabric API: 0.42.0+1.16\
|
|
||||||
Forge: 36.2.39\
|
|
||||||
Parchment: 1.16.5:2022.03.06\
|
|
||||||
Modmenu: 1.16.22
|
|
||||||
|
|
||||||
### Versions no longer supported
|
|
||||||
- 1.18.1, 1.18
|
|
||||||
- 1.19.1, 1.19
|
|
||||||
- 1.19.3
|
|
||||||
|
|
||||||
<br>
|
|
||||||
|
|
||||||
### Plugin and Library versions
|
|
||||||
|
|
||||||
Gradle: 8.5\
|
|
||||||
Fabric loom: 1.4-SNAPSHOT\
|
|
||||||
Architectury loom (Forge gradle replacement): 1.4-SNAPSHOT\
|
|
||||||
Sponge vanilla gradle: 0.2.1-SNAPSHOT\
|
|
||||||
Java Preprocessor plugin: Manifold Preprocessor
|
|
||||||
|
|
||||||
<br>
|
|
||||||
|
|
||||||
## Source Code Installation
|
## Source Code Installation
|
||||||
|
|
||||||
### Prerequisites
|
### Prerequisites
|
||||||
|
|
||||||
* A Java Development Kit (JDK) for Java 17 (recommended) or newer. <br>
|
* A Java Development Kit (JDK) for Java 25 (recommended) or newer. <br>
|
||||||
Visit https://www.oracle.com/java/technologies/downloads/ for installers.
|
Visit https://www.oracle.com/java/technologies/downloads/ for installers.
|
||||||
* Git or someway to clone git projects. <br>
|
* Git or someway to clone git projects. <br>
|
||||||
Visit https://git-scm.com/ for installers.
|
Visit https://git-scm.com/ for installers.
|
||||||
@@ -104,15 +26,10 @@ Java Preprocessor plugin: Manifold Preprocessor
|
|||||||
|
|
||||||
**If using IntelliJ:**
|
**If using IntelliJ:**
|
||||||
1. Install the Manifold plugin
|
1. Install the Manifold plugin
|
||||||
|
- https://plugins.jetbrains.com/plugin/10057-manifold-ij
|
||||||
2. Open IDEA and import the build.gradle
|
2. Open IDEA and import the build.gradle
|
||||||
3. Refresh the Gradle project in IDEA if required
|
3. Refresh the Gradle project in IDEA if required
|
||||||
|
|
||||||
**If using Eclipse: (Note that Eclipse doesn't support Manifold's preprocessor!)**
|
|
||||||
1. Run the command: `./gradlew geneclipseruns`
|
|
||||||
2. Run the command: `./gradlew eclipse`
|
|
||||||
3. Make sure eclipse has the JDK 17 installed. (This is needed so that eclipse can run minecraft)
|
|
||||||
4. Import the project into eclipse
|
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
## Switching Versions
|
## Switching Versions
|
||||||
@@ -127,72 +44,42 @@ In IntelliJ, you will also need to do a gradle sync if it didn't happen automati
|
|||||||
## Compiling
|
## Compiling
|
||||||
|
|
||||||
Prerequisites:
|
Prerequisites:
|
||||||
- JDK 17 or newer
|
- JDK 25 or newer
|
||||||
|
|
||||||
From the File Explorer:
|
|
||||||
1. Download and extract the project zip
|
|
||||||
2. Download the core from https://gitlab.com/distant-horizons-team/distant-horizons-core and extract into a folder called `coreSubProjects`
|
|
||||||
3. Open a terminal emulator in the project folder (On Windows you can type `cmd` in the title bar)
|
|
||||||
4. Run the commands: `./gradlew assemble` (You may need to use a `.\` on Windows)
|
|
||||||
5. Merge the jars with `./gradlew mergeJars`
|
|
||||||
6. The compiled jar file will be in the folder `Merged`
|
|
||||||
|
|
||||||
From the command line:
|
From the command line:
|
||||||
1. `git clone --recurse-submodules https://gitlab.com/distant-horizons-team/distant-horizons.git`
|
1. `git clone --recurse-submodules https://gitlab.com/distant-horizons-team/distant-horizons.git`
|
||||||
2. `cd distant-horizons`
|
2. `cd distant-horizons`
|
||||||
3. `./gradlew assemble`
|
3. `./gradlew assemble`
|
||||||
4. `./gradlew mergeJars`
|
5. The compiled jar file will be in the folder `\build\libs`
|
||||||
5. The compiled jar file will be in the folder `Merged`
|
|
||||||
|
|
||||||
Run tests with: `./gradlew test`
|
From the File Explorer:
|
||||||
|
1. Download and extract the project zip
|
||||||
|
2. Download the core from https://gitlab.com/distant-horizons-team/distant-horizons-core and extract into a folder called `coreSubProjects`
|
||||||
|
3. Open command prompt/terminal in the project folder
|
||||||
|
4. Run the commands: `./gradlew assemble`
|
||||||
|
6. The compiled jar file will be in the folder `\build\libs`
|
||||||
|
|
||||||
>Note: You can add the argument `-PmcVer=?` to tell gradle to build a selected MC version instead of having to modify the `gradle.properties` file.\
|
>Note: You can add the argument `-PmcVer=?` to tell gradle to build a selected MC version instead of having to modify the `gradle.properties` file.\
|
||||||
> For example: `./gradlew assemble -PmcVer=1.18.2`
|
> For example: `./gradlew assemble -PmcVer=1.18.2`
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
## Compiling with Docker
|
|
||||||
|
|
||||||
`./compile <version>`
|
|
||||||
|
|
||||||
You can also locally compile the DH jars without a Java environment by using Docker. Where `<version>` is the version of Minecraft to compile for (ie `1.20.1`), or the keyword `all`. See [Versions](#minecraft-and-library-versions) for a list of all supported values.
|
|
||||||
|
|
||||||
<br>
|
|
||||||
|
|
||||||
## Other commands
|
## Other commands
|
||||||
|
|
||||||
`./gradlew --refresh-dependencies` to refresh local dependencies.
|
|
||||||
|
|
||||||
`./gradlew clean` to delete any compiled code.
|
|
||||||
|
|
||||||
<br>
|
|
||||||
|
|
||||||
## Note to self
|
|
||||||
|
|
||||||
The Minecraft source code is NOT added to your workspace in an editable way. Minecraft is treated like a normal Library. Sources are there for documentation and research purposes only.
|
|
||||||
|
|
||||||
Source code uses Mojang mappings & [Parchment](https://parchmentmc.org/) mappings.
|
|
||||||
|
|
||||||
To generate the source code run `./gradlew genSources` <br>
|
|
||||||
If your IDE fails to auto-detect the source jars when browsing Minecraft classes; manually select the JAR file ending with -sources.jar when prompted by your IDE. <br>
|
|
||||||
(In IntelliJ it's at the top where it says "choose sources" when browsing a Minecraft class)
|
|
||||||
|
|
||||||
<br>
|
|
||||||
|
|
||||||
## Other Useful commands
|
|
||||||
|
|
||||||
Run the standalone jar: `./gradlew run` <br>
|
Run the standalone jar: `./gradlew run` <br>
|
||||||
Build the standalone jar: `./gradlew core:build` <br>
|
Build the standalone jar: `./gradlew core:build` <br>
|
||||||
Only build Fabric: `./gradlew fabric:assemble` or `./gradlew fabric:build` <br>
|
Only build Fabric: `./gradlew fabric:assemble` or `./gradlew fabric:build` <br>
|
||||||
Only build Forge: `./gradlew forge:assemble` or `./gradlew forge:build` <br>
|
Only build Forge: `./gradlew forge:assemble` or `./gradlew forge:build` <br>
|
||||||
Run the Fabric client (for debugging): `./gradlew fabric:runClient` <br>
|
Run the Fabric client (for debugging): `./gradlew fabric:runClient` <br>
|
||||||
Run the Forge client (for debugging): `./gradlew forge:runClient` <br>
|
Run the Forge client (for debugging): `./gradlew forge:runClient` <br>
|
||||||
|
Delete all compiled code: `./gradlew clean` <br>
|
||||||
|
Refresh local dependencies: `./gradlew --refresh-dependencies`
|
||||||
|
|
||||||
To build all versions: `./buildAll` (all builds will end up in the `Merged` folder)
|
To build all versions: `./buildAll`
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
## Open Source Acknowledgements
|
## Open Source Libraries
|
||||||
|
|
||||||
Forgix (To merge multiple mod versions into one jar) [_Formerly_ [_DHJarMerger_](https://github.com/Ran-helo/DHJarMerger)]\
|
Forgix (To merge multiple mod versions into one jar) [_Formerly_ [_DHJarMerger_](https://github.com/Ran-helo/DHJarMerger)]\
|
||||||
https://github.com/PacifistMC/Forgix
|
https://github.com/PacifistMC/Forgix
|
||||||
@@ -208,3 +95,18 @@ https://github.com/blackears/svgSalamander
|
|||||||
|
|
||||||
sqlite-jdbc\
|
sqlite-jdbc\
|
||||||
https://github.com/xerial/sqlite-jdbc
|
https://github.com/xerial/sqlite-jdbc
|
||||||
|
|
||||||
|
|
||||||
|
## Acknowledgements
|
||||||
|
|
||||||
|
Distant Horizons has been graciously provided an open source license for <a href="https://www.yourkit.com/java/profiler/">YourKit Java Profiler</a>.
|
||||||
|
|
||||||
|
> <img src="https://www.yourkit.com/images/yklogo.png">
|
||||||
|
>
|
||||||
|
> YourKit supports open source projects with innovative and intelligent tools
|
||||||
|
for monitoring and profiling Java and .NET applications.
|
||||||
|
YourKit is the creator of <a href="https://www.yourkit.com/java/profiler/">YourKit Java Profiler</a>,
|
||||||
|
<a href="https://www.yourkit.com/dotnet-profiler/">YourKit .NET Profiler</a>,
|
||||||
|
and <a href="https://www.yourkit.com/youmonitor/">YourKit YouMonitor</a>.
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -54,7 +54,12 @@ repositories {
|
|||||||
url "https://www.cursemaven.com"
|
url "https://www.cursemaven.com"
|
||||||
content { includeGroup "curse.maven" }
|
content { includeGroup "curse.maven" }
|
||||||
}
|
}
|
||||||
maven { url "https://repo.spongepowered.org/maven/" }
|
maven {
|
||||||
|
url "https://repo.spongepowered.org/maven/"
|
||||||
|
// exclusion is needed since sponge has a deprecated version of fabric
|
||||||
|
// that gradle would prefer to get over the up-to-date version modrinth provides
|
||||||
|
content { excludeGroupByRegex "net\\.fabricmc(\\..*)?" }
|
||||||
|
}
|
||||||
maven { url "https://maven.terraformersmc.com/" }
|
maven { url "https://maven.terraformersmc.com/" }
|
||||||
maven { url "https://maven.neoforged.net/releases/" }
|
maven { url "https://maven.neoforged.net/releases/" }
|
||||||
flatDir {
|
flatDir {
|
||||||
@@ -361,6 +366,23 @@ if (isNotCommonProject) {
|
|||||||
!arg.startsWith("-XX:MaxGCPauseMillis")
|
!arg.startsWith("-XX:MaxGCPauseMillis")
|
||||||
}
|
}
|
||||||
runTask.jvmArgs = filteredArgs
|
runTask.jvmArgs = filteredArgs
|
||||||
|
|
||||||
|
// fix (Neo)forge debug running
|
||||||
|
doFirst {
|
||||||
|
def modsDir = rootProject.file("run/${isClient ? 'client' : 'server'}/mods")
|
||||||
|
modsDir.mkdirs()
|
||||||
|
|
||||||
|
// Remove any stale DH jars before copying the fresh one
|
||||||
|
modsDir.listFiles()?.each { file ->
|
||||||
|
if (file.name.startsWith(rootProject.mod_name)) file.delete()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy shadow jar into mods folder so (Neo)Forge discovers it properly
|
||||||
|
copy {
|
||||||
|
from shadowJar.archiveFile
|
||||||
|
into modsDir
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// JVM args
|
// JVM args
|
||||||
runTask.jvmArgs(
|
runTask.jvmArgs(
|
||||||
@@ -371,7 +393,8 @@ if (isNotCommonProject) {
|
|||||||
//"-XX:+ZGenerational",
|
//"-XX:+ZGenerational",
|
||||||
rootProject.minecraftMemoryJavaArg,
|
rootProject.minecraftMemoryJavaArg,
|
||||||
)
|
)
|
||||||
if (isClient) {
|
if (isClient)
|
||||||
|
{
|
||||||
runTask.jvmArgs(
|
runTask.jvmArgs(
|
||||||
"-Dminecraft.api.auth.host=https://nope.invalid",
|
"-Dminecraft.api.auth.host=https://nope.invalid",
|
||||||
"-Dminecraft.api.account.host=https://nope.invalid",
|
"-Dminecraft.api.account.host=https://nope.invalid",
|
||||||
@@ -382,9 +405,17 @@ if (isNotCommonProject) {
|
|||||||
// use a consistent username for easier debugging in a given world (vs randomly teleporting to a new user each time the game boots)
|
// use a consistent username for easier debugging in a given world (vs randomly teleporting to a new user each time the game boots)
|
||||||
"--username", "Dev",
|
"--username", "Dev",
|
||||||
// "--renderDebugLabels" is a Mojang command to show render names in RenderDoc
|
// "--renderDebugLabels" is a Mojang command to show render names in RenderDoc
|
||||||
"--renderDebugLabels",
|
"--renderDebugLabels"
|
||||||
|
)
|
||||||
|
|
||||||
|
// enabling tracy causes constant memory growth so it isn't always desired
|
||||||
|
if (rootProject.minecraftEnableTracy == "true")
|
||||||
|
{
|
||||||
// "--tracy" is a Mojang command to allow individual frames to be debugged using Tracy https://github.com/wolfpld/tracy/releases/tag/v0.13.1
|
// "--tracy" is a Mojang command to allow individual frames to be debugged using Tracy https://github.com/wolfpld/tracy/releases/tag/v0.13.1
|
||||||
"--tracy")
|
runTask.args("--tracy")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+110
@@ -0,0 +1,110 @@
|
|||||||
|
package com.seibel.distanthorizons.common.commonMixins;
|
||||||
|
|
||||||
|
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftClientWrapper;
|
||||||
|
import com.seibel.distanthorizons.core.api.internal.ClientApi;
|
||||||
|
import com.seibel.distanthorizons.core.config.Config;
|
||||||
|
import com.seibel.distanthorizons.core.dependencyInjection.ModAccessorInjector;
|
||||||
|
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.Minecraft;
|
||||||
|
import net.minecraft.client.Camera;
|
||||||
|
import net.minecraft.world.effect.MobEffects;
|
||||||
|
import net.minecraft.world.entity.Entity;
|
||||||
|
import net.minecraft.world.entity.LivingEntity;
|
||||||
|
|
||||||
|
|
||||||
|
import net.minecraft.client.Camera;
|
||||||
|
import net.minecraft.world.effect.MobEffects;
|
||||||
|
import net.minecraft.world.entity.Entity;
|
||||||
|
import net.minecraft.world.entity.LivingEntity;
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_17_1
|
||||||
|
import net.minecraft.world.level.material.FluidState;
|
||||||
|
import net.minecraft.client.renderer.FogRenderer;
|
||||||
|
import net.minecraft.client.renderer.FogRenderer.FogMode;
|
||||||
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
|
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
#elif MC_VER < MC_1_21_3
|
||||||
|
import net.minecraft.world.level.material.FogType;
|
||||||
|
import net.minecraft.client.renderer.FogRenderer;
|
||||||
|
import net.minecraft.client.renderer.FogRenderer.FogMode;
|
||||||
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
|
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
#elif MC_VER < MC_1_21_6
|
||||||
|
import net.minecraft.world.level.material.FogType;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||||
|
import com.mojang.blaze3d.shaders.FogShape;
|
||||||
|
import net.minecraft.client.renderer.FogRenderer;
|
||||||
|
import net.minecraft.client.renderer.FogRenderer.FogMode;
|
||||||
|
import net.minecraft.client.renderer.FogParameters;
|
||||||
|
import org.joml.Vector4f;
|
||||||
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
|
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
#else
|
||||||
|
import net.minecraft.world.level.material.FogType;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
public class MixinVanillaFogCommon
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_21_6
|
||||||
|
public static boolean cancelFog(Camera camera, FogRenderer.FogMode fogMode)
|
||||||
|
#else
|
||||||
|
public static boolean cancelFog()
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_21_6
|
||||||
|
Entity entity = camera.getEntity();
|
||||||
|
#elif MC_VER <= MC_1_21_10
|
||||||
|
Camera camera = Minecraft.getInstance().gameRenderer.getMainCamera();
|
||||||
|
Entity entity = camera.getEntity();
|
||||||
|
#else
|
||||||
|
Camera camera = Minecraft.getInstance().gameRenderer.getMainCamera();
|
||||||
|
Entity entity = camera.entity();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
boolean cameraNotInFluid = cameraNotInFluid(camera);
|
||||||
|
boolean isSpecialFog = (entity instanceof LivingEntity) && ((LivingEntity) entity).hasEffect(MobEffects.BLINDNESS);
|
||||||
|
|
||||||
|
boolean cancelFog = !isSpecialFog;
|
||||||
|
cancelFog = cancelFog && cameraNotInFluid;
|
||||||
|
#if MC_VER < MC_1_21_6
|
||||||
|
cancelFog = cancelFog && (fogMode == FogRenderer.FogMode.FOG_TERRAIN);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
cancelFog = cancelFog && !SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class).isFogStateSpecial();
|
||||||
|
cancelFog = cancelFog && !Config.Client.Advanced.Graphics.Fog.enableVanillaFog.get();
|
||||||
|
|
||||||
|
|
||||||
|
return cancelFog;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean cameraNotInFluid(Camera camera)
|
||||||
|
{
|
||||||
|
#if MC_VER < MC_1_17_1
|
||||||
|
FluidState fluidState = camera.getFluidInCamera();
|
||||||
|
boolean cameraNotInFluid = fluidState.isEmpty();
|
||||||
|
#else
|
||||||
|
FogType fogTypes = camera.getFluidInCamera();
|
||||||
|
boolean cameraNotInFluid = fogTypes == FogType.NONE;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return cameraNotInFluid;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
+23
@@ -57,6 +57,7 @@ import com.seibel.distanthorizons.core.logging.DhLogger;
|
|||||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||||
import com.seibel.distanthorizons.core.logging.f3.F3Screen;
|
import com.seibel.distanthorizons.core.logging.f3.F3Screen;
|
||||||
import com.seibel.distanthorizons.core.render.RenderParams;
|
import com.seibel.distanthorizons.core.render.RenderParams;
|
||||||
|
import com.seibel.distanthorizons.core.render.RenderThreadTaskHandler;
|
||||||
import com.seibel.distanthorizons.core.render.renderer.GenericRenderObjectFactory;
|
import com.seibel.distanthorizons.core.render.renderer.GenericRenderObjectFactory;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.render.objects.IDhGenericObjectVertexBufferContainer;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.render.objects.IDhGenericObjectVertexBufferContainer;
|
||||||
import com.seibel.distanthorizons.core.render.renderer.RenderableBoxGroup;
|
import com.seibel.distanthorizons.core.render.renderer.RenderableBoxGroup;
|
||||||
@@ -615,5 +616,27 @@ public class BlazeDhGenericObjectRenderer implements IDhGenericRenderer
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//================//
|
||||||
|
// base overrides //
|
||||||
|
//================//
|
||||||
|
//region
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close()
|
||||||
|
{
|
||||||
|
// close is called outside the render thread and buffer closing must be done on the render thread
|
||||||
|
RenderThreadTaskHandler.INSTANCE.queueRunningOnRenderThread("Generic Obj Cleanup", () ->
|
||||||
|
{
|
||||||
|
if (this.vertUniformBuffer != null)
|
||||||
|
{
|
||||||
|
this.vertUniformBuffer.close();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
//endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
+23
@@ -748,4 +748,27 @@ public class GlGenericObjectRenderer implements IDhGenericRenderer
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//================//
|
||||||
|
// base overrides //
|
||||||
|
//================//
|
||||||
|
//region
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close()
|
||||||
|
{
|
||||||
|
if (this.boxVertexBuffer != null)
|
||||||
|
{
|
||||||
|
this.boxVertexBuffer.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.boxIndexBuffer != null)
|
||||||
|
{
|
||||||
|
this.boxIndexBuffer.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+215
-32
@@ -23,11 +23,17 @@ 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.GLProxy;
|
||||||
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftGLWrapper;
|
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftGLWrapper;
|
||||||
import com.seibel.distanthorizons.core.config.Config;
|
import com.seibel.distanthorizons.core.config.Config;
|
||||||
|
import com.seibel.distanthorizons.core.jar.EPlatform;
|
||||||
import com.seibel.distanthorizons.core.logging.DhLogger;
|
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||||
|
import com.seibel.distanthorizons.core.logging.f3.F3Screen;
|
||||||
import com.seibel.distanthorizons.core.render.RenderThreadTaskHandler;
|
import com.seibel.distanthorizons.core.render.RenderThreadTaskHandler;
|
||||||
import com.seibel.distanthorizons.core.util.LodUtil;
|
import com.seibel.distanthorizons.core.util.LodUtil;
|
||||||
import com.seibel.distanthorizons.core.util.ThreadUtil;
|
import com.seibel.distanthorizons.core.util.ThreadUtil;
|
||||||
|
import com.seibel.distanthorizons.core.util.objects.Pair;
|
||||||
|
import com.seibel.distanthorizons.core.util.objects.pooling.PhantomLoggingHelper;
|
||||||
|
import com.seibel.distanthorizons.coreapi.ModInfo;
|
||||||
|
import com.seibel.distanthorizons.coreapi.util.StringUtil;
|
||||||
import org.lwjgl.opengl.GL32;
|
import org.lwjgl.opengl.GL32;
|
||||||
import org.lwjgl.opengl.GL44;
|
import org.lwjgl.opengl.GL44;
|
||||||
|
|
||||||
@@ -35,6 +41,8 @@ import java.lang.ref.PhantomReference;
|
|||||||
import java.lang.ref.Reference;
|
import java.lang.ref.Reference;
|
||||||
import java.lang.ref.ReferenceQueue;
|
import java.lang.ref.ReferenceQueue;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.ThreadPoolExecutor;
|
import java.util.concurrent.ThreadPoolExecutor;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
@@ -50,14 +58,35 @@ public class GLBuffer implements AutoCloseable
|
|||||||
private static final MinecraftGLWrapper GLMC = MinecraftGLWrapper.INSTANCE;
|
private static final MinecraftGLWrapper GLMC = MinecraftGLWrapper.INSTANCE;
|
||||||
|
|
||||||
|
|
||||||
|
// TODO move to a shared location that can be handled by both GL and Blaze3D buffers
|
||||||
|
/** if enabled the number of GC'ed buffers will be logged */
|
||||||
|
private static final boolean LOG_PHANTOM_RECOVERY = ModInfo.IS_DEV_BUILD;
|
||||||
|
/** If enabled buffers allocation/upload stacks will be logged when GC'ed. */
|
||||||
|
private static final boolean LOG_PHANTOM_ALLOCATION_STACKS = false; // disabled by default due to the increased GC load
|
||||||
|
|
||||||
public static final double BUFFER_EXPANSION_MULTIPLIER = 1.3;
|
public static final double BUFFER_EXPANSION_MULTIPLIER = 1.3;
|
||||||
public static final double BUFFER_SHRINK_TRIGGER = BUFFER_EXPANSION_MULTIPLIER * BUFFER_EXPANSION_MULTIPLIER;
|
public static final double BUFFER_SHRINK_TRIGGER = BUFFER_EXPANSION_MULTIPLIER * BUFFER_EXPANSION_MULTIPLIER;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* On macOS the legacy OpenGL -> Metal bridge crashes with SIGBUS in
|
||||||
|
* {@code _platform_memmove} when {@code glBufferData} or {@code glBufferSubData}
|
||||||
|
* are called with a large ByteBuffer in one shot. To work around it, we split
|
||||||
|
* the upload into smaller sub-data calls that each fit comfortably inside the
|
||||||
|
* driver's internal staging path. <br>
|
||||||
|
* 256 KiB tuned empirically against macOS 26.5 — a 1 MiB chunk still
|
||||||
|
* tripped the same {@code _platform_memmove} crash inside
|
||||||
|
* {@code glBufferSubData_Exec}, but 256 KiB consistently survives.
|
||||||
|
*/
|
||||||
|
public static final int MAC_UPLOAD_CHUNK_BYTES = 256 * 1024;
|
||||||
|
/** Threshold above which the chunked path kicks in on macOS. */
|
||||||
|
public static final int MAC_UPLOAD_CHUNK_THRESHOLD = MAC_UPLOAD_CHUNK_BYTES;
|
||||||
/** the number of active buffers, can be used for debugging */
|
/** the number of active buffers, can be used for debugging */
|
||||||
public static AtomicInteger bufferCount = new AtomicInteger(0);
|
public static AtomicInteger bufferCount = new AtomicInteger(0);
|
||||||
|
|
||||||
private static final int PHANTOM_REF_CHECK_TIME_IN_MS = 5 * 1000;
|
private static final int PHANTOM_REF_CHECK_TIME_IN_MS = 5 * 1000;
|
||||||
private static final ConcurrentHashMap<PhantomReference<? extends GLBuffer>, Integer> PHANTOM_TO_BUFFER_ID = new ConcurrentHashMap<>();
|
private static final ConcurrentHashMap<PhantomReference<? extends GLBuffer>, Integer> PHANTOM_TO_BUFFER_ID = new ConcurrentHashMap<>();
|
||||||
private static final ConcurrentHashMap<Integer, PhantomReference<? extends GLBuffer>> BUFFER_ID_TO_PHANTOM = new ConcurrentHashMap<>();
|
private static final ConcurrentHashMap<Integer, PhantomReference<? extends GLBuffer>> BUFFER_ID_TO_PHANTOM = new ConcurrentHashMap<>();
|
||||||
|
private static final ConcurrentHashMap<Integer, String> BUFFER_ID_TO_ALLOCATION_STRING = new ConcurrentHashMap<>();
|
||||||
private static final ReferenceQueue<GLBuffer> PHANTOM_REFERENCE_QUEUE = new ReferenceQueue<>();
|
private static final ReferenceQueue<GLBuffer> PHANTOM_REFERENCE_QUEUE = new ReferenceQueue<>();
|
||||||
private static final ThreadPoolExecutor CLEANUP_THREAD = ThreadUtil.makeSingleDaemonThreadPool("GLBuffer Cleanup");
|
private static final ThreadPoolExecutor CLEANUP_THREAD = ThreadUtil.makeSingleDaemonThreadPool("GLBuffer Cleanup");
|
||||||
|
|
||||||
@@ -128,8 +157,9 @@ public class GLBuffer implements AutoCloseable
|
|||||||
long writeStamp = renderStampLock.writeLock();
|
long writeStamp = renderStampLock.writeLock();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
int oldId = this.id;
|
final int oldId = this.id;
|
||||||
this.id = GLMC.glGenBuffers();
|
this.id = GLMC.glGenBuffers();
|
||||||
|
//LOGGER.info("created [" + newId + "].");
|
||||||
|
|
||||||
// destroy the old buffer
|
// destroy the old buffer
|
||||||
// after the new one has been created
|
// after the new one has been created
|
||||||
@@ -139,7 +169,7 @@ public class GLBuffer implements AutoCloseable
|
|||||||
{
|
{
|
||||||
// this ID doesn't need to be tracked anymore
|
// this ID doesn't need to be tracked anymore
|
||||||
tryRemoveBufferIdFromPhantom(oldId);
|
tryRemoveBufferIdFromPhantom(oldId);
|
||||||
destroyBufferIdNow(oldId);
|
destroyBufferIdNow(oldId, "destroyOldAndCreate");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -149,6 +179,8 @@ public class GLBuffer implements AutoCloseable
|
|||||||
PhantomReference<GLBuffer> phantom = new PhantomReference<>(this, PHANTOM_REFERENCE_QUEUE);
|
PhantomReference<GLBuffer> phantom = new PhantomReference<>(this, PHANTOM_REFERENCE_QUEUE);
|
||||||
PHANTOM_TO_BUFFER_ID.put(phantom, this.id);
|
PHANTOM_TO_BUFFER_ID.put(phantom, this.id);
|
||||||
BUFFER_ID_TO_PHANTOM.put(this.id, phantom);
|
BUFFER_ID_TO_PHANTOM.put(this.id, phantom);
|
||||||
|
|
||||||
|
this.updateAllocationStackTrace();
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
@@ -181,7 +213,8 @@ public class GLBuffer implements AutoCloseable
|
|||||||
this.id = 0;
|
this.id = 0;
|
||||||
this.size = 0;
|
this.size = 0;
|
||||||
|
|
||||||
RenderThreadTaskHandler.INSTANCE.queueRunningOnRenderThread("GLBuffer destroyAsync", () -> { destroyBufferIdNow(idToDelete); });
|
//LOGGER.info("async destroy [" + idToDelete + "].");
|
||||||
|
RenderThreadTaskHandler.INSTANCE.queueRunningOnRenderThread("GLBuffer destroyAsync", () -> { destroyBufferIdNow(idToDelete, "destroyAsync"); });
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
@@ -189,49 +222,43 @@ public class GLBuffer implements AutoCloseable
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void destroyBufferIdNow(int id)
|
private static void destroyBufferIdNow(int id, String cause)
|
||||||
{
|
{
|
||||||
// only delete valid buffers
|
// only delete valid buffers
|
||||||
if (id == 0)
|
if (id == 0)
|
||||||
{
|
{
|
||||||
LOGGER.warn("Attempted to destroy a buffer with ID 0, VRAM memory leaks may occur.");
|
LOGGER.warn("Attempted to destroy a buffer with ID 0, VRAM memory leaks may occur, cause: ["+cause+"].");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bufferCount.decrementAndGet();
|
bufferCount.decrementAndGet();
|
||||||
|
GLMC.glDeleteBuffers(id);
|
||||||
|
|
||||||
// destroy the buffer if it exists,
|
if (Config.Client.Advanced.Debugging.logBufferGarbageCollection.get())
|
||||||
// the buffer may not exist if the destroy method is called twice
|
|
||||||
if (GL32.glIsBuffer(id))
|
|
||||||
{
|
{
|
||||||
GLMC.glDeleteBuffers(id);
|
LOGGER.info("destroyed buffer [" + id + "], remaining: [" + BUFFER_ID_TO_PHANTOM.size() + "], cause: ["+cause+"].");
|
||||||
|
|
||||||
if (Config.Client.Advanced.Debugging.logBufferGarbageCollection.get())
|
|
||||||
{
|
|
||||||
LOGGER.info("destroyed buffer [" + id + "], remaining: [" + BUFFER_ID_TO_PHANTOM.size() + "]");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// shouldn't happen, but just in case
|
|
||||||
LOGGER.warn("Attempted to destroy a non buffer object with ID ["+id+"].");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** should be called before {@link GLBuffer#destroyBufferIdNow} */
|
/** should be called before {@link GLBuffer#destroyBufferIdNow} */
|
||||||
private static void tryRemoveBufferIdFromPhantom(int id)
|
private static void tryRemoveBufferIdFromPhantom(int id)
|
||||||
{
|
{
|
||||||
if (BUFFER_ID_TO_PHANTOM.containsKey(id))
|
// will contain nothing if stack tracking isn't enabled
|
||||||
|
BUFFER_ID_TO_ALLOCATION_STRING.remove(id);
|
||||||
|
|
||||||
|
PhantomReference<? extends GLBuffer> phantom = BUFFER_ID_TO_PHANTOM.remove(id);
|
||||||
|
if (phantom != null)
|
||||||
{
|
{
|
||||||
Reference<? extends GLBuffer> phantom = BUFFER_ID_TO_PHANTOM.get(id);
|
|
||||||
|
|
||||||
// if we are manually closing this buffer, we don't want the phantom reference to accidentally close it again
|
// if we are manually closing this buffer, we don't want the phantom reference to accidentally close it again
|
||||||
// this can cause a race condition were we accidentally delete an in-use buffer and cause NVIDIA
|
// this can cause a race condition were we accidentally delete an in-use buffer and cause NVIDIA
|
||||||
// to throw an EXCEPTION_ACCESS_VIOLATION when we attempt to render it
|
// to throw an EXCEPTION_ACCESS_VIOLATION when we attempt to render it
|
||||||
phantom.clear();
|
phantom.clear();
|
||||||
|
|
||||||
PHANTOM_TO_BUFFER_ID.remove(phantom);
|
Integer phantomId = PHANTOM_TO_BUFFER_ID.remove(phantom);
|
||||||
BUFFER_ID_TO_PHANTOM.remove(id);
|
if (phantomId == null)
|
||||||
|
{
|
||||||
|
LOGGER.warn("No Phantom->ID binding stored for ID ["+id+"]");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -322,8 +349,25 @@ public class GLBuffer implements AutoCloseable
|
|||||||
LodUtil.assertTrue(!this.bufferStorage, "Buffer is bufferStorage but its trying to use bufferData upload method!");
|
LodUtil.assertTrue(!this.bufferStorage, "Buffer is bufferStorage but its trying to use bufferData upload method!");
|
||||||
|
|
||||||
int bbSize = bb.limit() - bb.position();
|
int bbSize = bb.limit() - bb.position();
|
||||||
GL32.glBufferData(this.getBufferBindingTarget(), bb, bufferDataHint);
|
int target = this.getBufferBindingTarget();
|
||||||
|
|
||||||
|
if (shouldUploadToGpuInChunks(bbSize))
|
||||||
|
{
|
||||||
|
// Two-step path used on macOS to dodge the Apple OpenGL -> Metal
|
||||||
|
// memmove SIGBUS triggered by uploading a large ByteBuffer in one
|
||||||
|
// glBufferData call:
|
||||||
|
// 1) allocate-only with the size overload (no memcpy)
|
||||||
|
// 2) fill the buffer through chunked glBufferSubData calls
|
||||||
|
GL32.glBufferData(target, (long) bbSize, bufferDataHint);
|
||||||
|
subDataUploadInChunks(target, 0, bb, MAC_UPLOAD_CHUNK_BYTES);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GL32.glBufferData(target, bb, bufferDataHint);
|
||||||
|
}
|
||||||
this.size = bbSize;
|
this.size = bbSize;
|
||||||
|
|
||||||
|
this.updateAllocationStackTrace();
|
||||||
}
|
}
|
||||||
/** Requires the buffer to be bound */
|
/** Requires the buffer to be bound */
|
||||||
protected void uploadSubData(ByteBuffer bb, int maxExpansionSize, int bufferDataHint)
|
protected void uploadSubData(ByteBuffer bb, int maxExpansionSize, int bufferDataHint)
|
||||||
@@ -331,14 +375,30 @@ public class GLBuffer implements AutoCloseable
|
|||||||
LodUtil.assertTrue(!this.bufferStorage, "Buffer is bufferStorage but its trying to use subData upload method!");
|
LodUtil.assertTrue(!this.bufferStorage, "Buffer is bufferStorage but its trying to use subData upload method!");
|
||||||
|
|
||||||
int bbSize = bb.limit() - bb.position();
|
int bbSize = bb.limit() - bb.position();
|
||||||
|
int target = this.getBufferBindingTarget();
|
||||||
if (this.size < bbSize || this.size > bbSize * BUFFER_SHRINK_TRIGGER)
|
if (this.size < bbSize || this.size > bbSize * BUFFER_SHRINK_TRIGGER)
|
||||||
{
|
{
|
||||||
int newSize = (int) (bbSize * BUFFER_EXPANSION_MULTIPLIER);
|
int newSize = (int) (bbSize * BUFFER_EXPANSION_MULTIPLIER);
|
||||||
if (newSize > maxExpansionSize) newSize = maxExpansionSize;
|
if (newSize > maxExpansionSize)
|
||||||
GL32.glBufferData(this.getBufferBindingTarget(), newSize, bufferDataHint);
|
{
|
||||||
|
newSize = maxExpansionSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
// allocate-only — no memcpy, safe on macOS regardless of size
|
||||||
|
GL32.glBufferData(target, (long) newSize, bufferDataHint);
|
||||||
this.size = newSize;
|
this.size = newSize;
|
||||||
}
|
}
|
||||||
GL32.glBufferSubData(this.getBufferBindingTarget(), 0, bb);
|
|
||||||
|
if (shouldUploadToGpuInChunks(bbSize))
|
||||||
|
{
|
||||||
|
subDataUploadInChunks(target, 0, bb, MAC_UPLOAD_CHUNK_BYTES);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GL32.glBufferSubData(target, 0, bb);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.updateAllocationStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
//endregion
|
//endregion
|
||||||
@@ -396,6 +456,91 @@ public class GLBuffer implements AutoCloseable
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* macOS-only mitigation for the SIGBUS in
|
||||||
|
* {@code libsystem_platform.dylib _platform_memmove} that happens when the
|
||||||
|
* Apple OpenGL -> Metal translation layer copies a single large ByteBuffer
|
||||||
|
* out of LWJGL into driver memory. Splitting the copy into
|
||||||
|
* {@link #MAC_UPLOAD_CHUNK_BYTES} slices keeps every memmove inside a size
|
||||||
|
* the bridge handles reliably.
|
||||||
|
*/
|
||||||
|
private static boolean shouldUploadToGpuInChunks(int byteCount)
|
||||||
|
{
|
||||||
|
return EPlatform.get() == EPlatform.MACOS
|
||||||
|
&& byteCount > MAC_UPLOAD_CHUNK_THRESHOLD;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Uploads {@code bb} into the currently bound buffer at {@code baseOffset}
|
||||||
|
* using a sequence of {@link GL32#glBufferSubData(int, long, ByteBuffer)}
|
||||||
|
* calls of at most {@code chunkBytes} each. The buffer's position/limit are
|
||||||
|
* restored before returning.
|
||||||
|
*/
|
||||||
|
private static void subDataUploadInChunks(int target, int baseOffset, ByteBuffer bb, int chunkBytes)
|
||||||
|
{
|
||||||
|
final int origPos = bb.position();
|
||||||
|
final int origLimit = bb.limit();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
final int total = origLimit - origPos;
|
||||||
|
int uploaded = 0;
|
||||||
|
while (uploaded < total)
|
||||||
|
{
|
||||||
|
int chunk = Math.min(chunkBytes, total - uploaded);
|
||||||
|
bb.position(origPos + uploaded);
|
||||||
|
bb.limit(origPos + uploaded + chunk);
|
||||||
|
GL32.glBufferSubData(target, (long) (baseOffset + uploaded), bb);
|
||||||
|
uploaded += chunk;
|
||||||
|
// Force the driver to drain its command queue between chunks
|
||||||
|
// so the OpenGL -> Metal bridge processes (and frees) each
|
||||||
|
// staging copy before the next sub-data call piles another
|
||||||
|
// memmove on top of it.
|
||||||
|
if (uploaded < total)
|
||||||
|
{
|
||||||
|
GL32.glFlush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
bb.limit(origLimit);
|
||||||
|
bb.position(origPos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* used to help track down leaks where the buffer isn't properly closed
|
||||||
|
* Note: this probably needs extending to accept a stack trace from outside where it's being called
|
||||||
|
* since it's often called on the render thread in an un-helpful location.
|
||||||
|
*/
|
||||||
|
public void updateAllocationStackTrace()
|
||||||
|
{
|
||||||
|
if (LOG_PHANTOM_ALLOCATION_STACKS)
|
||||||
|
{
|
||||||
|
String stack;
|
||||||
|
|
||||||
|
RenderThreadTaskHandler.QueuedRunnable parentQueuedRunnable;
|
||||||
|
// if this is running on the render thread, try getting the render task's stack trace instead
|
||||||
|
// since it's a lot more helpful than wherever the render thread tasks themselves are being run from
|
||||||
|
if (RenderThreadTaskHandler.INSTANCE.isCurrentThread()
|
||||||
|
&& (parentQueuedRunnable = RenderThreadTaskHandler.INSTANCE.getCurrentlyRunningTask()) != null
|
||||||
|
&& parentQueuedRunnable.stackTrace != null)
|
||||||
|
{
|
||||||
|
// trim off the getStacktrace() and queueRunningOnRenderThread() methods
|
||||||
|
StackTraceElement[] trimmedElements = Arrays.copyOfRange(parentQueuedRunnable.stackTrace, 2, parentQueuedRunnable.stackTrace.length);
|
||||||
|
stack = StringUtil.join("\n", trimmedElements).intern();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// not running on the render thread, use the normal stack trace
|
||||||
|
StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
|
||||||
|
stack = StringUtil.join("\n", stackTraceElements).intern();
|
||||||
|
}
|
||||||
|
|
||||||
|
BUFFER_ID_TO_ALLOCATION_STRING.put(this.id, stack);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//endregion
|
//endregion
|
||||||
|
|
||||||
|
|
||||||
@@ -407,8 +552,13 @@ public class GLBuffer implements AutoCloseable
|
|||||||
|
|
||||||
private static void runPhantomReferenceCleanupLoop()
|
private static void runPhantomReferenceCleanupLoop()
|
||||||
{
|
{
|
||||||
|
// these arrays are stored here so they don't have to be re-allocated each loop
|
||||||
|
ArrayList<Pair<String, AtomicInteger>> allocationStackTraceCountPairList = new ArrayList<>();
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
|
allocationStackTraceCountPairList.clear();
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -417,20 +567,53 @@ public class GLBuffer implements AutoCloseable
|
|||||||
}
|
}
|
||||||
catch (InterruptedException ignore) { }
|
catch (InterruptedException ignore) { }
|
||||||
|
|
||||||
|
int collectedCount = 0;
|
||||||
|
|
||||||
Reference<? extends GLBuffer> phantomRef = PHANTOM_REFERENCE_QUEUE.poll();
|
Reference<? extends GLBuffer> phantomRef = PHANTOM_REFERENCE_QUEUE.poll();
|
||||||
while (phantomRef != null)
|
while (phantomRef != null)
|
||||||
{
|
{
|
||||||
// destroy the buffer if it hasn't been cleared yet
|
// destroy the buffer if it hasn't been cleared yet
|
||||||
if (PHANTOM_TO_BUFFER_ID.containsKey(phantomRef))
|
Integer idRef = PHANTOM_TO_BUFFER_ID.remove((PhantomReference<? extends GLBuffer>)phantomRef); // cast to make IntelliJ happy
|
||||||
|
if (idRef != null)
|
||||||
{
|
{
|
||||||
int id = PHANTOM_TO_BUFFER_ID.get(phantomRef);
|
BUFFER_ID_TO_PHANTOM.remove(idRef);
|
||||||
RenderThreadTaskHandler.INSTANCE.queueRunningOnRenderThread("GLBuffer phantom destroy", () -> { destroyBufferIdNow(id); });
|
final int id = idRef;
|
||||||
//LOGGER.warn("Buffer Phantom collected, ID: ["+id+"]");
|
RenderThreadTaskHandler.INSTANCE.queueRunningOnRenderThread("GLBuffer phantom destroy", () -> { destroyBufferIdNow(id, "runPhantomReferenceCleanupLoop"); });
|
||||||
|
//LOGGER.info("Buffer Phantom collected, ID: ["+id+"]");
|
||||||
|
|
||||||
|
if (LOG_PHANTOM_ALLOCATION_STACKS) // stack trace shouldn't be null, but just in case
|
||||||
|
{
|
||||||
|
String stack = BUFFER_ID_TO_ALLOCATION_STRING.get(idRef);
|
||||||
|
PhantomLoggingHelper.putAndIncrementTrackingString(stack, allocationStackTraceCountPairList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LOGGER.warn("Failed to find Buffer ID for phantom reference: ["+phantomRef+"]");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
collectedCount++;
|
||||||
phantomRef = PHANTOM_REFERENCE_QUEUE.poll();
|
phantomRef = PHANTOM_REFERENCE_QUEUE.poll();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (LOG_PHANTOM_RECOVERY)
|
||||||
|
{
|
||||||
|
// we only want to log when something has been returned
|
||||||
|
if (collectedCount != 0)
|
||||||
|
{
|
||||||
|
LOGGER.warn("GLBuffer phantom recovered: ["+ F3Screen.NUMBER_FORMAT.format(collectedCount)+"].");
|
||||||
|
|
||||||
|
// log stack traces if present
|
||||||
|
if (LOG_PHANTOM_ALLOCATION_STACKS)
|
||||||
|
{
|
||||||
|
PhantomLoggingHelper.LogAllocationStackTracePairCounts(LOGGER, allocationStackTraceCountPairList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
|||||||
+5
-4
@@ -37,10 +37,11 @@ public class GLIndexBuffer extends GLBuffer
|
|||||||
protected int glType = GL32.GL_UNSIGNED_INT;
|
protected int glType = GL32.GL_UNSIGNED_INT;
|
||||||
public int getGlType() { return this.glType; }
|
public int getGlType() { return this.glType; }
|
||||||
|
|
||||||
public GLIndexBuffer(boolean isBufferStorage)
|
|
||||||
{
|
|
||||||
super(isBufferStorage);
|
public GLIndexBuffer(boolean isBufferStorage) { super(isBufferStorage); }
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void destroyAsync()
|
public void destroyAsync()
|
||||||
|
|||||||
+42
-11
@@ -167,20 +167,46 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
|||||||
return AIR;
|
return AIR;
|
||||||
}
|
}
|
||||||
|
|
||||||
// create a wrapper specifically for the API event to use
|
// pooling wrappers significantly improves chunk->LOD processing speed
|
||||||
BlockStateWrapper apiWrapper = new BlockStateWrapper(blockState, levelWrapper, null);
|
// and also reduces GC pressure
|
||||||
DhApiBlockStateWrapperCreatedEvent.EventParam eventParam = new DhApiBlockStateWrapperCreatedEvent.EventParam(apiWrapper);
|
BlockStateWrapper existingWrapper = WRAPPER_BY_BLOCK_STATE.get(blockState);
|
||||||
ApiEventInjector.INSTANCE.fireAllEvents(DhApiBlockStateWrapperCreatedEvent.class, eventParam);
|
if (existingWrapper != null)
|
||||||
|
|
||||||
if (!eventParam.getOverridesSet())
|
|
||||||
{
|
{
|
||||||
// no changes needed, use the existing object
|
return existingWrapper;
|
||||||
return apiWrapper;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// create a new wrapper using whatever overrides the API user set
|
|
||||||
BlockStateWrapper returnWrapper = new BlockStateWrapper(blockState, levelWrapper, eventParam);
|
|
||||||
return returnWrapper;
|
// synchronized so the API event only fires once per block
|
||||||
|
synchronized (WRAPPER_BY_BLOCK_STATE)
|
||||||
|
{
|
||||||
|
// if another thread already finished this block, use that wrapper
|
||||||
|
existingWrapper = WRAPPER_BY_BLOCK_STATE.get(blockState);
|
||||||
|
if (existingWrapper != null)
|
||||||
|
{
|
||||||
|
return existingWrapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// create a wrapper specifically for the API event to use
|
||||||
|
BlockStateWrapper apiWrapper = new BlockStateWrapper(blockState, levelWrapper, null);
|
||||||
|
DhApiBlockStateWrapperCreatedEvent.EventParam eventParam = new DhApiBlockStateWrapperCreatedEvent.EventParam(apiWrapper);
|
||||||
|
ApiEventInjector.INSTANCE.fireAllEvents(DhApiBlockStateWrapperCreatedEvent.class, eventParam);
|
||||||
|
|
||||||
|
if (!eventParam.getOverridesSet())
|
||||||
|
{
|
||||||
|
// no API changes needed, use the existing object
|
||||||
|
WRAPPER_BY_BLOCK_STATE.putIfAbsent(blockState, apiWrapper);
|
||||||
|
return apiWrapper;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// create a new wrapper using whatever overrides the API user set
|
||||||
|
BlockStateWrapper returnWrapper = new BlockStateWrapper(blockState, levelWrapper, eventParam);
|
||||||
|
WRAPPER_BY_BLOCK_STATE.putIfAbsent(blockState, returnWrapper);
|
||||||
|
return returnWrapper;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
private BlockStateWrapper(
|
private BlockStateWrapper(
|
||||||
@Nullable BlockState blockState, ILevelWrapper levelWrapper,
|
@Nullable BlockState blockState, ILevelWrapper levelWrapper,
|
||||||
@@ -1000,6 +1026,11 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
|||||||
// put if absent in case two threads deserialize at the same time
|
// put if absent in case two threads deserialize at the same time
|
||||||
// unfortunately we can't put everything in a computeIfAbsent() since we also throw exceptions
|
// unfortunately we can't put everything in a computeIfAbsent() since we also throw exceptions
|
||||||
WRAPPER_BY_RESOURCE_LOCATION.putIfAbsent(finalResourceStateString, foundWrapper);
|
WRAPPER_BY_RESOURCE_LOCATION.putIfAbsent(finalResourceStateString, foundWrapper);
|
||||||
|
|
||||||
|
if (foundWrapper != AIR)
|
||||||
|
{
|
||||||
|
WRAPPER_BY_BLOCK_STATE.putIfAbsent(foundWrapper.blockState, foundWrapper);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+55
-47
@@ -260,39 +260,55 @@ public class ClientBlockStateColorCache
|
|||||||
&& !quads.isEmpty()
|
&& !quads.isEmpty()
|
||||||
&& quads.get(0) != null)
|
&& quads.get(0) != null)
|
||||||
{
|
{
|
||||||
BakedQuad firstQuad = quads.get(0);
|
try
|
||||||
|
{
|
||||||
|
BakedQuad firstQuad = quads.get(0);
|
||||||
|
|
||||||
#if MC_VER <= MC_1_21_11
|
#if MC_VER <= MC_1_21_11
|
||||||
this.needPostTinting = firstQuad.isTinted();
|
this.needPostTinting = firstQuad.isTinted();
|
||||||
#else
|
#else
|
||||||
this.needPostTinting = firstQuad.materialInfo().isTinted();
|
this.needPostTinting = firstQuad.materialInfo().isTinted();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if MC_VER <= MC_1_21_4
|
#if MC_VER <= MC_1_21_4
|
||||||
this.tintIndex = firstQuad.getTintIndex();
|
this.tintIndex = firstQuad.getTintIndex();
|
||||||
#elif MC_VER <= MC_1_21_11
|
#elif MC_VER <= MC_1_21_11
|
||||||
this.tintIndex = firstQuad.tintIndex();
|
this.tintIndex = firstQuad.tintIndex();
|
||||||
#else
|
#else
|
||||||
this.tintIndex = firstQuad.materialInfo().tintIndex();
|
this.tintIndex = firstQuad.materialInfo().tintIndex();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if MC_VER < MC_1_17_1
|
#if MC_VER < MC_1_17_1
|
||||||
this.baseColor = calculateColorFromTexture(
|
this.baseColor = calculateColorFromTexture(
|
||||||
firstQuad.sprite,
|
firstQuad.sprite,
|
||||||
EColorMode.getColorMode(this.blockState.getBlock()));
|
EColorMode.getColorMode(this.blockState.getBlock()));
|
||||||
#elif MC_VER < MC_1_21_5
|
#elif MC_VER < MC_1_21_5
|
||||||
this.baseColor = calculateColorFromTexture(
|
this.baseColor = calculateColorFromTexture(
|
||||||
firstQuad.getSprite(),
|
firstQuad.getSprite(),
|
||||||
EColorMode.getColorMode(this.blockState.getBlock()));
|
EColorMode.getColorMode(this.blockState.getBlock()));
|
||||||
#elif MC_VER <= MC_1_21_11
|
#elif MC_VER <= MC_1_21_11
|
||||||
this.baseColor = calculateColorFromTexture(
|
this.baseColor = calculateColorFromTexture(
|
||||||
firstQuad.sprite(),
|
firstQuad.sprite(),
|
||||||
EColorMode.getColorMode(this.blockState.getBlock()));
|
EColorMode.getColorMode(this.blockState.getBlock()));
|
||||||
#else
|
#else
|
||||||
this.baseColor = calculateColorFromTexture(
|
this.baseColor = calculateColorFromTexture(
|
||||||
firstQuad.materialInfo().sprite(),
|
firstQuad.materialInfo().sprite(),
|
||||||
EColorMode.getColorMode(this.blockState.getBlock()));
|
EColorMode.getColorMode(this.blockState.getBlock()));
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
// Shouldn't normally happen, but there was at least
|
||||||
|
// one report of MC's texture being un-loaded
|
||||||
|
// which prevented us from getting the texture.
|
||||||
|
// So we should have some basic backup logic.
|
||||||
|
|
||||||
|
LOGGER.warn("Failed to get texture color for block ["+this.blockStateWrapper.getSerialString()+"] due to: ["+e.getMessage()+"], falling back to particle color.");
|
||||||
|
|
||||||
|
this.needPostTinting = false;
|
||||||
|
this.tintIndex = 0;
|
||||||
|
this.baseColor = this.getParticleIconColor();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -399,22 +415,14 @@ public class ClientBlockStateColorCache
|
|||||||
int scale = 1;
|
int scale = 1;
|
||||||
if (colorMode == EColorMode.Leaves)
|
if (colorMode == EColorMode.Leaves)
|
||||||
{
|
{
|
||||||
//switch (//FIXME add config option)
|
if (a == 0)
|
||||||
// case BLACK:
|
{
|
||||||
// a = 255; //simulate black background of fast leaves
|
continue; //same long grass
|
||||||
// break;
|
}
|
||||||
// case IGNORE:
|
else
|
||||||
if (a == 0) {
|
{
|
||||||
continue; //same long grass
|
a = 255; //just in case there are semi transparent pixels
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
a = 255; //just in case there are semi transparent pixels
|
|
||||||
}
|
|
||||||
// break;
|
|
||||||
// case TRANSPARENT:
|
|
||||||
// break; //do nothing, let it count towards transparency
|
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (a == 0 && colorMode != EColorMode.Glass)
|
else if (a == 0 && colorMode != EColorMode.Glass)
|
||||||
{
|
{
|
||||||
|
|||||||
-31
@@ -1,31 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
publish_version()
|
|
||||||
{
|
|
||||||
if [[ "$2" == "all" || "$1" == "$2" ]]
|
|
||||||
then
|
|
||||||
docker run --name=dh-build-$1 --rm -v /${PWD}:/home/build -e MC_VER=$1 dh-eclipse-temurin
|
|
||||||
cp ./fabric/build/libs/*$1.jar ./buildAllJars/fabric/
|
|
||||||
cp ./forge/build/libs/*$1.jar ./buildAllJars/forge/
|
|
||||||
cp ./Merged/*.jar ./buildAllJars/merged/
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if [ -z "$1" ]
|
|
||||||
then
|
|
||||||
echo "Build target is undefined! [all] [1.20.1] [1.19.4] [1.19.2] [1.18.2] [1.17.1] [1.16.5]"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
docker build --tag=dh-eclipse-temurin -q .
|
|
||||||
|
|
||||||
mkdir -p buildAllJars/fabric
|
|
||||||
mkdir -p buildAllJars/forge
|
|
||||||
mkdir -p buildAllJars/merged
|
|
||||||
publish_version 1.20.1 $1
|
|
||||||
publish_version 1.19.4 $1
|
|
||||||
publish_version 1.19.2 $1
|
|
||||||
publish_version 1.18.2 $1
|
|
||||||
publish_version 1.17.1 $1
|
|
||||||
publish_version 1.16.5 $1
|
|
||||||
+1
-1
Submodule coreSubProjects updated: 1b066327a8...b592012ba8
@@ -1,6 +1,8 @@
|
|||||||
package com.seibel.distanthorizons.fabric;
|
package com.seibel.distanthorizons.fabric;
|
||||||
|
|
||||||
import com.seibel.distanthorizons.api.DhApi;
|
import com.seibel.distanthorizons.api.DhApi;
|
||||||
|
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiBlockColorOverrideEvent;
|
||||||
|
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiBlockStateWrapperCreatedEvent;
|
||||||
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiChunkProcessingEvent;
|
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiChunkProcessingEvent;
|
||||||
import com.seibel.distanthorizons.api.methods.events.DhApiEventRegister;
|
import com.seibel.distanthorizons.api.methods.events.DhApiEventRegister;
|
||||||
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiLevelLoadEvent;
|
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiLevelLoadEvent;
|
||||||
@@ -16,7 +18,9 @@ import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
|||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IPluginPacketSender;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IPluginPacketSender;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
|
||||||
|
import com.seibel.distanthorizons.fabric.testing.TestBlockWrapperCreatedEvent;
|
||||||
import com.seibel.distanthorizons.fabric.testing.TestChunkInputReplacerEvent;
|
import com.seibel.distanthorizons.fabric.testing.TestChunkInputReplacerEvent;
|
||||||
|
import com.seibel.distanthorizons.fabric.testing.TestCustomColorEvent;
|
||||||
import com.seibel.distanthorizons.fabric.testing.TestWorldGenBindingEvent;
|
import com.seibel.distanthorizons.fabric.testing.TestWorldGenBindingEvent;
|
||||||
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerChunkEvents;
|
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.ServerLifecycleEvents;
|
||||||
@@ -87,11 +91,21 @@ public class FabricServerProxy implements AbstractModInitializer.IEventProxy
|
|||||||
|
|
||||||
/* Register the mod needed event callbacks */
|
/* Register the mod needed event callbacks */
|
||||||
|
|
||||||
// can be enabled to test overrides/events without having to build a separate API project
|
// can be enabled to test overrides/events without having to build a separate API project
|
||||||
if (false)
|
|
||||||
{
|
{
|
||||||
DhApiEventRegister.on(DhApiLevelLoadEvent.class, new TestWorldGenBindingEvent());
|
// test custom world gen
|
||||||
DhApi.events.bind(DhApiChunkProcessingEvent.class, new TestChunkInputReplacerEvent());
|
if (false)
|
||||||
|
{
|
||||||
|
DhApiEventRegister.on(DhApiLevelLoadEvent.class, new TestWorldGenBindingEvent());
|
||||||
|
DhApi.events.bind(DhApiChunkProcessingEvent.class, new TestChunkInputReplacerEvent());
|
||||||
|
}
|
||||||
|
|
||||||
|
// test custom colors
|
||||||
|
if (false)
|
||||||
|
{
|
||||||
|
DhApi.events.bind(DhApiBlockColorOverrideEvent.class, new TestCustomColorEvent());
|
||||||
|
DhApi.events.bind(DhApiBlockStateWrapperCreatedEvent.class, new TestBlockWrapperCreatedEvent());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+5
-59
@@ -19,19 +19,13 @@
|
|||||||
|
|
||||||
package com.seibel.distanthorizons.fabric.mixins.client;
|
package com.seibel.distanthorizons.fabric.mixins.client;
|
||||||
|
|
||||||
|
import com.seibel.distanthorizons.common.commonMixins.MixinVanillaFogCommon;
|
||||||
import com.seibel.distanthorizons.core.api.internal.ClientApi;
|
import com.seibel.distanthorizons.core.api.internal.ClientApi;
|
||||||
import com.seibel.distanthorizons.core.config.Config;
|
|
||||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
|
|
||||||
import net.minecraft.client.Minecraft;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Unique;
|
import org.spongepowered.asm.mixin.Unique;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
|
||||||
import net.minecraft.client.Camera;
|
import net.minecraft.client.Camera;
|
||||||
import net.minecraft.world.effect.MobEffects;
|
|
||||||
import net.minecraft.world.entity.Entity;
|
|
||||||
import net.minecraft.world.entity.LivingEntity;
|
|
||||||
|
|
||||||
#if MC_VER < MC_1_17_1
|
#if MC_VER < MC_1_17_1
|
||||||
import net.minecraft.world.level.material.FluidState;
|
import net.minecraft.world.level.material.FluidState;
|
||||||
@@ -42,7 +36,6 @@ import com.mojang.blaze3d.systems.RenderSystem;
|
|||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
#elif MC_VER < MC_1_21_3
|
#elif MC_VER < MC_1_21_3
|
||||||
import net.minecraft.world.level.material.FogType;
|
|
||||||
import net.minecraft.client.renderer.FogRenderer;
|
import net.minecraft.client.renderer.FogRenderer;
|
||||||
import net.minecraft.client.renderer.FogRenderer.FogMode;
|
import net.minecraft.client.renderer.FogRenderer.FogMode;
|
||||||
import com.mojang.blaze3d.systems.RenderSystem;
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
@@ -96,11 +89,11 @@ public class MixinFogRenderer
|
|||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
#if MC_VER < MC_1_21_6
|
#if MC_VER < MC_1_21_6
|
||||||
boolean cancelFog = cancelFog(camera, fogMode);
|
boolean cancelFog = MixinVanillaFogCommon.cancelFog(camera, fogMode);
|
||||||
#elif MC_VER < MC_1_21_6
|
#elif MC_VER < MC_1_21_6
|
||||||
boolean cancelFog = cancelFog(camera);
|
boolean cancelFog = MixinVanillaFogCommon.cancelFog(camera);
|
||||||
#else
|
#else
|
||||||
boolean cancelFog = cancelFog();
|
boolean cancelFog = MixinVanillaFogCommon.cancelFog();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (cancelFog)
|
if (cancelFog)
|
||||||
@@ -142,7 +135,7 @@ public class MixinFogRenderer
|
|||||||
)
|
)
|
||||||
private void onSetRenderDistanceEnd(FogData instance, float value, Operation<Void> original)
|
private void onSetRenderDistanceEnd(FogData instance, float value, Operation<Void> original)
|
||||||
{
|
{
|
||||||
if (cancelFog())
|
if (MixinVanillaFogCommon.cancelFog())
|
||||||
{
|
{
|
||||||
instance.environmentalStart = A_REALLY_REALLY_BIG_VALUE;
|
instance.environmentalStart = A_REALLY_REALLY_BIG_VALUE;
|
||||||
instance.environmentalEnd = A_EVEN_LARGER_VALUE;
|
instance.environmentalEnd = A_EVEN_LARGER_VALUE;
|
||||||
@@ -164,52 +157,5 @@ public class MixinFogRenderer
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@Unique
|
|
||||||
#if MC_VER < MC_1_21_6
|
|
||||||
private static boolean cancelFog(Camera camera, FogMode fogMode)
|
|
||||||
#else
|
|
||||||
private static boolean cancelFog()
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
#if MC_VER < MC_1_21_6
|
|
||||||
Entity entity = camera.getEntity();
|
|
||||||
#elif MC_VER <= MC_1_21_10
|
|
||||||
Camera camera = Minecraft.getInstance().gameRenderer.getMainCamera();
|
|
||||||
Entity entity = camera.getEntity();
|
|
||||||
#else
|
|
||||||
Camera camera = Minecraft.getInstance().gameRenderer.getMainCamera();
|
|
||||||
Entity entity = camera.entity();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
boolean cameraNotInFluid = cameraNotInFluid(camera);
|
|
||||||
boolean isSpecialFog = (entity instanceof LivingEntity) && ((LivingEntity) entity).hasEffect(MobEffects.BLINDNESS);
|
|
||||||
|
|
||||||
boolean cancelFog = !isSpecialFog;
|
|
||||||
cancelFog = cancelFog && cameraNotInFluid;
|
|
||||||
#if MC_VER < MC_1_21_6
|
|
||||||
cancelFog = cancelFog && (fogMode == FogMode.FOG_TERRAIN);
|
|
||||||
#endif
|
|
||||||
cancelFog = cancelFog && !SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class).isFogStateSpecial();
|
|
||||||
cancelFog = cancelFog && !Config.Client.Advanced.Graphics.Fog.enableVanillaFog.get();
|
|
||||||
|
|
||||||
return cancelFog;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Unique
|
|
||||||
private static boolean cameraNotInFluid(Camera camera)
|
|
||||||
{
|
|
||||||
#if MC_VER < MC_1_17_1
|
|
||||||
FluidState fluidState = camera.getFluidInCamera();
|
|
||||||
boolean cameraNotInFluid = fluidState.isEmpty();
|
|
||||||
#else
|
|
||||||
FogType fogTypes = camera.getFluidInCamera();
|
|
||||||
boolean cameraNotInFluid = fogTypes == FogType.NONE;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return cameraNotInFluid;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+43
@@ -0,0 +1,43 @@
|
|||||||
|
package com.seibel.distanthorizons.fabric.testing;
|
||||||
|
|
||||||
|
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiBlockStateWrapperCreatedEvent;
|
||||||
|
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiEventParam;
|
||||||
|
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||||
|
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||||
|
import com.seibel.distanthorizons.core.util.LodUtil;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see TestCustomColorEvent
|
||||||
|
*/
|
||||||
|
public class TestBlockWrapperCreatedEvent extends DhApiBlockStateWrapperCreatedEvent
|
||||||
|
{
|
||||||
|
private static final DhLogger LOGGER = new DhLoggerBuilder().build();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void blockStateWrapperCreated(DhApiEventParam<EventParam> event)
|
||||||
|
{
|
||||||
|
EventParam eventParam = event.value;
|
||||||
|
|
||||||
|
// can be enabled to flip the opacity of transparent/opaque blocks
|
||||||
|
if (false)
|
||||||
|
{
|
||||||
|
if (eventParam.getBlockStateWrapper().getOpacity() == LodUtil.BLOCK_FULLY_OPAQUE)
|
||||||
|
{
|
||||||
|
eventParam.setOpacity(LodUtil.BLOCK_FULLY_TRANSPARENT);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
eventParam.setOpacity(LodUtil.BLOCK_FULLY_OPAQUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// needed for TestCustomColorEvent
|
||||||
|
eventParam.setAllowApiColorOverride(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+86
@@ -0,0 +1,86 @@
|
|||||||
|
package com.seibel.distanthorizons.fabric.testing;
|
||||||
|
|
||||||
|
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiBlockColorOverrideEvent;
|
||||||
|
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiEventParam;
|
||||||
|
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||||
|
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||||
|
import com.seibel.distanthorizons.core.util.LodUtil;
|
||||||
|
import com.seibel.distanthorizons.coreapi.util.ColorUtil;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see TestBlockWrapperCreatedEvent
|
||||||
|
*/
|
||||||
|
public class TestCustomColorEvent extends DhApiBlockColorOverrideEvent
|
||||||
|
{
|
||||||
|
private static final DhLogger LOGGER = new DhLoggerBuilder().build();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void blockStateWrapperCreated(DhApiEventParam<EventParam> event)
|
||||||
|
{
|
||||||
|
EventParam eventParam = event.value;
|
||||||
|
|
||||||
|
//randomDatapointColors(eventParam);
|
||||||
|
//randomPerBlockColors(eventParam);
|
||||||
|
//blackWhitePositionStripe(eventParam);
|
||||||
|
positionRainbow(eventParam);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** each datapoint has a random color */
|
||||||
|
private void randomDatapointColors(EventParam eventParam)
|
||||||
|
{
|
||||||
|
// random colors for each datapoint
|
||||||
|
int a = eventParam.getAlpha();
|
||||||
|
int r = eventParam.getRed();
|
||||||
|
int g = eventParam.getGreen();
|
||||||
|
int b = eventParam.getBlue();
|
||||||
|
|
||||||
|
if (eventParam.getBlockStateWrapper().getOpacity() == LodUtil.BLOCK_FULLY_OPAQUE)
|
||||||
|
{
|
||||||
|
eventParam.setColor(255,r,g,b);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
eventParam.setColor(60,r,g,b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** each block has a different color */
|
||||||
|
private void randomPerBlockColors(EventParam eventParam)
|
||||||
|
{
|
||||||
|
// random colors per block
|
||||||
|
int r = Math.abs(eventParam.getBlockStateWrapper().hashCode() % 255);
|
||||||
|
int g = Math.abs((eventParam.getBlockStateWrapper().hashCode() << 4) % 255);
|
||||||
|
int b = Math.abs((eventParam.getBlockStateWrapper().hashCode() << 8) % 255);
|
||||||
|
eventParam.setColor(r,g,b);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void blackWhitePositionStripe(EventParam eventParam)
|
||||||
|
{
|
||||||
|
// black-white stripes
|
||||||
|
int r = Math.abs(eventParam.getBlockPosX() % 255);
|
||||||
|
int g = r;
|
||||||
|
int b = r;
|
||||||
|
eventParam.setColor(r,g,b);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** rainbow along the X axis repeating every 255 blocks */
|
||||||
|
private void positionRainbow(EventParam eventParam)
|
||||||
|
{
|
||||||
|
float[] ahsv = ColorUtil.argbToAhsv(ColorUtil.RED);
|
||||||
|
float a = ahsv[0];
|
||||||
|
|
||||||
|
int xModPos = Math.abs(eventParam.getBlockPosX() % 510);
|
||||||
|
float h = xModPos < 255 ? xModPos : 510 - xModPos;
|
||||||
|
float s = ahsv[2];
|
||||||
|
float v = ahsv[3];
|
||||||
|
int colorInt = ColorUtil.ahsvToArgb(a,h,s,v);
|
||||||
|
eventParam.setColor(ColorUtil.getRed(colorInt),ColorUtil.getGreen(colorInt),ColorUtil.getBlue(colorInt));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
+5
-2
@@ -18,10 +18,13 @@ def addMod(path, enabled) {
|
|||||||
dependencies {
|
dependencies {
|
||||||
// TerraForged
|
// TerraForged
|
||||||
addMod("curse.maven:TerraForged-363820:${rootProject.terraforged_version}", rootProject.enable_terraforged)
|
addMod("curse.maven:TerraForged-363820:${rootProject.terraforged_version}", rootProject.enable_terraforged)
|
||||||
|
|
||||||
// TerraFirmaCraft
|
// TerraFirmaCraft
|
||||||
addMod("curse.maven:TerraFirmaCraft-302973:4616004", rootProject.enable_terrafirmacraft)
|
addMod("curse.maven:TerraFirmaCraft-302973:4616004", rootProject.enable_terrafirmacraft)
|
||||||
|
|
||||||
|
// Oculus (Iris port)
|
||||||
|
addMod("maven.modrinth:oculus:${rootProject.oculus_version}", rootProject.enable_oculus)
|
||||||
|
|
||||||
// TODO: Check if this is still needed and if so ensure this code works for MC 26.1+
|
// 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+
|
// (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("\\.")
|
def mcParts = rootProject.minecraft_version.split("\\.")
|
||||||
|
|||||||
+12
-25
@@ -19,10 +19,8 @@
|
|||||||
|
|
||||||
package com.seibel.distanthorizons.forge.mixins.client;
|
package com.seibel.distanthorizons.forge.mixins.client;
|
||||||
|
|
||||||
|
import com.seibel.distanthorizons.common.commonMixins.MixinVanillaFogCommon;
|
||||||
import com.seibel.distanthorizons.core.api.internal.ClientApi;
|
import com.seibel.distanthorizons.core.api.internal.ClientApi;
|
||||||
import com.seibel.distanthorizons.core.config.Config;
|
|
||||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
@@ -33,14 +31,6 @@ import com.mojang.blaze3d.systems.RenderSystem;
|
|||||||
import net.minecraft.client.Camera;
|
import net.minecraft.client.Camera;
|
||||||
import net.minecraft.client.renderer.FogRenderer;
|
import net.minecraft.client.renderer.FogRenderer;
|
||||||
import net.minecraft.client.renderer.FogRenderer.FogMode;
|
import net.minecraft.client.renderer.FogRenderer.FogMode;
|
||||||
import net.minecraft.world.effect.MobEffects;
|
|
||||||
import net.minecraft.world.entity.Entity;
|
|
||||||
import net.minecraft.world.entity.LivingEntity;
|
|
||||||
#if MC_VER < MC_1_17_1
|
|
||||||
import net.minecraft.world.level.material.FluidState;
|
|
||||||
#else
|
|
||||||
import net.minecraft.world.level.material.FogType;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@Mixin(FogRenderer.class)
|
@Mixin(FogRenderer.class)
|
||||||
public class MixinFogRenderer
|
public class MixinFogRenderer
|
||||||
@@ -55,29 +45,25 @@ public class MixinFogRenderer
|
|||||||
remap = #if MC_VER == MC_1_17_1 || MC_VER == MC_1_18_2 false #else true #endif ) // Remap messiness due to this being weird in forge
|
remap = #if MC_VER == MC_1_17_1 || MC_VER == MC_1_18_2 false #else true #endif ) // Remap messiness due to this being weird in forge
|
||||||
private static void disableSetupFog(Camera camera, FogMode fogMode, float f, boolean bl, float partTick, CallbackInfo callback)
|
private static void disableSetupFog(Camera camera, FogMode fogMode, float f, boolean bl, float partTick, CallbackInfo callback)
|
||||||
{
|
{
|
||||||
#if MC_VER < MC_1_17_1
|
#if MC_VER < MC_1_21_6
|
||||||
FluidState fluidState = camera.getFluidInCamera();
|
boolean cancelFog = MixinVanillaFogCommon.cancelFog(camera, fogMode);
|
||||||
boolean cameraNotInFluid = fluidState.isEmpty();
|
#elif MC_VER < MC_1_21_6
|
||||||
|
boolean cancelFog = MixinVanillaFogCommon.cancelFog(camera);
|
||||||
#else
|
#else
|
||||||
FogType fogTypes = camera.getFluidInCamera();
|
boolean cancelFog = MixinVanillaFogCommon.cancelFog();
|
||||||
boolean cameraNotInFluid = fogTypes == FogType.NONE;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (cancelFog)
|
||||||
Entity entity = camera.getEntity();
|
|
||||||
boolean isSpecialFog = (entity instanceof LivingEntity) && ((LivingEntity) entity).hasEffect(MobEffects.BLINDNESS);
|
|
||||||
if (!isSpecialFog
|
|
||||||
&& cameraNotInFluid
|
|
||||||
&& fogMode == FogMode.FOG_TERRAIN
|
|
||||||
&& !SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class).isFogStateSpecial()
|
|
||||||
&& !Config.Client.Advanced.Graphics.Fog.enableVanillaFog.get())
|
|
||||||
{
|
{
|
||||||
#if MC_VER < MC_1_17_1
|
#if MC_VER < MC_1_17_1
|
||||||
RenderSystem.fogStart(A_REALLY_REALLY_BIG_VALUE);
|
RenderSystem.fogStart(A_REALLY_REALLY_BIG_VALUE);
|
||||||
RenderSystem.fogEnd(A_EVEN_LARGER_VALUE);
|
RenderSystem.fogEnd(A_EVEN_LARGER_VALUE);
|
||||||
#else
|
#elif MC_VER < MC_1_21_3
|
||||||
RenderSystem.setShaderFogStart(A_REALLY_REALLY_BIG_VALUE);
|
RenderSystem.setShaderFogStart(A_REALLY_REALLY_BIG_VALUE);
|
||||||
RenderSystem.setShaderFogEnd(A_EVEN_LARGER_VALUE);
|
RenderSystem.setShaderFogEnd(A_EVEN_LARGER_VALUE);
|
||||||
|
#elif MC_VER < MC_1_21_6
|
||||||
|
callback.setReturnValue(FogParameters.NO_FOG);
|
||||||
|
#else
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ClientApi.RENDER_STATE.vanillaFogEnabled = false;
|
ClientApi.RENDER_STATE.vanillaFogEnabled = false;
|
||||||
@@ -86,6 +72,7 @@ public class MixinFogRenderer
|
|||||||
{
|
{
|
||||||
ClientApi.RENDER_STATE.vanillaFogEnabled = true;
|
ClientApi.RENDER_STATE.vanillaFogEnabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+22
-7
@@ -23,35 +23,50 @@ import com.seibel.distanthorizons.core.logging.DhLogger;
|
|||||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IIrisAccessor;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IIrisAccessor;
|
||||||
|
|
||||||
|
#if MC_VER == MC_1_20_1
|
||||||
|
import net.irisshaders.iris.Iris;
|
||||||
|
import net.irisshaders.iris.api.v0.IrisApi;
|
||||||
|
#else
|
||||||
|
#endif
|
||||||
|
|
||||||
public class OculusAccessor implements IIrisAccessor
|
public class OculusAccessor implements IIrisAccessor
|
||||||
{
|
{
|
||||||
protected static final DhLogger LOGGER = new DhLoggerBuilder().build();
|
protected static final DhLogger LOGGER = new DhLoggerBuilder().build();
|
||||||
|
|
||||||
|
|
||||||
public OculusAccessor()
|
public OculusAccessor()
|
||||||
{
|
{ LOGGER.warn("Partial Oculus support enabled. Some DH features may be disabled or behave strangely, use Iris instead if possible."); }
|
||||||
LOGGER.warn("Partial Oculus support enabled. Some DH features may be disabled or behave strangely, use Iris instead if possible.");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getModName()
|
public String getModName()
|
||||||
{
|
{
|
||||||
return "oculus";
|
#if MC_VER == MC_1_20_1
|
||||||
|
return Iris.MODID;
|
||||||
|
#else
|
||||||
|
return "iris"; // Oculus doesn't support this MC version
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isShaderPackInUse()
|
public boolean isShaderPackInUse()
|
||||||
{
|
{
|
||||||
// assume shaders are always active
|
#if MC_VER == MC_1_20_1
|
||||||
return true;
|
return IrisApi.getInstance().isShaderPackInUse();
|
||||||
|
#else
|
||||||
|
return true; // Oculus doesn't support this MC version
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isRenderingShadowPass()
|
public boolean isRenderingShadowPass()
|
||||||
{
|
{
|
||||||
return false;
|
#if MC_VER == MC_1_20_1
|
||||||
|
return IrisApi.getInstance().isRenderingShadowPass();
|
||||||
|
#else
|
||||||
|
return false; // Oculus doesn't support this MC version
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-2
@@ -6,8 +6,8 @@ org.gradle.caching=true
|
|||||||
# Mod Info
|
# Mod Info
|
||||||
mod_name=DistantHorizons
|
mod_name=DistantHorizons
|
||||||
api_name=DistantHorizonsApi
|
api_name=DistantHorizonsApi
|
||||||
mod_version=3.0.2-b
|
mod_version=3.0.3-b
|
||||||
api_version=6.1.0
|
api_version=6.1.1
|
||||||
maven_group=com.seibel.distanthorizons
|
maven_group=com.seibel.distanthorizons
|
||||||
mod_readable_name=Distant Horizons
|
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.
|
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.
|
||||||
@@ -51,3 +51,6 @@ mcVer=26.1.2
|
|||||||
|
|
||||||
# Defines the maximum amount of memory Minecraft is allowed when run in a development environment
|
# Defines the maximum amount of memory Minecraft is allowed when run in a development environment
|
||||||
minecraftMemoryJavaArg=-Xmx6G
|
minecraftMemoryJavaArg=-Xmx6G
|
||||||
|
# can be enabled for use with the Tracy profiler, disabled by default since it causes constant memory growth when running
|
||||||
|
minecraftEnableTracy=false
|
||||||
|
|
||||||
|
|||||||
+5
-55
@@ -19,11 +19,8 @@
|
|||||||
|
|
||||||
package com.seibel.distanthorizons.neoforge.mixins.client;
|
package com.seibel.distanthorizons.neoforge.mixins.client;
|
||||||
|
|
||||||
|
import com.seibel.distanthorizons.common.commonMixins.MixinVanillaFogCommon;
|
||||||
import com.seibel.distanthorizons.core.api.internal.ClientApi;
|
import com.seibel.distanthorizons.core.api.internal.ClientApi;
|
||||||
import com.seibel.distanthorizons.core.config.Config;
|
|
||||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
|
|
||||||
import net.minecraft.client.Minecraft;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Unique;
|
import org.spongepowered.asm.mixin.Unique;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
@@ -96,11 +93,11 @@ public class MixinFogRenderer
|
|||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
#if MC_VER < MC_1_21_6
|
#if MC_VER < MC_1_21_6
|
||||||
boolean cancelFog = cancelFog(camera, fogMode);
|
boolean cancelFog = MixinVanillaFogCommon.cancelFog(camera, fogMode);
|
||||||
#elif MC_VER < MC_1_21_6
|
#elif MC_VER < MC_1_21_6
|
||||||
boolean cancelFog = cancelFog(camera);
|
boolean cancelFog = MixinVanillaFogCommon.cancelFog(camera);
|
||||||
#else
|
#else
|
||||||
boolean cancelFog = cancelFog();
|
boolean cancelFog = MixinVanillaFogCommon.cancelFog();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (cancelFog)
|
if (cancelFog)
|
||||||
@@ -142,7 +139,7 @@ public class MixinFogRenderer
|
|||||||
)
|
)
|
||||||
private void onSetRenderDistanceEnd(FogData instance, float value, Operation<Void> original)
|
private void onSetRenderDistanceEnd(FogData instance, float value, Operation<Void> original)
|
||||||
{
|
{
|
||||||
if (cancelFog())
|
if (MixinVanillaFogCommon.cancelFog())
|
||||||
{
|
{
|
||||||
instance.environmentalStart = A_REALLY_REALLY_BIG_VALUE;
|
instance.environmentalStart = A_REALLY_REALLY_BIG_VALUE;
|
||||||
instance.environmentalEnd = A_EVEN_LARGER_VALUE;
|
instance.environmentalEnd = A_EVEN_LARGER_VALUE;
|
||||||
@@ -164,52 +161,5 @@ public class MixinFogRenderer
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@Unique
|
|
||||||
#if MC_VER < MC_1_21_6
|
|
||||||
private static boolean cancelFog(Camera camera, FogMode fogMode)
|
|
||||||
#else
|
|
||||||
private static boolean cancelFog()
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
#if MC_VER < MC_1_21_6
|
|
||||||
Entity entity = camera.getEntity();
|
|
||||||
#elif MC_VER <= MC_1_21_10
|
|
||||||
Camera camera = Minecraft.getInstance().gameRenderer.getMainCamera();
|
|
||||||
Entity entity = camera.getEntity();
|
|
||||||
#else
|
|
||||||
Camera camera = Minecraft.getInstance().gameRenderer.getMainCamera();
|
|
||||||
Entity entity = camera.entity();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
boolean cameraNotInFluid = cameraNotInFluid(camera);
|
|
||||||
boolean isSpecialFog = (entity instanceof LivingEntity) && ((LivingEntity) entity).hasEffect(MobEffects.BLINDNESS);
|
|
||||||
|
|
||||||
boolean cancelFog = !isSpecialFog;
|
|
||||||
cancelFog = cancelFog && cameraNotInFluid;
|
|
||||||
#if MC_VER < MC_1_21_6
|
|
||||||
cancelFog = cancelFog && (fogMode == FogMode.FOG_TERRAIN);
|
|
||||||
#endif
|
|
||||||
cancelFog = cancelFog && !SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class).isFogStateSpecial();
|
|
||||||
cancelFog = cancelFog && !Config.Client.Advanced.Graphics.Fog.enableVanillaFog.get();
|
|
||||||
|
|
||||||
return cancelFog;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Unique
|
|
||||||
private static boolean cameraNotInFluid(Camera camera)
|
|
||||||
{
|
|
||||||
#if MC_VER < MC_1_17_1
|
|
||||||
FluidState fluidState = camera.getFluidInCamera();
|
|
||||||
boolean cameraNotInFluid = fluidState.isEmpty();
|
|
||||||
#else
|
|
||||||
FogType fogTypes = camera.getFluidInCamera();
|
|
||||||
boolean cameraNotInFluid = fogTypes == FogType.NONE;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return cameraNotInFluid;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ forge_version=36.2.39
|
|||||||
|
|
||||||
# Forge mod versions
|
# Forge mod versions
|
||||||
terraforged_version=4044290
|
terraforged_version=4044290
|
||||||
|
oculus_version=
|
||||||
|
|
||||||
# Forge mod run
|
# Forge mod run
|
||||||
# 0 = Don't enable and don't run
|
# 0 = Don't enable and don't run
|
||||||
@@ -62,3 +63,4 @@ forge_version=36.2.39
|
|||||||
enable_starlight_forge=0
|
enable_starlight_forge=0
|
||||||
enable_terraforged=1
|
enable_terraforged=1
|
||||||
enable_terrafirmacraft=0
|
enable_terrafirmacraft=0
|
||||||
|
enable_oculus=0
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ forge_version=37.1.1
|
|||||||
|
|
||||||
# Forge mod versions
|
# Forge mod versions
|
||||||
terraforged_version=
|
terraforged_version=
|
||||||
|
oculus_version=
|
||||||
|
|
||||||
# Forge mod run
|
# Forge mod run
|
||||||
# 0 = Don't enable and don't run
|
# 0 = Don't enable and don't run
|
||||||
@@ -61,3 +62,4 @@ forge_version=37.1.1
|
|||||||
enable_starlight_forge=0
|
enable_starlight_forge=0
|
||||||
enable_terraforged=0
|
enable_terraforged=0
|
||||||
enable_terrafirmacraft=0
|
enable_terrafirmacraft=0
|
||||||
|
enable_oculus=0
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ forge_version=40.2.10
|
|||||||
|
|
||||||
# Forge mod versions
|
# Forge mod versions
|
||||||
terraforged_version=
|
terraforged_version=
|
||||||
|
oculus_version=
|
||||||
|
|
||||||
# Forge mod run
|
# Forge mod run
|
||||||
# 0 = Don't enable and don't run
|
# 0 = Don't enable and don't run
|
||||||
@@ -69,4 +70,5 @@ forge_version=40.2.10
|
|||||||
# 2 = Can be referenced in code and runs in client
|
# 2 = Can be referenced in code and runs in client
|
||||||
enable_starlight_forge=0
|
enable_starlight_forge=0
|
||||||
enable_terraforged=0
|
enable_terraforged=0
|
||||||
enable_terrafirmacraft=0
|
enable_terrafirmacraft=0
|
||||||
|
enable_oculus=0
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ forge_version=43.3.2
|
|||||||
|
|
||||||
# Forge mod versions
|
# Forge mod versions
|
||||||
terraforged_version=
|
terraforged_version=
|
||||||
|
oculus_version=
|
||||||
|
|
||||||
# Forge mod run
|
# Forge mod run
|
||||||
# 0 = Don't enable and don't run
|
# 0 = Don't enable and don't run
|
||||||
@@ -60,3 +61,4 @@ forge_version=43.3.2
|
|||||||
enable_starlight_forge=0
|
enable_starlight_forge=0
|
||||||
enable_terraforged=0
|
enable_terraforged=0
|
||||||
enable_terrafirmacraft=0
|
enable_terrafirmacraft=0
|
||||||
|
enable_oculus=0
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ forge_version=45.2.4
|
|||||||
|
|
||||||
# Forge mod versions
|
# Forge mod versions
|
||||||
terraforged_version=
|
terraforged_version=
|
||||||
|
oculus_version=
|
||||||
|
|
||||||
# Forge mod run
|
# Forge mod run
|
||||||
# 0 = Don't enable and don't run
|
# 0 = Don't enable and don't run
|
||||||
@@ -59,3 +60,4 @@ forge_version=45.2.4
|
|||||||
enable_starlight_forge=0
|
enable_starlight_forge=0
|
||||||
enable_terraforged=0
|
enable_terraforged=0
|
||||||
enable_terrafirmacraft=0
|
enable_terrafirmacraft=0
|
||||||
|
enable_oculus=0
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ forge_version=47.2.1
|
|||||||
|
|
||||||
# Forge mod versions
|
# Forge mod versions
|
||||||
terraforged_version=
|
terraforged_version=
|
||||||
|
oculus_version=1.20.1-1.8.0
|
||||||
|
|
||||||
# Forge mod run
|
# Forge mod run
|
||||||
# 0 = Don't enable and don't run
|
# 0 = Don't enable and don't run
|
||||||
@@ -59,3 +60,4 @@ forge_version=47.2.1
|
|||||||
enable_starlight_forge=0
|
enable_starlight_forge=0
|
||||||
enable_terraforged=0
|
enable_terraforged=0
|
||||||
enable_terrafirmacraft=0
|
enable_terrafirmacraft=0
|
||||||
|
enable_oculus=1
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ forge_version=48.0.13
|
|||||||
|
|
||||||
# Forge mod versions
|
# Forge mod versions
|
||||||
terraforged_version=
|
terraforged_version=
|
||||||
|
oculus_version=
|
||||||
|
|
||||||
# Forge mod run
|
# Forge mod run
|
||||||
# 0 = Don't enable and don't run
|
# 0 = Don't enable and don't run
|
||||||
@@ -59,3 +60,4 @@ forge_version=48.0.13
|
|||||||
enable_starlight_forge=0
|
enable_starlight_forge=0
|
||||||
enable_terraforged=0
|
enable_terraforged=0
|
||||||
enable_terrafirmacraft=0
|
enable_terrafirmacraft=0
|
||||||
|
enable_oculus=0
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ neoforge_version=
|
|||||||
|
|
||||||
# Forge mod versions
|
# Forge mod versions
|
||||||
terraforged_version=
|
terraforged_version=
|
||||||
|
oculus_version=
|
||||||
|
|
||||||
# Forge mod run
|
# Forge mod run
|
||||||
# 0 = Don't enable and don't run
|
# 0 = Don't enable and don't run
|
||||||
@@ -60,3 +61,4 @@ neoforge_version=
|
|||||||
enable_starlight_forge=0
|
enable_starlight_forge=0
|
||||||
enable_terraforged=0
|
enable_terraforged=0
|
||||||
enable_terrafirmacraft=0
|
enable_terrafirmacraft=0
|
||||||
|
enable_oculus=0
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ lwjgl_version=3.3.3
|
|||||||
|
|
||||||
# Fabric loader
|
# Fabric loader
|
||||||
fabric_loader_version=0.16.9
|
fabric_loader_version=0.16.9
|
||||||
fabric_api_version=0.115.0+1.21.1
|
fabric_api_version=0.116.11+1.21.1
|
||||||
# Fabric mod versions
|
# Fabric mod versions
|
||||||
modmenu_version=11.0.0-beta.1
|
modmenu_version=11.0.0-beta.1
|
||||||
starlight_version_fabric=
|
starlight_version_fabric=
|
||||||
|
|||||||
Reference in New Issue
Block a user