Re added capture, and added make texture from color

This commit is contained in:
Thomas Forgione 2018-04-17 14:21:35 +02:00
parent 69606e4d56
commit 2725d04a3d
No known key found for this signature in database
GPG Key ID: C75CD416BD1FFCE1
1 changed files with 101 additions and 1 deletions

View File

@ -1,11 +1,15 @@
//! This module contains the rendering structs.
use std::cell::Ref;
use std::borrow::Cow;
use image;
use glium::texture::{RawImage2d, SrgbTexture2d};
use glium::texture::{RawImage2d, SrgbTexture2d, Texture2dDataSink};
use glium::{Frame, Display, Surface, Program, DrawParameters, Depth, VertexBuffer};
use glium::{Rect, BlitTarget};
use glium::framebuffer::SimpleFrameBuffer;
use glium::uniforms::MagnifySamplerFilter;
use glium::draw_parameters::{DepthTest, Blend};
use glium::index::{NoIndices, PrimitiveType};
use glium::glutin::GlWindow;
@ -15,6 +19,28 @@ use camera::RenderCamera;
use model::{Vertex, Part, Model};
/// Image data stored as RGBA.
pub struct RgbaImageData {
/// The array of colors.
pub data: Vec<(u8, u8, u8, u8)>,
/// The width of the image.
pub width: u32,
/// The height of the image.
pub height: u32,
}
impl Texture2dDataSink<(u8, u8, u8, u8)> for RgbaImageData {
fn from_raw(data: Cow<[(u8, u8, u8, u8)]>, width: u32, height: u32) -> Self {
RgbaImageData {
data: data.into_owned(),
width: width,
height: height,
}
}
}
/// A renderer. It contains a display, shaders, and some rendering parameters.
pub struct Renderer {
/// The display on which the rendering will be done.
@ -61,6 +87,12 @@ impl Renderer {
SrgbTexture2d::new(&self.display, image).ok().unwrap()
}
/// Creates a 1x1 SrgbTexture with the color passed as parameter.
pub fn make_texture_from_color(&self, r: f32, g: f32, b: f32, a: f32) -> SrgbTexture2d {
let image = RawImage2d::from_raw_rgba(vec![r, g, b, a], (1, 1));
SrgbTexture2d::new(&self.display, image).ok().unwrap()
}
/// Creates a frame from the display.
pub fn draw(&self) -> Frame {
self.display.draw()
@ -155,4 +187,72 @@ impl Renderer {
pub fn show(&mut self) {
self.gl_window().show();
}
/// Returns a DynamicImage of the corresponding frame.
pub fn capture(&self, dimensions: (u32, u32)) -> image::DynamicImage {
rgba_image_data_to_image(self.capture_rgba_image_data(dimensions))
}
/// Returns a RgbaImageData of the corresponding frame.
pub fn capture_rgba_image_data(&self, dimensions: (u32, u32)) -> RgbaImageData {
let rect = Rect {
left: 0,
bottom: 0,
width: dimensions.0,
height: dimensions.1,
};
let blit_target = BlitTarget {
left: 0,
bottom: 0,
width: dimensions.0 as i32,
height: dimensions.1 as i32,
};
// Create temporary texture and blit the front buffer to it
let texture = SrgbTexture2d::empty(&self.display, dimensions.0, dimensions.1)
.unwrap();
let framebuffer = SimpleFrameBuffer::new(&self.display, &texture)
.unwrap();
use glium::Surface;
framebuffer.blit_from_frame(
&rect,
&blit_target,
MagnifySamplerFilter::Nearest
);
// Read the texture into new pixel buffer
let pixel_buffer = texture.read_to_pixel_buffer();
pixel_buffer.read_as_texture_2d().unwrap()
}
}
/// Converts a RgbaImamgeData to a DynamicImage.
pub fn rgba_image_data_to_image(image_data: RgbaImageData) -> image::DynamicImage {
let pixels = {
let mut v = Vec::with_capacity(image_data.data.len() * 4);
for (a, b, c, d) in image_data.data {
v.push(a);
v.push(b);
v.push(c);
v.push(d);
}
v
};
// Create ImageBuffer
let image_buffer =
image::ImageBuffer::from_raw(image_data.width, image_data.height, pixels)
.unwrap();
// Save the screenshot to file
let image = image::DynamicImage::ImageRgba8(image_buffer).flipv();
image
}