fixed: auto_ptr -> unique_ptr
[opensg.git] / Source / System / Cluster / Base / OSGClusterViewBuffer.cpp
blobed5102ef4ab77fe567fbab164aef4d410c5120ee
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 \*---------------------------------------------------------------------------*/
38 //---------------------------------------------------------------------------
39 // Includes
40 //---------------------------------------------------------------------------
42 #include <stdlib.h>
43 #include <stdio.h>
45 #include "OSGConfig.h"
46 #include "OSGGL.h"
47 #include "OSGGLU.h"
48 #include "OSGBaseFunctions.h"
49 #include "OSGLog.h"
50 #include "OSGClusterViewBuffer.h"
51 #include "OSGImageFileHandler.h"
52 #include "OSGImageFileType.h"
53 #include "OSGPointConnection.h"
54 #include "OSGGroupConnection.h"
56 OSG_USING_NAMESPACE
58 /*! \class OSG::ClusterViewBuffer
59 \ingroup GrpSystemCluster
60 \brief Viewbuffer functions
62 This class provides an interface to an OpenGL view buffer.
63 The Buffer contents can be transfered over a Connection.
64 All Image types can be used for image compression. The
65 ClusterViewBuffer can access RGBA, Stencil and Z-Buffer values.
67 The whole imagebuffer is divided into subtiles. Each subtile
68 is read from the buffer, compressed and send over the nertwork.
69 In most cases, the buffer read and the network send of the previous
70 tile is done in parallel.
72 todo: currently ClusterViewBuffer works on the activated window.
73 Is this a good idea. Better WindowPtr as parameter and then
74 call activate before send,recv? MR
77 /*-------------------------------------------------------------------------*/
78 /* Constructors/Destructor */
80 /*! Initialize a ClusterViewBuffer. By default, no image compression
81 is set and the subtile size is set to 32. The viewbuffer contents
82 is send in packages. If the package size is not too large, then
83 network transmission of the last and graphics card read of the current
84 package is done in parallel.
87 ClusterViewBuffer::ClusterViewBuffer(void) :
88 _imgTransType (NULL ),
89 _subTileSize (32 ),
90 _rgbDataType (GL_UNSIGNED_BYTE),
91 _rgbDataSize (3 ),
92 _rgbaDataType (GL_UNSIGNED_BYTE),
93 _rgbaDataSize (4 ),
94 _depthDataType(GL_UNSIGNED_INT ),
95 _depthDataSize(4 )
99 /*! Destructor
102 ClusterViewBuffer::~ClusterViewBuffer(void)
106 /*-------------------------------------------------------------------------*/
107 /* send/recv */
109 /*! Receive image data from all channels of a conneciton. The receive is
110 * finished, when the last channel signals a transmission end.
113 void ClusterViewBuffer::recv(GroupConnection &connection)
115 UInt32 tx, ty, tw, th;
116 UInt32 missing;
117 BufferT data;
118 BufferT imageData;
119 UInt32 dataSize;
120 UInt32 component;
121 GLenum glformat;
122 int componentCnt;
123 Connection::Channel channel;
125 missing = connection.getChannelCount();
127 glPushMatrix();
128 glLoadIdentity();
129 glMatrixMode(GL_PROJECTION);
130 glPushMatrix();
131 glLoadIdentity();
132 gluOrtho2D(0, getBufferWidth(), 0, getBufferHeight());
133 glDisable(GL_DEPTH_TEST);
134 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
136 // we expect tiles form all connected servers
137 while(missing)
139 channel = connection.selectChannel();
140 connection.getValue(component);
141 if(!component)
143 connection.subSelection(channel);
144 missing--;
145 continue;
148 // get dimension
149 connection.getValue(tx);
150 connection.getValue(ty);
151 connection.getValue(tw);
152 connection.getValue(th);
153 glRasterPos2i(tx, ty);
155 // =========== recv stencil =====================================
156 if(component & STENCIL)
158 data.resize(tw * th);
159 connection.get(&data[0], tw * th);
160 glDrawPixels(tw, th, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, &data[0]);
161 glEnable(GL_STENCIL_TEST);
164 // =========== recv depth =======================================
165 if(component & DEPTH)
167 glEnable(GL_DEPTH_TEST);
168 glEnable(GL_STENCIL_TEST);
169 glStencilFunc(GL_ALWAYS, 1, 1);
170 glStencilOp(GL_KEEP, GL_ZERO, GL_REPLACE);
171 data.resize(tw * th * sizeof(float));
172 connection.get(&data[0], tw * th * sizeof(float));
173 glDrawPixels(tw, th, GL_DEPTH_COMPONENT, GL_FLOAT, &data[0]);
174 glDisable(GL_DEPTH_TEST);
177 // =========== recv RGBA ========================================
178 if(component & RGBA)
180 if(component & (DEPTH | STENCIL))
182 glStencilFunc(GL_EQUAL, 1, 1);
185 switch(component & RGBA)
187 case RGB:
188 glformat = GL_RGB;
189 componentCnt = 3;
190 break;
191 case RGBA:
192 glformat = GL_RGBA;
193 componentCnt = 4;
194 break;
195 default:
196 SFATAL << "Component combination not supported"
197 << std::endl;
198 return;
201 connection.getValue(dataSize);
203 // compression ?
204 if(dataSize > 0)
206 #if 0
207 pImage = new Image;
209 data.resize(dataSize);
210 connection.get(&data[0], dataSize);
211 imageData.resize(tw * th * componentCnt);
212 ImageFileType::restore(*pImage, (UChar8 *) &data[0], dataSize);
213 glDrawPixels(tw, th, glformat, GL_UNSIGNED_BYTE,
214 pImage->getData());
215 #endif
217 else
219 data.resize(tw * th * componentCnt);
220 connection.get(&data[0], tw * th * componentCnt);
221 glDrawPixels(tw, th, glformat, GL_UNSIGNED_BYTE, &data[0]);
225 if(component & (DEPTH | STENCIL))
227 glDisable(GL_STENCIL_TEST);
230 connection.resetSelection();
231 glPopMatrix();
232 glMatrixMode(GL_MODELVIEW);
233 glPopMatrix();
234 glEnable(GL_DEPTH_TEST);
237 /*! Send parts of a view buffer to a Connection
239 \a connection defines the connection to use, \a component which color
240 channels (RGB/RGBA) should be transferred, \a x1, \a y1, \a x2, \a y2
241 (inclusive) define the source area and \a toX and \a toY the lower left
242 corner of the destination area.
244 void ClusterViewBuffer::send(PointConnection &connection,
245 UInt32 component,
246 UInt32 x1,
247 UInt32 y1,
248 UInt32 x2,
249 UInt32 y2,
250 UInt32 toX,
251 UInt32 toY)
253 UInt32 tx, ty, tw, th;
254 // Image *pImage;
255 BufferT data;
256 BufferT imageData;
257 UInt32 dataSize;
258 GLenum glformat;
259 // Image::PixelFormat imgformat;
260 int componentCnt;
261 int imgtranssize = 0;
263 switch(component & RGBA)
265 case RGB:
266 glformat = GL_RGB;
267 // imgformat = Image::OSG_RGB_PF;
268 componentCnt = 3;
269 break;
270 case RGBA:
271 glformat = GL_RGBA;
272 // imgformat = Image::OSG_RGBA_PF;
273 componentCnt = 4;
274 break;
275 default:
276 SFATAL << "Component combination not supported"
277 << std::endl;
278 return;
281 // resize image buffer
282 imageData.resize(_subTileSize * _subTileSize * componentCnt);
284 glPixelStorei(GL_PACK_ALIGNMENT, 1);
286 for(ty = y1; ty <= y2; ty += _subTileSize)
288 for(tx = x1; tx <= x2; tx += _subTileSize)
290 tw = osgMin(_subTileSize, x2 + 1 - tx);
291 th = osgMin(_subTileSize, y2 + 1 - ty);
293 connection.putValue(component);
294 connection.putValue(tx + toX);
295 connection.putValue(ty + toY);
296 connection.putValue(tw);
297 connection.putValue(th);
299 // =========== send STENCIL =======================================
300 if(component & STENCIL)
302 // read stencil buffer
303 data.resize(tw * th);
304 glReadPixels(tx,
305 ty,
306 tw,
307 th,
308 GL_STENCIL_INDEX,
309 GL_UNSIGNED_BYTE,
310 &data[0]);
312 connection.put(&data[0], tw * th);
315 // =========== send DEPTH =======================================
316 if(component & DEPTH)
318 // read stencil buffer
319 data.resize(tw * th * sizeof(float));
320 glReadPixels(tx, ty, tw, th, GL_DEPTH_COMPONENT, GL_FLOAT,
321 &data[0]);
322 connection.put(&data[0], tw * th * sizeof(float));
325 // =========== send RGBA ========================================
326 if(component & RGBA)
328 // use compression ?
329 if(_imgTransType)
331 #if 0
332 // set image size
333 pImage = new Image;
335 pImage->set(imgformat, tw, th, 1, 1, 1, 0.0,
336 (UChar8 *) &imageData[0]);
338 // read buffer data into image
339 glReadPixels(tx, ty, tw, th, glformat, GL_UNSIGNED_BYTE,
340 pImage->getData());
342 // bug maxsize is not big enugh
343 data.resize(_imgTransType->maxBufferSize(*pImage) + 1000);
344 dataSize = _imgTransType->store(*pImage, (UChar8 *) &data[0],
345 data.size());
346 connection.putValue(dataSize);
347 connection.put(&data[0], dataSize);
348 imgtranssize += dataSize;
349 #endif
351 else
353 data.resize(tw * th * componentCnt);
355 // read buffer data
356 glReadPixels(tx, ty, tw, th, glformat, GL_UNSIGNED_BYTE,
357 &data[0]);
358 dataSize = 0;
359 connection.putValue(dataSize);
360 connection.put(&data[0], tw * th * componentCnt);
361 imgtranssize += tw * th * componentCnt;
365 connection.flush();
369 component = 0;
370 connection.putValue(component);
371 connection.flush();
374 /*! Send parts of a view buffer to a Connection
376 void ClusterViewBuffer::send(PointConnection &connection,
377 UInt32 component,
378 UInt32 toX,
379 UInt32 toY)
381 send(connection,
382 component,
385 getBufferWidth(),
386 getBufferHeight(), toX,
387 toY);
390 /*-------------------------------------------------------------------------*/
391 /* set parameters */
393 /*! Set compression type. By default, no compression is used for image
394 * transmission. The given mime type identifies an ImageType e.g. "JPEG".
395 * This image type is used for compression.
398 void ClusterViewBuffer::setImgTransType(const Char8 *mimeType)
400 if(mimeType == NULL)
402 _imgTransType = NULL;
404 else
406 _imgTransType = ImageFileHandler::the()->getFileType(mimeType);
410 /*! Set subtile size. The whole buffer is transfered as small subtiles.
411 Increasing or decreasing the subtile size will result in changes to the
412 performance. The best size depends on network package size and the
413 ration between network performance and buffer read/write performance.
416 void ClusterViewBuffer::setSubtileSize(UInt32 size)
418 _subTileSize = size;
421 /*! Set opengl datatype for rgb tramsmission
424 void ClusterViewBuffer::setRGBADataType(UInt32 type, UInt32 size)
426 _rgbaDataType = type;
427 _rgbaDataSize = size;
430 /*! Set opengl datatype for rgba tramsmission
433 void ClusterViewBuffer::setRGBDataType(UInt32 type, UInt32 size)
435 _rgbDataType = type;
436 _rgbDataSize = size;
439 /*! Set opengl datatype for Z-Buffer tramsmission
442 void ClusterViewBuffer::setDepthDataType(UInt32 type, UInt32 size)
444 _depthDataType = type;
445 _depthDataSize = size;
448 /*-------------------------------------------------------------------------*/
449 /* get */
451 /*! Get buffer width
454 UInt32 ClusterViewBuffer::getBufferWidth(void)
456 GLint view[4];
457 glGetIntegerv(GL_VIEWPORT, view);
459 return view[2];
462 /*! Get buffer width
465 UInt32 ClusterViewBuffer::getBufferHeight(void)
467 GLint view[4];
468 glGetIntegerv(GL_VIEWPORT, view);
470 return view[3];