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 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;
}