Texture Problem

Hello,

I want to load a bitmap with size other than powers of 2 as a texture. Here is the code:

bool CChildView::LoadTexture(CString sFileName, GLuint& uTexture)
{
	if (sFileName.GetLength() <= 0)
		return false;
	
	FILE* f = fopen(sFileName, "r");
	if (!f)
		return false;
	fclose(f);

	AUX_RGBImageRec* pImg = auxDIBImageLoad(sFileName);
	if (!pImg)
		return false;

	glGenTextures(1, &uTexture);
	glBindTexture(GL_TEXTURE_2D, uTexture);

	int nWidth, nHeight;
	
	nWidth = 1;
	while (nWidth <= pImg->sizeX)
		nWidth *= 2;
	nWidth /= 2;

	nHeight = 1;
	while (nHeight <= pImg->sizeY)
		nHeight *= 2;
	nHeight /= 2;

	if (nWidth != pImg->sizeX &#0124;&#0124; nHeight != pImg->sizeY)
	{
		GLubyte* pNewData = (GLubyte*)malloc(nWidth * nHeight * 3 * sizeof(GLubyte));
		int iErr = gluScaleImage(GL_RGB,
			pImg->sizeX, pImg->sizeY, GL_UNSIGNED_BYTE, pImg->data,
			nWidth, nHeight, GL_UNSIGNED_BYTE, pNewData);
		
		if (iErr == 0)
		{
			free(pImg->data);
			pImg->sizeX = nWidth;
			pImg->sizeY = nHeight;
			pImg->data = pNewData;
		}
		else
			free(pNewData);
	}
	
	//gluBuild2DMipmaps(GL_TEXTURE_2D, 1, pImg->sizeX, pImg->sizeY, GL_RGB, GL_UNSIGNED_BYTE, pImg->data);
	glTexImage2D(GL_TEXTURE_2D, 0, 3, pImg->sizeX, pImg->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, pImg->data);

	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	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);

	if (pImg->data)
		free(pImg->data);
	free(pImg);

	return true;
}

The textures appear distorted, where am I doing wrong?

Thanks!

maybe your texture has an alpha channel?

When I try to load the texture with GL_RGBA, I always get an exception. I copied the code from NeHe’s tutorial #6.

Do you have a picture of the distortion?

Originally posted by Bumbala:
[b]

	nWidth = 1;
	while (nWidth &lt;= pImg-&gt;sizeX)
		nWidth *= 2;
	nWidth /= 2;

nHeight = 1;
while (nHeight <= pImg->sizeY)
nHeight *= 2;
nHeight /= 2;

[/b]

What you made (and not only what I quoted) is non-sense for loading NPOT textures… if I understand correctly that you want to load NPOT textures, don’t you ?
So a bit of knowledge about what you’re programming could help you more than several guesses about GL errors/misunderstandings…

Hope that helps.

Edit:

I personally never have used NPOT textures, so maybe a scale is necessary, so forgive me if that’s needed…

what you quote is an algorithm that finds values for width and height, which are smaller or equal to the actual image size and powers of two.

then the original image is scaled to these values, so that the scaled image’s size is a power of two in both directions. where’s the nonsense?

The fact that he wants to load a NPOT texture but that he scales it into a POT texture. That was what I said in my last post.
He just said he wants to load a NPOT texture not to scale a NPOT image into a POT texture.

Between, I know what I quoted…

What I simply need is to load textures with sizes other than powers of 2. For example, 130x130, 167x167, 130x260 etc. I know that glTexImage2D accepts only powers of 2 and when I use gluBuild2DMipmaps or gluScaleImage, the textures are distorted (strange shapes, colors).

Thank you!

If your system supports NPOT texturex, I suggest you to have a look at this:
http://oss.sgi.com/projects/ogl-sample/registry/ARB/texture_non_power_of_two.txt

Otherwise, the simpler thing (and surely getting best quality) is to use an image program like Gimp and scale the image yourself.

bumbala,

your approach should work, in my opinion. maybe it would help if you could upload the image itself and a screenshot of the distorted image, as interface suggested.

btw, have you tried to display the original image with glDrawPixels? that way you could check if the image has been correctly loaded.

I solved the problem by resizing the raw image to the nearest power of 2 by a third party library before loading the texture. Now they are displayed properly. Thanks all for the recommendations.

if your cards supports GL_ARB_texture_non_power_of_two extension (some are listed here : http://delphi3d.net/hardware/extsupport.php?extension=GL_ARB_texture_non_power_of_two )
you can simply provide a texture with any coordinates to glTexImage2D without worrying about power of 2 or not.

Moreover, gluBuild2DMipmaps should take any texture size, and will rescale it to nearest power of 2. If you get distorsion, it is probable that you messed up something… for example, you should not mess up with changin nHeight, nWidth if you use gluBuild2DMipmaps.

ZBuffer is correct. gluBuild2DMipmaps() converts the picture to a power of 2 texture if necessary.
I have used from none power of 2 textures in some of my applications. But it’s better that we rescale the image out of our program–As Jide already said.
-Ehsan-