CinematicaTutorial

©1995 - 2003 Joshua A. Solomon & Andrew B. Watson

Credits & Version

Written by Joshua A. Solomon & Andrew B. Watson. All rights reserved.  No warranties expressed or implied. This is version 3.3, created with Mathematica version 4.1. Cinematica does not yet run native on OSX.

Cinematica Version History

Version 3.3: CinematicaOpen[] now accepts the argument attenuatorAttached. It also no longer produces that irritating "Cinematica is already Open" garbage. Also, MovieToGWorld exits gracefully when movies are composed of differently sized frames and/or imageIndex is not a positive integer.

Version 3.2.3: The video driver for the Blue & White Macs contains a bug which destroyed Cinematica 3.2.2's display synchronisation. The bug should not affect v3.2.3. Also, ColorMap now allows rational (in addition to real) luminance values. Finally, Cinematica no longer crashes if CinematicaOpen[] is called twice in succession without an intervening CinematicaClose[].

Version 3.2.2: Name change. No other changes.

Version 3.2.1: This file was not included with Version 3.2. It's back. No other changes.

Version 3.2: Made PlaySound an "official" function. Some documentation expanded. delay and duration in WarnTone and MovieTone are now in seconds.

Version 3.1: Added GWorldToVisor. Allowed for arbitrary image placement on display screen. Interrupts during GWorldToScreen (and GWorldToVisor) are now prevented. Added WarnTone and MovieTone options to GWorldToScreen (and GWorldToVisor).

Version 3.0: Never properly released.

Version 2.1.2: A VideoToolbox bug which caused some flakey behaviour when Cinematica ran on Machines with QuickTime 3 has been fixed.

Version 2.1.1: FileToGWorld now accepts file names that begin with ":". This is standard in Mathematica 3.0. FileToGWorld still accepts file names that do not begin with ":". The cinematica application remains unchanged.

Version 2.1: Cinematica.68k is no longer supported.

Version 2.0.1.1: Rush.c (see Version 2.0.1, below) introduced a bug that could potentially cause crashes on 68k machines. This has been fixed. Cinematica.ppc and Cinematica.m remain unchanged.

Version 2.0.1: Thanks to Denis Pelli's Rush.c program (part of his VideoToolbox; see the "Introduction" of the Read Me First! section, below), GWorldToScreen is now run as a deferred process. This means that TimeVideo (see "Displaying a single image for a specified duration" in the Tutorial section, below) no longer overestimates the display-rate accuracy of Cinematica displays. (Note: TimeVideo's estimate hasn't changed, but previous versions of Cinematica may not have always achieved that estimate.)

Version 2.0:  Cleaned up documentation of Cinematica functions. Introduced Combine2Movies. Doesn't crash if proper monitor is not connected. Display on any monitor. Compatible with System 7.6. Both versions (68k as well as ppc) now properly restore display monitor colormaps upon CinematicaClose[]. Cinematica.68k no longer allows image indices higher than 1024 or colormap indices higher than 512.

Version 1.2.4:  Cinematica.ppc currently allows image indices as high as 16384. Cinematica.68k currently allows image indices as high as 2048. Both allow colormap indices as high as 1024.

Version 1.2.3:  Previously, loading multi-frame movies took longer than loading each frame individually. That bug has been fixed. Display monitor colormaps are now properly restored upon CinematicaClose[]. Cinematica.ppc currently allows image indices as high as 2048. Cinematica.68k currently allows image indices as high as 1024. Both allow colormap indices as high as 1024.

Version 1.2.2:  fileToGWorld now loads files from any folder within the current working directory (e.g. "FileToGWorld["enclosed folder 1:enclosed folder 2:photo", 5, 192, 128]).
Previously an attempt to load a nonexistant file could cause a crash. Now the offending fileName is written to the console and Cinematica doesn't crash.

Version 1.2: 
-Cinematica now requires only 4 megabytes of RAM. 
-1 additional byte (rather than the 4 required by version 1.1) is required for every pixel stored in GWorlds.
-Cinematica now writes each image after the colormap is in place (cf. Examples:Display a single image for a specified duration) rather than the other way around. 
-GWorldToScreen now makes sure that
TensorRank[displayList] == Dimensions[displayList][[2]] == 2. 
Previously, an incorrect displayList could cause a crash. 
-The "wait" feature was unreliable. It has been removed.

Version 1.1 introduces the "wait" feature. See the example: Kernel/Cinematica synchronization. Version 1.0 didn't "wait."

Read Me First!

Introduction

Cinematica is a minimal system for producing calibrated grayscale movies on an Apple Macintosh Computer from within the Mathematica programming environment. It makes use of the VideoToolbox software library developed by Denis Pelli. The VideoToolbox is free. You may download it from http://rajsky.psych.nyu.edu/VideoToolbox/	.

The purpose of this Notebook is to provide some elementary examples of the use of the Cinematica system. Working through the complete tutorial should take about an hour, and should render users sufficiently proficient that they can then go on to do real experiments.

By design, Cinematica provides a very low-level interface to the display routine, consisting of {image index, colormap index} pairs. The philosophy is that programming is much easier in Mathematica than in C, so we reserve the complexity for Mathematica. The examples in the tutorial are quite simple, but they provide a foundation for elaborate displays. We would be happy to receive suggestions for future improvements.

We have written a brief article on this system. Should the user wish to cite this work they might use:
Solomon, J.A. & Watson, A.B. (1996) Cinematica: a system for calibrated, Macintosh-driven displays from within Mathematica. Behavior Research Methods, Instruments, & Computers, 28, 607-610.

Hardware Requirements

Optimally, you should have at least two monitors connected to your Macintosh. One monitor (typically the start-up screen) is used to interface with Mathematica., the other monitor is used to display the movies. However, if necessary, the same monitor can be used for both the interface and the display. The display monitor must be driven by a color video card. The monitor itself should be monochrome and it should be connected with an ISR Video Attenuator (see below). Note that the following examples will work on a either a monochrome monitor or a color monitor. They will also work with or without a Video Attenuator. However, Cinematica cannot display accurately calibrated movies without the Video Attenuator. Movies on color monitors will be green.

The ISR Video Attenuator is a small box with Macintosh-video-compatible connectors at either end that connects to the video cable between the computer and monitor. It combines the three color RGB signals from a color video card to produce a single monochrome signal of higher grayscale resolution. The circuit was first described in Pelli, D. G. & Zhang, L. (1991) Accurate control of contrast on microcomputer displays. Vision Research, 31, 1337-1350. Please cite this article if you use the Video Attenuator. For more information, including ordering information, read the Video Attenuator file in the VideoToolbox. (See the Introduction if you don't already have the VideoToolbox.)

If you want to display images dichoptically with LCD glasses, you will need either the StereoMac driver or the SEGA driver plugged into the Modem port. The StereoMac driver and glasses are available from 3D TV Corporation. For more information, see http://ijvr.uccs.edu/3dtvadb.htm . The circuit for the SEGA driver has been described by Juri Munkki. For more information, see http://www.hut.fi/~jmunkki/cards/sega.html .

Installation

Before commencing these exercises 1) start a local kernel on a Macintosh, 3) put the application cinematica into the current working directory (by default, this will be Mathematica 3.0 Files), 4) put the files photo and letterC into the current working directory and 5) put the file Cinematica.m (a short Package of Mathematica Functions) into one of the directories in $Path (the current working directory will usually suffice). Note: the file CinematicaTutorial.nb (this file) may be stored in any folder.

Luminance Calibration

The VideoToolbox application CalibrateLuminance.68k will produce a file called LuminanceRecordX.h, where X is the number of the calibrated monitor. CalibrateLuminance.68k runs best with Extensions Off. This is an interactive program which displays images and asks the user to enter luminance measurements. When you have calibrated your display monitor, place the file LuminanceRecordX.h into the current working directory. A default LuminanceRecord has been compiled with Cinematica, thus it is not necessary to calibrate your display monitor when first working through the examples below.

Memory Requirements

Cinematica requires a minimum of 4MB unused RAM. 1 additional byte is required for every pixel. Click on the Cinematica icon and key apple-I. This will bring forth the Cinematica Info window, wherein the amount of memory allocated to Cinematica can be set to the user's preference.

Known Bugs

Users of 8100 Macs have reported problems with earlier versions of Cinematica.

The menu bar disappears when CinematicaOpen[] is evaluated. To re-display the title bar, simply click on the desktop.

Tutorial

To proceed with the tutorial, select Evaluate Initializations from the Action Menu, and then start working through the Examples. Note that by repeatedly typing Shift-Enter one can successively evaluate all of the input cells. Enjoy.

Loading the Package

The first is to load the Package called Cinematica.m. This contains the definitions of the various Cinematica functions.

Needs["Cinematica`"]

The next step is to call the function CinematicaOpen. This initiates a MathLink connection to the external program cinematica. If the application is not in the current working directory (see Installation, above), a beep will sound and the user will have to bring MathKernel  to the fore and instruct it as to the location of cinematica.

By default, Cinematica assumes that you have at least two monitors connected to your Macintosh. Movies will be displayed on monitor number 1. (Monitor numbers can be obtained by running the program CalibrateLuminance.68k. The monitor number is usually the number in the Monitors control panel - 1. The console is always monitor number 0.) If you wish to display movies on a monitor other than monitor number 1, type the desired monitor number in the square brackets below, prior to evaluating the command. For example, if you only have one monitor (the console) and you want to use it for the display as well as the interface, the command below should be CinematicaOpen[0].

Also: If you do not yet have an ISR Video Attenuator (see Hardware Requirements, above) and just want to see what Cinematica can do, please supply two arguments to CinematicaOpen. The first argument should specify the monitor (see preceding paragraph), the second should be "False." For example, if you have an iMac and thus cannot attatch a second monitor or a Video Attenuator, the command below should be CinematicaOpen[0,False].

CinematicaOpen[]

Displaying a single image

The simplest possible use of Cinematica consists of three steps: 1) load an image, 2) load a colormap, and 3) display the image with the colormap. We now illustrate these steps.

We first create in Mathematica an image consisting of a single frame of noise, and display it on the console for verification.

noise = 
	Table[Random[Integer, {64, 192}], {32}, {32}];

ListDensityPlot[noise, Frame->False, Mesh->False];

Next we load the image into a type of Macintosh memory called a GWorld. Each image is associated with an arbitrary integer index.

MovieToGWorld[1, noise];

Next we create one colormap. This also gets an (arbitrary) positive integer index. We use the defaults for the other parameters. This will get us a linear, unit-contrast colormap.

ColorMap[1];

Next we display the image using the colormap. This done by calling  GWorldToScreen with a single argument consisting of a display list that consists of {image index, colormap index} pairs. In this case, the list contains only one pair.

GWorldToScreen[{{1, 1}}];

If things are working, you should see a 32 x 32 pixel noise image on an otherwise dark background.

Changing the background luminance

GWorldToScreen copies images to an area of video memory that we will call the screen. Initially the entire screen is set to the graylevel zero. To create a uniform background of a luminance other than zero, we create a new colormap.  This call to ColorMap is a little more complicated. We  specify that the colormap index is 1 (note that we may freely re-use colormap and image indices), the contrast is 1, the image graylevels will range between 2 and 254, and we assign the remaining three graylevels to specific relative luminances that correspond to the mean, minimum, and maximum. Thus our uniform background of 0's will map to a relative luminance of 0.5 (the mean luminance). Note also that symmetric placement of minimum and maximum graylevels means that 128 will also map to the mean luminance.

ColorMap[1, 1, 2, 254, {{0, .5}, {1, 0.}, {255, 1.}}];

Now we display the noise image with the new  colormap.

GWorldToScreen[{{1, 1}}];

Displaying a single image for a specified duration

Note that the noise image is still on the screen. The only way to remove it (short of quitting cinematica) is to display something else. For example, one could display a blank image. Alternatively, one could display any image coupled to a zero-contrast colormap.

Here we load an image of zeroes.

MovieToGWorld[2, Table[0, {32}, {32}]];

Here we load a zero-contrast colormap.

ColorMap[2, 0, 2, 254, {{0, 0.5}, {1, 0.}, {255, 1.}}];

Here we display the blank image with the zero-contrast colormap

GWorldToScreen[{{2, 2}}];

It is now a trivial matter to show the noise image for a fixed duration of 32 frames.

The duration of this display will depend on the refresh rate of the display monitor. For example, if the refresh rate is 67 Hz, this 32-frame display will be 0.48 seconds long.

GWorldToScreen[
	Join[{{2, 2}}, Table[{1, 1}, {32}], {{2, 2}}]];

Note that the above display list began with a blank image at zero contrast. While this practice is not strictly necessary, it is recommended for the following reason: The writing of an image to the screen and the implementation of a colormap cannot be truly simultaneous. Cinematica implements the colormap first. To prevent the brief display of an old image with a new colormap, we begin the display list with a blank image.

Note also that not all video drivers are capable of redrawing the entire screen at every available refresh rate. TimeVideo (an application within the VideoToolbox) can determine the display-rate accuracy of any Macintosh-driven display.

Placing an image on the display screen

By default, images are placed in the center of the display screen. Images can be placed anywhere on the display screen by using a display list that consists of {image index, colormap index, rightward shift, upward shift} quadruples. rightward and upward shifts are measured in pixels. They can be either positive or negative.

Here we flash the noise on the left side of the screen:

GWorldToScreen[
	Join[Table[{1, 1, -100, 0}, {32}], {{2, 2, -100, 0}}]];

Here we flash the noise in the upper right quadrant:

GWorldToScreen[
	Join[Table[{1, 1, 100, 100}, {32}], {{2, 2, 100, 100}}]];

Slow video cards can images to tear near the top of the display screen. One way to avoid this problem is by displaying images near the bottom.

A moving image

Cinematica contains no special provisions for making images move. Instead, moving images are created in advance as a sequence of frames. In this example, we create the frames by scrolling the noise image created above. Note that the first frame is assigned index 3, and subsequent frames increment by 1.

MovieToGWorld[3, Table[RotateRight[noise, k], {k, 32}]];

Now we can show something. We create a display list that consists of {image index, colormap index} pairs. This list is given to GWorldToScreen.

GWorldToScreen[
	Join[{{2, 2}}, Table[{k, 1}, {k, 3, 34}], {{2, 2}}]];

If things are working, you should see a 128x128 gray rectangle in which is embedded a square of noise that scrolls vertically for a duration of 32 frames.

Varying contrast over time

Now we create a set of 32 colormaps that describe a Gaussian variation in contrast. First we create a  sequence of contrast values (the time-list). This Gaussian has a time-scale of 16 frames and is centered on the 17th frame.

gauss = Table[N[Exp[-Pi*(((t - 17)/16)^2)]], {t, 32}];

We plot the waveform for verification.

ListPlot[gauss, PlotJoined->True];

We use the time-list to load a set of 32 colormaps, one for each contrast. We start at index 3, to leave our unit- and zero-contrast colormaps in place.

ColorMap[3, gauss, 2, 254, {{0, 0.5}, {1, 0.}, {255, 1.}}];

We create a display list that associates our static noise repeatedly with the elements of the list of colormaps. As usual, we return to the uniform field at the end of the display.

dlist = Join[{{2, 2}}, Table[{1, n}, {n, 3, 34}], {{2, 2}}];

GWorldToScreen[dlist];

Moving and varying contrast over time

It is now trivial to use our set of colormaps to vary the contrast of an image as it moves. The only change is that for each element of the display list, we choose a new image and a new colormap.

dlist = Join[{{2, 2}}, Table[{n, n}, {n, 3, 34}], {{2, 2}}];

GWorldToScreen[dlist];

Periodic movies

Of course, we can re-use image and colormap indices as often as we like in the display list, for example to create temporally periodic displays. Here we show four cycles of the Gaussian contrast modulation developed above.

dlist = Join[{{2, 2}}, 
		Table[{3 + Mod[n - 1, 32], 3 + Mod[n - 1, 32]}, {n, 128}], 
		{{2, 2}}];

GWorldToScreen[dlist];

Counterphase grating

Here is a more familiar periodic spatiotemporal stimulus: a counterphase modulating sinusoidal grating.

ListDensityPlot[cosGrat = 
 	Round[N[128 + 126*Table[Cos[2*Pi*x/8], {32}, {x, 32}]]], Frame->False, Mesh->False];

MovieToGWorld[3, cosGrat];

We create and load colormaps appropriate for one cycle of sinusoidal temporal modulation.

sinwave = Table[Sin[2*Pi*t/32], {t, 32}]//N;

ColorMap[3, sinwave, 2, 254, {{0, 0.5}, {1, 0.}, {255, 1.}}];

In the display list, we use the Mod function to re-cycle through the colormaps.

GWorldToScreen[Join[{{2, 2}}, 
		Table[{3, Mod[t - 1, 32] + 3}, {t, 128}], {{2, 2}}]];

Fixation point

It is useful to have a fixation point handy, so we make one here. This is a 3 x 3 pixel cross. Note that we use the graylevels 0 (typically the background luminance) and 1 (typically black), which is one of our (typically) reserved values.

MovieToGWorld[1, {{0, 1, 0}, {1, 1, 1}, {0, 1, 0}}];

GWorldToScreen[{{1, 2}}];

Gabor stimulus

One virtue of Cinematica is the ease with which complex stimuli can be created in Mathematica. Here is a Gabor stimulus.

size = 32; 
fx = 4/size; 
fy = 0/size; 
s = .5*size; 
half = size/2;
gabor = Round[128 + 126*Table[
			Cos[2*Pi*(x*fx + y*fy)]*Exp[-Pi*((x^2 + y^2)/s^2)],
			{y, -half, half - 1}, {x, -half, half - 1}]//N];

ListDensityPlot[gabor, Frame->False, Mesh->False];

MovieToGWorld[3, gabor];

Now we display the gabor using the counterphase temporal modulation developed in the previous subsection. We also display the fixation point developed above before and after the gabor.

GWorldToScreen[dlist=Join[{{1, 2}},
		Table[{3, Mod[t - 1, 32] + 3}, {t, 128}], {{1, 2}}]];

Sound

A warning tone can be played prior to stimulus display by setting the option WarnTone->{duration,anote,delay}. Here we play a 0.5 second tone prior to the display of the Gabor stimulus. 0.3 seconds is the delay between the warning tone and the stimulus display. The frequency of the tone is given by the MIDI value: 88. (A MIDI value of 60 is middle C.)

GWorldToScreen[dlist, WarnTone->{.5,88,.3}];

To play sounds during movie displays, use the option MovieTone->anote. anote is an integer MIDI value. The tone lasts for the duration of the display.

GWorldToScreen[dlist, MovieTone->60];

To play sounds without displaying anything, use PlaySound. Its arguments are duration, anote, delay–just like WarnTone.

PlaySound[.5,88,.3];

Loading image files

Above we have emphasized loading of images and movies directly from Mathematica expressions. Occasionally one may wish to load an image file that was created previously by Mathematica or some other source. To do this we use the function FileToGWorld. For illustration, we first write an image to a file.

WriteBinary["Cinematica.test", 
	Flatten[gabor], ByteConversion->Identity];
Close["Cinematica.test"];

Then we write the file to the GWorld, specifying the image dimensions.

FileToGWorld["Cinematica.test", 4, 32, 32];

Then we verify that it displays correctly.

GWorldToScreen[{{4,1}}];

Combining two images

Images can be processed in Mathematica, however Mathematica can be slow. One alternative is to use the 7500/7600/8500 Graphics Driver which comes with The VideoToolbox (see the Introduction to the Read Me First! section).This allows certain monitors to refresh at a rate of 120 Hz. In this case, the human visual system will combine any two images which alternate in the display list. Another alternative is to use Cinematica.

The Cinematica function Combine2Movies allows for the rapid manipulation of images already in GWorlds. Combine2Movies scales the graylevels of one image or movie and adds them to the graylevels of another, putting the sum into a new GWorld (or GWorlds) and leaving the original images unchanged. The two images or movies must have the same dimensions. Here we will combine two images. First we write a simple image file into a GWorld and look at it.

FileToGWorld["letterC", 1, 32, 32];
ColorMap[1];
GWorldToScreen[{{1,1}}];

"letterC" is the letter C; a 32 x 32 pixel image where all of the pixels inside the C have the value 128 and all of the pixels outside the C have the value 0. Now we re-load our noise.

MovieToGWorld[2, noise];

We want to scale the letter and add it to the noise. The first argument to Combine2Movies is the index of the combined image. The second argument is the index of the image-to-be-scaled. The third argument is the scale factor (see below). The final argument is the index of the image-to-be-added. Combine2Movies produces an image whose pixels will  have the value Floor[Floor[src1ScaleFactor]*src1/128]+src2, where src1 and src2 are the corresponding pixels in the image-to-be-scaled and the image-to-be-added, respectively. Since our letter has a maximum pixel value of 128, a src1ScaleFactor of 1 will result in a combined image where the letter has an amplitude of 1; a src1ScaleFactor of 2 will result in a combined image where the letter has an amplitude of 2; etc. Our noise has pixel values between 64 and 192 (see "Displaying a single image," above). Hence the letter can have a maximum amplitude of 255 - 192 = 63.

Combine2Movies[3,1,63,2];

Now, let's look at our noisy C on a mean-gray background.

ColorMap[1,1,1];
GWorldToScreen[{{3,1}}];

Combining two movies

Combining two movies is faster than an equivalent sequence of image combinantions. To combine two movies simply make the arguments to Combine2Movies lists of numbers instead of single numbers. All lists must be of equal length. Here we again combine the scaled letter and noise. This time we will scale the letter by a series of different scale factors.

Combine2Movies[
	Table[6+i,{i,64}],
	Table[1,{64}],
	Table[64-i,{i,64}],
	Table[2,{64}]];

Now, let's look at our combined movie.

movie=Table[{6+i,1},{i,64}];
GWorldToScreen[
	Flatten[Table[Join[movie,Reverse[movie]],{3}],1]];

Setting the gamma exponent

The function ColorMap contains an optional argument that allows one to set the exponent (gamma) of a power function relating graylevels to luminance. In psychophysics this is typically set to gamma=1, so that there is a linear relation between graylevel and luminance. This is the default value for ColorMap. However, in the digital imaging and digital video communities it is almost universal to use graylevels to represent a nonlinear function of luminance, with gamma~2.2. We illustrate this here with an image that we alternate between gamma=1 and gamma=2.2.

FileToGWorld["photo", 5, 192, 128];

ColorMap[1, 1, 2, 254, {{0, .5}, {1, 0.}, {255, 1.}},1];

ColorMap[2, 1, 2, 254, {{0, .5^2.2}, {1, 0.}, {255, 1.}},2.2];

GWorldToScreen[Flatten[Table[{5,i},{4},{i,2},{64}],2]];

The one curiosity here is the first entry in the list of {graylevel,luminance} pairings in the second call to ColorMap. The exponent on the .5 is there so that a graylevel of 0 (the background) will map to the same luminance as will a graylevel of 128. This is a "mean" luminance not in the sense of midway between minimum and maximum luminances, but rather the midpoint of graylevels.

Combining images and movies with "negative" graylevels

First, let's clear the screen.

MovieToGWorld[6, Table[0, {192}, {192}]];
ColorMap[2, 0];
GWorldToScreen[{{6, 2}}];

When scaling an image, it is often desirable to pretend that the background or mean value is 0, with darker pixels having negative values. However, as far as Combine2Movies is concerned, there is no such thing as a negative graylevel. All graylevels are modulo 256. Thus, for example, adding pixels with graylevels 255 and 1 produces a pixel with graylevel 0. This subsection provides an example of how to exploit this fact in order to combine images and movies with "negative" graylevels. We will pretend that our Gabor stimulus (see above) has a background and mean value of 0, scale it, and add it to our noise stimulus.

The first step is to ensure that the to-be-scaled image has a minimum (actual) graylevel of 0. That way it will remain 0 after scaling. Our Gabor stimulus currently has a minimum graylevel of 2. Thus we will need to increase each pixel's graylevel by 254. (Mod[2+254,256]=0.)

MovieToGWorld[1,Table[254,{32},{32}]];
Combine2Movies[3,4,128,1];

We know from the previous subsection, "Combining two images," that we shouldn't add anything to our noise with a maximum graylevel greater than 63. Thus we'll want our Gabor stimulus to have a maximum graylevel no greater than than (2 X 63 equals) 126 prior to "subtracting" its mean/background graylevel from every pixel. Since our Gabor now has a maximum graylevel of 252, this means that src1ScaleFactor should satisfy the expression Floor[Floor[src1ScaleFactor]*252/128]<=126.
We'll use src1ScaleFactor=64 to get the maximum contrast. After scaling, our Gabor will have a mean/background graylevel of (126/2 equals) 63. To "subtract" 63 from each pixel's graylevel, we need to add 193 to each pixel's graylevel (Mod[-63,256]=193).

MovieToGWorld[1,Table[193,{32},{32}]];
Combine2Movies[5,3,64,1];

Finally, we combine the noise and the scaled Gabor, and display it on the screen.

Combine2Movies[1,5,128,2];
GWorldToScreen[{{1,1}}];

Displaying images dichoptically with LCD glasses

You may skip this section if you do not have LCD glasses. For more information about LCD glasses, see Hardware Requirements, above.

Once CinematicaOpen is called, one lens of the LCD glasses will be "open" and the other will be "closed." GWorldToVisor behaves just like GWorldToScreen, except that each element of its display list is a triple. The triples are of the form {image index, colormap index, leftClosed}. leftClosed must be either 1 or 0. If 1 then the left eye will be closed. If 0 then the right eye will be closed.

Here we see the noisy Gabor through the right eye.

GWorldToVisor[{{1,1,1}}]

Here we see it through the left eye.

GWorldToVisor[{{1,1,0}}]

Let's make a random-dot stereogram and load it into memory.

backgroundNoise=Table[Random[Integer, {64, 192}], {64}, {64}];

disparity=2;
rightEyeImage=Table[If[16<i<=48&&16-disparity<j<=48-disparity,
			noise[[i-16,j-16+disparity]],backgroundNoise[[i,j]]],
		{i,64},{j,64}];
leftEyeImage=Table[If[16<i<=48&&16+disparity<j<=48+disparity,
			noise[[i-16,j-16-disparity]],backgroundNoise[[i,j]]],
		{i,64},{j,64}];

MovieToGWorld[1,{leftEyeImage,rightEyeImage}]

By simultaneously switching images and eyes, depth is perceived.

GWorldToVisor[dlist=Table[{Mod[i,2]+1,1,Mod[i,2]},{i,0,1000}]]

Note that an intereference band is seen on the screen. Above the band, images are seen through the proper eye; below the band, images are seen through the other eye. The band can be positioned on the bottom of the screen by increasing the second argument to GWorldToVisor, visorOffsetSeconds (default value = 0.000). The proper value should be less than the reciprocal of the monitor's refresh rate. I find that the following example works well with my gear (refresh rate = 120 Hz).

GWorldToVisor[dlist,0.0045]

GWorldToVisor also accepts display lists of the form {image index, colormap index, leftClosed, rightward shift, upward shift}.

GWorldToVisor[Prepend[Table[{Mod[i,2]+1,1,Mod[i,2], 0, 100},{i,0,1000}],
		{6, 2, 0, 0, 0}],0.0045]

GWorldToVisor also accepts the options WarnTone and MovieTone (see Sound, above).

Closing Cinematica

To gracefully exit Cinematica, we use:

CinematicaClose[]

Note: quitting Mathematica Kernel prior to CinematicaClose[] may result in a crash!