Simple texture loading with DevIL revisited
r3dux | September 8, 2011I wrote an article a while back about loading images to use as textures in OpenGL, and in it I’d written my own single line image to texture-handle function because I couldn’t get the built-in ilutGLLoadImage function to work. Since I’ve been getting blank looks and failure to compile reports about it, I thought I’d go and take a look at it again, and this time ilutGLLoadImage seems to work just fine, so let’s document it up properly shall we?
Pre-requisites
You will need:
- A C++ compiler of your choice (I prefer Code::Blocks)
- Working OpenGL drivers
- A copy of DevIL
- A copy of GLEW (GL Extension Wrangler – to make the functionality in your OpenGL drivers availble for use)
- A copy of GLFW (GL FrameWork – to quickly and easily set up a OpenGL context)
- An image to load
Preparation and libraries
Create a new project in your IDE of choice, and link in the following libraries:

You’ll have to figure out where the libraries are on your own system but these are where they are on mine, where a /usr/local/ address indicates packages I’ve build myself, /usr/lib/ indicates standard system installed packages, and no prefix uses any paths defined by the compiler (in this case /usr/ where the lib and include directories are assumed). I’ve also added /usr/local/ to the include path so that any headers in /usr/local/include/ are picked up before any in /usr/include. Yes, library paths are a pain
Also, be sure that your project includes its own directory as the working directory (i.e. the directory to be in when executing) so that you can place your image (in this example, a file called abstract-image.jpg) in the main project directory and it’ll be picked up when we try to load it. The way that you specify the working directory will vary depending on the IDE you’re using, but in Code::Blocks you set it from Project | Properties | Build targets like this:

Source Code
Create a new project with source code something like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 | #include <iostream> #include <cstdlib> #include <GL/glew.h> // Include GLEW, which pulls in OpenGL headers as required #include <GL/glfw.h> // Include OpenGL Framework headers #define ILUT_USE_OPENGL // This MUST be defined before calling the DevIL headers or we don't get OpenGL functionality #include <IL/il.h> #include <IL/ilu.h> #include <IL/ilut.h> GLuint textureHandle; // Create a uint to store the handle to our texture GLfloat frameCount = 0.0f; void initGL(int width, int height) { // ----- Initialise GLEW ----- GLenum err = glewInit(); if (GLEW_OK != err) { std::cout << "GLEW initialisation error: " << glewGetErrorString(err) << std::endl; exit(-1); } std::cout << "GLEW intialised successfully. Using GLEW version: " << glewGetString(GLEW_VERSION) << std::endl; // ----- Window and Projection Settings ----- // Set the window title glfwSetWindowTitle("ilutGLLoadImage Test | September 2011 | r3dux.org"); // Setup our viewport to be the entire size of the window glViewport(0, 0, (GLsizei)width, (GLsizei)height); GLfloat ratio = (float)width / (float)height; // Calculate the window ratio // Change to the projection matrix, reset the matrix and set up our projection glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45.0f, ratio, 0.1f, 100.0f); // Params: Field-of-Vision, window-ration, near-clip-plane, far-clip-plane // ----- OpenGL settings ----- glfwSwapInterval(1); // Lock to vertical sync of monitor (normally 60Hz, so 60fps) glEnable(GL_DEPTH); // Enable the depth buffer glDepthFunc(GL_LEQUAL); // Set our depth function to overwrite if new value less than or equal to current value glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Ask for nicest perspective correction glEnable(GL_TEXTURE_2D); // Enable 2D textures // ----- Initialize DevIL libraries ----- // DevIL sanity check if ( (iluGetInteger(IL_VERSION_NUM) < IL_VERSION) || (iluGetInteger(ILU_VERSION_NUM) < ILU_VERSION) || (ilutGetInteger(ILUT_VERSION_NUM) < ILUT_VERSION) ) { std::cout << "DevIL versions are different... Exiting." << std::endl; exit(-1); } // Initialise all DevIL functionality ilInit(); iluInit(); ilutInit(); ilutRenderer(ILUT_OPENGL); // Tell DevIL that we're using OpenGL for our rendering } void drawScene() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear the screen and depth buffer // Reset the matrix to identity glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(0.0f, 0.0f, -40.0f); // Move things back into the screen glRotatef(frameCount, 0.1f, 1.0f, 0.3f); // Rotate the MVP matrix orientation glBindTexture(GL_TEXTURE_2D, textureHandle); // Select the texture to use and bind to it static float hsize = 15.0f; // Vertical size of the quad static float vsize = 10.0f; // Vertical size of the quad // Draw our textured geometry (just a rectangle in this instance) glEnable(GL_TEXTURE_2D); glBegin(GL_QUADS); glTexCoord2f(0.0, 0.0); glVertex3f(-hsize, -vsize, 0.0f); // Top left glTexCoord2f(0.0, 1.0); glVertex3f(-hsize, vsize, 0.0f); // Bottom left glTexCoord2f(1.0, 1.0); glVertex3f(hsize, vsize, 0.0f); // Bottom right glTexCoord2f(1.0, 0.0); glVertex3f(hsize, -vsize, 0.0f); // Top right glEnd(); glDisable(GL_TEXTURE_2D); // ----- Stop Drawing Stuff! ------ glfwSwapBuffers(); // Swap the buffers to display the scene (so we don't have to watch it being drawn!) frameCount++; } int main() { // Window settings int width = 800, height = 600; int redBits = 8, greenBits = 8, blueBits = 8; int alphaBits = 8, depthBits = 24, stencilBits = 8; // Flag to keep our main loop running bool running = true; // Initialise glfw glfwInit(); // Create a window if(!glfwOpenWindow(width, height, redBits, greenBits, blueBits, alphaBits, depthBits, stencilBits, GLFW_WINDOW)) { std::cout << "Failed to open window!" << std::endl; glfwTerminate(); return 0; } initGL(width, height); // Call our initGL function to set up our OpenGL options ILstring imageFilename = "abstract-image.jpg"; // Specify filename textureHandle = ilutGLLoadImage(imageFilename); // Load image directly to texture // Output last image loaded properties // Available properties list is at: http://www-f9.ijs.si/~matevz/docs/DevIL/il/f00027.htm std::cout << "Image width : " << ilGetInteger(IL_IMAGE_WIDTH) << std::endl; std::cout << "Image height : " << ilGetInteger(IL_IMAGE_HEIGHT) << std::endl; std::cout << "Image bits per pixel: " << ilGetInteger(IL_IMAGE_BITS_PER_PIXEL) << std::endl; // Main loop while (running == true) { // Draw our scene drawScene(); // exit if ESC was pressed or window was closed running = !glfwGetKey(GLFW_KEY_ESC) && glfwGetWindowParam( GLFW_OPENED); } glfwTerminate(); return 0; } |
End Result
If you’ve linked in the libraries and used source code like the above, you should end up with a working texture that looks something like this:

And information regarding the image being used that looks something like this:

I’ve attached a copy of my Code::Blocks project here for anyone who wants it.
Cheers!
Credits: The wallpaper I used as the texture in this guide is Life by N.Design Studio, which you can find here.











nice one Al looks quite spic
When I try with recommended libraries, above, i get segfault on FreeBSD 10.0-CURRENT.
However, adding thr library to link works. It seems one of the OpenGL ports is built against the alternate threading library.
My system is running:
GLEW version 1.9.0
Reporting capabilities of display :0.0, visual 0x2b
Running on a GeForce GT 220/PCIe/SSE2 from NVIDIA Corporation
OpenGL version 3.3.0 NVIDIA 310.32 is supported
I did not try Code::Blocks but here is a Makefile for the example:
CXX= /usr/local/bin/clang++
CC= /usr/local/bin/clang
CXXFLAGS+= -std=c++11 -stdlib=libc++ -I/usr/local/include -Wall -Werror -pedantic
LIBS+= -lGLEW -lGL -lthr -lIL -lILU -lILUT -lglfw -lGLU
LDFLAGS+= -L/usr/local/lib
all: testone
testone:
${CXX} ${CXXFLAGS} ${LDFLAGS} ${LIBS} -o testone testone.cpp
clean:
rm -f testone
(I also changed a couple of lines, to avoid compiler warning)
ILstring imageFilename = “abstract-image.jpg”; // Specify filename
textureHandle = ilutGLLoadImage(imageFilename); // Load image directly to texture
to
textureHandle = ilutGLLoadImage((ILstring)”abstract-image.jpg”); // Load image directly to texture
to get example to compile.
Thank you.