Mercurial > touhou
diff examples/eclrenderer.rs @ 706:bca515da9047
examples: use common module.
author | Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> |
---|---|
date | Fri, 23 Aug 2019 19:46:47 +0200 |
parents | b6c351ca0a35 |
children | 987409d48991 |
line wrap: on
line diff
--- a/examples/eclrenderer.rs +++ b/examples/eclrenderer.rs @@ -1,12 +1,12 @@ -use image::GenericImageView; +use luminance::blending::{Equation, Factor}; use luminance::context::GraphicsContext; use luminance::framebuffer::Framebuffer; use luminance::pipeline::BoundTexture; -use luminance::pixel::{NormRGB8UI, Floating}; +use luminance::pixel::Floating; use luminance::render_state::RenderState; use luminance::shader::program::{Program, Uniform}; use luminance::tess::{Mode, TessBuilder}; -use luminance::texture::{Dim2, Flat, Sampler, Texture, GenMipmaps}; +use luminance::texture::{Dim2, Flat}; use luminance_derive::{Semantics, Vertex, UniformInterface}; use luminance_glfw::event::{Action, Key, WindowEvent}; use luminance_glfw::surface::{GlfwSurface, Surface, WindowDim, WindowOpt}; @@ -18,12 +18,14 @@ use touhou::th06::enemy::{Enemy, Game, P use touhou::util::math::{perspective, setup_camera}; use touhou::util::prng::Prng; use std::cell::RefCell; -use std::fs::File; -use std::io::{BufReader, Read}; use std::rc::Rc; use std::env; use std::path::Path; +#[path = "common.rs"] +mod common; +use common::{load_file_into_vec, load_anm_image, LoadedTexture}; + const VS: &str = r#" in ivec3 in_position; in vec2 in_texcoord; @@ -88,26 +90,17 @@ struct ShaderInterface { mvp: Uniform<[[f32; 4]; 4]>, } -fn load_file_into_vec(filename: &str) -> Vec<u8> { - let file = File::open(filename).unwrap(); - let mut file = BufReader::new(file); - let mut buf = vec![]; - file.read_to_end(&mut buf).unwrap(); - buf -} - fn main() { // Parse arguments. let args: Vec<_> = env::args().collect(); - if args.len() != 6 { - eprintln!("Usage: {} <ECL file> <ANM file> <PNG file> <easy|normal|hard|lunatic> <sub number>", args[0]); + if args.len() != 5 { + eprintln!("Usage: {} <ECL file> <ANM file> <easy|normal|hard|lunatic> <sub number>", args[0]); return; } - let ecl_filename = &args[1]; - let anm_filename = &args[2]; - let png_filename = &args[3]; - let rank: Rank = args[4].parse().expect("rank"); - let sub: u16 = args[5].parse().expect("number"); + let ecl_filename = Path::new(&args[1]); + let anm_filename = Path::new(&args[2]); + let rank: Rank = args[3].parse().expect("rank"); + let sub: u16 = args[4].parse().expect("number"); // Open the ECL file. let buf = load_file_into_vec(ecl_filename); @@ -142,7 +135,7 @@ fn main() { let mut surface = GlfwSurface::new(WindowDim::Windowed(384, 448), "Touhou", WindowOpt::default()).unwrap(); // Open the image atlas matching this ANM. - let tex = load_from_disk(&mut surface, Path::new(png_filename)).expect("texture loading"); + let tex = load_anm_image(&mut surface, &anm0.borrow(), anm_filename); // set the uniform interface to our type so that we can read textures from the shader let (program, _) = @@ -195,7 +188,10 @@ fn main() { .pipeline_builder() .pipeline(&back_buffer, [0., 0., 0., 0.], |pipeline, shd_gate| { // bind our fancy texture to the GPU: it gives us a bound texture we can use with the shader - let bound_tex = pipeline.bind_texture(&tex); + let bound_tex = match &tex { + LoadedTexture::Rgb(tex) => pipeline.bind_texture(tex), + LoadedTexture::Rgba(tex) => pipeline.bind_texture(tex), + }; shd_gate.shade(&program, |rdr_gate, iface| { // update the texture; strictly speaking, this update doesn’t do much: it just tells the GPU @@ -209,7 +205,10 @@ fn main() { // TODO: check how to pass by reference. iface.mvp.update(*mvp.borrow_inner()); - rdr_gate.render(RenderState::default(), |tess_gate| { + let render_state = RenderState::default() + .set_blending((Equation::Additive, Factor::SrcAlpha, Factor::SrcAlphaComplement)); + + rdr_gate.render(render_state, |tess_gate| { // render the tessellation to the surface the regular way and let the vertex shader’s // magic do the rest! tess_gate.render(&mut surface, (&tess).into()); @@ -228,32 +227,3 @@ fn fill_vertices_ptr(sprites: Vec<(f32, sprite.fill_vertices(&mut fake_vertices, x, y, z); } } - -fn load_from_disk(surface: &mut GlfwSurface, path: &Path) -> Option<Texture<Flat, Dim2, NormRGB8UI>> { - // load the texture into memory as a whole bloc (i.e. no streaming) - match image::open(&path) { - Ok(img) => { - let (width, height) = img.dimensions(); - let texels = img - .pixels() - .map(|(x, y, rgb)| (rgb[0], rgb[1], rgb[2])) - .collect::<Vec<_>>(); - - // create the luminance texture; the third argument is the number of mipmaps we want (leave it - // to 0 for now) and the latest is a the sampler to use when sampling the texels in the - // shader (we’ll just use the default one) - let tex = - Texture::new(surface, [width, height], 0, &Sampler::default()).expect("luminance texture creation"); - - // the first argument disables mipmap generation (we don’t care so far) - tex.upload(GenMipmaps::No, &texels); - - Some(tex) - } - - Err(e) => { - eprintln!("cannot open image {}: {}", path.display(), e); - None - } - } -}