summaryrefslogtreecommitdiff
path: root/src/instance.rs
blob: eded8cf32bb9e769b0f2e6b5493b4c752fe6edb9 (plain)
use std::mem::size_of;

use bytemuck::{Pod, Zeroable};

#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub struct InstanceId(pub(crate) usize);

#[repr(C)]
#[derive(Copy, Clone, Debug, PartialEq, Pod, Zeroable)]
pub struct Instance {
	/// Position on the screen
	pub position: [f32; 2],
	/// Relative size
	pub size: [f32; 2],
	/// The location of the texture in the texture atlas
	pub texture_coordinates: [f32; 2],
	/// The size of the sprite's texture
	pub texture_size: [f32; 2],
	/// The index of the texture atlas to use
	pub texture_atlas_index: u32,
	/// Rotation, in radians
	pub rotation: f32,
	/// z-index
	pub z_index: u32,
}

impl Default for Instance {
	fn default() -> Self {
		Self {
			position: [0.0; 2],
			size: [1.0; 2],
			rotation: 0.0,
			z_index: 0,
			texture_coordinates: [0.0; 2],
			texture_size: [1.0; 2],
			texture_atlas_index: 0,
		}
	}
}

impl Instance {
	// whenever this is updated, please also update `sprite.wgsl`
	const ATTRIBUTES: [wgpu::VertexAttribute; 7] = wgpu::vertex_attr_array![
		1 => Float32x2, 2 => Float32x2, 3 => Float32x2, 4 => Float32x2,
		5 => Uint32, 6 => Float32, 7 => Uint32
	];

	pub(crate) fn desc<'a>() -> wgpu::VertexBufferLayout<'a> {
		// make sure these two don't conflict
		debug_assert_eq!(
			Self::ATTRIBUTES[0].shader_location as usize,
			crate::Vertex::ATTRIBUTES.len()
		);
		wgpu::VertexBufferLayout {
			array_stride: size_of::<Self>() as wgpu::BufferAddress,
			step_mode: wgpu::VertexStepMode::Instance,
			attributes: &Self::ATTRIBUTES,
		}
	}
}