Skip to content

Commit

Permalink
gfx: Sprite: sort/draw sprites back-to-front always
Browse files Browse the repository at this point in the history
Prior to this change sprite draw order was not something we could specify,
now we can by changing the Z value of sprites (sprites further away / with
greater Z values are drawn first), which is obviously desirable for layering
and alpha blending purposes.

The implementation here is rather naive: we sort all sprites each frame based
on their Z value; but its performance is quite good with ~half a million sprites
and so is good enough for now.

Signed-off-by: Stephen Gutekanst <stephen@hexops.com>
  • Loading branch information
slimsag committed May 23, 2024
1 parent 1237858 commit b261a81
Showing 1 changed file with 25 additions and 0 deletions.
25 changes: 25 additions & 0 deletions src/gfx/Sprite.zig
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,31 @@ fn updatePipeline(
}
}

// Sort sprites back-to-front for draw order, alpha blending
const Context = struct {
transforms: []Mat4x4,
uv_transforms: []Mat3x3,
sizes: []Vec2,

pub fn lessThan(ctx: @This(), a: usize, b: usize) bool {
const a_z = ctx.transforms[a].translation().z();
const b_z = ctx.transforms[b].translation().z();
// Greater z values are further away, and thus should render/sort before those with lesser z values.
return a_z > b_z;
}

pub fn swap(ctx: @This(), a: usize, b: usize) void {
std.mem.swap(Mat4x4, &ctx.transforms[a], &ctx.transforms[b]);
std.mem.swap(Mat3x3, &ctx.uv_transforms[a], &ctx.uv_transforms[b]);
std.mem.swap(Vec2, &ctx.sizes[a], &ctx.sizes[b]);
}
};
std.sort.pdqContext(0, i, Context{
.transforms = gfx.SpritePipeline.cp_transforms[0..i],
.uv_transforms = gfx.SpritePipeline.cp_uv_transforms[0..i],
.sizes = gfx.SpritePipeline.cp_sizes[0..i],
});

// TODO: optimize by removing this component set call and instead use a .write() query
try sprite_pipeline.set(pipeline_id, .num_sprites, num_sprites);
if (num_sprites > 0) {
Expand Down

0 comments on commit b261a81

Please sign in to comment.