1#![allow(dead_code)]
2
3use wgpu_3dgs_viewer::selection::ViewportTexture;
4
5#[derive(Debug)]
7pub struct ViewportTextureOverlayRenderer {
8 sampler: wgpu::Sampler,
10 bind_group_layout: wgpu::BindGroupLayout,
12 bind_group: wgpu::BindGroup,
14 pipeline: wgpu::RenderPipeline,
16}
17
18impl ViewportTextureOverlayRenderer {
19 pub const BIND_GROUP_LAYOUT_DESCRIPTOR: wgpu::BindGroupLayoutDescriptor<'static> =
21 wgpu::BindGroupLayoutDescriptor {
22 label: Some("Selection Viewport Texture Overlay Renderer Bind Group Layout"),
23 entries: &[
24 wgpu::BindGroupLayoutEntry {
25 binding: 0,
26 visibility: wgpu::ShaderStages::FRAGMENT,
27 ty: wgpu::BindingType::Texture {
28 sample_type: wgpu::TextureSampleType::Float { filterable: true },
29 view_dimension: wgpu::TextureViewDimension::D2,
30 multisampled: false,
31 },
32 count: None,
33 },
34 wgpu::BindGroupLayoutEntry {
35 binding: 1,
36 visibility: wgpu::ShaderStages::FRAGMENT,
37 ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering),
38 count: None,
39 },
40 ],
41 };
42
43 pub fn new(
45 device: &wgpu::Device,
46 texture_format: wgpu::TextureFormat,
47 viewport_texture: &ViewportTexture,
48 ) -> Self {
49 log::debug!("Creating selection viewport texture overlay renderer sampler");
50 let sampler = device.create_sampler(&wgpu::SamplerDescriptor {
51 label: Some("Selection Viewport Texture Overlay Renderer Sampler"),
52 ..Default::default()
53 });
54
55 log::debug!("Creating selection viewport texture overlay renderer bind group layout");
56 let bind_group_layout =
57 device.create_bind_group_layout(&Self::BIND_GROUP_LAYOUT_DESCRIPTOR);
58
59 log::debug!("Creating selection viewport texture overlay renderer bind group");
60 let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
61 label: Some("Selection Viewport Texture Overlay Renderer Bind Group"),
62 layout: &bind_group_layout,
63 entries: &[
64 wgpu::BindGroupEntry {
65 binding: 0,
66 resource: wgpu::BindingResource::TextureView(viewport_texture.view()),
67 },
68 wgpu::BindGroupEntry {
69 binding: 1,
70 resource: wgpu::BindingResource::Sampler(&sampler),
71 },
72 ],
73 });
74
75 log::debug!("Creating selection viewport texture overlay renderer pipeline layout");
76 let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
77 label: Some("Selection Viewport Texture Overlay Renderer Pipeline Layout"),
78 bind_group_layouts: &[&bind_group_layout],
79 ..Default::default()
80 });
81
82 log::debug!("Creating selection viewport texture overlay renderer shader");
83 let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
84 label: Some("Selection Viewport Texture Overlay Renderer Shader"),
85 source: wgpu::ShaderSource::Wgsl(
86 include_str!("../shader/selection/viewport_texture_overlay.wgsl").into(),
87 ),
88 });
89
90 log::debug!("Creating selection viewport texture overlay renderer pipeline");
91 let pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
92 label: Some("Selection Viewport Texture Overlay Renderer Pipeline"),
93 layout: Some(&pipeline_layout),
94 vertex: wgpu::VertexState {
95 module: &shader,
96 entry_point: Some("vert_main"),
97 buffers: &[],
98 compilation_options: wgpu::PipelineCompilationOptions::default(),
99 },
100 fragment: Some(wgpu::FragmentState {
101 module: &shader,
102 entry_point: Some("frag_main"),
103 targets: &[Some(wgpu::ColorTargetState {
104 format: texture_format,
105 blend: Some(wgpu::BlendState::ALPHA_BLENDING),
106 write_mask: wgpu::ColorWrites::ALL,
107 })],
108 compilation_options: wgpu::PipelineCompilationOptions::default(),
109 }),
110 primitive: wgpu::PrimitiveState::default(),
111 depth_stencil: None,
112 multisample: wgpu::MultisampleState::default(),
113 multiview_mask: None,
114 cache: None,
115 });
116
117 Self {
118 sampler,
119 bind_group_layout,
120 bind_group,
121 pipeline,
122 }
123 }
124
125 pub fn update_bind_group(&mut self, device: &wgpu::Device, viewport_texture: &ViewportTexture) {
129 self.bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
130 label: Some("Selection Viewport Texture Overlay Renderer Bind Group"),
131 layout: &self.bind_group_layout,
132 entries: &[
133 wgpu::BindGroupEntry {
134 binding: 0,
135 resource: wgpu::BindingResource::TextureView(viewport_texture.view()),
136 },
137 wgpu::BindGroupEntry {
138 binding: 1,
139 resource: wgpu::BindingResource::Sampler(&self.sampler),
140 },
141 ],
142 });
143 }
144
145 pub fn render(&self, encoder: &mut wgpu::CommandEncoder, view: &wgpu::TextureView) {
147 let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
148 label: Some("Selection Viewport Texture Overlay Render Pass"),
149 color_attachments: &[Some(wgpu::RenderPassColorAttachment {
150 view,
151 resolve_target: None,
152 ops: wgpu::Operations {
153 load: wgpu::LoadOp::Load,
154 store: wgpu::StoreOp::Store,
155 },
156 depth_slice: None,
157 })],
158 ..Default::default()
159 });
160
161 self.render_with_pass(&mut render_pass);
162 }
163
164 pub fn render_with_pass(&self, pass: &mut wgpu::RenderPass<'_>) {
166 pass.set_pipeline(&self.pipeline);
167 pass.set_bind_group(0, &self.bind_group, &[]);
168 pass.draw(0..3, 0..1);
169 }
170}