Zoran Zivkovic

09-21-2000, 04:44 AM

It seems that OpenGL can take only texture images of the 2^kx2^k format. Can this be changed? If no, is there some code of work-arounds for this problem?

View Full Version : Textures 2^k x 2^k?

Zoran Zivkovic

09-21-2000, 04:44 AM

It seems that OpenGL can take only texture images of the 2^kx2^k format. Can this be changed? If no, is there some code of work-arounds for this problem?

NewROmancer

09-21-2000, 05:00 AM

Yes it cans but I don't know how to do it.

NewROmancer

NewROmancer

Eric

09-21-2000, 05:14 AM

Your statement is not totally correct : OpenGL handles textures of size 2^m x 2^n (which means a rectangle) ! When you say 2^k x 2^k, you define a square...

Then, if you want to use a texture that does have that type or dimension, there are two options :

1 - Scale you texture (you can use a linear scaling for a start ; pretty easy to code) so that it fits in a 2^m x 2^n bitmap.

2 - Just create a texture of size 2^m x 2^n and copy your texture at (0,0) in the new one... That can be compare to watching an image in a bigger window (part of the window is useless !). The problem with this method is that you then have to tweak your texture coordinates i.e. the bottom right of your texture is not (1,1) but (0.xx,0.yy) !

Here is part of a code I used which implements the first method :

tUsedHeight and tUsedWidth are the real dimensions of your texture. tImage is an array of GLubyte that contains the actual pixels...

void HGL_RGBATexture::AdjustSize(void)

{

double dHeightPow2,dWidthPow2;

int iHeightPow2,iWidthPow2;

unsigned char* adjustedImage;

int i,j,ti,tj;

dHeightPow2=log(tUsedHeight)/log(2);

dWidthPow2=log(tUsedWidth)/log(2);

iHeightPow2=dHeightPow2;

iWidthPow2=dWidthPow2;

if (dHeightPow2==iHeightPow2)

tHeight=tUsedHeight;

else

tHeight=pow(2,iHeightPow2+1);

if (dWidthPow2==iWidthPow2)

tWidth=tUsedWidth;

else

tWidth=pow(2,iWidthPow2+1);

adjustedImage = new unsigned char[tWidth*tHeight*4];

memset(adjustedImage,0,tWidth*tHeight*4);

for (j=0;j<tHeight;j++)

{

tj=(double) j*tUsedHeight/tHeight;

for (i=0;i<tWidth;i++)

{

ti=(double) i*tUsedWidth/tWidth;

adjustedImage[(j*tWidth+i)*4]=tImage[(tj*tUsedWidth+ti)*4];

adjustedImage[(j*tWidth+i)*4+1]=tImage[(tj*tUsedWidth+ti)*4+1];

adjustedImage[(j*tWidth+i)*4+2]=tImage[(tj*tUsedWidth+ti)*4+2];

adjustedImage[(j*tWidth+i)*4+3]=tImage[(tj*tUsedWidth+ti)*4+3];

}

delete [] tImage;

tImage=adjustedImage;

}

}

That's a crappy scaling algorithm but it works !

Regards.

Eric

Then, if you want to use a texture that does have that type or dimension, there are two options :

1 - Scale you texture (you can use a linear scaling for a start ; pretty easy to code) so that it fits in a 2^m x 2^n bitmap.

2 - Just create a texture of size 2^m x 2^n and copy your texture at (0,0) in the new one... That can be compare to watching an image in a bigger window (part of the window is useless !). The problem with this method is that you then have to tweak your texture coordinates i.e. the bottom right of your texture is not (1,1) but (0.xx,0.yy) !

Here is part of a code I used which implements the first method :

tUsedHeight and tUsedWidth are the real dimensions of your texture. tImage is an array of GLubyte that contains the actual pixels...

void HGL_RGBATexture::AdjustSize(void)

{

double dHeightPow2,dWidthPow2;

int iHeightPow2,iWidthPow2;

unsigned char* adjustedImage;

int i,j,ti,tj;

dHeightPow2=log(tUsedHeight)/log(2);

dWidthPow2=log(tUsedWidth)/log(2);

iHeightPow2=dHeightPow2;

iWidthPow2=dWidthPow2;

if (dHeightPow2==iHeightPow2)

tHeight=tUsedHeight;

else

tHeight=pow(2,iHeightPow2+1);

if (dWidthPow2==iWidthPow2)

tWidth=tUsedWidth;

else

tWidth=pow(2,iWidthPow2+1);

adjustedImage = new unsigned char[tWidth*tHeight*4];

memset(adjustedImage,0,tWidth*tHeight*4);

for (j=0;j<tHeight;j++)

{

tj=(double) j*tUsedHeight/tHeight;

for (i=0;i<tWidth;i++)

{

ti=(double) i*tUsedWidth/tWidth;

adjustedImage[(j*tWidth+i)*4]=tImage[(tj*tUsedWidth+ti)*4];

adjustedImage[(j*tWidth+i)*4+1]=tImage[(tj*tUsedWidth+ti)*4+1];

adjustedImage[(j*tWidth+i)*4+2]=tImage[(tj*tUsedWidth+ti)*4+2];

adjustedImage[(j*tWidth+i)*4+3]=tImage[(tj*tUsedWidth+ti)*4+3];

}

delete [] tImage;

tImage=adjustedImage;

}

}

That's a crappy scaling algorithm but it works !

Regards.

Eric

Zoran Zivkovic

09-25-2000, 07:38 AM

Thanks, but I'll use the second method because I have some scientific applications in mind. First one has a double interpolation.

Powered by vBulletin® Version 4.2.3 Copyright © 2018 vBulletin Solutions, Inc. All rights reserved.