Skip to content

Instantly share code, notes, and snippets.

@matthewjberger
Created December 28, 2023 22:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save matthewjberger/7ec0f73b80bdd06c088b0f38929c1199 to your computer and use it in GitHub Desktop.
Save matthewjberger/7ec0f73b80bdd06c088b0f38929c1199 to your computer and use it in GitHub Desktop.
Put a pixel on the screen using SDL2's software renderer in Rust
[package]
name = "chitauri"
version = "0.1.0"
edition = "2021"
[dependencies]
sdl2 = { version = "0.36.0", features = ["bundled"] }
use sdl2::{event::Event, keyboard::Keycode, pixels::PixelFormatEnum};
use std::time::Duration;
const WIDTH: usize = 320;
const HEIGHT: usize = 200;
#[derive(Default, Copy, Clone)]
struct Pixel {
r: u8,
g: u8,
b: u8,
}
#[derive(Default, Clone)]
struct Renderer {
width: usize,
height: usize,
front_buffer: Vec<Pixel>,
back_buffer: Vec<Pixel>,
}
impl Renderer {
fn new(width: usize, height: usize) -> Self {
let total_pixels = width * height;
let black_pixel = Pixel { r: 0, g: 0, b: 0 };
Renderer {
width,
height,
front_buffer: vec![black_pixel; total_pixels],
back_buffer: vec![black_pixel; total_pixels],
}
}
fn draw(&mut self) {
// Clear back buffer
for pixel in &mut self.back_buffer {
*pixel = Pixel { r: 0, g: 0, b: 0 };
}
// Draw a red pixel in the middle
let mid_point = (self.width / 2) + (self.height / 2) * self.width;
self.back_buffer[mid_point] = Pixel { r: 255, g: 0, b: 0 };
}
fn swap_buffers(&mut self) {
std::mem::swap(&mut self.front_buffer, &mut self.back_buffer);
}
fn present(&self, canvas: &mut sdl2::render::Canvas<sdl2::video::Window>) {
let texture_creator = canvas.texture_creator();
let mut texture = texture_creator
.create_texture_target(
PixelFormatEnum::RGB24,
self.width as u32,
self.height as u32,
)
.unwrap();
texture
.update(None, &self.front_buffer_as_bytes(), self.width * 3)
.unwrap();
canvas.copy(&texture, None, None).unwrap();
}
fn front_buffer_as_bytes(&self) -> Vec<u8> {
self.front_buffer
.iter()
.flat_map(|p| vec![p.r, p.g, p.b])
.collect()
}
}
pub fn main() {
let sdl_context = sdl2::init().unwrap();
let video_subsystem = sdl_context.video().unwrap();
let window = video_subsystem
.window(
"Rust-SDL2 Demo with Double Buffer",
WIDTH as u32,
HEIGHT as u32,
)
.position_centered()
.build()
.unwrap();
let mut canvas = window.into_canvas().build().unwrap();
let mut event_pump = sdl_context.event_pump().unwrap();
let mut renderer = Renderer::new(WIDTH, HEIGHT);
'running: loop {
renderer.draw();
renderer.swap_buffers();
// Handle events
for event in event_pump.poll_iter() {
match event {
Event::Quit { .. }
| Event::KeyDown {
keycode: Some(Keycode::Escape),
..
} => break 'running,
_ => {}
}
}
renderer.present(&mut canvas);
canvas.present();
::std::thread::sleep(Duration::new(0, 1_000_000_000u32 / 60));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment