<?xml version='1.0' encoding='UTF-8'?>

<?xml-stylesheet href="./_c74_tut.xsl" type="text/xsl"?>
<chapter name="Tutorial 40: Drawing in OpenGL using jit.gl.sketch">
<setdocpatch name="40jSketch" patch="40jSketch.maxpat"/>

<previous name="jitterchapter39">Spatial Mapping</previous>
<next name="jitterchapter41">Shaders</next>
<parent name="jitindex">Jitter Tutorials</parent>



<h1>Tutorial 40: Drawing in OpenGL using jit.gl.sketch</h1>
<p>The OpenGL capabilities of Jitter provide us with a variety of tools for creating animated scenes in three dimensions. The Jitter OpenGL objects we&#x2019;ve looked at thus far each perform a fairly straightforward task, be it creating simple geometries (<o>jit.gl.gridshape</o> and <o>jit.gl.plato</o>), importing <i>OBJ</i> models (<o>jit.gl.model</o>), or manipulating the position of objects and scenes (<o>jit.gl.handle</o>). More complex scenes can be built by using several of these objects at once. After a certain point, however, it may make sense to work with an object that understands OpenGL commands directly and can be used to perform a large number of drawing commands at once. This object is <o>jit.gl.sketch</o>, and it is the subject of this Tutorial.</p>

<p>The <o>jit.gl.sketch</o> object interfaces with the OpenGL system in Jitter just as other OpenGL objects; as a result, it may help to review <i><link type="tutorial" module="jit" name="jitterchapter30">Tutorial 30:</link> Drawing 3D Text</i> and <i><link type="tutorial" module="jit" name="jitterchapter31">Tutorial 31:</link> Rendering Destinations</i> before we begin. In addition, the messages and attributes understood by <o>jit.gl.sketch</o> bear a strong resemblance to the methods and properties of the JavaScript sketch object used in the Max <o>jsui</o> object. <i><link type="tutorial" module="max" name="javascriptchapter04">Designing User Interfaces</link></i> will give you some additional information on the capabilities of OpenGL vector graphics that is common to both of these systems.</p>

<p>The majority of the messages used by <o>jit.gl.sketch</o> are slightly modified versions of standard functions within the OpenGL API. The entire API is outside the scope of this Tutorial; however, the standard reference for these functions (the OpenGL &#x201C;Redbook&#x201D;) is available online at:</p>

<p><a href="http://www.opengl.org/sdk/docs/man4/">http://www.opengl.org/sdk/docs/man4/</a></p>

<p>Converting between OpenGL code as given in the &#x201C;Redbook&#x201D; and elsewhere (in the C programming language) and messages to <o>jit.gl.sketch</o> is reasonably straightforward if the following conventions are kept in mind:</p>

<bullet>All OpenGL commands are lowercase in <o>jit.gl.sketch</o>. Thus the OpenGL function <i>glColor()</i> becomes the Max message <m>glcolor</m> sent to <o>jit.gl.sketch</o>.</bullet>
<bullet>OpenGL symbolic constants, in addition to being lowercase, lose their &#x201C;GL_&#x201D; prefix, so that <i>GL_CLIP_PLANE1</i> (in OpenGL) becomes <m>clip_plane1</m> when used with <o>jit.gl.sketch</o>, for example.</bullet>
<p>In addition to the basic OpenGL API, <o>jit.gl.sketch</o> also understands a number of high-level drawing commands to instruct the object to render basic shapes and perform vector graphics-style drawing operations.</p>

<bullet>Open the tutorial patch.</bullet>
<p>The Tutorial patch consists of a series of Jitter objects used for rendering in OpenGL: a <o>jit.gl.render</o> object, a <o>jit.pwindow</o> object, and a <o>jit.gl.sketch</o> object. The <o>jit.gl.sketch</o> object is sent messages from a <o>bpatcher</o> object containing <o>message</o> box objects containing lists of commands. Different views of the <o>bpatcher</o> can be obtained by selecting different offsets from the <o>umenu</o> object connected to it. In this Tutorial we'll step through the different sections of the <o>bpatcher</o> one-by-one and look at the messages contained in each view.</p>

<illustration><img src="images/jitterchapter40a.png"/>Our <o>jit.gl.sketch</o> object receiving messages from within a <o>bpatcher</o>.</illustration>
<bullet>Click on the <o>toggle</o> box labeled <i>Display</i> attached to the <o>qmetro</o> object at the top-left of the patcher.</bullet>
<p>By starting the <o>qmetro</o> object, we&#x2019;ve begun rendering our OpenGL scene. Our <o>jit.gl.render</o> object shares it&#x2019;s <m>name</m> (<i>sketchy</i>) with the <o>jit.pwindow</o> object and the <o>jit.gl.sketch</o> object in the patch. Because of this, the <o>jit.pwindow</o> will display anything drawn by the <o>jit.gl.render</o> object, which in turn will draw whatever the <o>jit.gl.sketch</o> object instructs it to draw.</p>

<h2>The command list</h2>
<bullet>Set the <o>umenu</o> object attached to the <o>bpatcher</o> to read &#x201C;one&#x201D;. The <o>bpatcher</o> object will show a <o>message</o> box containing a series of messages separated by commas. Click on the <o>message</o> box to send its contents to our <o>jit.gl.sketch</o> object.</bullet>
<p>A green triangle should appear in the <o>jit.pwindow</o> object.</p>

<illustration><img src="images/jitterchapter40b.png"/>A green triangle drawn with a sequence of messages to <o>jit.gl.sketch</o>.</illustration>
<div>
<techdetail><i>Technical Detail:</i> The <o>jit.gl.sketch</o> object works by maintaining a <i>command list</i> of OpenGL commands that are then executed every time the scene is drawn (in our patch, when the <o>jit.gl.render</o> object receives a <m>bang</m>). Most of the messages we send to <o>jit.gl.sketch</o> become part of this command list. This command list can be stored in the internal memory of the object or, if the <m>displaylist</m> attribute of <o>jit.gl.sketch</o> is set to <m>1</m>, it can be stored on the GPU of our computer. When working with large numbers of commands, turning on the <m>displaylist</m> attribute will speed up rendering time; however, new commands added onto the list may take longer to be added if they are sent very quickly, as they need to be loaded onto the GPU.</techdetail>
</div>
<p>Our first <o>message</o> box sends the following messages in sequence to <o>jit.gl.sketch</o>:</p>


<code>reset,
glcolor 0 1 0 1,
glbegin line_loop,
glvertex -0.5 -0.5,
glvertex 0 0.5,
glvertex 0.5 -0.5,
glend</code>
<p>The <m>reset</m> message to <o>jit.gl.sketch</o> simply tells the object to clear its command list and reinitialize itself. What follows are a sequence of OpenGL commands. The <m>glcolor</m> command tells <o>jit.gl.sketch</o> to change the color it uses to draw. As with all OpenGL objects in Jitter, these colors are floating-point values in RGBA (red, green, blue, alpha) order; thus, <m>glcolor 0 1 0 1</m> tells <o>jit.gl.sketch</o> to draw in a fully opaque (alpha=1) green.</p>

<p>The <m>glbegin</m> message tells <o>jit.gl.sketch</o> to interpret what follows as instructions defining an <i>object</i>. The argument to <m>glbegin</m> specifies the <i>drawing primitive</i> to use when rendering the shape. The primitive we&#x2019;ve chosen, <m>line_loop</m>, will take a set of points (called <i>vertices</i>) and connect them with lines, completing the shape by connecting the last vertex to the first vertex again. Thus in a shape with four points A, B, C, and D, our object will contain lines from A to B, B to C, C to D, and D to A.</p>

<p>The <m>glvertex</m> messages contain the coordinates of the points in our shape. If only two coordinates are given, they are interpreted as <i>x</i> and <i>y</i> values. If three coordinates are given, the last value is interpreted as a <i>z</i> coordinate. The <m>glend</m> message tells <o>jit.gl.sketch</o> that we&#x2019;ve finished defining the shape. We could then move on to another shape (or execute other commands) if we so desired.</p>

<p>Step one of our patch therefore resets the object, sets the color to green, and instructs it to draw an outlined shape with three vertices connected to one another. These messages (with the exception of the <m>reset</m> message) form the command list for <o>jit.gl.sketch</o> for the image we see in the <o>jit.pwindow</o>.</p>

<h2>More about drawing primitives</h2>
<bullet>Select the <o>umenu</o> object and set it to &#x201C;two&#x201D;. Click on the <o>message</o> box that appears in the <o>bpatcher</o>.  Our outlined triangle should disappear and a filled green triangle should take its place.</bullet>
<illustration><img src="images/jitterchapter40c.png"/><i>A filled green triangle.</i></illustration>
<p>The list of commands in our <o>message</o> box is very similar to the first one:</p>

<code>
reset,
glcolor 0 1 0 1,
glbegin triangles,
glvertex -0.5 -0.5,
glvertex 0 0.5,
glvertex 0.5 -0.5,
glend</code>
<p>Once again, we reset the object and then define a color (green) and an object with three vertices to be drawn. The only difference is the drawing primitive specified as an argument to the <m>glbegin</m> message. In this example, we&#x2019;re using <m>triangles</m> as our drawing primitive. This tells <o>jit.gl.sketch</o> to interpret triplets of vertices as <i>triangles</i>. Rather than outlining the shape as we did before, we&#x2019;ve now instructed <o>jit.gl.sketch</o> to generate a <i>polygon</i>. As a result, the interior of our vertices is filled with the specified <m>glcolor</m> (green). </p>

<div>
<techdetail>There are ten (10) different drawing primitives recognized by OpenGL and, as a result, by objects such as <o>jit.gl.render</o> and <o>jit.gl.sketch</o>. They are <i>points</i>, <i>lines</i>, <i>line_strip</i>, <i>line_loop</i>, <i>triangles</i>, <i>triangle_strip</i> (abbreviated <i>tri_strip</i>), <i>triangle_fan</i> (abbreviated <i>tri_fan</i>), <i>quads</i>, <i>quad_strip</i>, and <i>polygon</i>. These primitives each specify the algorithm by which a series of vertices will be connected. <i><link type="tutorial" module="jit" name="jitterchapter37">Tutorial 37:</link> Geometry Under the Hood</i> and Table 2-2 and Figure 2-7 of the OpenGL &#x201C;Redbook&#x201D; give descriptions and examples of each and describe their common uses.</techdetail>
</div>
<bullet>Set the <o>umenu</o> object in the Tutorial patch to &#x201C;three&#x201D; and click the <o>message</o> box that appears in the <o>bpatcher</o>. A triangle with a rainbow surface will appear in place of the solid green triangle.</bullet>
<illustration><img src="images/jitterchapter40d.png"/>A shape with different colored vertices.</illustration>
<p>In this command list, we&#x2019;ve embedded <m>glcolor</m> commands for each vertex of our triangle:</p>

<code>
reset,
glbegin triangles,
glcolor 1 0 0 1,
glvertex -0.5 -0.5,
glcolor 0 1 0 1,
glvertex 0 0.5,
glcolor 0 0 1 1,
glvertex 0.5 -0.5,
glend</code>
<p>As a result, our <o>jit.gl.sketch</o> object sets our three vertices to red, green, and blue, respectively, and fills in the interior surface with a color gradient that fades smoothly between the three colors. The <m>smooth_shading</m> attribute of <o>jit.gl.sketch</o> allows this behavior when set to <m>1</m> (as is the case with the <o>jit.gl.sketch</o> object in our Tutorial patch).</p>

<bullet>Set the <o>umenu</o> object in the Tutorial patch to &#x201C;four&#x201D;. Set the <o>umenu</o> <i>inside</i> the <o>bpatcher</o> to &#x201C;fill&#x201D;. Our <o>jit.pwindow</o> now contains a square with a rainbow-colored surface. Set the <o>umenu</o> to &#x201C;outline&#x201D;. Now we only see rainbow-colored lines outlining the shape, as well as a diagonal across it.</bullet>
<illustration><img src="images/jitterchapter40e.png"/>A square made up of connected triangles, filled and unfilled.</illustration>
<p>This section of the <o>bpatcher</o> allows us to see how a drawing primitive works to make a more complex shape. We begin our command list with the <m>glpolygonmode</m> command, which tells <o>jit.gl.sketch</o> whether to fill in complete polygons or leave them as outlines, exposing the skeleton that defines how the vertices are connected. The first argument to <m>glpolygonmode</m> defines whether we&#x2019;re talking about the <m>front</m> of the shape, the <m>back</m> of the shape, or both (<m>front_and_back</m>, as we&#x2019;re using here). The second argument defines whether that side of the shape will be filled (<m>fill</m>) or left outlined (<m>line</m>). The <m>poly_mode</m> attribute of the Jitter OpenGL objects accomplishes the same thing.</p>

<p>After we&#x2019;ve reset and decided how we want our shape drawn (filled or outlined), we supply a shape description:</p>

<code>
glbegin tri_strip,
glcolor 1 0 0 1,
glvertex -0.5 -0.5,
glcolor 0 1 0 1,
glvertex -0.5 0.5,
glcolor 0 0 1 1,
glvertex 0.5 -0.5,
glcolor 1 1 1 1,
glvertex 0.5 0.5,
glend</code>
<p>As with the triangle in our previous example, we provide a <m>glcolor</m> for each <m>glvertex</m> (in this example red, green, blue, and white for the four points of the square). The <m>tri_strip</m> drawing primitive used as an argument to <m>glbegin</m> tells <o>jit.gl.sketch</o> to draw the shape as a series of triangles where the last two vertices of a triangle are recycled into the next triangle. Thus a polygon with six vertices A, B, C, D, E, and F would be drawn as <i>four</i> triangles using the <m>tri_strip</m> primitive: ABC, CBD, CDE, and EDF (the ordering ensures that the triangles are all drawn with the same orientation). In our code, we get a shape with two triangles that when connected and filled appear to us as a square.</p>

<h2>Rotation, translation, and scaling</h2>
<bullet>Set the <o>umenu</o> in the Tutorial patch to &#x201C;five&#x201D;. Click and drag the <o>number</o> box in the <o>bpatcher</o> slowly upwards from <m>0</m> to <m>360</m>. The filled rainbow square from the previous example will reappear and rotate in a counter-clockwise direction.</bullet>

<illustration><img src="images/jitterchapter40f.png"/>A rotation matrix applied to an object.</illustration>
<p>In addition to defining shapes containing vertices and colors, <o>jit.gl.sketch</o> allows us to manipulate something called the modelview matrix so our objects can be animated and scaled. Our command list sets this up for us by supplying some additional commands:</p>

<code>
reset,
glpushmatrix,
glrotate $1 0 0 1, </code>
<p>After resetting everything, we send the  <m>glpushmatrix</m> message, which copies our current <m>modelview</m> matrix onto a stack, allowing us to return to it later. This allows us to create nested translations for drawing complex objects. For example, we could draw a series of polygons, each with rotations relative to the <i>previous</i> polygon; in this way we could generate sequences of shapes that have the same orientation with respect to each other but could then all be rotated with respect to another group of shapes. The use of a stack for this process greatly aids in modeling as we can use simple face-on coordinates for the vertices in our shapes and then tell the renderer to compute the rotations for us. The <m>glrotate</m> command specifies the <i>degrees</i> of rotation for our shape followed by three values that specify the <i>axis</i> of rotation as an <i>xyz</i> vector. Thus we&#x2019;re rotating our object around the <i>z</i> axis (which spins the shape along the <i>x-y</i> plane of the screen).</p>

<p>Following the rotation, we continue with our command list as in the previous example. At the end of the shape specification, we complete our command list with the <m>glpopmatrix</m> command, which returns our <o>jit.gl.sketch</o> object to the previous rotation. New commands added to the command list after that would then use the original rotation vector, not the one we&#x2019;ve applied to our shape.</p>

<bullet>Set the <o>umenu</o> to &#x201C;six&#x201D;, and manipulate the <o>number</o> box objects attached to the <o>pak</o> object inside the <o>bpatcher</o>. We can now rotate our square around all three axes. In addition, lines are rendered to provide us with unit vectors to guide us in our rotation.</bullet>
<illustration><img src="images/jitterchapter40g.png"/>A rotation matrix applied to multiple objects (a square and three vectors).</illustration>
<p>Our command list here sets up a new <m>modelview</m> matrix and performs the rotation three times in series:</p>

<code>
reset,
glpushmatrix,
glrotate $1 1 0 0,
glrotate $2 0 1 0,
glrotate $3 0 0 1, </code>
<p>This allows us to rotate our shape along the <i>x</i> axis, <i>y</i> axis, and <i>z</i> axis in sequence according to the values of the <o>number</o> box objects in our patch. We then create <i>four</i> objects using this rotation before we send a <m>glpopmatrix</m> to return to our original orientation. After our square is rendered, we create three two-vertex lines in different colors oriented along the same axes as the plane:</p>

<code>
glcolor 1 0 0 1, glbegin lines, glvertex 0 0 0, glvertex 1 0 0, glend,
glcolor 0 1 0 1, glbegin lines, glvertex 0 0 0, glvertex 0 1 0, glend,
glcolor 0 0 1 1, glbegin lines, glvertex 0 0 0, glvertex 0 0 1, glend, \nglpopmatrix</code>
<p>The drawing primitive <m>lines</m> simply connects all the vertices in the shape (unlike <m>line_loop</m>, it does <i>not</i> connect the last vertex back to the first). Notice that because these objects (and our square) are all within the same <m>modelview</m> matrix, they all share the same rotation.</p>

<bullet>Set the <o>umenu</o> to &#x201C;seven&#x201D; and manipulate the <o>number</o> box objects in the <o>bpatcher</o>.  The colored square can be moved along the <i>x</i> and <i>y</i> axes of the space.</bullet>
<illustration><img src="images/jitterchapter40h.png"/>A translation matrix applied to our shape.</illustration>
<p>In addition to image rotation, the <m>modelview</m> matrix can apply translation of an image. This allows us to specify vertices for our object centered around (0, 0) and then move the object anywhere we want in the space. The <m>gltranslate</m> message in our command list performs this function, taking as arguments the <i>x</i> and <i>y</i> offsets that will be applied to every vertex in the shape(s) affected by the transformation.</p>

<bullet>Set the <o>umenu</o> to &#x201C;eight&#x201D; and manipulate the <o>number</o> box objects in the <o>bpatcher</o>. The colored square can be stretched along both axes.</bullet>
<illustration><img src="images/jitterchapter40i.png"/>Our object transformed by scaling.</illustration>
<p>Just as we can rotate and translate a shape or shapes, we can also control their scaling with the <m>glscale</m> message. The vertices in our shape are <i>multiplied</i> by the arguments to the <m>glscale</m> message (specified as <i>x</i>, <i>y</i>, and optional <i>z</i> scaling factors).</p>

<div>
<techdetail>The <i>order</i> in which you provide <m>glrotate</m>, <m>gltranslate</m>, and <m>glscale</m> commands to <o>jit.gl.sketch</o> is important, as they are processed <i>sequentially</i> and <i>cumulatively</i> to create the final transformation of the affected objects. For example, say you have a vertex at coordinates (0.5, 1). If you translate that vertex by (0.2, 0.2) and then scale it by (1.5, 1.5) the vertex will end up at (1.6, 1.7). If you reverse the order of those operations (scale <i>then</i> translate), your vertex will end up at (0.95, 1.7).</techdetail>
</div>

<h2>Summary</h2>
<p>The <o>jit.gl.sketch</o> object gives us access to the powerful OpenGL API, allowing us to define and execute an OpenGL command list within a Max patch. Lists of vertices, specified by <m>glvertex</m> messages and bracketed by <m>glbegin</m> and <m>glend</m> messages, can be used to specify the shapes of objects. The <m>glbegin</m> command takes a <i>drawing primitive</i> as its argument that defines the algorithm by which the vertices are connected and filled. You can use the <m>glpolygonmode</m> command to expose the outlined structure of a shape, and you can color entire shapes or vertices using <m>glcolor</m> messages. You can perform rotation, translation, and scaling of a defined shape by sending the <m>glmatrixview</m> command with the argument <m>modelview</m>. Using <m>glrotate</m>, <m>gltranslate</m>, and <m>glscale</m> commands, you can then specify a viewing transformation. The <m>glpushmatrix</m> and <m>glpopmatrix</m> commands allow you to define a <i>stack</i> of these transformations so that you can change the rotation, position, and size of shapes either independently or in nested groups within a sequence of OpenGL commands.</p>

	<seealsolist>
		<seealso name="bpatcher">Embed a visible subpatch inside a box</seealso>
		<seealso name="jit.gl.render">Render Open GL</seealso>
		<seealso name="jit.gl.sketch">GL parallel to lcd</seealso>
		<seealso name="jit.pwindow">In-Patcher Window</seealso>
	</seealsolist>
	</chapter>
