Main Page   Modules   Class Hierarchy   Compound List   File List   Compound Members   File Members   Related Pages   Examples  

glt/buffer.h

Go to the documentation of this file.
00001 #ifndef GLT_BUFFER_H
00002 #define GLT_BUFFER_H
00003 
00004 /*
00005 
00006   GLT OpenGL C++ Toolkit      
00007   Copyright (C) 2000-2002 Nigel Stewart
00008   Email: nigels.com@gmail.com   WWW: http://www.nigels.com/glt/
00009 
00010   This library is free software; you can redistribute it and/or
00011   modify it under the terms of the GNU Lesser General Public
00012   License as published by the Free Software Foundation; either
00013   version 2.1 of the License, or (at your option) any later version.
00014 
00015   This library is distributed in the hope that it will be useful,
00016   but WITHOUT ANY WARRANTY; without even the implied warranty of
00017   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018   Lesser General Public License for more details.
00019 
00020   You should have received a copy of the GNU Lesser General Public
00021   License along with this library; if not, write to the Free Software
00022   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
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 //  /// Construct from memory buffer
00119 //  GltFrameBufferRGB(GLubyte *pixels);
00121     GltFrameBufferRGB(const GltFrameBufferRGB &a,const GltFrameBufferRGB &b,const GLdouble alpha);
00123     ~GltFrameBufferRGB();
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 //  GLubyte *_pixels;
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         // Check that viewport has not changed since
00177         // construction.
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         // Check that viewport has not changed since
00212         // construction.
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         // Set all the counts to zero
00333         memset(freq,0,64*sizeof(GLuint));
00334 
00335         uint32 i;
00336 
00337         // For each pixel in buffer...
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         // Check that viewport has not changed since
00448         // construction.
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         // TODO - stencil depth != 8 ??
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

Generated on Tue Nov 5 11:11:03 2002 for GLT by doxygen1.2.18