Compare commits

..

91 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 64d8f7ee2d update blaze 3d api use 2026-05-11 22:00:07 -05:00
James Seibel d8b3aee9dc temp disable forgix 2026-05-11 22:00:07 -05:00
James Seibel fce94fa4bf update screen mixin update 2026-05-11 22:00:07 -05:00
James Seibel 254d671629 basic mixin updates 2026-05-11 21:58:33 -05:00
James Seibel e66e7e627a disable mod compat code 2026-05-11 21:55:30 -05:00
130 changed files with 3075 additions and 1901 deletions
+23
View File
@@ -4,6 +4,7 @@ image: eclipse-temurin:25
# all stages need to be defined here
stages:
- translations
- build
- api
- pages
@@ -32,6 +33,9 @@ variables:
build:
stage: build
needs:
- job: translations
artifacts: true
parallel:
matrix:
- MC_VER: [
@@ -44,6 +48,11 @@ build:
"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:
# 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/;
@@ -102,3 +111,17 @@ pages:
- public
allow_failure: false
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">
<configuration default="false" name="Fabric Client &amp; Server" type="CompoundRunConfigurationType">
<toRun name="Fabric Client (:fabric)" type="Application" />
<toRun name="Fabric Server (:fabric)" type="Application" />
<toRun name="distant-horizons [fabric:runClient]" type="GradleRunConfiguration" />
<toRun name="distant-horizons [fabric:runServer]" type="GradleRunConfiguration" />
<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>
## 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>
## Source Code Installation
+9 -3
View File
@@ -131,7 +131,7 @@ if (isNotCommonProject) {
'MixinConfigs': "${mod_id}.default.mixin.json,${mod_id}.mod.mixin.json",
'FMLCorePlugin': 'com.seibel.distanthorizons.cleanroom.DistantHorizonsLoadingPlugin',
'FMLCorePluginContainsFMLMod': true,
'FMLAT': "src/main/resources/${gradle.ext.accessWidenerVersion}.distanthorizons_at.cfg"
'FMLAT': "${gradle.ext.accessWidenerVersion}.distanthorizons_at.cfg"
)
}
}
@@ -188,6 +188,7 @@ if (isNotCommonProject) {
if (gradle.ext.minecraft_version.equals("1.12.2")) {
cleanroom {
loader gradle.ext.cleanroom_loader_version
accessTransformer project.file("src/main/resources/${gradle.ext.accessWidenerVersion}.distanthorizons_at.cfg")
}
} else {
fabric {
@@ -483,7 +484,11 @@ if (isNotCommonProject) {
"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
def quilt_contributors = []
@@ -573,7 +578,8 @@ if (isNotCommonProject) {
new JsonSlurper()
.parse(input)
.each { key, value ->
writer.writeLine("${key}=${value.toString().replace("%", "%%").replace("\n", "\\n")}")
def text = value.toString().replaceAll(/%(?!((\d+)\$)?s|%)/, "%%").replace("\n", "\\n")
writer.writeLine("${key}=${text}")
}
}
}
@@ -126,7 +126,7 @@ public class CleanroomServerProxy implements AbstractModInitializer.IEventProxy
@SubscribeEvent
public void serverChunkSaveEvent(ChunkDataEvent.Save event)
{
if (event.getWorld() instanceof WorldServer worldServer)
if (event.getWorld() instanceof WorldServer worldServer && event.getChunk().dirty)
{
MixinChunkMapCommon.onChunkSave(worldServer, event.getChunk());
}
@@ -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);
}
}
}
@@ -21,16 +21,12 @@ 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.Mat4f;
import com.seibel.distanthorizons.core.util.math.DhMat4f;
import net.minecraft.client.multiplayer.WorldClient;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.RenderGlobal;
import net.minecraft.entity.Entity;
import net.minecraft.util.BlockRenderLayer;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL15;
import org.lwjgl.opengl.GL20;
import org.lwjgl.opengl.GL30;
import org.lwjgl.opengl.GL32;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
@@ -48,34 +44,25 @@ public class MixinRenderGlobal
if (blockLayerIn == BlockRenderLayer.SOLID)
{
float[] mcProjMatrixRaw = new float[16];
GL11.glGetFloatv(GL11.GL_PROJECTION_MATRIX, mcProjMatrixRaw);
ClientApi.RENDER_STATE.mcProjectionMatrix = new Mat4f(mcProjMatrixRaw);
GL32.glGetFloatv(GL32.GL_PROJECTION_MATRIX, mcProjMatrixRaw);
ClientApi.RENDER_STATE.mcProjectionMatrix = new DhMat4f(mcProjMatrixRaw);
ClientApi.RENDER_STATE.mcProjectionMatrix.transpose();
float[] mcModelViewRaw = new float[16];
GL11.glGetFloatv(GL11.GL_MODELVIEW_MATRIX, mcModelViewRaw);
ClientApi.RENDER_STATE.mcModelViewMatrix = new Mat4f(mcModelViewRaw);
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);
int blendSrc = GL11.glGetInteger(GL11.GL_BLEND_SRC);
int blendDst = GL11.glGetInteger(GL11.GL_BLEND_DST);
int boundTexture = GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D);
ClientApi.INSTANCE.renderLods();
GL30.glBindVertexArray(0);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);
GL20.glUseProgram(0);
//Restore vanilla states
GlStateManager.depthFunc(GL11.GL_LEQUAL);
GlStateManager.bindTexture(boundTexture);
GlStateManager.tryBlendFuncSeparate(blendSrc, blendDst, GL11.GL_ONE, GL11.GL_ZERO);
//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);
}
}
@@ -1,17 +1,20 @@
{
"required": true,
"package": "com.seibel.distanthorizons.cleanroom.mixins",
"compatibilityLevel": "JAVA_8",
"target": "@env(DEFAULT)",
"mixins": [],
"minVersion": "0.8.7",
"server": [
"server.MixinEntityPlayerMP"
],
"client": [
"client.MixinEntityRenderer",
"client.MixinNetHandlerPlayClient",
"client.MixinOptionsScreen",
"client.MixinRenderGlobal"
]
"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"
]
}
@@ -1,13 +1,14 @@
package com.seibel.distanthorizons.common;
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.DhApiBeforeDhInitEvent;
import com.seibel.distanthorizons.common.commands.CommandInitializer;
import com.seibel.distanthorizons.common.wrappers.DependencySetup;
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.core.Initializer;
import com.seibel.distanthorizons.core.api.internal.ClientApi;
@@ -264,6 +265,8 @@ public abstract class AbstractModInitializer
}
catch (Exception e)
{
NativeDialogUtil.showDialog(ModInfo.READABLE_NAME, e.getMessage(), "ok", "error");
MinecraftClientWrapper.INSTANCE.crashMinecraft(e.getMessage(), e);
future.completeExceptionally(e);
}
finally
@@ -387,17 +390,17 @@ public abstract class AbstractModInitializer
if (iris != null)
{
// get the currently selected rendering API
EDhApiRenderApi renderApi = Config.Client.Advanced.Graphics.Experimental.renderingApi.get();
if (renderApi == EDhApiRenderApi.AUTO)
EDhApiRenderingEngine renderApi = Config.Client.Advanced.Graphics.Experimental.renderingEngine.get();
if (renderApi == EDhApiRenderingEngine.AUTO)
{
IVersionConstants versionConstants = SingletonInjector.INSTANCE.get(IVersionConstants.class);
renderApi = versionConstants.getDefaultRenderingApi();
renderApi = versionConstants.getDefaultRenderingEngine();
}
// 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);
NativeDialogUtil.showDialog(ModInfo.READABLE_NAME, irisUnsupportedMessage, "ok", "error");
@@ -421,11 +424,11 @@ public abstract class AbstractModInitializer
{
#if MC_VER <= MC_1_12_2
Config.Client.Advanced.Graphics.Experimental.renderingApi.setMcVersionOverrideValue(EDhApiRenderApi.OPEN_GL);
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.renderingApi.setMcVersionOverrideValue(EDhApiRenderApi.OPEN_GL);
Config.Client.Advanced.Graphics.Experimental.renderingEngine.setMcVersionOverrideValue(EDhApiRenderingEngine.OPEN_GL);
#else
#endif
}
@@ -1,7 +1,7 @@
package com.seibel.distanthorizons.common.commonMixins;
#if MC_VER > MC_1_12_2
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.core.config.Config;
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
@@ -10,10 +10,11 @@ import com.seibel.distanthorizons.core.jar.installer.ModrinthGetter;
import com.seibel.distanthorizons.core.jar.updater.SelfUpdater;
import com.seibel.distanthorizons.core.logging.DhLogger;
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import com.seibel.distanthorizons.core.render.RenderThreadTaskHandler;
import com.seibel.distanthorizons.core.wrapperInterfaces.IVersionConstants;
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;
#endif
@@ -23,8 +24,11 @@ public class DhUpdateScreenBase
{
private static final DhLogger LOGGER = new DhLoggerBuilder().build();
private static final Minecraft MC = Minecraft #if MC_VER <= MC_1_12_2 .getMinecraft() #else .getInstance() #endif;
#if MC_VER <= MC_1_12_2
private static final Minecraft MC = Minecraft.getMinecraft();
#else
private static final Minecraft MC = Minecraft.getInstance();
#endif
public static void tryShowUpdateScreenAndRunAutoUpdateStartup(Runnable runnable)
{
@@ -34,12 +38,6 @@ public class DhUpdateScreenBase
{
return;
}
if (!Config.Client.Advanced.AutoUpdater.enableAutoUpdater.get())
{
LOGGER.info("Auto update disabled, ignoring new version...");
return;
}
runnable = () ->
@@ -71,22 +69,33 @@ 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", () ->
{
MC.setScreen(new UpdateModScreen(
new TitleScreen(false),
versionId
));
}
catch (Exception e)
{
// info instead of error since this can be ignored and probably just means
// there isn't a new DH version available
LOGGER.info("Unable to show DH update screen, reason: ["+e.getMessage()+"].");
}
try
{
#if MC_VER <= MC_1_12_2
DhScreenUtil.setScreen(new UpdateModScreen(
new GuiMainMenu(),
versionId
));
#else
DhScreenUtil.setScreen(new UpdateModScreen(
new TitleScreen(false),
versionId
));
#endif
}
catch (Exception e)
{
// 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();
}
}
#endif
@@ -1,10 +1,10 @@
package com.seibel.distanthorizons.common.commonMixins;
#if MC_VER > MC_1_12_2
import com.seibel.distanthorizons.common.wrappers.modAccessor.ImmersivePortalsAccessorCommon;
import com.seibel.distanthorizons.core.pos.DhChunkPos;
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.Vec3d;
import com.seibel.distanthorizons.core.util.math.DhVec3d;
import net.minecraft.client.Minecraft;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.ChunkPos;
@@ -12,40 +12,50 @@ 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();
ImmersivePortalsAccessorCommon.originalLevel = mc.level;
if (mc.player == null) {
ImmersivePortalsAccessorCommon.originalBlockPos = null;
ImmersivePortalsAccessorCommon.originalChunkPos = null;
ImmersivePortalsAccessorCommon.originalCameraPos = null;
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;
}
BlockPos pos = mc.player.blockPosition();
ImmersivePortalsAccessorCommon.originalBlockPos = new DhBlockPos(pos.getX(), pos.getY(), pos.getZ());
// 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 cPos = new ChunkPos(mc.player.blockPosition());
ChunkPos playerChunkPos = new ChunkPos(mc.player.blockPosition());
#else
ChunkPos cPos = mc.player.chunkPosition();
ChunkPos playerChunkPos = mc.player.chunkPosition();
#endif
AbstractImmersivePortalsAccessorCommon.actualChunkPos = McObjectConverter.Convert(playerChunkPos);
#if MC_VER <= MC_1_21_11
ImmersivePortalsAccessorCommon.originalChunkPos = new DhChunkPos(cPos.x, cPos.z);
#else
ImmersivePortalsAccessorCommon.originalChunkPos = new DhChunkPos(cPos.x(), cPos.z());
#endif
// camera pos
#if MC_VER <= MC_1_21_10
Vec3 cameraPos = mc.gameRenderer.getMainCamera().getPosition();
#else
#elif MC_VER <= MC_26_1_2
Vec3 cameraPos = mc.gameRenderer.getMainCamera().position();
#else
Vec3 cameraPos = mc.gameRenderer.mainCamera().position();
#endif
ImmersivePortalsAccessorCommon.originalCameraPos = new Vec3d(cameraPos.x(), cameraPos.y(), cameraPos.z());
AbstractImmersivePortalsAccessorCommon.actualCameraPos = new DhVec3d(cameraPos.x(), cameraPos.y(), cameraPos.z());
}
}
@@ -21,7 +21,11 @@ import net.minecraft.world.entity.LivingEntity;
#if MC_VER <= MC_1_12_2
import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.entity.Entity;
import net.minecraft.init.MobEffects;
import net.minecraft.util.math.BlockPos;
import net.minecraftforge.fluids.IFluidBlock;
import net.minecraft.block.state.IBlockState;
#elif MC_VER < MC_1_17_1
import net.minecraft.world.level.material.FluidState;
import net.minecraft.client.renderer.FogRenderer;
@@ -79,9 +83,12 @@ public class MixinVanillaFogCommon
#elif MC_VER <= MC_1_21_10
Camera camera = Minecraft.getInstance().gameRenderer.getMainCamera();
Entity entity = camera.getEntity();
#else
#elif MC_VER <= MC_26_1_2
Camera camera = Minecraft.getInstance().gameRenderer.getMainCamera();
Entity entity = camera.entity();
#else
Camera camera = Minecraft.getInstance().gameRenderer.mainCamera();
Entity entity = camera.entity();
#endif
#if MC_VER <= MC_1_12_2
@@ -108,7 +115,8 @@ public class MixinVanillaFogCommon
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())
@@ -125,7 +133,11 @@ public class MixinVanillaFogCommon
#endif
{
#if MC_VER <= MC_1_12_2
boolean cameraNotInFluid = mc.getRenderViewEntity() != null && !mc.world.getBlockState(mc.getRenderViewEntity().getPosition()).getMaterial().isLiquid();
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();
boolean cameraNotInFluid = fluidState.isEmpty();
@@ -26,34 +26,29 @@ public class BlazeDebugWireframeRenderer {}
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.platform.PolygonMode;
import com.mojang.blaze3d.shaders.UniformType;
import com.mojang.blaze3d.systems.CommandEncoder;
import com.mojang.blaze3d.systems.GpuDevice;
import com.mojang.blaze3d.systems.RenderPass;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.VertexFormat;
import com.seibel.distanthorizons.common.render.blaze.util.BlazeUniformUtil;
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.uniform.BlazeUniformBufferWrapper;
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
import com.seibel.distanthorizons.core.logging.DhLogger;
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import com.seibel.distanthorizons.core.render.EDhRenderDepth;
import com.seibel.distanthorizons.core.render.renderer.AbstractDebugWireframeRenderer;
import com.seibel.distanthorizons.core.util.math.Mat4f;
import com.seibel.distanthorizons.core.util.math.Vec3d;
import com.seibel.distanthorizons.core.util.math.Vec3f;
import com.seibel.distanthorizons.core.util.math.DhMat4f;
import com.seibel.distanthorizons.core.util.math.DhVec3d;
import com.seibel.distanthorizons.core.util.math.DhVec3f;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
import net.minecraft.resources.Identifier;
import org.lwjgl.system.MemoryUtil;
import com.seibel.distanthorizons.core.wrapperInterfaces.render.AbstractDhRenderApiDefinition;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.OptionalDouble;
import java.util.OptionalInt;
/**
* 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 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();
/** A box from 0,0,0 to 1,1,1 */
private static final float[] BOX_VERTICES = {
//region
@@ -103,6 +97,7 @@ public class BlazeDebugWireframeRenderer extends AbstractDebugWireframeRenderer
//endregion
};
private static final DhMat4f TRANSFORM_MATRIX = new DhMat4f();
@@ -114,7 +109,7 @@ public class BlazeDebugWireframeRenderer extends AbstractDebugWireframeRenderer
private GpuBuffer boxVertexBuffer;
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.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.withoutBlend();
pipelineBuilder.withPolygonMode(RenderPipelineBuilderWrapper.EDhPolygonMode.WIREFRAME);
@@ -155,7 +157,7 @@ public class BlazeDebugWireframeRenderer extends AbstractDebugWireframeRenderer
pipelineBuilder.withUniformBuffer("uniformBlock");
VertexFormat vertexFormat = VertexFormat.builder()
VertexFormat vertexFormat = new BlazeVertexFormatBuilder()
.add("vPosition", BlazeDhVertexFormatUtil.FLOAT_XYZ_POS)
.build();
pipelineBuilder.withVertexFormat(vertexFormat);
@@ -171,17 +173,17 @@ public class BlazeDebugWireframeRenderer extends AbstractDebugWireframeRenderer
// 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.rewind();
MemoryUtil.memFree(boxVerticesBuffer);
// upload vertex data
{
int usage = GpuBuffer.USAGE_COPY_DST
| GpuBuffer.USAGE_VERTEX;
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;
@@ -251,77 +253,56 @@ public class BlazeDebugWireframeRenderer extends AbstractDebugWireframeRenderer
// uniforms
{
int uniformBufferSize = new Std140SizeCalculator()
.putMat4f() // uTransform
.putVec4() // uColor
.get();
// 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();
Vec3f camPosFloatThisFrame = new Vec3f((float) camPos.x, (float) camPos.y, (float) camPos.z);
Mat4f boxTransform = Mat4f.createTranslateMatrix(
DhMat4f boxTransform = DhMat4f.createTranslateMatrix(
box.minPos.x - camPosFloatThisFrame.x,
box.minPos.y - camPosFloatThisFrame.y,
box.minPos.z - camPosFloatThisFrame.z);
boxTransform.multiply(Mat4f.createScaleMatrix(
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();
transformMatrix.multiply(boxTransform);
TRANSFORM_MATRIX.set(this.dhMvmProjMatrixThisFrame);
TRANSFORM_MATRIX.multiply(boxTransform);
// upload data //
ByteBuffer buffer = ByteBuffer.allocateDirect(uniformBufferSize);
buffer.order(ByteOrder.nativeOrder());
buffer = Std140Builder.intoBuffer(buffer)
.putMat4f(transformMatrix.createJomlMatrix()) // uTransform
.putVec4(
this.uniformBufferWrapper
.putMat4f(TRANSFORM_MATRIX) // uTransform
.putVec4f(
box.color.getRed() / 255.0f,
box.color.getGreen() / 255.0f,
box.color.getBlue() / 255.0f,
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 //
try (RenderPass renderPass = commandEncoder.createRenderPass(
try (RenderPassWrapper renderPassWrapper = new RenderPassWrapper(
this::getRenderPassName,
BlazeDhMetaRenderer.INSTANCE.dhColorTextureWrapper.textureView,
/*optionalClearColorAsInt*/ OptionalInt.empty(),
BlazeDhMetaRenderer.INSTANCE.dhDepthTextureWrapper.textureView,
/*optionalDepthValueAsDouble*/ OptionalDouble.empty()))
BlazeDhMetaRenderer.INSTANCE.dhColorTextureWrapper,
BlazeDhMetaRenderer.INSTANCE.dhDepthTextureWrapper))
{
// Bind instance data //
renderPass.setUniform("uniformBlock", this.uniformBuffer);
renderPass.setPipeline(this.pipeline);
renderPass.setIndexBuffer(this.boxIndexBuffer, VertexFormat.IndexType.INT);
renderPass.setVertexBuffer(0, this.boxVertexBuffer);
renderPass.drawIndexed(
/*indexStart*/ 0,
/*firstIndex*/0,
/*indexCount*/BOX_OUTLINE_INDICES.length,
/*instanceCount*/1);
renderPassWrapper.setUniform("uniformBlock", this.uniformBufferWrapper);
renderPassWrapper.setPipeline(this.pipeline);
renderPassWrapper.setIndexBuffer(this.boxIndexBuffer);
renderPassWrapper.setVertexBuffer(this.boxVertexBuffer);
renderPassWrapper.drawIndexed(BOX_OUTLINE_INDICES.length);
}
}
private String getRenderPassName() { return "distantHorizons:McDebugRenderer"; }
private String getRenderPassName() { return "distantHorizons:DebugRenderer"; }
//endregion
@@ -24,17 +24,10 @@ public class BlazeDhGenericObjectRenderer {}
#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.RenderPipeline;
import com.mojang.blaze3d.platform.PolygonMode;
import com.mojang.blaze3d.shaders.UniformType;
import com.mojang.blaze3d.systems.CommandEncoder;
import com.mojang.blaze3d.systems.GpuDevice;
import com.mojang.blaze3d.systems.RenderPass;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.VertexFormat;
import com.seibel.distanthorizons.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.DhApiBeforeGenericRenderCleanupEvent;
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.render.DhApiRenderableBox;
import com.seibel.distanthorizons.api.objects.render.DhApiRenderableBoxGroupShading;
import com.seibel.distanthorizons.common.render.blaze.objects.BlazeGenericObjectVertexContainer;
import com.seibel.distanthorizons.common.render.blaze.util.BlazeDhVertexFormatUtil;
import com.seibel.distanthorizons.common.render.blaze.wrappers.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.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.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.render.EDhRenderDepth;
import com.seibel.distanthorizons.core.render.RenderParams;
import com.seibel.distanthorizons.core.render.RenderThreadTaskHandler;
import com.seibel.distanthorizons.core.render.renderer.GenericRenderObjectFactory;
import com.seibel.distanthorizons.core.wrapperInterfaces.render.AbstractDhRenderApiDefinition;
import com.seibel.distanthorizons.core.wrapperInterfaces.render.objects.IDhGenericObjectVertexBufferContainer;
import com.seibel.distanthorizons.core.render.renderer.RenderableBoxGroup;
import com.seibel.distanthorizons.core.util.LodUtil;
import com.seibel.distanthorizons.core.util.math.Mat4f;
import com.seibel.distanthorizons.core.util.math.Vec3d;
import com.seibel.distanthorizons.core.util.math.DhMat4f;
import com.seibel.distanthorizons.core.util.math.DhVec3d;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IProfilerWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass.IDhGenericRenderer;
import com.seibel.distanthorizons.coreapi.DependencyInjection.ApiEventInjector;
import com.seibel.distanthorizons.coreapi.ModInfo;
import net.minecraft.resources.Identifier;
import java.awt.*;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.Collection;
import java.util.OptionalDouble;
import java.util.OptionalInt;
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 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 CommandEncoder COMMAND_ENCODER = GPU_DEVICE.createCommandEncoder();
@@ -103,6 +97,10 @@ public class BlazeDhGenericObjectRenderer implements IDhGenericRenderer
*/
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<>();
@@ -111,7 +109,7 @@ public class BlazeDhGenericObjectRenderer implements IDhGenericRenderer
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.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.withColorWrite(true);
pipelineBuilder.withPolygonMode(RenderPipelineBuilderWrapper.EDhPolygonMode.FILL);
@@ -156,7 +161,7 @@ public class BlazeDhGenericObjectRenderer implements IDhGenericRenderer
pipelineBuilder.withUniformBuffer("vertUniformBlock");
VertexFormat vertexFormat = VertexFormat.builder()
VertexFormat vertexFormat = new BlazeVertexFormatBuilder()
.add("vPosition", BlazeDhVertexFormatUtil.FLOAT_XYZ_POS)
.add("aColor", BlazeDhVertexFormatUtil.RGBA_UBYTE_COLOR)
.add("aMaterial", BlazeDhVertexFormatUtil.IRIS_MATERIAL)
@@ -343,9 +348,9 @@ public class BlazeDhGenericObjectRenderer implements IDhGenericRenderer
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
@@ -389,7 +394,8 @@ public class BlazeDhGenericObjectRenderer implements IDhGenericRenderer
}
// 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)
{
continue;
@@ -415,61 +421,37 @@ public class BlazeDhGenericObjectRenderer implements IDhGenericRenderer
// 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 //
Mat4f projectionMvmMatrix = new Mat4f(renderEventParam.dhProjectionMatrix);
DhMat4f projectionMvmMatrix = new DhMat4f(renderEventParam.dhProjectionMatrix);
projectionMvmMatrix.multiply(renderEventParam.dhModelViewMatrix);
// upload data //
ByteBuffer buffer = ByteBuffer.allocateDirect(uniformBufferSize);
buffer.order(ByteOrder.nativeOrder());
buffer = Std140Builder.intoBuffer(buffer)
.putIVec3(
this.vertUniformBufferWrapper
.putVec3i(
LodUtil.getChunkPosFromDouble(boxGroup.getOriginBlockPos().x),
LodUtil.getChunkPosFromDouble(boxGroup.getOriginBlockPos().y),
LodUtil.getChunkPosFromDouble(boxGroup.getOriginBlockPos().z)
) // uOffsetChunk
.putVec3(
.putVec3f(
LodUtil.getSubChunkPosFromDouble(boxGroup.getOriginBlockPos().x),
LodUtil.getSubChunkPosFromDouble(boxGroup.getOriginBlockPos().y),
LodUtil.getSubChunkPosFromDouble(boxGroup.getOriginBlockPos().z)
) // uOffsetSubChunk
.putIVec3(
.putVec3i(
LodUtil.getChunkPosFromDouble(camPos.x),
LodUtil.getChunkPosFromDouble(camPos.y),
LodUtil.getChunkPosFromDouble(camPos.z)
) // uCameraPosChunk
.putVec3(
.putVec3f(
LodUtil.getSubChunkPosFromDouble(camPos.x),
LodUtil.getSubChunkPosFromDouble(camPos.y),
LodUtil.getSubChunkPosFromDouble(camPos.z)
) // uCameraPosSubChunk
.putMat4f(projectionMvmMatrix.createJomlMatrix()) // uProjectionMvm
.putMat4f(projectionMvmMatrix) // uProjectionMvm
.putInt(boxGroup.getSkyLight()) // uSkyLight
.putInt(boxGroup.getBlockLight()) // uBlockLight
@@ -480,13 +462,8 @@ public class BlazeDhGenericObjectRenderer implements IDhGenericRenderer
.putFloat(shading.top)
.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
}
}
private String getRenderPassName() { return "distantHorizons:McGenericObjectRenderer"; }
private String getRenderPassName() { return "distantHorizons:GenericObjectRenderer"; }
//endregion
@@ -536,12 +513,10 @@ public class BlazeDhGenericObjectRenderer implements IDhGenericRenderer
RenderableBoxGroup boxGroup,
IProfilerWrapper profiler)
{
try (RenderPass renderPass = COMMAND_ENCODER.createRenderPass(
try (RenderPassWrapper renderPassWrapper = new RenderPassWrapper(
this::getRenderPassName,
BlazeDhMetaRenderer.INSTANCE.dhColorTextureWrapper.textureView,
/*optionalClearColorAsInt*/ OptionalInt.empty(),
BlazeDhMetaRenderer.INSTANCE.dhDepthTextureWrapper.textureView,
/*optionalDepthValueAsDouble*/ OptionalDouble.empty()))
BlazeDhMetaRenderer.INSTANCE.dhColorTextureWrapper,
BlazeDhMetaRenderer.INSTANCE.dhDepthTextureWrapper))
{
// update instance data //
@@ -550,30 +525,26 @@ public class BlazeDhGenericObjectRenderer implements IDhGenericRenderer
LightMapWrapper lightMapWrapper = (LightMapWrapper) renderEventParam.lightmap;
BlazeTextureViewWrapper lightmapTextureViewWrapper = lightMapWrapper.getTextureViewWrapper();
renderPass.bindTexture("uLightMap", lightmapTextureViewWrapper.textureView, lightmapTextureViewWrapper.textureSampler);
renderPassWrapper.bindTexture("uLightMap", lightmapTextureViewWrapper);
// Bind instance data //
renderPass.setUniform("vertUniformBlock", this.vertUniformBuffer);
renderPassWrapper.setUniform("vertUniformBlock", this.vertUniformBufferWrapper);
// set pipeline
renderPass.setPipeline(this.pipeline);
renderPass.setIndexBuffer(container.indexGpuBuffer, VertexFormat.IndexType.INT);
renderPassWrapper.setPipeline(this.pipeline);
renderPassWrapper.setIndexBuffer(container.indexGpuBuffer);
renderPass.setVertexBuffer(0, container.vboGpuBuffer);
renderPassWrapper.setVertexBuffer(container.vboGpuBuffer);
// Draw instanced
if (container.uploadedBoxCount > 0)
{
renderPass.drawIndexed(
/*indexStart*/ 0,
/*firstIndex*/0,
/*indexCount*/container.uploadedBoxCount * 36, // 36 = 6 faces * 6 verticies per face
/*instanceCount*/1);
// 36 = 6 faces * 6 verticies per face
renderPassWrapper.drawIndexed(container.uploadedBoxCount * 36);
}
}
}
@@ -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
RenderThreadTaskHandler.INSTANCE.queueRunningOnRenderThread("Generic Obj Cleanup", () ->
{
if (this.vertUniformBuffer != null)
if (this.vertUniformBufferWrapper != null)
{
this.vertUniformBuffer.close();
this.vertUniformBufferWrapper.close();
}
});
}
@@ -10,8 +10,10 @@ import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiAfterCo
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiTextureCreatedParam;
import com.seibel.distanthorizons.common.render.blaze.apply.BlazeDhApplyRenderer;
import com.seibel.distanthorizons.common.render.blaze.wrappers.texture.BlazeTextureWrapper;
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftRenderWrapper;
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
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.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass.IDhMetaRenderer;
@@ -28,6 +30,7 @@ public class BlazeDhMetaRenderer implements IDhMetaRenderer
private BlazeDhApplyRenderer applyRenderer;
private final float clearDepth;
public final BlazeTextureWrapper dhDepthTextureWrapper = BlazeTextureWrapper.createDepth("DhDepthTexture");
public final BlazeTextureWrapper dhColorTextureWrapper = BlazeTextureWrapper.createColor("DhColorTexture");
@@ -41,6 +44,9 @@ public class BlazeDhMetaRenderer implements IDhMetaRenderer
private BlazeDhMetaRenderer()
{
AbstractDhRenderApiDefinition renderApiDefinition = SingletonInjector.INSTANCE.get(AbstractDhRenderApiDefinition.class);
this.clearDepth = renderApiDefinition.getRenderDepth().farDepth;
this.applyRenderer = new BlazeDhApplyRenderer(
"dh_apply_to_mc",
null,
@@ -86,7 +92,7 @@ public class BlazeDhMetaRenderer implements IDhMetaRenderer
@Override
public void applyToMcTexture(RenderParams renderParams)
{
GpuTexture mcColorTexture = Minecraft.getInstance().getMainRenderTarget().getColorTexture();
GpuTexture mcColorTexture = MinecraftRenderWrapper.INSTANCE.getRenderTarget().getColorTexture();
this.applyRenderer.render(this.dhColorTextureWrapper.texture, this.dhDepthTextureWrapper.texture, mcColorTexture);
}
@@ -102,7 +108,7 @@ public class BlazeDhMetaRenderer implements IDhMetaRenderer
@Override
public void clearDhDepthAndColorTextures(RenderParams renderParams)
{
this.dhDepthTextureWrapper.clearDepth(1.0f);
this.dhDepthTextureWrapper.clearDepth(this.clearDepth);
Color color = MC_RENDER.getSkyColor();
this.dhColorTextureWrapper.clearColor(ColorUtil.toColorInt(color));
@@ -111,5 +117,6 @@ public class BlazeDhMetaRenderer implements IDhMetaRenderer
//endregion
}
#endif
@@ -5,6 +5,7 @@ public class BlazeDhRenderApiDefinition {}
#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.postProcessing.BlazeDhFarFadeRenderer;
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.wrappers.buffer.BlazeVertexBufferWrapper;
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.wrapperInterfaces.render.AbstractDhRenderApiDefinition;
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.renderPass.*;
#if MC_VER <= MC_26_1_2
#else
#endif
public class BlazeDhRenderApiDefinition extends AbstractDhRenderApiDefinition
{
//=========//
@@ -27,7 +34,43 @@ public class BlazeDhRenderApiDefinition extends AbstractDhRenderApiDefinition
//=========//
//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
@@ -5,68 +5,66 @@ public class BlazeDhTerrainRenderer {}
#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.RenderPipeline;
import com.mojang.blaze3d.platform.PolygonMode;
import com.mojang.blaze3d.shaders.UniformType;
import com.mojang.blaze3d.systems.CommandEncoder;
import com.mojang.blaze3d.systems.GpuDevice;
import com.mojang.blaze3d.systems.RenderPass;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.VertexFormat;
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiBeforeBufferRenderEvent;
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.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.texture.BlazeTextureViewWrapper;
import com.seibel.distanthorizons.common.render.blaze.wrappers.uniform.BlazeLodUniformBufferWrapper;
import com.seibel.distanthorizons.common.render.blaze.wrappers.buffer.BlazeVertexBufferWrapper;
import com.seibel.distanthorizons.common.render.blaze.wrappers.uniform.BlazeUniformBufferWrapper;
import com.seibel.distanthorizons.common.wrappers.misc.LightMapWrapper;
import com.seibel.distanthorizons.core.config.Config;
import com.seibel.distanthorizons.core.dataObjects.render.bufferBuilding.LodBufferContainer;
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
import com.seibel.distanthorizons.core.logging.DhLogger;
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import com.seibel.distanthorizons.core.pos.DhSectionPos;
import com.seibel.distanthorizons.core.render.EDhRenderDepth;
import com.seibel.distanthorizons.core.render.RenderParams;
import com.seibel.distanthorizons.core.util.RenderUtil;
import com.seibel.distanthorizons.core.util.math.Mat4f;
import com.seibel.distanthorizons.core.util.math.Vec3d;
import com.seibel.distanthorizons.core.util.math.Vec3f;
import com.seibel.distanthorizons.core.util.math.DhMat4f;
import com.seibel.distanthorizons.core.util.math.DhVec3d;
import com.seibel.distanthorizons.core.util.math.DhVec3f;
import com.seibel.distanthorizons.core.util.objects.SortedArraySet;
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.objects.IVertexBufferWrapper;
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. */
public class BlazeDhTerrainRenderer implements IDhTerrainRenderer
{
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 CommandEncoder COMMAND_ENCODER = GPU_DEVICE.createCommandEncoder();
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 transparentPipeline;
private boolean init = false;
private GpuBuffer fragUniformBuffer;
private GpuBuffer vertSharedUniformBuffer;
private final BlazeUniformBufferWrapper fragUniformBufferWrapper = new BlazeUniformBufferWrapper("fragUniformBlock");
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.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.withPolygonMode(RenderPipelineBuilderWrapper.EDhPolygonMode.FILL);
pipelineBuilder.withName("terrain");
pipelineBuilder.withSampler("uLightMap");
@@ -104,7 +116,7 @@ public class BlazeDhTerrainRenderer implements IDhTerrainRenderer
pipelineBuilder.withUniformBuffer("vertSharedUniformBlock");
pipelineBuilder.withUniformBuffer("fragUniformBlock");
VertexFormat vertexFormat = VertexFormat.builder()
VertexFormat vertexFormat = new BlazeVertexFormatBuilder()
.add("vPosition", BlazeDhVertexFormatUtil.SHORT_XYZ_POS)
.add("meta", BlazeDhVertexFormatUtil.META)
.add("vColor", BlazeDhVertexFormatUtil.RGBA_UBYTE_COLOR)
@@ -120,15 +132,17 @@ public class BlazeDhTerrainRenderer implements IDhTerrainRenderer
// opaque
{
pipelineBuilder.withoutBlend();
this.opaquePipeline = pipelineBuilder.build();
opaquePipelineBuilder.withName("opaque_terrain");
opaquePipelineBuilder.withoutBlend();
this.opaquePipeline = opaquePipelineBuilder.build();
}
// transparent
{
translucentPipelineBuilder.withName("transparent_terrain");
// TRANSLUCENT = new BlendFunction(SourceFactor.SRC_ALPHA, DestFactor.ONE_MINUS_SRC_ALPHA, SourceFactor.ONE, DestFactor.ONE_MINUS_SRC_ALPHA);
pipelineBuilder.withBlend(BlendFunction.TRANSLUCENT);
this.transparentPipeline = pipelineBuilder.build();
translucentPipelineBuilder.withBlend(BlendFunction.TRANSLUCENT);
this.transparentPipeline = translucentPipelineBuilder.build();
}
this.init = true;
@@ -161,13 +175,13 @@ public class BlazeDhTerrainRenderer implements IDhTerrainRenderer
for (int lodIndex = 0; lodIndex < bufferContainers.size(); lodIndex++)
{
LodBufferContainer bufferContainer = bufferContainers.get(lodIndex);
bufferContainer.uniformContainer.tryUpload();
bufferContainer.uniformContainer.tryUpload(bufferContainer);
}
}
profiler.popPush("vert share uniforms");
{
Mat4f combinedMatrix = new Mat4f(renderEventParam.dhProjectionMatrix);
DhMat4f combinedMatrix = new DhMat4f(renderEventParam.dhProjectionMatrix);
combinedMatrix.multiply(renderEventParam.dhModelViewMatrix);
float earthCurveRatio = Config.Client.Advanced.Graphics.Experimental.earthCurveRatio.get();
@@ -184,53 +198,25 @@ public class BlazeDhTerrainRenderer implements IDhTerrainRenderer
// upload data //
int uniformBufferSize = new Std140SizeCalculator()
.putInt() // uIsWhiteWorld
.putFloat() // uWorldYOffset
.putFloat() // uMircoOffset
.putFloat() // uEarthRadius
.putVec3() // uCameraPos
.putMat4f() // uCombinedMatrix
.get();
int i = Config.Client.Advanced.Debugging.enableWhiteWorld.get() ? 1 : 0;
ByteBuffer buffer = MemoryUtil.memAlloc(uniformBufferSize);
buffer.order(ByteOrder.nativeOrder());
Std140Builder.intoBuffer(buffer)
.putInt(0) // uIsWhiteWorld
this.vertSharedUniformBufferWrapper
.putInt(i) // uIsWhiteWorld
.putFloat((float) renderEventParam.worldYOffset) // uWorldYOffset
.putFloat(0.01f) // uMircoOffset // 0.01 block offset
.putFloat(earthCurveRatio) // uEarthRadius
.putVec3(
.putVec3f(
(float) renderEventParam.exactCameraPosition.x,
(float) renderEventParam.exactCameraPosition.y,
(float) renderEventParam.exactCameraPosition.z) // uCameraPos
.putMat4f(combinedMatrix.createJomlMatrix()) // uCombinedMatrix
.get();
this.vertSharedUniformBuffer = BlazeUniformUtil.createBuffer("vertSharedUniformBlock", uniformBufferSize, this.vertSharedUniformBuffer);
GpuBufferSlice bufferSlice = new GpuBufferSlice(this.vertSharedUniformBuffer, 0, uniformBufferSize);
COMMAND_ENCODER.writeToBuffer(bufferSlice, buffer);
MemoryUtil.memFree(buffer);
.putMat4f(combinedMatrix) // uCombinedMatrix
.finishAndUpload();
}
profiler.popPush("set frag uniforms");
{
int uniformBufferSize = new Std140SizeCalculator()
.putFloat() // uClipDistance
.putFloat() // uNoiseIntensity
.putInt() // uNoiseSteps
.putInt() // uNoiseDropoff
.putInt() // uDitherDhRendering
.putInt() // uNoiseEnabled
.get();
// create data //
float dhNearClipDistance = RenderUtil.getNearClipPlaneInBlocks();
@@ -242,24 +228,15 @@ public class BlazeDhTerrainRenderer implements IDhTerrainRenderer
// upload data //
ByteBuffer buffer = MemoryUtil.memAlloc(uniformBufferSize);
buffer.order(ByteOrder.nativeOrder());
buffer = Std140Builder.intoBuffer(buffer)
this.fragUniformBufferWrapper
.putFloat(dhNearClipDistance) // uClipDistance
.putFloat(Config.Client.Advanced.Graphics.NoiseTexture.noiseIntensity.get()) // uNoiseIntensity
.putInt(Config.Client.Advanced.Graphics.NoiseTexture.noiseSteps.get()) // uNoiseSteps
.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.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");
ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeRenderPassEvent.class, renderEventParam);
ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeRenderPassEvent.class, renderEventParam.apiCopy);
// create a render pass
try (RenderPass renderPass = COMMAND_ENCODER.createRenderPass(
try (RenderPassWrapper renderPassWrapper = new RenderPassWrapper(
this::getRenderPassName,
BlazeDhMetaRenderer.INSTANCE.dhColorTextureWrapper.textureView,
/*optionalClearColorAsInt*/ OptionalInt.empty(),
BlazeDhMetaRenderer.INSTANCE.dhDepthTextureWrapper.textureView,
/*optionalDepthValueAsDouble*/ OptionalDouble.empty())
BlazeDhMetaRenderer.INSTANCE.dhColorTextureWrapper,
BlazeDhMetaRenderer.INSTANCE.dhDepthTextureWrapper)
)
{
LightMapWrapper lightMapWrapper = (LightMapWrapper) renderEventParam.lightmap;
BlazeTextureViewWrapper lightmapTextureViewWrapper = lightMapWrapper.getTextureViewWrapper();
renderPass.bindTexture("uLightMap", lightmapTextureViewWrapper.textureView, lightmapTextureViewWrapper.textureSampler);
renderPassWrapper.bindTexture("uLightMap", lightmapTextureViewWrapper);
// set pipeline
renderPass.setPipeline(opaquePass ? this.opaquePipeline : this.transparentPipeline);
renderPassWrapper.setPipeline(opaquePass ? this.opaquePipeline : this.transparentPipeline);
// shared uniforms
renderPass.setUniform("fragUniformBlock", this.fragUniformBuffer);
renderPass.setUniform("vertSharedUniformBlock", this.vertSharedUniformBuffer);
renderPassWrapper.setUniform("fragUniformBlock", this.fragUniformBufferWrapper);
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
{
Vec3d camPos = renderEventParam.exactCameraPosition;
Vec3f modelPos = new Vec3f(
DhVec3d camPos = renderEventParam.exactCameraPosition;
MODEL_POS.set(
(float) (bufferContainer.minCornerBlockPos.getX() - camPos.x),
(float) (bufferContainer.minCornerBlockPos.getY() - camPos.y),
(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);
renderPass.setVertexBuffer(0, bufferWrapper.vertexGpuBuffer); // vertex buffer can only be "0" lol
renderPassWrapper.setIndexBuffer(bufferWrapper.getIndexGpuBuffer());
renderPassWrapper.setVertexBuffer(bufferWrapper.vertexGpuBuffer);
if (!bufferWrapper.vertexGpuBuffer.isClosed())
{
renderPass.drawIndexed(
/*indexStart*/ 0,
/*firstIndex*/0,
/*indexCount*/bufferWrapper.indexCount,
/*instanceCount*/1);
renderPassWrapper.drawIndexed(bufferWrapper.indexCount);
}
}
}
@@ -356,7 +328,7 @@ public class BlazeDhTerrainRenderer implements IDhTerrainRenderer
}
}
private String getIndexBufferName() { return "distantHorizons:LodIndexBuffer"; }
private String getRenderPassName() { return "distantHorizons:McLodRenderer"; }
private String getRenderPassName() { return "distantHorizons:TerrainRenderer"; }
//endregion
@@ -29,23 +29,26 @@ import com.mojang.blaze3d.pipeline.BlendFunction;
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.textures.*;
import com.mojang.blaze3d.vertex.VertexFormat;
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.texture.BlazeTextureViewWrapper;
import com.seibel.distanthorizons.common.render.blaze.util.BlazePostProcessUtil;
import com.seibel.distanthorizons.common.render.blaze.wrappers.texture.BlazeTextureWrapper;
import com.seibel.distanthorizons.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.DhLoggerBuilder;
import com.seibel.distanthorizons.core.render.EDhRenderDepth;
import com.seibel.distanthorizons.core.wrapperInterfaces.render.AbstractDhRenderApiDefinition;
import com.seibel.distanthorizons.coreapi.ModInfo;
import org.jetbrains.annotations.Nullable;
import java.util.Arrays;
import java.util.OptionalDouble;
import java.util.OptionalInt;
/**
* Copies the given color texture
@@ -57,13 +60,17 @@ import java.util.OptionalInt;
*/
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 CommandEncoder COMMAND_ENCODER = GPU_DEVICE.createCommandEncoder();
private RenderPipeline pipeline;
private final BlazeUniformBufferWrapper fragUniformBufferWrapper = new BlazeUniformBufferWrapper("baseFragUniformBlock");
protected GpuBuffer vboGpuBuffer;
protected final String name;
@@ -92,7 +99,7 @@ public class BlazeDhApplyRenderer
*/
private final String[] uniformNames;
/** 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.uniformNames = uniformNames;
this.uniformBuffers = new GpuBuffer[this.uniformNames.length];
this.uniformBufferWrappers = new BlazeUniformBufferWrapper[this.uniformNames.length];
}
private void tryInit(
@@ -179,10 +186,12 @@ public class BlazeDhApplyRenderer
pipelineBuilder.withUniformBuffer(uniformName);
}
pipelineBuilder.withUniformBuffer("baseFragUniformBlock");
pipelineBuilder.withSampler("uSourceColorTexture");
pipelineBuilder.withSampler("uSourceDepthTexture");
VertexFormat vertexFormat = VertexFormat.builder()
VertexFormat vertexFormat = new BlazeVertexFormatBuilder()
.add("vPosition", BlazeDhVertexFormatUtil.SCREEN_POS)
.build();
pipelineBuilder.withVertexFormat(vertexFormat);
@@ -191,7 +200,6 @@ public class BlazeDhApplyRenderer
this.pipeline = pipelineBuilder.build();
}
//endregion
@@ -201,7 +209,7 @@ public class BlazeDhApplyRenderer
//========//
//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)
// where a sequential search should be plenty fast
@@ -210,7 +218,7 @@ public class BlazeDhApplyRenderer
String nameAtIndex = this.uniformNames[i];
if (nameAtIndex.equals(uniformName))
{
this.uniformBuffers[i] = uniformBuffer;
this.uniformBufferWrappers[i] = uniformBufferWrapper;
break;
}
}
@@ -225,32 +233,38 @@ public class BlazeDhApplyRenderer
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.destinationColorTextureViewWrapper.textureView,
/*optionalClearColorAsInt*/ OptionalInt.empty(),
this.dummyDepthTextureWrapper.textureView,
/*optionalDepthValueAsDouble*/ OptionalDouble.empty()))
this.destinationColorTextureViewWrapper,
this.dummyDepthTextureWrapper))
{
renderPass.bindTexture("uSourceColorTexture", this.sourceColorTextureViewWrapper.textureView, this.sourceColorTextureViewWrapper.textureSampler);
renderPass.bindTexture("uSourceDepthTexture", this.sourceDepthTextureViewWrapper.textureView, this.sourceDepthTextureViewWrapper.textureSampler);
renderPassWrapper.bindTexture("uSourceColorTexture", this.sourceColorTextureViewWrapper);
renderPassWrapper.bindTexture("uSourceDepthTexture", this.sourceDepthTextureViewWrapper);
for (int i = 0; i < this.uniformNames.length; i++)
{
String uniformName = this.uniformNames[i];
GpuBuffer uniformBuffer = this.uniformBuffers[i];
BlazeUniformBufferWrapper uniformBuffer = this.uniformBufferWrappers[i];
if (uniformBuffer == null)
{
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);
renderPass.setPipeline(this.pipeline);
renderPassWrapper.setUniform("baseFragUniformBlock", this.fragUniformBufferWrapper);
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
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.systems.CommandEncoder;
import com.mojang.blaze3d.systems.GpuDevice;
import com.mojang.blaze3d.systems.RenderPass;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.textures.*;
import com.seibel.distanthorizons.common.render.blaze.wrappers.RenderPassWrapper;
import com.seibel.distanthorizons.common.render.blaze.wrappers.RenderPipelineBuilderWrapper;
import com.seibel.distanthorizons.common.render.blaze.wrappers.texture.BlazeTextureViewWrapper;
import com.seibel.distanthorizons.common.render.blaze.wrappers.texture.BlazeTextureWrapper;
import com.seibel.distanthorizons.common.render.blaze.util.BlazePostProcessUtil;
import com.seibel.distanthorizons.common.render.blaze.wrappers.texture.IDhBlazeTexture;
import com.seibel.distanthorizons.core.logging.DhLogger;
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import java.util.OptionalDouble;
import java.util.OptionalInt;
/**
* Blindly copies one texture into another.
*
@@ -103,7 +100,7 @@ public class BlazeDhCopyRenderer
this.pipeline = pipelineBuilder.build();
this.vboGpuBuffer = BlazePostProcessUtil.createAndUploadScreenVertexData("McCopyRenderer");
this.vboGpuBuffer = BlazePostProcessUtil.createAndUploadScreenVertexData("CopyRenderer");
}
@@ -117,48 +114,28 @@ public class BlazeDhCopyRenderer
//region
public void render(
BlazeTextureWrapper sourceColorTextureWrapper,
BlazeTextureViewWrapper 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)
IDhBlazeTexture sourceColorTextureWrapper,
IDhBlazeTexture destinationColorTextureWrapper)
{
this.tryInit();
this.dummyDepthTextureWrapper.tryCreateOrResize();
try (RenderPass renderPass = COMMAND_ENCODER.createRenderPass(
try (RenderPassWrapper renderPassWrapper = new RenderPassWrapper(
this::getRenderPassName,
destinationTextureView,
/*optionalClearColorAsInt*/ OptionalInt.empty(),
this.dummyDepthTextureWrapper.textureView,
/*optionalDepthValueAsDouble*/ OptionalDouble.empty()))
destinationColorTextureWrapper,
this.dummyDepthTextureWrapper))
{
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);
renderPass.draw(/*indexStart*/ 0, /*indexCount*/ 4);
renderPassWrapper.setPipeline(this.pipeline);
renderPassWrapper.draw(4);
}
}
private String getRenderPassName() { return "distantHorizons:McCopyRenderer"; }
private String getRenderPassName() { return "distantHorizons:CopyRenderer"; }
//endregion
@@ -25,33 +25,27 @@ public class BlazeDhFarFadeRenderer {}
#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.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.seibel.distanthorizons.common.render.blaze.BlazeDhMetaRenderer;
import com.seibel.distanthorizons.common.render.blaze.apply.BlazeDhCopyRenderer;
import com.seibel.distanthorizons.common.render.blaze.util.BlazePostProcessUtil;
import com.seibel.distanthorizons.common.render.blaze.util.BlazeUniformUtil;
import com.seibel.distanthorizons.common.render.blaze.wrappers.RenderPassWrapper;
import com.seibel.distanthorizons.common.render.blaze.wrappers.RenderPipelineBuilderWrapper;
import com.seibel.distanthorizons.common.render.blaze.wrappers.texture.BlazeTextureViewWrapper;
import com.seibel.distanthorizons.common.render.blaze.wrappers.texture.BlazeTextureWrapper;
import com.seibel.distanthorizons.common.render.blaze.wrappers.uniform.BlazeUniformBufferWrapper;
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.DhLoggerBuilder;
import com.seibel.distanthorizons.core.render.EDhRenderDepth;
import com.seibel.distanthorizons.core.render.RenderParams;
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 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
@@ -62,13 +56,14 @@ public class BlazeDhFarFadeRenderer implements IDhFarFadeRenderer
private static final GpuDevice GPU_DEVICE = RenderSystem.getDevice();
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();
private RenderPipeline pipeline;
private boolean init = false;
private GpuBuffer fragUniformBuffer;
private final BlazeUniformBufferWrapper fragUniformBufferWrapper = new BlazeUniformBufferWrapper("fragUniformBlock");
private GpuBuffer vboGpuBuffer;
@@ -123,7 +118,7 @@ public class BlazeDhFarFadeRenderer implements IDhFarFadeRenderer
this.pipeline = pipelineBuilder.build();
this.vboGpuBuffer = BlazePostProcessUtil.createAndUploadScreenVertexData("McFadeRenderer");
this.vboGpuBuffer = BlazePostProcessUtil.createAndUploadScreenVertexData("DhFarFadeRenderer");
}
//endregion
@@ -151,18 +146,11 @@ public class BlazeDhFarFadeRenderer implements IDhFarFadeRenderer
// textures
this.dhFadeColorTextureWrapper.tryCreateOrResize();
this.mcColorTextureViewWrapper.tryWrap(Minecraft.getInstance().getMainRenderTarget().getColorTexture());
this.mcColorTextureViewWrapper.tryWrap(MinecraftRenderWrapper.INSTANCE.getRenderTarget().getColorTexture());
this.dhFadeDepthTextureWrapper.tryCreateOrResize();
{
int uniformBufferSize = new Std140SizeCalculator()
.putFloat() // uStartFadeBlockDistance
.putFloat() // uEndFadeBlockDistance
.putMat4f() // uDhInvMvmProj
.get();
// create data //
float dhFarClipDistance = RenderUtil.getFarClipPlaneDistanceInBlocks();
@@ -170,30 +158,14 @@ public class BlazeDhFarFadeRenderer implements IDhFarFadeRenderer
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 //
ByteBuffer buffer = ByteBuffer.allocateDirect(uniformBufferSize);
buffer.order(ByteOrder.nativeOrder());
buffer = Std140Builder.intoBuffer(buffer)
fragUniformBufferWrapper
.putFloat(fadeStartDistance) // uStartFadeBlockDistance
.putFloat(fadeEndDistance) // uEndFadeBlockDistance
.putMat4f(inverseDhMvmProjMatrix.createJomlMatrix()) // uDhInvMvmProj
.get()
.putMat4f(renderParams.dhInverseMvmProjectionMatrix) // uDhInvMvmProj
.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);
}
@@ -204,29 +176,27 @@ public class BlazeDhFarFadeRenderer implements IDhFarFadeRenderer
private void renderFadeToTexture()
{
try (RenderPass renderPass = COMMAND_ENCODER.createRenderPass(
try (RenderPassWrapper renderPassWrapper = new RenderPassWrapper(
this::getRenderPassName,
this.dhFadeColorTextureWrapper.textureView,
/*optionalClearColorAsInt*/ OptionalInt.empty(),
this.dhFadeDepthTextureWrapper.textureView,
/*optionalDepthValueAsDouble*/ OptionalDouble.empty()))
this.dhFadeColorTextureWrapper,
this.dhFadeDepthTextureWrapper))
{
// MC texture
renderPass.bindTexture("uMcColorTexture", this.mcColorTextureViewWrapper.textureView, this.mcColorTextureViewWrapper.textureSampler);
renderPassWrapper.bindTexture("uMcColorTexture", this.mcColorTextureViewWrapper);
// DH textures
renderPass.bindTexture("uDhDepthTexture", BlazeDhMetaRenderer.INSTANCE.dhDepthTextureWrapper.textureView, BlazeDhMetaRenderer.INSTANCE.dhDepthTextureWrapper.textureSampler);
renderPass.bindTexture("uDhColorTexture", BlazeDhMetaRenderer.INSTANCE.dhColorTextureWrapper.textureView, BlazeDhMetaRenderer.INSTANCE.dhColorTextureWrapper.textureSampler);
renderPassWrapper.bindTexture("uDhDepthTexture", BlazeDhMetaRenderer.INSTANCE.dhDepthTextureWrapper);
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
renderPass.setPipeline(this.pipeline);
renderPassWrapper.setVertexBuffer(this.vboGpuBuffer);
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
@@ -23,44 +23,44 @@ package com.seibel.distanthorizons.common.render.blaze.postProcessing;
public class BlazeDhFogRenderer {}
#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.RenderPipeline;
import com.mojang.blaze3d.platform.DestFactor;
import com.mojang.blaze3d.platform.SourceFactor;
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.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.methods.events.sharedParameterObjects.DhApiFogRenderParam;
import com.seibel.distanthorizons.common.render.blaze.BlazeDhMetaRenderer;
import com.seibel.distanthorizons.common.render.blaze.apply.BlazeDhApplyRenderer;
import com.seibel.distanthorizons.common.render.blaze.wrappers.RenderPassWrapper;
import com.seibel.distanthorizons.common.render.blaze.wrappers.RenderPipelineBuilderWrapper;
import com.seibel.distanthorizons.common.render.blaze.wrappers.texture.BlazeTextureWrapper;
import com.seibel.distanthorizons.common.render.blaze.util.BlazePostProcessUtil;
import com.seibel.distanthorizons.common.render.blaze.util.BlazeUniformUtil;
import com.seibel.distanthorizons.common.render.blaze.wrappers.uniform.BlazeUniformBufferWrapper;
import com.seibel.distanthorizons.core.config.Config;
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
import com.seibel.distanthorizons.core.logging.DhLogger;
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import com.seibel.distanthorizons.core.render.EDhRenderDepth;
import com.seibel.distanthorizons.core.render.RenderParams;
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.IMinecraftRenderWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.render.AbstractDhRenderApiDefinition;
import com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass.IDhFogRenderer;
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.pipeline.BlendFunction;
import com.mojang.blaze3d.pipeline.RenderPipeline;
import com.mojang.blaze3d.systems.CommandEncoder;
import com.mojang.blaze3d.systems.GpuDevice;
import com.mojang.blaze3d.systems.RenderSystem;
#if MC_VER <= MC_26_1_2
import com.mojang.blaze3d.platform.DestFactor;
import com.mojang.blaze3d.platform.SourceFactor;
#else
import com.mojang.blaze3d.platform.BlendFactor;
#endif
/**
* Renders fog onto the LODs.
@@ -69,8 +69,7 @@ public class BlazeDhFogRenderer implements IDhFogRenderer
{
public static final DhLogger LOGGER = new DhLoggerBuilder().build();
private static final IMinecraftClientWrapper MC = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.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 CommandEncoder COMMAND_ENCODER = GPU_DEVICE.createCommandEncoder();
@@ -83,7 +82,7 @@ public class BlazeDhFogRenderer implements IDhFogRenderer
private RenderPipeline pipeline;
private boolean init = false;
private GpuBuffer fragUniformBuffer;
private final BlazeUniformBufferWrapper fragUniformBufferWrapper = new BlazeUniformBufferWrapper("dh_fog_frag_uniform");
private GpuBuffer vboGpuBuffer;
@@ -109,11 +108,16 @@ public class BlazeDhFogRenderer implements IDhFogRenderer
this.init = true;
BlendFunction blendFunc;
#if MC_VER <= MC_26_1_2
blendFunc = new BlendFunction(SourceFactor.SRC_ALPHA, DestFactor.ONE_MINUS_SRC_ALPHA, SourceFactor.ONE, DestFactor.ONE_MINUS_SRC_ALPHA);
#else
blendFunc = new BlendFunction(BlendFactor.SRC_ALPHA, BlendFactor.ONE_MINUS_SRC_ALPHA, BlendFactor.ONE, BlendFactor.ONE_MINUS_SRC_ALPHA);
#endif
this.applyRenderer = new BlazeDhApplyRenderer(
"fog_apply_to_dh",
new BlendFunction(SourceFactor.SRC_ALPHA, DestFactor.ONE_MINUS_SRC_ALPHA, SourceFactor.ONE, DestFactor.ONE_MINUS_SRC_ALPHA),
blendFunc,
"apply/blaze/vert", "apply/blaze/frag"
);
@@ -140,7 +144,7 @@ public class BlazeDhFogRenderer implements IDhFogRenderer
this.pipeline = pipelineBuilder.build();
this.vboGpuBuffer = BlazePostProcessUtil.createAndUploadScreenVertexData("McFogRenderer");
this.vboGpuBuffer = BlazePostProcessUtil.createAndUploadScreenVertexData("FogRenderer");
}
//endregion
@@ -153,7 +157,7 @@ public class BlazeDhFogRenderer implements IDhFogRenderer
//region
@Override
public void render(RenderParams renderParams)
public void render(RenderParams renderParams, DhApiFogRenderParam fogRenderParams)
{
this.tryInit();
@@ -170,144 +174,68 @@ public class BlazeDhFogRenderer implements IDhFogRenderer
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 //
int lodDrawDistance = Config.Client.Advanced.Graphics.Quality.lodChunkRenderDistanceRadius.get() * LodUtil.CHUNK_WIDTH;
Mat4f inverseMvmProjMatrix = new Mat4f(renderParams.dhMvmProjMatrix);
DhMat4f inverseMvmProjMatrix = new DhMat4f(renderParams.dhMvmProjMatrix);
inverseMvmProjMatrix.invert();
if (renderParams.dhMvmProjMatrix == null)
{
return;
}
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;
EDhApiHeightFogMixMode heightFogMixingMode = fogRenderParams.getHeightFogMixingMode();
boolean heightFogEnabled =
heightFogMixingMode != EDhApiHeightFogMixMode.SPHERICAL
&& heightFogMixingMode != EDhApiHeightFogMixMode.CYLINDRICAL;
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();
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();
Color fogColor = fogRenderParams.getFogColor();
// upload data //
ByteBuffer buffer = ByteBuffer.allocateDirect(uniformBufferSize);
buffer.order(ByteOrder.nativeOrder());
buffer = Std140Builder.intoBuffer(buffer)
this.fragUniformBufferWrapper
// fog uniforms
.putVec4(
.putVec4f(
fogColor.getRed() / 255.0f,
fogColor.getGreen() / 255.0f,
fogColor.getBlue() / 255.0f,
fogColor.getAlpha() / 255.0f) // uFogColor
.putFloat(1.f / lodDrawDistance) //uFogScale
.putFloat(1.f / MC.getWrappedClientLevel().getMaxHeight()) //uFogVerticalScale
// only used for debugging
.putInt(0) //uFogDebugMode // 1 = render everything with fog color // 7 = use debug rendering
.putInt(Config.Client.Advanced.Graphics.Fog.farFogFalloff.get().value) //uFogFalloffType
.putFloat(1.f / renderParams.clientLevelWrapper.getMaxHeight()) //uFogVerticalScale
.putInt(0) //uFogDebugMode // 0 = normal // 1 = render everything with fog color // 7 = use debug rendering
.putInt(fogRenderParams.getFarFogFalloff().value) //uFogFalloffType
// fog config
.putFloat(farFogStart) // uFarFogStart
.putFloat(farFogEnd - farFogStart) // uFarFogLength
.putFloat(farFogMin) // uFarFogMin
.putFloat(farFogMax - farFogMin) // uFarFogRange
.putFloat(farFogDensity) // uFarFogDensity
.putFloat(fogRenderParams.getFarFogStartPercent()) // uFarFogStart
.putFloat(fogRenderParams.getFarFogEndPercent() - fogRenderParams.getFarFogStartPercent()) // uFarFogLength
.putFloat(fogRenderParams.getFarFogMinThickness()) // uFarFogMin
.putFloat(fogRenderParams.getFarFogMaxThickness() - fogRenderParams.getFarFogMinThickness()) // uFarFogRange
.putFloat(fogRenderParams.getFarFogDensity()) // uFarFogDensity
// height fog config
.putFloat(heightFogStart) // uHeightFogStart
.putFloat(heightFogEnd - heightFogStart) // uHeightFogLength
.putFloat(heightFogMin) // uHeightFogMin
.putFloat(heightFogMax - heightFogMin) // uHeightFogRange
.putFloat(heightFogDensity) // uHeightFogDensity
.putFloat(fogRenderParams.getHeightFogStartPercent()) // uHeightFogStart
.putFloat(fogRenderParams.getHeightFogEndPercent() - fogRenderParams.getHeightFogStartPercent()) // uHeightFogLength
.putFloat(fogRenderParams.getHeightFogMinThickness()) // uHeightFogMin
.putFloat(fogRenderParams.getHeightFogMaxThickness() - fogRenderParams.getHeightFogMinThickness()) // uHeightFogRange
.putFloat(fogRenderParams.getHeightFogDensity()) // uHeightFogDensity
// ??
.putInt(heightFogEnabled ? 1 : 0) // uHeightFogEnabled
.putInt(Config.Client.Advanced.Graphics.Fog.HeightFog.heightFogFalloff.get().value) // uHeightFogFalloffType
.putInt(heightFogCameraDirection.basedOnCamera ? 1 : 0) // uHeightBasedOnCamera
.putFloat(Config.Client.Advanced.Graphics.Fog.HeightFog.heightFogBaseHeight.get()) // uHeightFogBaseHeight
.putInt(heightFogCameraDirection.fogAppliesUp ? 1 : 0) // uHeightFogAppliesUp
.putInt(heightFogCameraDirection.fogAppliesDown ? 1 : 0) // uHeightFogAppliesDown
.putInt(fogRenderParams.getHeightFogFalloff().value) // uHeightFogFalloffType
.putInt(fogRenderParams.getHeightFogDirection().basedOnCamera ? 1 : 0) // uHeightBasedOnCamera
.putFloat(fogRenderParams.getHeightFogBaseHeight()) // uHeightFogBaseHeight
.putInt(fogRenderParams.getHeightFogDirection().fogAppliesUp ? 1 : 0) // uHeightFogAppliesUp
.putInt(fogRenderParams.getHeightFogDirection().fogAppliesDown ? 1 : 0) // uHeightFogAppliesDown
.putInt(useSphericalFog ? 1 : 0) // uUseSphericalFog
.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);
}
@@ -316,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()
{
try (RenderPass renderPass = COMMAND_ENCODER.createRenderPass(
try (RenderPassWrapper renderPassWrapper = new RenderPassWrapper(
this::getRenderPassName,
this.fogColorTextureWrapper.textureView,
/*optionalClearColorAsInt*/ OptionalInt.empty(),
this.fogDepthTextureWrapper.textureView,
/*optionalDepthValueAsDouble*/ OptionalDouble.empty()))
this.fogColorTextureWrapper,
this.fogDepthTextureWrapper))
{
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
renderPass.setPipeline(this.pipeline);
renderPassWrapper.setVertexBuffer(this.vboGpuBuffer); // vertex buffer can only be "0" lol
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
@@ -23,38 +23,38 @@ package com.seibel.distanthorizons.common.render.blaze.postProcessing;
public class BlazeDhSsaoRenderer {}
#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.RenderPipeline;
import com.mojang.blaze3d.platform.DestFactor;
import com.mojang.blaze3d.platform.SourceFactor;
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.seibel.distanthorizons.common.render.blaze.BlazeDhMetaRenderer;
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.texture.BlazeTextureWrapper;
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.logging.DhLogger;
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.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.render.AbstractDhRenderApiDefinition;
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.pipeline.BlendFunction;
import com.mojang.blaze3d.pipeline.RenderPipeline;
import com.mojang.blaze3d.systems.CommandEncoder;
import com.mojang.blaze3d.systems.GpuDevice;
import com.mojang.blaze3d.systems.RenderSystem;
#if MC_VER <= MC_26_1_2
import com.mojang.blaze3d.platform.DestFactor;
import com.mojang.blaze3d.platform.SourceFactor;
#else
import com.mojang.blaze3d.platform.BlendFactor;
#endif
/** Renders SSAO to the DH LODs. */
public class BlazeDhSsaoRenderer implements IDhSsaoRenderer
@@ -62,6 +62,7 @@ public class BlazeDhSsaoRenderer implements IDhSsaoRenderer
private static final DhLogger LOGGER = new DhLoggerBuilder().build();
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 CommandEncoder COMMAND_ENCODER = GPU_DEVICE.createCommandEncoder();
@@ -74,8 +75,8 @@ public class BlazeDhSsaoRenderer implements IDhSsaoRenderer
private RenderPipeline pipeline;
private boolean init = false;
private GpuBuffer fragUniformBuffer;
private GpuBuffer applyFragUniformBuffer;
private final BlazeUniformBufferWrapper fragUniformBufferWrapper = new BlazeUniformBufferWrapper("fragUniformBlock");
private final BlazeUniformBufferWrapper applyFragUniformBufferWrapper = new BlazeUniformBufferWrapper("applyFragUniformBlock");
private GpuBuffer vboGpuBuffer;
@@ -101,9 +102,17 @@ public class BlazeDhSsaoRenderer implements IDhSsaoRenderer
this.init = true;
BlendFunction blendFunc;
#if MC_VER <= MC_26_1_2
blendFunc = new BlendFunction(SourceFactor.ZERO, DestFactor.SRC_ALPHA, SourceFactor.ZERO, DestFactor.ONE);
#else
blendFunc = new BlendFunction(BlendFactor.ZERO, BlendFactor.SRC_ALPHA, BlendFactor.ZERO, BlendFactor.ONE);
#endif
this.applyRenderer = new BlazeDhApplyRenderer(
"ssao_apply_to_dh",
new BlendFunction(SourceFactor.ZERO, DestFactor.SRC_ALPHA, SourceFactor.ZERO, DestFactor.ONE),
blendFunc,
"apply/blaze/vert", "ssao/blaze/apply",
/*uniforms*/ new String[] { "applyFragUniformBlock" }
);
@@ -163,32 +172,14 @@ public class BlazeDhSsaoRenderer implements IDhSsaoRenderer
// 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 //
Mat4f projMatrix = new Mat4f(renderParams.dhProjectionMatrix);
Mat4f invertedProjMatrix = new Mat4f(renderParams.dhProjectionMatrix);
DhMat4f projMatrix = new DhMat4f(renderParams.dhProjectionMatrix);
DhMat4f invertedProjMatrix = new DhMat4f(renderParams.dhProjectionMatrix);
invertedProjMatrix.invert();
// upload data //
ByteBuffer buffer = ByteBuffer.allocateDirect(uniformBufferSize);
buffer.order(ByteOrder.nativeOrder());
buffer = Std140Builder.intoBuffer(buffer)
this.fragUniformBufferWrapper
.putInt(6) // uSampleCount
.putFloat(4.0f) // uRadius
@@ -197,27 +188,16 @@ public class BlazeDhSsaoRenderer implements IDhSsaoRenderer
.putFloat(0.02f) // uBias
.putFloat(1_600.0f) // uFadeDistanceInBlocks
.putMat4f(invertedProjMatrix.createJomlMatrix())
.putMat4f(projMatrix.createJomlMatrix())
.get()
.putMat4f(invertedProjMatrix)
.putMat4f(projMatrix)
.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
{
int uniformBufferSize = new Std140SizeCalculator()
.putVec2() // uViewSize
.putInt() // uBlurRadius
.putFloat() // uNearClipPlane
.putFloat() // uFarClipPlane
.get();
// create data //
float viewWidth = (float)MC_RENDER.getTargetFramebufferViewportWidth();
@@ -228,51 +208,41 @@ public class BlazeDhSsaoRenderer implements IDhSsaoRenderer
// upload data //
ByteBuffer buffer = ByteBuffer.allocateDirect(uniformBufferSize);
buffer.order(ByteOrder.nativeOrder());
buffer = Std140Builder.intoBuffer(buffer)
.putVec2(viewWidth, viewHeight) // uViewSize
this.applyFragUniformBufferWrapper
.putVec2f(viewWidth, viewHeight) // uViewSize
.putInt(2) // uBlurRadius
.putFloat(nearClipPlane) // uNearClipPlane
.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.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);
}
private void renderSsaoToTexture()
{
try (RenderPass renderPass = COMMAND_ENCODER.createRenderPass(
try (RenderPassWrapper renderPassWrapper = new RenderPassWrapper(
this::getRenderPassName,
this.ssaoColorTextureWrapper.textureView,
/*optionalClearColorAsInt*/ OptionalInt.empty(),
this.ssaoDepthTextureWrapper.textureView,
/*optionalDepthValueAsDouble*/ OptionalDouble.empty()))
this.ssaoColorTextureWrapper,
this.ssaoDepthTextureWrapper))
{
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);
renderPass.draw(/*indexStart*/ 0, /*indexCount*/ 4);
renderPassWrapper.setPipeline(this.pipeline);
renderPassWrapper.draw(4);
}
}
private String getRenderPassName() { return "distantHorizons:McSsaoRenderer"; }
private String getRenderPassName() { return "distantHorizons:SsaoRenderer"; }
//endregion
@@ -25,40 +25,30 @@ public class BlazeVanillaFadeRenderer {}
#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.RenderPipeline;
import com.mojang.blaze3d.platform.PolygonMode;
import com.mojang.blaze3d.shaders.UniformType;
import com.mojang.blaze3d.systems.CommandEncoder;
import com.mojang.blaze3d.systems.GpuDevice;
import com.mojang.blaze3d.systems.RenderPass;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.VertexFormat;
import com.seibel.distanthorizons.common.render.blaze.BlazeDhMetaRenderer;
import com.seibel.distanthorizons.common.render.blaze.apply.BlazeDhCopyRenderer;
import com.seibel.distanthorizons.common.render.blaze.util.BlazePostProcessUtil;
import com.seibel.distanthorizons.common.render.blaze.util.BlazeUniformUtil;
import com.seibel.distanthorizons.common.render.blaze.wrappers.RenderPassWrapper;
import com.seibel.distanthorizons.common.render.blaze.wrappers.RenderPipelineBuilderWrapper;
import com.seibel.distanthorizons.common.render.blaze.wrappers.texture.BlazeTextureViewWrapper;
import com.seibel.distanthorizons.common.render.blaze.wrappers.texture.BlazeTextureWrapper;
import com.seibel.distanthorizons.common.render.blaze.wrappers.uniform.BlazeUniformBufferWrapper;
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftRenderWrapper;
import com.seibel.distanthorizons.core.config.Config;
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
import com.seibel.distanthorizons.core.logging.DhLogger;
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import com.seibel.distanthorizons.core.render.EDhRenderDepth;
import com.seibel.distanthorizons.core.render.RenderParams;
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.render.AbstractDhRenderApiDefinition;
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
@@ -69,16 +59,18 @@ public class BlazeVanillaFadeRenderer implements IDhVanillaFadeRenderer
public static final DhLogger LOGGER = new DhLoggerBuilder().build();
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 CommandEncoder COMMAND_ENCODER = GPU_DEVICE.createCommandEncoder();
public static final BlazeVanillaFadeRenderer INSTANCE = new BlazeVanillaFadeRenderer();
private RenderPipeline pipeline;
private boolean init = false;
private GpuBuffer fragUniformBuffer;
private final BlazeUniformBufferWrapper fragUniformBufferWrapper = new BlazeUniformBufferWrapper("fragUniformBlock");
private GpuBuffer vboGpuBuffer;
@@ -136,7 +128,7 @@ public class BlazeVanillaFadeRenderer implements IDhVanillaFadeRenderer
this.pipeline = pipelineBuilder.build();
this.vboGpuBuffer = BlazePostProcessUtil.createAndUploadScreenVertexData("McFadeRenderer");
this.vboGpuBuffer = BlazePostProcessUtil.createAndUploadScreenVertexData("VanillaFadeRenderer");
}
//endregion
@@ -164,21 +156,11 @@ public class BlazeVanillaFadeRenderer implements IDhVanillaFadeRenderer
this.fadeColorTextureWrapper.tryCreateOrResize();
this.fadeDepthTextureWrapper.tryCreateOrResize();
this.mcDepthTextureWrapper.tryWrap(Minecraft.getInstance().getMainRenderTarget().getDepthTexture());
this.mcColorTextureWrapper.tryWrap(Minecraft.getInstance().getMainRenderTarget().getColorTexture());
this.mcDepthTextureWrapper.tryWrap(MinecraftRenderWrapper.INSTANCE.getRenderTarget().getDepthTexture());
this.mcColorTextureWrapper.tryWrap(MinecraftRenderWrapper.INSTANCE.getRenderTarget().getColorTexture());
{
int uniformBufferSize = new Std140SizeCalculator()
.putInt() // uOnlyRenderLods
.putFloat() // uStartFadeBlockDistance
.putFloat() // uEndFadeBlockDistance
.putFloat() // uMaxLevelHeight
.putMat4f() // uDhInvMvmProj
.putMat4f() // uMcInvMvmProj
.get();
// create data //
float dhNearClipDistance = RenderUtil.getNearClipPlaneInBlocks();
@@ -192,40 +174,30 @@ public class BlazeVanillaFadeRenderer implements IDhVanillaFadeRenderer
float fadeEndDistance = dhNearClipDistance * 1.9f;
Mat4f inverseMcModelViewProjectionMatrix = new Mat4f(renderParams.mcProjectionMatrix);
DhMat4f inverseMcModelViewProjectionMatrix = new DhMat4f(renderParams.mcProjectionMatrix);
inverseMcModelViewProjectionMatrix.multiply(renderParams.mcModelViewMatrix);
inverseMcModelViewProjectionMatrix.invert();
Mat4f inverseMcMvmProjMatrix = inverseMcModelViewProjectionMatrix;
DhMat4f inverseMcMvmProjMatrix = inverseMcModelViewProjectionMatrix;
Mat4f dhProjectionMatrix = RenderUtil.createLodProjectionMatrix(renderParams.mcProjectionMatrix);
Mat4f dhModelViewMatrix = RenderUtil.createLodModelViewMatrix(renderParams.mcModelViewMatrix);
Mat4f inverseDhModelViewProjectionMatrix = new Mat4f(dhProjectionMatrix);
inverseDhModelViewProjectionMatrix.multiply(dhModelViewMatrix);
DhMat4f inverseDhModelViewProjectionMatrix = new DhMat4f(renderParams.dhProjectionMatrix);
inverseDhModelViewProjectionMatrix.multiply(renderParams.dhModelViewMatrix);
inverseDhModelViewProjectionMatrix.invert();
Mat4f inverseDhMvmProjMatrix = inverseDhModelViewProjectionMatrix;
DhMat4f inverseDhMvmProjMatrix = inverseDhModelViewProjectionMatrix;
// upload data //
ByteBuffer buffer = ByteBuffer.allocateDirect(uniformBufferSize);
buffer.order(ByteOrder.nativeOrder());
buffer = Std140Builder.intoBuffer(buffer)
this.fragUniformBufferWrapper
.putInt(Config.Client.Advanced.Debugging.lodOnlyMode.get() ? 1 : 0) // uOnlyRenderLods
.putFloat(fadeStartDistance) // uStartFadeBlockDistance
.putFloat(fadeEndDistance) // uEndFadeBlockDistance
.putFloat(renderParams.clientLevelWrapper.getMaxHeight()) // uMaxLevelHeight
.putMat4f(inverseDhMvmProjMatrix.createJomlMatrix()) // uDhInvMvmProj
.putMat4f(inverseMcMvmProjMatrix.createJomlMatrix()) // uMcInvMvmProj
.get()
.putMat4f(inverseDhMvmProjMatrix) // uDhInvMvmProj
.putMat4f(inverseMcMvmProjMatrix) // uMcInvMvmProj
.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);
}
@@ -236,28 +208,26 @@ public class BlazeVanillaFadeRenderer implements IDhVanillaFadeRenderer
private void renderFadeToTexture()
{
try (RenderPass renderPass = COMMAND_ENCODER.createRenderPass(
try (RenderPassWrapper renderPassWrapper = new RenderPassWrapper(
this::getRenderPassName,
this.fadeColorTextureWrapper.textureView,
/*optionalClearColorAsInt*/ OptionalInt.empty(),
this.fadeDepthTextureWrapper.textureView,
/*optionalDepthValueAsDouble*/ OptionalDouble.empty()))
this.fadeColorTextureWrapper,
this.fadeDepthTextureWrapper))
{
renderPass.bindTexture("uMcDepthTexture", this.mcDepthTextureWrapper.textureView, this.mcDepthTextureWrapper.textureSampler);
renderPass.bindTexture("uCombinedMcDhColorTexture", this.mcColorTextureWrapper.textureView, this.mcColorTextureWrapper.textureSampler);
renderPassWrapper.bindTexture("uMcDepthTexture", this.mcDepthTextureWrapper);
renderPassWrapper.bindTexture("uCombinedMcDhColorTexture", this.mcColorTextureWrapper);
renderPass.bindTexture("uDhDepthTexture", BlazeDhMetaRenderer.INSTANCE.dhDepthTextureWrapper.textureView, BlazeDhMetaRenderer.INSTANCE.dhDepthTextureWrapper.textureSampler);
renderPass.bindTexture("uDhColorTexture", BlazeDhMetaRenderer.INSTANCE.dhColorTextureWrapper.textureView, BlazeDhMetaRenderer.INSTANCE.dhColorTextureWrapper.textureSampler);
renderPassWrapper.bindTexture("uDhDepthTexture", BlazeDhMetaRenderer.INSTANCE.dhDepthTextureWrapper);
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);
renderPass.draw(/*indexStart*/ 0, /*indexCount*/ 4);
renderPassWrapper.setPipeline(this.pipeline);
renderPassWrapper.draw(/*indexCount*/ 4);
}
}
private String getRenderPassName() { return "distantHorizons:McFadeRenderer"; }
private String getRenderPassName() { return "distantHorizons:VanillaFadeRenderer"; }
//endregion
@@ -35,8 +35,11 @@ import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.textures.*;
import com.mojang.blaze3d.vertex.VertexFormat;
import com.seibel.distanthorizons.common.render.blaze.util.BlazeDhVertexFormatUtil;
import com.seibel.distanthorizons.common.render.blaze.wrappers.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.texture.BlazeTextureViewWrapper;
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftRenderWrapper;
import com.seibel.distanthorizons.core.logging.DhLogger;
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import com.seibel.distanthorizons.core.render.RenderParams;
@@ -106,7 +109,7 @@ public class BlazeDhTestTriangleRenderer implements IDhTestTriangleRenderer
pipelineBuilder.withVertexShader("test/blaze/vert");
pipelineBuilder.withFragmentShader("test/blaze/frag");
VertexFormat vertexFormat = VertexFormat.builder()
VertexFormat vertexFormat = new BlazeVertexFormatBuilder()
.add("vPosition", BlazeDhVertexFormatUtil.SCREEN_POS)
.add("vColor", BlazeDhVertexFormatUtil.RGBA_FLOAT_COLOR)
.build();
@@ -164,19 +167,17 @@ public class BlazeDhTestTriangleRenderer implements IDhTestTriangleRenderer
{
this.tryInit();
this.mcColorTextureViewWrapper.tryWrap(Minecraft.getInstance().getMainRenderTarget().getColorTexture());
this.mcDepthTextureViewWrapper.tryWrap(Minecraft.getInstance().getMainRenderTarget().getDepthTexture());
this.mcColorTextureViewWrapper.tryWrap(MinecraftRenderWrapper.INSTANCE.getRenderTarget().getColorTexture());
this.mcDepthTextureViewWrapper.tryWrap(MinecraftRenderWrapper.INSTANCE.getRenderTarget().getDepthTexture());
try (RenderPass renderPass = COMMAND_ENCODER.createRenderPass(
try (RenderPassWrapper renderPassWrapper = new RenderPassWrapper(
this::getRenderPassName,
this.mcColorTextureViewWrapper.textureView,
/*optionalClearColorAsInt*/ OptionalInt.empty(),
this.mcDepthTextureViewWrapper.textureView,
/*optionalDepthValueAsDouble*/ OptionalDouble.empty()))
this.mcColorTextureViewWrapper,
this.mcDepthTextureViewWrapper))
{
renderPass.setVertexBuffer(0, this.vboGpuBuffer);
renderPass.setPipeline(this.pipeline);
renderPass.draw(/*indexStart*/ 0, /*indexCount*/ 3);
renderPassWrapper.setVertexBuffer(this.vboGpuBuffer);
renderPassWrapper.setPipeline(this.pipeline);
renderPassWrapper.draw(3);
}
}
private String getRenderPassName() { return "distantHorizons:DhTestRenderer"; }
@@ -4,9 +4,9 @@ package com.seibel.distanthorizons.common.render.blaze.util;
public class BlazeDhVertexFormatUtil {}
#else
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.dataObjects.render.bufferBuilding.LodQuadBuilder;
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
@@ -16,6 +16,11 @@ import com.seibel.distanthorizons.core.wrapperInterfaces.IVersionConstants;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
import org.jetbrains.annotations.NotNull;
#if MC_VER <= MC_26_1_2
#else
import com.mojang.blaze3d.GpuFormat;
#endif
/**
* @see LodQuadBuilder
*/
@@ -43,14 +48,14 @@ public class BlazeDhVertexFormatUtil
static
{
EDhApiRenderApi renderingApi = Config.Client.Advanced.Graphics.Experimental.renderingApi.get();
if (renderingApi == EDhApiRenderApi.AUTO)
EDhApiRenderingEngine renderingApi = Config.Client.Advanced.Graphics.Experimental.renderingEngine.get();
if (renderingApi == EDhApiRenderingEngine.AUTO)
{
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)
{
LOGGER.debug("Attempting to register ["+VertexFormatElement.class.getSimpleName()+"]...");
@@ -70,7 +75,7 @@ public class BlazeDhVertexFormatUtil
IRIS_NORMAL = VertexFormatElement.register(/*id*/29, /*index*/0, VertexFormatElement.Type.BYTE, VertexFormatElement.Usage.GENERIC, /*count*/ 1);
FLOAT_XYZ_POS = VertexFormatElement.register(/*id*/30, /*index*/0, VertexFormatElement.Type.FLOAT, VertexFormatElement.Usage.POSITION, /*count*/ 3);
#else
#elif MC_VER <= MC_26_1_2
SCREEN_POS = VertexFormatElement.register(/*id*/22, /*index*/0, VertexFormatElement.Type.FLOAT, false, /*count*/ 2);
RGBA_FLOAT_COLOR = VertexFormatElement.register(/*id*/23, /*index*/0, VertexFormatElement.Type.FLOAT, false, /*count*/ 4);
@@ -83,6 +88,35 @@ public class BlazeDhVertexFormatUtil
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);
#elif MC_VER <= MC_26_1_2
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
SHORT_XYZ_POS = VertexFormatElement.register(/*id*/24, /*index*/0, GpuFormat.RGB16_UINT); // 3 ushorts
BYTE_PAD = VertexFormatElement.register(/*id*/25, /*index*/0, GpuFormat.R8_UINT); // 1 byte
META = VertexFormatElement.register(/*id*/26, /*index*/0, GpuFormat.R16_UINT); // 1 ushort
RGBA_UBYTE_COLOR = VertexFormatElement.register(/*id*/27, /*index*/0, GpuFormat.RGBA8_UNORM); // 4 ubytes
IRIS_MATERIAL = VertexFormatElement.register(/*id*/28, /*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
#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
}
catch (Exception e)
@@ -118,5 +152,7 @@ public class BlazeDhVertexFormatUtil
}
#endif
@@ -11,6 +11,7 @@ import com.mojang.blaze3d.systems.CommandEncoder;
import com.mojang.blaze3d.systems.GpuDevice;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.VertexFormat;
import com.seibel.distanthorizons.common.render.blaze.wrappers.BlazeVertexFormatBuilder;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
@@ -67,7 +68,7 @@ public class BlazePostProcessUtil
public static VertexFormat createVertexFormat()
{
VertexFormat vertexFormat = VertexFormat.builder()
VertexFormat vertexFormat = new BlazeVertexFormatBuilder()
.add("vPosition", BlazeDhVertexFormatUtil.SCREEN_POS)
.build();
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,8 +6,7 @@ public class RenderPipelineBuilderWrapper {}
#else
import com.mojang.blaze3d.pipeline.BlendFunction;
import com.mojang.blaze3d.pipeline.RenderPipeline;
import com.mojang.blaze3d.pipeline.*;
import com.mojang.blaze3d.platform.PolygonMode;
import com.mojang.blaze3d.shaders.UniformType;
import com.mojang.blaze3d.vertex.VertexFormat;
@@ -15,14 +14,17 @@ import net.minecraft.resources.Identifier;
#if MC_VER <= MC_1_21_11
import com.mojang.blaze3d.platform.DepthTestFunction;
#else
import com.mojang.blaze3d.pipeline.ColorTargetState;
import com.mojang.blaze3d.pipeline.DepthStencilState;
#elif MC_VER <= MC_26_1_2
import com.mojang.blaze3d.platform.CompareOp;
#else
import com.mojang.blaze3d.platform.CompareOp;
import com.mojang.blaze3d.GpuFormat;
import com.mojang.blaze3d.PrimitiveTopology;
#endif
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Optional;
public class RenderPipelineBuilderWrapper
@@ -130,15 +132,27 @@ public class RenderPipelineBuilderWrapper
return this;
}
private final ArrayList<String> samplerNames = new ArrayList<>();
public RenderPipelineBuilderWrapper withSampler(String name) throws IllegalArgumentException
{
#if MC_VER <= MC_26_1_2
this.blazePipelineBuilder.withSampler(name);
#else
samplerNames.add(name);
#endif
return this;
}
private final ArrayList<String> uniformBufferNames = new ArrayList<>();
public RenderPipelineBuilderWrapper withUniformBuffer(String name) throws IllegalArgumentException
{
#if MC_VER <= MC_26_1_2
this.blazePipelineBuilder.withUniform(name, UniformType.UNIFORM_BUFFER);
#else
uniformBufferNames.add(name);
#endif
return this;
}
@@ -243,18 +257,31 @@ public class RenderPipelineBuilderWrapper
case LESS:
compareOp = CompareOp.LESS_THAN;
break;
case GREATER:
compareOp = CompareOp.GREATER_THAN;
break;
default:
throw new UnsupportedOperationException("No depth test defined for type ["+this.depthTest+"].");
}
this.blazePipelineBuilder.withDepthStencilState(new DepthStencilState(compareOp, this.writeDepth));
#if MC_VER <= MC_26_1_2
this.blazePipelineBuilder.withColorTargetState(
new ColorTargetState(
Optional.ofNullable(this.blendFunction),
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
}
@@ -262,6 +289,7 @@ public class RenderPipelineBuilderWrapper
// vertex format
{
#if MC_VER <= MC_26_1_2
VertexFormat.Mode blazeVertexMode;
switch (this.vertexMode)
{
@@ -280,8 +308,56 @@ public class RenderPipelineBuilderWrapper
}
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
}
// uniform buffers
{
#if MC_VER <= MC_26_1_2
// handled before this point
#else
BindGroupLayout.Builder bindGroupBuilder = BindGroupLayout.builder();
for (String name : this.samplerNames)
{
bindGroupBuilder.withSampler(name);
}
for (String name : this.uniformBufferNames)
{
bindGroupBuilder.withUniform(name, UniformType.UNIFORM_BUFFER);
}
BindGroupLayout bindGroup = bindGroupBuilder.build();
this.blazePipelineBuilder.withBindGroupLayout(bindGroup);
#endif
}
return this.blazePipelineBuilder.build();
}
@@ -342,6 +418,7 @@ public class RenderPipelineBuilderWrapper
public enum EDhDepthTest
{
NONE,
GREATER,
LESS;
}
@@ -18,7 +18,6 @@ import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import com.seibel.distanthorizons.core.render.RenderThreadTaskHandler;
import com.seibel.distanthorizons.core.wrapperInterfaces.render.AbstractDhRenderApiDefinition;
import com.seibel.distanthorizons.core.wrapperInterfaces.render.objects.IVertexBufferWrapper;
import org.lwjgl.system.MemoryUtil;
import java.nio.ByteBuffer;
import java.util.concurrent.atomic.AtomicInteger;
@@ -83,9 +82,6 @@ public class BlazeVertexBufferWrapper implements IVertexBufferWrapper
GpuBufferSlice bufferSlice = new GpuBufferSlice(GLOBAL_INDEX_GPU_BUFFER, /*offset*/ 0, indexBuffer.capacity());
COMMAND_ENCODER.writeToBuffer(bufferSlice, indexBuffer);
MemoryUtil.memFree(indexBuffer);
});
}
}
@@ -14,7 +14,7 @@ import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import java.util.OptionalDouble;
public class BlazeTextureViewWrapper
public class BlazeTextureViewWrapper implements IDhBlazeTexture
{
public static final DhLogger LOGGER = new DhLoggerBuilder().build();
@@ -22,8 +22,11 @@ public class BlazeTextureViewWrapper
private static final CommandEncoder COMMAND_ENCODER = GPU_DEVICE.createCommandEncoder();
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; }
@@ -5,11 +5,6 @@ public class BlazeTextureWrapper {}
#else
import com.mojang.blaze3d.buffers.GpuBuffer;
import com.mojang.blaze3d.systems.CommandEncoder;
import com.mojang.blaze3d.systems.GpuDevice;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.textures.*;
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
import com.seibel.distanthorizons.core.logging.DhLogger;
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
@@ -18,7 +13,19 @@ import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRen
import java.util.OptionalDouble;
public class BlazeTextureWrapper
import com.mojang.blaze3d.systems.CommandEncoder;
import com.mojang.blaze3d.systems.GpuDevice;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.textures.*;
#if MC_VER <= MC_26_1_2
#else
import com.mojang.blaze3d.GpuFormat;
import org.joml.Vector4f;
#endif
public class BlazeTextureWrapper implements IDhBlazeTexture
{
public static final DhLogger LOGGER = new DhLoggerBuilder().build();
@@ -29,11 +36,20 @@ public class BlazeTextureWrapper
public final String name;
#if MC_VER <= MC_26_1_2
public final TextureFormat textureFormat;
#else
public final GpuFormat textureFormat;
#endif
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 height = -1;
@@ -45,10 +61,27 @@ public class BlazeTextureWrapper
//==============//
//region
public static BlazeTextureWrapper createDepth(String name) { return new BlazeTextureWrapper(name, TextureFormat.DEPTH32); }
public static BlazeTextureWrapper createColor(String name) { return new BlazeTextureWrapper(name, TextureFormat.RGBA8); }
public static BlazeTextureWrapper createDepth(String name)
{
#if MC_VER <= MC_26_1_2
return new BlazeTextureWrapper(name, TextureFormat.DEPTH32);
#else
return new BlazeTextureWrapper(name, GpuFormat.D32_FLOAT);
#endif
}
public static BlazeTextureWrapper createColor(String name)
{
#if MC_VER <= MC_26_1_2
return new BlazeTextureWrapper(name, TextureFormat.RGBA8);
#else
return new BlazeTextureWrapper(name, GpuFormat.RGBA8_UNORM);
#endif
}
private BlazeTextureWrapper(String name, TextureFormat textureFormat)
private BlazeTextureWrapper(
String name,
#if MC_VER <= MC_26_1_2 TextureFormat #else GpuFormat #endif textureFormat
)
{
this.name = name;
this.textureFormat = textureFormat;
@@ -116,11 +149,13 @@ public class BlazeTextureWrapper
| GpuTexture.USAGE_TEXTURE_BINDING
| GpuTexture.USAGE_COPY_SRC
| GpuTexture.USAGE_RENDER_ATTACHMENT;
this.texture = GPU_DEVICE.createTexture(this.name,
this.texture = GPU_DEVICE.createTexture(
this.name,
usage,
this.textureFormat,
viewWidth, viewHeight,
/*depthOrLayers*/ 1, /*mipLevels*/ 1
/*depthOrLayers*/ 1, /*mipLevels*/ 1
);
this.textureView = GPU_DEVICE.createTextureView(this.texture);
@@ -156,7 +191,18 @@ public class BlazeTextureWrapper
{
if (this.texture != null)
{
#if MC_VER <= MC_26_1_2
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
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.util.math.Vec3f;
import com.seibel.distanthorizons.core.util.math.DhVec3f;
import com.seibel.distanthorizons.core.wrapperInterfaces.render.objects.ILodContainerUniformBufferWrapper;
import java.nio.ByteBuffer;
public class BlazeLodUniformBufferWrapper extends BlazeUniformBufferWrapper implements ILodContainerUniformBufferWrapper
{
@@ -37,35 +33,22 @@ public class BlazeLodUniformBufferWrapper extends BlazeUniformBufferWrapper impl
//region
@Override
public void createUniformData(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()
public void tryUpload(LodBufferContainer bufferContainer)
{
if (this.uploaded)
{
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;
}
@@ -7,17 +7,22 @@ public class BlazeUniformBufferWrapper {}
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.systems.CommandEncoder;
import com.mojang.blaze3d.systems.GpuDevice;
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.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.ByteOrder;
import java.util.ArrayList;
public class BlazeUniformBufferWrapper implements IUniformBufferWrapper
public class BlazeUniformBufferWrapper implements AutoCloseable
{
private static final DhLogger LOGGER = new DhLoggerBuilder().build();
@@ -27,11 +32,22 @@ public class BlazeUniformBufferWrapper implements IUniformBufferWrapper
private final String name;
private int cpuBufferSize = 0;
private int gpuBufferSize = 0;
/** measured in bytes */
private int bufferSize = 0;
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
protected ByteBuffer getOrCreateBuffer(int size)
public BlazeUniformBufferWrapper putVec2f(float x, float y)
{
if (this.cpuBuffer == null
|| this.cpuBufferSize != size)
this.putElement(EUniformElement.VEC2f);
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.cpuBuffer.order(ByteOrder.nativeOrder());
this.cpuBufferSize = size;
this.recreateCpuBuffer();
createNewBuilder = true;
}
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
|| this.gpuBufferSize != this.cpuBufferSize)
{
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;
}
// upload to GPU
this.cpuBuffer.position(0);
COMMAND_ENCODER.writeToBuffer(this.bufferSlice, this.cpuBuffer);
int byteSize = (this.cpuBuffer.limit() - this.cpuBuffer.position());
GpuBufferSlice bufferSlice = new GpuBufferSlice(this.gpuBuffer, /*offset*/0, byteSize);
if (!bufferSlice.buffer().isClosed())
{
COMMAND_ENCODER.writeToBuffer(bufferSlice, this.cpuBuffer);
}
else
{
LOGGER.warn("Uploading to buffer ["+this.name+"] failed due to already being closed");
}
// clear the element tracking for next time
this.elementCount = 0;
this.uniformElementTypes.clear();
this.uniformBufferBuilder = null;
}
private String getBufferName() { return this.name; }
//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
@@ -30,7 +30,7 @@ import com.seibel.distanthorizons.core.logging.DhLogger;
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import com.seibel.distanthorizons.core.render.RenderParams;
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 java.nio.ByteBuffer;
@@ -178,10 +178,10 @@ public class GlDhDebugWireframeRenderer extends AbstractDebugWireframeRenderer
@Override
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);
boxTransform.multiply(Mat4f.createScaleMatrix(box.maxPos.x - box.minPos.x, box.maxPos.y - box.minPos.y, box.maxPos.z - box.minPos.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(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);
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 */
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,
boolean firstPass)
{
#if MC_VER <= MC_1_12_2
this.previousBoundTextureId = GLMC.getActiveTexture();
this.previousDepthFunc = GLMC.getActiveDepthFunc();
#endif
//===================//
// 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.shaderProgramForThisFrame.unbind();
}
@@ -455,8 +467,12 @@ public class GlDhMetaRenderer implements IDhMetaRenderer
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)
GLMC.glBindTexture(0);
// 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)
#if MC_VER <= MC_1_12_2
GLMC.glBindTexture(previousBoundTextureId);
#else
GLMC.glBindTexture(0);
#endif
}
//endregion
@@ -1,5 +1,7 @@
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.GlGenericObjectVertexContainer;
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.fog.GlDhFogRenderer;
import com.seibel.distanthorizons.common.render.openGl.postProcessing.ssao.GlDhSSAORenderer;
import com.seibel.distanthorizons.common.render.openGl.terrain.GlDhTerrainShaderProgram;
import com.seibel.distanthorizons.common.render.openGl.test.GlTestTriangleRenderer;
import com.seibel.distanthorizons.core.render.EDhRenderDepth;
import com.seibel.distanthorizons.core.render.renderer.AbstractDebugWireframeRenderer;
import com.seibel.distanthorizons.core.wrapperInterfaces.render.AbstractDhRenderApiDefinition;
import com.seibel.distanthorizons.core.wrapperInterfaces.render.objects.IDhGenericObjectVertexBufferContainer;
@@ -24,7 +26,17 @@ public class GlDhRenderApiDefinition extends AbstractDhRenderApiDefinition
//=========//
//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
@@ -45,7 +45,7 @@ import com.seibel.distanthorizons.core.render.renderer.RenderableBoxGroup;
import com.seibel.distanthorizons.core.util.LodUtil;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
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.coreapi.DependencyInjection.ApiEventInjector;
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.GL32;
import org.lwjgl.opengl.GL33;
import org.lwjgl.system.MemoryUtil;
import java.awt.*;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.*;
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 DhApiBeforeGenericObjectRenderEvent.EventParam EVENT_PARAM = new DhApiBeforeGenericObjectRenderEvent.EventParam();
/**
* Can be used to troubleshoot the renderer.
@@ -225,22 +226,22 @@ public class GlGenericObjectRenderer implements IDhGenericRenderer
private void createBuffers()
{
// 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.rewind();
this.boxVertexBuffer = new GLVertexBuffer(false);
this.boxVertexBuffer.bind();
this.boxVertexBuffer.uploadBuffer(boxVerticesBuffer, 8, EDhApiGpuUploadMethod.DATA, BOX_VERTICES.length * Float.BYTES);
MemoryUtil.memFree(boxVerticesBuffer);
// 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.rewind();
this.boxIndexBuffer = new GLIndexBuffer(false);
this.boxIndexBuffer.uploadBuffer(solidIndexBuffer, EDhApiGpuUploadMethod.DATA, BOX_INDICES.length * Integer.BYTES, GL32.GL_STATIC_DRAW);
this.boxIndexBuffer.bind();
MemoryUtil.memFree(solidIndexBuffer);
}
private void addGenericDebugObjects()
{
@@ -418,7 +419,7 @@ public class GlGenericObjectRenderer implements IDhGenericRenderer
this.init();
ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeGenericRenderSetupEvent.class, renderEventParam);
ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeGenericRenderSetupEvent.class, renderEventParam.apiCopy);
boolean renderWireframe = Config.Client.Advanced.Debugging.renderWireframe.get();
@@ -449,8 +450,6 @@ public class GlGenericObjectRenderer implements IDhGenericRenderer
this.boxIndexBuffer.bind();
Vec3d camPos = MC_RENDER.getCameraExactPosition();
// rendering //
@@ -482,7 +481,8 @@ public class GlGenericObjectRenderer implements IDhGenericRenderer
}
// 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)
{
continue;
@@ -510,11 +510,11 @@ public class GlGenericObjectRenderer implements IDhGenericRenderer
{
if (this.instancedRenderingAvailable)
{
this.renderBoxGroupInstanced(shaderProgram, renderEventParam, boxGroup, camPos, profiler);
this.renderBoxGroupInstanced(shaderProgram, renderEventParam, boxGroup, renderEventParam.exactCameraPosition, profiler);
}
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");
ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeGenericRenderCleanupEvent.class, renderEventParam);
ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeGenericRenderCleanupEvent.class, renderEventParam.apiCopy);
if (renderWireframe)
{
@@ -553,7 +553,7 @@ public class GlGenericObjectRenderer implements IDhGenericRenderer
private void renderBoxGroupInstanced(
IDhApiGenericObjectShaderProgram shaderProgram, DhApiRenderParam renderEventParam,
RenderableBoxGroup boxGroup, Vec3d camPos,
RenderableBoxGroup boxGroup, DhVec3d camPos,
IProfilerWrapper profiler)
{
try (IProfilerWrapper.IProfileBlock render_profile = profiler.push("vertex setup"))
@@ -654,7 +654,7 @@ public class GlGenericObjectRenderer implements IDhGenericRenderer
private void renderBoxGroupDirect(
IDhApiGenericObjectShaderProgram shaderProgram,
DhApiRenderParam renderEventParam,
RenderableBoxGroup boxGroup, Vec3d camPos,
RenderableBoxGroup boxGroup, DhVec3d camPos,
IProfilerWrapper profiler)
{
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.wrappers.misc.LightMapWrapper;
import com.seibel.distanthorizons.core.util.LodUtil;
import com.seibel.distanthorizons.core.util.math.Mat4f;
import com.seibel.distanthorizons.core.util.math.Vec3f;
import com.seibel.distanthorizons.core.util.math.DhMat4f;
import com.seibel.distanthorizons.core.util.math.DhVec3f;
public class GlGenericObjectShaderProgram extends GlShaderProgram implements IDhApiGenericObjectShaderProgram
{
@@ -123,7 +123,7 @@ public class GlGenericObjectShaderProgram extends GlShaderProgram implements IDh
DhApiVec3d camPos
)
{
Mat4f projectionMvmMatrix = new Mat4f(renderParameters.dhProjectionMatrix);
DhMat4f projectionMvmMatrix = new DhMat4f(renderParameters.dhProjectionMatrix);
projectionMvmMatrix.multiply(renderParameters.dhModelViewMatrix);
super.bind();
@@ -138,7 +138,7 @@ public class GlGenericObjectShaderProgram extends GlShaderProgram implements IDh
LodUtil.getChunkPosFromDouble(boxGroup.getOriginBlockPos().z)
));
this.setUniform(this.instancedShaderOffsetSubChunkUniform,
new Vec3f(
new DhVec3f(
LodUtil.getSubChunkPosFromDouble(boxGroup.getOriginBlockPos().x),
LodUtil.getSubChunkPosFromDouble(boxGroup.getOriginBlockPos().y),
LodUtil.getSubChunkPosFromDouble(boxGroup.getOriginBlockPos().z)
@@ -151,7 +151,7 @@ public class GlGenericObjectShaderProgram extends GlShaderProgram implements IDh
LodUtil.getChunkPosFromDouble(camPos.z)
));
this.setUniform(this.instancedShaderCameraSubChunkPosUniform,
new Vec3f(
new DhVec3f(
LodUtil.getSubChunkPosFromDouble(camPos.x),
LodUtil.getSubChunkPosFromDouble(camPos.y),
LodUtil.getSubChunkPosFromDouble(camPos.z)
@@ -201,14 +201,14 @@ public class GlGenericObjectShaderProgram extends GlShaderProgram implements IDh
IDhApiRenderableBoxGroup boxGroup, DhApiRenderableBox box,
DhApiVec3d camPos)
{
Mat4f projectionMvmMatrix = new Mat4f(renderParameters.dhProjectionMatrix);
DhMat4f projectionMvmMatrix = new DhMat4f(renderParameters.dhProjectionMatrix);
projectionMvmMatrix.multiply(renderParameters.dhModelViewMatrix);
Mat4f boxTransform = Mat4f.createTranslateMatrix(
DhMat4f boxTransform = DhMat4f.createTranslateMatrix(
(float) (box.minPos.x + boxGroup.getOriginBlockPos().x - camPos.x),
(float) (box.minPos.y + boxGroup.getOriginBlockPos().y - camPos.y),
(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.y - box.minPos.y),
(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.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.types.ConfigEntry;
import com.seibel.distanthorizons.core.dependencyInjection.ModAccessorInjector;
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
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.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IIrisAccessor;
import com.seibel.distanthorizons.core.wrapperInterfaces.render.AbstractDhRenderApiDefinition;
import com.seibel.distanthorizons.coreapi.ModInfo;
import org.lwjgl.glfw.GLFW;
import org.lwjgl.opengl.GL;
@@ -51,6 +52,9 @@ import java.util.concurrent.ConcurrentHashMap;
public class GLProxy
{
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;
static
@@ -126,13 +130,22 @@ public class GLProxy
private GLProxy() throws IllegalStateException
{
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
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) + "].");
@@ -9,9 +9,7 @@ import com.seibel.distanthorizons.core.wrapperInterfaces.render.objects.ILodCont
*/
public class GlDummyUniformData implements ILodContainerUniformBufferWrapper
{
@Override public void createUniformData(LodBufferContainer bufferContainer) { }
@Override public void tryUpload() { }
@Override public void upload() { }
@Override public void tryUpload(LodBufferContainer bufferContainer) { }
@Override public void close() { }
}
@@ -31,7 +31,6 @@ import com.seibel.distanthorizons.core.wrapperInterfaces.render.objects.IVertexB
import org.lwjgl.opengl.GL32;
import com.seibel.distanthorizons.api.enums.config.EDhApiGpuUploadMethod;
import org.lwjgl.system.MemoryUtil;
/**
* This is a container for a OpenGL
@@ -87,7 +86,6 @@ public class GLVertexBuffer extends GLBuffer implements IVertexBufferWrapper
ByteBuffer buffer = IndexBufferBuilder.createBuffer(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.common.render.openGl.glObject.enums.GLEnums;
import com.seibel.distanthorizons.core.dataObjects.render.bufferBuilding.IndexBufferBuilder;
import com.seibel.distanthorizons.core.logging.DhLogger;
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import org.lwjgl.opengl.GL32;
import org.lwjgl.system.MemoryUtil;
import java.nio.ByteBuffer;
@@ -22,12 +22,13 @@ package com.seibel.distanthorizons.common.render.openGl.glObject.shader;
import java.awt.Color;
import java.nio.FloatBuffer;
import com.seibel.distanthorizons.api.objects.math.DhApiMat4f;
import com.seibel.distanthorizons.api.objects.math.DhApiVec3i;
import org.lwjgl.opengl.GL32;
import org.lwjgl.system.MemoryStack;
import com.seibel.distanthorizons.core.util.math.Mat4f;
import com.seibel.distanthorizons.core.util.math.Vec3f;
import com.seibel.distanthorizons.core.util.math.DhMat4f;
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); } }
/** Requires a bound ShaderProgram. */
public void setUniform(int location, Vec3f value) { GL32.glUniform3f(location, value.x, value.y, value.z); }
/** @see GlShaderProgram#setUniform(int, Vec3f) */
public void trySetUniform(int location, Vec3f value) { if (location != -1) { this.setUniform(location, value); } }
public void setUniform(int location, DhVec3f value) { GL32.glUniform3f(location, value.x, value.y, value.z); }
/** @see GlShaderProgram#setUniform(int, DhVec3f) */
public void trySetUniform(int location, DhVec3f value) { if (location != -1) { this.setUniform(location, value); } }
/** Requires a bound ShaderProgram. */
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); } }
/** Requires a bound ShaderProgram. */
public void setUniform(int location, Mat4f value)
public void setUniform(int location, DhApiMat4f value)
{
try (MemoryStack stack = MemoryStack.stackPush())
{
FloatBuffer buffer = stack.mallocFloat(4 * 4);
value.store(buffer);
FloatBuffer buffer = stack.mallocFloat(16);
storeMatrixInBuffer(value, buffer);
GL32.glUniformMatrix4fv(location, false, buffer);
}
}
/** @see GlShaderProgram#setUniform(int, Mat4f) */
public void trySetUniform(int location, Mat4f value) { if (location != -1) { this.setUniform(location, value); } }
private static void storeMatrixInBuffer(DhApiMat4f matrix, FloatBuffer floatBuffer)
{
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>
@@ -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.GlVertexPointer;
import org.lwjgl.opengl.GL32;
import org.lwjgl.system.MemoryUtil;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
/**
* Renders a full-screen textured quad to the screen.
@@ -76,14 +76,14 @@ public class GlScreenQuad
}
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.rewind();
this.boxBuffer = new GLVertexBuffer(false);
this.boxBuffer.bind();
this.boxBuffer.uploadBuffer(buffer, BOX_VERTICES.length, EDhApiGpuUploadMethod.DATA, BOX_VERTICES.length * Float.BYTES);
MemoryUtil.memFree(buffer);
}
//endregion
@@ -132,7 +132,7 @@ public class GlDhApplyShader extends GlAbstractShaderRenderer
}
private void renderToMcTexture()
{
int targetColorTextureId = MC_RENDER.getColorTextureId();
int targetColorTextureId = MC_RENDER.getGlColorTextureId();
if (targetColorTextureId == -1)
{
return;
@@ -136,7 +136,7 @@ public class GlDhFarFadeRenderer implements IDhFarFadeRenderer
GlDhFarFadeShader.INSTANCE.frameBuffer = this.fadeFramebuffer;
GlDhFarFadeShader.INSTANCE.setProjectionMatrix(renderParams.mcModelViewMatrix, renderParams.mcProjectionMatrix);
GlDhFarFadeShader.INSTANCE.setProjectionMatrix(renderParams);
GlDhFarFadeShader.INSTANCE.render(renderParams);
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.core.render.RenderParams;
import com.seibel.distanthorizons.core.util.RenderUtil;
import com.seibel.distanthorizons.core.util.math.Mat4f;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
import org.lwjgl.opengl.GL32;
@@ -42,7 +41,7 @@ public class GlDhFarFadeShader extends GlAbstractShaderRenderer
public int frameBuffer = -1;
private Mat4f inverseDhMvmProjMatrix;
private DhApiMat4f inverseDhMvmProjMatrix;
// 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);
Mat4f dhModelViewMatrix = RenderUtil.createLodModelViewMatrix(mcModelViewMatrix);
Mat4f inverseDhModelViewProjectionMatrix = new Mat4f(dhProjectionMatrix);
inverseDhModelViewProjectionMatrix.multiply(dhModelViewMatrix);
inverseDhModelViewProjectionMatrix.invert();
this.inverseDhMvmProjMatrix = inverseDhModelViewProjectionMatrix;
this.inverseDhMvmProjMatrix = renderParams.dhInverseMvmProjectionMatrix;
}
@@ -153,7 +146,7 @@ public class GlDhFarFadeShader extends GlAbstractShaderRenderer
GL32.glUniform1i(this.uDhDepthTexture, 0);
GLMC.glActiveTexture(GL32.GL_TEXTURE1);
GLMC.glBindTexture(MC_RENDER.getColorTextureId());
GLMC.glBindTexture(MC_RENDER.getGlColorTextureId());
GL32.glUniform1i(this.uMcColorTexture, 1);
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.core.render.RenderParams;
import com.seibel.distanthorizons.core.util.RenderUtil;
import com.seibel.distanthorizons.core.util.math.Mat4f;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
import org.lwjgl.opengl.GL32;
@@ -43,8 +42,8 @@ public class GlDhVanillaFadeShader extends GlAbstractShaderRenderer
public int frameBuffer = -1;
private Mat4f inverseMcMvmProjMatrix;
private Mat4f inverseDhMvmProjMatrix;
private DhApiMat4f inverseMcMvmProjMatrix;
private DhApiMat4f inverseDhMvmProjMatrix;
private float levelMaxHeight;
@@ -136,21 +135,10 @@ public class GlDhVanillaFadeShader extends GlAbstractShaderRenderer
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);
inverseMcModelViewProjectionMatrix.multiply(mcModelViewMatrix);
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;
this.inverseMcMvmProjMatrix = renderParams.mcInverseMvmProjectionMatrix;
this.inverseDhMvmProjMatrix = renderParams.dhInverseMvmProjectionMatrix;
}
public void setLevelMaxHeight(int levelMaxHeight) { this.levelMaxHeight = levelMaxHeight; }
@@ -185,7 +173,7 @@ public class GlDhVanillaFadeShader extends GlAbstractShaderRenderer
GLMC.disableBlend();
GLMC.glActiveTexture(GL32.GL_TEXTURE0);
GLMC.glBindTexture(MC_RENDER.getDepthTextureId());
GLMC.glBindTexture(MC_RENDER.getGlDepthTextureId());
GL32.glUniform1i(this.uMcDepthTexture, 0);
GLMC.glActiveTexture(GL32.GL_TEXTURE1);
@@ -193,7 +181,7 @@ public class GlDhVanillaFadeShader extends GlAbstractShaderRenderer
GL32.glUniform1i(this.uDhDepthTexture, 1);
GLMC.glActiveTexture(GL32.GL_TEXTURE2);
GLMC.glBindTexture(MC_RENDER.getColorTextureId());
GLMC.glBindTexture(MC_RENDER.getGlColorTextureId());
GL32.glUniform1i(this.uCombinedMcDhColorTexture, 2);
GLMC.glActiveTexture(GL32.GL_TEXTURE3);
@@ -108,7 +108,7 @@ public class GlVanillaFadeRenderer implements IDhVanillaFadeRenderer
}
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.setProjectionMatrix(renderParams.mcModelViewMatrix, renderParams.mcProjectionMatrix);
GlDhVanillaFadeShader.INSTANCE.setProjectionMatrix(renderParams);
GlDhVanillaFadeShader.INSTANCE.setLevelMaxHeight(renderParams.clientLevelWrapper.getMaxHeight());
GlDhVanillaFadeShader.INSTANCE.render(renderParams);
@@ -19,6 +19,7 @@
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.wrappers.minecraft.MinecraftGLWrapper;
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
@@ -108,7 +109,7 @@ public class GlDhFogRenderer implements IDhFogRenderer
//region
@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
try (GLState state = new GLState())
@@ -126,7 +127,7 @@ public class GlDhFogRenderer implements IDhFogRenderer
}
GlDhFogShader.INSTANCE.frameBuffer = this.fogFramebuffer;
GlDhFogShader.INSTANCE.setProjectionMatrix(renderParams.dhMvmProjMatrix);
GlDhFogShader.INSTANCE.prepUniformObjects(renderParams.dhMvmProjMatrix, fogRenderParams);
GlDhFogShader.INSTANCE.render(renderParams);
GlDhFogApplyShader.INSTANCE.fogTexture = this.fogTexture;
@@ -19,9 +19,9 @@
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.EDhApiHeightFogMixMode;
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiFogRenderParam;
import com.seibel.distanthorizons.api.objects.math.DhApiMat4f;
import com.seibel.distanthorizons.common.render.openGl.GlDhMetaRenderer;
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.util.LodUtil;
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 org.lwjgl.opengl.GL32;
import java.awt.*;
public class GlDhFogShader extends GlAbstractShaderRenderer
{
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 IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class);
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;
if (this.inverseMvmProjMatrix != null)
{
this.shader.setUniform(this.uInvMvmProj, this.inverseMvmProjMatrix);
}
this.shader.setUniform(this.uInvMvmProj, this.inverseMvmProjMatrix);
// 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.uFogVerticalScale, 1.f / MC.getWrappedClientLevel().getMaxHeight());
// only used for debugging
this.shader.setUniform(this.uFogDebugMode, 0); // 1 = render everything with fog color // 7 = use debug rendering
this.shader.setUniform(this.uFogFalloffType, Config.Client.Advanced.Graphics.Fog.farFogFalloff.get().value);
this.shader.setUniform(this.uFogVerticalScale, 1.f / renderParams.clientLevelWrapper.getMaxHeight());
this.shader.setUniform(this.uFogDebugMode, 0); // 0 = normal // 1 = render everything with fog color // 7 = use debug rendering
this.shader.setUniform(this.uFogFalloffType, this.fogRenderParams.getFarFogFalloff().value);
// 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;
}
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);
this.shader.setUniform(this.uFarFogStart, this.fogRenderParams.getFarFogStartPercent());
this.shader.setUniform(this.uFarFogLength, this.fogRenderParams.getFarFogEndPercent() - this.fogRenderParams.getFarFogStartPercent());
this.shader.setUniform(this.uFarFogMin, this.fogRenderParams.getFarFogMinThickness());
this.shader.setUniform(this.uFarFogRange, this.fogRenderParams.getFarFogMaxThickness() - this.fogRenderParams.getFarFogMinThickness());
this.shader.setUniform(this.uFarFogDensity, this.fogRenderParams.getFarFogDensity());
// height config
EDhApiHeightFogMixMode heightFogMixingMode = Config.Client.Advanced.Graphics.Fog.HeightFog.heightFogMixMode.get();
boolean heightFogEnabled = heightFogMixingMode != EDhApiHeightFogMixMode.SPHERICAL && heightFogMixingMode != EDhApiHeightFogMixMode.CYLINDRICAL;
EDhApiHeightFogMixMode heightFogMixingMode = this.fogRenderParams.getHeightFogMixingMode();
boolean heightFogEnabled =
heightFogMixingMode != EDhApiHeightFogMixMode.SPHERICAL
&& heightFogMixingMode != EDhApiHeightFogMixMode.CYLINDRICAL;
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();
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();
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.uHeightFogStart, this.fogRenderParams.getHeightFogStartPercent());
this.shader.setUniform(this.uHeightFogLength, this.fogRenderParams.getHeightFogEndPercent() - this.fogRenderParams.getHeightFogStartPercent());
this.shader.setUniform(this.uHeightFogMin, this.fogRenderParams.getFarFogMinThickness());
this.shader.setUniform(this.uHeightFogRange, this.fogRenderParams.getFarFogMaxThickness() - this.fogRenderParams.getFarFogMinThickness());
this.shader.setUniform(this.uHeightFogDensity, this.fogRenderParams.getFarFogDensity());
this.shader.setUniform(this.uHeightFogEnabled, heightFogEnabled);
this.shader.setUniform(this.uHeightFogFalloffType, Config.Client.Advanced.Graphics.Fog.HeightFog.heightFogFalloff.get().value);
this.shader.setUniform(this.uHeightFogBaseHeight, Config.Client.Advanced.Graphics.Fog.HeightFog.heightFogBaseHeight.get());
this.shader.setUniform(this.uHeightBasedOnCamera, heightFogCameraDirection.basedOnCamera);
this.shader.setUniform(this.uHeightFogAppliesUp, heightFogCameraDirection.fogAppliesUp);
this.shader.setUniform(this.uHeightFogAppliesDown, heightFogCameraDirection.fogAppliesDown);
this.shader.setUniform(this.uHeightFogFalloffType, this.fogRenderParams.getHeightFogFalloff().value);
this.shader.setUniform(this.uHeightFogBaseHeight, this.fogRenderParams.getHeightFogBaseHeight());
this.shader.setUniform(this.uHeightBasedOnCamera, heightFogDirection.basedOnCamera);
this.shader.setUniform(this.uHeightFogAppliesUp, heightFogDirection.fogAppliesUp);
this.shader.setUniform(this.uHeightFogAppliesDown, heightFogDirection.fogAppliesDown);
this.shader.setUniform(this.uUseSphericalFog, useSphericalFog);
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.fogRenderParams = fogRenderParams;
}
//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.render.openGl.util.GlAbstractShaderRenderer;
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;
/**
@@ -45,8 +45,8 @@ public class GlDhSSAOShader extends GlAbstractShaderRenderer
public int frameBuffer;
private Mat4f projection;
private Mat4f invertedProjection;
private DhMat4f projection;
private DhMat4f invertedProjection;
// uniforms
@@ -95,9 +95,9 @@ public class GlDhSSAOShader extends GlAbstractShaderRenderer
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();
}
@@ -23,9 +23,9 @@ import com.seibel.distanthorizons.core.logging.DhLogger;
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import com.seibel.distanthorizons.core.render.RenderParams;
import com.seibel.distanthorizons.core.util.RenderUtil;
import com.seibel.distanthorizons.core.util.math.Mat4f;
import com.seibel.distanthorizons.core.util.math.Vec3d;
import com.seibel.distanthorizons.core.util.math.Vec3f;
import com.seibel.distanthorizons.core.util.math.DhMat4f;
import com.seibel.distanthorizons.core.util.math.DhVec3d;
import com.seibel.distanthorizons.core.util.math.DhVec3f;
import com.seibel.distanthorizons.core.util.objects.SortedArraySet;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IProfilerWrapper;
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 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;
@@ -194,7 +199,7 @@ public class GlDhTerrainShaderProgram extends GlShaderProgram implements IDhApiS
@Override
public void fillUniformData(DhApiRenderParam renderParameters)
{
Mat4f combinedMatrix = new Mat4f(renderParameters.dhProjectionMatrix);
DhMat4f combinedMatrix = new DhMat4f(renderParameters.dhProjectionMatrix);
combinedMatrix.multiply(renderParameters.dhModelViewMatrix);
super.bind();
@@ -241,7 +246,7 @@ public class GlDhTerrainShaderProgram extends GlShaderProgram implements IDhApiS
}
@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
public int getId() { return this.id; }
@@ -289,9 +294,13 @@ public class GlDhTerrainShaderProgram extends GlShaderProgram implements IDhApiS
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
// 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
{
Vec3d camPos = renderEventParam.exactCameraPosition;
Vec3f modelPos = new Vec3f(
DhVec3d camPos = renderEventParam.exactCameraPosition;
MODEL_POS.set(
(float) (bufferContainer.minCornerBlockPos.getX() - camPos.x),
(float) (bufferContainer.minCornerBlockPos.getY() - camPos.y),
(float) (bufferContainer.minCornerBlockPos.getZ() - camPos.z));
BEFORE_BUFFER_RENDER_EVENT_PARAM.update(renderEventParam, MODEL_POS);
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);
@@ -19,11 +19,12 @@
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.common.render.blaze.BlazeDhRenderApiDefinition;
import com.seibel.distanthorizons.common.render.openGl.GlDhRenderApiDefinition;
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.common.wrappers.gui.classicConfig.ClassicConfigGUI;
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(IVersionConstants.class, VersionConstants.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);
}
@@ -94,25 +95,25 @@ public class DependencySetup
EDhApiRenderApi renderingApiEnum = Config.Client.Advanced.Graphics.Experimental.renderingApi.get();
if (renderingApiEnum == EDhApiRenderApi.AUTO)
EDhApiRenderingEngine renderingApiEnum = Config.Client.Advanced.Graphics.Experimental.renderingEngine.get();
if (renderingApiEnum == EDhApiRenderingEngine.AUTO)
{
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;
AbstractDhRenderApiDefinition renderDefinition;
if (renderingApiEnum == EDhApiRenderApi.OPEN_GL)
if (renderingApiEnum == EDhApiRenderingEngine.OPEN_GL)
{
validApi = true;
renderDefinition = new GlDhRenderApiDefinition();
}
else if (renderingApiEnum == EDhApiRenderApi.BLAZE_3D)
else if (renderingApiEnum == EDhApiRenderingEngine.BLAZE_3D)
{
#if MC_VER <= MC_1_21_10
validApi = false;
@@ -133,14 +134,24 @@ public class DependencySetup
// crash if an invalid API is set
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);
Config.Client.Advanced.Graphics.Experimental.renderingApi.set(EDhApiRenderApi.AUTO);
throw new IllegalStateException(message);
}
renderDefinition.bindRenderers();
LOGGER.info("DH Rendering successfully bound to: ["+renderDefinition.getEngineName()+"]...");
}
@@ -24,7 +24,7 @@ import java.nio.FloatBuffer;
import com.seibel.distanthorizons.core.enums.EDhDirection;
import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos;
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;
@@ -53,7 +53,7 @@ public class McObjectConverter
//region
/** 4x4 float matrix converter */
public static Mat4f Convert(
public static DhMat4f Convert(
#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
@@ -63,7 +63,7 @@ public class McObjectConverter
{
FloatBuffer buffer = FloatBuffer.allocate(16);
storeMatrix(mcMatrix, buffer);
Mat4f matrix = new Mat4f(buffer);
DhMat4f matrix = new DhMat4f(buffer);
#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
#endif
@@ -19,7 +19,7 @@
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;
public class VersionConstants implements IVersionConstants
@@ -98,6 +98,8 @@ public class VersionConstants implements IVersionConstants
return "1.21.11";
#elif MC_VER == MC_26_1_2
return "26.1.2";
#elif MC_VER == MC_26_2_0
return "26.2.0";
#else
ERROR MC version constant missing
#endif
@@ -105,12 +107,12 @@ public class VersionConstants implements IVersionConstants
}
@Override
public EDhApiRenderApi getDefaultRenderingApi()
public EDhApiRenderingEngine getDefaultRenderingEngine()
{
#if MC_VER <= MC_1_21_11
return EDhApiRenderApi.OPEN_GL;
return EDhApiRenderingEngine.OPEN_GL;
#else
return EDhApiRenderApi.BLAZE_3D;
return EDhApiRenderingEngine.BLAZE_3D;
#endif
}
@@ -345,9 +345,9 @@ public abstract class AbstractDhTintGetter implements BlockAndTintGetter
//===========//
// set color //
//===========//
//=================//
// static handlers //
//=================//
//region
/**
@@ -360,6 +360,8 @@ public abstract class AbstractDhTintGetter implements BlockAndTintGetter
COLOR_BY_BLOCK_BIOME_PAIR.put(pair, colorInt);
}
public static void clear() { COLOR_BY_BLOCK_BIOME_PAIR.clear(); }
//endregion
@@ -309,8 +309,21 @@ public class ClientBlockStateColorCache
for (int i = 0; i < COLOR_RESOLUTION_DIRECTION_ORDER.length; i++)
{
direction = COLOR_RESOLUTION_DIRECTION_ORDER[i];
quads = this.getQuadsForDirection(direction);
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
@@ -328,7 +341,15 @@ public class ClientBlockStateColorCache
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
@@ -406,6 +427,23 @@ public class ClientBlockStateColorCache
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
{
RESOLVE_LOCK.unlock();
@@ -413,12 +451,16 @@ public class ClientBlockStateColorCache
}
@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
#if MC_VER <= MC_1_12_2
private List<BakedQuad> getQuadsForDirection(@Nullable EnumFacing direction)
private List<BakedQuad> getQuadsForDirection(@Nullable EnumFacing direction) throws Exception
#else
private List<BakedQuad> getQuadsForDirection(@Nullable Direction direction)
private List<BakedQuad> getQuadsForDirection(@Nullable Direction direction) throws Exception
#endif
{
#if MC_VER <= MC_1_12_2
@@ -427,6 +469,13 @@ public class ClientBlockStateColorCache
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,
// otherwise the color will use the side, which isn't as accurate
#if MC_VER <= MC_1_12_2
@@ -441,6 +490,31 @@ public class ClientBlockStateColorCache
}
#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;
#if MC_VER <= MC_1_12_2
@@ -480,6 +554,8 @@ public class ClientBlockStateColorCache
}
#endif
//endregion
return quads;
}
@@ -621,6 +697,15 @@ public class ClientBlockStateColorCache
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(
#if MC_VER <= MC_1_12_2
Minecraft.getMinecraft().getBlockRendererDispatcher().getBlockModelShapes().getTexture(this.blockState),
@@ -641,7 +726,9 @@ public class ClientBlockStateColorCache
//===============//
//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
int tintColor = ClientBlockStateColorCache.INVALID_COLOR;
@@ -805,14 +892,17 @@ public class ClientBlockStateColorCache
}
// only fire an API event if needed
// (this is done to reduce GC pressure and speed up color getting)
if (this.blockStateWrapper.allowApiColorOverride())
// only fire the API event if allowed
// (done to prevent infinite loops if called during by another color resolution event)
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();
eventParam.update(
this.clientLevelWrapper,
this.blockStateWrapper, returnColor,
this.clientLevelWrapper, fullDataSource,
this.blockStateWrapper, biomeWrapper, returnColor,
blockPos.getX(), blockPos.getY(), blockPos.getZ()
);
ApiEventInjector.INSTANCE.fireAllEvents(DhApiBlockColorOverrideEvent.class, eventParam);
@@ -828,6 +918,23 @@ public class ClientBlockStateColorCache
//=========//
// cleanup //
//=========//
//region
public static void clearCachedTints()
{
#if MC_VER <= MC_1_12_2
#else
AbstractDhTintGetter.clear();
#endif
}
//endregion
//================//
// helper classes //
//================//
@@ -731,16 +731,25 @@ public class ChunkWrapper implements IChunkWrapper
//1.12.2 doesn't store lights we must bruteforce it
#if MC_VER <= MC_1_12_2
for (int x = 0; x < 16; x++)
{
for (int z = 0; z < 16; z++)
for (ExtendedBlockStorage section : this.chunk.getBlockStorageArray()) {
if (section == null || section.isEmpty())
{
for (int y = 0; y < 256; y++)
continue;
}
int baseY = section.getYLocation();
for (int x = 0; x < 16; x++)
{
for (int z = 0; z < 16; z++)
{
IBlockState blockState = this.chunk.getBlockState(x, y, z);
if (blockState.getLightValue() > 0)
for (int y = 0; y < 16; y++)
{
this.blockLightPosList.add(new DhBlockPos(this.chunk.getPos().getXStart() + x, y, this.chunk.getPos().getZStart() + z));
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));
}
}
}
}
@@ -0,0 +1,38 @@
package com.seibel.distanthorizons.common.wrappers.gui;
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;
#endif
import java.util.Objects;
public class DhScreenUtil
{
//================//
// helper methods //
//================//
//region
#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_1_12_2
Objects.requireNonNull(Minecraft.getMinecraft()).displayGuiScreen(screen);
#elif MC_VER <= MC_26_1_2
Objects.requireNonNull(Minecraft.getInstance()).setScreen(screen);
#else
Objects.requireNonNull(Minecraft.getInstance()).setScreenAndShow(screen);
#endif
}
//endregion
}
@@ -16,8 +16,14 @@ public class LangWrapper implements ILangWrapper
{
#if MC_VER <= MC_1_12_2
return I18n.hasKey(str);
#else
#elif MC_VER <= MC_26_1_2
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
}
@@ -43,6 +43,13 @@ public class MinecraftScreen
return new ConfigScreenRenderer(parent, screen, translationName);
}
//=========//
// screens //
//=========//
//region
private static class ConfigScreenRenderer extends DhScreen
{
#if MC_VER <= MC_1_12_2
@@ -231,11 +238,7 @@ public class MinecraftScreen
#endif
{
this.screen.onClose(); // Close our screen
#if MC_VER <= MC_1_12_2
Objects.requireNonNull(this.mc).displayGuiScreen(this.parent); // Goto the parent screen
#else
Objects.requireNonNull(this.minecraft).setScreen(this.parent); // Goto the parent screen
#endif
DhScreenUtil.setScreen(this.parent); // Goto the parent screen
}
#if MC_VER > MC_1_12_2
@@ -280,4 +283,8 @@ public class MinecraftScreen
#endif
}
//endregion
}
@@ -155,16 +155,21 @@ public class TexturedButtonWidget extends Button
@Override
public void drawButton(Minecraft mc, int mouseX, int mouseY, float partialTicks) {
if (this.visible) {
//Render vanilla background
mc.getTextureManager().bindTexture(BUTTON_TEXTURES);
GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
this.hovered = mouseX >= this.x && mouseY >= this.y && mouseX < this.x + this.width && mouseY < this.y + this.height;
int i = this.getHoverState(this.hovered);
GlStateManager.enableBlend();
GlStateManager.tryBlendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ZERO);
GlStateManager.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA);
this.drawTexturedModalRect(this.x, this.y, 0, 46 + i * 20, this.width / 2, this.height);
this.drawTexturedModalRect(this.x + this.width / 2, this.y, 200 - this.width / 2, 46 + i * 20, this.width / 2, this.height);
GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
if (this.renderBackground)
{
//Render vanilla background
mc.getTextureManager().bindTexture(BUTTON_TEXTURES);
this.drawTexturedModalRect(this.x, this.y, 0, 46 + i * 20, this.width / 2, this.height);
this.drawTexturedModalRect(this.x + this.width / 2, this.y, 200 - this.width / 2, 46 + i * 20, this.width / 2, this.height);
}
//Render DH texture
mc.getTextureManager().bindTexture(textureResourceLocation);
@@ -12,19 +12,13 @@ import java.util.function.Predicate;
import java.util.regex.Pattern;
import com.seibel.distanthorizons.api.enums.config.DisallowSelectingViaConfigGui;
import com.seibel.distanthorizons.common.wrappers.gui.DhScreen;
import com.seibel.distanthorizons.common.wrappers.gui.GuiHelper;
import com.seibel.distanthorizons.common.wrappers.gui.TexturedButtonWidget;
import com.seibel.distanthorizons.common.wrappers.gui.*;
import com.seibel.distanthorizons.common.wrappers.gui.config.ConfigGuiInfo;
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftClientWrapper;
import com.seibel.distanthorizons.core.config.Config;
import com.seibel.distanthorizons.core.config.ConfigHandler;
import com.seibel.distanthorizons.core.config.types.*;
#if MC_VER <= MC_1_12_2
import com.seibel.distanthorizons.common.wrappers.gui.OnPressed;
#else
import com.seibel.distanthorizons.common.wrappers.gui.updater.ChangelogScreen;
#endif
import com.seibel.distanthorizons.core.config.types.enums.EConfigCommentTextPosition;
import com.seibel.distanthorizons.core.config.types.enums.EConfigValidity;
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
@@ -95,6 +89,10 @@ class DhConfigScreen extends DhScreen
private static final MinecraftClientWrapper MC_CLIENT = MinecraftClientWrapper.INSTANCE;
#if MC_VER <= MC_1_12_2
private static final int changelogButton_id = 101;
#endif
#if MC_VER <= MC_1_12_2
private final GuiScreen parent;
#else
@@ -141,7 +139,7 @@ class DhConfigScreen extends DhScreen
// menu UI lifecycle //
//===================//
//region
@Override
#if MC_VER <= MC_1_12_2
public void updateScreen() { super.updateScreen(); }
@@ -150,9 +148,9 @@ class DhConfigScreen extends DhScreen
#endif
//endregion
//==================//
// menu UI creation //
//==================//
@@ -176,13 +174,15 @@ class DhConfigScreen extends DhScreen
ConfigHandler.INSTANCE.configFileHandler.loadFromFile();
}
#if MC_VER > MC_1_12_2
// Changelog button
if (Config.Client.Advanced.AutoUpdater.enableAutoUpdater.get()
// we only have changelogs for stable builds
&& !ModInfo.IS_DEV_BUILD)
{
this.addBtn(new TexturedButtonWidget(
#if MC_VER <= MC_1_12_2
changelogButton_id,
#endif
// Where the button is on the screen
this.width - 28, this.height - 28,
// Width and height of the button
@@ -200,22 +200,27 @@ class DhConfigScreen extends DhScreen
#endif
20, 20,
// Create the button and tell it where to go
#if MC_VER > MC_1_12_2
(buttonWidget) -> {
ChangelogScreen changelogScreen = new ChangelogScreen(this);
if (changelogScreen.usable)
{
Objects.requireNonNull(this.minecraft).setScreen(changelogScreen);
DhScreenUtil.setScreen(changelogScreen);
}
else
{
LOGGER.warn("Changelog was not able to open");
}
},
#endif
// Add a title to the button
#if MC_VER <= MC_1_12_2
Translatable(ModInfo.ID + ".updater.title").getFormattedText()
#else
Translatable(ModInfo.ID + ".updater.title")
#endif
));
}
#endif
// back button
@@ -225,11 +230,7 @@ class DhConfigScreen extends DhScreen
(button) ->
{
ConfigHandler.INSTANCE.configFileHandler.loadFromFile();
#if MC_VER <= MC_1_12_2
Objects.requireNonNull(this.mc).displayGuiScreen(this.parent);
#else
Objects.requireNonNull(this.minecraft).setScreen(this.parent);
#endif
DhScreenUtil.setScreen(this.parent);
}));
// done/close button
@@ -240,11 +241,7 @@ class DhConfigScreen extends DhScreen
(button) ->
{
ConfigHandler.INSTANCE.configFileHandler.saveToFile();
#if MC_VER <= MC_1_12_2
Objects.requireNonNull(this.mc).displayGuiScreen(this.parent);
#else
Objects.requireNonNull(this.minecraft).setScreen(this.parent);
#endif
DhScreenUtil.setScreen(this.parent);
}));
#if MC_VER <= MC_1_12_2
@@ -447,7 +444,7 @@ class DhConfigScreen extends DhScreen
#else
button.active = !booleanConfigEntry.apiIsOverriding();
#endif
booleanConfigEntry.uiSetWithoutSaving(!booleanConfigEntry.get());
#if MC_VER <= MC_1_12_2
@@ -468,7 +465,7 @@ class DhConfigScreen extends DhScreen
#else
Function<Object, Component> getEnumTranslatableFunc = (value) -> Translatable(TRANSLATION_PREFIX + "enum." + enumClass.getSimpleName() + "." + enumConfigEntry.get().toString());
#endif
configGuiInfo.buttonOptionMap =
#if MC_VER <= MC_1_12_2
new AbstractMap.SimpleEntry<OnPressed, Function<Object, ITextComponent>>(
@@ -565,12 +562,7 @@ class DhConfigScreen extends DhScreen
{
configEntry.uiSetWithoutSaving(configEntry.getDefaultValue());
this.reload = true;
#if MC_VER <= MC_1_12_2
Objects.requireNonNull(this.mc).displayGuiScreen(ClassicConfigGUI.getScreen(this.parent, this.category));
#else
Objects.requireNonNull(this.minecraft).setScreen(this.parent);
#endif
DhScreenUtil.setScreen(this);
};
int resetButtonPosX = this.width
@@ -580,13 +572,13 @@ class DhConfigScreen extends DhScreen
#if MC_VER <= MC_1_12_2 GuiButton #else Button #endif resetButton = MakeBtn(
#if MC_VER <= MC_1_12_2
Translatable("distanthorizons.general.reset").setStyle(new Style().setColor(TextFormatting.RED)),
Translatable("distanthorizons.general.reset").setStyle(new Style().setColor(TextFormatting.RED)),
#else
Translatable("distanthorizons.general.reset").withStyle(ChatFormatting.RED),
#endif
resetButtonPosX, resetButtonPosZ,
ClassicConfigGUI.ConfigScreenConfigs.RESET_BUTTON_WIDTH, ClassicConfigGUI.ConfigScreenConfigs.RESET_BUTTON_HEIGHT,
btnAction);
resetButtonPosX, resetButtonPosZ,
ClassicConfigGUI.ConfigScreenConfigs.RESET_BUTTON_WIDTH, ClassicConfigGUI.ConfigScreenConfigs.RESET_BUTTON_HEIGHT,
btnAction);
if (configEntry.mcVersionOverridePresent())
@@ -619,8 +611,8 @@ class DhConfigScreen extends DhScreen
}
//endregion
//==============//
// option field //
@@ -750,11 +742,7 @@ class DhConfigScreen extends DhScreen
((button) ->
{
ConfigHandler.INSTANCE.configFileHandler.saveToFile();
#if MC_VER <= MC_1_12_2
Objects.requireNonNull(this.mc).displayGuiScreen(ClassicConfigGUI.getScreen(this, configCategory.getDestination()));
#else
Objects.requireNonNull(this.minecraft).setScreen(ClassicConfigGUI.getScreen(this, configCategory.getDestination()));
#endif
DhScreenUtil.setScreen(ClassicConfigGUI.getScreen(this, configCategory.getDestination()));
}));
this.configListWidget.addButton(this, configType, widget, null, null, null);
@@ -859,7 +847,7 @@ class DhConfigScreen extends DhScreen
//endregion
//===========//
// rendering //
@@ -988,7 +976,6 @@ class DhConfigScreen extends DhScreen
unsupportedMcVersion = ((ConfigEntry<?>) configBase).mcVersionOverridePresent();
}
String key = TRANSLATION_PREFIX + (configBase.category.isEmpty() ? "" : configBase.category + ".") + configBase.getName() + ".@tooltip";
if (unsupportedMcVersion)
@@ -1034,6 +1021,24 @@ class DhConfigScreen extends DhScreen
}
#if MC_VER <= MC_1_12_2
@Override
protected void actionPerformed(GuiButton button)
{
super.actionPerformed(button);
if(button.id == changelogButton_id)
{
ChangelogScreen changelogScreen = new ChangelogScreen(this);
if (changelogScreen.usable)
{
DhScreenUtil.setScreen(changelogScreen);
}
else
{
LOGGER.warn("Changelog was not able to open");
}
}
}
@Override
protected void mouseClicked(int mouseX, int mouseY, int mouseButton) throws java.io.IOException
{
@@ -1108,8 +1113,10 @@ class DhConfigScreen extends DhScreen
#endif
{
ConfigHandler.INSTANCE.configFileHandler.saveToFile();
#if MC_VER > MC_1_12_2
Objects.requireNonNull(this.minecraft).setScreen(this.parent);
#if MC_VER <= MC_1_12_2
// Handled by button to avoid recursive loop
#else
DhScreenUtil.setScreen(this.parent);
#endif
ClassicConfigGUI.CONFIG_CORE_INTERFACE.onScreenChangeListenerList.forEach((listener) -> listener.run());
}
@@ -1,6 +1,6 @@
package com.seibel.distanthorizons.common.wrappers.gui.updater;
#if MC_VER > MC_1_12_2
import com.seibel.distanthorizons.common.wrappers.gui.DhScreen;
import com.seibel.distanthorizons.common.wrappers.gui.DhScreenUtil;
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import com.seibel.distanthorizons.core.wrapperInterfaces.IVersionConstants;
@@ -8,19 +8,30 @@ import com.seibel.distanthorizons.coreapi.ModInfo;
import com.seibel.distanthorizons.core.jar.installer.MarkdownFormatter;
import com.seibel.distanthorizons.core.jar.installer.ModrinthGetter;
import net.minecraft.client.Minecraft;
#if MC_VER <= MC_1_12_2
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.Gui;
import net.minecraft.client.gui.GuiListExtended;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.util.text.ITextComponent;
#else
import net.minecraft.client.gui.Font;
import net.minecraft.client.gui.components.AbstractWidget;
import net.minecraft.client.gui.components.ContainerObjectSelectionList;
import net.minecraft.client.gui.components.events.GuiEventListener;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.network.chat.Component;
#endif
import com.seibel.distanthorizons.core.logging.DhLogger;
#if MC_VER >= MC_1_17_1
import net.minecraft.client.gui.narration.NarratableEntry;
#endif
#if MC_VER < MC_1_20_1
#if MC_VER <= MC_1_12_2
#elif MC_VER < MC_1_20_1
import net.minecraft.client.gui.GuiComponent;
import com.mojang.blaze3d.vertex.PoseStack;
#elif MC_VER <= MC_1_21_11
@@ -44,14 +55,22 @@ public class ChangelogScreen extends DhScreen
private static final DhLogger LOGGER = new DhLoggerBuilder().build();
#if MC_VER <= MC_1_12_2
private GuiScreen parent;
#else
private Screen parent;
#endif
private String versionID;
private List<String> changelog;
private TextArea changelogArea;
public boolean usable = false;
#if MC_VER <= MC_1_12_2
public ChangelogScreen(GuiScreen parent)
#else
public ChangelogScreen(Screen parent)
#endif
{
this(parent, null);
@@ -86,7 +105,11 @@ public class ChangelogScreen extends DhScreen
}
}
#if MC_VER <= MC_1_12_2
public ChangelogScreen(GuiScreen parent, String versionID)
#else
public ChangelogScreen(Screen parent, String versionID)
#endif
{
super(Translatable(ModInfo.ID + ".updater.title"));
this.parent = parent;
@@ -142,9 +165,18 @@ public class ChangelogScreen extends DhScreen
@Override
#if MC_VER <= MC_1_12_2
public void initGui()
#else
protected void init()
#endif
{
#if MC_VER <= MC_1_12_2
super.initGui();
#else
super.init();
#endif
if (!this.usable)
{
return;
@@ -153,12 +185,19 @@ public class ChangelogScreen extends DhScreen
this.addBtn( // Close
MakeBtn(Translatable(ModInfo.ID + ".general.back"), 5, this.height - 25, 100, 20, (btn) -> {
#if MC_VER <= MC_1_12_2
DhScreenUtil.setScreen(this.parent);
#else
this.onClose();
#endif
})
);
#if MC_VER <= MC_1_12_2
this.changelogArea = new TextArea(this.mc, this.width * 2, this.height, 32, 32, 10);
#else
this.changelogArea = new TextArea(this.minecraft, this.width * 2, this.height, 32, 32, 10);
#endif
for (int i = 0; i < this.changelog.size(); i++)
{
this.changelogArea.addButton(TextOrLiteral(this.changelog.get(i)));
@@ -168,7 +207,9 @@ public class ChangelogScreen extends DhScreen
}
@Override
#if MC_VER < MC_1_20_1
#if MC_VER <= MC_1_12_2
public void drawScreen(int mouseX, int mouseY, float delta)
#elif MC_VER < MC_1_20_1
public void render(PoseStack matrices, int mouseX, int mouseY, float delta)
#elif MC_VER <= MC_1_21_11
public void render(GuiGraphics matrices, int mouseX, int mouseY, float delta)
@@ -176,7 +217,9 @@ public class ChangelogScreen extends DhScreen
public void extractRenderState(GuiGraphicsExtractor matrices, int mouseX, int mouseY, float delta)
#endif
{
#if MC_VER < MC_1_20_2
#if MC_VER <= MC_1_12_2
this.drawDefaultBackground(); // Render background
#elif MC_VER < MC_1_20_2
this.renderBackground(matrices); // Render background
#elif MC_VER < MC_1_21_6
this.renderBackground(matrices, mouseX, mouseY, delta); // Render background
@@ -200,7 +243,9 @@ public class ChangelogScreen extends DhScreen
// This is a bit of a hack as we cannot scroll on this area
double scrollAmount = ((double) mouseY) / ((double) this.height) * 1.1 * maxScroll;
#if MC_VER == MC_1_16_5 || MC_VER == MC_1_17_1
#if MC_VER <= MC_1_12_2
this.changelogArea.amountScrolled = (float)scrollAmount;
#elif MC_VER == MC_1_16_5 || MC_VER == MC_1_17_1
this.changelogArea.setScrollAmount(scrollAmount);
#elif MC_VER <= MC_1_21_3
this.changelogArea.scrollAmount = scrollAmount;
@@ -208,9 +253,13 @@ public class ChangelogScreen extends DhScreen
this.changelogArea.setScrollAmount(scrollAmount);
#endif
// render order matters, otherwise on 1.20.6+ the blurred background will render on top of the text
#if MC_VER <= MC_1_21_11
// render order matters, otherwise on
// 1.12.2- buttons won't render
// 1.20.6+ the blurred background will render on top of the text
#if MC_VER <= MC_1_12_2
this.changelogArea.drawScreen(mouseX, mouseY, delta); // Render the changelog
super.drawScreen(mouseX, mouseY, delta); // Render the buttons
#elif MC_VER <= MC_1_21_11
super.render(matrices, mouseX, mouseY, delta); // Render the buttons
this.changelogArea.render(matrices, mouseX, mouseY, delta); // Render the changelog
#else
@@ -218,18 +267,45 @@ public class ChangelogScreen extends DhScreen
this.changelogArea.extractRenderState(matrices, mouseX, mouseY, delta); // Render the changelog
#endif
this.DhDrawCenteredString(matrices, this.font, this.title, this.width / 2, 15, 0xFFFFFF); // Render title
// Render title
#if MC_VER <= MC_1_12_2
this.DhDrawCenteredString(this.title, this.width / 2, 15, 0xFFFFFF);
#else
this.DhDrawCenteredString(matrices, this.font, this.title, this.width / 2, 15, 0xFFFFFF);
#endif
}
#if MC_VER <= MC_1_12_2
@Override
public void onGuiClosed()
#else
@Override
public void onClose()
#endif
{
Objects.requireNonNull(this.minecraft).setScreen(this.parent); // Goto the parent screen
// Go to the parent screen
#if MC_VER <= MC_1_12_2
// Handled by button to avoid recursive loop
#else
DhScreenUtil.setScreen(this.parent);
#endif
}
#if MC_VER <= MC_1_12_2
public static class TextArea extends GuiListExtended
#else
public static class TextArea extends ContainerObjectSelectionList<ButtonEntry>
#endif
{
#if MC_VER <= MC_1_12_2
public List<ButtonEntry> children = new ArrayList<>();
#endif
#if MC_VER <= MC_1_12_2
FontRenderer textRenderer;
#else
Font textRenderer;
#endif
public TextArea(Minecraft minecraftClient, int canvasWidth, int canvasHeight, int topMargin, int botMargin, int itemSpacing)
{
@@ -238,63 +314,129 @@ public class ChangelogScreen extends DhScreen
#else
super(minecraftClient, canvasWidth, canvasHeight - (topMargin + botMargin), topMargin, itemSpacing);
#endif
this.centerListVertically = false;
#if MC_VER <= MC_1_12_2
this.textRenderer = minecraftClient.fontRenderer;
#else
this.textRenderer = minecraftClient.font;
#endif
}
#if MC_VER <= MC_1_12_2
public void addButton(ITextComponent text)
#else
public void addButton(Component text)
#endif
{
#if MC_VER <= MC_1_12_2
this.children.add(ButtonEntry.create(text));
#else
this.addEntry(ButtonEntry.create(text));
#endif
}
@Override
#if MC_VER <= MC_1_12_2
public int getListWidth()
#else
public int getRowWidth()
#endif
{
return 10000;
return 10_000;
}
#if MC_VER <= MC_1_12_2
@Override
protected int getSize()
{
return this.children.size();
}
@Override
public IGuiListEntry getListEntry(int index)
{
return this.children.get(index);
}
#endif
}
#if MC_VER <= MC_1_12_2
public static class ButtonEntry implements GuiListExtended.IGuiListEntry
#else
public static class ButtonEntry extends ContainerObjectSelectionList.Entry<ButtonEntry>
#endif
{
#if MC_VER <= MC_1_12_2
private static final FontRenderer textRenderer = Minecraft.getMinecraft().fontRenderer;
#else
private static final Font textRenderer = Minecraft.getInstance().font;
#endif
#if MC_VER <= MC_1_12_2
private final ITextComponent text;
#else
private final Component text;
#endif
#if MC_VER <= MC_1_12_2
private final List<Gui> children = new ArrayList<>();
#else
private final List<AbstractWidget> children = new ArrayList<>();
#endif
#if MC_VER <= MC_1_12_2
private ButtonEntry(ITextComponent text) { this.text = text; }
#else
private ButtonEntry(Component text) { this.text = text; }
#endif
#if MC_VER <= MC_1_12_2
public static ButtonEntry create(ITextComponent text)
#else
public static ButtonEntry create(Component text)
#endif
{ return new ButtonEntry(text); }
#if MC_VER < MC_1_20_1
@Override
#if MC_VER <= MC_1_12_2
public void drawEntry(int slotIndex, int x, int y, int listWidth, int slotHeight, int mouseX, int mouseY, boolean isSelected, float tickDelta)
{ textRenderer.drawString(text.getFormattedText(), 12, y + 5, 0xFFFFFF); }
#elif MC_VER < MC_1_20_1
public void render(PoseStack matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta)
{ GuiComponent.drawString(matrices, textRenderer, text, 12, y + 5, 0xFFFFFF); }
#elif MC_VER < MC_1_21_9
@Override
public void render(GuiGraphics matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta)
{ matrices.drawString(textRenderer, this.text, 12, y + 5, 0xFFFFFF); }
#elif MC_VER <= MC_1_21_11
@Override
public void renderContent(GuiGraphics matrices, int y, int x, boolean hovered, float tickDelta)
{ matrices.drawString(textRenderer, this.text, 12, y + 5, 0xFFFFFF); }
#else
@Override
public void extractContent(GuiGraphicsExtractor matrices, int y, int x, boolean hovered, float tickDelta)
{ matrices.text(textRenderer, this.text, 12, y + 5, 0xFFFFFF); }
#endif
#if MC_VER > MC_1_12_2
@Override
public List<? extends GuiEventListener> children() { return this.children; }
#endif
#if MC_VER >= MC_1_17_1
@Override
public List<? extends NarratableEntry> narratables() { return this.children; }
#endif
#if MC_VER <= MC_1_12_2
@Override
public void updatePosition(int slotIndex, int x, int y, float partialTicks) { }
@Override
public boolean mousePressed(int slotIndex, int mouseX, int mouseY, int mouseEvent, int relativeX, int relativeY) { return false; }
@Override
public void mouseReleased(int slotIndex, int x, int y, int mouseEvent, int relativeX, int relativeY) { }
#endif
}
}
#endif
@@ -1,7 +1,7 @@
package com.seibel.distanthorizons.common.wrappers.gui.updater;
#if MC_VER > MC_1_12_2
import com.seibel.distanthorizons.api.enums.config.EDhApiUpdateBranch;
import com.seibel.distanthorizons.common.wrappers.gui.DhScreen;
import com.seibel.distanthorizons.common.wrappers.gui.DhScreenUtil;
import com.seibel.distanthorizons.common.wrappers.gui.TexturedButtonWidget;
import com.seibel.distanthorizons.core.jar.ModJarInfo;
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
@@ -10,10 +10,15 @@ import com.seibel.distanthorizons.core.config.Config;
import com.seibel.distanthorizons.core.jar.installer.ModrinthGetter;
import com.seibel.distanthorizons.core.jar.updater.SelfUpdater;
import com.seibel.distanthorizons.core.logging.DhLogger;
#if MC_VER <= MC_1_12_2
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiScreen;
#else
import net.minecraft.client.gui.screens.Screen;
#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;
#elif MC_VER <= MC_1_21_11
import net.minecraft.client.gui.GuiGraphics;
@@ -21,7 +26,9 @@ import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.GuiGraphicsExtractor;
#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;
#else
import net.minecraft.resources.Identifier;
@@ -29,8 +36,6 @@ import net.minecraft.resources.Identifier;
import static com.seibel.distanthorizons.common.wrappers.gui.GuiHelper.*;
import java.util.*;
/**
* The screen that pops up if the mod has an update.
*
@@ -40,15 +45,26 @@ public class UpdateModScreen extends DhScreen
{
private static final DhLogger LOGGER = new DhLoggerBuilder().build();
#if MC_VER <= MC_1_12_2
private GuiScreen parent;
#else
private Screen parent;
#endif
private String newVersionID;
private String currentVer;
private String nextVer;
#if MC_VER <= MC_1_12_2
private static final int logoButton_id = 100;
private static final int changelogButton_id = 101;
#endif
#if MC_VER <= MC_1_12_2
public UpdateModScreen(GuiScreen parent, String newVersionID) throws IllegalArgumentException
#else
public UpdateModScreen(Screen parent, String newVersionID) throws IllegalArgumentException
#endif
{
super(Translatable(ModInfo.ID + ".updater.title"));
this.parent = parent;
@@ -76,10 +92,17 @@ public class UpdateModScreen extends DhScreen
}
@Override
#if MC_VER <= MC_1_12_2
public void initGui()
#else
protected void init()
#endif
{
#if MC_VER <= MC_1_12_2
super.initGui();
#else
super.init();
#endif
try
{
@@ -87,6 +110,9 @@ public class UpdateModScreen extends DhScreen
// Logo image
this.addBtn(new TexturedButtonWidget(
#if MC_VER <= MC_1_12_2
logoButton_id,
#endif
// Where the button is on the screen
this.width / 2 - 95, this.height / 2 - 110,
// Width and height of the button
@@ -105,9 +131,15 @@ public class UpdateModScreen extends DhScreen
195, 65,
// Create the button and tell it where to go
// For now it goes to the client option by default
#if MC_VER > MC_1_12_2
(buttonWidget) -> LOGGER.info("Nice, you found an Easter egg :)"),
#endif
// Add a title to the button
#if MC_VER <= MC_1_12_2
Translatable(ModInfo.ID + ".updater.title").getFormattedText(),
#else
Translatable(ModInfo.ID + ".updater.title"),
#endif
// Dont render the background of the button
false
));
@@ -120,6 +152,9 @@ public class UpdateModScreen extends DhScreen
if (!ModInfo.IS_DEV_BUILD)
{
this.addBtn(new TexturedButtonWidget(
#if MC_VER <= MC_1_12_2
changelogButton_id,
#endif
// Where the button is on the screen
this.width / 2 - 97, this.height / 2 + 8,
// Width and height of the button
@@ -137,9 +172,15 @@ public class UpdateModScreen extends DhScreen
#endif
20, 20,
// Create the button and tell it where to go
(buttonWidget) -> Objects.requireNonNull(this.minecraft).setScreen(new ChangelogScreen(this, this.newVersionID)),
#if MC_VER > MC_1_12_2
(buttonWidget) -> DhScreenUtil.setScreen(new ChangelogScreen(this, this.newVersionID)),
#endif
// Add a title to the button
#if MC_VER <= MC_1_12_2
Translatable(ModInfo.ID + ".updater.title").getFormattedText()
#else
Translatable(ModInfo.ID + ".updater.title")
#endif
));
}
@@ -147,32 +188,50 @@ public class UpdateModScreen extends DhScreen
this.addBtn( // Update
MakeBtn(Translatable(ModInfo.ID + ".updater.update"), this.width / 2 - 75, this.height / 2 + 8, 150, 20, (btn) -> {
SelfUpdater.updateMod();
#if MC_VER <= MC_1_12_2
DhScreenUtil.setScreen(this.parent);
#else
this.onClose();
#endif
})
);
this.addBtn( // Silent update
MakeBtn(Translatable(ModInfo.ID + ".updater.silent"), this.width / 2 - 75, this.height / 2 + 30, 150, 20, (btn) -> {
Config.Client.Advanced.AutoUpdater.enableSilentUpdates.set(true);
SelfUpdater.updateMod();
#if MC_VER <= MC_1_12_2
DhScreenUtil.setScreen(this.parent);
#else
this.onClose();
#endif
})
);
this.addBtn( // Later (not now)
MakeBtn(Translatable(ModInfo.ID + ".updater.later"), this.width / 2 + 2, this.height / 2 + 70, 100, 20, (btn) -> {
#if MC_VER <= MC_1_12_2
DhScreenUtil.setScreen(this.parent);
#else
this.onClose();
#endif
})
);
this.addBtn( // Never
MakeBtn(Translatable(ModInfo.ID + ".updater.never"), this.width / 2 - 102, this.height / 2 + 70, 100, 20, (btn) -> {
Config.Client.Advanced.AutoUpdater.enableAutoUpdater.set(false);
#if MC_VER <= MC_1_12_2
DhScreenUtil.setScreen(this.parent);
#else
this.onClose();
#endif
})
);
}
@Override
#if MC_VER < MC_1_20_1
#if MC_VER <= MC_1_12_2
public void drawScreen(int mouseX, int mouseY, float delta)
#elif MC_VER < MC_1_20_1
public void render(PoseStack matrices, int mouseX, int mouseY, float delta)
#elif MC_VER <= MC_1_21_11
public void render(GuiGraphics matrices, int mouseX, int mouseY, float delta)
@@ -180,7 +239,9 @@ public class UpdateModScreen extends DhScreen
public void extractRenderState(GuiGraphicsExtractor matrices, int mouseX, int mouseY, float delta)
#endif
{
#if MC_VER < MC_1_20_2
#if MC_VER <= MC_1_12_2
this.drawDefaultBackground(); // Render background
#elif MC_VER < MC_1_20_2
this.renderBackground(matrices); // Render background
#elif MC_VER < MC_1_21_6
this.renderBackground(matrices, mouseX, mouseY, delta); // Render background
@@ -188,15 +249,20 @@ public class UpdateModScreen extends DhScreen
// background blur is already being rendered, rendering again causes the game to crash
#endif
#if MC_VER <= MC_1_21_11
#if MC_VER <= MC_1_12_2
super.drawScreen(mouseX, mouseY, delta); // Render the buttons
#elif MC_VER <= MC_1_21_11
super.render(matrices, mouseX, mouseY, delta); // Render the buttons
#else
super.extractRenderState(matrices, mouseX, mouseY, delta);
#endif
// Render the text's
this.DhDrawCenteredString(matrices, this.font,
Translatable(ModInfo.ID + ".updater.text1"),
this.DhDrawCenteredString(
#if MC_VER > MC_1_12_2
matrices, this.font,
#endif
Translatable(ModInfo.ID + ".updater.updateAvailable"),
this.width / 2, this.height / 2 - 35,
#if MC_VER < MC_1_21_6
0xFFFFFF // RGB
@@ -204,8 +270,11 @@ public class UpdateModScreen extends DhScreen
0xFFFFFFFF // ARGB
#endif
);
this.DhDrawCenteredString(matrices, this.font,
Translatable(ModInfo.ID + ".updater.text2", this.currentVer, this.nextVer),
this.DhDrawCenteredString(
#if MC_VER > MC_1_12_2
matrices, this.font,
#endif
Translatable(ModInfo.ID + ".updater.updateConfirmation", this.currentVer, this.nextVer),
this.width / 2, this.height / 2 - 20,
#if MC_VER < MC_1_21_6
0x52FD52 // RGB
@@ -216,10 +285,38 @@ public class UpdateModScreen extends DhScreen
}
@Override
#if MC_VER <= MC_1_12_2
public void onGuiClosed()
#else
public void onClose()
#endif
{
Objects.requireNonNull(this.minecraft).setScreen(this.parent); // Go to the parent screen
// Go to the parent screen
#if MC_VER <= MC_1_12_2
// Handled by button to avoid recursive loop
#else
DhScreenUtil.setScreen(this.parent); // Go to the parent screen
#endif
}
}
#endif
#if MC_VER <= MC_1_12_2
@Override
protected void actionPerformed(GuiButton button)
{
super.actionPerformed(button);
if(button.id == changelogButton_id)
{
ChangelogScreen changelogScreen = new ChangelogScreen(this);
if (changelogScreen.usable)
{
DhScreenUtil.setScreen(changelogScreen);
}
else
{
LOGGER.warn("Changelog was not able to open");
}
}
}
#endif
}
@@ -19,40 +19,18 @@ import java.util.concurrent.ConcurrentHashMap;
public class KeyedClientLevelManager implements IKeyedClientLevelManager
{
public static final KeyedClientLevelManager INSTANCE = new KeyedClientLevelManager();
private static class KeyInfo {
public final String serverKey;
public final String levelKey;
public KeyInfo(String serverKey, String levelKey) {
this.serverKey = serverKey;
this.levelKey = levelKey;
}
}
/** Stores the server-provided keys indexed by dimension name for persistence. */
private final Map<String, KeyInfo> keysByDimensionName = new ConcurrentHashMap<>();
/** Cache for already keyed level wrappers to maintain object identity. */
private final Map<#if MC_VER > MC_1_12_2 ClientLevel #else WorldClient #endif, IServerKeyedClientLevel> keyedLevelsCache = Collections.synchronizedMap(new WeakHashMap<>());
private final Map<#if MC_VER > MC_1_12_2 ClientLevel #else WorldClient #endif, IServerKeyedClientLevel>
keyedLevelsCache = Collections.synchronizedMap(new WeakHashMap<>());
/** Allows to keep level manager enabled between loading different keyed levels */
private volatile boolean enabled = false;
//=============//
// constructor //
//=============//
//region
private KeyedClientLevelManager() { }
//endregion
//======================//
// level override logic //
//======================//
@@ -60,19 +38,9 @@ public class KeyedClientLevelManager implements IKeyedClientLevelManager
@Override
@Nullable
public IServerKeyedClientLevel getServerKeyedLevel()
{
#if MC_VER > MC_1_12_2
return this.getServerKeyedLevel(Minecraft.getInstance().level);
#else
return this.getServerKeyedLevel(Minecraft.getMinecraft().world);
#endif
}
@Nullable
public IServerKeyedClientLevel getServerKeyedLevel(@Nullable #if MC_VER > MC_1_12_2 ClientLevel #else WorldClient #endif level)
public IServerKeyedClientLevel getServerKeyedLevel(IClientLevelWrapper levelWrapper)
{
if (level == null)
if (levelWrapper == null)
{
return null;
}
@@ -81,6 +49,12 @@ public class KeyedClientLevelManager implements IKeyedClientLevelManager
// This prevents multiple threads from creating duplicate wrappers for the same level.
synchronized (this.keyedLevelsCache)
{
#if MC_VER <= MC_1_12_2
WorldClient level = (WorldClient) levelWrapper.getWrappedMcObject();
#else
ClientLevel level = (ClientLevel) levelWrapper.getWrappedMcObject();
#endif
// Check the cache first
IServerKeyedClientLevel cached = this.keyedLevelsCache.get(level);
if (cached != null)
@@ -111,45 +85,31 @@ public class KeyedClientLevelManager implements IKeyedClientLevelManager
}
@Override
public IServerKeyedClientLevel setServerKeyedLevel(IClientLevelWrapper clientLevel, String serverKey, String levelKey)
public IServerKeyedClientLevel setServerKeyedLevel(IClientLevelWrapper clientLevel, String dimensionResource, String serverKey, String levelKey)
{
// 1. Determine the target dimension name
String targetDimensionName = clientLevel.getDimensionName();
int separatorIndex = levelKey.lastIndexOf("@");
if (separatorIndex != -1)
{
targetDimensionName = levelKey.substring(separatorIndex + 1);
}
final String finalTargetDimensionName = targetDimensionName;
// 2. Store the key for this dimension
this.keysByDimensionName.put(finalTargetDimensionName, new KeyInfo(serverKey, levelKey));
this.keysByDimensionName.put(dimensionResource, new KeyInfo(serverKey, levelKey));
this.enabled = true;
// 3. Clear the cache for this dimension to ensure new wrappers are created with the new key
// (though in practice keys shouldn't change mid-session)
//
// We synchronize manually on the map to ensure atomicity of the compound removal operation
// and to prevent race conditions or deadlocks with other threads accessing the map.
// We avoid calling ClientLevelWrapper.getWrapper() inside the lock to prevent circular lock dependencies.
synchronized (this.keyedLevelsCache)
{
this.keyedLevelsCache.keySet().removeIf(level -> {
#if MC_VER <= MC_1_12_2
String levelDim = level.provider.getDimensionType().getName() + ":" + level.provider.getDimension();
#elif MC_VER <= MC_1_21_10
#if MC_VER <= MC_1_12_2
String levelDim = level.provider.getDimensionType().getName() + ":" + level.provider.getDimension();
#elif MC_VER <= MC_1_21_10
String levelDim = level.dimension().location().toString();
#else
String levelDim = level.dimension().identifier().toString();
#endif
return levelDim.equals(finalTargetDimensionName);
#else
String levelDim = level.dimension().identifier().toString();
#endif
return levelDim.equals(dimensionResource);
});
}
// 4. Return the keyed wrapper for whatever level the core passed us,
// but only if it matches the dimension we just keyed.
return this.getServerKeyedLevel((#if MC_VER > MC_1_12_2 ClientLevel #else WorldClient #endif) clientLevel.getWrappedMcObject());
if (clientLevel == null || !clientLevel.getDimensionName().equals(dimensionResource)) {
return null;
}
return this.getServerKeyedLevel(clientLevel);
}
@Override
@@ -172,4 +132,26 @@ public class KeyedClientLevelManager implements IKeyedClientLevelManager
this.clearKeyedLevel();
}
//================//
// helper classes //
//================//
//region
private static class KeyInfo
{
public final String serverKey;
public final String levelKey;
public KeyInfo(String serverKey, String levelKey)
{
this.serverKey = serverKey;
this.levelKey = levelKey;
}
}
//endregion
}
@@ -0,0 +1,66 @@
package com.seibel.distanthorizons.common.wrappers.minecraft;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftSharedWrapper;
import org.jetbrains.annotations.Nullable;
#if MC_VER > MC_1_12_2
import net.minecraft.resources.ResourceKey;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.Level;
#endif
#if MC_VER <= MC_1_12_2
#elif MC_VER <= MC_1_21_10
import net.minecraft.resources.ResourceLocation;
#else
import net.minecraft.resources.Identifier;
#endif
#if MC_VER > MC_1_19_2
import net.minecraft.core.registries.Registries;
#elif MC_VER > MC_1_12_2
import net.minecraft.core.Registry;
#endif
public abstract class AbstractMinecraftSharedWrapper implements IMinecraftSharedWrapper
{
@Nullable
#if MC_VER <= MC_1_12_2
protected Integer deserializeDimensionResourceKey(String dimensionResourceLocation)
#else
protected ResourceKey<Level> deserializeDimensionResourceKey(String dimensionResourceLocation)
#endif
{
#if MC_VER <= MC_1_12_2
try
{
return Integer.parseInt(dimensionResourceLocation.substring(dimensionResourceLocation.indexOf(":")+1));
}
catch (NumberFormatException ignored)
{
return null;
}
#else
#if MC_VER <= MC_1_21_10
ResourceLocation dimResourceLocation = ResourceLocation.tryParse(dimensionResourceLocation);
#else
Identifier dimResourceLocation = Identifier.tryParse(dimensionResourceLocation);
#endif
if (dimResourceLocation == null)
{
return null;
}
#if MC_VER > MC_1_19_2
ResourceKey<Level> dimensionKey = ResourceKey.create(Registries.DIMENSION, dimResourceLocation);
#else
ResourceKey<Level> dimensionKey = ResourceKey.create(Registry.DIMENSION_REGISTRY, dimResourceLocation);
#endif
return dimensionKey;
#endif
}
}
@@ -20,7 +20,6 @@
package com.seibel.distanthorizons.common.wrappers.minecraft;
import java.io.File;
import java.util.Arrays;
#if MC_VER > MC_1_12_2
import com.mojang.blaze3d.platform.Window;
@@ -88,7 +87,6 @@ import net.minecraft.client.GraphicsStatus;
#if MC_VER <= MC_1_12_2
import net.minecraft.util.ResourceLocation;
#elif MC_VER <= MC_1_21_10
import net.minecraft.resources.ResourceLocation;
#else
import net.minecraft.resources.Identifier;
#endif
@@ -96,7 +94,6 @@ import net.minecraft.resources.Identifier;
#if MC_VER > MC_1_19_2
import net.minecraft.core.registries.Registries;
#elif MC_VER > MC_1_12_2
import net.minecraft.core.Registry;
#endif
@@ -105,7 +102,7 @@ import net.minecraft.core.Registry;
*
* @author James Seibel
*/
public class MinecraftClientWrapper implements IMinecraftClientWrapper, IMinecraftSharedWrapper
public class MinecraftClientWrapper extends AbstractMinecraftSharedWrapper implements IMinecraftClientWrapper
{
private static final DhLogger LOGGER = new DhLoggerBuilder().build();
@@ -120,9 +117,10 @@ public class MinecraftClientWrapper implements IMinecraftClientWrapper, IMinecra
private ProfilerWrapper profilerWrapper;
// Need to classload this field later because otherwise it will be null even when Immersive Portals is present.
public static class Late {
private static final IImmersivePortalsAccessor IMMERSIVE_PORTALS = ModAccessorInjector.INSTANCE.get(IImmersivePortalsAccessor.class);
/** Delayed accessing is necessary since this object will be created before the mod accessors are bound. */
private static class DelayedAccessors
{
public static final IImmersivePortalsAccessor IMMERSIVE_PORTALS = ModAccessorInjector.INSTANCE.get(IImmersivePortalsAccessor.class);
}
@@ -262,10 +260,13 @@ public class MinecraftClientWrapper implements IMinecraftClientWrapper, IMinecra
return new DhBlockPos(0, 0, 0);
}
if (Late.IMMERSIVE_PORTALS != null)
if (DelayedAccessors.IMMERSIVE_PORTALS != null)
{
DhBlockPos pos = Late.IMMERSIVE_PORTALS.getOriginalPlayerBlockPos();
if (pos != null) return pos;
DhBlockPos pos = DelayedAccessors.IMMERSIVE_PORTALS.getActualPlayerBlockPos();
if (pos != null)
{
return pos;
}
}
#if MC_VER <= MC_1_12_2
@@ -289,10 +290,13 @@ public class MinecraftClientWrapper implements IMinecraftClientWrapper, IMinecra
return new DhChunkPos(0, 0);
}
if (Late.IMMERSIVE_PORTALS != null)
if (DelayedAccessors.IMMERSIVE_PORTALS != null)
{
DhChunkPos pos = Late.IMMERSIVE_PORTALS.getOriginalPlayerChunkPos();
if (pos != null) return pos;
DhChunkPos pos = DelayedAccessors.IMMERSIVE_PORTALS.getActualPlayerChunkPos();
if (pos != null)
{
return pos;
}
}
#if MC_VER <= MC_1_12_2
@@ -327,11 +331,16 @@ public class MinecraftClientWrapper implements IMinecraftClientWrapper, IMinecra
@Nullable
public IClientLevelWrapper getWrappedClientLevel(boolean bypassLevelKeyManager)
{
if (!bypassLevelKeyManager && Late.IMMERSIVE_PORTALS != null)
if (!bypassLevelKeyManager
&& DelayedAccessors.IMMERSIVE_PORTALS != null)
{
IClientLevelWrapper level = Late.IMMERSIVE_PORTALS.getOriginalClientLevelWrapper();
if (level != null) return level;
IClientLevelWrapper level = DelayedAccessors.IMMERSIVE_PORTALS.getActualClientLevelWrapper();
if (level != null)
{
return level;
}
}
#if MC_VER <= MC_1_12_2
WorldClient level = MINECRAFT.world;
#else
@@ -630,42 +639,28 @@ public class MinecraftClientWrapper implements IMinecraftClientWrapper, IMinecra
}
}
@Nullable
@Override
public IServerLevelWrapper getWrappedServerLevel(String levelKey)
public IServerLevelWrapper getLevelWrapper(String dimensionResourceLocation)
{
if (!hasSinglePlayerServer()) return null;
#if MC_VER <= MC_1_12_2
int dimensionID;
try
{
dimensionID = Integer.parseInt(levelKey.substring(levelKey.indexOf(":")+1));
}
catch (NumberFormatException ignored)
if (!this.hasSinglePlayerServer())
{
return null;
}
#else
#if MC_VER <= MC_1_21_10
ResourceLocation levelID = ResourceLocation.tryParse(levelKey);
#else
Identifier levelID = Identifier.tryParse(levelKey);
#endif
if (levelID == null) return null;
#if MC_VER > MC_1_19_2
ResourceKey<Level> resourceKey = ResourceKey.create(Registries.DIMENSION, levelID);
#else
ResourceKey<Level> resourceKey = ResourceKey.create(Registry.DIMENSION_REGISTRY, levelID);
#endif
#endif
#if MC_VER <= MC_1_12_2
WorldServer level = MINECRAFT.getIntegratedServer().getWorld(dimensionID);
Integer dimensionKey = this.deserializeDimensionResourceKey(dimensionResourceLocation);
if (dimensionKey == null || MINECRAFT.getIntegratedServer() == null)
{
return null;
}
WorldServer mcLevel = MINECRAFT.getIntegratedServer().getWorld(dimensionKey);
#else
ServerLevel level = MINECRAFT.getSingleplayerServer().getLevel(resourceKey);
ResourceKey<Level> dimensionKey = this.deserializeDimensionResourceKey(dimensionResourceLocation);
ServerLevel mcLevel = MINECRAFT.getSingleplayerServer().getLevel(dimensionKey);
#endif
return ServerLevelWrapper.getWrapper(level);
return ServerLevelWrapper.getWrapper(mcLevel);
}
//endregion
@@ -126,6 +126,7 @@ public class MinecraftGLWrapper
GlStateManager._depthFunc(func);
#endif
}
public int getActiveDepthFunc() { return GL32.glGetInteger(GL32.GL_DEPTH_FUNC); }
/** @see GL32#glDepthMask(boolean) */
public void enableDepthMask()
@@ -157,8 +158,10 @@ public class MinecraftGLWrapper
GL32.glEnable(GL32.GL_BLEND);
#if MC_VER <= MC_1_12_2
GlStateManager.enableBlend();
#else
#elif MC_VER <= MC_26_1_2
GlStateManager._enableBlend();
#else
GlStateManager._enableBlend(0);
#endif
}
/** @see GL32#GL_BLEND */
@@ -167,8 +170,10 @@ public class MinecraftGLWrapper
GL32.glDisable(GL32.GL_BLEND);
#if MC_VER <= MC_1_12_2
GlStateManager.disableBlend();
#elif MC_VER <= MC_26_1_2
GlStateManager._disableBlend();
#else
GlStateManager._disableBlend();
GlStateManager._disableBlend(0);
#endif
}
@@ -22,30 +22,33 @@ package com.seibel.distanthorizons.common.wrappers.minecraft;
import java.awt.Color;
import java.util.concurrent.ConcurrentHashMap;
import com.seibel.distanthorizons.core.render.RenderThreadTaskHandler;
import org.jetbrains.annotations.Nullable;
#if MC_VER > MC_1_12_2
import com.mojang.blaze3d.pipeline.RenderTarget;
import com.mojang.blaze3d.platform.NativeImage;
import com.mojang.blaze3d.systems.RenderSystem;
#endif
import com.seibel.distanthorizons.api.enums.config.EDhApiLodShading;
import com.seibel.distanthorizons.common.wrappers.McObjectConverter;
import com.seibel.distanthorizons.common.wrappers.misc.LightMapWrapper;
import com.seibel.distanthorizons.core.api.internal.ClientApi;
import com.seibel.distanthorizons.core.config.Config;
import com.seibel.distanthorizons.core.dependencyInjection.ModAccessorInjector;
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
import com.seibel.distanthorizons.core.enums.EDhDirection;
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import com.seibel.distanthorizons.api.enums.config.EDhApiRenderingApi;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.ILightMapWrapper;
#if MC_VER < MC_1_17_1
#elif MC_VER < MC_1_21_3
import net.minecraft.client.renderer.FogRenderer;
import com.mojang.blaze3d.systems.RenderSystem;
#elif MC_VER < MC_1_21_6
import com.seibel.distanthorizons.coreapi.util.ColorUtil;
import net.minecraft.client.renderer.FogRenderer;
import com.mojang.blaze3d.systems.RenderSystem;
#else
import com.seibel.distanthorizons.coreapi.util.ColorUtil;
import net.minecraft.client.renderer.fog.FogData;
@@ -61,8 +64,8 @@ import org.joml.Vector3f;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IDimensionTypeWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
import com.seibel.distanthorizons.core.util.math.Vec3d;
import com.seibel.distanthorizons.core.util.math.Vec3f;
import com.seibel.distanthorizons.core.util.math.DhVec3d;
import com.seibel.distanthorizons.core.util.math.DhVec3f;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IImmersivePortalsAccessor;
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IOptifineAccessor;
@@ -84,7 +87,6 @@ import net.minecraft.world.phys.Vec3;
import net.minecraft.client.Minecraft;
import com.seibel.distanthorizons.core.logging.DhLogger;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.joml.Vector4f;
#if MC_VER <= MC_1_12_2
@@ -128,9 +130,10 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
private static final Minecraft MC = Minecraft.getInstance();
#endif
// Need to classload this field later because otherwise it will be null even when Immersive Portals is present.
public static class Late {
private static final IImmersivePortalsAccessor IMMERSIVE_PORTALS = ModAccessorInjector.INSTANCE.get(IImmersivePortalsAccessor.class);
/** Delayed accessing is necessary since this object will be created before the mod accessors are bound. */
private static class DelayedAccessors
{
public static final IImmersivePortalsAccessor IMMERSIVE_PORTALS = ModAccessorInjector.INSTANCE.get(IImmersivePortalsAccessor.class);
}
/**
@@ -160,17 +163,20 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
//=========//
@Override
public Vec3f getLookAtVector()
public DhVec3f getLookAtVector()
{
#if MC_VER <= MC_1_12_2
net.minecraft.util.math.Vec3d lookVector = (MC.getRenderViewEntity().getLook(MC.getRenderPartialTicks()));
return new Vec3f((float) lookVector.x, (float) lookVector.y, (float) lookVector.z);
return new DhVec3f((float) lookVector.x, (float) lookVector.y, (float) lookVector.z);
#elif MC_VER <= MC_1_21_10
Camera camera = MC.gameRenderer.getMainCamera();
return new Vec3f(camera.getLookVector().x(), camera.getLookVector().y(), camera.getLookVector().z());
#else
return new DhVec3f(camera.getLookVector().x(), camera.getLookVector().y(), camera.getLookVector().z());
#elif MC_VER <= MC_26_1_2
Camera camera = MC.gameRenderer.getMainCamera();
return new Vec3f(camera.forwardVector().x(), camera.forwardVector().y(), camera.forwardVector().z());
return new DhVec3f(camera.forwardVector().x(), camera.forwardVector().y(), camera.forwardVector().z());
#else
Camera camera = MC.gameRenderer.mainCamera();
return new DhVec3f(camera.forwardVector().x(), camera.forwardVector().y(), camera.forwardVector().z());
#endif
}
@@ -209,24 +215,41 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
}
@Override
public Vec3d getCameraExactPosition()
public DhVec3d getCameraExactPosition()
{
if (Late.IMMERSIVE_PORTALS != null)
// When immersive portals is enabled getting the camera position
// outside the render thread means you may get the camera for any one of the dimensions
// immersive portals is currently rendering, which isn't what DH wants.
// We want the camera that the player is currently looking through.
if (DelayedAccessors.IMMERSIVE_PORTALS != null
&& !RenderThreadTaskHandler.INSTANCE.isCurrentThread())
{
Vec3d cameraPos = Late.IMMERSIVE_PORTALS.getOriginalCameraPos();
if (cameraPos != null) return cameraPos;
// this camera position will likely be delayed by 1 frame, so it shouldn't
// be used for rendering,
// but anything else that doesn't require that level of percision is fine.
DhVec3d cameraPos = DelayedAccessors.IMMERSIVE_PORTALS.getActualCameraPos();
if (cameraPos != null)
{
return cameraPos;
}
}
#if MC_VER <= MC_1_12_2
RenderManager rm = MC.getRenderManager();
return new Vec3d(rm.viewerPosX, rm.viewerPosY, rm.viewerPosZ);
return new DhVec3d(rm.viewerPosX, rm.viewerPosY, rm.viewerPosZ);
#else
#if MC_VER <= MC_26_1_2
Camera camera = MC.gameRenderer.getMainCamera();
#else
Camera camera = MC.gameRenderer.mainCamera();
#endif
#if MC_VER <= MC_1_21_10
Vec3 projectedView = camera.getPosition();
#else
Vec3 projectedView = camera.position();
#endif
return new Vec3d(projectedView.x, projectedView.y, projectedView.z);
return new DhVec3d(projectedView.x, projectedView.y, projectedView.z);
#endif
}
@@ -315,20 +338,29 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
float darkenAmount;
#if MC_VER <= MC_1_21_11
darkenAmount = MC.gameRenderer.getDarkenWorldAmount(MC.deltaTracker.getGameTimeDeltaPartialTick(true));
#else
#elif MC_VER <= MC_26_1_2
darkenAmount = MC.gameRenderer.getBossOverlayWorldDarkening(MC.deltaTracker.getGameTimeDeltaPartialTick(true));
#else
darkenAmount = MC.gameRenderer.bossOverlayWorldDarkening(MC.deltaTracker.getGameTimeDeltaPartialTick(true));
#endif
#if MC_VER <= MC_26_1_2
Camera camera = MC.gameRenderer.getMainCamera();
#else
Camera camera = MC.gameRenderer.mainCamera();
#endif
#if MC_VER <= MC_1_21_11
Vector4f colorValues = mcFogRenderer.setupFog(
MC.gameRenderer.getMainCamera(),
camera,
MC.options.getEffectiveRenderDistance(),
MC.deltaTracker,
darkenAmount,
MC.level);
#else
FogData fogData = mcFogRenderer.setupFog(
MC.gameRenderer.getMainCamera(),
camera,
MC.options.getEffectiveRenderDistance(),
MC.deltaTracker,
darkenAmount,
@@ -370,8 +402,11 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
float frameTime = this.getPartialTickTime();
int argbColorInt = MC.level.getSkyColor(MC.gameRenderer.getMainCamera().getPosition(), frameTime);
return ColorUtil.toColorObjARGB(argbColorInt);
#elif MC_VER <= MC_26_1_2
int argbColor = MC.level.environmentAttributes().getValue(EnvironmentAttributes.SKY_COLOR, MC.gameRenderer.getMainCamera().position());
return new Color(ColorUtil.getRed(argbColor), ColorUtil.getGreen(argbColor), ColorUtil.getBlue(argbColor), 255 /* ignore alpha since DH clouds don't render correctly with transparency */);
#else
int argbColor = MC.level.environmentAttributes().getValue(EnvironmentAttributes.SKY_COLOR, BlockPos.ZERO);
int argbColor = MC.level.environmentAttributes().getValue(EnvironmentAttributes.SKY_COLOR, MC.gameRenderer.mainCamera().position());
return new Color(ColorUtil.getRed(argbColor), ColorUtil.getGreen(argbColor), ColorUtil.getBlue(argbColor), 255 /* ignore alpha since DH clouds don't render correctly with transparency */);
#endif
}
@@ -407,7 +442,14 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
}
#if MC_VER > MC_1_12_2
protected RenderTarget getRenderTarget() { return MC.getMainRenderTarget(); }
public RenderTarget getRenderTarget()
{
#if MC_VER <= MC_26_1_2
return MC.getMainRenderTarget();
#else
return MC.gameRenderer.mainRenderTarget();
#endif
}
#endif
@Override
@@ -430,6 +472,30 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
#endif
}
private EDhApiRenderingApi renderApi = null;
@Override
public EDhApiRenderingApi getMcRenderingApi()
{
if (this.renderApi != null)
{
return this.renderApi;
}
#if MC_VER <= MC_26_1_2
this.renderApi = EDhApiRenderingApi.OPEN_GL;
#else
String backendName = RenderSystem
.getDevice()
.getDeviceInfo()
.backendName();
boolean isVulkan = backendName.equalsIgnoreCase("Vulkan");
this.renderApi = isVulkan ? EDhApiRenderingApi.VULKAN : EDhApiRenderingApi.OPEN_GL;
#endif
return this.renderApi;
}
@Override
public int getTargetFramebuffer()
{
@@ -454,7 +520,7 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
public void clearTargetFrameBuffer() { this.finalLevelFrameBufferId = -1; }
@Override
public int getDepthTextureId()
public int getGlDepthTextureId()
{
#if MC_VER <= MC_1_12_2
//1.12.2 is using renderbuffer instead of framebuffer for depth texture
@@ -487,7 +553,7 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
#endif
}
@Override
public int getColorTextureId()
public int getGlColorTextureId()
{
#if MC_VER <= MC_1_12_2
return MC.getFramebuffer().framebufferTexture;
@@ -557,9 +623,12 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
isBlind |= fluidState.is(FluidTags.WATER);
isBlind |= fluidState.is(FluidTags.LAVA);
return isBlind;
#else
#elif MC_VER <= MC_26_1_2
boolean isBlind = this.playerHasBlindingEffect();
return MC.gameRenderer.getMainCamera().getFluidInCamera() != FogType.NONE || isBlind;
#else
boolean isBlind = this.playerHasBlindingEffect();
return MC.gameRenderer.mainCamera().getFluidInCamera() != FogType.NONE || isBlind;
#endif
}
@@ -633,6 +702,7 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
}
#endif
/** special logic is necessary in order for Immersive Portals to work correctly */
private static @Nullable IClientLevelWrapper getLightmapClientLevelWrapper()
{
IClientLevelWrapper clientLevel = ClientApi.RENDER_STATE.clientLevelWrapper;
@@ -1,7 +1,6 @@
package com.seibel.distanthorizons.common.wrappers.minecraft;
import com.seibel.distanthorizons.common.wrappers.world.ServerLevelWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftSharedWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IServerLevelWrapper;
import net.minecraft.server.dedicated.DedicatedServer;
import org.jetbrains.annotations.Nullable;
@@ -29,7 +28,7 @@ import net.minecraft.core.Registry;
import java.io.File;
public class MinecraftServerWrapper implements IMinecraftSharedWrapper
public class MinecraftServerWrapper extends AbstractMinecraftSharedWrapper
{
public static final MinecraftServerWrapper INSTANCE = new MinecraftServerWrapper();
@@ -87,41 +86,27 @@ public class MinecraftServerWrapper implements IMinecraftSharedWrapper
}
@Nullable
@Override
public IServerLevelWrapper getWrappedServerLevel(String levelKey)
public IServerLevelWrapper getLevelWrapper(String dimensionResourceLocation)
{
#if MC_VER <= MC_1_12_2
int dimensionID;
try
if (this.dedicatedServer == null)
{
dimensionID = Integer.parseInt(levelKey.substring(levelKey.indexOf(":")+1));
throw new IllegalStateException("Trying to get the server mcLevel before dedicated server completed initialization!");
}
catch (NumberFormatException ignored)
#if MC_VER <= MC_1_12_2
Integer dimensionKey = this.deserializeDimensionResourceKey(dimensionResourceLocation);
if (dimensionKey == null)
{
return null;
}
WorldServer mcLevel = dedicatedServer.getWorld(dimensionKey);
#else
#if MC_VER <= MC_1_21_10
ResourceLocation levelID = ResourceLocation.tryParse(levelKey);
#else
Identifier levelID = Identifier.tryParse(levelKey);
ResourceKey<Level> dimensionKey = this.deserializeDimensionResourceKey(dimensionResourceLocation);
ServerLevel mcLevel = dedicatedServer.getLevel(dimensionKey);
#endif
if (levelID == null) return null;
#if MC_VER > MC_1_19_2
ResourceKey<Level> resourceKey = ResourceKey.create(Registries.DIMENSION, levelID);
#else
ResourceKey<Level> resourceKey = ResourceKey.create(Registry.DIMENSION_REGISTRY, levelID);
#endif
#endif
#if MC_VER > MC_1_12_2
ServerLevel level = dedicatedServer.getLevel(resourceKey);
#else
WorldServer level = dedicatedServer.getWorld(dimensionID);
#endif
return ServerLevelWrapper.getWrapper(level);
return ServerLevelWrapper.getWrapper(mcLevel);
}
}
@@ -5,7 +5,7 @@ import com.google.common.collect.MapMaker;
import com.seibel.distanthorizons.common.wrappers.world.ServerLevelWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IServerPlayerWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IServerLevelWrapper;
import com.seibel.distanthorizons.core.util.math.Vec3d;
import com.seibel.distanthorizons.core.util.math.DhVec3d;
#if MC_VER <= MC_1_12_2
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.network.NetHandlerPlayServer;
@@ -19,7 +19,6 @@ import net.minecraft.server.network.ServerGamePacketListenerImpl;
import net.minecraft.world.phys.Vec3;
#endif
import java.net.SocketAddress;
import java.util.concurrent.ConcurrentMap;
#if MC_VER <= MC_1_12_2
@@ -126,14 +125,14 @@ public class ServerPlayerWrapper implements IServerPlayerWrapper
}
@Override
public Vec3d getPosition()
public DhVec3d getPosition()
{
#if MC_VER <= MC_1_12_2
BlockPos position = this.getServerPlayer().getPosition();
return new Vec3d(position.getX(), position.getY(), position.getZ());
return new DhVec3d(position.getX(), position.getY(), position.getZ());
#else
Vec3 position = this.getServerPlayer().position();
return new Vec3d(position.x, position.y, position.z);
return new DhVec3d(position.x, position.y, position.z);
#endif
}
@@ -0,0 +1,75 @@
/*
* This file is part of the Distant Horizons mod
* licensed under the GNU LGPL v3 License.
*
* Copyright (C) 2020 James Seibel
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.seibel.distanthorizons.common.wrappers.modAccessor;
#if MC_VER <= MC_1_12_2
public abstract class AbstractImmersivePortalsAccessorCommon {}
#else
import com.seibel.distanthorizons.common.wrappers.world.ClientLevelWrapper;
import com.seibel.distanthorizons.core.pos.DhChunkPos;
import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos;
import com.seibel.distanthorizons.core.util.math.DhVec3d;
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.AbstractImmersivePortalsAccessor;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
import net.minecraft.client.multiplayer.ClientLevel;
import org.jetbrains.annotations.Nullable;
#if MC_VER > MC_1_19_2
#else
#endif
#if MC_VER < MC_1_17_1
import java.lang.reflect.Field;
#endif
public abstract class AbstractImmersivePortalsAccessorCommon extends AbstractImmersivePortalsAccessor
{
// We don't use the fields in RenderStates because they are not volatile.
@Nullable
public static volatile ClientLevel actualLevel;
@Nullable
public static volatile DhBlockPos actualBlockPos;
@Nullable
public static volatile DhChunkPos actualChunkPos;
@Nullable
public static volatile DhVec3d actualCameraPos;
@Override
@Nullable
public DhBlockPos getActualPlayerBlockPos() { return actualBlockPos; }
@Override
@Nullable
public DhChunkPos getActualPlayerChunkPos() { return actualChunkPos; }
@Override
@Nullable
public IClientLevelWrapper getActualClientLevelWrapper() { return ClientLevelWrapper.getWrapper(actualLevel, false); }
@Override
@Nullable
public DhVec3d getActualCameraPos() { return actualCameraPos; }
}
#endif
@@ -1,144 +0,0 @@
/*
* This file is part of the Distant Horizons mod
* licensed under the GNU LGPL v3 License.
*
* Copyright (C) 2020 James Seibel
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.seibel.distanthorizons.common.wrappers.modAccessor;
#if MC_VER > MC_1_12_2
import com.google.common.base.Suppliers;
import com.mojang.blaze3d.systems.RenderSystem;
import com.seibel.distanthorizons.common.wrappers.world.ClientLevelWrapper;
import com.seibel.distanthorizons.core.api.internal.ClientApi;
import com.seibel.distanthorizons.core.pos.DhChunkPos;
import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos;
import com.seibel.distanthorizons.core.util.math.Vec3d;
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.ImmersivePortalsAbstractAccessor;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.client.renderer.culling.Frustum;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.Vec3;
import org.jetbrains.annotations.Nullable;
#if MC_VER > MC_1_19_2
import org.joml.Matrix4f;
#else
import com.mojang.math.Matrix4f;
import com.seibel.distanthorizons.core.util.math.Mat4f;
#endif
#if MC_VER < MC_1_17_1
import java.lang.reflect.Field;
#endif
import java.util.function.Supplier;
public abstract class ImmersivePortalsAccessorCommon extends ImmersivePortalsAbstractAccessor
{
// We don't use the fields in RenderStates because they are not volatile.
@Nullable
public static volatile ClientLevel originalLevel;
@Nullable
public static volatile DhBlockPos originalBlockPos;
@Nullable
public static volatile DhChunkPos originalChunkPos;
@Nullable
public static volatile Vec3d originalCameraPos;
@Override
protected Object getClientLevel() { return Minecraft.getInstance().level; }
@Override
protected Class<?> getLevelClass() { return Level.class; }
@Override
protected Iterable<?> getEntitiesForRendering() { return Minecraft.getInstance().level.entitiesForRendering(); }
#if MC_VER < MC_1_21_6
private static Matrix4f getProjectionMatrix()
{
#if MC_VER > MC_1_16_5
return RenderSystem.getProjectionMatrix();
#else
try
{
Class<?> renderStates = Class.forName("com.qouteall.immersive_portals.render.context_management.RenderStates");
Field projectionMatrix = renderStates.getField("projectionMatrix");
return (Matrix4f) projectionMatrix.get(null);
}
catch (Throwable e)
{
throw new RuntimeException(e);
}
#endif
}
#endif
#if MC_VER <= MC_1_19_2
protected abstract Matrix4f convert(Mat4f matrix);
#endif
@Override
protected Supplier<?> getFrustumSupplier()
{
#if MC_VER < MC_1_21_6 // TODO Fix this for 1.21.6+ when a more modern version of Immersive Portals is available.
return Suppliers.memoize(() -> {
Frustum frustum = new Frustum(
#if MC_VER > MC_1_19_2
ClientApi.RENDER_STATE.mcModelViewMatrix.createJomlMatrix(),
#else
convert(ClientApi.RENDER_STATE.mcModelViewMatrix),
#endif
getProjectionMatrix()
);
Vec3 cameraPos = Minecraft.getInstance().gameRenderer.getMainCamera().getPosition();
frustum.prepare(cameraPos.x, cameraPos.y, cameraPos.z);
return frustum;
});
#else
return null;
#endif
}
@Override
@Nullable
public DhBlockPos getOriginalPlayerBlockPos() {
return originalBlockPos;
}
@Override
@Nullable
public DhChunkPos getOriginalPlayerChunkPos() {
return originalChunkPos;
}
@Override
@Nullable
public IClientLevelWrapper getOriginalClientLevelWrapper() {
return ClientLevelWrapper.getWrapper(originalLevel, false);
}
@Override
@Nullable
public Vec3d getOriginalCameraPos() {
return originalCameraPos;
}
}
#endif
@@ -2,14 +2,16 @@ package com.seibel.distanthorizons.common.wrappers.world;
import com.seibel.distanthorizons.api.enums.config.EDhApiLodShading;
import com.seibel.distanthorizons.api.enums.worldGeneration.EDhApiLevelType;
import com.seibel.distanthorizons.api.interfaces.block.IDhApiBiomeWrapper;
import com.seibel.distanthorizons.api.interfaces.block.IDhApiBlockStateWrapper;
import com.seibel.distanthorizons.api.interfaces.render.IDhApiCustomRenderRegister;
import com.seibel.distanthorizons.common.wrappers.McObjectConverter;
import com.seibel.distanthorizons.api.objects.DhApiResult;
import com.seibel.distanthorizons.api.objects.data.IDhApiFullDataSource;
import com.seibel.distanthorizons.common.wrappers.block.BiomeWrapper;
import com.seibel.distanthorizons.common.wrappers.block.BlockStateWrapper;
import com.seibel.distanthorizons.common.wrappers.block.ClientBlockStateColorCache;
import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
import com.seibel.distanthorizons.common.wrappers.McObjectConverter;
import com.seibel.distanthorizons.common.wrappers.level.KeyedClientLevelManager;
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftClientWrapper;
import com.seibel.distanthorizons.core.api.internal.SharedApi;
import com.seibel.distanthorizons.core.config.Config;
import com.seibel.distanthorizons.core.dataObjects.fullData.sources.FullDataSourceV2;
@@ -19,6 +21,7 @@ import com.seibel.distanthorizons.core.level.*;
import com.seibel.distanthorizons.core.level.IServerKeyedClientLevel;
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos;
import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPosMutable;
import com.seibel.distanthorizons.core.util.TimerUtil;
import com.seibel.distanthorizons.core.world.AbstractDhWorld;
import com.seibel.distanthorizons.core.wrapperInterfaces.block.IBlockStateWrapper;
@@ -27,6 +30,7 @@ import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapp
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IDimensionTypeWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IServerLevelWrapper;
import com.seibel.distanthorizons.coreapi.util.ColorUtil;
import net.minecraft.client.Minecraft;
#if MC_VER <= MC_1_12_2
import net.minecraft.util.math.Vec3d;
@@ -39,7 +43,6 @@ import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.chunk.ChunkAccess;
#endif
import com.seibel.distanthorizons.core.logging.DhLogger;
@@ -51,7 +54,6 @@ import java.io.File;
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.util.*;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
@@ -59,7 +61,6 @@ import java.util.function.Function;
#elif MC_VER <= MC_1_20_4
import net.minecraft.world.level.chunk.ChunkStatus;
#else
import net.minecraft.world.level.chunk.status.ChunkStatus;
#endif
#if MC_VER <= MC_1_12_2
@@ -86,7 +87,7 @@ public class ClientLevelWrapper implements IClientLevelWrapper
private static final Map<
#if MC_VER <= MC_1_12_2 WorldClient #else ClientLevel #endif,
WeakReference<ClientLevelWrapper>> LEVEL_WRAPPER_REF_BY_CLIENT_LEVEL = Collections.synchronizedMap(new WeakHashMap<>());
private static final IKeyedClientLevelManager KEYED_CLIENT_LEVEL_MANAGER = SingletonInjector.INSTANCE.get(IKeyedClientLevelManager.class);
private static final KeyedClientLevelManager KEYED_CLIENT_LEVEL_MANAGER = (KeyedClientLevelManager) SingletonInjector.INSTANCE.get(IKeyedClientLevelManager.class);
#if MC_VER <= MC_1_12_2
private static final Minecraft MINECRAFT = Minecraft.getMinecraft();
@@ -94,9 +95,15 @@ public class ClientLevelWrapper implements IClientLevelWrapper
private static final Minecraft MINECRAFT = Minecraft.getInstance();
#endif
private static final ThreadLocal<DhBlockPosMutable> MUTABLE_BLOCK_POS_THREAD_LOCAL = ThreadLocal.withInitial(DhBlockPosMutable::new);
private static final Timer CLIENT_CLEANUP_TIMER = TimerUtil.CreateTimer("ClientLevelTickCleanup");
private static final TimerTask CLIENT_CLEANUP_TASK = TimerUtil.createTimerTask(ClientLevelWrapper::tickCleanup);
/** how long in milliseconds can a level be unused before it's automatically unloaded */
private static final long INACTIVE_TIME_BEFORE_UNLOADED_IN_MS = 30 * 1000;
#if MC_VER <= MC_1_12_2
private final WorldClient level;
@@ -133,9 +140,9 @@ public class ClientLevelWrapper implements IClientLevelWrapper
//==================//
// instance methods //
//==================//
//======================//
// inactivity unloading //
//======================//
//region
@Override
@@ -144,69 +151,77 @@ public class ClientLevelWrapper implements IClientLevelWrapper
static
{
// 20 ticks per second (50ms interval)
// fire 20 times per second (i.e. 50ms interval)
CLIENT_CLEANUP_TIMER.scheduleAtFixedRate(CLIENT_CLEANUP_TASK, 0, 1000 / 20);
}
private void unload()
{
AbstractDhWorld world = SharedApi.getAbstractDhWorld();
if (world == null || !world.unloadLevel(this))
{
this.onUnload();
}
}
private static #if MC_VER > MC_1_12_2 ClientLevel #else WorldClient #endif clientLevel() {
return #if MC_VER > MC_1_12_2 MINECRAFT.level #else MINECRAFT.world #endif;
}
public static void tickCleanup()
{
if (clientLevel() == null)
#if MC_VER <= MC_1_12_2
WorldClient clientLevel = MINECRAFT.world;
#else
ClientLevel clientLevel = MINECRAFT.level;
#endif
if (clientLevel == null)
{
return;
}
long currentTime = System.currentTimeMillis();
long timeout = 30 * 1000;
ArrayList<ClientLevelWrapper> toUnload = new ArrayList<>();
synchronized(LEVEL_WRAPPER_REF_BY_CLIENT_LEVEL)
long currentTime = System.currentTimeMillis();
ArrayList<ClientLevelWrapper> levelsToUnload = new ArrayList<>();
synchronized(LEVEL_WRAPPER_REF_BY_CLIENT_LEVEL) // should only be run on one thread at a time, but just in case
{
for (WeakReference<ClientLevelWrapper> ref : LEVEL_WRAPPER_REF_BY_CLIENT_LEVEL.values())
{
ClientLevelWrapper wrapper = ref.get();
if (wrapper != null
&& wrapper.level != clientLevel())
ClientLevelWrapper levelWrapper = ref.get();
if (levelWrapper != null
&& levelWrapper.level != clientLevel)
{
// We use the synchronized getter to prevent race conditions with markAccessed()
if (currentTime - wrapper.getLastAccessTime() > timeout)
long inactiveTimeMs = currentTime - levelWrapper.getLastAccessTime();
if (inactiveTimeMs > INACTIVE_TIME_BEFORE_UNLOADED_IN_MS)
{
toUnload.add(wrapper);
levelsToUnload.add(levelWrapper);
}
}
}
}
for (ClientLevelWrapper wrapper : toUnload)
for (ClientLevelWrapper wrapper : levelsToUnload)
{
// Re-verify all conditions inside a synchronized block on the wrapper
// to ensure atomicity with respect to markAccessed()
synchronized(wrapper)
{
if (wrapper.level != clientLevel()
&& currentTime - wrapper.getLastAccessTime() > timeout)
long inactiveTimeMs = currentTime - wrapper.getLastAccessTime();
if (wrapper.level != clientLevel
&& inactiveTimeMs > INACTIVE_TIME_BEFORE_UNLOADED_IN_MS)
{
LOGGER.debug("Unloading level [" + wrapper.getDhIdentifier() + "] due to inactivity");
wrapper.unload();
wrapper.tryUnloadFromWorld();
}
}
}
}
//endregion
//================//
// level handling //
//================//
//region
@Override
public void setDhLevel(IDhLevel dhLevel) { this.dhLevel = dhLevel; }
@Override
public IDhLevel getDhLevel() { return this.dhLevel; }
/**
* can be used when speed is important and the same level is likely to be passed in,
* IE rendering.
@@ -218,18 +233,7 @@ public class ClientLevelWrapper implements IClientLevelWrapper
{
if (KEYED_CLIENT_LEVEL_MANAGER.isEnabled())
{
IServerKeyedClientLevel keyedLevel = null;
if (KEYED_CLIENT_LEVEL_MANAGER instanceof KeyedClientLevelManager)
{
keyedLevel = ((KeyedClientLevelManager) KEYED_CLIENT_LEVEL_MANAGER).getServerKeyedLevel(level);
}
else
{
// FIXME: If the implementation is not KeyedClientLevelManager,
// this fallback may return the key for the wrong dimension in multiverse scenarios.
keyedLevel = KEYED_CLIENT_LEVEL_MANAGER.getServerKeyedLevel();
}
IServerKeyedClientLevel keyedLevel = KEYED_CLIENT_LEVEL_MANAGER.getServerKeyedLevel(getWrapper(level, true));
if (keyedLevel != levelWrapper)
{
return getWrapper(level);
@@ -263,31 +267,28 @@ public class ClientLevelWrapper implements IClientLevelWrapper
}
// used if the client is connected to a server that defines the currently loaded level
IServerKeyedClientLevel overrideLevel = null;
if (KEYED_CLIENT_LEVEL_MANAGER instanceof KeyedClientLevelManager)
{
overrideLevel = ((KeyedClientLevelManager) KEYED_CLIENT_LEVEL_MANAGER).getServerKeyedLevel(level);
}
else
{
// FIXME: If the implementation is not KeyedClientLevelManager,
// this fallback may return the key for the wrong dimension in multiverse scenarios.
overrideLevel = KEYED_CLIENT_LEVEL_MANAGER.getServerKeyedLevel();
}
IServerKeyedClientLevel overrideLevel = KEYED_CLIENT_LEVEL_MANAGER.getServerKeyedLevel(getWrapper(level, true));
if (overrideLevel != null)
{
// if the currently loaded level wrapper doesn't match what's incoming, unload it
WeakReference<ClientLevelWrapper> levelRef = LEVEL_WRAPPER_REF_BY_CLIENT_LEVEL.get(level);
if (levelRef != null && levelRef.get() != overrideLevel)
if (levelRef != null
&& levelRef.get() != overrideLevel)
{
ClientLevelWrapper l = levelRef.get();
if (l != null) l.unload();
ClientLevelWrapper levelWrapper = levelRef.get();
if (levelWrapper != null)
{
levelWrapper.tryUnloadFromWorld();
}
levelRef = null;
}
if (levelRef == null && overrideLevel instanceof ClientLevelWrapper)
if (levelRef == null
&& overrideLevel instanceof ClientLevelWrapper)
{
LEVEL_WRAPPER_REF_BY_CLIENT_LEVEL.put(level, new WeakReference<>((ClientLevelWrapper) overrideLevel));
}
return overrideLevel;
}
}
@@ -372,7 +373,9 @@ public class ClientLevelWrapper implements IClientLevelWrapper
//region
@Override
public int getBlockColor(DhBlockPos blockPos, IBiomeWrapper biome, FullDataSourceV2 fullDataSource, IBlockStateWrapper blockWrapper)
public int getBlockColor(
DhBlockPos blockWorldPos, IBiomeWrapper biome, FullDataSourceV2 fullDataSource, IBlockStateWrapper blockWrapper,
boolean allowApiOverride)
{
ClientBlockStateColorCache blockColorCache = this.blockColorCacheByBlockState.get(((BlockStateWrapper) blockWrapper).blockState);
if (blockColorCache == null)
@@ -382,7 +385,7 @@ public class ClientLevelWrapper implements IClientLevelWrapper
this.createCachedBlockColorCacheFunc);
}
return blockColorCache.getColor((BiomeWrapper) biome, fullDataSource, blockPos);
return blockColorCache.getColor((BiomeWrapper) biome, fullDataSource, blockWorldPos, allowApiOverride);
}
@Override
@@ -406,7 +409,14 @@ public class ClientLevelWrapper implements IClientLevelWrapper
}
@Override
public void clearBlockColorCache() { this.blockColorCacheByBlockState.clear(); }
public void clearBlockColorCache()
{
this.blockColorCacheByBlockState.clear();
// this technically only needs to be called once globally, but it's easier
// to handle here statically
ClientBlockStateColorCache.clearCachedTints();
}
private IDimensionTypeWrapper dimensionTypeWrapper = null;
@Override
@@ -547,6 +557,15 @@ public class ClientLevelWrapper implements IClientLevelWrapper
@Override
public #if MC_VER <= MC_1_12_2 WorldClient #else ClientLevel #endif getWrappedMcObject() { return this.level; }
private void tryUnloadFromWorld()
{
AbstractDhWorld world = SharedApi.getAbstractDhWorld();
if (world == null
|| !world.unloadLevel(this))
{
this.onUnload();
}
}
@Override
public void onUnload()
{
@@ -565,20 +584,54 @@ public class ClientLevelWrapper implements IClientLevelWrapper
return this.dhLevel.getSaveStructure().getSaveFolder(this);
}
@Override
public DhApiResult<Color> getBlockColorPreApi(
IDhApiBlockStateWrapper blockStateWrapper,
IDhApiBiomeWrapper biomeWrapper,
int blockWorldPosX, int blockWorldPosY, int blockWorldPosZ,
IDhApiFullDataSource dataSource)
{
// cast to core objects //
//region
if(!(blockStateWrapper instanceof IBlockStateWrapper coreBlockStateWrapper))
{
return DhApiResult.createFail("Unable to cast ["+blockStateWrapper.getClass()+"] to ["+IBlockStateWrapper.class+"]");
}
if(!(biomeWrapper instanceof IBiomeWrapper coreBiomeWrapper))
{
return DhApiResult.createFail("Unable to cast ["+biomeWrapper.getClass()+"] to ["+IBiomeWrapper.class+"]");
}
if(!(dataSource instanceof FullDataSourceV2 coreDataSource))
{
return DhApiResult.createFail("Unable to cast ["+dataSource.getClass()+"] to ["+FullDataSourceV2.class+"]");
}
//endregion
// use a mutable thread local to reduce allocations slightly
DhBlockPosMutable blockWorldPos = MUTABLE_BLOCK_POS_THREAD_LOCAL.get();
blockWorldPos.setX(blockWorldPosX);
blockWorldPos.setY(blockWorldPosY);
blockWorldPos.setZ(blockWorldPosZ);
int color = this.getBlockColor(blockWorldPos, coreBiomeWrapper, coreDataSource, coreBlockStateWrapper, false);
return DhApiResult.createSuccess(ColorUtil.toColorObjARGB(color));
}
//endregion
//===================//
// generic rendering //
//===================//
//===========//
// rendering //
//===========//
//region
@Override
public void setDhLevel(IDhLevel dhLevel) { this.dhLevel = dhLevel; }
@Override
public IDhLevel getDhLevel() { return this.dhLevel; }
@Override
public IDhApiCustomRenderRegister getRenderRegister()
{
@@ -19,6 +19,7 @@
package com.seibel.distanthorizons.common.wrappers.world;
import java.awt.*;
import java.io.File;
import java.lang.ref.WeakReference;
import java.util.Collections;
@@ -26,21 +27,30 @@ import java.util.Map;
import java.util.WeakHashMap;
import com.seibel.distanthorizons.api.enums.worldGeneration.EDhApiLevelType;
import com.seibel.distanthorizons.api.interfaces.block.IDhApiBiomeWrapper;
import com.seibel.distanthorizons.api.interfaces.block.IDhApiBlockStateWrapper;
import com.seibel.distanthorizons.api.interfaces.render.IDhApiCustomRenderRegister;
import com.seibel.distanthorizons.api.objects.DhApiResult;
import com.seibel.distanthorizons.api.objects.data.IDhApiFullDataSource;
import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
import com.seibel.distanthorizons.core.api.internal.SharedApi;
import com.seibel.distanthorizons.core.config.Config;
import com.seibel.distanthorizons.core.dataObjects.fullData.sources.FullDataSourceV2;
import com.seibel.distanthorizons.core.level.IDhLevel;
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import com.seibel.distanthorizons.core.network.messages.base.LevelInitMessage;
import com.seibel.distanthorizons.core.pos.DhChunkPos;
import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPosMutable;
import com.seibel.distanthorizons.core.world.EWorldEnvironment;
import com.seibel.distanthorizons.core.wrapperInterfaces.block.IBlockStateWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IBiomeWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IServerLevelWrapper;
#if MC_VER <= MC_1_12_2
import net.minecraft.world.WorldServer;
#else
import com.seibel.distanthorizons.coreapi.util.ColorUtil;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.chunk.ChunkAccess;
@@ -73,13 +83,14 @@ public class ServerLevelWrapper implements IServerLevelWrapper
* this name is cached to prevent issues during shutdown where
* the server variables needed may no longer be available.
*/
private final String KeyedLevelDimensionName;
private final String keyedLevelDimensionName;
//==============//
// constructors //
//==============//
//region
public static ServerLevelWrapper getWrapper(#if MC_VER <= MC_1_12_2 WorldServer #else ServerLevel #endif level)
{
@@ -101,14 +112,17 @@ public class ServerLevelWrapper implements IServerLevelWrapper
public ServerLevelWrapper(#if MC_VER <= MC_1_12_2 WorldServer #else ServerLevel #endif level)
{
this.level = level;
this.KeyedLevelDimensionName = this.createKeyedLevelDimensionName();
this.keyedLevelDimensionName = this.createKeyedLevelDimensionName();
}
//endregion
//==================//
// instance methods //
//==================//
//region
@Override
public File getMcSaveFolder()
@@ -123,7 +137,7 @@ public class ServerLevelWrapper implements IServerLevelWrapper
}
@Override
public String getKeyedLevelDimensionName() { return this.KeyedLevelDimensionName; }
public String getKeyedLevelDimensionName() { return this.keyedLevelDimensionName; }
private String createKeyedLevelDimensionName()
{
@@ -293,14 +307,28 @@ public class ServerLevelWrapper implements IServerLevelWrapper
return this.dhLevel.getSaveStructure().getSaveFolder(this);
}
@Override
public DhApiResult<Color> getBlockColorPreApi(
IDhApiBlockStateWrapper blockStateWrapper,
IDhApiBiomeWrapper biomeWrapper,
int blockWorldPosX, int blockWorldPosY, int blockWorldPosZ,
IDhApiFullDataSource dataSource)
{ return DhApiResult.createFail("["+ServerLevelWrapper.class.getSimpleName()+"]'s cannot get block colors, please use a ["+ClientLevelWrapper.class.getSimpleName()+"] instead."); }
//endregion
//================//
// base overrides //
//================//
//region
@Override
public String toString() { return "Wrapped{" + this.level.toString() + "@" + this.getDhIdentifier() + "}"; }
//endregion
}
@@ -77,6 +77,7 @@ import net.minecraft.world.level.chunk.*;
import net.minecraft.world.level.levelgen.DebugLevelSource;
import net.minecraft.world.level.levelgen.FlatLevelSource;
import net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator;
import net.minecraft.world.level.levelgen.Heightmap;
#endif
@@ -672,12 +673,16 @@ public final class BatchGenerationEnvironment implements IBatchGeneratorEnvironm
return;
}
// throwIfThreadInterrupted();
// // caves can generally be ignored since they aren't generally visible from far away
// if (step == EDhApiWorldGenerationStep.CARVERS)
// {
// return;
// }
// carvers heightmaps are needed by some world gen mods,
// otherwise unexpected issues may occur
// (like trying to use an empty heightmap and walking out the bottom of
// the world looking for a valid snow location).
throwIfThreadInterrupted();
for (ChunkWrapper chunkWrapper : chunkWrappersToGenerate)
{
ChunkAccess chunk = chunkWrapper.getChunk();
Heightmap.primeHeightmaps(chunk, ChunkStatus.CARVERS.heightmapsAfter());
}
throwIfThreadInterrupted();
this.stepFeatures.generateGroup(genEvent.threadedParam, region, GetCutoutFrom(chunkWrappersToGenerate, EDhApiWorldGenerationStep.FEATURES));
@@ -31,6 +31,9 @@ import net.minecraft.world.WorldServer;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.gen.ChunkProviderServer;
import net.minecraftforge.common.ForgeChunkManager;
import net.minecraft.server.MinecraftServer;
import net.minecraft.world.chunk.storage.AnvilChunkLoader;
import net.minecraft.world.storage.ThreadedFileIOBase;
#else
import net.minecraft.server.level.ChunkHolder;
import net.minecraft.server.level.ServerLevel;
@@ -47,6 +50,7 @@ import net.minecraft.world.level.chunk.status.ChunkStatus;
#endif
import java.util.*;
import java.util.concurrent.CancellationException;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException;
import java.util.function.Function;
@@ -91,7 +95,9 @@ public class InternalServerGenerator
@Nullable
private final ChunkUpdateQueueManager updateManager;
private final Timer chunkSaveIgnoreTimer = TimerUtil.CreateTimer("ChunkSaveIgnoreTimer");
#if MC_VER <= MC_1_12_2
private static final java.util.concurrent.Semaphore chunkRequestSemaphore = new java.util.concurrent.Semaphore(20);
#endif
//=============//
@@ -128,11 +134,29 @@ public class InternalServerGenerator
#endif
{
#if MC_VER <= MC_1_12_2
while (!isServerHealthy())
{
try
{
// Don't submit request until server tps is healthy
Thread.sleep(50);
}
catch (InterruptedException e)
{
throw new CancellationException("Interrupted while waiting for server");
}
}
#endif
Iterator<ChunkPos> chunkPosIterator = ChunkPosGenStream.getIterator(genEvent.minPos.getX(), genEvent.minPos.getZ(), genEvent.widthInChunks, 0);
while (chunkPosIterator.hasNext())
{
ChunkPos chunkPos = chunkPosIterator.next();
#if MC_VER <= MC_1_12_2
chunkRequestSemaphore.acquireUninterruptibly();
#endif
#if MC_VER <= MC_1_12_2
CompletableFuture<Chunk> requestChunkFuture;
#else
@@ -145,6 +169,9 @@ public class InternalServerGenerator
.whenCompleteAsync(
(chunk, throwable) ->
{
#if MC_VER <= MC_1_12_2
chunkRequestSemaphore.release();
#endif
// unwrap the CompletionException if necessary
Throwable actualThrowable = throwable;
while (actualThrowable instanceof CompletionException)
@@ -155,9 +182,9 @@ public class InternalServerGenerator
if (actualThrowable != null)
{
// ignore expected shutdown exceptions
boolean isShutdownException =
boolean isShutdownException =
ExceptionUtil.isShutdownException(actualThrowable)
|| actualThrowable.getMessage().contains("Unloaded chunk");
|| actualThrowable.getMessage().contains("Unloaded chunk");
if (!isShutdownException)
{
CHUNK_LOAD_LOGGER.warn("DistantHorizons: Couldn't load chunk [" + chunkPos + "] from server, error: [" + actualThrowable.getMessage() + "].", actualThrowable);
@@ -224,6 +251,9 @@ public class InternalServerGenerator
finally
{
ArrayList<CompletableFuture<Void>> releaseFutures = new ArrayList<>();
#if MC_VER <= MC_1_12_2
Set<Long> neighborIgnoreSet = new HashSet<>();
#endif
// release all chunks from the server to prevent out of memory issues
Iterator<ChunkPos> chunkPosIterator = ChunkPosGenStream.getIterator(genEvent.minPos.getX(), genEvent.minPos.getZ(), genEvent.widthInChunks, 0);
@@ -231,7 +261,28 @@ public class InternalServerGenerator
{
ChunkPos chunkPos = chunkPosIterator.next();
releaseFutures.add(this.releaseChunkFromServerAsync(this.params.mcServerLevel, chunkPos));
#if MC_VER <= MC_1_12_2
// collect unique neighbor positions for release and ignore removal
for (int dx = -1; dx <= 1; dx++)
{
for (int dz = -1; dz <= 1; dz++)
{
if (dx == 0 && dz == 0) continue;
neighborIgnoreSet.add(ChunkPos.asLong(chunkPos.x + dx, chunkPos.z + dz));
}
}
#endif
}
#if MC_VER <= MC_1_12_2
// release neighbor chunks that were loaded in requestChunkFromServerAsync
for (long posLong : neighborIgnoreSet)
{
ChunkPos neighborPos = new ChunkPos(ChunkPos.getX(posLong), ChunkPos.getZ(posLong));
releaseFutures.add(this.releaseChunkFromServerAsync(this.params.mcServerLevel, neighborPos));
}
#endif
// wait for all release futures to finish to prevent an issue where DH queues
// tickets faster than MC can clear them out
@@ -240,6 +291,45 @@ public class InternalServerGenerator
CompletableFuture<Void> releaseFuture = releaseFutures.get(i);
releaseFuture.join();
}
// tick after all unloads are queued
#if MC_VER <= MC_1_12_2
CompletableFuture<Void> tickFuture = new CompletableFuture<>();
this.params.mcServerLevel.getMinecraftServer().addScheduledTask(() ->
{
try
{
ChunkProviderServer provider = this.params.mcServerLevel.getChunkProvider();
while (!provider.droppedChunks.isEmpty())
{
provider.tick();
}
}
finally
{
tickFuture.complete(null);
}
});
tickFuture.join();
#endif
#if MC_VER <= MC_1_12_2
for (long posLong : neighborIgnoreSet)
{
ChunkPos neighborPos = new ChunkPos(ChunkPos.getX(posLong), ChunkPos.getZ(posLong));
this.chunkSaveIgnoreTimer.schedule(new TimerTask()
{
@Override
public void run()
{
if (InternalServerGenerator.this.updateManager != null)
{
InternalServerGenerator.this.updateManager.removePosToIgnore(McObjectConverter.Convert(neighborPos));
}
}
}, MS_TO_IGNORE_CHUNK_AFTER_COMPLETION);
}
#endif
}
}
private void runValidation()
@@ -251,7 +341,7 @@ public class InternalServerGenerator
throw new IllegalStateException("Internal server generation should be called from one of DH's world gen thread. Current thread: ["+Thread.currentThread().getName()+"]");
}
#if MC_VER > MC_1_12_2
// C2ME present?
if (C2ME_ACCESSOR == null
&& !c2meMissingWarningLogged)
@@ -274,6 +364,7 @@ public class InternalServerGenerator
LOGGER.warn(c2meWarning);
}
#endif
}
#if MC_VER <= MC_1_12_2
private CompletableFuture<Chunk> requestChunkFromServerAsync(ChunkPos chunkPos)
@@ -289,24 +380,25 @@ public class InternalServerGenerator
{
this.updateManager.addPosToIgnore(McObjectConverter.Convert(chunkPos));
}
CompletableFuture<Chunk> future = new CompletableFuture<>();
level.getMinecraftServer().addScheduledTask(() ->
{
ChunkProviderServer provider = level.getChunkProvider();
// load neighbors first so the target chunk can fully populate
for (int i = -1; i <= 1; i++)
for (int dx = -1; dx <= 1; dx++)
{
for (int j = -1; j <= 1; j++)
for (int dz = -1; dz <= 1; dz++)
{
if (i != 0 || j != 0)
if (dx == 0 && dz == 0) continue;
if (this.updateManager != null)
{
if (this.updateManager != null)
{
this.updateManager.addPosToIgnore(new DhChunkPos(chunkPos.x + i, chunkPos.z + j));
}
provider.provideChunk(chunkPos.x + i, chunkPos.z + j);
this.updateManager.addPosToIgnore(new DhChunkPos(chunkPos.x + dx, chunkPos.z + dz));
}
if (provider.getLoadedChunk(chunkPos.x + dx, chunkPos.z + dz) == null)
{
provider.provideChunk(chunkPos.x + dx, chunkPos.z + dz);
}
}
}
@@ -345,14 +437,16 @@ public class InternalServerGenerator
throw new IllegalStateException("No chunk chunkHolder for pos ["+chunkPos+"] after ticket has been added.");
}
// Note: ChunkStatus.FEATURES would be slightly faster than FULL, but can cause issues
// with other mods where they need lighting/full chunk data.
#if MC_VER <= MC_1_20_4
return chunkHolder.getOrScheduleFuture(ChunkStatus.FEATURES, level.getChunkSource().chunkMap)
return chunkHolder.getOrScheduleFuture(ChunkStatus.FULL, level.getChunkSource().chunkMap)
.thenApply(result -> result.left().orElseThrow(() -> new RuntimeException(result.right().get().toString()))); // can throw if the server is shutting down
#elif MC_VER <= MC_1_20_6
return chunkHolder.getOrScheduleFuture(ChunkStatus.FEATURES, level.getChunkSource().chunkMap)
return chunkHolder.getOrScheduleFuture(ChunkStatus.FULL, level.getChunkSource().chunkMap)
.thenApply(result -> result.orElseThrow(() -> new RuntimeException(result.toString()))); // can throw if the server is shutting down
#else
return chunkHolder.scheduleChunkGenerationTask(ChunkStatus.FEATURES, level.getChunkSource().chunkMap)
return chunkHolder.scheduleChunkGenerationTask(ChunkStatus.FULL, level.getChunkSource().chunkMap)
.thenApply(result -> result.orElseThrow(() -> new RuntimeException(result.getError()))); // can throw if the server is shutting down
#endif
@@ -380,32 +474,12 @@ public class InternalServerGenerator
try
{
#if MC_VER <= MC_1_12_2
for (int difX = -1; difX <= 1; difX++)
ChunkProviderServer provider = level.getChunkProvider();
Chunk chunk = provider.getLoadedChunk(chunkPos.x, chunkPos.z);
if (chunk != null)
{
for (int difZ = -1; difZ <= 1; difZ++)
{
if (difX != 0 || difZ != 0)
{
final int finalDifX = difX;
final int finalDifZ = difZ;
this.chunkSaveIgnoreTimer.schedule(new TimerTask()
{
@Override
public void run()
{
if (InternalServerGenerator.this.updateManager != null)
{
InternalServerGenerator.this.updateManager.removePosToIgnore(
new DhChunkPos(
chunkPos.x + finalDifX,
chunkPos.z + finalDifZ
)
);
}
}
}, MS_TO_IGNORE_CHUNK_AFTER_COMPLETION);
}
}
provider.queueUnload(chunk);
}
#elif MC_VER < MC_1_21_5
int chunkLevel = 33; // 33 is equivalent to FULL Chunk
@@ -428,7 +502,7 @@ public class InternalServerGenerator
this.chunkSaveIgnoreTimer.schedule(new TimerTask()
{
@Override
public void run()
public void run()
{
if (InternalServerGenerator.this.updateManager != null)
{
@@ -452,4 +526,25 @@ public class InternalServerGenerator
//======//
// misc //
//======//
#if MC_VER <= MC_1_12_2
private boolean isServerHealthy()
{
if(this.params.mcServerLevel.getMinecraftServer() == null) { return false; }
long[] ticks = this.params.mcServerLevel.getMinecraftServer().tickTimeArray;
long[] sorted = ticks.clone();
Arrays.sort(sorted);
int p99Index = (int)Math.ceil(0.99 * sorted.length) - 1;
double p99Ms = sorted[Math.max(0, p99Index)] * 1e-6;
double avgMs = Arrays.stream(sorted).average().orElse(0) * 1e-6;
return avgMs < 20.0 && p99Ms < 50.0;
}
#endif
}
@@ -94,7 +94,7 @@ public class DhLitWorldGenRegion extends WorldGenRegion
public final int size;
private final DhChunkPos firstPos;
private final List<ChunkAccess> cache;
private final List<ChunkAccess> chunkCacheList;
private final Long2ObjectOpenHashMap<ChunkAccess> chunkMap = new Long2ObjectOpenHashMap<ChunkAccess>();
/**
@@ -158,7 +158,7 @@ public class DhLitWorldGenRegion extends WorldGenRegion
this.generator = generator;
this.lightEngine = lightEngine;
this.writeRadius = writeRadius;
this.cache = chunkList;
this.chunkCacheList = chunkList;
this.size = Mth.floor(Math.sqrt(chunkList.size()));
}
@@ -294,6 +294,24 @@ public class DhLitWorldGenRegion extends WorldGenRegion
{
int chunkX = SectionPos.blockToSectionCoord(blockPos.getX());
int chunkZ = SectionPos.blockToSectionCoord(blockPos.getZ());
// No one should be trying to a block pos 1 million blocks
// above or below the world height.
// If that happens that likely means a mod is assuming DH populated the
// world/chunk in a certain way and that assumption isn't being met.
if (blockPos.getY() < -1_000_000
|| blockPos.getY() > 1_000_000)
{
// Throwing an exception here is done to break out of potential
// infinite loops where a mod attempts to walk down the level to find a specific block type.
// Example from WilderWild:
// https://github.com/FrozenBlock/WilderWild/blob/1eaaaa2179d837aac6ece002ff795eed665cd7b7/src/main/java/net/frozenblock/wilderwild/worldgen/impl/feature/SnowBlanketFeature.java#L95
throw new ArrayIndexOutOfBoundsException(
"Attempted to getBlockState outside the DH defined Y bounds [-1_000_000, 1_000_000]: ["+blockPos+"]. " +
"This is likely a mod compatibility issue, " +
"there is no reason to try getting a block this far outside the world during world gen.");
}
return this.getChunk(chunkX, chunkZ).getBlockState(blockPos);
}
@@ -366,8 +384,14 @@ public class DhLitWorldGenRegion extends WorldGenRegion
*/
private ChunkAccess getChunkAccess(int chunkX, int chunkZ, ChunkStatus chunkStatus, boolean returnNonNull)
{
ChunkAccess chunk = this.superHasChunk(chunkX, chunkZ) ? this.superGetChunk(chunkX, chunkZ) : null;
if (chunk != null && ChunkWrapper.getStatus(chunk).isOrAfter(chunkStatus))
ChunkAccess chunk = null;
if (this.dhHasChunk(chunkX, chunkZ))
{
chunk = this.dhGetChunk(chunkX, chunkZ);
}
if (chunk != null
&& ChunkWrapper.getStatus(chunk).isOrAfter(chunkStatus))
{
return chunk;
}
@@ -417,7 +441,7 @@ public class DhLitWorldGenRegion extends WorldGenRegion
}
/** Use this instead of super.hasChunk() to bypass C2ME concurrency checks */
public boolean superHasChunk(int x, int z)
public boolean dhHasChunk(int x, int z)
{
int xOffset = x - this.firstPos.getX();
int zOffset = z - this.firstPos.getZ();
@@ -426,11 +450,11 @@ public class DhLitWorldGenRegion extends WorldGenRegion
}
/** Use this instead of super.getChunk() to bypass C2ME concurrency checks */
private ChunkAccess superGetChunk(int x, int z)
private ChunkAccess dhGetChunk(int x, int z)
{
int xOffset = x - this.firstPos.getX();
int zOffset = z - this.firstPos.getZ();
return this.cache.get(xOffset + zOffset * this.size);
return this.chunkCacheList.get(xOffset + zOffset * this.size);
}
@@ -1,3 +1,6 @@
public net.minecraft.client.renderer.EntityRenderer getFOVModifier(FZ)F
public net.minecraft.client.renderer.ActiveRenderInfo MODELVIEW
public net.minecraft.client.renderer.ActiveRenderInfo PROJECTION
public net.minecraft.client.renderer.ActiveRenderInfo PROJECTION
public net.minecraft.client.gui.GuiSlot amountScrolled
public net.minecraft.world.gen.ChunkProviderServer droppedChunks
public net.minecraft.world.chunk.Chunk dirty
+2
View File
@@ -4,7 +4,9 @@ Thanks for your interest in contributing to Distant Horizons!
Check out the [Core Wiki](https://gitlab.com/jeseibel/distant-horizons-core/-/wikis/home) for a rough overview of Distant Horizon's project structure.
## Translations
See [translations.md](translations.md) for the Crowdin workflow.
## Submitting a merge request
+8
View File
@@ -0,0 +1,8 @@
project_id_env: CROWDIN_PROJECT_ID
api_token_env: CROWDIN_PERSONAL_TOKEN
base_path: ./coreSubProjects/core/src/main/resources/assets/distanthorizons/lang
preserve_hierarchy: true
files:
- source: /en_us.json
translation: /%locale_with_underscore%.json
type: json
+5 -2
View File
@@ -17,8 +17,11 @@ dependencies {
modImplementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}"
// Fabric API (bundled as jar-in-jar so users don't need to install it separately)
modImplementation "net.fabricmc.fabric-api:fabric-api:${rootProject.fabric_api_version}"
include "net.fabricmc.fabric-api:fabric-api:${rootProject.fabric_api_version}"
modImplementation ("net.fabricmc.fabric-api:fabric-api:${rootProject.fabric_api_version}")
include ("net.fabricmc.fabric-api:fabric-api:${rootProject.fabric_api_version}") {
// including the gametest API can cause issues for other mods if included in our jar
exclude module: "fabric-gametest-api-v1"
}
// Mod Menu
addMod("com.terraformersmc:modmenu:${rootProject.modmenu_version}", rootProject.enable_mod_menu)
@@ -32,7 +32,7 @@ import com.seibel.distanthorizons.core.api.internal.SharedApi;
import com.seibel.distanthorizons.core.dependencyInjection.ModAccessorInjector;
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import com.seibel.distanthorizons.core.util.math.Mat4f;
import com.seibel.distanthorizons.core.util.math.DhMat4f;
import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IPluginPacketSender;
@@ -98,9 +98,6 @@ public class FabricClientProxy implements AbstractModInitializer.IEventProxy
private static final MinecraftClientWrapper MC = MinecraftClientWrapper.INSTANCE;
private static final AbstractPluginPacketSender PACKET_SENDER = (AbstractPluginPacketSender) SingletonInjector.INSTANCE.get(IPluginPacketSender.class);
@Deprecated // just use the static reference
private static final ClientApi clientApi = ClientApi.INSTANCE;
HashSet<Integer> previouslyPressKeyCodes = new HashSet<>();
@@ -244,7 +241,7 @@ public class FabricClientProxy implements AbstractModInitializer.IEventProxy
ClientApi.RENDER_STATE.clientLevelWrapper = ClientLevelWrapper.getWrapperIfDifferent(ClientApi.RENDER_STATE.clientLevelWrapper, renderContext.world());
this.clientApi.renderLods();
ClientApi.INSTANCE.renderLods();
});
@@ -267,7 +264,7 @@ public class FabricClientProxy implements AbstractModInitializer.IEventProxy
ClientApi.RENDER_STATE.clientLevelWrapper = ClientLevelWrapper.getWrapperIfDifferent(ClientApi.RENDER_STATE.clientLevelWrapper, renderContext.world());
this.clientApi.renderFadeOpaque();
ClientApi.INSTANCE.renderFadeOpaque();
});
WorldRenderEvents.AFTER_TRANSLUCENT.register((renderContext) ->
@@ -297,7 +294,7 @@ public class FabricClientProxy implements AbstractModInitializer.IEventProxy
ClientApi.INSTANCE.renderDeferredLodsForShaders();
#endif
this.clientApi.renderFadeTransparent();
ClientApi.INSTANCE.renderFadeTransparent();
});
#endif
@@ -327,10 +324,11 @@ public class FabricClientProxy implements AbstractModInitializer.IEventProxy
// FIXME: Use better hooks so it doesn't trigger key press events in text boxes
ClientTickEvents.END_CLIENT_TICK.register(client ->
{
if (client.player != null && !(Minecraft.getInstance().screen instanceof TitleScreen))
{
this.onKeyInput();
}
// TODO
//if (client.player != null && !(Minecraft.getInstance().screen instanceof TitleScreen))
//{
// this.onKeyInput();
//}
});
//endregion
@@ -1,11 +1,8 @@
package com.seibel.distanthorizons.fabric;
import com.seibel.distanthorizons.api.DhApi;
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiBlockColorOverrideEvent;
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiBlockStateWrapperCreatedEvent;
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiChunkProcessingEvent;
import com.seibel.distanthorizons.api.methods.events.abstractEvents.*;
import com.seibel.distanthorizons.api.methods.events.DhApiEventRegister;
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiLevelLoadEvent;
import com.seibel.distanthorizons.common.AbstractModInitializer;
import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
import com.seibel.distanthorizons.common.wrappers.misc.ServerPlayerWrapper;
@@ -18,10 +15,7 @@ import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IPluginPacketSender;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
import com.seibel.distanthorizons.fabric.testing.TestBlockWrapperCreatedEvent;
import com.seibel.distanthorizons.fabric.testing.TestChunkInputReplacerEvent;
import com.seibel.distanthorizons.fabric.testing.TestCustomColorEvent;
import com.seibel.distanthorizons.fabric.testing.TestWorldGenBindingEvent;
import com.seibel.distanthorizons.fabric.testing.*;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerChunkEvents;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents;
@@ -106,6 +100,12 @@ public class FabricServerProxy implements AbstractModInitializer.IEventProxy
DhApi.events.bind(DhApiBlockColorOverrideEvent.class, new TestCustomColorEvent());
DhApi.events.bind(DhApiBlockStateWrapperCreatedEvent.class, new TestBlockWrapperCreatedEvent());
}
// test fog override
if (false)
{
DhApi.events.bind(DhApiBeforeFogRenderEvent.class, new TestFogRenderEvent());
}
}
@@ -1,76 +0,0 @@
/*
* This file is part of the Distant Horizons mod
* licensed under the GNU LGPL v3 License.
*
* Copyright (C) 2020 James Seibel
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.seibel.distanthorizons.fabric.mixins.client;
#if MC_VER <= MC_1_19_2
import com.mojang.math.Matrix4f;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
@Mixin(Matrix4f.class)
public interface AccessorMatrix4f
{
@Accessor("m00")
void setM00(float v);
@Accessor("m01")
void setM01(float v);
@Accessor("m02")
void setM02(float v);
@Accessor("m03")
void setM03(float v);
@Accessor("m10")
void setM10(float v);
@Accessor("m11")
void setM11(float v);
@Accessor("m12")
void setM12(float v);
@Accessor("m13")
void setM13(float v);
@Accessor("m20")
void setM20(float v);
@Accessor("m21")
void setM21(float v);
@Accessor("m22")
void setM22(float v);
@Accessor("m23")
void setM23(float v);
@Accessor("m30")
void setM30(float v);
@Accessor("m31")
void setM31(float v);
@Accessor("m32")
void setM32(float v);
@Accessor("m33")
void setM33(float v);
}
#else
import net.minecraft.world.entity.Entity;
import org.spongepowered.asm.mixin.Mixin;
@Mixin(Entity.class)
public interface AccessorMatrix4f
{ /* not present in newer MC versions */ }
#endif
@@ -93,7 +93,10 @@ public class MixinChunkSectionsToRender
@Inject(at = @At("HEAD"), method = "renderGroup", order = 800)
private void renderDeferredLayerHead(ChunkSectionLayerGroup chunkSectionLayerGroup, GpuSampler gpuSampler, CallbackInfo ci)
{
#if MC_VER <= MC_26_1_2
ClientApi.RENDER_STATE.clientLevelWrapper = ClientLevelWrapper.getWrapperIfDifferent(ClientApi.RENDER_STATE.clientLevelWrapper, Minecraft.getInstance().levelRenderer.level);
#else
#endif
ClientApi.RENDER_STATE.canRenderOrThrow();
@@ -33,7 +33,7 @@ public class MixinClientPacketListener
{
ClientApi.INSTANCE.onClientOnlyConnected();
}
#if MC_VER < MC_1_19_4
@Inject(method = "cleanup", at = @At("HEAD"))
#else
@@ -61,11 +61,11 @@ public class MixinClientPacketListener
}
// Important to get the level from the chunk because the client level might be different if Immersive Portals is present.
ClientLevel level = (ClientLevel) chunk.getLevel();
ClientLevel clientLevel = (ClientLevel) chunk.getLevel();
executor.execute(() ->
{
IClientLevelWrapper clientLevel = ClientLevelWrapper.getWrapper(level);
SharedApi.INSTANCE.applyChunkUpdate(new ChunkWrapper(chunk, clientLevel), clientLevel);
IClientLevelWrapper clientLevelWrapper = ClientLevelWrapper.getWrapper(clientLevel);
SharedApi.INSTANCE.applyChunkUpdate(new ChunkWrapper(chunk, clientLevelWrapper), clientLevelWrapper);
});
}
@@ -29,8 +29,11 @@ public class MixinGameRenderer {}
#else
import com.mojang.blaze3d.vertex.PoseStack;
import com.seibel.distanthorizons.common.wrappers.McObjectConverter;
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 net.minecraft.client.DeltaTracker;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.client.player.LocalPlayer;
import net.minecraft.client.renderer.GameRenderer;
import net.minecraft.client.renderer.state.OptionsRenderState;
@@ -71,6 +74,16 @@ public class MixinGameRenderer
final Matrix4f projectionMatrix,
final PoseStack poseStack)
{
#if MC_VER <= MC_26_1_2
#else
ClientApi.RENDER_STATE.clientLevelWrapper = ClientLevelWrapper.getWrapperIfDifferent(ClientApi.RENDER_STATE.clientLevelWrapper, (ClientLevel)player.level());
ClientApi.RENDER_STATE.mcModelViewMatrix = McObjectConverter.Convert(modelViewMatrix);
ClientApi.RENDER_STATE.partialTickTime = MinecraftRenderWrapper.INSTANCE.getPartialTickTime();
#endif
ClientApi.RENDER_STATE.mcProjectionMatrix = McObjectConverter.Convert(projectionMatrix);
}
}
@@ -18,8 +18,6 @@ public class MixinImmersivePortalsRenderStates
@Inject(method = "updatePreRenderInfo", at = @At("HEAD"))
private static void preRender(CallbackInfo ci)
{
MixinImmersivePortalsRenderStatesCommon.saveVolatileOriginals();
}
{ MixinImmersivePortalsRenderStatesCommon.saveVolatileOriginals(); }
}
@@ -20,14 +20,15 @@
package com.seibel.distanthorizons.fabric.mixins.client;
#if MC_VER < MC_1_19_4
import com.seibel.distanthorizons.core.util.math.Mat4f;
import com.seibel.distanthorizons.core.util.math.DhMat4f;
import com.seibel.distanthorizons.core.util.math.DhVec3f;
import net.minecraft.client.renderer.RenderType;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.math.Matrix4f;
import org.lwjgl.opengl.GL32;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
#elif MC_VER < MC_1_21_6
import com.seibel.distanthorizons.core.util.math.Mat4f;
import com.seibel.distanthorizons.core.util.math.DhMat4f;
import net.minecraft.client.renderer.RenderType;
import com.mojang.blaze3d.vertex.PoseStack;
import org.joml.Matrix4f;
@@ -36,7 +37,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import com.mojang.blaze3d.buffers.GpuBufferSlice;
import com.mojang.blaze3d.framegraph.FrameGraphBuilder;
import com.mojang.blaze3d.resource.GraphicsResourceAllocator;
import com.seibel.distanthorizons.core.util.math.Mat4f;
import com.seibel.distanthorizons.core.util.math.DhMat4f;
import net.minecraft.client.Camera;
import net.minecraft.client.DeltaTracker;
import net.minecraft.client.renderer.chunk.ChunkSectionsToRender;
@@ -94,8 +95,11 @@ import com.seibel.distanthorizons.core.logging.DhLogger;
@Mixin(LevelRenderer.class)
public class MixinLevelRenderer
{
#if MC_VER <= MC_26_1_2
@Shadow
private ClientLevel level;
#else
#endif
@Unique
private static final DhLogger LOGGER = new DhLoggerBuilder().build();
@@ -149,7 +153,7 @@ public class MixinLevelRenderer
// get the matrices from the OpenGL fixed pipeline
float[] mcProjMatrixRaw = new float[16];
GL32.glGetFloatv(GL32.GL_PROJECTION_MATRIX, mcProjMatrixRaw);
ClientApi.RENDER_STATE.mcProjectionMatrix = new Mat4f(mcProjMatrixRaw);
ClientApi.RENDER_STATE.mcProjectionMatrix = new DhMat4f(mcProjMatrixRaw);
ClientApi.RENDER_STATE.mcProjectionMatrix.transpose();
ClientApi.RENDER_STATE.mcModelViewMatrix = McObjectConverter.Convert(matrixStackIn.last().pose());
@@ -161,7 +165,7 @@ public class MixinLevelRenderer
#elif MC_VER < MC_1_21_9
// MC combined the model view and projection matricies
ClientApi.RENDER_STATE.mcModelViewMatrix = McObjectConverter.Convert(projectionMatrix);
ClientApi.RENDER_STATE.mcProjectionMatrix = new Mat4f();
ClientApi.RENDER_STATE.mcProjectionMatrix = new DhMat4f();
ClientApi.RENDER_STATE.mcProjectionMatrix.setIdentity();
#else
ClientApi.RENDER_STATE.mcModelViewMatrix = McObjectConverter.Convert(positionMatrix);
@@ -218,12 +222,14 @@ public class MixinLevelRenderer
#if MC_VER <= MC_1_21_11
#else
#if MC_VER <= MC_26_1_2
@Inject(at = @At("HEAD"), method = "prepareChunkRenders")
private void prepareChunkRenders(final Matrix4fc modelViewMatrix, CallbackInfoReturnable<ChunkSectionsToRender> callback)
{
ClientApi.RENDER_STATE.clientLevelWrapper = ClientLevelWrapper.getWrapperIfDifferent(ClientApi.RENDER_STATE.clientLevelWrapper, this.level);
}
@Inject(at = @At("HEAD"), method = "renderLevel")
public void renderLevel(
final GraphicsResourceAllocator resourceAllocator, final DeltaTracker deltaTracker,
@@ -239,6 +245,9 @@ public class MixinLevelRenderer
}
#else
#endif
#endif
//endregion
@@ -100,13 +100,26 @@ public class MixinLightTexture
#elif MC_VER <= MC_1_21_10
GlTexture glTexture = (GlTexture) this.texture;
this.renderWrapper.setLightmapId(glTexture.glId());
#else
#elif MC_VER <= MC_26_1_2
// both options are available since the renderer can be changed to either Blaze3D or OpenGL
GlTexture glTexture = (GlTexture) this.texture;
this.renderWrapper.setLightmapId(glTexture.glId());
this.renderWrapper.setLightmapGpuTexture(this.texture);
#else
// this will only be used when using native GL rendering
if (this.texture instanceof GlTexture)
{
GlTexture glTexture = (GlTexture) this.texture;
this.renderWrapper.setLightmapId(glTexture.glId());
}
// this will be used for Blaze3D OpenGL and Vulkan
this.renderWrapper.setLightmapGpuTexture(this.texture);
#endif
}
}
@@ -86,11 +86,19 @@ public abstract class MixinMinecraft
#endif
#if MC_VER >= MC_1_20_2
#if MC_VER <= MC_26_1_2
@Redirect(
method = "Lnet/minecraft/client/Minecraft;onGameLoadFinished(Lnet/minecraft/client/Minecraft$GameLoadCookie;)V",
at = @At(value = "INVOKE", target = "Ljava/lang/Runnable;run()V")
)
private void buildInitialScreens(Runnable runnable)
#else
@Redirect(
method = "Lnet/minecraft/client/Minecraft;onGameLoadFinished(Lnet/minecraft/client/GameLoadCookie;)V",
at = @At(value = "INVOKE", target = "Ljava/lang/Runnable;run()V")
)
private void buildInitialScreens(Runnable runnable)
#endif
{
DhUpdateScreenBase.tryShowUpdateScreenAndRunAutoUpdateStartup(runnable);
runnable.run();
@@ -19,6 +19,7 @@
package com.seibel.distanthorizons.fabric.mixins.client;
import com.seibel.distanthorizons.common.wrappers.gui.DhScreenUtil;
import com.seibel.distanthorizons.common.wrappers.gui.GetConfigScreen;
import com.seibel.distanthorizons.common.wrappers.gui.TexturedButtonWidget;
import com.seibel.distanthorizons.coreapi.ModInfo;
@@ -34,7 +35,6 @@ import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger;
#if MC_VER >= MC_1_20_6
@@ -147,7 +147,7 @@ public class MixinOptionsScreen extends Screen
20, ICON_TEXTURE, 20, 40,
// Create the button and tell it where to go
// For now it goes to the client option by default
(buttonWidget) -> Objects.requireNonNull(this.minecraft).setScreen(GetConfigScreen.getScreen(this)),
(buttonWidget) -> DhScreenUtil.setScreen(GetConfigScreen.getScreen(this)),
// Add a title to the button
#if MC_VER < MC_1_19_2
new TranslatableComponent(ModInfo.ID + ".title"));
@@ -24,18 +24,19 @@ public abstract class MixinSharedConstants
@Mutable
@Shadow @Final public static boolean IS_RUNNING_IN_IDE;
@Unique
private static final DhLogger DH_LOGGER = new DhLoggerBuilder().name("SharedConstants").build();
@Inject(method = "<clinit>", at = @At("TAIL"))
private static void setIsRunningInIde(CallbackInfo ci)
{
DhLogger logger = new DhLoggerBuilder().name("SharedConstants").build();
// setting IS_RUNNING_IN_IDE to true enables
// additional validation on Mojang's side which
// helps catch errors when developing for Blaze3D
boolean irisPresent;
boolean brokenIrisVersionPresent = false;
#if MC_VER <= MC_1_21_11
IS_RUNNING_IN_IDE = ModInfo.IS_DEV_BUILD;
#else
try
{
@@ -44,17 +45,28 @@ public abstract class MixinSharedConstants
// Blaze3D validation is enabled (which is enabled by if
// IS_RUNNING_IN_IDE is true)
ModInfo.class.getClassLoader().loadClass("net.irisshaders.iris.api.v0.IrisApi");
irisPresent = true;
brokenIrisVersionPresent = true;
}
catch (ClassNotFoundException ignore)
{
irisPresent = false;
}
IS_RUNNING_IN_IDE = ModInfo.IS_DEV_BUILD && !irisPresent;
catch (ClassNotFoundException ignore) { }
#endif
logger.info("Setting Minecraft's SharedConstants.IS_RUNNING_IN_IDE to ["+IS_RUNNING_IN_IDE+"]");
boolean wilderWildPresent = false;
try
{
// Wilder Wild will refuse to launch if
// "IS_RUNNING_IN_IDE" is true
// not sure why
ModInfo.class.getClassLoader().loadClass("net.frozenblock.wilderwild.WilderWild");
wilderWildPresent = true;
}
catch (ClassNotFoundException ignore) { }
IS_RUNNING_IN_IDE = ModInfo.IS_DEV_BUILD
&& !brokenIrisVersionPresent
&& !wilderWildPresent;
DH_LOGGER.info("DH is setting Minecraft's SharedConstants.IS_RUNNING_IN_IDE to ["+IS_RUNNING_IN_IDE+"]");
}
}

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