Compare commits

...

133 Commits

Author SHA1 Message Date
Vojtěch Šokala 4f3aaecae2 Reduce getWorldBlockLightPosList() work for 1.12.2 by skipping empty chunk sections 2026-06-09 17:10:10 +02:00
Vojtěch Šokala e53622d17c Try to fix LOD builder task spam for 1.12.2 2026-06-09 16:49:07 +02:00
James Seibel 516dab0d29 Try fixing 1.12 compiling in CI 2026-06-09 07:41:34 -05:00
James Seibel 98d68704e1 Fix generic object rendering 2026-06-09 07:29:28 -05:00
James Seibel a13e06d600 Fix Iris boats disabling DH water rendering
Fixes !1262
2026-06-08 22:06:14 -05:00
James Seibel eb82ab1439 Fully generate chunks when using Internal Server
a bit slower than just doing FEATURES, but allows other mods to use the chunks DH generates
2026-06-08 07:27:02 -05:00
Vojtěch Šokala 00b47fc776 Implement auto-updater screen for 1.12.2 2026-06-07 23:01:08 +02:00
Vojtěch Šokala 1d7cb1e6fc Fix camera fluid check in 1.12.2 to use eye position instead of entity position 2026-06-07 22:39:53 +02:00
s809 3da97f75d7 Fix level requests not being sent more than once per session 2026-06-07 14:30:53 +05:00
James Seibel ab7a34be54 Fix auto updater checking when disabled
Fixes !1105
2026-06-06 19:39:07 -05:00
James Seibel e412ec2409 Remove MemUtil references due to native crashing 2026-06-06 18:11:20 -05:00
s809 4a2f7178ee Add original level resource to level init 2026-06-07 01:32:52 +05:00
James Seibel 656bf17191 DH cloud culling/color changes 2026-06-06 11:05:03 -05:00
James Seibel 068399fd2f Fix huge mushroom colors 2026-06-06 10:39:44 -05:00
James Seibel be95801640 Fix underwater fog rendering 2026-06-06 09:13:59 -05:00
Vojtěch Šokala 41e2912de7 Restore texture and depthFunc in GlDhMetaRenderer instead of in CleanroomRenderMixin 2026-06-06 12:21:50 +02:00
Vojtěch Šokala f64072eeab Fix 1.12.2 not compiling 2026-06-06 11:09:09 +02:00
s809 17af90d4e8 Make level key requests work kinda 2026-06-04 23:05:19 +05:00
James Seibel 0dfbcb3c6d Render engine validation cleanup and 26.2.0 prep 2026-06-03 07:45:31 -05:00
James Seibel 19df5c10cb Add error messages if DB becomes corrupted 2026-06-02 21:42:31 -05:00
James Seibel b25afa4ef5 add useCameraPositionForQualityDropOff config/api 2026-06-02 18:05:20 -05:00
James Seibel 9e092091d2 Fix camera position off-by-one with immersive portals 2026-06-02 17:40:58 -05:00
James Seibel 2afefd03b4 fix some MC version compiling 2026-06-02 07:17:11 -05:00
James Seibel 4c65c710f2 add Dh prefix to DH math objects 2026-06-01 22:07:08 -05:00
James Seibel 88710bde46 Fix LOD clouds not showing the correct colors 2026-06-01 21:48:40 -05:00
James Seibel 1ef6382582 remove unused standalone jar files 2026-06-01 19:11:54 -05:00
James Seibel 0393375fae apply immersive portals mixins 2026-06-01 19:05:05 -05:00
James Seibel 608fbd5952 change fabric run client/server to use gradle 2026-06-01 19:04:47 -05:00
James Seibel a94cd91a97 Merge branch 'immersivePortals'
Thanks Acuadragon100!
2026-06-01 07:45:25 -05:00
James Seibel de33cbce2b Clarify the world gen progress message 2026-05-30 19:44:32 -05:00
James Seibel 2b5f621ff8 Fix old MC version compiling 2026-05-30 16:45:16 -05:00
James Seibel 1681adc10b Add the option for 3 layer clouds 2026-05-30 16:39:00 -05:00
James Seibel f606f2b7c2 remove deprecated items 2026-05-30 11:39:45 -05:00
James Seibel e3f9b66994 reduce GC pressure during LOD loading slightly 2026-05-30 11:32:59 -05:00
James Seibel ec3ff260fe Reduce render event GC pressure 2026-05-30 09:17:46 -05:00
James Seibel fafab30a09 clean up blaze buffer uniform creation 2026-05-22 14:09:47 -05:00
James Seibel 707352ce51 fix native GL instanced generic rendering 2026-05-22 12:51:15 -05:00
James Seibel a9f5dafefe re-add fabric modMenuIntegration 2026-05-22 09:59:59 -05:00
James Seibel 291ffd311b fix renderingEngine lang 2026-05-22 09:59:47 -05:00
James Seibel 0e8c0b459b Fix 1.21.11 and older MC compiling 2026-05-22 09:55:25 -05:00
James Seibel c575a2968b update core 2026-05-22 09:37:45 -05:00
James Seibel 0b297b4cd7 add DhApiBeforeFogRenderEvent 2026-05-22 09:37:12 -05:00
Ran b8c90985ce Merge branch 'translations' into 'main'
Trans :3 lations

See merge request distant-horizons-team/distant-horizons!96
2026-05-21 12:46:52 +00:00
Ran b924576983 Trans :3 lations 2026-05-21 12:46:51 +00:00
James Seibel a8b62b31a1 fix 3+ version number ranges 2026-05-20 17:30:33 -05:00
James Seibel 95b2d5a908 fix pre 26.2 compiling 2026-05-20 17:30:13 -05:00
James Seibel 7d2ccc302d fix render api vs engine enum 2026-05-20 07:28:04 -05:00
James Seibel 1ba1bff859 document openGL interfaces not used on Blaze3D
Also add API logic to determine if DH is handling the rendering natively or using an interpretation layer
2026-05-19 21:52:15 -05:00
James Seibel 9409841c89 fix logger GC warning and running wilderwild in dev 2026-05-19 21:16:22 -05:00
James Seibel 6c4e8021d6 Fix DH world gen not priming CARVER heightmaps
Fixes some world gen mods not having access to the necessary heightmaps
2026-05-19 21:04:51 -05:00
James Seibel 4b1623e8c0 Add world gen getBlockState() Y pos validation 2026-05-19 21:03:56 -05:00
James Seibel a1e88bff70 26.1.2 up fabric API 0.145 -> 0.149 2026-05-19 20:58:03 -05:00
James Seibel f3c20cde30 clean up config menu, remove fake transparency 2026-05-19 19:18:15 -05:00
James Seibel eb601d9276 Fix unit test compiling 2026-05-19 07:26:14 -05:00
James Seibel 17a13993cc Fix holes on LOD borders 2026-05-18 22:24:33 -05:00
James Seibel 16e7254179 add IDhApiLevelWrapper.getBlockColorPreApi() 2026-05-18 19:59:56 -05:00
James Seibel ab055f1a0e fix compiling for MC 1.20 and older 2026-05-18 07:21:34 -05:00
James Seibel 0cb3716dc7 move remaining blaze pipeline methods to wrapper 2026-05-17 18:39:13 -05:00
James Seibel 71e9877808 blaze3D renderPassWrapper 2026-05-17 18:30:36 -05:00
James Seibel f05e424c49 lang wrapper update 2026-05-17 18:27:44 -05:00
James Seibel 646882e1a9 update 26.2 snapshot 5 -> 7 2026-05-17 18:20:27 -05:00
James Seibel 482311fe48 Improve ColorCache resolution errors 2026-05-17 18:04:26 -05:00
James Seibel 97a80ed887 Fix renderingString for disabled dimensions 2026-05-16 19:08:02 -05:00
James Seibel 0e547c80a9 Merge branch 'main' of gitlab.com:distant-horizons-team/distant-horizons 2026-05-16 18:58:46 -05:00
James Seibel b792487b60 fix auto update screen on MC 26.2 2026-05-16 18:55:52 -05:00
James Seibel 7920415d18 Improve incorrect rendering API error handling 2026-05-16 18:25:48 -05:00
James Seibel ada7668c28 fix reverseZDepth uniform name 2026-05-16 17:54:46 -05:00
James Seibel e7a34f9498 fix Blaze3D GL pipelines 2026-05-16 17:03:43 -05:00
James Seibel 2a5c465923 BlazeDhRenderApi handle GL and Vulkan 2026-05-16 16:16:15 -05:00
James Seibel a14a558f0d blaze3D shaders work on both GL and Vulkan 2026-05-16 15:50:25 -05:00
James Seibel 66db5f0df1 add reverse Z java code 2026-05-16 10:49:12 -05:00
James Seibel 2dc4ba20fb fix DH Far Fade renderer name 2026-05-16 10:20:24 -05:00
James Seibel 2f14d7ac27 remove forgix workaround 2026-05-16 10:20:09 -05:00
Vojtěch Šokala 6cc659bda5 Make renderingString show correct value if rendering is disabled for this dimension 2026-05-16 13:33:43 +02:00
James Seibel 206e492e7c use DhScreenUtil.setScreen when possible 2026-05-15 22:28:25 -05:00
James Seibel 09289e72a1 Merge branch 'Vulkan' 2026-05-15 22:25:14 -05:00
James Seibel 7861b63c99 Fix auto update screen not appearing on MC 26.1.2
May also be necessary for old MC versions
2026-05-15 22:13:46 -05:00
James Seibel 965b9c948e update api test method name 2026-05-15 22:03:07 -05:00
James Seibel ae4ca8cd6b Mark vertigo as incompatible 2026-05-15 21:45:58 -05:00
James Seibel 2dec862c3b up api version 6.1.1 -> 7.0.0 2026-05-15 21:41:25 -05:00
James Seibel f9d8073e80 Remove fabric-gametest-api from release 2026-05-15 21:35:25 -05:00
James Seibel 2ca99c29d2 config reset button don't change menu 2026-05-15 18:30:12 -05:00
James Seibel 2e4477b533 fix color tints not clearing with other colors 2026-05-15 18:29:53 -05:00
Vojtěch Šokala b0c7919dda Rewrite 1.12.2 world gen 2026-05-15 20:04:57 +02:00
Vojtěch Šokala 398c14ee96 Merge remote-tracking branch 'origin/main' 2026-05-15 18:59:42 +02:00
Vojtěch Šokala 422e54b488 ChangelogScreen for 1.12.2 2026-05-15 18:59:34 +02:00
James Seibel 36f1c49f49 Add MC Version locking to the config 2026-05-15 07:44:22 -05:00
James Seibel 271f4e8b21 Fix compiling MC 1.16.5+ 2026-05-14 20:52:36 -05:00
James Seibel b164e4646d add 1.12.2 to the build script 2026-05-14 20:13:22 -05:00
James Seibel 14fd5729e2 use ModInfo packet path 2026-05-14 20:11:41 -05:00
James Seibel 7c3e279237 preprocessor cleanup 2026-05-14 20:11:32 -05:00
James Seibel 2884094dee refactoring and cleanup 2026-05-14 07:49:32 -05:00
James Seibel 817c268491 Tint color cleanup 2026-05-14 07:11:44 -05:00
Vojtěch Šokala 071a306f14 Preprocessor cleanup 2026-05-14 13:03:32 +02:00
Vojtěch Šokala c97fea6d0a Fix compile of modern 2026-05-14 07:53:00 +02:00
Vojtěch Šokala d94faf828d Preprocessor cleanup + colored beacons for 1.12.2 2026-05-13 23:59:09 +02:00
Vojtěch Šokala 0d6d4b133e Fix compile of modern 2026-05-13 23:58:25 +02:00
James Seibel 5ab6bfb663 preprocessor cleanup 2026-05-13 07:49:18 -05:00
James Seibel e087dbc878 temp unit test disable 2026-05-12 21:56:30 -05:00
James Seibel 391e96ad3d abstract mod init cleanup 2026-05-12 21:54:03 -05:00
James Seibel fbf812091d MC 1.12.2 refactoring and cleanup 2026-05-12 21:38:07 -05:00
James Seibel 7448483f84 revert option screen name for consistency 2026-05-12 08:02:26 -05:00
James Seibel e3d6e1bcc6 use vanilla fog common 2026-05-12 07:32:57 -05:00
James Seibel fbbcd1b95b fix forgix running on only a single modloader 2026-05-12 07:28:59 -05:00
James Seibel d8e7325044 minor gradle cleanup 2026-05-12 07:28:45 -05:00
James Seibel f17aeca79c add cleanroom run config 2026-05-12 07:28:37 -05:00
James Seibel ac3a223114 add missing licensing headers 2026-05-12 07:28:25 -05:00
James Seibel e4312c2f8b reformat 1.12.2 version prop 2026-05-12 07:28:11 -05:00
James Seibel 17bde631ac Put back jvmdowngrader 2026-05-12 07:02:04 -05:00
Vojtěch Šokala 578efbf15f Fix compile of 1.21.6+ 2026-05-08 02:19:45 +02:00
Vojtěch Šokala 8b6bb228e3 Put 26.1.2 back in mcVer 2026-05-08 01:17:19 +02:00
Vojtěch Šokala 611c4606d7 Fix 1.12.2 bugs, fill mcmod.info 2026-05-08 01:15:13 +02:00
Vojtěch Šokala 05bdaf0390 Prevent air transforming into water if waterSubSurfaceBlockReplacementCsv contains invalid resource location 2026-05-07 15:39:14 +02:00
Vojtěch Šokala eb8fcaee36 Fix compilation of modern 2026-05-07 15:34:26 +02:00
Vojtěch Šokala 32a71933d6 Bump forge version on 1.20.1, 1.20.4 for Java 26 support 2026-05-07 15:34:01 +02:00
Vojtěch Šokala a4baf9ca0a make cleanroom work in dev 2026-05-07 12:23:01 +02:00
Vojtěch Šokala 72bfd0a2bb fix color resolve for liquid blocks 2026-05-07 03:39:49 +02:00
Vojtěch Šokala 7ae4a9f460 1.12.2 compiles again 2026-05-06 20:51:08 +02:00
Vojtěch Šokala 9bd6fb0105 merge upstream 2026-05-05 10:00:18 +02:00
Vojtěch Šokala 9fea29cbb6 Put canvas back 2026-03-17 15:46:00 +01:00
Vojtěch Šokala 7e1e5a56e2 Set back 1.21.11 as default mcVer 2026-03-15 23:41:13 +01:00
Vojtěch Šokala 059293ebe0 Add missing shaders into cleanroom project 2026-03-15 23:31:35 +01:00
Vojtěch Šokala 4f9d4e2a14 Fix compile error 2026-03-15 23:31:13 +01:00
Vojtěch Šokala 6bd3c825c3 Merge branch 'main' of https://gitlab.com/distant-horizons-team/distant-horizons
# Conflicts:
#	common/src/main/java/com/seibel/distanthorizons/common/wrappers/worldGeneration/InternalServerGenerator.java
2026-03-15 23:27:20 +01:00
Vojtěch Šokala c75595a5e2 [1.12.2] implement pregen command 2026-03-15 23:17:12 +01:00
Vojtěch Šokala 266d463873 fix compile errors 2026-03-15 23:14:54 +01:00
Vojtěch Šokala 73c718c676 [1.12.2] improve config gui to match other versions 2026-03-15 22:13:07 +01:00
Vojtěch Šokala 3df5c04759 Fix issue when MC framebuffer is using renderbuffer for depth 2026-03-15 22:10:03 +01:00
Vojtěch Šokala d72c34a926 Merge branch 'main' of https://gitlab.com/distant-horizons-team/distant-horizons
# Conflicts:
#	common/src/main/java/com/seibel/distanthorizons/common/AbstractModInitializer.java
#	common/src/main/java/com/seibel/distanthorizons/common/commands/PregenCommand.java
#	common/src/main/java/com/seibel/distanthorizons/common/render/openGl/GlDhTerrainShaderProgram.java
2026-03-15 15:49:41 +01:00
Vojtěch Šokala 8991338be1 [1.12.2] add support for 3.0.0b 2026-03-15 15:42:08 +01:00
Vojtěch Šokala 6b32ab02d3 Merge branch 'main' of https://gitlab.com/distant-horizons-team/distant-horizons
# Conflicts:
#	common/src/main/java/com/seibel/distanthorizons/common/AbstractModInitializer.java
#	common/src/main/java/com/seibel/distanthorizons/common/wrappers/WrapperFactory.java
#	common/src/main/java/com/seibel/distanthorizons/common/wrappers/block/BlockStateWrapper.java
#	common/src/main/java/com/seibel/distanthorizons/common/wrappers/minecraft/MinecraftGLWrapper.java
#	common/src/main/java/com/seibel/distanthorizons/common/wrappers/misc/LightMapWrapper.java
2026-03-11 09:42:18 +01:00
Vojtěch Šokala c5adc3f72a 1.12.2 working in dev 2026-03-11 09:20:32 +01:00
Vojtěch Šokala 1d0d67d215 1.12.2 buildscript 2026-02-20 15:00:13 +01:00
203 changed files with 8348 additions and 2307 deletions
+25 -1
View File
@@ -4,6 +4,7 @@ image: eclipse-temurin:25
# all stages need to be defined here # all stages need to be defined here
stages: stages:
- translations
- build - build
- api - api
- pages - pages
@@ -32,6 +33,9 @@ variables:
build: build:
stage: build stage: build
needs:
- job: translations
artifacts: true
parallel: parallel:
matrix: matrix:
- MC_VER: [ - MC_VER: [
@@ -41,8 +45,14 @@ build:
"1.19.4", "1.19.2", "1.19.4", "1.19.2",
"1.18.2", "1.18.2",
"1.17.1", "1.17.1",
"1.16.5" "1.16.5",
"1.12.2"
] ]
before_script:
# MC 1.12.2 needs both JDK 25 (for unimined) and JDK 8 (for MC 1.12)
# hopefully downloading the JDK 8 like this will solve that problem?
- apt-get update -q
- apt-get install -y openjdk-8-jdk
script: script:
# this both runs the unit tests and assembles the code # 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 clean -PmcVer="${MC_VER}" -PinfoGitCommit="${CI_COMMIT_SHA}" -PinfoGitBranch="${CI_COMMIT_BRANCH}" -PinfoBuildSource="GitLab CI (${CI_PIPELINE_ID})" --gradle-user-home cache/;
@@ -101,3 +111,17 @@ pages:
- public - public
allow_failure: false allow_failure: false
extends: .build_java extends: .build_java
translations:
stage: translations
needs: []
image: crowdin/cli:latest
script:
- if [ "$CI_COMMIT_BEFORE_SHA" = "0000000000000000000000000000000000000000" ] || git diff --name-only "$CI_COMMIT_BEFORE_SHA" "$CI_COMMIT_SHA" -- coreSubProjects/core/src/main/resources/assets/distanthorizons/lang | grep -q .; then crowdin upload sources; fi
- crowdin download --export-only-approved --skip-untranslated-files
- for f in coreSubProjects/core/src/main/resources/assets/distanthorizons/lang/*.json; do [ -e "$f" ] || continue; sed -i 's/\\\\n/\\n/g' "$f"; n="$(basename "$f" | tr '[:upper:]' '[:lower:]')"; [ "$(basename "$f")" = "$n" ] || mv "$f" "$(dirname "$f")/$n"; done
artifacts:
paths:
- coreSubProjects/core/src/main/resources/assets/distanthorizons/lang/**
expire_in: 1 day
when: always
+2 -2
View File
@@ -1,7 +1,7 @@
<component name="ProjectRunConfigurationManager"> <component name="ProjectRunConfigurationManager">
<configuration default="false" name="Fabric Client &amp; Server" type="CompoundRunConfigurationType"> <configuration default="false" name="Fabric Client &amp; Server" type="CompoundRunConfigurationType">
<toRun name="Fabric Client (:fabric)" type="Application" /> <toRun name="distant-horizons [fabric:runClient]" type="GradleRunConfiguration" />
<toRun name="Fabric Server (:fabric)" type="Application" /> <toRun name="distant-horizons [fabric:runServer]" type="GradleRunConfiguration" />
<method v="2" /> <method v="2" />
</configuration> </configuration>
</component> </component>
@@ -0,0 +1,27 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="distant-horizons [cleanroom:runClient]" type="GradleRunConfiguration" factoryName="Gradle">
<ExternalSystemSettings>
<option name="executionName" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="externalSystemIdString" value="GRADLE" />
<option name="scriptParameters" value="" />
<option name="taskDescriptions">
<list />
</option>
<option name="taskNames">
<list>
<option value="cleanroom:runClient" />
</list>
</option>
<option name="vmOptions" />
</ExternalSystemSettings>
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
<ExternalSystemDebugDisabled>false</ExternalSystemDebugDisabled>
<DebugAllEnabled>false</DebugAllEnabled>
<RunAsTest>false</RunAsTest>
<GradleProfilingDisabled>false</GradleProfilingDisabled>
<GradleCoverageDisabled>false</GradleCoverageDisabled>
<method v="2" />
</configuration>
</component>
+5
View File
@@ -12,6 +12,11 @@ Below is a video demonstrating the system:
<a href="https://youtu.be/SxQdbtjGEsc" target="_blank">![Distant Horizons - Alpha 2.0](https://i.ytimg.com/vi/SxQdbtjGEsc/hqdefault.jpg)</a> <a href="https://youtu.be/SxQdbtjGEsc" target="_blank">![Distant Horizons - Alpha 2.0](https://i.ytimg.com/vi/SxQdbtjGEsc/hqdefault.jpg)</a>
## Translations
[![Crowdin](https://badges.crowdin.net/distant-horizons/localized.svg)](https://crowdin.com/project/distant-horizons)\
Crowdin Project: [Distant Horizons](https://crowdin.com/project/distant-horizons)\
Guidelines: [translations.md](translations.md)
<br> <br>
## Source Code Installation ## Source Code Installation
+7 -2
View File
@@ -3,12 +3,11 @@ plugins {
id 'io.github.pacifistmc.forgix' version '2.+' id 'io.github.pacifistmc.forgix' version '2.+'
} }
if (false) // TODO vulkan don't run if there is only one mod loader
forgix { forgix {
autoRun = true
// add the mod loaders to the end of the jar // add the mod loaders to the end of the jar
// put together in the format: "a", "a-b", "a-b-c" // put together in the format: "a", "a-b", "a-b-c"
int loaderCount = 0;
String modLoaders = ""; String modLoaders = "";
((String) gradle.builds_for) ((String) gradle.builds_for)
.split(",") .split(",")
@@ -21,7 +20,13 @@ forgix {
} }
modLoaders += loaderName; modLoaders += loaderName;
loaderCount++;
} }
// run if there are multiple launchers that need merging
autoRun = (loaderCount > 1);
// merged jars are named in the format: // merged jars are named in the format:
// "DistantHorizons-3.0.1-b-dev-26.1-fabric-neoforge.jar" // "DistantHorizons-3.0.1-b-dev-26.1-fabric-neoforge.jar"
archiveClassifier = modLoaders archiveClassifier = modLoaders
+105 -27
View File
@@ -6,6 +6,7 @@ import org.apache.tools.zip.ZipOutputStream
import javax.annotation.Nonnull import javax.annotation.Nonnull
import java.util.function.Function import java.util.function.Function
import java.util.function.Predicate import java.util.function.Predicate
import groovy.json.JsonSlurper
// Convention plugin for all MC-facing subprojects (common + loaders). // Convention plugin for all MC-facing subprojects (common + loaders).
// Common uses this directly; loaders use it via unimined-fabric/forge/neoforge. // Common uses this directly; loaders use it via unimined-fabric/forge/neoforge.
@@ -23,6 +24,9 @@ plugins {
def isNotCommonProject = project.name != "common" def isNotCommonProject = project.name != "common"
if (isNotCommonProject) {
evaluationDependsOn(":common")
}
// ==================== Version Properties ==================== // ==================== Version Properties ====================
@@ -121,6 +125,15 @@ if (isNotCommonProject) {
'Multi-Release': true, 'Multi-Release': true,
'Main-Class': 'com.seibel.distanthorizons.core.jar.JarMain', 'Main-Class': 'com.seibel.distanthorizons.core.jar.JarMain',
) )
if (project.name == "cleanroom") {
attributes(
'ModType': 'CRL',
'MixinConfigs': "${mod_id}.default.mixin.json,${mod_id}.mod.mixin.json",
'FMLCorePlugin': 'com.seibel.distanthorizons.cleanroom.DistantHorizonsLoadingPlugin',
'FMLCorePluginContainsFMLMod': true,
'FMLAT': "${gradle.ext.accessWidenerVersion}.distanthorizons_at.cfg"
)
}
} }
} }
} }
@@ -133,8 +146,14 @@ unimined.minecraft(sourceSets.main, true) {
if (gradle.ext.minecraft_version.startsWith("1.")) { // 26.1+ doesn't use obfuscation if (gradle.ext.minecraft_version.startsWith("1.")) { // 26.1+ doesn't use obfuscation
mappings { mappings {
mojmap() if(gradle.ext.minecraft_version.startsWith("1.12.2")){
devNamespace "mojmap" mcp("stable", "39-1.12")
}
else{
mojmap()
devNamespace "mojmap"
}
} }
} }
} }
@@ -165,18 +184,23 @@ if (isNotCommonProject) {
source(project(":common").sourceSets.main.allSource) source(project(":common").sourceSets.main.allSource)
} }
} else { } else {
// Common: fabric for compilation + access widener, no jar remapping or runs
unimined.minecraft { unimined.minecraft {
fabric { if (gradle.ext.minecraft_version.equals("1.12.2")) {
loader gradle.ext.fabric_loader_version cleanroom {
accessWidener project.file("src/main/resources/${gradle.ext.accessWidenerVersion}.distanthorizons.accesswidener") loader gradle.ext.cleanroom_loader_version
accessTransformer project.file("src/main/resources/${gradle.ext.accessWidenerVersion}.distanthorizons_at.cfg")
}
} else {
fabric {
loader gradle.ext.fabric_loader_version
accessWidener project.file("src/main/resources/${gradle.ext.accessWidenerVersion}.distanthorizons.accesswidener")
}
} }
defaultRemapJar = false defaultRemapJar = false
runs.off = true runs.off = true
} }
} }
// ==================== Configurations ==================== // ==================== Configurations ====================
evaluationDependsOn(":core") evaluationDependsOn(":core")
@@ -346,12 +370,25 @@ if (isNotCommonProject) {
def loaderPaths = configurations.minecraftLibraries.resolve().collect { it.path }.toSet() def loaderPaths = configurations.minecraftLibraries.resolve().collect { it.path }.toSet()
tasks.withType(JavaExec).configureEach { runTask -> tasks.withType(JavaExec).configureEach { runTask ->
dependsOn(shadowJar) dependsOn(shadowJar)
classpath = files(shadowJar.archiveFile) + classpath.filter { file -> if (project.name != "cleanroom") {
!file.path.contains(project.buildDir.path) && classpath = files(shadowJar.archiveFile) + classpath.filter { file ->
!file.path.contains("core${File.separator}build") && file != shadowJar.archiveFile.get().asFile &&
!file.path.contains("api${File.separator}build") && !file.path.contains(project.buildDir.path) &&
!file.path.contains("common${File.separator}build") && !file.path.contains("core${File.separator}build") &&
!(shadowedPaths.contains(file.path) && !loaderPaths.contains(file.path)) !file.path.contains("api${File.separator}build") &&
!file.path.contains("common${File.separator}build") &&
!(shadowedPaths.contains(file.path) && !loaderPaths.contains(file.path))
}
} else {
// For cleanroom, don't put shadow jar on app classpath.
// crl.dev.extrapath loads it via LaunchClassLoader instead.
classpath = 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 // Shared run directory so all loaders use the same worlds
@@ -367,20 +404,28 @@ if (isNotCommonProject) {
} }
runTask.jvmArgs = filteredArgs runTask.jvmArgs = filteredArgs
// fix (Neo)forge debug running if(project.name == "forge"
doFirst { || project.name == "neoforge"
def modsDir = rootProject.file("run/${isClient ? 'client' : 'server'}/mods") || project.name == "cleanroom")
modsDir.mkdirs() {
// fix (Neo)forge, Cleanroom debug running
doFirst {
def modsDir = rootProject.file("run/${isClient ? 'client' : 'server'}/mods")
modsDir.mkdirs()
// Remove any stale DH jars before copying the fresh one // Remove any stale DH jars before copying the fresh one
modsDir.listFiles()?.each { file -> modsDir.listFiles()?.each({ file ->
if (file.name.startsWith(rootProject.mod_name)) file.delete() if (file.name.startsWith(rootProject.mod_name))
} {
file.delete()
}
});
// Copy shadow jar into mods folder so (Neo)Forge discovers it properly // Copy shadow jar into mods folder so (Neo)Forge discovers it properly
copy { copy {
from shadowJar.archiveFile from shadowJar.archiveFile
into modsDir into modsDir
}
} }
} }
@@ -418,6 +463,10 @@ if (isNotCommonProject) {
} }
} }
tasks.downgradeJar.inputFile.set(tasks.named("remapJar").flatMap { it.archiveFile })
tasks.jar.finalizedBy(tasks.named("remapJar"))
tasks.named("remapJar").configure { finalizedBy(tasks.shadeDowngradedApi) }
} }
} }
@@ -429,16 +478,22 @@ if (isNotCommonProject) {
def resourceTargets = [ def resourceTargets = [
"build_info.json", "build_info.json",
"fabric.mod.json", "fabric.mod.json",
"mcmod.info",
"quilt.mod.json", "quilt.mod.json",
"META-INF/mods.toml", "META-INF/mods.toml",
"META-INF/neoforge.mods.toml", "META-INF/neoforge.mods.toml",
] ]
def compatible_forgemc_versions = "${rootProject.compatible_minecraft_versions}".replaceAll("\"", "").replaceAll("]", ",)") // incoming format: `["26.2.0","26.2-alpha.9"]`
// outgoing format: `[26.2.0],[26.2-alpha.9]`
def compatible_forgemc_versions = "${rootProject.compatible_minecraft_versions}"
.replaceAll("\",\"", "],[")
.replaceAll("\"", "")
// Quilt contributors // Quilt contributors
def quilt_contributors = [] def quilt_contributors = []
def mod_author_list = rootProject.mod_authors.replaceAll("\"", "").replace("[", "").replace("]", "").split(",") def mod_author_list = rootProject.mod_authors.replaceAll("\"", "").replace("[", "").replace("]", "").split(",")
def cleanroom_author_list = rootProject.mod_authors.replace('[', '').replace(']', '').split(',').collect({ it.trim().replace('"', '') }).join('", "')
for (dev in mod_author_list) { for (dev in mod_author_list) {
quilt_contributors.push("\"${dev.strip()}\": \"Developer\"") quilt_contributors.push("\"${dev.strip()}\": \"Developer\"")
} }
@@ -456,9 +511,11 @@ if (isNotCommonProject) {
def replaceProperties = [ def replaceProperties = [
version : rootProject.mod_version, version : rootProject.mod_version,
mod_id : rootProject.mod_id,
mod_name : rootProject.mod_readable_name, mod_name : rootProject.mod_readable_name,
group : rootProject.maven_group, group : rootProject.maven_group,
authors : rootProject.mod_authors, authors : rootProject.mod_authors,
cleanroom_authors : cleanroom_author_list,
description : rootProject.mod_description, description : rootProject.mod_description,
homepage : rootProject.mod_homepage, homepage : rootProject.mod_homepage,
source : rootProject.mod_source, source : rootProject.mod_source,
@@ -476,6 +533,7 @@ if (isNotCommonProject) {
fabric_incompatibility_list : rootProject.fabric_incompatibility_list, fabric_incompatibility_list : rootProject.fabric_incompatibility_list,
fabric_recommend_list : rootProject.fabric_recommend_list, fabric_recommend_list : rootProject.fabric_recommend_list,
neoforge_version_range : rootProject.neoforge_version_range, neoforge_version_range : rootProject.neoforge_version_range,
logo_path : "assets/distanthorizons/icon.png"
] ]
inputs.properties replaceProperties inputs.properties replaceProperties
@@ -486,7 +544,7 @@ if (isNotCommonProject) {
// Remove unused access wideners // Remove unused access wideners
exclude { file -> exclude { file ->
if (file.name.contains(".distanthorizons.accesswidener") && file.name != "${rootProject.accessWidenerVersion}.distanthorizons.accesswidener") { if ((file.name.contains(".distanthorizons.accesswidener") && file.name != "${rootProject.accessWidenerVersion}.distanthorizons.accesswidener")) {
return true return true
} }
return false return false
@@ -506,6 +564,26 @@ if (isNotCommonProject) {
from fileTree(project(":core").file("src/main/resources")) from fileTree(project(":core").file("src/main/resources"))
into project.file("build/resources/main") into project.file("build/resources/main")
} }
tasks.register("convertJsonToLang") {
dependsOn(copyCoreResources)
File input = project.file("build/resources/main/assets/distanthorizons/lang/en_us.json")
File output = project.file("build/resources/main/assets/distanthorizons/lang/en_us.lang")
inputs.file(input)
outputs.file(output)
doLast {
output.withWriter("UTF-8") { writer ->
writer.writeLine("#PARSE_ESCAPES")
new JsonSlurper()
.parse(input)
.each { key, value ->
def text = value.toString().replaceAll(/%(?!((\d+)\$)?s|%)/, "%%").replace("\n", "\\n")
writer.writeLine("${key}=${text}")
}
}
}
}
// ==================== JVMDowngrader ==================== // ==================== JVMDowngrader ====================
@@ -0,0 +1,15 @@
plugins {
id 'dh-loader'
}
unimined.minecraft {
cleanroom {
loader gradle.ext.cleanroom_loader_version
useToolchains = false
accessTransformer project(":common").file("src/main/resources/${gradle.ext.accessWidenerVersion}.distanthorizons_at.cfg")
runs.all {
systemProperty("crl.dev.mixin", "${mod_id}.default.mixin.json,${mod_id}.mod.mixin.json")
systemProperty("fml.coreMods.load", "com.seibel.distanthorizons.cleanroom.DistantHorizonsLoadingPlugin")
}
}
}
+48
View File
@@ -0,0 +1,48 @@
plugins {
id 'unimined-cleanroom'
}
// ==================== Mod Dependency Helper ====================
def addMod(path, enabled) {
if (enabled == "2")
dependencies { modImplementation(path) }
else if (enabled == "1")
dependencies { compileOnly(path) }
}
// ==================== Dependencies ====================
dependencies {
}
// ==================== Tasks ====================
task deleteResources(type: Delete) {
delete file("build/resources/main")
}
processResources {
rename '(.+_at.cfg)', 'META-INF/$1'
dependsOn(copyCoreResources)
dependsOn(convertJsonToLang)
// dependsOn(copyCommonLoaderResources)
}
tasks.named('runClient') {
dependsOn(copyCoreResources)
// dependsOn(copyCommonLoaderResources)
finalizedBy(deleteResources)
}
sourcesJar {
def commonSources = project(":common").sourcesJar
dependsOn commonSources
from commonSources.archiveFile.map { zipTree(it) }
}
@@ -0,0 +1,214 @@
/*
* 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.cleanroom;
import com.seibel.distanthorizons.common.AbstractModInitializer;
import com.seibel.distanthorizons.common.util.ProxyUtil;
import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftRenderWrapper;
import com.seibel.distanthorizons.common.wrappers.world.ClientLevelWrapper;
import com.seibel.distanthorizons.core.api.internal.ClientApi;
import com.seibel.distanthorizons.core.api.internal.ServerApi;
import com.seibel.distanthorizons.core.api.internal.SharedApi;
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.logging.f3.F3Screen;
import com.seibel.distanthorizons.core.network.messages.AbstractNetworkMessage;
import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil;
import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IPluginPacketSender;
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IServerPlayerWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.WorldClient;
import net.minecraft.world.World;
import net.minecraft.world.chunk.Chunk;
import net.minecraftforge.client.event.RenderGameOverlayEvent;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.entity.player.PlayerInteractEvent;
import net.minecraftforge.event.world.ChunkEvent;
import net.minecraftforge.event.world.WorldEvent;
import net.minecraftforge.fml.common.FMLCommonHandler;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.gameevent.InputEvent;
import net.minecraftforge.fml.common.gameevent.TickEvent;
import org.jetbrains.annotations.NotNull;
import org.lwjgl.glfw.GLFW;
import org.lwjgl.opengl.GL32;
import java.util.concurrent.AbstractExecutorService;
public class CleanroomClientProxy implements AbstractModInitializer.IEventProxy
{
private static final IMinecraftClientWrapper MC = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class);
private static final CleanroomPluginPacketSender PACKET_SENDER = (CleanroomPluginPacketSender) SingletonInjector.INSTANCE.get(IPluginPacketSender.class);
private static final DhLogger LOGGER = new DhLoggerBuilder().build();
private static World GetEventLevel(WorldEvent e) { return e.getWorld(); }
@Override
public void registerEvents()
{
MinecraftForge.EVENT_BUS.register(this);
MinecraftForge.EVENT_BUS.register(FMLCommonHandler.instance());
CleanroomPluginPacketSender.setPacketHandler(ClientApi.INSTANCE::pluginMessageReceived);
}
//==============//
// chunk events //
//==============//
//region
@SubscribeEvent
public void rightClickBlockEvent(PlayerInteractEvent.RightClickBlock event)
{
if (MC.clientConnectedToDedicatedServer())
{
World level = event.getWorld();
ILevelWrapper wrappedLevel = ProxyUtil.getLevelWrapper(level);
if (SharedApi.isChunkAtBlockPosAlreadyUpdating(wrappedLevel, event.getPos().getX(), event.getPos().getZ()))
{
return;
}
AbstractExecutorService executor = ThreadPoolUtil.getFileHandlerExecutor();
if (executor != null)
{
executor.execute(() ->
{
Chunk chunk = level.getChunk(event.getPos());
SharedApi.INSTANCE.applyChunkUpdate(new ChunkWrapper(chunk, wrappedLevel), wrappedLevel);
});
}
}
}
@SubscribeEvent
public void leftClickBlockEvent(PlayerInteractEvent.LeftClickBlock event)
{
if (MC.clientConnectedToDedicatedServer())
{
World level = event.getWorld();
ILevelWrapper wrappedLevel = ProxyUtil.getLevelWrapper(level);
if (SharedApi.isChunkAtBlockPosAlreadyUpdating(wrappedLevel, event.getPos().getX(), event.getPos().getZ()))
{
return;
}
AbstractExecutorService executor = ThreadPoolUtil.getFileHandlerExecutor();
if (executor != null)
{
executor.execute(() ->
{
Chunk chunk = level.getChunk(event.getPos());
SharedApi.INSTANCE.applyChunkUpdate(new ChunkWrapper(chunk, wrappedLevel), wrappedLevel);
});
}
}
}
@SubscribeEvent
public void clientChunkLoadEvent(ChunkEvent.Load event)
{
if (MC.clientConnectedToDedicatedServer())
{
ILevelWrapper wrappedLevel = ProxyUtil.getLevelWrapper(GetEventLevel(event));
IChunkWrapper chunkWrapper = new ChunkWrapper(event.getChunk(), wrappedLevel);
SharedApi.INSTANCE.applyChunkUpdate(chunkWrapper, wrappedLevel);
}
}
//endregion
//==============//
// key bindings //
//==============//
//region
@SubscribeEvent
public void registerKeyBindings(InputEvent.KeyInputEvent event)
{
/* if (Minecraft.getMinecraft().player == null)
{
return;
}
if (event.getAction() != GLFW.GLFW_PRESS)
{
return;
}
ClientApi.INSTANCE.keyPressedEvent(event.getKey());*/
}
//endregion
//===========//
// rendering //
//===========//
//region
@SubscribeEvent
public void afterLevelRenderEvent(TickEvent.RenderTickEvent event)
{
if (event.type.equals(TickEvent.RenderTickEvent.Type.RENDER))
{
try
{
// should generally only need to be set once per game session
// allows DH to render directly to Optifine's level frame buffer,
// allowing better shader support
MinecraftRenderWrapper.INSTANCE.finalLevelFrameBufferId = GL32.glGetInteger(GL32.GL_FRAMEBUFFER_BINDING);
}
catch (Exception | Error e)
{
LOGGER.error("Unexpected error in afterLevelRenderEvent: "+e.getMessage(), e);
}
}
}
@SubscribeEvent
public void onRenderOverlay(RenderGameOverlayEvent.Text event)
{
Minecraft mc = Minecraft.getMinecraft();
if (event.isCanceled()
|| !mc.gameSettings.showDebugInfo)
{
return;
}
F3Screen.addStringToDisplay(event.getRight());
}
//endregion
}
@@ -0,0 +1,147 @@
/*
* 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.cleanroom;
import com.seibel.distanthorizons.cleanroom.modAccessor.ModChecker;
import com.seibel.distanthorizons.common.AbstractModInitializer;
import com.seibel.distanthorizons.common.commands.CommandInitializer;
import com.seibel.distanthorizons.common.wrappers.worldGeneration.InternalServerGenerator;
import com.seibel.distanthorizons.core.api.internal.ServerApi;
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IPluginPacketSender;
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IModChecker;
import com.seibel.distanthorizons.coreapi.ModInfo;
import net.minecraft.server.MinecraftServer;
import net.minecraft.world.World;
import net.minecraftforge.common.ForgeChunkManager;
import net.minecraftforge.fml.common.FMLCommonHandler;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.event.*;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.core.config.Configurator;
import java.util.List;
import java.util.function.Consumer;
/**
* Initialize and setup the Mod. <br>
* If you are looking for the real start of the mod
* check out the ClientProxy.
*/
@Mod(modid = ModInfo.ID, name = ModInfo.NAME, version = ModInfo.VERSION)
public class CleanroomMain extends AbstractModInitializer
{
@Mod.Instance
public static CleanroomMain instance;
@Mod.EventHandler
public void preinit(FMLPreInitializationEvent event)
{
Configurator.setLevel("org.sqlite", Level.INFO);
ForgeChunkManager.setForcedChunkLoadingCallback(CleanroomMain.instance, (tickets, world) -> { });
}
@Mod.EventHandler
public void init(FMLInitializationEvent event)
{
if (FMLCommonHandler.instance().getEffectiveSide().isClient())
{
this.onInitializeClient();
}
else
{
this.onInitializeServer();
}
}
@Override
protected void createInitialSharedBindings()
{
SingletonInjector.INSTANCE.bind(IModChecker.class, ModChecker.INSTANCE);
SingletonInjector.INSTANCE.bind(IPluginPacketSender.class, new CleanroomPluginPacketSender());
}
@Override
protected void createInitialClientBindings() { /* no additional setup needed currently */ }
@Override
protected IEventProxy createClientProxy() { return new CleanroomClientProxy(); }
@Override
protected IEventProxy createServerProxy(boolean isDedicated) { return new CleanroomServerProxy(isDedicated); }
@Override
protected void initializeModCompat()
{
}
/* @Override
protected void subscribeRegisterCommandsEvent(Consumer<CommandDispatcher<CommandSourceStack>> eventHandler)
{ MinecraftForge.EVENT_BUS.addListener((RegisterCommandsEvent e) -> { eventHandler.accept(e.getDispatcher()); }); }*/
@Override
protected void subscribeClientStartedEvent(Runnable eventHandler)
{
// Just run the event handler, since there are no proper ClientLifecycleEvent for the client
// to signify readiness other than FmlClientSetupEvent
eventHandler.run();
}
@Mod.EventHandler
public void onServerStarting(FMLServerStartingEvent event)
{
event.registerServerCommand(CommandInitializer.initCommands());
}
@Mod.EventHandler
public void onServerAboutToStart(FMLServerAboutToStartEvent event)
{
if (eventHandlerStartServer != null)
{
eventHandlerStartServer.accept(event.getServer());
}
}
Consumer<MinecraftServer> eventHandlerStartServer;
@Override
protected void subscribeServerStartingEvent(Consumer<MinecraftServer> eventHandler)
{
eventHandlerStartServer = eventHandler;
}
@Override
protected void runDelayedSetup() { SingletonInjector.INSTANCE.runDelayedSetup(); }
// ServerWorldLoadEvent
@Mod.EventHandler
public void dedicatedWorldLoadEvent(FMLServerAboutToStartEvent event)
{
ServerApi.INSTANCE.serverLoadEvent(event.getServer().isDedicatedServer());
}
// ServerWorldUnloadEvent
@Mod.EventHandler
public void serverWorldUnloadEvent(FMLServerStoppingEvent event)
{
ServerApi.INSTANCE.serverUnloadEvent();
}
}
@@ -0,0 +1,136 @@
/*
* 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.cleanroom;
import com.seibel.distanthorizons.common.AbstractPluginPacketSender;
import com.seibel.distanthorizons.common.wrappers.misc.ServerPlayerWrapper;
import com.seibel.distanthorizons.core.network.messages.AbstractNetworkMessage;
import com.seibel.distanthorizons.core.network.messages.MessageRegistry;
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IServerPlayerWrapper;
import io.netty.buffer.ByteBuf;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraftforge.fml.common.network.NetworkRegistry;
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler;
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
import net.minecraftforge.fml.common.network.simpleimpl.SimpleNetworkWrapper;
import net.minecraftforge.fml.relauncher.Side;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
public class CleanroomPluginPacketSender extends AbstractPluginPacketSender
{
public static final SimpleNetworkWrapper PLUGIN_CHANNEL =
NetworkRegistry.INSTANCE.newSimpleChannel(
AbstractPluginPacketSender.WRAPPER_PACKET_RESOURCE
);
public static void setPacketHandler(Consumer<AbstractNetworkMessage> consumer)
{ setPacketHandler((player, message) -> consumer.accept(message)); }
static BiConsumer<IServerPlayerWrapper, AbstractNetworkMessage> consumerPacket;
public static void setPacketHandler(BiConsumer<IServerPlayerWrapper, AbstractNetworkMessage> consumer)
{
PLUGIN_CHANNEL.registerMessage(MessageWrapper.Handler.class, MessageWrapper.class, 0, Side.CLIENT);
PLUGIN_CHANNEL.registerMessage(MessageWrapper.Handler.class, MessageWrapper.class, 0, Side.SERVER);
consumerPacket = consumer;
}
@Override
public void sendToServer(AbstractNetworkMessage message)
{ PLUGIN_CHANNEL.sendToServer(new MessageWrapper(message)); }
@Override
public void sendToClient(EntityPlayerMP serverPlayer, AbstractNetworkMessage message)
{ PLUGIN_CHANNEL.sendTo(new MessageWrapper(message), serverPlayer); }
//================//
// helper classes //
//================//
//region
// Forge doesn't support using abstract classes
@SuppressWarnings({"ClassCanBeRecord", "RedundantSuppression"})
public static class MessageWrapper implements IMessage
{
public AbstractNetworkMessage message;
//=============//
// constructor //
//=============//
//region
public MessageWrapper(AbstractNetworkMessage message) { this.message = message; }
public MessageWrapper()
{
// For reflection
}
//endregion
@Override
public void fromBytes(ByteBuf buf)
{
int messageId = buf.readByte();
message = MessageRegistry.INSTANCE.createMessage(messageId);
message.decode(buf);
}
@Override
public void toBytes(ByteBuf buf)
{
buf.writeByte(MessageRegistry.INSTANCE.getMessageId(message));
message.encode(buf);
}
public static class Handler implements IMessageHandler<MessageWrapper, IMessage>
{
@Override
public IMessage onMessage(MessageWrapper wrapper, MessageContext context)
{
if (wrapper.message != null)
{
if (context.side == Side.SERVER)
{
consumerPacket.accept(ServerPlayerWrapper.getWrapper(context.getServerHandler().player), wrapper.message);
}
else
{
consumerPacket.accept(null, wrapper.message);
}
}
return null; // No response needed
}
}
}
//endregion
}
@@ -0,0 +1,181 @@
/*
* 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.cleanroom;
import com.seibel.distanthorizons.common.AbstractModInitializer;
import com.seibel.distanthorizons.common.commands.CommandInitializer;
import com.seibel.distanthorizons.common.commonMixins.MixinChunkMapCommon;
import com.seibel.distanthorizons.common.util.ProxyUtil;
import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
import com.seibel.distanthorizons.common.wrappers.misc.ServerPlayerWrapper;
import com.seibel.distanthorizons.common.wrappers.world.ServerLevelWrapper;
import com.seibel.distanthorizons.common.wrappers.worldGeneration.InternalServerGenerator;
import com.seibel.distanthorizons.core.api.internal.ServerApi;
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.wrapperInterfaces.chunk.IChunkWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IPluginPacketSender;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.server.MinecraftServer;
import net.minecraft.world.World;
import net.minecraft.world.WorldServer;
import net.minecraftforge.common.ForgeChunkManager;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.world.ChunkDataEvent;
import net.minecraftforge.event.world.ChunkEvent;
import net.minecraftforge.event.world.WorldEvent;
import net.minecraftforge.fml.common.FMLCommonHandler;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.event.FMLServerAboutToStartEvent;
import net.minecraftforge.fml.common.event.FMLServerStartingEvent;
import net.minecraftforge.fml.common.event.FMLServerStoppingEvent;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.gameevent.PlayerEvent;
import java.lang.reflect.Field;
import static com.seibel.distanthorizons.cleanroom.CleanroomMain.instance;
public class CleanroomServerProxy implements AbstractModInitializer.IEventProxy
{
private static final CleanroomPluginPacketSender PACKET_SENDER = (CleanroomPluginPacketSender) SingletonInjector.INSTANCE.get(IPluginPacketSender.class);
private static World GetEventLevel(WorldEvent e) { return e.getWorld(); }
private static final DhLogger LOGGER = new DhLoggerBuilder().build();
private final ServerApi serverApi = ServerApi.INSTANCE;
private final boolean isDedicated;
@Override
public void registerEvents()
{
MinecraftForge.EVENT_BUS.register(this);
FMLCommonHandler.instance().bus().register(this);
if (this.isDedicated)
{
PACKET_SENDER.setPacketHandler(ServerApi.INSTANCE::pluginMessageReceived);
}
}
//=============//
// constructor //
//=============//
//region
public CleanroomServerProxy(boolean isDedicated) { this.isDedicated = isDedicated; }
//endregion
//========//
// events //
//========//
//region
// ServerLevelLoadEvent
@SubscribeEvent
public void serverLevelLoadEvent(WorldEvent.Load event)
{
if (GetEventLevel(event) instanceof WorldServer)
{
this.serverApi.serverLevelLoadEvent(getServerLevelWrapper((WorldServer) GetEventLevel(event)));
}
}
// ServerLevelUnloadEvent
@SubscribeEvent
public void serverLevelUnloadEvent(WorldEvent.Unload event)
{
if (GetEventLevel(event) instanceof WorldServer)
{
this.serverApi.serverLevelUnloadEvent(getServerLevelWrapper((WorldServer) GetEventLevel(event)));
}
}
@SubscribeEvent
public void serverChunkLoadEvent(ChunkEvent.Load event)
{
ILevelWrapper levelWrapper = ProxyUtil.getLevelWrapper(GetEventLevel(event));
IChunkWrapper chunk = new ChunkWrapper(event.getChunk(), levelWrapper);
this.serverApi.serverChunkLoadEvent(chunk, levelWrapper);
}
@SubscribeEvent
public void serverChunkSaveEvent(ChunkDataEvent.Save event)
{
if (event.getWorld() instanceof WorldServer worldServer && event.getChunk().dirty)
{
MixinChunkMapCommon.onChunkSave(worldServer, event.getChunk());
}
}
@SubscribeEvent
public void playerLoggedInEvent(PlayerEvent.PlayerLoggedInEvent event)
{ this.serverApi.serverPlayerJoinEvent(getServerPlayerWrapper(event)); }
@SubscribeEvent
public void playerLoggedOutEvent(PlayerEvent.PlayerLoggedOutEvent event)
{ this.serverApi.serverPlayerDisconnectEvent(getServerPlayerWrapper(event)); }
@SubscribeEvent
public void playerChangedDimensionEvent(PlayerEvent.PlayerChangedDimensionEvent event)
{
this.serverApi.serverPlayerLevelChangeEvent(
getServerPlayerWrapper(event),
getServerLevelWrapper(event.fromDim, event),
getServerLevelWrapper(event.toDim, event)
);
}
//endregion
//================//
// helper methods //
//================//
//region
private static ServerLevelWrapper getServerLevelWrapper(WorldServer level) { return ServerLevelWrapper.getWrapper(level); }
private static ServerLevelWrapper getServerLevelWrapper(int dimensionId, PlayerEvent event)
{
MinecraftServer server = event.player.getServer();
if (server == null)
{
LOGGER.error("getServerLevelWrapper: server is null for player {}", event.player.getName());
return null;
}
return getServerLevelWrapper(server.getWorld(dimensionId));
}
private static ServerPlayerWrapper getServerPlayerWrapper(PlayerEvent event)
{ return ServerPlayerWrapper.getWrapper((EntityPlayerMP) event.player); }
//endregion
}
@@ -0,0 +1,56 @@
/*
* 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.cleanroom;
import net.minecraftforge.fml.common.Loader;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.objectweb.asm.tree.ClassNode;
import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin;
import org.spongepowered.asm.mixin.extensibility.IMixinInfo;
import java.util.List;
import java.util.Set;
public class DistantHorizonsConfigPlugin implements IMixinConfigPlugin
{
private static final Logger LOGGER = LogManager.getLogger();
@Override
public void onLoad(String mixinPackage)
{ }
@Override
public boolean shouldApplyMixin(String targetClassName, String mixinClassName)
{
/* return switch (mixinClassName.split("\\.")[5]) {
case "mist" -> Loader.isModLoaded("mist");
default -> true;
};*/
return true;
}
@Override public String getRefMapperConfig() { return null; }
@Override public void acceptTargets(Set<String> myTargets, Set<String> otherTargets) { }
@Override public List<String> getMixins() { return null; }
@Override public void preApply(String targetClassName, ClassNode classNode, String mixinClassName, IMixinInfo mixinInfo) { }
@Override public void postApply(String targetClassName, ClassNode classNode, String mixinClassName, IMixinInfo mixinInfo) { }
}
@@ -0,0 +1,52 @@
/*
* 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.cleanroom;
import net.minecraftforge.fml.relauncher.IFMLLoadingPlugin;
import org.jetbrains.annotations.Nullable;
import java.util.Map;
public class DistantHorizonsLoadingPlugin implements IFMLLoadingPlugin
{
@Override
public @Nullable String[] getASMTransformerClass()
{
return new String[0];
}
@Override
public @Nullable String getModContainerClass()
{
return null;
}
@Override
public @Nullable String getSetupClass()
{
return null;
}
@Override
public void injectData(Map<String, Object> data) { }
@Override
public @Nullable String getAccessTransformerClass()
{
return null;
}
}
@@ -0,0 +1,82 @@
/*
* 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.cleanroom.mixins.client;
import com.seibel.distanthorizons.common.commonMixins.MixinVanillaFogCommon;
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftRenderWrapper;
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.IMinecraftClientWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.EntityRenderer;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.texture.DynamicTexture;
import net.minecraft.init.MobEffects;
import org.apache.logging.log4j.Logger;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(EntityRenderer.class)
public class MixinEntityRenderer
{
@Shadow
@Final
private DynamicTexture lightmapTexture;
@Shadow @Final private Minecraft mc;
@Shadow @Final private static Logger LOGGER;
private static final float A_REALLY_REALLY_BIG_VALUE = 420694206942069.F;
private static final float A_EVEN_LARGER_VALUE = 42069420694206942069.F;
@Inject(at = @At("TAIL"), method = "updateLightmap")
public void onUpdateLightmap(float patrialTicks, CallbackInfo ci)
{
IMinecraftClientWrapper mc = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class);
if (mc == null || mc.getWrappedClientLevel() == null)
{
return;
}
MinecraftRenderWrapper renderWrapper = (MinecraftRenderWrapper)SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class);
renderWrapper.setLightmapId(lightmapTexture.getGlTextureId());
}
@Inject(at = @At("RETURN"), method = "setupFog")
private void disableSetupFog(int startCoords, float partialTicks, CallbackInfo ci)
{
boolean cancelFog = MixinVanillaFogCommon.cancelFog(startCoords, mc);
if (cancelFog)
{
GlStateManager.setFogStart(A_REALLY_REALLY_BIG_VALUE);
GlStateManager.setFogEnd(A_EVEN_LARGER_VALUE);
ClientApi.RENDER_STATE.vanillaFogEnabled = false;
}
else
{
ClientApi.RENDER_STATE.vanillaFogEnabled = true;
}
}
}
@@ -0,0 +1,24 @@
package com.seibel.distanthorizons.cleanroom.mixins.client;
import com.seibel.distanthorizons.common.commonMixins.DhUpdateScreenBase;
import com.seibel.distanthorizons.core.config.Config;
import com.seibel.distanthorizons.coreapi.ModInfo;
import net.minecraft.client.Minecraft;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(Minecraft.class)
public class MixinMinecraft
{
@Inject(method = "init", at = @At("TAIL"))
private void onInit(CallbackInfo ci)
{
if(Config.Client.Advanced.AutoUpdater.enableAutoUpdater.get() && !ModInfo.IS_DEV_BUILD) // weird lib class not found error can occur if we don't check if we are in dev
{
DhUpdateScreenBase.tryShowUpdateScreenAndRunAutoUpdateStartup(null);
}
}
}
@@ -0,0 +1,46 @@
/*
* 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.cleanroom.mixins.client;
import com.seibel.distanthorizons.core.api.internal.ClientApi;
import net.minecraft.client.network.NetHandlerPlayClient;
import net.minecraft.network.play.server.SPacketJoinGame;
import net.minecraft.util.text.ITextComponent;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(NetHandlerPlayClient.class)
public class MixinNetHandlerPlayClient
{
@Inject(method = "handleJoinGame", at = @At("RETURN"))
private void onHandleJoinGameEnd(SPacketJoinGame packet, CallbackInfo ci)
{
ClientApi.INSTANCE.onClientOnlyConnected();
}
@Inject(method = "onDisconnect", at = @At("RETURN"))
private void onDisconnect(ITextComponent reason, CallbackInfo ci)
{
ClientApi.INSTANCE.onClientOnlyDisconnected();
}
}
@@ -0,0 +1,83 @@
/*
* 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.cleanroom.mixins.client;
import com.seibel.distanthorizons.common.wrappers.gui.GetConfigScreen;
import com.seibel.distanthorizons.common.wrappers.gui.TexturedButtonWidget;
import com.seibel.distanthorizons.core.config.Config;
import com.seibel.distanthorizons.coreapi.ModInfo;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiOptions;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.util.ResourceLocation;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
/**
* Adds a button to the menu to goto the config
*
* @author coolGi
* @version 12-02-2021
*/
@Mixin(GuiOptions.class)
public class MixinOptionsScreen extends GuiScreen
{
// Get the texture for the button
@Unique private static final ResourceLocation ICON_TEXTURE = new ResourceLocation(ModInfo.ID, "textures/gui/button.png");
@Unique private static final int button_id = 99;
@Inject(at = @At("HEAD"), method = "initGui")
private void lodconfig$init(CallbackInfo ci)
{
if (Config.Client.showDhOptionsButtonInMinecraftUi.get())
this.buttonList.add(
(new TexturedButtonWidget(
button_id,
// Where the button is on the screen
this.width / 2 - 180, this.height / 6 - 12,
// Width and height of the button
20, 20,
// Offset
0, 0,
// Some textuary stuff
20, ICON_TEXTURE, 20, 40,
// Create the button and tell it where to go
// For now it goes to the client option by default
// Add a title to the button
ModInfo.ID + ".title")));
}
@Inject(at = @At("HEAD"), method = "actionPerformed", cancellable = true)
private void lodconfig$actionPerformed(GuiButton button, CallbackInfo ci)
{
if (button.id == button_id)
{
Minecraft.getMinecraft().displayGuiScreen(GetConfigScreen.getScreen(this));
ci.cancel();
}
}
}
@@ -0,0 +1,68 @@
/*
* 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.cleanroom.mixins.client;
import com.seibel.distanthorizons.common.wrappers.world.ClientLevelWrapper;
import com.seibel.distanthorizons.core.api.internal.ClientApi;
import com.seibel.distanthorizons.core.util.math.DhMat4f;
import net.minecraft.client.multiplayer.WorldClient;
import net.minecraft.client.renderer.RenderGlobal;
import net.minecraft.entity.Entity;
import net.minecraft.util.BlockRenderLayer;
import org.lwjgl.opengl.GL32;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(RenderGlobal.class)
public class MixinRenderGlobal
{
@Shadow private WorldClient world;
@Inject(method = "renderBlockLayer(Lnet/minecraft/util/BlockRenderLayer;DILnet/minecraft/entity/Entity;)I", at = @At("HEAD"))
private void renderChunkLayer(BlockRenderLayer blockLayerIn, double partialTicks, int pass, Entity entityIn, CallbackInfoReturnable<Integer> cir)
{
if (blockLayerIn == BlockRenderLayer.SOLID)
{
float[] mcProjMatrixRaw = new float[16];
GL32.glGetFloatv(GL32.GL_PROJECTION_MATRIX, mcProjMatrixRaw);
ClientApi.RENDER_STATE.mcProjectionMatrix = new DhMat4f(mcProjMatrixRaw);
ClientApi.RENDER_STATE.mcProjectionMatrix.transpose();
float[] mcModelViewRaw = new float[16];
GL32.glGetFloatv(GL32.GL_MODELVIEW_MATRIX, mcModelViewRaw);
ClientApi.RENDER_STATE.mcModelViewMatrix = new DhMat4f(mcModelViewRaw);
ClientApi.RENDER_STATE.mcModelViewMatrix.transpose();
ClientApi.RENDER_STATE.partialTickTime = (float) partialTicks;
ClientApi.RENDER_STATE.clientLevelWrapper = ClientLevelWrapper.getWrapperIfDifferent(ClientApi.RENDER_STATE.clientLevelWrapper, this.world);
ClientApi.INSTANCE.renderLods();
//Some 1.12.2 rendering mods breaks if we don't unbind buffers
GL32.glBindVertexArray(0);
GL32.glBindBuffer(GL32.GL_ARRAY_BUFFER, 0);
GL32.glBindBuffer(GL32.GL_ELEMENT_ARRAY_BUFFER, 0);
GL32.glUseProgram(0);
}
}
}
@@ -0,0 +1,17 @@
package com.seibel.distanthorizons.cleanroom.mixins.common;
import net.minecraft.world.storage.ThreadedFileIOBase;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
@Mixin(ThreadedFileIOBase.class)
public class MixinThreadedFileIOBase
{
@Redirect(method = "processQueue", at = @At(value = "INVOKE", target = "Ljava/lang/Thread;sleep(J)V"))
private void reduceSleep(long millis) throws InterruptedException
{
// 0ms between chunks, 5ms when idle
Thread.sleep(millis == 25L ? 5L : 0L);
}
}
@@ -0,0 +1,66 @@
/*
* 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.cleanroom.mixins.server;
import com.seibel.distanthorizons.common.wrappers.misc.IMixinServerPlayer;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.server.MinecraftServer;
import net.minecraft.world.WorldServer;
import net.minecraftforge.common.util.ITeleporter;
import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(EntityPlayerMP.class)
public abstract class MixinEntityPlayerMP implements IMixinServerPlayer
{
@Shadow
@Final
public MinecraftServer server;
@Unique
@Nullable
private volatile WorldServer distantHorizons$dimensionChangeDestination;
@Override
@Nullable
public WorldServer distantHorizons$getDimensionChangeDestination()
{ return this.distantHorizons$dimensionChangeDestination; }
@Inject(at = @At("HEAD"), method = "changeDimension(ILnet/minecraftforge/common/util/ITeleporter;)Lnet/minecraft/entity/Entity;")
public void setDimensionChangeDestination(int destinationDimensionID, ITeleporter teleporter, CallbackInfoReturnable<Entity> cir)
{ this.distantHorizons$dimensionChangeDestination = this.server.getWorld(destinationDimensionID); }
@Inject(at = @At("RETURN"), method = "clearInvulnerableDimensionChange")
public void clearDimensionChangeDestination(CallbackInfo ci)
{ this.distantHorizons$dimensionChangeDestination = null; }
}
@@ -0,0 +1,52 @@
/*
* 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.cleanroom.modAccessor;
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IModChecker;
import net.minecraftforge.fml.common.Loader;
import net.minecraftforge.fml.common.ModContainer;
import java.io.File;
import java.util.Optional;
import java.util.stream.Stream;
public class ModChecker implements IModChecker
{
public static final ModChecker INSTANCE = new ModChecker();
@Override
public boolean isModLoaded(String modid)
{
return Loader.isModLoaded(modid);
}
@Override
public File modLocation(String modid)
{
Stream<ModContainer> foundStream = Loader.instance().getModList().stream().filter(x -> x.getModId().equals(modid));
Optional<ModContainer> container = foundStream.findFirst();
if (!container.isPresent())
{
throw new RuntimeException("Mod not found: " + modid);
}
return container.get().getSource();
}
}
@@ -0,0 +1,20 @@
{
"required": true,
"package": "com.seibel.distanthorizons.cleanroom.mixins",
"compatibilityLevel": "JAVA_8",
"target": "@env(DEFAULT)",
"mixins": [
"common.MixinThreadedFileIOBase"
],
"minVersion": "0.8.7",
"server": [
"server.MixinEntityPlayerMP"
],
"client": [
"client.MixinEntityRenderer",
"client.MixinMinecraft",
"client.MixinNetHandlerPlayClient",
"client.MixinOptionsScreen",
"client.MixinRenderGlobal"
]
}
@@ -0,0 +1,11 @@
{
"required": false,
"package": "com.seibel.distanthorizons.cleanroom.mixins.mod",
"compatibilityLevel": "JAVA_8",
"target": "@env(MOD)",
"mixins": [],
"minVersion": "0.8.7",
"plugin": "com.seibel.distanthorizons.cleanroom.DistantHorizonsConfigPlugin",
"client": [
]
}
+12
View File
@@ -0,0 +1,12 @@
[{
"modid": "${mod_id}",
"name": "${mod_name}",
"version": "${version}",
"mcversion": "1.12.2",
"description": "${description}",
"authorList": ["${cleanroom_authors}"],
"credits": "",
"url": "",
"updateJSON": "",
"logoFile": "${logo_path}"
}]
+6
View File
@@ -0,0 +1,6 @@
{
"pack": {
"description": "${mod_name} Resources",
"pack_format": 3
}
}
@@ -1,12 +1,14 @@
package com.seibel.distanthorizons.common; package com.seibel.distanthorizons.common;
import com.mojang.brigadier.CommandDispatcher; import com.seibel.distanthorizons.api.enums.config.EDhApiMcRenderingFadeMode;
import com.seibel.distanthorizons.api.enums.config.EDhApiRenderApi; import com.seibel.distanthorizons.api.enums.config.EDhApiRenderingEngine;
import com.seibel.distanthorizons.api.enums.worldGeneration.EDhApiDistantGeneratorMode;
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiAfterDhInitEvent; import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiAfterDhInitEvent;
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiBeforeDhInitEvent; import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiBeforeDhInitEvent;
import com.seibel.distanthorizons.common.commands.CommandInitializer; import com.seibel.distanthorizons.common.commands.CommandInitializer;
import com.seibel.distanthorizons.common.wrappers.DependencySetup; import com.seibel.distanthorizons.common.wrappers.DependencySetup;
import com.seibel.distanthorizons.common.wrappers.gui.DhDebugScreenEntry; import com.seibel.distanthorizons.common.wrappers.gui.DhDebugScreenEntry;
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftClientWrapper;
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftServerWrapper; import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftServerWrapper;
import com.seibel.distanthorizons.core.Initializer; import com.seibel.distanthorizons.core.Initializer;
import com.seibel.distanthorizons.core.api.internal.ClientApi; import com.seibel.distanthorizons.core.api.internal.ClientApi;
@@ -30,7 +32,6 @@ import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IModAccesso
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IModChecker; import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IModChecker;
import com.seibel.distanthorizons.coreapi.DependencyInjection.ApiEventInjector; import com.seibel.distanthorizons.coreapi.DependencyInjection.ApiEventInjector;
import com.seibel.distanthorizons.coreapi.ModInfo; import com.seibel.distanthorizons.coreapi.ModInfo;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.server.MinecraftServer; import net.minecraft.server.MinecraftServer;
import net.minecraft.server.dedicated.DedicatedServer; import net.minecraft.server.dedicated.DedicatedServer;
import com.seibel.distanthorizons.core.logging.DhLogger; import com.seibel.distanthorizons.core.logging.DhLogger;
@@ -39,6 +40,11 @@ import java.util.concurrent.CompletableFuture;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.Supplier; import java.util.function.Supplier;
#if MC_VER > MC_1_12_2
import com.mojang.brigadier.CommandDispatcher;
import net.minecraft.commands.CommandSourceStack;
#endif
/** /**
* Base for all mod loader initializers * Base for all mod loader initializers
* and handles most setup. * and handles most setup.
@@ -62,7 +68,9 @@ public abstract class AbstractModInitializer
protected abstract IEventProxy createServerProxy(boolean isDedicated); protected abstract IEventProxy createServerProxy(boolean isDedicated);
protected abstract void initializeModCompat(); protected abstract void initializeModCompat();
#if MC_VER > MC_1_12_2
protected abstract void subscribeRegisterCommandsEvent(Consumer<CommandDispatcher<CommandSourceStack>> eventHandler); protected abstract void subscribeRegisterCommandsEvent(Consumer<CommandDispatcher<CommandSourceStack>> eventHandler);
#endif
protected abstract void subscribeClientStartedEvent(Runnable eventHandler); protected abstract void subscribeClientStartedEvent(Runnable eventHandler);
protected abstract void subscribeServerStartingEvent(Consumer<MinecraftServer> eventHandler); protected abstract void subscribeServerStartingEvent(Consumer<MinecraftServer> eventHandler);
@@ -96,6 +104,7 @@ public abstract class AbstractModInitializer
// Client uses config for auto-updater, so it's initialized here instead of post-init stage // Client uses config for auto-updater, so it's initialized here instead of post-init stage
this.initConfig(); this.initConfig();
logIncompatibilityWarnings(); // needs to be called after config loading logIncompatibilityWarnings(); // needs to be called after config loading
setUnsupportedConfigsBasedOnMcVersion();
Initializer.postConfigInit(); Initializer.postConfigInit();
LOGGER.info(ModInfo.READABLE_NAME + " client Initialized."); LOGGER.info(ModInfo.READABLE_NAME + " client Initialized.");
@@ -130,8 +139,10 @@ public abstract class AbstractModInitializer
this.initializeModCompat(); this.initializeModCompat();
LOGGER.info(ModInfo.READABLE_NAME + " server Initialized, adding event subscribers..."); LOGGER.info(ModInfo.READABLE_NAME + " server Initialized, adding event subscribers...");
#if MC_VER > MC_1_12_2
this.commandInitializer = new CommandInitializer(); this.commandInitializer = new CommandInitializer();
this.subscribeRegisterCommandsEvent(dispatcher -> { this.commandInitializer.initCommands(dispatcher); }); this.subscribeRegisterCommandsEvent(dispatcher -> { this.commandInitializer.initCommands(dispatcher); });
#endif
this.subscribeServerStartingEvent(server -> this.subscribeServerStartingEvent(server ->
{ {
@@ -141,11 +152,20 @@ public abstract class AbstractModInitializer
Initializer.postConfigInit(); Initializer.postConfigInit();
this.postInit(); this.postInit();
this.postServerInit(); this.postServerInit();
#if MC_VER > MC_1_12_2
this.commandInitializer.onServerReady(); this.commandInitializer.onServerReady();
#endif
this.checkForUpdates(); this.checkForUpdates();
LOGGER.info(ModInfo.READABLE_NAME + " server Initialized at " + server.getServerDirectory()); String serverFolderPath;
#if MC_VER <= MC_1_12_2
serverFolderPath = server.getDataDirectory() + "";
#else
serverFolderPath = server.getServerDirectory() + "";
#endif
LOGGER.info(ModInfo.READABLE_NAME + " server Initialized at " + serverFolderPath);
}); });
} }
@@ -245,6 +265,8 @@ public abstract class AbstractModInitializer
} }
catch (Exception e) catch (Exception e)
{ {
NativeDialogUtil.showDialog(ModInfo.READABLE_NAME, e.getMessage(), "ok", "error");
MinecraftClientWrapper.INSTANCE.crashMinecraft(e.getMessage(), e);
future.completeExceptionally(e); future.completeExceptionally(e);
} }
finally finally
@@ -368,17 +390,17 @@ public abstract class AbstractModInitializer
if (iris != null) if (iris != null)
{ {
// get the currently selected rendering API // get the currently selected rendering API
EDhApiRenderApi renderApi = Config.Client.Advanced.Graphics.Experimental.renderingApi.get(); EDhApiRenderingEngine renderApi = Config.Client.Advanced.Graphics.Experimental.renderingEngine.get();
if (renderApi == EDhApiRenderApi.AUTO) if (renderApi == EDhApiRenderingEngine.AUTO)
{ {
IVersionConstants versionConstants = SingletonInjector.INSTANCE.get(IVersionConstants.class); IVersionConstants versionConstants = SingletonInjector.INSTANCE.get(IVersionConstants.class);
renderApi = versionConstants.getDefaultRenderingApi(); renderApi = versionConstants.getDefaultRenderingEngine();
} }
// Iris only supports native OpenGL // Iris only supports native OpenGL
if (renderApi != EDhApiRenderApi.OPEN_GL) if (renderApi != EDhApiRenderingEngine.OPEN_GL)
{ {
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 the DH config file."; String irisUnsupportedMessage = "Iris doesn't support DH when using the ["+ EDhApiRenderingEngine.BLAZE_3D+"] rendering engine, this will need to be fixed on Iris end. As a temporary fix please change the rendering engine to ["+ EDhApiRenderingEngine.OPEN_GL+"] in the DH config file.";
LOGGER.fatal(irisUnsupportedMessage); LOGGER.fatal(irisUnsupportedMessage);
NativeDialogUtil.showDialog(ModInfo.READABLE_NAME, irisUnsupportedMessage, "ok", "error"); NativeDialogUtil.showDialog(ModInfo.READABLE_NAME, irisUnsupportedMessage, "ok", "error");
@@ -393,6 +415,24 @@ public abstract class AbstractModInitializer
} }
/**
* Some Minecraft versions don't support all
* DH options.
* In that case we need to override what options are available.
*/
private static void setUnsupportedConfigsBasedOnMcVersion()
{
#if MC_VER <= MC_1_12_2
Config.Client.Advanced.Graphics.Experimental.renderingEngine.setMcVersionOverrideValue(EDhApiRenderingEngine.OPEN_GL);
Config.Client.Advanced.Graphics.Quality.vanillaFadeMode.setMcVersionOverrideValue(EDhApiMcRenderingFadeMode.NONE);
Config.Common.WorldGenerator.distantGeneratorMode.setMcVersionOverrideValue(EDhApiDistantGeneratorMode.INTERNAL_SERVER);
#elif MC_VER <= MC_1_21_10
Config.Client.Advanced.Graphics.Experimental.renderingEngine.setMcVersionOverrideValue(EDhApiRenderingEngine.OPEN_GL);
#else
#endif
}
//endregion //endregion
@@ -12,10 +12,17 @@ import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IPluginPacketSende
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IServerPlayerWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IServerPlayerWrapper;
import com.seibel.distanthorizons.coreapi.ModInfo; import com.seibel.distanthorizons.coreapi.ModInfo;
import io.netty.buffer.ByteBufUtil; import io.netty.buffer.ByteBufUtil;
#if MC_VER <= MC_1_12_2
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.network.PacketBuffer;
#else
import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
#endif
#if MC_VER <= MC_1_21_10 #if MC_VER <= MC_1_12_2
import net.minecraft.util.ResourceLocation;
#elif MC_VER <= MC_1_21_10
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
#else #else
import net.minecraft.resources.Identifier; import net.minecraft.resources.Identifier;
@@ -30,7 +37,9 @@ public abstract class AbstractPluginPacketSender implements IPluginPacketSender
.fileLevelConfig(Config.Common.Logging.logNetworkEventToFile) .fileLevelConfig(Config.Common.Logging.logNetworkEventToFile)
.build(); .build();
#if MC_VER <= MC_1_20_6 #if MC_VER <= MC_1_12_2
public static final String WRAPPER_PACKET_RESOURCE = ModInfo.RESOURCE_NAMESPACE + ModInfo.WRAPPER_PACKET_PATH;
#elif MC_VER <= MC_1_20_6
public static final ResourceLocation WRAPPER_PACKET_RESOURCE = new ResourceLocation(ModInfo.RESOURCE_NAMESPACE, ModInfo.WRAPPER_PACKET_PATH); public static final ResourceLocation WRAPPER_PACKET_RESOURCE = new ResourceLocation(ModInfo.RESOURCE_NAMESPACE, ModInfo.WRAPPER_PACKET_PATH);
#elif MC_VER <= MC_1_21_10 #elif MC_VER <= MC_1_21_10
public static final ResourceLocation WRAPPER_PACKET_RESOURCE = ResourceLocation.fromNamespaceAndPath(ModInfo.RESOURCE_NAMESPACE, ModInfo.WRAPPER_PACKET_PATH); public static final ResourceLocation WRAPPER_PACKET_RESOURCE = ResourceLocation.fromNamespaceAndPath(ModInfo.RESOURCE_NAMESPACE, ModInfo.WRAPPER_PACKET_PATH);
@@ -52,14 +61,28 @@ public abstract class AbstractPluginPacketSender implements IPluginPacketSender
@Override @Override
public final void sendToClient(IServerPlayerWrapper serverPlayer, AbstractNetworkMessage message) public final void sendToClient(IServerPlayerWrapper serverPlayer, AbstractNetworkMessage message)
{ {
#if MC_VER <= MC_1_12_2
this.sendToClient((EntityPlayerMP) serverPlayer.getWrappedMcObject(), message);
#else
this.sendToClient((ServerPlayer) serverPlayer.getWrappedMcObject(), message); this.sendToClient((ServerPlayer) serverPlayer.getWrappedMcObject(), message);
#endif
} }
#if MC_VER <= MC_1_12_2
public abstract void sendToClient(EntityPlayerMP serverPlayer, AbstractNetworkMessage message);
#else
public abstract void sendToClient(ServerPlayer serverPlayer, AbstractNetworkMessage message); public abstract void sendToClient(ServerPlayer serverPlayer, AbstractNetworkMessage message);
#endif
@Override @Override
public abstract void sendToServer(AbstractNetworkMessage message); public abstract void sendToServer(AbstractNetworkMessage message);
#if MC_VER <= MC_1_12_2
public AbstractNetworkMessage decodeMessage(PacketBuffer in)
#else
public AbstractNetworkMessage decodeMessage(FriendlyByteBuf in) public AbstractNetworkMessage decodeMessage(FriendlyByteBuf in)
#endif
{ {
AbstractNetworkMessage message = null; AbstractNetworkMessage message = null;
@@ -100,7 +123,11 @@ public abstract class AbstractPluginPacketSender implements IPluginPacketSender
} }
} }
#if MC_VER <= MC_1_12_2
public void encodeMessage(PacketBuffer out, AbstractNetworkMessage message)
#else
public void encodeMessage(FriendlyByteBuf out, AbstractNetworkMessage message) public void encodeMessage(FriendlyByteBuf out, AbstractNetworkMessage message)
#endif
{ {
// This is intentionally unhandled, because errors related to this are unlikely to appear in wild // This is intentionally unhandled, because errors related to this are unlikely to appear in wild
Objects.requireNonNull(message); Objects.requireNonNull(message);
@@ -1,5 +1,9 @@
package com.seibel.distanthorizons.common.commands; package com.seibel.distanthorizons.common.commands;
#if MC_VER <= MC_1_12_2
public abstract class AbstractCommand {}
#else
import com.mojang.brigadier.builder.LiteralArgumentBuilder; import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.context.CommandContext; import com.mojang.brigadier.context.CommandContext;
import com.seibel.distanthorizons.common.wrappers.misc.ServerPlayerWrapper; import com.seibel.distanthorizons.common.wrappers.misc.ServerPlayerWrapper;
@@ -100,3 +104,4 @@ public abstract class AbstractCommand
} }
} }
#endif
@@ -1,12 +1,26 @@
package com.seibel.distanthorizons.common.commands; package com.seibel.distanthorizons.common.commands;
#if MC_VER <= MC_1_12_2
import com.seibel.distanthorizons.core.config.ConfigHandler;
import com.seibel.distanthorizons.core.config.types.AbstractConfigBase;
import com.seibel.distanthorizons.core.config.types.ConfigEntry;
import com.seibel.distanthorizons.core.logging.f3.F3Screen;
import net.minecraft.command.CommandBase;
import net.minecraft.command.ICommand;
import net.minecraft.command.ICommandSender;
import net.minecraft.server.MinecraftServer;
import net.minecraft.util.text.TextComponentString;
#else
import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.builder.LiteralArgumentBuilder; import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.CommandSourceStack;
import static net.minecraft.commands.Commands.literal;
#endif
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
import static com.seibel.distanthorizons.core.network.messages.MessageRegistry.DEBUG_CODEC_CRASH_MESSAGE; import static com.seibel.distanthorizons.core.network.messages.MessageRegistry.DEBUG_CODEC_CRASH_MESSAGE;
import static net.minecraft.commands.Commands.literal;
#if MC_VER <= MC_1_21_10 #if MC_VER <= MC_1_21_10
#else #else
@@ -25,6 +39,70 @@ public class CommandInitializer
#endif #endif
#if MC_VER <= MC_1_12_2
public static ICommand initCommands()
{
return new CommandBase()
{
@Override
public String getName() { return "dh"; }
@Override
public String getUsage(ICommandSender sender) { return "/dh <debug|config|pregen>"; }
@Override
public void execute(MinecraftServer server, ICommandSender sender, String[] args)
{
if (args.length == 0)
{
if (DEBUG_CODEC_CRASH_MESSAGE)
{
sender.sendMessage(new TextComponentString("Usage: /dh <debug|config|crash|pregen>"));
}
else
{
sender.sendMessage(new TextComponentString("Usage: /dh <debug|config|pregen"));
}
return;
}
switch (args[0])
{
case "debug":
DebugCommand debugCommand = new DebugCommand();
debugCommand.execute(sender);
break;
case "config":
ConfigCommand configCommand = new ConfigCommand();
configCommand.execute(sender, args);
break;
case "crash":
if (DEBUG_CODEC_CRASH_MESSAGE)
{
CrashCommand crashCommand = new CrashCommand();
crashCommand.execute(sender, args);
}
break;
case "pregen":
if (!server.isDedicatedServer())
{
sender.sendMessage(new TextComponentString("Pregen command is only available on dedicated servers"));
break;
}
PregenCommand pregenCommand = new PregenCommand();
pregenCommand.execute(server, sender, args);
break;
default:
sender.sendMessage(new TextComponentString("Unknown subcommand: " + args[0]));
}
}
};
}
#else
/** /**
* A received command dispatcher, which is held until the server is ready to initialize the commands. * A received command dispatcher, which is held until the server is ready to initialize the commands.
*/ */
@@ -80,5 +158,5 @@ public class CommandInitializer
commandDispatcher.register(builder); commandDispatcher.register(builder);
} }
#endif
} }
@@ -1,13 +1,25 @@
package com.seibel.distanthorizons.common.commands; package com.seibel.distanthorizons.common.commands;
import com.mojang.brigadier.arguments.*;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.context.CommandContext;
import com.seibel.distanthorizons.core.config.ConfigHandler; import com.seibel.distanthorizons.core.config.ConfigHandler;
import com.seibel.distanthorizons.core.config.types.AbstractConfigBase; import com.seibel.distanthorizons.core.config.types.AbstractConfigBase;
import com.seibel.distanthorizons.core.config.types.ConfigEntry; import com.seibel.distanthorizons.core.config.types.ConfigEntry;
#if MC_VER <= MC_1_12_2
import net.minecraft.command.ICommandSender;
import net.minecraft.util.text.TextComponentString;
#else
import com.mojang.brigadier.arguments.*;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.context.CommandContext;
import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.CommandSourceStack;
import static com.mojang.brigadier.arguments.DoubleArgumentType.doubleArg;
import static com.mojang.brigadier.arguments.IntegerArgumentType.integer;
import static net.minecraft.commands.Commands.argument;
import static net.minecraft.commands.Commands.literal;
#endif
import java.util.Arrays; import java.util.Arrays;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
@@ -16,16 +28,75 @@ import java.util.function.Function;
import java.util.function.Supplier; import java.util.function.Supplier;
import java.util.function.ToIntBiFunction; import java.util.function.ToIntBiFunction;
import static com.mojang.brigadier.arguments.DoubleArgumentType.doubleArg;
import static com.mojang.brigadier.arguments.IntegerArgumentType.integer;
import static net.minecraft.commands.Commands.argument;
import static net.minecraft.commands.Commands.literal;
/** /**
* Command for managing config. * Command for managing config.
*/ */
public class ConfigCommand extends AbstractCommand public class ConfigCommand extends AbstractCommand
{ {
#if MC_VER <= MC_1_12_2
@SuppressWarnings({"unchecked", "rawtypes"})
private static void setConfigValue(ConfigEntry<?> configEntry, String value)
{
Class<?> type = configEntry.getType();
if (type == Boolean.class) ((ConfigEntry) configEntry).set(Boolean.parseBoolean(value));
else if (type == Integer.class) ((ConfigEntry) configEntry).set(Integer.parseInt(value));
else if (type == Double.class) ((ConfigEntry) configEntry).set(Double.parseDouble(value));
else if (type == Float.class) ((ConfigEntry) configEntry).set(Float.parseFloat(value));
else if (type == Long.class) ((ConfigEntry) configEntry).set(Long.parseLong(value));
else if (type == String.class) ((ConfigEntry) configEntry).set(value);
else if (type.isEnum()) ((ConfigEntry) configEntry).set(Enum.valueOf((Class<Enum>) type, value));
else throw new RuntimeException("Unsupported config type: " + type.getSimpleName());
}
public void execute(ICommandSender sender, String[] args)
{
if (args.length < 2)
{
sender.sendMessage(new TextComponentString("Usage: /dh config <name> [value]"));
return;
}
String configName = args[1];
AbstractConfigBase<?> found = null;
for (AbstractConfigBase<?> entry : ConfigHandler.INSTANCE.configBaseList)
{
if (entry instanceof ConfigEntry && configName.equals(((ConfigEntry<?>) entry).getChatCommandName()))
{
found = entry;
break;
}
}
if (found == null)
{
sender.sendMessage(new TextComponentString("Unknown config: " + configName));
return;
}
ConfigEntry<?> configEntry = (ConfigEntry<?>) found;
if (args.length == 2)
{
sender.sendMessage(new TextComponentString("Current value of " + configName + " is " + configEntry.get()));
}
else
{
String value = args[2];
try
{
setConfigValue(configEntry, value);
sender.sendMessage(new TextComponentString("Changed " + configName + " to " + value));
}
catch (Exception e)
{
sender.sendMessage(new TextComponentString("Invalid value: " + value));
}
}
}
#else
private static final List<CommandArgumentData<?>> commandArguments = Arrays.asList( private static final List<CommandArgumentData<?>> commandArguments = Arrays.asList(
new CommandArgumentData<>(Integer.class, configEntry -> integer(configEntry.getMin(), configEntry.getMax()), IntegerArgumentType::getInteger), new CommandArgumentData<>(Integer.class, configEntry -> integer(configEntry.getMin(), configEntry.getMax()), IntegerArgumentType::getInteger),
new CommandArgumentData<>(Double.class, configEntry -> doubleArg(configEntry.getMin(), configEntry.getMax()), DoubleArgumentType::getDouble), new CommandArgumentData<>(Double.class, configEntry -> doubleArg(configEntry.getMin(), configEntry.getMax()), DoubleArgumentType::getDouble),
@@ -150,5 +221,6 @@ public class ConfigCommand extends AbstractCommand
} }
} }
#endif
} }
@@ -1,15 +1,60 @@
package com.seibel.distanthorizons.common.commands; package com.seibel.distanthorizons.common.commands;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.seibel.distanthorizons.core.api.internal.SharedApi; import com.seibel.distanthorizons.core.api.internal.SharedApi;
import com.seibel.distanthorizons.core.multiplayer.server.ServerPlayerState; import com.seibel.distanthorizons.core.multiplayer.server.ServerPlayerState;
import com.seibel.distanthorizons.core.network.messages.base.CodecCrashMessage; import com.seibel.distanthorizons.core.network.messages.base.CodecCrashMessage;
#if MC_VER <= MC_1_12_2
import com.seibel.distanthorizons.common.wrappers.misc.ServerPlayerWrapper;
import net.minecraft.command.ICommandSender;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.util.text.TextComponentString;
#else
import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.CommandSourceStack;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import static net.minecraft.commands.Commands.literal; import static net.minecraft.commands.Commands.literal;
#endif
public class CrashCommand extends AbstractCommand public class CrashCommand extends AbstractCommand
{ {
#if MC_VER <= MC_1_12_2
public void execute(ICommandSender sender, String[] args)
{
if (!(sender instanceof EntityPlayerMP))
{
sender.sendMessage(new TextComponentString("This command can only be run by a player"));
return;
}
if (args.length < 2)
{
sender.sendMessage(new TextComponentString("Usage: /dh crash <encode|decode>"));
return;
}
if (SharedApi.tryGetDhServerWorld() == null) return;
ServerPlayerState serverPlayerState = SharedApi.tryGetDhServerWorld()
.getServerPlayerStateManager()
.getConnectedPlayer(ServerPlayerWrapper.getWrapper((EntityPlayerMP) sender));
if (serverPlayerState == null) return;
switch (args[1])
{
case "encode":
serverPlayerState.networkSession.sendMessage(new CodecCrashMessage(CodecCrashMessage.ECrashPhase.ENCODE));
break;
case "decode":
serverPlayerState.networkSession.sendMessage(new CodecCrashMessage(CodecCrashMessage.ECrashPhase.DECODE));
break;
default:
sender.sendMessage(new TextComponentString("Usage: /dh crash <encode|decode>"));
}
}
#else
@Override @Override
public LiteralArgumentBuilder<CommandSourceStack> buildCommand() public LiteralArgumentBuilder<CommandSourceStack> buildCommand()
{ {
@@ -40,5 +85,6 @@ public class CrashCommand extends AbstractCommand
return 1; return 1;
})); }));
} }
#endif
} }
@@ -1,25 +1,44 @@
package com.seibel.distanthorizons.common.commands; package com.seibel.distanthorizons.common.commands;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.seibel.distanthorizons.core.logging.f3.F3Screen; import com.seibel.distanthorizons.core.logging.f3.F3Screen;
#if MC_VER <= MC_1_12_2
import net.minecraft.command.ICommandSender;
import net.minecraft.util.text.TextComponentString;
#else
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.CommandSourceStack;
import static net.minecraft.commands.Commands.literal;
#endif
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import static net.minecraft.commands.Commands.literal;
public class DebugCommand extends AbstractCommand public class DebugCommand extends AbstractCommand
{ {
private static String getDebugString()
{
List<String> lines = new ArrayList<>();
F3Screen.addStringToDisplay(lines);
return String.join("\n", lines);
}
#if MC_VER > MC_1_12_2
@Override @Override
public LiteralArgumentBuilder<CommandSourceStack> buildCommand() public LiteralArgumentBuilder<CommandSourceStack> buildCommand()
{ {
return literal("debug") return literal("debug")
.executes(c -> { .executes(c -> {
List<String> lines = new ArrayList<>(); return this.sendSuccessResponse(c, getDebugString(), false);
F3Screen.addStringToDisplay(lines); });
return this.sendSuccessResponse(c, String.join("\n", lines), false);
});
} }
#else
public void execute(ICommandSender sender)
{
sender.sendMessage(new TextComponentString(getDebugString()));
}
#endif
} }
@@ -1,27 +1,36 @@
package com.seibel.distanthorizons.common.commands; package com.seibel.distanthorizons.common.commands;
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.common.wrappers.world.ServerLevelWrapper;
import com.seibel.distanthorizons.core.api.internal.SharedApi; import com.seibel.distanthorizons.core.api.internal.SharedApi;
import com.seibel.distanthorizons.core.generation.PregenManager; import com.seibel.distanthorizons.core.generation.PregenManager;
import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos2D; import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos2D;
import com.seibel.distanthorizons.core.world.DhServerWorld; import com.seibel.distanthorizons.core.world.DhServerWorld;
#if MC_VER <= MC_1_12_2
import net.minecraft.command.ICommandSender;
import net.minecraft.server.MinecraftServer;
import net.minecraft.util.text.TextComponentString;
import net.minecraft.world.WorldServer;
#else
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.arguments.DimensionArgument; import net.minecraft.commands.arguments.DimensionArgument;
import net.minecraft.commands.arguments.coordinates.ColumnPosArgument; import net.minecraft.commands.arguments.coordinates.ColumnPosArgument;
import net.minecraft.server.level.ColumnPos; import net.minecraft.server.level.ColumnPos;
import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerLevel;
import java.util.Objects;
import java.util.concurrent.CancellationException;
import java.util.concurrent.CompletableFuture;
import static com.mojang.brigadier.arguments.IntegerArgumentType.getInteger; import static com.mojang.brigadier.arguments.IntegerArgumentType.getInteger;
import static com.mojang.brigadier.arguments.IntegerArgumentType.integer; import static com.mojang.brigadier.arguments.IntegerArgumentType.integer;
import static net.minecraft.commands.Commands.argument; import static net.minecraft.commands.Commands.argument;
import static net.minecraft.commands.Commands.literal; import static net.minecraft.commands.Commands.literal;
#endif
import java.util.Objects;
import java.util.concurrent.CancellationException;
import java.util.concurrent.CompletableFuture;
public class PregenCommand extends AbstractCommand public class PregenCommand extends AbstractCommand
{ {
@@ -31,6 +40,101 @@ public class PregenCommand extends AbstractCommand
return world.getPregenManager(); return world.getPregenManager();
} }
#if MC_VER <= MC_1_12_2
public void execute(MinecraftServer server, ICommandSender sender, String[] args)
{
if (args.length < 2)
{
sender.sendMessage(new TextComponentString("Usage: /dh pregen <status|start|stop>"));
return;
}
switch (args[1])
{
case "status":
{
String statusString = this.getPregenManager().getStatusString();
sender.sendMessage(new TextComponentString(
statusString != null ? statusString : "Pregen is not running"));
break;
}
case "start":
{
if (args.length < 5)
{
sender.sendMessage(new TextComponentString("Usage: /dh pregen start <dimension> <x> <z> <chunkRadius>"));
return;
}
try
{
String dimensionName = args[2];
int x = Integer.parseInt(args[3]);
int z = Integer.parseInt(args[4]);
int chunkRadius = args.length >= 6 ? Integer.parseInt(args[5]) : 32;
// find the world by dimension name
WorldServer world = null;
for (WorldServer w : server.worlds)
{
if (w.provider.getDimensionType().getName().equals(dimensionName))
{
world = w;
break;
}
}
if (world == null)
{
sender.sendMessage(new TextComponentString("Unknown dimension: " + dimensionName));
return;
}
sender.sendMessage(new TextComponentString("Starting pregen. Progress will be in the server console."));
final ICommandSender finalSender = sender;
CompletableFuture<Void> future = this.getPregenManager().startPregen(
ServerLevelWrapper.getWrapper(world),
new DhBlockPos2D(x, z),
chunkRadius
);
future.whenComplete((result, throwable) -> {
if (throwable instanceof CancellationException)
{
finalSender.sendMessage(new TextComponentString("Pregen is cancelled"));
return;
}
else if (throwable != null)
{
finalSender.sendMessage(new TextComponentString("Pregen failed: " + throwable.getMessage()));
return;
}
finalSender.sendMessage(new TextComponentString("Pregen is complete"));
});
}
catch (NumberFormatException e)
{
sender.sendMessage(new TextComponentString("Invalid number format"));
}
break;
}
case "stop":
{
CompletableFuture<Void> runningPregen = this.getPregenManager().getRunningPregen();
if (runningPregen == null)
{
sender.sendMessage(new TextComponentString("Pregen is not running"));
return;
}
runningPregen.cancel(true);
break;
}
default:
sender.sendMessage(new TextComponentString("Unknown subcommand: " + args[1]));
}
}
#else
@Override @Override
public LiteralArgumentBuilder<CommandSourceStack> buildCommand() public LiteralArgumentBuilder<CommandSourceStack> buildCommand()
{ {
@@ -110,5 +214,5 @@ public class PregenCommand extends AbstractCommand
runningPregen.cancel(true); runningPregen.cancel(true);
return 1; return 1;
} }
#endif
} }
@@ -1,6 +1,7 @@
package com.seibel.distanthorizons.common.commonMixins; package com.seibel.distanthorizons.common.commonMixins;
import com.seibel.distanthorizons.api.enums.config.EDhApiUpdateBranch; import com.seibel.distanthorizons.api.enums.config.EDhApiUpdateBranch;
import com.seibel.distanthorizons.common.wrappers.gui.DhScreenUtil;
import com.seibel.distanthorizons.common.wrappers.gui.updater.UpdateModScreen; import com.seibel.distanthorizons.common.wrappers.gui.updater.UpdateModScreen;
import com.seibel.distanthorizons.core.config.Config; import com.seibel.distanthorizons.core.config.Config;
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
@@ -9,19 +10,25 @@ import com.seibel.distanthorizons.core.jar.installer.ModrinthGetter;
import com.seibel.distanthorizons.core.jar.updater.SelfUpdater; import com.seibel.distanthorizons.core.jar.updater.SelfUpdater;
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.render.RenderThreadTaskHandler;
import com.seibel.distanthorizons.core.wrapperInterfaces.IVersionConstants; import com.seibel.distanthorizons.core.wrapperInterfaces.IVersionConstants;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
#if MC_VER <= MC_1_12_2
import net.minecraft.client.gui.GuiMainMenu;
#else
import net.minecraft.client.gui.screens.TitleScreen; import net.minecraft.client.gui.screens.TitleScreen;
#endif
import java.util.ArrayList; import java.util.ArrayList;
public class DhUpdateScreenBase public class DhUpdateScreenBase
{ {
private static final DhLogger LOGGER = new DhLoggerBuilder().build(); private static final DhLogger LOGGER = new DhLoggerBuilder().build();
#if MC_VER <= MC_1_12_2
private static final Minecraft MC = Minecraft.getMinecraft();
#else
private static final Minecraft MC = Minecraft.getInstance(); private static final Minecraft MC = Minecraft.getInstance();
#endif
public static void tryShowUpdateScreenAndRunAutoUpdateStartup(Runnable runnable) public static void tryShowUpdateScreenAndRunAutoUpdateStartup(Runnable runnable)
{ {
@@ -31,12 +38,6 @@ public class DhUpdateScreenBase
{ {
return; return;
} }
if (!Config.Client.Advanced.AutoUpdater.enableAutoUpdater.get())
{
LOGGER.info("Auto update disabled, ignoring new version...");
return;
}
runnable = () -> runnable = () ->
@@ -68,25 +69,31 @@ public class DhUpdateScreenBase
} }
try // running on the render thread is required since setting the MC screen may trigger
// before its allowed, silently failing
RenderThreadTaskHandler.INSTANCE.queueRunningOnRenderThread("Update Screen", () ->
{ {
UpdateModScreen updateScreen = new UpdateModScreen( try
new TitleScreen(false), {
versionId #if MC_VER <= MC_1_12_2
); DhScreenUtil.setScreen(new UpdateModScreen(
new GuiMainMenu(),
#if MC_VER <= MC_26_1_2 versionId
MC.setScreen(updateScreen); ));
#else #else
MC.setScreenAndShow(updateScreen); DhScreenUtil.setScreen(new UpdateModScreen(
#endif new TitleScreen(false),
} versionId
catch (Exception e) ));
{ #endif
// info instead of error since this can be ignored and probably just means }
// there isn't a new DH version available catch (Exception e)
LOGGER.info("Unable to show DH update screen, reason: ["+e.getMessage()+"]."); {
} // info instead of error since this can be ignored and probably just means
// there isn't a new DH version available
LOGGER.error("Unable to show DH update screen, reason: ["+e.getMessage()+"].");
}
});
}; };
runnable.run(); runnable.run();
} }
@@ -6,15 +6,23 @@ import com.seibel.distanthorizons.core.api.internal.ServerApi;
import com.seibel.distanthorizons.core.api.internal.SharedApi; import com.seibel.distanthorizons.core.api.internal.SharedApi;
import com.seibel.distanthorizons.core.pos.DhChunkPos; import com.seibel.distanthorizons.core.pos.DhChunkPos;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IServerLevelWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.world.IServerLevelWrapper;
#if MC_VER <= MC_1_12_2
import net.minecraft.world.WorldServer;
import net.minecraft.world.chunk.Chunk;
#else
import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.chunk.ChunkAccess; import net.minecraft.world.level.chunk.ChunkAccess;
import net.minecraft.world.level.chunk.ProtoChunk; import net.minecraft.world.level.chunk.ProtoChunk;
#endif
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
public class MixinChunkMapCommon public class MixinChunkMapCommon
{ {
#if MC_VER <= MC_1_12_2
public static void onChunkSave(WorldServer level, Chunk chunk)
#else
public static void onChunkSave(ServerLevel level, ChunkAccess chunk, CallbackInfoReturnable<Boolean> ci) public static void onChunkSave(ServerLevel level, ChunkAccess chunk, CallbackInfoReturnable<Boolean> ci)
#endif
{ {
IServerLevelWrapper levelWrapper = ServerLevelWrapper.getWrapper(level); IServerLevelWrapper levelWrapper = ServerLevelWrapper.getWrapper(level);
@@ -37,7 +45,7 @@ public class MixinChunkMapCommon
// is this chunk being saved to disk? // is this chunk being saved to disk?
boolean savingChunkToDisk = ci.getReturnValue(); boolean savingChunkToDisk = #if MC_VER <= MC_1_12_2 true #else ci.getReturnValue() #endif;
// true means a chunk was saved to disk // true means a chunk was saved to disk
if (!savingChunkToDisk) if (!savingChunkToDisk)
{ {
@@ -50,7 +58,12 @@ public class MixinChunkMapCommon
// MC has a tendency to try saving incomplete or corrupted chunks (which show up as empty or black chunks) // 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 // this logic should prevent that from happening
#if MC_VER <= MC_1_17_1 #if MC_VER <= MC_1_12_2
if (!chunk.isTerrainPopulated() || !chunk.isLightPopulated())
{
return;
}
#elif MC_VER <= MC_1_17_1
if (chunk.isUnsaved() || chunk.getUpgradeData() != null || !chunk.isLightCorrect()) if (chunk.isUnsaved() || chunk.getUpgradeData() != null || !chunk.isLightCorrect())
{ {
return; return;
@@ -67,7 +80,12 @@ public class MixinChunkMapCommon
// biome validation // // biome validation //
// some chunks may be missing their biomes, which cause issues when attempting to save them // some chunks may be missing their biomes, which cause issues when attempting to save them
#if MC_VER <= MC_1_17_1 #if MC_VER <= MC_1_12_2
if (chunk. getBiomeArray() == null)
{
return;
}
#elif MC_VER <= MC_1_17_1
if (chunk.getBiomes() == null) if (chunk.getBiomes() == null)
{ {
return; return;
@@ -0,0 +1,62 @@
package com.seibel.distanthorizons.common.commonMixins;
#if MC_VER > MC_1_12_2
import com.seibel.distanthorizons.common.wrappers.McObjectConverter;
import com.seibel.distanthorizons.common.wrappers.modAccessor.AbstractImmersivePortalsAccessorCommon;
import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos;
import com.seibel.distanthorizons.core.util.math.DhVec3d;
import net.minecraft.client.Minecraft;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.phys.Vec3;
public class MixinImmersivePortalsRenderStatesCommon
{
/**
* Used to access variables that will change when rendering
* different levels with Immersive Portals
* (ie player/camera position level reference)
* but that we only want for the loaded level.
*/
public static void saveVolatileOriginals()
{
Minecraft mc = Minecraft.getInstance();
AbstractImmersivePortalsAccessorCommon.actualLevel = mc.level;
// clear everything if the player is missing
// (ie the world hasn't loaded yet)
if (mc.player == null)
{
AbstractImmersivePortalsAccessorCommon.actualBlockPos = null;
AbstractImmersivePortalsAccessorCommon.actualChunkPos = null;
AbstractImmersivePortalsAccessorCommon.actualCameraPos = null;
return;
}
// player block pos
BlockPos playerBlockPos = mc.player.blockPosition();
AbstractImmersivePortalsAccessorCommon.actualBlockPos = new DhBlockPos(playerBlockPos.getX(), playerBlockPos.getY(), playerBlockPos.getZ());
// player chunk pos
#if MC_VER < MC_1_17_1
ChunkPos playerChunkPos = new ChunkPos(mc.player.blockPosition());
#else
ChunkPos playerChunkPos = mc.player.chunkPosition();
#endif
AbstractImmersivePortalsAccessorCommon.actualChunkPos = McObjectConverter.Convert(playerChunkPos);
// camera pos
#if MC_VER <= MC_1_21_10
Vec3 cameraPos = mc.gameRenderer.getMainCamera().getPosition();
#elif MC_VER <= MC_26_1_2
Vec3 cameraPos = mc.gameRenderer.getMainCamera().position();
#else
Vec3 cameraPos = mc.gameRenderer.mainCamera().position();
#endif
AbstractImmersivePortalsAccessorCommon.actualCameraPos = new DhVec3d(cameraPos.x(), cameraPos.y(), cameraPos.z());
}
}
#endif
@@ -7,21 +7,26 @@ import com.seibel.distanthorizons.core.dependencyInjection.ModAccessorInjector;
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IImmersivePortalsAccessor;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
#if MC_VER <= MC_1_12_2
#else
import net.minecraft.client.Camera; import net.minecraft.client.Camera;
import net.minecraft.world.effect.MobEffects; import net.minecraft.world.effect.MobEffects;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.LivingEntity;
#endif
#if MC_VER <= MC_1_12_2
import net.minecraft.client.Camera; import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.world.effect.MobEffects; import net.minecraft.entity.Entity;
import net.minecraft.world.entity.Entity; import net.minecraft.init.MobEffects;
import net.minecraft.world.entity.LivingEntity; import net.minecraft.util.math.BlockPos;
import net.minecraftforge.fluids.IFluidBlock;
#if MC_VER < MC_1_17_1 import net.minecraft.block.state.IBlockState;
#elif MC_VER < MC_1_17_1
import net.minecraft.world.level.material.FluidState; import net.minecraft.world.level.material.FluidState;
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;
@@ -51,22 +56,29 @@ import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
#else #else
import net.minecraft.world.level.material.FogType; import net.minecraft.world.level.material.FogType;
import net.minecraft.client.renderer.fog.FogRenderer;
import net.minecraft.client.renderer.fog.FogData;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
#endif #endif
public class MixinVanillaFogCommon public class MixinVanillaFogCommon
{ {
#if MC_VER <= MC_1_12_2
#if MC_VER < MC_1_21_6 public static boolean cancelFog(int startCoords, Minecraft mc)
#elif MC_VER < MC_1_21_6
public static boolean cancelFog(Camera camera, FogRenderer.FogMode fogMode) public static boolean cancelFog(Camera camera, FogRenderer.FogMode fogMode)
#else #else
public static boolean cancelFog() public static boolean cancelFog()
#endif #endif
{ {
#if MC_VER <= MC_1_12_2
#if MC_VER < MC_1_21_6 EntityPlayerSP entity = mc.player;
#elif MC_VER < MC_1_21_6
Entity entity = camera.getEntity(); Entity entity = camera.getEntity();
#elif MC_VER <= MC_1_21_10 #elif MC_VER <= MC_1_21_10
Camera camera = Minecraft.getInstance().gameRenderer.getMainCamera(); Camera camera = Minecraft.getInstance().gameRenderer.getMainCamera();
@@ -79,13 +91,23 @@ public class MixinVanillaFogCommon
Entity entity = camera.entity(); Entity entity = camera.entity();
#endif #endif
#if MC_VER <= MC_1_12_2
boolean cameraNotInFluid = cameraNotInFluid(mc);
#else
boolean cameraNotInFluid = cameraNotInFluid(camera); boolean cameraNotInFluid = cameraNotInFluid(camera);
#endif
#if MC_VER <= MC_1_12_2
boolean isSpecialFog = entity.isPotionActive(MobEffects.BLINDNESS);
#else
boolean isSpecialFog = (entity instanceof LivingEntity) && ((LivingEntity) entity).hasEffect(MobEffects.BLINDNESS); boolean isSpecialFog = (entity instanceof LivingEntity) && ((LivingEntity) entity).hasEffect(MobEffects.BLINDNESS);
#endif
boolean cancelFog = !isSpecialFog; boolean cancelFog = !isSpecialFog;
cancelFog = cancelFog && cameraNotInFluid; cancelFog = cancelFog && cameraNotInFluid;
#if MC_VER < MC_1_21_6 #if MC_VER <= MC_1_12_2
cancelFog = cancelFog && startCoords == 0; // 0 = terrain fog
#elif MC_VER < MC_1_21_6
cancelFog = cancelFog && (fogMode == FogRenderer.FogMode.FOG_TERRAIN); cancelFog = cancelFog && (fogMode == FogRenderer.FogMode.FOG_TERRAIN);
#endif #endif
@@ -93,12 +115,30 @@ public class MixinVanillaFogCommon
cancelFog = cancelFog && !Config.Client.Advanced.Graphics.Fog.enableVanillaFog.get(); cancelFog = cancelFog && !Config.Client.Advanced.Graphics.Fog.enableVanillaFog.get();
// since DH won't render through immersive portals
// the vanilla fog should be enabled
IImmersivePortalsAccessor immersivePortals = ModAccessorInjector.INSTANCE.get(IImmersivePortalsAccessor.class);
if (immersivePortals != null
&& immersivePortals.isRenderingPortal())
{
cancelFog = false;
}
return cancelFog; return cancelFog;
} }
#if MC_VER <= MC_1_12_2
private static boolean cameraNotInFluid(Minecraft mc)
#else
private static boolean cameraNotInFluid(Camera camera) private static boolean cameraNotInFluid(Camera camera)
#endif
{ {
#if MC_VER < MC_1_17_1 #if MC_VER <= MC_1_12_2
Entity view = mc.getRenderViewEntity();
if (view == null) return true;
IBlockState fluidState = mc.world.getBlockState(new BlockPos(view.getPositionEyes(mc.getRenderPartialTicks())));
boolean cameraNotInFluid = !(fluidState.getMaterial().isLiquid() || fluidState.getBlock() instanceof IFluidBlock);
#elif MC_VER < MC_1_17_1
FluidState fluidState = camera.getFluidInCamera(); FluidState fluidState = camera.getFluidInCamera();
boolean cameraNotInFluid = fluidState.isEmpty(); boolean cameraNotInFluid = fluidState.isEmpty();
#else #else
@@ -26,34 +26,29 @@ public class BlazeDebugWireframeRenderer {}
import com.mojang.blaze3d.buffers.GpuBuffer; import com.mojang.blaze3d.buffers.GpuBuffer;
import com.mojang.blaze3d.buffers.GpuBufferSlice; 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.pipeline.RenderPipeline;
import com.mojang.blaze3d.platform.PolygonMode;
import com.mojang.blaze3d.shaders.UniformType;
import com.mojang.blaze3d.systems.CommandEncoder; import com.mojang.blaze3d.systems.CommandEncoder;
import com.mojang.blaze3d.systems.GpuDevice; import com.mojang.blaze3d.systems.GpuDevice;
import com.mojang.blaze3d.systems.RenderPass;
import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.VertexFormat; 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.util.BlazeDhVertexFormatUtil;
import com.seibel.distanthorizons.common.render.blaze.wrappers.BlazeVertexFormatBuilder;
import com.seibel.distanthorizons.common.render.blaze.wrappers.RenderPassWrapper;
import com.seibel.distanthorizons.common.render.blaze.wrappers.RenderPipelineBuilderWrapper; import com.seibel.distanthorizons.common.render.blaze.wrappers.RenderPipelineBuilderWrapper;
import com.seibel.distanthorizons.common.render.blaze.wrappers.uniform.BlazeUniformBufferWrapper;
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
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.render.EDhRenderDepth;
import com.seibel.distanthorizons.core.render.renderer.AbstractDebugWireframeRenderer; import com.seibel.distanthorizons.core.render.renderer.AbstractDebugWireframeRenderer;
import com.seibel.distanthorizons.core.util.math.Mat4f; import com.seibel.distanthorizons.core.util.math.DhMat4f;
import com.seibel.distanthorizons.core.util.math.Vec3d; import com.seibel.distanthorizons.core.util.math.DhVec3d;
import com.seibel.distanthorizons.core.util.math.Vec3f; import com.seibel.distanthorizons.core.util.math.DhVec3f;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
import net.minecraft.resources.Identifier; import com.seibel.distanthorizons.core.wrapperInterfaces.render.AbstractDhRenderApiDefinition;
import org.lwjgl.system.MemoryUtil;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.ByteOrder; import java.nio.ByteOrder;
import java.util.OptionalDouble;
import java.util.OptionalInt;
/** /**
* Handles rendering the wireframe particles * Handles rendering the wireframe particles
@@ -64,11 +59,10 @@ public class BlazeDebugWireframeRenderer extends AbstractDebugWireframeRenderer
private static final DhLogger LOGGER = new DhLoggerBuilder().build(); private static final DhLogger LOGGER = new DhLoggerBuilder().build();
private static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class); private static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class);
private static final AbstractDhRenderApiDefinition RENDER_API_DEF = SingletonInjector.INSTANCE.get(AbstractDhRenderApiDefinition.class);
public static BlazeDebugWireframeRenderer INSTANCE = new BlazeDebugWireframeRenderer(); public static BlazeDebugWireframeRenderer INSTANCE = new BlazeDebugWireframeRenderer();
/** A box from 0,0,0 to 1,1,1 */ /** A box from 0,0,0 to 1,1,1 */
private static final float[] BOX_VERTICES = { private static final float[] BOX_VERTICES = {
//region //region
@@ -103,6 +97,7 @@ public class BlazeDebugWireframeRenderer extends AbstractDebugWireframeRenderer
//endregion //endregion
}; };
private static final DhMat4f TRANSFORM_MATRIX = new DhMat4f();
@@ -114,7 +109,7 @@ public class BlazeDebugWireframeRenderer extends AbstractDebugWireframeRenderer
private GpuBuffer boxVertexBuffer; private GpuBuffer boxVertexBuffer;
private GpuBuffer boxIndexBuffer; private GpuBuffer boxIndexBuffer;
private GpuBuffer uniformBuffer; private final BlazeUniformBufferWrapper uniformBufferWrapper = new BlazeUniformBufferWrapper("debugWireframeUniformBlock");
@@ -143,7 +138,14 @@ public class BlazeDebugWireframeRenderer extends AbstractDebugWireframeRenderer
{ {
pipelineBuilder.withFaceCulling(false); pipelineBuilder.withFaceCulling(false);
pipelineBuilder.withDepthWrite(true); pipelineBuilder.withDepthWrite(true);
pipelineBuilder.withDepthTest(RenderPipelineBuilderWrapper.EDhDepthTest.LESS); if (RENDER_API_DEF.getRenderDepth() == EDhRenderDepth.FORWARD_Z)
{
pipelineBuilder.withDepthTest(RenderPipelineBuilderWrapper.EDhDepthTest.LESS);
}
else
{
pipelineBuilder.withDepthTest(RenderPipelineBuilderWrapper.EDhDepthTest.GREATER);
}
pipelineBuilder.withColorWrite(true); pipelineBuilder.withColorWrite(true);
pipelineBuilder.withoutBlend(); pipelineBuilder.withoutBlend();
pipelineBuilder.withPolygonMode(RenderPipelineBuilderWrapper.EDhPolygonMode.WIREFRAME); pipelineBuilder.withPolygonMode(RenderPipelineBuilderWrapper.EDhPolygonMode.WIREFRAME);
@@ -155,7 +157,7 @@ public class BlazeDebugWireframeRenderer extends AbstractDebugWireframeRenderer
pipelineBuilder.withUniformBuffer("uniformBlock"); pipelineBuilder.withUniformBuffer("uniformBlock");
VertexFormat vertexFormat = VertexFormat.builder() VertexFormat vertexFormat = new BlazeVertexFormatBuilder()
.add("vPosition", BlazeDhVertexFormatUtil.FLOAT_XYZ_POS) .add("vPosition", BlazeDhVertexFormatUtil.FLOAT_XYZ_POS)
.build(); .build();
pipelineBuilder.withVertexFormat(vertexFormat); pipelineBuilder.withVertexFormat(vertexFormat);
@@ -171,17 +173,17 @@ public class BlazeDebugWireframeRenderer extends AbstractDebugWireframeRenderer
// box vertices // box vertices
ByteBuffer boxVerticesBuffer = MemoryUtil.memAlloc(BOX_VERTICES.length * Float.BYTES); ByteBuffer boxVerticesBuffer = ByteBuffer.allocateDirect(BOX_VERTICES.length * Float.BYTES);
boxVerticesBuffer.order(ByteOrder.nativeOrder());
boxVerticesBuffer.asFloatBuffer().put(BOX_VERTICES); boxVerticesBuffer.asFloatBuffer().put(BOX_VERTICES);
boxVerticesBuffer.rewind(); boxVerticesBuffer.rewind();
MemoryUtil.memFree(boxVerticesBuffer);
// upload vertex data // upload vertex data
{ {
int usage = GpuBuffer.USAGE_COPY_DST int usage = GpuBuffer.USAGE_COPY_DST
| GpuBuffer.USAGE_VERTEX; | GpuBuffer.USAGE_VERTEX;
int size = BOX_VERTICES.length * Float.BYTES; int size = BOX_VERTICES.length * Float.BYTES;
this.boxVertexBuffer = GPU_DEVICE.createBuffer(() -> "distantHorizons:McDebugWireframeBox", usage, size); this.boxVertexBuffer = GPU_DEVICE.createBuffer(() -> "distantHorizons:DebugWireframeBox", usage, size);
{ {
int length = BOX_VERTICES.length * Float.BYTES; int length = BOX_VERTICES.length * Float.BYTES;
@@ -251,77 +253,56 @@ public class BlazeDebugWireframeRenderer extends AbstractDebugWireframeRenderer
// uniforms // uniforms
{ {
int uniformBufferSize = new Std140SizeCalculator()
.putMat4f() // uTransform
.putVec4() // uColor
.get();
// create data // // create data //
DhVec3d camPos = MC_RENDER.getCameraExactPosition();
DhVec3f camPosFloatThisFrame = new DhVec3f((float) camPos.x, (float) camPos.y, (float) camPos.z);
Vec3d camPos = MC_RENDER.getCameraExactPosition(); DhMat4f boxTransform = DhMat4f.createTranslateMatrix(
Vec3f camPosFloatThisFrame = new Vec3f((float) camPos.x, (float) camPos.y, (float) camPos.z);
Mat4f boxTransform = Mat4f.createTranslateMatrix(
box.minPos.x - camPosFloatThisFrame.x, box.minPos.x - camPosFloatThisFrame.x,
box.minPos.y - camPosFloatThisFrame.y, box.minPos.y - camPosFloatThisFrame.y,
box.minPos.z - camPosFloatThisFrame.z); box.minPos.z - camPosFloatThisFrame.z);
boxTransform.multiply(Mat4f.createScaleMatrix( boxTransform.multiply(DhMat4f.createScaleMatrix(
box.maxPos.x - box.minPos.x, box.maxPos.x - box.minPos.x,
box.maxPos.y - box.minPos.y, box.maxPos.y - box.minPos.y,
box.maxPos.z - box.minPos.z)); box.maxPos.z - box.minPos.z));
Mat4f transformMatrix = this.dhMvmProjMatrixThisFrame.copy(); TRANSFORM_MATRIX.set(this.dhMvmProjMatrixThisFrame);
transformMatrix.multiply(boxTransform); TRANSFORM_MATRIX.multiply(boxTransform);
// upload data // // upload data //
this.uniformBufferWrapper
ByteBuffer buffer = ByteBuffer.allocateDirect(uniformBufferSize); .putMat4f(TRANSFORM_MATRIX) // uTransform
buffer.order(ByteOrder.nativeOrder()); .putVec4f(
buffer = Std140Builder.intoBuffer(buffer)
.putMat4f(transformMatrix.createJomlMatrix()) // uTransform
.putVec4(
box.color.getRed() / 255.0f, box.color.getRed() / 255.0f,
box.color.getGreen() / 255.0f, box.color.getGreen() / 255.0f,
box.color.getBlue() / 255.0f, box.color.getBlue() / 255.0f,
box.color.getAlpha() / 255.0f) // uColor box.color.getAlpha() / 255.0f) // uColor
.get() .finishAndUpload()
; ;
this.uniformBuffer = BlazeUniformUtil.createBuffer("uniformBlock", uniformBufferSize, this.uniformBuffer);
GpuBufferSlice bufferSlice = new GpuBufferSlice(this.uniformBuffer, 0, uniformBufferSize);
commandEncoder.writeToBuffer(bufferSlice, buffer);
} }
// render // // render //
try (RenderPass renderPass = commandEncoder.createRenderPass( try (RenderPassWrapper renderPassWrapper = new RenderPassWrapper(
this::getRenderPassName, this::getRenderPassName,
BlazeDhMetaRenderer.INSTANCE.dhColorTextureWrapper.textureView, BlazeDhMetaRenderer.INSTANCE.dhColorTextureWrapper,
/*optionalClearColorAsInt*/ OptionalInt.empty(), BlazeDhMetaRenderer.INSTANCE.dhDepthTextureWrapper))
BlazeDhMetaRenderer.INSTANCE.dhDepthTextureWrapper.textureView,
/*optionalDepthValueAsDouble*/ OptionalDouble.empty()))
{ {
// Bind instance data // // Bind instance data //
renderPass.setUniform("uniformBlock", this.uniformBuffer); renderPassWrapper.setUniform("uniformBlock", this.uniformBufferWrapper);
renderPass.setPipeline(this.pipeline); renderPassWrapper.setPipeline(this.pipeline);
renderPass.setIndexBuffer(this.boxIndexBuffer, VertexFormat.IndexType.INT); renderPassWrapper.setIndexBuffer(this.boxIndexBuffer);
renderPass.setVertexBuffer(0, this.boxVertexBuffer); renderPassWrapper.setVertexBuffer(this.boxVertexBuffer);
renderPass.drawIndexed( renderPassWrapper.drawIndexed(BOX_OUTLINE_INDICES.length);
/*indexStart*/ 0,
/*firstIndex*/0,
/*indexCount*/BOX_OUTLINE_INDICES.length,
/*instanceCount*/1);
} }
} }
private String getRenderPassName() { return "distantHorizons:McDebugRenderer"; } private String getRenderPassName() { return "distantHorizons:DebugRenderer"; }
//endregion //endregion
@@ -24,17 +24,10 @@ public class BlazeDhGenericObjectRenderer {}
#else #else
import com.mojang.blaze3d.buffers.GpuBuffer;
import com.mojang.blaze3d.buffers.GpuBufferSlice;
import com.mojang.blaze3d.buffers.Std140Builder;
import com.mojang.blaze3d.buffers.Std140SizeCalculator;
import com.mojang.blaze3d.pipeline.BlendFunction; import com.mojang.blaze3d.pipeline.BlendFunction;
import com.mojang.blaze3d.pipeline.RenderPipeline; import com.mojang.blaze3d.pipeline.RenderPipeline;
import com.mojang.blaze3d.platform.PolygonMode;
import com.mojang.blaze3d.shaders.UniformType;
import com.mojang.blaze3d.systems.CommandEncoder; import com.mojang.blaze3d.systems.CommandEncoder;
import com.mojang.blaze3d.systems.GpuDevice; import com.mojang.blaze3d.systems.GpuDevice;
import com.mojang.blaze3d.systems.RenderPass;
import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.VertexFormat; import com.mojang.blaze3d.vertex.VertexFormat;
import com.seibel.distanthorizons.api.enums.rendering.EDhApiBlockMaterial; import com.seibel.distanthorizons.api.enums.rendering.EDhApiBlockMaterial;
@@ -43,41 +36,41 @@ import com.seibel.distanthorizons.api.interfaces.render.IDhApiRenderableBoxGroup
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiBeforeGenericObjectRenderEvent; import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiBeforeGenericObjectRenderEvent;
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiBeforeGenericRenderCleanupEvent; import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiBeforeGenericRenderCleanupEvent;
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiBeforeGenericRenderSetupEvent; import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiBeforeGenericRenderSetupEvent;
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiRenderParam;
import com.seibel.distanthorizons.api.objects.math.DhApiVec3d; import com.seibel.distanthorizons.api.objects.math.DhApiVec3d;
import com.seibel.distanthorizons.api.objects.render.DhApiRenderableBox; import com.seibel.distanthorizons.api.objects.render.DhApiRenderableBox;
import com.seibel.distanthorizons.api.objects.render.DhApiRenderableBoxGroupShading; import com.seibel.distanthorizons.api.objects.render.DhApiRenderableBoxGroupShading;
import com.seibel.distanthorizons.common.render.blaze.objects.BlazeGenericObjectVertexContainer; 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.util.BlazeDhVertexFormatUtil;
import com.seibel.distanthorizons.common.render.blaze.wrappers.BlazeVertexFormatBuilder;
import com.seibel.distanthorizons.common.render.blaze.wrappers.RenderPassWrapper;
import com.seibel.distanthorizons.common.render.blaze.wrappers.RenderPipelineBuilderWrapper; 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.BlazeTextureViewWrapper;
import com.seibel.distanthorizons.common.render.blaze.util.BlazeUniformUtil; import com.seibel.distanthorizons.common.render.blaze.wrappers.uniform.BlazeUniformBufferWrapper;
import com.seibel.distanthorizons.common.wrappers.misc.LightMapWrapper; import com.seibel.distanthorizons.common.wrappers.misc.LightMapWrapper;
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
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.logging.f3.F3Screen;
import com.seibel.distanthorizons.core.render.EDhRenderDepth;
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.RenderThreadTaskHandler;
import com.seibel.distanthorizons.core.render.renderer.GenericRenderObjectFactory; import com.seibel.distanthorizons.core.render.renderer.GenericRenderObjectFactory;
import com.seibel.distanthorizons.core.wrapperInterfaces.render.AbstractDhRenderApiDefinition;
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;
import com.seibel.distanthorizons.core.util.LodUtil; import com.seibel.distanthorizons.core.util.LodUtil;
import com.seibel.distanthorizons.core.util.math.Mat4f; import com.seibel.distanthorizons.core.util.math.DhMat4f;
import com.seibel.distanthorizons.core.util.math.Vec3d; import com.seibel.distanthorizons.core.util.math.DhVec3d;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IProfilerWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IProfilerWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass.IDhGenericRenderer; import com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass.IDhGenericRenderer;
import com.seibel.distanthorizons.coreapi.DependencyInjection.ApiEventInjector; import com.seibel.distanthorizons.coreapi.DependencyInjection.ApiEventInjector;
import com.seibel.distanthorizons.coreapi.ModInfo; import com.seibel.distanthorizons.coreapi.ModInfo;
import net.minecraft.resources.Identifier;
import java.awt.*; import java.awt.*;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.OptionalDouble;
import java.util.OptionalInt;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
/** /**
@@ -91,6 +84,7 @@ public class BlazeDhGenericObjectRenderer implements IDhGenericRenderer
private static final DhLogger LOGGER = new DhLoggerBuilder().build(); private static final DhLogger LOGGER = new DhLoggerBuilder().build();
private static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class); private static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class);
private static final AbstractDhRenderApiDefinition RENDER_API_DEF = SingletonInjector.INSTANCE.get(AbstractDhRenderApiDefinition.class);
private static final GpuDevice GPU_DEVICE = RenderSystem.getDevice(); private static final GpuDevice GPU_DEVICE = RenderSystem.getDevice();
private static final CommandEncoder COMMAND_ENCODER = GPU_DEVICE.createCommandEncoder(); private static final CommandEncoder COMMAND_ENCODER = GPU_DEVICE.createCommandEncoder();
@@ -103,6 +97,10 @@ public class BlazeDhGenericObjectRenderer implements IDhGenericRenderer
*/ */
public static final boolean RENDER_DEBUG_OBJECTS = false; public static final boolean RENDER_DEBUG_OBJECTS = false;
private static final DhApiBeforeGenericObjectRenderEvent.EventParam EVENT_PARAM = new DhApiBeforeGenericObjectRenderEvent.EventParam();
private final ConcurrentHashMap<Long, RenderableBoxGroup> boxGroupById = new ConcurrentHashMap<>(); private final ConcurrentHashMap<Long, RenderableBoxGroup> boxGroupById = new ConcurrentHashMap<>();
@@ -111,7 +109,7 @@ public class BlazeDhGenericObjectRenderer implements IDhGenericRenderer
private RenderPipeline pipeline; private RenderPipeline pipeline;
private GpuBuffer vertUniformBuffer; private final BlazeUniformBufferWrapper vertUniformBufferWrapper = new BlazeUniformBufferWrapper("vertUniformBlock");
@@ -143,7 +141,14 @@ public class BlazeDhGenericObjectRenderer implements IDhGenericRenderer
{ {
pipelineBuilder.withFaceCulling(true); pipelineBuilder.withFaceCulling(true);
pipelineBuilder.withDepthWrite(true); pipelineBuilder.withDepthWrite(true);
pipelineBuilder.withDepthTest(RenderPipelineBuilderWrapper.EDhDepthTest.LESS); if (RENDER_API_DEF.getRenderDepth() == EDhRenderDepth.FORWARD_Z)
{
pipelineBuilder.withDepthTest(RenderPipelineBuilderWrapper.EDhDepthTest.LESS);
}
else
{
pipelineBuilder.withDepthTest(RenderPipelineBuilderWrapper.EDhDepthTest.GREATER);
}
pipelineBuilder.withBlend(BlendFunction.TRANSLUCENT); // TRANSLUCENT = new BlendFunction(SourceFactor.SRC_ALPHA, DestFactor.ONE_MINUS_SRC_ALPHA, SourceFactor.ONE, DestFactor.ONE_MINUS_SRC_ALPHA); 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.withColorWrite(true);
pipelineBuilder.withPolygonMode(RenderPipelineBuilderWrapper.EDhPolygonMode.FILL); pipelineBuilder.withPolygonMode(RenderPipelineBuilderWrapper.EDhPolygonMode.FILL);
@@ -156,7 +161,7 @@ public class BlazeDhGenericObjectRenderer implements IDhGenericRenderer
pipelineBuilder.withUniformBuffer("vertUniformBlock"); pipelineBuilder.withUniformBuffer("vertUniformBlock");
VertexFormat vertexFormat = VertexFormat.builder() VertexFormat vertexFormat = new BlazeVertexFormatBuilder()
.add("vPosition", BlazeDhVertexFormatUtil.FLOAT_XYZ_POS) .add("vPosition", BlazeDhVertexFormatUtil.FLOAT_XYZ_POS)
.add("aColor", BlazeDhVertexFormatUtil.RGBA_UBYTE_COLOR) .add("aColor", BlazeDhVertexFormatUtil.RGBA_UBYTE_COLOR)
.add("aMaterial", BlazeDhVertexFormatUtil.IRIS_MATERIAL) .add("aMaterial", BlazeDhVertexFormatUtil.IRIS_MATERIAL)
@@ -343,9 +348,9 @@ public class BlazeDhGenericObjectRenderer implements IDhGenericRenderer
this.init(); this.init();
ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeGenericRenderSetupEvent.class, renderEventParam); ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeGenericRenderSetupEvent.class, renderEventParam.apiCopy);
Vec3d camPos = MC_RENDER.getCameraExactPosition(); DhVec3d camPos = MC_RENDER.getCameraExactPosition();
//#endregion //#endregion
@@ -389,7 +394,8 @@ public class BlazeDhGenericObjectRenderer implements IDhGenericRenderer
} }
// allow API users to cancel this object's rendering // allow API users to cancel this object's rendering
boolean cancelRendering = ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeGenericObjectRenderEvent.class, new DhApiBeforeGenericObjectRenderEvent.EventParam(renderEventParam, boxGroup)); EVENT_PARAM.update(renderEventParam, boxGroup);
boolean cancelRendering = ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeGenericObjectRenderEvent.class, EVENT_PARAM);
if (cancelRendering) if (cancelRendering)
{ {
continue; continue;
@@ -415,61 +421,37 @@ public class BlazeDhGenericObjectRenderer implements IDhGenericRenderer
// uniforms // uniforms
{ {
int uniformBufferSize = new Std140SizeCalculator()
.putIVec3() // uOffsetChunk
.putVec3() // uOffsetSubChunk
.putIVec3() // uCameraPosChunk
.putVec3() // uCameraPosSubChunk
.putVec3() // aTranslateChunk
.putVec3() // aTranslateSubChunk
.putMat4f() // uProjectionMvm
.putInt() // uSkyLight
.putInt() // uBlockLight
.putFloat() // uNorthShading
.putFloat() // uSouthShading
.putFloat() // uEastShading
.putFloat() // uWestShading
.putFloat() // uTopShading
.putFloat() // uBottomShading
.get();
// create data // // create data //
Mat4f projectionMvmMatrix = new Mat4f(renderEventParam.dhProjectionMatrix); DhMat4f projectionMvmMatrix = new DhMat4f(renderEventParam.dhProjectionMatrix);
projectionMvmMatrix.multiply(renderEventParam.dhModelViewMatrix); projectionMvmMatrix.multiply(renderEventParam.dhModelViewMatrix);
// upload data // // upload data //
ByteBuffer buffer = ByteBuffer.allocateDirect(uniformBufferSize); this.vertUniformBufferWrapper
buffer.order(ByteOrder.nativeOrder()); .putVec3i(
buffer = Std140Builder.intoBuffer(buffer)
.putIVec3(
LodUtil.getChunkPosFromDouble(boxGroup.getOriginBlockPos().x), LodUtil.getChunkPosFromDouble(boxGroup.getOriginBlockPos().x),
LodUtil.getChunkPosFromDouble(boxGroup.getOriginBlockPos().y), LodUtil.getChunkPosFromDouble(boxGroup.getOriginBlockPos().y),
LodUtil.getChunkPosFromDouble(boxGroup.getOriginBlockPos().z) LodUtil.getChunkPosFromDouble(boxGroup.getOriginBlockPos().z)
) // uOffsetChunk ) // uOffsetChunk
.putVec3( .putVec3f(
LodUtil.getSubChunkPosFromDouble(boxGroup.getOriginBlockPos().x), LodUtil.getSubChunkPosFromDouble(boxGroup.getOriginBlockPos().x),
LodUtil.getSubChunkPosFromDouble(boxGroup.getOriginBlockPos().y), LodUtil.getSubChunkPosFromDouble(boxGroup.getOriginBlockPos().y),
LodUtil.getSubChunkPosFromDouble(boxGroup.getOriginBlockPos().z) LodUtil.getSubChunkPosFromDouble(boxGroup.getOriginBlockPos().z)
) // uOffsetSubChunk ) // uOffsetSubChunk
.putIVec3( .putVec3i(
LodUtil.getChunkPosFromDouble(camPos.x), LodUtil.getChunkPosFromDouble(camPos.x),
LodUtil.getChunkPosFromDouble(camPos.y), LodUtil.getChunkPosFromDouble(camPos.y),
LodUtil.getChunkPosFromDouble(camPos.z) LodUtil.getChunkPosFromDouble(camPos.z)
) // uCameraPosChunk ) // uCameraPosChunk
.putVec3( .putVec3f(
LodUtil.getSubChunkPosFromDouble(camPos.x), LodUtil.getSubChunkPosFromDouble(camPos.x),
LodUtil.getSubChunkPosFromDouble(camPos.y), LodUtil.getSubChunkPosFromDouble(camPos.y),
LodUtil.getSubChunkPosFromDouble(camPos.z) LodUtil.getSubChunkPosFromDouble(camPos.z)
) // uCameraPosSubChunk ) // uCameraPosSubChunk
.putMat4f(projectionMvmMatrix.createJomlMatrix()) // uProjectionMvm .putMat4f(projectionMvmMatrix) // uProjectionMvm
.putInt(boxGroup.getSkyLight()) // uSkyLight .putInt(boxGroup.getSkyLight()) // uSkyLight
.putInt(boxGroup.getBlockLight()) // uBlockLight .putInt(boxGroup.getBlockLight()) // uBlockLight
@@ -480,13 +462,8 @@ public class BlazeDhGenericObjectRenderer implements IDhGenericRenderer
.putFloat(shading.top) .putFloat(shading.top)
.putFloat(shading.bottom) .putFloat(shading.bottom)
.get() .finishAndUpload()
; ;
this.vertUniformBuffer = BlazeUniformUtil.createBuffer("vertUniformBlock", uniformBufferSize, this.vertUniformBuffer);
GpuBufferSlice bufferSlice = new GpuBufferSlice(this.vertUniformBuffer, 0, uniformBufferSize);
COMMAND_ENCODER.writeToBuffer(bufferSlice, buffer);
} }
@@ -520,7 +497,7 @@ public class BlazeDhGenericObjectRenderer implements IDhGenericRenderer
//endregion //endregion
} }
} }
private String getRenderPassName() { return "distantHorizons:McGenericObjectRenderer"; } private String getRenderPassName() { return "distantHorizons:GenericObjectRenderer"; }
//endregion //endregion
@@ -536,12 +513,10 @@ public class BlazeDhGenericObjectRenderer implements IDhGenericRenderer
RenderableBoxGroup boxGroup, RenderableBoxGroup boxGroup,
IProfilerWrapper profiler) IProfilerWrapper profiler)
{ {
try (RenderPass renderPass = COMMAND_ENCODER.createRenderPass( try (RenderPassWrapper renderPassWrapper = new RenderPassWrapper(
this::getRenderPassName, this::getRenderPassName,
BlazeDhMetaRenderer.INSTANCE.dhColorTextureWrapper.textureView, BlazeDhMetaRenderer.INSTANCE.dhColorTextureWrapper,
/*optionalClearColorAsInt*/ OptionalInt.empty(), BlazeDhMetaRenderer.INSTANCE.dhDepthTextureWrapper))
BlazeDhMetaRenderer.INSTANCE.dhDepthTextureWrapper.textureView,
/*optionalDepthValueAsDouble*/ OptionalDouble.empty()))
{ {
// update instance data // // update instance data //
@@ -550,30 +525,26 @@ public class BlazeDhGenericObjectRenderer implements IDhGenericRenderer
LightMapWrapper lightMapWrapper = (LightMapWrapper) renderEventParam.lightmap; LightMapWrapper lightMapWrapper = (LightMapWrapper) renderEventParam.lightmap;
BlazeTextureViewWrapper lightmapTextureViewWrapper = lightMapWrapper.getTextureViewWrapper(); BlazeTextureViewWrapper lightmapTextureViewWrapper = lightMapWrapper.getTextureViewWrapper();
renderPass.bindTexture("uLightMap", lightmapTextureViewWrapper.textureView, lightmapTextureViewWrapper.textureSampler); renderPassWrapper.bindTexture("uLightMap", lightmapTextureViewWrapper);
// Bind instance data // // Bind instance data //
renderPass.setUniform("vertUniformBlock", this.vertUniformBuffer); renderPassWrapper.setUniform("vertUniformBlock", this.vertUniformBufferWrapper);
// set pipeline // set pipeline
renderPass.setPipeline(this.pipeline); renderPassWrapper.setPipeline(this.pipeline);
renderPass.setIndexBuffer(container.indexGpuBuffer, VertexFormat.IndexType.INT); renderPassWrapper.setIndexBuffer(container.indexGpuBuffer);
renderPass.setVertexBuffer(0, container.vboGpuBuffer); renderPassWrapper.setVertexBuffer(container.vboGpuBuffer);
// Draw instanced // Draw instanced
if (container.uploadedBoxCount > 0) if (container.uploadedBoxCount > 0)
{ {
renderPass.drawIndexed( // 36 = 6 faces * 6 verticies per face
/*indexStart*/ 0, renderPassWrapper.drawIndexed(container.uploadedBoxCount * 36);
/*firstIndex*/0,
/*indexCount*/container.uploadedBoxCount * 36, // 36 = 6 faces * 6 verticies per face
/*instanceCount*/1);
} }
} }
} }
@@ -627,9 +598,9 @@ public class BlazeDhGenericObjectRenderer implements IDhGenericRenderer
// close is called outside the render thread and buffer closing must be done on the render thread // close is called outside the render thread and buffer closing must be done on the render thread
RenderThreadTaskHandler.INSTANCE.queueRunningOnRenderThread("Generic Obj Cleanup", () -> RenderThreadTaskHandler.INSTANCE.queueRunningOnRenderThread("Generic Obj Cleanup", () ->
{ {
if (this.vertUniformBuffer != null) if (this.vertUniformBufferWrapper != null)
{ {
this.vertUniformBuffer.close(); this.vertUniformBufferWrapper.close();
} }
}); });
} }
@@ -13,6 +13,7 @@ import com.seibel.distanthorizons.common.render.blaze.wrappers.texture.BlazeText
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftRenderWrapper; import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftRenderWrapper;
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
import com.seibel.distanthorizons.core.render.RenderParams; import com.seibel.distanthorizons.core.render.RenderParams;
import com.seibel.distanthorizons.core.wrapperInterfaces.render.AbstractDhRenderApiDefinition;
import com.seibel.distanthorizons.coreapi.util.ColorUtil; import com.seibel.distanthorizons.coreapi.util.ColorUtil;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass.IDhMetaRenderer; import com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass.IDhMetaRenderer;
@@ -29,6 +30,7 @@ public class BlazeDhMetaRenderer implements IDhMetaRenderer
private BlazeDhApplyRenderer applyRenderer; private BlazeDhApplyRenderer applyRenderer;
private final float clearDepth;
public final BlazeTextureWrapper dhDepthTextureWrapper = BlazeTextureWrapper.createDepth("DhDepthTexture"); public final BlazeTextureWrapper dhDepthTextureWrapper = BlazeTextureWrapper.createDepth("DhDepthTexture");
public final BlazeTextureWrapper dhColorTextureWrapper = BlazeTextureWrapper.createColor("DhColorTexture"); public final BlazeTextureWrapper dhColorTextureWrapper = BlazeTextureWrapper.createColor("DhColorTexture");
@@ -42,6 +44,9 @@ public class BlazeDhMetaRenderer implements IDhMetaRenderer
private BlazeDhMetaRenderer() private BlazeDhMetaRenderer()
{ {
AbstractDhRenderApiDefinition renderApiDefinition = SingletonInjector.INSTANCE.get(AbstractDhRenderApiDefinition.class);
this.clearDepth = renderApiDefinition.getRenderDepth().farDepth;
this.applyRenderer = new BlazeDhApplyRenderer( this.applyRenderer = new BlazeDhApplyRenderer(
"dh_apply_to_mc", "dh_apply_to_mc",
null, null,
@@ -103,7 +108,7 @@ public class BlazeDhMetaRenderer implements IDhMetaRenderer
@Override @Override
public void clearDhDepthAndColorTextures(RenderParams renderParams) public void clearDhDepthAndColorTextures(RenderParams renderParams)
{ {
this.dhDepthTextureWrapper.clearDepth(1.0f); this.dhDepthTextureWrapper.clearDepth(this.clearDepth);
Color color = MC_RENDER.getSkyColor(); Color color = MC_RENDER.getSkyColor();
this.dhColorTextureWrapper.clearColor(ColorUtil.toColorInt(color)); this.dhColorTextureWrapper.clearColor(ColorUtil.toColorInt(color));
@@ -112,5 +117,6 @@ public class BlazeDhMetaRenderer implements IDhMetaRenderer
//endregion //endregion
} }
#endif #endif
@@ -5,6 +5,7 @@ public class BlazeDhRenderApiDefinition {}
#else #else
import com.seibel.distanthorizons.api.enums.config.EDhApiRenderingApi;
import com.seibel.distanthorizons.common.render.blaze.objects.BlazeGenericObjectVertexContainer; import com.seibel.distanthorizons.common.render.blaze.objects.BlazeGenericObjectVertexContainer;
import com.seibel.distanthorizons.common.render.blaze.postProcessing.BlazeDhFarFadeRenderer; import com.seibel.distanthorizons.common.render.blaze.postProcessing.BlazeDhFarFadeRenderer;
import com.seibel.distanthorizons.common.render.blaze.postProcessing.BlazeDhFogRenderer; import com.seibel.distanthorizons.common.render.blaze.postProcessing.BlazeDhFogRenderer;
@@ -13,6 +14,8 @@ import com.seibel.distanthorizons.common.render.blaze.postProcessing.BlazeVanill
import com.seibel.distanthorizons.common.render.blaze.test.BlazeDhTestTriangleRenderer; import com.seibel.distanthorizons.common.render.blaze.test.BlazeDhTestTriangleRenderer;
import com.seibel.distanthorizons.common.render.blaze.wrappers.buffer.BlazeVertexBufferWrapper; import com.seibel.distanthorizons.common.render.blaze.wrappers.buffer.BlazeVertexBufferWrapper;
import com.seibel.distanthorizons.common.render.blaze.wrappers.uniform.BlazeLodUniformBufferWrapper; import com.seibel.distanthorizons.common.render.blaze.wrappers.uniform.BlazeLodUniformBufferWrapper;
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftRenderWrapper;
import com.seibel.distanthorizons.core.render.EDhRenderDepth;
import com.seibel.distanthorizons.core.render.renderer.AbstractDebugWireframeRenderer; import com.seibel.distanthorizons.core.render.renderer.AbstractDebugWireframeRenderer;
import com.seibel.distanthorizons.core.wrapperInterfaces.render.AbstractDhRenderApiDefinition; import com.seibel.distanthorizons.core.wrapperInterfaces.render.AbstractDhRenderApiDefinition;
import com.seibel.distanthorizons.core.wrapperInterfaces.render.objects.IDhGenericObjectVertexBufferContainer; import com.seibel.distanthorizons.core.wrapperInterfaces.render.objects.IDhGenericObjectVertexBufferContainer;
@@ -20,6 +23,10 @@ import com.seibel.distanthorizons.core.wrapperInterfaces.render.objects.ILodCont
import com.seibel.distanthorizons.core.wrapperInterfaces.render.objects.IVertexBufferWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.render.objects.IVertexBufferWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass.*; import com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass.*;
#if MC_VER <= MC_26_1_2
#else
#endif
public class BlazeDhRenderApiDefinition extends AbstractDhRenderApiDefinition public class BlazeDhRenderApiDefinition extends AbstractDhRenderApiDefinition
{ {
//=========// //=========//
@@ -27,7 +34,43 @@ public class BlazeDhRenderApiDefinition extends AbstractDhRenderApiDefinition
//=========// //=========//
//region //region
public String getApiName() { return "Blaze3D"; } private final String engineName;
public String getEngineName() { return this.engineName; }
public EDhRenderDepth getRenderDepth()
{
#if MC_VER <= MC_26_1_2
return EDhRenderDepth.FORWARD_Z;
#else
return EDhRenderDepth.REVERSE_Z;
#endif
}
private final EDhApiRenderingApi renderApi;
public EDhApiRenderingApi getRenderApi() { return renderApi; }
public boolean isNativeRenderer() { return false; }
//endregion
//=============//
// constructor //
//=============//
//region
public BlazeDhRenderApiDefinition()
{
#if MC_VER <= MC_26_1_2
renderApi = EDhApiRenderingApi.OPEN_GL;
#else
// Blaze always uses the same rendering API as Minecraft
this.renderApi = MinecraftRenderWrapper.INSTANCE.getMcRenderingApi();
#endif
this.engineName = "Blaze3D: " + this.getRenderApi();
}
//endregion //endregion
@@ -5,68 +5,66 @@ public class BlazeDhTerrainRenderer {}
#else #else
import com.mojang.blaze3d.buffers.GpuBuffer;
import com.mojang.blaze3d.buffers.GpuBufferSlice;
import com.mojang.blaze3d.buffers.Std140Builder;
import com.mojang.blaze3d.buffers.Std140SizeCalculator;
import com.mojang.blaze3d.pipeline.BlendFunction; import com.mojang.blaze3d.pipeline.BlendFunction;
import com.mojang.blaze3d.pipeline.RenderPipeline; import com.mojang.blaze3d.pipeline.RenderPipeline;
import com.mojang.blaze3d.platform.PolygonMode;
import com.mojang.blaze3d.shaders.UniformType;
import com.mojang.blaze3d.systems.CommandEncoder; import com.mojang.blaze3d.systems.CommandEncoder;
import com.mojang.blaze3d.systems.GpuDevice; import com.mojang.blaze3d.systems.GpuDevice;
import com.mojang.blaze3d.systems.RenderPass;
import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.VertexFormat; import com.mojang.blaze3d.vertex.VertexFormat;
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiBeforeBufferRenderEvent; import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiBeforeBufferRenderEvent;
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiBeforeRenderPassEvent; import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiBeforeRenderPassEvent;
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiRenderParam;
import com.seibel.distanthorizons.common.render.blaze.util.BlazeDhVertexFormatUtil; 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.BlazeVertexFormatBuilder;
import com.seibel.distanthorizons.common.render.blaze.wrappers.RenderPassWrapper;
import com.seibel.distanthorizons.common.render.blaze.wrappers.RenderPipelineBuilderWrapper; 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.BlazeTextureViewWrapper;
import com.seibel.distanthorizons.common.render.blaze.wrappers.uniform.BlazeLodUniformBufferWrapper; 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.render.blaze.wrappers.buffer.BlazeVertexBufferWrapper;
import com.seibel.distanthorizons.common.render.blaze.wrappers.uniform.BlazeUniformBufferWrapper;
import com.seibel.distanthorizons.common.wrappers.misc.LightMapWrapper; import com.seibel.distanthorizons.common.wrappers.misc.LightMapWrapper;
import com.seibel.distanthorizons.core.config.Config; import com.seibel.distanthorizons.core.config.Config;
import com.seibel.distanthorizons.core.dataObjects.render.bufferBuilding.LodBufferContainer; import com.seibel.distanthorizons.core.dataObjects.render.bufferBuilding.LodBufferContainer;
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
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.pos.DhSectionPos; import com.seibel.distanthorizons.core.pos.DhSectionPos;
import com.seibel.distanthorizons.core.render.EDhRenderDepth;
import com.seibel.distanthorizons.core.render.RenderParams; import com.seibel.distanthorizons.core.render.RenderParams;
import com.seibel.distanthorizons.core.util.RenderUtil; import com.seibel.distanthorizons.core.util.RenderUtil;
import com.seibel.distanthorizons.core.util.math.Mat4f; import com.seibel.distanthorizons.core.util.math.DhMat4f;
import com.seibel.distanthorizons.core.util.math.Vec3d; import com.seibel.distanthorizons.core.util.math.DhVec3d;
import com.seibel.distanthorizons.core.util.math.Vec3f; import com.seibel.distanthorizons.core.util.math.DhVec3f;
import com.seibel.distanthorizons.core.util.objects.SortedArraySet; import com.seibel.distanthorizons.core.util.objects.SortedArraySet;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IProfilerWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IProfilerWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.render.AbstractDhRenderApiDefinition;
import com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass.IDhTerrainRenderer; import com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass.IDhTerrainRenderer;
import com.seibel.distanthorizons.core.wrapperInterfaces.render.objects.IVertexBufferWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.render.objects.IVertexBufferWrapper;
import com.seibel.distanthorizons.coreapi.DependencyInjection.ApiEventInjector; import com.seibel.distanthorizons.coreapi.DependencyInjection.ApiEventInjector;
import net.minecraft.resources.Identifier;
import org.lwjgl.system.MemoryUtil;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.OptionalDouble;
import java.util.OptionalInt;
/** Renders rendering DH's LOD terrain. */ /** Renders rendering DH's LOD terrain. */
public class BlazeDhTerrainRenderer implements IDhTerrainRenderer public class BlazeDhTerrainRenderer implements IDhTerrainRenderer
{ {
public static final DhLogger LOGGER = new DhLoggerBuilder().build(); public static final DhLogger LOGGER = new DhLoggerBuilder().build();
private static final AbstractDhRenderApiDefinition RENDER_API_DEF = SingletonInjector.INSTANCE.get(AbstractDhRenderApiDefinition.class);
private static final GpuDevice GPU_DEVICE = RenderSystem.getDevice(); private static final GpuDevice GPU_DEVICE = RenderSystem.getDevice();
private static final CommandEncoder COMMAND_ENCODER = GPU_DEVICE.createCommandEncoder(); private static final CommandEncoder COMMAND_ENCODER = GPU_DEVICE.createCommandEncoder();
public static final BlazeDhTerrainRenderer INSTANCE = new BlazeDhTerrainRenderer(); public static final BlazeDhTerrainRenderer INSTANCE = new BlazeDhTerrainRenderer();
private static final DhVec3f MODEL_POS = new DhVec3f();
/** single event object used to reduce GC pressure */
private static final DhApiBeforeBufferRenderEvent.EventParam BEFORE_BUFFER_RENDER_EVENT_PARAM = new DhApiBeforeBufferRenderEvent.EventParam();
private RenderPipeline opaquePipeline; private RenderPipeline opaquePipeline;
private RenderPipeline transparentPipeline; private RenderPipeline transparentPipeline;
private boolean init = false; private boolean init = false;
private GpuBuffer fragUniformBuffer; private final BlazeUniformBufferWrapper fragUniformBufferWrapper = new BlazeUniformBufferWrapper("fragUniformBlock");
private GpuBuffer vertSharedUniformBuffer; private final BlazeUniformBufferWrapper vertSharedUniformBufferWrapper = new BlazeUniformBufferWrapper("vertSharedUniformBlock");
@@ -86,14 +84,28 @@ public class BlazeDhTerrainRenderer implements IDhTerrainRenderer
RenderPipelineBuilderWrapper pipelineBuilder = new RenderPipelineBuilderWrapper(); RenderPipelineBuilderWrapper opaquePipelineBuilder = new RenderPipelineBuilderWrapper();
RenderPipelineBuilderWrapper translucentPipelineBuilder = new RenderPipelineBuilderWrapper();
// apply shared options to both pipelines
for (int i = 0; i < 2; i++)
{ {
RenderPipelineBuilderWrapper pipelineBuilder = (i == 0)
? opaquePipelineBuilder
: translucentPipelineBuilder;
pipelineBuilder.withFaceCulling(true); pipelineBuilder.withFaceCulling(true);
pipelineBuilder.withDepthWrite(true); pipelineBuilder.withDepthWrite(true);
pipelineBuilder.withDepthTest(RenderPipelineBuilderWrapper.EDhDepthTest.LESS); if (RENDER_API_DEF.getRenderDepth() == EDhRenderDepth.FORWARD_Z)
{
pipelineBuilder.withDepthTest(RenderPipelineBuilderWrapper.EDhDepthTest.LESS);
}
else
{
pipelineBuilder.withDepthTest(RenderPipelineBuilderWrapper.EDhDepthTest.GREATER);
}
pipelineBuilder.withColorWrite(true); pipelineBuilder.withColorWrite(true);
pipelineBuilder.withPolygonMode(RenderPipelineBuilderWrapper.EDhPolygonMode.FILL); pipelineBuilder.withPolygonMode(RenderPipelineBuilderWrapper.EDhPolygonMode.FILL);
pipelineBuilder.withName("terrain");
pipelineBuilder.withSampler("uLightMap"); pipelineBuilder.withSampler("uLightMap");
@@ -104,7 +116,7 @@ public class BlazeDhTerrainRenderer implements IDhTerrainRenderer
pipelineBuilder.withUniformBuffer("vertSharedUniformBlock"); pipelineBuilder.withUniformBuffer("vertSharedUniformBlock");
pipelineBuilder.withUniformBuffer("fragUniformBlock"); pipelineBuilder.withUniformBuffer("fragUniformBlock");
VertexFormat vertexFormat = VertexFormat.builder() VertexFormat vertexFormat = new BlazeVertexFormatBuilder()
.add("vPosition", BlazeDhVertexFormatUtil.SHORT_XYZ_POS) .add("vPosition", BlazeDhVertexFormatUtil.SHORT_XYZ_POS)
.add("meta", BlazeDhVertexFormatUtil.META) .add("meta", BlazeDhVertexFormatUtil.META)
.add("vColor", BlazeDhVertexFormatUtil.RGBA_UBYTE_COLOR) .add("vColor", BlazeDhVertexFormatUtil.RGBA_UBYTE_COLOR)
@@ -120,15 +132,17 @@ public class BlazeDhTerrainRenderer implements IDhTerrainRenderer
// opaque // opaque
{ {
pipelineBuilder.withoutBlend(); opaquePipelineBuilder.withName("opaque_terrain");
this.opaquePipeline = pipelineBuilder.build(); opaquePipelineBuilder.withoutBlend();
this.opaquePipeline = opaquePipelineBuilder.build();
} }
// transparent // transparent
{ {
translucentPipelineBuilder.withName("transparent_terrain");
// TRANSLUCENT = new BlendFunction(SourceFactor.SRC_ALPHA, DestFactor.ONE_MINUS_SRC_ALPHA, SourceFactor.ONE, DestFactor.ONE_MINUS_SRC_ALPHA); // TRANSLUCENT = new BlendFunction(SourceFactor.SRC_ALPHA, DestFactor.ONE_MINUS_SRC_ALPHA, SourceFactor.ONE, DestFactor.ONE_MINUS_SRC_ALPHA);
pipelineBuilder.withBlend(BlendFunction.TRANSLUCENT); translucentPipelineBuilder.withBlend(BlendFunction.TRANSLUCENT);
this.transparentPipeline = pipelineBuilder.build(); this.transparentPipeline = translucentPipelineBuilder.build();
} }
this.init = true; this.init = true;
@@ -161,13 +175,13 @@ public class BlazeDhTerrainRenderer implements IDhTerrainRenderer
for (int lodIndex = 0; lodIndex < bufferContainers.size(); lodIndex++) for (int lodIndex = 0; lodIndex < bufferContainers.size(); lodIndex++)
{ {
LodBufferContainer bufferContainer = bufferContainers.get(lodIndex); LodBufferContainer bufferContainer = bufferContainers.get(lodIndex);
bufferContainer.uniformContainer.tryUpload(); bufferContainer.uniformContainer.tryUpload(bufferContainer);
} }
} }
profiler.popPush("vert share uniforms"); profiler.popPush("vert share uniforms");
{ {
Mat4f combinedMatrix = new Mat4f(renderEventParam.dhProjectionMatrix); DhMat4f combinedMatrix = new DhMat4f(renderEventParam.dhProjectionMatrix);
combinedMatrix.multiply(renderEventParam.dhModelViewMatrix); combinedMatrix.multiply(renderEventParam.dhModelViewMatrix);
float earthCurveRatio = Config.Client.Advanced.Graphics.Experimental.earthCurveRatio.get(); float earthCurveRatio = Config.Client.Advanced.Graphics.Experimental.earthCurveRatio.get();
@@ -184,53 +198,25 @@ public class BlazeDhTerrainRenderer implements IDhTerrainRenderer
// upload data // // upload data //
int uniformBufferSize = new Std140SizeCalculator() int i = Config.Client.Advanced.Debugging.enableWhiteWorld.get() ? 1 : 0;
.putInt() // uIsWhiteWorld
.putFloat() // uWorldYOffset
.putFloat() // uMircoOffset
.putFloat() // uEarthRadius
.putVec3() // uCameraPos
.putMat4f() // uCombinedMatrix
.get();
ByteBuffer buffer = MemoryUtil.memAlloc(uniformBufferSize); this.vertSharedUniformBufferWrapper
buffer.order(ByteOrder.nativeOrder()); .putInt(i) // uIsWhiteWorld
Std140Builder.intoBuffer(buffer)
.putInt(0) // uIsWhiteWorld
.putFloat((float) renderEventParam.worldYOffset) // uWorldYOffset .putFloat((float) renderEventParam.worldYOffset) // uWorldYOffset
.putFloat(0.01f) // uMircoOffset // 0.01 block offset .putFloat(0.01f) // uMircoOffset // 0.01 block offset
.putFloat(earthCurveRatio) // uEarthRadius .putFloat(earthCurveRatio) // uEarthRadius
.putVec3( .putVec3f(
(float) renderEventParam.exactCameraPosition.x, (float) renderEventParam.exactCameraPosition.x,
(float) renderEventParam.exactCameraPosition.y, (float) renderEventParam.exactCameraPosition.y,
(float) renderEventParam.exactCameraPosition.z) // uCameraPos (float) renderEventParam.exactCameraPosition.z) // uCameraPos
.putMat4f(combinedMatrix.createJomlMatrix()) // uCombinedMatrix .putMat4f(combinedMatrix) // uCombinedMatrix
.get(); .finishAndUpload();
this.vertSharedUniformBuffer = BlazeUniformUtil.createBuffer("vertSharedUniformBlock", uniformBufferSize, this.vertSharedUniformBuffer);
GpuBufferSlice bufferSlice = new GpuBufferSlice(this.vertSharedUniformBuffer, 0, uniformBufferSize);
COMMAND_ENCODER.writeToBuffer(bufferSlice, buffer);
MemoryUtil.memFree(buffer);
} }
profiler.popPush("set frag uniforms"); profiler.popPush("set frag uniforms");
{ {
int uniformBufferSize = new Std140SizeCalculator()
.putFloat() // uClipDistance
.putFloat() // uNoiseIntensity
.putInt() // uNoiseSteps
.putInt() // uNoiseDropoff
.putInt() // uDitherDhRendering
.putInt() // uNoiseEnabled
.get();
// create data // // create data //
float dhNearClipDistance = RenderUtil.getNearClipPlaneInBlocks(); float dhNearClipDistance = RenderUtil.getNearClipPlaneInBlocks();
@@ -242,24 +228,15 @@ public class BlazeDhTerrainRenderer implements IDhTerrainRenderer
// upload data // // upload data //
this.fragUniformBufferWrapper
ByteBuffer buffer = MemoryUtil.memAlloc(uniformBufferSize);
buffer.order(ByteOrder.nativeOrder());
buffer = Std140Builder.intoBuffer(buffer)
.putFloat(dhNearClipDistance) // uClipDistance .putFloat(dhNearClipDistance) // uClipDistance
.putFloat(Config.Client.Advanced.Graphics.NoiseTexture.noiseIntensity.get()) // uNoiseIntensity .putFloat(Config.Client.Advanced.Graphics.NoiseTexture.noiseIntensity.get()) // uNoiseIntensity
.putInt(Config.Client.Advanced.Graphics.NoiseTexture.noiseSteps.get()) // uNoiseSteps .putInt(Config.Client.Advanced.Graphics.NoiseTexture.noiseSteps.get()) // uNoiseSteps
.putInt(Config.Client.Advanced.Graphics.NoiseTexture.noiseDropoff.get()) // uNoiseDropoff .putInt(Config.Client.Advanced.Graphics.NoiseTexture.noiseDropoff.get()) // uNoiseDropoff
.putInt(Config.Client.Advanced.Graphics.Quality.ditherDhFade.get() ? 1 : 0) // uDitherDhRendering .putInt(Config.Client.Advanced.Graphics.Quality.ditherDhFade.get() ? 1 : 0) // uDitherDhRendering
.putInt(Config.Client.Advanced.Graphics.NoiseTexture.enableNoiseTexture.get() ? 1 : 0) // uNoiseEnabled .putInt(Config.Client.Advanced.Graphics.NoiseTexture.enableNoiseTexture.get() ? 1 : 0) // uNoiseEnabled
.get() .finishAndUpload()
; ;
this.fragUniformBuffer = BlazeUniformUtil.createBuffer("fragUniformBlock", uniformBufferSize, this.fragUniformBuffer);
GpuBufferSlice bufferSlice = new GpuBufferSlice(this.fragUniformBuffer, 0, uniformBufferSize);
COMMAND_ENCODER.writeToBuffer(bufferSlice, buffer);
MemoryUtil.memFree(buffer);
} }
@@ -268,27 +245,25 @@ public class BlazeDhTerrainRenderer implements IDhTerrainRenderer
{ {
profiler.popPush("rendering"); profiler.popPush("rendering");
ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeRenderPassEvent.class, renderEventParam); ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeRenderPassEvent.class, renderEventParam.apiCopy);
// create a render pass // create a render pass
try (RenderPass renderPass = COMMAND_ENCODER.createRenderPass( try (RenderPassWrapper renderPassWrapper = new RenderPassWrapper(
this::getRenderPassName, this::getRenderPassName,
BlazeDhMetaRenderer.INSTANCE.dhColorTextureWrapper.textureView, BlazeDhMetaRenderer.INSTANCE.dhColorTextureWrapper,
/*optionalClearColorAsInt*/ OptionalInt.empty(), BlazeDhMetaRenderer.INSTANCE.dhDepthTextureWrapper)
BlazeDhMetaRenderer.INSTANCE.dhDepthTextureWrapper.textureView,
/*optionalDepthValueAsDouble*/ OptionalDouble.empty())
) )
{ {
LightMapWrapper lightMapWrapper = (LightMapWrapper) renderEventParam.lightmap; LightMapWrapper lightMapWrapper = (LightMapWrapper) renderEventParam.lightmap;
BlazeTextureViewWrapper lightmapTextureViewWrapper = lightMapWrapper.getTextureViewWrapper(); BlazeTextureViewWrapper lightmapTextureViewWrapper = lightMapWrapper.getTextureViewWrapper();
renderPass.bindTexture("uLightMap", lightmapTextureViewWrapper.textureView, lightmapTextureViewWrapper.textureSampler); renderPassWrapper.bindTexture("uLightMap", lightmapTextureViewWrapper);
// set pipeline // set pipeline
renderPass.setPipeline(opaquePass ? this.opaquePipeline : this.transparentPipeline); renderPassWrapper.setPipeline(opaquePass ? this.opaquePipeline : this.transparentPipeline);
// shared uniforms // shared uniforms
renderPass.setUniform("fragUniformBlock", this.fragUniformBuffer); renderPassWrapper.setUniform("fragUniformBlock", this.fragUniformBufferWrapper);
renderPass.setUniform("vertSharedUniformBlock", this.vertSharedUniformBuffer); renderPassWrapper.setUniform("vertSharedUniformBlock", this.vertSharedUniformBufferWrapper);
@@ -312,7 +287,7 @@ public class BlazeDhTerrainRenderer implements IDhTerrainRenderer
} }
} }
renderPass.setUniform("vertUniqueUniformBlock", uniformWrapper.gpuBuffer); renderPassWrapper.setUniform("vertUniqueUniformBlock", uniformWrapper);
@@ -329,24 +304,21 @@ public class BlazeDhTerrainRenderer implements IDhTerrainRenderer
// fire render event // fire render event
{ {
Vec3d camPos = renderEventParam.exactCameraPosition; DhVec3d camPos = renderEventParam.exactCameraPosition;
Vec3f modelPos = new Vec3f( MODEL_POS.set(
(float) (bufferContainer.minCornerBlockPos.getX() - camPos.x), (float) (bufferContainer.minCornerBlockPos.getX() - camPos.x),
(float) (bufferContainer.minCornerBlockPos.getY() - camPos.y), (float) (bufferContainer.minCornerBlockPos.getY() - camPos.y),
(float) (bufferContainer.minCornerBlockPos.getZ() - camPos.z)); (float) (bufferContainer.minCornerBlockPos.getZ() - camPos.z));
ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeBufferRenderEvent.class, new DhApiBeforeBufferRenderEvent.EventParam(renderEventParam, modelPos)); BEFORE_BUFFER_RENDER_EVENT_PARAM.update(renderEventParam, MODEL_POS);
ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeBufferRenderEvent.class, BEFORE_BUFFER_RENDER_EVENT_PARAM);
} }
renderPass.setIndexBuffer(bufferWrapper.getIndexGpuBuffer(), VertexFormat.IndexType.INT); renderPassWrapper.setIndexBuffer(bufferWrapper.getIndexGpuBuffer());
renderPass.setVertexBuffer(0, bufferWrapper.vertexGpuBuffer); // vertex buffer can only be "0" lol renderPassWrapper.setVertexBuffer(bufferWrapper.vertexGpuBuffer);
if (!bufferWrapper.vertexGpuBuffer.isClosed()) if (!bufferWrapper.vertexGpuBuffer.isClosed())
{ {
renderPass.drawIndexed( renderPassWrapper.drawIndexed(bufferWrapper.indexCount);
/*indexStart*/ 0,
/*firstIndex*/0,
/*indexCount*/bufferWrapper.indexCount,
/*instanceCount*/1);
} }
} }
} }
@@ -356,7 +328,7 @@ public class BlazeDhTerrainRenderer implements IDhTerrainRenderer
} }
} }
private String getIndexBufferName() { return "distantHorizons:LodIndexBuffer"; } private String getIndexBufferName() { return "distantHorizons:LodIndexBuffer"; }
private String getRenderPassName() { return "distantHorizons:McLodRenderer"; } private String getRenderPassName() { return "distantHorizons:TerrainRenderer"; }
//endregion //endregion
@@ -29,23 +29,26 @@ import com.mojang.blaze3d.pipeline.BlendFunction;
import com.mojang.blaze3d.pipeline.RenderPipeline; import com.mojang.blaze3d.pipeline.RenderPipeline;
import com.mojang.blaze3d.systems.CommandEncoder; import com.mojang.blaze3d.systems.CommandEncoder;
import com.mojang.blaze3d.systems.GpuDevice; import com.mojang.blaze3d.systems.GpuDevice;
import com.mojang.blaze3d.systems.RenderPass;
import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.textures.*; import com.mojang.blaze3d.textures.*;
import com.mojang.blaze3d.vertex.VertexFormat; import com.mojang.blaze3d.vertex.VertexFormat;
import com.seibel.distanthorizons.common.render.blaze.util.BlazeDhVertexFormatUtil; import com.seibel.distanthorizons.common.render.blaze.util.BlazeDhVertexFormatUtil;
import com.seibel.distanthorizons.common.render.blaze.wrappers.BlazeVertexFormatBuilder;
import com.seibel.distanthorizons.common.render.blaze.wrappers.RenderPassWrapper;
import com.seibel.distanthorizons.common.render.blaze.wrappers.RenderPipelineBuilderWrapper; 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.BlazeTextureViewWrapper;
import com.seibel.distanthorizons.common.render.blaze.util.BlazePostProcessUtil; import com.seibel.distanthorizons.common.render.blaze.util.BlazePostProcessUtil;
import com.seibel.distanthorizons.common.render.blaze.wrappers.texture.BlazeTextureWrapper; import com.seibel.distanthorizons.common.render.blaze.wrappers.texture.BlazeTextureWrapper;
import com.seibel.distanthorizons.common.render.blaze.wrappers.uniform.BlazeUniformBufferWrapper;
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
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.render.EDhRenderDepth;
import com.seibel.distanthorizons.core.wrapperInterfaces.render.AbstractDhRenderApiDefinition;
import com.seibel.distanthorizons.coreapi.ModInfo; import com.seibel.distanthorizons.coreapi.ModInfo;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.Arrays; import java.util.Arrays;
import java.util.OptionalDouble;
import java.util.OptionalInt;
/** /**
* Copies the given color texture * Copies the given color texture
@@ -57,13 +60,17 @@ import java.util.OptionalInt;
*/ */
public class BlazeDhApplyRenderer public class BlazeDhApplyRenderer
{ {
public static final DhLogger LOGGER = new DhLoggerBuilder().build(); public static final DhLogger LOGGER = new DhLoggerBuilder().build();
private static final AbstractDhRenderApiDefinition RENDER_API_DEF = SingletonInjector.INSTANCE.get(AbstractDhRenderApiDefinition.class);
private static final GpuDevice GPU_DEVICE = RenderSystem.getDevice(); private static final GpuDevice GPU_DEVICE = RenderSystem.getDevice();
private static final CommandEncoder COMMAND_ENCODER = GPU_DEVICE.createCommandEncoder(); private static final CommandEncoder COMMAND_ENCODER = GPU_DEVICE.createCommandEncoder();
private RenderPipeline pipeline; private RenderPipeline pipeline;
private final BlazeUniformBufferWrapper fragUniformBufferWrapper = new BlazeUniformBufferWrapper("baseFragUniformBlock");
protected GpuBuffer vboGpuBuffer; protected GpuBuffer vboGpuBuffer;
protected final String name; protected final String name;
@@ -92,7 +99,7 @@ public class BlazeDhApplyRenderer
*/ */
private final String[] uniformNames; private final String[] uniformNames;
/** will be an empty array if unneeded */ /** will be an empty array if unneeded */
private final GpuBuffer[] uniformBuffers; private final BlazeUniformBufferWrapper[] uniformBufferWrappers;
@@ -128,7 +135,7 @@ public class BlazeDhApplyRenderer
this.fragmentShaderPath = fragmentShaderPath; this.fragmentShaderPath = fragmentShaderPath;
this.uniformNames = uniformNames; this.uniformNames = uniformNames;
this.uniformBuffers = new GpuBuffer[this.uniformNames.length]; this.uniformBufferWrappers = new BlazeUniformBufferWrapper[this.uniformNames.length];
} }
private void tryInit( private void tryInit(
@@ -179,10 +186,12 @@ public class BlazeDhApplyRenderer
pipelineBuilder.withUniformBuffer(uniformName); pipelineBuilder.withUniformBuffer(uniformName);
} }
pipelineBuilder.withUniformBuffer("baseFragUniformBlock");
pipelineBuilder.withSampler("uSourceColorTexture"); pipelineBuilder.withSampler("uSourceColorTexture");
pipelineBuilder.withSampler("uSourceDepthTexture"); pipelineBuilder.withSampler("uSourceDepthTexture");
VertexFormat vertexFormat = VertexFormat.builder() VertexFormat vertexFormat = new BlazeVertexFormatBuilder()
.add("vPosition", BlazeDhVertexFormatUtil.SCREEN_POS) .add("vPosition", BlazeDhVertexFormatUtil.SCREEN_POS)
.build(); .build();
pipelineBuilder.withVertexFormat(vertexFormat); pipelineBuilder.withVertexFormat(vertexFormat);
@@ -191,7 +200,6 @@ public class BlazeDhApplyRenderer
this.pipeline = pipelineBuilder.build(); this.pipeline = pipelineBuilder.build();
} }
//endregion //endregion
@@ -201,7 +209,7 @@ public class BlazeDhApplyRenderer
//========// //========//
//region //region
public void setUniform(String uniformName, GpuBuffer uniformBuffer) public void setUniform(String uniformName, BlazeUniformBufferWrapper uniformBufferWrapper)
{ {
// the uniform array should be short enough (less than 10 items) // the uniform array should be short enough (less than 10 items)
// where a sequential search should be plenty fast // where a sequential search should be plenty fast
@@ -210,7 +218,7 @@ public class BlazeDhApplyRenderer
String nameAtIndex = this.uniformNames[i]; String nameAtIndex = this.uniformNames[i];
if (nameAtIndex.equals(uniformName)) if (nameAtIndex.equals(uniformName))
{ {
this.uniformBuffers[i] = uniformBuffer; this.uniformBufferWrappers[i] = uniformBufferWrapper;
break; break;
} }
} }
@@ -225,32 +233,38 @@ public class BlazeDhApplyRenderer
this.dummyDepthTextureWrapper.tryCreateOrResize(); this.dummyDepthTextureWrapper.tryCreateOrResize();
try (RenderPass renderPass = COMMAND_ENCODER.createRenderPass(
this.fragUniformBufferWrapper
.putInt((RENDER_API_DEF.getRenderDepth() == EDhRenderDepth.REVERSE_Z) ? 1 : 0) // uIsReverseZDepth
.finishAndUpload();
;
try (RenderPassWrapper renderPassWrapper = new RenderPassWrapper(
this::getIdentifierName, this::getIdentifierName,
this.destinationColorTextureViewWrapper.textureView, this.destinationColorTextureViewWrapper,
/*optionalClearColorAsInt*/ OptionalInt.empty(), this.dummyDepthTextureWrapper))
this.dummyDepthTextureWrapper.textureView,
/*optionalDepthValueAsDouble*/ OptionalDouble.empty()))
{ {
renderPass.bindTexture("uSourceColorTexture", this.sourceColorTextureViewWrapper.textureView, this.sourceColorTextureViewWrapper.textureSampler); renderPassWrapper.bindTexture("uSourceColorTexture", this.sourceColorTextureViewWrapper);
renderPass.bindTexture("uSourceDepthTexture", this.sourceDepthTextureViewWrapper.textureView, this.sourceDepthTextureViewWrapper.textureSampler); renderPassWrapper.bindTexture("uSourceDepthTexture", this.sourceDepthTextureViewWrapper);
for (int i = 0; i < this.uniformNames.length; i++) for (int i = 0; i < this.uniformNames.length; i++)
{ {
String uniformName = this.uniformNames[i]; String uniformName = this.uniformNames[i];
GpuBuffer uniformBuffer = this.uniformBuffers[i]; BlazeUniformBufferWrapper uniformBuffer = this.uniformBufferWrappers[i];
if (uniformBuffer == null) if (uniformBuffer == null)
{ {
throw new IllegalStateException("Missing uniform ["+uniformName+"], please set the uniform before rendering."); throw new IllegalStateException("Missing uniform ["+uniformName+"], please set the uniform before rendering.");
} }
renderPass.setUniform(uniformName, uniformBuffer); renderPassWrapper.setUniform(uniformName, uniformBuffer);
} }
renderPass.setVertexBuffer(0, this.vboGpuBuffer); renderPassWrapper.setUniform("baseFragUniformBlock", this.fragUniformBufferWrapper);
renderPass.setPipeline(this.pipeline);
renderPass.draw(/*indexStart*/ 0, /*indexCount*/ 4); renderPassWrapper.setVertexBuffer(this.vboGpuBuffer);
renderPassWrapper.setPipeline(this.pipeline);
renderPassWrapper.draw(4);
} }
@@ -258,7 +272,7 @@ public class BlazeDhApplyRenderer
// so we can check if they're missing during next frame's rendering // so we can check if they're missing during next frame's rendering
if (ModInfo.IS_DEV_BUILD) if (ModInfo.IS_DEV_BUILD)
{ {
Arrays.fill(this.uniformBuffers, null); Arrays.fill(this.uniformBufferWrappers, null);
} }
} }
@@ -28,19 +28,16 @@ import com.mojang.blaze3d.buffers.GpuBuffer;
import com.mojang.blaze3d.pipeline.RenderPipeline; import com.mojang.blaze3d.pipeline.RenderPipeline;
import com.mojang.blaze3d.systems.CommandEncoder; import com.mojang.blaze3d.systems.CommandEncoder;
import com.mojang.blaze3d.systems.GpuDevice; import com.mojang.blaze3d.systems.GpuDevice;
import com.mojang.blaze3d.systems.RenderPass;
import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.textures.*; import com.seibel.distanthorizons.common.render.blaze.wrappers.RenderPassWrapper;
import com.seibel.distanthorizons.common.render.blaze.wrappers.RenderPipelineBuilderWrapper; 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.BlazeTextureViewWrapper;
import com.seibel.distanthorizons.common.render.blaze.wrappers.texture.BlazeTextureWrapper; 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.BlazePostProcessUtil;
import com.seibel.distanthorizons.common.render.blaze.wrappers.texture.IDhBlazeTexture;
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 java.util.OptionalDouble;
import java.util.OptionalInt;
/** /**
* Blindly copies one texture into another. * Blindly copies one texture into another.
* *
@@ -103,7 +100,7 @@ public class BlazeDhCopyRenderer
this.pipeline = pipelineBuilder.build(); this.pipeline = pipelineBuilder.build();
this.vboGpuBuffer = BlazePostProcessUtil.createAndUploadScreenVertexData("McCopyRenderer"); this.vboGpuBuffer = BlazePostProcessUtil.createAndUploadScreenVertexData("CopyRenderer");
} }
@@ -117,48 +114,28 @@ public class BlazeDhCopyRenderer
//region //region
public void render( public void render(
BlazeTextureWrapper sourceColorTextureWrapper, IDhBlazeTexture sourceColorTextureWrapper,
BlazeTextureViewWrapper destinationColorTextureWrapper) IDhBlazeTexture destinationColorTextureWrapper)
{
this.render(
sourceColorTextureWrapper.textureView, sourceColorTextureWrapper.textureSampler,
destinationColorTextureWrapper.textureView);
}
public void render(
BlazeTextureWrapper sourceColorTextureWrapper,
BlazeTextureWrapper destinationColorTextureWrapper)
{
this.render(
sourceColorTextureWrapper.textureView, sourceColorTextureWrapper.textureSampler,
destinationColorTextureWrapper.textureView);
}
private void render(
GpuTextureView sourceTextureView,
GpuSampler sourceTextureSampler,
GpuTextureView destinationTextureView)
{ {
this.tryInit(); this.tryInit();
this.dummyDepthTextureWrapper.tryCreateOrResize(); this.dummyDepthTextureWrapper.tryCreateOrResize();
try (RenderPass renderPass = COMMAND_ENCODER.createRenderPass( try (RenderPassWrapper renderPassWrapper = new RenderPassWrapper(
this::getRenderPassName, this::getRenderPassName,
destinationTextureView, destinationColorTextureWrapper,
/*optionalClearColorAsInt*/ OptionalInt.empty(), this.dummyDepthTextureWrapper))
this.dummyDepthTextureWrapper.textureView,
/*optionalDepthValueAsDouble*/ OptionalDouble.empty()))
{ {
renderPass.bindTexture("uCopyTexture", sourceTextureView, sourceTextureSampler); renderPassWrapper.bindTexture("uCopyTexture", sourceColorTextureWrapper);
renderPass.setVertexBuffer(0, this.vboGpuBuffer); // vertex buffer can only be "0" lol renderPassWrapper.setVertexBuffer(this.vboGpuBuffer); // vertex buffer can only be "0" lol
renderPass.setPipeline(this.pipeline); renderPassWrapper.setPipeline(this.pipeline);
renderPass.draw(/*indexStart*/ 0, /*indexCount*/ 4); renderPassWrapper.draw(4);
} }
} }
private String getRenderPassName() { return "distantHorizons:McCopyRenderer"; } private String getRenderPassName() { return "distantHorizons:CopyRenderer"; }
//endregion //endregion
@@ -25,34 +25,27 @@ public class BlazeDhFarFadeRenderer {}
#else #else
import com.mojang.blaze3d.buffers.GpuBuffer; import com.mojang.blaze3d.buffers.GpuBuffer;
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.pipeline.RenderPipeline;
import com.mojang.blaze3d.systems.CommandEncoder; import com.mojang.blaze3d.systems.CommandEncoder;
import com.mojang.blaze3d.systems.GpuDevice; import com.mojang.blaze3d.systems.GpuDevice;
import com.mojang.blaze3d.systems.RenderPass;
import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.systems.RenderSystem;
import com.seibel.distanthorizons.common.render.blaze.BlazeDhMetaRenderer; import com.seibel.distanthorizons.common.render.blaze.BlazeDhMetaRenderer;
import com.seibel.distanthorizons.common.render.blaze.apply.BlazeDhCopyRenderer; 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.BlazePostProcessUtil;
import com.seibel.distanthorizons.common.render.blaze.util.BlazeUniformUtil; import com.seibel.distanthorizons.common.render.blaze.wrappers.RenderPassWrapper;
import com.seibel.distanthorizons.common.render.blaze.wrappers.RenderPipelineBuilderWrapper; 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.BlazeTextureViewWrapper;
import com.seibel.distanthorizons.common.render.blaze.wrappers.texture.BlazeTextureWrapper; import com.seibel.distanthorizons.common.render.blaze.wrappers.texture.BlazeTextureWrapper;
import com.seibel.distanthorizons.common.render.blaze.wrappers.uniform.BlazeUniformBufferWrapper;
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftRenderWrapper; import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftRenderWrapper;
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
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.render.EDhRenderDepth;
import com.seibel.distanthorizons.core.render.RenderParams; import com.seibel.distanthorizons.core.render.RenderParams;
import com.seibel.distanthorizons.core.util.RenderUtil; import com.seibel.distanthorizons.core.util.RenderUtil;
import com.seibel.distanthorizons.core.util.math.Mat4f; import com.seibel.distanthorizons.core.wrapperInterfaces.render.AbstractDhRenderApiDefinition;
import com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass.IDhFarFadeRenderer; import com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass.IDhFarFadeRenderer;
import net.minecraft.client.Minecraft;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.OptionalDouble;
import java.util.OptionalInt;
/** /**
* Fades out DH's far clip plane * Fades out DH's far clip plane
@@ -63,13 +56,14 @@ public class BlazeDhFarFadeRenderer implements IDhFarFadeRenderer
private static final GpuDevice GPU_DEVICE = RenderSystem.getDevice(); private static final GpuDevice GPU_DEVICE = RenderSystem.getDevice();
private static final CommandEncoder COMMAND_ENCODER = GPU_DEVICE.createCommandEncoder(); private static final CommandEncoder COMMAND_ENCODER = GPU_DEVICE.createCommandEncoder();
private static final AbstractDhRenderApiDefinition RENDER_API_DEF = SingletonInjector.INSTANCE.get(AbstractDhRenderApiDefinition.class);
public static final BlazeDhFarFadeRenderer INSTANCE = new BlazeDhFarFadeRenderer(); public static final BlazeDhFarFadeRenderer INSTANCE = new BlazeDhFarFadeRenderer();
private RenderPipeline pipeline; private RenderPipeline pipeline;
private boolean init = false; private boolean init = false;
private GpuBuffer fragUniformBuffer; private final BlazeUniformBufferWrapper fragUniformBufferWrapper = new BlazeUniformBufferWrapper("fragUniformBlock");
private GpuBuffer vboGpuBuffer; private GpuBuffer vboGpuBuffer;
@@ -124,7 +118,7 @@ public class BlazeDhFarFadeRenderer implements IDhFarFadeRenderer
this.pipeline = pipelineBuilder.build(); this.pipeline = pipelineBuilder.build();
this.vboGpuBuffer = BlazePostProcessUtil.createAndUploadScreenVertexData("McFadeRenderer"); this.vboGpuBuffer = BlazePostProcessUtil.createAndUploadScreenVertexData("DhFarFadeRenderer");
} }
//endregion //endregion
@@ -157,13 +151,6 @@ public class BlazeDhFarFadeRenderer implements IDhFarFadeRenderer
this.dhFadeDepthTextureWrapper.tryCreateOrResize(); this.dhFadeDepthTextureWrapper.tryCreateOrResize();
{ {
int uniformBufferSize = new Std140SizeCalculator()
.putFloat() // uStartFadeBlockDistance
.putFloat() // uEndFadeBlockDistance
.putMat4f() // uDhInvMvmProj
.get();
// create data // // create data //
float dhFarClipDistance = RenderUtil.getFarClipPlaneDistanceInBlocks(); float dhFarClipDistance = RenderUtil.getFarClipPlaneDistanceInBlocks();
@@ -171,30 +158,14 @@ public class BlazeDhFarFadeRenderer implements IDhFarFadeRenderer
float fadeEndDistance = dhFarClipDistance * 0.9f; float fadeEndDistance = dhFarClipDistance * 0.9f;
Mat4f dhProjectionMatrix = RenderUtil.createLodProjectionMatrix(renderParams.mcProjectionMatrix);
Mat4f dhModelViewMatrix = RenderUtil.createLodModelViewMatrix(renderParams.mcModelViewMatrix);
Mat4f inverseDhMvmProjMatrix = new Mat4f(dhProjectionMatrix);
inverseDhMvmProjMatrix.multiply(dhModelViewMatrix);
inverseDhMvmProjMatrix.invert();
// upload data // // upload data //
fragUniformBufferWrapper
ByteBuffer buffer = ByteBuffer.allocateDirect(uniformBufferSize);
buffer.order(ByteOrder.nativeOrder());
buffer = Std140Builder.intoBuffer(buffer)
.putFloat(fadeStartDistance) // uStartFadeBlockDistance .putFloat(fadeStartDistance) // uStartFadeBlockDistance
.putFloat(fadeEndDistance) // uEndFadeBlockDistance .putFloat(fadeEndDistance) // uEndFadeBlockDistance
.putMat4f(inverseDhMvmProjMatrix.createJomlMatrix()) // uDhInvMvmProj .putMat4f(renderParams.dhInverseMvmProjectionMatrix) // uDhInvMvmProj
.get() .putInt((RENDER_API_DEF.getRenderDepth() == EDhRenderDepth.REVERSE_Z) ? 1 : 0) // uIsReverseZDepth
.finishAndUpload()
; ;
this.fragUniformBuffer = BlazeUniformUtil.createBuffer("fragUniformBlock", uniformBufferSize, this.fragUniformBuffer);
GpuBufferSlice bufferSlice = new GpuBufferSlice(this.fragUniformBuffer, 0, uniformBufferSize);
COMMAND_ENCODER.writeToBuffer(bufferSlice, buffer);
} }
@@ -205,29 +176,27 @@ public class BlazeDhFarFadeRenderer implements IDhFarFadeRenderer
private void renderFadeToTexture() private void renderFadeToTexture()
{ {
try (RenderPass renderPass = COMMAND_ENCODER.createRenderPass( try (RenderPassWrapper renderPassWrapper = new RenderPassWrapper(
this::getRenderPassName, this::getRenderPassName,
this.dhFadeColorTextureWrapper.textureView, this.dhFadeColorTextureWrapper,
/*optionalClearColorAsInt*/ OptionalInt.empty(), this.dhFadeDepthTextureWrapper))
this.dhFadeDepthTextureWrapper.textureView,
/*optionalDepthValueAsDouble*/ OptionalDouble.empty()))
{ {
// MC texture // MC texture
renderPass.bindTexture("uMcColorTexture", this.mcColorTextureViewWrapper.textureView, this.mcColorTextureViewWrapper.textureSampler); renderPassWrapper.bindTexture("uMcColorTexture", this.mcColorTextureViewWrapper);
// DH textures // DH textures
renderPass.bindTexture("uDhDepthTexture", BlazeDhMetaRenderer.INSTANCE.dhDepthTextureWrapper.textureView, BlazeDhMetaRenderer.INSTANCE.dhDepthTextureWrapper.textureSampler); renderPassWrapper.bindTexture("uDhDepthTexture", BlazeDhMetaRenderer.INSTANCE.dhDepthTextureWrapper);
renderPass.bindTexture("uDhColorTexture", BlazeDhMetaRenderer.INSTANCE.dhColorTextureWrapper.textureView, BlazeDhMetaRenderer.INSTANCE.dhColorTextureWrapper.textureSampler); renderPassWrapper.bindTexture("uDhColorTexture", BlazeDhMetaRenderer.INSTANCE.dhColorTextureWrapper);
renderPass.setUniform("fragUniformBlock", this.fragUniformBuffer); renderPassWrapper.setUniform("fragUniformBlock", this.fragUniformBufferWrapper);
renderPass.setVertexBuffer(0, this.vboGpuBuffer); // vertex buffer can only be "0" lol renderPassWrapper.setVertexBuffer(this.vboGpuBuffer);
renderPass.setPipeline(this.pipeline); renderPassWrapper.setPipeline(this.pipeline);
renderPass.draw(/*indexStart*/ 0, /*indexCount*/ 4); renderPassWrapper.draw(4);
} }
} }
private String getRenderPassName() { return "distantHorizons:McFadeRenderer"; } private String getRenderPassName() { return "distantHorizons:DhFarFadeRenderer"; }
//endregion //endregion
@@ -24,41 +24,35 @@ public class BlazeDhFogRenderer {}
#else #else
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.api.enums.rendering.EDhApiHeightFogMixMode;
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiFogRenderParam;
import com.seibel.distanthorizons.common.render.blaze.BlazeDhMetaRenderer; import com.seibel.distanthorizons.common.render.blaze.BlazeDhMetaRenderer;
import com.seibel.distanthorizons.common.render.blaze.apply.BlazeDhApplyRenderer; import com.seibel.distanthorizons.common.render.blaze.apply.BlazeDhApplyRenderer;
import com.seibel.distanthorizons.common.render.blaze.wrappers.RenderPassWrapper;
import com.seibel.distanthorizons.common.render.blaze.wrappers.RenderPipelineBuilderWrapper; 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.wrappers.texture.BlazeTextureWrapper;
import com.seibel.distanthorizons.common.render.blaze.util.BlazePostProcessUtil; 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.uniform.BlazeUniformBufferWrapper;
import com.seibel.distanthorizons.core.config.Config; import com.seibel.distanthorizons.core.config.Config;
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
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.render.EDhRenderDepth;
import com.seibel.distanthorizons.core.render.RenderParams; import com.seibel.distanthorizons.core.render.RenderParams;
import com.seibel.distanthorizons.core.util.LodUtil; import com.seibel.distanthorizons.core.util.LodUtil;
import com.seibel.distanthorizons.core.util.math.Mat4f; import com.seibel.distanthorizons.core.util.math.DhMat4f;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.render.AbstractDhRenderApiDefinition;
import com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass.IDhFogRenderer; import com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass.IDhFogRenderer;
import java.awt.*; import java.awt.*;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.OptionalDouble;
import java.util.OptionalInt;
import com.mojang.blaze3d.buffers.GpuBuffer; import com.mojang.blaze3d.buffers.GpuBuffer;
import com.mojang.blaze3d.buffers.GpuBufferSlice;
import com.mojang.blaze3d.buffers.Std140Builder;
import com.mojang.blaze3d.buffers.Std140SizeCalculator;
import com.mojang.blaze3d.pipeline.BlendFunction; import com.mojang.blaze3d.pipeline.BlendFunction;
import com.mojang.blaze3d.pipeline.RenderPipeline; import com.mojang.blaze3d.pipeline.RenderPipeline;
import com.mojang.blaze3d.systems.CommandEncoder; import com.mojang.blaze3d.systems.CommandEncoder;
import com.mojang.blaze3d.systems.GpuDevice; import com.mojang.blaze3d.systems.GpuDevice;
import com.mojang.blaze3d.systems.RenderPass;
import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.systems.RenderSystem;
#if MC_VER <= MC_26_1_2 #if MC_VER <= MC_26_1_2
@@ -75,8 +69,7 @@ public class BlazeDhFogRenderer implements IDhFogRenderer
{ {
public static final DhLogger LOGGER = new DhLoggerBuilder().build(); public static final DhLogger LOGGER = new DhLoggerBuilder().build();
private static final IMinecraftClientWrapper MC = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class); private static final AbstractDhRenderApiDefinition RENDER_API_DEF = SingletonInjector.INSTANCE.get(AbstractDhRenderApiDefinition.class);
private static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class);
private static final GpuDevice GPU_DEVICE = RenderSystem.getDevice(); private static final GpuDevice GPU_DEVICE = RenderSystem.getDevice();
private static final CommandEncoder COMMAND_ENCODER = GPU_DEVICE.createCommandEncoder(); private static final CommandEncoder COMMAND_ENCODER = GPU_DEVICE.createCommandEncoder();
@@ -89,7 +82,7 @@ public class BlazeDhFogRenderer implements IDhFogRenderer
private RenderPipeline pipeline; private RenderPipeline pipeline;
private boolean init = false; private boolean init = false;
private GpuBuffer fragUniformBuffer; private final BlazeUniformBufferWrapper fragUniformBufferWrapper = new BlazeUniformBufferWrapper("dh_fog_frag_uniform");
private GpuBuffer vboGpuBuffer; private GpuBuffer vboGpuBuffer;
@@ -151,7 +144,7 @@ public class BlazeDhFogRenderer implements IDhFogRenderer
this.pipeline = pipelineBuilder.build(); this.pipeline = pipelineBuilder.build();
this.vboGpuBuffer = BlazePostProcessUtil.createAndUploadScreenVertexData("McFogRenderer"); this.vboGpuBuffer = BlazePostProcessUtil.createAndUploadScreenVertexData("FogRenderer");
} }
//endregion //endregion
@@ -164,7 +157,7 @@ public class BlazeDhFogRenderer implements IDhFogRenderer
//region //region
@Override @Override
public void render(RenderParams renderParams) public void render(RenderParams renderParams, DhApiFogRenderParam fogRenderParams)
{ {
this.tryInit(); this.tryInit();
@@ -181,144 +174,68 @@ public class BlazeDhFogRenderer implements IDhFogRenderer
this.fogDepthTextureWrapper.tryCreateOrResize(); this.fogDepthTextureWrapper.tryCreateOrResize();
{ {
int uniformBufferSize = new Std140SizeCalculator()
// fog uniforms
.putVec4() // uFogColor
.putFloat() //uFogScale
.putFloat() //uFogVerticalScale
// only used for debugging
.putInt() //uFogDebugMode // 1 = render everything with fog color // 7 = use debug rendering
.putInt() //uFogFalloffType
// fog config
.putFloat() // uFarFogStart
.putFloat() // uFarFogLength
.putFloat() // uFarFogMin
.putFloat() // uFarFogRange
.putFloat() // uFarFogDensity
// height fog config
.putFloat() // uHeightFogStart
.putFloat() // uHeightFogLength
.putFloat() // uHeightFogMin
.putFloat() // uHeightFogRange
.putFloat() // uHeightFogDensity
// ??
.putInt() // uHeightFogEnabled
.putInt() // uHeightFogFalloffType
.putInt() // uHeightBasedOnCamera
.putFloat() // uHeightFogBaseHeight
.putInt() // uHeightFogAppliesUp
.putInt() // uHeightFogAppliesDown
.putInt() // uUseSphericalFog
.putInt() // uHeightFogMixingMode
.putFloat() // uCameraBlockYPos
.putMat4f() // uInvMvmProj
.get();
// create data // // create data //
int lodDrawDistance = Config.Client.Advanced.Graphics.Quality.lodChunkRenderDistanceRadius.get() * LodUtil.CHUNK_WIDTH; int lodDrawDistance = Config.Client.Advanced.Graphics.Quality.lodChunkRenderDistanceRadius.get() * LodUtil.CHUNK_WIDTH;
DhMat4f inverseMvmProjMatrix = new DhMat4f(renderParams.dhMvmProjMatrix);
Mat4f inverseMvmProjMatrix = new Mat4f(renderParams.dhMvmProjMatrix);
inverseMvmProjMatrix.invert(); inverseMvmProjMatrix.invert();
if (renderParams.dhMvmProjMatrix == null) EDhApiHeightFogMixMode heightFogMixingMode = fogRenderParams.getHeightFogMixingMode();
{ boolean heightFogEnabled =
return; heightFogMixingMode != EDhApiHeightFogMixMode.SPHERICAL
} && heightFogMixingMode != EDhApiHeightFogMixMode.CYLINDRICAL;
Color fogColor = this.getFogColor(renderParams.partialTicks);
// fog config
float farFogStart = Config.Client.Advanced.Graphics.Fog.farFogStart.get();
float farFogEnd = Config.Client.Advanced.Graphics.Fog.farFogEnd.get();
float farFogMin = Config.Client.Advanced.Graphics.Fog.farFogMin.get();
float farFogMax = Config.Client.Advanced.Graphics.Fog.farFogMax.get();
float farFogDensity = Config.Client.Advanced.Graphics.Fog.farFogDensity.get();
// override fog if underwater
if (MC_RENDER.isFogStateSpecial())
{
// hide everything behind fog
farFogStart = 0.0f;
farFogEnd = 0.0f;
}
// height config
EDhApiHeightFogMixMode heightFogMixingMode = Config.Client.Advanced.Graphics.Fog.HeightFog.heightFogMixMode.get();
boolean heightFogEnabled = heightFogMixingMode != EDhApiHeightFogMixMode.SPHERICAL && heightFogMixingMode != EDhApiHeightFogMixMode.CYLINDRICAL;
boolean useSphericalFog = heightFogMixingMode == EDhApiHeightFogMixMode.SPHERICAL; boolean useSphericalFog = heightFogMixingMode == EDhApiHeightFogMixMode.SPHERICAL;
EDhApiHeightFogDirection heightFogCameraDirection = Config.Client.Advanced.Graphics.Fog.HeightFog.heightFogDirection.get();
float heightFogStart = Config.Client.Advanced.Graphics.Fog.HeightFog.heightFogStart.get(); Color fogColor = fogRenderParams.getFogColor();
float heightFogEnd = Config.Client.Advanced.Graphics.Fog.HeightFog.heightFogEnd.get();
float heightFogMin = Config.Client.Advanced.Graphics.Fog.HeightFog.heightFogMin.get();
float heightFogMax = Config.Client.Advanced.Graphics.Fog.HeightFog.heightFogMax.get();
float heightFogDensity = Config.Client.Advanced.Graphics.Fog.HeightFog.heightFogDensity.get();
// upload data // // upload data //
ByteBuffer buffer = ByteBuffer.allocateDirect(uniformBufferSize); this.fragUniformBufferWrapper
buffer.order(ByteOrder.nativeOrder());
buffer = Std140Builder.intoBuffer(buffer)
// fog uniforms // fog uniforms
.putVec4( .putVec4f(
fogColor.getRed() / 255.0f, fogColor.getRed() / 255.0f,
fogColor.getGreen() / 255.0f, fogColor.getGreen() / 255.0f,
fogColor.getBlue() / 255.0f, fogColor.getBlue() / 255.0f,
fogColor.getAlpha() / 255.0f) // uFogColor fogColor.getAlpha() / 255.0f) // uFogColor
.putFloat(1.f / lodDrawDistance) //uFogScale .putFloat(1.f / lodDrawDistance) //uFogScale
.putFloat(1.f / MC.getWrappedClientLevel().getMaxHeight()) //uFogVerticalScale .putFloat(1.f / renderParams.clientLevelWrapper.getMaxHeight()) //uFogVerticalScale
// only used for debugging .putInt(0) //uFogDebugMode // 0 = normal // 1 = render everything with fog color // 7 = use debug rendering
.putInt(0) //uFogDebugMode // 1 = render everything with fog color // 7 = use debug rendering .putInt(fogRenderParams.getFarFogFalloff().value) //uFogFalloffType
.putInt(Config.Client.Advanced.Graphics.Fog.farFogFalloff.get().value) //uFogFalloffType
// fog config // fog config
.putFloat(farFogStart) // uFarFogStart .putFloat(fogRenderParams.getFarFogStartPercent()) // uFarFogStart
.putFloat(farFogEnd - farFogStart) // uFarFogLength .putFloat(fogRenderParams.getFarFogEndPercent() - fogRenderParams.getFarFogStartPercent()) // uFarFogLength
.putFloat(farFogMin) // uFarFogMin .putFloat(fogRenderParams.getFarFogMinThickness()) // uFarFogMin
.putFloat(farFogMax - farFogMin) // uFarFogRange .putFloat(fogRenderParams.getFarFogMaxThickness() - fogRenderParams.getFarFogMinThickness()) // uFarFogRange
.putFloat(farFogDensity) // uFarFogDensity .putFloat(fogRenderParams.getFarFogDensity()) // uFarFogDensity
// height fog config // height fog config
.putFloat(heightFogStart) // uHeightFogStart .putFloat(fogRenderParams.getHeightFogStartPercent()) // uHeightFogStart
.putFloat(heightFogEnd - heightFogStart) // uHeightFogLength .putFloat(fogRenderParams.getHeightFogEndPercent() - fogRenderParams.getHeightFogStartPercent()) // uHeightFogLength
.putFloat(heightFogMin) // uHeightFogMin .putFloat(fogRenderParams.getHeightFogMinThickness()) // uHeightFogMin
.putFloat(heightFogMax - heightFogMin) // uHeightFogRange .putFloat(fogRenderParams.getHeightFogMaxThickness() - fogRenderParams.getHeightFogMinThickness()) // uHeightFogRange
.putFloat(heightFogDensity) // uHeightFogDensity .putFloat(fogRenderParams.getHeightFogDensity()) // uHeightFogDensity
// ?? // ??
.putInt(heightFogEnabled ? 1 : 0) // uHeightFogEnabled .putInt(heightFogEnabled ? 1 : 0) // uHeightFogEnabled
.putInt(Config.Client.Advanced.Graphics.Fog.HeightFog.heightFogFalloff.get().value) // uHeightFogFalloffType .putInt(fogRenderParams.getHeightFogFalloff().value) // uHeightFogFalloffType
.putInt(heightFogCameraDirection.basedOnCamera ? 1 : 0) // uHeightBasedOnCamera .putInt(fogRenderParams.getHeightFogDirection().basedOnCamera ? 1 : 0) // uHeightBasedOnCamera
.putFloat(Config.Client.Advanced.Graphics.Fog.HeightFog.heightFogBaseHeight.get()) // uHeightFogBaseHeight .putFloat(fogRenderParams.getHeightFogBaseHeight()) // uHeightFogBaseHeight
.putInt(heightFogCameraDirection.fogAppliesUp ? 1 : 0) // uHeightFogAppliesUp .putInt(fogRenderParams.getHeightFogDirection().fogAppliesUp ? 1 : 0) // uHeightFogAppliesUp
.putInt(heightFogCameraDirection.fogAppliesDown ? 1 : 0) // uHeightFogAppliesDown .putInt(fogRenderParams.getHeightFogDirection().fogAppliesDown ? 1 : 0) // uHeightFogAppliesDown
.putInt(useSphericalFog ? 1 : 0) // uUseSphericalFog .putInt(useSphericalFog ? 1 : 0) // uUseSphericalFog
.putInt(heightFogMixingMode.value) // uHeightFogMixingMode .putInt(heightFogMixingMode.value) // uHeightFogMixingMode
.putFloat((float)MC_RENDER.getCameraExactPosition().y) // uCameraBlockYPos .putFloat((float)renderParams.exactCameraPosition.y) // uCameraBlockYPos
.putMat4f(inverseMvmProjMatrix.createJomlMatrix()) // uInvMvmProj .putMat4f(inverseMvmProjMatrix) // uInvMvmProj
.get() .putInt((RENDER_API_DEF.getRenderDepth() == EDhRenderDepth.REVERSE_Z) ? 1 : 0) // uIsReverseZDepth
.finishAndUpload()
; ;
this.fragUniformBuffer = BlazeUniformUtil.createBuffer("fragUniformBlock", uniformBufferSize, this.fragUniformBuffer);
GpuBufferSlice bufferSlice = new GpuBufferSlice(this.fragUniformBuffer, 0, uniformBufferSize);
COMMAND_ENCODER.writeToBuffer(bufferSlice, buffer);
} }
@@ -327,42 +244,26 @@ public class BlazeDhFogRenderer implements IDhFogRenderer
} }
private Color getFogColor(float partialTicks)
{
Color fogColor;
if (Config.Client.Advanced.Graphics.Fog.colorMode.get() == EDhApiFogColorMode.USE_SKY_COLOR)
{
fogColor = MC_RENDER.getSkyColor();
}
else
{
fogColor = MC_RENDER.getFogColor(partialTicks);
}
return fogColor;
}
private void renderFogToTexture() private void renderFogToTexture()
{ {
try (RenderPass renderPass = COMMAND_ENCODER.createRenderPass( try (RenderPassWrapper renderPassWrapper = new RenderPassWrapper(
this::getRenderPassName, this::getRenderPassName,
this.fogColorTextureWrapper.textureView, this.fogColorTextureWrapper,
/*optionalClearColorAsInt*/ OptionalInt.empty(), this.fogDepthTextureWrapper))
this.fogDepthTextureWrapper.textureView,
/*optionalDepthValueAsDouble*/ OptionalDouble.empty()))
{ {
renderPass.bindTexture("uDhDepthTexture", BlazeDhMetaRenderer.INSTANCE.dhDepthTextureWrapper.textureView, BlazeDhMetaRenderer.INSTANCE.dhDepthTextureWrapper.textureSampler); renderPassWrapper.bindTexture("uDhDepthTexture", BlazeDhMetaRenderer.INSTANCE.dhDepthTextureWrapper);
renderPass.setUniform("fragUniformBlock", this.fragUniformBuffer); renderPassWrapper.setUniform("fragUniformBlock", this.fragUniformBufferWrapper);
renderPass.setVertexBuffer(0, this.vboGpuBuffer); // vertex buffer can only be "0" lol renderPassWrapper.setVertexBuffer(this.vboGpuBuffer); // vertex buffer can only be "0" lol
renderPass.setPipeline(this.pipeline); renderPassWrapper.setPipeline(this.pipeline);
renderPass.draw(/*indexStart*/ 0, /*indexCount*/ 4); renderPassWrapper.draw(/*indexCount*/ 4);
} }
} }
private String getRenderPassName() { return "distantHorizons:McFogRenderer"; } private String getRenderPassName() { return "distantHorizons:FogRenderer"; }
//endregion //endregion
@@ -26,34 +26,27 @@ public class BlazeDhSsaoRenderer {}
import com.seibel.distanthorizons.common.render.blaze.BlazeDhMetaRenderer; import com.seibel.distanthorizons.common.render.blaze.BlazeDhMetaRenderer;
import com.seibel.distanthorizons.common.render.blaze.apply.BlazeDhApplyRenderer; import com.seibel.distanthorizons.common.render.blaze.apply.BlazeDhApplyRenderer;
import com.seibel.distanthorizons.common.render.blaze.wrappers.RenderPassWrapper;
import com.seibel.distanthorizons.common.render.blaze.wrappers.RenderPipelineBuilderWrapper; 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.wrappers.texture.BlazeTextureWrapper;
import com.seibel.distanthorizons.common.render.blaze.util.BlazePostProcessUtil; 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.uniform.BlazeUniformBufferWrapper;
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
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.render.EDhRenderDepth;
import com.seibel.distanthorizons.core.render.RenderParams; import com.seibel.distanthorizons.core.render.RenderParams;
import com.seibel.distanthorizons.core.util.RenderUtil; import com.seibel.distanthorizons.core.util.RenderUtil;
import com.seibel.distanthorizons.core.util.math.Mat4f; import com.seibel.distanthorizons.core.util.math.DhMat4f;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.render.AbstractDhRenderApiDefinition;
import com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass.IDhSsaoRenderer; import com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass.IDhSsaoRenderer;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.OptionalDouble;
import java.util.OptionalInt;
import com.mojang.blaze3d.buffers.GpuBuffer; import com.mojang.blaze3d.buffers.GpuBuffer;
import com.mojang.blaze3d.buffers.GpuBufferSlice;
import com.mojang.blaze3d.buffers.Std140Builder;
import com.mojang.blaze3d.buffers.Std140SizeCalculator;
import com.mojang.blaze3d.pipeline.BlendFunction; import com.mojang.blaze3d.pipeline.BlendFunction;
import com.mojang.blaze3d.pipeline.RenderPipeline; import com.mojang.blaze3d.pipeline.RenderPipeline;
import com.mojang.blaze3d.platform.BlendFactor;
import com.mojang.blaze3d.systems.CommandEncoder; import com.mojang.blaze3d.systems.CommandEncoder;
import com.mojang.blaze3d.systems.GpuDevice; import com.mojang.blaze3d.systems.GpuDevice;
import com.mojang.blaze3d.systems.RenderPass;
import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.systems.RenderSystem;
#if MC_VER <= MC_26_1_2 #if MC_VER <= MC_26_1_2
@@ -69,6 +62,7 @@ public class BlazeDhSsaoRenderer implements IDhSsaoRenderer
private static final DhLogger LOGGER = new DhLoggerBuilder().build(); private static final DhLogger LOGGER = new DhLoggerBuilder().build();
private static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class); private static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class);
private static final AbstractDhRenderApiDefinition RENDER_API_DEF = SingletonInjector.INSTANCE.get(AbstractDhRenderApiDefinition.class);
private static final GpuDevice GPU_DEVICE = RenderSystem.getDevice(); private static final GpuDevice GPU_DEVICE = RenderSystem.getDevice();
private static final CommandEncoder COMMAND_ENCODER = GPU_DEVICE.createCommandEncoder(); private static final CommandEncoder COMMAND_ENCODER = GPU_DEVICE.createCommandEncoder();
@@ -81,8 +75,8 @@ public class BlazeDhSsaoRenderer implements IDhSsaoRenderer
private RenderPipeline pipeline; private RenderPipeline pipeline;
private boolean init = false; private boolean init = false;
private GpuBuffer fragUniformBuffer; private final BlazeUniformBufferWrapper fragUniformBufferWrapper = new BlazeUniformBufferWrapper("fragUniformBlock");
private GpuBuffer applyFragUniformBuffer; private final BlazeUniformBufferWrapper applyFragUniformBufferWrapper = new BlazeUniformBufferWrapper("applyFragUniformBlock");
private GpuBuffer vboGpuBuffer; private GpuBuffer vboGpuBuffer;
@@ -178,32 +172,14 @@ public class BlazeDhSsaoRenderer implements IDhSsaoRenderer
// frag uniforms // frag uniforms
{ {
int uniformBufferSize = new Std140SizeCalculator()
.putInt() // uSampleCount\
.putFloat() // uRadius
.putFloat() // uStrength
.putFloat() // uMinLight
.putFloat() // uBias
.putFloat() // uFadeDistanceInBlocks
.putMat4f() // uInvProj
.putMat4f() // uProj
.get();
// create data // // create data //
DhMat4f projMatrix = new DhMat4f(renderParams.dhProjectionMatrix);
Mat4f projMatrix = new Mat4f(renderParams.dhProjectionMatrix); DhMat4f invertedProjMatrix = new DhMat4f(renderParams.dhProjectionMatrix);
Mat4f invertedProjMatrix = new Mat4f(renderParams.dhProjectionMatrix);
invertedProjMatrix.invert(); invertedProjMatrix.invert();
// upload data // // upload data //
this.fragUniformBufferWrapper
ByteBuffer buffer = ByteBuffer.allocateDirect(uniformBufferSize);
buffer.order(ByteOrder.nativeOrder());
buffer = Std140Builder.intoBuffer(buffer)
.putInt(6) // uSampleCount .putInt(6) // uSampleCount
.putFloat(4.0f) // uRadius .putFloat(4.0f) // uRadius
@@ -212,27 +188,16 @@ public class BlazeDhSsaoRenderer implements IDhSsaoRenderer
.putFloat(0.02f) // uBias .putFloat(0.02f) // uBias
.putFloat(1_600.0f) // uFadeDistanceInBlocks .putFloat(1_600.0f) // uFadeDistanceInBlocks
.putMat4f(invertedProjMatrix.createJomlMatrix()) .putMat4f(invertedProjMatrix)
.putMat4f(projMatrix.createJomlMatrix()) .putMat4f(projMatrix)
.get()
.putInt((RENDER_API_DEF.getRenderDepth() == EDhRenderDepth.REVERSE_Z) ? 1 : 0) // uIsReverseZDepth
.finishAndUpload()
; ;
this.fragUniformBuffer = BlazeUniformUtil.createBuffer("fragUniformBlock", uniformBufferSize, this.fragUniformBuffer);
GpuBufferSlice bufferSlice = new GpuBufferSlice(this.fragUniformBuffer, 0, uniformBufferSize);
COMMAND_ENCODER.writeToBuffer(bufferSlice, buffer);
} }
// apply frag uniforms // apply frag uniforms
{ {
int uniformBufferSize = new Std140SizeCalculator()
.putVec2() // uViewSize
.putInt() // uBlurRadius
.putFloat() // uNearClipPlane
.putFloat() // uFarClipPlane
.get();
// create data // // create data //
float viewWidth = (float)MC_RENDER.getTargetFramebufferViewportWidth(); float viewWidth = (float)MC_RENDER.getTargetFramebufferViewportWidth();
@@ -243,51 +208,41 @@ public class BlazeDhSsaoRenderer implements IDhSsaoRenderer
// upload data // // upload data //
this.applyFragUniformBufferWrapper
ByteBuffer buffer = ByteBuffer.allocateDirect(uniformBufferSize); .putVec2f(viewWidth, viewHeight) // uViewSize
buffer.order(ByteOrder.nativeOrder());
buffer = Std140Builder.intoBuffer(buffer)
.putVec2(viewWidth, viewHeight) // uViewSize
.putInt(2) // uBlurRadius .putInt(2) // uBlurRadius
.putFloat(nearClipPlane) // uNearClipPlane .putFloat(nearClipPlane) // uNearClipPlane
.putFloat(farClipPlane) // uFarClipPlane .putFloat(farClipPlane) // uFarClipPlane
.get() .finishAndUpload()
; ;
this.applyFragUniformBuffer = BlazeUniformUtil.createBuffer("applyFragUniformBlock", uniformBufferSize, this.applyFragUniformBuffer);
GpuBufferSlice bufferSlice = new GpuBufferSlice(this.applyFragUniformBuffer, 0, uniformBufferSize);
COMMAND_ENCODER.writeToBuffer(bufferSlice, buffer);
} }
this.renderSsaoToTexture(); this.renderSsaoToTexture();
this.applyRenderer.setUniform("applyFragUniformBlock", this.applyFragUniformBuffer); this.applyRenderer.setUniform("applyFragUniformBlock", this.applyFragUniformBufferWrapper);
this.applyRenderer.render(this.ssaoColorTextureWrapper.texture, BlazeDhMetaRenderer.INSTANCE.dhDepthTextureWrapper.texture, BlazeDhMetaRenderer.INSTANCE.dhColorTextureWrapper.texture); this.applyRenderer.render(this.ssaoColorTextureWrapper.texture, BlazeDhMetaRenderer.INSTANCE.dhDepthTextureWrapper.texture, BlazeDhMetaRenderer.INSTANCE.dhColorTextureWrapper.texture);
} }
private void renderSsaoToTexture() private void renderSsaoToTexture()
{ {
try (RenderPass renderPass = COMMAND_ENCODER.createRenderPass( try (RenderPassWrapper renderPassWrapper = new RenderPassWrapper(
this::getRenderPassName, this::getRenderPassName,
this.ssaoColorTextureWrapper.textureView, this.ssaoColorTextureWrapper,
/*optionalClearColorAsInt*/ OptionalInt.empty(), this.ssaoDepthTextureWrapper))
this.ssaoDepthTextureWrapper.textureView,
/*optionalDepthValueAsDouble*/ OptionalDouble.empty()))
{ {
renderPass.bindTexture("uDhDepthTexture", BlazeDhMetaRenderer.INSTANCE.dhDepthTextureWrapper.textureView, BlazeDhMetaRenderer.INSTANCE.dhDepthTextureWrapper.textureSampler); renderPassWrapper.bindTexture("uDhDepthTexture", BlazeDhMetaRenderer.INSTANCE.dhDepthTextureWrapper);
renderPass.setUniform("fragUniformBlock", this.fragUniformBuffer); renderPassWrapper.setUniform("fragUniformBlock", this.fragUniformBufferWrapper);
renderPass.setVertexBuffer(0, this.vboGpuBuffer); // vertex buffer can only be "0" lol renderPassWrapper.setVertexBuffer(this.vboGpuBuffer);
renderPass.setPipeline(this.pipeline); renderPassWrapper.setPipeline(this.pipeline);
renderPass.draw(/*indexStart*/ 0, /*indexCount*/ 4); renderPassWrapper.draw(4);
} }
} }
private String getRenderPassName() { return "distantHorizons:McSsaoRenderer"; } private String getRenderPassName() { return "distantHorizons:SsaoRenderer"; }
//endregion //endregion
@@ -25,41 +25,30 @@ public class BlazeVanillaFadeRenderer {}
#else #else
import com.mojang.blaze3d.buffers.GpuBuffer; import com.mojang.blaze3d.buffers.GpuBuffer;
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.pipeline.RenderPipeline;
import com.mojang.blaze3d.platform.PolygonMode;
import com.mojang.blaze3d.shaders.UniformType;
import com.mojang.blaze3d.systems.CommandEncoder; import com.mojang.blaze3d.systems.CommandEncoder;
import com.mojang.blaze3d.systems.GpuDevice; import com.mojang.blaze3d.systems.GpuDevice;
import com.mojang.blaze3d.systems.RenderPass;
import com.mojang.blaze3d.systems.RenderSystem; 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.BlazeDhMetaRenderer;
import com.seibel.distanthorizons.common.render.blaze.apply.BlazeDhCopyRenderer; 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.BlazePostProcessUtil;
import com.seibel.distanthorizons.common.render.blaze.util.BlazeUniformUtil; import com.seibel.distanthorizons.common.render.blaze.wrappers.RenderPassWrapper;
import com.seibel.distanthorizons.common.render.blaze.wrappers.RenderPipelineBuilderWrapper; 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.BlazeTextureViewWrapper;
import com.seibel.distanthorizons.common.render.blaze.wrappers.texture.BlazeTextureWrapper; import com.seibel.distanthorizons.common.render.blaze.wrappers.texture.BlazeTextureWrapper;
import com.seibel.distanthorizons.common.render.blaze.wrappers.uniform.BlazeUniformBufferWrapper;
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftRenderWrapper; import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftRenderWrapper;
import com.seibel.distanthorizons.core.config.Config; import com.seibel.distanthorizons.core.config.Config;
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
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.render.EDhRenderDepth;
import com.seibel.distanthorizons.core.render.RenderParams; import com.seibel.distanthorizons.core.render.RenderParams;
import com.seibel.distanthorizons.core.util.RenderUtil; import com.seibel.distanthorizons.core.util.RenderUtil;
import com.seibel.distanthorizons.core.util.math.Mat4f; import com.seibel.distanthorizons.core.util.math.DhMat4f;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.render.AbstractDhRenderApiDefinition;
import com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass.IDhVanillaFadeRenderer; import com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass.IDhVanillaFadeRenderer;
import net.minecraft.client.Minecraft;
import net.minecraft.resources.Identifier;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.OptionalDouble;
import java.util.OptionalInt;
/** /**
* Fades the vanilla chunks * Fades the vanilla chunks
@@ -70,16 +59,18 @@ public class BlazeVanillaFadeRenderer implements IDhVanillaFadeRenderer
public static final DhLogger LOGGER = new DhLoggerBuilder().build(); public static final DhLogger LOGGER = new DhLoggerBuilder().build();
private static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class); private static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class);
private static final AbstractDhRenderApiDefinition RENDER_API_DEF = SingletonInjector.INSTANCE.get(AbstractDhRenderApiDefinition.class);
private static final GpuDevice GPU_DEVICE = RenderSystem.getDevice(); private static final GpuDevice GPU_DEVICE = RenderSystem.getDevice();
private static final CommandEncoder COMMAND_ENCODER = GPU_DEVICE.createCommandEncoder(); private static final CommandEncoder COMMAND_ENCODER = GPU_DEVICE.createCommandEncoder();
public static final BlazeVanillaFadeRenderer INSTANCE = new BlazeVanillaFadeRenderer(); public static final BlazeVanillaFadeRenderer INSTANCE = new BlazeVanillaFadeRenderer();
private RenderPipeline pipeline; private RenderPipeline pipeline;
private boolean init = false; private boolean init = false;
private GpuBuffer fragUniformBuffer; private final BlazeUniformBufferWrapper fragUniformBufferWrapper = new BlazeUniformBufferWrapper("fragUniformBlock");
private GpuBuffer vboGpuBuffer; private GpuBuffer vboGpuBuffer;
@@ -137,7 +128,7 @@ public class BlazeVanillaFadeRenderer implements IDhVanillaFadeRenderer
this.pipeline = pipelineBuilder.build(); this.pipeline = pipelineBuilder.build();
this.vboGpuBuffer = BlazePostProcessUtil.createAndUploadScreenVertexData("McFadeRenderer"); this.vboGpuBuffer = BlazePostProcessUtil.createAndUploadScreenVertexData("VanillaFadeRenderer");
} }
//endregion //endregion
@@ -170,16 +161,6 @@ public class BlazeVanillaFadeRenderer implements IDhVanillaFadeRenderer
{ {
int uniformBufferSize = new Std140SizeCalculator()
.putInt() // uOnlyRenderLods
.putFloat() // uStartFadeBlockDistance
.putFloat() // uEndFadeBlockDistance
.putFloat() // uMaxLevelHeight
.putMat4f() // uDhInvMvmProj
.putMat4f() // uMcInvMvmProj
.get();
// create data // // create data //
float dhNearClipDistance = RenderUtil.getNearClipPlaneInBlocks(); float dhNearClipDistance = RenderUtil.getNearClipPlaneInBlocks();
@@ -193,37 +174,30 @@ public class BlazeVanillaFadeRenderer implements IDhVanillaFadeRenderer
float fadeEndDistance = dhNearClipDistance * 1.9f; float fadeEndDistance = dhNearClipDistance * 1.9f;
Mat4f inverseMcModelViewProjectionMatrix = new Mat4f(renderParams.mcProjectionMatrix); DhMat4f inverseMcModelViewProjectionMatrix = new DhMat4f(renderParams.mcProjectionMatrix);
inverseMcModelViewProjectionMatrix.multiply(renderParams.mcModelViewMatrix); inverseMcModelViewProjectionMatrix.multiply(renderParams.mcModelViewMatrix);
inverseMcModelViewProjectionMatrix.invert(); inverseMcModelViewProjectionMatrix.invert();
Mat4f inverseMcMvmProjMatrix = inverseMcModelViewProjectionMatrix; DhMat4f inverseMcMvmProjMatrix = inverseMcModelViewProjectionMatrix;
Mat4f inverseDhModelViewProjectionMatrix = new Mat4f(renderParams.dhProjectionMatrix); DhMat4f inverseDhModelViewProjectionMatrix = new DhMat4f(renderParams.dhProjectionMatrix);
inverseDhModelViewProjectionMatrix.multiply(renderParams.dhModelViewMatrix); inverseDhModelViewProjectionMatrix.multiply(renderParams.dhModelViewMatrix);
inverseDhModelViewProjectionMatrix.invert(); inverseDhModelViewProjectionMatrix.invert();
Mat4f inverseDhMvmProjMatrix = inverseDhModelViewProjectionMatrix; DhMat4f inverseDhMvmProjMatrix = inverseDhModelViewProjectionMatrix;
// upload data // // upload data //
this.fragUniformBufferWrapper
ByteBuffer buffer = ByteBuffer.allocateDirect(uniformBufferSize);
buffer.order(ByteOrder.nativeOrder());
buffer = Std140Builder.intoBuffer(buffer)
.putInt(Config.Client.Advanced.Debugging.lodOnlyMode.get() ? 1 : 0) // uOnlyRenderLods .putInt(Config.Client.Advanced.Debugging.lodOnlyMode.get() ? 1 : 0) // uOnlyRenderLods
.putFloat(fadeStartDistance) // uStartFadeBlockDistance .putFloat(fadeStartDistance) // uStartFadeBlockDistance
.putFloat(fadeEndDistance) // uEndFadeBlockDistance .putFloat(fadeEndDistance) // uEndFadeBlockDistance
.putFloat(renderParams.clientLevelWrapper.getMaxHeight()) // uMaxLevelHeight .putFloat(renderParams.clientLevelWrapper.getMaxHeight()) // uMaxLevelHeight
.putMat4f(inverseDhMvmProjMatrix.createJomlMatrix()) // uDhInvMvmProj .putMat4f(inverseDhMvmProjMatrix) // uDhInvMvmProj
.putMat4f(inverseMcMvmProjMatrix.createJomlMatrix()) // uMcInvMvmProj .putMat4f(inverseMcMvmProjMatrix) // uMcInvMvmProj
.get() .putInt((RENDER_API_DEF.getRenderDepth() == EDhRenderDepth.REVERSE_Z) ? 1 : 0) // uIsReverseZDepth
.finishAndUpload()
; ;
this.fragUniformBuffer = BlazeUniformUtil.createBuffer("fragUniformBlock", uniformBufferSize, this.fragUniformBuffer);
GpuBufferSlice bufferSlice = new GpuBufferSlice(this.fragUniformBuffer, 0, uniformBufferSize);
COMMAND_ENCODER.writeToBuffer(bufferSlice, buffer);
} }
@@ -234,28 +208,26 @@ public class BlazeVanillaFadeRenderer implements IDhVanillaFadeRenderer
private void renderFadeToTexture() private void renderFadeToTexture()
{ {
try (RenderPass renderPass = COMMAND_ENCODER.createRenderPass( try (RenderPassWrapper renderPassWrapper = new RenderPassWrapper(
this::getRenderPassName, this::getRenderPassName,
this.fadeColorTextureWrapper.textureView, this.fadeColorTextureWrapper,
/*optionalClearColorAsInt*/ OptionalInt.empty(), this.fadeDepthTextureWrapper))
this.fadeDepthTextureWrapper.textureView,
/*optionalDepthValueAsDouble*/ OptionalDouble.empty()))
{ {
renderPass.bindTexture("uMcDepthTexture", this.mcDepthTextureWrapper.textureView, this.mcDepthTextureWrapper.textureSampler); renderPassWrapper.bindTexture("uMcDepthTexture", this.mcDepthTextureWrapper);
renderPass.bindTexture("uCombinedMcDhColorTexture", this.mcColorTextureWrapper.textureView, this.mcColorTextureWrapper.textureSampler); renderPassWrapper.bindTexture("uCombinedMcDhColorTexture", this.mcColorTextureWrapper);
renderPass.bindTexture("uDhDepthTexture", BlazeDhMetaRenderer.INSTANCE.dhDepthTextureWrapper.textureView, BlazeDhMetaRenderer.INSTANCE.dhDepthTextureWrapper.textureSampler); renderPassWrapper.bindTexture("uDhDepthTexture", BlazeDhMetaRenderer.INSTANCE.dhDepthTextureWrapper);
renderPass.bindTexture("uDhColorTexture", BlazeDhMetaRenderer.INSTANCE.dhColorTextureWrapper.textureView, BlazeDhMetaRenderer.INSTANCE.dhColorTextureWrapper.textureSampler); renderPassWrapper.bindTexture("uDhColorTexture", BlazeDhMetaRenderer.INSTANCE.dhColorTextureWrapper);
renderPass.setUniform("fragUniformBlock", this.fragUniformBuffer); renderPassWrapper.setUniform("fragUniformBlock", this.fragUniformBufferWrapper);
renderPass.setVertexBuffer(0, this.vboGpuBuffer); // vertex buffer can only be "0" lol renderPassWrapper.setVertexBuffer(this.vboGpuBuffer);
renderPass.setPipeline(this.pipeline); renderPassWrapper.setPipeline(this.pipeline);
renderPass.draw(/*indexStart*/ 0, /*indexCount*/ 4); renderPassWrapper.draw(/*indexCount*/ 4);
} }
} }
private String getRenderPassName() { return "distantHorizons:McFadeRenderer"; } private String getRenderPassName() { return "distantHorizons:VanillaFadeRenderer"; }
//endregion //endregion
@@ -35,6 +35,8 @@ import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.textures.*; import com.mojang.blaze3d.textures.*;
import com.mojang.blaze3d.vertex.VertexFormat; import com.mojang.blaze3d.vertex.VertexFormat;
import com.seibel.distanthorizons.common.render.blaze.util.BlazeDhVertexFormatUtil; import com.seibel.distanthorizons.common.render.blaze.util.BlazeDhVertexFormatUtil;
import com.seibel.distanthorizons.common.render.blaze.wrappers.BlazeVertexFormatBuilder;
import com.seibel.distanthorizons.common.render.blaze.wrappers.RenderPassWrapper;
import com.seibel.distanthorizons.common.render.blaze.wrappers.RenderPipelineBuilderWrapper; 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.BlazeTextureViewWrapper;
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftRenderWrapper; import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftRenderWrapper;
@@ -107,7 +109,7 @@ public class BlazeDhTestTriangleRenderer implements IDhTestTriangleRenderer
pipelineBuilder.withVertexShader("test/blaze/vert"); pipelineBuilder.withVertexShader("test/blaze/vert");
pipelineBuilder.withFragmentShader("test/blaze/frag"); pipelineBuilder.withFragmentShader("test/blaze/frag");
VertexFormat vertexFormat = VertexFormat.builder() VertexFormat vertexFormat = new BlazeVertexFormatBuilder()
.add("vPosition", BlazeDhVertexFormatUtil.SCREEN_POS) .add("vPosition", BlazeDhVertexFormatUtil.SCREEN_POS)
.add("vColor", BlazeDhVertexFormatUtil.RGBA_FLOAT_COLOR) .add("vColor", BlazeDhVertexFormatUtil.RGBA_FLOAT_COLOR)
.build(); .build();
@@ -168,16 +170,14 @@ public class BlazeDhTestTriangleRenderer implements IDhTestTriangleRenderer
this.mcColorTextureViewWrapper.tryWrap(MinecraftRenderWrapper.INSTANCE.getRenderTarget().getColorTexture()); this.mcColorTextureViewWrapper.tryWrap(MinecraftRenderWrapper.INSTANCE.getRenderTarget().getColorTexture());
this.mcDepthTextureViewWrapper.tryWrap(MinecraftRenderWrapper.INSTANCE.getRenderTarget().getDepthTexture()); this.mcDepthTextureViewWrapper.tryWrap(MinecraftRenderWrapper.INSTANCE.getRenderTarget().getDepthTexture());
try (RenderPass renderPass = COMMAND_ENCODER.createRenderPass( try (RenderPassWrapper renderPassWrapper = new RenderPassWrapper(
this::getRenderPassName, this::getRenderPassName,
this.mcColorTextureViewWrapper.textureView, this.mcColorTextureViewWrapper,
/*optionalClearColorAsInt*/ OptionalInt.empty(), this.mcDepthTextureViewWrapper))
this.mcDepthTextureViewWrapper.textureView,
/*optionalDepthValueAsDouble*/ OptionalDouble.empty()))
{ {
renderPass.setVertexBuffer(0, this.vboGpuBuffer); renderPassWrapper.setVertexBuffer(this.vboGpuBuffer);
renderPass.setPipeline(this.pipeline); renderPassWrapper.setPipeline(this.pipeline);
renderPass.draw(/*indexStart*/ 0, /*indexCount*/ 3); renderPassWrapper.draw(3);
} }
} }
private String getRenderPassName() { return "distantHorizons:DhTestRenderer"; } private String getRenderPassName() { return "distantHorizons:DhTestRenderer"; }
@@ -4,10 +4,9 @@ package com.seibel.distanthorizons.common.render.blaze.util;
public class BlazeDhVertexFormatUtil {} public class BlazeDhVertexFormatUtil {}
#else #else
import com.mojang.blaze3d.GpuFormat;
import com.mojang.blaze3d.vertex.VertexFormatElement; import com.mojang.blaze3d.vertex.VertexFormatElement;
import com.seibel.distanthorizons.api.enums.config.EDhApiRenderApi; import com.seibel.distanthorizons.api.enums.config.EDhApiRenderingEngine;
import com.seibel.distanthorizons.core.config.Config; import com.seibel.distanthorizons.core.config.Config;
import com.seibel.distanthorizons.core.dataObjects.render.bufferBuilding.LodQuadBuilder; import com.seibel.distanthorizons.core.dataObjects.render.bufferBuilding.LodQuadBuilder;
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
@@ -17,6 +16,11 @@ import com.seibel.distanthorizons.core.wrapperInterfaces.IVersionConstants;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
#if MC_VER <= MC_26_1_2
#else
import com.mojang.blaze3d.GpuFormat;
#endif
/** /**
* @see LodQuadBuilder * @see LodQuadBuilder
*/ */
@@ -44,14 +48,14 @@ public class BlazeDhVertexFormatUtil
static static
{ {
EDhApiRenderApi renderingApi = Config.Client.Advanced.Graphics.Experimental.renderingApi.get(); EDhApiRenderingEngine renderingApi = Config.Client.Advanced.Graphics.Experimental.renderingEngine.get();
if (renderingApi == EDhApiRenderApi.AUTO) if (renderingApi == EDhApiRenderingEngine.AUTO)
{ {
IVersionConstants versionConstants = SingletonInjector.INSTANCE.get(IVersionConstants.class); IVersionConstants versionConstants = SingletonInjector.INSTANCE.get(IVersionConstants.class);
renderingApi = versionConstants.getDefaultRenderingApi(); renderingApi = versionConstants.getDefaultRenderingEngine();
} }
boolean register = (renderingApi == EDhApiRenderApi.BLAZE_3D); boolean register = (renderingApi == EDhApiRenderingEngine.BLAZE_3D);
if (register) if (register)
{ {
LOGGER.debug("Attempting to register ["+VertexFormatElement.class.getSimpleName()+"]..."); LOGGER.debug("Attempting to register ["+VertexFormatElement.class.getSimpleName()+"]...");
@@ -84,7 +88,7 @@ public class BlazeDhVertexFormatUtil
IRIS_NORMAL = VertexFormatElement.register(/*id*/29, /*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); FLOAT_XYZ_POS = VertexFormatElement.register(/*id*/30, /*index*/0, VertexFormatElement.Type.FLOAT, false, /*count*/ 3);
#else #elif MC_VER <= MC_26_1_2
SCREEN_POS = VertexFormatElement.register(/*id*/22, /*index*/0, GpuFormat.RG32_FLOAT); // 2 floats SCREEN_POS = VertexFormatElement.register(/*id*/22, /*index*/0, GpuFormat.RG32_FLOAT); // 2 floats
RGBA_FLOAT_COLOR = VertexFormatElement.register(/*id*/23, /*index*/0, GpuFormat.RGBA32_FLOAT); // 4 floats RGBA_FLOAT_COLOR = VertexFormatElement.register(/*id*/23, /*index*/0, GpuFormat.RGBA32_FLOAT); // 4 floats
@@ -98,6 +102,21 @@ public class BlazeDhVertexFormatUtil
IRIS_NORMAL = VertexFormatElement.register(/*id*/29, /*index*/0, GpuFormat.R8_UINT); // 1 byte IRIS_NORMAL = VertexFormatElement.register(/*id*/29, /*index*/0, GpuFormat.R8_UINT); // 1 byte
FLOAT_XYZ_POS = VertexFormatElement.register(/*id*/30, /*index*/0, GpuFormat.RGB32_FLOAT); // 3 floats FLOAT_XYZ_POS = VertexFormatElement.register(/*id*/30, /*index*/0, GpuFormat.RGB32_FLOAT); // 3 floats
#else
SCREEN_POS = new VertexFormatElement("Screen Pos", Float.BYTES * 2, GpuFormat.RG32_FLOAT);
RGBA_FLOAT_COLOR = new VertexFormatElement("RGBA Float Color", Float.BYTES * 4, GpuFormat.RGBA32_FLOAT);
SHORT_XYZ_POS = new VertexFormatElement("Short XYZ Pos", Short.BYTES * 3, GpuFormat.RGB16_UINT);
BYTE_PAD = new VertexFormatElement("Byte Pad", 1, GpuFormat.R8_UINT);
META = new VertexFormatElement("DH Meta", Short.BYTES, GpuFormat.R16_UINT);
RGBA_UBYTE_COLOR = new VertexFormatElement("Rgba Ubyte Color", 4, GpuFormat.RGBA8_UNORM);
IRIS_MATERIAL = new VertexFormatElement("Iris Material", 1, GpuFormat.R8_UINT);
IRIS_NORMAL = new VertexFormatElement("Iris Normal", 1, GpuFormat.R8_UINT);
FLOAT_XYZ_POS = new VertexFormatElement("Float XYZ Pos", Float.BYTES * 3, GpuFormat.RGB32_FLOAT);
#endif #endif
} }
catch (Exception e) catch (Exception e)
@@ -133,5 +152,7 @@ public class BlazeDhVertexFormatUtil
} }
#endif #endif
@@ -11,6 +11,7 @@ import com.mojang.blaze3d.systems.CommandEncoder;
import com.mojang.blaze3d.systems.GpuDevice; import com.mojang.blaze3d.systems.GpuDevice;
import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.VertexFormat; import com.mojang.blaze3d.vertex.VertexFormat;
import com.seibel.distanthorizons.common.render.blaze.wrappers.BlazeVertexFormatBuilder;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.ByteOrder; import java.nio.ByteOrder;
@@ -67,7 +68,7 @@ public class BlazePostProcessUtil
public static VertexFormat createVertexFormat() public static VertexFormat createVertexFormat()
{ {
VertexFormat vertexFormat = VertexFormat.builder() VertexFormat vertexFormat = new BlazeVertexFormatBuilder()
.add("vPosition", BlazeDhVertexFormatUtil.SCREEN_POS) .add("vPosition", BlazeDhVertexFormatUtil.SCREEN_POS)
.build(); .build();
return vertexFormat; return vertexFormat;
@@ -0,0 +1,58 @@
package com.seibel.distanthorizons.common.render.blaze.wrappers;
#if MC_VER <= MC_1_21_10
public class BlazeVertexFormatBuilder {}
#else
import com.mojang.blaze3d.vertex.VertexFormat;
import com.mojang.blaze3d.vertex.VertexFormatElement;
import com.seibel.distanthorizons.common.render.blaze.util.BlazeDhVertexFormatUtil;
public class BlazeVertexFormatBuilder
{
private final VertexFormat.Builder builder;
//=============//
// constructor //
//=============//
//region
public BlazeVertexFormatBuilder()
{
#if MC_VER <= MC_26_1_2
this.builder = VertexFormat.builder();
#else
this.builder = VertexFormat.builder(0);
#endif
}
//endregion
//==========//
// building //
//==========//
//region
public BlazeVertexFormatBuilder add(String name, VertexFormatElement element)
{
#if MC_VER <= MC_26_1_2
this.builder.add(name, element);
#else
this.builder.addAttribute(name, element.format());
#endif
return this;
}
public VertexFormat build() { return this.builder.build(); }
//endregion
}
#endif
@@ -0,0 +1,163 @@
package com.seibel.distanthorizons.common.render.blaze.wrappers;
#if MC_VER <= MC_1_21_10
public class RenderPassWrapper {}
#else
import com.mojang.blaze3d.buffers.GpuBuffer;
import com.mojang.blaze3d.pipeline.RenderPipeline;
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.wrappers.texture.IDhBlazeTexture;
import com.seibel.distanthorizons.common.render.blaze.wrappers.uniform.BlazeUniformBufferWrapper;
import com.seibel.distanthorizons.core.logging.DhLogger;
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import java.util.Optional;
import java.util.OptionalDouble;
import java.util.OptionalInt;
import java.util.function.Supplier;
#if MC_VER <= MC_26_1_2
#else
import com.mojang.blaze3d.IndexType;
#endif
public class RenderPassWrapper implements AutoCloseable
{
public static final DhLogger LOGGER = new DhLoggerBuilder().build();
private static final GpuDevice GPU_DEVICE = RenderSystem.getDevice();
private static final CommandEncoder COMMAND_ENCODER = GPU_DEVICE.createCommandEncoder();
private final RenderPass renderPass;
//=============//
// constructor //
//=============//
//region
public RenderPassWrapper(
final Supplier<String> nameGetterFunc,
final IDhBlazeTexture colorTexture,
final IDhBlazeTexture depthTexture)
{
#if MC_VER <= MC_26_1_2
this.renderPass = COMMAND_ENCODER.createRenderPass(
nameGetterFunc,
colorTexture.getTextureView(),
/*optionalClearColorAsInt*/ OptionalInt.empty(),
depthTexture.getTextureView(),
/*optionalDepthValueAsDouble*/ OptionalDouble.empty());
#else
this.renderPass = COMMAND_ENCODER.createRenderPass(
nameGetterFunc,
colorTexture.getTextureView(),
/*clearColor*/ Optional.empty(),
depthTexture.getTextureView(),
/*clearDepth*/ OptionalDouble.empty());
#endif
}
//endregion
//=======//
// setup //
//=======//
//region
public void bindTexture(
final String name,
final IDhBlazeTexture textureView)
{
this.renderPass.bindTexture(
name,
textureView.getTextureView(),
textureView.getTextureSampler());
}
public void setVertexBuffer(GpuBuffer buffer)
{
#if MC_VER <= MC_26_1_2
this.renderPass.setVertexBuffer(/*slot*/0, buffer);
#else
this.renderPass.setVertexBuffer(/*slot*/0, buffer.slice());
#endif
}
public void setIndexBuffer(GpuBuffer buffer)
{
#if MC_VER <= MC_26_1_2
this.renderPass.setIndexBuffer(buffer, VertexFormat.IndexType.INT);
#else
this.renderPass.setIndexBuffer(buffer, IndexType.INT);
#endif
}
public void setUniform(String uniformName, BlazeUniformBufferWrapper uniformBuffer) { this.renderPass.setUniform(uniformName, uniformBuffer.getGpuBuffer()); }
public void setPipeline(RenderPipeline pipeline) { this.renderPass.setPipeline(pipeline); }
//endregion
//===========//
// rendering //
//===========//
//region
public void draw(int vertexCount)
{
#if MC_VER <= MC_26_1_2
this.renderPass.draw(0, vertexCount);
#else
this.renderPass.draw(vertexCount, /*instanceCount*/1, /*firstVertex*/0, /*firstInstance*/0);
#endif
}
public void drawIndexed(int indexCount)
{
#if MC_VER <= MC_26_1_2
this.renderPass.drawIndexed(
/*indexStart*/ 0,
/*firstIndex*/0,
indexCount,
/*instanceCount*/1);
#else
this.renderPass.drawIndexed(
indexCount,
/*instanceCount*/1,
/*firstVertex*/0,
/*vertexOffset*/0,
/*firstInstance*/0);
#endif
}
//endregion
//================//
// base overrides //
//================//
//region
@Override
public void close() { this.renderPass.close(); }
//endregion
}
#endif
@@ -6,7 +6,6 @@ public class RenderPipelineBuilderWrapper {}
#else #else
import com.mojang.blaze3d.GpuFormat;
import com.mojang.blaze3d.pipeline.*; import com.mojang.blaze3d.pipeline.*;
import com.mojang.blaze3d.platform.PolygonMode; import com.mojang.blaze3d.platform.PolygonMode;
import com.mojang.blaze3d.shaders.UniformType; import com.mojang.blaze3d.shaders.UniformType;
@@ -15,8 +14,12 @@ import net.minecraft.resources.Identifier;
#if MC_VER <= MC_1_21_11 #if MC_VER <= MC_1_21_11
import com.mojang.blaze3d.platform.DepthTestFunction; import com.mojang.blaze3d.platform.DepthTestFunction;
#elif MC_VER <= MC_26_1_2
import com.mojang.blaze3d.platform.CompareOp;
#else #else
import com.mojang.blaze3d.platform.CompareOp; import com.mojang.blaze3d.platform.CompareOp;
import com.mojang.blaze3d.GpuFormat;
import com.mojang.blaze3d.PrimitiveTopology;
#endif #endif
import java.io.IOException; import java.io.IOException;
@@ -254,18 +257,31 @@ public class RenderPipelineBuilderWrapper
case LESS: case LESS:
compareOp = CompareOp.LESS_THAN; compareOp = CompareOp.LESS_THAN;
break; break;
case GREATER:
compareOp = CompareOp.GREATER_THAN;
break;
default: default:
throw new UnsupportedOperationException("No depth test defined for type ["+this.depthTest+"]."); throw new UnsupportedOperationException("No depth test defined for type ["+this.depthTest+"].");
} }
this.blazePipelineBuilder.withDepthStencilState(new DepthStencilState(compareOp, this.writeDepth)); this.blazePipelineBuilder.withDepthStencilState(new DepthStencilState(compareOp, this.writeDepth));
#if MC_VER <= MC_26_1_2
this.blazePipelineBuilder.withColorTargetState( this.blazePipelineBuilder.withColorTargetState(
new ColorTargetState( new ColorTargetState(
Optional.ofNullable(this.blendFunction), Optional.ofNullable(this.blendFunction),
this.writeColor ? ColorTargetState.WRITE_ALL : ColorTargetState.WRITE_NONE this.writeColor ? ColorTargetState.WRITE_ALL : ColorTargetState.WRITE_NONE
) )
); );
#else
this.blazePipelineBuilder.withColorTargetState(
new ColorTargetState(
Optional.ofNullable(this.blendFunction),
GpuFormat.RGBA8_UNORM,
this.writeColor ? ColorTargetState.WRITE_ALL : ColorTargetState.WRITE_NONE
)
);
#endif
#endif #endif
} }
@@ -273,6 +289,7 @@ public class RenderPipelineBuilderWrapper
// vertex format // vertex format
{ {
#if MC_VER <= MC_26_1_2
VertexFormat.Mode blazeVertexMode; VertexFormat.Mode blazeVertexMode;
switch (this.vertexMode) switch (this.vertexMode)
{ {
@@ -291,6 +308,29 @@ public class RenderPipelineBuilderWrapper
} }
this.blazePipelineBuilder.withVertexFormat(vertexFormat, blazeVertexMode); this.blazePipelineBuilder.withVertexFormat(vertexFormat, blazeVertexMode);
#else
PrimitiveTopology primitiveTopology;
switch (this.vertexMode)
{
case TRIANGLES:
primitiveTopology = PrimitiveTopology.TRIANGLES;
break;
case TRIANGLE_FAN:
primitiveTopology = PrimitiveTopology.TRIANGLE_FAN;
break;
case LINES:
primitiveTopology = PrimitiveTopology.DEBUG_LINES;
break;
default:
throw new UnsupportedOperationException("No PrimitiveTopology defined for type ["+this.vertexMode+"].");
}
this.blazePipelineBuilder.withVertexBinding(0, vertexFormat);
this.blazePipelineBuilder.withPrimitiveTopology(primitiveTopology);
#endif
} }
@@ -378,6 +418,7 @@ public class RenderPipelineBuilderWrapper
public enum EDhDepthTest public enum EDhDepthTest
{ {
NONE, NONE,
GREATER,
LESS; LESS;
} }
@@ -18,7 +18,6 @@ import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import com.seibel.distanthorizons.core.render.RenderThreadTaskHandler; import com.seibel.distanthorizons.core.render.RenderThreadTaskHandler;
import com.seibel.distanthorizons.core.wrapperInterfaces.render.AbstractDhRenderApiDefinition; import com.seibel.distanthorizons.core.wrapperInterfaces.render.AbstractDhRenderApiDefinition;
import com.seibel.distanthorizons.core.wrapperInterfaces.render.objects.IVertexBufferWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.render.objects.IVertexBufferWrapper;
import org.lwjgl.system.MemoryUtil;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
@@ -83,9 +82,6 @@ public class BlazeVertexBufferWrapper implements IVertexBufferWrapper
GpuBufferSlice bufferSlice = new GpuBufferSlice(GLOBAL_INDEX_GPU_BUFFER, /*offset*/ 0, indexBuffer.capacity()); GpuBufferSlice bufferSlice = new GpuBufferSlice(GLOBAL_INDEX_GPU_BUFFER, /*offset*/ 0, indexBuffer.capacity());
COMMAND_ENCODER.writeToBuffer(bufferSlice, indexBuffer); COMMAND_ENCODER.writeToBuffer(bufferSlice, indexBuffer);
MemoryUtil.memFree(indexBuffer);
}); });
} }
} }
@@ -14,7 +14,7 @@ import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import java.util.OptionalDouble; import java.util.OptionalDouble;
public class BlazeTextureViewWrapper public class BlazeTextureViewWrapper implements IDhBlazeTexture
{ {
public static final DhLogger LOGGER = new DhLoggerBuilder().build(); public static final DhLogger LOGGER = new DhLoggerBuilder().build();
@@ -22,8 +22,11 @@ public class BlazeTextureViewWrapper
private static final CommandEncoder COMMAND_ENCODER = GPU_DEVICE.createCommandEncoder(); private static final CommandEncoder COMMAND_ENCODER = GPU_DEVICE.createCommandEncoder();
public GpuTextureView textureView = null; private GpuTextureView textureView = null;
public GpuSampler textureSampler = null; public GpuTextureView getTextureView() { return this.textureView; }
private GpuSampler textureSampler = null;
public GpuSampler getTextureSampler() { return this.textureSampler; }
@@ -22,9 +22,10 @@ import com.mojang.blaze3d.textures.*;
#else #else
import com.mojang.blaze3d.GpuFormat; import com.mojang.blaze3d.GpuFormat;
import org.joml.Vector4f;
#endif #endif
public class BlazeTextureWrapper public class BlazeTextureWrapper implements IDhBlazeTexture
{ {
public static final DhLogger LOGGER = new DhLoggerBuilder().build(); public static final DhLogger LOGGER = new DhLoggerBuilder().build();
@@ -42,8 +43,13 @@ public class BlazeTextureWrapper
#endif #endif
public GpuTexture texture = null; public GpuTexture texture = null;
public GpuTextureView textureView = null;
public GpuSampler textureSampler = null; private GpuTextureView textureView = null;
public GpuTextureView getTextureView() { return this.textureView; }
private GpuSampler textureSampler = null;
public GpuSampler getTextureSampler() { return this.textureSampler; }
private int width = -1; private int width = -1;
private int height = -1; private int height = -1;
@@ -185,7 +191,18 @@ public class BlazeTextureWrapper
{ {
if (this.texture != null) if (this.texture != null)
{ {
#if MC_VER <= MC_26_1_2
COMMAND_ENCODER.clearColorTexture(this.texture, clearArgbColor); COMMAND_ENCODER.clearColorTexture(this.texture, clearArgbColor);
#else
Vector4f clearColor = new Vector4f(
// color values should be between 0.0 and 1.0
ColorUtil.getRed(clearArgbColor) / 255.0f,
ColorUtil.getGreen(clearArgbColor) / 255.0f,
ColorUtil.getBlue(clearArgbColor) / 255.0f,
ColorUtil.getAlpha(clearArgbColor) / 255.0f
);
COMMAND_ENCODER.clearColorTexture(this.texture, clearColor);
#endif
} }
} }
@@ -0,0 +1,17 @@
package com.seibel.distanthorizons.common.render.blaze.wrappers.texture;
#if MC_VER <= MC_1_21_10
public interface IDhBlazeTexture {}
#else
import com.mojang.blaze3d.textures.GpuSampler;
import com.mojang.blaze3d.textures.GpuTextureView;
public interface IDhBlazeTexture
{
GpuTextureView getTextureView();
GpuSampler getTextureSampler();
}
#endif
@@ -5,14 +5,10 @@ public class BlazeLodUniformBufferWrapper {}
#else #else
import com.mojang.blaze3d.buffers.Std140Builder;
import com.mojang.blaze3d.buffers.Std140SizeCalculator;
import com.seibel.distanthorizons.core.dataObjects.render.bufferBuilding.LodBufferContainer; import com.seibel.distanthorizons.core.dataObjects.render.bufferBuilding.LodBufferContainer;
import com.seibel.distanthorizons.core.util.math.Vec3f; import com.seibel.distanthorizons.core.util.math.DhVec3f;
import com.seibel.distanthorizons.core.wrapperInterfaces.render.objects.ILodContainerUniformBufferWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.render.objects.ILodContainerUniformBufferWrapper;
import java.nio.ByteBuffer;
public class BlazeLodUniformBufferWrapper extends BlazeUniformBufferWrapper implements ILodContainerUniformBufferWrapper public class BlazeLodUniformBufferWrapper extends BlazeUniformBufferWrapper implements ILodContainerUniformBufferWrapper
{ {
@@ -37,35 +33,22 @@ public class BlazeLodUniformBufferWrapper extends BlazeUniformBufferWrapper impl
//region //region
@Override @Override
public void createUniformData(LodBufferContainer bufferContainer) public void tryUpload(LodBufferContainer bufferContainer)
{
Vec3f modelOffset = new Vec3f(
(float) (bufferContainer.minCornerBlockPos.getX()),
(float) (bufferContainer.minCornerBlockPos.getY()),
(float) (bufferContainer.minCornerBlockPos.getZ()));
// upload data //
int uniformBufferSize = new Std140SizeCalculator()
.putVec3() // uModelOffset
.get();
ByteBuffer buffer = this.getOrCreateBuffer(uniformBufferSize);
Std140Builder.intoBuffer(buffer)
.putVec3(modelOffset.x, modelOffset.y, modelOffset.z) // uModelOffset
.get();
}
@Override
public void tryUpload()
{ {
if (this.uploaded) if (this.uploaded)
{ {
return; return;
} }
this.upload(); DhVec3f modelOffset = new DhVec3f(
(float) (bufferContainer.minCornerBlockPos.getX()),
(float) (bufferContainer.minCornerBlockPos.getY()),
(float) (bufferContainer.minCornerBlockPos.getZ()));
// upload data //
this
.putVec3f(modelOffset.x, modelOffset.y, modelOffset.z) // uModelOffset
.finishAndUpload();
this.uploaded = true; this.uploaded = true;
} }
@@ -7,17 +7,22 @@ public class BlazeUniformBufferWrapper {}
import com.mojang.blaze3d.buffers.GpuBuffer; import com.mojang.blaze3d.buffers.GpuBuffer;
import com.mojang.blaze3d.buffers.GpuBufferSlice; import com.mojang.blaze3d.buffers.GpuBufferSlice;
import com.mojang.blaze3d.buffers.Std140Builder;
import com.mojang.blaze3d.buffers.Std140SizeCalculator;
import com.mojang.blaze3d.systems.CommandEncoder; import com.mojang.blaze3d.systems.CommandEncoder;
import com.mojang.blaze3d.systems.GpuDevice; import com.mojang.blaze3d.systems.GpuDevice;
import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.systems.RenderSystem;
import com.seibel.distanthorizons.api.objects.math.DhApiMat4f;
import com.seibel.distanthorizons.common.render.blaze.util.BlazeUniformUtil;
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.wrapperInterfaces.render.objects.IUniformBufferWrapper; import com.seibel.distanthorizons.core.util.math.DhMat4f;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.ByteOrder; import java.nio.ByteOrder;
import java.util.ArrayList;
public class BlazeUniformBufferWrapper implements IUniformBufferWrapper public class BlazeUniformBufferWrapper implements AutoCloseable
{ {
private static final DhLogger LOGGER = new DhLoggerBuilder().build(); private static final DhLogger LOGGER = new DhLoggerBuilder().build();
@@ -27,11 +32,22 @@ public class BlazeUniformBufferWrapper implements IUniformBufferWrapper
private final String name; private final String name;
private int cpuBufferSize = 0; /** measured in bytes */
private int gpuBufferSize = 0; private int bufferSize = 0;
private ByteBuffer cpuBuffer = null; private ByteBuffer cpuBuffer = null;
public GpuBuffer gpuBuffer = null;
private GpuBuffer gpuBuffer = null;
public GpuBuffer getGpuBuffer() { return this.gpuBuffer; }
private GpuBufferSlice bufferSlice = null;
/** the element count the current CPU Buffer is sized for */
private int previousElementCount = 0;
/** how many elements are currently in flight (ie being added to the buffer right now) */
private int elementCount = 0;
/** used to resize the buffers dur first-time setup */
private final ArrayList<EUniformElement> uniformElementTypes = new ArrayList<>(0);
private Std140Builder uniformBufferBuilder = null;
@@ -46,63 +62,135 @@ public class BlazeUniformBufferWrapper implements IUniformBufferWrapper
//========// //=================//
// render // // element builder //
//========// //=================//
//region //region
protected ByteBuffer getOrCreateBuffer(int size) public BlazeUniformBufferWrapper putVec2f(float x, float y)
{ {
if (this.cpuBuffer == null this.putElement(EUniformElement.VEC2f);
|| this.cpuBufferSize != size) this.uniformBufferBuilder.putVec2(x,y);
return this;
}
public BlazeUniformBufferWrapper putVec3i(int x, int y, int z)
{
this.putElement(EUniformElement.VEC3i);
this.uniformBufferBuilder.putIVec3(x,y,z);
return this;
}
public BlazeUniformBufferWrapper putVec3f(float x, float y, float z)
{
this.putElement(EUniformElement.VEC3f);
this.uniformBufferBuilder.putVec3(x,y,z);
return this;
}
public BlazeUniformBufferWrapper putVec4f(float x, float y, float z, float w)
{
this.putElement(EUniformElement.VEC4f);
this.uniformBufferBuilder.putVec4(x,y,z,w);
return this;
}
public BlazeUniformBufferWrapper putMat4f(DhApiMat4f matrix)
{
this.putElement(EUniformElement.MAT4f);
this.uniformBufferBuilder.putMat4f(DhMat4f.createJomlMatrix(matrix));
return this;
}
public BlazeUniformBufferWrapper putFloat(float f)
{
this.putElement(EUniformElement.FLOAT);
this.uniformBufferBuilder.putFloat(f);
return this;
}
public BlazeUniformBufferWrapper putInt(int i)
{
this.putElement(EUniformElement.INT);
this.uniformBufferBuilder.putInt(i);
return this;
}
private void putElement(EUniformElement elementTypeEnum)
{
this.uniformElementTypes.add(elementTypeEnum);
boolean createNewBuilder = (this.elementCount == 0);
this.elementCount++;
if (this.elementCount > this.previousElementCount)
{ {
this.cpuBuffer = ByteBuffer.allocateDirect(size); this.recreateCpuBuffer();
this.cpuBuffer.order(ByteOrder.nativeOrder()); createNewBuilder = true;
this.cpuBufferSize = size;
} }
return this.cpuBuffer; if (createNewBuilder)
{
this.uniformBufferBuilder = Std140Builder.intoBuffer(this.cpuBuffer);
}
}
private void recreateCpuBuffer()
{
ByteBuffer oldBuffer = this.cpuBuffer;
int size = calcBufferSize(this.uniformElementTypes);
this.cpuBuffer = ByteBuffer.allocateDirect(size);
this.cpuBuffer.order(ByteOrder.nativeOrder());
if (oldBuffer != null)
{
oldBuffer.position(0);
this.cpuBuffer.put(oldBuffer);
}
this.bufferSize = size;
this.previousElementCount = this.elementCount;
}
private static int calcBufferSize(ArrayList<EUniformElement> uniformElements)
{
Std140SizeCalculator calculator = new Std140SizeCalculator();
for (int i = 0; i < uniformElements.size(); i++)
{
EUniformElement element = uniformElements.get(i);
switch (element)
{
case VEC2f -> calculator.putVec2();
case VEC3i -> calculator.putIVec3();
case VEC3f -> calculator.putVec3();
case VEC4f -> calculator.putVec4();
case MAT4f -> calculator.putMat4f();
case INT -> calculator.putInt();
case FLOAT -> calculator.putFloat();
default -> throw new UnsupportedOperationException("No definition for element type ["+element.name()+"]");
}
}
return calculator.get();
} }
@Override
public void upload() throws IllegalStateException
public void finishAndUpload()
{ {
if (this.cpuBuffer == null) // re-create the GPU buffer if needed
GpuBuffer oldGpuBuffer = this.gpuBuffer;
this.gpuBuffer = BlazeUniformUtil.createBuffer(this.name, this.bufferSize, this.gpuBuffer);
boolean createNewBufferSlice = (this.bufferSlice == null || this.gpuBuffer != oldGpuBuffer);
if (createNewBufferSlice)
{ {
throw new IllegalStateException("Upload called before buffer was created"); this.bufferSlice = new GpuBufferSlice(this.gpuBuffer, 0, this.bufferSize);
} }
if (this.gpuBuffer == null // upload to GPU
|| this.gpuBufferSize != this.cpuBufferSize) this.cpuBuffer.position(0);
{ COMMAND_ENCODER.writeToBuffer(this.bufferSlice, this.cpuBuffer);
if (this.gpuBuffer != null)
{
this.gpuBuffer.close();
}
int usage = GpuBuffer.USAGE_COPY_DST
| GpuBuffer.USAGE_VERTEX
| GpuBuffer.USAGE_UNIFORM;
this.gpuBuffer = GPU_DEVICE.createBuffer(this::getBufferName, usage, this.cpuBufferSize);
this.gpuBufferSize = this.cpuBufferSize;
}
// clear the element tracking for next time
int byteSize = (this.cpuBuffer.limit() - this.cpuBuffer.position()); this.elementCount = 0;
GpuBufferSlice bufferSlice = new GpuBufferSlice(this.gpuBuffer, /*offset*/0, byteSize); this.uniformElementTypes.clear();
if (!bufferSlice.buffer().isClosed()) this.uniformBufferBuilder = null;
{
COMMAND_ENCODER.writeToBuffer(bufferSlice, this.cpuBuffer);
}
else
{
LOGGER.warn("Uploading to buffer ["+this.name+"] failed due to already being closed");
}
} }
private String getBufferName() { return this.name; }
//endregion //endregion
@@ -126,5 +214,24 @@ public class BlazeUniformBufferWrapper implements IUniformBufferWrapper
//================//
// helper classes //
//================//
//region
private enum EUniformElement
{
VEC2f,
VEC3f,
VEC3i,
VEC4f,
MAT4f,
INT,
FLOAT,
}
//endregion
} }
#endif #endif
@@ -30,7 +30,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.render.RenderParams; import com.seibel.distanthorizons.core.render.RenderParams;
import com.seibel.distanthorizons.core.render.renderer.AbstractDebugWireframeRenderer; import com.seibel.distanthorizons.core.render.renderer.AbstractDebugWireframeRenderer;
import com.seibel.distanthorizons.core.util.math.Mat4f; import com.seibel.distanthorizons.core.util.math.DhMat4f;
import org.lwjgl.opengl.GL32; import org.lwjgl.opengl.GL32;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
@@ -178,10 +178,10 @@ public class GlDhDebugWireframeRenderer extends AbstractDebugWireframeRenderer
@Override @Override
public void renderBox(Box box) public void renderBox(Box box)
{ {
Mat4f boxTransform = Mat4f.createTranslateMatrix(box.minPos.x - this.camPosFloatThisFrame.x, box.minPos.y - this.camPosFloatThisFrame.y, box.minPos.z - this.camPosFloatThisFrame.z); DhMat4f boxTransform = DhMat4f.createTranslateMatrix(box.minPos.x - this.camPosFloatThisFrame.x, box.minPos.y - this.camPosFloatThisFrame.y, box.minPos.z - this.camPosFloatThisFrame.z);
boxTransform.multiply(Mat4f.createScaleMatrix(box.maxPos.x - box.minPos.x, box.maxPos.y - box.minPos.y, box.maxPos.z - box.minPos.z)); boxTransform.multiply(DhMat4f.createScaleMatrix(box.maxPos.x - box.minPos.x, box.maxPos.y - box.minPos.y, box.maxPos.z - box.minPos.z));
Mat4f transformMatrix = this.dhMvmProjMatrixThisFrame.copy(); DhMat4f transformMatrix = this.dhMvmProjMatrixThisFrame.copy();
transformMatrix.multiply(boxTransform); transformMatrix.multiply(boxTransform);
this.basicShader.setUniform(this.basicShader.getUniformLocation("uTransform"), transformMatrix); this.basicShader.setUniform(this.basicShader.getUniformLocation("uTransform"), transformMatrix);
@@ -71,6 +71,11 @@ public class GlDhMetaRenderer implements IDhMetaRenderer
/** used in case there's an API override */ /** used in case there's an API override */
public IDhApiShaderProgram shaderProgramForThisFrame; public IDhApiShaderProgram shaderProgramForThisFrame;
/** Older MC versions assume GL state is unchanged, so we must restore it after DH rendering */
#if MC_VER <= MC_1_12_2
private int previousBoundTextureId;
private int previousDepthFunc;
#endif
//============// //============//
@@ -113,6 +118,11 @@ public class GlDhMetaRenderer implements IDhMetaRenderer
DhApiRenderParam renderEventParam, DhApiRenderParam renderEventParam,
boolean firstPass) boolean firstPass)
{ {
#if MC_VER <= MC_1_12_2
this.previousBoundTextureId = GLMC.getActiveTexture();
this.previousDepthFunc = GLMC.getActiveDepthFunc();
#endif
//===================// //===================//
// framebuffer setup // // framebuffer setup //
//===================// //===================//
@@ -357,7 +367,9 @@ public class GlDhMetaRenderer implements IDhMetaRenderer
} }
} }
#if MC_VER <= MC_1_12_2
GLMC.glDepthFunc(previousDepthFunc);
#endif
this.unbindLightmap(); this.unbindLightmap();
this.shaderProgramForThisFrame.unbind(); this.shaderProgramForThisFrame.unbind();
} }
@@ -455,8 +467,12 @@ public class GlDhMetaRenderer implements IDhMetaRenderer
public void unbindLightmap() public void unbindLightmap()
{ {
// strange that we don't call "glActiveTexture" here but since it's working James isn't going to change it right now (2026-03-10) // strange that we don't call "glActiveTexture" here but since it's working James isn't going to change it right now (2026-03-10)
GLMC.glBindTexture(0); #if MC_VER <= MC_1_12_2
GLMC.glBindTexture(previousBoundTextureId);
#else
GLMC.glBindTexture(0);
#endif
} }
//endregion //endregion
@@ -1,5 +1,7 @@
package com.seibel.distanthorizons.common.render.openGl; package com.seibel.distanthorizons.common.render.openGl;
import com.seibel.distanthorizons.api.enums.config.EDhApiRenderingApi;
import com.seibel.distanthorizons.api.enums.config.EDhApiRenderingEngine;
import com.seibel.distanthorizons.common.render.openGl.generic.GlGenericObjectRenderer; import com.seibel.distanthorizons.common.render.openGl.generic.GlGenericObjectRenderer;
import com.seibel.distanthorizons.common.render.openGl.generic.GlGenericObjectVertexContainer; import com.seibel.distanthorizons.common.render.openGl.generic.GlGenericObjectVertexContainer;
import com.seibel.distanthorizons.common.render.openGl.glObject.GlDummyUniformData; import com.seibel.distanthorizons.common.render.openGl.glObject.GlDummyUniformData;
@@ -8,8 +10,8 @@ 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.fade.GlVanillaFadeRenderer;
import com.seibel.distanthorizons.common.render.openGl.postProcessing.fog.GlDhFogRenderer; 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.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.common.render.openGl.test.GlTestTriangleRenderer;
import com.seibel.distanthorizons.core.render.EDhRenderDepth;
import com.seibel.distanthorizons.core.render.renderer.AbstractDebugWireframeRenderer; import com.seibel.distanthorizons.core.render.renderer.AbstractDebugWireframeRenderer;
import com.seibel.distanthorizons.core.wrapperInterfaces.render.AbstractDhRenderApiDefinition; import com.seibel.distanthorizons.core.wrapperInterfaces.render.AbstractDhRenderApiDefinition;
import com.seibel.distanthorizons.core.wrapperInterfaces.render.objects.IDhGenericObjectVertexBufferContainer; import com.seibel.distanthorizons.core.wrapperInterfaces.render.objects.IDhGenericObjectVertexBufferContainer;
@@ -24,7 +26,17 @@ public class GlDhRenderApiDefinition extends AbstractDhRenderApiDefinition
//=========// //=========//
//region //region
public String getApiName() { return "OpenGL"; } public String getEngineName() { return "OpenGL"; }
public EDhRenderDepth getRenderDepth()
{
// reversed Z shouldn't be supported on OpenGL due
// to that breaking Iris shaders
return EDhRenderDepth.FORWARD_Z;
}
public EDhApiRenderingApi getRenderApi() { return EDhApiRenderingApi.OPEN_GL; }
public boolean isNativeRenderer() { return true; }
//endregion //endregion
@@ -45,7 +45,7 @@ import com.seibel.distanthorizons.core.render.renderer.RenderableBoxGroup;
import com.seibel.distanthorizons.core.util.LodUtil; import com.seibel.distanthorizons.core.util.LodUtil;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IProfilerWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IProfilerWrapper;
import com.seibel.distanthorizons.core.util.math.Vec3d; import com.seibel.distanthorizons.core.util.math.DhVec3d;
import com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass.IDhGenericRenderer; import com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass.IDhGenericRenderer;
import com.seibel.distanthorizons.coreapi.DependencyInjection.ApiEventInjector; import com.seibel.distanthorizons.coreapi.DependencyInjection.ApiEventInjector;
import com.seibel.distanthorizons.coreapi.DependencyInjection.OverrideInjector; import com.seibel.distanthorizons.coreapi.DependencyInjection.OverrideInjector;
@@ -53,10 +53,10 @@ import com.seibel.distanthorizons.coreapi.ModInfo;
import org.lwjgl.opengl.ARBInstancedArrays; import org.lwjgl.opengl.ARBInstancedArrays;
import org.lwjgl.opengl.GL32; import org.lwjgl.opengl.GL32;
import org.lwjgl.opengl.GL33; import org.lwjgl.opengl.GL33;
import org.lwjgl.system.MemoryUtil;
import java.awt.*; import java.awt.*;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.*; import java.util.*;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
@@ -75,6 +75,7 @@ public class GlGenericObjectRenderer implements IDhGenericRenderer
private static final DhApiRenderableBoxGroupShading DEFAULT_SHADING = DhApiRenderableBoxGroupShading.getUnshaded(); private static final DhApiRenderableBoxGroupShading DEFAULT_SHADING = DhApiRenderableBoxGroupShading.getUnshaded();
private static final DhApiBeforeGenericObjectRenderEvent.EventParam EVENT_PARAM = new DhApiBeforeGenericObjectRenderEvent.EventParam();
/** /**
* Can be used to troubleshoot the renderer. * Can be used to troubleshoot the renderer.
@@ -225,22 +226,22 @@ public class GlGenericObjectRenderer implements IDhGenericRenderer
private void createBuffers() private void createBuffers()
{ {
// box vertices // box vertices
ByteBuffer boxVerticesBuffer = MemoryUtil.memAlloc(BOX_VERTICES.length * Float.BYTES); ByteBuffer boxVerticesBuffer = ByteBuffer.allocateDirect(BOX_VERTICES.length * Float.BYTES);
boxVerticesBuffer.order(ByteOrder.nativeOrder());
boxVerticesBuffer.asFloatBuffer().put(BOX_VERTICES); boxVerticesBuffer.asFloatBuffer().put(BOX_VERTICES);
boxVerticesBuffer.rewind(); boxVerticesBuffer.rewind();
this.boxVertexBuffer = new GLVertexBuffer(false); this.boxVertexBuffer = new GLVertexBuffer(false);
this.boxVertexBuffer.bind(); this.boxVertexBuffer.bind();
this.boxVertexBuffer.uploadBuffer(boxVerticesBuffer, 8, EDhApiGpuUploadMethod.DATA, BOX_VERTICES.length * Float.BYTES); this.boxVertexBuffer.uploadBuffer(boxVerticesBuffer, 8, EDhApiGpuUploadMethod.DATA, BOX_VERTICES.length * Float.BYTES);
MemoryUtil.memFree(boxVerticesBuffer);
// box vertex indexes // box vertex indexes
ByteBuffer solidIndexBuffer = MemoryUtil.memAlloc(BOX_INDICES.length * Integer.BYTES); ByteBuffer solidIndexBuffer = ByteBuffer.allocateDirect(BOX_INDICES.length * Integer.BYTES);
solidIndexBuffer.order(ByteOrder.nativeOrder());
solidIndexBuffer.asIntBuffer().put(BOX_INDICES); solidIndexBuffer.asIntBuffer().put(BOX_INDICES);
solidIndexBuffer.rewind(); solidIndexBuffer.rewind();
this.boxIndexBuffer = new GLIndexBuffer(false); this.boxIndexBuffer = new GLIndexBuffer(false);
this.boxIndexBuffer.uploadBuffer(solidIndexBuffer, EDhApiGpuUploadMethod.DATA, BOX_INDICES.length * Integer.BYTES, GL32.GL_STATIC_DRAW); this.boxIndexBuffer.uploadBuffer(solidIndexBuffer, EDhApiGpuUploadMethod.DATA, BOX_INDICES.length * Integer.BYTES, GL32.GL_STATIC_DRAW);
this.boxIndexBuffer.bind(); this.boxIndexBuffer.bind();
MemoryUtil.memFree(solidIndexBuffer);
} }
private void addGenericDebugObjects() private void addGenericDebugObjects()
{ {
@@ -418,7 +419,7 @@ public class GlGenericObjectRenderer implements IDhGenericRenderer
this.init(); this.init();
ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeGenericRenderSetupEvent.class, renderEventParam); ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeGenericRenderSetupEvent.class, renderEventParam.apiCopy);
boolean renderWireframe = Config.Client.Advanced.Debugging.renderWireframe.get(); boolean renderWireframe = Config.Client.Advanced.Debugging.renderWireframe.get();
@@ -449,8 +450,6 @@ public class GlGenericObjectRenderer implements IDhGenericRenderer
this.boxIndexBuffer.bind(); this.boxIndexBuffer.bind();
Vec3d camPos = MC_RENDER.getCameraExactPosition();
// rendering // // rendering //
@@ -482,7 +481,8 @@ public class GlGenericObjectRenderer implements IDhGenericRenderer
} }
// allow API users to cancel this object's rendering // allow API users to cancel this object's rendering
boolean cancelRendering = ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeGenericObjectRenderEvent.class, new DhApiBeforeGenericObjectRenderEvent.EventParam(renderEventParam, boxGroup)); EVENT_PARAM.update(renderEventParam, boxGroup);
boolean cancelRendering = ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeGenericObjectRenderEvent.class, EVENT_PARAM);
if (cancelRendering) if (cancelRendering)
{ {
continue; continue;
@@ -510,11 +510,11 @@ public class GlGenericObjectRenderer implements IDhGenericRenderer
{ {
if (this.instancedRenderingAvailable) if (this.instancedRenderingAvailable)
{ {
this.renderBoxGroupInstanced(shaderProgram, renderEventParam, boxGroup, camPos, profiler); this.renderBoxGroupInstanced(shaderProgram, renderEventParam, boxGroup, renderEventParam.exactCameraPosition, profiler);
} }
else else
{ {
this.renderBoxGroupDirect(shaderProgram, renderEventParam, boxGroup, camPos, profiler); this.renderBoxGroupDirect(shaderProgram, renderEventParam, boxGroup, renderEventParam.exactCameraPosition, profiler);
} }
} }
@@ -529,7 +529,7 @@ public class GlGenericObjectRenderer implements IDhGenericRenderer
profiler.popPush("cleanup"); profiler.popPush("cleanup");
ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeGenericRenderCleanupEvent.class, renderEventParam); ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeGenericRenderCleanupEvent.class, renderEventParam.apiCopy);
if (renderWireframe) if (renderWireframe)
{ {
@@ -553,7 +553,7 @@ public class GlGenericObjectRenderer implements IDhGenericRenderer
private void renderBoxGroupInstanced( private void renderBoxGroupInstanced(
IDhApiGenericObjectShaderProgram shaderProgram, DhApiRenderParam renderEventParam, IDhApiGenericObjectShaderProgram shaderProgram, DhApiRenderParam renderEventParam,
RenderableBoxGroup boxGroup, Vec3d camPos, RenderableBoxGroup boxGroup, DhVec3d camPos,
IProfilerWrapper profiler) IProfilerWrapper profiler)
{ {
try (IProfilerWrapper.IProfileBlock render_profile = profiler.push("vertex setup")) try (IProfilerWrapper.IProfileBlock render_profile = profiler.push("vertex setup"))
@@ -654,7 +654,7 @@ public class GlGenericObjectRenderer implements IDhGenericRenderer
private void renderBoxGroupDirect( private void renderBoxGroupDirect(
IDhApiGenericObjectShaderProgram shaderProgram, IDhApiGenericObjectShaderProgram shaderProgram,
DhApiRenderParam renderEventParam, DhApiRenderParam renderEventParam,
RenderableBoxGroup boxGroup, Vec3d camPos, RenderableBoxGroup boxGroup, DhVec3d camPos,
IProfilerWrapper profiler) IProfilerWrapper profiler)
{ {
profiler.popPush("shared uniforms"); profiler.popPush("shared uniforms");
@@ -12,8 +12,8 @@ import com.seibel.distanthorizons.common.render.openGl.glObject.vertexAttribute.
import com.seibel.distanthorizons.common.render.openGl.glObject.vertexAttribute.GlVertexPointer; import com.seibel.distanthorizons.common.render.openGl.glObject.vertexAttribute.GlVertexPointer;
import com.seibel.distanthorizons.common.wrappers.misc.LightMapWrapper; import com.seibel.distanthorizons.common.wrappers.misc.LightMapWrapper;
import com.seibel.distanthorizons.core.util.LodUtil; import com.seibel.distanthorizons.core.util.LodUtil;
import com.seibel.distanthorizons.core.util.math.Mat4f; import com.seibel.distanthorizons.core.util.math.DhMat4f;
import com.seibel.distanthorizons.core.util.math.Vec3f; import com.seibel.distanthorizons.core.util.math.DhVec3f;
public class GlGenericObjectShaderProgram extends GlShaderProgram implements IDhApiGenericObjectShaderProgram public class GlGenericObjectShaderProgram extends GlShaderProgram implements IDhApiGenericObjectShaderProgram
{ {
@@ -123,7 +123,7 @@ public class GlGenericObjectShaderProgram extends GlShaderProgram implements IDh
DhApiVec3d camPos DhApiVec3d camPos
) )
{ {
Mat4f projectionMvmMatrix = new Mat4f(renderParameters.dhProjectionMatrix); DhMat4f projectionMvmMatrix = new DhMat4f(renderParameters.dhProjectionMatrix);
projectionMvmMatrix.multiply(renderParameters.dhModelViewMatrix); projectionMvmMatrix.multiply(renderParameters.dhModelViewMatrix);
super.bind(); super.bind();
@@ -138,7 +138,7 @@ public class GlGenericObjectShaderProgram extends GlShaderProgram implements IDh
LodUtil.getChunkPosFromDouble(boxGroup.getOriginBlockPos().z) LodUtil.getChunkPosFromDouble(boxGroup.getOriginBlockPos().z)
)); ));
this.setUniform(this.instancedShaderOffsetSubChunkUniform, this.setUniform(this.instancedShaderOffsetSubChunkUniform,
new Vec3f( new DhVec3f(
LodUtil.getSubChunkPosFromDouble(boxGroup.getOriginBlockPos().x), LodUtil.getSubChunkPosFromDouble(boxGroup.getOriginBlockPos().x),
LodUtil.getSubChunkPosFromDouble(boxGroup.getOriginBlockPos().y), LodUtil.getSubChunkPosFromDouble(boxGroup.getOriginBlockPos().y),
LodUtil.getSubChunkPosFromDouble(boxGroup.getOriginBlockPos().z) LodUtil.getSubChunkPosFromDouble(boxGroup.getOriginBlockPos().z)
@@ -151,7 +151,7 @@ public class GlGenericObjectShaderProgram extends GlShaderProgram implements IDh
LodUtil.getChunkPosFromDouble(camPos.z) LodUtil.getChunkPosFromDouble(camPos.z)
)); ));
this.setUniform(this.instancedShaderCameraSubChunkPosUniform, this.setUniform(this.instancedShaderCameraSubChunkPosUniform,
new Vec3f( new DhVec3f(
LodUtil.getSubChunkPosFromDouble(camPos.x), LodUtil.getSubChunkPosFromDouble(camPos.x),
LodUtil.getSubChunkPosFromDouble(camPos.y), LodUtil.getSubChunkPosFromDouble(camPos.y),
LodUtil.getSubChunkPosFromDouble(camPos.z) LodUtil.getSubChunkPosFromDouble(camPos.z)
@@ -201,14 +201,14 @@ public class GlGenericObjectShaderProgram extends GlShaderProgram implements IDh
IDhApiRenderableBoxGroup boxGroup, DhApiRenderableBox box, IDhApiRenderableBoxGroup boxGroup, DhApiRenderableBox box,
DhApiVec3d camPos) DhApiVec3d camPos)
{ {
Mat4f projectionMvmMatrix = new Mat4f(renderParameters.dhProjectionMatrix); DhMat4f projectionMvmMatrix = new DhMat4f(renderParameters.dhProjectionMatrix);
projectionMvmMatrix.multiply(renderParameters.dhModelViewMatrix); projectionMvmMatrix.multiply(renderParameters.dhModelViewMatrix);
Mat4f boxTransform = Mat4f.createTranslateMatrix( DhMat4f boxTransform = DhMat4f.createTranslateMatrix(
(float) (box.minPos.x + boxGroup.getOriginBlockPos().x - camPos.x), (float) (box.minPos.x + boxGroup.getOriginBlockPos().x - camPos.x),
(float) (box.minPos.y + boxGroup.getOriginBlockPos().y - camPos.y), (float) (box.minPos.y + boxGroup.getOriginBlockPos().y - camPos.y),
(float) (box.minPos.z + boxGroup.getOriginBlockPos().z - camPos.z)); (float) (box.minPos.z + boxGroup.getOriginBlockPos().z - camPos.z));
boxTransform.multiply(Mat4f.createScaleMatrix( boxTransform.multiply(DhMat4f.createScaleMatrix(
(float) (box.maxPos.x - box.minPos.x), (float) (box.maxPos.x - box.minPos.x),
(float) (box.maxPos.y - box.minPos.y), (float) (box.maxPos.y - box.minPos.y),
(float) (box.maxPos.z - box.minPos.z))); (float) (box.maxPos.z - box.minPos.z)));
@@ -21,9 +21,9 @@ package com.seibel.distanthorizons.common.render.openGl.glObject;
import com.seibel.distanthorizons.api.enums.config.EDhApiGLErrorHandlingMode; import com.seibel.distanthorizons.api.enums.config.EDhApiGLErrorHandlingMode;
import com.seibel.distanthorizons.api.enums.config.EDhApiGpuUploadMethod; import com.seibel.distanthorizons.api.enums.config.EDhApiGpuUploadMethod;
import com.seibel.distanthorizons.api.enums.config.EDhApiLoggerLevel; import com.seibel.distanthorizons.api.enums.config.EDhApiRenderingApi;
import com.seibel.distanthorizons.api.enums.config.EDhApiRenderingEngine;
import com.seibel.distanthorizons.core.config.Config; import com.seibel.distanthorizons.core.config.Config;
import com.seibel.distanthorizons.core.config.types.ConfigEntry;
import com.seibel.distanthorizons.core.dependencyInjection.ModAccessorInjector; import com.seibel.distanthorizons.core.dependencyInjection.ModAccessorInjector;
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
import com.seibel.distanthorizons.core.jar.EPlatform; import com.seibel.distanthorizons.core.jar.EPlatform;
@@ -32,6 +32,7 @@ import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import com.seibel.distanthorizons.core.util.objects.GLMessages.*; import com.seibel.distanthorizons.core.util.objects.GLMessages.*;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IIrisAccessor; import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IIrisAccessor;
import com.seibel.distanthorizons.core.wrapperInterfaces.render.AbstractDhRenderApiDefinition;
import com.seibel.distanthorizons.coreapi.ModInfo; import com.seibel.distanthorizons.coreapi.ModInfo;
import org.lwjgl.glfw.GLFW; import org.lwjgl.glfw.GLFW;
import org.lwjgl.opengl.GL; import org.lwjgl.opengl.GL;
@@ -51,6 +52,9 @@ import java.util.concurrent.ConcurrentHashMap;
public class GLProxy public class GLProxy
{ {
private static final IIrisAccessor IRIS_ACCESSOR = ModAccessorInjector.INSTANCE.get(IIrisAccessor.class); private static final IIrisAccessor IRIS_ACCESSOR = ModAccessorInjector.INSTANCE.get(IIrisAccessor.class);
private static final IMinecraftClientWrapper MC_CLIENT = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class);
private static final AbstractDhRenderApiDefinition RENDER_API_DEF = SingletonInjector.INSTANCE.get(AbstractDhRenderApiDefinition.class);
public static final DhLogger LOGGER; public static final DhLogger LOGGER;
static static
@@ -126,15 +130,22 @@ public class GLProxy
private GLProxy() throws IllegalStateException private GLProxy() throws IllegalStateException
{ {
// TODO vulkan complain if created when MC is running on vulkan if (RENDER_API_DEF.getRenderApi() != EDhApiRenderingApi.OPEN_GL)
{
throw new IllegalStateException("[" + GLProxy.class.getSimpleName() + "] was created with the wrong Rendering API ["+RENDER_API_DEF.getRenderApi()+"]!");
}
// this must be created on minecraft's render context to work correctly // this must be created on minecraft's render context to work correctly
if (GLFW.glfwGetCurrentContext() == 0L) if (GLFW.glfwGetCurrentContext() == 0L)
{ {
throw new IllegalStateException(GLProxy.class.getSimpleName() + " was created outside the render thread!"); String message = "[" + GLProxy.class.getSimpleName() + "] was created outside the render thread!";
IllegalStateException exception = new IllegalStateException(message);
MC_CLIENT.crashMinecraft(message, exception);
throw exception;
} }
LOGGER.info("Creating " + GLProxy.class.getSimpleName() + "... If this is the last message you see there must have been an OpenGL error."); LOGGER.info("Creating [" + GLProxy.class.getSimpleName() + "]... If this is the last message you see there must have been an OpenGL error.");
LOGGER.info("Lod Render OpenGL version [" + GL32.glGetString(GL32.GL_VERSION) + "]."); LOGGER.info("Lod Render OpenGL version [" + GL32.glGetString(GL32.GL_VERSION) + "].");
@@ -97,7 +97,9 @@ public class GLState implements AutoCloseable
{ {
this.frameBufferTexture0 = GL32.glGetFramebufferAttachmentParameteri(GL32.GL_FRAMEBUFFER, GL32.GL_COLOR_ATTACHMENT0, GL32.GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME); this.frameBufferTexture0 = GL32.glGetFramebufferAttachmentParameteri(GL32.GL_FRAMEBUFFER, GL32.GL_COLOR_ATTACHMENT0, GL32.GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME);
this.frameBufferTexture1 = GL32.glGetFramebufferAttachmentParameteri(GL32.GL_FRAMEBUFFER, GL32.GL_COLOR_ATTACHMENT1, GL32.GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME); this.frameBufferTexture1 = GL32.glGetFramebufferAttachmentParameteri(GL32.GL_FRAMEBUFFER, GL32.GL_COLOR_ATTACHMENT1, GL32.GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME);
this.frameBufferDepthTexture = GL32.glGetFramebufferAttachmentParameteri(GL32.GL_FRAMEBUFFER, GL32.GL_DEPTH_ATTACHMENT, GL32.GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME);
int depthType = GL32.glGetFramebufferAttachmentParameteri(GL32.GL_FRAMEBUFFER, GL32.GL_DEPTH_ATTACHMENT, GL32.GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE);
this.frameBufferDepthTexture = (depthType == GL32.GL_TEXTURE) ? GL32.glGetFramebufferAttachmentParameteri(GL32.GL_FRAMEBUFFER, GL32.GL_DEPTH_ATTACHMENT, GL32.GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) : 0;
} }
else else
{ {
@@ -179,9 +181,21 @@ public class GLState implements AutoCloseable
// attempting to set textures on the default frame buffer (ID 0) will throw errors // attempting to set textures on the default frame buffer (ID 0) will throw errors
if (frameBufferSet) if (frameBufferSet)
{ {
GL32.glFramebufferTexture2D(GL32.GL_FRAMEBUFFER, GL32.GL_COLOR_ATTACHMENT0, GL32.GL_TEXTURE_2D, this.frameBufferTexture0, 0); if (GL32.glIsTexture(this.frameBufferTexture0))
GL32.glFramebufferTexture2D(GL32.GL_FRAMEBUFFER, GL32.GL_COLOR_ATTACHMENT1, GL32.GL_TEXTURE_2D, this.frameBufferTexture1, 0); {
GL32.glFramebufferTexture2D(GL32.GL_FRAMEBUFFER, GL32.GL_DEPTH_ATTACHMENT, GL32.GL_TEXTURE_2D, this.frameBufferDepthTexture, 0); GL32.glFramebufferTexture2D(GL32.GL_FRAMEBUFFER, GL32.GL_COLOR_ATTACHMENT0, GL32.GL_TEXTURE_2D, this.frameBufferTexture0, 0);
}
if (this.frameBufferTexture1 != 0 && GL32.glIsTexture(this.frameBufferTexture1))
{
GL32.glFramebufferTexture2D(GL32.GL_FRAMEBUFFER, GL32.GL_COLOR_ATTACHMENT1, GL32.GL_TEXTURE_2D, this.frameBufferTexture1, 0);
}
if (GL32.glIsTexture(this.frameBufferDepthTexture))
{
GL32.glFramebufferTexture2D(GL32.GL_FRAMEBUFFER, GL32.GL_DEPTH_ATTACHMENT, GL32.GL_TEXTURE_2D, this.frameBufferDepthTexture, 0);
}
} }
GL32.glBindVertexArray(GL32.glIsVertexArray(this.vao) ? this.vao : 0); GL32.glBindVertexArray(GL32.glIsVertexArray(this.vao) ? this.vao : 0);
@@ -9,9 +9,7 @@ import com.seibel.distanthorizons.core.wrapperInterfaces.render.objects.ILodCont
*/ */
public class GlDummyUniformData implements ILodContainerUniformBufferWrapper public class GlDummyUniformData implements ILodContainerUniformBufferWrapper
{ {
@Override public void createUniformData(LodBufferContainer bufferContainer) { } @Override public void tryUpload(LodBufferContainer bufferContainer) { }
@Override public void tryUpload() { }
@Override public void upload() { }
@Override public void close() { } @Override public void close() { }
} }
@@ -31,7 +31,6 @@ import com.seibel.distanthorizons.core.wrapperInterfaces.render.objects.IVertexB
import org.lwjgl.opengl.GL32; import org.lwjgl.opengl.GL32;
import com.seibel.distanthorizons.api.enums.config.EDhApiGpuUploadMethod; import com.seibel.distanthorizons.api.enums.config.EDhApiGpuUploadMethod;
import org.lwjgl.system.MemoryUtil;
/** /**
* This is a container for a OpenGL * This is a container for a OpenGL
@@ -87,7 +86,6 @@ public class GLVertexBuffer extends GLBuffer implements IVertexBufferWrapper
ByteBuffer buffer = IndexBufferBuilder.createBuffer(maxQuadCount); ByteBuffer buffer = IndexBufferBuilder.createBuffer(maxQuadCount);
GLOBAL_QUAD_IBO.upload(buffer, maxQuadCount); GLOBAL_QUAD_IBO.upload(buffer, maxQuadCount);
MemoryUtil.memFree(buffer);
}); });
} }
} }
@@ -21,11 +21,9 @@ package com.seibel.distanthorizons.common.render.openGl.glObject.buffer;
import com.seibel.distanthorizons.api.enums.config.EDhApiGpuUploadMethod; import com.seibel.distanthorizons.api.enums.config.EDhApiGpuUploadMethod;
import com.seibel.distanthorizons.common.render.openGl.glObject.enums.GLEnums; 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.DhLogger;
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import org.lwjgl.opengl.GL32; import org.lwjgl.opengl.GL32;
import org.lwjgl.system.MemoryUtil;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
@@ -22,12 +22,13 @@ package com.seibel.distanthorizons.common.render.openGl.glObject.shader;
import java.awt.Color; import java.awt.Color;
import java.nio.FloatBuffer; import java.nio.FloatBuffer;
import com.seibel.distanthorizons.api.objects.math.DhApiMat4f;
import com.seibel.distanthorizons.api.objects.math.DhApiVec3i; import com.seibel.distanthorizons.api.objects.math.DhApiVec3i;
import org.lwjgl.opengl.GL32; import org.lwjgl.opengl.GL32;
import org.lwjgl.system.MemoryStack; import org.lwjgl.system.MemoryStack;
import com.seibel.distanthorizons.core.util.math.Mat4f; import com.seibel.distanthorizons.core.util.math.DhMat4f;
import com.seibel.distanthorizons.core.util.math.Vec3f; import com.seibel.distanthorizons.core.util.math.DhVec3f;
/** /**
@@ -181,27 +182,51 @@ public class GlShaderProgram
public void trySetUniform(int location, float value) { if (location != -1) { this.setUniform(location, value); } } public void trySetUniform(int location, float value) { if (location != -1) { this.setUniform(location, value); } }
/** Requires a bound ShaderProgram. */ /** Requires a bound ShaderProgram. */
public void setUniform(int location, Vec3f value) { GL32.glUniform3f(location, value.x, value.y, value.z); } public void setUniform(int location, DhVec3f value) { GL32.glUniform3f(location, value.x, value.y, value.z); }
/** @see GlShaderProgram#setUniform(int, Vec3f) */ /** @see GlShaderProgram#setUniform(int, DhVec3f) */
public void trySetUniform(int location, Vec3f value) { if (location != -1) { this.setUniform(location, value); } } public void trySetUniform(int location, DhVec3f value) { if (location != -1) { this.setUniform(location, value); } }
/** Requires a bound ShaderProgram. */ /** Requires a bound ShaderProgram. */
public void setUniform(int location, DhApiVec3i value) { GL32.glUniform3i(location, value.x, value.y, value.z); } public void setUniform(int location, DhApiVec3i value) { GL32.glUniform3i(location, value.x, value.y, value.z); }
/** @see GlShaderProgram#setUniform(int, Mat4f) */ /** @see GlShaderProgram#setUniform(int, DhApiMat4f) */
public void trySetUniform(int location, DhApiVec3i value) { if (location != -1) { this.setUniform(location, value); } } public void trySetUniform(int location, DhApiVec3i value) { if (location != -1) { this.setUniform(location, value); } }
/** Requires a bound ShaderProgram. */ /** Requires a bound ShaderProgram. */
public void setUniform(int location, Mat4f value) public void setUniform(int location, DhApiMat4f value)
{ {
try (MemoryStack stack = MemoryStack.stackPush()) try (MemoryStack stack = MemoryStack.stackPush())
{ {
FloatBuffer buffer = stack.mallocFloat(4 * 4); FloatBuffer buffer = stack.mallocFloat(16);
value.store(buffer); storeMatrixInBuffer(value, buffer);
GL32.glUniformMatrix4fv(location, false, buffer); GL32.glUniformMatrix4fv(location, false, buffer);
} }
} }
/** @see GlShaderProgram#setUniform(int, Mat4f) */ private static void storeMatrixInBuffer(DhApiMat4f matrix, FloatBuffer floatBuffer)
public void trySetUniform(int location, Mat4f value) { if (location != -1) { this.setUniform(location, value); } } {
floatBuffer.put(bufferIndex(0, 0), matrix.m00);
floatBuffer.put(bufferIndex(0, 1), matrix.m01);
floatBuffer.put(bufferIndex(0, 2), matrix.m02);
floatBuffer.put(bufferIndex(0, 3), matrix.m03);
floatBuffer.put(bufferIndex(1, 0), matrix.m10);
floatBuffer.put(bufferIndex(1, 1), matrix.m11);
floatBuffer.put(bufferIndex(1, 2), matrix.m12);
floatBuffer.put(bufferIndex(1, 3), matrix.m13);
floatBuffer.put(bufferIndex(2, 0), matrix.m20);
floatBuffer.put(bufferIndex(2, 1), matrix.m21);
floatBuffer.put(bufferIndex(2, 2), matrix.m22);
floatBuffer.put(bufferIndex(2, 3), matrix.m23);
floatBuffer.put(bufferIndex(3, 0), matrix.m30);
floatBuffer.put(bufferIndex(3, 1), matrix.m31);
floatBuffer.put(bufferIndex(3, 2), matrix.m32);
floatBuffer.put(bufferIndex(3, 3), matrix.m33);
}
private static int bufferIndex(int xIndex, int zIndex) { return (zIndex * 4) + xIndex; }
/** @see GlShaderProgram#setUniform(int, DhApiMat4f) */
public void trySetUniform(int location, DhMat4f value) { if (location != -1) { this.setUniform(location, value); } }
/** /**
* Converts the color's RGBA values into values between 0 and 1. <br> * Converts the color's RGBA values into values between 0 and 1. <br>
@@ -24,9 +24,9 @@ import com.seibel.distanthorizons.common.render.openGl.glObject.buffer.GLVertexB
import com.seibel.distanthorizons.common.render.openGl.glObject.vertexAttribute.GlAbstractVertexAttribute; import com.seibel.distanthorizons.common.render.openGl.glObject.vertexAttribute.GlAbstractVertexAttribute;
import com.seibel.distanthorizons.common.render.openGl.glObject.vertexAttribute.GlVertexPointer; import com.seibel.distanthorizons.common.render.openGl.glObject.vertexAttribute.GlVertexPointer;
import org.lwjgl.opengl.GL32; import org.lwjgl.opengl.GL32;
import org.lwjgl.system.MemoryUtil;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.ByteOrder;
/** /**
* Renders a full-screen textured quad to the screen. * Renders a full-screen textured quad to the screen.
@@ -76,14 +76,14 @@ public class GlScreenQuad
} }
private void createBuffer() private void createBuffer()
{ {
ByteBuffer buffer = MemoryUtil.memAlloc(BOX_VERTICES.length * Float.BYTES); ByteBuffer buffer = ByteBuffer.allocateDirect(BOX_VERTICES.length * Float.BYTES);
buffer.order(ByteOrder.nativeOrder());
buffer.asFloatBuffer().put(BOX_VERTICES); buffer.asFloatBuffer().put(BOX_VERTICES);
buffer.rewind(); buffer.rewind();
this.boxBuffer = new GLVertexBuffer(false); this.boxBuffer = new GLVertexBuffer(false);
this.boxBuffer.bind(); this.boxBuffer.bind();
this.boxBuffer.uploadBuffer(buffer, BOX_VERTICES.length, EDhApiGpuUploadMethod.DATA, BOX_VERTICES.length * Float.BYTES); this.boxBuffer.uploadBuffer(buffer, BOX_VERTICES.length, EDhApiGpuUploadMethod.DATA, BOX_VERTICES.length * Float.BYTES);
MemoryUtil.memFree(buffer);
} }
//endregion //endregion
@@ -132,7 +132,7 @@ public class GlDhApplyShader extends GlAbstractShaderRenderer
} }
private void renderToMcTexture() private void renderToMcTexture()
{ {
int targetColorTextureId = MC_RENDER.getColorTextureId(); int targetColorTextureId = MC_RENDER.getGlColorTextureId();
if (targetColorTextureId == -1) if (targetColorTextureId == -1)
{ {
return; return;
@@ -136,7 +136,7 @@ public class GlDhFarFadeRenderer implements IDhFarFadeRenderer
GlDhFarFadeShader.INSTANCE.frameBuffer = this.fadeFramebuffer; GlDhFarFadeShader.INSTANCE.frameBuffer = this.fadeFramebuffer;
GlDhFarFadeShader.INSTANCE.setProjectionMatrix(renderParams.mcModelViewMatrix, renderParams.mcProjectionMatrix); GlDhFarFadeShader.INSTANCE.setProjectionMatrix(renderParams);
GlDhFarFadeShader.INSTANCE.render(renderParams); GlDhFarFadeShader.INSTANCE.render(renderParams);
GlDhFarFadeApplyShader.INSTANCE.fadeTexture = this.fadeTexture; GlDhFarFadeApplyShader.INSTANCE.fadeTexture = this.fadeTexture;
@@ -28,7 +28,6 @@ import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
import com.seibel.distanthorizons.common.render.openGl.util.GlAbstractShaderRenderer; import com.seibel.distanthorizons.common.render.openGl.util.GlAbstractShaderRenderer;
import com.seibel.distanthorizons.core.render.RenderParams; import com.seibel.distanthorizons.core.render.RenderParams;
import com.seibel.distanthorizons.core.util.RenderUtil; 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.minecraft.IMinecraftRenderWrapper;
import org.lwjgl.opengl.GL32; import org.lwjgl.opengl.GL32;
@@ -42,7 +41,7 @@ public class GlDhFarFadeShader extends GlAbstractShaderRenderer
public int frameBuffer = -1; public int frameBuffer = -1;
private Mat4f inverseDhMvmProjMatrix; private DhApiMat4f inverseDhMvmProjMatrix;
// Uniforms // Uniforms
@@ -110,15 +109,9 @@ public class GlDhFarFadeShader extends GlAbstractShaderRenderer
} }
public void setProjectionMatrix(DhApiMat4f mcModelViewMatrix, DhApiMat4f mcProjectionMatrix) public void setProjectionMatrix(RenderParams renderParams)
{ {
Mat4f dhProjectionMatrix = RenderUtil.createLodProjectionMatrix(mcProjectionMatrix); this.inverseDhMvmProjMatrix = renderParams.dhInverseMvmProjectionMatrix;
Mat4f dhModelViewMatrix = RenderUtil.createLodModelViewMatrix(mcModelViewMatrix);
Mat4f inverseDhModelViewProjectionMatrix = new Mat4f(dhProjectionMatrix);
inverseDhModelViewProjectionMatrix.multiply(dhModelViewMatrix);
inverseDhModelViewProjectionMatrix.invert();
this.inverseDhMvmProjMatrix = inverseDhModelViewProjectionMatrix;
} }
@@ -153,7 +146,7 @@ public class GlDhFarFadeShader extends GlAbstractShaderRenderer
GL32.glUniform1i(this.uDhDepthTexture, 0); GL32.glUniform1i(this.uDhDepthTexture, 0);
GLMC.glActiveTexture(GL32.GL_TEXTURE1); GLMC.glActiveTexture(GL32.GL_TEXTURE1);
GLMC.glBindTexture(MC_RENDER.getColorTextureId()); GLMC.glBindTexture(MC_RENDER.getGlColorTextureId());
GL32.glUniform1i(this.uMcColorTexture, 1); GL32.glUniform1i(this.uMcColorTexture, 1);
GLMC.glActiveTexture(GL32.GL_TEXTURE2); GLMC.glActiveTexture(GL32.GL_TEXTURE2);
@@ -29,7 +29,6 @@ import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
import com.seibel.distanthorizons.common.render.openGl.util.GlAbstractShaderRenderer; import com.seibel.distanthorizons.common.render.openGl.util.GlAbstractShaderRenderer;
import com.seibel.distanthorizons.core.render.RenderParams; import com.seibel.distanthorizons.core.render.RenderParams;
import com.seibel.distanthorizons.core.util.RenderUtil; 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.minecraft.IMinecraftRenderWrapper;
import org.lwjgl.opengl.GL32; import org.lwjgl.opengl.GL32;
@@ -43,8 +42,8 @@ public class GlDhVanillaFadeShader extends GlAbstractShaderRenderer
public int frameBuffer = -1; public int frameBuffer = -1;
private Mat4f inverseMcMvmProjMatrix; private DhApiMat4f inverseMcMvmProjMatrix;
private Mat4f inverseDhMvmProjMatrix; private DhApiMat4f inverseDhMvmProjMatrix;
private float levelMaxHeight; private float levelMaxHeight;
@@ -136,21 +135,10 @@ public class GlDhVanillaFadeShader extends GlAbstractShaderRenderer
this.shader.setUniform(this.uOnlyRenderLods, Config.Client.Advanced.Debugging.lodOnlyMode.get()); this.shader.setUniform(this.uOnlyRenderLods, Config.Client.Advanced.Debugging.lodOnlyMode.get());
} }
public void setProjectionMatrix(DhApiMat4f mcModelViewMatrix, DhApiMat4f mcProjectionMatrix) public void setProjectionMatrix(RenderParams renderParams)
{ {
Mat4f inverseMcModelViewProjectionMatrix = new Mat4f(mcProjectionMatrix); this.inverseMcMvmProjMatrix = renderParams.mcInverseMvmProjectionMatrix;
inverseMcModelViewProjectionMatrix.multiply(mcModelViewMatrix); this.inverseDhMvmProjMatrix = renderParams.dhInverseMvmProjectionMatrix;
inverseMcModelViewProjectionMatrix.invert();
this.inverseMcMvmProjMatrix = inverseMcModelViewProjectionMatrix;
Mat4f dhProjectionMatrix = RenderUtil.createLodProjectionMatrix(mcProjectionMatrix);
Mat4f dhModelViewMatrix = RenderUtil.createLodModelViewMatrix(mcModelViewMatrix);
Mat4f inverseDhModelViewProjectionMatrix = new Mat4f(dhProjectionMatrix);
inverseDhModelViewProjectionMatrix.multiply(dhModelViewMatrix);
inverseDhModelViewProjectionMatrix.invert();
this.inverseDhMvmProjMatrix = inverseDhModelViewProjectionMatrix;
} }
public void setLevelMaxHeight(int levelMaxHeight) { this.levelMaxHeight = levelMaxHeight; } public void setLevelMaxHeight(int levelMaxHeight) { this.levelMaxHeight = levelMaxHeight; }
@@ -185,7 +173,7 @@ public class GlDhVanillaFadeShader extends GlAbstractShaderRenderer
GLMC.disableBlend(); GLMC.disableBlend();
GLMC.glActiveTexture(GL32.GL_TEXTURE0); GLMC.glActiveTexture(GL32.GL_TEXTURE0);
GLMC.glBindTexture(MC_RENDER.getDepthTextureId()); GLMC.glBindTexture(MC_RENDER.getGlDepthTextureId());
GL32.glUniform1i(this.uMcDepthTexture, 0); GL32.glUniform1i(this.uMcDepthTexture, 0);
GLMC.glActiveTexture(GL32.GL_TEXTURE1); GLMC.glActiveTexture(GL32.GL_TEXTURE1);
@@ -193,7 +181,7 @@ public class GlDhVanillaFadeShader extends GlAbstractShaderRenderer
GL32.glUniform1i(this.uDhDepthTexture, 1); GL32.glUniform1i(this.uDhDepthTexture, 1);
GLMC.glActiveTexture(GL32.GL_TEXTURE2); GLMC.glActiveTexture(GL32.GL_TEXTURE2);
GLMC.glBindTexture(MC_RENDER.getColorTextureId()); GLMC.glBindTexture(MC_RENDER.getGlColorTextureId());
GL32.glUniform1i(this.uCombinedMcDhColorTexture, 2); GL32.glUniform1i(this.uCombinedMcDhColorTexture, 2);
GLMC.glActiveTexture(GL32.GL_TEXTURE3); GLMC.glActiveTexture(GL32.GL_TEXTURE3);
@@ -108,7 +108,7 @@ public class GlVanillaFadeRenderer implements IDhVanillaFadeRenderer
} }
else else
{ {
GL32.glFramebufferTexture2D(GL32.GL_FRAMEBUFFER, GL32.GL_COLOR_ATTACHMENT0, GL32.GL_TEXTURE_2D, MC_RENDER.getColorTextureId(), 0); GL32.glFramebufferTexture2D(GL32.GL_FRAMEBUFFER, GL32.GL_COLOR_ATTACHMENT0, GL32.GL_TEXTURE_2D, MC_RENDER.getGlColorTextureId(), 0);
} }
} }
@@ -152,7 +152,7 @@ public class GlVanillaFadeRenderer implements IDhVanillaFadeRenderer
GlDhVanillaFadeShader.INSTANCE.frameBuffer = this.fadeFramebuffer; GlDhVanillaFadeShader.INSTANCE.frameBuffer = this.fadeFramebuffer;
GlDhVanillaFadeShader.INSTANCE.setProjectionMatrix(renderParams.mcModelViewMatrix, renderParams.mcProjectionMatrix); GlDhVanillaFadeShader.INSTANCE.setProjectionMatrix(renderParams);
GlDhVanillaFadeShader.INSTANCE.setLevelMaxHeight(renderParams.clientLevelWrapper.getMaxHeight()); GlDhVanillaFadeShader.INSTANCE.setLevelMaxHeight(renderParams.clientLevelWrapper.getMaxHeight());
GlDhVanillaFadeShader.INSTANCE.render(renderParams); GlDhVanillaFadeShader.INSTANCE.render(renderParams);
@@ -19,6 +19,7 @@
package com.seibel.distanthorizons.common.render.openGl.postProcessing.fog; package com.seibel.distanthorizons.common.render.openGl.postProcessing.fog;
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiFogRenderParam;
import com.seibel.distanthorizons.common.render.openGl.glObject.GLState; import com.seibel.distanthorizons.common.render.openGl.glObject.GLState;
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftGLWrapper; import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftGLWrapper;
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
@@ -108,7 +109,7 @@ public class GlDhFogRenderer implements IDhFogRenderer
//region //region
@Override @Override
public void render(RenderParams renderParams) public void render(RenderParams renderParams, DhApiFogRenderParam fogRenderParams)
{ {
// GLState needed in MC 1.16.5 probably due to MC not manually setting each GL state they need before the next rendering step // GLState needed in MC 1.16.5 probably due to MC not manually setting each GL state they need before the next rendering step
try (GLState state = new GLState()) try (GLState state = new GLState())
@@ -126,7 +127,7 @@ public class GlDhFogRenderer implements IDhFogRenderer
} }
GlDhFogShader.INSTANCE.frameBuffer = this.fogFramebuffer; GlDhFogShader.INSTANCE.frameBuffer = this.fogFramebuffer;
GlDhFogShader.INSTANCE.setProjectionMatrix(renderParams.dhMvmProjMatrix); GlDhFogShader.INSTANCE.prepUniformObjects(renderParams.dhMvmProjMatrix, fogRenderParams);
GlDhFogShader.INSTANCE.render(renderParams); GlDhFogShader.INSTANCE.render(renderParams);
GlDhFogApplyShader.INSTANCE.fogTexture = this.fogTexture; GlDhFogApplyShader.INSTANCE.fogTexture = this.fogTexture;
@@ -19,9 +19,9 @@
package com.seibel.distanthorizons.common.render.openGl.postProcessing.fog; package com.seibel.distanthorizons.common.render.openGl.postProcessing.fog;
import com.seibel.distanthorizons.api.enums.rendering.EDhApiFogColorMode;
import com.seibel.distanthorizons.api.enums.rendering.EDhApiHeightFogDirection; import com.seibel.distanthorizons.api.enums.rendering.EDhApiHeightFogDirection;
import com.seibel.distanthorizons.api.enums.rendering.EDhApiHeightFogMixMode; import com.seibel.distanthorizons.api.enums.rendering.EDhApiHeightFogMixMode;
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiFogRenderParam;
import com.seibel.distanthorizons.api.objects.math.DhApiMat4f; import com.seibel.distanthorizons.api.objects.math.DhApiMat4f;
import com.seibel.distanthorizons.common.render.openGl.GlDhMetaRenderer; import com.seibel.distanthorizons.common.render.openGl.GlDhMetaRenderer;
import com.seibel.distanthorizons.common.render.openGl.glObject.shader.GlShaderProgram; import com.seibel.distanthorizons.common.render.openGl.glObject.shader.GlShaderProgram;
@@ -33,24 +33,21 @@ import com.seibel.distanthorizons.common.render.openGl.util.GlAbstractShaderRend
import com.seibel.distanthorizons.core.render.RenderParams; import com.seibel.distanthorizons.core.render.RenderParams;
import com.seibel.distanthorizons.core.util.LodUtil; import com.seibel.distanthorizons.core.util.LodUtil;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
import com.seibel.distanthorizons.core.util.math.Mat4f; import com.seibel.distanthorizons.core.util.math.DhMat4f;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
import org.lwjgl.opengl.GL32; import org.lwjgl.opengl.GL32;
import java.awt.*;
public class GlDhFogShader extends GlAbstractShaderRenderer public class GlDhFogShader extends GlAbstractShaderRenderer
{ {
public static final GlDhFogShader INSTANCE = new GlDhFogShader(); public static final GlDhFogShader INSTANCE = new GlDhFogShader();
private static final IMinecraftClientWrapper MC = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class);
private static final MinecraftGLWrapper GLMC = MinecraftGLWrapper.INSTANCE; private static final MinecraftGLWrapper GLMC = MinecraftGLWrapper.INSTANCE;
private static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class);
public int frameBuffer; public int frameBuffer;
private Mat4f inverseMvmProjMatrix; private DhMat4f inverseMvmProjMatrix;
private DhApiFogRenderParam fogRenderParams;
@@ -167,95 +164,58 @@ public class GlDhFogShader extends GlAbstractShaderRenderer
{ {
int lodDrawDistance = Config.Client.Advanced.Graphics.Quality.lodChunkRenderDistanceRadius.get() * LodUtil.CHUNK_WIDTH; int lodDrawDistance = Config.Client.Advanced.Graphics.Quality.lodChunkRenderDistanceRadius.get() * LodUtil.CHUNK_WIDTH;
this.shader.setUniform(this.uInvMvmProj, this.inverseMvmProjMatrix);
if (this.inverseMvmProjMatrix != null)
{
this.shader.setUniform(this.uInvMvmProj, this.inverseMvmProjMatrix);
}
// Fog uniforms // Fog uniforms
this.shader.setUniform(this.uFogColor, this.getFogColor(renderParams.partialTicks)); this.shader.setUniform(this.uFogColor, this.fogRenderParams.getFogColor());
this.shader.setUniform(this.uFogScale, 1.f / lodDrawDistance); this.shader.setUniform(this.uFogScale, 1.f / lodDrawDistance);
this.shader.setUniform(this.uFogVerticalScale, 1.f / MC.getWrappedClientLevel().getMaxHeight()); this.shader.setUniform(this.uFogVerticalScale, 1.f / renderParams.clientLevelWrapper.getMaxHeight());
// only used for debugging this.shader.setUniform(this.uFogDebugMode, 0); // 0 = normal // 1 = render everything with fog color // 7 = use debug rendering
this.shader.setUniform(this.uFogDebugMode, 0); // 1 = render everything with fog color // 7 = use debug rendering this.shader.setUniform(this.uFogFalloffType, this.fogRenderParams.getFarFogFalloff().value);
this.shader.setUniform(this.uFogFalloffType, Config.Client.Advanced.Graphics.Fog.farFogFalloff.get().value);
// fog config // fog config
float farFogStart = Config.Client.Advanced.Graphics.Fog.farFogStart.get(); this.shader.setUniform(this.uFarFogStart, this.fogRenderParams.getFarFogStartPercent());
float farFogEnd = Config.Client.Advanced.Graphics.Fog.farFogEnd.get(); this.shader.setUniform(this.uFarFogLength, this.fogRenderParams.getFarFogEndPercent() - this.fogRenderParams.getFarFogStartPercent());
float farFogMin = Config.Client.Advanced.Graphics.Fog.farFogMin.get(); this.shader.setUniform(this.uFarFogMin, this.fogRenderParams.getFarFogMinThickness());
float farFogMax = Config.Client.Advanced.Graphics.Fog.farFogMax.get(); this.shader.setUniform(this.uFarFogRange, this.fogRenderParams.getFarFogMaxThickness() - this.fogRenderParams.getFarFogMinThickness());
float farFogDensity = Config.Client.Advanced.Graphics.Fog.farFogDensity.get(); this.shader.setUniform(this.uFarFogDensity, this.fogRenderParams.getFarFogDensity());
// override fog if underwater
if (MC_RENDER.isFogStateSpecial())
{
// hide everything behind fog
farFogStart = 0.0f;
farFogEnd = 0.0f;
}
this.shader.setUniform(this.uFarFogStart, farFogStart);
this.shader.setUniform(this.uFarFogLength, farFogEnd - farFogStart);
this.shader.setUniform(this.uFarFogMin, farFogMin);
this.shader.setUniform(this.uFarFogRange, farFogMax - farFogMin);
this.shader.setUniform(this.uFarFogDensity, farFogDensity);
// height config // height config
EDhApiHeightFogMixMode heightFogMixingMode = Config.Client.Advanced.Graphics.Fog.HeightFog.heightFogMixMode.get(); EDhApiHeightFogMixMode heightFogMixingMode = this.fogRenderParams.getHeightFogMixingMode();
boolean heightFogEnabled = heightFogMixingMode != EDhApiHeightFogMixMode.SPHERICAL && heightFogMixingMode != EDhApiHeightFogMixMode.CYLINDRICAL; boolean heightFogEnabled =
heightFogMixingMode != EDhApiHeightFogMixMode.SPHERICAL
&& heightFogMixingMode != EDhApiHeightFogMixMode.CYLINDRICAL;
boolean useSphericalFog = heightFogMixingMode == EDhApiHeightFogMixMode.SPHERICAL; boolean useSphericalFog = heightFogMixingMode == EDhApiHeightFogMixMode.SPHERICAL;
EDhApiHeightFogDirection heightFogCameraDirection = Config.Client.Advanced.Graphics.Fog.HeightFog.heightFogDirection.get(); EDhApiHeightFogDirection heightFogDirection = this.fogRenderParams.getHeightFogDirection();
float heightFogStart = Config.Client.Advanced.Graphics.Fog.HeightFog.heightFogStart.get(); this.shader.setUniform(this.uHeightFogStart, this.fogRenderParams.getHeightFogStartPercent());
float heightFogEnd = Config.Client.Advanced.Graphics.Fog.HeightFog.heightFogEnd.get(); this.shader.setUniform(this.uHeightFogLength, this.fogRenderParams.getHeightFogEndPercent() - this.fogRenderParams.getHeightFogStartPercent());
float heightFogMin = Config.Client.Advanced.Graphics.Fog.HeightFog.heightFogMin.get(); this.shader.setUniform(this.uHeightFogMin, this.fogRenderParams.getFarFogMinThickness());
float heightFogMax = Config.Client.Advanced.Graphics.Fog.HeightFog.heightFogMax.get(); this.shader.setUniform(this.uHeightFogRange, this.fogRenderParams.getFarFogMaxThickness() - this.fogRenderParams.getFarFogMinThickness());
float heightFogDensity = Config.Client.Advanced.Graphics.Fog.HeightFog.heightFogDensity.get(); this.shader.setUniform(this.uHeightFogDensity, this.fogRenderParams.getFarFogDensity());
this.shader.setUniform(this.uHeightFogStart, heightFogStart);
this.shader.setUniform(this.uHeightFogLength, heightFogEnd - heightFogStart);
this.shader.setUniform(this.uHeightFogMin, heightFogMin);
this.shader.setUniform(this.uHeightFogRange, heightFogMax - heightFogMin);
this.shader.setUniform(this.uHeightFogDensity, heightFogDensity);
this.shader.setUniform(this.uHeightFogEnabled, heightFogEnabled); this.shader.setUniform(this.uHeightFogEnabled, heightFogEnabled);
this.shader.setUniform(this.uHeightFogFalloffType, Config.Client.Advanced.Graphics.Fog.HeightFog.heightFogFalloff.get().value); this.shader.setUniform(this.uHeightFogFalloffType, this.fogRenderParams.getHeightFogFalloff().value);
this.shader.setUniform(this.uHeightFogBaseHeight, Config.Client.Advanced.Graphics.Fog.HeightFog.heightFogBaseHeight.get()); this.shader.setUniform(this.uHeightFogBaseHeight, this.fogRenderParams.getHeightFogBaseHeight());
this.shader.setUniform(this.uHeightBasedOnCamera, heightFogCameraDirection.basedOnCamera); this.shader.setUniform(this.uHeightBasedOnCamera, heightFogDirection.basedOnCamera);
this.shader.setUniform(this.uHeightFogAppliesUp, heightFogCameraDirection.fogAppliesUp); this.shader.setUniform(this.uHeightFogAppliesUp, heightFogDirection.fogAppliesUp);
this.shader.setUniform(this.uHeightFogAppliesDown, heightFogCameraDirection.fogAppliesDown); this.shader.setUniform(this.uHeightFogAppliesDown, heightFogDirection.fogAppliesDown);
this.shader.setUniform(this.uUseSphericalFog, useSphericalFog); this.shader.setUniform(this.uUseSphericalFog, useSphericalFog);
this.shader.setUniform(this.uHeightFogMixingMode, heightFogMixingMode.value); this.shader.setUniform(this.uHeightFogMixingMode, heightFogMixingMode.value);
this.shader.setUniform(this.uCameraBlockYPos, (float)MC_RENDER.getCameraExactPosition().y); this.shader.setUniform(this.uCameraBlockYPos, (float)renderParams.exactCameraPosition.y);
} }
private Color getFogColor(float partialTicks)
{
Color fogColor;
if (Config.Client.Advanced.Graphics.Fog.colorMode.get() == EDhApiFogColorMode.USE_SKY_COLOR)
{
fogColor = MC_RENDER.getSkyColor();
}
else
{
fogColor = MC_RENDER.getFogColor(partialTicks);
}
return fogColor;
}
public void setProjectionMatrix(DhApiMat4f modelViewProjectionMatrix) public void prepUniformObjects(DhApiMat4f modelViewProjectionMatrix, DhApiFogRenderParam fogRenderParams)
{ {
this.inverseMvmProjMatrix = new Mat4f(modelViewProjectionMatrix); this.inverseMvmProjMatrix = new DhMat4f(modelViewProjectionMatrix);
this.inverseMvmProjMatrix.invert(); this.inverseMvmProjMatrix.invert();
this.fogRenderParams = fogRenderParams;
} }
//endregion //endregion
@@ -26,7 +26,7 @@ import com.seibel.distanthorizons.common.render.openGl.postProcessing.GlScreenQu
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftGLWrapper; import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftGLWrapper;
import com.seibel.distanthorizons.common.render.openGl.util.GlAbstractShaderRenderer; import com.seibel.distanthorizons.common.render.openGl.util.GlAbstractShaderRenderer;
import com.seibel.distanthorizons.core.render.RenderParams; import com.seibel.distanthorizons.core.render.RenderParams;
import com.seibel.distanthorizons.core.util.math.Mat4f; import com.seibel.distanthorizons.core.util.math.DhMat4f;
import org.lwjgl.opengl.GL32; import org.lwjgl.opengl.GL32;
/** /**
@@ -45,8 +45,8 @@ public class GlDhSSAOShader extends GlAbstractShaderRenderer
public int frameBuffer; public int frameBuffer;
private Mat4f projection; private DhMat4f projection;
private Mat4f invertedProjection; private DhMat4f invertedProjection;
// uniforms // uniforms
@@ -95,9 +95,9 @@ public class GlDhSSAOShader extends GlAbstractShaderRenderer
public void setProjectionMatrix(DhApiMat4f projectionMatrix) public void setProjectionMatrix(DhApiMat4f projectionMatrix)
{ {
this.projection = new Mat4f(projectionMatrix); this.projection = new DhMat4f(projectionMatrix);
this.invertedProjection = new Mat4f(projectionMatrix); this.invertedProjection = new DhMat4f(projectionMatrix);
this.invertedProjection.invert(); this.invertedProjection.invert();
} }
@@ -23,9 +23,9 @@ 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.render.RenderParams; import com.seibel.distanthorizons.core.render.RenderParams;
import com.seibel.distanthorizons.core.util.RenderUtil; import com.seibel.distanthorizons.core.util.RenderUtil;
import com.seibel.distanthorizons.core.util.math.Mat4f; import com.seibel.distanthorizons.core.util.math.DhMat4f;
import com.seibel.distanthorizons.core.util.math.Vec3d; import com.seibel.distanthorizons.core.util.math.DhVec3d;
import com.seibel.distanthorizons.core.util.math.Vec3f; import com.seibel.distanthorizons.core.util.math.DhVec3f;
import com.seibel.distanthorizons.core.util.objects.SortedArraySet; import com.seibel.distanthorizons.core.util.objects.SortedArraySet;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IProfilerWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IProfilerWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IIrisAccessor; import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IIrisAccessor;
@@ -46,6 +46,11 @@ public class GlDhTerrainShaderProgram extends GlShaderProgram implements IDhApiS
private static final MinecraftGLWrapper GLMC = MinecraftGLWrapper.INSTANCE; private static final MinecraftGLWrapper GLMC = MinecraftGLWrapper.INSTANCE;
private static final IIrisAccessor IRIS_ACCESSOR = ModAccessorInjector.INSTANCE.get(IIrisAccessor.class); private static final IIrisAccessor IRIS_ACCESSOR = ModAccessorInjector.INSTANCE.get(IIrisAccessor.class);
private static final DhVec3f MODEL_POS = new DhVec3f();
/** single event object used to reduce GC pressure */
private static final DhApiBeforeBufferRenderEvent.EventParam BEFORE_BUFFER_RENDER_EVENT_PARAM = new DhApiBeforeBufferRenderEvent.EventParam();
private boolean init = false; private boolean init = false;
@@ -194,7 +199,7 @@ public class GlDhTerrainShaderProgram extends GlShaderProgram implements IDhApiS
@Override @Override
public void fillUniformData(DhApiRenderParam renderParameters) public void fillUniformData(DhApiRenderParam renderParameters)
{ {
Mat4f combinedMatrix = new Mat4f(renderParameters.dhProjectionMatrix); DhMat4f combinedMatrix = new DhMat4f(renderParameters.dhProjectionMatrix);
combinedMatrix.multiply(renderParameters.dhModelViewMatrix); combinedMatrix.multiply(renderParameters.dhModelViewMatrix);
super.bind(); super.bind();
@@ -241,7 +246,7 @@ public class GlDhTerrainShaderProgram extends GlShaderProgram implements IDhApiS
} }
@Override @Override
public void setModelOffsetPos(DhApiVec3f modelOffsetPos) { this.setUniform(this.uModelOffset, new Vec3f(modelOffsetPos)); } public void setModelOffsetPos(DhApiVec3f modelOffsetPos) { this.setUniform(this.uModelOffset, new DhVec3f(modelOffsetPos)); }
@Override @Override
public int getId() { return this.id; } public int getId() { return this.id; }
@@ -289,9 +294,13 @@ public class GlDhTerrainShaderProgram extends GlShaderProgram implements IDhApiS
GLMC.disableBlend(); GLMC.disableBlend();
} }
// needs to be explicitly called since Iris may disable color rendering and not re-enable it
// when boats are rendered in the scene (due to rendering out water inside the boat)
GL32.glColorMask(true, true, true, true);
// needs to be triggered after DH attempts to set the GL state so that Iris // needs to be triggered after DH attempts to set the GL state so that Iris
// can override it as needed // can override it as needed
ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeRenderPassEvent.class, renderEventParam); ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeRenderPassEvent.class, renderEventParam.apiCopy);
@@ -323,16 +332,17 @@ public class GlDhTerrainShaderProgram extends GlShaderProgram implements IDhApiS
// set uniforms and fire events // set uniforms and fire events
{ {
Vec3d camPos = renderEventParam.exactCameraPosition; DhVec3d camPos = renderEventParam.exactCameraPosition;
Vec3f modelPos = new Vec3f( MODEL_POS.set(
(float) (bufferContainer.minCornerBlockPos.getX() - camPos.x), (float) (bufferContainer.minCornerBlockPos.getX() - camPos.x),
(float) (bufferContainer.minCornerBlockPos.getY() - camPos.y), (float) (bufferContainer.minCornerBlockPos.getY() - camPos.y),
(float) (bufferContainer.minCornerBlockPos.getZ() - camPos.z)); (float) (bufferContainer.minCornerBlockPos.getZ() - camPos.z));
BEFORE_BUFFER_RENDER_EVENT_PARAM.update(renderEventParam, MODEL_POS);
GlDhMetaRenderer.INSTANCE.shaderProgramForThisFrame.bind(); GlDhMetaRenderer.INSTANCE.shaderProgramForThisFrame.bind();
GlDhMetaRenderer.INSTANCE.shaderProgramForThisFrame.setModelOffsetPos(modelPos); GlDhMetaRenderer.INSTANCE.shaderProgramForThisFrame.setModelOffsetPos(MODEL_POS);
ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeBufferRenderEvent.class, new DhApiBeforeBufferRenderEvent.EventParam(renderEventParam, modelPos)); ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeBufferRenderEvent.class, BEFORE_BUFFER_RENDER_EVENT_PARAM);
} }
IVertexBufferWrapper[] vertexBuffers = (opaquePass ? bufferContainer.vboOpaqueWrappers : bufferContainer.vboTransparentWrappers); IVertexBufferWrapper[] vertexBuffers = (opaquePass ? bufferContainer.vboOpaqueWrappers : bufferContainer.vboTransparentWrappers);
@@ -22,23 +22,34 @@ package com.seibel.distanthorizons.common.util;
import com.seibel.distanthorizons.common.wrappers.world.ClientLevelWrapper; import com.seibel.distanthorizons.common.wrappers.world.ClientLevelWrapper;
import com.seibel.distanthorizons.common.wrappers.world.ServerLevelWrapper; import com.seibel.distanthorizons.common.wrappers.world.ServerLevelWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
#if MC_VER <= MC_1_12_2
import net.minecraft.client.multiplayer.WorldClient;
import net.minecraft.world.World;
import net.minecraft.world.WorldServer;
#else
import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.LevelAccessor; import net.minecraft.world.level.LevelAccessor;
#endif
public class ProxyUtil public class ProxyUtil
{ {
public static ILevelWrapper getLevelWrapper(LevelAccessor level) public static ILevelWrapper getLevelWrapper(
#if MC_VER <= MC_1_12_2 World #else LevelAccessor #endif level
)
{ {
ILevelWrapper levelWrapper; ILevelWrapper levelWrapper;
if (level instanceof ServerLevel) if (level instanceof #if MC_VER <= MC_1_12_2 WorldServer #else ServerLevel #endif)
{ {
levelWrapper = ServerLevelWrapper.getWrapper((ServerLevel) level); levelWrapper = ServerLevelWrapper.getWrapper(
#if MC_VER <= MC_1_12_2 (WorldServer) #else (ServerLevel) #endif level
);
} }
else else
{ {
levelWrapper = ClientLevelWrapper.getWrapper((ClientLevel) level); levelWrapper = ClientLevelWrapper.getWrapper(
#if MC_VER <= MC_1_12_2 (WorldClient) #else (ClientLevel) #endif level
);
} }
return levelWrapper; return levelWrapper;
@@ -19,11 +19,12 @@
package com.seibel.distanthorizons.common.wrappers; package com.seibel.distanthorizons.common.wrappers;
import com.seibel.distanthorizons.api.enums.config.EDhApiRenderApi; import com.seibel.distanthorizons.api.enums.config.EDhApiRenderingEngine;
import com.seibel.distanthorizons.api.interfaces.render.IDhApiCustomRenderObjectFactory; import com.seibel.distanthorizons.api.interfaces.render.IDhApiCustomRenderObjectFactory;
import com.seibel.distanthorizons.common.render.blaze.BlazeDhRenderApiDefinition; import com.seibel.distanthorizons.common.render.blaze.BlazeDhRenderApiDefinition;
import com.seibel.distanthorizons.common.render.openGl.GlDhRenderApiDefinition; import com.seibel.distanthorizons.common.render.openGl.GlDhRenderApiDefinition;
import com.seibel.distanthorizons.core.config.Config; import com.seibel.distanthorizons.core.config.Config;
import com.seibel.distanthorizons.api.enums.config.EDhApiRenderingApi;
import com.seibel.distanthorizons.core.render.renderer.GenericRenderObjectFactory; import com.seibel.distanthorizons.core.render.renderer.GenericRenderObjectFactory;
import com.seibel.distanthorizons.common.wrappers.gui.classicConfig.ClassicConfigGUI; import com.seibel.distanthorizons.common.wrappers.gui.classicConfig.ClassicConfigGUI;
import com.seibel.distanthorizons.common.wrappers.gui.LangWrapper; import com.seibel.distanthorizons.common.wrappers.gui.LangWrapper;
@@ -65,7 +66,7 @@ public class DependencySetup
SingletonInjector.INSTANCE.bind(ILangWrapper.class, LangWrapper.INSTANCE); SingletonInjector.INSTANCE.bind(ILangWrapper.class, LangWrapper.INSTANCE);
SingletonInjector.INSTANCE.bind(IVersionConstants.class, VersionConstants.INSTANCE); SingletonInjector.INSTANCE.bind(IVersionConstants.class, VersionConstants.INSTANCE);
SingletonInjector.INSTANCE.bind(IWrapperFactory.class, WrapperFactory.INSTANCE); SingletonInjector.INSTANCE.bind(IWrapperFactory.class, WrapperFactory.INSTANCE);
SingletonInjector.INSTANCE.bind(IKeyedClientLevelManager.class, KeyedClientLevelManager.INSTANCE); SingletonInjector.INSTANCE.bind(IKeyedClientLevelManager.class, new KeyedClientLevelManager());
SingletonInjector.INSTANCE.bind(IDhApiCustomRenderObjectFactory.class, GenericRenderObjectFactory.INSTANCE); SingletonInjector.INSTANCE.bind(IDhApiCustomRenderObjectFactory.class, GenericRenderObjectFactory.INSTANCE);
} }
@@ -94,25 +95,25 @@ public class DependencySetup
EDhApiRenderApi renderingApiEnum = Config.Client.Advanced.Graphics.Experimental.renderingApi.get(); EDhApiRenderingEngine renderingApiEnum = Config.Client.Advanced.Graphics.Experimental.renderingEngine.get();
if (renderingApiEnum == EDhApiRenderApi.AUTO) if (renderingApiEnum == EDhApiRenderingEngine.AUTO)
{ {
IVersionConstants versionConstants = SingletonInjector.INSTANCE.get(IVersionConstants.class); IVersionConstants versionConstants = SingletonInjector.INSTANCE.get(IVersionConstants.class);
renderingApiEnum = versionConstants.getDefaultRenderingApi(); renderingApiEnum = versionConstants.getDefaultRenderingEngine();
} }
LOGGER.info("Setting DH Rendering API to: ["+renderingApiEnum+"]."); LOGGER.info("Setting DH Rendering API to: ["+renderingApiEnum+"]...");
boolean validApi; boolean validApi;
AbstractDhRenderApiDefinition renderDefinition; AbstractDhRenderApiDefinition renderDefinition;
if (renderingApiEnum == EDhApiRenderApi.OPEN_GL) if (renderingApiEnum == EDhApiRenderingEngine.OPEN_GL)
{ {
validApi = true; validApi = true;
renderDefinition = new GlDhRenderApiDefinition(); renderDefinition = new GlDhRenderApiDefinition();
} }
else if (renderingApiEnum == EDhApiRenderApi.BLAZE_3D) else if (renderingApiEnum == EDhApiRenderingEngine.BLAZE_3D)
{ {
#if MC_VER <= MC_1_21_10 #if MC_VER <= MC_1_21_10
validApi = false; validApi = false;
@@ -133,14 +134,24 @@ public class DependencySetup
// crash if an invalid API is set // crash if an invalid API is set
if (!validApi) if (!validApi)
{ {
String message = "["+renderingApiEnum+"] is not supported on this version of Minecraft, reverting to ["+EDhApiRenderApi.AUTO+"]."; String message = "The Distant Horizons rendering engine ["+renderDefinition.getEngineName()+"]-["+renderingApiEnum+"] is not supported with this Minecraft config, reverting to ["+ EDhApiRenderingEngine.AUTO+"].";
LOGGER.fatal(message);
Config.Client.Advanced.Graphics.Experimental.renderingEngine.set(EDhApiRenderingEngine.AUTO);
throw new IllegalStateException(message);
}
// crash if the rendering API set doesn't match Minecraft's
EDhApiRenderingApi mcRenderApi = MinecraftRenderWrapper.INSTANCE.getMcRenderingApi();
if (mcRenderApi != renderDefinition.getRenderApi())
{
String message = "The Distant Horizons rendering engine ["+renderDefinition.getEngineName()+"]-["+renderDefinition.getRenderApi().name()+"] cannot be used since it's API doesn't match what Minecraft is currently set to use ["+mcRenderApi.name()+"]. Please either change Minecraft's rendering API or Distant Horizons'.";
LOGGER.fatal(message); LOGGER.fatal(message);
Config.Client.Advanced.Graphics.Experimental.renderingApi.set(EDhApiRenderApi.AUTO);
throw new IllegalStateException(message); throw new IllegalStateException(message);
} }
renderDefinition.bindRenderers(); renderDefinition.bindRenderers();
LOGGER.info("DH Rendering successfully bound to: ["+renderDefinition.getEngineName()+"]...");
} }
@@ -24,11 +24,17 @@ import java.nio.FloatBuffer;
import com.seibel.distanthorizons.core.enums.EDhDirection; import com.seibel.distanthorizons.core.enums.EDhDirection;
import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos; import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos;
import com.seibel.distanthorizons.core.pos.DhChunkPos; import com.seibel.distanthorizons.core.pos.DhChunkPos;
import com.seibel.distanthorizons.core.util.math.Mat4f; import com.seibel.distanthorizons.core.util.math.DhMat4f;
#if MC_VER <= MC_1_12_2
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.ChunkPos;
#else
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.ChunkPos;
#endif
/** /**
* This class converts to and from Minecraft objects (Ex: Matrix4f) * This class converts to and from Minecraft objects (Ex: Matrix4f)
@@ -39,15 +45,17 @@ import net.minecraft.world.level.ChunkPos;
*/ */
public class McObjectConverter public class McObjectConverter
{ {
private static int bufferIndex(int x, int y)
{
return y * 4 + x;
}
//========//
// matrix //
//========//
//region
/** 4x4 float matrix converter */ /** 4x4 float matrix converter */
public static Mat4f Convert( public static DhMat4f Convert(
#if MC_VER < MC_1_19_4 com.mojang.math.Matrix4f #if MC_VER <= MC_1_12_2 org.joml.Matrix4f
#elif MC_VER < MC_1_19_4 com.mojang.math.Matrix4f
#elif MC_VER < MC_1_21_6 org.joml.Matrix4f #elif MC_VER < MC_1_21_6 org.joml.Matrix4f
#else org.joml.Matrix4fc #else org.joml.Matrix4fc
#endif #endif
@@ -55,22 +63,25 @@ public class McObjectConverter
{ {
FloatBuffer buffer = FloatBuffer.allocate(16); FloatBuffer buffer = FloatBuffer.allocate(16);
storeMatrix(mcMatrix, buffer); storeMatrix(mcMatrix, buffer);
Mat4f matrix = new Mat4f(buffer); DhMat4f matrix = new DhMat4f(buffer);
#if MC_VER < MC_1_19_4 #if MC_VER > MC_1_12_2 && MC_VER < MC_1_19_4
matrix.transpose(); // In 1.19.3 and later, we no longer need to transpose it matrix.transpose(); // In 1.19.3 and later, we no longer need to transpose it
#endif #endif
return matrix; return matrix;
} }
/** Taken from Minecraft's com.mojang.math.Matrix4f class from 1.18.2 */ /** Taken from Minecraft's com.mojang.math.Matrix4f class from 1.18.2 */
private static void storeMatrix( private static void storeMatrix(
#if MC_VER < MC_1_19_4 com.mojang.math.Matrix4f #if MC_VER <= MC_1_12_2 org.joml.Matrix4f
#elif MC_VER < MC_1_19_4 com.mojang.math.Matrix4f
#elif MC_VER < MC_1_21_6 org.joml.Matrix4f #elif MC_VER < MC_1_21_6 org.joml.Matrix4f
#else org.joml.Matrix4fc #else org.joml.Matrix4fc
#endif #endif
matrix, matrix,
FloatBuffer buffer) FloatBuffer buffer)
{ {
#if MC_VER < MC_1_19_4 #if MC_VER <= MC_1_12_2
matrix.get(buffer);
#elif MC_VER < MC_1_19_4
matrix.store(buffer); matrix.store(buffer);
#else #else
// Mojang starts to use joml's Matrix4f libary in 1.19.3 so we copy their store method and use it here if its newer than 1.19.3 // Mojang starts to use joml's Matrix4f libary in 1.19.3 so we copy their store method and use it here if its newer than 1.19.3
@@ -92,37 +103,85 @@ public class McObjectConverter
buffer.put(bufferIndex(3, 3), matrix.m33()); buffer.put(bufferIndex(3, 3), matrix.m33());
#endif #endif
} }
private static int bufferIndex(int x, int y) { return y * 4 + x; }
//endregion
static final Direction[] directions;
static final EDhDirection[] lodDirections; //===========//
// direction //
//===========//
//region
#if MC_VER <= MC_1_12_2
private static final EnumFacing[] mcDirections;
#else
private static final Direction[] mcDirections;
#endif
private static final EDhDirection[] dhDirections;
static static
{ {
EDhDirection[] lodDirs = EDhDirection.values(); EDhDirection[] lodDirs = EDhDirection.values();
directions = new Direction[lodDirs.length];
lodDirections = new EDhDirection[lodDirs.length]; #if MC_VER <= MC_1_12_2
mcDirections = new EnumFacing[lodDirs.length];
#else
mcDirections = new Direction[lodDirs.length];
#endif
dhDirections = new EDhDirection[lodDirs.length];
for (EDhDirection lodDir : lodDirs) for (EDhDirection lodDir : lodDirs)
{ {
Direction dir; #if MC_VER <= MC_1_12_2
EnumFacing dir;
#else
Direction dir;
#endif
switch (lodDir.name().toUpperCase()) switch (lodDir.name().toUpperCase())
{ {
case "DOWN": case "DOWN":
#if MC_VER <= MC_1_12_2
dir = EnumFacing.DOWN;
#else
dir = Direction.DOWN; dir = Direction.DOWN;
#endif
break; break;
case "UP": case "UP":
#if MC_VER <= MC_1_12_2
dir = EnumFacing.UP;
#else
dir = Direction.UP; dir = Direction.UP;
#endif
break; break;
case "NORTH": case "NORTH":
#if MC_VER <= MC_1_12_2
dir = EnumFacing.NORTH;
#else
dir = Direction.NORTH; dir = Direction.NORTH;
#endif
break; break;
case "SOUTH": case "SOUTH":
#if MC_VER <= MC_1_12_2
dir = EnumFacing.SOUTH;
#else
dir = Direction.SOUTH; dir = Direction.SOUTH;
#endif
break; break;
case "WEST": case "WEST":
#if MC_VER <= MC_1_12_2
dir = EnumFacing.WEST;
#else
dir = Direction.WEST; dir = Direction.WEST;
#endif
break; break;
case "EAST": case "EAST":
#if MC_VER <= MC_1_12_2
dir = EnumFacing.EAST;
#else
dir = Direction.EAST; dir = Direction.EAST;
#endif
break; break;
default: default:
dir = null; dir = null;
@@ -131,13 +190,37 @@ public class McObjectConverter
if (dir == null) if (dir == null)
{ {
throw new IllegalArgumentException("Invalid direction on init mapping: " + lodDir); throw new IllegalArgumentException("Invalid direction on init mapping: [" + lodDir + "].");
} }
directions[lodDir.ordinal()] = dir; mcDirections[lodDir.ordinal()] = dir;
lodDirections[dir.ordinal()] = lodDir; dhDirections[dir.ordinal()] = lodDir;
} }
} }
#if MC_VER <= MC_1_12_2
public static EnumFacing Convert(EDhDirection lodDirection)
#else
public static Direction Convert(EDhDirection lodDirection)
#endif
{ return mcDirections[lodDirection.ordinal()]; }
#if MC_VER <= MC_1_12_2
public static EDhDirection Convert(EnumFacing direction)
#else
public static EDhDirection Convert(Direction direction)
#endif
{ return dhDirections[direction.ordinal()]; }
//endregion
//==================//
// position objects //
//==================//
//region
public static BlockPos Convert(DhBlockPos wrappedPos) { return new BlockPos(wrappedPos.getX(), wrappedPos.getY(), wrappedPos.getZ()); } 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 ChunkPos Convert(DhChunkPos wrappedPos) { return new ChunkPos(wrappedPos.getX(), wrappedPos.getZ()); }
@@ -150,7 +233,8 @@ public class McObjectConverter
#endif #endif
} }
public static Direction Convert(EDhDirection lodDirection) { return directions[lodDirection.ordinal()]; } //endregion
public static EDhDirection Convert(Direction direction) { return lodDirections[direction.ordinal()]; }
} }
@@ -19,7 +19,7 @@
package com.seibel.distanthorizons.common.wrappers; package com.seibel.distanthorizons.common.wrappers;
import com.seibel.distanthorizons.api.enums.config.EDhApiRenderApi; import com.seibel.distanthorizons.api.enums.config.EDhApiRenderingEngine;
import com.seibel.distanthorizons.core.wrapperInterfaces.IVersionConstants; import com.seibel.distanthorizons.core.wrapperInterfaces.IVersionConstants;
public class VersionConstants implements IVersionConstants public class VersionConstants implements IVersionConstants
@@ -51,7 +51,10 @@ public class VersionConstants implements IVersionConstants
// it can't load client classes when running as a dedicated server, // it can't load client classes when running as a dedicated server,
// which was how we were dynamically accessing the MC version string // which was how we were dynamically accessing the MC version string
#if MC_VER == MC_1_16_5 #if MC_VER == MC_1_12_2
return "1.12.2";
#elif MC_VER == MC_1_16_5
return "1.16.5"; return "1.16.5";
#elif MC_VER == MC_1_17_1 #elif MC_VER == MC_1_17_1
@@ -104,12 +107,12 @@ public class VersionConstants implements IVersionConstants
} }
@Override @Override
public EDhApiRenderApi getDefaultRenderingApi() public EDhApiRenderingEngine getDefaultRenderingEngine()
{ {
#if MC_VER <= MC_1_21_11 #if MC_VER <= MC_1_21_11
return EDhApiRenderApi.OPEN_GL; return EDhApiRenderingEngine.OPEN_GL;
#else #else
return EDhApiRenderApi.BLAZE_3D; return EDhApiRenderingEngine.BLAZE_3D;
#endif #endif
} }
@@ -46,17 +46,30 @@ import com.seibel.distanthorizons.core.wrapperInterfaces.world.IBiomeWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.worldGeneration.IBatchGeneratorEnvironmentWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.worldGeneration.IBatchGeneratorEnvironmentWrapper;
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
import net.minecraft.client.multiplayer.ClientLevel;
#if MC_VER > MC_1_17_1 #if MC_VER > MC_1_17_1
import net.minecraft.core.Holder; import net.minecraft.core.Holder;
#endif #endif
#if MC_VER <= MC_1_12_2
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.multiplayer.WorldClient;
import net.minecraft.world.World;
import net.minecraft.world.WorldServer;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.chunk.Chunk;
#else
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraft.world.level.LevelReader;
import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.chunk.ChunkAccess; import net.minecraft.world.level.chunk.ChunkAccess;
#endif
import java.io.IOException; import java.io.IOException;
import java.util.HashSet;
/** /**
* This handles creating abstract wrapper objects. * This handles creating abstract wrapper objects.
@@ -115,7 +128,7 @@ public class WrapperFactory implements IWrapperFactory
throw new ClassCastException("levelWrapper must be returned by DH and of type ["+ILevelWrapper.class.getName()+"]."); throw new ClassCastException("levelWrapper must be returned by DH and of type ["+ILevelWrapper.class.getName()+"].");
} }
return BiomeWrapper.deserialize(resourceLocationString, (ILevelWrapper)levelWrapper); return BiomeWrapper.deserialize(resourceLocationString, (ILevelWrapper)levelWrapper);
} }
@Override @Override
public IDhApiBlockStateWrapper getDefaultBlockStateWrapper(String resourceLocationString, IDhApiLevelWrapper levelWrapper) throws IOException, ClassCastException public IDhApiBlockStateWrapper getDefaultBlockStateWrapper(String resourceLocationString, IDhApiLevelWrapper levelWrapper) throws IOException, ClassCastException
@@ -125,19 +138,19 @@ public class WrapperFactory implements IWrapperFactory
throw new ClassCastException("Invalid ["+IDhApiLevelWrapper.class.getSimpleName()+"] value given. Level wrapper object must be one given by the DH API (it can't be a custom implementation), specifically of type ["+ILevelWrapper.class.getName()+"]."); throw new ClassCastException("Invalid ["+IDhApiLevelWrapper.class.getSimpleName()+"] value given. Level wrapper object must be one given by the DH API (it can't be a custom implementation), specifically of type ["+ILevelWrapper.class.getName()+"].");
} }
return BlockStateWrapper.deserialize(resourceLocationString, (ILevelWrapper)levelWrapper); return BlockStateWrapper.deserialize(resourceLocationString, (ILevelWrapper)levelWrapper);
} }
@Override @Override
public IBiomeWrapper deserializeBiomeWrapper(String str, ILevelWrapper levelWrapper) throws IOException { return BiomeWrapper.deserialize(str, levelWrapper); } public IBiomeWrapper deserializeBiomeWrapper(String str, ILevelWrapper levelWrapper) throws IOException { return BiomeWrapper.deserialize(str, levelWrapper); }
@Override @Override
public IBiomeWrapper getPlainsBiomeWrapper(ILevelWrapper levelWrapper) public IBiomeWrapper getPlainsBiomeWrapper(ILevelWrapper levelWrapper)
{ {
try try
{ {
return BiomeWrapper.deserialize(BiomeWrapper.PLAINS_RESOURCE_LOCATION_STRING, levelWrapper); return BiomeWrapper.deserialize(BiomeWrapper.PLAINS_RESOURCE_LOCATION_STRING, levelWrapper);
} }
catch (IOException e) catch (IOException e)
{ {
throw new LodUtil.AssertFailureException("Unable to parse plains resource string ["+BiomeWrapper.PLAINS_RESOURCE_LOCATION_STRING+"], error:\n " + e.getMessage()); throw new LodUtil.AssertFailureException("Unable to parse plains resource string ["+BiomeWrapper.PLAINS_RESOURCE_LOCATION_STRING+"], error:\n " + e.getMessage());
} }
@@ -172,7 +185,8 @@ public class WrapperFactory implements IWrapperFactory
*/ */
public IChunkWrapper createChunkWrapper(Object[] objectArray) throws ClassCastException public IChunkWrapper createChunkWrapper(Object[] objectArray) throws ClassCastException
{ {
if (objectArray.length == 1 && objectArray[0] instanceof IChunkWrapper) if (objectArray.length == 1
&& objectArray[0] instanceof IChunkWrapper)
{ {
try try
{ {
@@ -186,41 +200,102 @@ public class WrapperFactory implements IWrapperFactory
} }
} }
//#if MC_VER <= MC_1_XX_X else if (objectArray.length != 2)
else if (objectArray.length == 2)
{
// correct number of parameters from the API
// chunk
if (!(objectArray[0] instanceof ChunkAccess))
{
throw new ClassCastException(createChunkWrapperErrorMessage(objectArray));
}
ChunkAccess chunk = (ChunkAccess) objectArray[0];
// level / light source
if (!(objectArray[1] instanceof Level))
{
throw new ClassCastException(createChunkWrapperErrorMessage(objectArray));
}
// the level is needed for the DH level wrapper...
Level level = (Level) objectArray[1];
// level wrapper
ILevelWrapper levelWrapper = level.isClientSide()
? ClientLevelWrapper.getWrapper((ClientLevel)level)
: ServerLevelWrapper.getWrapper((ServerLevel)level);
return new ChunkWrapper(chunk, levelWrapper);
}
// incorrect number of parameters from the API
else
{ {
throw new ClassCastException(createChunkWrapperErrorMessage(objectArray)); throw new ClassCastException(createChunkWrapperErrorMessage(objectArray));
} }
//#endif
// correct number of parameters from the API
//=======//
// chunk //
//=======//
//region
boolean chunkClassCorrect;
#if MC_VER <= MC_1_12_2
chunkClassCorrect = (objectArray[0] instanceof Chunk);
#else
chunkClassCorrect = (objectArray[0] instanceof ChunkAccess);
#endif
if (!chunkClassCorrect)
{
throw new ClassCastException(createChunkWrapperErrorMessage(objectArray));
}
#if MC_VER <= MC_1_12_2
Chunk chunk = (Chunk) objectArray[0];
#else
ChunkAccess chunk = (ChunkAccess) objectArray[0];
#endif
//endregion
//=======//
// level //
//=======//
//region
boolean levelClassCorrect;
#if MC_VER <= MC_1_12_2
levelClassCorrect = (objectArray[1] instanceof World);
#else
levelClassCorrect = (objectArray[1] instanceof Level);
#endif
if (!levelClassCorrect)
{
throw new ClassCastException(createChunkWrapperErrorMessage(objectArray));
}
#if MC_VER <= MC_1_12_2
World level = (World) objectArray[1];
#else
Level level = (Level) objectArray[1];
#endif
//endregion
//===============//
// level wrapper //
//===============//
//region
boolean isClientSide;
#if MC_VER <= MC_1_12_2
isClientSide = !level.isRemote;
#else
isClientSide = level.isClientSide();
#endif
ILevelWrapper levelWrapper;
if (isClientSide)
{
#if MC_VER <= MC_1_12_2
levelWrapper = ClientLevelWrapper.getWrapper((WorldClient)level);
#else
levelWrapper = ClientLevelWrapper.getWrapper((ClientLevel)level);
#endif
}
else
{
#if MC_VER <= MC_1_12_2
levelWrapper = ServerLevelWrapper.getWrapper((WorldServer)level);
#else
levelWrapper = ServerLevelWrapper.getWrapper((ServerLevel)level);
#endif
}
//endregion
return new ChunkWrapper(chunk, levelWrapper);
} }
/** /**
* Note: when this is updated for different MC versions, * Note: when this is updated for different MC versions,
@@ -230,13 +305,19 @@ public class WrapperFactory implements IWrapperFactory
{ {
String[] expectedClassNames; String[] expectedClassNames;
//#if MC_VER <= MC_1_XX_X #if MC_VER <= MC_1_12_2
expectedClassNames = new String[] expectedClassNames = new String[]
{ {
ChunkAccess.class.getName(), Chunk.class.getName(),
"[ServerLevel] or [ClientLevel]" // Classes are not referenced by names to avoid exception when one of them is missing "[WorldClient] or [WorldServer]" // Classes are not referenced by names to avoid exception when one of them is missing
}; };
//#endif #else
expectedClassNames = new String[]
{
ChunkAccess.class.getName(),
"[ServerLevel] or [ClientLevel]" // Classes are not referenced by names to avoid exception when one of them is missing
};
#endif
return createWrapperErrorMessage("Chunk wrapper", expectedClassNames, objectArray); return createWrapperErrorMessage("Chunk wrapper", expectedClassNames, objectArray);
} }
@@ -258,7 +339,7 @@ public class WrapperFactory implements IWrapperFactory
// documentation should be in the API interface // documentation should be in the API interface
public IDhApiBiomeWrapper getBiomeWrapper(Object[] objectArray, IDhApiLevelWrapper levelWrapper) public IDhApiBiomeWrapper getBiomeWrapper(Object[] objectArray, IDhApiLevelWrapper levelWrapper)
{ {
// confirm the API level wrapper is also a Core wrapper // confirm the API level wrapper is also a Core wrapper
if (!(levelWrapper instanceof ILevelWrapper)) if (!(levelWrapper instanceof ILevelWrapper))
@@ -322,19 +403,29 @@ public class WrapperFactory implements IWrapperFactory
//#if MC_VER <= MC_1_XX_X
if (objectArray.length != 1) if (objectArray.length != 1)
{ {
throw new ClassCastException(createBlockStateWrapperErrorMessage(objectArray)); throw new ClassCastException(createBlockStateWrapperErrorMessage(objectArray));
} }
if (!(objectArray[0] instanceof BlockState))
boolean blockClassCorrect;
#if MC_VER <= MC_1_12_2
blockClassCorrect = (objectArray[0] instanceof IBlockState);
#else
blockClassCorrect = (objectArray[0] instanceof BlockState);
#endif
if (!blockClassCorrect)
{ {
throw new ClassCastException(createBlockStateWrapperErrorMessage(objectArray)); throw new ClassCastException(createBlockStateWrapperErrorMessage(objectArray));
} }
#if MC_VER <= MC_1_12_2
IBlockState blockState = (IBlockState) objectArray[0];
return BlockStateWrapper.fromBlockState(blockState, coreLevelWrapper);
#else
BlockState blockState = (BlockState) objectArray[0]; BlockState blockState = (BlockState) objectArray[0];
return BlockStateWrapper.fromBlockState(blockState, coreLevelWrapper); return BlockStateWrapper.fromBlockState(blockState, coreLevelWrapper);
//#endif #endif
} }
/** /**
* Note: when this is updated for different MC versions, * Note: when this is updated for different MC versions,
@@ -344,7 +435,9 @@ public class WrapperFactory implements IWrapperFactory
{ {
String[] expectedClassNames; String[] expectedClassNames;
#if MC_VER == MC_1_16_5 || MC_VER == MC_1_17_1 #if MC_VER <= MC_1_12_2
expectedClassNames = new String[] { IBlockState.class.getName() };
#elif MC_VER <= MC_1_17_1
expectedClassNames = new String[] { Biome.class.getName() }; expectedClassNames = new String[] { Biome.class.getName() };
#else #else
expectedClassNames = new String[] { Holder.class.getName()+"<"+Biome.class.getName()+">" }; expectedClassNames = new String[] { Holder.class.getName()+"<"+Biome.class.getName()+">" };
@@ -357,7 +450,6 @@ public class WrapperFactory implements IWrapperFactory
//================// //================//
// helper methods // // helper methods //
//================// //================//
@@ -367,8 +459,8 @@ public class WrapperFactory implements IWrapperFactory
{ {
// error header // error header
StringBuilder message = new StringBuilder( StringBuilder message = new StringBuilder(
wrapperName + " creation failed. \n" + wrapperName + " creation failed. \n" +
"Expected object array parameters: \n"); "Expected object array parameters: \n");
// expected parameters // expected parameters
@@ -1,5 +1,5 @@
package com.seibel.distanthorizons.common.wrappers.block; package com.seibel.distanthorizons.common.wrappers.block;
#if MC_VER > MC_1_12_2
import com.seibel.distanthorizons.core.config.Config; import com.seibel.distanthorizons.core.config.Config;
import com.seibel.distanthorizons.core.dataObjects.BlockBiomeWrapperPair; import com.seibel.distanthorizons.core.dataObjects.BlockBiomeWrapperPair;
import com.seibel.distanthorizons.core.dataObjects.fullData.sources.FullDataSourceV2; import com.seibel.distanthorizons.core.dataObjects.fullData.sources.FullDataSourceV2;
@@ -11,10 +11,14 @@ import com.seibel.distanthorizons.core.util.FullDataPointUtil;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
#if MC_VER <= MC_1_12_2
import net.minecraft.world.biome.Biome;
#else
import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.world.level.ColorResolver; import net.minecraft.world.level.ColorResolver;
import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.biome.Biome;
#endif
import java.io.IOException; import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
@@ -45,8 +49,6 @@ public abstract class AbstractDhTintGetter implements BlockAndTintGetter
#endif #endif
private static final ConcurrentHashMap<BlockBiomeWrapperPair, Integer> COLOR_BY_BLOCK_BIOME_PAIR = new ConcurrentHashMap<>(); private static final ConcurrentHashMap<BlockBiomeWrapperPair, Integer> COLOR_BY_BLOCK_BIOME_PAIR = new ConcurrentHashMap<>();
/** returned if the color cache is incomplete */
public static final int INVALID_COLOR = -1;
protected BiomeWrapper biomeWrapper; protected BiomeWrapper biomeWrapper;
@@ -98,7 +100,7 @@ public abstract class AbstractDhTintGetter implements BlockAndTintGetter
* Can be called by DH directly, skipping some of MC's logic * Can be called by DH directly, skipping some of MC's logic
* to speed up tint getting slightly. * to speed up tint getting slightly.
* *
* @return {@link AbstractDhTintGetter#INVALID_COLOR} if any of the biomes needed for this position * @return {@link ClientBlockStateColorCache#INVALID_COLOR} if any of the biomes needed for this position
* were not cached. In that case calling {@link AbstractDhTintGetter#getBlockTint(BlockPos, ColorResolver)} * were not cached. In that case calling {@link AbstractDhTintGetter#getBlockTint(BlockPos, ColorResolver)}
* will need to be called by MC's ColorResolver so we can * will need to be called by MC's ColorResolver so we can
* populate the color cache. * populate the color cache.
@@ -159,9 +161,9 @@ public abstract class AbstractDhTintGetter implements BlockAndTintGetter
int id = FullDataPointUtil.getId(dataPoint); int id = FullDataPointUtil.getId(dataPoint);
BiomeWrapper biomeWrapper = (BiomeWrapper) this.fullDataSource.mapping.getBiomeWrapper(id); BiomeWrapper biomeWrapper = (BiomeWrapper) this.fullDataSource.mapping.getBiomeWrapper(id);
int color = this.tryGetClientBiomeColor(colorResolver, biomeWrapper); int color = this.tryGetClientBiomeColor(colorResolver, biomeWrapper);
if (color == INVALID_COLOR) if (color == ClientBlockStateColorCache.INVALID_COLOR)
{ {
return INVALID_COLOR; return ClientBlockStateColorCache.INVALID_COLOR;
} }
@@ -210,7 +212,7 @@ public abstract class AbstractDhTintGetter implements BlockAndTintGetter
// no color resolver is present, // no color resolver is present,
// the cache needs to be populated before // the cache needs to be populated before
// we can use the fast path // we can use the fast path
return INVALID_COLOR; return ClientBlockStateColorCache.INVALID_COLOR;
} }
@@ -343,9 +345,9 @@ public abstract class AbstractDhTintGetter implements BlockAndTintGetter
//===========// //=================//
// set color // // static handlers //
//===========// //=================//
//region //region
/** /**
@@ -358,8 +360,11 @@ public abstract class AbstractDhTintGetter implements BlockAndTintGetter
COLOR_BY_BLOCK_BIOME_PAIR.put(pair, colorInt); COLOR_BY_BLOCK_BIOME_PAIR.put(pair, colorInt);
} }
public static void clear() { COLOR_BY_BLOCK_BIOME_PAIR.clear(); }
//endregion //endregion
} }
#endif
@@ -28,12 +28,15 @@ import java.util.concurrent.ConcurrentMap;
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
import net.minecraft.world.level.Level;
import com.seibel.distanthorizons.core.logging.DhLogger; import com.seibel.distanthorizons.core.logging.DhLogger;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IBiomeWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.world.IBiomeWrapper;
#if MC_VER == MC_1_16_5 || MC_VER == MC_1_17_1 #if MC_VER > MC_1_12_2
import net.minecraft.world.level.Level;
#endif
#if MC_VER <= MC_1_12_2
#elif MC_VER == MC_1_16_5 || MC_VER == MC_1_17_1
import net.minecraft.core.Registry; import net.minecraft.core.Registry;
#elif MC_VER == MC_1_18_2 || MC_VER == MC_1_19_2 #elif MC_VER == MC_1_18_2 || MC_VER == MC_1_19_2
import net.minecraft.core.Holder; import net.minecraft.core.Holder;
@@ -45,14 +48,21 @@ import net.minecraft.core.Holder;
import net.minecraft.core.registries.Registries; import net.minecraft.core.registries.Registries;
#endif #endif
#if MC_VER <= MC_1_21_10 #if MC_VER <= MC_1_12_2
import net.minecraft.util.ResourceLocation;
#elif MC_VER <= MC_1_21_10
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
#else #else
import net.minecraft.resources.Identifier; import net.minecraft.resources.Identifier;
import net.minecraft.core.component.DataComponentMap; import net.minecraft.core.component.DataComponentMap;
#endif #endif
#if MC_VER <= MC_1_12_2
import net.minecraft.world.biome.Biome;
#else
import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.biome.Biome;
#endif
#if MC_VER >= MC_1_18_2 #if MC_VER >= MC_1_18_2
import net.minecraft.world.level.biome.Biomes; import net.minecraft.world.level.biome.Biomes;
@@ -108,8 +118,13 @@ public class BiomeWrapper implements IBiomeWrapper
//==============// //==============//
// constructors // // constructors //
//==============// //==============//
//region
public static BiomeWrapper getBiomeWrapper(#if MC_VER < MC_1_18_2 Biome #else Holder<Biome> #endif biome, ILevelWrapper levelWrapper) #if MC_VER < MC_1_18_2
public static BiomeWrapper getBiomeWrapper(Biome biome, ILevelWrapper levelWrapper)
#else
public static BiomeWrapper getBiomeWrapper(Holder<Biome> biome, ILevelWrapper levelWrapper)
#endif
{ {
if (biome == null) if (biome == null)
{ {
@@ -129,7 +144,12 @@ public class BiomeWrapper implements IBiomeWrapper
return newWrapper; return newWrapper;
} }
} }
private BiomeWrapper(#if MC_VER < MC_1_18_2 Biome #else Holder<Biome> #endif biome, ILevelWrapper levelWrapper)
#if MC_VER < MC_1_18_2
private BiomeWrapper(Biome biome, ILevelWrapper levelWrapper)
#else
private BiomeWrapper(Holder<Biome> biome, ILevelWrapper levelWrapper)
#endif
{ {
this.biome = biome; this.biome = biome;
this.serialString = this.serialize(levelWrapper); this.serialString = this.serialize(levelWrapper);
@@ -138,11 +158,14 @@ public class BiomeWrapper implements IBiomeWrapper
//LOGGER.trace("Created BiomeWrapper ["+this.serialString+"] for ["+biome+"]"); //LOGGER.trace("Created BiomeWrapper ["+this.serialString+"] for ["+biome+"]");
} }
//endregion
//=========// //=========//
// methods // // methods //
//=========// //=========//
//region
@Override @Override
public String getName() public String getName()
@@ -188,11 +211,14 @@ public class BiomeWrapper implements IBiomeWrapper
@Override @Override
public String toString() { return this.getSerialString(); } public String toString() { return this.getSerialString(); }
//endregion
//=======================// //=======================//
// serialization methods // // serialization methods //
//=======================// //=======================//
//region
public String serialize(ILevelWrapper levelWrapper) public String serialize(ILevelWrapper levelWrapper)
{ {
@@ -219,8 +245,10 @@ public class BiomeWrapper implements IBiomeWrapper
// generate the serial string // // generate the serial string //
#if MC_VER > MC_1_12_2
Level level = (Level)levelWrapper.getWrappedMcObject(); Level level = (Level)levelWrapper.getWrappedMcObject();
net.minecraft.core.RegistryAccess registryAccess = level.registryAccess(); net.minecraft.core.RegistryAccess registryAccess = level.registryAccess();
#endif
#if MC_VER <= MC_1_21_10 #if MC_VER <= MC_1_21_10
ResourceLocation resourceLocation; ResourceLocation resourceLocation;
@@ -228,7 +256,9 @@ public class BiomeWrapper implements IBiomeWrapper
Identifier resourceLocation; Identifier resourceLocation;
#endif #endif
#if MC_VER <= MC_1_17_1 #if MC_VER <= MC_1_12_2
resourceLocation = biome.getRegistryName();
#elif MC_VER <= MC_1_17_1
resourceLocation = registryAccess.registryOrThrow(Registry.BIOME_REGISTRY).getKey(this.biome); resourceLocation = registryAccess.registryOrThrow(Registry.BIOME_REGISTRY).getKey(this.biome);
#elif MC_VER <= MC_1_19_2 #elif MC_VER <= MC_1_19_2
resourceLocation = registryAccess.registryOrThrow(Registry.BIOME_REGISTRY).getKey(this.biome.value()); resourceLocation = registryAccess.registryOrThrow(Registry.BIOME_REGISTRY).getKey(this.biome.value());
@@ -293,11 +323,16 @@ public class BiomeWrapper implements IBiomeWrapper
{ {
try try
{ {
#if MC_VER > MC_1_12_2
Level level = (Level) levelWrapper.getWrappedMcObject(); Level level = (Level) levelWrapper.getWrappedMcObject();
net.minecraft.core.RegistryAccess registryAccess = level.registryAccess(); net.minecraft.core.RegistryAccess registryAccess = level.registryAccess();
#endif
#if MC_VER <= MC_1_12_2
BiomeDeserializeResult deserializeResult = deserializeBiome(resourceLocationString);
#else
BiomeDeserializeResult deserializeResult = deserializeBiome(resourceLocationString, registryAccess); BiomeDeserializeResult deserializeResult = deserializeBiome(resourceLocationString, registryAccess);
#endif
if (!deserializeResult.success) if (!deserializeResult.success)
@@ -325,7 +360,11 @@ public class BiomeWrapper implements IBiomeWrapper
} }
} }
#if MC_VER <= MC_1_12_2
public static BiomeDeserializeResult deserializeBiome(String resourceLocationString) throws IOException
#else
public static BiomeDeserializeResult deserializeBiome(String resourceLocationString, net.minecraft.core.RegistryAccess registryAccess) throws IOException public static BiomeDeserializeResult deserializeBiome(String resourceLocationString, net.minecraft.core.RegistryAccess registryAccess) throws IOException
#endif
{ {
// parse the resource location // parse the resource location
int separatorIndex = resourceLocationString.indexOf(":"); int separatorIndex = resourceLocationString.indexOf(":");
@@ -356,7 +395,10 @@ public class BiomeWrapper implements IBiomeWrapper
boolean success; boolean success;
#if MC_VER <= MC_1_17_1 #if MC_VER <= MC_1_12_2
Biome biome = Biome.REGISTRY.getObject(resourceLocation);
success = (biome != null);
#elif MC_VER <= MC_1_17_1
Biome biome = registryAccess.registryOrThrow(Registry.BIOME_REGISTRY).get(resourceLocation); Biome biome = registryAccess.registryOrThrow(Registry.BIOME_REGISTRY).get(resourceLocation);
success = (biome != null); success = (biome != null);
#elif MC_VER <= MC_1_19_2 #elif MC_VER <= MC_1_19_2
@@ -400,10 +442,14 @@ public class BiomeWrapper implements IBiomeWrapper
return new BiomeDeserializeResult(success, biome); return new BiomeDeserializeResult(success, biome);
} }
//endregion
//================// //================//
// helper classes // // helper classes //
//================// //================//
//region
public static class BiomeDeserializeResult public static class BiomeDeserializeResult
{ {
@@ -413,14 +459,21 @@ public class BiomeWrapper implements IBiomeWrapper
public final Biome biome; public final Biome biome;
#else #else
public final Holder<Biome> biome; public final Holder<Biome> biome;
#endif #endif
public BiomeDeserializeResult(boolean success, #if MC_VER < MC_1_18_2 Biome #else Holder<Biome> #endif biome) #if MC_VER < MC_1_18_2
public BiomeDeserializeResult(boolean success, Biome biome)
#else
public BiomeDeserializeResult(boolean success, Holder<Biome> biome)
#endif
{ {
this.success = success; this.success = success;
this.biome = biome; this.biome = biome;
} }
} }
//endregion
} }
@@ -32,12 +32,20 @@ import com.seibel.distanthorizons.core.wrapperInterfaces.block.IBlockStateWrappe
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
import com.seibel.distanthorizons.coreapi.DependencyInjection.ApiEventInjector; import com.seibel.distanthorizons.coreapi.DependencyInjection.ApiEventInjector;
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
#if MC_VER <= MC_1_12_2
import net.minecraft.block.*;
import net.minecraft.init.Blocks;
import net.minecraft.block.state.IBlockState;
import net.minecraft.block.properties.IProperty;
import net.minecraftforge.fluids.IFluidBlock;
#else
import net.minecraft.tags.BlockTags; import net.minecraft.tags.BlockTags;
import net.minecraft.world.level.block.BeaconBeamBlock; import net.minecraft.world.level.block.BeaconBeamBlock;
import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.SoundType; import net.minecraft.world.level.block.SoundType;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
#endif
import com.seibel.distanthorizons.core.logging.DhLogger; import com.seibel.distanthorizons.core.logging.DhLogger;
import java.awt.*; import java.awt.*;
@@ -61,7 +69,7 @@ import net.minecraft.world.level.Level;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.Registry; import net.minecraft.core.Registry;
import net.minecraft.world.level.EmptyBlockGetter; import net.minecraft.world.level.EmptyBlockGetter;
#else #elif MC_VER > MC_1_12_2
import net.minecraft.tags.TagKey; import net.minecraft.tags.TagKey;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
@@ -70,12 +78,15 @@ import net.minecraft.world.level.EmptyBlockGetter;
import net.minecraft.core.Holder; import net.minecraft.core.Holder;
#endif #endif
#if MC_VER <= MC_1_21_10 #if MC_VER <= MC_1_12_2
import net.minecraft.util.ResourceLocation;
#elif MC_VER <= MC_1_21_10
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
#else #else
import net.minecraft.resources.Identifier; import net.minecraft.resources.Identifier;
#endif #endif
public class BlockStateWrapper implements IBlockStateWrapper public class BlockStateWrapper implements IBlockStateWrapper
{ {
/** example "minecraft:water" */ /** example "minecraft:water" */
@@ -87,7 +98,11 @@ public class BlockStateWrapper implements IBlockStateWrapper
// must be defined before AIR, otherwise a null pointer will be thrown // must be defined before AIR, otherwise a null pointer will be thrown
private static final DhLogger LOGGER = new DhLoggerBuilder().build(); private static final DhLogger LOGGER = new DhLoggerBuilder().build();
#if MC_VER <= MC_1_12_2
public static final ConcurrentHashMap<IBlockState, BlockStateWrapper> WRAPPER_BY_BLOCK_STATE = new ConcurrentHashMap<>();
#else
public static final ConcurrentHashMap<BlockState, BlockStateWrapper> WRAPPER_BY_BLOCK_STATE = new ConcurrentHashMap<>(); public static final ConcurrentHashMap<BlockState, BlockStateWrapper> WRAPPER_BY_BLOCK_STATE = new ConcurrentHashMap<>();
#endif
public static final ConcurrentHashMap<String, BlockStateWrapper> WRAPPER_BY_RESOURCE_LOCATION = new ConcurrentHashMap<>(); public static final ConcurrentHashMap<String, BlockStateWrapper> WRAPPER_BY_RESOURCE_LOCATION = new ConcurrentHashMap<>();
public static final String AIR_STRING = "AIR"; public static final String AIR_STRING = "AIR";
@@ -114,7 +129,11 @@ public class BlockStateWrapper implements IBlockStateWrapper
// properties // // properties //
@Nullable @Nullable
#if MC_VER <= MC_1_12_2
public final IBlockState blockState;
#else
public final BlockState blockState; public final BlockState blockState;
#endif
/** technically final, but since it requires a method call to generate it can't be marked as such */ /** technically final, but since it requires a method call to generate it can't be marked as such */
private String serialString; private String serialString;
private final int hashCode; private final int hashCode;
@@ -139,27 +158,71 @@ public class BlockStateWrapper implements IBlockStateWrapper
// constructors // // constructors //
//==============// //==============//
//region //region
/** /**
* Can be faster than {@link BlockStateWrapper#fromBlockState(BlockState, ILevelWrapper)} * Can be faster than BlockStateWrapper#fromBlockState(BlockState, ILevelWrapper)
* in cases where the same block state is expected to be referenced multiple times. * in cases where the same block state is expected to be referenced multiple times.
*/ */
#if MC_VER <= MC_1_12_2
public static BlockStateWrapper fromBlockState(IBlockState blockState, ILevelWrapper levelWrapper, IBlockStateWrapper guess)
#else
public static BlockStateWrapper fromBlockState(BlockState blockState, ILevelWrapper levelWrapper, IBlockStateWrapper guess) public static BlockStateWrapper fromBlockState(BlockState blockState, ILevelWrapper levelWrapper, IBlockStateWrapper guess)
#endif
{ {
BlockState guessBlockState = (guess == null || guess.isAir()) ? null : (BlockState) guess.getWrappedMcObject(); if (guess == null)
BlockState inputBlockState = (blockState == null || blockState.isAir()) ? null : blockState;
if (guess instanceof BlockStateWrapper
&& guessBlockState == inputBlockState)
{
return (BlockStateWrapper) guess;
}
else
{ {
return fromBlockState(blockState, levelWrapper); return fromBlockState(blockState, levelWrapper);
} }
// guess block state
BlockStateWrapper wrapperGuess = (BlockStateWrapper) guess;
#if MC_VER <= MC_1_12_2
IBlockState guessBlockState;
#else
BlockState guessBlockState;
#endif
if(isAir(wrapperGuess.blockState))
{
guessBlockState = null;
}
else
{
#if MC_VER <= MC_1_12_2
guessBlockState = (IBlockState) guess.getWrappedMcObject();
#else
guessBlockState = (BlockState) guess.getWrappedMcObject();
#endif
}
// input block state
#if MC_VER <= MC_1_12_2
IBlockState inputBlockState;
#else
BlockState inputBlockState;
#endif
if (isAir(blockState))
{
inputBlockState = null;
}
else
{
inputBlockState = blockState;
}
if (guessBlockState == inputBlockState)
{
return (BlockStateWrapper) guess;
}
return fromBlockState(blockState, levelWrapper);
} }
#if MC_VER <= MC_1_12_2
public static BlockStateWrapper fromBlockState(@Nullable IBlockState blockState, ILevelWrapper levelWrapper)
#else
public static BlockStateWrapper fromBlockState(@Nullable BlockState blockState, ILevelWrapper levelWrapper) public static BlockStateWrapper fromBlockState(@Nullable BlockState blockState, ILevelWrapper levelWrapper)
#endif
{ {
// air is a special case // air is a special case
if (isAir(blockState)) if (isAir(blockState))
@@ -208,9 +271,12 @@ public class BlockStateWrapper implements IBlockStateWrapper
} }
} }
} }
private BlockStateWrapper(
@Nullable BlockState blockState, ILevelWrapper levelWrapper, #if MC_VER <= MC_1_12_2
@Nullable DhApiBlockStateWrapperCreatedEvent.EventParam overrideEventParam) private BlockStateWrapper(@Nullable IBlockState blockState, ILevelWrapper levelWrapper, @Nullable DhApiBlockStateWrapperCreatedEvent.EventParam overrideEventParam)
#else
private BlockStateWrapper(@Nullable BlockState blockState, ILevelWrapper levelWrapper, @Nullable DhApiBlockStateWrapperCreatedEvent.EventParam overrideEventParam)
#endif
{ {
this.blockState = blockState; this.blockState = blockState;
this.serialString = serialize(blockState, levelWrapper); this.serialString = serialize(blockState, levelWrapper);
@@ -228,11 +294,13 @@ public class BlockStateWrapper implements IBlockStateWrapper
} }
else else
{ {
#if MC_VER < MC_1_20_1 #if MC_VER <= MC_1_12_2
this.isLiquid = this.blockState.getMaterial().isLiquid() || !this.blockState.getFluidState().isEmpty(); this.isLiquid = this.blockState.getMaterial().isLiquid() || this.blockState.getBlock() instanceof IFluidBlock;
#else #elif MC_VER < MC_1_20_1
this.isLiquid = this.blockState.getMaterial().isLiquid() || !this.blockState.getFluidState().isEmpty();
#else
this.isLiquid = !this.blockState.getFluidState().isEmpty(); this.isLiquid = !this.blockState.getFluidState().isEmpty();
#endif #endif
} }
} }
@@ -332,9 +400,21 @@ public class BlockStateWrapper implements IBlockStateWrapper
&& !this.isBeaconBlock) && !this.isBeaconBlock)
{ {
Block block = this.blockState.getBlock(); Block block = this.blockState.getBlock();
int colorInt;
#if MC_VER <= MC_1_12_2
if (block instanceof BlockStainedGlass)
{
colorInt = blockState.getValue(BlockStainedGlass.COLOR).getColorValue();
beaconTintColor = ColorUtil.toColorObjRGB(colorInt);
}
else if (block instanceof BlockStainedGlassPane)
{
colorInt = blockState.getValue(BlockStainedGlassPane.COLOR).getColorValue();
beaconTintColor = ColorUtil.toColorObjRGB(colorInt);
}
#else
if (block instanceof BeaconBeamBlock) if (block instanceof BeaconBeamBlock)
{ {
int colorInt;
#if MC_VER <= MC_1_19_4 #if MC_VER <= MC_1_19_4
colorInt = ((BeaconBeamBlock) block).getColor().getMaterialColor().col; colorInt = ((BeaconBeamBlock) block).getColor().getMaterialColor().col;
#else #else
@@ -343,6 +423,7 @@ public class BlockStateWrapper implements IBlockStateWrapper
beaconTintColor = ColorUtil.toColorObjRGB(colorInt); beaconTintColor = ColorUtil.toColorObjRGB(colorInt);
} }
#endif
} }
this.beaconTintColor = beaconTintColor; this.beaconTintColor = beaconTintColor;
@@ -392,8 +473,10 @@ public class BlockStateWrapper implements IBlockStateWrapper
if (this.blockState != null) if (this.blockState != null)
{ {
int mcColor = 0; int mcColor = 0;
#if MC_VER < MC_1_20_1 #if MC_VER <= MC_1_12_2
mcColor = this.blockState.getMaterial().getMaterialMapColor().colorValue;
#elif MC_VER < MC_1_20_1
mcColor = this.blockState.getMaterial().getColor().col; mcColor = this.blockState.getMaterial().getColor().col;
#else #else
mcColor = this.blockState.getMapColor(EmptyBlockGetter.INSTANCE, BlockPos.ZERO).col; mcColor = this.blockState.getMapColor(EmptyBlockGetter.INSTANCE, BlockPos.ZERO).col;
@@ -420,7 +503,7 @@ public class BlockStateWrapper implements IBlockStateWrapper
#if MC_VER < MC_1_20_1 #if MC_VER < MC_1_20_1
this.isSolid = this.blockState.getMaterial().isSolid(); this.isSolid = this.blockState.getMaterial().isSolid();
#else #else
this.isSolid = !this.blockState.getCollisionShape(EmptyBlockGetter.INSTANCE, BlockPos.ZERO).isEmpty(); this.isSolid = !this.blockState.getCollisionShape(EmptyBlockGetter.INSTANCE, BlockPos.ZERO).isEmpty();
#endif #endif
} }
} }
@@ -431,76 +514,193 @@ public class BlockStateWrapper implements IBlockStateWrapper
// static constructor helpers // // static constructor helpers //
//region //region
private static EDhApiBlockMaterial calculateEDhApiBlockMaterialId( #if MC_VER <= MC_1_12_2
@Nullable BlockState blockState, private static EDhApiBlockMaterial calculateEDhApiBlockMaterialId(@Nullable IBlockState blockState, String lowercaseSerialString, boolean isLiquid)
String lowercaseSerialString, #else
boolean isLiquid private static EDhApiBlockMaterial calculateEDhApiBlockMaterialId(@Nullable BlockState blockState, String lowercaseSerialString, boolean isLiquid)
) #endif
{ {
if (blockState == null) if (isAir(blockState))
{ {
return EDhApiBlockMaterial.AIR; return EDhApiBlockMaterial.AIR;
} }
if (blockState.is(BlockTags.LEAVES)
//========//
// leaves //
//========//
//region
boolean isLeafBlock;
#if MC_VER <= MC_1_12_2
isLeafBlock = blockState.getBlock() instanceof BlockLeaves;
#else
isLeafBlock = blockState.is(BlockTags.LEAVES);
#endif
if (isLeafBlock
|| lowercaseSerialString.contains("bamboo") || lowercaseSerialString.contains("bamboo")
|| lowercaseSerialString.contains("cactus") || lowercaseSerialString.contains("cactus")
|| lowercaseSerialString.contains("chorus_flower") || lowercaseSerialString.contains("chorus_flower")
|| lowercaseSerialString.contains("mushroom") || lowercaseSerialString.contains("mushroom")
) )
{ {
return EDhApiBlockMaterial.LEAVES; return EDhApiBlockMaterial.LEAVES;
} }
else if (blockState.is(Blocks.LAVA))
//endregion
//======//
// lava //
//======//
//region
boolean isLavaBlock;
#if MC_VER <= MC_1_12_2
isLavaBlock = blockState.getBlock() == Blocks.LAVA || blockState.getBlock() == Blocks.FLOWING_LAVA;
#else
isLavaBlock = blockState.is(Blocks.LAVA);
#endif
if (isLavaBlock)
{ {
return EDhApiBlockMaterial.LAVA; return EDhApiBlockMaterial.LAVA;
} }
else if (isLiquid
|| blockState.is(Blocks.WATER)) //endregion
//=======//
// water //
//=======//
//region
boolean isWaterBlock;
#if MC_VER <= MC_1_12_2
isWaterBlock = blockState.getBlock() == Blocks.WATER || blockState.getBlock() == Blocks.FLOWING_WATER;
#else
isWaterBlock = blockState.is(Blocks.WATER);
#endif
if (isLiquid
|| isWaterBlock)
{ {
return EDhApiBlockMaterial.WATER; return EDhApiBlockMaterial.WATER;
} }
else if (blockState.getSoundType() == SoundType.WOOD
//endregion
//======//
// wood //
//======//
//region
boolean isWoodSoundingBlock;
#if MC_VER <= MC_1_12_2
isWoodSoundingBlock = blockState.getBlock().getSoundType() == SoundType.WOOD;
#else
isWoodSoundingBlock = blockState.getSoundType() == SoundType.WOOD;
#endif
boolean isCherryWood;
#if MC_VER <= MC_1_19_2
isCherryWood = false;
#else
isCherryWood = blockState.getSoundType() == SoundType.CHERRY_WOOD;
#endif
if (isWoodSoundingBlock
|| lowercaseSerialString.contains("root") || lowercaseSerialString.contains("root")
#if MC_VER >= MC_1_19_4 || isCherryWood
|| blockState.getSoundType() == SoundType.CHERRY_WOOD )
#endif
)
{ {
return EDhApiBlockMaterial.WOOD; return EDhApiBlockMaterial.WOOD;
} }
else if (blockState.getSoundType() == SoundType.METAL
#if MC_VER >= MC_1_19_2 //endregion
|| blockState.getSoundType() == SoundType.COPPER
#endif
#if MC_VER >= MC_1_20_4
|| blockState.getSoundType() == SoundType.COPPER_BULB //=======//
|| blockState.getSoundType() == SoundType.COPPER_GRATE // metal //
#endif //=======//
) //region
boolean isMetalSoundingBlock;
#if MC_VER <= MC_1_12_2
isMetalSoundingBlock = blockState.getBlock().getSoundType() == SoundType.METAL;
#else
isMetalSoundingBlock = blockState.getSoundType() == SoundType.METAL;
#endif
boolean isCopperSounding;
#if MC_VER <= MC_1_18_2
isCopperSounding = false;
#elif MC_VER <= MC_1_20_2
isCopperSounding = blockState.getSoundType() == SoundType.COPPER;
#else
isCopperSounding
= blockState.getSoundType() == SoundType.COPPER
|| blockState.getSoundType() == SoundType.COPPER_BULB
|| blockState.getSoundType() == SoundType.COPPER_GRATE;
#endif
if (isMetalSoundingBlock
|| isCopperSounding)
{ {
return EDhApiBlockMaterial.METAL; return EDhApiBlockMaterial.METAL;
} }
else if (
lowercaseSerialString.contains("grass_block") //endregion
|| lowercaseSerialString.contains("grass_slab")
)
//=======//
// grass //
//=======//
//region
if (lowercaseSerialString.contains("grass_block")
|| lowercaseSerialString.contains("grass_slab")
)
{ {
return EDhApiBlockMaterial.GRASS; return EDhApiBlockMaterial.GRASS;
} }
else if (
//endregion
//======//
// dirt //
//======//
//region
if (
lowercaseSerialString.contains("dirt") lowercaseSerialString.contains("dirt")
|| lowercaseSerialString.contains("gravel") || lowercaseSerialString.contains("gravel")
|| lowercaseSerialString.contains("mud") || lowercaseSerialString.contains("mud")
|| lowercaseSerialString.contains("podzol") || lowercaseSerialString.contains("podzol")
|| lowercaseSerialString.contains("mycelium") || lowercaseSerialString.contains("mycelium")
) )
{ {
return EDhApiBlockMaterial.DIRT; return EDhApiBlockMaterial.DIRT;
} }
//endregion
//===========//
// deepslate //
//===========//
//region
#if MC_VER >= MC_1_17_1 #if MC_VER >= MC_1_17_1
else if (blockState.getSoundType() == SoundType.DEEPSLATE if (blockState.getSoundType() == SoundType.DEEPSLATE
|| blockState.getSoundType() == SoundType.DEEPSLATE_BRICKS || blockState.getSoundType() == SoundType.DEEPSLATE_BRICKS
|| blockState.getSoundType() == SoundType.DEEPSLATE_TILES || blockState.getSoundType() == SoundType.DEEPSLATE_TILES
|| blockState.getSoundType() == SoundType.POLISHED_DEEPSLATE || blockState.getSoundType() == SoundType.POLISHED_DEEPSLATE
@@ -509,41 +709,75 @@ public class BlockStateWrapper implements IBlockStateWrapper
return EDhApiBlockMaterial.DEEPSLATE; return EDhApiBlockMaterial.DEEPSLATE;
} }
#endif #endif
else if (lowercaseSerialString.contains("snow"))
{ //endregion
return EDhApiBlockMaterial.SNOW;
}
else if (lowercaseSerialString.contains("sand"))
{ //============//
return EDhApiBlockMaterial.SAND; // netherrack //
} //============//
else if (lowercaseSerialString.contains("terracotta")) //region
{
return EDhApiBlockMaterial.TERRACOTTA; boolean isNetherRack;
} #if MC_VER <= MC_1_12_2
else if (blockState.is(BlockTags.BASE_STONE_NETHER)) isNetherRack = blockState.getBlock() == Blocks.NETHERRACK;
#else
isNetherRack = blockState.is(BlockTags.BASE_STONE_NETHER);
#endif
if (isNetherRack)
{ {
return EDhApiBlockMaterial.NETHER_STONE; return EDhApiBlockMaterial.NETHER_STONE;
} }
else if (lowercaseSerialString.contains("stone")
//endregion
//=============//
// misc/simple //
//=============//
//region
if (lowercaseSerialString.contains("snow"))
{
return EDhApiBlockMaterial.SNOW;
}
if (lowercaseSerialString.contains("sand"))
{
return EDhApiBlockMaterial.SAND;
}
if (lowercaseSerialString.contains("terracotta"))
{
return EDhApiBlockMaterial.TERRACOTTA;
}
if (lowercaseSerialString.contains("stone")
|| lowercaseSerialString.contains("ore")) || lowercaseSerialString.contains("ore"))
{ {
return EDhApiBlockMaterial.STONE; return EDhApiBlockMaterial.STONE;
} }
else if (blockState.getLightEmission() > 0)
if (getLightEmission(blockState) > 0)
{ {
return EDhApiBlockMaterial.ILLUMINATED; return EDhApiBlockMaterial.ILLUMINATED;
} }
else
{ //endregion
return EDhApiBlockMaterial.UNKNOWN;
}
return EDhApiBlockMaterial.UNKNOWN;
} }
private static int calculateOpacity( #if MC_VER <= MC_1_12_2
@Nullable BlockState blockState, private static int calculateOpacity(@Nullable IBlockState blockState, boolean isAir, boolean isLiquid)
boolean isAir, boolean isLiquid #else
) private static int calculateOpacity(@Nullable BlockState blockState, boolean isAir, boolean isLiquid)
#endif
{ {
// get block properties (defaults to the values used by air) // get block properties (defaults to the values used by air)
boolean canOcclude = getCanOcclude(blockState); boolean canOcclude = getCanOcclude(blockState);
@@ -582,24 +816,40 @@ public class BlockStateWrapper implements IBlockStateWrapper
return opacity; return opacity;
} }
#if MC_VER <= MC_1_12_2
private static boolean getCanOcclude(@Nullable IBlockState blockState)
#else
private static boolean getCanOcclude(@Nullable BlockState blockState) private static boolean getCanOcclude(@Nullable BlockState blockState)
#endif
{ {
// defaults to the value used by air // defaults to the value used by air
boolean canOcclude = false; boolean canOcclude = false;
if (blockState != null) if (blockState != null)
{ {
#if MC_VER <= MC_1_12_2
canOcclude = blockState.getMaterial().isSolid();
#else
canOcclude = blockState.canOcclude(); canOcclude = blockState.canOcclude();
#endif
} }
return canOcclude; return canOcclude;
} }
#if MC_VER <= MC_1_12_2
private static boolean getPropagatesSkyLightDown(@Nullable IBlockState blockState)
#else
private static boolean getPropagatesSkyLightDown(@Nullable BlockState blockState) private static boolean getPropagatesSkyLightDown(@Nullable BlockState blockState)
#endif
{ {
// defaults to the value used by air // defaults to the value used by air
boolean propagatesSkyLightDown = true; boolean propagatesSkyLightDown = true;
if (blockState != null) if (blockState != null)
{ {
#if MC_VER < MC_1_21_3 #if MC_VER <= MC_1_12_2
propagatesSkyLightDown = blockState.getBlock().getLightOpacity(blockState) == 0;
#elif MC_VER < MC_1_21_3
propagatesSkyLightDown = blockState.propagatesSkylightDown(EmptyBlockGetter.INSTANCE, BlockPos.ZERO); propagatesSkyLightDown = blockState.propagatesSkylightDown(EmptyBlockGetter.INSTANCE, BlockPos.ZERO);
#else #else
propagatesSkyLightDown = blockState.propagatesSkylightDown(); propagatesSkyLightDown = blockState.propagatesSkylightDown();
@@ -659,8 +909,10 @@ public class BlockStateWrapper implements IBlockStateWrapper
return waterSurfaceReplacementBlocks; return waterSurfaceReplacementBlocks;
} }
ObjectOpenHashSet<String> baseIgnoredBlock = new ObjectOpenHashSet<>(); ObjectOpenHashSet<String> baseIgnoredBlockResourceSet = new ObjectOpenHashSet<>();
waterSurfaceReplacementBlocks = getAllBlockWrappers(Config.Client.Advanced.Graphics.Culling.waterSurfaceBlockReplacementCsv, baseIgnoredBlock, levelWrapper); waterSurfaceReplacementBlocks = getAllBlockWrappers(Config.Client.Advanced.Graphics.Culling.waterSurfaceBlockReplacementCsv, baseIgnoredBlockResourceSet, levelWrapper);
waterSubsurfaceReplacementBlocks.remove(AIR);
return waterSurfaceReplacementBlocks; return waterSurfaceReplacementBlocks;
} }
public static ObjectOpenHashSet<IBlockStateWrapper> getWaterSubsurfaceReplacementBlocks(ILevelWrapper levelWrapper) public static ObjectOpenHashSet<IBlockStateWrapper> getWaterSubsurfaceReplacementBlocks(ILevelWrapper levelWrapper)
@@ -671,8 +923,12 @@ public class BlockStateWrapper implements IBlockStateWrapper
return waterSubsurfaceReplacementBlocks; return waterSubsurfaceReplacementBlocks;
} }
ObjectOpenHashSet<String> baseIgnoredBlock = new ObjectOpenHashSet<>(); ObjectOpenHashSet<String> baseIgnoredBlockResourceSet = new ObjectOpenHashSet<>();
waterSubsurfaceReplacementBlocks = getAllBlockWrappers(Config.Client.Advanced.Graphics.Culling.waterSubSurfaceBlockReplacementCsv, baseIgnoredBlock, levelWrapper); waterSubsurfaceReplacementBlocks = getAllBlockWrappers(Config.Client.Advanced.Graphics.Culling.waterSubSurfaceBlockReplacementCsv, baseIgnoredBlockResourceSet, levelWrapper);
// air will be present if any invalid resource locations are present
// but we don't want to replace air with water, that'll cause monoliths
waterSubsurfaceReplacementBlocks.remove(AIR);
return waterSubsurfaceReplacementBlocks; return waterSubsurfaceReplacementBlocks;
} }
public static IBlockStateWrapper getWaterBlockStateWrapper(ILevelWrapper levelWrapper) public static IBlockStateWrapper getWaterBlockStateWrapper(ILevelWrapper levelWrapper)
@@ -740,8 +996,17 @@ public class BlockStateWrapper implements IBlockStateWrapper
if (defaultBlockStateToIgnore != AIR) if (defaultBlockStateToIgnore != AIR)
{ {
// add all possible blockstates (to account for light blocks with different light values and such) // add all possible blockstates (to account for light blocks with different light values and such)
#if MC_VER <= MC_1_12_2
List<IBlockState> blockStatesToIgnore = defaultBlockStateToIgnore.blockState.getBlock().getBlockState().getValidStates();
#else
List<BlockState> blockStatesToIgnore = defaultBlockStateToIgnore.blockState.getBlock().getStateDefinition().getPossibleStates(); List<BlockState> blockStatesToIgnore = defaultBlockStateToIgnore.blockState.getBlock().getStateDefinition().getPossibleStates();
#endif
#if MC_VER <= MC_1_12_2
for (IBlockState blockState : blockStatesToIgnore)
#else
for (BlockState blockState : blockStatesToIgnore) for (BlockState blockState : blockStatesToIgnore)
#endif
{ {
BlockStateWrapper newBlockToIgnore = fromBlockState(blockState, levelWrapper); BlockStateWrapper newBlockToIgnore = fromBlockState(blockState, levelWrapper);
blockStateWrappers.add(newBlockToIgnore); blockStateWrappers.add(newBlockToIgnore);
@@ -788,7 +1053,25 @@ public class BlockStateWrapper implements IBlockStateWrapper
public int getOpacity() { return this.opacity; } public int getOpacity() { return this.opacity; }
@Override @Override
public int getLightEmission() { return (this.blockState != null) ? this.blockState.getLightEmission() : 0; } public int getLightEmission() { return getLightEmission(this.blockState); }
#if MC_VER <= MC_1_12_2
public static int getLightEmission(IBlockState blockState)
#else
public static int getLightEmission(BlockState blockState)
#endif
{
if (blockState == null)
{
return 0;
}
#if MC_VER <= MC_1_12_2
return blockState.getLightValue();
#else
return blockState.getLightEmission();
#endif
}
@Override @Override
public String getSerialString() { return this.serialString; } public String getSerialString() { return this.serialString; }
@@ -798,7 +1081,23 @@ public class BlockStateWrapper implements IBlockStateWrapper
@Override @Override
public boolean isAir() { return isAir(this.blockState); } public boolean isAir() { return isAir(this.blockState); }
public static boolean isAir(BlockState blockState) { return blockState == null || blockState.isAir(); } #if MC_VER <= MC_1_12_2
public static boolean isAir(IBlockState blockState)
#else
public static boolean isAir(BlockState blockState)
#endif
{
if (blockState == null)
{
return true;
}
#if MC_VER <= MC_1_12_2
return blockState.getBlock() == Blocks.AIR;
#else
return blockState.isAir();
#endif
}
@Override @Override
public boolean isSolid() { return this.isSolid; } public boolean isSolid() { return this.isSolid; }
@@ -832,7 +1131,11 @@ public class BlockStateWrapper implements IBlockStateWrapper
//=======================// //=======================//
//region //region
#if MC_VER <= MC_1_12_2
private static String serialize(IBlockState blockState, ILevelWrapper levelWrapper)
#else
private static String serialize(BlockState blockState, ILevelWrapper levelWrapper) private static String serialize(BlockState blockState, ILevelWrapper levelWrapper)
#endif
{ {
if (blockState == null) if (blockState == null)
{ {
@@ -854,7 +1157,9 @@ public class BlockStateWrapper implements IBlockStateWrapper
Identifier resourceLocation; Identifier resourceLocation;
#endif #endif
#if MC_VER <= MC_1_17_1 #if MC_VER <= MC_1_12_2
resourceLocation = blockState.getBlock().getRegistryName();
#elif MC_VER <= MC_1_17_1
resourceLocation = Registry.BLOCK.getKey(blockState.getBlock()); resourceLocation = Registry.BLOCK.getKey(blockState.getBlock());
#elif MC_VER <= MC_1_19_2 #elif MC_VER <= MC_1_19_2
resourceLocation = registryAccess.registryOrThrow(Registry.BLOCK_REGISTRY).getKey(blockState.getBlock()); resourceLocation = registryAccess.registryOrThrow(Registry.BLOCK_REGISTRY).getKey(blockState.getBlock());
@@ -953,7 +1258,9 @@ public class BlockStateWrapper implements IBlockStateWrapper
#endif #endif
Block block; Block block;
#if MC_VER <= MC_1_17_1 #if MC_VER <= MC_1_12_2
block = Block.REGISTRY.getObject(resourceLocation);
#elif MC_VER <= MC_1_17_1
block = Registry.BLOCK.get(resourceLocation); block = Registry.BLOCK.get(resourceLocation);
#elif MC_VER <= MC_1_19_2 #elif MC_VER <= MC_1_19_2
net.minecraft.core.RegistryAccess registryAccess = level.registryAccess(); net.minecraft.core.RegistryAccess registryAccess = level.registryAccess();
@@ -982,11 +1289,24 @@ public class BlockStateWrapper implements IBlockStateWrapper
// attempt to find the blockstate from all possibilities // attempt to find the blockstate from all possibilities
#if MC_VER <= MC_1_12_2
IBlockState foundState = null;
#else
BlockState foundState = null; BlockState foundState = null;
#endif
if (blockStatePropertiesString != null) if (blockStatePropertiesString != null)
{ {
#if MC_VER <= MC_1_12_2
List<IBlockState> possibleStateList = block.getBlockState().getValidStates();
#else
List<BlockState> possibleStateList = block.getStateDefinition().getPossibleStates(); List<BlockState> possibleStateList = block.getStateDefinition().getPossibleStates();
#endif
#if MC_VER <= MC_1_12_2
for (IBlockState possibleState : possibleStateList)
#else
for (BlockState possibleState : possibleStateList) for (BlockState possibleState : possibleStateList)
#endif
{ {
String possibleStatePropertiesString = serializeBlockStateProperties(possibleState); String possibleStatePropertiesString = serializeBlockStateProperties(possibleState);
if (possibleStatePropertiesString.equals(blockStatePropertiesString)) if (possibleStatePropertiesString.equals(blockStatePropertiesString))
@@ -1010,7 +1330,12 @@ public class BlockStateWrapper implements IBlockStateWrapper
} }
} }
foundState = block.defaultBlockState();
#if MC_VER <= MC_1_12_2
foundState = block.getDefaultState();
#else
foundState = block.defaultBlockState();
#endif
} }
foundWrapper = fromBlockState(foundState, levelWrapper); foundWrapper = fromBlockState(foundState, levelWrapper);
@@ -1035,26 +1360,44 @@ public class BlockStateWrapper implements IBlockStateWrapper
} }
/** used to compare and save BlockStates based on their properties */ /** used to compare and save BlockStates based on their properties */
#if MC_VER <= MC_1_12_2
private static String serializeBlockStateProperties(IBlockState blockState)
#else
private static String serializeBlockStateProperties(BlockState blockState) private static String serializeBlockStateProperties(BlockState blockState)
#endif
{ {
// get the property list for this block (doesn't contain this block state's values, just the names and possible values) // get the property list for this block (doesn't contain this block state's values, just the names and possible values)
java.util.Collection<net.minecraft.world.level.block.state.properties.Property<?>> blockPropertyCollection = blockState.getProperties(); #if MC_VER <= MC_1_12_2
java.util.Collection<IProperty<?>> blockPropertyCollection = blockState.getPropertyKeys();
List<IProperty<?>> sortedBlockPropteryList = new ArrayList<>(blockPropertyCollection);
#else
java.util.Collection<net.minecraft.world.level.block.state.properties.Property<?>> blockPropertyCollection = blockState.getProperties();;
List<net.minecraft.world.level.block.state.properties.Property<?>> sortedBlockPropteryList = new ArrayList<>(blockPropertyCollection);
#endif
// alphabetically sort the list so they are always in the same order // alphabetically sort the list so they are always in the same order
List<net.minecraft.world.level.block.state.properties.Property<?>> sortedBlockPropteryList = new ArrayList<>(blockPropertyCollection);
sortedBlockPropteryList.sort((a, b) -> a.getName().compareTo(b.getName())); sortedBlockPropteryList.sort((a, b) -> a.getName().compareTo(b.getName()));
StringBuilder stringBuilder = new StringBuilder(); StringBuilder stringBuilder = new StringBuilder();
#if MC_VER <= MC_1_12_2
for (IProperty<?> property : sortedBlockPropteryList)
#else
for (net.minecraft.world.level.block.state.properties.Property<?> property : sortedBlockPropteryList) for (net.minecraft.world.level.block.state.properties.Property<?> property : sortedBlockPropteryList)
#endif
{ {
String propertyName = property.getName(); String propertyName = property.getName();
String value = "NULL"; String value = "NULL";
#if MC_VER <= MC_1_12_2
value = blockState.getValue(property).toString();
#else
if (blockState.hasProperty(property)) if (blockState.hasProperty(property))
{ {
value = blockState.getValue(property).toString(); value = blockState.getValue(property).toString();
} }
#endif
stringBuilder.append("{"); stringBuilder.append("{");
stringBuilder.append(propertyName).append(RESOURCE_LOCATION_SEPARATOR).append(value); stringBuilder.append(propertyName).append(RESOURCE_LOCATION_SEPARATOR).append(value);
@@ -32,22 +32,31 @@ import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapp
import com.seibel.distanthorizons.coreapi.DependencyInjection.ApiEventInjector; import com.seibel.distanthorizons.coreapi.DependencyInjection.ApiEventInjector;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.renderer.texture.TextureAtlasSprite;
#if MC_VER <= MC_1_12_2
import net.minecraft.block.state.IBlockState;
import net.minecraft.init.Blocks;
import net.minecraft.util.EnumBlockRenderType;
import net.minecraft.util.EnumFacing;
import net.minecraft.block.BlockRotatedPillar;
import net.minecraft.block.*;
import net.minecraft.client.multiplayer.WorldClient;
import net.minecraft.client.renderer.color.BlockColors;
import net.minecraft.util.math.BlockPos;
#else
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
import net.minecraft.world.level.block.*; import net.minecraft.world.level.block.*;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import com.seibel.distanthorizons.core.logging.DhLogger;
import net.minecraft.world.level.block.state.properties.SlabType; import net.minecraft.world.level.block.state.properties.SlabType;
#endif
import com.seibel.distanthorizons.core.logging.DhLogger;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.ArrayList; import java.util.*;
import java.util.HashSet;
import java.util.List;
import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.ReentrantLock;
#if MC_VER >= MC_1_19_2 #if MC_VER >= MC_1_19_2
import net.minecraft.util.RandomSource; import net.minecraft.util.RandomSource;
#else #else
import java.util.Random;
#endif #endif
#if MC_VER < MC_1_21_5 #if MC_VER < MC_1_21_5
@@ -64,19 +73,32 @@ import net.minecraft.client.color.block.BlockTintSource;
/** /**
* This stores and calculates the colors * This stores and calculates the colors
* the given {@link BlockState} should have based * the given BlockState should have based
* on the given {@link IClientLevelWrapper}. * on the given {@link IClientLevelWrapper}.
* *
* @see ColorUtil * @see ColorUtil
*/ */
public class ClientBlockStateColorCache public class ClientBlockStateColorCache
{ {
private static final DhLogger LOGGER = new DhLoggerBuilder().build(); private static final DhLogger LOGGER = new DhLoggerBuilder().build();
#if MC_VER <= MC_1_12_2
private static final Minecraft MC = Minecraft.getMinecraft();
#else
private static final Minecraft MC = Minecraft.getInstance(); private static final Minecraft MC = Minecraft.getInstance();
#endif
#if MC_VER <= MC_1_12_2
#else
private static final HashSet<BlockState> BLOCK_STATES_THAT_NEED_LEVEL = new HashSet<>(); private static final HashSet<BlockState> BLOCK_STATES_THAT_NEED_LEVEL = new HashSet<>();
#endif
#if MC_VER <= MC_1_12_2
private static final HashSet<IBlockState> BROKEN_BLOCK_STATES = new HashSet<>();
#else
private static final HashSet<BlockState> BROKEN_BLOCK_STATES = new HashSet<>(); private static final HashSet<BlockState> BROKEN_BLOCK_STATES = new HashSet<>();
#endif
/** /**
* Methods using MC's "RandomSource" object aren't thread safe <br> * Methods using MC's "RandomSource" object aren't thread safe <br>
@@ -88,18 +110,33 @@ public class ClientBlockStateColorCache
*/ */
private static final ReentrantLock RESOLVE_LOCK = new ReentrantLock(); private static final ReentrantLock RESOLVE_LOCK = new ReentrantLock();
public static final int INVALID_COLOR = -1;
/** This is the order each direction on a block is processed when attempting to get the texture/color */ /** This is the order each direction on a block is processed when attempting to get the texture/color */
#if MC_VER <= MC_1_12_2
private static final @Nullable EnumFacing[] COLOR_RESOLUTION_DIRECTION_ORDER =
{
EnumFacing.UP,
null, // null represents "unculled" faces, IE the top of farmland
EnumFacing.NORTH,
EnumFacing.EAST,
EnumFacing.WEST,
EnumFacing.SOUTH,
EnumFacing.DOWN
};
#else
private static final @Nullable Direction[] COLOR_RESOLUTION_DIRECTION_ORDER = private static final @Nullable Direction[] COLOR_RESOLUTION_DIRECTION_ORDER =
{ {
Direction.UP, Direction.UP,
null, // null represents "unculled" faces, IE the top of farmland null, // null represents "unculled" faces, IE the top of farmland
Direction.NORTH, Direction.NORTH,
Direction.EAST, Direction.EAST,
Direction.WEST, Direction.WEST,
Direction.SOUTH, Direction.SOUTH,
Direction.DOWN Direction.DOWN
}; };
#endif
private static final int FLOWER_COLOR_SCALE = 5; private static final int FLOWER_COLOR_SCALE = 5;
@@ -113,7 +150,11 @@ public class ClientBlockStateColorCache
#endif #endif
private final IClientLevelWrapper clientLevelWrapper; private final IClientLevelWrapper clientLevelWrapper;
#if MC_VER <= MC_1_12_2
private final IBlockState blockState;
#else
private final BlockState blockState; private final BlockState blockState;
#endif
private final BlockStateWrapper blockStateWrapper; private final BlockStateWrapper blockStateWrapper;
private boolean isColorResolved = false; private boolean isColorResolved = false;
@@ -191,8 +232,10 @@ public class ClientBlockStateColorCache
}; };
// these are threadlocals since AbstractDhTintGetter use local variables to handle color queries // these are threadlocals since AbstractDhTintGetter use local variables to handle color queries
#if MC_VER > MC_1_12_2
private static final ThreadLocal<TintWithoutLevelOverrider> TintWithoutLevelOverrideGetter = ThreadLocal.withInitial(TintWithoutLevelOverrider::new); private static final ThreadLocal<TintWithoutLevelOverrider> TintWithoutLevelOverrideGetter = ThreadLocal.withInitial(TintWithoutLevelOverrider::new);
private static final ThreadLocal<TintGetterOverride> TintOverrideGetter = ThreadLocal.withInitial(TintGetterOverride::new); private static final ThreadLocal<TintGetterOverride> TintOverrideGetter = ThreadLocal.withInitial(TintGetterOverride::new);
#endif
private static final ThreadLocal<DhApiBlockColorOverrideEvent.EventParam> ColorOverrideEventParamGetter = ThreadLocal.withInitial(DhApiBlockColorOverrideEvent.EventParam::new); private static final ThreadLocal<DhApiBlockColorOverrideEvent.EventParam> ColorOverrideEventParamGetter = ThreadLocal.withInitial(DhApiBlockColorOverrideEvent.EventParam::new);
//endregion //endregion
@@ -204,7 +247,11 @@ public class ClientBlockStateColorCache
//=============// //=============//
//region //region
#if MC_VER <= MC_1_12_2
public ClientBlockStateColorCache(IBlockState blockState, IClientLevelWrapper clientLevelWrapper)
#else
public ClientBlockStateColorCache(BlockState blockState, IClientLevelWrapper clientLevelWrapper) public ClientBlockStateColorCache(BlockState blockState, IClientLevelWrapper clientLevelWrapper)
#endif
{ {
this.blockState = blockState; this.blockState = blockState;
this.blockStateWrapper = BlockStateWrapper.fromBlockState(blockState, clientLevelWrapper); this.blockStateWrapper = BlockStateWrapper.fromBlockState(blockState, clientLevelWrapper);
@@ -220,6 +267,7 @@ public class ClientBlockStateColorCache
//===================// //===================//
// color calculation // // color calculation //
//===================// //===================//
//region
private void resolveColors() private void resolveColors()
{ {
@@ -233,17 +281,57 @@ public class ClientBlockStateColorCache
// getQuads() isn't thread safe so we need to put this logic in a lock // getQuads() isn't thread safe so we need to put this logic in a lock
RESOLVE_LOCK.lock(); RESOLVE_LOCK.lock();
if (this.blockState.getFluidState().isEmpty()) #if MC_VER <= MC_1_12_2
if (this.blockState.getRenderType() == EnumBlockRenderType.ENTITYBLOCK_ANIMATED)
{
this.needPostTinting = false;
this.tintIndex = 0;
this.baseColor = ColorUtil.argbToInt(255,
this.blockStateWrapper.getMapColor().getRed(),
this.blockStateWrapper.getMapColor().getGreen(),
this.blockStateWrapper.getMapColor().getBlue());
this.isColorResolved = true;
return;
}
#endif
if (!this.blockStateWrapper.isLiquid())
{ {
// look for the first non-empty direction // look for the first non-empty direction
List<BakedQuad> quads = null; List<BakedQuad> quads = null;
for (Direction direction : COLOR_RESOLUTION_DIRECTION_ORDER)
#if MC_VER <= MC_1_12_2
EnumFacing direction;
#else
Direction direction;
#endif
for (int i = 0; i < COLOR_RESOLUTION_DIRECTION_ORDER.length; i++)
{ {
quads = this.getQuadsForDirection(direction); direction = COLOR_RESOLUTION_DIRECTION_ORDER[i];
if (quads != null && !quads.isEmpty() try
{
quads = this.getQuadsForDirection(direction);
}
catch (Exception ignore)
{
// failing to get quads can happen in the block is invalid
// (i.e. AIR is somehow passed in)
}
// return for the first valid direction we find
if (quads != null
&& !quads.isEmpty()
// for rotated blocks (ie logs) we want the side instead of the top,
// so logs use their bark side instead of their cut/inner side
&& !( && !(
#if MC_VER <= MC_1_12_2
this.blockState.getBlock() instanceof BlockRotatedPillar
&& direction == EnumFacing.UP
#else
this.blockState.getBlock() instanceof RotatedPillarBlock this.blockState.getBlock() instanceof RotatedPillarBlock
&& direction == Direction.UP && direction == Direction.UP
#endif
) )
) )
{ {
@@ -253,7 +341,15 @@ public class ClientBlockStateColorCache
if (quads == null || quads.isEmpty()) if (quads == null || quads.isEmpty())
{ {
quads = this.getUnculledQuads(); try
{
quads = this.getUnculledQuads();
}
catch (Exception ignore)
{
// failing to get quads can happen in the block is invalid
// (i.e. AIR is somehow passed in)
}
} }
if (quads != null if (quads != null
@@ -263,8 +359,10 @@ public class ClientBlockStateColorCache
try try
{ {
BakedQuad firstQuad = quads.get(0); BakedQuad firstQuad = quads.get(0);
#if MC_VER <= MC_1_21_11 #if MC_VER <= MC_1_12_2
this.needPostTinting = firstQuad.hasTintIndex();
#elif 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();
@@ -278,7 +376,7 @@ public class ClientBlockStateColorCache
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 && MC_VER > MC_1_12_2
this.baseColor = calculateColorFromTexture( this.baseColor = calculateColorFromTexture(
firstQuad.sprite, firstQuad.sprite,
EColorMode.getColorMode(this.blockState.getBlock())); EColorMode.getColorMode(this.blockState.getBlock()));
@@ -329,6 +427,23 @@ public class ClientBlockStateColorCache
this.isColorResolved = true; this.isColorResolved = true;
} }
catch (Exception resolveError)
{
LOGGER.warn("Failed to get color for block ["+this.blockStateWrapper.getSerialString()+"], error: ["+resolveError.getMessage()+"]. Attempting to use particle icon color...", resolveError);
this.needPostTinting = true;
this.tintIndex = 0;
try
{
this.baseColor = this.getParticleIconColor();
}
catch (Exception getParticleIconError)
{
LOGGER.warn("Failed to get particle icon color for block ["+this.blockStateWrapper.getSerialString()+"], error: ["+getParticleIconError.getMessage()+"], block will render as hot pink.", getParticleIconError);
this.baseColor = ColorUtil.HOT_PINK;
}
}
finally finally
{ {
RESOLVE_LOCK.unlock(); RESOLVE_LOCK.unlock();
@@ -336,22 +451,81 @@ public class ClientBlockStateColorCache
} }
@Nullable @Nullable
private List<BakedQuad> getUnculledQuads() { return this.getQuadsForDirection(null); } private List<BakedQuad> getUnculledQuads() throws Exception { return this.getQuadsForDirection(null); }
/**
* throws Exception is to document that rarely MC will throw errors if this method
* is called on the wrong block (even though in that case it should just return null).
*/
@Nullable @Nullable
private List<BakedQuad> getQuadsForDirection(@Nullable Direction direction) #if MC_VER <= MC_1_12_2
private List<BakedQuad> getQuadsForDirection(@Nullable EnumFacing direction) throws Exception
#else
private List<BakedQuad> getQuadsForDirection(@Nullable Direction direction) throws Exception
#endif
{ {
#if MC_VER <= MC_1_12_2
IBlockState effectiveBlockState = this.blockState;
#else
BlockState effectiveBlockState = this.blockState; BlockState effectiveBlockState = this.blockState;
#endif
//=========================//
// specific state handling //
//=========================//
//region
// if this block is a slab, use it's double variant so we can get the top face, // if this block is a slab, use it's double variant so we can get the top face,
// otherwise the color will use the side, which isn't as accurate // otherwise the color will use the side, which isn't as accurate
#if MC_VER <= MC_1_12_2
if (this.blockState.getBlock() instanceof BlockSlab && !((BlockSlab) this.blockState.getBlock()).isDouble())
{
effectiveBlockState = this.blockState.withProperty(BlockSlab.HALF, BlockSlab.EnumBlockHalf.TOP);
}
#else
if (this.blockState.getBlock() instanceof SlabBlock) if (this.blockState.getBlock() instanceof SlabBlock)
{ {
effectiveBlockState = this.blockState.setValue( SlabBlock.TYPE, SlabType.DOUBLE ); effectiveBlockState = this.blockState.setValue( SlabBlock.TYPE, SlabType.DOUBLE );
} }
#endif
// huge mushroom block sides will show the inner color,
// which isn't what you want to see at a distance,
// you want to see the primary color (ie red for red mushrooms)
// which is shown on all sides for the default state
#if MC_VER <= MC_1_12_2
if (this.blockState.getBlock() instanceof BlockHugeMushroom)
{
effectiveBlockState = this.blockState.getBlock().getDefaultState();
}
#else
if (this.blockState.getBlock() instanceof HugeMushroomBlock)
{
effectiveBlockState = this.blockState.getBlock().defaultBlockState();
}
#endif
//endregion
//===============//
// quad handling //
//===============//
//region
List<BakedQuad> quads; List<BakedQuad> quads;
#if MC_VER < MC_1_21_5 #if MC_VER <= MC_1_12_2
try {
quads = MC.getBlockRendererDispatcher().getModelForState(effectiveBlockState).getQuads(effectiveBlockState, direction, RANDOM.nextLong());
}
catch (Exception e)
{
quads = Collections.emptyList();
}
#elif MC_VER < MC_1_21_5
quads = MC.getModelManager().getBlockModelShaper(). quads = MC.getModelManager().getBlockModelShaper().
getBlockModel(effectiveBlockState).getQuads(effectiveBlockState, direction, RANDOM); getBlockModel(effectiveBlockState).getQuads(effectiveBlockState, direction, RANDOM);
#elif MC_VER <= MC_1_21_11 #elif MC_VER <= MC_1_21_11
@@ -380,6 +554,8 @@ public class ClientBlockStateColorCache
} }
#endif #endif
//endregion
return quads; return quads;
} }
@@ -408,10 +584,18 @@ public class ClientBlockStateColorCache
//_ OpenGL RGBA format Java Order: 0xAA BB GG RR //_ OpenGL RGBA format Java Order: 0xAA BB GG RR
tempColor = TextureAtlasSpriteWrapper.getPixelRGBA(texture, 0, u, v); tempColor = TextureAtlasSpriteWrapper.getPixelRGBA(texture, 0, u, v);
#if MC_VER <= MC_1_12_2
int b = (tempColor & 0x000000FF);
int g = (tempColor & 0x0000FF00) >>> 8;
int r = (tempColor & 0x00FF0000) >>> 16;
int a = (tempColor & 0xFF000000) >>> 24;
#else
int r = (tempColor & 0x000000FF); int r = (tempColor & 0x000000FF);
int g = (tempColor & 0x0000FF00) >>> 8; int g = (tempColor & 0x0000FF00) >>> 8;
int b = (tempColor & 0x00FF0000) >>> 16; int b = (tempColor & 0x00FF0000) >>> 16;
int a = (tempColor & 0xFF000000) >>> 24; int a = (tempColor & 0xFF000000) >>> 24;
#endif
int scale = 1; int scale = 1;
if (colorMode == EColorMode.Leaves) if (colorMode == EColorMode.Leaves)
{ {
@@ -468,7 +652,9 @@ public class ClientBlockStateColorCache
} }
private static int getTextureWidth(TextureAtlasSprite texture) private static int getTextureWidth(TextureAtlasSprite texture)
{ {
#if MC_VER < MC_1_19_4 #if MC_VER <= MC_1_12_2
return texture.getIconWidth();
#elif MC_VER < MC_1_19_4
return texture.getWidth(); return texture.getWidth();
#else #else
return texture.contents().width(); return texture.contents().width();
@@ -476,7 +662,9 @@ public class ClientBlockStateColorCache
} }
private static int getTextureHeight(TextureAtlasSprite texture) private static int getTextureHeight(TextureAtlasSprite texture)
{ {
#if MC_VER < MC_1_19_4 #if MC_VER <= MC_1_12_2
return texture.getIconHeight();
#elif MC_VER < MC_1_19_4
return texture.getHeight(); return texture.getHeight();
#else #else
return texture.contents().height(); return texture.contents().height();
@@ -509,8 +697,19 @@ public class ClientBlockStateColorCache
private int getParticleIconColor() private int getParticleIconColor()
{ {
// Air can be null which will cause issues below,
// just use a static color, it shouldn't be rendered anyway.
// This is just to capture a rare bug state where we attempt
// to get air's color.
if (BlockStateWrapper.isAir(this.blockState))
{
return ColorUtil.INVISIBLE;
}
return calculateColorFromTexture( return calculateColorFromTexture(
#if MC_VER <= MC_1_21_11 #if MC_VER <= MC_1_12_2
Minecraft.getMinecraft().getBlockRendererDispatcher().getBlockModelShapes().getTexture(this.blockState),
#elif MC_VER <= MC_1_21_11
Minecraft.getInstance().getModelManager().getBlockModelShaper().getParticleIcon(this.blockState), Minecraft.getInstance().getModelManager().getBlockModelShaper().getParticleIcon(this.blockState),
#else #else
Minecraft.getInstance().getModelManager().getBlockStateModelSet().get(this.blockState).particleMaterial().sprite(), Minecraft.getInstance().getModelManager().getBlockStateModelSet().get(this.blockState).particleMaterial().sprite(),
@@ -518,16 +717,22 @@ public class ClientBlockStateColorCache
EColorMode.getColorMode(this.blockState.getBlock())); EColorMode.getColorMode(this.blockState.getBlock()));
} }
//endregion
//===============// //===============//
// public getter // // public getter //
//===============// //===============//
//region
public int getColor(BiomeWrapper biomeWrapper, FullDataSourceV2 fullDataSource, DhBlockPos blockPos) public int getColor(
BiomeWrapper biomeWrapper, FullDataSourceV2 fullDataSource, DhBlockPos blockPos,
boolean allowApiOverride)
{ {
// only get the tint if the block needs to be tinted // only get the tint if the block needs to be tinted
int tintColor = AbstractDhTintGetter.INVALID_COLOR; int tintColor = ClientBlockStateColorCache.INVALID_COLOR;
if (this.needPostTinting) if (this.needPostTinting)
{ {
// don't try tinting blocks that don't support our method of tint getting // don't try tinting blocks that don't support our method of tint getting
@@ -540,28 +745,62 @@ public class ClientBlockStateColorCache
// attempt to get the tint // attempt to get the tint
try try
{ {
#if MC_VER <= MC_1_12_2
// 1.12.2 doesn't have BlockAndTintGetter -> get tintColor from biome
WorldClient world = (WorldClient) this.clientLevelWrapper.getWrappedMcObject();
BlockPos mcPos = new BlockPos(blockPos.getX(), blockPos.getY(), blockPos.getZ());
Block block = this.blockState.getBlock();
if (block instanceof BlockGrass
|| block instanceof BlockBush)
{
tintColor = biomeWrapper.biome.getGrassColorAtPos(mcPos);
}
else if (block instanceof BlockLeaves)
{
tintColor = biomeWrapper.biome.getFoliageColorAtPos(mcPos);
}
else if (block instanceof BlockLiquid) // We don't want lava to fall into the else block
{
if(block == Blocks.WATER
|| block == Blocks.FLOWING_WATER)
{
tintColor = biomeWrapper.biome.getWaterColor();
}
}
else
{
BlockColors blockColors = Minecraft.getMinecraft().getBlockColors();
tintColor = blockColors.colorMultiplier(blockState, world, mcPos, this.tintIndex);
if (tintColor == ClientBlockStateColorCache.INVALID_COLOR)
{
tintColor = blockColors.getColor(blockState, world, mcPos);
}
}
#else
// try to use the fast tint getter logic first // try to use the fast tint getter logic first
if (!BLOCK_STATES_THAT_NEED_LEVEL.contains(this.blockState)) if (!BLOCK_STATES_THAT_NEED_LEVEL.contains(this.blockState))
{ {
try try
{ {
TintWithoutLevelOverrider tintOverride = TintWithoutLevelOverrideGetter.get(); TintWithoutLevelOverrider tintOverride = TintWithoutLevelOverrideGetter.get();
tintOverride.update(biomeWrapper, this.blockStateWrapper, fullDataSource, this.clientLevelWrapper); tintOverride.update(biomeWrapper, this.blockStateWrapper, fullDataSource, this.clientLevelWrapper);
// try using DH's cached tint values first if possible // try using DH's cached tint values first if possible
tintColor = tintOverride.tryGetBlockTint(new DhBlockPosMutable(blockPos)); tintColor = tintOverride.tryGetBlockTint(new DhBlockPosMutable(blockPos));
if (tintColor == AbstractDhTintGetter.INVALID_COLOR) if (tintColor == ClientBlockStateColorCache.INVALID_COLOR)
{ {
// one or more tint values weren't calculated, // one or more tint values weren't calculated,
// we need MC's color resolver // we need MC's color resolver
#if MC_VER <= MC_1_21_11 #if MC_VER <= MC_1_21_11
tintColor = Minecraft.getInstance() tintColor = Minecraft.getInstance()
.getBlockColors() .getBlockColors()
.getColor(this.blockState, .getColor(this.blockState,
tintOverride, // tintOverride will save the result of this query to speed up future queries tintOverride, // tintOverride will save the result of this query to speed up future queries
McObjectConverter.Convert(blockPos), McObjectConverter.Convert(blockPos),
this.tintIndex); this.tintIndex);
#else #else
BlockTintSource tintSource = Minecraft.getInstance() BlockTintSource tintSource = Minecraft.getInstance()
.getBlockColors() .getBlockColors()
.getTintSource(this.blockState, this.tintIndex); .getTintSource(this.blockState, this.tintIndex);
@@ -572,18 +811,12 @@ public class ClientBlockStateColorCache
{ {
BlockPos mcPos = McObjectConverter.Convert(blockPos); BlockPos mcPos = McObjectConverter.Convert(blockPos);
tintColor = tintSource.colorInWorld(this.blockState, tintOverride, mcPos); tintColor = tintSource.colorInWorld(this.blockState, tintOverride, mcPos);
if (tintColor == -1) if (tintColor == ClientBlockStateColorCache.INVALID_COLOR)
{ {
tintColor = tintSource.colorAsTerrainParticle(this.blockState, tintOverride, mcPos); tintColor = tintSource.colorAsTerrainParticle(this.blockState, tintOverride, mcPos);
} }
} }
if (tintColor == -1)
{
// no color found, use the base color
tintColor = AbstractDhTintGetter.INVALID_COLOR;
}
// save this color to speed up future queries // save this color to speed up future queries
TintWithoutLevelOverrider.setStaticColor(this.blockStateWrapper, biomeWrapper, tintColor); TintWithoutLevelOverrider.setStaticColor(this.blockStateWrapper, biomeWrapper, tintColor);
// try to get the blended color with this new information // try to get the blended color with this new information
@@ -593,44 +826,47 @@ public class ClientBlockStateColorCache
} }
catch (Exception e) catch (Exception e)
{ {
#if MC_VER <= MC_1_21_11 #if MC_VER <= MC_1_21_11
// this exception generally occurs if the tint requires other blocks besides itself // this exception generally occurs if the tint requires other blocks besides itself
LOGGER.debug("Unable to use ["+ TintWithoutLevelOverrider.class.getSimpleName()+"] to get the block tint for block: [" + this.blockState + "] and biome: [" + biomeWrapper + "] at pos: " + blockPos + ". Error: [" + e.getMessage() + "]. Attempting to use backup method...", e); LOGGER.debug("Unable to use ["+ TintWithoutLevelOverrider.class.getSimpleName()+"] to get the block tint for block: [" + this.blockState + "] and biome: [" + biomeWrapper + "] at pos: " + blockPos + ". Error: [" + e.getMessage() + "]. Attempting to use backup method...", e);
BLOCK_STATES_THAT_NEED_LEVEL.add(this.blockState); BLOCK_STATES_THAT_NEED_LEVEL.add(this.blockState);
#else #else
// only display the error once per block/biome type to reduce log spam // only display the error once per block/biome type to reduce log spam
if (!BROKEN_BLOCK_STATES.contains(this.blockState)) if (!BROKEN_BLOCK_STATES.contains(this.blockState))
{ {
LOGGER.warn("Failed to get block color for block: [" + this.blockState + "] and biome: [" + biomeWrapper + "] at pos: " + blockPos + ". Error: [" + e.getMessage() + "]. Note: future errors for this block/biome will be ignored.", e); LOGGER.warn("Failed to get block color for block: [" + this.blockState + "] and biome: [" + biomeWrapper + "] at pos: " + blockPos + ". Error: [" + e.getMessage() + "]. Note: future errors for this block/biome will be ignored.", e);
BROKEN_BLOCK_STATES.add(this.blockState); BROKEN_BLOCK_STATES.add(this.blockState);
} }
#endif #endif
} }
} }
#endif
// level-specific logic is only needed for MC 1.21.11 and older // level-specific logic is only needed for MC 1.21.11 and older
#if MC_VER <= MC_1_21_11 #if MC_VER <= MC_1_21_11 && MC_VER > MC_1_12_2
// use the level logic only if requested // use the level logic only if requested
if (BLOCK_STATES_THAT_NEED_LEVEL.contains(this.blockState)) if (BLOCK_STATES_THAT_NEED_LEVEL.contains(this.blockState))
{
// the level shouldn't be used all the time due to it breaking some blocks tinting
// specifically oceans don't render correctly
TintGetterOverride tintOverride = TintOverrideGetter.get();
tintOverride.update(biomeWrapper, this.blockStateWrapper, fullDataSource, this.clientLevelWrapper);
tintColor = tintOverride.tryGetBlockTint(new DhBlockPosMutable(blockPos));
if (tintColor == AbstractDhTintGetter.INVALID_COLOR)
{ {
tintColor = Minecraft.getInstance() // the level shouldn't be used all the time due to it breaking some blocks tinting
.getBlockColors() // specifically oceans don't render correctly
.getColor(this.blockState,
tintOverride, TintGetterOverride tintOverride = TintOverrideGetter.get();
McObjectConverter.Convert(blockPos), tintOverride.update(biomeWrapper, this.blockStateWrapper, fullDataSource, this.clientLevelWrapper);
this.tintIndex);
tintColor = tintOverride.tryGetBlockTint(new DhBlockPosMutable(blockPos));
if (tintColor == ClientBlockStateColorCache.INVALID_COLOR)
{
tintColor = Minecraft.getInstance()
.getBlockColors()
.getColor(this.blockState,
tintOverride,
McObjectConverter.Convert(blockPos),
this.tintIndex);
}
} }
} #endif
#endif
} }
catch (Exception e) catch (Exception e)
{ {
@@ -645,7 +881,7 @@ public class ClientBlockStateColorCache
int returnColor; int returnColor;
if (tintColor != AbstractDhTintGetter.INVALID_COLOR) if (tintColor != ClientBlockStateColorCache.INVALID_COLOR)
{ {
returnColor = ColorUtil.multiplyARGBwithRGB(this.baseColor, tintColor); returnColor = ColorUtil.multiplyARGBwithRGB(this.baseColor, tintColor);
} }
@@ -656,14 +892,17 @@ public class ClientBlockStateColorCache
} }
// only fire an API event if needed // only fire the API event if allowed
// (this is done to reduce GC pressure and speed up color getting) // (done to prevent infinite loops if called during by another color resolution event)
if (this.blockStateWrapper.allowApiColorOverride()) if (allowApiOverride
// if the API event is requested
// (this is done to reduce GC pressure and speed up color getting)
&& this.blockStateWrapper.allowApiColorOverride())
{ {
DhApiBlockColorOverrideEvent.EventParam eventParam = ColorOverrideEventParamGetter.get(); DhApiBlockColorOverrideEvent.EventParam eventParam = ColorOverrideEventParamGetter.get();
eventParam.update( eventParam.update(
this.clientLevelWrapper, this.clientLevelWrapper, fullDataSource,
this.blockStateWrapper, returnColor, this.blockStateWrapper, biomeWrapper, returnColor,
blockPos.getX(), blockPos.getY(), blockPos.getZ() blockPos.getX(), blockPos.getY(), blockPos.getZ()
); );
ApiEventInjector.INSTANCE.fireAllEvents(DhApiBlockColorOverrideEvent.class, eventParam); ApiEventInjector.INSTANCE.fireAllEvents(DhApiBlockColorOverrideEvent.class, eventParam);
@@ -675,6 +914,25 @@ public class ClientBlockStateColorCache
return returnColor; return returnColor;
} }
//endregion
//=========//
// cleanup //
//=========//
//region
public static void clearCachedTints()
{
#if MC_VER <= MC_1_12_2
#else
AbstractDhTintGetter.clear();
#endif
}
//endregion
//================// //================//
@@ -692,14 +950,54 @@ public class ClientBlockStateColorCache
static EColorMode getColorMode(Block block) static EColorMode getColorMode(Block block)
{ {
if (block instanceof LeavesBlock)
//========//
// leaves //
//========//
//region
boolean isLeavesBlock;
#if MC_VER <= MC_1_12_2
isLeavesBlock = block instanceof BlockLeaves;
#else
isLeavesBlock = block instanceof LeavesBlock;
#endif
if (isLeavesBlock)
{ {
return Leaves; return Leaves;
} }
if (block instanceof FlowerBlock)
//endregion
//========//
// flower //
//========//
//region
boolean isFlowerBlock;
#if MC_VER <= MC_1_12_2
isFlowerBlock = block instanceof BlockFlower;
#else
isFlowerBlock = block instanceof FlowerBlock;
#endif
if (isFlowerBlock)
{ {
return Flower; return Flower;
} }
//endregion
//=============//
// misc/simple //
//=============//
//region
if (block.toString().contains("glass")) if (block.toString().contains("glass"))
{ {
return Glass; return Glass;
@@ -708,6 +1006,11 @@ public class ClientBlockStateColorCache
{ {
return Chisel; return Chisel;
} }
//endregion
return Default; return Default;
} }
} }
@@ -38,7 +38,10 @@ public class TextureAtlasSpriteWrapper
{ {
public static int getPixelRGBA(TextureAtlasSprite sprite, int frameIndex, int x, int y) public static int getPixelRGBA(TextureAtlasSprite sprite, int frameIndex, int x, int y)
{ {
#if MC_VER < MC_1_17_1 #if MC_VER <= MC_1_12_2
int[][] frameData = sprite.getFrameTextureData(frameIndex);
return frameData[0][y * sprite.getIconWidth() + x];
#elif MC_VER < MC_1_17_1
return sprite.mainImage[0].getPixelRGBA( return sprite.mainImage[0].getPixelRGBA(
x + sprite.framesX[frameIndex] * sprite.getWidth(), x + sprite.framesX[frameIndex] * sprite.getWidth(),
y + sprite.framesY[frameIndex] * sprite.getHeight()); y + sprite.framesY[frameIndex] * sprite.getHeight());
@@ -18,7 +18,7 @@
*/ */
package com.seibel.distanthorizons.common.wrappers.block; package com.seibel.distanthorizons.common.wrappers.block;
#if MC_VER > MC_1_12_2
import com.seibel.distanthorizons.core.dataObjects.fullData.sources.FullDataSourceV2; import com.seibel.distanthorizons.core.dataObjects.fullData.sources.FullDataSourceV2;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
@@ -189,3 +189,4 @@ public class TintGetterOverride extends AbstractDhTintGetter
} }
#endif
@@ -18,7 +18,7 @@
*/ */
package com.seibel.distanthorizons.common.wrappers.block; package com.seibel.distanthorizons.common.wrappers.block;
#if MC_VER > MC_1_12_2
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
import net.minecraft.world.level.LevelReader; import net.minecraft.world.level.LevelReader;
@@ -109,3 +109,4 @@ public class TintWithoutLevelOverrider extends AbstractDhTintGetter
} }
#endif
@@ -31,12 +31,19 @@ import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.ChunkLightStorage
import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IMutableBlockPosWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IMutableBlockPosWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IBiomeWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.world.IBiomeWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
#if MC_VER <= MC_1_12_2
import net.minecraft.block.state.IBlockState;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.chunk.storage.ExtendedBlockStorage;
#else
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.world.level.chunk.ChunkAccess; import net.minecraft.world.level.chunk.ChunkAccess;
import net.minecraft.world.level.chunk.ProtoChunk; import net.minecraft.world.level.chunk.ProtoChunk;
import net.minecraft.world.level.levelgen.Heightmap; import net.minecraft.world.level.levelgen.Heightmap;
#endif
import com.seibel.distanthorizons.core.logging.DhLogger; import com.seibel.distanthorizons.core.logging.DhLogger;
@@ -67,9 +74,10 @@ import net.minecraft.world.level.chunk.LevelChunkSection;
import net.minecraft.world.level.chunk.LevelChunkSection; import net.minecraft.world.level.chunk.LevelChunkSection;
#endif #endif
#if MC_VER <= MC_1_20_4 #if MC_VER <= MC_1_12_2
#elif MC_VER <= MC_1_20_4
import net.minecraft.world.level.chunk.ChunkStatus; import net.minecraft.world.level.chunk.ChunkStatus;
#else #elif MC_VER > MC_1_12_2
import net.minecraft.world.level.chunk.status.ChunkStatus; import net.minecraft.world.level.chunk.status.ChunkStatus;
#endif #endif
@@ -86,8 +94,12 @@ public class ChunkWrapper implements IChunkWrapper
private static boolean heightmapThreadWarningLogged = false; private static boolean heightmapThreadWarningLogged = false;
#if MC_VER <= MC_1_12_2
private final Chunk chunk;
#else
private final ChunkAccess chunk; private final ChunkAccess chunk;
#endif
private final DhChunkPos chunkPos; private final DhChunkPos chunkPos;
private final ILevelWrapper wrappedLevel; private final ILevelWrapper wrappedLevel;
@@ -112,13 +124,17 @@ public class ChunkWrapper implements IChunkWrapper
//=============// //=============//
// constructor // // constructor //
//=============// //=============//
//region
/** /**
* Note: this constructor should be very * Note: this constructor should be very
* fast since it will be called frequently on the MC * fast since it will be called frequently on the MC
* server thread and a slow method will cause server lag. * server thread and a slow method will cause server lag.
*/ */
#if MC_VER <= MC_1_12_2
public ChunkWrapper(Chunk chunk, ILevelWrapper wrappedLevel)
#else
public ChunkWrapper(ChunkAccess chunk, ILevelWrapper wrappedLevel) public ChunkWrapper(ChunkAccess chunk, ILevelWrapper wrappedLevel)
#endif
{ {
this.chunk = chunk; this.chunk = chunk;
this.wrappedLevel = wrappedLevel; this.wrappedLevel = wrappedLevel;
@@ -133,15 +149,22 @@ public class ChunkWrapper implements IChunkWrapper
@Override @Override
public ChunkWrapper copy() { return new ChunkWrapper(this.chunk, this.wrappedLevel); } public ChunkWrapper copy() { return new ChunkWrapper(this.chunk, this.wrappedLevel); }
//endregion
//=========// //=========//
// getters // // getters //
//=========// //=========//
//region
@Override @Override
public int getHeight() { return getHeight(this.chunk); } public int getHeight() { return getHeight(this.chunk); }
#if MC_VER <= MC_1_12_2
public static int getHeight(Chunk chunk)
#else
public static int getHeight(ChunkAccess chunk) public static int getHeight(ChunkAccess chunk)
#endif
{ {
#if MC_VER < MC_1_17_1 #if MC_VER < MC_1_17_1
return 255; return 255;
@@ -152,7 +175,11 @@ public class ChunkWrapper implements IChunkWrapper
@Override @Override
public int getInclusiveMinBuildHeight() { return getInclusiveMinBuildHeight(this.chunk); } public int getInclusiveMinBuildHeight() { return getInclusiveMinBuildHeight(this.chunk); }
#if MC_VER <= MC_1_12_2
public static int getInclusiveMinBuildHeight(Chunk chunk)
#else
public static int getInclusiveMinBuildHeight(ChunkAccess chunk) public static int getInclusiveMinBuildHeight(ChunkAccess chunk)
#endif
{ {
#if MC_VER < MC_1_17_1 #if MC_VER < MC_1_17_1
return 0; return 0;
@@ -165,9 +192,15 @@ public class ChunkWrapper implements IChunkWrapper
@Override @Override
public int getExclusiveMaxBuildHeight() { return getExclusiveMaxBuildHeight(this.chunk); } public int getExclusiveMaxBuildHeight() { return getExclusiveMaxBuildHeight(this.chunk); }
#if MC_VER <= MC_1_12_2
public static int getExclusiveMaxBuildHeight(Chunk chunk)
#else
public static int getExclusiveMaxBuildHeight(ChunkAccess chunk) public static int getExclusiveMaxBuildHeight(ChunkAccess chunk)
#endif
{ {
#if MC_VER < MC_1_21_3 #if MC_VER <= MC_1_12_2
return 256;
#elif MC_VER < MC_1_21_3
return chunk.getMaxBuildHeight(); return chunk.getMaxBuildHeight();
#else #else
// +1 since Minecraft made the max value inclusive // +1 since Minecraft made the max value inclusive
@@ -188,7 +221,11 @@ public class ChunkWrapper implements IChunkWrapper
this.minNonEmptyHeight = this.getInclusiveMinBuildHeight(); this.minNonEmptyHeight = this.getInclusiveMinBuildHeight();
// determine the lowest empty section (bottom up) // determine the lowest empty section (bottom up)
#if MC_VER <= MC_1_12_2
ExtendedBlockStorage[] sections = this.chunk.getBlockStorageArray();
#else
LevelChunkSection[] sections = this.chunk.getSections(); LevelChunkSection[] sections = this.chunk.getSections();
#endif
for (int index = 0; index < sections.length; index++) for (int index = 0; index < sections.length; index++)
{ {
if (sections[index] == null) if (sections[index] == null)
@@ -220,7 +257,11 @@ public class ChunkWrapper implements IChunkWrapper
this.maxNonEmptyHeight = this.getExclusiveMaxBuildHeight(); this.maxNonEmptyHeight = this.getExclusiveMaxBuildHeight();
// determine the highest empty section (top down) // determine the highest empty section (top down)
#if MC_VER <= MC_1_12_2
ExtendedBlockStorage[] sections = this.chunk.getBlockStorageArray();
#else
LevelChunkSection[] sections = this.chunk.getSections(); LevelChunkSection[] sections = this.chunk.getSections();
#endif
for (int index = sections.length-1; index >= 0; index--) for (int index = sections.length-1; index >= 0; index--)
{ {
// update at each position to fix using the max height if the chunk is empty // update at each position to fix using the max height if the chunk is empty
@@ -240,11 +281,13 @@ public class ChunkWrapper implements IChunkWrapper
return this.maxNonEmptyHeight; return this.maxNonEmptyHeight;
} }
#if MC_VER <= MC_1_12_2
private static boolean isChunkSectionEmpty(ExtendedBlockStorage section)
#else
private static boolean isChunkSectionEmpty(LevelChunkSection section) private static boolean isChunkSectionEmpty(LevelChunkSection section)
#endif
{ {
#if MC_VER == MC_1_16_5 #if MC_VER <= MC_1_17_1
return section.isEmpty();
#elif MC_VER == MC_1_17_1
return section.isEmpty(); return section.isEmpty();
#else #else
return section.hasOnlyAir(); return section.hasOnlyAir();
@@ -322,7 +365,11 @@ public class ChunkWrapper implements IChunkWrapper
// will be null if we want to use MC heightmaps // will be null if we want to use MC heightmaps
if (this.solidHeightMap == null) if (this.solidHeightMap == null)
{ {
#if MC_VER <= MC_1_12_2
return this.chunk.getHeightValue(xRel, zRel);
#else
return this.chunk.getOrCreateHeightmapUnprimed(Heightmap.Types.WORLD_SURFACE).getFirstAvailable(xRel, zRel); return this.chunk.getOrCreateHeightmapUnprimed(Heightmap.Types.WORLD_SURFACE).getFirstAvailable(xRel, zRel);
#endif
} }
else else
{ {
@@ -337,19 +384,30 @@ public class ChunkWrapper implements IChunkWrapper
if (this.lightBlockingHeightMap == null) if (this.lightBlockingHeightMap == null)
{ {
#if MC_VER <= MC_1_12_2
return this.chunk.getHeightValue(xRel, zRel);
#else
return this.chunk.getOrCreateHeightmapUnprimed(Heightmap.Types.MOTION_BLOCKING).getFirstAvailable(xRel, zRel); return this.chunk.getOrCreateHeightmapUnprimed(Heightmap.Types.MOTION_BLOCKING).getFirstAvailable(xRel, zRel);
#endif
} }
else else
{ {
return this.lightBlockingHeightMap[xRel][zRel]; return this.lightBlockingHeightMap[xRel][zRel];
} }
} }
@Override @Override
public IBiomeWrapper getBiome(int relX, int relY, int relZ) public IBiomeWrapper getBiome(int relX, int relY, int relZ)
{ {
#if MC_VER < MC_1_17_1 #if MC_VER <= MC_1_12_2
BlockPos.MutableBlockPos blockPos = MUTABLE_BLOCK_POS_REF.get();
blockPos.setPos(relX, relY, relZ);
World world = (World) this.wrappedLevel.getWrappedMcObject();
return BiomeWrapper.getBiomeWrapper(this.chunk.getBiome(blockPos, world.getBiomeProvider()), wrappedLevel);
#elif MC_VER < MC_1_17_1
return BiomeWrapper.getBiomeWrapper(this.chunk.getBiomes().getNoiseBiome( return BiomeWrapper.getBiomeWrapper(this.chunk.getBiomes().getNoiseBiome(
relX >> 2, relY >> 2, relZ >> 2), relX >> 2, relY >> 2, relZ >> 2),
this.wrappedLevel); this.wrappedLevel);
@@ -357,10 +415,6 @@ public class ChunkWrapper implements IChunkWrapper
return BiomeWrapper.getBiomeWrapper(this.chunk.getBiomes().getNoiseBiome( return BiomeWrapper.getBiomeWrapper(this.chunk.getBiomes().getNoiseBiome(
QuartPos.fromBlock(relX), QuartPos.fromBlock(relY), QuartPos.fromBlock(relZ)), QuartPos.fromBlock(relX), QuartPos.fromBlock(relY), QuartPos.fromBlock(relZ)),
this.wrappedLevel); this.wrappedLevel);
#elif MC_VER < MC_1_18_2
return BiomeWrapper.getBiomeWrapper(this.chunk.getNoiseBiome(
QuartPos.fromBlock(relX), QuartPos.fromBlock(relY), QuartPos.fromBlock(relZ)),
this.wrappedLevel);
#else #else
//Now returns a Holder<Biome> instead of Biome //Now returns a Holder<Biome> instead of Biome
return BiomeWrapper.getBiomeWrapper(this.chunk.getNoiseBiome( return BiomeWrapper.getBiomeWrapper(this.chunk.getNoiseBiome(
@@ -376,9 +430,13 @@ public class ChunkWrapper implements IChunkWrapper
BlockPos.MutableBlockPos blockPos = MUTABLE_BLOCK_POS_REF.get(); BlockPos.MutableBlockPos blockPos = MUTABLE_BLOCK_POS_REF.get();
#if MC_VER <= MC_1_12_2
blockPos.setPos(relX, relY, relZ);
#else
blockPos.setX(relX); blockPos.setX(relX);
blockPos.setY(relY); blockPos.setY(relY);
blockPos.setZ(relZ); blockPos.setZ(relZ);
#endif
try try
{ {
@@ -401,9 +459,13 @@ public class ChunkWrapper implements IChunkWrapper
this.throwIndexOutOfBoundsIfRelativePosOutsideChunkBounds(relX, relY, relZ); this.throwIndexOutOfBoundsIfRelativePosOutsideChunkBounds(relX, relY, relZ);
BlockPos.MutableBlockPos pos = (BlockPos.MutableBlockPos)mcBlockPos.getWrappedMcObject(); BlockPos.MutableBlockPos pos = (BlockPos.MutableBlockPos)mcBlockPos.getWrappedMcObject();
#if MC_VER <= MC_1_12_2
pos.setPos(relX, relY, relZ);
#else
pos.setX(relX); pos.setX(relX);
pos.setY(relY); pos.setY(relY);
pos.setZ(relZ); pos.setZ(relZ);
#endif
try try
{ {
@@ -513,8 +575,14 @@ public class ChunkWrapper implements IChunkWrapper
@Override @Override
public DhChunkPos getChunkPos() { return this.chunkPos; } public DhChunkPos getChunkPos() { return this.chunkPos; }
public ChunkAccess getChunk() { return this.chunk; } #if MC_VER <= MC_1_12_2
public Chunk getChunk()
#else
public ChunkAccess getChunk()
#endif
{ return this.chunk; }
#if MC_VER > MC_1_12_2
public void trySetStatus(ChunkStatus status) { trySetStatus(this.getChunk(), status); } public void trySetStatus(ChunkStatus status) { trySetStatus(this.getChunk(), status); }
/** does nothing if the chunk object doesn't support setting it's status */ /** does nothing if the chunk object doesn't support setting it's status */
public static void trySetStatus(ChunkAccess chunk, ChunkStatus status) public static void trySetStatus(ChunkAccess chunk, ChunkStatus status)
@@ -538,21 +606,53 @@ public class ChunkWrapper implements IChunkWrapper
return chunk.getPersistedStatus(); return chunk.getPersistedStatus();
#endif #endif
} }
#endif
@Override @Override
public int getMaxBlockX() { return this.chunk.getPos().getMaxBlockX(); } public int getMaxBlockX()
{
#if MC_VER <= MC_1_12_2
return this.chunk.getPos().getXEnd();
#else
return this.chunk.getPos().getMaxBlockX();
#endif
}
@Override @Override
public int getMaxBlockZ() { return this.chunk.getPos().getMaxBlockZ(); } public int getMaxBlockZ()
{
#if MC_VER <= MC_1_12_2
return this.chunk.getPos().getZEnd();
#else
return this.chunk.getPos().getMaxBlockZ();
#endif
}
@Override @Override
public int getMinBlockX() { return this.chunk.getPos().getMinBlockX(); } public int getMinBlockX()
{
#if MC_VER <= MC_1_12_2
return this.chunk.getPos().getXStart();
#else
return this.chunk.getPos().getMinBlockX();
#endif
}
@Override @Override
public int getMinBlockZ() { return this.chunk.getPos().getMinBlockZ(); } public int getMinBlockZ()
{
#if MC_VER <= MC_1_12_2
return this.chunk.getPos().getZStart();
#else
return this.chunk.getPos().getMinBlockZ();
#endif
}
//endregion
//==========// //==========//
// lighting // // lighting //
//==========// //==========//
//region
@Override @Override
public void setIsDhSkyLightCorrect(boolean isDhLightCorrect) { this.isDhSkyLightCorrect = isDhLightCorrect; } public void setIsDhSkyLightCorrect(boolean isDhLightCorrect) { this.isDhSkyLightCorrect = isDhLightCorrect; }
@@ -629,8 +729,32 @@ public class ChunkWrapper implements IChunkWrapper
{ {
this.blockLightPosList = new ArrayList<>(); this.blockLightPosList = new ArrayList<>();
//1.12.2 doesn't store lights we must bruteforce it
#if MC_VER < MC_1_20_1 #if MC_VER <= MC_1_12_2
for (ExtendedBlockStorage section : this.chunk.getBlockStorageArray()) {
if (section == null || section.isEmpty())
{
continue;
}
int baseY = section.getYLocation();
for (int x = 0; x < 16; x++)
{
for (int z = 0; z < 16; z++)
{
for (int y = 0; y < 16; y++)
{
IBlockState blockState = section.get(x, y, z);
if (blockState.getLightValue() > 0)
{
this.blockLightPosList.add(new DhBlockPos(this.chunk.getPos().getXStart() + x, baseY + y, this.chunk.getPos().getZStart() + z));
}
}
}
}
}
#elif MC_VER < MC_1_20_1
this.chunk.getLights().forEach((blockPos) -> this.chunk.getLights().forEach((blockPos) ->
{ {
this.blockLightPosList.add(new DhBlockPos(blockPos.getX(), blockPos.getY(), blockPos.getZ())); this.blockLightPosList.add(new DhBlockPos(blockPos.getX(), blockPos.getY(), blockPos.getZ()));
@@ -652,11 +776,14 @@ public class ChunkWrapper implements IChunkWrapper
return this.blockLightPosList; return this.blockLightPosList;
} }
//endregion
//================// //================//
// base overrides // // base overrides //
//================// //================//
//region
@Override @Override
public String toString() { return this.chunk.getClass().getSimpleName() + this.chunk.getPos(); } public String toString() { return this.chunk.getClass().getSimpleName() + this.chunk.getPos(); }
@@ -672,4 +799,8 @@ public class ChunkWrapper implements IChunkWrapper
// return this.blockBiomeHashCode; // return this.blockBiomeHashCode;
//} //}
//endregion
} }
@@ -1,12 +1,19 @@
package com.seibel.distanthorizons.common.wrappers.gui; package com.seibel.distanthorizons.common.wrappers.gui;
#if MC_VER <= MC_1_12_2
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.util.text.ITextComponent;
#else
import net.minecraft.client.gui.Font; import net.minecraft.client.gui.Font;
import net.minecraft.client.gui.components.Button; import net.minecraft.client.gui.components.Button;
import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.gui.screens.Screen;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
#endif
#if MC_VER < MC_1_20_1 #if MC_VER <= MC_1_12_2
#elif MC_VER < MC_1_20_1
import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.PoseStack;
#elif MC_VER <= MC_1_21_11 #elif MC_VER <= MC_1_21_11
import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.GuiGraphics;
@@ -16,26 +23,73 @@ import net.minecraft.client.gui.GuiGraphicsExtractor;
import java.util.List; import java.util.List;
#if MC_VER <= MC_1_12_2
public class DhScreen extends GuiScreen
#else
public class DhScreen extends Screen public class DhScreen extends Screen
#endif
{ {
#if MC_VER <= MC_1_12_2
protected ITextComponent title;
#endif
protected DhScreen(Component $$0) #if MC_VER <= MC_1_12_2
protected DhScreen(ITextComponent title)
{ {
super($$0); this.title = title;
} }
#else
protected DhScreen(Component title)
{
super(title);
}
#endif
// addRenderableWidget in 1.17 and over // addRenderableWidget in 1.17 and over
// addButton in 1.16 and below // addButton in 1.16 and below
#if MC_VER <= MC_1_12_2
protected GuiButton addBtn(GuiButton button)
#else
protected Button addBtn(Button button) protected Button addBtn(Button button)
#endif
{ {
#if MC_VER < MC_1_17_1 #if MC_VER <= MC_1_12_2
this.buttonList.add(button);
return button;
#elif MC_VER < MC_1_17_1
return this.addButton(button); return this.addButton(button);
#else #else
return this.addRenderableWidget(button); return this.addRenderableWidget(button);
#endif #endif
} }
#if MC_VER < MC_1_20_1 #if MC_VER <= MC_1_12_2
@Override
protected void actionPerformed(GuiButton button)
{
OnPressed handler = GuiHelper.HANDLER_BY_BUTTON.get(button);
if (handler != null)
{
handler.pressed(button);
}
}
protected void DhDrawCenteredString(ITextComponent text, int x, int y, int color) {
drawCenteredString(fontRenderer, text.getFormattedText(), x, y, color);
}
protected void DhDrawString(ITextComponent text, int x, int y, int color) {
drawString(fontRenderer, text.getFormattedText(), x, y, color);
}
protected void DhRenderComponentTooltip(List<ITextComponent> list, int x, int y) {
drawHoveringText(list.stream().map(ITextComponent::getFormattedText).toList(), x, y, fontRenderer);
}
protected void DhRenderTooltip(ITextComponent text, int x, int y) {
drawHoveringText(List.of(text.getFormattedText()), x, y, fontRenderer);
}
#elif MC_VER < MC_1_20_1
protected void DhDrawCenteredString(PoseStack guiStack, Font font, Component text, int x, int y, int color) protected void DhDrawCenteredString(PoseStack guiStack, Font font, Component text, int x, int y, int color)
{ {
drawCenteredString(guiStack, font, text, x, y, color); drawCenteredString(guiStack, font, text, x, y, color);
@@ -112,7 +166,4 @@ public class DhScreen extends Screen
guiStack.setTooltipForNextFrame(font, text, x, y); guiStack.setTooltipForNextFrame(font, text, x, y);
} }
#endif #endif
} }
@@ -1,7 +1,11 @@
package com.seibel.distanthorizons.common.wrappers.gui; package com.seibel.distanthorizons.common.wrappers.gui;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
#if MC_VER <= MC_1_12_2
import net.minecraft.client.gui.GuiScreen;
#else
import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.gui.screens.Screen;
#endif
import java.util.Objects; import java.util.Objects;
@@ -12,9 +16,15 @@ public class DhScreenUtil
//================// //================//
//region //region
public static void showScreen(Screen screen) #if MC_VER <= MC_1_12_2
public static void setScreen(GuiScreen screen)
#else
public static void setScreen(Screen screen)
#endif
{ {
#if MC_VER <= MC_26_1_2 #if MC_VER <= MC_1_12_2
Objects.requireNonNull(Minecraft.getMinecraft()).displayGuiScreen(screen);
#elif MC_VER <= MC_26_1_2
Objects.requireNonNull(Minecraft.getInstance()).setScreen(screen); Objects.requireNonNull(Minecraft.getInstance()).setScreen(screen);
#else #else
Objects.requireNonNull(Minecraft.getInstance()).setScreenAndShow(screen); Objects.requireNonNull(Minecraft.getInstance()).setScreenAndShow(screen);
@@ -4,14 +4,22 @@ import com.seibel.distanthorizons.common.wrappers.gui.classicConfig.ClassicConfi
import com.seibel.distanthorizons.core.config.ConfigHandler; import com.seibel.distanthorizons.core.config.ConfigHandler;
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import com.seibel.distanthorizons.coreapi.ModInfo; import com.seibel.distanthorizons.coreapi.ModInfo;
#if MC_VER <= MC_1_12_2
import net.minecraft.client.gui.GuiScreen;
#else
import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.gui.screens.Screen;
#endif
import com.seibel.distanthorizons.core.logging.DhLogger; import com.seibel.distanthorizons.core.logging.DhLogger;
public class GetConfigScreen public class GetConfigScreen
{ {
protected static final DhLogger LOGGER = new DhLoggerBuilder().build(); protected static final DhLogger LOGGER = new DhLoggerBuilder().build();
#if MC_VER <= MC_1_12_2
public static GuiScreen getScreen(GuiScreen parent)
#else
public static Screen getScreen(Screen parent) public static Screen getScreen(Screen parent)
#endif
{ {
if (ModInfo.IS_DEV_BUILD) if (ModInfo.IS_DEV_BUILD)
{ {
@@ -1,11 +1,21 @@
package com.seibel.distanthorizons.common.wrappers.gui; package com.seibel.distanthorizons.common.wrappers.gui;
#if MC_VER <= MC_1_12_2
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiTextField;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TextComponentString;
import net.minecraft.util.text.TextComponentTranslation;
import java.util.HashMap;
import java.util.Map;
#else
import net.minecraft.client.gui.components.AbstractWidget; import net.minecraft.client.gui.components.AbstractWidget;
import net.minecraft.client.gui.components.Button; import net.minecraft.client.gui.components.Button;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.MutableComponent; import net.minecraft.network.chat.MutableComponent;
#endif
#if MC_VER < MC_1_19_2 #if MC_VER < MC_1_19_2 && MC_VER > MC_1_12_2
import net.minecraft.network.chat.TextComponent; import net.minecraft.network.chat.TextComponent;
import net.minecraft.network.chat.TranslatableComponent; import net.minecraft.network.chat.TranslatableComponent;
#endif #endif
@@ -15,57 +25,99 @@ public class GuiHelper
/** /**
* Helper static methods for versional compat * Helper static methods for versional compat
*/ */
#if MC_VER <= MC_1_12_2
public static final Map<GuiButton, OnPressed> HANDLER_BY_BUTTON = new HashMap<>();
#endif
#if MC_VER <= MC_1_12_2
public static GuiButton MakeBtn(ITextComponent base, int posX, int posZ, int width, int height, OnPressed action)
#else
public static Button MakeBtn(Component base, int posX, int posZ, int width, int height, Button.OnPress action) public static Button MakeBtn(Component base, int posX, int posZ, int width, int height, Button.OnPress action)
#endif
{ {
#if MC_VER < MC_1_19_4 #if MC_VER <= MC_1_12_2
GuiButton button = new GuiButton(HANDLER_BY_BUTTON.size(), posX, posZ, width, height, base.getFormattedText());
HANDLER_BY_BUTTON.put(button, action);
return button;
#elif MC_VER < MC_1_19_4
return new Button(posX, posZ, width, height, base, action); return new Button(posX, posZ, width, height, base, action);
#else #else
return Button.builder(base, action).bounds(posX, posZ, width, height).build(); return Button.builder(base, action).bounds(posX, posZ, width, height).build();
#endif #endif
} }
#if MC_VER <= MC_1_12_2
public static ITextComponent TextOrLiteral(String text)
#else
public static MutableComponent TextOrLiteral(String text) public static MutableComponent TextOrLiteral(String text)
#endif
{ {
#if MC_VER < MC_1_19_2 #if MC_VER <= MC_1_12_2
return new TextComponentString(text);
#elif MC_VER < MC_1_19_2
return new TextComponent(text); return new TextComponent(text);
#else #else
return Component.literal(text); return Component.literal(text);
#endif #endif
} }
#if MC_VER <= MC_1_12_2
public static ITextComponent TextOrTranslatable(String text)
#else
public static MutableComponent TextOrTranslatable(String text) public static MutableComponent TextOrTranslatable(String text)
#endif
{ {
#if MC_VER < MC_1_19_2 #if MC_VER <= MC_1_12_2
return new TextComponentString(text);
#elif MC_VER < MC_1_19_2
return new TextComponent(text); return new TextComponent(text);
#else #else
return Component.translatable(text); return Component.translatable(text);
#endif #endif
} }
#if MC_VER <= MC_1_12_2
public static ITextComponent Translatable(String text, Object... args)
#else
public static MutableComponent Translatable(String text, Object... args) public static MutableComponent Translatable(String text, Object... args)
#endif
{ {
#if MC_VER < MC_1_19_2 #if MC_VER <= MC_1_12_2
return new TextComponentTranslation(text, args);
#elif MC_VER < MC_1_19_2
return new TranslatableComponent(text, args); return new TranslatableComponent(text, args);
#else #else
return Component.translatable(text, args); return Component.translatable(text, args);
#endif #endif
} }
public static void SetX(AbstractWidget w, int x) #if MC_VER <= MC_1_12_2
public static void SetX(GuiButton widget, int x)
#else
public static void SetX(AbstractWidget widget, int x)
#endif
{ {
#if MC_VER < MC_1_19_4 #if MC_VER < MC_1_19_4
w.x = x; widget.x = x;
#else #else
w.setX(x); widget.setX(x);
#endif #endif
} }
public static void SetY(AbstractWidget w, int y) #if MC_VER <= MC_1_12_2
public static void SetY(GuiTextField textField, int y) { textField.y = y; }
#endif
#if MC_VER <= MC_1_12_2
public static void SetY(GuiButton widget, int y)
#else
public static void SetY(AbstractWidget widget, int y)
#endif
{ {
#if MC_VER < MC_1_19_4 #if MC_VER < MC_1_19_4
w.y = y; widget.y = y;
#else #else
w.setY(y); widget.setY(y);
#endif #endif
} }
@@ -1,21 +1,40 @@
package com.seibel.distanthorizons.common.wrappers.gui; package com.seibel.distanthorizons.common.wrappers.gui;
import com.seibel.distanthorizons.core.wrapperInterfaces.config.ILangWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.config.ILangWrapper;
#if MC_VER <= MC_1_12_2
import net.minecraft.client.resources.I18n;
#else
import net.minecraft.client.resources.language.I18n; import net.minecraft.client.resources.language.I18n;
#endif
public class LangWrapper implements ILangWrapper public class LangWrapper implements ILangWrapper
{ {
public static final LangWrapper INSTANCE = new LangWrapper(); public static final LangWrapper INSTANCE = new LangWrapper();
@Override @Override
public boolean langExists(String str) public boolean langExists(String str)
{ {
#if MC_VER <= MC_1_12_2
return I18n.hasKey(str);
#elif MC_VER <= MC_26_1_2
return I18n.exists(str); return I18n.exists(str);
#else
String translated = getLang(str);
return translated != null
// if this isn't translatable it will generally return
// the same string as was passed in
&& !translated.equalsIgnoreCase(str);
#endif
} }
@Override @Override
public String getLang(String str) public String getLang(String str)
{ {
#if MC_VER <= MC_1_12_2
return I18n.format(str);
#else
return I18n.get(str); return I18n.get(str);
#endif
} }
} }

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