/*! init client window * * If manageClientViewports is set, then all viewports from the * cluster window are duplcated to the client window. */ void MultiDisplayWindow::clientInit( void ) { bool changed = false; ViewportPtr vp,cvp; if(getManageClientViewports() == false || getClientWindow() == NullFC) return; // check if something changed if(getMFPort()->size() == getClientWindow()->getMFPort()->size()) { for(UInt32 v = 0 ; v < getMFPort()->size() && !changed ; v++) { vp = getPort(v); cvp = getClientWindow()->getPort(v); if( vp->getRoot() != cvp->getRoot() || vp->getLeft() != cvp->getLeft() || vp->getRight() != cvp->getRight() || vp->getBottom() != cvp->getBottom() || vp->getTop() != cvp->getTop() || vp->getBackground() != cvp->getBackground() || vp->getMFForegrounds()->size() != cvp->getMFForegrounds()->size() ) changed = true; } } else { changed = true; } if(changed) { beginEditCP(getClientWindow()); // remove all viewports while(getClientWindow()->getMFPort()->size()) { vp = getClientWindow()->getPort(0); getClientWindow()->subPort(0); subRefCP(vp); } // duplicate viewports for(UInt32 v=0 ; v<getMFPort()->size() ;v++) { getClientWindow()->addPort(ViewportPtr::dcast(getPort(v)->shallowCopy())); } endEditCP(getClientWindow()); } }
ViewportUnrecPtr WindowEventProducer::windowToViewport(const Pnt2f& WindowPoint, Pnt2f& ViewportPoint) { ViewportUnrecPtr ThePort; for(UInt32 i(0) ; i<getMFPort()->size() ; ++i) { ThePort = getPort(i); if(ThePort->getEnabled()) { ViewportPoint.setValues(WindowPoint.x() - ThePort->getPixelLeft(), WindowPoint.y() - ThePort->getPixelBottom()); return ThePort; } } return NULL; }
void MultiDisplayWindow::clientInit(void) { bool changed = false; Viewport *vp, *cvp; if(getManageClientViewports() == false || getClientWindow () == NULL) { return; } // check if something changed if(getMFPort()->size() == getClientWindow()->getMFPort()->size()) { for(UInt32 v = 0 ; v < getMFPort()->size() && !changed ; v++) { vp = getPort(v); cvp = getClientWindow()->getPort(v); if( vp->getRoot() != cvp->getRoot() || vp->getLeft() != cvp->getLeft() || vp->getRight() != cvp->getRight() || vp->getBottom() != cvp->getBottom() || vp->getTop() != cvp->getTop() || vp->getBackground() != cvp->getBackground() || vp->getMFForegrounds()->size() != cvp->getMFForegrounds()->size() ) { changed = true; } } } else { changed = true; } if(changed) { // remove all viewports #if 0 while(getClientWindow()->getMFPort()-size()) { vp = getClientWindow()->getPort(0); getClientWindow()->subPort(0U); } #endif getClientWindow()->clearPorts(); // duplicate viewports for(UInt32 v=0 ; v<getMFPort()->size() ; v++) { ViewportUnrecPtr pTmpPort = dynamic_pointer_cast<Viewport>(getPort(v)->shallowCopy()); getClientWindow()->addPort(pTmpPort); } } }
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); }
/*! 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(); } } }
void SortLastWindow::serverRender(Window *serverWindow, UInt32 id, RenderActionBase *action ) { ViewportUnrecPtr serverPort = NULL; Viewport *clientPort = NULL; UInt32 sv = 0; UInt32 cv = 0; // duplicate viewports for(cv = 0, sv = 0; cv < getMFPort()->size(); ++cv) { clientPort = getPort(cv); if(serverWindow->getMFPort()->size() <= sv) { // create new port serverPort = Viewport::create(); serverWindow->addPort(serverPort); } else { serverPort = serverWindow->getPort(sv); } // duplicate values if(getWidth() && getHeight()) { serverPort->setSize(clientPort->calcPixelLeft (), clientPort->calcPixelBottom(), clientPort->calcPixelRight (), clientPort->calcPixelTop ()); } else { serverPort->setSize(0,0,0,0); } serverPort->setCamera (clientPort->getCamera ()); serverPort->setRoot (clientPort->getRoot ()); serverPort->setBackground(clientPort->getBackground()); // ignore statistics foreground serverPort->clearForegrounds(); for(UInt32 f = 0 ; f < serverPort->getMFForegrounds()->size(); ++f) { Foreground *fg = clientPort->getForegrounds(f); StatisticsForeground *sfg = dynamic_cast<StatisticsForeground *>(fg); if(sfg == NULL) { serverPort->addForeground(fg); } } serverPort->setTravMask(clientPort->getTravMask()); sv++; } // remove unused ports while(serverWindow->getMFPort()->size() > sv) { serverWindow->subPort(sv); } // setup visible nodes setupNodes(id); // render the viewports serverWindow->activate(); serverWindow->frameInit(); action->setWindow(serverWindow); if(getComposer() != NULL) getComposer()->startFrame(); for(sv = 0; sv < serverWindow->getMFPort()->size(); ++sv) { Viewport *vp = serverWindow->getPort(sv); if(getComposer() != NULL) getComposer()->startViewport(vp); // render vp->render(action); // compose single viewport if(getComposer() != NULL) getComposer()->composeViewport(vp); } // compose whole window if(getComposer() != NULL) getComposer()->composeWindow(); }