appy 0.1.6

Declarative UI framework with native rendering
Documentation
extern crate nalgebra_glm as glm;

use crate::gl;
use crate::gl::types::*;
use crate::{types::*, utils::*};

pub struct ImageRenderer {
    program: ShaderProgram,
    buf: ArrayBuffer,
    window_width: f32,
    window_height: f32,
    loc_vertex: i32,
    loc_tex_coord: i32,
    loc_mvp: i32,
    loc_pos: i32,
    loc_size: i32,
}

impl ImageRenderer {
    pub fn new(window_width: f32, window_height: f32) -> Self {
        let program = ShaderProgram::new(vec![
            ShaderSource::VertexShader(
                "
				#version 300 es
				precision mediump float;
				uniform mat4 mvp;
				uniform vec2 pos,size;
				in vec2 vertex;
				in vec2 tex_coord;
				out vec2 fragment_tex_coord;
				void main() {
					//vec3 size3=vec3(size.x,size.1,1.0);
					//vec3 pos3=vec3(pos.x,pos.y,1.0);
					gl_Position=mvp*vec4(pos+vertex*size,0.0,1.0);
					fragment_tex_coord=tex_coord;
				}
			"
                .to_string(),
            ),
            ShaderSource::FragmentShader(
                "
				#version 300 es
				precision mediump float;
				uniform sampler2D texture0;
				in vec2 fragment_tex_coord;
				out vec4 fragment_color;
				void main() {
					vec4 tex_data=texture(texture0,fragment_tex_coord);
					fragment_color=vec4(tex_data.r,tex_data.g,tex_data.b,tex_data.a);
				}
			"
                .to_string(),
            ),
        ]);

        let mut buf = ArrayBuffer::new(4);
        buf.set_data(vec![
            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,
            1.0, 1.0, 1.0, 0.0, 1.0, 0.0, 1.0,
        ]);

        Self {
            loc_vertex: program.get_attrib_location("vertex"),
            loc_tex_coord: program.get_attrib_location("tex_coord"),
            loc_mvp: program.get_uniform_location("mvp"),
            loc_pos: program.get_uniform_location("pos"),
            loc_size: program.get_uniform_location("size"),
            program,
            window_width,
            window_height,
            buf,
        }
    }

    pub fn set_size(&mut self, window_width: f32, window_height: f32) {
        self.window_width = window_width;
        self.window_height = window_height;
    }

    pub fn draw(&self, rect: &Rect, image: &ImageSource) {
        let m = glm::ortho(
            0.0,
            self.window_width as f32,
            self.window_height as f32,
            0.0,
            -1.0,
            1.0,
        );

        image.bind();

        self.program.use_program();
        self.buf.bind(self.loc_vertex, 0, 2);
        self.buf.bind(self.loc_tex_coord, 2, 2);

        unsafe {
            gl::ActiveTexture(gl::TEXTURE0);
            gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MIN_FILTER, gl::NEAREST as GLint);
            gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MAG_FILTER, gl::NEAREST as GLint);

            gl::Uniform2f(self.loc_pos, rect.x as f32, rect.y as f32);
            gl::Uniform2f(self.loc_size, rect.w as f32, rect.h as f32);
            gl::UniformMatrix4fv(self.loc_mvp, 1, gl::FALSE, m.as_ptr());
            gl::Enable(gl::BLEND);
            gl::BlendFunc(gl::SRC_ALPHA, gl::ONE_MINUS_SRC_ALPHA);
            gl::DrawArrays(gl::TRIANGLES, 0, self.buf.len() as i32);
        }
    }
}