00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
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;
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
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
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
00205 int bpp = FreeImage_GetBPP(bitmap)/8;
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
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
00219
00220
00221
00222
00224
00225 int linesize = xSize*4;
00226
00227
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;
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;
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
00292 if (!dataOut) return FALSE;
00293 if (x>=xSize||y>=ySize||x<0||y<0) return FALSE;
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
00307 if (!dataOut) return FALSE;
00308 if (x>=xSize||y>=ySize||x<0||y<0) return FALSE;
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
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
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
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;
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
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 }