// react to keys
void keyboard(unsigned char k, int, int)
{
    switch(k)
    {
        case 27:    
        {
#ifdef OSG_WITH_NVPERFSDK
            NVPMShutdown();
#endif
            mgr      = NULL;

            tact     = NULL;
            debugact = NULL;
            
            scene    = NULL;
            mainwin  = NULL;
            debugwin = NULL;
            statfg   = NULL;

            OSG::osgExit();
            exit(0);
        }
        
#ifdef OSG_OLD_RENDER_ACTION
        case 'v':
        {
            mgr->getAction()->setVolumeDrawing(
                                    !mgr->getAction()->getVolumeDrawing());
		    std::cerr << "Volume Drawing: " 
                      << (mgr->getAction()->getVolumeDrawing()?"on":"off") 
                      << std::endl;
        }
        
        case 'z':
        {
            OSG::RenderAction *ract = 
                dynamic_cast<OSG::RenderAction *>(mgr->getAction());

            ract->setZWriteTrans(!ract->getZWriteTrans());

		    std::cerr << "Switch TransZWrite to " 
                      << (ract->getZWriteTrans()?"on":"off") 
                      << std::endl;
             
        }
        break;
#endif

        case 'r':
        {
            initElements();
            bool buseTrav = mgr->getUseTraversalAction();
            buseTrav = !buseTrav;
            mgr->setUseTraversalAction(buseTrav);
         }
         break;

#ifdef OSG_OLD_RENDER_ACTION
        case 'n':
            fprintf(stderr, "1) set s sorting to %d\n", act->getStateSorting());
            act->setStateSorting(!act->getStateSorting());
            fprintf(stderr, "2) set s sorting to %d\n", act->getStateSorting());
            break;
#endif

        case 'k':
            tact->setKeyGen(0);
            break;

        case 's':
        {
            OSG::UInt32 uiSId = OSG::SimpleSHLChunk  ::getStaticClassId() & 0x000003FF;
            OSG::UInt32 uiTId = OSG::TextureBaseChunk::getStaticClassId() & 0x000003FF;
            OSG::UInt32 uiMId = OSG::MaterialChunk   ::getStaticClassId() & 0x000003FF;
            
  
            OSG::UInt32 uiKeyGen = (uiSId) | (uiTId << 10) | (uiMId << 20);

            tact->setKeyGen(uiKeyGen);
        }
        break;

        case 'g':
            bGLFinish = !bGLFinish;
            tact->setUseGLFinish(bGLFinish);
#ifdef OSG_OLD_RENDER_ACTION
            act->setUseGLFinish(bGLFinish);
#endif
            break;


        case 'C':
        {
            OSG::Real32 cov = tact->getOcclusionCullingCoveredThreshold();
            cov+=0.1f;
            tact->setOcclusionCullingCoveredThreshold(cov);
            std::cout << "Covered Threshold now: " << cov << std::endl;
        }
        break;
            
        case 'c':
        {
            OSG::Real32 cov1 = tact->getOcclusionCullingCoveredThreshold();
            cov1-=0.1f;
            tact->setOcclusionCullingCoveredThreshold(cov1);
            std::cout << "Covered Threshold now: " << cov1 << std::endl;
        }
            break;

        case 'M':
        {
            OSG::UInt32 minFSize = tact->getOcclusionCullingMinimumFeatureSize();
            minFSize+=1;
            tact->setOcclusionCullingMinimumFeatureSize(minFSize);
            std::cout << "Minimum Feature Size now: " << minFSize << std::endl;
        }
        break;
            
        case 'm':
        {
            OSG::UInt32 small1 = tact->getOcclusionCullingMinimumFeatureSize();
            small1-=1;
            tact->setOcclusionCullingMinimumFeatureSize(small1);
            std::cout << "Minimum Feature Size now: " << small1 << std::endl;
        }
        break;
        
        case 'I':
        {
            OSG::UInt32 visT = tact->getOcclusionCullingVisibilityThreshold();
            visT+=1;
            tact->setOcclusionCullingVisibilityThreshold(visT);
            std::cout << "Visibility Threshold now: " << visT << std::endl;
        }
        break;

        case 'i':
        {
            OSG::UInt32 visTa = tact->getOcclusionCullingVisibilityThreshold();
            visTa-=1;
            tact->setOcclusionCullingVisibilityThreshold(visTa);
            std::cout << "Visibility Threshold now: " << visTa << std::endl;
        }
        break;

        case 'l':
        {
            OSG::UInt32 numLev = tact->getScreenLODNumLevels();
            numLev-=1;
            tact->setScreenLODNumLevels(numLev);
            std::cout << "LOD's in use now: " << numLev << std::endl;
        }
        break;

        case 'L':
        {
            OSG::UInt32 numLeva = tact->getScreenLODNumLevels();
            numLeva+=1;
            tact->setScreenLODNumLevels(numLeva);
            std::cout << "LOD's in use now: " << numLeva << std::endl;
        }
        break;

        case 'B':
        {
            OSG::UInt32 bfsz = tact->getOcclusionCullingQueryBufferSize();
            bfsz+=200;
            tact->setOcclusionCullingQueryBufferSize(bfsz);
            std::cout << "Query Buffer Size now: " << bfsz << std::endl;
        }
        break;

        case 'b':
        {
            OSG::UInt32 bfsza = tact->getOcclusionCullingQueryBufferSize();
            bfsza-=200;
            tact->setOcclusionCullingQueryBufferSize(bfsza);
            std::cout << "Query Buffer Size now: " << bfsza << std::endl;
        }
        break;

        case 't':
        {
            OSG::UInt32 tcount = tact->getOcclusionCullingMinimumTriangleCount();
            tcount-=50;
            tact->setOcclusionCullingMinimumTriangleCount(tcount);
            std::cout << "Minimum Triangle Count now: " << tcount << std::endl;
        }
        break;

        case 'T':
        {
            OSG::UInt32 tcounta = tact->getOcclusionCullingMinimumTriangleCount();
            tcounta+=50;
            tact->setOcclusionCullingMinimumTriangleCount(tcounta);
            std::cout << "Minimum Triangle Count now: " << tcounta << std::endl;
        }
        break;

        case 'H':
        {
            OSG::UInt32 mfsa = 0;
            OSG::Real32 sfta = 0.0f;
            tact->setOcclusionCullingMinimumFeatureSize(mfsa);
            tact->setOcclusionCullingVisibilityThreshold(mfsa);
            tact->setScreenLODCoverageThreshold(sfta);
            std::cout << "High Resolution Mode" << std::endl;
        }
        break;

        case 'h':
        {
            OSG::UInt32 mfs = 1000;
            OSG::Real32 sft = 0.15f;
            tact->setOcclusionCullingMinimumFeatureSize(mfs);
            tact->setOcclusionCullingVisibilityThreshold(mfs);
            tact->setScreenLODCoverageThreshold(sft);
            std::cout << "Low Resolution Mode" << std::endl;
        }
        break;

        case 'P':
        {
            OSG::Real32 cover = tact->getScreenLODCoverageThreshold();
            cover+=0.001f;
            tact->setScreenLODCoverageThreshold(cover);
            std::cout << "ScreenLOD Coverage Threshold now: " << cover << std::endl;
        }
        break;
            
        case 'p':
        {
            OSG::Real32 covera = tact->getScreenLODCoverageThreshold();
            covera-=0.001f;
            tact->setScreenLODCoverageThreshold(covera);
            std::cout << "ScreenLOD Coverage Threshold now: " << covera << std::endl;
        }
        break;

        case 'D':
        {
            OSG::Real32 user_dega = tact->getScreenLODDegradationFactor();
            user_dega+=0.01f;
            tact->setScreenLODDegradationFactor(user_dega);
            std::cout << "ScreenLOD User Degradation Factor now: " << user_dega << std::endl;
        }
        break;

        case 'd':
        {
            OSG::Real32 user_deg = tact->getScreenLODDegradationFactor();
            user_deg-=0.01f;
            tact->setScreenLODDegradationFactor(user_deg);
            std::cout << "ScreenLOD User Degradation Factor now: " << user_deg << std::endl;
        }
        break;
        
        case 'N':
        {
            OSG::Real32 coverb = tact->getScreenLODCoverageThreshold();
            coverb=0.0;
            tact->setScreenLODCoverageThreshold(coverb);
            std::cout << "ScreenLOD Coverage Threshold now: " << coverb << std::endl;
        }
        break;

        case 'o':
        {
            tact->setOcclusionCulling(false);
            std::cout << "OCC Off" << std::endl;
        }
        break;

        case 'O':
        {
            tact->setOcclusionCulling(true);
            std::cout << "OCC On" << std::endl;
        }
        break;

        case 'f':
        {
            std::cout << "Freeze Occlusion result" << std::endl;
            
            //initElements();
            mgr->setUseTraversalAction(false);
            
            // Render stuff that is visible and tested
            mgr->getWindow()->getPort(0)->setTravMask(0x5);
        }
        break;
        
        case 'F':
        {
            std::cout << "Unfreeze Occlusion result" << std::endl;
            
            //initElements();
            mgr->setUseTraversalAction(true);
            
            mgr->getWindow()->getPort(0)->setTravMask(0xffffffff);
        }
        break;

        case 'W':
        {
            std::string sss = "out.osb";
            OSG::SceneFileHandler::the()->write(scene, sss.c_str());
        }
        break;

#ifdef OSG_WITH_NVPERFSDK
        case 'e':
            runExperiment = true;
            break;
#endif
    }

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

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

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

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

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

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

    OSG::commitChanges();

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

    mgr->setUseTraversalAction(true);

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


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

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

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

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

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

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

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

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

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

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

#ifdef OSG_WITH_NVPERFSDK
    NVPMRESULT status;

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

    return 0;
}
void key(unsigned char key, int x, int y)
{
    switch ( key )
    {
        case 27:    
            win         = NULL;
            cam_trans   = NULL;
            pPoly       = NULL;
            pCOver      = NULL;
            pAlgo       = NULL;

            rentravact  = NULL;

            OSG::osgExit(); 

            exit(0);

        case 'v':
            rentravact->setVolumeDrawing(!rentravact->getVolumeDrawing());
            break;

        case 'z':   
            pPoly->setFrontMode(GL_POINT);
            pPoly->setBackMode(GL_POINT);
            std::cerr << "PolygonMode: Point." << std::endl;
            break;

        case 'x':   
            pPoly->setFrontMode(GL_LINE);
            pPoly->setBackMode(GL_LINE);
            std::cerr << "PolygonMode: Line." << std::endl;
            break;

        case 'c':   
            pPoly->setFrontMode(GL_FILL);
            pPoly->setBackMode(GL_FILL);
            std::cerr << "PolygonMode: Fill." << std::endl;
            break;

        case 'p':
        {
            if(bPolyActive == true)
            {
                OSG_ASSERT(pCOver->subChunk(pPoly) == true);
                bPolyActive = false;
            }
            else
            {
                OSG_ASSERT(pCOver->addChunk(pPoly) == true);
                bPolyActive = true;
            }
            break;
        }

		case 'w':
			pAlgo->setStepsize(pAlgo->getStepsize() + (1.0/2048.0));

			if(pAlgo->getStepsize() > 0.25) 
                pAlgo->setStepsize(0.25);

			break;

		case 'e':
			pAlgo->setStepsize(pAlgo->getStepsize() - (1.0/2048.0));
            
			if(pAlgo->getStepsize() <= 1.0/200.0) 
                pAlgo->setStepsize(1.0/200.0);
			break;

        case 'd':
            pAlgo->setToggleVisuals(!pAlgo->getToggleVisuals());
            break;
            
        default:
            break;
    }
}
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;
}
void key(unsigned char key, int x, int y)
{
    switch ( key )
    {
        case 27:    

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

            rentravact = NULL;

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

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

            cam_trans   = NULL;
            scene_trans = NULL;

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

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

        case 'd':
            OSG::ActionDataSlotPool::the()->dumpState();
            OSG::StageIdPool       ::the()->dumpState();
            rentravact->dumpStore();
            break;
        case ' ':
        {
            OSG::Matrix     m;
            OSG::Quaternion q;
            OSG::Vec3f      v;

            q = oldq;
            v = oldv;

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

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

            }
            else
            {
                puts("moving camera");
                tball.setMode( OSG::Trackball::OSGObject );
            }
            
            tball.setStartPosition( v, true );
            tball.setStartRotation( q, true );
        }
        break;
    }
}
Exemple #6
0
void key(unsigned char key, int x, int y)
{
    switch ( key )
    {
        case 27:    

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

            rentravact = NULL;

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

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

            cam_trans   = NULL;
            scene_trans = NULL;

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

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

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

            q = oldq;
            v = oldv;

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

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

            }
            else
            {
                puts("moving camera");
                tball.setMode( OSG::Trackball::OSGObject );
            }
            
            tball.setStartPosition( v, true );
            tball.setStartRotation( q, true );
        }
        break;

        case '1':
        {
            OSG::HDR2Stage* pHDR = dynamic_cast<OSG::HDR2Stage*>(hdrroot->getCore());
            if (pHDR) pHDR->setTarget(OSG::HDR2Stage::SCENE_TEXTURE);
        }
        break;
        case '2':
        {
            OSG::HDR2Stage* pHDR = dynamic_cast<OSG::HDR2Stage*>(hdrroot->getCore());
            if (pHDR) pHDR->setTarget(OSG::HDR2Stage::LUMINANCE_TEXTURE);
        }
        break;
        case '3':
        {
            OSG::HDR2Stage* pHDR = dynamic_cast<OSG::HDR2Stage*>(hdrroot->getCore());
            if (pHDR) pHDR->setTarget(OSG::HDR2Stage::ADAPTED_LUMINANCE_TEXTURE);
        }
        break;
        case '4':
        {
            OSG::HDR2Stage* pHDR = dynamic_cast<OSG::HDR2Stage*>(hdrroot->getCore());
            if (pHDR) pHDR->setTarget(OSG::HDR2Stage::THRESHOLD_TEXTURE);
        }
        break;
        case '5':
        {
            OSG::HDR2Stage* pHDR = dynamic_cast<OSG::HDR2Stage*>(hdrroot->getCore());
            if (pHDR) pHDR->setTarget(OSG::HDR2Stage::BLURRED_TEXTURE);
        }
        break;
        case '6':
        {
            OSG::HDR2Stage* pHDR = dynamic_cast<OSG::HDR2Stage*>(hdrroot->getCore());
            if (pHDR) pHDR->setTarget(OSG::HDR2Stage::COMPOSITE_TEXTURE);
        }
        break;
        case '7':
        {
            OSG::HDR2Stage* pHDR = dynamic_cast<OSG::HDR2Stage*>(hdrroot->getCore());
            if (pHDR) pHDR->setTarget(OSG::HDR2Stage::EXPOSURE_TEXTURE);
        }
        break;

    }
}
int doMain(int argc,char **argv)
{
    int                      i;
    char                    *opt;
    std::vector<std::string> filenames;
    std::vector<std::string> servers;
    std::string              connectionType = "StreamSock";
    std::string              connectionParameters;
    int                      rows=1;
    int                      cols=-1;
    char                     type='M';
    bool                     clientRendering=true;
    bool                     compose=false;

    std::string              composerType="";
    std::string              autostart;
    
    for(i=1;i<argc;i++)
    {
        if(strlen(argv[i])>1 && argv[i][0]=='-')
        {
            switch(argv[i][1])
            {
                case 'o':
                    opt = argv[i][2] ? argv[i]+2 : argv[++i];
                    connectionParameters = opt;
                    printf("connectionParameters: '%s'\n", connectionParameters.c_str());
                    break;
                case 'A':
                    opt = argv[i][2] ? argv[i]+2 : argv[++i];
                    autostart = opt;
                    break;
                case 'D':
                    opt = argv[i][2] ? argv[i]+2 : argv[++i];
                    if(sscanf(opt,"%f,%f,%f",&ca,&cb,&cc)!=3)
                    {
                        std::cout << "Copy opton -D x,y,z" << std::endl;
                        return 1;
                    }
                    break;
                case 'b':
                    opt = argv[i][2] ? argv[i]+2 : argv[++i];
                    serviceInterface.assign(opt);
                    serviceInterfaceValid = true;
                    break;
                case 'B':
                    opt = argv[i][2] ? argv[i]+2 : argv[++i];
                    serviceAddress.assign(opt);
                    serviceAddressValid = true;
                    break;
                case 'f':
                    opt = argv[i][2] ? argv[i]+2 : argv[++i];
                    filenames.push_back(opt);
                    printf("<%s>\n",opt);
                    break;
                case 'm':
                    connectionType="Multicast";
                    break;
                case 'r':
                    opt = argv[i][2] ? argv[i]+2 : argv[++i];
                    if(sscanf(opt,"%d,%d",&rows,&cols) != 2)
                        sscanf(opt,"%d",&rows);
                    break;
                case 't':
                    opt = argv[i][2] ? argv[i]+2 : argv[++i];
                    subtilesize=atoi(opt);
                    break;
#ifdef FRAMEINTERLEAVE
                case 'i':
                    opt = argv[i][2] ? argv[i]+2 : argv[++i];
                    interleave=atoi(opt);
                    break;
#endif
                case 'C':
                    compose=true;
                    break;
                case 'F':
                    type='F';
                    break;
                case 'X':
                    type='X';
                    break;
                case 'P':
                    type='P';
                    break;
                case 'L':
                {
                    type='L';
                    int lpos=2;
                    while(argv[i][lpos])
                    {
                        if(argv[i][lpos] == 'B') 
                            composerType = "BinarySwapComposer";
                        if(argv[i][lpos] == 'P')
                            composerType = "PipelineComposer";
                        if(argv[i][lpos] == 'S')
                            composerType = "SepiaComposer";
                        if(argv[i][lpos] == 'p')
                            pipelinedBufferRead = true;
                        ++lpos;
                    }
                    break;
                }
                case 'M':
                    type='M';
                    break;
                case 'I':
                    type='I';
                    break;
                case 's':
                    stereoMode=1;
                    break;
                case 'c':
                    stereoMode=2;
                    break;
                case 'S':
                    info=true;
                    break;
                case 'e':
                    opt = argv[i][2] ? argv[i]+2 : argv[++i];
                    sscanf(opt,"%f",&eyedistance);
                    break;
                case 'z':
                    opt = argv[i][2] ? argv[i]+2 : argv[++i];
                    sscanf(opt,"%f",&zeroparallax);
                    break;
                case 'd':
                    clientRendering=false;
                    break;
                case 'v':
                    multiport=true;
                    break;
                case 'x':
                    opt = argv[i][2] ? argv[i]+2 : argv[++i];
                    sscanf(opt,"%d",&serverx);
                    break;
                case 'y':
                    opt = argv[i][2] ? argv[i]+2 : argv[++i];
                    sscanf(opt,"%d",&servery);
                    break;
                case 'a':
                    opt = argv[i][2] ? argv[i]+2 : argv[++i];
                    animName=opt;
                    loadAnim();
                    animate=true;
                    break;
                case 'l':
                    opt = argv[i][2] ? argv[i]+2 : argv[++i];
                    if(sscanf(opt,"%d,%d",&animLoops,&animLength) != 2)
                    {
                        animLength = 30;
                        if(sscanf(opt,"%d",&animLoops) != 1)
                        {
                            animLoops = -1;
                        }
                    }
                    break;
                case 'g':
                    opt = argv[i][2] ? argv[i]+2 : argv[++i];
                    if(sscanf(opt,"%d,%d,%d,%d",
                              &winwidth,&winheight,&winx,&winy) != 4)
                        sscanf(opt,"%d,%d",&winwidth,&winheight);
                    break;
                case 'G':
                    opt = argv[i][2] ? argv[i]+2 : argv[++i];
                    connectionDestination = opt;
                    break;
                case 'i':
                    opt = argv[i][2] ? argv[i]+2 : argv[++i];
                    connectionInterface = opt;
                    break;
                default:
                    std::cout << argv[0] 
                              << "-ffile -m -rrows[,cols] -C -M"
                              << std::endl;
                    std::cout << "-m  use multicast" << std::endl
                              << "-G  multicast group" << std::endl
                              << "-i  interface" << std::endl
                              << "-b  service interface" << std::endl
                              << "-M  multi display" << std::endl
#ifdef FRAMEINTERLEAVE
                              << "-I  frame interleave" << std::endl
#endif
                              << "-r  number of display rows" << std::endl
                              << "-C  compose" << std::endl
                              << "-F  sort-first" << std::endl
                              << "-L  sort-last" << std::endl
                              << "-h  this msg" << std::endl
                              << "-s  stereo" << std::endl
                              << "-c  red/cyan stereo" << std::endl
                              << "-e  eye distance" << std::endl
                              << "-z  zero parallax" << std::endl
                              << "-d  disable client rendering"<<std::endl
                              << "-v  use two viewports" << std::endl
                              << "-x  server x resolution" << std::endl
                              << "-y  server y resolution" << std::endl
                              << "-t  subtile size for img composition" << std::endl
                              << "-D  x,y,z duplicate geometry" << std::endl
                              << "-A  Autostart command" << std::endl
                              << "-o  connection parameter string e.g. \"TTL=8\"" << std::endl;
                    return 0;
            }
        }
        else
        {
            servers.push_back(argv[i]);
        }
    }

    OSG::ChangeList::setReadWriteDefault(true);
    OSG::osgInit(argc, argv);
    glutInit(&argc, argv);
    glutInitDisplayMode( GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE );
    if(winx >=0 && winy >=0)
        glutInitWindowPosition(winx,winy);
    glutInitWindowSize(winwidth,winheight);
    winid = glutCreateWindow("OpenSG Cluster Client");
    glutKeyboardFunc(key);
    glutReshapeFunc(reshape);
    glutDisplayFunc(display);     
    if(animate)
        glutIdleFunc(display);       
    glutMouseFunc(mouse);   
    glutMotionFunc(motion); 
    ract = OSG::RenderAction::create();
#ifdef OSG_OLD_RENDER_ACTION
    ract->setSortTrans(true);
    ract->setZWriteTrans(true);
    ract->setLocalLights(true);
    ract->setCorrectTwoSidedLighting(true);
#endif

    // clear changelist from prototypes
    OSG::Thread::getCurrentChangeList()->clear();
    
    // create cluster window
    switch(type)
    {
        case 'M': 
            multidisplay=OSG::MultiDisplayWindow::create();
            clusterWindow=multidisplay;
            break;
        case 'X': 
            balancedmultidisplay=OSG::BalancedMultiWindow::create();
            clusterWindow=balancedmultidisplay;
            break;
        case 'F':
            sortfirst=OSG::SortFirstWindow::create();
            if(compose)
                sortfirst->setCompose(true);
            else
                sortfirst->setCompose(false);
            clusterWindow=sortfirst;
            break;
        case 'L':
            sortlast=OSG::SortLastWindow::create();
            if(!composerType.empty())
            {
                OSG::FieldContainerUnrecPtr fcPtr = 
                    OSG::FieldContainerFactory::the()->
                    createContainer(composerType.c_str());
                OSG::ImageComposer *icPtr = 
                    dynamic_cast<OSG::ImageComposer *>(fcPtr.get());
                
                if(icPtr != NULL)
                {
                    if(dynamic_cast<OSG::PipelineComposer *>(icPtr) != NULL)
                    {
                        if(subtilesize>0)
                            dynamic_cast<OSG::PipelineComposer *>(icPtr)->setTileSize(subtilesize);
                        dynamic_cast<OSG::PipelineComposer *>(icPtr)->setPipelined(pipelinedBufferRead);
                    }
                    if(dynamic_cast<OSG::BinarySwapComposer *>(icPtr) != NULL)
                    {
                        if(subtilesize>0)
                            dynamic_cast<OSG::BinarySwapComposer *>(icPtr)->setTileSize(subtilesize);
                    }
                    icPtr->setStatistics(info);
//                        icPtr->setShort(false);
                    sortlast->setComposer(icPtr);
                }
            }
            clusterWindow=sortlast;
            break;
#ifdef FRAMEINTERLEAVE
        case 'I':
            frameinterleave=OSG::FrameInterleaveWindow::create();
            clusterWindow=frameinterleave;
            if(compose)
                frameinterleave->setCompose(true);
            else
                frameinterleave->setCompose(false);
            break;
#endif
        case 'P':
            sortfirst=OSG::SortFirstWindow::create();
            sortfirst->setCompose(false);
            clusterWindow=sortfirst;
            break;
    }
    
    if(!autostart.empty())
        clusterWindow->editMFAutostart()->push_back(autostart);
    
    for(i=0 ; i<int(servers.size()) ; ++i)
        clusterWindow->editMFServers()->push_back(servers[i]);
    if(cols < 0)
        cols = clusterWindow->getMFServers()->size32() / rows;
    switch(type)
    {
        case 'M': 
            multidisplay->setHServers(cols);
            multidisplay->setVServers(rows);
            break;
        case 'X': 
            balancedmultidisplay->setHServers(cols);
            balancedmultidisplay->setVServers(rows);
//                    balancedmultidisplay->setShowBalancing(true);
//            balancedmultidisplay->setShowBalancing(info);
            break;
    }
#ifdef FRAMEINTERLEAVE
    clusterWindow->setInterleave(interleave);
#endif
        
    // create client window
    clientWindow=OSG::GLUTWindow::create();
//        glutReshapeWindow(800,600);
    glutReshapeWindow(winwidth,winheight);
    clientWindow->setGlutId(winid);
    clientWindow->init();
    
    // init scene graph
    init(filenames);
    
    // init client
    clusterWindow->setConnectionType(connectionType);
    // needs to be called before init()!
    clusterWindow->setConnectionParams(connectionParameters);
    if(clientRendering)
    {
        clusterWindow->setClientWindow(clientWindow);
    }
    clusterWindow->setConnectionDestination(connectionDestination);
    clusterWindow->setConnectionInterface(connectionInterface);
    clusterWindow->init();
    if(serverx > 0)
        clusterWindow->resize(serverx,servery);
    else
        clusterWindow->resize(winwidth,winheight);
    clientWindow->resize(winwidth,winheight);

//    OSG::FieldContainerFactory::the()->dump();

    OSG::commitChanges();

    glutMainLoop();

    return 0;
}