DeferredShadingStage::DSStageDataTransitPtr
    DeferredShadingStage::createStageData(void)
{
    DSStageDataTransitPtr              data              =
        DSStageData::createLocal();
    FrameBufferObjectUnrecPtr          gBufferTarget     =
        FrameBufferObject::createLocal();
    RenderBufferUnrecPtr               gBufferDepth      =
        RenderBuffer::createLocal();
    SolidBackgroundUnrecPtr            gBufferBackground =
        SolidBackground::createLocal();
    BlendChunkUnrecPtr                 shadingBlendChunk =
        BlendChunk::createLocal();

    gBufferDepth     ->setInternalFormat (GL_DEPTH_COMPONENT24);
    gBufferTarget    ->setDepthAttachment(gBufferDepth        );

    gBufferBackground->setColor(Color3f(0.0f, 0.0f, 0.0f));

    shadingBlendChunk->setSrcFactor (GL_ONE);
    shadingBlendChunk->setDestFactor(GL_ONE);

    data->setGBufferTarget    (gBufferTarget    );
    data->setGBufferBackground(gBufferBackground);

    data->setBlendChunk       (shadingBlendChunk);

    return data;
}
DepthPeelingStageDataTransitPtr
    DepthPeelingStage::setupStageData(Int32 iPixelWidth,
                                      Int32 iPixelHeight)
{
    DepthPeelingStageDataTransitPtr returnValue =
        DepthPeelingStageData::createLocal();

    if(returnValue == NULL)
        return returnValue;

    OSG::Thread::setCurrentLocalFlags();

    //Depth, Blend chunks and Background in Data?
    DepthChunkUnrecPtr pDepthOffChunk = DepthChunk::createLocal();
    pDepthOffChunk->setEnable(false);

    DepthChunkUnrecPtr pDepthOnChunk = DepthChunk::createLocal();
    pDepthOnChunk->setEnable(true);

    returnValue->setDepthChunk(pDepthOnChunk);

    ShaderProgramVariableChunkUnrecPtr pSPVChunk1 =
        ShaderProgramVariableChunk::createLocal();
    pSPVChunk1->addUniformVariable("uIsPeelPass", true);

    returnValue->setSpvIsPeelChunk(pSPVChunk1);

    ShaderProgramVariableChunkUnrecPtr pSPVChunk2 =
        ShaderProgramVariableChunk::createLocal();
    pSPVChunk2->addUniformVariable("uIsPeelPass", false);

    returnValue->setSpvIsInitialChunk(pSPVChunk2);

    BlendChunkUnrecPtr pBlendChunk = BlendChunk::createLocal();
    pBlendChunk->setSrcFactor(GL_DST_ALPHA);
    pBlendChunk->setDestFactor(GL_ONE);
    pBlendChunk->setAlphaSrcFactor(GL_ZERO);
    pBlendChunk->setAlphaDestFactor(GL_ONE_MINUS_SRC_ALPHA);
    pBlendChunk->setEquation(GL_FUNC_ADD);

    SolidBackgroundUnrecPtr pSolidBackground = SolidBackground::createLocal();
    pSolidBackground->setColor(Color3f(0.f, 0.f, 0.f));
    pSolidBackground->setAlpha(0.f);
    returnValue->setBackground(pSolidBackground);

    SimpleSHLChunkUnrecPtr pQuadShader = SimpleSHLChunk::createLocal();
    pQuadShader->setFragmentProgram(std::string(blendFS));
    pQuadShader->addUniformVariable("uSampler", 0);

    //2 FBOs (Ping-Pong)
    FrameBufferObjectUnrecPtr pPeelFBOs[2];
    TextureBufferUnrecPtr pPeelColorTexBuffers[2];
    TextureBufferUnrecPtr pPeelDepthTexBuffers[2];

    TextureObjChunkUnrecPtr pColorTexs[2];
    ImageUnrecPtr           pColorImgs[2];

    TextureObjChunkUnrecPtr pDepthTexs[2];
    ImageUnrecPtr           pDepthImgs[2];

    for (int i=0; i<2; ++i)
    {
        //Color textures
        pColorTexs[i]     = TextureObjChunk::createLocal();
        pColorImgs[i]     = Image          ::createLocal();

        pColorImgs[i]->set(Image::OSG_RGBA_PF,
                  iPixelWidth,
                  iPixelHeight,
                  1,
                  1,
                  1,
                  0.0,
                  0,
                  Image::OSG_FLOAT32_IMAGEDATA,
                  false);

        pColorTexs[i]   ->setImage         (pColorImgs[i]   );
        pColorTexs[i]   ->setMinFilter     (GL_NEAREST       );
        pColorTexs[i]   ->setMagFilter     (GL_NEAREST       );
        pColorTexs[i]   ->setWrapS         (GL_CLAMP_TO_EDGE );
        pColorTexs[i]   ->setWrapT         (GL_CLAMP_TO_EDGE );
        pColorTexs[i]   ->setInternalFormat(GL_RGBA8);

        pPeelColorTexBuffers[i]   = TextureBuffer::createLocal();
        pPeelColorTexBuffers[i]->setTexture(pColorTexs[i]);

        //Depth textures
        pDepthTexs[i]      = TextureObjChunk::createLocal();
        pDepthImgs[i]      = Image          ::createLocal();

        pDepthImgs[i]->set(Image::OSG_DEPTH_PF,
                  iPixelWidth,
                  iPixelHeight,
                  1,
                  1,
                  1,
                  0.0,
                  0,
                  Image::OSG_FLOAT32_IMAGEDATA,
                  false);

        pDepthTexs[i]   ->setImage         (pDepthImgs[i]   );
        pDepthTexs[i]   ->setMinFilter     (GL_NEAREST       );
        pDepthTexs[i]   ->setMagFilter     (GL_NEAREST       );
        pDepthTexs[i]   ->setWrapS         (GL_CLAMP_TO_EDGE );
        pDepthTexs[i]   ->setWrapT         (GL_CLAMP_TO_EDGE );
        pDepthTexs[i]   ->setInternalFormat(GL_DEPTH_COMPONENT32F);
        pDepthTexs[i]   ->setExternalFormat(GL_DEPTH_COMPONENT);

        pPeelDepthTexBuffers[i] = TextureBuffer::createLocal();
        pPeelDepthTexBuffers[i]->setTexture(pDepthTexs[i]);

        pPeelFBOs[i] = FrameBufferObject::createLocal();

        pPeelFBOs[i]->setSize(iPixelWidth, iPixelHeight);
        pPeelFBOs[i]->setColorAttachment(pPeelColorTexBuffers[i], 0);
        pPeelFBOs[i]->setDepthAttachment(pPeelDepthTexBuffers[i]);
        pPeelFBOs[i]->editMFDrawBuffers()->push_back(GL_COLOR_ATTACHMENT0_EXT);

        //Peel material for Quad (!)
        ChunkMaterialUnrecPtr pPeelMat  = ChunkMaterial  ::createLocal();
        pPeelMat->addChunk(pQuadShader, 0);
        pPeelMat->addChunk(pColorTexs[i],     0);
        pPeelMat->addChunk(pDepthOffChunk);
        pPeelMat->addChunk(pBlendChunk);

        if (i == 0)
        {
            returnValue->setPeelPingFBO(pPeelFBOs[i]);
            returnValue->setPeelPingMaterial(pPeelMat);
        }
        else
        {
            returnValue->setPeelPongFBO(pPeelFBOs[i]);
            returnValue->setPeelPongMaterial(pPeelMat);
        }
    }

    // The final color blend target
    FrameBufferObjectUnrecPtr pBlendFBO      = FrameBufferObject::createLocal();

    //Color texture
    TextureObjChunkUnrecPtr   pBlendColorTex = TextureObjChunk::createLocal();
    ImageUnrecPtr             pBlendColorImg = Image          ::createLocal();

    pBlendColorImg->set(Image::OSG_RGBA_PF,
              iPixelWidth,
              iPixelHeight,
              1,
              1,
              1,
              0.0,
              0,
              Image::OSG_FLOAT32_IMAGEDATA,
              false);

    pBlendColorTex->setImage         (pBlendColorImg   );
    pBlendColorTex->setMinFilter     (GL_NEAREST       );
    pBlendColorTex->setMagFilter     (GL_NEAREST       );
    pBlendColorTex->setWrapS         (GL_CLAMP_TO_EDGE );
    pBlendColorTex->setWrapT         (GL_CLAMP_TO_EDGE );
    pBlendColorTex->setInternalFormat(GL_RGBA8);

    TextureBufferUnrecPtr pBlendColorTexBuffer   = TextureBuffer::createLocal();
    pBlendColorTexBuffer->setTexture(pBlendColorTex);

    TextureBufferUnrecPtr pBlendDepthTexBuffer   = TextureBuffer::createLocal();
    pBlendDepthTexBuffer->setTexture(pDepthTexs[0]);

    pBlendFBO->setSize(iPixelWidth, iPixelHeight);
    pBlendFBO->setColorAttachment(pBlendColorTexBuffer, 0);
    pBlendFBO->setDepthAttachment(pBlendDepthTexBuffer);

    pBlendFBO->editMFDrawBuffers()->push_back(GL_COLOR_ATTACHMENT0_EXT);

    returnValue->setBlendFBO(pBlendFBO);

    // Blend Final Material
    ChunkMaterialUnrecPtr pBlendFinalMat = ChunkMaterial::createLocal();

    pBlendFinalMat->addChunk(pDepthOffChunk);
    pBlendFinalMat->addChunk(pBlendColorTex,     0);

    SimpleSHLChunkUnrecPtr pBlendFinalShader = SimpleSHLChunk::createLocal();
    pBlendFinalShader->setFragmentProgram(std::string(blendFinalFS));
    pBlendFinalShader->addUniformVariable("uSampler", 0);

    pBlendFinalMat->addChunk(pBlendFinalShader, 0);
    returnValue->setBlendFinalMaterial(pBlendFinalMat);

    OSG::Thread::resetCurrentLocalFlags();

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

    return returnValue;
}
Ejemplo n.º 3
0
int main (int argc, char **argv)
{
    osgInit(argc,argv);
    
    // GLUT init

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

    glutInitWindowSize    (uiSize, uiSize);
    glutInitWindowPosition(100,100);


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

    // OSG

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

    // create the graph

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

    b1n->setCore( b1 );

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

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

    cam_trans = t1;

    // light
    
    NodeUnrecPtr             dlight = Node::create();
    DirectionalLightUnrecPtr dl     = 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              = Node:: create();
    GroupUnrecPtr gr1 = Group::create();

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

    // Load the file

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

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

        file = makeSphere(4, 20.0);
    }

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

    file->updateVolume();


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

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

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


                 ref_trans = Transform::create();
    NodeUnrecPtr refTrN    = Node::create();

    refTrN->setCore (ref_trans);
    refTrN->addChild(makeSphere(4, 20.0));



#ifdef OLD_BBQ
    AlgorithmStageUnrecPtr pAlgoStage = AlgorithmStage::create();

    pAlgoStage->setInheritedTarget(true);
    pAlgoStage->setProjectionMode(AlgorithmStage::Ignore);
    pAlgoStage->setCopyViewing(true);

    CallbackAlgorithmUnrecPtr pAlgo = CallbackAlgorithm::create();


    pAlgo->setCallback(&terrainRenderCB, "");

    pAlgoStage->setAlgorithm(pAlgo);
#endif

    pSource = BbqOutOfCoreDataSource::create();

//    pSource->setFilename("data/ps_com.bbq");
    pSource->setFilename("data/ps.bbq");
//    pSource->setFilename("/home/gerrit/mtmp/ps.bbq");

    pSource->setHeightScale  (6500.0f);
    pSource->setHeightOffset (0.0f  );
    pSource->setSampleSpacing(1.0f  );

    pTerrain = BbqTerrain::create();

    pTerrain->setBeacon    (sceneTrN);
    pTerrain->setDataSource(pSource );

    pTerrain->setScreenSpaceError(6.0);

    NodeUnrecPtr pAlgoNode = Node::create();

    pAlgoNode->setCore(pTerrain);

    dlight->addChild(pAlgoNode);

    dlight->addChild(sceneTrN);
    dlight->addChild(refTrN  );

    OSG::commitChanges();

    const BbqDataSourceInformation &tInfo = 
        pSource->getInformation();

    fprintf(stderr, "%d %d\n",
            tInfo.heightSampleCount[0],
            tInfo.heightSampleCount[1]);

    fprintf(stderr, "min %f %f\n",
            tInfo.vOrigin[0],
            tInfo.vOrigin[1]);

    fprintf(stderr, "max %f %f\n",
            tInfo.vOrigin[0] + 
                tInfo.heightSampleCount[0] * tInfo.vPixelSize[0],
            tInfo.vOrigin[1] + 
                tInfo.heightSampleCount[1] * tInfo.vPixelSize[1]);

    fprintf(stderr, "ts: %f\n", tInfo.sampleSpacing);


    fprintf(stderr, "info Bbox min %f %f\n", 
            tInfo.gridBBoxMin[0],
            tInfo.gridBBoxMin[1]);

    fprintf(stderr, "info Bbox max %f %f\n", 
            tInfo.gridBBoxMax[0],
            tInfo.gridBBoxMax[1]);

    fUnitScale  = tInfo.sampleSpacing / tInfo.vPixelSize[0];
    fUnitScale1 = tInfo.sampleSpacing / tInfo.vPixelSize[1];

    //(- 285.728333 - (170.f * fUnitScale)
    
    vUnitOffset[0] = tInfo.gridBBoxMin[0] - (tInfo.vOrigin[0] * fUnitScale);
    //m4c[3][2] = (-m4c[3][2] - 40.f) * fUnitScale - 285.728333; 

    vUnitOffset[1] = tInfo.gridBBoxMin[1] - (tInfo.vOrigin[1] * fUnitScale1);

#if 1
    NodeUnrecPtr geoRef = Node::create();
    
    geoRef->setCore(Group::create());

    NodeUnrecPtr           pEll     = Node::create();
    MaterialGroupUnrecPtr  pEllMatG = MaterialGroup::create();
    SimpleMaterialUnrecPtr pEllMat  = SimpleMaterial::create();

    pEllMat->editDiffuse().setValuesRGB(0.3, 0.3, 0.3);

    pEllMatG->setMaterial(pEllMat);

    pEll->setCore(pEllMatG);

    pEll->addChild(makeLatLongEllipsoid(18, 
                                        36, 
                                        6378.137 * 0.95,
                                        6356.7523142 * 0.95));
    

    geoRef->addChild(pEll);
    
    geoRef->addChild(makeEllipsoidAxis(18, 
                                       36, 
                                       6378.137 * 1.05,
                                       6356.7523142 * 1.05));




#if 0
    NodeUnrecPtr           pEllSeg     = Node::create();
    MaterialGroupUnrecPtr  pEllSegMatG = MaterialGroup::create();
    SimpleMaterialUnrecPtr pEllSegMat  = SimpleMaterial::create();

    pEllSegMat->editDiffuse().setValuesRGB(1.0, 0.0, 0.0);
    

    pEllSegMatG->setMaterial(pEllSegMat);

    pEllSeg->setCore(pEllSegMatG);

    pEllSeg->addChild(makeLatLongEllipsoidSeg(18, 
                                              36, 
                                              6378.137 * 1.01,
                                              6356.7523142 * 1.01,
                                              osgDegree2Rad(-50.f),
                                              osgDegree2Rad(165.f),
                                              osgDegree2Rad(-35.f),
                                              osgDegree2Rad(180.f)));

    geoRef->addChild(pEllSeg);
#endif


    NodeUnrecPtr pCorner0 = Node::create();
    NodeUnrecPtr pCorner1 = Node::create();
    NodeUnrecPtr pCorner2 = Node::create();
    NodeUnrecPtr pCorner3 = Node::create();

    TransformUnrecPtr pCornerTr0 = Transform::create();
    TransformUnrecPtr pCornerTr1 = Transform::create();
    TransformUnrecPtr pCornerTr2 = Transform::create();
    TransformUnrecPtr pCornerTr3 = Transform::create();

    pCorner0->setCore(pCornerTr0);
    pCorner1->setCore(pCornerTr1);
    pCorner2->setCore(pCornerTr2);
    pCorner3->setCore(pCornerTr3);

    pCorner0->addChild(makeLatLongSphere(10, 10, 100.f));
    pCorner1->addChild(makeLatLongSphere(10, 10, 100.f));
    pCorner2->addChild(makeLatLongSphere(10, 10, 100.f));
    pCorner3->addChild(makeLatLongSphere(10, 10, 100.f));

    Pnt3f trpos(0.f, 0.f, 0.f);

    projectPnt(trpos, -50.f, 165, 10);

    pCornerTr0->editMatrix()[3][0] = trpos[0];
    pCornerTr0->editMatrix()[3][1] = trpos[1];
    pCornerTr0->editMatrix()[3][2] = trpos[2];

    projectPnt(trpos, -35.f, 165, 10);

    pCornerTr1->editMatrix()[3][0] = trpos[0];
    pCornerTr1->editMatrix()[3][1] = trpos[1];
    pCornerTr1->editMatrix()[3][2] = trpos[2];

    projectPnt(trpos, -50.f, 180, 10);

    pCornerTr2->editMatrix()[3][0] = trpos[0];
    pCornerTr2->editMatrix()[3][1] = trpos[1];
    pCornerTr2->editMatrix()[3][2] = trpos[2];

    projectPnt(trpos, -35.f, 180, 10);

    pCornerTr3->editMatrix()[3][0] = trpos[0];
    pCornerTr3->editMatrix()[3][1] = trpos[1];
    pCornerTr3->editMatrix()[3][2] = trpos[2];

    geoRef->addChild(pCorner0);
    geoRef->addChild(pCorner1);
    geoRef->addChild(pCorner2);
    geoRef->addChild(pCorner3);

    dlight->addChild(geoRef);
#endif

    Pnt3f x1;
    Pnt3f x2;

    projectPnt(x1, 170.0,               40.0, 0);
    projectPnt(x2, 170.000833333333333, 40.0, 0);

    Vec3f v1 = x1 - x2;

    fprintf(stderr, "l:%f\n", v1.length());

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

    // Background
    SolidBackgroundUnrecPtr bkgnd = SolidBackground::create();
    {
        bkgnd->setColor(Color3f(0,0,1));
    }

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


    // Window
    GLUTWindowUnrecPtr gwin;

    GLint glvp[4];

    glGetIntegerv(GL_VIEWPORT, glvp);

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

        win->addPort( vp );

        win->init();
    }

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

    rentravact->setFrustumCulling(false);

#ifdef OLD_BBQ
    outOfCoreDataSource_ = new BbqOutOfCoreDataSource();

    bool rc = outOfCoreDataSource_->initialize( 
//        "data/ps.bbq", 
        "data/ps_com.bbq", 
        650.0f, 
        0.0f, 
        1.0f );

    fprintf(stderr, "ds::init %d\n", rc);

    const BbqDataSourceInformation &bbqInfo = 
        outOfCoreDataSource_->getInformation();
   

    fprintf(stderr, "%d %d\n",
            bbqInfo.levelCount,
            bbqInfo.nodeCount);

    fprintf(stderr, "%d %d %d\n",
            bbqInfo.heightTileSize,
            bbqInfo.heightSampleCount[0],
            bbqInfo.heightSampleCount[1]);

    fprintf(stderr, "%f %f %f\n",
            bbqInfo.heightScale,
            bbqInfo.heightOffset,
            bbqInfo.sampleSpacing);

    

    const int maxResidentNodeCount = 5000;

    terrain_ = new BbqTerrainEngine();

    rc = terrain_->initialize(outOfCoreDataSource_, maxResidentNodeCount);

    fprintf(stderr, "t::init %d\n", rc);

    terrainRenderOptions_.showSkirts           = false;
    terrainRenderOptions_.showSwitchDistance   = true;
#endif


    // tball
    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;

    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            (Trackball::OSGObject);
    tball.setStartPosition   (pos, true           );
    tball.setSum             (true                );
    tball.setTranslationMode (Trackball::OSGFree  );
    tball.setTranslationScale(scale * 400         );
    tball.setRotationCenter  (tCenter             );

    tScale = scale * 400;

    fprintf(stderr, "tscale %f\n", tScale);

//    pos.setValues(0, 400, 0);

    projectPnt(pos, -42.5, 172.5, 10);

    tCenter.setValues(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]);

    tcamball.setMode            (Trackball::OSGObject);
    tcamball.setStartPosition   (pos, true           );
    tcamball.setSum             (true                );
    tcamball.setTranslationMode (Trackball::OSGFree  );
    tcamball.setTranslationScale(100                 );
    tcamball.setRotationCenter  (tCenter             );

    m1c.setIdentity();

    m1c[3][1] = 5000;

    m4c.setIdentity();

    m4c[3][1] = 5000;


    pActiveTBall = &tball;

    commitChanges();

    // run...
    glutMainLoop();
    
    return 0;
}
Ejemplo n.º 4
0
int doMain(int argc, char **argv)
{
    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

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

    // create the graph

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

    b1n->setCore( b1 );

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

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

    cam_trans = t1;

    // light
    
    NodeUnrecPtr             dlight = Node::create();
    DirectionalLightUnrecPtr dl     = 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              = Node:: create();
    GroupUnrecPtr gr1 = Group::create();

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

    // Load the file

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

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

        NodeUnrecPtr geoRef = Node::create();
    
        geoRef->setCore(Group::create());

        NodeUnrecPtr           pEll     = Node::create();
        MaterialGroupUnrecPtr  pEllMatG = MaterialGroup::create();
        SimpleMaterialUnrecPtr pEllMat  = SimpleMaterial::create();

        pEllMat->editDiffuse().setValuesRGB(0.3, 0.3, 0.3);

        pEllMatG->setMaterial(pEllMat);

        pEll->setCore(pEllMatG);

        pEll->addChild(makeLatLongEllipsoid(18, 
                                            36, 
                                            6378137. * 0.95,
                                            6356752.3142 * 0.95));
    

        geoRef->addChild(pEll);
    
        geoRef->addChild(makeEllipsoidAxis(18, 
                                           36, 
                                           6378137. * 1.05,
                                           6356752.3142 * 1.05));

        file = geoRef; //makeSphere(4, 2.0);
#endif

        file = makeSphere(4, 2.0);
    }

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

    file->updateVolume();


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

/*
    min[0] = -500;
    min[1] = 0;
    min[2] = -500;

    max[0] = 500;
    max[1] = 100;
    max[2] = 500;
 */

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

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

    AlgorithmStageUnrecPtr pAlgoStage = AlgorithmStage::create();

    pAlgoStage->setInheritedTarget(true);
    pAlgoStage->setProjectionMode (AlgorithmStage::Ignore);
    pAlgoStage->setCopyViewing    (true);

    CallbackAlgorithmUnrecPtr pAlgo = CallbackAlgorithm::create();

    pAlgo->setCallback(&terrainRenderCB, "");

    pAlgoStage->setAlgorithm(pAlgo);

    NodeUnrecPtr pAlgoNode = Node::create();

    pAlgoNode->setCore(pAlgoStage);

    sceneTrN->addChild(pAlgoNode);

    dlight->addChild(sceneTrN);

    // Camera
    
    cam = PerspectiveCamera::create();
    {
        cam->setBeacon( b1n );
        cam->setFov( osgDegree2Rad( 90 ) );
        cam->setNear( 1000 );
        cam->setFar( 100000000 );
    }

    // Background
    SolidBackgroundUnrecPtr bkgnd = SolidBackground::create();
    {
        bkgnd->setColor(Color3f(0,0,1));
    }

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


    // Window
    GLUTWindowUnrecPtr gwin;

    GLint glvp[4];

    glGetIntegerv(GL_VIEWPORT, glvp);

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

        win->addPort( vp );

        win->init();
    }

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

    int cols = 1;
    int rows = 1;
    
    terrain = new miniload(); 

    terrain->configure_mipmaps(0);

    terrain->setloader(hw_request_callback,
                       NULL);

#if 1
    static const char *abasepath1 = 
        "/home/gerrit/SoftwareBuild/Hawaii/data/HawaiiTileset/tiles";
    static const char *abasepath2 =
        "/home/gerrit/SoftwareBuild/Hawaii/data/HawaiiTileset/landsat";

    static const float viewx = 0.f; //-560309.0f;
    static const float viewy = 0.f; //72234.0f;

    // vertical exaggeration
    static const float exaggeration=1.5f; // exaggeration=150%

    float tscale = 1.f; //00.0f; // 1:100

    // number of columns and rows
    cols = 32;
    rows = 24;

    // approximate value of one arc-second in meters
    static float arcsec[3];

    // resampling output parameters
    static float outparams[5];

    std::string szTilePath;
    std::string szLandSatPath;

    if(argc > 1)
    {
        fprintf(stderr, "loading from %s\n", argv[1]);

        szTilePath   .assign(argv[1]);
        szLandSatPath.assign(argv[1]);

        szTilePath    += "/data/HawaiiTileset/tiles";
        szLandSatPath += "/data/HawaiiTileset/landsat";

        abasepath1 = szTilePath   .c_str();
        abasepath2 = szLandSatPath.c_str();
    }


    // load resampled tiles
    terrain->load(cols,rows, // number of columns and rows

                  abasepath1,
                  abasepath2,
                  NULL, // directories for tiles and textures (and no fogmaps)

                  -viewx,-viewy, // horizontal offset in arc-seconds
                  0.0f, // no vertical offset
                  1.0f,1.0f,1.0f, // no horizontal stretching
                  exaggeration,tscale, // vertical exaggeration and global scale
                  0.0f,0.0f, // no fog parameters required
                  0.0f, // choose default minimum resolution
                  0.0f, // disable base offset safety
                  outparams, // geometric output parameters
                  arcsec); // one arcsec in meters
#endif

#if 1
    fprintf(stderr, "%f %f %f\n",
            terrain->getminitile()->getcenterx(),
            terrain->getminitile()->getcentery(),
            terrain->getminitile()->getcenterz());

    fprintf(stderr, "%f %f \n",
            terrain->getminitile()->getsizex(),
            terrain->getminitile()->getsizez());
#endif            

    max[0] = terrain->getminitile()->getcenterx();
    max[1] = terrain->getminitile()->getcentery();
    max[2] = terrain->getminitile()->getcenterz();

    min[0] = 
        terrain->getminitile()->getcenterx() -
        (terrain->getminitile()->getsizex() / 2.f);

    min[1] = terrain->getminitile()->getcentery();

    min[2] = 
        terrain->getminitile()->getcenterz() -
        (terrain->getminitile()->getsizez() / 2.f);

    // tball
    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;

    //scale = 100;

    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]);
    fprintf(stderr, "tcenter  : %f %f %f\n", 
            tCenter[0], tCenter[1], tCenter[2]);

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

    return 0;
}