fixed: auto_ptr -> unique_ptr
[opensg.git] / Source / System / Cluster / Window / SortLast / OSGParallelComposer.cpp
blobec76f0a65ce02f93b6a739802c4fd9db1ccc7179
1 /*---------------------------------------------------------------------------*\
2 * OpenSG *
3 * *
4 * *
5 * Copyright (C) 2000-2002 by the OpenSG Forum *
6 * *
7 * www.opensg.org *
8 * *
9 * contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de *
10 * *
11 \*---------------------------------------------------------------------------*/
12 /*---------------------------------------------------------------------------*\
13 * License *
14 * *
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. *
18 * *
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. *
23 * *
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. *
27 * *
28 \*---------------------------------------------------------------------------*/
29 /*---------------------------------------------------------------------------*\
30 * Changes *
31 * *
32 * *
33 * *
34 * *
35 * *
36 * *
37 \*---------------------------------------------------------------------------*/
39 //---------------------------------------------------------------------------
40 // Includes
41 //---------------------------------------------------------------------------
43 #include <stdlib.h>
44 #include <stdio.h>
45 #include <iostream>
47 #include "OSGConfig.h"
49 #include "OSGParallelComposer.h"
52 OSG_USING_NAMESPACE
54 /***************************************************************************\
55 * Description *
56 \***************************************************************************/
58 /*! \class OSG::ParallelComposer
62 /***************************************************************************\
63 * Class variables *
64 \***************************************************************************/
66 /***************************************************************************\
67 * Class methods *
68 \***************************************************************************/
70 void ParallelComposer::initMethod(InitPhase ePhase)
72 Inherited::initMethod(ePhase);
76 /***************************************************************************\
77 * Instance methods *
78 \***************************************************************************/
80 /*-------------------------------------------------------------------------*\
81 - private -
82 \*-------------------------------------------------------------------------*/
84 /*----------------------- constructors & destructors ----------------------*/
86 ParallelComposer::ParallelComposer(void) :
87 Inherited ( ),
88 _usableServers(0 ),
89 _wWidth (0 ),
90 _wHeight (0 ),
91 _serverList (NULL ),
92 _bufColor (NULL ),
93 _bufDepth (NULL ),
94 _bufRet (NULL ),
95 _createContext(false)
96 #ifdef OSG_WITH_PARALLEL
97 , _rowPixels(0 )
98 , _context (NULL)
99 #endif
103 ParallelComposer::ParallelComposer(const ParallelComposer &source) :
104 Inherited (source),
105 _usableServers(0 ),
106 _wWidth (0 ),
107 _wHeight (0 ),
108 _serverList (NULL ),
109 _bufColor (NULL ),
110 _bufDepth (NULL ),
111 _bufRet (NULL ),
112 _createContext(false )
113 #ifdef OSG_WITH_PARALLEL
114 , _rowPixels(0 )
115 , _context (NULL)
116 #endif
120 ParallelComposer::~ParallelComposer(void)
124 /*----------------------------- features ----------------------------------*/
126 bool ParallelComposer::clientRendering(void)
128 return false;
131 bool ParallelComposer::getClientRendering(void)
133 return false;
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);
149 else
151 char *pc = getenv("PCLIB_PATH");
152 if(pc!= NULL)
153 pcSysInitialize(pc, 123458);
154 else
155 pcSysInitialize(".", 123458);
158 // Initialize buffers
159 _bufColor = NULL;
160 _bufDepth = NULL;
161 _bufRet = NULL;
162 _createContext = true;
164 // determine usable servers
165 _usableServers = serverCount();
167 // create server cross connection
168 _clusterWindow->getNetwork()->connectAllPointToPoint(clusterId(),
169 "StreamSock");
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;
178 int i = 1;
179 for(; i<_usableServers+1; i++)
181 _serverList[i] = (char*)clusterWindow()->getServers(i-1).c_str();
183 _serverList[i]= NULL;
184 #endif
187 void ParallelComposer::composeViewport(Viewport *port)
189 #ifdef OSG_WITH_PARALLEL
190 // setup viewport
191 GLint
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)
198 _wWidth = pr-pl+1;
199 _wHeight= pt-pb+1;
200 _createContext = true;
202 bool full = port->isFullWindow();
203 glViewport(pl, pb, _wWidth, _wHeight);
204 glScissor(pl, pb, _wWidth, _wHeight);
205 if(! full)
206 glEnable(GL_SCISSOR_TEST);
208 GLboolean depth = glIsEnabled(GL_DEPTH_TEST);
209 GLboolean blend = glIsEnabled(GL_BLEND);
211 glDisable(GL_DEPTH_TEST);
212 glPushMatrix();
213 glLoadIdentity();
214 glMatrixMode(GL_PROJECTION);
215 glPushMatrix();
216 glLoadIdentity();
217 glOrtho(0, port->getPixelWidth(),
218 0, port->getPixelHeight(),-1,1);
220 if(_createContext)
222 createCtx(port);
223 _createContext = false;
226 if(getAlpha())
228 glEnable(GL_BLEND);
229 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
232 if(isClient())
234 UInt32 id = beginFrame();
235 renderRead();
236 endFrame(id);
237 drawFrame();
239 else
241 if(clusterId() < _usableServers)
243 UInt32 id = beginFrame();
244 renderRead();
245 endFrame(id);
246 //drawFrame();
249 glPopMatrix();
250 glMatrixMode(GL_MODELVIEW);
251 glPopMatrix();
252 glEnable(GL_DEPTH_TEST);
254 // reset state
255 if(depth && !glIsEnabled(GL_DEPTH_TEST))
256 glEnable(GL_DEPTH_TEST);
257 if(!blend && glIsEnabled(GL_BLEND))
258 glDisable(GL_BLEND);
259 #endif
262 void ParallelComposer::close(void)
264 #ifdef OSG_WITH_PARALLEL
265 pcContextDestroy(_context);
266 pcSysFinalize();
267 #endif
270 /*----------------------------- class specific ----------------------------*/
272 void ParallelComposer::changed(ConstFieldMaskArg whichField,
273 UInt32 origin,
274 BitVector details)
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
291 PCint attribs[40];
292 UInt32 i = 0;
293 PCerr err;
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;
304 if(isClient())
306 // we need a global context
307 err = pcContextCreateGlobal(attribs, _serverList, _serviceAddr, &_context);
308 if(err)
310 SLOG << "Error creating global context" << std::endl;
313 else
315 // create a local context
316 err = pcContextCreateLocal(PC_ID_DEFAULT, _serviceAddr, &_context);
317 if(err)
319 SLOG << "Error creating local context" << std::endl;
323 if(isClient())
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);
331 if(_bufColor)
332 delete [] _bufColor;
333 _bufColor = new UInt8 [_wWidth * _wHeight * 4 * sizeof(GLubyte)];
335 if(_bufDepth)
336 delete [] _bufDepth;
337 _bufDepth = new UInt8 [_wWidth * _wHeight * sizeof(GLuint)];
338 #endif
341 void ParallelComposer::endFrame(UInt32 id)
343 #ifdef OSG_WITH_PARALLEL
345 PCerr err;
347 /* send the pixels */
348 err = pcFrameAddFramelet(_context,id,_bufColor,_bufDepth);
349 if(err)
351 SLOG << "Error adding framelet in endFrame" << std::endl;
355 /* done with the frame */
356 err = pcFrameEnd(_context,id);
357 if(err)
359 SLOG << "Error while calling pcFrameEnd" << std::endl;
361 if (isClient())
363 /* grab the results */
364 err = pcFrameResult(_context,id,0,0,_wWidth,_wHeight,reinterpret_cast<void**>(&_bufRet),NULL,
365 &_rowPixels);
366 if(err)
368 SLOG << "Error while getting frame results" << std::endl;
372 #endif
375 UInt32 ParallelComposer::beginFrame(void)
377 UInt32 id = 0;
378 #ifdef OSG_WITH_PARALLEL
379 PCerr err;
381 /* start the frame (all framelets are full size thus, NULLs) */
382 err = pcFrameBegin(_context, &id, 1, NULL, NULL, NULL, NULL, NULL);
383 if(err)
385 SLOG << "Error while calling beginFrame" << std::endl;
387 #endif
388 return(id);
391 void ParallelComposer::drawFrame(void)
393 #ifdef OSG_WITH_PARALLEL
394 if (isClient())
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);
401 // swap buffers?
402 _bufRet = NULL;
404 #endif
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,
414 _bufDepth);
415 #endif