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: MipmapFilterMode::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 self.image_bind_groups.get(&texture_id).ok_or_else(|| {
114 RendererError::InvalidRenderState("Image bind group missing after creation".to_string())
115 })
116 }
117
118 pub fn remove_image_bind_group(&mut self, texture_id: u64) {
120 self.image_bind_groups.remove(&texture_id);
121 }
122
123 pub fn clear_image_bind_groups(&mut self) {
125 self.image_bind_groups.clear();
126 }
127
128 pub fn sampler(&self) -> Option<&Sampler> {
130 self.sampler.as_ref()
131 }
132
133 pub fn uniform_buffer(&self) -> Option<&UniformBuffer> {
135 self.uniform_buffer.as_ref()
136 }
137
138 pub fn common_bind_group(&self) -> Option<&BindGroup> {
140 self.uniform_buffer.as_ref().map(|ub| ub.bind_group())
141 }
142
143 pub fn image_bind_group_layout(&self) -> Option<&BindGroupLayout> {
145 self.image_bind_group_layout.as_ref()
146 }
147
148 pub fn is_initialized(&self) -> bool {
150 self.sampler.is_some()
151 && self.uniform_buffer.is_some()
152 && self.image_bind_group_layout.is_some()
153 }
154
155 pub fn stats(&self) -> RenderResourcesStats {
157 RenderResourcesStats {
158 image_bind_groups_count: self.image_bind_groups.len(),
159 is_initialized: self.is_initialized(),
160 }
161 }
162}
163
164impl Default for RenderResources {
165 fn default() -> Self {
166 Self::new()
167 }
168}
169
170#[derive(Debug, Clone)]
172pub struct RenderResourcesStats {
173 pub image_bind_groups_count: usize,
174 pub is_initialized: bool,
175}