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 image_bind_groups: HashMap<u64, BindGroup>,
22 pub image_bind_group_layout: Option<BindGroupLayout>,
24}
25
26impl RenderResources {
27 pub fn new() -> Self {
29 Self {
30 sampler: None,
31 uniform_buffer: None,
32 image_bind_groups: HashMap::new(),
33 image_bind_group_layout: None,
34 }
35 }
36
37 pub fn initialize(&mut self, device: &Device) -> RendererResult<()> {
39 let sampler = device.create_sampler(&SamplerDescriptor {
43 label: Some("Dear ImGui Texture Sampler"),
44 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()
52 });
53
54 let uniform_buffer = UniformBuffer::new(device, &sampler);
56
57 let image_bind_group_layout = device.create_bind_group_layout(&BindGroupLayoutDescriptor {
59 label: Some("Dear ImGui Image Bind Group Layout"),
60 entries: &[BindGroupLayoutEntry {
61 binding: 0,
62 visibility: ShaderStages::FRAGMENT,
63 ty: BindingType::Texture {
64 multisampled: false,
65 sample_type: TextureSampleType::Float { filterable: true },
66 view_dimension: TextureViewDimension::D2,
67 },
68 count: None,
69 }],
70 });
71
72 self.sampler = Some(sampler);
73 self.uniform_buffer = Some(uniform_buffer);
74 self.image_bind_group_layout = Some(image_bind_group_layout);
75
76 Ok(())
77 }
78
79 pub fn create_image_bind_group(
81 &self,
82 device: &Device,
83 texture_view: &TextureView,
84 ) -> RendererResult<BindGroup> {
85 let layout = self.image_bind_group_layout.as_ref().ok_or_else(|| {
86 RendererError::InvalidRenderState("Image bind group layout not initialized".to_string())
87 })?;
88
89 let bind_group = device.create_bind_group(&BindGroupDescriptor {
90 label: Some("Dear ImGui Image Bind Group"),
91 layout,
92 entries: &[BindGroupEntry {
93 binding: 0,
94 resource: BindingResource::TextureView(texture_view),
95 }],
96 });
97
98 Ok(bind_group)
99 }
100
101 pub fn get_or_create_image_bind_group(
103 &mut self,
104 device: &Device,
105 texture_id: u64,
106 texture_view: &TextureView,
107 ) -> RendererResult<&BindGroup> {
108 if !self.image_bind_groups.contains_key(&texture_id) {
109 let bind_group = self.create_image_bind_group(device, texture_view)?;
110 self.image_bind_groups.insert(texture_id, bind_group);
111 }
112
113 Ok(self.image_bind_groups.get(&texture_id).unwrap())
114 }
115
116 pub fn remove_image_bind_group(&mut self, texture_id: u64) {
118 self.image_bind_groups.remove(&texture_id);
119 }
120
121 pub fn clear_image_bind_groups(&mut self) {
123 self.image_bind_groups.clear();
124 }
125
126 pub fn sampler(&self) -> Option<&Sampler> {
128 self.sampler.as_ref()
129 }
130
131 pub fn uniform_buffer(&self) -> Option<&UniformBuffer> {
133 self.uniform_buffer.as_ref()
134 }
135
136 pub fn common_bind_group(&self) -> Option<&BindGroup> {
138 self.uniform_buffer.as_ref().map(|ub| ub.bind_group())
139 }
140
141 pub fn image_bind_group_layout(&self) -> Option<&BindGroupLayout> {
143 self.image_bind_group_layout.as_ref()
144 }
145
146 pub fn is_initialized(&self) -> bool {
148 self.sampler.is_some()
149 && self.uniform_buffer.is_some()
150 && self.image_bind_group_layout.is_some()
151 }
152
153 pub fn stats(&self) -> RenderResourcesStats {
155 RenderResourcesStats {
156 image_bind_groups_count: self.image_bind_groups.len(),
157 is_initialized: self.is_initialized(),
158 }
159 }
160}
161
162impl Default for RenderResources {
163 fn default() -> Self {
164 Self::new()
165 }
166}
167
168#[derive(Debug, Clone)]
170pub struct RenderResourcesStats {
171 pub image_bind_groups_count: usize,
172 pub is_initialized: bool,
173}