summaryrefslogtreecommitdiff
path: root/DevIL/src-ILUT/src/ilut_opengl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'DevIL/src-ILUT/src/ilut_opengl.cpp')
-rw-r--r--DevIL/src-ILUT/src/ilut_opengl.cpp923
1 files changed, 923 insertions, 0 deletions
diff --git a/DevIL/src-ILUT/src/ilut_opengl.cpp b/DevIL/src-ILUT/src/ilut_opengl.cpp
new file mode 100644
index 00000000..a0530047
--- /dev/null
+++ b/DevIL/src-ILUT/src/ilut_opengl.cpp
@@ -0,0 +1,923 @@
+//-----------------------------------------------------------------------------
+//
+// ImageLib Utility Toolkit Sources
+// Copyright (C) 2000-2002 by Denton Woods
+// Last modified: 05/25/2002 <--Y2K Compliant! =]
+//
+// Filename: src-ILUT/src/ilut_opengl.c
+//
+// Description: OpenGL functions for images
+//
+//-----------------------------------------------------------------------------
+
+
+#include "ilut_opengl.h"
+
+#ifdef ILUT_USE_OPENGL
+
+#include <stdio.h>
+#include <string.h>
+
+#ifdef __APPLE__
+#include <OpenGL/glext.h>
+#include <dlfcn.h>
+void *aglGetProcAddress( const GLubyte *name ) {
+ // deprecated code! and wasn't working
+ /*NSSymbol symbol;
+ char* symbolName;
+ // prepend a '_' for the Unix C symbol mangling convention
+ int len = strlen((const char*)name);
+ symbolName = malloc(len + 2);
+ memcpy(symbolName+1, (const char*)name, len );
+ symbolName[0] = '_';
+ symbol = NULL;
+ if (NSIsSymbolNameDefined(symbolName))
+ symbol = NSLookupAndBindSymbol(symbolName);
+ free(symbolName);
+ return symbol ? NSAddressOfSymbol(symbol) : NULL;
+ */
+ // not deprecated code! and isn't working :(
+ // now the address is directly known with glext.h include
+ const int len = strlen((const char*)name);
+ char *symbolName = calloc(len + 2,1);
+
+ memcpy(symbolName+1, (const char*)name, len );
+ symbolName[0] = '_';
+ printf("searching %s as %s ",name,symbolName);
+ void *image = dlopen(NULL,RTLD_LAZY); // brutal solution
+ if( image == NULL ) {
+ return NULL;
+ }
+ return dlsym(image,symbolName);
+}
+#endif
+
+#ifdef _MSC_VER
+ #pragma comment(lib, "opengl32.lib")
+ #pragma comment(lib, "Glu32.lib")
+// #pragma comment(lib, "freeglut.lib")
+#endif
+
+#ifdef linux
+ // fix for glXGetProcAddressARB
+ #define GLX_GLXEXT_PROTOTYPES
+ #include <GL/glx.h>
+#endif
+
+//used for automatic texture target detection
+#define ILGL_TEXTURE_CUBE_MAP 0x8513
+#define ILGL_TEXTURE_BINDING_CUBE_MAP 0x8514
+#define ILGL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515
+#define ILGL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516
+#define ILGL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517
+#define ILGL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518
+#define ILGL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519
+#define ILGL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A
+#define ILGL_CLAMP_TO_EDGE 0x812F
+#define ILGL_TEXTURE_WRAP_R 0x8072
+
+// Not defined in OpenGL 1.1 headers.
+#define ILGL_TEXTURE_DEPTH 0x8071
+#define ILGL_TEXTURE_3D 0x806F
+#define ILGL_MAX_3D_TEXTURE_SIZE 0x8073
+
+
+static ILboolean HasCubemapHardware = IL_FALSE;
+static ILboolean HasNonPowerOfTwoHardware = IL_FALSE;
+#if defined(_WIN32) || defined(_WIN64) || defined(linux) || defined(__APPLE__)
+ ILGLTEXIMAGE3DARBPROC ilGLTexImage3D = NULL;
+ ILGLTEXSUBIMAGE3DARBPROC ilGLTexSubImage3D = NULL;
+ ILGLCOMPRESSEDTEXIMAGE2DARBPROC ilGLCompressed2D = NULL;
+ ILGLCOMPRESSEDTEXIMAGE3DARBPROC ilGLCompressed3D = NULL;
+#endif
+
+
+// Absolutely *have* to call this if planning on using the image library with OpenGL.
+// Call this after OpenGL has initialized.
+ILboolean ilutGLInit()
+{
+ ILint MaxTexW, MaxTexH, MaxTexD = 1;
+
+ // Should we really be setting all this ourselves? Seems too much like a glu(t) approach...
+ glEnable(GL_TEXTURE_2D);
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+ glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
+ glPixelStorei(GL_PACK_ALIGNMENT, 1);
+
+//#ifndef GL_VERSION_1_3
+ #if (defined (_WIN32) || defined(_WIN64))
+ if (IsExtensionSupported("GL_ARB_texture_compression") &&
+ IsExtensionSupported("GL_EXT_texture_compression_s3tc")) {
+ ilGLCompressed2D = (ILGLCOMPRESSEDTEXIMAGE2DARBPROC)wglGetProcAddress("glCompressedTexImage2DARB");
+ }
+ if (IsExtensionSupported("GL_EXT_texture3D")) {
+ ilGLTexImage3D = (ILGLTEXIMAGE3DARBPROC)wglGetProcAddress("glTexImage3D");
+ ilGLTexImage3D = (ILGLTEXIMAGE3DARBPROC)wglGetProcAddress("glTexSubImage3D");
+ }
+ if (IsExtensionSupported("GL_ARB_texture_compression") &&
+ IsExtensionSupported("GL_EXT_texture_compression_s3tc") &&
+ IsExtensionSupported("GL_EXT_texture3D")) {
+ ilGLCompressed3D = (ILGLCOMPRESSEDTEXIMAGE3DARBPROC)wglGetProcAddress("glCompressedTexImage3DARB");
+ }
+ #elif linux
+ if (IsExtensionSupported("GL_ARB_texture_compression") &&
+ IsExtensionSupported("GL_EXT_texture_compression_s3tc")) {
+ ilGLCompressed2D = (ILGLCOMPRESSEDTEXIMAGE2DARBPROC)
+ glXGetProcAddressARB((const GLubyte*)"glCompressedTexImage2DARB");
+ }
+ if (IsExtensionSupported("GL_EXT_texture3D")) {
+ ilGLTexImage3D = (ILGLTEXIMAGE3DARBPROC)glXGetProcAddressARB((const GLubyte*)"glTexImage3D");
+ }
+ if (IsExtensionSupported("GL_ARB_texture_compression") &&
+ IsExtensionSupported("GL_EXT_texture_compression_s3tc") &&
+ IsExtensionSupported("GL_EXT_texture3D")) {
+ ilGLCompressed3D = (ILGLCOMPRESSEDTEXIMAGE3DARBPROC)glXGetProcAddressARB((const GLubyte*)"glCompressedTexImage3DARB");
+ }
+ #elif defined(__APPLE__)
+ // Mac OS X headers are OpenGL 1.4 compliant already.
+ ilGLCompressed2D = glCompressedTexImage2DARB;//(ILGLCOMPRESSEDTEXIMAGE2DARBPROC)aglGetProcAddress((const GLubyte *)"glCompressedTexImage2DARB");
+ ilGLTexImage3D = glTexImage3D;
+ ilGLCompressed3D = glCompressedTexImage3DARB;
+ #else
+ return IL_FALSE; // @TODO: Find any other systems that we could be on.
+ #endif
+//#else
+//#endif//GL_VERSION_1_3
+
+ // Use PROXY_TEXTURE_2D/3D with glTexImage2D/3D() to test more accurately...
+ glGetIntegerv(GL_MAX_TEXTURE_SIZE, (GLint*)&MaxTexW);
+ glGetIntegerv(GL_MAX_TEXTURE_SIZE, (GLint*)&MaxTexH);
+ if (ilGLTexImage3D != NULL)
+ glGetIntegerv(ILGL_MAX_3D_TEXTURE_SIZE, (GLint*)&MaxTexD);
+ if (MaxTexW <= 0 || MaxTexH <= 0 || MaxTexD <= 0) {
+ MaxTexW = MaxTexH = 256; // Trying this because of the VooDoo series of cards.
+ MaxTexD = 1;
+ }
+
+ ilutSetInteger(ILUT_MAXTEX_WIDTH, MaxTexW);
+ ilutSetInteger(ILUT_MAXTEX_HEIGHT, MaxTexH);
+ ilutSetInteger(ILUT_MAXTEX_DEPTH, MaxTexD);
+
+ if (IsExtensionSupported("GL_ARB_texture_cube_map"))
+ HasCubemapHardware = IL_TRUE;
+ if (IsExtensionSupported("GL_ARB_texture_non_power_of_two"))
+ HasNonPowerOfTwoHardware = IL_TRUE;
+
+ return IL_TRUE;
+}
+
+
+// @TODO: Check what dimensions an image has and use the appropriate IL_IMAGE_XD #define!
+
+GLuint ILAPIENTRY ilutGLBindTexImage()
+{
+ GLuint TexID = 0, Target = GL_TEXTURE_2D;
+ ILimage *Image;
+
+ Image = ilGetCurImage();
+ if (Image == NULL)
+ return 0;
+
+ if (ilutGetBoolean(ILUT_GL_AUTODETECT_TEXTURE_TARGET)) {
+ if (HasCubemapHardware && Image->CubeFlags != 0)
+ Target = ILGL_TEXTURE_CUBE_MAP;
+
+ }
+
+ glGenTextures(1, &TexID);
+ glBindTexture(Target, TexID);
+
+ if (Target == GL_TEXTURE_2D) {
+ glTexParameteri(Target, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameteri(Target, GL_TEXTURE_WRAP_T, GL_REPEAT);
+ }
+ else if (Target == ILGL_TEXTURE_CUBE_MAP) {
+ glTexParameteri(Target, GL_TEXTURE_WRAP_S, ILGL_CLAMP_TO_EDGE);
+ glTexParameteri(Target, GL_TEXTURE_WRAP_T, ILGL_CLAMP_TO_EDGE);
+ glTexParameteri(Target, ILGL_TEXTURE_WRAP_R, ILGL_CLAMP_TO_EDGE);
+ }
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+ glTexParameteri(Target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+ glPixelStorei(GL_UNPACK_SWAP_BYTES, IL_FALSE);
+
+ if (!ilutGLTexImage(0)) {
+ glDeleteTextures(1, &TexID);
+ return 0;
+ }
+
+ return TexID;
+}
+
+
+ILuint GLGetDXTCNum(ILenum DXTCFormat)
+{
+ switch (DXTCFormat)
+ {
+ // Constants from glext.h.
+ case IL_DXT1:
+ DXTCFormat = 0x83F1;
+ break;
+ case IL_DXT3:
+ DXTCFormat = 0x83F2;
+ break;
+ case IL_DXT5:
+ DXTCFormat = 0x83F3;
+ break;
+ }
+
+ return DXTCFormat;
+}
+
+
+// We assume *all* states have been set by the user, including 2D texturing!
+ILboolean ILAPIENTRY ilutGLTexImage_(GLuint Level, GLuint Target, ILimage *Image)
+{
+ ILimage *ImageCopy, *OldImage;
+#if defined (_MSC_VER) || defined (linux) || defined(__APPLE__)
+ ILenum DXTCFormat;
+ ILuint Size;
+ ILubyte *Buffer;
+#endif
+
+ if (Image == NULL) {
+ ilSetError(ILUT_ILLEGAL_OPERATION);
+ return IL_FALSE;
+ }
+
+ OldImage = ilGetCurImage();
+
+#if defined (_MSC_VER) || defined (linux) || defined(__APPLE__)
+ if (ilutGetBoolean(ILUT_GL_USE_S3TC) && ilGLCompressed2D != NULL) {
+ if (Image->DxtcData != NULL && Image->DxtcSize != 0) {
+ DXTCFormat = GLGetDXTCNum(Image->DxtcFormat);
+ ilGLCompressed2D(Target, Level, DXTCFormat, Image->Width,
+ Image->Height, 0, Image->DxtcSize, Image->DxtcData);
+ return IL_TRUE;
+ }
+
+ if (ilutGetBoolean(ILUT_GL_GEN_S3TC)) {
+ DXTCFormat = ilutGetInteger(ILUT_S3TC_FORMAT);
+
+ ilSetCurImage(Image);
+ Size = ilGetDXTCData(NULL, 0, DXTCFormat);
+ if (Size != 0) {
+ Buffer = (ILubyte*)ialloc(Size);
+ if (Buffer == NULL) {
+ ilSetCurImage(OldImage);
+ return IL_FALSE;
+ }
+
+ Size = ilGetDXTCData(Buffer, Size, DXTCFormat);
+ if (Size == 0) {
+ ilSetCurImage(OldImage);
+ ifree(Buffer);
+ return IL_FALSE;
+ }
+
+ DXTCFormat = GLGetDXTCNum(DXTCFormat);
+ ilGLCompressed2D(Target, Level, DXTCFormat, Image->Width,
+ Image->Height, 0, Size, Buffer);
+ ifree(Buffer);
+ ilSetCurImage(OldImage);
+ return IL_TRUE;
+ }
+ ilSetCurImage(OldImage);
+ }
+ }
+#endif//_MSC_VER
+
+ ImageCopy = MakeGLCompliant2D(Image);
+ if (ImageCopy == NULL)
+ return IL_FALSE;
+
+ glTexImage2D(
+ Target,
+ Level,
+ ilutGLFormat(ImageCopy->Format, ImageCopy->Bpp),
+ ImageCopy->Width,
+ ImageCopy->Height,
+ 0,
+ ImageCopy->Format,
+ ImageCopy->Type,
+ ImageCopy->Data);
+
+ if (Image != ImageCopy)
+ ilCloseImage(ImageCopy);
+
+ return IL_TRUE;
+}
+
+GLuint iToGLCube(ILuint cube)
+{
+ switch (cube) {
+ case IL_CUBEMAP_POSITIVEX:
+ return ILGL_TEXTURE_CUBE_MAP_POSITIVE_X;
+ case IL_CUBEMAP_POSITIVEY:
+ return ILGL_TEXTURE_CUBE_MAP_POSITIVE_Y;
+ case IL_CUBEMAP_POSITIVEZ:
+ return ILGL_TEXTURE_CUBE_MAP_POSITIVE_Z;
+ case IL_CUBEMAP_NEGATIVEX:
+ return ILGL_TEXTURE_CUBE_MAP_NEGATIVE_X;
+ case IL_CUBEMAP_NEGATIVEY:
+ return ILGL_TEXTURE_CUBE_MAP_NEGATIVE_Y;
+ case IL_CUBEMAP_NEGATIVEZ:
+ return ILGL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
+
+ default:
+ return ILGL_TEXTURE_CUBE_MAP_POSITIVE_X; //???
+ }
+}
+
+ILboolean ILAPIENTRY ilutGLTexImage(GLuint Level)
+{
+ ILimage *Temp;
+
+ ilutCurImage = ilGetCurImage();
+
+ if (!ilutGetBoolean(ILUT_GL_AUTODETECT_TEXTURE_TARGET))
+ return ilutGLTexImage_(Level, GL_TEXTURE_2D, ilGetCurImage());
+ else {
+ // Autodetect texture target
+
+ // Cubemap
+ if (ilutCurImage->CubeFlags != 0 && HasCubemapHardware) { //bind to cubemap
+ Temp = ilutCurImage;
+ while (Temp != NULL && Temp->CubeFlags != 0) {
+ ilutGLTexImage_(Level, iToGLCube(Temp->CubeFlags), Temp);
+ Temp = Temp->Next;
+ }
+ return IL_TRUE; //@TODO: check for errors??
+ }
+ else // 2D texture
+ return ilutGLTexImage_(Level, GL_TEXTURE_2D, ilGetCurImage());
+ }
+}
+
+GLuint ILAPIENTRY ilutGLBindMipmaps()
+{
+ GLuint TexID = 0;
+
+// glPushAttrib(GL_ALL_ATTRIB_BITS);
+
+ glGenTextures(1, &TexID);
+ glBindTexture(GL_TEXTURE_2D, TexID);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+
+ if (!ilutGLBuildMipmaps()) {
+ glDeleteTextures(1, &TexID);
+ return 0;
+ }
+
+// glPopAttrib();
+
+ return TexID;
+}
+
+
+ILboolean ILAPIENTRY ilutGLBuildMipmaps()
+{
+ ILimage *Image;
+
+ ilutCurImage = ilGetCurImage();
+ if (ilutCurImage == NULL) {
+ ilSetError(ILUT_ILLEGAL_OPERATION);
+ return IL_FALSE;
+ }
+
+ Image = MakeGLCompliant2D(ilutCurImage);
+ if (Image == NULL)
+ return IL_FALSE;
+
+ gluBuild2DMipmaps(GL_TEXTURE_2D, ilutGLFormat(Image->Format, Image->Bpp), Image->Width,
+ Image->Height, Image->Format, Image->Type, Image->Data);
+
+ if (Image != ilutCurImage)
+ ilCloseImage(Image);
+
+ return IL_TRUE;
+}
+
+
+ILboolean ILAPIENTRY ilutGLSubTex(GLuint TexID, ILuint XOff, ILuint YOff)
+{
+ return ilutGLSubTex2D(TexID, XOff, YOff);
+}
+
+
+ILboolean ILAPIENTRY ilutGLSubTex2D(GLuint TexID, ILuint XOff, ILuint YOff)
+{
+ ILimage *Image;
+ ILint Width, Height;
+
+ ilutCurImage = ilGetCurImage();
+ if (ilutCurImage == NULL) {
+ ilSetError(ILUT_ILLEGAL_OPERATION);
+ return IL_FALSE;
+ }
+
+ Image = MakeGLCompliant2D(ilutCurImage);
+ if (Image == NULL)
+ return IL_FALSE;
+
+ glBindTexture(GL_TEXTURE_2D, TexID);
+
+ glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, (GLint*)&Width);
+ glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, (GLint*)&Height);
+
+ if (Image->Width + XOff > (ILuint)Width || Image->Height + YOff > (ILuint)Height) {
+ ilSetError(ILUT_BAD_DIMENSIONS);
+ return IL_FALSE;
+ }
+
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+ glPixelStorei(GL_UNPACK_SWAP_BYTES, IL_FALSE);
+ glTexSubImage2D(GL_TEXTURE_2D, 0, XOff, YOff, Image->Width, Image->Height, Image->Format,
+ Image->Type, Image->Data);
+
+ if (Image != ilutCurImage)
+ ilCloseImage(Image);
+
+ return IL_TRUE;
+}
+
+
+ILboolean ILAPIENTRY ilutGLSubTex3D(GLuint TexID, ILuint XOff, ILuint YOff, ILuint ZOff)
+{
+ ILimage *Image;
+ ILint Width, Height, Depth;
+
+ if (ilGLTexSubImage3D == NULL) {
+ ilSetError(ILUT_ILLEGAL_OPERATION); // Set a different error?
+ return IL_FALSE;
+ }
+
+ ilutCurImage = ilGetCurImage();
+ if (ilutCurImage == NULL) {
+ ilSetError(ILUT_ILLEGAL_OPERATION);
+ return IL_FALSE;
+ }
+
+ Image = MakeGLCompliant3D(ilutCurImage);
+ if (Image == NULL)
+ return IL_FALSE;
+
+ glBindTexture(ILGL_TEXTURE_3D, TexID);
+
+ glGetTexLevelParameteriv(ILGL_TEXTURE_3D, 0, GL_TEXTURE_WIDTH, (GLint*)&Width);
+ glGetTexLevelParameteriv(ILGL_TEXTURE_3D, 0, GL_TEXTURE_HEIGHT, (GLint*)&Height);
+ glGetTexLevelParameteriv(ILGL_TEXTURE_3D, 0, ILGL_TEXTURE_DEPTH, (GLint*)&Depth);
+
+ if (Image->Width + XOff > (ILuint)Width || Image->Height + YOff > (ILuint)Height
+ || Image->Depth + ZOff > (ILuint)Depth) {
+ ilSetError(ILUT_BAD_DIMENSIONS);
+ return IL_FALSE;
+ }
+
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+ glPixelStorei(GL_UNPACK_SWAP_BYTES, IL_FALSE);
+ ilGLTexSubImage3D(ILGL_TEXTURE_3D, 0, XOff, YOff, ZOff, Image->Width, Image->Height, Image->Depth,
+ Image->Format, Image->Type, Image->Data);
+
+ if (Image != ilutCurImage)
+ ilCloseImage(Image);
+
+ return IL_TRUE;
+}
+
+
+ILimage* MakeGLCompliant2D(ILimage *Src)
+{
+ ILimage *Dest = Src, *Temp;
+ ILboolean Created = IL_FALSE;
+ ILenum Filter;
+ ILubyte *Flipped;
+ ILboolean need_resize = IL_FALSE;
+ ILint MaxTexW, MaxTexH;
+
+ MaxTexW = ilutGetInteger(ILUT_MAXTEX_WIDTH);
+ MaxTexH = ilutGetInteger(ILUT_MAXTEX_HEIGHT);
+
+ if (Src->Pal.Palette != NULL && Src->Pal.PalSize != 0 && Src->Pal.PalType != IL_PAL_NONE) {
+ //ilSetCurImage(Src);
+ Dest = iConvertImage(Src, ilGetPalBaseType(Src->Pal.PalType), IL_UNSIGNED_BYTE);
+ //Dest = iConvertImage(IL_BGR);
+ //ilSetCurImage(ilutCurImage);
+ if (Dest == NULL)
+ return NULL;
+
+ Created = IL_TRUE;
+
+ // Change here!
+
+
+ // Set Dest's palette stuff here
+ Dest->Pal.PalType = IL_PAL_NONE;
+ }
+
+ if (HasNonPowerOfTwoHardware == IL_FALSE &&
+ (Src->Width != ilNextPower2(Src->Width) ||
+ Src->Height != ilNextPower2(Src->Height) )) {
+ need_resize = IL_TRUE;
+ }
+
+ if ((ILint)Src->Width > MaxTexW || (ILint)Src->Height > MaxTexH)
+ need_resize = IL_TRUE;
+
+ if (need_resize == IL_TRUE) {
+ if (!Created) {
+ Dest = ilCopyImage_(Src);
+ if (Dest == NULL) {
+ return NULL;
+ }
+ Created = IL_TRUE;
+ }
+
+ Filter = iluGetInteger(ILU_FILTER);
+ if (Src->Format == IL_COLOUR_INDEX) {
+ iluImageParameter(ILU_FILTER, ILU_NEAREST);
+ Temp = HasNonPowerOfTwoHardware == IL_TRUE ?
+ iluScale_(Dest, min((ILuint)MaxTexW, Dest->Width), min((ILuint)MaxTexH, Dest->Height), 1)
+ : iluScale_(Dest, min((ILuint)MaxTexW, ilNextPower2(Dest->Width)),
+ min((ILuint)MaxTexH, ilNextPower2(Dest->Height)), 1);
+ iluImageParameter(ILU_FILTER, Filter);
+ } else {
+ iluImageParameter(ILU_FILTER, ILU_BILINEAR);
+ Temp = HasNonPowerOfTwoHardware == IL_TRUE ?
+ iluScale_(Dest, min((ILuint)MaxTexW, Dest->Width), min((ILuint)MaxTexH, Dest->Height), 1)
+ : iluScale_(Dest, min((ILuint)MaxTexW, (ILint)ilNextPower2(Dest->Width)),
+ min(MaxTexH, (ILint)ilNextPower2(Dest->Height)), 1);
+ iluImageParameter(ILU_FILTER, Filter);
+ }
+
+ ilCloseImage(Dest);
+ if (!Temp) {
+ return NULL;
+ }
+ Dest = Temp;
+ }
+
+ if (Dest->Origin != IL_ORIGIN_LOWER_LEFT) {
+ Flipped = iGetFlipped(Dest);
+ ifree(Dest->Data);
+ Dest->Data = Flipped;
+ Dest->Origin = IL_ORIGIN_LOWER_LEFT;
+ }
+
+ return Dest;
+}
+
+
+ILimage* MakeGLCompliant3D(ILimage *Src)
+{
+ ILimage *Dest = Src, *Temp;
+ ILboolean Created = IL_FALSE;
+ ILenum Filter;
+ ILubyte *Flipped;
+ ILboolean need_resize = IL_FALSE;
+ ILint MaxTexW, MaxTexH, MaxTexD;
+
+ MaxTexW = ilutGetInteger(ILUT_MAXTEX_WIDTH);
+ MaxTexH = ilutGetInteger(ILUT_MAXTEX_HEIGHT);
+ MaxTexD = ilutGetInteger(ILUT_MAXTEX_DEPTH);
+
+ if (Src->Pal.Palette != NULL && Src->Pal.PalSize != 0 && Src->Pal.PalType != IL_PAL_NONE) {
+ //ilSetCurImage(Src);
+ Dest = iConvertImage(Src, ilGetPalBaseType(Src->Pal.PalType), IL_UNSIGNED_BYTE);
+ //Dest = iConvertImage(IL_BGR);
+ //ilSetCurImage(ilutCurImage);
+ if (Dest == NULL)
+ return NULL;
+
+ Created = IL_TRUE;
+
+ // Change here!
+
+
+ // Set Dest's palette stuff here
+ Dest->Pal.PalType = IL_PAL_NONE;
+ }
+
+ if (HasNonPowerOfTwoHardware == IL_FALSE &&
+ (Src->Width != ilNextPower2(Src->Width) ||
+ Src->Height != ilNextPower2(Src->Height) ||
+ Src->Depth != ilNextPower2(Src->Depth) )) {
+ need_resize = IL_TRUE;
+ }
+
+ if ((ILint)Src->Width > MaxTexW || (ILint)Src->Height > MaxTexH || (ILint)Src->Depth > MaxTexD)
+ need_resize = IL_TRUE;
+
+ if (need_resize == IL_TRUE) {
+ if (!Created) {
+ Dest = ilCopyImage_(Src);
+ if (Dest == NULL) {
+ return NULL;
+ }
+ Created = IL_TRUE;
+ }
+
+ Filter = iluGetInteger(ILU_FILTER);
+ if (Src->Format == IL_COLOUR_INDEX) {
+ iluImageParameter(ILU_FILTER, ILU_NEAREST);
+ Temp = HasNonPowerOfTwoHardware == IL_TRUE ?
+ iluScale_(Dest, min((ILuint)MaxTexW, Dest->Width), min((ILuint)MaxTexH, Dest->Height), min((ILuint)MaxTexD, Dest->Depth))
+ : iluScale_(Dest, min((ILuint)MaxTexW, ilNextPower2(Dest->Width)),
+ min((ILuint)MaxTexH, ilNextPower2(Dest->Height)),
+ min((ILuint)MaxTexD, ilNextPower2(Dest->Height)));
+ iluImageParameter(ILU_FILTER, Filter);
+ } else {
+ iluImageParameter(ILU_FILTER, ILU_BILINEAR);
+ Temp = HasNonPowerOfTwoHardware == IL_TRUE ?
+ iluScale_(Dest, min((ILuint)MaxTexW, Dest->Width), min((ILuint)MaxTexH, Dest->Height), min((ILuint)MaxTexD, Dest->Depth))
+ : iluScale_(Dest, min((ILuint)MaxTexW, (ILint)ilNextPower2(Dest->Width)),
+ min(MaxTexH, (ILint)ilNextPower2(Dest->Height)),
+ min(MaxTexD, (ILint)ilNextPower2(Dest->Depth)));
+ iluImageParameter(ILU_FILTER, Filter);
+ }
+
+ ilCloseImage(Dest);
+ if (!Temp) {
+ return NULL;
+ }
+ Dest = Temp;
+ }
+
+ if (Dest->Origin != IL_ORIGIN_LOWER_LEFT) {
+ Flipped = iGetFlipped(Dest);
+ ifree(Dest->Data);
+ Dest->Data = Flipped;
+ Dest->Origin = IL_ORIGIN_LOWER_LEFT;
+ }
+
+ return Dest;
+}
+
+
+//! Just a convenience function.
+#ifndef _WIN32_WCE
+GLuint ILAPIENTRY ilutGLLoadImage(ILstring FileName)
+{
+ GLuint TexId;
+ //ILuint Id;
+
+ iBindImageTemp();
+ //ilGenImages(1, &Id);
+ //ilBindImage(Id);
+
+ if (!ilLoadImage(FileName))
+ return 0;
+
+ TexId = ilutGLBindTexImage();
+
+ //ilDeleteImages(1, &Id);
+
+ return TexId;
+}
+#endif//_WIN32_WCE
+
+
+#ifndef _WIN32_WCE
+ILboolean ILAPIENTRY ilutGLSaveImage(ILstring FileName, GLuint TexID)
+{
+ ILuint CurName;
+ ILboolean Saved;
+
+ CurName = ilGetCurName();
+
+ iBindImageTemp();
+
+ if (!ilutGLSetTex(TexID)) {
+ ilBindImage(CurName);
+ return IL_FALSE;
+ }
+
+ Saved = ilSaveImage(FileName);
+ ilBindImage(CurName);
+
+ return Saved;
+}
+#endif//_WIN32_WCE
+
+
+//! Takes a screenshot of the current OpenGL window.
+ILboolean ILAPIENTRY ilutGLScreen()
+{
+ ILuint ViewPort[4];
+
+ ilutCurImage = ilGetCurImage();
+ if (ilutCurImage == NULL) {
+ ilSetError(ILUT_ILLEGAL_OPERATION);
+ return IL_FALSE;
+ }
+
+ glGetIntegerv(GL_VIEWPORT, (GLint*)ViewPort);
+
+ if (!ilTexImage(ViewPort[2], ViewPort[3], 1, 3, IL_RGB, IL_UNSIGNED_BYTE, NULL))
+ return IL_FALSE; // Error already set.
+ ilutCurImage->Origin = IL_ORIGIN_LOWER_LEFT;
+
+ glPixelStorei(GL_PACK_ALIGNMENT, 1);
+ glReadPixels(0, 0, ViewPort[2], ViewPort[3], GL_RGB, GL_UNSIGNED_BYTE, ilutCurImage->Data);
+
+ return IL_TRUE;
+}
+
+
+#ifndef _WIN32_WCE
+ILboolean ILAPIENTRY ilutGLScreenie()
+{
+ FILE *File;
+ ILchar Buff[255];
+ ILuint i, CurName;
+ ILboolean ReturnVal = IL_TRUE;
+
+ CurName = ilGetCurName();
+
+ // Could go above 128 easily...
+ for (i = 0; i < 128; i++) {
+#ifndef _UNICODE
+ sprintf(Buff, "screen%d.tga", i);
+ File = fopen(Buff, "rb");
+#else
+ swprintf(Buff, 128, L"screen%d.tga", i);
+ // Windows has a different function, _wfopen, to open UTF16 files,
+ // whereas Linux just uses fopen.
+ #ifdef _WIN32
+ File = _wfopen(Buff, L"rb");
+ #else
+ File = fopen((char*)Buff, "rb");
+ #endif
+#endif
+ if (!File)
+ break;
+ fclose(File);
+ }
+
+ if (i == 127) {
+ ilSetError(ILUT_COULD_NOT_OPEN_FILE);
+ return IL_FALSE;
+ }
+
+ iBindImageTemp();
+ if (!ilutGLScreen()) {
+ ReturnVal = IL_FALSE;
+ }
+
+ if (ReturnVal)
+ ilSave(IL_TGA, Buff);
+
+ ilBindImage(CurName);
+
+ return ReturnVal;
+}
+#endif//_WIN32_WCE
+
+
+//! Deprecated - use ilutGLSetTex2D instead.
+ILboolean ILAPIENTRY ilutGLSetTex(GLuint TexID)
+{
+ return ilutGLSetTex2D(TexID);
+}
+
+
+ILboolean ILAPIENTRY ilutGLSetTex2D(GLuint TexID)
+{
+ ILubyte *Data;
+ ILuint Width, Height;
+
+ glBindTexture(GL_TEXTURE_2D, TexID);
+
+ glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, (GLint*)&Width);
+ glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, (GLint*)&Height);
+
+ Data = (ILubyte*)ialloc(Width * Height * 4);
+ if (Data == NULL) {
+ return IL_FALSE;
+ }
+
+ glGetTexImage(GL_TEXTURE_2D, 0, IL_BGRA, GL_UNSIGNED_BYTE, Data);
+
+ if (!ilTexImage(Width, Height, 1, 4, IL_BGRA, IL_UNSIGNED_BYTE, Data)) {
+ ifree(Data);
+ return IL_FALSE;
+ }
+ ilutCurImage->Origin = IL_ORIGIN_LOWER_LEFT;
+
+ ifree(Data);
+ return IL_TRUE;
+}
+
+
+ILboolean ILAPIENTRY ilutGLSetTex3D(GLuint TexID)
+{
+ ILubyte *Data;
+ ILuint Width, Height, Depth;
+
+ if (ilGLTexImage3D == NULL) {
+ ilSetError(ILUT_ILLEGAL_OPERATION); // Set a different error?
+ return IL_FALSE;
+ }
+
+ glBindTexture(ILGL_TEXTURE_3D, TexID);
+
+ glGetTexLevelParameteriv(ILGL_TEXTURE_3D, 0, GL_TEXTURE_WIDTH, (GLint*)&Width);
+ glGetTexLevelParameteriv(ILGL_TEXTURE_3D, 0, GL_TEXTURE_HEIGHT, (GLint*)&Height);
+ glGetTexLevelParameteriv(ILGL_TEXTURE_3D, 0, ILGL_TEXTURE_DEPTH, (GLint*)&Depth);
+
+ Data = (ILubyte*)ialloc(Width * Height * Depth * 4);
+ if (Data == NULL) {
+ return IL_FALSE;
+ }
+
+ glGetTexImage(ILGL_TEXTURE_3D, 0, IL_BGRA, GL_UNSIGNED_BYTE, Data);
+
+ if (!ilTexImage(Width, Height, Depth, 4, IL_BGRA, IL_UNSIGNED_BYTE, Data)) {
+ ifree(Data);
+ return IL_FALSE;
+ }
+ ilutCurImage->Origin = IL_ORIGIN_LOWER_LEFT;
+
+ ifree(Data);
+ return IL_TRUE;
+}
+
+
+
+ILenum ilutGLFormat(ILenum Format, ILubyte Bpp)
+{
+ if (Format == IL_RGB || Format == IL_BGR) {
+ if (ilutIsEnabled(ILUT_OPENGL_CONV)) {
+ return GL_RGB8;
+ }
+ }
+ else if (Format == IL_RGBA || Format == IL_BGRA) {
+ if (ilutIsEnabled(ILUT_OPENGL_CONV)) {
+ return GL_RGBA8;
+ }
+ }
+ else if (Format == IL_ALPHA) {
+ if (ilutIsEnabled(ILUT_OPENGL_CONV)) {
+ return GL_ALPHA;
+ }
+ }
+
+ return Bpp;
+}
+
+
+// From http://www.opengl.org/News/Special/OGLextensions/OGLextensions.html
+// Should we make this accessible outside the lib?
+ILboolean IsExtensionSupported(const char *extension)
+{
+ const GLubyte *extensions;// = NULL;
+ const GLubyte *start;
+ GLubyte *where, *terminator;
+
+ // Extension names should not have spaces.
+ where = (GLubyte *) strchr(extension, ' ');
+ if (where || *extension == '\0')
+ return IL_FALSE;
+ extensions = glGetString(GL_EXTENSIONS);
+ if (!extensions)
+ return IL_FALSE;
+ // It takes a bit of care to be fool-proof about parsing the
+ // OpenGL extensions string. Don't be fooled by sub-strings, etc.
+ start = extensions;
+ for (;;) {
+ where = (GLubyte *)strstr((const char *) start, extension);
+ if (!where)
+ break;
+ terminator = where + strlen(extension);
+ if (where == start || *(where - 1) == ' ')
+ if (*terminator == ' ' || *terminator == '\0')
+ return IL_TRUE;
+ start = terminator;
+ }
+ return IL_FALSE;
+}
+
+
+#endif//ILUT_USE_OPENGL