=============
= VIEWPORTS =
=============

Canvas viewport items are created via the canvas create command:

	<canvas> create viewport ?options?

while viewport widgets are created via the viewport command:

	viewport create <path> ?options?


------------------
selecting a visual
------------------

A viewport will inherit its toplevel window's colormap and visual class
properties.  You must therefore specify the desired colormap and visual type
when creating the toplevel window that will contain the viewport.  You can use
the <sminfo> command to query for visuals with the required OpenGL attributes:

	sminfo visuals [ canvas | widgets ]

<sminfo> will return the id, class, and depth of all visuals that can be
used for canvas viewport items or viewport widgets.


------------------------
defining the view volume
------------------------

The view volume is the volume of space in the cell that is visible through
the viewport.  It not only defines which objects will be seen, but also
controls how these objects will be projected onto the viewport.  The view
volume is determined by the following parameters:

	vrp (view reference point, VRP)
	prp (projection reference point, PRP)
	vpn (view projection normal, VPN)
	vup (view up vector, VUP)
	maxu (maximum u coordinate)
	minu (minimum u coordinate)
	maxv (maximum v coordinate)
	minv (minimum v coordinate)
	bp (back plane distance)
	projection (type of projection: perspective or parallel)

Imagine the viewport as a rectangular window floating in a 3D world.  In order
to specify the position, size, and orientation of the viewport, we define a
3D viewing reference coordinate (VRC) system with its origin at VRP.  The 3
orthogonal axes of the VRC system are the n-axis, u-axis, and v-axis, and the
viewport lies in the u-v plane at n=0 (the view plane).  n-axis is given by
VPN.  v-axis is defined such that the projection of VUP parallel to VPN onto
the view plane is coincident with the v-axis.  The u-axis direction then can
be found by the cross-product of a vector in the direction of the v-axis with a
vector in the direction of the n-axis.

With this VRC system defined, the viewport's position and size are given by
its minimum and maximum u and v coordinates.

For perspective projection, the view volume is the pyramid with apex at the
PRP (specified in the VRC system) and edges passing through the corners of
the viewport window.

For parallel projection, the view volume is an parallelepiped with sides
parallel to the direction of proection, which is the direction from PRP to
the center of the viewport window.

The view volume is clipped in front by the view plane, and in back by a u-v
plane whose distance along the n-axis from the VRC origin is given by bp,
the back plane distance.

Readers of Computer Graphics: Principles and Practice will find the definition
of view volume here consistent with that given in the book, with the exception
that here the view plane is also the front clipping plane.

-------------
light sources
-------------

OpenGL supports a minimum of 8 light sources.  For a detailed explanation of
the lighting effects, please see "OpenGL Programming Guide".  Here I will only
describe how the light sources are specified.

Each light option {-light0 through -light7} has the following format:

{ambient diffuse specular {x y z w} {dx dy dz} exponent cutoff {k0 k1 k2} model}

ambient, diffuse, specular are the ambient, diffuse, and specular colors of
the light source respectively.  {x y z w} defines the position of the the light
source.  If w=0, the light source is a directional light; otherwise it is a
positional light.  For a positional light, if cutoff=180, the light radiates
in all directions.  You can define a spotlight by restricting the shape of the
light a positional light source emits to a cone.  This is controlled with the
cutoff parameter, which should be between 0 and 90.  In this case {dx dy dz}
is the direction of the spotlight, and exponent affects the intensity
distribution of the light within the cone.

You may also choose to enable attenuation for positional light sources. The
attenuation factor is computed as the inverse of (k0 + k1 * d + k2 * d * d),
where d is the distance between the light's position and the vertex (OpenGL
does lighting computation at vertices only.)

If you specify a valid model name, then the light source will track the model.
{x y z w} and {dx dy dz} are taken to be given in the model's local coordinate
system, and the light source will move as the model moves.

You may omit {dx dy dz}, exponent, cutoff, {k0 k1 k2} and model when you
specify a light source. If you do, default values of {0 0 -1}, 0.0, 180.0,
{1.0 0.0 0.0}, and {} will be used.


------------
depth-cueing
------------

Depth cueing is the effect where objects farther from the viewer appear at a
lower intensity than objects closer to the viewer.  Under OpenGL, depth-cueing
is achieved through the use of fog.  Objects that are far away from the view-
point will begin to fade into the fog color.  To use fog, you will need to
define the fog color, and select one of three different fog equations: linear
exp, and exp2, and provide the appropriate parameters:

For linear fog, the depthcue option should be specified as:

	{{r g b} linear start end},

and for exp and exp2 fog,

	{{r g b} exp density},
	{{r g b} exp2 density}

where r, g, and b are floating point numbers between 0 and 1 inclusive.

---------------------------------
navigation (viewport widget only)
---------------------------------

For performance reason I have moved part of the navigation code from Tcl to
C.  Viewport widgets now have a 'navigate' command:

<viewport> navigate x y rootx rooty cx cy {dx dy dz} modifier

where 'x' and 'y' are the mouse position as returned by 'winfo pointerxy',
      'rootx' and 'rooty' are the root coordinates of the viewport widget,
      'dx', 'dy', 'dz' are the width, height, and depth of the cell and are
		       used to determine, together with 'cx' and 'cy', how
		       much to move the VRP by.
      'modifier' can be "None", "Shift", or "Control".


-------
picking
-------

Picking allows you to identify objects on the screen.  You would first specify
a rectangular region of the viewport window (in window coordinates), and query
for the the list of objects whose images intersect that region.  This makes it
possible for you to implement a direct object selection mechanism.

example:

	$view configure -pick {180 180 1 1}
	$view cget -pick

The first line sets up the pick region (a square of size 1 pixel centered at
(180,180)), and the second line queries for the result of the pick operation.
The result will be in the form: {{180 180 1 1} model1 model2 ...}.  If no
object falls in the pick region the result will be in the form: {180 180 1 1}.


-------------------------
updating viewport widgets
-------------------------

Normally viewport widgets are redrawn when 'update', 'update idletasks', or
'vwait' is issued. However, there are situations where you would want more
precise control over the timing of viewport refreshes than these commands
afford. For example, in the distributed simulation application that I'm
writing, I have packets arriving over the network that change the positions of
models asynchronously, and at the same time the user may be navigating the
virtual world with the mouse. In order to produce a smooth animation effect
the viewport must be redrawn at a more or less constant rate. With the
default Tk widget update mechanism this effect would be hard to achieve, so
I've added a new viewport widget command 'update', along with a new viewport
widget option '-async', that together provide a reasonable solution.  When
'-async' is true (the default), viewport widgets are redrawn (if necessary) as
usual. On the other hand, when '-async' is true, a viewport widget is redrawn
only when the widget update command is called. This allows me to process
network packets as they arrive asynchronously, modify model positions as
dictated, and redraw the viewport at a fixed rate.


----------------
viewport options
----------------

-ambientLight
	color of the global ambient light.

-async (viewport widget only)
	If on, viewport will be refreshed when 'update' or 'update idletasks'
	is issued.  If off, viewport will be refreshed only when the viewport
	update command is explicitly invoked. See above section on updating
	viewport.  Viewport will be refreshed regardless of the value of this
	option when it is resized or exposed.

-bp
	backplane of the view volume. see above section on defining the
	view volume.

-cell
	cell associated with the viewport.

-depthcue
	see section on depth-cueing.

-doublebuffer (viewport widget only)
	if on, requests a double-buffered visual. Canvas viewport items are
	always single-buffered.  Once the viewport is created this option
	can not be changed.

-epsilon
	used in normalizing vectors. A vector will be considered a null
        vector (0, 0, 0) if its magnitude is less than epsilon.

-fill
	the color the viewport should be filled with.

-foghint
	OpenGL FOG_HINT: none, nicest, fastest.

-hsr
	whether hidden surface removal should be performed.


-light{0-7}
	see above section on light sources.

-maxu
-maxv
-minu
-minv
	see above section on defining the view volume.

-outline
	viewport outline color.

-perspectivehint
	OpenGL PERSPECTIVE_CORRECTION_HINT: none, nicest, fastest.

-pick
	see above section on picking.

-projection
	projection mode: perspective or parallel.

-prp
	projectin reference point.

-tags (canvas viewport item only)

-texture
	boolean flag that turns texture mapping for the viewport on/off

-vismask
-visiblemask
	list of model names to be made invisible.  If the list is preceded
	with ^, only models whose name appear in the list will be visible.
	Descendents of masked models will remain visible.

-vpn
	view projection normal

-vrp
	view reference point

-vup
	view up vector

-width
	width of the viewport outline.
