Breaking big texture into 256x256 textures

Hi,

As far as I know, maximum texture dimension supported by gfx cards can be vary. I use Vodoo3 and I see that the highest dimension that I can use to maintain its quality is 256x256. Bigger than that, it become blur.

So each time I create a project which has a fullscreen background image, I break my background’s texture into 256x256 manually using Paint Brush. Then I paste them on several quards and rearrange them. By using this way, I can get a “wallpaper” quality.

Is there any other better way?

yep there is another way, i’ve done it, but its not as easy like your verion (but works for all texture-sizes). The problem for you is, that i dont publicate this source, but here is a sheme of the algo:
1.st get maxtexsize
2. calc:
tilesx= image_x+1 /maxtexsize
tilesy= image_y+1 /maxtexsize
calc much other stuff (related to texcoords, vertexcoords)
3. now you gen tilesxtilesy times a texture of maxtexsizemaxtexsize and use for each of them seperate texcoord, vertexcoords (i prefer the range from 0 to 1) the clue is that you have to handle the last row/col seperate, it gets different texcoords …

now you maybe have an idea of how it works, but in real life its more complicated. think of that:
you have an image 100100 and a max texsize of 6464 now your algo should produce 4 textures with vertexes and texcoords. all together producing a texture which lay on a playne between (o,o) and (1,1) and it is not that easy that you can split at half the length (or you want to waste memory)…

and dont forget: to map this texture on an object you will have to split the object at the texture-edges…

but there is another way, an extension (which i dont know anymore) makes all this stuff for you…

Hi, thanks for that. But I’m not that good to manipulate your idea. I’m still in a “beginer” category. So that idea won’t help me much.

I just know how to load a texture (which I grab from somebody tutorial). I don’t know how to take a portion of it and pass it into glGenTexture.

Let say I found the array that hold the pixels value and I know the texture actual dimension, what should I do with it? This is the most important part for me.

Please give me more tips. Or can I have your codes so I can use it without any modifying?

But I think I can make the coordinate and vertex part.

my code won’t help you, but hmm here is it(i’ve decided that you can have this part of my code :slight_smile: but not more, so try to understand), and dont try to copy simple to your app, it won’t work(you need some struct/the class IMAGE …):

void IMAGE::GenImages(){
unsigned long max_texture_size= GetTextureSize();
if(!max_texture_size)
return;

_glImage_Columns= width/max_texture_size +1;
_glImage_Rows= height/max_texture_size +1;

unsigned long flag_new_texture= !glimages;
if(flag_new_texture)
glimages= new _glImage[_glImage_Columns * _glImage_Rows];

unsigned long partimagesize= max_texture_size* datacomponents;
partimagesize+= partimagesize%4;
unsigned char partimage= new unsigned char [partimagesizemax_texture_size];

_glImage *ptr= glimages;
for(unsigned long i= _glImage_Columns;i-- :wink:
for(unsigned long j= _glImage_Rows;j-- ;){
if(flag_new_texture)
glGenTextures(1, &ptr->id);
glBindTexture(GL_TEXTURE_2D, ptr->id);

  	unsigned long	partimage_left= (_glImage_Columns-i-1) * max_texture_size * datacomponents,
  					partimage_top= (_glImage_Rows-j-1) * max_texture_size,
  					partimage_width= max_texture_size * datacomponents,
  					partimage_height= max_texture_size;

  	float tmp= (2.0f/width*max_texture_size);
  	if(tmp > 2.0f) tmp= 2.0f;
  	ptr->texture_coords.left=0;
  	ptr->image_coords.left= -1.0f + tmp*(_glImage_Columns-i-1);
  	if(i){
  		ptr->texture_coords.right=1;
  		ptr->image_coords.right= ptr->image_coords.left + tmp;
  	}
  	else{
  		partimage_width= width *datacomponents - (_glImage_Columns -1) * partimage_width;
  		ptr->texture_coords.right= 1.0f/max_texture_size*(width-max_texture_size*(_glImage_Columns-1));
  		ptr->image_coords.right= 1;
  	}

  	tmp= (2.0f/height*max_texture_size);
  	if(tmp > 2.0f) tmp= 2.0f;
  	ptr->texture_coords.top=0;
  	ptr->image_coords.top= 1.0f - tmp*(_glImage_Rows-j-1);
  	if(j){
  		ptr->texture_coords.bottom=1;
  		ptr->image_coords.bottom= ptr->image_coords.top - tmp;
  	}
  	else{
  		partimage_height= height - (_glImage_Rows -1) * partimage_height;
  		ptr->texture_coords.bottom= 1.0f/max_texture_size*(height-max_texture_size*(_glImage_Rows-1));
  		ptr->image_coords.bottom= -1;
  	}

  	unsigned long	src_lineoffset= width*datacomponents;
  	src_lineoffset+= src_lineoffset%4;
  	unsigned char	*src= data + (partimage_top * src_lineoffset) + partimage_left,
  					*dest= partimage;
  	unsigned long tmp2;
  	for(unsigned long k= partimage_height; k-- ;){
  		memcpy(dest, src, partimage_width);
  		tmp2= partimagesize-partimage_width;
  		if(tmp2)
  			memset(dest+ partimage_width, 0, tmp2);
  		dest+= partimagesize;
  		src+= src_lineoffset;
  	}
  	tmp2= (max_texture_size-partimage_height)*partimagesize;
  	if(tmp2)
  		memset(dest, 0, tmp2 );

  	if(flag_new_texture){
  		glTexImage2D(GL_TEXTURE_2D, 0, datacomponents, max_texture_size, max_texture_size, 0, (datacomponents == 4 ? GL_RGBA : GL_RGB), GL_UNSIGNED_BYTE, partimage);
  		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);
  		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
  	}
  	else{
  		glTexSubImage2D(GL_TEXTURE_2D, 0, 0,0, max_texture_size, max_texture_size, (datacomponents == 4 ? GL_RGBA : GL_RGB), GL_UNSIGNED_BYTE, partimage);
  	}

  	ptr++;
  }

delete(partimage);
}

[This message has been edited by T2k (edited 03-01-2002).]

Thank you very much! I’ll try my best!