123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164 |
- extern crate sdl2;
- use sdl2::Sdl;
- use sdl2::video::{Window, WindowContext};
- use sdl2::render::{TextureCreator, Texture};
- use sdl2::surface::Surface;
- use sdl2::rect::Rect;
- use sdl2::event::Event;
- use sdl2::keyboard::Keycode;
- use std::path::Path;
- // using a different window size than lazyfoo, due to high-density screen
- const WIDTH:u32 = 1280;
- const HEIGHT:u32 = 960;
- // need the window (blit settings) as well as the canvas
- // and still the context for the event pump
- //
- // splitting canvas out for now due to compilation reasons
- fn init() -> (Sdl, Window) {
- let context = match sdl2::init() {
- Ok(context) => context,
- Err(err) => panic!("Could not initialize SDL2. Error: {}", err),
- };
- let video = match context.video() {
- Ok(video) => video,
- Err(err) => panic!("Could not gain access to the SDL2 video subsystem. Error: {}", err),
- };
- let window = match video.window("SDL Tutorial, lesson 05", WIDTH, HEIGHT)
- .position_centered()
- .opengl()
- .build() {
- Ok(window) => window,
- Err(err) => panic!("Could not create window. Error: {}", err),
- };
- return (context, window)
- }
- // we need to manipulate the surface post-load, so separating these functions out
- fn load_surface(path: &str) -> Surface {
- let surface = match Surface::load_bmp(&Path::new(path)) {
- Ok(surface) => surface,
- Err(err) => panic!("Could not load image: {}", err)
- };
- return surface;
- }
- fn surface_to_texture<'a>(surface: &Surface, tc: &'a TextureCreator<WindowContext>) -> Texture<'a> {
- let texture = match tc.create_texture_from_surface(&surface) {
- Ok(texture) => texture,
- Err(err) => panic!("Could not slap surface into a texture: {}", err)
- };
- return texture;
- }
- // And this becomes much simpler
- // although it's unused in this lesson
- fn load_texture<'a>(path: &'static str, tc: &'a TextureCreator<WindowContext>) -> Texture<'a> {
- return surface_to_texture(&load_surface(path), &tc);
- }
- fn main() {
- let mut running: bool = true;
- let (context, window) = init();
- let starting_surface = load_surface("../assets/stretch.bmp");
- // okay, now to modify the surface
- // this, afaict, has no perceivable benefit for this example
- // but should optimize things for future tight loops, etc
- //
- //
- // ... though we do create three separate surfaces in this process
- let pixel_format = window.window_pixel_format();
- let sf_pixel_format = starting_surface.pixel_format();
- let optimized_surface = match starting_surface
- .convert(&sf_pixel_format) {
- Ok(surface) => surface,
- Err(err) => panic!("Could not convert surface: {}", err)
- };
- // Now stretch the optimized surface to the dimensions we want
- let dst_rect = Rect::new(0, 0, WIDTH, HEIGHT);
- let mut stretched_surface = match Surface::new(WIDTH, HEIGHT, pixel_format) {
- Ok(surface) => surface,
- Err(err) => panic!("Could not create surface: {}", err)
- };
- // blit_scaled does not return anything, but it does return an SdlResult, so
- // we unwrap to trigger the panic if we can't blit.
- optimized_surface.blit_scaled(None, &mut stretched_surface, Some(dst_rect)).unwrap();
- // couldn't figure out how to wrap the canvas creation in a function,
- // since it involves borrowing `window`. Short enough to handle from
- // here, but still frustrating.
- let mut canvas = match window.into_canvas()
- .build() {
- Ok(canvas) => canvas,
- Err(err) => panic!("Could not create canvas from window. Error: {}", err),
- };
- let tc = canvas.texture_creator();
- let texture = surface_to_texture(&stretched_surface, &tc);
- let mut pump = match context.event_pump() {
- Ok(pump) => pump,
- Err(err) => panic!("Could not start pumping: {}", err)
- };
- while running {
- // pull all pending events
- for event in pump.poll_iter() {
- match event {
- // apparently '{..}' means "with whatever fields"
- Event::Quit {..} => {
- running = false
- },
- Event::KeyDown { keycode: k, .. } => match k {
- Some(Keycode::Escape) | Some(Keycode::Q) => {
- running = false
- },
- Some(_) => {},
- None => {}
- },
- _ => {}
- }
- }
- //canvas.clear();
- match canvas.copy(&texture, None, None) {
- Ok(()) => (), // no return value == success
- Err(err) => panic!("Could not render texture: {}", err),
- };
- canvas.present();
- }
- }
|