<?xml version='1.0' encoding='UTF-8'?>

<?xml-stylesheet href="./_c74_tut.xsl" type="text/xsl"?>
<chapter name="Tutorial 31: Rendering Destinations">
<setdocpatch name="31jRenderDestinations" patch="31jRenderDestinations.maxpat"/>

<previous name="jitterchapter30">Drawing 3D text</previous>
<next name="jitterchapter32">Camera View</next>
<parent name="jitindex">Jitter Tutorials</parent>



<h1>Tutorial 31: Rendering Destinations</h1>
<p>In the previous tutorial, we saw how to draw OpenGL graphics into a <o>jit.window</o> using  the <o>jit.gl.render</o> object. Now we will look at the other kinds of destinations into which a <o>jit.gl.render</o> object can draw, what to use them for, and how to switch between destinations. </p>

<p>Open the tutorial and double-click the <m>Render_Destinations</m> subpatch to open it.</p>

<p>In the upper left of the patch is a <o>jit.gl.render</o> object with an argument of <m>inky</m>, along with other objects.</p>

<bullet>Click on the <o>toggle</o> in the upper left of the patch labeled <i>Start Rendering</i>.</bullet><br/>
<p>You should see a red ball appear in the <o>jit.window</o> object. The <o>jit.gl.gridshape</o> object is drawing the ball. Its first argument, <m>inky</m>, specifies the drawing context currently being drawn by the <o>jit.gl.render</o> object to the <o>jit.window</o>. The other arguments set the <m>color</m> and <m>scale</m> attributes of the ball.</p>


<illustration><img src="images/jitterchapter31a.png"/>Draw a red ball in the window named <m>inky</m></illustration>

<h2>Drawing and Swapping Buffers </h2>

<p>Clicking the <o>toggle</o> starts the <o>qmetro</o> object, which sends <m>bang</m> messages to the object <link name="trigger" type="refpage">t</link> <m>b b erase</m>. This object first sends an <m>erase</m> message followed by a <m>bang</m> message to the <o>jit.gl.render</o> object, and then a <m>bang</m> message that is used elsewhere in the patch. </p>

<p>When the <o>jit.gl.render</o> object receives the <m>bang</m> message, it draws all of the GL group objects which share its destination, then copies its offscreen buffer, if any, to the screen. An <i>offscreen buffer</i> is an area of memory not visible on the screen, the same size as the drawing destination. By default, all drawing contexts have an offscreen buffer. Drawing is done into the buffer, which must then be copied to the screen in order to be seen. </p>

<p>The offscreen buffer makes flicker-free drawing and animation possible, as we see here. Even though the buffer is being erased before the red ball is drawn each time, we never see the buffer in its erased state. To see what drawing looks like without the offscreen buffer, click on the <o>message</o> box <m>doublebuffer 0</m> in the upper right of the patch . You will probably see the image start to flicker. This happens because the <m>erase</m> message now causes the window itself to be erased, not the offscreen buffer. The window remains blank for a short but indeterminate period of time before the red ball is drawn, so you can see the area under the ball flickering between red and the dark gray of the erased window. Click the <o>message</o> box <m>doublebuffer 1</m> to remake the offscreen buffer and stop the flickering. </p>

<h2>Setting Fullscreen Mode</h2>

<p>The <link name="patcher" type="refpage">p</link> <m>fullscreen</m> subpatch contains a <o>key</o> object, a <o>select</o> object, a <o>toggle</o>, a <o>message</o> box and an <o>outlet</o> object that sends the results of the subpatch to the <o>jit.window</o> object. This is standard Max stuff, so we won&#x2019;t go over it in too much detail&#x2014; the result is that the escape key toggles between sending the messages <m>fullscreen 0</m> and <m>fullscreen 1</m> to the <o>jit.window</o> object. (See the "Full Screen Display" section of <link type="tutorial" module="jit" name="jitterchapter14">Tutorial 14</link>.)</p>

<bullet>Press the 'esc' key to change the <o>jit.window</o> object to fullscreen mode and back. </bullet>
<div>
<techdetail>The escape key seems to be a common way to toggle fullscreen mode, so we&#x2019;ve used this setup in many of the example patches. It&#x2019;s important to note, however, that this is just a convention&#x2014;there&#x2019;s nothing built into Jitter that forces you to use one key or another for this purpose. </techdetail>
</div>
<p>You can use the <m>fsmenubar</m> attribute in conjunction with the <m>fullscreen</m> message to hide the menubar in addition to covering the screen. If the <o>jit.window</o> object has the <m>fsmenubar</m> attribute set to 0, the menubar will be hidden</p>

<h2>Setting a jit.pwindow Destination</h2>

<p>The <o>jit.gl.render</o> object can draw to two different kinds of destinations. This patch contains an object example of the two: a <o>jit.window</o> and a <o>jit.pwindow</o>. Right now we are rendering to the <o>jit.window</o> object. To change the destination to the <o>jit.pwindow</o> object, we need to first <m>name</m> the <o>jit.pwindow</o> object and then set the destinations of the <o>jit.gl.render</o> object and the <o>jit.gl.gridshape</o> object.</p>

<bullet>Click on the <o>message</o> box name blinky above the lefthand <o>jit.pwindow</o> objects.</bullet>

<p>This names the <o>jit.pwindow</o> object, which allows it to be used as a rendering destination.
To switch the drawing to this destination, we need to send messages to both the
<o>jit.gl.render</o> object and the <o>jit.gl.gridshape</o> object, telling them about the new destination.</p>

<bullet>Click on the <o>message</o> box <m>blinky</m> in the <i>Switch Destinations</i> section of the patch. </bullet>
<p>The symbol <m>drawto</m> is prepended to the message <m>blinky</m>, and the result is sent to the <link name="send" type="refpage">s</link> <m>dest</m>
object. Two objects receive this message &#x2014; <o>jit.gl.gridshape</o> and <link name="trigger" type="refpage">t</link> <m>l b erase</m>. The <o>trigger</o> object
sends a sequence of messages to the <o>jit.gl.render</o> object, which tell it to:</p>
<ol>
<li>Erase its current destination&#x2019;s draw buffer</li>

<li>Swap that buffer to the screen, visibly clearing the old destination, and</li>

<li>Switch future drawing to the new destination.</li>
</ol>
<p>The result is that the red ball is displayed on the <o>jit.pwindow</o> object at the right of the patch.</p>

<illustration><img src="images/jitterchapter31b.png"/>Viewing our rendered output in a <o>jit.pwindow</o> object</illustration>

<h2>Rendering to a Jitter Matrix</h2>

<bullet>Open the <m>Matrix_Rendering</m> subpatch.</bullet>
<p>You may want to create a rasterized image of your OpenGL scene so that any of Jitter's video-processing effects can be applied to the image. You can do this by using the <m>@output_matrix</m> attribute of the <o>jit.world</o> object. Click the <o>toggle</o> labeled <i>Start Rendering</i>.</p>

<p>You should see a cyan ball on a light gray background. This is because the red ball image generated by OpenGL is processed through the <o>jit.op</o> object, which subtracts each color component from 255, inverting the image.</p>

<illustration><img src="images/jitterchapter31c.png"/>Utilizing the matrix output of <o>jit.world</o></illustration>

<techdetail>
	Hardware vs. Software Rendering: One of the great advantages about using OpenGL for rendering graphics is that most of the work can be done by the graphics accelerator hardware in your computer, freeing the CPU up for other work such as generating audio. When drawing into jit.window objects or jit.pwindow objects, the hardware renderer can be used. Unfortunately, due to limitations of the current system software the hardware renderer cannot draw directly into jit.matrix objects. Note that drawing into Jitter matrices is significantly slower than drawing to jit.window or jit.pwindow objects, especially for complex scenes or those involving textures.
</techdetail>

<h2>Multiple Renderers and Drawing Order</h2>

<bullet>Open the <m>More_Render_Destinations</m> subpatch.</bullet>
<techdetail>
	Note that the <o>jit.gl.gridshape</o> objects have their z scaling set to 0. This essentially makes them 2D objects.
</techdetail>
<p>To move an OpenGL scene to a different destination, the <o>jit.gl.render</o> object as well as any GL group objects involved in drawing the scene must receive the <m>drawto</m> message. Why not just send a message to the renderer, telling it to move the entire scene? The reason is that each GL group object can have an independent destination, as well as each renderer. Objects in the GL group can be moved between multiple renderers. To see an example of why this might be useful, please look at the right-hand portion of the patch for this tutorial.</p>

<p><i>At the right are three </i><o>jit.pwindow</o> objects named <m>A</m>, <m>B</m> and <m>C</m>. The <o>message</o> box objects  above them are not strictly necessary, because once a <o>jit.pwindow</o> object has been named, its name is stored with it in the patch. But they are useful here as labels and as a reminder of what messages to send to name the objects.</p>

<p>There are also three <o>jit.gl.render</o> objects in the patch. Each of them is pointed at a different destination.</p>

<bullet>Click the <o>toggle</o><m> labeled </m><i>Start Rendering</i><m>. </m></bullet>

<p>This repeatedly sends the <m>erase</m> message followed by a <m>bang</m> message to each of the three renderers. You should see a yellow circle within a blue circle in the topmost drawing destination. This simple OpenGL scene is created by the two <o>jit.gl.gridshape</o> objects in the bottom left of the patch. We can move each of these objects to any of the three drawing destinations present.</p>

<illustration><img src="images/jitterchapter31d.png"/>Rendering to <o>jit.pwindow</o> A</illustration>

<bullet>Click the topmost <o>message</o> box<m> reading </m><m>B</m><m> in the </m><i>Switch Destinations</i> section of the tutorial patch. This changes the destination of the blue circle to the draw context named "B"&#x2014;it now appears on the center <o>jit.pwindow</o>.</bullet><br/>
<bullet>Click the lower <o>message</o> box<m> reading </m><m>B</m><m> in the </m><i>Switch Destinations</i> section of the tutorial patch. This changes the destination of the yellow circle to the draw context named "B". The two objects are reunited.</bullet><br/>

<p>Each time a <o>jit.gl.render</o> object receives a <m>bang</m> message, it draws all of the GL group objects that have been added to its context. It draws the objects in the order in which they were added to the context. In this case, the yellow circle was added to the draw context named "B" after the blue circle, so it appears on top. To change this order, we can send the message <m>drawto B</m> to the <o>jit.gl.gridshape</o> object drawing the blue circle again. This will remove it from its present place in the list of objects for the context named <m>B</m>, and add it again at the end of the list.</p>

<bullet>Click the upper <o>message</o> box<m> reading </m><m>B</m><m> in the </m><i>Switch Destinations</i> section of the tutorial patch again. The blue circle should now obscure the yellow circle.</bullet>
<illustration><img src="images/jitterchapter31e.png"/>The blue circle obscures the yellow one</illustration>

<h2>Summary</h2>
<p>We have introduced a flexible system for creating multiple OpenGL <i>renderers and drawing destinations</i>, and for moving objects in the GL group between them using <m>drawto</m> messages. </p>

<p>Two Jitter objects can function as drawing destinations: <o>jit.window</o> and <o>jit.pwindow</o>. Each kind of destination has different uses. A <o>jit.window</o> object can be moved to different monitors and quickly enlarged to cover the screen. A <o>jit.pwindow</o> object keeps its location in the patch. Futhermore, we can use the matrix output of the <o>jit.world</o> object to create a rasterized image of the 3D scene, to which further video processing may be applied. </p>

	<seealsolist>
		<seealso display="Video and Graphics Tutorial 4: Adding 3D Objects" module="Video and Graphics" name="jitterchapter00f_Adding 3D Objects" type="tutorial" />
		<seealso display="GL Contexts" module="core" name="jitter_gl_contexts" type="vignette" />
		<seealso name="jit.gl.gridshape">Generate simple geometric shapes as a connected grid</seealso>
		<seealso name="jit.gl.render">Render Open GL</seealso>
		<seealso name="jit.matrix">The Jitter Matrix!</seealso>
		<seealso name="jit.pwindow">In-Patcher Window</seealso>
		<seealso name="jit.window">Display data in a Window</seealso>
		<seealso name="qmetro">Queue-based metronome</seealso>
	</seealsolist>
	</chapter>
