fix occlusion culling

This commit is contained in:
lax1dude 2024-12-07 22:44:04 -08:00
parent d862a08a4a
commit 49e51c5883
4 changed files with 20 additions and 72 deletions

View File

@ -1375,7 +1375,7 @@ public class EaglerAdapterGL30 extends EaglerAdapterImpl2 {
public static final boolean glGetQueryResultAvailable(int obj) { public static final boolean glGetQueryResultAvailable(int obj) {
QueryGL q = queryObjs.get(obj); QueryGL q = queryObjs.get(obj);
return _wglGetQueryObjecti(q, _wGL_QUERY_RESULT_AVAILABLE) >= 0; return _wglGetQueryObjecti(q, _wGL_QUERY_RESULT_AVAILABLE) > 0;
} }
public static final int glGenTextures() { public static final int glGenTextures() {

View File

@ -20,7 +20,7 @@ public class GLAllocation {
/** /**
* Generates the specified number of display lists and returns the first index. * Generates the specified number of display lists and returns the first index.
*/ */
public static synchronized int generateDisplayLists(int par0) { public static int generateDisplayLists(int par0) {
int var1 = EaglerAdapter.glGenLists(par0); int var1 = EaglerAdapter.glGenLists(par0);
field_74531_a.put(Integer.valueOf(var1), Integer.valueOf(par0)); field_74531_a.put(Integer.valueOf(var1), Integer.valueOf(par0));
return var1; return var1;
@ -29,17 +29,17 @@ public class GLAllocation {
/** /**
* Generates texture names and stores them in the specified buffer. * Generates texture names and stores them in the specified buffer.
*/ */
public static synchronized int generateTextureNames() { public static int generateTextureNames() {
int var0 = EaglerAdapter.glGenTextures(); int var0 = EaglerAdapter.glGenTextures();
field_74530_b.add(Integer.valueOf(var0)); field_74530_b.add(Integer.valueOf(var0));
return var0; return var0;
} }
public static synchronized void deleteDisplayLists(int par0) { public static void deleteDisplayLists(int par0) {
EaglerAdapter.glDeleteLists(par0, ((Integer) field_74531_a.remove(Integer.valueOf(par0))).intValue()); EaglerAdapter.glDeleteLists(par0, ((Integer) field_74531_a.remove(Integer.valueOf(par0))).intValue());
} }
public static synchronized void func_98302_b() { public static void func_98302_b() {
for (int var0 = 0; var0 < field_74530_b.size(); ++var0) { for (int var0 = 0; var0 < field_74530_b.size(); ++var0) {
EaglerAdapter.glDeleteTextures(((Integer) field_74530_b.get(var0)).intValue()); EaglerAdapter.glDeleteTextures(((Integer) field_74530_b.get(var0)).intValue());
} }
@ -51,7 +51,7 @@ public class GLAllocation {
* Deletes all textures and display lists. Called when Minecraft is shutdown to * Deletes all textures and display lists. Called when Minecraft is shutdown to
* free up resources. * free up resources.
*/ */
public static synchronized void deleteTexturesAndDisplayLists() { public static void deleteTexturesAndDisplayLists() {
Iterator var0 = field_74531_a.entrySet().iterator(); Iterator var0 = field_74531_a.entrySet().iterator();
while (var0.hasNext()) { while (var0.hasNext()) {

View File

@ -156,8 +156,6 @@ public class RenderGlobal implements IWorldAccess {
for(int i = 0; i < glOcclusionQuery.length; ++i) { for(int i = 0; i < glOcclusionQuery.length; ++i) {
this.glOcclusionQuery[i] = -1; this.glOcclusionQuery[i] = -1;
} }
this.occlusionQueryAvailable = new boolean[glOcclusionQuery.length];
this.occlusionQueryStalled = new long[occlusionQueryAvailable.length];
this.starGLCallList = GLAllocation.generateDisplayLists(3); this.starGLCallList = GLAllocation.generateDisplayLists(3);
EaglerAdapter.glPushMatrix(); EaglerAdapter.glPushMatrix();
EaglerAdapter.glNewList(this.starGLCallList, EaglerAdapter.GL_COMPILE); EaglerAdapter.glNewList(this.starGLCallList, EaglerAdapter.GL_COMPILE);
@ -321,8 +319,7 @@ public class RenderGlobal implements IWorldAccess {
int i = (var6 * this.renderChunksTall + var5) * this.renderChunksWide + var4; int i = (var6 * this.renderChunksTall + var5) * this.renderChunksWide + var4;
this.worldRenderers[i] = new WorldRenderer(this.theWorld, this.tileEntities, var4 * 16, var5 * 16, var6 * 16, this.glRenderListBase + var2); this.worldRenderers[i] = new WorldRenderer(this.theWorld, this.tileEntities, var4 * 16, var5 * 16, var6 * 16, this.glRenderListBase + var2);
this.worldRenderers[i].isWaitingOnOcclusionQuery = false; this.worldRenderers[i].isWaitingOnOcclusionQuery = false;
this.worldRenderers[i].isNowVisible = true; this.worldRenderers[i].isVisible = true;
this.worldRenderers[i].isVisible = 100;
this.worldRenderers[i].isInFrustum = true; this.worldRenderers[i].isInFrustum = true;
this.worldRenderers[i].chunkIndex = var3++; this.worldRenderers[i].chunkIndex = var3++;
this.worldRenderers[i].markDirty(); this.worldRenderers[i].markDirty();
@ -505,11 +502,7 @@ public class RenderGlobal implements IWorldAccess {
} }
} }
// GOSH FUCKING DAMMIT WHY IN THE FUCK IS GODDAMN WEBGL THIS UNSTABLE
private long lastOcclusionQuery = 0l; private long lastOcclusionQuery = 0l;
private boolean[] occlusionQueryAvailable;
private long[] occlusionQueryStalled;
/** /**
* Sorts all renderers based on the passed in entity. Args: entityLiving, * Sorts all renderers based on the passed in entity. Args: entityLiving,
@ -568,9 +561,6 @@ public class RenderGlobal implements IWorldAccess {
int var34; int var34;
long queryRate = 50l; long queryRate = 50l;
long stallRateVisible = 60l;
long stallRate = 500l;
int cooldownRate = 13;
long ct = EaglerAdapter.steadyTimeMillis(); long ct = EaglerAdapter.steadyTimeMillis();
if(par2 == 0) { if(par2 == 0) {
@ -581,35 +571,13 @@ public class RenderGlobal implements IWorldAccess {
int ccy = c.chunkY - fy; int ccy = c.chunkY - fy;
int ccz = c.chunkZ - fz; int ccz = c.chunkZ - fz;
boolean forced = ccx < 2 && ccx > -2 && ccy < 2 && ccy > -2 && ccz < 2 && ccz > -2; boolean forced = ccx < 2 && ccx > -2 && ccy < 2 && ccy > -2 && ccz < 2 && ccz > -2;
if(forced) { if(forced || c.chunkIndex == -1) {
c.hasOcclusionData = 5; c.isVisible = true;
} }else if(c.isWaitingOnOcclusionQuery) {
if(forced || glOcclusionQuery[c.chunkIndex] == -1) { int j = glOcclusionQuery[c.chunkIndex];
c.isNowVisible = true; if(EaglerAdapter.glGetQueryResultAvailable(j)) {
c.isVisible = cooldownRate; c.isVisible = EaglerAdapter.glGetQueryResult(j);
}else if(occlusionQueryAvailable[c.chunkIndex]) { c.isWaitingOnOcclusionQuery = false;
if(EaglerAdapter.glGetQueryResultAvailable(glOcclusionQuery[c.chunkIndex])) {
if(EaglerAdapter.glGetQueryResult(glOcclusionQuery[c.chunkIndex])) {
c.isNowVisible = true;
++c.hasOcclusionData;
if(c.hasOcclusionData > 5) {
c.hasOcclusionData = 5;
}
c.isVisible = cooldownRate;
}else {
if(c.isVisible <= 0) {
c.isNowVisible = false;
--c.hasOcclusionData;
if(c.hasOcclusionData < 0) {
c.hasOcclusionData = 0;
}
}
}
occlusionQueryAvailable[c.chunkIndex] = false;
occlusionQueryStalled[c.chunkIndex] = 0l;
}else if(occlusionQueryStalled[c.chunkIndex] != 0l && ct - occlusionQueryStalled[c.chunkIndex] > stallRateVisible) {
c.isNowVisible = true;
c.isVisible = cooldownRate;
} }
} }
} }
@ -663,17 +631,8 @@ public class RenderGlobal implements IWorldAccess {
} }
} }
if(shouldTry && !(ccx < 2 && ccx > -2 && ccy < 2 && ccy > -2 && ccz < 2 && ccz > -2)) { if(shouldTry && !(ccx < 2 && ccx > -2 && ccy < 2 && ccy > -2 && ccz < 2 && ccz > -2)) {
boolean stalled = false; if(!c.isWaitingOnOcclusionQuery) {
if(occlusionQueryAvailable[c.chunkIndex]) { c.isWaitingOnOcclusionQuery = true;
if(occlusionQueryStalled[c.chunkIndex] == 0l) {
occlusionQueryStalled[c.chunkIndex] = ct;
stalled = true;
}else if(ct - occlusionQueryStalled[c.chunkIndex] < stallRate) {
stalled = true;
}
}
if(!stalled) {
occlusionQueryAvailable[c.chunkIndex] = true;
int q = glOcclusionQuery[c.chunkIndex]; int q = glOcclusionQuery[c.chunkIndex];
if(q == -1) { if(q == -1) {
q = glOcclusionQuery[c.chunkIndex] = EaglerAdapter.glCreateQuery(); q = glOcclusionQuery[c.chunkIndex] = EaglerAdapter.glCreateQuery();
@ -682,14 +641,6 @@ public class RenderGlobal implements IWorldAccess {
EaglerAdapter.glDrawOcclusionBB((float)(c.posX - var33), (float)(c.posY - var7), (float)(c.posZ - var9), 16, 16, 16); EaglerAdapter.glDrawOcclusionBB((float)(c.posX - var33), (float)(c.posY - var7), (float)(c.posZ - var9), 16, 16, 16);
EaglerAdapter.glEndQuery(); EaglerAdapter.glEndQuery();
} }
}else {
--c.hasOcclusionData;
if(c.hasOcclusionData < 0) {
c.hasOcclusionData = 0;
}
}
if(c.isVisible > 0) {
--c.isVisible;
} }
} }
EaglerAdapter.glEndOcclusionBB(); EaglerAdapter.glEndOcclusionBB();
@ -718,14 +669,14 @@ public class RenderGlobal implements IWorldAccess {
++this.renderersSkippingRenderPass; ++this.renderersSkippingRenderPass;
} else if (!this.sortedWorldRenderers[var7].isInFrustum) { } else if (!this.sortedWorldRenderers[var7].isInFrustum) {
++this.renderersBeingClipped; ++this.renderersBeingClipped;
} else if(!this.sortedWorldRenderers[var7].isNowVisible) { } else if(!this.sortedWorldRenderers[var7].isVisible) {
++this.renderersBeingOccluded; ++this.renderersBeingOccluded;
} else { } else {
++this.renderersBeingRendered; ++this.renderersBeingRendered;
} }
} }
if (!this.sortedWorldRenderers[var7].skipRenderPass[par3] && this.sortedWorldRenderers[var7].isInFrustum && this.sortedWorldRenderers[var7].isNowVisible) { if (!this.sortedWorldRenderers[var7].skipRenderPass[par3] && this.sortedWorldRenderers[var7].isInFrustum && this.sortedWorldRenderers[var7].isVisible) {
int var8 = this.sortedWorldRenderers[var7].getGLCallListForPass(par3); int var8 = this.sortedWorldRenderers[var7].getGLCallListForPass(par3);
if (var8 >= 0) { if (var8 >= 0) {
@ -1277,7 +1228,7 @@ public class RenderGlobal implements IWorldAccess {
var10 = (WorldRenderer) this.worldRenderersToUpdate.get(var9); var10 = (WorldRenderer) this.worldRenderersToUpdate.get(var9);
if (var10 != null) { if (var10 != null) {
if (!var10.isInFrustum || !var10.isNowVisible || var10.hasOcclusionData < 3) { // config? if (!var10.isInFrustum || !var10.isVisible) {
laterUpdateList.add(var10); laterUpdateList.add(var10);
}else { }else {
if (var6 == null) { if (var6 == null) {

View File

@ -64,8 +64,7 @@ public class WorldRenderer {
public int chunkIndex; public int chunkIndex;
/** Is this renderer visible according to the occlusion query */ /** Is this renderer visible according to the occlusion query */
public int isVisible = 0; public boolean isVisible = true;
public boolean isNowVisible = true;
/** Is this renderer waiting on the result of the occlusion query */ /** Is this renderer waiting on the result of the occlusion query */
public boolean isWaitingOnOcclusionQuery; public boolean isWaitingOnOcclusionQuery;
@ -73,7 +72,6 @@ public class WorldRenderer {
/** Is the chunk lit */ /** Is the chunk lit */
public boolean isChunkLit; public boolean isChunkLit;
private boolean isInitialized = false; private boolean isInitialized = false;
public int hasOcclusionData = 0;
/** All the tile entities that have special rendering code for this chunk */ /** All the tile entities that have special rendering code for this chunk */
public List tileEntityRenderers = new ArrayList(); public List tileEntityRenderers = new ArrayList();
@ -98,7 +96,6 @@ public class WorldRenderer {
public void setPosition(int par1, int par2, int par3) { public void setPosition(int par1, int par2, int par3) {
if (par1 != this.posX || par2 != this.posY || par3 != this.posZ) { if (par1 != this.posX || par2 != this.posY || par3 != this.posZ) {
this.setDontDraw(); this.setDontDraw();
this.hasOcclusionData = 0;
this.posX = par1; this.posX = par1;
this.posY = par2; this.posY = par2;
this.posZ = par3; this.posZ = par3;