rsrt_cpu/src/render.rs

223 lines
7.8 KiB
Rust

extern crate mat4;
extern crate vec3;
extern crate vec4;
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. / 800.),
&(0.1),
&(1000.),
);
// let view_matrix: [f64; 16] = *mat4::translate(
// &mut mat4::new_identity(),
// &mat4::new_identity(),
// &vec3::new(0., 0., -10.),
// );
let mut view_matrix = mat4::new_zero();
// view_matrix[0] = 1.;
// view_matrix[4] = 0.;
// view_matrix[8] = 0.;
// view_matrix[12] = 0.;
// view_matrix[1] = 0.;
// view_matrix[5] = 1.;
// view_matrix[9] = 0.;
// view_matrix[13] = 0.;
// view_matrix[2] = 0.;
// view_matrix[6] = 0.;
// view_matrix[10] = 1.;
// view_matrix[14] = 0.;
// view_matrix[3] = 0.;
// view_matrix[7] = 0.;
// view_matrix[11] = -10.;
// view_matrix[15] = 1.;
view_matrix[0] = 1.;
view_matrix[1] = 0.;
view_matrix[2] = 0.;
view_matrix[3] = 0.;
view_matrix[4] = 0.;
view_matrix[5] = 1.;
view_matrix[6] = 0.;
view_matrix[7] = 0.;
view_matrix[8] = 0.;
view_matrix[9] = 0.;
view_matrix[10] = 1.;
view_matrix[11] = 0.;
view_matrix[12] = 0.;
view_matrix[13] = 0.;
view_matrix[14] = 10.;
view_matrix[15] = 1.;
let _model_matrix: [f64; 16] = *mat4::rotate_y(
&mut mat4::new_identity(),
mat4::translate(
&mut mat4::new_identity(),
&mat4::new_identity(),
&vec3::new(0.5, 0.5, 0.),
),
&(3.141592 / 4.),
);
let _model_matrix: [f64; 16] = *mat4::translate(
&mut mat4::new_identity(),
mat4::rotate_y(
&mut mat4::new_identity(),
&mat4::new_identity(),
&(3.141592 / 4.),
),
&vec3::new(0.5, 0.5, 0.),
);
let _model_matrix: [f64; 16] = *mat4::translate(
&mut mat4::new_identity(),
&mat4::new_identity(),
&vec3::new(0.5, 0.5, 0.),
);
let _model_matrix: [f64; 16] = *mat4::rotate_y(
&mut mat4::new_identity(),
&mat4::new_identity(),
&(3.141592 / 40.),
);
let _model_matrix: [f64; 16] =
*mat4::rotate_y(&mut mat4::new_identity(), &mat4::new_identity(), &0.03);
let model_matrix: [f64; 16] = *mat4::scale(
&mut mat4::new_zero(),
mat4::rotate_y(
&mut mat4::new_zero(),
mat4::translate(
&mut mat4::new_zero(),
&mat4::new_identity(),
&vec3::new(0., 0., 0.),
),
&(3.141592 / 4.),
),
&vec3::new(1., 1., 1.),
);
// let model_matrix: [f64; 16] = *mat4::scale(
// &mut mat4::new_zero(),
// mat4::translate(
// &mut mat4::new_zero(),
// &mat4::new_identity(),
// &vec3::new(0.5, 0.5, 0.),
// ),
// &vec3::new(1., 2., 1.),
// );
// let model_matrix = mat4::new_identity();
for x in 0..800 {
for y in 0..800 {
let mut view_projection_matrix = mat4::new_zero();
mat4::mul(&mut view_projection_matrix, &model_matrix, &view_matrix);
let mut model_view_projection_matrix = mat4::new_zero();
mat4::mul(
&mut model_view_projection_matrix,
&view_projection_matrix,
&projection_matrix,
);
let mut inverse_view_projection_matrix = mat4::new_zero();
mat4::inv(
&mut inverse_view_projection_matrix,
&model_view_projection_matrix,
);
let far = vec4::new((x as f64 - 400.) / 400., (y as f64 - 400.) / 400., 1., 0.);
let near = vec4::new((x as f64 - 400.) / 400., (y as f64 - 400.) / 400., 0., 0.);
let mut new_far = vec4::new_zero();
let mut new_near = vec4::new_zero();
vec4::transform_mat4(&mut new_far, &far, &inverse_view_projection_matrix);
vec4::transform_mat4(&mut new_near, &near, &inverse_view_projection_matrix);
new_far[0] /= new_far[3];
new_far[1] /= new_far[3];
new_far[2] /= new_far[3];
new_far[3] /= new_far[3];
new_near[0] /= new_near[3];
new_near[1] /= new_near[3];
new_near[2] /= new_near[3];
new_near[3] /= new_near[3];
// let mut ray = Ray {
// origin: [view_matrix[3], view_matrix[7], view_matrix[11]],
// direction: [
// new_far[0] - new_near[0],
// new_far[1] - new_near[1],
// new_far[2] - new_near[2],
// ],
// };
let mut ray = Ray {
origin: [view_matrix[12], view_matrix[13], view_matrix[14]],
direction: [
new_far[0] - new_near[0],
new_far[1] - new_near[1],
new_far[2] - new_near[2],
],
};
let scalar =
(ray.direction[0].powi(2) + ray.direction[1].powi(2) + ray.direction[2].powi(2))
.sqrt();
ray.direction = [
ray.direction[0] / scalar,
ray.direction[1] / scalar,
ray.direction[2] / scalar,
];
if x == 0 && y == 0 {
println!("{:?}", ray);
}
// 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. * 0.9 + 0.1 * 255.) as u8,
g: (diffuse * 255. * 0.9 + 0.1 * 255.) as u8,
b: (diffuse * 255. * 0.9 + 0.1 * 255.) as u8,
a: 0,
},
);
}
None => {
put_pixel(
&mut *data,
x,
y,
Color {
r: 0,
g: 0,
b: 0,
a: 0,
},
);
}
}
}
}
}