Lighting now updates in an unoptimized way when blocks are changed

This commit is contained in:
Goodlyay 2024-05-12 01:10:34 -07:00
parent d759277961
commit b26e9fc3a9
3 changed files with 59 additions and 10 deletions

View File

@ -240,7 +240,7 @@ static void ClassicLighting_RefreshAffected(int x, int y, int z, BlockID block,
} }
} }
static void ClassicLighting_OnBlockChanged(int x, int y, int z, BlockID oldBlock, BlockID newBlock) { void ClassicLighting_OnBlockChanged(int x, int y, int z, BlockID oldBlock, BlockID newBlock) {
int hIndex = Lighting_Pack(x, z); int hIndex = Lighting_Pack(x, z);
int lightH = classic_heightmap[hIndex]; int lightH = classic_heightmap[hIndex];
int newHeight; int newHeight;

View File

@ -71,4 +71,5 @@ void ClassicLighting_FreeState(void);
void ClassicLighting_AllocState(void); void ClassicLighting_AllocState(void);
int ClassicLighting_GetLightHeight(int x, int z); int ClassicLighting_GetLightHeight(int x, int z);
void ClassicLighting_LightHint(int startX, int startZ); void ClassicLighting_LightHint(int startX, int startZ);
void ClassicLighting_OnBlockChanged(int x, int y, int z, BlockID oldBlock, BlockID newBlock);
#endif #endif

View File

@ -136,6 +136,8 @@ static void ModernLighting_FreeState(void) {
#define ChunkCoordsToIndex(cx, cy, cz) (((cy) * World.ChunksZ + (cz)) * World.ChunksX + (cx)) #define ChunkCoordsToIndex(cx, cy, cz) (((cy) * World.ChunksZ + (cz)) * World.ChunksX + (cx))
/* Converts local x/y/z coordinates to the corresponding index in a chunk */ /* Converts local x/y/z coordinates to the corresponding index in a chunk */
#define LocalCoordsToIndex(lx, ly, lz) ((lx) | ((lz) << CHUNK_SHIFT) | ((ly) << (CHUNK_SHIFT * 2))) #define LocalCoordsToIndex(lx, ly, lz) ((lx) | ((lz) << CHUNK_SHIFT) | ((ly) << (CHUNK_SHIFT * 2)))
/* Converts global x/y/z coordinates to the corresponding index in a chunk */
#define GlobalCoordsToChunkCoordsIndex(x, y, z) (LocalCoordsToIndex(x & CHUNK_MASK, y & CHUNK_MASK, z & CHUNK_MASK))
static void SetBlocklight(cc_uint8 blockLight, int x, int y, int z, cc_bool sun) { static void SetBlocklight(cc_uint8 blockLight, int x, int y, int z, cc_bool sun) {
cc_uint8 clearMask; cc_uint8 clearMask;
@ -235,6 +237,7 @@ static void CalculateChunkLightingSelf(int chunkIndex, int cx, int cy, int cz) {
int chunkStartX, chunkStartY, chunkStartZ; //world coords int chunkStartX, chunkStartY, chunkStartZ; //world coords
int chunkEndX, chunkEndY, chunkEndZ; //world coords int chunkEndX, chunkEndY, chunkEndZ; //world coords
cc_uint8 brightness; cc_uint8 brightness;
BlockID curBlock;
chunkStartX = cx * CHUNK_SIZE; chunkStartX = cx * CHUNK_SIZE;
chunkStartY = cy * CHUNK_SIZE; chunkStartY = cy * CHUNK_SIZE;
chunkStartZ = cz * CHUNK_SIZE; chunkStartZ = cz * CHUNK_SIZE;
@ -253,7 +256,7 @@ static void CalculateChunkLightingSelf(int chunkIndex, int cx, int cy, int cz) {
for (z = chunkStartZ; z < chunkEndZ; z++) { for (z = chunkStartZ; z < chunkEndZ; z++) {
for (x = chunkStartX; x < chunkEndX; x++) { for (x = chunkStartX; x < chunkEndX; x++) {
BlockID curBlock = World_GetBlock(x, y, z); curBlock = World_GetBlock(x, y, z);
if (Blocks.Brightness[curBlock] > 0) { if (Blocks.Brightness[curBlock] > 0) {
/* mask out the sun brightness */ /* mask out the sun brightness */
brightness = Blocks.Brightness[curBlock] & MODERN_LIGHTING_MAX_LEVEL; brightness = Blocks.Brightness[curBlock] & MODERN_LIGHTING_MAX_LEVEL;
@ -274,7 +277,7 @@ static void CalculateChunkLightingSelf(int chunkIndex, int cx, int cy, int cz) {
chunkLightingDataFlags[chunkIndex] = CHUNK_SELF_CALCULATED; chunkLightingDataFlags[chunkIndex] = CHUNK_SELF_CALCULATED;
} }
static void CalculateChunkLightingAll(int chunkIndex, int cx, int cy, int cz) { static void CalculateChunkLightingAll(int chunkIndex, int cx, int cy, int cz, cc_bool recalculate) {
int x, y, z; int x, y, z;
int chunkStartX, chunkStartY, chunkStartZ; //chunk coords int chunkStartX, chunkStartY, chunkStartZ; //chunk coords
int chunkEndX, chunkEndY, chunkEndZ; //chunk coords int chunkEndX, chunkEndY, chunkEndZ; //chunk coords
@ -294,6 +297,25 @@ static void CalculateChunkLightingAll(int chunkIndex, int cx, int cy, int cz) {
if (chunkEndY == World.ChunksY) { chunkEndY--; } if (chunkEndY == World.ChunksY) { chunkEndY--; }
if (chunkEndZ == World.ChunksZ) { chunkEndZ--; } if (chunkEndZ == World.ChunksZ) { chunkEndZ--; }
if (recalculate) {
for (y = chunkStartY; y <= chunkEndY; y++) {
for (z = chunkStartZ; z <= chunkEndZ; z++) {
for (x = chunkStartX; x <= chunkEndX; x++) {
curChunkIndex = ChunkCoordsToIndex(x, y, z);
//Delete all lighting from this chunk
Mem_Free(chunkLightingData[curChunkIndex]);
//TODO: Why does skipping this allocation cause a crash? It should automatically allocate in SetBlocklight
chunkLightingData[curChunkIndex] = (cc_uint8*)Mem_TryAllocCleared(CHUNK_SIZE_3, sizeof(cc_uint8));
chunkLightingDataFlags[curChunkIndex] = CHUNK_UNCALCULATED;
MapRenderer_RefreshChunk(x, y, z);
}
}
}
}
for (y = chunkStartY; y <= chunkEndY; y++) { for (y = chunkStartY; y <= chunkEndY; y++) {
for (z = chunkStartZ; z <= chunkEndZ; z++) { for (z = chunkStartZ; z <= chunkEndZ; z++) {
for (x = chunkStartX; x <= chunkEndX; x++) { for (x = chunkStartX; x <= chunkEndX; x++) {
@ -308,7 +330,31 @@ static void CalculateChunkLightingAll(int chunkIndex, int cx, int cy, int cz) {
chunkLightingDataFlags[chunkIndex] = CHUNK_ALL_CALCULATED; chunkLightingDataFlags[chunkIndex] = CHUNK_ALL_CALCULATED;
} }
static void CalcUnlight(int x, int y, int z, cc_uint8 lightData) {
}
static void ModernLighting_OnBlockChanged(int x, int y, int z, BlockID oldBlock, BlockID newBlock) { static void ModernLighting_OnBlockChanged(int x, int y, int z, BlockID oldBlock, BlockID newBlock) {
cc_uint8 lightData;
int cx, cy, cz, chunkIndex;
int chunkCoordsIndex;
BlockID curBlock;
ClassicLighting_OnBlockChanged(x, y, z, oldBlock, newBlock);
cx = x >> CHUNK_SHIFT;
cy = y >> CHUNK_SHIFT;
cz = z >> CHUNK_SHIFT;
chunkIndex = ChunkCoordsToIndex(cx, cy, cz);
if (chunkLightingData[chunkIndex] == NULL) {
lightData = 0;
} else {
chunkCoordsIndex = GlobalCoordsToChunkCoordsIndex(x, y, z);
lightData = chunkLightingData[chunkIndex][chunkCoordsIndex];
}
/* lazily recalculate all lighting in this chunkand neighbors, TODO optimise this */
CalculateChunkLightingAll(chunkIndex, cx, cy, cz, true);
} }
/* Invalidates/Resets lighting state for all of the blocks in the world */ /* Invalidates/Resets lighting state for all of the blocks in the world */
@ -320,19 +366,21 @@ static void ModernLighting_Refresh(void) {
static cc_bool ModernLighting_IsLit(int x, int y, int z) { return true; } static cc_bool ModernLighting_IsLit(int x, int y, int z) { return true; }
static cc_bool ModernLighting_IsLit_Fast(int x, int y, int z) { return true; } static cc_bool ModernLighting_IsLit_Fast(int x, int y, int z) { return true; }
static PackedCol ModernLighting_Color_Core(int x, int y, int z, PackedCol* palette, PackedCol outOfBoundsColor) { static PackedCol ModernLighting_Color_Core(int x, int y, int z, PackedCol* palette, PackedCol outOfBoundsColor) {
cc_uint8 lightData; cc_uint8 lightData;
int localIndex, cx, cy, cz, lx, ly, lz, chunkIndex; int cx, cy, cz, chunkIndex;
int chunkCoordsIndex;
if (!World_Contains(x, y, z)) return outOfBoundsColor; if (!World_Contains(x, y, z)) return outOfBoundsColor;
cx = x >> CHUNK_SHIFT, lx = x & CHUNK_MASK; cx = x >> CHUNK_SHIFT;
cy = y >> CHUNK_SHIFT, ly = y & CHUNK_MASK; cy = y >> CHUNK_SHIFT;
cz = z >> CHUNK_SHIFT, lz = z & CHUNK_MASK; cz = z >> CHUNK_SHIFT;
chunkIndex = ChunkCoordsToIndex(cx, cy, cz); chunkIndex = ChunkCoordsToIndex(cx, cy, cz);
if (chunkLightingDataFlags[chunkIndex] < CHUNK_ALL_CALCULATED) { if (chunkLightingDataFlags[chunkIndex] < CHUNK_ALL_CALCULATED) {
CalculateChunkLightingAll(chunkIndex, cx, cy, cz); CalculateChunkLightingAll(chunkIndex, cx, cy, cz, false);
} }
/* There might be no light data in this chunk even after it was calculated */ /* There might be no light data in this chunk even after it was calculated */
@ -340,8 +388,8 @@ static PackedCol ModernLighting_Color_Core(int x, int y, int z, PackedCol* palet
/* 0, no sun or light (but it may appear as sun based on the 2D sun map) */ /* 0, no sun or light (but it may appear as sun based on the 2D sun map) */
lightData = 0; lightData = 0;
} else { } else {
localIndex = LocalCoordsToIndex(lx, ly, lz); chunkCoordsIndex = GlobalCoordsToChunkCoordsIndex(x, y, z);
lightData = chunkLightingData[chunkIndex][localIndex]; lightData = chunkLightingData[chunkIndex][chunkCoordsIndex];
} }
/* This cell is exposed to sunlight */ /* This cell is exposed to sunlight */