Skip to content

Commit

Permalink
Add simple example and fix overflow bug
Browse files Browse the repository at this point in the history
  • Loading branch information
happenslol committed Dec 4, 2018
1 parent cae33a4 commit 0e71da1
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 1 deletion.
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
[workspace]
members = ["sheep", "sheep_cli"]
members = ["sheep", "sheep_cli"]
8 changes: 8 additions & 0 deletions sheep/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,11 @@ amethyst = ["serde", "serde_derive"]
[dependencies]
serde = { version = "1", optional = true }
serde_derive = { version = "1", optional = true }

[dev-dependencies]
image = "0.20"
ron = "0.4"

[[example]]
name = "simple_pack"
path = "examples/simple_pack/main.rs"
53 changes: 53 additions & 0 deletions sheep/examples/simple_pack/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
extern crate image;
extern crate sheep;

use sheep::{AmethystFormat, InputSprite, SimplePacker};
use std::{fs::File, io::prelude::*};

fn main() {
// First, we get the raw, uncompressed pixel data of the image. These
// can come from any sources and even be generated in code, but for
// simplicity's sake we're using the image crate here.
let img =
image::open("sheep/examples/simple_pack/resources/logo.png").expect("Failed to open image");
let img = img.as_rgba8().expect("Failed to convert image to rgba8");

let dimensions = img.dimensions();
let bytes = img
.pixels()
.flat_map(|it| it.data.iter().map(|it| *it))
.collect::<Vec<u8>>();

// We'll just repeat the same sprite 16 times and pack it into a texture.
let sprites = (0..16)
.map(|_| InputSprite {
dimensions,
bytes: bytes.clone(),
}).collect::<Vec<InputSprite>>();

// Do the actual packing! 4 defines the stride, since we're using rgba8 we
// have 4 bytes per pixel.
let sprite_sheet = sheep::pack::<SimplePacker>(sprites, 4);

// Now, we can encode the sprite sheet in a format of our choosing to
// save things such as offsets, positions of the sprites and so on.
let meta = sheep::encode::<AmethystFormat>(&sprite_sheet);

// Next, we save the output to a file using the image crate again.
let outbuf = image::RgbaImage::from_vec(
sprite_sheet.dimensions.0,
sprite_sheet.dimensions.1,
sprite_sheet.bytes,
).expect("Failed to construct image from sprite sheet bytes");

outbuf.save("out.png").expect("Failed to save image");

// Lastly, we serialize the meta info using serde. This can be any format
// you want, just implement the trait and pass it to encode.
let mut meta_file = File::create("out.ron").expect("Failed to create meta file");
let meta_str = ron::ser::to_string(&meta).expect("Failed to encode meta file");

meta_file
.write_all(meta_str.as_bytes())
.expect("Failed to write meta file");
}
Binary file added sheep/examples/simple_pack/resources/logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions sheep/src/pack/simple.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,12 @@ fn compare_area(a: &SpriteData, b: &SpriteData) -> Ordering {
}

fn compare_pos(a: &(u32, u32), b: &(u32, u32)) -> Ordering {
// NOTE(happenslol): We might overflow here quickly if the output
// sprite becomes too big, so we use u64s. This is why this algorithm
// doesn't scale very well...
let a = (a.0 as u64, a.1 as u64);
let b = (b.0 as u64, b.1 as u64);

(a.0.pow(4) + a.1.pow(4)).cmp(&(b.0.pow(4) + b.1.pow(4)))
}

Expand Down

0 comments on commit 0e71da1

Please sign in to comment.