Attempting to render image in chunks
This commit is contained in:
parent
edb0b64282
commit
fbf41fae22
|
@ -7,4 +7,3 @@ edition = "2018"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
sdl2 = "0.33.0"
|
sdl2 = "0.33.0"
|
||||||
rand = "0.7.3"
|
rand = "0.7.3"
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,8 @@ pub struct LinearGradientRectangle;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
types::{Ray, Vec3},
|
types::{Ray, Vec3},
|
||||||
Demo,
|
HORIZONTAL_PARTITION, VERTICAL_PARTITION,
|
||||||
|
{demos::Chunk, Demo},
|
||||||
};
|
};
|
||||||
|
|
||||||
impl Demo for LinearGradientRectangle {
|
impl Demo for LinearGradientRectangle {
|
||||||
|
@ -11,8 +12,35 @@ impl Demo for LinearGradientRectangle {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render(&self, buf: &mut [u8], width: usize, height: usize, _samples: u8) {
|
fn render(&self, buf: &mut [u8], width: usize, height: usize, _samples: u8) {
|
||||||
let mut offset = 0;
|
let nx = width / VERTICAL_PARTITION;
|
||||||
|
let ny = height / HORIZONTAL_PARTITION;
|
||||||
|
|
||||||
|
for j in 0..VERTICAL_PARTITION {
|
||||||
|
for i in 0..HORIZONTAL_PARTITION {
|
||||||
|
let start_y = j * ny;
|
||||||
|
let start_x = i * nx;
|
||||||
|
let chunk = Chunk {
|
||||||
|
x: width,
|
||||||
|
y: height,
|
||||||
|
nx,
|
||||||
|
ny,
|
||||||
|
start_x,
|
||||||
|
start_y,
|
||||||
|
};
|
||||||
|
|
||||||
|
self.render_chunk(buf, chunk);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn render_chunk(&self, buf: &mut [u8], meta: Chunk) {
|
||||||
|
let Chunk {
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
nx,
|
||||||
|
ny,
|
||||||
|
start_x,
|
||||||
|
start_y,
|
||||||
|
} = meta;
|
||||||
// -2.0 and 4.0 in lower_left_corner and horizontal respectively
|
// -2.0 and 4.0 in lower_left_corner and horizontal respectively
|
||||||
// because our canvas is in 2:1 ratio
|
// because our canvas is in 2:1 ratio
|
||||||
let lower_left_corner = Vec3::new(-2.0, -1.0, -1.0);
|
let lower_left_corner = Vec3::new(-2.0, -1.0, -1.0);
|
||||||
|
@ -20,18 +48,18 @@ impl Demo for LinearGradientRectangle {
|
||||||
let vertical = Vec3::new(0.0, 2.0, 0.0);
|
let vertical = Vec3::new(0.0, 2.0, 0.0);
|
||||||
let origin = Vec3::new(0.0, 0.0, 0.0);
|
let origin = Vec3::new(0.0, 0.0, 0.0);
|
||||||
|
|
||||||
for j in (0..height).rev() {
|
for j in start_y..start_y + ny {
|
||||||
for i in 0..width {
|
for i in start_x..start_x + nx {
|
||||||
let u = i as f64 / width as f64;
|
let u = i as f64 / x as f64;
|
||||||
let v = j as f64 / height as f64;
|
let v = j as f64 / y as f64;
|
||||||
let ray = Ray::new(origin, lower_left_corner + horizontal * u + vertical * v);
|
let ray = Ray::new(origin, lower_left_corner + horizontal * u + vertical * v);
|
||||||
|
|
||||||
let c = color(ray);
|
let c = color(ray);
|
||||||
|
|
||||||
|
let offset = (j * x + i) * 4;
|
||||||
buf[offset] = (255.99 * c.r()) as u8;
|
buf[offset] = (255.99 * c.r()) as u8;
|
||||||
buf[offset + 1] = (255.99 * c.g()) as u8;
|
buf[offset + 1] = (255.99 * c.g()) as u8;
|
||||||
buf[offset + 2] = (255.99 * c.b()) as u8;
|
buf[offset + 2] = (255.99 * c.b()) as u8;
|
||||||
offset += 4;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,25 +1,38 @@
|
||||||
mod diffuse_materials;
|
//mod diffuse_materials;
|
||||||
mod hitable_sphere;
|
//mod hitable_sphere;
|
||||||
mod linear_gradient_rectangle;
|
mod linear_gradient_rectangle;
|
||||||
mod materials;
|
//mod materials;
|
||||||
mod simple_antialiasing;
|
//mod simple_antialiasing;
|
||||||
mod simple_rectangle;
|
mod simple_rectangle;
|
||||||
mod simple_sphere;
|
//mod simple_sphere;
|
||||||
mod surface_normal_sphere;
|
//mod surface_normal_sphere;
|
||||||
|
|
||||||
pub use diffuse_materials::DiffuseMaterials;
|
//pub use diffuse_materials::DiffuseMaterials;
|
||||||
pub use hitable_sphere::HitableSphere;
|
//pub use hitable_sphere::HitableSphere;
|
||||||
pub use linear_gradient_rectangle::LinearGradientRectangle;
|
pub use linear_gradient_rectangle::LinearGradientRectangle;
|
||||||
pub use materials::Materials;
|
//pub use materials::Materials;
|
||||||
pub use simple_antialiasing::SimpleAntialiasing;
|
//pub use simple_antialiasing::SimpleAntialiasing;
|
||||||
pub use simple_rectangle::SimpleRectangle;
|
pub use simple_rectangle::SimpleRectangle;
|
||||||
pub use simple_sphere::SimpleSphere;
|
//pub use simple_sphere::SimpleSphere;
|
||||||
pub use surface_normal_sphere::SurfaceNormalSphere;
|
//pub use surface_normal_sphere::SurfaceNormalSphere;
|
||||||
|
|
||||||
use std::{fs::File, io::Write};
|
use std::{fs::File, io::Write};
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Chunk {
|
||||||
|
x: usize,
|
||||||
|
y: usize,
|
||||||
|
nx: usize,
|
||||||
|
ny: usize,
|
||||||
|
start_x: usize,
|
||||||
|
start_y: usize,
|
||||||
|
}
|
||||||
|
|
||||||
pub trait Demo {
|
pub trait Demo {
|
||||||
fn render(&self, buf: &mut [u8], width: usize, height: usize, samples: u8);
|
fn render(&self, buf: &mut [u8], width: usize, height: usize, samples: u8);
|
||||||
|
|
||||||
|
fn render_chunk(&self, buf: &mut [u8], meta: Chunk);
|
||||||
|
|
||||||
fn name(&self) -> &'static str;
|
fn name(&self) -> &'static str;
|
||||||
|
|
||||||
fn save_as_ppm(&self, buf: &[u8], width: usize, height: usize) {
|
fn save_as_ppm(&self, buf: &[u8], width: usize, height: usize) {
|
||||||
|
|
|
@ -1,4 +1,8 @@
|
||||||
use crate::{demos::Demo, types::Vec3};
|
use crate::{
|
||||||
|
demos::{Chunk, Demo},
|
||||||
|
types::Vec3,
|
||||||
|
HORIZONTAL_PARTITION, VERTICAL_PARTITION,
|
||||||
|
};
|
||||||
|
|
||||||
pub struct SimpleRectangle;
|
pub struct SimpleRectangle;
|
||||||
|
|
||||||
|
@ -8,16 +12,45 @@ impl Demo for SimpleRectangle {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render(&self, buf: &mut [u8], width: usize, height: usize, _samples: u8) {
|
fn render(&self, buf: &mut [u8], width: usize, height: usize, _samples: u8) {
|
||||||
let mut offset = 0;
|
let nx = width / VERTICAL_PARTITION;
|
||||||
for j in (0..height).rev() {
|
let ny = height / HORIZONTAL_PARTITION;
|
||||||
for i in 0..width {
|
|
||||||
let color = Vec3::new(i as f64 / width as f64, j as f64 / width as f64, 0.2);
|
|
||||||
|
|
||||||
buf[offset] = (255.99 * color.r()) as u8;
|
for j in 0..VERTICAL_PARTITION {
|
||||||
buf[offset + 1] = (255.99 * color.g()) as u8;
|
for i in 0..HORIZONTAL_PARTITION {
|
||||||
buf[offset + 2] = (255.99 * color.b()) as u8;
|
let start_y = j * ny;
|
||||||
|
let start_x = i * nx;
|
||||||
|
let chunk = Chunk {
|
||||||
|
x: width,
|
||||||
|
y: height,
|
||||||
|
nx,
|
||||||
|
ny,
|
||||||
|
start_x,
|
||||||
|
start_y,
|
||||||
|
};
|
||||||
|
|
||||||
offset += 4;
|
self.render_chunk(buf, chunk);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render_chunk(&self, buf: &mut [u8], meta: Chunk) {
|
||||||
|
let Chunk {
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
nx,
|
||||||
|
ny,
|
||||||
|
start_x,
|
||||||
|
start_y,
|
||||||
|
} = meta;
|
||||||
|
|
||||||
|
for j in start_y..start_y + ny {
|
||||||
|
for i in start_x..start_x + nx {
|
||||||
|
let color = [i as f64 / x as f64, j as f64 / y as f64, 0.2];
|
||||||
|
let offset = (j * x + i) * 4;
|
||||||
|
|
||||||
|
buf[offset] = (255.99 * color[0]) as u8;
|
||||||
|
buf[offset + 1] = (255.99 * color[1]) as u8;
|
||||||
|
buf[offset + 2] = (255.99 * color[2]) as u8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
34
src/main.rs
34
src/main.rs
|
@ -15,13 +15,16 @@ use {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const NUM_SAMPLES: u8 = 20;
|
const NUM_SAMPLES: u8 = 100;
|
||||||
|
|
||||||
|
const VERTICAL_PARTITION: usize = 8;
|
||||||
|
const HORIZONTAL_PARTITION: usize = 8;
|
||||||
|
|
||||||
fn main() -> Result<(), String> {
|
fn main() -> Result<(), String> {
|
||||||
let sdl_ctx = sdl2::init()?;
|
let sdl_ctx = sdl2::init()?;
|
||||||
let video_subsys = sdl_ctx.video()?;
|
let video_subsys = sdl_ctx.video()?;
|
||||||
|
|
||||||
let (mut width, mut height) = (1280, 640);
|
let (width, height) = (1280usize, 640usize);
|
||||||
|
|
||||||
let window = video_subsys
|
let window = video_subsys
|
||||||
.window("Ray tracing in a weekend", width as u32, height as u32)
|
.window("Ray tracing in a weekend", width as u32, height as u32)
|
||||||
|
@ -53,6 +56,7 @@ fn main() -> Result<(), String> {
|
||||||
// TODO: Maybe consider using condition variable to make loop {} not run at full
|
// TODO: Maybe consider using condition variable to make loop {} not run at full
|
||||||
// speed at all times pinning a core at 100%
|
// speed at all times pinning a core at 100%
|
||||||
let mut should_update = true;
|
let mut should_update = true;
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
for event in event_pump.poll_iter() {
|
for event in event_pump.poll_iter() {
|
||||||
match event {
|
match event {
|
||||||
|
@ -68,12 +72,12 @@ fn main() -> Result<(), String> {
|
||||||
Some(Keycode::Num2) => {
|
Some(Keycode::Num2) => {
|
||||||
active_demo = Box::new(demos::LinearGradientRectangle)
|
active_demo = Box::new(demos::LinearGradientRectangle)
|
||||||
}
|
}
|
||||||
Some(Keycode::Num3) => active_demo = Box::new(demos::SimpleSphere),
|
//Some(Keycode::Num3) => active_demo = Box::new(demos::SimpleSphere),
|
||||||
Some(Keycode::Num4) => active_demo = Box::new(demos::SurfaceNormalSphere),
|
//Some(Keycode::Num4) => active_demo = Box::new(demos::SurfaceNormalSphere),
|
||||||
Some(Keycode::Num5) => active_demo = Box::new(demos::HitableSphere),
|
//Some(Keycode::Num5) => active_demo = Box::new(demos::HitableSphere),
|
||||||
Some(Keycode::Num6) => active_demo = Box::new(demos::SimpleAntialiasing),
|
//Some(Keycode::Num6) => active_demo = Box::new(demos::SimpleAntialiasing),
|
||||||
Some(Keycode::Num7) => active_demo = Box::new(demos::DiffuseMaterials),
|
//Some(Keycode::Num7) => active_demo = Box::new(demos::DiffuseMaterials),
|
||||||
Some(Keycode::Num8) => active_demo = Box::new(demos::Materials),
|
//Some(Keycode::Num8) => active_demo = Box::new(demos::Materials),
|
||||||
None => unreachable!(),
|
None => unreachable!(),
|
||||||
_ => (),
|
_ => (),
|
||||||
};
|
};
|
||||||
|
@ -83,13 +87,13 @@ fn main() -> Result<(), String> {
|
||||||
win_event: WindowEvent::Resized(w, h),
|
win_event: WindowEvent::Resized(w, h),
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
width = w as usize;
|
//width = w as usize;
|
||||||
height = h as usize;
|
//height = h as usize;
|
||||||
buffer.resize(width * height * 4, 0);
|
//buffer.resize(width * height * 4, 0);
|
||||||
texture = texture_creator
|
//texture = texture_creator
|
||||||
.create_texture_static(PixelFormatEnum::BGR888, width as u32, height as u32)
|
// .create_texture_static(PixelFormatEnum::BGR888, width as u32, height as u32)
|
||||||
.expect("error in resizing texture");
|
// .expect("error in resizing texture");
|
||||||
should_update = true;
|
//should_update = true;
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue
Block a user