ranim_render/primitives/
viewport.rs1use glam::{Mat4, Vec2};
2
3use crate::utils::{WgpuBuffer, WgpuContext};
4
5pub const DEPTH_ORDER_SPAN: f32 = 1e-4;
13
14#[repr(C, align(16))]
16#[derive(Debug, Clone, Copy, bytemuck::Pod, bytemuck::Zeroable)]
17pub struct ViewportUniform {
18 proj_mat: Mat4,
19 view_mat: Mat4,
20 half_frame_size: Vec2,
21 bias_epsilon: f32,
23 _padding: u32,
24}
25
26impl ViewportUniform {
27 pub fn new(proj_mat: Mat4, view_mat: Mat4, half_frame_size: Vec2, bias_epsilon: f32) -> Self {
29 Self {
30 proj_mat,
31 view_mat,
32 half_frame_size,
33 bias_epsilon,
34 _padding: 0,
35 }
36 }
37 pub(crate) fn as_bind_group_layout_entry(binding: u32) -> wgpu::BindGroupLayoutEntry {
38 wgpu::BindGroupLayoutEntry {
39 binding,
40 visibility: wgpu::ShaderStages::COMPUTE | wgpu::ShaderStages::VERTEX_FRAGMENT,
41 ty: wgpu::BindingType::Buffer {
42 ty: wgpu::BufferBindingType::Uniform,
43 has_dynamic_offset: false,
44 min_binding_size: None,
45 },
46 count: None,
47 }
48 }
49}
50
51impl Default for ViewportUniform {
52 fn default() -> Self {
53 Self::new(Mat4::IDENTITY, Mat4::IDENTITY, Vec2::ONE, 0.0)
54 }
55}
56
57pub struct ViewportBindGroup {
58 pub bind_group: wgpu::BindGroup,
59}
60
61impl AsRef<wgpu::BindGroup> for ViewportBindGroup {
62 fn as_ref(&self) -> &wgpu::BindGroup {
63 &self.bind_group
64 }
65}
66
67impl ViewportBindGroup {
68 pub fn bind_group_layout(ctx: &WgpuContext) -> wgpu::BindGroupLayout {
69 ctx.device
70 .create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
71 label: Some("Viewport Bind Group Layout"),
72 entries: &[ViewportUniform::as_bind_group_layout_entry(0)],
73 })
74 }
75
76 pub(crate) fn new(ctx: &WgpuContext, uniforms_buffer: &WgpuBuffer<ViewportUniform>) -> Self {
77 let bind_group = ctx.device.create_bind_group(&wgpu::BindGroupDescriptor {
78 label: Some("Camera Uniforms"),
79 layout: &Self::bind_group_layout(ctx),
80 entries: &[wgpu::BindGroupEntry {
81 binding: 0,
82 resource: wgpu::BindingResource::Buffer(
83 uniforms_buffer.as_ref().as_entire_buffer_binding(),
84 ),
85 }],
86 });
87 Self { bind_group }
88 }
89}
90
91#[derive(bevy_ecs::prelude::Resource)]
92pub struct ViewportGpuPacket {
93 pub(crate) uniforms_buffer: WgpuBuffer<ViewportUniform>,
94 pub(crate) uniforms_bind_group: ViewportBindGroup,
95}
96
97impl ViewportGpuPacket {
98 pub fn bind_group(&self) -> &wgpu::BindGroup {
100 &self.uniforms_bind_group.bind_group
101 }
102
103 pub(crate) fn new(ctx: &WgpuContext, data: &ViewportUniform) -> Self {
104 let uniforms_buffer = WgpuBuffer::new_init(
105 ctx,
106 Some("Uniforms Buffer"),
107 wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST,
108 *data,
109 );
110 let uniforms_bind_group = ViewportBindGroup::new(ctx, &uniforms_buffer);
111
112 Self {
113 uniforms_buffer,
114 uniforms_bind_group,
115 }
116 }
117
118 pub fn update(&mut self, ctx: &WgpuContext, data: &ViewportUniform) {
119 self.uniforms_buffer.set(ctx, *data);
120 }
121}