void PCSSShadowMap::initTextures(Window *win)
{
    _initTexturesDone = true;

    Int32   width = _shadowVP->getPixelWidth();
    Int32   height = _shadowVP->getPixelHeight();

    //if no NPOTTextures supported, resize images
    if(!_useNPOTTextures)
    {
        if(width > height)
            _widthHeightPOT = osgNextPower2(width - 1);
        else
            _widthHeightPOT = osgNextPower2(height - 1);

        _colorMapImage->set(GL_RGB, _widthHeightPOT, _widthHeightPOT);

        _shadowFactorMapImage->set(GL_RGB, _widthHeightPOT, _widthHeightPOT);
    }
}
void ParticleBSPTree::build(Particles *core)
{
    _tree.clear();
    
    if(core == NULL)
    {
        FWARNING(("ParticleBSP::build: no core!!\n"));
        return;
    }
    
    GeoVectorProperty * const pos = core->getPositions();
    
    if(pos == NULL)
        return;

    const MFInt32 *indices = core->getMFIndices();
        
    // 1. create list for particles
 
    std::vector<Int32> order;
    order.reserve(pos->size());
    
    for(UInt32 i = 0; i < pos->size32(); ++i )
    {     
        if(indices->size() == pos->size())
        {        
            order.push_back((*indices)[i]);
        }
        else
        {
            order.push_back(i);            
        }
    }
    
    // reserve mem for tree
    
    _tree.resize(osgNextPower2(order.size()) * 2);
    
    // 2. recursively build the tree
    
    UInt32 nnodes = doBuild(order.begin(), order.end(), 1, pos);
    
    // 3. remove the unneeded elements from the end
    
    if(nnodes < _tree.size())
        _tree.erase( _tree.begin() + nnodes, _tree.end());

    // done
}
void BinarySwapComposer::open()
{
    // determine usable servers
    if(osgIsPower2(serverCount()))
        _usableServers = serverCount();
    else
        _usableServers = osgNextPower2(serverCount()) / 2;

//    _usableServers = 1;

    // create server cross connection
    _clusterWindow->getNetwork()->connectAllPointToPoint(clusterId(),
                                                         "StreamSock");
    // do not buffer any data
    for(UInt32 i=0 ; i <= serverCount() ; ++i)
        clusterWindow()->getNetwork()->getConnection(i)->forceDirectIO();

/*
    // create barrier
    _barrier = Barrier::get(NULL);
    // create writer thread
    _writer = BaseThread::get(NULL);
*/

    // read whole buffer
    if(!_isClient && clusterId() < _usableServers)
    {
        // create barrier
        _barrier = Barrier::get(NULL, false);
        // create writer thread
        _writer = BaseThread::get(NULL, false);
        // start writer thread
        _writer->runFunction( writeProc, this );
    }
    else
    {
        _writer = NULL;
    }
}
void PCSSShadowMap::createShadowMaps(DrawEnv *pEnv)
{
    if(_tiledeco == NULL)
    {
        _tiledeco = TileCameraDecorator::create();
    }

    //Checking for the smallest Window-Dimension
    UInt32  minSize = _shadowVP->getPixelWidth();

    if(_shadowVP->getPixelHeight() < minSize)
        minSize = _shadowVP->getPixelHeight();

    //Checking for biggest PowerOf2 that fits in smallest Window-Dimension
    UInt32  _mapRenderSize = osgNextPower2(minSize + 1) / 2;
    if(_mapRenderSize == 0)
        _mapRenderSize = 128;

    Real32  vpTop, vpBottom, vpLeft, vpRight;

    //------Setting up Window to fit size of ShadowMap----------------

    // Saving original Viewport-Dimensions
    vpTop = _shadowVP->getTop();
    vpBottom = _shadowVP->getBottom();
    vpLeft = _shadowVP->getLeft();
    vpRight = _shadowVP->getRight();

    glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
    glShadeModel(GL_FLAT);
    glDisable(GL_LIGHTING);
    glDepthMask(GL_TRUE);

    // disable all lights more speed
    std::vector<bool> lightStates;
    for(UInt32 i = 0;i < _shadowVP->_lights.size();++i)
    {
        // store old states.
        lightStates.push_back(_shadowVP->_lights[i].second->getOn());
        _shadowVP->_lights[i].second->setOn(false);
    }

    // deactivate exclude nodes:
    for(UInt32 i = 0;i < _shadowVP->getMFExcludeNodes()->size();++i)
    {
        Node *exnode = _shadowVP->getExcludeNodes(i);
        if(exnode != NULL)
            exnode->setTravMask(0);
    }

    for(UInt32 i = 0;i < _shadowVP->_lights.size();++i)
    {
        if(_shadowVP->_lightStates[i] != 0)
        {
            if(_shadowVP->getGlobalShadowIntensity() != 0.0 ||
               _shadowVP->_lights[i].second->getShadowIntensity() != 0.0)
            {
                if(_mapRenderSize > _shadowVP->getMapSize())
                    _mapRenderSize = _shadowVP->getMapSize();
                _shadowVP->setVPSize(0, 0, _mapRenderSize - 1, _mapRenderSize -
                                     1);
                // we use a tiledecorator to create shadow maps with
                // a higher resolutions than the viewport or the screen.
                _tiledeco->setDecoratee(_shadowVP->_lightCameras[i]);
                _tiledeco->setFullSize(_shadowVP->getMapSize(),
                                       _shadowVP->getMapSize());

                pEnv->getAction()->setCamera(_tiledeco);

                Real32  step = (1.0 / Real32(_shadowVP->getMapSize())) *
                    Real32(_mapRenderSize);

                UInt32  ypos = 0;
                for(Real32 y = 0;y < 1.0;y += step)
                {
                    UInt32  xpos = 0;
                    for(Real32 x = 0;x < 1.0;x += step)
                    {
                        _tiledeco->setSize(x, y, x + step, y + step);

                        glClear(GL_DEPTH_BUFFER_BIT);
                        glPolygonOffset(_shadowVP->getOffFactor(),
                                        _shadowVP->getOffBias());
                        glEnable(GL_POLYGON_OFFSET_FILL);

                        _shadowVP->renderLight(pEnv->getAction(), _unlitMat, i);

                        pEnv->getWindow()->validateGLObject(
                            _shadowVP->_texChunks[i]->getGLId(),
                                                           pEnv);

                        glDisable(GL_POLYGON_OFFSET_FILL);

                        //----------Shadow-Texture-Parameters and Indices-------------

                        glBindTexture(GL_TEXTURE_2D,
                                      pEnv->getWindow()->getGLObjectId(
                                      _shadowVP->_texChunks[i]->getGLId()));
                        if(glGetError() != GL_NO_ERROR)
                            SWARNING << "Error on binding Texture!" << endLog;

                        glCopyTexSubImage2D(GL_TEXTURE_2D, 0, xpos, ypos, 0, 0,
                                            _mapRenderSize, _mapRenderSize);

                        if(glGetError() != GL_NO_ERROR)
                            SWARNING << "Error on copying Texture!" << endLog;

                        glBindTexture(GL_TEXTURE_2D, 0);
                        if(glGetError() != GL_NO_ERROR)
                            SWARNING << "Error on releasing Texture!" <<
                                endLog;

                        if(glGetError() != GL_NO_ERROR)
                            SWARNING << "Error while Texture-Creation!" <<
                                endLog;

                        xpos += _mapRenderSize;
                    }
                    ypos += _mapRenderSize;
                }
            }
        }
    }


    // enable all lights.
    for(UInt32 i = 0;i < _shadowVP->_lights.size();++i)
    {
        // restore old states.
        _shadowVP->_lights[i].second->setOn(lightStates[i]);
    }

    // activate exclude nodes:
    for(UInt32 i = 0;i < _shadowVP->getMFExcludeNodes()->size();++i)
    {
        Node *exnode = _shadowVP->getExcludeNodes(i);
        if(exnode != NULL)
            if(_shadowVP->_excludeNodeActive[i])
                exnode->setTravMask(TypeTraits<UInt32>::BitsSet);
    }
    //-------Restoring old states of Window and Viewport----------

    {
        _shadowVP->setSize(vpLeft, vpBottom, vpRight, vpTop);
    }

    pEnv->getAction()->setCamera(_shadowVP->getCamera());

    glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
    glShadeModel(GL_SMOOTH);
    glEnable(GL_LIGHTING);
}
PCSSShadowMap::PCSSShadowMap(ShadowViewport *source) :
    TreeRenderer(source),
    _tiledeco(NULL),
    _colorMap(NULL),
    _shadowFactorMap(NULL),
    _colorMapImage(NULL),
    _shadowFactorMapImage(NULL),
    _shadowCmat(NULL),
    _shadowSHL(NULL),
    _combineSHL(NULL),
    _combineDepth(NULL),
    _pf(NULL),
    _firstRun(1),
    _width(1),
    _height(1),
    _widthHeightPOT(0),
    _fb(0),
    _fb2(0),
    _rb_depth(0),
    _initTexturesDone(false)
{
#if 0
    if(_shadowVP->getParent() != NULL)
    {
        _width = _shadowVP->getPixelWidth();
        _height = _shadowVP->getPixelHeight();
    }

    if(_width == 0)
        _width = 1;
    if(_height == 0)
        _height = 1;

    if(_width > _height)
        _widthHeightPOT = osgNextPower2(_width - 1);
    else
        _widthHeightPOT = osgNextPower2(_height - 1);
#endif

    _tiledeco = NULL;

    //Prepare Color Map grabbing
    _colorMap = TextureChunk::create();
    _colorMapImage = Image::create();

    _colorMap->setImage(_colorMapImage);
    _colorMap->setInternalFormat(GL_RGB);
    _colorMap->setExternalFormat(GL_RGB);
    _colorMap->setMinFilter(GL_NEAREST);
    _colorMap->setMagFilter(GL_NEAREST);
    _colorMap->setWrapS(GL_REPEAT);
    _colorMap->setWrapT(GL_REPEAT);
    _colorMap->setTarget(GL_TEXTURE_2D);

#if 0
    if(_useNPOTTextures)
    {
        _colorMapImage->set(GL_RGB, _width, _height);
    }
    else
    {
        _colorMapImage->set(GL_RGB, _widthHeightPOT, _widthHeightPOT);
    }
#endif

    //Prepare Shadow Factor Map grabbing
    _shadowFactorMap = TextureChunk::create();
    _shadowFactorMapImage = Image::create();

    _shadowFactorMap->setImage(_shadowFactorMapImage);
    _shadowFactorMap->setInternalFormat(GL_RGB);
    _shadowFactorMap->setExternalFormat(GL_RGB);
    _shadowFactorMap->setMinFilter(GL_LINEAR);
    _shadowFactorMap->setMagFilter(GL_LINEAR);
    _shadowFactorMap->setWrapS(GL_REPEAT);
    _shadowFactorMap->setWrapT(GL_REPEAT);
    _shadowFactorMap->setTarget(GL_TEXTURE_2D);

#if 0
    if(_useNPOTTextures)
    {
        _shadowFactorMapImage->set(GL_RGB, _width, _height);
    }
    else
    {
        _shadowFactorMapImage->set(GL_RGB, _widthHeightPOT, _widthHeightPOT);
    }
#endif

    //SHL Chunk 1

    _shadowSHL = SHLChunk::create();
    //_shadowSHL->readVertexProgram("PCSS_Shadow.vert");
    //_shadowSHL->readFragmentProgram("PCSS_Shadow.frag");
    _shadowSHL->setVertexProgram(_pcss_shadow_vp);
    _shadowSHL->setFragmentProgram(_pcss_shadow_fp);

    //SHL Chunk 2
    _combineSHL = SHLChunk::create();

    //_combineSHL->readVertexProgram("PCSS_Shadow_combine.vert");
    //_combineSHL->readFragmentProgram("PCSS_Shadow_combine.frag");
    _combineSHL->setVertexProgram(_shadow_combine_vp);
    _combineSHL->setFragmentProgram(_shadow_combine_fp);

    _combineDepth = DepthChunk::create();
        _combineDepth->setReadOnly(true);

    //Shadow Shader
    _shadowCmat = ChunkMaterial::create();

    //Combine Shader
    _combineCmat = ChunkMaterial::create();
    _combineCmat->addChunk(_combineSHL);
    _combineCmat->addChunk(_colorMap);
    _combineCmat->addChunk(_shadowFactorMap);
    _combineCmat->addChunk(_combineDepth);

    _pf = PolygonForeground::create();
    // ref counting is not supported in the polygon foreground!
    _pf->setMaterial(_combineCmat);
    _pf->editMFTexCoords()->push_back(Vec3f(0.0f, 0.0f, 0.0f));
    _pf->editMFPositions()->push_back(Pnt2f(0.0f, 0.0f));

    _pf->editMFTexCoords()->push_back(Vec3f(1.0f, 0.0f, 0.0f));
    _pf->editMFPositions()->push_back(Pnt2f(1.0f, 0.0f));

    _pf->editMFTexCoords()->push_back(Vec3f(1.0f, 1.0f, 0.0f));
    _pf->editMFPositions()->push_back(Pnt2f(1.0f, 1.0f));

    _pf->editMFTexCoords()->push_back(Vec3f(0.0f, 1.0f, 0.0f));
    _pf->editMFPositions()->push_back(Pnt2f(0.0f, 1.0f));

    _pf->setNormalizedX(true);
    _pf->setNormalizedY(true);
}
void PCSSShadowMap::render(DrawEnv *pEnv)
{
    Window  *win = pEnv->getWindow();
    initialize(win);

    if(!_useGLSL || !_useShadowExt)
        _shadowVP->Viewport::render(pEnv->getAction());
    else
    {
        glPushAttrib(GL_ENABLE_BIT);

        if(!_initTexturesDone)
            initTextures(win);

        if(_useFBO)
        {
            if(!initFBO(pEnv))
                printf("ERROR with FBOBJECT\n");
        }

        GLfloat globalAmbient[] =
        {
            0.0, 0.0, 0.0, 1.0
        };
        glLightModelfv(GL_LIGHT_MODEL_AMBIENT, globalAmbient);
        _firstRun = 1;

#if 0
        for(UInt32 i = 0;i < _shadowVP->_lights.size();i++)
        {
            {
                _shadowVP->_texChunks[i]->setMinFilter(GL_NEAREST);
                _shadowVP->_texChunks[i]->setMagFilter(GL_NEAREST);
            }
        }
#endif

        if(_shadowVP->getPixelWidth() != _width ||
           _shadowVP->getPixelHeight() != _height)
        {
            _width = _shadowVP->getPixelWidth();
            _height = _shadowVP->getPixelHeight();

            if(_useNPOTTextures)
            {
                _colorMapImage->set(GL_RGB, _width, _height);

                _shadowFactorMapImage->set(GL_RGB, _width, _height);

                reInit(pEnv);
            }
            else
            {
                if(_width > _height)
                    _widthHeightPOT = osgNextPower2(_width - 1);
                else
                    _widthHeightPOT = osgNextPower2(_height - 1);

                _colorMapImage->set(GL_RGB, _widthHeightPOT, _widthHeightPOT);

                _shadowFactorMapImage->set(GL_RGB, _widthHeightPOT,
                                           _widthHeightPOT);
            }
        }

        commitChanges();

        if(_shadowVP->getMapAutoUpdate())
        {
#ifdef USE_FBO_FOR_COLOR_AND_FACTOR_MAP
            if(_useFBO && _useNPOTTextures)
                createColorMapFBO(pEnv);
            else
#endif
                createColorMap(pEnv);

            //deactivate transparent Nodes
            for(UInt32 t = 0;t < _shadowVP->_transparent.size();++t)
                _shadowVP->_transparent[t]->setTravMask(0);

            if(_useFBO)
                createShadowMapsFBO(pEnv);
            else
                createShadowMaps(pEnv);

            // switch on all transparent geos
            for(UInt32 t = 0;t < _shadowVP->_transparent.size();++t)
                _shadowVP->_transparent[t]->setTravMask(TypeTraits<UInt32>::BitsSet);

            for(UInt32 i = 0;i < _shadowVP->_lights.size();i++)
            {
                if(_shadowVP->_lightStates[i] != 0)
                {
                    if(_shadowVP->getGlobalShadowIntensity() != 0.0 ||
                       _shadowVP->_lights[i].second->getShadowIntensity() != 0.0)
                    {
#ifdef USE_FBO_FOR_COLOR_AND_FACTOR_MAP
                        if(_useFBO && _useNPOTTextures)
                            createShadowFactorMapFBO(pEnv, i);
                        else
#endif
                            createShadowFactorMap(pEnv, i);
                        //_firstRun = 0;
                    }
                }
            }
        }
        else
        {
            if(_shadowVP->_trigger_update)
            {
#ifdef USE_FBO_FOR_COLOR_AND_FACTOR_MAP
                if(_useFBO && _useNPOTTextures)
                    createColorMapFBO(pEnv);
                else
#endif
                    createColorMap(pEnv);

                //deactivate transparent Nodes
                for(UInt32 t = 0;t < _shadowVP->_transparent.size();++t)
                    _shadowVP->_transparent[t]->setTravMask(0);

                if(_useFBO)
                    createShadowMapsFBO(pEnv);
                else
                    createShadowMaps(pEnv);

                // switch on all transparent geos
                for(UInt32 t = 0;t < _shadowVP->_transparent.size();++t)
                    _shadowVP->_transparent[t]->setTravMask(TypeTraits<UInt32>::BitsSet);

                for(UInt32 i = 0;i < _shadowVP->_lights.size();i++)
                {
                    if(_shadowVP->_lightStates[i] != 0)
                    {
                        if(_shadowVP->getGlobalShadowIntensity() != 0.0 ||
                           _shadowVP->_lights[i].second->getShadowIntensity() != 0.0)
                        {
#ifdef USE_FBO_FOR_COLOR_AND_FACTOR_MAP
                            if(_useFBO && _useNPOTTextures)
                                createShadowFactorMapFBO(pEnv, i);
                            else
#endif
                                createShadowFactorMap(pEnv, i);
                        }
                    }
                }
                _shadowVP->_trigger_update = false;
            }
        }

        drawCombineMap(pEnv);

        glPopAttrib();
        // render the foregrounds.
        for(UInt16 i = 0;i < _shadowVP->getMFForegrounds()->size();++i)
        {
            _shadowVP->getForegrounds(i)->draw(pEnv, _shadowVP);
        }
    }
}
void
OcclusionCullingTreeBuilder::addNodeAdaptiveBucketMode(OCRenderTreeNode *pNode)
{
    Real32 val       = pNode->getScalar();
    Int32  bucketIdx = static_cast<Int32>((val - _bucketLow) * _bucketScale);

    bucketIdx = osgClamp<Int32>(0, bucketIdx, _numBuckets - 1);

    // XXX with the above osgClamp this never triggers... ?? --cneumann
    if(bucketIdx < 0 || bucketIdx >= Int32(_numBuckets))
    {
        Real32 newLow   = osgMin(val, _bucketLow );
        Real32 newHigh  = osgMax(val, _bucketHigh);
        Real32 newScale = (_numBuckets + 1) / (newHigh - newLow);

        // only rescale in exponential steps to reduce the
        // number of rescales
        Real32 rescale  = _bucketScale / newScale;
        UInt32 step     = osgNextPower2(static_cast<UInt32>(osgCeil(rescale)));

        SLOG <<   "OCTB::addABM: old: " << _bucketLow << " - " << _bucketHigh << " - " << _bucketScale
             << "\n              new: " << newLow     << " - " << newHigh     << " - " << newScale
             << "\n rescale " << rescale << " step " << step
             << std::endl;

        newScale = _bucketScale / step;
        Real32 d = (_numBuckets - 1) / newScale;
        newLow  = osgMax(newLow - d / 2.f, 0.f);
        newHigh = osgMin(newLow + d,       1.f);

        // move bucket contents
        Real32 iter  = _bucketLow;
        Real32 istep = 1.f / _bucketScale;

        for(UInt32 i = 0; i < _numBuckets; ++i, iter += istep)
        {
            if(_buckets[i] == NULL)
                continue;

            UInt32 index = static_cast<UInt32>((iter - newLow) * newScale);

            if(_bucketsWork[index] == NULL)
            {
                _bucketsWork[index] = _buckets[i];
            }
            else
            {
                _bucketsWork[index]->addChild(_buckets[i]);
            }

            _buckets[i] = NULL;
        }

        _buckets.swap(_bucketsWork);

        _bucketLow   = newLow;
        _bucketHigh  = newHigh;
        _bucketScale = newScale;

        bucketIdx = osgClamp<Int32>(
            0,
            static_cast<Int32>((val - _bucketLow) * _bucketScale),
            _numBuckets - 1);
    }

    if(_buckets[bucketIdx] == NULL)
    {
        _buckets[bucketIdx] = pNode;
    }
    else
    {
        _buckets[bucketIdx]->addChild(pNode);
    }

    ++_numNodes;
}