• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

Surface causes big fps drop

Kyon

Member
Hello! I'm really trying to use surfaces in my game, I've finally managed to make a nice lightning effect, but it drops the fps from 60 to 45.

This is the surface I use. (if i delete this script the fps is back to 60)
Code:
surface_set_target(global.light){                        
    draw_clear_alpha(c_black,1);
    draw_set_blend_mode(bm_subtract);
    with (obj_player){
        alphalight=choose(.8,.8,.8,.75,.72,.77,.83,.76,.6);
        draw_sprite_ext(spr_oillamplight,1,itemx,itemy,1,1,image_angle,image_blend,alphalight+.1);
        draw_sprite_ext(spr_oillamplight,1,itemx,itemy,2,2,image_angle,image_blend,0.1);
    }
    draw_set_blend_mode(bm_normal);
    surface_reset_target();
}

if surface_exists(global.light) {
    draw_surface(global.light,0,0);
} else {
    global.light=surface_create(room_width,room_height);
}
This is what the surface does (the lightning):


Am I doing something wrong?
Or is this normal when using surfaces?


Thanks!
 
I

icuurd12b42

Guest
how big is your room?
your surface should be the size of the application surface.
the application surface should also be the size of the view or the port, whichever is smaller. using surface_resize. to limit the amount of data being rendered.

you surface check should be tweaked

Code:
if (!surface_exists(global.light))
{
    global.light = surface_create(room_width, room_height);
}
if surface_exists(global.light)
{
    surface_set_target(global.light)
    {
        draw_clear_alpha(c_black, 1);
        draw_set_blend_mode(bm_subtract);
        with(obj_player)
        {
            alphalight = choose(.8, .8, .8, .75, .72, .77, .83, .76, .6);
            draw_sprite_ext(spr_oillamplight, 1, itemx, itemy, 1, 1, image_angle, image_blend, alphalight + .1);
            draw_sprite_ext(spr_oillamplight, 1, itemx, itemy, 2, 2, image_angle, image_blend, 0.1);
        }
        draw_set_blend_mode(bm_normal);
        surface_reset_target();
    }
    draw_surface(global.light, 0, 0);
}
I'm not sure why the huge drop, unless it's a huge surface. are you sure there is only one object instance doing the code you posted?
 

Kyon

Member
how big is your room?
your surface should be the size of the application surface.
the application surface should also be the size of the view or the port, whichever is smaller. using surface_resize. to limit the amount of data being rendered.

you surface check should be tweaked

Code:
-
I'm not sure why the huge drop, unless it's a huge surface. are you sure there is only one object instance doing the code you posted?
Thanks! That's a lot cleaner haha.
The room ís quite big. It's 3200x2400, with nothing in it but the player though.
Also in the same object in the post draw event I'm drawing the application surface. Is it wrong to draw 2 surfaces in 1 object?
And if the room is too big for the surface, is there a way to draw the surface only in the view all the time? (the view is smaller)


EDIT:
i tried to create the surface like so: global.light = surface_create(view_wview, view_hview);
and then draw the surface like this: draw_surface(global.light,view_xview,view_yview);
But this gives me a strange black screen. The fps is 60 though. Am I doing something wrong?

EDIT2:
I figured it's not just a strange black screen, but the lightning effect just doesnt show. It only draws the black square.
 
Last edited:
I

icuurd12b42

Guest
easiest way is to create the surface the size of the view. I'm sure your view is not 3200x2400. and draw on it relative... like draw on it at x-view_xview,y-view_yview... to offset the draw to be relative to the 0,0 position the surface.

You can crad the surface at view_xview,view_yview instead of 0,0. this way you only need a smalle surface.
 

Kyon

Member
easiest way is to create the surface the size of the view. I'm sure your view is not 3200x2400. and draw on it relative... like draw on it at x-view_xview,y-view_yview... to offset the draw to be relative to the 0,0 position the surface.

You can crad the surface at view_xview,view_yview instead of 0,0. this way you only need a smalle surface.
How do you mean 'draw on it relative'?
And thanks ;)

EDIT:
I've done what you said, and changed a bit of the code to this:
Code:
draw_sprite_ext(spr_oillamplight,1,itemx-view_xview,itemy-view_yview,1,1,image_angle,image_blend,alphalight+.1);
draw_sprite_ext(spr_oillamplight,1,itemx-view_xview,itemy-view_yview,2,2,image_angle,image_blend,0.1);
It works, but I dont really understand why it works like this haha.
What is the logic behind it?
 
I

icuurd12b42

Guest
a surface of size 1024,1024 you can only draw on it from 0,0 to 1023,1023

if your lamp is in the room at 2000,2000 and your view is at 1500,1500... you need to draw the sprite at 2000-1500 on the surface...
 

Kyon

Member
a surface of size 1024,1024 you can only draw on it from 0,0 to 1023,1023

if your lamp is in the room at 2000,2000 and your view is at 1500,1500... you need to draw the sprite at 2000-1500 on the surface...
Ah of course, I understand now thanks! It's late haha. It runs with 60 fps again now.
Thanks a lot!
 
Top