/
sharing.rs
150 lines (132 loc) · 5.6 KB
/
sharing.rs
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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
mod support;
use glutin::dpi::PhysicalSize;
use glutin::event::{Event, WindowEvent};
use glutin::event_loop::{ControlFlow, EventLoop};
use glutin::window::WindowBuilder;
use glutin::ContextBuilder;
use support::{gl, ContextCurrentWrapper, ContextTracker, ContextWrapper};
fn make_renderbuf(gl: &support::Gl, size: PhysicalSize<u32>) -> gl::types::GLuint {
let mut render_buf = 0;
unsafe {
gl.gl.GenRenderbuffers(1, &mut render_buf);
gl.gl.BindRenderbuffer(gl::RENDERBUFFER, render_buf);
gl.gl.RenderbufferStorage(gl::RENDERBUFFER, gl::RGB8, size.width as _, size.height as _);
}
render_buf
}
fn main() {
let el = EventLoop::new();
let size = PhysicalSize::new(768, 480);
let mut ct = ContextTracker::default();
let headless_context =
ContextBuilder::new().build_headless(&el, PhysicalSize::new(1, 1)).unwrap();
let wb = WindowBuilder::new().with_title("A fantastic window!").with_inner_size(size);
let windowed_context =
ContextBuilder::new().with_shared_lists(&headless_context).build_windowed(wb, &el).unwrap();
let headless_id =
ct.insert(ContextCurrentWrapper::NotCurrent(ContextWrapper::Headless(headless_context)));
let windowed_id =
ct.insert(ContextCurrentWrapper::NotCurrent(ContextWrapper::Windowed(windowed_context)));
let windowed_context = ct.get_current(windowed_id).unwrap();
println!(
"Pixel format of the window's GL context: {:?}",
windowed_context.windowed().get_pixel_format()
);
let glw = support::load(&windowed_context.windowed().context());
let render_buf = make_renderbuf(&glw, size);
let mut window_fb = 0;
unsafe {
glw.gl.GenFramebuffers(1, &mut window_fb);
// Both `GL_DRAW_FRAMEBUFFER` and `GL_READ_FRAMEBUFFER` need to be
// non-zero for `glFramebufferRenderbuffer`. We can change
// `GL_DRAW_FRAMEBUFFER` after.
glw.gl.BindFramebuffer(gl::FRAMEBUFFER, window_fb);
glw.gl.FramebufferRenderbuffer(
gl::FRAMEBUFFER,
gl::COLOR_ATTACHMENT0,
gl::RENDERBUFFER,
render_buf,
);
glw.gl.BindFramebuffer(gl::DRAW_FRAMEBUFFER, 0);
glw.gl.Viewport(0, 0, size.width as _, size.height as _);
}
std::mem::drop(windowed_context);
let headless_context = ct.get_current(headless_id).unwrap();
let glc = support::load(&headless_context.headless());
let mut context_fb = 0;
unsafe {
// Using the fb backing a pbuffer is very much a bad idea. Fails on
// many platforms, and is deprecated. Better just make your own fb.
glc.gl.GenFramebuffers(1, &mut context_fb);
glc.gl.BindFramebuffer(gl::FRAMEBUFFER, context_fb);
glc.gl.BindRenderbuffer(gl::RENDERBUFFER, render_buf);
glc.gl.FramebufferRenderbuffer(
gl::FRAMEBUFFER,
gl::COLOR_ATTACHMENT0,
gl::RENDERBUFFER,
render_buf,
);
glc.gl.Viewport(0, 0, size.width as _, size.height as _);
}
std::mem::drop(headless_context);
el.run(move |event, _, control_flow| {
println!("{:?}", event);
*control_flow = ControlFlow::Wait;
match event {
Event::LoopDestroyed => {
unsafe {
let windowed_context = ct.get_current(windowed_id).unwrap();
glw.gl.DeleteFramebuffers(1, &window_fb);
glw.gl.DeleteRenderbuffers(1, &render_buf);
std::mem::drop(windowed_context);
let _ = ct.get_current(headless_id).unwrap();
glc.gl.DeleteFramebuffers(1, &context_fb);
}
return;
}
Event::WindowEvent { event, .. } => match event {
WindowEvent::Resized(physical_size) => {
let windowed_context = ct.get_current(windowed_id).unwrap();
windowed_context.windowed().resize(physical_size);
unsafe {
windowed_context.windowed().swap_buffers().unwrap();
glw.gl.RenderbufferStorage(
gl::RENDERBUFFER,
gl::RGB8,
size.width as _,
size.height as _,
);
glw.gl.Viewport(0, 0, size.width as _, size.height as _);
std::mem::drop(windowed_context);
let _ = ct.get_current(headless_id).unwrap();
glc.gl.Viewport(0, 0, size.width as _, size.height as _);
}
}
WindowEvent::CloseRequested => *control_flow = ControlFlow::Exit,
_ => (),
},
Event::RedrawRequested(_) => {
let headless_context = ct.get_current(headless_id).unwrap();
glc.draw_frame([1.0, 0.5, 0.7, 1.0]);
std::mem::drop(headless_context);
let windowed_context = ct.get_current(windowed_id).unwrap();
unsafe {
glw.gl.BlitFramebuffer(
0,
0,
size.width as _,
size.height as _,
0,
0,
size.width as _,
size.height as _,
gl::COLOR_BUFFER_BIT,
gl::NEAREST,
);
}
windowed_context.windowed().swap_buffers().unwrap();
}
_ => (),
}
});
}