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> { ) -> vec2<f32> {
var trans: vec2<f32> = vec2(0.0, 0.0); 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) if anchor == 0u { // NW C (screen anchor, sprite anchor)
trans += vec2(-window_dim.x, window_dim.y) / 2.0; // origin 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> { fn transform_vertex(obj: ObjectData, vertex_position: vec2<f32>, texture_index: u32) -> vec4<f32> {
// Object scale // 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 { if obj.is_child == 1u {
scale /= objects[obj.parent].zpos; 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) // (It's thus done later if this is a child)
if obj.is_child == u32(0) { if obj.is_child == u32(0) {
pos = vec2( pos = vec2(
pos.x / global_data.window_aspect.x, pos.x / global_data.window_aspect,
pos.y 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, // The height of the viewport is `zoom` in game units,
// but it's 2 in screen units (since coordinates range from -1 to 1) // but it's 2 in screen units (since coordinates range from -1 to 1)
if obj.is_child == u32(0) { 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( pos = pos + vec2(
trans.x / (global_data.camera_zoom.x / 2.0) / global_data.window_aspect.x, trans.x / (global_data.camera_zoom / 2.0) / global_data.window_aspect,
trans.y / (global_data.camera_zoom.x / 2.0) 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 // Apply translation relative to parent
// Note that obj.zpos is ignored // Note that obj.zpos is ignored
pos = pos + vec2( pos = pos + vec2(
obj.xpos / (global_data.camera_zoom.x / 2.0) / global_data.window_aspect.x, obj.xpos / (global_data.camera_zoom / 2.0) / global_data.window_aspect,
obj.ypos / (global_data.camera_zoom.x / 2.0) obj.ypos / (global_data.camera_zoom / 2.0)
) / parent.zpos; ) / parent.zpos;
// Apply parent's rotation // 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 // Correct for screen aspect, preserving height
pos = vec2( pos = vec2(
pos.x / global_data.window_aspect.x, pos.x / global_data.window_aspect,
pos.y pos.y
); );
// Apply parent's translation // 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( pos = pos + vec2(
ptrans.x / (global_data.camera_zoom.x / 2.0) / global_data.window_aspect.x, ptrans.x / (global_data.camera_zoom / 2.0) / global_data.window_aspect,
ptrans.y / (global_data.camera_zoom.x / 2.0) ptrans.y / (global_data.camera_zoom / 2.0)
); );
} }

View File

@ -51,7 +51,10 @@ fn vertex_main(
instance.anchor, instance.anchor,
instance.position, instance.position,
vec2(instance.diameter, instance.diameter) 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 // ^ slight correction, since anchor gives us a different result than we need here
return out; return out;
@ -62,8 +65,10 @@ fn fragment_main(in: VertexOutput) -> @location(0) vec4<f32> {
// Fragment position in logical pixels, relative to arc center // Fragment position in logical pixels, relative to arc center
let p = ( let p = (
vec2(1.0, -1.0) * 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; ) - in.center;
let bar_width = in.stroke; // Width of filled bar 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. // Center of the tile the camera is currently in, in game coordinates.
// x div y = x - (x mod y) // x div y = x - (x mod y)
let tile_center = ( let tile_center = (
global_data.camera_position.xy vec2(global_data.camera_position_x, global_data.camera_position_y)
- ( - (
fmod( fmod(
global_data.camera_position.xy + global_data.starfield_tile_size.x / 2.0, vec2(global_data.camera_position_x, global_data.camera_position_y) +
global_data.starfield_tile_size.x global_data.starfield_tile_size / 2.0,
) - global_data.starfield_tile_size.x / 2.0 global_data.starfield_tile_size
) - global_data.starfield_tile_size / 2.0
) )
); );
let zoom_min_times = ( 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 // Hide n% of the smallest stars
@ -64,8 +65,8 @@ fn vertex_main(
if ( if (
instance.size < ( instance.size < (
hide_fraction * (global_data.starfield_size_limits.y - global_data.starfield_size_limits.x) hide_fraction * (global_data.starfield_size_max - global_data.starfield_size_min)
+ (global_data.starfield_size_limits.x) + (global_data.starfield_size_min)
) )
) { ) {
out.position = vec4<f32>(2.0, 2.0, 0.0, 1.0); 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 // Apply sprite aspect ratio & scale factor
// also applies screen aspect ratio // also applies screen aspect ratio
// Note that we do NOT scale for distance here---this is intentional. // 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 // 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) { if (real_size.x < 2.0 || real_size.y < 2.0) {
// Otherwise, clamp to a minimum scale // 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 // Divide by two, because viewport height is 2 in screen units
// (coordinates go from -1 to 1) // (coordinates go from -1 to 1)
var pos: vec2<f32> = vec2<f32>( 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) vertex.position.y * (scale/2.0)
); );
// World position relative to camera // World position relative to camera
// (Note that instance position is in a different // (Note that instance position is in a different
// coordinate system than usual) // 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 // Translate
pos = pos + ( pos = pos + (
// Don't forget to correct distance for screen aspect ratio too! // Don't forget to correct distance for screen aspect ratio too!
(camera_pos / (global_data.camera_zoom.x * instance.position.z)) (camera_pos / (global_data.camera_zoom * instance.position.z))
/ vec2<f32>(global_data.window_aspect.x, 1.0) / vec2<f32>(global_data.window_aspect, 1.0)
); );
out.position = vec4<f32>(pos, 0.0, 1.0) * instance.position.z; out.position = vec4<f32>(pos, 0.0, 1.0) * instance.position.z;
// Starfield sprites may not be animated // 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_index = u32(t.atlas_texture);
out.texture_coords = vec2(t.xpos, t.ypos); out.texture_coords = vec2(t.xpos, t.ypos);
if vertex.texture_coords.x == 1.0 { if vertex.texture_coords.x == 1.0 {

View File

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

View File

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

View File

@ -22,16 +22,19 @@ impl GlobalUniform {
r#" r#"
var<uniform> global_data: GlobalData; var<uniform> global_data: GlobalData;
struct GlobalData { struct GlobalData {
camera_position: vec2<f32>, camera_position_x: f32,
camera_zoom: vec2<f32>, camera_position_y: f32,
camera_zoom_limits: vec2<f32>, camera_zoom: f32,
window_size: vec2<f32>, camera_zoom_min: f32,
window_scale: vec2<f32>, camera_zoom_max: f32,
window_aspect: vec2<f32>, window_size_w: f32,
starfield_sprite: vec2<u32>, window_size_h: f32,
starfield_tile_size: vec2<f32>, window_scale: f32,
starfield_size_limits: vec2<f32>, window_aspect: f32,
current_time: vec2<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, &self.state.global_uniform.data_buffer,
0, 0,
bytemuck::cast_slice(&[GlobalDataContent { bytemuck::cast_slice(&[GlobalDataContent {
camera_position: input.camera_pos.into(), camera_position_x: input.camera_pos.x,
camera_zoom: [input.camera_zoom, 0.0], camera_position_y: input.camera_pos.y,
camera_zoom_limits: [ camera_zoom: input.camera_zoom,
input.ct.get_config().zoom_min, camera_zoom_min: input.ct.get_config().zoom_min,
input.ct.get_config().zoom_max, camera_zoom_max: input.ct.get_config().zoom_max,
], window_size_w: self.state.window_size.width as f32,
window_size: [ window_size_h: self.state.window_size.height as f32,
self.state.window_size.width as f32, window_scale: self.state.window.scale_factor() as f32,
self.state.window_size.height as f32, window_aspect: self.state.window_aspect,
], starfield_sprite: input.ct.get_config().starfield_texture.into(),
window_scale: [self.state.window.scale_factor() as f32, 0.0], starfield_tile_size: input.ct.get_config().starfield_size,
window_aspect: [self.state.window_aspect, 0.0], starfield_size_min: input.ct.get_config().starfield_min_size,
starfield_sprite: [input.ct.get_config().starfield_texture.into(), 0], starfield_size_max: input.ct.get_config().starfield_max_size,
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],
}]), }]),
); );