Fix fog using vert instead of per frag. Oh and impl greedy meshing

This commit is contained in:
tom lee
2022-02-20 16:10:22 +08:00
parent 3cd71c1c69
commit 57f5ad5ea0
4 changed files with 231 additions and 8 deletions
@@ -457,6 +457,7 @@ public class LodBufferBuilderFactory {
} // for pos to in list to render
// the thread executed successfully
quadBuilder.mergeQuads();
return regPos;
}
@@ -4,8 +4,9 @@ import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.function.Function;
import java.util.ListIterator;
import com.seibel.lod.core.api.ClientApi;
import com.seibel.lod.core.enums.LodDirection;
import com.seibel.lod.core.enums.LodDirection.Axis;
import com.seibel.lod.core.enums.config.GpuUploadMethod;
@@ -15,14 +16,15 @@ public class LodQuadBuilder {
static final int MAX_BUFFER_SIZE = (1024 * 1024 * 1);
static final int QUAD_BYTE_SIZE = (12 * 6);
static final int MAX_QUADS_PER_BUFFER = MAX_BUFFER_SIZE / QUAD_BYTE_SIZE;
static final int MAX_MERGED_QUAD_SIZE = 64;
static class Quad {
final short x;
final short y;
final short z;
final short w0;
final short w1;
final int color;
short w0;
short w1;
int color;
final byte skylight;
final byte blocklight;
final LodDirection dir;
@@ -47,12 +49,181 @@ public class LodQuadBuilder {
void calculateDistance(double relativeX, double relativeY, double relativeZ) {
distance = pow(relativeX-x) + pow(relativeY-y) + pow(relativeZ-z);
}
private static int _compondCompare(short a0, short b0, short c0, short a1, short b1, short c1) {
if (a0 != a1) return a0-a1;
if (b0 != b1) return b0-b1;
return c0-c1;
}
public int compareTo1(Quad o) {
if (dir != o.dir) return dir.compareTo(o.dir);
switch (dir.getAxis()) {
case X:
return _compondCompare(x, y, z, o.x, o.y, o.z);
case Y:
return _compondCompare(y, z, x, o.y, o.z, o.x);
case Z:
return _compondCompare(z, y, x, o.z, o.y, o.x);
default:
throw new IllegalArgumentException("Invalid Axis enum: " + dir.getAxis());
}
}
public int compareTo2(Quad o) {
if (dir != o.dir) return dir.compareTo(o.dir);
switch (dir.getAxis()) {
case X:
return _compondCompare(x, z, y, o.x, o.z, o.y);
case Y:
return _compondCompare(y, x, z, o.y, o.x, o.z);
case Z:
return _compondCompare(z, x, y, o.z, o.x, o.y);
default:
throw new IllegalArgumentException("Invalid Axis enum: " + dir.getAxis());
}
}
public boolean tryMergeWith1(Quad o)
{
if (dir != o.dir)
return false;
if (w0 >= MAX_MERGED_QUAD_SIZE) return false;
switch (dir.getAxis())
{
case X:
if (x != o.x ||
y != o.y ||
z + w0 < o.z)
return false;
if (z + w0 > o.z)
{
ClientApi.LOGGER.warn("Overlapping quads detected!");
o.color = ColorUtil.rgbToInt(255, 0, 0);
return false;
}
if (w1 != o.w1 ||
color != o.color ||
skylight != o.skylight ||
blocklight != o.blocklight)
return false;
w0 += o.w0;
return true;
case Y:
if (y != o.y ||
z != o.z ||
x + w0 < o.x)
return false;
if (x + w0 > o.x)
{
ClientApi.LOGGER.warn("Overlapping quads detected!");
o.color = ColorUtil.rgbToInt(255, 0, 0);
return false;
}
if (w1 != o.w1 ||
color != o.color ||
skylight != o.skylight ||
blocklight != o.blocklight)
return false;
w0 += o.w0;
return true;
case Z:
if (z != o.z ||
y != o.y ||
x + w0 < o.x)
return false;
if (x + w0 > o.x)
{
ClientApi.LOGGER.warn("Overlapping quads detected!");
o.color = ColorUtil.rgbToInt(255, 0, 0);
return false;
}
if (w1 != o.w1 ||
color != o.color ||
skylight != o.skylight ||
blocklight != o.blocklight)
return false;
w0 += o.w0;
return true;
default:
throw new IllegalArgumentException("Invalid Axis enum: " + dir.getAxis());
}
}
public boolean tryMergeWith2(Quad o)
{
if (dir != o.dir)
return false;
if (w1 >= MAX_MERGED_QUAD_SIZE) return false;
switch (dir.getAxis())
{
case X:
if (x != o.x ||
z != o.z ||
y + w1 < o.y)
return false;
if (y + w1 > o.y)
{
ClientApi.LOGGER.warn("Overlapping quads detected!");
o.color = ColorUtil.rgbToInt(255, 0, 0);
return false;
}
if (w0 != o.w0 ||
color != o.color ||
skylight != o.skylight ||
blocklight != o.blocklight)
return false;
w1 += o.w1;
return true;
case Y:
if (y != o.y ||
x != o.x ||
z + w1 < o.z)
return false;
if (z + w1 > o.z)
{
ClientApi.LOGGER.warn("Overlapping quads detected!");
o.color = ColorUtil.rgbToInt(255, 0, 0);
return false;
}
if (w0 != o.w0 ||
color != o.color ||
skylight != o.skylight ||
blocklight != o.blocklight)
return false;
w1 += o.w1;
return true;
case Z:
if (z != o.z ||
x != o.x ||
y + w1 < o.y)
return false;
if (y + w1 > o.y)
{
ClientApi.LOGGER.warn("Overlapping quads detected!");
o.color = ColorUtil.rgbToInt(255, 0, 0);
return false;
}
if (w0 != o.w0 ||
color != o.color ||
skylight != o.skylight ||
blocklight != o.blocklight)
return false;
w1 += o.w1;
return true;
default:
throw new IllegalArgumentException("Invalid Axis enum: " + dir.getAxis());
}
}
}
final ArrayList<Quad> quads;
public LodQuadBuilder(int initialSize) {
quads = new ArrayList<Quad>(initialSize);
quads = new ArrayList<Quad>();
}
public void addQuadAdj(LodDirection dir, short x, short y, short z, short w0, short wy, int color, byte skylight,
@@ -157,7 +328,56 @@ public class LodQuadBuilder {
quads.forEach(p -> p.calculateDistance(dPlayerPosX, dPlayerPosY, dPlayerPosZ));
quads.sort((a, b) -> Double.compare(a.distance, b.distance));
}
private long merggeQuadsPass1() {
quads.sort(Quad::compareTo1);
ListIterator<Quad> iter = quads.listIterator();
long mergeCount = 0;
Quad currentQuad = iter.next();
while (iter.hasNext()) {
Quad nextQuad = iter.next();
if (currentQuad.tryMergeWith1(nextQuad)) {
mergeCount++;
iter.set(null);
} else {
currentQuad = nextQuad;
}
}
quads.removeIf(o -> o==null);
return mergeCount;
}
private long merggeQuadsPass2() {
quads.sort(Quad::compareTo2);
ListIterator<Quad> iter = quads.listIterator();
long mergeCount = 0;
Quad currentQuad = iter.next();
while (iter.hasNext()) {
Quad nextQuad = iter.next();
if (currentQuad.tryMergeWith2(nextQuad)) {
mergeCount++;
iter.set(null);
} else {
currentQuad = nextQuad;
}
}
quads.removeIf(o -> o==null);
return mergeCount;
}
public void mergeQuads() {
if (quads.size()<=1) return;
long mergeCount = 0;
long preQuadsCount = quads.size();
mergeCount += merggeQuadsPass1();
mergeCount += merggeQuadsPass2();
long postQuadsCount = quads.size();
//if (mergeCount != 0)
//ClientApi.LOGGER.info("Merged {} out of {} quads, to now {} quads.", mergeCount, preQuadsCount, postQuadsCount);
}
public Iterator<ByteBuffer> makeVertexBuffers() {
int numOfBuffers = getCurrentNeededVertexBuffers();
return new Iterator<ByteBuffer>() {
+3 -1
View File
@@ -1,7 +1,7 @@
#version 150 core
in vec4 vertexColor;
in float dist;
in vec3 vertexWorldPos;
out vec4 fragColor;
@@ -42,6 +42,8 @@ void main()
// no fog by default
float fogAlpha = 0;
float dist = length(vertexWorldPos);
// less than because nearFogStart is farther away than nearFogEnd
if (nearFogEnabled && dist < nearFogStart)
{
+2 -2
View File
@@ -4,7 +4,7 @@ in vec4 vPosition;
in vec4 color;
out vec4 vertexColor;
out float dist;
out vec3 vertexWorldPos;
uniform mat4 modelViewMatrix;
uniform mat4 projectionMatrix;
@@ -29,7 +29,7 @@ void main()
vertexColor = color * texture(lightMap, vec2(light,0.5));
dist = length(worldSpacePos.xyz);
vertexWorldPos = worldSpacePos.xyz;
gl_Position = projectionMatrix * worldSpacePos;
}