dear_imgui_wgpu/
render_resources.rs1use crate::{RendererError, RendererResult, UniformBuffer};
7use std::collections::HashMap;
8use wgpu::*;
9
10pub struct RenderResources {
16 pub sampler: Option<Sampler>,
18 pub uniform_buffer: Option<UniformBuffer>,
20 pub common_bind_group: Option<BindGroup>,
22 pub image_bind_groups: HashMap<u64, BindGroup>,
24 pub image_bind_group_layout: Option<BindGroupLayout>,
26}
27
28impl RenderResources {
29 pub fn new() -> Self {
31 Self {
32 sampler: None,
33 uniform_buffer: None,
34 common_bind_group: None,
35 image_bind_groups: HashMap::new(),
36 image_bind_group_layout: None,
37 }
38 }
39
40 pub fn initialize(&mut self, device: &Device) -> RendererResult<()> {
42 let sampler = device.create_sampler(&SamplerDescriptor {
46 label: Some("Dear ImGui Texture Sampler"),
47 address_mode_u: AddressMode::ClampToEdge, address_mode_v: AddressMode::ClampToEdge, address_mode_w: AddressMode::ClampToEdge, mag_filter: FilterMode::Linear, min_filter: FilterMode::Linear, mipmap_filter: FilterMode::Linear, anisotropy_clamp: 1, ..Default::default()
55 });
56
57 let uniform_buffer = UniformBuffer::new(device, &sampler);
59
60 let image_bind_group_layout = device.create_bind_group_layout(&BindGroupLayoutDescriptor {
62 label: Some("Dear ImGui Image Bind Group Layout"),
63 entries: &[BindGroupLayoutEntry {
64 binding: 0,
65 visibility: ShaderStages::FRAGMENT,
66 ty: BindingType::Texture {
67 multisampled: false,
68 sample_type: TextureSampleType::Float { filterable: true },
69 view_dimension: TextureViewDimension::D2,
70 },
71 count: None,
72 }],
73 });
74
75 self.sampler = Some(sampler);
76 self.uniform_buffer = Some(uniform_buffer);
77 self.common_bind_group = None; self.image_bind_group_layout = Some(image_bind_group_layout);
79
80 Ok(())
81 }
82
83 pub fn create_image_bind_group(
85 &self,
86 device: &Device,
87 texture_view: &TextureView,
88 ) -> RendererResult<BindGroup> {
89 let layout = self.image_bind_group_layout.as_ref().ok_or_else(|| {
90 RendererError::InvalidRenderState("Image bind group layout not initialized".to_string())
91 })?;
92
93 let bind_group = device.create_bind_group(&BindGroupDescriptor {
94 label: Some("Dear ImGui Image Bind Group"),
95 layout,
96 entries: &[BindGroupEntry {
97 binding: 0,
98 resource: BindingResource::TextureView(texture_view),
99 }],
100 });
101
102 Ok(bind_group)
103 }
104
105 pub fn get_or_create_image_bind_group(
107 &mut self,
108 device: &Device,
109 texture_id: u64,
110 texture_view: &TextureView,
111 ) -> RendererResult<&BindGroup> {
112 if !self.image_bind_groups.contains_key(&texture_id) {
113 let bind_group = self.create_image_bind_group(device, texture_view)?;
114 self.image_bind_groups.insert(texture_id, bind_group);
115 }
116
117 Ok(self.image_bind_groups.get(&texture_id).unwrap())
118 }
119
120 pub fn remove_image_bind_group(&mut self, texture_id: u64) {
122 self.image_bind_groups.remove(&texture_id);
123 }
124
125 pub fn clear_image_bind_groups(&mut self) {
127 self.image_bind_groups.clear();
128 }
129
130 pub fn sampler(&self) -> Option<&Sampler> {
132 self.sampler.as_ref()
133 }
134
135 pub fn uniform_buffer(&self) -> Option<&UniformBuffer> {
137 self.uniform_buffer.as_ref()
138 }
139
140 pub fn common_bind_group(&self) -> Option<&BindGroup> {
142 self.uniform_buffer.as_ref().map(|ub| ub.bind_group())
143 }
144
145 pub fn image_bind_group_layout(&self) -> Option<&BindGroupLayout> {
147 self.image_bind_group_layout.as_ref()
148 }
149
150 pub fn is_initialized(&self) -> bool {
152 self.sampler.is_some()
153 && self.uniform_buffer.is_some()
154 && self.image_bind_group_layout.is_some()
155 }
156
157 pub fn stats(&self) -> RenderResourcesStats {
159 RenderResourcesStats {
160 image_bind_groups_count: self.image_bind_groups.len(),
161 is_initialized: self.is_initialized(),
162 }
163 }
164}
165
166impl Default for RenderResources {
167 fn default() -> Self {
168 Self::new()
169 }
170}
171
172#[derive(Debug, Clone)]
174pub struct RenderResourcesStats {
175 pub image_bind_groups_count: usize,
176 pub is_initialized: bool,
177}