1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
use alloc::vec::Vec; use core::ops::Drop; use gl; use gl::types::*; use super::gl_texture::GLTexture; use super::gl_enums::Attachment; pub struct GLFramebuffer { id: GLuint, } impl GLFramebuffer { #[inline(always)] pub fn new(gl_texture: &GLTexture, buffers: &[Attachment], level: isize) -> Self { let framebuffer = GLFramebuffer { id: { let mut id = 0; unsafe { gl::GenFramebuffers(1, &mut id); } id }, }; framebuffer.set(gl_texture, buffers, level); framebuffer } #[inline(always)] pub fn id(&self) -> GLuint { self.id } #[inline] pub fn bind(&self) -> &Self { unsafe { gl::BindFramebuffer(gl::FRAMEBUFFER, self.id); } self } #[inline] pub fn unbind(&self) -> &Self { unsafe { gl::BindFramebuffer(gl::FRAMEBUFFER, 0); } self } #[inline] pub fn set(&self, gl_texture: &GLTexture, buffers: &[Attachment], level: isize) { let gl_texture_id = gl_texture.id(); let mut gl_enums = Vec::with_capacity(buffers.len()); for i in 0..buffers.len() { gl_enums.push(buffers[i].to_gl()); } unsafe { gl::BindFramebuffer(gl::FRAMEBUFFER, self.id); gl::BindTexture(gl_texture.kind().to_gl(), gl_texture_id); for i in 0..gl_enums.len() { gl::FramebufferTexture(gl::FRAMEBUFFER, gl_enums[i], gl_texture_id, level as GLint); } gl::DrawBuffers(buffers.len() as GLint, gl_enums.as_ptr()); if gl::CheckFramebufferStatus(gl::FRAMEBUFFER) != gl::FRAMEBUFFER_COMPLETE { panic!("Check framebuffer status failed"); } } } } impl Drop for GLFramebuffer { #[inline] fn drop(&mut self) { if self.id != 0 { unsafe { gl::DeleteFramebuffers(1, &self.id); } } } }