<?xml version='1.0' encoding='UTF-8'?>

<?xml-stylesheet href="./_c74_tut.xsl" type="text/xsl"?>
<chapter name="Tutorial 32: Camera View">
<setdocpatch name="32jCameraView" patch="32jCameraView.maxpat"/>

<previous name="jitterchapter31">Rendering Destinations</previous>
<next name="jitterchapter33">Polygon Modes, Colors and Blending</next>
<parent name="jitindex">Jitter Tutorials</parent>



<h1>Tutorial 32: Camera View</h1>

<techdetail>
	<i>Note:</i> Some techniques described in this tutorial are outdated. Users are recommended to use the <o>jit.gl.camera</o> object instead of the jit.gl.render <i>camera</i> and <i>lookat</i> messages described below.
</techdetail>

<p>This tutorial shows you how to set up the camera view and how to position and rotate GL objects using <o>jit.gl.handle</o>. It will cover the group of components which together make up the <i>camera view</i>: the camera's position, the point at which the camera is looking, the "up" vector, the type of projection, the lens angle, and the clipping planes.</p>

<p>In the lower left of the patch, there is a <o>jit.window</o> object named <m>mister</m>. This window will be the destination for our OpenGL drawing. You will notice that the <o><b>jit.window</b></o> object has an attribute argument <m>@depthbuffer 1</m> to specify the creation of a depth buffer. A depth buffer allows the OpenGL renderer to determine which drawing command is visible at a given pixel based on the proximity of the geometry to the camera. Without depth buffering, OpenGL uses what is often referred to as the "Painter's Algorithm"--i.e. the visible results of drawing commands correspond to sequence in which they are performed. </p>

<h2>The GL Context</h2>
<bullet>Click on the <o>toggle</o> object labeled <i>Start Rendering</i>.</bullet><br/>
<p>We now see large gray circle and some yellow lines. These are being drawn by two instances of the <o>jit.gl.gridshape</o> object. The <o>jit.gl.gridshape</o> object can draw a variety of 3D shapes, including spheres, tori, cylinders, cubes, planes, and circles. The grey circle we see drawn in the window is actually a sphere and is being drawn by the section of the patch labeled <i>Grey Shape</i>. The yellow lines are actually a plane and are being drawn by the section of the patch labeled <i>Yellow Plane</i>. The yellow plane is being rendered with <m>poly_mode 1 1,</m> which means that the shape is being drawn with outlined polygons rather than filled polygons for both the front and back faces of the plane.  If you switch off the  toggle  object connected to the <o>message</o> box <m>poly_mode $1 $1</m>, you can see the plane rendered with filled polygons.</p>


<illustration><img src="images/jitterchapter32a.png"/>The <m>mister</m> drawing context</illustration>
<bullet>In the <i>Grey Shape</i> section of the patch, click on the <o>message</o> box <m>scale 0.3 0.3 0.3</m> and then click on the message box containing <m>shape torus</m>. You should now see what looks like a grey doughnut.</bullet><br/>
<bullet>Click on the <o>toggle</o> object connected to the <o>message</o> box <m>lighting_enable $1</m> and then click on the  toggle  object connected to the <o>message</o> box <m>smooth_shading $1</m>. We are now staring at a lit, smoothly shaded, 3D gray torus.</bullet>
<div>
<techdetail>By default, Jitter's GL objects have lighting and smooth shading disabled, so it is necessary to turn these on. Lighting will be covered in detail in <link type="tutorial" module="jit" name="jitterchapter35">Tutorial 35</link>.</techdetail>
</div>

<illustration><img src="images/jitterchapter32b.png"/>Rendered shapes with smooth shading and lighting enabled</illustration>

<h2>Camera Position</h2>

<bullet>Open the <i>Camera View</i> subpatch of the patch, and click on the <o>toggle</o> object labeled <i>jit.gl.render axes</i>.</bullet>

<p>You should see a red line from the center of the window to the right of the window, a green line from the center of the window to the top of the window. These are the <i>x</i> and <i>y</i> axes, respectively. They help us to determine the origin of our scene. Since the default camera position is at [0.,0.,2.], and the default <m>lookat</m> position is [0.,0.,0.], the camera is looking directly at the origin of our scene along the <i>z</i> axis. Hence, we do not see the blue line which represents the <i>z</i> axis along which the camera is looking.</p>

<illustration><img src="images/jitterchapter32c.png"/>View the axes</illustration>
<bullet>Under the <i>camera position</i> label, set the <i>x</i> value to be <m>1</m>. Now the camera is at the position [1.,0.,2.], it is still looking at the position [0.,0.,0.], and the blue line of the <i>z</i> axis has become visible.</bullet>

<illustration><img src="images/jitterchapter32d.png"/>The axes with a different viewing position</illustration>
<bullet>Now let's set the <m>camera position</m> <i>x</i> value to <m>6.,</m> <i>y</i> value to -<m>6.,</m> and <i>z</i> value to <m>6</m>. so that the camera position is [6,&#x2013;6,6]. You can see that the yellow plane and the axes are, in fact, finite.</bullet>

<illustration><img src="images/jitterchapter32e.png"/>Viewing the edge of the plane</illustration>
<p>So far, the <i>y</i> axis has always been pointing upwards with respect to the camera view. This is because the default "up" vector is [0.,1.,0.]&#x2014;i.e. the unit <i>y</i> vector.</p>

<bullet>Under the <i>up vector</i> label, let's set the <i>y</i> value to 0. and the <i>z</i> value to 1. We see that the view has rotated, and the blue line of the <i>z</i> axis is now pointing upwards.</bullet>

<illustration><img src="images/jitterchapter32f.png"/>Using a different &#x201C;up&#x201D; vector</illustration>

<p>You may have noticed, as we've moved the camera further away from the origin, that the torus, plane, and axes have become smaller. This is because the default viewing mode uses a perspective projection, which is similar to the way we see things in the 3-dimensional world we inhabit. If you are familiar with camera lenses, you may also know that depending upon the angle of the lens, objects will be smaller as the lens angle increases to accommodate a larger field of view. Similarly, we can change the lens angle of our perspective transformation to increase the field of view, and in doing so the objects will become yet smaller.</p>

<bullet>The default lens angle is 45 degrees, so let's change it to something like 60 degrees by changing the <o>number</o> box connected to the <o>message</o> box <m>lens_angle $1</m>.</bullet>

<illustration><img src="images/jitterchapter32g.png"/>Using a 60-degree lens angle</illustration>

<h2>Orthographic Projection</h2>

<p>Another type of projection supported by OpenGL is the <i>orthographic projection</i>. This type of projection does not diminish the size of objects based on camera position. The orthographic projection is common to 3D CAD software used for tasks such as mechanical engineering. Many early video games like Q-Bert also used an orthographic projection. You can switch between the perspective projection and the orthographic projection by clicking on the <o>toggle</o> box labeled <i>orthographic projection</i>. The message <m>ortho 1</m> will turn on orthographic projection. If you try moving the camera with orthographic projection turned on, you should not see the objects become any smaller. However, changing the lens angle will still change the field of view, and the size of objects relative to the view.</p>

<illustration><img src="images/jitterchapter32h.png"/>Viewing our scene using orthographic projection</illustration>
<bullet>Click on the <o>toggle</o> again to turn off the orthographic projection with an <m>ortho 0</m> message.</bullet>
<h2>Clipping Planes</h2>
<p>Let's examine the <i>clipping planes</i> that determine the extent along the camera's view that will be rendered. OpenGL has a <i>near</i> clipping plane and a <i>far</i> clipping plane, and only geometry which lies in between these two planes will be rendered. These clipping planes are specified in units of distance from the camera along the viewing vector using the <m>clip_near</m> and <m>clip_far</m> messages. By default, the near clipping plane is set to 0.1 and the far clipping plane is set to 100.</p>

<bullet>Try increasing the near clipping plane to <m>10</m> and decreasing the far clipping plane to <m>12.</m> You should see the near and far edges of the yellow plane that fall outside the clipping planes disappear.</bullet>
<illustration><img src="images/jitterchapter32i.png"/>Using a more constrained clipping plane</illustration>
<bullet>Set the near clipping plane back to the default of <m>0.1</m> and the far clipping plane back to the default of <m>100</m>.</bullet>
<p>So far, the camera has always been looking at the origin [0.,0.,0.]. If we change the <m>lookat</m> position's x value to <m>3.</m>, the camera is now looking at [3.,0.,0.].</p>

<h2>Handles</h2>
<bullet>Let's move the torus to the position [3.,0.,0.], by clicking on the <o>message</o> box containing <m>position 3. 0. 0</m>. in the subpatch labeled <i>UI Rotation and Position Control</i>. The torus is now again located at the center point of the view, [3.,0.,0.].</bullet>

<illustration><img src="images/jitterchapter32j.png"/>Changing the viewing position and the position of the shape</illustration>
<p>Not only did this send the <m>position 3. 0. 0.</m> message to the torus, but also to the  jit.gl.handle  object. The  jit.gl.handle  object is a GL group object that uses mouse information to move and rotate objects in the 3D scene. Like the <o>jit.gl.gridshape</o> object, the <o>jit.gl.handle</o> object requires a named draw context into which to draw. Unlike the <o>jit.gl.gridshape</o> object, it's also a user interface object that translates mouse activity in the draw context's destination to Max messages.</p>

<p>In this patch, messages from the <o>jit.gl.handle</o> object are sent to the <o>jit.gl.gridshape</o> object. They are also sent to the <o>route </o> <m>rotate position</m> object and formatted so you can see exactly what is being sent. These messages are the only communication from the <o>jit.gl.handle</o> object&#x2014;there is nothing going on behind the scenes.</p>

<p>If you click on the torus and drag the mouse, you will see the torus being rotated by the <o>jit.gl.handle</o> object as though it were a virtual trackball. If you hold down the command key while dragging, you can move the torus left, right, up, and down. If you hold the option key as you drag, you can move the torus towards you or away from you. Using the shift key as you perform any of the above mouse actions will constrain the action to a single axis.</p>

<bullet>Try manipulating the orientation of the torus by clicking on it in the <o>jit.window</o> object. Get a feel for how the <o>jit.gl.handle</o> object translates the 2-dimensional mouse information into 3-dimensional rotation information.</bullet>

<illustration><img src="images/jitterchapter32k.png"/>Using the <o>jit.gl.handle</o> object to manipulate the object&#x2019;s position</illustration>

<div>
<techdetail>As with the displayable axes of the <o>jit.gl.render</o> object, the <o>jit.gl.handle</o> object shows colored lines that correspond to the <i>x</i> (red), <i>y</i> (green), and <i>z</i> (blue) planes of the object being rotated. The lines appear as circles around the relevant object being "handled."  The mouse controls the axes whose circles are nearest to the front of your current field of view. By manipulating the image so that those circles move to the back of the object, you can control a different pair of axes with the next mouse click. The modifier keys let you reposition the object by relocating it on the three axes. The <o>jit.gl.handle</o> object outputs the relevant messages to set the <m>rotate</m> and <m>position</m> attributes of the GL group object attached to it. Note that if you are displaying a GL context in a <o>jit.pwindow</o>, the Help in Locked Patchers option of Max (which you can change under the Options menu) needs to be disabled in order for zooming to work using <o>jit.gl.handle</o>. Otherwise, the option key will cause the help patch for <o>jit.pwindow</o> to appear(!).</techdetail>
</div>

<h2>Summary</h2>
<p>We have examined the several components which make up an OpenGL scene's camera view, and the necessary attributes of the <o>jit.gl.render</o> object which control them. The <m>camera</m> attribute specifies the camera position; <m>up</m> specifies the upwards vector; <m>lookat</m> specifies the position at which the camera is looking; <m>ortho</m> specifies whether to use an orthographic or perspective projection; and <m>near_clip</m> and <m>far_clip</m> specify the  clipping planes. Lighting and smooth shading attributes can be enabled by setting the  <m>lighting_enable</m> and <m>smooth_shading</m> attributes of the GL group object handling the geometry (in this case the <o>jit.gl.gridshape</o> object).</p>

<p>The <o>jit.gl.handle</o> object lets us rotate and reposition OpenGL objects using the mouse and the modifier keys on the keyboard. The <o>jit.gl.handle</o> object takes the name of a valid draw context to attach itself to, and sends messages to any connected object that is also using that context, setting the <m>rotation</m> and <m>position</m> attributes of that object.</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.handle">Use mouse movement to control position/rotation</seealso>
		<seealso name="jit.gl.render">Render Open GL</seealso>
		<seealso name="jit.window">Display data in a Window</seealso>
	</seealsolist>
	</chapter>
