Cleaned up global data buffer

master
Mark 2024-01-27 14:49:34 -08:00
parent 1a29130419
commit 25661817a4
Signed by: Mark
GPG Key ID: C6D63995FE72FD80
8 changed files with 108 additions and 85 deletions

View File

@ -8,7 +8,10 @@ fn anchor(
) -> vec2<f32> {
var trans: vec2<f32> = vec2(0.0, 0.0);
let window_dim = global_data.window_size / global_data.window_scale.x;
let window_dim = (
vec2(global_data.window_size_w, global_data.window_size_h) /
global_data.window_scale
);
if anchor == 0u { // NW C (screen anchor, sprite anchor)
trans += vec2(-window_dim.x, window_dim.y) / 2.0; // origin

View File

@ -30,7 +30,7 @@ var sampler_array: binding_array<sampler>;
fn transform_vertex(obj: ObjectData, vertex_position: vec2<f32>, texture_index: u32) -> vec4<f32> {
// Object scale
var scale: f32 = obj.size / (global_data.camera_zoom.x * obj.zpos);
var scale: f32 = obj.size / (global_data.camera_zoom * obj.zpos);
if obj.is_child == 1u {
scale /= objects[obj.parent].zpos;
}
@ -56,7 +56,7 @@ fn transform_vertex(obj: ObjectData, vertex_position: vec2<f32>, texture_index:
// (It's thus done later if this is a child)
if obj.is_child == u32(0) {
pos = vec2(
pos.x / global_data.window_aspect.x,
pos.x / global_data.window_aspect,
pos.y
);
}
@ -67,10 +67,13 @@ fn transform_vertex(obj: ObjectData, vertex_position: vec2<f32>, texture_index:
// The height of the viewport is `zoom` in game units,
// but it's 2 in screen units (since coordinates range from -1 to 1)
if obj.is_child == u32(0) {
let trans = (vec2(obj.xpos, obj.ypos) - global_data.camera_position) / obj.zpos;
let trans = (
vec2(obj.xpos, obj.ypos) -
vec2(global_data.camera_position_x, global_data.camera_position_y)
) / obj.zpos;
pos = pos + vec2(
trans.x / (global_data.camera_zoom.x / 2.0) / global_data.window_aspect.x,
trans.y / (global_data.camera_zoom.x / 2.0)
trans.x / (global_data.camera_zoom / 2.0) / global_data.window_aspect,
trans.y / (global_data.camera_zoom / 2.0)
);
}
@ -81,8 +84,8 @@ fn transform_vertex(obj: ObjectData, vertex_position: vec2<f32>, texture_index:
// Apply translation relative to parent
// Note that obj.zpos is ignored
pos = pos + vec2(
obj.xpos / (global_data.camera_zoom.x / 2.0) / global_data.window_aspect.x,
obj.ypos / (global_data.camera_zoom.x / 2.0)
obj.xpos / (global_data.camera_zoom / 2.0) / global_data.window_aspect,
obj.ypos / (global_data.camera_zoom / 2.0)
) / parent.zpos;
// Apply parent's rotation
@ -93,15 +96,18 @@ fn transform_vertex(obj: ObjectData, vertex_position: vec2<f32>, texture_index:
// Correct for screen aspect, preserving height
pos = vec2(
pos.x / global_data.window_aspect.x,
pos.x / global_data.window_aspect,
pos.y
);
// Apply parent's translation
let ptrans = (vec2(parent.xpos, parent.ypos) - global_data.camera_position) / parent.zpos;
let ptrans = (
vec2(parent.xpos, parent.ypos) -
vec2(global_data.camera_position_x, global_data.camera_position_y)
) / parent.zpos;
pos = pos + vec2(
ptrans.x / (global_data.camera_zoom.x / 2.0) / global_data.window_aspect.x,
ptrans.y / (global_data.camera_zoom.x / 2.0)
ptrans.x / (global_data.camera_zoom / 2.0) / global_data.window_aspect,
ptrans.y / (global_data.camera_zoom / 2.0)
);
}

View File

@ -51,7 +51,10 @@ fn vertex_main(
instance.anchor,
instance.position,
vec2(instance.diameter, instance.diameter)
) / 2.0 * (global_data.window_size / global_data.window_scale.x);
) / 2.0 * (
vec2(global_data.window_size_w, global_data.window_size_h) /
global_data.window_scale
);
// ^ slight correction, since anchor gives us a different result than we need here
return out;
@ -62,8 +65,10 @@ fn fragment_main(in: VertexOutput) -> @location(0) vec4<f32> {
// Fragment position in logical pixels, relative to arc center
let p = (
vec2(1.0, -1.0) *
(in.position.xy - global_data.window_size / 2.0) /
global_data.window_scale.x
(
in.position.xy -
vec2(global_data.window_size_w, global_data.window_size_h) / 2.0
) / global_data.window_scale
) - in.center;
let bar_width = in.stroke; // Width of filled bar

View File

@ -41,18 +41,19 @@ fn vertex_main(
// Center of the tile the camera is currently in, in game coordinates.
// x div y = x - (x mod y)
let tile_center = (
global_data.camera_position.xy
vec2(global_data.camera_position_x, global_data.camera_position_y)
- (
fmod(
global_data.camera_position.xy + global_data.starfield_tile_size.x / 2.0,
global_data.starfield_tile_size.x
) - global_data.starfield_tile_size.x / 2.0
vec2(global_data.camera_position_x, global_data.camera_position_y) +
global_data.starfield_tile_size / 2.0,
global_data.starfield_tile_size
) - global_data.starfield_tile_size / 2.0
)
);
let zoom_min_times = (
global_data.camera_zoom.x / global_data.camera_zoom_limits.x
global_data.camera_zoom / global_data.camera_zoom_min
);
// Hide n% of the smallest stars
@ -64,8 +65,8 @@ fn vertex_main(
if (
instance.size < (
hide_fraction * (global_data.starfield_size_limits.y - global_data.starfield_size_limits.x)
+ (global_data.starfield_size_limits.x)
hide_fraction * (global_data.starfield_size_max - global_data.starfield_size_min)
+ (global_data.starfield_size_min)
)
) {
out.position = vec4<f32>(2.0, 2.0, 0.0, 1.0);
@ -76,40 +77,43 @@ fn vertex_main(
// Apply sprite aspect ratio & scale factor
// also applies screen aspect ratio
// Note that we do NOT scale for distance here---this is intentional.
var scale: f32 = instance.size / global_data.camera_zoom.x;
var scale: f32 = instance.size / global_data.camera_zoom;
// Minimum scale to prevent flicker at large zoom levels
var real_size = scale * global_data.window_size.xy;
var real_size = scale * vec2(global_data.window_size_w, global_data.window_size_h);
if (real_size.x < 2.0 || real_size.y < 2.0) {
// Otherwise, clamp to a minimum scale
scale = 2.0 / max(global_data.window_size.x, global_data.window_size.y);
scale = 2.0 / max(global_data.window_size_w, global_data.window_size_h);
}
// Divide by two, because viewport height is 2 in screen units
// (coordinates go from -1 to 1)
var pos: vec2<f32> = vec2<f32>(
vertex.position.x * (scale/2.0) / global_data.window_aspect.x,
vertex.position.x * (scale/2.0) / global_data.window_aspect,
vertex.position.y * (scale/2.0)
);
// World position relative to camera
// (Note that instance position is in a different
// coordinate system than usual)
let camera_pos = (instance.position.xy + tile_center) - global_data.camera_position.xy;
let camera_pos = (
(instance.position.xy + tile_center) -
vec2(global_data.camera_position_x, global_data.camera_position_y)
);
// Translate
pos = pos + (
// Don't forget to correct distance for screen aspect ratio too!
(camera_pos / (global_data.camera_zoom.x * instance.position.z))
/ vec2<f32>(global_data.window_aspect.x, 1.0)
(camera_pos / (global_data.camera_zoom * instance.position.z))
/ vec2<f32>(global_data.window_aspect, 1.0)
);
out.position = vec4<f32>(pos, 0.0, 1.0) * instance.position.z;
// Starfield sprites may not be animated
let t = global_atlas[global_data.starfield_sprite.x];
let t = global_atlas[global_data.starfield_sprite];
out.texture_index = u32(t.atlas_texture);
out.texture_coords = vec2(t.xpos, t.ypos);
if vertex.texture_coords.x == 1.0 {

View File

@ -44,7 +44,11 @@ fn transform_vertex(
texture_index: u32,
) -> vec4<f32> {
let window_dim = global_data.window_size / global_data.window_scale.x;
let window_dim = (
vec2(global_data.window_size_w, global_data.window_size_h)
/ global_data.window_scale
);
let scale = instance.size / window_dim.y;
let aspect = (
global_atlas[instance.texture_index.x].width /
@ -66,7 +70,7 @@ fn transform_vertex(
// Correct for screen aspect, preserving height
pos = vec2(
pos.x / global_data.window_aspect.x,
pos.x / global_data.window_aspect,
pos.y
);

View File

@ -10,41 +10,45 @@ use wgpu;
// also, [f32; 3] are aligned as [f32; 4]
// (since alignments must be powers of two)
pub struct GlobalDataContent {
/// Camera position, in game units
pub camera_position: [f32; 2],
/// Camera position x, in game units
pub camera_position_x: f32,
/// Camera zoom value, in game units.
/// Second component is ignored.
pub camera_zoom: [f32; 2],
/// Camera position y, in game units
pub camera_position_y: f32,
/// Camera zoom min and max.
pub camera_zoom_limits: [f32; 2],
/// Camera zoom, in game units
/// i.e, height if window in game units
pub camera_zoom: f32,
/// Size ratio of window, in physical pixels
pub window_size: [f32; 2],
/// Minimum camera zoom
pub camera_zoom_min: f32,
/// Physical pixel to logical pixel conversion factor.
/// Second component is ignored.
pub window_scale: [f32; 2],
/// Maximum camera zoom
pub camera_zoom_max: f32,
/// Window width, in physical pixels
pub window_size_w: f32,
/// Window height, in physical pixels
pub window_size_h: f32,
/// Physical to logical pixel conversion factor
pub window_scale: f32,
/// Aspect ratio of window
/// Second component is ignored.
pub window_aspect: [f32; 2],
pub window_aspect: f32,
/// Index of starfield sprite
/// Second component is ignored.
pub starfield_sprite: [u32; 2],
pub starfield_sprite: u32,
// Size of (square) starfield tiles, in game units
/// Second component is ignored.
pub starfield_tile_size: [f32; 2],
/// Size of starfield tile squares
pub starfield_tile_size: f32,
/// Min and max starfield star size, in game units
pub starfield_size_limits: [f32; 2],
/// Minimum starfield star size
pub starfield_size_min: f32,
/// Current game time, in seconds.
/// Second component is ignored.
pub current_time: [f32; 2],
/// Maximum starfield star size
pub starfield_size_max: f32,
}
impl GlobalDataContent {

View File

@ -22,16 +22,19 @@ impl GlobalUniform {
r#"
var<uniform> global_data: GlobalData;
struct GlobalData {
camera_position: vec2<f32>,
camera_zoom: vec2<f32>,
camera_zoom_limits: vec2<f32>,
window_size: vec2<f32>,
window_scale: vec2<f32>,
window_aspect: vec2<f32>,
starfield_sprite: vec2<u32>,
starfield_tile_size: vec2<f32>,
starfield_size_limits: vec2<f32>,
current_time: vec2<f32>,
camera_position_x: f32,
camera_position_y: f32,
camera_zoom: f32,
camera_zoom_min: f32,
camera_zoom_max: f32,
window_size_w: f32,
window_size_h: f32,
window_scale: f32,
window_aspect: f32,
starfield_sprite: u32,
starfield_tile_size: f32,
starfield_size_min: f32,
starfield_size_max: f32,
};
"#,
);

View File

@ -258,25 +258,19 @@ impl<'a> super::GPUState {
&self.state.global_uniform.data_buffer,
0,
bytemuck::cast_slice(&[GlobalDataContent {
camera_position: input.camera_pos.into(),
camera_zoom: [input.camera_zoom, 0.0],
camera_zoom_limits: [
input.ct.get_config().zoom_min,
input.ct.get_config().zoom_max,
],
window_size: [
self.state.window_size.width as f32,
self.state.window_size.height as f32,
],
window_scale: [self.state.window.scale_factor() as f32, 0.0],
window_aspect: [self.state.window_aspect, 0.0],
starfield_sprite: [input.ct.get_config().starfield_texture.into(), 0],
starfield_tile_size: [input.ct.get_config().starfield_size, 0.0],
starfield_size_limits: [
input.ct.get_config().starfield_min_size,
input.ct.get_config().starfield_max_size,
],
current_time: [input.current_time, 0.0],
camera_position_x: input.camera_pos.x,
camera_position_y: input.camera_pos.y,
camera_zoom: input.camera_zoom,
camera_zoom_min: input.ct.get_config().zoom_min,
camera_zoom_max: input.ct.get_config().zoom_max,
window_size_w: self.state.window_size.width as f32,
window_size_h: self.state.window_size.height as f32,
window_scale: self.state.window.scale_factor() as f32,
window_aspect: self.state.window_aspect,
starfield_sprite: input.ct.get_config().starfield_texture.into(),
starfield_tile_size: input.ct.get_config().starfield_size,
starfield_size_min: input.ct.get_config().starfield_min_size,
starfield_size_max: input.ct.get_config().starfield_max_size,
}]),
);