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
151
152
extern crate glutin;

mod support;

use support::gl;
use glutin::GlContext;

fn main() {
    let mut events_loop = glutin::EventsLoop::new();
    let mut size = glutin::dpi::PhysicalSize::new(768., 480.);

    let context = glutin::ContextBuilder::new();
    let gl_context = glutin::Context::new(&events_loop, context, true).unwrap();

    let window = glutin::WindowBuilder::new().with_title("A fantastic window!")
        .with_dimensions(glutin::dpi::LogicalSize::from_physical(size, 1.0));
    let context = glutin::ContextBuilder::new()
        .with_shared_lists(&gl_context);
    let gl_window = unsafe { glutin::GlWindow::new_shared(window, context, &events_loop).unwrap() };

    let _ = unsafe { gl_window.make_current() };
    println!("Pixel format of the window's GL context: {:?}", gl_window.get_pixel_format());
    let glw = support::load(&gl_window.context());

    let mut render_tex = 0;
    unsafe {
        glw.gl.GenTextures(1, &mut render_tex);
        glw.gl.BindTexture(gl::TEXTURE_2D, render_tex);
        glw.gl.TexStorage2D(
            gl::TEXTURE_2D,
            1,
            gl::SRGB8_ALPHA8,
            size.width as _,
            size.height as _,
        );
    }

    let mut window_fb = 0;
    unsafe {
        glw.gl.GenFramebuffers(1, &mut window_fb);
        glw.gl.BindFramebuffer(gl::READ_FRAMEBUFFER, window_fb);
        glw.gl.BindFramebuffer(gl::DRAW_FRAMEBUFFER, 0);
        glw.gl.FramebufferTexture2D(
            gl::READ_FRAMEBUFFER,
            gl::COLOR_ATTACHMENT0,
            gl::TEXTURE_2D,
            render_tex,
            0,
        );
    }

    let _ = unsafe { gl_context.make_current() };
    let glc = support::load(&gl_context);

    let mut context_fb = 0;
    unsafe {
        glc.gl.GenFramebuffers(1, &mut context_fb);
        glc.gl.BindFramebuffer(gl::FRAMEBUFFER, context_fb);
        glc.gl.FramebufferTexture2D(
            gl::FRAMEBUFFER,
            gl::COLOR_ATTACHMENT0,
            gl::TEXTURE_2D,
            render_tex,
            0,
        );
        glc.gl.Viewport(0, 0, size.width as _, size.height as _);
    }

    let mut running = true;
    while running {
        events_loop.poll_events(|event| {
            println!("{:?}", event);
            match event {
                glutin::Event::WindowEvent { event, .. } => match event {
                    glutin::WindowEvent::CloseRequested => running = false,
                    glutin::WindowEvent::Resized(logical_size) => {
                        let _ = unsafe { gl_window.make_current() };
                        let dpi_factor = gl_window.get_hidpi_factor();
                        size = logical_size.to_physical(dpi_factor);
                        gl_window.resize(size);

                        unsafe {
                            let _ = gl_window.make_current();
                            glw.gl.DeleteTextures(1, &render_tex);
                            glw.gl.DeleteFramebuffers(1, &window_fb);

                            glw.gl.GenTextures(1, &mut render_tex);
                            glw.gl.BindTexture(gl::TEXTURE_2D, render_tex);
                            glw.gl.TexStorage2D(
                                gl::TEXTURE_2D,
                                1,
                                gl::SRGB8_ALPHA8,
                                size.width as _,
                                size.height as _,
                            );

                            glw.gl.GenFramebuffers(1, &mut window_fb);
                            glw.gl.BindFramebuffer(gl::READ_FRAMEBUFFER, window_fb);
                            glw.gl.BindFramebuffer(gl::DRAW_FRAMEBUFFER, 0);
                            glw.gl.FramebufferTexture2D(
                                gl::READ_FRAMEBUFFER,
                                gl::COLOR_ATTACHMENT0,
                                gl::TEXTURE_2D,
                                render_tex,
                                0,
                            );

                            let _ = gl_context.make_current();
                            glc.gl.DeleteFramebuffers(1, &context_fb);

                            glc.gl.GenFramebuffers(1, &mut context_fb);
                            glc.gl.BindFramebuffer(gl::FRAMEBUFFER, context_fb);
                            glc.gl.FramebufferTexture2D(
                                gl::FRAMEBUFFER,
                                gl::COLOR_ATTACHMENT0,
                                gl::TEXTURE_2D,
                                render_tex,
                                0,
                            );

                            glc.gl.Viewport(0, 0, size.width as _, size.height as _);
                        }
                    },
                    _ => (),
                },
                _ => ()
            }
        });

        let _ = unsafe { gl_context.make_current() };
        glc.draw_frame([1.0, 0.5, 0.7, 1.0]);

        let _ = unsafe { gl_window.make_current() };
        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,
            );
        }
        let _ = gl_window.swap_buffers();
    }

    unsafe {
        let _ = gl_window.make_current();
        glw.gl.DeleteTextures(1, &render_tex);
        glw.gl.DeleteFramebuffers(1, &window_fb);
        let _ = gl_context.make_current();
        glc.gl.DeleteFramebuffers(1, &context_fb);
    }
}