Separate out Generic object rendering
This commit is contained in:
@@ -23,6 +23,7 @@ import com.seibel.distanthorizons.api.interfaces.events.IDhApiEventInjector;
|
||||
import com.seibel.distanthorizons.api.interfaces.factories.IDhApiWrapperFactory;
|
||||
import com.seibel.distanthorizons.api.interfaces.override.IDhApiOverrideable;
|
||||
import com.seibel.distanthorizons.api.interfaces.override.worldGenerator.IDhApiWorldGeneratorOverrideRegister;
|
||||
import com.seibel.distanthorizons.api.interfaces.render.IDhApiCustomRenderRegister;
|
||||
import com.seibel.distanthorizons.api.interfaces.render.IDhApiRenderProxy;
|
||||
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiAfterDhInitEvent;
|
||||
import com.seibel.distanthorizons.api.methods.override.DhApiWorldGeneratorOverrideRegister;
|
||||
@@ -127,6 +128,7 @@ public class DhApi
|
||||
*/
|
||||
public static IDhApiWrapperFactory wrapperFactory = null;
|
||||
|
||||
public static IDhApiCustomRenderRegister renderRegister = null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
package com.seibel.distanthorizons.api.interfaces.render;
|
||||
|
||||
import com.seibel.distanthorizons.api.objects.render.DhApiRenderableBox;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface IDhApiCustomRenderRegister
|
||||
{
|
||||
void add(IDhApiRenderableBoxGroup cubeGroup) throws IllegalArgumentException;
|
||||
|
||||
IDhApiRenderableBoxGroup remove(long id);
|
||||
|
||||
|
||||
IDhApiRenderableBoxGroup createForSingleBox(DhApiRenderableBox cube);
|
||||
IDhApiRenderableBoxGroup createRelativePositionedGroup(float originBlockX, float originBlockY, float originBlockZ, List<DhApiRenderableBox> cubeList);
|
||||
IDhApiRenderableBoxGroup createAbsolutePositionedGroup(List<DhApiRenderableBox> cubeList);
|
||||
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
package com.seibel.distanthorizons.api.interfaces.render;
|
||||
|
||||
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiRenderParam;
|
||||
import com.seibel.distanthorizons.api.objects.render.DhApiRenderableBox;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public interface IDhApiRenderableBoxGroup extends List<DhApiRenderableBox>
|
||||
{
|
||||
|
||||
|
||||
long getId();
|
||||
void setOriginBlockPos(float x, float y, float z);
|
||||
float getOriginBlockX();
|
||||
float getOriginBlockY();
|
||||
float getOriginBlockZ();
|
||||
|
||||
void setPreRenderFunc(Consumer<DhApiRenderParam> renderEventParam);
|
||||
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
package com.seibel.distanthorizons.api.objects.render;
|
||||
|
||||
|
||||
import com.seibel.distanthorizons.coreapi.util.math.Vec3f;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
public final class DhApiRenderableBox
|
||||
{
|
||||
public Vec3f minPos;
|
||||
public Vec3f maxPos;
|
||||
public Color color;
|
||||
|
||||
public boolean fullBright = false;
|
||||
|
||||
|
||||
|
||||
public DhApiRenderableBox(Vec3f minPos, Vec3f maxPos, Color color)
|
||||
{
|
||||
this.minPos = minPos;
|
||||
this.maxPos = maxPos;
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
package com.seibel.distanthorizons.core;
|
||||
|
||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||
import com.seibel.distanthorizons.core.render.renderer.GenericObjectRenderer;
|
||||
import com.seibel.distanthorizons.core.sql.DatabaseUpdater;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.IWrapperFactory;
|
||||
import com.seibel.distanthorizons.coreapi.ModInfo;
|
||||
@@ -93,6 +94,7 @@ public class Initializer
|
||||
DhApi.Delayed.terrainRepo = DhApiTerrainDataRepo.INSTANCE;
|
||||
DhApi.Delayed.worldProxy = DhApiWorldProxy.INSTANCE;
|
||||
DhApi.Delayed.renderProxy = DhApiRenderProxy.INSTANCE;
|
||||
DhApi.Delayed.renderRegister = GenericObjectRenderer.INSTANCE;
|
||||
DhApi.Delayed.wrapperFactory = SingletonInjector.INSTANCE.get(IWrapperFactory.class);
|
||||
if (DhApi.Delayed.wrapperFactory == null)
|
||||
{
|
||||
|
||||
+61
-63
@@ -80,7 +80,7 @@ public class DebugRenderer
|
||||
|
||||
|
||||
/** A box from 0,0,0 to 1,1,1 */
|
||||
private static final float[] BOX_VERTICIES = {
|
||||
private static final float[] BOX_VERTICES = {
|
||||
// Pos x y z
|
||||
0, 0, 0,
|
||||
1, 0, 0,
|
||||
@@ -115,7 +115,47 @@ public class DebugRenderer
|
||||
// constructor //
|
||||
//=============//
|
||||
|
||||
public DebugRenderer() { }
|
||||
private DebugRenderer() { }
|
||||
|
||||
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.basicShader = new ShaderProgram("shaders/debug/vert.vert", "shaders/debug/frag.frag",
|
||||
"fragColor", new String[]{"vPosition"});
|
||||
this.createBuffer();
|
||||
}
|
||||
|
||||
private void createBuffer()
|
||||
{
|
||||
// box vertices
|
||||
ByteBuffer boxVerticesBuffer = ByteBuffer.allocateDirect(BOX_VERTICES.length * Float.BYTES);
|
||||
boxVerticesBuffer.order(ByteOrder.nativeOrder());
|
||||
boxVerticesBuffer.asFloatBuffer().put(BOX_VERTICES);
|
||||
boxVerticesBuffer.rewind();
|
||||
this.vertexBuffer = new GLVertexBuffer(false);
|
||||
this.vertexBuffer.bind();
|
||||
this.vertexBuffer.uploadBuffer(boxVerticesBuffer, 8, EDhApiGpuUploadMethod.DATA, BOX_VERTICES.length * Float.BYTES);
|
||||
|
||||
|
||||
// outline vertex indexes
|
||||
ByteBuffer boxOutlineBuffer = ByteBuffer.allocateDirect(BOX_OUTLINE_INDICES.length * Integer.BYTES);
|
||||
boxOutlineBuffer.order(ByteOrder.nativeOrder());
|
||||
boxOutlineBuffer.asIntBuffer().put(BOX_OUTLINE_INDICES);
|
||||
boxOutlineBuffer.rewind();
|
||||
this.outlineIndexBuffer = new GLElementBuffer(false);
|
||||
this.outlineIndexBuffer.uploadBuffer(boxOutlineBuffer, EDhApiGpuUploadMethod.DATA, BOX_OUTLINE_INDICES.length * Integer.BYTES, GL32.GL_STATIC_DRAW);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -141,52 +181,10 @@ public class DebugRenderer
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//===========//
|
||||
// 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.basicShader = new ShaderProgram("shaders/debug/vert.vert", "shaders/debug/frag.frag",
|
||||
"fragColor", new String[]{"vPosition"});
|
||||
this.createBuffer();
|
||||
}
|
||||
|
||||
private void createBuffer()
|
||||
{
|
||||
// box 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);
|
||||
|
||||
|
||||
// outline vertex indexes
|
||||
ByteBuffer boxOutlineBuffer = ByteBuffer.allocateDirect(BOX_OUTLINE_INDICES.length * Integer.BYTES);
|
||||
boxOutlineBuffer.order(ByteOrder.nativeOrder());
|
||||
boxOutlineBuffer.asIntBuffer().put(BOX_OUTLINE_INDICES);
|
||||
boxOutlineBuffer.rewind();
|
||||
this.outlineIndexBuffer = new GLElementBuffer(false);
|
||||
this.outlineIndexBuffer.uploadBuffer(boxOutlineBuffer, EDhApiGpuUploadMethod.DATA, BOX_OUTLINE_INDICES.length * Integer.BYTES, GL32.GL_STATIC_DRAW);
|
||||
|
||||
}
|
||||
|
||||
public void render(Mat4f transform)
|
||||
{
|
||||
this.transformationMatrixThisFrame = transform;
|
||||
@@ -229,8 +227,8 @@ public class DebugRenderer
|
||||
|
||||
public void renderBox(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 boxTransform = Mat4f.createTranslateMatrix(box.minPos.x - this.camPosFloatThisFrame.x, box.minPos.y - this.camPosFloatThisFrame.y, box.minPos.z - this.camPosFloatThisFrame.z);
|
||||
boxTransform.multiply(Mat4f.createScaleMatrix(box.maxPos.x - box.minPos.x, box.maxPos.y - box.minPos.y, box.maxPos.z - box.minPos.z));
|
||||
Mat4f t = this.transformationMatrixThisFrame.copy();
|
||||
t.multiply(boxTransform);
|
||||
this.basicShader.setUniform(this.basicShader.getUniformLocation("transform"), t);
|
||||
@@ -246,25 +244,25 @@ public class DebugRenderer
|
||||
|
||||
public static final class Box
|
||||
{
|
||||
public Vec3f a;
|
||||
public Vec3f b;
|
||||
public Vec3f minPos;
|
||||
public Vec3f maxPos;
|
||||
public Color color;
|
||||
|
||||
|
||||
|
||||
public Box(Vec3f a, Vec3f b, Color color)
|
||||
public Box(Vec3f minPos, Vec3f maxPos, Color color)
|
||||
{
|
||||
this.a = a;
|
||||
this.b = b;
|
||||
this.minPos = minPos;
|
||||
this.maxPos = maxPos;
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
public Box(Vec3f a, Vec3f b, Color color, Vec3f margin)
|
||||
public Box(Vec3f minPos, Vec3f maxPos, Color color, Vec3f margin)
|
||||
{
|
||||
this.a = a;
|
||||
this.a.add(margin);
|
||||
this.b = b;
|
||||
this.b.subtract(margin);
|
||||
this.minPos = minPos;
|
||||
this.minPos.add(margin);
|
||||
this.maxPos = maxPos;
|
||||
this.maxPos.subtract(margin);
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
@@ -275,8 +273,8 @@ public class DebugRenderer
|
||||
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.minPos = a;
|
||||
this.maxPos = b;
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
@@ -288,8 +286,8 @@ public class DebugRenderer
|
||||
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.minPos = a;
|
||||
this.maxPos = b;
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
@@ -337,7 +335,7 @@ public class DebugRenderer
|
||||
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);
|
||||
return new Box(new Vec3f(this.box.minPos.x, this.box.minPos.y + yDiff, this.box.minPos.z), new Vec3f(this.box.maxPos.x, this.box.maxPos.y + yDiff, this.box.maxPos.z), this.box.color);
|
||||
}
|
||||
|
||||
public boolean isDead(long time) { return (time - this.startTime) > this.duration; }
|
||||
@@ -353,7 +351,7 @@ public class DebugRenderer
|
||||
public BoxWithLife(Box box, long ns, float yChange, Color deathColor)
|
||||
{
|
||||
this.box = box;
|
||||
this.particaleOnClose = new BoxParticle(new Box(box.a, box.b, deathColor), -1, ns, yChange);
|
||||
this.particaleOnClose = new BoxParticle(new Box(box.minPos, box.maxPos, deathColor), -1, ns, yChange);
|
||||
register(this, null);
|
||||
}
|
||||
|
||||
@@ -363,7 +361,7 @@ public class DebugRenderer
|
||||
public BoxWithLife(Box box, double s, float yChange, Color deathColor)
|
||||
{
|
||||
this.box = box;
|
||||
this.particaleOnClose = new BoxParticle(new Box(box.a, box.b, deathColor), s, yChange);
|
||||
this.particaleOnClose = new BoxParticle(new Box(box.minPos, box.maxPos, deathColor), s, yChange);
|
||||
}
|
||||
|
||||
public BoxWithLife(Box box, double s, float yChange) { this(box, s, yChange, box.color); }
|
||||
|
||||
-470
@@ -1,470 +0,0 @@
|
||||
/*
|
||||
* 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.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<BoxParticle> 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<Boolean> config) { if (INSTANCE != null) { INSTANCE.addRenderer(renderable, config); } }
|
||||
//public void addRenderer(IDebugRenderable renderable, ConfigEntry<Boolean> config) { this.rendererLists.addRenderable(renderable, config); }
|
||||
//
|
||||
//public static void unregister(IDebugRenderable renderable, ConfigEntry<Boolean> config) { if (INSTANCE != null) { INSTANCE.removeRenderer(renderable, config); } }
|
||||
//private void removeRenderer(IDebugRenderable renderable, ConfigEntry<Boolean> 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<BoxParticle>
|
||||
//{
|
||||
// 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<WeakReference<IDebugRenderable>> generalRenderableList = new LinkedList<>();
|
||||
//
|
||||
// private final HashMap<ConfigEntry<Boolean>, LinkedList<WeakReference<IDebugRenderable>>> renderableListByConfig = new HashMap<>();
|
||||
//
|
||||
//
|
||||
//
|
||||
// // registration //
|
||||
//
|
||||
// public void addRenderable(IDebugRenderable renderable, @Nullable ConfigEntry<Boolean> config)
|
||||
// {
|
||||
// synchronized (this)
|
||||
// {
|
||||
// if (config != null)
|
||||
// {
|
||||
// if (!this.renderableListByConfig.containsKey(config))
|
||||
// {
|
||||
// this.renderableListByConfig.put(config, new LinkedList<>());
|
||||
// }
|
||||
//
|
||||
// LinkedList<WeakReference<IDebugRenderable>> renderableList = this.renderableListByConfig.get(config);
|
||||
// renderableList.add(new WeakReference<>(renderable));
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// this.generalRenderableList.add(new WeakReference<>(renderable));
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// public void removeRenderable(IDebugRenderable renderable, @Nullable ConfigEntry<Boolean> config)
|
||||
// {
|
||||
// synchronized (this)
|
||||
// {
|
||||
// if (config != null)
|
||||
// {
|
||||
// if (this.renderableListByConfig.containsKey(config))
|
||||
// {
|
||||
// LinkedList<WeakReference<IDebugRenderable>> renderableList = this.renderableListByConfig.get(config);
|
||||
// this.removeRenderableFromInternalList(renderableList, renderable);
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// this.removeRenderableFromInternalList(this.generalRenderableList, renderable);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// private void removeRenderableFromInternalList(LinkedList<WeakReference<IDebugRenderable>> rendererList, IDebugRenderable renderable)
|
||||
// {
|
||||
// Iterator<WeakReference<IDebugRenderable>> iterator = rendererList.iterator();
|
||||
// while (iterator.hasNext())
|
||||
// {
|
||||
// WeakReference<IDebugRenderable> renderableRef = iterator.next();
|
||||
// if (renderableRef.get() == null)
|
||||
// {
|
||||
// iterator.remove();
|
||||
// continue;
|
||||
// }
|
||||
//
|
||||
// if (renderableRef.get() == renderable)
|
||||
// {
|
||||
// iterator.remove();
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// public void clearRenderables()
|
||||
// {
|
||||
// for (ConfigEntry<Boolean> config : this.renderableListByConfig.keySet())
|
||||
// {
|
||||
// LinkedList<WeakReference<IDebugRenderable>> 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<Boolean> config : this.renderableListByConfig.keySet())
|
||||
// {
|
||||
// LinkedList<WeakReference<IDebugRenderable>> renderableList = this.renderableListByConfig.get(config);
|
||||
// if (config.get() && renderableList != null && renderableList.size() != 0)
|
||||
// {
|
||||
// this.renderList(debugRenderer, renderableList);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// private void renderList(GenericCubeRenderer debugRenderer, LinkedList<WeakReference<IDebugRenderable>> rendererList)
|
||||
// {
|
||||
// synchronized (this)
|
||||
// {
|
||||
// try
|
||||
// {
|
||||
// Iterator<WeakReference<IDebugRenderable>> iterator = rendererList.iterator();
|
||||
// while (iterator.hasNext())
|
||||
// {
|
||||
// WeakReference<IDebugRenderable> 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);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
}
|
||||
+496
@@ -0,0 +1,496 @@
|
||||
/*
|
||||
* 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.core.render.renderer;
|
||||
|
||||
import com.seibel.distanthorizons.api.DhApi;
|
||||
import com.seibel.distanthorizons.api.enums.config.EDhApiGpuUploadMethod;
|
||||
import com.seibel.distanthorizons.api.enums.config.EDhApiLoggerMode;
|
||||
import com.seibel.distanthorizons.api.interfaces.render.IDhApiRenderableBoxGroup;
|
||||
import com.seibel.distanthorizons.api.interfaces.render.IDhApiCustomRenderRegister;
|
||||
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiRenderParam;
|
||||
import com.seibel.distanthorizons.api.objects.render.DhApiRenderableBox;
|
||||
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.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 it.unimi.dsi.fastutil.longs.Long2ReferenceOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.longs.LongSet;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.lwjgl.opengl.GL32;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.awt.*;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.util.AbstractList;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Spliterator;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.function.UnaryOperator;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class GenericObjectRenderer implements IDhApiCustomRenderRegister
|
||||
{
|
||||
public static GenericObjectRenderer INSTANCE = new GenericObjectRenderer();
|
||||
|
||||
public static final ConfigBasedLogger LOGGER = new ConfigBasedLogger(LogManager.getLogger(GenericObjectRenderer.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;
|
||||
|
||||
|
||||
// TODO may need to be double buffered to prevent rendering lag
|
||||
private final Long2ReferenceOpenHashMap<DhApiRenderableBoxGroup> boxGroupById = new Long2ReferenceOpenHashMap<>();
|
||||
private final ReentrantLock mapModifyLock = new ReentrantLock();
|
||||
|
||||
|
||||
|
||||
/** A box from 0,0,0 to 1,1,1 */
|
||||
private static final float[] BOX_VERTICES = {
|
||||
// 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 //
|
||||
//=============//
|
||||
|
||||
private GenericObjectRenderer() { }
|
||||
|
||||
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/genericObject/vert.vert", "shaders/genericObject/frag.frag",
|
||||
"fragColor", new String[]{"vPosition"});
|
||||
|
||||
this.createBuffers();
|
||||
|
||||
|
||||
|
||||
// testing //
|
||||
|
||||
// single giant cube
|
||||
IDhApiRenderableBoxGroup singleGiantCubeGroup = DhApi.Delayed.renderRegister.createForSingleBox(
|
||||
new DhApiRenderableBox(
|
||||
new Vec3f(0f,0f,0f), new Vec3f(16f,190f,16f),
|
||||
new Color(Color.CYAN.getRed(), Color.CYAN.getGreen(), Color.CYAN.getBlue(), 125))
|
||||
);
|
||||
DhApi.Delayed.renderRegister.add(singleGiantCubeGroup);
|
||||
|
||||
// single slender cube
|
||||
singleGiantCubeGroup = DhApi.Delayed.renderRegister.createForSingleBox(
|
||||
new DhApiRenderableBox(
|
||||
new Vec3f(16f,0f,31f), new Vec3f(17f,2000f,32f),
|
||||
new Color(Color.GREEN.getRed(), Color.GREEN.getGreen(), Color.GREEN.getBlue(), 125))
|
||||
);
|
||||
DhApi.Delayed.renderRegister.add(singleGiantCubeGroup);
|
||||
|
||||
// absolute cube group
|
||||
ArrayList<DhApiRenderableBox> absCubeList = new ArrayList<>();
|
||||
for (int i = 0; i < 18; i++)
|
||||
{
|
||||
absCubeList.add(new DhApiRenderableBox(
|
||||
new Vec3f(0f+i,150f+i,24f), new Vec3f(1f+i,151f+i,25f),
|
||||
new Color(Color.ORANGE.getRed(), Color.ORANGE.getGreen(), Color.ORANGE.getBlue())));
|
||||
}
|
||||
IDhApiRenderableBoxGroup absolutePosCubeGroup = DhApi.Delayed.renderRegister.createAbsolutePositionedGroup(absCubeList);
|
||||
DhApi.Delayed.renderRegister.add(absolutePosCubeGroup);
|
||||
|
||||
// relative cube group
|
||||
ArrayList<DhApiRenderableBox> relCubeList = new ArrayList<>();
|
||||
for (int i = 0; i < 8; i+=2)
|
||||
{
|
||||
relCubeList.add(new DhApiRenderableBox(
|
||||
new Vec3f(0f,0f+i,0f), new Vec3f(1f,1f+i,1f),
|
||||
new Color(Color.MAGENTA.getRed(), Color.MAGENTA.getGreen(), Color.MAGENTA.getBlue())));
|
||||
}
|
||||
IDhApiRenderableBoxGroup relativePosCubeGroup = DhApi.Delayed.renderRegister.createRelativePositionedGroup(
|
||||
24f, 140f, 24f,
|
||||
relCubeList);
|
||||
AtomicInteger frameCount = new AtomicInteger(0);
|
||||
relativePosCubeGroup.setPreRenderFunc((event) ->
|
||||
{
|
||||
float x = relativePosCubeGroup.getOriginBlockX();
|
||||
x += event.partialTicks / 2;
|
||||
x %= 32;
|
||||
relativePosCubeGroup.setOriginBlockPos(x, relativePosCubeGroup.getOriginBlockY(), relativePosCubeGroup.getOriginBlockZ());
|
||||
});
|
||||
DhApi.Delayed.renderRegister.add(relativePosCubeGroup);
|
||||
|
||||
}
|
||||
private void createBuffers()
|
||||
{
|
||||
// cube vertices
|
||||
ByteBuffer boxVerticesBuffer = ByteBuffer.allocateDirect(BOX_VERTICES.length * Float.BYTES);
|
||||
boxVerticesBuffer.order(ByteOrder.nativeOrder());
|
||||
boxVerticesBuffer.asFloatBuffer().put(BOX_VERTICES);
|
||||
boxVerticesBuffer.rewind();
|
||||
this.vertexBuffer = new GLVertexBuffer(false);
|
||||
this.vertexBuffer.bind();
|
||||
this.vertexBuffer.uploadBuffer(boxVerticesBuffer, 8, EDhApiGpuUploadMethod.DATA, BOX_VERTICES.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();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
//================//
|
||||
// group creation //
|
||||
//================//
|
||||
|
||||
@Override
|
||||
public IDhApiRenderableBoxGroup createForSingleBox(DhApiRenderableBox box)
|
||||
{
|
||||
ArrayList<DhApiRenderableBox> list = new ArrayList<>();
|
||||
list.add(box);
|
||||
return new DhApiRenderableBoxGroup(0, 0, 0, list, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IDhApiRenderableBoxGroup createRelativePositionedGroup(float originBlockX, float originBlockY, float originBlockZ, List<DhApiRenderableBox> cubeList)
|
||||
{ return new DhApiRenderableBoxGroup(originBlockX, originBlockY, originBlockZ, cubeList, true); }
|
||||
|
||||
@Override
|
||||
public IDhApiRenderableBoxGroup createAbsolutePositionedGroup(List<DhApiRenderableBox> boxList)
|
||||
{ return new DhApiRenderableBoxGroup(0, 0, 0, boxList, false); }
|
||||
|
||||
|
||||
|
||||
//==============//
|
||||
// registration //
|
||||
//==============//
|
||||
|
||||
@Override
|
||||
public void add(IDhApiRenderableBoxGroup boxGroup) throws IllegalArgumentException
|
||||
{
|
||||
try
|
||||
{
|
||||
mapModifyLock.lock();
|
||||
|
||||
long id = boxGroup.getId();
|
||||
if (this.boxGroupById.containsKey(id))
|
||||
{
|
||||
throw new IllegalArgumentException("A cube group with the ID [" + id + "] is already present.");
|
||||
}
|
||||
|
||||
this.boxGroupById.put(id, (DhApiRenderableBoxGroup) boxGroup);
|
||||
|
||||
// TODO add to DB async?
|
||||
}
|
||||
finally
|
||||
{
|
||||
mapModifyLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IDhApiRenderableBoxGroup remove(long id)
|
||||
{
|
||||
try
|
||||
{
|
||||
mapModifyLock.lock();
|
||||
// TODO remove from DB async?
|
||||
return this.boxGroupById.remove(id);
|
||||
}
|
||||
finally
|
||||
{
|
||||
mapModifyLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public void clear()
|
||||
{
|
||||
try
|
||||
{
|
||||
mapModifyLock.lock();
|
||||
this.boxGroupById.clear();
|
||||
}
|
||||
finally
|
||||
{
|
||||
mapModifyLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//===========//
|
||||
// rendering //
|
||||
//===========//
|
||||
|
||||
public void render(DhApiRenderParam renderEventParam)
|
||||
{
|
||||
Mat4f transform = new Mat4f(renderEventParam.dhProjectionMatrix);
|
||||
transform.multiply(renderEventParam.dhModelViewMatrix);
|
||||
|
||||
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);
|
||||
|
||||
GL32.glEnable(GL32.GL_BLEND);
|
||||
GL32.glBlendEquation(GL32.GL_FUNC_ADD);
|
||||
GL32.glBlendFuncSeparate(GL32.GL_SRC_ALPHA, GL32.GL_ONE_MINUS_SRC_ALPHA, GL32.GL_ONE, GL32.GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
this.basicUnlitShader.bind();
|
||||
this.va.bind();
|
||||
this.va.bindBufferToAllBindingPoints(this.vertexBuffer.getId());
|
||||
|
||||
this.solidIndexBuffer.bind();
|
||||
|
||||
LongSet keys = boxGroupById.keySet();
|
||||
for (long key : keys)
|
||||
{
|
||||
DhApiRenderableBoxGroup cubeGroup = boxGroupById.get(key);
|
||||
this.renderCubeGroup(cubeGroup, renderEventParam);
|
||||
}
|
||||
|
||||
|
||||
this.basicUnlitShader.unbind();
|
||||
glState.restore();
|
||||
}
|
||||
|
||||
private void renderCubeGroup(DhApiRenderableBoxGroup cubeGroup, DhApiRenderParam renderEventParam)
|
||||
{
|
||||
cubeGroup.preRender(renderEventParam);
|
||||
|
||||
for (DhApiRenderableBox cube : cubeGroup.cubeList)
|
||||
{
|
||||
renderCube(cubeGroup, cube);
|
||||
}
|
||||
}
|
||||
private void renderCube(DhApiRenderableBoxGroup cubeGroup, DhApiRenderableBox cube)
|
||||
{
|
||||
float originOffsetX = 0;
|
||||
float originOffsetY = 0;
|
||||
float originOffsetZ = 0;
|
||||
if (cubeGroup.positionCubesRelativeToGroupOrigin)
|
||||
{
|
||||
originOffsetX = cubeGroup.originBlockX;
|
||||
originOffsetY = cubeGroup.originBlockY;
|
||||
originOffsetZ = cubeGroup.originBlockZ;
|
||||
}
|
||||
|
||||
Mat4f boxTransform = Mat4f.createTranslateMatrix(
|
||||
cube.minPos.x + originOffsetX - this.camPosFloatThisFrame.x,
|
||||
cube.minPos.y + originOffsetY - this.camPosFloatThisFrame.y,
|
||||
cube.minPos.z + originOffsetZ - this.camPosFloatThisFrame.z);
|
||||
boxTransform.multiply(Mat4f.createScaleMatrix(
|
||||
cube.maxPos.x - cube.minPos.x,
|
||||
cube.maxPos.y - cube.minPos.y,
|
||||
cube.maxPos.z - cube.minPos.z));
|
||||
Mat4f transformMatrix = this.transformationMatrixThisFrame.copy();
|
||||
transformMatrix.multiply(boxTransform);
|
||||
this.basicUnlitShader.setUniform(this.basicUnlitShader.getUniformLocation("transform"), transformMatrix);
|
||||
|
||||
this.basicUnlitShader.setUniform(this.basicUnlitShader.getUniformLocation("uColor"), cube.color);
|
||||
|
||||
GL32.glDrawElements(GL32.GL_TRIANGLES , SOLID_BOX_INDICES.length, GL32.GL_UNSIGNED_INT, 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//================//
|
||||
// helper classes //
|
||||
//================//
|
||||
|
||||
private static final class DhApiRenderableBoxGroup extends AbstractList<DhApiRenderableBox> implements IDhApiRenderableBoxGroup
|
||||
{
|
||||
public final static AtomicInteger NEXT_ID_ATOMIC_INT = new AtomicInteger(0);
|
||||
|
||||
public final long id;
|
||||
|
||||
/** If false the cubes will be positioned relative to the level's origin */
|
||||
public final boolean positionCubesRelativeToGroupOrigin;
|
||||
|
||||
private final ArrayList<DhApiRenderableBox> cubeList;
|
||||
|
||||
private float originBlockX;
|
||||
private float originBlockY;
|
||||
private float originBlockZ;
|
||||
|
||||
@Nullable
|
||||
public Consumer<DhApiRenderParam> beforeRenderFunc;
|
||||
|
||||
|
||||
// setters/getters //
|
||||
|
||||
@Override
|
||||
public long getId() { return this.id; }
|
||||
|
||||
@Override
|
||||
public void setOriginBlockPos(float x, float y, float z)
|
||||
{
|
||||
this.originBlockX = x;
|
||||
this.originBlockY = y;
|
||||
this.originBlockZ = z;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getOriginBlockX() { return this.originBlockX; }
|
||||
@Override
|
||||
public float getOriginBlockY() { return this.originBlockY; }
|
||||
@Override
|
||||
public float getOriginBlockZ() { return this.originBlockZ; }
|
||||
|
||||
|
||||
|
||||
// constructor //
|
||||
|
||||
public DhApiRenderableBoxGroup(float originBlockX, float originBlockY, float originBlockZ, List<DhApiRenderableBox> cubeList, boolean positionCubesRelativeToGroupOrigin)
|
||||
{
|
||||
// TODO save to database
|
||||
// TODO when?
|
||||
|
||||
this.id = NEXT_ID_ATOMIC_INT.getAndIncrement();
|
||||
this.cubeList = new ArrayList<>(cubeList);
|
||||
|
||||
this.originBlockX = originBlockX;
|
||||
this.originBlockY = originBlockY;
|
||||
this.originBlockZ = originBlockZ;
|
||||
this.positionCubesRelativeToGroupOrigin = positionCubesRelativeToGroupOrigin;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// methods //
|
||||
|
||||
@Override
|
||||
public boolean add(DhApiRenderableBox cube) { return this.cubeList.add(cube); }
|
||||
|
||||
@Override
|
||||
public void setPreRenderFunc(Consumer<DhApiRenderParam> func) { this.beforeRenderFunc = func; }
|
||||
|
||||
//@Override
|
||||
public void preRender(DhApiRenderParam renderEventParam)
|
||||
{
|
||||
if (this.beforeRenderFunc != null)
|
||||
{
|
||||
beforeRenderFunc.accept(renderEventParam);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// overrides //
|
||||
|
||||
@Override
|
||||
public DhApiRenderableBox get(int index) { return this.cubeList.get(index); }
|
||||
@Override
|
||||
public int size() { return this.cubeList.size(); }
|
||||
@Override
|
||||
public boolean removeIf(Predicate<? super DhApiRenderableBox> filter) { return this.cubeList.removeIf(filter); }
|
||||
@Override
|
||||
public void replaceAll(UnaryOperator<DhApiRenderableBox> operator) { this.cubeList.replaceAll(operator); }
|
||||
@Override
|
||||
public void sort(Comparator<? super DhApiRenderableBox> c) { this.cubeList.sort(c); }
|
||||
@Override
|
||||
public void forEach(Consumer<? super DhApiRenderableBox> action) { this.cubeList.forEach(action); }
|
||||
@Override
|
||||
public Spliterator<DhApiRenderableBox> spliterator() { return this.cubeList.spliterator(); }
|
||||
@Override
|
||||
public Stream<DhApiRenderableBox> stream() { return this.cubeList.stream(); }
|
||||
@Override
|
||||
public Stream<DhApiRenderableBox> parallelStream() { return this.cubeList.parallelStream(); }
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+3
-11
@@ -57,9 +57,6 @@ import org.apache.logging.log4j.LogManager;
|
||||
import org.lwjgl.opengl.GL32;
|
||||
|
||||
import java.awt.*;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.time.Duration;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
@@ -424,15 +421,10 @@ public class LodRenderer
|
||||
DebugRenderer.INSTANCE.render(combinedMatrix);
|
||||
}
|
||||
|
||||
profiler.popPush("Generic Cubes");
|
||||
profiler.popPush("Custom Objects");
|
||||
GenericObjectRenderer.INSTANCE.render(renderEventParam);
|
||||
|
||||
{
|
||||
Mat4f combinedMatrix = new Mat4f(renderEventParam.dhProjectionMatrix);
|
||||
combinedMatrix.multiply(renderEventParam.dhModelViewMatrix);
|
||||
|
||||
GenericCubeRenderer.INSTANCE.render(combinedMatrix);
|
||||
profiler.popPush("LOD cleanup");
|
||||
}
|
||||
profiler.popPush("LOD cleanup");
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
#version 150 core
|
||||
|
||||
uniform vec4 uColor;
|
||||
out vec4 fragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
fragColor = uColor;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
#version 150 core
|
||||
|
||||
uniform mat4 transform;
|
||||
|
||||
in vec3 vPosition;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = transform * vec4(vPosition, 1.0);
|
||||
}
|
||||
Reference in New Issue
Block a user