Compare commits
62 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 062ed5bcc8 | |||
| 539d152caa | |||
| a1af4335e0 | |||
| e68b112020 | |||
| fab6d187ca | |||
| 0daa00cec2 | |||
| f3036850ce | |||
| 51c8b47bba | |||
| 89efd53d61 | |||
| 7667f51cf3 | |||
| 61eaa5a734 | |||
| 1d589d1a62 | |||
| 03b1eeb77e | |||
| 8446df72f7 | |||
| c07397e9c0 | |||
| 29a92aeb93 | |||
| 8467782b80 | |||
| c8dbb21ea4 | |||
| 63e1c12564 | |||
| 52f58150da | |||
| d1d642a7bb | |||
| 8e45358aad | |||
| a959c7220b | |||
| e06425c5eb | |||
| 66ce258fe1 | |||
| 181881a661 | |||
| af0d8d1d2f | |||
| 6c68e94b96 | |||
| 93313a5c50 | |||
| 0527baa708 | |||
| ce1fbde937 | |||
| 764abdac45 | |||
| b42d3d8f74 | |||
| cd67a773c5 | |||
| 6d7bade7ca | |||
| dea8d4498a | |||
| 2969916f34 | |||
| 8785224c51 | |||
| 605f02a655 | |||
| 8099d37c14 | |||
| dd4dbefe9a | |||
| 52a15fd349 | |||
| 3b3be6aed4 | |||
| aeb7d6d0f9 | |||
| 5336dbafec | |||
| 6079cb4830 | |||
| 50ff174104 | |||
| b77ef89df6 | |||
| a701dd29a9 | |||
| ab36fdd545 | |||
| f87afb34f4 | |||
| 053917d3d7 | |||
| 063ba01970 | |||
| 72a888f3ff | |||
| 0bd36bff1d | |||
| 2bf125b7ac | |||
| ba3cf8fd56 | |||
| 951f2a4ee7 | |||
| d55b1bb3c2 | |||
| 275ecb78c3 | |||
| 64ac0d6017 | |||
| 29381bce7b |
+1
-1
@@ -35,7 +35,7 @@ build:
|
|||||||
parallel:
|
parallel:
|
||||||
matrix:
|
matrix:
|
||||||
- MC_VER: [
|
- MC_VER: [
|
||||||
"1.26.1",
|
"26.1.2",
|
||||||
"1.21.11", "1.21.10", "1.21.9", "1.21.8", "1.21.6", "1.21.5", "1.21.4", "1.21.3", "1.21.1",
|
"1.21.11", "1.21.10", "1.21.9", "1.21.8", "1.21.6", "1.21.5", "1.21.4", "1.21.3", "1.21.1",
|
||||||
"1.20.6", "1.20.4", "1.20.2", "1.20.1",
|
"1.20.6", "1.20.4", "1.20.2", "1.20.1",
|
||||||
"1.19.4", "1.19.2",
|
"1.19.4", "1.19.2",
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
echo "==================== Note: All build jars will be in the folder called 'buildAllJars' ===================="
|
echo "==================== Note: All build jars will be in the folder called 'buildAllJars' ===================="
|
||||||
mkdir -p buildAllJars
|
mkdir -p buildAllJars
|
||||||
rm -rf buildAllJars/*
|
rm -rf buildAllJars/*
|
||||||
|
rm -rf build/forgix/*
|
||||||
|
|
||||||
# Loop trough everything in the version properties folder
|
# Loop trough everything in the version properties folder
|
||||||
for d in versionProperties/*; do
|
for d in versionProperties/*; do
|
||||||
@@ -24,5 +25,5 @@ for d in versionProperties/*; do
|
|||||||
if [ $? != 0 ]; then continue; fi
|
if [ $? != 0 ]; then continue; fi
|
||||||
|
|
||||||
echo "==================== Moving jar ===================="
|
echo "==================== Moving jar ===================="
|
||||||
mv build/merged/*.jar buildAllJars/
|
mv build/forgix/*.jar buildAllJars/
|
||||||
done
|
done
|
||||||
|
|||||||
+2
-1
@@ -6,6 +6,7 @@
|
|||||||
echo ==================== Note: All build jars will be in the folder called 'buildAllJars' ====================
|
echo ==================== Note: All build jars will be in the folder called 'buildAllJars' ====================
|
||||||
mkdir buildAllJars
|
mkdir buildAllJars
|
||||||
del buildAllJars/*
|
del buildAllJars/*
|
||||||
|
del build/forgix/*
|
||||||
|
|
||||||
@rem Loop trough everything in the version properties folder
|
@rem Loop trough everything in the version properties folder
|
||||||
for %%f in (versionProperties\*) do (
|
for %%f in (versionProperties\*) do (
|
||||||
@@ -23,7 +24,7 @@ for %%f in (versionProperties\*) do (
|
|||||||
call .\gradlew.bat mergeJars -PmcVer="!version!"
|
call .\gradlew.bat mergeJars -PmcVer="!version!"
|
||||||
|
|
||||||
echo ==================== Moving jar ====================
|
echo ==================== Moving jar ====================
|
||||||
move build\merged\*.jar buildAllJars\
|
move build\forgix\*.jar buildAllJars\
|
||||||
)
|
)
|
||||||
|
|
||||||
endlocal
|
endlocal
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ repositories {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation 'com.gradleup.shadow:shadow-gradle-plugin:9.0.0'
|
implementation 'com.gradleup.shadow:shadow-gradle-plugin:9.0.0'
|
||||||
implementation 'xyz.wagyourtail.unimined:xyz.wagyourtail.unimined.gradle.plugin:1.4.17-kappa'
|
implementation 'xyz.wagyourtail.unimined:xyz.wagyourtail.unimined.gradle.plugin:1.4.18-kappa'
|
||||||
implementation 'xyz.wagyourtail:manifold-gradle:1.0.0-SNAPSHOT'
|
implementation 'xyz.wagyourtail:manifold-gradle:1.0.0-SNAPSHOT'
|
||||||
implementation 'xyz.wagyourtail.jvmdowngrader:xyz.wagyourtail.jvmdowngrader.gradle.plugin:1.3.4'
|
implementation 'xyz.wagyourtail.jvmdowngrader:xyz.wagyourtail.jvmdowngrader.gradle.plugin:1.3.4'
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -286,7 +286,6 @@ class NativeTransformer implements ResourceTransformer {
|
|||||||
if (isNotCommonProject) {
|
if (isNotCommonProject) {
|
||||||
shadowJar {
|
shadowJar {
|
||||||
configurations = [project.configurations.shadowMe]
|
configurations = [project.configurations.shadowMe]
|
||||||
relocate "com.seibel.distanthorizons.common", "loaderCommon.${project.name}.com.seibel.distanthorizons.common"
|
|
||||||
def librariesLocation = "DistantHorizons.libraries"
|
def librariesLocation = "DistantHorizons.libraries"
|
||||||
|
|
||||||
// LZ4
|
// LZ4
|
||||||
@@ -354,11 +353,23 @@ if (isNotCommonProject) {
|
|||||||
def isClient = runTask.name.toLowerCase().contains("client")
|
def isClient = runTask.name.toLowerCase().contains("client")
|
||||||
runTask.workingDir = rootProject.file("run/${isClient ? 'client' : 'server'}")
|
runTask.workingDir = rootProject.file("run/${isClient ? 'client' : 'server'}")
|
||||||
|
|
||||||
|
// Minecraft automatically has G1GC args present,
|
||||||
|
// remove them so we can use ZGC instead
|
||||||
|
def filteredArgs = runTask.jvmArgs.findAll { arg ->
|
||||||
|
!arg.startsWith("-XX:+UseG1GC") &&
|
||||||
|
!arg.startsWith("-XX:G1") &&
|
||||||
|
!arg.startsWith("-XX:MaxGCPauseMillis")
|
||||||
|
}
|
||||||
|
runTask.jvmArgs = filteredArgs
|
||||||
|
|
||||||
// JVM args
|
// JVM args
|
||||||
runTask.jvmArgs(
|
runTask.jvmArgs(
|
||||||
"-Dio.netty.leakDetection.level=advanced",
|
"-Dio.netty.leakDetection.level=advanced",
|
||||||
//"-XX:+UseZGC",
|
// TODO only use for modern java versions
|
||||||
|
"-XX:+UseZGC",
|
||||||
|
// TODO don't use for even more modern-er java versions
|
||||||
//"-XX:+ZGenerational",
|
//"-XX:+ZGenerational",
|
||||||
|
rootProject.minecraftMemoryJavaArg,
|
||||||
)
|
)
|
||||||
if (isClient) {
|
if (isClient) {
|
||||||
runTask.jvmArgs(
|
runTask.jvmArgs(
|
||||||
@@ -367,7 +378,13 @@ if (isNotCommonProject) {
|
|||||||
"-Dminecraft.api.session.host=https://nope.invalid",
|
"-Dminecraft.api.session.host=https://nope.invalid",
|
||||||
"-Dminecraft.api.services.host=https://nope.invalid",
|
"-Dminecraft.api.services.host=https://nope.invalid",
|
||||||
)
|
)
|
||||||
runTask.args("--username", "Dev", "--renderDebugLabels", "--tracy")
|
runTask.args(
|
||||||
|
// use a consistent username for easier debugging in a given world (vs randomly teleporting to a new user each time the game boots)
|
||||||
|
"--username", "Dev",
|
||||||
|
// "--renderDebugLabels" is a Mojang command to show render names in RenderDoc
|
||||||
|
"--renderDebugLabels",
|
||||||
|
// "--tracy" is a Mojang command to allow individual frames to be debugged using Tracy https://github.com/wolfpld/tracy/releases/tag/v0.13.1
|
||||||
|
"--tracy")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -417,6 +434,7 @@ if (isNotCommonProject) {
|
|||||||
issues : rootProject.mod_issues,
|
issues : rootProject.mod_issues,
|
||||||
discord : rootProject.mod_discord,
|
discord : rootProject.mod_discord,
|
||||||
minecraft_version : rootProject.minecraft_version,
|
minecraft_version : rootProject.minecraft_version,
|
||||||
|
accessWidenerVersion : rootProject.accessWidenerVersion,
|
||||||
compatible_minecraft_versions: rootProject.compatible_minecraft_versions,
|
compatible_minecraft_versions: rootProject.compatible_minecraft_versions,
|
||||||
compatible_forgemc_versions : compatible_forgemc_versions,
|
compatible_forgemc_versions : compatible_forgemc_versions,
|
||||||
java_version : rootProject.java_version,
|
java_version : rootProject.java_version,
|
||||||
@@ -447,11 +465,11 @@ if (isNotCommonProject) {
|
|||||||
|
|
||||||
// ==================== Resource Copy Tasks ====================
|
// ==================== Resource Copy Tasks ====================
|
||||||
|
|
||||||
task copyCommonLoaderResources(type: Copy) {
|
// task copyCommonLoaderResources(type: Copy) {
|
||||||
from project(":common").file("src/main/resources/${rootProject.accessWidenerVersion}.distanthorizons.accesswidener")
|
// from project(":common").file("src/main/resources/${rootProject.accessWidenerVersion}.distanthorizons.accesswidener")
|
||||||
into(file(project.file("build/resources/main")))
|
// into(file(project.file("build/resources/main")))
|
||||||
rename "${rootProject.accessWidenerVersion}.distanthorizons.accesswidener", "distanthorizons.accesswidener"
|
// rename "${rootProject.accessWidenerVersion}.distanthorizons.accesswidener", "distanthorizons.accesswidener"
|
||||||
}
|
// }
|
||||||
|
|
||||||
task copyCoreResources(type: Copy) {
|
task copyCoreResources(type: Copy) {
|
||||||
from fileTree(project(":core").file("src/main/resources"))
|
from fileTree(project(":core").file("src/main/resources"))
|
||||||
|
|||||||
@@ -21,10 +21,8 @@ import com.seibel.distanthorizons.core.jar.updater.SelfUpdater;
|
|||||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||||
import com.seibel.distanthorizons.core.render.renderer.AbstractDebugWireframeRenderer;
|
import com.seibel.distanthorizons.core.render.renderer.AbstractDebugWireframeRenderer;
|
||||||
import com.seibel.distanthorizons.core.render.renderer.StubDebugWireframeRenderer;
|
import com.seibel.distanthorizons.core.render.renderer.StubDebugWireframeRenderer;
|
||||||
import com.seibel.distanthorizons.core.util.NativeDialogUtil;
|
import com.seibel.distanthorizons.common.wrappers.gui.NativeDialogUtil;
|
||||||
import com.seibel.distanthorizons.core.util.ThreadUtil;
|
import com.seibel.distanthorizons.core.util.ThreadUtil;
|
||||||
import com.seibel.distanthorizons.core.util.threading.DhThreadFactory;
|
|
||||||
import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil;
|
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.IVersionConstants;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.IVersionConstants;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IIrisAccessor;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IIrisAccessor;
|
||||||
@@ -375,10 +373,10 @@ public abstract class AbstractModInitializer
|
|||||||
renderApi = versionConstants.getDefaultRenderingApi();
|
renderApi = versionConstants.getDefaultRenderingApi();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Iris only supports nataive OpenGL
|
// Iris only supports native OpenGL
|
||||||
if (renderApi != EDhApiRenderApi.OPEN_GL)
|
if (renderApi != EDhApiRenderApi.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 DH's config file.";
|
String irisUnsupportedMessage = "Iris doesn't support DH when using the ["+EDhApiRenderApi.BLAZE_3D+"] rendering API, this will need to be fixed on Iris end. As a temporary fix please change the rendering API to ["+EDhApiRenderApi.OPEN_GL+"] in the DH config file.";
|
||||||
LOGGER.fatal(irisUnsupportedMessage);
|
LOGGER.fatal(irisUnsupportedMessage);
|
||||||
NativeDialogUtil.showDialog(ModInfo.READABLE_NAME, irisUnsupportedMessage, "ok", "error");
|
NativeDialogUtil.showDialog(ModInfo.READABLE_NAME, irisUnsupportedMessage, "ok", "error");
|
||||||
|
|
||||||
|
|||||||
+164
-169
@@ -330,194 +330,194 @@ public class BlazeDhGenericObjectRenderer implements IDhGenericRenderer
|
|||||||
@Override
|
@Override
|
||||||
public void render(RenderParams renderEventParam, IProfilerWrapper profiler, boolean renderingWithSsao)
|
public void render(RenderParams renderEventParam, IProfilerWrapper profiler, boolean renderingWithSsao)
|
||||||
{
|
{
|
||||||
//==============//
|
|
||||||
// render setup //
|
|
||||||
//==============//
|
|
||||||
//#region
|
|
||||||
|
|
||||||
profiler.push("setup");
|
try (IProfilerWrapper.IProfileBlock generic_profile = profiler.push("setup"))
|
||||||
|
|
||||||
this.init();
|
|
||||||
|
|
||||||
ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeGenericRenderSetupEvent.class, renderEventParam);
|
|
||||||
|
|
||||||
Vec3d camPos = MC_RENDER.getCameraExactPosition();
|
|
||||||
|
|
||||||
//#endregion
|
|
||||||
|
|
||||||
if (BlazeDhMetaRenderer.INSTANCE.dhColorTextureWrapper.isEmpty()
|
|
||||||
|| BlazeDhMetaRenderer.INSTANCE.dhDepthTextureWrapper.isEmpty())
|
|
||||||
{
|
{
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
//==============//
|
||||||
|
// render setup //
|
||||||
|
//==============//
|
||||||
|
//#region
|
||||||
|
|
||||||
//===========//
|
this.init();
|
||||||
// rendering //
|
|
||||||
//===========//
|
|
||||||
//#region
|
|
||||||
|
|
||||||
Collection<RenderableBoxGroup> boxList = this.boxGroupById.values();
|
ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeGenericRenderSetupEvent.class, renderEventParam);
|
||||||
for (RenderableBoxGroup boxGroup : boxList)
|
|
||||||
{
|
|
||||||
// validation //
|
|
||||||
|
|
||||||
// shouldn't happen, but just in case
|
Vec3d camPos = MC_RENDER.getCameraExactPosition();
|
||||||
if (boxGroup == null)
|
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
if (BlazeDhMetaRenderer.INSTANCE.dhColorTextureWrapper.isEmpty()
|
||||||
|
|| BlazeDhMetaRenderer.INSTANCE.dhDepthTextureWrapper.isEmpty())
|
||||||
{
|
{
|
||||||
continue;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// skip boxes that shouldn't render this pass
|
|
||||||
if (boxGroup.ssaoEnabled != renderingWithSsao)
|
|
||||||
|
//===========//
|
||||||
|
// rendering //
|
||||||
|
//===========//
|
||||||
|
//#region
|
||||||
|
|
||||||
|
Collection<RenderableBoxGroup> boxList = this.boxGroupById.values();
|
||||||
|
for (RenderableBoxGroup boxGroup : boxList)
|
||||||
{
|
{
|
||||||
continue;
|
// validation //
|
||||||
}
|
|
||||||
|
|
||||||
profiler.popPush("render prep");
|
// shouldn't happen, but just in case
|
||||||
boxGroup.preRender(renderEventParam); // called even if the group is inactive, so the group can be activate if desired
|
if (boxGroup == null)
|
||||||
|
|
||||||
// ignore inactive groups
|
|
||||||
if (!boxGroup.active)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// allow API users to cancel this object's rendering
|
|
||||||
boolean cancelRendering = ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeGenericObjectRenderEvent.class, new DhApiBeforeGenericObjectRenderEvent.EventParam(renderEventParam, boxGroup));
|
|
||||||
if (cancelRendering)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// update instanced data if needed
|
|
||||||
{
|
|
||||||
boxGroup.tryUpdateInstancedDataAsync();
|
|
||||||
|
|
||||||
// skip groups that haven't been uploaded yet
|
|
||||||
if (boxGroup.vertexBufferContainer.getState() != IDhGenericObjectVertexBufferContainer.EState.RENDER)
|
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// skip boxes that shouldn't render this pass
|
||||||
|
if (boxGroup.ssaoEnabled != renderingWithSsao)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
profiler.popPush("render prep");
|
||||||
|
boxGroup.preRender(renderEventParam); // called even if the group is inactive, so the group can be activate if desired
|
||||||
|
|
||||||
|
// ignore inactive groups
|
||||||
|
if (!boxGroup.active)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// allow API users to cancel this object's rendering
|
||||||
|
boolean cancelRendering = ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeGenericObjectRenderEvent.class, new DhApiBeforeGenericObjectRenderEvent.EventParam(renderEventParam, boxGroup));
|
||||||
|
if (cancelRendering)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// update instanced data if needed
|
||||||
|
{
|
||||||
|
boxGroup.tryUpdateInstancedDataAsync();
|
||||||
|
|
||||||
|
// skip groups that haven't been uploaded yet
|
||||||
|
if (boxGroup.vertexBufferContainer.getState() != IDhGenericObjectVertexBufferContainer.EState.RENDER)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DhApiRenderableBoxGroupShading shading = boxGroup.shading;
|
||||||
|
if (shading == null)
|
||||||
|
{
|
||||||
|
shading = DEFAULT_SHADING;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
projectionMvmMatrix.multiply(renderEventParam.dhModelViewMatrix);
|
||||||
|
|
||||||
|
|
||||||
|
// upload data //
|
||||||
|
|
||||||
|
ByteBuffer buffer = ByteBuffer.allocateDirect(uniformBufferSize);
|
||||||
|
buffer.order(ByteOrder.nativeOrder());
|
||||||
|
buffer = Std140Builder.intoBuffer(buffer)
|
||||||
|
.putIVec3(
|
||||||
|
LodUtil.getChunkPosFromDouble(boxGroup.getOriginBlockPos().x),
|
||||||
|
LodUtil.getChunkPosFromDouble(boxGroup.getOriginBlockPos().y),
|
||||||
|
LodUtil.getChunkPosFromDouble(boxGroup.getOriginBlockPos().z)
|
||||||
|
) // uOffsetChunk
|
||||||
|
.putVec3(
|
||||||
|
LodUtil.getSubChunkPosFromDouble(boxGroup.getOriginBlockPos().x),
|
||||||
|
LodUtil.getSubChunkPosFromDouble(boxGroup.getOriginBlockPos().y),
|
||||||
|
LodUtil.getSubChunkPosFromDouble(boxGroup.getOriginBlockPos().z)
|
||||||
|
) // uOffsetSubChunk
|
||||||
|
.putIVec3(
|
||||||
|
LodUtil.getChunkPosFromDouble(camPos.x),
|
||||||
|
LodUtil.getChunkPosFromDouble(camPos.y),
|
||||||
|
LodUtil.getChunkPosFromDouble(camPos.z)
|
||||||
|
) // uCameraPosChunk
|
||||||
|
.putVec3(
|
||||||
|
LodUtil.getSubChunkPosFromDouble(camPos.x),
|
||||||
|
LodUtil.getSubChunkPosFromDouble(camPos.y),
|
||||||
|
LodUtil.getSubChunkPosFromDouble(camPos.z)
|
||||||
|
) // uCameraPosSubChunk
|
||||||
|
|
||||||
|
.putMat4f(projectionMvmMatrix.createJomlMatrix()) // uProjectionMvm
|
||||||
|
.putInt(boxGroup.getSkyLight()) // uSkyLight
|
||||||
|
.putInt(boxGroup.getBlockLight()) // uBlockLight
|
||||||
|
|
||||||
|
.putFloat(shading.north)
|
||||||
|
.putFloat(shading.south)
|
||||||
|
.putFloat(shading.east)
|
||||||
|
.putFloat(shading.west)
|
||||||
|
.putFloat(shading.top)
|
||||||
|
.putFloat(shading.bottom)
|
||||||
|
|
||||||
|
.get()
|
||||||
|
;
|
||||||
|
|
||||||
|
this.vertUniformBuffer = BlazeUniformUtil.createBuffer("vertUniformBlock", uniformBufferSize, this.vertUniformBuffer);
|
||||||
|
GpuBufferSlice bufferSlice = new GpuBufferSlice(this.vertUniformBuffer, 0, uniformBufferSize);
|
||||||
|
|
||||||
|
COMMAND_ENCODER.writeToBuffer(bufferSlice, buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// render //
|
||||||
|
|
||||||
|
profiler.popPush("rendering");
|
||||||
|
try (IProfilerWrapper.IProfileBlock namespace_profile = profiler.push(boxGroup.getResourceLocationNamespace());
|
||||||
|
IProfilerWrapper.IProfileBlock location_profile = profiler.push(boxGroup.getResourceLocationPath()))
|
||||||
|
{
|
||||||
|
this.renderBoxGroupInstanced(renderEventParam, boxGroup, profiler);
|
||||||
|
}
|
||||||
|
|
||||||
|
boxGroup.postRender(renderEventParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//#endregion
|
||||||
DhApiRenderableBoxGroupShading shading = boxGroup.shading;
|
|
||||||
if (shading == null)
|
|
||||||
{
|
|
||||||
shading = DEFAULT_SHADING;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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);
|
|
||||||
projectionMvmMatrix.multiply(renderEventParam.dhModelViewMatrix);
|
|
||||||
|
|
||||||
|
|
||||||
// upload data //
|
|
||||||
|
|
||||||
ByteBuffer buffer = ByteBuffer.allocateDirect(uniformBufferSize);
|
|
||||||
buffer.order(ByteOrder.nativeOrder());
|
|
||||||
buffer = Std140Builder.intoBuffer(buffer)
|
|
||||||
.putIVec3(
|
|
||||||
LodUtil.getChunkPosFromDouble(boxGroup.getOriginBlockPos().x),
|
|
||||||
LodUtil.getChunkPosFromDouble(boxGroup.getOriginBlockPos().y),
|
|
||||||
LodUtil.getChunkPosFromDouble(boxGroup.getOriginBlockPos().z)
|
|
||||||
) // uOffsetChunk
|
|
||||||
.putVec3(
|
|
||||||
LodUtil.getSubChunkPosFromDouble(boxGroup.getOriginBlockPos().x),
|
|
||||||
LodUtil.getSubChunkPosFromDouble(boxGroup.getOriginBlockPos().y),
|
|
||||||
LodUtil.getSubChunkPosFromDouble(boxGroup.getOriginBlockPos().z)
|
|
||||||
) // uOffsetSubChunk
|
|
||||||
.putIVec3(
|
|
||||||
LodUtil.getChunkPosFromDouble(camPos.x),
|
|
||||||
LodUtil.getChunkPosFromDouble(camPos.y),
|
|
||||||
LodUtil.getChunkPosFromDouble(camPos.z)
|
|
||||||
) // uCameraPosChunk
|
|
||||||
.putVec3(
|
|
||||||
LodUtil.getSubChunkPosFromDouble(camPos.x),
|
|
||||||
LodUtil.getSubChunkPosFromDouble(camPos.y),
|
|
||||||
LodUtil.getSubChunkPosFromDouble(camPos.z)
|
|
||||||
) // uCameraPosSubChunk
|
|
||||||
|
|
||||||
.putMat4f(projectionMvmMatrix.createJomlMatrix()) // uProjectionMvm
|
|
||||||
.putInt(boxGroup.getSkyLight()) // uSkyLight
|
|
||||||
.putInt(boxGroup.getBlockLight()) // uBlockLight
|
|
||||||
|
|
||||||
.putFloat(shading.north)
|
|
||||||
.putFloat(shading.south)
|
|
||||||
.putFloat(shading.east)
|
|
||||||
.putFloat(shading.west)
|
|
||||||
.putFloat(shading.top)
|
|
||||||
.putFloat(shading.bottom)
|
|
||||||
|
|
||||||
.get()
|
|
||||||
;
|
|
||||||
|
|
||||||
this.vertUniformBuffer = BlazeUniformUtil.createBuffer("vertUniformBlock", uniformBufferSize, this.vertUniformBuffer);
|
|
||||||
GpuBufferSlice bufferSlice = new GpuBufferSlice(this.vertUniformBuffer, 0, uniformBufferSize);
|
|
||||||
|
|
||||||
COMMAND_ENCODER.writeToBuffer(bufferSlice, buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//==========//
|
||||||
|
// clean up //
|
||||||
|
//==========//
|
||||||
|
//region
|
||||||
|
|
||||||
// render //
|
profiler.popPush("cleanup");
|
||||||
|
|
||||||
profiler.popPush("rendering");
|
ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeGenericRenderCleanupEvent.class, renderEventParam);
|
||||||
profiler.push(boxGroup.getResourceLocationNamespace());
|
|
||||||
profiler.push(boxGroup.getResourceLocationPath());
|
|
||||||
|
|
||||||
this.renderBoxGroupInstanced(renderEventParam, boxGroup, profiler);
|
//endregion
|
||||||
|
|
||||||
profiler.pop(); // resource path
|
|
||||||
profiler.pop(); // resource namespace
|
|
||||||
|
|
||||||
boxGroup.postRender(renderEventParam);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//#endregion
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//==========//
|
|
||||||
// clean up //
|
|
||||||
//==========//
|
|
||||||
//region
|
|
||||||
|
|
||||||
profiler.popPush("cleanup");
|
|
||||||
|
|
||||||
ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeGenericRenderCleanupEvent.class, renderEventParam);
|
|
||||||
|
|
||||||
profiler.pop();
|
|
||||||
|
|
||||||
//endregion
|
|
||||||
}
|
}
|
||||||
private String getRenderPassName() { return "distantHorizons:McGenericObjectRenderer"; }
|
private String getRenderPassName() { return "distantHorizons:McGenericObjectRenderer"; }
|
||||||
|
|
||||||
@@ -545,8 +545,6 @@ public class BlazeDhGenericObjectRenderer implements IDhGenericRenderer
|
|||||||
|
|
||||||
// update instance data //
|
// update instance data //
|
||||||
|
|
||||||
profiler.push("vertex setup");
|
|
||||||
|
|
||||||
BlazeGenericObjectVertexContainer container = (BlazeGenericObjectVertexContainer) boxGroup.vertexBufferContainer;
|
BlazeGenericObjectVertexContainer container = (BlazeGenericObjectVertexContainer) boxGroup.vertexBufferContainer;
|
||||||
|
|
||||||
LightMapWrapper lightMapWrapper = (LightMapWrapper) renderEventParam.lightmap;
|
LightMapWrapper lightMapWrapper = (LightMapWrapper) renderEventParam.lightmap;
|
||||||
@@ -556,7 +554,6 @@ public class BlazeDhGenericObjectRenderer implements IDhGenericRenderer
|
|||||||
|
|
||||||
|
|
||||||
// Bind instance data //
|
// Bind instance data //
|
||||||
profiler.popPush("binding");
|
|
||||||
|
|
||||||
|
|
||||||
renderPass.setUniform("vertUniformBlock", this.vertUniformBuffer);
|
renderPass.setUniform("vertUniformBlock", this.vertUniformBuffer);
|
||||||
@@ -568,7 +565,6 @@ public class BlazeDhGenericObjectRenderer implements IDhGenericRenderer
|
|||||||
renderPass.setVertexBuffer(0, container.vboGpuBuffer);
|
renderPass.setVertexBuffer(0, container.vboGpuBuffer);
|
||||||
|
|
||||||
// Draw instanced
|
// Draw instanced
|
||||||
profiler.popPush("render");
|
|
||||||
if (container.uploadedBoxCount > 0)
|
if (container.uploadedBoxCount > 0)
|
||||||
{
|
{
|
||||||
renderPass.drawIndexed(
|
renderPass.drawIndexed(
|
||||||
@@ -579,7 +575,6 @@ public class BlazeDhGenericObjectRenderer implements IDhGenericRenderer
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
profiler.pop();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//endregion
|
//endregion
|
||||||
|
|||||||
+22
-4
@@ -6,13 +6,16 @@ public class BlazeDhMetaRenderer {}
|
|||||||
#else
|
#else
|
||||||
|
|
||||||
import com.mojang.blaze3d.textures.GpuTexture;
|
import com.mojang.blaze3d.textures.GpuTexture;
|
||||||
|
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiAfterColorDepthTextureCreatedEvent;
|
||||||
|
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.apply.BlazeDhApplyRenderer;
|
||||||
import com.seibel.distanthorizons.common.render.blaze.wrappers.texture.BlazeTextureWrapper;
|
import com.seibel.distanthorizons.common.render.blaze.wrappers.texture.BlazeTextureWrapper;
|
||||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||||
import com.seibel.distanthorizons.core.render.RenderParams;
|
import com.seibel.distanthorizons.core.render.RenderParams;
|
||||||
import com.seibel.distanthorizons.core.util.ColorUtil;
|
import com.seibel.distanthorizons.coreapi.util.ColorUtil;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass.IDhMetaRenderer;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass.IDhMetaRenderer;
|
||||||
|
import com.seibel.distanthorizons.coreapi.DependencyInjection.ApiEventInjector;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
@@ -57,9 +60,24 @@ public class BlazeDhMetaRenderer implements IDhMetaRenderer
|
|||||||
@Override
|
@Override
|
||||||
public void runRenderPassSetup(RenderParams renderParams)
|
public void runRenderPassSetup(RenderParams renderParams)
|
||||||
{
|
{
|
||||||
// textures
|
int oldWidth = this.dhDepthTextureWrapper.getWidth();
|
||||||
this.dhDepthTextureWrapper.tryCreateOrResize();
|
int oldHeight = this.dhDepthTextureWrapper.getHeight();
|
||||||
this.dhColorTextureWrapper.tryCreateOrResize();
|
|
||||||
|
boolean texturesChanged = false;
|
||||||
|
texturesChanged = this.dhDepthTextureWrapper.tryCreateOrResize() | texturesChanged;
|
||||||
|
texturesChanged = this.dhColorTextureWrapper.tryCreateOrResize() | texturesChanged;
|
||||||
|
|
||||||
|
if (texturesChanged)
|
||||||
|
{
|
||||||
|
int newTextureWidth = MC_RENDER.getTargetFramebufferViewportWidth();
|
||||||
|
int newTextureHeight = MC_RENDER.getTargetFramebufferViewportHeight();
|
||||||
|
|
||||||
|
DhApiTextureCreatedParam textureCreatedParam = new DhApiTextureCreatedParam(
|
||||||
|
oldWidth, oldHeight,
|
||||||
|
newTextureWidth, newTextureHeight
|
||||||
|
);
|
||||||
|
ApiEventInjector.INSTANCE.fireAllEvents(DhApiAfterColorDepthTextureCreatedEvent.class, textureCreatedParam);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+188
-192
@@ -151,210 +151,206 @@ public class BlazeDhTerrainRenderer implements IDhTerrainRenderer
|
|||||||
{
|
{
|
||||||
this.tryInit();
|
this.tryInit();
|
||||||
|
|
||||||
|
try(IProfilerWrapper.IProfileBlock terrain_profile = profiler.push("terrain render"))
|
||||||
profiler.push("vert unique uniforms");
|
|
||||||
{
|
{
|
||||||
// create data //
|
profiler.popPush("vert unique uniforms");
|
||||||
|
|
||||||
for (int lodIndex = 0; lodIndex < bufferContainers.size(); lodIndex++)
|
|
||||||
{
|
{
|
||||||
LodBufferContainer bufferContainer = bufferContainers.get(lodIndex);
|
// create data //
|
||||||
bufferContainer.uniformContainer.tryUpload();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
profiler.popPush("vert share uniforms");
|
|
||||||
{
|
|
||||||
Mat4f combinedMatrix = new Mat4f(renderEventParam.dhProjectionMatrix);
|
|
||||||
combinedMatrix.multiply(renderEventParam.dhModelViewMatrix);
|
|
||||||
|
|
||||||
float earthCurveRatio = Config.Client.Advanced.Graphics.Experimental.earthCurveRatio.get();
|
|
||||||
if (earthCurveRatio < -1.0f || earthCurveRatio > 1.0f)
|
|
||||||
{
|
|
||||||
earthCurveRatio = /*6371KM*/ 6371000.0f / earthCurveRatio;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// disable curvature if the config value is between -1 and 1
|
|
||||||
earthCurveRatio = 0.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// upload data //
|
|
||||||
|
|
||||||
int uniformBufferSize = new Std140SizeCalculator()
|
|
||||||
.putInt() // uIsWhiteWorld
|
|
||||||
|
|
||||||
.putFloat() // uWorldYOffset
|
|
||||||
.putFloat() // uMircoOffset
|
|
||||||
.putFloat() // uEarthRadius
|
|
||||||
|
|
||||||
.putVec3() // uCameraPos
|
|
||||||
.putMat4f() // uCombinedMatrix
|
|
||||||
.get();
|
|
||||||
|
|
||||||
ByteBuffer buffer = MemoryUtil.memAlloc(uniformBufferSize);
|
|
||||||
buffer.order(ByteOrder.nativeOrder());
|
|
||||||
Std140Builder.intoBuffer(buffer)
|
|
||||||
.putInt(0) // uIsWhiteWorld
|
|
||||||
|
|
||||||
.putFloat((float) renderEventParam.worldYOffset) // uWorldYOffset
|
|
||||||
.putFloat(0.01f) // uMircoOffset // 0.01 block offset
|
|
||||||
.putFloat(earthCurveRatio) // uEarthRadius
|
|
||||||
|
|
||||||
.putVec3(
|
|
||||||
(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);
|
|
||||||
}
|
|
||||||
|
|
||||||
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();
|
|
||||||
if (!Config.Client.Advanced.Debugging.lodOnlyMode.get())
|
|
||||||
{
|
|
||||||
// this added value prevents the near clip plane and discard circle from touching, which looks bad
|
|
||||||
dhNearClipDistance += 16f;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// upload data //
|
|
||||||
|
|
||||||
ByteBuffer buffer = MemoryUtil.memAlloc(uniformBufferSize);
|
|
||||||
buffer.order(ByteOrder.nativeOrder());
|
|
||||||
buffer = Std140Builder.intoBuffer(buffer)
|
|
||||||
.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()
|
|
||||||
;
|
|
||||||
|
|
||||||
this.fragUniformBuffer = BlazeUniformUtil.createBuffer("fragUniformBlock", uniformBufferSize, this.fragUniformBuffer);
|
|
||||||
GpuBufferSlice bufferSlice = new GpuBufferSlice(this.fragUniformBuffer, 0, uniformBufferSize);
|
|
||||||
|
|
||||||
COMMAND_ENCODER.writeToBuffer(bufferSlice, buffer);
|
|
||||||
MemoryUtil.memFree(buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// render pass setup
|
|
||||||
{
|
|
||||||
profiler.popPush("setup");
|
|
||||||
|
|
||||||
// create a render pass
|
|
||||||
try(RenderPass renderPass = COMMAND_ENCODER.createRenderPass(
|
|
||||||
this::getRenderPassName,
|
|
||||||
BlazeDhMetaRenderer.INSTANCE.dhColorTextureWrapper.textureView,
|
|
||||||
/*optionalClearColorAsInt*/ OptionalInt.empty(),
|
|
||||||
BlazeDhMetaRenderer.INSTANCE.dhDepthTextureWrapper.textureView,
|
|
||||||
/*optionalDepthValueAsDouble*/ OptionalDouble.empty())
|
|
||||||
)
|
|
||||||
{
|
|
||||||
LightMapWrapper lightMapWrapper = (LightMapWrapper) renderEventParam.lightmap;
|
|
||||||
BlazeTextureViewWrapper lightmapTextureViewWrapper = lightMapWrapper.getTextureViewWrapper();
|
|
||||||
renderPass.bindTexture("uLightMap", lightmapTextureViewWrapper.textureView, lightmapTextureViewWrapper.textureSampler);
|
|
||||||
|
|
||||||
// set pipeline
|
|
||||||
renderPass.setPipeline(opaquePass ? this.opaquePipeline : this.transparentPipeline);
|
|
||||||
|
|
||||||
// shared uniforms
|
|
||||||
renderPass.setUniform("fragUniformBlock", this.fragUniformBuffer);
|
|
||||||
renderPass.setUniform("vertSharedUniformBlock", this.vertSharedUniformBuffer);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
for (int lodIndex = 0; lodIndex < bufferContainers.size(); lodIndex++)
|
for (int lodIndex = 0; lodIndex < bufferContainers.size(); lodIndex++)
|
||||||
{
|
{
|
||||||
profiler.popPush("binding");
|
|
||||||
|
|
||||||
LodBufferContainer bufferContainer = bufferContainers.get(lodIndex);
|
LodBufferContainer bufferContainer = bufferContainers.get(lodIndex);
|
||||||
BlazeLodUniformBufferWrapper uniformWrapper = (BlazeLodUniformBufferWrapper)bufferContainer.uniformContainer;
|
bufferContainer.uniformContainer.tryUpload();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
boolean columnBuilderDebugEnabled = Config.Client.Advanced.Debugging.ColumnBuilderDebugging.columnBuilderDebugEnable.get();
|
profiler.popPush("vert share uniforms");
|
||||||
if (columnBuilderDebugEnabled)
|
{
|
||||||
{
|
Mat4f combinedMatrix = new Mat4f(renderEventParam.dhProjectionMatrix);
|
||||||
if (DhSectionPos.getDetailLevel(bufferContainer.pos) == Config.Client.Advanced.Debugging.ColumnBuilderDebugging.columnBuilderDebugDetailLevel.get()
|
combinedMatrix.multiply(renderEventParam.dhModelViewMatrix);
|
||||||
&& DhSectionPos.getX(bufferContainer.pos) == Config.Client.Advanced.Debugging.ColumnBuilderDebugging.columnBuilderDebugXPos.get()
|
|
||||||
&& DhSectionPos.getZ(bufferContainer.pos) == Config.Client.Advanced.Debugging.ColumnBuilderDebugging.columnBuilderDebugZPos.get())
|
|
||||||
{
|
|
||||||
int breakpoint = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
renderPass.setUniform("vertUniqueUniformBlock", uniformWrapper.gpuBuffer);
|
float earthCurveRatio = Config.Client.Advanced.Graphics.Experimental.earthCurveRatio.get();
|
||||||
|
if (earthCurveRatio < -1.0f || earthCurveRatio > 1.0f)
|
||||||
|
{
|
||||||
|
earthCurveRatio = /*6371KM*/ 6371000.0f / earthCurveRatio;
|
||||||
profiler.popPush("rendering");
|
}
|
||||||
|
else
|
||||||
// render each buffer
|
{
|
||||||
IVertexBufferWrapper[] bufferWrapperList = opaquePass ? bufferContainer.vboOpaqueWrappers : bufferContainer.vboTransparentWrappers;
|
// disable curvature if the config value is between -1 and 1
|
||||||
for (int i = 0; i < bufferWrapperList.length; i++)
|
earthCurveRatio = 0.0f;
|
||||||
{
|
|
||||||
BlazeVertexBufferWrapper bufferWrapper = (BlazeVertexBufferWrapper) bufferWrapperList[i];
|
|
||||||
if (!bufferWrapper.uploaded
|
|
||||||
|| bufferWrapper.vertexCount == 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// fire render event
|
|
||||||
{
|
|
||||||
Vec3d camPos = renderEventParam.exactCameraPosition;
|
|
||||||
Vec3f modelPos = new Vec3f(
|
|
||||||
(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));
|
|
||||||
}
|
|
||||||
|
|
||||||
renderPass.setIndexBuffer(bufferWrapper.getIndexGpuBuffer(), VertexFormat.IndexType.INT);
|
|
||||||
renderPass.setVertexBuffer(0, bufferWrapper.vertexGpuBuffer); // vertex buffer can only be "0" lol
|
|
||||||
|
|
||||||
if (!bufferWrapper.vertexGpuBuffer.isClosed())
|
|
||||||
{
|
|
||||||
renderPass.drawIndexed(
|
|
||||||
/*indexStart*/ 0,
|
|
||||||
/*firstIndex*/0,
|
|
||||||
/*indexCount*/bufferWrapper.indexCount,
|
|
||||||
/*instanceCount*/1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// upload data //
|
||||||
|
|
||||||
|
int uniformBufferSize = new Std140SizeCalculator()
|
||||||
|
.putInt() // uIsWhiteWorld
|
||||||
|
|
||||||
|
.putFloat() // uWorldYOffset
|
||||||
|
.putFloat() // uMircoOffset
|
||||||
|
.putFloat() // uEarthRadius
|
||||||
|
|
||||||
|
.putVec3() // uCameraPos
|
||||||
|
.putMat4f() // uCombinedMatrix
|
||||||
|
.get();
|
||||||
|
|
||||||
|
ByteBuffer buffer = MemoryUtil.memAlloc(uniformBufferSize);
|
||||||
|
buffer.order(ByteOrder.nativeOrder());
|
||||||
|
Std140Builder.intoBuffer(buffer)
|
||||||
|
.putInt(0) // uIsWhiteWorld
|
||||||
|
|
||||||
|
.putFloat((float) renderEventParam.worldYOffset) // uWorldYOffset
|
||||||
|
.putFloat(0.01f) // uMircoOffset // 0.01 block offset
|
||||||
|
.putFloat(earthCurveRatio) // uEarthRadius
|
||||||
|
|
||||||
|
.putVec3(
|
||||||
|
(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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
if (!Config.Client.Advanced.Debugging.lodOnlyMode.get())
|
||||||
|
{
|
||||||
|
// this added value prevents the near clip plane and discard circle from touching, which looks bad
|
||||||
|
dhNearClipDistance += 16f;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// upload data //
|
||||||
|
|
||||||
|
ByteBuffer buffer = MemoryUtil.memAlloc(uniformBufferSize);
|
||||||
|
buffer.order(ByteOrder.nativeOrder());
|
||||||
|
buffer = Std140Builder.intoBuffer(buffer)
|
||||||
|
.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()
|
||||||
|
;
|
||||||
|
|
||||||
|
this.fragUniformBuffer = BlazeUniformUtil.createBuffer("fragUniformBlock", uniformBufferSize, this.fragUniformBuffer);
|
||||||
|
GpuBufferSlice bufferSlice = new GpuBufferSlice(this.fragUniformBuffer, 0, uniformBufferSize);
|
||||||
|
|
||||||
|
COMMAND_ENCODER.writeToBuffer(bufferSlice, buffer);
|
||||||
|
MemoryUtil.memFree(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// render pass setup
|
||||||
|
{
|
||||||
|
profiler.popPush("rendering");
|
||||||
|
|
||||||
|
// create a render pass
|
||||||
|
try (RenderPass renderPass = COMMAND_ENCODER.createRenderPass(
|
||||||
|
this::getRenderPassName,
|
||||||
|
BlazeDhMetaRenderer.INSTANCE.dhColorTextureWrapper.textureView,
|
||||||
|
/*optionalClearColorAsInt*/ OptionalInt.empty(),
|
||||||
|
BlazeDhMetaRenderer.INSTANCE.dhDepthTextureWrapper.textureView,
|
||||||
|
/*optionalDepthValueAsDouble*/ OptionalDouble.empty())
|
||||||
|
)
|
||||||
|
{
|
||||||
|
LightMapWrapper lightMapWrapper = (LightMapWrapper) renderEventParam.lightmap;
|
||||||
|
BlazeTextureViewWrapper lightmapTextureViewWrapper = lightMapWrapper.getTextureViewWrapper();
|
||||||
|
renderPass.bindTexture("uLightMap", lightmapTextureViewWrapper.textureView, lightmapTextureViewWrapper.textureSampler);
|
||||||
|
|
||||||
|
// set pipeline
|
||||||
|
renderPass.setPipeline(opaquePass ? this.opaquePipeline : this.transparentPipeline);
|
||||||
|
|
||||||
|
// shared uniforms
|
||||||
|
renderPass.setUniform("fragUniformBlock", this.fragUniformBuffer);
|
||||||
|
renderPass.setUniform("vertSharedUniformBlock", this.vertSharedUniformBuffer);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
for (int lodIndex = 0; lodIndex < bufferContainers.size(); lodIndex++)
|
||||||
|
{
|
||||||
|
LodBufferContainer bufferContainer = bufferContainers.get(lodIndex);
|
||||||
|
BlazeLodUniformBufferWrapper uniformWrapper = (BlazeLodUniformBufferWrapper) bufferContainer.uniformContainer;
|
||||||
|
|
||||||
|
boolean columnBuilderDebugEnabled = Config.Client.Advanced.Debugging.ColumnBuilderDebugging.columnBuilderDebugEnable.get();
|
||||||
|
if (columnBuilderDebugEnabled)
|
||||||
|
{
|
||||||
|
if (DhSectionPos.getDetailLevel(bufferContainer.pos) == Config.Client.Advanced.Debugging.ColumnBuilderDebugging.columnBuilderDebugDetailLevel.get()
|
||||||
|
&& DhSectionPos.getX(bufferContainer.pos) == Config.Client.Advanced.Debugging.ColumnBuilderDebugging.columnBuilderDebugXPos.get()
|
||||||
|
&& DhSectionPos.getZ(bufferContainer.pos) == Config.Client.Advanced.Debugging.ColumnBuilderDebugging.columnBuilderDebugZPos.get())
|
||||||
|
{
|
||||||
|
int breakpoint = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
renderPass.setUniform("vertUniqueUniformBlock", uniformWrapper.gpuBuffer);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// render each buffer
|
||||||
|
IVertexBufferWrapper[] bufferWrapperList = opaquePass ? bufferContainer.vboOpaqueWrappers : bufferContainer.vboTransparentWrappers;
|
||||||
|
for (int i = 0; i < bufferWrapperList.length; i++)
|
||||||
|
{
|
||||||
|
BlazeVertexBufferWrapper bufferWrapper = (BlazeVertexBufferWrapper) bufferWrapperList[i];
|
||||||
|
if (!bufferWrapper.uploaded
|
||||||
|
|| bufferWrapper.vertexCount == 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// fire render event
|
||||||
|
{
|
||||||
|
Vec3d camPos = renderEventParam.exactCameraPosition;
|
||||||
|
Vec3f modelPos = new Vec3f(
|
||||||
|
(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));
|
||||||
|
}
|
||||||
|
|
||||||
|
renderPass.setIndexBuffer(bufferWrapper.getIndexGpuBuffer(), VertexFormat.IndexType.INT);
|
||||||
|
renderPass.setVertexBuffer(0, bufferWrapper.vertexGpuBuffer); // vertex buffer can only be "0" lol
|
||||||
|
|
||||||
|
if (!bufferWrapper.vertexGpuBuffer.isClosed())
|
||||||
|
{
|
||||||
|
renderPass.drawIndexed(
|
||||||
|
/*indexStart*/ 0,
|
||||||
|
/*firstIndex*/0,
|
||||||
|
/*indexCount*/bufferWrapper.indexCount,
|
||||||
|
/*instanceCount*/1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
profiler.pop();
|
|
||||||
}
|
}
|
||||||
private String getIndexBufferName() { return "distantHorizons:LodIndexBuffer"; }
|
private String getIndexBufferName() { return "distantHorizons:LodIndexBuffer"; }
|
||||||
private String getRenderPassName() { return "distantHorizons:McLodRenderer"; }
|
private String getRenderPassName() { return "distantHorizons:McLodRenderer"; }
|
||||||
|
|||||||
+1
-1
@@ -17,7 +17,7 @@ import com.seibel.distanthorizons.common.render.openGl.glObject.enums.GLEnums;
|
|||||||
import com.seibel.distanthorizons.core.render.RenderThreadTaskHandler;
|
import com.seibel.distanthorizons.core.render.RenderThreadTaskHandler;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.render.objects.IDhGenericObjectVertexBufferContainer;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.render.objects.IDhGenericObjectVertexBufferContainer;
|
||||||
import com.seibel.distanthorizons.core.render.renderer.RenderableBoxGroup;
|
import com.seibel.distanthorizons.core.render.renderer.RenderableBoxGroup;
|
||||||
import com.seibel.distanthorizons.core.util.ColorUtil;
|
import com.seibel.distanthorizons.coreapi.util.ColorUtil;
|
||||||
import org.lwjgl.opengl.GL32;
|
import org.lwjgl.opengl.GL32;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
|||||||
+22
-5
@@ -1,15 +1,26 @@
|
|||||||
package com.seibel.distanthorizons.common.render.blaze.wrappers;
|
package com.seibel.distanthorizons.common.render.blaze.wrappers;
|
||||||
|
|
||||||
|
|
||||||
|
#if MC_VER <= MC_1_21_10
|
||||||
|
public class RenderPipelineBuilderWrapper {}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
import com.mojang.blaze3d.pipeline.BlendFunction;
|
import com.mojang.blaze3d.pipeline.BlendFunction;
|
||||||
import com.mojang.blaze3d.pipeline.ColorTargetState;
|
|
||||||
import com.mojang.blaze3d.pipeline.DepthStencilState;
|
|
||||||
import com.mojang.blaze3d.pipeline.RenderPipeline;
|
import com.mojang.blaze3d.pipeline.RenderPipeline;
|
||||||
import com.mojang.blaze3d.platform.CompareOp;
|
|
||||||
import com.mojang.blaze3d.platform.PolygonMode;
|
import com.mojang.blaze3d.platform.PolygonMode;
|
||||||
import com.mojang.blaze3d.shaders.UniformType;
|
import com.mojang.blaze3d.shaders.UniformType;
|
||||||
import com.mojang.blaze3d.vertex.VertexFormat;
|
import com.mojang.blaze3d.vertex.VertexFormat;
|
||||||
import net.minecraft.resources.Identifier;
|
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;
|
||||||
|
import com.mojang.blaze3d.platform.CompareOp;
|
||||||
|
#endif
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
@@ -206,15 +217,20 @@ public class RenderPipelineBuilderWrapper
|
|||||||
this.blazePipelineBuilder.withoutBlend();
|
this.blazePipelineBuilder.withoutBlend();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DepthTestFunction depthTestFunction;
|
||||||
switch (this.depthTest)
|
switch (this.depthTest)
|
||||||
{
|
{
|
||||||
case NONE:
|
case NONE:
|
||||||
|
depthTestFunction = DepthTestFunction.NO_DEPTH_TEST;
|
||||||
break;
|
break;
|
||||||
case LESS:
|
case LESS:
|
||||||
|
depthTestFunction = DepthTestFunction.LESS_DEPTH_TEST;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new UnsupportedOperationException("No depth test defined for type ["+this.depthTest+"].");
|
||||||
}
|
}
|
||||||
this.blazepipelineBuilder.withDepthTest(RenderPipelineBuilderWrapper.EDhDepthTest.NONE);
|
this.blazePipelineBuilder.withDepthTestFunction(depthTestFunction);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
@@ -349,3 +365,4 @@ public class RenderPipelineBuilderWrapper
|
|||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
+1
-6
@@ -140,7 +140,7 @@ public class BlazeVertexBufferWrapper implements IVertexBufferWrapper
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void uploadIndexBuffer(ByteBuffer buffer, int vertexCount)
|
public void uploadIndexBuffer(ByteBuffer indexBuffer, int vertexCount)
|
||||||
{
|
{
|
||||||
int oldIndexCount = this.indexCount;
|
int oldIndexCount = this.indexCount;
|
||||||
// 4 vertices per face, but 6 indices (IE 2 triangles) per face, aka need to multiply by 1.5
|
// 4 vertices per face, but 6 indices (IE 2 triangles) per face, aka need to multiply by 1.5
|
||||||
@@ -169,17 +169,12 @@ public class BlazeVertexBufferWrapper implements IVertexBufferWrapper
|
|||||||
this.indexGpuBuffer.close();
|
this.indexGpuBuffer.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
ByteBuffer indexBuffer = IndexBufferBuilder.createBuffer(this.vertexCount);
|
|
||||||
|
|
||||||
int usage = GpuBuffer.USAGE_COPY_DST
|
int usage = GpuBuffer.USAGE_COPY_DST
|
||||||
| GpuBuffer.USAGE_INDEX;
|
| GpuBuffer.USAGE_INDEX;
|
||||||
this.indexGpuBuffer = GPU_DEVICE.createBuffer(BlazeVertexBufferWrapper::getIndexBufferName, usage, indexBuffer.capacity());
|
this.indexGpuBuffer = GPU_DEVICE.createBuffer(BlazeVertexBufferWrapper::getIndexBufferName, usage, indexBuffer.capacity());
|
||||||
|
|
||||||
GpuBufferSlice bufferSlice = new GpuBufferSlice(this.indexGpuBuffer, /*offset*/ 0, indexBuffer.capacity());
|
GpuBufferSlice bufferSlice = new GpuBufferSlice(this.indexGpuBuffer, /*offset*/ 0, indexBuffer.capacity());
|
||||||
COMMAND_ENCODER.writeToBuffer(bufferSlice, indexBuffer);
|
COMMAND_ENCODER.writeToBuffer(bufferSlice, indexBuffer);
|
||||||
|
|
||||||
MemoryUtil.memFree(indexBuffer);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private static String getIndexBufferName() { return "distantHorizons:LodIndexBuffer"; }
|
private static String getIndexBufferName() { return "distantHorizons:LodIndexBuffer"; }
|
||||||
|
|||||||
+38
-28
@@ -13,7 +13,7 @@ import com.mojang.blaze3d.textures.*;
|
|||||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||||
import com.seibel.distanthorizons.core.logging.DhLogger;
|
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||||
import com.seibel.distanthorizons.core.util.ColorUtil;
|
import com.seibel.distanthorizons.coreapi.util.ColorUtil;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
|
||||||
|
|
||||||
import java.util.OptionalDouble;
|
import java.util.OptionalDouble;
|
||||||
@@ -79,42 +79,52 @@ public class BlazeTextureWrapper
|
|||||||
//=======//
|
//=======//
|
||||||
//region
|
//region
|
||||||
|
|
||||||
/** does nothing if the texture is already created and the correct size */
|
/**
|
||||||
public void tryCreateOrResize()
|
* does nothing if the texture is already created and the correct size
|
||||||
|
* @return true if the texture was (re)created
|
||||||
|
*/
|
||||||
|
public boolean tryCreateOrResize()
|
||||||
{
|
{
|
||||||
this.tryCreateTexture();
|
boolean textureChanged = this.tryCreateTexture();
|
||||||
this.tryCreateSampler();
|
this.tryCreateSampler();
|
||||||
|
return textureChanged;
|
||||||
}
|
}
|
||||||
private void tryCreateTexture()
|
private boolean tryCreateTexture()
|
||||||
{
|
{
|
||||||
int viewWidth = MC_RENDER.getTargetFramebufferViewportWidth();
|
int viewWidth = MC_RENDER.getTargetFramebufferViewportWidth();
|
||||||
int viewHeight = MC_RENDER.getTargetFramebufferViewportHeight();
|
int viewHeight = MC_RENDER.getTargetFramebufferViewportHeight();
|
||||||
|
|
||||||
if (this.texture == null
|
if (this.texture != null
|
||||||
|| this.width != viewWidth
|
&& this.width == viewWidth
|
||||||
|| this.height != viewHeight)
|
&& this.height == viewHeight)
|
||||||
{
|
{
|
||||||
if (this.texture != null)
|
// no changes needed
|
||||||
{
|
return false;
|
||||||
this.texture.close();
|
|
||||||
this.textureView.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
this.width = viewWidth;
|
|
||||||
this.height = viewHeight;
|
|
||||||
|
|
||||||
int usage = GpuTexture.USAGE_COPY_DST
|
|
||||||
| GpuTexture.USAGE_TEXTURE_BINDING
|
|
||||||
| GpuTexture.USAGE_COPY_SRC
|
|
||||||
| GpuTexture.USAGE_RENDER_ATTACHMENT;
|
|
||||||
this.texture = GPU_DEVICE.createTexture(this.name,
|
|
||||||
usage,
|
|
||||||
this.textureFormat,
|
|
||||||
viewWidth, viewHeight,
|
|
||||||
/*depthOrLayers*/ 1, /*mipLevels*/ 1
|
|
||||||
);
|
|
||||||
this.textureView = GPU_DEVICE.createTextureView(this.texture);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (this.texture != null)
|
||||||
|
{
|
||||||
|
this.texture.close();
|
||||||
|
this.textureView.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.width = viewWidth;
|
||||||
|
this.height = viewHeight;
|
||||||
|
|
||||||
|
int usage = GpuTexture.USAGE_COPY_DST
|
||||||
|
| GpuTexture.USAGE_TEXTURE_BINDING
|
||||||
|
| GpuTexture.USAGE_COPY_SRC
|
||||||
|
| GpuTexture.USAGE_RENDER_ATTACHMENT;
|
||||||
|
this.texture = GPU_DEVICE.createTexture(this.name,
|
||||||
|
usage,
|
||||||
|
this.textureFormat,
|
||||||
|
viewWidth, viewHeight,
|
||||||
|
/*depthOrLayers*/ 1, /*mipLevels*/ 1
|
||||||
|
);
|
||||||
|
this.textureView = GPU_DEVICE.createTextureView(this.texture);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
private void tryCreateSampler()
|
private void tryCreateSampler()
|
||||||
{
|
{
|
||||||
|
|||||||
+22
-23
@@ -14,6 +14,7 @@ import com.seibel.distanthorizons.common.render.openGl.terrain.GlDhTerrainShader
|
|||||||
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftGLWrapper;
|
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftGLWrapper;
|
||||||
import com.seibel.distanthorizons.common.wrappers.misc.LightMapWrapper;
|
import com.seibel.distanthorizons.common.wrappers.misc.LightMapWrapper;
|
||||||
import com.seibel.distanthorizons.core.config.Config;
|
import com.seibel.distanthorizons.core.config.Config;
|
||||||
|
import com.seibel.distanthorizons.core.dependencyInjection.ModAccessorInjector;
|
||||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||||
import com.seibel.distanthorizons.core.logging.DhLogger;
|
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||||
@@ -22,6 +23,7 @@ import com.seibel.distanthorizons.core.render.RenderParams;
|
|||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.ILightMapWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.ILightMapWrapper;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.AbstractOptifineAccessor;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.AbstractOptifineAccessor;
|
||||||
|
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IOptifineAccessor;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass.IDhMetaRenderer;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass.IDhMetaRenderer;
|
||||||
import com.seibel.distanthorizons.coreapi.DependencyInjection.ApiEventInjector;
|
import com.seibel.distanthorizons.coreapi.DependencyInjection.ApiEventInjector;
|
||||||
import com.seibel.distanthorizons.coreapi.DependencyInjection.OverrideInjector;
|
import com.seibel.distanthorizons.coreapi.DependencyInjection.OverrideInjector;
|
||||||
@@ -45,6 +47,8 @@ public class GlDhMetaRenderer implements IDhMetaRenderer
|
|||||||
private static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class);
|
private static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class);
|
||||||
private static final MinecraftGLWrapper GLMC = MinecraftGLWrapper.INSTANCE;
|
private static final MinecraftGLWrapper GLMC = MinecraftGLWrapper.INSTANCE;
|
||||||
|
|
||||||
|
private static final IOptifineAccessor OPTIFINE_ACCESSOR = ModAccessorInjector.INSTANCE.get(IOptifineAccessor.class);
|
||||||
|
|
||||||
|
|
||||||
private int activeFramebufferId = -1;
|
private int activeFramebufferId = -1;
|
||||||
private int activeColorTextureId = -1;
|
private int activeColorTextureId = -1;
|
||||||
@@ -242,7 +246,7 @@ public class GlDhMetaRenderer implements IDhMetaRenderer
|
|||||||
|
|
||||||
|
|
||||||
// create or get the frame buffer
|
// create or get the frame buffer
|
||||||
if (AbstractOptifineAccessor.optifinePresent())
|
if (OPTIFINE_ACCESSOR != null)
|
||||||
{
|
{
|
||||||
// use MC/Optifine's default Framebuffer so shaders won't remove the LODs
|
// use MC/Optifine's default Framebuffer so shaders won't remove the LODs
|
||||||
int currentFramebufferId = MC_RENDER.getTargetFramebuffer();
|
int currentFramebufferId = MC_RENDER.getTargetFramebuffer();
|
||||||
@@ -383,31 +387,26 @@ public class GlDhMetaRenderer implements IDhMetaRenderer
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
// needs to be fired after all the textures have been created/bound
|
GL32.glClearDepth(1.0);
|
||||||
boolean clearTextures = !ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeTextureClearEvent.class, renderParams);
|
|
||||||
if (clearTextures)
|
float[] clearColorValues = new float[4];
|
||||||
|
GL32.glGetFloatv(GL32.GL_COLOR_CLEAR_VALUE, clearColorValues);
|
||||||
|
GL32.glClearColor(clearColorValues[0], clearColorValues[1], clearColorValues[2], 1.0f);
|
||||||
|
|
||||||
|
if (this.usingMcFramebuffer
|
||||||
|
&& framebufferOverride == null)
|
||||||
{
|
{
|
||||||
GL32.glClearDepth(1.0);
|
//// Due to using MC/Optifine's framebuffer we need to re-bind the depth texture,
|
||||||
|
//// otherwise we'll be writing to MC/Optifine's depth texture which causes rendering issues
|
||||||
float[] clearColorValues = new float[4];
|
//this.framebuffer.addDepthAttachment(this.depthTexture.getTextureId(), EDhDepthBufferFormat.DEPTH32F.isCombinedStencil());
|
||||||
GL32.glGetFloatv(GL32.GL_COLOR_CLEAR_VALUE, clearColorValues);
|
|
||||||
GL32.glClearColor(clearColorValues[0], clearColorValues[1], clearColorValues[2], 1.0f);
|
|
||||||
|
|
||||||
if (this.usingMcFramebuffer
|
|
||||||
&& framebufferOverride == null)
|
|
||||||
{
|
|
||||||
//// Due to using MC/Optifine's framebuffer we need to re-bind the depth texture,
|
|
||||||
//// otherwise we'll be writing to MC/Optifine's depth texture which causes rendering issues
|
|
||||||
//this.framebuffer.addDepthAttachment(this.depthTexture.getTextureId(), EDhDepthBufferFormat.DEPTH32F.isCombinedStencil());
|
|
||||||
|
|
||||||
|
|
||||||
// don't clear the color texture, that removes the sky
|
// don't clear the color texture, that removes the sky
|
||||||
GL32.glClear(GL32.GL_DEPTH_BUFFER_BIT);
|
GL32.glClear(GL32.GL_DEPTH_BUFFER_BIT);
|
||||||
}
|
}
|
||||||
else if (firstPass)
|
else if (firstPass)
|
||||||
{
|
{
|
||||||
GL32.glClear(GL32.GL_COLOR_BUFFER_BIT | GL32.GL_DEPTH_BUFFER_BIT);
|
GL32.glClear(GL32.GL_COLOR_BUFFER_BIT | GL32.GL_DEPTH_BUFFER_BIT);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+163
-166
@@ -413,133 +413,133 @@ public class GlGenericObjectRenderer implements IDhGenericRenderer
|
|||||||
|
|
||||||
|
|
||||||
// render setup //
|
// render setup //
|
||||||
profiler.push("setup");
|
try (IProfilerWrapper.IProfileBlock setup_profile = profiler.push("setup"))
|
||||||
|
|
||||||
this.init();
|
|
||||||
|
|
||||||
ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeGenericRenderSetupEvent.class, renderEventParam);
|
|
||||||
|
|
||||||
|
|
||||||
boolean renderWireframe = Config.Client.Advanced.Debugging.renderWireframe.get();
|
|
||||||
if (renderWireframe)
|
|
||||||
{
|
{
|
||||||
GL32.glPolygonMode(GL32.GL_FRONT_AND_BACK, GL32.GL_LINE);
|
|
||||||
GLMC.disableFaceCulling();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
GL32.glPolygonMode(GL32.GL_FRONT_AND_BACK, GL32.GL_FILL);
|
|
||||||
GLMC.enableFaceCulling();
|
|
||||||
}
|
|
||||||
|
|
||||||
GLMC.enableBlend();
|
this.init();
|
||||||
GL32.glBlendEquation(GL32.GL_FUNC_ADD);
|
|
||||||
GLMC.glBlendFuncSeparate(GL32.GL_SRC_ALPHA, GL32.GL_ONE_MINUS_SRC_ALPHA, GL32.GL_ONE, GL32.GL_ONE_MINUS_SRC_ALPHA);
|
|
||||||
|
|
||||||
IDhApiGenericObjectShaderProgram shaderProgram = this.instancedRenderingAvailable ? this.instancedShaderProgram : this.directShaderProgram;
|
ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeGenericRenderSetupEvent.class, renderEventParam);
|
||||||
IDhApiGenericObjectShaderProgram shaderProgramOverride = OverrideInjector.INSTANCE.get(IDhApiGenericObjectShaderProgram.class);
|
|
||||||
if (shaderProgramOverride != null && shaderProgram.overrideThisFrame())
|
|
||||||
{
|
|
||||||
shaderProgram = shaderProgramOverride;
|
|
||||||
}
|
|
||||||
|
|
||||||
shaderProgram.bind(renderEventParam);
|
|
||||||
shaderProgram.bindVertexBuffer(this.boxVertexBuffer.getId());
|
|
||||||
|
|
||||||
this.boxIndexBuffer.bind();
|
|
||||||
|
|
||||||
Vec3d camPos = MC_RENDER.getCameraExactPosition();
|
|
||||||
|
|
||||||
|
|
||||||
|
boolean renderWireframe = Config.Client.Advanced.Debugging.renderWireframe.get();
|
||||||
// rendering //
|
if (renderWireframe)
|
||||||
|
|
||||||
Collection<RenderableBoxGroup> boxList = this.boxGroupById.values();
|
|
||||||
for (RenderableBoxGroup boxGroup : boxList)
|
|
||||||
{
|
|
||||||
// validation //
|
|
||||||
|
|
||||||
// shouldn't happen, but just in case
|
|
||||||
if (boxGroup == null)
|
|
||||||
{
|
{
|
||||||
continue;
|
GL32.glPolygonMode(GL32.GL_FRONT_AND_BACK, GL32.GL_LINE);
|
||||||
}
|
GLMC.disableFaceCulling();
|
||||||
|
|
||||||
// skip boxes that shouldn't render this pass
|
|
||||||
if (boxGroup.ssaoEnabled != renderingWithSsao)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
profiler.popPush("render prep");
|
|
||||||
boxGroup.preRender(renderEventParam); // called even if the group is inactive, so the group can be activate if desired
|
|
||||||
|
|
||||||
// ignore inactive groups
|
|
||||||
if (!boxGroup.active)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// allow API users to cancel this object's rendering
|
|
||||||
boolean cancelRendering = ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeGenericObjectRenderEvent.class, new DhApiBeforeGenericObjectRenderEvent.EventParam(renderEventParam, boxGroup));
|
|
||||||
if (cancelRendering)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// update instanced data if needed
|
|
||||||
if (this.instancedRenderingAvailable)
|
|
||||||
{
|
|
||||||
boxGroup.tryUpdateInstancedDataAsync();
|
|
||||||
|
|
||||||
// skip groups that haven't been uploaded yet
|
|
||||||
if (boxGroup.vertexBufferContainer.getState() != GlGenericObjectVertexContainer.EState.RENDER)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// render //
|
|
||||||
|
|
||||||
profiler.popPush("rendering");
|
|
||||||
profiler.push(boxGroup.getResourceLocationNamespace());
|
|
||||||
profiler.push(boxGroup.getResourceLocationPath());
|
|
||||||
if (this.instancedRenderingAvailable)
|
|
||||||
{
|
|
||||||
this.renderBoxGroupInstanced(shaderProgram, renderEventParam, boxGroup, camPos, profiler);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
this.renderBoxGroupDirect(shaderProgram, renderEventParam, boxGroup, camPos, profiler);
|
GL32.glPolygonMode(GL32.GL_FRONT_AND_BACK, GL32.GL_FILL);
|
||||||
|
GLMC.enableFaceCulling();
|
||||||
}
|
}
|
||||||
profiler.pop(); // resource path
|
|
||||||
profiler.pop(); // resource namespace
|
|
||||||
|
|
||||||
boxGroup.postRender(renderEventParam);
|
GLMC.enableBlend();
|
||||||
|
GL32.glBlendEquation(GL32.GL_FUNC_ADD);
|
||||||
|
GLMC.glBlendFuncSeparate(GL32.GL_SRC_ALPHA, GL32.GL_ONE_MINUS_SRC_ALPHA, GL32.GL_ONE, GL32.GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
|
||||||
|
IDhApiGenericObjectShaderProgram shaderProgram = this.instancedRenderingAvailable ? this.instancedShaderProgram : this.directShaderProgram;
|
||||||
|
IDhApiGenericObjectShaderProgram shaderProgramOverride = OverrideInjector.INSTANCE.get(IDhApiGenericObjectShaderProgram.class);
|
||||||
|
if (shaderProgramOverride != null && shaderProgram.overrideThisFrame())
|
||||||
|
{
|
||||||
|
shaderProgram = shaderProgramOverride;
|
||||||
|
}
|
||||||
|
|
||||||
|
shaderProgram.bind(renderEventParam);
|
||||||
|
shaderProgram.bindVertexBuffer(this.boxVertexBuffer.getId());
|
||||||
|
|
||||||
|
this.boxIndexBuffer.bind();
|
||||||
|
|
||||||
|
Vec3d camPos = MC_RENDER.getCameraExactPosition();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// rendering //
|
||||||
|
|
||||||
|
Collection<RenderableBoxGroup> boxList = this.boxGroupById.values();
|
||||||
|
for (RenderableBoxGroup boxGroup : boxList)
|
||||||
|
{
|
||||||
|
// validation //
|
||||||
|
|
||||||
|
// shouldn't happen, but just in case
|
||||||
|
if (boxGroup == null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// skip boxes that shouldn't render this pass
|
||||||
|
if (boxGroup.ssaoEnabled != renderingWithSsao)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
profiler.popPush("render prep");
|
||||||
|
boxGroup.preRender(renderEventParam); // called even if the group is inactive, so the group can be activate if desired
|
||||||
|
|
||||||
|
// ignore inactive groups
|
||||||
|
if (!boxGroup.active)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// allow API users to cancel this object's rendering
|
||||||
|
boolean cancelRendering = ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeGenericObjectRenderEvent.class, new DhApiBeforeGenericObjectRenderEvent.EventParam(renderEventParam, boxGroup));
|
||||||
|
if (cancelRendering)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// update instanced data if needed
|
||||||
|
if (this.instancedRenderingAvailable)
|
||||||
|
{
|
||||||
|
boxGroup.tryUpdateInstancedDataAsync();
|
||||||
|
|
||||||
|
// skip groups that haven't been uploaded yet
|
||||||
|
if (boxGroup.vertexBufferContainer.getState() != GlGenericObjectVertexContainer.EState.RENDER)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// render //
|
||||||
|
|
||||||
|
profiler.popPush("rendering");
|
||||||
|
try (IProfilerWrapper.IProfileBlock namespace_profile = profiler.push(boxGroup.getResourceLocationNamespace());
|
||||||
|
IProfilerWrapper.IProfileBlock location_profile = profiler.push(boxGroup.getResourceLocationPath()))
|
||||||
|
{
|
||||||
|
if (this.instancedRenderingAvailable)
|
||||||
|
{
|
||||||
|
this.renderBoxGroupInstanced(shaderProgram, renderEventParam, boxGroup, camPos, profiler);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.renderBoxGroupDirect(shaderProgram, renderEventParam, boxGroup, camPos, profiler);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
boxGroup.postRender(renderEventParam);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//==========//
|
||||||
|
// clean up //
|
||||||
|
//==========//
|
||||||
|
|
||||||
|
profiler.popPush("cleanup");
|
||||||
|
|
||||||
|
ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeGenericRenderCleanupEvent.class, renderEventParam);
|
||||||
|
|
||||||
|
if (renderWireframe)
|
||||||
|
{
|
||||||
|
// default back to GL_FILL since all other rendering uses it
|
||||||
|
GL32.glPolygonMode(GL32.GL_FRONT_AND_BACK, GL32.GL_FILL);
|
||||||
|
GLMC.enableFaceCulling();
|
||||||
|
}
|
||||||
|
|
||||||
|
shaderProgram.unbind();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//==========//
|
|
||||||
// clean up //
|
|
||||||
//==========//
|
|
||||||
|
|
||||||
profiler.popPush("cleanup");
|
|
||||||
|
|
||||||
ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeGenericRenderCleanupEvent.class, renderEventParam);
|
|
||||||
|
|
||||||
if (renderWireframe)
|
|
||||||
{
|
|
||||||
// default back to GL_FILL since all other rendering uses it
|
|
||||||
GL32.glPolygonMode(GL32.GL_FRONT_AND_BACK, GL32.GL_FILL);
|
|
||||||
GLMC.enableFaceCulling();
|
|
||||||
}
|
|
||||||
|
|
||||||
shaderProgram.unbind();
|
|
||||||
|
|
||||||
profiler.pop();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//endregion
|
//endregion
|
||||||
@@ -556,72 +556,71 @@ public class GlGenericObjectRenderer implements IDhGenericRenderer
|
|||||||
RenderableBoxGroup boxGroup, Vec3d camPos,
|
RenderableBoxGroup boxGroup, Vec3d camPos,
|
||||||
IProfilerWrapper profiler)
|
IProfilerWrapper profiler)
|
||||||
{
|
{
|
||||||
// update instance data //
|
try (IProfilerWrapper.IProfileBlock render_profile = profiler.push("vertex setup"))
|
||||||
|
|
||||||
profiler.push("vertex setup");
|
|
||||||
|
|
||||||
DhApiRenderableBoxGroupShading shading = boxGroup.shading;
|
|
||||||
if (shading == null)
|
|
||||||
{
|
{
|
||||||
shading = DEFAULT_SHADING;
|
|
||||||
}
|
|
||||||
|
|
||||||
shaderProgram.fillIndirectUniformData(
|
// update instance data //
|
||||||
|
DhApiRenderableBoxGroupShading shading = boxGroup.shading;
|
||||||
|
if (shading == null)
|
||||||
|
{
|
||||||
|
shading = DEFAULT_SHADING;
|
||||||
|
}
|
||||||
|
|
||||||
|
shaderProgram.fillIndirectUniformData(
|
||||||
renderEventParam,
|
renderEventParam,
|
||||||
shading, boxGroup,
|
shading, boxGroup,
|
||||||
camPos);
|
camPos);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Bind instance data //
|
// Bind instance data //
|
||||||
profiler.popPush("binding");
|
profiler.popPush("binding");
|
||||||
|
|
||||||
GlGenericObjectVertexContainer container = (GlGenericObjectVertexContainer)(boxGroup.vertexBufferContainer);
|
GlGenericObjectVertexContainer container = (GlGenericObjectVertexContainer) (boxGroup.vertexBufferContainer);
|
||||||
|
|
||||||
GL32.glBindBuffer(GL32.GL_ARRAY_BUFFER, container.color);
|
GL32.glBindBuffer(GL32.GL_ARRAY_BUFFER, container.color);
|
||||||
GL32.glEnableVertexAttribArray(1);
|
GL32.glEnableVertexAttribArray(1);
|
||||||
GL32.glVertexAttribPointer(1, 4, GL32.GL_FLOAT, false, 4 * Float.BYTES, 0);
|
GL32.glVertexAttribPointer(1, 4, GL32.GL_FLOAT, false, 4 * Float.BYTES, 0);
|
||||||
this.vertexAttribDivisor(1, 1);
|
this.vertexAttribDivisor(1, 1);
|
||||||
|
|
||||||
GL32.glBindBuffer(GL32.GL_ARRAY_BUFFER, container.scale);
|
GL32.glBindBuffer(GL32.GL_ARRAY_BUFFER, container.scale);
|
||||||
GL32.glEnableVertexAttribArray(2);
|
GL32.glEnableVertexAttribArray(2);
|
||||||
this.vertexAttribDivisor(2, 1);
|
this.vertexAttribDivisor(2, 1);
|
||||||
GL32.glVertexAttribPointer(2, 3, GL32.GL_FLOAT, false, 3 * Float.BYTES, 0);
|
GL32.glVertexAttribPointer(2, 3, GL32.GL_FLOAT, false, 3 * Float.BYTES, 0);
|
||||||
|
|
||||||
GL32.glBindBuffer(GL32.GL_ARRAY_BUFFER, container.chunkPos);
|
GL32.glBindBuffer(GL32.GL_ARRAY_BUFFER, container.chunkPos);
|
||||||
GL32.glEnableVertexAttribArray(3);
|
GL32.glEnableVertexAttribArray(3);
|
||||||
this.vertexAttribDivisor(3, 1);
|
this.vertexAttribDivisor(3, 1);
|
||||||
GL32.glVertexAttribIPointer(3, 3, GL32.GL_INT, 3 * Integer.BYTES, 0);
|
GL32.glVertexAttribIPointer(3, 3, GL32.GL_INT, 3 * Integer.BYTES, 0);
|
||||||
|
|
||||||
GL32.glBindBuffer(GL32.GL_ARRAY_BUFFER, container.subChunkPos);
|
GL32.glBindBuffer(GL32.GL_ARRAY_BUFFER, container.subChunkPos);
|
||||||
GL32.glEnableVertexAttribArray(4);
|
GL32.glEnableVertexAttribArray(4);
|
||||||
this.vertexAttribDivisor(4, 1);
|
this.vertexAttribDivisor(4, 1);
|
||||||
GL32.glVertexAttribPointer(4, 3, GL32.GL_FLOAT, false, 3 * Float.BYTES, 0);
|
GL32.glVertexAttribPointer(4, 3, GL32.GL_FLOAT, false, 3 * Float.BYTES, 0);
|
||||||
|
|
||||||
GL32.glBindBuffer(GL32.GL_ARRAY_BUFFER, container.material);
|
GL32.glBindBuffer(GL32.GL_ARRAY_BUFFER, container.material);
|
||||||
GL32.glEnableVertexAttribArray(5);
|
GL32.glEnableVertexAttribArray(5);
|
||||||
this.vertexAttribDivisor(5, 1);
|
this.vertexAttribDivisor(5, 1);
|
||||||
GL32.glVertexAttribIPointer(5, 1, GL32.GL_BYTE, Byte.BYTES, 0);
|
GL32.glVertexAttribIPointer(5, 1, GL32.GL_BYTE, Byte.BYTES, 0);
|
||||||
|
|
||||||
|
|
||||||
// Draw instanced
|
// Draw instanced
|
||||||
profiler.popPush("render");
|
profiler.popPush("render");
|
||||||
if (container.uploadedBoxCount > 0)
|
if (container.uploadedBoxCount > 0)
|
||||||
{
|
{
|
||||||
GL32.glDrawElementsInstanced(GL32.GL_TRIANGLES, BOX_INDICES.length, GL32.GL_UNSIGNED_INT, 0, container.uploadedBoxCount);
|
GL32.glDrawElementsInstanced(GL32.GL_TRIANGLES, BOX_INDICES.length, GL32.GL_UNSIGNED_INT, 0, container.uploadedBoxCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Clean up
|
||||||
|
profiler.popPush("cleanup");
|
||||||
|
|
||||||
|
GL32.glDisableVertexAttribArray(1);
|
||||||
|
GL32.glDisableVertexAttribArray(2);
|
||||||
|
GL32.glDisableVertexAttribArray(3);
|
||||||
|
GL32.glDisableVertexAttribArray(4);
|
||||||
|
GL32.glDisableVertexAttribArray(5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Clean up
|
|
||||||
profiler.popPush("cleanup");
|
|
||||||
|
|
||||||
GL32.glDisableVertexAttribArray(1);
|
|
||||||
GL32.glDisableVertexAttribArray(2);
|
|
||||||
GL32.glDisableVertexAttribArray(3);
|
|
||||||
GL32.glDisableVertexAttribArray(4);
|
|
||||||
GL32.glDisableVertexAttribArray(5);
|
|
||||||
|
|
||||||
profiler.pop();
|
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Clean way to handle both {@link GL33#glVertexAttribDivisor} and {@link ARBInstancedArrays#glVertexAttribDivisorARB}
|
* Clean way to handle both {@link GL33#glVertexAttribDivisor} and {@link ARBInstancedArrays#glVertexAttribDivisorARB}
|
||||||
@@ -689,8 +688,6 @@ public class GlGenericObjectRenderer implements IDhGenericRenderer
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
profiler.pop();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//endregion
|
//endregion
|
||||||
|
|||||||
+40
-9
@@ -21,13 +21,17 @@ package com.seibel.distanthorizons.common.render.openGl.glObject;
|
|||||||
|
|
||||||
import com.seibel.distanthorizons.api.enums.config.EDhApiGLErrorHandlingMode;
|
import com.seibel.distanthorizons.api.enums.config.EDhApiGLErrorHandlingMode;
|
||||||
import com.seibel.distanthorizons.api.enums.config.EDhApiGpuUploadMethod;
|
import com.seibel.distanthorizons.api.enums.config.EDhApiGpuUploadMethod;
|
||||||
|
import com.seibel.distanthorizons.api.enums.config.EDhApiLoggerLevel;
|
||||||
import com.seibel.distanthorizons.core.config.Config;
|
import com.seibel.distanthorizons.core.config.Config;
|
||||||
|
import com.seibel.distanthorizons.core.config.types.ConfigEntry;
|
||||||
|
import com.seibel.distanthorizons.core.dependencyInjection.ModAccessorInjector;
|
||||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||||
import com.seibel.distanthorizons.core.jar.EPlatform;
|
import com.seibel.distanthorizons.core.jar.EPlatform;
|
||||||
import com.seibel.distanthorizons.core.logging.DhLogger;
|
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||||
import com.seibel.distanthorizons.core.util.objects.GLMessages.*;
|
import com.seibel.distanthorizons.core.util.objects.GLMessages.*;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
|
||||||
|
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IIrisAccessor;
|
||||||
import com.seibel.distanthorizons.coreapi.ModInfo;
|
import com.seibel.distanthorizons.coreapi.ModInfo;
|
||||||
import org.lwjgl.glfw.GLFW;
|
import org.lwjgl.glfw.GLFW;
|
||||||
import org.lwjgl.opengl.GL;
|
import org.lwjgl.opengl.GL;
|
||||||
@@ -46,10 +50,30 @@ import java.util.concurrent.ConcurrentHashMap;
|
|||||||
*/
|
*/
|
||||||
public class GLProxy
|
public class GLProxy
|
||||||
{
|
{
|
||||||
public static final DhLogger LOGGER = new DhLoggerBuilder()
|
private static final IIrisAccessor IRIS_ACCESSOR = ModAccessorInjector.INSTANCE.get(IIrisAccessor.class);
|
||||||
.fileLevelConfig(Config.Common.Logging.logRendererGLEventToFile)
|
|
||||||
.chatLevelConfig(Config.Common.Logging.logRendererGLEventToChat)
|
public static final DhLogger LOGGER;
|
||||||
.build();
|
static
|
||||||
|
{
|
||||||
|
DhLoggerBuilder loggerBuilder = new DhLoggerBuilder();
|
||||||
|
loggerBuilder.fileLevelConfig(Config.Common.Logging.logRendererGLEventToFile);
|
||||||
|
|
||||||
|
// don't send chat messages if Iris is present since
|
||||||
|
// Iris is known to cause (harmless) GL errors
|
||||||
|
// and this can confuse users
|
||||||
|
boolean irisPresent = (IRIS_ACCESSOR != null);
|
||||||
|
if (!irisPresent)
|
||||||
|
{
|
||||||
|
loggerBuilder.chatLevelConfig(Config.Common.Logging.logRendererGLEventToChat);
|
||||||
|
}
|
||||||
|
|
||||||
|
LOGGER = loggerBuilder.build();
|
||||||
|
|
||||||
|
if (irisPresent)
|
||||||
|
{
|
||||||
|
LOGGER.info("Iris detected, Distant Horizons OpenGL error logging won't be sent in the chat due to Iris throwing known (harmless) OpenGL errors. This is a bug with Iris, not Distant Horizons.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static final Set<String> LOGGED_GL_MESSAGES = Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>());
|
public static final Set<String> LOGGED_GL_MESSAGES = Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>());
|
||||||
|
|
||||||
@@ -238,7 +262,7 @@ public class GLProxy
|
|||||||
//region
|
//region
|
||||||
|
|
||||||
/** this method is called on the render thread at the point of the GL Error */
|
/** this method is called on the render thread at the point of the GL Error */
|
||||||
private static void logMessage(GLMessage msg)
|
private static void logMessage(GLMessage glMessage)
|
||||||
{
|
{
|
||||||
EDhApiGLErrorHandlingMode errorHandlingMode = Config.Client.Advanced.Debugging.OpenGl.glErrorHandlingMode.get();
|
EDhApiGLErrorHandlingMode errorHandlingMode = Config.Client.Advanced.Debugging.OpenGl.glErrorHandlingMode.get();
|
||||||
if (errorHandlingMode == EDhApiGLErrorHandlingMode.IGNORE)
|
if (errorHandlingMode == EDhApiGLErrorHandlingMode.IGNORE)
|
||||||
@@ -249,19 +273,26 @@ public class GLProxy
|
|||||||
|
|
||||||
|
|
||||||
boolean onlyLogOnce = Config.Client.Advanced.Debugging.OpenGl.onlyLogGlErrorsOnce.get();
|
boolean onlyLogOnce = Config.Client.Advanced.Debugging.OpenGl.onlyLogGlErrorsOnce.get();
|
||||||
String errorMessage = "GL ERROR [" + msg.id + "] from [" + msg.source + "]: [" + msg.message + "]"+(onlyLogOnce ? " this message will only be logged once" : "")+".";
|
|
||||||
if (onlyLogOnce
|
if (onlyLogOnce
|
||||||
&& !LOGGED_GL_MESSAGES.add(errorMessage))
|
&& !LOGGED_GL_MESSAGES.add(glMessage.message))
|
||||||
{
|
{
|
||||||
// this message has already been logged
|
// this message has already been logged
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String errorMessage = "GL ERROR [" + glMessage.id + "] from [" + glMessage.source + "]: [" + glMessage.message + "].";
|
||||||
|
if (onlyLogOnce)
|
||||||
|
{
|
||||||
|
errorMessage += " This message will only be logged once.";
|
||||||
|
errorMessage += " Note: Distant Horizons will catch and log OpenGL errors from other mods, not just DH itself; if everything is rendering correctly these errors can probably be ignored.";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// create an exception so we get a stacktrace of where the message was triggered from
|
// create an exception so we get a stacktrace of where the message was triggered from
|
||||||
RuntimeException exception = new RuntimeException(errorMessage);
|
RuntimeException exception = new RuntimeException(errorMessage);
|
||||||
|
|
||||||
if (msg.type == EGLMessageType.ERROR || msg.type == EGLMessageType.UNDEFINED_BEHAVIOR)
|
if (glMessage.type == EGLMessageType.ERROR || glMessage.type == EGLMessageType.UNDEFINED_BEHAVIOR)
|
||||||
{
|
{
|
||||||
// critical error
|
// critical error
|
||||||
|
|
||||||
@@ -278,7 +309,7 @@ public class GLProxy
|
|||||||
{
|
{
|
||||||
// non-critical log
|
// non-critical log
|
||||||
|
|
||||||
EGLMessageSeverity severity = msg.severity;
|
EGLMessageSeverity severity = glMessage.severity;
|
||||||
if (severity == null)
|
if (severity == null)
|
||||||
{
|
{
|
||||||
// just in case the message was malformed
|
// just in case the message was malformed
|
||||||
|
|||||||
+9
-4
@@ -210,9 +210,12 @@ public class GLBuffer implements AutoCloseable
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
// re-binding the old VBO is necessary for old MC versions (IE 1.16.5 and older)
|
// re-binding the old buffers is necessary for old MC versions for the following reasons:
|
||||||
// otherwise the screen may be black when on the home menu
|
// for 16.5 and older the screen may be black when on the home menu
|
||||||
int previousBoundVbo = GL32.glGetInteger(GL32.GL_ARRAY_BUFFER_BINDING);
|
// and for 1.19.2 - 1.21.4 the inventory/UI will render without a background
|
||||||
|
int vao = GL32.glGetInteger(GL32.GL_VERTEX_ARRAY_BINDING);
|
||||||
|
int vbo = GL32.glGetInteger(GL32.GL_ARRAY_BUFFER_BINDING);
|
||||||
|
int ebo = GL32.glGetInteger(GL32.GL_ELEMENT_ARRAY_BUFFER_BINDING);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -238,7 +241,9 @@ public class GLBuffer implements AutoCloseable
|
|||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
GL32.glBindBuffer(GL32.GL_ARRAY_BUFFER, GL32.glIsBuffer(previousBoundVbo) ? previousBoundVbo : 0);
|
GL32.glBindVertexArray(GL32.glIsVertexArray(vao) ? vao : 0);
|
||||||
|
GL32.glBindBuffer(GL32.GL_ARRAY_BUFFER, GL32.glIsBuffer(vbo) ? vbo : 0);
|
||||||
|
GL32.glBindBuffer(GL32.GL_ELEMENT_ARRAY_BUFFER, GL32.glIsBuffer(ebo) ? ebo: 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/** Requires the buffer to be bound */
|
/** Requires the buffer to be bound */
|
||||||
|
|||||||
+7
-3
@@ -22,15 +22,16 @@ package com.seibel.distanthorizons.common.render.openGl.glObject.buffer;
|
|||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
import com.seibel.distanthorizons.common.render.openGl.glObject.GLProxy;
|
import com.seibel.distanthorizons.common.render.openGl.glObject.GLProxy;
|
||||||
|
import com.seibel.distanthorizons.core.dataObjects.render.bufferBuilding.IndexBufferBuilder;
|
||||||
import com.seibel.distanthorizons.core.dataObjects.render.bufferBuilding.LodQuadBuilder;
|
import com.seibel.distanthorizons.core.dataObjects.render.bufferBuilding.LodQuadBuilder;
|
||||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||||
import com.seibel.distanthorizons.core.jar.EPlatform;
|
|
||||||
import com.seibel.distanthorizons.core.render.RenderThreadTaskHandler;
|
import com.seibel.distanthorizons.core.render.RenderThreadTaskHandler;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.render.AbstractDhRenderApiDefinition;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.render.AbstractDhRenderApiDefinition;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.render.objects.IVertexBufferWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.render.objects.IVertexBufferWrapper;
|
||||||
import org.lwjgl.opengl.GL32;
|
import org.lwjgl.opengl.GL32;
|
||||||
|
|
||||||
import com.seibel.distanthorizons.api.enums.config.EDhApiGpuUploadMethod;
|
import com.seibel.distanthorizons.api.enums.config.EDhApiGpuUploadMethod;
|
||||||
|
import org.lwjgl.system.MemoryUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is a container for a OpenGL
|
* This is a container for a OpenGL
|
||||||
@@ -83,7 +84,10 @@ public class GLVertexBuffer extends GLBuffer implements IVertexBufferWrapper
|
|||||||
int maxSize = LodQuadBuilder.getMaxBufferByteSize();
|
int maxSize = LodQuadBuilder.getMaxBufferByteSize();
|
||||||
int maxVertexCount = maxSize / LodQuadBuilder.BYTES_PER_VERTEX;
|
int maxVertexCount = maxSize / LodQuadBuilder.BYTES_PER_VERTEX;
|
||||||
int maxQuadCount = (maxVertexCount / 4);
|
int maxQuadCount = (maxVertexCount / 4);
|
||||||
GLOBAL_QUAD_IBO.upload(maxQuadCount);
|
|
||||||
|
ByteBuffer buffer = IndexBufferBuilder.createBuffer(maxQuadCount);
|
||||||
|
GLOBAL_QUAD_IBO.upload(buffer, maxQuadCount);
|
||||||
|
MemoryUtil.memFree(buffer);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -158,7 +162,7 @@ public class GLVertexBuffer extends GLBuffer implements IVertexBufferWrapper
|
|||||||
this.quadIBO = new GlQuadIndexBuffer();
|
this.quadIBO = new GlQuadIndexBuffer();
|
||||||
|
|
||||||
int quadCount = (vertexCount / 4);
|
int quadCount = (vertexCount / 4);
|
||||||
this.quadIBO.upload(quadCount);
|
this.quadIBO.upload(buffer, quadCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
//endregion
|
//endregion
|
||||||
|
|||||||
+1
-5
@@ -43,7 +43,7 @@ public class GlQuadIndexBuffer extends GLIndexBuffer
|
|||||||
|
|
||||||
public GlQuadIndexBuffer() { super(false); }
|
public GlQuadIndexBuffer() { super(false); }
|
||||||
|
|
||||||
public void upload(int quadCount)
|
public void upload(ByteBuffer buffer, int quadCount)
|
||||||
{
|
{
|
||||||
if (quadCount < 0)
|
if (quadCount < 0)
|
||||||
{
|
{
|
||||||
@@ -63,12 +63,8 @@ public class GlQuadIndexBuffer extends GLIndexBuffer
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.glType = GL32.GL_UNSIGNED_INT;
|
this.glType = GL32.GL_UNSIGNED_INT;
|
||||||
ByteBuffer buffer = IndexBufferBuilder.createBuffer(quadCount);
|
|
||||||
this.bind();
|
|
||||||
super.uploadBuffer(buffer, EDhApiGpuUploadMethod.DATA,
|
super.uploadBuffer(buffer, EDhApiGpuUploadMethod.DATA,
|
||||||
this.indicesCount * GLEnums.getTypeSize(this.glType), GL32.GL_STATIC_DRAW);
|
this.indicesCount * GLEnums.getTypeSize(this.glType), GL32.GL_STATIC_DRAW);
|
||||||
|
|
||||||
MemoryUtil.memFree(buffer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//endregion
|
//endregion
|
||||||
|
|||||||
-8
@@ -122,8 +122,6 @@ public class GlDhFarFadeRenderer implements IDhFarFadeRenderer
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
//profiler.push("Fade Generate");
|
|
||||||
|
|
||||||
this.init();
|
this.init();
|
||||||
|
|
||||||
// resize the framebuffer if necessary
|
// resize the framebuffer if necessary
|
||||||
@@ -141,8 +139,6 @@ public class GlDhFarFadeRenderer implements IDhFarFadeRenderer
|
|||||||
GlDhFarFadeShader.INSTANCE.setProjectionMatrix(renderParams.mcModelViewMatrix, renderParams.mcProjectionMatrix);
|
GlDhFarFadeShader.INSTANCE.setProjectionMatrix(renderParams.mcModelViewMatrix, renderParams.mcProjectionMatrix);
|
||||||
GlDhFarFadeShader.INSTANCE.render(renderParams);
|
GlDhFarFadeShader.INSTANCE.render(renderParams);
|
||||||
|
|
||||||
//profiler.popPush("Fade Apply");
|
|
||||||
|
|
||||||
GlDhFarFadeApplyShader.INSTANCE.fadeTexture = this.fadeTexture;
|
GlDhFarFadeApplyShader.INSTANCE.fadeTexture = this.fadeTexture;
|
||||||
GlDhFarFadeApplyShader.INSTANCE.readFramebuffer = GlDhFarFadeShader.INSTANCE.frameBuffer;
|
GlDhFarFadeApplyShader.INSTANCE.readFramebuffer = GlDhFarFadeShader.INSTANCE.frameBuffer;
|
||||||
GlDhFarFadeApplyShader.INSTANCE.drawFramebuffer = GlDhMetaRenderer.INSTANCE.getActiveFramebufferId();
|
GlDhFarFadeApplyShader.INSTANCE.drawFramebuffer = GlDhMetaRenderer.INSTANCE.getActiveFramebufferId();
|
||||||
@@ -152,10 +148,6 @@ public class GlDhFarFadeRenderer implements IDhFarFadeRenderer
|
|||||||
{
|
{
|
||||||
LOGGER.error("Unexpected error during fade render, error: ["+e.getMessage()+"].", e);
|
LOGGER.error("Unexpected error during fade render, error: ["+e.getMessage()+"].", e);
|
||||||
}
|
}
|
||||||
finally
|
|
||||||
{
|
|
||||||
//profiler.pop();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//emdregion
|
//emdregion
|
||||||
|
|||||||
+3
-12
@@ -135,14 +135,9 @@ public class GlVanillaFadeRenderer implements IDhVanillaFadeRenderer
|
|||||||
|
|
||||||
|
|
||||||
IProfilerWrapper profiler = MC_CLIENT.getProfiler();
|
IProfilerWrapper profiler = MC_CLIENT.getProfiler();
|
||||||
profiler.pop(); // get out of "terrain"
|
try (IProfilerWrapper.IProfileBlock fade_profile = profiler.push("DH-Vanilla Fade");
|
||||||
profiler.push("DH-Vanilla Fade");
|
GLState mcState = new GLState())
|
||||||
|
|
||||||
|
|
||||||
try(GLState mcState = new GLState())
|
|
||||||
{
|
{
|
||||||
profiler.push("Vanilla Fade Generate");
|
|
||||||
|
|
||||||
this.init();
|
this.init();
|
||||||
|
|
||||||
// resize the framebuffer if necessary
|
// resize the framebuffer if necessary
|
||||||
@@ -165,19 +160,15 @@ public class GlVanillaFadeRenderer implements IDhVanillaFadeRenderer
|
|||||||
// otherwise we can directly render to their texture
|
// otherwise we can directly render to their texture
|
||||||
if (MC_RENDER.mcRendersToFrameBuffer())
|
if (MC_RENDER.mcRendersToFrameBuffer())
|
||||||
{
|
{
|
||||||
profiler.popPush("Vanilla Fade Apply");
|
|
||||||
|
|
||||||
GlDhFarFadeApplyShader.INSTANCE.fadeTexture = this.fadeTexture;
|
GlDhFarFadeApplyShader.INSTANCE.fadeTexture = this.fadeTexture;
|
||||||
GlDhFarFadeApplyShader.INSTANCE.readFramebuffer = GlDhVanillaFadeShader.INSTANCE.frameBuffer;
|
GlDhFarFadeApplyShader.INSTANCE.readFramebuffer = GlDhVanillaFadeShader.INSTANCE.frameBuffer;
|
||||||
GlDhFarFadeApplyShader.INSTANCE.drawFramebuffer = MC_RENDER.getTargetFramebuffer();
|
GlDhFarFadeApplyShader.INSTANCE.drawFramebuffer = MC_RENDER.getTargetFramebuffer();
|
||||||
GlDhFarFadeApplyShader.INSTANCE.render(renderParams);
|
GlDhFarFadeApplyShader.INSTANCE.render(renderParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
profiler.pop();
|
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
LOGGER.error("Unexpected error during fade render, error: ["+e.getMessage()+"].", e);
|
LOGGER.error("Unexpected error during fade render, error: [" + e.getMessage() + "].", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
-2
@@ -296,8 +296,6 @@ public class GlDhTerrainShaderProgram extends GlShaderProgram implements IDhApiS
|
|||||||
// rendering //
|
// rendering //
|
||||||
//===========//
|
//===========//
|
||||||
|
|
||||||
ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeRenderPassEvent.class, renderEventParam);
|
|
||||||
|
|
||||||
if (IRIS_ACCESSOR != null)
|
if (IRIS_ACCESSOR != null)
|
||||||
{
|
{
|
||||||
// done to fix a bug with Iris where face culling isn't properly set or reverted in the MC state manager
|
// done to fix a bug with Iris where face culling isn't properly set or reverted in the MC state manager
|
||||||
|
|||||||
+1
-1
@@ -25,7 +25,7 @@ import com.seibel.distanthorizons.common.render.blaze.BlazeDhRenderApiDefinition
|
|||||||
import com.seibel.distanthorizons.common.render.openGl.GlDhRenderApiDefinition;
|
import com.seibel.distanthorizons.common.render.openGl.GlDhRenderApiDefinition;
|
||||||
import com.seibel.distanthorizons.core.config.Config;
|
import com.seibel.distanthorizons.core.config.Config;
|
||||||
import com.seibel.distanthorizons.core.render.renderer.GenericRenderObjectFactory;
|
import com.seibel.distanthorizons.core.render.renderer.GenericRenderObjectFactory;
|
||||||
import com.seibel.distanthorizons.common.wrappers.gui.ClassicConfigGUI;
|
import com.seibel.distanthorizons.common.wrappers.gui.classicConfig.ClassicConfigGUI;
|
||||||
import com.seibel.distanthorizons.common.wrappers.gui.LangWrapper;
|
import com.seibel.distanthorizons.common.wrappers.gui.LangWrapper;
|
||||||
import com.seibel.distanthorizons.common.wrappers.level.KeyedClientLevelManager;
|
import com.seibel.distanthorizons.common.wrappers.level.KeyedClientLevelManager;
|
||||||
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftServerWrapper;
|
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftServerWrapper;
|
||||||
|
|||||||
+4
-4
@@ -93,8 +93,8 @@ public class VersionConstants implements IVersionConstants
|
|||||||
return "1.21.10";
|
return "1.21.10";
|
||||||
#elif MC_VER == MC_1_21_11
|
#elif MC_VER == MC_1_21_11
|
||||||
return "1.21.11";
|
return "1.21.11";
|
||||||
#elif MC_VER == MC_1_26_1
|
#elif MC_VER == MC_26_1_2
|
||||||
return "21.6";
|
return "26.1.2";
|
||||||
#else
|
#else
|
||||||
ERROR MC version constant missing
|
ERROR MC version constant missing
|
||||||
#endif
|
#endif
|
||||||
@@ -104,10 +104,10 @@ public class VersionConstants implements IVersionConstants
|
|||||||
@Override
|
@Override
|
||||||
public EDhApiRenderApi getDefaultRenderingApi()
|
public EDhApiRenderApi getDefaultRenderingApi()
|
||||||
{
|
{
|
||||||
#if MC_VER <= MC_1_26_1
|
#if MC_VER <= MC_1_21_11
|
||||||
return EDhApiRenderApi.OPEN_GL;
|
return EDhApiRenderApi.OPEN_GL;
|
||||||
#else
|
#else
|
||||||
ERROR MC version constant missing
|
return EDhApiRenderApi.BLAZE_3D;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+31
-6
@@ -6,7 +6,7 @@ import com.seibel.distanthorizons.core.dataObjects.fullData.sources.FullDataSour
|
|||||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||||
import com.seibel.distanthorizons.core.pos.DhSectionPos;
|
import com.seibel.distanthorizons.core.pos.DhSectionPos;
|
||||||
import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPosMutable;
|
import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPosMutable;
|
||||||
import com.seibel.distanthorizons.core.util.ColorUtil;
|
import com.seibel.distanthorizons.coreapi.util.ColorUtil;
|
||||||
import com.seibel.distanthorizons.core.util.FullDataPointUtil;
|
import com.seibel.distanthorizons.core.util.FullDataPointUtil;
|
||||||
|
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
||||||
@@ -46,7 +46,7 @@ public abstract class AbstractDhTintGetter implements BlockAndTintGetter
|
|||||||
|
|
||||||
private static final ConcurrentHashMap<BlockBiomeWrapperPair, Integer> COLOR_BY_BLOCK_BIOME_PAIR = new ConcurrentHashMap<>();
|
private static final ConcurrentHashMap<BlockBiomeWrapperPair, Integer> COLOR_BY_BLOCK_BIOME_PAIR = new ConcurrentHashMap<>();
|
||||||
/** returned if the color cache is incomplete */
|
/** returned if the color cache is incomplete */
|
||||||
public static final int INVALID_COLOR = Integer.MIN_VALUE;
|
public static final int INVALID_COLOR = -1;
|
||||||
|
|
||||||
|
|
||||||
protected BiomeWrapper biomeWrapper;
|
protected BiomeWrapper biomeWrapper;
|
||||||
@@ -60,6 +60,7 @@ public abstract class AbstractDhTintGetter implements BlockAndTintGetter
|
|||||||
//=============//
|
//=============//
|
||||||
// constructor //
|
// constructor //
|
||||||
//=============//
|
//=============//
|
||||||
|
//region
|
||||||
|
|
||||||
public AbstractDhTintGetter() { }
|
public AbstractDhTintGetter() { }
|
||||||
|
|
||||||
@@ -76,11 +77,14 @@ public abstract class AbstractDhTintGetter implements BlockAndTintGetter
|
|||||||
this.smoothingRadiusInBlocks = Config.Client.Advanced.Graphics.Quality.lodBiomeBlending.get();
|
this.smoothingRadiusInBlocks = Config.Client.Advanced.Graphics.Quality.lodBiomeBlending.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//endregion
|
||||||
|
|
||||||
|
|
||||||
//================//
|
|
||||||
// shared methods //
|
//===============//
|
||||||
//================//
|
// color getters //
|
||||||
|
//===============//
|
||||||
|
//region
|
||||||
|
|
||||||
/** Called by MC's tint getter */
|
/** Called by MC's tint getter */
|
||||||
@Override
|
@Override
|
||||||
@@ -195,7 +199,7 @@ public abstract class AbstractDhTintGetter implements BlockAndTintGetter
|
|||||||
BlockBiomeWrapperPair pair = BlockBiomeWrapperPair.get(this.blockStateWrapper, biomeWrapper);
|
BlockBiomeWrapperPair pair = BlockBiomeWrapperPair.get(this.blockStateWrapper, biomeWrapper);
|
||||||
|
|
||||||
// use the cached color if possible
|
// use the cached color if possible
|
||||||
Integer cachedColor = COLOR_BY_BLOCK_BIOME_PAIR.get(pair); // explicit Integer return here reduces unnecessary allocations
|
Integer cachedColor = COLOR_BY_BLOCK_BIOME_PAIR.get(pair);
|
||||||
if (cachedColor != null)
|
if (cachedColor != null)
|
||||||
{
|
{
|
||||||
return cachedColor;
|
return cachedColor;
|
||||||
@@ -335,6 +339,27 @@ public abstract class AbstractDhTintGetter implements BlockAndTintGetter
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//===========//
|
||||||
|
// set color //
|
||||||
|
//===========//
|
||||||
|
//region
|
||||||
|
|
||||||
|
/**
|
||||||
|
* can be used in newer MC versions
|
||||||
|
* where the color getting logic is a bit more manual
|
||||||
|
*/
|
||||||
|
public static void setStaticColor(BlockStateWrapper blockStateWrapper, BiomeWrapper biomeWrapper, Integer colorInt)
|
||||||
|
{
|
||||||
|
BlockBiomeWrapperPair pair = BlockBiomeWrapperPair.get(blockStateWrapper, biomeWrapper);
|
||||||
|
COLOR_BY_BLOCK_BIOME_PAIR.put(pair, colorInt);
|
||||||
|
}
|
||||||
|
|
||||||
|
//endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-2
@@ -232,12 +232,13 @@ public class BiomeWrapper implements IBiomeWrapper
|
|||||||
resourceLocation = registryAccess.registryOrThrow(Registry.BIOME_REGISTRY).getKey(this.biome);
|
resourceLocation = registryAccess.registryOrThrow(Registry.BIOME_REGISTRY).getKey(this.biome);
|
||||||
#elif MC_VER <= MC_1_19_2
|
#elif MC_VER <= MC_1_19_2
|
||||||
resourceLocation = registryAccess.registryOrThrow(Registry.BIOME_REGISTRY).getKey(this.biome.value());
|
resourceLocation = registryAccess.registryOrThrow(Registry.BIOME_REGISTRY).getKey(this.biome.value());
|
||||||
#elif MC_VER <= MC_1_21_4
|
#elif MC_VER <= MC_1_21_1
|
||||||
resourceLocation = registryAccess.registryOrThrow(Registries.BIOME).getKey(this.biome.value());
|
resourceLocation = registryAccess.registryOrThrow(Registries.BIOME).getKey(this.biome.value());
|
||||||
#else
|
#else
|
||||||
resourceLocation = registryAccess.lookupOrThrow(Registries.BIOME).getKey(this.biome.value());
|
resourceLocation = registryAccess.lookupOrThrow(Registries.BIOME).getKey(this.biome.value());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
if (resourceLocation == null)
|
if (resourceLocation == null)
|
||||||
{
|
{
|
||||||
String biomeName;
|
String biomeName;
|
||||||
@@ -362,7 +363,7 @@ public class BiomeWrapper implements IBiomeWrapper
|
|||||||
Biome unwrappedBiome = registryAccess.registryOrThrow(Registry.BIOME_REGISTRY).get(resourceLocation);
|
Biome unwrappedBiome = registryAccess.registryOrThrow(Registry.BIOME_REGISTRY).get(resourceLocation);
|
||||||
success = (unwrappedBiome != null);
|
success = (unwrappedBiome != null);
|
||||||
Holder<Biome> biome = new Holder.Direct<>(unwrappedBiome);
|
Holder<Biome> biome = new Holder.Direct<>(unwrappedBiome);
|
||||||
#elif MC_VER <= MC_1_21_4
|
#elif MC_VER <= MC_1_21_1
|
||||||
Biome unwrappedBiome = registryAccess.registryOrThrow(Registries.BIOME).get(resourceLocation);
|
Biome unwrappedBiome = registryAccess.registryOrThrow(Registries.BIOME).get(resourceLocation);
|
||||||
success = (unwrappedBiome != null);
|
success = (unwrappedBiome != null);
|
||||||
Holder<Biome> biome = new Holder.Direct<>(unwrappedBiome);
|
Holder<Biome> biome = new Holder.Direct<>(unwrappedBiome);
|
||||||
|
|||||||
+110
-57
@@ -20,15 +20,17 @@
|
|||||||
package com.seibel.distanthorizons.common.wrappers.block;
|
package com.seibel.distanthorizons.common.wrappers.block;
|
||||||
|
|
||||||
import com.seibel.distanthorizons.api.enums.rendering.EDhApiBlockMaterial;
|
import com.seibel.distanthorizons.api.enums.rendering.EDhApiBlockMaterial;
|
||||||
|
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiBlockStateWrapperCreatedEvent;
|
||||||
import com.seibel.distanthorizons.common.wrappers.WrapperFactory;
|
import com.seibel.distanthorizons.common.wrappers.WrapperFactory;
|
||||||
import com.seibel.distanthorizons.core.config.Config;
|
import com.seibel.distanthorizons.core.config.Config;
|
||||||
import com.seibel.distanthorizons.core.config.types.ConfigEntry;
|
import com.seibel.distanthorizons.core.config.types.ConfigEntry;
|
||||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||||
import com.seibel.distanthorizons.core.util.ColorUtil;
|
import com.seibel.distanthorizons.coreapi.util.ColorUtil;
|
||||||
import com.seibel.distanthorizons.core.util.LodUtil;
|
import com.seibel.distanthorizons.core.util.LodUtil;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.block.IBlockStateWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.block.IBlockStateWrapper;
|
||||||
|
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
|
||||||
|
import com.seibel.distanthorizons.coreapi.DependencyInjection.ApiEventInjector;
|
||||||
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
|
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
|
||||||
import net.minecraft.tags.BlockTags;
|
import net.minecraft.tags.BlockTags;
|
||||||
import net.minecraft.world.level.block.BeaconBeamBlock;
|
import net.minecraft.world.level.block.BeaconBeamBlock;
|
||||||
@@ -51,6 +53,7 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
import net.minecraft.core.Registry;
|
import net.minecraft.core.Registry;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.world.level.EmptyBlockGetter;
|
import net.minecraft.world.level.EmptyBlockGetter;
|
||||||
|
import net.minecraft.world.level.Level;
|
||||||
#elif MC_VER == MC_1_18_2 || MC_VER == MC_1_19_2
|
#elif MC_VER == MC_1_18_2 || MC_VER == MC_1_19_2
|
||||||
import net.minecraft.tags.TagKey;
|
import net.minecraft.tags.TagKey;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
@@ -88,7 +91,7 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
|||||||
public static final ConcurrentHashMap<String, BlockStateWrapper> WRAPPER_BY_RESOURCE_LOCATION = new ConcurrentHashMap<>();
|
public static final ConcurrentHashMap<String, BlockStateWrapper> WRAPPER_BY_RESOURCE_LOCATION = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
public static final String AIR_STRING = "AIR";
|
public static final String AIR_STRING = "AIR";
|
||||||
public static final BlockStateWrapper AIR = new BlockStateWrapper(null, null);
|
public static final BlockStateWrapper AIR = new BlockStateWrapper(null, null, null);
|
||||||
|
|
||||||
public static final String DIRT_RESOURCE_LOCATION_STRING = "minecraft:dirt";
|
public static final String DIRT_RESOURCE_LOCATION_STRING = "minecraft:dirt";
|
||||||
public static final String WATER_RESOURCE_LOCATION_STRING = "minecraft:water";
|
public static final String WATER_RESOURCE_LOCATION_STRING = "minecraft:water";
|
||||||
@@ -123,6 +126,9 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
|||||||
private final boolean isBeaconBlock;
|
private final boolean isBeaconBlock;
|
||||||
private final boolean isBeaconBaseBlock;
|
private final boolean isBeaconBaseBlock;
|
||||||
private final boolean allowsBeaconBeamPassage;
|
private final boolean allowsBeaconBeamPassage;
|
||||||
|
private final boolean isSolid;
|
||||||
|
private final boolean isLiquid;
|
||||||
|
private final boolean allowApiColorOverride;
|
||||||
/** null if this block can't tint beacons */
|
/** null if this block can't tint beacons */
|
||||||
private final Color beaconTintColor;
|
private final Color beaconTintColor;
|
||||||
private final Color mapColor;
|
private final Color mapColor;
|
||||||
@@ -148,7 +154,7 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
BlockStateWrapper newWrapper = new BlockStateWrapper(blockState, levelWrapper);
|
BlockStateWrapper newWrapper = createNewWrapper(blockState, levelWrapper);
|
||||||
WRAPPER_BY_BLOCK_STATE.put(blockState, newWrapper);
|
WRAPPER_BY_BLOCK_STATE.put(blockState, newWrapper);
|
||||||
return newWrapper;
|
return newWrapper;
|
||||||
}
|
}
|
||||||
@@ -174,15 +180,64 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private BlockStateWrapper(@Nullable BlockState blockState, ILevelWrapper levelWrapper)
|
private static BlockStateWrapper createNewWrapper(@Nullable BlockState blockState, ILevelWrapper levelWrapper)
|
||||||
|
{
|
||||||
|
// create a wrapper specifically for the API event to use
|
||||||
|
BlockStateWrapper apiWrapper = new BlockStateWrapper(blockState, levelWrapper, null);
|
||||||
|
DhApiBlockStateWrapperCreatedEvent.EventParam eventParam = new DhApiBlockStateWrapperCreatedEvent.EventParam(apiWrapper);
|
||||||
|
ApiEventInjector.INSTANCE.fireAllEvents(DhApiBlockStateWrapperCreatedEvent.class, eventParam);
|
||||||
|
|
||||||
|
if (!eventParam.getOverridesSet())
|
||||||
|
{
|
||||||
|
// no changes needed, use the existing object
|
||||||
|
return apiWrapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
// create a new wrapper using whatever overrides the API user set
|
||||||
|
BlockStateWrapper returnWrapper = new BlockStateWrapper(blockState, levelWrapper, eventParam);
|
||||||
|
return returnWrapper;
|
||||||
|
}
|
||||||
|
private BlockStateWrapper(@Nullable BlockState blockState, ILevelWrapper levelWrapper, @Nullable DhApiBlockStateWrapperCreatedEvent.EventParam overrideEventParam)
|
||||||
{
|
{
|
||||||
this.blockState = blockState;
|
this.blockState = blockState;
|
||||||
this.serialString = this.serialize(levelWrapper);
|
this.serialString = this.serialize(levelWrapper);
|
||||||
this.hashCode = Objects.hash(this.serialString);
|
this.hashCode = Objects.hash(this.serialString);
|
||||||
this.blockMaterialId = this.calculateEDhApiBlockMaterialId().index;
|
|
||||||
this.opacity = this.calculateOpacity();
|
|
||||||
|
|
||||||
String lowercaseSerial = this.serialString.toLowerCase();
|
// allow overriding if present
|
||||||
|
if (overrideEventParam != null
|
||||||
|
&& overrideEventParam.getBlockMaterial() != null)
|
||||||
|
{
|
||||||
|
this.blockMaterialId = overrideEventParam.getBlockMaterial().index;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// no API override, use the base logic
|
||||||
|
this.blockMaterialId = this.calculateEDhApiBlockMaterialId().index;
|
||||||
|
}
|
||||||
|
|
||||||
|
// allow overriding if present
|
||||||
|
if (overrideEventParam != null
|
||||||
|
&& overrideEventParam.getOpacity() != null)
|
||||||
|
{
|
||||||
|
this.opacity = overrideEventParam.getOpacity();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.opacity = this.calculateOpacity();
|
||||||
|
}
|
||||||
|
|
||||||
|
// allow overriding if present
|
||||||
|
if (overrideEventParam != null
|
||||||
|
&& overrideEventParam.getAllowApiColorOverride() != null)
|
||||||
|
{
|
||||||
|
this.allowApiColorOverride = overrideEventParam.getAllowApiColorOverride();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.allowApiColorOverride = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
String lowerCaseSerial = this.serialString.toLowerCase();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -203,7 +258,7 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
|||||||
for (int i = 0; i < oldBeaconBaseBlockNameList.size(); i++)
|
for (int i = 0; i < oldBeaconBaseBlockNameList.size(); i++)
|
||||||
{
|
{
|
||||||
String baseBlockName = oldBeaconBaseBlockNameList.get(i);
|
String baseBlockName = oldBeaconBaseBlockNameList.get(i);
|
||||||
if (lowercaseSerial.contains(baseBlockName))
|
if (lowerCaseSerial.contains(baseBlockName))
|
||||||
{
|
{
|
||||||
isBeaconBaseBlock = true;
|
isBeaconBaseBlock = true;
|
||||||
break;
|
break;
|
||||||
@@ -231,7 +286,7 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// beacon block
|
// beacon block
|
||||||
this.isBeaconBlock = lowercaseSerial.contains("minecraft:beacon");
|
this.isBeaconBlock = lowerCaseSerial.contains("minecraft:beacon");
|
||||||
|
|
||||||
|
|
||||||
// beacon tint color
|
// beacon tint color
|
||||||
@@ -264,12 +319,12 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
|||||||
boolean canOcclude = this.getCanOcclude();
|
boolean canOcclude = this.getCanOcclude();
|
||||||
boolean propagatesSkyLightDown = this.getPropagatesSkyLightDown();
|
boolean propagatesSkyLightDown = this.getPropagatesSkyLightDown();
|
||||||
|
|
||||||
if (lowercaseSerial.contains("minecraft:bedrock"))
|
if (lowerCaseSerial.contains("minecraft:bedrock"))
|
||||||
{
|
{
|
||||||
// bedrock is a special case fully opaque block that does allow beacons through
|
// bedrock is a special case fully opaque block that does allow beacons through
|
||||||
allowsBeaconBeamPassage = true;
|
allowsBeaconBeamPassage = true;
|
||||||
}
|
}
|
||||||
else if (lowercaseSerial.contains("minecraft:tinted_glass"))
|
else if (lowerCaseSerial.contains("minecraft:tinted_glass"))
|
||||||
{
|
{
|
||||||
// tinted glass is a special case where it isn't fully opaque,
|
// tinted glass is a special case where it isn't fully opaque,
|
||||||
// but should block beacons
|
// but should block beacons
|
||||||
@@ -295,14 +350,17 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
|||||||
this.allowsBeaconBeamPassage = allowsBeaconBeamPassage;
|
this.allowsBeaconBeamPassage = allowsBeaconBeamPassage;
|
||||||
|
|
||||||
|
|
||||||
int mcColor = 0;
|
// map color
|
||||||
if (this.blockState != null)
|
if (this.blockState != null)
|
||||||
{
|
{
|
||||||
|
int mcColor = 0;
|
||||||
|
|
||||||
#if MC_VER < MC_1_20_1
|
#if MC_VER < MC_1_20_1
|
||||||
mcColor = this.blockState.getMaterial().getColor().col;
|
mcColor = this.blockState.getMaterial().getColor().col;
|
||||||
#else
|
#else
|
||||||
mcColor = this.blockState.getMapColor(EmptyBlockGetter.INSTANCE, BlockPos.ZERO).col;
|
mcColor = this.blockState.getMapColor(EmptyBlockGetter.INSTANCE, BlockPos.ZERO).col;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
this.mapColor = ColorUtil.toColorObjRGB(mcColor);
|
this.mapColor = ColorUtil.toColorObjRGB(mcColor);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -310,7 +368,39 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
|||||||
this.mapColor = new Color(0,0,0,0);
|
this.mapColor = new Color(0,0,0,0);
|
||||||
}
|
}
|
||||||
|
|
||||||
//LOGGER.trace("Created BlockStateWrapper ["+this.serialString+"] for ["+blockState+"] with material ID ["+this.EDhApiBlockMaterialId+"]");
|
|
||||||
|
// is solid
|
||||||
|
if (this.isAir()
|
||||||
|
|| this.blockState == null) // "== null" isn't necessary since its handled in isAir() but is here to prevent intellij from complaining
|
||||||
|
{
|
||||||
|
this.isSolid = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#if MC_VER < MC_1_20_1
|
||||||
|
this.isSolid = this.blockState.getMaterial().isSolid();
|
||||||
|
#else
|
||||||
|
this.isSolid = !this.blockState.getCollisionShape(EmptyBlockGetter.INSTANCE, BlockPos.ZERO).isEmpty();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// is liquid
|
||||||
|
if (this.isAir()
|
||||||
|
|| this.blockState == null) // == null isn't necessary since its handled in isAir() but is here to prevent intellij from complaining
|
||||||
|
{
|
||||||
|
this.isLiquid = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#if MC_VER < MC_1_20_1
|
||||||
|
this.isLiquid = this.blockState.getMaterial().isLiquid() || !this.blockState.getFluidState().isEmpty();
|
||||||
|
#else
|
||||||
|
this.isLiquid = !this.blockState.getFluidState().isEmpty();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//endregion
|
//endregion
|
||||||
@@ -557,7 +647,6 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getLightEmission() { return (this.blockState != null) ? this.blockState.getLightEmission() : 0; }
|
public int getLightEmission() { return (this.blockState != null) ? this.blockState.getLightEmission() : 0; }
|
||||||
|
|
||||||
@@ -593,48 +682,10 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
|||||||
public boolean isAir() { return this.isAir(this.blockState); }
|
public boolean isAir() { return this.isAir(this.blockState); }
|
||||||
public boolean isAir(BlockState blockState) { return blockState == null || blockState.isAir(); }
|
public boolean isAir(BlockState blockState) { return blockState == null || blockState.isAir(); }
|
||||||
|
|
||||||
private Boolean blockIsSolid = null;
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isSolid()
|
public boolean isSolid() { return this.isSolid; }
|
||||||
{
|
|
||||||
if (this.isAir()
|
|
||||||
|| this.blockState == null) // == null isn't necessary since its handled in isAir() but is here to prevent intellij from complaining
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// cached since getCollisionShape() is a dictionary lookup that allocates objects
|
|
||||||
// and this call is used in a high traffic location
|
|
||||||
if (this.blockIsSolid != null)
|
|
||||||
{
|
|
||||||
return this.blockIsSolid;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#if MC_VER < MC_1_20_1
|
|
||||||
this.blockIsSolid = this.blockState.getMaterial().isSolid();
|
|
||||||
#else
|
|
||||||
this.blockIsSolid = !this.blockState.getCollisionShape(EmptyBlockGetter.INSTANCE, BlockPos.ZERO).isEmpty();
|
|
||||||
#endif
|
|
||||||
return this.blockIsSolid;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isLiquid()
|
public boolean isLiquid() { return this.isLiquid; }
|
||||||
{
|
|
||||||
if (this.isAir()
|
|
||||||
|| this.blockState == null) // == null isn't necessary since its handled in isAir() but is here to prevent intellij from complaining
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if MC_VER < MC_1_20_1
|
|
||||||
return this.blockState.getMaterial().isLiquid() || !this.blockState.getFluidState().isEmpty();
|
|
||||||
#else
|
|
||||||
return !this.blockState.getFluidState().isEmpty();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isBeaconBlock() { return this.isBeaconBlock; }
|
public boolean isBeaconBlock() { return this.isBeaconBlock; }
|
||||||
@Override
|
@Override
|
||||||
@@ -643,6 +694,8 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
|||||||
public boolean isBeaconTintBlock() { return this.beaconTintColor != null; }
|
public boolean isBeaconTintBlock() { return this.beaconTintColor != null; }
|
||||||
@Override
|
@Override
|
||||||
public boolean allowsBeaconBeamPassage() { return this.allowsBeaconBeamPassage; }
|
public boolean allowsBeaconBeamPassage() { return this.allowsBeaconBeamPassage; }
|
||||||
|
@Override
|
||||||
|
public boolean allowApiColorOverride() { return this.allowApiColorOverride; }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Color getMapColor() { return this.mapColor; }
|
public Color getMapColor() { return this.mapColor; }
|
||||||
@@ -690,7 +743,7 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
|||||||
resourceLocation = Registry.BLOCK.getKey(this.blockState.getBlock());
|
resourceLocation = Registry.BLOCK.getKey(this.blockState.getBlock());
|
||||||
#elif MC_VER <= MC_1_19_2
|
#elif MC_VER <= MC_1_19_2
|
||||||
resourceLocation = registryAccess.registryOrThrow(Registry.BLOCK_REGISTRY).getKey(this.blockState.getBlock());
|
resourceLocation = registryAccess.registryOrThrow(Registry.BLOCK_REGISTRY).getKey(this.blockState.getBlock());
|
||||||
#elif MC_VER <= MC_1_21_4
|
#elif MC_VER <= MC_1_21_1
|
||||||
resourceLocation = registryAccess.registryOrThrow(Registries.BLOCK).getKey(this.blockState.getBlock());
|
resourceLocation = registryAccess.registryOrThrow(Registries.BLOCK).getKey(this.blockState.getBlock());
|
||||||
#else
|
#else
|
||||||
resourceLocation = registryAccess.lookupOrThrow(Registries.BLOCK).getKey(this.blockState.getBlock());
|
resourceLocation = registryAccess.lookupOrThrow(Registries.BLOCK).getKey(this.blockState.getBlock());
|
||||||
@@ -791,7 +844,7 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
|||||||
#elif MC_VER <= MC_1_19_2
|
#elif MC_VER <= MC_1_19_2
|
||||||
net.minecraft.core.RegistryAccess registryAccess = level.registryAccess();
|
net.minecraft.core.RegistryAccess registryAccess = level.registryAccess();
|
||||||
block = registryAccess.registryOrThrow(Registry.BLOCK_REGISTRY).get(resourceLocation);
|
block = registryAccess.registryOrThrow(Registry.BLOCK_REGISTRY).get(resourceLocation);
|
||||||
#elif MC_VER <= MC_1_21_4
|
#elif MC_VER <= MC_1_21_1
|
||||||
net.minecraft.core.RegistryAccess registryAccess = level.registryAccess();
|
net.minecraft.core.RegistryAccess registryAccess = level.registryAccess();
|
||||||
block = registryAccess.registryOrThrow(Registries.BLOCK).get(resourceLocation);
|
block = registryAccess.registryOrThrow(Registries.BLOCK).get(resourceLocation);
|
||||||
#else
|
#else
|
||||||
@@ -846,7 +899,7 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
|||||||
foundState = block.defaultBlockState();
|
foundState = block.defaultBlockState();
|
||||||
}
|
}
|
||||||
|
|
||||||
foundWrapper = new BlockStateWrapper(foundState, levelWrapper);
|
foundWrapper = createNewWrapper(foundState, levelWrapper);
|
||||||
return foundWrapper;
|
return foundWrapper;
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
|
|||||||
+127
-67
@@ -19,22 +19,21 @@
|
|||||||
|
|
||||||
package com.seibel.distanthorizons.common.wrappers.block;
|
package com.seibel.distanthorizons.common.wrappers.block;
|
||||||
|
|
||||||
|
import com.seibel.distanthorizons.api.interfaces.block.IDhApiBlockStateWrapper;
|
||||||
|
import com.seibel.distanthorizons.api.interfaces.world.IDhApiLevelWrapper;
|
||||||
|
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiBlockColorOverrideEvent;
|
||||||
import com.seibel.distanthorizons.common.wrappers.McObjectConverter;
|
import com.seibel.distanthorizons.common.wrappers.McObjectConverter;
|
||||||
import com.seibel.distanthorizons.core.dataObjects.fullData.sources.FullDataSourceV2;
|
import com.seibel.distanthorizons.core.dataObjects.fullData.sources.FullDataSourceV2;
|
||||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||||
import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos;
|
import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos;
|
||||||
import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPosMutable;
|
import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPosMutable;
|
||||||
import com.seibel.distanthorizons.core.util.ColorUtil;
|
import com.seibel.distanthorizons.coreapi.util.ColorUtil;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
||||||
|
import com.seibel.distanthorizons.coreapi.DependencyInjection.ApiEventInjector;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||||
import net.minecraft.core.Direction;
|
import net.minecraft.core.Direction;
|
||||||
import net.minecraft.world.level.block.*;
|
import net.minecraft.world.level.block.*;
|
||||||
#if MC_VER >= MC_1_19_2
|
|
||||||
import net.minecraft.util.RandomSource;
|
|
||||||
#else
|
|
||||||
import java.util.Random;
|
|
||||||
#endif
|
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import com.seibel.distanthorizons.core.logging.DhLogger;
|
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||||
import net.minecraft.world.level.block.state.properties.SlabType;
|
import net.minecraft.world.level.block.state.properties.SlabType;
|
||||||
@@ -45,6 +44,12 @@ import java.util.HashSet;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
|
||||||
|
#if MC_VER >= MC_1_19_2
|
||||||
|
import net.minecraft.util.RandomSource;
|
||||||
|
#else
|
||||||
|
import java.util.Random;
|
||||||
|
#endif
|
||||||
|
|
||||||
#if MC_VER < MC_1_21_5
|
#if MC_VER < MC_1_21_5
|
||||||
import net.minecraft.client.renderer.block.model.BakedQuad;
|
import net.minecraft.client.renderer.block.model.BakedQuad;
|
||||||
#elif MC_VER <= MC_1_21_11
|
#elif MC_VER <= MC_1_21_11
|
||||||
@@ -53,6 +58,8 @@ import net.minecraft.client.renderer.block.model.BakedQuad;
|
|||||||
#else
|
#else
|
||||||
import net.minecraft.client.renderer.block.dispatch.BlockStateModelPart;
|
import net.minecraft.client.renderer.block.dispatch.BlockStateModelPart;
|
||||||
import net.minecraft.client.resources.model.geometry.BakedQuad;
|
import net.minecraft.client.resources.model.geometry.BakedQuad;
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.client.color.block.BlockTintSource;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -119,6 +126,7 @@ public class ClientBlockStateColorCache
|
|||||||
//===========//
|
//===========//
|
||||||
// constants //
|
// constants //
|
||||||
//===========//
|
//===========//
|
||||||
|
//region
|
||||||
|
|
||||||
private static final int MIN_SRGB_BITS = 0x39000000; // 2^(-13)
|
private static final int MIN_SRGB_BITS = 0x39000000; // 2^(-13)
|
||||||
private static final int MAX_SRGB_BITS = 0x3f7fffff; // 1.0 - f32::EPSILON
|
private static final int MAX_SRGB_BITS = 0x3f7fffff; // 1.0 - f32::EPSILON
|
||||||
@@ -182,14 +190,19 @@ public class ClientBlockStateColorCache
|
|||||||
//endregion
|
//endregion
|
||||||
};
|
};
|
||||||
|
|
||||||
private static final ThreadLocal<TintWithoutLevelOverrider> TintWithoutLevelOverrideGetter = ThreadLocal.withInitial(() -> new TintWithoutLevelOverrider());
|
// these are threadlocals since AbstractDhTintGetter use local variables to handle color queries
|
||||||
private static final ThreadLocal<TintGetterOverride> TintOverrideGetter = ThreadLocal.withInitial(() -> new TintGetterOverride());
|
private static final ThreadLocal<TintWithoutLevelOverrider> TintWithoutLevelOverrideGetter = ThreadLocal.withInitial(TintWithoutLevelOverrider::new);
|
||||||
|
private static final ThreadLocal<TintGetterOverride> TintOverrideGetter = ThreadLocal.withInitial(TintGetterOverride::new);
|
||||||
|
private static final ThreadLocal<DhApiBlockColorOverrideEvent.EventParam> ColorOverrideEventParamGetter = ThreadLocal.withInitial(DhApiBlockColorOverrideEvent.EventParam::new);
|
||||||
|
|
||||||
|
//endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//=============//
|
//=============//
|
||||||
// constructor //
|
// constructor //
|
||||||
//=============//
|
//=============//
|
||||||
|
//region
|
||||||
|
|
||||||
public ClientBlockStateColorCache(BlockState blockState, IClientLevelWrapper clientLevelWrapper)
|
public ClientBlockStateColorCache(BlockState blockState, IClientLevelWrapper clientLevelWrapper)
|
||||||
{
|
{
|
||||||
@@ -200,6 +213,8 @@ public class ClientBlockStateColorCache
|
|||||||
this.resolveColors();
|
this.resolveColors();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//===================//
|
//===================//
|
||||||
@@ -504,60 +519,89 @@ public class ClientBlockStateColorCache
|
|||||||
public int getColor(BiomeWrapper biomeWrapper, FullDataSourceV2 fullDataSource, DhBlockPos blockPos)
|
public int getColor(BiomeWrapper biomeWrapper, FullDataSourceV2 fullDataSource, DhBlockPos blockPos)
|
||||||
{
|
{
|
||||||
// only get the tint if the block needs to be tinted
|
// only get the tint if the block needs to be tinted
|
||||||
if (!this.needPostTinting)
|
int tintColor = AbstractDhTintGetter.INVALID_COLOR;
|
||||||
|
if (this.needPostTinting)
|
||||||
{
|
{
|
||||||
return this.baseColor;
|
// don't try tinting blocks that don't support our method of tint getting
|
||||||
}
|
if (BROKEN_BLOCK_STATES.contains(this.blockState))
|
||||||
|
|
||||||
// don't try tinting blocks that don't support our method of tint getting
|
|
||||||
if (BROKEN_BLOCK_STATES.contains(this.blockState))
|
|
||||||
{
|
|
||||||
return this.baseColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// attempt to get the tint
|
|
||||||
int tintColor = -1;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// try to use the fast tint getter logic first
|
|
||||||
if (!BLOCK_STATES_THAT_NEED_LEVEL.contains(this.blockState))
|
|
||||||
{
|
{
|
||||||
try
|
return this.baseColor;
|
||||||
{
|
}
|
||||||
TintWithoutLevelOverrider tintOverride = TintWithoutLevelOverrideGetter.get();
|
|
||||||
tintOverride.update(biomeWrapper, this.blockStateWrapper, fullDataSource, this.clientLevelWrapper);
|
|
||||||
|
|
||||||
// try using DH's cached tint values first if possible
|
|
||||||
tintColor = tintOverride.tryGetBlockTint(new DhBlockPosMutable(blockPos));
|
// attempt to get the tint
|
||||||
if (tintColor == AbstractDhTintGetter.INVALID_COLOR)
|
try
|
||||||
|
{
|
||||||
|
// try to use the fast tint getter logic first
|
||||||
|
if (!BLOCK_STATES_THAT_NEED_LEVEL.contains(this.blockState))
|
||||||
|
{
|
||||||
|
try
|
||||||
{
|
{
|
||||||
// one or more tint values weren't calculated,
|
TintWithoutLevelOverrider tintOverride = TintWithoutLevelOverrideGetter.get();
|
||||||
// we need MC's color resolver
|
tintOverride.update(biomeWrapper, this.blockStateWrapper, fullDataSource, this.clientLevelWrapper);
|
||||||
|
|
||||||
|
// try using DH's cached tint values first if possible
|
||||||
|
tintColor = tintOverride.tryGetBlockTint(new DhBlockPosMutable(blockPos));
|
||||||
|
if (tintColor == AbstractDhTintGetter.INVALID_COLOR)
|
||||||
|
{
|
||||||
|
// one or more tint values weren't calculated,
|
||||||
|
// we need MC's color resolver
|
||||||
#if MC_VER <= MC_1_21_11
|
#if MC_VER <= MC_1_21_11
|
||||||
tintColor = Minecraft.getInstance()
|
tintColor = Minecraft.getInstance()
|
||||||
.getBlockColors()
|
.getBlockColors()
|
||||||
.getColor(this.blockState,
|
.getColor(this.blockState,
|
||||||
tintOverride,
|
tintOverride, // tintOverride will save the result of this query to speed up future queries
|
||||||
McObjectConverter.Convert(blockPos),
|
McObjectConverter.Convert(blockPos),
|
||||||
this.tintIndex);
|
this.tintIndex);
|
||||||
#else
|
#else
|
||||||
tintColor = Minecraft.getInstance()
|
BlockTintSource tintSource = Minecraft.getInstance()
|
||||||
.getBlockColors()
|
.getBlockColors()
|
||||||
.getTintSources(this.blockState)
|
.getTintSource(this.blockState, this.tintIndex);
|
||||||
.get(this.tintIndex)
|
// a tint source may be null for blocks that don't actually need tinting
|
||||||
.color(this.blockState);
|
// in that case the base color should be sufficient
|
||||||
|
// Example: cherry blossom leaves
|
||||||
|
if (tintSource != null)
|
||||||
|
{
|
||||||
|
BlockPos mcPos = McObjectConverter.Convert(blockPos);
|
||||||
|
tintColor = tintSource.colorInWorld(this.blockState, tintOverride, mcPos);
|
||||||
|
if (tintColor == -1)
|
||||||
|
{
|
||||||
|
tintColor = tintSource.colorAsTerrainParticle(this.blockState, tintOverride, mcPos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tintColor == -1)
|
||||||
|
{
|
||||||
|
// no color found, use the base color
|
||||||
|
tintColor = AbstractDhTintGetter.INVALID_COLOR;
|
||||||
|
}
|
||||||
|
|
||||||
|
// save this color to speed up future queries
|
||||||
|
TintWithoutLevelOverrider.setStaticColor(this.blockStateWrapper, biomeWrapper, tintColor);
|
||||||
|
// try to get the blended color with this new information
|
||||||
|
tintColor = tintOverride.tryGetBlockTint(new DhBlockPosMutable(blockPos));
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
catch (Exception e)
|
||||||
catch (UnsupportedOperationException e)
|
{
|
||||||
{
|
#if MC_VER <= MC_1_21_11
|
||||||
// this exception generally occurs if the tint requires other blocks besides itself
|
// this exception generally occurs if the tint requires other blocks besides itself
|
||||||
LOGGER.debug("Unable to use ["+ TintWithoutLevelOverrider.class.getSimpleName()+"] to get the block tint for block: [" + this.blockState + "] and biome: [" + biomeWrapper + "] at pos: " + blockPos + ". Error: [" + e.getMessage() + "]. Attempting to use backup method...", e);
|
LOGGER.debug("Unable to use ["+ TintWithoutLevelOverrider.class.getSimpleName()+"] to get the block tint for block: [" + this.blockState + "] and biome: [" + biomeWrapper + "] at pos: " + blockPos + ". Error: [" + e.getMessage() + "]. Attempting to use backup method...", e);
|
||||||
BLOCK_STATES_THAT_NEED_LEVEL.add(this.blockState);
|
BLOCK_STATES_THAT_NEED_LEVEL.add(this.blockState);
|
||||||
|
#else
|
||||||
|
// only display the error once per block/biome type to reduce log spam
|
||||||
|
if (!BROKEN_BLOCK_STATES.contains(this.blockState))
|
||||||
|
{
|
||||||
|
LOGGER.warn("Failed to get block color for block: [" + this.blockState + "] and biome: [" + biomeWrapper + "] at pos: " + blockPos + ". Error: [" + e.getMessage() + "]. Note: future errors for this block/biome will be ignored.", e);
|
||||||
|
BROKEN_BLOCK_STATES.add(this.blockState);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
// level-specific logic is only needed for MC 1.21.11 and older
|
||||||
|
#if MC_VER <= MC_1_21_11
|
||||||
// use the level logic only if requested
|
// use the level logic only if requested
|
||||||
if (BLOCK_STATES_THAT_NEED_LEVEL.contains(this.blockState))
|
if (BLOCK_STATES_THAT_NEED_LEVEL.contains(this.blockState))
|
||||||
{
|
{
|
||||||
@@ -570,44 +614,57 @@ public class ClientBlockStateColorCache
|
|||||||
tintColor = tintOverride.tryGetBlockTint(new DhBlockPosMutable(blockPos));
|
tintColor = tintOverride.tryGetBlockTint(new DhBlockPosMutable(blockPos));
|
||||||
if (tintColor == AbstractDhTintGetter.INVALID_COLOR)
|
if (tintColor == AbstractDhTintGetter.INVALID_COLOR)
|
||||||
{
|
{
|
||||||
#if MC_VER <= MC_1_21_11
|
|
||||||
tintColor = Minecraft.getInstance()
|
tintColor = Minecraft.getInstance()
|
||||||
.getBlockColors()
|
.getBlockColors()
|
||||||
.getColor(this.blockState,
|
.getColor(this.blockState,
|
||||||
tintOverride,
|
tintOverride,
|
||||||
McObjectConverter.Convert(blockPos),
|
McObjectConverter.Convert(blockPos),
|
||||||
this.tintIndex);
|
this.tintIndex);
|
||||||
#else
|
}
|
||||||
tintColor = Minecraft.getInstance()
|
}
|
||||||
.getBlockColors()
|
#endif
|
||||||
.getTintSources(this.blockState)
|
}
|
||||||
.get(this.tintIndex)
|
catch (Exception e)
|
||||||
.color(this.blockState);
|
{
|
||||||
#endif
|
// only display the error once per block/biome type to reduce log spam
|
||||||
|
if (!BROKEN_BLOCK_STATES.contains(this.blockState))
|
||||||
|
{
|
||||||
|
LOGGER.warn("Failed to get block color for block: [" + this.blockState + "] and biome: [" + biomeWrapper + "] at pos: " + blockPos + ". Error: [" + e.getMessage() + "]. Note: future errors for this block/biome will be ignored.", e);
|
||||||
|
BROKEN_BLOCK_STATES.add(this.blockState);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
|
||||||
|
|
||||||
|
int returnColor;
|
||||||
|
if (tintColor != AbstractDhTintGetter.INVALID_COLOR)
|
||||||
{
|
{
|
||||||
// only display the error once per block/biome type to reduce log spam
|
returnColor = ColorUtil.multiplyARGBwithRGB(this.baseColor, tintColor);
|
||||||
if (!BROKEN_BLOCK_STATES.contains(this.blockState))
|
|
||||||
{
|
|
||||||
LOGGER.warn("Failed to get block color for block: [" + this.blockState + "] and biome: [" + biomeWrapper + "] at pos: " + blockPos + ". Error: ["+e.getMessage() + "]. Note: future errors for this block/biome will be ignored.", e);
|
|
||||||
BROKEN_BLOCK_STATES.add(this.blockState);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (tintColor != -1)
|
|
||||||
{
|
|
||||||
return ColorUtil.multiplyARGBwithRGB(this.baseColor, tintColor);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// unable to get the tinted color, use the base color instead
|
// unable to get the tinted color, use the base color instead
|
||||||
return this.baseColor;
|
returnColor = this.baseColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// only fire an API event if needed
|
||||||
|
// (this is done to reduce GC pressure and speed up color getting)
|
||||||
|
if (this.blockStateWrapper.allowApiColorOverride())
|
||||||
|
{
|
||||||
|
DhApiBlockColorOverrideEvent.EventParam eventParam = ColorOverrideEventParamGetter.get();
|
||||||
|
eventParam.update(
|
||||||
|
this.clientLevelWrapper,
|
||||||
|
this.blockStateWrapper, returnColor,
|
||||||
|
blockPos.getX(), blockPos.getY(), blockPos.getZ()
|
||||||
|
);
|
||||||
|
ApiEventInjector.INSTANCE.fireAllEvents(DhApiBlockColorOverrideEvent.class, eventParam);
|
||||||
|
|
||||||
|
// let the API user override this color
|
||||||
|
returnColor = eventParam.getColorAsInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -615,6 +672,7 @@ public class ClientBlockStateColorCache
|
|||||||
//================//
|
//================//
|
||||||
// helper classes //
|
// helper classes //
|
||||||
//================//
|
//================//
|
||||||
|
//region
|
||||||
|
|
||||||
private enum EColorMode
|
private enum EColorMode
|
||||||
{
|
{
|
||||||
@@ -646,6 +704,8 @@ public class ClientBlockStateColorCache
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -25,7 +25,7 @@ import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
|||||||
#if MC_VER < MC_1_17_1
|
#if MC_VER < MC_1_17_1
|
||||||
#elif MC_VER < MC_1_21_3
|
#elif MC_VER < MC_1_21_3
|
||||||
#else
|
#else
|
||||||
import com.seibel.distanthorizons.core.util.ColorUtil;
|
import com.seibel.distanthorizons.coreapi.util.ColorUtil;
|
||||||
import net.minecraft.client.renderer.texture.SpriteContents;
|
import net.minecraft.client.renderer.texture.SpriteContents;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
-1121
File diff suppressed because it is too large
Load Diff
+1
@@ -1,5 +1,6 @@
|
|||||||
package com.seibel.distanthorizons.common.wrappers.gui;
|
package com.seibel.distanthorizons.common.wrappers.gui;
|
||||||
|
|
||||||
|
import com.seibel.distanthorizons.common.wrappers.gui.classicConfig.ClassicConfigGUI;
|
||||||
import com.seibel.distanthorizons.core.config.ConfigHandler;
|
import com.seibel.distanthorizons.core.config.ConfigHandler;
|
||||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||||
import com.seibel.distanthorizons.coreapi.ModInfo;
|
import com.seibel.distanthorizons.coreapi.ModInfo;
|
||||||
|
|||||||
+38
@@ -0,0 +1,38 @@
|
|||||||
|
package com.seibel.distanthorizons.common.wrappers.gui;
|
||||||
|
|
||||||
|
import org.lwjgl.util.tinyfd.TinyFileDialogs;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Should be used instead of the direct call to {@link TinyFileDialogs}
|
||||||
|
* so we can run additional validation and/or string cleanup.
|
||||||
|
* Otherwise, we may get error messages back. <br><br>
|
||||||
|
*
|
||||||
|
* source:
|
||||||
|
* https://sourceforge.net/projects/tinyfiledialogs/
|
||||||
|
*
|
||||||
|
* @see TinyFileDialogs
|
||||||
|
*/
|
||||||
|
public class NativeDialogUtil
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @param dialogType the dialog type. One of:<br><table><tr><td>"ok"</td><td>"okcancel"</td><td>"yesno"</td><td>"yesnocancel"</td></tr></table>
|
||||||
|
* @param iconType the icon type. One of:<br><table><tr><td>"info"</td><td>"warning"</td><td>"error"</td><td>"question"</td></tr></table>
|
||||||
|
*/
|
||||||
|
public static void showDialog(String title, String message, String dialogType, String iconType)
|
||||||
|
{
|
||||||
|
// Tinyfd doesn't support the following characters, attempting to display them will cause the message
|
||||||
|
// to be replaced with an error message
|
||||||
|
String unsafeCharsRegex = "['\"`]";
|
||||||
|
|
||||||
|
title = title.replaceAll(unsafeCharsRegex, "");
|
||||||
|
message = message.replaceAll(unsafeCharsRegex, "");
|
||||||
|
|
||||||
|
#if MC_VER <= MC_1_21_11
|
||||||
|
TinyFileDialogs.tinyfd_messageBox(title, message, dialogType, iconType, false);
|
||||||
|
#else
|
||||||
|
// https://mfbridge.github.io/tinyfiledialogs/reference/messageBox.html
|
||||||
|
TinyFileDialogs.tinyfd_messageBox(title, message, dialogType, iconType, 1 /* ok/yes */);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+5
-5
@@ -218,11 +218,11 @@ public class TexturedButtonWidget extends Button
|
|||||||
this.getX(), this.getY(),
|
this.getX(), this.getY(),
|
||||||
this.getWidth(), this.getHeight());
|
this.getWidth(), this.getHeight());
|
||||||
#else
|
#else
|
||||||
//matrices.blitSprite(
|
matrices.blitSprite(
|
||||||
// RenderPipelines.GUI_TEXTURED,
|
RenderPipelines.GUI_TEXTURED,
|
||||||
// SPRITES.get(this.active, this.isHoveredOrFocused()),
|
SPRITES.get(this.active, this.isHoveredOrFocused()),
|
||||||
// this.getX(), this.getY(),
|
this.getX(), this.getY(),
|
||||||
// this.getWidth(), this.getHeight());
|
this.getWidth(), this.getHeight());
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
+384
@@ -0,0 +1,384 @@
|
|||||||
|
package com.seibel.distanthorizons.common.wrappers.gui.classicConfig;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import com.seibel.distanthorizons.core.config.types.*;
|
||||||
|
|
||||||
|
import com.seibel.distanthorizons.core.config.types.enums.EConfigCommentTextPosition;
|
||||||
|
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||||
|
import com.seibel.distanthorizons.core.wrapperInterfaces.config.IConfigGui;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
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;
|
||||||
|
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_20_1
|
||||||
|
import com.mojang.blaze3d.vertex.PoseStack;
|
||||||
|
import net.minecraft.client.gui.GuiComponent;
|
||||||
|
#elif MC_VER <= MC_1_21_11
|
||||||
|
import net.minecraft.client.gui.GuiGraphics;
|
||||||
|
#else
|
||||||
|
import net.minecraft.client.gui.GuiGraphicsExtractor;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if MC_VER >= MC_1_17_1
|
||||||
|
import net.minecraft.client.gui.narration.NarratableEntry;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if MC_VER <= MC_1_21_10
|
||||||
|
#else
|
||||||
|
import net.minecraft.resources.Identifier;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
import static com.seibel.distanthorizons.common.wrappers.gui.GuiHelper.*;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Based upon TinyConfig but is highly modified
|
||||||
|
* https://github.com/Minenash/TinyConfig
|
||||||
|
*
|
||||||
|
* @author coolGi
|
||||||
|
* @author Motschen
|
||||||
|
* @author James Seibel
|
||||||
|
* @version 5-21-2022
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public class ClassicConfigGUI
|
||||||
|
{
|
||||||
|
private static final DhLogger LOGGER = new DhLoggerBuilder().build();
|
||||||
|
public static final DhLogger RATE_LIMITED_LOGGER = new DhLoggerBuilder()
|
||||||
|
.maxCountPerSecond(1)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
public static final ConfigCoreInterface CONFIG_CORE_INTERFACE = new ConfigCoreInterface();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//==============//
|
||||||
|
// Initializers //
|
||||||
|
//==============//
|
||||||
|
|
||||||
|
// Some regexes to check if an input is valid
|
||||||
|
public static final Pattern INTEGER_ONLY_REGEX = Pattern.compile("(-?[0-9]*)");
|
||||||
|
public static final Pattern DECIMAL_ONLY_REGEX = Pattern.compile("-?([\\d]+\\.?[\\d]*|[\\d]*\\.?[\\d]+|\\.)");
|
||||||
|
|
||||||
|
public static class ConfigScreenConfigs
|
||||||
|
{
|
||||||
|
// This contains all the configs for the configs
|
||||||
|
public static final int SPACE_FROM_RIGHT_SCREEN = 10;
|
||||||
|
public static final int SPACE_BETWEEN_TEXT_AND_OPTION_FIELD = 8;
|
||||||
|
public static final int BUTTON_WIDTH_SPACING = 5;
|
||||||
|
public static final int RESET_BUTTON_WIDTH = 60;
|
||||||
|
public static final int RESET_BUTTON_HEIGHT = 20;
|
||||||
|
public static final int OPTION_FIELD_WIDTH = 150;
|
||||||
|
public static final int OPTION_FIELD_HEIGHT = 20;
|
||||||
|
public static final int CATEGORY_BUTTON_WIDTH = 200;
|
||||||
|
public static final int CATEGORY_BUTTON_HEIGHT = 20;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//==============//
|
||||||
|
// GUI handling //
|
||||||
|
//==============//
|
||||||
|
|
||||||
|
/** if you want to get this config gui's screen call this */
|
||||||
|
public static Screen getScreen(Screen parent, String category)
|
||||||
|
{ return new DhConfigScreen(parent, category); }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//================//
|
||||||
|
// helper classes //
|
||||||
|
//================//
|
||||||
|
|
||||||
|
public static class ConfigListWidget extends ContainerObjectSelectionList<DhButtonEntry>
|
||||||
|
{
|
||||||
|
Font textRenderer;
|
||||||
|
|
||||||
|
public ConfigListWidget(Minecraft minecraftClient, int canvasWidth, int canvasHeight, int topMargin, int botMargin, int itemSpacing)
|
||||||
|
{
|
||||||
|
#if MC_VER < MC_1_20_4
|
||||||
|
super(minecraftClient, canvasWidth, canvasHeight, topMargin, canvasHeight - botMargin, itemSpacing);
|
||||||
|
#else
|
||||||
|
super(minecraftClient, canvasWidth, canvasHeight - (topMargin + botMargin), topMargin, itemSpacing);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
this.centerListVertically = false;
|
||||||
|
this.textRenderer = minecraftClient.font;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addButton(DhConfigScreen gui, AbstractConfigBase dhConfigType, AbstractWidget button, AbstractWidget resetButton, AbstractWidget indexButton, Component text)
|
||||||
|
{ this.addEntry(new DhButtonEntry(gui, dhConfigType, button, text, resetButton, indexButton)); }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getRowWidth() { return 10_000; }
|
||||||
|
|
||||||
|
public AbstractWidget getHoveredButton(double mouseX, double mouseY)
|
||||||
|
{
|
||||||
|
for (DhButtonEntry buttonEntry : this.children())
|
||||||
|
{
|
||||||
|
AbstractWidget button = buttonEntry.button;
|
||||||
|
if (button != null
|
||||||
|
&& button.visible)
|
||||||
|
{
|
||||||
|
#if MC_VER < MC_1_19_4
|
||||||
|
double minX = button.x;
|
||||||
|
double minY = button.y;
|
||||||
|
#else
|
||||||
|
double minX = button.getX();
|
||||||
|
double minY = button.getY();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
double maxX = minX + button.getWidth();
|
||||||
|
double maxY = minY + button.getHeight();
|
||||||
|
|
||||||
|
if (mouseX >= minX && mouseX < maxX
|
||||||
|
&& mouseY >= minY && mouseY < maxY)
|
||||||
|
{
|
||||||
|
return button;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static class DhButtonEntry extends ContainerObjectSelectionList.Entry<DhButtonEntry>
|
||||||
|
{
|
||||||
|
private static final Font textRenderer = Minecraft.getInstance().font;
|
||||||
|
|
||||||
|
private final AbstractWidget button;
|
||||||
|
|
||||||
|
private final DhConfigScreen gui;
|
||||||
|
|
||||||
|
private final AbstractWidget resetButton;
|
||||||
|
private final AbstractWidget indexButton;
|
||||||
|
private final Component text;
|
||||||
|
private final List<AbstractWidget> children = new ArrayList<>();
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private final EConfigCommentTextPosition textPosition;
|
||||||
|
public final AbstractConfigBase dhConfigType;
|
||||||
|
|
||||||
|
public static final Map<AbstractWidget, Component> TEXT_BY_WIDGET = new HashMap<>();
|
||||||
|
public static final Map<AbstractWidget, DhButtonEntry> BUTTON_BY_WIDGET = new HashMap<>();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public DhButtonEntry(
|
||||||
|
DhConfigScreen gui, AbstractConfigBase dhConfigType,
|
||||||
|
AbstractWidget button, Component text, AbstractWidget resetButton, AbstractWidget indexButton)
|
||||||
|
{
|
||||||
|
TEXT_BY_WIDGET.put(button, text);
|
||||||
|
BUTTON_BY_WIDGET.put(button, this);
|
||||||
|
|
||||||
|
this.gui = gui;
|
||||||
|
this.dhConfigType = dhConfigType;
|
||||||
|
|
||||||
|
this.button = button;
|
||||||
|
this.resetButton = resetButton;
|
||||||
|
this.text = text;
|
||||||
|
this.indexButton = indexButton;
|
||||||
|
|
||||||
|
if (button != null) { this.children.add(button); }
|
||||||
|
if (resetButton != null) { this.children.add(resetButton); }
|
||||||
|
if (indexButton != null) { this.children.add(indexButton); }
|
||||||
|
|
||||||
|
|
||||||
|
EConfigCommentTextPosition textPosition = null;
|
||||||
|
if (this.dhConfigType instanceof ConfigUIComment)
|
||||||
|
{
|
||||||
|
textPosition = ((ConfigUIComment)this.dhConfigType).textPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (textPosition == null)
|
||||||
|
{
|
||||||
|
if (this.button != null)
|
||||||
|
{
|
||||||
|
// if a button is present
|
||||||
|
textPosition = EConfigCommentTextPosition.RIGHT_JUSTIFIED;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
textPosition = EConfigCommentTextPosition.CENTERED_OVER_BUTTONS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.textPosition = textPosition;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
#if 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)
|
||||||
|
#elif MC_VER < MC_1_21_9
|
||||||
|
public void render(GuiGraphics matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta)
|
||||||
|
#elif MC_VER <= MC_1_21_11
|
||||||
|
public void renderContent(GuiGraphics matrices, int mouseX, int mouseY, boolean hovered, float tickDelta)
|
||||||
|
#else
|
||||||
|
public void extractContent(GuiGraphicsExtractor matrices, int mouseX, int mouseY, boolean hovered, float tickDelta)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// setting the "y" variable is necessary so each child item
|
||||||
|
// renders at the correct height,
|
||||||
|
// if not set they will render off-screen.
|
||||||
|
#if MC_VER < MC_1_21_9
|
||||||
|
// Y value passed in from method args
|
||||||
|
#else
|
||||||
|
int y = this.getY();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (this.button != null)
|
||||||
|
{
|
||||||
|
SetY(this.button, y);
|
||||||
|
#if MC_VER <= MC_1_21_11
|
||||||
|
this.button.render(matrices, mouseX, mouseY, tickDelta);
|
||||||
|
#else
|
||||||
|
this.button.extractRenderState(matrices, mouseX, mouseY, tickDelta);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.resetButton != null)
|
||||||
|
{
|
||||||
|
SetY(this.resetButton, y);
|
||||||
|
#if MC_VER <= MC_1_21_11
|
||||||
|
this.resetButton.render(matrices, mouseX, mouseY, tickDelta);
|
||||||
|
#else
|
||||||
|
this.resetButton.extractRenderState(matrices, mouseX, mouseY, tickDelta);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.indexButton != null)
|
||||||
|
{
|
||||||
|
SetY(this.indexButton, y);
|
||||||
|
#if MC_VER <= MC_1_21_11
|
||||||
|
this.indexButton.render(matrices, mouseX, mouseY, tickDelta);
|
||||||
|
#else
|
||||||
|
this.indexButton.extractRenderState(matrices, mouseX, mouseY, tickDelta);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.text != null)
|
||||||
|
{
|
||||||
|
int translatedLength = textRenderer.width(this.text);
|
||||||
|
|
||||||
|
int textXPos;
|
||||||
|
if (this.textPosition == EConfigCommentTextPosition.RIGHT_JUSTIFIED)
|
||||||
|
{
|
||||||
|
// text right justified aligned against the buttons
|
||||||
|
textXPos = this.gui.width
|
||||||
|
- translatedLength
|
||||||
|
- ConfigScreenConfigs.SPACE_BETWEEN_TEXT_AND_OPTION_FIELD
|
||||||
|
- ConfigScreenConfigs.SPACE_FROM_RIGHT_SCREEN
|
||||||
|
- ConfigScreenConfigs.OPTION_FIELD_WIDTH
|
||||||
|
- ConfigScreenConfigs.BUTTON_WIDTH_SPACING
|
||||||
|
- ConfigScreenConfigs.RESET_BUTTON_WIDTH;
|
||||||
|
}
|
||||||
|
else if (this.textPosition == EConfigCommentTextPosition.CENTERED_OVER_BUTTONS)
|
||||||
|
{
|
||||||
|
// have button centered relative to a category button
|
||||||
|
textXPos = this.gui.width
|
||||||
|
- (translatedLength / 2)
|
||||||
|
- (ConfigScreenConfigs.CATEGORY_BUTTON_WIDTH / 2)
|
||||||
|
- ConfigScreenConfigs.SPACE_FROM_RIGHT_SCREEN;
|
||||||
|
}
|
||||||
|
else if (this.textPosition == EConfigCommentTextPosition.CENTER_OF_SCREEN)
|
||||||
|
{
|
||||||
|
// have button centered in the screen
|
||||||
|
textXPos = (this.gui.width / 2)
|
||||||
|
- (translatedLength / 2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new UnsupportedOperationException("No text position render defined for [" + this.textPosition + "]");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_20_1
|
||||||
|
GuiComponent.drawString(matrices, textRenderer,
|
||||||
|
this.text,
|
||||||
|
textXPos, y + 5,
|
||||||
|
0xFFFFFF);
|
||||||
|
#elif MC_VER < MC_1_21_6
|
||||||
|
matrices.drawString(textRenderer,
|
||||||
|
this.text,
|
||||||
|
textXPos, y + 5,
|
||||||
|
0xFFFFFF);
|
||||||
|
#elif MC_VER <= MC_1_21_11
|
||||||
|
matrices.drawString(textRenderer,
|
||||||
|
this.text,
|
||||||
|
textXPos, y + 5,
|
||||||
|
0xFFFFFFFF);
|
||||||
|
#else
|
||||||
|
matrices.text(textRenderer,
|
||||||
|
this.text,
|
||||||
|
textXPos, y + 5,
|
||||||
|
0xFFFFFFFF);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
// should prevent crashing the game if there's an issue
|
||||||
|
RATE_LIMITED_LOGGER.error("Unexpected gui rendering issue: ["+e.getMessage()+"]", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull List<? extends GuiEventListener> children()
|
||||||
|
{ return this.children; }
|
||||||
|
|
||||||
|
#if MC_VER >= MC_1_17_1
|
||||||
|
@Override
|
||||||
|
public @NotNull List<? extends NarratableEntry> narratables()
|
||||||
|
{ return this.children; }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//================//
|
||||||
|
// event handling //
|
||||||
|
//================//
|
||||||
|
|
||||||
|
public static class ConfigCoreInterface implements IConfigGui
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* in the future it would be good to pass in the current page and other variables,
|
||||||
|
* but for now just knowing when the page is closed is good enough
|
||||||
|
*/
|
||||||
|
public final ArrayList<Runnable> onScreenChangeListenerList = new ArrayList<>();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addOnScreenChangeListener(Runnable newListener) { this.onScreenChangeListenerList.add(newListener); }
|
||||||
|
@Override
|
||||||
|
public void removeOnScreenChangeListener(Runnable oldListener) { this.onScreenChangeListenerList.remove(oldListener); }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+799
@@ -0,0 +1,799 @@
|
|||||||
|
package com.seibel.distanthorizons.common.wrappers.gui.classicConfig;
|
||||||
|
|
||||||
|
import java.util.AbstractMap;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.function.Function;
|
||||||
|
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.TexturedButtonWidget;
|
||||||
|
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.*;
|
||||||
|
import com.seibel.distanthorizons.common.wrappers.gui.updater.ChangelogScreen;
|
||||||
|
|
||||||
|
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;
|
||||||
|
import com.seibel.distanthorizons.core.jar.updater.SelfUpdater;
|
||||||
|
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||||
|
import com.seibel.distanthorizons.core.util.AnnotationUtil;
|
||||||
|
import com.seibel.distanthorizons.core.wrapperInterfaces.config.IConfigGui;
|
||||||
|
import com.seibel.distanthorizons.core.wrapperInterfaces.config.ILangWrapper;
|
||||||
|
import com.seibel.distanthorizons.coreapi.ModInfo;
|
||||||
|
import net.minecraft.ChatFormatting;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.gui.Font;
|
||||||
|
import net.minecraft.client.gui.components.AbstractWidget;
|
||||||
|
import net.minecraft.client.gui.components.Button;
|
||||||
|
import net.minecraft.client.gui.components.ContainerObjectSelectionList;
|
||||||
|
import net.minecraft.client.gui.components.EditBox;
|
||||||
|
import net.minecraft.client.gui.components.events.GuiEventListener;
|
||||||
|
import net.minecraft.client.gui.screens.Screen;
|
||||||
|
import net.minecraft.network.chat.Component;
|
||||||
|
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_20_1
|
||||||
|
import com.mojang.blaze3d.vertex.PoseStack;
|
||||||
|
import net.minecraft.client.gui.GuiComponent;
|
||||||
|
#elif MC_VER <= MC_1_21_11
|
||||||
|
import net.minecraft.client.gui.GuiGraphics;
|
||||||
|
#else
|
||||||
|
import net.minecraft.client.gui.GuiGraphicsExtractor;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if MC_VER >= MC_1_17_1
|
||||||
|
import net.minecraft.client.gui.narration.NarratableEntry;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if MC_VER <= MC_1_21_10
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
#else
|
||||||
|
import net.minecraft.resources.Identifier;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
import org.lwjgl.glfw.GLFW;
|
||||||
|
import com.mojang.blaze3d.platform.InputConstants;
|
||||||
|
|
||||||
|
import static com.seibel.distanthorizons.common.wrappers.gui.GuiHelper.*;
|
||||||
|
import static com.seibel.distanthorizons.common.wrappers.gui.GuiHelper.Translatable;
|
||||||
|
|
||||||
|
class DhConfigScreen extends DhScreen
|
||||||
|
{
|
||||||
|
private static final DhLogger LOGGER = new DhLoggerBuilder().build();
|
||||||
|
private static final ILangWrapper LANG_WRAPPER = SingletonInjector.INSTANCE.get(ILangWrapper.class);
|
||||||
|
|
||||||
|
private static final String TRANSLATION_PREFIX = ModInfo.ID + ".config.";
|
||||||
|
|
||||||
|
private static final MinecraftClientWrapper MC_CLIENT = MinecraftClientWrapper.INSTANCE;
|
||||||
|
|
||||||
|
|
||||||
|
private final Screen parent;
|
||||||
|
private final String category;
|
||||||
|
private ClassicConfigGUI.ConfigListWidget configListWidget;
|
||||||
|
private boolean reload = false;
|
||||||
|
|
||||||
|
private Button doneButton;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//=============//
|
||||||
|
// constructor //
|
||||||
|
//=============//
|
||||||
|
|
||||||
|
protected DhConfigScreen(Screen parent, String category)
|
||||||
|
{
|
||||||
|
super(Translatable(
|
||||||
|
LANG_WRAPPER.langExists(ModInfo.ID + ".config" + (category.isEmpty() ? "." + category : "") + ".title") ?
|
||||||
|
ModInfo.ID + ".config.title" :
|
||||||
|
ModInfo.ID + ".config" + (category.isEmpty() ? "" : "." + category) + ".title")
|
||||||
|
);
|
||||||
|
this.parent = parent;
|
||||||
|
this.category = category;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void tick() { super.tick(); }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//==================//
|
||||||
|
// menu UI creation //
|
||||||
|
//==================//
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void init()
|
||||||
|
{
|
||||||
|
super.init();
|
||||||
|
if (!this.reload)
|
||||||
|
{
|
||||||
|
ConfigHandler.INSTANCE.configFileHandler.loadFromFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Changelog button
|
||||||
|
if (Config.Client.Advanced.AutoUpdater.enableAutoUpdater.get()
|
||||||
|
// we only have changelogs for stable builds
|
||||||
|
&& !ModInfo.IS_DEV_BUILD)
|
||||||
|
{
|
||||||
|
this.addBtn(new TexturedButtonWidget(
|
||||||
|
// Where the button is on the screen
|
||||||
|
this.width - 28, this.height - 28,
|
||||||
|
// Width and height of the button
|
||||||
|
20, 20,
|
||||||
|
// texture UV Offset
|
||||||
|
0, 0,
|
||||||
|
// Some texture stuff
|
||||||
|
0,
|
||||||
|
#if MC_VER < MC_1_21_1
|
||||||
|
new ResourceLocation(ModInfo.ID, "textures/gui/changelog.png"),
|
||||||
|
#elif MC_VER <= MC_1_21_10
|
||||||
|
ResourceLocation.fromNamespaceAndPath(ModInfo.ID, "textures/gui/changelog.png"),
|
||||||
|
#else
|
||||||
|
Identifier.fromNamespaceAndPath(ModInfo.ID, "textures/gui/changelog.png"),
|
||||||
|
#endif
|
||||||
|
20, 20,
|
||||||
|
// Create the button and tell it where to go
|
||||||
|
(buttonWidget) -> {
|
||||||
|
ChangelogScreen changelogScreen = new ChangelogScreen(this);
|
||||||
|
if (changelogScreen.usable)
|
||||||
|
{
|
||||||
|
Objects.requireNonNull(this.minecraft).setScreen(changelogScreen);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LOGGER.warn("Changelog was not able to open");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// Add a title to the button
|
||||||
|
Translatable(ModInfo.ID + ".updater.title")
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// back button
|
||||||
|
this.addBtn(MakeBtn(Translatable("distanthorizons.general.back"),
|
||||||
|
(this.width / 2) - 154, this.height - 28,
|
||||||
|
ClassicConfigGUI.ConfigScreenConfigs.OPTION_FIELD_WIDTH, ClassicConfigGUI.ConfigScreenConfigs.OPTION_FIELD_HEIGHT,
|
||||||
|
(button) ->
|
||||||
|
{
|
||||||
|
ConfigHandler.INSTANCE.configFileHandler.loadFromFile();
|
||||||
|
Objects.requireNonNull(this.minecraft).setScreen(this.parent);
|
||||||
|
}));
|
||||||
|
|
||||||
|
// done/close button
|
||||||
|
this.doneButton = this.addBtn(
|
||||||
|
MakeBtn(Translatable("distanthorizons.general.done"),
|
||||||
|
(this.width / 2) + 4, this.height - 28,
|
||||||
|
ClassicConfigGUI.ConfigScreenConfigs.OPTION_FIELD_WIDTH, ClassicConfigGUI.ConfigScreenConfigs.OPTION_FIELD_HEIGHT,
|
||||||
|
(button) ->
|
||||||
|
{
|
||||||
|
ConfigHandler.INSTANCE.configFileHandler.saveToFile();
|
||||||
|
Objects.requireNonNull(this.minecraft).setScreen(this.parent);
|
||||||
|
}));
|
||||||
|
|
||||||
|
this.configListWidget = new ClassicConfigGUI.ConfigListWidget(this.minecraft, this.width * 2, this.height, 32, 32, 25);
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_20_6 // no background is rendered in MC 1.20.6+
|
||||||
|
if (this.minecraft != null && this.minecraft.level != null)
|
||||||
|
{
|
||||||
|
this.configListWidget.setRenderBackground(false);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
this.addWidget(this.configListWidget);
|
||||||
|
|
||||||
|
for (AbstractConfigBase<?> configEntry : ConfigHandler.INSTANCE.configBaseList)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (configEntry.getCategory().matches(this.category)
|
||||||
|
&& configEntry.getAppearance().showInGui)
|
||||||
|
{
|
||||||
|
this.addMenuItem(configEntry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
String message = "ERROR: Failed to show [" + configEntry.getNameAndCategory() + "], error: [" + e.getMessage() + "]";
|
||||||
|
if (configEntry.get() != null)
|
||||||
|
{
|
||||||
|
message += " with the value [" + configEntry.get() + "] with type [" + configEntry.getType() + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
LOGGER.error(message, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ClassicConfigGUI.CONFIG_CORE_INTERFACE.onScreenChangeListenerList.forEach((listener) -> listener.run());
|
||||||
|
}
|
||||||
|
private void addMenuItem(AbstractConfigBase<?> configEntry)
|
||||||
|
{
|
||||||
|
trySetupConfigEntry(configEntry);
|
||||||
|
|
||||||
|
if (this.tryCreateInputField(configEntry)) return;
|
||||||
|
if (this.tryCreateCategoryButton(configEntry)) return;
|
||||||
|
if (this.tryCreateButton(configEntry)) return;
|
||||||
|
if (this.tryCreateComment(configEntry)) return;
|
||||||
|
if (this.tryCreateSpacer(configEntry)) return;
|
||||||
|
if (this.tryCreateLinkedEntry(configEntry)) return;
|
||||||
|
|
||||||
|
LOGGER.warn("Config [" + configEntry.getNameAndCategory() + "] failed to show. Please try something like changing its type.");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void trySetupConfigEntry(AbstractConfigBase<?> configMenuOption)
|
||||||
|
{
|
||||||
|
configMenuOption.guiValue = new ConfigGuiInfo();
|
||||||
|
Class<?> configValueClass = configMenuOption.getType();
|
||||||
|
|
||||||
|
if (configMenuOption instanceof ConfigEntry)
|
||||||
|
{
|
||||||
|
ConfigEntry<?> configEntry = (ConfigEntry<?>) configMenuOption;
|
||||||
|
|
||||||
|
if (configValueClass == Integer.class)
|
||||||
|
{
|
||||||
|
setupTextMenuOption(configEntry, Integer::parseInt, ClassicConfigGUI.INTEGER_ONLY_REGEX, true);
|
||||||
|
}
|
||||||
|
else if (configValueClass == Double.class)
|
||||||
|
{
|
||||||
|
setupTextMenuOption(configEntry, Double::parseDouble, ClassicConfigGUI.DECIMAL_ONLY_REGEX, false);
|
||||||
|
}
|
||||||
|
else if (configValueClass == Float.class)
|
||||||
|
{
|
||||||
|
setupTextMenuOption(configEntry, Float::parseFloat, ClassicConfigGUI.DECIMAL_ONLY_REGEX, false);
|
||||||
|
}
|
||||||
|
else if (configValueClass == String.class || configValueClass == List.class)
|
||||||
|
{
|
||||||
|
// For string or list
|
||||||
|
setupTextMenuOption(configEntry, String::length, null, true);
|
||||||
|
}
|
||||||
|
else if (configValueClass == Boolean.class)
|
||||||
|
{
|
||||||
|
ConfigEntry<Boolean> booleanConfigEntry = (ConfigEntry<Boolean>) configEntry;
|
||||||
|
setupBooleanMenuOption(booleanConfigEntry);
|
||||||
|
}
|
||||||
|
else if (configValueClass.isEnum())
|
||||||
|
{
|
||||||
|
ConfigEntry<Enum<?>> enumConfigEntry = (ConfigEntry<Enum<?>>) configEntry;
|
||||||
|
Class<? extends Enum<?>> configEnumClass = (Class<? extends Enum<?>>) configValueClass;
|
||||||
|
setupEnumMenuOption(enumConfigEntry, configEnumClass);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LOGGER.error("No definition for config with type: [" + configValueClass.getName() + "], for config: [" + configMenuOption.name + "].");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
private static void setupTextMenuOption(AbstractConfigBase<?> configMenuOption, Function<String, Number> parsingFunc, @Nullable Pattern pattern, boolean cast)
|
||||||
|
{
|
||||||
|
final ConfigGuiInfo configGuiInfo = ((ConfigGuiInfo) configMenuOption.guiValue);
|
||||||
|
|
||||||
|
configGuiInfo.tooltipFunction =
|
||||||
|
(editBox, button) ->
|
||||||
|
(stringValue) ->
|
||||||
|
{
|
||||||
|
boolean isNumber = (pattern != null);
|
||||||
|
|
||||||
|
stringValue = stringValue.trim();
|
||||||
|
if (!(stringValue.isEmpty() || !isNumber || pattern.matcher(stringValue).matches()))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Number numberValue = configMenuOption.typeIsFloatingPointNumber() ? 0.0 : 0; // different default values are needed so implicit casting works correctly (if not done casting from 0 (an int) to a double will cause an exception)
|
||||||
|
configGuiInfo.errorMessage = null;
|
||||||
|
if (isNumber
|
||||||
|
&& !stringValue.isEmpty()
|
||||||
|
&& !stringValue.equals("-")
|
||||||
|
&& !stringValue.equals("."))
|
||||||
|
{
|
||||||
|
ConfigEntry<Number> numberConfigEntry = (ConfigEntry<Number>) configMenuOption;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
numberValue = parsingFunc.apply(stringValue);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
numberValue = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
EConfigValidity validity = numberConfigEntry.getValidity(numberValue);
|
||||||
|
switch (validity)
|
||||||
|
{
|
||||||
|
case VALID:
|
||||||
|
configGuiInfo.errorMessage = null;
|
||||||
|
break;
|
||||||
|
case NUMBER_TOO_LOW:
|
||||||
|
configGuiInfo.errorMessage = TextOrTranslatable("§cMinimum length is " + numberConfigEntry.getMin());
|
||||||
|
break;
|
||||||
|
case NUMBER_TOO_HIGH:
|
||||||
|
configGuiInfo.errorMessage = TextOrTranslatable("§cMaximum length is " + numberConfigEntry.getMax());
|
||||||
|
break;
|
||||||
|
case INVALID:
|
||||||
|
configGuiInfo.errorMessage = TextOrTranslatable("§cValue is invalid");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
editBox.setTextColor(((ConfigEntry<Number>) configMenuOption).getValidity(numberValue) == EConfigValidity.VALID ? 0xFFFFFFFF : 0xFFFF7777); // white and red
|
||||||
|
|
||||||
|
|
||||||
|
if (configMenuOption.getType() == String.class
|
||||||
|
|| configMenuOption.getType() == List.class)
|
||||||
|
{
|
||||||
|
((ConfigEntry<String>) configMenuOption).uiSetWithoutSaving(stringValue);
|
||||||
|
}
|
||||||
|
else if (((ConfigEntry<Number>) configMenuOption).getValidity(numberValue) == EConfigValidity.VALID)
|
||||||
|
{
|
||||||
|
if (!cast)
|
||||||
|
{
|
||||||
|
((ConfigEntry<Number>) configMenuOption).uiSetWithoutSaving(numberValue);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
((ConfigEntry<Number>) configMenuOption).uiSetWithoutSaving(numberValue != null ? numberValue.intValue() : 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
private static void setupBooleanMenuOption(ConfigEntry<Boolean> booleanConfigEntry)
|
||||||
|
{
|
||||||
|
// For boolean
|
||||||
|
Function<Object, Component> func = value -> Translatable("distanthorizons.general." + ((Boolean) value ? "true" : "false")).withStyle((Boolean) value ? ChatFormatting.GREEN : ChatFormatting.RED);
|
||||||
|
|
||||||
|
final ConfigGuiInfo configGuiInfo = ((ConfigGuiInfo) booleanConfigEntry.guiValue);
|
||||||
|
|
||||||
|
configGuiInfo.buttonOptionMap =
|
||||||
|
new AbstractMap.SimpleEntry<Button.OnPress, Function<Object, Component>>(
|
||||||
|
(button) ->
|
||||||
|
{
|
||||||
|
button.active = !booleanConfigEntry.apiIsOverriding();
|
||||||
|
|
||||||
|
booleanConfigEntry.uiSetWithoutSaving(!booleanConfigEntry.get());
|
||||||
|
button.setMessage(func.apply(booleanConfigEntry.get()));
|
||||||
|
}, func);
|
||||||
|
}
|
||||||
|
private static void setupEnumMenuOption(ConfigEntry<Enum<?>> enumConfigEntry, Class<? extends Enum<?>> enumClass)
|
||||||
|
{
|
||||||
|
List<Enum<?>> enumList = Arrays.asList(enumClass.getEnumConstants());
|
||||||
|
|
||||||
|
final ConfigGuiInfo configGuiInfo = ((ConfigGuiInfo) enumConfigEntry.guiValue);
|
||||||
|
|
||||||
|
Function<Object, Component> getEnumTranslatableFunc = (value) -> Translatable(TRANSLATION_PREFIX + "enum." + enumClass.getSimpleName() + "." + enumConfigEntry.get().toString());
|
||||||
|
configGuiInfo.buttonOptionMap =
|
||||||
|
new AbstractMap.SimpleEntry<Button.OnPress, Function<Object, Component>>(
|
||||||
|
(button) ->
|
||||||
|
{
|
||||||
|
// get the currently selected enum and enum index
|
||||||
|
int startingIndex = enumList.indexOf(enumConfigEntry.get());
|
||||||
|
Enum<?> enumValue = enumList.get(startingIndex);
|
||||||
|
|
||||||
|
boolean shiftPressed =
|
||||||
|
InputConstants.isKeyDown(MC_CLIENT.getGlfwWindowId(), GLFW.GLFW_KEY_LEFT_SHIFT)
|
||||||
|
|| InputConstants.isKeyDown(MC_CLIENT.getGlfwWindowId(), GLFW.GLFW_KEY_RIGHT_SHIFT);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// move forward or backwards depending on if the shift key is pressed
|
||||||
|
int index = shiftPressed ? startingIndex - 1 : startingIndex + 1;
|
||||||
|
|
||||||
|
// wrap around to the other side of the array when necessary
|
||||||
|
if (index >= enumList.size())
|
||||||
|
{
|
||||||
|
index = 0;
|
||||||
|
}
|
||||||
|
else if (index < 0)
|
||||||
|
{
|
||||||
|
index = enumList.size() - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// walk through the enums to find the next selectable one
|
||||||
|
while (index != startingIndex)
|
||||||
|
{
|
||||||
|
enumValue = enumList.get(index);
|
||||||
|
if (!AnnotationUtil.doesEnumHaveAnnotation(enumValue, DisallowSelectingViaConfigGui.class))
|
||||||
|
{
|
||||||
|
// this enum shouldn't be selectable via the UI,
|
||||||
|
// skip it
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// move forward or backwards depending on if the shift key is pressed
|
||||||
|
index = shiftPressed ? index - 1 : index + 1;
|
||||||
|
|
||||||
|
// wrap around to the other side of the array when necessary
|
||||||
|
if (index >= enumList.size())
|
||||||
|
{
|
||||||
|
index = 0;
|
||||||
|
}
|
||||||
|
else if (index < 0)
|
||||||
|
{
|
||||||
|
index = enumList.size() - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (index == startingIndex)
|
||||||
|
{
|
||||||
|
// one of the enums should be selectable, this is a programmer error
|
||||||
|
enumValue = enumList.get(startingIndex);
|
||||||
|
LOGGER.warn("Enum [" + enumValue.getClass() + "] doesn't contain any values that should be selectable via the UI, sticking to the currently selected value [" + enumValue + "].");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
enumConfigEntry.uiSetWithoutSaving(enumValue);
|
||||||
|
|
||||||
|
button.active = !enumConfigEntry.apiIsOverriding();
|
||||||
|
|
||||||
|
button.setMessage(getEnumTranslatableFunc.apply(enumConfigEntry.get()));
|
||||||
|
}, getEnumTranslatableFunc);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean tryCreateInputField(AbstractConfigBase<?> configBase)
|
||||||
|
{
|
||||||
|
final ConfigGuiInfo configGuiInfo = ((ConfigGuiInfo) configBase.guiValue);
|
||||||
|
|
||||||
|
if (configBase instanceof ConfigEntry)
|
||||||
|
{
|
||||||
|
ConfigEntry configEntry = (ConfigEntry) configBase;
|
||||||
|
|
||||||
|
|
||||||
|
//==============//
|
||||||
|
// reset button //
|
||||||
|
//==============//
|
||||||
|
|
||||||
|
Button.OnPress btnAction = (button) ->
|
||||||
|
{
|
||||||
|
configEntry.uiSetWithoutSaving(configEntry.getDefaultValue());
|
||||||
|
this.reload = true;
|
||||||
|
Objects.requireNonNull(this.minecraft).setScreen(this);
|
||||||
|
};
|
||||||
|
|
||||||
|
int resetButtonPosX = this.width
|
||||||
|
- ClassicConfigGUI.ConfigScreenConfigs.RESET_BUTTON_WIDTH
|
||||||
|
- ClassicConfigGUI.ConfigScreenConfigs.SPACE_FROM_RIGHT_SCREEN;
|
||||||
|
int resetButtonPosZ = 0;
|
||||||
|
|
||||||
|
Button resetButton = MakeBtn(
|
||||||
|
Translatable("distanthorizons.general.reset").withStyle(ChatFormatting.RED),
|
||||||
|
resetButtonPosX, resetButtonPosZ,
|
||||||
|
ClassicConfigGUI.ConfigScreenConfigs.RESET_BUTTON_WIDTH, ClassicConfigGUI.ConfigScreenConfigs.RESET_BUTTON_HEIGHT,
|
||||||
|
btnAction);
|
||||||
|
|
||||||
|
if (configEntry.apiIsOverriding())
|
||||||
|
{
|
||||||
|
resetButton.active = false;
|
||||||
|
resetButton.setMessage(Translatable("distanthorizons.general.apiOverride").withStyle(ChatFormatting.DARK_GRAY));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
resetButton.active = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//==============//
|
||||||
|
// option field //
|
||||||
|
//==============//
|
||||||
|
|
||||||
|
Component textComponent = this.GetTranslatableTextComponentForConfig(configEntry);
|
||||||
|
|
||||||
|
int optionFieldPosX = this.width
|
||||||
|
- ClassicConfigGUI.ConfigScreenConfigs.SPACE_FROM_RIGHT_SCREEN
|
||||||
|
- ClassicConfigGUI.ConfigScreenConfigs.RESET_BUTTON_WIDTH
|
||||||
|
- ClassicConfigGUI.ConfigScreenConfigs.BUTTON_WIDTH_SPACING
|
||||||
|
- ClassicConfigGUI.ConfigScreenConfigs.OPTION_FIELD_WIDTH;
|
||||||
|
int optionFieldPosZ = 0;
|
||||||
|
|
||||||
|
if (configGuiInfo.buttonOptionMap != null)
|
||||||
|
{
|
||||||
|
// enum/multi option input button
|
||||||
|
|
||||||
|
Map.Entry<Button.OnPress, Function<Object, Component>> widget = configGuiInfo.buttonOptionMap;
|
||||||
|
if (configEntry.getType().isEnum())
|
||||||
|
{
|
||||||
|
widget.setValue((value) -> Translatable(TRANSLATION_PREFIX + "enum." + configEntry.getType().getSimpleName() + "." + configEntry.get().toString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
Button button = MakeBtn(
|
||||||
|
widget.getValue().apply(configEntry.get()),
|
||||||
|
optionFieldPosX, optionFieldPosZ,
|
||||||
|
ClassicConfigGUI.ConfigScreenConfigs.OPTION_FIELD_WIDTH, ClassicConfigGUI.ConfigScreenConfigs.CATEGORY_BUTTON_HEIGHT,
|
||||||
|
widget.getKey());
|
||||||
|
|
||||||
|
// deactivate the button if the API is overriding it
|
||||||
|
button.active = !configEntry.apiIsOverriding();
|
||||||
|
|
||||||
|
|
||||||
|
this.configListWidget.addButton(this, configEntry,
|
||||||
|
button,
|
||||||
|
resetButton,
|
||||||
|
null,
|
||||||
|
textComponent);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// text box input
|
||||||
|
|
||||||
|
EditBox widget = new EditBox(this.font,
|
||||||
|
optionFieldPosX, optionFieldPosZ,
|
||||||
|
ClassicConfigGUI.ConfigScreenConfigs.OPTION_FIELD_WIDTH - 4, ClassicConfigGUI.ConfigScreenConfigs.CATEGORY_BUTTON_HEIGHT,
|
||||||
|
Translatable(""));
|
||||||
|
widget.setMaxLength(3_000_000); // hopefully 3 million characters should be enough for any normal use-case, lol
|
||||||
|
widget.insertText(String.valueOf(configEntry.get()));
|
||||||
|
|
||||||
|
Predicate<String> processor = configGuiInfo.tooltipFunction.apply(widget, this.doneButton);
|
||||||
|
#if MC_VER <= MC_1_21_11
|
||||||
|
widget.setFilter(processor);
|
||||||
|
#else
|
||||||
|
widget.setResponder(processor::test);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
this.configListWidget.addButton(this, configEntry, widget, resetButton, null, textComponent);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
private boolean tryCreateCategoryButton(AbstractConfigBase<?> configType)
|
||||||
|
{
|
||||||
|
if (configType instanceof ConfigCategory)
|
||||||
|
{
|
||||||
|
ConfigCategory configCategory = (ConfigCategory) configType;
|
||||||
|
|
||||||
|
Component textComponent = this.GetTranslatableTextComponentForConfig(configCategory);
|
||||||
|
|
||||||
|
int categoryPosX = this.width - ClassicConfigGUI.ConfigScreenConfigs.CATEGORY_BUTTON_WIDTH - ClassicConfigGUI.ConfigScreenConfigs.SPACE_FROM_RIGHT_SCREEN;
|
||||||
|
int categoryPosZ = this.height - ClassicConfigGUI.ConfigScreenConfigs.CATEGORY_BUTTON_HEIGHT; // Note: the posZ value here seems to be ignored
|
||||||
|
|
||||||
|
Button widget = MakeBtn(textComponent,
|
||||||
|
categoryPosX, categoryPosZ,
|
||||||
|
ClassicConfigGUI.ConfigScreenConfigs.CATEGORY_BUTTON_WIDTH, ClassicConfigGUI.ConfigScreenConfigs.CATEGORY_BUTTON_HEIGHT,
|
||||||
|
((button) ->
|
||||||
|
{
|
||||||
|
ConfigHandler.INSTANCE.configFileHandler.saveToFile();
|
||||||
|
Objects.requireNonNull(this.minecraft).setScreen(ClassicConfigGUI.getScreen(this, configCategory.getDestination()));
|
||||||
|
}));
|
||||||
|
this.configListWidget.addButton(this, configType, widget, null, null, null);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
private boolean tryCreateButton(AbstractConfigBase<?> configType)
|
||||||
|
{
|
||||||
|
if (configType instanceof ConfigUIButton)
|
||||||
|
{
|
||||||
|
ConfigUIButton configUiButton = (ConfigUIButton) configType;
|
||||||
|
|
||||||
|
Component textComponent = this.GetTranslatableTextComponentForConfig(configUiButton);
|
||||||
|
|
||||||
|
int buttonPosX = this.width - ClassicConfigGUI.ConfigScreenConfigs.CATEGORY_BUTTON_WIDTH - ClassicConfigGUI.ConfigScreenConfigs.SPACE_FROM_RIGHT_SCREEN;
|
||||||
|
|
||||||
|
Button widget = MakeBtn(textComponent,
|
||||||
|
buttonPosX, this.height - 28,
|
||||||
|
ClassicConfigGUI.ConfigScreenConfigs.CATEGORY_BUTTON_WIDTH, ClassicConfigGUI.ConfigScreenConfigs.CATEGORY_BUTTON_HEIGHT,
|
||||||
|
(button) -> ((ConfigUIButton) configType).runAction());
|
||||||
|
this.configListWidget.addButton(this, configType, widget, null, null, null);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
private boolean tryCreateComment(AbstractConfigBase<?> configType)
|
||||||
|
{
|
||||||
|
if (configType instanceof ConfigUIComment)
|
||||||
|
{
|
||||||
|
ConfigUIComment configUiComment = (ConfigUIComment) configType;
|
||||||
|
|
||||||
|
Component textComponent = this.GetTranslatableTextComponentForConfig(configUiComment);
|
||||||
|
if (configUiComment.parentConfigPath != null)
|
||||||
|
{
|
||||||
|
textComponent = Translatable(TRANSLATION_PREFIX + configUiComment.parentConfigPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.configListWidget.addButton(this, configType, null, null, null, textComponent);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
private boolean tryCreateSpacer(AbstractConfigBase<?> configType)
|
||||||
|
{
|
||||||
|
if (configType instanceof ConfigUISpacer)
|
||||||
|
{
|
||||||
|
Button spacerButton = MakeBtn(Translatable("distanthorizons.general.spacer"),
|
||||||
|
10, 10, // having too small of a size causes division by 0 errors in older MC versions (IE 1.20.1)
|
||||||
|
1, 1,
|
||||||
|
(button) -> { });
|
||||||
|
|
||||||
|
spacerButton.visible = false;
|
||||||
|
this.configListWidget.addButton(this, configType, spacerButton, null, null, null);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
private boolean tryCreateLinkedEntry(AbstractConfigBase<?> configType)
|
||||||
|
{
|
||||||
|
if (configType instanceof ConfigUiLinkedEntry)
|
||||||
|
{
|
||||||
|
this.addMenuItem(((ConfigUiLinkedEntry) configType).get());
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Component GetTranslatableTextComponentForConfig(AbstractConfigBase<?> configType)
|
||||||
|
{ return Translatable(TRANSLATION_PREFIX + configType.getNameAndCategory()); }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//===========//
|
||||||
|
// rendering //
|
||||||
|
//===========//
|
||||||
|
|
||||||
|
@Override
|
||||||
|
#if 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)
|
||||||
|
#else
|
||||||
|
public void extractRenderState(GuiGraphicsExtractor matrices, int mouseX, int mouseY, float delta)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
#if MC_VER < MC_1_20_2 // 1.20.2 now enables this by default in the `this.list.render` function
|
||||||
|
this.renderBackground(matrices);
|
||||||
|
#elif MC_VER <= MC_1_21_11
|
||||||
|
super.render(matrices, mouseX, mouseY, delta);
|
||||||
|
#else
|
||||||
|
super.extractRenderState(matrices, mouseX, mouseY, delta);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Render buttons
|
||||||
|
#if MC_VER <= MC_1_21_11
|
||||||
|
this.configListWidget.render(matrices, mouseX, mouseY, delta);
|
||||||
|
#else
|
||||||
|
this.configListWidget.extractRenderState(matrices, mouseX, mouseY, delta);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
// Render config title
|
||||||
|
this.DhDrawCenteredString(matrices, this.font, this.title,
|
||||||
|
this.width / 2, 15,
|
||||||
|
#if MC_VER < MC_1_21_6
|
||||||
|
0xFFFFFF // RGB white
|
||||||
|
#else
|
||||||
|
0xFFFFFFFF // ARGB white
|
||||||
|
#endif );
|
||||||
|
|
||||||
|
|
||||||
|
// render DH version
|
||||||
|
this.DhDrawString(matrices, this.font, TextOrLiteral(ModInfo.VERSION), 2, this.height - 10,
|
||||||
|
#if MC_VER < MC_1_21_6
|
||||||
|
0xAAAAAA // RGB white
|
||||||
|
#else
|
||||||
|
0xFFAAAAAA // ARGB white
|
||||||
|
#endif );
|
||||||
|
|
||||||
|
// If the update is pending, display this message to inform the user that it will apply when the game restarts
|
||||||
|
if (SelfUpdater.deleteOldJarOnJvmShutdown)
|
||||||
|
{
|
||||||
|
this.DhDrawString(matrices, this.font, Translatable(ModInfo.ID + ".updater.waitingForClose"), 4, this.height - 42,
|
||||||
|
#if MC_VER < MC_1_21_6
|
||||||
|
0xFFFFFF // RGB white
|
||||||
|
#else
|
||||||
|
0xFFFFFFFF // ARGB white
|
||||||
|
#endif );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
this.renderTooltip(matrices, mouseX, mouseY, delta);
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_20_2
|
||||||
|
super.render(matrices, mouseX, mouseY, delta);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#if MC_VER < MC_1_20_1
|
||||||
|
private void renderTooltip(PoseStack matrices, int mouseX, int mouseY, float delta)
|
||||||
|
#elif MC_VER <= MC_1_21_11
|
||||||
|
private void renderTooltip(GuiGraphics matrices, int mouseX, int mouseY, float delta)
|
||||||
|
#else
|
||||||
|
private void renderTooltip(GuiGraphicsExtractor matrices, int mouseX, int mouseY, float delta)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
AbstractWidget hoveredWidget = this.configListWidget.getHoveredButton(mouseX, mouseY);
|
||||||
|
if (hoveredWidget == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ClassicConfigGUI.DhButtonEntry button = ClassicConfigGUI.DhButtonEntry.BUTTON_BY_WIDGET.get(hoveredWidget);
|
||||||
|
|
||||||
|
|
||||||
|
// A quick fix for tooltips on linked entries
|
||||||
|
AbstractConfigBase<?> configBase = ConfigUiLinkedEntry.class.isAssignableFrom(button.dhConfigType.getClass()) ?
|
||||||
|
((ConfigUiLinkedEntry) button.dhConfigType).get() :
|
||||||
|
button.dhConfigType;
|
||||||
|
|
||||||
|
boolean apiOverrideActive = false;
|
||||||
|
if (configBase instanceof ConfigEntry)
|
||||||
|
{
|
||||||
|
apiOverrideActive = ((ConfigEntry<?>) configBase).apiIsOverriding();
|
||||||
|
}
|
||||||
|
|
||||||
|
String key = TRANSLATION_PREFIX + (configBase.category.isEmpty() ? "" : configBase.category + ".") + configBase.getName() + ".@tooltip";
|
||||||
|
|
||||||
|
if (apiOverrideActive)
|
||||||
|
{
|
||||||
|
key = "distanthorizons.general.disabledByApi.@tooltip";
|
||||||
|
}
|
||||||
|
|
||||||
|
// display the validation error tooltip if present
|
||||||
|
final ConfigGuiInfo configGuiInfo = ((ConfigGuiInfo) configBase.guiValue);
|
||||||
|
if (configGuiInfo.errorMessage != null)
|
||||||
|
{
|
||||||
|
this.DhRenderTooltip(matrices, this.font, configGuiInfo.errorMessage, mouseX, mouseY);
|
||||||
|
}
|
||||||
|
// display the tooltip if present
|
||||||
|
else if (LANG_WRAPPER.langExists(key))
|
||||||
|
{
|
||||||
|
List<Component> list = new ArrayList<>();
|
||||||
|
String lang = LANG_WRAPPER.getLang(key);
|
||||||
|
for (String langLine : lang.split("\n"))
|
||||||
|
{
|
||||||
|
list.add(TextOrTranslatable(langLine));
|
||||||
|
}
|
||||||
|
|
||||||
|
this.DhRenderComponentTooltip(matrices, this.font, list, mouseX, mouseY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//==========//
|
||||||
|
// shutdown //
|
||||||
|
//==========//
|
||||||
|
|
||||||
|
/** When you close it, it goes to the previous screen and saves */
|
||||||
|
@Override
|
||||||
|
public void onClose()
|
||||||
|
{
|
||||||
|
ConfigHandler.INSTANCE.configFileHandler.saveToFile();
|
||||||
|
Objects.requireNonNull(this.minecraft).setScreen(this.parent);
|
||||||
|
|
||||||
|
ClassicConfigGUI.CONFIG_CORE_INTERFACE.onScreenChangeListenerList.forEach((listener) -> listener.run());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
+18
-6
@@ -22,6 +22,7 @@ package com.seibel.distanthorizons.common.wrappers.minecraft;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
|
||||||
import com.mojang.blaze3d.platform.Window;
|
import com.mojang.blaze3d.platform.Window;
|
||||||
|
import com.seibel.distanthorizons.common.wrappers.gui.NativeDialogUtil;
|
||||||
import com.seibel.distanthorizons.common.wrappers.world.ClientLevelWrapper;
|
import com.seibel.distanthorizons.common.wrappers.world.ClientLevelWrapper;
|
||||||
import com.seibel.distanthorizons.core.file.structure.ClientOnlySaveStructure;
|
import com.seibel.distanthorizons.core.file.structure.ClientOnlySaveStructure;
|
||||||
import com.seibel.distanthorizons.core.render.RenderThreadTaskHandler;
|
import com.seibel.distanthorizons.core.render.RenderThreadTaskHandler;
|
||||||
@@ -370,17 +371,28 @@ public class MinecraftClientWrapper implements IMinecraftClientWrapper, IMinecra
|
|||||||
public void crashMinecraft(String errorMessage, Throwable exception)
|
public void crashMinecraft(String errorMessage, Throwable exception)
|
||||||
{
|
{
|
||||||
LOGGER.fatal(ModInfo.READABLE_NAME + " had the following error: [" + errorMessage + "]. Crashing Minecraft...", exception);
|
LOGGER.fatal(ModInfo.READABLE_NAME + " had the following error: [" + errorMessage + "]. Crashing Minecraft...", exception);
|
||||||
CrashReport report = new CrashReport(errorMessage, exception);
|
|
||||||
#if MC_VER < MC_1_20_4
|
// Only crash once the renderer has been set up.
|
||||||
Minecraft.crash(report);
|
// If the renderer hasn't been set up yet crashing MC will
|
||||||
#else
|
// cause a Blaze3D/UI error instead of the error we're trying to send.
|
||||||
MINECRAFT.delayCrash(report);
|
executeOnRenderThread(() ->
|
||||||
#endif
|
{
|
||||||
|
CrashReport report = new CrashReport(errorMessage, exception);
|
||||||
|
#if MC_VER < MC_1_20_4
|
||||||
|
Minecraft.crash(report);
|
||||||
|
#else
|
||||||
|
MINECRAFT.delayCrash(report);
|
||||||
|
#endif
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void executeOnRenderThread(Runnable runnable) { MINECRAFT.execute(runnable); }
|
public void executeOnRenderThread(Runnable runnable) { MINECRAFT.execute(runnable); }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showDialog(String title, String message, String dialogType, String iconType)
|
||||||
|
{ NativeDialogUtil.showDialog(title, message, dialogType, iconType); }
|
||||||
|
|
||||||
//endregion
|
//endregion
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+6
-2
@@ -30,9 +30,10 @@ import com.seibel.distanthorizons.common.wrappers.McObjectConverter;
|
|||||||
import com.seibel.distanthorizons.common.wrappers.misc.LightMapWrapper;
|
import com.seibel.distanthorizons.common.wrappers.misc.LightMapWrapper;
|
||||||
import com.seibel.distanthorizons.core.config.Config;
|
import com.seibel.distanthorizons.core.config.Config;
|
||||||
|
|
||||||
|
import com.seibel.distanthorizons.core.dependencyInjection.ModAccessorInjector;
|
||||||
import com.seibel.distanthorizons.core.enums.EDhDirection;
|
import com.seibel.distanthorizons.core.enums.EDhDirection;
|
||||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||||
import com.seibel.distanthorizons.core.util.ColorUtil;
|
import com.seibel.distanthorizons.coreapi.util.ColorUtil;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.ILightMapWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.ILightMapWrapper;
|
||||||
|
|
||||||
#if MC_VER < MC_1_17_1
|
#if MC_VER < MC_1_17_1
|
||||||
@@ -57,6 +58,7 @@ import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
|
|||||||
import com.seibel.distanthorizons.core.util.math.Vec3d;
|
import com.seibel.distanthorizons.core.util.math.Vec3d;
|
||||||
import com.seibel.distanthorizons.core.util.math.Vec3f;
|
import com.seibel.distanthorizons.core.util.math.Vec3f;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
|
||||||
|
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IOptifineAccessor;
|
||||||
|
|
||||||
import net.minecraft.client.Camera;
|
import net.minecraft.client.Camera;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
@@ -97,6 +99,8 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
|
|||||||
{
|
{
|
||||||
public static final MinecraftRenderWrapper INSTANCE = new MinecraftRenderWrapper();
|
public static final MinecraftRenderWrapper INSTANCE = new MinecraftRenderWrapper();
|
||||||
|
|
||||||
|
private static final IOptifineAccessor OPTIFINE_ACCESSOR = ModAccessorInjector.INSTANCE.get(IOptifineAccessor.class);
|
||||||
|
|
||||||
private static final DhLogger LOGGER = new DhLoggerBuilder().build();
|
private static final DhLogger LOGGER = new DhLoggerBuilder().build();
|
||||||
private static final Minecraft MC = Minecraft.getInstance();
|
private static final Minecraft MC = Minecraft.getInstance();
|
||||||
|
|
||||||
@@ -364,7 +368,7 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
|
|||||||
public int getTargetFramebuffer()
|
public int getTargetFramebuffer()
|
||||||
{
|
{
|
||||||
// used so we can access the framebuffer shaders end up rendering to
|
// used so we can access the framebuffer shaders end up rendering to
|
||||||
if (AbstractOptifineAccessor.optifinePresent())
|
if (OPTIFINE_ACCESSOR != null)
|
||||||
{
|
{
|
||||||
return this.finalLevelFrameBufferId;
|
return this.finalLevelFrameBufferId;
|
||||||
}
|
}
|
||||||
|
|||||||
+32
-12
@@ -23,27 +23,47 @@ import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IProfilerWrap
|
|||||||
|
|
||||||
import net.minecraft.util.profiling.ProfilerFiller;
|
import net.minecraft.util.profiling.ProfilerFiller;
|
||||||
|
|
||||||
/**
|
|
||||||
* @author James Seibel
|
|
||||||
* @version 11-20-2021
|
|
||||||
*/
|
|
||||||
public class ProfilerWrapper implements IProfilerWrapper
|
public class ProfilerWrapper implements IProfilerWrapper
|
||||||
{
|
{
|
||||||
public ProfilerFiller profiler;
|
public ProfilerFiller profiler;
|
||||||
|
|
||||||
public ProfilerWrapper(ProfilerFiller newProfiler) { this.profiler = newProfiler; }
|
public ProfilerWrapper(ProfilerFiller newProfiler) { this.profiler = newProfiler; }
|
||||||
|
|
||||||
|
|
||||||
/** starts a new section inside the currently running section */
|
|
||||||
@Override
|
@Override
|
||||||
public void push(String newSection) { this.profiler.push(newSection); }
|
public IProfileBlock push(String newSection)
|
||||||
|
{
|
||||||
|
this.profiler.push(newSection);
|
||||||
|
return new ProfileBlock(this.profiler);
|
||||||
|
}
|
||||||
|
|
||||||
/** ends the currently running section and starts a new one */
|
|
||||||
@Override
|
@Override
|
||||||
public void popPush(String newSection) { this.profiler.popPush(newSection); }
|
public void popPush(String newSection)
|
||||||
|
{
|
||||||
|
this.profiler.popPush(newSection);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//================//
|
||||||
|
// helper classes //
|
||||||
|
//================//
|
||||||
|
//region
|
||||||
|
|
||||||
|
public static class ProfileBlock implements IProfileBlock
|
||||||
|
{
|
||||||
|
private final ProfilerFiller profiler;
|
||||||
|
public ProfileBlock(ProfilerFiller newProfiler) { this.profiler = newProfiler; }
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close()
|
||||||
|
{
|
||||||
|
this.profiler.pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//endregion
|
||||||
|
|
||||||
|
|
||||||
/** ends the currently running section */
|
|
||||||
@Override
|
|
||||||
public void pop() { this.profiler.pop(); }
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -48,7 +48,7 @@ import net.minecraft.world.level.chunk.status.ChunkStatus;
|
|||||||
#if MC_VER < MC_1_21_3
|
#if MC_VER < MC_1_21_3
|
||||||
import net.minecraft.world.phys.Vec3;
|
import net.minecraft.world.phys.Vec3;
|
||||||
#else
|
#else
|
||||||
import com.seibel.distanthorizons.core.util.ColorUtil;
|
import com.seibel.distanthorizons.coreapi.util.ColorUtil;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if MC_VER <= MC_1_21_10
|
#if MC_VER <= MC_1_21_10
|
||||||
|
|||||||
+1
-1
Submodule coreSubProjects updated: 71e6b9b58e...53fcce9d7c
+2
-2
@@ -76,12 +76,12 @@ task deleteResources(type: Delete) {
|
|||||||
|
|
||||||
processResources {
|
processResources {
|
||||||
dependsOn(copyCoreResources)
|
dependsOn(copyCoreResources)
|
||||||
dependsOn(copyCommonLoaderResources)
|
// dependsOn(copyCommonLoaderResources)
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.named('runClient') {
|
tasks.named('runClient') {
|
||||||
dependsOn(copyCoreResources)
|
dependsOn(copyCoreResources)
|
||||||
dependsOn(copyCommonLoaderResources)
|
// dependsOn(copyCommonLoaderResources)
|
||||||
finalizedBy(deleteResources)
|
finalizedBy(deleteResources)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -66,6 +66,13 @@ import java.util.concurrent.AbstractExecutorService;
|
|||||||
import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderEvents;
|
import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderEvents;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if MC_VER <= MC_1_21_11
|
||||||
|
#else
|
||||||
|
import net.fabricmc.fabric.api.client.rendering.v1.level.LevelRenderContext;
|
||||||
|
import net.fabricmc.fabric.api.client.rendering.v1.level.LevelRenderEvents;
|
||||||
|
import net.fabricmc.fabric.api.client.rendering.v1.level.LevelTerrainRenderContext;
|
||||||
|
#endif
|
||||||
|
|
||||||
import com.mojang.blaze3d.platform.InputConstants;
|
import com.mojang.blaze3d.platform.InputConstants;
|
||||||
|
|
||||||
import net.minecraft.client.multiplayer.ClientLevel;
|
import net.minecraft.client.multiplayer.ClientLevel;
|
||||||
@@ -91,6 +98,7 @@ public class FabricClientProxy implements AbstractModInitializer.IEventProxy
|
|||||||
private static final MinecraftClientWrapper MC = MinecraftClientWrapper.INSTANCE;
|
private static final MinecraftClientWrapper MC = MinecraftClientWrapper.INSTANCE;
|
||||||
private static final AbstractPluginPacketSender PACKET_SENDER = (AbstractPluginPacketSender) SingletonInjector.INSTANCE.get(IPluginPacketSender.class);
|
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;
|
private static final ClientApi clientApi = ClientApi.INSTANCE;
|
||||||
|
|
||||||
HashSet<Integer> previouslyPressKeyCodes = new HashSet<>();
|
HashSet<Integer> previouslyPressKeyCodes = new HashSet<>();
|
||||||
@@ -108,17 +116,10 @@ public class FabricClientProxy implements AbstractModInitializer.IEventProxy
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
//========================//
|
|
||||||
// register mod accessors //
|
|
||||||
//========================//
|
|
||||||
|
|
||||||
SodiumAccessor sodiumAccessor = (SodiumAccessor) ModAccessorInjector.INSTANCE.get(ISodiumAccessor.class);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//==============//
|
//==============//
|
||||||
// chunk events //
|
// chunk events //
|
||||||
//==============//
|
//==============//
|
||||||
|
//region
|
||||||
|
|
||||||
// ClientChunkLoadEvent
|
// ClientChunkLoadEvent
|
||||||
ClientChunkEvents.CHUNK_LOAD.register((level, chunk) ->
|
ClientChunkEvents.CHUNK_LOAD.register((level, chunk) ->
|
||||||
@@ -214,12 +215,14 @@ public class FabricClientProxy implements AbstractModInitializer.IEventProxy
|
|||||||
return InteractionResult.PASS;
|
return InteractionResult.PASS;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
//endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//==============//
|
//==============//
|
||||||
// render event //
|
// render event //
|
||||||
//==============//
|
//==============//
|
||||||
|
//region
|
||||||
|
|
||||||
#if MC_VER < MC_1_21_9
|
#if MC_VER < MC_1_21_9
|
||||||
WorldRenderEvents.AFTER_SETUP.register((renderContext) ->
|
WorldRenderEvents.AFTER_SETUP.register((renderContext) ->
|
||||||
@@ -298,6 +301,27 @@ public class FabricClientProxy implements AbstractModInitializer.IEventProxy
|
|||||||
});
|
});
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if MC_VER <= MC_1_21_11
|
||||||
|
#else
|
||||||
|
LevelRenderEvents.AFTER_TRANSLUCENT_TERRAIN.register((LevelRenderContext levelRenderContext) ->
|
||||||
|
{
|
||||||
|
ClientApi.INSTANCE.renderFadeTransparent();
|
||||||
|
});
|
||||||
|
|
||||||
|
LevelRenderEvents.AFTER_OPAQUE_TERRAIN.register((LevelTerrainRenderContext levelTerrainRenderContext) ->
|
||||||
|
{
|
||||||
|
ClientApi.INSTANCE.renderFadeOpaque();
|
||||||
|
});
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//=================//
|
||||||
|
// keyboard events //
|
||||||
|
//=================//
|
||||||
|
//region
|
||||||
|
|
||||||
// Debug keyboard event
|
// Debug keyboard event
|
||||||
// FIXME: Use better hooks so it doesn't trigger key press events in text boxes
|
// FIXME: Use better hooks so it doesn't trigger key press events in text boxes
|
||||||
@@ -309,11 +333,14 @@ public class FabricClientProxy implements AbstractModInitializer.IEventProxy
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
//endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//==================//
|
//==================//
|
||||||
// networking event //
|
// networking event //
|
||||||
//==================//
|
//==================//
|
||||||
|
//region
|
||||||
|
|
||||||
#if MC_VER < MC_1_20_6
|
#if MC_VER < MC_1_20_6
|
||||||
ClientPlayNetworking.registerGlobalReceiver(AbstractPluginPacketSender.WRAPPER_PACKET_RESOURCE, (client, handler, buffer, packetSender) ->
|
ClientPlayNetworking.registerGlobalReceiver(AbstractPluginPacketSender.WRAPPER_PACKET_RESOURCE, (client, handler, buffer, packetSender) ->
|
||||||
@@ -345,6 +372,11 @@ public class FabricClientProxy implements AbstractModInitializer.IEventProxy
|
|||||||
ClientApi.INSTANCE.pluginMessageReceived(payload.message());
|
ClientApi.INSTANCE.pluginMessageReceived(payload.message());
|
||||||
});
|
});
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
//endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onKeyInput()
|
public void onKeyInput()
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ import com.seibel.distanthorizons.core.config.Config;
|
|||||||
import com.seibel.distanthorizons.core.dependencyInjection.ModAccessorInjector;
|
import com.seibel.distanthorizons.core.dependencyInjection.ModAccessorInjector;
|
||||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||||
import com.seibel.distanthorizons.core.util.NativeDialogUtil;
|
import com.seibel.distanthorizons.common.wrappers.gui.NativeDialogUtil;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IPluginPacketSender;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IPluginPacketSender;
|
||||||
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.*;
|
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.*;
|
||||||
|
|||||||
+1
-14
@@ -50,8 +50,8 @@ public class MixinChunkSectionsToRender
|
|||||||
//===========//
|
//===========//
|
||||||
// Pre MC 26 //
|
// Pre MC 26 //
|
||||||
//===========//
|
//===========//
|
||||||
//regino
|
|
||||||
#if MC_VER <= MC_1_21_11
|
#if MC_VER <= MC_1_21_11
|
||||||
|
//region
|
||||||
|
|
||||||
#if MC_VER <= MC_1_21_10
|
#if MC_VER <= MC_1_21_10
|
||||||
// needs to fire at HEAD with a lower than normal order (less than 1000)
|
// needs to fire at HEAD with a lower than normal order (less than 1000)
|
||||||
@@ -78,7 +78,6 @@ public class MixinChunkSectionsToRender
|
|||||||
ClientApi.INSTANCE.renderFadeTransparent();
|
ClientApi.INSTANCE.renderFadeTransparent();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//endregion
|
//endregion
|
||||||
#else
|
#else
|
||||||
|
|
||||||
@@ -105,22 +104,10 @@ public class MixinChunkSectionsToRender
|
|||||||
}
|
}
|
||||||
else if (chunkSectionLayerGroup == ChunkSectionLayerGroup.OPAQUE)
|
else if (chunkSectionLayerGroup == ChunkSectionLayerGroup.OPAQUE)
|
||||||
{
|
{
|
||||||
ClientApi.INSTANCE.renderFadeTransparent();
|
|
||||||
ClientApi.INSTANCE.renderLods();
|
ClientApi.INSTANCE.renderLods();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(at = @At("RETURN"), method = "renderGroup", order = 800)
|
|
||||||
private void renderDeferredLayerReturn(ChunkSectionLayerGroup chunkSectionLayerGroup, GpuSampler gpuSampler, CallbackInfo ci)
|
|
||||||
{
|
|
||||||
ClientApi.RENDER_STATE.canRenderOrThrow();
|
|
||||||
|
|
||||||
if (chunkSectionLayerGroup == ChunkSectionLayerGroup.TRANSLUCENT)
|
|
||||||
{
|
|
||||||
ClientApi.INSTANCE.renderFadeOpaque();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//endregion
|
//endregion
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
+77
@@ -0,0 +1,77 @@
|
|||||||
|
/*
|
||||||
|
* 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_21_11
|
||||||
|
import net.minecraft.world.entity.Entity;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
|
||||||
|
@Mixin(Entity.class)
|
||||||
|
public class MixinGameRenderer {}
|
||||||
|
|
||||||
|
#else
|
||||||
|
import com.mojang.blaze3d.vertex.PoseStack;
|
||||||
|
import com.seibel.distanthorizons.common.wrappers.McObjectConverter;
|
||||||
|
import com.seibel.distanthorizons.core.api.internal.ClientApi;
|
||||||
|
import net.minecraft.client.DeltaTracker;
|
||||||
|
import net.minecraft.client.player.LocalPlayer;
|
||||||
|
import net.minecraft.client.renderer.GameRenderer;
|
||||||
|
import net.minecraft.client.renderer.state.OptionsRenderState;
|
||||||
|
import net.minecraft.client.renderer.state.level.CameraRenderState;
|
||||||
|
import net.minecraft.util.profiling.ProfilerFiller;
|
||||||
|
import org.joml.Matrix4f;
|
||||||
|
import org.joml.Matrix4fc;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
||||||
|
|
||||||
|
@Mixin(GameRenderer.class)
|
||||||
|
public class MixinGameRenderer
|
||||||
|
{
|
||||||
|
// get the modified projection matrix right before it's uploaded to the GPU
|
||||||
|
@Inject(
|
||||||
|
method = "renderLevel",
|
||||||
|
at = @At(
|
||||||
|
value = "INVOKE",
|
||||||
|
target = "Lcom/mojang/blaze3d/systems/RenderSystem;setProjectionMatrix(Lcom/mojang/blaze3d/buffers/GpuBufferSlice;Lcom/mojang/blaze3d/ProjectionType;)V",
|
||||||
|
shift = At.Shift.BEFORE
|
||||||
|
),
|
||||||
|
locals = LocalCapture.CAPTURE_FAILHARD
|
||||||
|
)
|
||||||
|
private void renderLevel(
|
||||||
|
final DeltaTracker deltaTracker,
|
||||||
|
final CallbackInfo callback,
|
||||||
|
final float partialTickTime,
|
||||||
|
final float cameraEntityPartialTicks,
|
||||||
|
final LocalPlayer player,
|
||||||
|
final ProfilerFiller profiler,
|
||||||
|
final boolean renderBlockOutline,
|
||||||
|
final OptionsRenderState options,
|
||||||
|
final CameraRenderState camera,
|
||||||
|
final Matrix4fc modelViewMatrix,
|
||||||
|
final Matrix4f projectionMatrix,
|
||||||
|
final PoseStack poseStack)
|
||||||
|
{
|
||||||
|
ClientApi.RENDER_STATE.mcProjectionMatrix = McObjectConverter.Convert(projectionMatrix);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
+3
-24
@@ -50,9 +50,10 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
|||||||
#elif MC_VER <= MC_1_21_11
|
#elif MC_VER <= MC_1_21_11
|
||||||
import com.mojang.blaze3d.buffers.GpuBufferSlice;
|
import com.mojang.blaze3d.buffers.GpuBufferSlice;
|
||||||
import com.mojang.blaze3d.resource.GraphicsResourceAllocator;
|
import com.mojang.blaze3d.resource.GraphicsResourceAllocator;
|
||||||
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftRenderWrapper;
|
import net.minecraft.client.Camera;
|
||||||
import net.minecraft.client.DeltaTracker;
|
import net.minecraft.client.DeltaTracker;
|
||||||
import net.minecraft.client.renderer.chunk.ChunkSectionsToRender;
|
import net.minecraft.client.renderer.chunk.ChunkSectionsToRender;
|
||||||
|
import org.joml.Matrix4f;
|
||||||
import org.joml.Matrix4fc;
|
import org.joml.Matrix4fc;
|
||||||
import org.joml.Vector4f;
|
import org.joml.Vector4f;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
@@ -60,7 +61,6 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
|||||||
#else
|
#else
|
||||||
import com.mojang.blaze3d.buffers.GpuBufferSlice;
|
import com.mojang.blaze3d.buffers.GpuBufferSlice;
|
||||||
import com.mojang.blaze3d.resource.GraphicsResourceAllocator;
|
import com.mojang.blaze3d.resource.GraphicsResourceAllocator;
|
||||||
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftRenderWrapper;
|
|
||||||
import net.minecraft.client.DeltaTracker;
|
import net.minecraft.client.DeltaTracker;
|
||||||
import net.minecraft.client.renderer.chunk.ChunkSectionsToRender;
|
import net.minecraft.client.renderer.chunk.ChunkSectionsToRender;
|
||||||
import org.joml.Matrix4fc;
|
import org.joml.Matrix4fc;
|
||||||
@@ -71,6 +71,7 @@ import net.minecraft.client.renderer.state.level.CameraRenderState;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftRenderWrapper;
|
||||||
import com.seibel.distanthorizons.common.wrappers.McObjectConverter;
|
import com.seibel.distanthorizons.common.wrappers.McObjectConverter;
|
||||||
import com.seibel.distanthorizons.common.wrappers.world.ClientLevelWrapper;
|
import com.seibel.distanthorizons.common.wrappers.world.ClientLevelWrapper;
|
||||||
import com.seibel.distanthorizons.core.api.internal.ClientApi;
|
import com.seibel.distanthorizons.core.api.internal.ClientApi;
|
||||||
@@ -235,33 +236,11 @@ public class MixinLevelRenderer
|
|||||||
CallbackInfo callback)
|
CallbackInfo callback)
|
||||||
{
|
{
|
||||||
ClientApi.RENDER_STATE.mcModelViewMatrix = McObjectConverter.Convert(modelViewMatrix);
|
ClientApi.RENDER_STATE.mcModelViewMatrix = McObjectConverter.Convert(modelViewMatrix);
|
||||||
ClientApi.RENDER_STATE.mcProjectionMatrix = McObjectConverter.Convert(camera.projectionMatrix);
|
|
||||||
|
|
||||||
ClientApi.RENDER_STATE.partialTickTime = MinecraftRenderWrapper.INSTANCE.getPartialTickTime();
|
ClientApi.RENDER_STATE.partialTickTime = MinecraftRenderWrapper.INSTANCE.getPartialTickTime();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(
|
|
||||||
method = "addMainPass(Lcom/mojang/blaze3d/framegraph/FrameGraphBuilder;Lnet/minecraft/client/renderer/culling/Frustum;Lorg/joml/Matrix4fc;Lcom/mojang/blaze3d/buffers/GpuBufferSlice;ZLnet/minecraft/client/renderer/state/level/LevelRenderState;Lnet/minecraft/client/DeltaTracker;Lnet/minecraft/util/profiling/ProfilerFiller;Lnet/minecraft/client/renderer/chunk/ChunkSectionsToRender;)V",
|
|
||||||
at = @At(
|
|
||||||
value = "RETURN",
|
|
||||||
target = "Lcom/mojang/blaze3d/framegraph/FramePass;executes(Ljava/lang/Runnable;)V",
|
|
||||||
remap = false
|
|
||||||
)
|
|
||||||
)
|
|
||||||
public void addMainPass(
|
|
||||||
CallbackInfo ci)
|
|
||||||
{
|
|
||||||
// only crash during development
|
|
||||||
if (ModInfo.IS_DEV_BUILD)
|
|
||||||
{
|
|
||||||
ClientApi.RENDER_STATE.canRenderOrThrow();
|
|
||||||
}
|
|
||||||
|
|
||||||
ClientApi.INSTANCE.renderLods();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
//endregion
|
//endregion
|
||||||
|
|
||||||
|
|||||||
+39
-1
@@ -1,5 +1,16 @@
|
|||||||
package com.seibel.distanthorizons.fabric.mixins.client;
|
package com.seibel.distanthorizons.fabric.mixins.client;
|
||||||
|
|
||||||
|
#if MC_VER <= MC_1_21_10
|
||||||
|
import net.minecraft.world.entity.Entity;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
|
||||||
|
@Mixin(Entity.class)
|
||||||
|
public class MixinSharedConstants
|
||||||
|
{ /* not present in older MC versions */ }
|
||||||
|
#else
|
||||||
|
|
||||||
|
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||||
|
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||||
import com.seibel.distanthorizons.coreapi.ModInfo;
|
import com.seibel.distanthorizons.coreapi.ModInfo;
|
||||||
import net.minecraft.SharedConstants;
|
import net.minecraft.SharedConstants;
|
||||||
import org.spongepowered.asm.mixin.*;
|
import org.spongepowered.asm.mixin.*;
|
||||||
@@ -16,8 +27,35 @@ public abstract class MixinSharedConstants
|
|||||||
@Inject(method = "<clinit>", at = @At("TAIL"))
|
@Inject(method = "<clinit>", at = @At("TAIL"))
|
||||||
private static void setIsRunningInIde(CallbackInfo ci)
|
private static void setIsRunningInIde(CallbackInfo ci)
|
||||||
{
|
{
|
||||||
// run extra validation for dev builds
|
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;
|
||||||
|
#if MC_VER <= MC_1_21_11
|
||||||
IS_RUNNING_IN_IDE = ModInfo.IS_DEV_BUILD;
|
IS_RUNNING_IN_IDE = ModInfo.IS_DEV_BUILD;
|
||||||
|
#else
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Iris has a bug for MC 26 and newer where it doesn't have
|
||||||
|
// a "sampler1" bound, causing a renderer crash if
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
catch (ClassNotFoundException ignore)
|
||||||
|
{
|
||||||
|
irisPresent = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
IS_RUNNING_IN_IDE = ModInfo.IS_DEV_BUILD && !irisPresent;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
logger.info("Setting Minecraft's SharedConstants.IS_RUNNING_IN_IDE to ["+IS_RUNNING_IN_IDE+"]");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
"client.MixinClientPacketListener",
|
"client.MixinClientPacketListener",
|
||||||
"client.MixinDebugScreenOverlay",
|
"client.MixinDebugScreenOverlay",
|
||||||
"client.MixinFogRenderer",
|
"client.MixinFogRenderer",
|
||||||
|
"client.MixinGameRenderer",
|
||||||
"client.MixinLevelRenderer",
|
"client.MixinLevelRenderer",
|
||||||
"client.MixinChunkSectionsToRender",
|
"client.MixinChunkSectionsToRender",
|
||||||
"client.MixinLightTexture",
|
"client.MixinLightTexture",
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
"license": "LGPL-3",
|
"license": "LGPL-3",
|
||||||
"icon": "assets/distanthorizons/icon.png",
|
"icon": "assets/distanthorizons/icon.png",
|
||||||
|
|
||||||
"accessWidener": "distanthorizons.accesswidener",
|
"accessWidener": "${accessWidenerVersion}.distanthorizons.accesswidener",
|
||||||
|
|
||||||
"environment": "*",
|
"environment": "*",
|
||||||
"entrypoints": {
|
"entrypoints": {
|
||||||
|
|||||||
+1
-1
@@ -39,7 +39,7 @@ task deleteResources(type: Delete) {
|
|||||||
|
|
||||||
tasks.register('copyAllResources') {
|
tasks.register('copyAllResources') {
|
||||||
dependsOn(copyCoreResources)
|
dependsOn(copyCoreResources)
|
||||||
dependsOn(copyCommonLoaderResources)
|
// dependsOn(copyCommonLoaderResources)
|
||||||
}
|
}
|
||||||
|
|
||||||
processResources {
|
processResources {
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
{
|
{
|
||||||
"pack": {
|
"pack": {
|
||||||
"pack_format": 7,
|
"pack_format": 64,
|
||||||
"supported_formats": {
|
"supported_formats": {
|
||||||
"min_inclusive": 16,
|
"min_inclusive": 64,
|
||||||
"max_inclusive": 90000
|
"max_inclusive": 90000
|
||||||
},
|
},
|
||||||
"description": "Distant Horizons"
|
"description": "Distant Horizons",
|
||||||
|
"min_format": 64,
|
||||||
|
"max_format": 90000
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-5
@@ -5,7 +5,7 @@ org.gradle.caching=true
|
|||||||
|
|
||||||
# Mod Info
|
# Mod Info
|
||||||
mod_name=DistantHorizons
|
mod_name=DistantHorizons
|
||||||
mod_version=3.0.0-b-dev
|
mod_version=3.0.0-b
|
||||||
api_version=6.0.0
|
api_version=6.0.0
|
||||||
maven_group=com.seibel.distanthorizons
|
maven_group=com.seibel.distanthorizons
|
||||||
mod_readable_name=Distant Horizons
|
mod_readable_name=Distant Horizons
|
||||||
@@ -13,8 +13,8 @@ mod_description=This mod generates and renders simplified terrain beyond the nor
|
|||||||
# Note: In forge's mods.toml this is hard coded because Architectury throws an error with setting it as a variable
|
# Note: In forge's mods.toml this is hard coded because Architectury throws an error with setting it as a variable
|
||||||
mod_authors=["James Seibel", "Leonardo Amato", "Cola", "coolGi", "Ran", "Leetom", "pshsh"]
|
mod_authors=["James Seibel", "Leonardo Amato", "Cola", "coolGi", "Ran", "Leetom", "pshsh"]
|
||||||
mod_homepage=https://modrinth.com/mod/distanthorizons
|
mod_homepage=https://modrinth.com/mod/distanthorizons
|
||||||
mod_source=https://gitlab.com/jeseibel/distant-horizons
|
mod_source=https://gitlab.com/distant-horizons-team/distant-horizons/
|
||||||
mod_issues=https://gitlab.com/jeseibel/distant-horizons/-/issues
|
mod_issues=https://gitlab.com/distant-horizons-team/distant-horizons/-/issues
|
||||||
mod_discord=https://discord.gg/xAB8G4cENx
|
mod_discord=https://discord.gg/xAB8G4cENx
|
||||||
|
|
||||||
# Global Plugin Versions
|
# Global Plugin Versions
|
||||||
@@ -46,7 +46,7 @@ versionStr=
|
|||||||
|
|
||||||
# This defines what MC version Intellij will use for the preprocessor
|
# This defines what MC version Intellij will use for the preprocessor
|
||||||
# and what version is used automatically by build and run commands
|
# and what version is used automatically by build and run commands
|
||||||
mcVer=1.26.1
|
mcVer=26.1.2
|
||||||
|
|
||||||
# Defines the maximum amount of memory Minecraft is allowed when run in a development environment
|
# Defines the maximum amount of memory Minecraft is allowed when run in a development environment
|
||||||
#minecraftMemoryJavaArg="-Xmx4G"
|
minecraftMemoryJavaArg=-Xmx6G
|
||||||
|
|||||||
@@ -29,12 +29,12 @@ task deleteResources(type: Delete) {
|
|||||||
|
|
||||||
processResources {
|
processResources {
|
||||||
dependsOn(copyCoreResources)
|
dependsOn(copyCoreResources)
|
||||||
dependsOn(copyCommonLoaderResources)
|
// dependsOn(copyCommonLoaderResources)
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.named('runClient') {
|
tasks.named('runClient') {
|
||||||
dependsOn(copyCoreResources)
|
dependsOn(copyCoreResources)
|
||||||
dependsOn(copyCommonLoaderResources)
|
// dependsOn(copyCommonLoaderResources)
|
||||||
finalizedBy(deleteResources)
|
finalizedBy(deleteResources)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -228,8 +228,10 @@ public class NeoforgeClientProxy implements AbstractModInitializer.IEventProxy
|
|||||||
{
|
{
|
||||||
#if MC_VER < MC_1_21_9
|
#if MC_VER < MC_1_21_9
|
||||||
ClientApi.RENDER_STATE.clientLevelWrapper = ClientLevelWrapper.getWrapperIfDifferent(ClientApi.RENDER_STATE.clientLevelWrapper, (ClientLevel)event.getLevel());
|
ClientApi.RENDER_STATE.clientLevelWrapper = ClientLevelWrapper.getWrapperIfDifferent(ClientApi.RENDER_STATE.clientLevelWrapper, (ClientLevel)event.getLevel());
|
||||||
#else
|
#elif MC_VER <= MC_1_21_11
|
||||||
ClientApi.RENDER_STATE.clientLevelWrapper = ClientLevelWrapper.getWrapperIfDifferent(ClientApi.RENDER_STATE.clientLevelWrapper, event.getLevelRenderer().level);
|
ClientApi.RENDER_STATE.clientLevelWrapper = ClientLevelWrapper.getWrapperIfDifferent(ClientApi.RENDER_STATE.clientLevelWrapper, event.getLevelRenderer().level);
|
||||||
|
#else
|
||||||
|
// handled via the same mixin as fabric for consistency
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ClientApi.INSTANCE.renderFadeOpaque();
|
ClientApi.INSTANCE.renderFadeOpaque();
|
||||||
@@ -241,11 +243,11 @@ public class NeoforgeClientProxy implements AbstractModInitializer.IEventProxy
|
|||||||
{
|
{
|
||||||
#if MC_VER < MC_1_21_9
|
#if MC_VER < MC_1_21_9
|
||||||
ClientApi.RENDER_STATE.clientLevelWrapper = ClientLevelWrapper.getWrapperIfDifferent(ClientApi.RENDER_STATE.clientLevelWrapper, (ClientLevel)event.getLevel());
|
ClientApi.RENDER_STATE.clientLevelWrapper = ClientLevelWrapper.getWrapperIfDifferent(ClientApi.RENDER_STATE.clientLevelWrapper, (ClientLevel)event.getLevel());
|
||||||
#else
|
#elif MC_VER <= MC_1_21_11
|
||||||
ClientApi.RENDER_STATE.clientLevelWrapper = ClientLevelWrapper.getWrapperIfDifferent(ClientApi.RENDER_STATE.clientLevelWrapper, event.getLevelRenderer().level);
|
ClientApi.RENDER_STATE.clientLevelWrapper = ClientLevelWrapper.getWrapperIfDifferent(ClientApi.RENDER_STATE.clientLevelWrapper, event.getLevelRenderer().level);
|
||||||
|
#else
|
||||||
|
// handled via the same mixin as fabric for consistency
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ClientApi.INSTANCE.renderDeferredLodsForShaders();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
@@ -253,8 +255,10 @@ public class NeoforgeClientProxy implements AbstractModInitializer.IEventProxy
|
|||||||
{
|
{
|
||||||
#if MC_VER < MC_1_21_9
|
#if MC_VER < MC_1_21_9
|
||||||
ClientApi.RENDER_STATE.clientLevelWrapper = ClientLevelWrapper.getWrapperIfDifferent(ClientApi.RENDER_STATE.clientLevelWrapper, (ClientLevel)event.getLevel());
|
ClientApi.RENDER_STATE.clientLevelWrapper = ClientLevelWrapper.getWrapperIfDifferent(ClientApi.RENDER_STATE.clientLevelWrapper, (ClientLevel)event.getLevel());
|
||||||
#else
|
#elif MC_VER <= MC_1_21_11
|
||||||
ClientApi.RENDER_STATE.clientLevelWrapper = ClientLevelWrapper.getWrapperIfDifferent(ClientApi.RENDER_STATE.clientLevelWrapper, event.getLevelRenderer().level);
|
ClientApi.RENDER_STATE.clientLevelWrapper = ClientLevelWrapper.getWrapperIfDifferent(ClientApi.RENDER_STATE.clientLevelWrapper, event.getLevelRenderer().level);
|
||||||
|
#else
|
||||||
|
// handled via the same mixin as fabric for consistency
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+82
@@ -0,0 +1,82 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Distant Horizons mod
|
||||||
|
* licensed under the GNU LGPL v3 License.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2020 James Seibel
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, version 3.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.seibel.distanthorizons.neoforge.mixins.client;
|
||||||
|
|
||||||
|
#if MC_VER <= MC_1_21_11
|
||||||
|
import net.minecraft.world.entity.Entity;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
|
||||||
|
@Mixin(Entity.class)
|
||||||
|
public class MixinChunkSectionsToRender
|
||||||
|
{ /* rendering before was handled via Fabric API events */ }
|
||||||
|
#else
|
||||||
|
|
||||||
|
import com.mojang.blaze3d.textures.GpuSampler;
|
||||||
|
import com.seibel.distanthorizons.common.wrappers.world.ClientLevelWrapper;
|
||||||
|
import com.seibel.distanthorizons.core.api.internal.ClientApi;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.renderer.chunk.ChunkSectionLayerGroup;
|
||||||
|
import net.minecraft.client.renderer.chunk.ChunkSectionsToRender;
|
||||||
|
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(ChunkSectionsToRender.class)
|
||||||
|
public class MixinChunkSectionsToRender
|
||||||
|
{
|
||||||
|
|
||||||
|
//============//
|
||||||
|
// post MC 26 //
|
||||||
|
//============//
|
||||||
|
//region
|
||||||
|
|
||||||
|
#if MC_VER <= MC_1_21_11
|
||||||
|
#else
|
||||||
|
|
||||||
|
// needs to fire at HEAD with a lower than normal order (less than 1000)
|
||||||
|
// otherwise it will be canceled by Sodium
|
||||||
|
@Inject(at = @At("HEAD"), method = "renderGroup", order = 800)
|
||||||
|
private void renderDeferredLayerHead(ChunkSectionLayerGroup chunkSectionLayerGroup, GpuSampler gpuSampler, CallbackInfo ci)
|
||||||
|
{
|
||||||
|
ClientApi.RENDER_STATE.clientLevelWrapper = ClientLevelWrapper.getWrapperIfDifferent(ClientApi.RENDER_STATE.clientLevelWrapper, Minecraft.getInstance().levelRenderer.level);
|
||||||
|
|
||||||
|
|
||||||
|
ClientApi.RENDER_STATE.canRenderOrThrow();
|
||||||
|
|
||||||
|
if (chunkSectionLayerGroup == ChunkSectionLayerGroup.TRANSLUCENT)
|
||||||
|
{
|
||||||
|
ClientApi.INSTANCE.renderDeferredLodsForShaders();
|
||||||
|
}
|
||||||
|
else if (chunkSectionLayerGroup == ChunkSectionLayerGroup.OPAQUE)
|
||||||
|
{
|
||||||
|
ClientApi.INSTANCE.renderLods();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//endregion
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
+77
@@ -0,0 +1,77 @@
|
|||||||
|
/*
|
||||||
|
* 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.neoforge.mixins.client;
|
||||||
|
|
||||||
|
#if MC_VER <= MC_1_21_11
|
||||||
|
import net.minecraft.world.entity.Entity;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
|
||||||
|
@Mixin(Entity.class)
|
||||||
|
public class MixinGameRenderer {}
|
||||||
|
|
||||||
|
#else
|
||||||
|
import com.mojang.blaze3d.vertex.PoseStack;
|
||||||
|
import com.seibel.distanthorizons.common.wrappers.McObjectConverter;
|
||||||
|
import com.seibel.distanthorizons.core.api.internal.ClientApi;
|
||||||
|
import net.minecraft.client.DeltaTracker;
|
||||||
|
import net.minecraft.client.player.LocalPlayer;
|
||||||
|
import net.minecraft.client.renderer.GameRenderer;
|
||||||
|
import net.minecraft.client.renderer.state.OptionsRenderState;
|
||||||
|
import net.minecraft.client.renderer.state.level.CameraRenderState;
|
||||||
|
import net.minecraft.util.profiling.ProfilerFiller;
|
||||||
|
import org.joml.Matrix4f;
|
||||||
|
import org.joml.Matrix4fc;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
||||||
|
|
||||||
|
@Mixin(GameRenderer.class)
|
||||||
|
public class MixinGameRenderer
|
||||||
|
{
|
||||||
|
// get the modified projection matrix right before it's uploaded to the GPU
|
||||||
|
@Inject(
|
||||||
|
method = "renderLevel",
|
||||||
|
at = @At(
|
||||||
|
value = "INVOKE",
|
||||||
|
target = "Lcom/mojang/blaze3d/systems/RenderSystem;setProjectionMatrix(Lcom/mojang/blaze3d/buffers/GpuBufferSlice;Lcom/mojang/blaze3d/ProjectionType;)V",
|
||||||
|
shift = At.Shift.BEFORE
|
||||||
|
),
|
||||||
|
locals = LocalCapture.CAPTURE_FAILHARD
|
||||||
|
)
|
||||||
|
private void renderLevel(
|
||||||
|
final DeltaTracker deltaTracker,
|
||||||
|
final CallbackInfo callback,
|
||||||
|
final float partialTickTime,
|
||||||
|
final float cameraEntityPartialTicks,
|
||||||
|
final LocalPlayer player,
|
||||||
|
final ProfilerFiller profiler,
|
||||||
|
final boolean renderBlockOutline,
|
||||||
|
final OptionsRenderState options,
|
||||||
|
final CameraRenderState camera,
|
||||||
|
final Matrix4fc modelViewMatrix,
|
||||||
|
final Matrix4f projectionMatrix,
|
||||||
|
final PoseStack poseStack)
|
||||||
|
{
|
||||||
|
ClientApi.RENDER_STATE.mcProjectionMatrix = McObjectConverter.Convert(projectionMatrix);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
+20
-30
@@ -26,7 +26,7 @@ import net.minecraft.client.renderer.LevelRenderer;
|
|||||||
import net.minecraft.client.renderer.RenderType;
|
import net.minecraft.client.renderer.RenderType;
|
||||||
import net.neoforged.neoforge.client.event.RenderLevelStageEvent;
|
import net.neoforged.neoforge.client.event.RenderLevelStageEvent;
|
||||||
import org.joml.Matrix4f;
|
import org.joml.Matrix4f;
|
||||||
#else
|
#elif MC_VER <= MC_1_21_11
|
||||||
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftRenderWrapper;
|
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftRenderWrapper;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.renderer.chunk.ChunkSectionsToRender;
|
import net.minecraft.client.renderer.chunk.ChunkSectionsToRender;
|
||||||
@@ -35,6 +35,25 @@ import net.minecraft.client.DeltaTracker;
|
|||||||
import net.minecraft.client.multiplayer.ClientLevel;
|
import net.minecraft.client.multiplayer.ClientLevel;
|
||||||
import net.minecraft.client.renderer.LevelRenderer;
|
import net.minecraft.client.renderer.LevelRenderer;
|
||||||
|
|
||||||
|
import org.joml.Matrix4f;
|
||||||
|
import org.joml.Matrix4fc;
|
||||||
|
import org.joml.Vector4f;
|
||||||
|
|
||||||
|
import com.mojang.blaze3d.buffers.GpuBufferSlice;
|
||||||
|
import com.mojang.blaze3d.resource.GraphicsResourceAllocator;
|
||||||
|
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||||
|
#else
|
||||||
|
import com.mojang.blaze3d.textures.GpuSampler;
|
||||||
|
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftRenderWrapper;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.renderer.chunk.ChunkSectionLayerGroup;
|
||||||
|
import net.minecraft.client.renderer.chunk.ChunkSectionsToRender;
|
||||||
|
import net.minecraft.client.Camera;
|
||||||
|
import net.minecraft.client.DeltaTracker;
|
||||||
|
import net.minecraft.client.multiplayer.ClientLevel;
|
||||||
|
import net.minecraft.client.renderer.LevelRenderer;
|
||||||
|
|
||||||
import net.minecraft.client.renderer.state.level.CameraRenderState;
|
import net.minecraft.client.renderer.state.level.CameraRenderState;
|
||||||
import org.joml.Matrix4f;
|
import org.joml.Matrix4f;
|
||||||
import org.joml.Matrix4fc;
|
import org.joml.Matrix4fc;
|
||||||
@@ -201,40 +220,11 @@ public class MixinLevelRenderer
|
|||||||
CallbackInfo callback)
|
CallbackInfo callback)
|
||||||
{
|
{
|
||||||
ClientApi.RENDER_STATE.mcModelViewMatrix = McObjectConverter.Convert(modelViewMatrix);
|
ClientApi.RENDER_STATE.mcModelViewMatrix = McObjectConverter.Convert(modelViewMatrix);
|
||||||
ClientApi.RENDER_STATE.mcProjectionMatrix = McObjectConverter.Convert(camera.projectionMatrix);
|
|
||||||
|
|
||||||
ClientApi.RENDER_STATE.partialTickTime = MinecraftRenderWrapper.INSTANCE.getPartialTickTime();
|
ClientApi.RENDER_STATE.partialTickTime = MinecraftRenderWrapper.INSTANCE.getPartialTickTime();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(
|
|
||||||
method = "addMainPass(Lcom/mojang/blaze3d/framegraph/FrameGraphBuilder;Lnet/minecraft/client/renderer/culling/Frustum;Lorg/joml/Matrix4fc;Lcom/mojang/blaze3d/buffers/GpuBufferSlice;ZLnet/minecraft/client/renderer/state/level/LevelRenderState;Lnet/minecraft/client/DeltaTracker;Lnet/minecraft/util/profiling/ProfilerFiller;Lnet/minecraft/client/renderer/chunk/ChunkSectionsToRender;)V",
|
|
||||||
at = @At(
|
|
||||||
value = "RETURN",
|
|
||||||
target = "Lcom/mojang/blaze3d/framegraph/FramePass;executes(Ljava/lang/Runnable;)V",
|
|
||||||
remap = false
|
|
||||||
)
|
|
||||||
)
|
|
||||||
public void addMainPass(
|
|
||||||
CallbackInfo ci)
|
|
||||||
{
|
|
||||||
// only crash during development
|
|
||||||
if (ModInfo.IS_DEV_BUILD)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
ClientApi.RENDER_STATE.canRenderOrThrow();
|
|
||||||
}
|
|
||||||
catch (IllegalStateException e)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ClientApi.INSTANCE.renderLods();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
//endregion
|
//endregion
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,8 @@
|
|||||||
"client.MixinClientPacketListener",
|
"client.MixinClientPacketListener",
|
||||||
"client.MixinDebugScreenOverlay",
|
"client.MixinDebugScreenOverlay",
|
||||||
"client.MixinFogRenderer",
|
"client.MixinFogRenderer",
|
||||||
|
"client.MixinChunkSectionsToRender",
|
||||||
|
"client.MixinGameRenderer",
|
||||||
"client.MixinLevelRenderer",
|
"client.MixinLevelRenderer",
|
||||||
"client.MixinLightTexture",
|
"client.MixinLightTexture",
|
||||||
"client.MixinMinecraft",
|
"client.MixinMinecraft",
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
# 1.26.1 version
|
# 26.1.2 version
|
||||||
java_version=25
|
java_version=25
|
||||||
minecraft_version=26.1
|
minecraft_version=26.1
|
||||||
parchment_version=1.21:2024.07.28
|
parchment_version=1.21:2024.07.28
|
||||||
compatible_minecraft_versions=["26.1"]
|
# version range should be used instead of individual versions due to how NeoForge handles version loading
|
||||||
accessWidenerVersion=1_26_1
|
compatible_minecraft_versions=["26.1.0", "26.1.2"]
|
||||||
|
accessWidenerVersion=26_1
|
||||||
builds_for=fabric,neoforge
|
builds_for=fabric,neoforge
|
||||||
# forge is broken due to gradle/build script issues
|
# forge is broken due to gradle/build script issues
|
||||||
|
|
||||||
@@ -11,17 +12,17 @@ builds_for=fabric,neoforge
|
|||||||
netty_version=4.1.97.Final
|
netty_version=4.1.97.Final
|
||||||
|
|
||||||
# LWJGL
|
# LWJGL
|
||||||
lwjgl_version=3.3.3
|
lwjgl_version=3.4.1
|
||||||
|
|
||||||
# Fabric loader
|
# Fabric loader
|
||||||
fabric_loader_version=0.18.5
|
fabric_loader_version=0.18.5
|
||||||
fabric_api_version=0.144.3+26.1
|
fabric_api_version=0.145.4+26.1.2
|
||||||
modmenu_version=18.0.0-alpha.8
|
modmenu_version=18.0.0-alpha.8
|
||||||
starlight_version_fabric=
|
starlight_version_fabric=
|
||||||
phosphor_version_fabric=
|
phosphor_version_fabric=
|
||||||
lithium_version=
|
lithium_version=
|
||||||
sodium_version=mc1.21.11-0.8.7-fabric
|
sodium_version=mc26.1.1-0.8.9-fabric
|
||||||
iris_version=1.10.7+26.1-fabric
|
iris_version=1.10.9+26.1-fabric
|
||||||
bclib_version=
|
bclib_version=
|
||||||
immersive_portals_version=
|
immersive_portals_version=
|
||||||
canvas_version=
|
canvas_version=
|
||||||
@@ -45,7 +46,7 @@ enable_canvas=0
|
|||||||
|
|
||||||
# NeoForge loader
|
# NeoForge loader
|
||||||
forge_version=
|
forge_version=
|
||||||
neoforge_version=1-beta
|
neoforge_version=15-beta
|
||||||
neoforge_version_range=[*,)
|
neoforge_version_range=[*,)
|
||||||
|
|
||||||
# NeoForge mod versions
|
# NeoForge mod versions
|
||||||
Reference in New Issue
Block a user