allow creation of non-atlas sprites
This commit is contained in:
parent
3fd910702f
commit
262d49fee8
@ -316,7 +316,7 @@ void GC_TickAsync(WaveLaneCtx *lane, AsyncFrameLaneCtx *base_async_lane_frame)
|
|||||||
gpu_perm, cl,
|
gpu_perm, cl,
|
||||||
G_Format_R8G8B8A8_Unorm_Srgb,
|
G_Format_R8G8B8A8_Unorm_Srgb,
|
||||||
atlas->dims,
|
atlas->dims,
|
||||||
G_Layout_Simultaneous,
|
G_Layout_Simultaneous, // Simultaneous because atlas will be written asynchronously during regular reads
|
||||||
.name = Lit("Glyph atlas")
|
.name = Lit("Glyph atlas")
|
||||||
);
|
);
|
||||||
atlas->tex = G_PushTexture2DRef(gpu_perm, atlas->tex_res);
|
atlas->tex = G_PushTexture2DRef(gpu_perm, atlas->tex_res);
|
||||||
|
|||||||
@ -5,7 +5,22 @@ SPR_Ctx SPR = Zi;
|
|||||||
|
|
||||||
void SPR_Bootstrap(void)
|
void SPR_Bootstrap(void)
|
||||||
{
|
{
|
||||||
// FIXME: Initialize nil/unready sprite texture here
|
G_ArenaHandle gpu_perm = G_PermArena();
|
||||||
|
G_CommandListHandle cl = G_PrepareCommandList(G_QueueKind_Direct);
|
||||||
|
{
|
||||||
|
G_ResourceHandle unready_tex_res = G_PushTexture2D(
|
||||||
|
gpu_perm, cl,
|
||||||
|
G_Format_R8G8B8A8_Unorm,
|
||||||
|
VEC2I32(8, 8),
|
||||||
|
G_Layout_Common,
|
||||||
|
.flags = G_ResourceFlag_ZeroMemory,
|
||||||
|
.name = Lit("Sprite unready texture")
|
||||||
|
);
|
||||||
|
SPR.unready_tex = G_PushTexture2DRef(gpu_perm, unready_tex_res);
|
||||||
|
SPR.unready_tex_dims = Vec2FromVec(G_Count2D(unready_tex_res));
|
||||||
|
}
|
||||||
|
G_CommitCommandList(cl);
|
||||||
|
G_QueueSync(G_QueueMask_Direct, G_QueueMask_All);
|
||||||
|
|
||||||
OnAsyncTick(SPR_TickAsync);
|
OnAsyncTick(SPR_TickAsync);
|
||||||
}
|
}
|
||||||
@ -65,7 +80,7 @@ SPR_LayerKind SPR_LayerKindFromName(String name)
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Lookup
|
//~ Lookup
|
||||||
|
|
||||||
SPR_Sprite SPR_SpriteFromSheet(SPR_SheetKey sheet_key, SPR_SpanKey span_key, i64 frame_seq)
|
SPR_Sprite SPR_SpriteFromSheetEx(SPR_SheetKey sheet_key, SPR_SpanKey span_key, i64 frame_seq, SPR_SheetFlag flags)
|
||||||
{
|
{
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
//- Fetch sheet
|
//- Fetch sheet
|
||||||
@ -77,7 +92,7 @@ SPR_Sprite SPR_SpriteFromSheet(SPR_SheetKey sheet_key, SPR_SpanKey span_key, i64
|
|||||||
{
|
{
|
||||||
for (sheet = sheet_bin->first; sheet; sheet = sheet->next_in_bin)
|
for (sheet = sheet_bin->first; sheet; sheet = sheet->next_in_bin)
|
||||||
{
|
{
|
||||||
if (sheet->key.r.v == sheet_key.r.v)
|
if (sheet->key.r.v == sheet_key.r.v && sheet->flags == flags)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -107,6 +122,7 @@ SPR_Sprite SPR_SpriteFromSheet(SPR_SheetKey sheet_key, SPR_SpanKey span_key, i64
|
|||||||
sheet = PushStruct(perm, SPR_SheetEntry);
|
sheet = PushStruct(perm, SPR_SheetEntry);
|
||||||
SllStackPushN(sheet_bin->first, sheet, next_in_bin);
|
SllStackPushN(sheet_bin->first, sheet, next_in_bin);
|
||||||
sheet->key = sheet_key;
|
sheet->key = sheet_key;
|
||||||
|
sheet->flags = flags;
|
||||||
|
|
||||||
String sheet_data = DataFromResource(sheet->key.r);
|
String sheet_data = DataFromResource(sheet->key.r);
|
||||||
String sheet_name = NameFromResource(sheet->key.r);
|
String sheet_name = NameFromResource(sheet->key.r);
|
||||||
@ -344,6 +360,11 @@ SPR_Sprite SPR_SpriteFromSheet(SPR_SheetKey sheet_key, SPR_SpanKey span_key, i64
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SPR_Sprite SPR_SpriteFromSheet(SPR_SheetKey sheet_key, SPR_SpanKey span_key, i64 frame_seq)
|
||||||
|
{
|
||||||
|
return SPR_SpriteFromSheetEx(sheet_key, span_key, frame_seq, SPR_SheetFlag_None);
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Async
|
//~ Async
|
||||||
|
|
||||||
@ -389,10 +410,6 @@ void SPR_TickAsync(WaveLaneCtx *lane, AsyncFrameLaneCtx *base_async_lane_frame)
|
|||||||
SPR_SheetEntry *sheet = cmd->sheet;
|
SPR_SheetEntry *sheet = cmd->sheet;
|
||||||
ASE_Meta meta = sheet->meta;
|
ASE_Meta meta = sheet->meta;
|
||||||
|
|
||||||
// String encoded = DataFromResource(sheet->key.r);
|
|
||||||
// String name = NameFromResource(sheet->key.r);
|
|
||||||
// LogInfoF("Rasterizing sprite sheet %F \"%F\" (%F bytes)", FmtHandle(sheet->key.r), FmtString(name), FmtUint(encoded.len));
|
|
||||||
|
|
||||||
SPR_SliceEntry *slice = &sheet->slices[cmd->slice_idx];
|
SPR_SliceEntry *slice = &sheet->slices[cmd->slice_idx];
|
||||||
Vec2 slice_dims = DimsFromRng2(slice->canvas_rect);
|
Vec2 slice_dims = DimsFromRng2(slice->canvas_rect);
|
||||||
|
|
||||||
@ -421,49 +438,69 @@ void SPR_TickAsync(WaveLaneCtx *lane, AsyncFrameLaneCtx *base_async_lane_frame)
|
|||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
//- Write atlas
|
//- Write atlas
|
||||||
|
|
||||||
// TODO: Use a more efficient atlas packing algorithm for less wasted space
|
|
||||||
SPR_Atlas *atlas = SPR.first_atlas;
|
|
||||||
b32 can_use_atlas = 0;
|
|
||||||
Vec2I32 atlas_pos = Zi;
|
Vec2I32 atlas_pos = Zi;
|
||||||
while (can_use_atlas == 0)
|
SPR_Atlas *atlas = 0;
|
||||||
|
if (AnyBit(sheet->flags, SPR_SheetFlag_NoAtlas) && slice_dims.x > 0 && slice_dims.y > 0)
|
||||||
{
|
{
|
||||||
// Create atlas
|
atlas = PushStruct(perm, SPR_Atlas);
|
||||||
if (!atlas)
|
atlas->dims = Vec2I32FromVec(slice_dims);
|
||||||
{
|
{
|
||||||
atlas = PushStruct(perm, SPR_Atlas);
|
G_ArenaHandle gpu_perm = G_PermArena();
|
||||||
i32 atlas_size = MaxI32(1024, NextPow2U64(MaxI32(slice_dims.x, slice_dims.y)));
|
atlas->tex_res = G_PushTexture2D(
|
||||||
atlas->dims = VEC2I32(atlas_size, atlas_size);
|
gpu_perm, cl,
|
||||||
|
G_Format_R8G8B8A8_Unorm_Srgb,
|
||||||
|
atlas->dims,
|
||||||
|
G_Layout_Common,
|
||||||
|
.name = Lit("Isolated sprite texture")
|
||||||
|
);
|
||||||
|
atlas->tex = G_PushTexture2DRef(gpu_perm, atlas->tex_res);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// TODO: Use a more efficient atlas packing algorithm for less wasted space
|
||||||
|
atlas = SPR.first_atlas;
|
||||||
|
b32 can_use_atlas = 0;
|
||||||
|
while (can_use_atlas == 0)
|
||||||
|
{
|
||||||
|
// Create atlas
|
||||||
|
if (!atlas)
|
||||||
{
|
{
|
||||||
G_ArenaHandle gpu_perm = G_PermArena();
|
atlas = PushStruct(perm, SPR_Atlas);
|
||||||
atlas->tex_res = G_PushTexture2D(
|
i32 atlas_size = MaxI32(1024, NextPow2U64(MaxI32(slice_dims.x, slice_dims.y)));
|
||||||
gpu_perm, cl,
|
atlas->dims = VEC2I32(atlas_size, atlas_size);
|
||||||
G_Format_R8G8B8A8_Unorm_Srgb,
|
{
|
||||||
atlas->dims,
|
G_ArenaHandle gpu_perm = G_PermArena();
|
||||||
G_Layout_Simultaneous,
|
atlas->tex_res = G_PushTexture2D(
|
||||||
.name = Lit("Sprite atlas")
|
gpu_perm, cl,
|
||||||
);
|
G_Format_R8G8B8A8_Unorm_Srgb,
|
||||||
atlas->tex = G_PushTexture2DRef(gpu_perm, atlas->tex_res);
|
atlas->dims,
|
||||||
|
G_Layout_Simultaneous, // Simultaneous because atlas will be written asynchronously during regular reads
|
||||||
|
.name = StringF(perm, "Sprite atlas #%F", FmtSint(SPR.atlases_count))
|
||||||
|
);
|
||||||
|
atlas->tex = G_PushTexture2DRef(gpu_perm, atlas->tex_res);
|
||||||
|
}
|
||||||
|
SllStackPush(SPR.first_atlas, atlas);
|
||||||
|
++SPR.atlases_count;
|
||||||
|
}
|
||||||
|
if (atlas->cur_pos.x + slice_dims.x > atlas->dims.x)
|
||||||
|
{
|
||||||
|
atlas->cur_pos.x = 0;
|
||||||
|
atlas->cur_pos.y += atlas->cur_row_height;
|
||||||
|
atlas->cur_row_height = 0;
|
||||||
|
}
|
||||||
|
if (atlas->cur_pos.x + slice_dims.x <= atlas->dims.x && atlas->cur_pos.y + slice_dims.y <= atlas->dims.y)
|
||||||
|
{
|
||||||
|
atlas_pos = atlas->cur_pos;
|
||||||
|
atlas->cur_row_height = MaxI32(atlas->cur_row_height, slice_dims.y);
|
||||||
|
atlas->cur_pos.x += slice_dims.x;
|
||||||
|
can_use_atlas = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// New atlas required
|
||||||
|
atlas = 0;
|
||||||
}
|
}
|
||||||
SllStackPush(SPR.first_atlas, atlas);
|
|
||||||
++SPR.atlases_count;
|
|
||||||
}
|
|
||||||
if (atlas->cur_pos.x + slice_dims.x > atlas->dims.x)
|
|
||||||
{
|
|
||||||
atlas->cur_pos.x = 0;
|
|
||||||
atlas->cur_pos.y += atlas->cur_row_height;
|
|
||||||
atlas->cur_row_height = 0;
|
|
||||||
}
|
|
||||||
if (atlas->cur_pos.x + slice_dims.x <= atlas->dims.x && atlas->cur_pos.y + slice_dims.y <= atlas->dims.y)
|
|
||||||
{
|
|
||||||
atlas_pos = atlas->cur_pos;
|
|
||||||
atlas->cur_row_height = MaxI32(atlas->cur_row_height, slice_dims.y);
|
|
||||||
atlas->cur_pos.x += slice_dims.x;
|
|
||||||
can_use_atlas = 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// New atlas required
|
|
||||||
atlas = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -13,7 +13,6 @@ Struct(SPR_SpanKey) { u64 v; };
|
|||||||
Struct(SPR_Atlas)
|
Struct(SPR_Atlas)
|
||||||
{
|
{
|
||||||
SPR_Atlas *next;
|
SPR_Atlas *next;
|
||||||
|
|
||||||
Vec2I32 dims;
|
Vec2I32 dims;
|
||||||
G_ResourceHandle tex_res;
|
G_ResourceHandle tex_res;
|
||||||
G_Texture2DRef tex;
|
G_Texture2DRef tex;
|
||||||
@ -47,7 +46,13 @@ Enum(SPR_LayerKind)
|
|||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Lookup result types
|
//~ Lookup types
|
||||||
|
|
||||||
|
Enum(SPR_SheetFlag)
|
||||||
|
{
|
||||||
|
SPR_SheetFlag_None = 0,
|
||||||
|
SPR_SheetFlag_NoAtlas = (1 << 0),
|
||||||
|
};
|
||||||
|
|
||||||
Struct(SPR_Ray)
|
Struct(SPR_Ray)
|
||||||
{
|
{
|
||||||
@ -107,6 +112,7 @@ Struct(SPR_SheetEntry)
|
|||||||
{
|
{
|
||||||
SPR_SheetEntry *next_in_bin;
|
SPR_SheetEntry *next_in_bin;
|
||||||
SPR_SheetKey key;
|
SPR_SheetKey key;
|
||||||
|
SPR_SheetFlag flags;
|
||||||
|
|
||||||
i64 slices_count;
|
i64 slices_count;
|
||||||
SPR_SliceEntry *slices;
|
SPR_SliceEntry *slices;
|
||||||
@ -153,7 +159,6 @@ Struct(SPR_Ctx)
|
|||||||
{
|
{
|
||||||
SPR_SheetBin sheet_bins[Kibi(16)];
|
SPR_SheetBin sheet_bins[Kibi(16)];
|
||||||
|
|
||||||
// FIXME: Initialize this
|
|
||||||
G_Texture2DRef unready_tex;
|
G_Texture2DRef unready_tex;
|
||||||
Vec2 unready_tex_dims;
|
Vec2 unready_tex_dims;
|
||||||
|
|
||||||
@ -194,6 +199,7 @@ SPR_LayerKind SPR_LayerKindFromName(String name);
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Lookup
|
//~ Lookup
|
||||||
|
|
||||||
|
SPR_Sprite SPR_SpriteFromSheetEx(SPR_SheetKey sheet_key, SPR_SpanKey span_key, i64 frame_seq, SPR_SheetFlag flags);
|
||||||
SPR_Sprite SPR_SpriteFromSheet(SPR_SheetKey sheet_key, SPR_SpanKey span_key, i64 frame_seq);
|
SPR_Sprite SPR_SpriteFromSheet(SPR_SheetKey sheet_key, SPR_SpanKey span_key, i64 frame_seq);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user