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 "OSGMultiDisplayWindow.h"
00054 #include "OSGConnection.h"
00055 #include "OSGNode.h"
00056
00057 #define FAST_SYNC 0
00058
00059 OSG_USING_NAMESPACE
00060
00065
00066
00069 MultiDisplayWindow::MultiDisplayWindow(void) :
00070 Inherited()
00071 {
00072 }
00073
00076 MultiDisplayWindow::MultiDisplayWindow(const MultiDisplayWindow &source) :
00077 Inherited(source)
00078 {
00079 }
00080
00083 MultiDisplayWindow::~MultiDisplayWindow(void)
00084 {
00085 }
00086
00087
00088
00091 void MultiDisplayWindow::initMethod (void)
00092 {
00093 }
00094
00097 void MultiDisplayWindow::changed(BitVector whichField, UInt32 origin)
00098 {
00099 Inherited::changed(whichField, origin);
00100 }
00101
00104 void MultiDisplayWindow::dump( UInt32 ,
00105 const BitVector ) const
00106 {
00107 SLOG << "hServers:" << getHServers() << " "
00108 << "vServers:" << getVServers() << std::endl;
00109 }
00110
00111
00112
00116 void MultiDisplayWindow::serverInit( WindowPtr ,
00117 UInt32 )
00118 {
00119 }
00120
00127 void MultiDisplayWindow::serverRender( WindowPtr serverWindow,
00128 UInt32 id,
00129 RenderActionBase *action )
00130 {
00131 TileCameraDecoratorPtr deco;
00132 ViewportPtr serverPort;
00133 ViewportPtr clientPort;
00134 StereoBufferViewportPtr clientStereoPort;
00135 UInt32 sv,cv;
00136 Int32 l,r,t,b;
00137 Int32 cleft,cright,ctop,cbottom;
00138
00139 if(!getHServers())
00140 {
00141 setHServers(getServers().size());
00142 }
00143 if(!getVServers())
00144 {
00145 setVServers(1);
00146 }
00147 UInt32 row =id/getHServers();
00148 UInt32 column=id%getHServers();
00149
00150 UInt32 width = serverWindow->getWidth() ;
00151 UInt32 height = serverWindow->getHeight();
00152 if(getWidth()==0)
00153 {
00154 setWidth( width*getHServers() );
00155 }
00156 if(getHeight()==0)
00157 {
00158 setHeight( height*getVServers() );
00159 }
00160 Int32 left = column * width - column * getXOverlap();
00161 Int32 bottom = row * height - row * getYOverlap();
00162 Int32 right = left + width - 1;
00163 Int32 top = bottom + height - 1;
00164 Real64 scaleCWidth = ((width - getXOverlap()) * (getHServers() - 1) + width) / (float)getWidth();
00165 Real64 scaleCHeight = ((height - getYOverlap())* (getVServers() - 1) + height)/ (float)getHeight();
00166
00167
00168 for(cv=0,sv=0;cv<getPort().size();cv++)
00169 {
00170 clientPort = getPort()[cv];
00171 clientStereoPort = StereoBufferViewportPtr::dcast(clientPort);
00172 cleft = (Int32)(clientPort->getPixelLeft() * scaleCWidth) ;
00173 cbottom = (Int32)(clientPort->getPixelBottom() * scaleCHeight) ;
00174 cright = (Int32)((clientPort->getPixelRight()+1) * scaleCWidth) -1;
00175 ctop = (Int32)((clientPort->getPixelTop()+1) * scaleCHeight)-1;
00176 if(cright < left ||
00177 cleft > right ||
00178 ctop < bottom ||
00179 cbottom > top )
00180 {
00181
00182 continue;
00183 }
00184
00185 l = osgMax(cleft ,left ) - left;
00186 b = osgMax(cbottom,bottom) - bottom;
00187 r = osgMin(cright ,right ) - left;
00188 t = osgMin(ctop ,top ) - bottom;
00189 if(serverWindow->getPort().size() <= sv)
00190 {
00191 serverPort = ViewportPtr::dcast(clientPort->shallowCopy());
00192 beginEditCP(serverPort);
00193 deco=TileCameraDecorator::create();
00194 beginEditCP(serverWindow);
00195 serverWindow->addPort(serverPort);
00196 serverPort->setCamera(deco);
00197 endEditCP(serverWindow);
00198 endEditCP(serverPort);
00199 }
00200 else
00201 {
00202 serverPort = serverWindow->getPort()[sv];
00203 deco=TileCameraDecoratorPtr::dcast(serverPort->getCamera());
00204 if(serverWindow->getPort()[sv]->getType() !=
00205 clientPort->getType())
00206 {
00207
00208 subRefCP(serverWindow->getPort()[sv]);
00209 serverPort = ViewportPtr::dcast(clientPort->shallowCopy());
00210 beginEditCP(serverWindow);
00211 serverWindow->getPort()[sv] = serverPort;
00212 serverPort->setCamera(deco);
00213 endEditCP(serverWindow);
00214 }
00215 else
00216 {
00217 deco=TileCameraDecoratorPtr::dcast(serverPort->getCamera());
00218 }
00219 }
00220
00221 updateViewport(serverPort,clientPort);
00222
00223 beginEditCP(serverPort,
00224 Viewport::LeftFieldMask|
00225 Viewport::BottomFieldMask|
00226 Viewport::RightFieldMask|
00227 Viewport::TopFieldMask);
00228 serverPort->setSize(Real32(l),Real32(b),Real32(r),Real32(t));
00229
00230 if(serverPort->getLeft() == 1.0)
00231 serverPort->setLeft(1.0001);
00232 if(serverPort->getRight() == 1.0)
00233 serverPort->setRight(1.0001);
00234 if(serverPort->getTop() == 1.0)
00235 serverPort->setTop(1.0001);
00236 if(serverPort->getBottom() == 1.0)
00237 serverPort->setBottom(1.0001);
00238 endEditCP(serverPort,
00239 Viewport::LeftFieldMask|
00240 Viewport::BottomFieldMask|
00241 Viewport::RightFieldMask|
00242 Viewport::TopFieldMask);
00243
00244 beginEditCP(deco);
00245 deco->setFullWidth ( cright-cleft );
00246 deco->setFullHeight( ctop-cbottom );
00247 deco->setSize( ( l+left-cleft ) / (float)( cright-cleft ),
00248 ( b+bottom-cbottom ) / (float)( ctop-cbottom ),
00249 ( r+left-cleft ) / (float)( cright-cleft ),
00250 ( t+bottom-cbottom ) / (float)( ctop-cbottom ) );
00251 deco->setDecoratee( clientPort->getCamera() );
00252 endEditCP(deco);
00253 sv++;
00254 }
00255
00256 while(serverWindow->getPort().size()>sv)
00257 {
00258 serverWindow->subPort(sv);
00259 }
00260 Inherited::serverRender(serverWindow,id,action);
00261 }
00262
00265 void MultiDisplayWindow::serverSwap( WindowPtr window,UInt32 id )
00266 {
00267 Connection *connection;
00268
00269
00270 UInt8 pixel[3];
00271 glReadPixels(0,0,
00272 1,1,
00273 GL_RGB,GL_UNSIGNED_BYTE,
00274 pixel);
00275 glFinish();
00276
00277 #if !FAST_SYNC
00278 connection=getNetwork()->getMainConnection();
00279 if(!getInterleave())
00280 {
00281
00282 connection->signal();
00283
00284 connection->wait();
00285 }
00286 #endif
00287 Inherited::serverSwap(window,id);
00288 }
00289
00290
00291
00297 void MultiDisplayWindow::clientInit( void )
00298 {
00299 bool changed = false;
00300 ViewportPtr vp,cvp;
00301
00302 if(getManageClientViewports() == false ||
00303 getClientWindow() == NullFC)
00304 return;
00305
00306
00307 if(getPort().size() == getClientWindow()->getPort().size())
00308 {
00309 for(UInt32 v = 0 ; v < getPort().size() && !changed ; v++)
00310 {
00311 vp = getPort(v);
00312 cvp = getClientWindow()->getPort(v);
00313 if( vp->getRoot() != cvp->getRoot() ||
00314 vp->getLeft() != cvp->getLeft() ||
00315 vp->getRight() != cvp->getRight() ||
00316 vp->getBottom() != cvp->getBottom() ||
00317 vp->getTop() != cvp->getTop() ||
00318 vp->getBackground() != cvp->getBackground() ||
00319 vp->getForegrounds().size() != cvp->getForegrounds().size() )
00320 changed = true;
00321 }
00322 }
00323 else
00324 {
00325 changed = true;
00326 }
00327
00328 if(changed)
00329 {
00330 beginEditCP(getClientWindow());
00331
00332 while(getClientWindow()->getPort().size())
00333 {
00334 vp = getClientWindow()->getPort(0);
00335 getClientWindow()->subPort(0);
00336 subRefCP(vp);
00337 }
00338
00339 for(UInt32 v=0 ; v<getPort().size() ;v++)
00340 {
00341 getClientWindow()->addPort(ViewportPtr::dcast(getPort(v)->shallowCopy()));
00342 }
00343 endEditCP(getClientWindow());
00344 }
00345 }
00346
00349 void MultiDisplayWindow::clientSwap( void )
00350 {
00351 Connection *connection=getNetwork()->getMainConnection();
00352
00353 #if FAST_SYNC
00354 connection->selectChannel();
00355 #else
00356 if(!getInterleave())
00357 {
00358
00359 connection->wait();
00360
00361 connection->signal();
00362 }
00363 #endif
00364
00365
00366 Inherited::clientSwap();
00367 }
00368
00369
00370
00371
00374 void MultiDisplayWindow::updateViewport(ViewportPtr &serverPort,
00375 ViewportPtr &clientPort)
00376 {
00377 bool equal;
00378
00379
00380 if(serverPort == clientPort)
00381 return;
00382 if(serverPort == NullFC || clientPort == NullFC)
00383 return;
00384 if(serverPort->getType() != serverPort->getType())
00385 return;
00386
00387 const FieldContainerType &type = serverPort->getType();
00388 UInt32 fcount = osgMin(serverPort->getType().getNumFieldDescs(),
00389 clientPort->getType().getNumFieldDescs());
00390
00391 for(UInt32 i=1;i <= fcount;++i)
00392 {
00393 const FieldDescription* fdesc = type.getFieldDescription(i);
00394
00395 if(strcmp(fdesc->getCName(), "parent") == 0 ||
00396 strcmp(fdesc->getCName(), "camera") == 0)
00397 continue;
00398
00399 BitVector mask = fdesc->getFieldMask();
00400
00401 Field *dst_field = serverPort->getField(i);
00402 Field *src_field = clientPort->getField(i);
00403
00404 const FieldType &dst_ftype = dst_field->getType();
00405 const FieldType &src_ftype = src_field->getType();
00406
00407 if(dst_ftype != src_ftype)
00408 continue;
00409
00410 equal = true;
00411
00412 if(strstr(dst_ftype.getCName(), "Ptr") == NULL)
00413 {
00414 if(dst_field->getCardinality() == FieldType::MULTI_FIELD)
00415 {
00416 std::string av, bv;
00417 dst_field->getValueByStr(av);
00418 src_field->getValueByStr(bv);
00419 if(av != bv)
00420 equal = false;
00421 }
00422 else
00423 {
00424
00425 std::string av, bv;
00426 dst_field->getValueByStr(av);
00427 src_field->getValueByStr(bv);
00428 if(av != bv)
00429 equal = false;
00430 }
00431 }
00432 else
00433 {
00434 if(dst_field->getCardinality() == FieldType::SINGLE_FIELD)
00435 {
00436 if((((SFFieldContainerPtr *)dst_field)->getValue() !=
00437 ((SFFieldContainerPtr *)src_field)->getValue()))
00438 equal = false;
00439 }
00440 else if(dst_field->getCardinality() == FieldType::MULTI_FIELD)
00441 {
00442 if(((MFFieldContainerPtr*)dst_field)->size() !=
00443 ((MFFieldContainerPtr*)src_field)->size())
00444 equal = false;
00445 for(UInt32 j=0;j < ((MFFieldContainerPtr*)dst_field)->size();++j)
00446 {
00447 if(((*(((MFFieldContainerPtr *)dst_field)))[j] !=
00448 (*(((MFFieldContainerPtr *)src_field)))[j]))
00449 equal = false;
00450 }
00451 }
00452 }
00453 if(equal == false)
00454 {
00455 beginEditCP(serverPort, mask);
00456 dst_field->setAbstrValue(*src_field);
00457 endEditCP(serverPort, mask);
00458 }
00459 }
00460 }
00461
00462
00463
00464
00465 #ifdef __sgi
00466 #pragma set woff 1174
00467 #endif
00468
00469 #ifdef OSG_LINUX_ICC
00470 #pragma warning( disable : 177 )
00471 #endif
00472
00473 namespace
00474 {
00475 static char cvsid_cpp[] = "@(#)$Id: $";
00476 static char cvsid_hpp[] = OSGMULTIDISPLAYCONFIG_HEADER_CVSID;
00477 static char cvsid_inl[] = OSGMULTIDISPLAYCONFIG_INLINE_CVSID;
00478 }