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
|
use std::ffi::{CStr, CString};
use std::ptr::null_mut;
use crate::init::{initialize, Glfw};
use crate::{get_glfw_error, Error};
pub struct Window
{
_init: Glfw,
handle: *mut crate::ffi::GLFWwindow,
}
impl Window
{
/// Creates a new window.
///
/// # Errors
/// Will return `Err` if
/// - The title contains an internal nul byte
/// - A GLFW error occurs
pub fn create(size: &Size, title: &str) -> Result<Self, Error>
{
let init = initialize()?;
let c_title =
CString::new(title).map_err(|_| Error::InternalNulByteInWindowTitle)?;
// SAFETY: The initialize function makes sure the current thread is the main
// thread
let handle = unsafe {
#[allow(clippy::cast_possible_wrap)]
crate::ffi::glfwCreateWindow(
size.width as i32,
size.height as i32,
c_title.as_ptr(),
null_mut(),
null_mut(),
)
};
get_glfw_error()?;
Ok(Self {
_init: init,
handle,
})
}
/// Makes the context of the window current for the calling thread.
///
/// # Errors
/// Will return `Err` if a GLFW platform error occurs or if no OpenGL context is
/// present.
pub fn make_context_current(&self) -> Result<(), Error>
{
unsafe { crate::ffi::glfwMakeContextCurrent(self.handle) };
get_glfw_error()?;
Ok(())
}
/// Returns the address of the specified OpenGL function, if it is supported by the
/// current context.
///
/// # Errors
/// Will return `Err` if a GLFW platform error occurs or if no current context has
/// been set.
pub fn get_proc_address(
&self,
proc_name: &CStr,
) -> Result<unsafe extern "C" fn(), Error>
{
let proc_addr = unsafe { crate::ffi::glfwGetProcAddress(proc_name.as_ptr()) };
get_glfw_error()?;
// SAFETY: Is only None when a error has occured and that case is handled above
Ok(unsafe { proc_addr.unwrap_unchecked() })
}
/// Processes all pending events.
///
/// # Errors
/// Will return `Err` if a GLFW platform error occurs.
pub fn poll_events(&self) -> Result<(), Error>
{
// SAFETY: The initialize function (called when the window is created) makes sure
// the current thread is the main thread
unsafe { crate::ffi::glfwPollEvents() };
get_glfw_error()?;
Ok(())
}
/// Swaps the front and back buffers of the window.
///
/// # Errors
/// Will return `Err` if a GLFW platform error occurs or if no OpenGL window context
/// is present.
pub fn swap_buffers(&self) -> Result<(), Error>
{
unsafe {
crate::ffi::glfwSwapBuffers(self.handle);
};
get_glfw_error()?;
Ok(())
}
/// Returns whether or not the window should close.
#[must_use]
pub fn should_close(&self) -> bool
{
let should_close = unsafe { crate::ffi::glfwWindowShouldClose(self.handle) };
should_close == crate::ffi::GLFW_TRUE
}
}
/// Window size.
pub struct Size
{
pub width: u32,
pub height: u32,
}
|