Changes for blaze/gl rendering config
This commit is contained in:
+6
-4
@@ -28,15 +28,17 @@ dependencies { // All of these dependencies are in Vanilla Minecraft, but we nee
|
||||
implementation "org.lwjgl:lwjgl"
|
||||
implementation "org.lwjgl:lwjgl-assimp"
|
||||
implementation "org.lwjgl:lwjgl-glfw"
|
||||
implementation "org.lwjgl:lwjgl-openal"
|
||||
implementation "org.lwjgl:lwjgl-opengl"
|
||||
// OpenGL is removed since DH now handles rendering in the "Common" project
|
||||
// so we can use OpenGL for old MC versions and Blaze3D (IE Vulkan) for newer ones
|
||||
// implementation "org.lwjgl:lwjgl-openal"
|
||||
// implementation "org.lwjgl:lwjgl-opengl"
|
||||
implementation "org.lwjgl:lwjgl-stb"
|
||||
implementation "org.lwjgl:lwjgl-tinyfd"
|
||||
runtimeOnly "org.lwjgl:lwjgl::$lwjglNatives"
|
||||
runtimeOnly "org.lwjgl:lwjgl-assimp::$lwjglNatives"
|
||||
runtimeOnly "org.lwjgl:lwjgl-glfw::$lwjglNatives"
|
||||
runtimeOnly "org.lwjgl:lwjgl-openal::$lwjglNatives"
|
||||
runtimeOnly "org.lwjgl:lwjgl-opengl::$lwjglNatives"
|
||||
// runtimeOnly "org.lwjgl:lwjgl-openal::$lwjglNatives"
|
||||
// runtimeOnly "org.lwjgl:lwjgl-opengl::$lwjglNatives"
|
||||
runtimeOnly "org.lwjgl:lwjgl-stb::$lwjglNatives"
|
||||
runtimeOnly "org.lwjgl:lwjgl-tinyfd::$lwjglNatives"
|
||||
|
||||
|
||||
@@ -40,6 +40,7 @@ import com.seibel.distanthorizons.core.util.objects.Pair;
|
||||
import com.seibel.distanthorizons.core.util.objects.RollingAverage;
|
||||
import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass.IDhTerrainRenderer;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass.IDhVanillaFadeRenderer;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass.IDhTestTriangleRenderer;
|
||||
import com.seibel.distanthorizons.coreapi.DependencyInjection.ApiEventInjector;
|
||||
@@ -595,7 +596,7 @@ public class ClientApi
|
||||
boolean renderingCancelled = ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeRenderEvent.class, renderParams);
|
||||
if (!renderingCancelled)
|
||||
{
|
||||
BlazeLodRenderer.INSTANCE.render(renderParams, profiler);
|
||||
LodRenderer.INSTANCE.render(renderParams, profiler);
|
||||
}
|
||||
|
||||
if (!DhApi.Delayed.renderProxy.getDeferTransparentRendering())
|
||||
@@ -608,7 +609,7 @@ public class ClientApi
|
||||
boolean renderingCancelled = ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeDeferredRenderEvent.class, renderParams);
|
||||
if (!renderingCancelled)
|
||||
{
|
||||
BlazeLodRenderer.INSTANCE.renderDeferred(renderParams, profiler);
|
||||
LodRenderer.INSTANCE.renderDeferred(renderParams, profiler);
|
||||
}
|
||||
|
||||
|
||||
@@ -620,14 +621,23 @@ public class ClientApi
|
||||
}
|
||||
else
|
||||
{
|
||||
IDhTestTriangleRenderer testRenderer = SingletonInjector.INSTANCE.get(IDhTestTriangleRenderer.class);
|
||||
if (testRenderer != null)
|
||||
if (!renderingDeferredLayer)
|
||||
{
|
||||
testRenderer.render();
|
||||
}
|
||||
else
|
||||
{
|
||||
RATE_LIMITED_LOGGER.warn("Unable to find singleton ["+ IDhTestTriangleRenderer.class.getSimpleName()+"]");
|
||||
IDhTerrainRenderer lodRenderer = SingletonInjector.INSTANCE.get(IDhTerrainRenderer.class);
|
||||
IDhTestTriangleRenderer testRenderer = SingletonInjector.INSTANCE.get(IDhTestTriangleRenderer.class);
|
||||
if (testRenderer != null
|
||||
&& lodRenderer != null)
|
||||
{
|
||||
lodRenderer.runRenderPassSetup(renderParams);
|
||||
|
||||
testRenderer.render();
|
||||
|
||||
lodRenderer.runRenderPassCleanup(renderParams);
|
||||
}
|
||||
else
|
||||
{
|
||||
RATE_LIMITED_LOGGER.warn("Unable to find singleton [" + IDhTestTriangleRenderer.class.getSimpleName() + "]");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -835,8 +835,9 @@ public class Config
|
||||
|
||||
public static ConfigEntry<EDhApiRenderApi> renderingApi = new ConfigEntry.Builder<EDhApiRenderApi>()
|
||||
.set(EDhApiRenderApi.AUTO)
|
||||
.setAppearance(EConfigEntryAppearance.ONLY_IN_FILE) // can't be changed while the game is running
|
||||
.comment(""
|
||||
+ "Requires a restart to change. \n"
|
||||
+ " \n"
|
||||
+ "Options: \n"
|
||||
+ EDhApiRenderApi.AUTO + " \n"
|
||||
+ EDhApiRenderApi.OPEN_GL + " \n"
|
||||
|
||||
+1
-3
@@ -215,11 +215,9 @@ public class LodBufferContainer implements AutoCloseable
|
||||
}
|
||||
IVertexBufferWrapper vbo = vbos[vboIndex];
|
||||
|
||||
IDhTerrainRenderer lodRenderer = SingletonInjector.INSTANCE.get(IDhTerrainRenderer.class);
|
||||
|
||||
ByteBuffer buffer = byteBuffers.get(i);
|
||||
int size = buffer.limit() - buffer.position();
|
||||
int vertexCount = size / lodRenderer.getVertexByteSize();
|
||||
int vertexCount = size / LodQuadBuilder.BYTES_PER_VERTEX;
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
+13
-6
@@ -57,7 +57,8 @@ public class LodQuadBuilder
|
||||
private final EDhApiDebugRendering debugRenderingMode;
|
||||
private final EDhApiGrassSideRendering grassSideRenderingMode;
|
||||
|
||||
|
||||
/** the number of bytes for */
|
||||
public static final int BYTES_PER_VERTEX = 14;
|
||||
|
||||
public static final int[][][] DIRECTION_VERTEX_IBO_QUAD = new int[][][]
|
||||
///region
|
||||
@@ -117,6 +118,7 @@ public class LodQuadBuilder
|
||||
//=============//
|
||||
// constructor //
|
||||
//=============//
|
||||
//region
|
||||
|
||||
public LodQuadBuilder(boolean doTransparency, IClientLevelWrapper clientLevelWrapper)
|
||||
{
|
||||
@@ -134,6 +136,8 @@ public class LodQuadBuilder
|
||||
|
||||
}
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
//===========//
|
||||
@@ -482,6 +486,11 @@ public class LodQuadBuilder
|
||||
}
|
||||
|
||||
private static int maxBufferByteSize = -1;
|
||||
/**
|
||||
* The max number of bytes we allow for a single Vertex buffer.
|
||||
* If an LOD has more data than this it will be split
|
||||
* up into multiple buffers.
|
||||
*/
|
||||
public static int getMaxBufferByteSize()
|
||||
{
|
||||
if (maxBufferByteSize != -1)
|
||||
@@ -489,11 +498,9 @@ public class LodQuadBuilder
|
||||
return maxBufferByteSize;
|
||||
}
|
||||
|
||||
IDhTerrainRenderer LOD_RENDERER = SingletonInjector.INSTANCE.get(IDhTerrainRenderer.class);
|
||||
|
||||
/** number of bytes a single quad takes */
|
||||
int QUADS_BYTE_SIZE = LOD_RENDERER.getVertexByteSize() * 4;
|
||||
/** how big a single VBO can be in bytes */
|
||||
// number of bytes a single quad takes
|
||||
int QUADS_BYTE_SIZE = BYTES_PER_VERTEX * 4;
|
||||
// how big a single VBO can be in bytes
|
||||
int MAX_VBO_BYTE_SIZE = 10 * 1024 * 1024; // 10 MB
|
||||
int MAX_QUADS_PER_BUFFER = MAX_VBO_BYTE_SIZE / QUADS_BYTE_SIZE;
|
||||
int FULL_SIZED_BUFFER = MAX_QUADS_PER_BUFFER * QUADS_BYTE_SIZE;
|
||||
|
||||
@@ -35,6 +35,7 @@ import com.seibel.distanthorizons.core.util.threading.PriorityTaskPicker;
|
||||
import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil;
|
||||
import com.seibel.distanthorizons.core.world.AbstractDhWorld;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.render.AbstractDhRenderApiDefinition;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass.IDhGenericRenderer;
|
||||
import com.seibel.distanthorizons.coreapi.ModInfo;
|
||||
import com.seibel.distanthorizons.coreapi.util.StringUtil;
|
||||
@@ -83,6 +84,7 @@ public class F3Screen
|
||||
{
|
||||
String r = MinecraftTextFormat.RED;
|
||||
String y = MinecraftTextFormat.YELLOW;
|
||||
String a = MinecraftTextFormat.AQUA;
|
||||
String cf = MinecraftTextFormat.CLEAR_FORMATTING;
|
||||
|
||||
|
||||
@@ -123,6 +125,9 @@ public class F3Screen
|
||||
int posX = DhSectionPos.getX(sectionPos);
|
||||
int posZ = DhSectionPos.getZ(sectionPos);
|
||||
messageList.add("LOD Pos: "+y+detailLevel+"*"+posX+","+posZ+cf);
|
||||
|
||||
AbstractDhRenderApiDefinition renderApiDef = SingletonInjector.INSTANCE.get(AbstractDhRenderApiDefinition.class);
|
||||
messageList.add("Rendering API: "+a+renderApiDef.getApiName()+cf);
|
||||
}
|
||||
messageList.add("");
|
||||
}
|
||||
|
||||
@@ -85,13 +85,13 @@ public class DhApiRenderProxy implements IDhApiRenderProxy
|
||||
@Override
|
||||
public DhApiResult<Integer> getDhDepthTextureId()
|
||||
{
|
||||
int activeTexture = BlazeLodRenderer.INSTANCE.getActiveDepthTextureId();
|
||||
int activeTexture = -1;//DhTerrainShaderProgram.OpenGlRenderState.INSTANCE.getActiveDepthTextureId();
|
||||
return (activeTexture == -1) ? DhApiResult.createFail("DH's depth texture hasn't been created and/or bound yet.", -1) : DhApiResult.createSuccess(activeTexture);
|
||||
}
|
||||
@Override
|
||||
public DhApiResult<Integer> getDhColorTextureId()
|
||||
{
|
||||
int activeTexture = BlazeLodRenderer.INSTANCE.getActiveColorTextureId();
|
||||
int activeTexture = -1;//DhTerrainShaderProgram.OpenGlRenderState.INSTANCE.getActiveColorTextureId();
|
||||
return (activeTexture == -1) ? DhApiResult.createFail("DH's color texture hasn't been created and/or bound yet.", -1) : DhApiResult.createSuccess(activeTexture);
|
||||
}
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ import com.seibel.distanthorizons.core.pos.DhSectionPos;
|
||||
import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos2D;
|
||||
import com.seibel.distanthorizons.core.render.QuadTree.LodQuadTree;
|
||||
import com.seibel.distanthorizons.core.render.QuadTree.LodRenderSection;
|
||||
import com.seibel.distanthorizons.core.render.renderer.BlazeLodRenderer;
|
||||
import com.seibel.distanthorizons.core.render.renderer.LodRenderer;
|
||||
import com.seibel.distanthorizons.core.render.renderer.cullingFrustum.DhFrustumBounds;
|
||||
import com.seibel.distanthorizons.core.render.renderer.cullingFrustum.NeverCullFrustum;
|
||||
import com.seibel.distanthorizons.core.util.objects.SortedArraySet;
|
||||
@@ -48,7 +48,7 @@ import org.joml.Matrix4fc;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* This object tells the {@link BlazeLodRenderer} what buffers to render
|
||||
* This object tells the {@link LodRenderer} what buffers to render
|
||||
*/
|
||||
public class RenderBufferHandler implements AutoCloseable
|
||||
{
|
||||
|
||||
@@ -45,7 +45,7 @@ public class RenderParams extends DhApiRenderParam
|
||||
/** @see DhRenderState#vanillaFogEnabled */
|
||||
public boolean vanillaFogEnabled;
|
||||
|
||||
public boolean validationRun = false;
|
||||
public boolean hasBeenValidated = false;
|
||||
|
||||
|
||||
|
||||
@@ -120,7 +120,7 @@ public class RenderParams extends DhApiRenderParam
|
||||
{
|
||||
// Note: all strings here should be constants to prevent String allocations
|
||||
|
||||
this.validationRun = true;
|
||||
this.hasBeenValidated = true;
|
||||
|
||||
|
||||
if (!MC_CLIENT.playerExists())
|
||||
|
||||
+1
-1
@@ -104,7 +104,7 @@ public class RenderThreadTaskHandler
|
||||
{
|
||||
runnable.run();
|
||||
|
||||
// only try running for 4ms (240 FPS) at a time to prevent random lag spikes
|
||||
// only try running for a limited amount of time to prevent lag spikes
|
||||
long currentTimeMs = System.currentTimeMillis();
|
||||
long runDuration = currentTimeMs - startTimeMs;
|
||||
if (runDuration > msMaxRunTime)
|
||||
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* This file is part of the Distant Horizons mod
|
||||
* licensed under the GNU LGPL v3 License.
|
||||
*
|
||||
* Copyright (C) 2020 James Seibel
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.distanthorizons.core.render.renderer;
|
||||
|
||||
import com.seibel.distanthorizons.api.interfaces.render.IDhApiCustomRenderObjectFactory;
|
||||
import com.seibel.distanthorizons.api.interfaces.render.IDhApiCustomRenderRegister;
|
||||
import com.seibel.distanthorizons.api.interfaces.render.IDhApiRenderableBoxGroup;
|
||||
import com.seibel.distanthorizons.api.objects.math.DhApiVec3d;
|
||||
import com.seibel.distanthorizons.api.objects.render.DhApiRenderableBox;
|
||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Handles creating {@link DhApiRenderableBox}.
|
||||
*
|
||||
* @see IDhApiCustomRenderRegister
|
||||
* @see DhApiRenderableBox
|
||||
*/
|
||||
public class GenericRenderObjectFactory implements IDhApiCustomRenderObjectFactory
|
||||
{
|
||||
private static final DhLogger LOGGER = new DhLoggerBuilder().build();
|
||||
|
||||
public static final GenericRenderObjectFactory INSTANCE = new GenericRenderObjectFactory();
|
||||
|
||||
|
||||
|
||||
//=============//
|
||||
// constructor //
|
||||
//=============//
|
||||
|
||||
private GenericRenderObjectFactory() { }
|
||||
|
||||
|
||||
|
||||
//================//
|
||||
// group creation //
|
||||
//================//
|
||||
|
||||
@Override
|
||||
public IDhApiRenderableBoxGroup createForSingleBox(String resourceLocation, DhApiRenderableBox box)
|
||||
{
|
||||
ArrayList<DhApiRenderableBox> list = new ArrayList<>();
|
||||
list.add(box);
|
||||
return this.createAbsolutePositionedGroup(resourceLocation, list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IDhApiRenderableBoxGroup createRelativePositionedGroup(String resourceLocation, DhApiVec3d originBlockPos, List<DhApiRenderableBox> boxList)
|
||||
{ return new RenderableBoxGroup(resourceLocation, new DhApiVec3d(originBlockPos.x, originBlockPos.y, originBlockPos.z), boxList, true); }
|
||||
|
||||
@Override
|
||||
public IDhApiRenderableBoxGroup createAbsolutePositionedGroup(String resourceLocation, List<DhApiRenderableBox> boxList)
|
||||
{ return new RenderableBoxGroup(resourceLocation, new DhApiVec3d(0, 0, 0), boxList, false); }
|
||||
|
||||
}
|
||||
+19
-31
@@ -39,7 +39,7 @@ import com.seibel.distanthorizons.coreapi.DependencyInjection.ApiEventInjector;
|
||||
* This is where all the magic happens. <br>
|
||||
* This is where LODs are draw to the world.
|
||||
*/
|
||||
public class BlazeLodRenderer
|
||||
public class LodRenderer
|
||||
{
|
||||
public static final DhLogger LOGGER = new DhLoggerBuilder()
|
||||
.fileLevelConfig(Config.Common.Logging.logRendererEventToFile)
|
||||
@@ -52,19 +52,22 @@ public class BlazeLodRenderer
|
||||
|
||||
private static final IMinecraftClientWrapper MC = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class);
|
||||
|
||||
public static final BlazeLodRenderer INSTANCE = new BlazeLodRenderer();
|
||||
public static final LodRenderer INSTANCE = new LodRenderer();
|
||||
|
||||
|
||||
|
||||
private boolean renderObjectsCreated = false;
|
||||
private boolean vanillaSettingsOverridden = false;
|
||||
|
||||
|
||||
|
||||
//=============//
|
||||
// constructor //
|
||||
//=============//
|
||||
//region
|
||||
|
||||
private BlazeLodRenderer() { }
|
||||
private LodRenderer() { }
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
@@ -105,7 +108,7 @@ public class BlazeLodRenderer
|
||||
boolean firstPass = !runningDeferredPass;
|
||||
|
||||
// RenderParams parameter validation should be done before this
|
||||
if (!renderParams.validationRun)
|
||||
if (!renderParams.hasBeenValidated)
|
||||
{
|
||||
throw new IllegalArgumentException("Render parameters validation");
|
||||
}
|
||||
@@ -113,6 +116,11 @@ public class BlazeLodRenderer
|
||||
RenderBufferHandler renderBufferHandler = renderParams.renderBufferHandler;
|
||||
IDhGenericRenderer genericRenderer = renderParams.genericRenderer;
|
||||
|
||||
IDhTerrainRenderer lodRenderer = SingletonInjector.INSTANCE.get(IDhTerrainRenderer.class);
|
||||
IDhSsaoRenderer ssaoRenderer = SingletonInjector.INSTANCE.get(IDhSsaoRenderer.class);
|
||||
IDhFogRenderer fogRenderer = SingletonInjector.INSTANCE.get(IDhFogRenderer.class);
|
||||
IDhFarFadeRenderer farFadeRenderer = SingletonInjector.INSTANCE.get(IDhFarFadeRenderer.class);
|
||||
AbstractDebugWireframeRenderer debugWireframeRenderer = SingletonInjector.INSTANCE.get(AbstractDebugWireframeRenderer.class);
|
||||
|
||||
|
||||
//=================//
|
||||
@@ -122,7 +130,9 @@ public class BlazeLodRenderer
|
||||
ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeRenderSetupEvent.class, renderParams);
|
||||
profiler.push("LOD GL setup");
|
||||
|
||||
if (!this.renderObjectsCreated)
|
||||
lodRenderer.runRenderPassSetup(renderParams);
|
||||
|
||||
if (!this.vanillaSettingsOverridden)
|
||||
{
|
||||
// only do this once, that way they can still be reverted if desired
|
||||
if (Config.Client.Advanced.Graphics.overrideVanillaGraphicsSettings.get())
|
||||
@@ -134,7 +144,7 @@ public class BlazeLodRenderer
|
||||
MC.disableFabulousTransparency();
|
||||
}
|
||||
|
||||
this.renderObjectsCreated = true;
|
||||
this.vanillaSettingsOverridden = true;
|
||||
}
|
||||
|
||||
if (firstPass)
|
||||
@@ -144,12 +154,6 @@ public class BlazeLodRenderer
|
||||
renderBufferHandler.buildRenderList(renderParams);
|
||||
}
|
||||
|
||||
IDhTerrainRenderer lodRenderer = SingletonInjector.INSTANCE.get(IDhTerrainRenderer.class);
|
||||
IDhSsaoRenderer ssaoRenderer = SingletonInjector.INSTANCE.get(IDhSsaoRenderer.class);
|
||||
IDhFogRenderer fogRenderer = SingletonInjector.INSTANCE.get(IDhFogRenderer.class);
|
||||
IDhFarFadeRenderer farFadeRenderer = SingletonInjector.INSTANCE.get(IDhFarFadeRenderer.class);
|
||||
AbstractDebugWireframeRenderer debugWireframeRenderer = SingletonInjector.INSTANCE.get(AbstractDebugWireframeRenderer.class);
|
||||
|
||||
|
||||
|
||||
//===========//
|
||||
@@ -274,6 +278,8 @@ public class BlazeLodRenderer
|
||||
profiler.popPush("LOD cleanup");
|
||||
ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeRenderCleanupEvent.class, renderParams);
|
||||
|
||||
lodRenderer.runRenderPassCleanup(renderParams);
|
||||
|
||||
|
||||
|
||||
// end of internal LOD profiling
|
||||
@@ -310,22 +316,4 @@ public class BlazeLodRenderer
|
||||
|
||||
|
||||
|
||||
//===============//
|
||||
// API functions //
|
||||
//===============//
|
||||
//region
|
||||
|
||||
/** @return -1 if no frame buffer has been bound yet */
|
||||
public int getActiveFramebufferId() { return -1; }
|
||||
|
||||
/** @return -1 if no texture has been bound yet */
|
||||
public int getActiveColorTextureId() { return -1; }
|
||||
|
||||
/** @return -1 if no texture has been bound yet */
|
||||
public int getActiveDepthTextureId() { return -1; }
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
}
|
||||
+361
@@ -0,0 +1,361 @@
|
||||
package com.seibel.distanthorizons.core.render.renderer;
|
||||
|
||||
import com.seibel.distanthorizons.api.interfaces.render.IDhApiRenderableBoxGroup;
|
||||
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiRenderParam;
|
||||
import com.seibel.distanthorizons.api.objects.math.DhApiVec3d;
|
||||
import com.seibel.distanthorizons.api.objects.render.DhApiRenderableBox;
|
||||
import com.seibel.distanthorizons.api.objects.render.DhApiRenderableBoxGroupShading;
|
||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||
import com.seibel.distanthorizons.core.render.RenderThreadTaskHandler;
|
||||
import com.seibel.distanthorizons.core.util.LodUtil;
|
||||
import com.seibel.distanthorizons.core.util.threading.PriorityTaskPicker;
|
||||
import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.IWrapperFactory;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.render.objects.IDhGenericObjectVertexBufferContainer;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.RejectedExecutionException;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.function.UnaryOperator;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class RenderableBoxGroup
|
||||
extends AbstractList<DhApiRenderableBox>
|
||||
implements IDhApiRenderableBoxGroup, Closeable
|
||||
{
|
||||
private static final DhLogger LOGGER = new DhLoggerBuilder().build();
|
||||
|
||||
private static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class);
|
||||
private static final IWrapperFactory WRAPPER_FACTORY = SingletonInjector.INSTANCE.get(IWrapperFactory.class);
|
||||
|
||||
public static final AtomicInteger NEXT_ID_ATOMIC_INT = new AtomicInteger(0);
|
||||
|
||||
|
||||
|
||||
public final long id;
|
||||
|
||||
public final String resourceLocationNamespace;
|
||||
public final String resourceLocationPath;
|
||||
|
||||
/** If false the boxes will be positioned relative to the level's origin */
|
||||
public final boolean positionBoxesRelativeToGroupOrigin;
|
||||
|
||||
private final List<DhApiRenderableBox> boxList;
|
||||
/** backup list which allows for uploading the boxes even it the main list is being modified on a different thread. */
|
||||
private final List<DhApiRenderableBox> uploadBoxList;
|
||||
private final DhApiVec3d originBlockPos;
|
||||
|
||||
|
||||
public boolean active = true;
|
||||
public boolean ssaoEnabled = true;
|
||||
private boolean vertexDataDirty = true;
|
||||
|
||||
public byte skyLight = LodUtil.MAX_MC_LIGHT;
|
||||
public byte blockLight = LodUtil.MIN_MC_LIGHT;
|
||||
public DhApiRenderableBoxGroupShading shading = DhApiRenderableBoxGroupShading.getDefaultShaded();
|
||||
|
||||
@Nullable
|
||||
public Consumer<DhApiRenderParam> beforeRenderFunc;
|
||||
public Consumer<DhApiRenderParam> afterRenderFunc;
|
||||
|
||||
// instance data
|
||||
public IDhGenericObjectVertexBufferContainer vertexBufferContainer = WRAPPER_FACTORY.createGenericObjectVboContainer();
|
||||
/** double buffering for thread safety and to prevent locking the render thread during update */
|
||||
private IDhGenericObjectVertexBufferContainer altVertexBufferContainer = WRAPPER_FACTORY.createGenericObjectVboContainer();
|
||||
|
||||
|
||||
|
||||
//=================//
|
||||
// getters/setters //
|
||||
//=================//
|
||||
//region
|
||||
|
||||
@Override
|
||||
public long getId() { return this.id; }
|
||||
|
||||
@Override
|
||||
public String getResourceLocationNamespace() { return this.resourceLocationNamespace; }
|
||||
@Override
|
||||
public String getResourceLocationPath() { return this.resourceLocationPath; }
|
||||
|
||||
@Override
|
||||
public void setOriginBlockPos(DhApiVec3d pos)
|
||||
{
|
||||
this.originBlockPos.x = pos.x;
|
||||
this.originBlockPos.y = pos.y;
|
||||
this.originBlockPos.z = pos.z;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DhApiVec3d getOriginBlockPos() { return new DhApiVec3d(this.originBlockPos.x, this.originBlockPos.y, this.originBlockPos.z); }
|
||||
|
||||
|
||||
@Override
|
||||
public void setSkyLight(int skyLight)
|
||||
{
|
||||
if (skyLight < LodUtil.MIN_MC_LIGHT
|
||||
|| skyLight > LodUtil.MAX_MC_LIGHT)
|
||||
{
|
||||
throw new IllegalArgumentException("Sky light ["+skyLight+"] must be between ["+LodUtil.MIN_MC_LIGHT+"] and ["+LodUtil.MAX_MC_LIGHT+"] (inclusive).");
|
||||
}
|
||||
this.skyLight = (byte)skyLight;
|
||||
}
|
||||
@Override
|
||||
public int getSkyLight() { return this.skyLight; }
|
||||
|
||||
@Override
|
||||
public void setBlockLight(int blockLight)
|
||||
{
|
||||
if (blockLight < LodUtil.MIN_MC_LIGHT
|
||||
|| blockLight > LodUtil.MAX_MC_LIGHT)
|
||||
{
|
||||
throw new IllegalArgumentException("Block light ["+blockLight+"] must be between ["+LodUtil.MIN_MC_LIGHT+"] and ["+LodUtil.MAX_MC_LIGHT+"] (inclusive).");
|
||||
}
|
||||
this.blockLight = (byte)blockLight;
|
||||
}
|
||||
@Override
|
||||
public int getBlockLight() { return this.blockLight; }
|
||||
|
||||
@Override
|
||||
public void setPreRenderFunc(Consumer<DhApiRenderParam> func) { this.beforeRenderFunc = func; }
|
||||
|
||||
@Override
|
||||
public void setPostRenderFunc(Consumer<DhApiRenderParam> func) { this.afterRenderFunc = func; }
|
||||
|
||||
@Override
|
||||
public void setActive(boolean active) { this.active = active; }
|
||||
@Override
|
||||
public boolean isActive() { return this.active; }
|
||||
|
||||
@Override
|
||||
public void setSsaoEnabled(boolean ssaoEnabled) { this.ssaoEnabled = ssaoEnabled; }
|
||||
@Override
|
||||
public boolean isSsaoEnabled() { return this.ssaoEnabled; }
|
||||
|
||||
@Override
|
||||
public void setShading(DhApiRenderableBoxGroupShading shading) { this.shading = shading; }
|
||||
@Override
|
||||
public DhApiRenderableBoxGroupShading getShading() { return this.shading; }
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
//=============//
|
||||
// constructor //
|
||||
//=============//
|
||||
//region
|
||||
|
||||
public RenderableBoxGroup(
|
||||
String resourceLocation,
|
||||
DhApiVec3d originBlockPos, List<DhApiRenderableBox> boxList,
|
||||
boolean positionBoxesRelativeToGroupOrigin) throws IllegalArgumentException
|
||||
{
|
||||
String[] splitResourceLocation = resourceLocation.split(":");
|
||||
if (splitResourceLocation.length != 2)
|
||||
{
|
||||
throw new IllegalArgumentException("Resource Location must be a string that's separated by a single colon, for example: [DistantHorizons:Beacons], your namespace ["+resourceLocation+"], contains ["+(splitResourceLocation.length-1)+"] colons.");
|
||||
}
|
||||
|
||||
this.resourceLocationNamespace = splitResourceLocation[0];
|
||||
this.resourceLocationPath = splitResourceLocation[1];
|
||||
|
||||
this.id = NEXT_ID_ATOMIC_INT.getAndIncrement();
|
||||
this.boxList = Collections.synchronizedList(new ArrayList<>(boxList));
|
||||
this.uploadBoxList = Collections.synchronizedList(new ArrayList<>(boxList));
|
||||
|
||||
this.originBlockPos = originBlockPos;
|
||||
this.positionBoxesRelativeToGroupOrigin = positionBoxesRelativeToGroupOrigin;
|
||||
}
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
//=================//
|
||||
// render building //
|
||||
//=================//
|
||||
//region
|
||||
|
||||
@Override
|
||||
public void triggerBoxChange() { this.vertexDataDirty = true; }
|
||||
|
||||
/**
|
||||
* Does nothing if the vertex data is already up-to-date
|
||||
* and is meaningless if using direct rendering.
|
||||
*/
|
||||
public void tryUpdateInstancedDataAsync()
|
||||
{
|
||||
// if the alt container is done, swap it in
|
||||
if (this.altVertexBufferContainer.getState() == IDhGenericObjectVertexBufferContainer.EState.READY_TO_UPLOAD)
|
||||
{
|
||||
this.altVertexBufferContainer.uploadDataToGpu();
|
||||
|
||||
// swap VBO references for rendering
|
||||
IDhGenericObjectVertexBufferContainer temp = this.vertexBufferContainer;
|
||||
this.vertexBufferContainer = this.altVertexBufferContainer;
|
||||
this.altVertexBufferContainer = temp;
|
||||
|
||||
this.vertexDataDirty = false;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// if the vertex data is already up to date, do nothing
|
||||
if (!this.vertexDataDirty)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
PriorityTaskPicker.Executor executor = ThreadPoolUtil.getRenderLoadingExecutor();
|
||||
if (executor == null || executor.isTerminated())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// if the alternate container is already updating, don't double-queue it
|
||||
if (this.altVertexBufferContainer.getState() == IDhGenericObjectVertexBufferContainer.EState.UPDATING_DATA)
|
||||
{
|
||||
return;
|
||||
}
|
||||
this.altVertexBufferContainer.setState(IDhGenericObjectVertexBufferContainer.EState.UPDATING_DATA);
|
||||
|
||||
|
||||
|
||||
//this.altInstancedVbos.tryRunRenderThreadSetup();
|
||||
|
||||
// copy over the box list so we can upload without concurrent modification issues
|
||||
this.uploadBoxList.clear();
|
||||
synchronized (this.uploadBoxList)
|
||||
{
|
||||
this.uploadBoxList.addAll(this.boxList);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
executor.runTask(() ->
|
||||
{
|
||||
try
|
||||
{
|
||||
this.altVertexBufferContainer.updateVertexData(this.uploadBoxList);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOGGER.error("Unexpected error updating instanced VBO data for: ["+this+"], error: ["+e.getMessage()+"].", e);
|
||||
this.altVertexBufferContainer.setState(IDhGenericObjectVertexBufferContainer.EState.ERROR);
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (RejectedExecutionException ignore)
|
||||
{
|
||||
// the executor was shut down, it should be back up shortly and able to accept new jobs
|
||||
this.altVertexBufferContainer.setState(IDhGenericObjectVertexBufferContainer.EState.NEW);
|
||||
}
|
||||
}
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
//===============//
|
||||
// render events //
|
||||
//===============//
|
||||
//region
|
||||
|
||||
/**
|
||||
* This is called before every frame, even if {@link this#isActive()} returns false. <br>
|
||||
* {@link this#isActive()} can be changed at this point before the object is rendered to the frame.
|
||||
*/
|
||||
public void preRender(DhApiRenderParam renderEventParam)
|
||||
{
|
||||
if (this.beforeRenderFunc != null)
|
||||
{
|
||||
this.beforeRenderFunc.accept(renderEventParam);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Called after rendering is completed. <br>
|
||||
* Can be used to handle any necessary cleanup.
|
||||
*/
|
||||
public void postRender(DhApiRenderParam renderEventParam)
|
||||
{
|
||||
if (this.afterRenderFunc != null)
|
||||
{
|
||||
this.afterRenderFunc.accept(renderEventParam);
|
||||
}
|
||||
}
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
//================//
|
||||
// List Overrides //
|
||||
//================//
|
||||
//region
|
||||
|
||||
@Override
|
||||
public boolean add(DhApiRenderableBox box) { return this.boxList.add(box); }
|
||||
@Override
|
||||
public DhApiRenderableBox get(int index) { return this.boxList.get(index); }
|
||||
@Override
|
||||
public int size() { return this.boxList.size(); }
|
||||
@Override
|
||||
public boolean removeIf(Predicate<? super DhApiRenderableBox> filter) { return this.boxList.removeIf(filter); }
|
||||
@Override
|
||||
public boolean remove(Object obj) { return this.boxList.remove(obj); }
|
||||
@Override
|
||||
public DhApiRenderableBox remove(int index) { return this.boxList.remove(index); }
|
||||
@Override
|
||||
public void replaceAll(UnaryOperator<DhApiRenderableBox> operator) { this.boxList.replaceAll(operator); }
|
||||
@Override
|
||||
public void sort(Comparator<? super DhApiRenderableBox> comparator) { this.boxList.sort(comparator); }
|
||||
@Override
|
||||
public void forEach(Consumer<? super DhApiRenderableBox> action) { this.boxList.forEach(action); }
|
||||
@Override
|
||||
public Spliterator<DhApiRenderableBox> spliterator() { return this.boxList.spliterator(); }
|
||||
@Override
|
||||
public Stream<DhApiRenderableBox> stream() { return this.boxList.stream(); }
|
||||
@Override
|
||||
public Stream<DhApiRenderableBox> parallelStream() { return this.boxList.parallelStream(); }
|
||||
@Override
|
||||
public void clear() { this.boxList.clear(); }
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
//================//
|
||||
// base overrides //
|
||||
//================//
|
||||
//region
|
||||
|
||||
@Override
|
||||
public String toString() { return "["+this.resourceLocationNamespace+":"+this.resourceLocationPath+"] ID:["+this.id+"], pos:[("+this.originBlockPos.x+", "+this.originBlockPos.y+", "+this.originBlockPos.z+")], size:["+this.size()+"], active:["+this.active+"]"; }
|
||||
|
||||
@Override
|
||||
public void close()
|
||||
{
|
||||
RenderThreadTaskHandler.INSTANCE.queueRunningOnRenderThread(() ->
|
||||
{
|
||||
this.vertexBufferContainer.close();
|
||||
this.altVertexBufferContainer.close();
|
||||
});
|
||||
}
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
+12
@@ -10,6 +10,18 @@ import com.seibel.distanthorizons.coreapi.interfaces.dependencyInjection.IBindab
|
||||
|
||||
public abstract class AbstractDhRenderApiDefinition implements IBindable
|
||||
{
|
||||
//=========//
|
||||
// getters //
|
||||
//=========//
|
||||
//region
|
||||
|
||||
/** Used for debugging */
|
||||
public abstract String getApiName();
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
//============//
|
||||
// singletons //
|
||||
//============//
|
||||
|
||||
+2
-2
@@ -32,10 +32,10 @@ public interface IDhTerrainRenderer extends IBindable
|
||||
SortedArraySet<LodBufferContainer> bufferContainers,
|
||||
IProfilerWrapper profiler);
|
||||
|
||||
@Deprecated // TODO put somewhere else
|
||||
int getVertexByteSize();
|
||||
|
||||
// TODO should these go somewhere else?
|
||||
void runRenderPassSetup(RenderParams renderParams);
|
||||
void runRenderPassCleanup(RenderParams renderParams);
|
||||
void applyToMcTexture();
|
||||
void clearDepth();
|
||||
void clearColor();
|
||||
|
||||
@@ -418,7 +418,7 @@
|
||||
"distanthorizons.config.client.advanced.graphics.experimental.renderingApi":
|
||||
"Rendering API",
|
||||
"distanthorizons.config.client.advanced.graphics.experimental.renderingApi.@tooltip":
|
||||
"",
|
||||
"Requires a restart to change.",
|
||||
|
||||
|
||||
|
||||
@@ -1044,7 +1044,7 @@
|
||||
"distanthorizons.config.enum.EDhApiRendererMode.DEFAULT":
|
||||
"Default",
|
||||
"distanthorizons.config.enum.EDhApiRendererMode.DEBUG":
|
||||
"Debug",
|
||||
"Debug Triangle",
|
||||
"distanthorizons.config.enum.EDhApiRendererMode.DISABLED":
|
||||
"Disabled",
|
||||
|
||||
@@ -1121,6 +1121,15 @@
|
||||
"distanthorizons.config.enum.EDhApiGrassSideRendering.FADE_TO_DIRT":
|
||||
"Fade To Dirt",
|
||||
"distanthorizons.config.enum.EDhApiGrassSideRendering.AS_DIRT":
|
||||
"As Dirt"
|
||||
"As Dirt",
|
||||
|
||||
"distanthorizons.config.enum.EDhApiRenderApi.AUTO":
|
||||
"Auto",
|
||||
"distanthorizons.config.enum.EDhApiRenderApi.OPEN_GL":
|
||||
"OpenGL",
|
||||
"distanthorizons.config.enum.EDhApiRenderApi.BLAZE_3D":
|
||||
"Blaze3D"
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ void main()
|
||||
uint lights = meta & 0xFFu;
|
||||
float skyLight = (float(lights/16u)+0.5) / 16.0;
|
||||
float blockLight = (mod(float(lights), 16.0)+0.5) / 16.0;
|
||||
vertexColor = vec4(1.0); //vec4(texture(uLightMap, vec2(skyLight, blockLight)).xyz, 1.0);
|
||||
vertexColor = vec4(texture(uLightMap, vec2(skyLight, blockLight)).xyz, 1.0);
|
||||
|
||||
if (!uIsWhiteWorld)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user