TEST_FIXTURE(FileFixture, TestNameRetention)
{
   std::string start_name("node");
   OSG::NodeUnrecPtr n = OSG::Node::create();
   OSG::setName(n, start_name);
   n->setCore(OSG::Group::create());

   CHECK(!bf::exists(test_file));
   OSG::SceneFileHandler::the()->write(n, test_file.native_file_string().c_str());
   CHECK(bf::exists(test_file));

   OSG::NodeUnrecPtr new_n =
      OSG::SceneFileHandler::the()->read(test_file.native_file_string().c_str());
   CHECK(new_n != NULL);
   CHECK(OSG::getName(new_n) != NULL);
   std::string cur_name = std::string(OSG::getName(new_n));

   CHECK(cur_name == start_name);
}
void VTKPolyDataMapper::initGeometries(void)
{
    NodeUnrecPtr pRoot = Node::create();
    
    pRoot->setCore(Group::create());

    setRoot(pRoot);

    for(UInt32 i = 0; i < 4; ++i)
    {
        GeometryUnrecPtr           pGeo      = Geometry::create();
    
        ChunkMaterialUnrecPtr      pMat      = ChunkMaterial::create();
        MaterialChunkUnrecPtr      pMatChunk = MaterialChunk::create();
        
        GeoPnt3fPropertyUnrecPtr   pPoints   = GeoPnt3fProperty  ::create();
        GeoUInt32PropertyUnrecPtr  pLengths  = GeoUInt32Property ::create();
        GeoUInt8PropertyUnrecPtr   pTypes    = GeoUInt8Property  ::create();
        GeoColor4fPropertyUnrecPtr pColors   = GeoColor4fProperty::create();
        GeoVec3fPropertyUnrecPtr   pNormals  = GeoVec3fProperty  ::create();

        if(i < 2)
        {
            pMatChunk->setLit(false);
        }
        
        pMatChunk->setDiffuse  (OSG::Color4f(1.0, 1.0, 1.0, 1.0));
        pMatChunk->setSpecular (OSG::Color4f(0.0, 0.0, 0.0, 1.0));
        pMatChunk->setShininess(10.0f);
        
        pMat->addChunk(pMatChunk);

        TwoSidedLightingChunkUnrecPtr pTSLChunk = 
            TwoSidedLightingChunk::create();
            
        pMat->addChunk(pTSLChunk);

        pGeo->setDlistCache(false   );
        
        pGeo->setMaterial  (pMat    );
        pGeo->setPositions (pPoints );
        pGeo->setLengths   (pLengths);
        pGeo->setTypes     (pTypes  );
        pGeo->setColors    (pColors );

        if(i > 1)
        {
            pGeo->setNormals(pNormals);
        }

        OSG::NodeUnrecPtr pGeoRoot = OSG::Node::create();
        
        pGeoRoot->setCore    (pGeo);
        pGeoRoot->setTravMask(0   );

        pRoot->addChild(pGeoRoot);

        this->pushToGeometries    (pGeo     );
        this->pushToMaterials     (pMat     );
        this->pushToMaterialChunks(pMatChunk);
        this->pushToPositions     (pPoints  );
        this->pushToLength        (pLengths );
        this->pushToTypes         (pTypes   );
        this->pushToColors        (pColors  );
        this->pushToNormals       (pNormals );
        this->pushToGeoRoots      (pGeoRoot );
    }
}
// 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 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 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);  

    // 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);
    
    dl->setAmbient  (0.0, 0.0, 0.0, 1.0);
    dl->setDiffuse  (0.8, 0.8, 0.8, 1.0);
    dl->setDirection(0.0, 0.0, 1.0     );
    dl->setBeacon   (b1n               );

    // root
    OSG::NodeUnrecPtr  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);

        file = OSG::Node::create();
        OSG::AlgorithmStageUnrecPtr pStage = OSG::AlgorithmStage::create();

        file->setCore(pStage);

        pAlgo = OSG::GPUVolRTV2::create();

        pStage->setAlgorithm(pAlgo);

        // fix/freeze the node volume
        file->editVolume().setStatic(true);
        file->editVolume().setBounds( 0.f,   0.f,   0.f,
                                      1.f,   1.f,   1.f);
        
   }
   
    OSG::commitChanges();

    file->updateVolume();


    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();
    OSG::TransformRecPtr scene_trans = OSG::Transform::create();

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

    pPoly = OSG::PolygonChunk::create();

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

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

    dlight->addChild(sceneTrN);


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

    cam->setBeacon(b1n                   );
    cam->setFov   (OSG::osgDegree2Rad(60));
    cam->setNear  (0.1                   );
    cam->setFar   (400                   );

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

    bkgnd->setColor(OSG::Color3f(0,0,0));
    
    // Viewport
    OSG::ViewportRecPtr vp = OSG::Viewport::create();

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


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

    GLint glvp[4];

    glGetIntegerv(GL_VIEWPORT, glvp);

    OSG::GLUTWindowUnrecPtr 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();
//    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...


    return 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 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);
}
OSG::NodeTransitPtr initVTK(void)
{
    OSG::NodeUnrecPtr returnValue = NULL;

    OSG::Char8 *szDataRoot = getenv("VTK_DATA_ROOT");

    if(szDataRoot == NULL)
    {
        fprintf(stderr, "VTK_DATA_ROOT not set\n");
        exit(0);
    }

    std::string szFilename;

    szFilename.assign(szDataRoot);
    szFilename += "/Data/office.binary.vtk";

    vtkStructuredGridReader *reader = vtkStructuredGridReader::New();

    reader->SetFileName(szFilename.c_str());
    reader->Update();

#if 0
    OSG::Real64 length = reader->GetOutput()->GetLength();

    OSG::Real64 maxVelocity = 
        reader->GetOutput()->GetPointData()->GetVectors()->GetMaxNorm();

    OSG::Real64 maxTime = 35.0 * length / maxVelocity;
#endif


    returnValue = OSG::Node::create();

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

    // Create source for streamtubes
    vtkPointSource *seeds = vtkPointSource::New();
    seeds->SetRadius(0.15);
    seeds->SetCenter(0.1, 2.1, 0.5);
    seeds->SetNumberOfPoints(6);

    vtkRungeKutta4 *integ = vtkRungeKutta4::New();
    vtkStreamLine *streamer = vtkStreamLine::New();
    streamer->SetInputConnection(reader->GetOutputPort());
#if VTK_MAJOR_VERSION >= 6
    streamer->SetSourceData(seeds->GetOutput());
#else
    streamer->SetSource(seeds->GetOutput());
#endif
    streamer->SetMaximumPropagationTime(500);
    streamer->SetStepLength(0.5);
    streamer->SetIntegrationStepLength(0.05);
    streamer->SetIntegrationDirectionToIntegrateBothDirections();
    streamer->SetIntegrator(integ);

    // The tube is wrapped around the generated streamline. By varying the
    // radius by the inverse of vector magnitude, we are creating a tube
    // whose radius is proportional to mass flux (in incompressible flow).
    vtkTubeFilter *streamTube = vtkTubeFilter::New();
    streamTube->SetInputConnection(streamer->GetOutputPort());
    streamTube->SetRadius(0.02);
    streamTube->SetNumberOfSides(12);
    streamTube->SetVaryRadiusToVaryRadiusByVector();
    vtkPolyDataMapper *mapStreamTube = vtkPolyDataMapper::New();
    mapStreamTube->SetInputConnection(streamTube->GetOutputPort());
    mapStreamTube->SetScalarRange(
        reader->GetOutput()->GetPointData()->GetScalars()->GetRange());
    vtkActor *streamTubeActor = vtkActor::New();
    streamTubeActor->SetMapper(mapStreamTube);
    streamTubeActor->GetProperty()->BackfaceCullingOn();

    addActor(returnValue, streamTubeActor);


    vtkStructuredGridGeometryFilter *table1 = 
        vtkStructuredGridGeometryFilter::New();

    table1->SetInputConnection(reader->GetOutputPort());
    table1->SetExtent(11, 15, 7, 9, 8, 8);

    vtkPolyDataNormals *normTable1 = vtkPolyDataNormals::New();
    normTable1->SetInputConnection(table1->GetOutputPort());

    vtkPolyDataMapper *mapTable1 = vtkPolyDataMapper::New();
    mapTable1->SetInputConnection(normTable1->GetOutputPort());
    mapTable1->ScalarVisibilityOff();
    
    vtkActor *table1Actor = vtkActor::New();
    table1Actor->SetMapper(mapTable1);
    table1Actor->GetProperty()->SetColor(.59, .427, .392);

    addActor(returnValue, table1Actor);



    vtkStructuredGridGeometryFilter *table2 = 
        vtkStructuredGridGeometryFilter::New();
    table2->SetInputConnection(reader->GetOutputPort());
    table2->SetExtent(11, 15, 10, 12, 8, 8);

    vtkPolyDataNormals *normTable2 = vtkPolyDataNormals::New();
    normTable2->SetInputConnection(table2->GetOutputPort());

    vtkPolyDataMapper *mapTable2 = vtkPolyDataMapper::New();
    mapTable2->SetInputConnection(normTable2->GetOutputPort());
    mapTable2->ScalarVisibilityOff();
    
    vtkActor *table2Actor = vtkActor::New();
    table2Actor->SetMapper(mapTable2);
    table2Actor->GetProperty()->SetColor(.59, .427, .392);

    addActor(returnValue, table2Actor);



    vtkStructuredGridGeometryFilter *FilingCabinet1 = 
        vtkStructuredGridGeometryFilter::New();

    FilingCabinet1->SetInputConnection(reader->GetOutputPort());
    FilingCabinet1->SetExtent(15, 15, 7, 9, 0, 8);

    vtkPolyDataNormals *normFilingCabinet1 = vtkPolyDataNormals::New();
    normFilingCabinet1->SetInputConnection(FilingCabinet1->GetOutputPort());

    vtkPolyDataMapper *mapFilingCabinet1 = vtkPolyDataMapper::New();
    mapFilingCabinet1->SetInputConnection(normFilingCabinet1->GetOutputPort());
    mapFilingCabinet1->ScalarVisibilityOff();

    vtkActor *FilingCabinet1Actor = vtkActor::New();
    FilingCabinet1Actor->SetMapper(mapFilingCabinet1);
    FilingCabinet1Actor->GetProperty()->SetColor(.8, .8, .6);

    addActor(returnValue, FilingCabinet1Actor);



    vtkStructuredGridGeometryFilter *FilingCabinet2 = 
        vtkStructuredGridGeometryFilter::New();
    FilingCabinet2->SetInputConnection(reader->GetOutputPort());
    FilingCabinet2->SetExtent(15, 15, 10, 12, 0, 8);

    vtkPolyDataNormals *normFilingCabinet2 = vtkPolyDataNormals::New();
    normFilingCabinet2->SetInputConnection(FilingCabinet2->GetOutputPort());

    vtkPolyDataMapper *mapFilingCabinet2 = vtkPolyDataMapper::New();
    mapFilingCabinet2->SetInputConnection(normFilingCabinet2->GetOutputPort());
    mapFilingCabinet2->ScalarVisibilityOff();

    vtkActor *FilingCabinet2Actor = vtkActor::New();
    FilingCabinet2Actor->SetMapper(mapFilingCabinet2);
    FilingCabinet2Actor->GetProperty()->SetColor(.8, .8, .6);

    addActor(returnValue, FilingCabinet2Actor);



    vtkStructuredGridGeometryFilter *bookshelf1Top = 
        vtkStructuredGridGeometryFilter::New();
    bookshelf1Top->SetInputConnection(reader->GetOutputPort());
    bookshelf1Top->SetExtent(13, 13, 0, 4, 0, 11);

    vtkPolyDataNormals *normbookshelf1Top = vtkPolyDataNormals::New();
    normbookshelf1Top->SetInputConnection(bookshelf1Top->GetOutputPort());

    vtkPolyDataMapper *mapBookshelf1Top = vtkPolyDataMapper::New();
    mapBookshelf1Top->SetInputConnection(normbookshelf1Top->GetOutputPort());
    mapBookshelf1Top->ScalarVisibilityOff();

    vtkActor *bookshelf1TopActor = vtkActor::New();
    bookshelf1TopActor->SetMapper(mapBookshelf1Top);
    bookshelf1TopActor->GetProperty()->SetColor(.8, .8, .6);

    addActor(returnValue, bookshelf1TopActor);


    
    vtkStructuredGridGeometryFilter *bookshelf1Bottom = 
        vtkStructuredGridGeometryFilter::New();
    bookshelf1Bottom->SetInputConnection(reader->GetOutputPort());
    bookshelf1Bottom->SetExtent(20, 20, 0, 4, 0, 11);

    vtkPolyDataNormals *normbookshelf1Bottom = vtkPolyDataNormals::New();
    normbookshelf1Bottom->SetInputConnection(
        bookshelf1Bottom->GetOutputPort());

    vtkPolyDataMapper *mapBookshelf1Bottom = vtkPolyDataMapper::New();
    mapBookshelf1Bottom->SetInputConnection(
        normbookshelf1Bottom->GetOutputPort());
    mapBookshelf1Bottom->ScalarVisibilityOff();

    vtkActor *bookshelf1BottomActor = vtkActor::New();
    bookshelf1BottomActor->SetMapper(mapBookshelf1Bottom);
    bookshelf1BottomActor->GetProperty()->SetColor(.8, .8, .6);

    addActor(returnValue, bookshelf1BottomActor);



    vtkStructuredGridGeometryFilter *bookshelf1Front = 
        vtkStructuredGridGeometryFilter::New();
    bookshelf1Front->SetInputConnection(reader->GetOutputPort());
    bookshelf1Front->SetExtent(13, 20, 0, 0, 0, 11);

    vtkPolyDataNormals *normbookshelf1Front = vtkPolyDataNormals::New();
    normbookshelf1Front->SetInputConnection(bookshelf1Front->GetOutputPort());

    vtkPolyDataMapper *mapBookshelf1Front = vtkPolyDataMapper::New();
    mapBookshelf1Front->SetInputConnection(
        normbookshelf1Front->GetOutputPort());
    mapBookshelf1Front->ScalarVisibilityOff();

    vtkActor *bookshelf1FrontActor = vtkActor::New();
    bookshelf1FrontActor->SetMapper(mapBookshelf1Front);
    bookshelf1FrontActor->GetProperty()->SetColor(.8, .8, .6);

    addActor(returnValue, bookshelf1FrontActor);



    vtkStructuredGridGeometryFilter *bookshelf1Back = 
        vtkStructuredGridGeometryFilter::New();
    bookshelf1Back->SetInputConnection(reader->GetOutputPort());
    bookshelf1Back->SetExtent(13, 20, 4, 4, 0, 11);

    vtkPolyDataNormals *normbookshelf1Back = vtkPolyDataNormals::New();
    normbookshelf1Back->SetInputConnection(bookshelf1Back->GetOutputPort());

    vtkPolyDataMapper *mapBookshelf1Back = vtkPolyDataMapper::New();
    mapBookshelf1Back->SetInputConnection(normbookshelf1Back->GetOutputPort());
    mapBookshelf1Back->ScalarVisibilityOff();

    vtkActor *bookshelf1BackActor = vtkActor::New();
    bookshelf1BackActor->SetMapper(mapBookshelf1Back);
    bookshelf1BackActor->GetProperty()->SetColor(.8, .8, .6);
    
    addActor(returnValue, bookshelf1BackActor);



    vtkStructuredGridGeometryFilter *bookshelf1LHS = 
        vtkStructuredGridGeometryFilter::New();
    bookshelf1LHS->SetInputConnection(reader->GetOutputPort());
    bookshelf1LHS->SetExtent(13, 20, 0, 4, 0, 0);

    vtkPolyDataNormals *normbookshelf1LHS = vtkPolyDataNormals::New();
    normbookshelf1LHS->SetInputConnection(bookshelf1LHS->GetOutputPort());

    vtkPolyDataMapper *mapBookshelf1LHS = vtkPolyDataMapper::New();
    mapBookshelf1LHS->SetInputConnection(normbookshelf1LHS->GetOutputPort());
    mapBookshelf1LHS->ScalarVisibilityOff();

    vtkActor *bookshelf1LHSActor = vtkActor::New();
    bookshelf1LHSActor->SetMapper(mapBookshelf1LHS);
    bookshelf1LHSActor->GetProperty()->SetColor(.8, .8, .6);

    addActor(returnValue, bookshelf1LHSActor);



    vtkStructuredGridGeometryFilter *bookshelf1RHS = 
        vtkStructuredGridGeometryFilter::New();
    bookshelf1RHS->SetInputConnection(reader->GetOutputPort());
    bookshelf1RHS->SetExtent(13, 20, 0, 4, 11, 11);

    vtkPolyDataNormals *normbookshelf1RHS = vtkPolyDataNormals::New();
    normbookshelf1RHS->SetInputConnection(bookshelf1RHS->GetOutputPort());

    vtkPolyDataMapper *mapBookshelf1RHS = vtkPolyDataMapper::New();
    mapBookshelf1RHS->SetInputConnection(normbookshelf1RHS->GetOutputPort());
    mapBookshelf1RHS->ScalarVisibilityOff();

    vtkActor *bookshelf1RHSActor = vtkActor::New();
    bookshelf1RHSActor->SetMapper(mapBookshelf1RHS);
    bookshelf1RHSActor->GetProperty()->SetColor(.8, .8, .6);

    addActor(returnValue, bookshelf1RHSActor);



    vtkStructuredGridGeometryFilter *bookshelf2Top = 
        vtkStructuredGridGeometryFilter::New();
    bookshelf2Top->SetInputConnection(reader->GetOutputPort());
    bookshelf2Top->SetExtent(13, 13, 15, 19, 0, 11);

    vtkPolyDataNormals *normbookshelf2Top = vtkPolyDataNormals::New();
    normbookshelf2Top->SetInputConnection(bookshelf2Top->GetOutputPort());

    vtkPolyDataMapper *mapBookshelf2Top = vtkPolyDataMapper::New();
    mapBookshelf2Top->SetInputConnection(normbookshelf2Top->GetOutputPort());
    mapBookshelf2Top->ScalarVisibilityOff();

    vtkActor *bookshelf2TopActor = vtkActor::New();
    bookshelf2TopActor->SetMapper(mapBookshelf2Top);
    bookshelf2TopActor->GetProperty()->SetColor(.8, .8, .6);

    addActor(returnValue, bookshelf2TopActor);


    vtkStructuredGridGeometryFilter *bookshelf2Bottom = 
        vtkStructuredGridGeometryFilter::New();
    bookshelf2Bottom->SetInputConnection(reader->GetOutputPort());
    bookshelf2Bottom->SetExtent(20, 20, 15, 19, 0, 11);

    vtkPolyDataNormals *normbookshelf2Bottom = vtkPolyDataNormals::New();
    normbookshelf2Bottom->SetInputConnection(
        bookshelf2Bottom->GetOutputPort());

    vtkPolyDataMapper *mapBookshelf2Bottom = vtkPolyDataMapper::New();
    mapBookshelf2Bottom->SetInputConnection(
        normbookshelf2Bottom->GetOutputPort());
    mapBookshelf2Bottom->ScalarVisibilityOff();

    vtkActor *bookshelf2BottomActor = vtkActor::New();
    bookshelf2BottomActor->SetMapper(mapBookshelf2Bottom);
    bookshelf2BottomActor->GetProperty()->SetColor(.8, .8, .6);

    addActor(returnValue, bookshelf2BottomActor);



    vtkStructuredGridGeometryFilter *bookshelf2Front = 
        vtkStructuredGridGeometryFilter::New();
    bookshelf2Front->SetInputConnection(reader->GetOutputPort());
    bookshelf2Front->SetExtent(13, 20, 15, 15, 0, 11);

    vtkPolyDataNormals *normbookshelf2Front = vtkPolyDataNormals::New();
    normbookshelf2Front->SetInputConnection(bookshelf2Front->GetOutputPort());

    vtkPolyDataMapper *mapBookshelf2Front = vtkPolyDataMapper::New();
    mapBookshelf2Front->SetInputConnection(
        normbookshelf2Front->GetOutputPort());
    mapBookshelf2Front->ScalarVisibilityOff();

    vtkActor *bookshelf2FrontActor = vtkActor::New();
    bookshelf2FrontActor->SetMapper(mapBookshelf2Front);
    bookshelf2FrontActor->GetProperty()->SetColor(.8, .8, .6);

    addActor(returnValue, bookshelf2FrontActor);



    vtkStructuredGridGeometryFilter *bookshelf2Back = 
        vtkStructuredGridGeometryFilter::New();
    bookshelf2Back->SetInputConnection(reader->GetOutputPort());
    bookshelf2Back->SetExtent(13, 20, 19, 19, 0, 11);

    vtkPolyDataNormals *normbookshelf2Back = vtkPolyDataNormals::New();
    normbookshelf2Back->SetInputConnection(bookshelf2Back->GetOutputPort());

    vtkPolyDataMapper *mapBookshelf2Back = vtkPolyDataMapper::New();
    mapBookshelf2Back->SetInputConnection(normbookshelf2Back->GetOutputPort());
    mapBookshelf2Back->ScalarVisibilityOff();

    vtkActor *bookshelf2BackActor = vtkActor::New();
    bookshelf2BackActor->SetMapper(mapBookshelf2Back);
    bookshelf2BackActor->GetProperty()->SetColor(.8, .8, .6);
    
    addActor(returnValue, bookshelf2BackActor);



    vtkStructuredGridGeometryFilter *bookshelf2LHS = 
        vtkStructuredGridGeometryFilter::New();
    bookshelf2LHS->SetInputConnection(reader->GetOutputPort());
    bookshelf2LHS->SetExtent(13, 20, 15, 19, 0, 0);

    vtkPolyDataNormals *normbookshelf2LHS = vtkPolyDataNormals::New();
    normbookshelf2LHS->SetInputConnection(bookshelf2LHS->GetOutputPort());

    vtkPolyDataMapper *mapBookshelf2LHS = vtkPolyDataMapper::New();
    mapBookshelf2LHS->SetInputConnection(normbookshelf2LHS->GetOutputPort());
    mapBookshelf2LHS->ScalarVisibilityOff();
    vtkActor *bookshelf2LHSActor = vtkActor::New();
    bookshelf2LHSActor->SetMapper(mapBookshelf2LHS);
    bookshelf2LHSActor->GetProperty()->SetColor(.8, .8, .6);

    addActor(returnValue, bookshelf2LHSActor);



    vtkStructuredGridGeometryFilter *bookshelf2RHS = 
        vtkStructuredGridGeometryFilter::New();
    bookshelf2RHS->SetInputConnection(reader->GetOutputPort());
    bookshelf2RHS->SetExtent(13, 20, 15, 19, 11, 11);

    vtkPolyDataNormals *normbookshelf2RHS = vtkPolyDataNormals::New();
    normbookshelf2RHS->SetInputConnection(bookshelf2RHS->GetOutputPort());

    vtkPolyDataMapper *mapBookshelf2RHS = vtkPolyDataMapper::New();
    mapBookshelf2RHS->SetInputConnection(normbookshelf2RHS->GetOutputPort());
    mapBookshelf2RHS->ScalarVisibilityOff();

    vtkActor *bookshelf2RHSActor = vtkActor::New();
    bookshelf2RHSActor->SetMapper(mapBookshelf2RHS);
    bookshelf2RHSActor->GetProperty()->SetColor(.8, .8, .6);
    
    addActor(returnValue, bookshelf2RHSActor);



    vtkStructuredGridGeometryFilter *window = 
        vtkStructuredGridGeometryFilter::New();
    window->SetInputConnection(reader->GetOutputPort());
    window->SetExtent(20, 20, 6, 13, 10, 13);

    vtkPolyDataNormals *normWindow = vtkPolyDataNormals::New();
    normWindow->SetInputConnection(window->GetOutputPort());

    vtkPolyDataMapper *mapWindow = vtkPolyDataMapper::New();
    mapWindow->SetInputConnection(normWindow->GetOutputPort());
    mapWindow->ScalarVisibilityOff(); 

    vtkActor *windowActor = vtkActor::New();
    windowActor->SetMapper(mapWindow);
    windowActor->GetProperty()->SetColor(.3, .3, .5);
    
    addActor(returnValue, windowActor);



    vtkStructuredGridGeometryFilter *outlet = 
        vtkStructuredGridGeometryFilter::New();
    outlet->SetInputConnection(reader->GetOutputPort());
    outlet->SetExtent(0, 0, 9, 10, 14, 16);

    vtkPolyDataNormals *normoutlet = vtkPolyDataNormals::New();
    normoutlet->SetInputConnection(outlet->GetOutputPort());

    vtkPolyDataMapper *mapOutlet = vtkPolyDataMapper::New();
    mapOutlet->SetInputConnection(normoutlet->GetOutputPort());
    mapOutlet->ScalarVisibilityOff();
    vtkActor *outletActor = vtkActor::New();
    outletActor->SetMapper(mapOutlet);
    outletActor->GetProperty()->SetColor(0, 0, 0);

    addActor(returnValue, outletActor);



    vtkStructuredGridGeometryFilter *inlet = 
        vtkStructuredGridGeometryFilter::New();
    inlet->SetInputConnection(reader->GetOutputPort());
    inlet->SetExtent(0, 0, 9, 10, 0, 6);

    vtkPolyDataNormals *norminlet = vtkPolyDataNormals::New();
    norminlet->SetInputConnection(inlet->GetOutputPort());

    vtkPolyDataMapper *mapInlet = vtkPolyDataMapper::New();
    mapInlet->SetInputConnection(norminlet->GetOutputPort());

    mapInlet->ScalarVisibilityOff();
    vtkActor *inletActor = vtkActor::New();
    inletActor->SetMapper(mapInlet);
    inletActor->GetProperty()->SetColor(0, 0, 0);



    vtkStructuredGridOutlineFilter *outline = 
        vtkStructuredGridOutlineFilter::New();
    
    outline->SetInputConnection(reader->GetOutputPort());
    
    vtkPolyDataMapper *mapOutline = vtkPolyDataMapper::New();
    mapOutline->SetInputConnection(outline->GetOutputPort());
    
    vtkActor *outlineActor = vtkActor::New();
    
    outlineActor->SetMapper(mapOutline);
    outlineActor->GetProperty()->SetColor(0, 0, 0);
    
    addActor(returnValue, outlineActor);

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

    return OSG::NodeTransitPtr(returnValue);
}
TEST_FIXTURE(FileFixture, TextureChunkIO)
{
    OSG::NodeUnrecPtr          n   = OSG::Node::create();
    OSG::GeometryUnrecPtr      geo = OSG::makeBoxGeo(2.0, 2.0, 2.0, 1, 1, 1);
    OSG::ChunkMaterialUnrecPtr mat = OSG::ChunkMaterial::create();
    
    OSG::ImageUnrecPtr img = OSG::Image::create();
    img->set(OSG::Image::OSG_RGBA_PF, 2, 2);
    
    img->editData()[0 * 2 * 4 + 0 * 4 + 0] = 255;
    img->editData()[0 * 2 * 4 + 0 * 4 + 1] =   0;
    img->editData()[0 * 2 * 4 + 0 * 4 + 2] =   0;
    img->editData()[0 * 2 * 4 + 0 * 4 + 3] = 255;
    
    img->editData()[0 * 2 * 4 + 1 * 4 + 0] = 255;
    img->editData()[0 * 2 * 4 + 1 * 4 + 1] = 255;
    img->editData()[0 * 2 * 4 + 1 * 4 + 2] =   0;
    img->editData()[0 * 2 * 4 + 1 * 4 + 3] = 255;
    
    img->editData()[1 * 2 * 4 + 0 * 4 + 0] =   0;
    img->editData()[1 * 2 * 4 + 0 * 4 + 1] =   0;
    img->editData()[1 * 2 * 4 + 0 * 4 + 2] = 255;
    img->editData()[1 * 2 * 4 + 0 * 4 + 3] = 255;
    
    img->editData()[1 * 2 * 4 + 1 * 4 + 0] =   0;
    img->editData()[1 * 2 * 4 + 1 * 4 + 1] = 255;
    img->editData()[1 * 2 * 4 + 1 * 4 + 2] = 255;
    img->editData()[1 * 2 * 4 + 1 * 4 + 3] = 255;
    
    OSG::TextureChunkUnrecPtr tex = OSG::TextureChunk::create();
    tex->setImage(img);
    
    mat->addChunk(tex);
    geo->setMaterial(mat);
    
    n->setCore(geo);
    
    OSG::SceneFileHandler::the()->write(n, test_file.native_file_string().c_str());
    
    OSG::NodeUnrecPtr n2 =
        OSG::SceneFileHandler::the()->read(test_file.native_file_string().c_str());
        
    CHECK(n2 != NULL);
    
    CHECK(n2->getCore() != NULL);
    OSG::GeometryUnrecPtr      geo2 =
        dynamic_cast<OSG::Geometry *>(n2->getCore());
    CHECK(geo2 != NULL);
    
    CHECK(geo2->getMaterial() != NULL);
    OSG::ChunkMaterialUnrecPtr mat2 =
        dynamic_cast<OSG::ChunkMaterial *>(geo2->getMaterial());
    CHECK(mat2 != NULL);    
    
    CHECK(mat2->getChunk(0) != NULL);
    const OSG::TextureChunk *tex2 =
        dynamic_cast<const OSG::TextureChunk *>(mat2->getChunk(0));
    const OSG::TextureObjChunk *texObj =
        dynamic_cast<const OSG::TextureObjChunk *>(mat2->getChunk(0));
    const OSG::TextureEnvChunk *texEnv =
        dynamic_cast<const OSG::TextureEnvChunk *>(mat2->getChunk(1));
    CHECK(tex2   == NULL);    
    CHECK(texObj != NULL);
    CHECK(texEnv != NULL);
    
    CHECK(texObj->getImage() != NULL);
    OSG::Image *img2 = texObj->getImage();
    CHECK(img2 != NULL);
    
    CHECK_EQUAL(255, img2->getData()[0 * 2 * 4 + 0 * 4 + 0]);
    CHECK_EQUAL(  0, img2->getData()[0 * 2 * 4 + 0 * 4 + 1]);
    CHECK_EQUAL(  0, img2->getData()[0 * 2 * 4 + 0 * 4 + 2]);
    CHECK_EQUAL(255, img2->getData()[0 * 2 * 4 + 0 * 4 + 3]);
    
    CHECK_EQUAL(255, img2->getData()[0 * 2 * 4 + 1 * 4 + 0]);
    CHECK_EQUAL(255, img2->getData()[0 * 2 * 4 + 1 * 4 + 1]);
    CHECK_EQUAL(  0, img2->getData()[0 * 2 * 4 + 1 * 4 + 2]);
    CHECK_EQUAL(255, img2->getData()[0 * 2 * 4 + 1 * 4 + 3]);
    
    CHECK_EQUAL(  0, img2->getData()[1 * 2 * 4 + 0 * 4 + 0]);
    CHECK_EQUAL(  0, img2->getData()[1 * 2 * 4 + 0 * 4 + 1]);
    CHECK_EQUAL(255, img2->getData()[1 * 2 * 4 + 0 * 4 + 2]);
    CHECK_EQUAL(255, img2->getData()[1 * 2 * 4 + 0 * 4 + 3]);
    
    CHECK_EQUAL(  0, img2->getData()[1 * 2 * 4 + 1 * 4 + 0]);
    CHECK_EQUAL(255, img2->getData()[1 * 2 * 4 + 1 * 4 + 1]);
    CHECK_EQUAL(255, img2->getData()[1 * 2 * 4 + 1 * 4 + 2]);
    CHECK_EQUAL(255, img2->getData()[1 * 2 * 4 + 1 * 4 + 3]);
}
// 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;
}
// 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;
}
// Initialize GLUT & OpenSG and set up the scene
int doMain(int argc, char **argv)
{
    printf("Press key '9' or '0' to toggle light sources.\n");
    printf("Set the shadow mode with key '1' ... '8'\n");
    printf("Change MapSize with keys 'y' = 512, 'x' = 1024, 'c' = 2048\n");
    printf("NOTE: Real point lights only supported for ShadowMode 1...6!\n");
    // OSG init
    OSG::osgInit(argc, argv);

    // GLUT init
    int                     winid = setupGLUT(&argc, argv);
    gwin = OSG::GLUTWindow::create();

    //Erstellen der ben�tigten Komponenten--------------------------------------

    rootNode = OSG::makeCoredNode<OSG::Group>();
    OSG::NodeUnrecPtr                 scene = OSG::makeCoredNode<OSG::Group>();

    /*
    // create lights
    //Directional Light 1
    OSG::NodeUnrecPtr light1        = OSG::makeCoredNode<OSG::DirectionalLight>(&_light1_core);
    OSG::NodeUnrecPtr light1_beacon = OSG::makeCoredNode<OSG::Transform>(&_light1_trans);
    _light1_trans->editMatrix().setTranslate(0.0, 0.0, 0.0);
    _light1_core->setDirection(0.8,0.8,0.5);
    _light1_core->setAmbient(0.15,0.15,0.15,1);
    _light1_core->setDiffuse(0.5,0.5,0.5,1);
    _light1_core->setSpecular(0.0,0.0,0.0,1);
    _light1_core->setBeacon(light1_beacon);
    _light1_core->setShadowIntensity(0.7);
    _light1_core->setOn(true);
    */

    // Point Light 1
    OSG::NodeUnrecPtr light1        = OSG::makeCoredNode<OSG::PointLight>(&_light1_core);
    OSG::NodeUnrecPtr light1_beacon = OSG::makeCoredNode<OSG::Transform >(&_light1_trans);
    _light1_trans->editMatrix().setTranslate(50.0, 50.0, 10.0);

    _light1_core->setAmbient(0.15f, 0.15f, 0.15f, 1);
    _light1_core->setDiffuse(0.5f, 0.5f, 0.5f, 1);
    _light1_core->setSpecular(0.0f, 0.0f, 0.0f, 1);
    _light1_core->setBeacon(light1_beacon);
    _light1_core->setOn(true);
    _light1_core->setShadowIntensity(0.8f);

    // Spot Light 2
    OSG::NodeUnrecPtr light2        = OSG::makeCoredNode<OSG::SpotLight>(&_light2_core);
    OSG::NodeUnrecPtr light2_beacon = OSG::makeCoredNode<OSG::Transform>(&_light2_trans);
    //_light2_trans->editMatrix().setTranslate(75.0, 0.0, 25.0);
    _light2_trans->editMatrix().setTranslate(250.0, -250.0, 300.0);
       
    _light2_core->setAmbient(0.15,0.15,0.15,1);
    _light2_core->setDiffuse(0.5,0.5,0.5,1);
    _light2_core->setSpecular(0.0,0.0,0.0,1);
    _light2_core->setSpotCutOffDeg(40.0);
    _light2_core->setSpotDirection(-0.85,0.85,-1.0);
    _light2_core->setBeacon(light2_beacon);
    _light2_core->setShadowIntensity(0.7);
    _light2_core->setOn(true);

    /*
    // Point Light 2
    OSG::NodeUnrecPtr light2        = OSG::makeCoredNode<OSG::PointLight>(&_light2_core);
    OSG::NodeUnrecPtr light2_beacon = OSG::makeCoredNode<OSG::Transform> (&_light2_trans);
    _light2_trans->editMatrix().setTranslate(40.0, 0.0, 40.0);

    _light2_core->setAmbient(0.15f, 0.15f, 0.15f, 1);
    _light2_core->setDiffuse(0.5f, 0.5f, 0.5f, 1);
    _light2_core->setSpecular(0.0f, 0.0f, 0.0f, 1);
    _light2_core->setBeacon(light2_beacon);
    _light2_core->setOn(false);
    _light2_core->setShadowIntensity(0.7f);
    */

    light1->addChild(light2);

    light2->addChild(scene);

    //Eigene Kamera erstellen
    Pcamera = OSG::PerspectiveCamera::create();
    cam_beacon = OSG::makeCoredNode<OSG::Transform>(&cam_trans);
    cam_trans->editMatrix().setTranslate(0.0, 0.0, 25.0);

    Pcamera->setBeacon(cam_beacon);
    Pcamera->setFov(OSG::osgDegree2Rad(60));
    Pcamera->setNear(1.0);
    Pcamera->setFar(1000);

    // create scene

    // bottom
    OSG::NodeUnrecPtr                 plane = OSG::makePlane(300.0, 300.0, 256, 256);

    OSG::ImageUnrecPtr                plane_img = OSG::Image::create();
    plane_img->read("gras.jpg");

    OSG::TextureObjChunkUnrecPtr         plane_tex_obj = OSG::TextureObjChunk::create();
    OSG::TextureEnvChunkUnrecPtr         plane_tex_env = OSG::TextureEnvChunk::create();
    plane_tex_obj->setImage(plane_img);
    plane_tex_obj->setMinFilter(GL_LINEAR);
    plane_tex_obj->setMagFilter(GL_LINEAR);
    plane_tex_obj->setWrapS(GL_REPEAT);
    plane_tex_obj->setWrapT(GL_REPEAT);
    plane_tex_env->setEnvMode(GL_MODULATE);

    OSG::SimpleMaterialUnrecPtr       plane_mat = OSG::SimpleMaterial::create();
    plane_mat->setAmbient(OSG::Color3f(0.3f, 0.3f, 0.3f));
    plane_mat->setDiffuse(OSG::Color3f(1.0f, 1.0f, 1.0f));
    plane_mat->addChunk(plane_tex_obj);
    plane_mat->addChunk(plane_tex_env);

    OSG::Geometry *plane_geo = dynamic_cast<OSG::Geometry *>(plane->getCore());
    plane_geo->setMaterial(plane_mat);

    //load Tree Objects

    OSG::NodeUnrecPtr                 tree1_trans_node = OSG::makeCoredNode<OSG::Transform>
        (&_tree1_trans);
    OSG::NodeUnrecPtr                 tree2_trans_node = OSG::makeCoredNode<OSG::Transform>
        (&_tree2_trans);
    OSG::NodeUnrecPtr                 tree3_trans_node = OSG::makeCoredNode<OSG::Transform>
        (&_tree3_trans);
    OSG::NodeUnrecPtr                 tree4_trans_node = OSG::makeCoredNode<OSG::Transform>
        (&_tree4_trans);
    OSG::NodeUnrecPtr                 tree5_trans_node = OSG::makeCoredNode<OSG::Transform>
        (&_tree5_trans);
    OSG::NodeUnrecPtr                 tree6_trans_node = OSG::makeCoredNode<OSG::Transform>
        (&_tree6_trans);
    OSG::NodeUnrecPtr                 tree7_trans_node = OSG::makeCoredNode<OSG::Transform>
        (&_tree7_trans);
    OSG::NodeUnrecPtr                 tree8_trans_node = OSG::makeCoredNode<OSG::Transform>
        (&_tree8_trans);
    OSG::NodeUnrecPtr                 tree9_trans_node = OSG::makeCoredNode<OSG::Transform>
        (&_tree9_trans);

    _tree1_trans->editMatrix().setTranslate(-80.0, -80.0, 0.0);
    _tree1_trans->editMatrix().setScale(OSG::Vec3f(12.0, 12.0, 10.0));

    _tree2_trans->editMatrix().setTranslate(0.0, -80.0, 0.0);
    _tree2_trans->editMatrix().setScale(OSG::Vec3f(12.0, 12.0, 10.0));

    _tree3_trans->editMatrix().setTranslate(80.0, -80.0, 0.0);
    _tree3_trans->editMatrix().setScale(OSG::Vec3f(12.0, 12.0, 10.0));

    _tree4_trans->editMatrix().setTranslate(-80.0, 0.0, 0.0);
    _tree4_trans->editMatrix().setScale(OSG::Vec3f(12.0, 12.0, 10.0));

    _tree5_trans->editMatrix().setTranslate(0.0, 0.0, 0.0);
    _tree5_trans->editMatrix().setScale(OSG::Vec3f(12.0, 12.0, 10.0));

    _tree6_trans->editMatrix().setTranslate(80.0, 0.0, 0.0);
    _tree6_trans->editMatrix().setScale(OSG::Vec3f(12.0, 12.0, 10.0));

    _tree7_trans->editMatrix().setTranslate(-80.0, 80.0, 0.0);
    _tree7_trans->editMatrix().setScale(OSG::Vec3f(12.0, 12.0, 10.0));

    _tree8_trans->editMatrix().setTranslate(0.0, 80.0, 0.0);
    _tree8_trans->editMatrix().setScale(OSG::Vec3f(12.0, 12.0, 10.0));

    _tree9_trans->editMatrix().setTranslate(80.0, 80.0, 0.0);
    _tree9_trans->editMatrix().setScale(OSG::Vec3f(12.0, 12.0, 10.0));

    OSG::NodeUnrecPtr tree1 = OSG::SceneFileHandler::the()->read("tree1.3ds");

//    NodeUnrecPtr tree1 = makeSphere(2, 2.0);

    tree1_trans_node->addChild(tree1);

    tree2_trans_node->addChild(cloneTree(tree1));


    tree3_trans_node->addChild(cloneTree(tree1));

    tree4_trans_node->addChild(cloneTree(tree1));

    tree5_trans_node->addChild(cloneTree(tree1));

    tree6_trans_node->addChild(cloneTree(tree1));

    tree7_trans_node->addChild(cloneTree(tree1));

    tree8_trans_node->addChild(cloneTree(tree1));

    tree9_trans_node->addChild(cloneTree(tree1));

    OSG::NodeUnrecPtr                 trees = OSG::makeCoredNode<OSG::Group>();

    trees->addChild(tree1_trans_node);
    trees->addChild(tree2_trans_node);
    trees->addChild(tree3_trans_node);
    trees->addChild(tree4_trans_node);
    trees->addChild(tree5_trans_node);
    trees->addChild(tree6_trans_node);
    trees->addChild(tree7_trans_node);
    trees->addChild(tree8_trans_node);
    trees->addChild(tree9_trans_node);

    /*//load Airplane Object
       NodePtr obj1_trans_node = makeCoredNode<Transform>(&_obj1_trans);
       
       _obj1_trans->editMatrix().setTranslate(0.0, 0.0, 10.0);
       _obj1_trans->editMatrix().setScale(Vec3f(0.15,0.15,0.15));
       
       NodePtr object1 = SceneFileHandler::the().read("triplane.3ds");
       
       obj1_trans_node->addChild(object1);
       */

    //Load a Quad as Pointlight
    OSG::GeometryUnrecPtr             boxGeo = OSG::makeBoxGeo(15, 15, 15, 1, 1, 1);
    OSG::NodeUnrecPtr                 boxNode = OSG::Node::create();
    boxNode->setCore(boxGeo);

    OSG::SimpleMaterialUnrecPtr       box_mat = OSG::SimpleMaterial::create();
    box_mat->setAmbient(OSG::Color3f(0.95f, 1.0f, 0.2f));
    box_mat->setDiffuse(OSG::Color3f(0.95f, 1.0f, 0.2f));

    boxGeo->setMaterial(box_mat);

    OSG::NodeUnrecPtr                 obj1_trans_node = OSG::makeCoredNode<OSG::Transform>
        (&_obj1_trans);

    obj1_trans_node->addChild(boxNode);

    //load Dino Objects

    OSG::NodeUnrecPtr                 dino1_trans_node = OSG::makeCoredNode<OSG::Transform>
        (&_dino1_trans);
    OSG::NodeUnrecPtr                 dino2_trans_node = OSG::makeCoredNode<OSG::Transform>
        (&_dino2_trans);
    OSG::NodeUnrecPtr                 dino3_trans_node = OSG::makeCoredNode<OSG::Transform>
        (&_dino3_trans);
    OSG::NodeUnrecPtr                 dino4_trans_node = OSG::makeCoredNode<OSG::Transform>
        (&_dino4_trans);

    _dino1_trans->editMatrix().setTranslate(-20.0, -20.0, 10.0);
    _dino1_trans->editMatrix().setScale(OSG::Vec3f(5.0, 5.0, 5.0));

    _dino2_trans->editMatrix().setTranslate(-20.0, -20.0, 6.0);
    _dino2_trans->editMatrix().setScale(OSG::Vec3f(3.0, 3.0, 3.0));

    _dino3_trans->editMatrix().setTranslate(-20.0, -20.0, 6.0);
    _dino3_trans->editMatrix().setScale(OSG::Vec3f(3.0, 3.0, 3.0));

    _dino4_trans->editMatrix().setTranslate(-20.0, -20.0, 6.0);
    _dino4_trans->editMatrix().setScale(OSG::Vec3f(3.0, 3.0, 3.0));

    OSG::NodeUnrecPtr dino1 = OSG::SceneFileHandler::the()->read("dinopet.3ds");

//    NodeUnrecPtr dino1 = makeBox(2., 2., 2., 4, 4, 4);

    dino1_trans_node->addChild(dino1);

    dino2_trans_node->addChild(cloneTree(dino1));

    dino3_trans_node->addChild(cloneTree(dino1));

    dino4_trans_node->addChild(cloneTree(dino1));

    OSG::NodeUnrecPtr                 dinos = OSG::makeCoredNode<OSG::Group>();

    dinos->addChild(dino1_trans_node);
    dinos->addChild(dino2_trans_node);
    dinos->addChild(dino3_trans_node);
    dinos->addChild(dino4_trans_node);

    //load Stone Objects

    OSG::TransformUnrecPtr            _stone_trans1, _stone_trans2, _stone_trans3,
                            _stone_trans4, _stone_trans5, _stone_trans6,
                            _stone_trans7, _stone_trans8,
                            _stone_trans9;
    OSG::NodeUnrecPtr                 stone_trans_node1 = OSG::makeCoredNode<OSG::Transform>
        (&_stone_trans1);
    OSG::NodeUnrecPtr                 stone_trans_node2 = OSG::makeCoredNode<OSG::Transform>
        (&_stone_trans2);
    OSG::NodeUnrecPtr                 stone_trans_node3 = OSG::makeCoredNode<OSG::Transform>
        (&_stone_trans3);
    OSG::NodeUnrecPtr                 stone_trans_node4 = OSG::makeCoredNode<OSG::Transform>
        (&_stone_trans4);
    OSG::NodeUnrecPtr                 stone_trans_node5 = OSG::makeCoredNode<OSG::Transform>
        (&_stone_trans5);
    OSG::NodeUnrecPtr                 stone_trans_node6 = OSG::makeCoredNode<OSG::Transform>
        (&_stone_trans6);
    OSG::NodeUnrecPtr                 stone_trans_node7 = OSG::makeCoredNode<OSG::Transform>
        (&_stone_trans7);
    OSG::NodeUnrecPtr                 stone_trans_node8 = OSG::makeCoredNode<OSG::Transform>
        (&_stone_trans8);
    OSG::NodeUnrecPtr                 stone_trans_node9 = OSG::makeCoredNode<OSG::Transform>
        (&_stone_trans9);

    _stone_trans1->editMatrix().setTranslate(-70, -70, 0);

    _stone_trans2->editMatrix().setTranslate(10, -70, 0);

    _stone_trans3->editMatrix().setTranslate(90, -70, 0);

    _stone_trans4->editMatrix().setTranslate(-70, 10, 0);

    _stone_trans5->editMatrix().setTranslate(10, 10, 0);

    _stone_trans6->editMatrix().setTranslate(90, 10, 0);

    _stone_trans7->editMatrix().setTranslate(-70, 90, 0);

    _stone_trans8->editMatrix().setTranslate(10, 90, 0);

    _stone_trans9->editMatrix().setTranslate(90, 90, 0);

    OSG::NodeUnrecPtr                 stone1 = OSG::makeSphere(1, 7.0);
    OSG::NodeUnrecPtr                 stone2 = OSG::makeSphere(1, 7.0);
    OSG::NodeUnrecPtr                 stone3 = OSG::makeSphere(1, 7.0);
    OSG::NodeUnrecPtr                 stone4 = OSG::makeSphere(1, 7.0);
    OSG::NodeUnrecPtr                 stone5 = OSG::makeSphere(1, 7.0);
    OSG::NodeUnrecPtr                 stone6 = OSG::makeSphere(1, 7.0);
    OSG::NodeUnrecPtr                 stone7 = OSG::makeSphere(1, 7.0);
    OSG::NodeUnrecPtr                 stone8 = OSG::makeSphere(1, 7.0);
    OSG::NodeUnrecPtr                 stone9 = OSG::makeSphere(1, 7.0);

    OSG::ImageUnrecPtr                plane_img2 = OSG::Image::create();
    plane_img2->read("stone.jpg");

    OSG::TextureObjChunkUnrecPtr         plane_tex2_obj = OSG::TextureObjChunk::create();
    OSG::TextureEnvChunkUnrecPtr         plane_tex2_env = OSG::TextureEnvChunk::create();
    plane_tex2_obj->setImage(plane_img2);
    plane_tex2_obj->setMinFilter(GL_LINEAR);
    plane_tex2_obj->setMagFilter(GL_LINEAR);
    plane_tex2_obj->setWrapS(GL_REPEAT);
    plane_tex2_obj->setWrapT(GL_REPEAT);
    plane_tex2_env->setEnvMode(GL_MODULATE);

    OSG::SimpleMaterialUnrecPtr       plane_mat2 = OSG::SimpleMaterial::create();
    plane_mat2->setAmbient(OSG::Color3f(0.3f, 0.3f, 0.3f));
    plane_mat2->setDiffuse(OSG::Color3f(1.0f, 1.0f, 1.0f));
    plane_mat2->addChunk(plane_tex2_obj);
    plane_mat2->addChunk(plane_tex2_env);

    OSG::Geometry *plane_geo3 = dynamic_cast<OSG::Geometry *>(stone1->getCore());
    plane_geo3->setMaterial(plane_mat2);

    plane_geo3 = dynamic_cast<OSG::Geometry *>(stone2->getCore());
    plane_geo3->setMaterial(plane_mat2);

    plane_geo3 = dynamic_cast<OSG::Geometry *>(stone3->getCore());
    plane_geo3->setMaterial(plane_mat2);

    plane_geo3 = dynamic_cast<OSG::Geometry *>(stone4->getCore());
    plane_geo3->setMaterial(plane_mat2);

    plane_geo3 = dynamic_cast<OSG::Geometry *>(stone5->getCore());
    plane_geo3->setMaterial(plane_mat2);

    plane_geo3 = dynamic_cast<OSG::Geometry *>(stone6->getCore());
    plane_geo3->setMaterial(plane_mat2);

    plane_geo3 = dynamic_cast<OSG::Geometry *>(stone7->getCore());
    plane_geo3->setMaterial(plane_mat2);

    plane_geo3 = dynamic_cast<OSG::Geometry *>(stone8->getCore());
    plane_geo3->setMaterial(plane_mat2);

    plane_geo3 = dynamic_cast<OSG::Geometry *>(stone9->getCore());
    plane_geo3->setMaterial(plane_mat2);


    stone_trans_node1->addChild(stone1);

    stone_trans_node2->addChild(stone2);

    stone_trans_node3->addChild(stone3);

    stone_trans_node4->addChild(stone4);

    stone_trans_node5->addChild(stone5);

    stone_trans_node6->addChild(stone6);

    stone_trans_node7->addChild(stone7);

    stone_trans_node8->addChild(stone8);

    stone_trans_node9->addChild(stone9);

    OSG::NodeUnrecPtr                 stones = OSG::makeCoredNode<OSG::Group>();

    stones->addChild(stone_trans_node1);
    stones->addChild(stone_trans_node2);
    stones->addChild(stone_trans_node3);
    stones->addChild(stone_trans_node4);
    stones->addChild(stone_trans_node5);
    stones->addChild(stone_trans_node6);
    stones->addChild(stone_trans_node7);
    stones->addChild(stone_trans_node8);
    stones->addChild(stone_trans_node9);


    scene->addChild(plane);
    scene->addChild(obj1_trans_node);
    scene->addChild(trees);
    scene->addChild(stones);
    scene->addChild(dinos);

    svp = OSG::ShadowStage::create();
    OSG::GradientBackgroundUnrecPtr   gbg = OSG::GradientBackground::create();
    OSG::SolidBackgroundUnrecPtr      sbg = OSG::SolidBackground::create();

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

    rootNode->setCore(svp);

    rootNode->addChild(light1);
    rootNode->addChild(light1_beacon);
    rootNode->addChild(light2_beacon);
    rootNode->addChild(cam_beacon);

    // Shadow viewport
#ifdef SHADOW_CHECK
    svp->setBackground(gbg);
    svp->setRoot(rootNode);
    svp->setSize(0, 0, 1, 1);
#endif
    //svp->setOffFactor(4.0);
    //svp->setOffBias(8.0);
    //used to set global shadow intensity, ignores shadow intensity from light sources if != 0.0
    //svp->setGlobalShadowIntensity(0.8);
    svp->setMapSize(1024);
    //ShadowSmoothness used for PCF_SHADOW_MAP and VARIANCE_SHADOW_MAP, defines Filter Width. Range can be 0.0 ... 1.0.
    //ShadowSmoothness also used to define the light size for PCSS_SHADOW_MAP
    svp->setShadowSmoothness(0.5);
    // add light sources here
    //svp->editMFLightNodes  ()->push_back(light1);
    //svp->editMFLightNodes  ()->push_back(light2);
    svp->editMFExcludeNodes()->push_back(obj1_trans_node);
    svp->setAutoSearchForLights(true);

    //one active light at startup
    _light2_core->setOn(true);
    _light2_core->setAmbient(0.3f, 0.3f, 0.3f, 1);
    _light2_core->setDiffuse(0.8f, 0.8f, 0.8f, 1);

    _light1_core->setOn(false);
    _light1_core->setAmbient(0.3, 0.3, 0.3, 1);
    _light1_core->setDiffuse(0.8, 0.8, 0.8, 1);

    gwin->setGlutId(winid);
#ifdef SHADOW_CHECK
    gwin->addPort(svp);
#endif

    gwin->init();

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

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

    mgr->setWindow(gwin);
    mgr->setCamera(Pcamera);
    mgr->setRoot(rootNode);

    _navigator.setMode(OSG::Navigator::TRACKBALL);

#ifdef SHADOW_CHECK
    _navigator.setViewport(svp);
#endif
    _navigator.setCameraTransformation(cam_beacon);


    OSG::Vec3f                   up(0,1,0);
    OSG::Pnt3f                   at(0,0,0);
    OSG::Pnt3f                   from(0.0f,-100.1f,20.0f);

    _navigator.set(from, at, up);

    _navigator.setMotionFactor(0.5f);


#ifdef SHADOW_CHECK
    svp->setCamera(Pcamera);
#endif

    //activate Framecounter
    startFpsCounter();

//    dynamic_cast<RenderAction *>(mgr->getAction())->setLocalLights(true);
    mgr->turnHeadlightOff();

    mgr->showAll();

    mgr->getCamera()->setNear(      1.0f);
    mgr->getCamera()->setFar (1000000.f );

    _navigator.setViewport(gwin->getPort(0));

    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;
}
int main(int argc, char **argv)
{
    OSG::osgInit(argc,argv);
    OSG::PerfMonitor::the()->enable(true);   // Enable performance monitoring

    // GLUT init
    glutInit(&argc, argv);

    glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);

    glutInitWindowSize(500, 500);
    glutCreateWindow("PerfMonitor FG Test");

    glutReshapeFunc(reshape);
    glutDisplayFunc(display);
    glutIdleFunc(display);
    glutMouseFunc(mouse);
    glutMotionFunc(motion);
    glutKeyboardFunc(keyboard);

    pwin=OSG::PassiveWindow::create();
    pwin->init();

    // create the scene
    OSG::NodeUnrecPtr scene;

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

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

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

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

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

    // add the statistics forground

    perfmon_fg = OSG::PerfMonitorForeground::create();
    pwin->getPort(0)->addForeground(perfmon_fg);

    //statfg->setMaxSize(25);
    //statfg->setColor(Color4f(0,1,0,0.7));

    act = OSG::RenderAction::create();
    mgr->setAction(act);

    // GLUT main loop
    glutMainLoop();

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

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

    int winid = glutCreateWindow("OpenSG CGFX Shader");

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

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

    // init callbacks
    glutSetWindow(winid);
    glutReshapeFunc(reshape);
    glutDisplayFunc(display);
    glutIdleFunc(display);
    glutMouseFunc(mouse);
    glutMotionFunc(motion);
    glutKeyboardFunc(keyboard);

    const char *effectFile = "blinn_bump_reflect.vinstruct.cgfx";

    if(argc > 1)
    {
        effectFile = argv[1];
    }

    _cgfxmat = OSG::CgFXMaterial::create();

    _cgfxmat->setEffectFile(effectFile);

    // this multipass technique leads to a render bug, 
    // I have no idea what's wrong :-(
    //_cgfxmat->setTechnique(1);

    OSG::ChunkMaterialUnrecPtr mat2 = OSG::ChunkMaterial::create();
    OSG::MaterialChunkUnrecPtr matc = OSG::MaterialChunk::create();

    matc->setDiffuse(OSG::Color4f(1, 0, 0, 1));
    mat2->addChunk(matc);
    //mat2->addChunk(texc);

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

    OSG::GeometryUnrecPtr geo1 = OSG::makeLatLongSphereGeo(50, 50, 2.0f);
    
    OSG::calcVertexTangents(geo1, 
                            0, 
                            OSG::Geometry::TexCoords6Index, 
                            OSG::Geometry::TexCoords7Index);

    geo1->setMaterial(_cgfxmat);

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

    sphere1->setCore(geo1);

    OSG::TransformUnrecPtr trans1 = OSG::Transform::create();

    trans1->editMatrix().setTranslate(-2 , 0, 0);

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

    transn1->setCore(trans1);
    transn1->addChild(sphere1);

    //
    OSG::GeometryUnrecPtr geo2 = OSG::makeLatLongSphereGeo(50, 50, 1.0f);
    
    geo2->setMaterial(mat2);


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

    sphere2->setCore(geo2);

    OSG::TransformUnrecPtr trans2 = OSG::Transform::create();

    trans2->editMatrix().setTranslate(2 , 0, 0);


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

    transn2->setCore(trans2);
    transn2->addChild(sphere2);

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

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

    // 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.7, 0.7, 0.8), 0);
    gback->addLine(OSG::Color3f(0.0, 0.1, 0.3), 1);

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

    for(OSG::UInt32 i = 0; i < win->getMFPort()->size(); ++i)
    {
        OSG::Viewport *vp = win->getPort(i);

        vp->setBackground(gback);
    }

    return 0;
}
OSG::NodeTransitPtr setupAnim(void)
{
    OSG::NodeTransitPtr returnValue = OSG::Node::create();

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

    static const OSG::Real32 aOffsets[6][3] = 
    {
        { -5.5,  0.0,  0.0 },
        {  5.5,  0.0,  0.0 },
        {  0.0, -5.5,  0.0 },
        {  0.0,  5.5,  0.0 },
        {  0.0,  0.0, -5.5 },
        {  0.0,  0.0,  5.5 }
    };

    static const OSG::Real32 aDiffuse[6][3] =
    {
        { 1.f, 0.f, 0.f },
        { 0.f, 1.f, 0.f },
        { 0.f, 0.f, 1.f },
        { 1.f, 1.f, 0.f },
        { 1.f, 0.f, 1.f },
        { 0.f, 1.f, 1.f }
    };

    for(OSG::UInt32 i = 0; i < 6; ++i)
    {
        OSG::NodeUnrecPtr pTN                = OSG::Node::create();
        
        pAnimTrs[i] = OSG::ComponentTransform::create();
        
        OSG::GeometryUnrecPtr pGeo     = OSG::makeBoxGeo(1.f, 1.f, 1.f, 
                                                         2,   2,   2);
        OSG::NodeUnrecPtr     pGeoNode = OSG::Node::create();
        
        pGeoNode->setCore(pGeo);

        OSG::SimpleMaterialUnrecPtr pMat = OSG::SimpleMaterial::create();
        
        pMat->setDiffuse(OSG::Color3f(aDiffuse[i][0],
                                      aDiffuse[i][1],
                                      aDiffuse[i][2]));
        pMat->setAmbient(OSG::Color3f(aDiffuse[i][0],
                                      aDiffuse[i][1],
                                      aDiffuse[i][2]));

        pGeo->setMaterial(pMat);

        pAnimTrs[i]->editTranslation().setValues(aOffsets[i][0],
                                                 aOffsets[i][1],
                                                 aOffsets[i][2]);
        
        pTN->setCore (pAnimTrs[i]);
        pTN->addChild(pGeoNode   );
        
        returnValue->addChild(pTN);
    }


    return returnValue;
}
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)
{
    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;
}
// 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;
}
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;
}