diff --git a/api/src/main/java/com/seibel/distanthorizons/api/methods/events/abstractEvents/DhApiBeforeBufferRenderEvent.java b/api/src/main/java/com/seibel/distanthorizons/api/methods/events/abstractEvents/DhApiBeforeBufferRenderEvent.java index 4ac2ff470..ce352bf5c 100644 --- a/api/src/main/java/com/seibel/distanthorizons/api/methods/events/abstractEvents/DhApiBeforeBufferRenderEvent.java +++ b/api/src/main/java/com/seibel/distanthorizons/api/methods/events/abstractEvents/DhApiBeforeBufferRenderEvent.java @@ -59,23 +59,25 @@ public abstract class DhApiBeforeBufferRenderEvent implements IDhApiEvent
@@ -33,7 +35,7 @@ import com.seibel.distanthorizons.api.interfaces.util.IDhApiCopyable; * * * @author James Seibel - * @version 2024-6-30 + * @version 2026-05-22 */ public class DhApiMat4f implements IDhApiCopyable { @@ -62,6 +64,7 @@ public class DhApiMat4f implements IDhApiCopyable //==============// // constructors // //==============// + //region public DhApiMat4f() { /* all values are 0 */ } @@ -71,14 +74,17 @@ public class DhApiMat4f implements IDhApiCopyable this.m01 = sourceMatrix.m01; this.m02 = sourceMatrix.m02; this.m03 = sourceMatrix.m03; + this.m10 = sourceMatrix.m10; this.m11 = sourceMatrix.m11; this.m12 = sourceMatrix.m12; this.m13 = sourceMatrix.m13; + this.m20 = sourceMatrix.m20; this.m21 = sourceMatrix.m21; this.m22 = sourceMatrix.m22; this.m23 = sourceMatrix.m23; + this.m30 = sourceMatrix.m30; this.m31 = sourceMatrix.m31; this.m32 = sourceMatrix.m32; @@ -109,12 +115,74 @@ public class DhApiMat4f implements IDhApiCopyable this.m33 = values[15]; } + //endregion //=========// // methods // //=========// + //region + + /** Returns the values of this matrix in row major order (AKA rows then columns) */ + public float[] getValuesAsArray() + { + float[] array = new float[16]; + this.putValuesInArray(array); + return array; + } + + /** + * Returns the values of this matrix in row major order (AKA rows then columns) + * @since API 7.0.0 + */ + public void putValuesInArray(float[] array) + { + array[0] = this.m00; + array[1] = this.m01; + array[2] = this.m02; + array[3] = this.m03; + + array[4] = this.m10; + array[5] = this.m11; + array[6] = this.m12; + array[7] = this.m13; + + array[8] = this.m20; + array[9] = this.m21; + array[10] = this.m22; + array[11] = this.m23; + + array[12] = this.m30; + array[13] = this.m31; + array[14] = this.m32; + array[15] = this.m33; + } + + + /** @since API 7.0.0 */ + public void set(DhApiMat4f mat) + { + this.m00 = mat.m00; + this.m01 = mat.m01; + this.m02 = mat.m02; + this.m03 = mat.m03; + + this.m10 = mat.m10; + this.m11 = mat.m11; + this.m12 = mat.m12; + this.m13 = mat.m13; + + this.m20 = mat.m20; + this.m21 = mat.m21; + this.m22 = mat.m22; + this.m23 = mat.m23; + + this.m30 = mat.m30; + this.m31 = mat.m31; + this.m32 = mat.m32; + this.m33 = mat.m33; + } public void setIdentity() { @@ -279,47 +347,14 @@ public class DhApiMat4f implements IDhApiCopyable this.m33 *= scalar; } - - - - //==================// - // Distant Horizons // - // methods // - //==================// - - private static int getArrayIndex(int xIndex, int zIndex) { return (zIndex * 4) + xIndex; } - - /** Returns the values of this matrix in row major order (AKA rows then columns) */ - public float[] getValuesAsArray() - { - return new float[]{ - this.m00, - this.m01, - this.m02, - this.m03, - - this.m10, - this.m11, - this.m12, - this.m13, - - this.m20, - this.m21, - this.m22, - this.m23, - - this.m30, - this.m31, - this.m32, - this.m33, - }; - } + //endregion //================// // base overrides // //================// + //region @Override public boolean equals(Object obj) @@ -388,4 +423,8 @@ public class DhApiMat4f implements IDhApiCopyable @Override public DhApiMat4f copy() { return new DhApiMat4f(this); } + //endregion + + + } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientApi.java b/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientApi.java index 62b7fdb9b..0c7637c7f 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientApi.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientApi.java @@ -99,6 +99,11 @@ public class ClientApi * Only downside is making sure each variable is populated before rendering. */ public static final DhRenderState RENDER_STATE = new DhRenderState(); + /** + * static variable so we don't have to re-create it each frame, + * reducing GC pressure. + */ + private static final RenderParams RENDER_PARAMS = new RenderParams(); /** * 50ms = 20 FPS @@ -148,8 +153,6 @@ public class ClientApi private Vec3d lastCameraPosForSpeedCheck = new Vec3d(); private long msSinceLastSpeedCheck = 0L; - public static long firstRenderTimeMs = 0; - /** * keeping track of this is necessary to fix * out-of-date LODs from rendering when the shading @@ -570,7 +573,7 @@ public class ClientApi // render prep and actual rendering into different threads/methods // this is annoying since it's possible to start a render with only // partially complete info, but there isn't a better option at the moment - RenderParams renderParams = new RenderParams(renderPass, RENDER_STATE); + RENDER_PARAMS.update(renderPass, RENDER_STATE); //endregion @@ -581,12 +584,7 @@ public class ClientApi //============// //region - if (firstRenderTimeMs == 0) - { - firstRenderTimeMs = System.currentTimeMillis(); - } - - String validationMessage = renderParams.getValidationErrorMessage(firstRenderTimeMs); + String validationMessage = RENDER_PARAMS.getValidationErrorMessage(); if (validationMessage != null) { // store the error message so it can be seen on the F3 screen @@ -632,10 +630,10 @@ public class ClientApi { if (!renderingDeferredLayer) { - boolean renderingCancelled = ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeRenderEvent.class, renderParams); + boolean renderingCancelled = ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeRenderEvent.class, RENDER_PARAMS); if (!renderingCancelled) { - LodRenderer.INSTANCE.render(renderParams, profiler); + LodRenderer.INSTANCE.render(RENDER_PARAMS, profiler); } if (!DhApi.Delayed.renderProxy.getDeferTransparentRendering()) @@ -645,10 +643,10 @@ public class ClientApi } else { - boolean renderingCancelled = ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeDeferredRenderEvent.class, renderParams); + boolean renderingCancelled = ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeDeferredRenderEvent.class, RENDER_PARAMS); if (!renderingCancelled) { - LodRenderer.INSTANCE.renderDeferred(renderParams, profiler); + LodRenderer.INSTANCE.renderDeferred(RENDER_PARAMS, profiler); } @@ -669,11 +667,11 @@ public class ClientApi { // meta renderer needed for render state/texture // for setup on some APIs (IE openGL) - metaRenderer.runRenderPassSetup(renderParams); + metaRenderer.runRenderPassSetup(RENDER_PARAMS); - testRenderer.render(renderParams); + testRenderer.render(RENDER_PARAMS); - metaRenderer.runRenderPassCleanup(renderParams); + metaRenderer.runRenderPassCleanup(RENDER_PARAMS); } else { @@ -730,8 +728,8 @@ public class ClientApi // don't fade when Iris shaders are active, otherwise the rendering can get weird && !DhApiRenderProxy.INSTANCE.getDeferTransparentRendering()) { - RenderParams renderParams = new RenderParams(EDhApiRenderPass.OPAQUE, RENDER_STATE); - fadeRenderer.render(renderParams); + RENDER_PARAMS.update(EDhApiRenderPass.OPAQUE, RENDER_STATE); + fadeRenderer.render(RENDER_PARAMS); } } /** @@ -761,8 +759,8 @@ public class ClientApi && !DhApiRenderProxy.INSTANCE.getDeferTransparentRendering(); if (renderFade) { - RenderParams renderParams = new RenderParams(EDhApiRenderPass.TRANSPARENT, RENDER_STATE); - fadeRenderer.render(renderParams); + RENDER_PARAMS.update(EDhApiRenderPass.TRANSPARENT, RENDER_STATE); + fadeRenderer.render(RENDER_PARAMS); } } } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/RenderBufferHandler.java b/core/src/main/java/com/seibel/distanthorizons/core/render/RenderBufferHandler.java index 92eaaeae8..b85774ced 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/RenderBufferHandler.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/RenderBufferHandler.java @@ -22,6 +22,7 @@ package com.seibel.distanthorizons.core.render; import com.seibel.distanthorizons.api.DhApi; import com.seibel.distanthorizons.api.interfaces.override.rendering.IDhApiCullingFrustum; import com.seibel.distanthorizons.api.interfaces.override.rendering.IDhApiShadowCullingFrustum; +import com.seibel.distanthorizons.api.objects.math.DhApiMat4f; import com.seibel.distanthorizons.core.config.Config; import com.seibel.distanthorizons.core.dataObjects.render.bufferBuilding.LodBufferContainer; import com.seibel.distanthorizons.core.dependencyInjection.ModAccessorInjector; @@ -36,9 +37,11 @@ import com.seibel.distanthorizons.core.render.QuadTree.LodRenderSection; import com.seibel.distanthorizons.core.render.renderer.LodRenderer; import com.seibel.distanthorizons.core.render.renderer.cullingFrustum.DhFrustumBounds; import com.seibel.distanthorizons.core.render.renderer.cullingFrustum.NeverCullFrustum; +import com.seibel.distanthorizons.core.util.LodUtil; import com.seibel.distanthorizons.core.util.objects.SortedArraySet; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IIrisAccessor; +import com.seibel.distanthorizons.coreapi.ModInfo; import com.seibel.distanthorizons.coreapi.interfaces.dependencyInjection.IOverrideInjector; import com.seibel.distanthorizons.core.util.math.Mat4f; import com.seibel.distanthorizons.core.util.math.Vec3d; @@ -58,6 +61,13 @@ public class RenderBufferHandler implements AutoCloseable private static final IIrisAccessor IRIS_ACCESSOR = ModAccessorInjector.INSTANCE.get(IIrisAccessor.class); + // static values for re-use to reduce GC pressure + private static final float[] JOML_TRANSPOSE_ARRAY = new float[16]; + private static final Matrix4f WORLD_VIEW_JOML_MATRIX = new Matrix4f(); + private static final Matrix4f WORLD_VIEW_PROJ_JOML_MATRIX = new Matrix4f(); + private static final Mat4f FRUSTOM_DH_MATRIX = new Mat4f(); + + /** contains all relevant data */ public final LodQuadTree lodQuadTree; @@ -123,6 +133,14 @@ public class RenderBufferHandler implements AutoCloseable */ public void buildRenderList(RenderParams renderParams) { + if (ModInfo.IS_DEV_BUILD) + { + if (!RenderThreadTaskHandler.INSTANCE.isCurrentThread()) + { + LodUtil.assertNotReach("Should only be run on the render thread"); + } + } + // clear the old list so we can start fresh this.loadedNearToFarBuffers.clear(); @@ -156,18 +174,21 @@ public class RenderBufferHandler implements AutoCloseable Vec3d cameraPos = MC_RENDER.getCameraExactPosition(); - Matrix4fc matWorldView = new Matrix4f() - .setTransposed(renderParams.mcModelViewMatrix.getValuesAsArray()) - .translate( - -(float) cameraPos.x, - -(float) cameraPos.y, - -(float) cameraPos.z); + renderParams.mcModelViewMatrix.putValuesInArray(JOML_TRANSPOSE_ARRAY); + WORLD_VIEW_JOML_MATRIX + .setTransposed(JOML_TRANSPOSE_ARRAY) + .translate( + -(float) cameraPos.x, + -(float) cameraPos.y, + -(float) cameraPos.z); - Matrix4fc matWorldViewProjection = new Matrix4f() - .setTransposed(renderParams.dhProjectionMatrix.getValuesAsArray()) - .mul(matWorldView); - - frustum.update(worldMinY, worldMinY + worldHeight, new Mat4f(matWorldViewProjection)); + renderParams.dhProjectionMatrix.putValuesInArray(JOML_TRANSPOSE_ARRAY); + WORLD_VIEW_PROJ_JOML_MATRIX + .setTransposed(JOML_TRANSPOSE_ARRAY) + .mul(WORLD_VIEW_JOML_MATRIX); + + FRUSTOM_DH_MATRIX.set(WORLD_VIEW_PROJ_JOML_MATRIX); + frustum.update(worldMinY, worldMinY + worldHeight, FRUSTOM_DH_MATRIX); } @@ -175,6 +196,7 @@ public class RenderBufferHandler implements AutoCloseable //=========================// // Update the section list // //=========================// + //region if (isShadowPass) { @@ -251,6 +273,9 @@ public class RenderBufferHandler implements AutoCloseable { this.visibleBufferCount = this.loadedNearToFarBuffers.size(); } + + //endregion + } //endregion diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/RenderParams.java b/core/src/main/java/com/seibel/distanthorizons/core/render/RenderParams.java index e9455a32f..e7949dc5f 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/RenderParams.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/RenderParams.java @@ -2,22 +2,19 @@ package com.seibel.distanthorizons.core.render; import com.seibel.distanthorizons.api.enums.rendering.EDhApiRenderPass; import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiRenderParam; +import com.seibel.distanthorizons.api.objects.math.DhApiMat4f; import com.seibel.distanthorizons.core.api.internal.SharedApi; import com.seibel.distanthorizons.core.api.internal.rendering.DhRenderState; import com.seibel.distanthorizons.core.dependencyInjection.ModAccessorInjector; import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; -import com.seibel.distanthorizons.core.jar.EPlatform; import com.seibel.distanthorizons.core.level.IDhClientLevel; import com.seibel.distanthorizons.core.util.RenderUtil; import com.seibel.distanthorizons.core.util.math.Mat4f; import com.seibel.distanthorizons.core.util.math.Vec3d; -import com.seibel.distanthorizons.core.util.threading.PriorityTaskPicker; -import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil; import com.seibel.distanthorizons.core.world.IDhClientWorld; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.misc.ILightMapWrapper; -import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.AbstractOptifineAccessor; import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IOptifineAccessor; import com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass.IDhGenericRenderer; import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper; @@ -34,8 +31,12 @@ public class RenderParams extends DhApiRenderParam private static final IOptifineAccessor OPTIFINE_ACCESSOR = ModAccessorInjector.INSTANCE.get(IOptifineAccessor.class); - private static final long TIME_FOR_MAC_TO_FINISH_COMPILING_IN_MS = 10_000; - private static boolean initialLoadingComplete = false; + /** + * Copy used for API events.
+ * A separate copy is used to prevent API users from accidentally setting values + * that screw up DH's copy of the render parameters. + */ + public final DhApiRenderParam apiCopy = new DhApiRenderParam(); public IDhClientWorld dhClientWorld; @@ -58,36 +59,27 @@ public class RenderParams extends DhApiRenderParam //=============// //region - public RenderParams(EDhApiRenderPass renderPass, DhRenderState renderState) + public void update(EDhApiRenderPass renderPass, DhRenderState renderState) { - this(renderPass, - renderState.partialTickTime, - renderState.mcProjectionMatrix, renderState.mcModelViewMatrix, - renderState.clientLevelWrapper, - renderState.vanillaFogEnabled - ); - } - private RenderParams( - EDhApiRenderPass renderPass, - float newPartialTicks, - Mat4f newMcProjectionMatrix, Mat4f newMcModelViewMatrix, - IClientLevelWrapper clientLevelWrapper, - boolean vanillaFogEnabled - ) - { - super(renderPass, - newPartialTicks, - RenderUtil.getNearClipPlaneInBlocks(), RenderUtil.getFarClipPlaneDistanceInBlocks(), - newMcProjectionMatrix, newMcModelViewMatrix, - RenderUtil.createLodProjectionMatrix(newMcProjectionMatrix), RenderUtil.createLodModelViewMatrix(newMcModelViewMatrix), - clientLevelWrapper.getMinHeight(), - clientLevelWrapper); + RenderUtil.setDhProjectionMatrix(this.dhProjectionMatrix, renderState.mcProjectionMatrix); + this.dhModelViewMatrix.set(renderState.mcModelViewMatrix); // DH and MC MVM matrix are the same + super.update(renderPass, + renderState.partialTickTime, + RenderUtil.getNearClipPlaneInBlocks(), RenderUtil.getFarClipPlaneDistanceInBlocks(), + renderState.mcProjectionMatrix, renderState.mcModelViewMatrix, + this.dhProjectionMatrix, this.dhModelViewMatrix, + renderState.clientLevelWrapper.getMinHeight(), + renderState.clientLevelWrapper); + + + + this.clientLevelWrapper = renderState.clientLevelWrapper; this.dhClientWorld = SharedApi.tryGetDhClientWorld(); if (this.dhClientWorld != null) { - this.dhClientLevel = (IDhClientLevel) this.dhClientWorld.getLevel(clientLevelWrapper); + this.dhClientLevel = (IDhClientLevel) this.dhClientWorld.getLevel(this.clientLevelWrapper); if (this.dhClientLevel != null) { this.renderBufferHandler = this.dhClientLevel.getRenderBufferHandler(); @@ -95,7 +87,6 @@ public class RenderParams extends DhApiRenderParam } } - this.clientLevelWrapper = clientLevelWrapper; this.lightmap = MC_RENDER.getLightmapWrapper(this.clientLevelWrapper); if (MC_CLIENT.playerExists()) @@ -103,8 +94,9 @@ public class RenderParams extends DhApiRenderParam this.exactCameraPosition = MC_RENDER.getCameraExactPosition(); } - this.vanillaFogEnabled = vanillaFogEnabled; + this.vanillaFogEnabled = renderState.vanillaFogEnabled; + this.apiCopy.update(this); } //endregion @@ -120,7 +112,7 @@ public class RenderParams extends DhApiRenderParam * Should be called before rendering is done. * @return a message if LODs shouldn't be rendered, null if the LODs can render */ - public String getValidationErrorMessage(long firstRenderTimeMs) + public String getValidationErrorMessage() { // Note: all strings here should be constants to prevent String allocations @@ -162,12 +154,21 @@ public class RenderParams extends DhApiRenderParam return "No Generic Renderer Present"; } - if (this.dhModelViewMatrix == null - || this.mcModelViewMatrix == null) + if (this.dhModelViewMatrix.equals(Mat4f.IDENTITY) + || this.dhModelViewMatrix.equals(Mat4f.EMPTY)) { - return "No MVM or Proj Matrix Given"; + return "No DH MVM Matrix Given"; } + if (this.mcModelViewMatrix.equals(Mat4f.IDENTITY) + || this.mcModelViewMatrix.equals(Mat4f.EMPTY)) + { + return "No MC MVM Matrix Given"; + } + + // projection matrix not checked since there are some MC versions where + // the MVM and projection matrices are pre-multiplied together + if (OPTIFINE_ACCESSOR != null && MC_RENDER.getTargetFramebuffer() == -1) { diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/FogRenderParamFactory.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/FogRenderParamFactory.java index adbc92a67..2ea31dd89 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/FogRenderParamFactory.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/FogRenderParamFactory.java @@ -21,9 +21,18 @@ public class FogRenderParamFactory { private static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class); + /** cached object to reduce GC pressure */ + private static final DhApiBeforeFogRenderEvent.EventParam EVENT_PARAM = new DhApiBeforeFogRenderEvent.EventParam(); - public static DhApiBeforeFogRenderEvent.EventParam createRenderParam(RenderParams renderParams) + + //=========// + // methods // + //=========// + //region + + /** returns a cached object to reduce GC pressure */ + public static DhApiBeforeFogRenderEvent.EventParam getRenderParam(RenderParams renderParams) { Color fogColor = getFogColor(renderParams.partialTicks); @@ -74,8 +83,8 @@ public class FogRenderParamFactory heightFogDensity ); - DhApiBeforeFogRenderEvent.EventParam fogRenderEventParam = new DhApiBeforeFogRenderEvent.EventParam(renderParams, fogRenderParam); - return fogRenderEventParam; + EVENT_PARAM.update(renderParams, fogRenderParam); + return EVENT_PARAM; } private static Color getFogColor(float partialTicks) @@ -94,6 +103,8 @@ public class FogRenderParamFactory return fogColor; } + //endregion + } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/LodRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/LodRenderer.java index a9c7c6662..6e8e886ec 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/LodRenderer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/LodRenderer.java @@ -21,7 +21,6 @@ package com.seibel.distanthorizons.core.render.renderer; import com.seibel.distanthorizons.api.enums.rendering.EDhApiTransparency; import com.seibel.distanthorizons.api.methods.events.abstractEvents.*; -import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiFogRenderParam; import com.seibel.distanthorizons.core.config.Config; import com.seibel.distanthorizons.core.dataObjects.render.bufferBuilding.LodBufferContainer; import com.seibel.distanthorizons.core.dependencyInjection.ModAccessorInjector; @@ -119,9 +118,9 @@ public class LodRenderer private void renderTerrain(RenderParams renderParams, IProfilerWrapper profiler, boolean runningDeferredPass) { - // validate rendering // - //====================// - //====================// + //===============// + // validate pass // + //===============// //region boolean deferTransparentRendering = DhApiRenderProxy.INSTANCE.getDeferTransparentRendering(); @@ -147,7 +146,7 @@ public class LodRenderer //=================// //region - ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeRenderSetupEvent.class, renderParams); + ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeRenderSetupEvent.class, renderParams.apiCopy); try (IProfilerWrapper.IProfileBlock terrainRender_profile = profiler.push("LOD GL setup")) // starts the new profile block for most DH rendering { @@ -203,7 +202,7 @@ public class LodRenderer renderFog |= renderParams.vanillaFogEnabled; } - DhApiBeforeFogRenderEvent.EventParam fogRenderEventParam = FogRenderParamFactory.createRenderParam(renderParams); + DhApiBeforeFogRenderEvent.EventParam fogRenderEventParam = FogRenderParamFactory.getRenderParam(renderParams); //endregion @@ -216,7 +215,7 @@ public class LodRenderer if (!runningDeferredPass) { // needs to be fired after all the textures have been created/bound - boolean clearTextures = !ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeTextureClearEvent.class, renderParams); + boolean clearTextures = !ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeTextureClearEvent.class, renderParams.apiCopy); if (clearTextures) { this.metaRenderer.clearDhDepthAndColorTextures(renderParams); @@ -318,7 +317,7 @@ public class LodRenderer // Apply to the MC Framebuffer // //=============================// - boolean cancelApplyShader = ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeApplyShaderRenderEvent.class, renderParams); + boolean cancelApplyShader = ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeApplyShaderRenderEvent.class, renderParams.apiCopy); if (!cancelApplyShader) { profiler.popPush("Apply to MC"); @@ -356,7 +355,7 @@ public class LodRenderer //================// profiler.popPush("LOD cleanup"); - ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeRenderCleanupEvent.class, renderParams); + ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeRenderCleanupEvent.class, renderParams.apiCopy); this.metaRenderer.runRenderPassCleanup(renderParams); } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/util/RenderUtil.java b/core/src/main/java/com/seibel/distanthorizons/core/util/RenderUtil.java index d95250500..0cbbc7d6c 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/util/RenderUtil.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/util/RenderUtil.java @@ -34,7 +34,6 @@ import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IIrisAccess import com.seibel.distanthorizons.core.wrapperInterfaces.render.AbstractDhRenderApiDefinition; import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper; import com.seibel.distanthorizons.coreapi.util.MathUtil; -import com.seibel.distanthorizons.core.util.math.Mat4f; /** * This holds miscellaneous helper code @@ -76,7 +75,7 @@ public class RenderUtil * * @param mcProjMat Minecraft's current projection matrix */ - public static Mat4f createLodProjectionMatrix(DhApiMat4f mcProjMat) + public static void setDhProjectionMatrix(DhApiMat4f updateMatrix, DhApiMat4f mcProjMat) { // in James' testing a near clip plane distance of 2 blocks is enough to allow the fragment // culling to take effect instead of seeing the near clip plane. @@ -93,28 +92,32 @@ public class RenderUtil float farClipDist = RenderUtil.getFarClipPlaneDistanceInBlocks(); // Create a copy of the current matrix, so it won't be modified. - Mat4f lodProj = new Mat4f(mcProjMat); + updateMatrix.set(mcProjMat); // Set new far and near clip plane values. if (RENDER_API_DEF.getRenderDepth() == EDhRenderDepth.FORWARD_Z) { - lodProj.setClipPlanes(nearClipDist, farClipDist, false); + setClipPlanes(updateMatrix, nearClipDist, farClipDist, false); } else { - lodProj.setClipPlanes(farClipDist, nearClipDist, true); + setClipPlanes(updateMatrix, farClipDist, nearClipDist, true); } - - return lodProj; } - /** create and return a new projection matrix based on MC's modelView and projection matrices */ - public static Mat4f createLodModelViewMatrix(DhApiMat4f mcModelViewMat) + /** + * Changes the values that store the clipping planes. + * Formula for calculating matrix values is the same that OpenGL uses when making matrices. + * + * @param nearClip New near clipping plane value. + * @param farClip New far clipping plane value. + */ + public static void setClipPlanes(DhApiMat4f matrix, float nearClip, float farClip, boolean zZeroToOne) { - // nothing beyond copying needs to be done to MC's MVM currently, - // this method is just here in case that changes in the future - return new Mat4f(mcModelViewMat); + // formula copied JOML's implementation to match Minecraft + matrix.m22 = (zZeroToOne ? farClip : farClip + nearClip) / (nearClip - farClip); + matrix.m23 = (zZeroToOne ? farClip : farClip + farClip) * nearClip / (nearClip - farClip); } //endregion diff --git a/core/src/main/java/com/seibel/distanthorizons/core/util/math/Mat4f.java b/core/src/main/java/com/seibel/distanthorizons/core/util/math/Mat4f.java index f5be3daa6..2254777b2 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/util/math/Mat4f.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/util/math/Mat4f.java @@ -20,8 +20,6 @@ package com.seibel.distanthorizons.core.util.math; import com.seibel.distanthorizons.api.objects.math.DhApiMat4f; -import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; -import com.seibel.distanthorizons.core.wrapperInterfaces.render.AbstractDhRenderApiDefinition; import org.joml.Matrix4f; import org.joml.Matrix4fc; @@ -36,12 +34,33 @@ import java.nio.FloatBuffer; */ public class Mat4f extends DhApiMat4f { + /** + * A matrix containing all 0's.

+ * + * Should not be modified.
+ * Can be used for comparison testing. + */ + public static final DhApiMat4f EMPTY = new DhApiMat4f(); + /** + * The 4x4 identity matrix.

+ * + * Should not be modified.
+ * Can be used for comparison testing. + */ + public static final DhApiMat4f IDENTITY = new DhApiMat4f(); + static + { + IDENTITY.setIdentity(); + } + + //==============// // constructors // //==============// - public Mat4f() { /* all values are 0 */ } + /** all values are 0 */ + public Mat4f() { } public Mat4f(DhApiMat4f sourceMatrix) { super(sourceMatrix); } @@ -50,56 +69,31 @@ public class Mat4f extends DhApiMat4f /** Expects the values of the input array to be in row major order (AKA rows then columns) */ public Mat4f(float[] values) { super(values); } - public Mat4f(Matrix4fc sourceMatrix) { this(convertJomlMatrixToArray(sourceMatrix)); } - private static float[] convertJomlMatrixToArray(Matrix4fc sourceMatrix) + public Mat4f(Matrix4fc sourceMatrix) { this.set(sourceMatrix); } + + public void set(Matrix4fc sourceMatrix) { - FloatBuffer buffer = FloatBuffer.allocate(16); + // JOML matricies are stored transposed vs DH's matricies + this.m00 = sourceMatrix.m00(); + this.m01 = sourceMatrix.m10(); + this.m02 = sourceMatrix.m20(); + this.m03 = sourceMatrix.m30(); - buffer.put(bufferIndex(0, 0), sourceMatrix.m00()); - buffer.put(bufferIndex(0, 1), sourceMatrix.m01()); - buffer.put(bufferIndex(0, 2), sourceMatrix.m02()); - buffer.put(bufferIndex(0, 3), sourceMatrix.m03()); + this.m10 = sourceMatrix.m01(); + this.m11 = sourceMatrix.m11(); + this.m12 = sourceMatrix.m21(); + this.m13 = sourceMatrix.m31(); - buffer.put(bufferIndex(1, 0), sourceMatrix.m10()); - buffer.put(bufferIndex(1, 1), sourceMatrix.m11()); - buffer.put(bufferIndex(1, 2), sourceMatrix.m12()); - buffer.put(bufferIndex(1, 3), sourceMatrix.m13()); + this.m20 = sourceMatrix.m02(); + this.m21 = sourceMatrix.m12(); + this.m22 = sourceMatrix.m22(); + this.m23 = sourceMatrix.m32(); - buffer.put(bufferIndex(2, 0), sourceMatrix.m20()); - buffer.put(bufferIndex(2, 1), sourceMatrix.m21()); - buffer.put(bufferIndex(2, 2), sourceMatrix.m22()); - buffer.put(bufferIndex(2, 3), sourceMatrix.m23()); - - buffer.put(bufferIndex(3, 0), sourceMatrix.m30()); - buffer.put(bufferIndex(3, 1), sourceMatrix.m31()); - buffer.put(bufferIndex(3, 2), sourceMatrix.m32()); - buffer.put(bufferIndex(3, 3), sourceMatrix.m33()); - - return buffer.array(); + this.m30 = sourceMatrix.m03(); + this.m31 = sourceMatrix.m13(); + this.m32 = sourceMatrix.m23(); + this.m33 = sourceMatrix.m33(); } - private static int bufferIndex(int xIndex, int zIndex) { return (zIndex * 4) + xIndex; } - - - public void store(FloatBuffer floatBuffer) - { - floatBuffer.put(bufferIndex(0, 0), this.m00); - floatBuffer.put(bufferIndex(0, 1), this.m01); - floatBuffer.put(bufferIndex(0, 2), this.m02); - floatBuffer.put(bufferIndex(0, 3), this.m03); - floatBuffer.put(bufferIndex(1, 0), this.m10); - floatBuffer.put(bufferIndex(1, 1), this.m11); - floatBuffer.put(bufferIndex(1, 2), this.m12); - floatBuffer.put(bufferIndex(1, 3), this.m13); - floatBuffer.put(bufferIndex(2, 0), this.m20); - floatBuffer.put(bufferIndex(2, 1), this.m21); - floatBuffer.put(bufferIndex(2, 2), this.m22); - floatBuffer.put(bufferIndex(2, 3), this.m23); - floatBuffer.put(bufferIndex(3, 0), this.m30); - floatBuffer.put(bufferIndex(3, 1), this.m31); - floatBuffer.put(bufferIndex(3, 2), this.m32); - floatBuffer.put(bufferIndex(3, 3), this.m33); - } - public static Matrix4f createJomlMatrix(DhApiMat4f matrix) { @@ -171,26 +165,6 @@ public class Mat4f extends DhApiMat4f // Forge methods // //===============// - public void set(DhApiMat4f mat) - { - this.m00 = mat.m00; - this.m01 = mat.m01; - this.m02 = mat.m02; - this.m03 = mat.m03; - this.m10 = mat.m10; - this.m11 = mat.m11; - this.m12 = mat.m12; - this.m13 = mat.m13; - this.m20 = mat.m20; - this.m21 = mat.m21; - this.m22 = mat.m22; - this.m23 = mat.m23; - this.m30 = mat.m30; - this.m31 = mat.m31; - this.m32 = mat.m32; - this.m33 = mat.m33; - } - public void add(DhApiMat4f other) { m00 += other.m00; @@ -229,20 +203,8 @@ public class Mat4f extends DhApiMat4f this.m23 = z; } - /** - * Changes the values that store the clipping planes. - * Formula for calculating matrix values is the same that OpenGL uses when making matrices. - * - * @param nearClip New near clipping plane value. - * @param farClip New far clipping plane value. - */ - public void setClipPlanes(float nearClip, float farClip, boolean zZeroToOne) - { - //convert to matrix values, formula copied JOML's implementation to match Minecraft - this.m22 = (zZeroToOne ? farClip : farClip + nearClip) / (nearClip - farClip); - this.m23 = (zZeroToOne ? farClip : farClip + farClip) * nearClip / (nearClip - farClip); - } - public Mat4f copy() { return new Mat4f(this); } + + }