Compare commits
No commits in common. "a40ba662093b87c606eeda2ae20ac98854937c6b" and "98fbf892bcb138a712c78b4b4673ff5091bcb51d" have entirely different histories.
a40ba66209
...
98fbf892bc
|
|
@ -1,18 +0,0 @@
|
|||
{
|
||||
"Auto_generated": "This file is auto-generated. Any extra tags or formatting will be lost",
|
||||
"target_sets": [
|
||||
{
|
||||
"cmake_config": "",
|
||||
"directory": "%B",
|
||||
"loaded_via_cmake": false,
|
||||
"name": "Cargo",
|
||||
"targets": [
|
||||
{
|
||||
"build_cmd": "cargo build --bin wireframe",
|
||||
"name": "wireframe",
|
||||
"run_cmd": "cargo run --bin wireframe"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
936
Cargo.lock
generated
936
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
|
|
@ -21,8 +21,6 @@ show-image = "0.14.0"
|
|||
flo_draw = "0.3.1"
|
||||
flo_canvas = "0.3.1"
|
||||
itertools-num = "0.1.3"
|
||||
glium = "0.35.0"
|
||||
winit = "0.30.5"
|
||||
|
||||
[dev-dependencies]
|
||||
approx = "0.5.1"
|
||||
|
|
|
|||
|
|
@ -1,200 +0,0 @@
|
|||
use glam::{mat4, vec2, vec3, vec4, Mat4, Quat, Vec2, Vec3};
|
||||
use glium::{
|
||||
backend::glutin::SimpleWindowBuilder,
|
||||
implement_vertex, uniform,
|
||||
winit::event::{Event, WindowEvent},
|
||||
Program, Surface, VertexBuffer,
|
||||
};
|
||||
use winit::{event::ElementState, event_loop::EventLoop};
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
struct Vertex {
|
||||
position: [f32; 3],
|
||||
}
|
||||
implement_vertex!(Vertex, position);
|
||||
|
||||
struct DragCtl<S> {
|
||||
state: S,
|
||||
ctl: Option<(Vec2, S)>,
|
||||
}
|
||||
|
||||
impl<S: Copy> DragCtl<S> {
|
||||
pub fn new(state: S) -> Self {
|
||||
Self { state, ctl: None }
|
||||
}
|
||||
|
||||
pub fn state(&self) -> S {
|
||||
self.state
|
||||
}
|
||||
|
||||
pub fn on_button(&mut self, pos: Vec2, state: ElementState) {
|
||||
match state {
|
||||
ElementState::Pressed => {
|
||||
assert!(self.ctl.is_none());
|
||||
self.ctl = Some((pos, self.state));
|
||||
}
|
||||
ElementState::Released => {
|
||||
assert!(self.ctl.is_some());
|
||||
self.ctl = None;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn on_move(&mut self, pos: Vec2, f: impl FnOnce(S, Vec2) -> S) {
|
||||
if let Some((old_pos, old_state)) = self.ctl {
|
||||
self.state = f(old_state, pos - old_pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let event_loop = EventLoop::builder().build().unwrap();
|
||||
let (window, display) = SimpleWindowBuilder::new()
|
||||
.with_title("Refraction: Wireframe")
|
||||
.build(&event_loop);
|
||||
|
||||
let vs_src = include_str!("ray.v.glsl");
|
||||
let fs_src = include_str!("ray.f.glsl");
|
||||
let program = Program::from_source(&display, vs_src, fs_src, None).unwrap();
|
||||
|
||||
let indices = glium::index::NoIndices(glium::index::PrimitiveType::LineLoop);
|
||||
let shape = vec![
|
||||
Vertex {
|
||||
position: [-1., 0., 4.],
|
||||
},
|
||||
Vertex {
|
||||
position: [0., -1., 4.],
|
||||
},
|
||||
Vertex {
|
||||
position: [1., 0., 4.],
|
||||
},
|
||||
Vertex {
|
||||
position: [0., 1., 4.],
|
||||
},
|
||||
];
|
||||
let vertex_buffer = VertexBuffer::new(&display, &shape).unwrap();
|
||||
|
||||
let mut cur_pos = vec2(0., 0.);
|
||||
let mut cam_pos = DragCtl::new(Vec3::ZERO);
|
||||
let mut cam_rot = DragCtl::new(Quat::IDENTITY);
|
||||
|
||||
#[allow(deprecated)]
|
||||
event_loop
|
||||
.run(move |ev, window_target| match ev {
|
||||
Event::WindowEvent { event, .. } => match event {
|
||||
WindowEvent::RedrawRequested => {
|
||||
let size = window.inner_size();
|
||||
let size = vec2(size.width as f32, size.height as f32).normalize()
|
||||
* std::f32::consts::SQRT_2;
|
||||
let proj = make_proj_matrix(vec3(size.x, size.y, 2.), (0.125, 1024.125));
|
||||
|
||||
let view =
|
||||
Mat4::from_quat(cam_rot.state()) * Mat4::from_translation(cam_pos.state());
|
||||
|
||||
let mut target = display.draw();
|
||||
target.clear_color(0.0, 0.0, 0.2, 1.0);
|
||||
|
||||
let mvp = proj * view;
|
||||
let uniforms = uniform! {
|
||||
mvp: mvp.to_cols_array_2d(),
|
||||
};
|
||||
|
||||
target
|
||||
.draw(
|
||||
&vertex_buffer,
|
||||
&indices,
|
||||
&program,
|
||||
&uniforms,
|
||||
&Default::default(),
|
||||
)
|
||||
.unwrap();
|
||||
target.finish().unwrap();
|
||||
}
|
||||
|
||||
WindowEvent::MouseInput {
|
||||
device_id: _,
|
||||
state,
|
||||
button,
|
||||
} => match button {
|
||||
winit::event::MouseButton::Left => cam_pos.on_button(cur_pos, state),
|
||||
winit::event::MouseButton::Right => cam_rot.on_button(cur_pos, state),
|
||||
_ => {}
|
||||
},
|
||||
|
||||
WindowEvent::CursorMoved {
|
||||
device_id: _,
|
||||
position,
|
||||
} => {
|
||||
let size = window.inner_size();
|
||||
let size = vec2(size.width as f32, size.height as f32);
|
||||
cur_pos = vec2(position.x as f32, position.y as f32) / size.length();
|
||||
cam_pos.on_move(cur_pos, |init, off| {
|
||||
window.request_redraw();
|
||||
init + 4. * (cam_rot.state().inverse() * vec3(off.x, -off.y, 0.))
|
||||
});
|
||||
cam_rot.on_move(cur_pos, |init, off| {
|
||||
window.request_redraw();
|
||||
Quat::from_euler(glam::EulerRot::YXZ, 5. * off.x, 5. * off.y, 0.) * init
|
||||
});
|
||||
}
|
||||
|
||||
WindowEvent::Resized(window_size) => {
|
||||
display.resize(window_size.into());
|
||||
}
|
||||
|
||||
WindowEvent::CloseRequested => {
|
||||
window_target.exit();
|
||||
}
|
||||
|
||||
_ => (),
|
||||
},
|
||||
|
||||
Event::AboutToWait => {
|
||||
window.request_redraw();
|
||||
}
|
||||
_ => (),
|
||||
})
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
/// Make a projection matrix, assuming input coordinates are (right, up, forward).
|
||||
///
|
||||
/// `corner` is a vector that will be mapped to (x=1, y=1) after the perspective division.
|
||||
/// `zrange` is the Z range that will be mapped to z∈[-1, 1]. It has no other effect. Both ends have to be positive though.
|
||||
fn make_proj_matrix(corner: Vec3, zrange: (f32, f32)) -> Mat4 {
|
||||
let scale = 1.0 / corner;
|
||||
let zspan = zrange.1 - zrange.0;
|
||||
mat4(
|
||||
scale.x * vec4(1., 0., 0., 0.),
|
||||
scale.y * vec4(0., 1., 0., 0.),
|
||||
scale.z * vec4(0., 0., (zrange.0 + zrange.1) / zspan, 1.),
|
||||
scale.z * vec4(0., 0., -2. * zrange.0 * zrange.1 / zspan, 0.),
|
||||
)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use approx::assert_abs_diff_eq;
|
||||
use glam::vec3;
|
||||
|
||||
#[test]
|
||||
fn test_proj_matrix() {
|
||||
let m = make_proj_matrix(vec3(2., 3., 4.), (0.5, 20.0));
|
||||
|
||||
let v = m * vec4(2., 3., 4., 1.);
|
||||
assert_abs_diff_eq!(v.x / v.w, 1.0);
|
||||
assert_abs_diff_eq!(v.y / v.w, 1.0);
|
||||
assert!(-v.w < v.z && v.z < v.w, "z out of range in {v}");
|
||||
|
||||
let v = m * vec4(2., 3., 0.5, 1.);
|
||||
assert_abs_diff_eq!(v.x / v.w, 8.0);
|
||||
assert_abs_diff_eq!(v.y / v.w, 8.0);
|
||||
assert_abs_diff_eq!(v.z / v.w, -1.0);
|
||||
|
||||
let v = m * vec4(2., 3., 20.0, 1.);
|
||||
assert_abs_diff_eq!(v.x / v.w, 0.2);
|
||||
assert_abs_diff_eq!(v.y / v.w, 0.2);
|
||||
assert_abs_diff_eq!(v.z / v.w, 1.0);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
#version 330
|
||||
|
||||
in vec3 vertex_color;
|
||||
|
||||
out vec4 color;
|
||||
|
||||
void main() {
|
||||
color = vec4(vertex_color, 1.0);
|
||||
}
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
#version 330
|
||||
|
||||
uniform mat4 mvp;
|
||||
uniform vec3 color;
|
||||
|
||||
in vec3 position;
|
||||
|
||||
out vec3 vertex_color;
|
||||
|
||||
void main() {
|
||||
vertex_color = color;
|
||||
gl_Position = mvp * vec4(position, 1.0);
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user