Buffers: Fixed critical render bugs and vertex buffer leaks

This commit is contained in:
tom lee
2022-01-04 15:10:41 +08:00
parent d72805d1fe
commit 3b475886ef
4 changed files with 106 additions and 7 deletions
@@ -280,7 +280,9 @@ public class LodBufferBuilderFactory
vboY = buildableCenterBlockY;
vboZ = buildableCenterBlockZ;
buildableBuffers.move(playerRegionX, playerRegionZ);
buildableVbos.move(playerRegionX, playerRegionZ);
buildableVbos.move(playerRegionX, playerRegionZ, (bs) -> {
if (bs!=null) for (LodVertexBuffer b : bs) if (b!=null) b.close();
});
setsToRender.move(playerRegionX, playerRegionZ);
vertexOptimizerCache.move(playerRegionX, playerRegionZ);
}
@@ -847,7 +849,7 @@ public class LodBufferBuilderFactory
drawableVbos = buildableVbos;
buildableVbos = tmpVbo;
//ClientApi.LOGGER.info("Lod Swapped Buffers: "+drawableVbos.toDetailString());
ClientApi.LOGGER.info("Lod Swapped Buffers: "+drawableVbos.toDetailString());
int tempX = drawableCenterBlockX;
int tempY = drawableCenterBlockY;
@@ -21,6 +21,7 @@ package com.seibel.lod.core.objects.opengl;
import org.lwjgl.opengl.GL32;
import com.seibel.lod.core.api.ClientApi;
import com.seibel.lod.core.enums.rendering.GLProxyContext;
import com.seibel.lod.core.render.GLProxy;
@@ -33,6 +34,7 @@ import com.seibel.lod.core.render.GLProxy;
*/
public class LodVertexBuffer implements AutoCloseable
{
public static int count = 0;
public int id;
public int vertexCount;
public final boolean isBufferStorage;
@@ -44,6 +46,8 @@ public class LodVertexBuffer implements AutoCloseable
throw new IllegalStateException("Thread [" +Thread.currentThread().getName() + "] tried to create a [" + LodVertexBuffer.class.getSimpleName() + "] outside a OpenGL contex.");
this.id = GL32.glGenBuffers();
this.isBufferStorage = isBufferStorage;
count++;
ClientApi.LOGGER.info("LodVertexBuffer Count: "+count);
}
@@ -54,6 +58,8 @@ public class LodVertexBuffer implements AutoCloseable
{
GLProxy.getInstance().recordOpenGlCall(() -> GL32.glDeleteBuffers(this.id));
this.id = -1;
count--;
ClientApi.LOGGER.info("LodVertexBuffer Count: "+count);
}
}
}
@@ -304,14 +304,18 @@ public class LodRenderer
int lowRegionX = vbos.getCenterX() - vbos.gridCentreToEdge;
int lowRegionZ = vbos.getCenterY() - vbos.gridCentreToEdge;
int drawCall = 0;
for (int regionX=lowRegionX; regionX<vbos.gridSize; regionX++) {
for (int regionZ=lowRegionZ; regionZ<vbos.gridSize; regionZ++) {
int vCount0 = 0;
for (int regionX=lowRegionX; regionX<lowRegionX+vbos.gridSize; regionX++) {
for (int regionZ=lowRegionZ; regionZ<lowRegionZ+vbos.gridSize; regionZ++) {
if (vbos.get(regionX, regionZ) == null) continue;
if (cullingDisabled || RenderUtil.isRegionInViewFrustum(MC_RENDER.getCameraBlockPosition(),
MC_RENDER.getLookAtVector(), regionX, regionZ)) {
for (LodVertexBuffer vbo : vbos.get(regionX, regionZ)) {
if (vbo == null) continue;
if (vbo.vertexCount == 0) continue;
if (vbo.vertexCount == 0) {
vCount0++;
continue;
}
GL32.glBindBuffer(GL32.GL_ARRAY_BUFFER, vbo.id);
shaderProgram.bindVertexBuffer(vbo.id);
drawCall++;
@@ -322,8 +326,8 @@ public class LodRenderer
}
}
//if (drawCall!=0)
// ClientApi.LOGGER.info("DrawCall Count: "+drawCall);
//if (drawCall==0)
// ClientApi.LOGGER.info("DrawCall Count: "+drawCall+"("+vCount0+")");
//================//
// render cleanup //
@@ -2,6 +2,7 @@ package com.seibel.lod.core.util;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
/*Layout:
* 0,1,2,
@@ -46,6 +47,14 @@ public class MovableGridList<T> extends ArrayList<T> implements List<T> {
super.add(null);
}
}
public void clear(Consumer<? super T> d) {
super.forEach(d);
super.clear();
super.ensureCapacity(gridSize*gridSize);
for (int i=0; i<gridSize*gridSize; i++) {
super.add(null);
}
}
public int getCenterX() {return centerX;}
public int getCenterY() {return centerY;}
@@ -90,6 +99,8 @@ public class MovableGridList<T> extends ArrayList<T> implements List<T> {
centerY = newCenterY;
return;
}
centerX = newCenterX;
centerY = newCenterY;
// X
if (deltaX >= 0 && deltaY >= 0)
@@ -136,8 +147,82 @@ public class MovableGridList<T> extends ArrayList<T> implements List<T> {
}
}
}
}
public void move(int newCenterX, int newCenterY, Consumer<? super T> d) {
if (centerX == newCenterX && centerY == newCenterY) return;
int deltaX = newCenterX - centerX;
int deltaY = newCenterY - centerY;
// if the x or z offset is equal to or greater than
// the total width, just delete the current data
// and update the centerX and/or centerZ
if (Math.abs(deltaX) >= gridSize || Math.abs(deltaY) >= gridSize)
{
clear(d);
// update the new center
centerX = newCenterX;
centerY = newCenterY;
return;
}
centerX = newCenterX;
centerY = newCenterY;
// Dealloc stuff
for (int x=0; x<gridSize; x++) {
for (int y=0; y<gridSize; y++) {
if (x-deltaX<0 || y-deltaY<0 ||
x-deltaX>=gridSize || y-deltaY>=gridSize) {
d.accept(_getDirect(x,y));
}
}
}
// X
if (deltaX >= 0 && deltaY >= 0)
{
// move everything over to the left-up (as the center moves to the right-down)
for (int x = 0; x < gridSize; x++)
{
for (int y = 0; y < gridSize; y++)
{
_setDirect(x, y, _getDirect(x+deltaX, y+deltaY));
}
}
}
else if (deltaX < 0 && deltaY >= 0)
{
// move everything over to the right-up (as the center moves to the left-down)
for (int x = gridSize - 1; x >= 0; x--)
{
for (int y = 0; y < gridSize; y++)
{
_setDirect(x, y, _getDirect(x+deltaX, y+deltaY));
}
}
}
else if (deltaX >= 0 && deltaY < 0)
{
// move everything over to the left-down (as the center moves to the right-up)
for (int x = 0; x < gridSize; x++)
{
for (int y = gridSize - 1; y >= 0; y--)
{
_setDirect(x, y, _getDirect(x+deltaX, y+deltaY));
}
}
}
else //if (deltaX < 0 && deltaY < 0)
{
// move everything over to the right-down (as the center moves to the left-up)
for (int x = gridSize - 1; x >= 0; x--)
{
for (int y = gridSize - 1; y >= 0; y--)
{
_setDirect(x, y, _getDirect(x+deltaX, y+deltaY));
}
}
}
}
@@ -154,6 +239,8 @@ public class MovableGridList<T> extends ArrayList<T> implements List<T> {
public String toDetailString() {
StringBuilder str = new StringBuilder("\n");
int i = 0;
str.append(toString());
str.append("\n");
for (T t : this) {
str.append(t!=null ? t.toString() : "NULL");