_Stereoscopic Imaging_
by Andy Ramm

Example 1: 

(a)
window (-top * aspect + (half_sep * clip_near / distance), top * aspect + (half_sep * clip_near / distance), -top, top, clip_near, clip_far); translate (half_sep, 0.0, 0.0);

(b)
window (-top * aspect - (half_sep * clip_near / distance), top * aspect - (half_sep * clip_near / distance), -top, top, clip_near, clip_far); translate (-half_sep, 0.0, 0.0);


Listing One
#if STEREO
#define EYE_OFFSET 0.200    // default viewpoint separation
#define EYE_ADJUST -0.070   // default horizontal image shift adjustment

int winWidth, winHeight;    // client window
int winAdjust=30;       // Y height adjustment to "above" viewport 

GLfloat eyeDist=4.5;        // Z distance for zero parallax setting
GLfloat eyeOffset=EYE_OFFSET;   // X offset for left/right viewpoint separation
GLfloat eyeAdjust=EYE_ADJUST;   // X adjustment for horizontal image shift
#endif

static void CALLBACK Reshape(int width, int height)
{
#if STEREO
    winWidth = width;
    winHeight = height;

    // viewport and perspective matrixes must be updated every drawn frame to 
    // render left/right views in above/below format onto same client window
#else
    glViewport(0, 0, (GLint)width, (GLint)height);
    
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glFrustum(-1, 1, -1, 1, 1, 10);
    gluLookAt(2, 2, 2, 0, 0, 0, 0, 0, 1);
    glMatrixMode(GL_MODELVIEW);
#endif
}
static void CALLBACK Draw(void)
{
#if STEREO
    // calculate delta-X translation for left or right perspective view
    GLfloat dx0 = eyeAdjust;    // asymmetrical viewing pyramid offset
    GLfloat dx1 = eyeOffset;    // viewpoint separation

    // set "above" viewport for left eye rendering
    glViewport(0, (GLint)(winHeight/2 + winAdjust), (GLint)winWidth, 
                                           (GLint)(winHeight/2 - winAdjust));
    // set left-eye perspective 
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glFrustum(-1-dx0, 1-dx0, -1, 1, 1, 10); // skew viewer symmetry leftward
    glTranslatef(0+dx1, 0, 0);          // move rightward for left eye view
    glTranslatef(0, 0, -3);             // pull back to look at
    glMatrixMode(GL_MODELVIEW);
#endif // STEREO

    glLoadIdentity();
    glRotatef(xRotation, 1, 0, 0);
    glRotatef(yRotation, 0, 1, 0);
    glRotatef(zRotation, 0, 0, 1);

    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

    glColor3f(1.0, 1.0, 1.0);
    switch (whichQuadric) {
      case 0:
    glTranslatef(0, 0, -height/20.0);
    gluCylinder(quadObj,radius1/10.0,radius2/10.0,height/10.0,slices,stacks);
    break;
      case 1:
    gluSphere(quadObj, radius1/10.0, slices, stacks);
    break;
      case 2:
    gluPartialDisk(quadObj, radius2/10.0, radius1/10.0, slices, 
               stacks, angle1, angle2);
    break;
      case 3:
    gluDisk(quadObj, radius2/10.0, radius1/10.0, slices, stacks);
    break;
    }
# if STEREO
    // set "below" viewport for right eye rendering
    glViewport(0, 0, (GLint)winWidth, (GLint)(winHeight/2 - winAdjust));

    // set right-eye perspective
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glFrustum(-1+dx0, 1+dx0, -1, 1, 1, 10); // skew viewer symmetry rightward
    glTranslatef(0-dx1, 0, 0);          // move leftward for right eye view
    glTranslatef(0, 0, -3);             // pull back to look at
    glMatrixMode(GL_MODELVIEW);

    // render scene again for right-eye view
    glLoadIdentity();
    glRotatef(xRotation, 1, 0, 0);
    glRotatef(yRotation, 0, 1, 0);
    glRotatef(zRotation, 0, 0, 1);

    glColor3f(1.0, 1.0, 1.0);
    switch (whichQuadric) {
      case 0:
    glTranslatef(0, 0, -height/20.0);
    gluCylinder(quadObj, radius1/10.0, radius2/10.0, height/10.0, 
            slices, stacks);
    break;
      case 1:
    gluSphere(quadObj, radius1/10.0, slices, stacks);
    break;
      case 2:
    
    gluPartialDisk(quadObj, radius2/10.0, radius1/10.0, slices, 
               stacks, angle1, angle2);
    break;
      case 3:
    gluDisk(quadObj, radius2/10.0, radius1/10.0, slices, stacks);
    break;
    }
#endif // STEREO
    glFlush();

    if (doubleBuffer) {
    auxSwapBuffers();
    }







