I am currently looking at the feasibility of adding support for SVI autostereoscopic display in OSG.
Does anyone know anything about this?
So far, I have been looking at an SDK that provides an OpenGL based API and examples for driving the display. I have also been looking at the different ways OSG implements stereo modes with a view to seeing where might be the best place to perform the interlace function required to support the SVI display. I noticed that the WOWVX support is done by creating two slave cameras that render to textures, then combining the textures and wowvx headers using a pixel shader. So, at first, that seemed a good pattern to try and follow, but on reflection it's difficult for me to see how to use the SVI API in this way (even though internally I suspect something similar is going on). I seem to be floundering a bit., so I wondered if I can trouble anyone on the list to take a quick look at the attached OpenGL example code from the SVILaceOGL SDK and make any suggestions about how and where the best place to try and use the API from within OSG (or from an OSG application). Of course, if I'm successful with the integration, I'll be happy to share the result with the OSG community. ;-)
Cheers.
Chris.

/**
\file SVILaceOgl Example 1 Initialize an interlacer. Set an arbitary stereo mode and
                provide anaglyph red cyan stereo
        \author klaus.kesseler<at>spatialview.com
        \author dietrich.john<at>spatialview.com
        \author (c) http://www.spatialview.com
*/

#include "SVILaceOgl.h"
#include "OglCameras.h"

#include <vector>
#include <string>
#include <iostream>

#include <GL/glut.h>

using namespace SVI;
using namespace SVI::OglCameras;

//==============================================================================
namespace{
        int g_rotation = 0;
        int g_rotation_increment = 1;

struct IlaceData{
        IlaceOgl::IlaceHandle  interlacer;
        std::vector<GLuint> textures;
        unsigned int texWidth;
        unsigned int texHeight;
};
IlaceData g_data;

} // anonymous Namespace

//==============================================================================
void cbDisplay();
void cbResize(int w, int h);
void cbIdle(void);
void cbTimer(int );
void cbKey(unsigned char k, int , int );
//==============================================================================
// init Glut window
void initGlut(int *argc, char *argv[])
{
        //Init window position and size:

        int windowX      = 100;
        int windowY      = 100;
        int windowWidth  = 680;
        int windowHeight = 480;
        
        glutInit(argc, argv);
        glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);

        glutInitWindowSize(windowWidth, windowHeight);
        glutInitWindowPosition(windowX, windowY);
        glutCreateWindow(argv[0]);

        //call backs
        glutDisplayFunc(cbDisplay);
        glutReshapeFunc(cbResize);
        glutIdleFunc(cbIdle);
        glutTimerFunc(10000/360, cbTimer, 0);
        glutKeyboardFunc(cbKey);
}
//==============================================================================
// create the interlacer bool ilaceInit(){
        // Check for OpenGL extensions, we need
        if (!IlaceOgl::checkHardware())
        {
                std::cout << "Interlacing support is not available. Missing OpenGL 
extensions:" << std::endl;
                std::cout << IlaceOgl::getMissingExt();
                return false;
        }
        // Create an interlacer
        g_data.interlacer=IlaceOgl::createInstance();
        // Test for failure:
        if (!g_data.interlacer)
        {
                std::cout << "Failure, can not create interlacer" << std::endl;
                return false;
        }
        // Set an arbitrary Stereo Mode:
        IlaceOgl::setCurrentStereoMode(g_data.interlacer,"AnaglyphRedCyan");
        // Query the number of camera views, we need for the stereo mode:
        int camCount = IlaceOgl::getCameraCount(g_data.interlacer);

        int windowWidth  = glutGet(GLUT_WINDOW_WIDTH );
        int windowHeight = glutGet(GLUT_WINDOW_HEIGHT);
//initialize input textures g_data.textures.resize(camCount); g_data.texWidth = windowWidth; g_data.texHeight = windowHeight;
        // use a helper function from IlaceOgl to request texture id's and 
initialize the texture:
        
IlaceOgl::provideTextures(&g_data.textures[0],camCount,g_data.texWidth,g_data.texHeight);
        IlaceOgl::setTextures(g_data.interlacer, &g_data.textures[0], camCount);

int screenX = 0; // Here we use 0,0 for x,y for the first display, but we should know int screenY = 0; // the position of the display, if we use a second one.
        int screenWidth  = glutGet(GLUT_SCREEN_WIDTH);
        int screenHeight = glutGet(GLUT_SCREEN_HEIGHT);
        IlaceOgl::setScreen(g_data.interlacer, screenX, screenY, screenWidth, 
screenHeight);

        return true;
}
//------------------------------------------------------------------------------
void ilaceClear()
{
        //free the interlacer handle
        IlaceOgl::destroy(g_data.interlacer);
        //free the textures
        for(std::size_t i = 0; i < g_data.textures.size(); i++)
        {
                glDeleteTextures(1, &g_data.textures[i]);
        }
        g_data.textures.clear();
}

//------------------------------------------------------------------------------
// some initialization for OpenGL to make it look nice
void initOpenGL(void)
{
        glClearColor(0.2, 0.2, 0.2, 1.0);

        GLfloat matAmb [4]   = {1.0, 1.0, 1.0, 1.0};
        GLfloat matDiff[4]   = {1.0, 0.1, 0.2, 1.0};
        GLfloat matSpec[4]   = {1.0, 1.0, 1.0, 1.0};

        GLfloat lightPos []  = {10.0, 10.0, 10.0, 0.0};
        GLfloat lightAmb [4] = { 0.0,  0.0,  0.0, 1.0};
        GLfloat lightDiff[4] = { 1.0,  1.0,  1.0, 1.0};
        GLfloat lightSpec[4] = { 1.0,  1.0,  1.0, 1.0};

        glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, matAmb);
        glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, matDiff);
        glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, matSpec);
        glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 60.0);

        glLightfv(GL_LIGHT0, GL_POSITION, lightPos);
        glLightfv(GL_LIGHT0, GL_AMBIENT, lightAmb);
        glLightfv(GL_LIGHT0, GL_DIFFUSE, lightDiff);
        glLightfv(GL_LIGHT0, GL_SPECULAR, lightSpec);

        //cmd4 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL_EXT, 
GL_SEPARATE_SPECULAR_COLOR_EXT);
        GLfloat black[] =  {0.0, 0.0, 0.0, 1.0};
        glLightModelfv(GL_LIGHT_MODEL_AMBIENT, black);

        glEnable(GL_LIGHT0);
        glEnable(GL_LIGHTING);
        glEnable(GL_DEPTH_TEST);
}
//------------------------------------------------------------------------------
void cbIdle(void)
{
        glutPostRedisplay();
}
//------------------------------------------------------------------------------
//change the window size and position void cbResize(int w, int h)
{
        if (h == 0) h = 1;
        // init or reset window positions and dimensions of the interlacer.
   int windowX      = glutGet(GLUT_WINDOW_X);
        int windowY      = glutGet(GLUT_WINDOW_Y);
        int windowWidth  = w; // glutGet(GLUT_WINDOW_WIDTH );
        int windowHeight = h; // glutGet(GLUT_WINDOW_HEIGHT);
        
        glViewport(0, 0, windowWidth, windowHeight);

        IlaceOgl::move(g_data.interlacer, windowX, windowY);
        IlaceOgl::resize(g_data.interlacer, windowWidth, windowHeight );
        
        // also adapt the input texture size
g_data.texWidth = windowWidth; g_data.texHeight = windowHeight;
        
        glutPostRedisplay();
}
//------------------------------------------------------------------------------
void initCamera(std::vector<Matrix>& tgtCams, std::vector<Matrix>& 
tgtProjections)
{
        // init the MODEL_VIEW and PROJECTION matrices
        int windowWidth  = glutGet(GLUT_WINDOW_WIDTH );
        int windowHeight = glutGet(GLUT_WINDOW_HEIGHT);
        GLdouble aspectRatio = (GLdouble)windowWidth / (GLdouble)windowHeight;
        double separation=0.3;        // eye base width
        double zeroPlaneDistance=4.0; // distance to the plane of no disparity
        getOffAxisPerspective(&tgtProjections[0], tgtProjections.size(), 
separation, zeroPlaneDistance,
                                      45.0, aspectRatio, 0.5, 150.);
        
        GLdouble srcCamera[16] = { 1.0, 0.0, 0.0, 0.0,
                              0.0, 1.0, 0.0, 0.0,
                              0.0, 0.0, 1.0, 0.0,
                              0.0, 0.0,-4.0, 1.0};
        glMatrixMode(GL_MODELVIEW);
        glLoadMatrixd(srcCamera);
        glRotated(g_rotation, 0, 1, 0);
        Matrix sourceCamera;
        glGetDoublev(GL_MODELVIEW_MATRIX, sourceCamera.mat);
        getViewMatrixBySeparation(sourceCamera, &tgtCams[0], tgtCams.size(), 
AlignOffAxis, separation, zeroPlaneDistance);
}
//------------------------------------------------------------------------------
// draw the model
void cbDisplay()
{
        int camCount = IlaceOgl::getCameraCount(g_data.interlacer);
        std::vector<Matrix> tgtCams(camCount);
        std::vector<Matrix> tgtProjections(camCount);
        initCamera(tgtCams, tgtProjections);

        // draw each view
        for(int i = 0; i < camCount; i ++)
        {
                glClearColor(0.2, 0.2, 0.2, 1);
                glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

                // apply the MODEL_VIEW and PROJECTION matrices for the 
specific target camera
                glMatrixMode(GL_PROJECTION);
                glLoadMatrixd(tgtProjections[i].mat);
                glMatrixMode(GL_MODELVIEW);
                glLoadMatrixd( tgtCams[i].mat );

                // draw the model
                glBindTexture(GL_TEXTURE_2D, 0);
                glutSolidTeapot(1.f);
                
// copy to the frame buffer, // if your hardware support it, you can also draw direct to the texture, instead copying each view
                glBindTexture(GL_TEXTURE_2D, g_data.textures[i]);
                glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 0, 0, 
g_data.texWidth, g_data.texHeight, 0);
                glBindTexture(GL_TEXTURE_2D, 0);
        }
        // interlace the views and draw to screen
        IlaceOgl::render(g_data.interlacer);
   GLenum errorNo = glGetError();
   if (errorNo!=GL_NO_ERROR)
   {
       int j = 10;
   }
        glutSwapBuffers();
}
//------------------------------------------------------------------------------
void cbTimer(int )
{
        g_rotation = (g_rotation + g_rotation_increment) %360;
        glutTimerFunc(10000/360, cbTimer, 0);
}
//------------------------------------------------------------------------------
void cbKey(unsigned char k, int , int )
{
        switch(k)
        {
                case 27:  // quit
                case 'Q':
                case 'q':
                        ilaceClear();
                        exit(0);
                        break;
                case 'R': // start/stop rotation
                case 'r':
                        if (g_rotation_increment == 0) {g_rotation_increment = 
1; }
                        else                                       
{g_rotation_increment = 0; }
                        break;
        }
}
//==============================================================================
int main(int argc, char* argv[])
{
        //init Glut - or any other way to open an OpenGL context
        initGlut(&argc, argv);
        //initialize the material and lights for the geometry to render
        initOpenGL();
        // initialize the interlacer
        if (!ilaceInit()) {return 1; }
        // call the main loop
        glutMainLoop();
        // clean up:
        ilaceClear();
        return 0;
}
_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to