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 super::*;

pub struct ColorData<'a> {
    width: usize,
    height: usize,
    buffer: Vec<raw::UByte>, // TODO: Box<[T]>
    phantom_data: PhantomData<&'a i32>,
}

impl<'a> ColorData<'a> {
    pub fn get(&self, x: usize, y: usize) -> Color<u8> {
        assert!(x < self.width);
        assert!(y < self.height);
        Color::rgba(
            self.buffer[(y * self.width + x) * 4],
            self.buffer[(y * self.width + x) * 4 + 1],
            self.buffer[(y * self.width + x) * 4 + 2],
            self.buffer[(y * self.width + x) * 4 + 3],
        )
    }
}

impl<'a> FramebufferRead<'a> {
    pub fn read_color(&self) -> ColorData {
        let gl = &self.fbo.ugli.inner;
        // TODO
        // if self.fbo.handle != 0 {
        //     if let ColorAttachmentRead::None = self.color {
        //         panic!("Framebuffer has no color attached");
        //     }
        // }
        self.fbo.bind();
        let result = unsafe {
            let buffer_len = self.size.x * self.size.y * 4;
            let mut buffer = Vec::with_capacity(buffer_len);
            buffer.set_len(buffer_len);
            gl.read_pixels(
                0,
                0,
                self.size.x as raw::SizeI,
                self.size.y as raw::SizeI,
                raw::RGBA,
                raw::UNSIGNED_BYTE,
                &mut buffer,
            );
            ColorData {
                width: self.size.x,
                height: self.size.y,
                buffer,
                phantom_data: PhantomData,
            }
        };
        self.fbo.ugli.debug_check();
        result
    }

    pub fn copy_to_texture(
        &self,
        texture: &mut Texture,
        source_rect: AABB<usize>,
        dest: Vec2<usize>,
    ) {
        let gl = &self.fbo.ugli.inner;
        self.fbo.bind();
        gl.bind_texture(raw::TEXTURE_2D, &texture.handle);
        gl.copy_tex_sub_image_2d(
            raw::TEXTURE_2D,
            0,
            dest.x as raw::Int,
            dest.y as raw::Int,
            source_rect.bottom_left().x as raw::Int,
            source_rect.bottom_left().y as raw::Int,
            source_rect.width() as raw::SizeI,
            source_rect.height() as raw::SizeI,
        );
        self.fbo.ugli.debug_check();
    }
}