matrix/matrix_graphics/src/main.rs
Ivan Bushchik 5448afe653
Update deps and fix some useless code
Signed-off-by: Ivan Bushchik <ivabus@ivabus.dev>
2023-03-12 21:27:34 +03:00

192 lines
4.7 KiB
Rust

use std::time::Instant;
use log::error;
use pixels::{PixelsBuilder, SurfaceTexture};
use winit::dpi::LogicalSize;
use winit::event::{Event, VirtualKeyCode};
use winit::event_loop::{ControlFlow, EventLoop};
use winit::window::{WindowBuilder, WindowButtons};
use winit_input_helper::WinitInputHelper;
use crate::structs::Line;
mod structs;
const WIDTH: u32 = 640;
const HEIGHT: u32 = 480;
const POLYGON: usize = 4;
// POLYGON >= 2
const CENTER_X: u32 = 320;
const CENTER_Y: u32 = 240;
const RADIUS: u32 = 100;
const PI: f64 = std::f64::consts::PI;
const DEFAULT_ANGLE: f64 = 0.;
impl Default for Line {
fn default() -> Self {
Line {
start_x: 0.,
start_y: 0.,
end_x: 0.,
end_y: 0.,
rotate_angle: 0.,
rotate_center_x: 0.,
rotate_center_y: 0.,
}
}
}
fn create_polygon() -> [Line; POLYGON] {
let mut it: [Line; POLYGON] = [Line::default(); POLYGON];
let mut dots: Vec<(f64, f64)> = Vec::new();
for i in 0..POLYGON {
dots.push((
CENTER_X as f64 + RADIUS as f64 * (2. * PI * i as f64 / POLYGON as f64).cos(),
CENTER_Y as f64 + RADIUS as f64 * (2. * PI * i as f64 / POLYGON as f64).sin(),
));
}
for i in 0..POLYGON {
let next = if i + 1 == POLYGON {
0
} else {
i + 1
};
it[i] = Line::new(
dots[i].0,
dots[i].1,
dots[next].0,
dots[next].1,
DEFAULT_ANGLE,
CENTER_X as f64,
CENTER_Y as f64,
);
}
it
}
// Most based render, that goes by existing frame bitmap and just expands it to RGBA.
fn render(frame: &mut [u8], bitmap: &[[bool; WIDTH as usize]; HEIGHT as usize]) {
for (i, pixel) in frame.chunks_exact_mut(4).enumerate() {
let x = i % WIDTH as usize;
let y = i / WIDTH as usize;
if bitmap[y][x] {
pixel.copy_from_slice(&[0xff, 0xff, 0xff, 0xff]);
} else {
pixel.copy_from_slice(&[0x00, 0x00, 0x00, 0xff]);
}
}
}
fn main() {
env_logger::init();
let event_loop = EventLoop::new();
let mut input = WinitInputHelper::new();
let window = {
let size = LogicalSize::new(WIDTH as f64, HEIGHT as f64);
WindowBuilder::new()
.with_title("matrix_graphics")
.with_enabled_buttons(WindowButtons::CLOSE.union(WindowButtons::MINIMIZE))
.with_inner_size(size)
.with_min_inner_size(size)
.with_max_inner_size(size)
.build(&event_loop)
.unwrap()
};
let mut pixels = {
let window_size = window.inner_size();
let surface_texture = SurfaceTexture::new(window_size.width, window_size.height, &window);
PixelsBuilder::new(WIDTH, HEIGHT, surface_texture).enable_vsync(true).build().unwrap()
};
let mut objects = create_polygon();
let mut frame_count = 0;
let mut now = Instant::now();
let mut bitmap: [[bool; WIDTH as usize]; HEIGHT as usize] =
[[false; WIDTH as usize]; HEIGHT as usize];
event_loop.run(move |event, _, control_flow| {
if event == Event::MainEventsCleared {
render(pixels.get_frame_mut(), &bitmap);
if let Err(err) = pixels.render() {
error!("pixels.render() failed: {err}");
*control_flow = ControlFlow::Exit;
return;
}
}
// Handle input events
if input.update(&event) {
if input.key_pressed(VirtualKeyCode::Escape)
|| input.close_requested()
|| input.destroyed()
{
*control_flow = ControlFlow::Exit;
return;
}
if input.key_pressed(VirtualKeyCode::F) {
println!("Average FPS: {}", frame_count as f64 / now.elapsed().as_secs_f64());
frame_count = 0;
now = Instant::now();
}
if input.key_held(VirtualKeyCode::Equals) {
for i in &mut objects {
i.rotate_angle += std::f64::consts::PI / 360.;
}
}
if input.key_held(VirtualKeyCode::Space) {
for i in &mut objects {
i.rotate_angle = 0.;
}
}
if input.key_held(VirtualKeyCode::Minus) {
for i in &mut objects {
i.rotate_angle -= std::f64::consts::PI / 360.;
}
}
if input.key_held(VirtualKeyCode::Up) {
for i in &mut objects {
i.start_y -= 1.;
i.end_y -= 1.;
i.rotate_center_y -= 1.;
}
}
if input.key_held(VirtualKeyCode::Down) {
for i in &mut objects {
i.start_y += 1.;
i.end_y += 1.;
i.rotate_center_y += 1.;
}
}
if input.key_held(VirtualKeyCode::Left) {
for i in &mut objects {
i.start_x -= 1.;
i.end_x -= 1.;
i.rotate_center_x -= 1.;
}
}
if input.key_held(VirtualKeyCode::Right) {
for i in &mut objects {
i.start_x += 1.;
i.end_x += 1.;
i.rotate_center_x += 1.;
}
}
for i in &mut objects {
i.update();
}
bitmap = [[false; WIDTH as usize]; HEIGHT as usize];
for object in &objects {
let current_dots = object.get_points();
for (x, y) in current_dots {
if x >= 0 && y >= 0 && x < WIDTH as isize && y < HEIGHT as isize {
bitmap[y as usize][x as usize] = true;
}
}
}
frame_count += 1;
}
});
}