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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
pub use glin::fbo::*;
use glin::{OffscreenBuffer, Fbo, Rect, Texture};
use std::cell::UnsafeCell;
use glin::Result;
use super::Renderer;
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 fbo_blit;
let fbo;
if samples > 0 {
let color_attachment = gl.new_fbo_color_attachment()
.render_buffer_multisampled(w, h, samples, format)?;
fbo = gl.new_fbo().from_color(color_attachment)?;
let color_attachment = gl.new_fbo_color_attachment()
.texture(w, h, format)?;
fbo_blit = Some(UnsafeCell::new(gl.new_fbo().from_color(color_attachment)?))
}else{
let color_attachment = gl.new_fbo_color_attachment()
.texture(w, h, format)?;
fbo = gl.new_fbo().from_color(color_attachment)?;
fbo_blit = None;
};
Ok(SimpleFbo{
fbo,
fbo_blit: fbo_blit,
changed: UnsafeCell::new(false),
})
}
pub fn blit(&self, fbo2: &mut Fbo, src_rect: &Rect, dst_rect: &Rect){
self.fbo.blit(fbo2, src_rect, dst_rect)
}
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::TextureLevel(ref tex, _) => Some(tex),
_ => None
}).unwrap()
}
pub fn depth(&self) -> &DepthAttachment{
self.non_multisampled_buffer().depth().unwrap()
}
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<'a> OffscreenBuffer for &'a SimpleFbo{
type ColorAttach = ColorAttachment;
type DepthAttach = DepthAttachment;
fn render_buffer(&self) -> &Fbo{
unsafe{
(*self.changed.get()) = true;
}
&self.fbo
}
fn color_attachment(&self, idx: usize) -> Option<&ColorAttachment>{
self.non_multisampled_buffer().color(idx)
}
fn depth_attachment(&self) -> Option<&DepthAttachment>{
self.non_multisampled_buffer().depth()
}
}