21/02/2010 OpenGL tip: Generate mipmaps

Through the years OpenGL has seen three different methods to generate mipmaps. Now days mipmaps are absolutely common and should be used it most of the cases, even bi-linear filtering because it provides both higher performance and higher visual quality for just 1/3 of image memory cost.

The first method is available since OpenGL 1.1 and used to be gluBuild2DMipmaps. It generates mipmaps on the CPU side and automatically calls glTexImage2D for each level just like if the programmer was generating them himself or loading a S3TC texture. A good feature at that time was the capability of gluBuild2DMipmaps to use NPOT textures and convert them to power of two (POT) mipmaps. Until OpenGL 2.0, graphics card didn't had POT 2D textures support beside rectangular textures...

gluBuild2DMipmaps is the solution for convenience but isn't efficient and out dated feature wise. POT can be useful but can't be used anymore and mipmaps generation on FrameBuffer Object is really complicated and inefficient. It would involve copying the texture data from the graphics memory to the main memory and sending it back in the graphics memory... I don't like so much this method but I must admit that it is a really good method for some compatibilities issues with old hardware or OpenGL implementation that doesn't support NPOT textures or doesn't provide other mipmaps generation method. Moreover, at texture loading, this method feats well in a compatibility code path.

OpenGL 1.4 brings the second method with the extention GL_SGIS_generate_mipmap. This method is "hardware accelerated"; the OpenGL API is simple but completely weard because based on a state change using glTexParameter*.

  • glTexParameteri(Target, GL_GENERATE_MIPMAP, GL_TRUE);

A state change for an operation... sound awkward? It is! This call will NOT generate any mipmap. It only says that when a modification to the base level mipmap is done, the lower mipmaps of the base level mipmap shoud be generated. For example, when loading a texture, it means that this previous call should be done before glTexImage2D.

  • GL_GENERATE_MIPMAP can't be used with NPOT if there are not supported by the hardware of GL_ARB_texture_non_power_of_two.
  • GL_GENERATE_MIPMAP can't be used with framebuffer object.
  • GL_GENERATE_MIPMAP doesn't provide a fine control of when the mipmaps should be generated. The best you can do, is disable GL_GENERATE_MIPMAP, update several parts of the texture and enable it just before the last update... awkward.

Finally, but not least, for everyone who is using OpenGL ES 2.0, OpenGL 3.x or hardware supporting GL_EXT_framebuffer_object: glGenerateMipmap!

This function does actually two things which is maybe the only issue with it: It allocates the mipmaps memory and generate the mipmaps. This is very important to notice for framebuffer object texture mipmaps generation because it might reduce render to texture efficiency or simply crash depending if you are using nVidia or ATI OpenGL implementation.

Example of glGnerateMipmap for rendering to mipmapped texture:
  • //Create the mipmapped texture
  • glGenTextures(1, &ColorbufferName);
  • glBindTexture(ColorbufferName);
  • glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 512, 512, 0, GL_UNSIGNED_BYTE, NULL);
  • glGenerateMipmap(GL_TEXTURE_2D); // /!\ Allocate the mipmaps /!\
  • ...
  • //Create the framebuffer object and attach the mipmapped texture
  • glBindFramebuffer(GL_FRAMEBUFFER, FramebufferName);
  • glFramebufferTexture2D(
  • GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, ColorbufferName, 0);
  • ...
  • //Commands to actually draw something
  • render();
  • ...
  • //Generate the mipmaps of ColorbufferName
  • glActiveTexture(GL_TEXTURE0);
  • glBindTexture(GL_TEXTURE_2D, ColorbufferName);
  • glGenerateMipmap(GL_TEXTURE_2D);

On the software design point of view, glGenerateMipmap will make programmers happy as generating mipmaps with it is completely independent from texture modifications.

  • "Hardware acceleration".
  • Mipmaps generation of Framebuffer Object textures.
  • A fine control of when mipmaps are generated.
  • A great API to use within the OpenGL program.

Finally, OpenGL provides the function call glHint(GL_GENERATE_MIPMAP_HINT, Hint); where 'hint' could be GL_FASTEST, GL_NICEST or GL_DONT_CARE to indicate the quality of filtering when generating mipmaps.

My personal advice would be to use glGenerateMipmap but is need to be available on your platform. From GeForce FX 5*** and Radeon 9*** you will have support for GL_EXT_framebuffer_object or GL_ARB_framebuffer_object with updated drivers. S3 supports GL_EXT_framebuffer_object and OpenGL 3 with its Chrome 430. Apple supports glGenerateMipmap from MacOS X 10.2 and even Intel claims a support. (I would not confirm that one without a test!) If you really need compatibility with old platform, gluBuild2DMipmaps is a great and solid choice.

G-Truc Creation 6.3 source released >
< GLM 0.9 Alpha 2 released
Copyright Christophe Riccio 2002-2016 all rights reserved
Designed for Chrome 9, Firefox 4, Opera 11 and Safari 5