From 2c11bc7d05bd2bebb40b52cb473d5a2335f007e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Manuel=20Tom=C3=A1s?= Date: Sun, 17 Jan 2021 09:34:40 -0300 Subject: Render using opengl --- src/main.rs | 123 ++++++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 95 insertions(+), 28 deletions(-) (limited to 'src') diff --git a/src/main.rs b/src/main.rs index 7424f7a..aa149e3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,12 +7,32 @@ use number::Number; use std::thread; use std::time::Duration; +use std::os::raw::c_void; +use std::ffi::{CString, CStr}; use sdl2::event::Event; use sdl2::keyboard::Keycode; use sdl2::pixels::Color; use sdl2::rect::Rect; +use gl::types::*; + +fn shader_from_source(source: &CStr, shader_type: GLenum) -> GLuint { + unsafe { + let shader: GLuint = gl::CreateShader(shader_type); + gl::ShaderSource(shader, 1, &source.as_ptr(), std::ptr::null()); + gl::CompileShader(shader); + let mut success: gl::types::GLint = 1; + unsafe { + gl::GetShaderiv(shader, gl::COMPILE_STATUS, &mut success); + } + if success == 0 { + println!("Compilation error: {}", source.to_str().unwrap()); + } + shader + } +} + fn main() { let a = Lerp::new(vec![2.0, -2.0, 2.0]); let b = Lerp::new(vec![-1.0, 1.0, 2.0]); @@ -23,18 +43,84 @@ fn main() { let sdl_context = sdl2::init().unwrap(); let video_subsystem = sdl_context.video().unwrap(); + let gl_attr = video_subsystem.gl_attr(); + + gl_attr.set_context_profile(sdl2::video::GLProfile::Core); + gl_attr.set_context_version(4, 1); + + let window_w: u32 = 800; + let window_h: u32 = 600; + let window = video_subsystem - .window("rust-sdl2 demo", 800, 600) + .window("bezier", window_w, window_h) .position_centered() + .opengl() .build() .unwrap(); - let mut canvas = window.into_canvas().build().unwrap(); + let gl_context = window.gl_create_context().unwrap(); + + gl::load_with(|s| video_subsystem.gl_get_proc_address(s) as *const std::os::raw::c_void); + + unsafe { + gl::Viewport(0, 0, window_w as i32, window_h as i32); + } + + let vertices: [f32; 18] = [ + // first triangle + 1.0, 1.0, 0.0, + 1.0, -1.0, 0.0, + -1.0, 1.0, 0.0, + // // second triangle + 1.0, -1.0, 0.0, + -1.0, -1.0, 0.0, + -1.0, 1.0, 0.0 + ]; + + let vertex_shader_source = b" + #version 410 core + layout (location = 0) in vec3 aPos; + + void main() { + gl_Position = vec4(aPos.xyz, 1.0); + } + ".to_vec(); + + let fragment_shader_source = b" + #version 410 core + out vec4 FragColor; + + void main() { + FragColor = vec4(0.4, 0.8, 0.2, 1.0); + } + ".to_vec(); + + let mut vbo: GLuint = 0; + let mut vao: GLuint = 0; + unsafe { + gl::GenVertexArrays(1, &mut vao); + gl::BindVertexArray(vao); + gl::GenBuffers(1, &mut vbo); + gl::BindBuffer(gl::ARRAY_BUFFER, vbo); + gl::BufferData(gl::ARRAY_BUFFER, (vertices.len() * std::mem::size_of::()) as GLsizeiptr, vertices.as_ptr() as *const GLvoid, gl::STATIC_DRAW); + gl::VertexAttribPointer(0, 3, gl::FLOAT, gl::FALSE, (3 * std::mem::size_of::()) as GLint, std::ptr::null()); + gl::EnableVertexAttribArray(0); + } + + let mut shader_program: GLuint = 0; + unsafe { + let vertex_shader = shader_from_source(&CString::from_vec_unchecked(vertex_shader_source), gl::VERTEX_SHADER); + let fragment_shader = shader_from_source(&CString::from_vec_unchecked(fragment_shader_source), gl::FRAGMENT_SHADER); + shader_program = gl::CreateProgram(); + gl::AttachShader(shader_program, vertex_shader); + gl::AttachShader(shader_program, fragment_shader); + gl::LinkProgram(shader_program); + gl::DeleteShader(vertex_shader); + gl::DeleteShader(fragment_shader); + } let mut event_pump = sdl_context.event_pump().unwrap(); 'running: loop { - canvas.set_draw_color(Color::RGB(20, 20, 20)); - canvas.clear(); for event in event_pump.poll_iter() { match event { Event::Quit { .. } @@ -46,31 +132,12 @@ fn main() { } } - let s = -600.0 / 10.0; - let k = 600.0 / 2.0; - for t in -800..800 { - let x = k + s * pa.eval(t as Number / 100.0); - let y = k + s * pb.eval(t as Number / 100.0); - let z = k + s * p.eval(t as Number / 100.0); - canvas.set_draw_color(Color::RGB(180, 20, 20)); - canvas - .fill_rect(Rect::new(400 + t, x as i32, 5, 5)) - .unwrap(); - canvas.set_draw_color(Color::RGB(20, 180, 20)); - canvas - .fill_rect(Rect::new(400 + t, y as i32, 5, 5)) - .unwrap(); - canvas.set_draw_color(Color::RGB(20, 20, 180)); - canvas - .fill_rect(Rect::new(400 + t, z as i32, 2, 2)) - .unwrap(); - canvas.set_draw_color(Color::RGB(255, 0, 0)); - canvas - .fill_rect(Rect::new(400 + t, k as i32, 2, 2)) - .unwrap(); + unsafe { + gl::Clear(gl::COLOR_BUFFER_BIT); + gl::UseProgram(shader_program); + gl::DrawArrays(gl::TRIANGLES, 0, 6); } - canvas.present(); - thread::sleep(Duration::new(0, 1_000_000_000u32 / 60)); + window.gl_swap_window(); } } -- cgit v1.2.3