// Initialize GLUT & OpenSG and set up the scene
int doMain(int argc, char **argv)
{
    std::cout << "start a cluster server with './testClusterServer -w pipe0'\n"
                 "press 'c' to connect to the servers.\n"
                 "press 'd' to disconnect from the servers.\n"
                 "press 'n' to delete current scene.\n"
                 "press 't' to create a torus.\n"
                 "press 'l' to load scene 'tie.wrl'.\n"
              << std::endl;
    
    // OSG init
    OSG::osgInit(argc,argv);

    OSG::VTKPolyDataMapper::getClassType().dump();

    // GLUT init
    int winid = setupGLUT(&argc, argv);

    // the connection between GLUT and OpenSG

    _client_win = OSG::GLUTWindow::create();

    _client_win->setGlutId(winid);
    _client_win->init();
    _client_win->setSize(300,300);
    
    for(OSG::Int32 i=0;i<argc-1;++i)
    {
        if(argv[i+1] != NULL)
            _pipenames.push_back(argv[i+1]);
    }

    if(_pipenames.empty())
        _pipenames.push_back("pipe0");
    
    _root = OSG::Node::create();
    
    _root->setCore(OSG::Group::create());
    
    // create default scene
//    NodePtr scene = makeTorus(.5, 2, 16, 16);
    OSG::NodeUnrecPtr scene = initVTK();

    _root->addChild(scene);

    // create the SimpleSceneManager helper
    _mgr = OSG::SimpleSceneManager::create();

    // tell the manager what to manage
    _mgr->setWindow(_client_win );
    _mgr->setRoot  (_root);

    // show the whole scene
    _mgr->showAll();
    

    return 0;
}
// react to keys
void keyboard(unsigned char k, int x, int y)
{
    switch(k)
    {
        case 27:    
        {
            delete _mgr;

            _client_win  = NULL;
            _cluster_win = NULL;
            _root        = NULL;

            OSG::osgExit();
            exit(0);
        }
        case 'n':
            while(_root->getNChildren() > 0)
                _root->subChild(_root->getChild(0));

            glutPostRedisplay();
        break;
        case 'l':
        {
            OSG::NodeUnrecPtr scene = 
                OSG::SceneFileHandler::the()->read("tie.wrl", NULL);

            if(scene != NULL)
            {
                _root->addChild(scene);

                _mgr->showAll();

                glutPostRedisplay();
            }
        }
        break;
        case 't':
        {
            OSG::NodeUnrecPtr scene = OSG::makeTorus(.5, 2, 16, 16);

            _root->addChild(scene);

            _mgr->showAll();

            glutPostRedisplay();
        }
        break;
        case 'c':
            connectCluster();
        break;
        case 'd':
            disconnectCluster();
        break;
    }
}
OSG::NodeTransitPtr createScene(OSG::Window *win)
{
   OSG::NodeRecPtr rootN = OSG::makeNodeFor(OSG::Group::create());

   // Create ground:
   OSG::NodeUnrecPtr groundN = OSG::makePlane(25,25,1,1);
   OSG::Matrix m;
   OSG::Quaternion q;
   q.setValueAsAxisDeg(OSG::Vec3f(1,0,0), -90);
   m.setRotate(q);

   OSG::TransformUnrecPtr groundTransC = OSG::Transform::create();
   groundTransC->setMatrix(m);

   OSG::NodeUnrecPtr groundTransN = OSG::makeNodeFor(groundTransC);
   groundTransN->addChild(groundN);
   rootN->addChild(groundTransN);

   // Set ground material:
   OSG::SimpleMaterialUnrecPtr mat = OSG::SimpleMaterial::create();
   mat->setDiffuse(OSG::Color3f(0.8,0.8,0.8));
   dynamic_cast<OSG::Geometry*>(groundN->getCore())->setMaterial(mat);

//   // Create figure:
//   OSG::NodeUnrecPtr figure1N =
//         OSG::SceneFileHandler::the()->read("../Models/Figure.obj");

//   G.figure1TransC = OSG::Transform::create();
//   OSG::NodeUnrecPtr trans1N = OSG::makeNodeFor(G.figure1TransC);
//   trans1N->addChild(figure1N);
//   rootN->addChild(trans1N);

   OSG::NodeUnrecPtr figureModelA =
         OSG::SceneFileHandler::the()->read("../assets/Figure.obj");

   BoardGame::Figure* figureA = new BoardGame::Figure();
   figureA->setModel(figureModelA);
   rootN->addChild(figureA->getRoot());

   OSG::NodeUnrecPtr figureModelB =
         OSG::SceneFileHandler::the()->read("../assets/Figure.obj");

   BoardGame::Figure* figureB = new BoardGame::Figure();
   figureB->setModel(figureModelB);
   rootN->addChild(figureB->getRoot());

   G.selectedNode = figureModelA;

   return(OSG::NodeTransitPtr(rootN));
}
// Initialize GLUT & OpenSG and set up the scene
int doMain(int argc, char **argv)
{
    // OSG init
    OSG::osgInit(argc,argv);

    // GLUT init
    int winid = setupGLUT(&argc, argv);

    // the connection between GLUT and OpenSG
    OSG::GLUTWindowRecPtr gwin= OSG::GLUTWindow::create();
    gwin->setGlutId(winid);
    gwin->init();

    // put the geometry core into a node
    scene = OSG::Node::create();
    OSG::GroupRecPtr groupPtr = OSG::Group::create();
    scene->setCore(groupPtr);

    statfg = OSG::SimpleStatisticsForeground::create();
    statfg->setSize(25);
    statfg->setColor(OSG::Color4f(0,1,0,0.9f));
    statfg->addElement(textureFormatDesc, "Pixel Format: %s");
    statfg->addElement(textureDataTypeDesc, "Data Type: %s");
    statfg->addElement(textureSizeDesc, "Texture Size: %s");
    statfg->addElement(textureDimensionDesc, "Dimension: %i");
    statfg->addElement(textureBPPDesc, "BPP: %i");
    statfg->addElement(textureMipMapCountDesc, "MipMapCount: %i");
    statfg->addElement(textureFrameCountDesc, "FrameCount: %i");

    // Create the background
    OSG::SolidBackgroundRecPtr bg = OSG::SolidBackground::create();
    bg->setColor(OSG::Color3f(0.1f, 0.1f, 0.5f));

    if (argc < 2)
    {
        std::cerr << "Usage: testImageLoader <filename>" << std::endl;
        return EXIT_FAILURE;
    }

    updateScene(argv[1]);

    szFilename = argv[1];

    // create the SimpleSceneManager helper
    mgr = new OSG::SimpleSceneManager;

    // tell the manager what to manage
    mgr->setWindow(gwin );
    mgr->setRoot  (scene);

    // show the whole scene
    mgr->showAll();

    // add the statistics forground
    gwin->getPort(0)->addForeground(statfg);
    gwin->getPort(0)->setBackground(bg);


    return 0;
}
void display(void)
{
    OSG::Real32 time = glutGet(GLUT_ELAPSED_TIME);
    updateMesh(time);
    
    // we extract the core out of the root node
    // as we now this is a geometry node
    OSG::GeometryRecPtr geo = dynamic_cast<OSG::Geometry *>(scene->getCore());
    
    //now modify it's content
    
    // first we need a pointer to the position data field
    OSG::GeoPnt3fPropertyRecPtr pos = 
        dynamic_cast<OSG::GeoPnt3fProperty *>(geo->getPositions());
    
    //get the data field the pointer is pointing at
    OSG::GeoPnt3fProperty::StoredFieldType *posfield = pos->editFieldPtr();
    //get some iterators
    OSG::GeoPnt3fProperty::StoredFieldType::iterator last, it;

    // set the iterator to the first data
    it = posfield->begin();
    
    //now simply run over all entires in the array
    for (int x = 0; x < N; x++)
    {
        for (int z = 0; z < N; z++)
        {
            (*it) = OSG::Pnt3f(x, wMesh[x][z], z);
            it++;
        }
    }
    
    mgr->redraw();
}
OSG::NodeRecPtr createScenegraph(void)
{
    //create sun, planet & moon geometry

    OSG::GeometryRecPtr sun    = OSG::makeSphereGeo(3, 6);
    OSG::NodeRecPtr     planet = OSG::makeSphere   (3, 3);
    OSG::NodeRecPtr     moon   = OSG::makeSphere   (2, 1);

    //the root node will be the sun
    OSG::NodeRecPtr root = OSG::Node::create();
    root->setCore(sun);

    OSG::NodeRecPtr planetTransformNode = OSG::Node::create();
    OSG::NodeRecPtr moonTransformNode   = OSG::Node::create();

    // these were declared globally
    planetTransform = OSG::Transform::create();
    moonTransform   = OSG::Transform::create();

    // Now we need to fill it with live
    // We want to have the planet some distance away from the sun,
    // but initial with no rotation. The same aplies to the moon
    OSG::Matrix m,n;

    m.setIdentity();
    n.setIdentity();

    m.setTranslate(20, 0, 0);
    n.setTranslate( 8, 0, 0);

    planetTransform->setMatrix(m);
    moonTransform  ->setMatrix(n);

    //Insert the cores into the apropiate nodes and add the geometry
    planetTransformNode->setCore (planetTransform);
    planetTransformNode->addChild(planet         );

    moonTransformNode->setCore (moonTransform);
    moonTransformNode->addChild(moon         );

    //add the planet to the sun
    root->addChild(planetTransformNode);
    root->addChild(moonTransformNode  );

    //now we are done
    return OSG::NodeTransitPtr(root);
}
int main( int argc, char **argv )
{
    OSG::osgInit(argc,argv);
    
    QApplication::setColorSpec( QApplication::CustomColor );
    QApplication a( argc, argv );

    if ( !QGLFormat::hasOpenGL() ) {
    qWarning( "This system has no OpenGL support. Exiting." );
    return -1;
    }
    
    OpenSGWidget w(QGLFormat(QGL::DoubleBuffer | QGL::DepthBuffer | QGL::Rgba |
                             QGL::DirectRendering));

    // create the scene
    OSG::NodeRecPtr scene;
    
    if(argc > 1)
    {
        scene = OSG::Node::create();
        OSG::GroupRecPtr g = OSG::Group::create();

        scene->setCore(g);
        
        for(OSG::UInt16 i = 1; i < argc; ++i)
            scene->addChild(OSG::SceneFileHandler::the()->read(argv[i]));
    }
    else
    {
        scene = OSG::makeTorus(.5, 3, 16, 16);
    }

    w.getManager()->setRoot(scene);
    w.getManager()->showAll();

    w.show();
    return a.exec();
}
void display(void)
{
    OSG::Real32 time = glutGet(GLUT_ELAPSED_TIME);
    updateMesh(time);
    
    // we extract the core out of the root node
    // as we now this is a geometry node
    OSG::GeometryRecPtr geo = dynamic_cast<OSG::Geometry *>(scene->getCore());
    
    //now modify it's content
    
    // first we need a pointer to the position data field
    OSG::GeoPnt3fPropertyRecPtr pos = 
        dynamic_cast<OSG::GeoPnt3fProperty *>(geo->getPositions());
    
    //this loop is similar to when we generted the data during createScenegraph()
    // here they all come
    for (int x = 0; x < N; x++)
        for (int z = 0; z < N; z++)
            pos->setValue(OSG::Pnt3f(x, wMesh[x][z], z), N * x + z);
    
    mgr->redraw();
}
int main (int argc, char **argv)
{
    doMain(argc, argv);

    fprintf(stderr, "Create hdrroot %p %d %d \n",
            hdrroot.get(),
            hdrroot->getRefCount(),
            hdrroot->getWeakRefCount());

    fprintf(stderr, "Create root %p %d %d \n",
            root.get(),
            root->getRefCount(),
            root->getWeakRefCount());

    // run...
    glutMainLoop();

    return 0;
}
int main( int argc, char **argv )
{
    // OSG init
    OSG::osgInit(argc, argv);

    OSG::SceneFileHandler::the()->print();

    // create the graph

    // beacon for camera and light  
    OSG::NodeRecPtr b1n = OSG::Node::create();
    OSG::GroupRecPtr b1 = OSG::Group::create();
    b1n->setCore( b1 );

    // transformation
    OSG::NodeRecPtr t1n = OSG::Node::create();
    OSG::TransformRecPtr t1 = OSG::Transform::create();
    t1n->setCore( t1 );
    t1n->addChild( b1n );

    cam_trans = t1;

    // light
    OSG::NodeRecPtr dlight = OSG::Node::create();
    OSG::DirectionalLightRecPtr dl = OSG::DirectionalLight::create();

    dlight->setCore( dl );
    
    dl->setAmbient( .3, .3, .3, 1 );
    dl->setDiffuse( 1, 1, 1, 1 );
    dl->setDirection(0,0,1);
    dl->setBeacon( b1n);

    // root
    root = OSG::Node::create();
    OSG::GroupRecPtr gr1 = OSG::Group::create();
    root->setCore( gr1 );
    root->addChild( t1n );
    root->addChild( dlight );

    // Load the file
    OSG::NodeRecPtr file = NULL;
    
    if ( argc > 1 )
        file = OSG::SceneFileHandler::the()->read(argv[1]);
    
    if ( file == NULL )
    {
        std::cerr << "Couldn't load file, ignoring" << std::endl;
        file = OSG::makeTorus( .5, 2, 16, 16 );
    }

    OSG::commitChanges();
    
    file->updateVolume();

    OSG::Vec3f min,max;
    file->getVolume().getBounds( min, max );
    
    std::cout << "Volume: from " << min << " to " << max << std::endl;

    dlight->addChild( file );

    std::cerr << "Tree: " << std::endl;
    root->dump();

    // Camera
    OSG::PerspectiveCameraRecPtr cam = OSG::PerspectiveCamera::create();

    cam->setBeacon( b1n );
    cam->setFov( OSG::osgDegree2Rad( 60 ) );
    cam->setNear( 1 );
    cam->setFar( 4000 );

    // Background
    OSG::SolidBackgroundRecPtr bkgnd = OSG::SolidBackground::create();
    bkgnd->setColor( OSG::Color3f( 0,0,1 ) );

    // Viewport
    vp = OSG::Viewport::create();
    vp->setCamera( cam );
    vp->setBackground( bkgnd );
    vp->setRoot( root );
    vp->setSize( 0,0, 1,1 );
    
    // Action
    ract = OSG::RenderAction::create();

    // QT init
    QApplication::setColorSpec( QApplication::CustomColor );
    a = new QApplication( argc, argv );

    if ( !QGLFormat::hasOpenGL() )
    {
        qWarning( "This system has no OpenGL support. Exiting." );
        return -1;
    }

    OSG::Vec3f pos( 0, 0, max[2] + ( max[2] - min[2] ) * 1.5 );

    // Create Window
    glWidget = new MyOSGQGLWidget(
        new OSG::OSGQGLWidget::GLContext(QGLFormat::defaultFormat()), 0, 0, 0);

    glWidget->tball.setMode( OSG::Trackball::OSGObject );
    glWidget->tball.setStartPosition( pos, true );
    glWidget->tball.setSum( true );
    glWidget->tball.setTranslationMode( OSG::Trackball::OSGFree );

    glWidget->osgWin = OSG::QT4Window::create();
    glWidget->osgWin->setGlWidget( glWidget );
    glWidget->osgWin->addPort( vp );
    glWidget->osgWin->init(&MyOSGQGLWidget::initOpenGL);

    a->processEvents();

    glWidget->show();

    a->exec(); // execute QT main loop

    root      = NULL;
    file      = NULL;
    vp        = NULL;
    cam_trans = NULL;
    cam       = NULL;
    osgTWin   = NULL;

    delete glWidget;

    glWidget = NULL;

    delete a;

    return 0;
}
void init(std::vector<std::string> &filenames)
{
    size_t i;
    OSG::DirectionalLightUnrecPtr dl;
    OSG::Real32 x,y,z;
    OSG::BoxVolume volume;
    OSG::Vec3f min,max;
    OSG::Vec3f size;

    glEnable( GL_DEPTH_TEST );
    glEnable( GL_LIGHTING );
    glEnable( GL_LIGHT0 );
//    GLint twoSide = 1;
//    glLightModeliv(GL_LIGHT_MODEL_TWO_SIDE,&twoSide);
    glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );

    // create the graph

    // beacon for camera and light
    OSG::NodeUnrecPtr b1n = OSG::Node::create();
    OSG::GroupUnrecPtr b1 = OSG::Group::create();
    b1n->setCore( b1 );

    // transformation
    OSG::NodeUnrecPtr t1n = OSG::Node::create();
    OSG::TransformUnrecPtr t1 = OSG::Transform::create();
    t1n->setCore( t1 );
    t1n->addChild( b1n );

    cam_trans = t1;

    // light

    OSG::NodeUnrecPtr dlight = OSG::Node::create();
    dl = OSG::DirectionalLight::create();

    dlight->setCore( dl );

    dl->setAmbient( .3f, .3f, .3f, 1 );
    dl->setDiffuse( 1, 1, 1, 1 );
    dl->setDirection(0,0,1);
    dl->setBeacon( b1n);

    // root
    root = OSG::Node::create();

    OSG::GroupUnrecPtr gr1 = OSG::Group::create();

    root->setCore( gr1 );
    root->addChild( t1n );
    root->addChild( dlight );

    // Load the file
    OSG::NodeUnrecPtr scene = OSG::Node::create();
    scene->setCore(OSG::Group::create());

    OSG::NodeUnrecPtr file;
    for(i=0;i<filenames.size();i++)
    {
        file = OSG::SceneFileHandler::the()->read(filenames[i].c_str(),0);
        if(file != NULL)
            scene->addChild(file);
        else
            std::cerr << "Couldn't load file, ignoring " << filenames[i] << std::endl;
    }
	if ( filenames.size()==0 )
	{
        file = OSG::makeTorus( .5, 2, 16, 16 );
        scene->addChild(file);
//        scene->addChild(makeBox(.6,.6,.6,5,5,5));
    }

    prepareSceneGraph(scene);

    OSG::Thread::getCurrentChangeList()->commitChanges();

    scene->invalidateVolume();
    scene->updateVolume();
    volume=scene->getVolume();
    volume.getBounds(min,max);
    size = max-min;

    if(ca>0)
    {
        if(cb==-1)
            cb=ca;
        if(cc==-1)
            cc=cb;
            
        OSG::NodeUnrecPtr node;
        OSG::NodeUnrecPtr geoNode;
        OSG::TransformUnrecPtr trans;
        for(x=-ca/2.0 ; x<ca/2.0 ; x++)
            for(y=-cb/2.0 ; y<cb/2.0 ; y++)
                for(z=-cc/2.0 ; z<cc/2.0 ; z++)
                {
                    trans=OSG::Transform::create();
                    node=OSG::Node::create();
                    
                    node->setCore(trans);
                    trans->editMatrix().setTranslate(
                        x*size[0]*1.1,
                        y*size[1]*1.1,
                        z*size[2]*1.1);
                    geoNode = OSG::cloneTree(scene);
                    geoNode->editSFVolume()->getValue() = scene->getSFVolume()->getValue();
                    geoNode->editVolume(false).setValid(true);
                    node->addChild( geoNode );
                    dlight->addChild(node);
                }
    }
    else
    {
        dlight->addChild(scene);
	}

    if(ca>0)
    {
        sum_geometries*=OSG::UInt32(ca*cb*cc);
        sum_triangles *=OSG::UInt32(ca*cb*cc);
        sum_positions *=OSG::UInt32(ca*cb*cc);
    }

    OSG::Thread::getCurrentChangeList()->commitChanges();

//    dlight->invalidateVolume();
    printf("update Volume\n");
    dlight->updateVolume();
    printf("update Volume OK\n");

    // should check first. ok for now.
    const OSG::BoxVolume &vol = dlight->getVolume();

    OSG::Pnt3f center;

    vol.getBounds(min, max);
    vol.getCenter(center);

    size = max - min;

    std::cout << "Volume: from " << min << " to " << max << std::endl;
    std::cout << "Center: " << center << std::endl;

    // Camera

    OSG::PerspectiveCameraUnrecPtr cam = OSG::PerspectiveCamera::create();
    cam->setBeacon( b1n );
    cam->setFov( OSG::osgDegree2Rad( 60 ) );
    cam->setNear( 10 );
    cam->setFar( 50000 );

    // Solid Background
    bkgnd = OSG::SolidBackground::create();
    bkgnd->setColor( OSG::Color3f(0,0,0) );
//    bkgnd->setColor( OSG::Color3f(.1,.1,.6) );
//    bkgnd->setColor( OSG::Color3f(1,1,1) );

    // Viewport
    OSG::ViewportUnrecPtr vp1;
    OSG::ViewportUnrecPtr vp2;
    if(stereoMode == 0)
    {
        vp1 = OSG::Viewport::create();
        vp1->setCamera    ( cam );
        vp1->setBackground( bkgnd );
        vp1->setRoot      ( root );
        vp1->setSize      ( 0,0, 1,1 );

        if(multiport)
        {
            vp2 = OSG::Viewport::create();
            vp2->setCamera    ( cam );
            vp2->setBackground( bkgnd );
            vp2->setRoot      ( root );
            vp2->setSize      ( .1f, .55f, .7f,.95f );
        }
    }
    else if(stereoMode == 1)
    {
        OSG::ShearedStereoCameraDecoratorUnrecPtr deco;
        // left
        deco=OSG::ShearedStereoCameraDecorator::create();
        deco->setLeftEye(true);
        deco->setEyeSeparation(eyedistance);
        deco->setDecoratee(cam);
        deco->setZeroParallaxDistance(zeroparallax);
        vp1 = OSG::Viewport::create();
        vp1->setCamera    ( deco );
        vp1->setBackground( bkgnd );
        vp1->setRoot      ( root );
        vp1->setSize      ( 0,0, .5,1 );
        // right
        deco=OSG::ShearedStereoCameraDecorator::create();
        deco->setLeftEye(false);
        deco->setEyeSeparation(eyedistance);
        deco->setDecoratee(cam);
        deco->setZeroParallaxDistance(zeroparallax);
        vp2 = OSG::Viewport::create();
        vp2->setCamera    ( deco );
        vp2->setBackground( bkgnd );
        vp2->setRoot      ( root );
        vp2->setSize      ( .5,0,1,1 );
    }
    else if(stereoMode == 2)
    {
        OSG::ShearedStereoCameraDecoratorUnrecPtr deco;
        // left
        deco=OSG::ShearedStereoCameraDecorator::create();
        deco->setLeftEye(true);
        deco->setEyeSeparation(eyedistance);
        deco->setDecoratee(cam);
        deco->setZeroParallaxDistance(zeroparallax);
        
        OSG::ColorBufferViewportUnrecPtr cvp1 = 
            OSG::ColorBufferViewport::create();
        cvp1->setCamera    ( deco );
        cvp1->setBackground( bkgnd );
        cvp1->setRoot      ( root );
        cvp1->setSize      ( 0,0, 1,1 );
        cvp1->setRed(GL_FALSE);
        cvp1->setGreen(GL_TRUE);
        cvp1->setBlue(GL_TRUE);
        cvp1->setAlpha(GL_TRUE);
        vp1 = cvp1;
        
        // right
        deco=OSG::ShearedStereoCameraDecorator::create();
        deco->setLeftEye(false);
        deco->setEyeSeparation(eyedistance);
        deco->setDecoratee(cam);
        deco->setZeroParallaxDistance(zeroparallax);
        
        OSG::ColorBufferViewportUnrecPtr cvp2 = 
            OSG::ColorBufferViewport::create();
        cvp2->setCamera    ( deco );
        cvp2->setBackground( bkgnd );
        cvp2->setRoot      ( root );
        cvp2->setSize      ( 0,0,1,1 );
        cvp2->setRed(GL_TRUE);
        cvp2->setGreen(GL_FALSE);
        cvp2->setBlue(GL_FALSE);
        cvp2->setAlpha(GL_FALSE);
        vp2 = cvp2;
    }

    GLint glvp[4];
    glGetIntegerv( GL_VIEWPORT, glvp );
    
    if(serverx>0 && servery>0)
        clusterWindow->setSize( serverx, servery );
    else
        clusterWindow->setSize( glvp[2], glvp[3] );
    clusterWindow->addPort( vp1 );

    if(multiport || stereoMode > 0)
        clusterWindow->addPort( vp2 );

    if(serviceInterfaceValid == true)
    {
        clusterWindow->setServiceInterface(serviceInterface);

        fprintf(stderr, "tcclient use if %s\n", serviceInterface.c_str());
    }

    if(serviceAddressValid == true)
    {
        clusterWindow->setServiceAddress(serviceAddress);

        fprintf(stderr, "tcclient use ba %s\n", serviceAddress.c_str());
    }

    // tball

    OSG::Vec3f pos(min[0] + ((max[0] - min[0]) * 0.5),
                   min[1] + ((max[1] - min[1]) * 0.5),
                   max[2] + ( max[2] - min[2] ) * 1.5 );

    float scale = (max[2] - min[2] + max[1] - min[1] + max[0] - min[0]) / 6;

    tball.setMode( OSG::Trackball::OSGObject );
    tball.setStartPosition( pos, true );
    tball.setSum( true );
    tball.setTranslationMode( OSG::Trackball::OSGFree );
    tball.setTranslationScale(scale);
    tball.setRotationCenter(center);
    tball.setTranslationGen(OSG::Trackball::OSGAbsoluteTranslation);

    // run...
    std::cout << size.length() << std::endl;
    cam->setFar (size.length() * 100.0);
    cam->setNear(size.length() * 100.0 / 100000.0);
}
// Initialize GLUT & OpenSG and set up the scene
int main(int argc, char **argv)
{
    printf("Usage: testCGShader [normal map filename]\n");
    const char *normal_map_img_name = "opensg_logoDOT3.png";

    OSG::Color4f tmp;

    if( argc > 1 )
        normal_map_img_name = argv[1];

    // OSG init
    OSG::osgInit(argc,argv);

    // GLUT init
    int winid = setupGLUT(&argc, argv);

    // the connection between GLUT and OpenSG
    OSG::GLUTWindowUnrecPtr gwin= OSG::GLUTWindow::create();
    gwin->setGlutId(winid);
    gwin->setSize( 800, 800 );
    gwin->init();

    // Create the shader material

    // Read the image for the normal texture
    OSG::ImageUnrecPtr normal_map_img = OSG::Image::create();
    if(!normal_map_img->read(normal_map_img_name))
    {
        fprintf(stderr, "Couldn't read normalmap texture '%s'!\n", normal_map_img_name);
        return 1;
    }

    OSG::ChunkMaterialUnrecPtr cmat = OSG::ChunkMaterial::create();

    OSG::MaterialChunkUnrecPtr matc = OSG::MaterialChunk::create();

    matc->setAmbient(OSG::Color4f(0.1, 0.1, 0.1, 1.0));
    matc->setDiffuse(OSG::Color4f(0.3, 0.3, 0.3, 1.0));
    matc->setSpecular(OSG::Color4f(0.8, 0.8, 0.8, 1.0));
    matc->setShininess(100);
    matc->setLit(true);

    OSG::SHLChunkUnrecPtr shl = OSG::SHLChunk::create();

    shl->setVertexProgram(_vp_program);
    shl->setFragmentProgram(_fp_program);

    OSG::TextureObjChunkUnrecPtr tex_normal_map     = 
        OSG::TextureObjChunk::create();
    OSG::TextureEnvChunkUnrecPtr tex_normal_map_env = 
        OSG::TextureEnvChunk::create();

    tex_normal_map->setImage(normal_map_img);
    tex_normal_map->setMinFilter(GL_LINEAR_MIPMAP_LINEAR);
    tex_normal_map->setMagFilter(GL_LINEAR);
    tex_normal_map->setWrapS(GL_REPEAT);
    tex_normal_map->setWrapT(GL_REPEAT);
    tex_normal_map_env->setEnvMode(GL_MODULATE);

        //cmat->addChunk(matc);
    cmat->addChunk(shl);
    cmat->addChunk(tex_normal_map);
    cmat->addChunk(tex_normal_map_env);


    // create root node
    _scene = OSG::Node::create();

    // create geometry
    //GeometryPtr geo = makeLatLongSphereGeo (100, 100, 1.0);
    OSG::GeometryUnrecPtr geo = OSG::makePlaneGeo(1.0, 1.0, 100, 100);

    geo->setMaterial(cmat);

    OSG::NodeUnrecPtr torus = OSG::Node::create();
    torus->setCore(geo);

    // add torus to scene
    OSG::GroupUnrecPtr group = OSG::Group::create();

    _scene->setCore(group);
    _scene->addChild(torus);

    // create the SimpleSceneManager helper
    _mgr = new OSG::SimpleSceneManager;

    // tell the manager what to manage
    _mgr->setWindow(gwin );
    _mgr->setRoot(_scene);

    /*
    // create point headlight
    _mgr->turnHeadlightOff();
    NodePtr headlight = _mgr->getHighlight();
    PointLightPtr light    = PointLight::create();
    beginEditCP(light);
        light->setAmbient  (.3, .3, .3, 1);
        light->setDiffuse  ( 1,  1,  1, 1);
        light->setSpecular ( 1,  1,  1, 1);
        light->setBeacon   (_mgr->getCamera()->getBeacon());
    endEditCP(light);
    beginEditCP(_scene);
        _scene->setCore(light);
    endEditCP(_scene);
    */

    // show the whole scene
    _mgr->showAll();

    // GLUT main loop
    glutMainLoop();

    return 0;
}
void key(unsigned char key, int x, int y)
{
    switch ( key )
    {
        case 27:    

            fprintf(stderr, "Start Destruction\n\n");

            rentravact = NULL;

            hdrroot = NULL;
            root    = NULL;
            file    = NULL;

            cam = NULL;
            vp  = NULL;
            win = NULL;

            cam_trans   = NULL;
            scene_trans = NULL;

            pAnimTrs[0] = NULL;
            pAnimTrs[1] = NULL;
            pAnimTrs[2] = NULL;
            pAnimTrs[3] = NULL;
            pAnimTrs[4] = NULL;
            pAnimTrs[5] = NULL;
            

            OSG::osgExit(); 
            exit(0);
        case 'a':   
            glDisable( GL_LIGHTING );
            std::cerr << "Lighting disabled." << std::endl;
            break;
        case 's':   
            glEnable( GL_LIGHTING );
            std::cerr << "Lighting enabled." << std::endl;
            break;
        case 'r':   
        {
            std::cerr << "Sending ray through " << x << "," << y << std::endl;
            OSG::Line l;
            cam->calcViewRay( l, x, y, *vp );
            std::cerr << "From " << l.getPosition() << ", dir " 
                      << l.getDirection()
                      << std::endl;
        }
        break;

        case 'g':
            hdrroot->setCore(OSG::Group::create());
            break;
        case 'h':
            createHDRCore(hdrroot);
            break;
        case 'd':
            OSG::ActionDataSlotPool::the()->dumpState();
            OSG::StageIdPool       ::the()->dumpState();
            rentravact->dumpStore();
            break;
        case ' ':
        {
            OSG::Matrix     m;
            OSG::Quaternion q;
            OSG::Vec3f      v;

            q = oldq;
            v = oldv;

            oldq = tball.getRotation();
            oldv = tball.getPosition();

            move_obj = ! move_obj;
            if ( move_obj )
            {
                puts("moving object");
                tball.setMode( OSG::Trackball::OSGCamera );

            }
            else
            {
                puts("moving camera");
                tball.setMode( OSG::Trackball::OSGObject );
            }
            
            tball.setStartPosition( v, true );
            tball.setStartRotation( q, true );
        }
        break;
    }
}
// Initialize GLUT & OpenSG and set up the scene
int doMain(int argc, char **argv)
{
    printf("Press key '1', '2', or '3' to toggle the light sources.\n");
    // OSG init
    OSG::osgInit(argc,argv);

    // GLUT init
    int winid = setupGLUT(&argc, argv);

    // the connection between GLUT and OpenSG
    OSG::GLUTWindowUnrecPtr gwin= OSG::GLUTWindow::create();

    gwin->setGlutId(winid);
    gwin->setSize( 800, 800 );
    gwin->init();

    // Create the shader material

    OSG::ChunkMaterialUnrecPtr cmat = OSG::ChunkMaterial::create();

    OSG::MaterialChunkUnrecPtr matc = OSG::MaterialChunk::create();

    matc->setAmbient(OSG::Color4f(0.1f, 0.1f, 0.1f, 1.0f));
    matc->setDiffuse(OSG::Color4f(0.3f, 0.3f, 0.3f, 1.0f));
    matc->setSpecular(OSG::Color4f(0.8f, 0.8f, 0.8f, 1.0f));
    matc->setShininess(100);
    matc->setLit(true);

    OSG::ShaderProgramChunkUnrecPtr shl = OSG::ShaderProgramChunk::create();

    OSG::ShaderProgramUnrecPtr shl_vp = 
        OSG::ShaderProgram::createVertexShader();

    shl_vp->setProgram(_vp_program);

    shl->addShader(shl_vp);

    OSG::ShaderProgramUnrecPtr shl_fp = 
        OSG::ShaderProgram::createFragmentShader();

    shl_fp->setProgram(_fp_program);

    shl->addShader(shl_fp);

    shl_vp->addProceduralVariable    ("Light0Active", &light0Active);
    shl_vp->addProceduralVariable    ("Light1Active", &light1Active);
    shl_vp->addNodeProceduralVariable("Light2Active", &light2Active);

    cmat->addChunk(matc);
    cmat->addChunk(shl);

    // create root node
    _scene = OSG::Node::create();

    // create two light sources.

    OSG::TransformUnrecPtr point1_trans;

    OSG::NodeUnrecPtr point1        = 
        OSG::makeCoredNode<OSG::PointLight>(&_point1_core);
    point1_beacon = OSG::makeCoredNode<OSG::Transform >(&point1_trans);

    point1_trans->editMatrix().setTranslate(-10.0, 5.0, 5.0);

    _point1_core->setAmbient(0.0f, 0.0f, 0.0f , 1.0f);
    _point1_core->setDiffuse(1.0f, 0.0f, 0.0f, 1.0f);
    _point1_core->setSpecular(1.0f, 1.0f, 1.0f, 1.0f);
    _point1_core->setBeacon(point1_beacon);
    _point1_core->setOn(true);


    OSG::TransformUnrecPtr point2_trans;

    OSG::NodeUnrecPtr point2        =
        OSG::makeCoredNode<OSG::PointLight>(&_point2_core);
    point2_beacon = OSG::makeCoredNode<OSG::Transform >(&point2_trans);

    point2_trans->editMatrix().setTranslate(10.0, 5.0, 5.0);

    _point2_core->setAmbient(0.0f, 0.0f, 0.0f, 1.0f);
    _point2_core->setDiffuse(0.0f, 1.0f, 0.0f, 1.0f);
    _point2_core->setSpecular(1.0f, 1.0f, 1.0f, 1.0f);
    _point2_core->setBeacon(point2_beacon);
    _point2_core->setOn(true);

    point1->addChild(point2);
    
    OSG::TransformUnrecPtr point3_trans;

    OSG::NodeUnrecPtr point3        = 
        OSG::makeCoredNode<OSG::PointLight>(&_point3_core);
    
    point3_beacon = OSG::makeCoredNode<OSG::Transform >(&point3_trans);

    point3_trans->editMatrix().setTranslate(0.0, -12.0, 5.0);

    _point3_core->setAmbient(0.0f, 0.0f, 0.0f, 1.0f);
    _point3_core->setDiffuse(0.5f, 0.0f, 1.0f, 1.0f);
    _point3_core->setSpecular(1.0f, 1.0f, 1.0f, 1.0f);
    _point3_core->setBeacon(point3_beacon);
    _point3_core->setOn(true);

    point2->addChild(point3);


    // create a sphere.
    OSG::GeometryUnrecPtr geo = OSG::makeLatLongSphereGeo (100, 100, 1.0);

    geo->setMaterial(cmat);


    OSG::NodeUnrecPtr sphere = OSG::makeNodeFor(geo);

    point3->addChild(sphere);


    _scene->setCore(OSG::Group::create());
    _scene->addChild(point1);

    // create the SimpleSceneManager helper
    _mgr = OSG::SimpleSceneManager::create();

    // tell the manager what to manage
    _mgr->setWindow(gwin );
    _mgr->setRoot(_scene);

    _mgr->turnHeadlightOff();

    // show the whole scene
    _mgr->showAll();

    // enable local lights.
//    OSG::RenderAction *ract = 
//        dynamic_cast<OSG::RenderAction *>(_mgr->getRenderAction());

//    ract->setLocalLights(true);

    return 0;
}
// Initialize GLUT & OpenSG and set up the scene
int doMain(int argc, char **argv)
{
    // OSG init
    OSG::osgInit(argc,argv);

    // GLUT init
    int winid = setupGLUT(&argc, argv);

    // the connection between GLUT and OpenSG
    OSG::GLUTWindowUnrecPtr gwin= OSG::GLUTWindow::create();
    gwin->setGlutId(winid);
    gwin->setSize( 800, 800 );
    gwin->init();

    // Create the shader material
    OSG::ChunkMaterialUnrecPtr cmat = OSG::ChunkMaterial::create();

    // Read the image for the normal texture
    OSG::ImageUnrecPtr earth_map_img = OSG::Image::create();
    if(!earth_map_img->read("Earth.jpg"))
    {
        fprintf(stderr, "Couldn't read texture 'Earth.jpg'\n");
        return 1;
    }
    OSG::TextureObjChunkUnrecPtr tex_earth     = OSG::TextureObjChunk::create();
    OSG::TextureEnvChunkUnrecPtr tex_earth_env = OSG::TextureEnvChunk::create();

    tex_earth->setImage(earth_map_img);
    tex_earth->setMinFilter(GL_LINEAR_MIPMAP_LINEAR);
    tex_earth->setMagFilter(GL_LINEAR);
    tex_earth->setWrapS(GL_REPEAT);
    tex_earth->setWrapT(GL_REPEAT);

    tex_earth_env->setEnvMode(GL_MODULATE);

    // Read the image for the normal texture
    OSG::ImageUnrecPtr earth_night_map_img = OSG::Image::create();
    if(!earth_night_map_img->read("EarthNight.jpg"))
    {
        fprintf(stderr, "Couldn't read texture 'EarthNight.jpg'\n");
        return 1;
    }

    OSG::TextureObjChunkUnrecPtr tex_earth_night     = 
        OSG::TextureObjChunk::create();
    OSG::TextureEnvChunkUnrecPtr tex_earth_night_env = 
        OSG::TextureEnvChunk::create();

    tex_earth_night->setImage(earth_night_map_img);
    tex_earth_night->setMinFilter(GL_LINEAR_MIPMAP_LINEAR);
    tex_earth_night->setMagFilter(GL_LINEAR);
    tex_earth_night->setWrapS(GL_REPEAT);
    tex_earth_night->setWrapT(GL_REPEAT);

    tex_earth_night_env->setEnvMode(GL_MODULATE);
    
    // Read the image for the normal texture
    OSG::ImageUnrecPtr earth_clouds_map_img = OSG::Image::create();
    if(!earth_clouds_map_img->read("EarthClouds.jpg"))
    {
        fprintf(stderr, "Couldn't read texture 'EarthClouds.jpg'\n");
        return 1;
    }

    OSG::TextureObjChunkUnrecPtr tex_earth_clouds     = 
        OSG::TextureObjChunk::create();
    OSG::TextureEnvChunkUnrecPtr tex_earth_clouds_env = 
        OSG::TextureEnvChunk::create();

    tex_earth_clouds->setImage(earth_clouds_map_img);
    tex_earth_clouds->setMinFilter(GL_LINEAR_MIPMAP_LINEAR);
    tex_earth_clouds->setMagFilter(GL_LINEAR);
    tex_earth_clouds->setWrapS(GL_REPEAT);
    tex_earth_clouds->setWrapT(GL_REPEAT);

    tex_earth_clouds_env->setEnvMode(GL_MODULATE);


    _shl = OSG::ShaderProgramChunk::create();

    _shl_vp = OSG::ShaderProgram::create();
    _shl_fp = OSG::ShaderProgram::create();
    
    if(!_shl_vp->readProgram("Earth.vp"))
        fprintf(stderr, "Couldn't read vertex program 'Earth.vp'\n");
    if(!_shl_fp->readProgram("Earth.fp"))
        fprintf(stderr, "Couldn't read fragment program 'Earth.fp'\n");

    _shl_vp->setShaderType(GL_VERTEX_SHADER);
    _shl_fp->setShaderType(GL_FRAGMENT_SHADER);

    _shl->addVertexShader  (_shl_vp);
    _shl->addFragmentShader(_shl_fp);

    _shl_fp->addUniformVariable("EarthDay", 0);
    _shl_fp->addUniformVariable("EarthNight", 1);
    _shl_fp->addUniformVariable("EarthCloudGloss", 2);

    _shl_vp->addUniformVariable("season", 0.0f);
    _shl_vp->addUniformVariable("cos_time_0_2PI", -0.406652f);
    _shl_vp->addUniformVariable("sin_time_0_2PI", -0.913583f);
//    _shl->setUniformParameter("foo", -0.913583f);

    
    cmat->addChunk(_shl);
    cmat->addChunk(tex_earth);
    cmat->addChunk(tex_earth_env);
    cmat->addChunk(tex_earth_night);
    cmat->addChunk(tex_earth_night_env);
    cmat->addChunk(tex_earth_clouds);
    cmat->addChunk(tex_earth_clouds_env);


    // create root node
    _scene = OSG::Node::create();

    OSG::GeometryUnrecPtr geo = OSG::makeLatLongSphereGeo (100, 100, 1.0);

    geo->setMaterial(cmat);


    OSG::NodeUnrecPtr torus = OSG::Node::create();
    
    torus->setCore(geo);


    // add torus to scene
    OSG::GroupUnrecPtr group = OSG::Group::create();

    _scene->setCore(group);
    _scene->addChild(torus);


    // create the SimpleSceneManager helper
    _mgr = OSG::SimpleSceneManager::create();

    // tell the manager what to manage
    _mgr->setWindow(gwin );
    _mgr->setRoot(_scene);

    // show the whole scene
    _mgr->showAll();

    return 0;
}
// Initialize GLUT & OpenSG and set up the scene
int doMain(int argc, char **argv)
{
    // OSG init
    OSG::osgInit(argc,argv);

    // GLUT init
    int winid = setupGLUT(&argc, argv);

    // the connection between GLUT and OpenSG
    OSG::GLUTWindowUnrecPtr gwin = OSG::GLUTWindow::create();
    gwin->setGlutId(winid);
    gwin->setSize( 800, 800 );
    gwin->init();

    // Create the shader material
    OSG::ChunkMaterialUnrecPtr cmat = OSG::ChunkMaterial::create();

    OSG::SHLChunkUnrecPtr shl = OSG::SHLChunk::create();

    shl->setProgramParameter(GL_GEOMETRY_INPUT_TYPE_EXT, 
                             GL_TRIANGLES);
    shl->setProgramParameter(GL_GEOMETRY_OUTPUT_TYPE_EXT, 
                             GL_TRIANGLE_STRIP);
    shl->setProgramParameter(GL_GEOMETRY_VERTICES_OUT_EXT, 6);

    shl->setVertexProgram(_vertex_shader);
    shl->setFragmentProgram(_fragment_shader);
    shl->setGeometryProgram(_geometry_shader);

    cmat->addChunk(shl);

    // create root node
    _scene = OSG::Node::create();

    // create torus
    OSG::GeometryUnrecPtr geo = OSG::makeTorusGeo(.8, 1.8, 128, 128);

    geo->setMaterial(cmat);

    OSG::NodeUnrecPtr torus = OSG::Node::create();

    torus->setCore(geo);

    // add torus to scene
    OSG::GroupUnrecPtr group = OSG::Group::create();

    _scene->setCore(group);
    _scene->addChild(torus);

    // create the SimpleSceneManager helper
    _mgr = OSG::SimpleSceneManager::create();

    // tell the manager what to manage
    _mgr->setWindow(gwin );
    _mgr->setRoot(_scene);

    // show the whole scene
    _mgr->showAll();

    return 0;
}
int main (int argc, char **argv)
{
    OSG::osgInit(argc, argv);

    Foo foo;

    OSG::Thread::getCurrentChangeList()->clear();

    OSG::NodeRecPtr pNode = OSG::Node::create();

    OSG::ChangedFunctor objCB = boost::bind(&Foo::testCB, &foo, _1, _2, _3);

    pNode->addChangedFunctor(testCB, "");
    pNode->addChangedFunctor(objCB, "");

    pNode->setTravMask(0);

    fprintf(stderr, "Test 1\n");
    OSG::Thread::getCurrentChangeList()->commitChanges();
   


    pNode->addChangedFunctor(testCB, "");

    pNode->setTravMask(1);

    fprintf(stderr, "Test 2 \n");
    OSG::Thread::getCurrentChangeList()->commitChanges();



    pNode->subChangedFunctor(testCB);

    pNode->setTravMask(1);

    fprintf(stderr, "Test 3\n");
    OSG::Thread::getCurrentChangeList()->commitChanges();

    
    pNode->addChangedFunctor(testCB, "");

    pNode->setTravMask(1);

    fprintf(stderr, "Test 4 \n");
    OSG::Thread::getCurrentChangeList()->commitChanges();


    pNode->subChangedFunctor(testCB);

    pNode->setTravMask(1);

    fprintf(stderr, "Test 5\n");
    OSG::Thread::getCurrentChangeList()->commitChanges();

    fprintf(stderr, "Delete\n");
    pNode = NULL;
}
OSG::NodeTransitPtr createScenegraph(void)
{
    // At first we load all needed models from file
    OSG::NodeRecPtr w_high   = 
        OSG::SceneFileHandler::the()->read("Data/woman_high.wrl");

    OSG::NodeRecPtr w_medium = 
        OSG::SceneFileHandler::the()->read("Data/woman_medium.wrl");

    OSG::NodeRecPtr w_low    = 
        OSG::SceneFileHandler::the()->read("Data/woman_low.wrl");
    
    // we check the result
    if((w_high == NULL) || (w_medium == NULL)|| (w_low == NULL))
    {
        std::cout << "It was not possible to load all needed models from file"
                << std::endl;
        return OSG::NodeTransitPtr();
    }
    
    // now the LOD core
    OSG::DistanceLODRecPtr lod = OSG::DistanceLOD::create();
    lod->editSFCenter()->setValue(OSG::Pnt3f(0,0,0));
    lod->editMFRange()->push_back(200);
    lod->editMFRange()->push_back(500);
    
    // the node containing the LOD core. The three models will be
    // added as its children
    OSG::NodeRecPtr lodNode = OSG::Node::create();
    lodNode->setCore(lod);
    lodNode->addChild(w_high);
    lodNode->addChild(w_medium);
    lodNode->addChild(w_low);
    
    // create the node with switch core ********************
    OSG::SwitchRecPtr sw = OSG::Switch::create();
    //Notice: the first choice is 0
    sw->setChoice(0);
    
    OSG::NodeRecPtr switchNode = OSG::Node::create();
    switchNode->setCore(sw);
    switchNode->addChild(lodNode);
    
    //end switch creation **********************************
    
    OSG::NodeRecPtr root = OSG::Node::create();
    root->setCore(OSG::Group::create());
    root->addChild(switchNode);
    
    // we know want to extract the mesh geometry out of the graph
    // it is sufficent to pass the model only as root for searching
    OSG::NodeRecPtr     womanGeometry = checkName(w_high);
    OSG::GeometryRecPtr geo = 
        dynamic_cast<OSG::Geometry *>(womanGeometry->getCore());
    
    //new node with "old" geometry core referenced
    OSG::NodeRecPtr woman = OSG::Node::create();
    woman->setCore(geo);
    
    //translate it a bit to see both women
    OSG::NodeRecPtr      womanTrans = OSG::Node     ::create();
    OSG::TransformRecPtr t          = OSG::Transform::create();
    OSG::Matrix m;
    m.setIdentity();
    m.setTranslate(OSG::Vec3f(0,0,200));
    t->setMatrix(m);
        
    womanTrans->setCore(t);
    womanTrans->addChild(woman);
    
    //add it to the root
    root->addChild(womanTrans);
    
    return OSG::NodeTransitPtr(root);
}
// Initialize GLUT & OpenSG and set up the scene
int doMain(int argc, char **argv)
{
    printf("Usage: testCGShader [normal map filename]\n");
    const char *normal_map_img_name = "opensg_logoDOT3.png";

    OSG::Color4f tmp;

    if( argc > 1 )
        normal_map_img_name = argv[1];

    // OSG init
    OSG::osgInit(argc,argv);

    // GLUT init
    int winid = setupGLUT(&argc, argv);

    // the connection between GLUT and OpenSG
    OSG::GLUTWindowUnrecPtr gwin= OSG::GLUTWindow::create();
    gwin->setGlutId(winid);
    gwin->setSize( 800, 800 );
    gwin->init();

    // Create the shader material

    // Read the image for the normal texture
    OSG::ImageUnrecPtr normal_map_img = OSG::Image::create();
    if(!normal_map_img->read(normal_map_img_name))
    {
        fprintf(stderr, "Couldn't read normalmap texture '%s'!\n", normal_map_img_name);
        return 1;
    }

    OSG::ChunkMaterialUnrecPtr cmat = OSG::ChunkMaterial::create();

    OSG::MaterialChunkUnrecPtr matc = OSG::MaterialChunk::create();

    matc->setAmbient(OSG::Color4f(0.1, 0.1, 0.1, 1.0));
    matc->setDiffuse(OSG::Color4f(0.3, 0.3, 0.3, 1.0));
    matc->setSpecular(OSG::Color4f(0.8, 0.8, 0.8, 1.0));
    matc->setShininess(100);
    matc->setLit(true);

    OSG::ShaderProgramChunkUnrecPtr shl = OSG::ShaderProgramChunk::create();

    OSG::ShaderProgramUnrecPtr shl_vp = 
        OSG::ShaderProgram::createVertexShader();
    
    shl_vp->setProgram(_vp_program);
    shl_vp->setProgramAttribute(OSG::ShaderConstants::TexCoordsIndex, "TexCoord0");
    shl_vp->setProgramAttribute(OSG::ShaderConstants::NormalsIndex,   "Normal"  );
    shl_vp->setProgramAttribute(OSG::ShaderConstants::PositionsIndex, "Position");

    shl->addShader(shl_vp);

    OSG::ShaderProgramUnrecPtr shl_fp = 
        OSG::ShaderProgram::createFragmentShader();

    shl_fp->setProgram(_fp_program);

    shl->addShader(shl_fp);


    OSG::TextureObjChunkUnrecPtr tex_normal_map     = 
        OSG::TextureObjChunk::create();
    OSG::TextureEnvChunkUnrecPtr tex_normal_map_env = 
        OSG::TextureEnvChunk::create();

    tex_normal_map->setImage(normal_map_img);
    tex_normal_map->setMinFilter(GL_LINEAR_MIPMAP_LINEAR);
    tex_normal_map->setMagFilter(GL_LINEAR);
    tex_normal_map->setWrapS(GL_REPEAT);
    tex_normal_map->setWrapT(GL_REPEAT);
    tex_normal_map_env->setEnvMode(GL_MODULATE);

        //cmat->addChunk(matc);
    cmat->addChunk(shl);
    cmat->addChunk(tex_normal_map);
    cmat->addChunk(tex_normal_map_env);


    // create root node
    _scene = OSG::Node::create();

    // create geometry
    //GeometryPtr geo = makeLatLongSphereGeo (100, 100, 1.0);
    OSG::GeometryUnrecPtr geo = OSG::makePlaneGeo(1.0, 1.0, 100, 100);

    geo->setMaterial(cmat);

    OSG::NodeUnrecPtr torus = OSG::Node::create();
    torus->setCore(geo);

    // add torus to scene
    OSG::GroupUnrecPtr group = OSG::Group::create();

    _scene->setCore(group);
    _scene->addChild(torus);

    // create the SimpleSceneManager helper
    _mgr = new OSG::SimpleSceneManager;

    // tell the manager what to manage
    _mgr->setWindow(gwin );
    _mgr->setRoot(_scene);

    // show the whole scene
    _mgr->showAll();

    return 0;
}
void updateScene(const std::string &filename, OSG::Image::PixelFormat compressTo = OSG::Image::OSG_INVALID_PF)
{
    // Try to create the new image
    OSG::ImageRecPtr imagePtr = 
        OSG::ImageFileHandler::the()->read(filename.c_str());

    if (imagePtr == NULL)
        return;

    if(compressTo != OSG::Image::OSG_INVALID_PF)
    {
        imagePtr->reformat(compressTo);
    }

    // Update information on the screen
    OSG::StatStringElem *statElem = 
        statfg->editCollector()->getElem(textureFormatDesc);

    switch (imagePtr->getPixelFormat())
    {
        case OSG::Image::OSG_A_PF:
            statElem->set("OSG_A_PF");
            break;
        case OSG::Image::OSG_I_PF:
            statElem->set("OSG_I_PF");
            break;
        case OSG::Image::OSG_L_PF:
            statElem->set("OSG_L_PF");
            break;
        case OSG::Image::OSG_LA_PF:
            statElem->set("OSG_LA_PF");
            break;
        case OSG::Image::OSG_RGB_PF:
            statElem->set("OSG_RGB_PF");
            break;
        case OSG::Image::OSG_RGBA_PF:
            statElem->set("OSG_RGBA_PF");
            break;
        case OSG::Image::OSG_BGR_PF:
            statElem->set("OSG_BGRA_PF");
            break;
        case OSG::Image::OSG_BGRA_PF:
            statElem->set("OSG_BGRA_PF");
            break;
        case OSG::Image::OSG_RGB_DXT1:
            statElem->set("OSG_RGB_DXT1");
            break;
        case OSG::Image::OSG_RGBA_DXT1:
            statElem->set("OSG_RGBA_DXT1");
            break;
        case OSG::Image::OSG_RGBA_DXT3:
            statElem->set("OSG_RGBA_DXT3");
            break;
        case OSG::Image::OSG_RGBA_DXT5:
            statElem->set("OSG_RGBA_DXT5");
            break;
        default:
            statElem->set("???");
            break;
    }
    statElem = statfg->editCollector()->getElem(textureDataTypeDesc);
    switch (imagePtr->getDataType())
    {
        case OSG::Image::OSG_UINT8_IMAGEDATA:
            statElem->set("OSG_UINT8_IMAGEDATA");
            break;
        case OSG::Image::OSG_UINT16_IMAGEDATA:
            statElem->set("OSG_UINT16_IMAGEDATA");
            break;
        case OSG::Image::OSG_UINT32_IMAGEDATA:
            statElem->set("OSG_UINT32_IMAGEDATA");
            break;
        case OSG::Image::OSG_FLOAT16_IMAGEDATA:
            statElem->set("OSG_FLOAT16_IMAGEDATA");
            break;
        case OSG::Image::OSG_FLOAT32_IMAGEDATA:
            statElem->set("OSG_FLOAT32_IMAGEDATA");
            break;
        case OSG::Image::OSG_INT16_IMAGEDATA:
            statElem->set("OSG_INT16_IMAGEDATA");
            break;
        case OSG::Image::OSG_INT32_IMAGEDATA:
            statElem->set("OSG_INT32_IMAGEDATA");
            break;
        default:
            statElem->set("???");
            break;
    }
    ostringstream os;
    os << imagePtr->getWidth() << 'x' << imagePtr->getHeight() << 'x' << imagePtr->getDepth();
    statfg->editCollector()->getElem(textureSizeDesc)->set(os.str());
    statfg->editCollector()->getElem(textureDimensionDesc)->set(imagePtr->getDimension());
    statfg->editCollector()->getElem(textureBPPDesc)->set(imagePtr->getBpp());
    statfg->editCollector()->getElem(textureMipMapCountDesc)->set(imagePtr->getMipMapCount());
    statfg->editCollector()->getElem(textureFrameCountDesc)->set(imagePtr->getFrameCount());

    // Put it all together into a Geometry NodeCore.
    OSG::GeometryRecPtr geo = OSG::makePlaneGeo(imagePtr->getWidth(), imagePtr->getHeight(), 1, 1);
    OSG::NodeRecPtr imageNode = OSG::Node::create();
    imageNode->setCore(geo);
    OSG::NodeRecPtr transNodePtr = OSG::Node::create();
    OSG::TransformRecPtr transPtr = OSG::Transform::create();
    OSG::Matrix transMatrix;
    transMatrix.setTranslate(0.f, 0.f, -1.f);
    transPtr->setMatrix(transMatrix);
    transNodePtr->setCore(transPtr);
    transNodePtr->addChild(imageNode);

    OSG::TextureObjChunkRecPtr texObjChunk = OSG::TextureObjChunk::create();
    texObjChunk->setImage(imagePtr);
    texObjChunk->setWrapS(GL_CLAMP);
    texObjChunk->setWrapT(GL_CLAMP);
    texObjChunk->setMagFilter(GL_NEAREST);
    texObjChunk->setMinFilter(GL_NEAREST);
    OSG::TextureEnvChunkRecPtr texEnvChunk = OSG::TextureEnvChunk::create();
    texEnvChunk->setEnvMode(GL_MODULATE);

    OSG::MaterialChunkRecPtr matChunk = OSG::MaterialChunk::create();
    matChunk->setAmbient(OSG::Color4f(1.f, 1.f, 1.f, 1.f));
    matChunk->setDiffuse(OSG::Color4f(1.f, 1.f, 1.f, 1.f));
    matChunk->setEmission(OSG::Color4f(0.f, 0.f, 0.f, 1.f));
    matChunk->setSpecular(OSG::Color4f(0.f, 0.f, 0.f, 1.f));
    matChunk->setShininess(0);

    OSG::ChunkMaterialRecPtr m = OSG::ChunkMaterial::create();
    m->addChunk(texObjChunk);
    m->addChunk(texEnvChunk);
    m->addChunk(matChunk);

    geo->setMaterial(m);

    scene->clearChildren();
    scene->addChild(transNodePtr);

    if(compressTo != OSG::Image::OSG_INVALID_PF)
    {
        OSG::SceneFileHandler::the()->write(scene->getChild(0), 
                                            "/tmp/comp.osb");
        OSG::SceneFileHandler::the()->write(scene->getChild(0), 
                                            "/tmp/comp.osg");
    }

}
int main(int argc, char **argv)
{
    OSG::osgInit(argc,argv);
    
    if(argc > 1 && !strcmp(argv[1],"-s"))
    {
        show = false;
        argv++;
        argc--;
    }
    
    if(argc > 1 && !strcmp(argv[1],"-d"))
    {
        debug = true;
        argv++;
        argc--;
    }

    
    if(argc > 1)
    {
        scene = OSG::Node::create();
        OSG::GroupUnrecPtr g = OSG::Group::create();
        
        scene->setCore(g);
        
        for(OSG::UInt16 i = 1; i < argc; ++i)
            scene->addChild(OSG::SceneFileHandler::the()->read(argv[i]));
    }
    else
    {
        scene = OSG::makeTorus(.5, 3, 16, 16);
    }

    // GLUT init
    glutInit(&argc, argv);
    
    glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);

    glutInitWindowSize(1024, 768);
    mainwinid = glutCreateWindow("OpenSG");
    
    glutReshapeFunc(reshape);
    glutDisplayFunc(display);
    glutIdleFunc(idle);
    glutMouseFunc(mouse);
    glutMotionFunc(motion);
    glutKeyboardFunc(keyboard);

    OSG::GLUTWindowUnrecPtr mainwin=OSG::GLUTWindow::create();
    mainwin->setGlutId(mainwinid);
    mainwin->init();
    
    // create the SimpleSceneManager helper
    mgr = OSG::SimpleSceneManager::create();

    // create the window and initial camera/viewport
    mgr->setWindow(mainwin);
    // tell the manager what to manage
    mgr->setRoot  (scene);

    OSG::commitChanges();

    // show the whole scene
    mgr->showAll();

    mgr->setUseTraversalAction(true);

    tact      = OSG::RenderAction::create();
#ifdef OSG_OLD_RENDER_ACTION
    act       = OSG::RenderAction::create();
#endif
    debugact  = OSG::RenderAction::create();
    tact->setOcclusionCulling(true);


    // Open the debug window
    if(debug)
    {
        OSG::traverse(scene, initMask);

        glutInitWindowSize(800, 400);
        debugwinid = glutCreateWindow("OpenSG Occlusion Debugging");

        glutReshapeFunc(reshape);
        glutDisplayFunc(display);
        glutIdleFunc(display);
        glutKeyboardFunc(keyboard);

        debugwin=OSG::GLUTWindow::create();
        debugwin->setGlutId(debugwinid);
        debugwin->init();       
        
        OSG::ViewportUnrecPtr vp = mainwin->getPort(0);
        
        OSG::ViewportUnrecPtr newvp = OSG::Viewport::create();        
        newvp->setLeft(0);
        newvp->setRight(0.5);
        newvp->setBottom(0);
        newvp->setTop(1);
        newvp->setRoot(vp->getRoot());
        newvp->setCamera(vp->getCamera());
        newvp->setBackground(vp->getBackground());
        newvp->setTravMask(0x1);
        debugwin->addPort(newvp);
        
        newvp = OSG::Viewport::create();        
        newvp->setLeft(0.5);
        newvp->setRight(1);
        newvp->setBottom(0);
        newvp->setTop(1);
        newvp->setRoot(vp->getRoot());
        newvp->setCamera(vp->getCamera());
        newvp->setBackground(vp->getBackground());
        newvp->setTravMask(0x2);
        debugwin->addPort(newvp);
        
        tact->setOcclusionCullingDebug(true);
        tact->setOcclusionDebugMasks(0x1, 0x2, 0x4);
    }

    // add the statistics forground
    
    statfg = OSG::SimpleStatisticsForeground::create();
    
    statfg->setSize(25);
    statfg->setColor(OSG::Color4f(0,1,0,0.7f));

    statfg->addElement(OSG::RenderAction::statDrawTime, 
                       "Draw FPS: %r.3f");
    statfg->addElement(OSG::RenderAction::statNMatrices, 
                       "Matrix Changes: %d");
    statfg->addElement(OSG::RenderAction::statNStates, 
                       "State Changes: %d");
                       
    statfg->addElement(OSG::RenderPartition::statCullTestedNodes, 
                       "Cull-tested Nodes: %d");
    statfg->addElement(OSG::RenderPartition::statCulledNodes, 
                       "Culled Nodes: %d");

    statfg->addElement(OSG::OcclusionCullingTreeBuilder::statNOccNodes, 
                       "Nodes in DrawTree: %d");
    statfg->addElement(OSG::OcclusionCullingTreeBuilder::statNOccTests, 
                       "Occ Tests: %d");
    statfg->addElement(OSG::OcclusionCullingTreeBuilder::statNOccInvisible, 
                       "Invisible Nodes: %d");
    statfg->addElement(OSG::OcclusionCullingTreeBuilder::statNOccSuccessTestPer, 
                       "OCC Success rate: %per%%");
    statfg->addElement(OSG::OcclusionCullingTreeBuilder::statNOccTriangles, 
                       "Triangles culled: %d");
   
    collector = statfg->getCollector();

    tact->setStatCollector(collector);
#ifdef OSG_OLD_RENDER_ACTION
    act ->setStatCollector(collector);
#endif

    mgr->setAction(tact);
#ifdef OSG_OLD_RENDER_ACTION
    mgr->setAction( act);
#endif

    //tact->setOcclusionCullingMinimumFeatureSize(15);
    //tact->setOcclusionCullingVisibilityThreshold(15);
    //tact->setScreenLODCoverageThreshold(0.005);
    
    if(show)
    {
        mainwin->getPort(0)->addForeground(statfg);
    }

#ifdef OSG_WITH_NVPERFSDK
    NVPMRESULT status;

    status = NVPMInit();
    if (status != NVPM_OK) {
        FFATAL(("NVPerfSDK failed to initialize - no GPU data will be available"));
    }
    else
    {
        nvDataProvider->add("gpu_idle");
        nvDataProvider->add("pixel_shader_busy");
        nvDataProvider->add("vertex_shader_busy");
        nvDataProvider->add("shader_waits_for_texture");
        if (!nvDataProvider->add("OGL FPS")) 
            FLOG(("nvDataProvider::add: 'OGL FPS' failed!\n"));
        
        statfg->addElement(GPUIdleStat);
        statfg->addElement(PSBusyStat);
        statfg->addElement(VSBusyStat);
        statfg->addElement(TextureWaitStat);
        statfg->addElement(OGLFPSStat);        
    }
#endif
    
    // GLUT main loop
    glutMainLoop();

    return 0;
}
int doMain (int argc, char **argv)
{
    osx_AllowForeground();

    // OSG init

    OSG::osgInit(argc, argv);

    // create the graph

    // beacon for camera and light
    OSG::NodeUnrecPtr b1n = OSG::Node::create();
    OSG::GroupUnrecPtr b1 = OSG::Group::create();
    b1n->setCore( b1 );

    // transformation
    OSG::NodeUnrecPtr t1n = OSG::Node::create();
    OSG::TransformUnrecPtr t1 = OSG::Transform::create();
    t1n->setCore( t1 );
    t1n->addChild( b1n );

    cam_trans = t1;

    // light

    OSG::NodeUnrecPtr dlight = OSG::Node::create();
    OSG::DirectionalLightUnrecPtr dl = OSG::DirectionalLight::create();

    dlight->setCore( dl );

    dl->setAmbient( .0, .0, .0, 1 );
    dl->setDiffuse( .8, .8, .8, .8 );
    dl->setDirection(0,0,1);
    dl->setBeacon( b1n);

    // root
    root = OSG::Node::create();
    OSG::GroupUnrecPtr gr1 = OSG::Group::create();

    root->setCore( gr1 );
    root->addChild( t1n );
    root->addChild( dlight );

    // Load the file

    OSG::NodeUnrecPtr file = NULL;

    if ( argc > 1 )
        file = OSG::SceneFileHandler::the()->read(argv[1]);

    if ( file == NULL )
    {
        std::cerr << "Couldn't load file, ignoring" << std::endl;
        file = OSG::makeTorus( .5, 2, 16, 16 );
    }

    OSG::Thread::getCurrentChangeList()->commitChanges();
    file->updateVolume();

    OSG::Vec3f min,max;
    file->getVolume().getBounds( min, max );

    std::cout << "Volume: from " << min << " to " << max << std::endl;

    dlight->addChild( file );

    std::cerr << "Tree: " << std::endl;
    //root->dump();

    // Camera
    cam = OSG::PerspectiveCamera::create();

    cam->setBeacon( b1n );
    cam->setFov( OSG::osgDegree2Rad( 90 ) );
    cam->setNear( 0.1 );
    cam->setFar( 100000 );

    // Background
    OSG::SolidBackgroundUnrecPtr bkgnd = OSG::SolidBackground::create();

    bkgnd->setColor(OSG::Color3f(0,0,1));

    // Viewport

    vp = OSG::Viewport::create();
    vp->setCamera( cam );
    vp->setBackground( bkgnd );
    vp->setRoot( root );
    vp->setSize( 0,0, 1,1 );

    // Action

    ract = OSG::RenderAction::create();

    // tball

    OSG::Vec3f pos;
    pos.setValues(min[0] + ((max[0] - min[0]) * 0.5), 
                  min[1] + ((max[1] - min[1]) * 0.5), 
                  max[2] + ( max[2] - min[2] ) * 1.5 );
    
    float scale = (max[2] - min[2] + max[1] - min[1] + max[0] - min[0]) / 6;

    OSG::Pnt3f tCenter(min[0] + (max[0] - min[0]) / 2,
                       min[1] + (max[1] - min[1]) / 2,
                       min[2] + (max[2] - min[2]) / 2);

    tball.setMode( OSG::Trackball::OSGObject );
    tball.setStartPosition( pos, true );
    tball.setSum( true );
    tball.setTranslationMode( OSG::Trackball::OSGFree );
    tball.setTranslationScale(scale);
    tball.setRotationCenter(tCenter);

    // Carbon init

    // Create window
    WindowAttributes windowAttrs =
        kWindowStandardDocumentAttributes |
        kWindowLiveResizeAttribute |
        kWindowStandardHandlerAttribute;
    Rect contentRect;
    SetRect(&contentRect, 0,  0, 300, 300);
    WindowRef window;
    CreateNewWindow(kDocumentWindowClass, windowAttrs, &contentRect, &window);
    SetWindowTitleWithCFString(window, CFSTR("testWindowCarbon"));

    // Install event handler
    EventHandlerUPP eventHandlerUPP = NewEventHandlerUPP(eventHandler);
    EventTypeSpec eventList[] =
    {
        { kEventClassTextInput, kEventTextInputUnicodeForKeyEvent },
        { kEventClassMouse, kEventMouseDown },
        { kEventClassMouse, kEventMouseUp },
        { kEventClassMouse, kEventMouseDragged },
        { kEventClassWindow, kEventWindowClose },
        { kEventClassWindow, kEventWindowDrawContent },
        { kEventClassWindow, kEventWindowBoundsChanged }
    };
    InstallWindowEventHandler(window, eventHandlerUPP, GetEventTypeCount(eventList), eventList, /*this*/0, 0);

    // Initialize OpenGL
    GLint attribs[] = { AGL_RGBA, AGL_DOUBLEBUFFER, AGL_DEPTH_SIZE, 16, AGL_NONE };
    AGLPixelFormat pixelFormat = aglChoosePixelFormat(0, 0, attribs);
    if (pixelFormat == 0)
        std::cerr << "Cannot choose pixel format" << std::endl;
    AGLContext context = aglCreateContext(pixelFormat, 0);
    aglDestroyPixelFormat(pixelFormat);
    if (context == 0)
        std::cerr << "Cannot create context" << std::endl;
    aglSetDrawable(context, GetWindowPort(window));

    // Create OpenSG window
    win = OSG::CarbonWindow::create();
    win->addPort( vp );             
    win->setContext ( context );
    win->init();
    win->resize( 300, 300 );

    // Show window
    RepositionWindow(window, 0, kWindowCascadeOnMainScreen);
    ShowWindow(window);

    win->activate();

    // do some OpenGL init. Will move into State Chunks later.

    glEnable( GL_DEPTH_TEST );
    glEnable( GL_LIGHTING );
    glEnable( GL_LIGHT0 );


    // Main loop ( event dispatching )
    RunApplicationEventLoop();

    // Cleanup
    aglDestroyContext(context);
    DisposeWindow(window);
    DisposeEventHandlerUPP(eventHandlerUPP);

    ract      = NULL;
    win       = NULL;
    root      = NULL;
    file      = NULL;
    vp        = NULL;
    cam_trans = NULL;
    cam       = NULL;

    return 0;
}
// Initialize GLUT & OpenSG and set up the scene
int main(int argc, char **argv)
{
    printf("Usage: testCGShader <filename.vp> <filename.fp>\n");

    if( argc < 3 )
        return 0;
    
    // OSG init
    OSG::osgInit(argc,argv);

    // GLUT init
    int winid = setupGLUT(&argc, argv);

    // the connection between GLUT and OpenSG
    OSG::GLUTWindowUnrecPtr gwin= OSG::GLUTWindow::create();
    gwin->setGlutId(winid);
    gwin->setSize( 800, 800 );
    gwin->init();

    // Create the shader material
    OSG::ChunkMaterialUnrecPtr cmat = OSG::ChunkMaterial::create();

    OSG::MaterialChunkUnrecPtr matc = OSG::MaterialChunk::create();

    matc->setAmbient(OSG::Color4f(0.1, 0.1, 0.1, 1.0));
    matc->setDiffuse(OSG::Color4f(0.3, 0.3, 0.3, 1.0));
    matc->setSpecular(OSG::Color4f(0.8, 0.8, 0.8, 1.0));
    matc->setShininess(100);
    matc->setLit(true);

    OSG::SHLChunkUnrecPtr shl = OSG::SHLChunk::create();

    shl->readVertexProgram(argv[1]);
    shl->readFragmentProgram(argv[2]);

    cmat->addChunk(shl);


    // create root node
    _scene = OSG::Node::create();

    // create torus
    OSG::GeometryUnrecPtr geo = OSG::makeTorusGeo(.8, 1.8, 128, 128);
    geo->setMaterial(cmat);

    OSG::NodeUnrecPtr torus = OSG::Node::create();
    torus->setCore(geo);

    // add torus to scene
    OSG::GroupUnrecPtr group = OSG::Group::create();
    _scene->setCore(group);
    _scene->addChild(torus);

    // create the SimpleSceneManager helper
    _mgr = OSG::SimpleSceneManager::create();

    // tell the manager what to manage
    _mgr->setWindow(gwin );
    _mgr->setRoot(_scene);

    /*
    // create point headlight
    _mgr->turnHeadlightOff();
    NodePtr headlight = _mgr->getHighlight();
    PointLightPtr light    = PointLight::create();
    beginEditCP(light);
        light->setAmbient  (.3, .3, .3, 1);
        light->setDiffuse  ( 1,  1,  1, 1);
        light->setSpecular ( 1,  1,  1, 1);
        light->setBeacon   (_mgr->getCamera()->getBeacon());
    endEditCP(light);
    beginEditCP(_scene);
        _scene->setCore(light);
    endEditCP(_scene);
    */

    // show the whole scene
    _mgr->showAll();

    // GLUT main loop
    glutMainLoop();

    return 0;
}
int main(int argc, char *argv[])
{
    // Init the OpenSG subsystem
    OSG::osgInit(argc, argv);

    {
        // We create a GLUT Window (that is almost the same for most applications)
        int winid = setupGLUT(&argc, argv);
        OSG::GLUTWindowRecPtr gwin = OSG::GLUTWindow::create();
        gwin->setGlutId(winid);
        gwin->init();
    
        // Create the face
        std::string family = "SANS";
        OSG::TextFace::Style style = OSG::TextFace::STYLE_PLAIN;
        OSG::UInt32 size = 32;
        OSG::TextPixmapFaceRefPtr face = 
            OSG::TextPixmapFace::create(family, style, size);
        if (face == 0)
        {
            std::cerr << "ERROR: Cannot create face object!" << std::endl;
            return -1;
        }
    
        // Lay out one single line of text
        std::string text = "Hello World!"; // Use UTF-8 encoding!
        OSG::TextLayoutParam layoutParam;
        layoutParam.horizontal = true;
        layoutParam.leftToRight = true;
        layoutParam.topToBottom = true;
        layoutParam.majorAlignment = OSG::TextLayoutParam::ALIGN_FIRST;
        layoutParam.minorAlignment = OSG::TextLayoutParam::ALIGN_FIRST;
        layoutParam.spacing = 1.f;
        layoutParam.length.push_back(0.f);
        layoutParam.maxExtend = 0.f;
        OSG::TextLayoutResult layoutResult;
        face->layout(text, layoutParam, layoutResult);
    
        // Render the text into an OpenSG image
        OSG::Vec2f offset;
        OSG::UInt32 border = 1;
        OSG::ImageRecPtr imagePtr = face->makeImage(layoutResult, offset, border);
        
        // Create the geometry which we will assign the texture to
        OSG::Real32 width = imagePtr->getWidth();
        OSG::Real32 height = imagePtr->getHeight();
        OSG::NodeRecPtr plane = OSG::makePlane(width, height, 1, 1);
    
        // Create the texture that will hold the image
        OSG::SimpleTexturedMaterialRecPtr tex = 
            OSG::SimpleTexturedMaterial::create();
        tex->setImage(imagePtr);
        tex->setEnvMode(GL_MODULATE);
        tex->setDiffuse(OSG::Color3f(1, 0, 0));
    
        // Assign the texture to the geometry
        OSG::GeometryRecPtr geo =
            dynamic_cast<OSG::Geometry *>(plane->getCore());
        geo->setMaterial(tex);
    
        // Transform the geometry so that the origin of the text is at
        // the origin of the world coordinate system
        OSG::NodeRecPtr scene = OSG::Node::create();
        OSG::TransformRecPtr transformPtr = OSG::Transform::create();
        OSG::Matrix m;
        m.setTranslate(offset.x() + width / 2, offset.y() - height / 2, 0);
        transformPtr->setMatrix(m);
        
        scene->setCore(transformPtr);
        scene->addChild(plane);
        
        // Create and setup the SSM
        mgr = new OSG::SimpleSceneManager;
        mgr->setWindow(gwin);
        mgr->setRoot(scene);
    
        // Create a blue background
        OSG::SolidBackgroundRecPtr bg = OSG::SolidBackground::create();
        bg->setColor(OSG::Color3f(0.1, 0.1, 0.5));
        
        gwin->getPort(0)->setBackground(bg);
        
        mgr->showAll();
        
        OSG::commitChanges();
    }

    // Give Control to the GLUT Main Loop
    glutMainLoop();

    return 0;
}
void key(unsigned char key, int /*x*/, int /*y*/)
{
	switch ( key )
	{
        case 'l':
        {
            loadAnim();
            break;
        }
        case 'c':
        {
            FILE *file=fopen(animName.c_str(),"w");
            fclose(file);
            animOri.clear();
            animPos.clear();
            frameCount = 0;
            animTime = 0;
            break;
        }
        case 's':
        {
            FILE *file=fopen(animName.c_str(),"a");
            OSG::Matrix m=cam_trans->getMatrix();
            OSG::Quaternion q(m);
            OSG::Real32 ax,ay,az,r;
            animPos.push_back(OSG::Vec3f(m[3][0],
                                         m[3][1],
                                         m[3][2]));
            animOri.push_back(q);
            q.getValueAsAxisRad(ax,ay,az,r);
            fprintf(file,"%f %f %f %f,%f %f %f\n",ax,ay,az,r,
                    m[3][0],
                    m[3][1],
                    m[3][2]);
            fclose(file);
            frameCount = 0;
            animTime = 0;
            break;
        }
        case 'S':
        {
            FILE *file=fopen((animName+".wrl").c_str(),"w");
            std::vector<OSG::Quaternion>::iterator qit;
            
            fprintf(file,"DEF OriInter OrientationInterpolator {\n\tkey [");
            for(size_t i = 0; i < animOri.size(); ++i)
            {               
                fprintf(file, "%f", i / OSG::Real32(animOri.size() - 1) );
                if(i < animOri.size() - 1)
                    fprintf(file,", ");
            }
            fprintf(file,"]\n\tkeyValue [");
            for(qit = animOri.begin(); qit != animOri.end(); ++qit)
            {
                OSG::Real32 ax,ay,az,r;
                (*qit).getValueAsAxisRad(ax,ay,az,r);
                
                fprintf(file, "%f %f %f %f", ax, ay, az, r );
                if(qit < animOri.end() - 1)
                    fprintf(file,", ");
            }
            fprintf(file,"]\n}\n\n");

            std::vector<OSG::Vec3f>::iterator vit;
            
            fprintf(file,"DEF PosInter PositionInterpolator {\n\tkey [");
            for(size_t i = 0; i < animPos.size(); ++i)
            {               
                fprintf(file, "%f", i / OSG::Real32(animPos.size() - 1) );
                if(i < animPos.size() - 1)
                    fprintf(file,", ");
            }
            fprintf(file,"]\n\tkeyValue [");
            for(vit = animPos.begin(); vit != animPos.end(); ++vit)
            {
                OSG::Vec3f v = *vit;
                
                fprintf(file, "%f %f %f, ", v[0], v[1], v[2] );
            }
            fprintf(file,"]\n}\n\n");

            fclose(file);
            break;
        }
        case 'j':
            if(sortfirst!=NULL)
            {
                sortfirst->setCompression("JPEG");
            }
            break;
        case 'r':
            if(sortfirst!=NULL)
            {
                sortfirst->setCompression("RLE");
            }
            break;
        case 'n':
            if(sortfirst!=NULL)
            {
                sortfirst->editCompression().erase();
            }
            break;
        case 'i':
            showInfo = !showInfo;
            break;
        case 'w':
            if(polygonChunk->getFrontMode() == GL_FILL)
                polygonChunk->setFrontMode(GL_LINE);
            else
                polygonChunk->setFrontMode(GL_FILL);

            if(polygonChunk->getBackMode() == GL_FILL)
                polygonChunk->setBackMode(GL_LINE);
            else
                polygonChunk->setBackMode(GL_FILL);
            break;
        case 'a':
            if(animate)
            {
                glutIdleFunc(NULL);       
                animate=false;
            }
            else
            {
                glutIdleFunc(display);       
                animate=true;
            }
            frameCount = 0;
            animTime = 0;
            break;
        case 'd':
            // remove tree
            while(root->getNChildren())
            {
                root->subChild(0u);
            }
            break;
        case '+':
            _dsFactor += 0.01f;
            if(_dsFactor > 1.0f)
                _dsFactor = 1.0f;
            setHEyeWallParameter(_dsFactor, _enablecc);
            break;
        case '-':
            _dsFactor -= 0.01f;
            if(_dsFactor <= 0.0f)
                _dsFactor = 0.01f;
            setHEyeWallParameter(_dsFactor, _enablecc);
            break;
        case 'f':
            if(_enablecc)
                _enablecc = false;
            else
                _enablecc = true;
            setHEyeWallParameter(_dsFactor, _enablecc);
            break;
        case 'B':
            if(bkgnd->getColor()[0] == 0.0)
                bkgnd->setColor( OSG::Color3f(1,1,1) );
            else
                bkgnd->setColor( OSG::Color3f(0,0,0) );
            break;
        case 27:	// should kill the clients here
            // exit
            cleanup();
            OSG::osgExit(); 
            exit(0);
	}
	
	glutPostRedisplay();
}
int doMain (int argc, char **argv)
{
    OSG::osgInit(argc,argv);
    
    // GLUT init

    glutInit(&argc, argv);
    glutInitDisplayMode( GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE);
    glutInitWindowSize(800, 800);
    

    int winid = glutCreateWindow("OpenSG");
    glutKeyboardFunc(key);
    glutVisibilityFunc(vis);
    glutReshapeFunc(reshape);
    glutDisplayFunc(display);       
    glutMouseFunc(mouse);   
    glutMotionFunc(motion); 
    
    glutIdleFunc(display);  

    // OSG

    OSG::SceneFileHandler::the()->print();

    // create the graph

    // beacon for camera and light  
    OSG::NodeUnrecPtr  b1n = OSG::Node::create();
    OSG::GroupUnrecPtr b1  = OSG::Group::create();

    fprintf(stderr, "Create b1n %p %d %d \n",
            b1n.get(),
            b1n->getRefCount(),
            b1n->getWeakRefCount());

    b1n->setCore( b1 );

    // transformation
    OSG::NodeUnrecPtr      t1n = OSG::Node::create();
    OSG::TransformUnrecPtr t1  = OSG::Transform::create();

    t1n->setCore (t1 );
    t1n->addChild(b1n);

    fprintf(stderr, "Create t1n %p %d %d \n",
            t1n.get(),
            t1n->getRefCount(),
            t1n->getWeakRefCount());

    cam_trans = t1;

    // light
    
    OSG::NodeUnrecPtr             dlight = OSG::Node::create();
    OSG::DirectionalLightUnrecPtr dl     = OSG::DirectionalLight::create();

    {
        dlight->setCore(dl);
        
        dl->setAmbient( .3f, .3f, .3f, 1 );
        dl->setDiffuse( .8f, .8f, .8f, .8f );
        dl->setDirection(0,0,1);
        dl->setBeacon( b1n);
    }

    fprintf(stderr, "Create dlight %p %d %d \n",
            dlight.get(),
            dlight->getRefCount(),
            dlight->getWeakRefCount());

    hdrroot = OSG::Node::create();
    
    hdrroot->editVolume().setInfinite();
    hdrroot->editVolume().setStatic  ();

    hdrroot->setCore(OSG::Group::create());

    // root
    root         = OSG::Node:: create();

    OSG::GroupUnrecPtr gr1 = OSG::Group::create();

    root->setCore(gr1);

    
    hdrroot->addChild(root);

    root->addChild(t1n   );
    root->addChild(dlight);

    fprintf(stderr, "Create root %p %d %d \n",
            root.get(),
            root->getRefCount(),
            root->getWeakRefCount());

    // Load the file

    OSG::NodeUnrecPtr file = NULL;
    
    if(argc > 1)
    {
        file = OSG::SceneFileHandler::the()->read(argv[1], NULL);
    }

    if(file == NULL)
    {
        std::cerr << "Couldn't load file, ignoring" << std::endl;

//        file = makeBox(2.f, 2.f, 2.f, 2, 2, 2);
        file = OSG::makeSphere(4, 2.0);
    }

    OSG::NodeUnrecPtr pCubeRoot            = OSG::Node::create();
    OSG::CubeMapGeneratorUnrecPtr pCubeGen = OSG::CubeMapGenerator::create();

    pCubeRoot->addChild(file);
    pCubeRoot->setCore(pCubeGen);
//    pCubeRoot->setCore(Group::create());

    OSG::NodeUnrecPtr         pCubeSceneRoot = OSG::Node::create();
    OSG::VisitSubTreeUnrecPtr pCubeVisit     = OSG::VisitSubTree::create();

    pCubeSceneRoot->setCore(pCubeVisit);
    pCubeVisit->setSubTreeRoot(root);

    pCubeGen->setRoot         (pCubeSceneRoot);
    pCubeGen->setTextureFormat(GL_RGB32F_ARB );
    pCubeGen->setSize         (512, 
                               512           );
    pCubeGen->setTexUnit      (3);

    // Cubemap Background
    OSG::SolidBackgroundUnrecPtr cubeBkgnd = OSG::SolidBackground::create();
    {
        cubeBkgnd->setColor(OSG::Color3f(0.5f, 0.3f, 0.3f));
    }

    pCubeGen->setBackground(cubeBkgnd);


    OSG::NodeUnrecPtr pAnimRoot = setupAnim();

            scene_trans = OSG::Transform::create();
    OSG::NodeUnrecPtr sceneTrN    = OSG::Node::create();

    scene_trans->editMatrix()[3][2] = -50.f;

    sceneTrN->setCore (scene_trans);
    sceneTrN->addChild(pCubeRoot  );
    sceneTrN->addChild(pAnimRoot  );

    OSG::Thread::getCurrentChangeList()->commitChanges();

    OSG::Vec3f min,max;
    sceneTrN->updateVolume();
    sceneTrN->getVolume().getBounds(min, max);
    
    std::cout << "Volume: from " << min << " to " << max << std::endl;


    dlight->addChild(sceneTrN);

    // Camera
    
    cam = OSG::PerspectiveCamera::create();
    {
        cam->setBeacon( b1n );
        cam->setFov( OSG::osgDegree2Rad( 90 ) );
        cam->setNear( 0.1f );
        cam->setFar( 100000 );
    }

    // Background
    OSG::SolidBackgroundUnrecPtr bkgnd = OSG::SolidBackground::create();
    {
        bkgnd->setColor(OSG::Color3f(0.3f, 0.3f, 0.3f));
    }

    // Viewport
    vp = OSG::Viewport::create();
    {
        vp->setCamera( cam );
        vp->setBackground( bkgnd );
        vp->setRoot( hdrroot );
//        vp->setRoot( root );
        vp->setSize( 0,0, 1,1 );
    }


    // Window
    OSG::GLUTWindowUnrecPtr gwin;

    GLint glvp[4];

    glGetIntegerv(GL_VIEWPORT, glvp);

    gwin = OSG::GLUTWindow::create();
    {
        gwin->setGlutId(winid);
        gwin->setSize( glvp[2], glvp[3] );
        
        win = gwin;

        win->addPort( vp );

        win->init();
    }

    // Action
    rentravact = OSG::RenderAction::create();

    rentravact->setVolumeDrawing(true);
//    rentravact->setFrustumCulling(false);

    // tball
    OSG::Vec3f pos;

    pos.setValues(min[0] + ((max[0] - min[0]) * 0.5), 
                  min[1] + ((max[1] - min[1]) * 0.5), 
                  max[2] + ( max[2] - min[2] ) * 1.5 );
    
    float scale = (max[2] - min[2] + max[1] - min[1] + max[0] - min[0]) / 6;

    OSG::Pnt3f tCenter(min[0] + (max[0] - min[0]) / 2,
                       min[1] + (max[1] - min[1]) / 2,
                       min[2] + (max[2] - min[2]) / 2);

    fprintf(stderr, "Startpos : %f %f %f\n", pos[0], pos[1], pos[2]);

    tball.setMode            (OSG::Trackball::OSGObject);
    tball.setStartPosition   (pos, true                );
    tball.setSum             (true                     );
    tball.setTranslationMode (OSG::Trackball::OSGFree  );
    tball.setTranslationScale(scale                    );
    tball.setRotationCenter  (tCenter                  );

    fprintf(stderr, "Create b1n %p %d %d \n",
            b1n.get(),
            b1n->getRefCount(),
            b1n->getWeakRefCount());

    fprintf(stderr, "Create t1n %p %d %d \n",
            t1n.get(),
            t1n->getRefCount(),
            t1n->getWeakRefCount());

    fprintf(stderr, "Create dlight %p %d %d \n",
            dlight.get(),
            dlight->getRefCount(),
            dlight->getWeakRefCount());

    fprintf(stderr, "Create hdrroot %p %d %d \n",
            hdrroot.get(),
            hdrroot->getRefCount(),
            hdrroot->getWeakRefCount());

    fprintf(stderr, "Create root %p %d %d \n",
            root.get(),
            root->getRefCount(),
            root->getWeakRefCount());

    return 0;
}
int init(int argc, char **argv)
{
    OSG::osgInit(argc,argv);
    
    // GLUT init

    glutInit(&argc, argv);
    glutInitDisplayMode( GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE);
    int winid = glutCreateWindow("OpenSG");
    glutKeyboardFunc(key);
    glutVisibilityFunc(vis);
    glutReshapeFunc(reshape);
    glutDisplayFunc(display);       
    glutMouseFunc(mouse);   
    glutMotionFunc(motion); 
    
    glutIdleFunc(display);  

    // glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
    
//    glEnable( GL_DEPTH_TEST );
//    glEnable( GL_LIGHTING );
//    glEnable( GL_LIGHT0 );
//    glFrontFace(GL_CW);
    glEnable(GL_CULL_FACE);

    // OSG

    OSG::SceneFileHandler::the()->print();

    // create the graph

    // beacon for camera and light  
    OSG::NodeUnrecPtr b1n = OSG::Node::create();
    OSG::GroupUnrecPtr b1 = OSG::Group::create();

    b1n->setCore( b1 );

    // transformation
    OSG::NodeUnrecPtr t1n = OSG::Node::create();
    OSG::TransformUnrecPtr t1 = OSG::Transform::create();

    t1n->setCore( t1 );
    t1n->addChild( b1n );

    cam_trans = t1;

    // light
    
    OSG::NodeUnrecPtr dlight = OSG::Node::create();
    OSG::DirectionalLightUnrecPtr dl = OSG::DirectionalLight::create();

    dlight->setCore( dl );
//    dlight->setCore( Group::create() );
    
    dl->setAmbient( .0, .0, .0, 1 );
    dl->setDiffuse( .8f, .8f, .8f, 1.f );
    dl->setDirection(0,0,1);
    dl->setBeacon( b1n);

    // root
    root = OSG::Node::create();
    OSG::GroupUnrecPtr gr1 = OSG::Group::create();

    root->setCore( gr1 );
    root->addChild( t1n );
    root->addChild( dlight );

    // Load the file

    OSG::NodeUnrecPtr file = NULL;
    
    if(argc > 1)
        file = OSG::SceneFileHandler::the()->read(argv[1], NULL);
    
    if ( file == NULL )
    {
        std::cerr << "Couldn't load file, ignoring" << std::endl;

        file = OSG::makeSphere(4, 2.0);

    }

#if 0
    OSG::GeometryPtr pGeo = cast_dynamic<OSG::GeometryPtr>(file->getCore());
    
    if(pGeo == NULL && file->getNChildren() != 0)
    {
        pGeo = cast_dynamic<OSG::GeometryPtr>(file->getChild(0)->getCore());
    }

    if(pGeo == NULL)
    {
        fprintf(stderr, "no geo\n");
    }
#endif

//    OSG::GraphOpRefPtr op = OSG::GraphOpFactory::the()->create("Stripe");

//    op->traverse(file);
//    createOptimizedPrimitives(pGeo);
//    createSharedIndex(pGeo);
    
    OSG::Thread::getCurrentChangeList()->commitChanges();

//    file->dump();
    file->updateVolume();

#if 0
    const char *outFileName = "/tmp/foo1.osg";

    OSG::IndentFileOutStream outFileStream(outFileName);

    if( !outFileStream )
    {
        std::cerr << "Can not open output stream to file: "
                  << outFileName << std::endl;
        return -1;
    }

    std::cerr << "STARTING PRINTOUT:" << std::endl;
    OSGWriter writer( outFileStream, 4 );

    writer.write( file );

    outFileStream.close();

    OSG::SceneFileHandler::the()->write(file, "/tmp/foo.osb");
#endif    


//    return 0;


    OSG::Vec3f min,max;
    file->getVolume().getBounds( min, max );
    

    std::cout << "Volume: from " << min << " to " << max << std::endl;


    OSG::MultiCoreUnrecPtr pMCore = OSG::MultiCore::create();

    pCOver      = OSG::ChunkOverrideGroup::create();
    scene_trans = OSG::Transform::create();

    pMCore->addCore(scene_trans);
    pMCore->addCore(pCOver     );

    OSG::NodeUnrecPtr sceneTrN = OSG::Node::create();

    sceneTrN->setCore(pMCore);
    sceneTrN->addChild(file);


    dlight->addChild(sceneTrN);

    std::cerr << "Tree: " << std::endl;
//  root->dump();

    // Camera
    
    cam = OSG::PerspectiveCamera::create();

    cam->setBeacon( b1n );
    cam->setFov( OSG::osgDegree2Rad( 90 ) );
    cam->setNear( 0.1f );
    cam->setFar( 100000 );

    // Background
    OSG::SolidBackgroundUnrecPtr bkgnd = OSG::SolidBackground::create();

    bkgnd->setColor(OSG::Color3f(1,0,0));
    
    // Viewport

    vp = OSG::Viewport::create();

    vp->setCamera( cam );
    vp->setBackground( bkgnd );
    vp->setRoot( root );
    vp->setSize( 0,0, 1,1 );

#if 0
    OSG::UInt8 imgdata[] =
    {  
        64,64,64, 128,128,128, 192,192,192, 255,255,255 
    };
#endif

    pImg = OSG::Image::create();

    pImg->set(OSG::Image::OSG_RGB_PF, 128, 128); //, 1, 1, 1, 0.0, imgdata);

    tx1o = OSG::TextureObjChunk::create();
    tx1e = OSG::TextureEnvChunk::create();

    tx1o->setImage    (pImg      ); 
    tx1o->setMinFilter(GL_LINEAR );
    tx1o->setMagFilter(GL_LINEAR );
    tx1o->setWrapS    (GL_CLAMP );
    tx1o->setWrapT    (GL_CLAMP );
    tx1e->setEnvMode  (GL_REPLACE);

    OSG::SimpleMaterialUnrecPtr mat = OSG::SimpleMaterial::create();
    
    mat->setDiffuse(OSG::Color3f(1,1,1));
    mat->setLit    (false              );
    mat->addChunk  (tx1o               );
    mat->addChunk  (tx1e               );

    OSG::PolygonForegroundUnrecPtr pFG =  OSG::PolygonForeground::create();

    pFG->setMaterial(mat);

    OSG::MFPnt2f *pPos = pFG->editMFPositions();
    OSG::MFVec3f *pTex = pFG->editMFTexCoords();

    pPos->push_back(OSG::Pnt2f(0.0f, 0.0f));
    pPos->push_back(OSG::Pnt2f(0.3f, 0.0f));
    pPos->push_back(OSG::Pnt2f(0.3f, 0.3f));
    pPos->push_back(OSG::Pnt2f(0.0f, 0.3f));

    pTex->push_back(OSG::Vec3f(0.0f, 1.0f, 0.0f));
    pTex->push_back(OSG::Vec3f(1.0f, 1.0f, 0.0f));
    pTex->push_back(OSG::Vec3f(1.0f, 0.0f, 0.0f));
    pTex->push_back(OSG::Vec3f(0.0f, 0.0f, 0.0f));

    vp->addForeground(pFG);



    OSG::SimpleMaterialUnrecPtr matFgCheck = OSG::SimpleMaterial::create();
    
    matFgCheck->setDiffuse(OSG::Color3f(0,1,0));
    matFgCheck->setLit    (false              );

    OSG::PolygonForegroundUnrecPtr pFGCheck =  OSG::PolygonForeground::create();

    pFGCheck->setMaterial(matFgCheck);

    pPos = pFGCheck->editMFPositions();

    pPos->push_back(OSG::Pnt2f(0.6f, 0.0f));
    pPos->push_back(OSG::Pnt2f(0.9f, 0.0f));
    pPos->push_back(OSG::Pnt2f(0.9f, 0.3f));
    pPos->push_back(OSG::Pnt2f(0.6f, 0.3f));


    vp->addForeground(pFG);
    vp->addForeground(pFGCheck);
//    vp->dump();


    // Background
    OSG::SolidBackgroundUnrecPtr bkgndFBO = OSG::SolidBackground::create();

    bkgndFBO->setColor(OSG::Color3f(1.0,0.5,0.5));
    
    // Viewport

    vpFBO = OSG::FBOViewport::create();

    vpFBO->setCamera    (cam       );
    vpFBO->setBackground(bkgndFBO  );
    vpFBO->setRoot      (root      );
    vpFBO->setSize      (0, 0, 1, 1);

    vpFBO->addForeground(pFGCheck);

    OSG::FrameBufferObjectUnrecPtr pFBO = OSG::FrameBufferObject::create();

                               pTexBuffer   = OSG::TextureBuffer::create();
    OSG::RenderBufferUnrecPtr  pDepthBuffer = OSG::RenderBuffer ::create();

    pDepthBuffer->setInternalFormat(GL_DEPTH_COMPONENT24   );

    pTexBuffer->setTexture(tx1o);

    pFBO->setSize(128, 128);
    
    pFBO->setColorAttachment(pTexBuffer, 0);
    pFBO->setDepthAttachment(pDepthBuffer );

    pFBO->editMFDrawBuffers()->clear();
    pFBO->editMFDrawBuffers()->push_back(GL_COLOR_ATTACHMENT0_EXT);


    vpFBO->setFrameBufferObject(pFBO);



    // Window
    std::cout << "GLUT winid: " << winid << std::endl;


    GLint glvp[4];

    glGetIntegerv( GL_VIEWPORT, glvp );

    gwin = OSG::GLUTWindow::create();
    gwin->setGlutId(winid);
    gwin->setSize( glvp[2], glvp[3] );

    win = gwin;

    win->addPort(vpFBO   );
    win->addPort(vp      );

    win->init();

    // Action
    
    rentravact = OSG::RenderAction::create();
//    renact->setFrustumCulling(false);


    // tball

    OSG::Vec3f pos;
    pos.setValues(min[0] + ((max[0] - min[0]) * 0.5), 
                  min[1] + ((max[1] - min[1]) * 0.5), 
                  max[2] + ( max[2] - min[2] ) * 1.5 );
    
    float scale = (max[2] - min[2] + max[1] - min[1] + max[0] - min[0]) / 6;

    OSG::Pnt3f tCenter(min[0] + (max[0] - min[0]) / 2,
                       min[1] + (max[1] - min[1]) / 2,
                       min[2] + (max[2] - min[2]) / 2);

    fprintf(stderr, "Startpos : %f %f %f\n", pos[0], pos[1], pos[2]);

    tball.setMode( OSG::Trackball::OSGObject );
    tball.setStartPosition( pos, true );
    tball.setSum( true );
    tball.setTranslationMode( OSG::Trackball::OSGFree );
    tball.setTranslationScale(scale);
    tball.setRotationCenter(tCenter);

    // run...
    
    pPoly = OSG::PolygonChunk::create();

    pCOver->subChunk(pPoly);

    return 0;
}
int doMain (int argc, char **argv)
{
    int dummy;

    // OSG init

    OSG::osgInit(argc, argv);

    // create the graph

    // beacon for camera and light
    OSG::NodeUnrecPtr b1n = OSG::Node::create();
    OSG::GroupUnrecPtr b1 = OSG::Group::create();
    b1n->setCore( b1 );

    // transformation
    OSG::NodeUnrecPtr t1n = OSG::Node::create();
    OSG::TransformUnrecPtr t1 = OSG::Transform::create();
    t1n->setCore( t1 );
    t1n->addChild( b1n );

    cam_trans = t1;

    // light

    OSG::NodeUnrecPtr dlight = OSG::Node::create();
    OSG::DirectionalLightUnrecPtr dl = OSG::DirectionalLight::create();

    dlight->setCore( dl );

    dl->setAmbient( .3, .3, .3, 1 );
    dl->setDiffuse( 1, 1, 1, 1 );
    dl->setDirection(0,0,1);
    dl->setBeacon( b1n);

    // root
    root = OSG::Node::create();
    OSG::GroupUnrecPtr gr1 = OSG::Group::create();

    root->setCore( gr1 );
    root->addChild( t1n );
    root->addChild( dlight );

    // Load the file

    OSG::NodeUnrecPtr file = NULL;

    if ( argc > 1 )
        file = OSG::SceneFileHandler::the()->read(argv[1]);

    if ( file == NULL )
    {
        std::cerr << "Couldn't load file, ignoring" << std::endl;
        file = OSG::makeTorus( .5, 2, 16, 16 );
    }

    OSG::Thread::getCurrentChangeList()->commitChanges();
    file->updateVolume();

    OSG::Vec3f min,max;
    file->getVolume().getBounds( min, max );

    std::cout << "Volume: from " << min << " to " << max << std::endl;

    dlight->addChild( file );

    std::cerr << "Tree: " << std::endl;
    //root->dump();

    // Camera
    cam = OSG::PerspectiveCamera::create();

    cam->setBeacon( b1n );
    cam->setFov( OSG::osgDegree2Rad( 90 ) );
    cam->setNear( 0.1 );
    cam->setFar( 100000 );

    // Background
    OSG::SolidBackgroundUnrecPtr bkgnd = OSG::SolidBackground::create();

    bkgnd->setColor(OSG::Color3f(0,0,1));

    // Viewport

    vp = OSG::Viewport::create();
    vp->setCamera( cam );
    vp->setBackground( bkgnd );
    vp->setRoot( root );
    vp->setSize( 0,0, 1,1 );

    // Action

    ract = OSG::RenderAction::create();

    // tball

    OSG::Vec3f pos;
    pos.setValues(min[0] + ((max[0] - min[0]) * 0.5), 
                  min[1] + ((max[1] - min[1]) * 0.5), 
                  max[2] + ( max[2] - min[2] ) * 1.5 );
    
    float scale = (max[2] - min[2] + max[1] - min[1] + max[0] - min[0]) / 6;

    OSG::Pnt3f tCenter(min[0] + (max[0] - min[0]) / 2,
                       min[1] + (max[1] - min[1]) / 2,
                       min[2] + (max[2] - min[2]) / 2);
    
    tball.setMode( OSG::Trackball::OSGObject );
    tball.setStartPosition( pos, true );
    tball.setSum( true );
    tball.setTranslationMode( OSG::Trackball::OSGFree );
    tball.setTranslationScale(scale);
    tball.setRotationCenter(tCenter);

    // CoreGL init

    // Install event handler
    EventHandlerUPP eventHandlerUPP = NewEventHandlerUPP(eventHandler);
    EventTypeSpec eventList[] =
    {
        { kEventClassTextInput, kEventTextInputUnicodeForKeyEvent },
        { kEventClassMouse, kEventMouseDown },
        { kEventClassMouse, kEventMouseUp },
        { kEventClassMouse, kEventMouseDragged }
    };
    InstallApplicationEventHandler(eventHandlerUPP, GetEventTypeCount(eventList), eventList, 0, 0);

    CGDisplayCapture(kCGDirectMainDisplay);
    CGLPixelFormatAttribute attribs[] =
    {
        kCGLPFADoubleBuffer,
        kCGLPFAFullScreen,
        kCGLPFADepthSize,
        (CGLPixelFormatAttribute)16,
        kCGLPFADisplayMask,
        (CGLPixelFormatAttribute)CGDisplayIDToOpenGLDisplayMask(kCGDirectMainDisplay),
        (CGLPixelFormatAttribute)0
    };
    CGLPixelFormatObj pixelFormatObj;
    GLint numPixelFormats;
    CGLChoosePixelFormat(attribs, &pixelFormatObj, &numPixelFormats); 

    CGLContextObj contextObj;
    CGLCreateContext(pixelFormatObj, 0, &contextObj);

    CGLDestroyPixelFormat(pixelFormatObj);

    CGLSetCurrentContext(contextObj);
    CGLSetFullScreen(contextObj);

    // Create OpenSG window
    win = OSG::CoreGLWindow::create();
    win->addPort( vp );             
    win->setContext ( contextObj );
    win->init();
    win->resize( CGDisplayPixelsWide(kCGDirectMainDisplay), CGDisplayPixelsHigh(kCGDirectMainDisplay) );

    win->activate();

    // do some OpenGL init. Will move into State Chunks later.

    glEnable( GL_DEPTH_TEST );
    glEnable( GL_LIGHTING );
    glEnable( GL_LIGHT0 );
    redraw();

    // Main loop ( event dispatching )
    RunApplicationEventLoop();

    // Cleanup
    CGLSetCurrentContext(0);
    CGLClearDrawable(contextObj);
    CGLDestroyContext(contextObj);
    CGReleaseAllDisplays();
    DisposeEventHandlerUPP(eventHandlerUPP);

    ract      = NULL;
    win       = NULL;
    root      = NULL;
    file      = NULL;
    vp        = NULL;
    cam_trans = NULL;
    cam       = NULL;

    return 0;
}
// Initialize GLUT & OpenSG and set up the scene
int doMain(int argc, char **argv)
{
    // OSG init
    OSG::osgInit(argc,argv);

    // GLUT init
    int winid = setupGLUT(&argc, argv);

    // the connection between GLUT and OpenSG
    OSG::GLUTWindowUnrecPtr gwin = OSG::GLUTWindow::create();

    gwin->setGlutId(winid);
    gwin->setSize( 800, 800 );
    gwin->init();

    // create root node
    _scene = OSG::makeCoredNode<OSG::Group>();

    OSG::GeometryUnrecPtr geo = OSG::makeBoxGeo(0.5, 0.5, 0.5, 1, 1, 1);

    // share the chunk
    OSG::SimpleSHLChunkUnrecPtr shl = OSG::SimpleSHLChunk::create();

    shl->setVertexProgram(_vp_program);
    shl->setFragmentProgram(_fp_program);
    // These parameters are the same for all geometries so we
    // keep them in here.
    shl->addUniformVariable("Scale", OSG::Vec2f(20.0f, 20.0f));
    shl->addUniformVariable("Threshold", OSG::Vec2f(0.7f, 0.7f));

    OSG::Int32 size = 4;

    // start color
    OSG::Vec3f sc(0.0, 0.0, 0.0);

    // end color
    OSG::Vec3f ec(1.0, 1.0, 1.0);

    OSG::Real32 sr = (ec[0] - sc[0]) / OSG::Real32((size*2));
    OSG::Real32 sg = (ec[1] - sc[1]) / OSG::Real32((size*2));
    OSG::Real32 sb = (ec[2] - sc[2]) / OSG::Real32((size*2));

    OSG::Vec3f color(sc);

    OSG::Int32 x = - size;
    OSG::Int32 y = - size;
    OSG::Int32 z = - size;

    OSG::UInt32 iterations = size*2 * size*2 * size*2;

    printf("Creating %u cubes ...\n", iterations);
    for(OSG::UInt32 i=0; i<iterations; ++i)
    {
        OSG::ChunkMaterialUnrecPtr cmat = OSG::ChunkMaterial::create();

        // ok use one SHLChunk and n SHLParameterChunks
        // Assing a different "SurfaceColor" parameter to each geometry.
        OSG::SimpleSHLVariableChunkUnrecPtr shlparameter =
            OSG::SimpleSHLVariableChunk::create();

//        shlparameter->setSHLChunk(shl);
        shlparameter->addUniformVariable("SurfaceColor", color);

        _shlparameter = shlparameter;

        cmat->addChunk(shl);
        cmat->addChunk(shlparameter);

        OSG::TransformUnrecPtr trans;
        OSG::NodeUnrecPtr trans_node =
            OSG::makeCoredNode<OSG::Transform>(&trans);

        trans->editMatrix().setTranslate(OSG::Real32(x),
                                         OSG::Real32(y),
                                         OSG::Real32(z));

        OSG::MaterialGroupUnrecPtr mg;

        OSG::NodeUnrecPtr mg_node = OSG::makeCoredNode<OSG::MaterialGroup>(&mg);

        mg->setMaterial(cmat);

        OSG::NodeUnrecPtr geonode = OSG::Node::create();

        geonode->setCore(geo);

        mg_node->addChild(geonode);

        trans_node->addChild(mg_node);

        // add to scene
        _scene->addChild(trans_node);

        // ----
        ++x;
        color[0] += sr;

        if(x == size)
        {
            x = - size;
            ++y;
            color[0] = sc[0];
            color[1] += sg;
            if(y == size)
            {
                y = - size;
                ++z;
                color[1] = sc[1];
                color[2] += sb;
            }
        }
    }


    // create the SimpleSceneManager helper
    _mgr = OSG::SimpleSceneManager::create();

    // tell the manager what to manage
    _mgr->setWindow(gwin );
    _mgr->setRoot(_scene);

    // show the whole scene
    _mgr->showAll();

    // create a gradient background.
    OSG::GradientBackgroundUnrecPtr gback = OSG::GradientBackground::create();

    gback->clearLines();
    gback->addLine(OSG::Color3f(0.7f, 0.7f, 0.8f), 0);
    gback->addLine(OSG::Color3f(0.0f, 0.1f, 0.3f), 1);

    OSG::Window *win = _mgr->getWindow();

    for(unsigned int i=0; i<win->getMFPort()->size(); ++i)
    {
        OSG::Viewport *vp = win->getPort(i);
        vp->setBackground(gback);
    }

    return 0;
}
OSG::NodeTransitPtr createScenegraph(void)
{
    // the scene must be created here
    for (int i = 0; i < N; i++)
        for (int j = 0; j < N; j++)
            wMesh[i][j] = 0;
    
    // the types of primitives that are used - an integerer propery
    OSG::GeoUInt8PropertyRecPtr types = OSG::GeoUInt8Property::create();
    
    // we want to use quads ONLY 
    types->addValue(GL_QUADS);
    
    // the number of vertices (or indices) we want to use with the primitive
    // type; types and lengths always have the same number of elements
    // (here both have just one)
    OSG::GeoUInt32PropertyRecPtr lengths = OSG::GeoUInt32Property::create();
    // the length of our quads is four ;-)
    lengths->addValue(4 * (N - 1) * (N - 1));

    // GeoPnt3fProperty stores the positions of all vertices used in
    // this specific geometry core
    OSG::GeoPnt3fPropertyRecPtr pos = OSG::GeoPnt3fProperty::create();
    // here they all come
    for (int x = 0; x < N; x++)
        for (int z = 0; z < N; z++)
            pos->addValue(OSG::Pnt3f(x, wMesh[x][z], z));

    // GeoColor3fProperty stores all color values that will be used
    OSG::GeoColor3fPropertyRecPtr colors = OSG::GeoColor3fProperty::create();
    for (int x = 0; x < N; x++)
        for (int z = 0; z < N; z++)
            colors->addValue(OSG::Color3f(0,0,1));
    
    // and finally the normals are stored in a GeoVec3fProperty
    OSG::GeoVec3fPropertyRecPtr norms = OSG::GeoVec3fProperty::create();
    for (int x = 0; x < N; x++)
        for (int z = 0; z < N; z++)
            // As initially all heights are set to zero thus yielding a plane,
            // we set all normals to (0,1,0) parallel to the y-axis
            norms->addValue(OSG::Vec3f(0,1,0));
    
    OSG::SimpleMaterialRecPtr mat = OSG::SimpleMaterial::create();
    
    // Indices define the order in which the entries in the above properties
    // are used
    OSG::GeoUInt32PropertyRecPtr indices = OSG::GeoUInt32Property::create();
    for (int x = 0; x < N-1; x++)
    {
        for (int z = 0; z < N-1; z++)
        {
            // points to four vertices that will
            // define a single quad
            indices->addValue( z    * N + x    );
            indices->addValue((z+1) * N + x    );
            indices->addValue((z+1) * N + x + 1);
            indices->addValue( z    * N + x + 1);
        }
    }

    OSG::GeometryRecPtr geo = OSG::Geometry::create();

    geo->setTypes    (types  );
    geo->setLengths  (lengths);
    geo->setIndices  (indices);
    geo->setPositions(pos    );
    geo->setNormals  (norms  );
    geo->setMaterial (mat    );
    geo->setColors   (colors );
    
    // Turn off creation of display lists, since the geometry changes each
    // frame
    geo->setDlistCache(false);
    
    OSG::NodeRecPtr root = OSG::Node::create();
    root->setCore(geo);

    return OSG::NodeTransitPtr(root);
}