StereoGL Design Considerations
General
I plan to implement in C++ in order to use VL-1.2,
a vector/matrix library that works well with OpenGL and is compatible with
regular arrays, so it will be callable from plain C. I do not plan to do
object oriented programming.
The prefix STGL_ will be used for definitions and macros, and the library
will be called "libstgl". I was going to use just SGL, but someone else
is already using it.
Stereo display methods
OpenGL-supported (hardware page-flipping)
Normally, this will use Quad-buffering, but should probably be able to
handle dual-buffer stereo, where rendering is directly into the FRONT_LEFT
and FRONT_RIGHT buffers. SGI also have some strange stereo modes that use
extensions to standard OpenGL. Are there any other special cases we need
to be aware of?
There are many systems that require specific video modes to be activated
before hardware stereo will work, and it is not handled by OpenGL. This
is a general requirement for mny methods below as well. This is really
complex for IRIX because they have many very different graphics boards.
Software page-flipping
There are some stereo display systems that alternate left and right frames
(page-flip) manually. This approach probably requires a vertical blank
interrupt, which can be fed in externally through a parallel port for video
cards that don't support a vblank interrupt. This should be very
similar to real OpenGL-supported stereo, once the driver is installed.
ELSA revelators work this way, but use BIOS code for at least part of the
page-flipping process. I don't see any special problems with this method
other than getting the page-flipping driver built and knowing how to feed
it left/right data, which may be difficult if we can't get good hardware
documentation.
Interlaced
This approach uses the interesting side-effect that interlaced displays
have naturally alternating frames of image data. It provides a fairly easy
way to get stereo-in-a-window without trashing the desktop like above/below
does. Interlaced displays can be generated pretty easily in OpenGL using
a stencil buffer with every other row set.
-
You have to know which lines in the window are odd/even for the screen.
This can be found with a glutGet, but there's no callback for a moved window,
so we will have to poll for window moving events unless someone knows a
better way.
-
Details that are one pixel in size don't look good because part of the
image is lost. Text and thin lines are especially bad. It would be better
to blur the image slightly (a 1:2:1 convolution) to lower the vertical
resolution by 50%, but this may take too much time. Maybe it should be
an option enhancement? There's not much we can do about the desktop in
windowed stereo, except to provide a special font.
-
There's the related problem that parts of the image lost from left and
right are not the same, which increases artifacts from details. This can
be easily fixed by shifting one view up or down one pixel, or both by 1/2
pixel.
-
Newer video displays often do not have interlace, because it was created
to get hi-res on old slow monitors. Several of the cheaper stereo devices
get around this by blanking alternate lines of video output by the video
card, creating artificial interlace. (Could this be stressful for some
monitor circuitry?)
Above/Below
This method works by inserting an extra vertical blank in the middle of
the screen. The result is two display frames from each actual video frame,
each stretched to just under half the original vertical resolution. This
avoids the missing-data problem of interlaced stereo, but has problems
of its own.
-
Above below trashes the desktop for stereo in a window, so it is most useful
for fullscreen stereo. The only way to fix this is with a stereo-aware
desktop. SGI does this for some of their OpenGL-supported hardware. I don't
plan to attempt this.
-
Pixels are very non-square. Most of this is handled by viewport scaling,
but it can be a problem when displaying text. A simple fix is to have a
special font. I think this is less of a problem that lost pixels with interlaced
stereo.
-
Menus have to be drawn twice; once for each view. This has to be handled
by the menuing system. It might be useful to add this to WxWindows. The
alternative is to write programs with all menus & buttons displayed
via OpenGL.
Some stereo viewing methods that don't use LCD shuttering
Anaglyph
This is the old-fashioned colored glasses. There is a big variety of color
combinations. There are two basic types: "pure anaglyph" is derived from
greyscale left and right frames. Color anaglyph allows the originals to
be colored, but color saturation must be low to keep intensities similar
for both eyes. This is a good one to implement as an alternative and cheap
method. It is easy to implement in OpenGL using color masks. Problems are:
-
We can reduce color saturation on-the-fly, but how do we deal with existing
display lists when switching to anaglyph mode?
-
It would be good to enable non-linear color saturation reduction so colors
that are already low-saturation are not effected.
Side-by-Side
Left and right images are displayed side by side, and can either be left
view on the left (straight-eyed or relaxed-eyed) or left on the right (cross-eyed).
Straight-eyed stereo works better for small images (<6cm seperation)
or when viewing through mirrors that increase the effective separation
between eyes. Some people learned stereo viewing with mirrors and
still prefer it to LCD glasses, so we should try to support this. Cross-eyed
stereo allows for unassisted viewing of larger images than straight-eyed,
but causes more strain because there is a larger disagreement between actual
focal length and the focal length your eyes expect. I think that this can
be overcome with practice, but I doubt that this is good for long-term
eye health.
-
The obvious problem here is that the aspect ratio differs a lot from the
original, and must be displayed as a smaller image. This would work best
for mirror viewing systems if menus are drawn twice, as with above/below.
Mirror
This is an interesting method that uses side-by-side display with one image
flipped left to right. First, place a mirror in front of your screen, vertical
and perpendicular to the screen surface. Next, position your eyes
near the close edge of the mirror. If you look to one side of the screen
such that one eye views a reflection, you will get a stereo image. This
could be a useful item for stereo on flat LCD displays.
-
Same problems as side-by-side, but using menus visible in stereo means
having one of them mirrored. This could be hard to do unless displayed
through OpenGL.
Pixel screening
This is a term I just made up for a group of stereo devices under development
for flat LCD displays, which can't do shuttered stereo because the refresh
rate is too slow and pixel persistence is too high. These techniques screen
out individual pixels for left or right views, instead of screening frame
by frame. I know of two methods: pixel-sized polarizing filters viewed
through polarizing glasses, and lenticular lenses which are like those
3D/animated postcards and require no glasses at all (neat!) One advantage
is that there should be no ghosting. This should be easy to implement with
stencil buffer screens, once you know which pixels go with which view.
Same problems as with interlaced (pixel sized details can be lost) but
could be harder to adjust for, depending on the pixel pattern.
User control
How should stereo display settings be controlled? It may be useful to have
a separate controller application running in the background, like a MS-Windows
tray item, or the Spaceball daemon in UNIX. This means installing an extra
program. Settings should also be controllable from the main application.
There could also be a standard GLUT menu for a quick and easy way to include
stereo control.