/*! read server cababilities
 */
void SortLastWindow::clientInit( void )
{
    getNetwork()->getAspect()->addFieldFilter(Node::getClassType().getId(),
                                              Node::VolumeFieldMask);
    getNetwork()->getAspect()->addFieldFilter(Node::getClassType().getId(),
                                              Node::TravMaskFieldMask);

    // create default composer
    if(getComposer() == NULL)
    {
/*
        FieldContainerPtr fcPtr = 
            FieldContainerFactory::the()->createFieldContainer("BinarySwapComposer");
        setComposer(ImageComposerPtr::dcast(fcPtr));
*/
    }
    if(getComposer() != NULL)
    {
        SortLastWindow *clusterWindow(this);
        getComposer()->setup(true,
                             getMFServers()->size32(),
                             getClientWindow(),
                             clusterWindow);
        getComposer()->open();
        // build node groups
        buildGroups();
    }
}
void MultiDisplayWindow::serverRender(Window           *window,
                                      UInt32            id,
                                      RenderActionBase *action)
{
    TileCameraDecoratorUnrecPtr deco;
    ViewportUnrecPtr serverPort;
    Viewport * clientPort;
    StereoBufferViewport *clientStereoPort;
    UInt32 sv,cv;
    Int32 l,r,t,b;
    Int32 cleft,cright,ctop,cbottom;

    if(!getHServers())
    {
        setHServers(getMFServers()->size());
    }
    if(!getVServers())
    {
        setVServers(1);
    }

    UInt32 row   =id/getHServers();
    UInt32 column=id%getHServers();

    // calculate width and height from local width and height
    UInt32 width  = window->getWidth() ;
    UInt32 height = window->getHeight();

    if(getWidth()==0)
    {
        setWidth( width*getHServers() );
    }
    if(getHeight()==0)
    {
        setHeight( height*getVServers() );
    }

    Int32 left   = column * width  - column * getXOverlap();
    Int32 bottom = row    * height - row    * getYOverlap();
    Int32 right  = left   + width  - 1;
    Int32 top    = bottom + height - 1;
    Real64 scaleCWidth  =
        ((width - getXOverlap()) * (getHServers() - 1) + width) /
        float(getWidth());
    Real64 scaleCHeight =
        ((height - getYOverlap())* (getVServers() - 1) + height)/
        float(getHeight());

    // duplicate viewports
    for(cv=0,sv=0; cv<getMFPort()->size(); cv++)
    {
        clientPort = getPort(cv);

        clientStereoPort = dynamic_cast<StereoBufferViewport *>(clientPort);

        cleft   = Int32(clientPort->getPixelLeft()      * scaleCWidth)   ;
        cbottom = Int32(clientPort->getPixelBottom()    * scaleCHeight)  ;
        cright  = Int32((clientPort->getPixelRight()+1) * scaleCWidth) -1;
        ctop    = Int32((clientPort->getPixelTop()+1)   * scaleCHeight)-1;

        if(cright  < left   ||
                cleft   > right  ||
                ctop    < bottom ||
                cbottom > top      )
        {
            // invisible on this server screen
            continue;
        }

        // calculate overlapping viewport
        l = osgMax(cleft  ,left  ) - left;
        b = osgMax(cbottom,bottom) - bottom;
        r = osgMin(cright ,right ) - left;
        t = osgMin(ctop   ,top   ) - bottom;

        if(window->getMFPort()->size() <= sv)
        {
            serverPort = dynamic_pointer_cast<Viewport>(
                             clientPort->shallowCopy());

            deco = TileCameraDecorator::create();

            window->addPort(serverPort);

            serverPort->setCamera(deco);
        }
        else
        {
            serverPort = window->getPort(sv);

            deco = dynamic_cast<TileCameraDecorator *>(
                       serverPort->getCamera());

            if(window->getPort(sv)->getType() != clientPort->getType())
            {
                // there is a viewport with the wrong type
                serverPort =
                    dynamic_pointer_cast<Viewport>(clientPort->shallowCopy());

                window->replacePort(sv,
                                    serverPort);//[sv] = serverPort;
                serverPort->setCamera(deco);
            }
            else
            {
                deco = dynamic_cast<TileCameraDecorator *>(
                           serverPort->getCamera());
            }
        }

        // update changed viewport fields
        updateViewport(serverPort, clientPort);

        // set viewport size
        serverPort->setSize(Real32(l),Real32(b),Real32(r),Real32(t));

        // use pixel even if pixel = 1
        if(serverPort->getLeft() == 1.0)
            serverPort->setLeft(1.0001f);

        if(serverPort->getRight() == 1.0)
            serverPort->setRight(1.0001f);

        if(serverPort->getTop() == 1.0)
            serverPort->setTop(1.0001f);

        if(serverPort->getBottom() == 1.0)
            serverPort->setBottom(1.0001f);

        // calculate tile parameters
        deco->setFullWidth ( cright-cleft );
        deco->setFullHeight( ctop-cbottom );
        deco->setSize( ( l+left-cleft     ) / float( cright-cleft ),
                       ( b+bottom-cbottom ) / float( ctop-cbottom ),
                       ( r+left-cleft     ) / float( cright-cleft ),
                       ( t+bottom-cbottom ) / float( ctop-cbottom ) );
        deco->setDecoratee( clientPort->getCamera() );

        sv++;
    }

    // remove unused ports
    while(window->getMFPort()->size()>sv)
    {
        window->subPort(sv);
    }

    Inherited::serverRender(window,id,action);
}
Пример #3
0
/*! render server window
 *
 *  update all viewport parameters and render local viewports
 *  Width and height of the whole window are calculated by
 *  multiplieing the local window size by hServers and vServers.
 */
void MultiDisplayWindow::serverRender( WindowPtr serverWindow,
                                       UInt32 id,
                                       RenderActionBase *action )
{
    TileCameraDecoratorPtr deco;
    ViewportPtr serverPort;
    ViewportPtr clientPort;
    StereoBufferViewportPtr clientStereoPort;
    UInt32 sv,cv;
    Int32 l,r,t,b;
    Int32 cleft,cright,ctop,cbottom;

    // sync, otherwise viewports will be out of date

    if(!getHServers())
    {
        setHServers(getMFServers()->size());
    }
    if(!getVServers())
    {
        setVServers(1);
    }
    UInt32 row   =id/getHServers();
    UInt32 column=id%getHServers();
    // calculate width and height from local width and height
    UInt32 width  = serverWindow->getWidth() ;
    UInt32 height = serverWindow->getHeight();
    if(getWidth()==0)
    {
        setWidth( width*getHServers() );
    }
    if(getHeight()==0)
    {
        setHeight( height*getVServers() );
    }
    Int32 left   = column * width  - column * getXOverlap();
    Int32 bottom = row    * height - row    * getYOverlap();
    Int32 right  = left   + width  - 1;
    Int32 top    = bottom + height - 1;
    Real64 scaleCWidth   = ((width - getXOverlap()) * (getHServers() - 1) + width) / float(getWidth());
    Real64 scaleCHeight  = ((height - getYOverlap())* (getVServers() - 1) + height)/ float(getHeight());
    bool   isVirtualPort = false;

    // duplicate viewports
    for(cv = 0, sv = 0; cv < getMFPort()->size(); ++cv)
    {
        clientPort    = getPort(cv);
        isVirtualPort = clientPort->getType().isDerivedFrom(FBOViewport::getClassType());

        if(isVirtualPort)
        {
            // TODO -- seems wrong to render this on all servers, though rendering
            // then transmitting the texture doesn't seem like a good idea either.
            if(serverWindow->getMFPort()->size() <= sv)
            {
                serverPort = ViewportPtr::dcast(clientPort->shallowCopy());
                beginEditCP(serverWindow);
                serverWindow->addPort(serverPort);
                endEditCP(serverWindow);
            }
            else
            {
                serverPort = serverWindow->getPort(sv);

                if(serverPort->getType() != clientPort->getType())
                {
                    // there is a viewport with the wrong type
                    subRefCP(serverWindow->getPort(sv));
                    serverPort = ViewportPtr::dcast(clientPort->shallowCopy());
                    beginEditCP(serverWindow);
                    {
                        serverWindow->editPort(sv) = serverPort;
                    }
                    endEditCP(serverWindow);
                }
            }
            // update changed viewport fields
            updateViewport(serverPort,clientPort);
        }
        else
        {
            clientStereoPort = StereoBufferViewportPtr::dcast(clientPort);
            cleft   = Int32(clientPort->getPixelLeft()      * scaleCWidth)   ;
            cbottom = Int32(clientPort->getPixelBottom()    * scaleCHeight)  ;
            cright  = Int32((clientPort->getPixelRight()+1) * scaleCWidth) -1;
            ctop    = Int32((clientPort->getPixelTop()+1)   * scaleCHeight)-1;

            if( cright  < left   ||
                cleft   > right  ||
                ctop    < bottom ||
                cbottom > top       )
            {
                // invisible on this server screen
                continue;
            }
            // calculate overlapping viewport
            l = osgMax(cleft  ,left  ) - left;
            b = osgMax(cbottom,bottom) - bottom;
            r = osgMin(cright ,right ) - left;
            t = osgMin(ctop   ,top   ) - bottom;
            if(serverWindow->getMFPort()->size() <= sv)
            {
                serverPort = ViewportPtr::dcast(clientPort->shallowCopy());
                beginEditCP(serverPort);
                deco=TileCameraDecorator::create();
                beginEditCP(serverWindow);
                serverWindow->addPort(serverPort);
                serverPort->setCamera(deco);
                endEditCP(serverWindow);
                endEditCP(serverPort);
            }
            else
            {
                serverPort = serverWindow->getPort(sv);
                deco = TileCameraDecoratorPtr::dcast(serverPort->getCamera());

                if(serverPort->getType() != clientPort->getType())
                {
                    // there is a viewport with the wrong type
                    subRefCP(serverWindow->getPort(sv));
                    serverPort = ViewportPtr::dcast(clientPort->shallowCopy());

                    if(deco == NullFC)
                        deco = TileCameraDecorator::create();

                    beginEditCP(serverPort, Viewport::CameraFieldMask);
                    serverPort->setCamera(deco);
                    endEditCP(serverPort, Viewport::CameraFieldMask);

                    beginEditCP(serverWindow, Window::PortFieldMask);
                    serverWindow->editPort(sv) = serverPort;
                    endEditCP(serverWindow, Window::PortFieldMask);
                }
            }

            // update changed viewport fields
            updateViewport(serverPort,clientPort);

            // set viewport size
            beginEditCP(serverPort,
                        Viewport::LeftFieldMask|
                        Viewport::BottomFieldMask|
                        Viewport::RightFieldMask|
                        Viewport::TopFieldMask);
            serverPort->setSize(Real32(l),Real32(b),Real32(r),Real32(t));
            // use pixel even if pixel = 1
            if(serverPort->getLeft() == 1.0)
                serverPort->setLeft(1.0001);
            if(serverPort->getRight() == 1.0)
                serverPort->setRight(1.0001);
            if(serverPort->getTop() == 1.0)
                serverPort->setTop(1.0001);
            if(serverPort->getBottom() == 1.0)
                serverPort->setBottom(1.0001);
            endEditCP(serverPort,
                      Viewport::LeftFieldMask|
                      Viewport::BottomFieldMask|
                      Viewport::RightFieldMask|
                      Viewport::TopFieldMask);
            // calculate tile parameters
            beginEditCP(deco);
            deco->setFullWidth ( cright-cleft );
            deco->setFullHeight( ctop-cbottom );
            deco->setSize( ( l+left-cleft     ) / float( cright-cleft ),
                       ( b+bottom-cbottom ) / float( ctop-cbottom ),
                       ( r+left-cleft     ) / float( cright-cleft ),
                       ( t+bottom-cbottom ) / float( ctop-cbottom ) );
            deco->setDecoratee( clientPort->getCamera() );
            endEditCP(deco);
        }
        sv++;
    }
    // remove unused ports
    while(serverWindow->getMFPort()->size()>sv)
    {
        serverWindow->subPort(sv);
    }
    Inherited::serverRender(serverWindow,id,action);
}
void SortLastWindow::setupNodes(UInt32 groupId)
{
    UInt32  v             = 0;
    Node   *root          = NULL;
    UInt32  nI            = 0;
    UInt32  gnI           = 0;
    UInt32  gI            = 0;
    UInt32  group         = 0;
    UInt32  groupCount    = 0;
    UInt32  usableServers = getMFServers()->size32();

    if(!getGroupsChanged())
        return;

    // client and no client rendering 
    if(getMFServers()->size() == groupId &&
       (getComposer() == NULL ||
        !getComposer()->getClientRendering()))
    {
        for(nI = 0 ; nI < getMFGroupNodes()->size() ; ++nI)
        {
            if(getGroupNodes(nI)->getTravMask())
            {
                getGroupNodes(nI)->setTravMask(0);
                getGroupNodes(nI)->invalidateVolume();
            }
        }

        return;
    }

    if(getComposer() != NULL)
        usableServers = getComposer()->getUsableServers();

    // server but not usable, then invalidate all nodes
    if((getMFServers()->size() > groupId && usableServers <= groupId))
    {
        for(v = 0; v < getMFPort()->size(); ++v)
        {
            root = getPort(v)->getRoot();

            root->setTravMask(0);
            root->invalidateVolume();
        }

        setGroupsChanged(false);
        return;
    }        

    groupCount = usableServers;

    if(getComposer() != NULL) 
    {
        groupCount = getComposer()->getUsableServers();

        if(getComposer()->getClientRendering())
        {
            groupCount++;
        }
    }

    if(getMFServers()->size() == groupId)
        groupId = usableServers;

    // setup nodes
    for(nI = 0,gnI = 0,gI = 0,group = 0 ; nI < getMFGroupNodes()->size() ; ++nI)
    {
        while(nI >= gnI)
        {
            gnI += getGroupLengths(group); 
            gI++;
            group = gI % groupCount;
        }
        if(group == groupId)
        {
            if(getGroupNodes(nI)->getTravMask() != 
               TypeTraits<UInt32>::getMax())
            {
                getGroupNodes(nI)->setTravMask(TypeTraits<UInt32>::getMax());
                getGroupNodes(nI)->invalidateVolume();
            }
        }
        else
        {
            if(getGroupNodes(nI)->getTravMask())
            {
                getGroupNodes(nI)->setTravMask(0);
                getGroupNodes(nI)->invalidateVolume();
            }
        }

        getGroupNodes(nI)->updateVolume();
    }

    setGroupsChanged(false);
}
OSG_USING_NAMESPACE

/*! \class OSG::SortLastWindow
Cluster rendering configuration for sort first image composition
*/

/*----------------------------- static grouping functions -----------------*/

void SortLastWindow::buildGroups(void)
{
    UInt32            v          = 0;
    DrawableListT     drawables;
    UInt32            groupCount = 0;
    bool              rebuild    = false;

    // check for new nodes.
    FieldContainerFactoryBase *fcFactory = FieldContainerFactory::the();

    FieldContainer *fcPtr = NULL;

    ChangeList::ChangedStoreConstIt createdI;

    ChangeList *changeList = OSG::Thread::getCurrentChangeList();

    for(createdI  = changeList->beginCreated();
        createdI != changeList->endCreated(); 
        createdI++)
    {
        UInt32 uiId = (*createdI)->uiContainerId;

        fcPtr = fcFactory->getContainer(uiId);

        if(fcPtr != NULL && dynamic_cast<Node *>(fcPtr) != NULL)
            rebuild = true;
    }

    // is rebuild neccessary ?
    if(!rebuild && getMFGroupNodes()->size())
        return;

    groupCount = getMFServers()->size32();

    if(getComposer() != NULL)
    {
        groupCount = getComposer()->getUsableServers();
        if(getComposer()->getClientRendering())
            groupCount++;
    }

    // build groups for all viewports

    clearGroupNodes();
    editMFGroupLengths()->clear();

    for(v = 0; v < getMFPort()->size(); ++v)
    {
        Viewport *vp         = getPort(v);
        Node     *root       = vp->getRoot();

        drawables.clear();

        collectDrawables(root, drawables);

        if(drawables.size())
            splitDrawables(drawables, groupCount, false);
    }
}
void SortLastWindow::clientRender(RenderActionBase *action)
{
    UInt32          p;
    UInt32          groupId = getMFServers()->size32();

    if(getMFServers()->size())
    {
        if(getClientWindow() != NULL)
        {
            setupNodes(groupId);
/*
            getClientWindow()->activate();
            getClientWindow()->frameInit();
*/
            action->setWindow(getClientWindow());

            if(getComposer() != NULL)
                getComposer()->startFrame();

            DrawEnv oEnv;
            
            oEnv.setWindow(action->getWindow());

            // render all viewports
            for(p = 0; p < getMFPort()->size() ; ++p)
            {
                Viewport *vp=getPort(p);

                oEnv.setViewportDimension(vp->calcPixelLeft   (),
                                          vp->calcPixelBottom (),
                                          vp->calcPixelRight  (),
                                          vp->calcPixelTop    (),
                                          vp->calcIsFullWindow());
                if(getComposer() != NULL)
                {
                    getComposer()->startViewport(vp);

                    action->setCamera    (vp->getCamera    ());
                    action->setBackground(vp->getBackground());
                    action->setViewarea  (vp                 );
                    action->setTravMask  (vp->getTravMask  ());

                    action->apply(vp->getRoot());

                    for(UInt16 i=0; i < vp->getMFForegrounds()->size(); i++)
                    {
                        if(dynamic_cast<StatisticsForeground *>(
                               vp->getForegrounds(i)) == NULL)
                        {
                            vp->getForegrounds(i)->draw(&oEnv);
                        }
                    }

                    getComposer()->composeViewport(vp);

                    for(UInt16 i=0; i < vp->getMFForegrounds()->size(); i++)
                    {
                        if(dynamic_cast<StatisticsForeground *>(
                               vp->getForegrounds(i)) != NULL)
                        {
                            vp->getForegrounds(i)->draw(&oEnv);
                        }
                    }

                }
                else
                {
                    vp->render(action);
                }
            }

            // compose whole window
            if(getComposer() != NULL)
                getComposer()->composeWindow();
        }
    }
}