Skip to content

Commit 6d07b78

Browse files
committed
neighbor lookups
1 parent 72e7f62 commit 6d07b78

11 files changed

Lines changed: 146 additions & 28 deletions

File tree

src/block.c

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,69 +3,109 @@
33

44
struct
55
{
6+
bool Opaque;
7+
bool Sprite;
68
int Faces[6];
79
}
810
static const kBlocks[BlockCount] =
911
{
1012
[BlockBluebell] =
1113
{
14+
.Opaque = true,
15+
.Sprite = true,
1216
.Faces = {13, 13, 13, 13, 13, 13}
1317
},
1418
[BlockBush] =
1519
{
20+
.Opaque = true,
21+
.Sprite = true,
1622
.Faces = {15, 15, 15, 15, 15, 15}
1723
},
1824
[BlockCloud] =
1925
{
26+
.Opaque = true,
27+
.Sprite = false,
2028
.Faces = { 9, 9, 9, 9, 9, 9}
2129
},
2230
[BlockDandelion] =
2331
{
32+
.Opaque = true,
33+
.Sprite = true,
2434
.Faces = {12, 12, 12, 12, 12, 12}
2535
},
2636
[BlockDirt] =
2737
{
38+
.Opaque = true,
39+
.Sprite = false,
2840
.Faces = { 3, 3, 3, 3, 3, 3}
2941
},
3042
[BlockGrass] =
3143
{
44+
.Opaque = true,
45+
.Sprite = false,
3246
.Faces = { 2, 2, 2, 2, 1, 3}
3347
},
3448
[BlockLavender] =
3549
{
50+
.Opaque = true,
51+
.Sprite = true,
3652
.Faces = {14, 14, 14, 14, 14, 14}
3753
},
3854
[BlockLeaves] =
3955
{
56+
.Opaque = true,
57+
.Sprite = false,
4058
.Faces = {10, 10, 10, 10, 10, 10}
4159
},
4260
[BlockLog] =
4361
{
62+
.Opaque = true,
63+
.Sprite = false,
4464
.Faces = { 8, 8, 8, 8, 7, 7}
4565
},
4666
[BlockRose] =
4767
{
68+
.Opaque = true,
69+
.Sprite = true,
4870
.Faces = {11, 11, 11, 11, 11, 11}
4971
},
5072
[BlockSand] =
5173
{
74+
.Opaque = true,
75+
.Sprite = false,
5276
.Faces = { 5, 5, 5, 5, 5, 5}
5377
},
5478
[BlockSnow] =
5579
{
80+
.Opaque = true,
81+
.Sprite = false,
5682
.Faces = { 6, 6, 6, 6, 6, 6}
5783
},
5884
[BlockStone] =
5985
{
86+
.Opaque = true,
87+
.Sprite = false,
6088
.Faces = { 4, 4, 4, 4, 4, 4}
6189
},
6290
[BlockWater] =
6391
{
92+
.Opaque = false,
93+
.Sprite = false,
6494
.Faces = {16, 16, 16, 16, 16, 16}
6595
},
6696
};
6797

98+
bool IsBlockOpaque(Block block)
99+
{
100+
return kBlocks[block].Opaque;
101+
}
102+
103+
bool IsBlockSprite(Block block)
104+
{
105+
return kBlocks[block].Sprite;
106+
}
107+
68108
int GetBlockFace(Block block, Direction direction)
69109
{
70110
return kBlocks[block].Faces[direction];
71-
}
111+
}

src/block.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,6 @@ enum /* Block */
2525
BlockCount,
2626
};
2727

28+
bool IsBlockOpaque(Block block);
29+
bool IsBlockSprite(Block block);
2830
int GetBlockFace(Block block, Direction direction);

src/chunk.c

Lines changed: 48 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include "block.h"
44
#include "buffer.h"
55
#include "chunk.h"
6+
#include "direction.h"
67
#include "map.h"
78
#include "noise.h"
89
#include "voxel.h"
@@ -57,7 +58,7 @@ void SetChunkBlock(Chunk* chunk, int x, int y, int z, Block block)
5758

5859
Block GetChunkBlock(const Chunk* chunk, int x, int y, int z)
5960
{
60-
SDL_assert(chunk->Flags & ChunkFlagGenerate);
61+
SDL_assert(!(chunk->Flags & ChunkFlagGenerate));
6162
Transform(chunk, &x, &y, &z);
6263
return GetMapValue(&chunk->Blocks, x, y, z);
6364
}
@@ -85,12 +86,54 @@ void MeshChunk(Chunk* chunk, const Chunk* neighbors[3][3], SDL_GPUCopyPass* pass
8586
}
8687
MapRow row = GetMapRow(&chunk->Blocks, i);
8788
SDL_assert(row.Value != BlockEmpty);
88-
89-
for (int i = 0; i < 6; i++)
89+
if (IsBlockSprite(row.Value))
90+
{
91+
continue;
92+
}
93+
for (int j = 0; j < 6; j++)
9094
{
91-
for (int j = 0; j < 4; j++)
95+
int neighborX = row.X + kDirections[j][0];
96+
int neighborY = row.Y + kDirections[j][1];
97+
int neighborZ = row.Z + kDirections[j][2];
98+
Block neighborBlock;
99+
if (neighborY == CHUNK_HEIGHT)
100+
{
101+
neighborBlock = BlockEmpty;
102+
}
103+
else if (neighborY == -1)
104+
{
105+
continue;
106+
}
107+
else if (Contains(chunk, neighborX, neighborY, neighborZ))
108+
{
109+
neighborBlock = GetMapValue(&chunk->Blocks, neighborX, neighborY, neighborZ);
110+
}
111+
else
112+
{
113+
neighborX += chunk->X;
114+
neighborY += chunk->Y;
115+
neighborZ += chunk->Z;
116+
SDL_assert(kDirections[j][1] == 0);
117+
int directionX = kDirections[j][0] + 1;
118+
int directionZ = kDirections[j][2] + 1;
119+
const Chunk* neighbor = neighbors[directionX][directionZ];
120+
// TODO: replace condition with SDL_assert
121+
if (neighbor)
122+
{
123+
neighborBlock = GetChunkBlock(neighbor, neighborX, neighborY, neighborZ);
124+
}
125+
else
126+
{
127+
neighborBlock = BlockEmpty;
128+
}
129+
}
130+
if (IsBlockOpaque(neighborBlock))
131+
{
132+
continue;
133+
}
134+
for (int k = 0; k < 4; k++)
92135
{
93-
Voxel voxel = VoxelPackCube(row.Value, row.X, row.Y, row.Z, i, 0, j);
136+
Voxel voxel = VoxelPackCube(row.Value, row.X, row.Y, row.Z, j, 0, k);
94137
AppendCpuBuffer(&voxelBuffers[ChunkMeshTypeDefault], &voxel);
95138
}
96139
}

src/chunk.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
#include "buffer.h"
77
#include "map.h"
88

9-
#define CHUNK_WIDTH 32
10-
#define CHUNK_HEIGHT 256
9+
#define CHUNK_WIDTH 30
10+
#define CHUNK_HEIGHT 240
1111

1212
typedef struct Noise Noise;
1313

src/light.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44

55
typedef struct Light
66
{
7-
Uint8 red;
8-
Uint8 green;
9-
Uint8 blue;
10-
Uint8 intensity;
7+
Uint8 Red;
8+
Uint8 Green;
9+
Uint8 Blue;
10+
Uint8 Intensity;
1111
}
1212
Light;

src/main.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ SDL_AppResult SDLCALL SDL_AppInit(void** appstate, int argc, char** argv)
216216
#ifndef NDEBUG
217217
SDL_SetLogPriorities(SDL_LOG_PRIORITY_VERBOSE);
218218
#endif
219-
SDL_SetAppMetadata("Voxel Raytracer", NULL, NULL);
219+
SDL_SetAppMetadata("Blocks", NULL, NULL);
220220
if (!SDL_Init(SDL_INIT_VIDEO))
221221
{
222222
SDL_Log("Failed to initialize SDL: %s", SDL_GetError());
@@ -276,7 +276,7 @@ SDL_AppResult SDLCALL SDL_AppInit(void** appstate, int argc, char** argv)
276276
SDL_ShowWindow(window);
277277
SDL_SetWindowResizable(window, true);
278278
SDL_FlashWindow(window, SDL_FLASH_BRIEFLY);
279-
CreateNoise(&noise, NoiseType1x1x1, 1337);
279+
CreateNoise(&noise, NoiseTypeStairs, 1337);
280280
CreateWorld(&world, device);
281281
CreateCamera(&camera, CameraTypePerspective);
282282
ticks = SDL_GetTicks();

src/noise.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,16 @@ static void _1x1x1(const Noise* noise, Chunk* chunk)
1414
SetChunkBlock(chunk, chunk->X, chunk->Y, chunk->Z, BlockGrass);
1515
}
1616

17+
static void Stairs(const Noise* noise, Chunk* chunk)
18+
{
19+
for (int x = 0; x < CHUNK_WIDTH; x++)
20+
for (int z = 0; z < CHUNK_WIDTH; z++)
21+
for (int y = 0; y < z; y++)
22+
{
23+
SetChunkBlock(chunk, chunk->X + x, chunk->Y + y, chunk->Z + z, BlockStone);
24+
}
25+
}
26+
1727
static void Terrain(const Noise* noise, Chunk* chunk)
1828
{
1929
for (int x = 0; x < CHUNK_WIDTH; x++)
@@ -30,6 +40,9 @@ void GenerateChunkNoise(const Noise* noise, Chunk* chunk)
3040
case NoiseType1x1x1:
3141
_1x1x1(noise, chunk);
3242
break;
43+
case NoiseTypeStairs:
44+
Stairs(noise, chunk);
45+
break;
3346
case NoiseTypeTerrain:
3447
Terrain(noise, chunk);
3548
break;

src/noise.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ typedef struct Chunk Chunk;
77
typedef enum NoiseType
88
{
99
NoiseType1x1x1,
10+
NoiseTypeStairs,
1011
NoiseTypeTerrain,
1112
}
1213
NoiseType;

src/world.c

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,17 @@ void CreateWorld(World* world, SDL_GPUDevice* device)
3232
for (int x = 0; x < WORLD_WIDTH; x++)
3333
for (int z = 0; z < WORLD_WIDTH; z++)
3434
{
35-
world->SortedChunks[x][z][0] = x;
36-
world->SortedChunks[x][z][1] = z;
3735
world->Chunks[x][z] = SDL_malloc(sizeof(Chunk));
3836
CreateChunk(world->Chunks[x][z], device);
3937
}
40-
int w = WORLD_WIDTH;
41-
SortXY(w / 2, w / 2, (int*) world->SortedChunks, w * w);
38+
for (int x = 0; x < WORLD_WIDTH - 2; x++)
39+
for (int z = 0; z < WORLD_WIDTH - 2; z++)
40+
{
41+
world->SortedChunks[x][z][0] = x + 1;
42+
world->SortedChunks[x][z][1] = z + 1;
43+
}
44+
int w = WORLD_WIDTH - 2;
45+
SortXY(w / 2 + 1, w / 2 + 1, (int*) world->SortedChunks, w * w);
4246
}
4347

4448
void DestroyWorld(World* world)
@@ -76,6 +80,7 @@ static void Move(World* world, const Camera* camera)
7680
for (int x = 0; x < WORLD_WIDTH; x++)
7781
for (int z = 0; z < WORLD_WIDTH; z++)
7882
{
83+
SDL_assert(world->Chunks[x][z]);
7984
const int a = x - offsetX;
8085
const int b = z - offsetZ;
8186
if (Contains(world, a, b))
@@ -94,6 +99,7 @@ static void Move(World* world, const Camera* camera)
9499
{
95100
if (!world->Chunks[x][z])
96101
{
102+
SDL_assert(size > 0);
97103
Chunk* chunk = out[--size];
98104
chunk->Flags |= ChunkFlagGenerate;
99105
world->Chunks[x][z] = chunk;
@@ -139,25 +145,37 @@ void UpdateWorld(World* world, const Camera* camera, Save* save, Noise* noise)
139145
SDL_CancelGPUCommandBuffer(commandBuffer);
140146
return;
141147
}
148+
bool generated = true;
142149
for (int x = 0; x < WORLD_WIDTH; x++)
143150
for (int y = 0; y < WORLD_WIDTH; y++)
144151
{
145-
int a = world->SortedChunks[x][y][0];
146-
int b = world->SortedChunks[x][y][1];
147-
Chunk* chunk = world->Chunks[a][b];
152+
Chunk* chunk = world->Chunks[x][y];
148153
if (chunk->Flags & ChunkFlagGenerate)
149154
{
150155
GenerateChunk(chunk, noise);
151-
// save
156+
generated = false;
157+
// TODO: use save
158+
// return;
152159
}
153-
if (chunk->Flags & ChunkFlagMesh)
160+
}
161+
if (generated)
162+
{
163+
for (int x = 0; x < WORLD_WIDTH - 2; x++)
164+
for (int y = 0; y < WORLD_WIDTH - 2; y++)
154165
{
166+
int a = world->SortedChunks[x][y][0];
167+
int b = world->SortedChunks[x][y][1];
168+
Chunk* chunk = world->Chunks[a][b];
169+
if (!(chunk->Flags & ChunkFlagMesh))
170+
{
171+
continue;
172+
}
155173
Chunk* neighbors[3][3] = {0};
156174
for (int i = -1; i <= 1; i++)
157175
for (int j = -1; j <= 1; j++)
158176
{
159177
int k = a + i;
160-
int l = y + j;
178+
int l = b + j;
161179
if (Contains(world, k, l))
162180
{
163181
neighbors[i + 1][j + 1] = world->Chunks[k][l];
@@ -168,6 +186,7 @@ void UpdateWorld(World* world, const Camera* camera, Save* save, Noise* noise)
168186
{
169187
CreateIndexBuffer(world, pass, chunk->VoxelBuffers[i].Size * 1.5);
170188
}
189+
// return;
171190
}
172191
}
173192
SDL_EndGPUCopyPass(pass);
@@ -176,8 +195,8 @@ void UpdateWorld(World* world, const Camera* camera, Save* save, Noise* noise)
176195

177196
void RenderWorld(World* world, const Camera* camera, SDL_GPUCommandBuffer* commandBuffer, SDL_GPURenderPass* pass, ChunkMeshType type)
178197
{
179-
for (int x = 0; x < WORLD_WIDTH; x++)
180-
for (int y = 0; y < WORLD_WIDTH; y++)
198+
for (int x = 0; x < WORLD_WIDTH - 2; x++)
199+
for (int y = 0; y < WORLD_WIDTH - 2; y++)
181200
{
182201
int a = world->SortedChunks[x][y][0];
183202
int b = world->SortedChunks[x][y][1];

src/world.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
#include "buffer.h"
77
#include "chunk.h"
88

9-
#define WORLD_WIDTH 20
9+
#define WORLD_WIDTH 4
1010

1111
typedef struct Camera Camera;
1212
typedef struct Noise Noise;
@@ -23,7 +23,7 @@ typedef struct World
2323
CpuBuffer CpuVoxelBuffers[ChunkMeshTypeCount];
2424
CpuBuffer CpuLightBuffer;
2525
Chunk* Chunks[WORLD_WIDTH][WORLD_WIDTH];
26-
int SortedChunks[WORLD_WIDTH][WORLD_WIDTH][2];
26+
int SortedChunks[WORLD_WIDTH - 2][WORLD_WIDTH - 2][2];
2727
}
2828
World;
2929

0 commit comments

Comments
 (0)