99 lines
3.5 KiB
Rust
99 lines
3.5 KiB
Rust
extern crate mat4;
|
|
extern crate vec3;
|
|
|
|
use crate::object::Object;
|
|
use crate::ray::Ray;
|
|
use crate::sphere::Sphere;
|
|
use sdl2::pixels::Color;
|
|
|
|
fn put_pixel(data: &mut [u8], x: usize, y: usize, color: Color) {
|
|
data[y * 3 * 800 + x * 3] = color.r;
|
|
data[y * 3 * 800 + x * 3 + 1] = color.g;
|
|
data[y * 3 * 800 + x * 3 + 2] = color.b;
|
|
}
|
|
|
|
pub fn render(data: &mut [u8]) {
|
|
let sphere = Sphere {};
|
|
let projection_matrix: [f64; 16] = *mat4::perspective(
|
|
&mut mat4::new_zero(),
|
|
&(45. * 3.141592 / 180.),
|
|
&(800. / 600.),
|
|
&(0.1),
|
|
&(1000.),
|
|
);
|
|
let view_matrix: [f64; 16] = *mat4::translate(
|
|
&mut mat4::new_identity(),
|
|
&mat4::new_identity(),
|
|
&vec3::new(0., 0., -10.),
|
|
);
|
|
let model_matrix: [f64; 16] = *mat4::translate(
|
|
&mut mat4::new_identity(),
|
|
&mat4::new_identity(),
|
|
&vec3::new(1., 1., 0.),
|
|
);
|
|
for x in 0..800 {
|
|
for y in 0..600 {
|
|
let mut ray = Ray {
|
|
origin: [0., 0., 0.],
|
|
direction: [0., 0., 1.],
|
|
};
|
|
ray.direction[0] += (x as f64 - 400.) / 800.;
|
|
ray.direction[1] += (y as f64 - 300.) / 800.;
|
|
let mut n =
|
|
ray.direction[0].powi(2) + ray.direction[1].powi(2) + ray.direction[2].powi(2);
|
|
n = n.sqrt();
|
|
ray.direction[0] /= n;
|
|
ray.direction[1] /= n;
|
|
ray.direction[2] /= n;
|
|
// let ray2 = Box::clone(&Box::new(ray));
|
|
// vec3::transform_mat4(&mut ray.direction, &ray2.direction, &projection_matrix);
|
|
let ray2 = Box::clone(&Box::new(ray));
|
|
vec3::transform_mat4(&mut ray.origin, &ray2.origin, &view_matrix);
|
|
let ray2 = Box::clone(&Box::new(ray));
|
|
vec3::transform_mat4(&mut ray.origin, &ray2.origin, &model_matrix);
|
|
match sphere.get_intersection(ray) {
|
|
Some(dist) => {
|
|
let n = [
|
|
ray.origin[0] + ray.direction[0] * dist,
|
|
ray.origin[1] + ray.direction[1] * dist,
|
|
ray.origin[2] + ray.direction[2] * dist,
|
|
];
|
|
let normal = sphere.get_normal(n);
|
|
let light = [n[0] - 10., n[1] - 10., n[2] - 10.];
|
|
let scalar = (light[0].powi(2) + light[1].powi(2) + light[2].powi(2)).sqrt();
|
|
let light_d = [light[0] / scalar, light[1] / scalar, light[2] / scalar];
|
|
let mut diffuse =
|
|
normal[0] * light_d[0] + normal[1] * light_d[1] + normal[2] * light_d[2];
|
|
if diffuse < 0. {
|
|
diffuse = 0.;
|
|
}
|
|
put_pixel(
|
|
&mut *data,
|
|
x,
|
|
y,
|
|
Color {
|
|
r: (diffuse * 255.) as u8,
|
|
g: (diffuse * 255.) as u8,
|
|
b: (diffuse * 255.) as u8,
|
|
a: 0,
|
|
},
|
|
);
|
|
}
|
|
None => {
|
|
put_pixel(
|
|
&mut *data,
|
|
x,
|
|
y,
|
|
Color {
|
|
r: 0,
|
|
g: 0,
|
|
b: 0,
|
|
a: 0,
|
|
},
|
|
);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|