Render a basic scene
This commit is contained in:
parent
e9900af986
commit
1eb3741b7d
|
|
@ -2,6 +2,7 @@ use nalgebra::{convert, RealField, Vector3};
|
|||
|
||||
use super::image::OutputImage;
|
||||
use super::raycasting::{Intersect, IntersectionInfo, Plane, Ray};
|
||||
use super::scene::Scene;
|
||||
|
||||
struct ImageSampler<T: RealField> {
|
||||
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)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
pub mod raycasting;
|
||||
pub mod image;
|
||||
pub mod camera;
|
||||
pub mod scene;
|
||||
|
|
|
|||
20
src/main.rs
20
src/main.rs
|
|
@ -5,7 +5,12 @@ use sdl2::render::{Canvas, Texture};
|
|||
use sdl2::Sdl;
|
||||
use std::time::Duration;
|
||||
|
||||
use nalgebra::Vector3;
|
||||
|
||||
use vanrijn::camera::render_scene;
|
||||
use vanrijn::image::OutputImage;
|
||||
use vanrijn::raycasting::{Plane, Sphere};
|
||||
use vanrijn::scene::Scene;
|
||||
|
||||
fn update_texture(image: &OutputImage, texture: &mut Texture) {
|
||||
texture
|
||||
|
|
@ -47,7 +52,15 @@ pub fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
image_height as u32,
|
||||
)?;
|
||||
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 i = 0;
|
||||
|
|
@ -65,11 +78,6 @@ pub fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
}
|
||||
|
||||
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.present();
|
||||
|
|
|
|||
|
|
@ -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 p = Plane::new(Vector3::new(1.0, 0.0, 0.0), -5.0);
|
||||
match p.intersect(&r) {
|
||||
Some(IntersectionInfo { distance, location }) => {
|
||||
assert!((location.x - (-5.0f64)).abs() < 0.0000000001)
|
||||
}
|
||||
None => panic!()
|
||||
Some(IntersectionInfo {
|
||||
distance: _,
|
||||
location,
|
||||
}) => assert!((location.x - (-5.0f64)).abs() < 0.0000000001),
|
||||
None => panic!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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>>>,
|
||||
}
|
||||
Loading…
Reference in New Issue