1extern crate gl;
2
3use crate::{GlBind, GlObject, GlTarget, GlEnum};
4use crate::texture::GlTexture;
5
6#[derive(Debug, PartialEq, Eq, Copy, Clone)]
7pub enum FramebufferAttachment {
8 ColorAttachment(u32),
9 DepthAttachment,
10 StencilAttachment
11}
12
13impl Default for FramebufferAttachment {
14 fn default() -> Self {
15 FramebufferAttachment::ColorAttachment(0)
16 }
17}
18
19impl GlEnum for FramebufferAttachment {
20 fn to_enum(&self) -> u32 {
21 match self {
22 Self::ColorAttachment(c) => { return gl::COLOR_ATTACHMENT0 + c; },
23 Self::DepthAttachment => { return gl::DEPTH_ATTACHMENT },
24 Self::StencilAttachment => { return gl::STENCIL_ATTACHMENT }
25 }
26 }
27}
28
29#[derive(Default, Debug, Eq, PartialEq)]
30pub struct Framebuffer(u32);
31
32impl Framebuffer {
36 pub fn new() -> Result<Self, String> {
37 let mut handle: u32 = 0;
38 unsafe {
39 gl::GenFramebuffers(1, &mut handle);
40 }
41 Ok(Framebuffer(handle))
42 }
43
44 pub fn attach_texture<T: GlTexture>(&self, attachment: FramebufferAttachment, texture: &T) {
45 unsafe {
46 gl::FramebufferTexture2D(
47 Self::target(),
48 attachment.to_enum(),
49 T::target(), texture.get_id(), 0
50 );
51 }
52 }
53
54 pub fn bind_read(&self) {
55 unsafe { gl::BindFramebuffer(gl::READ_FRAMEBUFFER, self.0) };
56 }
57
58 pub fn bind_draw(&self) {
59 unsafe { gl::BindFramebuffer(gl::DRAW_FRAMEBUFFER, self.0) };
60 }
61}
62
63impl GlTarget for Framebuffer {
64 fn target() -> u32 { gl::FRAMEBUFFER }
65 fn binding() -> u32 { gl::FRAMEBUFFER_BINDING }
66}
67
68impl GlObject for Framebuffer {
69 fn get_id(&self) -> u32 {
70 self.0
71 }
72}
73
74impl GlBind for Framebuffer {
75 fn bind(&self) {
76 unsafe { gl::BindFramebuffer(Self::target(), self.0) };
77 }
78
79 fn unbind(&self) {
80 unsafe { gl::BindFramebuffer(Self::target(), 0) };
81 }
82}
83
84impl Drop for Framebuffer {
85 fn drop(&mut self) {
86 unsafe { gl::DeleteFramebuffers(1, &self.0) };
87 }
88}