Attempting to render image in chunks

This commit is contained in:
Ishan Jain 2020-02-15 23:58:23 +05:30
parent edb0b64282
commit fbf41fae22
5 changed files with 121 additions and 44 deletions

View File

@ -7,4 +7,3 @@ edition = "2018"
[dependencies] [dependencies]
sdl2 = "0.33.0" sdl2 = "0.33.0"
rand = "0.7.3" rand = "0.7.3"

View File

@ -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;
} }
} }
} }

View File

@ -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) {

View File

@ -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;
} }
} }
} }

View File

@ -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;
} }
_ => {} _ => {}
}; };