The Column Interleaved Format

Overview 

The VRex VR-4200 stereoscopic projector expects 3D stereoscopic information to be encoded in a column interleaved format.  This document describes the details of this format and give some programming tips on rendering images quickly into this format. 

Note:  The VR-4200 ships with a format converter box that is used for field sequential video signals.  This converter box will automatically format the incoming 3D stereoscopic field sequential video into the column interleaved format.  If you are using field sequential 3D video, you do not need to modify your video format.  This document is for users that want to drive the VR-4200 directly and bypass the format converter box.

 

Column Interleaved Format for the VR-4200 

The VR-4200 projector expects 3D stereoscopic data to be formatted in a specific column interleaved format.  The data is input to the projector on the RGB video connector (15 pin).  The data must be in 1024 pixel wide by 768 pixel high resolution.  Alternating columns are assigned to right and left image components as shown in Figure 1 .

 

Figure 1.  Column Format

 

Each column is a single pixel wide by 768 pixels tall.  There are 1024 columns alternating between the right image data and the left image data.  Thus, there are 512 columns for the right eye and 512 columns for the left eye. 

 

Interleaving with OpenGL

In OpenGL, you typically do not have direct pixel access.   Interleaving your left and right views as above involves using ReadPixels and WritePixels and is too time consuming.   A better method exists using only OpenGL calls.   This has the added benefit of being accelerated in hardware.

We will use the OpenGL Stencil buffer to interleave our left and right views.   The first step is to initialize the Stencil buffer with our "mask".   This function only needs to be called once!


GLubyte *mask;

void initStencilMask() {

    glClearStencil(0x0);
    glEnable(GL_STENCIL_TEST);

    glClear(GL_STENCIL_BUFFER_BIT);
    glStencilFunc(GL_ALWAYS, GL_REPLACE, GL_REPLACE);

    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

    if (mask != NULL) {
        delete [] mask ;
        mask = NULL ;
    }

    int w = width / 8;
    if (width % 8) w++;
    GLubyte * myPixels = new GLubyte[w*height];
    mask = myPixels;

    // alternating columns of 0's and 1's
    for(int i=0; i<height; i++) {
        memset(myPixels, 0x55, w);
        myPixels += w;
    }

    glRasterPos2f(0.0, 0.0);
    glDrawPixels(width, height, GL_STENCIL_INDEX, GL_BITMAP, mask);
    glFlush();
}

Once the Stencil buffer has been initiated, interleaving left and right views is fairly trivial.   NOTE: you should replace RenderLeftView() and RenderRightView() with the appropriate functions for your application.

void renderStereoView() {

    glDrawBuffer(GL_BACK);

    // render left camera view...
    // note: we do not need to use a stencil mask
    // for the left rendered view.

    RenderLeftView();

    // render right camera view...

    glStencilFunc(GL_EQUAL, 0x1, 0x1);
    glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
    RenderRightView();

    SwapBuffers();
}


Note that in this case we are rendering our left and right views at the normal, full, aspect ratio.   This method works well for most cases.   However, for scenes that have many thin (1 or 2 pixel thick) vertical lines, this method of interleaving may be unacceptable.   For this case, you can render with half the horizontal aspect ratio, and use glPixelZoom() to "stretch" the view horizontally to obtain a full aspect ratio, which is then passed through the stencil buffer.   This method produces higher quality interleaving at a performance cost.

If you have any further questions, feel free to email us at: dev@vrex.com.