Android [SOLVED] Surface "disappears" after room_restart()

C

Cervian

Guest
Good morning Game Makers!,
I started developing a game based on procedurally generated mazes. In my design, I used surface to draw shadows based on directional light.
The game works in Windows as in Android enviroment...
BUT
In Windows enviroment, when I use a method like room_goto() or room_restart(), the new room shows the new calculated surface without any problem.
In Android enviroment, the surface is shown only on first room. After I use aforementioned methods, new room does not show the surface.
This is the code:

Create Event:
Code:
/// Initialization
/* shadow casting effect is based on caster direction*/

shader=shader_clamp_alpha; //shader for fixing surface
surface = surface_create(obj_level.roomWidth, obj_level.roomHeight); //surface on which shadows are casted

iDir = 0; //index light direction
currentDir = 0; //current selected light direction
numDirs = 8; //number of directions
necessaryToDraw = true;

// light direction
lightDir[7] = 0;
lightDir[6] = 45;
lightDir[5] = 90;
lightDir[4] = 135;
lightDir[3] = 180;
lightDir[2] = 225;
lightDir[1] = 270;
lightDir[0] = 315;
Draw Event:
Code:
/// Draw all the lights on the surface

// Update light direction
if (DEBUG)
{
    if device_mouse_check_button_pressed(0, mb_right)
    {
        iDir += 1;
        necessaryToDraw = true;
    }
    if (iDir >= numDirs) iDir = 0;
}

if (necessaryToDraw == true || !surface_exists(surface))
{
    show_debug_message('Update shadows...');
    surface = surface_create(obj_level.roomWidth, obj_level.roomHeight);
    surface_set_target(surface); //setting current target for drawing
    draw_clear_alpha(c_black,0); // clean up the surface with plain invisible black
    draw_set_blend_mode(bm_normal);
  
    currentDir = lightDir[iDir];
  
    // Update light effect to draw the correct shadows
    var imin, imax;
    var i;
  
    with (obj_wall_placeholder)
    {
        // Draw a triangle strip outside the shadow caster
        draw_primitive_begin(pr_trianglestrip);
      
        for (i = 0; i < points; i++)
        {   
            draw_vertex_color(x + px[i], y + py[i], c_black, 1);
            draw_vertex_color(x + px[i] + lengthdir_x(height, other.currentDir), y + py[i] + lengthdir_y(height, other.currentDir), c_black,1);
        }
      
        draw_vertex_color(x + px[0], y + py[0], c_black, 1);
        draw_vertex_color(x + px[0] + lengthdir_x(height, other.currentDir), y + py[0] + lengthdir_y(height, other.currentDir), c_black,1);
      
        draw_primitive_end();
      
        // Draw shadow under shadow caster
        draw_primitive_begin(pr_trianglestrip);
        {   
            draw_vertex_color(x + px[0], y + py[0], c_black, 1);
            draw_vertex_color(x + px[3], y + py[3], c_black, 1);
            draw_vertex_color(x + px[1], y + py[1], c_black, 1);
            draw_vertex_color(x + px[2], y + py[2], c_black, 1);
        }
        draw_primitive_end();
    }  
    surface_reset_target();
    necessaryToDraw = false;
}

shader_set(shader);
draw_surface(surface,0,0);
shader_reset();
draw_set_blend_mode(bm_normal);
Room End:
Code:
if surface_exists(surface)
{
show_debug_message('Clean up surface...');
    surface_free(surface);
}
Hope someone could help me solve this crap :D.
 
Last edited by a moderator:

CMAllen

Member
At a guess, the surface is being released due to memory limitations (something that would be more stringent on a mobile device than a PC) after the initial create event and it doesn't appear to be checked for recreation anywhere. Somewhere in either the drawing code or a step event, you need to check that the surface exists and recreate it if it doesn't. My suggestion would be draw_begin event or at the start of the draw event itself, that way your entire draw routine can then complete itself, and if it runs into memory problems afterward, the surface can be released without impacting the shadow drawing routine. But that's just my impression from the code you've shown.
 
C

Cervian

Guest
Thank you! You solved my issue!
By the way I fixed the code in this way:
Chunk of Draw Event:
Code:
if (necessaryToDraw == true)
{
    show_debug_message('Update shadows...');
    if !surface_exists(surface)
    surface = surface_create(obj_level.roomWidth, obj_level.roomHeight);
    surface_set_target(surface); //setting current target for drawing
    draw_clear_alpha(c_black,0); // clean up the surface with plain invisible black
    draw_set_blend_mode(bm_normal);
...
}
P.S. In the last minutes I diagnosed something similar by noticing memory leakage at every room restart.
My opinion is that if you use multiple times surface_create() you are actually "stacking" surfaces
 
Top