Compare commits

..

No commits in common. "45bc3d3b4182cc18a850a92238c35a678a98728d" and "f1dba0978e45b199f69df87a4a4133f9828aaec4" have entirely different histories.

9 changed files with 301 additions and 271 deletions

View File

@ -16,7 +16,6 @@
- Higher texture limit (16 x 8096 x 8096 isn't enough) - Higher texture limit (16 x 8096 x 8096 isn't enough)
- GPU limits? (texture size, texture number) - GPU limits? (texture size, texture number)
- Particles when a ship is damaged (events) - Particles when a ship is damaged (events)
- Sticky radar
---------------------------------- ----------------------------------

View File

@ -1,41 +0,0 @@
// 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<f32>, // Anchored position
dim: vec2<f32>, // Sprite dimensions (width, height)
) -> vec2<f32> {
var trans: vec2<f32> = 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;
}

View File

@ -1,10 +1,10 @@
// INCLUDE: global uniform header // INCLUDE: global uniform header
struct InstanceInput { struct InstanceInput {
@location(2) anchor: u32, @location(2) transform_matrix_0: vec4<f32>,
@location(3) position: vec2<f32>, @location(3) transform_matrix_1: vec4<f32>,
@location(4) angle: f32, @location(4) transform_matrix_2: vec4<f32>,
@location(5) size: f32, @location(5) transform_matrix_3: vec4<f32>,
@location(6) color_transform: vec4<f32>, @location(6) color_transform: vec4<f32>,
@location(7) sprite_index: u32, @location(7) sprite_index: u32,
}; };
@ -28,7 +28,7 @@ var sampler_array: binding_array<sampler>;
// INCLUDE: animate.wgsl // INCLUDE: animate.wgsl
// INCLUDE: anchor.wgsl
@vertex @vertex
fn vertex_main( fn vertex_main(
@ -36,43 +36,17 @@ fn vertex_main(
instance: InstanceInput, instance: InstanceInput,
) -> VertexOutput { ) -> VertexOutput {
let transform = mat4x4<f32>(
let window_dim = global_data.window_size / global_data.window_scale.x; instance.transform_matrix_0,
let scale = instance.size / window_dim.y; instance.transform_matrix_1,
let sprite_aspect = global_sprites[instance.sprite_index].aspect; instance.transform_matrix_2,
instance.transform_matrix_3,
// Apply scale and sprite aspect
// Note that our mesh starts centered at (0, 0). This is important!
var pos: vec2<f32> = 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; var out: VertexOutput;
out.position = vec4<f32>(pos, 1.0, 1.0); out.position = transform * vec4<f32>(vertex.position, 1.0);
out.color_transform = instance.color_transform; out.color_transform = instance.color_transform;
// TODO: animate
// 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);

View File

@ -1,47 +0,0 @@
/// 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,
}
}
}

View File

@ -1,9 +1,11 @@
//! GPUState routines for drawing HUD elements //! GPUState routines for drawing HUD elements
use cgmath::{Deg, InnerSpace, Point2, Rad, Vector2}; use cgmath::{Deg, InnerSpace, Point2, Vector2};
use galactica_world::util; use galactica_world::util;
use crate::{vertexbuffer::types::UiInstance, GPUState, PositionAnchor, RenderState}; use crate::{
sprite::UiSprite, vertexbuffer::types::UiInstance, AnchoredUiPosition, GPUState, RenderState,
};
impl GPUState { impl GPUState {
pub(super) fn hud_add_radar(&mut self, state: &RenderState, instances: &mut Vec<UiInstance>) { pub(super) fn hud_add_radar(&mut self, state: &RenderState, instances: &mut Vec<UiInstance>) {
@ -12,7 +14,7 @@ impl GPUState {
let hide_range = 0.85; let hide_range = 0.85;
let shrink_distance = 20.0; let shrink_distance = 20.0;
//let system_object_scale = 1.0 / 600.0; //let system_object_scale = 1.0 / 600.0;
let ship_scale = 1.0 / 10.0; let ship_scale = 1.0 / 15.0;
let (_, player_body) = state.world.get_ship_body(*state.player).unwrap(); let (_, player_body) = state.world.get_ship_body(*state.player).unwrap();
let player_position = util::rigidbody_position(player_body); let player_position = util::rigidbody_position(player_body);
@ -20,23 +22,33 @@ impl GPUState {
let ship_sprite = state.content.get_sprite_handle("ui::shipblip"); let ship_sprite = state.content.get_sprite_handle("ui::shipblip");
let arrow_sprite = state.content.get_sprite_handle("ui::centerarrow"); let arrow_sprite = state.content.get_sprite_handle("ui::centerarrow");
instances.push(UiInstance { self.push_ui_sprite(
anchor: PositionAnchor::NeNe.to_int(), instances,
position: [0.0, 0.0], &UiSprite {
angle: 0.0, sprite: state.content.get_sprite_handle("ui::status"),
size: radar_size, pos: AnchoredUiPosition::NeNe(Point2 { x: -10.0, y: -10.0 }),
color: [1.0, 1.0, 1.0, 1.0], dimensions: Point2 {
sprite_index: state.content.get_sprite_handle("ui::status").get_index(), x: radar_size,
}); y: radar_size,
},
angle: Deg(0.0),
color: None,
},
);
instances.push(UiInstance { self.push_ui_sprite(
anchor: PositionAnchor::NwNw.to_int(), instances,
position: [10.0, -10.0], &UiSprite {
angle: 0.0, sprite: state.content.get_sprite_handle("ui::radar"),
size: radar_size, pos: AnchoredUiPosition::NwNw(Point2 { x: 10.0, y: -10.0 }),
color: [1.0, 1.0, 1.0, 1.0], dimensions: Point2 {
sprite_index: state.content.get_sprite_handle("ui::radar").get_index(), x: radar_size,
}); y: radar_size,
},
angle: Deg(0.0),
color: None,
},
);
/* /*
// Draw system objects // Draw system objects
@ -92,20 +104,24 @@ impl GPUState {
.into(); .into();
let f = state.content.get_faction(s.ship.faction).color; let f = state.content.get_faction(s.ship.faction).color;
let f = [f[0], f[1], f[2], 1.0]; let f = [f[0], f[1], f[2], 1.0];
self.push_ui_sprite(
let position = Point2 { instances,
x: radar_size / 2.0 + 10.0, &UiSprite {
y: radar_size / -2.0 - 10.0, sprite: ship_sprite,
} + (d * (radar_size / 2.0)); pos: AnchoredUiPosition::NwC(
Point2 {
instances.push(UiInstance { x: radar_size / 2.0 + 10.0,
anchor: PositionAnchor::NwC.to_int(), y: radar_size / -2.0 - 10.0,
position: position.into(), } + (d * (radar_size / 2.0)),
angle: -Rad::from(angle).0, // TODO: consistent angles ),
size, dimensions: Point2 {
color: f.into(), x: ship_sprite.aspect,
sprite_index: ship_sprite.get_index(), y: 1.0,
}); } * size,
angle: -angle,
color: Some(f),
},
);
} }
} }
@ -116,83 +132,93 @@ impl GPUState {
} / radar_range; } / radar_range;
let m = d.magnitude(); let m = d.magnitude();
let d = d * (radar_size / 2.0); let d = d * (radar_size / 2.0);
let color = [0.3, 0.3, 0.3, 1.0]; let color = Some([0.3, 0.3, 0.3, 1.0]);
if m < 0.8 { if m < 0.8 {
let sprite = state.content.get_sprite_handle("ui::radarframe"); let sprite = state.content.get_sprite_handle("ui::radarframe");
let size = 7.0f32.min((0.8 - m) * 70.0); 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,
},
);
instances.push(UiInstance { self.push_ui_sprite(
anchor: PositionAnchor::NwNw.to_int(), instances,
position: Point2 { &UiSprite {
x: (radar_size / 2.0 + 10.0) - d.x, sprite,
y: (radar_size / -2.0 - 10.0) + d.y, pos: AnchoredUiPosition::NwSw(Point2 {
} x: (radar_size / 2.0 + 10.0) - d.x,
.into(), y: (radar_size / -2.0 - 10.0) - d.y,
angle: 0.0, }),
size, dimensions,
color, angle: Deg(90.0),
sprite_index: sprite.get_index(), color,
}); },
);
instances.push(UiInstance { self.push_ui_sprite(
anchor: PositionAnchor::NwSw.to_int(), instances,
position: Point2 { &UiSprite {
x: (radar_size / 2.0 + 10.0) - d.x, sprite,
y: (radar_size / -2.0 - 10.0) - d.y, pos: AnchoredUiPosition::NwSe(Point2 {
} x: (radar_size / 2.0 + 10.0) + d.x,
.into(), y: (radar_size / -2.0 - 10.0) - d.y,
angle: Rad::from(Deg(90.0)).0, }),
size, dimensions,
color, angle: Deg(180.0),
sprite_index: sprite.get_index(), color,
}); },
);
instances.push(UiInstance { self.push_ui_sprite(
anchor: PositionAnchor::NwSe.to_int(), instances,
position: Point2 { &UiSprite {
x: (radar_size / 2.0 + 10.0) + d.x, sprite,
y: (radar_size / -2.0 - 10.0) - d.y, pos: AnchoredUiPosition::NwNe(Point2 {
} x: (radar_size / 2.0 + 10.0) + d.x,
.into(), y: (radar_size / -2.0 - 10.0) + d.y,
angle: Rad::from(Deg(180.0)).0, }),
size, dimensions,
color, angle: Deg(270.0),
sprite_index: sprite.get_index(), color,
}); },
);
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 // Arrow to center of system
let q = Point2 { x: 0.0, y: 0.0 } - player_position; let q = Point2 { x: 0.0, y: 0.0 } - player_position;
let m = q.magnitude(); let m = q.magnitude();
if m > 200.0 { if m > 200.0 {
let player_angle = q.angle(Vector2 { x: 0.0, y: 1.0 }); let player_angle: Deg<f32> = q.angle(Vector2 { x: 0.0, y: 1.0 }).into();
self.push_ui_sprite(
let position: Point2<f32> = Point2 { instances,
x: radar_size / 2.0 + 10.0, &UiSprite {
y: radar_size / -2.0 - 10.0, sprite: arrow_sprite,
} + ((q.normalize() * 0.865) * (radar_size / 2.0)); pos: AnchoredUiPosition::NwC(
Point2 {
instances.push(UiInstance { x: radar_size / 2.0 + 10.0,
anchor: PositionAnchor::NwC.to_int(), y: radar_size / -2.0 - 10.0,
position: position.into(), } + ((q.normalize() * 0.865) * (radar_size / 2.0)),
angle: -player_angle.0, ),
size: 10.0, dimensions: Point2 {
color: [1.0, 1.0, 1.0, 1f32.min((m - 200.0) / 400.0)], x: arrow_sprite.aspect,
sprite_index: arrow_sprite.get_index(), y: 1.0,
}); } * 10.0,
angle: -player_angle,
color: Some([1.0, 1.0, 1.0, 1f32.min((m - 200.0) / 400.0)]),
},
);
} }
} }
} }

View File

@ -1,17 +1,18 @@
use anyhow::Result; use anyhow::Result;
use bytemuck; use bytemuck;
use cgmath::Point2; use cgmath::{Matrix4, Point2, Vector3};
use galactica_constants; use galactica_constants;
use rand::seq::SliceRandom; use rand::seq::SliceRandom;
use std::{iter, rc::Rc}; use std::{iter, rc::Rc};
use wgpu; use wgpu;
use winit::{self, window::Window}; use winit::{self, dpi::LogicalSize, window::Window};
use crate::{ use crate::{
content, content,
globaluniform::{GlobalDataContent, GlobalUniform}, globaluniform::{GlobalDataContent, GlobalUniform},
pipeline::PipelineBuilder, pipeline::PipelineBuilder,
sprite::UiSprite,
starfield::Starfield, starfield::Starfield,
texturearray::TextureArray, texturearray::TextureArray,
vertexbuffer::{ vertexbuffer::{
@ -22,7 +23,7 @@ use crate::{
}, },
BufferObject, VertexBuffer, BufferObject, VertexBuffer,
}, },
RenderState, RenderState, OPENGL_TO_WGPU_MATRIX,
}; };
// Additional implementaitons for GPUState // Additional implementaitons for GPUState
@ -93,15 +94,6 @@ fn preprocess_shader(
)), )),
); );
let shader = shader.replace(
"// INCLUDE: anchor.wgsl",
&include_str!(concat!(
env!("CARGO_MANIFEST_DIR"),
"/shaders/include/",
"anchor.wgsl"
)),
);
return shader; return shader;
} }
@ -345,6 +337,65 @@ impl GPUState {
self.update_starfield_buffer() 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<UiInstance>, s: &UiSprite) {
let logical_size: LogicalSize<f32> =
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 /// Make an instance for all the game's sprites
/// (Objects and UI) /// (Objects and UI)
/// This will Will panic if any X_SPRITE_INSTANCE_LIMIT is exceeded. /// This will Will panic if any X_SPRITE_INSTANCE_LIMIT is exceeded.
@ -586,7 +637,7 @@ impl GPUState {
]), ]),
);*/ );*/
// Radial progress bar // Ui pipeline
// TODO: do we need to do this every time? // TODO: do we need to do this every time?
self.vertex_buffers.radialbar.set_in_pass(&mut render_pass); self.vertex_buffers.radialbar.set_in_pass(&mut render_pass);
render_pass.set_pipeline(&self.radialbar_pipeline); render_pass.set_pipeline(&self.radialbar_pipeline);

View File

@ -7,19 +7,19 @@
//! and the only one external code should interact with. //! and the only one external code should interact with.
//! (Excluding data structs, like [`ObjectSprite`]) //! (Excluding data structs, like [`ObjectSprite`])
mod anchoredposition;
mod globaluniform; mod globaluniform;
mod gpustate; mod gpustate;
mod pipeline; mod pipeline;
mod renderstate; mod renderstate;
mod sprite;
mod starfield; mod starfield;
mod texturearray; mod texturearray;
mod vertexbuffer; mod vertexbuffer;
pub use anchoredposition::PositionAnchor;
use galactica_content as content; use galactica_content as content;
pub use gpustate::GPUState; pub use gpustate::GPUState;
pub use renderstate::RenderState; pub use renderstate::RenderState;
pub use sprite::AnchoredUiPosition;
use cgmath::Matrix4; use cgmath::Matrix4;

View File

@ -0,0 +1,79 @@
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<f32>),
/// Position of this sprite's nw corner,
/// relative to the nw corner of the window.
NwNw(Point2<f32>),
/// Position of this sprite's ne corner,
/// relative to the nw corner of the window.
NwNe(Point2<f32>),
/// Position of this sprite's sw corner,
/// relative to the nw corner of the window.
NwSw(Point2<f32>),
/// Position of this sprite's se corner,
/// relative to the nw corner of the window.
NwSe(Point2<f32>),
/// Position of this sprite's ne corner,
/// relative to the ne corner of the window.
NeNe(Point2<f32>),
}
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<f32> {
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<f32>,
/// This sprite's rotation, measured ccw
pub angle: Deg<f32>,
}

View File

@ -120,18 +120,10 @@ impl BufferObject for ObjectInstance {
#[repr(C)] #[repr(C)]
#[derive(Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)] #[derive(Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)]
pub struct UiInstance { pub struct UiInstance {
/// How to interpret this object's coordinates. /// Extra transformations this sprite
/// this should be generated from an AnchoredUiPosition /// (rotation, etc)
pub anchor: u32, /// TODO: remove
pub transform: [[f32; 4]; 4],
/// 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. /// This lets us color ui sprites dynamically.
/// Each fragment's color is multiplied by this value. /// Each fragment's color is multiplied by this value.
@ -151,39 +143,36 @@ impl BufferObject for UiInstance {
// instance when the shader starts processing a new instance // instance when the shader starts processing a new instance
step_mode: wgpu::VertexStepMode::Instance, step_mode: wgpu::VertexStepMode::Instance,
attributes: &[ attributes: &[
// Anchor // 4 arrays = 1 4x4 matrix
wgpu::VertexAttribute { wgpu::VertexAttribute {
offset: 0, offset: 0,
shader_location: 2, shader_location: 2,
format: wgpu::VertexFormat::Uint32, format: wgpu::VertexFormat::Float32x4,
}, },
// 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 { wgpu::VertexAttribute {
offset: mem::size_of::<[f32; 4]>() as wgpu::BufferAddress, 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, shader_location: 5,
format: wgpu::VertexFormat::Float32, format: wgpu::VertexFormat::Float32x4,
}, },
// Color // Color
wgpu::VertexAttribute { wgpu::VertexAttribute {
offset: mem::size_of::<[f32; 5]>() as wgpu::BufferAddress, offset: mem::size_of::<[f32; 16]>() as wgpu::BufferAddress,
shader_location: 6, shader_location: 6,
format: wgpu::VertexFormat::Float32x4, format: wgpu::VertexFormat::Float32x4,
}, },
// Sprite // Sprite
wgpu::VertexAttribute { wgpu::VertexAttribute {
offset: mem::size_of::<[f32; 9]>() as wgpu::BufferAddress, offset: mem::size_of::<[f32; 20]>() as wgpu::BufferAddress,
shader_location: 7, shader_location: 7,
format: wgpu::VertexFormat::Uint32, format: wgpu::VertexFormat::Uint32,
}, },
@ -297,7 +286,7 @@ pub struct RadialBarInstance {
/// this should be generated from an AnchoredUiPosition /// this should be generated from an AnchoredUiPosition
pub anchor: u32, pub anchor: u32,
/// Position of this object in logical pixels /// Position of this particle in logical pixels
pub position: [f32; 2], pub position: [f32; 2],
/// The diameter of this bar, in logical pixels /// The diameter of this bar, in logical pixels