77 lines
2.2 KiB
Rust
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(())
|
|
});
|
|
}
|
|
}
|