1 /*---------------------------------------------------------------------------*\
5 * Copyright (C) 2000-2002 by the OpenSG Forum *
9 * contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de *
11 \*---------------------------------------------------------------------------*/
12 /*---------------------------------------------------------------------------*\
15 * This library is free software; you can redistribute it and/or modify it *
16 * under the terms of the GNU Library General Public License as published *
17 * by the Free Software Foundation, version 2. *
19 * This library is distributed in the hope that it will be useful, but *
20 * WITHOUT ANY WARRANTY; without even the implied warranty of *
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
22 * Library General Public License for more details. *
24 * You should have received a copy of the GNU Library General Public *
25 * License along with this library; if not, write to the Free Software *
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
28 \*---------------------------------------------------------------------------*/
29 /*---------------------------------------------------------------------------*\
37 \*---------------------------------------------------------------------------*/
39 //---------------------------------------------------------------------------
41 //---------------------------------------------------------------------------
45 #include "OSGConfig.h"
47 #include "OSGTileCameraDecorator.h"
48 #include "OSGViewport.h"
49 #include "OSGGeometry.h"
50 #include "OSGStereoBufferViewport.h"
51 #include "OSGSortFirstWindow.h"
52 #include "OSGClusterViewBuffer.h"
53 #include "OSGConnection.h"
54 #include "OSGRenderNode.h"
55 #include "OSGTileGeometryLoad.h"
56 #include "OSGClusterNetwork.h"
57 #include "OSGRenderActionBase.h"
61 ClusterViewBuffer
SortFirstWindow::_bufferHandler
;
63 // #define USE_VPORT_SLICES
65 /*! \class OSG::SortFirstWindow
66 \ingroup GrpSystemCluster
67 Cluster rendering configuration for sort first image composition
70 /*----------------------- constructors & destructors ----------------------*/
74 SortFirstWindow::SortFirstWindow(void) :
76 _tileLoadBalancer(NULL
),
83 SortFirstWindow::SortFirstWindow(const SortFirstWindow
&source
) :
85 _tileLoadBalancer(NULL
),
92 SortFirstWindow::~SortFirstWindow(void)
95 delete _tileLoadBalancer
;
100 /*----------------------------- class specific ----------------------------*/
102 //! initialize the static features of the class, e.g. action callbacks
104 void SortFirstWindow::initMethod(InitPhase ePhase
)
106 Inherited::initMethod(ePhase
);
109 //! react to field changes
111 void SortFirstWindow::changed(ConstFieldMaskArg whichField
,
115 Inherited::changed(whichField
, origin
, details
);
118 //! output the instance for debug purposes
120 void SortFirstWindow::dump( UInt32
,
121 const BitVector
) const
123 SLOG
<< "Dump SortFirstWindow NI" << std::endl
;
126 /*----------------------------- server methods ----------------------------*/
128 /** transfer server cababilities to the client
131 void SortFirstWindow::serverInit(Window
*serverWindow
,
138 RenderNode renderNode
;
139 Connection
*connection
=getNetwork()->getMainConnection();
141 // create cluster node information
143 renderNode
.determinePerformance(serverWindow
);
145 // transfer to client for load balancing
146 connection
->putValue(id
);
147 renderNode
.copyToBin(*connection
);
149 connection
->selectChannel();
150 connection
->getValue(sync
);
154 #ifdef OSG_OLD_RENDER_ACTION
155 /** update server window
157 * todo: enamble frustum culling if error is removed
159 void SortFirstWindow::serverRender( Window
*serverWindow
,
161 DrawActionBase
*action
)
163 TileCameraDecoratorPtr deco
;
164 ViewportPtr serverPort
;
165 ViewportPtr clientPort
;
166 UInt32 sv
,cv
,regionStart
;
170 // duplicate viewports
171 for(cv
=0,sv
=0;cv
<getPort().size();cv
++)
173 clientPort
= getPort()[cv
];
174 if(serverWindow
->getPort().size() <= sv
)
177 //serverPort = StereoBufferViewport::create();
178 serverPort
= dynamic_cast<ViewportPtr
>(clientPort
->shallowCopy());
179 deco
=TileCameraDecorator::create();
181 serverWindow
->addPort(serverPort
);
182 serverPort
->setCamera(deco
);
186 serverPort
= serverWindow
->getPort()[sv
];
187 deco
=dynamic_cast<TileCameraDecoratorPtr
>(serverPort
->getCamera());
188 if(serverWindow
->getPort()[sv
]->getType() !=
189 clientPort
->getType())
191 // there is a viewport with the wrong type
192 serverPort
= dynamic_cast<ViewportPtr
>(clientPort
->shallowCopy());
193 serverWindow
->replacePort(sv
, serverPort
);//[sv] = serverPort;
194 serverPort
->setCamera(deco
);
198 deco
=dynamic_cast<TileCameraDecoratorPtr
>(serverPort
->getCamera());
200 //serverPort = serverWindow->getPort()[sv];
201 //deco=TileCameraDecoratorPtr::dcast(serverPort->getCamera());
205 regionStart
=cv
* getServers().size() * 4 + id
* 4;
207 Real32(getRegion()[regionStart
+0] + clientPort
->getPixelLeft()),
208 Real32(getRegion()[regionStart
+1] + clientPort
->getPixelBottom()),
209 Real32(getRegion()[regionStart
+2] + clientPort
->getPixelLeft()),
210 Real32(getRegion()[regionStart
+3] + clientPort
->getPixelBottom()));
212 serverPort
->setRoot ( clientPort
->getRoot() );
213 serverPort
->setBackground( clientPort
->getBackground() );
215 serverPort
->assignForegrounds(clientPort
->getForegrounds());
217 serverPort
->setTravMask ( clientPort
->getTravMask() );
219 // calculate tile parameters
220 vpWidth
=clientPort
->getPixelWidth();
221 vpHeight
=clientPort
->getPixelHeight();
223 deco
->setFullWidth ( vpWidth
);
224 deco
->setFullHeight( vpHeight
);
225 deco
->setSize( getRegion()[ regionStart
+0 ]/(float)vpWidth
,
226 getRegion()[ regionStart
+1 ]/(float)vpHeight
,
227 getRegion()[ regionStart
+2 ]/(float)vpWidth
,
228 getRegion()[ regionStart
+3 ]/(float)vpHeight
);
229 deco
->setDecoratee( clientPort
->getCamera() );
233 // remove unused ports
234 while(serverWindow
->getPort().size()>sv
)
236 serverWindow
->subPort(sv
);
239 Inherited::serverRender(serverWindow
,id
,action
);
244 if(getCompression().empty())
246 _bufferHandler
.setImgTransType(NULL
);
250 _bufferHandler
.setImgTransType(getCompression().c_str());
254 _bufferHandler
.setSubtileSize(getSubtileSize());
259 glDisable(GL_SCISSOR_TEST
);
260 glClearColor(0,0,0,0);
261 glClear(GL_COLOR_BUFFER_BIT
);
264 // render the viewports
265 serverWindow
->activate();
266 serverWindow
->frameInit();
267 action
->setWindow( serverWindow
);
268 for(sv
=0;sv
<serverWindow
->getPort().size();++sv
)
270 ViewportPtr vp
=serverWindow
->getPort()[sv
];
271 vp
->render( action
);
273 // send resulting image
276 // activate the appropriate viewport to retrieve image
281 *getNetwork()->getMainPointConnection(),
282 ClusterViewBuffer::RGB
,
284 vp
->getPixelBottom(),
289 // deactivate the viewport
296 void SortFirstWindow::serverRender( Window
*serverWindow
,
298 RenderActionBase
*action
)
300 TileCameraDecoratorUnrecPtr deco
;
301 ViewportUnrecPtr serverPort
;
302 Viewport
*clientPort
;
303 UInt32 sv
,cv
,regionStart
;
307 // duplicate viewports
308 for(cv
=0,sv
=0;cv
<getMFPort()->size();cv
++)
310 clientPort
= getPort(cv
);
311 if(serverWindow
->getMFPort()->size() <= sv
)
314 //serverPort = StereoBufferViewport::create();
316 dynamic_pointer_cast
<Viewport
>(clientPort
->shallowCopy());
317 deco
=TileCameraDecorator::create();
319 serverWindow
->addPort(serverPort
);
320 serverPort
->setCamera(deco
);
324 serverPort
= serverWindow
->getPort(sv
);
325 deco
=dynamic_cast<TileCameraDecorator
*>(serverPort
->getCamera());
326 if(serverWindow
->getPort(sv
)->getType() !=
327 clientPort
->getType())
329 // there is a viewport with the wrong type
330 serverPort
= dynamic_pointer_cast
<Viewport
>(
331 clientPort
->shallowCopy());
333 serverWindow
->replacePort(sv
,
334 serverPort
);//[sv] = serverPort;
335 serverPort
->setCamera(deco
);
339 deco
=dynamic_cast<TileCameraDecorator
*>(
340 serverPort
->getCamera());
342 //serverPort = serverWindow->getPort()[sv];
343 //deco=TileCameraDecoratorPtr::dcast(serverPort->getCamera());
347 regionStart
=cv
* getMFServers()->size32() * 4 + id
* 4;
349 Real32(getRegion(regionStart
+0) + clientPort
->calcPixelLeft()),
350 Real32(getRegion(regionStart
+1) + clientPort
->calcPixelBottom()),
351 Real32(getRegion(regionStart
+2) + clientPort
->calcPixelLeft()),
352 Real32(getRegion(regionStart
+3) + clientPort
->calcPixelBottom()));
354 serverPort
->setRoot ( clientPort
->getRoot() );
355 serverPort
->setBackground( clientPort
->getBackground() );
357 serverPort
->assignForegrounds(*(clientPort
->getMFForegrounds()));
359 serverPort
->setTravMask ( clientPort
->getTravMask() );
361 // calculate tile parameters
362 vpWidth
=clientPort
->calcPixelWidth();
363 vpHeight
=clientPort
->calcPixelHeight();
365 deco
->setFullWidth ( vpWidth
);
366 deco
->setFullHeight( vpHeight
);
367 deco
->setSize( getRegion( regionStart
+0 )/Real32(vpWidth
),
368 getRegion( regionStart
+1 )/Real32(vpHeight
),
369 getRegion( regionStart
+2 )/Real32(vpWidth
),
370 getRegion( regionStart
+3 )/Real32(vpHeight
) );
371 deco
->setDecoratee( clientPort
->getCamera() );
375 // remove unused ports
376 while(serverWindow
->getMFPort()->size()>sv
)
378 serverWindow
->subPort(sv
);
381 Inherited::serverRender(serverWindow
,id
,action
);
386 if(getCompression().empty())
388 _bufferHandler
.setImgTransType(NULL
);
392 _bufferHandler
.setImgTransType(getCompression().c_str());
396 _bufferHandler
.setSubtileSize(getSubtileSize());
401 glDisable(GL_SCISSOR_TEST
);
402 glClearColor(0,0,0,0);
403 glClear(GL_COLOR_BUFFER_BIT
);
406 // render the viewports
407 serverWindow
->activate();
408 serverWindow
->frameInit();
409 action
->setWindow( serverWindow
);
410 for(sv
=0;sv
<serverWindow
->getMFPort()->size();++sv
)
412 Viewport
*vp
=serverWindow
->getPort(sv
);
413 vp
->render( action
);
415 // send resulting image
418 // activate the appropriate viewport to retrieve image
423 *getNetwork()->getMainPointConnection(),
424 ClusterViewBuffer::RGB
,
426 vp
->calcPixelBottom(),
427 vp
->calcPixelRight(),
431 // deactivate the viewport
437 /*! send image to client
439 void SortFirstWindow::serverSwap( Window
*window
,
444 Connection
*connection
=getNetwork()->getMainConnection();
445 connection
->signal();
451 /*----------------------------- client methods ----------------------------*/
453 /*! read server cababilities
456 void SortFirstWindow::clientInit( void )
462 RenderNode renderNode
;
463 GroupConnection
*connection
= getNetwork()->getMainGroupConnection();
464 Connection::Channel channel
;
466 _tileLoadBalancer
=new TileLoadBalancer(getUseFaceDistribution());
467 // read all node infos
468 for(UInt32 i
=0;i
<connection
->getChannelCount();++i
)
471 channel
= connection
->selectChannel();
472 connection
->subSelection(channel
);
473 connection
->getValue(id
);
474 renderNode
.copyFromBin(*connection
);
476 _tileLoadBalancer
->addRenderNode(renderNode
,id
);
478 connection
->resetSelection();
481 connection
->putValue(id
);
485 Inherited::clientInit();
488 /*! client frame init
491 void SortFirstWindow::clientPreSync( void )
495 // get window size from client window
496 if(getClientWindow() != NULL
)
498 if(getWidth() != getClientWindow()->getWidth() ||
499 getHeight() != getClientWindow()->getHeight())
501 setSize(getClientWindow()->getWidth(),
502 getClientWindow()->getHeight());
515 TileLoadBalancer::ResultT region
;
517 editMFRegion()->clear();
519 for(cv
=0;cv
<getPort().size();cv
++)
521 int s
=getServers().size();
524 editRegion().push_back(i
/float(s
)*getWidth());
525 editRegion().push_back(0);
526 editRegion().push_back((i
+1)/float(s
)*getWidth());
527 editRegion().push_back(1*getHeight());
531 for(cv
=0;cv
<getMFPort()->size();cv
++)
533 _tileLoadBalancer
->update( getPort(cv
)->getRoot() );
534 _tileLoadBalancer
->balance(getPort(cv
),
537 for(i
=0;i
<getMFServers()->size();i
++)
539 editMFRegion()->push_back(region
[i
].x1
);
540 editMFRegion()->push_back(region
[i
].y1
);
541 editMFRegion()->push_back(region
[i
].x2
);
542 editMFRegion()->push_back(region
[i
].y2
);
547 Inherited::clientPreSync();
550 #ifdef OSG_OLD_RENDER_ACTION
553 * one tile is rendered by the client
556 void SortFirstWindow::clientRender( RenderActionBase
* /* action */ )
558 // Inherited::clientRender(action);
562 void SortFirstWindow::clientRender(RenderActionBase
* /* action */)
564 // Inherited::clientRender(action);
570 void SortFirstWindow::clientSwap( void )
573 GroupConnection
*connection
=getNetwork()->getMainGroupConnection();
576 if(getClientWindow()!=NULL
)
578 // receive all viewports
579 for(cv
=0;cv
<getMFPort()->size();++cv
)
581 Viewport
*vp
=getPort(cv
);
583 // activate the appropriate viewport to receive image
587 _bufferHandler
.recv(*connection
);
589 // deactivate the viewport
592 Inherited::clientSwap();
598 connection
->signal();