views:

234

answers:

2

Hi,

I am having trouble implementing mipmapping in OpenGL. I am using OpenFrameworks and have modified the ofTexture class to support the creation and rendering of mipmaps.

The following code is the original texture creation code from the class (slightly modified for clarity):

  glEnable(texData.textureTarget);
      glBindTexture(texData.textureTarget, (GLuint)texData.textureID);
      glTexSubImage2D(texData.textureTarget, 0, 0, 0, w, h, texData.glType, texData.pixelType, data);
      glTexParameteri(texData.textureTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
      glTexParameteri(texData.textureTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  glDisable(texData.textureTarget);

This is my version with mipmap support:

  glEnable(texData.textureTarget);
       glBindTexture(texData.textureTarget, (GLuint)texData.textureID);
       gluBuild2DMipmaps(texData.textureTarget, texData.glTypeInternal, w, h, texData.glType, texData.pixelType, data);
       glTexParameteri(texData.textureTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR);
       glTexParameteri(texData.textureTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
  glDisable(texData.textureTarget);

The code does not generate errors (gluBuild2DMipmaps returns '0') and the textures are rendered without problems. However, I do not see any difference.

The scene I render consists of "flat, square tiles" at z=0. It's basically a 2D scene. I zoom in and out by using "glScale()" before drawing the tiles. When I zoom out, the pixels of the tile textures start to "dance", indicating (as far as I can tell) unfiltered texture look-up. See: http://www.youtube.com/watch?v=b_As2Np3m8A at 25s.

My question is: since I do not move the camera position, but only use scaling of the whole scene, does this mean OpenGL can not decide on the appropriate mipmap level and uses the full texture size (level 0)?

Paul

A: 

You should probably switch to automatic mipmap generation if you're targeting OpenGL >= 1.4.

You could try changing GL_TEXTURE_MIN/MAX_LOD to force a particular mip level.

genpfault
Thanks, I tried the MIN/MAX_LOD option but again no effect. I noticed, though, that glTexSubImage2D() does not support mipmapping. I have changed it to a glTexImage2D() call and also followed the advice about automatic mipmap generation. Still no success, there's no visual difference and the pixels still flicker. My driver has OpenGL2.1 support so it should work. I am perplexed, hehe.
Droozle
A: 

Mipmapping will compensate for scene scale in addition to perspective distance. The vertex shader outputs (which the driver will still create even if you aren't using your own shader) specify the screenspace coordinates of each vertex and the texture coordinates of those vertices. The GPU will decide which mip level to use based on the texel-to-pixel ratio of the fragments that will be generated.

Are you setting GL_LINEAR_MIPMAP_LINEAR when you render your tiles as well? It only matters when you render things, not when you create/load the texture. Your bracketing glEnable/glDisable calls may need to be moved too, depending on what state you are actually passing in there.

Alan
Thanks for your reply. I have moved the glTexParamateri() calls to above my call to gluBuild2DMipmaps() and even added them to the draw functions. I have called glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST) too, but still I see no difference. At least, thanks to you, I understand now how OpenGL decides on mipmap level.
Droozle
@Droozle: When you moved the glTexParameter to your render code, did you put it before or after the glDraw* call? It has to be before. When you call something like glTexParameter or glEnable, you are setting a state in the gl driver. The driver will remember those states until you set it to something else. Most of those states are only used by the driver at the exact instant you call glDrawSomething.
Alan
@Alan: thanks for replying. I am aware that OpenGL is a state machine and I *think* I did everything by the book. After looking at at least 20 different code examples, I have given up on it for now. Maybe it has to do with the fact that my textures have an alpha channel but so far I am out of luck. It's weird.
Droozle