Main Page | Class Hierarchy | Class List | Directories | File List

Image2D_impl.h

00001 #include "Util.h"
00002 #include "ViewportGL.h"
00003 #include "Message.h"
00004 #include <math.h>
00005 
00006 namespace apig {
00007 
00008 /*********************************************************************************************/
00009 // Image2D :
00010 
00011 template<class Color>
00012 Image2D<Color>::Image2D(int w, int h, Color* inputData) : AbstractImage2D(w, h), data(inputData), wrapMode(CLAMP_TO_EDGE) {
00013     if (w <= 0 || h <= 0) {
00014         w = h = 0;
00015         data = NULL;
00016         }
00017     else if (inputData == NULL) {
00018         data = new Color[w * h];
00019         if (data == NULL) {
00020             Message::error("l'allocation memoire pour l'image a echoué");
00021             w = h = 0;
00022             }
00023         }
00024     }
00025 
00026 template<class Color>
00027 Image2D<Color>::Image2D(QImage image) : AbstractImage2D(0,0), data(NULL), wrapMode(CLAMP_TO_EDGE) {
00028     initialize(image);
00029     }
00030 
00031 template<class Color>
00032 Image2D<Color>::Image2D(QString fileName) : AbstractImage2D(0,0), data(NULL), wrapMode(CLAMP_TO_EDGE) {
00033     QImage image(fileName);
00034     if (image.isNull())
00035         Message::error(QString("probleme lors du chargement du fichier '%1'").arg(fileName));
00036     else
00037         initialize(image);
00038     }
00039 
00040 template<class Color>
00041 void Image2D<Color>::destroy() {
00042     if (data != NULL) delete[] data;
00043     data = NULL;
00044     w = h = 0;
00045     }
00046 
00047 template<class Color>
00048 void Image2D<Color>::initialize(QImage image) {
00049     destroy();
00050     if (image.isNull())
00051         Message::error("l'image fournie ne contient pas de données");
00052     else {
00053         w = image.width();
00054         h = image.height();
00055         data = new Color[w * h];
00056         if (data == NULL) {
00057             Message::error("l'allocation memoire pour l'image a echoué");
00058             w = h = 0;
00059             }
00060         else
00061             for (int i=0; i<w; i++)
00062                 for (int j=0; j<h; j++)
00063                     texel(i,j) = Color(image.pixel(i, h-1-j));  // inversion des ordonnées
00064         }
00065     }
00066 
00067 template<class Color>
00068 QImage Image2D<Color>::toQImage() const {
00069     QImage image(w, h, QImage::Format_ARGB32);
00070     for (int i=0; i<w; i++)
00071         for (int j=0; j<h; j++)
00072             image.setPixel(i, j, texel(i,h-1-j).toQRgb());      // inversion des ordonnées
00073     return image;
00074     }
00075 
00076 template<class Color>
00077 Image2D<Color> Image2D<Color>::clone() const {
00078     if (data == NULL) return Image2D<Color>();
00079     Color *clonedData = new Color[w * h];
00080     if (clonedData == NULL) {
00081         Message::error("l'allocation memoire pour l'image a echoué");
00082         return Image2D<Color>();
00083         }
00084     for (int c=0; c<w*h; c++)
00085         clonedData[c] = data[c];
00086     return Image2D<Color>(w, h, clonedData);
00087     }
00088 
00089 template<class Color>
00090 Image2D<Color> Image2D<Color>::subImage(int i0, int j0, int ws, int hs) const {
00091     Image2D<Color> res(ws, hs);
00092     for (int i=0; i<ws; i++)
00093         for (int j=0; j<hs; j++)
00094             res.texel(i,j) = texel(i0+i, j0+j);
00095     return res;
00096     }
00097 
00098 template<class Color>
00099 Image2D<Color> Image2D<Color>::supImage(int i0, int j0, int ws, int hs) const {
00100     Image2D<Color> res(ws, hs);
00101     for (int i=0; i<w; i++)
00102         for (int j=0; j<h; j++)
00103             res.texel(i0+i, j0+j) = texel(i, j);
00104     return res;
00105     }
00106 
00107 template<class Color>
00108 Image2D<Color> Image2D<Color>::boundingPowerOfTwo() const {
00109     int ws, hs;
00110     for (ws = 1; ws < w; ws *= 2);
00111     for (hs = 1; hs < h; hs *= 2);
00112     return supImage(0,0,ws,hs);
00113     }
00114 
00115 template<class Color>
00116 void Image2D<Color>::setBorderColor(Color c) {
00117     borderColor = c;
00118     }
00119 
00120 template<class Color>
00121 void Image2D<Color>::setWrapMode(WrapMode mode) {
00122     wrapMode = mode;
00123     }
00124 
00125 template<class Color>
00126 void Image2D<Color>::setupBorder(WrapMode mode, Color c) {
00127     wrapMode = mode;
00128     borderColor = c;
00129     }
00130 
00131 template<class Color>
00132 Color Image2D<Color>::sample(int i, int j) const {
00133     switch (wrapMode) {
00134         case CLAMP_TO_BORDER :  return contains(i, j) ? texel(i,j) : borderColor;
00135         case REPEAT :           return texel(util::modulo(i, w), util::modulo(j, h));
00136         case MIRRORED_REPEAT :  return texel(util::mirror(i,w), util::mirror(j,h));
00137         case CLAMP_TO_EDGE :
00138         default :               return texel(util::clamp(i, 0, w-1), util::clamp(j, 0, h-1));
00139         };
00140     }
00141 
00142 template<class Color>
00143 Color Image2D<Color>::interp(float x, float y) const {
00144     int i0 = (int)(floorf(x - 0.5)),
00145         j0 = (int)(floorf(y - 0.5));
00146     float a = x - 0.5 - i0,
00147           b = y - 0.5 - j0;
00148     return (1-a) * (1-b) * sample(i0, j0  ) + a * (1-b) * sample(i0+1, j0  )
00149          + (1-a) *    b  * sample(i0, j0+1) + a *    b  * sample(i0+1, j0+1);
00150     }
00151 
00152 template<class Color>
00153 void Image2D<Color>::clear(Color c) {
00154     for (int i=0; i<w*h; i++) data[i] = c;
00155     }
00156 
00157 
00158 /*********************************************************************************************/
00159 // fonctions de lecture/écriture de buffer OpenGL :
00160 template<class Color>
00161 void Image2D<Color>::loadTexture2D(GLenum texFormat, GLenum target) const {
00162     glTexImage2D(target, 0, texFormat, w, h, 0, Color::DATA_FORMAT, Color::DATA_TYPE, data);
00163     }
00164 
00165 template<class Color>
00166 Image2D<Color> Image2D<Color>::getTexture(const Texture *tex) {
00167     int w = tex->getWidth(),
00168         h = tex->getHeight();
00169     Image2D<Color> res(w, h, NULL);
00170     if (w < 0 || h < 0)
00171         Message::error("dimensions de la texture non definies");
00172     else {
00173         tex->bind();
00174         glGetTexImage(GL_TEXTURE_2D, 0, Color::DATA_FORMAT, Color::DATA_TYPE, res.data);
00175         }
00176     return res;
00177     }
00178 
00179 template<class Color>
00180 void Image2D<Color>::readTexture(const Texture *tex) {
00181     int wTex = tex->getWidth(),
00182         hTex = tex->getHeight();
00183     if (wTex < 0 || hTex < 0)
00184         Message::error("dimensions de la texture non definies");
00185     else if
00186         (wTex != w && hTex != h)
00187         Message::error("dimensions de la texture differentes de celles de l'image");
00188     else {
00189         tex->bind();
00190         glGetTexImage(GL_TEXTURE_2D, 0, Color::DATA_FORMAT, Color::DATA_TYPE, data);
00191         }
00192     }
00193 
00194 template<class Color>
00195 Image2D<Color> Image2D<Color>::getColorBuffer() {
00196     ViewportGL view;    // récupère le viewport courant
00197     Image2D<Color> res(view.w, view.h, NULL);
00198     glReadPixels(0, 0, view.w, view.h, Color::DATA_FORMAT, Color::DATA_TYPE, res.data);
00199     return res;
00200     }
00201 
00202 template<class Color>
00203 Image2D<Color> Image2D<Color>::getDepthBuffer() {
00204     ViewportGL view;    // récupère le viewport courant
00205     Image2D<Color> res(view.w, view.h, NULL);
00206     glReadPixels(0, 0, view.w, view.h, GL_DEPTH_COMPONENT, Color::DATA_TYPE, res.data);
00207     return res;
00208     }
00209 
00210 template<class Color>
00211 void Image2D<Color>::readColorBuffer(int i, int j) {
00212     glReadPixels(i, j, w, h, Color::DATA_FORMAT, Color::DATA_TYPE, data);
00213     }
00214 
00215 template<class Color>
00216 void Image2D<Color>::readDepthBuffer(int i, int j) {
00217     glReadPixels(i, j, w, h, GL_DEPTH_COMPONENT, Color::DATA_TYPE, data);
00218     }
00219 
00220 template<class Color>
00221 Color Image2D<Color>::readPixelColor(int i, int j) {
00222     Color pix;
00223     glReadPixels(i, j, 1, 1, Color::DATA_FORMAT, Color::DATA_TYPE, &pix);
00224     return pix;
00225     }
00226         
00227 template<class Color>
00228 void Image2D<Color>::drawColorBuffer(int i, int j) const {
00229     glPushAttrib(GL_ALL_ATTRIB_BITS);
00230     ViewportGL view;
00231     view.pushScreenMatrices();
00232         glRasterPos2i(i, j);
00233         glDisable(GL_DEPTH_TEST);
00234         glDrawPixels(w, h, Color::DATA_FORMAT, Color::DATA_TYPE, data);
00235     view.popScreenMatrices();
00236     glPopAttrib();
00237     }
00238 
00239 /*********************************************************************************************/
00240 
00241 template<class Color>
00242 Texture Image2D<Color>::createTex2D(QString fileName, GLint internalFormat, GLenum interpMode, GLenum wrapMode) {
00243     Image2D<Color> image(fileName);
00244     Texture tex(&image, interpMode, wrapMode);
00245     tex.load(internalFormat);
00246     image.destroy();
00247     return tex;
00248     }
00249 
00250 }
00251 

Generated on Fri Nov 14 20:49:47 2008 for Api Graphics by  doxygen 1.4.4