Skip to main content

enigma_3d/postprocessing/
lens_dirt.rs

1use glium::glutin::surface::WindowSurface;
2use glium::{IndexBuffer, Surface, Texture2d, uniform, VertexBuffer};
3use glium::framebuffer::SimpleFrameBuffer;
4use glium::texture::DepthTexture2d;
5use crate::{AppState, resources, shader};
6use crate::geometry::Vertex;
7use crate::postprocessing::PostProcessingEffect;
8
9pub struct LensDirt {
10    program: glium::Program,
11    dirt_texture: Texture2d,
12    intensity: f32,
13    tile_scale: [f32; 2],
14    light_sensitivity: f32,
15}
16
17impl LensDirt {
18    pub fn new(
19        display: &glium::Display<WindowSurface>,
20        dirt_texture_data: &[u8],
21        intensity: f32,
22        tile_scale: [f32; 2],
23        light_sensitivity: f32
24    ) -> Self {
25        let shader = shader::Shader::from_strings(
26            resources::post_processing_vertex(),
27            resources::post_processing_lens_dirt_fragment(),
28            None
29        );
30        let program = glium::Program::from_source(
31            display,
32            &shader.get_vertex_shader(),
33            &shader.get_fragment_shader(),
34            None
35        ).expect("Failed to compile lens dirt shader program");
36
37        let image = image::load_from_memory(dirt_texture_data)
38            .expect("Failed to load lens dirt texture")
39            .to_rgba8();
40        let image_dimensions = image.dimensions();
41        let image = glium::texture::RawImage2d::from_raw_rgba_reversed(&image.into_raw(), image_dimensions);
42        let dirt_texture = glium::texture::Texture2d::with_mipmaps(
43            display,
44            image,
45            glium::texture::MipmapsOption::AutoGeneratedMipmaps
46        ).expect("Failed to create lens dirt texture");
47
48        Self {
49            program,
50            dirt_texture,
51            intensity,
52            tile_scale,
53            light_sensitivity,
54        }
55    }
56}
57
58impl PostProcessingEffect for LensDirt {
59    fn render(&self, app_state: &AppState, vertex_buffer: &VertexBuffer<Vertex>, index_buffer: &IndexBuffer<u32>, target: &mut SimpleFrameBuffer, source: &Texture2d, _depth_source: &DepthTexture2d, _buffer_textures: &Vec<Texture2d>) {
60        let screen_size = app_state.display.as_ref().unwrap().get_framebuffer_dimensions();
61        let uniforms = uniform! {
62            scene: source,
63            dirt_texture: &self.dirt_texture,
64            intensity: self.intensity,
65            tile_scale: self.tile_scale,
66            screen_size: screen_size,
67            light_sensitivity: self.light_sensitivity,
68        };
69
70        target.draw(
71            vertex_buffer,
72            index_buffer,
73            &self.program,
74            &uniforms,
75            &Default::default(),
76        ).unwrap();
77    }
78}