From 45bc3d3b4182cc18a850a92238c35a678a98728d Mon Sep 17 00:00:00 2001 From: Mark Date: Mon, 8 Jan 2024 17:57:49 -0800 Subject: [PATCH] Moved UI positioning to shaders --- crates/render/shaders/include/anchor.wgsl | 41 ++++ crates/render/shaders/ui.wgsl | 48 +++-- crates/render/src/anchoredposition.rs | 47 +++++ crates/render/src/gpustate/hud.rs | 224 ++++++++++------------ crates/render/src/gpustate/mod.rs | 77 ++------ crates/render/src/lib.rs | 4 +- crates/render/src/sprite.rs | 79 -------- crates/render/src/vertexbuffer/types.rs | 51 +++-- 8 files changed, 270 insertions(+), 301 deletions(-) create mode 100644 crates/render/shaders/include/anchor.wgsl create mode 100644 crates/render/src/anchoredposition.rs delete mode 100644 crates/render/src/sprite.rs diff --git a/crates/render/shaders/include/anchor.wgsl b/crates/render/shaders/include/anchor.wgsl new file mode 100644 index 0000000..241ffc0 --- /dev/null +++ b/crates/render/shaders/include/anchor.wgsl @@ -0,0 +1,41 @@ +// Given an anchored position and sprite dimensions, +// return the translation that should be applied on +// vertex coordinates +fn anchor( + anchor: u32, // Anchor index + position: vec2, // Anchored position + dim: vec2, // Sprite dimensions (width, height) +) -> vec2 { + + var trans: vec2 = vec2(0.0, 0.0); + let window_dim = global_data.window_size / global_data.window_scale.x; + + if anchor == 0u { // NW C (screen anchor, sprite anchor) + trans += vec2(-window_dim.x, window_dim.y) / 2.0; // origin + trans += vec2(0.0, 0.0) / 2.0; // offset + } else if anchor == 1u { // NW NW + trans += vec2(-window_dim.x, window_dim.y) / 2.0; + trans += vec2(dim.x, -dim.y) / 2.0; + } else if anchor == 2u { // NW NE + trans += vec2(-window_dim.x, window_dim.y) / 2.0; + trans += vec2(-dim.x, -dim.y) / 2.0; + } else if anchor == 3u { // NW SW + trans += vec2(-window_dim.x, window_dim.y) / 2.0; + trans += vec2(dim.x, dim.y) / 2.0; + } else if anchor == 4u { // NW SE + trans += vec2(-window_dim.x, window_dim.y) / 2.0; + trans += vec2(-dim.x, dim.y) / 2.0; + } else if anchor == 5u { // NE NE + trans += vec2(window_dim.x, window_dim.y) / 2.0; + trans += vec2(dim.x, -dim.y) / 2.0; + } else { // center / center as default, since it's the most visible variant. + trans += vec2(0.0, 0.0); + trans += vec2(0.0, 0.0) / 2.0; + } + + trans += position; + + // This renders correctly, but the offsets here are off by a factor of two. + // I'm not sure why... might be because WGPU screen coordinates are -1 to 1. + return (trans / window_dim) * 2.0; +} diff --git a/crates/render/shaders/ui.wgsl b/crates/render/shaders/ui.wgsl index c36512e..d075502 100644 --- a/crates/render/shaders/ui.wgsl +++ b/crates/render/shaders/ui.wgsl @@ -1,10 +1,10 @@ // INCLUDE: global uniform header struct InstanceInput { - @location(2) transform_matrix_0: vec4, - @location(3) transform_matrix_1: vec4, - @location(4) transform_matrix_2: vec4, - @location(5) transform_matrix_3: vec4, + @location(2) anchor: u32, + @location(3) position: vec2, + @location(4) angle: f32, + @location(5) size: f32, @location(6) color_transform: vec4, @location(7) sprite_index: u32, }; @@ -28,7 +28,7 @@ var sampler_array: binding_array; // INCLUDE: animate.wgsl - +// INCLUDE: anchor.wgsl @vertex fn vertex_main( @@ -36,17 +36,43 @@ fn vertex_main( instance: InstanceInput, ) -> VertexOutput { - let transform = mat4x4( - instance.transform_matrix_0, - instance.transform_matrix_1, - instance.transform_matrix_2, - instance.transform_matrix_3, + + let window_dim = global_data.window_size / global_data.window_scale.x; + let scale = instance.size / window_dim.y; + let sprite_aspect = global_sprites[instance.sprite_index].aspect; + + // Apply scale and sprite aspect + // Note that our mesh starts centered at (0, 0). This is important! + var pos: vec2 = vec2( + vertex.position.x * scale * sprite_aspect, + vertex.position.y * scale + ); + + // Apply rotation + pos = mat2x2( + vec2(cos(instance.angle), sin(instance.angle)), + vec2(-sin(instance.angle), cos(instance.angle)) + ) * pos; + + // Correct for screen aspect, preserving height + pos = vec2( + pos.x / global_data.window_aspect.x, + pos.y + ); + + pos = pos + anchor( + instance.anchor, + instance.position, + vec2(instance.size * sprite_aspect, instance.size) ); var out: VertexOutput; - out.position = transform * vec4(vertex.position, 1.0); + out.position = vec4(pos, 1.0, 1.0); out.color_transform = instance.color_transform; + + + // TODO: animate // Pick texture frame let t = global_atlas[u32(animate(instance.sprite_index, global_data.current_time.x, 0.0))]; out.texture_index = u32(t.atlas_texture); diff --git a/crates/render/src/anchoredposition.rs b/crates/render/src/anchoredposition.rs new file mode 100644 index 0000000..08a2922 --- /dev/null +++ b/crates/render/src/anchoredposition.rs @@ -0,0 +1,47 @@ +/// The location of a UI element, in one of a few +/// possible coordinate systems. +/// +/// Positive Y always points up, +/// positive X always points right. +#[derive(Debug, Clone)] +pub enum PositionAnchor { + /// Position of this sprite's center, + /// relative to the nw corner of the window. + NwC, + + /// Position of this sprite's nw corner, + /// relative to the nw corner of the window. + NwNw, + + /// Position of this sprite's ne corner, + /// relative to the nw corner of the window. + NwNe, + + /// Position of this sprite's sw corner, + /// relative to the nw corner of the window. + NwSw, + + /// Position of this sprite's se corner, + /// relative to the nw corner of the window. + NwSe, + + /// Position of this sprite's ne corner, + /// relative to the ne corner of the window. + NeNe, +} + +// These offsets are implemented in wgsl shaders. + +impl PositionAnchor { + /// Get the uint that represents this anchor mode in shaders + pub fn to_int(&self) -> u32 { + match self { + Self::NwC => 0, + Self::NwNw => 1, + Self::NwNe => 2, + Self::NwSw => 3, + Self::NwSe => 4, + Self::NeNe => 5, + } + } +} diff --git a/crates/render/src/gpustate/hud.rs b/crates/render/src/gpustate/hud.rs index 205b322..a50b883 100644 --- a/crates/render/src/gpustate/hud.rs +++ b/crates/render/src/gpustate/hud.rs @@ -1,11 +1,9 @@ //! GPUState routines for drawing HUD elements -use cgmath::{Deg, InnerSpace, Point2, Vector2}; +use cgmath::{Deg, InnerSpace, Point2, Rad, Vector2}; use galactica_world::util; -use crate::{ - sprite::UiSprite, vertexbuffer::types::UiInstance, AnchoredUiPosition, GPUState, RenderState, -}; +use crate::{vertexbuffer::types::UiInstance, GPUState, PositionAnchor, RenderState}; impl GPUState { pub(super) fn hud_add_radar(&mut self, state: &RenderState, instances: &mut Vec) { @@ -14,7 +12,7 @@ impl GPUState { let hide_range = 0.85; let shrink_distance = 20.0; //let system_object_scale = 1.0 / 600.0; - let ship_scale = 1.0 / 15.0; + let ship_scale = 1.0 / 10.0; let (_, player_body) = state.world.get_ship_body(*state.player).unwrap(); let player_position = util::rigidbody_position(player_body); @@ -22,33 +20,23 @@ impl GPUState { let ship_sprite = state.content.get_sprite_handle("ui::shipblip"); let arrow_sprite = state.content.get_sprite_handle("ui::centerarrow"); - self.push_ui_sprite( - instances, - &UiSprite { - sprite: state.content.get_sprite_handle("ui::status"), - pos: AnchoredUiPosition::NeNe(Point2 { x: -10.0, y: -10.0 }), - dimensions: Point2 { - x: radar_size, - y: radar_size, - }, - angle: Deg(0.0), - color: None, - }, - ); + instances.push(UiInstance { + anchor: PositionAnchor::NeNe.to_int(), + position: [0.0, 0.0], + angle: 0.0, + size: radar_size, + color: [1.0, 1.0, 1.0, 1.0], + sprite_index: state.content.get_sprite_handle("ui::status").get_index(), + }); - self.push_ui_sprite( - instances, - &UiSprite { - sprite: state.content.get_sprite_handle("ui::radar"), - pos: AnchoredUiPosition::NwNw(Point2 { x: 10.0, y: -10.0 }), - dimensions: Point2 { - x: radar_size, - y: radar_size, - }, - angle: Deg(0.0), - color: None, - }, - ); + instances.push(UiInstance { + anchor: PositionAnchor::NwNw.to_int(), + position: [10.0, -10.0], + angle: 0.0, + size: radar_size, + color: [1.0, 1.0, 1.0, 1.0], + sprite_index: state.content.get_sprite_handle("ui::radar").get_index(), + }); /* // Draw system objects @@ -104,24 +92,20 @@ impl GPUState { .into(); let f = state.content.get_faction(s.ship.faction).color; let f = [f[0], f[1], f[2], 1.0]; - self.push_ui_sprite( - instances, - &UiSprite { - sprite: ship_sprite, - pos: AnchoredUiPosition::NwC( - Point2 { - x: radar_size / 2.0 + 10.0, - y: radar_size / -2.0 - 10.0, - } + (d * (radar_size / 2.0)), - ), - dimensions: Point2 { - x: ship_sprite.aspect, - y: 1.0, - } * size, - angle: -angle, - color: Some(f), - }, - ); + + let position = Point2 { + x: radar_size / 2.0 + 10.0, + y: radar_size / -2.0 - 10.0, + } + (d * (radar_size / 2.0)); + + instances.push(UiInstance { + anchor: PositionAnchor::NwC.to_int(), + position: position.into(), + angle: -Rad::from(angle).0, // TODO: consistent angles + size, + color: f.into(), + sprite_index: ship_sprite.get_index(), + }); } } @@ -132,93 +116,83 @@ impl GPUState { } / radar_range; let m = d.magnitude(); let d = d * (radar_size / 2.0); - let color = Some([0.3, 0.3, 0.3, 1.0]); + let color = [0.3, 0.3, 0.3, 1.0]; if m < 0.8 { let sprite = state.content.get_sprite_handle("ui::radarframe"); - let dimensions = Point2 { - x: sprite.aspect, - y: 1.0, - } * 7.0f32.min((0.8 - m) * 70.0); - self.push_ui_sprite( - instances, - &UiSprite { - sprite, - pos: AnchoredUiPosition::NwNw(Point2 { - x: (radar_size / 2.0 + 10.0) - d.x, - y: (radar_size / -2.0 - 10.0) + d.y, - }), - dimensions, - angle: Deg(0.0), - color, - }, - ); + let size = 7.0f32.min((0.8 - m) * 70.0); - self.push_ui_sprite( - instances, - &UiSprite { - sprite, - pos: AnchoredUiPosition::NwSw(Point2 { - x: (radar_size / 2.0 + 10.0) - d.x, - y: (radar_size / -2.0 - 10.0) - d.y, - }), - dimensions, - angle: Deg(90.0), - color, - }, - ); + instances.push(UiInstance { + anchor: PositionAnchor::NwNw.to_int(), + position: Point2 { + x: (radar_size / 2.0 + 10.0) - d.x, + y: (radar_size / -2.0 - 10.0) + d.y, + } + .into(), + angle: 0.0, + size, + color, + sprite_index: sprite.get_index(), + }); - self.push_ui_sprite( - instances, - &UiSprite { - sprite, - pos: AnchoredUiPosition::NwSe(Point2 { - x: (radar_size / 2.0 + 10.0) + d.x, - y: (radar_size / -2.0 - 10.0) - d.y, - }), - dimensions, - angle: Deg(180.0), - color, - }, - ); + instances.push(UiInstance { + anchor: PositionAnchor::NwSw.to_int(), + position: Point2 { + x: (radar_size / 2.0 + 10.0) - d.x, + y: (radar_size / -2.0 - 10.0) - d.y, + } + .into(), + angle: Rad::from(Deg(90.0)).0, + size, + color, + sprite_index: sprite.get_index(), + }); - self.push_ui_sprite( - instances, - &UiSprite { - sprite, - pos: AnchoredUiPosition::NwNe(Point2 { - x: (radar_size / 2.0 + 10.0) + d.x, - y: (radar_size / -2.0 - 10.0) + d.y, - }), - dimensions, - angle: Deg(270.0), - color, - }, - ); + instances.push(UiInstance { + anchor: PositionAnchor::NwSe.to_int(), + position: Point2 { + x: (radar_size / 2.0 + 10.0) + d.x, + y: (radar_size / -2.0 - 10.0) - d.y, + } + .into(), + angle: Rad::from(Deg(180.0)).0, + size, + color, + sprite_index: sprite.get_index(), + }); + + instances.push(UiInstance { + anchor: PositionAnchor::NwNe.to_int(), + position: Point2 { + x: (radar_size / 2.0 + 10.0) + d.x, + y: (radar_size / -2.0 - 10.0) + d.y, + } + .into(), + angle: Rad::from(Deg(270.0)).0, + size, + color, + sprite_index: sprite.get_index(), + }); } // Arrow to center of system let q = Point2 { x: 0.0, y: 0.0 } - player_position; let m = q.magnitude(); if m > 200.0 { - let player_angle: Deg = q.angle(Vector2 { x: 0.0, y: 1.0 }).into(); - self.push_ui_sprite( - instances, - &UiSprite { - sprite: arrow_sprite, - pos: AnchoredUiPosition::NwC( - Point2 { - x: radar_size / 2.0 + 10.0, - y: radar_size / -2.0 - 10.0, - } + ((q.normalize() * 0.865) * (radar_size / 2.0)), - ), - dimensions: Point2 { - x: arrow_sprite.aspect, - y: 1.0, - } * 10.0, - angle: -player_angle, - color: Some([1.0, 1.0, 1.0, 1f32.min((m - 200.0) / 400.0)]), - }, - ); + let player_angle = q.angle(Vector2 { x: 0.0, y: 1.0 }); + + let position: Point2 = Point2 { + x: radar_size / 2.0 + 10.0, + y: radar_size / -2.0 - 10.0, + } + ((q.normalize() * 0.865) * (radar_size / 2.0)); + + instances.push(UiInstance { + anchor: PositionAnchor::NwC.to_int(), + position: position.into(), + angle: -player_angle.0, + size: 10.0, + color: [1.0, 1.0, 1.0, 1f32.min((m - 200.0) / 400.0)], + sprite_index: arrow_sprite.get_index(), + }); } } } diff --git a/crates/render/src/gpustate/mod.rs b/crates/render/src/gpustate/mod.rs index ea6ee63..09af7eb 100644 --- a/crates/render/src/gpustate/mod.rs +++ b/crates/render/src/gpustate/mod.rs @@ -1,18 +1,17 @@ use anyhow::Result; use bytemuck; -use cgmath::{Matrix4, Point2, Vector3}; +use cgmath::Point2; use galactica_constants; use rand::seq::SliceRandom; use std::{iter, rc::Rc}; use wgpu; -use winit::{self, dpi::LogicalSize, window::Window}; +use winit::{self, window::Window}; use crate::{ content, globaluniform::{GlobalDataContent, GlobalUniform}, pipeline::PipelineBuilder, - sprite::UiSprite, starfield::Starfield, texturearray::TextureArray, vertexbuffer::{ @@ -23,7 +22,7 @@ use crate::{ }, BufferObject, VertexBuffer, }, - RenderState, OPENGL_TO_WGPU_MATRIX, + RenderState, }; // Additional implementaitons for GPUState @@ -94,6 +93,15 @@ fn preprocess_shader( )), ); + let shader = shader.replace( + "// INCLUDE: anchor.wgsl", + &include_str!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/shaders/include/", + "anchor.wgsl" + )), + ); + return shader; } @@ -337,65 +345,6 @@ impl GPUState { self.update_starfield_buffer() } - // TODO:remove - /// Create a UiInstance for a ui sprite and add it to `instances` - fn push_ui_sprite(&self, instances: &mut Vec, s: &UiSprite) { - let logical_size: LogicalSize = - self.window_size.to_logical(self.window.scale_factor()); - - let width = s.dimensions.x; - let height = s.dimensions.y; - - // Compute square scale, since we must apply screen aspect ratio - // AFTER rotation. - let scale = Matrix4::from_nonuniform_scale( - width / logical_size.height, - height / logical_size.height, - 1.0, - ); - let rotate = Matrix4::from_angle_z(s.angle); - let translate = Matrix4::from_translation(match s.pos { - super::AnchoredUiPosition::NwC(p) => Vector3 { - // Note the signs. Positive y points north! - x: -1.0 + p.x / (logical_size.width / 2.0), - y: 1.0 + p.y / (logical_size.height / 2.0), - z: 0.0, - }, - super::AnchoredUiPosition::NwNw(p) => Vector3 { - x: -1.0 + (width / 2.0 + p.x) / (logical_size.width / 2.0), - y: 1.0 - (height / 2.0 - p.y) / (logical_size.height / 2.0), - z: 0.0, - }, - super::AnchoredUiPosition::NwNe(p) => Vector3 { - x: -1.0 - (width / 2.0 - p.x) / (logical_size.width / 2.0), - y: 1.0 - (height / 2.0 - p.y) / (logical_size.height / 2.0), - z: 0.0, - }, - super::AnchoredUiPosition::NwSw(p) => Vector3 { - x: -1.0 + (width / 2.0 + p.x) / (logical_size.width / 2.0), - y: 1.0 + (height / 2.0 + p.y) / (logical_size.height / 2.0), - z: 0.0, - }, - super::AnchoredUiPosition::NwSe(p) => Vector3 { - x: -1.0 - (width / 2.0 - p.x) / (logical_size.width / 2.0), - y: 1.0 + (height / 2.0 + p.y) / (logical_size.height / 2.0), - z: 0.0, - }, - super::AnchoredUiPosition::NeNe(p) => Vector3 { - x: 1.0 - (width / 2.0 - p.x) / (logical_size.width / 2.0), - y: 1.0 - (height / 2.0 - p.y) / (logical_size.height / 2.0), - z: 0.0, - }, - }); - let screen_aspect = Matrix4::from_nonuniform_scale(1.0 / self.window_aspect, 1.0, 1.0); - - instances.push(UiInstance { - transform: (OPENGL_TO_WGPU_MATRIX * translate * screen_aspect * rotate * scale).into(), - sprite_index: s.sprite.get_index(), - color: s.color.unwrap_or([1.0, 1.0, 1.0, 1.0]), - }); - } - /// Make an instance for all the game's sprites /// (Objects and UI) /// This will Will panic if any X_SPRITE_INSTANCE_LIMIT is exceeded. @@ -637,7 +586,7 @@ impl GPUState { ]), );*/ - // Ui pipeline + // Radial progress bar // TODO: do we need to do this every time? self.vertex_buffers.radialbar.set_in_pass(&mut render_pass); render_pass.set_pipeline(&self.radialbar_pipeline); diff --git a/crates/render/src/lib.rs b/crates/render/src/lib.rs index 4b45039..42151c3 100644 --- a/crates/render/src/lib.rs +++ b/crates/render/src/lib.rs @@ -7,19 +7,19 @@ //! and the only one external code should interact with. //! (Excluding data structs, like [`ObjectSprite`]) +mod anchoredposition; mod globaluniform; mod gpustate; mod pipeline; mod renderstate; -mod sprite; mod starfield; mod texturearray; mod vertexbuffer; +pub use anchoredposition::PositionAnchor; use galactica_content as content; pub use gpustate::GPUState; pub use renderstate::RenderState; -pub use sprite::AnchoredUiPosition; use cgmath::Matrix4; diff --git a/crates/render/src/sprite.rs b/crates/render/src/sprite.rs deleted file mode 100644 index ada0dce..0000000 --- a/crates/render/src/sprite.rs +++ /dev/null @@ -1,79 +0,0 @@ -use crate::content; -use cgmath::{Deg, Point2}; - -/// The location of a UI element, in one of a few -/// possible coordinate systems. -/// -/// Positive Y always points up, -/// positive X always points right. -#[derive(Debug, Clone)] -pub enum AnchoredUiPosition { - /// Position of this sprite's center, - /// relative to the nw corner of the window. - NwC(Point2), - - /// Position of this sprite's nw corner, - /// relative to the nw corner of the window. - NwNw(Point2), - - /// Position of this sprite's ne corner, - /// relative to the nw corner of the window. - NwNe(Point2), - - /// Position of this sprite's sw corner, - /// relative to the nw corner of the window. - NwSw(Point2), - - /// Position of this sprite's se corner, - /// relative to the nw corner of the window. - NwSe(Point2), - - /// Position of this sprite's ne corner, - /// relative to the ne corner of the window. - NeNe(Point2), -} - -impl AnchoredUiPosition { - pub fn to_anchor_int(&self) -> u32 { - match self { - Self::NwC(_) => 0, - Self::NwNw(_) => 1, - Self::NwNe(_) => 2, - Self::NwSw(_) => 3, - Self::NwSe(_) => 4, - Self::NeNe(_) => 5, - } - } - - pub fn position(&self) -> &Point2 { - match self { - Self::NwC(x) - | Self::NwNw(x) - | Self::NwNe(x) - | Self::NwSw(x) - | Self::NwSe(x) - | Self::NeNe(x) => x, - } - } -} - -// TODO: remove -/// A sprite that represents a ui element -#[derive(Debug, Clone)] -pub struct UiSprite { - /// The sprite to draw - pub sprite: content::SpriteHandle, - - /// This object's position, in logical (dpi-adjusted) pixels - pub pos: AnchoredUiPosition, - - /// This sprite's color will be multiplied by this value. - /// If this is None, color will not be changed. - pub color: Option<[f32; 4]>, - - /// The size of this sprite, in logical (dpi-adjusted) pixels - pub dimensions: Point2, - - /// This sprite's rotation, measured ccw - pub angle: Deg, -} diff --git a/crates/render/src/vertexbuffer/types.rs b/crates/render/src/vertexbuffer/types.rs index 3611b4f..0551340 100644 --- a/crates/render/src/vertexbuffer/types.rs +++ b/crates/render/src/vertexbuffer/types.rs @@ -120,10 +120,18 @@ impl BufferObject for ObjectInstance { #[repr(C)] #[derive(Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)] pub struct UiInstance { - /// Extra transformations this sprite - /// (rotation, etc) - /// TODO: remove - pub transform: [[f32; 4]; 4], + /// How to interpret this object's coordinates. + /// this should be generated from an AnchoredUiPosition + pub anchor: u32, + + /// Position of this object in logical pixels + pub position: [f32; 2], + + /// The angle of this sprite, in radians + pub angle: f32, + + /// The height of this sprite, in logical pixels + pub size: f32, /// This lets us color ui sprites dynamically. /// Each fragment's color is multiplied by this value. @@ -143,36 +151,39 @@ impl BufferObject for UiInstance { // instance when the shader starts processing a new instance step_mode: wgpu::VertexStepMode::Instance, attributes: &[ - // 4 arrays = 1 4x4 matrix + // Anchor wgpu::VertexAttribute { offset: 0, shader_location: 2, - format: wgpu::VertexFormat::Float32x4, + format: wgpu::VertexFormat::Uint32, }, + // Position + wgpu::VertexAttribute { + offset: mem::size_of::<[f32; 1]>() as wgpu::BufferAddress, + shader_location: 3, + format: wgpu::VertexFormat::Float32x2, + }, + // Angle + wgpu::VertexAttribute { + offset: mem::size_of::<[f32; 3]>() as wgpu::BufferAddress, + shader_location: 4, + format: wgpu::VertexFormat::Float32, + }, + // Size wgpu::VertexAttribute { offset: mem::size_of::<[f32; 4]>() as wgpu::BufferAddress, - shader_location: 3, - format: wgpu::VertexFormat::Float32x4, - }, - wgpu::VertexAttribute { - offset: mem::size_of::<[f32; 8]>() as wgpu::BufferAddress, - shader_location: 4, - format: wgpu::VertexFormat::Float32x4, - }, - wgpu::VertexAttribute { - offset: mem::size_of::<[f32; 12]>() as wgpu::BufferAddress, shader_location: 5, - format: wgpu::VertexFormat::Float32x4, + format: wgpu::VertexFormat::Float32, }, // Color wgpu::VertexAttribute { - offset: mem::size_of::<[f32; 16]>() as wgpu::BufferAddress, + offset: mem::size_of::<[f32; 5]>() as wgpu::BufferAddress, shader_location: 6, format: wgpu::VertexFormat::Float32x4, }, // Sprite wgpu::VertexAttribute { - offset: mem::size_of::<[f32; 20]>() as wgpu::BufferAddress, + offset: mem::size_of::<[f32; 9]>() as wgpu::BufferAddress, shader_location: 7, format: wgpu::VertexFormat::Uint32, }, @@ -286,7 +297,7 @@ pub struct RadialBarInstance { /// this should be generated from an AnchoredUiPosition pub anchor: u32, - /// Position of this particle in logical pixels + /// Position of this object in logical pixels pub position: [f32; 2], /// The diameter of this bar, in logical pixels