reverie_engine_opengl/
context.rs

1use std::ffi::c_void;
2
3use crate::{gl::Gl, window::Window};
4
5pub trait ContextBackend {
6    fn new(window: &Window) -> Self;
7    fn get_proc_address(&self, symbol: &str) -> *const c_void;
8    /// この[`Context`]を描画先として設定する
9    fn make_current(&self);
10    fn make_not_current(&self);
11    fn swap_buffers(&self);
12}
13
14#[cfg(feature = "raw_gl_context")]
15impl ContextBackend for raw_gl_context::GlContext {
16    fn new(window: &Window) -> Self {
17        Self::create(&window.window, raw_gl_context::GlConfig::default()).unwrap()
18    }
19    fn get_proc_address(&self, symbol: &str) -> *const c_void {
20        self.get_proc_address(symbol)
21    }
22
23    fn make_current(&self) {
24        self.make_current()
25    }
26
27    fn make_not_current(&self) {
28        self.make_not_current()
29    }
30
31    fn swap_buffers(&self) {
32        self.swap_buffers()
33    }
34}
35
36#[cfg(feature = "glutin")]
37impl ContextBackend for glutin::RawContext<glutin::PossiblyCurrent> {
38    #[cfg(target_os = "windows")]
39    fn new(window: &Window) -> Self {
40        use glutin::platform::windows::RawContextExt;
41        use winit::platform::windows::WindowExtWindows;
42        let hwnd = window.window.hwnd();
43        let raw_context = unsafe { glutin::ContextBuilder::new().build_raw_context(hwnd) }.unwrap();
44
45        unsafe { raw_context.make_current() }.unwrap()
46    }
47
48    #[cfg(not(target_os = "windows"))]
49    fn new(_window: &Window) -> Self {
50        panic!("glutin rawcontext is not implemented for this platform");
51    }
52
53    fn get_proc_address(&self, symbol: &str) -> *const c_void {
54        self.get_proc_address(symbol)
55    }
56
57    fn make_current(&self) {
58        // todo
59    }
60
61    fn make_not_current(&self) {
62        // todo
63    }
64
65    fn swap_buffers(&self) {
66        self.swap_buffers().unwrap();
67    }
68}
69
70#[derive(Debug)]
71pub struct Context<C: ContextBackend> {
72    backend: C,
73    gl: Gl,
74}
75
76impl<C: ContextBackend> Context<C> {
77    pub fn new(window: &Window) -> Self {
78        let backend = C::new(window);
79        let gl = Gl::load_with(|symbol| backend.get_proc_address(symbol) as *const _);
80
81        Self { backend, gl }
82    }
83    pub fn gl(&self) -> Gl {
84        Gl::clone(&self.gl)
85    }
86
87    /// この[`Context`]を描画先として設定する
88    pub fn make_current(&self) {
89        self.backend.make_current();
90    }
91
92    pub fn make_not_current(&self) {
93        self.backend.make_not_current();
94    }
95
96    pub fn swap_buffers(&self) {
97        self.backend.swap_buffers();
98    }
99}