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

How to avoid drawing sprite duplicate of Draw surface on Draw GUI Begin surface?

Biosyn

Member
Hello,

I'm having a small issue with a sprite that's drawn on a surface, that's demonstrating unwanted behavior by also being drawn at the corner of the screen when a fullscreen shader control object runs its Draw GUI Begin event to apply shaders to the application surface + additional surfaces, then draw it stretched.

If the fullscreen control object does not exist, the sprite, drawn on a custom surface in a separate object's Draw event, is drawn correctly at 4x resolution - call this the "clip" object. Once I create the fullscreen control object, everything still works fine - I can see the clip object's surface drawn correctly as well. The only small issue is that the sprite/surface that's being drawn on the "clip" object has a duplicate drawn at the top-left corner of the screen at 1x resolution along with the one that's being drawn correctly at 4x resolution.

Here's the relevant code. Clip Object:

CREATE:
GML:
surf = -1;
DRAW:
GML:
if (!surface_exists(surf)){
    surf = surface_create(sprite_width, sprite_height);
}
x = mouse_x
y = mouse_y
var _scl = 1;

//Set target
surface_set_target(surf);

//Draw sprite
draw_sprite_ext(sprite_index, image_index, sprite_xoffset, sprite_yoffset, _scl, _scl, 0, c_white, 1);

//Draw overlay clipping sprite
gpu_set_colorwriteenable(1, 1, 1, 0);

draw_sprite_ext(spr_overlay, 0, 0, 20, _scl, _scl, 0, -1, 1);

gpu_set_colorwriteenable(1, 1, 1, 1);

//Reset target
surface_reset_target();

//Draw surface
draw_surface(surf, x - sprite_xoffset, y - sprite_yoffset);
And for the fullscreen object:

DRAW GUI BEGIN EVENT (note: this object is also drawing a few surfaces to apply shaders on):

GML:
if (shader_type == 0) exit; // no shader

// SET VALUES:
//-----------------------------------------------------------------------------
var blur_steps        = round(1 * 15) + 1;
var sigma            = max(0.66, 0.0001);
var bloom_intensity    = 1 * 2;
var bloom_darken    = 1 - 0;
var bloom_saturation= 1 * 2;

if (shader_type == 1) { // GLSL ES
    var bloom_threshold = 0.5//slider_get_value(5); //no effect, prob coz of GLSL ES (i.e. no layers)
    var bloom_range        = 0.5//slider_get_value(6); //no effect
}

// DRAW:
//-----------------------------------------------------------------------------

// 1st pass: Draw brights to bloom surface:
// AppSrf -> srf_ping
// GLSL ES only; GLSL & HLSL do this pass per layer using MRT
if (shader_type == 1) {
    shader_set(shader_bloom_lum);
        shader_set_uniform_f(u_bloom_threshold,        bloom_threshold);
        shader_set_uniform_f(u_bloom_range,            bloom_range);

        surface_set_target(srf_ping);
            draw_surface(application_surface, 0, 0); //feed app surf into srf_ping
        surface_reset_target();
}

// 2nd pass: blur horizontally
// srf_ping -> srf_pong
gpu_set_tex_filter(true);
shader_set(shader_blur);
    shader_set_uniform_f(u_blur_steps,        blur_steps);
    shader_set_uniform_f(u_sigma,            sigma);
    shader_set_uniform_f(u_blur_vector,        1, 0);
    shader_set_uniform_f(u_texel_size,        texel_w, texel_h);

    surface_set_target(srf_pong);
        draw_surface(srf_ping, 0, 0);
    surface_reset_target();

// 3rd pass: blur vertically
// srf_pong -> srf_ping
    shader_set_uniform_f(u_blur_vector,        0, 1);

    surface_set_target(srf_ping);
        draw_surface(srf_pong, 0, 0);
    surface_reset_target();

gpu_set_tex_filter(false);

// 4th pass: Blend bloom surface with app surface
// AppSrf & srf_ping -> screen
//shader_set(shader_bloom_blend);
//    shader_set_uniform_f(u_bloom_intensity, bloom_intensity);
//    shader_set_uniform_f(u_bloom_darken, bloom_darken);
//    shader_set_uniform_f(u_bloom_saturation, bloom_saturation);
//    texture_set_stage(u_bloom_texture, bloom_texture);
//    gpu_set_tex_filter_ext(u_bloom_texture, false);


//Handle additional surfaces
#region Bloom + both shaders
//Apply bloom to application surface (on motion blur surface)
surface_set_target(srf_moblur);
shader_set(shader_bloom_blend);
shader_set_uniform_f(u_bloom_intensity, bloom_intensity);
shader_set_uniform_f(u_bloom_darken, bloom_darken);
shader_set_uniform_f(u_bloom_saturation, bloom_saturation);
texture_set_stage(u_bloom_texture, bloom_texture);
gpu_set_tex_filter_ext(u_bloom_texture, false);
draw_surface(application_surface, 0, 0);
surface_reset_target();

//Apply motion blur to motion surface (on hue surface)
surface_set_target(srf_hue);
shader_set(shd_moblur);
shader_set_uniform_f(fs_moblur_upos,fs_moblur_x,fs_moblur_x);
draw_surface_stretched(srf_moblur, 0, 0, gui_w, gui_h);
surface_reset_target();

// Apply hue shift to hue surface.
shader_set(shd_hue);
    shader_set_uniform_f(hue_pos_uni, hue_amt);
    draw_surface_stretched(srf_hue, 0, 0, gui_w, gui_h);
shader_reset();
Again, it all works fine. Just that a 1x resolution of the sprite drawn on the clip object's surface appears on the top-left corner of the screen. Is there a way to get rid of it?

Thanks.
 
Last edited:
Top