Added ui sprite masking
parent
81dc7b170c
commit
1ae8e6c5a8
|
@ -7,6 +7,7 @@ struct InstanceInput {
|
||||||
@location(5) size: f32,
|
@location(5) size: f32,
|
||||||
@location(6) color_transform: vec4<f32>,
|
@location(6) color_transform: vec4<f32>,
|
||||||
@location(7) sprite_index: u32,
|
@location(7) sprite_index: u32,
|
||||||
|
@location(8) mask_index: vec2<u32>,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct VertexInput {
|
struct VertexInput {
|
||||||
|
@ -18,7 +19,9 @@ struct VertexOutput {
|
||||||
@builtin(position) position: vec4<f32>,
|
@builtin(position) position: vec4<f32>,
|
||||||
@location(0) texture_coords: vec2<f32>,
|
@location(0) texture_coords: vec2<f32>,
|
||||||
@location(1) texture_index: u32,
|
@location(1) texture_index: u32,
|
||||||
@location(2) color_transform: vec4<f32>,
|
@location(2) mask_coords: vec2<f32>,
|
||||||
|
@location(3) mask_index: vec2<u32>,
|
||||||
|
@location(4) color_transform: vec4<f32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@group(0) @binding(0)
|
@group(0) @binding(0)
|
||||||
|
@ -72,7 +75,7 @@ fn vertex_main(
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// TODO: animate
|
// TODO: function to get texture from sprite
|
||||||
// Pick texture frame
|
// Pick texture frame
|
||||||
let t = global_atlas[u32(animate(instance.sprite_index, global_data.current_time.x, 0.0))];
|
let t = global_atlas[u32(animate(instance.sprite_index, global_data.current_time.x, 0.0))];
|
||||||
out.texture_index = u32(t.atlas_texture);
|
out.texture_index = u32(t.atlas_texture);
|
||||||
|
@ -84,16 +87,55 @@ fn vertex_main(
|
||||||
out.texture_coords = vec2(out.texture_coords.x, out.texture_coords.y + t.height);
|
out.texture_coords = vec2(out.texture_coords.x, out.texture_coords.y + t.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Pick mask image if mask is enabled
|
||||||
|
// x coordinate of mask index is either 0 or 1, telling us whether or not to use a mask.
|
||||||
|
// y coordinate is mask sprite index
|
||||||
|
if instance.mask_index.x == 1u {
|
||||||
|
let ms = global_sprites[instance.mask_index.y].first_frame;
|
||||||
|
let m = global_atlas[ms];
|
||||||
|
out.mask_index = vec2(1u, u32(m.atlas_texture));
|
||||||
|
out.mask_coords = vec2(m.xpos, m.ypos);
|
||||||
|
if vertex.texture_coords.x == 1.0 {
|
||||||
|
out.mask_coords = vec2(out.mask_coords.x + m.width, out.mask_coords.y);
|
||||||
|
}
|
||||||
|
if vertex.texture_coords.y == 1.0 {
|
||||||
|
out.mask_coords = vec2(out.mask_coords.x, out.mask_coords.y + m.height);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
out.mask_coords = vec2(0.0, 0.0);
|
||||||
|
out.mask_index = vec2(0u, 0u);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@fragment
|
@fragment
|
||||||
fn fragment_main(in: VertexOutput) -> @location(0) vec4<f32> {
|
fn fragment_main(in: VertexOutput) -> @location(0) vec4<f32> {
|
||||||
return textureSampleLevel(
|
|
||||||
|
var mask: f32 = 1.0;
|
||||||
|
if in.mask_index.x == 1u {
|
||||||
|
mask = textureSampleLevel(
|
||||||
|
texture_array[in.mask_index.y],
|
||||||
|
sampler_array[0],
|
||||||
|
in.mask_coords,
|
||||||
|
0.0
|
||||||
|
).a;
|
||||||
|
}
|
||||||
|
|
||||||
|
var color: vec4<f32> = textureSampleLevel(
|
||||||
texture_array[in.texture_index],
|
texture_array[in.texture_index],
|
||||||
sampler_array[0],
|
sampler_array[0],
|
||||||
in.texture_coords,
|
in.texture_coords,
|
||||||
0.0
|
0.0
|
||||||
).rgba * in.color_transform;
|
).rgba * in.color_transform;
|
||||||
|
|
||||||
|
// Apply mask and discard fully transparent pixels
|
||||||
|
color = vec4(color.rgb, color.a *mask);
|
||||||
|
if color.a == 0.0 {
|
||||||
|
discard;
|
||||||
|
}
|
||||||
|
|
||||||
|
return color;
|
||||||
}
|
}
|
|
@ -68,6 +68,7 @@ impl Radar {
|
||||||
size: radar_size,
|
size: radar_size,
|
||||||
color: [1.0, 1.0, 1.0, 1.0],
|
color: [1.0, 1.0, 1.0, 1.0],
|
||||||
sprite_index: input.ct.get_sprite_handle("ui::radar").get_index(),
|
sprite_index: input.ct.get_sprite_handle("ui::radar").get_index(),
|
||||||
|
mask_index: [0, 0],
|
||||||
});
|
});
|
||||||
|
|
||||||
// Draw system objects
|
// Draw system objects
|
||||||
|
@ -96,6 +97,7 @@ impl Radar {
|
||||||
size,
|
size,
|
||||||
color: [0.5, 0.5, 0.5, 1.0],
|
color: [0.5, 0.5, 0.5, 1.0],
|
||||||
sprite_index: planet_sprite.get_index(),
|
sprite_index: planet_sprite.get_index(),
|
||||||
|
mask_index: [0, 0],
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -149,6 +151,7 @@ impl Radar {
|
||||||
size,
|
size,
|
||||||
color,
|
color,
|
||||||
sprite_index: ship_sprite.get_index(),
|
sprite_index: ship_sprite.get_index(),
|
||||||
|
mask_index: [0, 0],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -176,6 +179,7 @@ impl Radar {
|
||||||
size,
|
size,
|
||||||
color,
|
color,
|
||||||
sprite_index: sprite.get_index(),
|
sprite_index: sprite.get_index(),
|
||||||
|
mask_index: [0, 0],
|
||||||
});
|
});
|
||||||
|
|
||||||
state.push_ui_buffer(UiInstance {
|
state.push_ui_buffer(UiInstance {
|
||||||
|
@ -189,6 +193,7 @@ impl Radar {
|
||||||
size,
|
size,
|
||||||
color,
|
color,
|
||||||
sprite_index: sprite.get_index(),
|
sprite_index: sprite.get_index(),
|
||||||
|
mask_index: [0, 0],
|
||||||
});
|
});
|
||||||
|
|
||||||
state.push_ui_buffer(UiInstance {
|
state.push_ui_buffer(UiInstance {
|
||||||
|
@ -202,6 +207,7 @@ impl Radar {
|
||||||
size,
|
size,
|
||||||
color,
|
color,
|
||||||
sprite_index: sprite.get_index(),
|
sprite_index: sprite.get_index(),
|
||||||
|
mask_index: [0, 0],
|
||||||
});
|
});
|
||||||
|
|
||||||
state.push_ui_buffer(UiInstance {
|
state.push_ui_buffer(UiInstance {
|
||||||
|
@ -215,6 +221,7 @@ impl Radar {
|
||||||
size,
|
size,
|
||||||
color,
|
color,
|
||||||
sprite_index: sprite.get_index(),
|
sprite_index: sprite.get_index(),
|
||||||
|
mask_index: [0, 0],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -233,6 +240,7 @@ impl Radar {
|
||||||
size: 10.0,
|
size: 10.0,
|
||||||
color: [1.0, 1.0, 1.0, 1f32.min((m - 200.0) / 400.0)],
|
color: [1.0, 1.0, 1.0, 1f32.min((m - 200.0) / 400.0)],
|
||||||
sprite_index: arrow_sprite.get_index(),
|
sprite_index: arrow_sprite.get_index(),
|
||||||
|
mask_index: [0, 0],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,6 +52,7 @@ impl Status {
|
||||||
size: 200.0,
|
size: 200.0,
|
||||||
color: [1.0, 1.0, 1.0, 1.0],
|
color: [1.0, 1.0, 1.0, 1.0],
|
||||||
sprite_index: input.ct.get_sprite_handle("ui::status").get_index(),
|
sprite_index: input.ct.get_sprite_handle("ui::status").get_index(),
|
||||||
|
mask_index: [0, 0],
|
||||||
});
|
});
|
||||||
|
|
||||||
state.push_radialbar_buffer(RadialBarInstance {
|
state.push_radialbar_buffer(RadialBarInstance {
|
||||||
|
|
|
@ -140,6 +140,11 @@ pub struct UiInstance {
|
||||||
|
|
||||||
/// What texture to use for this sprite
|
/// What texture to use for this sprite
|
||||||
pub sprite_index: u32,
|
pub sprite_index: u32,
|
||||||
|
|
||||||
|
/// What mask to use for this sprite
|
||||||
|
/// If the first element is not 1, no mask is used.
|
||||||
|
/// Second element is sprite index of mask.
|
||||||
|
pub mask_index: [u32; 2],
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BufferObject for UiInstance {
|
impl BufferObject for UiInstance {
|
||||||
|
@ -187,6 +192,12 @@ impl BufferObject for UiInstance {
|
||||||
shader_location: 7,
|
shader_location: 7,
|
||||||
format: wgpu::VertexFormat::Uint32,
|
format: wgpu::VertexFormat::Uint32,
|
||||||
},
|
},
|
||||||
|
// Mask
|
||||||
|
wgpu::VertexAttribute {
|
||||||
|
offset: mem::size_of::<[f32; 10]>() as wgpu::BufferAddress,
|
||||||
|
shader_location: 8,
|
||||||
|
format: wgpu::VertexFormat::Uint32x2,
|
||||||
|
},
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue