Skip to content

Instantly share code, notes, and snippets.

@khalby786
Last active May 20, 2022
Embed
What would you like to do?
Move a triangle around your screen with Rust OpenGL ft. Glium, Glutin
[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 = "*"
#[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