Render a basic scene

This commit is contained in:
Matthew Gordon 2019-11-12 08:03:29 -05:00
parent e9900af986
commit 1eb3741b7d
5 changed files with 49 additions and 10 deletions

View File

@ -2,6 +2,7 @@ use nalgebra::{convert, RealField, Vector3};
use super::image::OutputImage; use super::image::OutputImage;
use super::raycasting::{Intersect, IntersectionInfo, Plane, Ray}; use super::raycasting::{Intersect, IntersectionInfo, Plane, Ray};
use super::scene::Scene;
struct ImageSampler<T: RealField> { struct ImageSampler<T: RealField> {
image_height_pixels: u32, image_height_pixels: u32,
@ -58,6 +59,26 @@ impl<T: RealField> ImageSampler<T> {
} }
} }
pub fn render_scene<T: RealField>(output_image: &mut OutputImage, scene: &Scene<T>) {
let image_sampler = ImageSampler::new(
output_image.get_width(),
output_image.get_height(),
scene.camera_location,
);
for column in 0..output_image.get_width() {
for row in 0..output_image.get_height() {
let ray = image_sampler.ray_for_pixel(row, column);
for object in scene.objects.iter() {
let gray = match object.intersect(&ray) {
None => 0,
Some(_) => 255,
};
output_image.set_color(row, column, gray, gray, gray);
}
}
}
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;

View File

@ -1,3 +1,4 @@
pub mod raycasting; pub mod raycasting;
pub mod image; pub mod image;
pub mod camera; pub mod camera;
pub mod scene;

View File

@ -5,7 +5,12 @@ use sdl2::render::{Canvas, Texture};
use sdl2::Sdl; use sdl2::Sdl;
use std::time::Duration; use std::time::Duration;
use nalgebra::Vector3;
use vanrijn::camera::render_scene;
use vanrijn::image::OutputImage; use vanrijn::image::OutputImage;
use vanrijn::raycasting::{Plane, Sphere};
use vanrijn::scene::Scene;
fn update_texture(image: &OutputImage, texture: &mut Texture) { fn update_texture(image: &OutputImage, texture: &mut Texture) {
texture texture
@ -47,7 +52,15 @@ pub fn main() -> Result<(), Box<dyn std::error::Error>> {
image_height as u32, image_height as u32,
)?; )?;
let mut output_image = OutputImage::new(image_width, image_height); let mut output_image = OutputImage::new(image_width, image_height);
output_image.clear();
let scene = Scene {
camera_location: Vector3::new(0.0, 0.0, 0.0),
objects: vec![
Box::new(Plane::new(Vector3::new(0.0, 1.0, 0.0), -2.0)),
Box::new(Sphere::new(Vector3::new(0.0, 1.0, 5.0), 1.0)),
],
};
render_scene(&mut output_image, &scene);
let mut event_pump = sdl_context.event_pump()?; let mut event_pump = sdl_context.event_pump()?;
let mut i = 0; let mut i = 0;
@ -65,11 +78,6 @@ pub fn main() -> Result<(), Box<dyn std::error::Error>> {
} }
update_texture(&output_image, &mut rendered_image_texture); update_texture(&output_image, &mut rendered_image_texture);
for row in 0..image_height {
for column in 0..image_width {
output_image.set_color(row, column, i, i, i);
}
}
canvas.copy(&rendered_image_texture, None, None)?; canvas.copy(&rendered_image_texture, None, None)?;
canvas.present(); canvas.present();

View File

@ -180,10 +180,11 @@ mod tests {
let r = Ray::new(Vector3::new(1.0, 2.0, 3.0), Vector3::new(-1.0, 0.0, 1.0)); let r = Ray::new(Vector3::new(1.0, 2.0, 3.0), Vector3::new(-1.0, 0.0, 1.0));
let p = Plane::new(Vector3::new(1.0, 0.0, 0.0), -5.0); let p = Plane::new(Vector3::new(1.0, 0.0, 0.0), -5.0);
match p.intersect(&r) { match p.intersect(&r) {
Some(IntersectionInfo { distance, location }) => { Some(IntersectionInfo {
assert!((location.x - (-5.0f64)).abs() < 0.0000000001) distance: _,
} location,
None => panic!() }) => assert!((location.x - (-5.0f64)).abs() < 0.0000000001),
None => panic!(),
} }
} }
} }

8
src/scene.rs Normal file
View File

@ -0,0 +1,8 @@
use nalgebra::{RealField,Vector3};
use crate::raycasting::Intersect;
pub struct Scene<T:RealField> {
pub camera_location: Vector3<T>,
pub objects: Vec<Box<dyn Intersect<T>>>,
}