Shaders Shaders in Fullscreen, shader effect is at incorrect position

Silverfire

Member
Hi guys. So I understand how shaders work and how to implement them. In my game, I have an object with a Post Draw event that applies a distortion shader to simulate a water effect. This effect is not applied to the whole screen/view, only the water object. A different object takes care of drawing the application surface. It looks good when not stretching the surface to cover the whole screen, but not so much when I go fullscreen. See the pictures for reference:

Surface displayed at 0,0 with room view original width and height (960x540):



Full screen (1920x1080 in my case), the effect is displayed close to where it would be if it wasn't in fullscreen:



I think the solution is having a 960x540 surface, apply the shaders on this surface, then stretch the surface to fill the screen? But I am unable to do it, I can't seem to find the correct code lines.

Thanks.
 
Last edited:

Silverfire

Member
Finally found a solution to my issue! If you see this and you know of a better solution, please let me know. Here's the relevant code in case someone has a similar problem:

Global Settings

✓ Start in fullscreen mode
✓ Keep aspect ratio

obj_control Create event

Code:
application_surface_draw_enable(false);

global.surf=surface_create(view_wview,view_hview);
surface_set_target(global.surf);
draw_clear_alpha(c_black, 0);
surface_reset_target();
view_surface_id[0]=global.surf;
obj_control Post Draw event
Code:
draw_surface_stretched(global.surf,0,0,display_get_width(),display_get_width()/(16/9));
obj_water Create event
Code:
u_resolution=shader_get_uniform(shd_water,"iResolution")
u_seconds=shader_get_uniform(shd_water,"iGlobalTime")
rw=display_get_width()/960
obj_water Post Draw event
Code:
shader_set(shd_water)
shader_set_uniform_f(u_resolution,display_get_width(),display_get_width()/(16/9))
shader_set_uniform_f(u_seconds,global.sec)
draw_rectangle((x-view_xview)*rw,(y-view_yview)*rw,((x+(image_xscale*32))-view_xview)*rw,((y+(image_yscale*32))-view_yview)*rw,0)
shader_reset()
 
M

Mann_mit_Hut

Guest
Just flying over the code, but it is strange that you are using view coordinates to position the rectangle. The water rectangle has a fixed position in the room, so the view coordinates must not be in the coordinatecalculation of it.
Also the shader is using display width and height, which is also not needed, it's all happening in room space. So maybe you are making it way to complicated...
 

Silverfire

Member
@Mann_mit_Hut - My room uses a view, the shader effect is applied at a fixed location on the screen if I don't position the rectangle using the view coordinates. Might be because of the way the shader I use is written. From the manual:
[...] if you have a view-sized surface and wish to draw something that is currently in view to that surface, you should subtract the view x and y coordinates from the actual x and y coordinates to get a relative position to the surface (0,0) position.
Regarding the use of display width and height, if I use this line of code
Code:
shader_set_uniform_f(u_resolution,960,540)
instead of the one I currently use
Code:
shader_set_uniform_f(u_resolution,display_get_width(),display_get_width()/(16/9))
the shader effect is messed up, it does not display the way it should. Again, might be due to the way the specific shader I use is coded.
 
M

Mann_mit_Hut

Guest
Ah i see, so if thats the point where it goes wrong, then the results of display_get_width() and display_get_width()/(16/9) cant be 960 and 540... did you check that?
 

Silverfire

Member
The values can be 960 and 540 if the user's screen resolution is 960x540 :) The width value must be the user's screen width, using display_get_width() ensures the value is correct with any resolution, even when the ratio is not 16:9. The fact you asked this question prompted me to check various resolutions and see if it works. Everything is fine except I need to offset the game's surface y position to have black bars above and below when the ratio is not 16:9.
 
Top