Move chunks dimensions code from MapRenderer to World

This commit is contained in:
UnknownShadow200 2022-07-02 16:58:35 +10:00
parent 033560a773
commit db97e790c3
7 changed files with 47 additions and 47 deletions

View File

@ -412,14 +412,14 @@ void Builder_MakeChunk(struct ChunkInfo* info) {
hasMesh = BuildChunk(x, y, z, info); hasMesh = BuildChunk(x, y, z, info);
if (!hasMesh) return; if (!hasMesh) return;
partsIndex = MapRenderer_Pack(x >> CHUNK_SHIFT, y >> CHUNK_SHIFT, z >> CHUNK_SHIFT); partsIndex = World_ChunkPack(x >> CHUNK_SHIFT, y >> CHUNK_SHIFT, z >> CHUNK_SHIFT);
offset = 0; offset = 0;
hasNorm = false; hasNorm = false;
hasTran = false; hasTran = false;
for (i = 0; i < MapRenderer_1DUsedCount; i++) { for (i = 0; i < MapRenderer_1DUsedCount; i++) {
j = i + ATLAS1D_MAX_ATLASES; j = i + ATLAS1D_MAX_ATLASES;
curIdx = partsIndex + i * MapRenderer_ChunksCount; curIdx = partsIndex + i * World.ChunksCount;
SetPartInfo(&Builder_Parts[i], &offset, &MapRenderer_PartsNormal[curIdx], &hasNorm); SetPartInfo(&Builder_Parts[i], &offset, &MapRenderer_PartsNormal[curIdx], &hasNorm);
SetPartInfo(&Builder_Parts[j], &offset, &MapRenderer_PartsTranslucent[curIdx], &hasTran); SetPartInfo(&Builder_Parts[j], &offset, &MapRenderer_PartsTranslucent[curIdx], &hasTran);

View File

@ -218,13 +218,13 @@ static void ClassicLighting_RefreshAffected(int x, int y, int z, BlockID block,
ClassicLighting_ResetNeighbour(x, y, z - 1, block, cx, cy, cz - 1, minCy, maxCy); ClassicLighting_ResetNeighbour(x, y, z - 1, block, cx, cy, cz - 1, minCy, maxCy);
} }
if (bX == 15 && cx < MapRenderer_ChunksX - 1) { if (bX == 15 && cx < World.ChunksX - 1) {
ClassicLighting_ResetNeighbour(x + 1, y, z, block, cx + 1, cy, cz, minCy, maxCy); ClassicLighting_ResetNeighbour(x + 1, y, z, block, cx + 1, cy, cz, minCy, maxCy);
} }
if (bY == 15 && cy < MapRenderer_ChunksY - 1 && ClassicLighting_Needs(block, World_GetBlock(x, y + 1, z))) { if (bY == 15 && cy < World.ChunksY - 1 && ClassicLighting_Needs(block, World_GetBlock(x, y + 1, z))) {
MapRenderer_RefreshChunk(cx, cy + 1, cz); MapRenderer_RefreshChunk(cx, cy + 1, cz);
} }
if (bZ == 15 && cz < MapRenderer_ChunksZ - 1) { if (bZ == 15 && cz < World.ChunksZ - 1) {
ClassicLighting_ResetNeighbour(x, y, z + 1, block, cx, cy, cz + 1, minCy, maxCy); ClassicLighting_ResetNeighbour(x, y, z + 1, block, cx, cy, cz + 1, minCy, maxCy);
} }
} }

View File

@ -15,8 +15,7 @@
#include "World.h" #include "World.h"
#include "Options.h" #include "Options.h"
int MapRenderer_ChunksX, MapRenderer_ChunksY, MapRenderer_ChunksZ; int MapRenderer_1DUsedCount;
int MapRenderer_1DUsedCount, MapRenderer_ChunksCount;
struct ChunkPartInfo* MapRenderer_PartsNormal; struct ChunkPartInfo* MapRenderer_PartsNormal;
struct ChunkPartInfo* MapRenderer_PartsTranslucent; struct ChunkPartInfo* MapRenderer_PartsTranslucent;
@ -117,7 +116,7 @@ if (drawMin && drawMax) { \
} }
static void RenderNormalBatch(int batch) { static void RenderNormalBatch(int batch) {
int batchOffset = MapRenderer_ChunksCount * batch; int batchOffset = World.ChunksCount * batch;
struct ChunkInfo* info; struct ChunkInfo* info;
struct ChunkPartInfo part; struct ChunkPartInfo part;
cc_bool drawMin, drawMax; cc_bool drawMin, drawMax;
@ -221,7 +220,7 @@ if (drawMin && drawMax) { \
} }
static void RenderTranslucentBatch(int batch) { static void RenderTranslucentBatch(int batch) {
int batchOffset = MapRenderer_ChunksCount * batch; int batchOffset = World.ChunksCount * batch;
struct ChunkInfo* info; struct ChunkInfo* info;
struct ChunkPartInfo part; struct ChunkPartInfo part;
cc_bool drawMin, drawMax; cc_bool drawMin, drawMax;
@ -324,7 +323,7 @@ static void DeleteChunk(struct ChunkInfo* info) {
if (info->NormalParts) { if (info->NormalParts) {
ptr = info->NormalParts; ptr = info->NormalParts;
for (i = 0; i < MapRenderer_1DUsedCount; i++, ptr += MapRenderer_ChunksCount) { for (i = 0; i < MapRenderer_1DUsedCount; i++, ptr += World.ChunksCount) {
if (ptr->Offset < 0) continue; if (ptr->Offset < 0) continue;
normPartsCount[i]--; normPartsCount[i]--;
#ifdef CC_BUILD_GL11 #ifdef CC_BUILD_GL11
@ -336,7 +335,7 @@ static void DeleteChunk(struct ChunkInfo* info) {
if (info->TranslucentParts) { if (info->TranslucentParts) {
ptr = info->TranslucentParts; ptr = info->TranslucentParts;
for (i = 0; i < MapRenderer_1DUsedCount; i++, ptr += MapRenderer_ChunksCount) { for (i = 0; i < MapRenderer_1DUsedCount; i++, ptr += World.ChunksCount) {
if (ptr->Offset < 0) continue; if (ptr->Offset < 0) continue;
tranPartsCount[i]--; tranPartsCount[i]--;
#ifdef CC_BUILD_GL11 #ifdef CC_BUILD_GL11
@ -363,14 +362,14 @@ static void BuildChunk(struct ChunkInfo* info, int* chunkUpdates) {
if (info->NormalParts) { if (info->NormalParts) {
ptr = info->NormalParts; ptr = info->NormalParts;
for (i = 0; i < MapRenderer_1DUsedCount; i++, ptr += MapRenderer_ChunksCount) { for (i = 0; i < MapRenderer_1DUsedCount; i++, ptr += World.ChunksCount) {
if (ptr->Offset >= 0) normPartsCount[i]++; if (ptr->Offset >= 0) normPartsCount[i]++;
} }
} }
if (info->TranslucentParts) { if (info->TranslucentParts) {
ptr = info->TranslucentParts; ptr = info->TranslucentParts;
for (i = 0; i < MapRenderer_1DUsedCount; i++, ptr += MapRenderer_ChunksCount) { for (i = 0; i < MapRenderer_1DUsedCount; i++, ptr += World.ChunksCount) {
if (ptr->Offset >= 0) tranPartsCount[i]++; if (ptr->Offset >= 0) tranPartsCount[i]++;
} }
} }
@ -400,7 +399,7 @@ static void FreeChunks(void) {
static void AllocateParts(void) { static void AllocateParts(void) {
struct ChunkPartInfo* ptr; struct ChunkPartInfo* ptr;
cc_uint32 count = MapRenderer_ChunksCount * MapRenderer_1DUsedCount; cc_uint32 count = World.ChunksCount * MapRenderer_1DUsedCount;
ptr = (struct ChunkPartInfo*)Mem_AllocCleared(count * 2, sizeof(struct ChunkPartInfo), "chunk parts"); ptr = (struct ChunkPartInfo*)Mem_AllocCleared(count * 2, sizeof(struct ChunkPartInfo), "chunk parts");
MapRenderer_PartsNormal = ptr; MapRenderer_PartsNormal = ptr;
@ -408,10 +407,10 @@ static void AllocateParts(void) {
} }
static void AllocateChunks(void) { static void AllocateChunks(void) {
mapChunks = (struct ChunkInfo*) Mem_Alloc(MapRenderer_ChunksCount, sizeof(struct ChunkInfo), "chunk info"); mapChunks = (struct ChunkInfo*) Mem_Alloc(World.ChunksCount, sizeof(struct ChunkInfo), "chunk info");
sortedChunks = (struct ChunkInfo**)Mem_Alloc(MapRenderer_ChunksCount, sizeof(struct ChunkInfo*), "sorted chunk info"); sortedChunks = (struct ChunkInfo**)Mem_Alloc(World.ChunksCount, sizeof(struct ChunkInfo*), "sorted chunk info");
renderChunks = (struct ChunkInfo**)Mem_Alloc(MapRenderer_ChunksCount, sizeof(struct ChunkInfo*), "render chunk info"); renderChunks = (struct ChunkInfo**)Mem_Alloc(World.ChunksCount, sizeof(struct ChunkInfo*), "render chunk info");
distances = (cc_uint32*)Mem_Alloc(MapRenderer_ChunksCount, 4, "chunk distances"); distances = (cc_uint32*)Mem_Alloc(World.ChunksCount, 4, "chunk distances");
} }
static void ResetPartFlags(void) { static void ResetPartFlags(void) {
@ -463,7 +462,7 @@ static void DeleteChunks(void) {
int i; int i;
if (!mapChunks) return; if (!mapChunks) return;
for (i = 0; i < MapRenderer_ChunksCount; i++) { for (i = 0; i < World.ChunksCount; i++) {
DeleteChunk(&mapChunks[i]); DeleteChunk(&mapChunks[i]);
} }
ResetPartCounts(); ResetPartCounts();
@ -496,10 +495,10 @@ static void RefreshBorderChunks(int maxHeight) {
chunkPos = IVec3_MaxValue(); chunkPos = IVec3_MaxValue();
if (!mapChunks || !World.Blocks) return; if (!mapChunks || !World.Blocks) return;
for (cz = 0; cz < MapRenderer_ChunksZ; cz++) { for (cz = 0; cz < World.ChunksZ; cz++) {
for (cy = 0; cy < MapRenderer_ChunksY; cy++) { for (cy = 0; cy < World.ChunksY; cy++) {
for (cx = 0; cx < MapRenderer_ChunksX; cx++) { for (cx = 0; cx < World.ChunksX; cx++) {
onBorder = cx == 0 || cz == 0 || cx == (MapRenderer_ChunksX - 1) || cz == (MapRenderer_ChunksZ - 1); onBorder = cx == 0 || cz == 0 || cx == (World.ChunksX - 1) || cz == (World.ChunksZ - 1);
if (onBorder && (cy * CHUNK_SIZE) < maxHeight) { if (onBorder && (cy * CHUNK_SIZE) < maxHeight) {
MapRenderer_RefreshChunk(cx, cy, cz); MapRenderer_RefreshChunk(cx, cy, cz);
@ -543,7 +542,7 @@ static int UpdateChunksAndVisibility(int* chunkUpdates) {
int i, j = 0, distSqr; int i, j = 0, distSqr;
cc_bool noData; cc_bool noData;
for (i = 0; i < MapRenderer_ChunksCount; i++) { for (i = 0; i < World.ChunksCount; i++) {
info = sortedChunks[i]; info = sortedChunks[i];
if (info->Empty) continue; if (info->Empty) continue;
@ -576,7 +575,7 @@ static int UpdateChunksStill(int* chunkUpdates) {
int i, j = 0, distSqr; int i, j = 0, distSqr;
cc_bool noData; cc_bool noData;
for (i = 0; i < MapRenderer_ChunksCount; i++) { for (i = 0; i < World.ChunksCount; i++) {
info = sortedChunks[i]; info = sortedChunks[i];
if (info->Empty) continue; if (info->Empty) continue;
@ -661,9 +660,9 @@ static void UpdateSortOrder(void) {
/* If in same chunk, don't need to recalculate sort order */ /* If in same chunk, don't need to recalculate sort order */
if (pos.X == chunkPos.X && pos.Y == chunkPos.Y && pos.Z == chunkPos.Z) return; if (pos.X == chunkPos.X && pos.Y == chunkPos.Y && pos.Z == chunkPos.Z) return;
chunkPos = pos; chunkPos = pos;
if (!MapRenderer_ChunksCount) return; if (!World.ChunksCount) return;
for (i = 0; i < MapRenderer_ChunksCount; i++) { for (i = 0; i < World.ChunksCount; i++) {
info = sortedChunks[i]; info = sortedChunks[i];
/* Calculate distance to chunk centre */ /* Calculate distance to chunk centre */
dx = info->CentreX - pos.X; dy = info->CentreY - pos.Y; dz = info->CentreZ - pos.Z; dx = info->CentreX - pos.X; dy = info->CentreY - pos.Y; dz = info->CentreZ - pos.Z;
@ -682,7 +681,7 @@ static void UpdateSortOrder(void) {
info->DrawYMin = dy >= 0; info->DrawYMax = dy <= 0; info->DrawYMin = dy >= 0; info->DrawYMax = dy <= 0;
} }
SortMapChunks(0, MapRenderer_ChunksCount - 1); SortMapChunks(0, World.ChunksCount - 1);
ResetPartFlags(); ResetPartFlags();
/*SimpleOcclusionCulling();*/ /*SimpleOcclusionCulling();*/
} }
@ -699,10 +698,9 @@ void MapRenderer_Update(double delta) {
*#########################################################################################################################*/ *#########################################################################################################################*/
void MapRenderer_RefreshChunk(int cx, int cy, int cz) { void MapRenderer_RefreshChunk(int cx, int cy, int cz) {
struct ChunkInfo* info; struct ChunkInfo* info;
if (cx < 0 || cy < 0 || cz < 0 || cx >= MapRenderer_ChunksX if (cx < 0 || cy < 0 || cz < 0 || cx >= World.ChunksX || cy >= World.ChunksY || cz >= World.ChunksZ) return;
|| cy >= MapRenderer_ChunksY || cz >= MapRenderer_ChunksZ) return;
info = &mapChunks[MapRenderer_Pack(cx, cy, cz)]; info = &mapChunks[World_ChunkPack(cx, cy, cz)];
if (info->AllAir) return; /* do not recreate chunks completely air */ if (info->AllAir) return; /* do not recreate chunks completely air */
info->Empty = false; info->Empty = false;
info->PendingDelete = true; info->PendingDelete = true;
@ -712,7 +710,7 @@ void MapRenderer_OnBlockChanged(int x, int y, int z, BlockID block) {
int cx = x >> CHUNK_SHIFT, cy = y >> CHUNK_SHIFT, cz = z >> CHUNK_SHIFT; int cx = x >> CHUNK_SHIFT, cy = y >> CHUNK_SHIFT, cz = z >> CHUNK_SHIFT;
struct ChunkInfo* chunk; struct ChunkInfo* chunk;
chunk = &mapChunks[MapRenderer_Pack(cx, cy, cz)]; chunk = &mapChunks[World_ChunkPack(cx, cy, cz)];
chunk->AllAir &= Blocks.Draw[block] == DRAW_GAS; chunk->AllAir &= Blocks.Draw[block] == DRAW_GAS;
/* TODO: Don't lookup twice, refresh directly using chunk pointer */ /* TODO: Don't lookup twice, refresh directly using chunk pointer */
MapRenderer_RefreshChunk(cx, cy, cz); MapRenderer_RefreshChunk(cx, cy, cz);
@ -767,15 +765,9 @@ static void OnNewMap(void) {
} }
static void OnNewMapLoaded(void) { static void OnNewMapLoaded(void) {
int count;
MapRenderer_ChunksX = (World.Width + CHUNK_MAX) >> CHUNK_SHIFT;
MapRenderer_ChunksY = (World.Height + CHUNK_MAX) >> CHUNK_SHIFT;
MapRenderer_ChunksZ = (World.Length + CHUNK_MAX) >> CHUNK_SHIFT;
count = MapRenderer_ChunksX * MapRenderer_ChunksY * MapRenderer_ChunksZ;
/* TODO: Only perform reallocation when map volume has changed */ /* TODO: Only perform reallocation when map volume has changed */
/*if (MapRenderer_ChunksCount != count) { */ /*if (MapRenderer_ChunksCount != World.ChunksCount) { */
MapRenderer_ChunksCount = count; /* MapRenderer_ChunksCount = World.ChunksCount; */
FreeChunks(); FreeChunks();
FreeParts(); FreeParts();
AllocateChunks(); AllocateChunks();

View File

@ -10,14 +10,8 @@
struct IGameComponent; struct IGameComponent;
extern struct IGameComponent MapRenderer_Component; extern struct IGameComponent MapRenderer_Component;
extern int MapRenderer_ChunksX, MapRenderer_ChunksY, MapRenderer_ChunksZ;
#define MapRenderer_Pack(cx, cy, cz) (((cz) * MapRenderer_ChunksY + (cy)) * MapRenderer_ChunksX + (cx))
/* TODO: Swap Y and Z? Make sure to update ChunkUpdater's ResetChunkCache and ClearChunkCache methods! */
/* Max used 1D atlases. (i.e. Atlas1D_Index(maxTextureLoc) + 1) */ /* Max used 1D atlases. (i.e. Atlas1D_Index(maxTextureLoc) + 1) */
extern int MapRenderer_1DUsedCount; extern int MapRenderer_1DUsedCount;
/* Number of chunks in the world, or ChunksX * ChunksY * ChunksZ */
extern int MapRenderer_ChunksCount;
/* Buffer for all chunk parts. There are (MapRenderer_ChunksCount * Atlas1D_Count) parts in the buffer, /* Buffer for all chunk parts. There are (MapRenderer_ChunksCount * Atlas1D_Count) parts in the buffer,
with parts for 'normal' buffer being in lower half. */ with parts for 'normal' buffer being in lower half. */

View File

@ -197,7 +197,7 @@ static LRESULT CALLBACK Window_Procedure(HWND handle, UINT message, WPARAM wPara
/* To understand reasoning behind the following code, see Remarks in */ /* To understand reasoning behind the following code, see Remarks in */
/* https://docs.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-rawmouse */ /* https://docs.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-rawmouse */
static int prevPosX, prevPosY; static int prevPosX, prevPosY;
isVirtual = (raw.data.mouse.usFlags & MOUSE_VIRTUAL_DESKTOP); isVirtual = raw.data.mouse.usFlags & MOUSE_VIRTUAL_DESKTOP;
width = GetSystemMetrics(isVirtual ? SM_CXVIRTUALSCREEN : SM_CXSCREEN); width = GetSystemMetrics(isVirtual ? SM_CXVIRTUALSCREEN : SM_CXSCREEN);
height = GetSystemMetrics(isVirtual ? SM_CYVIRTUALSCREEN : SM_CYSCREEN); height = GetSystemMetrics(isVirtual ? SM_CYVIRTUALSCREEN : SM_CYSCREEN);

View File

@ -91,6 +91,12 @@ CC_NOINLINE void World_SetDimensions(int width, int height, int length) {
World.MaxX = width - 1; World.MaxX = width - 1;
World.MaxY = height - 1; World.MaxY = height - 1;
World.MaxZ = length - 1; World.MaxZ = length - 1;
World.ChunksX = (width + CHUNK_MAX) >> CHUNK_SHIFT;
World.ChunksY = (height + CHUNK_MAX) >> CHUNK_SHIFT;
World.ChunksZ = (length + CHUNK_MAX) >> CHUNK_SHIFT;
World.ChunksCount = World.ChunksX * World.ChunksY * World.ChunksZ;
} }
#ifdef EXTENDED_BLOCKS #ifdef EXTENDED_BLOCKS

View File

@ -15,6 +15,10 @@ extern struct IGameComponent World_Component;
#define World_Pack(x, y, z) (((y) * World.Length + (z)) * World.Width + (x)) #define World_Pack(x, y, z) (((y) * World.Length + (z)) * World.Width + (x))
#define WORLD_UUID_LEN 16 #define WORLD_UUID_LEN 16
#define World_ChunkPack(cx, cy, cz) (((cz) * World.ChunksY + (cy)) * World.ChunksX + (cx))
/* TODO: Swap Y and Z? Make sure to update MapRenderer's ResetChunkCache and ClearChunkCache methods! */
CC_VAR extern struct _WorldData { CC_VAR extern struct _WorldData {
/* The blocks in the world. */ /* The blocks in the world. */
BlockRaw* Blocks; BlockRaw* Blocks;
@ -48,6 +52,10 @@ CC_VAR extern struct _WorldData {
double LastSave; double LastSave;
/* Default name of the world when saving */ /* Default name of the world when saving */
cc_string Name; cc_string Name;
/* Number of chunks on each axis the world is subdivided into */
int ChunksX, ChunksY, ChunksZ;
/* Number of chunks in the world, or ChunksX * ChunksY * ChunksZ */
int ChunksCount;
} World; } World;
/* Frees the blocks array, sets dimensions to 0, resets environment to default. */ /* Frees the blocks array, sets dimensions to 0, resets environment to default. */