239 lines
6.1 KiB
C
239 lines
6.1 KiB
C
// ::Assets::Constants::Start::
|
|
|
|
const u32 M3D_FILE = CreateMagicValue('3', 'D', 'M', 'O');
|
|
const u32 M3D_PREVIEW = CreateMagicValue('P', 'R', 'V', 'W');
|
|
const u32 M3D_HEAD = CreateMagicValue('H', 'E', 'A', 'D');
|
|
const u32 M3D_END_CHUNK = CreateMagicValue('O', 'M', 'D', '3');
|
|
const u32 M3D_ASSET = CreateMagicValue('A', 'S', 'E', 'T');
|
|
const u32 M3D_ACTION = CreateMagicValue('A', 'C', 'T', 'N');
|
|
const u32 M3D_COL_MAP = CreateMagicValue('C', 'M', 'A', 'P');
|
|
const u32 M3D_TEX_MAP = CreateMagicValue('T', 'M', 'A', 'P');
|
|
const u32 M3D_VERT = CreateMagicValue('V', 'R', 'T', 'S');
|
|
const u32 M3D_BONE = CreateMagicValue('B', 'O', 'N', 'E');
|
|
const u32 M3D_MAT = CreateMagicValue('M', 'T', 'R', 'L');
|
|
const u32 M3D_PROCEDURAL = CreateMagicValue('P', 'R', 'O', 'C');
|
|
const u32 M3D_MESH = CreateMagicValue('M', 'E', 'S', 'H');
|
|
const u32 M3D_VOXEL_TYPE = CreateMagicValue('V', 'O', 'X', 'T');
|
|
const u32 M3D_VOXEL_DATA = CreateMagicValue('V', 'O', 'X', 'D');
|
|
const u32 M3D_SHAPE = CreateMagicValue('S', 'H', 'P', 'E');
|
|
const u32 M3D_LABEL = CreateMagicValue('L', 'B', 'L', 'S');
|
|
|
|
|
|
// ::Assets::Constants::Start::
|
|
|
|
|
|
|
|
// ::Assets::Globals::Start::
|
|
|
|
u8 ASSET_PACK[] =
|
|
{
|
|
#embed "../assets.sgp"
|
|
};
|
|
|
|
static FileHeader File_Header = {0};
|
|
|
|
static AssetFile Texture_Assets[TEXTURE_ASSET_MAX];
|
|
static Asset Texture_Asset_Lookup[TEXTURE_ASSET_MAX];
|
|
|
|
static AssetFile Shader_Assets[SHADER_ASSET_MAX];
|
|
static Asset Shader_Asset_Lookup[SHADER_ASSET_MAX];
|
|
|
|
static AssetFile Model_Assets[MODEL_ASSET_MAX];
|
|
static Asset Model_Asset_Lookup[MODEL_ASSET_MAX];
|
|
|
|
// TODO(MA): Implement async asset handling
|
|
static u32 Shader_Asset_Ref_Count[SHADER_ASSET_MAX];
|
|
static u32 Texture_Asset_Ref_Count[TEXTURE_ASSET_MAX];
|
|
static u32 Model_Asset_Ref_Count[MODEL_ASSET_MAX];
|
|
|
|
static b32 ASSET_HEADER_LOADED = false;
|
|
|
|
|
|
// ::Assets::Global::End::
|
|
|
|
|
|
|
|
// ::Assets::Init::Functions::Start::
|
|
|
|
static void apInit()
|
|
{
|
|
MemCpy(&File_Header, ASSET_PACK, sizeof(FileHeader));
|
|
|
|
Assert(File_Header.magic_num == CreateMagicValue('s', 't', 'e', 'g'), "Magic value is incorrect");
|
|
|
|
MemCpy(Texture_Assets, &ASSET_PACK[File_Header.asset_offsets[TEXTURE_ASSET]], sizeof(AssetFile) * File_Header.asset_counts[TEXTURE_ASSET]);
|
|
|
|
MemCpy(Shader_Assets, &ASSET_PACK[File_Header.asset_offsets[SHADER_ASSET]], sizeof(AssetFile) * File_Header.asset_counts[SHADER_ASSET]);
|
|
|
|
MemCpy(Model_Assets, &ASSET_PACK[File_Header.asset_offsets[MODEL_ASSET]], sizeof(AssetFile) * File_Header.asset_counts[MODEL_ASSET]);
|
|
|
|
ASSET_HEADER_LOADED = true;
|
|
}
|
|
|
|
// ::Assets::Init::Functions::End::
|
|
|
|
|
|
|
|
// ::Assets::Loading::Functions::Start::
|
|
|
|
static Asset apLoadTexture(TextureAsset asset_id)
|
|
{
|
|
if (!ASSET_HEADER_LOADED)
|
|
{
|
|
apInit();
|
|
}
|
|
|
|
Assert(asset_id < i32(TEXTURE_ASSET_MAX), "LoadTextureAsset failure: asset_id is higher than TEXTURE_ASSET_MAX");
|
|
|
|
Asset asset = Texture_Asset_Lookup[asset_id];
|
|
|
|
if (asset.bytes == NULL)
|
|
{
|
|
AssetFile *asset_info = Texture_Assets + asset_id;
|
|
u8 *img = FLMemAlloc(asset_info->len);
|
|
MemCpy(img, &ASSET_PACK[asset_info->data_offset], asset_info->len);
|
|
|
|
asset.bytes = img;
|
|
asset.len = asset_info->len;
|
|
|
|
Texture_Asset_Lookup[asset_id] = asset;
|
|
}
|
|
|
|
return asset;
|
|
}
|
|
|
|
static Asset apLoadShader(ShaderAsset asset_id)
|
|
{
|
|
if (!ASSET_HEADER_LOADED)
|
|
{
|
|
apInit();
|
|
}
|
|
|
|
Assert(asset_id < SHADER_ASSET_MAX, "LoadShaderAsset failure: asset_id is higher than SHADER_ASSET_MAX");
|
|
|
|
Asset asset = Shader_Asset_Lookup[asset_id];
|
|
if (asset.bytes == NULL)
|
|
{
|
|
AssetFile *asset_info = Shader_Assets + asset_id;
|
|
|
|
asset.bytes = FLMemAlloc(asset_info->len);
|
|
MemCpy(asset.bytes, &ASSET_PACK[asset_info->data_offset], asset_info->len);
|
|
asset.len = asset_info->len;
|
|
Shader_Asset_Lookup[asset_id] = asset;
|
|
}
|
|
|
|
return asset;
|
|
}
|
|
|
|
static Asset apLoadModel(ModelAsset asset_id)
|
|
{
|
|
if (!ASSET_HEADER_LOADED)
|
|
{
|
|
apInit();
|
|
}
|
|
|
|
Assert(asset_id < MODEL_ASSET_MAX, "apLoadModel failure: asset_id is higher than MODEL_ASSET_MAX");
|
|
|
|
Asset asset = Model_Asset_Lookup[asset_id];
|
|
if (asset.bytes == NULL)
|
|
{
|
|
AssetFile *asset_info = Model_Assets + asset_id;
|
|
|
|
asset.bytes = FLMemAlloc(asset_info->len);
|
|
MemCpy(asset.bytes, &ASSET_PACK[asset_info->data_offset], asset_info->len);
|
|
asset.len = asset_info->len;
|
|
Model_Asset_Lookup[asset_id] = asset;
|
|
}
|
|
|
|
return asset;
|
|
}
|
|
|
|
static TextureAssetMeta apGetTextureMeta(TextureAsset asset_id)
|
|
{
|
|
AssetFile *asset_file = Texture_Assets + asset_id;
|
|
return asset_file->texture_meta;
|
|
}
|
|
|
|
static void apUnloadTexture(TextureAsset asset_id)
|
|
{
|
|
Asset *asset = Texture_Asset_Lookup + asset_id;
|
|
if (asset->bytes != NULL)
|
|
{
|
|
FLMemFree(asset->bytes);
|
|
asset->bytes = NULL;
|
|
asset->len = 0;
|
|
}
|
|
}
|
|
|
|
static void apUnloadShader(ShaderAsset asset_id)
|
|
{
|
|
Asset *asset = Shader_Asset_Lookup + asset_id;
|
|
if (asset->bytes != NULL)
|
|
{
|
|
FLMemFree(asset->bytes);
|
|
asset->bytes = NULL;
|
|
asset->len = 0;
|
|
}
|
|
}
|
|
|
|
static void apUnloadModel(ModelAsset asset_id)
|
|
{
|
|
Asset *asset = Model_Asset_Lookup + asset_id;
|
|
if (asset->bytes != NULL)
|
|
{
|
|
FLMemFree(asset->bytes);
|
|
asset->bytes = NULL;
|
|
asset->len = 0;
|
|
}
|
|
}
|
|
|
|
// ::Assets::Loading::Functions::End::
|
|
|
|
|
|
|
|
// ::Assets::Models::Functions::Start::
|
|
|
|
static inline b32 apChkMag(u32 *magic, u32 expected)
|
|
{
|
|
return *magic == expected;
|
|
}
|
|
|
|
// TODO: parse this without the SDK
|
|
static m3dModel *apParseModel(rawptr data)
|
|
{
|
|
m3d_t *m3d = m3d_load(data, NULL, NULL, NULL);
|
|
|
|
m3dModel *model = FLMemAlloc(sizeof(m3dModel));
|
|
model->v_count = u64(m3d->numvertex);
|
|
model->vertices = FLMemAlloc(sizeof(Vertex) * model->v_count);
|
|
|
|
for (u64 i = 0; i < m3d->numvertex; i += 1)
|
|
{
|
|
model->vertices[i].pos.x = m3d->vertex[i].x;
|
|
model->vertices[i].pos.y = m3d->vertex[i].y;
|
|
model->vertices[i].pos.z = m3d->vertex[i].z;
|
|
model->vertices[i].pos.w = m3d->vertex[i].w;
|
|
|
|
model->vertices[i].col.r = 0.0f;
|
|
model->vertices[i].col.g = 1.0f;
|
|
model->vertices[i].col.b = 0.0f;
|
|
model->vertices[i].col.a = 0.0f;
|
|
}
|
|
|
|
model->i_count = u64(m3d->numface * 3);
|
|
model->indices = FLMemAlloc(sizeof(u32) * model->i_count);
|
|
|
|
for (u64 i = 0; i < m3d->numface; i += 1)
|
|
{
|
|
model->indices[i] = m3d->face[i].vertex[0];
|
|
model->indices[i+1] = m3d->face[i].vertex[1];
|
|
model->indices[i+2] = m3d->face[i].vertex[2];
|
|
}
|
|
|
|
m3d_free(m3d);
|
|
|
|
return model;
|
|
}
|
|
|
|
// ::Assets::Models::Functions::End::
|