Opening a window using SDL2 in Rust
Introduction
Simple DirectMedia Layer(SDL) is a library written in C which provides low-level access to audio, keyboard, mouse, joystick, and graphics hardware. We will use the rust-sdl2 library, which has SDL2 Rust bindings for C. In this tutorial, we will see how to open a window using SDL2 in Rust.
Setup
Install sdl2 on your system.
You can follow the installation steps mentioned in the rust-sdl2 documentation.
If you use Windows or macOS, ensure the LIBRARY_PATH
environment variable is set.
Now create a new cargo project sdl2_tutorial
using the following command.
cargo new sdl2_tutorial
cd sdl2_tutorial
Add the sdl2 dependency to Cargo.toml
file.
sdl2 = "0.35.2"
Sdl Initialization
The first step to using SDL functionalities is to initialize the SDL Library.
So let's start by initializing the SDL library using init()
function in main.rs
.
The sdl init
function must be called before using any other SDL function.
pub fn main() -> Result<(), String> {
let sdl_context = sdl2::init()?;
}
Sdl can be initialized only once at a time.
The init
function calls SDL_Init and throws an error if Sdl
has already been initialized.
You can initialize another Sdl only after the first instance of Sdl is dropped.
Video Subsystem
To open a window, we need a connection to Window Manager of our system, which is provided by the SDL Video Subsystem.
Let's initialize the video subsystem by calling video()
function on sdl_context
which we just created.
let video_subsystem = sdl_context.video()?;
The video
function calls SDL_VideoInit and throws an error on failure.
Opening Window
Now that we have a connection to the window manager through video_subsystem, let's define a window.
let window = video_subsystem
.window("first window", 640, 480)
.position_centered()
.build()
.map_err(|e| format!("{e}"))?;
The window()
function takes the window's title, width and height as params.
position_centered()
positions our window at the center of the screen.
SDL provides options to make the window resizable, fullscreen, borderless, etc. You can play around with the options mentioned in docs.
build()
function calls SDL_CreateWindow and throws WindowBuildError
error type on failure.
Since we defined our main function to return errors as String, we mapped WindowBuildError
error type to String.
Event Pump
When we perform any action on our application like mouse movement, mouse clicks, pressing keyboard keys, etc.
our Operating System generates events for all our actions.
SDL Event Pump gathers and places all these events in the event queue.
We poll for these events and define what action should be performed for each event.
Now that we know we have to handle all input events, let's handle closing of our window.
On clicking the close button, Quit
event will be generated.
We will start the Event Pump, poll for events and handle Quit
event.
'app: loop {
for event in sdl_context.event_pump()?.poll_iter() {
if let Event::Quit { .. } = event { break 'app; }
}
}
event_pump()
initializes Event Pump and places all events in the event queue.
poll_iter()
returns a polling iterator that calls poll_event()
which polls for pending events in the event queue.
The iterator will terminate once there are no more pending events.
To keep the window open, we used an infinite loop.
Since we are using nested loops, we annotated our outer loop with 'app
so that we can easily break from the outer loop by passing the loop annotation to break
.
The poll iterator keeps polling for events and when we receive Quit
event, we break from the loop.
Once the Window
instance goes out of scope, our window will be destroyed and closed.
Run Application
Here is the complete code for opening a window using SDL2 in Rust.
use sdl2::event::Event;
pub fn main() -> Result<(), String> {
let sdl_context = sdl2::init()?;
let video_subsystem = sdl_context.video()?;
let window = video_subsystem
.window("first window", 640, 480)
.position_centered()
.build()
.map_err(|e| format!("{e}"))?;
'app: loop {
for event in sdl_context.event_pump()?.poll_iter() {
if let Event::Quit { .. } = event { break 'app; }
}
}
Ok(())
}
Build and run the project.
cargo run
You will see a blank window with first window
as title.
Stay tuned for more posts on SDL2 in Rust. Happy coding! 😀