Drawing optimisations

This commit is contained in:
STP
2023-11-25 13:22:54 -05:00
parent 055f3b6a71
commit 348be665c9
3 changed files with 35 additions and 85 deletions

View File

@@ -1,71 +1,10 @@
// engine
// .register_type::<Vector3<f32>>()
// .register_fn("V", Vector3::<f32>::new);
// engine
// .register_type::<Point3<f32>>()
// .register_fn("P", Point3::<f32>::new);
// engine
// .register_type::<Scene>()
// .register_fn("Scene", Scene::empty)
// .register_fn("addNode", Scene::add_node)
// .register_fn("addLight", Scene::add_light);
// engine
// .register_type::<Node>()
// .register_fn("Node", Node::new)
// .register_fn("translate", Node::translate)
// .register_fn("rotate", Node::rotate)
// .register_fn("scale", Node::scale);
// engine
// .register_type::<Camera>()
// .register_fn("Camera", Camera::new);
// engine
// .register_type::<Light>()
// .register_fn("Light", Light::new);
// engine
// .register_type::<Material>()
// .register_fn("Material", Material::new)
// .register_fn("MaterialRed", Material::red)
// .register_fn("MaterialBlue", Material::blue)
// .register_fn("MaterialGreen", Material::green)
// .register_fn("MaterialMagenta", Material::magenta)
// .register_fn("MaterialTurquoise", Material::turquoise);
// engine
// .register_type::<Sphere>()
// .register_fn("Sphere", Sphere::new)
// .register_fn("SphereUnit", Sphere::unit);
// engine
// .register_type::<Cube>()
// .register_fn("Cube", Cube::new)
// .register_fn("CubeUnit", Cube::unit);
// engine
// .register_type::<Cone>()
// .register_fn("Cone", Cone::new)
// .register_fn("ConeUnit", Cone::unit);
// engine
// .register_type::<Cylinder>()
// .register_fn("Cylinder", Cylinder::new);
// engine
// .register_type::<Circle>()
// .register_fn("Circle", Circle::new)
// .register_fn("CircleUnit", Circle::unit);
// engine
// .register_type::<Rectangle>()
// .register_fn("Rectangle", Rectangle::new)
// .register_fn("RectangleUnit", Rectangle::unit);
// engine
// .register_type::<SteinerSurface>()
// .register_fn("Steiner", SteinerSurface::new);
// engine
// .register_type::<Torus>()
// .register_fn("Torus", Torus::new);
let scene = Scene(); let scene = Scene();
let eye = P(0.0, 0.0, 3.0); let eye = P(0.0, 0.0, 3.0);
let target = P(0.0, 0.0, 0.0); let target = P(0.0, 0.0, 0.0);
let up = V(0.0, 1.0, 3.0); let up = V(0.0, 1.0, 3.0);
let cam = Camera(eye, target, up, 70.0, 1.0);
let cam = Camera(eye, target, up, 70.0);
let material = Material(V(0.5,0.5,0.5), V(0.8, 0.8, 0.8), 25.0); let material = Material(V(0.5,0.5,0.5), V(0.8, 0.8, 0.8), 25.0);
@@ -74,15 +13,19 @@ let ambient = Light(P(10.0,0.0,0.0), V(1.0,1.0,1.0), V(0.0, 0.0, 0.0));
let light2 = Light(P(0.0,0.0,10.0), V(0.0,1.0,1.0), V(0.1, 0.01, 0.001)); let light2 = Light(P(0.0,0.0,10.0), V(0.0,1.0,1.0), V(0.1, 0.01, 0.001));
scene.addLight(light2); scene.addLight(light2);
scene.addLight(ambient); scene.addLight(ambient);
// let sphere = Sphere(P(0.0,0.0,0.0), 4.0, material); // let sphere = Sphere(P(0.0,0.0,0.0), 4.0, material);
// let node = Node(sphere); // let node = Node(sphere);
// scene.addNode(node); // scene.addNode(node);
let stein = Steiner(material); let sphere = Adam( material);
let node = Node(stein); let node = Node(sphere);
scene.addNode(node); scene.addNode(node);
// let stein = Steiner(material);
// let node = Node(stein);
// scene.addNode(node);
scene scene

View File

@@ -1,7 +1,7 @@
use crate::state::run; use crate::state::run;
use error_iter::ErrorIter; use error_iter::ErrorIter;
const EPSILON: f32 = 1e-6; const EPSILON: f32 = 1e-9;
const INFINITY: f32 = f32::MAX; const INFINITY: f32 = f32::MAX;
const EPSILON_VECTOR: Vector3<f32> = Vector3::new(EPSILON, EPSILON, EPSILON); const EPSILON_VECTOR: Vector3<f32> = Vector3::new(EPSILON, EPSILON, EPSILON);
static ZERO_VECTOR: Vector3<f32> = Vector3::new(0.0, 0.0, 0.0); static ZERO_VECTOR: Vector3<f32> = Vector3::new(0.0, 0.0, 0.0);

View File

@@ -15,8 +15,8 @@ use winit::event::{Event, KeyboardInput, MouseButton, VirtualKeyCode, WindowEven
use winit::event_loop::{ControlFlow, EventLoop}; use winit::event_loop::{ControlFlow, EventLoop};
use winit::window::{Window, WindowBuilder}; use winit::window::{Window, WindowBuilder};
const START_WIDTH: i32 = 800; const START_WIDTH: i32 = 1400;
const START_HEIGHT: i32 = 800; const START_HEIGHT: i32 = 1000;
const COLOUR_CLEAR: [u8; 4] = [0x22, 0x00, 0x11, 0xff]; const COLOUR_CLEAR: [u8; 4] = [0x22, 0x00, 0x11, 0xff];
pub const INIT_FILE: &str = "scene.rhai"; pub const INIT_FILE: &str = "scene.rhai";
@@ -88,25 +88,18 @@ pub struct State {
scene: Scene, scene: Scene,
camera: Camera, camera: Camera,
window: Window, window: Window,
buffer_width: u32, buffer_width: u32,
buffer_height: u32, buffer_height: u32,
pixels: Arc<Mutex<Pixels>>, pixels: Arc<Mutex<Pixels>>,
gui: Gui, gui: Gui,
index: usize, index: usize,
finished: bool,
} }
impl State { impl State {
pub fn import_rhai_from_file(&mut self, filename: &str) -> Result<(), Box<dyn Error>> {
let script = std::fs::read_to_string(filename)?;
self.scene = Scene::from_rhai(&script)?.into();
Ok(())
}
pub fn import_rhai(&mut self, script: &str) -> Result<(), Box<dyn Error>> {
self.scene = Scene::from_rhai(&script)?.into();
Ok(())
}
pub fn new(window: Window, pixels: Pixels, gui: Gui) -> Self { pub fn new(window: Window, pixels: Pixels, gui: Gui) -> Self {
let scene = Scene::empty(); let scene = Scene::empty();
let window_size = window.inner_size(); let window_size = window.inner_size();
@@ -121,6 +114,7 @@ impl State {
pixels: Arc::new(Mutex::new(pixels)), pixels: Arc::new(Mutex::new(pixels)),
gui, gui,
index: 0, index: 0,
finished: false,
} }
} }
@@ -128,8 +122,11 @@ impl State {
if let Some(event) = self.gui.event.take() { if let Some(event) = self.gui.event.take() {
match event { match event {
GuiEvent::BufferResize(proportion) => self.resize_buffer(proportion)?, GuiEvent::BufferResize(proportion) => self.resize_buffer(proportion)?,
GuiEvent::CameraUpdate(camera) => self.set_camera(camera), GuiEvent::CameraUpdate(camera) => self.set_camera(camera)?,
GuiEvent::SceneLoad(script) => self.import_rhai(&script)?, GuiEvent::SceneLoad(scene) => {
self.scene = scene;
self.clear()?;
}
} }
}; };
Ok(()) Ok(())
@@ -143,6 +140,7 @@ impl State {
self.camera.set_size(self.buffer_width, self.buffer_height); self.camera.set_size(self.buffer_width, self.buffer_height);
self.clear()?; self.clear()?;
let mut pixels = self.pixels.lock().unwrap(); let mut pixels = self.pixels.lock().unwrap();
pixels.resize_buffer(self.buffer_width, self.buffer_height)?; pixels.resize_buffer(self.buffer_width, self.buffer_height)?;
Ok(()) Ok(())
@@ -173,13 +171,18 @@ impl State {
let mut pixels = self.pixels.lock().unwrap(); let mut pixels = self.pixels.lock().unwrap();
let frame = pixels.frame_mut(); let frame = pixels.frame_mut();
frame[i * 4..(i + 1) * 4].copy_from_slice(&rgba); frame[i * 4..(i + 1) * 4].copy_from_slice(&rgba);
self.index = (self.index + 1) % (frame.len() / 4); self.index = self.index + 1;
if self.index >= frame.len() / 4 {
self.finished = true;
return Ok(());
};
} }
Ok(()) Ok(())
} }
fn clear(&mut self) -> Result<(), Box<dyn Error>> { fn clear(&mut self) -> Result<(), Box<dyn Error>> {
self.index = 0; self.index = 0;
self.finished = false;
let mut pixels = self.pixels.lock().unwrap(); let mut pixels = self.pixels.lock().unwrap();
let frame = pixels.frame_mut(); let frame = pixels.frame_mut();
for pixel in frame.chunks_exact_mut(4) { for pixel in frame.chunks_exact_mut(4) {
@@ -188,14 +191,18 @@ impl State {
Ok(()) Ok(())
} }
fn set_camera(&mut self, camera: Camera) { fn set_camera(&mut self, camera: Camera) -> Result<(), Box<dyn Error>> {
self.clear()?;
self.camera = camera; self.camera = camera;
self.camera.set_size(self.buffer_width, self.buffer_height); self.camera.set_size(self.buffer_width, self.buffer_height);
Ok(())
} }
fn render(&mut self) -> Result<(), Box<dyn Error>> { fn render(&mut self) -> Result<(), Box<dyn Error>> {
self.update()?; //Update state self.update()?; //Update state
self.draw()?; //Draw to pixels if !self.finished {
self.draw()?;
}; //Draw to pixels
let pixels = self.pixels.lock().unwrap(); let pixels = self.pixels.lock().unwrap();
self.gui self.gui
.prepare(&self.window) .prepare(&self.window)