00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 #include <stdlib.h>
00044 #include <stdio.h>
00045 #include <OSGConfig.h>
00046 #include <OSGGL.h>
00047 #include <OSGNodePtr.h>
00048 #include <OSGViewport.h>
00049 #include <OSGTileCameraDecorator.h>
00050 #include <OSGBaseFunctions.h>
00051 #include <OSGStereoBufferViewport.h>
00052 #include <OSGFieldContainerFields.h>
00053 #include <OSGDisplayFilterForeground.h>
00054 #include "OSGMultiDisplayWindow.h"
00055 #include "OSGConnection.h"
00056 #include "OSGNode.h"
00057
00058 #define FAST_SYNC 0
00059
00060 OSG_USING_NAMESPACE
00061
00066
00067
00070 MultiDisplayWindow::MultiDisplayWindow(void) :
00071 Inherited()
00072 {
00073 }
00074
00077 MultiDisplayWindow::MultiDisplayWindow(const MultiDisplayWindow &source) :
00078 Inherited(source)
00079 {
00080 }
00081
00084 MultiDisplayWindow::~MultiDisplayWindow(void)
00085 {
00086 }
00087
00088
00089
00092 void MultiDisplayWindow::initMethod (void)
00093 {
00094 }
00095
00098 void MultiDisplayWindow::changed(BitVector whichField, UInt32 origin)
00099 {
00100 Inherited::changed(whichField, origin);
00101 }
00102
00105 void MultiDisplayWindow::dump( UInt32 ,
00106 const BitVector ) const
00107 {
00108 SLOG << "hServers:" << getHServers() << " "
00109 << "vServers:" << getVServers() << std::endl;
00110 }
00111
00112
00113
00117 void MultiDisplayWindow::serverInit( WindowPtr ,
00118 UInt32 )
00119 {
00120 }
00121
00128 void MultiDisplayWindow::serverRender( WindowPtr serverWindow,
00129 UInt32 id,
00130 RenderActionBase *action )
00131 {
00132 TileCameraDecoratorPtr deco;
00133 ViewportPtr serverPort;
00134 ViewportPtr clientPort;
00135 StereoBufferViewportPtr clientStereoPort;
00136 UInt32 sv,cv;
00137 Int32 l,r,t,b;
00138 Int32 cleft,cright,ctop,cbottom;
00139
00140 if(!getHServers())
00141 {
00142 setHServers(getServers().size());
00143 }
00144 if(!getVServers())
00145 {
00146 setVServers(1);
00147 }
00148 UInt32 row =id/getHServers();
00149 UInt32 column=id%getHServers();
00150
00151 UInt32 width = serverWindow->getWidth() ;
00152 UInt32 height = serverWindow->getHeight();
00153 if(getWidth()==0)
00154 {
00155 setWidth( width*getHServers() );
00156 }
00157 if(getHeight()==0)
00158 {
00159 setHeight( height*getVServers() );
00160 }
00161 Int32 left = column * width - column * getXOverlap();
00162 Int32 bottom = row * height - row * getYOverlap();
00163 Int32 right = left + width - 1;
00164 Int32 top = bottom + height - 1;
00165 Real64 scaleCWidth = ((width - getXOverlap()) * (getHServers() - 1) + width) / (float)getWidth();
00166 Real64 scaleCHeight = ((height - getYOverlap())* (getVServers() - 1) + height)/ (float)getHeight();
00167
00168
00169 for(cv=0,sv=0;cv<getPort().size();cv++)
00170 {
00171 clientPort = getPort()[cv];
00172 clientStereoPort = StereoBufferViewportPtr::dcast(clientPort);
00173 cleft = (Int32)(clientPort->getPixelLeft() * scaleCWidth) ;
00174 cbottom = (Int32)(clientPort->getPixelBottom() * scaleCHeight) ;
00175 cright = (Int32)((clientPort->getPixelRight()+1) * scaleCWidth) -1;
00176 ctop = (Int32)((clientPort->getPixelTop()+1) * scaleCHeight)-1;
00177 if(cright < left ||
00178 cleft > right ||
00179 ctop < bottom ||
00180 cbottom > top )
00181 {
00182
00183 continue;
00184 }
00185
00186 l = osgMax(cleft ,left ) - left;
00187 b = osgMax(cbottom,bottom) - bottom;
00188 r = osgMin(cright ,right ) - left;
00189 t = osgMin(ctop ,top ) - bottom;
00190 if(serverWindow->getPort().size() <= sv)
00191 {
00192 serverPort = ViewportPtr::dcast(clientPort->shallowCopy());
00193 beginEditCP(serverPort);
00194 deco=TileCameraDecorator::create();
00195 beginEditCP(serverWindow);
00196 serverWindow->addPort(serverPort);
00197 serverPort->setCamera(deco);
00198 endEditCP(serverWindow);
00199 endEditCP(serverPort);
00200 }
00201 else
00202 {
00203 serverPort = serverWindow->getPort()[sv];
00204 deco=TileCameraDecoratorPtr::dcast(serverPort->getCamera());
00205 if(serverWindow->getPort()[sv]->getType() !=
00206 clientPort->getType())
00207 {
00208
00209 subRefCP(serverWindow->getPort()[sv]);
00210 serverPort = ViewportPtr::dcast(clientPort->shallowCopy());
00211 beginEditCP(serverWindow);
00212 serverWindow->getPort()[sv] = serverPort;
00213 serverPort->setCamera(deco);
00214 endEditCP(serverWindow);
00215 }
00216 else
00217 {
00218 deco=TileCameraDecoratorPtr::dcast(serverPort->getCamera());
00219 }
00220 }
00221
00222 updateViewport(serverPort,clientPort);
00223
00224 beginEditCP(serverPort,
00225 Viewport::LeftFieldMask|
00226 Viewport::BottomFieldMask|
00227 Viewport::RightFieldMask|
00228 Viewport::TopFieldMask);
00229 serverPort->setSize(Real32(l),Real32(b),Real32(r),Real32(t));
00230
00231 if(serverPort->getLeft() == 1.0)
00232 serverPort->setLeft(1.0001);
00233 if(serverPort->getRight() == 1.0)
00234 serverPort->setRight(1.0001);
00235 if(serverPort->getTop() == 1.0)
00236 serverPort->setTop(1.0001);
00237 if(serverPort->getBottom() == 1.0)
00238 serverPort->setBottom(1.0001);
00239 endEditCP(serverPort,
00240 Viewport::LeftFieldMask|
00241 Viewport::BottomFieldMask|
00242 Viewport::RightFieldMask|
00243 Viewport::TopFieldMask);
00244
00245 beginEditCP(deco);
00246 deco->setFullWidth ( cright-cleft );
00247 deco->setFullHeight( ctop-cbottom );
00248 deco->setSize( ( l+left-cleft ) / (float)( cright-cleft ),
00249 ( b+bottom-cbottom ) / (float)( ctop-cbottom ),
00250 ( r+left-cleft ) / (float)( cright-cleft ),
00251 ( t+bottom-cbottom ) / (float)( ctop-cbottom ) );
00252 deco->setDecoratee( clientPort->getCamera() );
00253 endEditCP(deco);
00254 sv++;
00255 }
00256
00257 while(serverWindow->getPort().size()>sv)
00258 {
00259 serverWindow->subPort(sv);
00260 }
00261 Inherited::serverRender(serverWindow,id,action);
00262 }
00263
00266 void MultiDisplayWindow::serverSwap( WindowPtr window,UInt32 id )
00267 {
00268 Connection *connection;
00269
00270
00271 UInt8 pixel[3];
00272 glReadPixels(0,0,
00273 1,1,
00274 GL_RGB,GL_UNSIGNED_BYTE,
00275 pixel);
00276 glFinish();
00277
00278 #if !FAST_SYNC
00279 connection=getNetwork()->getMainConnection();
00280 if(!getInterleave())
00281 {
00282
00283 connection->signal();
00284
00285 connection->wait();
00286 }
00287 #endif
00288 Inherited::serverSwap(window,id);
00289 }
00290
00291
00292
00298 void MultiDisplayWindow::clientInit( void )
00299 {
00300 bool changed = false;
00301 ViewportPtr vp,cvp;
00302
00303 if(getManageClientViewports() == false ||
00304 getClientWindow() == NullFC)
00305 return;
00306
00307
00308 if(getPort().size() == getClientWindow()->getPort().size())
00309 {
00310 for(UInt32 v = 0 ; v < getPort().size() && !changed ; v++)
00311 {
00312 vp = getPort(v);
00313 cvp = getClientWindow()->getPort(v);
00314 if( vp->getRoot() != cvp->getRoot() ||
00315 vp->getLeft() != cvp->getLeft() ||
00316 vp->getRight() != cvp->getRight() ||
00317 vp->getBottom() != cvp->getBottom() ||
00318 vp->getTop() != cvp->getTop() ||
00319 vp->getBackground() != cvp->getBackground() ||
00320 vp->getForegrounds().size() != cvp->getForegrounds().size() )
00321 changed = true;
00322 }
00323 }
00324 else
00325 {
00326 changed = true;
00327 }
00328
00329 if(changed)
00330 {
00331 beginEditCP(getClientWindow());
00332
00333 while(getClientWindow()->getPort().size())
00334 {
00335 vp = getClientWindow()->getPort(0);
00336 getClientWindow()->subPort(0);
00337 subRefCP(vp);
00338 }
00339
00340 for(UInt32 v=0 ; v<getPort().size() ;v++)
00341 {
00342 getClientWindow()->addPort(ViewportPtr::dcast(getPort(v)->shallowCopy()));
00343 }
00344 endEditCP(getClientWindow());
00345 }
00346 }
00347
00350 void MultiDisplayWindow::clientSwap( void )
00351 {
00352 Connection *connection=getNetwork()->getMainConnection();
00353
00354 #if FAST_SYNC
00355 connection->selectChannel();
00356 #else
00357 if(!getInterleave())
00358 {
00359
00360 connection->wait();
00361
00362 connection->signal();
00363 }
00364 #endif
00365
00366
00367 Inherited::clientSwap();
00368 }
00369
00370
00371
00372
00375 void MultiDisplayWindow::updateViewport(ViewportPtr &serverPort,
00376 ViewportPtr &clientPort)
00377 {
00378 bool equal, found;
00379
00380
00381 if(serverPort == clientPort)
00382 return;
00383 if(serverPort == NullFC || clientPort == NullFC)
00384 return;
00385 if(serverPort->getType() != serverPort->getType())
00386 return;
00387
00388 const FieldContainerType &type = serverPort->getType();
00389 UInt32 fcount = osgMin(serverPort->getType().getNumFieldDescs(),
00390 clientPort->getType().getNumFieldDescs());
00391
00392 for(UInt32 i=1;i <= fcount;++i)
00393 {
00394 const FieldDescription* fdesc = type.getFieldDescription(i);
00395
00396 if(strcmp(fdesc->getCName(), "parent") == 0 ||
00397 strcmp(fdesc->getCName(), "camera") == 0)
00398 continue;
00399
00400 BitVector mask = fdesc->getFieldMask();
00401
00402 Field *dst_field = serverPort->getField(i);
00403 Field *src_field = clientPort->getField(i);
00404
00405 const FieldType &dst_ftype = dst_field->getType();
00406 const FieldType &src_ftype = src_field->getType();
00407
00408 if(dst_ftype != src_ftype)
00409 continue;
00410
00411 equal = true;
00412 found = false;
00413
00414 if(strstr(dst_ftype.getCName(), "Ptr") == NULL)
00415 {
00416
00417 std::string av, bv;
00418 dst_field->getValueByStr(av);
00419 src_field->getValueByStr(bv);
00420 if(av != bv)
00421 equal = false;
00422 }
00423 else
00424 {
00425 if(dst_field->getCardinality() == FieldType::SINGLE_FIELD)
00426 {
00427 if((((SFFieldContainerPtr *)dst_field)->getValue() !=
00428 ((SFFieldContainerPtr *)src_field)->getValue()))
00429 equal = false;
00430 }
00431 else if(dst_field->getCardinality() == FieldType::MULTI_FIELD)
00432 {
00433 UInt32 j, cn = ((MFFieldContainerPtr*)src_field)->size(),
00434 sn = ((MFFieldContainerPtr*)src_field)->size();
00435
00436 if (strcmp(fdesc->getCName(), "foregrounds") == 0)
00437 {
00438 MFForegroundPtr sFgndBag;
00439 MFForegroundPtr::iterator sFgndIt, cFgndIt;
00440 DisplayFilterForegroundPtr filterFgnd = NullFC;
00441
00442 sFgndIt = serverPort->getForegrounds().begin();
00443 cFgndIt = clientPort->getForegrounds().begin();
00444
00445 while (sFgndIt != serverPort->getForegrounds().end())
00446 {
00447 filterFgnd = DisplayFilterForegroundPtr::dcast(*sFgndIt);
00448
00449 if (filterFgnd != NullFC &&
00450 !filterFgnd->getServer().empty())
00451 found = true;
00452 else
00453 sFgndBag.push_back(*sFgndIt);
00454
00455 ++sFgndIt;
00456 }
00457
00458 if (sFgndBag.size() != clientPort->getForegrounds().size())
00459 {
00460 equal = false;
00461 }
00462 else
00463 {
00464 sFgndIt = sFgndBag.begin();
00465
00466 while (sFgndIt != sFgndBag.end() &&
00467 cFgndIt != clientPort->getForegrounds().end() &&
00468 *sFgndIt == *cFgndIt)
00469 {
00470 ++sFgndIt;
00471 ++cFgndIt;
00472 }
00473
00474 if (sFgndIt != sFgndBag.end() ||
00475 cFgndIt != clientPort->getForegrounds().end())
00476 equal = false;
00477 }
00478 }
00479 else
00480 {
00481 if(((MFFieldContainerPtr*)dst_field)->size() !=
00482 ((MFFieldContainerPtr*)src_field)->size()) {
00483 equal = false;
00484 }
00485 else {
00486 for(j=0;j < ((MFFieldContainerPtr*)dst_field)->size();++j)
00487 {
00488 if(((*(((MFFieldContainerPtr *)dst_field)))[j] !=
00489 (*(((MFFieldContainerPtr *)src_field)))[j]))
00490 equal = false;
00491 }
00492 }
00493 }
00494 }
00495 }
00496 if(equal == false)
00497 {
00498 beginEditCP(serverPort, mask);
00499 dst_field->setAbstrValue(*src_field);
00500 endEditCP(serverPort, mask);
00501
00502 if (found)
00503 {
00504 ClusterWindowPtr ptr(this);
00505
00506 beginEditCP(ptr, DirtyFieldMask);
00507 setDirty(true);
00508 endEditCP(ptr, DirtyFieldMask);
00509 }
00510 }
00511 }
00512 }
00513
00514
00515
00516
00517 #ifdef __sgi
00518 #pragma set woff 1174
00519 #endif
00520
00521 #ifdef OSG_LINUX_ICC
00522 #pragma warning( disable : 177 )
00523 #endif
00524
00525 namespace
00526 {
00527 static char cvsid_cpp[] = "@(#)$Id: $";
00528 static char cvsid_hpp[] = OSGMULTIDISPLAYCONFIG_HEADER_CVSID;
00529 static char cvsid_inl[] = OSGMULTIDISPLAYCONFIG_INLINE_CVSID;
00530 }