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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102

use __gl;
use __gl::types::GLuint;

use Region;
use device::Device;

///
pub enum ClearAttachment {
    ColorInt(usize, [i32; 4]),
    ColorUint(usize, [u32; 4]),
    ColorFloat(usize, [f32; 4]),
    Depth(f32),
    Stencil(i32),
    DepthStencil(f32, i32),
}

///
pub enum Attachment {
    Color(usize),
    Depth,
    Stencil,
    DepthStencil,
}

///
pub struct Framebuffer(GLuint);

impl Framebuffer {
    pub const DEFAULT: &'static Self = &Framebuffer(0);
}

///
pub struct Renderbuffer(GLuint);

impl Device {
    ///
    pub fn create_framebuffer(&self) -> Framebuffer {
        let mut framebuffer = 0;
        unsafe { self.0.CreateFramebuffers(1, &mut framebuffer); }
        self.get_error("CreateFramebuffers");

        Framebuffer(framebuffer)
    }

    ///
    pub fn delete_framebuffer(&self, framebuffer: Framebuffer) {
        unsafe { self.0.DeleteFramebuffers(1, &framebuffer.0); }
        self.get_error("DeleteFramebuffers");
    }

    ///
    pub fn create_renderbuffer(&self) -> Renderbuffer {
        let mut renderbuffer = 0;
        unsafe { self.0.CreateRenderbuffers(1, &mut renderbuffer); }
        self.get_error("CreateRenderbuffers");

        Renderbuffer(renderbuffer)
    }

    ///
    pub fn delete_renderbuffer(&self, renderbuffer: Renderbuffer) {
        unsafe { self.0.DeleteRenderbuffers(1, &renderbuffer.0); }
        self.get_error("DeleteRenderbuffers");
    }

    /// Clear framebuffer attachment.
    pub fn clear_attachment(&self, fb: &Framebuffer, cv: ClearAttachment) {
        unsafe {
            match cv {
                ClearAttachment::ColorInt(id, color) => {
                    self.0.ClearNamedFramebufferiv(fb.0, __gl::COLOR, id as _, color.as_ptr());
                }
                ClearAttachment::ColorUint(id, color) => {
                    self.0.ClearNamedFramebufferuiv(fb.0, __gl::COLOR, id as _, color.as_ptr());
                }
                ClearAttachment::ColorFloat(id, color) => {
                    self.0.ClearNamedFramebufferfv(fb.0, __gl::COLOR, id as _, color.as_ptr());
                }
                ClearAttachment::Depth(depth) => {
                    self.0.ClearNamedFramebufferfi(fb.0, __gl::DEPTH, 0, depth, 0);
                }
                ClearAttachment::Stencil(stencil) => {
                    self.0.ClearNamedFramebufferfi(fb.0, __gl::STENCIL, 0, 0.0, stencil);
                }
                ClearAttachment::DepthStencil(depth, stencil) => {
                    self.0.ClearNamedFramebufferfi(fb.0, __gl::DEPTH_STENCIL, 0, depth, stencil);
                }
            }
        }
    }

    ///
    pub fn invalidate_framebuffer(
        &self,
        _framebuffer: &Framebuffer,
        _attachments: &[Attachment],
        _region: Region,
    ) {
        unimplemented!()
    }
}