Re added capture, and added make texture from color
This commit is contained in:
parent
69606e4d56
commit
2725d04a3d
102
src/renderer.rs
102
src/renderer.rs
|
@ -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
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue