use std::rc::Rc;
use glam::{Vec2, vec2};
use glow::HasContext;
use crate::common::{create_shader_program, pop_debug_group, push_debug_group, slice_as_bytes};
const SRC_VERT_WHITE: &str = include_str!("./shaders/white.vert");
const SRC_FRAG_WHITE: &str = include_str!("./shaders/white.frag");
pub struct WhiteRectRenderer {
gl: Rc<glow::Context>,
shader: glow::Program,
vao: glow::VertexArray,
vbo: glow::Buffer,
}
impl WhiteRectRenderer {
pub fn new(gl: Rc<glow::Context>) -> Self {
unsafe {
push_debug_group(&gl, "WhiteRectRenderer: init");
let shader = create_shader_program(&gl, SRC_VERT_WHITE, SRC_FRAG_WHITE);
let vao = gl.create_vertex_array().unwrap();
gl.bind_vertex_array(Some(vao));
let vbo = gl.create_buffer().unwrap();
gl.bind_buffer(glow::ARRAY_BUFFER, Some(vbo));
gl.buffer_data_u8_slice(glow::ARRAY_BUFFER, slice_as_bytes(SCREEN_VERTICES), glow::STATIC_DRAW);
#[rustfmt::skip]
{
let a_position = gl.get_attrib_location(shader, "position").unwrap();
gl.vertex_attrib_pointer_f32(a_position, 2, glow::FLOAT, false, size_of::<Vec2>() as i32, 0);
gl.enable_vertex_attrib_array(a_position);
};
pop_debug_group(&gl);
Self { gl, shader, vao, vbo }
}
}
pub fn draw(&self) -> usize {
let gl = &self.gl;
unsafe {
push_debug_group(gl, "WhiteRectRenderer: draw");
gl.bind_vertex_array(Some(self.vao));
gl.bind_buffer(glow::ARRAY_BUFFER, Some(self.vbo));
gl.use_program(Some(self.shader));
gl.draw_arrays(glow::TRIANGLES, 0, 6);
pop_debug_group(gl);
1
}
}
}
impl Drop for WhiteRectRenderer {
fn drop(&mut self) {
let gl = &self.gl;
unsafe {
push_debug_group(gl, "WhiteRectRenderer: drop");
gl.delete_program(self.shader);
gl.delete_vertex_array(self.vao);
gl.delete_buffer(self.vbo);
pop_debug_group(gl);
}
}
}
#[rustfmt::skip]
const SCREEN_VERTICES: &[Vec2] = &[
vec2(-1.0, -1.0),
vec2(-1.0, 1.0),
vec2( 1.0, 1.0),
vec2(-1.0, -1.0),
vec2( 1.0, 1.0),
vec2( 1.0, -1.0),
];