#![allow(dead_code)] #![allow(unused_variables)] #![allow(unused_mut)] extern crate cgmath; extern crate image; extern crate nalgebra as na; extern crate rand; extern crate sfml; extern crate time; use sfml::graphics::*; use sfml::graphics::{ Color, RenderTarget, RenderWindow, }; use sfml::system::*; use sfml::window::{Event, Key, Style}; use sfml::window::mouse::*; use sfml::window::mouse; use vulkano::sync; use std::sync::Arc; use std::{fs, mem, iter, ptr}; use std::path::PathBuf; use std::result; use crate::input::Input; use crate::slider::Slider; use crate::timer::Timer; use na::DimAdd; use std::time::{SystemTime, Duration}; use std::ffi::CStr; use std::ptr::write; use vulkano::buffer::{BufferUsage, CpuAccessibleBuffer, DeviceLocalBuffer, ImmutableBuffer, BufferAccess}; use vulkano::command_buffer::AutoCommandBufferBuilder; use vulkano::descriptor::descriptor_set::PersistentDescriptorSet; use vulkano::device::{Device, DeviceExtensions}; use vulkano::instance::{Instance, InstanceExtensions, PhysicalDevice}; use vulkano::pipeline::ComputePipeline; use vulkano::sync::GpuFuture; use shaderc::CompileOptions; use shade_runner::CompileError; use crate::workpiece::{WorkpieceLoader, Workpiece}; mod slider; mod timer; mod input; mod vkprocessor; mod util; mod button; mod workpiece; /* What next? Second sprite for rendering paths at x10 or so resolution color bucketing Textures and Sprites cannot live in the same struct as there is no way for a sprite to own its texture and become a single object (rust self-referencing structs) I want to pull out the textures into their own managing struct instead But I want to be able to modify the texture after I give it to a sprite which is an issue So if I place all the textures in a single container and then let a sprite borrow that container I will no longer be able to modify any of the textures I have to pass in the textures to the sprite individually so they don't get borrow poisoned It seems like I can put the textures in a struct as long as I pass the struct.texture explicitly So at first glance it seems like we need to + create a texture + assign that texture to a sprite And any time we want to update the texture. We need to delete the sprite So I'm kinda coming to the conclusion here that rust SFML is not made for frequent updates to the screen... Let's take a look at how easy it would be to replace SFML... e.g */ /// ``` /// struct Thing<'a> { /// field1: Option<&'a mut Thing<'a>> /// } /// /// fn main() { /// let mut thing1 = Thing { field1: None }; /// let mut thing2 = Thing { field1: None }; /// /// thing1.field1 = Some(&mut thing2); /// thing1.field1 = Some(&mut thing2); <-- Second mutable borrow error /// } /// ``` fn main() { let font = Font::from_file("resources/fonts/sansation.ttf").unwrap(); let instance = Instance::new(None, &InstanceExtensions::none(), None).unwrap(); let mut processor = vkprocessor::VkProcessor::new(&instance); processor.compile_kernel(String::from("simple-edge.compute")); processor.load_buffers(String::from("funky-bird.jpg")); processor.run_kernel(); processor.read_image(); processor.save_image(); let mut window = RenderWindow::new( (900, 900), "Custom drawable", Style::CLOSE, &Default::default(), ); let mut timer = Timer::new(); let mut input = Input::new(); let xy = processor.xy; let mut workpieceloader = WorkpieceLoader::new(String::from("resources/images/funky-bird.jpg")); workpieceloader.load_first_stage(processor.read_image()); let mut workpiece = Workpiece::new(); workpiece.render_sprite.set_texture(&mut workpieceloader.first_stage_texture, false); // workpiece.render_sprite.set_texture(&mut workpieceloader.swatch_texture, false); // workpiece.render_sprite.set_texture(&mut workpieceloader.vec.get(0).unwrap(), false); workpiece.render_sprite.set_texture(&mut workpieceloader.vec.get(0).unwrap(), false); workpiece.render_sprite = Sprite::new(); workpieceloader.first_stage_texture.set_smooth(false); let mut slider = Slider::new(Vector2f::new(40.0, 40.0), None, &font); let mut selected_colors = Vec::new(); let mut button = button::Button::new(Vector2f::new(40.0,40.0), Vector2f::new(100.0,100.0), &font); button.set_text("Text"); let step_size: f32 = 0.005; let mut elapsed_time: f32; let mut delta_time: f32; let mut accumulator_time: f32 = 0.0; let mut current_time: f32 = timer.elap_time(); let mut mouse_xy = Vector2i::new(0,0); while window.is_open() { while let Some(event) = window.poll_event() { match event { Event::Closed => return, Event::KeyPressed { code, .. } => { if code == Key::Escape { return; } }, Event::MouseButtonPressed { button, x, y} => { let x = x as u32; let y = y as u32; mouse_xy = mouse::desktop_position(); let r = processor.image_buffer[((processor.xy.0 * y + x) * 4 + 0) as usize] as u8; let g = processor.image_buffer[((processor.xy.0 * y + x) * 4 + 1) as usize] as u8; let b = processor.image_buffer[((processor.xy.0 * y + x) * 4 + 2) as usize] as u8; let a = processor.image_buffer[((processor.xy.0 * y + x) * 4 + 3) as usize] as u8; selected_colors.push( RectangleShape::with_size(Vector2f::new(30.0, 30.0)) ); let mut x_position = 45.0 * selected_colors.len() as f32; selected_colors.last_mut().unwrap().set_position(Vector2f::new(x_position, 80.0)); selected_colors.last_mut().unwrap().set_fill_color(&Color::rgba(r,g,b,a)); }, Event::MouseWheelScrolled { wheel, delta, x, y } => { if delta > 0.0 { workpiece.render_sprite.set_scale(workpiece.render_sprite.get_scale()*Vector2f::new(1.1,1.1)); } else { workpiece.render_sprite.set_scale(workpiece.render_sprite.get_scale()*Vector2f::new(0.9,0.9)); } }, _ => {} } input.ingest(&event) } // Dragging by middle click if input.is_mousebutton_held(Button::Middle) { let delta = mouse_xy - mouse::desktop_position(); mouse_xy = mouse::desktop_position(); workpiece.render_sprite.set_position( workpiece.render_sprite.position() - Vector2f::new(delta.x as f32, delta.y as f32) ); } elapsed_time = timer.elap_time(); delta_time = elapsed_time - current_time; current_time = elapsed_time; if delta_time > 0.02 { delta_time = 0.02; } accumulator_time += delta_time; while (accumulator_time - step_size) >= step_size { accumulator_time -= step_size; } window.clear(&Color::BLACK); window.draw(&workpiece.render_sprite); window.draw(&slider); for i in &selected_colors { window.draw(i); } window.draw(&button); window.display(); } }