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 //---------------------------------------------------------------------------
46 #include "OSGConfig.h"
47 #include "OSGCamera.h"
50 #include "OSGImageComposer.h"
54 /** \class OSG::ImageComposer
55 * \ingroup GrpSystemCluster
56 * \brief Cluster image composition implementation
58 * An ImageComposer class is used to compose multiple images into
59 * a final image. Each cluster server produces one part of the
60 * image. This class is abstract. Derived classes should implement
61 * composition over network or other cluster interconnects.
65 /*-------------------------------------------------------------------------*/
66 /* window functions */
68 void ImageComposer::initMethod(InitPhase ePhase
)
70 Inherited::initMethod(ePhase
);
73 void ImageComposer::exitMethod(InitPhase ePhase
)
75 Inherited::exitMethod(ePhase
);
79 /***************************************************************************\
81 \***************************************************************************/
83 /*-------------------------------------------------------------------------*\
85 \*-------------------------------------------------------------------------*/
87 /*----------------------- constructors & destructors ----------------------*/
89 ImageComposer::ImageComposer(void) :
101 ImageComposer::ImageComposer(const ImageComposer
&source
) :
104 _isClient (source
._isClient
),
105 _clusterId (source
._clusterId
),
106 _clusterSize (source
._clusterSize
),
107 _serverCount (source
._serverCount
),
108 _localWindow (source
._localWindow
),
109 _clusterWindow(source
._clusterWindow
)
113 ImageComposer::~ImageComposer(void)
117 /*----------------------------- class specific ----------------------------*/
119 void ImageComposer::changed(ConstFieldMaskArg whichField
,
123 Inherited::changed(whichField
, origin
, details
);
126 void ImageComposer::dump( UInt32
,
127 const BitVector
) const
129 SLOG
<< "Dump ImageComposer NI" << std::endl
;
132 /*----------------------------- setup ------------------------------------*/
134 /*! initialize the composer
136 void ImageComposer::setup(bool bIsClient
,
138 Window
*pLocalWindow
,
139 ClusterWindow
*pClusterWindow
)
141 _isClient
= bIsClient
;
142 _clusterId
= uiClusterId
;
143 _localWindow
= pLocalWindow
;
144 _clusterWindow
= pClusterWindow
;
145 _clusterSize
= pClusterWindow
->getMFServers()->size32() + 1;
146 _serverCount
= pClusterWindow
->getMFServers()->size32();
149 /*----------------------------- composition ------------------------------*/
153 void ImageComposer::open(void)
157 /*! called after sync, before rendering
159 void ImageComposer::startFrame(void)
163 /*! called before rendering to a viewport. This can be used to
164 synchronize some actions during rendering
166 void ImageComposer::startViewport(Viewport
*)
170 /*! compose singel viewport
172 void ImageComposer::composeViewport(Viewport
*port
)
176 /*! compose whole window
178 void ImageComposer::composeWindow(void)
184 void ImageComposer::close(void)
188 /*----------------------------- features ---------------------------------*/
190 /*! The default is that the cluster window should render on the
191 client side. Overload this method if the composer is not
192 able to handle client rendering.
195 bool ImageComposer::getClientRendering(void)
200 /*! Return the number of Servers that can be uses by the composer
203 UInt32
ImageComposer::getUsableServers(void)
205 return serverCount();
208 /*----------------------------- helpers ----------------------------------*/
210 /*! get screen aligned bounding box of the given geometrie.
211 width and hight are given in pixels. depth is given as
212 uint32. Returns false if the node is invisible
214 bool ImageComposer::getScreenAlignedBBox(Node
*node
,
223 UInt32 width
= vp
->calcPixelWidth();
224 UInt32 height
= vp
->calcPixelHeight();
227 Real32 rNear
= vp
->getCamera()->getNear();
230 Real32 minx
=0,miny
=0,minz
=0;
231 Real32 maxx
=0,maxy
=0,maxz
=0;
234 vp
->getCamera()->getViewing (viewing
,width
,height
);
235 vp
->getCamera()->getProjection(projection
,width
,height
);
239 // get whole transformation
240 Matrix m
=node
->getToWorld();
242 // get transformed volume
243 node
->updateVolume();
244 BoxVolume volume
= node
->getVolume();
255 volume
.getBounds(vol
[0], vol
[1]);
257 if(vol
[0][2] > -rNear
)
259 if(vol
[1][2] > -rNear
)
261 // volume lays on the fron clipping plane
267 // volume lays on the visible side of the clipping plane
268 node
->getVolume().getBounds(vol
[0], vol
[1]);
269 m
.multLeft(projection
);
272 // create corners of a bounding box
275 p
->multFull(Pnt3f( vol
[ (i
)&1 ][0] ,
277 vol
[ (i
>>2)&1 ][2]) , pnt
);
280 if(minx
> pnt
[0]) minx
= pnt
[0];
281 if(miny
> pnt
[1]) miny
= pnt
[1];
282 if(minz
> pnt
[2]) minz
= pnt
[2];
283 if(maxx
< pnt
[0]) maxx
= pnt
[0];
284 if(maxy
< pnt
[1]) maxy
= pnt
[1];
285 if(maxz
< pnt
[2]) maxz
= pnt
[2];
289 maxx
= minx
= pnt
[0];
290 maxy
= miny
= pnt
[1];
291 maxz
= minz
= pnt
[2];
296 if(maxx
<-1 || maxy
<-1 ||
303 minx
=width
* ( minx
+ 1.0 ) / 2.0 - .5;
304 maxx
=width
* ( maxx
+ 1.0 ) / 2.0 + .5;
305 miny
=height
* ( miny
+ 1.0 ) / 2.0 - .5;
306 maxy
=height
* ( maxy
+ 1.0 ) / 2.0 + .5;
308 if(minx
< 0 ) minx
= 0;
309 if(maxx
>= width
) maxx
= width
-1;
311 if(miny
< 0 ) miny
= 0;
312 if(maxy
>= height
) maxy
= height
-1;
320 maxz = 1 / (2.0 / (maxz+1));
321 minz = 1 / (2.0 / (minz+1));
324 front
= UInt32( double((UInt64(1))<<32) * (minz
+1) / 2);
325 back
= UInt32( double((UInt64(1))<<32) * (maxz
+1) / 2);
331 glMatrixMode(GL_PROJECTION
);
337 glDisable(GL_DEPTH_TEST
);
338 glEnable(GL_COLOR_MATERIAL
);
339 glBegin(GL_LINE_LOOP
);
346 glDisable(GL_COLOR_MATERIAL
);
347 glEnable(GL_DEPTH_TEST
);
349 glMatrixMode(GL_MODELVIEW
);