예제 #1
0
//
// transform vector from world space to eye space
//
OSG::Vec3f transform_to_eye_space(const OSG::Vec3f& v, OSG::SimpleSceneManager* pSSM)
{
    if (!pSSM || !pSSM->getWindow() || pSSM->getWindow()->getMFPort()->size() == 0)
        return v;

    OSG::Viewport* pPort = mgr->getWindow()->getPort(0);

    OSG::Vec3f v_es;

    OSG::Matrix view;
    OSG::Int16 width  = pPort->calcPixelWidth();
    OSG::Int16 height = pPort->calcPixelHeight();

    pPort->getCamera()->getViewing(view, width, height);

    view.multFull( v, v_es);

    return v_es;
}
// 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;
}
// react to keys
void keyboard(unsigned char k, int x, int y)
{
    static OSG::Real32 season = 0.0f; 
    switch(k)
    {
        case 27:
        case 'q':
            
            _mgr    = NULL;
            _scene  = NULL; 
            _shl    = NULL;
            _shl_vp = NULL;
            _shl_fp = NULL;

            OSG::osgExit();
            exit(1);
        break;

        case 'c':
            _mgr->getWindow()->getShaderCache()->dump();
            break;

        case 'w':
            OSG::SceneFileHandler::the()->write(_scene, "scene.osb.gz", true);
            printf("wrote scene.osb.gz\n");
        break;
        case 's':
            if(season < 0.435)
                season += 0.01f;

            _shl_vp->updateUniformVariable("season", season);

        break;
        case 'S':
            if(season > -0.435)
                season -= 0.01f;

            _shl_vp->updateUniformVariable("season", season);
        break;
        case 'd':
            _animation = 1 - _animation;
        break;

        case 'b':
            if(!_shl_fp->readProgram("Earth.fp"))
                fprintf(stderr, "Couldn't read fragment program 'Earth.fp'\n");
            else
                fprintf(stderr, "blue loaded\n");
            break;
        case 'r':
            if(!_shl_fp->readProgram("Earth_red.fp"))
                fprintf(stderr, "Couldn't read fragment program 'Earth.fp'\n");
            else
                fprintf(stderr, "red loaded\n");
            break;

        case 'B':
            _shl_fp = OSG::ShaderProgram::create();

            _shl_fp->setShaderType(GL_FRAGMENT_SHADER);

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

            if(!_shl_fp->readProgram("Earth.fp"))
            {
                fprintf(stderr, "Couldn't read fragment program 'Earth.fp'\n");
            }
            else
            {
                _shl->subFragmentShader(0);
                _shl->addFragmentShader(_shl_fp);
                fprintf(stderr, "blue loaded\n");
            }
            break;

        case 'R':
            _shl_fp = OSG::ShaderProgram::create();

            _shl_fp->setShaderType(GL_FRAGMENT_SHADER);

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

            if(!_shl_fp->readProgram("Earth_red.fp"))
            {
                fprintf(stderr, "Couldn't read fragment program 'Earth.fp'\n");
            }
            else
            {
                _shl->subFragmentShader(0);
                _shl->addFragmentShader(_shl_fp);
                fprintf(stderr, "red loaded\n");
            }
            break;

        case 'A':
            _shl_vp->subUniformVariable("season");
            //OSGSceneFileType::the().writeContainer(_shl, "/tmp/rem.osg");
            break;
        case 'a':
            _shl_vp->addUniformVariable("season", season);
            //OSGSceneFileType::the().writeContainer(_shl, "/tmp/add.osg");
            break;
            
    }

    glutPostRedisplay();
}
// 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)
{
    g_error = 0.01f;

    if ( argc > 1 && !strcmp(argv[1], "-f"))
    {
        std::cerr << "Using forceTesselate()." << std::endl;
        useForceTesselate = true;
        ++argv, --argc;
    }
    
    if ( argc == 2 )
    {
        g_error = atof( argv[1] );
    }
    if ( g_error < 0.001 )
    {
        g_error = 0.001f;
    }
    
    OSG::osgInit(argc,argv);
    // GLUT init
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);

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

    {
        OSG::GLUTWindowRefPtr gwin = OSG::GLUTWindow::create();
        gwin->setGlutId(winid);
        gwin->init();
    
        // create the scene
        OSG::NodeRefPtr scene;
        scene = makeScene( );
        
        if ( scene == NULL )
        {
            std::cerr<<"makeScene returned NullFC, exiting..."<<std::endl;
            return -1;
        }
    
        // create the SimpleSceneManager helper
        mgr = OSG::SimpleSceneManager::create();
    
        // create the window and initial camera/viewport
        mgr->setWindow( gwin );
        // tell the manager what to manage
        mgr->setRoot  ( scene );
        
        // show the whole scene
        mgr->showAll();
        mgr->redraw();
        OSG::SolidBackgroundRefPtr bgr = OSG::SolidBackground::create();
        bgr->setColor( OSG::Color3f( 0.7f, 0.7f, 0.7f ));
        mgr->getWindow()->getPort(0)->setBackground( bgr );
    }
    
    // GLUT main loop
    glutMainLoop();

    return 0;
}