Mercurial > touhou
diff examples/stdrenderer.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/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 - } - } -}