Added some code for shader compile/link, rendered a quad
authorEleni Maria Stea <estea@igalia.com>
Fri, 30 Aug 2019 07:48:13 +0000 (10:48 +0300)
committerEleni Maria Stea <estea@igalia.com>
Wed, 4 Sep 2019 16:17:12 +0000 (19:17 +0300)
Cargo.toml
src/main.rs

index ced8622..97473f8 100644 (file)
@@ -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"
index a2c00e9..6718096 100644 (file)
 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<u8> = 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<u8> = 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::<GLfloat>()) 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);
     }
 }