From: Eleni Maria Stea Date: Fri, 30 Aug 2019 07:48:13 +0000 (+0300) Subject: Added some code for shader compile/link, rendered a quad X-Git-Url: http://git.mutantstargoat.com?p=rust_hw;a=commitdiff_plain;h=71a577b9c4b3fc0b58ed2ec35748fa6d4f0473fd Added some code for shader compile/link, rendered a quad --- diff --git a/Cargo.toml b/Cargo.toml index ced8622..97473f8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,8 +6,8 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html -[dependencies] -gl = "0.10.0" +[dependencies.gl] +version = "0.10.0" [dependencies.sdl2] version = "0.32.2" diff --git a/src/main.rs b/src/main.rs index a2c00e9..6718096 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,39 +1,158 @@ extern crate sdl2; extern crate gl; -//use std::ffi::CString; -//pub mod draw; +use sdl2::video::GLProfile; +use gl::types::*; -static _WIN_W : u32 = 800; -static _WIN_H : u32 = 600; +use std; + +/*enum Vattr { + VATTR_VERTEX, + VATTR_TEXCOORD +}*/ + +static WIN_W : u32 = 800; +static WIN_H : u32 = 600; + +static VERTEX_DATA : [GLfloat; 12] = [ + -0.5, -0.5, + 0.5, -0.5, + 0.5, 0.5, + + -0.5, -0.5, + 0.5, 0.5, + -0.5, 0.5 +]; + +static NUM_VERTICES : GLint = 6; +static VERTEX_LOC : u32 = 0; + +let tex : u32 = 0; + +static VS : &'static str = +"#version 130\n\ + attribute vec4 pos;\n\ + void main() {\n\ + gl_Position = pos;\n\ + }"; + +static FS : &'static str = +"#version 130\n\ + out vec4 color;\n\ + void main() {\n\ + color = vec4(0.0, 0.5, 0.8, 1.0);\n\ + }"; + +fn compile_sdr(src: &str, stage:GLenum) -> GLuint { + let shader; + unsafe { + shader = gl::CreateShader(stage); + + let s = std::ffi::CString::new(src).expect("CString::new failed");; + + gl::ShaderSource(shader, 1, &s.as_ptr(), std::ptr::null()); + gl::CompileShader(shader); + // status + let mut status = gl::FALSE as GLint; + gl::GetShaderiv(shader, gl::COMPILE_STATUS, &mut status); + + // error handling + if status != (gl::TRUE as GLint) { + let mut len = 0; + gl::GetShaderiv(shader, gl::INFO_LOG_LENGTH, &mut len); + + let mut buf: Vec = Vec::with_capacity((len + 1) as usize); + buf.extend([b' '].iter().cycle().take(len as usize)); + let err: std::ffi::CString = std::ffi::CString::from_vec_unchecked(buf); + + gl::GetShaderInfoLog(shader, len, std::ptr::null_mut(), + err.as_ptr() as *mut GLchar); + println!("{}", err.to_str().unwrap()); + + } + } + shader +} + +fn link_sdr_prog(vs: GLuint, fs: GLuint) -> GLuint { + unsafe { + let sdr_prog = gl::CreateProgram(); + gl::AttachShader(sdr_prog, vs); + gl::AttachShader(sdr_prog, fs); + gl::LinkProgram(sdr_prog); + + let mut status = gl::FALSE as GLint; + gl::GetProgramiv(sdr_prog, gl::LINK_STATUS, &mut status); + if status != (gl::TRUE as GLint) { + let mut len: GLint = 0; + gl::GetProgramiv(sdr_prog, gl::INFO_LOG_LENGTH, &mut len); + + + let mut buf: Vec = Vec::with_capacity((len + 1) as usize); + buf.extend([b' '].iter().cycle().take(len as usize)); + let err: std::ffi::CString = std::ffi::CString::from_vec_unchecked(buf); + + gl::GetProgramInfoLog(sdr_prog, len, std::ptr::null_mut(), err.as_ptr() as *mut GLchar); + println!("{}", err.to_str().unwrap()); + } + sdr_prog + } +} fn main() { - let _sdl = sdl2::init().unwrap(); - let _video = _sdl.video().unwrap(); - let _win = _video - .window("foobar", _WIN_W, _WIN_H) + let sdl_ctx = sdl2::init().unwrap(); + let vid_sys = sdl_ctx.video().unwrap(); + let gl_attr = vid_sys.gl_attr(); + + gl_attr.set_context_profile(GLProfile::Core); + + let win = vid_sys + .window("foobar", WIN_W, WIN_H) .opengl() // add opengl flag .resizable() .build() .unwrap(); - let _gl_ctx = _win.gl_create_context().unwrap(); - let _gl = gl::load_with(|s| _video.gl_get_proc_address(s) as + let _gl_ctx = win.gl_create_context().unwrap(); + let _gl = gl::load_with(|s| vid_sys.gl_get_proc_address(s) as *const std::os::raw::c_void); -// let _vsdr = draw::Shader::load_vs_code(&CString::new(include_str!("data/quad.v.glsl").unwrap.unrap(); -// let _fsdr = draw::Shader::load_fs_code(&CString::new(include_str!("data/quad.f.glsl").unwrap.unrap(); -// let sdr_prog = draw::Program::from_shaders(&[vsdr, fsdr]).unwrap(); + let mut vao = 0; + let mut vbo = 0; + + let mut sprog; + let fs; + let vs; unsafe { gl::ClearColor(0.3, 0.1, 0.1, 1.0); + gl::GenVertexArrays(1, &mut vao); + gl::BindVertexArray(vao); + + gl::GenBuffers(1, &mut vbo); + gl::BindBuffer(gl::ARRAY_BUFFER, vbo); + gl::BufferData(gl::ARRAY_BUFFER, (VERTEX_DATA.len() * std::mem::size_of::()) as GLsizeiptr, + std::mem::transmute(&VERTEX_DATA[0]), + gl::STATIC_DRAW); + gl::BindBuffer(gl::ARRAY_BUFFER, 0); + + vs = compile_sdr(VS, gl::VERTEX_SHADER); + fs = compile_sdr(FS, gl::FRAGMENT_SHADER); + + sprog = link_sdr_prog(vs, fs); + let att_str = std::ffi::CString::new("position").unwrap(); + + gl::BindAttribLocation(sprog, VERTEX_LOC, att_str.as_ptr()); + sprog = link_sdr_prog(vs, fs); + + gl::UseProgram(sprog); } - let mut event_pump = _sdl.event_pump().unwrap(); + let mut event_pump = sdl_ctx.event_pump().unwrap(); 'main: loop { - for _event in event_pump.poll_iter() { + for event in event_pump.poll_iter() { // handle user input here - match _event { + match event { sdl2::event::Event::Quit {..} | sdl2::event::Event::KeyDown {keycode: Some(sdl2::keyboard::Keycode::Escape), ..} => @@ -44,9 +163,25 @@ fn main() { unsafe { gl::Clear(gl::COLOR_BUFFER_BIT); - gl::Viewport(0, 0, _WIN_W as i32, _WIN_H as i32); + gl::Viewport(0, 0, WIN_W as i32, WIN_H as i32); + + gl::EnableVertexAttribArray(VERTEX_LOC); + gl::BindBuffer(gl::ARRAY_BUFFER, vbo); + gl::VertexAttribPointer(VERTEX_LOC, 2, + gl::FLOAT, gl::FALSE, + 0 as i32, std::ptr::null()); + + gl::DrawArrays(gl::TRIANGLES, 0, NUM_VERTICES); } - _win.gl_swap_window(); + win.gl_swap_window(); + } + + unsafe { + gl::DeleteProgram(sprog); + gl::DeleteShader(vs); + gl::DeleteShader(fs); + gl::DeleteBuffers(1, &vbo); + gl::DeleteVertexArrays(1, &vao); } }