00001 #ifndef GLT_BUFFER_H
00002 #define GLT_BUFFER_H
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00042 #include <glt/config.h>
00043 #include <glt/gl.h>
00044 #include <glt/viewport.h>
00045 #include <glt/error.h>
00046
00047 #include <misc/image.h>
00048 #include <misc/string.h>
00049
00050 #include <iostream>
00051 #include <cassert>
00052 #include <cmath>
00053 #include <string>
00054 #include <cstring>
00055
00057
00063 class GltFrameBuffer
00064 {
00065 public:
00066
00068 virtual void read() = 0;
00070 virtual void write() const = 0;
00071
00073 GLuint x() const;
00075 GLuint y() const;
00077 GLuint width() const;
00079 GLuint height() const;
00081 GLuint size() const;
00082
00084 virtual void writePPM(std::ostream &os) const = 0;
00086 virtual void writeTGA(std::ostream &os) const = 0;
00087
00088 #ifdef GLT_PNG
00089 virtual void writePNG(std::ostream &os) const = 0;
00090 #endif
00091
00092 protected:
00093
00095 GltFrameBuffer();
00097 GltFrameBuffer(const GltViewport &viewport);
00098
00100 virtual ~GltFrameBuffer();
00101
00102 GltViewport _viewport;
00103 };
00104
00106
00112 class GltFrameBufferRGB : public GltFrameBuffer
00113 {
00114 public:
00115
00117 GltFrameBufferRGB();
00118
00119
00121
00123
00124
00125 GLubyte *operator[](const uint32 n) { assert(n<size()); return ( GLubyte *) _image.data() + n*3; }
00126 const GLubyte *operator[](const uint32 n) const { assert(n<size()); return (const GLubyte *) _image.data() + n*3; }
00127
00128 void read();
00129 void write() const;
00130
00131 void writePPM(std::ostream &os) const;
00132 void writeTGA(std::ostream &os) const;
00133
00134 #ifdef GLT_PNG
00135 virtual void writePNG(std::ostream &os) const;
00136 #endif
00137
00138 protected:
00139
00140 std::string _image;
00141
00142 };
00143
00145
00151 template< class DepthType , GLenum GlDepthType >
00152 class GltFrameBufferZ : public GltFrameBuffer
00153 {
00154 protected:
00155
00156 std::string _image;
00157 GLint _depthBits;
00158
00159 public:
00160
00161 GltFrameBufferZ()
00162 : GltFrameBuffer()
00163 {
00164 glGetIntegerv(GL_DEPTH_BITS,&_depthBits);
00165 _image.resize(size()*sizeof(DepthType));
00166 read();
00167 };
00168
00169 ~GltFrameBufferZ()
00170 {
00171 };
00172
00173 GltFrameBufferZ &
00174 operator=(const DepthType &value)
00175 {
00176
00177
00178
00179 GLuint viewport[4];
00180 glGetIntegerv(GL_VIEWPORT,(GLint *) viewport);
00181
00182 if (_width!=viewport[2] || _height!=viewport[3] || _pixels==NULL)
00183 {
00184 _x = viewport[0];
00185 _y = viewport[1];
00186 _width = viewport[2];
00187 _height = viewport[3];
00188 _size = _width*_height;
00189
00190 if (_pixels)
00191 delete [] _pixels;
00192
00193 _pixels = new DepthType[_size];
00194 }
00195
00196 for (uint32 n=0; n<_size; n++)
00197 _pixels[n] = value;
00198
00199 return *this;
00200 }
00201
00202 DepthType &operator[](const uint32 n) { return *(( DepthType *) _image.data() + n); }
00203 const DepthType &operator[](const uint32 n) const { return *((const DepthType *) _image.data() + n); }
00204
00205 void
00206 read()
00207 {
00208 GLERROR
00209
00210
00211
00212
00213
00214
00215 GltViewport viewport(true);
00216 if (_viewport!=viewport || !_image.size())
00217 {
00218 _viewport = viewport;
00219 _image.resize(size()*sizeof(DepthType));
00220 }
00221
00222
00223
00224 glPixelStorei(GL_PACK_ALIGNMENT,sizeof(DepthType));
00225 glReadPixels(x(),y(),width(),height(),GL_DEPTH_COMPONENT,GlDepthType,(GLvoid *) _image.data());
00226
00227 GLERROR
00228 }
00229
00230 void
00231 write() const
00232 {
00233 GLERROR
00234
00235 glPixelStorei(GL_UNPACK_ALIGNMENT,sizeof(DepthType));
00236
00237 glMatrixMode(GL_PROJECTION);
00238 glPushMatrix();
00239
00240 glLoadIdentity();
00241 glOrtho(-1.0,1.0,-1.0,1.0,0.0,100.0);
00242
00243 glMatrixMode(GL_MODELVIEW);
00244 glPushMatrix();
00245 glLoadIdentity();
00246
00247 glRasterPos2f(-1.0F,-1.0F);
00248 glDrawPixels(width(),height(),GL_DEPTH_COMPONENT,GlDepthType,(GLvoid *) _image.data());
00249
00250 glPopMatrix();
00251 glMatrixMode(GL_PROJECTION);
00252 glPopMatrix();
00253 glMatrixMode(GL_MODELVIEW);
00254
00255 GLERROR
00256 }
00257
00258 void
00259 writePPM(std::ostream &os) const
00260 {
00261 std::string tmp;
00262 toGreyscale(tmp);
00263
00264 std::string data;
00265 if (encodePPM(data,width(),height(),tmp))
00266 writeStream(os,data);
00267 }
00268
00269 void
00270 writeTGA(std::ostream &os) const
00271 {
00272 std::string tmp;
00273 toHeightfield(tmp);
00274
00275 std::string data;
00276 if (encodeTGA(data,width(),height(),tmp))
00277 writeStream(os,data);
00278 }
00279
00280 #ifdef GLT_PNG
00281 void
00282 writePNG(std::ostream &os) const
00283 {
00284 std::string tmp;
00285 toGreyscale(tmp);
00286
00287 std::string data;
00288 if (encodePNG(data,width(),height(),tmp))
00289 writeStream(os,data);
00290
00291 }
00292 #endif
00293
00294 DepthType
00295 maxPossible() const
00296 {
00297 switch (GlDepthType)
00298 {
00299 case GL_UNSIGNED_SHORT:
00300 return DepthType(0xffff);
00301 case GL_UNSIGNED_INT:
00302 #ifdef GLT_WIN32
00303 return DepthType(0xffffffff - 6911);
00304 #else
00305 return DepthType(0xffffffff);
00306 #endif
00307 case GL_FLOAT:
00308 return DepthType(1.0);
00309 default:
00310 assert(0);
00311 return DepthType();
00312 }
00313 };
00314
00315 DepthType
00316 minPossible() const
00317 {
00318 switch (GlDepthType)
00319 {
00320 case GL_UNSIGNED_SHORT: return 0x0;
00321 case GL_UNSIGNED_INT: return 0x0;
00322 case GL_FLOAT: return (DepthType) 0.0;
00323 default:
00324 assert(0);
00325 return DepthType();
00326 }
00327 };
00328
00329 bool
00330 histogram(GLuint freq[64]) const
00331 {
00332
00333 memset(freq,0,64*sizeof(GLuint));
00334
00335 uint32 i;
00336
00337
00338 switch (GlDepthType)
00339 {
00340 case GL_UNSIGNED_SHORT:
00341 case GL_UNSIGNED_INT:
00342 for (i=0; i<size(); i++)
00343 {
00344 const int index = (*this)[i]>>(_depthBits-5);
00345 assert(index>=0 && index<=63);
00346 freq[index]++;
00347 }
00348 break;
00349 default:
00350 assert(0);
00351 return DepthType();
00352 }
00353
00354 return true;
00355 }
00356
00357 protected:
00358
00359 void
00360 toGreyscale(std::string &image) const
00361 {
00362 image.resize(size());
00363
00364 byte *i = (byte *) image.data();
00365 DepthType *j = (DepthType *) _image.data();
00366
00367 const double min = minPossible();
00368 const double range = maxPossible()-min;
00369
00370 for (uint32 k=0; k<size(); k++)
00371 *(i++) = (byte) ((*(j++)-min)/range*255.0);
00372 }
00373
00374 void
00375 toHeightfield(std::string &image) const
00376 {
00377 image.resize(size()*3);
00378
00379 byte *i = (byte *) image.data();
00380 DepthType *j = (DepthType *) _image.data();
00381
00382 const double min = minPossible();
00383 const double range = maxPossible()-min;
00384
00385 for (uint32 k=0; k<size(); k++)
00386 {
00387 double v = (*(j++)-min)/range;
00388 *(i++) = (byte) floor(v = v*255.0);
00389 *(i++) = (byte) floor(v = fmod(v,1.0)*255.0);
00390 *(i++) = (byte) floor( fmod(v,1.0)*255.0);
00391 }
00392 }
00393 };
00394
00410 typedef GltFrameBufferZ<GLfloat,GL_FLOAT> GltFrameBufferZFloat;
00411 typedef GltFrameBufferZ<GLushort,GL_UNSIGNED_SHORT> GltFrameBufferZShort;
00412 typedef GltFrameBufferZ<GLuint,GL_UNSIGNED_INT> GltFrameBufferZUint;
00413
00414
00416
00422 template<class StencilType,GLenum GlStencilType>
00423 class GltFrameBufferStencil : public GltFrameBuffer
00424 {
00425 protected:
00426 std::string _image;
00427
00428 public:
00429
00430 GltFrameBufferStencil()
00431 : GltFrameBuffer()
00432 {
00433 _image.resize(size()*sizeof(StencilType));
00434 read();
00435 }
00436
00437 ~GltFrameBufferStencil()
00438 {
00439 }
00440
00441 void
00442 read()
00443 {
00444 GLERROR
00445
00446
00447
00448
00449
00450
00451 GltViewport viewport(true);
00452 if (_viewport!=viewport || !_image.size())
00453 {
00454 _viewport = viewport;
00455 _image.resize(size()*sizeof(StencilType));
00456 }
00457
00458
00459
00460 glPixelStorei(GL_PACK_ALIGNMENT,sizeof(StencilType));
00461 glReadPixels(x(),y(),width(),height(),GL_STENCIL_INDEX,GlStencilType,(GLvoid *) _image.data());
00462
00463 GLERROR
00464 }
00465
00466 void
00467 write() const
00468 {
00469 GLERROR
00470
00471 glPixelStorei(GL_UNPACK_ALIGNMENT,sizeof(StencilType));
00472
00473 glMatrixMode(GL_PROJECTION);
00474 glPushMatrix();
00475 glLoadIdentity();
00476 glOrtho(-1.0,1.0,-1.0,1.0,0.0,100.0);
00477
00478 glMatrixMode(GL_MODELVIEW);
00479 glPushMatrix();
00480 glLoadIdentity();
00481 glRasterPos2f(-1.0F,-1.0F);
00482 glStencilMask(~0);
00483 glDrawPixels(width(),height(),GL_STENCIL_INDEX,GlStencilType,(GLvoid *) _image.data());
00484 glPopMatrix();
00485
00486 glMatrixMode(GL_PROJECTION);
00487 glPopMatrix();
00488
00489 glMatrixMode(GL_MODELVIEW);
00490
00491 GLERROR
00492 }
00493
00494 StencilType &operator[](const int i) { return (( StencilType *) _image.data())[i]; }
00495 const StencilType &operator[](const int i) const { return ((const StencilType *) _image.data())[i]; }
00496
00497 void
00498 writePPM(std::ostream &os) const
00499 {
00500
00501
00502 std::string data;
00503 if (encodePPM(data,width(),height(),_image))
00504 writeStream(os,data);
00505 }
00506
00507 void
00508 writeTGA(std::ostream &os) const
00509 {
00510 std::string data;
00511 if (encodeTGA(data,width(),height(),_image))
00512 writeStream(os,data);
00513 }
00514
00515 #ifdef GLT_PNG
00516 void
00517 writePNG(std::ostream &os) const
00518 {
00519 std::string data;
00520 if (encodePNG(data,width(),height(),_image))
00521 writeStream(os,data);
00522 }
00523 #endif
00524 };
00525
00531 typedef GltFrameBufferStencil<GLubyte,GL_UNSIGNED_BYTE> GltFrameBufferStencilUbyte;
00532
00533
00534 #endif