use { crate::render::{ egl::{context::EglContext, image::EglImage, PROCS}, gl::{ frame_buffer::GlFrameBuffer, sys::{ glBindFramebuffer, glBindRenderbuffer, glCheckFramebufferStatus, glDeleteRenderbuffers, glFramebufferRenderbuffer, glGenFramebuffers, glGenRenderbuffers, GLeglImageOES, GLuint, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER, GL_FRAMEBUFFER_COMPLETE, GL_RENDERBUFFER, }, }, RenderError, }, std::rc::Rc, }; pub struct GlRenderBuffer { pub img: Rc, pub ctx: Rc, rbo: GLuint, } impl GlRenderBuffer { pub unsafe fn from_image( img: &Rc, ctx: &Rc, ) -> Result, RenderError> { let mut rbo = 0; glGenRenderbuffers(1, &mut rbo); glBindRenderbuffer(GL_RENDERBUFFER, rbo); PROCS.glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER, GLeglImageOES(img.img.0)); glBindRenderbuffer(GL_RENDERBUFFER, 0); Ok(Rc::new(GlRenderBuffer { img: img.clone(), ctx: ctx.clone(), rbo, })) } pub unsafe fn create_framebuffer(self: &Rc) -> Result { let mut fbo = 0; glGenFramebuffers(1, &mut fbo); glBindFramebuffer(GL_FRAMEBUFFER, fbo); glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, self.rbo, ); let status = glCheckFramebufferStatus(GL_FRAMEBUFFER); glBindFramebuffer(GL_FRAMEBUFFER, 0); let fb = GlFrameBuffer { _rb: Some(self.clone()), _tex: None, ctx: self.ctx.clone(), fbo, width: self.img.width, height: self.img.height, }; if status != GL_FRAMEBUFFER_COMPLETE { return Err(RenderError::CreateFramebuffer); } Ok(fb) } } impl Drop for GlRenderBuffer { fn drop(&mut self) { let _ = self.ctx.with_current(|| { unsafe { glDeleteRenderbuffers(1, &self.rbo); } Ok(()) }); } }