1
0
Fork 0
forked from wry/wry
wry/src/render/gl/render_buffer.rs
2022-04-07 17:31:31 +02:00

77 lines
2.2 KiB
Rust

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<EglImage>,
pub ctx: Rc<EglContext>,
rbo: GLuint,
}
impl GlRenderBuffer {
pub unsafe fn from_image(
img: &Rc<EglImage>,
ctx: &Rc<EglContext>,
) -> Result<Rc<GlRenderBuffer>, 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<Self>) -> Result<GlFrameBuffer, RenderError> {
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(())
});
}
}