webgl_rc/
frame_buffer.rs

1use crate::{DepthBuffer, Gl, GlError, Settings, Texture};
2use std::rc::Rc;
3use web_sys::{WebGlFramebuffer, WebGlRenderingContext};
4
5#[derive(Clone, Debug)]
6struct FrameBufferInfo {
7    gl: Gl,
8    handle: WebGlFramebuffer,
9}
10
11impl Drop for FrameBufferInfo {
12    fn drop(&mut self) {
13        self.gl.context().delete_framebuffer(Some(&self.handle));
14    }
15}
16
17#[derive(Clone, Debug)]
18pub struct FrameBuffer {
19    data: Rc<FrameBufferInfo>,
20    color_buffer: Option<Texture>,
21    depth_buffer: Option<DepthBuffer>,
22}
23
24impl PartialEq for FrameBuffer {
25    fn eq(&self, other: &Self) -> bool {
26        self.data.handle == other.data.handle
27    }
28}
29
30impl Eq for FrameBuffer {}
31
32impl FrameBuffer {
33    pub fn new(gl: Gl) -> Result<FrameBuffer, GlError> {
34        Ok(FrameBuffer {
35            data: Rc::new(FrameBufferInfo {
36                handle: gl
37                    .context()
38                    .create_framebuffer()
39                    .ok_or(GlError::FrameBufferError)?,
40                gl,
41            }),
42            color_buffer: None,
43            depth_buffer: None,
44        })
45    }
46    pub fn set_color_buffer(&mut self, texture: Option<Texture>) -> &mut Self {
47        self.color_buffer = texture.clone();
48        self.data
49            .gl
50            .apply(Gl::settings().frame_buffer(self.clone()), || {
51                self.data.gl.context().framebuffer_texture_2d(
52                    WebGlRenderingContext::FRAMEBUFFER,
53                    WebGlRenderingContext::COLOR_ATTACHMENT0,
54                    WebGlRenderingContext::TEXTURE_2D,
55                    self.color_buffer.as_ref().map(|buffer| buffer.handle()),
56                    0,
57                );
58            });
59        self
60    }
61    pub fn set_depth_buffer(&mut self, buffer: Option<DepthBuffer>) -> &mut Self {
62        self.depth_buffer = buffer;
63        self.data
64            .gl
65            .apply(Gl::settings().frame_buffer(self.clone()), || {
66                self.data.gl.context().framebuffer_renderbuffer(
67                    WebGlRenderingContext::FRAMEBUFFER,
68                    WebGlRenderingContext::DEPTH_ATTACHMENT,
69                    WebGlRenderingContext::RENDERBUFFER,
70                    self.depth_buffer.as_ref().map(|buffer| buffer.handle()),
71                );
72            });
73        self
74    }
75    pub fn color_buffer(&self) -> Option<Texture> {
76        self.color_buffer.clone()
77    }
78    pub fn depth_buffer(&self) -> Option<DepthBuffer> {
79        self.depth_buffer.clone()
80    }
81
82    pub(crate) fn handle(&self) -> &WebGlFramebuffer {
83        &self.data.handle
84    }
85}