• 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.

HTML5 Bug with surface_reset_target in Draw GUI?

Mortalo

Member
So, I'm converting my game from windows to html5. I knew that there would be some changes needed, but I was not expecting that I will have to forget about any surface use in the GUI layer.
TL;DR: In Draw GUI events, surface_reset_target makes drawing on the GUI layer to not work properly.

Let me show what is happening (look at the HUD on top):
(window size is set to 1280x720, GUI size to 1920x1080, my desktop resolution is Full HD as well)
1a.png
2a.png
Code from the HUD Draw GUI event:
GML:
draw_set_font(global.HudFont);
    
draw_set_alpha(local_card_alpha);
draw_sprite_ext(spr_hud_card, 0, local_draw_x_c, local_draw_y,
    local_card_scale,local_card_scale,image_angle,-1,local_card_alpha);
draw_set_alpha(local_alpha_text);
draw_text(local_draw_x_c_d, local_draw_y, cards_left);
You can see that there is no use of surfaces.
Now let's take a look at the Draw GUI Begin event from the Rewind object:
GML:
draw_set_colour(c_teal);draw_set_alpha(local_bronze_alpha);
draw_rectangle(0, 0,
    display_get_gui_width(), display_get_gui_height(), false);
draw_set_colour(c_white);draw_set_alpha(1);

if(local_clock && local_blue)
{
    draw_sprite_ext(spr_clock_arm, 0, local_clock_x, local_clock_y,
        1, 1, image_angle, c_white, 1);
    draw_sprite_ext(spr_clock_dot, 0, local_clock_x, local_clock_y,
        1, 1, 0, c_white, 1);
}
if(local_blue)
{
    scr_GameControl_drawRewindBorder(local_rewindCount, local_border_alpha);
}
and scr_GameControl_drawRewindBorder where I'm using a surface:
GML:
if(!surface_exists(local_rewindSurface))
    local_rewindSurface = surface_create(local_rewindSurface_width,
                                            local_rewindSurface_height);

surface_set_target(local_rewindSurface)
draw_clear_alpha(c_black, 0);

draw_set_colour(c_orange);//c_orange//c_blue//c_aqua
draw_rectangle(0+local_draw_rewind_x,
    0+local_draw_rewind_y1,
    0+local_draw_rewind_x+local_rewind_cell*argument0,
    0+local_draw_rewind_y2,false);
draw_set_colour(c_white);
draw_sprite_ext(spr_rewind_border,0,0+local_draw_border_x,
    0+local_draw_border_y,
    local_menuSize,local_menuSize,0,-1,1);

surface_reset_target();

draw_surface_ext(local_rewindSurface, local_rewindSurface_x,local_rewindSurface_y,
    1,1,0,c_white,argument1);
On two screens above you see that clock drawn before use of a surface is drawn correctly, while both the rewind bar and HUD, which are drawn after surface_reset_target are drawn wrongly. It seems like surface_reset_target sets the wrong surface to draw to.
I have checked that nothing changes - GUI size, view size, window size. Nothing. Though when I've put gui_maximize(1,1,0,0) after the surface_reset_target, the clock is drawn upscaled as well, starting the next frame.
This issue doesn't happen with surfaces in normal Draw events (I use surfaces to draw shadows, which you can see on the screens).

You can simply recreate this with this code:
GML:
Draw GUI Begin:

draw_rectangle(0,0,100,100,false);
var _surf = surface_create(200,200);
surface_set_target(_surf);
draw_clear_alpha(c_black,0);
draw_rectangle(0,0,100,100,false);
surface_reset_target();
draw_surface(_surf,300,0);
surface_free(_surf);

Draw GUI:

draw_rectangle(50,150,150,250,false);
I don't hope that solution to this problem exists, so I would rewrite my code to not use surfaces in the GUI layer.
 
Top