GameMaker Using shaders vs draw for tinting the whole screen.

Carloskhard

Member
So I've make an effect that makes the whole screen tints red.
So far I was doing it by drawing a red rectangle over the whole camera space but my camera in the game rotates a lot and drawing always at the right position and angle is hard.
Should I try using shaders for tinting the whole camera? How could I do it so the shaders applies to all of the view?
This could also be applies with black screens.
Thanks
 

obscene

Member
You could probably find a shader to do it... and you would apply it by drawing the surface application (which is the built in surface GM is drawing to) through the shader.

Probably simpler and more efficient to just draw it like you are doing. However, you want to be doing this in a draw GUI event so its drawn to screen coordinates instead of game coordinates so it won't matter what your camera is doing.
 
If you were to draw the rectangle, just draw it to the GUI layer. Then you don't have to worry about positions or angles.
If you use a shader, you can apply it to the application surface.
 

YawningDad

Member
You could do this with shaders, but you could also do it by drawing to the application_surface after all of your game's drawing is done. Off the top of my head, this could be something like:

Code:
var old_color = draw_get_color();
surface_set_target( application_surface );
draw_set_alpha( 0.3 ); // 0 = transparent, 1 = opaque
draw_set_color( c_red );
draw_rectangle( 0, 0, window_get_width(), window_get_height() );
draw_set_alpha( 1 );
draw_set_color( old_color );
surface_reset_target();
 

Carloskhard

Member
Thank you guys @YawningDad and @obscene but I forgot to mention that the game is for mobile and I can't afford to use surfaces :c

If you were to draw the rectangle, just draw it to the GUI layer. Then you don't have to worry about positions or angles.
If you use a shader, you can apply it to the application surface.
I've set the rectangle to be drawn in the GUI behind the UI interface in the GUI and works just fine now so thanks for that trick @BattleRifle BR55 !

Eatherway I'd like to know what would be the better way to apply a shader to all of the view without using surfaces.
 
Last edited:

Carloskhard

Member

Carloskhard

Member
Also using GUI was working well, but I've noticed now that the effect gets drawn above everything and I want some stuff to not get drawn over by this effect so I guess I'll have to draw the rectangle using the same position and angle that the camera uses.
Eatherway I still hope to find some shader alternative solution to this.At least just to learn how could be done and if the result would be better
 

obscene

Member
You have the Draw GUI Begin, Draw GUI and Draw GUI End events you can use, so draw this in the Draw GUI Begin event and make sure everything you want to not have the effect is in one of the others. You can also use depth to manipulate this. Instances that share the same draw events will draw in descending order by depth.
 

Relic

Member
You can’t disable all surfaces- the game is drawn to a surface called the application surface, which can never be removed.

In any draw event you are drawing to the application surface (unless you set a different surface as the current target). Resetting the surface target simply means “go back to drawing on the the application surface”.

By default, game maker draws the application surface onto the screen in the post draw event as shown by the flow of draw events in the link I posted earlier. All I’m suggesting is turning off that default state so the application surface is not drawn when GM wants, but rather when you want- which is after you set the shader in the post draw event (and so you still have a chance to reset the shader before the next step).
 

Cameron

Member
Using surfaces in mobile destroy performance. Consider that not even triple A mobile games like rayman use surfaces.
Lol no they don't. I've published to mobile and used surfaces to improve performance. Not to mention the size of the surface makes a difference as well. I'm thinking you are misinformed and should do more study and testing on surfaces.
 

Bingdom

Googledom
Using surfaces in mobile destroy performance. Consider that not even triple A mobile games like rayman use surfaces.
This is old news. Mobile devices are more powerful than ever. Pick up a recent Android device for a cheap price and there's a good chance it would run the game just fine.
Here's the current market share for the OS versions in 2018.
From experience, I would be most concerned about Ice Cream Sandwich and lower. Given that they account for less than 1% of the market, it's fair to consider them as anomalies.

... the game is drawn to a surface called the application surface, which can never be removed.
You can - see: application_surface_enable().
iirc, In GMS1.4, you can also disable it in global game settings.

In any draw event you are drawing to the application surface (unless you set a different surface as the current target). Resetting the surface target simply means “go back to drawing on the the application surface”.
More accurately; pop the current surface from the surface stack. Surfaces are stackable.

Creating your own shader is unnecessary. You can apply a colour blend with draw_surface_ext.
E.g.
Code:
draw_surface_ext(application_surface, 0, 0, 1, 1, 0, c_red, 1);
I recommend putting this code in the post draw event.

Remember to call application_surface_draw_enable(false) at least once.
 

Relic

Member
Disabling the application surface is not the same as removing/freeing it since you wanted to get semantically correct on me!
 

Carloskhard

Member
This is old news. Mobile devices are more powerful than ever. Pick up a recent Android device for a cheap price and there's a good chance it would run the game just fine.
Here's the current market share for the OS versions in 2018.
From experience, I would be most concerned about Ice Cream Sandwich and lower. Given that they account for less than 1% of the market, it's fair to consider them as anomalies.


You can - see: application_surface_enable().
iirc, In GMS1.4, you can also disable it in global game settings.


More accurately; pop the current surface from the surface stack. Surfaces are stackable.

Creating your own shader is unnecessary. You can apply a colour blend with draw_surface_ext.
E.g.
Code:
draw_surface_ext(application_surface, 0, 0, 1, 1, 0, c_red, 1);
I recommend putting this code in the post draw event.

Remember to call application_surface_draw_enable(false) at least once.
Thats some nice info, however I can't even use 60fps for my game so not sure how much I could push that. I'll make some study these days.
 
Last edited:
Top