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 = img->sizeX;
00099 d_height = 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
00168
00169
00170
00171
00172 void OpenGLTexture::loadFromMemory(const void* buffPtr, uint buffWidth, uint buffHeight)
00173 {
00174 glBindTexture(GL_TEXTURE_2D, d_ogltexture);
00175 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, buffWidth, buffHeight, 0, GL_RGBA ,GL_UNSIGNED_BYTE, buffPtr);
00176
00177 d_width = buffWidth;
00178 d_height = buffHeight;
00179 }
00180
00181
00182
00183
00184
00185 void OpenGLTexture::setOGLTextureSize(uint size)
00186 {
00187
00188 if ((size & (size - 1)) || !size)
00189 {
00190 int log = 0;
00191
00192
00193 while (size >>= 1)
00194 {
00195 ++log;
00196 }
00197
00198
00199 size = (2 << log);
00200 }
00201
00202
00203 uchar* buff = new uchar[size * size * 4];
00204
00205
00206 glBindTexture(GL_TEXTURE_2D, d_ogltexture);
00207 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size, size, 0, GL_RGBA ,GL_UNSIGNED_BYTE, buff);
00208
00209
00210 delete[] buff;
00211
00212 d_height = d_width = size;
00213 }
00214
00215
00217
00218
00219
00220
00221
00222
00224
00225 #ifndef USE_DEVIL_LIBRARY
00226
00227
00228
00229 void OpenGLTexture::flipImageTGA(OpenGLTexture::tImageTGA* img)
00230 {
00231 int pitch = img->sizeX * img->channels;
00232
00233
00234 for (int line = 0; line < img->sizeY / 2; ++line)
00235 {
00236 int srcOffset = (line * pitch);
00237 int dstOffest = ((img->sizeY - line - 1) * pitch);
00238
00239 for (int colBit = 0; colBit < pitch; ++colBit)
00240 {
00241 uchar tmp = img->data[dstOffest + colBit];
00242 img->data[dstOffest + colBit] = img->data[srcOffset + colBit];
00243 img->data[srcOffset + colBit] = tmp;
00244 }
00245
00246 }
00247
00248 }
00249
00250
00259
00260 OpenGLTexture::tImageTGA* OpenGLTexture::LoadTGA(const unsigned char* buffer, unsigned int buffer_size)
00261 {
00262 tImageTGA *pImageData = NULL;
00263 short width = 0, height = 0;
00264 GLbyte length = 0;
00265 GLbyte imageType = 0;
00266
00267 GLbyte bits = 0;
00268 int channels = 0;
00269 int stride = 0;
00270 int i = 0;
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286 pImageData = (tImageTGA*)malloc(sizeof(tImageTGA));
00287
00288
00289 memcpy(&length, buffer, sizeof(GLbyte));
00290 buffer += sizeof(GLbyte);
00291
00292
00293 ++buffer;
00294
00295
00296 memcpy(&imageType, buffer, sizeof(GLbyte));
00297 buffer += sizeof(GLbyte);
00298
00299
00300 buffer += 9;
00301
00302
00303 memcpy(&width, buffer, sizeof(short));
00304 buffer += sizeof(short);
00305 memcpy(&height, buffer, sizeof(short));
00306 buffer += sizeof(short);
00307 memcpy(&bits, buffer, sizeof(GLbyte));
00308 buffer += sizeof(GLbyte);
00309
00310
00311 buffer += length + 1;
00312
00313
00314 if(imageType != TGA_RLE)
00315 {
00316
00317 if(bits == 24 || bits == 32)
00318 {
00319
00320
00321 channels = bits / 8;
00322 stride = channels * width;
00323 pImageData->data = new unsigned char[stride * height];
00324
00325
00326 for(int y = 0; y < height; y++)
00327 {
00328
00329 unsigned char *pLine = &(pImageData->data[stride * y]);
00330
00331
00332 memcpy(pLine, buffer, stride);
00333 buffer += stride;
00334
00335
00336
00337 for(i = 0; i < stride; i += channels)
00338 {
00339 int temp = pLine[i];
00340 pLine[i] = pLine[i + 2];
00341 pLine[i + 2] = temp;
00342 }
00343 }
00344 }
00345
00346 else if(bits == 16)
00347 {
00348 unsigned short pixels = 0;
00349 int r=0, g=0, b=0;
00350
00351
00352
00353 channels = 3;
00354 stride = channels * width;
00355 pImageData->data = new unsigned char[stride * height];
00356
00357
00358 for(int i = 0; i < width*height; i++)
00359 {
00360
00361 memcpy(&pixels, buffer, sizeof(unsigned short));
00362 buffer += sizeof(unsigned short);
00363
00364
00365
00366
00367
00368
00369 b = (pixels & 0x1f) << 3;
00370 g = ((pixels >> 5) & 0x1f) << 3;
00371 r = ((pixels >> 10) & 0x1f) << 3;
00372
00373
00374
00375 pImageData->data[i * 3 + 0] = r;
00376 pImageData->data[i * 3 + 1] = g;
00377 pImageData->data[i * 3 + 2] = b;
00378 }
00379 }
00380
00381 else
00382 return NULL;
00383 }
00384
00385 else
00386 {
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405 unsigned char rleID = 0;
00406 int colorsRead = 0;
00407 channels = bits / 8;
00408 stride = channels * width;
00409
00410
00411
00412 pImageData->data = new unsigned char[stride * height];
00413 GLbyte *pColors = new GLbyte [channels];
00414
00415
00416 while(i < width*height)
00417 {
00418
00419 memcpy(&rleID, buffer, sizeof(unsigned char));
00420 buffer += sizeof(unsigned char);
00421
00422
00423 if(rleID < 128)
00424 {
00425
00426 rleID++;
00427
00428
00429 while(rleID)
00430 {
00431
00432 memcpy(pColors, buffer, sizeof(GLbyte) * channels);
00433 buffer += sizeof(GLbyte) * channels;
00434
00435
00436 pImageData->data[colorsRead + 0] = pColors[2];
00437 pImageData->data[colorsRead + 1] = pColors[1];
00438 pImageData->data[colorsRead + 2] = pColors[0];
00439
00440
00441 if(bits == 32)
00442 pImageData->data[colorsRead + 3] = pColors[3];
00443
00444
00445
00446 i++;
00447 rleID--;
00448 colorsRead += channels;
00449 }
00450 }
00451
00452 else
00453 {
00454
00455 rleID -= 127;
00456
00457
00458 memcpy(pColors, buffer, sizeof(GLbyte) * channels);
00459 buffer += sizeof(GLbyte) * channels;
00460
00461
00462 while(rleID)
00463 {
00464
00465 pImageData->data[colorsRead + 0] = pColors[2];
00466 pImageData->data[colorsRead + 1] = pColors[1];
00467 pImageData->data[colorsRead + 2] = pColors[0];
00468
00469
00470 if(bits == 32)
00471 pImageData->data[colorsRead + 3] = pColors[3];
00472
00473
00474
00475 i++;
00476 rleID--;
00477 colorsRead += channels;
00478 }
00479
00480 }
00481
00482 }
00483
00484
00485 delete[] pColors;
00486 }
00487
00488
00489 pImageData->channels = channels;
00490 pImageData->sizeX = width;
00491 pImageData->sizeY = height;
00492
00493
00494 return pImageData;
00495 }
00496 #endif
00497
00498 }