perf: writer

This commit is contained in:
dengqn 2025-08-05 14:13:47 +08:00
parent 71ae83d205
commit f60a06d84b
5 changed files with 94 additions and 23 deletions

View File

@ -1,10 +1,14 @@
use std::fs::File;
use std::io::{BufWriter};
use crate::hittable::HittableList;
use crate::math_utils::clamp;
use crate::ppm_writer::PPMWriter;
use crate::types_defined::{Camera, Color, Point, Ray, Vec3};
use rand::rngs::ThreadRng;
use rand::{Rng, thread_rng};
impl Camera {
impl<'a> Camera<'a> {
pub fn new(
image_width: i32,
aspect_ratio: f32,
@ -12,7 +16,8 @@ impl Camera {
camera_center: Point,
focal_length: Vec3,
sample_times: i8,
reflect_depth: i8
reflect_depth: i8,
ppm_file_writer: &'a mut PPMWriter<BufWriter<File>>
) -> Self {
let image_height = ((image_width as f32 / aspect_ratio) as i32).max(1);
let viewport_width = viewport_height * (image_width as f32 / image_height as f32);
@ -48,11 +53,12 @@ impl Camera {
viewport_top_left_pixel_center,
sample_times,
reflect_depth,
ppm_file_writer
}
}
pub fn render(&self, world: &HittableList) -> String {
let mut img_content = format!("P3\n{} {}\n255\n", self.image_width, self.image_height);
pub fn render(&mut self, world: &HittableList) {
// let mut img_content = format!("P3\n{} {}\n255\n", self.image_width, self.image_height);
for j in 0..self.image_height {
if j % 10 == 0 {
@ -63,7 +69,7 @@ impl Camera {
// color
let mut color = Color::new(0.0, 0.0, 0.0);
let rng = &mut thread_rng();
for s in 0..self.sample_times {
for _ in 0..self.sample_times {
let bias = self.random_square(rng);
let pix_sample = self.viewport_top_left_pixel_center
+ (i as f32 + bias.x) * self.viewport_u_delta
@ -82,13 +88,16 @@ impl Camera {
clamp(color.z, 0.0, 1.0),
);
self.ppm_file_writer.write(color.to_color());
// content
img_content.push_str(color_clamped.to_color().as_str());
img_content.push('\n');
// img_content.push_str(&color_clamped.to_color_str().as_str());
// img_content.push('\n');
}
}
img_content
// img_content
}
fn ray_color(&self, ray: &Ray, depth: i8, world: &HittableList) -> Vec3 {

View File

@ -1,7 +1,10 @@
use crate::types_defined::Color;
impl Color {
pub fn to_color(self) -> String {
pub fn to_color(self) -> Self {
return Color::new(self.x * 256.0 , self.y * 256.0, self.z * 256.0);
}
pub fn to_color_str(self) -> String {
return format!("{} {} {}\n", (self.x * 256.0) as u8, (self.y * 256.0) as u8, (self.z * 256.0) as u8);
}
}

View File

@ -1,6 +1,9 @@
use std::fs::File;
use std::io::BufWriter;
use crate::hittable::HittableList;
use crate::ppm_writer::PPMWriter;
use crate::types_defined::{Camera, Point, Sphere, Vec3};
use write_file_util::write_image;
mod camera;
mod color;
mod hittable;
@ -10,20 +13,35 @@ mod types_defined;
mod vec3;
mod write_file_util;
mod math_utils;
mod ppm_writer;
fn main() {
camera_render();
}
fn camera_render() {
let camera = Camera::new(
400,
let width: i32 = 400;
let height: i32 = 200;
let pw_r = PPMWriter::new(
BufWriter::new(File::create("./target/ray_sphere_normal_scene_render.ppm").unwrap()),
width, height);
if let Err(e) = pw_r {
println!("创建文件报错:{}", e);
return;
}
let pw = &mut pw_r.unwrap();
let mut camera: Camera = Camera::new(
width,
16.0 / 9.0,
2.0,
Point::new(0.0, 0.0, 0.0),
Vec3::new(0.0, 0.0, -1.0),
100,
50
50,
50,
pw
);
// world
// world objects(spheres)
@ -34,9 +52,9 @@ fn camera_render() {
world.put(Box::new(Sphere::new(Point::new(0.0, -100.0, -1.0), 100.0)));
world.put(Box::new(Sphere::new(Point::new(-0.5, 0.2, -0.5), 0.4)));
let ppm_content = camera.render(&world);
write_image(
ppm_content,
"./target/ray_sphere_normal_scene_render.ppm".to_string(),
)
camera.render(&world);
// write_image(
// ppm_content,
// "".to_string(),
// )
}

36
src/ppm_writer.rs Normal file
View File

@ -0,0 +1,36 @@
use std::io::{BufWriter, Write, Result};
use crate::types_defined::Color;
pub struct PPMWriter<W: Write> {
writter: BufWriter<W>
}
impl<W: Write> PPMWriter<W> {
/// 创建新的 PPM 写入器
///
/// 参数:
/// writer: 实现 Write 的目标
/// width: 图像宽度
/// height: 图像高度
pub fn new(mut inner: W, width: i32, height: i32) -> Result<Self> {
// 写入 PPM 头 (P6 二进制格式)
let header = format!("P6\n{} {}\n255\n", width, height);
inner.write_all(header.as_bytes())?;
Ok(PPMWriter { writter: BufWriter::new(inner) })
}
/// 写入单个像素 (高性能实现)
#[inline]
pub fn write(&mut self, color: Color) -> Result<()> {
// 直接写入字节数组避免额外内存分配
let bytes = [color.x as u8, color.y as u8, color.z as u8];
self.writter.write_all(&bytes)
}
/// 完成写入并刷新缓冲区
pub fn finish(mut self) -> Result<()> {
self.writter.flush()
}
}

View File

@ -1,8 +1,10 @@
use std::{fs::File, io::{BufWriter, Write}};
use crate::ppm_writer::PPMWriter;
/*
* [3]
*/
use crate::hittable::Hittable;
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Vec3 {
pub x: f32,
@ -28,7 +30,7 @@ pub struct HitRecord {
pub front_face: bool,
}
pub struct Camera {
pub struct Camera<'a> {
pub image_width: i32,
pub image_height: i32,
pub aspect_ratio: f32,
@ -44,7 +46,10 @@ pub struct Camera {
// sample times
pub sample_times: i8,
pub reflect_depth: i8
pub reflect_depth: i8,
// writer
pub ppm_file_writer: &'a mut PPMWriter<BufWriter<File>>
}
/*