use std::rc::Rc;
use crate::error::Result;
use crate::graphics::{DrawParams, FilterMode, Texture};
use crate::platform::{RawCanvas, RawRenderbuffer};
use crate::Context;
use super::{ImageData, TextureFormat};
#[derive(Debug, Clone)]
pub struct CanvasBuilder {
width: i32,
height: i32,
texture_format: TextureFormat,
samples: u8,
stencil_buffer: bool,
}
impl CanvasBuilder {
pub fn new(width: i32, height: i32) -> CanvasBuilder {
CanvasBuilder {
width,
height,
texture_format: TextureFormat::Rgba8,
samples: 0,
stencil_buffer: false,
}
}
pub fn texture_format(&mut self, format: TextureFormat) -> &mut CanvasBuilder {
self.texture_format = format;
self
}
pub fn samples(&mut self, samples: u8) -> &mut CanvasBuilder {
self.samples = samples;
self
}
pub fn stencil_buffer(&mut self, enabled: bool) -> &mut CanvasBuilder {
self.stencil_buffer = enabled;
self
}
pub fn build(&self, ctx: &mut Context) -> Result<Canvas> {
let attachments = ctx.device.new_canvas(
self.width,
self.height,
self.texture_format,
ctx.graphics.default_filter_mode,
self.samples,
self.stencil_buffer,
)?;
Ok(Canvas {
handle: Rc::new(attachments.canvas),
texture: Texture::from_raw(attachments.color, ctx.graphics.default_filter_mode),
stencil_buffer: attachments.depth_stencil.map(Rc::new),
multisample: attachments.multisample_color.map(Rc::new),
})
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct Canvas {
pub(crate) handle: Rc<RawCanvas>,
pub(crate) texture: Texture,
pub(crate) stencil_buffer: Option<Rc<RawRenderbuffer>>,
pub(crate) multisample: Option<Rc<RawRenderbuffer>>,
}
impl Canvas {
pub fn new(ctx: &mut Context, width: i32, height: i32) -> Result<Canvas> {
CanvasBuilder::new(width, height).build(ctx)
}
pub fn builder(width: i32, height: i32) -> CanvasBuilder {
CanvasBuilder::new(width, height)
}
pub fn draw<P>(&self, ctx: &mut Context, params: P)
where
P: Into<DrawParams>,
{
self.texture.draw(ctx, params)
}
pub fn width(&self) -> i32 {
self.texture.width()
}
pub fn height(&self) -> i32 {
self.texture.height()
}
pub fn size(&self) -> (i32, i32) {
self.texture.size()
}
pub fn filter_mode(&self) -> FilterMode {
self.texture.filter_mode()
}
pub fn set_filter_mode(&mut self, ctx: &mut Context, filter_mode: FilterMode) {
self.texture.set_filter_mode(ctx, filter_mode);
}
pub fn get_data(&self, ctx: &mut Context) -> ImageData {
self.texture.get_data(ctx)
}
pub fn set_data(
&self,
ctx: &mut Context,
x: i32,
y: i32,
width: i32,
height: i32,
data: &[u8],
) -> Result {
self.texture.set_data(ctx, x, y, width, height, data)
}
pub fn replace_data(&self, ctx: &mut Context, data: &[u8]) -> Result {
self.texture.replace_data(ctx, data)
}
pub fn texture(&self) -> &Texture {
&self.texture
}
}