Basic OpenGL

This commit is contained in:
numzero 2024-09-22 15:11:08 +03:00
parent 98fbf892bc
commit 6012c480de
5 changed files with 1084 additions and 19 deletions

936
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -21,6 +21,8 @@ show-image = "0.14.0"
flo_draw = "0.3.1" flo_draw = "0.3.1"
flo_canvas = "0.3.1" flo_canvas = "0.3.1"
itertools-num = "0.1.3" itertools-num = "0.1.3"
glium = "0.35.0"
winit = "0.30.5"
[dev-dependencies] [dev-dependencies]
approx = "0.5.1" approx = "0.5.1"

143
src/bin/wireframe/main.rs Normal file
View File

@ -0,0 +1,143 @@
use glam::{mat4, vec2, vec3, vec4, Mat4, Vec3};
use glium::{
backend::glutin::SimpleWindowBuilder,
implement_vertex, uniform,
winit::event::{Event, WindowEvent},
Program, Surface, VertexBuffer,
};
use winit::event_loop::EventLoop;
#[derive(Copy, Clone)]
struct Vertex {
position: [f32; 3],
}
implement_vertex!(Vertex, position);
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., 2.],
},
Vertex {
position: [0., -1., 2.],
},
Vertex {
position: [1., 0., 2.],
},
Vertex {
position: [0., 1., 2.],
},
];
let vertex_buffer = VertexBuffer::new(&display, &shape).unwrap();
let mut t: f32 = -0.5;
#[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));
t += 0.02;
let x = t.sin() * 0.5;
let mdl = mat4(
vec4(1., 0., 0., 0.),
vec4(0., 1., 0., 0.),
vec4(0., 0., 1., 0.),
vec4(x, 0., 0., 1.),
);
let mut target = display.draw();
target.clear_color(0.0, 0.0, 0.2, 1.0);
let mvp = proj * mdl;
let uniforms = uniform! {
mvp: mvp.to_cols_array_2d(),
};
target
.draw(
&vertex_buffer,
&indices,
&program,
&uniforms,
&Default::default(),
)
.unwrap();
target.finish().unwrap();
}
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);
}
}

View File

@ -0,0 +1,9 @@
#version 330
in vec3 vertex_color;
out vec4 color;
void main() {
color = vec4(vertex_color, 1.0);
}

View File

@ -0,0 +1,13 @@
#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);
}