gfx: Sprite: sort/draw sprites back-to-front always
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>
This commit is contained in:
parent
1237858359
commit
b261a8177f
1 changed files with 25 additions and 0 deletions
|
|
@ -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) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue