318 lines
4.5 KiB
D
318 lines
4.5 KiB
D
import aliases;
|
|
import std.file;
|
|
import std.stdio;
|
|
import util;
|
|
import std.exception;
|
|
import alloc;
|
|
|
|
File Asset_File;
|
|
|
|
FileHeader Asset_Header;
|
|
|
|
AssetInfo[] Asset_Info;
|
|
|
|
u8[][] Asset_Data;
|
|
|
|
const u32 FILE_VERSION = 2;
|
|
const u32 MODEL_VERSION = 1;
|
|
|
|
enum AssetType : u32
|
|
{
|
|
None,
|
|
ModelM3D,
|
|
Shader,
|
|
Texture,
|
|
}
|
|
|
|
alias AT = AssetType;
|
|
|
|
struct FileHeader
|
|
{
|
|
u32 magic;
|
|
u32 file_version;
|
|
u64 asset_count;
|
|
u64 asset_info_offset;
|
|
}
|
|
|
|
struct ModelHeader
|
|
{
|
|
u32 magic;
|
|
u32 model_version;
|
|
u64 vertex_count;
|
|
u64 vertex_offset;
|
|
u64 index_count;
|
|
u64 index_offset;
|
|
u64 material_count;
|
|
u64 material_offset;
|
|
u64 texture_count;
|
|
u64 texture_offset;
|
|
}
|
|
|
|
struct Vertex
|
|
{
|
|
Vec4 color;
|
|
Vec4 tangent;
|
|
Vec3 pos;
|
|
Vec3 normal;
|
|
Vec2 uv;
|
|
}
|
|
|
|
struct ModelData
|
|
{
|
|
Vertex[] vertices;
|
|
u32[] indices;
|
|
Material[] materials;
|
|
TextureInfo[] textures;
|
|
}
|
|
|
|
struct Material
|
|
{
|
|
Vec4 ambient;
|
|
Vec4 albedo;
|
|
Vec4 specular;
|
|
u32 albedo_texture;
|
|
u32 ambient_texture;
|
|
u32 specular_texture;
|
|
u32 alpha_texture;
|
|
b32 albedo_has_texture;
|
|
b32 ambient_has_texture;
|
|
b32 specular_has_texture;
|
|
b32 alpha_has_texture;
|
|
f32 shininess = 0.0;
|
|
f32 alpha = 0.0;
|
|
}
|
|
|
|
struct TextureInfo
|
|
{
|
|
string name;
|
|
u32 id;
|
|
}
|
|
|
|
struct TextureHeader
|
|
{
|
|
u64 str_length;
|
|
u64 str_offset;
|
|
u32 texture_id;
|
|
}
|
|
|
|
struct ModelMeta
|
|
{
|
|
u64 index_count;
|
|
}
|
|
|
|
struct TexData
|
|
{
|
|
void* data;
|
|
TexMeta meta;
|
|
}
|
|
|
|
struct TexMeta
|
|
{
|
|
u32 w;
|
|
u32 h;
|
|
u32 ch;
|
|
}
|
|
|
|
struct AssetInfo
|
|
{
|
|
u64 hash;
|
|
u64 offset;
|
|
u64 length;
|
|
AssetType type;
|
|
}
|
|
|
|
bool Asset_Pack_Opened = false;
|
|
|
|
debug
|
|
{
|
|
|
|
bool g_DIR_SET = false;
|
|
|
|
void
|
|
SetDir()
|
|
{
|
|
if (exists("assets"))
|
|
{
|
|
chdir("./assets");
|
|
}
|
|
else if (exists("Gears") || exists("Gears.exe"))
|
|
{
|
|
chdir("../assets");
|
|
}
|
|
else
|
|
{
|
|
assert(false, "Unable to set directory");
|
|
}
|
|
|
|
g_DIR_SET = true;
|
|
}
|
|
|
|
u8[]
|
|
LoadAssetData(Arena* arena, string name)
|
|
{
|
|
if (!g_DIR_SET)
|
|
{
|
|
SetDir();
|
|
}
|
|
|
|
File f;
|
|
try
|
|
{
|
|
f = File(name, "rb");
|
|
}
|
|
catch (ErrnoException e)
|
|
{
|
|
assert(false, "Unable to open file");
|
|
}
|
|
|
|
u8[] mem = AllocArray!(u8)(arena, f.size());
|
|
return f.rawRead(mem);
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
|
|
void
|
|
OpenAssetPack()
|
|
{
|
|
if (!Asset_Pack_Opened)
|
|
{
|
|
bool success = true;
|
|
string file_path = exists("build/assets.sgp") ? "build/assets.sgp" : "assets.sgp";
|
|
|
|
// TODO: replace this with something that doesn't throw an exception and figure out if this is the best way to handle thing (probably isnt)
|
|
try
|
|
{
|
|
Asset_File = File(file_path, "rb");
|
|
}
|
|
catch (ErrnoException e)
|
|
{
|
|
Logf("OpenAssetPack failure: Unable to open file %s", file_path);
|
|
assert(false, "Unable to open asset pack file");
|
|
}
|
|
|
|
FileHeader[1] header_arr;
|
|
|
|
Asset_File.rawRead(header_arr);
|
|
|
|
Asset_Header = header_arr[0];
|
|
|
|
Asset_Info = AllocArray!(AssetInfo)(Asset_Header.asset_count);
|
|
Asset_Data = AllocArray!(u8[])(Asset_Header.asset_count);
|
|
|
|
assert(Asset_Header.file_version == FILE_VERSION, "OpenAssetPack failure: file version incorrect");
|
|
|
|
Asset_File.seek(Asset_Header.asset_info_offset);
|
|
|
|
Asset_File.rawRead(Asset_Info);
|
|
}
|
|
}
|
|
|
|
pragma(inline): void
|
|
CheckAssetPack()
|
|
{
|
|
if (!Asset_Pack_Opened)
|
|
{
|
|
OpenAssetPack();
|
|
}
|
|
}
|
|
|
|
AssetInfo
|
|
GetAssetInfo(string name)
|
|
{
|
|
CheckAssetPack();
|
|
|
|
u64 hash = Hash(name);
|
|
|
|
AssetInfo asset_info;
|
|
foreach(i, info; Asset_Info)
|
|
{
|
|
if (info.hash == hash)
|
|
{
|
|
asset_info = info;
|
|
break;
|
|
}
|
|
}
|
|
|
|
assert(asset_info.hash != 0, "GetAssetInfo failure: unable to find matching asset");
|
|
|
|
return asset_info;
|
|
}
|
|
|
|
u8[]
|
|
LoadAssetData(Arena* arena, string name)
|
|
{
|
|
CheckAssetPack();
|
|
|
|
u64 hash = Hash(name);
|
|
u8[] data = null;
|
|
|
|
foreach(i, info; Asset_Info)
|
|
{
|
|
if (info.hash == hash)
|
|
{
|
|
data = AllocArray!(u8)(arena, info.length);
|
|
Asset_File.seek(info.offset);
|
|
Asset_File.rawRead(data);
|
|
assert(data != null && data.length == info.length, "LoadAssetData failure: Asset data loaded incorrectly");
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
return data;
|
|
}
|
|
|
|
u8[]
|
|
LoadAssetData(string name)
|
|
{
|
|
CheckAssetPack();
|
|
|
|
u64 hash = Hash(name);
|
|
u8[] data = null;
|
|
|
|
foreach(i, info; Asset_Info)
|
|
{
|
|
if (info.hash == hash)
|
|
{
|
|
if (Asset_Data[i].ptr == null)
|
|
{
|
|
Asset_Data[i] = AllocArray!(u8)(info.length);
|
|
Asset_File.seek(info.offset);
|
|
Asset_File.rawRead(Asset_Data[i]);
|
|
assert(Asset_Data[i] != null && Asset_Data[i].length == info.length, "LoadAssetData failure: Asset data loaded incorrectly.");
|
|
}
|
|
|
|
data = Asset_Data[i];
|
|
break;
|
|
}
|
|
}
|
|
|
|
return data;
|
|
}
|
|
|
|
void
|
|
UnloadAssetData(string name)
|
|
{
|
|
u64 hash = Hash(name);
|
|
|
|
foreach(i, info; Asset_Info)
|
|
{
|
|
if (info.hash == hash)
|
|
{
|
|
if (Asset_Data[i] != null)
|
|
{
|
|
FreeArray(Asset_Data[i]);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|