Merge branch 'main' of https://gitlab.com/jeseibel/distant-horizons-core
This commit is contained in:
@@ -58,7 +58,7 @@ public class DhApi
|
||||
*
|
||||
* Note: Don't use this string in your code. It may change and is only for reference.
|
||||
*/
|
||||
public static String READ_ME =
|
||||
public static final String READ_ME =
|
||||
"If you don't see Javadocs something is wrong. \n" +
|
||||
"If you are only using the full DH Mod in your build script, you won't have access to our javadocs and could potentially call into unsafe code. \n" +
|
||||
"\n" +
|
||||
@@ -69,6 +69,12 @@ public class DhApi
|
||||
"and suggested setup. \n" + // DH Dev note: no links were included to prevent link rot.
|
||||
"";
|
||||
public static String readMe() { return READ_ME; }
|
||||
|
||||
/**
|
||||
* This is just a humorous way to reference the {@link DhApi#READ_ME} constant string and hopefully peak a few people's attention
|
||||
* vs the relatively boring "readMe".
|
||||
*/
|
||||
public static final String HEY_YOU_YOURE_FINALLY_AWAKE = READ_ME;
|
||||
/**
|
||||
* This is just a humorous way to reference the {@link DhApi#READ_ME} constant string and hopefully peak a few people's attention
|
||||
* vs the relatively boring "readMe".
|
||||
|
||||
@@ -32,8 +32,15 @@ public enum ELodShading
|
||||
// when adding items up the API minor version
|
||||
// when removing items up the API major version
|
||||
|
||||
/** Uses Minecraft's shading for LODs */
|
||||
MINECRAFT,
|
||||
/**
|
||||
* Simulates Minecraft's shading.
|
||||
* This is most useful for shaders that disable Minecraft's shading
|
||||
* but still require shading on LODs.
|
||||
*/
|
||||
OLD_LIGHTING,
|
||||
/** LODs will have no shading */
|
||||
NONE;
|
||||
|
||||
}
|
||||
|
||||
+7
-2
@@ -44,9 +44,13 @@ public enum EDebugRendering
|
||||
/** LOD colors are based on their detail */
|
||||
SHOW_DETAIL,
|
||||
|
||||
@Deprecated
|
||||
/** LOD colors are based on their gen mode. */
|
||||
SHOW_GENMODE,
|
||||
|
||||
/** Block Materials are often used by Iris shaders to determine how LODs should be rendered */
|
||||
SHOW_BLOCK_MATERIAL,
|
||||
|
||||
/** Only draw overlapping LOD quads. */
|
||||
SHOW_OVERLAPPING_QUADS,
|
||||
|
||||
@@ -61,8 +65,8 @@ public enum EDebugRendering
|
||||
case OFF:
|
||||
return SHOW_DETAIL;
|
||||
case SHOW_DETAIL:
|
||||
return SHOW_GENMODE;
|
||||
case SHOW_GENMODE:
|
||||
return SHOW_BLOCK_MATERIAL;
|
||||
case SHOW_BLOCK_MATERIAL:
|
||||
return SHOW_OVERLAPPING_QUADS;
|
||||
case SHOW_OVERLAPPING_QUADS:
|
||||
return SHOW_RENDER_SOURCE_FLAG;
|
||||
@@ -87,4 +91,5 @@ public enum EDebugRendering
|
||||
return OFF;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
package com.seibel.distanthorizons.api.enums.rendering;
|
||||
|
||||
/**
|
||||
* OPAQUE_AND_TRANSPARENT, <br>
|
||||
* OPAQUE, <br>
|
||||
* TRANSPARENT, <br>
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 2024-1-30
|
||||
* @since API 1.1.0
|
||||
*/
|
||||
public enum EDhApiRenderPass
|
||||
{
|
||||
OPAQUE_AND_TRANSPARENT,
|
||||
OPAQUE,
|
||||
TRANSPARENT,
|
||||
}
|
||||
+20
@@ -112,6 +112,19 @@ public interface IDhApiGraphicsConfig extends IDhApiConfigGroup
|
||||
// advanced graphic settings //
|
||||
//===========================//
|
||||
|
||||
/**
|
||||
* Sets whether LODs outside the view frustum culling will
|
||||
* be culled. <br><br>
|
||||
*
|
||||
* Disabling this will prevent LODs not rendering on the corner
|
||||
* of the users vision and may fix issues if LODs appear to
|
||||
* start/stop rendering incorrectly based on the camera direction,
|
||||
* but will also reduce FPS.
|
||||
*
|
||||
* @since API 1.1.0
|
||||
*/
|
||||
IDhApiConfigValue<Boolean> disableFrustumCulling();
|
||||
|
||||
/**
|
||||
* Sets the distance used by the near clip plane to reduce
|
||||
* overdraw. <br>
|
||||
@@ -167,4 +180,11 @@ public interface IDhApiGraphicsConfig extends IDhApiConfigGroup
|
||||
*/
|
||||
IDhApiConfigValue<Double> lodBias();
|
||||
|
||||
/**
|
||||
* Determines how LODs should be shaded.
|
||||
*
|
||||
* @since API 1.1.0
|
||||
*/
|
||||
IDhApiConfigValue<ELodShading> lodShading();
|
||||
|
||||
}
|
||||
|
||||
+1
-1
@@ -51,7 +51,7 @@ public interface IDhApiEventInjector extends IDependencyInjector<IDhApiEvent>
|
||||
* @param eventParameterObject event parameter
|
||||
* @param <T> the parameter type taken by the event handlers.
|
||||
* @param <U> the {@link IDhApiEvent}'s class
|
||||
* @return if any of bound event handlers returned that this event should be canceled.
|
||||
* @return if any of the bound event handlers notified that this event should be canceled.
|
||||
*/
|
||||
<T, U extends IDhApiEvent<T>> boolean fireAllEvents(Class<U> abstractEvent, T eventParameterObject);
|
||||
|
||||
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* This file is part of the Distant Horizons mod
|
||||
* licensed under the GNU LGPL v3 License.
|
||||
*
|
||||
* Copyright (C) 2020-2023 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.api.interfaces.override.rendering;
|
||||
|
||||
import com.seibel.distanthorizons.api.enums.EDhApiDetailLevel;
|
||||
import com.seibel.distanthorizons.api.interfaces.override.IDhApiOverrideable;
|
||||
import com.seibel.distanthorizons.coreapi.util.math.Mat4f;
|
||||
|
||||
/**
|
||||
* Used to determine if a LOD should be rendered or is outside the
|
||||
* user's field of view.
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 2024-2-6
|
||||
* @since API 1.1.0
|
||||
*/
|
||||
public interface IDhApiCullingFrustum extends IDhApiOverrideable
|
||||
{
|
||||
|
||||
/**
|
||||
* Called before a render pass is done.
|
||||
*
|
||||
* @param worldMinBlockY the lowest block position this level allows.
|
||||
* @param worldMaxBlockY the highest block position this level allows.
|
||||
* @param worldViewProjection the projection matrix used in this render pass.
|
||||
*/
|
||||
void update(int worldMinBlockY, int worldMaxBlockY, Mat4f worldViewProjection);
|
||||
|
||||
/**
|
||||
* returns true if the LOD bounds intersect this frustum
|
||||
*
|
||||
* @param lodBlockPosMinX this LOD's starting block X position closest to negative infinity
|
||||
* @param lodBlockPosMinZ this LOD's starting block Z position closest to negative infinity
|
||||
* @param lodBlockWidth this LOD's width in blocks
|
||||
* @param lodDetailLevel this LOD's detail level
|
||||
*
|
||||
* @see EDhApiDetailLevel
|
||||
*/
|
||||
boolean intersects(int lodBlockPosMinX, int lodBlockPosMinZ, int lodBlockWidth, int lodDetailLevel);
|
||||
|
||||
}
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* This file is part of the Distant Horizons mod
|
||||
* licensed under the GNU LGPL v3 License.
|
||||
*
|
||||
* Copyright (C) 2020-2023 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.api.interfaces.override.rendering;
|
||||
|
||||
import com.seibel.distanthorizons.api.interfaces.override.IDhApiOverrideable;
|
||||
|
||||
/**
|
||||
* @author James Seibel
|
||||
* @version 2024-1-24
|
||||
* @since API 1.1.0
|
||||
*/
|
||||
public interface IDhApiFramebuffer extends IDhApiOverrideable
|
||||
{
|
||||
|
||||
/**
|
||||
* If this method is called that means this program has the highest priority as defined by {@link IDhApiOverrideable#getPriority()}
|
||||
* and gets to decide if it wants to be used to render this frame or not. <br><br>
|
||||
*
|
||||
* If this method returns true then this program will be used for this frame. <br>
|
||||
* If this returns false then the default DH {@link IDhApiShaderProgram} will be used instead.
|
||||
*/
|
||||
boolean overrideThisFrame();
|
||||
|
||||
/** Runs any necessary binding this program needs so rendering can be done. */
|
||||
void bind();
|
||||
|
||||
/** Binds the given OpenGL depth texture ID. */
|
||||
void addDepthAttachment(int textureId, boolean isCombinedStencil);
|
||||
|
||||
/** @return the OpenGL ID for this shader program */
|
||||
int getId();
|
||||
|
||||
/** @return the OpenGL framebuffer status as defined by <code>glCheckFramebufferStatus</code> */
|
||||
int getStatus();
|
||||
|
||||
/** Binds the given OpenGL texture ID to the given texture index relative to OpenGL's <code>GL_COLOR_ATTACHMENT0</code> */
|
||||
void addColorAttachment(int textureIndex, int textureId);
|
||||
|
||||
/** Destroys this framebuffer's OpenGL object(s). */
|
||||
void destroy();
|
||||
|
||||
}
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* This file is part of the Distant Horizons mod
|
||||
* licensed under the GNU LGPL v3 License.
|
||||
*
|
||||
* Copyright (C) 2020-2023 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.api.interfaces.override.rendering;
|
||||
|
||||
import com.seibel.distanthorizons.api.interfaces.override.IDhApiOverrideable;
|
||||
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiRenderParam;
|
||||
import com.seibel.distanthorizons.coreapi.util.math.Mat4f;
|
||||
import com.seibel.distanthorizons.coreapi.util.math.Vec3f;
|
||||
|
||||
/**
|
||||
* @author James Seibel
|
||||
* @version 2024-1-24
|
||||
* @since API 1.1.0
|
||||
*/
|
||||
public interface IDhApiShaderProgram extends IDhApiOverrideable
|
||||
{
|
||||
|
||||
/**
|
||||
* If this method is called that means this program has the highest priority as defined by {@link IDhApiOverrideable#getPriority()}
|
||||
* and gets to decide if it wants to be used to render this frame or not. <br><br>
|
||||
*
|
||||
* If this method returns true then this program will be used for this frame. <br>
|
||||
* If this returns false then the default DH {@link IDhApiShaderProgram} will be used instead.
|
||||
*/
|
||||
boolean overrideThisFrame();
|
||||
|
||||
/** @return the OpenGL ID for this shader program */
|
||||
int getId();
|
||||
|
||||
/** Free any OpenGL objects owned by this program. */
|
||||
void free();
|
||||
|
||||
/** Runs any necessary binding this program needs so rendering can be done. */
|
||||
void bind();
|
||||
/** Runs any necessary unbinding this program needs so rendering can be done by another program. */
|
||||
void unbind();
|
||||
|
||||
|
||||
/** sets up the necessary uniforms for rendering */
|
||||
void fillUniformData(DhApiRenderParam renderParameters);
|
||||
|
||||
/** sets the vec3 that all DH verticies should be offset by when rendering */
|
||||
void setModelOffsetPos(Vec3f modelPos);
|
||||
|
||||
/** Binds the given Vertex Buffer Object to this shader program for rendering. */
|
||||
void bindVertexBuffer(int vbo);
|
||||
|
||||
}
|
||||
+26
-17
@@ -21,6 +21,7 @@ package com.seibel.distanthorizons.api.interfaces.render;
|
||||
|
||||
import com.seibel.distanthorizons.api.objects.DhApiResult;
|
||||
|
||||
|
||||
/**
|
||||
* Used to interact with Distant Horizons' rendering system.
|
||||
*
|
||||
@@ -45,34 +46,42 @@ public interface IDhApiRenderProxy
|
||||
*/
|
||||
DhApiResult<Boolean> clearRenderDataCache();
|
||||
|
||||
/**
|
||||
* Returns the name of Distant Horizons' FrameBuffer. <br>
|
||||
* Will return {@link DhApiResult#success} = false and {@link DhApiResult#payload} = -1 if the FrameBuffer hasn't been created yet.
|
||||
*/
|
||||
DhApiResult<Integer> getDhFrameBufferId();
|
||||
|
||||
/**
|
||||
* Sets the FrameBuffer name that Distant Horizons will draw to after it finishes generating a frame texture. <br>
|
||||
* Setting this to -1 will cause Distant Horizons to use Minecraft's FrameBuffer. <br><br>
|
||||
*
|
||||
* Will return {@link DhApiResult#success} = false given name isn't a valid FrameBuffer.
|
||||
*/
|
||||
DhApiResult<Void> setTargetFrameBufferId(int frameBufferId);
|
||||
/**
|
||||
* Returns the FrameBuffer name that Distant Horizons will draw to after it finishes generating a frame texture. <br>
|
||||
* By default this will be Minecraft's FrameBuffer.
|
||||
*/
|
||||
DhApiResult<Integer> getTargetFrameBufferId();
|
||||
|
||||
//=======================//
|
||||
// OpenGL object getters //
|
||||
//=======================//
|
||||
|
||||
/**
|
||||
* Returns the name of Distant Horizons' depth texture. <br>
|
||||
* Will return {@link DhApiResult#success} = false and {@link DhApiResult#payload} = -1 if the texture hasn't been created yet.
|
||||
*/
|
||||
DhApiResult<Integer> getDhDepthTextureId();
|
||||
|
||||
/**
|
||||
* Returns the name of Distant Horizons' color texture. <br>
|
||||
* Will return {@link DhApiResult#success} = false and {@link DhApiResult#payload} = -1 if the texture hasn't been created yet.
|
||||
*/
|
||||
DhApiResult<Integer> getDhColorTextureId();
|
||||
|
||||
|
||||
|
||||
//======================//
|
||||
// Shader compatibility //
|
||||
//======================//
|
||||
|
||||
/**
|
||||
* If set to true DH won't render opaque and transparent LODs in the same pass.
|
||||
* Instead, opaque objects will be rendered at the normal time, but
|
||||
* transparent objects will only be rendered in a second pass during Minecraft's
|
||||
* own transparent rendering pass.
|
||||
*/
|
||||
void setDeferTransparentRendering(boolean deferTransparentRendering);
|
||||
/** @return If DH should defer transparent rendering or not. */
|
||||
boolean getDeferTransparentRendering();
|
||||
|
||||
/** This may change based on FOV, player speed, and other factors. */
|
||||
float getNearClipPlaneDistanceInBlocks(float partialTicks);
|
||||
|
||||
|
||||
}
|
||||
|
||||
+4
-18
@@ -29,14 +29,14 @@ import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhAp
|
||||
* did to the OpenGL state, so the state should be back to Minecraft's defaults.
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 2023-6-23
|
||||
* @version 2024-1-31
|
||||
* @see DhApiRenderParam
|
||||
* @since API 1.0.0
|
||||
*/
|
||||
public abstract class DhApiAfterRenderEvent implements IDhApiEvent<DhApiAfterRenderEvent.EventParam>
|
||||
public abstract class DhApiAfterRenderEvent implements IDhApiEvent<DhApiRenderParam>
|
||||
{
|
||||
/** Fired after Distant Horizons finishes rendering fake chunks. */
|
||||
public abstract void afterRender(DhApiEventParam<EventParam> input);
|
||||
public abstract void afterRender(DhApiEventParam<DhApiRenderParam> event);
|
||||
|
||||
|
||||
//=========================//
|
||||
@@ -44,20 +44,6 @@ public abstract class DhApiAfterRenderEvent implements IDhApiEvent<DhApiAfterRen
|
||||
//=========================//
|
||||
|
||||
@Override
|
||||
public final void fireEvent(DhApiEventParam<EventParam> input) { this.afterRender(input); }
|
||||
|
||||
|
||||
//==================//
|
||||
// parameter object //
|
||||
//==================//
|
||||
|
||||
public static class EventParam extends DhApiRenderParam
|
||||
{
|
||||
public EventParam(DhApiRenderParam parent)
|
||||
{
|
||||
super(parent.mcProjectionMatrix, parent.mcModelViewMatrix, parent.dhProjectionMatrix, parent.dhModelViewMatrix, parent.partialTicks);
|
||||
}
|
||||
|
||||
}
|
||||
public final void fireEvent(DhApiEventParam<DhApiRenderParam> event) { this.afterRender(event); }
|
||||
|
||||
}
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* This file is part of the Distant Horizons mod
|
||||
* licensed under the GNU LGPL v3 License.
|
||||
*
|
||||
* Copyright (C) 2020-2023 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.api.methods.events.abstractEvents;
|
||||
|
||||
import com.seibel.distanthorizons.api.methods.events.interfaces.IDhApiCancelableEvent;
|
||||
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiCancelableEventParam;
|
||||
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiRenderParam;
|
||||
|
||||
/**
|
||||
* Fired before DH runs its apply shader.
|
||||
* The apply shader is a shader that copies over everything DH has rendered
|
||||
* for this pass into MC's framebuffers so it can be rendered to the screen.
|
||||
* Canceling this event prevents the apply shader from running.
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 2024-1-31
|
||||
* @since API 1.1.0
|
||||
*/
|
||||
public abstract class DhApiBeforeApplyShaderRenderEvent implements IDhApiCancelableEvent<DhApiRenderParam>
|
||||
{
|
||||
/** Fired before the apply shader is run. */
|
||||
public abstract void beforeRender(DhApiCancelableEventParam<DhApiRenderParam> event);
|
||||
|
||||
|
||||
//=========================//
|
||||
// internal DH API methods //
|
||||
//=========================//
|
||||
|
||||
@Override
|
||||
public final void fireEvent(DhApiCancelableEventParam<DhApiRenderParam> event) { this.beforeRender(event); }
|
||||
|
||||
}
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* This file is part of the Distant Horizons mod
|
||||
* licensed under the GNU LGPL v3 License.
|
||||
*
|
||||
* Copyright (C) 2020-2023 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.api.methods.events.abstractEvents;
|
||||
|
||||
import com.seibel.distanthorizons.api.methods.events.interfaces.IDhApiEvent;
|
||||
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiEventParam;
|
||||
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiRenderParam;
|
||||
import com.seibel.distanthorizons.coreapi.util.math.Vec3f;
|
||||
|
||||
/**
|
||||
* Called before Distant Horizons starts rendering a buffer. <br>
|
||||
* This event cannot be cancelled, use {@link DhApiBeforeRenderEvent} if you want to cancel rendering.
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 2023-1-31
|
||||
* @since API 1.1.0
|
||||
*
|
||||
* @see DhApiBeforeRenderEvent
|
||||
*/
|
||||
public abstract class DhApiBeforeBufferRenderEvent implements IDhApiEvent<DhApiBeforeBufferRenderEvent.EventParam>
|
||||
{
|
||||
/** Fired immediately before Distant Horizons starts rendering a buffer. */
|
||||
public abstract void beforeRender(DhApiEventParam<EventParam> input);
|
||||
|
||||
|
||||
//=========================//
|
||||
// internal DH API methods //
|
||||
//=========================//
|
||||
|
||||
@Override
|
||||
public final void fireEvent(DhApiEventParam<EventParam> input) { this.beforeRender(input); }
|
||||
|
||||
|
||||
//==================//
|
||||
// parameter object //
|
||||
//==================//
|
||||
|
||||
public static class EventParam extends DhApiRenderParam
|
||||
{
|
||||
/**
|
||||
* Measured in blocks.
|
||||
* Should be applied to the model view matrix to move the buffer into its proper place.
|
||||
*/
|
||||
public final Vec3f modelPos;
|
||||
|
||||
|
||||
public EventParam(DhApiRenderParam parent, Vec3f modelPos)
|
||||
{
|
||||
super(parent);
|
||||
this.modelPos = modelPos;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* This file is part of the Distant Horizons mod
|
||||
* licensed under the GNU LGPL v3 License.
|
||||
*
|
||||
* Copyright (C) 2020-2023 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.api.methods.events.abstractEvents;
|
||||
|
||||
import com.seibel.distanthorizons.api.interfaces.render.IDhApiRenderProxy;
|
||||
|
||||
/**
|
||||
* Called before Distant Horizons starts rendering the deferred rendering pass. <br>
|
||||
* Will only happen if {@link IDhApiRenderProxy#getDeferTransparentRendering()} is true. <br>
|
||||
* Generally this is only used when shaders are enabled. <br>
|
||||
* Canceling the event will prevent DH from rendering the deferred pass that frame.
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 2024-1-22
|
||||
* @since API 1.1.0
|
||||
*/
|
||||
public abstract class DhApiBeforeDeferredRenderEvent extends DhApiBeforeRenderEvent
|
||||
{
|
||||
|
||||
}
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* This file is part of the Distant Horizons mod
|
||||
* licensed under the GNU LGPL v3 License.
|
||||
*
|
||||
* Copyright (C) 2020-2023 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.api.methods.events.abstractEvents;
|
||||
|
||||
import com.seibel.distanthorizons.api.methods.events.interfaces.IDhApiEvent;
|
||||
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiEventParam;
|
||||
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiRenderParam;
|
||||
|
||||
/**
|
||||
* Called before Distant Horizons starts the cleanup process done after rendering. <br>
|
||||
* This called after every render pass.
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 2024-1-31
|
||||
* @since API 1.1.0
|
||||
*/
|
||||
public abstract class DhApiBeforeRenderCleanupEvent implements IDhApiEvent<DhApiRenderParam>
|
||||
{
|
||||
/** Fired before Distant Horizons renders LODs. */
|
||||
public abstract void beforeCleanup(DhApiEventParam<DhApiRenderParam> event);
|
||||
|
||||
|
||||
//=========================//
|
||||
// internal DH API methods //
|
||||
//=========================//
|
||||
|
||||
@Override
|
||||
public final void fireEvent(DhApiEventParam<DhApiRenderParam> event) { this.beforeCleanup(event); }
|
||||
|
||||
}
|
||||
+3
-17
@@ -31,10 +31,10 @@ import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhAp
|
||||
* @version 2023-6-23
|
||||
* @since API 1.0.0
|
||||
*/
|
||||
public abstract class DhApiBeforeRenderEvent implements IDhApiCancelableEvent<DhApiBeforeRenderEvent.EventParam>
|
||||
public abstract class DhApiBeforeRenderEvent implements IDhApiCancelableEvent<DhApiRenderParam>
|
||||
{
|
||||
/** Fired before Distant Horizons renders LODs. */
|
||||
public abstract void beforeRender(DhApiCancelableEventParam<EventParam> input);
|
||||
public abstract void beforeRender(DhApiCancelableEventParam<DhApiRenderParam> event);
|
||||
|
||||
|
||||
//=========================//
|
||||
@@ -42,20 +42,6 @@ public abstract class DhApiBeforeRenderEvent implements IDhApiCancelableEvent<Dh
|
||||
//=========================//
|
||||
|
||||
@Override
|
||||
public final void fireEvent(DhApiCancelableEventParam<EventParam> input) { this.beforeRender(input); }
|
||||
|
||||
|
||||
//==================//
|
||||
// parameter object //
|
||||
//==================//
|
||||
|
||||
public static class EventParam extends DhApiRenderParam
|
||||
{
|
||||
public EventParam(DhApiRenderParam parent)
|
||||
{
|
||||
super(parent.mcProjectionMatrix, parent.mcModelViewMatrix, parent.dhProjectionMatrix, parent.dhModelViewMatrix, parent.partialTicks);
|
||||
}
|
||||
|
||||
}
|
||||
public final void fireEvent(DhApiCancelableEventParam<DhApiRenderParam> input) { this.beforeRender(input); }
|
||||
|
||||
}
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* This file is part of the Distant Horizons mod
|
||||
* licensed under the GNU LGPL v3 License.
|
||||
*
|
||||
* Copyright (C) 2020-2023 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.api.methods.events.abstractEvents;
|
||||
|
||||
import com.seibel.distanthorizons.api.enums.rendering.EDhApiRenderPass;
|
||||
import com.seibel.distanthorizons.api.methods.events.interfaces.IDhApiEvent;
|
||||
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiEventParam;
|
||||
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiRenderParam;
|
||||
|
||||
/**
|
||||
* Called immediately before Distant Horizons starts a rendering pass. <br>
|
||||
* At this point the GL state will be set up for DH to render. <br>
|
||||
* This event cannot be cancelled, use {@link DhApiBeforeRenderEvent} if you want to cancel rendering.
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 2023-1-31
|
||||
* @since API 1.1.0
|
||||
*
|
||||
* @see DhApiBeforeRenderEvent
|
||||
*/
|
||||
public abstract class DhApiBeforeRenderPassEvent implements IDhApiEvent<DhApiRenderParam>
|
||||
{
|
||||
/**
|
||||
* Fired immediately before Distant Horizons starts a rendering pass. <br>
|
||||
* {@link DhApiRenderParam#renderPass} should either be {@link EDhApiRenderPass#OPAQUE} or {@link EDhApiRenderPass#TRANSPARENT}.
|
||||
*/
|
||||
public abstract void beforeRender(DhApiEventParam<DhApiRenderParam> event);
|
||||
|
||||
|
||||
//=========================//
|
||||
// internal DH API methods //
|
||||
//=========================//
|
||||
|
||||
@Override
|
||||
public final void fireEvent(DhApiEventParam<DhApiRenderParam> event) { this.beforeRender(event); }
|
||||
|
||||
}
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* This file is part of the Distant Horizons mod
|
||||
* licensed under the GNU LGPL v3 License.
|
||||
*
|
||||
* Copyright (C) 2020-2023 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.api.methods.events.abstractEvents;
|
||||
|
||||
import com.seibel.distanthorizons.api.methods.events.interfaces.IDhApiEvent;
|
||||
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiEventParam;
|
||||
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiRenderParam;
|
||||
|
||||
/**
|
||||
* Called before Distant Horizons has started setting up OpenGL objects for rendering. <br>
|
||||
* If you want to modify already bound DH OpenGL objects try using {@link DhApiBeforeRenderPassEvent}.
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 2024-1-31
|
||||
* @since API 1.1.0
|
||||
*
|
||||
* @see DhApiBeforeRenderPassEvent
|
||||
*/
|
||||
public abstract class DhApiBeforeRenderSetupEvent implements IDhApiEvent<DhApiRenderParam>
|
||||
{
|
||||
/** Fired before Distant Horizons has started setting up OpenGL objects for rendering. */
|
||||
public abstract void beforeSetup(DhApiEventParam<DhApiRenderParam> input);
|
||||
|
||||
|
||||
//=========================//
|
||||
// internal DH API methods //
|
||||
//=========================//
|
||||
|
||||
@Override
|
||||
public final void fireEvent(DhApiEventParam<DhApiRenderParam> input) { this.beforeSetup(input); }
|
||||
|
||||
|
||||
}
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* This file is part of the Distant Horizons mod
|
||||
* licensed under the GNU LGPL v3 License.
|
||||
*
|
||||
* Copyright (C) 2020-2023 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.api.methods.events.abstractEvents;
|
||||
|
||||
import com.seibel.distanthorizons.api.methods.events.interfaces.IDhApiCancelableEvent;
|
||||
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiCancelableEventParam;
|
||||
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiRenderParam;
|
||||
|
||||
/**
|
||||
* Called during Distant Horizons rendering setup and immediately <br>
|
||||
* before the render textures are cleared. <br>
|
||||
* Generally the textures cleared are Distant Horizons owned depth and color textures. <br>
|
||||
* Canceling the event will prevent DH from clearing any textures.
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 2024-1-31
|
||||
* @since API 1.1.0
|
||||
*/
|
||||
public abstract class DhApiBeforeTextureClearEvent implements IDhApiCancelableEvent<DhApiRenderParam>
|
||||
{
|
||||
/** Fired before Distant Horizons clears any textures. */
|
||||
public abstract void beforeClear(DhApiCancelableEventParam<DhApiRenderParam> event);
|
||||
|
||||
|
||||
//=========================//
|
||||
// internal DH API methods //
|
||||
//=========================//
|
||||
|
||||
@Override
|
||||
public final void fireEvent(DhApiCancelableEventParam<DhApiRenderParam> input) { this.beforeClear(input); }
|
||||
|
||||
}
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* This file is part of the Distant Horizons mod
|
||||
* licensed under the GNU LGPL v3 License.
|
||||
*
|
||||
* Copyright (C) 2020-2023 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.api.methods.events.abstractEvents;
|
||||
|
||||
import com.seibel.distanthorizons.api.methods.events.interfaces.IDhApiEvent;
|
||||
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiEventParam;
|
||||
|
||||
/**
|
||||
* Called before Distant Horizons starts rendering a buffer. <br>
|
||||
* This event cannot be cancelled, use {@link DhApiBeforeRenderEvent} if you want to cancel rendering.
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 2023-1-23
|
||||
* @since API 1.1.0
|
||||
*/
|
||||
public abstract class DhApiScreenResizeEvent implements IDhApiEvent<DhApiScreenResizeEvent.EventParam>
|
||||
{
|
||||
/** Fired immediately before Distant Horizons renders any transparent buffers. */
|
||||
public abstract void onResize(DhApiEventParam<EventParam> event);
|
||||
|
||||
|
||||
//=========================//
|
||||
// internal DH API methods //
|
||||
//=========================//
|
||||
|
||||
@Override
|
||||
public final void fireEvent(DhApiEventParam<EventParam> event) { this.onResize(event); }
|
||||
|
||||
|
||||
//==================//
|
||||
// parameter object //
|
||||
//==================//
|
||||
|
||||
public static class EventParam
|
||||
{
|
||||
/** Measured in pixels */
|
||||
public final int previousWidth;
|
||||
/** Measured in pixels */
|
||||
public final int previousHeight;
|
||||
|
||||
/** Measured in pixels */
|
||||
public final int newWidth;
|
||||
/** Measured in pixels */
|
||||
public final int newHeight;
|
||||
|
||||
|
||||
public EventParam(
|
||||
int previousWidth, int previousHeight,
|
||||
int newWidth, int newHeight)
|
||||
{
|
||||
this.previousWidth = previousWidth;
|
||||
this.previousHeight = previousHeight;
|
||||
|
||||
this.newWidth = newWidth;
|
||||
this.newHeight = newHeight;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+53
-5
@@ -19,17 +19,35 @@
|
||||
|
||||
package com.seibel.distanthorizons.api.methods.events.sharedParameterObjects;
|
||||
|
||||
import com.seibel.distanthorizons.api.enums.rendering.EDhApiRenderPass;
|
||||
import com.seibel.distanthorizons.coreapi.util.math.Mat4f;
|
||||
|
||||
/**
|
||||
* Contains information relevant to Distant Horizons and Minecraft rendering.
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 2022-9-5
|
||||
* @version 2024-1-31
|
||||
* @since API 1.0.0
|
||||
*/
|
||||
public class DhApiRenderParam
|
||||
{
|
||||
/** Indicates what render pass DH is currently rendering */
|
||||
public final EDhApiRenderPass renderPass;
|
||||
|
||||
/** Indicates how far into this tick the frame is. */
|
||||
public final float partialTicks;
|
||||
|
||||
/**
|
||||
* Indicates DH's near clip plane, measured in blocks.
|
||||
* Note: this may change based on time, player speed, and other factors.
|
||||
*/
|
||||
public final float nearClipPlane;
|
||||
/**
|
||||
* Indicates DH's far clip plane, measured in blocks.
|
||||
* Note: this may change based on time, player speed, and other factors.
|
||||
*/
|
||||
public final float farClipPlane;
|
||||
|
||||
/** The projection matrix Minecraft is using to render this frame. */
|
||||
public final Mat4f mcProjectionMatrix;
|
||||
/** The model view matrix Minecraft is using to render this frame. */
|
||||
@@ -40,23 +58,53 @@ public class DhApiRenderParam
|
||||
/** The model view matrix Distant Horizons is using to render this frame. */
|
||||
public final Mat4f dhModelViewMatrix;
|
||||
|
||||
/** Indicates how far into this tick the frame is. */
|
||||
public final float partialTicks;
|
||||
public final int lightmapBindingIndex = 0;
|
||||
|
||||
// TODO why is this here? wouldn't it make more sense to have this built into the vertex buffer data?
|
||||
public final int worldYOffset;
|
||||
|
||||
|
||||
|
||||
//==============//
|
||||
// constructors //
|
||||
//==============//
|
||||
|
||||
public DhApiRenderParam(DhApiRenderParam parent)
|
||||
{
|
||||
this(
|
||||
parent.renderPass,
|
||||
parent.partialTicks,
|
||||
parent.nearClipPlane, parent.farClipPlane,
|
||||
parent.mcProjectionMatrix, parent.mcModelViewMatrix,
|
||||
parent.dhProjectionMatrix, parent.dhModelViewMatrix,
|
||||
parent.worldYOffset
|
||||
);
|
||||
}
|
||||
|
||||
public DhApiRenderParam(
|
||||
EDhApiRenderPass renderPass,
|
||||
float newPartialTicks,
|
||||
float nearClipPlane, float farClipPlane,
|
||||
Mat4f newMcProjectionMatrix, Mat4f newMcModelViewMatrix,
|
||||
Mat4f newDhProjectionMatrix, Mat4f newDhModelViewMatrix,
|
||||
float newPartialTicks)
|
||||
int worldYOffset
|
||||
)
|
||||
{
|
||||
this.renderPass = renderPass;
|
||||
|
||||
this.partialTicks = newPartialTicks;
|
||||
|
||||
this.farClipPlane = farClipPlane;
|
||||
this.nearClipPlane = nearClipPlane;
|
||||
|
||||
this.mcProjectionMatrix = newMcProjectionMatrix;
|
||||
this.mcModelViewMatrix = newMcModelViewMatrix;
|
||||
|
||||
this.dhProjectionMatrix = newDhProjectionMatrix;
|
||||
this.dhModelViewMatrix = newDhModelViewMatrix;
|
||||
|
||||
this.partialTicks = newPartialTicks;
|
||||
this.worldYOffset = worldYOffset;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+29
-5
@@ -30,7 +30,7 @@ import java.util.HashMap;
|
||||
* This is done so other mods can override our methods to improve features down the line.
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 2022-9-8
|
||||
* @version 2024-1-30
|
||||
*/
|
||||
public class OverrideInjector implements IOverrideInjector<IDhApiOverrideable>
|
||||
{
|
||||
@@ -38,7 +38,6 @@ public class OverrideInjector implements IOverrideInjector<IDhApiOverrideable>
|
||||
|
||||
private final HashMap<Class<? extends IDhApiOverrideable>, OverridePriorityListContainer> overrideContainerByInterface = new HashMap<>();
|
||||
|
||||
|
||||
/**
|
||||
* This is used to determine if an override is part of Distant Horizons'
|
||||
* Core or not.
|
||||
@@ -48,6 +47,10 @@ public class OverrideInjector implements IOverrideInjector<IDhApiOverrideable>
|
||||
|
||||
|
||||
|
||||
//==============//
|
||||
// constructors //
|
||||
//==============//
|
||||
|
||||
public OverrideInjector()
|
||||
{
|
||||
String thisPackageName = this.getClass().getPackage().getName();
|
||||
@@ -60,6 +63,10 @@ public class OverrideInjector implements IOverrideInjector<IDhApiOverrideable>
|
||||
|
||||
|
||||
|
||||
//=========//
|
||||
// binding //
|
||||
//=========//
|
||||
|
||||
@Override
|
||||
public void bind(Class<? extends IDhApiOverrideable> dependencyInterface, IDhApiOverrideable dependencyImplementation) throws IllegalStateException, IllegalArgumentException
|
||||
{
|
||||
@@ -103,6 +110,22 @@ public class OverrideInjector implements IOverrideInjector<IDhApiOverrideable>
|
||||
overrideContainer.addOverride(dependencyImplementation);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unbind(Class<? extends IDhApiOverrideable> dependencyInterface, IDhApiOverrideable dependencyImplementation)
|
||||
{
|
||||
OverridePriorityListContainer overrideContainer = this.overrideContainerByInterface.get(dependencyInterface);
|
||||
if (overrideContainer != null)
|
||||
{
|
||||
overrideContainer.removeOverride(dependencyImplementation);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//=========//
|
||||
// getters //
|
||||
//=========//
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T extends IDhApiOverrideable> T get(Class<T> interfaceClass) throws ClassCastException
|
||||
@@ -121,12 +144,13 @@ public class OverrideInjector implements IOverrideInjector<IDhApiOverrideable>
|
||||
|
||||
|
||||
|
||||
//==========//
|
||||
// clearing //
|
||||
//==========//
|
||||
|
||||
@Override
|
||||
public void clear() { this.overrideContainerByInterface.clear(); }
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
+3
-12
@@ -42,23 +42,14 @@ public class OverridePriorityListContainer implements IBindable
|
||||
OverridePriorityPair priorityPair = new OverridePriorityPair(override, override.getPriority());
|
||||
this.overridePairList.add(priorityPair);
|
||||
|
||||
sortList();
|
||||
this.sortList();
|
||||
}
|
||||
|
||||
/** @return true if the override was removed from the list, false otherwise. */
|
||||
public boolean removeOverride(IDhApiOverrideable override)
|
||||
{
|
||||
if (this.overridePairList.contains(override))
|
||||
{
|
||||
this.overridePairList.remove(override);
|
||||
sortList();
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
boolean overrideRemoved = this.overridePairList.removeIf((pair) -> pair.override.equals(override));
|
||||
return overrideRemoved;
|
||||
}
|
||||
|
||||
|
||||
|
||||
+1
-1
@@ -83,7 +83,7 @@ public interface IDependencyInjector<BindableType extends IBindable>
|
||||
|
||||
|
||||
/** Removes all bound dependencies. */
|
||||
public void clear();
|
||||
void clear();
|
||||
|
||||
|
||||
|
||||
|
||||
+7
-5
@@ -28,21 +28,22 @@ public interface IOverrideInjector<BindableType extends IBindable>
|
||||
* All core overrides should have this priority. <Br>
|
||||
* Should be lower than {@link IOverrideInjector#MIN_NON_CORE_OVERRIDE_PRIORITY}.
|
||||
*/
|
||||
public static final int CORE_PRIORITY = -1;
|
||||
int CORE_PRIORITY = -1;
|
||||
/**
|
||||
* The lowest priority non-core overrides can have.
|
||||
* Should be higher than {@link IOverrideInjector#CORE_PRIORITY}.
|
||||
*/
|
||||
public static final int MIN_NON_CORE_OVERRIDE_PRIORITY = 0;
|
||||
int MIN_NON_CORE_OVERRIDE_PRIORITY = 0;
|
||||
/** The priority given to overrides that don't explicitly define a priority. */
|
||||
public static final int DEFAULT_NON_CORE_OVERRIDE_PRIORITY = 10;
|
||||
int DEFAULT_NON_CORE_OVERRIDE_PRIORITY = 10;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* See {@link IDependencyInjector#bind(Class, IBindable) bind(Class, IBindable)} for full documentation.
|
||||
*
|
||||
* @throws IllegalArgumentException if a non-Distant Horizons Override with the priority CORE is passed in or a invalid priority value.
|
||||
* @throws IllegalArgumentException if a non-Distant Horizons Override with the priority {@link IOverrideInjector#CORE_PRIORITY} is passed in
|
||||
* or an override is passed in with an invalid priority value.
|
||||
* @throws IllegalStateException if another override with the given priority already has been bound.
|
||||
* @see IDependencyInjector#bind(Class, IBindable)
|
||||
*/
|
||||
@@ -66,7 +67,8 @@ public interface IOverrideInjector<BindableType extends IBindable>
|
||||
*/
|
||||
<T extends IDhApiOverrideable> T get(Class<T> interfaceClass, int priority) throws ClassCastException;
|
||||
|
||||
|
||||
/** Removes the given concrete {@link IDhApiOverrideable} bound to the given interface. */
|
||||
void unbind(Class<? extends IDhApiOverrideable> dependencyInterface, IDhApiOverrideable dependencyImplementation);
|
||||
|
||||
/** Removes all bound overrides. */
|
||||
void clear();
|
||||
|
||||
@@ -19,6 +19,9 @@
|
||||
|
||||
package com.seibel.distanthorizons.coreapi.util.math;
|
||||
|
||||
import org.joml.Matrix4f;
|
||||
import org.joml.Matrix4fc;
|
||||
|
||||
import java.nio.FloatBuffer;
|
||||
|
||||
/**
|
||||
@@ -73,6 +76,31 @@ public class Mat4f
|
||||
this.m33 = sourceMatrix.m33;
|
||||
}
|
||||
|
||||
public Mat4f(Matrix4fc sourceMatrix) { this(convertJomlMatrixToArray(sourceMatrix)); }
|
||||
private static float[] convertJomlMatrixToArray(Matrix4fc sourceMatrix)
|
||||
{
|
||||
FloatBuffer buffer = FloatBuffer.allocate(16);
|
||||
|
||||
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());
|
||||
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());
|
||||
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();
|
||||
}
|
||||
|
||||
/* Quaternions are not currently needed/implemented
|
||||
public Matrix4float(Quaternion p_i48104_1_)
|
||||
{
|
||||
@@ -189,6 +217,17 @@ public class Mat4f
|
||||
floatBuffer.put(bufferIndex(3, 3), this.m33);
|
||||
}
|
||||
|
||||
public Matrix4f createJomlMatrix()
|
||||
{
|
||||
return new Matrix4f(
|
||||
this.m00, this.m10, this.m20, this.m30,
|
||||
this.m01, this.m11, this.m21, this.m31,
|
||||
this.m02, this.m12, this.m22, this.m32,
|
||||
this.m03, this.m13, this.m23, this.m33
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
private static int bufferIndex(int xIndex, int zIndex)
|
||||
{
|
||||
return (zIndex * 4) + xIndex;
|
||||
|
||||
+7
-3
@@ -105,9 +105,9 @@ public class DhApiGraphicsConfig implements IDhApiGraphicsConfig
|
||||
// advanced graphic settings //
|
||||
//===========================//
|
||||
|
||||
// @Override
|
||||
// public IDhApiConfigValue<Boolean> getDisableDirectionalCulling()
|
||||
// { return new DhApiConfigValue<Boolean, Boolean>(AdvancedGraphics.disableDirectionalCulling); }
|
||||
@Override
|
||||
public IDhApiConfigValue<Boolean> disableFrustumCulling()
|
||||
{ return new DhApiConfigValue<Boolean, Boolean>(Config.Client.Advanced.Graphics.AdvancedGraphics.disableFrustumCulling); }
|
||||
|
||||
@Deprecated
|
||||
@Override
|
||||
@@ -146,6 +146,10 @@ public class DhApiGraphicsConfig implements IDhApiGraphicsConfig
|
||||
public IDhApiConfigValue<Double> lodBias()
|
||||
{ return new DhApiConfigValue<Double, Double>(Config.Client.Advanced.Graphics.AdvancedGraphics.lodBias); }
|
||||
|
||||
@Override
|
||||
public IDhApiConfigValue<ELodShading> lodShading()
|
||||
{ return new DhApiConfigValue<ELodShading, ELodShading>(Config.Client.Advanced.Graphics.AdvancedGraphics.lodShading); }
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -19,21 +19,25 @@
|
||||
|
||||
package com.seibel.distanthorizons.core.api.internal;
|
||||
|
||||
import com.seibel.distanthorizons.api.DhApi;
|
||||
import com.seibel.distanthorizons.api.enums.rendering.EDhApiRenderPass;
|
||||
import com.seibel.distanthorizons.api.interfaces.override.rendering.IDhApiFramebuffer;
|
||||
import com.seibel.distanthorizons.api.methods.events.abstractEvents.*;
|
||||
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiRenderParam;
|
||||
import com.seibel.distanthorizons.core.level.IKeyedClientLevelManager;
|
||||
import com.seibel.distanthorizons.core.level.IServerKeyedClientLevel;
|
||||
import com.seibel.distanthorizons.core.pos.DhChunkPos;
|
||||
import com.seibel.distanthorizons.core.render.DhApiRenderProxy;
|
||||
import com.seibel.distanthorizons.core.util.objects.Pair;
|
||||
import com.seibel.distanthorizons.core.world.*;
|
||||
import com.seibel.distanthorizons.coreapi.DependencyInjection.ApiEventInjector;
|
||||
import com.seibel.distanthorizons.core.level.IDhClientLevel;
|
||||
import com.seibel.distanthorizons.core.config.Config;
|
||||
import com.seibel.distanthorizons.coreapi.DependencyInjection.OverrideInjector;
|
||||
import com.seibel.distanthorizons.coreapi.ModInfo;
|
||||
import com.seibel.distanthorizons.api.enums.rendering.EDebugRendering;
|
||||
import com.seibel.distanthorizons.api.enums.rendering.ERendererMode;
|
||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||
import com.seibel.distanthorizons.core.level.IDhLevel;
|
||||
import com.seibel.distanthorizons.core.logging.ConfigBasedLogger;
|
||||
import com.seibel.distanthorizons.core.logging.ConfigBasedSpamLogger;
|
||||
import com.seibel.distanthorizons.core.logging.SpamReducedLogger;
|
||||
@@ -51,9 +55,8 @@ import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
import org.lwjgl.opengl.GL32;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@@ -93,6 +96,9 @@ public class ClientApi
|
||||
/** Holds any chunks that were loaded before the {@link ClientApi#clientLevelLoadEvent(IClientLevelWrapper)} was fired. */
|
||||
public final HashMap<Pair<IClientLevelWrapper, DhChunkPos>, IChunkWrapper> waitingChunkByClientLevelAndPos = new HashMap<>();
|
||||
|
||||
/** re-set every frame during the opaque rendering stage */
|
||||
private boolean renderingCancelledForThisFrame;
|
||||
|
||||
|
||||
|
||||
//==============//
|
||||
@@ -451,21 +457,72 @@ public class ClientApi
|
||||
// rendering //
|
||||
//===========//
|
||||
|
||||
/** Should be called before {@link ClientApi#renderDeferredLods} */
|
||||
public void renderLods(IClientLevelWrapper levelWrapper, Mat4f mcModelViewMatrix, Mat4f mcProjectionMatrix, float partialTicks)
|
||||
{ this.renderLodLayer(levelWrapper, mcModelViewMatrix, mcProjectionMatrix, partialTicks, false); }
|
||||
|
||||
/**
|
||||
* Only necessary when Shaders are in use.
|
||||
* Should be called after {@link ClientApi#renderLods}
|
||||
*/
|
||||
public void renderDeferredLods(IClientLevelWrapper levelWrapper, Mat4f mcModelViewMatrix, Mat4f mcProjectionMatrix, float partialTicks)
|
||||
{ this.renderLodLayer(levelWrapper, mcModelViewMatrix, mcProjectionMatrix, partialTicks, true); }
|
||||
|
||||
private void renderLodLayer(
|
||||
IClientLevelWrapper levelWrapper, Mat4f mcModelViewMatrix, Mat4f mcProjectionMatrix, float partialTicks,
|
||||
boolean renderingDeferredLayer)
|
||||
{
|
||||
// logging //
|
||||
|
||||
if (ModInfo.IS_DEV_BUILD && !this.configOverrideReminderPrinted && MC.playerExists())
|
||||
{
|
||||
this.configOverrideReminderPrinted = true;
|
||||
|
||||
// remind the user that this is a development build
|
||||
MC.sendChatMessage(ModInfo.READABLE_NAME + " experimental build " + ModInfo.VERSION);
|
||||
MC.sendChatMessage("You are running an unsupported version of Distant Horizons!");
|
||||
MC.sendChatMessage("Here be dragons!");
|
||||
this.configOverrideReminderPrinted = true;
|
||||
}
|
||||
|
||||
|
||||
IProfilerWrapper profiler = MC.getProfiler();
|
||||
profiler.pop(); // get out of "terrain"
|
||||
profiler.push("DH-RenderLevel");
|
||||
|
||||
|
||||
|
||||
// render parameter setup //
|
||||
|
||||
EDhApiRenderPass renderPass;
|
||||
if (DhApiRenderProxy.INSTANCE.getDeferTransparentRendering())
|
||||
{
|
||||
if (renderingDeferredLayer)
|
||||
{
|
||||
renderPass = EDhApiRenderPass.TRANSPARENT;
|
||||
}
|
||||
else
|
||||
{
|
||||
renderPass = EDhApiRenderPass.OPAQUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
renderPass = EDhApiRenderPass.OPAQUE_AND_TRANSPARENT;
|
||||
}
|
||||
|
||||
DhApiRenderParam renderEventParam =
|
||||
new DhApiRenderParam(
|
||||
renderPass,
|
||||
partialTicks,
|
||||
RenderUtil.getNearClipPlaneDistanceInBlocks(partialTicks), RenderUtil.getFarClipPlaneDistanceInBlocks(),
|
||||
mcProjectionMatrix, mcModelViewMatrix,
|
||||
RenderUtil.createLodProjectionMatrix(mcProjectionMatrix, partialTicks), RenderUtil.createLodModelViewMatrix(mcModelViewMatrix),
|
||||
levelWrapper.getMinHeight()
|
||||
);
|
||||
|
||||
|
||||
|
||||
// render validation //
|
||||
|
||||
try
|
||||
{
|
||||
if (!RenderUtil.shouldLodsRender(levelWrapper))
|
||||
@@ -473,29 +530,35 @@ public class ClientApi
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//FIXME: Improve class hierarchy of DhWorld, IClientWorld, IServerWorld to fix all this hard casting
|
||||
// (also in RenderUtil)
|
||||
IDhClientWorld dhClientWorld = SharedApi.getIDhClientWorld();
|
||||
if (dhClientWorld == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
IDhClientLevel level = dhClientWorld.getOrLoadClientLevel(levelWrapper);
|
||||
|
||||
if (this.rendererDisabledBecauseOfExceptions)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
try
|
||||
// render pass //
|
||||
|
||||
if (!renderingDeferredLayer)
|
||||
{
|
||||
if (Config.Client.Advanced.Debugging.rendererMode.get() == ERendererMode.DEFAULT)
|
||||
{
|
||||
DhApiRenderParam renderEventParam =
|
||||
new DhApiRenderParam(mcProjectionMatrix, mcModelViewMatrix,
|
||||
RenderUtil.createLodProjectionMatrix(mcProjectionMatrix, partialTicks),
|
||||
RenderUtil.createLodModelViewMatrix(mcModelViewMatrix), partialTicks);
|
||||
|
||||
boolean renderingCanceled = ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeRenderEvent.class, new DhApiBeforeRenderEvent.EventParam(renderEventParam));
|
||||
if (!this.rendererDisabledBecauseOfExceptions && !renderingCanceled)
|
||||
this.renderingCancelledForThisFrame = ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeRenderEvent.class, renderEventParam);
|
||||
if (!this.renderingCancelledForThisFrame)
|
||||
{
|
||||
level.render(mcModelViewMatrix, mcProjectionMatrix, partialTicks, profiler);
|
||||
ApiEventInjector.INSTANCE.fireAllEvents(DhApiAfterRenderEvent.class, new DhApiAfterRenderEvent.EventParam(renderEventParam));
|
||||
level.render(renderEventParam, profiler);
|
||||
}
|
||||
|
||||
if (!DhApi.Delayed.renderProxy.getDeferTransparentRendering())
|
||||
{
|
||||
ApiEventInjector.INSTANCE.fireAllEvents(DhApiAfterRenderEvent.class, renderEventParam);
|
||||
}
|
||||
}
|
||||
else if (Config.Client.Advanced.Debugging.rendererMode.get() == ERendererMode.DEBUG)
|
||||
@@ -504,22 +567,30 @@ public class ClientApi
|
||||
ClientApi.testRenderer.render();
|
||||
profiler.pop();
|
||||
}
|
||||
// the other rendererMode is DISABLED
|
||||
}
|
||||
catch (RuntimeException e)
|
||||
else
|
||||
{
|
||||
this.rendererDisabledBecauseOfExceptions = true;
|
||||
LOGGER.error("Renderer thrown an uncaught exception: ", e);
|
||||
boolean renderingCancelled = ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeDeferredRenderEvent.class, renderEventParam);
|
||||
if (!renderingCancelled)
|
||||
{
|
||||
level.renderDeferred(renderEventParam, profiler);
|
||||
}
|
||||
|
||||
MC.sendChatMessage("\u00A74\u00A7l\u00A7uERROR: Distant Horizons"
|
||||
+ " renderer has encountered an exception!");
|
||||
MC.sendChatMessage("\u00A74Renderer is now disabled to prevent further issues.");
|
||||
MC.sendChatMessage("\u00A74Exception detail: " + e);
|
||||
|
||||
if (DhApi.Delayed.renderProxy.getDeferTransparentRendering())
|
||||
{
|
||||
ApiEventInjector.INSTANCE.fireAllEvents(DhApiAfterRenderEvent.class, renderEventParam);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOGGER.error("client level rendering uncaught exception: ", e);
|
||||
this.rendererDisabledBecauseOfExceptions = true;
|
||||
LOGGER.error("Unexpected Renderer error in render pass [" + renderPass + "]. Error: " + e.getMessage(), e);
|
||||
|
||||
MC.sendChatMessage("\u00A74\u00A7l\u00A7uERROR: Distant Horizons renderer has encountered an exception!");
|
||||
MC.sendChatMessage("\u00A74Renderer is now disabled to prevent further issues.");
|
||||
MC.sendChatMessage("\u00A74Exception detail: " + e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
@@ -530,6 +601,7 @@ public class ClientApi
|
||||
|
||||
|
||||
|
||||
|
||||
//=================//
|
||||
// DEBUG USE //
|
||||
//=================//
|
||||
|
||||
@@ -541,18 +541,17 @@ public class Config
|
||||
|
||||
public static class AdvancedGraphics
|
||||
{
|
||||
// TODO re-implement
|
||||
// public static ConfigEntry<Boolean> disableDirectionalCulling = new ConfigEntry.Builder<Boolean>()
|
||||
// .set(false)
|
||||
// .comment(""
|
||||
// + "If false fake chunks behind the player's camera \n"
|
||||
// + "aren't drawn, increasing GPU performance. \n"
|
||||
// + "\n"
|
||||
// + "If true all LODs are drawn, even those behind \n"
|
||||
// + "the player's camera, decreasing GPU performance. \n"
|
||||
// + "\n"
|
||||
// + "Disable this if you see LODs disappearing at the corners of your vision.")
|
||||
// .build();
|
||||
public static ConfigEntry<Boolean> disableFrustumCulling = new ConfigEntry.Builder<Boolean>()
|
||||
.set(false)
|
||||
.comment(""
|
||||
+ "If false LODs outside the player's camera \n"
|
||||
+ "aren't drawn, increasing GPU performance. \n"
|
||||
+ "\n"
|
||||
+ "If true all LODs are drawn, even those behind \n"
|
||||
+ "the player's camera, decreasing GPU performance. \n"
|
||||
+ "\n"
|
||||
+ "Disable this if you see LODs disappearing at the corners of your vision.")
|
||||
.build();
|
||||
|
||||
/**
|
||||
* @deprecated Use overdrawPrevention instead, will be removed when DH updates to MC 1.21 <br>
|
||||
@@ -581,6 +580,7 @@ public class Config
|
||||
.setPerformance(EConfigEntryPerformance.NONE)
|
||||
.build();
|
||||
|
||||
@Deprecated // TODO remove failed experiment
|
||||
public static ConfigEntry<Boolean> seamlessOverdraw = new ConfigEntry.Builder<Boolean>()
|
||||
.set(false)
|
||||
.comment(""
|
||||
@@ -1225,11 +1225,11 @@ public class Config
|
||||
.comment(""
|
||||
+ "Should specialized colors/rendering modes be used? \n"
|
||||
+ "\n"
|
||||
+ EDebugRendering.OFF + ": Fake chunks will be drawn with their normal colors. \n"
|
||||
+ EDebugRendering.SHOW_DETAIL + ": Fake chunks color will be based on their detail level. \n"
|
||||
+ EDebugRendering.SHOW_GENMODE + ": Fake chunks color will be based on their distant generation mode. \n"
|
||||
+ EDebugRendering.SHOW_OVERLAPPING_QUADS + ": Fake chunks will be drawn with total white, but overlapping quads will be drawn with red. \n"
|
||||
+ " but overlapping quads will be drawn with red, drawn as a wireframe.")
|
||||
+ EDebugRendering.OFF + ": LODs will be drawn with their normal colors. \n"
|
||||
+ EDebugRendering.SHOW_DETAIL + ": LODs' color will be based on their detail level. \n"
|
||||
+ EDebugRendering.SHOW_BLOCK_MATERIAL + ": LODs' color will be based on their material. \n"
|
||||
+ EDebugRendering.SHOW_OVERLAPPING_QUADS + ": LODs will be drawn with total white, but overlapping quads will be drawn with red. \n"
|
||||
+ "")
|
||||
.build();
|
||||
|
||||
public static ConfigEntry<Boolean> renderWireframe = new ConfigEntry.Builder<Boolean>()
|
||||
|
||||
+3
-24
@@ -274,27 +274,6 @@ public class ColumnRenderSource implements IDataSource<IDhClientLevel>
|
||||
// the source isn't empty, this object won't be empty after the method finishes
|
||||
this.isEmpty = false;
|
||||
|
||||
for (int i = 0; i < this.renderDataContainer.length; i += this.verticalDataCount)
|
||||
{
|
||||
int thisGenMode = RenderDataPointUtil.getGenerationMode(this.renderDataContainer[i]);
|
||||
int srcGenMode = RenderDataPointUtil.getGenerationMode(renderSource.renderDataContainer[i]);
|
||||
|
||||
if (srcGenMode == 0)
|
||||
{
|
||||
// the source hasn't been generated, don't write it
|
||||
continue;
|
||||
}
|
||||
|
||||
// this object's column is older than the source's column, update it
|
||||
if (thisGenMode <= srcGenMode)
|
||||
{
|
||||
ColumnArrayView thisColumnArrayView = new ColumnArrayView(this.renderDataContainer, this.verticalDataCount, i, this.verticalDataCount);
|
||||
ColumnArrayView srcColumnArrayView = new ColumnArrayView(renderSource.renderDataContainer, renderSource.verticalDataCount, i, renderSource.verticalDataCount);
|
||||
thisColumnArrayView.copyFrom(srcColumnArrayView);
|
||||
|
||||
this.debugSourceFlags[i / this.verticalDataCount] = renderSource.debugSourceFlags[i / this.verticalDataCount];
|
||||
}
|
||||
}
|
||||
localVersion.incrementAndGet();
|
||||
}
|
||||
/**
|
||||
@@ -361,7 +340,7 @@ public class ColumnRenderSource implements IDataSource<IDhClientLevel>
|
||||
FullDataToRenderDataTransformer.convertColumnData(level,
|
||||
sourceBlockX + sourceDataPointBlockWidth * (blockOffsetX + x),
|
||||
sourceBlockZ + sourceDataPointBlockWidth * (blockOffsetZ + z),
|
||||
columnArrayView, fullArrayView, 2);
|
||||
columnArrayView, fullArrayView);
|
||||
dataChanged |= hash != columnArrayView.getDataHash();
|
||||
}
|
||||
}
|
||||
@@ -391,7 +370,7 @@ public class ColumnRenderSource implements IDataSource<IDhClientLevel>
|
||||
FullDataToRenderDataTransformer.convertColumnData(level,
|
||||
sourceBlockX + sourceDataPointBlockWidth * relSourceX,
|
||||
sourceBlockZ + sourceDataPointBlockWidth * relSourceZ,
|
||||
columnArrayView, fullArrayView, 2);
|
||||
columnArrayView, fullArrayView);
|
||||
dataChanged |= hash != columnArrayView.getDataHash();
|
||||
}
|
||||
}
|
||||
@@ -415,7 +394,7 @@ public class ColumnRenderSource implements IDataSource<IDhClientLevel>
|
||||
SingleColumnFullDataAccessor fullArrayView = chunkDataView.get(0, 0);
|
||||
FullDataToRenderDataTransformer.convertColumnData(level, dataCornerPos.x * sourceDataPointBlockWidth,
|
||||
dataCornerPos.z * sourceDataPointBlockWidth,
|
||||
columnArrayView, fullArrayView, 2);
|
||||
columnArrayView, fullArrayView);
|
||||
dataChanged = hash != columnArrayView.getDataHash();
|
||||
this.fillDebugFlag(relStartX, relStartZ, 1, 1, ColumnRenderSource.DebugSourceFlag.DIRECT);
|
||||
}
|
||||
|
||||
-7
@@ -55,14 +55,7 @@ public class ColumnRenderSourceLoader
|
||||
switch (dataFileVersion)
|
||||
{
|
||||
case 1:
|
||||
//LOGGER.info("loading render source "+dataFile.pos);
|
||||
|
||||
ParsedColumnData parsedColumnData = readDataV1(inputStream, level.getMinY());
|
||||
if (parsedColumnData.isEmpty)
|
||||
{
|
||||
LOGGER.warn("Empty render file " + dto.pos);
|
||||
}
|
||||
|
||||
return new ColumnRenderSource(dto.pos, parsedColumnData, level);
|
||||
default:
|
||||
throw new IOException("Invalid Data: The data version [" + dataFileVersion + "] is not supported");
|
||||
|
||||
+6
-7
@@ -49,12 +49,9 @@ public final class BufferQuad
|
||||
/** This is both North/South and Up/Down since the merging logic is the same either way */
|
||||
public short widthNorthSouthOrUpDown;
|
||||
|
||||
/**
|
||||
* not final since it may need to be modified to be opaque
|
||||
*
|
||||
* @see LodQuadBuilder#fixTransparencyOverVoid
|
||||
*/
|
||||
public int color;
|
||||
public final int color;
|
||||
/** used by the Iris shader mod to determine how each LOD should be rendered */
|
||||
public final byte irisBlockMaterialId;
|
||||
|
||||
public final byte skyLight;
|
||||
public final byte blockLight;
|
||||
@@ -66,7 +63,7 @@ public final class BufferQuad
|
||||
|
||||
BufferQuad(
|
||||
short x, short y, short z, short widthEastWest, short widthNorthSouthOrUpDown,
|
||||
int color, byte skylight, byte blockLight,
|
||||
int color, byte irisBlockMaterialId, byte skylight, byte blockLight,
|
||||
EDhDirection direction)
|
||||
{
|
||||
if (widthEastWest == 0 || widthNorthSouthOrUpDown == 0)
|
||||
@@ -80,6 +77,7 @@ public final class BufferQuad
|
||||
this.widthEastWest = widthEastWest;
|
||||
this.widthNorthSouthOrUpDown = widthNorthSouthOrUpDown;
|
||||
this.color = color;
|
||||
this.irisBlockMaterialId = irisBlockMaterialId;
|
||||
this.skyLight = skylight;
|
||||
this.blockLight = blockLight;
|
||||
this.direction = direction;
|
||||
@@ -301,6 +299,7 @@ public final class BufferQuad
|
||||
|
||||
// do the quads' color, light, etc. match?
|
||||
if (this.color != quad.color ||
|
||||
this.irisBlockMaterialId != quad.irisBlockMaterialId ||
|
||||
this.skyLight != quad.skyLight ||
|
||||
this.blockLight != quad.blockLight)
|
||||
{
|
||||
|
||||
+33
-33
@@ -36,7 +36,7 @@ public class ColumnBox
|
||||
LodQuadBuilder builder,
|
||||
short xSize, short ySize, short zSize,
|
||||
short x, short minY, short z,
|
||||
int color, byte skyLight, byte blockLight,
|
||||
int color, byte irisBlockMaterialId, byte skyLight, byte blockLight,
|
||||
long topData, long bottomData, ColumnArrayView[][] adjData)
|
||||
{
|
||||
short maxX = (short) (x + xSize);
|
||||
@@ -102,13 +102,13 @@ public class ColumnBox
|
||||
boolean skipTop = RenderDataPointUtil.doesDataPointExist(topData) && (RenderDataPointUtil.getYMin(topData) == maxY) && !isTopTransparent;
|
||||
if (!skipTop)
|
||||
{
|
||||
builder.addQuadUp(x, maxY, z, xSize, zSize, ColorUtil.applyShade(color, MC.getShade(EDhDirection.UP)), skyLightTop, blockLight);
|
||||
builder.addQuadUp(x, maxY, z, xSize, zSize, ColorUtil.applyShade(color, MC.getShade(EDhDirection.UP)), irisBlockMaterialId, skyLightTop, blockLight);
|
||||
}
|
||||
|
||||
boolean skipBottom = RenderDataPointUtil.doesDataPointExist(bottomData) && (RenderDataPointUtil.getYMax(bottomData) == minY) && !isBottomTransparent;
|
||||
if (!skipBottom)
|
||||
{
|
||||
builder.addQuadDown(x, minY, z, xSize, zSize, ColorUtil.applyShade(color, MC.getShade(EDhDirection.DOWN)), skyLightBot, blockLight);
|
||||
builder.addQuadDown(x, minY, z, xSize, zSize, ColorUtil.applyShade(color, MC.getShade(EDhDirection.DOWN)), irisBlockMaterialId, skyLightBot, blockLight);
|
||||
}
|
||||
|
||||
|
||||
@@ -124,22 +124,22 @@ public class ColumnBox
|
||||
// add an adjacent face if this is opaque face or transparent over the void
|
||||
if (!isTransparent || overVoid)
|
||||
{
|
||||
builder.addQuadAdj(EDhDirection.NORTH, x, minY, z, xSize, ySize, color, (byte) 15, blockLight);
|
||||
builder.addQuadAdj(EDhDirection.NORTH, x, minY, z, xSize, ySize, color, irisBlockMaterialId, (byte) 15, blockLight);
|
||||
}
|
||||
}
|
||||
else if (adjDataNorth.length == 1)
|
||||
{
|
||||
makeAdjVerticalQuad(builder, adjDataNorth[0], EDhDirection.NORTH, x, minY, z, xSize, ySize,
|
||||
color, adjOverlapNorth, skyLightTop, blockLight,
|
||||
color, adjOverlapNorth, irisBlockMaterialId, skyLightTop, blockLight,
|
||||
topData, bottomData);
|
||||
}
|
||||
else
|
||||
{
|
||||
makeAdjVerticalQuad(builder, adjDataNorth[0], EDhDirection.NORTH, x, minY, z, (short) (xSize / 2), ySize,
|
||||
color, adjOverlapNorth, skyLightTop, blockLight,
|
||||
color, adjOverlapNorth, irisBlockMaterialId, skyLightTop, blockLight,
|
||||
topData, bottomData);
|
||||
makeAdjVerticalQuad(builder, adjDataNorth[1], EDhDirection.NORTH, (short) (x + xSize / 2), minY, z, (short) (xSize / 2), ySize,
|
||||
color, adjOverlapNorth, skyLightTop, blockLight,
|
||||
color, adjOverlapNorth, irisBlockMaterialId, skyLightTop, blockLight,
|
||||
topData, bottomData);
|
||||
}
|
||||
}
|
||||
@@ -151,22 +151,22 @@ public class ColumnBox
|
||||
if (adjDataSouth == null)
|
||||
{
|
||||
if (!isTransparent || overVoid)
|
||||
builder.addQuadAdj(EDhDirection.SOUTH, x, minY, maxZ, xSize, ySize, color, (byte) 15, blockLight);
|
||||
builder.addQuadAdj(EDhDirection.SOUTH, x, minY, maxZ, xSize, ySize, color, irisBlockMaterialId, (byte) 15, blockLight);
|
||||
}
|
||||
else if (adjDataSouth.length == 1)
|
||||
{
|
||||
makeAdjVerticalQuad(builder, adjDataSouth[0], EDhDirection.SOUTH, x, minY, maxZ, xSize, ySize,
|
||||
color, adjOverlapSouth, skyLightTop, blockLight,
|
||||
color, adjOverlapSouth, irisBlockMaterialId, skyLightTop, blockLight,
|
||||
topData, bottomData);
|
||||
}
|
||||
else
|
||||
{
|
||||
makeAdjVerticalQuad(builder, adjDataSouth[0], EDhDirection.SOUTH, x, minY, maxZ, (short) (xSize / 2), ySize,
|
||||
color, adjOverlapSouth, skyLightTop, blockLight,
|
||||
color, adjOverlapSouth, irisBlockMaterialId, skyLightTop, blockLight,
|
||||
topData, bottomData);
|
||||
|
||||
makeAdjVerticalQuad(builder, adjDataSouth[1], EDhDirection.SOUTH, (short) (x + xSize / 2), minY, maxZ, (short) (xSize / 2), ySize,
|
||||
color, adjOverlapSouth, skyLightTop, blockLight,
|
||||
color, adjOverlapSouth, irisBlockMaterialId, skyLightTop, blockLight,
|
||||
topData, bottomData);
|
||||
}
|
||||
}
|
||||
@@ -178,21 +178,21 @@ public class ColumnBox
|
||||
if (adjDataWest == null)
|
||||
{
|
||||
if (!isTransparent || overVoid)
|
||||
builder.addQuadAdj(EDhDirection.WEST, x, minY, z, zSize, ySize, color, (byte) 15, blockLight);
|
||||
builder.addQuadAdj(EDhDirection.WEST, x, minY, z, zSize, ySize, color, irisBlockMaterialId, (byte) 15, blockLight);
|
||||
}
|
||||
else if (adjDataWest.length == 1)
|
||||
{
|
||||
makeAdjVerticalQuad(builder, adjDataWest[0], EDhDirection.WEST, x, minY, z, zSize, ySize,
|
||||
color, adjOverlapWest, skyLightTop, blockLight,
|
||||
color, adjOverlapWest, irisBlockMaterialId, skyLightTop, blockLight,
|
||||
topData, bottomData);
|
||||
}
|
||||
else
|
||||
{
|
||||
makeAdjVerticalQuad(builder, adjDataWest[0], EDhDirection.WEST, x, minY, z, (short) (zSize / 2), ySize,
|
||||
color, adjOverlapWest, skyLightTop, blockLight,
|
||||
color, adjOverlapWest, irisBlockMaterialId, skyLightTop, blockLight,
|
||||
topData, bottomData);
|
||||
makeAdjVerticalQuad(builder, adjDataWest[1], EDhDirection.WEST, x, minY, (short) (z + zSize / 2), (short) (zSize / 2), ySize,
|
||||
color, adjOverlapWest, skyLightTop, blockLight,
|
||||
color, adjOverlapWest, irisBlockMaterialId, skyLightTop, blockLight,
|
||||
topData, bottomData);
|
||||
}
|
||||
}
|
||||
@@ -204,21 +204,21 @@ public class ColumnBox
|
||||
if (adjData[EDhDirection.EAST.ordinal() - 2] == null)
|
||||
{
|
||||
if (!isTransparent || overVoid)
|
||||
builder.addQuadAdj(EDhDirection.EAST, maxX, minY, z, zSize, ySize, color, (byte) 15, blockLight);
|
||||
builder.addQuadAdj(EDhDirection.EAST, maxX, minY, z, zSize, ySize, color, irisBlockMaterialId, (byte) 15, blockLight);
|
||||
}
|
||||
else if (adjDataEast.length == 1)
|
||||
{
|
||||
makeAdjVerticalQuad(builder, adjDataEast[0], EDhDirection.EAST, maxX, minY, z, zSize, ySize,
|
||||
color, adjOverlapEast, skyLightTop, blockLight,
|
||||
color, adjOverlapEast, irisBlockMaterialId, skyLightTop, blockLight,
|
||||
topData, bottomData);
|
||||
}
|
||||
else
|
||||
{
|
||||
makeAdjVerticalQuad(builder, adjDataEast[0], EDhDirection.EAST, maxX, minY, z, (short) (zSize / 2), ySize,
|
||||
color, adjOverlapEast, skyLightTop, blockLight,
|
||||
color, adjOverlapEast, irisBlockMaterialId, skyLightTop, blockLight,
|
||||
topData, bottomData);
|
||||
makeAdjVerticalQuad(builder, adjDataEast[1], EDhDirection.EAST, maxX, minY, (short) (z + zSize / 2), (short) (zSize / 2), ySize,
|
||||
color, adjOverlapEast, skyLightTop, blockLight,
|
||||
color, adjOverlapEast, irisBlockMaterialId, skyLightTop, blockLight,
|
||||
topData, bottomData);
|
||||
}
|
||||
}
|
||||
@@ -228,7 +228,7 @@ public class ColumnBox
|
||||
private static void makeAdjVerticalQuad(
|
||||
LodQuadBuilder builder, ColumnArrayView adjColumnView, EDhDirection direction,
|
||||
short x, short yMin, short z, short horizontalWidth, short ySize,
|
||||
int color, int debugOverlapColor, byte skyLightTop, byte blockLight,
|
||||
int color, int debugOverlapColor, byte irisBlockMaterialId, byte skyLightTop, byte blockLight,
|
||||
long topData, long bottomData)
|
||||
{
|
||||
color = ColorUtil.applyShade(color, MC.getShade(direction));
|
||||
@@ -236,7 +236,7 @@ public class ColumnBox
|
||||
if (adjColumnView == null || adjColumnView.size == 0 || RenderDataPointUtil.isVoid(adjColumnView.get(0)))
|
||||
{
|
||||
// there isn't any data adjacent to this LOD, add the vertical quad
|
||||
builder.addQuadAdj(direction, x, yMin, z, horizontalWidth, ySize, color, (byte) 15, blockLight);
|
||||
builder.addQuadAdj(direction, x, yMin, z, horizontalWidth, ySize, color, irisBlockMaterialId, (byte) 15, blockLight);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -362,7 +362,7 @@ public class ColumnBox
|
||||
|
||||
if (firstFace)
|
||||
{
|
||||
builder.addQuadAdj(direction, x, yMin, z, horizontalWidth, ySize, color, skyLight, blockLight);
|
||||
builder.addQuadAdj(direction, x, yMin, z, horizontalWidth, ySize, color, irisBlockMaterialId, skyLight, blockLight);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -373,7 +373,7 @@ public class ColumnBox
|
||||
throw new RuntimeException("Loop error");
|
||||
}
|
||||
|
||||
builder.addQuadAdj(direction, x, yMin, z, horizontalWidth, (short) (previousAdjDepth - yMin), color, skyLight, blockLight);
|
||||
builder.addQuadAdj(direction, x, yMin, z, horizontalWidth, (short) (previousAdjDepth - yMin), color, irisBlockMaterialId, skyLight, blockLight);
|
||||
|
||||
previousAdjDepth = -1;
|
||||
}
|
||||
@@ -393,7 +393,7 @@ public class ColumnBox
|
||||
// The input face is completely inside the adj's face, don't render it
|
||||
if (debugOverlapColor != 0)
|
||||
{
|
||||
builder.addQuadAdj(direction, x, yMin, z, horizontalWidth, ySize, debugOverlapColor, (byte) 15, (byte) 15);
|
||||
builder.addQuadAdj(direction, x, yMin, z, horizontalWidth, ySize, debugOverlapColor, irisBlockMaterialId, (byte) 15, (byte) 15);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -402,14 +402,14 @@ public class ColumnBox
|
||||
|
||||
if (adjYMax > yMin && debugOverlapColor != 0)
|
||||
{
|
||||
builder.addQuadAdj(direction, x, yMin, z, horizontalWidth, (short) (adjYMax - yMin), debugOverlapColor, (byte) 15, (byte) 15);
|
||||
builder.addQuadAdj(direction, x, yMin, z, horizontalWidth, (short) (adjYMax - yMin), debugOverlapColor, irisBlockMaterialId, (byte) 15, (byte) 15);
|
||||
}
|
||||
|
||||
// if this is the only face, use the yMax and break,
|
||||
// if there was another face finish the last one and then break
|
||||
if (firstFace)
|
||||
{
|
||||
builder.addQuadAdj(direction, x, adjYMax, z, horizontalWidth, (short) (yMax - adjYMax), color,
|
||||
builder.addQuadAdj(direction, x, adjYMax, z, horizontalWidth, (short) (yMax - adjYMax), color, irisBlockMaterialId,
|
||||
RenderDataPointUtil.getLightSky(adjPoint), blockLight);
|
||||
}
|
||||
else
|
||||
@@ -423,7 +423,7 @@ public class ColumnBox
|
||||
|
||||
if (previousAdjDepth > adjYMax)
|
||||
{
|
||||
builder.addQuadAdj(direction, x, adjYMax, z, horizontalWidth, (short) (previousAdjDepth - adjYMax), color,
|
||||
builder.addQuadAdj(direction, x, adjYMax, z, horizontalWidth, (short) (previousAdjDepth - adjYMax), color, irisBlockMaterialId,
|
||||
RenderDataPointUtil.getLightSky(adjPoint), blockLight);
|
||||
}
|
||||
previousAdjDepth = -1;
|
||||
@@ -448,7 +448,7 @@ public class ColumnBox
|
||||
// the adj data intersects the higher part of the current data
|
||||
if (debugOverlapColor != 0)
|
||||
{
|
||||
builder.addQuadAdj(direction, x, adjYMin, z, horizontalWidth, (short) (yMax - adjYMin), debugOverlapColor, (byte) 15, (byte) 15);
|
||||
builder.addQuadAdj(direction, x, adjYMin, z, horizontalWidth, (short) (yMax - adjYMin), debugOverlapColor, irisBlockMaterialId, (byte) 15, (byte) 15);
|
||||
}
|
||||
|
||||
// we start the creation of a new face
|
||||
@@ -459,12 +459,12 @@ public class ColumnBox
|
||||
// _______&&: y < depth ______ < yMax
|
||||
if (debugOverlapColor != 0)
|
||||
{
|
||||
builder.addQuadAdj(direction, x, adjYMin, z, horizontalWidth, (short) (adjYMax - adjYMin), debugOverlapColor, (byte) 15, (byte) 15);
|
||||
builder.addQuadAdj(direction, x, adjYMin, z, horizontalWidth, (short) (adjYMax - adjYMin), debugOverlapColor, irisBlockMaterialId, (byte) 15, (byte) 15);
|
||||
}
|
||||
|
||||
if (firstFace)
|
||||
{
|
||||
builder.addQuadAdj(direction, x, adjYMax, z, horizontalWidth, (short) (yMax - adjYMax), color,
|
||||
builder.addQuadAdj(direction, x, adjYMax, z, horizontalWidth, (short) (yMax - adjYMax), color, irisBlockMaterialId,
|
||||
RenderDataPointUtil.getLightSky(adjPoint), blockLight);
|
||||
}
|
||||
else
|
||||
@@ -474,7 +474,7 @@ public class ColumnBox
|
||||
throw new RuntimeException("Loop error");
|
||||
if (previousAdjDepth > adjYMax)
|
||||
{
|
||||
builder.addQuadAdj(direction, x, adjYMax, z, horizontalWidth, (short) (previousAdjDepth - adjYMax), color,
|
||||
builder.addQuadAdj(direction, x, adjYMax, z, horizontalWidth, (short) (previousAdjDepth - adjYMax), color, irisBlockMaterialId,
|
||||
RenderDataPointUtil.getLightSky(adjPoint), blockLight);
|
||||
}
|
||||
previousAdjDepth = -1;
|
||||
@@ -502,12 +502,12 @@ public class ColumnBox
|
||||
{
|
||||
// the input LOD is above all adjacent LODs and won't be affected
|
||||
// by them, add the vertical quad using the input's lighting and height
|
||||
builder.addQuadAdj(direction, x, yMin, z, horizontalWidth, ySize, color, skyLightTop, blockLight);
|
||||
builder.addQuadAdj(direction, x, yMin, z, horizontalWidth, ySize, color, irisBlockMaterialId, skyLightTop, blockLight);
|
||||
}
|
||||
else if (previousAdjDepth != -1)
|
||||
{
|
||||
// We need to finish the last quad.
|
||||
builder.addQuadAdj(direction, x, yMin, z, horizontalWidth, (short) (previousAdjDepth - yMin), color, nextTopSkyLight, blockLight);
|
||||
builder.addQuadAdj(direction, x, yMin, z, horizontalWidth, (short) (previousAdjDepth - yMin), color, irisBlockMaterialId, nextTopSkyLight, blockLight);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+5
-4
@@ -19,6 +19,7 @@
|
||||
|
||||
package com.seibel.distanthorizons.core.dataObjects.render.bufferBuilding;
|
||||
|
||||
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiRenderParam;
|
||||
import com.seibel.distanthorizons.core.config.Config;
|
||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||
import com.seibel.distanthorizons.core.enums.EGLProxyContext;
|
||||
@@ -275,10 +276,10 @@ public class ColumnRenderBuffer extends AbstractRenderBuffer
|
||||
//========//
|
||||
|
||||
@Override
|
||||
public boolean renderOpaque(LodRenderer renderContext)
|
||||
public boolean renderOpaque(LodRenderer renderContext, DhApiRenderParam renderEventParam)
|
||||
{
|
||||
boolean hasRendered = false;
|
||||
renderContext.setupOffset(this.pos);
|
||||
renderContext.setModelViewMatrixOffset(this.pos, renderEventParam);
|
||||
for (GLVertexBuffer vbo : this.vbos)
|
||||
{
|
||||
if (vbo == null)
|
||||
@@ -299,14 +300,14 @@ public class ColumnRenderBuffer extends AbstractRenderBuffer
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean renderTransparent(LodRenderer renderContext)
|
||||
public boolean renderTransparent(LodRenderer renderContext, DhApiRenderParam renderEventParam)
|
||||
{
|
||||
boolean hasRendered = false;
|
||||
|
||||
try
|
||||
{
|
||||
// can throw an IllegalStateException if the GL program was freed before it should've been
|
||||
renderContext.setupOffset(this.pos);
|
||||
renderContext.setModelViewMatrixOffset(this.pos, renderEventParam);
|
||||
|
||||
for (GLVertexBuffer vbo : this.vbosTransparent)
|
||||
{
|
||||
|
||||
+59
-2
@@ -27,6 +27,7 @@ import com.seibel.distanthorizons.core.util.LodUtil;
|
||||
import com.seibel.distanthorizons.core.util.RenderDataPointUtil;
|
||||
import com.seibel.distanthorizons.api.enums.rendering.EDebugRendering;
|
||||
import com.seibel.distanthorizons.core.dataObjects.render.columnViews.ColumnArrayView;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.block.IBlockStateWrapper;
|
||||
import com.seibel.distanthorizons.coreapi.util.BitShiftUtil;
|
||||
|
||||
/**
|
||||
@@ -60,6 +61,8 @@ public class CubicLodTemplate
|
||||
throw new IllegalArgumentException("Negative y size for the data! Data: " + RenderDataPointUtil.toString(data));
|
||||
}
|
||||
|
||||
byte blockMaterialId = RenderDataPointUtil.getBlockMaterialId(data);
|
||||
|
||||
|
||||
|
||||
int color;
|
||||
@@ -85,14 +88,67 @@ public class CubicLodTemplate
|
||||
break;
|
||||
}
|
||||
case SHOW_DETAIL:
|
||||
case SHOW_GENMODE:
|
||||
{
|
||||
color = LodUtil.DEBUG_DETAIL_LEVEL_COLORS[detailLevel];
|
||||
fullBright = true;
|
||||
break;
|
||||
}
|
||||
case SHOW_GENMODE:
|
||||
case SHOW_BLOCK_MATERIAL:
|
||||
{
|
||||
color = LodUtil.DEBUG_DETAIL_LEVEL_COLORS[RenderDataPointUtil.getGenerationMode(data)];
|
||||
switch (blockMaterialId)
|
||||
{
|
||||
case IBlockStateWrapper.IrisBlockMaterial.UNKOWN:
|
||||
case IBlockStateWrapper.IrisBlockMaterial.AIR: // shouldn't normally be rendered, but just in case
|
||||
color = ColorUtil.HOT_PINK;
|
||||
break;
|
||||
|
||||
case IBlockStateWrapper.IrisBlockMaterial.LEAVES:
|
||||
color = ColorUtil.GREEN;
|
||||
break;
|
||||
case IBlockStateWrapper.IrisBlockMaterial.STONE:
|
||||
color = ColorUtil.GRAY;
|
||||
break;
|
||||
case IBlockStateWrapper.IrisBlockMaterial.WOOD:
|
||||
color = ColorUtil.BROWN;
|
||||
break;
|
||||
case IBlockStateWrapper.IrisBlockMaterial.METAL:
|
||||
color = ColorUtil.DARK_GRAY;
|
||||
break;
|
||||
case IBlockStateWrapper.IrisBlockMaterial.DIRT:
|
||||
color = ColorUtil.LIGHT_BROWN;
|
||||
break;
|
||||
case IBlockStateWrapper.IrisBlockMaterial.LAVA:
|
||||
color = ColorUtil.ORANGE;
|
||||
break;
|
||||
case IBlockStateWrapper.IrisBlockMaterial.DEEPSLATE:
|
||||
color = ColorUtil.BLACK;
|
||||
break;
|
||||
case IBlockStateWrapper.IrisBlockMaterial.SNOW:
|
||||
color = ColorUtil.WHITE;
|
||||
break;
|
||||
case IBlockStateWrapper.IrisBlockMaterial.SAND:
|
||||
color = ColorUtil.TAN;
|
||||
break;
|
||||
case IBlockStateWrapper.IrisBlockMaterial.TERRACOTTA:
|
||||
color = ColorUtil.DARK_ORANGE;
|
||||
break;
|
||||
case IBlockStateWrapper.IrisBlockMaterial.NETHER_STONE:
|
||||
color = ColorUtil.DARK_RED;
|
||||
break;
|
||||
case IBlockStateWrapper.IrisBlockMaterial.WATER:
|
||||
color = ColorUtil.BLUE;
|
||||
break;
|
||||
case IBlockStateWrapper.IrisBlockMaterial.ILLUMINATED:
|
||||
color = ColorUtil.YELLOW;
|
||||
break;
|
||||
|
||||
default:
|
||||
// undefined color
|
||||
color = ColorUtil.CYAN;
|
||||
break;
|
||||
}
|
||||
|
||||
fullBright = true;
|
||||
break;
|
||||
}
|
||||
@@ -117,6 +173,7 @@ public class CubicLodTemplate
|
||||
width, ySize, width, // setWidth
|
||||
x, yMin, z, // setOffset
|
||||
color, // setColor
|
||||
blockMaterialId, // irisBlockMaterialId
|
||||
RenderDataPointUtil.getLightSky(data), // setSkyLights
|
||||
fullBright ? 15 : RenderDataPointUtil.getLightBlock(data), // setBlockLights
|
||||
topData, bottomData, adjColumnViews); // setAdjData
|
||||
|
||||
+15
-7
@@ -135,7 +135,7 @@ public class LodQuadBuilder
|
||||
public void addQuadAdj(
|
||||
EDhDirection dir, short x, short y, short z,
|
||||
short widthEastWest, short widthNorthSouthOrUpDown,
|
||||
int color, byte skyLight, byte blockLight)
|
||||
int color, byte irisBlockMaterialId, byte skyLight, byte blockLight)
|
||||
{
|
||||
if (dir == EDhDirection.DOWN)
|
||||
{
|
||||
@@ -147,7 +147,7 @@ public class LodQuadBuilder
|
||||
return;
|
||||
}
|
||||
|
||||
BufferQuad quad = new BufferQuad(x, y, z, widthEastWest, widthNorthSouthOrUpDown, color, skyLight, blockLight, dir);
|
||||
BufferQuad quad = new BufferQuad(x, y, z, widthEastWest, widthNorthSouthOrUpDown, color, irisBlockMaterialId, skyLight, blockLight, dir);
|
||||
ArrayList<BufferQuad> quadList = (this.doTransparency && ColorUtil.getAlpha(color) < 255) ? this.transparentQuads[dir.ordinal()] : this.opaqueQuads[dir.ordinal()];
|
||||
if (!quadList.isEmpty() &&
|
||||
(
|
||||
@@ -163,7 +163,7 @@ public class LodQuadBuilder
|
||||
}
|
||||
|
||||
// XZ
|
||||
public void addQuadUp(short x, short maxY, short z, short widthEastWest, short widthNorthSouthOrUpDown, int color, byte skylight, byte blocklight) // TODO argument names are wrong
|
||||
public void addQuadUp(short x, short maxY, short z, short widthEastWest, short widthNorthSouthOrUpDown, int color, byte irisBlockMaterialId, byte skylight, byte blocklight) // TODO argument names are wrong
|
||||
{
|
||||
// cave culling
|
||||
if (this.skipQuadsWithZeroSkylight && skylight == 0 && maxY < this.skyLightCullingBelow)
|
||||
@@ -171,7 +171,7 @@ public class LodQuadBuilder
|
||||
return;
|
||||
}
|
||||
|
||||
BufferQuad quad = new BufferQuad(x, maxY, z, widthEastWest, widthNorthSouthOrUpDown, color, skylight, blocklight, EDhDirection.UP);
|
||||
BufferQuad quad = new BufferQuad(x, maxY, z, widthEastWest, widthNorthSouthOrUpDown, color, irisBlockMaterialId, skylight, blocklight, EDhDirection.UP);
|
||||
boolean isTransparent = (this.doTransparency && ColorUtil.getAlpha(color) < 255);
|
||||
ArrayList<BufferQuad> quadList = isTransparent ? this.transparentQuads[EDhDirection.UP.ordinal()] : this.opaqueQuads[EDhDirection.UP.ordinal()];
|
||||
|
||||
@@ -190,11 +190,11 @@ public class LodQuadBuilder
|
||||
quadList.add(quad);
|
||||
}
|
||||
|
||||
public void addQuadDown(short x, short y, short z, short width, short wz, int color, byte skylight, byte blocklight)
|
||||
public void addQuadDown(short x, short y, short z, short width, short wz, int color, byte irisBlockMaterialId, byte skylight, byte blocklight)
|
||||
{
|
||||
if (skipQuadsWithZeroSkylight && skylight == 0 && y < skyLightCullingBelow)
|
||||
return;
|
||||
BufferQuad quad = new BufferQuad(x, y, z, width, wz, color, skylight, blocklight, EDhDirection.DOWN);
|
||||
BufferQuad quad = new BufferQuad(x, y, z, width, wz, color, irisBlockMaterialId, skylight, blocklight, EDhDirection.DOWN);
|
||||
ArrayList<BufferQuad> qs = (doTransparency && ColorUtil.getAlpha(color) < 255)
|
||||
? transparentQuads[EDhDirection.DOWN.ordinal()] : opaqueQuads[EDhDirection.DOWN.ordinal()];
|
||||
if (!qs.isEmpty() &&
|
||||
@@ -219,6 +219,7 @@ public class LodQuadBuilder
|
||||
int[][] quadBase = DIRECTION_VERTEX_IBO_QUAD[quad.direction.ordinal()];
|
||||
short widthEastWest = quad.widthEastWest;
|
||||
short widthNorthSouth = quad.widthNorthSouthOrUpDown;
|
||||
byte normalIndex = (byte) quad.direction.ordinal();
|
||||
EDhDirection.Axis axis = quad.direction.getAxis();
|
||||
for (int i = 0; i < quadBase.length; i++)
|
||||
{
|
||||
@@ -255,13 +256,15 @@ public class LodQuadBuilder
|
||||
}
|
||||
putVertex(bb, (short) (quad.x + dx), (short) (quad.y + dy), (short) (quad.z + dz),
|
||||
quad.hasError ? ColorUtil.RED : quad.color, // TODO add debug config that allows toggling this
|
||||
quad.hasError ? 0 : normalIndex,
|
||||
quad.hasError ? 0 : quad.irisBlockMaterialId,
|
||||
quad.hasError ? 15 : quad.skyLight,
|
||||
quad.hasError ? 15 : quad.blockLight,
|
||||
mx, my, mz);
|
||||
}
|
||||
}
|
||||
|
||||
private void putVertex(ByteBuffer bb, short x, short y, short z, int color, byte skylight, byte blocklight, int mx, int my, int mz)
|
||||
private void putVertex(ByteBuffer bb, short x, short y, short z, int color, byte normalIndex, byte irisBlockMaterialId, byte skylight, byte blocklight, int mx, int my, int mz)
|
||||
{
|
||||
skylight %= 16;
|
||||
blocklight %= 16;
|
||||
@@ -292,6 +295,11 @@ public class LodQuadBuilder
|
||||
bb.put(g);
|
||||
bb.put(b);
|
||||
bb.put(a);
|
||||
|
||||
// Block ID and normal index are used by the Iris format
|
||||
bb.put(irisBlockMaterialId);
|
||||
bb.put(normalIndex);
|
||||
bb.putShort((short) 0); // padding to make sure the vertex format as a whole is a multiple of 4
|
||||
}
|
||||
|
||||
|
||||
|
||||
+8
-15
@@ -134,12 +134,7 @@ public class FullDataToRenderDataTransformer
|
||||
|
||||
ColumnArrayView columnArrayView = columnSource.getVerticalDataPointView(x, z);
|
||||
SingleColumnFullDataAccessor fullArrayView = fullDataSource.get(x, z);
|
||||
convertColumnData(level, baseX + x, baseZ + z, columnArrayView, fullArrayView, 1);
|
||||
|
||||
if (fullArrayView.doesColumnExist())
|
||||
{
|
||||
LodUtil.assertTrue(columnSource.doesDataPointExist(x, z));
|
||||
}
|
||||
convertColumnData(level, baseX + x, baseZ + z, columnArrayView, fullArrayView);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -190,11 +185,9 @@ public class FullDataToRenderDataTransformer
|
||||
}
|
||||
|
||||
ColumnArrayView columnArrayView = columnSource.getVerticalDataPointView(x, z);
|
||||
convertColumnData(level, baseX + x, baseZ + z, columnArrayView, fullArrayView, 1);
|
||||
convertColumnData(level, baseX + x, baseZ + z, columnArrayView, fullArrayView);
|
||||
|
||||
columnSource.fillDebugFlag(x, z, 1, 1, ColumnRenderSource.DebugSourceFlag.SPARSE);
|
||||
if (fullArrayView.doesColumnExist())
|
||||
LodUtil.assertTrue(columnSource.doesDataPointExist(x, z));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -229,7 +222,7 @@ public class FullDataToRenderDataTransformer
|
||||
|
||||
|
||||
// TODO what does this mean?
|
||||
private static void iterateAndConvert(IDhClientLevel level, int blockX, int blockZ, int genMode, ColumnArrayView column, SingleColumnFullDataAccessor data)
|
||||
private static void iterateAndConvert(IDhClientLevel level, int blockX, int blockZ, ColumnArrayView column, SingleColumnFullDataAccessor data)
|
||||
{
|
||||
boolean avoidSolidBlocks = (Config.Client.Advanced.Graphics.Quality.blocksToIgnore.get() == EBlocksToAvoid.NON_COLLIDING);
|
||||
boolean colorBelowWithAvoidedBlocks = Config.Client.Advanced.Graphics.Quality.tintWithAvoidedBlocks.get();
|
||||
@@ -308,7 +301,7 @@ public class FullDataToRenderDataTransformer
|
||||
|
||||
// add the block
|
||||
isVoid = false;
|
||||
long columnData = RenderDataPointUtil.createDataPoint(bottomY + blockHeight, bottomY, color, light, genMode);
|
||||
long columnData = RenderDataPointUtil.createDataPoint(bottomY + blockHeight, bottomY, color, light, block.getIrisBlockMaterialId());
|
||||
column.set(columnOffset, columnData);
|
||||
columnOffset++;
|
||||
}
|
||||
@@ -316,12 +309,12 @@ public class FullDataToRenderDataTransformer
|
||||
|
||||
if (isVoid)
|
||||
{
|
||||
column.set(0, RenderDataPointUtil.createVoidDataPoint((byte) genMode));
|
||||
column.set(0, RenderDataPointUtil.createVoidDataPoint());
|
||||
}
|
||||
}
|
||||
|
||||
// TODO what does this mean?
|
||||
public static void convertColumnData(IDhClientLevel level, int blockX, int blockZ, ColumnArrayView columnArrayView, SingleColumnFullDataAccessor fullArrayView, int genMode)
|
||||
public static void convertColumnData(IDhClientLevel level, int blockX, int blockZ, ColumnArrayView columnArrayView, SingleColumnFullDataAccessor fullArrayView)
|
||||
{
|
||||
if (!fullArrayView.doesColumnExist())
|
||||
{
|
||||
@@ -337,12 +330,12 @@ public class FullDataToRenderDataTransformer
|
||||
if (dataTotalLength > columnArrayView.verticalSize())
|
||||
{
|
||||
ColumnArrayView totalColumnData = new ColumnArrayView(new long[dataTotalLength], dataTotalLength, 0, dataTotalLength);
|
||||
iterateAndConvert(level, blockX, blockZ, genMode, totalColumnData, fullArrayView);
|
||||
iterateAndConvert(level, blockX, blockZ, totalColumnData, fullArrayView);
|
||||
columnArrayView.changeVerticalSizeFrom(totalColumnData);
|
||||
}
|
||||
else
|
||||
{
|
||||
iterateAndConvert(level, blockX, blockZ, genMode, columnArrayView, fullArrayView); //Directly use the arrayView since it fits.
|
||||
iterateAndConvert(level, blockX, blockZ, columnArrayView, fullArrayView); //Directly use the arrayView since it fits.
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-2
@@ -275,7 +275,6 @@ public abstract class AbstractDataSourceHandler<TDataSource extends IDataSource<
|
||||
// done to prevent queueing saves while the current queue is being cleared
|
||||
if (this.isShutdown)
|
||||
{
|
||||
LOGGER.warn("Attempted to queue save for section ["+pos+"] while the handler is being shut down. Some data for that position may be lost.");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -307,7 +306,7 @@ public abstract class AbstractDataSourceHandler<TDataSource extends IDataSource<
|
||||
AbstractDataSourceHandler.this.writeDataSourceToFile(finalDataSource);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
catch (Exception e) // this can throw errors (not exceptions) when installed in Iris' dev environment for some reason due to an issue with LZ4's compression library
|
||||
{
|
||||
LOGGER.error("Failed to save updated data for section ["+pos+"], error: ["+e.getMessage()+"]", e);
|
||||
}
|
||||
|
||||
+8
-1
@@ -195,7 +195,14 @@ public class GeneratedFullDataFileHandler extends FullDataFileHandler
|
||||
ArrayList<CompletableFuture<WorldGenResult>> taskFutureList = new ArrayList<>();
|
||||
for (DhSectionPos genPos : genPosList)
|
||||
{
|
||||
// queue each gen task
|
||||
// try not to re-queue already generating tasks
|
||||
if (this.generatingDataSourceByPos.containsKey(genPos))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
// queue each new gen task
|
||||
GenTask genTask = new GenTask(dataSource.getSectionPos(), new WeakReference<>(dataSource));
|
||||
CompletableFuture<WorldGenResult> worldGenFuture = worldGenQueue.submitGenTask(genPos, dataSource.getDataDetailLevel(), genTask);
|
||||
worldGenFuture.whenComplete((genTaskResult, ex) ->
|
||||
|
||||
+1
-1
@@ -26,7 +26,7 @@ import com.seibel.distanthorizons.core.pos.DhBlockPos;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.IWrapperFactory;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
|
||||
@@ -19,6 +19,9 @@
|
||||
|
||||
package com.seibel.distanthorizons.core.jar;
|
||||
|
||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IModChecker;
|
||||
import com.seibel.distanthorizons.coreapi.ModInfo;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -48,10 +51,18 @@ public class JarUtils
|
||||
try
|
||||
{
|
||||
jarFile = new File(JarUtils.class.getProtectionDomain().getCodeSource().getLocation().toURI()); // Always safe
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOGGER.warn("Unable to get jarFile, Error: "+e.getMessage(), e);
|
||||
try
|
||||
{
|
||||
LOGGER.warn("Unable to get the jar file, trying backup method... Error: "+e.getMessage(), e);
|
||||
jarFile = SingletonInjector.INSTANCE.get(IModChecker.class).modLocation(ModInfo.ID);
|
||||
}
|
||||
catch (Exception f)
|
||||
{
|
||||
LOGGER.warn("Backup jar file getter failed. Error: "+f.getMessage(), f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
package com.seibel.distanthorizons.core.level;
|
||||
|
||||
import com.seibel.distanthorizons.api.enums.rendering.EDebugRendering;
|
||||
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiRenderParam;
|
||||
import com.seibel.distanthorizons.core.config.Config;
|
||||
import com.seibel.distanthorizons.core.dataObjects.fullData.accessor.ChunkSizedFullDataAccessor;
|
||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||
@@ -41,7 +42,6 @@ import com.seibel.distanthorizons.coreapi.util.math.Mat4f;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
public class ClientLevelModule implements Closeable
|
||||
@@ -142,7 +142,7 @@ public class ClientLevelModule implements Closeable
|
||||
return this.ClientRenderStateRef.get() != null;
|
||||
}
|
||||
|
||||
public void render(Mat4f mcModelViewMatrix, Mat4f mcProjectionMatrix, float partialTicks, IProfilerWrapper profiler)
|
||||
public void render(DhApiRenderParam renderEventParam, IProfilerWrapper profiler)
|
||||
{
|
||||
ClientRenderState ClientRenderState = this.ClientRenderStateRef.get();
|
||||
if (ClientRenderState == null)
|
||||
@@ -150,7 +150,18 @@ public class ClientLevelModule implements Closeable
|
||||
// either the renderer hasn't been started yet, or is being reloaded
|
||||
return;
|
||||
}
|
||||
ClientRenderState.renderer.drawLODs(ClientRenderState.clientLevelWrapper, mcModelViewMatrix, mcProjectionMatrix, partialTicks, profiler);
|
||||
ClientRenderState.renderer.drawLods(ClientRenderState.clientLevelWrapper, renderEventParam, profiler);
|
||||
}
|
||||
|
||||
public void renderDeferred(DhApiRenderParam renderEventParam, IProfilerWrapper profiler)
|
||||
{
|
||||
ClientRenderState ClientRenderState = this.ClientRenderStateRef.get();
|
||||
if (ClientRenderState == null)
|
||||
{
|
||||
// either the renderer hasn't been started yet, or is being reloaded
|
||||
return;
|
||||
}
|
||||
ClientRenderState.renderer.drawDeferredLods(ClientRenderState.clientLevelWrapper, renderEventParam, profiler);
|
||||
}
|
||||
|
||||
public void stopRenderer()
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
package com.seibel.distanthorizons.core.level;
|
||||
|
||||
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiRenderParam;
|
||||
import com.seibel.distanthorizons.core.config.AppliedConfigState;
|
||||
import com.seibel.distanthorizons.core.config.Config;
|
||||
import com.seibel.distanthorizons.core.dataObjects.fullData.accessor.ChunkSizedFullDataAccessor;
|
||||
@@ -43,7 +44,6 @@ import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IProfilerWrap
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IBiomeWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
|
||||
import com.seibel.distanthorizons.coreapi.util.math.Mat4f;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -203,10 +203,12 @@ public class DhClientLevel extends DhLevel implements IDhClientLevel
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(Mat4f mcModelViewMatrix, Mat4f mcProjectionMatrix, float partialTicks, IProfilerWrapper profiler)
|
||||
{
|
||||
this.clientside.render(mcModelViewMatrix, mcProjectionMatrix, partialTicks, profiler);
|
||||
}
|
||||
public void render(DhApiRenderParam renderEventParam, IProfilerWrapper profiler)
|
||||
{ this.clientside.render(renderEventParam, profiler); }
|
||||
|
||||
@Override
|
||||
public void renderDeferred(DhApiRenderParam renderEventParam, IProfilerWrapper profiler)
|
||||
{ this.clientside.renderDeferred(renderEventParam, profiler); }
|
||||
|
||||
|
||||
|
||||
@@ -215,25 +217,25 @@ public class DhClientLevel extends DhLevel implements IDhClientLevel
|
||||
//================//
|
||||
|
||||
@Override
|
||||
public int computeBaseColor(DhBlockPos pos, IBiomeWrapper biome, IBlockStateWrapper block) { return this.levelWrapper.computeBaseColor(pos, biome, block); }
|
||||
public int computeBaseColor(DhBlockPos pos, IBiomeWrapper biome, IBlockStateWrapper block) { return levelWrapper.computeBaseColor(pos, biome, block); }
|
||||
|
||||
@Override
|
||||
public IClientLevelWrapper getClientLevelWrapper() { return this.levelWrapper; }
|
||||
public IClientLevelWrapper getClientLevelWrapper() { return levelWrapper; }
|
||||
|
||||
@Override
|
||||
public void clearRenderCache()
|
||||
{
|
||||
this.clientside.clearRenderCache();
|
||||
clientside.clearRenderCache();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ILevelWrapper getLevelWrapper() { return this.levelWrapper; }
|
||||
public ILevelWrapper getLevelWrapper() { return levelWrapper; }
|
||||
|
||||
@Override
|
||||
public void updateDataSourcesWithChunkData(ChunkSizedFullDataAccessor data) { this.clientside.updateDataSourcesWithChunkData(data); }
|
||||
|
||||
@Override
|
||||
public int getMinY() { return this.levelWrapper.getMinHeight(); }
|
||||
public int getMinY() { return levelWrapper.getMinHeight(); }
|
||||
|
||||
@Override
|
||||
public void close()
|
||||
@@ -244,8 +246,8 @@ public class DhClientLevel extends DhLevel implements IDhClientLevel
|
||||
}
|
||||
this.clientside.close();
|
||||
super.close();
|
||||
this.dataFileHandler.close();
|
||||
LOGGER.info("Closed " + DhClientLevel.class.getSimpleName() + " for " + this.levelWrapper);
|
||||
dataFileHandler.close();
|
||||
LOGGER.info("Closed " + DhClientLevel.class.getSimpleName() + " for " + levelWrapper);
|
||||
}
|
||||
|
||||
//=======================//
|
||||
@@ -255,13 +257,13 @@ public class DhClientLevel extends DhLevel implements IDhClientLevel
|
||||
@Override
|
||||
public IFullDataSourceProvider getFileHandler()
|
||||
{
|
||||
return this.dataFileHandler;
|
||||
return dataFileHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbstractSaveStructure getSaveStructure()
|
||||
{
|
||||
return this.saveStructure;
|
||||
return saveStructure;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
package com.seibel.distanthorizons.core.level;
|
||||
|
||||
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiRenderParam;
|
||||
import com.seibel.distanthorizons.core.dataObjects.fullData.accessor.ChunkSizedFullDataAccessor;
|
||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||
import com.seibel.distanthorizons.core.file.fullDatafile.IFullDataSourceProvider;
|
||||
@@ -81,10 +82,12 @@ public class DhClientServerLevel extends DhLevel implements IDhClientLevel, IDhS
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(Mat4f mcModelViewMatrix, Mat4f mcProjectionMatrix, float partialTicks, IProfilerWrapper profiler)
|
||||
{
|
||||
clientside.render(mcModelViewMatrix, mcProjectionMatrix, partialTicks, profiler);
|
||||
}
|
||||
public void render(DhApiRenderParam renderEventParam, IProfilerWrapper profiler)
|
||||
{ this.clientside.render(renderEventParam, profiler); }
|
||||
|
||||
@Override
|
||||
public void renderDeferred(DhApiRenderParam renderEventParam, IProfilerWrapper profiler)
|
||||
{ this.clientside.renderDeferred(renderEventParam, profiler); }
|
||||
|
||||
@Override
|
||||
public void serverTick() { this.chunkToLodBuilder.tick(); }
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
package com.seibel.distanthorizons.core.level;
|
||||
|
||||
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiRenderParam;
|
||||
import com.seibel.distanthorizons.core.pos.DhBlockPos;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.block.IBlockStateWrapper;
|
||||
import com.seibel.distanthorizons.coreapi.util.math.Mat4f;
|
||||
@@ -30,7 +31,8 @@ public interface IDhClientLevel extends IDhWorldGenLevel
|
||||
{
|
||||
void clientTick();
|
||||
|
||||
void render(Mat4f mcModelViewMatrix, Mat4f mcProjectionMatrix, float partialTicks, IProfilerWrapper profiler);
|
||||
void render(DhApiRenderParam renderEventParam, IProfilerWrapper profiler);
|
||||
void renderDeferred(DhApiRenderParam renderEventParam, IProfilerWrapper profiler);
|
||||
|
||||
int computeBaseColor(DhBlockPos pos, IBiomeWrapper biome, IBlockStateWrapper block);
|
||||
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
package com.seibel.distanthorizons.core.logging.f3;
|
||||
|
||||
import com.seibel.distanthorizons.coreapi.ModInfo;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.util.*;
|
||||
@@ -27,6 +29,8 @@ import java.util.function.Supplier;
|
||||
|
||||
public class F3Screen
|
||||
{
|
||||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
|
||||
private static final String[] DEFAULT_STRING = {
|
||||
"", // blank line for spacing
|
||||
ModInfo.READABLE_NAME + " version: " + ModInfo.VERSION
|
||||
@@ -98,10 +102,18 @@ public class F3Screen
|
||||
|
||||
public void printTo(List<String> list)
|
||||
{
|
||||
String message = this.supplier.get();
|
||||
if (message != null)
|
||||
|
||||
try
|
||||
{
|
||||
list.add(message);
|
||||
String message = this.supplier.get();
|
||||
if (message != null)
|
||||
{
|
||||
list.add(message);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOGGER.error("Unexpected Exception in F3 ["+DynamicMessage.class.getSimpleName()+"], error: "+e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,10 +130,17 @@ public class F3Screen
|
||||
{
|
||||
for (Supplier<String> supplier : this.supplierList)
|
||||
{
|
||||
String message = supplier.get();
|
||||
if (message != null)
|
||||
try
|
||||
{
|
||||
list.add(message);
|
||||
String message = supplier.get();
|
||||
if (message != null)
|
||||
{
|
||||
list.add(message);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOGGER.error("Unexpected Exception in F3 ["+DynamicMessage.class.getSimpleName()+"], error: "+e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -139,10 +158,17 @@ public class F3Screen
|
||||
|
||||
public void printTo(List<String> list)
|
||||
{
|
||||
String[] message = this.supplier.get();
|
||||
if (message != null)
|
||||
try
|
||||
{
|
||||
list.addAll(Arrays.asList(message));
|
||||
String[] message = this.supplier.get();
|
||||
if (message != null)
|
||||
{
|
||||
list.addAll(Arrays.asList(message));
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOGGER.error("Unexpected Exception in F3 ["+DynamicMessage.class.getSimpleName()+"], error: "+e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ package com.seibel.distanthorizons.core.pos;
|
||||
import com.seibel.distanthorizons.core.enums.EDhDirection;
|
||||
import com.seibel.distanthorizons.core.util.LodUtil;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import java.util.Objects;
|
||||
|
||||
public class DhBlockPos
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
package com.seibel.distanthorizons.core.pos;
|
||||
|
||||
import com.seibel.distanthorizons.api.interfaces.override.rendering.IDhApiCullingFrustum;
|
||||
import com.seibel.distanthorizons.coreapi.interfaces.dependencyInjection.IOverrideInjector;
|
||||
import com.seibel.distanthorizons.coreapi.util.math.Mat4f;
|
||||
import org.joml.FrustumIntersection;
|
||||
import org.joml.Matrix4f;
|
||||
import org.joml.Matrix4fc;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
|
||||
public class DhFrustumBounds implements IDhApiCullingFrustum
|
||||
{
|
||||
private final FrustumIntersection frustum;
|
||||
private final Vector3f boundsMin = new Vector3f();
|
||||
private final Vector3f boundsMax = new Vector3f();
|
||||
public float worldMinY;
|
||||
public float worldMaxY;
|
||||
|
||||
|
||||
|
||||
//=============//
|
||||
// constructor //
|
||||
//=============//
|
||||
|
||||
public DhFrustumBounds()
|
||||
{
|
||||
this.frustum = new FrustumIntersection();
|
||||
}
|
||||
|
||||
|
||||
|
||||
//=========//
|
||||
// methods //
|
||||
//=========//
|
||||
|
||||
@Override
|
||||
public void update(int worldMinBlockY, int worldMaxBlockY, Mat4f dhWorldViewProjection)
|
||||
{
|
||||
this.worldMinY = worldMinBlockY;
|
||||
this.worldMaxY = worldMaxBlockY;
|
||||
|
||||
Matrix4f worldViewProjection = new Matrix4f(dhWorldViewProjection.createJomlMatrix());
|
||||
this.frustum.set(worldViewProjection);
|
||||
|
||||
Matrix4fc matWorldViewProjectionInv = new Matrix4f(worldViewProjection).invert();
|
||||
matWorldViewProjectionInv.frustumAabb(this.boundsMin, this.boundsMax);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean intersects(int lodBlockPosMinX, int lodBlockPosMinZ, int lodBlockWidth, int lodDetailLevel)
|
||||
{
|
||||
Vector3f lodMin = new Vector3f(lodBlockPosMinX, this.worldMinY, lodBlockPosMinZ);
|
||||
Vector3f lodMax = new Vector3f(lodBlockPosMinX + lodBlockWidth, this.worldMaxY, lodBlockPosMinZ + lodBlockWidth);
|
||||
|
||||
if (lodMax.x < this.boundsMin.x || lodMin.x > this.boundsMax.x) return false;
|
||||
if (lodMax.z < this.boundsMin.z || lodMin.z > this.boundsMax.z) return false;
|
||||
if (this.worldMaxY < this.boundsMin.y || this.worldMinY > this.boundsMax.y) return false;
|
||||
|
||||
return this.frustum.testAab(lodMin, lodMax);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//=====================//
|
||||
// overridable methods //
|
||||
//=====================//
|
||||
|
||||
@Override
|
||||
public int getPriority() { return IOverrideInjector.CORE_PRIORITY; }
|
||||
|
||||
}
|
||||
@@ -55,8 +55,10 @@ public class DhLodPos implements Comparable<DhLodPos>
|
||||
// getters //
|
||||
//=========//
|
||||
|
||||
public DhLodUnit getX() { return new DhLodUnit(this.detailLevel, this.x); }
|
||||
public DhLodUnit getZ() { return new DhLodUnit(this.detailLevel, this.z); }
|
||||
/** gets the X position closest to negative infinity */
|
||||
public DhLodUnit getMinX() { return new DhLodUnit(this.detailLevel, this.x); }
|
||||
/** gets the Z position closest to negative infinity */
|
||||
public DhLodUnit getMinZ() { return new DhLodUnit(this.detailLevel, this.z); }
|
||||
|
||||
// Get the width of this pos, measured in the mc block unit. (i.e. detail 0)
|
||||
public int getBlockWidth() { return this.getWidthAtDetail((byte) 0); }
|
||||
@@ -71,10 +73,10 @@ public class DhLodPos implements Comparable<DhLodPos>
|
||||
public DhBlockPos2D getCenterBlockPos()
|
||||
{
|
||||
return new DhBlockPos2D(
|
||||
this.getX().toBlockWidth() + BitShiftUtil.half(this.getBlockWidth()),
|
||||
this.getZ().toBlockWidth() + BitShiftUtil.half(this.getBlockWidth()));
|
||||
this.getMinX().toBlockWidth() + BitShiftUtil.half(this.getBlockWidth()),
|
||||
this.getMinZ().toBlockWidth() + BitShiftUtil.half(this.getBlockWidth()));
|
||||
}
|
||||
public DhBlockPos2D getCornerBlockPos() { return new DhBlockPos2D(this.getX().toBlockWidth(), this.getZ().toBlockWidth()); }
|
||||
public DhBlockPos2D getCornerBlockPos() { return new DhBlockPos2D(this.getMinX().toBlockWidth(), this.getMinZ().toBlockWidth()); }
|
||||
|
||||
/** converts this position to a lower detail level, angled towards the corner position. */
|
||||
public DhLodPos getCornerLodPos(byte newDetail)
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
package com.seibel.distanthorizons.core.render;
|
||||
|
||||
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiRenderParam;
|
||||
import com.seibel.distanthorizons.core.util.LodUtil;
|
||||
import com.seibel.distanthorizons.core.util.objects.StatsMap;
|
||||
import com.seibel.distanthorizons.core.render.renderer.LodRenderer;
|
||||
@@ -31,9 +32,9 @@ public abstract class AbstractRenderBuffer implements AutoCloseable
|
||||
|
||||
// ========== Called by render thread ==========
|
||||
/** @return true if something was rendered, false otherwise */
|
||||
public abstract boolean renderOpaque(LodRenderer renderContext);
|
||||
public abstract boolean renderOpaque(LodRenderer renderContext, DhApiRenderParam renderEventParam);
|
||||
/** @return true if something was rendered, false otherwise */
|
||||
public abstract boolean renderTransparent(LodRenderer renderContext);
|
||||
public abstract boolean renderTransparent(LodRenderer renderContext, DhApiRenderParam renderEventParam);
|
||||
|
||||
// ========== Called by any thread. (thread safe) ==========
|
||||
|
||||
@@ -52,9 +53,8 @@ public abstract class AbstractRenderBuffer implements AutoCloseable
|
||||
|
||||
|
||||
|
||||
public static final int DEFAULT_MEMORY_ALLOCATION = (LodUtil.LOD_VERTEX_FORMAT.getByteSize() * 3) * 8;
|
||||
public static final int QUADS_BYTE_SIZE = LodUtil.LOD_VERTEX_FORMAT.getByteSize() * 4;
|
||||
public static final int MAX_QUADS_PER_BUFFER = (1024 * 1024 * 1) / QUADS_BYTE_SIZE;
|
||||
public static final int QUADS_BYTE_SIZE = LodUtil.LOD_VERTEX_FORMAT.getByteSize() * 4; // TODO what does the 4 represent
|
||||
public static final int MAX_QUADS_PER_BUFFER = (1024 * 1024 * 1) / QUADS_BYTE_SIZE; // TODO what do these multiples represent?
|
||||
public static final int FULL_SIZED_BUFFER = MAX_QUADS_PER_BUFFER * QUADS_BYTE_SIZE;
|
||||
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||
import com.seibel.distanthorizons.core.level.IDhClientLevel;
|
||||
import com.seibel.distanthorizons.core.level.IDhLevel;
|
||||
import com.seibel.distanthorizons.core.render.renderer.LodRenderer;
|
||||
import com.seibel.distanthorizons.core.util.RenderUtil;
|
||||
import com.seibel.distanthorizons.core.world.AbstractDhWorld;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
|
||||
import org.lwjgl.opengl.GL32;
|
||||
@@ -42,7 +43,7 @@ public class DhApiRenderProxy implements IDhApiRenderProxy
|
||||
|
||||
private static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class);
|
||||
|
||||
public int targetFrameBufferOverride = -1;
|
||||
private boolean deferTransparentRendering = false;
|
||||
|
||||
|
||||
|
||||
@@ -82,29 +83,6 @@ public class DhApiRenderProxy implements IDhApiRenderProxy
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public DhApiResult<Integer> getDhFrameBufferId()
|
||||
{
|
||||
int activeFrameBuffer = LodRenderer.getActiveFramebufferId();
|
||||
return (activeFrameBuffer == -1) ? DhApiResult.createFail("DH's FrameBuffer hasn't been created and/or bound yet.", -1) : DhApiResult.createSuccess(activeFrameBuffer);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public DhApiResult<Void> setTargetFrameBufferId(int frameBufferId)
|
||||
{
|
||||
if (frameBufferId != -1 && !GL32.glIsFramebuffer(frameBufferId))
|
||||
{
|
||||
return DhApiResult.createFail("FrameBufferID ["+frameBufferId+"] isn't a valid FrameBuffer ID.");
|
||||
}
|
||||
|
||||
this.targetFrameBufferOverride = frameBufferId;
|
||||
return DhApiResult.createSuccess();
|
||||
}
|
||||
@Override
|
||||
public DhApiResult<Integer> getTargetFrameBufferId() { return (this.targetFrameBufferOverride == -1) ? DhApiResult.createSuccess("Default MC FrameBuffer in use.", MC_RENDER.getTargetFrameBuffer()) : DhApiResult.createSuccess("FrameBuffer override active.", this.targetFrameBufferOverride); }
|
||||
|
||||
|
||||
@Override
|
||||
public DhApiResult<Integer> getDhDepthTextureId()
|
||||
{
|
||||
@@ -118,4 +96,13 @@ public class DhApiRenderProxy implements IDhApiRenderProxy
|
||||
return (activeTexture == -1) ? DhApiResult.createFail("DH's color texture hasn't been created and/or bound yet.", -1) : DhApiResult.createSuccess(activeTexture);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setDeferTransparentRendering(boolean deferTransparentRendering) { this.deferTransparentRendering = deferTransparentRendering; }
|
||||
@Override
|
||||
public boolean getDeferTransparentRendering() { return this.deferTransparentRendering; }
|
||||
|
||||
@Override
|
||||
public float getNearClipPlaneDistanceInBlocks(float partialTicks) { return RenderUtil.getNearClipPlaneDistanceInBlocks(partialTicks); }
|
||||
|
||||
}
|
||||
|
||||
@@ -297,6 +297,9 @@ public class LodRenderSection implements IDebugRenderable
|
||||
}
|
||||
}
|
||||
|
||||
// probably used by Iris
|
||||
public void disposeBufferForRecreate() { this.disposeActiveBuffer = true; }
|
||||
|
||||
|
||||
/**
|
||||
* Try and swap in new render buffer for this section. Note that before this call, there should be no other
|
||||
|
||||
+149
-30
@@ -19,18 +19,29 @@
|
||||
|
||||
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.methods.events.sharedParameterObjects.DhApiRenderParam;
|
||||
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.logging.DhLoggerBuilder;
|
||||
import com.seibel.distanthorizons.core.logging.f3.F3Screen;
|
||||
import com.seibel.distanthorizons.core.pos.DhFrustumBounds;
|
||||
import com.seibel.distanthorizons.core.pos.DhLodPos;
|
||||
import com.seibel.distanthorizons.core.pos.DhSectionPos;
|
||||
import com.seibel.distanthorizons.core.pos.Pos2D;
|
||||
import com.seibel.distanthorizons.core.render.renderer.LodRenderer;
|
||||
import com.seibel.distanthorizons.core.util.LodUtil;
|
||||
import com.seibel.distanthorizons.core.util.objects.SortedArraySet;
|
||||
import com.seibel.distanthorizons.core.util.objects.quadTree.QuadNode;
|
||||
import com.seibel.distanthorizons.core.render.renderer.LodRenderer;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IIrisAccessor;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
||||
import com.seibel.distanthorizons.coreapi.interfaces.dependencyInjection.IOverrideInjector;
|
||||
import com.seibel.distanthorizons.coreapi.util.math.Mat4f;
|
||||
import com.seibel.distanthorizons.coreapi.util.math.Vec3f;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.joml.Matrix4fc;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.Iterator;
|
||||
@@ -45,6 +56,8 @@ public class RenderBufferHandler implements AutoCloseable
|
||||
{
|
||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
||||
|
||||
private static final IIrisAccessor IRIS_ACCESSOR = ModAccessorInjector.INSTANCE.get(IIrisAccessor.class);
|
||||
|
||||
/** contains all relevant data */
|
||||
public final LodQuadTree lodQuadTree;
|
||||
|
||||
@@ -53,7 +66,12 @@ public class RenderBufferHandler implements AutoCloseable
|
||||
|
||||
private final AtomicBoolean rebuildAllBuffers = new AtomicBoolean(false);
|
||||
|
||||
public F3Screen.DynamicMessage f3Message;
|
||||
public F3Screen.MultiDynamicMessage f3Message;
|
||||
|
||||
private int visibleBufferCount;
|
||||
private int culledBufferCount;
|
||||
private int shadowVisibleBufferCount;
|
||||
private int shadowCulledBufferCount;
|
||||
|
||||
|
||||
|
||||
@@ -64,12 +82,48 @@ public class RenderBufferHandler implements AutoCloseable
|
||||
public RenderBufferHandler(LodQuadTree lodQuadTree)
|
||||
{
|
||||
this.lodQuadTree = lodQuadTree;
|
||||
this.culledBufferCount = 0;
|
||||
|
||||
this.f3Message = new F3Screen.DynamicMessage(() -> LodUtil.formatLog("Rendered Buffer Count: " + this.loadedNearToFarBuffers.size()));
|
||||
IDhApiCullingFrustum coreFrustum = DhApi.overrides.get(IDhApiCullingFrustum.class, IOverrideInjector.CORE_PRIORITY);
|
||||
if (coreFrustum == null)
|
||||
{
|
||||
DhApi.overrides.bind(IDhApiCullingFrustum.class, new DhFrustumBounds());
|
||||
}
|
||||
|
||||
|
||||
this.f3Message = new F3Screen.MultiDynamicMessage(
|
||||
() ->
|
||||
{
|
||||
String countText = this.visibleBufferCount + "";
|
||||
if (!Config.Client.Advanced.Graphics.AdvancedGraphics.disableFrustumCulling.get())
|
||||
{
|
||||
countText += "/" + (this.visibleBufferCount + this.culledBufferCount);
|
||||
}
|
||||
return LodUtil.formatLog("Rendered Buffer Count: " + countText);
|
||||
},
|
||||
() ->
|
||||
{
|
||||
boolean hasIrisShaders = (IRIS_ACCESSOR != null && IRIS_ACCESSOR.isShaderPackInUse());
|
||||
if (!hasIrisShaders)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
String countText = this.shadowVisibleBufferCount + "";
|
||||
if (!Config.Client.Advanced.Graphics.AdvancedGraphics.disableFrustumCulling.get())
|
||||
{
|
||||
countText += "/" + (this.shadowVisibleBufferCount + this.shadowCulledBufferCount);
|
||||
}
|
||||
return LodUtil.formatLog("Shadow Buffer Count: " + countText);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
//=================//
|
||||
// render building //
|
||||
//=================//
|
||||
|
||||
/**
|
||||
* The following buildRenderList sorting method is based on the following reddit post: <br>
|
||||
* <a href="https://www.reddit.com/r/VoxelGameDev/comments/a0l8zc/correct_depthordering_for_translucent_discrete/">correct_depth_ordering_for_translucent_discrete</a> <br><br>
|
||||
@@ -77,7 +131,7 @@ public class RenderBufferHandler implements AutoCloseable
|
||||
* TODO: This might get locked by update() causing move() call. Is there a way to avoid this?
|
||||
* Maybe dupe the base list and use atomic swap on render? Or is this not worth it?
|
||||
*/
|
||||
public void buildRenderListAndUpdateSections(Vec3f lookForwardVector)
|
||||
public void buildRenderListAndUpdateSections(IClientLevelWrapper clientLevelWrapper, Matrix4fc matWorldViewProjection, Vec3f lookForwardVector)
|
||||
{
|
||||
EDhDirection[] axisDirections = new EDhDirection[3];
|
||||
|
||||
@@ -178,11 +232,37 @@ public class RenderBufferHandler implements AutoCloseable
|
||||
|
||||
return loadedBufferA.pos.getDetailLevel() - loadedBufferB.pos.getDetailLevel(); // If all else fails, sort by detail
|
||||
};
|
||||
|
||||
// Build the sorted list
|
||||
this.loadedNearToFarBuffers = new SortedArraySet<>((a, b) -> -farToNearComparator.compare(a, b)); // TODO is the comparator named wrong?
|
||||
|
||||
// Update the sections
|
||||
|
||||
|
||||
// update the frustum if necessary
|
||||
boolean enableFrustumCulling = !Config.Client.Advanced.Graphics.AdvancedGraphics.disableFrustumCulling.get();
|
||||
IDhApiCullingFrustum frustum = DhApi.overrides.get(IDhApiCullingFrustum.class, IOverrideInjector.CORE_PRIORITY);
|
||||
if (enableFrustumCulling)
|
||||
{
|
||||
int worldMinY = clientLevelWrapper.getMinHeight();
|
||||
int worldHeight = clientLevelWrapper.getHeight();
|
||||
|
||||
frustum.update(worldMinY, worldMinY + worldHeight, new Mat4f(matWorldViewProjection));
|
||||
}
|
||||
|
||||
|
||||
|
||||
//=========================//
|
||||
// Update the section list //
|
||||
//=========================//
|
||||
|
||||
boolean isShadowPass = (IRIS_ACCESSOR != null && IRIS_ACCESSOR.isRenderingShadowPass());
|
||||
if (isShadowPass)
|
||||
{
|
||||
this.shadowCulledBufferCount = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.culledBufferCount = 0;
|
||||
}
|
||||
|
||||
boolean rebuildAllBuffers = this.rebuildAllBuffers.getAndSet(false);
|
||||
Iterator<QuadNode<LodRenderSection>> nodeIterator = this.lodQuadTree.nodeIterator();
|
||||
while (nodeIterator.hasNext())
|
||||
@@ -191,26 +271,53 @@ public class RenderBufferHandler implements AutoCloseable
|
||||
|
||||
DhSectionPos sectionPos = node.sectionPos;
|
||||
LodRenderSection renderSection = node.value;
|
||||
if (renderSection == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
if (renderSection != null)
|
||||
if (enableFrustumCulling)
|
||||
{
|
||||
if (rebuildAllBuffers)
|
||||
DhLodPos lodBounds = renderSection.pos.getSectionBBoxPos();
|
||||
int blockMinX = lodBounds.getMinX().toBlockWidth();
|
||||
int blockMinZ = lodBounds.getMinZ().toBlockWidth();
|
||||
int lodBlockWidth = lodBounds.getBlockWidth();
|
||||
if (!frustum.intersects(blockMinX, blockMinZ, lodBlockWidth, lodBounds.detailLevel))
|
||||
{
|
||||
renderSection.markBufferDirty();
|
||||
}
|
||||
renderSection.tryBuildAndSwapBuffer();
|
||||
|
||||
if (renderSection.isRenderingEnabled())
|
||||
{
|
||||
AbstractRenderBuffer buffer = renderSection.activeRenderBufferRef.get();
|
||||
if (buffer != null)
|
||||
if (isShadowPass)
|
||||
{
|
||||
this.loadedNearToFarBuffers.add(new LoadedRenderBuffer(buffer, sectionPos));
|
||||
this.shadowCulledBufferCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.culledBufferCount++;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (rebuildAllBuffers)
|
||||
{
|
||||
renderSection.markBufferDirty();
|
||||
}
|
||||
|
||||
renderSection.tryBuildAndSwapBuffer();
|
||||
if (!renderSection.isRenderingEnabled())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
AbstractRenderBuffer buffer = renderSection.activeRenderBufferRef.get();
|
||||
if (buffer == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
this.loadedNearToFarBuffers.add(new LoadedRenderBuffer(buffer, sectionPos));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -218,29 +325,39 @@ public class RenderBufferHandler implements AutoCloseable
|
||||
renderSection.markBufferDirty();
|
||||
}
|
||||
}
|
||||
|
||||
if (isShadowPass)
|
||||
{
|
||||
this.shadowVisibleBufferCount = this.loadedNearToFarBuffers.size();
|
||||
}
|
||||
else
|
||||
{
|
||||
this.visibleBufferCount = this.loadedNearToFarBuffers.size();
|
||||
}
|
||||
}
|
||||
|
||||
public void renderOpaque(LodRenderer renderContext)
|
||||
public void MarkAllBuffersDirty() { this.rebuildAllBuffers.set(true); }
|
||||
|
||||
|
||||
|
||||
//================//
|
||||
// render methods //
|
||||
//================//
|
||||
|
||||
public void renderOpaque(LodRenderer renderContext, DhApiRenderParam renderEventParam)
|
||||
{
|
||||
//TODO: Directional culling
|
||||
this.loadedNearToFarBuffers.forEach(loadedBuffer -> loadedBuffer.buffer.renderOpaque(renderContext));
|
||||
this.loadedNearToFarBuffers.forEach(loadedBuffer -> loadedBuffer.buffer.renderOpaque(renderContext, renderEventParam));
|
||||
}
|
||||
public void renderTransparent(LodRenderer renderContext)
|
||||
public void renderTransparent(LodRenderer renderContext, DhApiRenderParam renderEventParam)
|
||||
{
|
||||
//TODO: Directional culling
|
||||
ListIterator<LoadedRenderBuffer> iter = this.loadedNearToFarBuffers.listIterator(this.loadedNearToFarBuffers.size());
|
||||
while (iter.hasPrevious())
|
||||
{
|
||||
LoadedRenderBuffer loadedBuffer = iter.previous();
|
||||
loadedBuffer.buffer.renderTransparent(renderContext);
|
||||
loadedBuffer.buffer.renderTransparent(renderContext, renderEventParam);
|
||||
}
|
||||
}
|
||||
|
||||
public void MarkAllBuffersDirty()
|
||||
{
|
||||
rebuildAllBuffers.set(true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//=========//
|
||||
@@ -259,6 +376,8 @@ public class RenderBufferHandler implements AutoCloseable
|
||||
renderSection.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
this.f3Message.close();
|
||||
}
|
||||
|
||||
|
||||
|
||||
+2
-5
@@ -139,7 +139,8 @@ public class GLBuffer implements AutoCloseable
|
||||
BUFFER_ID_TO_PHANTOM.remove(id);
|
||||
}
|
||||
|
||||
// destroy the buffer if it exists
|
||||
// destroy the buffer if it exists,
|
||||
// the buffer may not exist if the destroy method is called twice
|
||||
if (GL32.glIsBuffer(id))
|
||||
{
|
||||
GL32.glDeleteBuffers(id);
|
||||
@@ -147,10 +148,6 @@ public class GLBuffer implements AutoCloseable
|
||||
|
||||
//LOGGER.info("destroyed buffer ["+id+"], remaining: ["+BUFFER_ID_TO_PHANTOM.size()+"]");
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGGER.warn("Attempted to destroy invalid buffer ["+id+"], remaining: ["+BUFFER_ID_TO_PHANTOM.size()+"]");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+45
-38
@@ -1,11 +1,11 @@
|
||||
package com.seibel.distanthorizons.core.render.glObject.texture;
|
||||
|
||||
import com.seibel.distanthorizons.api.interfaces.override.rendering.IDhApiFramebuffer;
|
||||
import it.unimi.dsi.fastutil.ints.Int2IntArrayMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2IntMap;
|
||||
import org.lwjgl.opengl.GL32;
|
||||
|
||||
// TODO lowercase
|
||||
public class DhFramebuffer
|
||||
public class DhFramebuffer implements IDhApiFramebuffer
|
||||
{
|
||||
private final Int2IntMap attachments;
|
||||
private final int maxDrawBuffers;
|
||||
@@ -46,97 +46,104 @@ public class DhFramebuffer
|
||||
// methods //
|
||||
//=========//
|
||||
|
||||
public void addDepthAttachment(int texture, EDhDepthBufferFormat depthBufferFormat)
|
||||
@Override
|
||||
public void addDepthAttachment(int textureId, boolean isCombinedStencil)
|
||||
{
|
||||
bind();
|
||||
this.bind();
|
||||
|
||||
int depthAttachment = isCombinedStencil ? GL32.GL_DEPTH_STENCIL_ATTACHMENT : GL32.GL_DEPTH_ATTACHMENT;
|
||||
GL32.glFramebufferTexture2D(GL32.GL_FRAMEBUFFER, depthAttachment, GL32.GL_TEXTURE_2D, textureId, 0);
|
||||
|
||||
if (depthBufferFormat.isCombinedStencil())
|
||||
{
|
||||
GL32.glFramebufferTexture2D(GL32.GL_FRAMEBUFFER, GL32.GL_DEPTH_STENCIL_ATTACHMENT, GL32.GL_TEXTURE_2D, texture, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
GL32.glFramebufferTexture2D(GL32.GL_FRAMEBUFFER, GL32.GL_DEPTH_ATTACHMENT, GL32.GL_TEXTURE_2D, texture, 0);
|
||||
}
|
||||
|
||||
this.hasDepthAttachment = true;
|
||||
}
|
||||
|
||||
public void addColorAttachment(int index, int texture)
|
||||
|
||||
@Override
|
||||
public void addColorAttachment(int textureIndex, int textureId)
|
||||
{
|
||||
int fb = id;
|
||||
bind();
|
||||
this.bind();
|
||||
|
||||
GL32.glFramebufferTexture2D(GL32.GL_FRAMEBUFFER, GL32.GL_COLOR_ATTACHMENT0 + index, GL32.GL_TEXTURE_2D, texture, 0);
|
||||
attachments.put(index, texture);
|
||||
GL32.glFramebufferTexture2D(GL32.GL_FRAMEBUFFER, GL32.GL_COLOR_ATTACHMENT0 + textureIndex, GL32.GL_TEXTURE_2D, textureId, 0);
|
||||
this.attachments.put(textureIndex, textureId);
|
||||
}
|
||||
|
||||
public void noDrawBuffers()
|
||||
{
|
||||
bind();
|
||||
this.bind();
|
||||
GL32.glDrawBuffers(new int[]{GL32.GL_NONE});
|
||||
}
|
||||
|
||||
public void drawBuffers(int[] buffers)
|
||||
{
|
||||
int[] glBuffers = new int[buffers.length]; int index = 0;
|
||||
int[] glBuffers = new int[buffers.length];
|
||||
int index = 0;
|
||||
|
||||
if (buffers.length > maxDrawBuffers)
|
||||
if (buffers.length > this.maxDrawBuffers)
|
||||
{
|
||||
throw new IllegalArgumentException("Cannot write to more than " + maxDrawBuffers + " draw buffers on this GPU");
|
||||
throw new IllegalArgumentException("Cannot write to more than " + this.maxDrawBuffers + " draw buffers on this GPU");
|
||||
}
|
||||
|
||||
for (int buffer : buffers)
|
||||
{
|
||||
if (buffer >= maxColorAttachments)
|
||||
if (buffer >= this.maxColorAttachments)
|
||||
{
|
||||
throw new IllegalArgumentException("Only " + maxColorAttachments + " color attachments are supported on this GPU, but an attempt was made to write to a color attachment with index " + buffer);
|
||||
throw new IllegalArgumentException("Only " + this.maxColorAttachments + " color attachments are supported on this GPU, but an attempt was made to write to a color attachment with index " + buffer);
|
||||
}
|
||||
|
||||
glBuffers[index++] = GL32.GL_COLOR_ATTACHMENT0 + buffer;
|
||||
}
|
||||
|
||||
bind();
|
||||
this.bind();
|
||||
GL32.glDrawBuffers(new int[]{GL32.GL_NONE});
|
||||
}
|
||||
|
||||
public void readBuffer(int buffer)
|
||||
{
|
||||
bind();
|
||||
this.bind();
|
||||
GL32.glReadBuffer(GL32.GL_COLOR_ATTACHMENT0 + buffer);
|
||||
}
|
||||
|
||||
public int getColorAttachment(int index) { return attachments.get(index); }
|
||||
public int getColorAttachment(int index) { return this.attachments.get(index); }
|
||||
|
||||
public boolean hasDepthAttachment() { return hasDepthAttachment; }
|
||||
public boolean hasDepthAttachment() { return this.hasDepthAttachment; }
|
||||
|
||||
@Override
|
||||
public void bind()
|
||||
{
|
||||
if (id == -1)
|
||||
if (this.id == -1)
|
||||
{
|
||||
throw new IllegalStateException("Framebuffer does not exist!");
|
||||
}
|
||||
GL32.glBindFramebuffer(GL32.GL_FRAMEBUFFER, id);
|
||||
GL32.glBindFramebuffer(GL32.GL_FRAMEBUFFER, this.id);
|
||||
}
|
||||
|
||||
public void bindAsReadBuffer() { GL32.glBindFramebuffer(GL32.GL_READ_FRAMEBUFFER, id); }
|
||||
public void bindAsReadBuffer() { GL32.glBindFramebuffer(GL32.GL_READ_FRAMEBUFFER, this.id); }
|
||||
|
||||
public void bindAsDrawBuffer() { GL32.glBindFramebuffer(GL32.GL_DRAW_FRAMEBUFFER, id); }
|
||||
public void bindAsDrawBuffer() { GL32.glBindFramebuffer(GL32.GL_DRAW_FRAMEBUFFER, this.id); }
|
||||
|
||||
public void destroyInternal()
|
||||
@Override
|
||||
public void destroy()
|
||||
{
|
||||
GL32.glDeleteFramebuffers(id);
|
||||
GL32.glDeleteFramebuffers(this.id);
|
||||
this.id = -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStatus()
|
||||
{
|
||||
bind();
|
||||
this.bind();
|
||||
int status = GL32.glCheckFramebufferStatus(GL32.GL_FRAMEBUFFER);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
public int getId() { return id; }
|
||||
@Override
|
||||
public int getId() { return this.id; }
|
||||
|
||||
|
||||
|
||||
//=============//
|
||||
// API methods //
|
||||
//=============//
|
||||
|
||||
public boolean overrideThisFrame() { return true; }
|
||||
|
||||
}
|
||||
|
||||
+51
-47
@@ -19,8 +19,9 @@
|
||||
|
||||
package com.seibel.distanthorizons.core.render.renderer;
|
||||
|
||||
import com.seibel.distanthorizons.api.interfaces.override.rendering.IDhApiShaderProgram;
|
||||
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiRenderParam;
|
||||
import com.seibel.distanthorizons.core.config.Config;
|
||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||
import com.seibel.distanthorizons.core.render.glObject.GLProxy;
|
||||
import com.seibel.distanthorizons.core.render.glObject.shader.Shader;
|
||||
import com.seibel.distanthorizons.core.render.glObject.shader.ShaderProgram;
|
||||
@@ -29,18 +30,15 @@ import com.seibel.distanthorizons.core.render.glObject.vertexAttribute.VertexAtt
|
||||
import com.seibel.distanthorizons.core.render.glObject.vertexAttribute.VertexAttributePreGL43;
|
||||
import com.seibel.distanthorizons.core.render.glObject.vertexAttribute.VertexPointer;
|
||||
import com.seibel.distanthorizons.core.util.LodUtil;
|
||||
import com.seibel.distanthorizons.core.render.fog.LodFogConfig;
|
||||
import com.seibel.distanthorizons.core.util.RenderUtil;
|
||||
import com.seibel.distanthorizons.coreapi.util.math.Mat4f;
|
||||
import com.seibel.distanthorizons.coreapi.util.math.Vec3f;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.IVersionConstants;
|
||||
|
||||
public class LodRenderProgram extends ShaderProgram
|
||||
public class LodRenderProgram extends ShaderProgram implements IDhApiShaderProgram
|
||||
{
|
||||
public static final String VERTEX_SHADER_PATH = "shaders/standard.vert";
|
||||
public static final String VERTEX_CURVE_SHADER_PATH = "shaders/curve.vert";
|
||||
public static final String FRAGMENT_SHADER_PATH = "shaders/flat_shaded.frag";
|
||||
private static final IVersionConstants VERSION_CONSTANTS = SingletonInjector.INSTANCE.get(IVersionConstants.class);
|
||||
|
||||
public final AbstractVertexAttribute vao;
|
||||
|
||||
@@ -67,16 +65,19 @@ public class LodRenderProgram extends ShaderProgram
|
||||
// Debug Uniform
|
||||
public final int whiteWorldUniform;
|
||||
|
||||
private final LodFogConfig fogConfig;
|
||||
|
||||
|
||||
//=============//
|
||||
// constructor //
|
||||
//=============//
|
||||
|
||||
// This will bind AbstractVertexAttribute
|
||||
public LodRenderProgram(LodFogConfig fogConfig)
|
||||
public LodRenderProgram()
|
||||
{
|
||||
super(() -> Shader.loadFile(fogConfig.earthCurveRatio != 0 ? VERTEX_CURVE_SHADER_PATH : VERTEX_SHADER_PATH,
|
||||
super(() -> Shader.loadFile(Config.Client.Advanced.Graphics.AdvancedGraphics.earthCurveRatio.get() != 0 ? VERTEX_CURVE_SHADER_PATH : VERTEX_SHADER_PATH,
|
||||
false, new StringBuilder()).toString(),
|
||||
() -> Shader.loadFile(FRAGMENT_SHADER_PATH, false, new StringBuilder()).toString(),
|
||||
"fragColor", new String[]{"vPosition", "color"});
|
||||
this.fogConfig = fogConfig;
|
||||
|
||||
combinedMatUniform = getUniformLocation("combinedMatrix");
|
||||
modelOffsetUniform = getUniformLocation("modelOffset");
|
||||
@@ -106,9 +107,12 @@ public class LodRenderProgram extends ShaderProgram
|
||||
else
|
||||
vao = new VertexAttributePreGL43(); // also binds AbstractVertexAttribute
|
||||
vao.bind();
|
||||
// Now a pos+light.
|
||||
vao.setVertexAttribute(0, 0, VertexPointer.addUnsignedShortsPointer(4, false, true)); // 2+2+2+2
|
||||
vao.setVertexAttribute(0, 1, VertexPointer.addUnsignedBytesPointer(4, true, false)); // +4
|
||||
|
||||
// TODO comment what each attribute represents
|
||||
vao.setVertexAttribute(0, 0, VertexPointer.addUnsignedShortsPointer(4, false, true)); // 2+2+2+2 // TODO probably color, blockpos
|
||||
vao.setVertexAttribute(0, 1, VertexPointer.addUnsignedBytesPointer(4, true, false)); // +4 // TODO ?
|
||||
vao.setVertexAttribute(0, 2, VertexPointer.addUnsignedBytesPointer(4, true, true)); // +4 // TODO probably normal index and Iris block ID
|
||||
|
||||
try
|
||||
{
|
||||
vao.completeAndCheck(vertexByteCount);
|
||||
@@ -120,58 +124,53 @@ public class LodRenderProgram extends ShaderProgram
|
||||
}
|
||||
|
||||
if (earthRadiusUniform != -1) setUniform(earthRadiusUniform,
|
||||
/*6371KM*/ 6371000.0f / fogConfig.earthCurveRatio);
|
||||
/*6371KM*/ 6371000.0f / Config.Client.Advanced.Graphics.AdvancedGraphics.earthCurveRatio.get());
|
||||
|
||||
|
||||
// Noise Uniforms
|
||||
setUniform(noiseEnabledUniform, fogConfig.noiseEnable);
|
||||
setUniform(noiseStepsUniform, fogConfig.noiseSteps);
|
||||
setUniform(noiseIntensityUniform, fogConfig.noiseIntensity);
|
||||
setUniform(noiseDropoffUniform, fogConfig.noiseDropoff);
|
||||
setUniform(noiseEnabledUniform, Config.Client.Advanced.Graphics.NoiseTextureSettings.noiseEnabled.get());
|
||||
setUniform(noiseStepsUniform, Config.Client.Advanced.Graphics.NoiseTextureSettings.noiseSteps.get());
|
||||
setUniform(noiseIntensityUniform, Config.Client.Advanced.Graphics.NoiseTextureSettings.noiseIntensity.get().floatValue());
|
||||
setUniform(noiseDropoffUniform, Config.Client.Advanced.Graphics.NoiseTextureSettings.noiseDropoff.get());
|
||||
}
|
||||
|
||||
// If not usable, return a new LodFogConfig to be constructed
|
||||
public LodFogConfig isShaderUsable() // TODO replace with a config listener, look at LodFogConfig for more info
|
||||
{
|
||||
LodFogConfig newConfig = LodFogConfig.generateFogConfig();
|
||||
if (fogConfig.equals(newConfig))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return newConfig;
|
||||
}
|
||||
|
||||
// Override ShaderProgram.bind()
|
||||
|
||||
//=========//
|
||||
// methods //
|
||||
//=========//
|
||||
|
||||
@Override
|
||||
public void bind()
|
||||
{
|
||||
super.bind();
|
||||
vao.bind();
|
||||
}
|
||||
// Override ShaderProgram.unbind()
|
||||
@Override
|
||||
public void unbind()
|
||||
{
|
||||
super.unbind();
|
||||
vao.unbind();
|
||||
}
|
||||
|
||||
// Override ShaderProgram.free()
|
||||
@Override
|
||||
public void free()
|
||||
{
|
||||
vao.free();
|
||||
super.free();
|
||||
}
|
||||
|
||||
public void bindVertexBuffer(int vbo)
|
||||
{
|
||||
vao.bindBufferToAllBindingPoints(vbo);
|
||||
}
|
||||
@Override
|
||||
public void bindVertexBuffer(int vbo) { this.vao.bindBufferToAllBindingPoints(vbo); }
|
||||
|
||||
public void unbindVertexBuffer()
|
||||
{
|
||||
vao.unbindBuffersFromAllBindingPoint();
|
||||
}
|
||||
public void unbindVertexBuffer() { this.vao.unbindBuffersFromAllBindingPoint(); }
|
||||
|
||||
public void fillUniformData(Mat4f combinedMatrix, int lightmapBindPoint, int worldYOffset, float partialTicks)
|
||||
@Override
|
||||
public void fillUniformData(DhApiRenderParam renderParameters)
|
||||
{
|
||||
Mat4f combinedMatrix = new Mat4f(renderParameters.dhProjectionMatrix);
|
||||
combinedMatrix.multiply(renderParameters.dhModelViewMatrix);
|
||||
|
||||
super.bind();
|
||||
|
||||
// uniforms
|
||||
@@ -179,21 +178,26 @@ public class LodRenderProgram extends ShaderProgram
|
||||
setUniform(mircoOffsetUniform, 0.01f); // 0.01 block offset
|
||||
|
||||
// setUniform(skyLightUniform, skyLight);
|
||||
setUniform(lightMapUniform, lightmapBindPoint);
|
||||
setUniform(lightMapUniform, renderParameters.lightmapBindingIndex);
|
||||
|
||||
if (worldYOffsetUniform != -1) setUniform(worldYOffsetUniform, (float) worldYOffset);
|
||||
if (worldYOffsetUniform != -1) setUniform(worldYOffsetUniform, (float) renderParameters.worldYOffset);
|
||||
|
||||
// Debug
|
||||
setUniform(whiteWorldUniform, Config.Client.Advanced.Debugging.enableWhiteWorld.get());
|
||||
|
||||
// Fog/Clip Uniforms
|
||||
float dhNearClipDistance = RenderUtil.getNearClipPlaneDistanceInBlocks(partialTicks);
|
||||
// Clip Uniform
|
||||
float dhNearClipDistance = RenderUtil.getNearClipPlaneDistanceInBlocks(renderParameters.partialTicks);
|
||||
setUniform(clipDistanceUniform, dhNearClipDistance);
|
||||
}
|
||||
|
||||
public void setModelPos(Vec3f modelPos)
|
||||
{
|
||||
setUniform(modelOffsetUniform, modelPos);
|
||||
}
|
||||
@Override
|
||||
public void setModelOffsetPos(Vec3f modelOffsetPos) { this.setUniform(this.modelOffsetUniform, modelOffsetPos); }
|
||||
|
||||
@Override
|
||||
public int getId() { return this.id; }
|
||||
|
||||
/** The base DH render program should always render */
|
||||
@Override
|
||||
public boolean overrideThisFrame() { return true; }
|
||||
|
||||
}
|
||||
|
||||
+419
-237
@@ -19,13 +19,21 @@
|
||||
|
||||
package com.seibel.distanthorizons.core.render.renderer;
|
||||
|
||||
import com.seibel.distanthorizons.api.enums.rendering.EDhApiRenderPass;
|
||||
import com.seibel.distanthorizons.api.enums.rendering.EFogDrawMode;
|
||||
import com.seibel.distanthorizons.api.interfaces.override.rendering.IDhApiFramebuffer;
|
||||
import com.seibel.distanthorizons.api.interfaces.override.rendering.IDhApiShaderProgram;
|
||||
import com.seibel.distanthorizons.api.methods.events.abstractEvents.*;
|
||||
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiRenderParam;
|
||||
import com.seibel.distanthorizons.core.config.Config;
|
||||
import com.seibel.distanthorizons.core.dataObjects.render.bufferBuilding.ColumnRenderBuffer;
|
||||
import com.seibel.distanthorizons.core.dependencyInjection.ModAccessorInjector;
|
||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||
import com.seibel.distanthorizons.core.logging.ConfigBasedLogger;
|
||||
import com.seibel.distanthorizons.core.logging.ConfigBasedSpamLogger;
|
||||
import com.seibel.distanthorizons.core.pos.DhBlockPos;
|
||||
import com.seibel.distanthorizons.core.render.AbstractRenderBuffer;
|
||||
import com.seibel.distanthorizons.core.render.DhApiRenderProxy;
|
||||
import com.seibel.distanthorizons.core.render.RenderBufferHandler;
|
||||
import com.seibel.distanthorizons.core.render.glObject.GLProxy;
|
||||
import com.seibel.distanthorizons.core.render.glObject.GLState;
|
||||
@@ -43,11 +51,14 @@ import com.seibel.distanthorizons.core.render.fog.LodFogConfig;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.AbstractOptifineAccessor;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IIrisAccessor;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
||||
import com.seibel.distanthorizons.coreapi.DependencyInjection.ApiEventInjector;
|
||||
import com.seibel.distanthorizons.coreapi.DependencyInjection.OverrideInjector;
|
||||
import com.seibel.distanthorizons.coreapi.util.math.Mat4f;
|
||||
import com.seibel.distanthorizons.coreapi.util.math.Vec3d;
|
||||
import com.seibel.distanthorizons.coreapi.util.math.Vec3f;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.joml.Matrix4f;
|
||||
import org.joml.Matrix4fc;
|
||||
import org.lwjgl.opengl.GL32;
|
||||
|
||||
import java.awt.*;
|
||||
@@ -89,19 +100,29 @@ public class LodRenderer
|
||||
private int cachedHeight;
|
||||
|
||||
|
||||
|
||||
public void setupOffset(DhBlockPos pos) throws IllegalStateException
|
||||
/** called by each {@link ColumnRenderBuffer} before rendering */
|
||||
public void setModelViewMatrixOffset(DhBlockPos pos, DhApiRenderParam renderEventParam) throws IllegalStateException
|
||||
{
|
||||
Vec3d cam = MC_RENDER.getCameraExactPosition();
|
||||
Vec3f modelPos = new Vec3f((float) (pos.x - cam.x), (float) (pos.y - cam.y), (float) (pos.z - cam.z));
|
||||
|
||||
if (!GL32.glIsProgram(this.shaderProgram.id))
|
||||
|
||||
IDhApiShaderProgram shaderProgram = this.lodRenderProgram;
|
||||
IDhApiShaderProgram shaderProgramOverride = OverrideInjector.INSTANCE.get(IDhApiShaderProgram.class);
|
||||
if (shaderProgramOverride != null && shaderProgram.overrideThisFrame())
|
||||
{
|
||||
throw new IllegalStateException("No GL program exists with the ID: [" + this.shaderProgram.id + "]. This either means a shader program was freed while it was still in use or was never created.");
|
||||
shaderProgram = shaderProgramOverride;
|
||||
}
|
||||
|
||||
this.shaderProgram.bind();
|
||||
this.shaderProgram.setModelPos(modelPos);
|
||||
if (!GL32.glIsProgram(shaderProgram.getId()))
|
||||
{
|
||||
throw new IllegalStateException("No GL program exists with the ID: [" + shaderProgram.getId() + "]. This either means a shader program was freed while it was still in use or was never created.");
|
||||
}
|
||||
|
||||
shaderProgram.bind();
|
||||
shaderProgram.setModelOffsetPos(modelPos);
|
||||
|
||||
ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeBufferRenderEvent.class, new DhApiBeforeBufferRenderEvent.EventParam(renderEventParam, modelPos));
|
||||
}
|
||||
|
||||
public void drawVbo(GLVertexBuffer vbo)
|
||||
@@ -110,8 +131,16 @@ public class LodRenderer
|
||||
//// shouldn't be used in production due to the performance hit
|
||||
//if (GL32.glIsBuffer(vbo.getId()))
|
||||
{
|
||||
IDhApiShaderProgram shaderProgram = this.lodRenderProgram;
|
||||
IDhApiShaderProgram shaderProgramOverride = OverrideInjector.INSTANCE.get(IDhApiShaderProgram.class);
|
||||
if (shaderProgramOverride != null && shaderProgram.overrideThisFrame())
|
||||
{
|
||||
shaderProgram = shaderProgramOverride;
|
||||
}
|
||||
|
||||
|
||||
vbo.bind();
|
||||
this.shaderProgram.bindVertexBuffer(vbo.getId());
|
||||
shaderProgram.bindVertexBuffer(vbo.getId());
|
||||
GL32.glDrawElements(GL32.GL_TRIANGLES, (vbo.getVertexCount() / 4) * 6, // TODO what does the 4 and 6 here represent?
|
||||
this.quadIBO.getType(), 0);
|
||||
vbo.unbind();
|
||||
@@ -122,7 +151,6 @@ public class LodRenderer
|
||||
// //LOGGER.warn("Unable to draw VBO: "+vbo.getId());
|
||||
//}
|
||||
}
|
||||
public Vec3f getLookVector() { return MC_RENDER.getLookAtVector(); }
|
||||
|
||||
|
||||
public static class LagSpikeCatcher
|
||||
@@ -157,12 +185,13 @@ public class LodRenderer
|
||||
public final RenderBufferHandler bufferHandler;
|
||||
|
||||
// The shader program
|
||||
LodRenderProgram shaderProgram = null;
|
||||
IDhApiShaderProgram lodRenderProgram = null;
|
||||
LodFogConfig fogConfig;
|
||||
public QuadElementBuffer quadIBO = null;
|
||||
public boolean isSetupComplete = false;
|
||||
|
||||
// frameBuffer and texture ID's for this renderer
|
||||
private DhFramebuffer framebuffer;
|
||||
private IDhApiFramebuffer framebuffer;
|
||||
/** will be null if MC's framebuffer is being used since MC already has a color texture */
|
||||
private DhColorTexture nullableColorTexture;
|
||||
private DHDepthTexture depthTexture;
|
||||
@@ -214,15 +243,63 @@ public class LodRenderer
|
||||
|
||||
|
||||
|
||||
//===============//
|
||||
// main renderer //
|
||||
//===============//
|
||||
//===========//
|
||||
// rendering //
|
||||
//===========//
|
||||
|
||||
public void drawLODs(IClientLevelWrapper clientLevelWrapper, Mat4f baseModelViewMatrix, Mat4f baseProjectionMatrix, float partialTicks, IProfilerWrapper profiler)
|
||||
/**
|
||||
* This will draw both opaque and transparent LODs if
|
||||
* {@link DhApiRenderProxy#getDeferTransparentRendering()} is false,
|
||||
* otherwise it will only render opaque LODs.
|
||||
*/
|
||||
public void drawLods(
|
||||
IClientLevelWrapper clientLevelWrapper,
|
||||
DhApiRenderParam renderEventParam, IProfilerWrapper profiler)
|
||||
{
|
||||
this.renderLodPass(
|
||||
clientLevelWrapper,
|
||||
renderEventParam,
|
||||
profiler,
|
||||
false);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is designed for Iris to be able
|
||||
* to draw water in a deferred rendering context.
|
||||
* It needs to be updated with any major changes,
|
||||
* but shouldn't be activated as per deferWaterRendering.
|
||||
*/
|
||||
public void drawDeferredLods(
|
||||
IClientLevelWrapper clientLevelWrapper,
|
||||
DhApiRenderParam renderEventParam, IProfilerWrapper profiler)
|
||||
{
|
||||
this.renderLodPass(
|
||||
clientLevelWrapper,
|
||||
renderEventParam,
|
||||
profiler,
|
||||
true);
|
||||
}
|
||||
|
||||
private void renderLodPass(
|
||||
IClientLevelWrapper clientLevelWrapper,
|
||||
DhApiRenderParam renderEventParam,
|
||||
IProfilerWrapper profiler,
|
||||
boolean runningDeferredPass)
|
||||
{
|
||||
//====================//
|
||||
// validate rendering //
|
||||
//====================//
|
||||
|
||||
boolean deferTransparentRendering = DhApiRenderProxy.INSTANCE.getDeferTransparentRendering();
|
||||
if (runningDeferredPass && !deferTransparentRendering)
|
||||
{
|
||||
return;
|
||||
}
|
||||
boolean renderingFirstPass = !runningDeferredPass;
|
||||
|
||||
if (this.rendererClosed)
|
||||
{
|
||||
EVENT_LOGGER.error("drawLODs() called after close()!");
|
||||
EVENT_LOGGER.error("LOD rendering attempted after the renderer has been shut down!");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -238,19 +315,14 @@ public class LodRenderer
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//=================//
|
||||
// rendering setup //
|
||||
//=================//
|
||||
|
||||
try
|
||||
{
|
||||
if (IRIS_ACCESSOR != null && IRIS_ACCESSOR.isRenderingShadowPass())
|
||||
{
|
||||
// Do not do this while Iris compat is being worked on.
|
||||
|
||||
// We do not have a wy to properly render shader shadow pass, since they can
|
||||
// and often do change the projection entirely, as well as the output usage.
|
||||
|
||||
//EVENT_LOGGER.debug("Skipping shadow pass render.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Note: Since lightmapTexture is changing every frame, it's faster to recreate it than to reuse the old one.
|
||||
ILightMapWrapper lightmap = MC_RENDER.getLightmapWrapper(clientLevelWrapper);
|
||||
if (lightmap == null)
|
||||
@@ -268,133 +340,8 @@ public class LodRenderer
|
||||
}
|
||||
drawSaveGLState.end("drawSaveGLState");
|
||||
|
||||
|
||||
|
||||
//===================//
|
||||
// draw params setup //
|
||||
//===================//
|
||||
|
||||
profiler.push("LOD draw setup");
|
||||
|
||||
if (!this.isSetupComplete)
|
||||
{
|
||||
this.setup();
|
||||
|
||||
// shouldn't normally happen, but just in case
|
||||
if (!this.isSetupComplete)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (MC_RENDER.getTargetFrameBufferViewportWidth() != this.cachedWidth || MC_RENDER.getTargetFrameBufferViewportHeight() != this.cachedHeight)
|
||||
{
|
||||
this.cachedWidth = MC_RENDER.getTargetFrameBufferViewportWidth();
|
||||
this.cachedHeight = MC_RENDER.getTargetFrameBufferViewportHeight();
|
||||
|
||||
// just resizing the textures doesn't work when Optifine is present,
|
||||
// so recreate the textures with the new size instead
|
||||
this.createColorAndDepthTextures(this.cachedWidth, this.cachedHeight);
|
||||
}
|
||||
|
||||
this.setActiveFramebufferId(this.framebuffer.getId());
|
||||
this.setActiveDepthTextureId(this.depthTexture.getTextureId());
|
||||
if (this.nullableColorTexture != null)
|
||||
{
|
||||
this.setActiveColorTextureId(this.nullableColorTexture.getTextureId());
|
||||
}
|
||||
else
|
||||
{
|
||||
// get MC's color texture
|
||||
int mcColorTextureId = GL32.glGetFramebufferAttachmentParameteri(GL32.GL_FRAMEBUFFER, GL32.GL_COLOR_ATTACHMENT0, GL32.GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME);
|
||||
this.setActiveColorTextureId(mcColorTextureId);
|
||||
}
|
||||
// Bind LOD frame buffer
|
||||
this.framebuffer.bind();
|
||||
|
||||
|
||||
if (this.usingMcFrameBuffer)
|
||||
{
|
||||
// recreating the GL State at this point is necessary in order to get the correct depth texture
|
||||
minecraftGlState = new GLState();
|
||||
if (ENABLE_DUMP_GL_STATE)
|
||||
{
|
||||
tickLogger.debug("Re-saving GL state due to Optifine presence: " + minecraftGlState); //
|
||||
}
|
||||
|
||||
|
||||
// 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);
|
||||
|
||||
|
||||
// don't clear the color texture, that removes the sky
|
||||
GL32.glClear(GL32.GL_DEPTH_BUFFER_BIT);
|
||||
}
|
||||
else
|
||||
{
|
||||
GL32.glClear(GL32.GL_COLOR_BUFFER_BIT | GL32.GL_DEPTH_BUFFER_BIT);
|
||||
}
|
||||
|
||||
|
||||
GL32.glEnable(GL32.GL_DEPTH_TEST);
|
||||
GL32.glDepthFunc(GL32.GL_LESS);
|
||||
|
||||
// Set OpenGL polygon mode
|
||||
boolean renderWireframe = Config.Client.Advanced.Debugging.renderWireframe.get();
|
||||
if (renderWireframe)
|
||||
{
|
||||
GL32.glPolygonMode(GL32.GL_FRONT_AND_BACK, GL32.GL_LINE);
|
||||
//GL32.glDisable(GL32.GL_CULL_FACE);
|
||||
}
|
||||
else
|
||||
{
|
||||
GL32.glPolygonMode(GL32.GL_FRONT_AND_BACK, GL32.GL_FILL);
|
||||
GL32.glEnable(GL32.GL_CULL_FACE);
|
||||
}
|
||||
|
||||
// Enable depth test and depth mask
|
||||
GL32.glEnable(GL32.GL_DEPTH_TEST);
|
||||
GL32.glDepthFunc(GL32.GL_LESS);
|
||||
GL32.glDepthMask(true);
|
||||
|
||||
// Disable blending
|
||||
// We render opaque first, then transparent
|
||||
GL32.glDisable(GL32.GL_BLEND);
|
||||
|
||||
/*---------Bind required objects--------*/
|
||||
// Setup LodRenderProgram and the LightmapTexture if it has not yet been done
|
||||
// also binds LightmapTexture, VAO, and ShaderProgram
|
||||
if (!this.isSetupComplete)
|
||||
{
|
||||
this.setup();
|
||||
}
|
||||
else
|
||||
{
|
||||
LodFogConfig newFogConfig = this.shaderProgram.isShaderUsable();
|
||||
if (newFogConfig != null)
|
||||
{
|
||||
this.shaderProgram.free();
|
||||
this.shaderProgram = new LodRenderProgram(newFogConfig);
|
||||
|
||||
FogShader.INSTANCE.free();
|
||||
FogShader.INSTANCE = new FogShader(newFogConfig);
|
||||
}
|
||||
this.shaderProgram.bind();
|
||||
}
|
||||
|
||||
/*---------Get required data--------*/
|
||||
//int vanillaBlockRenderedDistance = MC_RENDER.getRenderDistance() * LodUtil.CHUNK_WIDTH;
|
||||
//Mat4f modelViewProjectionMatrix = RenderUtil.createCombinedModelViewProjectionMatrix(baseProjectionMatrix, baseModelViewMatrix, partialTicks);
|
||||
|
||||
Mat4f projectionMatrix = RenderUtil.createLodProjectionMatrix(baseProjectionMatrix, partialTicks);
|
||||
|
||||
Mat4f modelViewProjectionMatrix = new Mat4f(projectionMatrix);
|
||||
modelViewProjectionMatrix.multiply(RenderUtil.createLodModelViewMatrix(baseModelViewMatrix));
|
||||
|
||||
/*---------Fill uniform data--------*/
|
||||
this.shaderProgram.fillUniformData(modelViewProjectionMatrix, /*Light map = GL_TEXTURE0*/ 0,
|
||||
MC.getWrappedClientLevel().getMinHeight(), partialTicks);
|
||||
ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeRenderSetupEvent.class, renderEventParam);
|
||||
this.setupGLStateAndRenderObjects(minecraftGlState, profiler, renderEventParam, renderingFirstPass);
|
||||
|
||||
lightmap.bind();
|
||||
if (ENABLE_IBO)
|
||||
@@ -402,7 +349,21 @@ public class LodRenderer
|
||||
this.quadIBO.bind();
|
||||
}
|
||||
|
||||
this.bufferHandler.buildRenderListAndUpdateSections(this.getLookVector());
|
||||
if (renderingFirstPass)
|
||||
{
|
||||
Matrix4f matWorldView = new Matrix4f()
|
||||
.setTransposed(MC_RENDER.getWorldViewMatrix().getValuesAsArray());
|
||||
|
||||
Matrix4fc matWorldViewProjection = new Matrix4f()
|
||||
.setTransposed(renderEventParam.dhProjectionMatrix.getValuesAsArray())
|
||||
.mul(matWorldView);
|
||||
|
||||
this.bufferHandler.buildRenderListAndUpdateSections(clientLevelWrapper, matWorldViewProjection, MC_RENDER.getLookAtVector());
|
||||
|
||||
transparencyEnabled = Config.Client.Advanced.Graphics.Quality.transparency.get().transparencyEnabled;
|
||||
fakeOceanFloor = Config.Client.Advanced.Graphics.Quality.transparency.get().fakeTransparencyEnabled;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -412,72 +373,103 @@ public class LodRenderer
|
||||
|
||||
LagSpikeCatcher drawLagSpikeCatcher = new LagSpikeCatcher();
|
||||
|
||||
profiler.popPush("LOD Opaque");
|
||||
// TODO: Directional culling
|
||||
this.bufferHandler.renderOpaque(this);
|
||||
|
||||
if (Config.Client.Advanced.Graphics.Ssao.enabled.get())
|
||||
if (!runningDeferredPass)
|
||||
{
|
||||
profiler.popPush("LOD SSAO");
|
||||
SSAORenderer.INSTANCE.render(minecraftGlState, projectionMatrix, partialTicks);
|
||||
}
|
||||
|
||||
profiler.popPush("LOD Fog");
|
||||
FogShader.INSTANCE.setModelViewProjectionMatrix(modelViewProjectionMatrix);
|
||||
FogShader.INSTANCE.render(partialTicks);
|
||||
|
||||
//DarkShader.INSTANCE.render(partialTicks); // A test shader to make the world darker
|
||||
|
||||
// Render transparent LOD sections (such as water)
|
||||
transparencyEnabled = Config.Client.Advanced.Graphics.Quality.transparency.get().transparencyEnabled;
|
||||
fakeOceanFloor = Config.Client.Advanced.Graphics.Quality.transparency.get().fakeTransparencyEnabled;
|
||||
|
||||
if (Config.Client.Advanced.Graphics.Quality.transparency.get().transparencyEnabled)
|
||||
{
|
||||
profiler.popPush("LOD Transparent");
|
||||
//===================================//
|
||||
// standard (non-deferred) rendering //
|
||||
//===================================//
|
||||
|
||||
GL32.glEnable(GL32.GL_BLEND);
|
||||
GL32.glBlendEquation(GL32.GL_FUNC_ADD);
|
||||
GL32.glBlendFunc(GL32.GL_ONE, GL32.GL_ONE_MINUS_SRC_ALPHA);
|
||||
this.bufferHandler.renderTransparent(this);
|
||||
GL32.glDepthMask(true); // Apparently the depth mask state is stored in the FBO, so glState fails to restore it...
|
||||
|
||||
profiler.popPush("LOD Fog");
|
||||
FogShader.INSTANCE.render(partialTicks);
|
||||
// Disable blending for opaque rendering
|
||||
GL32.glDisable(GL32.GL_BLEND);
|
||||
|
||||
profiler.popPush("LOD Opaque");
|
||||
ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeRenderPassEvent.class, renderEventParam);
|
||||
|
||||
// TODO: Directional culling
|
||||
this.bufferHandler.renderOpaque(this, renderEventParam);
|
||||
|
||||
if (Config.Client.Advanced.Graphics.Ssao.enabled.get())
|
||||
{
|
||||
profiler.popPush("LOD SSAO");
|
||||
SSAORenderer.INSTANCE.render(minecraftGlState, renderEventParam.dhProjectionMatrix, renderEventParam.partialTicks);
|
||||
}
|
||||
|
||||
|
||||
if (Config.Client.Advanced.Graphics.Fog.drawMode.get() != EFogDrawMode.FOG_DISABLED)
|
||||
{
|
||||
profiler.popPush("LOD Fog");
|
||||
FogShader.INSTANCE.setModelViewProjectionMatrix(renderEventParam.dhModelViewMatrix);
|
||||
FogShader.INSTANCE.render(renderEventParam.partialTicks);
|
||||
}
|
||||
|
||||
//DarkShader.INSTANCE.render(partialTicks); // A test shader to make the world darker
|
||||
|
||||
if (!deferTransparentRendering && Config.Client.Advanced.Graphics.Quality.transparency.get().transparencyEnabled)
|
||||
{
|
||||
this.renderTransparentBuffers(profiler, renderEventParam, renderEventParam.partialTicks);
|
||||
}
|
||||
|
||||
|
||||
if (this.usingMcFrameBuffer)
|
||||
{
|
||||
// If MC's framebuffer is being used the depth needs to be cleared to prevent rendering on top of MC.
|
||||
// This should only happen when Optifine shaders are being used.
|
||||
GL32.glClear(GL32.GL_DEPTH_BUFFER_BIT);
|
||||
}
|
||||
|
||||
drawLagSpikeCatcher.end("LodDraw");
|
||||
|
||||
|
||||
//=================//
|
||||
// debug rendering //
|
||||
//=================//
|
||||
|
||||
if (Config.Client.Advanced.Debugging.DebugWireframe.enableRendering.get())
|
||||
{
|
||||
profiler.popPush("Debug wireframes");
|
||||
|
||||
Mat4f combinedMatrix = new Mat4f(renderEventParam.dhProjectionMatrix);
|
||||
combinedMatrix.multiply(renderEventParam.dhModelViewMatrix);
|
||||
|
||||
// Note: this can be very slow if a lot of boxes are being rendered
|
||||
DebugRenderer.INSTANCE.render(combinedMatrix);
|
||||
profiler.popPush("LOD cleanup");
|
||||
}
|
||||
|
||||
|
||||
|
||||
//=============================//
|
||||
// Apply to the MC FrameBuffer //
|
||||
//=============================//
|
||||
|
||||
boolean cancelApplyShader = ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeApplyShaderRenderEvent.class, renderEventParam);
|
||||
if (!cancelApplyShader)
|
||||
{
|
||||
profiler.popPush("LOD Apply");
|
||||
|
||||
GLState dhApplyGlState = new GLState();
|
||||
|
||||
// Copy the LOD framebuffer to Minecraft's framebuffer
|
||||
DhApplyShader.INSTANCE.render(renderEventParam.partialTicks);
|
||||
|
||||
dhApplyGlState.restore();
|
||||
}
|
||||
}
|
||||
|
||||
if (Config.Client.Advanced.Debugging.DebugWireframe.enableRendering.get())
|
||||
else
|
||||
{
|
||||
profiler.popPush("Debug wireframes");
|
||||
// Note: this can be very slow if a lot of boxes are being rendered
|
||||
DebugRenderer.INSTANCE.render(modelViewProjectionMatrix);
|
||||
//====================//
|
||||
// deferred rendering //
|
||||
//====================//
|
||||
|
||||
if (Config.Client.Advanced.Graphics.Quality.transparency.get().transparencyEnabled)
|
||||
{
|
||||
this.renderTransparentBuffers(profiler, renderEventParam, renderEventParam.partialTicks);
|
||||
}
|
||||
|
||||
drawLagSpikeCatcher.end("LodTranslucentDraw");
|
||||
}
|
||||
|
||||
if (this.usingMcFrameBuffer)
|
||||
{
|
||||
// If MC's framebuffer is being used the depth needs to be cleared to prevent rendering on top of MC.
|
||||
// This should only happen when Optifine shaders are being used.
|
||||
GL32.glClear(GL32.GL_DEPTH_BUFFER_BIT);
|
||||
}
|
||||
|
||||
drawLagSpikeCatcher.end("LodDraw");
|
||||
|
||||
|
||||
|
||||
//=============================//
|
||||
// Apply to the MC FrameBuffer //
|
||||
//=============================//
|
||||
|
||||
profiler.popPush("LOD Apply");
|
||||
|
||||
GLState dhApplyGlState = new GLState();
|
||||
|
||||
// Copy the LOD framebuffer to Minecraft's framebuffer
|
||||
DhApplyShader.INSTANCE.render(partialTicks);
|
||||
|
||||
dhApplyGlState.restore();
|
||||
|
||||
|
||||
|
||||
|
||||
//================//
|
||||
@@ -486,8 +478,15 @@ public class LodRenderer
|
||||
|
||||
profiler.popPush("LOD cleanup");
|
||||
LagSpikeCatcher drawCleanup = new LagSpikeCatcher();
|
||||
ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeRenderCleanupEvent.class, renderEventParam);
|
||||
|
||||
GLProxy.getInstance().runRenderThreadTasks();
|
||||
// GLProxy tasks should be run after all rendering has been done
|
||||
boolean afterEnabledDeferredPass = deferTransparentRendering && !renderingFirstPass;
|
||||
boolean afterOnlyRenderingPass = !deferTransparentRendering && renderingFirstPass;
|
||||
if (afterEnabledDeferredPass || afterOnlyRenderingPass)
|
||||
{
|
||||
GLProxy.getInstance().runRenderThreadTasks();
|
||||
}
|
||||
|
||||
lightmap.unbind();
|
||||
if (ENABLE_IBO)
|
||||
@@ -495,8 +494,13 @@ public class LodRenderer
|
||||
this.quadIBO.unbind();
|
||||
}
|
||||
|
||||
this.shaderProgram.unbind();
|
||||
|
||||
IDhApiShaderProgram shaderProgram = this.lodRenderProgram;
|
||||
IDhApiShaderProgram shaderProgramOverride = OverrideInjector.INSTANCE.get(IDhApiShaderProgram.class);
|
||||
if (shaderProgramOverride != null && shaderProgram.overrideThisFrame())
|
||||
{
|
||||
shaderProgram = shaderProgramOverride;
|
||||
}
|
||||
shaderProgram.unbind();
|
||||
|
||||
minecraftGlState.restore();
|
||||
drawCleanup.end("LodDrawCleanup");
|
||||
@@ -512,15 +516,173 @@ public class LodRenderer
|
||||
}
|
||||
}
|
||||
|
||||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
private void renderTransparentBuffers(IProfilerWrapper profiler, DhApiRenderParam renderEventParam, float partialTicks)
|
||||
{
|
||||
profiler.popPush("LOD Transparent");
|
||||
|
||||
GL32.glEnable(GL32.GL_BLEND);
|
||||
GL32.glBlendEquation(GL32.GL_FUNC_ADD);
|
||||
GL32.glBlendFunc(GL32.GL_ONE, GL32.GL_ONE_MINUS_SRC_ALPHA);
|
||||
ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeRenderPassEvent.class, renderEventParam);
|
||||
this.bufferHandler.renderTransparent(this, renderEventParam);
|
||||
GL32.glDepthMask(true); // Apparently the depth mask state is stored in the FBO, so glState fails to restore it...
|
||||
|
||||
|
||||
if (Config.Client.Advanced.Graphics.Fog.drawMode.get() != EFogDrawMode.FOG_DISABLED)
|
||||
{
|
||||
profiler.popPush("LOD Fog");
|
||||
FogShader.INSTANCE.render(partialTicks);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//=================//
|
||||
// Setup Functions //
|
||||
//=================//
|
||||
|
||||
/** Setup all render objects - REQUIRES to be in render thread */
|
||||
private void setup()
|
||||
private void setupGLStateAndRenderObjects(
|
||||
GLState minecraftGlState, IProfilerWrapper profiler,
|
||||
DhApiRenderParam renderEventParam,
|
||||
boolean firstPass)
|
||||
{
|
||||
//===================//
|
||||
// draw params setup //
|
||||
//===================//
|
||||
|
||||
profiler.push("LOD draw setup");
|
||||
|
||||
if (!this.isSetupComplete)
|
||||
{
|
||||
this.setupRenderObjects();
|
||||
|
||||
// shouldn't normally happen, but just in case
|
||||
if (!this.isSetupComplete)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (MC_RENDER.getTargetFrameBufferViewportWidth() != this.cachedWidth || MC_RENDER.getTargetFrameBufferViewportHeight() != this.cachedHeight)
|
||||
{
|
||||
// just resizing the textures doesn't work when Optifine is present,
|
||||
// so recreate the textures with the new size instead
|
||||
this.createColorAndDepthTextures();
|
||||
}
|
||||
|
||||
|
||||
IDhApiFramebuffer activeFrameBuffer = this.framebuffer;
|
||||
IDhApiFramebuffer framebufferOverride = OverrideInjector.INSTANCE.get(IDhApiFramebuffer.class);
|
||||
if (framebufferOverride != null && framebufferOverride.overrideThisFrame())
|
||||
{
|
||||
activeFrameBuffer = framebufferOverride;
|
||||
}
|
||||
|
||||
this.setActiveFramebufferId(activeFrameBuffer.getId());
|
||||
this.setActiveDepthTextureId(this.depthTexture.getTextureId());
|
||||
if (this.nullableColorTexture != null)
|
||||
{
|
||||
this.setActiveColorTextureId(this.nullableColorTexture.getTextureId());
|
||||
}
|
||||
else
|
||||
{
|
||||
// get MC's color texture
|
||||
int mcColorTextureId = GL32.glGetFramebufferAttachmentParameteri(GL32.GL_FRAMEBUFFER, GL32.GL_COLOR_ATTACHMENT0, GL32.GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME);
|
||||
this.setActiveColorTextureId(mcColorTextureId);
|
||||
}
|
||||
// Bind LOD frame buffer
|
||||
activeFrameBuffer.bind();
|
||||
|
||||
|
||||
boolean clearTextures = !ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeTextureClearEvent.class, renderEventParam);
|
||||
if (clearTextures)
|
||||
{
|
||||
if (this.usingMcFrameBuffer && framebufferOverride == null)
|
||||
{
|
||||
// recreating the GL State at this point is necessary in order to get the correct depth texture
|
||||
minecraftGlState.saveState();
|
||||
if (ENABLE_DUMP_GL_STATE)
|
||||
{
|
||||
tickLogger.debug("Re-saving GL state due to Optifine presence: " + minecraftGlState);
|
||||
}
|
||||
|
||||
|
||||
// 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
|
||||
activeFrameBuffer.addDepthAttachment(this.depthTexture.getTextureId(), EDhDepthBufferFormat.DEPTH32F.isCombinedStencil());
|
||||
|
||||
|
||||
// don't clear the color texture, that removes the sky
|
||||
GL32.glClear(GL32.GL_DEPTH_BUFFER_BIT);
|
||||
}
|
||||
else if (firstPass)
|
||||
{
|
||||
GL32.glClear(GL32.GL_COLOR_BUFFER_BIT | GL32.GL_DEPTH_BUFFER_BIT);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
GL32.glEnable(GL32.GL_DEPTH_TEST);
|
||||
GL32.glDepthFunc(GL32.GL_LESS);
|
||||
|
||||
// Set OpenGL polygon mode
|
||||
boolean renderWireframe = Config.Client.Advanced.Debugging.renderWireframe.get();
|
||||
if (renderWireframe)
|
||||
{
|
||||
GL32.glPolygonMode(GL32.GL_FRONT_AND_BACK, GL32.GL_LINE);
|
||||
//GL32.glDisable(GL32.GL_CULL_FACE);
|
||||
}
|
||||
else
|
||||
{
|
||||
GL32.glPolygonMode(GL32.GL_FRONT_AND_BACK, GL32.GL_FILL);
|
||||
GL32.glEnable(GL32.GL_CULL_FACE);
|
||||
}
|
||||
|
||||
// Enable depth test and depth mask
|
||||
GL32.glEnable(GL32.GL_DEPTH_TEST);
|
||||
GL32.glDepthFunc(GL32.GL_LESS);
|
||||
GL32.glDepthMask(true);
|
||||
|
||||
/*---------Bind required objects--------*/
|
||||
// Setup LodRenderProgram and the LightmapTexture if it has not yet been done
|
||||
// also binds LightmapTexture, VAO, and ShaderProgram
|
||||
if (!this.isSetupComplete)
|
||||
{
|
||||
this.setupRenderObjects();
|
||||
}
|
||||
else
|
||||
{
|
||||
LodFogConfig newFogConfig = LodFogConfig.generateFogConfig(); // TODO use a config listener instead
|
||||
if (this.fogConfig == null)
|
||||
{
|
||||
this.fogConfig = newFogConfig;
|
||||
}
|
||||
|
||||
if (!this.fogConfig.equals(newFogConfig))
|
||||
{
|
||||
this.fogConfig = newFogConfig;
|
||||
|
||||
this.lodRenderProgram.free();
|
||||
this.lodRenderProgram = new LodRenderProgram();
|
||||
|
||||
FogShader.INSTANCE.free();
|
||||
FogShader.INSTANCE = new FogShader(newFogConfig);
|
||||
}
|
||||
this.lodRenderProgram.bind();
|
||||
}
|
||||
|
||||
|
||||
IDhApiShaderProgram shaderProgramOverride = OverrideInjector.INSTANCE.get(IDhApiShaderProgram.class);
|
||||
if (shaderProgramOverride != null)
|
||||
{
|
||||
shaderProgramOverride.fillUniformData(renderEventParam);
|
||||
}
|
||||
|
||||
this.lodRenderProgram.fillUniformData(renderEventParam);
|
||||
}
|
||||
|
||||
/** Setup all render objects - MUST be called on the render thread */
|
||||
private void setupRenderObjects()
|
||||
{
|
||||
if (this.isSetupComplete)
|
||||
{
|
||||
@@ -541,7 +703,7 @@ public class LodRenderer
|
||||
|
||||
EVENT_LOGGER.info("Setting up renderer");
|
||||
this.isSetupComplete = true;
|
||||
this.shaderProgram = new LodRenderProgram(LodFogConfig.generateFogConfig()); // TODO this doesn't actually use the fog config
|
||||
this.lodRenderProgram = new LodRenderProgram();
|
||||
if (ENABLE_IBO)
|
||||
{
|
||||
this.quadIBO = new QuadElementBuffer();
|
||||
@@ -565,9 +727,7 @@ public class LodRenderer
|
||||
}
|
||||
|
||||
// create and bind the necessary textures
|
||||
this.cachedWidth = MC_RENDER.getTargetFrameBufferViewportWidth();
|
||||
this.cachedHeight = MC_RENDER.getTargetFrameBufferViewportHeight();
|
||||
this.createColorAndDepthTextures(this.cachedWidth, this.cachedHeight);
|
||||
this.createColorAndDepthTextures();
|
||||
|
||||
if(this.framebuffer.getStatus() != GL32.GL_FRAMEBUFFER_COMPLETE)
|
||||
{
|
||||
@@ -584,23 +744,45 @@ public class LodRenderer
|
||||
}
|
||||
}
|
||||
/** also binds the new textures to the {@link LodRenderer#framebuffer} */
|
||||
private void createColorAndDepthTextures(int width, int height)
|
||||
private void createColorAndDepthTextures()
|
||||
{
|
||||
// don't use the cached width/height just in case they haven't been set yet
|
||||
int oldWidth = this.cachedWidth;
|
||||
int oldHeight = this.cachedHeight;
|
||||
this.cachedWidth = MC_RENDER.getTargetFrameBufferViewportWidth();
|
||||
this.cachedHeight = MC_RENDER.getTargetFrameBufferViewportHeight();
|
||||
|
||||
this.depthTexture = new DHDepthTexture(width, height, EDhDepthBufferFormat.DEPTH32F);
|
||||
this.framebuffer.addDepthAttachment(this.depthTexture.getTextureId(), EDhDepthBufferFormat.DEPTH32F);
|
||||
|
||||
ApiEventInjector.INSTANCE.fireAllEvents(DhApiScreenResizeEvent.class,
|
||||
new DhApiScreenResizeEvent.EventParam(
|
||||
oldWidth, oldHeight,
|
||||
this.cachedWidth, this.cachedHeight
|
||||
));
|
||||
|
||||
|
||||
// also update the override if present
|
||||
IDhApiFramebuffer framebufferOverride = OverrideInjector.INSTANCE.get(IDhApiFramebuffer.class);
|
||||
|
||||
this.depthTexture = new DHDepthTexture(this.cachedWidth, this.cachedHeight, EDhDepthBufferFormat.DEPTH32F);
|
||||
this.framebuffer.addDepthAttachment(this.depthTexture.getTextureId(), EDhDepthBufferFormat.DEPTH32F.isCombinedStencil());
|
||||
if (framebufferOverride != null)
|
||||
{
|
||||
framebufferOverride.addDepthAttachment(this.depthTexture.getTextureId(), EDhDepthBufferFormat.DEPTH32F.isCombinedStencil());
|
||||
}
|
||||
|
||||
// if we are using MC's frame buffer, a color texture is already present and shouldn't need to be bound
|
||||
if (!this.usingMcFrameBuffer)
|
||||
{
|
||||
this.nullableColorTexture = DhColorTexture.builder().setDimensions(width, height)
|
||||
this.nullableColorTexture = DhColorTexture.builder().setDimensions(this.cachedWidth, this.cachedHeight)
|
||||
.setInternalFormat(EDhInternalTextureFormat.RGBA8)
|
||||
.setPixelType(EDhPixelType.UNSIGNED_BYTE)
|
||||
.setPixelFormat(EDhPixelFormat.RGBA)
|
||||
.build();
|
||||
|
||||
this.framebuffer.addColorAttachment(0, this.nullableColorTexture.getTextureId());
|
||||
if (framebufferOverride != null)
|
||||
{
|
||||
framebufferOverride.addColorAttachment(0, this.nullableColorTexture.getTextureId());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -647,12 +829,12 @@ public class LodRenderer
|
||||
|
||||
|
||||
|
||||
//======================//
|
||||
// Cleanup Functions //
|
||||
//======================//
|
||||
//===================//
|
||||
// Cleanup Functions //
|
||||
//===================//
|
||||
|
||||
/**
|
||||
* cleanup and free all render objects. MUST be on the render thread
|
||||
* cleanup and free all render objects.
|
||||
* (Many objects are Native, outside of JVM, and need manual cleanup)
|
||||
*/
|
||||
private void cleanup()
|
||||
@@ -673,10 +855,10 @@ public class LodRenderer
|
||||
{
|
||||
EVENT_LOGGER.info("Renderer Cleanup Started");
|
||||
|
||||
if (this.shaderProgram != null)
|
||||
if (this.lodRenderProgram != null)
|
||||
{
|
||||
this.shaderProgram.free();
|
||||
this.shaderProgram = null;
|
||||
this.lodRenderProgram.free();
|
||||
this.lodRenderProgram = null;
|
||||
}
|
||||
|
||||
if (this.quadIBO != null)
|
||||
@@ -684,7 +866,7 @@ public class LodRenderer
|
||||
|
||||
// Delete framebuffer, color texture, and depth texture
|
||||
if (this.framebuffer != null && !this.usingMcFrameBuffer)
|
||||
this.framebuffer.destroyInternal();
|
||||
this.framebuffer.destroy();
|
||||
if (this.nullableColorTexture != null)
|
||||
this.nullableColorTexture.destroy();
|
||||
if (this.depthTexture != null)
|
||||
|
||||
+7
-1
@@ -61,7 +61,13 @@ public abstract class AbstractShaderRenderer
|
||||
this.shader.unbind();
|
||||
}
|
||||
|
||||
public void free() { this.shader.free(); }
|
||||
public void free()
|
||||
{
|
||||
if (this.shader != null)
|
||||
{
|
||||
this.shader.free();
|
||||
}
|
||||
}
|
||||
|
||||
protected void onInit() {}
|
||||
|
||||
|
||||
+19
-3
@@ -35,9 +35,11 @@ public class DefaultLodVertexFormats
|
||||
public static final LodVertexFormatElement ELEMENT_UV = new LodVertexFormatElement(0, LodVertexFormatElement.DataType.FLOAT, 2, false);
|
||||
public static final LodVertexFormatElement ELEMENT_LIGHT_MAP_UV = new LodVertexFormatElement(1, LodVertexFormatElement.DataType.SHORT, 2, false);
|
||||
public static final LodVertexFormatElement ELEMENT_NORMAL = new LodVertexFormatElement(0, LodVertexFormatElement.DataType.BYTE, 3, false);
|
||||
public static final LodVertexFormatElement ELEMENT_PADDING = new LodVertexFormatElement(0, LodVertexFormatElement.DataType.BYTE, 1, true);
|
||||
public static final LodVertexFormatElement ELEMENT_BYTE_PADDING = new LodVertexFormatElement(0, LodVertexFormatElement.DataType.BYTE, 1, true);
|
||||
|
||||
public static final LodVertexFormatElement ELEMENT_LIGHT = new LodVertexFormatElement(0, LodVertexFormatElement.DataType.UBYTE, 1, false);
|
||||
public static final LodVertexFormatElement ELEMENT_IRIS_MATERIAL_INDEX = new LodVertexFormatElement(0, LodVertexFormatElement.DataType.BYTE, 1, false);
|
||||
public static final LodVertexFormatElement ELEMENT_IRIS_NORMAL_INDEX = new LodVertexFormatElement(0, LodVertexFormatElement.DataType.BYTE, 1, false);
|
||||
|
||||
|
||||
public static final LodVertexFormat POSITION = new LodVertexFormat(ImmutableList.<LodVertexFormatElement>builder().add(ELEMENT_POSITION).build());
|
||||
@@ -48,7 +50,21 @@ public class DefaultLodVertexFormats
|
||||
public static final LodVertexFormat POSITION_COLOR_TEX_LIGHTMAP = new LodVertexFormat(ImmutableList.<LodVertexFormatElement>builder().add(ELEMENT_POSITION).add(ELEMENT_COLOR).add(ELEMENT_UV).add(ELEMENT_LIGHT_MAP_UV).build());
|
||||
|
||||
public static final LodVertexFormat POSITION_COLOR_BLOCK_LIGHT_SKY_LIGHT = new LodVertexFormat(ImmutableList.<LodVertexFormatElement>builder()
|
||||
.add(ELEMENT_POSITION).add(ELEMENT_PADDING).add(ELEMENT_LIGHT)
|
||||
.add(ELEMENT_COLOR).build());
|
||||
.add(ELEMENT_POSITION)
|
||||
.add(ELEMENT_BYTE_PADDING)
|
||||
.add(ELEMENT_LIGHT)
|
||||
.add(ELEMENT_COLOR)
|
||||
.build());
|
||||
|
||||
public static final LodVertexFormat POSITION_COLOR_BLOCK_LIGHT_SKY_LIGHT_MATERIAL_ID_NORMAL_INDEX = new LodVertexFormat(ImmutableList.<LodVertexFormatElement>builder()
|
||||
.add(ELEMENT_POSITION)
|
||||
.add(ELEMENT_BYTE_PADDING)
|
||||
.add(ELEMENT_LIGHT)
|
||||
.add(ELEMENT_COLOR)
|
||||
.add(ELEMENT_IRIS_MATERIAL_INDEX)
|
||||
.add(ELEMENT_IRIS_NORMAL_INDEX)
|
||||
.add(ELEMENT_BYTE_PADDING)
|
||||
.add(ELEMENT_BYTE_PADDING) // padding is to make sure the format is a multiple of 4
|
||||
.build());
|
||||
|
||||
}
|
||||
|
||||
@@ -39,17 +39,22 @@ public class ColorUtil
|
||||
public static final int BLACK = rgbToInt(0, 0, 0);
|
||||
public static final int WHITE = rgbToInt(255, 255, 255);
|
||||
public static final int RED = rgbToInt(255, 0, 0);
|
||||
public static final int DARK_RED = rgbToInt(100, 0, 0);
|
||||
public static final int GREEN = rgbToInt(0, 255, 0);
|
||||
public static final int BLUE = rgbToInt(0, 0, 255);
|
||||
public static final int YELLOW = rgbToInt(255, 255, 0);
|
||||
public static final int CYAN = rgbToInt(0, 255, 255);
|
||||
public static final int MAGENTA = rgbToInt(255, 0, 255);
|
||||
public static final int ORANGE = rgbToInt(255, 128, 0);
|
||||
public static final int DARK_ORANGE = rgbToInt(125, 62, 0);
|
||||
public static final int TAN = rgbToInt(183, 165, 119);
|
||||
public static final int PINK = rgbToInt(255, 128, 128);
|
||||
public static final int HOT_PINK = rgbToInt(255, 105, 180);
|
||||
public static final int GRAY = rgbToInt(128, 128, 128);
|
||||
public static final int LIGHT_GRAY = rgbToInt(192, 192, 192);
|
||||
public static final int DARK_GRAY = rgbToInt(64, 64, 64);
|
||||
public static final int BROWN = rgbToInt(128, 64, 0);
|
||||
public static final int BROWN = rgbToInt(68, 46, 24);
|
||||
public static final int LIGHT_BROWN = rgbToInt(130, 112, 67);
|
||||
public static final int PURPLE = rgbToInt(128, 0, 128);
|
||||
|
||||
|
||||
|
||||
@@ -138,8 +138,7 @@ public class LodUtil
|
||||
public static final int MAX_ALLOCATABLE_DIRECT_MEMORY = 64 * 1024 * 1024;
|
||||
|
||||
/** the format of data stored in the GPU buffers */
|
||||
public static final LodVertexFormat LOD_VERTEX_FORMAT = DefaultLodVertexFormats.POSITION_COLOR_BLOCK_LIGHT_SKY_LIGHT;
|
||||
|
||||
public static final LodVertexFormat LOD_VERTEX_FORMAT = DefaultLodVertexFormats.POSITION_COLOR_BLOCK_LIGHT_SKY_LIGHT_MATERIAL_ID_NORMAL_INDEX;
|
||||
|
||||
|
||||
|
||||
|
||||
+4
-4
@@ -202,7 +202,7 @@ public class RenderDataPointReducingList
|
||||
lowerMaxY,
|
||||
RenderDataPointUtil.getLightSky(higherData),
|
||||
RenderDataPointUtil.getLightBlock(higherData),
|
||||
RenderDataPointUtil.getGenerationMode(higherData)
|
||||
RenderDataPointUtil.getBlockMaterialId(higherData)
|
||||
)
|
||||
);
|
||||
|
||||
@@ -829,7 +829,7 @@ public class RenderDataPointReducingList
|
||||
int size = view.size();
|
||||
if (size <= 0)
|
||||
{
|
||||
return RenderDataPointUtil.createVoidDataPoint((byte)(1));
|
||||
return RenderDataPointUtil.createVoidDataPoint();
|
||||
}
|
||||
|
||||
long highest;
|
||||
@@ -849,7 +849,7 @@ public class RenderDataPointReducingList
|
||||
}
|
||||
}
|
||||
//no visible segments, return void.
|
||||
return RenderDataPointUtil.createVoidDataPoint((byte) (1));
|
||||
return RenderDataPointUtil.createVoidDataPoint();
|
||||
}
|
||||
|
||||
//second loop: merge the rest of the segments.
|
||||
@@ -887,7 +887,7 @@ public class RenderDataPointReducingList
|
||||
// so, if we didn't set any data points, add a void data point.
|
||||
if (writeIndex == 0)
|
||||
{
|
||||
view.set(writeIndex++, RenderDataPointUtil.createVoidDataPoint((byte) (1)));
|
||||
view.set(writeIndex++, RenderDataPointUtil.createVoidDataPoint());
|
||||
}
|
||||
|
||||
for (int size = view.size(); writeIndex < size; writeIndex++)
|
||||
|
||||
@@ -24,8 +24,6 @@ import com.seibel.distanthorizons.core.logging.SpamReducedLogger;
|
||||
import com.seibel.distanthorizons.core.dataObjects.render.columnViews.ColumnArrayView;
|
||||
import com.seibel.distanthorizons.core.dataObjects.render.columnViews.IColumnDataView;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
|
||||
/**
|
||||
* A helper class that is used to access the data from a long
|
||||
@@ -35,7 +33,7 @@ import java.util.Arrays;
|
||||
*
|
||||
* <strong>DataPoint Format: </strong><br>
|
||||
* <code>
|
||||
* GM: generation mode <br>
|
||||
* BM: block material id <br>
|
||||
* A: color alpha <br>
|
||||
* R: color red <br>
|
||||
* G: color green <br>
|
||||
@@ -46,7 +44,7 @@ import java.util.Arrays;
|
||||
* SL: sky light <br>
|
||||
*
|
||||
* =======Bit layout======= <br>
|
||||
* _ GM GM GM A A A A | <br>
|
||||
* BM BM BM BM A A A A | <br>
|
||||
* R R R R R R R R | <br>
|
||||
* G G G G G G G G | <br>
|
||||
* B B B B B B B B | <br><br>
|
||||
@@ -74,7 +72,7 @@ public class RenderDataPointUtil
|
||||
public final static int ALPHA_DOWNSIZE_SHIFT = 4;
|
||||
|
||||
|
||||
public final static int GEN_TYPE_SHIFT = 60;
|
||||
public final static int IRIS_BLOCK_MATERIAL_ID_SHIFT = 60;
|
||||
|
||||
public final static int COLOR_SHIFT = 32;
|
||||
public final static int BLUE_SHIFT = COLOR_SHIFT;
|
||||
@@ -97,12 +95,11 @@ public class RenderDataPointUtil
|
||||
public final static long HEIGHT_DEPTH_MASK = 0xFFFFFF;
|
||||
public final static long BLOCK_LIGHT_MASK = 0xF;
|
||||
public final static long SKY_LIGHT_MASK = 0xF;
|
||||
public final static long GEN_TYPE_MASK = 0b111;
|
||||
public final static long COMPARE_SHIFT = GEN_TYPE_SHIFT;
|
||||
public final static long IRIS_BLOCK_MATERIAL_ID_MASK = 0xF;
|
||||
public final static long COMPARE_SHIFT = 0b111;
|
||||
|
||||
public final static long HEIGHT_SHIFTED_MASK = HEIGHT_MASK << HEIGHT_SHIFT;
|
||||
public final static long DEPTH_SHIFTED_MASK = DEPTH_MASK << DEPTH_SHIFT;
|
||||
public final static long GEN_TYPE_SHIFTED_MASK = GEN_TYPE_MASK << GEN_TYPE_SHIFT;
|
||||
|
||||
public final static long VOID_SETTER = HEIGHT_SHIFTED_MASK | DEPTH_SHIFTED_MASK;
|
||||
|
||||
@@ -112,27 +109,19 @@ public class RenderDataPointUtil
|
||||
// datapoint manipulation //
|
||||
//========================//
|
||||
|
||||
public static long createVoidDataPoint(byte generationMode)
|
||||
{
|
||||
if (generationMode == 0)
|
||||
{
|
||||
throw new IllegalArgumentException("Trying to create void datapoint with genMode 0, which is NOT allowed in DataPoint version 10!");
|
||||
}
|
||||
|
||||
return (generationMode & GEN_TYPE_MASK) << GEN_TYPE_SHIFT;
|
||||
}
|
||||
public static long createVoidDataPoint() { return EMPTY_DATA; }
|
||||
|
||||
public static long createDataPoint(int height, int depth, int color, int lightSky, int lightBlock, int generationMode)
|
||||
public static long createDataPoint(int height, int depth, int color, int lightSky, int lightBlock, int irisBlockMaterialId)
|
||||
{
|
||||
return createDataPoint(
|
||||
ColorUtil.getAlpha(color),
|
||||
ColorUtil.getRed(color),
|
||||
ColorUtil.getGreen(color),
|
||||
ColorUtil.getBlue(color),
|
||||
height, depth, lightSky, lightBlock, generationMode);
|
||||
height, depth, lightSky, lightBlock, irisBlockMaterialId);
|
||||
}
|
||||
|
||||
public static long createDataPoint(int height, int depth, int color, int light, int generationMode)
|
||||
public static long createDataPoint(int height, int depth, int color, int light, int irisBlockMaterialId)
|
||||
{
|
||||
LodUtil.assertTrue(light >= 0 && light < 256, "Raw Light value must be between 0 and 255!");
|
||||
|
||||
@@ -141,28 +130,29 @@ public class RenderDataPointUtil
|
||||
ColorUtil.getRed(color),
|
||||
ColorUtil.getGreen(color),
|
||||
ColorUtil.getBlue(color),
|
||||
height, depth, light % 16, light / 16, generationMode);
|
||||
height, depth,
|
||||
light % 16, light / 16,
|
||||
irisBlockMaterialId);
|
||||
}
|
||||
|
||||
public static long createDataPoint(int alpha, int red, int green, int blue, int height, int depth, int lightSky, int lightBlock, int generationMode)
|
||||
public static long createDataPoint(int alpha, int red, int green, int blue, int height, int depth, int lightSky, int lightBlock, int irisBlockMaterialId)
|
||||
{
|
||||
LodUtil.assertTrue(generationMode != 0, "Trying to create datapoint with genMode 0, which is NOT allowed in DataPoint version 10!");
|
||||
|
||||
LodUtil.assertTrue(height >= 0 && height < MAX_WORLD_Y_SIZE, "Trying to create datapoint with height[" + height + "] out of range!");
|
||||
LodUtil.assertTrue(depth >= 0 && depth < MAX_WORLD_Y_SIZE, "Trying to create datapoint with depth[" + depth + "] out of range!");
|
||||
|
||||
LodUtil.assertTrue(lightSky >= 0 && lightSky < 16, "Trying to create datapoint with lightSky[" + lightSky + "] out of range!");
|
||||
LodUtil.assertTrue(lightBlock >= 0 && lightBlock < 16, "Trying to create datapoint with lightBlock[" + lightBlock + "] out of range!");
|
||||
|
||||
LodUtil.assertTrue(irisBlockMaterialId >= 0 && irisBlockMaterialId < 256, "Trying to create datapoint with irisBlockMaterialId[" + irisBlockMaterialId + "] out of range!");
|
||||
|
||||
LodUtil.assertTrue(alpha >= 0 && alpha < 256, "Trying to create datapoint with alpha[" + alpha + "] out of range!");
|
||||
LodUtil.assertTrue(red >= 0 && red < 256, "Trying to create datapoint with red[" + red + "] out of range!");
|
||||
LodUtil.assertTrue(green >= 0 && green < 256, "Trying to create datapoint with green[" + green + "] out of range!");
|
||||
LodUtil.assertTrue(blue >= 0 && blue < 256, "Trying to create datapoint with blue[" + blue + "] out of range!");
|
||||
|
||||
LodUtil.assertTrue(generationMode >= 0 && generationMode < 8, "Trying to create datapoint with genMode[" + generationMode + "] out of range!");
|
||||
LodUtil.assertTrue(depth <= height, "Trying to create datapoint with depth[" + depth + "] greater than height[" + height + "]!");
|
||||
|
||||
return (long) (alpha >>> ALPHA_DOWNSIZE_SHIFT) << ALPHA_SHIFT
|
||||
long out = (long) (alpha >>> ALPHA_DOWNSIZE_SHIFT) << ALPHA_SHIFT
|
||||
| (red & RED_MASK) << RED_SHIFT
|
||||
| (green & GREEN_MASK) << GREEN_SHIFT
|
||||
| (blue & BLUE_MASK) << BLUE_SHIFT
|
||||
@@ -170,8 +160,10 @@ public class RenderDataPointUtil
|
||||
| (depth & DEPTH_MASK) << DEPTH_SHIFT
|
||||
| (lightBlock & BLOCK_LIGHT_MASK) << BLOCK_LIGHT_SHIFT
|
||||
| (lightSky & SKY_LIGHT_MASK) << SKY_LIGHT_SHIFT
|
||||
| (generationMode & GEN_TYPE_MASK) << GEN_TYPE_SHIFT
|
||||
| (irisBlockMaterialId & IRIS_BLOCK_MATERIAL_ID_MASK) << IRIS_BLOCK_MATERIAL_ID_SHIFT
|
||||
;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
public static long shiftHeightAndDepth(long dataPoint, short offset)
|
||||
@@ -195,19 +187,8 @@ public class RenderDataPointUtil
|
||||
public static byte getLightSky(long dataPoint) { return (byte) ((dataPoint >>> SKY_LIGHT_SHIFT) & SKY_LIGHT_MASK); }
|
||||
public static byte getLightBlock(long dataPoint) { return (byte) ((dataPoint >>> BLOCK_LIGHT_SHIFT) & BLOCK_LIGHT_MASK); }
|
||||
|
||||
public static byte getGenerationMode(long dataPoint)
|
||||
{
|
||||
byte genMode = (byte) ((dataPoint >>> GEN_TYPE_SHIFT) & GEN_TYPE_MASK);
|
||||
if (warnLogger.canMaybeLog() && doesDataPointExist(dataPoint) && genMode == 0)
|
||||
{
|
||||
warnLogger.warnInc("Existing datapoint with genMode 0 detected! This is invalid in DataPoint version 10!"
|
||||
+ " This may be caused by old data that has not been updated correctly.");
|
||||
return 1;
|
||||
}
|
||||
return (genMode == 0) ? 1 : genMode;
|
||||
}
|
||||
public static byte getBlockMaterialId(long dataPoint) { return (byte) ((dataPoint >>> IRIS_BLOCK_MATERIAL_ID_SHIFT) & IRIS_BLOCK_MATERIAL_ID_MASK); }
|
||||
|
||||
public static long overrideGenerationMode(long current, byte b) { return (current & ~GEN_TYPE_SHIFTED_MASK) | ((b & GEN_TYPE_MASK) << GEN_TYPE_SHIFT); }
|
||||
|
||||
public static boolean isVoid(long dataPoint) { return (((dataPoint >>> DEPTH_SHIFT) & HEIGHT_DEPTH_MASK) == 0); }
|
||||
|
||||
@@ -244,7 +225,7 @@ public class RenderDataPointUtil
|
||||
getGreen(dataPoint) +
|
||||
" BL:" + getLightBlock(dataPoint) +
|
||||
" SL:" + getLightSky(dataPoint) +
|
||||
" G:" + getGenerationMode(dataPoint);
|
||||
" BID:" + getBlockMaterialId(dataPoint);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+36
-1
@@ -25,11 +25,44 @@ import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
|
||||
/** A Minecraft version independent way of handling Blocks. */
|
||||
public interface IBlockStateWrapper extends IDhApiBlockStateWrapper
|
||||
{
|
||||
//===========//
|
||||
// constants //
|
||||
//===========//
|
||||
|
||||
int FULLY_TRANSPARENT = 0;
|
||||
int FULLY_OPAQUE = 16;
|
||||
int FULLY_OPAQUE = 16;
|
||||
|
||||
/** contains the indices used by Iris to determine how different block types should be rendered */
|
||||
class IrisBlockMaterial
|
||||
{
|
||||
public static final byte UNKOWN = 0;
|
||||
public static final byte LEAVES = 1;
|
||||
public static final byte STONE = 2;
|
||||
public static final byte WOOD = 3;
|
||||
public static final byte METAL = 4;
|
||||
public static final byte DIRT = 5;
|
||||
public static final byte LAVA = 6;
|
||||
public static final byte DEEPSLATE = 7;
|
||||
public static final byte SNOW = 8;
|
||||
public static final byte SAND = 9;
|
||||
public static final byte TERRACOTTA = 10;
|
||||
public static final byte NETHER_STONE = 11;
|
||||
public static final byte WATER = 12;
|
||||
// unlisted numbers are unused
|
||||
|
||||
/** shouldn't normally be needed, but just in case */
|
||||
public static final byte AIR = 14;
|
||||
public static final byte ILLUMINATED = 15; // Max value
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//=========//
|
||||
// methods //
|
||||
//=========//
|
||||
|
||||
String getSerialString();
|
||||
|
||||
/**
|
||||
@@ -40,4 +73,6 @@ public interface IBlockStateWrapper extends IDhApiBlockStateWrapper
|
||||
|
||||
int getLightEmission();
|
||||
|
||||
byte getIrisBlockMaterialId();
|
||||
|
||||
}
|
||||
|
||||
+2
@@ -54,6 +54,8 @@ public interface IMinecraftRenderWrapper extends IBindable
|
||||
|
||||
Vec3d getCameraExactPosition();
|
||||
|
||||
Mat4f getWorldViewMatrix();
|
||||
|
||||
Mat4f getDefaultProjectionMatrix(float partialTicks);
|
||||
|
||||
double getGamma();
|
||||
|
||||
+3
@@ -21,6 +21,8 @@ package com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor;
|
||||
|
||||
import com.seibel.distanthorizons.coreapi.interfaces.dependencyInjection.IBindable;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* Checks if a mod is loaded
|
||||
*
|
||||
@@ -32,4 +34,5 @@ public interface IModChecker extends IBindable
|
||||
/** Checks if a mod is loaded */
|
||||
boolean isModLoaded(String modid);
|
||||
|
||||
File modLocation(String modid);
|
||||
}
|
||||
|
||||
+1
-2
@@ -21,8 +21,7 @@ package com.seibel.distanthorizons.core.wrapperInterfaces.world;
|
||||
|
||||
import com.seibel.distanthorizons.core.pos.DhBlockPos;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.block.IBlockStateWrapper;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* @version 2022-9-16
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@
|
||||
|
||||
package com.seibel.distanthorizons.core.wrapperInterfaces.world;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import java.io.File;
|
||||
|
||||
public interface IServerLevelWrapper extends ILevelWrapper
|
||||
|
||||
@@ -265,6 +265,10 @@
|
||||
"distanthorizons.config.client.advanced.graphics.advancedGraphics":
|
||||
"Advanced Graphics Options",
|
||||
|
||||
"distanthorizons.config.client.advanced.graphics.advancedGraphics.disableFrustumCulling":
|
||||
"Disable Frustum Culling",
|
||||
"distanthorizons.config.client.advanced.graphics.advancedGraphics.disableFrustumCulling.@tooltip":
|
||||
"If false LODs outside the player's camera \naren't drawn, increasing GPU performance. \n\nIf true all LODs are drawn, even those behind \nthe player's camera, decreasing GPU performance. \n\nDisable this if you see LODs disappearing at the corners of your vision.",
|
||||
"distanthorizons.config.client.advanced.graphics.advancedGraphics.overdrawPrevention":
|
||||
"Overdraw Prevention",
|
||||
"distanthorizons.config.client.advanced.graphics.advancedGraphics.overdrawPrevention.@tooltip":
|
||||
@@ -803,6 +807,8 @@
|
||||
"Show detail",
|
||||
"distanthorizons.config.enum.EDebugRendering.SHOW_GENMODE":
|
||||
"Show generation mode",
|
||||
"distanthorizons.config.enum.EDebugRendering.SHOW_BLOCK_MATERIAL":
|
||||
"Show Material",
|
||||
"distanthorizons.config.enum.EDebugRendering.SHOW_OVERLAPPING_QUADS":
|
||||
"Show overlapping quads",
|
||||
"distanthorizons.config.enum.EDebugRendering.SHOW_RENDER_SOURCE_FLAG":
|
||||
|
||||
Reference in New Issue
Block a user