Move a triangle around your screen with Rust OpenGL ft. Glium, Glutin
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[package] | |
name = "rust-opengl" | |
version = "0.1.0" | |
edition = "2021" | |
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | |
[dependencies] | |
glium = "*" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#[macro_use] | |
#[allow(unused_imports)] | |
extern crate glium; | |
fn main() { | |
use glium::glutin; | |
use glium::Surface; | |
use std::time::{SystemTime, UNIX_EPOCH}; | |
// let time_in_ms = || { | |
// let start = SystemTime::now(); | |
// let since_the_epoch = start | |
// .duration_since(UNIX_EPOCH) | |
// .expect("time went backwards"); | |
// let in_ms = | |
// since_the_epoch.as_secs() * 1000 + since_the_epoch.subsec_nanos() as u64 / 1_000_000; | |
// in_ms | |
// }; | |
// let time_in_secs = || { | |
// let start = SystemTime::now(); | |
// let since_the_epoch = start | |
// .duration_since(UNIX_EPOCH) | |
// .expect("time went backwards"); | |
// let in_secs = since_the_epoch.as_secs(); | |
// in_secs | |
// }; | |
// Creating an EventLoop for handling window and device events. | |
let event_loop = glutin::event_loop::EventLoop::new(); | |
// Specify Window parameters using glium::glutin::WindowBuilder::new(). These are window-specific attributes that have nothing to do with OpenGL. | |
let wb = glutin::window::WindowBuilder::new(); | |
// Specify Context parameters using glium::glutin::ContextBuilder::new(). Here we specify OpenGL-specific attributes like multisampling or vsync. | |
let cb = glutin::ContextBuilder::new(); | |
// Create the OpenGL window (in glium, this is the Display): glium::Display::new(window, context, &event_loop).unwrap(). This builds a Display using the given window and context attributes, and registers the window with the given event_loop. | |
let display = glium::Display::new(wb, cb, &event_loop).unwrap(); | |
// window to capture events | |
let width = display.gl_window().window().inner_size().width as f32; | |
let height = display.gl_window().window().inner_size().height as f32; | |
println!("{} {}", width, height); | |
let gl_cords = move |x: f32, y: f32| { | |
// f((x,y))=(x−12,−(y−6)), | |
// struct Coords<f32> { | |
// x: x - (x / 2.0), | |
// y: -(y - (y / 2.0)), | |
// }; | |
struct Coords<f32> { | |
x: f32, | |
y: f32, | |
} | |
Coords { | |
x: x - (width / 2.0), | |
y: -(y - (height / 2.0)), | |
} | |
}; | |
#[derive(Copy, Clone)] | |
struct Vertex { | |
position: [f32; 2], | |
} | |
implement_vertex!(Vertex, position); | |
let vertex1 = Vertex { | |
position: [-0.5, -0.5], | |
}; | |
let vertex2 = Vertex { | |
position: [0.0, 0.5], | |
}; | |
let vertex3 = Vertex { | |
position: [0.5, -0.25], | |
}; | |
let shape = vec![vertex1, vertex2, vertex3]; | |
let vertex_buffer = glium::VertexBuffer::new(&display, &shape).unwrap(); | |
let indices = glium::index::NoIndices(glium::index::PrimitiveType::TrianglesList); | |
let mut x: f32 = 0.0; | |
let mut y: f32 = 0.0; | |
// let mut fps: i32 = 0; | |
let vertex_shader_src = r#" | |
#version 140 | |
in vec2 position; | |
uniform float y; | |
uniform float x; | |
void main() { | |
vec2 pos = position; | |
pos.x += x; | |
pos.y += y; | |
gl_Position = vec4(pos, 0.0, 1.0); | |
} | |
"#; | |
let fragment_shader_src = r#" | |
#version 140 | |
out vec4 color; | |
void main() { | |
color = vec4(1.0, 0.0, 0.0, 1.0); | |
} | |
"#; | |
let program = | |
glium::Program::from_source(&display, vertex_shader_src, fragment_shader_src, None) | |
.unwrap(); | |
#[allow(unused_mut)] | |
// let mut prev_time: f64 = 0.0; | |
// let mut current_time: f64 = 0.0; | |
// let mut time_diff: f64 = 0.0; | |
// let mut fps = 0; | |
// loop forever until we detect that a CloseRequested event has been received | |
event_loop.run(move |event, _, control_flow| { | |
let next_frame_time = | |
std::time::Instant::now() + std::time::Duration::from_nanos(16_666_667); | |
*control_flow = glutin::event_loop::ControlFlow::WaitUntil(next_frame_time); | |
// detect exit | |
match event { | |
glutin::event::Event::WindowEvent { event, .. } => match event { | |
glutin::event::WindowEvent::CloseRequested => { | |
*control_flow = glutin::event_loop::ControlFlow::Exit; | |
return; | |
} | |
glutin::event::WindowEvent::CursorMoved { position, .. } => { | |
println!("{:?}", position); | |
// x = gl_cords(position.x as f32, position.y as f32).x; | |
// y = gl_cords(position.x as f32, position.y as f32).y; | |
// println!("{:?}", (x, y)); | |
} | |
glutin::event::WindowEvent::KeyboardInput { | |
device_id, | |
input, | |
is_synthetic, | |
} => { | |
if input.state == glutin::event::ElementState::Pressed { | |
if input.virtual_keycode == Some(glutin::event::VirtualKeyCode::Up) { | |
y += 0.05; | |
} else if input.virtual_keycode == Some(glutin::event::VirtualKeyCode::Left) | |
{ | |
x -= 0.05; | |
} else if input.virtual_keycode | |
== Some(glutin::event::VirtualKeyCode::Right) | |
{ | |
x += 0.05; | |
} else if input.virtual_keycode == Some(glutin::event::VirtualKeyCode::Down) | |
{ | |
y -= 0.05; | |
} | |
} | |
} | |
_ => return, | |
}, | |
_ => (), | |
} | |
// current_time = time_in_secs() as f64; | |
// time_diff = current_time - prev_time; | |
// fps = fps + 1; | |
// if (time_diff >= 1.0 / 30.0) { | |
// let frames_string = format!("{}", ((1.0 / time_diff) * fps as f64)); | |
// // println!("{}", frames_string); | |
// } | |
// double buffering, clearing canvas | |
let mut target = display.draw(); | |
target.clear_color(1.0, 0.0, 1.0, 1.0); | |
// draw the freakin triangle | |
target | |
.draw( | |
&vertex_buffer, | |
&indices, | |
&program, | |
&uniform! { x: x, y: y }, | |
&Default::default(), | |
) | |
.unwrap(); | |
// destroy frame | |
target.finish().unwrap(); | |
}) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment