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

texture.cpp

Go to the documentation of this file.
00001 /* *************************************************************************************
00002         Writer:         Sebastien Bloc
00003         Copyright:      2003-2004
00004         eMail:          sebastien.bloc@free.fr
00005         URL:            http://mignonsoft.free.fr
00006 
00007         This program is free software; you can redistribute it and/or
00008         modify it under the terms of the GNU General Public License
00009         as published by the Free Software Foundation; either version 2
00010         of the License, or (at your option) any later version.
00011 
00012         This program is distributed in the hope that it will be useful,
00013         but WITHOUT ANY WARRANTY; without even the implied warranty of
00014         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015         GNU General Public License for more details.
00016         http://www.gnu.org/copyleft/gpl.html
00017 ************************************************************************************* */
00018 
00019 #include "3d.h"
00020 #include "texture.h"
00021 #include "FreeImage.h"
00022 
00023 void Texture::VerifyId()
00024 {
00025         if (!id) 
00026         {
00027                 GLuint idCur;
00028                 glGenTextures(1,&idCur);
00029                 id = idCur;
00030                 list.i+=this; // nouvelle arrivant dans la liste generale
00031                 Config();
00032         }
00033         glBindTexture(target,id);
00034 }
00035 
00036 void Texture::Config() 
00037 {
00038         VerifyId();
00039         glTexParameteri(target, GL_TEXTURE_MAG_FILTER, magFilter); 
00040         glTexParameteri(target, GL_TEXTURE_MIN_FILTER, minFilter); 
00041         glTexParameteri(target, GL_TEXTURE_WRAP_T , wrapT);
00042         glTexParameteri(target, GL_TEXTURE_WRAP_S , wrapS);
00043         if (border.isEnable) glTexParameterfv(target, GL_TEXTURE_BORDER_COLOR , border);
00044         glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,envMode);
00045         if (envColor.isEnable) glTexEnvfv(GL_TEXTURE_ENV,GL_TEXTURE_ENV_COLOR ,envColor);
00046 }
00047 
00051 BOOL Texture::Delete()
00052 {
00053         return Texture::Delete(this);
00054 }
00055 
00056 BOOL Texture::Delete(Texture *texture)
00057 {
00058         for (list.i=0;list.i.More();list.i++)
00059         {
00060                 if (texture==list.i.GetElem()) 
00061                 { 
00062                         list.i.Supr(); 
00063                         return TRUE; 
00064                 }
00065         }
00066         return FALSE;
00067 }
00068 
00069 void Texture::ConfigPixelStore()
00070 {
00071         // sinon pb defois
00072         glPixelStorei( GL_UNPACK_ALIGNMENT,   1);
00073         glPixelStorei( GL_UNPACK_ROW_LENGTH,  0);
00074         glPixelStorei( GL_UNPACK_SKIP_ROWS,   0);
00075         glPixelStorei( GL_UNPACK_SKIP_PIXELS, 0);
00076 }
00077 
00078 GLubyte * Texture::ConfigSize (int _xSize,int _ySize,BOOL allocate,BOOL resizeIt)
00079 {   
00080         VerifyId();
00081 
00082         xSize = GetNearExp2(_xSize);
00083         ySize = GetNearExp2(_ySize);
00084 
00085         if (resizeIt)
00086         {
00087                 xScale = 1;
00088                 yScale = 1;
00089         }
00090         else 
00091         {
00092                 xScale = _xSize/(double)xSize;
00093                 yScale = _ySize/(double)ySize;
00094                 if ( (xSize!=_xSize) || (ySize!=_ySize) ) useResizing = TRUE;
00095         }
00096 
00097         ConfigPixelStore();
00098 
00099         if (allocate)
00100         {
00101                 int size = xSize*ySize*3;
00102                 GLubyte *dataOut= new GLubyte[size];
00103                 ZeroMemory(dataOut,size); 
00104                 return dataOut;
00105         }
00106         else return NULL;
00107 }
00108 
00109 double Texture::GetXCoord(double x)
00110 {
00111         if (useResizing) return x*xScale;
00112         else return x;
00113 }
00114 
00115 double Texture::GetYCoord(double y)
00116 {
00117         if (useResizing) return y*yScale;
00118         else return y;
00119 }
00120 
00121 void Texture::SetCoord(double x,double y)
00122 {
00123         if (useResizing) glTexCoord2d(x*xScale,y*yScale);
00124         else glTexCoord2d(x,y);
00125 }
00126 
00127 
00128 Texture::Texture()
00129 {
00130         Zero();
00131 }
00132 
00133 Texture::~Texture()
00134 {
00135         GLuint idRes;
00136         glDeleteTextures(1,&idRes);
00137         id=idRes;
00138 }
00139 
00140 void Texture::Zero()
00141 {
00142         target = texture2D;
00143         magFilter=linear;
00144         minFilter=linear;
00145         wrapS = repeat;
00146         wrapT = repeat;
00147         envMode = modulate;
00148         envColor.Zero();
00149         border.Zero();
00150         name="";
00151         id=0;
00152         xScale=0;
00153         yScale=0;
00154         useResizing = FALSE;
00155         dataOut=NULL;
00156         //VerifId() //ne marche toujour au constructeur car la fenetre openGl n'est peut etre pas encors initialisé
00157 }
00158 
00159 void Texture::operator =(Texture &src)
00160 {
00161         target = src.target;
00162         id = src.id;
00163         xScale = src.xScale;
00164         yScale = src.yScale;
00165         name = src.name;
00166         source = src.source;
00167         useResizing = src.useResizing;
00168         xSize = src.xSize;
00169         ySize = src.ySize;
00170         wrapS = src.wrapS;
00171         wrapT = src.wrapT;
00172         magFilter = src.magFilter;
00173         minFilter = src.minFilter;
00174         border = src.border;
00175         envMode = src.envMode;
00176         envColor = src.envColor;
00177 }
00178 
00179 BOOL Texture::FromNull()
00180 {
00181         Begin("Null",1,1);
00182         SetPixel(0,0,255,255,255);
00183         End();
00184         return TRUE;
00185 }
00186 
00187 
00188 BOOL Texture::FromFile(char *_name,char *fileName,BOOL resizeIt)
00189 {
00190         source = fileName;
00191         FREE_IMAGE_FORMAT fif = FreeImage_GetFIFFromFilename(source);
00192         if (fif == FIF_UNKNOWN) return FALSE;
00193         FreeImage_Initialise();
00194 
00195         FIBITMAP *bitmap = FreeImage_Load(fif,fileName);
00196         if (!bitmap) return FALSE;
00197         BYTE *data = FreeImage_GetBits(bitmap);
00198         if (!data) 
00199         {
00200                 FreeImage_Unload(bitmap);       
00201                 return FALSE;
00202         }
00203 
00204         // get the size of our image
00205         int bpp = FreeImage_GetBPP(bitmap)/8; // convert from bits to bytes, convert width from bytes in row, to just number of pixels in row
00206 
00207         int xImage = FreeImage_GetPitch(bitmap)/bpp;
00208         int yImage = FreeImage_GetHeight(bitmap);
00209         name = _name;
00210         ConfigSize(xImage,yImage,FALSE,FALSE);
00211 
00212         // Create our texture data
00213         unsigned char *texData = new unsigned char[xSize*ySize*4];
00214 
00215         FreeImage_ConvertToRawBits(texData, bitmap, xSize*4, 32, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK,TRUE);
00216 
00218         // texData now contains our image.  However we need to 
00219         // swap the red and blue color channels and flip the scanlines
00220         // in the vertical direction
00221         // This is because of the difference between how OpenGL and FreeImage
00222         // store image data internally.
00224 
00225         int linesize = xSize*4;
00226 
00227         // flip color components
00228         for(int y=0; y < ySize; y++)
00229         {
00230                 int pos = y*linesize;
00231                 for(int x=0; x < xSize; x++)
00232                 {
00233                         int xpos = y*linesize + x*4;
00234                         unsigned char temp = texData[xpos];
00235                         texData[xpos] = texData[xpos+2];
00236                         texData[xpos+2] = temp;
00237                 }       
00238         }
00239 
00240         if (resizeIt)
00241         {
00242                 gluScaleImage(GL_RGBA,xImage,yImage,GL_UNSIGNED_BYTE,texData,xSize,ySize,GL_UNSIGNED_BYTE,texData);
00243                 glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,xSize,ySize,FALSE,GL_RGBA,GL_UNSIGNED_BYTE,texData);
00244                 xScale=1;
00245                 yScale=1;
00246                 useResizing=FALSE;
00247         }
00248         else glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,xSize,ySize,0,GL_RGBA, GL_UNSIGNED_BYTE,texData); 
00249         delete [] texData; // release files
00250 
00251         FreeImage_Unload(bitmap);       
00252         FreeImage_DeInitialise();
00253         return TRUE;
00254 }
00255 
00259 Texture * Texture::Find(char *name)
00260 {
00261         Texture *finding;
00262         for (list.i=0;list.i.More();list.i++)
00263         {
00264                 finding = list.i.GetElem();
00265                 if (finding->name==name) return finding;
00266         }
00267         return NULL;
00268 }
00269 
00270 BOOL Texture::Begin(char *_name,int deltaX,int deltaY)
00271 {
00272         name = _name;
00273         dataOut = ConfigSize(deltaX,deltaY,TRUE,FALSE);
00274         return dataOut?TRUE:FALSE;
00275 }
00276 
00277 BOOL Texture::End()
00278 {
00279         if (!dataOut) return FALSE; // erreur de semantique donc (il dois y avoir un Begin() avant
00280         glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,xSize,ySize,FALSE,GL_RGB,GL_UNSIGNED_BYTE,dataOut);
00281         delete dataOut;
00282         dataOut=NULL;
00283         return TRUE;
00284 }
00285 
00289 BOOL Texture::SetPixel(int x,int y,byte r,byte g,byte b)
00290 {
00291         // test d'integrité
00292         if (!dataOut) return FALSE;
00293         if (x>=xSize||y>=ySize||x<0||y<0) return FALSE; // le point est il a une coordonnée correct
00294         int pos = (xSize*y+x)*3;
00295         dataOut[pos]=r;
00296         dataOut[pos+1]=g;
00297         dataOut[pos+2]=b;
00298         return TRUE;
00299 }
00300 
00304 BOOL Texture::GetPixel(int x,int y,byte &r,byte &g,byte &b)
00305 {
00306         // test d'integrité
00307         if (!dataOut) return FALSE;
00308         if (x>=xSize||y>=ySize||x<0||y<0) return FALSE; // le point est il a une coordonnée correct
00309         int pos = (xSize*y+x)*3;
00310         r=dataOut[pos];
00311         g=dataOut[pos+1];
00312         b=dataOut[pos+2];
00313         return TRUE;
00314 }
00320 BOOL Texture::AddText(char *text,COLORREF color,COLORREF background,int xFormat,int yFormat)
00321 {
00322         if (!dataOut) return FALSE;
00323 
00324         HBITMAP hBitmap = CreateBitmap(xSize, ySize, 16, 2, NULL);
00325         if (!hBitmap) return FALSE;
00326         BITMAP bitmap;
00327         GetObject(hBitmap,sizeof(bitmap),&bitmap);
00328         HDC mainDC = GetDC (NULL) ;
00329         HDC dc = CreateCompatibleDC (mainDC) ;
00330         SelectObject ( dc, hBitmap);
00331         RECT r = { 0,0,xSize,ySize};
00332 
00333         // fond unie
00334         HPEN hPen = CreatePen(PS_SOLID,0,background);
00335         HPEN hPenOld = (HPEN) SelectObject(dc,hPen);
00336         HBRUSH hBrush = CreateSolidBrush(background);
00337         HBRUSH hBrushOld = (HBRUSH) SelectObject(dc,hBrush);
00338         Rectangle(dc,0,0,xSize,ySize);
00339         DeleteObject(hBrush);
00340         DeleteObject(hPen);
00341         SelectObject(dc,hBrushOld);
00342         SelectObject(dc,hPenOld);
00343 
00344         SetBkMode(dc,TRANSPARENT);
00345         SetTextColor(dc,color);
00346 
00347         // parse le type de format
00348         UINT format = 0;
00349         format |= DT_WORDBREAK;
00350         switch (xFormat)
00351         {
00352         case -1: format |= DT_LEFT; break;
00353         case 0: format |= DT_CENTER; break;
00354         case 1: format |= DT_RIGHT; break;
00355         }
00356         switch (yFormat)
00357         {
00358         //case -1: format |= DT_TOP|DT_SINGLELINE; break;
00359         case 0: format |= DT_VCENTER|DT_SINGLELINE; break;
00360         case 1: format |= DT_BOTTOM|DT_SINGLELINE; break;
00361         }
00362         DrawText(dc, text, (int)strlen(text), &r, format );
00363 
00364         
00365         BITMAPINFOHEADER bi;
00366         ZeroMemory(&bi,sizeof(BITMAPINFOHEADER));
00367         bi.biSize               = sizeof(BITMAPINFOHEADER);
00368         bi.biWidth              = bitmap.bmWidth;
00369         bi.biHeight             = bitmap.bmHeight;
00370         bi.biPlanes             = bitmap.bmPlanes; //1;
00371         bi.biBitCount           = 24;
00372 
00373         int res = GetDIBits (dc,hBitmap,0,bitmap.bmHeight,dataOut,(LPBITMAPINFO)&bi,DIB_RGB_COLORS);
00374         ReleaseDC (NULL,mainDC) ;
00375         DeleteDC (dc) ; 
00376         return TRUE;
00377 }
00378 
00379 BOOL Texture::FromText(char *_name,char *text,COLORREF color,COLORREF background,int xFormat,int yFormat)
00380 {
00381         Begin(_name,64,64);
00382         source = text;
00383         AddText(text,color,background,xFormat,yFormat);
00384         End();
00385         return TRUE;
00386 }
00387 
00389 BOOL Texture::FromBitmap(char *_name,char *fileName,BOOL resizeIt)
00390 {
00391         AUX_RGBImageRec *pImage = auxDIBImageLoad(fileName);
00392         if (!pImage) return FALSE;
00393 
00394         Begin(_name,pImage->sizeX,pImage->sizeY);
00395         source = fileName;
00396 
00397         if (resizeIt)
00398         {
00399                 BOOL result = gluScaleImage(GL_RGB,pImage->sizeX,pImage->sizeY,GL_UNSIGNED_BYTE,pImage->data,xSize,ySize,GL_UNSIGNED_BYTE,dataOut);
00400                 if (result) glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,xSize,ySize,FALSE,GL_RGB,GL_UNSIGNED_BYTE,dataOut);
00401                 End();
00402                 delete pImage;
00403                 return result;
00404         }
00405 
00406         // effectue le scaling 
00407         int xSizeScale = pImage->sizeX*3;
00408         int ySizeScale = pImage->sizeY;
00409         int xDeltaScale = (xSize-pImage->sizeX)*3;
00410 
00411         GLubyte *ptrBufferIn = (GLubyte *)pImage->data;
00412         GLubyte *ptrBufferOut = dataOut; 
00413 
00414         for (int y=0;y<ySizeScale;y++)
00415         {
00416                 for (int x=0;x<xSizeScale;x++) *ptrBufferOut++=*ptrBufferIn++;
00417                 ptrBufferOut+=xDeltaScale;
00418         }       
00419 
00420         End();
00421         delete pImage;
00422         return TRUE;
00423 }

Generated on Fri Aug 20 19:19:50 2004 for 3d Controls by doxygen 1.3.6