GM:S 1.4 Draw a surface as big as a level room[SOLVED]

Discussion in 'Programming' started by Unknown Yell, Dec 6, 2018.

  1. Unknown Yell

    Unknown Yell Member

    Joined:
    Mar 2, 2018
    Posts:
    16
    Hello there.
    I'm making a Deadbolt clone to learn GML better.
    I'm stuck on the light engine. Deadbolt lightning is really simple, I think it uses a surface or a shader to color the whole level black and then it "carves" a hole as big as the room the lamp is put in. With room I actually mean the room built in the room editor with objects, not the whole level.
    Now, I need help on drawing the carved out surface, as I don't really know what to do, nor what to search on the internet.
     
  2. c023-DeV

    c023-DeV Member

    Joined:
    Nov 23, 2016
    Posts:
    49
    Better have the lighting surface only at ViewPort Resolution (what you see). Then you could fill it black and paint white 'lights' on it and use multiply blendmode to paint that surface on the rest (at the current cameras position). It's a bit of translating the light coordinates to the relative position of the smaller surface and back but it saves a lot of memory compared to room sized surfaces (depending on how large the rooms are). (2048x2048 px is the default texture page size btw)
     
  3. Unknown Yell

    Unknown Yell Member

    Joined:
    Mar 2, 2018
    Posts:
    16
    Thanks for the useful advice, I'll remember that, but it wasn't really my issue. My apologize, I wasn't really clear.
    What I am trying to is this:
    [​IMG]
    Light is contained in one room, and does not go trough the walls, but stops there.
    I need help to get the boundaries of the room.
     
  4. BattleRifle BR55

    BattleRifle BR55 Member

    Joined:
    Jun 24, 2016
    Posts:
    832
    Considering the walls are objects, just scan from the light source out in two directions until collisions are found. If the light hits a wall, start a new scan downwards until it finds the floor. Then, make a primitive out of these two-to-four points and cut that shape out of the surface. You could even do it backwards to this by starting from where the light hits the ground or wall on either side and make primitives out of the shadows instead to fill in the surface.
     
  5. mark rob

    mark rob Member

    Joined:
    Dec 7, 2018
    Posts:
    7
    It is hard to draw the surface big as level room.
     
  6. Unknown Yell

    Unknown Yell Member

    Joined:
    Mar 2, 2018
    Posts:
    16
    Thanks a lot, it worked.
    I've used Yellow After Life's script, and this one by Zack Bell Games.
    This is my code:
    Obj_surf_vfx uses the Zack Bell script, wich creates the dark surface. Then, I get the room's boundaries with YAL script. It is used inside obj_light create event:
    Code:
    x0 = scr_collision_line_point(x,y,-room_width,y,obj_wall,false,true);
    x1 = scr_collision_line_point(x,y,room_width,y,obj_wall,false,true);
    y0 = scr_collision_line_point(x,y,x,-room_height,obj_wall,false,true);
    y1 = scr_collision_line_point(x,y,x,room_height,obj_wall,false,true);
    
    Then, inside the step event I actually draw the light, using my script scr_light:
    Code:
    //get the target object and the color;
    var obj = argument[0];
    var col = argument[1];
    if (surface_exists(obj_surf_vfx.surf_light)) {
        surface_set_target(obj_surf_vfx.surf_light);
    
        // set blend mode to subtract
        draw_set_blend_mode(bm_subtract);
        draw_set_color(col);
      
        //draw the light rectangle
        with (obj)
            draw_rectangle(x0[1],x0[2],x1[1],y1[2],false)
        // Reset
        draw_set_blend_mode(bm_normal);
        draw_set_alpha(1);
        surface_reset_target();
    } else {
       //check if the surface exists
        obj_surf_vfx.surf_light = surface_create(room_width, room_height);
        surface_set_target(obj_surf_vfx.surf_light);
        draw_clear_alpha(c_black, 0);
        surface_reset_target();
    }
    background_x[1] -= 0.5;
    
     
  7. YellowAfterlife

    YellowAfterlife ᴏɴʟɪɴᴇ ᴍᴜʟᴛɪᴘʟᴀʏᴇʀ Forum Staff Moderator

    Joined:
    Apr 21, 2016
    Posts:
    2,003
    The way this is usually handled (if you've been around the GM forums sometime around 2008-2009, you might recall a big influx of games with lighting and/or destructive terrain systems) is by covering the room with more reasonably sized surfaces. Nowadays 1024x1024 will work pretty well. Then you figure out which surfaces overlap the thing that you're about to draw, and draw it to each of them with an offset. And draw the surfaces overlapping the view with a simple for-loop.

    The other way would be to present your visibility data as non-pixel as such (e.g. marching squares), but it might be tricky to find a working example for this.
     

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice