From: Eleni Maria Stea Date: Sun, 15 Sep 2019 12:06:05 +0000 (+0300) Subject: working draft X-Git-Url: https://eleni.mutantstargoat.com/git/?a=commitdiff_plain;h=HEAD;p=rust_hw working draft --- diff --git a/Cargo.toml b/Cargo.toml index 97473f8..69c1c82 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,3 +12,6 @@ version = "0.10.0" [dependencies.sdl2] version = "0.32.2" features = ["bundled", "static-link"] + +[dependencies.image] +version = "0.22.2" diff --git a/src/main.rs b/src/main.rs index 6718096..e88a368 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,18 +1,13 @@ extern crate sdl2; extern crate gl; +extern crate image; use sdl2::video::GLProfile; use gl::types::*; - -use std; - -/*enum Vattr { - VATTR_VERTEX, - VATTR_TEXCOORD -}*/ +use image::GenericImageView; static WIN_W : u32 = 800; -static WIN_H : u32 = 600; +static WIN_H : u32 = 800; static VERTEX_DATA : [GLfloat; 12] = [ -0.5, -0.5, @@ -24,23 +19,37 @@ static VERTEX_DATA : [GLfloat; 12] = [ -0.5, 0.5 ]; +static TEX_DATA : [GLfloat; 12] = [ + 0.0, 1.0, + 1.0, 1.0, + 1.0, 0.0, + + 0.0, 1.0, + 1.0, 0.0, + 0.0, 0.0 +]; + static NUM_VERTICES : GLint = 6; static VERTEX_LOC : u32 = 0; - -let tex : u32 = 0; +static TEX_LOC : u32 = 1; static VS : &'static str = "#version 130\n\ - attribute vec4 pos;\n\ + in vec4 pos;\n\ + in vec2 in_tex_coord;\n\ + out vec2 tex_coord;\n\ void main() {\n\ gl_Position = pos;\n\ + tex_coord = in_tex_coord;\n\ }"; static FS : &'static str = "#version 130\n\ + uniform sampler2D tex;\n\ + in vec2 tex_coord;\n\ out vec4 color;\n\ void main() {\n\ - color = vec4(0.0, 0.5, 0.8, 1.0);\n\ + color = texture2D(tex, tex_coord);\n\ }"; fn compile_sdr(src: &str, stage:GLenum) -> GLuint { @@ -99,7 +108,27 @@ fn link_sdr_prog(vs: GLuint, fs: GLuint) -> GLuint { } } +fn gen_tex(fname : String, _id : &mut GLuint) { + let img : image::DynamicImage = image::open(&std::path::Path::new(&fname)).ok().expect("Can't open image.\n"); + let (_w, _h) = img.dimensions(); + + unsafe { + gl::GenTextures(1, _id); + gl::BindTexture(gl::TEXTURE_2D, *_id); + gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_WRAP_S, gl::REPEAT as i32); + gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_WRAP_T, gl::REPEAT as i32); + gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MIN_FILTER, gl::LINEAR as i32); + gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MAG_FILTER, gl::LINEAR as i32); + gl::TexImage2D(gl::TEXTURE_2D, 0, gl::RGBA as i32, + _w as i32, _h as i32, 0, + gl::RGBA, gl::UNSIGNED_BYTE, + img.to_rgba().into_raw().as_ptr() as *const std::ffi::c_void); + gl::BindTexture(gl::TEXTURE_2D, 0); + } +} + fn main() { + //TODO FIXME init let sdl_ctx = sdl2::init().unwrap(); let vid_sys = sdl_ctx.video().unwrap(); let gl_attr = vid_sys.gl_attr(); @@ -117,33 +146,47 @@ fn main() { let _gl = gl::load_with(|s| vid_sys.gl_get_proc_address(s) as *const std::os::raw::c_void); - let mut vao = 0; - let mut vbo = 0; + let mut vao = 1; + let mut vbo_pos = 1; + let mut vbo_tex = 2; + let sprog; - let mut sprog; let fs; let vs; + let mut tex_igalia : GLuint = 1; + let mut tex_guadec : GLuint = 2; + let mut tex_sel = tex_igalia; + + let mut uloc_stex : GLint = -1; + + gen_tex("data/igalia.png".to_string(), &mut tex_igalia); + gen_tex("data/guadec.png".to_string(), &mut tex_guadec); + unsafe { - gl::ClearColor(0.3, 0.1, 0.1, 1.0); + gl::ClearColor(0.0, 0.0, 0.0, 1.0); + gl::Enable(gl::BLEND); + gl::BlendFunc(gl::SRC_ALPHA, gl::ONE_MINUS_SRC_ALPHA); gl::GenVertexArrays(1, &mut vao); gl::BindVertexArray(vao); - gl::GenBuffers(1, &mut vbo); - gl::BindBuffer(gl::ARRAY_BUFFER, vbo); + gl::GenBuffers(1, &mut vbo_pos); + gl::BindBuffer(gl::ARRAY_BUFFER, vbo_pos); 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); + gl::GenBuffers(1, &mut vbo_tex); + gl::BindBuffer(gl::ARRAY_BUFFER, vbo_tex); + gl::BufferData(gl::ARRAY_BUFFER, (TEX_DATA.len() * std::mem::size_of::()) as GLsizeiptr, + std::mem::transmute(&TEX_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); } @@ -157,31 +200,59 @@ fn main() { sdl2::event::Event::KeyDown {keycode: Some(sdl2::keyboard::Keycode::Escape), ..} => break 'main, + sdl2::event::Event::KeyDown {keycode: + Some(sdl2::keyboard::Keycode::I), ..} => + tex_sel = tex_igalia, + sdl2::event::Event::KeyDown {keycode: + Some(sdl2::keyboard::Keycode::G), ..} => + tex_sel = tex_guadec, _ => {}, } } + //TODO FIXME: display unsafe { + let uni_str = std::ffi::CString::new("tex").unwrap(); + uloc_stex = gl::GetUniformLocation(sprog, uni_str.as_ptr()); + if uloc_stex > -1 { + gl::Uniform1i(uloc_stex, tex_sel as i32); + } + gl::Clear(gl::COLOR_BUFFER_BIT); gl::Viewport(0, 0, WIN_W as i32, WIN_H as i32); + /* pos */ gl::EnableVertexAttribArray(VERTEX_LOC); - gl::BindBuffer(gl::ARRAY_BUFFER, vbo); + gl::BindBuffer(gl::ARRAY_BUFFER, vbo_pos); gl::VertexAttribPointer(VERTEX_LOC, 2, gl::FLOAT, gl::FALSE, 0 as i32, std::ptr::null()); + /* tex coords */ + gl::EnableVertexAttribArray(TEX_LOC); + gl::BindBuffer(gl::ARRAY_BUFFER, vbo_tex); + gl::VertexAttribPointer(TEX_LOC, 2, + gl::FLOAT, gl::FALSE, + 0 as i32, std::ptr::null()); + + gl::ActiveTexture(gl::TEXTURE0 + tex_sel); + gl::BindTexture(gl::TEXTURE_2D, tex_sel); + gl::DrawArrays(gl::TRIANGLES, 0, NUM_VERTICES); } win.gl_swap_window(); } + //TODO FIXME: cleanup unsafe { gl::DeleteProgram(sprog); gl::DeleteShader(vs); gl::DeleteShader(fs); - gl::DeleteBuffers(1, &vbo); + gl::DeleteBuffers(1, &vbo_pos); + gl::DeleteBuffers(1, &vbo_tex); gl::DeleteVertexArrays(1, &vao); + gl::DeleteTextures(1, &tex_igalia); + gl::DeleteTextures(1, &tex_guadec); } }