Skip to main content

glium/framebuffer/
default_fb.rs

1//! Contains everything related to the default framebuffer.
2
3use std::rc::Rc;
4
5use crate::backend::Facade;
6use crate::context::Context;
7
8use crate::{DrawParameters, BlitMask};
9use crate::FboAttachments;
10use crate::Rect;
11use crate::BlitTarget;
12use crate::ContextExt;
13use crate::ToGlEnum;
14use crate::ops;
15use crate::uniforms;
16
17use crate::{Program, Surface};
18use crate::DrawError;
19
20use crate::fbo;
21use crate::index;
22use crate::vertex;
23use crate::framebuffer::{SimpleFrameBuffer, MultiOutputFrameBuffer};
24use crate::uniforms::MagnifySamplerFilter;
25
26/// One of the color attachments on the default framebuffer.
27#[derive(Copy, Clone, Debug)]
28pub enum DefaultFramebufferAttachment {
29    /// The backbuffer for the left eye. Equivalent to the backbuffer if stereoscopy is disabled.
30    BackLeft,
31    /// The backbuffer for the right eye. May not be present.
32    BackRight,
33    /// The frontbuffer for the left eye. Equivalent to the frontbuffer if stereoscopy is disabled.
34    /// May not be accessible.
35    FrontLeft,
36    /// The frontbuffer for the right eye. May not be present or accessible.
37    FrontRight,
38}
39
40/// A framebuffer which has only one color attachment.
41pub struct DefaultFramebuffer {
42    context: Rc<Context>,
43    attachment: DefaultFramebufferAttachment,
44}
45
46impl DefaultFramebuffer {
47    /// Creates a `DefaultFramebuffer` with the back left buffer.
48    #[inline]
49    pub fn back_left<F: ?Sized>(facade: &F) -> DefaultFramebuffer where F: Facade {
50        DefaultFramebuffer {
51            context: facade.get_context().clone(),
52            attachment: DefaultFramebufferAttachment::BackLeft,
53        }
54    }
55}
56
57impl Surface for DefaultFramebuffer {
58    #[inline]
59    fn clear(&mut self, rect: Option<&Rect>, color: Option<(f32, f32, f32, f32)>, color_srgb: bool,
60             depth: Option<f32>, stencil: Option<i32>)
61    {
62        // TODO: wrong attachment
63        ops::clear(&self.context, None, None, color, color_srgb, depth, stencil);
64    }
65
66    fn get_dimensions(&self) -> (u32, u32) {
67        self.context.get_framebuffer_dimensions()
68    }
69
70    fn get_depth_buffer_bits(&self) -> Option<u16> {
71        self.context.capabilities().depth_bits
72    }
73
74    fn get_stencil_buffer_bits(&self) -> Option<u16> {
75        self.context.capabilities().stencil_bits
76    }
77
78    fn draw<'a, 'b, V, I, U>(&mut self, vertex_buffer: V,
79                         index_buffer: I, program: &Program, uniforms: &U,
80                         draw_parameters: &DrawParameters<'_>) -> Result<(), DrawError>
81                         where I: Into<index::IndicesSource<'a>>, U: uniforms::Uniforms,
82                         V: vertex::MultiVerticesSource<'b>
83    {
84        if !self.has_depth_buffer() && (draw_parameters.depth.test.requires_depth_buffer() ||
85                draw_parameters.depth.write)
86        {
87            return Err(DrawError::NoDepthBuffer);
88        }
89
90        if let Some(viewport) = draw_parameters.viewport {
91            if viewport.width > self.context.capabilities().max_viewport_dims.0
92                    as u32
93            {
94                return Err(DrawError::ViewportTooLarge);
95            }
96            if viewport.height > self.context.capabilities().max_viewport_dims.1
97                    as u32
98            {
99                return Err(DrawError::ViewportTooLarge);
100            }
101        }
102
103        // TODO: wrong attachment
104        ops::draw(&self.context, None, vertex_buffer, index_buffer.into(), program,
105                  uniforms, draw_parameters, self.get_dimensions())
106    }
107
108    #[inline]
109    fn blit_color<S>(&self, source_rect: &Rect, target: &S, target_rect: &BlitTarget,
110                     filter: uniforms::MagnifySamplerFilter) where S: Surface
111    {
112        target.blit_from_frame(source_rect, target_rect, filter)
113    }
114
115    #[inline]
116    fn blit_buffers_from_frame(&self, source_rect: &Rect, target_rect: &BlitTarget, filter: MagnifySamplerFilter, mask: BlitMask) {
117        ops::blit(&self.context, None, self.get_attachments(),
118                  mask.to_glenum(), source_rect, target_rect, filter.to_glenum())
119    }
120
121    #[inline]
122    fn blit_buffers_from_simple_framebuffer(&self, source: &SimpleFrameBuffer<'_>, source_rect: &Rect, target_rect: &BlitTarget, filter: MagnifySamplerFilter, mask: BlitMask) {
123        ops::blit(&self.context, source.get_attachments(), self.get_attachments(),
124                  mask.to_glenum(), source_rect, target_rect, filter.to_glenum())
125    }
126
127    #[inline]
128    fn blit_buffers_from_multioutput_framebuffer(&self, source: &MultiOutputFrameBuffer<'_>, source_rect: &Rect, target_rect: &BlitTarget, filter: MagnifySamplerFilter, mask: BlitMask) {
129        ops::blit(&self.context, source.get_attachments(), self.get_attachments(),
130                  mask.to_glenum(), source_rect, target_rect, filter.to_glenum())
131    }
132}
133
134impl FboAttachments for DefaultFramebuffer {
135    #[inline]
136    fn get_attachments(&self) -> Option<&fbo::ValidatedAttachments<'_>> {
137        None
138    }
139}