00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "renderers/OpenGLGUIRenderer/opengltexture.h"
00028 #include "CEGUIExceptions.h"
00029 #include "CEGUISystem.h"
00030
00031 #ifdef USE_DEVIL_LIBRARY
00032 # include <IL/il.h>
00033 # include <IL/ilu.h>
00034
00035
00036 # ifdef _MSC_VER
00037 # pragma comment (lib, "DevIL.lib")
00038 # pragma comment (lib, "ilu.lib")
00039 # endif
00040
00041 #endif
00042
00043
00044 namespace CEGUI
00045 {
00046
00047
00048
00049
00050 OpenGLTexture::OpenGLTexture(Renderer* owner) :
00051 Texture(owner)
00052 {
00053
00054 glGenTextures(1, &d_ogltexture);
00055
00056
00057 glBindTexture(GL_TEXTURE_2D, d_ogltexture);
00058 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
00059 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
00060 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, 0x812F);
00061 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, 0x812F);
00062 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
00063
00064 #ifdef USE_DEVIL_LIBRARY
00065
00066 ilInit();
00067 iluInit();
00068 #endif
00069 }
00070
00071
00072
00073
00074 OpenGLTexture::~OpenGLTexture(void)
00075 {
00076
00077 glDeleteTextures(1, &d_ogltexture);
00078 }
00079
00080
00081
00082
00083
00084
00085 void OpenGLTexture::loadFromFile(const String& filename, const String& resourceGroup)
00086 {
00087 glBindTexture(GL_TEXTURE_2D, d_ogltexture);
00088
00089
00090 RawDataContainer texFile;
00091 System::getSingleton().getResourceProvider()->loadRawDataContainer(filename, texFile, resourceGroup);
00092
00093 #ifndef USE_DEVIL_LIBRARY
00094 tImageTGA* img = LoadTGA(texFile.getDataPtr(), texFile.getSize());
00095
00096 if (img != 0)
00097 {
00098 d_width = static_cast<ushort>(img->sizeX);
00099 d_height = static_cast<ushort>(img->sizeY);
00100
00101
00102 flipImageTGA(img);
00103
00104
00105 int textureType = (img->channels == 4) ? GL_RGBA : GL_RGB;
00106
00107 glTexImage2D(GL_TEXTURE_2D, 0, textureType, d_width, d_height, 0, textureType, GL_UNSIGNED_BYTE, img->data);
00108
00109
00110 if (img->data)
00111 {
00112 delete[] img->data;
00113 }
00114
00115
00116 free(img);
00117 }
00118 else
00119 {
00120 throw RendererException("OpenGLTexture::loadFromFile - internal Targa loader failed to load image '" + filename + "'.");
00121 }
00122
00123 # else
00124 ILuint imgName;
00125 ilGenImages(1, &imgName);
00126 ilBindImage(imgName);
00127
00128 if (ilLoadL(IL_TYPE_UNKNOWN, texFile.getDataPtr(), texFile.getSize()) != IL_FALSE)
00129 {
00130
00131 iluFlipImage();
00132
00133
00134 ILinfo imgInfo;
00135 iluGetImageInfo(&imgInfo);
00136
00137
00138 d_width = imgInfo.Width;
00139 d_height = imgInfo.Height;
00140
00141
00142 uchar* tmpBuff = new uchar[d_width * d_height * 4];
00143
00144
00145 ilCopyPixels(0, 0, 0, d_width, d_height, 1, IL_RGBA, IL_UNSIGNED_BYTE, (ILvoid*)tmpBuff);
00146
00147
00148 ilDeleteImages(1, &imgName);
00149
00150
00151 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, d_width, d_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, tmpBuff);
00152
00153
00154 delete[] tmpBuff;
00155 }
00156
00157 else
00158 {
00159
00160 ilDeleteImages(1, &imgName);
00161
00162 throw RendererException("OpenGLTexture::loadFromFile - DevIL returned IL_FALSE when trying to load file '" + filename + "'.");
00163 }
00164
00165 # endif
00166
00167 System::getSingleton().getResourceProvider()->unloadRawDataContainer(texFile);
00168
00169 }
00170
00171
00172
00173
00174
00175 void OpenGLTexture::loadFromMemory(const void* buffPtr, uint buffWidth, uint buffHeight)
00176 {
00177 glBindTexture(GL_TEXTURE_2D, d_ogltexture);
00178 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, buffWidth, buffHeight, 0, GL_RGBA ,GL_UNSIGNED_BYTE, buffPtr);
00179
00180 d_width = static_cast<ushort>(buffWidth);
00181 d_height = static_cast<ushort>(buffHeight);
00182 }
00183
00184
00185
00186
00187
00188 void OpenGLTexture::setOGLTextureSize(uint size)
00189 {
00190
00191 if ((size & (size - 1)) || !size)
00192 {
00193 int log = 0;
00194
00195
00196 while (size >>= 1)
00197 {
00198 ++log;
00199 }
00200
00201
00202 size = (2 << log);
00203 }
00204
00205
00206 uchar* buff = new uchar[size * size * 4];
00207
00208
00209 glBindTexture(GL_TEXTURE_2D, d_ogltexture);
00210 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size, size, 0, GL_RGBA ,GL_UNSIGNED_BYTE, buff);
00211
00212
00213 delete[] buff;
00214
00215 d_height = d_width = static_cast<ushort>(size);
00216 }
00217
00218
00220
00221
00222
00223
00224
00225
00227
00228 #ifndef USE_DEVIL_LIBRARY
00229
00230
00231
00232 void OpenGLTexture::flipImageTGA(OpenGLTexture::tImageTGA* img)
00233 {
00234 int pitch = img->sizeX * img->channels;
00235
00236
00237 for (int line = 0; line < img->sizeY / 2; ++line)
00238 {
00239 int srcOffset = (line * pitch);
00240 int dstOffest = ((img->sizeY - line - 1) * pitch);
00241
00242 for (int colBit = 0; colBit < pitch; ++colBit)
00243 {
00244 uchar tmp = img->data[dstOffest + colBit];
00245 img->data[dstOffest + colBit] = img->data[srcOffset + colBit];
00246 img->data[srcOffset + colBit] = tmp;
00247 }
00248
00249 }
00250
00251 }
00252
00253
00262
00263 OpenGLTexture::tImageTGA* OpenGLTexture::LoadTGA(const unsigned char* buffer, size_t buffer_size)
00264 {
00265 tImageTGA *pImageData = NULL;
00266 short width = 0, height = 0;
00267 GLbyte length = 0;
00268 GLbyte imageType = 0;
00269
00270 GLbyte bits = 0;
00271 int channels = 0;
00272 int stride = 0;
00273 int i = 0;
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289 pImageData = (tImageTGA*)malloc(sizeof(tImageTGA));
00290
00291
00292 memcpy(&length, buffer, sizeof(GLbyte));
00293 buffer += sizeof(GLbyte);
00294
00295
00296 ++buffer;
00297
00298
00299 memcpy(&imageType, buffer, sizeof(GLbyte));
00300 buffer += sizeof(GLbyte);
00301
00302
00303 buffer += 9;
00304
00305
00306 memcpy(&width, buffer, sizeof(short));
00307 buffer += sizeof(short);
00308 memcpy(&height, buffer, sizeof(short));
00309 buffer += sizeof(short);
00310 memcpy(&bits, buffer, sizeof(GLbyte));
00311 buffer += sizeof(GLbyte);
00312
00313
00314 buffer += length + 1;
00315
00316
00317 if(imageType != TGA_RLE)
00318 {
00319
00320 if(bits == 24 || bits == 32)
00321 {
00322
00323
00324 channels = bits / 8;
00325 stride = channels * width;
00326 pImageData->data = new unsigned char[stride * height];
00327
00328
00329 for(int y = 0; y < height; y++)
00330 {
00331
00332 unsigned char *pLine = &(pImageData->data[stride * y]);
00333
00334
00335 memcpy(pLine, buffer, stride);
00336 buffer += stride;
00337
00338
00339
00340 for(i = 0; i < stride; i += channels)
00341 {
00342 unsigned char temp = pLine[i];
00343 pLine[i] = pLine[i + 2];
00344 pLine[i + 2] = temp;
00345 }
00346 }
00347 }
00348
00349 else if(bits == 16)
00350 {
00351 unsigned short pixels = 0;
00352 unsigned char r=0, g=0, b=0;
00353
00354
00355
00356 channels = 3;
00357 stride = channels * width;
00358 pImageData->data = new unsigned char[stride * height];
00359
00360
00361 for(int i = 0; i < width*height; i++)
00362 {
00363
00364 memcpy(&pixels, buffer, sizeof(unsigned short));
00365 buffer += sizeof(unsigned short);
00366
00367
00368
00369
00370
00371
00372 b = static_cast<unsigned char>((pixels & 0x1f) << 3);
00373 g = static_cast<unsigned char>(((pixels >> 5) & 0x1f) << 3);
00374 r = static_cast<unsigned char>(((pixels >> 10) & 0x1f) << 3);
00375
00376
00377
00378 pImageData->data[i * 3 + 0] = r;
00379 pImageData->data[i * 3 + 1] = g;
00380 pImageData->data[i * 3 + 2] = b;
00381 }
00382 }
00383
00384 else
00385 return NULL;
00386 }
00387
00388 else
00389 {
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408 unsigned char rleID = 0;
00409 int colorsRead = 0;
00410 channels = bits / 8;
00411 stride = channels * width;
00412
00413
00414
00415 pImageData->data = new unsigned char[stride * height];
00416 GLbyte *pColors = new GLbyte [channels];
00417
00418
00419 while(i < width*height)
00420 {
00421
00422 memcpy(&rleID, buffer, sizeof(unsigned char));
00423 buffer += sizeof(unsigned char);
00424
00425
00426 if(rleID < 128)
00427 {
00428
00429 rleID++;
00430
00431
00432 while(rleID)
00433 {
00434
00435 memcpy(pColors, buffer, sizeof(GLbyte) * channels);
00436 buffer += sizeof(GLbyte) * channels;
00437
00438
00439 pImageData->data[colorsRead + 0] = pColors[2];
00440 pImageData->data[colorsRead + 1] = pColors[1];
00441 pImageData->data[colorsRead + 2] = pColors[0];
00442
00443
00444 if(bits == 32)
00445 pImageData->data[colorsRead + 3] = pColors[3];
00446
00447
00448
00449 i++;
00450 rleID--;
00451 colorsRead += channels;
00452 }
00453 }
00454
00455 else
00456 {
00457
00458 rleID -= 127;
00459
00460
00461 memcpy(pColors, buffer, sizeof(GLbyte) * channels);
00462 buffer += sizeof(GLbyte) * channels;
00463
00464
00465 while(rleID)
00466 {
00467
00468 pImageData->data[colorsRead + 0] = pColors[2];
00469 pImageData->data[colorsRead + 1] = pColors[1];
00470 pImageData->data[colorsRead + 2] = pColors[0];
00471
00472
00473 if(bits == 32)
00474 pImageData->data[colorsRead + 3] = pColors[3];
00475
00476
00477
00478 i++;
00479 rleID--;
00480 colorsRead += channels;
00481 }
00482
00483 }
00484
00485 }
00486
00487
00488 delete[] pColors;
00489 }
00490
00491
00492 pImageData->channels = channels;
00493 pImageData->sizeX = width;
00494 pImageData->sizeY = height;
00495
00496
00497 return pImageData;
00498 }
00499 #endif
00500
00501 }