Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

FrameBuffer.h

Go to the documentation of this file.
00001 #ifndef _FRAMEBUFFER_H_
00002 #define _FRAMEBUFFER_H_
00003 
00004 #include <stdio.h>
00005 #include <string.h>
00006 
00007 #include "vuColour.h"
00008 
00009 
00010 #define FB_FLOAT
00011 
00012 //namespace vuVolumeBCCUnimodal3d1BIntensitySheetSplat {
00013 
00014 typedef float fbtype;
00015 
00021 template <int N>
00022 class FrameBuffer
00023 {
00024   friend class vuColour<N>;
00025 public:
00026 
00028     FrameBuffer() {m_Buffer = 0; }
00029 
00031     FrameBuffer(int width, int height)
00032     {
00033         m_Buffer = 0;
00034         setSize(width, height);
00035     }
00036 
00038     ~FrameBuffer()
00039     {
00040         freeBuffer();
00041     }
00042 
00044     int getNumberOfChannels() { return N; }
00046     int getHeight() { return m_Height; }
00048     int getWidth() { return m_Width; }
00050     float* getData() { return m_Buffer; }
00051 
00053     bool setSize(int width, int height)
00054     {
00055         freeBuffer();
00056         m_Buffer = new float[ width * height * N];
00057         if(!m_Buffer) return false;
00058         m_Width = width;
00059         m_Height = height;
00060         return true;
00061     }
00062 
00064     bool freeBuffer()
00065     {
00066         if(m_Buffer) delete [] m_Buffer;
00067         m_Buffer = 0;
00068         m_Width = 0;
00069         m_Height = 0;
00070         return true;
00071     }
00072 
00078     bool copy(FrameBuffer<N>& fb, int x, int y)
00079     {
00080         if ((!fb.m_Buffer) ||
00081             (N != fb.getNumberOfChannels()) ||
00082             (x < 0 || y < 0) ||
00083             (x + fb.m_Width>m_Width)||
00084             (y + fb.m_Height>m_Height)) return false;
00085 
00086         if(fb.getNumberOfChannels() == N)
00087         {
00088             int h = m_Height;
00089             int incdst = m_Width * N;
00090             int incsrc = fb.m_Width * N;
00091             float* src = fb.m_Buffer;
00092             float* dst = m_Buffer[y*m_Width + x];
00093             for(h=m_Height; h!=0; h--)
00094             {
00095                 memcpy(dst,src,m_Width);
00096                 dst += incdst;
00097                 src += incsrc;
00098             }
00099         }
00100         else
00101         {
00102             // don't know
00103         }
00104         return true;
00105     }
00106 
00111     bool add(FrameBuffer<N>& fb, int x, int y)
00112     {
00113       if ((!fb.m_Buffer) ||
00114           (x < 0 || y < 0) ||
00115           (x + fb.m_Width>m_Width)||
00116           (y + fb.m_Height>m_Height)) return false;
00117 
00118       int h = m_Height;
00119       int incdst = (m_Width-fb.m_Width) * N;
00120       register float* src = fb.m_Buffer;
00121       register float* dst = &m_Buffer[y*m_Width + x];
00122       for(h=m_Height; h!=0; h--)
00123         {
00124           for(int len = fb.m_Width * N;len!=0;len--)
00125             *(dst++) += *(src++);
00126           dst += incdst;
00127         }
00128         return true;
00129     }
00130 
00131 
00136     bool addColourWithMask(FrameBuffer<1>& fb, vuColour<N>& colour, int x, int y)
00137     {
00138         if ((!fb.getData()) ||
00139             (x < 0 || y < 0) ||
00140             (x + fb.getWidth()>m_Width)||
00141             (y + fb.getHeight()>m_Height)) return false;
00142 
00143         int cpyh = fb.getHeight();
00144         int cpyw = fb.getWidth();
00145         int incdst = (m_Width-fb.getWidth()) * N;
00146         register float* src = fb.getData();
00147         register float* dst = &m_Buffer[(y*m_Width + x)*N];
00148         for(int h=cpyh; h!=0; h--) {
00149           for(register int len = cpyw; len!=0; len--) {
00150             register float *colval = colour.getData();
00151             register float alpha = (*src)*colour[3];
00152             for(register int comp = N-1; comp!=0; comp--, colval++) {
00153               *(dst++) += alpha*(*colval);              //add weighted colour
00154             }
00155             *(dst++) += *(src++)*(*colval);                     //add alpha
00156           }
00157           dst += incdst;
00158         }
00159         return true;
00160     }
00161 
00166     bool subColourWithMask(FrameBuffer<1>& fb, vuColour<N>& colour, int x, int y)
00167     {
00168         if ((!fb.getData()) ||
00169             (x < 0 || y < 0) ||
00170             (x + fb.getWidth()>m_Width)||
00171             (y + fb.getHeight()>m_Height)) return false;
00172 
00173         int cpyh = fb.getHeight();
00174         int cpyw = fb.getWidth();
00175         int incdst = (m_Width-fb.getWidth()) * N;
00176         register float* src = fb.getData();
00177         register float* dst = &m_Buffer[(y*m_Width + x)*N];
00178         for(int h=cpyh; h!=0; h--) {
00179           for(register int len = cpyw; len!=0; len--) {
00180             register float *colval = colour;
00181             for(register int comp = N-1; comp!=0; comp--, colval++) {
00182               *(dst++) -= (*src)*(*colval);             //sub weighted colour
00183             }
00184             *(dst++) -= *(src++)*(*colval);                     //sub alpha
00185           }
00186           dst += incdst;
00187         }
00188         return true;
00189     }
00190 
00195     bool addColourWithM1subM2(FrameBuffer<1>& m1, FrameBuffer<1>& m2,
00196                               vuColour<N>& colour, const int x, const int y)
00197     {
00198         if ((!m1.getData()) ||
00199             (!m2.getData()) ||
00200             ( m1.getWidth()!=m2.getWidth()) ||
00201             ( m1.getHeight()!=m2.getHeight()) ||
00202             (x < 0 || y < 0) ||
00203             (x + m1.getWidth()>m_Width)||
00204             (y + m1.getHeight()>m_Height)) return false;
00205 
00206         int cpyh = m1.getHeight();
00207         int cpyw = m1.getWidth();
00208         int incdst = (m_Width-m1.getWidth()) * N;
00209         if (N != 4) {
00210           register float* datm1 = m1.getData();
00211           register float* datm2 = m2.getData();
00212           register float* dst = &m_Buffer[(y*m_Width + x)*N];
00213           float *col = colour.getData();
00214           for(int h=cpyh; h!=0; h--) {
00215             for(register int len = cpyw; len!=0; len--) {
00216               float a = ((*datm1)-(*datm2))*col[N-1];
00217               for(int comp = 0; comp<N-1; comp++) {
00218                 *(dst++) += a*col[comp];                //add weighted colour
00219               }
00220               *(dst++) += a;                    //add alpha
00221               if(*(dst-1)>1) {
00222                 //  cout<<"ac"<<flush;
00223                 *(dst-1) = .99;
00224               }
00225               datm1++; datm2++;
00226             }
00227             dst += incdst;
00228           }
00229         } else {        // N==4
00230           register float* datm1 = m1.getData();
00231           register float* datm2 = m2.getData();
00232           register float* dst = &m_Buffer[(y*m_Width + x)*N];
00233           float *col = colour.getData();
00234           for(int h=cpyh; h!=0; h--) {
00235             for(register int len = cpyw; len!=0; len--) {
00236               register float a = ((*datm1)-(*datm2))*col[N-1];
00237               register float *comp = col;
00238               *(dst++) += a*(*comp++);          //add weighted colour R
00239               *(dst++) += a*(*comp++);          // G
00240               *(dst++) += a*(*comp++);          // B
00241               *(dst++) += a;                    //add alpha
00242               datm1++; datm2++;
00243             }
00244             dst += incdst;
00245           }
00246         }
00247         return true;
00248     }
00249 
00251     bool blendOver(FrameBuffer<N>& fb, int x, int y)
00252     {
00253         if ((!fb.getData()) ||
00254             (x < 0 || y < 0) ||
00255             (x + fb.getWidth()>m_Width)||
00256             (y + fb.getHeight()>m_Height)) return false;
00257 
00258         int cpyh = fb.getHeight();
00259         int cpyw = fb.getWidth();
00260         int incdst = (m_Width-fb.getWidth()) * N;
00261         register float* src = fb.getData();
00262         register float* dst = &m_Buffer[(y*m_Width + x)*N];
00263         for(int h=cpyh; h!=0; h--) {
00264           for(register int len = cpyw; len!=0; len--) {
00265             //float a1 = src[N-1];
00266             float a2 = 1-src[N-1];
00267             for(register int comp = 0;
00268                 comp<N-1;
00269                 comp++, dst++, src++) {
00270               *(dst) = (*dst)*a2 + (*src);
00271             }
00272             dst++;      // do nothing with the alpha value. (?)
00273             src++;
00274           }
00275           dst += incdst;
00276         }
00277         return true;
00278     }
00279 
00281     bool blendOver(FrameBuffer<N>& fb)
00282     {
00283         if ((!fb.getData()) ||
00284             (fb.getWidth()!=m_Width)||
00285             (fb.getHeight()!=m_Height)) return false;
00286         if(N!=4) {
00287           int cpylen = fb.getHeight()*fb.getWidth();
00288           register float* src = fb.getData();
00289           register float* dst = m_Buffer;
00290           for(register int len = cpylen; len!=0; len--) {
00291             float a2 = 1-src[N-1];
00292             for(register int comp = 0;
00293                 comp<N-1;
00294                 comp++, dst++, src++) {
00295               *(dst) = (*dst)*a2 + (*src);
00296             }
00297             dst++;      // do nothing with the alpha value.
00298             src++;
00299           }
00300         } else {
00301           int cpylen = fb.getHeight()*fb.getWidth();
00302           register float* src = fb.getData();
00303           register float* dst = m_Buffer;
00304           for(register int len = cpylen; len!=0; len--) {
00305             register float a2 = 1-src[N-1];     //1-x
00306 
00307             *(dst++) = (*dst)*a2 + (*src++);    //RGB...
00308             *(dst++) = (*dst)*a2 + (*src++);
00309             *(dst++) = (*dst)*a2 + (*src++);
00310 
00311             dst++;      // do nothing with the alpha value.
00312             src++;
00313           }
00314         }
00315         return true;
00316     }
00317 
00321     bool blendUnder(FrameBuffer<N>& fb, int x, int y)
00322     {
00323         if ((!fb.getData()) ||
00324             (x < 0 || y < 0) ||
00325             (x + fb.getWidth()>m_Width)||
00326             (y + fb.getHeight()>m_Height)) return false;
00327 
00328         int cpyh = fb.getHeight();
00329         int cpyw = fb.getWidth();
00330         int incdst = (m_Width-fb.getWidth()) * N;
00331         register float* src = fb.getData();
00332         register float* dst = &m_Buffer[(y*m_Width + x)*N];
00333         for(int h=cpyh; h!=0; h--) {
00334           for(register int len = cpyw; len!=0; len--) {
00335             float a = src[N-1]*dst[N-1];
00336             float t = 1-dst[N-1];
00337             for(register int comp = 0;
00338                 comp<N-1;
00339                 comp++, dst++, src++) {
00340               *(dst) = *(dst)*t + (*src)*a;
00341             }
00342             *(dst++) *= 1-(*(src++));   // modify transmittance of layer
00343           }
00344           dst += incdst;
00345         }
00346         return true;
00347     }
00348 
00350     bool blendUnder(FrameBuffer<N>& fb)
00351     {
00352         if ((!fb.getData()) ||
00353             (fb.getWidth()!=m_Width)||
00354             (fb.getHeight()!=m_Height)) return false;
00355         if(N!=4) {
00356           int cpylen = fb.getHeight()*fb.getWidth();
00357           register float* src = fb.getData();
00358           register float* dst = m_Buffer;
00359           for(register int len = cpylen; len!=0; len--) {
00360             float a2 = 1-src[N-1];
00361             for(register int comp = 0;
00362                 comp<N-1;
00363                 comp++, dst++, src++) {
00364               *(dst) = (*dst)*a2 + (*src);
00365             }
00366             dst++;      // do nothing with the alpha value.
00367             src++;
00368           }
00369         } else {        // N==4
00370           int cpylen = fb.getHeight()*fb.getWidth();
00371           register float* src = fb.getData();
00372           register float* dst = m_Buffer;
00373           for(register int len = cpylen; len!=0; len--) {
00374             register float t = (1-dst[N-1]);
00375 
00376             *(dst++) += *(src++)*t;
00377             *(dst++) += *(src++)*t;
00378             *(dst++) += *(src++)*t;
00379 
00380             *(dst++) += *(src++)*t;     // modify transmittance of layer
00381           }
00382         }
00383         return true;
00384     }
00385 
00387     bool clear(const vuColour<N> colour)
00388     {
00389         if(m_Buffer == 0) return false;
00390         float col[] = {colour[0],colour[1],colour[2],colour[3]};
00391         float *dst = m_Buffer;
00392         for(register int i = m_Width*m_Height; i!=0; i--) {
00393             memcpy(dst,col,sizeof(float)*N);
00394             dst += N;
00395         }
00396         return true;
00397     }
00398 
00401     bool print()
00402     {
00403         if(m_Buffer == 0) return false;
00404         float *buf = m_Buffer;
00405         for(int i = 0; i<m_Height; i++) {
00406             for(int j = 0;j<m_Width; j++) {
00407                 printf("[%3i,%3i] = (%4.5f", j, i, *(buf++));
00408                 for(int c = 1; c<N; c++, buf++){
00409                     printf(", %4.5f", *buf);
00410                 }
00411                 printf(")\n");
00412             }
00413             putchar('\n');
00414         }
00415         return true;
00416     }
00417 
00418 protected:
00419     int m_Width, m_Height; 
00420     float *m_Buffer; 
00421 };
00422 
00423 
00425 typedef FrameBuffer<1> AlphaMask;
00429 typedef FrameBuffer<4> RGBABuffer;
00430 
00431 //};    // end of namespace
00432 
00433 #endif

Generated on Wed Dec 15 21:20:28 2004 for vuVolume by  doxygen 1.3.9.1