diff options
-rw-r--r-- | src/main.rs | 45 | ||||
-rw-r--r-- | src/sdf.rs | 10 | ||||
-rw-r--r-- | src/win.rs | 10 |
3 files changed, 52 insertions, 13 deletions
diff --git a/src/main.rs b/src/main.rs index 7dccf9f..078b8bc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -48,6 +48,7 @@ pub mod sdf; mod sdl; pub mod win; +use win::ColorF32; use nalgebra::{Matrix3, Matrix4, Rotation3, Vector3}; use std::time::Instant; @@ -185,11 +186,11 @@ struct State { framebuffer_texture: win::Texture, framebuffer: win::Framebuffer, main_array: win::VertexArray, + test_array: win::VertexArray, } impl State { fn new() -> Result<Self, String> { - let mut window = win::Window::new("AutoSDF", 1280, 720, true) .map_err(|e| format!("Error creating window: {e}"))?; let mut programs = Programs::new(&mut window); @@ -205,7 +206,7 @@ impl State { let mut framebuffer_texture = window.create_texture(&Default::default()); // we don't really care if there's an error. not much bad will happen. - let _ = window.set_texture_no_data::<win::ColorU8>(&mut framebuffer_texture, TEST_WIDTH.into(), TEST_HEIGHT.into()); + let _ = window.set_texture_no_data::<win::ColorF32>(&mut framebuffer_texture, TEST_WIDTH.into(), TEST_HEIGHT.into()); let mut framebuffer = window.create_framebuffer(); window.set_framebuffer_texture( @@ -215,6 +216,7 @@ impl State { ); let mut main_buffer = window.create_buffer(); + let mut test_buffer = window.create_buffer(); let data: &[[f32; 2]] = &[ [-1.0, -1.0], [1.0, -1.0], @@ -224,13 +226,14 @@ impl State { [-1.0, 1.0], ]; window.set_buffer_data(&mut main_buffer, data); - let mut main_array = window.create_vertex_array(main_buffer, &programs.main); - window.array_attrib2f(&mut main_array, "v_pos", 0); + window.set_buffer_data(&mut test_buffer, data); + let main_array = window.create_vertex_array(main_buffer, &programs.main); + let test_array = window.create_vertex_array(test_buffer, &programs.test); let view = View::default(); window.set_mouse_relative(true); - Ok(Self { + let mut me = Self { window, programs, view, @@ -238,18 +241,44 @@ impl State { frame_time: Instant::now(), show_debug_info: false, total_time: 0.0, - scene, + scene: sdf::Scene::default(), framebuffer_texture, framebuffer, main_array, - }) + test_array, + }; + me.load_scene(scene); + Ok(me) } fn load_scene(&mut self, scene: sdf::Scene) { match self.programs.load_scene(&mut self.window, &scene) { Ok(()) => { self.scene = scene; - self.view.level_set = 0.0; + // *technically speaking* the location of v_pos could change between reloads + self.window.array_attrib2f(&mut self.main_array, "v_pos", 0); + self.window.array_attrib2f(&mut self.test_array, "v_pos", 0); + + // determine default level set + // specifically we want to select y such that + // for ~1/4 of p values, sdf(p) < y + self.window.bind_framebuffer(Some(&self.framebuffer)); + self.window.viewport(0, 0, TEST_WIDTH.into(), TEST_HEIGHT.into()); + + self.window.draw_array(&self.test_array); + + self.window.viewport_full_screen(); + self.window.bind_framebuffer(None); + + let mut sdf_values: Vec<f32> = self.window.get_texture_data_vec::<ColorF32>( + &self.framebuffer_texture + ).iter() + .map(|c| c.r) + .collect(); + let i = sdf_values.len() / 4; + let level_set = *sdf_values.select_nth_unstable_by(i, + |a, b| a.total_cmp(b)).1; + self.view.level_set = level_set; } Err(e) => { eprintln!("Error: {e}") @@ -554,6 +554,16 @@ pub struct Scene { pub color_function: R3ToR3, } +impl Default for Scene { + /// a sphere. pretty boring + fn default() -> Self { + Self { + sdf: R3ToR::Sphere(Constant::F32(1.0)), + color_function: R3ToR3::Identity, + } + } +} + impl Scene { pub fn export_string(&self) -> String { let mut data: Vec<u8> = vec![]; @@ -850,7 +850,7 @@ impl Texture { } /// panicks if `data` is the wrong length (should be exactly `self.width() * self.height()`). - unsafe fn get_data<T: Color>(&mut self, data: &mut [T]) { + unsafe fn get_data<T: Color>(&self, data: &mut [T]) { assert_eq!(data.len(), self.width * self.height, "Bad data size."); self.bind(); gl::GetTexImage( @@ -862,7 +862,7 @@ impl Texture { ); } - unsafe fn get_data_vec<T: Color>(&mut self) -> Vec<T> { + unsafe fn get_data_vec<T: Color>(&self) -> Vec<T> { let mut data = vec![T::default(); self.width * self.height]; self.get_data(&mut data); data @@ -1140,7 +1140,7 @@ impl Window { unsafe { framebuffer.set_texture(attachment, texture) }; } - pub fn set_draw_framebuffer(&mut self, framebuffer: Option<&Framebuffer>) { + pub fn bind_framebuffer(&mut self, framebuffer: Option<&Framebuffer>) { match framebuffer { Some(f) => unsafe { f.bind() }, None => unsafe { Framebuffer::unbind() }, @@ -1239,12 +1239,12 @@ impl Window { /// get texture image /// /// panicks if `data.len() != texture.width() * texture.height()` - pub fn get_texture_data<T: Color>(&mut self, texture: &mut Texture, data: &mut [T]) { + pub fn get_texture_data<T: Color>(&mut self, texture: &Texture, data: &mut [T]) { unsafe { texture.get_data(data) }; } /// get texture image as a newly-allocated `Vec` - pub fn get_texture_data_vec<T: Color>(&mut self, texture: &mut Texture) -> Vec<T> { + pub fn get_texture_data_vec<T: Color>(&mut self, texture: &Texture) -> Vec<T> { unsafe { texture.get_data_vec() } } |