Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

OSGMultiDisplayWindow.cpp

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002  *                                OpenSG                                     *
00003  *                                                                           *
00004  *                                                                           *
00005  *             Copyright (C) 2000-2002 by the OpenSG Forum                   *
00006  *                                                                           *
00007  *                            www.opensg.org                                 *
00008  *                                                                           *
00009  *   contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de          *
00010  *                                                                           *
00011 \*---------------------------------------------------------------------------*/
00012 /*---------------------------------------------------------------------------*\
00013  *                                License                                    *
00014  *                                                                           *
00015  * This library is free software; you can redistribute it and/or modify it   *
00016  * under the terms of the GNU Library General Public License as published    *
00017  * by the Free Software Foundation, version 2.                               *
00018  *                                                                           *
00019  * This library is distributed in the hope that it will be useful, but       *
00020  * WITHOUT ANY WARRANTY; without even the implied warranty of                *
00021  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU         *
00022  * Library General Public License for more details.                          *
00023  *                                                                           *
00024  * You should have received a copy of the GNU Library General Public         *
00025  * License along with this library; if not, write to the Free Software       *
00026  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                 *
00027  *                                                                           *
00028 \*---------------------------------------------------------------------------*/
00029 /*---------------------------------------------------------------------------*\
00030  *                                Changes                                    *
00031  *                                                                           *
00032  *                                                                           *
00033  *                                                                           *
00034  *                                                                           *
00035  *                                                                           *
00036  *                                                                           *
00037 \*---------------------------------------------------------------------------*/
00038 
00039 //---------------------------------------------------------------------------
00040 //  Includes
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 /*----------------------- constructors & destructors ----------------------*/
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 /*----------------------------- class specific ----------------------------*/
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 /*----------------------------- server methods ----------------------------*/
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     // calculate width and height from local width and height
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     // duplicate viewports
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             // invisible on this server screen
00182             continue;
00183         }
00184         // calculate overlapping viewport
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                 // there is a viewport with the wrong type
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         // update changed viewport fields
00221         updateViewport(serverPort,clientPort);
00222         // set viewport size
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         // use pixel even if pixel = 1
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         // calculate tile parameters
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     // remove unused ports
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     // clear command buffers
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         // tell client that we are finish
00282         connection->signal();
00283         // wait for swap
00284         connection->wait();
00285     }
00286 #endif
00287     Inherited::serverSwap(window,id);
00288 }
00289 
00290 /*----------------------------- client methods ----------------------------*/
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     // check if something changed
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         // remove all viewports
00332         while(getClientWindow()->getPort().size())
00333         {
00334             vp = getClientWindow()->getPort(0);
00335             getClientWindow()->subPort(0);
00336             subRefCP(vp);
00337         }
00338         // duplicate viewports
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         // wait for all servers to finish
00359         connection->wait();
00360         // initiate swap
00361         connection->signal();
00362     }
00363 #endif
00364 
00365     // show client window 
00366     Inherited::clientSwap();
00367 }
00368 
00369 /*-------------------------------------------------------------------------*/
00370 /*                              helper                                     */
00371 
00374 void MultiDisplayWindow::updateViewport(ViewportPtr &serverPort,
00375                                         ViewportPtr &clientPort)
00376 {
00377     bool equal;
00378 
00379     // Compare the pointers.
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         // ignore attachments
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                 // This is very slow with multi fields!!!!
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 /*                              cvs id's                                   */
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 }

Generated on Thu Aug 25 04:07:48 2005 for OpenSG by  doxygen 1.4.3