Fix x and y swapped

This commit is contained in:
Michael Zhang 2023-01-31 15:58:32 -06:00
parent d737124aa1
commit 3b04a7c494
5 changed files with 48 additions and 29 deletions

View file

@ -2,7 +2,25 @@ use std::io::{Result, Write};
/// A 24-bit pixel represented by a red, green, and blue value.
#[derive(Clone, Copy, Default, Debug)]
pub struct Pixel(pub u8, pub u8, pub u8);
pub struct Color {
pub red: u8,
pub green: u8,
pub blue: u8,
}
impl Color {
pub fn new(r: u8, g: u8, b: u8) -> Self {
Color {
red: r,
green: g,
blue: b,
}
}
pub fn from_01_float(r: f64, g: f64, b: f64) -> Self {
Color::new((r * 256.0) as u8, (g * 256.0) as u8, (b * 256.0) as u8)
}
}
/// A representation of an image
pub struct Image {
@ -13,7 +31,7 @@ pub struct Image {
pub(crate) height: usize,
/// Pixel data in row-major form.
pub(crate) data: Vec<Pixel>,
pub(crate) data: Vec<Color>,
}
impl Image {
@ -24,8 +42,10 @@ impl Image {
w.write_all(header.as_bytes())?;
// Pixel data
assert_eq!(self.data.len(), self.width * self.height);
for pixel in self.data.iter() {
let Pixel(red, green, blue) = pixel;
let Color { red, green, blue } = pixel;
let pixel = format!("{red} {green} {blue}\n");
w.write_all(pixel.as_bytes())?;
}

View file

@ -3,6 +3,7 @@ use std::{fs::File, io::Read, path::Path};
use anyhow::Result;
use crate::{
image::Color,
scene_data::{Object, Scene, Sphere},
vec3::Vec3,
};
@ -48,18 +49,25 @@ pub fn parse_input_file(path: impl AsRef<Path>) -> Result<Scene> {
Ok(Vec3::new(parts[0], parts[1], parts[2]))
};
let read_color = || {
if parts.len() < 3 {
bail!("Color requires 3 components.");
}
Ok(Color::from_01_float(parts[0], parts[1], parts[2]))
};
match keyword {
"eye" => scene.eye_pos = read_vec3()?,
"viewdir" => scene.view_dir = read_vec3()?,
"updir" => scene.up_dir = read_vec3()?,
"hfov" => scene.hfov = parts[0],
"bkgcolor" => scene.bkg_color = read_vec3()?,
"bkgcolor" => scene.bkg_color = read_color()?,
"mtlcolor" => {
let idx = scene.material_colors.len();
material_color = Some(idx);
scene.material_colors.push(read_vec3()?);
scene.material_colors.push(read_color()?);
}
"sphere" => scene.objects.push(Object::Sphere(Sphere {

View file

@ -15,7 +15,9 @@ use anyhow::Result;
use clap::Parser;
use itertools::Itertools;
use ordered_float::NotNan;
use rayon::prelude::{IntoParallelIterator, ParallelIterator};
use rayon::prelude::{
IndexedParallelIterator, IntoParallelIterator, ParallelIterator,
};
use crate::image::Image;
use crate::input_file::parse_input_file;
@ -24,7 +26,7 @@ use crate::scene_data::Object;
use crate::vec3::Vec3;
use crate::view::Rect;
const ARBITRARY_D: f64 = 1.0;
const ARBITRARY_D: f64 = 2.0;
/// Simple raycaster.
#[derive(Parser)]
@ -74,7 +76,6 @@ fn main() -> Result<()> {
let viewing_height = viewing_width / aspect_ratio;
// Compute viewing window corners
// TODO: See slide 101
let n = scene.view_dir.unit();
#[rustfmt::skip] // Otherwise this line wraps over
let view_window = Rect {
@ -103,14 +104,14 @@ fn main() -> Result<()> {
};
// This is an L because par_bridge is unordered
let pixels = (0..scene.image_width)
.cartesian_product(0..scene.image_height)
let pixels = (0..scene.image_height)
.cartesian_product(0..scene.image_width)
.collect_vec();
// Loop through every single pixel of the output file
let pixels = pixels
.into_par_iter()
.map(|(px, py)| {
.map(|(py, px)| {
let pixel_in_space = translate_pixel(px, py);
let ray = Ray::from_endpoints(scene.eye_pos, pixel_in_space);
@ -130,12 +131,12 @@ fn main() -> Result<()> {
let pixel_color = match earliest_intersection {
Some((_, sphere)) => scene.material_colors[sphere.material],
// There was no intersection, so this should default to the background
// color
// There was no intersection, so this should default to the scene's
// background color
None => scene.bkg_color,
};
pixel_color.to_pixel()
pixel_color
})
.collect::<Vec<_>>();

View file

@ -1,4 +1,4 @@
use crate::vec3::Vec3;
use crate::{image::Color, vec3::Vec3};
#[derive(Debug)]
pub struct Sphere {
@ -33,8 +33,8 @@ pub struct Scene {
pub image_height: usize,
/// Background color
pub bkg_color: Vec3,
pub bkg_color: Color,
pub material_colors: Vec<Vec3>,
pub material_colors: Vec<Color>,
pub objects: Vec<Object>,
}

View file

@ -1,9 +1,9 @@
use std::ops::{Add, Div, Mul, Sub};
use std::fmt;
use std::ops::{Add, Div, Mul, Sub};
use num::Float;
use crate::image::Pixel;
use crate::image::Color;
#[derive(Copy, Clone, Default, Debug, PartialEq, Eq)]
pub struct Vec3<T = f64> {
@ -54,16 +54,6 @@ impl<T: Float> Vec3<T> {
}
}
impl Vec3<f64> {
/// Convert into an RGB color
pub fn to_pixel(&self) -> Pixel {
let r = (self.x * 256.0) as u8;
let g = (self.y * 256.0) as u8;
let b = (self.z * 256.0) as u8;
Pixel(r, g, b)
}
}
/// Vector addition
impl<T> Add<Vec3<T>> for Vec3<T>
where