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 015146c7d..9ea58800f 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 @@ -24,6 +24,7 @@ import com.seibel.distanthorizons.api.enums.config.EDhApiMcRenderingFadeMode; import com.seibel.distanthorizons.api.enums.rendering.EDhApiRenderPass; import com.seibel.distanthorizons.api.methods.events.abstractEvents.*; import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiRenderParam; +import com.seibel.distanthorizons.core.api.internal.rendering.RenderState; import com.seibel.distanthorizons.core.file.structure.ClientOnlySaveStructure; import com.seibel.distanthorizons.core.network.messages.MessageRegistry; import com.seibel.distanthorizons.core.pos.DhChunkPos; @@ -399,21 +400,27 @@ public class ClientApi //===========// /** Should be called before {@link ClientApi#renderDeferredLodsForShaders} */ - public void renderLods(IClientLevelWrapper levelWrapper, Mat4f mcModelViewMatrix, Mat4f mcProjectionMatrix, float partialTicks) - { this.renderLodLayer(levelWrapper, mcModelViewMatrix, mcProjectionMatrix, partialTicks, false); } + public void renderLods() { this.renderLodLayer(false); } /** * Only necessary when Shaders are in use. * Should be called after {@link ClientApi#renderLods} */ - public void renderDeferredLodsForShaders(IClientLevelWrapper levelWrapper, Mat4f mcModelViewMatrix, Mat4f mcProjectionMatrix, float partialTicks) - { this.renderLodLayer(levelWrapper, mcModelViewMatrix, mcProjectionMatrix, partialTicks, true); } + public void renderDeferredLodsForShaders() { this.renderLodLayer(true); } - - private void renderLodLayer( - IClientLevelWrapper levelWrapper, Mat4f mcModelViewMatrix, Mat4f mcProjectionMatrix, float partialTicks, - boolean renderingDeferredLayer) + private void renderLodLayer(boolean renderingDeferredLayer) { + // A global render state variable is used since MC has split up their + // 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 + IClientLevelWrapper levelWrapper = RENDER_STATE.clientLevelWrapper; + Mat4f mcModelViewMatrix = RENDER_STATE.mcModelViewMatrix; + Mat4f mcProjectionMatrix = RENDER_STATE.mcProjectionMatrix; + float partialTicks = RENDER_STATE.frameTime; + + + // logging // this.sendQueuedChatMessages(); @@ -581,7 +588,7 @@ public class ClientApi } /** should be called after DH and MC finish rendering so we can smooth the transition between the two */ - public void renderFadeOpaque(Mat4f mcModelViewMatrix, Mat4f mcProjectionMatrix, float partialTicks, IClientLevelWrapper level) + public void renderFadeOpaque() { // only fade when DH is rendering if (Config.Client.Advanced.Debugging.rendererMode.get() == EDhApiRendererMode.DEFAULT @@ -590,11 +597,11 @@ public class ClientApi // don't fade when Iris shaders are active, otherwise the rendering can get weird && !DhApiRenderProxy.INSTANCE.getDeferTransparentRendering()) { - FadeRenderer.INSTANCE.render(mcModelViewMatrix, mcProjectionMatrix, partialTicks, level); + FadeRenderer.INSTANCE.render(RENDER_STATE.mcModelViewMatrix, RENDER_STATE.mcProjectionMatrix, RENDER_STATE.frameTime, RENDER_STATE.clientLevelWrapper); } } /** should be called after DH and MC finish rendering so we can smooth the transition between the two */ - public void renderFade(Mat4f mcModelViewMatrix, Mat4f mcProjectionMatrix, float partialTicks, IClientLevelWrapper level) + public void renderFade() { // only fade when DH is rendering if (Config.Client.Advanced.Debugging.rendererMode.get() == EDhApiRendererMode.DEFAULT) @@ -610,7 +617,7 @@ public class ClientApi && !DhApiRenderProxy.INSTANCE.getDeferTransparentRendering(); if (renderFade) { - FadeRenderer.INSTANCE.render(mcModelViewMatrix, mcProjectionMatrix, partialTicks, level); + FadeRenderer.INSTANCE.render(RENDER_STATE.mcModelViewMatrix, RENDER_STATE.mcProjectionMatrix, RENDER_STATE.frameTime, RENDER_STATE.clientLevelWrapper); } } } @@ -784,45 +791,4 @@ public class ClientApi - //================// - // helper classes // - //================// - - public static class RenderState - { - public Mat4f mcModelViewMatrix = null; - public Mat4f mcProjectionMatrix = null; - public float frameTime = -1; - - - public void canRenderOrThrow() throws IllegalStateException - { - String errorReasons = ""; - - if (this.mcModelViewMatrix == null) - { - errorReasons += "no MVM Matrix, "; - } - - if (this.mcProjectionMatrix == null) - { - errorReasons += "no Projection Matrix, "; - } - - if (this.frameTime == -1) - { - errorReasons += "no Frame Time, "; - } - - - if (!errorReasons.isEmpty()) - { - throw new IllegalStateException(errorReasons); - } - - } - } - - - } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/api/internal/rendering/RenderState.java b/core/src/main/java/com/seibel/distanthorizons/core/api/internal/rendering/RenderState.java new file mode 100644 index 000000000..2fcf3612e --- /dev/null +++ b/core/src/main/java/com/seibel/distanthorizons/core/api/internal/rendering/RenderState.java @@ -0,0 +1,72 @@ +package com.seibel.distanthorizons.core.api.internal.rendering; + +import com.seibel.distanthorizons.core.api.internal.ClientApi; +import com.seibel.distanthorizons.core.util.math.Mat4f; +import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper; + +/** + * Used to track the rendering state for the current frame. + * + * @see ClientApi + */ +public class RenderState +{ + public Mat4f mcModelViewMatrix = null; + public Mat4f mcProjectionMatrix = null; + public float frameTime = -1; + public IClientLevelWrapper clientLevelWrapper = null; + + + + //========// + // checks // + //========// + + public String unableToRenderBecause() + { + String errorReasons = ""; + + // the matrix may be the identity matrix or and old/incorrect matrix + // but we did set it at least once before this + if (this.mcModelViewMatrix == null) + { + errorReasons += "no MVM Matrix, "; + } + + if (this.mcProjectionMatrix == null) + { + errorReasons += "no Projection Matrix, "; + } + + if (this.frameTime == -1) + { + errorReasons += "no Frame Time, "; + } + + if (this.clientLevelWrapper == null) + { + errorReasons += "no Level Wrapper, "; + } + + return errorReasons; + } + + public boolean canRender() + { + // separated variable to allow for easy checking with the debugger + String errorReasons = this.unableToRenderBecause(); + return errorReasons.isEmpty(); + } + + public void canRenderOrThrow() throws IllegalStateException + { + String errorReasons = this.unableToRenderBecause(); + if (!errorReasons.isEmpty()) + { + throw new IllegalStateException(errorReasons); + } + } + + + +}