use super::{super::texture::*, *}; pub type Framebuffer = Object; pub type Renderbuffer = Object; pub trait FramebuffArg { fn apply(self, _: u32); } impl FramebuffArg for (&Tex, GLenum) { fn apply(self, obj: u32) { GL!(glFramebuffTex(obj, self.0.obj(), self.1)); } } impl FramebuffArg for (&Renderbuffer, GLenum) { fn apply(self, obj: u32) { GL!(glFramebuffRenderbuff(obj, self.0.obj, self.1)); } } impl Framebuffer { pub fn attach(self, args: impl FramebuffArg) -> Self { args.apply(self.obj); self } pub fn Bind(&self, tex: &Tex) -> Binding { let TexParam { w, h, .. } = tex.param; GL::Viewport::Set((0, 0, w, h)); Binding::new(self) } pub fn Clear(&self, typ: GLenum, args: impl ClearArgs) { let (attach, c) = args.get(); GL!(glClearFramebuff(self.obj, typ, attach, c.as_ptr())); } } pub struct RenderTgt { pub fbo: Fbo, pub depth: Renderbuffer, } impl RenderTgt { pub fn new(args: impl FboArgs) -> Self { let mut fbo = Fbo::new(args); let TexParam { w, h, .. } = fbo.tex.param; let depth = Renderbuffer::new(); GL!(glRenderbuffStorage(depth.obj, 1, gl::DEPTH_COMPONENT, w, h)); fbo.fb = fbo.fb.attach((&depth, gl::DEPTH_ATTACHMENT)); Self { fbo, depth } } } impl Frame for RenderTgt { fn ClearColor(&self, args: impl ClearArgs) { self.fbo.ClearColor(args); } fn ClearDepth(&self, d: T) where f32: Cast, { GL!(glClearFramebuff(self.fbo.fb.obj, gl::DEPTH, 0, &f32(d) as *const f32)); } fn size(&self) -> uVec2 { self.fbo.size() } fn bind(&self) -> Binding { self.fbo.bind() } }