Przeglądaj źródła

image rendering

master
Isabelle L. 5 lat temu
rodzic
commit
ac320b0513
7 zmienionych plików z 81 dodań i 9 usunięć
  1. +1
    -0
      .gitignore
  2. +1
    -0
      Cargo.toml
  3. BIN
      img.png
  4. +11
    -1
      src/color.rs
  5. +34
    -0
      src/img.rs
  6. +31
    -8
      src/lib.rs
  7. +3
    -0
      src/prelude.rs

+ 1
- 0
.gitignore Wyświetl plik

@@ -1,2 +1,3 @@
/target
Cargo.lock
/src/main.rs

+ 1
- 0
Cargo.toml Wyświetl plik

@@ -8,3 +8,4 @@ edition = "2018"
[dependencies]
minifb = {git = "https://github.com/emoon/rust_minifb" }
thiserror = "1.0.19"
image = "0.23.5"

BIN
img.png Wyświetl plik

Przed Po
Szerokość: 5  |  Wysokość: 5  |  Rozmiar: 105 B

+ 11
- 1
src/color.rs Wyświetl plik

@@ -1,4 +1,4 @@
// a 32 bit rgb
/// an 8 bit rgb with built in conversion to u32
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Color {
pub r: u8,
@@ -7,10 +7,20 @@ pub struct Color {
}

impl Color {
/// create a new color
pub fn new(r: u8, g: u8, b: u8) -> Color {
Color { r, g, b }
}

/// return a color from a given u32
pub fn from_u32(color: u32) -> Color {
let b = (color & 0xff) as u8;
let g = ((color >> 8) & 0xff) as u8;
let r = ((color >> 16) & 0xff) as u8;
Color { r, g, b }
}

/// return color as a u32 structured 0bxxxx_rrrr_gggg_bbbb
pub fn as_u32(&self) -> u32 {
let (r, g, b) = (self.r as u32, self.g as u32, self.b as u32);
(r << 16) | (g << 8) | b


+ 34
- 0
src/img.rs Wyświetl plik

@@ -0,0 +1,34 @@
use crate::{Color, Result};
use std::path::PathBuf;

/// an image
pub struct Image {
width: usize,
height: usize,
data: Vec<Color>,
}

impl Image {
/// load an image from a file
pub fn load(path: PathBuf) -> Result<Image> {
let (width, height) = image::image_dimensions(&path)?;
let (width, height) = (width as usize, height as usize);
let data: Vec<Color> = image::open(path)?
.into_rgb()
.pixels()
.map(|pixel| Color::new(pixel[0], pixel[1], pixel[2]))
.collect();

Ok(Image { width, height, data })
}
}

impl crate::Renderable for Image {
fn dimensions(&self) -> (usize, usize) {
(self.width, self.height)
}

fn data(&self) -> &Vec<Color> {
&self.data
}
}

+ 31
- 8
src/lib.rs Wyświetl plik

@@ -1,24 +1,36 @@
#![allow(dead_code)]

// modules
pub mod color;
mod color;
mod img;
pub mod prelude;

// namespacing
use color::Color;
pub use color::Color;
pub use img::Image;
pub use minifb::{Key, MouseButton};
use minifb::{Window, WindowOptions};

// error type
/// error type
#[derive(Debug, thiserror::Error)]
pub enum Error {
#[error(transparent)]
MiniFb(#[from] minifb::Error),
#[error(transparent)]
Image(#[from] image::ImageError),
}

// result type
/// result type
pub type Result<T> = std::result::Result<T, Error>;

/// renderable trait
pub trait Renderable {
/// return the dimensions of the structure
fn dimensions(&self) -> (usize, usize);
/// return a slice of row major data to be rendered
fn data(&self) -> &Vec<Color>;
}

// pixel buffer for internal use
struct PixelBuffer {
data: Vec<u32>,
@@ -102,15 +114,26 @@ impl Context {
/// !! this method can panic if the given buffer dimensions don't match the buffer length
pub fn insert_slice(&mut self, x: usize, y: usize, w: usize, h: usize, slice: &[Color]) {
assert!(w * h == slice.len());
let (ox, oy) = (x, y);

for i in x..(x + w) {
for j in y..(y + h) {
let color = slice[w * (i - x) + (j - y)];
self.insert_pixel(i, j, color);
for x in 0..w {
for y in 0..h {
self.insert_pixel(x + ox, y + oy, slice[y * w + x])
}
}
}

/// render a structure that impl's the renderable trait
pub fn render<T>(&mut self, x: usize, y: usize, renderable: &T)
where
T: Renderable,
{
let (w, h) = renderable.dimensions();
let slice = renderable.data();

self.insert_slice(x, y, w, h, &slice);
}

/// get mouse position
pub fn get_mouse_pos(&self) -> Option<(f32, f32)> {
self.window.get_mouse_pos(minifb::MouseMode::Discard)


+ 3
- 0
src/prelude.rs Wyświetl plik

@@ -1,3 +1,6 @@
//! namespacing for lazy people
pub use crate::color::Color;
pub use crate::img::Image;
pub use crate::Context;
pub use crate::Result;
pub use minifb::{Key, MouseButton};

Ładowanie…
Anuluj
Zapisz