check
This commit is contained in:
parent
328a3127ae
commit
57bbbfe97f
24
Cargo.lock
generated
24
Cargo.lock
generated
@ -1470,9 +1470,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "quick-xml"
|
||||
version = "0.31.0"
|
||||
version = "0.34.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1004a344b30a54e2ee58d66a71b32d2db2feb0a31f9a2d302bf0536f15de2a33"
|
||||
checksum = "6f24d770aeca0eacb81ac29dfbc55ebcc09312fdd1f8bbecdc7e4a84e000e3b4"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
@ -1670,9 +1670,9 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||
|
||||
[[package]]
|
||||
name = "sctk-adwaita"
|
||||
version = "0.8.1"
|
||||
version = "0.8.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "82b2eaf3a5b264a521b988b2e73042e742df700c4f962cde845d1541adb46550"
|
||||
checksum = "70b31447ca297092c5a9916fc3b955203157b37c19ca8edde4f52e9843e602c7"
|
||||
dependencies = [
|
||||
"ab_glyph",
|
||||
"log",
|
||||
@ -2051,9 +2051,9 @@ checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96"
|
||||
|
||||
[[package]]
|
||||
name = "wayland-backend"
|
||||
version = "0.3.4"
|
||||
version = "0.3.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "34e9e6b6d4a2bb4e7e69433e0b35c7923b95d4dc8503a84d25ec917a4bbfdf07"
|
||||
checksum = "f90e11ce2ca99c97b940ee83edbae9da2d56a08f9ea8158550fd77fa31722993"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"downcast-rs",
|
||||
@ -2065,9 +2065,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wayland-client"
|
||||
version = "0.31.3"
|
||||
version = "0.31.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e63801c85358a431f986cffa74ba9599ff571fc5774ac113ed3b490c19a1133"
|
||||
checksum = "7e321577a0a165911bdcfb39cf029302479d7527b517ee58ab0f6ad09edf0943"
|
||||
dependencies = [
|
||||
"bitflags 2.5.0",
|
||||
"rustix",
|
||||
@ -2137,9 +2137,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wayland-scanner"
|
||||
version = "0.31.2"
|
||||
version = "0.31.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "67da50b9f80159dec0ea4c11c13e24ef9e7574bd6ce24b01860a175010cea565"
|
||||
checksum = "d7b56f89937f1cf2ee1f1259cf2936a17a1f45d8f0aa1019fae6d470d304cfa6"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quick-xml",
|
||||
@ -2148,9 +2148,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wayland-sys"
|
||||
version = "0.31.2"
|
||||
version = "0.31.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "105b1842da6554f91526c14a2a2172897b7f745a805d62af4ce698706be79c12"
|
||||
checksum = "43676fe2daf68754ecf1d72026e4e6c15483198b5d24e888b74d3f22f887a148"
|
||||
dependencies = [
|
||||
"dlib",
|
||||
"log",
|
||||
|
||||
@ -13,7 +13,7 @@ glutin = "0.31.3"
|
||||
glutin-winit = "0.4.2"
|
||||
copypasta = "0.10.1"
|
||||
raw-window-handle = "0.5.2"
|
||||
winit = "0.29.15"
|
||||
winit = "0.29.3"
|
||||
cgmath = "0.18.0"
|
||||
nalgebra-glm = "0.18.0"
|
||||
regex = "1.10.5"
|
||||
|
||||
@ -21,4 +21,5 @@ void main()
|
||||
|
||||
if (v_color.a == 0) { discard; }
|
||||
FragColor = stroke(v_distance, v_linewidth, v_antialias, v_color);
|
||||
// FragColor = v_color;
|
||||
}
|
||||
@ -33,47 +33,67 @@ void main ()
|
||||
// This function is externally generated
|
||||
// fetch_uniforms();
|
||||
|
||||
float id = gl_VertexID;
|
||||
v_linewidth = linewidth;
|
||||
v_antialias = antialias;
|
||||
v_color = color;
|
||||
|
||||
// transform prev/curr/next
|
||||
vec4 prev_ = <transform(prev)>;
|
||||
vec4 curr_ = <transform(curr)>;
|
||||
vec4 next_ = <transform(next)>;
|
||||
// vec4 prev_ = <transform(prev)>;
|
||||
// vec4 curr_ = <transform(curr)>;
|
||||
// vec4 next_ = <transform(next)>;
|
||||
|
||||
// prev/curr/next in viewport coordinates
|
||||
vec2 _prev = NDC_to_viewport(prev_, <viewport.viewport_global>.zw);
|
||||
vec2 _curr = NDC_to_viewport(curr_, <viewport.viewport_global>.zw);
|
||||
vec2 _next = NDC_to_viewport(next_, <viewport.viewport_global>.zw);
|
||||
// vec2 _prev = NDC_to_viewport(prev_, <viewport.viewport_global>.zw);
|
||||
// vec2 _curr = NDC_to_viewport(curr_, <viewport.viewport_global>.zw);
|
||||
// vec2 _next = NDC_to_viewport(next_, <viewport.viewport_global>.zw);
|
||||
|
||||
// Compute vertex final position (in viewport coordinates)
|
||||
float w = linewidth/2.0 + 1.5*antialias;
|
||||
float z;
|
||||
vec2 P;
|
||||
// if( curr == prev) {
|
||||
// vec2 v = normalize(_next.xy - _curr.xy);
|
||||
// vec2 normal = normalize(vec2(-v.y,v.x));
|
||||
// P = _curr.xy + normal*w*id;
|
||||
// } else if (curr == next) {
|
||||
// vec2 v = normalize(_curr.xy - _prev.xy);
|
||||
// vec2 normal = normalize(vec2(-v.y,v.x));
|
||||
// P = _curr.xy + normal*w*id;
|
||||
// } else {
|
||||
// vec2 v0 = normalize(_curr.xy - _prev.xy);
|
||||
// vec2 v1 = normalize(_next.xy - _curr.xy);
|
||||
// vec2 normal = normalize(vec2(-v0.y,v0.x));
|
||||
// vec2 tangent = normalize(v0+v1);
|
||||
// vec2 miter = vec2(-tangent.y, tangent.x);
|
||||
// float l = abs(w / dot(miter,normal));
|
||||
// P = _curr.xy + miter*l*sign(id);
|
||||
// }
|
||||
|
||||
if( curr == prev) {
|
||||
vec2 v = normalize(_next.xy - _curr.xy);
|
||||
vec2 v = normalize(next.xy - curr.xy);
|
||||
vec2 normal = normalize(vec2(-v.y,v.x));
|
||||
P = _curr.xy + normal*w*id;
|
||||
P = curr.xy + normal*w*id;
|
||||
} else if (curr == next) {
|
||||
vec2 v = normalize(_curr.xy - _prev.xy);
|
||||
vec2 v = normalize(curr.xy - prev.xy);
|
||||
vec2 normal = normalize(vec2(-v.y,v.x));
|
||||
P = _curr.xy + normal*w*id;
|
||||
P = curr.xy + normal*w*id;
|
||||
} else {
|
||||
vec2 v0 = normalize(_curr.xy - _prev.xy);
|
||||
vec2 v1 = normalize(_next.xy - _curr.xy);
|
||||
vec2 v0 = normalize(curr.xy - prev.xy);
|
||||
vec2 v1 = normalize(next.xy - curr.xy);
|
||||
vec2 normal = normalize(vec2(-v0.y,v0.x));
|
||||
vec2 tangent = normalize(v0+v1);
|
||||
vec2 miter = vec2(-tangent.y, tangent.x);
|
||||
float l = abs(w / dot(miter,normal));
|
||||
P = _curr.xy + miter*l*sign(id);
|
||||
P = curr.xy + miter*l*sign(id);
|
||||
}
|
||||
|
||||
if( abs(id) > 1.5 ) v_color.a = 0.0;
|
||||
|
||||
v_distance = w*id;
|
||||
gl_Position = viewport_to_NDC(P, <viewport.viewport_global>.zw, curr_.z / curr_.w);
|
||||
// gl_Position = viewport_to_NDC(P, <viewport.viewport_global>.zw, curr_.z / curr_.w);
|
||||
// gl_Position = curr.xy + miter * l * sign(id);
|
||||
|
||||
<viewport.transform()>;
|
||||
gl_Position = vec4(P , 0.0, 1.0);
|
||||
|
||||
// <viewport.transform()>;
|
||||
}
|
||||
@ -1,12 +1,7 @@
|
||||
layout(location = 0) in vec3 vertex;
|
||||
uniform mat4 projection;
|
||||
uniform mat4 view;
|
||||
|
||||
const vec2 verts[3] = vec2[3](
|
||||
vec2(0.5f, 1.0f),
|
||||
vec2(0.0f, 0.0f),
|
||||
vec2(1.0f, 0.0f)
|
||||
);
|
||||
|
||||
out vec2 vert;
|
||||
out vec4 color;
|
||||
|
||||
@ -23,7 +18,7 @@ vec4 srgb_to_linear(vec4 srgb_color) {
|
||||
}
|
||||
|
||||
void main() {
|
||||
vert = verts[gl_VertexID];
|
||||
vert = vec2(vertex.xy);
|
||||
color = srgb_to_linear(vec4(vert, 0.5, 1.0));
|
||||
gl_Position = vec4(vert - 0.5, 0.0, 1.0);
|
||||
gl_Position = vec4(vert, 0.0, 1.0);
|
||||
}
|
||||
@ -3,6 +3,10 @@
|
||||
layout(points) in;
|
||||
layout(triangle_strip, max_vertices = 4) out;
|
||||
|
||||
uniform mat4 projection;
|
||||
uniform mat4 view;
|
||||
uniform mat4 model;
|
||||
|
||||
// conf: Range, Elevation, Resolution, 0.0
|
||||
uniform vec4 conf;
|
||||
in float in_value[];
|
||||
|
||||
@ -1,4 +1,6 @@
|
||||
// Layout
|
||||
|
||||
|
||||
layout(location = 0) in vec3 position;
|
||||
out float in_value;
|
||||
|
||||
|
||||
@ -1,25 +1,23 @@
|
||||
use std::num::NonZeroU32;
|
||||
use cgmath::Euler;
|
||||
use glow::NativeProgram;
|
||||
use nalgebra_glm::{
|
||||
Vec3, Mat4x4, look_at
|
||||
};
|
||||
use nalgebra_glm::{look_at, Mat4x4, Vec3};
|
||||
use std::num::NonZeroU32;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub(crate) struct Camera {
|
||||
pos: Vec3,
|
||||
upward: Vec3,
|
||||
front: Vec3
|
||||
front: Vec3,
|
||||
}
|
||||
|
||||
pub type CameraPositon = Vec3;
|
||||
|
||||
impl Camera {
|
||||
pub(crate) fn new(world_loc: CameraPositon, upward: Vec3, front: Vec3) -> Self {
|
||||
|
||||
Self {
|
||||
pos: world_loc,
|
||||
upward,
|
||||
front
|
||||
front,
|
||||
}
|
||||
}
|
||||
|
||||
@ -51,5 +49,4 @@ impl Camera {
|
||||
let l = self.pos + self.front;
|
||||
look_at(&self.pos, &l, &self.upward)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,68 +0,0 @@
|
||||
use glow::HasContext;
|
||||
|
||||
use crate::{
|
||||
components::{CodeType, Program, Shader},
|
||||
graphics::transforms::{
|
||||
polar::Polar, position::Position, trackball::Trackball, viewport::Viewport, Transform,
|
||||
},
|
||||
};
|
||||
|
||||
// pub struct PPI {
|
||||
// transform: Trackball,
|
||||
// program: Program,
|
||||
// }
|
||||
|
||||
// impl PPI {
|
||||
// pub fn new(version: &'static str) -> Self {
|
||||
// let trackball = Trackball::new().unwrap();
|
||||
// let projection = Polar::new().unwrap();
|
||||
// let position = Position::new().unwrap();
|
||||
|
||||
// // let transform = trackball.chain(projection.chain(position));
|
||||
|
||||
// let vertex = Shader::new(
|
||||
// glow::VERTEX_SHADER,
|
||||
// CodeType::<&'static str>::Path("agg-fast-path.vert".into()),
|
||||
// )
|
||||
// .unwrap();
|
||||
|
||||
// let fragment = Shader::new(
|
||||
// glow::FRAGMENT_SHADER,
|
||||
// CodeType::<&'static str>::Path("agg-fast-path.frag".into()),
|
||||
// )
|
||||
// .unwrap();
|
||||
|
||||
// let mut program = Program::new(vertex, fragment, None, version);
|
||||
|
||||
// let viewport = Viewport::new().unwrap();
|
||||
|
||||
// // program.set_transform(&transform);
|
||||
|
||||
// program.set_viewport(&viewport);
|
||||
|
||||
// Self { transform, program }
|
||||
// }
|
||||
|
||||
// pub fn compile(&mut self, gl: &glow::Context) {
|
||||
// self.program.compile(gl);
|
||||
// }
|
||||
|
||||
// pub fn program(&self) -> &Program {
|
||||
// &self.program
|
||||
// }
|
||||
|
||||
// pub fn native_program(&self) -> Option<<glow::Context as HasContext>::Program> {
|
||||
// self.program.native_program
|
||||
// }
|
||||
// }
|
||||
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_ppi() {
|
||||
// let ppi = PPI::new("450");
|
||||
|
||||
// println!("{}", ppi.program.vertex());
|
||||
}
|
||||
}
|
||||
@ -8,16 +8,18 @@ use crate::errors::*;
|
||||
use crate::graphics::transforms::viewport::Viewport;
|
||||
use crate::graphics::transforms::Transform;
|
||||
use crate::graphics::ty::Ty;
|
||||
use crate::graphics::Graphics;
|
||||
use crate::graphics::{AttaWithBuffer, Config, Graphics};
|
||||
|
||||
use super::Colletion;
|
||||
|
||||
pub struct AggFastPath {
|
||||
program: Program,
|
||||
buffer: Vec<Point>,
|
||||
indice: Vec<[u32; 3]>,
|
||||
|
||||
vao: Option<NativeVertexArray>,
|
||||
vbo: Option<NativeBuffer>,
|
||||
ebo: Option<NativeBuffer>,
|
||||
}
|
||||
|
||||
impl AggFastPath {
|
||||
@ -63,6 +65,8 @@ impl AggFastPath {
|
||||
Ok(Self {
|
||||
program,
|
||||
buffer: Vec::with_capacity(128),
|
||||
indice: Vec::with_capacity(128 * 2),
|
||||
ebo: None,
|
||||
vao: None,
|
||||
vbo: None,
|
||||
})
|
||||
@ -104,6 +108,12 @@ impl AggFastPath {
|
||||
pub fn program_ref(&self) -> &Program {
|
||||
&self.program
|
||||
}
|
||||
|
||||
fn init(&mut self, gl: &glow::Context) {
|
||||
self.set_anatialias(gl, 0.005);
|
||||
self.set_linecolor(gl, [1.0, 1.0, 1.0, 1.0]);
|
||||
self.set_linewidth(gl, 0.02);
|
||||
}
|
||||
}
|
||||
|
||||
impl Colletion for AggFastPath {
|
||||
@ -111,6 +121,7 @@ impl Colletion for AggFastPath {
|
||||
|
||||
fn append(&mut self, item: Self::Item) {
|
||||
self.buffer.extend(item.points);
|
||||
self.indice.extend(item.ebo);
|
||||
}
|
||||
}
|
||||
|
||||
@ -118,10 +129,15 @@ impl Graphics for AggFastPath {
|
||||
fn compile(&mut self, gl: &glow::Context) -> Result<()> {
|
||||
use bytemuck::cast_slice;
|
||||
self.program.compile(gl)?;
|
||||
|
||||
unsafe {
|
||||
let vao = gl.create_vertex_array().unwrap();
|
||||
|
||||
gl.bind_vertex_array(Some(vao));
|
||||
for p in self.buffer.iter() {
|
||||
println!("{}", p);
|
||||
}
|
||||
println!("{:?}", self.indice);
|
||||
|
||||
let vbo = gl.create_buffer().unwrap();
|
||||
gl.bind_buffer(glow::ARRAY_BUFFER, Some(vbo));
|
||||
@ -143,8 +159,18 @@ impl Graphics for AggFastPath {
|
||||
gl.enable_vertex_attrib_array(3);
|
||||
gl.vertex_attrib_pointer_f32(3, 1, glow::FLOAT, false, 40, 36);
|
||||
|
||||
let ebo = gl.create_buffer().unwrap();
|
||||
gl.bind_buffer(glow::ELEMENT_ARRAY_BUFFER, Some(ebo));
|
||||
|
||||
gl.buffer_data_u8_slice(
|
||||
glow::ELEMENT_ARRAY_BUFFER,
|
||||
cast_slice(&self.indice),
|
||||
glow::STATIC_DRAW,
|
||||
);
|
||||
|
||||
self.vao = Some(vao);
|
||||
self.vbo = Some(vbo);
|
||||
self.ebo = Some(ebo);
|
||||
|
||||
gl.bind_vertex_array(None);
|
||||
}
|
||||
@ -152,13 +178,16 @@ impl Graphics for AggFastPath {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn draw(&self, gl: &glow::Context) -> Result<()> {
|
||||
fn draw(&self, gl: &glow::Context, count: i32) -> Result<()> {
|
||||
unsafe {
|
||||
gl.clear(glow::COLOR_BUFFER_BIT);
|
||||
gl.use_program(Some(self.program.native_program.unwrap()));
|
||||
gl.bind_vertex_array(Some(self.vao.unwrap()));
|
||||
gl.draw_arrays(glow::TRIANGLE_STRIP, 0, self.buffer.len() as i32);
|
||||
|
||||
gl.draw_elements(
|
||||
glow::TRIANGLES,
|
||||
(self.indice.len() * 3) as i32,
|
||||
glow::UNSIGNED_INT,
|
||||
0,
|
||||
);
|
||||
gl.bind_vertex_array(None);
|
||||
}
|
||||
|
||||
@ -169,14 +198,53 @@ impl Graphics for AggFastPath {
|
||||
self.program.destroy(gl);
|
||||
|
||||
unsafe {
|
||||
self.ebo.map(|ebo| gl.delete_buffer(ebo));
|
||||
self.vao.map(|vao| gl.delete_vertex_array(vao));
|
||||
self.vbo.map(|vbo| gl.delete_buffer(vbo));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn program_ref(&self) -> &Program {
|
||||
&self.program
|
||||
}
|
||||
|
||||
fn program_mut(&mut self) -> &mut Program {
|
||||
&mut self.program
|
||||
}
|
||||
|
||||
fn set_config(&mut self, gl: &glow::Context, config: Option<&Config>) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn mount(&mut self, gl: &glow::Context) -> Result<()> {
|
||||
unsafe {
|
||||
gl.use_program(self.program.native_program);
|
||||
self.init(gl);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn unmount(&mut self, gl: &glow::Context) -> Result<()> {
|
||||
unsafe {
|
||||
gl.use_program(None);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl AttaWithBuffer for AggFastPath {
|
||||
type Data = ();
|
||||
|
||||
fn bake(&self, data: &Self::Data) -> Result<(Vec<f32>, Option<Vec<u32>>, i32)> {
|
||||
Ok((vec![], None, 0))
|
||||
}
|
||||
|
||||
fn init(&self, gl: &glow::Context) -> (NativeVertexArray, NativeBuffer, Option<NativeBuffer>) {
|
||||
(self.vao.unwrap(), self.vbo.unwrap(), self.ebo)
|
||||
}
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Clone, Copy, Zeroable, Pod)]
|
||||
pub struct Point {
|
||||
@ -186,11 +254,23 @@ pub struct Point {
|
||||
id: f32,
|
||||
}
|
||||
|
||||
impl std::fmt::Display for Point {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"Point {{ prev: {:?}, curr: {:?}, next: {:?}, id: {} }}",
|
||||
self.prev, self.curr, self.next, self.id
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl Ty for Point {}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Path {
|
||||
points: Vec<Point>,
|
||||
ebo: Vec<[u32; 3]>,
|
||||
|
||||
is_closed: bool,
|
||||
is_empty: bool,
|
||||
}
|
||||
@ -199,6 +279,8 @@ impl Default for Path {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
points: Vec::with_capacity(500),
|
||||
ebo: Vec::with_capacity(500),
|
||||
|
||||
is_closed: false,
|
||||
is_empty: true,
|
||||
}
|
||||
@ -225,6 +307,8 @@ impl PathBuilder {
|
||||
Path {
|
||||
points: Vec::with_capacity(500),
|
||||
is_closed: self.is_closed,
|
||||
ebo: Vec::with_capacity(500),
|
||||
|
||||
is_empty: true,
|
||||
}
|
||||
}
|
||||
@ -234,6 +318,7 @@ impl Path {
|
||||
pub fn new(is_closed: bool) -> Self {
|
||||
Self {
|
||||
points: Vec::with_capacity(500),
|
||||
ebo: Vec::with_capacity(500),
|
||||
is_closed,
|
||||
is_empty: true,
|
||||
}
|
||||
@ -304,6 +389,11 @@ impl Path {
|
||||
self.points[len - 1].next = curr;
|
||||
self.points[len - 2].next = curr;
|
||||
}
|
||||
for s in 0..(self.points.len() / 2) - 1 {
|
||||
let s = s as u32;
|
||||
self.ebo.push([s * 2, s * 2 + 1, (s + 1) * 2 + 1]);
|
||||
self.ebo.push([s * 2, (s + 1) * 2 + 1, (s + 1) * 2]);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn len(&self) -> usize {
|
||||
|
||||
@ -1,20 +1,21 @@
|
||||
use std::ops::{Deref, DerefMut};
|
||||
|
||||
use bytemuck::{Pod, Zeroable};
|
||||
use bytemuck::{cast_slice, Pod, Zeroable};
|
||||
use glow::{HasContext, NativeBuffer, NativeVertexArray};
|
||||
|
||||
use crate::components::{fetchcode, CodeComponent, CodeType, Program, Shader, Snippet};
|
||||
use crate::errors::*;
|
||||
use crate::graphics::transforms::viewport::Viewport;
|
||||
use crate::graphics::transforms::Transform;
|
||||
use crate::graphics::ty::Ty;
|
||||
use crate::graphics::Graphics;
|
||||
|
||||
use super::{AttaWithBuffer, Config};
|
||||
|
||||
pub struct Hello {
|
||||
program: Program,
|
||||
buffer: Vec<Point>,
|
||||
|
||||
vao: Option<NativeVertexArray>,
|
||||
vbo: Option<NativeBuffer>,
|
||||
}
|
||||
|
||||
impl Hello {
|
||||
@ -38,6 +39,7 @@ impl Hello {
|
||||
program,
|
||||
buffer: Vec::with_capacity(128),
|
||||
vao: None,
|
||||
vbo: None,
|
||||
})
|
||||
}
|
||||
|
||||
@ -58,19 +60,46 @@ impl Graphics for Hello {
|
||||
.create_vertex_array()
|
||||
.expect("Cannot create vertex array");
|
||||
|
||||
let buffer: Vec<[f32; 3]> = vec![
|
||||
[-0.5, -0.5, 0.0],
|
||||
[-0.5, 0.5, 0.0],
|
||||
[0.5, 0.5, 0.0],
|
||||
[0.5, -0.5, 0.0],
|
||||
];
|
||||
|
||||
gl.bind_vertex_array(Some(vertex_array));
|
||||
|
||||
let vbo = gl.create_buffer().unwrap();
|
||||
|
||||
gl.bind_buffer(glow::ARRAY_BUFFER, Some(vbo));
|
||||
gl.buffer_data_u8_slice(glow::ARRAY_BUFFER, cast_slice(&buffer), glow::STATIC_DRAW);
|
||||
gl.enable_vertex_attrib_array(0);
|
||||
gl.vertex_attrib_pointer_f32(0, 3, glow::FLOAT, false, 12, 0);
|
||||
|
||||
let ebo = gl.create_buffer().unwrap();
|
||||
// let e: [[u32; 3]; 2] = [[0, 1, 3], [0, 2, 3]];
|
||||
let e: [[u32; 3]; 2] = [[0, 1, 2], [2, 3, 0]];
|
||||
gl.bind_buffer(glow::ELEMENT_ARRAY_BUFFER, Some(ebo));
|
||||
gl.buffer_data_u8_slice(
|
||||
glow::ELEMENT_ARRAY_BUFFER,
|
||||
cast_slice(&e),
|
||||
glow::STATIC_DRAW,
|
||||
);
|
||||
|
||||
self.vao = Some(vertex_array);
|
||||
self.vbo = Some(vbo);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn draw(&self, gl: &glow::Context) -> Result<()> {
|
||||
fn draw(&self, gl: &glow::Context, count: i32) -> Result<()> {
|
||||
unsafe {
|
||||
gl.clear_color(0.05, 0.05, 0.1, 1.0);
|
||||
gl.clear(glow::COLOR_BUFFER_BIT);
|
||||
gl.use_program(Some(self.program.native_program.unwrap()));
|
||||
gl.bind_vertex_array(self.vao);
|
||||
gl.draw_arrays(glow::TRIANGLES, 0, 3);
|
||||
|
||||
gl.draw_elements(glow::TRIANGLES, 6, glow::UNSIGNED_INT, 0);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@ -80,11 +109,51 @@ impl Graphics for Hello {
|
||||
self.program.destroy(gl);
|
||||
|
||||
unsafe {
|
||||
self.vbo.map(|vbo| gl.delete_buffer(vbo));
|
||||
self.vao.map(|vao| gl.delete_vertex_array(vao));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn program_ref(&self) -> &Program {
|
||||
&self.program
|
||||
}
|
||||
|
||||
fn program_mut(&mut self) -> &mut Program {
|
||||
&mut self.program
|
||||
}
|
||||
|
||||
fn set_config(&mut self, gl: &glow::Context, config: Option<&Config>) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn mount(&mut self, gl: &glow::Context) -> Result<()> {
|
||||
unsafe {
|
||||
gl.use_program(self.program.native_program);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn unmount(&mut self, gl: &glow::Context) -> Result<()> {
|
||||
unsafe {
|
||||
gl.use_program(None);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl AttaWithBuffer for Hello {
|
||||
type Data = ();
|
||||
|
||||
fn bake(&self, data: &Self::Data) -> Result<(Vec<f32>, Option<Vec<u32>>, i32)> {
|
||||
return Ok((vec![], None, 0));
|
||||
}
|
||||
|
||||
fn init(&self, gl: &glow::Context) -> (NativeVertexArray, NativeBuffer, Option<NativeBuffer>) {
|
||||
panic!("Not implemented");
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
|
||||
@ -3,20 +3,31 @@ pub mod colormap;
|
||||
mod colormesh;
|
||||
pub mod hello;
|
||||
pub mod ppi;
|
||||
pub mod threed;
|
||||
pub mod tools;
|
||||
pub mod transforms;
|
||||
pub mod ty;
|
||||
use crate::{components::Program, errors::*};
|
||||
|
||||
pub use colormesh::ColorMesh;
|
||||
use imgui::TextureId;
|
||||
use glow::{NativeBuffer, NativeVertexArray};
|
||||
use ppi::PPIConfig;
|
||||
|
||||
pub trait Graphics {
|
||||
fn draw(&self, gl: &glow::Context) -> Result<()>;
|
||||
pub trait Graphics: AttaWithBuffer {
|
||||
fn draw(&self, gl: &glow::Context, count: i32) -> Result<()>;
|
||||
|
||||
fn compile(&mut self, gl: &glow::Context) -> Result<()>;
|
||||
|
||||
fn destroy(&mut self, gl: &glow::Context) -> Result<()>;
|
||||
|
||||
fn program_ref(&self) -> &Program;
|
||||
|
||||
fn program_mut(&mut self) -> &mut Program;
|
||||
|
||||
fn mount(&mut self, gl: &glow::Context) -> Result<()>;
|
||||
|
||||
fn unmount(&mut self, gl: &glow::Context) -> Result<()>;
|
||||
|
||||
fn set_config(&mut self, gl: &glow::Context, config: Option<&Config>) -> Result<()>;
|
||||
}
|
||||
|
||||
pub trait AttaWithProgram {
|
||||
@ -25,12 +36,36 @@ pub trait AttaWithProgram {
|
||||
|
||||
pub trait AttaWithBuffer {
|
||||
type Data;
|
||||
fn attach_with_buffer(&mut self, gl: &glow::Context, data: &Self::Data) -> Result<()>;
|
||||
|
||||
fn bake(&self, data: &Self::Data) -> Result<(Vec<f32>, Option<Vec<u32>>, i32)>;
|
||||
fn init(&self, gl: &glow::Context) -> (NativeVertexArray, NativeBuffer, Option<NativeBuffer>);
|
||||
}
|
||||
|
||||
macro_rules! config_for_everyitem {
|
||||
($({$conf:ty => $name:tt},)+) => {
|
||||
$(
|
||||
impl From<$conf> for Config {
|
||||
fn from(value: $conf) -> Self {
|
||||
Self::$name(value)
|
||||
}
|
||||
}
|
||||
)+
|
||||
|
||||
pub trait AttaWithWindow {
|
||||
};
|
||||
}
|
||||
|
||||
fn attach_with_window(&mut self, gl: &glow::Context) -> Result<TextureId>;
|
||||
|
||||
}
|
||||
#[derive(Clone)]
|
||||
pub enum Config {
|
||||
PPI(PPIConfig),
|
||||
}
|
||||
|
||||
config_for_everyitem!({PPIConfig => PPI},);
|
||||
|
||||
pub trait AttachWithMouse {
|
||||
fn attach_with_mouse(&mut self, state: MouseState);
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum MouseState {
|
||||
Drag { from: [f32; 2], delta: [f32; 2] },
|
||||
}
|
||||
|
||||
@ -1,30 +1,18 @@
|
||||
use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
use glow::{HasContext, NativeBuffer, NativeVertexArray};
|
||||
|
||||
use bytemuck::cast_slice;
|
||||
use glow::{HasContext, NativeBuffer, NativeFramebuffer, NativeTexture, NativeVertexArray};
|
||||
use ndarray::{s, IndexLonger};
|
||||
|
||||
use crate::components::{CodeType, Program, Shader, Snippet};
|
||||
use crate::components::{CodeType, Program, Shader};
|
||||
use crate::data_loader::{CoordType, Data, DataType};
|
||||
use crate::errors::*;
|
||||
|
||||
use super::colormap::ColorMap;
|
||||
use super::threed::ThreeD;
|
||||
use super::transforms::viewport::Viewport;
|
||||
use super::transforms::Transform;
|
||||
use super::{ty, AttaWithBuffer, AttaWithWindow, Graphics};
|
||||
use super::{transforms, AttaWithBuffer, Config, Graphics};
|
||||
|
||||
pub struct PPI {
|
||||
program: Program,
|
||||
layer: isize,
|
||||
vao: Option<NativeVertexArray>,
|
||||
vbo: Option<NativeBuffer>,
|
||||
|
||||
cmap: Option<Box<dyn ColorMap>>,
|
||||
|
||||
framebuffer: Option<NativeFramebuffer>,
|
||||
frametexture: Option<NativeTexture>,
|
||||
buffer: Vec<[f32; 3]>,
|
||||
}
|
||||
|
||||
impl PPI {
|
||||
@ -44,24 +32,18 @@ impl PPI {
|
||||
CodeType::<String>::Path("ppi.frag".into()),
|
||||
)?;
|
||||
|
||||
let program = Program::new(vertex, fragment, Some(geom), "330 core");
|
||||
let transform = ThreeD::new(1.0, 2.0, 1000.0, 45.0)?;
|
||||
|
||||
let mut program = Program::new(vertex, fragment, Some(geom), "330 core");
|
||||
program.set_transform(&transform);
|
||||
|
||||
Ok(Self {
|
||||
program,
|
||||
layer: 0,
|
||||
vao: None,
|
||||
vbo: None,
|
||||
buffer: Vec::with_capacity(180 * 50),
|
||||
framebuffer: None,
|
||||
frametexture: None,
|
||||
cmap: None,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn set_transform<T: Transform>(&mut self, transform: &T) {
|
||||
self.program.set_transform(transform);
|
||||
}
|
||||
|
||||
pub fn set_viewport(&mut self, viewport: &Viewport) {
|
||||
self.program.set_viewport(viewport);
|
||||
}
|
||||
@ -75,23 +57,14 @@ impl PPI {
|
||||
&mut self.program
|
||||
}
|
||||
|
||||
fn set_conf(&self, gl: &glow::Context, dpir: f32, dpie: f32) {
|
||||
fn set_conf(&self, gl: &glow::Context, rdpi: f32, adpi: f32) {
|
||||
let location = self.program.get_uniform_location(gl, "conf");
|
||||
unsafe {
|
||||
gl.uniform_4_f32(location.as_ref(), dpir, dpie, 0f32, 0f32);
|
||||
gl.uniform_4_f32(location.as_ref(), rdpi, adpi, 0f32, 0f32);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_ppi_layer(&mut self, layer: isize) {
|
||||
self.layer = self.layer + layer;
|
||||
self.layer.clamp(0, 23);
|
||||
}
|
||||
|
||||
pub fn program_ref(&self) -> &Program {
|
||||
&self.program
|
||||
}
|
||||
|
||||
fn bake_data(&self, data: &Data) -> Result<Vec<[f32; 3]>> {
|
||||
fn bake_data(&self, data: &Data) -> Result<(Vec<f32>, i32)> {
|
||||
let first_block = data.blocks.get(0).unwrap();
|
||||
let first_block_data = first_block.data.view();
|
||||
if let CoordType::Polar {
|
||||
@ -113,16 +86,17 @@ impl PPI {
|
||||
let dt = first_block_data
|
||||
.get([self.layer as usize, azi_idx, r_idx])
|
||||
.unwrap();
|
||||
vertices.push([r, *azi, *dt]);
|
||||
vertices.extend([r, *azi, *dt]);
|
||||
}
|
||||
}
|
||||
return Ok(vertices);
|
||||
let len = vertices.len() as i32 / 3;
|
||||
return Ok((vertices, len));
|
||||
} else {
|
||||
return Err(Error::InvalidDataType);
|
||||
}
|
||||
}
|
||||
|
||||
fn data_info(&self, data: &Data) -> Result<(f32, f32, DataType)> {
|
||||
pub fn data_info(&self, data: &Data) -> Result<(f32, f32, DataType)> {
|
||||
let first_block = data.blocks.get(0).unwrap();
|
||||
if let CoordType::Polar {
|
||||
azimuth,
|
||||
@ -140,6 +114,23 @@ impl PPI {
|
||||
return Err(Error::InvalidDataType);
|
||||
}
|
||||
}
|
||||
|
||||
fn init(&mut self, gl: &glow::Context, config: &PPIConfig) {
|
||||
self.cmap
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.attach_with_program(gl, &self.program)
|
||||
.unwrap();
|
||||
|
||||
let origin = self.program.get_uniform_location(gl, "polar_origin");
|
||||
|
||||
let rdpi = config.rdpi;
|
||||
let adpi = config.adpi;
|
||||
self.set_conf(gl, rdpi, adpi);
|
||||
unsafe {
|
||||
gl.uniform_1_f32(origin.as_ref(), 90.0f32.to_radians());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn min_step(data: &Vec<f32>) -> f32 {
|
||||
@ -173,84 +164,57 @@ fn max_step(data: &Vec<f32>) -> f32 {
|
||||
impl Graphics for PPI {
|
||||
fn compile(&mut self, gl: &glow::Context) -> Result<()> {
|
||||
self.program.compile(gl)?;
|
||||
self.cmap
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.attach_with_program(gl, &self.program)?;
|
||||
unsafe {
|
||||
let vao = gl.create_vertex_array().unwrap();
|
||||
gl.bind_vertex_array(Some(vao));
|
||||
let vbo = gl.create_buffer().unwrap();
|
||||
gl.bind_buffer(glow::ARRAY_BUFFER, Some(vbo));
|
||||
gl.enable_vertex_attrib_array(0);
|
||||
gl.vertex_attrib_pointer_f32(0, 3, glow::FLOAT, false, 12, 0);
|
||||
|
||||
self.vao = Some(vao);
|
||||
self.vbo = Some(vbo);
|
||||
gl.bind_vertex_array(None);
|
||||
}
|
||||
|
||||
// let location = self.program.get_uniform_location(gl, "conf");
|
||||
let origin = self.program.get_uniform_location(gl, "polar_origin");
|
||||
|
||||
unsafe {
|
||||
// gl.uniform_4_f32(location.as_ref(), dpir, dpie, 0.0, 0.0);
|
||||
gl.uniform_1_f32(origin.as_ref(), 90.0f32.to_radians());
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn destroy(&mut self, gl: &glow::Context) -> Result<()> {
|
||||
self.program.destroy(gl);
|
||||
|
||||
unsafe {
|
||||
self.vao.map(|vao| gl.delete_vertex_array(vao));
|
||||
self.vbo.map(|vbo| gl.delete_buffer(vbo));
|
||||
self.framebuffer.map(|fb| gl.delete_framebuffer(fb));
|
||||
self.frametexture.map(|ft| gl.delete_texture(ft));
|
||||
self.cmap.as_mut().unwrap().destroy(gl);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn draw(&self, gl: &glow::Context) -> Result<()> {
|
||||
fn draw(&self, gl: &glow::Context, count: i32) -> Result<()> {
|
||||
unsafe {
|
||||
gl.clear(glow::COLOR_BUFFER_BIT);
|
||||
gl.use_program(Some(self.program.native_program.unwrap()));
|
||||
self.cmap
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.bind_texture(gl, &self.program)?;
|
||||
|
||||
if self.framebuffer.is_some() {
|
||||
gl.bind_framebuffer(glow::FRAMEBUFFER, self.framebuffer);
|
||||
gl.draw_arrays(glow::POINTS, 0, count);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn program_ref(&self) -> &Program {
|
||||
&self.program
|
||||
}
|
||||
|
||||
fn program_mut(&mut self) -> &mut Program {
|
||||
&mut self.program
|
||||
}
|
||||
|
||||
fn set_config(&mut self, gl: &glow::Context, config: Option<&Config>) -> Result<()> {
|
||||
if let Some(config) = config {
|
||||
if let Config::PPI(config) = config {
|
||||
self.init(gl, config);
|
||||
} else {
|
||||
panic!("Errr config type");
|
||||
}
|
||||
}
|
||||
|
||||
gl.depth_mask(false);
|
||||
gl.bind_vertex_array(Some(self.vao.unwrap()));
|
||||
gl.draw_arrays(glow::POINTS, 0, self.buffer.len() as i32);
|
||||
gl.depth_mask(true);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
if self.framebuffer.is_some() {
|
||||
gl.framebuffer_texture_2d(
|
||||
glow::FRAMEBUFFER,
|
||||
glow::COLOR_ATTACHMENT0,
|
||||
glow::TEXTURE_2D,
|
||||
self.frametexture,
|
||||
0,
|
||||
);
|
||||
fn mount(&mut self, gl: &glow::Context) -> Result<()> {
|
||||
unsafe {
|
||||
gl.use_program(self.program.native_program);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
gl.check_framebuffer_status(glow::FRAMEBUFFER),
|
||||
glow::FRAMEBUFFER_COMPLETE
|
||||
);
|
||||
gl.bind_texture(glow::TEXTURE_2D, None);
|
||||
gl.bind_framebuffer(glow::FRAMEBUFFER, None);
|
||||
}
|
||||
|
||||
gl.bind_vertex_array(None);
|
||||
fn unmount(&mut self, gl: &glow::Context) -> Result<()> {
|
||||
unsafe {
|
||||
gl.use_program(None);
|
||||
}
|
||||
Ok(())
|
||||
@ -260,68 +224,33 @@ impl Graphics for PPI {
|
||||
impl AttaWithBuffer for PPI {
|
||||
type Data = Data;
|
||||
|
||||
fn attach_with_buffer(&mut self, gl: &glow::Context, data: &Self::Data) -> Result<()> {
|
||||
let (rdpi, adpi, data_type) = self.data_info(data)?;
|
||||
fn bake(&self, data: &Self::Data) -> Result<(Vec<f32>, Option<Vec<u32>>, i32)> {
|
||||
// let (rdpi, adpi, data_type) = self.data_info(data)?;
|
||||
let baked_buffer = self.bake_data(data)?;
|
||||
self.buffer = baked_buffer;
|
||||
unsafe {
|
||||
gl.use_program(self.program.native_program);
|
||||
self.set_conf(gl, rdpi, adpi);
|
||||
gl.bind_vertex_array(self.vao);
|
||||
gl.buffer_data_u8_slice(
|
||||
glow::ARRAY_BUFFER,
|
||||
cast_slice(&self.buffer),
|
||||
glow::STATIC_DRAW,
|
||||
);
|
||||
}
|
||||
Ok((baked_buffer.0, None, baked_buffer.1))
|
||||
}
|
||||
|
||||
Ok(())
|
||||
fn init(&self, gl: &glow::Context) -> (NativeVertexArray, NativeBuffer, Option<NativeBuffer>) {
|
||||
unsafe {
|
||||
let vao = gl.create_vertex_array().unwrap();
|
||||
gl.bind_vertex_array(Some(vao));
|
||||
let vbo = gl.create_buffer().unwrap();
|
||||
gl.bind_buffer(glow::ARRAY_BUFFER, Some(vbo));
|
||||
gl.enable_vertex_attrib_array(0);
|
||||
gl.vertex_attrib_pointer_f32(0, 3, glow::FLOAT, false, 12, 0);
|
||||
gl.bind_vertex_array(None);
|
||||
|
||||
(vao, vbo, None)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl AttaWithWindow for PPI {
|
||||
fn attach_with_window(&mut self, gl: &glow::Context) -> Result<imgui::TextureId> {
|
||||
unsafe {
|
||||
if self.framebuffer.is_none() {
|
||||
let framebuffer = gl.create_framebuffer().unwrap();
|
||||
gl.bind_framebuffer(glow::FRAMEBUFFER, Some(framebuffer));
|
||||
|
||||
let texture = gl.create_texture().unwrap();
|
||||
|
||||
gl.bind_texture(glow::TEXTURE_2D, Some(texture));
|
||||
gl.tex_image_2d(
|
||||
glow::TEXTURE_2D,
|
||||
0,
|
||||
glow::RGB8 as i32,
|
||||
800,
|
||||
600,
|
||||
0,
|
||||
glow::RGB,
|
||||
glow::UNSIGNED_BYTE,
|
||||
None,
|
||||
);
|
||||
gl.tex_parameter_i32(
|
||||
glow::TEXTURE_2D,
|
||||
glow::TEXTURE_MIN_FILTER,
|
||||
glow::LINEAR as i32,
|
||||
);
|
||||
gl.tex_parameter_i32(
|
||||
glow::TEXTURE_2D,
|
||||
glow::TEXTURE_MAG_FILTER,
|
||||
glow::LINEAR as i32,
|
||||
);
|
||||
|
||||
gl.bind_framebuffer(glow::FRAMEBUFFER, None);
|
||||
gl.bind_texture(glow::TEXTURE_2D, None);
|
||||
self.frametexture = Some(texture);
|
||||
Ok(imgui::TextureId::from(texture.0.get() as usize))
|
||||
} else {
|
||||
Ok(imgui::TextureId::from(
|
||||
self.frametexture.unwrap().0.get() as usize
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
#[derive(Default, Clone)]
|
||||
pub struct PPIConfig {
|
||||
pub layer: usize,
|
||||
pub rdpi: f32,
|
||||
pub adpi: f32,
|
||||
pub trackball: ThreeD,
|
||||
}
|
||||
|
||||
mod test {
|
||||
|
||||
82
src/graphics/threed.rs
Normal file
82
src/graphics/threed.rs
Normal file
@ -0,0 +1,82 @@
|
||||
use std::rc::Rc;
|
||||
|
||||
use super::transforms::Transform;
|
||||
use super::transforms::{position::Position, trackball::Trackball, ChainedTransform};
|
||||
use super::{AttaWithProgram, AttachWithMouse};
|
||||
use crate::camera::Camera;
|
||||
use crate::errors::*;
|
||||
use glow::HasContext;
|
||||
use nalgebra_glm::Vec3;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ThreeD {
|
||||
transform: Rc<ChainedTransform>,
|
||||
projection: nalgebra_glm::Mat4,
|
||||
trackball: Trackball,
|
||||
camera: Camera,
|
||||
}
|
||||
|
||||
impl ThreeD {
|
||||
pub fn new(aspect: f32, z_far: f32, z_near: f32, fov: f32) -> Result<Self> {
|
||||
let trackball = Trackball::new()?;
|
||||
let transform = ChainedTransform::from(&trackball).chain(&Position::new()?);
|
||||
|
||||
let camera = Camera::new(
|
||||
Vec3::new(0.0, 0.0, 0.0),
|
||||
Vec3::new(0.0, 0.0, -1.0),
|
||||
Vec3::new(0.0, 1.0, 0.0),
|
||||
);
|
||||
|
||||
let projection = nalgebra_glm::perspective(aspect, fov, z_near, z_far);
|
||||
|
||||
Ok(Self {
|
||||
transform: Rc::new(transform),
|
||||
trackball,
|
||||
camera,
|
||||
projection,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for ThreeD {
|
||||
fn default() -> Self {
|
||||
Self::new(1.0, 2.0, 1000.0, 45.0).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl AttaWithProgram for ThreeD {
|
||||
fn attach_with_program(
|
||||
&self,
|
||||
gl: &glow::Context,
|
||||
program: &crate::components::Program,
|
||||
) -> Result<()> {
|
||||
unsafe {
|
||||
let view = program.get_uniform_location(gl, "trackball_view");
|
||||
let projection = program.get_uniform_location(gl, "trackball_projection");
|
||||
self.trackball.attach_with_program(gl, program)?;
|
||||
|
||||
gl.uniform_matrix_4_f32_slice(
|
||||
view.as_ref(),
|
||||
false,
|
||||
self.camera.get_view_matrix().as_slice(),
|
||||
);
|
||||
gl.uniform_matrix_4_f32_slice(projection.as_ref(), false, self.projection.as_slice());
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Transform for ThreeD {
|
||||
fn snippet(&self) -> &crate::components::Snippet {
|
||||
self.transform.snippet()
|
||||
}
|
||||
}
|
||||
|
||||
impl AttachWithMouse for ThreeD {
|
||||
fn attach_with_mouse(&mut self, state: super::MouseState) {
|
||||
if let super::MouseState::Drag { from, delta } = state {
|
||||
self.trackball
|
||||
.on_mouse_drag(from[0], from[1], delta[0], delta[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -12,19 +12,19 @@ pub struct ChainedTransform {
|
||||
}
|
||||
|
||||
impl ChainedTransform {
|
||||
pub fn from<T: Transform + 'static>(transform: T) -> Self {
|
||||
pub fn from<T: Transform + Clone + 'static>(transform: &T) -> Self {
|
||||
let snippet = transform.snippet().clone();
|
||||
// let snippet = transform.snippet().to_owned();
|
||||
Self {
|
||||
snippet,
|
||||
chain: vec![Box::new(transform)],
|
||||
chain: vec![Box::new(transform.clone())],
|
||||
}
|
||||
}
|
||||
|
||||
pub fn chain(mut self, other: impl Transform + 'static) -> Self {
|
||||
pub fn chain<P: Transform + 'static + Clone>(mut self, other: &P) -> Self {
|
||||
let new_snippet = self.snippet.clone().chain(other.snippet().to_owned());
|
||||
self.snippet = new_snippet;
|
||||
self.chain.push(Box::new(other));
|
||||
self.chain.push(Box::new(other.clone()));
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,6 +4,7 @@ use crate::{
|
||||
errors::*,
|
||||
graphics::AttaWithProgram,
|
||||
};
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Position {
|
||||
snippet: Snippet,
|
||||
}
|
||||
|
||||
@ -7,6 +7,7 @@ use super::Transform;
|
||||
use glow::HasContext;
|
||||
use nalgebra::{Matrix4, Quaternion, Translation3, Unit, UnitQuaternion, Vector3};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct TrackballModel {
|
||||
rotation: UnitQuaternion<f32>,
|
||||
count: usize,
|
||||
@ -36,7 +37,7 @@ impl TrackballModel {
|
||||
trackball
|
||||
}
|
||||
|
||||
pub fn drag_to(&mut self, x: f32, y: f32, dx: f32, dy: f32) {
|
||||
fn drag_to(&mut self, x: f32, y: f32, dx: f32, dy: f32) {
|
||||
let q = self.rotate(x, y, dx, dy);
|
||||
self.rotation *= q;
|
||||
self.count += 1;
|
||||
@ -47,23 +48,23 @@ impl TrackballModel {
|
||||
self.model = self.rotation.to_homogeneous();
|
||||
}
|
||||
|
||||
pub fn model(&self) -> &Matrix4<f32> {
|
||||
fn model(&self) -> &Matrix4<f32> {
|
||||
&self.model
|
||||
}
|
||||
|
||||
pub fn theta(&self) -> f32 {
|
||||
fn theta(&self) -> f32 {
|
||||
self.theta
|
||||
}
|
||||
|
||||
pub fn set_theta(&mut self, theta: f32) {
|
||||
fn set_theta(&mut self, theta: f32) {
|
||||
self.set_orientation(theta % 360.0, self.phi % 360.0);
|
||||
}
|
||||
|
||||
pub fn phi(&self) -> f32 {
|
||||
fn phi(&self) -> f32 {
|
||||
self.phi
|
||||
}
|
||||
|
||||
pub fn set_phi(&mut self, phi: f32) {
|
||||
fn set_phi(&mut self, phi: f32) {
|
||||
self.set_orientation(self.theta % 360.0, phi % 360.0);
|
||||
}
|
||||
|
||||
@ -128,17 +129,10 @@ impl TrackballModel {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Trackball {
|
||||
snippet: Snippet,
|
||||
|
||||
znear: f32,
|
||||
zfar: f32,
|
||||
zoom: f32,
|
||||
aspect: f32,
|
||||
model: TrackballModel,
|
||||
|
||||
projection: nalgebra_glm::Mat4x4,
|
||||
view: nalgebra::Matrix4<f32>,
|
||||
}
|
||||
|
||||
impl Trackball {
|
||||
@ -152,82 +146,18 @@ impl Trackball {
|
||||
|
||||
let model = TrackballModel::new(45.0, 45.0);
|
||||
|
||||
let aspect = 1.0;
|
||||
let fovy = 45.0;
|
||||
let near = 2.0;
|
||||
let far = 1000.0;
|
||||
|
||||
let projection = nalgebra_glm::perspective(aspect, fovy, near, far);
|
||||
|
||||
let mut view: Matrix4<f32> = Matrix4::identity();
|
||||
|
||||
let distance: f32 = 8.0;
|
||||
|
||||
let translation = Translation3::new(0.0, 0.0, -distance.abs());
|
||||
view = translation.to_homogeneous() * view;
|
||||
|
||||
Ok(Self {
|
||||
snippet: snippets,
|
||||
znear: near,
|
||||
zfar: far,
|
||||
zoom: fovy,
|
||||
aspect,
|
||||
model,
|
||||
projection,
|
||||
view,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn on_mouse_drag(
|
||||
&mut self,
|
||||
gl: &glow::Context,
|
||||
program: &mut Program,
|
||||
x: f32,
|
||||
y: f32,
|
||||
dx: f32,
|
||||
dy: f32,
|
||||
) {
|
||||
pub fn on_mouse_drag(&mut self, x: f32, y: f32, dx: f32, dy: f32) {
|
||||
self.model.drag_to(x, y, dx, dy);
|
||||
unsafe {
|
||||
let model = self.snippet.find_symbol("trackball_model").unwrap();
|
||||
let l = program.get_uniform_location(gl, &model);
|
||||
gl.uniform_matrix_4_f32_slice(l.as_ref(), false, self.model.model().as_slice());
|
||||
}
|
||||
}
|
||||
|
||||
pub fn on_mouse_scroll(
|
||||
&mut self,
|
||||
gl: &glow::Context,
|
||||
program: &mut Program,
|
||||
x: f32,
|
||||
y: f32,
|
||||
dz: f32,
|
||||
) {
|
||||
self.zoom += dz;
|
||||
self.projection = nalgebra_glm::perspective(self.aspect, self.zoom, self.znear, self.zfar);
|
||||
unsafe {
|
||||
let model = self.snippet.find_symbol("trackball_projection").unwrap();
|
||||
let l = program.get_uniform_location(gl, &model);
|
||||
gl.uniform_matrix_4_f32_slice(l.as_ref(), false, self.model.model().as_slice());
|
||||
}
|
||||
}
|
||||
|
||||
fn attach_with_program(&self, gl: &glow::Context, program: &Program) -> Result<()> {
|
||||
unsafe {
|
||||
let model = self.snippet.find_symbol("trackball_model").unwrap();
|
||||
let l = program.get_uniform_location(gl, &model);
|
||||
gl.uniform_matrix_4_f32_slice(l.as_ref(), false, self.model.model().as_slice());
|
||||
|
||||
let projection = self.snippet.find_symbol("trackball_projection").unwrap();
|
||||
let l = program.get_uniform_location(gl, &projection);
|
||||
gl.uniform_matrix_4_f32_slice(l.as_ref(), false, self.projection.as_slice());
|
||||
|
||||
let view = self.snippet.find_symbol("trackball_view").unwrap();
|
||||
let l = program.get_uniform_location(gl, &view);
|
||||
gl.uniform_matrix_4_f32_slice(l.as_ref(), false, self.view.as_slice());
|
||||
}
|
||||
|
||||
Ok(())
|
||||
pub fn model(&self) -> &Matrix4<f32> {
|
||||
self.model.model()
|
||||
}
|
||||
}
|
||||
|
||||
@ -239,7 +169,13 @@ impl Transform for Trackball {
|
||||
|
||||
impl AttaWithProgram for Trackball {
|
||||
fn attach_with_program(&self, gl: &glow::Context, program: &Program) -> Result<()> {
|
||||
self.attach_with_program(gl, program)
|
||||
unsafe {
|
||||
let model = self.snippet.find_symbol("trackball_model").unwrap();
|
||||
let l = program.get_uniform_location(gl, &model);
|
||||
gl.uniform_matrix_4_f32_slice(l.as_ref(), false, self.model.model().as_slice());
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
79
src/main.rs
79
src/main.rs
@ -1,83 +1,16 @@
|
||||
use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
|
||||
use data_loader::Data;
|
||||
use graphics::colormap::linear::LinearColormap;
|
||||
use graphics::ppi::PPI;
|
||||
use graphics::transforms::position::Position;
|
||||
use graphics::transforms::viewport::Viewport;
|
||||
use graphics::{AttaWithBuffer, Graphics, AttaWithWindow};
|
||||
use imgui::Condition;
|
||||
|
||||
mod ui;
|
||||
use pg::App;
|
||||
mod camera;
|
||||
mod components;
|
||||
mod data_loader;
|
||||
mod errors;
|
||||
mod graphics;
|
||||
mod pg;
|
||||
mod support;
|
||||
mod utils;
|
||||
use imgui::*;
|
||||
|
||||
mod final_pg;
|
||||
use support::supporter::run;
|
||||
|
||||
fn main() {
|
||||
env_logger::init();
|
||||
|
||||
let transform = Position::new().unwrap();
|
||||
let mut viewport = Viewport::new().unwrap();
|
||||
viewport.set_global(0.0, 0.0, 600.0, 800.0);
|
||||
|
||||
let mut cmap = LinearColormap::new().unwrap();
|
||||
|
||||
cmap.set_colors(vec![
|
||||
[170, 170, 170, 255],
|
||||
[0, 34, 255, 255],
|
||||
[1, 160, 246, 255],
|
||||
[0, 236, 236, 255],
|
||||
[0, 216, 0, 255],
|
||||
[1, 144, 0, 255],
|
||||
[255, 255, 0, 255],
|
||||
[231, 192, 0, 255],
|
||||
[255, 144, 0, 255],
|
||||
[255, 0, 0, 255],
|
||||
[214, 0, 0, 255],
|
||||
[192, 0, 0, 255],
|
||||
[255, 0, 240, 255],
|
||||
[150, 0, 180, 255],
|
||||
]);
|
||||
|
||||
cmap.set_range(0.0, 70.0);
|
||||
|
||||
let mut ppi = PPI::new().unwrap();
|
||||
ppi.set_transform(&transform);
|
||||
ppi.set_viewport(&viewport);
|
||||
ppi.set_colormap(Box::new(cmap));
|
||||
|
||||
let ppi = Rc::new(RefCell::new(ppi));
|
||||
|
||||
let registers = vec![ppi.clone()];
|
||||
let registers = registers.into_iter().map(|r| {
|
||||
r as Rc<RefCell<dyn Graphics>>
|
||||
}).collect();
|
||||
|
||||
|
||||
support::supporter::init(move |run, ui, window, gl| {
|
||||
let mut ppi = ppi.borrow_mut();
|
||||
let texture = ppi.attach_with_window(gl).unwrap();
|
||||
|
||||
ui.window("test").build(||{
|
||||
if ui.button("load") {
|
||||
let data = Data::from_path(r#"C:\Users\qwin7\Downloads\ZJSXAA_20230113070200_R.dat.gz"#).unwrap();
|
||||
ppi.attach_with_buffer(gl, &data).unwrap();
|
||||
}
|
||||
});
|
||||
|
||||
ui.window("Test").size([200.0,400.0], imgui::Condition::FirstUseEver).build(|| {
|
||||
imgui::Image::new(texture, [200.0, 400.0]).build(ui);
|
||||
});
|
||||
|
||||
|
||||
},
|
||||
registers,
|
||||
);
|
||||
}
|
||||
run(move |gl| App::new(gl).unwrap());
|
||||
}
|
||||
|
||||
740
src/pg.rs
Normal file
740
src/pg.rs
Normal file
@ -0,0 +1,740 @@
|
||||
use crate::data_loader::Data;
|
||||
use crate::graphics::colormap::linear::LinearColormap;
|
||||
use crate::graphics::ppi::PPIConfig;
|
||||
use crate::graphics::transforms::position::Position;
|
||||
use crate::graphics::transforms::viewport::Viewport;
|
||||
use crate::graphics::transforms::ChainedTransform;
|
||||
use crate::graphics::{ppi::PPI, Graphics};
|
||||
use crate::graphics::{AttaWithBuffer, AttaWithProgram, Config, MouseState};
|
||||
use crate::{errors::*, ui::base};
|
||||
use glow::{HasContext, NativeBuffer, NativeFramebuffer, NativeTexture, NativeVertexArray};
|
||||
use imgui::{ImStr, ImString, Textures, Ui};
|
||||
use log::info;
|
||||
use serde::de;
|
||||
use std::collections::HashSet;
|
||||
use std::{cell::RefCell, collections::HashMap, rc::Rc};
|
||||
use winit::window;
|
||||
pub type Graphic<Data> = Rc<RefCell<dyn Graphics<Data = Data>>>;
|
||||
type RcGraphic<T> = Rc<RefCell<T>>;
|
||||
|
||||
pub struct App<'a> {
|
||||
pub ui_state: State,
|
||||
gl: &'a glow::Context,
|
||||
viewport: Viewport,
|
||||
windows: HashMap<ImString, WindowData>,
|
||||
programs: [Graphic<Data>; 1],
|
||||
pub ppi_module: RcGraphic<PPI>,
|
||||
program_with_window: HashMap<usize, Vec<ImString>>,
|
||||
// Auto clean up
|
||||
all_vaos: HashMap<NativeVertexArray, usize>,
|
||||
all_other_buffers: HashMap<NativeBuffer, usize>,
|
||||
all_framebuffers: HashMap<NativeFramebuffer, usize>,
|
||||
all_frametextures: HashMap<NativeTexture, usize>,
|
||||
}
|
||||
|
||||
impl<'a> App<'a> {
|
||||
pub fn new(gl: &'a glow::Context) -> Result<Self> {
|
||||
let viewport = Viewport::new()?;
|
||||
|
||||
let mut cmap = LinearColormap::new().unwrap();
|
||||
cmap.set_colors(vec![
|
||||
[170, 170, 170, 255],
|
||||
[0, 34, 255, 255],
|
||||
[1, 160, 246, 255],
|
||||
[0, 236, 236, 255],
|
||||
[0, 216, 0, 255],
|
||||
[1, 144, 0, 255],
|
||||
[255, 255, 0, 255],
|
||||
[231, 192, 0, 255],
|
||||
[255, 144, 0, 255],
|
||||
[255, 0, 0, 255],
|
||||
[214, 0, 0, 255],
|
||||
[192, 0, 0, 255],
|
||||
[255, 0, 240, 255],
|
||||
[150, 0, 180, 255],
|
||||
]);
|
||||
cmap.set_range(0.0, 70.0);
|
||||
let cmap = Box::new(cmap);
|
||||
|
||||
let mut ppi = PPI::new()?;
|
||||
ppi.set_viewport(&viewport);
|
||||
ppi.set_colormap(cmap);
|
||||
|
||||
let ppi = Rc::new(RefCell::new(ppi));
|
||||
let programs = [ppi.clone() as Graphic<Data>];
|
||||
|
||||
Ok(Self {
|
||||
ui_state: State {},
|
||||
viewport,
|
||||
programs,
|
||||
windows: HashMap::new(),
|
||||
ppi_module: ppi,
|
||||
gl,
|
||||
program_with_window: HashMap::new(),
|
||||
all_vaos: HashMap::with_capacity(30),
|
||||
all_other_buffers: HashMap::with_capacity(30),
|
||||
all_framebuffers: HashMap::with_capacity(30),
|
||||
all_frametextures: HashMap::with_capacity(30),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn render(&mut self) {
|
||||
let mut need_clean = false;
|
||||
for (id, program) in self.programs.iter().enumerate() {
|
||||
let mut p = program.borrow_mut();
|
||||
|
||||
if self.program_with_window.len() == 0 {
|
||||
return;
|
||||
}
|
||||
|
||||
p.mount(&self.gl).unwrap();
|
||||
self.program_with_window.get(&id).map(|windows| {
|
||||
for window in windows.iter() {
|
||||
let window_info = self.windows.get_mut(window).unwrap();
|
||||
if !window_info.need_redraw {
|
||||
continue;
|
||||
}
|
||||
|
||||
let conf = if window_info.re_init {
|
||||
window_info.config.as_ref()
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
{
|
||||
p.set_config(self.gl, conf).unwrap();
|
||||
window_info.re_init = false;
|
||||
}
|
||||
|
||||
unsafe {
|
||||
self.gl
|
||||
.bind_framebuffer(glow::FRAMEBUFFER, window_info.framebuffer);
|
||||
|
||||
let attach = window_info.attach.as_ref();
|
||||
|
||||
if attach.is_some() {
|
||||
self.gl.bind_vertex_array(Some(attach.unwrap().vao));
|
||||
}
|
||||
|
||||
if attach.is_some() {
|
||||
let window_size = window_info.size;
|
||||
|
||||
self.gl
|
||||
.viewport(0, 0, window_size[0] as i32, window_size[1] as i32);
|
||||
p.draw(&self.gl, attach.as_ref().unwrap().len).unwrap();
|
||||
}
|
||||
|
||||
if attach.is_some() {
|
||||
self.gl.bind_vertex_array(None);
|
||||
}
|
||||
self.gl.bind_framebuffer(glow::FRAMEBUFFER, None);
|
||||
window_info.need_redraw = false;
|
||||
need_clean = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
p.unmount(&self.gl).unwrap();
|
||||
}
|
||||
|
||||
if need_clean {
|
||||
self.clean();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn render_ui(&mut self, ui: &Ui, window: &winit::window::Window, run: &mut bool) {
|
||||
base(ui, window, run, self);
|
||||
}
|
||||
|
||||
pub fn create_framebuffer(
|
||||
&mut self,
|
||||
id: &str,
|
||||
size: (i32, i32),
|
||||
) -> Result<(NativeFramebuffer, NativeTexture)> {
|
||||
let id = &ImString::new(id);
|
||||
let gl = self.gl;
|
||||
let tex = unsafe {
|
||||
let already = self.windows.contains_key(id)
|
||||
&& self.windows.get(id).unwrap().framebuffer.is_some();
|
||||
|
||||
if already {
|
||||
return Ok((
|
||||
self.windows[id].framebuffer.unwrap(),
|
||||
self.windows[id].frametexture.unwrap(),
|
||||
));
|
||||
}
|
||||
|
||||
let framebuffer = gl.create_framebuffer().unwrap();
|
||||
gl.bind_framebuffer(glow::FRAMEBUFFER, Some(framebuffer));
|
||||
|
||||
let texture = gl.create_texture().unwrap();
|
||||
gl.bind_texture(glow::TEXTURE_2D, Some(texture));
|
||||
gl.tex_image_2d(
|
||||
glow::TEXTURE_2D,
|
||||
0,
|
||||
glow::RGB8 as i32,
|
||||
size.0,
|
||||
size.1,
|
||||
0,
|
||||
glow::RGB,
|
||||
glow::UNSIGNED_BYTE,
|
||||
None,
|
||||
);
|
||||
gl.tex_parameter_i32(
|
||||
glow::TEXTURE_2D,
|
||||
glow::TEXTURE_MIN_FILTER,
|
||||
glow::LINEAR as i32,
|
||||
);
|
||||
gl.tex_parameter_i32(
|
||||
glow::TEXTURE_2D,
|
||||
glow::TEXTURE_MAG_FILTER,
|
||||
glow::LINEAR as i32,
|
||||
);
|
||||
|
||||
gl.framebuffer_texture_2d(
|
||||
glow::FRAMEBUFFER,
|
||||
glow::COLOR_ATTACHMENT0,
|
||||
glow::TEXTURE_2D,
|
||||
Some(texture),
|
||||
0,
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
gl.check_framebuffer_status(glow::FRAMEBUFFER),
|
||||
glow::FRAMEBUFFER_COMPLETE
|
||||
);
|
||||
|
||||
gl.bind_framebuffer(glow::FRAMEBUFFER, None);
|
||||
gl.bind_texture(glow::TEXTURE_2D, None);
|
||||
|
||||
self.all_framebuffers_add(&framebuffer);
|
||||
self.all_frametextures_add(&texture);
|
||||
(framebuffer, texture)
|
||||
};
|
||||
|
||||
Ok(tex)
|
||||
}
|
||||
|
||||
pub fn prepare(&mut self) {
|
||||
for program in self.programs.iter() {
|
||||
let mut p = program.borrow_mut();
|
||||
p.compile(&self.gl).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn destroy(&mut self) {
|
||||
for p in self.programs.iter() {
|
||||
let mut p = p.borrow_mut();
|
||||
p.unmount(&self.gl).unwrap();
|
||||
p.destroy(&self.gl).unwrap();
|
||||
}
|
||||
|
||||
info!("Cleaning up all resources");
|
||||
|
||||
unsafe {
|
||||
for vao in self.all_vaos.keys() {
|
||||
self.gl.delete_vertex_array(*vao);
|
||||
}
|
||||
|
||||
for vbo in self.all_other_buffers.keys() {
|
||||
self.gl.delete_buffer(*vbo);
|
||||
}
|
||||
|
||||
for framebuffer in self.all_framebuffers.keys() {
|
||||
self.gl.delete_framebuffer(*framebuffer);
|
||||
}
|
||||
|
||||
for texture in self.all_frametextures.keys() {
|
||||
self.gl.delete_texture(*texture);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn create_ppi_render(&mut self, id: &str, config: Option<PPIConfig>) {
|
||||
let id = &ImString::new(id);
|
||||
let (vao, vbo, ebo) = self.ppi_module.borrow().init(&self.gl);
|
||||
self.windows.get_mut(id).map(|w| {
|
||||
w.attach = Some(Attach {
|
||||
vao,
|
||||
vbo,
|
||||
ebo,
|
||||
len: 0,
|
||||
});
|
||||
w.need_redraw = true;
|
||||
w.program = 0;
|
||||
w.config = Some(config.unwrap_or_default().into());
|
||||
});
|
||||
|
||||
let v = self.program_with_window.entry(0).or_insert(vec![]);
|
||||
v.push(id.clone());
|
||||
|
||||
self.all_vaos_add(&vao);
|
||||
self.all_other_buffers_add(&vbo);
|
||||
ebo.map(|ebo| self.all_other_buffers_add(&ebo));
|
||||
}
|
||||
|
||||
pub fn bind_data(&mut self, id: &str, data: &Data) -> Result<()> {
|
||||
let id = &ImString::new(id);
|
||||
use bytemuck::cast_slice;
|
||||
|
||||
let window = self.windows.get_mut(id).unwrap();
|
||||
|
||||
let program = window.program;
|
||||
let program = self.programs[program].borrow();
|
||||
|
||||
let data = program.bake(data)?;
|
||||
|
||||
assert!(window.attach.is_some());
|
||||
let attach = window.attach.as_mut().unwrap();
|
||||
|
||||
attach.len = data.2;
|
||||
|
||||
unsafe {
|
||||
self.gl.bind_buffer(glow::VERTEX_ARRAY, Some(attach.vbo));
|
||||
self.gl.buffer_data_u8_slice(
|
||||
glow::ARRAY_BUFFER,
|
||||
cast_slice(data.0.as_slice()),
|
||||
glow::STATIC_DRAW,
|
||||
);
|
||||
if let Some(ebo) = attach.ebo {
|
||||
self.gl.bind_buffer(glow::ELEMENT_ARRAY_BUFFER, attach.ebo);
|
||||
self.gl.buffer_data_u8_slice(
|
||||
glow::ELEMENT_ARRAY_BUFFER,
|
||||
cast_slice(&data.1.as_ref().unwrap()),
|
||||
glow::STATIC_DRAW,
|
||||
);
|
||||
|
||||
self.gl.bind_buffer(glow::ELEMENT_ARRAY_BUFFER, None);
|
||||
}
|
||||
self.gl.bind_buffer(glow::VERTEX_ARRAY, None);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn all_framebuffers_add(&mut self, framebuffer: &NativeFramebuffer) {
|
||||
self.all_framebuffers
|
||||
.entry(*framebuffer)
|
||||
.and_modify(|v| *v += 1)
|
||||
.or_insert(1);
|
||||
|
||||
info!(
|
||||
"Framebuffer: {:?} + 1, Framebuffer {:?}: {}",
|
||||
framebuffer, framebuffer, self.all_framebuffers[framebuffer]
|
||||
);
|
||||
}
|
||||
|
||||
fn all_framebuffers_minus(&mut self, framebuffer: &NativeFramebuffer) {
|
||||
self.all_framebuffers
|
||||
.entry(*framebuffer)
|
||||
.and_modify(|v| *v -= 1);
|
||||
|
||||
info!(
|
||||
"Framebuffer: {:?} - 1, Framebuffer {:?}: {}",
|
||||
framebuffer, framebuffer, self.all_framebuffers[framebuffer]
|
||||
);
|
||||
}
|
||||
|
||||
fn all_frametextures_add(&mut self, texture: &NativeTexture) {
|
||||
self.all_frametextures
|
||||
.entry(*texture)
|
||||
.and_modify(|v| *v += 1)
|
||||
.or_insert(1);
|
||||
|
||||
info!(
|
||||
"Texture: {:?} + 1, Frametexture {:?}: {}",
|
||||
texture, texture, self.all_frametextures[texture]
|
||||
);
|
||||
}
|
||||
|
||||
fn all_frametextures_minus(&mut self, texture: &NativeTexture) {
|
||||
self.all_frametextures
|
||||
.entry(*texture)
|
||||
.and_modify(|v| *v -= 1);
|
||||
|
||||
info!(
|
||||
"Texture: {:?} - 1, Frametexture {:?}: {}",
|
||||
texture, texture, self.all_frametextures[texture]
|
||||
);
|
||||
}
|
||||
|
||||
fn all_vaos_add(&mut self, vao: &NativeVertexArray) {
|
||||
self.all_vaos
|
||||
.entry(*vao)
|
||||
.and_modify(|v| *v += 1)
|
||||
.or_insert(1);
|
||||
|
||||
info!("Vao: {:?} + 1, Vao {:?}: {}", vao, vao, self.all_vaos[vao]);
|
||||
}
|
||||
|
||||
fn all_vaos_minus(&mut self, vao: &NativeVertexArray) {
|
||||
self.all_vaos.entry(*vao).and_modify(|v| *v -= 1);
|
||||
|
||||
info!("Vao: {:?} - 1, Vao {:?}: {}", vao, vao, self.all_vaos[vao]);
|
||||
}
|
||||
|
||||
fn all_other_buffers_add(&mut self, buffer: &NativeBuffer) {
|
||||
self.all_other_buffers
|
||||
.entry(*buffer)
|
||||
.and_modify(|v| *v += 1)
|
||||
.or_insert(1);
|
||||
|
||||
info!(
|
||||
"Buffer: {:?} + 1, Buffer {:?}: {}",
|
||||
buffer, buffer, self.all_other_buffers[buffer]
|
||||
);
|
||||
}
|
||||
|
||||
fn all_other_buffers_minus(&mut self, buffer: &NativeBuffer) {
|
||||
self.all_other_buffers
|
||||
.entry(*buffer)
|
||||
.and_modify(|v| *v -= 1);
|
||||
|
||||
info!(
|
||||
"Buffer: {:?} - 1, Buffer {:?}: {}",
|
||||
buffer, buffer, self.all_other_buffers[buffer]
|
||||
);
|
||||
}
|
||||
|
||||
pub fn show_window(&mut self, ui: &Ui) {
|
||||
let mut need_resize = vec![];
|
||||
|
||||
for (id, window) in self.windows.iter_mut() {
|
||||
ui.window(&window.title)
|
||||
.size(window.size, imgui::Condition::FirstUseEver)
|
||||
.opened(&mut window.open)
|
||||
.flags(imgui::WindowFlags::NO_SCROLLBAR)
|
||||
.build(|| {
|
||||
if ui.is_mouse_clicked(imgui::MouseButton::Left) {
|
||||
let io = ui.io();
|
||||
let pos = io.mouse_pos;
|
||||
window.last_mouse_position = pos;
|
||||
}
|
||||
|
||||
if ui.is_mouse_dragging(imgui::MouseButton::Left) {
|
||||
let delta = ui.mouse_drag_delta();
|
||||
window.last_mouse_delta = delta;
|
||||
window.accmulate_mouse_delta = [
|
||||
window.accmulate_mouse_delta[0] + delta[0],
|
||||
window.accmulate_mouse_delta[1] + delta[1],
|
||||
];
|
||||
window.motion = Some(MouseState::Drag {
|
||||
from: window.last_mouse_position,
|
||||
delta: delta,
|
||||
});
|
||||
}
|
||||
if ui.is_mouse_released(imgui::MouseButton::Left) {
|
||||
if window.size != ui.window_size() {
|
||||
window.size = ui.window_size();
|
||||
println!("resized: {:?}", window.size);
|
||||
need_resize.push((window.title.clone(), ui.window_size()));
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(texture) = window.frametexture {
|
||||
let cursor = ui.cursor_pos();
|
||||
imgui::Image::new(
|
||||
imgui::TextureId::new(texture.0.get() as usize),
|
||||
ui.window_size(),
|
||||
)
|
||||
.build(ui);
|
||||
ui.set_cursor_pos(cursor);
|
||||
if ui.invisible_button(&window.title, ui.window_size()) {
|
||||
let io = ui.io();
|
||||
let pos = io.mouse_pos;
|
||||
let window_pos = ui.window_pos();
|
||||
let related_pos = [pos[0] - window_pos[0], pos[1] - window_pos[1]];
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
for (id, size) in need_resize.iter() {
|
||||
self.reset_window_size(id, *size);
|
||||
}
|
||||
}
|
||||
|
||||
// pub fn copy_window_resource(
|
||||
// &mut self,
|
||||
// src: &str,
|
||||
// dst: &str,
|
||||
// stick: bool,
|
||||
// ) -> Option<NativeTexture> {
|
||||
// let src = &ImString::new(src);
|
||||
// let window_info = self.windows.get(src).unwrap();
|
||||
|
||||
// let new_texture = if stick {
|
||||
// let new_framebuffer_tex = self.create_framebuffer(dst, (300, 300)).unwrap();
|
||||
// unsafe {
|
||||
// self.gl
|
||||
// .bind_framebuffer(glow::READ_FRAMEBUFFER, window_info.framebuffer);
|
||||
// self.gl
|
||||
// .bind_framebuffer(glow::DRAW_FRAMEBUFFER, Some(self.framebuffers[dst].0));
|
||||
// self.gl.blit_framebuffer(
|
||||
// 0,
|
||||
// 0,
|
||||
// 300,
|
||||
// 300,
|
||||
// 0,
|
||||
// 0,
|
||||
// 300,
|
||||
// 300,
|
||||
// glow::COLOR_BUFFER_BIT,
|
||||
// glow::NEAREST,
|
||||
// );
|
||||
// self.gl.bind_framebuffer(glow::READ_FRAMEBUFFER, None);
|
||||
// self.gl.bind_framebuffer(glow::DRAW_FRAMEBUFFER, None);
|
||||
// }
|
||||
|
||||
// self.framebuffers
|
||||
// .get_mut(dst)
|
||||
// .map(|(_, redraw, program, atta)| {
|
||||
// *atta = new_framebuffer.as_ref().map(|v| v.3.clone()).flatten();
|
||||
// *redraw = true;
|
||||
// *program = new_framebuffer.as_ref().map(|v| v.2).unwrap();
|
||||
// });
|
||||
|
||||
// Some(new_framebuffer_tex)
|
||||
// } else {
|
||||
// let texture = self.frametextures.get(src).map(|texture| *texture);
|
||||
// if let Some(ref framebuffer) = new_framebuffer {
|
||||
// if let Some(ref texture) = texture {
|
||||
// self.all_framebuffers_add(&framebuffer.0);
|
||||
// self.all_frametextures_add(&texture);
|
||||
// self.framebuffers
|
||||
// .insert(ImString::new(dst), framebuffer.clone());
|
||||
// self.frametextures
|
||||
// .insert(ImString::new(dst), texture.clone());
|
||||
// }
|
||||
// }
|
||||
// texture
|
||||
// };
|
||||
|
||||
// new_framebuffer.map(|framebuffer| {
|
||||
// new_texture.map(|_| {
|
||||
// self.all_vaos_add(&framebuffer.3.as_ref().unwrap().vao);
|
||||
// self.all_other_buffers_add(&framebuffer.3.as_ref().unwrap().vbo);
|
||||
// framebuffer.3.as_ref().unwrap().ebo.map(|ebo| {
|
||||
// self.all_other_buffers_add(&ebo);
|
||||
// });
|
||||
|
||||
// self.program_with_window.get_mut(&framebuffer.2).map(|v| {
|
||||
// v.push(ImString::new(dst));
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
|
||||
// new_texture
|
||||
// }
|
||||
pub fn create_render_window(&mut self, title: &str, size: [f32; 2]) -> Result<()> {
|
||||
// Insert the window data into the windows hashmap
|
||||
let id = ImString::new(title);
|
||||
let mut data = WindowData::new(id.clone(), size);
|
||||
let (fb, tex) =
|
||||
self.create_framebuffer(title, (size[0].floor() as i32, size[1].floor() as i32))?;
|
||||
|
||||
data.framebuffer = Some(fb);
|
||||
data.frametexture = Some(tex);
|
||||
self.windows.insert(id, data);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn set_config(&mut self, id: &str) -> Option<&mut Config> {
|
||||
let id = &ImString::new(id);
|
||||
self.windows
|
||||
.get_mut(id)
|
||||
.map(|v| {
|
||||
v.re_init = true;
|
||||
v.config.as_mut()
|
||||
})
|
||||
.flatten()
|
||||
}
|
||||
|
||||
fn reset_window_size(&mut self, id: &ImString, size: [f32; 2]) {
|
||||
let window_info = self.windows.get_mut(id).unwrap();
|
||||
window_info.need_redraw = true;
|
||||
let tex = unsafe {
|
||||
self.gl
|
||||
.bind_framebuffer(glow::FRAMEBUFFER, window_info.framebuffer);
|
||||
let texture = self.gl.create_texture().unwrap();
|
||||
self.gl.bind_texture(glow::TEXTURE_2D, Some(texture));
|
||||
self.gl.tex_image_2d(
|
||||
glow::TEXTURE_2D,
|
||||
0,
|
||||
glow::RGB8 as i32,
|
||||
size[0].floor() as i32,
|
||||
size[1].floor() as i32,
|
||||
0,
|
||||
glow::RGB,
|
||||
glow::UNSIGNED_BYTE,
|
||||
None,
|
||||
);
|
||||
self.gl.tex_parameter_i32(
|
||||
glow::TEXTURE_2D,
|
||||
glow::TEXTURE_MIN_FILTER,
|
||||
glow::LINEAR as i32,
|
||||
);
|
||||
self.gl.tex_parameter_i32(
|
||||
glow::TEXTURE_2D,
|
||||
glow::TEXTURE_MAG_FILTER,
|
||||
glow::LINEAR as i32,
|
||||
);
|
||||
|
||||
self.gl.framebuffer_texture_2d(
|
||||
glow::FRAMEBUFFER,
|
||||
glow::COLOR_ATTACHMENT0,
|
||||
glow::TEXTURE_2D,
|
||||
Some(texture),
|
||||
0,
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
self.gl.check_framebuffer_status(glow::FRAMEBUFFER),
|
||||
glow::FRAMEBUFFER_COMPLETE
|
||||
);
|
||||
|
||||
self.gl.bind_framebuffer(glow::FRAMEBUFFER, None);
|
||||
self.gl.bind_texture(glow::TEXTURE_2D, None);
|
||||
|
||||
texture
|
||||
};
|
||||
let raw_tex = window_info.frametexture.as_ref().unwrap().to_owned();
|
||||
self.all_frametextures_minus(&raw_tex);
|
||||
self.all_frametextures_add(&tex);
|
||||
}
|
||||
|
||||
pub fn destroy_window(&mut self) {
|
||||
let ids: Vec<_> = self
|
||||
.windows
|
||||
.iter()
|
||||
.filter(|v| v.1.open == false)
|
||||
.map(|v| v.0.clone())
|
||||
.collect();
|
||||
|
||||
for id in ids.iter() {
|
||||
let window = self.windows.remove(id).unwrap();
|
||||
|
||||
window.framebuffer.map(|framebuffer| {
|
||||
self.all_framebuffers_minus(&framebuffer);
|
||||
});
|
||||
|
||||
window.frametexture.map(|texture| {
|
||||
self.all_frametextures_minus(&texture);
|
||||
});
|
||||
|
||||
if let Some(atta) = window.attach {
|
||||
self.all_vaos_minus(&atta.vao);
|
||||
self.all_other_buffers_minus(&atta.vbo);
|
||||
atta.ebo.map(|ebo| {
|
||||
self.all_other_buffers_minus(&ebo);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn clean(&mut self) {
|
||||
info!("Cleaning up unused resources");
|
||||
unsafe {
|
||||
self.all_framebuffers
|
||||
.iter()
|
||||
.filter(|v| *v.1 == 0)
|
||||
.for_each(|(bf, _)| {
|
||||
info!("Deleting framebuffer: {:?}", bf);
|
||||
self.gl.delete_framebuffer(*bf);
|
||||
});
|
||||
|
||||
self.all_frametextures
|
||||
.iter()
|
||||
.filter(|v| *v.1 == 0)
|
||||
.for_each(|(bf, _)| {
|
||||
info!("Deleting texture: {:?}", bf);
|
||||
self.gl.delete_texture(*bf);
|
||||
});
|
||||
|
||||
self.all_vaos
|
||||
.iter()
|
||||
.filter(|v| *v.1 == 0)
|
||||
.for_each(|(bf, _)| {
|
||||
info!("Deleting vao: {:?}", bf);
|
||||
self.gl.delete_vertex_array(*bf);
|
||||
});
|
||||
|
||||
self.all_other_buffers
|
||||
.iter()
|
||||
.filter(|v| *v.1 == 0)
|
||||
.for_each(|(bf, _)| {
|
||||
info!("Deleting buffer: {:?}", bf);
|
||||
self.gl.delete_buffer(*bf);
|
||||
});
|
||||
}
|
||||
self.all_framebuffers.retain(|_, v| *v > 0);
|
||||
self.all_frametextures.retain(|_, v| *v > 0);
|
||||
self.all_vaos.retain(|_, v| *v > 0);
|
||||
self.all_other_buffers.retain(|_, v| *v > 0);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Attach {
|
||||
pub vao: NativeVertexArray,
|
||||
pub vbo: NativeBuffer,
|
||||
pub ebo: Option<NativeBuffer>,
|
||||
pub len: i32,
|
||||
}
|
||||
|
||||
pub struct State {}
|
||||
|
||||
pub struct WindowData {
|
||||
pub title: ImString,
|
||||
pub open: bool,
|
||||
pub copy_from: Option<ImString>,
|
||||
pub size: [f32; 2],
|
||||
framebuffer: Option<NativeFramebuffer>,
|
||||
frametexture: Option<NativeTexture>,
|
||||
need_redraw: bool,
|
||||
program: usize,
|
||||
attach: Option<Attach>,
|
||||
|
||||
re_init: bool,
|
||||
last_mouse_position: [f32; 2],
|
||||
last_mouse_delta: [f32; 2],
|
||||
accmulate_mouse_delta: [f32; 2],
|
||||
mouse_position: [f32; 2],
|
||||
motion: Option<MouseState>,
|
||||
config: Option<Config>,
|
||||
}
|
||||
|
||||
impl WindowData {
|
||||
pub fn new(title: ImString, size: [f32; 2]) -> Self {
|
||||
Self {
|
||||
title,
|
||||
open: true,
|
||||
copy_from: None,
|
||||
size,
|
||||
last_mouse_position: [0.0, 0.0],
|
||||
last_mouse_delta: [0.0, 0.0],
|
||||
accmulate_mouse_delta: [0.0, 0.0],
|
||||
mouse_position: [0.0, 0.0],
|
||||
motion: None,
|
||||
|
||||
framebuffer: None,
|
||||
frametexture: None,
|
||||
need_redraw: false,
|
||||
program: 0,
|
||||
attach: None,
|
||||
re_init: false,
|
||||
config: None,
|
||||
}
|
||||
}
|
||||
|
||||
fn set_current_mouse_delta(&mut self, delta: [f32; 2]) {
|
||||
self.last_mouse_delta = delta;
|
||||
self.accmulate_mouse_delta = [
|
||||
self.accmulate_mouse_delta[0] + delta[0],
|
||||
self.accmulate_mouse_delta[1] + delta[1],
|
||||
];
|
||||
}
|
||||
|
||||
fn set_mouse_postion(&mut self, pos: [f32; 2]) {
|
||||
self.mouse_position = pos;
|
||||
}
|
||||
}
|
||||
215
src/support/_s.rs
Normal file
215
src/support/_s.rs
Normal file
@ -0,0 +1,215 @@
|
||||
use std::num::NonZeroU32;
|
||||
|
||||
use glow::HasContext;
|
||||
use glutin::{
|
||||
config::ConfigTemplateBuilder,
|
||||
context::{ContextApi, ContextAttributesBuilder, NotCurrentGlContext, PossiblyCurrentContext},
|
||||
display::{GetGlDisplay, GlDisplay},
|
||||
surface::{GlSurface, Surface, SurfaceAttributesBuilder, SwapInterval, WindowSurface},
|
||||
};
|
||||
use imgui_winit_support::WinitPlatform;
|
||||
use raw_window_handle::HasRawWindowHandle;
|
||||
use winit::{
|
||||
dpi::LogicalSize,
|
||||
event_loop::EventLoop,
|
||||
window::{Window, WindowBuilder},
|
||||
};
|
||||
|
||||
pub fn create_window(
|
||||
title: &str,
|
||||
context_api: Option<ContextApi>,
|
||||
) -> (
|
||||
EventLoop<()>,
|
||||
Window,
|
||||
Surface<WindowSurface>,
|
||||
PossiblyCurrentContext,
|
||||
) {
|
||||
let event_loop = EventLoop::new().unwrap();
|
||||
|
||||
let window_builder = WindowBuilder::new()
|
||||
.with_title(title)
|
||||
.with_inner_size(LogicalSize::new(1024, 768));
|
||||
let (window, cfg) = glutin_winit::DisplayBuilder::new()
|
||||
.with_window_builder(Some(window_builder))
|
||||
.build(&event_loop, ConfigTemplateBuilder::new(), |mut configs| {
|
||||
configs.next().unwrap()
|
||||
})
|
||||
.expect("Failed to create OpenGL window");
|
||||
|
||||
let window = window.unwrap();
|
||||
|
||||
let mut context_attribs = ContextAttributesBuilder::new();
|
||||
if let Some(context_api) = context_api {
|
||||
context_attribs = context_attribs.with_context_api(context_api);
|
||||
}
|
||||
let context_attribs = context_attribs.build(Some(window.raw_window_handle()));
|
||||
let context = unsafe {
|
||||
cfg.display()
|
||||
.create_context(&cfg, &context_attribs)
|
||||
.expect("Failed to create OpenGL context")
|
||||
};
|
||||
|
||||
let surface_attribs = SurfaceAttributesBuilder::<WindowSurface>::new()
|
||||
.with_srgb(Some(true))
|
||||
.build(
|
||||
window.raw_window_handle(),
|
||||
NonZeroU32::new(1024).unwrap(),
|
||||
NonZeroU32::new(768).unwrap(),
|
||||
);
|
||||
let surface = unsafe {
|
||||
cfg.display()
|
||||
.create_window_surface(&cfg, &surface_attribs)
|
||||
.expect("Failed to create OpenGL surface")
|
||||
};
|
||||
|
||||
let context = context
|
||||
.make_current(&surface)
|
||||
.expect("Failed to make OpenGL context current");
|
||||
|
||||
surface
|
||||
.set_swap_interval(&context, SwapInterval::Wait(NonZeroU32::new(1).unwrap()))
|
||||
.expect("Failed to set swap interval");
|
||||
|
||||
(event_loop, window, surface, context)
|
||||
}
|
||||
|
||||
pub fn glow_context(context: &PossiblyCurrentContext) -> glow::Context {
|
||||
unsafe {
|
||||
glow::Context::from_loader_function_cstr(|s| context.display().get_proc_address(s).cast())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn imgui_init(window: &Window) -> (WinitPlatform, imgui::Context) {
|
||||
let mut imgui_context = imgui::Context::create();
|
||||
imgui_context.set_ini_filename(None);
|
||||
|
||||
let mut winit_platform = WinitPlatform::init(&mut imgui_context);
|
||||
winit_platform.attach_window(
|
||||
imgui_context.io_mut(),
|
||||
window,
|
||||
imgui_winit_support::HiDpiMode::Rounded,
|
||||
);
|
||||
|
||||
imgui_context
|
||||
.fonts()
|
||||
.add_font(&[imgui::FontSource::DefaultFontData { config: None }]);
|
||||
|
||||
imgui_context.io_mut().font_global_scale = (1.0 / winit_platform.hidpi_factor()) as f32;
|
||||
|
||||
(winit_platform, imgui_context)
|
||||
}
|
||||
|
||||
pub struct Triangler {
|
||||
pub program: <glow::Context as HasContext>::Program,
|
||||
pub vertex_array: <glow::Context as HasContext>::VertexArray,
|
||||
}
|
||||
|
||||
impl Triangler {
|
||||
pub fn new(gl: &glow::Context, shader_header: &str) -> Self {
|
||||
const VERTEX_SHADER_SOURCE: &str = r#"
|
||||
const vec2 verts[3] = vec2[3](
|
||||
vec2(0.5f, 1.0f),
|
||||
vec2(0.0f, 0.0f),
|
||||
vec2(1.0f, 0.0f)
|
||||
);
|
||||
|
||||
out vec2 vert;
|
||||
out vec4 color;
|
||||
|
||||
vec4 srgb_to_linear(vec4 srgb_color) {
|
||||
// Calcuation as documented by OpenGL
|
||||
vec3 srgb = srgb_color.rgb;
|
||||
vec3 selector = ceil(srgb - 0.04045);
|
||||
vec3 less_than_branch = srgb / 12.92;
|
||||
vec3 greater_than_branch = pow((srgb + 0.055) / 1.055, vec3(2.4));
|
||||
return vec4(
|
||||
mix(less_than_branch, greater_than_branch, selector),
|
||||
srgb_color.a
|
||||
);
|
||||
}
|
||||
|
||||
void main() {
|
||||
vert = verts[gl_VertexID];
|
||||
color = srgb_to_linear(vec4(vert, 0.5, 1.0));
|
||||
gl_Position = vec4(vert - 0.5, 0.0, 1.0);
|
||||
}
|
||||
"#;
|
||||
const FRAGMENT_SHADER_SOURCE: &str = r#"
|
||||
in vec2 vert;
|
||||
in vec4 color;
|
||||
|
||||
out vec4 frag_color;
|
||||
|
||||
vec4 linear_to_srgb(vec4 linear_color) {
|
||||
vec3 linear = linear_color.rgb;
|
||||
vec3 selector = ceil(linear - 0.0031308);
|
||||
vec3 less_than_branch = linear * 12.92;
|
||||
vec3 greater_than_branch = pow(linear, vec3(1.0/2.4)) * 1.055 - 0.055;
|
||||
return vec4(
|
||||
mix(less_than_branch, greater_than_branch, selector),
|
||||
linear_color.a
|
||||
);
|
||||
}
|
||||
|
||||
void main() {
|
||||
frag_color = linear_to_srgb(color);
|
||||
}
|
||||
"#;
|
||||
|
||||
let mut shaders = [
|
||||
(glow::VERTEX_SHADER, VERTEX_SHADER_SOURCE, None),
|
||||
(glow::FRAGMENT_SHADER, FRAGMENT_SHADER_SOURCE, None),
|
||||
];
|
||||
|
||||
unsafe {
|
||||
let vertex_array = gl
|
||||
.create_vertex_array()
|
||||
.expect("Cannot create vertex array");
|
||||
|
||||
let program = gl.create_program().expect("Cannot create program");
|
||||
|
||||
for (kind, source, handle) in &mut shaders {
|
||||
let shader = gl.create_shader(*kind).expect("Cannot create shader");
|
||||
gl.shader_source(shader, &format!("{}\n{}", shader_header, *source));
|
||||
gl.compile_shader(shader);
|
||||
if !gl.get_shader_compile_status(shader) {
|
||||
panic!("{}", gl.get_shader_info_log(shader));
|
||||
}
|
||||
gl.attach_shader(program, shader);
|
||||
*handle = Some(shader);
|
||||
}
|
||||
|
||||
gl.link_program(program);
|
||||
if !gl.get_program_link_status(program) {
|
||||
panic!("{}", gl.get_program_info_log(program));
|
||||
}
|
||||
|
||||
for &(_, _, shader) in &shaders {
|
||||
gl.detach_shader(program, shader.unwrap());
|
||||
gl.delete_shader(shader.unwrap());
|
||||
}
|
||||
|
||||
Self {
|
||||
program,
|
||||
vertex_array,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn render(&self, gl: &glow::Context) {
|
||||
unsafe {
|
||||
gl.clear_color(0.05, 0.05, 0.1, 1.0);
|
||||
gl.clear(glow::COLOR_BUFFER_BIT);
|
||||
gl.use_program(Some(self.program));
|
||||
gl.bind_vertex_array(Some(self.vertex_array));
|
||||
gl.draw_arrays(glow::TRIANGLES, 0, 3);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn destroy(&self, gl: &glow::Context) {
|
||||
unsafe {
|
||||
gl.delete_program(self.program);
|
||||
gl.delete_vertex_array(self.vertex_array);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,8 +1,4 @@
|
||||
use crate::camera::Camera;
|
||||
use crate::graphics::colormap::linear::LinearColormap;
|
||||
use crate::graphics::ppi::PPI;
|
||||
use crate::graphics::transforms::{position, ChainedTransform};
|
||||
use crate::graphics::{hello, AttaWithBuffer, AttaWithProgram, Graphics};
|
||||
use crate::pg::App;
|
||||
use crate::{
|
||||
graphics::{
|
||||
collections::agg_fast_path::AggFastPath,
|
||||
@ -12,7 +8,6 @@ use crate::{
|
||||
},
|
||||
utils::Triangler,
|
||||
};
|
||||
use cgmath::InnerSpace;
|
||||
use glow::HasContext;
|
||||
use glutin::{
|
||||
config::ConfigTemplateBuilder,
|
||||
@ -32,35 +27,35 @@ use imgui_winit_support::{
|
||||
use nalgebra_glm::perspective;
|
||||
use nalgebra_glm::Vec3;
|
||||
use raw_window_handle::HasRawWindowHandle;
|
||||
use std::cell::RefCell;
|
||||
use std::num::NonZeroU32;
|
||||
use std::rc::Rc;
|
||||
use std::time::Instant;
|
||||
|
||||
pub fn init<FUi>(mut run_ui: FUi, mut register: Vec<Rc<RefCell<dyn Graphics>>>)
|
||||
pub fn run<F>(mut app: F)
|
||||
where
|
||||
FUi: FnMut(&mut bool, &mut Ui, &Window, &glow::Context) + 'static,
|
||||
F: for<'b> FnMut(&'b glow::Context) -> App<'b>,
|
||||
{
|
||||
// Create Window
|
||||
let (event_loop, window, surface, context) = create_window();
|
||||
let (mut winit_platform, mut imgui_context) = imgui_init(&window);
|
||||
|
||||
let gl = unsafe {
|
||||
let gl = glow_context(&context);
|
||||
gl.enable(glow::DEPTH_TEST);
|
||||
gl.enable(glow::BLEND);
|
||||
gl.blend_func(glow::SRC_ALPHA, glow::ONE_MINUS_SRC_ALPHA);
|
||||
gl
|
||||
};
|
||||
// OpenGL context
|
||||
let gl = glow_context(&context);
|
||||
|
||||
// OpenGL renderer from this crate
|
||||
let mut ig_renderer = imgui_glow_renderer::AutoRenderer::initialize(gl, &mut imgui_context)
|
||||
.expect("failed to create renderer");
|
||||
|
||||
let gl_app = ig_renderer.gl_context().clone();
|
||||
let gl_context = ig_renderer.gl_context().clone();
|
||||
|
||||
for r in register.iter_mut() {
|
||||
r.borrow_mut().compile(&gl_context).unwrap();
|
||||
}
|
||||
|
||||
// let mut run = true;
|
||||
let mut app = app(&gl_app);
|
||||
|
||||
let mut run = true;
|
||||
|
||||
// Prepare
|
||||
app.prepare();
|
||||
|
||||
let mut last_frame = Instant::now();
|
||||
|
||||
event_loop
|
||||
@ -86,32 +81,15 @@ where
|
||||
} => {
|
||||
// Render your custom scene, note we need to borrow the OpenGL
|
||||
// context from the `AutoRenderer`, which takes ownership of it.
|
||||
|
||||
unsafe {
|
||||
gl_context.clear(glow::DEPTH_BUFFER_BIT);
|
||||
gl_context.clear(glow::COLOR_BUFFER_BIT);
|
||||
gl_context.clear(glow::COLOR_BUFFER_BIT | glow::DEPTH_BUFFER_BIT);
|
||||
}
|
||||
|
||||
app.render();
|
||||
let ui = imgui_context.frame();
|
||||
app.render_ui(&ui, &window, &mut run);
|
||||
|
||||
if ui.is_mouse_pos_valid(ui.io().mouse_pos) {
|
||||
let mouse_pos = ui.io().mouse_pos;
|
||||
if ui.is_mouse_dragging(imgui::MouseButton::Right) {
|
||||
}
|
||||
}
|
||||
|
||||
for r in register.iter_mut() {
|
||||
r.borrow_mut().draw(&gl_context).unwrap();
|
||||
}
|
||||
|
||||
let mut run = true;
|
||||
|
||||
run_ui(&mut run, ui, &window, ig_renderer.gl_context());
|
||||
|
||||
if !run {
|
||||
window_target.exit();
|
||||
}
|
||||
|
||||
winit_platform.prepare_render(ui, &window);
|
||||
let draw_data = imgui_context.render();
|
||||
|
||||
// Render imgui on top of it
|
||||
@ -140,16 +118,11 @@ where
|
||||
NonZeroU32::new(new_size.width).unwrap(),
|
||||
NonZeroU32::new(new_size.height).unwrap(),
|
||||
);
|
||||
|
||||
}
|
||||
winit_platform.handle_event(imgui_context.io_mut(), &window, &event);
|
||||
}
|
||||
winit::event::Event::LoopExiting => {
|
||||
|
||||
for r in register.iter_mut() {
|
||||
r.borrow_mut().destroy(&gl_context).unwrap();
|
||||
}
|
||||
|
||||
app.destroy();
|
||||
}
|
||||
event => {
|
||||
winit_platform.handle_event(imgui_context.io_mut(), &window, &event);
|
||||
@ -159,51 +132,6 @@ where
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
fn mouse_callback(
|
||||
last_position: &mut Option<PhysicalPosition<f64>>,
|
||||
current_position: PhysicalPosition<f64>,
|
||||
sensitivity: f64,
|
||||
pitch: &mut f64,
|
||||
yaw: &mut f64,
|
||||
camera: &mut Camera,
|
||||
) {
|
||||
use cgmath::{Deg, Euler, Quaternion};
|
||||
|
||||
let xpos = current_position.x;
|
||||
let ypos = current_position.y;
|
||||
|
||||
if last_position.is_none() {
|
||||
*last_position = Some(PhysicalPosition::new(xpos, ypos));
|
||||
}
|
||||
|
||||
let _last_position = last_position.unwrap();
|
||||
|
||||
let mut xoffset = xpos - _last_position.x;
|
||||
let mut yoffset = _last_position.y - ypos; // reversed since y-coordinates go from bottom to top
|
||||
|
||||
*last_position = Some(PhysicalPosition::new(xpos, ypos));
|
||||
|
||||
xoffset *= sensitivity;
|
||||
yoffset *= sensitivity;
|
||||
|
||||
*yaw += xoffset;
|
||||
*pitch += yoffset;
|
||||
|
||||
if *pitch > 89.0 {
|
||||
*pitch = 89.0;
|
||||
}
|
||||
|
||||
if *pitch < -89.0 {
|
||||
*pitch = -89.0;
|
||||
}
|
||||
|
||||
let euler_deg = Euler::new(Deg(*pitch), Deg(*yaw), Deg(0.0));
|
||||
|
||||
let c = Quaternion::from(euler_deg).normalize();
|
||||
|
||||
camera.set_front(Vec3::new(c.v.x as f32, c.v.y as f32, c.v.z as f32));
|
||||
}
|
||||
|
||||
fn create_window() -> (
|
||||
EventLoop<()>,
|
||||
Window,
|
||||
|
||||
44
src/ui.rs
Normal file
44
src/ui.rs
Normal file
@ -0,0 +1,44 @@
|
||||
use crate::errors::*;
|
||||
use crate::graphics::Config;
|
||||
use crate::pg::App;
|
||||
use crate::{data_loader::Data, pg::WindowData};
|
||||
use glow::NativeTexture;
|
||||
use imgui::{ImString, Ui};
|
||||
|
||||
pub fn base(ui: &Ui, window: &winit::window::Window, run: &mut bool, app: &mut App) {
|
||||
ui.window("test")
|
||||
.size([300.0, 200.0], imgui::Condition::FirstUseEver)
|
||||
.build(|| {
|
||||
if ui.button("PPI") {
|
||||
let data =
|
||||
load_data(r#"/Users/tsuki/Desktop/ZJSXAA_20230113070200_R.dat.gz"#).unwrap();
|
||||
app.create_render_window("ppi", [300.0, 300.0]).unwrap();
|
||||
app.create_ppi_render("ppi", None);
|
||||
app.bind_data("ppi", &data).unwrap();
|
||||
|
||||
let (rdpi, adpi, _) = {
|
||||
let ppi = app.ppi_module.borrow_mut();
|
||||
ppi.data_info(&data).unwrap()
|
||||
};
|
||||
|
||||
app.set_config("ppi").map(|config| {
|
||||
if let Config::PPI(config) = config {
|
||||
config.rdpi = rdpi;
|
||||
config.adpi = adpi;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
app.show_window(ui);
|
||||
app.destroy_window();
|
||||
}
|
||||
|
||||
fn create_display_window(title: &str, size: [f32; 2], copy_from: Option<ImString>) -> WindowData {
|
||||
WindowData::new(ImString::new(title), size)
|
||||
}
|
||||
|
||||
fn load_data(path: impl AsRef<std::path::Path>) -> Result<Data> {
|
||||
let data = Data::from_path(path)?;
|
||||
Ok(data)
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user