Compare commits

..

No commits in common. "e37eb169ceb97a4c8211670fce9c0bc3872f2e1d" and "e59f6ce896b8dae6223d61bd9419e304f06cbd33" have entirely different histories.

2 changed files with 35 additions and 54 deletions

View File

@ -1,25 +1,11 @@
use eframe::{egui_glow, glow}; use eframe::{egui_glow, glow};
use egui::mutex::Mutex; use egui::mutex::Mutex;
use std::sync::mpsc;
use std::sync::Arc; use std::sync::Arc;
mod waterfall; mod waterfall;
use waterfall::Waterfall; use waterfall::Waterfall;
pub mod turbo_colormap; pub mod turbo_colormap;
mod deadbeef_rand {
static mut RNG_SEED: u32 = 0x3d2faba7;
static mut RNG_BEEF: u32 = 0xdeadbeef;
pub fn rand() -> u8 {
unsafe {
RNG_SEED = (RNG_SEED << 7) ^ ((RNG_SEED >> 25).wrapping_add(RNG_BEEF));
RNG_BEEF = (RNG_BEEF << 7) ^ ((RNG_BEEF >> 25).wrapping_add(0xdeadbeef));
(RNG_SEED & 0xff) as u8
}
}
}
use deadbeef_rand::rand;
/// We derive Deserialize/Serialize so we can persist app state on shutdown. /// We derive Deserialize/Serialize so we can persist app state on shutdown.
pub struct TemplateApp { pub struct TemplateApp {
// Example stuff: // Example stuff:
@ -27,7 +13,6 @@ pub struct TemplateApp {
value: f32, value: f32,
/// Behind an `Arc<Mutex<…>>` so we can pass it to [`egui::PaintCallback`] and paint later. /// Behind an `Arc<Mutex<…>>` so we can pass it to [`egui::PaintCallback`] and paint later.
waterfall: Arc<Mutex<Waterfall>>, waterfall: Arc<Mutex<Waterfall>>,
fft_sender: mpsc::Sender<Vec<u8>>,
} }
impl TemplateApp { impl TemplateApp {
@ -39,7 +24,6 @@ impl TemplateApp {
// Load previous app state (if any). // Load previous app state (if any).
// Note that you must enable the `persistence` feature for this to work. // Note that you must enable the `persistence` feature for this to work.
let (tx, rx) = mpsc::channel();
let gl = cc let gl = cc
.gl .gl
.as_ref() .as_ref()
@ -49,8 +33,7 @@ impl TemplateApp {
// Example stuff: // Example stuff:
label: "Hello World!".to_owned(), label: "Hello World!".to_owned(),
value: 2.7, value: 2.7,
waterfall: Arc::new(Mutex::new(Waterfall::new(gl, 300, 300, rx))), waterfall: Arc::new(Mutex::new(Waterfall::new(gl, 300, 300))),
fft_sender: tx,
} }
} }
} }
@ -121,12 +104,6 @@ impl eframe::App for TemplateApp {
let _angle = response.drag_motion().x * 0.01; let _angle = response.drag_motion().x * 0.01;
let mut new_data = vec![0_u8; 300];
for data in new_data.iter_mut() {
*data = rand();
}
self.fft_sender.send(new_data).unwrap();
// Clone locals so we can move them into the paint callback: // Clone locals so we can move them into the paint callback:
let waterfall = self.waterfall.clone(); let waterfall = self.waterfall.clone();

View File

@ -1,11 +1,8 @@
use eframe::glow::{ use eframe::glow::{self, PixelUnpackData, TEXTURE0, TEXTURE1, UNSIGNED_BYTE};
self, PixelUnpackData, CLAMP_TO_EDGE, TEXTURE0, TEXTURE1, TEXTURE_WRAP_S, UNSIGNED_BYTE,
};
use glow::HasContext as _; use glow::HasContext as _;
use glow::{NEAREST, TEXTURE_2D, TEXTURE_MAG_FILTER, TEXTURE_MIN_FILTER}; use glow::{NEAREST, TEXTURE_2D, TEXTURE_MAG_FILTER, TEXTURE_MIN_FILTER};
use log; use log;
use std::mem::{size_of, transmute}; use std::mem::{size_of, transmute};
use std::sync::mpsc::Receiver;
const SIZE_OF_F32: i32 = size_of::<f32>() as i32; const SIZE_OF_F32: i32 = size_of::<f32>() as i32;
@ -18,6 +15,19 @@ unsafe fn check_for_gl_errors(gl: &glow::Context, msg: &str) {
} }
} }
mod deadbeef_rand {
static mut RNG_SEED: u32 = 0x3d2faba7;
static mut RNG_BEEF: u32 = 0xdeadbeef;
pub fn rand() -> u8 {
unsafe {
RNG_SEED = (RNG_SEED << 7) ^ ((RNG_SEED >> 25).wrapping_add(RNG_BEEF));
RNG_BEEF = (RNG_BEEF << 7) ^ ((RNG_BEEF >> 25).wrapping_add(0xdeadbeef));
(RNG_SEED & 0xff) as u8
}
}
}
use deadbeef_rand::rand;
use crate::app::turbo_colormap; use crate::app::turbo_colormap;
pub struct Waterfall { pub struct Waterfall {
@ -28,8 +38,6 @@ pub struct Waterfall {
vbo: glow::Buffer, vbo: glow::Buffer,
ebo: glow::Buffer, ebo: glow::Buffer,
offset: usize, offset: usize,
width: usize,
fft_in: Receiver<Vec<u8>>,
} }
impl Waterfall { impl Waterfall {
@ -46,6 +54,11 @@ impl Waterfall {
pub fn paint(&mut self, gl: &glow::Context, _angle: f32) { pub fn paint(&mut self, gl: &glow::Context, _angle: f32) {
use glow::HasContext as _; use glow::HasContext as _;
let mut new_data: [u8; 300] = [0; 300];
for data in new_data.iter_mut() {
*data = rand();
}
unsafe { unsafe {
// Bind our texturs // Bind our texturs
gl.active_texture(TEXTURE1); gl.active_texture(TEXTURE1);
@ -67,27 +80,22 @@ impl Waterfall {
check_for_gl_errors(&gl, "bind vao"); check_for_gl_errors(&gl, "bind vao");
// Update texture // Update texture
while let Ok(fft) = self.fft_in.try_recv() { gl.tex_sub_image_2d(
if fft.len() != self.width { glow::TEXTURE_2D,
todo!(); 0,
} 0,
gl.tex_sub_image_2d( self.offset as i32,
glow::TEXTURE_2D, 300,
0, 1,
0, glow::RED,
self.offset as i32, glow::UNSIGNED_BYTE,
self.width as i32, PixelUnpackData::Slice(&new_data),
1, );
glow::RED, check_for_gl_errors(&gl, "update texture");
glow::UNSIGNED_BYTE, self.offset = (self.offset + 1) % 300;
PixelUnpackData::Slice(&fft),
);
check_for_gl_errors(&gl, "update texture");
self.offset = (self.offset + 1) % self.width;
}
if let Some(uniform) = gl.get_uniform_location(self.program, "offset") { if let Some(uniform) = gl.get_uniform_location(self.program, "offset") {
gl.uniform_1_f32(Some(&uniform), self.offset as f32 / self.width as f32); gl.uniform_1_f32(Some(&uniform), self.offset as f32 / 300.0);
} }
check_for_gl_errors(&gl, "update uniform"); check_for_gl_errors(&gl, "update uniform");
@ -98,7 +106,7 @@ impl Waterfall {
check_for_gl_errors(&gl, "APP PAINT"); check_for_gl_errors(&gl, "APP PAINT");
} }
} }
pub fn new(gl: &glow::Context, width: usize, height: usize, fft_in: Receiver<Vec<u8>>) -> Self { pub fn new(gl: &glow::Context, width: usize, height: usize) -> Self {
let vertices: [f32; 32] = [ let vertices: [f32; 32] = [
// positions // colors // texture coords // positions // colors // texture coords
1.0, 1.0, 0.0, /**/ 1.0, 0.0, 0.0, /**/ 1.0, 1.0, // top right 1.0, 1.0, 0.0, /**/ 1.0, 0.0, 0.0, /**/ 1.0, 1.0, // top right
@ -206,8 +214,6 @@ impl Waterfall {
check_for_gl_errors(&gl, "Set LUT MIN_FILTER"); check_for_gl_errors(&gl, "Set LUT MIN_FILTER");
gl.tex_parameter_i32(TEXTURE_2D, TEXTURE_MAG_FILTER, NEAREST as i32); gl.tex_parameter_i32(TEXTURE_2D, TEXTURE_MAG_FILTER, NEAREST as i32);
check_for_gl_errors(&gl, "Set LUT MAG_FILTER"); check_for_gl_errors(&gl, "Set LUT MAG_FILTER");
gl.tex_parameter_i32(TEXTURE_2D, TEXTURE_WRAP_S, CLAMP_TO_EDGE as i32);
check_for_gl_errors(&gl, "Set LUT wrap mode");
gl.tex_image_2d( gl.tex_image_2d(
TEXTURE_2D, TEXTURE_2D,
0, 0,
@ -314,8 +320,6 @@ impl Waterfall {
vbo, vbo,
ebo, ebo,
offset: 0_usize, offset: 0_usize,
width,
fft_in,
} }
} }
} }