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::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::*;
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
20
src/main.rs
20
src/main.rs
|
|
@ -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();
|
||||||
|
|
|
||||||
|
|
@ -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!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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