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
|
// TODO: optimize by removing this component set call and instead use a .write() query
|
||||||
try sprite_pipeline.set(pipeline_id, .num_sprites, num_sprites);
|
try sprite_pipeline.set(pipeline_id, .num_sprites, num_sprites);
|
||||||
if (num_sprites > 0) {
|
if (num_sprites > 0) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue