appy/utils/
image_renderer.rs

1extern crate nalgebra_glm as glm;
2
3use crate::gl;
4use crate::gl::types::*;
5use crate::{types::*, utils::*};
6
7pub struct ImageRenderer {
8    program: ShaderProgram,
9    buf: ArrayBuffer,
10    window_width: f32,
11    window_height: f32,
12    loc_vertex: i32,
13    loc_tex_coord: i32,
14    loc_mvp: i32,
15    loc_pos: i32,
16    loc_size: i32,
17}
18
19impl ImageRenderer {
20    pub fn new(window_width: f32, window_height: f32) -> Self {
21        let program = ShaderProgram::new(vec![
22            ShaderSource::VertexShader(
23                "
24				#version 300 es
25				precision mediump float;
26				uniform mat4 mvp;
27				uniform vec2 pos,size;
28				in vec2 vertex;
29				in vec2 tex_coord;
30				out vec2 fragment_tex_coord;
31				void main() {
32					//vec3 size3=vec3(size.x,size.1,1.0);
33					//vec3 pos3=vec3(pos.x,pos.y,1.0);
34					gl_Position=mvp*vec4(pos+vertex*size,0.0,1.0);
35					fragment_tex_coord=tex_coord;
36				}
37			"
38                .to_string(),
39            ),
40            ShaderSource::FragmentShader(
41                "
42				#version 300 es
43				precision mediump float;
44				uniform sampler2D texture0;
45				in vec2 fragment_tex_coord;
46				out vec4 fragment_color;
47				void main() {
48					vec4 tex_data=texture(texture0,fragment_tex_coord);
49					fragment_color=vec4(tex_data.r,tex_data.g,tex_data.b,tex_data.a);
50				}
51			"
52                .to_string(),
53            ),
54        ]);
55
56        let mut buf = ArrayBuffer::new(4);
57        buf.set_data(vec![
58            0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0,
59            1.0, 1.0, 1.0, 0.0, 1.0, 0.0, 1.0,
60        ]);
61
62        Self {
63            loc_vertex: program.get_attrib_location("vertex"),
64            loc_tex_coord: program.get_attrib_location("tex_coord"),
65            loc_mvp: program.get_uniform_location("mvp"),
66            loc_pos: program.get_uniform_location("pos"),
67            loc_size: program.get_uniform_location("size"),
68            program,
69            window_width,
70            window_height,
71            buf,
72        }
73    }
74
75    pub fn set_size(&mut self, window_width: f32, window_height: f32) {
76        self.window_width = window_width;
77        self.window_height = window_height;
78    }
79
80    pub fn draw(&self, rect: &Rect, image: &ImageSource) {
81        let m = glm::ortho(
82            0.0,
83            self.window_width as f32,
84            self.window_height as f32,
85            0.0,
86            -1.0,
87            1.0,
88        );
89
90        image.bind();
91
92        self.program.use_program();
93        self.buf.bind(self.loc_vertex, 0, 2);
94        self.buf.bind(self.loc_tex_coord, 2, 2);
95
96        unsafe {
97            gl::ActiveTexture(gl::TEXTURE0);
98            gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MIN_FILTER, gl::NEAREST as GLint);
99            gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MAG_FILTER, gl::NEAREST as GLint);
100
101            gl::Uniform2f(self.loc_pos, rect.x as f32, rect.y as f32);
102            gl::Uniform2f(self.loc_size, rect.w as f32, rect.h as f32);
103            gl::UniformMatrix4fv(self.loc_mvp, 1, gl::FALSE, m.as_ptr());
104            gl::Enable(gl::BLEND);
105            gl::BlendFunc(gl::SRC_ALPHA, gl::ONE_MINUS_SRC_ALPHA);
106            gl::DrawArrays(gl::TRIANGLES, 0, self.buf.len() as i32);
107        }
108    }
109}