How To: Load an OpenGL Texture using the FreeImage library (or FreeImagePlus, technically)

I’d been using DevIL (or OpenIL if you prefer) as my image loader library, only it hasn’t been updated in a long time and can be a pain to build properly, so I’ve needed to move onto something else. The DevIL fork, ResIL, isn’t quite ready for prime-time and my attempts to build it have resulted in wasted hours and failure (I’ve fixed multiple build errors on the way – but then I hit stuff I can’t see how to fix without trying to re-package the entire thing).

So, new image library, huh? I had a google and saw the FreeImage library (and it’s FreeImagePlus version for C++ – documentation for which can be found here) – and it just happens to be in the Arch community repos so a quick sudo pacman -S freeimage later and we’re ready to rock… Only it didn’t come with any examples, so I dug around on forums and found some code that just about worked, but I wasn’t a big fan of it – so I thought I’d rewrite it into a nicer, more robust method – and I think I’ve achieved just that.

A textured quad at an angle.

The loadTexture Method

Usage

To use the method, just set up your code something like this – in your main .cpp file at the top have:

In your initialisation/setup method add something like this:

In your main method, once you’ve create an OpenGL context (i.e. window) and called your initialise/setup method, then you can load a texture to use like this:

Finally, on shutdown you may (optionally, as long as you’re not using the Linux/Mac .a version of the library) like to add the following:

Wrap-up

Not a great deal to say – it works, it should be relatively robust, it doesn’t leak memory (or at least none that we control), and the code is commented to the hilt and explains why it’s doing things instead of just what it’s doing (some people don’t like verbose code like this – but I teach a lot of programming so I just try to explain everything as clearly as possible as I go – and find I prefer it to ‘terse’ code that I have no idea WTF it’s up to or why it’s bothering).

Many thanks to the FreeImage devs for the library – it’s rather feature-packed and I quite like it (some good example code wouldn’t go amiss though!) =D

Hope you find the code useful! (Bugs? Comments? Suggestions? Feedback always welcome!).

28 thoughts on “How To: Load an OpenGL Texture using the FreeImage library (or FreeImagePlus, technically)”

    1. Call glGetError() before calling the loadTexture() method – it could be something that’s happened previously, but the error is only being checked inside loadTexture(), so it looks like it’s coming from there..

      If loadTexture() is the method causing the invalid enum then I’d make a checkGLError(string location) method and call it at multiple stages, like this:

      – do something
      – checkGLError(“1”);
      – do something else
      – checkGLError(“2”);
      – etc.

      In this way you can track down the exact location of the operation with the invalid enum and fix it.

  1. Thanks.
    This is an old post, but I didn’t know where to ask… I got an error loading the texture – invalid value. Could you tell me what are the possible reasons my image fails to load (when it is in the project directory or not)? This is the 4th library I am trying. I tried stb_image, SOIL, libpng, and all fail to load my image.
    I am stalled at this point in openGL.

  2. Have you tried putting the image to load in the same folder as your executable, or specifying a relative path along with the file name?

    If that doesn’t work I’ll try to provide a working example for you tomorrow.

    1. I was so disappointed and confused that I put the file in ever possible folder in my project, and when that failed, I thought there was maybe something wrong with the file, so I downloaded one, and still failed to load image.
      I had been using a resource folder and specifying a relative path along with the file name before, and that failed also.
      I’ll look forward to the example. Thanks

  3. Okay, here’s a Code::Blocks version of the project. It links against your system’s opengl32.dll, but uses local copies of glew/glfw/glm/freeimageplus. I’ve made sure the Windows version works since that’s what I assume you’re working with – if you have freeimageplus installed on your Linux system then the Linux version of the project is also likely to work but I haven’t tested it.

    To build and run this from inside C::B doesn’t require the image, GLSL shaders (MyShader.vert/MyShader.frag) and FreeImage.dll to be in the same folder as the executable because I think I added ‘.’ to C::B’s search path (i.e. look in the current project directory for files).

    To run the executable standalone you DO require the image, shaders and FreeImage.dll to be in the same folder as the exe.

    I’ve left a compiled version in the bin\Debug folder for you so you can at least test that it’s not something odd going on with your machine that’s causing the issue.

    When you launch the exe don’t move the mouse about too much because it’s bound to the camera – and you may end up ‘looking at nothing’. If you just see a white screen move the mouse around and you should be able to find some textured quads rotating about.

    Oh, and here’s the project file: FreeImagePlus_GLSL.

    Cheers & happy coding!

  4. I’m sorry. I’m using Visual Studio. I don’t have code blocks installed, and I am preserving hard drive space. Would it be possible for you to produce the source code in VS. Would that be putting too much on you (I believe you must be busy). I do appreciate the time you took to respond and provide the example.
    If you can do it in VS, since this is the IDE I prefer to work with, I’d be most grateful.

    1. Looking over the source code of your example, I think I will be able to implement these in VS. Since I am using nuget packages, getting the libraries isn’t a problem.
      I’ll let you know how it goes.

      1. Sure. Have a crack at it yourself, and if you’re really struggling I’ll try to find some time this evening to put together a VS version for you.

            1. I only just finished organizing the codes in VS, and just did a build, but I am receiving linker errors from glfw. I realized your file doesn’t have glfw.lib, so I was thinking that may be the problem. I can’t use my glfw library in my nuget packages, since that’s version 3, while your code uses version 2, and I’d have to make some major changes to your code. (not desirable). So I just downloaded the source, and I’ll see if I can solve the problem from there.
              Having the VS example may make it easier for me, but then it might not, so I made a decision, that if I can’t fix these errors, I’ll install codeblocks, and try it from there.
              You’ve already been quite generous, so you deserve a little rest.
              I’ll let you know in a few hours the results. Thanks again.

                1. glfw.a is in the .\glfw\lib folder – and you know it works because I know it works (it’s just statically linked).

                  We also call:

                  #define glew_static

                  before we pull in the glew header. This helps us to embed glew in the exe so it doesn’t need external files.

    1. Ha
      You have more confidence than I do.
      I didn’t beat the errors, so I installed codeblocks – mingw.
      Without making any adjustments, I just click build. This is the output:
      ————– Build: Debug in FreeImagePlus GLSL (compiler: GNU GCC Compiler)—————

      mingw32-g++.exe -Wall -g -Iglew\include -Iglfw\include -Ifreeimage\include -Ifreeimageplus\include -c E:\GameDevelopment\FreeImagePlus_GLSL\Camera.cpp -o obj\Debug\Camera.o
      Execution of ‘mingw32-g++.exe -Wall -g -Iglew\include -Iglfw\include -Ifreeimage\include -Ifreeimageplus\include -c E:\GameDevelopment\FreeImagePlus_GLSL\Camera.cpp -o obj\Debug\Camera.o’ in ‘E:\GameDevelopment\FreeImagePlus_GLSL’ failed

      I don’t have a clue. Any suggestions?

      1. Is that the full error output? Doesn’t seem complete… Is it moaning about the Camera class?

        The CB project provided works just fine for me so I’m a bit confused now. You shouldn’t have to modify it at all for it to build and run.

        1. Yup. That’s the full output log. It ends with –‘E:\GameDevelopment\FreeImagePlus_GLSL’ failed.

          Don’t worry if you can’t figure it out. At least you tried, and I’d say you were a big help. Actually, I don’t think it’s anything you can fix. Something is wrong somewhere, just that we haven’t figured out where.
          I’m beginning to think it may be system security settings , because I have been following openGL tutorials to a T, and only got stuck at loading an image. There must be a reason why all the libraries I tried failed to load a simple texture file. That’s most definitely odd, since there was no problem with the code. I’ll keep at it, until either I solve it, or I don’t. In either case I’ll get to learn c++, openGL, and shaders. So I still win.
          Thanks for you code. I’ll learn from that too. :)
          If I crack it, I’ll let you know. Cheers

  5. I’m trying to put together a VS2017 version for you… and oh my word it’s being nuisance…

    I can pull in glew, glm and GLFW3 via nuget – but it doesn’t like FreeImage/FreeImagePlus at all – so I’ve just copied those in and linked the libs and put the DLLs in the exe folder – but it’s crashing on startup.

    It all BUILDS but fails on calling “glCreateShader” at the moment – I have no idea why.

    Feels like a DLL issue, but…. who knows?

    1. Man, you must like to work. Don’t pull out your hair trying to get this done. I learned to accept failure, especially when I tried a considerable amount.

  6. It’s more that I don’t like to fail than I like to work… especially when I know that something is perfectly do-able but it’s just being an ass at the moment.

    Sometimes you have to be a bit relentless in your pursuit of goals to actually get there – and also have a positive ‘you learn from every failure’ mindset.

    Anyways, I got it all working in VS2017 – here’s the project:
    FreeImagePlus_GLSL_VS2017.zip

    As before, I’ve left the compiled DEBUG executable for you so you can make sure it runs on your machine – but hopefully this time it’ll build and run for you just fine.

    When you launch the exe don’t touch the mouse for a moment and you should see stuff. As soon as you touch the mouse the camera orientation goes a bit whack and you have to ‘find’ the stuff on screen again by moving the mouse around. Once done you can move around with WSAD and mouse movement like an FPS.

    I’ve fixed this orientation issue before but it was a while ago. I think the fix is to set lastMouseX/lastMouseY to the actual mouseX/mouseY before the very first mouse cursor movement callback runs (because lastMouseX and lastMouseY are 0 by default on startup before any mouse cursor callback occurs) – but it’s taken me about 3 hours of extra work to get this running (lol) so I’ve had enough for one day.

    Anyways, hope this helps.

    1. NOPE. That’s not going to help because deleting the 538MB in the .vs folder before I zipped it up now means it’s forgotten all the include folders and libraries.

      Because why not. Why would you simply store the list of headers, libraries and their paths in the .SLN file, when you could store them somewhere deep in a hidden folder with 500MB+ of rubbish.

      I hate visual studio.

      Okay, fixed it by removing a lot of the hidden “.vs” folder junk but not the database file. Also refactored all paths to be relative so the project doesn’t care where it lives, and I fixed the camera jump-on-first move issue. I’ve overwritten the previous file with the fixed one at the same URL: FreeImagePlus_GLSL_VS2017.zip

      I still hate Visual Studio through =P

          1. Dude, this one worked! Unlike the previous that gave me 56 errors and complained about not finding FreeImagePlus. Hats off to you friend.

            Do you see VS is not as bad as you suggest? You’re hating the best IDE in the world bro. All you need is what Microsoft gives you and there is no problem. Try to implement something that don’t belong, and it will complain, which is no different to any other IDE, only… they still trail VS – by far. :)

            I really do appreciate you doing this though. I don’t think you really know how much I appreciate it. When I get my paypal account sorted out, I will make a contribution to any program you produce (so long as it’s not vile). Just let me know what you got.
            Cheers

            1. That’s fantastic – I’m happy you’re happy =D

              VS isn’t all that bad, I just find some aspects of it a little more difficult to use than other IDEs – and because I use a lot of Linux I like to try to write cross-platform code wherever possible. So in that regard, Code::Blocks works well for me because I can create separate project files for both platforms with different library settings but using the same sourcecode.

              If you really want to make a contribution as thanks then maybe just sling a couple of dollars to a charity like Save The Children or UNICEF or something.

              Cheers & happy coding!

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.