animation testing

This commit is contained in:
jacob 2026-01-23 17:29:04 -06:00
parent 7ee7a7f531
commit d5efdab6d9
16 changed files with 423 additions and 189 deletions

View File

@ -204,27 +204,166 @@ P_Anim P_AnimFromEnt(P_Ent *ent, i64 time_ns)
{
P_Anim result = Zi;
// result.slice_to_world_xf = XformIdentity;
// result.slice_to_world_xf = ent->xf;
i64 animation_rate_ns = NsFromSeconds(0.100);
// TODO: Determine animation dynamically
{
Vec2 world_dims = VEC2(0.5, 0.5);
result.slice_to_world_xf = XformIdentity;
result.slice_to_world_xf.og = ent->xf.og;
// result.slice_to_world_xf.og = SubVec2(result.slice_to_world_xf.og, MulVec2(world_dims, 0.25));
result.slice_to_world_xf = XformWithWorldRotation(result.slice_to_world_xf, AngleFromVec2(ent->control.look));
result.slice_to_world_xf = TranslateXform(result.slice_to_world_xf, MulVec2(world_dims, -0.5));
result.slice_to_world_xf = ScaleXform(result.slice_to_world_xf, world_dims);
ResourceKey sheet_resource = ResourceKeyFromStore(&P_Resources, Lit("sprite/bla3.ase"));
SPR_SheetKey sheet = SPR_SheetKeyFromResource(sheet_resource);
result.slice = SPR_SliceFromSheet(sheet, Lit(""));
i64 walk_duration_ns = time_ns;
result.frame_seq = walk_duration_ns / animation_rate_ns;
result.span = SPR_SpanKeyFromName(Lit("walk"));
}
result.sheet = SPR_SheetKeyFromResource(ResourceKeyFromStore(&P_Resources, Lit("sprite/bla3.ase")));
result.wep_sheet = SPR_SheetKeyFromResource(ResourceKeyFromStore(&P_Resources, Lit("sprite/raah.ase")));
return result;
// P_Anim result = Zi;
// // result.slice_to_world_xf = XformIdentity;
// // result.slice_to_world_xf = ent->xf;
// i64 animation_rate_ns = NsFromSeconds(0.100);
// SPR_SpanKey span_key = Zi;
// {
// // TODO: Determine span dynamically
// span_key = SPR_SpanKeyFromName(Lit("walk"));
// }
// SPR_SheetKey body_sheet_key = SPR_SheetKeyFromResource(ResourceKeyFromStore(&P_Resources, Lit("sprite/bla3.ase")));
// SPR_SheetKey weapon_sheet_key = SPR_SheetKeyFromResource(ResourceKeyFromStore(&P_Resources, Lit("sprite/raahase")));
// //- Body
// {
// // TODO: Real walk animation
// i64 walk_duration_ns = time_ns;
// i64 frame_seq = walk_duration_ns / animation_rate_ns;
// SPR_Frame sframe = SPR_FrameFromSheet(body_sheet_key, span_key, frame_seq);
// // FIXME: Use origin ray
// {
// Vec2 world_dims = DivVec2(sframe.dims, P_CellsPerMeter);
// result.body_to_world_xf = XformIdentity;
// result.body_to_world_xf.og = ent->xf.og;
// // result.body_to_world_xf.og = SubVec2(result.body_to_world_xf.og, MulVec2(world_dims, 0.25));
// result.body_to_world_xf = XformWithWorldRotation(result.body_to_world_xf, AngleFromVec2(ent->control.look));
// result.body_to_world_xf = TranslateXform(result.body_to_world_xf, MulVec2(world_dims, -0.5));
// result.body_to_world_xf = ScaleXform(result.body_to_world_xf, world_dims);
// }
// {
// result.
// }
// result.body_slice = sframe.slice;
// {
// // result.
// }
// // SPR_Ray origin_ray = SPR_RayFromFrame(body_sheet_key, origin_layer_key, frame_idx);
// // SPR_Ray ap_ray = SPR_RayFromFrame(body_sheet_key, ap_layer_key, frame_idx);
// // {
// // // Vec2 world_dims = VEC2(0.5, 0.5);
// // Vec2 px_dims = slice.dims;
// // Vec2 world_dims = DivVec2(px_dims, P_CellsPerMeter);
// // result.slice_to_world_xf = XformIdentity;
// // result.slice_to_world_xf.og = ent->xf.og;
// // // result.slice_to_world_xf.og = SubVec2(result.slice_to_world_xf.og, MulVec2(world_dims, 0.25));
// // result.slice_to_world_xf = XformWithWorldRotation(result.slice_to_world_xf, AngleFromVec2(ent->control.look));
// // result.slice_to_world_xf = TranslateXform(result.slice_to_world_xf, MulVec2(world_dims, -0.5));
// // result.slice_to_world_xf = ScaleXform(result.slice_to_world_xf, world_dims);
// // }
// // result.slice = SPR_SliceFromSheet(sheet,
// }
// //- Weapon
// {
// }
// return result;
// P_Anim result = Zi;
// // result.slice_to_world_xf = XformIdentity;
// // result.slice_to_world_xf = ent->xf;
// i64 animation_rate_ns = NsFromSeconds(0.100);
// SPR_LayerKey origin_layer_key = SPR_LayerKeyFromName(Lit(".origin"));
// SPR_LayerKey ap_layer_key = SPR_LayerKeyFromName(Lit(".ap"));
// SPR_SpanKey span_key = Zi;
// {
// // TODO: Determine span dynamically
// span_key = SPR_SpanKeyFromName(Lit("walk"));
// }
// SPR_SheetKey body_sheet_key = SPR_SheetKeyFromResource(ResourceKeyFromStore(&P_Resources, Lit("sprite/bla3.ase")));
// SPR_SheetKey weapon_sheet_key = SPR_SheetKeyFromResource(ResourceKeyFromStore(&P_Resources, Lit("sprite/raahase")));
// // Body
// {
// i64 frame_idx = 0;
// {
// // TODO: Real walk animation
// SPR_Span span = SPR_SpanFromKey(body_sheet_key, span_key);
// i64 walk_duration_ns = time_ns;
// i64 frame_seq = walk_duration_ns / animation_rate_ns;
// i64 frame_idx = span.start + (frame_seq % (span.end - span.start));
// }
// SPR_Slice slice = SPR_SliceFromFrame(body_sheet_key, SPR_NilLayerKey, frame_idx);
// SPR_Ray origin_ray = SPR_RayFromFrame(body_sheet_key, origin_layer_key, frame_idx);
// SPR_Ray ap_ray = SPR_RayFromFrame(body_sheet_key, ap_layer_key, frame_idx);
// {
// // Vec2 world_dims = VEC2(0.5, 0.5);
// Vec2 px_dims = slice.dims;
// Vec2 world_dims = DivVec2(px_dims, P_CellsPerMeter);
// result.slice_to_world_xf = XformIdentity;
// result.slice_to_world_xf.og = ent->xf.og;
// // result.slice_to_world_xf.og = SubVec2(result.slice_to_world_xf.og, MulVec2(world_dims, 0.25));
// result.slice_to_world_xf = XformWithWorldRotation(result.slice_to_world_xf, AngleFromVec2(ent->control.look));
// result.slice_to_world_xf = TranslateXform(result.slice_to_world_xf, MulVec2(world_dims, -0.5));
// result.slice_to_world_xf = ScaleXform(result.slice_to_world_xf, world_dims);
// }
// // result.slice = SPR_SliceFromSheet(sheet,
// }
// // Weapon
// {
// }
// return result;
}
////////////////////////////////////////////////////////////
@ -352,7 +491,7 @@ P_CollisionResult P_CollisionResultFromShapes(P_Shape shape0, P_Shape shape1)
Vec2 removed_a = Zi;
Vec2 removed_b = Zi;
u32 num_removed = 0;
u32 removed_count = 0;
for (;;)
{
//////////////////////////////
@ -387,9 +526,9 @@ P_CollisionResult P_CollisionResultFromShapes(P_Shape shape0, P_Shape shape1)
if (
Vec2LenSq(SubVec2(m.p, simplex.a.p)) < min_unique_pt_dist_sq ||
Vec2LenSq(SubVec2(m.p, simplex.b.p)) < min_unique_pt_dist_sq || (
(num_removed >= 1) && (
(removed_count >= 1) && (
(Vec2LenSq(SubVec2(m.p, removed_a)) < min_unique_pt_dist_sq) ||
(num_removed >= 2 && Vec2LenSq(SubVec2(m.p, removed_b)) < min_unique_pt_dist_sq)
(removed_count >= 2 && Vec2LenSq(SubVec2(m.p, removed_b)) < min_unique_pt_dist_sq)
)
) ||
AbsF32(WedgeVec2(SubVec2(simplex.b.p, simplex.a.p), SubVec2(m.p, simplex.a.p))) < min_unique_pt_dist_sq
@ -437,7 +576,7 @@ P_CollisionResult P_CollisionResultFromShapes(P_Shape shape0, P_Shape shape1)
if (rab_dot >= 0 && vab_dot >= 0 && vab_dot <= 1)
{
// Region ab, remove c
num_removed = 1;
removed_count = 1;
removed_a = simplex.c.p;
simplex.count = 2;
dir = rab_dir; // Next third point is in direction of region ab
@ -445,7 +584,7 @@ P_CollisionResult P_CollisionResultFromShapes(P_Shape shape0, P_Shape shape1)
else if (rac_dot >= 0 && vac_dot >= 0 && vac_dot <= 1)
{
// Region ac, remove b
num_removed = 1;
removed_count = 1;
removed_a = simplex.b.p;
simplex.count = 2;
simplex.b = simplex.c;
@ -454,7 +593,7 @@ P_CollisionResult P_CollisionResultFromShapes(P_Shape shape0, P_Shape shape1)
else if (rbc_dot >= 0 && vbc_dot >= 0 && vbc_dot <= 1)
{
// Region bc, remove a
num_removed = 1;
removed_count = 1;
removed_a = simplex.a.p;
simplex.count = 2;
simplex.a = simplex.b;
@ -464,7 +603,7 @@ P_CollisionResult P_CollisionResultFromShapes(P_Shape shape0, P_Shape shape1)
else if (vab_dot <= 0 && vac_dot <= 0)
{
// Region a, remove bc
num_removed = 2;
removed_count = 2;
removed_a = simplex.b.p;
removed_b = simplex.c.p;
simplex.count = 1;
@ -472,7 +611,7 @@ P_CollisionResult P_CollisionResultFromShapes(P_Shape shape0, P_Shape shape1)
else if (vab_dot >= 1 && vbc_dot <= 0)
{
// Region b, remove ac
num_removed = 2;
removed_count = 2;
removed_a = simplex.a.p;
removed_b = simplex.c.p;
simplex.count = 1;
@ -481,7 +620,7 @@ P_CollisionResult P_CollisionResultFromShapes(P_Shape shape0, P_Shape shape1)
else if (vac_dot >= 1 && vbc_dot >= 1)
{
// Region c, remove ab
num_removed = 2;
removed_count = 2;
removed_a = simplex.a.p;
removed_b = simplex.b.p;
simplex.count = 1;
@ -2321,7 +2460,31 @@ void P_StepFrame(P_Frame *frame)
{
P_Shape firer_world_shape = P_WorldShapeFromEnt(firer);
Vec2 pos = P_EdgePointFromShape(firer_world_shape, firer->control.look);
Vec2 base_pos = P_EdgePointFromShape(firer_world_shape, firer->control.look);
Vec2 base_dir = firer->control.look;
// Vec2 base_pos = Zi;
// Vec2 base_dir = Zi;
// {
// P_Anim anim = P_AnimFromEnt(firer);
// SPR_LayerKey origin_layer = SPR_LayerKeyFromName(Lit(".origin"));
// SPR_LayerKey ap_layer = SPR_LayerKeyFromName(Lit(".ap"));
// Vec2 firer_origin_ray = SPR_RayFromSheet(anim.sheet, anim.span, anim.frame_seq, origin_layer);
// Vec2 firer_ap_ray = SPR_RayFromSheet(anim.sheet, anim.span, anim.frame_seq, ap_layer);
// Vec2 wep_origin_ray = SPR_RayFromSheet(anim.wep_sheet, anim.span, anim.frame_seq, origin_layer);
// Vec2 wep_ap_ray = SPR_RayFromSheet(anim.wep_sheet, anim.span, anim.frame_seq, ap_layer);
// Vec2 fo2w = SubVec2(firer_
// base_pos =
// // FIXME: Real dir
// base_dir = firer->control.look;
// }
for (i64 bullet_idx = 0; bullet_idx < tick_bullets_count; ++bullet_idx)
{
@ -2333,14 +2496,14 @@ void P_StepFrame(P_Frame *frame)
f32 rand_angle = ((f32)P_RandU64FromEnt(firer) / (f32)0xFFFFFFFFFFFFFFFFull) - 0.5;
f32 speed = tweak_speed * sim_dt;
f32 angle = AngleFromVec2(firer->control.look);
f32 angle = AngleFromVec2(base_dir);
speed += (speed * 0.5) * rand_speed;
angle += rand_angle * spread;
Vec2 dir = Vec2FromAngle(angle);
bullet->bullet_start = pos;
bullet->bullet_start = base_pos;
bullet->bullet_end = AddVec2(bullet->bullet_start, MulVec2(dir, speed));
bullet->bullet_firer = firer->key;
}

View File

@ -171,8 +171,10 @@ Struct(P_EntBin)
Struct(P_Anim)
{
Xform slice_to_world_xf;
SPR_Slice slice;
i64 frame_seq;
SPR_SpanKey span;
SPR_SheetKey sheet;
SPR_SheetKey wep_sheet;
};
////////////////////////////////////////////////////////////

BIN
src/pp/pp_res/sprite/bla3.ase (Stored with Git LFS)

Binary file not shown.

BIN
src/pp/pp_res/sprite/palette.ase (Stored with Git LFS)

Binary file not shown.

BIN
src/pp/pp_res/sprite/palette2.ase (Stored with Git LFS)

Binary file not shown.

BIN
src/pp/pp_res/sprite/raah.ase (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -1,11 +1,14 @@
////////////////////////////////////////////////////////////
//~ Tile types
#define P_WorldPitch 64.0
#define P_CellsPerMeter 32.0
#define P_CellsPerSqMeter (P_CellsPerMeter * P_CellsPerMeter)
#define P_TilesPerMeter 2.0
#define P_TilesPerSqMeter (V_TilesPerMeter * V_TilesPerMeter)
////////////////////////////////////////////////////////////
//~ Tile types
#define P_TilesPitch (P_WorldPitch * P_TilesPerMeter)
#define P_TilesCount (P_TilesPitch * P_TilesPitch)

View File

@ -384,7 +384,7 @@ void V_TickForever(WaveLaneCtx *lane)
f32 smooth_remote_buffered_ticks_target = 2;
Vec2I32 tiles_dims = VEC2I32(P_TilesPitch, P_TilesPitch);
Vec2I32 cells_dims = VEC2I32(V_CellsPerMeter * P_WorldPitch, V_CellsPerMeter * P_WorldPitch);
Vec2I32 cells_dims = VEC2I32(P_CellsPerMeter * P_WorldPitch, P_CellsPerMeter * P_WorldPitch);
// Init gpu state
G_ResourceHandle gpu_state = Zi;
@ -683,7 +683,7 @@ void V_TickForever(WaveLaneCtx *lane)
Vec2 shade_extra_dims = VEC2(1, 1);
f32 max_shade_aspect_ratio = 16.0 / 10.0;
frame->shade_dims.x = V_CellsPerMeter * meters_per_camera_width;
frame->shade_dims.x = P_CellsPerMeter * meters_per_camera_width;
frame->shade_dims.y = frame->shade_dims.x / (frame->screen_dims.x / frame->screen_dims.y);
frame->shade_dims.y = MinF32(frame->shade_dims.y, frame->shade_dims.x / max_shade_aspect_ratio);
frame->shade_dims = AddVec2(frame->shade_dims, shade_extra_dims);
@ -934,7 +934,7 @@ void V_TickForever(WaveLaneCtx *lane)
frame->xf.world_to_cell = XformIdentity;
frame->xf.cell_to_world = XformIdentity;
{
frame->xf.world_to_cell = ScaleXform(frame->xf.world_to_cell, VEC2(V_CellsPerMeter, V_CellsPerMeter));
frame->xf.world_to_cell = ScaleXform(frame->xf.world_to_cell, VEC2(P_CellsPerMeter, P_CellsPerMeter));
frame->xf.world_to_cell = TranslateXform(frame->xf.world_to_cell, VEC2((P_WorldPitch / 2.0), (P_WorldPitch / 2.0)));
frame->xf.cell_to_world = InvertXform(frame->xf.world_to_cell);
}
@ -1837,17 +1837,43 @@ void V_TickForever(WaveLaneCtx *lane)
{
P_Anim anim = P_AnimFromEnt(ent, local_frame->time_ns);
// Push weapon quad
SPR_Slice body_slice = SPR_SliceFromSheet(anim.sheet, anim.span, anim.frame_seq);
if (body_slice.ready)
{
Xform body_to_world_xf = XformIdentity;
{
// FIXME: Use origin ray
Vec2 world_dims = DivVec2(body_slice.dims, P_CellsPerMeter);
body_to_world_xf.og = ent->xf.og;
// body_to_world_xf.og = SubVec2(body_to_world_xf.og, MulVec2(world_dims, 0.25));
body_to_world_xf = XformWithWorldRotation(body_to_world_xf, AngleFromVec2(ent->control.look));
body_to_world_xf = TranslateXform(body_to_world_xf, MulVec2(world_dims, -0.5));
body_to_world_xf = ScaleXform(body_to_world_xf, world_dims);
}
// Push body quad
{
V_Quad *quad = PushStruct(frame->quads_arena, V_Quad);
quad->to_shade_xf = MulXform(frame->xf.world_to_shade, anim.slice_to_world_xf);
quad->slice = anim.slice;
quad->to_shade_xf = MulXform(frame->xf.world_to_shade, body_to_world_xf);
quad->tex = body_slice.tex;
quad->uv_rect = body_slice.uv_rect;
}
}
// SPR_Slice wep_slice = SPR_FrameFromSheet(anim.weapon_sheet, anim.span, anim.frame_seq);
// Xform wep_to_world_xf = XformIdentity;
// {
// }
// // Push weapon quad
// {
// V_Quad *quad = PushStruct(frame->quads_arena, V_Quad);
// quad->xf = MulXform(frame->xf.world_to_shade, wep_to_world_xf);
// quad->slice = wep_sframe.slice;
// }
}
}
@ -4226,13 +4252,20 @@ void V_TickForever(WaveLaneCtx *lane)
// Fill tile textures
{
for (P_TileKind tile_kind = 0; tile_kind < P_TileKind_COUNT; ++tile_kind)
{
SPR_Slice tile_slice = Zi;
{
String tile_name = P_TileNameFromKind(tile_kind);
String sheet_name = StringF(frame->arena, "tile/%F.ase", FmtString(tile_name));
ResourceKey sheet_resource = ResourceKeyFromStore(&P_Resources, sheet_name);
SPR_SheetKey sheet = SPR_SheetKeyFromResource(sheet_resource);
SPR_Slice tile_slice = SPR_SliceFromSheet(sheet, Lit(""));
params.tile_slices[tile_kind] = tile_slice;
tile_slice = SPR_SliceFromSheet(sheet, SPR_NilSpanKey, 0);
}
V_TileDesc tile_desc = Zi;
{
tile_desc.tex = tile_slice.tex;
}
params.tile_descs[tile_kind] = tile_desc;
}
}
}

View File

@ -91,7 +91,7 @@ VertexShader(V_QuadVS, V_QuadPSInput)
Vec2 rect_uv = RectUvFromIdx(SV_VertexID);
Vec2 shade_pos = mul(quad.to_shade_xf, Vec3(rect_uv, 1));
Vec2 tex_uv = lerp(quad.slice.uv_rect.p0, quad.slice.uv_rect.p1, rect_uv);
Vec2 tex_uv = lerp(quad.uv_rect.p0, quad.uv_rect.p1, rect_uv);
// Vec2 shade_pos = lerp(quad.p0, quad.p1, rect_uv);
V_QuadPSInput result;
@ -112,7 +112,7 @@ PixelShader(V_QuadPS, V_QuadPSOutput, V_QuadPSInput input)
V_Quad quad = quads[input.quad_idx];
// Texture2D<Vec4> tex = G_Dereference<Vec4>(quad.slice.tex);
// Texture2D<Vec4> tex = G_Dereference<Vec4>(quad.tex);
// Vec4 albedo = tex.Sample(clamp_sampler, input.tex_uv);
Vec4 albedo = Color_Cyan;
@ -546,8 +546,8 @@ ComputeShader2D(V_ShadeCS, 8, 8)
}
else if (tile != P_TileKind_Empty)
{
SPR_Slice slice = params.tile_slices[tile];
Texture2D<Vec4> tile_tex = G_Dereference<Vec4>(slice.tex);
V_TileDesc tile_desc = params.tile_descs[tile];
Texture2D<Vec4> tile_tex = G_Dereference<Vec4>(tile_desc.tex);
tile_color = tile_tex.SampleLevel(wrap_sampler, world_pos, 0);
}
// Checkered grid

View File

@ -13,6 +13,19 @@ Struct(V_QuadPSOutput)
Semantic(Vec4, sv_target0);
};
////////////////////////////////////////////////////////////
//~ Composite shader types
Struct(V_CompositePSInput)
{
Semantic(Vec4, sv_position);
};
Struct(V_CompositePSOutput)
{
Semantic(Vec4, sv_target0);
};
////////////////////////////////////////////////////////////
//~ Debug shape shader types
@ -27,19 +40,6 @@ Struct(V_DVertPSOutput)
Semantic(Vec4, sv_target0);
};
////////////////////////////////////////////////////////////
//~ Composite shader types
Struct(V_CompositePSInput)
{
Semantic(Vec4, sv_position);
};
Struct(V_CompositePSOutput)
{
Semantic(Vec4, sv_target0);
};
////////////////////////////////////////////////////////////
//~ Helpers

View File

@ -1,6 +1,3 @@
#define V_CellsPerMeter 32.0
#define V_CellsPerSqMeter (V_CellsPerMeter * V_CellsPerMeter)
// #define V_ParticlesCap Kibi(128)
// #define V_ParticlesCap Mebi(1)
#define V_ParticlesCap Mebi(2)
@ -49,6 +46,11 @@ Struct(V_Xforms)
Xform tile_to_world;
};
Struct(V_TileDesc)
{
G_Texture2DRef tex;
};
Struct(V_GpuState)
{
// u32 particle_seq; // Atomic monotonically increasing allocation counter sequence for particle ring buffer
@ -103,7 +105,7 @@ Struct(V_GpuParams)
G_RWTexture2DRef stains;
G_RWTexture2DRef drynesses;
SPR_Slice tile_slices[P_TileKind_COUNT];
V_TileDesc tile_descs[P_TileKind_COUNT];
};
////////////////////////////////////////////////////////////
@ -180,9 +182,9 @@ Enum(V_QuadFlag)
Struct(V_Quad)
{
V_QuadFlag flags;
Xform to_shade_xf;
SPR_Slice slice;
G_Texture2DRef tex;
Rng2 uv_rect;
};
////////////////////////////////////////////////////////////

View File

@ -18,109 +18,133 @@ SPR_SheetKey SPR_SheetKeyFromResource(ResourceKey resource)
return result;
}
SPR_SpanKey SPR_SpanKeyFromName(String name)
{
SPR_SpanKey result = Zi;
// TODO
return result;
}
SPR_LayerKey SPR_LayerKeyFromName(String name)
{
SPR_LayerKey result = Zi;
// TODO
return result;
}
////////////////////////////////////////////////////////////
//~ Lookup
SPR_Slice SPR_SliceFromSheet(SPR_SheetKey sheet, String slice_name)
SPR_Slice SPR_SliceFromSheet(SPR_SheetKey sheet, SPR_SpanKey span, i64 frame_seq)
{
// TODO: Ability to specify desired alpha modes (Straight, Premultiplied, Opaque)
SPR_Slice result = Zi;
u64 hash = sheet.r.v;
hash = HashStringEx(hash, slice_name);
i64 completion = G_CompletionValueFromQueue(G_QueueKind_AsyncCopy);
// Search for existing entry
b32 found = 0;
SPR_SliceBin *bin = &SPR.slice_bins[hash % countof(SPR.slice_bins)];
{
Lock bin_lock = LockS(&bin->mutex);
{
SPR_SliceEntry *entry = bin->first;
for (; entry; entry = entry->next)
{
if (entry->hash == hash)
{
break;
}
}
if (entry)
{
if (completion >= Atomic64Fetch(&entry->async_copy_completion_target))
{
result = entry->slice;
}
found = 1;
}
}
Unlock(&bin_lock);
}
// Push new entry
if (!found)
{
Lock submit_lock = LockE(&SPR.submit.mutex);
Lock bin_lock = LockE(&bin->mutex);
{
SPR_SliceEntry *entry = bin->first;
for (; entry; entry = entry->next)
{
if (entry->hash == hash)
{
break;
}
}
if (entry)
{
if (completion >= Atomic64Fetch(&entry->async_copy_completion_target))
{
result = entry->slice;
}
found = 1;
}
else
{
Arena *perm = PermArena();
entry = PushStruct(perm, SPR_SliceEntry);
entry->hash = hash;
Atomic64FetchSet(&entry->async_copy_completion_target, I64Max);
entry->sheet = sheet;
entry->slice_name = PushString(perm, slice_name);
SllStackPush(bin->first, entry);
SPR_CmdNode *n = SPR.submit.first_free;
if (n)
{
SllStackPop(SPR.submit.first_free);
ZeroStruct(n);
}
else
{
n = PushStruct(perm, SPR_CmdNode);
}
n->cmd.entry = entry;
SllQueuePush(SPR.submit.first, SPR.submit.last, n);
++SPR.submit.count;
Atomic32FetchSet(&SPR.new_cmds_present, 1);
SignalAsyncTick();
}
}
Unlock(&bin_lock);
Unlock(&submit_lock);
}
if (G_IsRefNil(result.tex))
{
result.tex = G_BlankTexture2D();
result.uv_rect.p0 = VEC2(0, 0);
result.uv_rect.p1 = VEC2(1, 1);
}
// TODO
return result;
}
// SPR_Slice SPR_SliceFromSheet(SPR_SheetKey sheet, SPR_SpanKey span, i64 frame_seq)
// {
// // TODO: Ability to specify desired alpha modes (Straight, Premultiplied, Opaque)
// SPR_Slice result = Zi;
// // FIXME
// u64 hash = sheet.r.v;
// hash = HashStringEx(hash, slice_name);
// i64 completion = G_CompletionValueFromQueue(G_QueueKind_AsyncCopy);
// // Search for existing entry
// b32 found = 0;
// SPR_SliceBin *bin = &SPR.slice_bins[hash % countof(SPR.slice_bins)];
// {
// Lock bin_lock = LockS(&bin->mutex);
// {
// SPR_SliceEntry *entry = bin->first;
// for (; entry; entry = entry->next)
// {
// if (entry->hash == hash)
// {
// break;
// }
// }
// if (entry)
// {
// if (completion >= Atomic64Fetch(&entry->async_copy_completion_target))
// {
// result = entry->slice;
// }
// found = 1;
// }
// }
// Unlock(&bin_lock);
// }
// // Push new entry
// if (!found)
// {
// Lock submit_lock = LockE(&SPR.submit.mutex);
// Lock bin_lock = LockE(&bin->mutex);
// {
// SPR_SliceEntry *entry = bin->first;
// for (; entry; entry = entry->next)
// {
// if (entry->hash == hash)
// {
// break;
// }
// }
// if (entry)
// {
// if (completion >= Atomic64Fetch(&entry->async_copy_completion_target))
// {
// result = entry->slice;
// }
// found = 1;
// }
// else
// {
// Arena *perm = PermArena();
// entry = PushStruct(perm, SPR_SliceEntry);
// entry->hash = hash;
// Atomic64FetchSet(&entry->async_copy_completion_target, I64Max);
// entry->sheet = sheet;
// entry->slice_name = PushString(perm, slice_name);
// SllStackPush(bin->first, entry);
// SPR_CmdNode *n = SPR.submit.first_free;
// if (n)
// {
// SllStackPop(SPR.submit.first_free);
// ZeroStruct(n);
// }
// else
// {
// n = PushStruct(perm, SPR_CmdNode);
// }
// n->cmd.entry = entry;
// SllQueuePush(SPR.submit.first, SPR.submit.last, n);
// ++SPR.submit.count;
// Atomic32FetchSet(&SPR.new_cmds_present, 1);
// SignalAsyncTick();
// }
// }
// Unlock(&bin_lock);
// Unlock(&submit_lock);
// }
// if (G_IsRefNil(result.tex))
// {
// result.tex = G_BlankTexture2D();
// result.uv_rect.p0 = VEC2(0, 0);
// result.uv_rect.p1 = VEC2(1, 1);
// }
// return result;
// }
////////////////////////////////////////////////////////////
//~ Async

View File

@ -1,9 +1,24 @@
////////////////////////////////////////////////////////////
//~ Key types
Struct(SPR_SheetKey)
Struct(SPR_SheetKey) { ResourceKey r; };
Struct(SPR_SpanKey) { u64 v; };
Struct(SPR_LayerKey) { u64 v; };
#define SPR_NilSheetKey ((SPR_SheetKey) { 0 })
#define SPR_NilSpanKey ((SPR_SpanKey) { 0 })
#define SPR_NilLayerKey ((SPR_LayerKey) { 0 })
////////////////////////////////////////////////////////////
//~ Slice types
Struct(SPR_Slice)
{
ResourceKey r;
G_Texture2DRef tex;
Rng2 uv_rect;
Vec2 dims;
b32 ready;
};
////////////////////////////////////////////////////////////
@ -91,11 +106,13 @@ void SPR_Bootstrap(void);
//~ Key helpers
SPR_SheetKey SPR_SheetKeyFromResource(ResourceKey resource);
SPR_SpanKey SPR_SpanKeyFromName(String name);
SPR_LayerKey SPR_LayerKeyFromName(String name);
////////////////////////////////////////////////////////////
//~ Lookup
SPR_Slice SPR_SliceFromSheet(SPR_SheetKey sheet, String slice_name);
SPR_Slice SPR_SliceFromSheet(SPR_SheetKey sheet, SPR_SpanKey span, i64 frame_seq);
////////////////////////////////////////////////////////////
//~ Async

View File

@ -9,8 +9,6 @@
//////////////////////////////
//- Api
@IncludeC sprite_shared.cgh
@IncludeG sprite_shared.cgh
@IncludeC sprite.h
@Bootstrap SPR_Bootstrap

View File

@ -1,8 +0,0 @@
////////////////////////////////////////////////////////////
//~ Slice types
Struct(SPR_Slice)
{
G_Texture2DRef tex;
Rng2 uv_rect;
};

View File

@ -77,20 +77,20 @@ void WND_Bootstrap(void)
{
HMODULE instance = GetModuleHandle(0);
// Register the window class
// Register window class
WNDCLASSEXW *wc = &WND_W32.window_class;
wc->cbSize = sizeof(WNDCLASSEX);
wc->lpszClassName = WND_W32_WindowClassName;
wc->hCursor = LoadCursor(0, IDC_ARROW);
wc->style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
// wc->hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
wc->hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
wc->lpfnWndProc = WND_W32_WindowProc;
wc->hInstance = instance;
// Use first icon resource as window icon (same as explorer)
wchar_t path[4096] = Zi;
GetModuleFileNameW(instance, path, countof(path));
ExtractIconExW(path, 0, &wc->hIcon, &wc->hIconSm, 1);
wchar_t path_wstr[4096] = Zi;
GetModuleFileNameW(instance, path_wstr, countof(path_wstr));
ExtractIconExW(path_wstr, 0, &wc->hIcon, &wc->hIconSm, 1);
if (!RegisterClassExW(wc))
{