• Hello [name]! Thanks for joining the GMC. Before making any posts in the Tech Support forum, can we suggest you read the forum rules? These are simple guidelines that we ask you to follow so that you can get the best help possible for your issue.

Legacy GM surface usage causes huge fps drop

G

Gad

Guest
So I've decided I want to use shaders. I can either apply shader over each drawn object, or draw them all on surface and then apply shader on the surface.
I've been through various surface tutorials and I don't think I'm doing something wrong, but it's really bothering me.

As I keep regular draw with no surfaces, no shaders the fps are flying around ~2000. When i initalize surface (single surface for now) the fps drops to around 60 and sometimes drop to ~40.

My current graphic card is really weak (geforce 405), but I don't think that really explains the significant drop with usage of just one surface used and it's size for now is 1024x768. If i make it bigger it jams even more...

This is how I handle the surface:
So i've got an object called SurfaceHolder, that holds the surface and draws it.

Initialize surface at Create event:
Code:
specialsurface = surface_create(view_wport,view_hport);
surface_set_target(specialsurface);
draw_clear_alpha(c_white,0);
surface_reset_target()

Draw objects on surface and print surface on Draw event:
Code:
if surface_exists(specialsurface)
{
    surface_set_target(specialsurface)
    draw_clear_alpha(c_white,0);
    with(oHurt)
            {

                draw_sprite(sprite_index, image_index, x, y);
            }
}
else
{
  
      specialsurface = surface_create(view_wport,view_hport);
      surface_set_target(specialsurface);
      draw_clear_alpha(c_white,0);
      surface_reset_target()
}
surface_reset_target();

draw_surface(specialsurface,0,0);
Free surface on Game End event:
Code:
if surface_exists(specialsurface)
{
    surface_free(specialsurface);
}

Am I doing something wrong, or surfaces are just that badly optimalized?
 
Last edited by a moderator:

Juju

Member
draw_surface(specialsurface); isn't a valid line of code (that function takes three arguments). How many instances of oHurt do you have? Have you run the profiler to check what's slowing the game down?
 
G

Gad

Guest
oh sorry, its draw_surface at 0,0, i just copied part of the code that's necessary

i currently have 2 instances of oHurt, not having any events

i've tried to run a debugging mode, but i have no idea how to check what's actually causing this delay, can you somehow show me a direction how to arrange that?
 

Stubbjax

Member
I don't think you're meant to be switching the draw targets during the draw event. Generally, you'd draw everything to the surface elsewhere and then simply draw the surface in the draw event (at least that's what I do and it works flawlessly). Also, it's bad practice to duplicate your code like that. Create a script to initialise the surface that gets called in the create event and can be also called if the surface_exists check fails (which you'd ideally move to step or end step).
 
G

Gad

Guest
I rather don't duplicate script like that, but just for cleaner display I put it all together here. Actually I am using an external script to initalize a surface.

Ok, I've tried to do it the way you've suggested, but it doesn't seem to work. I did put all calls for surface at the step event, except for drawing the surface itself. Same outcome.
What I also have noticed is the fact that just holding the surface and updating it every frame jams the game, even if I don't draw the surface itself.
 

Stubbjax

Member
Well then I guess the real question is why are you updating the surface every frame? Surfaces are best used to draw multiple static elements as a single image, and continuously updating them every frame does not make a lot of sense. Also, how many instances of oHurt do you have? Is there only a single instance of the surface controller object?
 
G

Gad

Guest
First of all. There's a major thing that I've noted.
If I actually launch the game on fullscreen fps are pretty much constant around 1500, while on windowed they keep fly around ~60, sometimes jumping to ~800 and then falling back to 60, sometimes going below 60. So as long as I keep it at fullscreen it works good. Which is very weird. This might be a hardware issue, but it means that some other ppl might get this effect too.. hmm.

For the question why do I use it, follow up with uploaded image.
There are moving, animated objects, that I want to apply shaders on (atm simple fade to dark). For now I'm having two instances affected by that on the screen, so technically I could apply shader over every object. But if I decide to make 100 instances of this object, I believe it's faster to draw them on surface and then apply shader over surface.
 

Attachments

Stubbjax

Member
Not sure about the full screen issue. Regarding surfaces, why not just do this:

Code:
shader_set(your_shader);
with(oHurt)
{
  draw_sprite(sprite_index, image_index, x, y);
}
shader_reset();
 
G

Gad

Guest
As I've mentioned I think this will actually perform slower (if i have more instances), than applying shader just for one surface, thought for that I'm not sure. That's what I've been told by some guy more experienced with shaders.
But the real reason is the fact, that shader will only run through pixels on each sprites. If I want it to create a distortion or blur effect, this will cause pixels around sprite to get changed, which can not be achieved this way. For now I'm using very simple shader, but I plan to actually develop something more complicated later on.
 
Top