Browse Source

lesson 2, more different from the original, but some passing of values back and forth

jmelesky 7 years ago
parent
commit
018c7dc66d
3 changed files with 116 additions and 0 deletions
  1. 7 0
      lesson02/Cargo.toml
  2. BIN
      lesson02/assets/hello_world.bmp
  3. 109 0
      lesson02/src/main.rs

+ 7 - 0
lesson02/Cargo.toml

@@ -0,0 +1,7 @@
+[package]
+name = "lesson02"
+version = "0.1.0"
+authors = ["jmelesky <code@phaedrusdeinus.org>"]
+
+[dependencies]
+sdl2 = "0.30.0"

BIN
lesson02/assets/hello_world.bmp


+ 109 - 0
lesson02/src/main.rs

@@ -0,0 +1,109 @@
+extern crate sdl2;
+
+use sdl2::pixels::Color;
+use sdl2::video::Window;
+use sdl2::render::Canvas;
+use sdl2::surface::Surface;
+
+use std::time::Duration;
+use std::thread::sleep;
+use std::path::Path;
+
+
+
+// using a different window size than lazyfoo, due to high-density screen
+const WIDTH:u32  = 1280;
+const HEIGHT:u32 =  960;
+
+
+// This is all about figuring out what types go where, so that passing
+// arguments and return values works properly. We could probably go with
+// globals, like the C version, but if so, why use rust anyway?
+fn init() -> Canvas<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 01", WIDTH, HEIGHT)
+        .position_centered()
+        .opengl()
+        .build() {
+            Ok(window) => window,
+            Err(err)   => panic!("Could not create window. Error: {}", err),
+        };
+
+    let canvas = match window.into_canvas()
+        .build() {
+            Ok(canvas) => canvas,
+            Err(err)   => panic!("Could not create renderer from window. Error: {}", err),
+        };
+
+    return canvas
+}
+
+
+fn load_media(filename:&str) -> Surface { // -> &'static Texture {
+    // having difficulty with lifetimes. Going to try to use a TextureCreator
+    // to get around that problem for now.
+
+    // screw lifetimes (for now). going to just load and return the
+    // surface, to get around TextureCreator lifetime restrictions
+    let surface = match Surface::load_bmp(&Path::new(filename)) {
+        Ok(surface) => surface,
+        Err(err)    => panic!("Could not load image: {}", err)
+    };
+
+    return surface
+}
+
+fn main() {
+
+    let mut canvas = init();
+
+
+    let surface = load_media("assets/hello_world.bmp");
+
+
+    let tc = canvas.texture_creator();
+
+    let texture = match tc.create_texture_from_surface(&surface) {
+        Ok(texture) => texture,
+        Err(err)    => panic!("Could not slap surface into a texture: {}", err)
+    };
+
+    // These are fairly straightforward draw commands.
+    // The present() is needed to make the changes visible.
+    //
+    // keeping these because, hey, why not?
+    canvas.set_draw_color(Color::RGB(255,255,128));
+    canvas.clear();
+    canvas.present();
+
+
+    // 'copy' takes:
+    // - the texture
+    // - None or Some(Rect) -- the subrect of the texture (or the whole thing)
+    // - None or (not sure) -- if None, stretch to fill the rendering rectangle
+    match canvas.copy(&texture, None, None) {
+        Ok(())   => (), // no return value == success
+        Err(err) => panic!("Could not render texture: {}", err),
+    };
+
+    // and now flip the screen buffers again
+    canvas.present();
+
+
+    sleep(Duration::new(2,0));
+
+    // in the original tutorial, there is also a `close()` function which
+    // frees up the surface and destroys the window
+    // afaict, those are handled by scoping rules in rust, so are
+    // unneeded
+
+}