reverie_engine_opengl/
context.rs1use 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 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 }
60
61 fn make_not_current(&self) {
62 }
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 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}