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,
|
||||
G_Format_R8G8B8A8_Unorm_Srgb,
|
||||
atlas->dims,
|
||||
G_Layout_Simultaneous,
|
||||
G_Layout_Simultaneous, // Simultaneous because atlas will be written asynchronously during regular reads
|
||||
.name = Lit("Glyph atlas")
|
||||
);
|
||||
atlas->tex = G_PushTexture2DRef(gpu_perm, atlas->tex_res);
|
||||
|
||||
@ -5,7 +5,22 @@ SPR_Ctx SPR = Zi;
|
||||
|
||||
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);
|
||||
}
|
||||
@ -65,7 +80,7 @@ SPR_LayerKind SPR_LayerKindFromName(String name)
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ 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
|
||||
@ -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)
|
||||
{
|
||||
if (sheet->key.r.v == sheet_key.r.v)
|
||||
if (sheet->key.r.v == sheet_key.r.v && sheet->flags == flags)
|
||||
{
|
||||
break;
|
||||
}
|
||||
@ -107,6 +122,7 @@ SPR_Sprite SPR_SpriteFromSheet(SPR_SheetKey sheet_key, SPR_SpanKey span_key, i64
|
||||
sheet = PushStruct(perm, SPR_SheetEntry);
|
||||
SllStackPushN(sheet_bin->first, sheet, next_in_bin);
|
||||
sheet->key = sheet_key;
|
||||
sheet->flags = flags;
|
||||
|
||||
String sheet_data = DataFromResource(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;
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
@ -389,10 +410,6 @@ void SPR_TickAsync(WaveLaneCtx *lane, AsyncFrameLaneCtx *base_async_lane_frame)
|
||||
SPR_SheetEntry *sheet = cmd->sheet;
|
||||
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];
|
||||
Vec2 slice_dims = DimsFromRng2(slice->canvas_rect);
|
||||
|
||||
@ -421,49 +438,69 @@ void SPR_TickAsync(WaveLaneCtx *lane, AsyncFrameLaneCtx *base_async_lane_frame)
|
||||
//////////////////////////////
|
||||
//- 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;
|
||||
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
|
||||
if (!atlas)
|
||||
atlas = PushStruct(perm, SPR_Atlas);
|
||||
atlas->dims = Vec2I32FromVec(slice_dims);
|
||||
{
|
||||
atlas = PushStruct(perm, SPR_Atlas);
|
||||
i32 atlas_size = MaxI32(1024, NextPow2U64(MaxI32(slice_dims.x, slice_dims.y)));
|
||||
atlas->dims = VEC2I32(atlas_size, atlas_size);
|
||||
G_ArenaHandle gpu_perm = G_PermArena();
|
||||
atlas->tex_res = G_PushTexture2D(
|
||||
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->tex_res = G_PushTexture2D(
|
||||
gpu_perm, cl,
|
||||
G_Format_R8G8B8A8_Unorm_Srgb,
|
||||
atlas->dims,
|
||||
G_Layout_Simultaneous,
|
||||
.name = Lit("Sprite atlas")
|
||||
);
|
||||
atlas->tex = G_PushTexture2DRef(gpu_perm, atlas->tex_res);
|
||||
atlas = PushStruct(perm, SPR_Atlas);
|
||||
i32 atlas_size = MaxI32(1024, NextPow2U64(MaxI32(slice_dims.x, slice_dims.y)));
|
||||
atlas->dims = VEC2I32(atlas_size, atlas_size);
|
||||
{
|
||||
G_ArenaHandle gpu_perm = G_PermArena();
|
||||
atlas->tex_res = G_PushTexture2D(
|
||||
gpu_perm, cl,
|
||||
G_Format_R8G8B8A8_Unorm_Srgb,
|
||||
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)
|
||||
{
|
||||
SPR_Atlas *next;
|
||||
|
||||
Vec2I32 dims;
|
||||
G_ResourceHandle tex_res;
|
||||
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)
|
||||
{
|
||||
@ -107,6 +112,7 @@ Struct(SPR_SheetEntry)
|
||||
{
|
||||
SPR_SheetEntry *next_in_bin;
|
||||
SPR_SheetKey key;
|
||||
SPR_SheetFlag flags;
|
||||
|
||||
i64 slices_count;
|
||||
SPR_SliceEntry *slices;
|
||||
@ -153,7 +159,6 @@ Struct(SPR_Ctx)
|
||||
{
|
||||
SPR_SheetBin sheet_bins[Kibi(16)];
|
||||
|
||||
// FIXME: Initialize this
|
||||
G_Texture2DRef unready_tex;
|
||||
Vec2 unready_tex_dims;
|
||||
|
||||
@ -194,6 +199,7 @@ SPR_LayerKind SPR_LayerKindFromName(String name);
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ 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);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
Loading…
Reference in New Issue
Block a user