mipmapping

Hi,

I have added the following method to ofTexture in order to use mipmapping. [All-this-started-with-that-thread in the forum]
It seems to be working quite well. I have improved my application performance.
But something is not really clear.

If I understood correctly, it’s possible to generate mipmaps using [all this come from the openGL blue book] :

  • the function gluBuildMipmaps (in my case gluBuild2DMipmaps)
  • or by setting the following texture parameter, GL_GENERATE_MIPMAP to GL_TRUE (like this glTexParameteri(texData.textureTarget, GL_GENERATE_MIPMAP, GL_TRUE) )

setting the param GL_GENERATE_MIPMAP to GL_TRUE works. This is the way used in the method createMipmaps included in this post.

But if I use the other way, with the function gluBuild2DMipmaps, all the mipmaps texture get a blue tint. Here is a screen capture.

Would somebody have an idea as to why ?

Thanks,

Hugues.

  
  
  
//----------------------------------------------------------  
void ofTexture::createMipmaps(int w, int h, int internalGlDataType){  
	  
	//we need to calculate the next power of 2 for the requested dimensions  
	//ie (320x240) becomes (512x256)  
	texData.tex_w = ofNextPow2(w);  
	texData.tex_h = ofNextPow2(h);  
	texData.tex_t = 1.0f;  
	texData.tex_u = 1.0f;  
	texData.textureTarget = GL_TEXTURE_2D;  
	  
	texData.glTypeInternal = internalGlDataType;  
	  
	// attempt to free the previous bound texture, if we can:  
	clear();  
	  
	glGenTextures(1, (GLuint *)texData.textureName);   // could be more then one, but for now, just one  
	  
	glEnable(texData.textureTarget);  
	  
	glBindTexture(texData.textureTarget, (GLuint)texData.textureName[0]);  
	  
	//uncomment if Mip levels are generated with gluBuild2DMipmaps();  
	//unsigned char * data;  
	//data = (unsigned char *)malloc( (GLint)texData.tex_w * (GLint)texData.tex_h * 3 );  
	  
	//Hardware geneartion of Mipmaps  
	glTexParameteri(texData.textureTarget, GL_GENERATE_MIPMAP, GL_TRUE);  
	  
	//Mip levels that are loaded  
	glTexParameteri(texData.textureTarget, GL_TEXTURE_BASE_LEVEL, 0);  
	glTexParameteri(texData.textureTarget, GL_TEXTURE_MAX_LEVEL, 5);  
	  
	//Loaded mip levels that are used  
	/*  
	glTexParameteri(texData.textureTarget, GL_TEXTURE_MIN_LOD, 0);  
	glTexParameteri(texData.textureTarget, GL_TEXTURE_MAX_LOD, 4.5);  
	*/  
	  
	//Generating Mip levels  
	//gluBuild2DMipmaps( texData.textureTarget, texData.glTypeInternal, (GLint)texData.tex_w, (GLint)texData.tex_h, texData.glTypeInternal, GL_UNSIGNED_BYTE, data );  
	glTexImage2D(texData.textureTarget, 0, texData.glTypeInternal, (GLint)texData.tex_w, (GLint)texData.tex_h, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, 0);  
	  
	//Better visual quality  
	//glTexParameteri(texData.textureTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR); //GL_LINEAR_MIPMAP_LINEAR );  
        //glTexParameteri(texData.textureTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);  
	  
	//Better peformance (should give ...)  
	glTexParameteri(texData.textureTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST_MIPMAP_NEAREST); //GL_LINEAR);  
	glTexParameteri(texData.textureTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);  
	  
	glTexParameterf( texData.textureTarget, GL_TEXTURE_WRAP_S, GL_REPEAT );  
	glTexParameterf( texData.textureTarget, GL_TEXTURE_WRAP_T, GL_REPEAT );  
	  
	glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);  
	  
	//LOD BIAS - moves selection criteria back or forward  
	//lean toward larger mip levels or lean toward smaller mip levels  
	//glTexEnvf(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, -1.5);  
	  
	//uncomment if was previously created  
	//free(data);	  
	  
	glDisable(texData.textureTarget);  
	  
	texData.width = w;  
	texData.height = h;  
	  
	texData.bFlipTexture = false;  
	  
	texData.bAllocated = true;  
}  
  
  

something like this should be enough:

  
    glBindTexture( GL_TEXTURE_2D, result);  
	glGenerateMipmapEXT( GL_TEXTURE_2D);  
    glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);  
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);  
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);  
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);  
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);  

glGenerateMipmapEXT( GL_TEXTURE_2D); should do everything you need and is the common way of doing it (your way seems to be really oldschool)

reading the opengl blue book I thought that glGenerateMipmapEXT was to be used when working with FBOs.

I tried what you posted. I had to change the order of two opengl calls - glTexImage2D and glGenerateMipmapEXT - in order to get it to work. [otherwise I was getting white textures]

  
  
glBindTexture(texData.textureTarget, (GLuint)texData.textureName[0]);  
glTexImage2D(texData.textureTarget, 0, texData.glTypeInternal, (GLint)texData.tex_w, (GLint)texData.tex_h, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, 0);  
glGenerateMipmapEXT( GL_TEXTURE_2D);  
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);  
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);  
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);  
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);  
  

But now the mipmaps are not correct (all scrambled) - see the screen-capture.

I tried with GL_RGB and GL_RGBA for texData.glTypeInternal instead of GL_LUMINANCE (and also the GL_LUMINANCE in the call to glTexImage2D), but I still get crappy mipmap texture.

Thanks for your sharing.

ahh hmm actually it could be that its only for FBO.- the code snipped I posted is from an FBO, so I am not sure, google should be able to tell you though.- I am pretty sure it should work with normal textures too.

edit:
Seems my guessing was right:
http://www.opengl.org/discussion-boards-…-ber=233955

Yes I had saw that url. I misunderstood what is written in the blue book.
Also, the fact that I get something on the screen proved me that glGenerateMipmapEXT could be used with FBO. But I still do not see why the mipmaps textures are not generated correctly.

I think you have to put the generateMipmapEXT thing after everything else.- I just put it in the wrong place because it was throwing errors with my FBO configuration i guess.-

this could work:

  
  
glBindTexture(texData.textureTarget, (GLuint)texData.textureName[0]);  
glTexImage2D(texData.textureTarget, 0, texData.glTypeInternal, (GLint)texData.tex_w, (GLint)texData.tex_h, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, 0);  
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);  
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);  
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);  
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);  
glGenerateMipmapEXT( GL_TEXTURE_2D);  
  

I think I got it.
glGenerateMipmapEXT has to be after glTexImage2D;
and glEnable(GL_TEXTURE_2D) after glGenerateMipmapEXT.

  
  
glTexImage2D(texData.textureTarget, 0, texData.glTypeInternal, (GLint)texData.tex_w, (GLint)texData.tex_h, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, 0);  
glGenerateMipmapEXT(GL_TEXTURE_2D);  
glEnable(GL_TEXTURE_2D);  
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);  
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);  
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);  
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);  
  

Thanks again.

kool, you actually dont need to enable any texture target for the mipmap generation as far as I know.- only if you want to bind it for drawing with the fixed function pipeline.

well you are right. I just recompiled my project without the glEnable(GL_TEXTURE_2D) and it worked. But it did not work before. This made me realize that my project react differently almost every time I compile it. (Or the mipmaps textures are crap, or the different levels of mips do not correspond to the texture at the level 0 [the mipmaps of my different textures are mixed], or some time it works.)

And I do not have these problems when using glTexParameteri(texData.textureTarget, GL_GENERATE_MIPMAP, GL_TRUE); instead of glGenerateMipmapEXT( GL_TEXTURE_2D);

maybe something ‘wrong’ with my video card (GeForce 8600M GT on a MacBook Pro).

Well I guess for now I will be using the method that works :wink: