pub mod bayer;
pub mod crop;
pub mod passthrough;
pub mod yuv;
use glium::framebuffer::ValidationError;
use glium::texture::UnsignedTexture2d;
use thiserror::Error;
use crate::egl::Dimensions;
use crate::egl::Texture;
use crate::import_bind_texture;
use crate::uniform_extend;
use crate::uniforms::ExtendUniforms;
use glium::{self, IndexBuffer, VertexBuffer, Program, Surface};
use glium::uniforms::Uniforms;
use std::error;
use std::marker::PhantomData;
#[derive(Error, Debug)]
enum Error {
#[error("Transforming source texture doesn't create an image matching target dimensions")]
BadDimensions(&'static str),
#[error("Source is not in a supported format")]
BadFormat(&'static str),
}
#[derive(Copy, Clone, Debug)]
struct Vertex {
position: [f32; 2],
tex_coords: [f32; 2],
}
glium::implement_vertex!(Vertex, position, tex_coords);
fn covering_vertices<F: glium::backend::Facade>(facade: &F, (width, height): (u32, u32))
-> Result<(VertexBuffer<Vertex>, IndexBuffer<u16>), Box<dyn error::Error>>
{
Ok((
VertexBuffer::new(
facade,
&[
Vertex { position: [-1.0, -3.0], tex_coords: [0.0, height as f32 * 2.] },
Vertex { position: [-1.0, 1.0], tex_coords: [0.0, 0.0] },
Vertex { position: [3.0, 1.0], tex_coords: [width as f32 * 2., 0.0] },
]
)?,
IndexBuffer::new(
facade,
glium::index::PrimitiveType::TriangleStrip,
&[1 as u16, 2, 0],
)?,
))
}
pub struct Shader<T>{
program: Program,
vertices: glium::VertexBuffer<Vertex>,
indices: glium::IndexBuffer<u16>,
_data: PhantomData<T>,
}
pub fn import_target_texture(
facade: &impl glium::backend::Facade,
target_tex: &Texture,
) -> UnsignedTexture2d {
let Dimensions { width, height } = target_tex.dimensions();
unsafe {
use glium::texture::*;
UnsignedTexture2d::from_id(
facade,
UncompressedUintFormat::U8U8U8U8,
target_tex.id().as_gl_id(),
false,
MipmapsOption::NoMipmap,
Dimensions::Texture2d { width, height },
)
}
}
pub fn texture_to_surface<'a>(facade: &impl glium::backend::Facade, target: &'a mut UnsignedTexture2d)
-> Result<glium::framebuffer::SimpleFrameBuffer<'a>, ValidationError>
{
glium::framebuffer::SimpleFrameBuffer::new(facade, &*target)
}
impl<W> Shader<W> {
fn draw_any<'a, F: glium::backend::Facade>(
&self,
facade: &F,
source_tex: Texture,
target: &mut impl Surface,
uniforms: impl Uniforms + ExtendUniforms<'a>,
) -> Result<(), Box<dyn error::Error>>{
let Dimensions { width: source_width, height: source_height } = source_tex.dimensions();
let source = import_bind_texture(facade, source_tex)?;
let uniforms = uniform_extend! {
uniforms,
frameno: 0,
source_dims: (
source_width as f32, source_height as f32,
1.0 / source_width as f32, 1.0 / source_height as f32,
),
source: source
.sampled()
.wrap_function(glium::uniforms::SamplerWrapFunction::Repeat)
.minify_filter(glium::uniforms::MinifySamplerFilter::Nearest)
.magnify_filter(glium::uniforms::MagnifySamplerFilter::Nearest),
};
target.clear_color(0.0, 0.0, 1.0, 1.0);
target.draw(
&self.vertices,
&self.indices,
&self.program,
&uniforms,
&Default::default(),
)?;
facade.get_context().flush();
facade.get_context().finish();
Ok(())
}
}