<?xml version='1.0' encoding='UTF-8'?>

<?xml-stylesheet href="./_c74_tut.xsl" type="text/xsl"?>
<chapter name="Tutorial 33: Polygon Modes, Colors and Blending">
<setdocpatch name="33jPolyColorBlend" patch="33jPolyColorBlend.maxpat"/>

<previous name="jitterchapter32">Camera View</previous>
<next name="jitterchapter34">Using Textures</next>
<parent name="jitindex">Jitter Tutorials</parent>



<h1>Tutorial 33: Polygon Modes, Colors and Blending</h1>

<p>In the previous tutorial, you saw how to position the camera and objects in the GL group to construct an OpenGL scene in Jitter. After understanding this tutorial, you&#x2019;ll be able to hide selected polygons of an OpenGL object based on their spatial orientations, draw selected polygons in filled and wireframe  modes, and add the results to the draw buffer using antialiasing and blending.</p>

<bullet>Open the tutorial patch. Click on the <o>toggle</o> box labeled &#x201C;Start Rendering.&#x201D;</bullet>
<p>You should see a gray sphere in the <o>jit.pwindow</o> in the tutorial patch. It is drawn by a <o>jit.gl.gridshape</o> object, connected to a <o>jit.gl.handle</o> object that allows you to control its rotation. The <o>jit.gl.handle </o> object's <m>auto_rotate</m> attribute is on, so once you rotate it the sphere will continue to rotate along the axis you set. If you like, give it a spin.</p>

<illustration><img src="images/jitterchapter33a.png"/>The gray sphere.</illustration>

<h2>Wireframe Mode and Culling Faces</h2>
<p>Just below the label &#x201C;OpenGL Objects to Render&#x201D; in the example patch is an object <o>pak</o> <m>poly_mode 1 1</m>. This object generates messages that set the polygon mode attribute of the <o>jit.gl.gridshape</o> object.</p>

<bullet>Click both <o>toggle</o> objects above the <o>pak</o> <m> poly_mode</m> object. You should see the gray sphere in wireframe mode.</bullet>
<illustration><img src="images/jitterchapter33b.png"/>The sphere in wireframe mode.</illustration>

<p>Turning wireframe mode on allows you to see clearly that the <o>jit.gl.gridshape</o> object approximates a sphere using polygons -- in this case, quadrilaterals. Every polygon drawn in OpenGL has a front side, defined as the side from which its vertices appear to wrap in a clockwise direction. Each polygon in a scene can, therefore, be categorized as either front-facing or back-facing, depending on whether its front side is pointed towards or away from the camera.</p>

<p>OpenGL can automatically hide either front-facing or back-facing polygons, which can serve to speed up drawing greatly or highlight certain aspects of data being visualized. In Jitter, you can control polygon visibility on an object-by-object basis using the <m>cull_face</m> attribute.</p>

<bullet>Set the <o>number</o> box above the <o>prepend</o><m>cull_face</m> object to <m>1</m>.</bullet>
<illustration><img src="images/jitterchapter33c.png"/>The front-facing polygons of the sphere.</illustration>
<p>The <m>cull_face</m> attribute of a GL group object can be set to <m>0</m><b>, </b><m>1</m> or <m>2</m>. A setting of <m>0</m> shows all polygons in the object. A setting of <m>1</m> hides the back-facing polygons. A setting of <m>2</m> hides the front-facing polygons. With the current setting of <m>1</m>, the wireframe sphere appears solid, because the <i>hidden lines</i> -- polygon edges that would not be visible if the sphere were made of a solid material -- are not drawn. The rotation (did you give it a spin?) convincingly depicts that of a real-world solid object.</p>

<bullet>Set the number box above the <o>prepend</o> <m>cull_face</m> object to <m>2</m>.</bullet>

<illustration><img src="images/jitterchapter33d.png"/>The back-facing polygons of the sphere.</illustration>

<p>Now the front-facing polygons are hidden. It&#x2019;s as if you are looking through the sphere and seeing only the inside part that faces towards you. You can see from this picture that the perspective is somewhat strange, but watching the rotation in the patch makes it really obvious that the scene is not drawn &#x201C;normally.&#x201D;</p>

<p>In general, setting <m>cull_face 1 </m> will do a good job of removing the polygons that should be hidden for solid, convex objects such as the sphere. But for objects that aren&#x2019;t solid, a combination of the front-facing and back-facing polygons may be in view.</p>

<bullet>Set the <o>number</o> box above the <o>prepend </o><m>cull_<b>face</b></m> object to <m>0</m> to show all the polygons. Set the left <o>toggle</o> object above the <o>pak</o> <m> poly_mode</m> object to <m>0</m> (off). Set the <o>umenu</o> above the <o>prepend</o> <m>shape</m> object to &#x201C;opencylinder&#x201D;.</bullet>

<illustration><img width="397" src="images/jitterchapter33e.png"></img>Open cylinder, with solid front-facing and back-facing polygons.</illustration>

<h2>RGBA Colors</h2>
<p>The colors of objects in the GL group are specified using the message <m>color R G B A</m>, where R is the red component of the color, B is blue, G is green, and A is the alpha or opacity component. All values range from <m>0</m> to <m>1</m>.</p>

<bullet>Set the  <o>number</o> box objects above the <o>pak </o> <m>color&#x2026;</m> object to the values <m>1., 0., 0., 0.5. </m> This specifies pure red at 50% opacity.</bullet>
<p>You will see the color of the cylinder turn red, but the opacity is not visible. This is because <i>blending</i>, the mixing of pixels with those previously in the draw buffer, is turned off by default.</p>

<bullet>Click the <o>toggle</o> box above the <m>blend_enable $1</m> <o>message</o> box to turn blending on for the <o>jit.gl.gridshape</o> object. You should see something like this:</bullet>

<illustration><img width="397" src="images/jitterchapter33f.png"></img>The red cylinder with blending enabled.</illustration>
<div>
<techdetail><b>ARGB vs. RGBA</b> If you&#x2019;ve been using Jitter&#x2019;s video-manipulation objects, you know that colors in those objects are stored in planes and specified in arguments in the order A, R, G, B. In the GL group of objects, the order is RGBA, with alpha last, as we&#x2019;re seeing here. This may seem odd, so you are due a bit of explanation. Jitter objects are tied as closely to native formats as possible in both the OpenGL and video domains, to allow the fastest possible processing. OpenGL stores colors of objects and vertices in RGBA format, and QuickTime stores its images in ARGB format. So the Jitter objects reflect this. If you want to combine OpenGL and video matrix processing in your patch, the <o>pack</o>, <o>unpack</o>, <o>jit.pack</o> and <o>jit.unpack</o> objects provide an easy way to convert between the two systems. You can also convert a matrix of char values from ARGB to RGBA by sending the matrix through a <o>jit.matrix</o> object with the <at>planemap</at> attribute set to <m>1 2 3 0</m> (effectively shifting all the planes by one). <link type="tutorial" module="jit" name="jitterchapter06">Tutorial 6</link> shows more examples of using the <at>planemap</at> attribute of the <o>jit.matrix</o> object.</techdetail>
</div>

<h2>Erase Color</h2>
<p>Right now, each time the <o>jit.gl.render</o> object receives the <m>erase</m> message, the draw buffer is filled with the dark gray that is the default erase color. You can set a different erase color using the RGBA number boxes above the renderer object. </p>

<bullet>Set the <o>number</o> boxes above the <o>pak</o> <m>erase_color</m> object to the values 0, 0, 0.5 and 0.1. The background changes to a dark blue (Red = 0, Green = 0, Blue = 0.5).</bullet>

<illustration><img width="397" src="images/jitterchapter33g.png"></img>The cylinder with a dark blue erase color. </illustration>

<h2>Blend Modes</h2>
<p>When the <m>blend_enable</m> attribute of an object in the GL group is on, each pixel is applied to the draw buffer using a <i>blend function</i>. The blend function is the basic operation in image compositing. It controls the application of new pixels, the <i>source,</i> over existing pixels, the <i>destination</i>. The function has two parts: a source blending factor and a destination blending factor. The source blending factor specifies how the source&#x2019;s contribution to the finished image should be computed. The destination blending factor specifies the destination&#x2019;s contribution. </p>

<p>Jitter recognizes eleven possible modes for blending factors. Some can be applied only to the source, some only to the destination, and some to both. Each mode specifies a different set of multiplier values for red, green, blue and alpha. The message <m>blend_mode [src_factor] [dest_factor] </m>allows you to specify both factors for any of the drawing objects in the GL group. </p>

<p><m> </m></p>

<div>
<techdetail><b>The Blend Modes</b> The source and destination blend factors are RGBA quadruplets which are multiplied componentwise by the RGBA values of the source and destination pixels, respectively. The corresponding components of the source and destination are added and then clamped to the range [<m>0, 1</m>] to produce the output pixel. </techdetail>
<techdetail>This table shows how the blend factors are calculated. The &#x201C;Mode&#x201D; column lists the number passed in the Jitter message <m>blend_mode [src_factor] [dest_factor].</m> The &#x201C;OpenGL name&#x201D; column lists the name of the mode. The &#x201C;Relevant to&#x201D; column lists whether the mode can apply to the source factor, the destination factor, or both. Finally, the &#x201C;Blend Factor Equation&#x201D; column specifies the actual formula that is used to calculate the pixel. The subscripts s and d refer to source and destination components, respectively. For example, R<sub>s</sub> refers to the red component of the source pixel.</techdetail><br/>
<table>
	<tr>
		<th>Mode</th>
		<th>OpenGl Name</th>
		<th>Relevant to</th>
		<th>   Blend Factor Equation</th>
	</tr>
	<tr>
		<td>0</td><td>GL_ZERO</td><td>both</td><td>(0, 0, 0, 0)</td>
	</tr>
	<tr>
		<td>1</td><td>GL_ONE</td><td>both</td><td>(1, 1, 1, 1)</td>
	</tr>
	<tr>
		<td>2</td><td>GL_DST_COLOR</td><td>source</td><td>(R<sub>d</sub>, G<sub>d</sub>, B<sub>d</sub>, A<sub>d</sub>)</td>
	</tr>
	<tr>
		<td>3</td><td>GL_SRC_COLOR</td><td>destination</td><td>(R<sub>s</sub>, G<sub>s</sub>, B<sub>s</sub>, A<sub>s</sub>)</td>
	</tr>
	<tr>
		<td>4</td><td>GL_ONE_MINUS_DST_COLOR </td><td>source</td><td>(1, 1, 1, 1)-(R<sub>d</sub>, G<sub>d</sub>, B<sub>d</sub>, A<sub>d</sub>)</td>
	</tr>
	<tr>
		<td>5</td><td>GL_ONE_MINUS_SRC_COLOR</td><td>destination</td><td>(1, 1, 1, 1)- (A<sub>s</sub>, A<sub>s</sub>, A<sub>s</sub>, A<sub>s</sub>)</td>
	</tr>
	<tr>
		<td>6</td><td>GL_SRC_ALPHA</td><td>both</td><td>(A<sub>s</sub>, A<sub>s</sub>, A<sub>s</sub>, A<sub>s</sub>)</td>
	</tr>
	<tr>
		<td>7</td><td>GL_ONE_MINUS_ SRC_ALPHA </td><td>both</td><td>(1, 1, 1, 1)- (A<sub>s</sub>, A<sub>s</sub>, A<sub>s</sub>, A<sub>s</sub>)</td>
	</tr>
	<tr>
		<td>8</td><td>GL_DST_ALPHA</td><td>both</td><td>(A<sub>d</sub>, A<sub>d</sub>, A<sub>d</sub>, A<sub>d</sub>)</td>
	</tr>
	<tr>
		<td>9</td><td>GL_ONE_MINUS_ DST_ALPHA</td><td>(1, 1, 1, 1)-(A<sub>d</sub>, A<sub>d</sub>, A<sub>d</sub>, A<sub>d</sub>)</td>
	</tr>
	<tr>
		<td>10</td><td>GL_SRC_ALPHA_SATURATE</td><td>source</td><td>(f, f, f, 1); f = min(A<sub>s</sub>, 1-A<sub>d</sub>)</td>
	</tr>
</table>

</div>


<p>The default source and destination blend modes for all objects in the GL group are <m>6</m> and <m>7</m>, respectively. These correspond to the GL blend factors GL_SRC_ALPHA and GL_ONE_MINUS_SRC_ALPHA. This is a very commonly used blending operation, and you may never need another one. It allows you to crossfade intuitively between the source and destination by changing the source&#x2019;s alpha value. </p>

<p>Other values are useful for simulating various real-world lighting situations, as well as special effects that have no physical counterpart. </p>

<bullet>Set the RGBA number boxes above the <o>jit.gl.render</o> object, which control the <m>erase_color</m> attribute, to the values <m>1.0, 1.0, 0.5</m> and <m>1.0</m>. This will set the background color to yellow.</bullet><br/>
<bullet>Set the left and right number boxes above the object <o>pak</o> <m>blend_mode</m> to <m>0</m> and <m>7</m> respectively. This specifies a source blend factor of GL_ZERO and a destination blend factor of GL_SRC_ALPHA. </bullet>
<illustration><img width="397" src="images/jitterchapter33h.png"/>The cylinder with a setting of <m>blend_mode 0 7</m>.</illustration>
<p>Let&#x2019;s examine how this <m>blend_mode</m> produces the image we see here. The source factor is GL_ZERO. This means that all the components of the source pixel are multiplied by zero -- the source pixel has no effect. You can verify this by trying different RGB values for the cylinder. They all produce the same colors. </p>

<p>The destination factor is GL_SRC_ALPHA. Looking in the table above, we can find the blend factor equation this corresponds to: (A<sub>s</sub>, A<sub>s</sub>, A<sub>s</sub>, A<sub>s</sub>). Each component of the destination pixel is multiplied by the source&#x2019;s alpha, in this case  <m>0.5</m>, before being added to the source pixel times the source factor, which in this case is <m>0</m>. So, each time a pixel is drawn, it has its brightness reduced by one half. </p>

<h2>Antialiasing</h2>
<p>When OpenGL draws polygons and lines, it approximates their ideal geometric shapes by filling in pixels on a raster grid. This process is prone to difficulties that parallel those in reconstructing ideal waveforms with digital audio. Inevitably, <i>aliasing,</i> spatial frequencies that are not included in the ideal image, will be introduced once it is reconstructed from discrete pixels. This aliasing is visible as what are commonly known as &#x201C;jaggies,&#x201D; especially in near-horizontal or near-vertical lines or edges. </p>

<p>OpenGL has some antialiasing techniques for reducing the jaggies. We&#x2019;ve made these available in Jitter through attributes of the GL group of objects. Using these attributes, you can specify whether any given object in the GL group will use antialiasing when it is drawn.</p>

<bullet>Set the left <o>toggle</o> object above the <o>pak</o> <m> poly_mode</m> object to <m>1</m> (on). Turn on the <o>toggle</o> box above the <o>message</o> box <m>antialias $1</m> to send the message <m>antialias 1</m> <m>to the</m> <o>jit.gl.gridshape</o> object.</bullet>
<illustration><img width="397" src="images/jitterchapter33i.png"/>Antialiasing off</illustration>
<illustration><img width="397" src="images/jitterchapter33j.png"/>Antialiasing on</illustration>
<p>The antialiased lines have a smoother appearance, and also a fatter one. They may also draw more slowly, so if you&#x2019;re concerned about drawing speed, you have to decide whether the improved appearance is worth the extra time. </p>

<p>The behavior of antialiasing in OpenGL is implementation-dependent. This means that makers of OpenGL hardware and drivers have some leeway in deciding what exactly happens when you request antialiasing. When you turn antialiasing on, Jitter requests that polygon edges be antialiased. But the particular OpenGL implementation that generated these pictures (an ATI Rage 128 accelerator with version 5.9.8 drivers) does not offer any help in this regard. Your implementation may differ.</p>

<h2>Summary</h2>
<p>We have defined front-facing and back-facing polygons, and seen how to draw them in both solid and wireframe modes (using the <m>poly_mode</m> and <m>cull_face</m> attributes). We have also used the renderer&#x2019;s <m>erase_color</m> attribute, and have defined in detail what happens when a source pixel is applied to a draw buffer destination, taking opacity and blend modes into account. And finally, the handy if somewhat unpredictable antialiasing feature of OpenGL was introduced.</p>

	<seealsolist>
		<seealso display="Depth Testing vs Layering" module="core" name="jitter_layering" type="vignette" />
		<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.handle">Use mouse movement to control position/rotation</seealso>
		<seealso name="jit.gl.render">Render Open GL</seealso>
		<seealso name="jit.pack">Make a multiplane matrix out of single plane matrices</seealso>
		<seealso name="jit.pwindow">In-Patcher Window</seealso>
		<seealso name="jit.unpack">Make multiple single plane matrices out of a multiplane matrix</seealso>
		<seealso name="pack">Combine numbers and symbols into a list</seealso>
		<seealso name="unpack">Break a list up into individual messages</seealso>
	</seealsolist>
	</chapter>
