Mercurial > touhou
changeset 706:bca515da9047
examples: use common module.
author | Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> |
---|---|
date | Fri, 23 Aug 2019 19:46:47 +0200 |
parents | ed65f9412bc0 |
children | 987409d48991 |
files | examples/anmrenderer.rs examples/common.rs examples/eclrenderer.rs examples/stdrenderer.rs |
diffstat | 4 files changed, 62 insertions(+), 117 deletions(-) [+] |
line wrap: on
line diff
--- a/examples/anmrenderer.rs +++ b/examples/anmrenderer.rs @@ -21,8 +21,7 @@ use std::path::Path; #[path = "common.rs"] mod common; - -use common::{load_file_into_vec, load_rgb_png, load_rgb_a_pngs, LoadedTexture}; +use common::{load_file_into_vec, load_anm_image, LoadedTexture}; const VS: &str = r#" in ivec3 in_position; @@ -135,16 +134,7 @@ fn main() { let mut surface = GlfwSurface::new(WindowDim::Windowed(384, 448), "Touhou", WindowOpt::default()).unwrap(); // Open the image atlas matching this ANM. - let png_filename = anm_filename.with_file_name(Path::new(&anm0.png_filename).file_name().unwrap()); - let tex = match anm0.alpha_filename { - Some(ref filename) => { - let alpha_filename = anm_filename.with_file_name(Path::new(filename).file_name().unwrap()); - load_rgb_a_pngs(&mut surface, &png_filename, &alpha_filename).expect("texture loading") - }, - None => { - load_rgb_png(&mut surface, &png_filename).expect("texture loading") - } - }; + let tex = load_anm_image(&mut surface, &anm0, anm_filename); // set the uniform interface to our type so that we can read textures from the shader let (program, _) =
--- a/examples/common.rs +++ b/examples/common.rs @@ -2,6 +2,7 @@ use image::{GenericImageView, DynamicIma use luminance::pixel::{NormRGB8UI, NormRGBA8UI}; use luminance::texture::{Dim2, Flat, Sampler, Texture, GenMipmaps}; use luminance_glfw::surface::GlfwSurface; +use touhou::th06::anm0::Anm0; use std::fs::File; use std::io::{BufReader, Read}; use std::path::Path; @@ -19,7 +20,7 @@ pub enum LoadedTexture { Rgb(Texture<Flat, Dim2, NormRGB8UI>), } -pub fn load_rgb_png(surface: &mut GlfwSurface, path: &Path) -> Option<LoadedTexture> { +fn load_rgb_png(surface: &mut GlfwSurface, path: &Path) -> Option<LoadedTexture> { // load the texture into memory as a whole bloc (i.e. no streaming) match image::open(&path) { Ok(img) => { @@ -48,7 +49,7 @@ pub fn load_rgb_png(surface: &mut GlfwSu } } -pub fn load_rgb_a_pngs(surface: &mut GlfwSurface, rgb: &Path, alpha: &Path) -> Option<LoadedTexture> { +fn load_rgb_a_pngs(surface: &mut GlfwSurface, rgb: &Path, alpha: &Path) -> Option<LoadedTexture> { // load the texture into memory as a whole bloc (i.e. no streaming) match image::open(&alpha) { Ok(img) => { @@ -70,7 +71,7 @@ pub fn load_rgb_a_pngs(surface: &mut Glf let texels = img .pixels() .zip(alpha.pixels()) - .map(|((_x, _y, rgb), luma)| (rgb[0], rgb[1], rgb[1], luma[0])) + .map(|((_x, _y, rgb), luma)| (rgb[0], rgb[1], rgb[2], luma[0])) .collect::<Vec<_>>(); // create the luminance texture; the third argument is the number of mipmaps we want (leave it @@ -91,3 +92,17 @@ pub fn load_rgb_a_pngs(surface: &mut Glf } } } + +pub fn load_anm_image(mut surface: &mut GlfwSurface, anm0: &Anm0, anm_filename: &Path) -> LoadedTexture { + let png_filename = anm_filename.with_file_name(Path::new(&anm0.png_filename).file_name().unwrap()); + match anm0.alpha_filename { + Some(ref filename) => { + let alpha_filename = anm_filename.with_file_name(Path::new(filename).file_name().unwrap()); + println!("alpha {:?}", alpha_filename); + load_rgb_a_pngs(&mut surface, &png_filename, &alpha_filename).expect("texture loading") + }, + None => { + load_rgb_png(&mut surface, &png_filename).expect("texture loading") + } + } +}
--- 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 - } - } -}
--- a/examples/stdrenderer.rs +++ b/examples/stdrenderer.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, TessSliceIndex}; -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}; @@ -17,12 +17,14 @@ use touhou::th06::std_vm::StageRunner; use touhou::util::prng::Prng; use touhou::util::math::perspective; 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; @@ -107,24 +109,15 @@ struct ShaderInterface { fog_color: Uniform<[f32; 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() != 4 { - eprintln!("Usage: {} <STD file> <ANM file> <PNG file>", args[0]); + if args.len() != 3 { + eprintln!("Usage: {} <STD file> <ANM file>", args[0]); return; } - let std_filename = &args[1]; - let anm_filename = &args[2]; - let png_filename = &args[3]; + let std_filename = Path::new(&args[1]); + let anm_filename = Path::new(&args[2]); // Open the STD file. let buf = load_file_into_vec(std_filename); @@ -168,7 +161,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, anm_filename); // set the uniform interface to our type so that we can read textures from the shader let (program, _) = @@ -207,7 +200,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 @@ -226,11 +222,14 @@ fn main() { iface.fog_scale.update(1. / (far - near)); iface.fog_end.update(far); + let render_state = RenderState::default() + .set_blending((Equation::Additive, Factor::SrcAlpha, Factor::SrcAlphaComplement)); + let stage = stage_runner.stage.borrow(); for instance in stage.instances.iter() { iface.instance_position.update([instance.pos.x, instance.pos.y, instance.pos.z]); - rdr_gate.render(RenderState::default(), |tess_gate| { + rdr_gate.render(render_state, |tess_gate| { let (begin, end) = indices[instance.id as usize]; tess_gate.render(&mut surface, tess.slice(begin..end)); }); @@ -247,32 +246,3 @@ fn fill_vertices(sprite: Rc<RefCell<Spri let sprite = sprite.borrow(); 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 - } - } -}