gm-docs-parser 1.0.0

A collection of typings for GameMaker Studio 2 manual pages
Documentation
<?xml version="1.0" encoding="utf-8" ?>

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"><head>

  <script type="text/javascript" language="JavaScript">
    //<![CDATA[
    function reDo() {
      if (innerWidth != origWidth || innerHeight != origHeight)
        location.reload();
    }
    if ((parseInt(navigator.appVersion) == 4) && (navigator.appName == "Netscape")) {
      origWidth = innerWidth;
      origHeight = innerHeight;
      onresize = reDo;
    }
    onerror = null;
  //]]>
  </script>
  <style type="text/css">/*<![CDATA[*/

    < !-- div.WebHelpPopupMenu {
      position: absolute;
      left: 0px;
      top: 0px;
      z-index: 4;
      visibility: hidden;
    }

    p.WebHelpNavBar {
      text-align: right;
    }

    -->
  
/*]]>*/</style>

  <script type="text/javascript">//<![CDATA[

    gRootRelPath = "../../../..";
    gCommonRootRelPath = "../../../..";
    gTopicId = "9.2.5.8";
  
//]]></script>

  <script type="text/javascript" src="../../../../template/scripts/rh.min.js"></script>
  <script type="text/javascript" src="../../../../template/scripts/common.min.js"></script>
  <script type="text/javascript" src="../../../../template/scripts/topic.min.js"></script>
  <script type="text/javascript" src="../../../../template/scripts/topicwidgets.min.js"></script>
<script type="text/javascript" src="../../../../whxdata/projectsettings.js"></script>
  <link rel="stylesheet" type="text/css" href="../../../../template/styles/topic.min.css"/>
  <link rel="stylesheet" type="text/css" href="../../../../template/Charcoal_Grey/topicheader.css"/>
  <meta name="topic-status" content="Draft"/>

  <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
  <title>Surfaces</title>
  <meta name="generator" content="Adobe RoboHelp 2019"/>
  <link rel="stylesheet" href="../../../../assets/css/default.css" type="text/css"/>
  <meta name="rh-authors" content="Mark Alexander"/>
  <meta name="topic-comment" content="Reference section for the Surface functions and variables"/>
  <meta name="rh-index-keywords" content=""/>
  <meta name="search-keywords" content="Surfaces,application_surface,application surface,app surface"/>
</head>

<body>
  <div class="topic-header rh-hide" id="rh-topic-header" onclick="rh._.goToFullLayout()">
    <div class="logo">
    </div>
    <div class="nav">
      <div class="title" title="Surfaces">
        <span>Surfaces</span>
      </div>
      <div class="gotohome" title="Click here to see this page in full context">
        <span>Click here to see this page in full context</span>
      </div>
    </div>
  </div>
  <div class="topic-header-shadow rh-hide" id="rh-topic-header-shadow"></div>



  <!--<div class="body-scroll" style="top: 150px;">-->
  <h1>Surfaces</h1>
  <p>In the normal draw events, GameMaker Studio 2 doesn&#39;t actually draw directly to the screen, but rather draws to a <b>surface</b> called the <i>application surface</i>. This surface is basically a blank &quot;canvas&quot; that can then later
    be manipulated before being drawn to the screen when needed, and in most cases GameMaker Studio 2 handles this for you (although you can also manipulate it yourself in code for shaders, scaling and many other things - further details are given below).</p>
  <p>However, apart from this application surface, you can also create your own surfaces and use them to create stunning or subtle special effects in your game. For example, you can use surfaces to &quot;catch&quot; instances, which can then be destroyed,
    and in this way you can create a decal effect where the sprite for the instance is displayed on the surface as if it still existed, permitting graphical effects like debris, blood, etc... without any real processing overhead. Another thing you can
    do with surfaces is use them as textures to be manipulated, or to create sprites &quot;on the fly&quot;, or to create complex overlays. in fact, the uses for surfaces are endless!</p>
  <p>Normal surfaces are quite easy to use, but there are a few basic rules to be followed when you use them:</p>
  <ul class="colour">
    <li>First, you should realise that surfaces (<i>except</i> the application surface) are &quot;volatile&quot;. This means that if the device or window loses focus or is minimised (good examples are when you ALT +Tab to different window and back again on Windows,
      or on an Android device when the app loses focus due to a call) then the surface <strong>may be destroyed</strong>. This is because it is stored <em>only</em> in the texture memory (<a class="tooltip" title="VRAM is the amount of memory available for video, ie: the memory space that can store textures and images.">VRAM</a>) and
      may be overwritten when the target platform needs that memory for something else which means that you should <i><b>always</b></i> have some type of fail-safe code in place, usually with the <a href="surface_exists.htm"><tt>surface_exists()</tt></a>      function.</li>
  </ul>
  <p class="note" style="padding-top: 0.5em;padding-right: 1em;padding-bottom: 0.5em;padding-left: 4em"><strong>NOTE</strong>: This doesn&#39;t appear to happen with sprites or other visual assets (but actually does!) as they are also stored in regular memory (RAM) and when they are removed from texture memory (VRAM) they immediately get restored from
    regular memory when the game regains focus.</p>
  <ul class="colour">
    <li>Second, you should note that surfaces can require large quantities of VRAM to be used, and so you should attempt to keep them as small as possible. Normally you would try and keep them no larger than the size of the view or display window.</li>
    <li>Third, you should <b>only create surfaces in the draw event</b>. If you create a surface in the Create Event of an instance, you could potentially get the <i>same</i> index as the <tt>application_surface</tt>. This can then cause lots of problems
      and confusion as you think you are using your own surface, but you are actually using the current render target. You should also always try to limit <i>drawing</i> to a surface in the draw event too, since due to the optimised way in which GameMaker Studio 2      draws to the screen, it is recommended that you keep all draw functions <i>within the draw event</i> - this includes clearing a surface when it is first created, etc... Drawing to a surface outside of the draw event is possible and may even be necessary
      for some effects, but it&#39;s not how it <em>should</em> be done.</li>
    <li>Fourth, when drawing to a surface manually, the surface is <i>always</i> at the position of (0,0). This means that you may need to convert <em>absolute</em> coordinates into <em>relative</em> coordinates for the surface. For example, if you have a
      camera-sized surface and wish to draw something that is currently visible in the camera to that surface, you should subtract the camera view x and y coordinates from the actual x and y coordinates to get a relative position to the surface (0,0)
      position. So, the code would look something like this:</li>
  </ul>
  <p class="code" style="margin-top: 0px;margin-right: 50px;margin-bottom: 0px;margin-left: 100px">if view_current = 0<br/>     {<br/>     surface_set_target(surf);
    <br/>     with (obj_Effect)<br/>         {
    <br/>         var _vx = camera_get_view_x(view_camera[1]);<br/>         var _vy = camera_get_view_y(view_camera[1]);<br/>         draw_sprite(sprite_index, image_index, x - _vx, y - _vy);<br/>         }
    <br/>     surface_reset_target();
    <br/>     }
    <br/> else
    <br/>     {
    <br/>     draw_surface(surf, 0, 0);<br/>     }
  </p>
  <p> </p>
  <p>The basic use of a surface would be as follows:</p>
  <ul class="colour">
    <li>You first create a surface and assign its index to a variable.</li>
    <li>You would then set the drawing target to the surface rather than the display.</li>
    <li>Next, you would draw the things you wish as well as perform any other manipulations.</li>
    <li>Once you are done you reset the drawing target so that all further drawing happens on the screen again.</li>
    <li>Finally, you would draw the surface (or use it in a shader, or whatever is required).</li>
  </ul>
  <p>One thing to note is that should you require drawing the whole display to a surface (including tiles, backgrounds etc...) you can simply access the application surface itself (see below for further details) or you could assign a surface to a view port
    using the variable <a href="../../Cameras_And_Display/Cameras_And_Viewports/view_surface_id.htm"><tt>view_surface_id[0..7]</tt></a> as with this, all that is visible in that view port will be drawn to the corresponding surface.</p>
  <p>The following functions exist to deal with surfaces (these functions are specific for creating and manipulating surfaces, but to actually draw them to the screen you should be using the specific draw functions that can be found below):</p>
  <p> </p>
  <ul class="colour">
    <li><a href="surface_exists.htm">surface_exists</a></li>
    <li><a href="surface_create.htm">surface_create</a></li>
    <li><a href="surface_create_ext.htm">surface_create_ext</a></li>
    <li><a href="surface_resize.htm">surface_resize</a></li>
    <li><a href="surface_set_target.htm">surface_set_target</a></li>
    <li><a href="surface_set_target_ext.htm">surface_set_target_ext</a></li>
    <li><a href="surface_get_target.htm">surface_get_target</a></li>
    <li><a href="surface_get_target_ext.htm">surface_get_target_ext</a></li>
    <li><a href="surface_reset_target.htm">surface_reset_target</a></li>
    <li><a href="surface_copy.htm">surface_copy</a></li>
    <li><a href="surface_copy_part.htm">surface_copy_part</a></li>
    <li><a href="surface_depth_disable.htm">surface_depth_disable</a></li>
    <li><a href="surface_get_height.htm">surface_get_height</a></li>
    <li><a href="surface_get_width.htm">surface_get_width</a></li>
    <li><a href="surface_get_texture.htm">surface_get_texture</a></li>
    <li><a href="surface_get_depth_disable.htm">surface_get_depth_disable</a></li>
    <li><a href="surface_getpixel.htm">surface_getpixel</a></li>
    <li><a href="surface_getpixel_ext.htm">surface_getpixel_ext</a></li>
    <li><a href="surface_free.htm">surface_free</a></li>
    <li><a href="surface_save.htm">surface_save</a></li>
    <li><a href="surface_save_part.htm">surface_save_part</a></li>
  </ul>
  <p> </p>
  <p>The following functions exist for drawing surfaces:</p>
  <p class="note"><b>NOTE: </b>When working with surfaces there is the possibility that they can cease to exist at any time due to them being stored in texture memory. You should <b>ALWAYS</b> check that a surface exists using <span style="font-size:1px;"><a href="surface_exists.htm"><tt style="font-size: 14px">surface_exists()</tt></a></span> before
    referencing them directly.</p>
  <p> </p>
  <ul class="colour">
    <li><a href="draw_surface.htm">draw_surface</a></li>
    <li><a href="draw_surface_ext.htm">draw_surface_ext</a></li>
    <li><a href="draw_surface_part.htm">draw_surface_part</a></li>
    <li><a href="draw_surface_part_ext.htm">draw_surface_part_ext</a></li>
    <li><a href="draw_surface_stretched.htm">draw_surface_stretched</a></li>
    <li><a href="draw_surface_stretched_ext.htm">draw_surface_stretched_ext</a></li>
    <li><a href="draw_surface_tiled.htm">draw_surface_tiled</a></li>
    <li><a href="draw_surface_tiled_ext.htm">draw_surface_tiled_ext</a></li>
    <li><a href="draw_surface_general.htm">draw_surface_general</a></li>
  </ul>
  <p> </p>
  <p>Finally, you have two functions for storing and retrieving surfaces in <a href="../../Buffers/Buffers.htm">Buffers</a>:</p>
  <p> </p>
  <ul class="colour">
    <li><a href="../../Buffers/buffer_get_surface.htm">buffer_get_surface</a></li>
    <li><a href="../../Buffers/buffer_set_surface.htm">buffer_set_surface</a></li>
  </ul>
  <p> </p>
  <p>As mentioned above, GameMaker Studio 2 doesn&#39;t actually render most things to the screen directly, but instead it renders them to the <b>application surface</b>. This is essentially a surface - just like any that you can make yourself using the
    surface functions - and as such it can be manipulated, drawn to, sent to shaders, etc... Basically, anything that you would normally do with a surface you created can also be applied to the application surface.</p>
  <p class="note"><b>NOTE</b>: The only thing you <b>cannot</b> do with the application surface is free it. It always exists, although the index value to access it may change.</p>
  <p>When you run your game, this surface is created the first time that the <a href="../../../../The_Asset_Editors/Object_Properties/Draw_Events.htm">draw event</a> is called in each new room that you enter, which means that nothing is drawn until that
    point. However, you can still get the application surface position and resize it in the <b>Create Event</b> or any other event without getting any errors and the values used will be relevant to the surface when it is created. The actual sequence of
    events for the creation and drawing of the application surface is as follows:</p>
  <ul class="colour">
    <li>Pre-draw event<br/>          --- &gt; <b>the application surface is created (if it doesn&#39;t exist) and the render target is set</b></li>
    <li><b></b>For each visible view port, or, if no views ports are active, once
      <ul class="colour">
        <li>Draw begin event</li>
        <li>Draw event</li>
        <li>Draw end event<br/>         --- &gt; <b>the application surface render target is reset here</b></li>
      </ul>
    </li>
    <li><b></b>Post draw event<br/>         --- &gt; <b>the application surface is now drawn to the <a class="tooltip" title="The display buffer is the &#39;canvas&#39; where everything is finally drawn. Some events target this directly (like the Pre Draw event), while others will first draw to the application surface and then draw that to the display buffer.">display buffer</a> by default<br/>
	                 </b>(although you can switch this off using <span class="inline"><a href="application_surface_draw_enable.htm">application_surface_draw_enable()</a></span>)</li>
    <li><b></b>Draw GUI begin event</li>
    <li>Draw GUI event</li>
    <li>Draw GUI end event</li>
  </ul>
  <p>The use of this surface means that you can easily create incredible transitions using shaders, or take the screen and wrap it around a 3D form, or simply scale a low-res game up to any resolution screen... The possibilities are endless!</p>
  <p>To access this surface, you need to use the built-in global variable <tt>application_surface</tt> which is explained on the following page:</p>
  <p> </p>
  <ul class="colour">
    <li><a href="application_surface.htm">application_surface</a></li>
  </ul>
  <p> </p>
  <p>You also have a few specialist functions that are designed <em>only </em>for use with the application surface:</p>
  <p> </p>
  <ul class="colour">
    <li><a href="application_surface_enable.htm">application_surface_enable</a></li>
    <li><a href="application_surface_is_enabled.htm">application_surface_is_enabled</a></li>
    <li><a href="application_get_position.htm">application_get_position</a></li>
    <li><a href="application_surface_draw_enable.htm">application_surface_draw_enable</a></li>
  </ul>
  <p> </p>
  <p> </p>
  <p> </p>
  <div class="footer">
    <div class="buttons">
      <div class="clear">
        <div style="float:left">Back: <a href="../Drawing.htm">Drawing</a></div>
        <div style="float:right">Next: <a href="../Lighting/Lighting.htm">Lighting</a></div>
      </div>
    </div>
    <h5>© Copyright YoYo Games Ltd. 2020 All Rights Reserved</h5>
  </div>
  <!-- KEYWORDS
Surfaces
app surface
application surface
-->
  <!-- TAGS
surfaces_functions
-->

</body></html>