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
|
#![deny(clippy::all, clippy::pedantic)]
use std::ffi::CString;
use std::process::abort;
use glutin::context::{NotCurrentContext, PossiblyCurrentContext};
use glutin::display::GetGlDisplay;
use glutin::prelude::{GlDisplay, NotCurrentGlContext, PossiblyCurrentGlContext};
use glutin::surface::{Surface, SurfaceTypeTrait};
pub mod buffer;
pub mod data_types;
pub mod debug;
pub mod misc;
pub mod shader;
pub mod texture;
pub mod vertex_array;
pub struct ContextWithFns
{
context: PossiblyCurrentContext,
fns: Box<sys::Gl>,
}
impl ContextWithFns
{
/// Returns a new `ContextWithFns`.
///
/// # Errors
/// Returns `Err` if making this context current fails.
pub fn new<SurfaceType: SurfaceTypeTrait>(
context: NotCurrentContext,
surface: &Surface<SurfaceType>,
) -> Result<Self, Error>
{
let context = context
.make_current(surface)
.map_err(Error::MakeContextCurrentFailed)?;
let display = context.display();
let gl = sys::Gl::load_with(|symbol| {
let Ok(symbol) = CString::new(symbol) else {
eprintln!("GL symbol contains nul byte");
abort();
};
display.get_proc_address(&symbol)
});
Ok(Self { context, fns: Box::new(gl) })
}
/// Attempts to make this context current.
///
/// # Errors
/// Returns `Err` if making this context current fails.
pub fn make_current<SurfaceType: SurfaceTypeTrait>(
&self,
surface: &Surface<SurfaceType>,
) -> Result<CurrentContextWithFns<'_>, Error>
{
if !self.context.is_current() {
self.context
.make_current(surface)
.map_err(Error::MakeContextCurrentFailed)?;
}
Ok(CurrentContextWithFns { ctx: self })
}
#[must_use]
pub fn context(&self) -> &PossiblyCurrentContext
{
&self.context
}
#[must_use]
pub fn context_mut(&mut self) -> &mut PossiblyCurrentContext
{
&mut self.context
}
}
pub struct CurrentContextWithFns<'ctx>
{
ctx: &'ctx ContextWithFns,
}
impl CurrentContextWithFns<'_>
{
#[inline]
pub(crate) fn fns(&self) -> &sys::Gl
{
&self.ctx.fns
}
}
#[derive(Debug, thiserror::Error)]
pub enum Error
{
#[error("Failed to make context current")]
MakeContextCurrentFailed(#[source] glutin::error::Error),
}
mod sys
{
#![allow(
clippy::missing_safety_doc,
clippy::missing_transmute_annotations,
clippy::too_many_arguments,
clippy::unused_unit,
clippy::upper_case_acronyms,
clippy::doc_markdown,
clippy::unreadable_literal,
unsafe_op_in_unsafe_fn
)]
include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
}
|