Skip to content
This repository has been archived by the owner on Nov 25, 2024. It is now read-only.

Commit

Permalink
Load chunks around the camera
Browse files Browse the repository at this point in the history
  • Loading branch information
Oliver-makes-code committed Nov 26, 2023
1 parent ca46842 commit 4142968
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 16 deletions.
4 changes: 2 additions & 2 deletions Client/Rendering/World/ChunkRenderSlot.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,11 @@ public override void Render(double delta) {
}
}

public void Move(ivec3 newCenterPos) {
public void Move(ivec3 newCenterPos, LoadedChunkSection chunks) {
realPosition = newCenterPos + RelativePosition;

//Should never be null bc this only has 1 callsite that already null checks it
targetChunk = Client.world!.GetOrCreateChunk(realPosition);
targetChunk = chunks.GetChunkRelative(RelativePosition);
lastVersion = null;
}

Expand Down
38 changes: 24 additions & 14 deletions Client/Rendering/World/ChunkRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,25 @@
using Voxel.Client.Rendering.Texture;
using Voxel.Client.Rendering.VertexTypes;
using Voxel.Common.Util;
using Voxel.Common.World;

namespace Voxel.Client.Rendering.World;

public class ChunkRenderer : Renderer {

public readonly Pipeline ChunkPipeline;
public readonly ResourceLayout ChunkResourceLayout;

public readonly Atlas TerrainAtlas;

public LoadedChunkSection chunks;

private ChunkRenderSlot[]? renderSlots;
private int renderDistance = 0;
private int realRenderDistance = 0;

private ivec3 renderPosition = ivec3.Zero;

public readonly Pipeline ChunkPipeline;
public readonly ResourceLayout ChunkResourceLayout;

public readonly Atlas TerrainAtlas;

private ChunkRenderSlot? this[int x, int y, int z] {
get {
if (renderSlots == null) return null;
Expand All @@ -44,8 +47,9 @@ private ChunkRenderSlot? this[ivec3 pos] {
}

public ChunkRenderer(VoxelClient client) : base(client) {
chunks = new(client.world!, renderPosition, ClientConfig.General.renderDistance, ClientConfig.General.renderDistance);
SetRenderDistance(ClientConfig.General.renderDistance);

TerrainAtlas = new("main", client.RenderSystem);
AtlasLoader.LoadAtlas(RenderSystem.Game.AssetReader, TerrainAtlas, RenderSystem);
BlockModelManager.Init(RenderSystem.Game.AssetReader, TerrainAtlas);
Expand All @@ -58,16 +62,16 @@ public ChunkRenderer(VoxelClient client) : base(client) {
if (!client.RenderSystem.ShaderManager.GetShaders("shaders/simple", out var shaders))
throw new("Shaders not present.");

ChunkPipeline = ResourceFactory.CreateGraphicsPipeline(new GraphicsPipelineDescription {
ChunkPipeline = ResourceFactory.CreateGraphicsPipeline(new() {
BlendState = BlendStateDescription.SingleOverrideBlend,
DepthStencilState = new DepthStencilStateDescription {
DepthStencilState = new() {
DepthComparison = ComparisonKind.LessEqual,
DepthTestEnabled = true,
DepthWriteEnabled = true,
},
Outputs = RenderSystem.GraphicsDevice.SwapchainFramebuffer.OutputDescription,
PrimitiveTopology = PrimitiveTopology.TriangleList,
RasterizerState = new RasterizerStateDescription {
RasterizerState = new() {
CullMode = FaceCullMode.Back,
DepthClipEnabled = true,
FillMode = PolygonFillMode.Solid,
Expand All @@ -87,8 +91,7 @@ public ChunkRenderer(VoxelClient client) : base(client) {
}
});
}



public void Reload() {
if (renderSlots == null)
return;
Expand All @@ -114,20 +117,21 @@ public override void Render(double delta) {
}

public void SetRenderDistance(int distance) {
chunks.Resize(distance, distance);
if (renderSlots != null)
foreach (var slot in renderSlots)
slot.Dispose(); //Todo - Cache and re-use instead of dispose

renderDistance = distance;
realRenderDistance = ((renderDistance * 2) + 1);
realRenderDistance = renderDistance * 2 + 1;
var totalChunks = realRenderDistance * realRenderDistance * realRenderDistance;
renderSlots = new ChunkRenderSlot[totalChunks];

for (int x = 0; x < realRenderDistance; x++)
for (int y = 0; y < realRenderDistance; y++)
for (int z = 0; z < realRenderDistance; z++) {
var slot = new ChunkRenderSlot(Client, new ivec3(x, y, z) - distance);
slot.Move(renderPosition);
slot.Move(renderPosition, chunks);

this[x, y, z] = slot;
}
Expand All @@ -141,10 +145,16 @@ public void SetRenderPosition(dvec3 worldPosition) {

if (newPos == renderPosition || renderSlots == null)
return;

renderPosition = newPos;

chunks.Move(newPos);

foreach (var slot in renderSlots)
slot.Move(renderPosition);
slot.Move(renderPosition, chunks);

//Sort by distance so that closer chunks are rebuilt first.
Array.Sort(renderSlots, (a, b) => a.RelativePosition.LengthSqr.CompareTo(b.RelativePosition.LengthSqr));
}

public override void Dispose() {
Expand Down
2 changes: 2 additions & 0 deletions Client/VoxelClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ public override void OnTick() {
inputDir /= 4;

camera.MoveAndSlide(world!, inputDir);

GameRenderer.WorldRenderer.ChunkRenderer.SetRenderPosition(camera.position);
}

public override void OnWindowResize() {
Expand Down

0 comments on commit 4142968

Please sign in to comment.