rust_pathtracer/
buffer.rs1use crate::prelude::*;
2use rayon::{slice::ParallelSliceMut, iter::{IndexedParallelIterator, ParallelIterator}};
3
4#[derive(PartialEq, Debug, Clone)]
6pub struct ColorBuffer {
7
8 pub width : usize,
9 pub height : usize,
10
11 pub pixels : Vec<F>,
12
13 pub frames : usize,
14}
15
16impl ColorBuffer {
17
18 pub fn new(width: usize, height: usize) -> Self {
19 Self {
20 width,
21 height,
22
23 pixels : vec![0.0; width * height * 4],
24 frames : 0,
25 }
26 }
27
28 #[inline(always)]
29 pub fn at(&self, x: usize, y: usize) -> [F;4] {
30 let i = y * self.width * 4 + x * 4;
31 [self.pixels[i], self.pixels[i + 1], self.pixels[i + 2], self.pixels[i + 3]]
32 }
33
34 pub fn to_u8_vec(&self) -> Vec<u8> {
38
39 let source = &self.pixels[..];
40 let mut out : Vec<u8> = vec![0; self.width * self.height * 4];
41
42 for y in 0..self.height {
43 for x in 0..self.width {
44 let d = x * 4 + y * self.width * 4;
45 let c = [(source[d].powf(0.4545) * 255.0) as u8, (source[d+1].powf(0.4545) * 255.0) as u8, (source[d+2].powf(0.4545) * 255.0) as u8, (source[d+3] * 255.0) as u8];
47 out[d..d + 4].copy_from_slice(&c);
48 }
49 }
50
51 out
52 }
53
54 pub fn convert_to_u8(&self, frame: &mut [u8]) {
56 for y in 0..self.height {
57 for x in 0..self.width {
58 let o = x * 4 + y * self.width * 4;
59 let c = [(self.pixels[o].powf(0.4545) * 255.0) as u8, (self.pixels[o+1].powf(0.4545) * 255.0) as u8, (self.pixels[o+2].powf(0.4545) * 255.0) as u8, (self.pixels[o+3] * 255.0) as u8];
60 frame[o..o + 4].copy_from_slice(&c);
62 }
63 }
64 }
65
66 pub fn convert_to_u8_at(&self, frame: &mut [u8], at: (usize, usize, usize, usize)) {
68
69 let width = at.2;
70 let height = at.3;
71
72 frame
73 .par_rchunks_exact_mut(width * 4)
74 .enumerate()
75 .for_each(|(j, line)| {
76 for (i, pixel) in line.chunks_exact_mut(4).enumerate() {
77 let i = j * width + i;
78
79 let x = i % width;
80 let y = height - (i / width);
81
82 if x > at.0 && x < at.0 + self.width {
83 if y > at.1 && y < at.1 + self.height {
84 let o = (x - at.0) * 4 + (y - at.1) * self.width * 4;
85 let c = [(self.pixels[o] * 255.0) as u8, (self.pixels[o+1] * 255.0) as u8, (self.pixels[o+2] * 255.0) as u8, (self.pixels[o+3] * 255.0) as u8];
86 pixel.copy_from_slice(&c);
87 }
88 }
89 }
90 });
91
92
93 }
103}