- Main Page
- Data Structures
- Files

- File List

# E:/DevIL/src-ILUT/src/ilut_opengl.c

    00001 //-----------------------------------------------------------------------------
    00002 //
    00003 // ImageLib Utility Toolkit Sources
    00004 // Copyright (C) 2000-2002 by Denton Woods
    00005 // Last modified: 05/25/2002 <--Y2K Compliant! =]
    00006 //
    00007 // Filename: src-ILUT/src/ilut_opengl.c
    00008 //
    00009 // Description: OpenGL functions for images
    00010 //
    00011 //-----------------------------------------------------------------------------
    00012
    00013
    00014 #include "ilut_opengl.h"
    00015
    00016 #ifdef ILUT_USE_OPENGL
    00017
    00018 #include <stdio.h>
    00019 #include <string.h>
    00020
    00021 #ifdef __APPLE__
    00022 #include <OpenGL/glext.h>
    00023 #include <dlfcn.h>
    00024 void *aglGetProcAddress( const GLubyte *name ) {
    00025         // deprecated code! and wasn't working
    00026         /*NSSymbol symbol;
    00027         char* symbolName;
    00028         // prepend a '_' for the Unix C symbol mangling convention
    00029         int len = strlen((const char*)name);
    00030         symbolName = malloc(len + 2);
    00031         memcpy(symbolName+1, (const char*)name, len );
    00032         symbolName[0] = '_';
    00033         symbol = NULL;
    00034         if (NSIsSymbolNameDefined(symbolName))
    00035                 symbol = NSLookupAndBindSymbol(symbolName);
    00036         free(symbolName);
    00037         return symbol ? NSAddressOfSymbol(symbol) : NULL;
    00038         */
    00039         // not deprecated code! and isn't working :(
    00040         // now the address is directly known with glext.h include
    00041         const int len = strlen((const char*)name);
    00042         char *symbolName = calloc(len + 2,1);
    00043
    00044         memcpy(symbolName+1, (const char*)name, len );
    00045         symbolName[0] = '_';
    00046         printf("searching %s as %s ",name,symbolName);
    00047         void *image = dlopen(NULL,RTLD_LAZY); // brutal solution
    00048         if( image == NULL ) {
    00049                 return NULL;
    00050         }
    00051         return dlsym(image,symbolName);
    00052 }
    00053 #endif
    00054
    00055 #ifdef _MSC_VER
    00056         #pragma comment(lib, "opengl32.lib")
    00057         #pragma comment(lib, "Glu32.lib")
    00058 //      #pragma comment(lib, "freeglut.lib")
    00059 #endif
    00060
    00061 #ifdef linux
    00062         // fix for glXGetProcAddressARB
    00063         #define GLX_GLXEXT_PROTOTYPES
    00064         #include <GL/glx.h>
    00065 #endif
    00066
    00067 //used for automatic texture target detection
    00068 #define ILGL_TEXTURE_CUBE_MAP                           0x8513
    00069 #define ILGL_TEXTURE_BINDING_CUBE_MAP           0x8514
    00070 #define ILGL_TEXTURE_CUBE_MAP_POSITIVE_X        0x8515
    00071 #define ILGL_TEXTURE_CUBE_MAP_NEGATIVE_X        0x8516
    00072 #define ILGL_TEXTURE_CUBE_MAP_POSITIVE_Y        0x8517
    00073 #define ILGL_TEXTURE_CUBE_MAP_NEGATIVE_Y        0x8518
    00074 #define ILGL_TEXTURE_CUBE_MAP_POSITIVE_Z        0x8519
    00075 #define ILGL_TEXTURE_CUBE_MAP_NEGATIVE_Z        0x851A
    00076 #define ILGL_CLAMP_TO_EDGE                                      0x812F
    00077 #define ILGL_TEXTURE_WRAP_R                                     0x8072
    00078
    00079 // Not defined in OpenGL 1.1 headers.
    00080 #define ILGL_TEXTURE_DEPTH                                      0x8071
    00081 #define ILGL_TEXTURE_3D                                         0x806F
    00082 #define ILGL_MAX_3D_TEXTURE_SIZE                        0x8073
    00083
    00084
    00085 static ILboolean HasCubemapHardware = IL_FALSE;
    00086 static ILboolean HasNonPowerOfTwoHardware = IL_FALSE;
    00087 #if defined(_WIN32) || defined(_WIN64) || defined(linux) || defined(__APPLE__)
    00088         ILGLTEXIMAGE3DARBPROC                   ilGLTexImage3D = NULL;
    00089         ILGLTEXSUBIMAGE3DARBPROC                ilGLTexSubImage3D = NULL;
    00090         ILGLCOMPRESSEDTEXIMAGE2DARBPROC ilGLCompressed2D = NULL;
    00091         ILGLCOMPRESSEDTEXIMAGE3DARBPROC ilGLCompressed3D = NULL;
    00092 #endif
    00093
    00094
    00095 // Absolutely *have* to call this if planning on using the image library with OpenGL.
    00096 //      Call this after OpenGL has initialized.
    00097 ILboolean ilutGLInit()
    00098 {
    00099         ILint MaxTexW, MaxTexH, MaxTexD = 1;
    00100
    00101         // Should we really be setting all this ourselves?  Seems too much like a glu(t) approach...
    00102         glEnable(GL_TEXTURE_2D);
    00103         glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
    00104         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    00105         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    00106         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    00107         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    00108         glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    00109         glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
    00110         glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
    00111         glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
    00112         glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
    00113         glPixelStorei(GL_PACK_ALIGNMENT, 1);
    00114
    00115 //#ifndef GL_VERSION_1_3
    00116         #if (defined (_WIN32) || defined(_WIN64))
    00117                 if (IsExtensionSupported("GL_ARB_texture_compression") &&
    00118                         IsExtensionSupported("GL_EXT_texture_compression_s3tc")) {
    00119                                 ilGLCompressed2D = (ILGLCOMPRESSEDTEXIMAGE2DARBPROC)wglGetProcAddress("glCompressedTexImage2DARB");
    00120                 }
    00121                 if (IsExtensionSupported("GL_EXT_texture3D")) {
    00122                         ilGLTexImage3D = (ILGLTEXIMAGE3DARBPROC)wglGetProcAddress("glTexImage3D");
    00123                         ilGLTexImage3D = (ILGLTEXIMAGE3DARBPROC)wglGetProcAddress("glTexSubImage3D");
    00124                 }
    00125                 if (IsExtensionSupported("GL_ARB_texture_compression") &&
    00126                         IsExtensionSupported("GL_EXT_texture_compression_s3tc") &&
    00127                         IsExtensionSupported("GL_EXT_texture3D")) {
    00128                                 ilGLCompressed3D = (ILGLCOMPRESSEDTEXIMAGE3DARBPROC)wglGetProcAddress("glCompressedTexImage3DARB");
    00129                 }
    00130         #elif linux
    00131                 if (IsExtensionSupported("GL_ARB_texture_compression") &&
    00132                         IsExtensionSupported("GL_EXT_texture_compression_s3tc")) {
    00133                                 ilGLCompressed2D = (ILGLCOMPRESSEDTEXIMAGE2DARBPROC)
    00134                                         glXGetProcAddressARB((const GLubyte*)"glCompressedTexImage2DARB");
    00135                 }
    00136                 if (IsExtensionSupported("GL_EXT_texture3D")) {
    00137                         ilGLTexImage3D = (ILGLTEXIMAGE3DARBPROC)glXGetProcAddressARB((const GLubyte*)"glTexImage3D");
    00138                 }
    00139                 if (IsExtensionSupported("GL_ARB_texture_compression") &&
    00140                         IsExtensionSupported("GL_EXT_texture_compression_s3tc") &&
    00141                         IsExtensionSupported("GL_EXT_texture3D")) {
    00142                                 ilGLCompressed3D = (ILGLCOMPRESSEDTEXIMAGE3DARBPROC)glXGetProcAddressARB((const GLubyte*)"glCompressedTexImage3DARB");
    00143                 }
    00144         #elif defined(__APPLE__)
    00145                 // Mac OS X headers are OpenGL 1.4 compliant already.
    00146                 ilGLCompressed2D = glCompressedTexImage2DARB;//(ILGLCOMPRESSEDTEXIMAGE2DARBPROC)aglGetProcAddress((const GLubyte *)"glCompressedTexImage2DARB");
    00147                 ilGLTexImage3D = glTexImage3D;
    00148                 ilGLCompressed3D = glCompressedTexImage3DARB;
    00149         #else
    00150                 return IL_FALSE;  // @TODO: Find any other systems that we could be on.
    00151         #endif
    00152 //#else
    00153 //#endif//GL_VERSION_1_3
    00154
    00155         // Use PROXY_TEXTURE_2D/3D with glTexImage2D/3D() to test more accurately...
    00156         glGetIntegerv(GL_MAX_TEXTURE_SIZE, (GLint*)&MaxTexW);
    00157         glGetIntegerv(GL_MAX_TEXTURE_SIZE, (GLint*)&MaxTexH);
    00158         if (ilGLTexImage3D != NULL)
    00159                 glGetIntegerv(ILGL_MAX_3D_TEXTURE_SIZE, (GLint*)&MaxTexD);
    00160         if (MaxTexW == 0 || MaxTexH == 0 || MaxTexD == 0) {
    00161                 MaxTexW = MaxTexH = 256;  // Trying this because of the VooDoo series of cards.
    00162                 MaxTexD = 1;
    00163         }
    00164
    00165         ilutSetInteger(ILUT_MAXTEX_WIDTH, MaxTexW);
    00166         ilutSetInteger(ILUT_MAXTEX_HEIGHT, MaxTexH);
    00167         ilutSetInteger(ILUT_MAXTEX_DEPTH, MaxTexD);
    00168
    00169         if (IsExtensionSupported("GL_ARB_texture_cube_map"))
    00170                 HasCubemapHardware = IL_TRUE;
    00171         if (IsExtensionSupported("GL_ARB_texture_non_power_of_two"))
    00172                 HasNonPowerOfTwoHardware = IL_TRUE;
    00173
    00174         return IL_TRUE;
    00175 }
    00176
    00177
    00178 // @TODO:  Check what dimensions an image has and use the appropriate IL_IMAGE_XD #define!
    00179
    00180 GLuint ILAPIENTRY ilutGLBindTexImage()
    00181 {
    00182         GLuint  TexID = 0, Target = GL_TEXTURE_2D;
    00183         ILimage *Image;
    00184
    00185         Image = ilGetCurImage();
    00186         if (Image == NULL)
    00187                 return 0;
    00188
    00189         if (ilutGetBoolean(ILUT_GL_AUTODETECT_TEXTURE_TARGET)) {
    00190                 if (HasCubemapHardware && Image->CubeFlags != 0)
    00191                         Target = ILGL_TEXTURE_CUBE_MAP;
    00192
    00193         }
    00194
    00195         glGenTextures(1, &TexID);
    00196         glBindTexture(Target, TexID);
    00197
    00198         if (Target == GL_TEXTURE_2D) {
    00199                 glTexParameteri(Target, GL_TEXTURE_WRAP_S, GL_REPEAT);
    00200                 glTexParameteri(Target, GL_TEXTURE_WRAP_T, GL_REPEAT);
    00201         }
    00202         else if (Target == ILGL_TEXTURE_CUBE_MAP) {
    00203                 glTexParameteri(Target, GL_TEXTURE_WRAP_S, ILGL_CLAMP_TO_EDGE);
    00204                 glTexParameteri(Target, GL_TEXTURE_WRAP_T, ILGL_CLAMP_TO_EDGE);
    00205                 glTexParameteri(Target, ILGL_TEXTURE_WRAP_R, ILGL_CLAMP_TO_EDGE);
    00206         }
    00207         glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
    00208         glTexParameteri(Target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    00209         glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    00210         glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    00211         glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
    00212         glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
    00213         glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
    00214         glPixelStorei(GL_UNPACK_SWAP_BYTES, IL_FALSE);
    00215
    00216         if (!ilutGLTexImage(0)) {
    00217                 glDeleteTextures(1, &TexID);
    00218                 return 0;
    00219         }
    00220
    00221         return TexID;
    00222 }
    00223
    00224
    00225 ILuint GLGetDXTCNum(ILenum DXTCFormat)
    00226 {
    00227         switch (DXTCFormat)
    00228         {
    00229                 // Constants from glext.h.
    00230                 case IL_DXT1:
    00231                         DXTCFormat = 0x83F1;
    00232                         break;
    00233                 case IL_DXT3:
    00234                         DXTCFormat = 0x83F2;
    00235                         break;
    00236                 case IL_DXT5:
    00237                         DXTCFormat = 0x83F3;
    00238                         break;
    00239         }
    00240
    00241         return DXTCFormat;
    00242 }
    00243
    00244
    00245 // We assume *all* states have been set by the user, including 2D texturing!
    00246 ILboolean ILAPIENTRY ilutGLTexImage_(GLuint Level, GLuint Target, ILimage *Image)
    00247 {
    00248         ILimage *ImageCopy, *OldImage;
    00249 #if defined (_MSC_VER) || defined (linux) || defined(__APPLE__)
    00250         ILenum  DXTCFormat;
    00251         ILuint  Size;
    00252         ILubyte *Buffer;
    00253 #endif
    00254
    00255         if (Image == NULL) {
    00256                 ilSetError(ILUT_ILLEGAL_OPERATION);
    00257                 return IL_FALSE;
    00258         }
    00259
    00260         OldImage = ilGetCurImage();
    00261
    00262 #if defined (_MSC_VER) || defined (linux) || defined(__APPLE__)
    00263         if (ilutGetBoolean(ILUT_GL_USE_S3TC) && ilGLCompressed2D != NULL) {
    00264                 if (Image->DxtcData != NULL && Image->DxtcSize != 0) {
    00265                         DXTCFormat = GLGetDXTCNum(Image->DxtcFormat);
    00266                         ilGLCompressed2D(Target, Level, DXTCFormat, Image->Width,
    00267                                 Image->Height, 0, Image->DxtcSize, Image->DxtcData);
    00268                         return IL_TRUE;
    00269                 }
    00270
    00271                 if (ilutGetBoolean(ILUT_GL_GEN_S3TC)) {
    00272                         DXTCFormat = ilutGetInteger(ILUT_S3TC_FORMAT);
    00273
    00274                         ilSetCurImage(Image);
    00275                         Size = ilGetDXTCData(NULL, 0, DXTCFormat);
    00276                         if (Size != 0) {
    00277                                 Buffer = (ILubyte*)ialloc(Size);
    00278                                 if (Buffer == NULL) {
    00279                                         ilSetCurImage(OldImage);
    00280                                         return IL_FALSE;
    00281                                 }
    00282
    00283                                 Size = ilGetDXTCData(Buffer, Size, DXTCFormat);
    00284                                 if (Size == 0) {
    00285                                         ilSetCurImage(OldImage);
    00286                                         ifree(Buffer);
    00287                                         return IL_FALSE;
    00288                                 }
    00289
    00290                                 DXTCFormat = GLGetDXTCNum(DXTCFormat);
    00291                                 ilGLCompressed2D(Target, Level, DXTCFormat, Image->Width,
    00292                                         Image->Height, 0, Size, Buffer);
    00293                                 ifree(Buffer);
    00294                                 ilSetCurImage(OldImage);
    00295                                 return IL_TRUE;
    00296                         }
    00297                         ilSetCurImage(OldImage);
    00298                 }
    00299         }
    00300 #endif//_MSC_VER
    00301
    00302         ImageCopy = MakeGLCompliant2D(Image);
    00303         if (ImageCopy == NULL)
    00304                 return IL_FALSE;
    00305
    00306         glTexImage2D(
    00307                         Target,
    00308                         Level,
    00309                         ilutGLFormat(ImageCopy->Format, ImageCopy->Bpp),
    00310                         ImageCopy->Width,
    00311                         ImageCopy->Height,
    00312                         0,
    00313                         ImageCopy->Format,
    00314                         ImageCopy->Type,
    00315                         ImageCopy->Data);
    00316
    00317         if (Image != ImageCopy)
    00318                 ilCloseImage(ImageCopy);
    00319
    00320         return IL_TRUE;
    00321 }
    00322
    00323 GLuint iToGLCube(ILuint cube)
    00324 {
    00325         switch (cube) {
    00326                 case IL_CUBEMAP_POSITIVEX:
    00327                         return ILGL_TEXTURE_CUBE_MAP_POSITIVE_X;
    00328                 case IL_CUBEMAP_POSITIVEY:
    00329                         return ILGL_TEXTURE_CUBE_MAP_POSITIVE_Y;
    00330                 case IL_CUBEMAP_POSITIVEZ:
    00331                         return ILGL_TEXTURE_CUBE_MAP_POSITIVE_Z;
    00332                 case IL_CUBEMAP_NEGATIVEX:
    00333                         return ILGL_TEXTURE_CUBE_MAP_NEGATIVE_X;
    00334                 case IL_CUBEMAP_NEGATIVEY:
    00335                         return ILGL_TEXTURE_CUBE_MAP_NEGATIVE_Y;
    00336                 case IL_CUBEMAP_NEGATIVEZ:
    00337                         return ILGL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
    00338
    00339                 default:
    00340                         return ILGL_TEXTURE_CUBE_MAP_POSITIVE_X; //???
    00341         }
    00342 }
    00343
    00344 ILboolean ILAPIENTRY ilutGLTexImage(GLuint Level)
    00345 {
    00346         ILimage *Temp;
    00347
    00348         ilutCurImage = ilGetCurImage();
    00349
    00350         if (!ilutGetBoolean(ILUT_GL_AUTODETECT_TEXTURE_TARGET))
    00351                 return ilutGLTexImage_(Level, GL_TEXTURE_2D, ilGetCurImage());
    00352         else {
    00353                 // Autodetect texture target
    00354
    00355                 // Cubemap
    00356                 if (ilutCurImage->CubeFlags != 0 && HasCubemapHardware) { //bind to cubemap
    00357                         Temp = ilutCurImage;
    00358                         while (Temp != NULL && Temp->CubeFlags != 0) {
    00359                                 ilutGLTexImage_(Level, iToGLCube(Temp->CubeFlags), Temp);
    00360                                 Temp = Temp->Next;
    00361                         }
    00362                         return IL_TRUE; //@TODO: check for errors??
    00363                 }
    00364                 else  // 2D texture
    00365                         return ilutGLTexImage_(Level, GL_TEXTURE_2D, ilGetCurImage());
    00366         }
    00367 }
    00368
    00369 GLuint ILAPIENTRY ilutGLBindMipmaps()
    00370 {
    00371         GLuint  TexID = 0;
    00372
    00373 //      glPushAttrib(GL_ALL_ATTRIB_BITS);
    00374
    00375         glGenTextures(1, &TexID);
    00376         glBindTexture(GL_TEXTURE_2D, TexID);
    00377
    00378         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    00379         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    00380         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    00381         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
    00382
    00383         if (!ilutGLBuildMipmaps()) {
    00384                 glDeleteTextures(1, &TexID);
    00385                 return 0;
    00386         }
    00387
    00388 //      glPopAttrib();
    00389
    00390         return TexID;
    00391 }
    00392
    00393
    00394 ILboolean ILAPIENTRY ilutGLBuildMipmaps()
    00395 {
    00396         ILimage *Image;
    00397
    00398         ilutCurImage = ilGetCurImage();
    00399         if (ilutCurImage == NULL) {
    00400                 ilSetError(ILUT_ILLEGAL_OPERATION);
    00401                 return IL_FALSE;
    00402         }
    00403
    00404         Image = MakeGLCompliant2D(ilutCurImage);
    00405         if (Image == NULL)
    00406                 return IL_FALSE;
    00407
    00408         gluBuild2DMipmaps(GL_TEXTURE_2D, ilutGLFormat(Image->Format, Image->Bpp), Image->Width,
    00409                                                 Image->Height, Image->Format, Image->Type, Image->Data);
    00410
    00411         if (Image != ilutCurImage)
    00412                 ilCloseImage(Image);
    00413
    00414         return IL_TRUE;
    00415 }
    00416
    00417
    00418 ILboolean ILAPIENTRY ilutGLSubTex(GLuint TexID, ILuint XOff, ILuint YOff)
    00419 {
    00420         return ilutGLSubTex2D(TexID, XOff, YOff);
    00421 }
    00422
    00423
    00424 ILboolean ILAPIENTRY ilutGLSubTex2D(GLuint TexID, ILuint XOff, ILuint YOff)
    00425 {
    00426         ILimage *Image;
    00427         ILint Width, Height;
    00428
    00429         ilutCurImage = ilGetCurImage();
    00430         if (ilutCurImage == NULL) {
    00431                 ilSetError(ILUT_ILLEGAL_OPERATION);
    00432                 return IL_FALSE;
    00433         }
    00434
    00435         Image = MakeGLCompliant2D(ilutCurImage);
    00436         if (Image == NULL)
    00437                 return IL_FALSE;
    00438
    00439         glBindTexture(GL_TEXTURE_2D, TexID);
    00440
    00441         glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH,  (GLint*)&Width);
    00442         glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, (GLint*)&Height);
    00443
    00444         if (Image->Width + XOff > (ILuint)Width || Image->Height + YOff > (ILuint)Height) {
    00445                 ilSetError(ILUT_BAD_DIMENSIONS);
    00446                 return IL_FALSE;
    00447         }
    00448
    00449         glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    00450         glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
    00451         glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
    00452         glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
    00453         glPixelStorei(GL_UNPACK_SWAP_BYTES, IL_FALSE);
    00454         glTexSubImage2D(GL_TEXTURE_2D, 0, XOff, YOff, Image->Width, Image->Height, Image->Format,
    00455                         Image->Type, Image->Data);
    00456
    00457         if (Image != ilutCurImage)
    00458                 ilCloseImage(Image);
    00459
    00460         return IL_TRUE;
    00461 }
    00462
    00463
    00464 ILboolean ILAPIENTRY ilutGLSubTex3D(GLuint TexID, ILuint XOff, ILuint YOff, ILuint ZOff)
    00465 {
    00466         ILimage *Image;
    00467         ILint Width, Height, Depth;
    00468
    00469         if (ilGLTexSubImage3D == NULL) {
    00470                 ilSetError(ILUT_ILLEGAL_OPERATION);  // Set a different error?
    00471                 return IL_FALSE;
    00472         }
    00473
    00474         ilutCurImage = ilGetCurImage();
    00475         if (ilutCurImage == NULL) {
    00476                 ilSetError(ILUT_ILLEGAL_OPERATION);
    00477                 return IL_FALSE;
    00478         }
    00479
    00480         Image = MakeGLCompliant3D(ilutCurImage);
    00481         if (Image == NULL)
    00482                 return IL_FALSE;
    00483
    00484         glBindTexture(ILGL_TEXTURE_3D, TexID);
    00485
    00486         glGetTexLevelParameteriv(ILGL_TEXTURE_3D, 0, GL_TEXTURE_WIDTH,  (GLint*)&Width);
    00487         glGetTexLevelParameteriv(ILGL_TEXTURE_3D, 0, GL_TEXTURE_HEIGHT, (GLint*)&Height);
    00488         glGetTexLevelParameteriv(ILGL_TEXTURE_3D, 0, ILGL_TEXTURE_DEPTH, (GLint*)&Depth);
    00489
    00490         if (Image->Width + XOff > (ILuint)Width || Image->Height + YOff > (ILuint)Height
    00491                 || Image->Depth + ZOff > (ILuint)Depth) {
    00492                 ilSetError(ILUT_BAD_DIMENSIONS);
    00493                 return IL_FALSE;
    00494         }
    00495
    00496         glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    00497         glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
    00498         glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
    00499         glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
    00500         glPixelStorei(GL_UNPACK_SWAP_BYTES, IL_FALSE);
    00501         ilGLTexSubImage3D(ILGL_TEXTURE_3D, 0, XOff, YOff, ZOff, Image->Width, Image->Height, Image->Depth,
    00502                         Image->Format, Image->Type, Image->Data);
    00503
    00504         if (Image != ilutCurImage)
    00505                 ilCloseImage(Image);
    00506
    00507         return IL_TRUE;
    00508 }
    00509
    00510
    00511 ILimage* MakeGLCompliant2D(ILimage *Src)
    00512 {
    00513         ILimage         *Dest = Src, *Temp;
    00514         ILboolean       Created = IL_FALSE;
    00515         ILenum          Filter;
    00516         ILubyte         *Flipped;
    00517         ILboolean   need_resize = IL_FALSE;
    00518         ILint           MaxTexW, MaxTexH;
    00519
    00520         MaxTexW = ilutGetInteger(ILUT_MAXTEX_WIDTH);
    00521         MaxTexH = ilutGetInteger(ILUT_MAXTEX_HEIGHT);
    00522
    00523         if (Src->Pal.Palette != NULL && Src->Pal.PalSize != 0 && Src->Pal.PalType != IL_PAL_NONE) {
    00524                 //ilSetCurImage(Src);
    00525                 Dest = iConvertImage(Src, ilGetPalBaseType(Src->Pal.PalType), IL_UNSIGNED_BYTE);
    00526                 //Dest = iConvertImage(IL_BGR);
    00527                 //ilSetCurImage(ilutCurImage);
    00528                 if (Dest == NULL)
    00529                         return NULL;
    00530
    00531                 Created = IL_TRUE;
    00532
    00533                 // Change here!
    00534
    00535
    00536                 // Set Dest's palette stuff here
    00537                 Dest->Pal.PalType = IL_PAL_NONE;
    00538         }
    00539
    00540         if (HasNonPowerOfTwoHardware == IL_FALSE &&
    00541                   (Src->Width  != ilNextPower2(Src->Width)  ||
    00542                    Src->Height != ilNextPower2(Src->Height)  )) {
    00543                                 need_resize = IL_TRUE;
    00544                         }
    00545
    00546         if ((ILint)Src->Width > MaxTexW || (ILint)Src->Height > MaxTexH)
    00547                 need_resize = IL_TRUE;
    00548
    00549         if (need_resize == IL_TRUE) {
    00550                 if (!Created) {
    00551                         Dest = ilCopyImage_(Src);
    00552                         if (Dest == NULL) {
    00553                                 return NULL;
    00554                         }
    00555                         Created = IL_TRUE;
    00556                 }
    00557
    00558                 Filter = iluGetInteger(ILU_FILTER);
    00559                 if (Src->Format == IL_COLOUR_INDEX) {
    00560                         iluImageParameter(ILU_FILTER, ILU_NEAREST);
    00561                         Temp = HasNonPowerOfTwoHardware == IL_TRUE ?
    00562                                 iluScale_(Dest, min((ILuint)MaxTexW, Dest->Width), min((ILuint)MaxTexH, Dest->Height), 1)
    00563                           : iluScale_(Dest, min((ILuint)MaxTexW, ilNextPower2(Dest->Width)),
    00564                                         min((ILuint)MaxTexH, ilNextPower2(Dest->Height)), 1);
    00565                         iluImageParameter(ILU_FILTER, Filter);
    00566                 } else {
    00567                         iluImageParameter(ILU_FILTER, ILU_BILINEAR);
    00568                         Temp = HasNonPowerOfTwoHardware == IL_TRUE ?
    00569                                 iluScale_(Dest, min((ILuint)MaxTexW, Dest->Width), min((ILuint)MaxTexH, Dest->Height), 1)
    00570                          :      iluScale_(Dest, min((ILuint)MaxTexW, (ILint)ilNextPower2(Dest->Width)),
    00571                                         min(MaxTexH, (ILint)ilNextPower2(Dest->Height)), 1);
    00572                         iluImageParameter(ILU_FILTER, Filter);
    00573                 }
    00574
    00575                 ilCloseImage(Dest);
    00576                 if (!Temp) {
    00577                         return NULL;
    00578                 }
    00579                 Dest = Temp;
    00580         }
    00581
    00582         if (Dest->Origin != IL_ORIGIN_LOWER_LEFT) {
    00583                 Flipped = iGetFlipped(Dest);
    00584                 ifree(Dest->Data);
    00585                 Dest->Data = Flipped;
    00586                 Dest->Origin = IL_ORIGIN_LOWER_LEFT;
    00587         }
    00588
    00589         return Dest;
    00590 }
    00591
    00592
    00593 ILimage* MakeGLCompliant3D(ILimage *Src)
    00594 {
    00595         ILimage         *Dest = Src, *Temp;
    00596         ILboolean       Created = IL_FALSE;
    00597         ILenum          Filter;
    00598         ILubyte         *Flipped;
    00599         ILboolean   need_resize = IL_FALSE;
    00600         ILint           MaxTexW, MaxTexH, MaxTexD;
    00601
    00602         MaxTexW = ilutGetInteger(ILUT_MAXTEX_WIDTH);
    00603         MaxTexH = ilutGetInteger(ILUT_MAXTEX_HEIGHT);
    00604         MaxTexD = ilutGetInteger(ILUT_MAXTEX_DEPTH);
    00605
    00606         if (Src->Pal.Palette != NULL && Src->Pal.PalSize != 0 && Src->Pal.PalType != IL_PAL_NONE) {
    00607                 //ilSetCurImage(Src);
    00608                 Dest = iConvertImage(Src, ilGetPalBaseType(Src->Pal.PalType), IL_UNSIGNED_BYTE);
    00609                 //Dest = iConvertImage(IL_BGR);
    00610                 //ilSetCurImage(ilutCurImage);
    00611                 if (Dest == NULL)
    00612                         return NULL;
    00613
    00614                 Created = IL_TRUE;
    00615
    00616                 // Change here!
    00617
    00618
    00619                 // Set Dest's palette stuff here
    00620                 Dest->Pal.PalType = IL_PAL_NONE;
    00621         }
    00622
    00623         if (HasNonPowerOfTwoHardware == IL_FALSE &&
    00624                   (Src->Width  != ilNextPower2(Src->Width)  ||
    00625                    Src->Height != ilNextPower2(Src->Height) ||
    00626                    Src->Depth  != ilNextPower2(Src->Depth) )) {
    00627                                 need_resize = IL_TRUE;
    00628                         }
    00629
    00630         if ((ILint)Src->Width > MaxTexW || (ILint)Src->Height > MaxTexH || (ILint)Src->Depth > MaxTexD)
    00631                 need_resize = IL_TRUE;
    00632
    00633         if (need_resize == IL_TRUE) {
    00634                 if (!Created) {
    00635                         Dest = ilCopyImage_(Src);
    00636                         if (Dest == NULL) {
    00637                                 return NULL;
    00638                         }
    00639                         Created = IL_TRUE;
    00640                 }
    00641
    00642                 Filter = iluGetInteger(ILU_FILTER);
    00643                 if (Src->Format == IL_COLOUR_INDEX) {
    00644                         iluImageParameter(ILU_FILTER, ILU_NEAREST);
    00645                         Temp = HasNonPowerOfTwoHardware == IL_TRUE ?
    00646                                 iluScale_(Dest, min((ILuint)MaxTexW, Dest->Width), min((ILuint)MaxTexH, Dest->Height), min((ILuint)MaxTexD, Dest->Depth))
    00647                           : iluScale_(Dest, min((ILuint)MaxTexW, ilNextPower2(Dest->Width)),
    00648                                         min((ILuint)MaxTexH, ilNextPower2(Dest->Height)),
    00649                                         min((ILuint)MaxTexD, ilNextPower2(Dest->Height)));
    00650                         iluImageParameter(ILU_FILTER, Filter);
    00651                 } else {
    00652                         iluImageParameter(ILU_FILTER, ILU_BILINEAR);
    00653                         Temp = HasNonPowerOfTwoHardware == IL_TRUE ?
    00654                                 iluScale_(Dest, min((ILuint)MaxTexW, Dest->Width), min((ILuint)MaxTexH, Dest->Height), min((ILuint)MaxTexD, Dest->Depth))
    00655                          :      iluScale_(Dest, min((ILuint)MaxTexW, (ILint)ilNextPower2(Dest->Width)),
    00656                                         min(MaxTexH, (ILint)ilNextPower2(Dest->Height)),
    00657                                         min(MaxTexD, (ILint)ilNextPower2(Dest->Depth)));
    00658                         iluImageParameter(ILU_FILTER, Filter);
    00659                 }
    00660
    00661                 ilCloseImage(Dest);
    00662                 if (!Temp) {
    00663                         return NULL;
    00664                 }
    00665                 Dest = Temp;
    00666         }
    00667
    00668         if (Dest->Origin != IL_ORIGIN_LOWER_LEFT) {
    00669                 Flipped = iGetFlipped(Dest);
    00670                 ifree(Dest->Data);
    00671                 Dest->Data = Flipped;
    00672                 Dest->Origin = IL_ORIGIN_LOWER_LEFT;
    00673         }
    00674
    00675         return Dest;
    00676 }
    00677
    00678
    00680 #ifndef _WIN32_WCE
    00681 GLuint ILAPIENTRY ilutGLLoadImage(ILstring FileName)
    00682 {
    00683         GLuint  TexId;
    00684         //ILuint        Id;
    00685
    00686         iBindImageTemp();
    00687         //ilGenImages(1, &Id);
    00688         //ilBindImage(Id);
    00689
    00690         if (!ilLoadImage(FileName))
    00691                 return 0;
    00692
    00693         TexId = ilutGLBindTexImage();
    00694
    00695         //ilDeleteImages(1, &Id);
    00696
    00697         return TexId;
    00698 }
    00699 #endif//_WIN32_WCE
    00700
    00701
    00702 #ifndef _WIN32_WCE
    00703 ILboolean ILAPIENTRY ilutGLSaveImage(ILstring FileName, GLuint TexID)
    00704 {
    00705         ILuint          CurName;
    00706         ILboolean       Saved;
    00707
    00708         CurName = ilGetCurName();
    00709
    00710         iBindImageTemp();
    00711
    00712         if (!ilutGLSetTex(TexID)) {
    00713                 ilBindImage(CurName);
    00714                 return IL_FALSE;
    00715         }
    00716
    00717         Saved = ilSaveImage(FileName);
    00718         ilBindImage(CurName);
    00719
    00720         return Saved;
    00721 }
    00722 #endif//_WIN32_WCE
    00723
    00724
    00726 ILboolean ILAPIENTRY ilutGLScreen()
    00727 {
    00728         ILuint  ViewPort[4];
    00729
    00730         ilutCurImage = ilGetCurImage();
    00731         if (ilutCurImage == NULL) {
    00732                 ilSetError(ILUT_ILLEGAL_OPERATION);
    00733                 return IL_FALSE;
    00734         }
    00735
    00736         glGetIntegerv(GL_VIEWPORT, (GLint*)ViewPort);
    00737
    00738         if (!ilTexImage(ViewPort[2], ViewPort[3], 1, 3, IL_RGB, IL_UNSIGNED_BYTE, NULL))
    00739                 return IL_FALSE;  // Error already set.
    00740         ilutCurImage->Origin = IL_ORIGIN_LOWER_LEFT;
    00741
    00742         glPixelStorei(GL_PACK_ALIGNMENT, 1);
    00743         glReadPixels(0, 0, ViewPort[2], ViewPort[3], GL_RGB, GL_UNSIGNED_BYTE, ilutCurImage->Data);
    00744
    00745         return IL_TRUE;
    00746 }
    00747
    00748
    00749 #ifndef _WIN32_WCE
    00750 ILboolean ILAPIENTRY ilutGLScreenie()
    00751 {
    00752         FILE            *File;
    00753         ILchar          Buff[255];
    00754         ILuint          i, CurName;
    00755         ILboolean       ReturnVal = IL_TRUE;
    00756
    00757         CurName = ilGetCurName();
    00758
    00759         // Could go above 128 easily...
    00760         for (i = 0; i < 128; i++) {
    00761 #ifndef _UNICODE
    00762                 sprintf(Buff, "screen%d.tga", i);
    00763                 File = fopen(Buff, "rb");
    00764 #else
    00765                 swprintf(Buff, 128, L"screen%d.tga", i);
    00766                 // Windows has a different function, _wfopen, to open UTF16 files,
    00767                 //  whereas Linux just uses fopen.
    00768                 #ifdef _WIN32
    00769                         File = _wfopen(Buff, L"rb");
    00770                 #else
    00771                         File = fopen((char*)Buff, "rb");
    00772                 #endif
    00773 #endif
    00774                 if (!File)
    00775                         break;
    00776                 fclose(File);
    00777         }
    00778
    00779         if (i == 127) {
    00780                 ilSetError(ILUT_COULD_NOT_OPEN_FILE);
    00781                 return IL_FALSE;
    00782         }
    00783
    00784         iBindImageTemp();
    00785         if (!ilutGLScreen()) {
    00786                 ReturnVal = IL_FALSE;
    00787         }
    00788
    00789         if (ReturnVal)
    00790                 ilSave(IL_TGA, Buff);
    00791
    00792         ilBindImage(CurName);
    00793
    00794         return ReturnVal;
    00795 }
    00796 #endif//_WIN32_WCE
    00797
    00798
    00800 ILboolean ILAPIENTRY ilutGLSetTex(GLuint TexID)
    00801 {
    00802         return ilutGLSetTex2D(TexID);
    00803 }
    00804
    00805
    00806 ILboolean ILAPIENTRY ilutGLSetTex2D(GLuint TexID)
    00807 {
    00808         ILubyte *Data;
    00809         ILuint Width, Height;
    00810
    00811         glBindTexture(GL_TEXTURE_2D, TexID);
    00812
    00813         glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH,  (GLint*)&Width);
    00814         glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, (GLint*)&Height);
    00815
    00816         Data = (ILubyte*)ialloc(Width * Height * 4);
    00817         if (Data == NULL) {
    00818                 return IL_FALSE;
    00819         }
    00820
    00821         glGetTexImage(GL_TEXTURE_2D, 0, IL_BGRA, GL_UNSIGNED_BYTE, Data);
    00822
    00823         if (!ilTexImage(Width, Height, 1, 4, IL_BGRA, IL_UNSIGNED_BYTE, Data)) {
    00824                 ifree(Data);
    00825                 return IL_FALSE;
    00826         }
    00827         ilutCurImage->Origin = IL_ORIGIN_LOWER_LEFT;
    00828
    00829         ifree(Data);
    00830         return IL_TRUE;
    00831 }
    00832
    00833
    00834 ILboolean ILAPIENTRY ilutGLSetTex3D(GLuint TexID)
    00835 {
    00836         ILubyte *Data;
    00837         ILuint Width, Height, Depth;
    00838
    00839         if (ilGLTexImage3D == NULL) {
    00840                 ilSetError(ILUT_ILLEGAL_OPERATION);  // Set a different error?
    00841                 return IL_FALSE;
    00842         }
    00843
    00844         glBindTexture(ILGL_TEXTURE_3D, TexID);
    00845
    00846         glGetTexLevelParameteriv(ILGL_TEXTURE_3D, 0, GL_TEXTURE_WIDTH,  (GLint*)&Width);
    00847         glGetTexLevelParameteriv(ILGL_TEXTURE_3D, 0, GL_TEXTURE_HEIGHT, (GLint*)&Height);
    00848         glGetTexLevelParameteriv(ILGL_TEXTURE_3D, 0, ILGL_TEXTURE_DEPTH, (GLint*)&Depth);
    00849
    00850         Data = (ILubyte*)ialloc(Width * Height * Depth * 4);
    00851         if (Data == NULL) {
    00852                 return IL_FALSE;
    00853         }
    00854
    00855         glGetTexImage(ILGL_TEXTURE_3D, 0, IL_BGRA, GL_UNSIGNED_BYTE, Data);
    00856
    00857         if (!ilTexImage(Width, Height, Depth, 4, IL_BGRA, IL_UNSIGNED_BYTE, Data)) {
    00858                 ifree(Data);
    00859                 return IL_FALSE;
    00860         }
    00861         ilutCurImage->Origin = IL_ORIGIN_LOWER_LEFT;
    00862
    00863         ifree(Data);
    00864         return IL_TRUE;
    00865 }
    00866
    00867
    00868
    00869 ILenum ilutGLFormat(ILenum Format, ILubyte Bpp)
    00870 {
    00871         if (Format == IL_RGB || Format == IL_BGR) {
    00872                 if (ilutIsEnabled(ILUT_OPENGL_CONV)) {
    00873                         return GL_RGB8;
    00874                 }
    00875         }
    00876         else if (Format == IL_RGBA || Format == IL_BGRA) {
    00877                 if (ilutIsEnabled(ILUT_OPENGL_CONV)) {
    00878                         return GL_RGBA8;
    00879                 }
    00880         }
    00881         else if (Format == IL_ALPHA) {
    00882                 if (ilutIsEnabled(ILUT_OPENGL_CONV)) {
    00883                         return GL_ALPHA;
    00884                 }
    00885         }
    00886
    00887         return Bpp;
    00888 }
    00889
    00890
    00891 // From http://www.opengl.org/News/Special/OGLextensions/OGLextensions.html
    00892 //      Should we make this accessible outside the lib?
    00893 ILboolean IsExtensionSupported(const char *extension)
    00894 {
    00895         const GLubyte *extensions;// = NULL;
    00896         const GLubyte *start;
    00897         GLubyte *where, *terminator;
    00898
    00899         // Extension names should not have spaces.
    00900         where = (GLubyte *) strchr(extension, ' ');
    00901         if (where || *extension == '\0')
    00902                 return IL_FALSE;
    00903         extensions = glGetString(GL_EXTENSIONS);
    00904         if (!extensions)
    00905                 return IL_FALSE;
    00906         // It takes a bit of care to be fool-proof about parsing the
    00907         // OpenGL extensions string. Don't be fooled by sub-strings, etc.
    00908         start = extensions;
    00909         for (;;) {
    00910                 where = (GLubyte *)strstr((const char *) start, extension);
    00911                 if (!where)
    00912                         break;
    00913                 terminator = where + strlen(extension);
    00914                 if (where == start || *(where - 1) == ' ')
    00915                 if (*terminator == ' ' || *terminator == '\0')
    00916                         return IL_TRUE;
    00917                 start = terminator;
    00918         }
    00919         return IL_FALSE;
    00920 }
    00921
    00922
    00923 #endif//ILUT_USE_OPENGL