diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/DebugRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/DebugRenderer.java
index 36c3db42b..ecced576b 100644
--- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/DebugRenderer.java
+++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/DebugRenderer.java
@@ -66,7 +66,6 @@ public class DebugRenderer
private ShaderProgram basicShader;
private GLVertexBuffer vertexBuffer;
private GLElementBuffer outlineIndexBuffer;
- private GLElementBuffer solidIndexBuffer;
private AbstractVertexAttribute va;
private boolean init = false;
@@ -110,30 +109,6 @@ public class DebugRenderer
3, 7,
};
- private static final int[] SOLID_BOX_INDICES = {
- // min Z, vertical face
- 0, 3, 2,
- 2, 1, 0,
- // max Z, vertical face
- 4, 5, 6,
- 6, 7, 4,
-
- // min X, vertical face
- 7, 3, 0,
- 0, 4, 7,
- // max X, vertical face
- 2, 6, 5,
- 5, 1, 2,
-
- // min Y, horizontal face
- 1, 5, 4,
- 4, 0, 1,
- // max Y, horizontal face
- 3, 7, 6,
- 6, 2, 3,
- };
-
-
//=============//
@@ -210,16 +185,6 @@ public class DebugRenderer
this.outlineIndexBuffer = new GLElementBuffer(false);
this.outlineIndexBuffer.uploadBuffer(boxOutlineBuffer, EDhApiGpuUploadMethod.DATA, BOX_OUTLINE_INDICES.length * Integer.BYTES, GL32.GL_STATIC_DRAW);
-
- // solid vertex indexes
- ByteBuffer solidIndexBuffer = ByteBuffer.allocateDirect(SOLID_BOX_INDICES.length * Integer.BYTES);
- solidIndexBuffer.order(ByteOrder.nativeOrder());
- solidIndexBuffer.asIntBuffer().put(SOLID_BOX_INDICES);
- solidIndexBuffer.rewind();
- this.solidIndexBuffer = new GLElementBuffer(false);
- this.solidIndexBuffer.uploadBuffer(solidIndexBuffer, EDhApiGpuUploadMethod.DATA, SOLID_BOX_INDICES.length * Integer.BYTES, GL32.GL_STATIC_DRAW);
- this.solidIndexBuffer.bind();
-
}
public void render(Mat4f transform)
@@ -259,12 +224,6 @@ public class DebugRenderer
}
- this.solidIndexBuffer.bind();
- renderSolidBox(new Box(new Vec3f(0f,0f,0f), new Vec3f(16f,190f,16f), Color.CYAN), SOLID_BOX_INDICES);
-
-
-
- this.basicShader.unbind();
glState.restore();
}
@@ -279,17 +238,6 @@ public class DebugRenderer
GL32.glDrawElements(GL32.GL_LINES, BOX_OUTLINE_INDICES.length, GL32.GL_UNSIGNED_INT, 0);
}
- public void renderSolidBox(Box box, int[] drawIndices)
- {
- Mat4f boxTransform = Mat4f.createTranslateMatrix(box.a.x - this.camPosFloatThisFrame.x, box.a.y - this.camPosFloatThisFrame.y, box.a.z - this.camPosFloatThisFrame.z);
- boxTransform.multiply(Mat4f.createScaleMatrix(box.b.x - box.a.x, box.b.y - box.a.y, box.b.z - box.a.z));
- Mat4f transformMatrix = this.transformationMatrixThisFrame.copy();
- transformMatrix.multiply(boxTransform);
- this.basicShader.setUniform(this.basicShader.getUniformLocation("transform"), transformMatrix);
- this.basicShader.setUniform(this.basicShader.getUniformLocation("uColor"), box.color);
- GL32.glDrawElements(GL32.GL_TRIANGLES , drawIndices.length, GL32.GL_UNSIGNED_INT, 0);
- }
-
//================//
diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/GenericCubeRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/GenericCubeRenderer.java
new file mode 100644
index 000000000..1a68cefae
--- /dev/null
+++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/GenericCubeRenderer.java
@@ -0,0 +1,470 @@
+/*
+ * 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 .
+ */
+
+package com.seibel.distanthorizons.core.render.renderer;
+
+import com.seibel.distanthorizons.api.enums.config.EDhApiGpuUploadMethod;
+import com.seibel.distanthorizons.api.enums.config.EDhApiLoggerMode;
+import com.seibel.distanthorizons.core.config.Config;
+import com.seibel.distanthorizons.core.config.types.ConfigEntry;
+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.DhBlockPos2D;
+import com.seibel.distanthorizons.core.pos.DhLodPos;
+import com.seibel.distanthorizons.core.pos.DhSectionPos;
+import com.seibel.distanthorizons.core.render.glObject.GLState;
+import com.seibel.distanthorizons.core.render.glObject.buffer.GLElementBuffer;
+import com.seibel.distanthorizons.core.render.glObject.buffer.GLVertexBuffer;
+import com.seibel.distanthorizons.core.render.glObject.shader.ShaderProgram;
+import com.seibel.distanthorizons.core.render.glObject.vertexAttribute.AbstractVertexAttribute;
+import com.seibel.distanthorizons.core.render.glObject.vertexAttribute.VertexPointer;
+import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
+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.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.lwjgl.opengl.GL32;
+
+import java.awt.*;
+import java.io.Closeable;
+import java.lang.ref.WeakReference;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.concurrent.PriorityBlockingQueue;
+
+public class GenericCubeRenderer
+{
+ public static GenericCubeRenderer INSTANCE = new GenericCubeRenderer();
+
+ public static final ConfigBasedLogger LOGGER = new ConfigBasedLogger(LogManager.getLogger(GenericCubeRenderer.class), () -> EDhApiLoggerMode.LOG_ALL_TO_CHAT);
+ public static final ConfigBasedSpamLogger SPAM_LOGGER = new ConfigBasedSpamLogger(LogManager.getLogger(TestRenderer.class), () -> EDhApiLoggerMode.LOG_ALL_TO_CHAT, 1);
+
+ private static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class);
+
+
+ // rendering setup
+ private ShaderProgram basicUnlitShader;
+ private GLVertexBuffer vertexBuffer;
+ private GLElementBuffer solidIndexBuffer;
+ private AbstractVertexAttribute va;
+ private boolean init = false;
+
+ // used when rendering
+ private Mat4f transformationMatrixThisFrame;
+ private Vec3f camPosFloatThisFrame;
+
+
+ //private final RendererLists rendererLists = new RendererLists();
+ //private final PriorityBlockingQueue particles = new PriorityBlockingQueue<>();
+
+
+
+ /** A box from 0,0,0 to 1,1,1 */
+ private static final float[] BOX_VERTICIES = {
+ // Pos x y z
+ 0, 0, 0,
+ 1, 0, 0,
+ 1, 1, 0,
+ 0, 1, 0,
+ 0, 0, 1,
+ 1, 0, 1,
+ 1, 1, 1,
+ 0, 1, 1,
+ };
+
+ private static final int[] SOLID_BOX_INDICES = {
+ // min Z, vertical face
+ 0, 3, 2,
+ 2, 1, 0,
+ // max Z, vertical face
+ 4, 5, 6,
+ 6, 7, 4,
+
+ // min X, vertical face
+ 7, 3, 0,
+ 0, 4, 7,
+ // max X, vertical face
+ 2, 6, 5,
+ 5, 1, 2,
+
+ // min Y, horizontal face
+ 1, 5, 4,
+ 4, 0, 1,
+ // max Y, horizontal face
+ 3, 7, 6,
+ 6, 2, 3,
+ };
+
+
+
+ //=============//
+ // constructor //
+ //=============//
+
+ public GenericCubeRenderer() { }
+
+
+
+ //==============//
+ // registration //
+ //==============//
+
+ //public static void makeParticle(BoxParticle particle)
+ //{
+ // if (INSTANCE != null && Config.Client.Advanced.Debugging.DebugWireframe.enableRendering.get())
+ // {
+ // INSTANCE.particles.add(particle);
+ // }
+ //}
+ //
+ //public static void register(IDebugRenderable renderable, ConfigEntry config) { if (INSTANCE != null) { INSTANCE.addRenderer(renderable, config); } }
+ //public void addRenderer(IDebugRenderable renderable, ConfigEntry config) { this.rendererLists.addRenderable(renderable, config); }
+ //
+ //public static void unregister(IDebugRenderable renderable, ConfigEntry config) { if (INSTANCE != null) { INSTANCE.removeRenderer(renderable, config); } }
+ //private void removeRenderer(IDebugRenderable renderable, ConfigEntry config) { this.rendererLists.removeRenderable(renderable, config); }
+ //
+ //public static void clearRenderables() { INSTANCE.rendererLists.clearRenderables(); }
+
+
+
+ //===========//
+ // rendering //
+ //===========//
+
+ public void init()
+ {
+ if (this.init)
+ {
+ return;
+ }
+
+ this.init = true;
+ this.va = AbstractVertexAttribute.create();
+ this.va.bind();
+ // Pos
+ this.va.setVertexAttribute(0, 0, VertexPointer.addVec3Pointer(false));
+ this.va.completeAndCheck(Float.BYTES * 3);
+ this.basicUnlitShader = new ShaderProgram("shaders/debug/vert.vert", "shaders/debug/frag.frag",
+ "fragColor", new String[]{"vPosition"});
+ this.createBuffers();
+ }
+
+ private void createBuffers()
+ {
+ // cube vertices
+ ByteBuffer boxVerticesBuffer = ByteBuffer.allocateDirect(BOX_VERTICIES.length * Float.BYTES);
+ boxVerticesBuffer.order(ByteOrder.nativeOrder());
+ boxVerticesBuffer.asFloatBuffer().put(BOX_VERTICIES);
+ boxVerticesBuffer.rewind();
+ this.vertexBuffer = new GLVertexBuffer(false);
+ this.vertexBuffer.bind();
+ this.vertexBuffer.uploadBuffer(boxVerticesBuffer, 8, EDhApiGpuUploadMethod.DATA, BOX_VERTICIES.length * Float.BYTES);
+
+
+ // cube vertex indexes
+ ByteBuffer solidIndexBuffer = ByteBuffer.allocateDirect(SOLID_BOX_INDICES.length * Integer.BYTES);
+ solidIndexBuffer.order(ByteOrder.nativeOrder());
+ solidIndexBuffer.asIntBuffer().put(SOLID_BOX_INDICES);
+ solidIndexBuffer.rewind();
+ this.solidIndexBuffer = new GLElementBuffer(false);
+ this.solidIndexBuffer.uploadBuffer(solidIndexBuffer, EDhApiGpuUploadMethod.DATA, SOLID_BOX_INDICES.length * Integer.BYTES, GL32.GL_STATIC_DRAW);
+ this.solidIndexBuffer.bind();
+
+ }
+
+ public void render(Mat4f transform)
+ {
+ this.transformationMatrixThisFrame = transform;
+ Vec3d camPos = MC_RENDER.getCameraExactPosition();
+ this.camPosFloatThisFrame = new Vec3f((float) camPos.x, (float) camPos.y, (float) camPos.z);
+
+ GLState glState = new GLState();
+ this.init();
+
+ GL32.glPolygonMode(GL32.GL_FRONT_AND_BACK, GL32.GL_FILL);
+ GL32.glEnable(GL32.GL_DEPTH_TEST);
+
+ this.basicUnlitShader.bind();
+ this.va.bind();
+ this.va.bindBufferToAllBindingPoints(this.vertexBuffer.getId());
+
+ this.solidIndexBuffer.bind();
+
+ //this.rendererLists.render(this);
+
+ renderUnlitCube(new Box(new Vec3f(0f,0f,0f), new Vec3f(16f,190f,16f), Color.CYAN));
+
+
+ this.basicUnlitShader.unbind();
+ glState.restore();
+ }
+
+ private void renderUnlitCube(Box box)
+ {
+ Mat4f boxTransform = Mat4f.createTranslateMatrix(box.a.x - this.camPosFloatThisFrame.x, box.a.y - this.camPosFloatThisFrame.y, box.a.z - this.camPosFloatThisFrame.z);
+ boxTransform.multiply(Mat4f.createScaleMatrix(box.b.x - box.a.x, box.b.y - box.a.y, box.b.z - box.a.z));
+ Mat4f transformMatrix = this.transformationMatrixThisFrame.copy();
+ transformMatrix.multiply(boxTransform);
+ this.basicUnlitShader.setUniform(this.basicUnlitShader.getUniformLocation("transform"), transformMatrix);
+
+ this.basicUnlitShader.setUniform(this.basicUnlitShader.getUniformLocation("uColor"), box.color);
+
+ GL32.glDrawElements(GL32.GL_TRIANGLES , SOLID_BOX_INDICES.length, GL32.GL_UNSIGNED_INT, 0);
+ }
+
+
+
+ //================//
+ // helper classes //
+ //================//
+
+ public static final class Box
+ {
+ public Vec3f a;
+ public Vec3f b;
+ public Color color;
+
+
+
+ public Box(Vec3f a, Vec3f b, Color color)
+ {
+ this.a = a;
+ this.b = b;
+ this.color = color;
+ }
+
+ public Box(Vec3f a, Vec3f b, Color color, Vec3f margin)
+ {
+ this.a = a;
+ this.a.add(margin);
+ this.b = b;
+ this.b.subtract(margin);
+ this.color = color;
+ }
+
+ public Box(DhLodPos pos, float minY, float maxY, float marginPercent, Color color)
+ {
+ DhBlockPos2D blockMin = pos.getCornerBlockPos();
+ DhBlockPos2D blockMax = blockMin.add(pos.getBlockWidth(), pos.getBlockWidth());
+ float edge = pos.getBlockWidth() * marginPercent;
+ Vec3f a = new Vec3f(blockMin.x + edge, minY, blockMin.z + edge);
+ Vec3f b = new Vec3f(blockMax.x - edge, maxY, blockMax.z - edge);
+ this.a = a;
+ this.b = b;
+ this.color = color;
+ }
+
+ public Box(DhLodPos pos, float y, float yDiff, Object hash, float marginPercent, Color color)
+ {
+ float hashY = ((float) hash.hashCode() / Integer.MAX_VALUE) * yDiff;
+ DhBlockPos2D blockMin = pos.getCornerBlockPos();
+ DhBlockPos2D blockMax = blockMin.add(pos.getBlockWidth(), pos.getBlockWidth());
+ float edge = pos.getBlockWidth() * marginPercent;
+ Vec3f a = new Vec3f(blockMin.x + edge, hashY, blockMin.z + edge);
+ Vec3f b = new Vec3f(blockMax.x - edge, hashY, blockMax.z - edge);
+ this.a = a;
+ this.b = b;
+ this.color = color;
+ }
+
+ public Box(long pos, float minY, float maxY, float marginPercent, Color color)
+ {
+ this(DhSectionPos.getSectionBBoxPos(pos), minY, maxY, marginPercent, color);
+ }
+
+ public Box(long pos, float y, float yDiff, Object hash, float marginPercent, Color color)
+ {
+ this(DhSectionPos.getSectionBBoxPos(pos), y, yDiff, hash, marginPercent, color);
+ }
+
+ }
+
+ //public static final class BoxParticle implements Comparable
+ //{
+ // public Box box;
+ // public long startTime;
+ // public long duration;
+ // public float yChange;
+ //
+ // public BoxParticle(Box box, long startTime, long duration, float yChange)
+ // {
+ // this.box = box;
+ // this.startTime = startTime;
+ // this.duration = duration;
+ // this.yChange = yChange;
+ // }
+ //
+ // public BoxParticle(Box box, long nanoSecondDuratoin, float yChange) { this(box, System.nanoTime(), nanoSecondDuratoin, yChange); }
+ //
+ // public BoxParticle(Box box, double secondDuration, float yChange) { this(box, System.nanoTime(), (long) (secondDuration * 1000000000), yChange); }
+ //
+ //
+ // @Override
+ // public int compareTo(@NotNull BoxParticle particle)
+ // {
+ // return Long.compare(this.startTime + this.duration, particle.startTime + particle.duration);
+ // }
+ //
+ // public Box getBox()
+ // {
+ // long now = System.nanoTime();
+ // float percent = (now - this.startTime) / (float) this.duration;
+ // percent = (float) Math.pow(percent, 4);
+ // float yDiff = this.yChange * percent;
+ // return new Box(new Vec3f(this.box.a.x, this.box.a.y + yDiff, this.box.a.z), new Vec3f(this.box.b.x, this.box.b.y + yDiff, this.box.b.z), this.box.color);
+ // }
+ //
+ // public boolean isDead(long time) { return (time - this.startTime) > this.duration; }
+ //
+ //}
+
+
+ //private static class RendererLists
+ //{
+ // public final LinkedList> generalRenderableList = new LinkedList<>();
+ //
+ // private final HashMap, LinkedList>> renderableListByConfig = new HashMap<>();
+ //
+ //
+ //
+ // // registration //
+ //
+ // public void addRenderable(IDebugRenderable renderable, @Nullable ConfigEntry config)
+ // {
+ // synchronized (this)
+ // {
+ // if (config != null)
+ // {
+ // if (!this.renderableListByConfig.containsKey(config))
+ // {
+ // this.renderableListByConfig.put(config, new LinkedList<>());
+ // }
+ //
+ // LinkedList> renderableList = this.renderableListByConfig.get(config);
+ // renderableList.add(new WeakReference<>(renderable));
+ // }
+ // else
+ // {
+ // this.generalRenderableList.add(new WeakReference<>(renderable));
+ // }
+ // }
+ // }
+ //
+ // public void removeRenderable(IDebugRenderable renderable, @Nullable ConfigEntry config)
+ // {
+ // synchronized (this)
+ // {
+ // if (config != null)
+ // {
+ // if (this.renderableListByConfig.containsKey(config))
+ // {
+ // LinkedList> renderableList = this.renderableListByConfig.get(config);
+ // this.removeRenderableFromInternalList(renderableList, renderable);
+ // }
+ // }
+ // else
+ // {
+ // this.removeRenderableFromInternalList(this.generalRenderableList, renderable);
+ // }
+ // }
+ // }
+ // private void removeRenderableFromInternalList(LinkedList> rendererList, IDebugRenderable renderable)
+ // {
+ // Iterator> iterator = rendererList.iterator();
+ // while (iterator.hasNext())
+ // {
+ // WeakReference renderableRef = iterator.next();
+ // if (renderableRef.get() == null)
+ // {
+ // iterator.remove();
+ // continue;
+ // }
+ //
+ // if (renderableRef.get() == renderable)
+ // {
+ // iterator.remove();
+ // return;
+ // }
+ // }
+ // }
+ //
+ // public void clearRenderables()
+ // {
+ // for (ConfigEntry config : this.renderableListByConfig.keySet())
+ // {
+ // LinkedList> renderableList = this.renderableListByConfig.get(config);
+ // if (config.get() && renderableList != null)
+ // {
+ // renderableList.clear();
+ // }
+ // }
+ // }
+ //
+ //
+ //
+ // // rendering //
+ //
+ // public void render(GenericCubeRenderer debugRenderer)
+ // {
+ // this.renderList(debugRenderer, this.generalRenderableList);
+ //
+ // for (ConfigEntry config : this.renderableListByConfig.keySet())
+ // {
+ // LinkedList> renderableList = this.renderableListByConfig.get(config);
+ // if (config.get() && renderableList != null && renderableList.size() != 0)
+ // {
+ // this.renderList(debugRenderer, renderableList);
+ // }
+ // }
+ // }
+ // private void renderList(GenericCubeRenderer debugRenderer, LinkedList> rendererList)
+ // {
+ // synchronized (this)
+ // {
+ // try
+ // {
+ // Iterator> iterator = rendererList.iterator();
+ // while (iterator.hasNext())
+ // {
+ // WeakReference ref = iterator.next();
+ // IDebugRenderable renderable = ref.get();
+ // if (renderable == null)
+ // {
+ // iterator.remove();
+ // continue;
+ // }
+ //
+ // renderable.debugRender(debugRenderer);
+ // }
+ // }
+ // catch (Exception e)
+ // {
+ // SPAM_LOGGER.error("Unexpected Debug renderer error, Error: "+e.getMessage(), e);
+ // }
+ // }
+ // }
+ //}
+
+}
diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/LodRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/LodRenderer.java
index 780afd0fb..f23c4fb8f 100644
--- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/LodRenderer.java
+++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/LodRenderer.java
@@ -422,6 +422,15 @@ public class LodRenderer
// Note: this can be very slow if a lot of boxes are being rendered
DebugRenderer.INSTANCE.render(combinedMatrix);
+ }
+
+ profiler.popPush("Generic Cubes");
+
+ {
+ Mat4f combinedMatrix = new Mat4f(renderEventParam.dhProjectionMatrix);
+ combinedMatrix.multiply(renderEventParam.dhModelViewMatrix);
+
+ GenericCubeRenderer.INSTANCE.render(combinedMatrix);
profiler.popPush("LOD cleanup");
}