main.rs 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. extern crate sdl2;
  2. use sdl2::Sdl;
  3. use sdl2::video::{Window, WindowContext};
  4. use sdl2::render::{TextureCreator, Texture};
  5. use sdl2::surface::Surface;
  6. use sdl2::rect::Rect;
  7. use sdl2::event::Event;
  8. use sdl2::keyboard::Keycode;
  9. use std::path::Path;
  10. // using a different window size than lazyfoo, due to high-density screen
  11. const WIDTH:u32 = 1280;
  12. const HEIGHT:u32 = 960;
  13. // need the window (blit settings) as well as the canvas
  14. // and still the context for the event pump
  15. //
  16. // splitting canvas out for now due to compilation reasons
  17. fn init() -> (Sdl, Window) {
  18. let context = match sdl2::init() {
  19. Ok(context) => context,
  20. Err(err) => panic!("Could not initialize SDL2. Error: {}", err),
  21. };
  22. let video = match context.video() {
  23. Ok(video) => video,
  24. Err(err) => panic!("Could not gain access to the SDL2 video subsystem. Error: {}", err),
  25. };
  26. let window = match video.window("SDL Tutorial, lesson 05", WIDTH, HEIGHT)
  27. .position_centered()
  28. .opengl()
  29. .build() {
  30. Ok(window) => window,
  31. Err(err) => panic!("Could not create window. Error: {}", err),
  32. };
  33. return (context, window)
  34. }
  35. // we need to manipulate the surface post-load, so separating these functions out
  36. fn load_surface(path: &str) -> Surface {
  37. let surface = match Surface::load_bmp(&Path::new(path)) {
  38. Ok(surface) => surface,
  39. Err(err) => panic!("Could not load image: {}", err)
  40. };
  41. return surface;
  42. }
  43. fn surface_to_texture<'a>(surface: &Surface, tc: &'a TextureCreator<WindowContext>) -> Texture<'a> {
  44. let texture = match tc.create_texture_from_surface(&surface) {
  45. Ok(texture) => texture,
  46. Err(err) => panic!("Could not slap surface into a texture: {}", err)
  47. };
  48. return texture;
  49. }
  50. // And this becomes much simpler
  51. // although it's unused in this lesson
  52. fn load_texture<'a>(path: &'static str, tc: &'a TextureCreator<WindowContext>) -> Texture<'a> {
  53. return surface_to_texture(&load_surface(path), &tc);
  54. }
  55. fn main() {
  56. let mut running: bool = true;
  57. let (context, window) = init();
  58. let starting_surface = load_surface("../assets/stretch.bmp");
  59. // okay, now to modify the surface
  60. // this, afaict, has no perceivable benefit for this example
  61. // but should optimize things for future tight loops, etc
  62. //
  63. //
  64. // ... though we do create three separate surfaces in this process
  65. let pixel_format = window.window_pixel_format();
  66. let sf_pixel_format = starting_surface.pixel_format();
  67. let optimized_surface = match starting_surface
  68. .convert(&sf_pixel_format) {
  69. Ok(surface) => surface,
  70. Err(err) => panic!("Could not convert surface: {}", err)
  71. };
  72. // Now stretch the optimized surface to the dimensions we want
  73. let dst_rect = Rect::new(0, 0, WIDTH, HEIGHT);
  74. let mut stretched_surface = match Surface::new(WIDTH, HEIGHT, pixel_format) {
  75. Ok(surface) => surface,
  76. Err(err) => panic!("Could not create surface: {}", err)
  77. };
  78. // blit_scaled does not return anything, but it does return an SdlResult, so
  79. // we unwrap to trigger the panic if we can't blit.
  80. optimized_surface.blit_scaled(None, &mut stretched_surface, Some(dst_rect)).unwrap();
  81. // couldn't figure out how to wrap the canvas creation in a function,
  82. // since it involves borrowing `window`. Short enough to handle from
  83. // here, but still frustrating.
  84. let mut canvas = match window.into_canvas()
  85. .build() {
  86. Ok(canvas) => canvas,
  87. Err(err) => panic!("Could not create canvas from window. Error: {}", err),
  88. };
  89. let tc = canvas.texture_creator();
  90. let texture = surface_to_texture(&stretched_surface, &tc);
  91. let mut pump = match context.event_pump() {
  92. Ok(pump) => pump,
  93. Err(err) => panic!("Could not start pumping: {}", err)
  94. };
  95. while running {
  96. // pull all pending events
  97. for event in pump.poll_iter() {
  98. match event {
  99. // apparently '{..}' means "with whatever fields"
  100. Event::Quit {..} => {
  101. running = false
  102. },
  103. Event::KeyDown { keycode: k, .. } => match k {
  104. Some(Keycode::Escape) | Some(Keycode::Q) => {
  105. running = false
  106. },
  107. Some(_) => {},
  108. None => {}
  109. },
  110. _ => {}
  111. }
  112. }
  113. //canvas.clear();
  114. match canvas.copy(&texture, None, None) {
  115. Ok(()) => (), // no return value == success
  116. Err(err) => panic!("Could not render texture: {}", err),
  117. };
  118. canvas.present();
  119. }
  120. }