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

Commit

Permalink
Crude model loading
Browse files Browse the repository at this point in the history
  • Loading branch information
Oliver-makes-code committed Oct 12, 2023
1 parent df5c4ff commit f4a0559
Show file tree
Hide file tree
Showing 9 changed files with 61 additions and 46 deletions.
3 changes: 3 additions & 0 deletions Client/Content/models/block/dirt.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"texture": "main/dirt"
}
3 changes: 3 additions & 0 deletions Client/Content/models/block/grass.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"texture": "main/grass"
}
3 changes: 3 additions & 0 deletions Client/Content/models/block/stone.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"texture": "main/stone"
}
34 changes: 26 additions & 8 deletions Client/Rendering/Models/BlockModelManager.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,24 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using GlmSharp;
using Newtonsoft.Json;
using RenderSurface.Assets;
using Voxel.Client.Rendering.Texture;
using Voxel.Common.Tile;

namespace Voxel.Client.Rendering.Models;

public static class BlockModelManager {
private const string Suffix = ".json";

private static readonly string Prefix = Path.Combine("models", "block");

private static readonly Dictionary<Block, BlockModel> Models = new();

private static readonly JsonSerializer Serializer = new();

public static void RegisterModel(Block block, BlockModel model) => Models[block] = model;
public static bool TryGetModel(Block block, [NotNullWhen(true)] out BlockModel? model) => Models.TryGetValue(block, out model);

Expand Down Expand Up @@ -53,13 +62,22 @@ public static BlockModel GetDefault(Atlas.Sprite sprite) {
.Build();
}

public static void Init(Atlas atlas) {
Atlas.Sprite? sprite;
if (atlas.TryGetSprite("main/stone", out sprite))
RegisterModel(Blocks.Stone, GetDefault(sprite));
if (atlas.TryGetSprite("main/dirt", out sprite))
RegisterModel(Blocks.Dirt, GetDefault(sprite));
if (atlas.TryGetSprite("main/grass", out sprite))
RegisterModel(Blocks.Grass, GetDefault(sprite));
public static void Init(AssetReader reader, Atlas atlas) {
foreach ((string name, var stream, _) in reader.LoadAll(Prefix, Suffix)) {
using var sr = new StreamReader(stream);
using var jsonTextReader = new JsonTextReader(sr);

string texture = Serializer.Deserialize<ModelJson>(jsonTextReader)?.Texture ?? "";
int start = Prefix.Length + 1;
int end = name.Length - Suffix.Length;
string blockName = name[start..end];

if (Blocks.GetBlock(blockName, out var block) && atlas.TryGetSprite(texture, out var sprite))
RegisterModel(block, GetDefault(sprite));
}
}

private class ModelJson {
public string Texture { get; set; }
}
}
7 changes: 2 additions & 5 deletions Client/Rendering/Texture/AtlasLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,10 @@ namespace Voxel.Client.Rendering.Texture;

public class AtlasLoader {

private static JsonSerializer Serializer = new();
private static readonly JsonSerializer Serializer = new();

public static void LoadAtlas(AssetReader reader, Atlas target, RenderSystem renderSystem) {
bool FilenameMatches(string s)
=> s.StartsWith(Path.Combine("textures", "atlases", target.Name.ToLower())) && s.EndsWith(".json");

foreach ((string path, var stream, int length) in reader.LoadAll(FilenameMatches)) {
foreach (var (_, stream, _) in reader.LoadAll(Path.Combine("textures", "atlases", target.Name.ToLower()), ".json")) {
using var sr = new StreamReader(stream);
using var jsonTextReader = new JsonTextReader(sr);

Expand Down
4 changes: 2 additions & 2 deletions Client/Rendering/World/ChunkRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@ private ChunkRenderSlot? this[ivec3 pos] {
public ChunkRenderer(VoxelClient client) : base(client) {
SetRenderDistance(2);

TerrainAtlas = new Atlas("main", client.RenderSystem);
TerrainAtlas = new("main", client.RenderSystem);
AtlasLoader.LoadAtlas(RenderSystem.Game.AssetReader, TerrainAtlas, RenderSystem);
BlockModelManager.Init(TerrainAtlas);
BlockModelManager.Init(RenderSystem.Game.AssetReader, TerrainAtlas);

//Chunk resources are just the model matrix (for now)
ChunkResourceLayout = ResourceFactory.CreateResourceLayout(new ResourceLayoutDescription(
Expand Down
12 changes: 5 additions & 7 deletions Core/Assets/AssetReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,18 @@ public bool TryGetStream(string path, [NotNullWhen(true)] out Stream? assetStrea
return true;
}

public IEnumerable<(string path, Stream stream, int length)> LoadAll(ConditionDelegate condition) {
public IEnumerable<(string, Stream, int)> LoadAll(string prefix, string suffix) {
foreach (var entry in File.Entries) {
if (!condition(entry.FullName))
if (!(entry.FullName.StartsWith(prefix) && entry.FullName.EndsWith(suffix)))
continue;

using var str = entry.Open();
yield return (entry.FullName, str, (int)entry.Length);
}
}

public void LoadAll(ConditionDelegate condition, LoadDelegate loader) {
foreach ((string path, var stream, int length) in LoadAll(condition))
loader(path, stream, length);
}

public IEnumerable<(string, Stream, int)> LoadAll(string suffix)
=> LoadAll("", suffix);

public void Dispose() {
File.Dispose();
Expand Down
24 changes: 10 additions & 14 deletions Core/Rendering/ShaderManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,24 +19,20 @@ public class ShaderManager {
public ShaderManager(RenderSystem renderSystem, AssetReader assetReader) {
RenderSystem = renderSystem;

assetReader.LoadAll(s => s.EndsWith(".glsl"), LoadShaderSource);
foreach ((string path, Stream sourceStream, int length) in assetReader.LoadAll("", ".glsl")) {
Span<byte> tmp = stackalloc byte[length];
if (sourceStream.Read(tmp) != length)
return;

foreach (string uniqueShader in UniqueShaders)
LoadActualShader(uniqueShader);
}

private void LoadShaderSource(string path, Stream sourceStream, int length) {

Span<byte> tmp = stackalloc byte[length];
if (sourceStream.Read(tmp) != length)
return;
string src = Encoding.UTF8.GetString(tmp);
ShaderSources[path] = src;

var src = Encoding.UTF8.GetString(tmp);
ShaderSources[path] = src;
UniqueShaders.Add(path.Replace(".vert.glsl", string.Empty).Replace(".frag.glsl", string.Empty));
}

UniqueShaders.Add(path.Replace(".vert.glsl", string.Empty).Replace(".frag.glsl", string.Empty));
foreach (string uniqueShader in UniqueShaders)
LoadActualShader(uniqueShader);
}

private void LoadActualShader(string uniqueShaderName) {
if (!ShaderSources.TryGetValue($"{uniqueShaderName}.frag.glsl", out var fragSrc) || !ShaderSources.TryGetValue($"{uniqueShaderName}.vert.glsl", out var vertSrc))
return;
Expand Down
17 changes: 7 additions & 10 deletions Core/Rendering/TextureManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,16 @@ public TextureManager(RenderSystem renderSystem, AssetReader assetReader) {
new ResourceLayoutElementDescription("Texture", ResourceKind.TextureReadOnly, ShaderStages.Fragment | ShaderStages.Vertex)
));

assetReader.LoadAll(s => s.EndsWith(".png"), LoadTexture);
}

foreach ((string path, Stream textureStream, _) in assetReader.LoadAll(".png")) {
var loadedTexture = new ImageSharpTexture(textureStream, true);

private void LoadTexture(string path, Stream textureStream, int length) {
var loadedTexture = new ImageSharpTexture(textureStream, true);
var deviceTexture = loadedTexture.CreateDeviceTexture(RenderSystem.GraphicsDevice, RenderSystem.ResourceFactory);

var deviceTexture = loadedTexture.CreateDeviceTexture(RenderSystem.GraphicsDevice, RenderSystem.ResourceFactory);
var textureSet = CreateTextureResourceSet(deviceTexture);

var textureSet = CreateTextureResourceSet(deviceTexture);

LoadedTextures[path] = deviceTexture;
TextureSets[path] = textureSet;
LoadedTextures[path] = deviceTexture;
TextureSets[path] = textureSet;
}
}

public bool TryGetTexture(string path, [NotNullWhen(true)] out Texture? texture) => LoadedTextures.TryGetValue(path, out texture);
Expand Down

0 comments on commit f4a0559

Please sign in to comment.