DevIL Logo
      A full featured cross-platform image library.


About

News

Download

SourceForge Home

Documentation
Tutorials

Logos

Links

Projects

Contact Us

Tutorial 10: OpenGL AccessLast Revised: 9:26 PM 07/31/2001
DevIL provides some powerful access to the Open Graphics Library (OpenGL) API through DevILUT. DevIL is quite particularly suited to OpenGL, as DevIL was created specifically with OpenGL in mind. Of course, you do not *have* to use DevILUT at all and can call glTexImage2D with the image data ilGetData returns and the image information ilGetInteger reports. I would consider this an effort at reinventing the wheel, though, just like writing your own image loading functions. =]

Getting Started
Before you call any ilut functions dealing with OpenGL and after you have initialized OpenGL, you *must* call ilutRenderer with the ILUT_OPENGL parameter.

Required line to initialize DevIL's OpenGL access.
ilutRenderer(ILUT_OPENGL);

How ILUT Handles Textures
DevIL allows the use of arbitrarily-sized images, but OpenGL only works with images that have dimensions that are powers of 2, for optimization purposes. If an image has dimensions that are not powers of 2, DevIL will resize the image before sending it to OpenGL. Alternatively, you could use glTexSubImage2D after creating a texture, but this is outside the scope of this tutorial.

DevIL will properly handle paletted images with ease, but OpenGL does not natively supports these types of images. Ilut could utilize the paletted texture extension, but I decided against this, as the support seems shoddy, and nVidia does not even seem to support it on their cards. So, if an image is paletted, Ilut will convert the image to its truecolour equivalent before sending it off to OpenGL.

DevIL is only limited in the size of images it can load by the amount of system memory that is available. OpenGL does not have this luxury and must fit images in the video card's limited memory. The main reason you must call ilutRenderer is for ilut to determine just how large an image the video card can handle. glGetIntegerv reports this information and is called when you call ilutRenderer. If you try to send an image to OpenGL that is too large, DevIL will automatically convert the image to appropriate dimensions. If you do not call ilutRenderer, the largest dimensions of an image your video card can handle will be assumed to be 256x256.

One last conversion that may take place is if you have the origin set via ilEnable and ilOriginFunc. The image will be flipped if its origin is opposite that which you have set (such as if you changed the default origin after loading the image). If you wish to find out exactly what is going behind the scenes in Ilut, look at MakeGLCompliant in opengl.c. This is where all conversions take place.

ILUT_OPENGL_CONV
Some nVidia cards have this "feature" where they will automatically convert all images to 16-bit to save memory. This is good and all, but it introduces dithering effects. To counter this, call ilutEnable with the ILUT_OPENGL_CONV parameter. What this does is send a different value as the internalFormat parameter of glTexImage2D. The new values are GL_RGB8 and GL_RGBA8 instead of GL_RGB and GL_RGBA, respectively.

How to disable on-board conversion.
ilutEnable(ILUT_OPENGL_CONV);

Straight-Up Access to OpenGL
ILboolean ilutOglTexImage(GLuint Level);

ilutOglTexImage is the simplest of the ilut GL functions. Basically, all this function does is call glTexImage2D after performing any required conversions. The Level parameter allows you to manually set mipmaps.

GLuint ilutOglBindTexImage(ILvoid);

ilutOglBindTexImage is similar to the aforementioned ilutOglTexImage, except it generates and binds a texture via glGenTextures and glBindTexture. When you call ilutOglTexImage, you already have to have your texture bound, so this function makes it easier for the developer. Also, this function sets many of the texture environment settings, so this integrated solution may not be perfect for you. The return value is the OpenGL texture name. If it is 0, an error occurred.

Mipmapping With OpenGL
ILboolean ilutOglBuildMipmaps(ILvoid);

ilutOglBuildMipmaps is the mipmapping equivalent of ilutOglTexImage. Right now, it creates mipmaps via gluBuild2DMipmaps but may use DevIL's mipmap generation functions in the future.

GLuint ilutGLBindTexImage(ILvoid);

ilutGLBindTexImage is the mipmapping equivalent of ilutOglBindTexImage. This function is similar to ilutOglBuildMipmaps in that it performs the same operations, but it generates and binds an OpenGL texture and sets various texture states before generating mipmaps. The return value is the OpenGL texture name. If it is 0, an error occurred.

Simple Solutions
GLuint ilutOglLoadImage(char *FileName);

Feel that there is no reason to mess directly with DevIL, as you will not need a local copy of the DevIL images you load as OpenGL textures? If so, ilutOglLoadImage is for you. This function bypasses the need to generate image names, etc. Just call ilutOglLoadImage with the name of the file you wish to load, and it will load the image directly into an OpenGL texture, then delete all unnecessary local data. This function is quick and simple to use if it is all you will need.

Screenshots
Sometimes you want to take a screenshot, such as an in-game shot. ilutOglScreen can perform this for you.

ILboolean ilutOglScreen(ILvoid);

ilutOglScreen loads the viewport's data into the current bound image, for you to decide what to do with it. If you want to automate the process even further and save the viewport's data directly to disk, use:

ILboolean ilutOglScreenie(ILvoid);

ilutOglScreenie does not modify the current bound image at all. This function is very specialized and saves the image to a Targa file with the filename format of screen%d.tga, where %d is a number from 0 to 126. This function will probably not be suited to most developers' preferences.