Fix generic rendering at extreme distances

This commit is contained in:
James Seibel
2024-07-10 07:37:11 -05:00
parent 53a2bf1748
commit 4b27f39a04
13 changed files with 252 additions and 109 deletions
@@ -1,5 +1,6 @@
package com.seibel.distanthorizons.api.interfaces.render;
import com.seibel.distanthorizons.api.objects.math.DhApiVec3d;
import com.seibel.distanthorizons.api.objects.math.DhApiVec3f;
import com.seibel.distanthorizons.api.objects.render.DhApiRenderableBox;
@@ -20,7 +21,7 @@ import java.util.List;
public interface IDhApiCustomRenderObjectFactory
{
IDhApiRenderableBoxGroup createForSingleBox(DhApiRenderableBox cube);
IDhApiRenderableBoxGroup createRelativePositionedGroup(DhApiVec3f originBlockPos, List<DhApiRenderableBox> cubeList);
IDhApiRenderableBoxGroup createRelativePositionedGroup(DhApiVec3d originBlockPos, List<DhApiRenderableBox> cubeList);
IDhApiRenderableBoxGroup createAbsolutePositionedGroup(List<DhApiRenderableBox> cubeList);
}
@@ -2,7 +2,9 @@ package com.seibel.distanthorizons.api.interfaces.render;
import com.seibel.distanthorizons.api.enums.config.EDhApiLodShading;
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiRenderParam;
import com.seibel.distanthorizons.api.objects.math.DhApiVec3d;
import com.seibel.distanthorizons.api.objects.math.DhApiVec3f;
import com.seibel.distanthorizons.api.objects.math.DhApiVec3i;
import com.seibel.distanthorizons.api.objects.render.DhApiRenderableBox;
import com.seibel.distanthorizons.api.objects.render.DhApiRenderableBoxGroupShading;
@@ -35,9 +37,9 @@ public interface IDhApiRenderableBoxGroup extends List<DhApiRenderableBox>
boolean isSsaoEnabled();
/** Sets where this group will render in the level. */
void setOriginBlockPos(DhApiVec3f pos);
void setOriginBlockPos(DhApiVec3d pos);
/** @return the block position in the level that all {@see DhApiRenderableBox} will render relative to. */
DhApiVec3f getOriginBlockPos();
DhApiVec3d getOriginBlockPos();
/**
* Called right before this group is rendered. <br>
@@ -0,0 +1,94 @@
/*
* This file is part of the Distant Horizons mod
* licensed under the GNU LGPL v3 License.
*
* Copyright (C) 2020-2023 James Seibel
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.seibel.distanthorizons.api.objects.math;
/**
* Often used to store block positions or any other
* position in 3D space.
*
* @author James Seibel
* @version 2024-7-9
* @since API 3.0.0
*/
public class DhApiVec3d
{
public double x;
public double y;
public double z;
/** creates a Vec3 at (0,0,0) */
public DhApiVec3d()
{
this.x = 0;
this.y = 0;
this.z = 0;
}
public DhApiVec3d(double x, double y, double z)
{
this.x = x;
this.y = y;
this.z = z;
}
@Override
public boolean equals(Object obj)
{
if (this == obj)
{
return true;
}
else if (obj != null && this.getClass() == obj.getClass())
{
DhApiVec3d Vec3d = (DhApiVec3d) obj;
if (Double.compare(Vec3d.x, this.x) != 0)
{
return false;
}
else if (Double.compare(Vec3d.y, this.y) != 0)
{
return false;
}
else
{
return Double.compare(Vec3d.z, this.z) == 0;
}
}
else
{
return false;
}
}
@Override
public int hashCode()
{
long i = Double.doubleToLongBits(this.x);
i = 31 * i + Double.doubleToLongBits(this.y);
i = 31 * i + Double.doubleToLongBits(this.z);
return Long.hashCode(i);
}
@Override
public String toString() { return "[" + this.x + ", " + this.y + ", " + this.z + "]"; }
}
@@ -2,6 +2,7 @@ package com.seibel.distanthorizons.api.objects.render;
import com.seibel.distanthorizons.api.interfaces.render.IDhApiRenderableBoxGroup;
import com.seibel.distanthorizons.api.objects.math.DhApiVec3d;
import com.seibel.distanthorizons.api.objects.math.DhApiVec3f;
import java.awt.*;
@@ -16,9 +17,9 @@ import java.awt.*;
public class DhApiRenderableBox
{
/** the position closest to (-inf,-inf) */
public DhApiVec3f minPos;
public DhApiVec3d minPos;
/** the position closest to (+inf,+inf) */
public DhApiVec3f maxPos;
public DhApiVec3d maxPos;
public Color color;
@@ -28,16 +29,16 @@ public class DhApiRenderableBox
// constructors //
//==============//
public DhApiRenderableBox(DhApiVec3f minPos, float width, Color color)
public DhApiRenderableBox(DhApiVec3d minPos, float width, Color color)
{
this(minPos, new DhApiVec3f(
this(minPos, new DhApiVec3d(
minPos.x + width,
minPos.y + width,
minPos.z + width
), color);
}
public DhApiRenderableBox(DhApiVec3f minPos, DhApiVec3f maxPos, Color color)
public DhApiRenderableBox(DhApiVec3d minPos, DhApiVec3d maxPos, Color color)
{
this.minPos = minPos;
this.maxPos = maxPos;
@@ -26,6 +26,7 @@ import java.util.Arrays;
import java.util.List;
import java.util.function.Supplier;
import com.seibel.distanthorizons.api.objects.math.DhApiVec3i;
import org.lwjgl.opengl.GL32;
import org.lwjgl.system.MemoryStack;
@@ -195,11 +196,10 @@ public class ShaderProgram
{
GL32.glUniform3f(location, value.x, value.y, value.z);
}
/** Requires ShaderProgram binded. */
public void setUniform(int location, Vec3d value)
public void setUniform(int location, DhApiVec3i value)
{
GL32.glUniform3f(location, (float) value.x, (float) value.y, (float) value.z);
GL32.glUniform3i(location, value.x, value.y, value.z);
}
/** Requires ShaderProgram binded. */
@@ -20,6 +20,7 @@
package com.seibel.distanthorizons.core.render.renderer.generic;
import com.seibel.distanthorizons.api.interfaces.render.IDhApiRenderableBoxGroup;
import com.seibel.distanthorizons.api.objects.math.DhApiVec3d;
import com.seibel.distanthorizons.api.objects.math.DhApiVec3f;
import com.seibel.distanthorizons.api.objects.render.DhApiRenderableBox;
import com.seibel.distanthorizons.api.objects.render.DhApiRenderableBoxGroupShading;
@@ -182,8 +183,8 @@ public class BeaconRenderHandler
if (beaconRefCount.getAndIncrement() == 0)
{
DhApiRenderableBox beaconBox = new DhApiRenderableBox(
new DhApiVec3f(beacon.pos.x, beacon.pos.y+1, beacon.pos.z),
new DhApiVec3f(beacon.pos.x+1, BEAM_TOP_Y, beacon.pos.z+1),
new DhApiVec3d(beacon.pos.x, beacon.pos.y+1, beacon.pos.z),
new DhApiVec3d(beacon.pos.x+1, BEAM_TOP_Y, beacon.pos.z+1),
beacon.color
);
@@ -20,6 +20,7 @@
package com.seibel.distanthorizons.core.render.renderer.generic;
import com.seibel.distanthorizons.api.interfaces.render.IDhApiRenderableBoxGroup;
import com.seibel.distanthorizons.api.objects.math.DhApiVec3d;
import com.seibel.distanthorizons.api.objects.math.DhApiVec3f;
import com.seibel.distanthorizons.api.objects.render.DhApiRenderableBox;
import com.seibel.distanthorizons.api.objects.render.DhApiRenderableBoxGroupShading;
@@ -203,8 +204,8 @@ public class CloudRenderHandler
}
DhApiRenderableBox box = new DhApiRenderableBox(
new DhApiVec3f(minXBlockPos, 0, minZBlockPos),
new DhApiVec3f(maxXBlockPos, CLOUD_BOX_THICKNESS, maxZBlockPos),
new DhApiVec3d(minXBlockPos, 0, minZBlockPos),
new DhApiVec3d(maxXBlockPos, CLOUD_BOX_THICKNESS, maxZBlockPos),
color
);
boxList.add(box);
@@ -231,7 +232,7 @@ public class CloudRenderHandler
for (int z = -1; z <= 1; z++)
{
IDhApiRenderableBoxGroup boxGroup = GenericRenderObjectFactory.INSTANCE.createRelativePositionedGroup(
new DhApiVec3f(0, 0, 0), // the offset will be set during rendering
new DhApiVec3d(0, 0, 0), // the offset will be set during rendering
boxList);
boxGroup.setBlockLight(LodUtil.MIN_MC_LIGHT);
boxGroup.setSkyLight(LodUtil.MAX_MC_LIGHT);
@@ -265,6 +266,7 @@ public class CloudRenderHandler
this.disabledWarningLogged = true;
LOGGER.warn("Instanced rendering unavailable, cloud rendering disabled.");
}
boxGroup.setActive(false);
return;
}
@@ -311,7 +313,7 @@ public class CloudRenderHandler
//==============//
boxGroup.setOriginBlockPos(
new DhApiVec3f(
new DhApiVec3d(
clouds.xOffset + (clouds.instanceOffsetX * clouds.widthInBlocks) + xOffset + clouds.halfWidthInBlocks,
this.level.getLevelWrapper().getMaxHeight() + 200,
clouds.zOffset + (clouds.instanceOffsetZ * clouds.widthInBlocks) + zOffset + clouds.halfWidthInBlocks
@@ -24,7 +24,8 @@ 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.math.DhApiVec3f;
import com.seibel.distanthorizons.api.objects.math.DhApiVec3d;
import com.seibel.distanthorizons.api.objects.math.DhApiVec3i;
import com.seibel.distanthorizons.api.objects.render.DhApiRenderableBox;
import com.seibel.distanthorizons.api.objects.render.DhApiRenderableBoxGroupShading;
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
@@ -93,8 +94,10 @@ public class GenericObjectRenderer implements IDhApiCustomRenderRegister
private int directShaderTransformUniform;
private int directShaderColorUniform;
private int instancedShaderOffsetUniform;
private int instancedShaderCameraPosUniform;
private int instancedShaderOffsetChunkUniform;
private int instancedShaderOffsetSubChunkUniform;
private int instancedShaderCameraChunkPosUniform;
private int instancedShaderCameraSubChunkPosUniform;
private int instancedShaderProjectionModelViewMatrixUniform;
private int lightMapUniform;
@@ -213,8 +216,10 @@ public class GenericObjectRenderer implements IDhApiCustomRenderRegister
this.directShaderTransformUniform = this.shader.tryGetUniformLocation("uTransform");
this.directShaderColorUniform = this.shader.tryGetUniformLocation("uColor");
this.instancedShaderOffsetUniform = this.shader.tryGetUniformLocation("uOffset");
this.instancedShaderCameraPosUniform = this.shader.tryGetUniformLocation("uCameraPos");
this.instancedShaderOffsetChunkUniform = this.shader.tryGetUniformLocation("uOffsetChunk");
this.instancedShaderOffsetSubChunkUniform = this.shader.tryGetUniformLocation("uOffsetSubChunk");
this.instancedShaderCameraChunkPosUniform = this.shader.tryGetUniformLocation("uCameraPosChunk");
this.instancedShaderCameraSubChunkPosUniform = this.shader.tryGetUniformLocation("uCameraPosSubChunk");
this.instancedShaderProjectionModelViewMatrixUniform = this.shader.tryGetUniformLocation("uProjectionMvm");
this.lightMapUniform = this.shader.getUniformLocation("uLightMap");
@@ -266,7 +271,7 @@ public class GenericObjectRenderer implements IDhApiCustomRenderRegister
// single giant box
IDhApiRenderableBoxGroup singleGiantBoxGroup = factory.createForSingleBox(
new DhApiRenderableBox(
new DhApiVec3f(0f,0f,0f), new DhApiVec3f(16f,190f,16f),
new DhApiVec3d(0,0,0), new DhApiVec3d(16,190,16),
new Color(Color.CYAN.getRed(), Color.CYAN.getGreen(), Color.CYAN.getBlue(), 125))
);
singleGiantBoxGroup.setSkyLight(LodUtil.MAX_MC_LIGHT);
@@ -277,7 +282,7 @@ public class GenericObjectRenderer implements IDhApiCustomRenderRegister
// single slender box
IDhApiRenderableBoxGroup singleTallBoxGroup = factory.createForSingleBox(
new DhApiRenderableBox(
new DhApiVec3f(16f,0f,31f), new DhApiVec3f(17f,2000f,32f),
new DhApiVec3d(16,0,31), new DhApiVec3d(17,2000,32),
new Color(Color.GREEN.getRed(), Color.GREEN.getGreen(), Color.GREEN.getBlue(), 125))
);
singleTallBoxGroup.setSkyLight(LodUtil.MAX_MC_LIGHT);
@@ -290,7 +295,7 @@ public class GenericObjectRenderer implements IDhApiCustomRenderRegister
for (int i = 0; i < 18; i++)
{
absBoxList.add(new DhApiRenderableBox(
new DhApiVec3f(0f+i,150f+i,24f), new DhApiVec3f(1f+i,151f+i,25f),
new DhApiVec3d(i,150+i,24), new DhApiVec3d(1+i,151+i,25),
new Color(Color.ORANGE.getRed(), Color.ORANGE.getGreen(), Color.ORANGE.getBlue())));
}
IDhApiRenderableBoxGroup absolutePosBoxGroup = factory.createAbsolutePositionedGroup(absBoxList);
@@ -302,15 +307,15 @@ public class GenericObjectRenderer implements IDhApiCustomRenderRegister
for (int i = 0; i < 8; i+=2)
{
relBoxList.add(new DhApiRenderableBox(
new DhApiVec3f(0f,0f+i,0f), new DhApiVec3f(1f,1f+i,1f),
new DhApiVec3d(0,i,0), new DhApiVec3d(1,1+i,1),
new Color(Color.MAGENTA.getRed(), Color.MAGENTA.getGreen(), Color.MAGENTA.getBlue())));
}
IDhApiRenderableBoxGroup relativePosBoxGroup = factory.createRelativePositionedGroup(
new DhApiVec3f(24f, 140f, 24f),
new DhApiVec3d(24, 140, 24),
relBoxList);
relativePosBoxGroup.setPreRenderFunc((event) ->
{
DhApiVec3f pos = relativePosBoxGroup.getOriginBlockPos();
DhApiVec3d pos = relativePosBoxGroup.getOriginBlockPos();
pos.x += event.partialTicks / 2;
pos.x %= 32;
relativePosBoxGroup.setOriginBlockPos(pos);
@@ -325,16 +330,16 @@ public class GenericObjectRenderer implements IDhApiCustomRenderRegister
for (int z = 0; z < 50*2; z+=2)
{
massRelBoxList.add(new DhApiRenderableBox(
new DhApiVec3f(0f-x, 0f, 0f-z), new DhApiVec3f(1f-x, 1f, 1f-z),
new DhApiVec3d(-x, 0, -z), new DhApiVec3d(1-x, 1, 1-z),
new Color(Color.RED.getRed(), Color.RED.getGreen(), Color.RED.getBlue())));
}
}
IDhApiRenderableBoxGroup massRelativePosBoxGroup = factory.createRelativePositionedGroup(
new DhApiVec3f(-25f, 140f, 0f),
new DhApiVec3d(-25, 140, 0),
massRelBoxList);
massRelativePosBoxGroup.setPreRenderFunc((event) ->
{
DhApiVec3f blockPos = massRelativePosBoxGroup.getOriginBlockPos();
DhApiVec3d blockPos = massRelativePosBoxGroup.getOriginBlockPos();
blockPos.y += event.partialTicks / 4;
if (blockPos.y > 150f)
{
@@ -415,8 +420,7 @@ public class GenericObjectRenderer implements IDhApiCustomRenderRegister
Mat4f projectionMvmMatrix = new Mat4f(renderEventParam.dhProjectionMatrix);
projectionMvmMatrix.multiply(renderEventParam.dhModelViewMatrix);
Vec3d camPosDouble = MC_RENDER.getCameraExactPosition();
Vec3f camPos = new Vec3f((float) camPosDouble.x, (float) camPosDouble.y, (float) camPosDouble.z);
Vec3d camPos = MC_RENDER.getCameraExactPosition();
@@ -467,24 +471,36 @@ public class GenericObjectRenderer implements IDhApiCustomRenderRegister
// instanced rendering //
//=====================//
private void renderBoxGroupInstanced(RenderableBoxGroup boxGroup, Vec3f camPos, Mat4f projectionMvmMatrix)
private void renderBoxGroupInstanced(RenderableBoxGroup boxGroup, Vec3d camPos, Mat4f projectionMvmMatrix)
{
// update instance data //
boxGroup.updateVertexAttributeData();
this.shader.setUniform(this.instancedShaderOffsetUniform,
this.shader.setUniform(this.instancedShaderOffsetChunkUniform,
new DhApiVec3i(
LodUtil.getChunkPosFromDouble(boxGroup.getOriginBlockPos().x),
LodUtil.getChunkPosFromDouble(boxGroup.getOriginBlockPos().y),
LodUtil.getChunkPosFromDouble(boxGroup.getOriginBlockPos().z)
));
this.shader.setUniform(this.instancedShaderOffsetSubChunkUniform,
new Vec3f(
boxGroup.getOriginBlockPos().x,
boxGroup.getOriginBlockPos().y,
boxGroup.getOriginBlockPos().z
LodUtil.getSubChunkPosFromDouble(boxGroup.getOriginBlockPos().x),
LodUtil.getSubChunkPosFromDouble(boxGroup.getOriginBlockPos().y),
LodUtil.getSubChunkPosFromDouble(boxGroup.getOriginBlockPos().z)
));
this.shader.setUniform(this.instancedShaderCameraPosUniform,
this.shader.setUniform(this.instancedShaderCameraChunkPosUniform,
new DhApiVec3i(
LodUtil.getChunkPosFromDouble(camPos.x),
LodUtil.getChunkPosFromDouble(camPos.y),
LodUtil.getChunkPosFromDouble(camPos.z)
));
this.shader.setUniform(this.instancedShaderCameraSubChunkPosUniform,
new Vec3f(
camPos.x,
camPos.y,
camPos.z
LodUtil.getSubChunkPosFromDouble(camPos.x),
LodUtil.getSubChunkPosFromDouble(camPos.y),
LodUtil.getSubChunkPosFromDouble(camPos.z)
));
this.shader.setUniform(this.instancedShaderProjectionModelViewMatrixUniform,
@@ -516,15 +532,20 @@ public class GenericObjectRenderer implements IDhApiCustomRenderRegister
GL32.glVertexAttribPointer(1, 4, GL32.GL_FLOAT, false, 4 * Float.BYTES, 0);
this.vertexAttribDivisor(1, 1);
GL32.glBindBuffer(GL32.GL_ARRAY_BUFFER, boxGroup.instanceTranslationVbo);
GL32.glBindBuffer(GL32.GL_ARRAY_BUFFER, boxGroup.instanceScaleVbo);
GL32.glEnableVertexAttribArray(2);
this.vertexAttribDivisor(2, 1);
GL32.glVertexAttribPointer(2, 3, GL32.GL_FLOAT, false, 3 * Float.BYTES, 0);
GL32.glBindBuffer(GL32.GL_ARRAY_BUFFER, boxGroup.instanceScaleVbo);
GL32.glBindBuffer(GL32.GL_ARRAY_BUFFER, boxGroup.instanceChunkPosVbo);
GL32.glEnableVertexAttribArray(3);
this.vertexAttribDivisor(3, 1);
GL32.glVertexAttribPointer(3, 3, GL32.GL_FLOAT, false, 3 * Float.BYTES, 0);
GL32.glVertexAttribIPointer(3, 3, GL32.GL_INT, 3 * Integer.BYTES, 0);
GL32.glBindBuffer(GL32.GL_ARRAY_BUFFER, boxGroup.instanceSubChunkPosVbo);
GL32.glEnableVertexAttribArray(4);
this.vertexAttribDivisor(4, 1);
GL32.glVertexAttribPointer(4, 3, GL32.GL_FLOAT, false, 3 * Float.BYTES, 0);
// Draw instanced
@@ -568,7 +589,7 @@ public class GenericObjectRenderer implements IDhApiCustomRenderRegister
// direct rendering //
//==================//
private void renderBoxGroupDirect(RenderableBoxGroup boxGroup, Mat4f transformMatrix, Vec3f camPos)
private void renderBoxGroupDirect(RenderableBoxGroup boxGroup, Mat4f transformMatrix, Vec3d camPos)
{
this.shader.setUniform(this.lightMapUniform, 0); // TODO this should probably be passed in
this.shader.setUniform(this.skyLightUniform, boxGroup.skyLight);
@@ -594,32 +615,22 @@ public class GenericObjectRenderer implements IDhApiCustomRenderRegister
}
private void renderBox(
RenderableBoxGroup boxGroup, DhApiRenderableBox box,
Mat4f transformationMatrix, Vec3f camPos)
Mat4f transformationMatrix, Vec3d camPos)
{
float originOffsetX = 0;
float originOffsetY = 0;
float originOffsetZ = 0;
if (boxGroup.positionBoxesRelativeToGroupOrigin)
{
originOffsetX = boxGroup.getOriginBlockPos().x;
originOffsetY = boxGroup.getOriginBlockPos().y;
originOffsetZ = boxGroup.getOriginBlockPos().z;
}
Mat4f boxTransform = Mat4f.createTranslateMatrix(
box.minPos.x + originOffsetX - camPos.x,
box.minPos.y + originOffsetY - camPos.y,
box.minPos.z + originOffsetZ - camPos.z);
(float) (box.minPos.x + boxGroup.getOriginBlockPos().x - camPos.x),
(float) (box.minPos.y + boxGroup.getOriginBlockPos().y - camPos.y),
(float) (box.minPos.z + boxGroup.getOriginBlockPos().z - camPos.z));
boxTransform.multiply(Mat4f.createScaleMatrix(
box.maxPos.x - box.minPos.x,
box.maxPos.y - box.minPos.y,
box.maxPos.z - box.minPos.z));
(float) (box.maxPos.x - box.minPos.x),
(float) (box.maxPos.y - box.minPos.y),
(float) (box.maxPos.z - box.minPos.z)));
Mat4f transformMatrix = transformationMatrix.copy();
transformMatrix.multiply(boxTransform);
this.shader.setUniform(this.directShaderTransformUniform, transformMatrix);
this.shader.setUniform(this.directShaderColorUniform, box.color);
GL32.glDrawElements(GL32.GL_TRIANGLES, BOX_INDICES.length, GL32.GL_UNSIGNED_INT, 0);
}
@@ -22,9 +22,11 @@ package com.seibel.distanthorizons.core.render.renderer.generic;
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.math.DhApiVec3f;
import com.seibel.distanthorizons.api.objects.render.DhApiRenderableBox;
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import com.seibel.distanthorizons.core.util.math.Vec3d;
import com.seibel.distanthorizons.core.util.math.Vec3f;
import org.apache.logging.log4j.Logger;
@@ -66,11 +68,11 @@ public class GenericRenderObjectFactory implements IDhApiCustomRenderObjectFacto
}
@Override
public IDhApiRenderableBoxGroup createRelativePositionedGroup(DhApiVec3f originBlockPos, List<DhApiRenderableBox> boxList)
{ return new RenderableBoxGroup(new Vec3f(originBlockPos), boxList, true); }
public IDhApiRenderableBoxGroup createRelativePositionedGroup(DhApiVec3d originBlockPos, List<DhApiRenderableBox> boxList)
{ return new RenderableBoxGroup(new DhApiVec3d(originBlockPos.x, originBlockPos.y, originBlockPos.z), boxList, true); }
@Override
public IDhApiRenderableBoxGroup createAbsolutePositionedGroup(List<DhApiRenderableBox> boxList)
{ return new RenderableBoxGroup(new Vec3f(0, 0, 0), boxList, false); }
{ return new RenderableBoxGroup(new DhApiVec3d(0, 0, 0), boxList, false); }
}
@@ -2,12 +2,11 @@ package com.seibel.distanthorizons.core.render.renderer.generic;
import com.seibel.distanthorizons.api.interfaces.render.IDhApiRenderableBoxGroup;
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiRenderParam;
import com.seibel.distanthorizons.api.objects.math.DhApiVec3f;
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.render.glObject.GLProxy;
import com.seibel.distanthorizons.core.util.LodUtil;
import com.seibel.distanthorizons.core.util.math.Vec3f;
import org.jetbrains.annotations.Nullable;
import org.lwjgl.opengl.GL32;
@@ -36,7 +35,7 @@ public class RenderableBoxGroup
private final ArrayList<DhApiRenderableBox> boxList;
private final Vec3f originBlockPos;
private final DhApiVec3d originBlockPos;
public boolean active = true;
@@ -52,9 +51,11 @@ public class RenderableBoxGroup
public Consumer<DhApiRenderParam> afterRenderFunc;
// instance data
public int instanceTranslationVbo = 0;
public int instanceScaleVbo = 0;
public int instanceColorVbo = 0;
public int instanceScaleVbo = 0;
public int instanceChunkPosVbo = 0;
public int instanceSubChunkPosVbo = 0;
public int uploadedBoxCount = -1;
@@ -65,7 +66,7 @@ public class RenderableBoxGroup
public long getId() { return this.id; }
@Override
public void setOriginBlockPos(DhApiVec3f pos)
public void setOriginBlockPos(DhApiVec3d pos)
{
this.originBlockPos.x = pos.x;
this.originBlockPos.y = pos.y;
@@ -73,7 +74,7 @@ public class RenderableBoxGroup
}
@Override
public DhApiVec3f getOriginBlockPos() { return new DhApiVec3f(this.originBlockPos.x, this.originBlockPos.y, this.originBlockPos.z); }
public DhApiVec3d getOriginBlockPos() { return new DhApiVec3d(this.originBlockPos.x, this.originBlockPos.y, this.originBlockPos.z); }
@Override
@@ -106,7 +107,7 @@ public class RenderableBoxGroup
// constructor //
//=============//
public RenderableBoxGroup(Vec3f originBlockPos, List<DhApiRenderableBox> boxList, boolean positionBoxesRelativeToGroupOrigin)
public RenderableBoxGroup(DhApiVec3d originBlockPos, List<DhApiRenderableBox> boxList, boolean positionBoxesRelativeToGroupOrigin)
{
this.id = NEXT_ID_ATOMIC_INT.getAndIncrement();
this.boxList = new ArrayList<>(boxList);
@@ -201,9 +202,10 @@ public class RenderableBoxGroup
}
this.vertexDataDirty = false;
if (this.instanceTranslationVbo == 0)
if (this.instanceChunkPosVbo == 0)
{
this.instanceTranslationVbo = GL32.glGenBuffers();
this.instanceChunkPosVbo = GL32.glGenBuffers();
this.instanceSubChunkPosVbo = GL32.glGenBuffers();
this.instanceScaleVbo = GL32.glGenBuffers();
this.instanceColorVbo = GL32.glGenBuffers();
}
@@ -214,7 +216,8 @@ public class RenderableBoxGroup
// transformation / scaling //
float[] translationData = new float[boxCount * 3];
int[] chunkPosData = new int[boxCount * 3];
float[] subChunkPosData = new float[boxCount * 3];
float[] scalingData = new float[boxCount * 3];
for (int i = 0; i < boxCount; i++)
{
@@ -222,13 +225,17 @@ public class RenderableBoxGroup
int dataIndex = i * 3;
translationData[dataIndex] = box.minPos.x;
translationData[dataIndex + 1] = box.minPos.y;
translationData[dataIndex + 2] = box.minPos.z;
chunkPosData[dataIndex] = LodUtil.getChunkPosFromDouble(box.minPos.x);
chunkPosData[dataIndex + 1] = LodUtil.getChunkPosFromDouble(box.minPos.y);
chunkPosData[dataIndex + 2] = LodUtil.getChunkPosFromDouble(box.minPos.z);
scalingData[dataIndex] = box.maxPos.x - box.minPos.x;
scalingData[dataIndex + 1] = box.maxPos.y - box.minPos.y;
scalingData[dataIndex + 2] = box.maxPos.z - box.minPos.z;
subChunkPosData[dataIndex] = LodUtil.getSubChunkPosFromDouble(box.minPos.x);
subChunkPosData[dataIndex + 1] = LodUtil.getSubChunkPosFromDouble(box.minPos.y);
subChunkPosData[dataIndex + 2] = LodUtil.getSubChunkPosFromDouble(box.minPos.z);
scalingData[dataIndex] = (float) (box.maxPos.x - box.minPos.x);
scalingData[dataIndex + 1] = (float) (box.maxPos.y - box.minPos.y);
scalingData[dataIndex + 2] = (float) (box.maxPos.z - box.minPos.z);
}
@@ -249,8 +256,10 @@ public class RenderableBoxGroup
// Upload transformation matrices
GL32.glBindBuffer(GL32.GL_ARRAY_BUFFER, this.instanceTranslationVbo);
GL32.glBufferData(GL32.GL_ARRAY_BUFFER, translationData ,GL32.GL_DYNAMIC_DRAW);
GL32.glBindBuffer(GL32.GL_ARRAY_BUFFER, this.instanceChunkPosVbo);
GL32.glBufferData(GL32.GL_ARRAY_BUFFER, chunkPosData ,GL32.GL_DYNAMIC_DRAW);
GL32.glBindBuffer(GL32.GL_ARRAY_BUFFER, this.instanceSubChunkPosVbo);
GL32.glBufferData(GL32.GL_ARRAY_BUFFER, subChunkPosData ,GL32.GL_DYNAMIC_DRAW);
GL32.glBindBuffer(GL32.GL_ARRAY_BUFFER, this.instanceScaleVbo);
GL32.glBufferData(GL32.GL_ARRAY_BUFFER, scalingData, GL32.GL_DYNAMIC_DRAW);
@@ -273,10 +282,16 @@ public class RenderableBoxGroup
{
GLProxy.getInstance().queueRunningOnRenderThread(() ->
{
if (this.instanceTranslationVbo != 0)
if (this.instanceChunkPosVbo != 0)
{
GL32.glDeleteBuffers(this.instanceTranslationVbo);
this.instanceTranslationVbo = 0;
GL32.glDeleteBuffers(this.instanceChunkPosVbo);
this.instanceChunkPosVbo = 0;
}
if (this.instanceSubChunkPosVbo != 0)
{
GL32.glDeleteBuffers(this.instanceSubChunkPosVbo);
this.instanceSubChunkPosVbo = 0;
}
if (this.instanceScaleVbo != 0)
@@ -253,6 +253,15 @@ public class LodUtil
renderDist * 2 + 1);
}
/** Returns the chunk int position for the given double position */
public static int getChunkPosFromDouble(double value) { return (int) Math.floor(value / CHUNK_WIDTH); }
/** Returns the float position inside the chunk for the given double position */
public static float getSubChunkPosFromDouble(double value)
{
double chunkPos = Math.floor(value / CHUNK_WIDTH);
return (float) (value - chunkPos * CHUNK_WIDTH);
}
// True if the requested threshold pass, or false otherwise
// For details, see:
@@ -5,6 +5,7 @@ uniform vec4 uColor;
uniform int uSkyLight;
uniform int uBlockLight;
uniform sampler2D uLightMap;
uniform float uNorthShading;
uniform float uSouthShading;
uniform float uEastShading;
@@ -12,6 +13,7 @@ uniform float uWestShading;
uniform float uTopShading;
uniform float uBottomShading;
in vec3 vPosition;
out vec4 fColor;
@@ -1,15 +1,20 @@
#version 330 core
layout (location = 1) in vec4 aColor;
layout (location = 2) in vec3 aTranslate;
layout (location = 3) in vec3 aScale;
layout (location = 2) in vec3 aScale;
layout (location = 3) in ivec3 aTranslateChunk;
layout (location = 4) in vec3 aTranslateSubChunk;
uniform ivec3 uOffsetChunk;
uniform vec3 uOffsetSubChunk;
uniform ivec3 uCameraPosChunk;
uniform vec3 uCameraPosSubChunk;
uniform vec3 uOffset;
uniform vec3 uCameraPos;
uniform mat4 uProjectionMvm;
uniform int uSkyLight;
uniform int uBlockLight;
uniform sampler2D uLightMap;
uniform float uNorthShading;
uniform float uSouthShading;
uniform float uEastShading;
@@ -17,6 +22,7 @@ uniform float uWestShading;
uniform float uTopShading;
uniform float uBottomShading;
in vec3 vPosition;
out vec4 fColor;
@@ -24,22 +30,19 @@ out vec4 fColor;
void main()
{
// aTranslate - moves the vertex to the boxGroup's relative position
// uOffset - moves the vertex to the boxGroup's position
// uOffset - moves the vertex to the boxGroup's world position
// uCameraPos - moves the vertex into camera space
float transX = aTranslate.x + uOffset.x - uCameraPos.x;
float transY = aTranslate.y + uOffset.y - uCameraPos.y;
float transZ = aTranslate.z + uOffset.z - uCameraPos.z;
float scaleX = aScale.x;
float scaleY = aScale.y;
float scaleZ = aScale.z;
vec3 trans = (aTranslateChunk + uOffsetChunk - uCameraPosChunk) * 16.0f;
// separate float and int values are to fix percission loss at extreme distances from the origin (IE 10,000,000+)
// luckily large translate values minus large cameraPos generally equal values that cleanly fit in a float
trans += (aTranslateSubChunk + uOffsetSubChunk - uCameraPosSubChunk);
// combination translation and scaling matrix
mat4 transform = mat4(
scaleX, 0.0, 0.0, 0.0,
0.0, scaleY, 0.0, 0.0,
0.0, 0.0, scaleZ, 0.0,
transX, transY, transZ, 1.0
aScale.x, 0.0, 0.0, 0.0,
0.0, aScale.y, 0.0, 0.0,
0.0, 0.0, aScale.z, 0.0,
trans.x, trans.y, trans.z, 1.0
);
gl_Position = uProjectionMvm * transform * vec4(vPosition, 1.0);
@@ -47,10 +50,10 @@ void main()
float blockLight = (float(uBlockLight)+0.5) / 16.0;
float skyLight = (float(uSkyLight)+0.5) / 16.0;
vec4 lightColor = vec4(texture(uLightMap, vec2(blockLight, skyLight)).xyz, 1.0);
fColor = lightColor * aColor;
// apply directional shading
if (gl_VertexID >= 0 && gl_VertexID < 4) { fColor.rgb *= uNorthShading; }
else if (gl_VertexID >= 4 && gl_VertexID < 8) { fColor.rgb *= uSouthShading; }