OFFICIAL Using Surfaces

Pfap

Member
This blog comes at a great time, as my latest project which is coming along quite nicely relies heavily on them. The manual section on surfaces is in my opinion rather confusing and it took me awhile to figure them out. Especially, the section on only creating surfaces in the draw event, but this causes a memory leak which crashed my game when run on ios. I think my computer had enough resources to keep it running, but ios crashed fast.

I was originally under the impression that Gamemaker cleaned up surfaces in the draw event, every time control reached an existing recreate.

I will need to re-read the blog post as I didn't entirely grasp what is being changed about them, but I am keenly interested as I need to be able to update a surface every step; or rather re-draw to it every step.


Here is some of my surface code if anyone is interested.
Code:
//initially create the surfaces in the else block and then on subsequent steps draw a clear alpha to the surface to clear it
if surface_exists(wrap_surface){
 
//I'm not sure that I need to be calling this every step? If I recall correctly if I don't free or draw clear the surface begins to draw on "top" of stuff drawn the previous step causing the image to be smeared
surface_free(wrap_surface);
surface_free(opp_wrap_surface);


wrap_surface = surface_create(camera_get_view_width(view_camera[1]), camera_get_view_height(view_camera[1]));
opp_wrap_surface = surface_create(camera_get_view_width(view_camera[2]), camera_get_view_height(view_camera[2]));


//clear both surfaces 
surface_set_target(wrap_surface);
draw_clear_alpha(c_black, 0);
surface_reset_target();

surface_set_target(opp_wrap_surface);
draw_clear_alpha(c_black, 0);
surface_reset_target();

}
else{
wrap_surface = surface_create(camera_get_view_width(view_camera[1]), camera_get_view_height(view_camera[1]));
opp_wrap_surface = surface_create(camera_get_view_width(view_camera[2]), camera_get_view_height(view_camera[2]));
}



//set and draw to each surface 
surface_set_target(wrap_surface);
    
 with(player_inst)
 {
 var _vx = camera_get_view_x(view_camera[1]);
 var _vy = camera_get_view_y(view_camera[1]);
 draw_sprite(sprite_index, image_index, x - _vx, y - _vy);
 }
surface_reset_target();
   
   

surface_set_target(opp_wrap_surface);
    
 with(opponent_inst)
 {
 var _vx = camera_get_view_x(view_camera[2]);
 var _vy = camera_get_view_y(view_camera[2]);
 draw_sprite(sprite_index, image_index, x - _vx, y - _vy);
 }
surface_reset_target();
   
   
   
   
 //draw the created and drawn to surfaces
draw_surface(wrap_surface, left_line.bbox_left, top_line.bbox_top);
draw_surface(opp_wrap_surface, left_line.bbox_left, top_line_opp_draw.bbox_top);


I'm thinking I could probably just create the surface in the else block and then just draw the clear alpha onto it the following steps instead of freeing and creating it again.



I guess I am making this lengthy post, because the boldface type in the blog post has me confused.

You can no longer free or resize surfaces that are in use. This means once you set a surface, you can not free it, or resize it until you release it using surface_reset_target(). This means for each surface is set, you must have a matching surface reset in order to maintain the stack. An example of this is...

I can't think of a situation where you would resize a surface still in use, but I hope to have no problems with my code above.
 
Top