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
103
104
105
106
107
108
109
pub use glin::fbo::*;
use glin::{OffscreenBuffer, Fbo, Rect, Texture};
use std::cell::UnsafeCell;
use glin::Result;
pub struct SimpleFbo{
fbo: Fbo,
fbo_blit: Option<UnsafeCell<Fbo>>,
changed: UnsafeCell<bool>,
}
impl SimpleFbo{
pub(crate) fn new(gl: &::Renderer, w: u32, h: u32, samples: u32, format: ColorFormat) -> Result<SimpleFbo>{
let color_attachment = gl.new_fbo_color_attachment()
.texture_multisampled(w, h, samples, format)?;
let fbo = gl.new_fbo().from_color(color_attachment)?;
let fbo_blit = if samples > 0 {
let color_attachment = gl.new_fbo_color_attachment()
.texture(w, h, format)?;
Some(UnsafeCell::new(gl.new_fbo().from_color(color_attachment)?))
}else{
None
};
Ok(SimpleFbo{
fbo,
fbo_blit: fbo_blit,
changed: UnsafeCell::new(false),
})
}
#[cfg(not(feature = "gles"))]
pub fn blit(&self, fbo2: &mut Fbo, src_rect: &Rect, dst_rect: &Rect){
self.fbo.blit(fbo2, src_rect, dst_rect)
}
#[cfg(not(feature = "gles"))]
pub fn blit_depth(&self, fbo2: &mut Fbo, src_rect: &Rect, dst_rect: &Rect){
self.fbo.blit_depth(fbo2, src_rect, dst_rect)
}
pub fn color_tex(&self, idx: usize) -> &Texture{
self.non_multisampled_buffer().color(idx).and_then(|color| match color{
&ColorAttachment::Texture(ref tex) => Some(tex),
_ => None
}).unwrap()
}
pub fn depth(&self) -> &DepthAttachment{
self.non_multisampled_buffer().depth()
}
pub fn viewport(&self) -> Rect{
self.fbo.viewport()
}
pub fn width(&self) -> u32{
self.fbo.width()
}
pub fn height(&self) -> u32{
self.fbo.height()
}
pub fn aspect_ratio(&self) -> f32{
self.fbo.aspect_ratio()
}
pub fn size(&self) -> (u32, u32){
self.fbo.size()
}
pub fn non_multisampled_buffer(&self) -> &Fbo{
unsafe{
if let Some(fbo_blit) = self.fbo_blit.as_ref() {
if *self.changed.get() {
self.fbo.blit(&mut *fbo_blit.get(), &self.fbo.viewport(), &self.fbo.viewport());
(*self.changed.get()) = false;
}
&*fbo_blit.get()
}else{
&self.fbo
}
}
}
}
impl OffscreenBuffer for SimpleFbo{
fn render_buffer(&self) -> &Fbo{
unsafe{
(*self.changed.get()) = true;
}
&self.fbo
}
}