mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-17 11:35:08 -04:00
Fix normalfast render mode with 8 view distance inside a custom block with high fog distance causing mass chunk reloading when moving
This commit is contained in:
parent
e1a8c6f8ff
commit
6497c1da78
@ -66,7 +66,7 @@ static void EnvRenderer_CalcFog(float* density, PackedCol* col) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void EnvRenderer_UpdateFogMinimal(float fogDensity) {
|
static void EnvRenderer_UpdateFogMinimal(float fogDensity) {
|
||||||
double dist;
|
int dist;
|
||||||
/* TODO: rewrite this to avoid raising the event? want to avoid recreating vbos too many times often */
|
/* TODO: rewrite this to avoid raising the event? want to avoid recreating vbos too many times often */
|
||||||
|
|
||||||
if (fogDensity != 0.0f) {
|
if (fogDensity != 0.0f) {
|
||||||
@ -75,8 +75,8 @@ static void EnvRenderer_UpdateFogMinimal(float fogDensity) {
|
|||||||
/* i.e. log(0.05) = -density * coord */
|
/* i.e. log(0.05) = -density * coord */
|
||||||
#define LOG_005 -2.99573227355399
|
#define LOG_005 -2.99573227355399
|
||||||
|
|
||||||
dist = LOG_005 / -fogDensity;
|
dist = (int)(LOG_005 / -fogDensity);
|
||||||
Game_SetViewDistance((int)dist);
|
Game_SetViewDistance(min(dist, Game_UserViewDistance));
|
||||||
} else {
|
} else {
|
||||||
Game_SetViewDistance(Game_UserViewDistance);
|
Game_SetViewDistance(Game_UserViewDistance);
|
||||||
}
|
}
|
||||||
|
@ -67,6 +67,7 @@ void ChunkInfo_Reset(struct ChunkInfo* chunk, int x, int y, int z) {
|
|||||||
chunk->TranslucentParts = NULL;
|
chunk->TranslucentParts = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Index of maximum used 1D atlas + 1 */
|
||||||
CC_NOINLINE static int MapRenderer_UsedAtlases(void) {
|
CC_NOINLINE static int MapRenderer_UsedAtlases(void) {
|
||||||
TextureLoc maxLoc = 0;
|
TextureLoc maxLoc = 0;
|
||||||
int i;
|
int i;
|
||||||
@ -434,16 +435,27 @@ void MapRenderer_RefreshBorders(int maxHeight) {
|
|||||||
static int chunksTarget = 12;
|
static int chunksTarget = 12;
|
||||||
static Vector3 lastCamPos;
|
static Vector3 lastCamPos;
|
||||||
static float lastHeadY, lastHeadX;
|
static float lastHeadY, lastHeadX;
|
||||||
|
/* Max distance from camera that chunks are rendered within */
|
||||||
|
/* This may differ from the view distance configured by the user */
|
||||||
|
static int renderDistSquared;
|
||||||
|
/* Max distance from camera that chunks are built within */
|
||||||
|
/* Chunks past this distance are automatically unloaded */
|
||||||
|
static int buildDistSquared;
|
||||||
|
|
||||||
static int MapRenderer_AdjustViewDist(int dist) {
|
static int MapRenderer_AdjustDist(int dist) {
|
||||||
if (dist < CHUNK_SIZE) dist = CHUNK_SIZE;
|
if (dist < CHUNK_SIZE) dist = CHUNK_SIZE;
|
||||||
dist = Utils_AdjViewDist(dist);
|
dist = Utils_AdjViewDist(dist);
|
||||||
return (dist + 24) * (dist + 24);
|
return (dist + 24) * (dist + 24);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void MapRenderer_CalcViewDists(void) {
|
||||||
|
buildDistSquared = MapRenderer_AdjustDist(Game_UserViewDistance);
|
||||||
|
renderDistSquared = MapRenderer_AdjustDist(Game_ViewDistance);
|
||||||
|
}
|
||||||
|
|
||||||
static int MapRenderer_UpdateChunksAndVisibility(int* chunkUpdates) {
|
static int MapRenderer_UpdateChunksAndVisibility(int* chunkUpdates) {
|
||||||
int viewDistSqr = MapRenderer_AdjustViewDist(Game_ViewDistance);
|
int renderDistSqr = renderDistSquared;
|
||||||
int userDistSqr = MapRenderer_AdjustViewDist(Game_UserViewDistance);
|
int buildDistSqr = buildDistSquared;
|
||||||
|
|
||||||
struct ChunkInfo* info;
|
struct ChunkInfo* info;
|
||||||
int i, j = 0, distSqr;
|
int i, j = 0, distSqr;
|
||||||
@ -456,18 +468,18 @@ static int MapRenderer_UpdateChunksAndVisibility(int* chunkUpdates) {
|
|||||||
distSqr = distances[i];
|
distSqr = distances[i];
|
||||||
noData = !info->NormalParts && !info->TranslucentParts;
|
noData = !info->NormalParts && !info->TranslucentParts;
|
||||||
|
|
||||||
/* Unload chunks beyond visible range */
|
/* Auto unload chunks far away chunks */
|
||||||
if (!noData && distSqr >= userDistSqr + 32 * 16) {
|
if (!noData && distSqr >= buildDistSqr + 32 * 16) {
|
||||||
MapRenderer_DeleteChunk(info); continue;
|
MapRenderer_DeleteChunk(info); continue;
|
||||||
}
|
}
|
||||||
noData |= info->PendingDelete;
|
noData |= info->PendingDelete;
|
||||||
|
|
||||||
if (noData && distSqr <= viewDistSqr && *chunkUpdates < chunksTarget) {
|
if (noData && distSqr <= buildDistSqr && *chunkUpdates < chunksTarget) {
|
||||||
MapRenderer_DeleteChunk(info);
|
MapRenderer_DeleteChunk(info);
|
||||||
MapRenderer_BuildChunk(info, chunkUpdates);
|
MapRenderer_BuildChunk(info, chunkUpdates);
|
||||||
}
|
}
|
||||||
|
|
||||||
info->Visible = distSqr <= viewDistSqr &&
|
info->Visible = distSqr <= renderDistSqr &&
|
||||||
FrustumCulling_SphereInFrustum(info->CentreX, info->CentreY, info->CentreZ, 14); /* 14 ~ sqrt(3 * 8^2) */
|
FrustumCulling_SphereInFrustum(info->CentreX, info->CentreY, info->CentreZ, 14); /* 14 ~ sqrt(3 * 8^2) */
|
||||||
if (info->Visible && !info->Empty) { renderChunks[j] = info; j++; }
|
if (info->Visible && !info->Empty) { renderChunks[j] = info; j++; }
|
||||||
}
|
}
|
||||||
@ -475,8 +487,8 @@ static int MapRenderer_UpdateChunksAndVisibility(int* chunkUpdates) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int MapRenderer_UpdateChunksStill(int* chunkUpdates) {
|
static int MapRenderer_UpdateChunksStill(int* chunkUpdates) {
|
||||||
int viewDistSqr = MapRenderer_AdjustViewDist(Game_ViewDistance);
|
int renderDistSqr = renderDistSquared;
|
||||||
int userDistSqr = MapRenderer_AdjustViewDist(Game_UserViewDistance);
|
int buildDistSqr = buildDistSquared;
|
||||||
|
|
||||||
struct ChunkInfo* info;
|
struct ChunkInfo* info;
|
||||||
int i, j = 0, distSqr;
|
int i, j = 0, distSqr;
|
||||||
@ -489,18 +501,18 @@ static int MapRenderer_UpdateChunksStill(int* chunkUpdates) {
|
|||||||
distSqr = distances[i];
|
distSqr = distances[i];
|
||||||
noData = !info->NormalParts && !info->TranslucentParts;
|
noData = !info->NormalParts && !info->TranslucentParts;
|
||||||
|
|
||||||
/* Unload chunks beyond visible range */
|
/* Auto unload chunks far away chunks */
|
||||||
if (!noData && distSqr >= userDistSqr + 32 * 16) {
|
if (!noData && distSqr >= buildDistSqr + 32 * 16) {
|
||||||
MapRenderer_DeleteChunk(info); continue;
|
MapRenderer_DeleteChunk(info); continue;
|
||||||
}
|
}
|
||||||
noData |= info->PendingDelete;
|
noData |= info->PendingDelete;
|
||||||
|
|
||||||
if (noData && distSqr <= userDistSqr && *chunkUpdates < chunksTarget) {
|
if (noData && distSqr <= buildDistSqr && *chunkUpdates < chunksTarget) {
|
||||||
MapRenderer_DeleteChunk(info);
|
MapRenderer_DeleteChunk(info);
|
||||||
MapRenderer_BuildChunk(info, chunkUpdates);
|
MapRenderer_BuildChunk(info, chunkUpdates);
|
||||||
|
|
||||||
/* only need to update the visibility of chunks in range. */
|
/* only need to update the visibility of chunks in range. */
|
||||||
info->Visible = distSqr <= viewDistSqr &&
|
info->Visible = distSqr <= renderDistSqr &&
|
||||||
FrustumCulling_SphereInFrustum(info->CentreX, info->CentreY, info->CentreZ, 14); /* 14 ~ sqrt(3 * 8^2) */
|
FrustumCulling_SphereInFrustum(info->CentreX, info->CentreY, info->CentreZ, 14); /* 14 ~ sqrt(3 * 8^2) */
|
||||||
if (info->Visible && !info->Empty) { renderChunks[j] = info; j++; }
|
if (info->Visible && !info->Empty) { renderChunks[j] = info; j++; }
|
||||||
} else if (info->Visible) {
|
} else if (info->Visible) {
|
||||||
@ -715,9 +727,12 @@ static void MapRenderer_BlockDefinitionChanged(void* obj) {
|
|||||||
MapRenderer_ResetPartFlags();
|
MapRenderer_ResetPartFlags();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void MapRenderer_RecalcVisibility_(void* obj) { lastCamPos = Vector3_BigPos(); }
|
static void MapRenderer_RecalcVisibility(void* obj) {
|
||||||
static void MapRenderer_DeleteChunks_(void* obj) { MapRenderer_DeleteChunks(); }
|
lastCamPos = Vector3_BigPos();
|
||||||
static void MapRenderer_Refresh_(void* obj) { MapRenderer_Refresh(); }
|
MapRenderer_CalcViewDists();
|
||||||
|
}
|
||||||
|
static void MapRenderer_DeleteChunks_(void* obj) { MapRenderer_DeleteChunks(); }
|
||||||
|
static void MapRenderer_Refresh_(void* obj) { MapRenderer_Refresh(); }
|
||||||
|
|
||||||
static void MapRenderer_OnNewMap(void) {
|
static void MapRenderer_OnNewMap(void) {
|
||||||
Game.ChunkUpdates = 0;
|
Game.ChunkUpdates = 0;
|
||||||
@ -755,8 +770,8 @@ static void MapRenderer_Init(void) {
|
|||||||
Event_RegisterInt(&WorldEvents.EnvVarChanged, NULL, MapRenderer_EnvVariableChanged);
|
Event_RegisterInt(&WorldEvents.EnvVarChanged, NULL, MapRenderer_EnvVariableChanged);
|
||||||
Event_RegisterVoid(&BlockEvents.BlockDefChanged, NULL, MapRenderer_BlockDefinitionChanged);
|
Event_RegisterVoid(&BlockEvents.BlockDefChanged, NULL, MapRenderer_BlockDefinitionChanged);
|
||||||
|
|
||||||
Event_RegisterVoid(&GfxEvents.ViewDistanceChanged, NULL, MapRenderer_RecalcVisibility_);
|
Event_RegisterVoid(&GfxEvents.ViewDistanceChanged, NULL, MapRenderer_RecalcVisibility);
|
||||||
Event_RegisterVoid(&GfxEvents.ProjectionChanged, NULL, MapRenderer_RecalcVisibility_);
|
Event_RegisterVoid(&GfxEvents.ProjectionChanged, NULL, MapRenderer_RecalcVisibility);
|
||||||
Event_RegisterVoid(&GfxEvents.ContextLost, NULL, MapRenderer_DeleteChunks_);
|
Event_RegisterVoid(&GfxEvents.ContextLost, NULL, MapRenderer_DeleteChunks_);
|
||||||
Event_RegisterVoid(&GfxEvents.ContextRecreated, NULL, MapRenderer_Refresh_);
|
Event_RegisterVoid(&GfxEvents.ContextRecreated, NULL, MapRenderer_Refresh_);
|
||||||
|
|
||||||
@ -767,6 +782,7 @@ static void MapRenderer_Init(void) {
|
|||||||
|
|
||||||
Builder_Init();
|
Builder_Init();
|
||||||
Builder_ApplyActive();
|
Builder_ApplyActive();
|
||||||
|
MapRenderer_CalcViewDists();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void MapRenderer_Free(void) {
|
static void MapRenderer_Free(void) {
|
||||||
@ -774,8 +790,8 @@ static void MapRenderer_Free(void) {
|
|||||||
Event_UnregisterInt(&WorldEvents.EnvVarChanged, NULL, MapRenderer_EnvVariableChanged);
|
Event_UnregisterInt(&WorldEvents.EnvVarChanged, NULL, MapRenderer_EnvVariableChanged);
|
||||||
Event_UnregisterVoid(&BlockEvents.BlockDefChanged, NULL, MapRenderer_BlockDefinitionChanged);
|
Event_UnregisterVoid(&BlockEvents.BlockDefChanged, NULL, MapRenderer_BlockDefinitionChanged);
|
||||||
|
|
||||||
Event_UnregisterVoid(&GfxEvents.ViewDistanceChanged, NULL, MapRenderer_RecalcVisibility_);
|
Event_UnregisterVoid(&GfxEvents.ViewDistanceChanged, NULL, MapRenderer_RecalcVisibility);
|
||||||
Event_UnregisterVoid(&GfxEvents.ProjectionChanged, NULL, MapRenderer_RecalcVisibility_);
|
Event_UnregisterVoid(&GfxEvents.ProjectionChanged, NULL, MapRenderer_RecalcVisibility);
|
||||||
Event_UnregisterVoid(&GfxEvents.ContextLost, NULL, MapRenderer_DeleteChunks_);
|
Event_UnregisterVoid(&GfxEvents.ContextLost, NULL, MapRenderer_DeleteChunks_);
|
||||||
Event_UnregisterVoid(&GfxEvents.ContextRecreated, NULL, MapRenderer_Refresh_);
|
Event_UnregisterVoid(&GfxEvents.ContextRecreated, NULL, MapRenderer_Refresh_);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user