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 //---------------------------------------------------------------------------
47 #include "OSGConfig.h"
49 #include "OSGParallelComposer.h"
54 /***************************************************************************\
56 \***************************************************************************/
58 /*! \class OSG::ParallelComposer
62 /***************************************************************************\
64 \***************************************************************************/
66 /***************************************************************************\
68 \***************************************************************************/
70 void ParallelComposer::initMethod(InitPhase ePhase
)
72 Inherited::initMethod(ePhase
);
76 /***************************************************************************\
78 \***************************************************************************/
80 /*-------------------------------------------------------------------------*\
82 \*-------------------------------------------------------------------------*/
84 /*----------------------- constructors & destructors ----------------------*/
86 ParallelComposer::ParallelComposer(void) :
96 #ifdef OSG_WITH_PARALLEL
103 ParallelComposer::ParallelComposer(const ParallelComposer
&source
) :
112 _createContext(false )
113 #ifdef OSG_WITH_PARALLEL
120 ParallelComposer::~ParallelComposer(void)
124 /*----------------------------- features ----------------------------------*/
126 bool ParallelComposer::clientRendering(void)
131 bool ParallelComposer::getClientRendering(void)
136 UInt32
ParallelComposer::getUsableServers(void)
138 return _usableServers
;
140 /*----------------------------- composition -------------------------------*/
142 void ParallelComposer::open(void)
144 #ifdef OSG_WITH_PARALLEL
145 if(getPcLibPath() != "")
147 pcSysInitialize(getPcLibPath().c_str(), 123458);
151 char *pc
= getenv("PCLIB_PATH");
153 pcSysInitialize(pc
, 123458);
155 pcSysInitialize(".", 123458);
158 // Initialize buffers
162 _createContext
= true;
164 // determine usable servers
165 _usableServers
= serverCount();
167 // create server cross connection
168 _clusterWindow
->getNetwork()->connectAllPointToPoint(clusterId(),
170 // do not buffer any data
171 for(UInt32 i
=0 ; i
<= serverCount() ; ++i
)
172 clusterWindow()->getNetwork()->getConnection(i
)->forceDirectIO();
173 // populate server list from inherited cluster window
174 osgGetHostname(_serviceAddr
, sizeof(_serviceAddr
));
176 _serverList
= new char*[_usableServers
+2];
177 _serverList
[0] = _serviceAddr
;
179 for(; i
<_usableServers
+1; i
++)
181 _serverList
[i
] = (char*)clusterWindow()->getServers(i
-1).c_str();
183 _serverList
[i
]= NULL
;
187 void ParallelComposer::composeViewport(Viewport
*port
)
189 #ifdef OSG_WITH_PARALLEL
192 pl
=port
->getPixelLeft(),
193 pr
=port
->getPixelRight(),
194 pb
=port
->getPixelBottom(),
195 pt
=port
->getPixelTop();
196 if(_wWidth
!= pr
-pl
+1 || _wHeight
!= pt
-pb
+1)
200 _createContext
= true;
202 bool full
= port
->isFullWindow();
203 glViewport(pl
, pb
, _wWidth
, _wHeight
);
204 glScissor(pl
, pb
, _wWidth
, _wHeight
);
206 glEnable(GL_SCISSOR_TEST
);
208 GLboolean depth
= glIsEnabled(GL_DEPTH_TEST
);
209 GLboolean blend
= glIsEnabled(GL_BLEND
);
211 glDisable(GL_DEPTH_TEST
);
214 glMatrixMode(GL_PROJECTION
);
217 glOrtho(0, port
->getPixelWidth(),
218 0, port
->getPixelHeight(),-1,1);
223 _createContext
= false;
229 glBlendFunc(GL_SRC_ALPHA
, GL_ONE_MINUS_SRC_ALPHA
);
234 UInt32 id
= beginFrame();
241 if(clusterId() < _usableServers
)
243 UInt32 id
= beginFrame();
250 glMatrixMode(GL_MODELVIEW
);
252 glEnable(GL_DEPTH_TEST
);
255 if(depth
&& !glIsEnabled(GL_DEPTH_TEST
))
256 glEnable(GL_DEPTH_TEST
);
257 if(!blend
&& glIsEnabled(GL_BLEND
))
262 void ParallelComposer::close(void)
264 #ifdef OSG_WITH_PARALLEL
265 pcContextDestroy(_context
);
270 /*----------------------------- class specific ----------------------------*/
272 void ParallelComposer::changed(ConstFieldMaskArg whichField
,
276 Inherited::changed(whichField
, origin
, details
);
279 void ParallelComposer::dump( UInt32
,
280 const BitVector
) const
282 SLOG
<< "Dump ParallelComposer NI" << std::endl
;
285 /*----------------------------- helpers ----------------------------------*/
287 void ParallelComposer::createCtx( Viewport
*port
)
289 #ifdef OSG_WITH_PARALLEL
290 // get needed attributes from viewport
295 attribs
[i
++] = PC_FRAME_WIDTH
; attribs
[i
++] = _wWidth
;
296 attribs
[i
++] = PC_FRAME_HEIGHT
; attribs
[i
++] = _wHeight
;
297 attribs
[i
++] = PC_COMPOSITE_TYPE
; attribs
[i
++] = PC_COMP_DEPTH
;
298 attribs
[i
++] = PC_PIXEL_FORMAT
; attribs
[i
++] = PC_PF_BGRA8
|PC_PF_Z32I
;
299 // maybe this will change?
300 attribs
[i
++] = PC_OUTPUT_DEPTH
; attribs
[i
++] = 1;
301 // maybe more, force depth? compression?
302 attribs
[i
++] = PC_ATTRIB_END
;
306 // we need a global context
307 err
= pcContextCreateGlobal(attribs
, _serverList
, _serviceAddr
, &_context
);
310 SLOG
<< "Error creating global context" << std::endl
;
315 // create a local context
316 err
= pcContextCreateLocal(PC_ID_DEFAULT
, _serviceAddr
, &_context
);
319 SLOG
<< "Error creating local context" << std::endl
;
325 pcContextSetInteger(_context
,PC_OUTPUT_LEFT
,PC_LOCALHOST_INDEX
,0);
326 pcContextSetInteger(_context
,PC_OUTPUT_TOP
,PC_LOCALHOST_INDEX
,0);
327 pcContextSetInteger(_context
,PC_OUTPUT_WIDTH
,PC_LOCALHOST_INDEX
,_wWidth
);
328 pcContextSetInteger(_context
,PC_OUTPUT_HEIGHT
,PC_LOCALHOST_INDEX
,_wHeight
);
333 _bufColor
= new UInt8
[_wWidth
* _wHeight
* 4 * sizeof(GLubyte
)];
337 _bufDepth
= new UInt8
[_wWidth
* _wHeight
* sizeof(GLuint
)];
341 void ParallelComposer::endFrame(UInt32 id
)
343 #ifdef OSG_WITH_PARALLEL
347 /* send the pixels */
348 err
= pcFrameAddFramelet(_context
,id
,_bufColor
,_bufDepth
);
351 SLOG
<< "Error adding framelet in endFrame" << std::endl
;
355 /* done with the frame */
356 err
= pcFrameEnd(_context
,id
);
359 SLOG
<< "Error while calling pcFrameEnd" << std::endl
;
363 /* grab the results */
364 err
= pcFrameResult(_context
,id
,0,0,_wWidth
,_wHeight
,reinterpret_cast<void**>(&_bufRet
),NULL
,
368 SLOG
<< "Error while getting frame results" << std::endl
;
375 UInt32
ParallelComposer::beginFrame(void)
378 #ifdef OSG_WITH_PARALLEL
381 /* start the frame (all framelets are full size thus, NULLs) */
382 err
= pcFrameBegin(_context
, &id
, 1, NULL
, NULL
, NULL
, NULL
, NULL
);
385 SLOG
<< "Error while calling beginFrame" << std::endl
;
391 void ParallelComposer::drawFrame(void)
393 #ifdef OSG_WITH_PARALLEL
396 if (!_bufRet
) return;
397 glDisable(GL_DEPTH_TEST
);
398 glPixelStorei(GL_UNPACK_ROW_LENGTH
,_rowPixels
);
399 glDrawPixels(_wWidth
,_wHeight
,GL_BGRA
,GL_UNSIGNED_BYTE
,_bufRet
);
400 glEnable(GL_DEPTH_TEST
);
407 void ParallelComposer::renderRead(void)
409 #ifdef OSG_WITH_PARALLEL
410 /* readback the pixels */
411 glPixelStorei(GL_PACK_ROW_LENGTH
,_wWidth
);
412 glReadPixels(0,0,_wWidth
,_wHeight
,GL_BGRA
,GL_UNSIGNED_BYTE
,_bufColor
);
413 glReadPixels(0,0,_wWidth
,_wHeight
,GL_DEPTH_COMPONENT
,GL_UNSIGNED_INT
,