Created
August 30, 2025 16:56
-
-
Save madwareru/5e2043cd2082891b687de2e00b0914c1 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| use glfw::{Action, ClientApiHint, Glfw, Key, Monitor, WindowHint}; | |
| fn main() { | |
| /* | |
| I. Initialization | |
| Tries to initialize GLFW. If it fails to do so, let the user know and end the program, | |
| since there is no point in going further. | |
| glfw::fail_on_errors means there will be the panic in the case of initialization failure, | |
| so the unwrap call here is just symbolical. | |
| */ | |
| let mut glfw: Glfw = glfw::init(glfw::fail_on_errors).unwrap(); | |
| /* | |
| II. Acquiring the size of the window | |
| This piece of code grabs the main monitor, | |
| so that we can derive a window width and height from it, | |
| and it will look similar no matter what resolution you use. | |
| Both acquisition of the main monitor and video mode may result in None, | |
| in this case we will use default size of 800x600. | |
| */ | |
| let mut video_mode = None; | |
| glfw.with_primary_monitor(|_, monitor: Option<&mut Monitor>| { | |
| if let Some(mode) = monitor.and_then(|it| it.get_video_mode()) { | |
| video_mode = Some(mode); | |
| } | |
| }); | |
| let (window_width, window_height) = video_mode | |
| .map(|mode| ((mode.width * 9) / 10, (mode.height * 9) / 10)) | |
| .unwrap_or((800, 600)); | |
| /* | |
| III. Hints | |
| [|ScaleToMonitor|] will tell GLFW to not scale the window in any way, | |
| should you have set up a specific scaling other than 100% on your desktop. | |
| That will keep the window size at what we set it, and lets us forget about | |
| fractional window and pixel scaling. | |
| GLFW was initially meant to support development of OpenGL based applications, | |
| hence the gl in its name, but over the years it also started to support other | |
| APIs and not just OpenGL. Now since GLFW by default creates a context for OpenGL, | |
| and as we want to use DirectX, we need to tell GLFW to not do so via [|ClientApi|] hint | |
| with [|NoApi|] variant. | |
| There are many other options one can define through window_hint call. | |
| Many of these options might be useful in your application, depending on what you want | |
| and how you want to design your window. | |
| */ | |
| glfw.window_hint(WindowHint::ScaleToMonitor(false)); | |
| glfw.window_hint(WindowHint::ClientApi(ClientApiHint::NoApi)); | |
| /* | |
| IV. Window creation | |
| This piece actually creates the window, if everything goes well. | |
| Window creation may return None, hence we check it and panic if so. | |
| The call returns pair of window and GlfwReceiver, which we will use to poll events. | |
| The call for set_key_polling tells window to listen for the keys | |
| and resend it to GlfwReceiver. Alternatively we could use the manual | |
| callback setting through set_key_callback/unset_key_callback. | |
| */ | |
| let (title, window_mode) = ("LearnD3D11 - Hello Window", glfw::WindowMode::Windowed); | |
| let (mut window, events) = glfw | |
| .create_window(window_width, window_height, title, window_mode) | |
| .expect("Failed to create GLFW window."); | |
| window.set_key_polling(true); | |
| /* | |
| V. Positioning of the window | |
| If the video_mode was acquired successfully, we could accurately | |
| place the window at the center of the screen. | |
| */ | |
| if let Some(mode) = video_mode { | |
| let (window_left, window_top) = ( | |
| (mode.width - window_width) / 2, | |
| (mode.height - window_height) / 2 | |
| ); | |
| window.set_pos(window_left as _, window_top as _); | |
| } | |
| /* | |
| VI. Main window loop | |
| That is more or less the heart of your application, the main loop. | |
| You could also call it game loop, since in here everything happens. | |
| From reading keyboard and mouse input, reacting to it, to telling the | |
| graphics card to put a frog on the screen. It will keep doing it, until | |
| it gets signaled to not do that anymore because you closed the window, | |
| for example (window.should_close() part), or hit Escape and mapped Escape | |
| to close the window. The call to glfw.poll_events() will make sure that | |
| GLFW knows about all required events coming from the operating system. | |
| The loop which follows the call are looking for the Escape key event and | |
| triggers the window close mentioned earlier | |
| */ | |
| while !window.should_close() { | |
| glfw.poll_events(); | |
| for (_, event) in glfw::flush_messages(&events) { | |
| if let glfw::WindowEvent::Key(Key::Escape, _, Action::Press, _) = event { | |
| window.set_should_close(true) | |
| } | |
| } | |
| // future update code | |
| // future render code | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment