Rust-SDL2 / rust-sdl2

SDL2 bindings for Rust
MIT License
2.78k stars 475 forks source link

Question multiple textures and alpha channel #750

Open Schr3da opened 6 years ago

Schr3da commented 6 years ago

Hi,

Im currently workin on a game in web assembly by using rust and sdl. The game consists of several textures/layers and I would like to draw one layer over the other using alpha value. Its kind of a strategy game so I try to implement kind of a darker layer on top of my map with some "light radius". However Im facing some sisues which I dont know how to resolve properly.

Thats my current main render loop and Im exclusivly using features of the crates.io documentation, with no features at all.

Quesiton 1: Is this a proper way how to use the api to archieve multiple layers? Question 2: How can I set a transparent area for the clear color (currently my single render_light method is just drawing over the map without alpha values even when I use BlendMode::Blend before I start clearing/drawing the texture

pub fn run() {
    let sdl_context = sdl2::init().unwrap();
    let font_context = sdl2::ttf::init().unwrap();

    let mut keyboard_controlls = KeyboardControls::new(&sdl_context);
    let screen_rect = window::get_canvas_frame();

    let mut font_manager = FontManager::new(&font_context);
    load_all_fonts(&mut font_manager);

    let mut canvas = get_canvas(sdl_context);
    let texture_creator = canvas.texture_creator();

    let mut game = Game::new();
    game.init();

    let (width, height) = game.get_map_size();
    let mut map_rect = get_map_frame(width, height);
    let mut map_texture = create_map_texture(&texture_creator, width, height).unwrap();
    canvas.with_texture_canvas(&mut map_texture, |map_texture| render_map(&game, map_texture)).unwrap();

    let mut light_texture = create_light_texture(&texture_creator).unwrap();
    canvas.with_texture_canvas(&mut light_texture, |light_texture| render_light(&game, light_texture)).unwrap();

    let layers = vec![
        (&mut map_texture, layers::MAP),
        (&mut light_texture, layers::LIGHT)
    ];

    renderer(|is_init_done| {

        if is_init_done && !update(&mut keyboard_controlls) {
            thread::sleep(window::get_fps());
            return true;
        }

        canvas.clear();

        canvas.with_multiple_texture_canvas(layers.iter(), |texture, name| {
            match *name {
                layers::LIGHT => render_light(&game, texture),
                _ => {}
            }
        }).unwrap();

        for &(ref layer, name) in layers.iter(){
            match name {
                layers::LIGHT => canvas.copy(layer, None, Rect::new(0, 0, 100, 100)
                ).unwrap(),
                layers::MAP => canvas.copy(layer,
                    input::utils::get_render_rect_for_keyboard(&keyboard_controlls, &mut map_rect,  &screen_rect),
                    window::get_canvas_frame(),
                ).unwrap(),
                _ => {}
            }
        }

        canvas.present();
        thread::sleep(window::get_fps());
        return true;

Thanks,

Cobrand commented 6 years ago

Question 1: There is not "exact" way, only "recommended" ways :) It looks like you render everything on the "light" layer and then everything on the "map" layer, then draw the map and the light. If you want to have graphic layers, this is indeed a very good way to proceed.

Question 2: I don't really get what you want to say, is your issue that you can't set a transparent color to the Clear color? Or is it something else entirely? If you have very specific SDL2 questions (which are not rust-related), I would recommend trying the official SDL2 help, meaning their forum, their IRC, ... My knowledge of SDL2 is average at best, someone is surely much more knowledgeable than me about that.

PS: if you manage to have something working in wasm, I would love to have a look at it to include them in a tutorial or some examples :) ! People are really interested into building games for wasm and SDL2, and unfortunately I haven't had the time to look into it.

Schr3da commented 6 years ago

Thanks for the quick response, I'm working on my blog as well as soon as I have something more major working I will share my link. Im planning to do a devlog as well - will keep you updated!

In addition I will move my source code to github as well 2-3 weeks something more major should be there! Just as a note the wasm version is working but I would like to finish the light layer first than everything looks more major

Schr3da commented 6 years ago

Hey,

I just launched my web page which will contain upcoming devlogs related to the Rust + Wasm and SDL topic (http://hackertron.eu/). A current wasm build can be found under http://hackertron.eu/build/ You can use arrow keys to navigate and a,s keys to zoom in/out (I'm aware of a scaling bug)

Please note that the loading requires some time. Therefore please ignore any warnings...

regards, Schr3da

Cobrand commented 6 years ago

@Schr3da Very cool! Please keep us up to date, I'm sure the rust community will be very interested!

It doesn't work on my FF though, it says that SDL textures cannot be over 8192x8192. It works on my chromium after a few tries (made the tab hang several times), but when it finally worked, boy was it fluid! Very exciting to see!

Schr3da commented 6 years ago

Hey,

Thanks for the quick reply; I just pushed the latest version on my dev side (http://hackertron.eu/build/) It should work now much better

kind regards schreda

Schr3da commented 6 years ago

Hey, I just published the instruction about how to setup the webassembly build for my current project. In addition the source code is now available on github (https://github.com/Schr3da/hackertron-eu-wasm-game-project) ...

regards Schr3da